Lots of fixes and updates
authorMarty Connor <mdc@etherboot.org>
Sun, 30 Aug 2009 14:03:01 +0000 (10:03 -0400)
committerMarty Connor <mdc@etherboot.org>
Sun, 30 Aug 2009 14:03:01 +0000 (10:03 -0400)
 - Add docblock headers to all functions
 - fix handling of checkboxes as flags
 - improve directory deletion

bottom.php
build.php
customize-flags.php
directions.php
flag-table.php
index.php
top.php
utils.php

index 364ea2c..0a7f456 100644 (file)
@@ -1,6 +1,4 @@
-<!--\r
-\r
-/* Helpful information for users downloading images */\r
+<?\r
 \r
 /**\r
  * Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.\r
@@ -21,8 +19,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
  */\r
 \r
- -->\r
\r
+?>\r
 <hr>\r
 <h4>\r
 Resources:\r
index 1298603..0c47174 100644 (file)
--- a/build.php
+++ b/build.php
@@ -52,9 +52,6 @@ if ( $_POST['A'] == "Customize" ) {
 // OK, we're going to try to use whatever options have been set
 // to build an image.
 
-// Parse src/bin/NIC file
-list ( $nics, $roms ) = parse_nic_file ();
-
 // Make sure at least $nic was supplied
 if ( ! isset ( $_POST['nic'] ) ) {
     die ( "No NIC supplied!" );
@@ -122,15 +119,36 @@ if ( $nic == 'undionly' && $fmt_extension == "pxe" ) {
               . "${_POST['pci_device_code']}" );
     }
 } else if ( $fmt_extension != "rom" 
-            && ( $pci_vendor_code == "" || $pci_device_code == "" ) ) {
+            && ( $pci_vendor_code != "" || $pci_device_code != "" ) ) {
     die (   "'$fmt_extension' format was selected but PCI IDs were"
           . " also entered.<br>Did you mean to select 'rom' output format"
           . " instead?" );
 }
 
+
+/**
+ * remove temporary build directory
+ *
+ * @return bool true if removal is successful, false otherwise
+ */
+function rm_build_dir ()
+{
+    global $build_dir;
+    global $keep_build_dir;
+    
+    if ( $keep_build_dir !== true ) {
+        rm_file_or_dir ( $build_dir );
+    }
+}
+
+// Arrange for the build directory to always be removed on exit.
+$build_dir = "";
+$keep_build_dir = false;
+register_shutdown_function ( 'rm_build_dir' );
+
 // Make temporary copy of src directory
-$dir = mktempcopy ( "$src_dir", "/tmp" );
-$config_dir = $dir . "/config";
+$build_dir = mktempcopy ( "$src_dir", "/tmp", "MDCROM" );
+$config_dir = $build_dir . "/config";
 
 // Write config files with supplied flags
 write_gpxe_config_files ( $config_dir, $flags );
@@ -139,22 +157,29 @@ write_gpxe_config_files ( $config_dir, $flags );
 $emb_script_cmd = "";
 $embedded_script = isset ( $_POST['embedded_script'] ) ? $_POST['embedded_script'] : "";
 if ( $embedded_script != "" ) {
-    $emb_script_path = "$dir" . "/script0.gpxe";
-    write_embedded_file ( $emb_script_path, $embedded_script );
+    $emb_script_path = "$build_dir" . "/script0.gpxe";
+    write_file_from_string ( $emb_script_path, $embedded_script );
     $emb_script_cmd = "EMBEDDED_IMAGE=${emb_script_path}";
 }
 
 // Make the requested image.  $status is set to 0 on success
 $make_target = "bin/${nic}.${fmt_extension}";
-$make_cmd = "make -C '$dir' '$make_target' $emb_script_cmd $2>&1";
+$make_cmd = "make -C '$build_dir' '$make_target' $emb_script_cmd $2>&1";
 
 exec ( $make_cmd, $maketxt, $status );
 
 // Uncomment the following section for debugging
