]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - html/cgi-bin/base.cgi
git-svn-id: http://svn.ipfire.org/svn/ipfire/IPFire/source@16 ea5c0bd1-69bd-2848...
[people/pmueller/ipfire-2.x.git] / html / cgi-bin / base.cgi
CommitLineData
cd1a2927
MT
1#!/usr/bin/perl\r
2#\r
3# IPCop CGI's - base.cgi\r
4#\r
5# This code is distributed under the terms of the GPL\r
6#\r
7# (c) place a name here\r
8#\r
9# $Id: base.cgi,v 1.1.2.10 2005/11/03 19:20:50 franck78 Exp $\r
10#\r
11#\r
12\r
13\r
14# This file is a starting base for writting a new GUI screen using the three box model\r
15# Box 1 : global settings for the application\r
16# Box 2 : line editor for multiple data line\r
17# Box 3 : the list of data line, with edit/remove buttons\r
18#\r
19# This example do the following\r
20# Read global settings:\r
21# a NAME and an interface (IT)\r
22# Lines of data composed of:\r
23# an ipaddress (IP), an enabled/disabled options (CB), a comment (CO)\r
24#\r
25#\r
26# All you need to do is\r
27# replace 'XY' with your app name\r
28# define your global $settings{'var name'}\r
29# define your strings\r
30# write validation code for Settings1 and Settings2\r
31# write HTML box Settings1 and Settings2\r
32# adapt the sort function\r
33# write the correct configuration file\r
34#\r
35#\r
36# to fully troubleshot your code, uncomment diagnostics, Carp and cluck lines\r
37# use diagnostics; # need to add the file /usr/lib/perl5/5.8.x/pods/perldiag.pod before to work\r
38# next look at /var/log/httpd/error_log , http://www.perl.com/pub/a/2002/05/07/mod_perl.html may help\r
39#use warnings;\r
40use strict;\r
41#use Carp ();\r
42#local $SIG{__WARN__} = \&Carp::cluck;\r
43\r
44require '/var/ipcop/general-functions.pl'; # Replace all occurences of </var/ipcop> with CONFIG_ROOT\r
45 # before updating cvs IPCop file.\r
46require "${General::swroot}/lang.pl";\r
47require "${General::swroot}/header.pl";\r
48\r
49# Files used\r
50our $setting = "${General::swroot}/XY/settings"; # particular settings\r
51my $datafile = "${General::swroot}/XY/data"; # repeted settings (multilines)\r
52our $conffile = "${General::swroot}/XY/XY.conf"; # Config file for application XY\r
53\r
54# strings to add to languages databases or in addon language file\r
55$Lang::tr{'XY title'} = 'XY service';\r
56$Lang::tr{'XY settings'} = 'XY setup';\r
57$Lang::tr{'XY add data'} = 'add data';\r
58$Lang::tr{'XY edit data'} = 'edit data';\r
59$Lang::tr{'XY data'} = 'XY data';\r
60\r
61# informationnal & log strings, no translation required\r
62my $msg_added = 'XY added';\r
63my $msg_modified = 'XY modified';\r
64my $msg_deleted = 'XY removed';\r
65my $msg_datafileerror = 'XY data file error';\r
66our $msg_configfileerror = 'XY configuration file error';\r
67\r
68my %settings=();\r
69\r
70# Settings1\r
71$settings{'NAME'} = ''; # a string field than must be 'GOOD' or 'good'\r
72$settings{'IT'} = ''; # a 'choose' field for color interface\r
73$settings{'TURBO'} = 'off'; # a checkbox field to enable something\r
74\r
75# Settings2 for editing the multi-line list\r
76# Must not be saved by writehash !\r
77$settings{'IP'} = ''; # datalines are: IPaddress,enable,comment \r
78$settings{'CB'} = 'off'; # Every check box must be set to off\r
79$settings{'COMMENT'} = '';\r
80my @nosaved=('IP','CB','COMMENT'); # List here ALL setting2 fields. Mandatory\r
81\r
82$settings{'ACTION'} = ''; # add/edit/remove....\r
83$settings{'KEY1'} = ''; # point record for ACTION\r
84\r
85# Define each field that can be used to sort columns\r
86my $sortstring='^IP|^COMMENT';\r
87my $errormessage = '';\r
88my $warnmessage = '';\r
89\r
90&Header::showhttpheaders();\r
91\r
92# Read needed Ipcop settings (exemple)\r
93my %mainsettings=();\r
94&General::readhash("${General::swroot}/main/settings", \%mainsettings);\r
95\r
96# Get GUI values\r
97&Header::getcgihash(\%settings);\r
98\r
99# Load multiline data. Do it before use in save action\r
100our $f = new Multilines (filename => $datafile,\r
101 fields => ['IP','CB','COMMENT'],\r
102 comment => 1\r
103 );\r
104\r
105##\r
106## SAVE Settings1 \r
107##\r
108# Remove if no Settings1 needed\r
109if ($settings{'ACTION'} eq $Lang::tr{'save'}) {\r
110\r
111 #\r
112 #Validate static Settings1 here\r
113 #\r
114 if (($settings{"NAME"} ne "GOOD") &&\r
115 ($settings{"NAME"} ne "good")) {\r
116 $errormessage = 'Enter good or GOOD in Name field';\r
117 }\r
118\r
119 unless ($errormessage) { # Everything is ok, save settings\r
120 map (delete ($settings{$_}) ,(@nosaved,'ACTION','KEY1'));# Must never be saved\r
121 &General::writehash($setting, \%settings); # Save good settings\r
122 $settings{'ACTION'} = $Lang::tr{'save'}; # Recreate 'ACTION'\r
123 map ($settings{$_}= '',(@nosaved,'KEY1')); # and reinit var to empty\r
124\r
125 # Rebuild configuration file if needed\r
126 &BuildConfiguration;\r
127 }\r
128\r
129 ERROR: # Leave the faulty field untouched\r
130} else {\r
131 &General::readhash($setting, \%settings); # Get saved settings and reset to good if needed\r
132}\r
133\r
134##\r
135## Now manipulate the multiline list with Settings2\r
136##\r
137\r
138# Basic actions are:\r
139# toggle the check box\r
140# add/update a new line\r
141# begin editing a line\r
142# remove a line\r
143# $KEY1 contains the index of the line manipulated\r
144\r
145##\r
146## Toggle CB field.\r
147##\r
148if ($settings{'ACTION'} eq $Lang::tr{'toggle enable disable'}) {\r
149\r
150 $f->togglebyfields($settings{'KEY1'},'CB'); # toggle checkbox\r
151 $settings{'KEY1'} = ''; # End edit mode\r
152\r
153 &General::log($msg_modified);\r
154\r
155 # save changes\r
156 $f->savedata || die "$msg_datafileerror";\r
157\r
158 # Rebuild configuration file\r
159 &BuildConfiguration;\r
160}\r
161\r
162##\r
163## ADD/UPDATE a line of configuration from Settings2\r
164##\r
165if ($settings{'ACTION'} eq $Lang::tr{'add'}) {\r
166 # Validate inputs\r
167 if (! &General::validip($settings{'IP'})) {$errormessage = "Specify an IP value !"};\r
168 if (! $settings{'COMMENT'} ) {$warnmessage = "no comment specified"};\r
169\r
170 unless ($errormessage) {\r
171 if ($settings{'KEY1'} eq '') { #add or edit ?\r
172 # insert new data line\r
173 $f->writedata(-1, $settings{'IP'},$settings{'CB'},$settings{'COMMENT'});\r
174 &General::log($msg_added);\r
175 } else {\r
176 # modify data line\r
177 $f->writedata($settings{'KEY1'}, $settings{'IP'},$settings{'CB'},$settings{'COMMENT'});\r
178 $settings{'KEY1'} = ''; # End edit mode\r
179 &General::log($msg_modified);\r
180 }\r
181 # save changes\r
182 $f->savedata || die "$msg_datafileerror";\r
183\r
184 # Rebuild configuration file\r
185 &BuildConfiguration;\r
186\r
187 # if entering data line is a repetitive task, choose here to not erase fields between each addition\r
188 map ($settings{$_}='' ,@nosaved);\r
189 }\r
190}\r
191\r
192##\r
193## begin EDIT: move data fields to Settings2 controls\r
194##\r
195if ($settings{'ACTION'} eq $Lang::tr{'edit'}) {\r
196 $f->readdata ($settings{'KEY1'},\r
197 $settings{'IP'},\r
198 $settings{'CB'},\r
199 $settings{'COMMENT'});\r
200}\r
201##\r
202## REMOVE: remove selected line\r
203##\r
204if ($settings{'ACTION'} eq $Lang::tr{'remove'}) {\r
205 $f->deleteline ($settings{'KEY1'});\r
206 $settings{'KEY1'} = ''; # End remove mode\r
207 &General::log($msg_deleted);\r
208\r
209 # save changes\r
210 $f->savedata || die "$msg_datafileerror";\r
211\r
212 # Rebuild configuration file\r
213 &BuildConfiguration;\r
214}\r
215\r
216\r
217##\r
218## Check if sorting is asked\r
219##\r
220if ($ENV{'QUERY_STRING'} =~ /$sortstring/ ) {\r
221 my $newsort=$ENV{'QUERY_STRING'};\r
222 my $actual=$settings{'SORT_XY'};\r
223\r
224 # Reverse actual sort or choose new column ?\r
225 if ($actual =~ $newsort) {\r
226 $f->setsortorder ($newsort ,rindex($actual,'Rev'));\r
227 $newsort .= rindex($actual,'Rev')==-1 ? 'Rev' : '';\r
228 } else {\r
229 $f->setsortorder ($newsort ,1);\r
230 }\r
231 $f->savedata; # Synchronise file & display\r
232 $settings{'SORT_XY'} = $newsort;\r
233 map (delete ($settings{$_}) ,(@nosaved,'ACTION','KEY1')); # Must never be saved\r
234 &General::writehash($setting, \%settings);\r
235 $settings{'ACTION'} = 'SORT'; # Recreate an 'ACTION'\r
236 map ($settings{$_}= '',(@nosaved,,'KEY1')); # and reinit var to empty\r
237}\r
238\r
239##\r
240## Remove if no Setting1 needed\r
241##\r
242if ($settings{'ACTION'} eq '' ) { # First launch from GUI\r
243 # Place here default value when nothing is initialized\r
244\r
245}\r
246\r
247&Header::openpage($Lang::tr{'XY title'}, 1, '');\r
248&Header::openbigbox('100%', 'left', '', $errormessage);\r
249my %checked =(); # Checkbox manipulations\r
250\r
251if ($errormessage) {\r
252 &Header::openbox('100%', 'left', $Lang::tr{'error messages'});\r
253 print "<font class='base'>$errormessage&nbsp;</font>";\r
254 &Header::closebox();\r
255}\r
256\r
257##\r
258## First box Settings1. Remove if not needed\r
259##\r
260$warnmessage = "<font color=${Header::colourred}><b>$Lang::tr{'capswarning'}</b></font>: $warnmessage" if ($warnmessage);\r
261\r
262&Header::openbox('100%', 'left', $Lang::tr{'XY settings'});\r
263print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>";\r
264$checked{'IT'}{'RED'} = '';\r
265$checked{'IT'}{'GREEN'} = '';\r
266$checked{'IT'}{'ORANGE'} = '';\r
267$checked{'IT'}{'BLUE'} = '';\r
268$checked{'IT'}{$settings{'IT'}} = "checked='checked'";\r
269$checked{'TURBO'} = ($settings{'TURBO'} eq 'on') ? "checked='checked'" : '';\r
270\r
271print<<END\r
272<table width='100%'>\r
273<tr>\r
274 <td class='base'>Name:</td>\r
275 <td><input type='text' name='NAME' value='$settings{'NAME'}' /></td>\r
276 <td align='right'>INTERFACE</td>\r
277 <td align='right'>red<input type='radio' name='IT' value='RED' $checked{'IT'}{'RED'} /></td>\r
278</tr><tr>\r
279 <td>Turbo:</td>\r
280 <td><input type='checkbox' name='TURBO' $checked{'TURBO'}' /></td>\r
281 <td></td>\r
282 <td align='right'>green<input type='radio' name='IT' value='GREEN' $checked{'IT'}{'GREEN'} /></td>\r
283</tr><tr>\r
284 <td></td>\r
285 <td></td>\r
286 <td></td>\r
287 <td align='right'>blue<input type='radio' name='IT' value='BLUE' $checked{'IT'}{'BLUE'} /></td>\r
288</tr><tr>\r
289 <td></td>\r
290 <td></td>\r
291 <td></td>\r
292 <td align='right'>orange<input type='radio' name='IT' value='ORANGE' $checked{'IT'}{'ORANGE'} /></td>\r
293</tr>\r
294</table>\r
295<br />\r
296END\r
297;\r
298\r
299print<<END\r
300<table width='100%'>\r
301<hr />\r
302<tr>\r
303 <td class='base' width='25%'><img src='/blob.gif' align='top' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td>\r
304 <td class='base' width='25%'>$warnmessage</td>\r
305 <td width='50%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td>\r
306</tr>\r
307</table>\r
308</form>\r
309END\r
310;\r
311&Header::closebox(); # end of Settings1\r
312\r
313##\r
314## Second box is for editing the an item of the list\r
315##\r
316$checked{'CB'} = ($settings{'CB'} eq 'on') ? "checked='checked'" : '';\r
317\r
318my $buttontext = $Lang::tr{'add'};\r
319if ($settings{'KEY1'} ne '') {\r
320 $buttontext = $Lang::tr{'update'};\r
321 &Header::openbox('100%', 'left', $Lang::tr{'XY edit data'});\r
322} else {\r
323 &Header::openbox('100%', 'left', $Lang::tr{'XY add data'});\r
324}\r
325\r
326# Edited line number (KEY1) passed until cleared by 'save' or 'remove' or 'new sort order'\r
327print <<END\r
328<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
329<input type='hidden' name='KEY1' value='$settings{'KEY1'}' />\r
330<table width='100%'>\r
331<tr>\r
332 <td class='base'>$Lang::tr{'ip address'}:</td>\r
333 <td><input type='text' name='IP' value='$settings{'IP'}' /></td>\r
334 <td class='base'>$Lang::tr{'enabled'}</td>\r
335 <td><input type='checkbox' name='CB' $checked{'CB'} /></td>\r
336 <td class='base'>$Lang::tr{'remark'}:&nbsp;<img src='/blob.gif' alt='*' /></td>\r
337 <td><input type 'text' name='COMMENT' value='$settings{'COMMENT'}' /></td>\r
338</tr>\r
339</table>\r
340<hr />\r
341<table width='100%'>\r
342<tr>\r
343 <td class='base' width='50%'><img src='/blob.gif' align='top' alt='*' />&nbsp;$Lang::tr{'this field may be blank'}</td>\r
344 <td width='50%' align='center'><input type='hidden' name='ACTION' value='$Lang::tr{'add'}' /><input type='submit' name='SUBMIT' value='$buttontext' /></td>\r
345</tr>\r
346</table>\r
347</form>\r
348END\r
349;\r
350&Header::closebox();\r
351\r
352##\r
353## Third box shows the list\r
354##\r
355\r
356# Columns headers may be a sort link. In this case it must be named in $sortstring\r
357&Header::openbox('100%', 'left', $Lang::tr{'XY data'});\r
358print <<END\r
359<table width='100%'>\r
360<tr>\r
361 <td width='20%' align='center'><a href='$ENV{'SCRIPT_NAME'}?IP'><b>$Lang::tr{'ip address'}</b></a></td>\r
362 <td width='70%' align='center'><a href='$ENV{'SCRIPT_NAME'}?COMMENT'><b>$Lang::tr{'remark'}</b></a></td>\r
363 <td width='10%' colspan='3' class='boldbase' align='center'><b>$Lang::tr{'action'}</b></td>\r
364</tr>\r
365END\r
366;\r
367\r
368##\r
369## Print each line of @current list\r
370##\r
371my $key = 0;\r
372$f->readreset; # beginning of data\r
373for ($key=0; $key<$f->getnumberofline; $key++) {\r
374\r
375 my($cb,$comment,$ip) = $f->readbyfieldsseq($key,'CB','COMMENT','IP');\r
376\r
377 #Choose icon for checkbox\r
378 my $gif = '';\r
379 my $gdesc = '';\r
380 if ($cb eq "on") {\r
381 $gif = 'on.gif';\r
382 $gdesc = $Lang::tr{'click to disable'};\r
383 } else {\r
384 $gif = 'off.gif';\r
385 $gdesc = $Lang::tr{'click to enable'};\r
386 }\r
387\r
388 #Colorize each line\r
389 if ($settings{'KEY1'} eq $key) {\r
390 print "<tr bgcolor='${Header::colouryellow}'>";\r
391 } elsif ($key % 2) {\r
392 print "<tr bgcolor='${Header::table2colour}'>";\r
393 } else {\r
394 print "<tr bgcolor='${Header::table1colour}'>"; \r
395 }\r
396\r
397 print <<END\r
398<td align='center'>$ip</td>\r
399<td align='center'>$comment</td>\r
400\r
401<td align='center'>\r
402<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
403<input type='hidden' name='ACTION' value='$Lang::tr{'toggle enable disable'}' />\r
404<input type='image' name='$Lang::tr{'toggle enable disable'}' src='/images/$gif' alt='$gdesc' title='$gdesc' />\r
405<input type='hidden' name='KEY1' value='$key' />\r
406</form>\r
407</td>\r
408\r
409<td align='center'>\r
410<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
411<input type='hidden' name='ACTION' value='$Lang::tr{'edit'}' />\r
412<input type='image' name='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' />\r
413<input type='hidden' name='KEY1' value='$key' />\r
414</form>\r
415</td>\r
416\r
417<td align='center'>\r
418<form method='post' action='$ENV{'SCRIPT_NAME'}'>\r
419<input type='hidden' name='ACTION' value='$Lang::tr{'remove'}' />\r
420<input type='image' name='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' />\r
421<input type='hidden' name='KEY1' value='$key' />\r
422</form>\r
423</td>\r
424</tr>\r
425END\r
426;\r
427} print "</table>";\r
428\r
429# If table contains entries, print 'Key to action icons'\r
430if ($key) {\r
431print <<END\r
432<table>\r
433<tr>\r
434 <td class='boldbase'>&nbsp;<b>$Lang::tr{'legend'}:&nbsp;</b></td>\r
435 <td><img src='/images/on.gif' alt='$Lang::tr{'click to disable'}' /></td>\r
436 <td class='base'>$Lang::tr{'click to disable'}</td>\r
437 <td>&nbsp;&nbsp;</td>\r
438 <td><img src='/images/off.gif' alt='$Lang::tr{'click to enable'}' /></td>\r
439 <td class='base'>$Lang::tr{'click to enable'}</td>\r
440 <td>&nbsp;&nbsp;</td>\r
441 <td><img src='/images/edit.gif' alt='$Lang::tr{'edit'}' /></td>\r
442 <td class='base'>$Lang::tr{'edit'}</td>\r
443 <td>&nbsp;&nbsp;</td>\r
444 <td><img src='/images/delete.gif' alt='$Lang::tr{'remove'}' /></td>\r
445 <td class='base'>$Lang::tr{'remove'}</td>\r
446</tr>\r
447</table>\r
448END\r
449;\r
450}\r
451\r
452&Header::closebox();\r
453&Header::closebigbox();\r
454&Header::closepage();\r
455\r
456## Ouf it's the end !\r
457\r
458##\r
459## Build the configuration file for application XY\r
460##\r
461sub BuildConfiguration {\r
462 open(FILE, ">/$conffile") or die "$msg_configfileerror";\r
463 flock(FILE, 2);\r
464\r
465 #Global settings\r
466 print FILE "#\n# Configuration file for application XY\n#\n\n";\r
467 print FILE "# do not edit manually\n";\r
468 print FILE "# build for Ipcop:$mainsettings{'HOSTNAME'}\n\n\n";\r
469 print FILE "service=$settings{'NAME'}\n";\r
470 print FILE "activate-turbo\n" if $settings{'TURBO'} eq 'on';\r
471 print FILE "interface=$settings{'IT'}\n\n\n";\r
472 #write data line\r
473 {\r
474 my ($IP,$CB,$COMMENT);\r
475 $f->readreset;\r
476 while (defined ($f->readdataseq($IP,$CB,$COMMENT))) {\r
477 if ($CB eq "on") {\r
478 print FILE "$IP\t\t\t\t\t#$COMMENT\n";\r
479 } else {\r
480 print FILE "#DISABLED $IP\t\t\t\t#$COMMENT\n";\r
481 }\r
482 }\r
483 }\r
484 close FILE;\r
485\r
486 # Restart service\r
487 #system '/usr/local/bin/restartyourhelper';\r
488}\r