Subversion Repositories computer_asset_manager_v1

Rev

Rev 100 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

<?php


   /*
    * function will attempt to make a constant ($value) safe for SQL depending on the type.
    * 
    * if $value is empty, $default is returned, as will happen if any of the
    * conversions (date, datetime, etc...) fail.
    * 
    * First, it will pass it through get_magic_quotes_gpc, 
    * then will run through mysql_real_escape_string
    * 
    * For strings, will encapsulate in quotes
    * Dates will attempt a conversion, then change to YYYY-MM-DD and encapsulate in quotes
    *    if default is the constant now(), will pass that through to MySQL
    * DateTime will perform the same, but change to YYYY-MM-DD HH:MM:SS
    * Integer and Floats are passed through builtins intval and floatval
    * Boolean only checks the first character, a '0', 'f' and 'n' denoting false
    *    all else denoting true. The result is converted based on the variable
    *    $falsetrue, with the first char denoting false and the second denoting true
    */
   function makeSafeSQLConstant ( $value, $type='S', $default='null', $falsetrue='10' ) {
      // return $default on undefined or empty values
      if ( ! isset( $value ) ) return $default;
      if (strlen($value) == 0) return $default;
      // print "Processing $value as $type with default $default<br>\n";
      switch ( strtolower( $type ) ) {
         case 'string' :
         case 's' : 
                  if ( get_magic_quotes_gpc() ) 
                     $value = stripslashes($value);
                  $value = mysql_real_escape_string( $value );
                  $value = strlen( $value ) > 0 ? "'$value'" : $default;
                  break;
         case 'date' :
         case 'd' :
                  if ( $value != 'null' && $value != 'now()' ) {
                     $result = strtotime( $value );
                     $value = ( $result === false ) ? $default : "'" . Date( 'Y-m-d', $result) . "'";
                  }
                  break;
         case 'datetime':
         case 'timestamp':
         case 'dt': 
                  if ( $value != 'null' && $value != 'now()' ) {
                     $result = strtotime( $value );
                     $value = ( $result === false ) ? $default : "'" . Date( 'Y-m-d H:i:s', $result) . "'";
                  }
                  break;
         case 'integer':
         case 'i' :  
                  $value = intval( $value );
                  break;
         case 'float':
         case 'f' :  
                  $value = floatval( $value );
                  break;
         case 'bool':
         case 'boolean':
         case 'b' :  // note, because of the way strpos works, you can not
                     // simply set $value based on the output; you MUST do
                     // as below; specifically check for false, then set the result
                     $value =  strpos( '0fn', strtolower(substr( $value, 0, 1 )) ) === false ? 0 : 1;
                     $value = substr( $falsetrue, $value, 0, 1 );
                     break;
      } // switch
      return $value;
   }

   /*
    * Trims a value, then compares it to several 'null' possibilities
    * if it is a null, returns empty string, otherwise returns value
    */
   function cleanUpDMIValue( $value ) {
      $value = trim( $value );
      switch (strtolower( $value )) {
         case 'unknown':
         case 'unspecified' :
         case 'not available':
         case 'to be filled by o.e.m.':
         case 'not specified': return '';
      }
      return $value;
   }

   /*
    * Read value from array of hash, return array of "$outputKey\tvalue" for each entry found
    * If nothing found, returns empty array
    * if $unique is true, returns first non-empty value found
    * if $outputKey is not defined, uses $key
    */
   function getDMIInformation( $data, $type, $key, $outputKey = '', $unique = true ) {
      $return = array();
      foreach ( $data[$type] as $handle ) {
         if ( isset( $handle[$key]) ) {
            $a = cleanUpDMIValue( $handle[$key] );
            if ( $a ) {
               $return[] = ( $outputKey ? $outputKey : $key ) . "\t" . $a;
               if ( $unique ) {
                  return $return;
               }
            }
         }
      }
      return $return;
   }

   /*
    * adds $value to array
    * if $value is scalar, simply adds it
    * if $value is array, adds every row
    * returns modified array
    */
   function mergeArrays( $array, $value ) {
      if ( $value ) {
         switch (gettype( $value ) ) {
            case 'array' : foreach ( $value as $thisVal ) {
                              $array[] = $thisVal;
                           }
                           break;
            case 'boolean' :
            case 'integer' :
            case 'double'  :
            case 'string'  : $array[] = $value;
         } // switch
      }
      return $array;
   } //mergeArrays

   /*
    * Function will take an array of lines representing the output of a dmidecode file
    * and pick and choose the values we want to put into CAMP attributes.
    * It will return an array of key/value pairs to be added into the attributes table
    *
    * NOTE: this is a summary of values we decided to store. dmidecode files have a lot of
    * additional information we chose not to include
    * 
    */

   function dmidecode2array( $contents ) {

   // allows us to group the dmi types by function. not implemented
   $dmiGroups = array(
         "bios" => "0,13",
         "system" => "1,12,15,23,32",
         "baseboard" => "2,10,41",
         "chassis" => "3",
         "processor" => "4",
         "memory" => "5,6,16,17",
         "cache" => "7",
         "connector" => "8",
         "slot" => "9"
   );

   // This contains the standard DMI types, ie no OEM stuff. For reference, not used in code

   $standardDMITypes = array( 
         "0" => "BIOS",
         "1" => "System",
         "2" => "Baseboard",
         "3" => "Chassis",
         "4" => "Processor",
         "5" => "Memory Controller",
         "6" => "Memory Module",
         "7" => "Cache",
         "8" => "Port Connector",
         "9" => "System Slots",
         "10" => "On Board Devices",
         "11" => "OEM Strings",
         "12" => "System Configuration Options",
         "13" => "BIOS Language",
         "14" => "Group Associations",
         "15" => "System Event Log",
         "16" => "Physical Memory Array",
         "17" => "Memory Device",
         "18" => "32-bit Memory Error",
         "19" => "Memory Array Mapped Address",
         "20" => "Memory Device Mapped Address",
         "21" => "Built-in Pointing Device",
         "22" => "Portable Battery",
         "23" => "System Reset",
         "24" => "Hardware Security",
         "25" => "System Power Controls",
         "26" => "Voltage Probe",
         "27" => "Cooling Device",
         "28" => "Temperature Probe",
         "29" => "Electrical Current Probe",
         "30" => "Out-of-band Remote Access",
         "31" => "Boot Integrity Services",
         "32" => "System Boot",
         "33" => "64-bit Memory Error",
         "34" => "Management Device",
         "35" => "Management Device Component",
         "36" => "Management Device Threshold Data",
         "37" => "Memory Channel",
         "38" => "IPMI Device",
         "39" => "Power Supply",
         "40" => "Additional Information",
         "41" => "Onboard Devices Extended Information",
         "42" => "Management Controller Host Interface"
   );
      
      // verify this is something we can work with, First line should be the version of dmidecode found
      if ( preg_match('/dmidecode ([0-9.]+)/', $contents[0], $results) ) {
         $dmidecodeVersion = $results[1];
      } else {
         return "Not a valid dmidecode file";
      }
      // first, let's parse it into a hash
      $currentHandle = '';
      $currentType;
      $data = array();
      for ( $i = 0; $i < count($contents); $i++ ) {
         if ( preg_match('/^Handle ([0-9a-zx]+).*DMI type[^0-9]*(\d+),/i', $contents[$i], $outputArray) ) {
            //print "matched\n"; print_r($outputArray); die;
            $currentType = $outputArray[2];
            $currentHandle = $outputArray[1];
            if ( isset( $standardDMITypes[$currentType] ) || array_key_exists( $currentType,$standardDMITypes ) ) {
               $name = $contents[$i+1];
               $data[$currentType][$currentHandle]['name'] = $name;
               $i += 2; // skip the line with the name, and go to the next line
            } else {
               $currentType = $currentHandle = '';
            }
         }
         if ( $currentHandle &&  preg_match('/^\s+(.*):\s+(.*)$/i', $contents[$i], $outputArray) ) {
            $data[$currentType][$currentHandle][$outputArray[1]] = $outputArray[2];
         }
      }
      # well, we have at least one entry, so let's go
      $return = array();
      // manufacturer info
      $return = mergeArrays( $return, getDMIInformation( $data, '1','Manufacturer' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '1','Product Name', 'Model' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '1','Serial Number' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '1','UUID' ) );
      // physical machine
      $return = mergeArrays( $return, getDMIInformation( $data, '3','Type', 'Enclosure Type' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '3','Asset Tag', 'Enclosure Asset Tag' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '3','Height', 'Enclosure Height' ) );

      // firmware version
      $return = mergeArrays( $return, getDMIInformation( $data, '0','Vendor', 'Firmware Vendor' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '0','Release Date', 'Firmware Release' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '0','Version', 'Firmware Version' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '0','Firmware Revision', 'Firmware Revision' ) );
      // processor information. NOTE: assumes all sockets populated and all processors the saem
      if ( isset( $data['4'] ) ) // count the number of sockets
         $return[] = "CPU Count\t" . count( $data['4'] );
      $return = mergeArrays( $return, getDMIInformation( $data, '4','Family', 'CPU Family' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '4','Manufacturer', 'CPU Manufacturer' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '4','Version', 'CPU Version' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '4','Current Speed', 'CPU Speed' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '4','Core Count', 'CPU Cores (ea)' ) );
      $return = mergeArrays( $return, getDMIInformation( $data, '4','Thread Count', 'CPU Threads (ea)' ) );

      /*
       * memory information. We want details on each slot for this, so we have to go through each entry, one at a time.
       * For readability, we also want to take several values and turn them into one human
       * readable string for each socket. So, we go through each entry in the memory socket, determine if it is populated
       * then concat it together for a pretty output
       */
      
      if ( isset( $data['17'] ) ) {
         $return[] = "Memory Slots\t" . count( $data['17'] );
         $totalRAM = 0; // we'll accumulate the total size as we find slots populated
         foreach ( $data['17'] as $entry ) { // type 17 has one entry for every DIMM slot
            $mem = array(); // fill this up with the values we want to turn into a string, then we'll implode it into the string
            $mem[] = trim($entry['Locator'] ? $entry['Locator'] : ($entry['Bank Locator'] ? $entry['Bank Locator'] : '' ));
            if ( $entry['Size'] == 'No Module Installed' ) {
               $mem[] = 'Unpopulated';
            } else {
               $mem[] = trim($entry['Size']); // size can be kilo, meg, gig, tera, so convert it to mega
               if ( preg_match('/(\d+)\s+(GB|MB|TB|kb)/i', $entry['Size'] , $outputArray) ) {
                  switch ( strtolower( $outputArray[2] ) ) {
                     case 'gb' :
                              $outputArray[1] *= 1024;
                              break;
                     case 'tb' : 
                              $outputArray[1] *= 1024 * 1024;
                              break;
                     case 'kb' : 
                              $outputArray[1] /= 1024;
                              break;
                  }
                  $totalRAM += $outputArray[1];
               }
               $mem[] = trim($entry['Form Factor']);
               $mem[] = trim($entry['Type']);
               $mem[] = trim($entry['Data Width']);
               if ( isset( $entry['Configured Clock Speed']) && isset($entry['Speed']) && cleanUpDMIValue($entry['Configured Clock Speed']) && cleanUpDMIValue($entry['Speed']) )
                  $mem[] = cleanUpDMIValue($entry['Configured Clock Speed'] . '/' . cleanUpDMIValue($entry['Speed']) );
               if ( isset($entry['Manufacturer']) && cleanUpDMIValue($entry['Manufacturer']) )
                  $mem[] = cleanUpDMIValue($entry['Manufacturer']);
               if ( isset($entry['Part Number']) && cleanUpDMIValue( $entry['Part Number'] ) )
                  $mem[] = 'p/n ' . cleanUpDMIValue($entry['Part Number']);
               if ( isset($entry['Serial Number']) && trim($entry['Serial Number']) != 'Not Specified' )
                  $mem[] = 's/n ' . cleanUpDMIValue($entry['Serial Number']);
            }
            $return[] = "Memory\t" . implode( ', ', $mem );
         }
         $return[] = "Memory Total\t$totalRAM MB";
      }

      /*
       * power supplies. Most workstations will not even have an entry here, but for servers we will have details on each individual
       * power supply, including the part number, serial number, etc..., so like memory, we want a detailed listing with a human
       * readable string for each psu
       */
      if ( isset( $data['39'] ) ) {
         $return[] = "Power Supply Count\t" . count( $data['39'] );
         foreach ( $data['39'] as $entry ) {
            if ( preg_match('/^Present/i', $entry['Status'] ) ) {
               $psu = array();
               $psu[] = trim($entry['Name']);
               $psu[] = trim($entry['Max Power Capacity']);
               $psu[] = trim($entry['Manufacturer']);
               $psu[] = 'p/n ' . trim($entry['Model Part Number']);
               $psu[] = 's/n ' . trim($entry['Serial Number']);
               $return[] = "Power Supply\t" . implode( ', ', $psu );
            }
         }
      }
      return array( $return );
   }  // dmidecode2array

   /*
    * Test code for dmidecode input
    */
   /*
   $filename = $argv[1];
   if ( $filename ) {
      $contents = file( $filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
      $out = dmidecode2array( $contents );
      print_r( $out );
   } else {
      print "You must pass the file as the first command line parameter\n";
   }
   */

   /****************************************************************************************
    * Functions to process an array the device_attrib table
    ***************************************************************************************/

   /*
    * takes a tab delimited array of lines and turns it into an array of array
    * Assumes first line contains the headers
    * turns the file
    * header1\theader2\theader3
    * value1\tvalue2\tvalue3
    *
    * into
    * [0]
    *    header1=>value1
    *    header2=>value2
    *    header3=>value3
    *
    * $contents is an array of lines, with each line having multiple
    * fields delimited by $delimiter
    * 
    */
   function tabDelimToArray($contents, $delimiter = "\t" ) {
      $rows = array();
      if ( gettype($contents) != 'array' )
         $contents = explode( "\n", $contents );
      $headers = explode( $delimiter, array_shift( $contents ) );
      for  ( $line = 0; $line < count( $contents ); $line++ ) {
         if ( $contents[$line] ) {
            $thisLine = explode( $delimiter, $contents[$line] );
            $thisLine = preg_replace( '/^\s+/', '', $thisLine );
            $thisLine = preg_replace( '/\s+$/', '', $thisLine );
            $columns = array();
            for ( $i = 0; $i < count( $headers ); $i++ ) {
               $columns[$headers[$i]] = $thisLine[$i];
            } // for
            $rows[] = $columns;
         } // if
      } // while
      return $rows;
   } // function

   /*
    * getDeviceID
    */
   function getDeviceID( $device, $createIfNotFound = false, $site = '', $client = '', $site_id = 0, $client_id = 0 ) {
      $device = makeSafeSQLConstant( $device, 's', '' );
      if ( ! $device ) return 0;
      $device_id = getOneDBValue( "select device_id from device where name = $device" );
      if ( $device_id ) return $device_id;
      if ( $createIfNotFound ) {
         if ( ! $site_id ) {
            $site_id = findSite( $site, $client, $site_id, $client_id );
         }
         if ( $site_id ) {
            $site_id = makeSafeSQLConstant( $site_id,'i','' );
            $result = queryDatabaseExtended( "insert into device (site_id,device_type_id,name,added_date,removed_date) values( $site_id,1,$device,now(),null )" );
            if ( $result['insert_id'] )
               return $result[insert_id];
         }
      }
      return 0;
   } // getDeviceID


   function getAttributeID( $attribute, $createIfNotFound = false ) {
      $attribute = makeSafeSQLConstant( $attribute, 's', '' );
      if ( ! $attribute ) return 0;
      $return = getOneDBValue( "select attrib_id from attrib where name = $attribute" );
      if ( ! $return && $createIfNotFound ) {
         $return = queryDatabaseExtended( "insert into attrib( name, added_date, removed_date ) values ( $attribute, now(), null )" );
         return $result['insert_id'] ? $result['insert_id'] : 0;
      }
      return $return;
   }

   /*
    * returns true if the value is empty or null
    */
   function nullOrEmpty( $str ) {
      return ( !isset( $str) || trim($str) === '');
   }

   /*
    * Takes a two dimensional array and adds/updates the values in device_attrib
    * 
    * $contents is an array of array, where they keys for each sub-array is the field name of the table to insert/update
    * $unique if true will replace any existing key for the device in question
    * $createDeviceIfNotFound, if true, will create any device name found if it doesn't exist
    * $device_id is used for the insert/update unless $device_id is a key in any row in the array
    * $site_id is used to A) uniquely identify a device or B) create the device if $createDeviceIfNotFound is true and device not foudn
    * $client_id is used the same way as $site_id
    *
    * $contents is assumed to be
    * [0] => {
    *           [value]     => string to be set/added to device_attrib table
    *           [attrib_id] => key from attrib table
    *           [attribute] => string matching name from attrib table
    *           [device_id] => key from device table
    *           [device]    => string matching name from device table
    *           [site_id]   => key from site table
    *           [site]      => string matching name from site table
    *           [client_id] => key from client table
    *           [client]    => string matching name from client table
    *         }
    * [1] =>  { another set of values the same as above }
    *
    * The only required values are attrib_id (or attribute) and value. If this is the case, it will be added to the device from
    * parameter $device_id
    *
    * If [something_id] is found, that is used. If it is null (or doesn't exist), an attempt is made to determine the proper
    * id from the database by looking for the string. If that is null, the parameter passed to this function is used. If all of
    * that fails, the row is returned to the caller.
    *
    */
   function parseTabDelimFile ( $contents, $createAttributeIfNotFound = false, $createDeviceIfNotFound = false, $default_device_id='', $default_site_id='', $default_client_id='' ) {
      $data = tabDelimToArray( $contents );
      // we'll put our SQL into an array, then dump it.
      $sql = array();
      // the following two arrays will store attributes and devices as we find them
      // we can then FIRST look them up here, in memory, and go to database only when we don't know them
      $attributesFromDatabase = array(); // uniquely store our attributes here
      $deviceFromDatabase = array();
      for ( $i = 0; $i < count( $data ); $i++ ) {  // go through each line and grab fields we need

         // get device_id
         if ( ! $data[$i]['device_id'] ) {
            if ( $data[$i]['device'] ) {
               if ( isset( $deviceFromDatabase[$data[$i]['device']] ) ) {
                  $data[$i]['device_id'] = $deviceFromDatabase[$data[$i]['device']];
               } else {
                  $data[$i]['device_id'] = getDeviceID( $data[$i]['device'], $createDeviceIfNotFound, $default_site_id, $default_client_id );
               }
               if ( $data[$i]['device_id'] )
                  $deviceFromDatabase[$data[$i]['device']] = $data[$i]['device_id'];
            }
            if ( ! $data[$i]['device_id'] ) {
               if ( $default_device_id ) {
                  $data[$i]['device_id'] = $default_device_id;
               } else {
                  $sql[] = "/* Can not locate device in line $i */";
                  continue;
               }
            }
         }

         // get attribute_id
         if ( ! $data[$i]['attrib_id'] ) {
            if ( $data[$i]['attribute'] ) {
               if ( isset( $attributesFromDatabase[$data[$i]['attribute']] ) ) {
                  $data[$i]['attrib_id'] = $attributesFromDatabase[$data[$i]['attribute']];
               } else {
                  $data[$i]['attrib_id'] = getAttributeID( $data[$i]['attribute'], $createAttributeIfNotFound );
               }
               if ( $data[$i]['attrib_id'] )
                  $attributesFromDatabase[$data[$i]['attribute']] = $data[$i]['attrib_id'];
            }
            if ( ! $data[$i]['attrib_id'] ) {
               $sql[] = "/* Can not locate attribute in line $i */";
               continue;
            }
         }
         
         if ( ! $data[$i]['value'] ) {
            $sql[] = "/* No Value given for line $i, skipped */";
            continue;
         }

         $value = makeSafeSQLConstant( $data[$i]['value'] );
         $attrib_id = makeSafeSQLConstant( $data[$i]['attrib_id'], 'i' );
         $device_id = makeSafeSQLConstant( $data[$i]['device_id'],'i' );
         // standard SQL that does an insert if the value doesn't already exist.
         $sql[] =
            "insert into attrib_device ( device_id, attrib_id,value, added_date )
               select $device_id,$attrib_id, $value, now()
               from dual
               where
                  not exists (
                     select * from attrib_device join device using (device_id) join attrib using (attrib_id) where device_id = $device_id and attrib_id = $attrib_id
                     );";
      }
      return $sql;
   }


   /*
    * following block of code is duplicated from the files module. It should instead be placed in root/include/library.php or something
    */

   /*
    * function designed to handle input from a form. If the input is
    * unset, will retrun the $default value.
    * Otherwise, will filter the value based on $filter
    * Some common filters are:
    *    FILTER_SANITIZE_SPECIAL_CHARS - clean up text so no HTML
    *    FILTER_SANITIZE_EMAIL         - email addresses
    *    FILTER_SANITIZE_NUMBER_FLOAT  - floating point numbers
    *    FILTER_SANITIZE_NUMBER_INT    - integers
    *    FILTER_SANITIZE_URL           - A URL
    * http://php.net/manual/en/filter.filters.sanitize.php
    */
   function cleanInput ( $value, $default = '', $filter = FILTER_DEFAULT ) {
      // unset or empty values just get the default
      if ( ! isset( $value ) || strlen( trim( $value ) ) == 0 ) return $default;
      
      return filter_var( trim( $value ), $filter );
   }
   

   function return_bytes($val) {
       $val = trim($val);
       $last = strtolower($val[strlen($val)-1]);
       switch($last) 
       {
           case 'g':
           $val *= 1024;
           case 'm':
           $val *= 1024;
           case 'k':
           $val *= 1024;
       }
       return $val;
   } // return_bytes
   
   function prettyPrintBytes( $value ) {
      $sizes = array( '', 'kilo', 'mega', 'giga', 'tera' );
      while ( $value > 1024 ) {
         $value /= 1024;
         $index++;
      }
      return intval( $value ) . ' ' . $sizes[$index] . 'bytes';
   }
   
   function maxUploadFileSize () {
       //select maximum upload size
       $max_upload = return_bytes(ini_get('upload_max_filesize'));
       //select post limit
       $max_post = return_bytes(ini_get('post_max_size'));
       //select memory limit
       $memory_limit = return_bytes(ini_get('memory_limit'));
       // return the smallest of them, this defines the real limit
       return prettyPrintBytes( min($max_upload, $max_post, $memory_limit) );
    } // maxUploadFileSize
    
    function getFileUploadError( $error ) {
       $message = '';
       switch ( $error ) {
          case 0 : $message = 'There is no error, the file uploaded with success';
                   break;
          case 1 : $message = 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
                   break;
          case 2 : $message = 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form';
                   break;
          case 3 : $message = 'The uploaded file was only partially uploaded';
                   break;
          case 4 : $message = 'No file was uploaded';
                   break;
          case 6 : $message = 'Missing a temporary folder';
                   break;
          case 7 : $message = 'Failed to write file to disk.';
                   break;
          case 8 : $message = 'A PHP extension stopped the file upload.';
       }
       return array( 'valid' => $error == 0, 'message' => $message );
    } // getFileUploadError
 
   function uploadFile ( $source, $nameOnDisk ) {
      $saveTo = getAbsolutePath( $nameOnDisk );
      if ( makePath( $saveTo ) ) {
         logIt( "Path Made - $saveTo" );
         logIt( "moving $source to $saveTo" );
         $result['valid'] = move_uploaded_file( $source, $saveTo );
      } else {
         $result = array( 'valid'=>false, 'message' => print_r(error_get_last(), true) );
      } // if move_uploaded_file .. else
      return $result;
   } // uploadFile

   
?>
   

?>