+
 /**
+
 echo "<h2>build.php:</h2>";
+echo "<h3>Begin debugging output</h3>";
+
+//echo "<h3>\$_POST variables</h3>";
+//echo "<pre>"; var_dump ( $_POST ); echo "</pre>";
+
 echo "<h3>Build options:</h3>";
-echo "<strong>Build directory is:</strong> $dir" . "<br><br>";
+echo "<strong>Build directory is:</strong> $build_dir" . "<br><br>";
 echo "\$_POST['ofmt'] = " . "\"${_POST['ofmt']}\"" . "<br>";
 echo "\$_POST['nic'] = " . "\"${_POST['nic']}\"" .  "<br>";
 echo "\$_POST['pci_vendor_code'] = " . "\"${_POST['pci_vendor_code']}\"" . "<br>";
@@ -176,9 +201,9 @@ echo "Build status = <? echo $status ?>" . "<br>";
 echo "<blockquote>"."<pre>";
 echo htmlentities ( implode ("\n", $maketxt ) );
 echo "</pre>"."</blockquote>";
-// Uncomment the next line if you do not want to keep the
+// Uncomment the next line if you want to keep the
 // build directory around for inspection after building.
-// deltempdir ( $dir );
+$keep_build_dir = true;
 die ( "<h3>End debugging output</h3>" );
 
 **/ //   End debugging section
