]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - html/cgi-bin/hosts.cgi
immernoch das alte Problem...
[people/teissler/ipfire-2.x.git] / html / cgi-bin / hosts.cgi
CommitLineData
cd1a2927
MT
1#!/usr/bin/perl\r
2#\r
3# IPCop CGIs\r
4#\r
5# This code is distributed under the terms of the GPL\r
6#\r
7# (c) Alan Hourihane <alanh@fairlite.demon.co.uk>\r
8#\r
9# $Id: hosts.cgi,v 1.4.2.20 2005/11/05 15:46:25 gespinasse Exp $\r
10#\r
11# Franck\r
12# use dhcp.cgi model to rewrite this code\r
13\r
14use strict;\r
15\r
16# enable only the following on debugging purpose\r
17#use warnings;\r
18#use CGI::Carp 'fatalsToBrowser';\r
19\r
20require 'CONFIG_ROOT/general-functions.pl';\r
21require "${General::swroot}/lang.pl";\r
22require "${General::swroot}/header.pl";\r
23\r
24#workaround to suppress a warning when a variable is used only once\r
25my @dummy = ( ${Header::colouryellow} );\r
26undef (@dummy);\r
27\r
28# Files used\r
29my $setting = "${General::swroot}/main/settings";\r
30our $datafile = "${General::swroot}/main/hosts"; #(our: used in subroutine)\r
31\r
32our %settings = ();\r
33#Settings1\r
34# removed\r
35\r
36#Settings2 for editing the multi-line list\r
37#Must not be saved !\r
38$settings{'EN'} = ''; # reuse for dummy field in position zero\r
39$settings{'IP'} = '';\r
40$settings{'HOST'} = ''; \r
41$settings{'DOM'} = ''; \r
42my @nosaved=('EN','IP','HOST','DOM'); # List here ALL setting2 fields. Mandatory\r
43 \r
44$settings{'ACTION'} = ''; # add/edit/remove\r
45$settings{'KEY1'} = ''; # point record for ACTION\r
46\r
47#Define each field that can be used to sort columns\r
48my $sortstring='^IP|^HOST|^DOM';\r
49$settings{'SORT_HOSTSLIST'} = 'HOST';\r
50my $errormessage = '';\r
51my $warnmessage = '';\r
52\r
53&Header::showhttpheaders();\r
54\r
55#Get GUI values\r
56&Header::getcgihash(\%settings);\r
57\r
58# Load multiline data\r
59our @current = ();\r
60if (open(FILE, "$datafile")) {\r
61 @current = <FILE>;\r
62 close (FILE);\r
63}\r
64\r
65## Settings1 Box not used...\r
66&General::readhash("${General::swroot}/main/settings", \%settings);\r
67\r
68\r
69## Now manipulate the multi-line list with Settings2\r
70# Basic actions are:\r
71# toggle the check box\r
72# add/update a new line\r
73# begin editing a line\r
74# remove a line\r
75\r
76\r
77# Toggle enable/disable field. Field is in second position\r
78if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {\r
79 #move out new line\r
80 chomp(@current[$settings{'KEY1'}]);\r
81 my @temp = split(/\,/,@current[$settings{'KEY1'}]);\r
82\r
83 $temp[0] = $temp[0] ne '' ? '' : 'on'; # Toggle the field\r
84 @current[$settings{'KEY1'}] = join (',',@temp)."\n";\r
85 $settings{'KEY1'} = ''; # End edit mode\r
86 \r
87 &General::log($Lang::tr{'hosts config changed'});\r
88\r
89 #Save current\r
90 open(FILE, ">$datafile") or die 'hosts datafile error';\r
91 print FILE @current;\r
92 close(FILE);\r
93 \r
94 # Rebuild configuration file\r
95 &BuildConfiguration;\r
96}\r
97\r
98if ($settings{'ACTION'} eq $Lang::tr{'add'}) {\r
99 # Validate inputs\r
100 unless(&General::validip($settings{'IP'})) {\r
101 $errormessage = $Lang::tr{'invalid fixed ip address'};\r
102 }\r
103\r
104 unless(&General::validhostname($settings{'HOST'})) {\r
105 $errormessage = $Lang::tr{'invalid hostname'};\r
106 }\r
107\r
108 if ($settings{'DOM'} && ! &General::validdomainname($settings{'DOM'})) {\r
109 $errormessage = $Lang::tr{'invalid domain name'};\r
110 }\r
111\r
112\r
113 unless ($errormessage) {\r
114 if ($settings{'KEY1'} eq '') { #add or edit ?\r
115 unshift (@current, "$settings{'EN'},$settings{'IP'},$settings{'HOST'},$settings{'DOM'}\n");\r
116 &General::log($Lang::tr{'hosts config added'});\r
117 } else {\r
118 @current[$settings{'KEY1'}] = "$settings{'EN'},$settings{'IP'},$settings{'HOST'},$settings{'DOM'}\n";\r
119 $settings{'KEY1'} = ''; # End edit mode\r
120 &General::log($Lang::tr{'hosts config changed'});\r
121 }\r
122\r
123 # Write changes to config file.\r
124 &SortDataFile; # sort newly added/modified entry\r
125 &BuildConfiguration; # then re-build new host\r
126 \r
127 #map ($settings{$_}='' ,@nosaved); # Clear fields\r
128 }\r
129}\r
130\r
131if ($settings{'ACTION'} eq $Lang::tr{'edit'}) {\r
132 #move out new line\r
133 my $line = @current[$settings{'KEY1'}]; # KEY1 is the index in current\r
134 chomp($line);\r
135 my @temp = split(/\,/, $line);\r
136 $settings{'EN'}=$temp[0]; # Prepare the screen for editing\r
137 $settings{'IP'}=$temp[1];\r
138 $settings{'HOST'}=$temp[2];\r
139 $settings{'DOM'}=$temp[3];\r
140}\r
141\r
142if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {\r
143 splice (@current,$settings{'KEY1'},1); # Delete line \r
144 open(FILE, ">$datafile") or die 'hosts datafile error';\r
145 print FILE @current;\r
146 close(FILE);\r
147 $settings{'KEY1'} = ''; # End remove mode\r
148 &General::log($Lang::tr{'hosts config changed'});\r
149\r
150 &BuildConfiguration; # then re-build conf which use new data\r
151}\r
152\r
153\r
154\r
155## Check if sorting is asked\r
156# If same column clicked, reverse the sort.\r
157if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) {\r
158 my $newsort=$ENV{'QUERY_STRING'};\r
159 my $actual=$settings{'SORT_HOSTSLIST'};\r
160 #Reverse actual sort ?\r
161 if ($actual =~ $newsort) {\r
162 my $Rev='';\r
163 if ($actual !~ 'Rev') {\r
164 $Rev='Rev';\r
165 }\r
166 $newsort.=$Rev;\r
167 }\r
168 $settings{'SORT_HOSTSLIST'}=$newsort;\r
169 map (delete ($settings{$_}) ,(@nosaved,'ACTION','KEY1'));# Must never be saved\r
170 &General::writehash($setting, \%settings);\r
171 &SortDataFile;\r
172 $settings{'ACTION'} = 'SORT'; # Create an 'ACTION'\r
173 map ($settings{$_} = '' ,@nosaved,'KEY1'); # and reinit vars to empty\r
174}\r
175\r
176if ($settings{'ACTION'} eq '' ) { # First launch from GUI\r
177 # Place here default value when nothing is initialized\r
178 $settings{'EN'} = 'on';\r
179 $settings{'DOM'} = $settings{'DOMAINNAME'};\r
180}\r
181\r
182&Header::openpage($Lang::tr{'hostname'}, 1, '');\r
183&Header::openbigbox('100%', 'left', '', $errormessage);\r
184my %checked=(); # Checkbox manipulations\r
185\r
186if ($errormessage) {\r
187 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});\r
188 print "<font class='base'>$errormessage&nbsp;</font>";\r
189 &Header::closebox();\r
190}\r
191\r
192#\r
193# Remove if no Setting1 needed\r
194#\r
195#if ($warnmessage) {\r
196# $warnmessage = "<font color=${Header::colourred}><b>$Lang::tr{'capswarning'}</b></font>: $warnmessage";\r
197#}\r
198#&Header::openbox('100%', 'left', $Lang::tr{'settings'});\r
199#print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>";\r
200#print <<END\r
201#<table width='100%'>\r
202#<tr>\r
203# <td class='base'>$Lang::tr{'domain name'} : $settings{'DOMAINNAME'}</td>\r
204#</table>\r
205#\r
206#END\r
207#;\r
208#\r
209#print <<END\r
210#<table width='100%'>\r
211#<hr />\r
212#<tr>\r
213# <td class='base' width='25%'><!--<img src='/blob.gif' align='top' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td>-->\r
214# <td class='base' width='25%'>$warnmessage</td>\r
215# <td width='50%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' disabled='disabled' /></td>\r
216#</tr>\r
217#</table>\r
218#</form>\r
219#END\r
220#;\r
221#&Header::closebox(); # end of Settings1\r
222\r
223\r
224#\r
225# Second check box is for editing the list\r
226#\r
227$checked{'EN'}{'on'} = ($settings{'EN'} eq '' ) ? '' : "checked='checked'";\r
228\r
229my $buttontext = $Lang::tr{'add'};\r
230if ($settings{'KEY1'} ne '') {\r
231 $buttontext = $Lang::tr{'update'};\r
232 &Header::openbox('100%', 'left', $Lang::tr{'edit an existing host'});\r
233} else {\r
234 &Header::openbox('100%', 'left', $Lang::tr{'add a host'});\r
235}\r
236\r
237#Edited line number (KEY1) passed until cleared by 'save' or 'remove' or 'new sort order'\r
238print <<END\r
239<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
240<input type='hidden' name='KEY1' value='$settings{'KEY1'}' />\r
241<table width='100%'>\r
242<tr>\r
243 <td class='base'>$Lang::tr{'host ip'}:&nbsp;</td>\r
244 <td><input type='text' name='IP' value='$settings{'IP'}' /></td>\r
245 <td class='base'>$Lang::tr{'hostname'}:</td>\r
246 <td><input type='text' name='HOST' value='$settings{'HOST'}' /></td>\r
247</tr><tr>\r
248 <td class='base'>$Lang::tr{'domain name'}:&nbsp;<img src='/blob.gif' alt='*' /></td>\r
249 <td><input type='text' name='DOM' value='$settings{'DOM'}' /></td>\r
250 <td class='base'>$Lang::tr{'enabled'}</td>\r
251 <td><input type='checkbox' name='EN' $checked{'EN'}{'on'} /></td>\r
252</tr>\r
253</table>\r
254<hr />\r
255<table width='100%'>\r
256<tr>\r
257 <td class='base' width='50%'><img src='/blob.gif' align='top' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td>\r
258 <td width='50%' align='center'><input type='hidden' name='ACTION' value='$Lang::tr{'add'}' /><input type='submit' name='SUBMIT' value='$buttontext' /></td>\r
259</tr>\r
260</table>\r
261</form>\r
262END\r
263;\r
264&Header::closebox();\r
265\r
266#\r
267# Third box shows the list, in columns\r
268#\r
269# Columns headers may content a link. In this case it must be named in $sortstring\r
270#\r
271&Header::openbox('100%', 'left', $Lang::tr{'current hosts'});\r
272print <<END\r
273<table width='100%'>\r
274<tr>\r
275 <td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IP'><b>$Lang::tr{'host ip'}</b></a></td>\r
276 <td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?HOST'><b>$Lang::tr{'hostname'}</b></a></td>\r
277 <td width='50%' align='center'><a href='$ENV{'SCRIPT_NAME'}?DOM'><b>$Lang::tr{'domain name'}</b></a></td>\r
278 <td width='10%' colspan='3' class='boldbase' align='center'><b>$Lang::tr{'action'}</b></td>\r
279</tr>\r
280END\r
281;\r
282\r
283#\r
284# Print each line of @current list\r
285#\r
286\r
287my $key = 0;\r
288foreach my $line (@current) {\r
289 chomp($line); # remove newline\r
290 my @temp=split(/\,/,$line);\r
291 $temp[3] ='' unless defined $temp[3]; # not always populated\r
292\r
293 #Choose icon for checkbox\r
294 my $gif = '';\r
295 my $gdesc = '';\r
296 if ($temp[0] ne '' ) {\r
297 $gif = 'on.gif';\r
298 $gdesc = $Lang::tr{'click to disable'};\r
299 } else {\r
300 $gif = 'off.gif';\r
301 $gdesc = $Lang::tr{'click to enable'}; \r
302 }\r
303\r
304 #Colorize each line\r
305 if ($settings{'KEY1'} eq $key) {\r
306 print "<tr bgcolor='${Header::colouryellow}'>";\r
307 } elsif ($key % 2) {\r
308 print "<tr bgcolor='${Header::table2colour}'>";\r
309 } else {\r
310 print "<tr bgcolor='${Header::table1colour}'>"; \r
311 }\r
312 print <<END\r
313<td align='center'>$temp[1]</td>\r
314<td align='center'>$temp[2]</td>\r
315<td align='center'>$temp[3]</td>\r
316<td align='center'>\r
317<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
318<input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />\r
319<input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc' />\r
320<input type='hidden' name='KEY1' value='$key' />\r
321</form>\r
322</td>\r
323\r
324<td align='center'>\r
325<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
326<input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />\r
327<input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />\r
328<input type='hidden' name='KEY1' value='$key' />\r
329</form>\r
330</td>\r
331\r
332<td align='center'>\r
333<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
334<input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />\r
335<input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />\r
336<input type='hidden' name='KEY1' value='$key' />\r
337</form>\r
338</td>\r
339</tr>\r
340END\r
341;\r
342 $key++;\r
343}\r
344print "</table>";\r
345\r
346# If table contains entries, print 'Key to action icons'\r
347if ($key) {\r
348print <<END\r
349<table>\r
350<tr>\r
351 <td class='boldbase'>&nbsp;<b>$Lang::tr{'legend'}:&nbsp;</b></td>\r
352 <td><img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>\r
353 <td class='base'>$Lang::tr{'click to disable'}</td>\r
354 <td>&nbsp;&nbsp;</td>\r
355 <td><img src='/images/off.gif' alt='$Lang::tr{'click to enable'}' /></td>\r
356 <td class='base'>$Lang::tr{'click to enable'}</td>\r
357 <td>&nbsp;&nbsp;</td>\r
358 <td><img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>\r
359 <td class='base'>$Lang::tr{'edit'}</td>\r
360 <td>&nbsp;&nbsp;</td>\r
361 <td><img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>\r
362 <td class='base'>$Lang::tr{'remove'}</td>\r
363</tr>\r
364</table>\r
365END\r
366;\r
367}\r
368\r
369&Header::closebox();\r
370&Header::closebigbox();\r
371&Header::closepage();\r
372\r
373## Ouf it's the end !\r
374\r
375# Sort the "current" array according to choices\r
376sub SortDataFile\r
377{\r
378 our %entries = ();\r
379 \r
380 # Sort pair of record received in $a $b special vars.\r
381 # When IP is specified use numeric sort else alpha.\r
382 # If sortname ends with 'Rev', do reverse sort.\r
383 #\r
384 sub fixedleasesort {\r
385 my $qs=''; # The sort field specified minus 'Rev'\r
386 if (rindex ($settings{'SORT_HOSTSLIST'},'Rev') != -1) {\r
387 $qs=substr ($settings{'SORT_HOSTSLIST'},0,length($settings{'SORT_HOSTSLIST'})-3);\r
388 if ($qs eq 'IP') {\r
389 my @a = split(/\./,$entries{$a}->{$qs});\r
390 my @b = split(/\./,$entries{$b}->{$qs});\r
391 ($b[0]<=>$a[0]) ||\r
392 ($b[1]<=>$a[1]) ||\r
393 ($b[2]<=>$a[2]) ||\r
394 ($b[3]<=>$a[3]);\r
395 } else {\r
396 $entries{$b}->{$qs} cmp $entries{$a}->{$qs};\r
397 }\r
398 } else { #not reverse\r
399 $qs=$settings{'SORT_HOSTSLIST'};\r
400 if ($qs eq 'IP') {\r
401 my @a = split(/\./,$entries{$a}->{$qs});\r
402 my @b = split(/\./,$entries{$b}->{$qs});\r
403 ($a[0]<=>$b[0]) ||\r
404 ($a[1]<=>$b[1]) ||\r
405 ($a[2]<=>$b[2]) ||\r
406 ($a[3]<=>$b[3]);\r
407 } else {\r
408 $entries{$a}->{$qs} cmp $entries{$b}->{$qs};\r
409 }\r
410 }\r
411 }\r
412\r
413 #Use an associative array (%entries)\r
414 my $key = 0;\r
415 foreach my $line (@current) {\r
416 chomp( $line); #remove newline because can be on field 5 or 6 (addition of REMARK)\r
417 my @temp = ( '','','', '');\r
418 @temp = split (',',$line);\r
419\r
420 # Build a pair 'Field Name',value for each of the data dataline.\r
421 # Each SORTABLE field must have is pair.\r
422 # Other data fields (non sortable) can be grouped in one\r
423 \r
424 my @record = ('KEY',$key++,'EN',$temp[0],'IP',$temp[1],'HOST',$temp[2],'DOM',$temp[3]);\r
425 my $record = {}; # create a reference to empty hash\r
426 %{$record} = @record; # populate that hash with @record\r
427 $entries{$record->{KEY}} = $record; # add this to a hash of hashes\r
428 }\r
429 \r
430 open(FILE, ">$datafile") or die 'hosts datafile error';\r
431\r
432 # Each field value is printed , with the newline ! Don't forget separator and order of them.\r
433 foreach my $entry (sort fixedleasesort keys %entries) {\r
434 print FILE "$entries{$entry}->{EN},$entries{$entry}->{IP},$entries{$entry}->{HOST},$entries{$entry}->{DOM}\n";\r
435 }\r
436\r
437 close(FILE);\r
438 # Reload sorted @current\r
439 open (FILE, "$datafile");\r
440 @current = <FILE>;\r
441 close (FILE);\r
442}\r
443\r
444#\r
445# Build the configuration file\r
446#\r
447sub BuildConfiguration {\r
448 system '/usr/local/bin/rebuildhosts';\r
449}\r