Added support for a single embedded script file
[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     // add special cases
123     $nics["undi"] = "undionly";
124     $nics["gpxe-all-drivers"] = "gpxe";
125
126     // put NICs in nice alpha order for menu
127     ksort ( $nics );
128
129     return ( array ( $nics, $roms ) );
130 }
131
132 ////
133 // HTML form utility functions
134 ////
135
136 function hidden ( $flag, $value ) 
137 {
138     $value = htmlentities ( $value );
139     return "<input type=\"hidden\" value=\"$value\" name=\"$flag\"></input>";
140 }
141
142 function checkbox ( $flag, $value ) 
143 {
144     return "<input type=\"checkbox\" value=\"on\" name=\"$flag\"" .
145         ($value == "on" ? " checked>" : ">" );
146 }
147
148 function textbox ( $flag, $value, $size ) 
149 {
150     $value = htmlentities ( $value );
151     return "<input type=\"text\" size=\"$size\" value=\"$value\" name=\"$flag\">";
152 }
153  
154 function textarea ( $flag, $value, $rows, $cols ) 
155 {
156     $value = htmlentities ( $value );
157     return "<textarea name=\"$flag\" rows=\"$rows\" cols=\"$cols\">"
158             . $value . "</textarea>";
159 }
160
161 function menubox ( $name, $options, $value ) 
162 {
163     $s="<select name=\"$name\">";
164
165         foreach ( $options as $ignore => $option ) {
166         if ( !$value ) $value = $option;
167         $s .= "<option" . ( $option == $value ? " selected>" : ">" ) .
168             htmlentities ( $option ) . "</option>";
169     }
170     return $s . "</select>";
171 }
172
173 function keys_menubox ( $name, $options, $value ) 
174 {
175     $s="<select name=\"$name\">";
176     
177     foreach ( $options as $option => $ignore ) {
178         if ( !$value ) $value = $option;
179         $s .= "<option" . ( $option == $value ? " selected>" : ">" ) .
180             htmlentities ( $option ) . "</option>";
181     }
182     return $s . "</select>";
183 }  
184
185 ////
186 // Flag (compile option) handling functions
187 ////
188
189 function default_flags () 
190 {
191     global $flag_table;
192     
193     $flags = array ();
194
195     foreach ( $flag_table as $key => $props ) {
196
197         $flag  = $props["flag"];
198         $type  = $props["type"];
199
200         // Fields like headers have no "value" property
201         $value = isset ( $props["value"] ) ? $props['value'] : '';
202
203         if ( $value != '' ) {
204             if ( $type != "on/off" || $value == "on" ) {
205                 $flags[$flag] = $props["value"];
206             }
207         }
208     }
209     return $flags;
210 }
211
212 function get_flags () 
213 {
214     global $flag_table;
215     
216     $flags = default_flags ();
217
218     foreach ( $flag_table as $key => $props ) {
219
220         $flag = $props["flag"];
221         
222         if ( isset ( $_POST["$flag"] ) ) {
223             $flags[$flag] = $_POST["$flag"];
224         }
225     }
226     return $flags;
227 }
228
229 function pprint_flag ( $key, $value )
230 {
231     global $flag_table;
232
233     $type = $flag_table[$key]["type"];
234     $s = "";
235
236     if ( $type == "on/off" && $value == "on" ) {
237         $s = "#define $key";
238     } else if ( $type == "on/off" && $value != "on" ) {
239         $s = "#undef $key";
240     } else if ( $type == "string" ) {
241         if ( $value != "" ) $s = ( "#define $key \"" . cleanstring($value) . "\"" );
242     } else if ($type == "qstring" ) {
243         if ( $value != "" ) $s = ( "#define $key \\\"" . cleanstring($value) . "\\\"" );
244     } else {
245         $s = "#define $key " . cleanstring($value);
246     }
247     // print ( $s . "<br>" );
248     
249     return $s;
250 }
251
252 function pprint_flags ( $flags ) 
253 {
254     $s = "";
255         foreach ( $flags as $key => $value ) {
256         $f = pprint_flag($key, $value);
257         if ($f != "" )
258             $s .= $f . " ";
259     }
260     return $s;
261 }
262
263 function echo_flags ( $flags )
264 {
265     global $flag_table;
266
267     echo "<table>\n";
268
269         foreach ( $flag_table as $key => $props ) {
270
271         // Hide parameters from users that should not be changed.
272         $hide_from_user = isset ( $props["hide_from_user"] ) ? $props["hide_from_user"] : "no";
273
274         $flag = $props["flag"];
275         $type = $props["type"];
276
277         $value = isset ( $flags[$flag] ) ? $flags[$flag] : '';
278
279         if ( $hide_from_user == "yes" ) {
280
281             // Hidden flags cannot not be set by the user.  We use hidden form
282             // fields to keep them at their default values.
283             if ( $type != "header" ) {
284                 echo hidden ( $flag, $value );
285             }
286             
287         } else {
288             
289             // Flag (gPXE compile option) should be displayed to user
290
291             if ( $type == "header" ) {
292
293                 $label = $props["label"];
294                 echo "<td colspan=2><hr><h3>$label</h3><hr></td>";
295
296             } else if ($type == "on/off" ) {
297
298                 echo "<td>", checkbox ( $flag, $value ), "</td><td><b>$flag</b></td>";
299
300             } else {   // don't display checkbox for non-on/off flags
301
302                 echo "<td>&nbsp;</td><td><b>$flag: </b>";
303
304                 if ($type == "choice" ) {
305                     $options = $props["options"];
306                     echo menubox($flag, $options, $value);
307
308                 } else {
309
310                     echo textbox($flag, $value, ($type == "integer" ? 5 : 25));
311                 }
312                 echo "</td>";
313             }
314             echo "</tr>\n";
315
316             if ( $type != "header" ) {
317                 echo "<tr><td>&nbsp;</td>";
318                 echo "<td>\n";
319                 include_once "doc/$flag.html";
320                 echo "\n</td></tr>\n";
321             }
322         }
323     }
324     echo "</table>";
325 }
326
327 function get_cfgsecs ()
328 {
329     global $flag_table;
330     $cfgsecs = array ();
331
332     foreach ( $flag_table as $key => $props ) {
333         if ( isset ( $props['cfgsec'] ) ) {
334             $cfgsec = $props["cfgsec"];
335             $cfgsecs[$cfgsec] = $cfgsec;
336         }
337     }
338     return ( $cfgsecs );
339 }
340
341 ////
342 // File and directory handling functions
343 ////
344
345 function mktempcopy ( $src, $dst ) 
346 {
347     if ( $src[0] != "/" ) {
348         $src = dirname ( $_SERVER['SCRIPT_FILENAME'] ) . "/" . $src;
349     }
350
351     $dir = tempnam ( $dst, "MDCROM" );
352     unlink( $dir );
353
354     exec ( "/bin/cp -a '$src' '$dir' 2>&1", $cpytxt, $status );  
355     if ( $status != 0 ) {
356         die ( "src directory copy failed!" );
357     }
358     return ( $dir );
359 }
360
361 function write_gpxe_config_files ( $config_dir, $flags ) 
362 {
363     global $flag_table;
364
365     $cfgsecs = get_cfgsecs ();
366
367     foreach ( $cfgsecs as $cfgsec ) {
368
369         $fname = $config_dir . "/" . $cfgsec . ".h";
370
371         $fp = fopen ( $fname, "wb" );
372         if ( $fp <= 0 ) {
373             die ( "Unable to open $fname file for output!" );
374         }
375
376         $ifdef_secname = "CONFIG_" . strtoupper ( $cfgsec ) . "_H";
377
378         fwrite ( $fp, "#ifndef ${ifdef_secname}\n" );
379         fwrite ( $fp, "#define ${ifdef_secname}\n" );
380         fwrite ( $fp, "#include <config/defaults.h>\n" );
381
382         foreach ( $flags as $key => $value ) {
383             // When the flag matches this section name, write it out
384             if ( $flag_table[$key]["cfgsec"] == $cfgsec ) {
385                 fwrite ( $fp, pprint_flag ( $key, $value ) . "\n" );
386             } 
387         }
388         fwrite ( $fp, "#endif /* ${ifdef_secname} */\n" );
389         fclose ( $fp );
390     }
391 }
392
393 function write_embedded_file ( $fname, $ftext )
394 {
395         $fp = fopen ( $fname, "wb" );
396         if ( $fp <= 0 ) {
397             die ( "Unable to open $fname file for output!" );
398         }
399         fwrite ( $fp, $ftext );
400         fclose ( $fp );
401 }
402
403 function deltempdir ( $dir )
404 {
405     $dp = opendir ( $dir );
406     if ($dp < 1) {
407         die ( "opendir failed" );
408     }
409
410     while ( $file = readdir ( $dp ) ) {
411
412         if ( is_dir ( "$dir/$file" ) ) {
413             if ($file[0] != "." ) {
414                 deltempdir ( "$dir/$file" );
415             }
416         } else {
417             unlink( "$dir/$file" );
418         }
419     }
420     closedir ( $dp );
421
422     if ( !rmdir ( "$dir" ) ) {
423         die ( "rmdir failed" );
424     }
425 }
426
427 ////
428 // Debugging functions
429 ////
430
431 function show_flags ( $flags ) 
432 {
433     echo ( "\$flags contains " . count ( $flags ) . " elements:" . "<br>" );
434
435         foreach ( $flags as $key => $flag ) {
436         echo ( "\$flags[" . $key . "]=" . "\"$flag\"" . "<br>" );
437     }
438 }
439
440 function dump_flag_table () 
441 {
442     global $flag_table;
443
444         foreach ( $flag_table as $key => $props ) {
445         print ( "flag_table[" . $key . "] = " . "<br>" );
446
447                 foreach ( $props as $key2 => $props2 ) {
448             print ( "&nbsp;&nbsp;&nbsp;" . $key2 . " = " . $props2 . "<br>" );
449         }
450     }
451 }
452
453 function dump_flag_codes () 
454 {
455     global $flag_codes;
456
457         foreach ( $flag_codes as $key => $props ) {
458         print ( "flag_codes[" . $key . "] = " . "<br>" );
459
460                 foreach ( $props as $keys2 => $props2 ) {
461             print ( "&nbsp;&nbsp;&nbsp;" . $key2 . " = " . $props2 . "<br>" );
462         }
463     }
464 }
465
466 // For emacs:
467 // Local variables:
468 //  c-basic-offset: 4
469 //  c-indent-level: 4
470 //  tab-width: 4
471 // End:
472
473 ?>