@@ -187,19 +212,19 @@ die ( "<h3>End debugging output</h3>" );
 
 if ( $status == 0 ) {
 
-    $fp = fopen("$dir/$make_target", "rb" );
+    $fp = fopen("${build_dir}/${make_target}", "rb" );
     if ( $fp > 0 ) {
 
-        $len = filesize ( "$dir/$make_target" );
+        $len = filesize ( "${build_dir}/${make_target}" );
         if ( $len > 0 ) {
 
             $buf = fread ( $fp, $len );
             fclose ( $fp );
-            deltempdir ( $dir );
 
-            $output_filename = "gpxe-${version}-${nic}.${fmt_extension}";
+            // Delete build directory as soon as it is not needed
+            rm_build_dir ();
 
-            // echo "${output_filename}<br>"; exit ();
+            $output_filename = "gpxe-${version}-${nic}.${fmt_extension}";
 
             // Try to force IE to handle downloading right.
             Header ( "Cache-control: private");
@@ -217,15 +242,20 @@ if ( $status == 0 ) {
     }
 }
 
+/*
+ * If we reach this point, the build has failed, and we provide
+ * debugging information for a potential bug report
+ *
+ */
+
 // Remove build directory
-deltempdir ( $dir );
+rm_build_dir ();
 
 // Announce failure if $status from make was non-zero
-
 echo "<h2>Build failed.  Status = " . $status . "</h2>";
 echo "<h2>build.php:</h2>";
 echo "<h3>Build options:</h3>";
-echo "<strong>Build directory is:</strong> $dir" . "<br><br>";
+echo "<strong>Build directory is:</strong> $build_dir" . "<br><br>";
 echo "\$_POST['ofmt'] = " . "\"${_POST['ofmt']}\"" . "<br>";
 echo "\$_POST['nic'] = " . "\"${_POST['nic']}\"" .  "<br>";
 echo "\$_POST['pci_vendor_code'] = " . "\"${_POST['pci_vendor_code']}\"" . "<br>";
index edfc0b4..84883ca 100644 (file)
 // Get utility functions and set globals
 require_once "utils.php";
 
-// Parse src/bin/NIC file
-list ( $nics, $roms ) = parse_nic_file ();
-
 // Prepare settable compile options for presentation to user
-$flags = get_flags();
+$flags = default_flags ();
 
 $build = "<input type=\"submit\" name=\"A\" value=\"Get Image\">";
 $restart = "<input type=\"submit\" name=\"A\" value=\"Start Over\">";
index d1a93b9..1dbfe25 100644 (file)
@@ -1,4 +1,4 @@
-<!--
+<?
 
 /**
  * Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
@@ -19,7 +19,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
--->
+?>
     <li>
       Choose an output format: <? echo keys_menubox ( "ofmt", $ofmts,
       isset ( $_POST['ofmt'] ) ? $_POST['ofmt'] : "") ?>
index bb1c4c3..226c3a6 100644 (file)
@@ -441,37 +441,9 @@ $flag_table = array (
           "cfgsec" => "general"
                ),
        
-       // End Command-line commands to include
-       
+       // End Command-line commands to include 
 );
 
-$flag_codes = array ();
-
-function init_flag_tables () 
-{
-    global $flag_table;
-
-    $i = 1;
-
-    foreach ( $flag_table as $key => $props ) {
-
-               $is = ( string ) $i;
-
-               if ( $i < 10 )
-                   $is = "0" . $is;
-
-           $props["code"] = $is;
-               $props["flag"] = $key;
-
-           $flag_table[$key] = $props;
-               $flag_codes[$is] = $props;
-       
-               $i = $i + 1;
-    }
-}
-
-init_flag_tables ();
-
 // For emacs:
 // Local variables:
 //  c-basic-offset: 4
index b05399a..3ebcc41 100644 (file)
--- a/index.php
+++ b/index.php
@@ -22,9 +22,6 @@
 // Get utility functions and set globals
 require_once "utils.php";
 
-// Parse src/bin/NIC file
-list ( $nics, $roms ) = parse_nic_file ();
-
 // Begin html output
 include_once $top_inc;
 
diff --git a/top.php b/top.php
index 2b4c8ef..cb53b62 100644 (file)
--- a/top.php
+++ b/top.php
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
 
-<!--
+<?
 
 /**
  * Copyright (C) 2009 Marty Connor <mdc@etherboot.org>.
@@ -21,7 +21,7 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
 
--->
+?>
 
 <html>
 <head>
index ab80f3f..acb33fa 100644 (file)
--- a/utils.php
+++ b/utils.php
@@ -34,6 +34,18 @@ if ( is_file ( 'local-config.php' ) ) {
 // General utility functions
 ////
 
+/**
+ * Remove undesirable characters from a given string
+ *
+ * Certain characters have the potential to be used for
+ * malicious purposes by web-based attackers.  This routine
+ * filters out such characters.
+ *
+ * @param string $s supplied string
+ *
+ * @return string returned string with unwanted characters
+ *                removed
+ */
 function cleanstring ( $s ) 
 {
     $len = strlen ( $s );
@@ -62,6 +74,11 @@ function cleanstring ( $s )
     return $result;
 }
 
+/**
+ * Return URL of the currently running script, minus the filename
+ *
+ * @return string the URL of the currently running script, minus the filename
+ */
 function curDirURL () 
 {
         $dir = dirname ( $_SERVER['PHP_SELF'] );
@@ -83,17 +100,21 @@ function curDirURL ()
         return $dest;
 }
 
+/**
+ * Extract NIC families and associated ROM PCI IDs from the src/bin/NIC file.
+ *
+ * $src_dir must contain the path of the gPXE src directory for this build
+ *
+ * @return array[0] array $new_nics
+ * @return array[1] array $roms
+ */
 function parse_nic_file ()
 {
-    // Extract NIC families and associated ROM PCI IDs from 
-    // the src/bin/NIC file.
     global $src_dir;
 
-    $fd = fopen( "$src_dir/bin/NIC", "r" );
-
-    if ( $fd < 1 ) {
-        trigger_error ( "Missing NIC Config Info" );
-        exit ();
+    $fd = fopen ( "$src_dir/bin/NIC", "r" );
+    if ( ! $fd ) {
+        die ( "Missing src/bin/NIC file.  'make bin/NIC'" );
     }
 
     $nics = array ();
@@ -152,31 +173,66 @@ function parse_nic_file ()
                }
        }
 
-       return ( array ( $new_nics, $roms ) );
+       return array ( $new_nics, $roms );
 }
 
 ////
 // HTML form utility functions
 ////
 
+/**
+ * Return html code to create hidden form input fields
+ *
+ * @param string $flag  name of form variable to set
+ * @param string $value value to give form variable
+ *
+ * @return string html code for given hidden form input field
+ */
 function hidden ( $flag, $value ) 
 {
     $value = htmlentities ( $value );
     return "<input type=\"hidden\" value=\"$value\" name=\"$flag\"></input>";
 }
 
+/**
+ * Return html code to create checkbox form input fields
+ *
+ * @param string $flag  name of form variable to set
+ * @param string $value "on" means box should be checked
+ *
+ * @return string html code for given hidden form input field
+ */
 function checkbox ( $flag, $value ) 
 {
     return "<input type=\"checkbox\" value=\"on\" name=\"$flag\"" .
         ($value == "on" ? " checked>" : ">" );
 }
 
+/**
+ * Return html code to create text form input fields
+ *
+ * @param string $flag  name of form variable to set
+ * @param string $value initial contents of field
+ * @param string $size  size in characters of text box
+ *
+ * @return string html code for given text input field
+ */
 function textbox ( $flag, $value, $size ) 
 {
     $value = htmlentities ( $value );
     return "<input type=\"text\" size=\"$size\" value=\"$value\" name=\"$flag\">";
 }
+
+/**
+ * Return html code to create textarea form fields
+ *
+ * @param string $flag  name of form variable to set
+ * @param string $value initial contents of textarea
+ * @param string $rows  height of text area in rows
+ * @param string $cols  width of text area in columns
+ *
+ * @return string html code for given textarea input field
+ */
 function textarea ( $flag, $value, $rows, $cols ) 
 {
     $value = htmlentities ( $value );
@@ -184,6 +240,17 @@ function textarea ( $flag, $value, $rows, $cols )
             . $value . "</textarea>";
 }
 
+/**
+ * Return html code to create select (menu) form fields
+ *
+ * Use array of strings as menu choices
+ *
+ * @param string $flag    name of form variable to set
+ * @param array  $options array of strings representing choices
+ * @param string $value   value of choice to select in menu
+ *
+ * @return string html code for given select (menu) input field
+ */
 function menubox ( $name, $options, $value ) 
 {
     $s="<select name=\"$name\">";
@@ -196,6 +263,18 @@ function menubox ( $name, $options, $value )
     return $s . "</select>";
 }
 
+/**
+ * Return html code to create select (menu) form fields
+ *
+ * Use indices of array of strings as menu choices rather than
+ * the values pointed to by the indicies.
+ *
+ * @param string $flag    name of form variable to set
+ * @param array  $options array of strings representing choices
+ * @param string $value   value of choice to select in menu
+ *
+ * @return string html code for given select (menu) input field
+ */
 function keys_menubox ( $name, $options, $value ) 
 {
     $s="<select name=\"$name\">";
@@ -212,6 +291,14 @@ function keys_menubox ( $name, $options, $value )
 // Flag (compile option) handling functions
 ////
 
+/**
+ * Return default compile options (flags)
+ *
+ * Initial compile options are in a global called $flag_table.
+ * Create and return an array containing the ones we want.
+ *
+ * @return array default compile options (flags)
+ */
 function default_flags () 
 {
     global $flag_table;
@@ -231,6 +318,16 @@ function default_flags ()
     return $flags;
 }
 
+/**
+ * Return combination of default and user compile options (flags)
+ *
+ * Initial compile options are in a global called $flag_table.
+ * Compile options may have been changed via form input. We return
+ * an array with either the default value of each option or a user
+ * supplied value from form input.
+ *
+ * @return array combined default and user supplied compile options (flags)
+ */
 function get_flags () 
 {
     global $flag_table;
@@ -240,18 +337,39 @@ function get_flags ()
     foreach ( $flag_table as $key => $props ) {
 
         $flag = $props["flag"];
+        $type = $props["type"];
         
         if ( isset ( $_POST["$flag"] ) ) {
             $flags[$flag] = $_POST["$flag"];
-        }
+        } else if ( $type == "on/off" ) {
+                       // Unchecked checkboxes don't pass any POST value
+                       // so we must check for them specially.  At this 
+                       // point we know that there is no $_POST value set
+                       // for this option.  If it is a checkbox, this means
+                       // it is unchecked, so record that in $flags so we
+                       // can later generate an #undef for this option.
+            $flags[$flag] = "off";
+        }            
     }
     return $flags;
 }
 
+/**
+ * Output given value in appropriate format for gPXE config file
+ *
+ * gPXE config/*.h files use C pre-processor syntax.  Output the given
+ * compile option in a format appropriate to its type
+ *
+ * @param string $key   index into $flag_table for given compile option
+ * @param string $value value we wish to set compile option to
+ * 
+ * @return string code to set compile option to given value
+ */
 function pprint_flag ( $key, $value )
 {
     global $flag_table;
 
+    // Determine type of given compile option (flag)
     $type = $flag_table[$key]["type"];
     $s = "";
 
@@ -264,22 +382,19 @@ function pprint_flag ( $key, $value )
     } else if ($type == "qstring" ) {
         $s = ( "#define $key \\\"" . cleanstring ( $value ) . "\\\"" );
     } else {
-        $s = "#define $key " . cleanstring($value);
+        $s = "#define $key " . cleanstring ( $value );
     }
     
     return $s;
 }
 
