Slight wording changes on menus
[people/meteger/rom-o-matic/.git] / utils.php
1 <? // -*- Mode: PHP; -*-
2
3 // Include table of user-configurable gPXE options
4 require_once "flag-table.php";
5
6 // Include user-shadowable globals
7 require_once "globals.php";
8
9 // Allow user to shadow globals
10 if ( is_file ( 'local-config.php' ) ) { 
11     include "local-config.php";
12 }
13
14 // Parse src/bin/NIC file
15 list ( $nics, $roms ) = parse_nic_file ();
16
17 ////
18 // General utility functions
19 ////
20
21 function cleanstring ( $s ) 
22 {
23     $len = strlen ( $s );
24     if ( $len > 80 ) {
25         $s = substr ( $s, 0, 80 );
26     }
27
28     $s      = trim ( $s );
29     $pos    = 0;
30     $result = "";
31
32     while ( $pos < $len ) {
33         $ltr = ord ( ucfirst ( $s[$pos] ) );
34         if ( ( $ltr >= ord ( "A" ) ) && ( $ltr <= ord ( "Z" ) ) || 
35              ( $ltr >= ord ( "0" ) ) && ( $ltr <= ord ( "9" ) ) || 
36              ( $ltr == ord ( "." ) ) && ( strlen ( $result ) > 0 ) ||
37              ( $ltr == ord ( "_" ) ) ||
38              ( $ltr == ord ( "+" ) ) ||
39              ( $ltr == ord ( ":" ) ) ||
40              ( $ltr == ord ( "/" ) ) ||
41              ( $ltr == ord ( "-" ) ) ) {
42             $result .= $s[$pos];
43         }
44         $pos++;
45     }
46     return $result;
47 }
48
49 function curDirURL () 
50 {
51         $dir = dirname ( $_SERVER['PHP_SELF'] );
52
53         if ( $dir == "." || $dir == "/" ) {
54                 $dir = "";
55         }
56
57         $isHTTPS = ( isset ( $_SERVER["HTTPS"] ) && $_SERVER["HTTPS"] == "on" );
58         $port = ( isset($_SERVER["SERVER_PORT"] ) && 
59                           ( ( !$isHTTPS && $_SERVER["SERVER_PORT"] != "80" ) || 
60                                 ( $isHTTPS  && $_SERVER["SERVER_PORT"] != "443" ) ) );
61
62         $port = ( $port ) ? ':' . $_SERVER["SERVER_PORT"] : '';
63
64         $dest = ( $isHTTPS ? 'https://' : 'http://' ) .
65                 $_SERVER["SERVER_NAME"] . $dir . "/";
66
67         return $dest;
68 }
69
70 function parse_nic_file ()
71 {
72     // Extract NIC families and associated ROM PCI IDs from 
73     // the src/bin/NIC file.
74     global $src_dir;
75
76     $fd = fopen( "$src_dir/bin/NIC", "r" );
77
78     if ( $fd < 1 ) {
79         trigger_error ( "Missing NIC Config Info" );
80         exit ();
81     }
82
83     $nics = array ();
84     $roms = array ();
85     $nic = "";
86
87     while ( !feof ( $fd ) ) {
88
89         $line = trim ( fgets ( $fd, 200 ) );
90
91         $first_eight_chars = substr ( $line, 0, 8 );
92         settype ( $first_eight_chars, "string" );
93
94         if ( strpos ( $first_eight_chars, "family" ) === 0 ) {
95
96             // get pathname of NIC driver
97             list ( $dummy, $nic ) = split( "[ \t]+", $line );
98             settype ( $nic, "string" );
99             
100             // extract filename name of driver from pathname
101             $nic = substr ( $nic, strrpos ( $nic, "/" ) + 1, 
102                            strlen ( $nic ) - strrpos ( $nic, "/" ) + 1 );
103
104             $nics[$nic] = $nic;
105
106             // For each ISA NIC, there can only be one ROM variant
107             $roms[$nic] = $nic;
108         }
109
110         // If the first 8 digits of the line are hex digits
111         // add this rom to the current nic family.
112
113         if (    ( strlen ( $first_eight_chars ) == 8 ) 
114              && ( ctype_xdigit ( $first_eight_chars ) )
115              && ( $nic != "" ) ) {
116         
117             $roms[$first_eight_chars] = $nic;
118         }
119     }
120     fclose ( $fd );
121
122     // put most NICs in nice alpha order for menu
123     ksort ( $nics );
124
125     // add special cases to the top
126
127         $new_nics = array ( "all-drivers" => "gpxe",
128                                                 "undi" => "undionly" );
129
130         foreach ( $nics as $key => $value ) {
131                 // skip the undi driver
132                 if ( $key != "undi" ) {
133                         $new_nics[$key] = $value;
134                 }
135         }
136
137         return ( array ( $new_nics, $roms ) );
138 }
139
140 ////
141 // HTML form utility functions
142 ////
143
144 function hidden ( $flag, $value ) 
145 {
146     $value = htmlentities ( $value );
147     return "<input type=\"hidden\" value=\"$value\" name=\"$flag\"></input>";
148 }
149
150 function checkbox ( $flag, $value ) 
151 {
152     return "<input type=\"checkbox\" value=\"on\" name=\"$flag\"" .
153         ($value == "on" ? " checked>" : ">" );
154 }
155
156 function textbox ( $flag, $value, $size ) 
157 {
158     $value = htmlentities ( $value );
159     return "<input type=\"text\" size=\"$size\" value=\"$value\" name=\"$flag\">";
160 }
161  
162 function textarea ( $flag, $value, $rows, $cols ) 
163 {
164     $value = htmlentities ( $value );
165     return "<textarea name=\"$flag\" rows=\"$rows\" cols=\"$cols\">"
166             . $value . "</textarea>";
167 }
168
169 function menubox ( $name, $options, $value ) 
170 {
171     $s="<select name=\"$name\">";
172
173         foreach ( $options as $ignore => $option ) {
174         if ( !$value ) $value = $option;
175         $s .= "<option" . ( $option == $value ? " selected>" : ">" ) .
176             htmlentities ( $option ) . "</option>";
177     }
178     return $s . "</select>";
179 }
180
181 function keys_menubox ( $name, $options, $value ) 
182 {
183     $s="<select name=\"$name\">";
184     
185     foreach ( $options as $option => $ignore ) {
186         if ( !$value ) $value = $option;
187         $s .= "<option" . ( $option == $value ? " selected>" : ">" ) .
188             htmlentities ( $option ) . "</option>";
189     }
190     return $s . "</select>";
191 }  
192
193 ////
194 // Flag (compile option) handling functions
195 ////
196
197 function default_flags () 
198 {
199     global $flag_table;
200     
201     $flags = array ();
202
203     foreach ( $flag_table as $key => $props ) {
204
205         $flag  = $props["flag"];
206         $type  = $props["type"];
207
208         // Fields like headers have no "value" property
209         if ( isset ( $props["value"] ) ) {
210             $flags[$flag] = $props["value"];
211         }
212     }
213     return $flags;
214 }
215
216 function get_flags () 
217 {
218     global $flag_table;
219     
220     $flags = default_flags ();
221
222     foreach ( $flag_table as $key => $props ) {
223
224         $flag = $props["flag"];
225         
226         if ( isset ( $_POST["$flag"] ) ) {
227             $flags[$flag] = $_POST["$flag"];
228         }
229     }
230     return $flags;
231 }
232
233 function pprint_flag ( $key, $value )
234 {
235     global $flag_table;
236
237     $type = $flag_table[$key]["type"];
238     $s = "";
239
240     if ( $type == "on/off" && $value == "on" ) {
241         $s = "#define $key";
242     } else if ( $type == "on/off" && $value != "on" ) {
243         $s = "#undef $key";
244     } else if ( $type == "string" ) {
245         $s = ( "#define $key \"" . cleanstring ( $value ) . "\"" );
246     } else if ($type == "qstring" ) {
247         $s = ( "#define $key \\\"" . cleanstring ( $value ) . "\\\"" );
248     } else {
249         $s = "#define $key " . cleanstring($value);
250     }
251     
252     return $s;
253 }
254
255 function pprint_flags ( $flags ) 
256 {
257     $s = "";
258         foreach ( $flags as $key => $value ) {
259         $f = pprint_flag ( $key, $value );
260         $s .= $f . " ";
261     }
262     return $s;
263 }
264
265 function echo_flags ( $flags )
266 {
267     global $flag_table;
268
269     echo "<table>\n";
270
271         foreach ( $flag_table as $key => $props ) {
272
273         // Hide parameters from users that should not be changed.
274         $hide_from_user = isset ( $props["hide_from_user"] ) ? $props["hide_from_user"] : "no";
275
276         $flag = $props["flag"];
277         $type = $props["type"];
278
279         $value = isset ( $flags[$flag] ) ? $flags[$flag] : '';
280
281         if ( $hide_from_user == "yes" ) {
282
283             // Hidden flags cannot not be set by the user.  We use hidden form
284             // fields to keep them at their default values.
285             if ( $type != "header" ) {
286                 echo hidden ( $flag, $value );
287             }
288             
289         } else {
290             
291             // Flag (gPXE compile option) should be displayed to user
292
293             if ( $type == "header" ) {
294
295                 $label = $props["label"];
296                 echo "<td colspan=2><hr><h3>$label</h3><hr></td>";
297
298             } else if ($type == "on/off" ) {
299
300                 echo "<td>", checkbox ( $flag, $value ), "</td><td><strong>$flag</strong></td>";
301
302             } else {   // don't display checkbox for non-on/off flags
303
304                 echo "<td>&nbsp;</td><td><strong>$flag: </strong>";
305
306                 if ($type == "choice" ) {
307                     $options = $props["options"];
308                     echo menubox($flag, $options, $value);
309
310                 } else {
311
312                     echo textbox($flag, $value, ($type == "integer" ? 7 : 25));
313                 }
314                 echo "</td>";
315             }
316             echo "</tr>\n";
317
318             if ( $type != "header" ) {
319                                 echo "<tr><td>&nbsp;</td>";
320                                 echo "<td>\n";
321                                 if ( is_file ( "doc/$flag.html" ) ) { 
322                                         include_once "doc/$flag.html";
323                                 }
324                                 echo "\n</td></tr>\n";
325             }
326         }
327     }
328     echo "</table>";
329 }
330
331 function get_flag_cfgsecs ()
332 {
333     global $flag_table;
334     $cfgsecs = array ();
335
336     foreach ( $flag_table as $key => $props ) {
337         if ( isset ( $props['cfgsec'] ) ) {
338             $cfgsec = $props["cfgsec"];
339             $cfgsecs[$cfgsec] = $cfgsec;
340         }
341     }
342     return ( $cfgsecs );
343 }
344
345 ////
346 // File and directory handling functions
347 ////
348
349 function mktempcopy ( $src, $dst ) 
350 {
351     if ( $src[0] != "/" ) {
352         $src = dirname ( $_SERVER['SCRIPT_FILENAME'] ) . "/" . $src;
353     }
354
355     $dir = tempnam ( $dst, "MDCROM" );
356     unlink ( $dir );
357
358     exec ( "/bin/cp -a '$src' '$dir' 2>&1", $cpytxt, $status );  
359     if ( $status != 0 ) {
360         die ( "src directory copy failed!" );
361     }
362     return ( $dir );
363 }
364
365 function write_gpxe_config_files ( $config_dir, $flags ) 
366 {
367     global $flag_table;
368
369     $cfgsecs = get_flag_cfgsecs ();
370
371     foreach ( $cfgsecs as $cfgsec ) {
372
373         $fname = $config_dir . "/" . $cfgsec . ".h";
374
375         $fp = fopen ( $fname, "wb" );
376         if ( $fp <= 0 ) {
377             die ( "Unable to open $fname file for output!" );
378         }
379
380         $ifdef_secname = "CONFIG_" . strtoupper ( $cfgsec ) . "_H";
381
382         fwrite ( $fp, "#ifndef ${ifdef_secname}\n" );
383         fwrite ( $fp, "#define ${ifdef_secname}\n" );
384         fwrite ( $fp, "#include <config/defaults.h>\n" );
385
386         foreach ( $flags as $key => $value ) {
387             // When the flag matches this section name, write it out
388             if ( $flag_table[$key]["cfgsec"] == $cfgsec ) {
389                 fwrite ( $fp, pprint_flag ( $key, $value ) . "\n" );
390             } 
391         }
392         fwrite ( $fp, "#endif /* ${ifdef_secname} */\n" );
393         fclose ( $fp );
394     }
395 }
396
397 function write_embedded_file ( $fname, $ftext )
398 {
399         $fp = fopen ( $fname, "wb" );
400         if ( $fp <= 0 ) {
401             die ( "Unable to open $fname file for output!" );
402         }
403         fwrite ( $fp, $ftext );
404         fclose ( $fp );
405 }
406
407 function deltempdir ( $dir )
408 {
409     $dp = opendir ( $dir );
410     if ($dp < 1) {
411         die ( "opendir failed" );
412     }
413
414     while ( $file = readdir ( $dp ) ) {
415
416         if ( is_dir ( "$dir/$file" ) ) {
417             if ($file[0] != "." ) {
418                 deltempdir ( "$dir/$file" );
419             }
420         } else {
421             unlink ( "$dir/$file" );
422         }
423     }
424     closedir ( $dp );
425
426     if ( !rmdir ( "$dir" ) ) {
427         die ( "rmdir failed" );
428     }
429 }
430
431 ////
432 // Debugging functions
433 ////
434
435 function show_flags ( $flags ) 
436 {
437     echo ( "\$flags contains " . count ( $flags ) . " elements:" . "<br>" );
438
439         foreach ( $flags as $key => $flag ) {
440         echo ( "\$flags[" . $key . "]=" . "\"$flag\"" . "<br>" );
441     }
442 }
443
444 function dump_flag_table () 
445 {
446     global $flag_table;
447
448         foreach ( $flag_table as $key => $props ) {
449         print ( "flag_table[" . $key . "] = " . "<br>" );
450
451                 foreach ( $props as $key2 => $props2 ) {
452             print ( "&nbsp;&nbsp;&nbsp;" . $key2 . " = " . $props2 . "<br>" );
453         }
454     }
455 }
456
457 function dump_flag_codes () 
458 {
459     global $flag_codes;
460
461         foreach ( $flag_codes as $key => $props ) {
462         print ( "flag_codes[" . $key . "] = " . "<br>" );
463
464                 foreach ( $props as $keys2 => $props2 ) {
465             print ( "&nbsp;&nbsp;&nbsp;" . $key2 . " = " . $props2 . "<br>" );
466         }
467     }
468 }
469
470 // For emacs:
471 // Local variables:
472 //  c-basic-offset: 4
473 //  c-indent-level: 4
474 //  tab-width: 4
475 // End:
476
477 ?>