From 28b7d78adb4cabf670aa5d933ef2abd9009cf1cb Mon Sep 17 00:00:00 2001 From: maniacikarus Date: Thu, 12 Mar 2009 18:33:35 +0100 Subject: [PATCH] Added red alias to core28 and fixed linefeeds --- config/rootfiles/core/28/files | 3 + html/cgi-bin/aliases.cgi | 1013 ++++++++++++++++---------------- src/misc-progs/setaliases.c | 392 ++++++------ 3 files changed, 712 insertions(+), 696 deletions(-) mode change 100755 => 100644 html/cgi-bin/aliases.cgi diff --git a/config/rootfiles/core/28/files b/config/rootfiles/core/28/files index cabddbff1d..d7f909844b 100644 --- a/config/rootfiles/core/28/files +++ b/config/rootfiles/core/28/files @@ -18,3 +18,6 @@ usr/lib/libcurl.so usr/lib/libcurl.so.4 usr/lib/libcurl.so.4.1.1 lib/modules/2.6.25.19-ipfire/misc/kqemu.ko +usr/local/bin/setaliases +srv/web/ipfire/cgi-bin/aliases.cgi +var/ipfire/menu.d/30-network.menu \ No newline at end of file diff --git a/html/cgi-bin/aliases.cgi b/html/cgi-bin/aliases.cgi old mode 100755 new mode 100644 index c8d4362607..11a0fe98bb --- a/html/cgi-bin/aliases.cgi +++ b/html/cgi-bin/aliases.cgi @@ -1,500 +1,513 @@ -#!/usr/bin/perl -# -# IPCop CGI's - aliases.cgi -# -# This code is distributed under the terms of the GPL -# -# (c) Steve Bootes 2002/04/13 - Manage IP Aliases -# -# $Id: aliases.cgi,v 1.5.2.18 2006/12/08 21:59:59 eoberlander Exp $ - - -# to fully troubleshot your code, uncomment diagnostics, Carp and cluck lines -#use diagnostics; # need to add the file /usr/lib/perl5/5.8.x/pods/perldiag.pod before to work -# next look at /var/log/httpd/error_log , http://www.perl.com/pub/a/2002/05/07/mod_perl.html may help -#use warnings; -use strict; -#use Carp (); -#local $SIG{__WARN__} = \&Carp::cluck; - -require '/var/ipfire/general-functions.pl'; # replace /var/ipcop with /var/ipcop in case of manual install -require "${General::swroot}/lang.pl"; -require "${General::swroot}/header.pl"; - -#workaround to suppress a warning when a variable is used only once -my @dummy = ( ${Header::colouryellow} ); - @dummy = ( ${Header::table1colour} ); - @dummy = ( ${Header::table2colour} ); -undef (@dummy); - -# Files used -my $setting = "${General::swroot}/ethernet/settings"; -our $datafile = "${General::swroot}/ethernet/aliases"; - - -our %settings=(); -#Settings1 - -#Settings2 for editing the multi-line list -#Must not be saved ! -$settings{'IP'} = ''; -$settings{'ENABLED'} = 'off'; # Every check box must be set to off -$settings{'NAME'} = ''; -my @nosaved=('IP','ENABLED','NAME'); # List here ALL setting2 fields. Mandatory - -$settings{'ACTION'} = ''; # add/edit/remove -$settings{'KEY1'} = ''; # point record for ACTION - -#Define each field that can be used to sort columns -my $sortstring='^IP|^NAME'; -my $errormessage = ''; -my $warnmessage = ''; - -&Header::showhttpheaders(); - -# Read needed Ipcop netsettings -my %netsettings=(); -$netsettings{'SORT_ALIASES'} = 'NAME'; # default sort -&General::readhash($setting, \%netsettings); - -#Get GUI values -&Header::getcgihash(\%settings); - -# Load multiline data -our @current = (); -if (open(FILE, "$datafile")) { - @current = ; - close (FILE); -} - -# -# Check Settings1 first because they are needed before working on @current -# -# Remove if no Setting1 needed -# -if ($settings{'ACTION'} eq $Lang::tr{'save'}) { - - # - #Validate static Settings1 here - # - - unless ($errormessage) { # Everything is ok, save settings - #map (delete ($settings{$_}) ,(@nosaved,'ACTION','KEY1'));# Must never be saved - #&General::writehash($setting, \%settings); # Save good settings - #$settings{'ACTION'} = $Lang::tr{'save'}; # Recreate 'ACTION' - #map ($settings{$_}= '',(@nosaved,'KEY1')); # and reinit var to empty - - # Rebuild configuration file if needed - &BuildConfiguration; - } - - ERROR: # Leave the faulty field untouched -} else { - #&General::readhash($setting, \%settings); # Get saved settings and reset to good if needed -} - -## Now manipulate the multi-line list with Settings2 -# Basic actions are: -# toggle the check box -# add/update a new line -# begin editing a line -# remove a line - - -# Toggle enable/disable field. Field is in second position -if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { - #move out new line - chomp(@current[$settings{'KEY1'}]); - my @temp = split(/\,/,@current[$settings{'KEY1'}]); - $temp[1] = $temp[1] eq 'on' ? 'off' : 'on'; # Toggle the field - $temp[2] = '' if ( $temp[2] eq '' ); - @current[$settings{'KEY1'}] = join (',',@temp)."\n"; - $settings{'KEY1'} = ''; # End edit mode - - &General::log($Lang::tr{'ip alias changed'}); - - #Save current - open(FILE, ">$datafile") or die 'Unable to open aliases file.'; - print FILE @current; - close(FILE); - - # Rebuild configuration file - &BuildConfiguration; -} - -if ($settings{'ACTION'} eq $Lang::tr{'add'}) { - # Validate inputs - if (! &General::validip($settings{'IP'})) {$errormessage = "invalid ip"}; - $settings{'NAME'} = &Header::cleanhtml($settings{'NAME'}); - - # Make sure we haven't duplicated an alias or RED - my $spacer=''; - if ($settings{'IP'} eq $netsettings{'RED_ADDRESS'}) { - $errormessage = $Lang::tr{'duplicate ip'} . ' (RED)'; - $spacer=" & "; - } - my $idx=0; - foreach my $line (@current) { - chomp ($line); - my @temp = split (/\,/, $line); - if ( ($settings{'KEY1'} eq '')||(($settings{'KEY1'} ne '') && ($settings{'KEY1'} != $idx))) { # update - if ($temp[0] eq $settings{'IP'}) { - $errormessage .= $spacer.$Lang::tr{'duplicate ip'}; - $spacer=" & "; - } - if ($temp[2] eq $settings{'NAME'} && $temp[2] ne '') { - $errormessage .= $spacer.$Lang::tr{'duplicate name'}; - $spacer=" & "; - } - } - $idx++; - } - unless ($errormessage) { - if ($settings{'KEY1'} eq '') { #add or edit ? - unshift (@current, "$settings{'IP'},$settings{'ENABLED'},$settings{'NAME'}\n"); - &General::log($Lang::tr{'ip alias added'}); - } else { - @current[$settings{'KEY1'}] = "$settings{'IP'},$settings{'ENABLED'},$settings{'NAME'}\n"; - $settings{'KEY1'} = ''; # End edit mode - &General::log($Lang::tr{'ip alias changed'}); - } - - # Write changes to config file. - &SortDataFile; # sort newly added/modified entry - - &BuildConfiguration; # then re-build conf which use new data - -## -## if entering data line is repetitive, choose here to not erase fields between each addition -## - map ($settings{$_}='' ,@nosaved); # Clear fields - } -} - -if ($settings{'ACTION'} eq $Lang::tr{'edit'}) { - #move out new line - my $line = @current[$settings{'KEY1'}]; # KEY1 is the index in current - chomp($line); - my @temp = split(/\,/, $line); - -## -## move data fields to Setting2 for edition -## - $settings{'IP'}=$temp[0]; # Prepare the screen for editing - $settings{'ENABLED'}=$temp[1]; - $settings{'NAME'}=$temp[2]; -} - -if ($settings{'ACTION'} eq $Lang::tr{'remove'}) { - splice (@current,$settings{'KEY1'},1); # Delete line - open(FILE, ">$datafile") or die 'Unable to open aliases file.'; - print FILE @current; - close(FILE); - $settings{'KEY1'} = ''; # End remove mode - &General::log($Lang::tr{'ip alias removed'}); - - &BuildConfiguration; # then re-build conf which use new data -} - - - -## Check if sorting is asked -# If same column clicked, reverse the sort. -if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) { - my $newsort=$ENV{'QUERY_STRING'}; - my $actual=$netsettings{'SORT_ALIASES'}; - #Reverse actual sort ? - if ($actual =~ $newsort) { - my $Rev=''; - if ($actual !~ 'Rev') { - $Rev='Rev'; - } - $newsort.=$Rev; - } - $netsettings{'SORT_ALIASES'}=$newsort; - &General::writehash($setting, \%netsettings); - &SortDataFile; - $settings{'ACTION'} = 'SORT'; # Recreate 'ACTION' -} - -# Default initial value -if ($settings{'ACTION'} eq '' ) { # First launch from GUI - $settings{'ENABLED'} ='on'; -} - -&Header::openpage($Lang::tr{'external aliases configuration'}, 1, ''); -&Header::openbigbox('100%', 'left', '', $errormessage); -my %checked =(); # Checkbox manipulations - -if ($errormessage) { - &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); - print "$errormessage "; - &Header::closebox(); -} -unless (( $netsettings{'CONFIG_TYPE'} =~ /^(1|2|3|4)$/ ) && ($netsettings{'RED_TYPE'} eq 'STATIC')) -{ - &Header::openbox('100%', 'left', $Lang::tr{'capswarning'}); - print < - - $Lang::tr{'aliases not active'} - - -END -; - &Header::closebox(); -} - -# -# Second check box is for editing the list -# -$checked{'ENABLED'}{'on'} = ($settings{'ENABLED'} eq 'on') ? "checked='checked'" : '' ; - -my $buttontext = $Lang::tr{'add'}; -if ($settings{'KEY1'} ne '') { - $buttontext = $Lang::tr{'update'}; - &Header::openbox('100%', 'left', $Lang::tr{'edit an existing alias'}); -} else { - &Header::openbox('100%', 'left', $Lang::tr{'add new alias'}); -} - -#Edited line number (KEY1) passed until cleared by 'save' or 'remove' or 'new sort order' -print < - - - - - - - - - - -
$Lang::tr{'name'}: *$Lang::tr{'alias ip'}: $Lang::tr{'enabled'} 
-
- - - - - - -
* $Lang::tr{'this field may be blank'} - -
- -END -; -&Header::closebox(); - -# Add visual indicators to column headings to show sort order - EO -my $sortarrow1 = ''; -my $sortarrow2 = ''; - -if ($netsettings{'SORT_ALIASES'} eq 'NAMERev') { - $sortarrow1 = $Header::sortdn; -} elsif ($netsettings{'SORT_ALIASES'} eq 'NAME') { - $sortarrow1 = $Header::sortup; -} elsif ($netsettings{'SORT_ALIASES'} eq 'IPRev') { - $sortarrow2 = $Header::sortdn; -} else { - $sortarrow2 = $Header::sortup; -} - -# -# Third box shows the list, in columns -# -# Columns headers may content a link. In this case it must be named in $sortstring -# -&Header::openbox('100%', 'left', $Lang::tr{'current aliases'}); -print < - - $Lang::tr{'name'} $sortarrow1 - $Lang::tr{'alias ip'} $sortarrow2 - $Lang::tr{'action'} - -END -; - -# -# Print each line of @current list -# -# each data line is splitted into @temp. -# - -my $key = 0; -foreach my $line (@current) { - chomp($line); - my @temp = split(/\,/,$line); - - #Choose icon for checkbox - my $gif = ''; - my $gdesc = ''; - if ($temp[1] eq "on") { - $gif = 'on.gif'; - $gdesc = $Lang::tr{'click to disable'}; - } else { - $gif = 'off.gif'; - $gdesc = $Lang::tr{'click to enable'}; - } - - #Colorize each line - if ($settings{'KEY1'} eq $key) { - print ""; - } elsif ($key % 2) { - print ""; - } else { - print ""; - } - - print <$temp[2] -$temp[0] - - -
- - - -
- - - -
- - - -
- - - -
- - - -
- - -END -; - $key++; -} -print ""; - -# If table contains entries, print 'Key to action icons' -if ($key) { -print < - -  $Lang::tr{'legend'}:  - $Lang::tr{ - $Lang::tr{'click to disable'} -    - $Lang::tr{ - $Lang::tr{'click to enable'} -    - $Lang::tr{ - $Lang::tr{'edit'} -    - $Lang::tr{ - $Lang::tr{'remove'} - - -END -; -} - -&Header::closebox(); -&Header::closebigbox(); -&Header::closepage(); - -## Ouf it's the end ! - - - -# Sort the "current" array according to choices -sub SortDataFile -{ - our %entries = (); - - # Sort pair of record received in $a $b special vars. - # When IP is specified use numeric sort else alpha. - # If sortname ends with 'Rev', do reverse sort. - # - sub fixedleasesort { - my $qs=''; # The sort field specified minus 'Rev' - if (rindex ($netsettings{'SORT_ALIASES'},'Rev') != -1) { - $qs=substr ($netsettings{'SORT_ALIASES'},0,length($netsettings{'SORT_ALIASES'})-3); - if ($qs eq 'IP') { - my @a = split(/\./,$entries{$a}->{$qs}); - my @b = split(/\./,$entries{$b}->{$qs}); - ($b[0]<=>$a[0]) || - ($b[1]<=>$a[1]) || - ($b[2]<=>$a[2]) || - ($b[3]<=>$a[3]); - } else { - $entries{$b}->{$qs} cmp $entries{$a}->{$qs}; - } - } else { #not reverse - $qs=$netsettings{'SORT_ALIASES'}; - if ($qs eq 'IP') { - my @a = split(/\./,$entries{$a}->{$qs}); - my @b = split(/\./,$entries{$b}->{$qs}); - ($a[0]<=>$b[0]) || - ($a[1]<=>$b[1]) || - ($a[2]<=>$b[2]) || - ($a[3]<=>$b[3]); - } else { - $entries{$a}->{$qs} cmp $entries{$b}->{$qs}; - } - } - } - - #Use an associative array (%entries) - my $key = 0; - foreach my $line (@current) { - chomp( $line); #remove newline because can be on field 5 or 6 (addition of REMARK) - my @temp = split (',',$line); - - # Build a pair 'Field Name',value for each of the data dataline. - # Each SORTABLE field must have is pair. - # Other data fields (non sortable) can be grouped in one - - # Exemple - # F1,F2,F3,F4,F5 only F1 F2 for sorting - # my @record = ('KEY',$key++, - # 'F1',$temp[0], - # 'F2',$temp[1], - # 'DATA',join(',',@temp[2..4]) ); #group remainning values, with separator (,) - - # The KEY,key record permits doublons. If removed, then F1 becomes the key without doublon permitted. - - - my @record = ('KEY',$key++,'IP',$temp[0],'ENABLED',$temp[1],'NAME',$temp[2]); - my $record = {}; # create a reference to empty hash - %{$record} = @record; # populate that hash with @record - $entries{$record->{KEY}} = $record; # add this to a hash of hashes - } - - open(FILE, ">$datafile") or die 'Unable to open aliases file.'; - - # Each field value is printed , with the newline ! Don't forget separator and order of them. - foreach my $entry (sort fixedleasesort keys %entries) { - print FILE "$entries{$entry}->{IP},$entries{$entry}->{ENABLED},$entries{$entry}->{NAME}\n"; - } - - close(FILE); - # Reload sorted @current - open (FILE, "$datafile"); - @current = ; - close (FILE); -} - -# -# Build the configuration file for application aliases -# -sub BuildConfiguration { - # Restart service associated with this - system '/usr/local/bin/setaliases'; -} +#!/usr/bin/perl +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2007 Michael Tremer & Christian Schmidt # +# # +# This program is free software: you can redistribute it and/or modify # +# it under the terms of the GNU General Public License as published by # +# the Free Software Foundation, either version 3 of the License, or # +# (at your option) any later version. # +# # +# This program is distributed in the hope that it will be useful, # +# but WITHOUT ANY WARRANTY; without even the implied warranty of # +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +# GNU General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### +# +# this cgi is base on IPCop CGI - aliases.cgi +# + +# to fully troubleshot your code, uncomment diagnostics, Carp and cluck lines +#use diagnostics; # need to add the file /usr/lib/perl5/5.8.x/pods/perldiag.pod before to work +# next look at /var/log/httpd/error_log , http://www.perl.com/pub/a/2002/05/07/mod_perl.html may help +#use warnings; +use strict; +#use Carp (); +#local $SIG{__WARN__} = \&Carp::cluck; + +require '/var/ipfire/general-functions.pl'; # replace /var/ipcop with /var/ipcop in case of manual install +require "${General::swroot}/lang.pl"; +require "${General::swroot}/header.pl"; + +#workaround to suppress a warning when a variable is used only once +my @dummy = ( ${Header::colouryellow} ); + @dummy = ( ${Header::table1colour} ); + @dummy = ( ${Header::table2colour} ); +undef (@dummy); + +# Files used +my $setting = "${General::swroot}/ethernet/settings"; +our $datafile = "${General::swroot}/ethernet/aliases"; + + +our %settings=(); +#Settings1 + +#Settings2 for editing the multi-line list +#Must not be saved ! +$settings{'IP'} = ''; +$settings{'ENABLED'} = 'off'; # Every check box must be set to off +$settings{'NAME'} = ''; +my @nosaved=('IP','ENABLED','NAME'); # List here ALL setting2 fields. Mandatory + +$settings{'ACTION'} = ''; # add/edit/remove +$settings{'KEY1'} = ''; # point record for ACTION + +#Define each field that can be used to sort columns +my $sortstring='^IP|^NAME'; +my $errormessage = ''; +my $warnmessage = ''; + +&Header::showhttpheaders(); + +# Read needed Ipcop netsettings +my %netsettings=(); +$netsettings{'SORT_ALIASES'} = 'NAME'; # default sort +&General::readhash($setting, \%netsettings); + +#Get GUI values +&Header::getcgihash(\%settings); + +# Load multiline data +our @current = (); +if (open(FILE, "$datafile")) { + @current = ; + close (FILE); +} + +# +# Check Settings1 first because they are needed before working on @current +# +# Remove if no Setting1 needed +# +if ($settings{'ACTION'} eq $Lang::tr{'save'}) { + + # + #Validate static Settings1 here + # + + unless ($errormessage) { # Everything is ok, save settings + #map (delete ($settings{$_}) ,(@nosaved,'ACTION','KEY1'));# Must never be saved + #&General::writehash($setting, \%settings); # Save good settings + #$settings{'ACTION'} = $Lang::tr{'save'}; # Recreate 'ACTION' + #map ($settings{$_}= '',(@nosaved,'KEY1')); # and reinit var to empty + + # Rebuild configuration file if needed + &BuildConfiguration; + } + + ERROR: # Leave the faulty field untouched +} else { + #&General::readhash($setting, \%settings); # Get saved settings and reset to good if needed +} + +## Now manipulate the multi-line list with Settings2 +# Basic actions are: +# toggle the check box +# add/update a new line +# begin editing a line +# remove a line + + +# Toggle enable/disable field. Field is in second position +if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) { + #move out new line + chomp(@current[$settings{'KEY1'}]); + my @temp = split(/\,/,@current[$settings{'KEY1'}]); + $temp[1] = $temp[1] eq 'on' ? 'off' : 'on'; # Toggle the field + $temp[2] = '' if ( $temp[2] eq '' ); + @current[$settings{'KEY1'}] = join (',',@temp)."\n"; + $settings{'KEY1'} = ''; # End edit mode + + &General::log($Lang::tr{'ip alias changed'}); + + #Save current + open(FILE, ">$datafile") or die 'Unable to open aliases file.'; + print FILE @current; + close(FILE); + + # Rebuild configuration file + &BuildConfiguration; +} + +if ($settings{'ACTION'} eq $Lang::tr{'add'}) { + # Validate inputs + if (! &General::validip($settings{'IP'})) {$errormessage = "invalid ip"}; + $settings{'NAME'} = &Header::cleanhtml($settings{'NAME'}); + + # Make sure we haven't duplicated an alias or RED + my $spacer=''; + if ($settings{'IP'} eq $netsettings{'RED_ADDRESS'}) { + $errormessage = $Lang::tr{'duplicate ip'} . ' (RED)'; + $spacer=" & "; + } + my $idx=0; + foreach my $line (@current) { + chomp ($line); + my @temp = split (/\,/, $line); + if ( ($settings{'KEY1'} eq '')||(($settings{'KEY1'} ne '') && ($settings{'KEY1'} != $idx))) { # update + if ($temp[0] eq $settings{'IP'}) { + $errormessage .= $spacer.$Lang::tr{'duplicate ip'}; + $spacer=" & "; + } + if ($temp[2] eq $settings{'NAME'} && $temp[2] ne '') { + $errormessage .= $spacer.$Lang::tr{'duplicate name'}; + $spacer=" & "; + } + } + $idx++; + } + unless ($errormessage) { + if ($settings{'KEY1'} eq '') { #add or edit ? + unshift (@current, "$settings{'IP'},$settings{'ENABLED'},$settings{'NAME'}\n"); + &General::log($Lang::tr{'ip alias added'}); + } else { + @current[$settings{'KEY1'}] = "$settings{'IP'},$settings{'ENABLED'},$settings{'NAME'}\n"; + $settings{'KEY1'} = ''; # End edit mode + &General::log($Lang::tr{'ip alias changed'}); + } + + # Write changes to config file. + &SortDataFile; # sort newly added/modified entry + + &BuildConfiguration; # then re-build conf which use new data + +## +## if entering data line is repetitive, choose here to not erase fields between each addition +## + map ($settings{$_}='' ,@nosaved); # Clear fields + } +} + +if ($settings{'ACTION'} eq $Lang::tr{'edit'}) { + #move out new line + my $line = @current[$settings{'KEY1'}]; # KEY1 is the index in current + chomp($line); + my @temp = split(/\,/, $line); + +## +## move data fields to Setting2 for edition +## + $settings{'IP'}=$temp[0]; # Prepare the screen for editing + $settings{'ENABLED'}=$temp[1]; + $settings{'NAME'}=$temp[2]; +} + +if ($settings{'ACTION'} eq $Lang::tr{'remove'}) { + splice (@current,$settings{'KEY1'},1); # Delete line + open(FILE, ">$datafile") or die 'Unable to open aliases file.'; + print FILE @current; + close(FILE); + $settings{'KEY1'} = ''; # End remove mode + &General::log($Lang::tr{'ip alias removed'}); + + &BuildConfiguration; # then re-build conf which use new data +} + + + +## Check if sorting is asked +# If same column clicked, reverse the sort. +if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) { + my $newsort=$ENV{'QUERY_STRING'}; + my $actual=$netsettings{'SORT_ALIASES'}; + #Reverse actual sort ? + if ($actual =~ $newsort) { + my $Rev=''; + if ($actual !~ 'Rev') { + $Rev='Rev'; + } + $newsort.=$Rev; + } + $netsettings{'SORT_ALIASES'}=$newsort; + &General::writehash($setting, \%netsettings); + &SortDataFile; + $settings{'ACTION'} = 'SORT'; # Recreate 'ACTION' +} + +# Default initial value +if ($settings{'ACTION'} eq '' ) { # First launch from GUI + $settings{'ENABLED'} ='on'; +} + +&Header::openpage($Lang::tr{'external aliases configuration'}, 1, ''); +&Header::openbigbox('100%', 'left', '', $errormessage); +my %checked =(); # Checkbox manipulations + +if ($errormessage) { + &Header::openbox('100%', 'left', $Lang::tr{'error messages'}); + print "$errormessage "; + &Header::closebox(); +} +unless (( $netsettings{'CONFIG_TYPE'} =~ /^(1|2|3|4)$/ ) && ($netsettings{'RED_TYPE'} eq 'STATIC')) +{ + &Header::openbox('100%', 'left', $Lang::tr{'capswarning'}); + print < + + $Lang::tr{'aliases not active'} + + +END +; + &Header::closebox(); +} + +# +# Second check box is for editing the list +# +$checked{'ENABLED'}{'on'} = ($settings{'ENABLED'} eq 'on') ? "checked='checked'" : '' ; + +my $buttontext = $Lang::tr{'add'}; +if ($settings{'KEY1'} ne '') { + $buttontext = $Lang::tr{'update'}; + &Header::openbox('100%', 'left', $Lang::tr{'edit an existing alias'}); +} else { + &Header::openbox('100%', 'left', $Lang::tr{'add new alias'}); +} + +#Edited line number (KEY1) passed until cleared by 'save' or 'remove' or 'new sort order' +print < + + + + + + + + + + +
$Lang::tr{'name'}: *$Lang::tr{'alias ip'}: $Lang::tr{'enabled'} 
+
+ + + + + + +
* $Lang::tr{'this field may be blank'} + +
+ +END +; +&Header::closebox(); + +# Add visual indicators to column headings to show sort order - EO +my $sortarrow1 = ''; +my $sortarrow2 = ''; + +if ($netsettings{'SORT_ALIASES'} eq 'NAMERev') { + $sortarrow1 = $Header::sortdn; +} elsif ($netsettings{'SORT_ALIASES'} eq 'NAME') { + $sortarrow1 = $Header::sortup; +} elsif ($netsettings{'SORT_ALIASES'} eq 'IPRev') { + $sortarrow2 = $Header::sortdn; +} else { + $sortarrow2 = $Header::sortup; +} + +# +# Third box shows the list, in columns +# +# Columns headers may content a link. In this case it must be named in $sortstring +# +&Header::openbox('100%', 'left', $Lang::tr{'current aliases'}); +print < + + $Lang::tr{'name'} $sortarrow1 + $Lang::tr{'alias ip'} $sortarrow2 + $Lang::tr{'action'} + +END +; + +# +# Print each line of @current list +# +# each data line is splitted into @temp. +# + +my $key = 0; +foreach my $line (@current) { + chomp($line); + my @temp = split(/\,/,$line); + + #Choose icon for checkbox + my $gif = ''; + my $gdesc = ''; + if ($temp[1] eq "on") { + $gif = 'on.gif'; + $gdesc = $Lang::tr{'click to disable'}; + } else { + $gif = 'off.gif'; + $gdesc = $Lang::tr{'click to enable'}; + } + + #Colorize each line + if ($settings{'KEY1'} eq $key) { + print ""; + } elsif ($key % 2) { + print ""; + } else { + print ""; + } + + print <$temp[2] +$temp[0] + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + +END +; + $key++; +} +print ""; + +# If table contains entries, print 'Key to action icons' +if ($key) { +print < + +  $Lang::tr{'legend'}:  + $Lang::tr{ + $Lang::tr{'click to disable'} +    + $Lang::tr{ + $Lang::tr{'click to enable'} +    + $Lang::tr{ + $Lang::tr{'edit'} +    + $Lang::tr{ + $Lang::tr{'remove'} + + +END +; +} + +&Header::closebox(); +&Header::closebigbox(); +&Header::closepage(); + +## Ouf it's the end ! + + + +# Sort the "current" array according to choices +sub SortDataFile +{ + our %entries = (); + + # Sort pair of record received in $a $b special vars. + # When IP is specified use numeric sort else alpha. + # If sortname ends with 'Rev', do reverse sort. + # + sub fixedleasesort { + my $qs=''; # The sort field specified minus 'Rev' + if (rindex ($netsettings{'SORT_ALIASES'},'Rev') != -1) { + $qs=substr ($netsettings{'SORT_ALIASES'},0,length($netsettings{'SORT_ALIASES'})-3); + if ($qs eq 'IP') { + my @a = split(/\./,$entries{$a}->{$qs}); + my @b = split(/\./,$entries{$b}->{$qs}); + ($b[0]<=>$a[0]) || + ($b[1]<=>$a[1]) || + ($b[2]<=>$a[2]) || + ($b[3]<=>$a[3]); + } else { + $entries{$b}->{$qs} cmp $entries{$a}->{$qs}; + } + } else { #not reverse + $qs=$netsettings{'SORT_ALIASES'}; + if ($qs eq 'IP') { + my @a = split(/\./,$entries{$a}->{$qs}); + my @b = split(/\./,$entries{$b}->{$qs}); + ($a[0]<=>$b[0]) || + ($a[1]<=>$b[1]) || + ($a[2]<=>$b[2]) || + ($a[3]<=>$b[3]); + } else { + $entries{$a}->{$qs} cmp $entries{$b}->{$qs}; + } + } + } + + #Use an associative array (%entries) + my $key = 0; + foreach my $line (@current) { + chomp( $line); #remove newline because can be on field 5 or 6 (addition of REMARK) + my @temp = split (',',$line); + + # Build a pair 'Field Name',value for each of the data dataline. + # Each SORTABLE field must have is pair. + # Other data fields (non sortable) can be grouped in one + + # Exemple + # F1,F2,F3,F4,F5 only F1 F2 for sorting + # my @record = ('KEY',$key++, + # 'F1',$temp[0], + # 'F2',$temp[1], + # 'DATA',join(',',@temp[2..4]) ); #group remainning values, with separator (,) + + # The KEY,key record permits doublons. If removed, then F1 becomes the key without doublon permitted. + + + my @record = ('KEY',$key++,'IP',$temp[0],'ENABLED',$temp[1],'NAME',$temp[2]); + my $record = {}; # create a reference to empty hash + %{$record} = @record; # populate that hash with @record + $entries{$record->{KEY}} = $record; # add this to a hash of hashes + } + + open(FILE, ">$datafile") or die 'Unable to open aliases file.'; + + # Each field value is printed , with the newline ! Don't forget separator and order of them. + foreach my $entry (sort fixedleasesort keys %entries) { + print FILE "$entries{$entry}->{IP},$entries{$entry}->{ENABLED},$entries{$entry}->{NAME}\n"; + } + + close(FILE); + # Reload sorted @current + open (FILE, "$datafile"); + @current = ; + close (FILE); +} + +# +# Build the configuration file for application aliases +# +sub BuildConfiguration { + # Restart service associated with this + system '/usr/local/bin/setaliases'; +} diff --git a/src/misc-progs/setaliases.c b/src/misc-progs/setaliases.c index a03e148365..ea4bc11dbe 100755 --- a/src/misc-progs/setaliases.c +++ b/src/misc-progs/setaliases.c @@ -1,196 +1,196 @@ -/* - * setaliases - configure red aliased interfaces - * - * This program is distributed under the terms of the GNU General Public - * Licence. See the file COPYING for details. - * - * (c) Steve Bootes, 2002/04/15 - * - * 21/04/03 Robert Kerr Changed to link directly to libsmooth rather than - * using a copy & paste - * - * $Id: setaliases.c,v 1.2.2.5 2006/07/25 23:15:20 franck78 Exp $ - * - */ - -#include "libsmooth.h" -#include "setuid.h" -#include -#include -#include -#include -#include -#include -#include - -struct keyvalue *kv = NULL; -FILE *file = NULL; - -void exithandler(void) -{ - if (kv) freekeyvalues(kv); - if (file) fclose(file); -} - -int main(void) -{ - char s[STRING_SIZE]; - char command[STRING_SIZE]; - char red_netmask[STRING_SIZE]; - char red_broadcast[STRING_SIZE]; - char red_dev[STRING_SIZE]; - char default_gateway[STRING_SIZE]; - char *aliasip; - char *enabled; - char *sptr; - char *comment; - int alias; - int count; - - if (!(initsetuid())) - { - fprintf(stderr, "Cannot run setuid\n"); - exit(1); - } - - atexit(exithandler); - - /* Init the keyvalue structure */ - kv=initkeyvalues(); - - /* Read in the current values */ - if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")) - { - fprintf(stderr, "Cannot read ethernet settings\n"); - exit(1); - } - - /* Find the CONFIG_TYPE value */ - if (!findkey(kv, "CONFIG_TYPE", s)) - { - fprintf(stderr, "Cannot read CONFIG_TYPE\n"); - exit(1); - } - - /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not, - * exit gracefully. This is not an error... */ - if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0))) - exit(0); - - /* Now check the RED_TYPE - aliases only work with STATIC. - * At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */ - - /* Find the RED_TYPE value */ - if (!findkey(kv, "RED_TYPE", s)) - { - fprintf(stderr, "Cannot read RED_TYPE\n"); - exit(1); - } - - /* Make sure it's the right type */ - if (!(strcmp(s, "STATIC")==0)) - exit(0); - - /* Get the RED interface details */ - if((!findkey(kv, "RED_NETMASK", red_netmask)) || (!findkey(kv, "RED_BROADCAST", red_broadcast)) || - (!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway))) - { - fprintf(stderr, "Cannot read RED settings\n"); - exit(1); - } - - if (!VALID_DEVICE(red_dev)) - { - fprintf(stderr, "Bad red_dev: %s\n", red_dev); - exit(1); - } - - if (!VALID_IP(red_netmask)) - { - fprintf(stderr, "Bad red_netmask : %s\n", red_netmask); - exit(1); - } - - if (!VALID_IP(red_broadcast)) - { - fprintf(stderr, "Bad red_broadcast : %s\n", red_broadcast); - exit(1); - } - - if (!VALID_IP(default_gateway)) - { - fprintf(stderr, "Bad default_gateway : %s\n", default_gateway); - exit(1); - } - - /* down the aliases in turn until ifconfig complains */ - alias=0; - do - { - memset(command, 0, STRING_SIZE); - snprintf(command, STRING_SIZE-1, "/sbin/ifconfig %s:%d down 2>/dev/null", red_dev, alias++); - } while (safe_system(command)==0); - - /* Now set up the new aliases from the config file */ - if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r"))) - { - fprintf(stderr, "Unable to open aliases configuration file\n"); - exit(1); - } - - alias=0; - int linecounter = 0; - while (fgets(s, STRING_SIZE, file) != NULL) - { - linecounter++; - if (s[strlen(s) - 1] == '\n') - s[strlen(s) - 1] = '\0'; - count = 0; - aliasip = NULL; - enabled = NULL; - comment = NULL; - sptr = strtok(s, ","); - while (sptr) - { - if (count == 0) - aliasip = sptr; - if (count == 1) - enabled = sptr; - else - comment = sptr; - count++; - sptr = strtok(NULL, ","); - } - - if (!(aliasip && enabled)) { - fprintf(stderr, "Incomplete data line: in %s(%d)\n", - CONFIG_ROOT "/ethernet/aliases", - linecounter); - exit(1); - } - if (!strcmp(enabled, "on") == 0) /* disabled rule? */ - continue; - - if (!VALID_IP(aliasip)) - { - fprintf(stderr, "Bad alias : %s in %s(%d)\n", - aliasip, - CONFIG_ROOT "/ethernet/aliases", - linecounter); - exit(1); - } - - memset(command, 0, STRING_SIZE); - snprintf(command, STRING_SIZE-1, - "/sbin/ifconfig %s:%d %s netmask %s broadcast %s up", - red_dev, alias, aliasip, red_netmask, red_broadcast); - safe_system(command); - memset(command, 0, STRING_SIZE); - snprintf(command, STRING_SIZE-1, - "/usr/sbin/arping -q -c 1 -w 1 -i %s -S %s %s", - red_dev, aliasip, default_gateway); - safe_system(command); - alias++; - } - return 0; -} +/* + * setaliases - configure red aliased interfaces + * + * This program is distributed under the terms of the GNU General Public + * Licence. See the file COPYING for details. + * + * (c) Steve Bootes, 2002/04/15 + * + * 21/04/03 Robert Kerr Changed to link directly to libsmooth rather than + * using a copy & paste + * + * $Id: setaliases.c,v 1.2.2.5 2006/07/25 23:15:20 franck78 Exp $ + * + */ + +#include "libsmooth.h" +#include "setuid.h" +#include +#include +#include +#include +#include +#include +#include + +struct keyvalue *kv = NULL; +FILE *file = NULL; + +void exithandler(void) +{ + if (kv) freekeyvalues(kv); + if (file) fclose(file); +} + +int main(void) +{ + char s[STRING_SIZE]; + char command[STRING_SIZE]; + char red_netmask[STRING_SIZE]; + char red_broadcast[STRING_SIZE]; + char red_dev[STRING_SIZE]; + char default_gateway[STRING_SIZE]; + char *aliasip; + char *enabled; + char *sptr; + char *comment; + int alias; + int count; + + if (!(initsetuid())) + { + fprintf(stderr, "Cannot run setuid\n"); + exit(1); + } + + atexit(exithandler); + + /* Init the keyvalue structure */ + kv=initkeyvalues(); + + /* Read in the current values */ + if (!readkeyvalues(kv, CONFIG_ROOT "/ethernet/settings")) + { + fprintf(stderr, "Cannot read ethernet settings\n"); + exit(1); + } + + /* Find the CONFIG_TYPE value */ + if (!findkey(kv, "CONFIG_TYPE", s)) + { + fprintf(stderr, "Cannot read CONFIG_TYPE\n"); + exit(1); + } + + /* Check for CONFIG_TYPE=2 or 3 i.e. RED ethernet present. If not, + * exit gracefully. This is not an error... */ + if (!((strcmp(s, "1")==0) || (strcmp(s, "2")==0) || (strcmp(s, "3")==0) || (strcmp(s, "4")==0))) + exit(0); + + /* Now check the RED_TYPE - aliases only work with STATIC. + * At least, that's what /etc/rc.d/rc.netaddress.up thinks.. */ + + /* Find the RED_TYPE value */ + if (!findkey(kv, "RED_TYPE", s)) + { + fprintf(stderr, "Cannot read RED_TYPE\n"); + exit(1); + } + + /* Make sure it's the right type */ + if (!(strcmp(s, "STATIC")==0)) + exit(0); + + /* Get the RED interface details */ + if((!findkey(kv, "RED_NETMASK", red_netmask)) || (!findkey(kv, "RED_BROADCAST", red_broadcast)) || + (!findkey(kv, "RED_DEV", red_dev)) || (!findkey(kv, "DEFAULT_GATEWAY", default_gateway))) + { + fprintf(stderr, "Cannot read RED settings\n"); + exit(1); + } + + if (!VALID_DEVICE(red_dev)) + { + fprintf(stderr, "Bad red_dev: %s\n", red_dev); + exit(1); + } + + if (!VALID_IP(red_netmask)) + { + fprintf(stderr, "Bad red_netmask : %s\n", red_netmask); + exit(1); + } + + if (!VALID_IP(red_broadcast)) + { + fprintf(stderr, "Bad red_broadcast : %s\n", red_broadcast); + exit(1); + } + + if (!VALID_IP(default_gateway)) + { + fprintf(stderr, "Bad default_gateway : %s\n", default_gateway); + exit(1); + } + + /* down the aliases in turn until ifconfig complains */ + alias=0; + do + { + memset(command, 0, STRING_SIZE); + snprintf(command, STRING_SIZE-1, "/sbin/ifconfig %s:%d down 2>/dev/null", red_dev, alias++); + } while (safe_system(command)==0); + + /* Now set up the new aliases from the config file */ + if (!(file = fopen(CONFIG_ROOT "/ethernet/aliases", "r"))) + { + fprintf(stderr, "Unable to open aliases configuration file\n"); + exit(1); + } + + alias=0; + int linecounter = 0; + while (fgets(s, STRING_SIZE, file) != NULL) + { + linecounter++; + if (s[strlen(s) - 1] == '\n') + s[strlen(s) - 1] = '\0'; + count = 0; + aliasip = NULL; + enabled = NULL; + comment = NULL; + sptr = strtok(s, ","); + while (sptr) + { + if (count == 0) + aliasip = sptr; + if (count == 1) + enabled = sptr; + else + comment = sptr; + count++; + sptr = strtok(NULL, ","); + } + + if (!(aliasip && enabled)) { + fprintf(stderr, "Incomplete data line: in %s(%d)\n", + CONFIG_ROOT "/ethernet/aliases", + linecounter); + exit(1); + } + if (!strcmp(enabled, "on") == 0) /* disabled rule? */ + continue; + + if (!VALID_IP(aliasip)) + { + fprintf(stderr, "Bad alias : %s in %s(%d)\n", + aliasip, + CONFIG_ROOT "/ethernet/aliases", + linecounter); + exit(1); + } + + memset(command, 0, STRING_SIZE); + snprintf(command, STRING_SIZE-1, + "/sbin/ifconfig %s:%d %s netmask %s broadcast %s up", + red_dev, alias, aliasip, red_netmask, red_broadcast); + safe_system(command); + memset(command, 0, STRING_SIZE); + snprintf(command, STRING_SIZE-1, + "/usr/sbin/arping -q -c 1 -w 1 -i %s -S %s %s", + red_dev, aliasip, default_gateway); + safe_system(command); + alias++; + } + return 0; +} -- 2.39.2