-function pprint_flags ( $flags ) 
-{
-    $s = "";
-       foreach ( $flags as $key => $value ) {
-        $f = pprint_flag ( $key, $value );
-        $s .= $f . " ";
-    }
-    return $s;
-}
-
+/**
+ * Output html code to display all compile options as a table 
+ *
+ * @param array $flags array of compile options
+ * 
+ * @return void
+ */
 function echo_flags ( $flags )
 {
     global $flag_table;
@@ -346,6 +461,16 @@ function echo_flags ( $flags )
     echo "</table>";
 }
 
+/**
+ * Return an array of configuration sections used in all compile options
+ *
+ * $flag_table, the global list of compile options contains a 'cfgsec'
+ * property for each flag we are interested in.  We return a list of 
+ * all the unique cfgsec options we find in $flag_table.
+ *
+ * @return array an array of strings representing all unique cfgsec values
+ *               found in $flag_table
+ */
 function get_flag_cfgsecs ()
 {
     global $flag_table;
@@ -357,30 +482,59 @@ function get_flag_cfgsecs ()
             $cfgsecs[$cfgsec] = $cfgsec;
         }
     }
-    return ( $cfgsecs );
+    return $cfgsecs;
 }
 
 ////
 // File and directory handling functions
 ////
 
-function mktempcopy ( $src, $dst ) 
+/**
+ * Create a copy of a given source directory to a given destination
+ *
+ * Since we are going to modify the source directory, we create a copy
+ * of the directory with a unique name in the given destination directory.
+ * We supply a prefix for the tempnam call to prepend to the random filename
+ * it generates.
+ *
+ * @param string $src    source directory
+ * @param string $dst    destination directory
+ * @param string $prefix string to append to directory created
+ * 
+ * @return string absolute path to destination directory
+ */
+function mktempcopy ( $src, $dst, $prefix ) 
 {
     if ( $src[0] != "/" ) {
         $src = dirname ( $_SERVER['SCRIPT_FILENAME'] ) . "/" . $src;
     }
 
-    $dir = tempnam ( $dst, "MDCROM" );
+    // Create a file in the given destination directory with a unique name
+    $dir = tempnam ( $dst, $prefix );
+    
+    // Delete the file just created, since it would interfere with the copy we
+    // are about to do.  We only care that the dir name we copy to is unique.
     unlink ( $dir );
 
-    exec ( "/bin/cp -a '$src' '$dir' 2>&1", $cpytxt, $status );  
+    exec ( "/bin/cp -a '$src' '$dir' 2>&1", $cpytxt, $status );
 
     if ( $status != 0 ) {
         die ( "src directory copy failed!" );
     }
-    return ( $dir );
+    return $dir;
 }
 
+/**
+ * Write gPXE config files based on value of given flags
+ *
+ * gPXE compile options are stored in src/config/*.h .
+ * We write out a config file for each set of options.
+ * 
+ * @param string $config_dir directory to write .h files to
+ * @param array  $flags array of compile options for this build
+ * 
+ * @return void
+ */
 function write_gpxe_config_files ( $config_dir, $flags ) 
 {
     global $flag_table;
@@ -413,48 +567,67 @@ function write_gpxe_config_files ( $config_dir, $flags )
     }
 }
 
-function write_embedded_file ( $fname, $ftext )
+/**
+ * Output a string to a file
+ *
+ * Output a given string to a given pathname. The file will be created if 
+ * necessary, and the string will replace the file's contents in all cases.
+ *
+ * @param string $fname pathname of file to output string to
+ * @param string $ftext text to output to file
+ *
+ * @return void
+ */
+function write_file_from_string ( $fname, $ftext )
 {
         $fp = fopen ( $fname, "wb" );
-        if ( $fp <= 0 ) {
+        if ( ! $fp ) {
             die ( "Unable to open $fname file for output!" );
         }
         fwrite ( $fp, $ftext );
         fclose ( $fp );
 }
 
-function deltempdir ( $dir )
+/**
+ * Delete a file or recursively delete a directory tree
+ *
+ * @param   string   $file_or_dir_name  name of file or directory to delete
+ * @return  bool     Returns TRUE on success, FALSE on failure
+ */
+function rm_file_or_dir ( $file_or_dir_name )
 {
-    $dp = opendir ( $dir );
-    if ( ! $dp ) {
-        die ( "opendir failed" );
+    if ( ! file_exists ( $file_or_dir_name ) ) {
+        return false;
     }
 
-    while ( $file = readdir ( $dp ) ) {
+    if ( is_file ( $file_or_dir_name ) || is_link ( $file_or_dir_name ) ) {
+        return unlink ( $file_or_dir_name );
+    }
 
-               $dir_or_file = "$dir/$file";
+    $dir = dir ( $file_or_dir_name );
+    while ( ( $dir_entry = $dir->read () ) !== false ) {
 
-        if ( is_dir ( $dir_or_file ) ) {
-            if ( $file[0] != "." ) {
-                deltempdir ( $dir_or_file );
-            }
-        } else {
-                       if ( file_exists ( $dir_or_file ) ) {
-                               unlink ( $dir_or_file );
-                       }
+        if ( $dir_entry == '.' || $dir_entry == '..') {
+            continue;
         }
+        rm_file_or_dir ( $file_or_dir_name . '/' . $dir_entry );
     }
-    closedir ( $dp );
-
-    if ( ! rmdir ( "$dir" ) ) {
-        die ( "rmdir failed" );
-    }
+    $dir->close();
+    
+    return rmdir ( $file_or_dir_name );
 }
 
 ////
 // Debugging functions
 ////
 
+/**
+ * Emit html code to display given array of compile options (flags)
+ *
+ * @param array  $flags array of compile options for this build
+ *
+ * @return void
+ */
 function show_flags ( $flags ) 
 {
     echo ( "\$flags contains " . count ( $flags ) . " elements:" . "<br>" );
@@ -464,10 +637,20 @@ function show_flags ( $flags )
     }
 }
 
+/**
+ * Emit HTML code to display default array of compile options (flags)
+ * 
+ * $flag_table contains default compile options and properties.  This
+ * routine outputs HTML code to display all properties of $flag_table.
+ *
+ * @return void
+ */
 function dump_flag_table () 
 {
     global $flag_table;
 
+    echo ( "\$flag_table contains " . count ( $flag_table ) . " elements:" . "<br>" );
+
        foreach ( $flag_table as $key => $props ) {
         print ( "flag_table[" . $key . "] = " . "<br>" );
 
@@ -477,18 +660,8 @@ function dump_flag_table ()
     }
 }
 
-function dump_flag_codes () 
-{
-    global $flag_codes;
-
-       foreach ( $flag_codes as $key => $props ) {
-        print ( "flag_codes[" . $key . "] = " . "<br>" );
-
-               foreach ( $props as $keys2 => $props2 ) {
-            print ( "&nbsp;&nbsp;&nbsp;" . $key2 . " = " . $props2 . "<br>" );
-        }
-    }
-}
+// Parse src/bin/NIC file
+list ( $nics, $roms ) = parse_nic_file ();
 
 // For emacs:
 // Local variables: