Subversion Repositories computer_asset_manager_v1

Rev

Rev 23 | Rev 25 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 23 Rev 24
Line 5... Line 5...
5
 *
5
 *
6
 * apt-get install php-pear php5-dev libyaml-dev libyaml-0-2 libyaml-0-2-dbg
6
 * apt-get install php-pear php5-dev libyaml-dev libyaml-0-2 libyaml-0-2-dbg
7
 * pecl install yaml
7
 * pecl install yaml
8
 * echo 'extension=yaml.so' >> /etc/php5/cli/php.ini
8
 * echo 'extension=yaml.so' >> /etc/php5/cli/php.ini
9
 * echo 'extension=yaml.so' >> /etc/apache2/cli/php.ini
9
 * echo 'extension=yaml.so' >> /etc/apache2/cli/php.ini
10
 *
-
 
11
 * V0.9 20160203 RWR
-
 
12
 * Changed to use yaml for the configuration file. Had to take the
-
 
13
 * anonymous functions which parsed the different file types and convert
-
 
14
 * them to simpl eval() blocks.
-
 
15
 * 
10
 * 
16
 * V0.9.2 20160217 RWR
-
 
17
 * Fixed issue where if a device was marked as part of a Xen machine, it
11
 * alter table backups_run add skipped bigint(20),add file_name varchar(60),add notes text;
18
 * was being deleted by pci updates.
12
 * alter table backups_run modify end_time  datetime null, modify start_time datetime null;
19
 * 
13
 * 
20
*/
14
*/
21
 
15
 
22
require 'library.php';
16
require 'library.php';
23
$VERSION='0.9.2';
17
$VERSION='0.1.0';
24
 
-
 
25
 
-
 
26
class sysinfo {
-
 
27
   private $report; // this will hold an entire report
-
 
28
   private $messages = array();
-
 
29
   private $FATAL = false;
-
 
30
   private $parsingArray;   // this is a required array that teaches how to properly parse the input
-
 
31
 
-
 
32
   // following are used internally to track important information
-
 
33
   private $clientID;   // id in database
-
 
34
   private $clientName; // name from report
-
 
35
   private $machineID;  // id in database
-
 
36
   private $machineName;// name in report
-
 
37
   private $reportDate; // unix timestamp of report
-
 
38
   private $reportDateSQL; // used for inserts and compares in the database
-
 
39
   private $serialNumber; // the serial number, which is assumed to be unique
-
 
40
   private $fileContents;
-
 
41
   private $processDuplicates = false; // used for testing; allows duplicate reports
-
 
42
   private $returnCode = 0; // how we returned from this
-
 
43
   private $errors = array( 1 => 'Could not process file, not xml, yaml or ini',
-
 
44
                            2 => 'Invalid report, does not have one or more of report date, client name or computer name',
-
 
45
                            3 => 'Invalid Report, invalid machine name',
-
 
46
                            4 => 'Duplicate Report',
-
 
47
                            5 => 'New Report, must be added to CAMP',
-
 
48
                            6 => 'Report is in queue for addition after updates to CAMP'
-
 
49
                          );
-
 
50
   
-
 
51
   /*
-
 
52
    * $parsingArray contains one or more rows, each of which have three rows, starttag, endtag and eval
-
 
53
    * starttag and endtag are regex's which match the beginning and end of a document (ie, --- and ... for yaml)
-
 
54
    * eval is an anonymous function which will evaluate a particular type of document, returning it as an
-
 
55
    * array which we store in $report
-
 
56
    */
-
 
57
   
-
 
58
   function __construct( $parsingArray ) {
-
 
59
      $this->parsingArray = $parsingArray;
-
 
60
   }
-
 
61
 
18
 
62
   public function processReport () {
-
 
63
      $this->validateReport(); // validate the report appears to be ok
-
 
64
      // prepend the name of the report to messages BEFORE any error messages that may have appeared
-
 
65
      array_unshift( $this->messages,
-
 
66
            "Report on $this->reportDateSQL, client $this->clientName, system $this->machineName ($this->fileType)");
-
 
67
      // now, we do every step in turn. If they set the FATAL flag, we exit.
-
 
68
      if ( $this->FATAL ) return $this->returnCode;
-
 
69
      $this->getMachineID();
-
 
70
      if ( empty( $this->machineID ) ) return $this->returnCode;
-
 
71
      $this->checkDuplicate();
-
 
72
      if ( $this->FATAL) return $this->returnCode;
-
 
73
      $this->updateComputerMakeup();
-
 
74
      $this->updateOS();
19
$results = array();
75
      $this->updateBootTime();
-
 
76
      $this->doIPAddresses();
-
 
77
      $this->processPCI();
-
 
78
      $this->processSoftwarePackages();
-
 
79
      // at this point, we don't really need the report title information
-
 
80
      // so we will remove it before recordReport has a chance to put it
-
 
81
      // in database
-
 
82
      array_shift( $this->messages );
-
 
83
      // now record the report
-
 
84
      $this->recordReport();
-
 
85
      return $this->returnCode;;
-
 
86
   } // function processReport
-
 
87
 
-
 
88
   /* 
-
 
89
    * Name: loadFromFile
-
 
90
    * Parameters: filename (path to load file from)
-
 
91
    * Returns: true if on success, false if not
-
 
92
    * Modifies: 
-
 
93
    *    report - added messages on why the report is not valid
-
 
94
    *    FATAL    - set to true if any of the required values do not exist
-
 
95
    */
-
 
96
 
20
 
-
 
21
function parseFile( $filename, $path, $maxLineLength = 4096 ) {
-
 
22
   $data = array ( 
-
 
23
                     'server_name' => '',
-
 
24
                     'report_date' => '',
-
 
25
                     'start_time' => '',
-
 
26
                     'version' => '',
-
 
27
                     'end_time' => '',
-
 
28
                     'files_count' => '',
-
 
29
                     'files_size' => '',
-
 
30
                     'transferred_count' => 0,
-
 
31
                     'transferred_size' => '',
-
 
32
                     'files_deleted' => 0,
-
 
33
                     'skipped' => 0,
-
 
34
                     'data_sent' => '',
-
 
35
                     'data_received' => '',
-
 
36
                     'disk_used' => '',
-
 
37
                     'notes' => '',
-
 
38
   );
-
 
39
 
-
 
40
   /*
-
 
41
    * This will return error codes
-
 
42
    * 1 - Invalid Data File Name
-
 
43
    * 2 - Could not open the file
-
 
44
    */
-
 
45
 
-
 
46
   $matches = array();
-
 
47
 
-
 
48
   $line;
-
 
49
 
-
 
50
   $data['file_name'] = $filename;
-
 
51
   # get server name from the file name, which should be
-
 
52
   # datetime_servername.backup.log
-
 
53
   if ( preg_match( '/(\d+)_([a-z0-9-.]+)\.backup\.log/', $filename, $matches ) ) {
-
 
54
      $data['report_date'] = $matches[1];
-
 
55
      $data['server_name'] = $matches[2];
-
 
56
   } else {
-
 
57
      # ensure only three parts returned
-
 
58
      $data['error'] = "1\tInvalid Data File Name";
-
 
59
      return $data;
-
 
60
   }
-
 
61
 
97
   public function loadFromFile ( $filename ) {
62
   $log = fopen ( $path . '/' . $filename , 'rb' );
-
 
63
   if ( $log ) {
-
 
64
      // get through the header lines
-
 
65
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
-
 
66
         if ( preg_match( '/^backup\s+v?([\d.]+)$/', $line, $matches ) ) {
-
 
67
            $data['version'] = $matches[1];
-
 
68
         }
-
 
69
         // this line is the end of the header lines
-
 
70
         if ( preg_match( '/sending incremental file list/', $line, $matches ) ) {
-
 
71
            break;
-
 
72
         }
-
 
73
      }
-
 
74
      
98
      // load file into memory. Additionally, remove any \r's from it (leaving \n's for newlines)
75
      // count line by line processing information. These are the actual lines
-
 
76
      // indicating files checked and how they were processed
99
      $this->fileContents = str_replace("\r","", file_get_contents( $filename ) );
77
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
100
      // try to parse the body out
78
         $line = rtrim($line);
101
      $this->getBody();
79
         if ( $line ) {
-
 
80
            if ( ! preg_match( '~/$~', $line ) ) // count lines not ending in /, ie not directories
102
      if ( isset( $this->report ) ) {
81
               $data['transferred_count']++;
103
         if ( $this->fileType == 'xml' ) $this->fixXML();
82
            if ( preg_match( '/^deleting /', $line ) ) // count number deleted
104
         if ( $this->fileType == 'ini' ) {
83
               $data['files_deleted']++;
105
            $this->messages[] = 'We do not process ini files, but storing it instead';
84
            if ( preg_match( '/^skipping /', $line ) )  // count number skipped
-
 
85
               $data['skipped']++ ;
-
 
86
         } else {
-
 
87
            break;
106
         }
88
         }
107
         return $this->fileType;
-
 
108
      } else { // we don't know what it is
-
 
109
         $this->FATAL = true;
-
 
110
         $this->messages[] = "Unable to parse [$filename] using YAML, XML or INI";
-
 
111
         return false;
-
 
112
      }
89
      }
113
      //unset( $this->fileContents ); // free up memory
-
 
114
   } // function loadFromFile
-
 
115
   
-
 
116
 
-
 
117
   // once the file has been loaded, we need to figure out what kind of file it is
-
 
118
   // then use the function embedded in $parsingArray to import it.
-
 
119
   private function getBody ( ) {
-
 
120
      foreach ( $this->parsingArray as $key => $regexes ) {
-
 
121
         $matches;
-
 
122
         $pattern = $regexes['startTag'] . '.*' . $regexes['endTag'];
-
 
123
         if ( preg_match( "/$pattern/ms", $this->fileContents, $matches ) ) {
-
 
124
            $this->fileType = $key;
-
 
125
            $this->fileContents = $matches[0];
-
 
126
            $body = $this->fileContents;
-
 
127
            $this->report = eval( $regexes['eval'] );
-
 
128
            if ( $this->report ) return true;
-
 
129
         } // if
-
 
130
      } // foreach
-
 
131
      return false;
-
 
132
   }
-
 
133
 
-
 
134
   /*
-
 
135
    * Name: fixXML
-
 
136
    * Parameters: None
-
 
137
    * Returns: nothing
-
 
138
    * Modifies: $this->report
-
 
139
    * YAML creates the entries as ['network']['interface name']
-
 
140
    * XML  creates the entries as ["network"][x][name]=>
-
 
141
    * We will simply copy the XML information into a duplicate
-
 
142
    * in YAML style
-
 
143
    */
-
 
144
   private function fixXML() {
-
 
145
       $oldInfo = $this->report['network'];
-
 
146
       unset ($this->report['network']);
-
 
147
       foreach ( $oldInfo as $entry ) {
-
 
148
          #$this->messages[] = "Duplicating network entry for $entry[name]";
-
 
149
          foreach ($entry as $key => $value ) {
-
 
150
             $this->report['network'][$entry['name']][$key] = $value;
90
      $data['transferred_count'] -= $data['files_deleted'] + $data['skipped'];
151
             #$this->messages[] = "  Adding  $value as value for network.name.$key";
-
 
152
          } // inner foreach
-
 
153
       } // outer foreach
-
 
154
   } // fixXML
-
 
155
      
-
 
156
 
91
 
157
   private function processINI() {
92
      // we should have a stats summary at the end
-
 
93
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
-
 
94
         $data['notes'] .= $line; // everything here goes into notes
-
 
95
         if ( preg_match( '/Number of files:\s+(\d+)/', $line, $matches ) ) {
158
      return false;
96
            $data['files_count'] = $matches[1];
159
   }
-
 
160
   
-
 
-
 
97
         } elseif ( preg_match( '/Number of files transferred:\s+(\d+)/', $line, $matches ) ) {
-
 
98
            $data['transferred_count'] = $matches[1];
-
 
99
         } elseif ( preg_match( '/Total file size:\s+(\d+) bytes/', $line, $matches )  ) {
161
   public function dumpMessages () {
100
            $data['files_size'] = $matches[1];
-
 
101
         } elseif ( preg_match( '/Total transferred file size:\s+(\d+) bytes/', $line, $matches )  ) {
-
 
102
            $data['transferred_size'] = $matches[1];
-
 
103
         } elseif ( preg_match( '/Total bytes sent:\s+(\d+)/', $line, $matches )  ) {
162
      $return = '';
104
            $data['data_sent'] = $matches[1];
-
 
105
         } elseif ( preg_match( '/Total bytes received:\s+(\d+)/', $line, $matches )  ) {
163
      if ( $this->messages ) {
106
            $data['data_received'] = $matches[1];
-
 
107
         } elseif ( preg_match( '/Backup Version\s+v?([\d.]+)/', $line, $matches )  ) {
-
 
108
            // this is the end of the rsync stats summary, and the
-
 
109
            // beginning of the rsbackup summary
164
         $return = implode( "\n", $this->messages );
110
            $data['version'] = $matches[1];
165
         $return .= "\n";
111
            break;
-
 
112
         }
166
      }
113
      }
-
 
114
      
-
 
115
      // process rsbackup summary
-
 
116
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
-
 
117
         $data['notes'] .= $line;
-
 
118
         if ( preg_match( '/^Begin\s+(\d+)/', $line, $matches )   ) {
-
 
119
            $data['start_time'] = $matches[1];
-
 
120
         } elseif ( preg_match( '/Complete\s+(\d+)/', $line, $matches )   ) {
-
 
121
            $data['end_time'] = $matches[1];
-
 
122
         } elseif ( preg_match( '/^Status:/', $line, $matches )   ) {
167
      return $return;
123
            break;
-
 
124
         }
-
 
125
      }
-
 
126
      // the rest of it just goes into notes
-
 
127
      while (( $line = fgets( $log, $maxLineLength )) !== false ) {
-
 
128
         $data['notes'] .= $line;
-
 
129
      }
-
 
130
      fclose ( $log );
-
 
131
   } else {
-
 
132
      $data['error'] = "2\tCould not open file name $filename for read";
168
   }
133
   }
169
   
-
 
170
   /* 
-
 
171
    * Name: validateReport
-
 
172
    * Parameters: none
-
 
173
    * Returns: true if valid, false if not
-
 
174
    * Modifies: 
134
   return $data;
175
    *    messages - added messages on why the report is not valid
-
 
176
    *    FATAL    - set to true if any of the required values do not exist
-
 
177
    */
-
 
178
 
135
 
179
      public function validateReport () {
-
 
180
      /*
-
 
181
       * A report is considered valid if it has a date, client name and hostname
-
 
182
       * No check is made at this time for validity of that data
-
 
183
       */
-
 
184
      if ( empty( $this->report['report']['date']) ) {
-
 
185
         $this->messages[] = 'No report date';
-
 
186
      } else {
-
 
187
         $this->reportDate = strtotime( $this->report['report']['date'] ); // store in Unix timestamp
-
 
188
         $this->reportDateSQL = strftime( '%F %T', $this->reportDate ); // save a copy of the date in SQL format
-
 
189
         if ( empty( $this->reportDate ) )
-
 
190
            $this->messages[] = "Unable to parse report date [$this->report['report']['date']]";
-
 
191
      }
136
}
192
         
-
 
193
      if ( empty( $this->report['report']['client'] ) ) {
-
 
194
         $this->messages[] = 'No client name';
-
 
195
      } else {
-
 
196
         $this->clientName = $this->report['report']['client'];
-
 
197
      }
-
 
198
 
137
 
199
      if ( empty ( $this->report['system']['hostname'] ) ) {
-
 
200
         $this->messages[] = 'No Computer Name';
-
 
201
      } else {
-
 
202
         $this->machineName = $this->report['system']['hostname'];
-
 
203
      }
-
 
204
      $this->FATAL = ! empty( $this->messages );
-
 
205
      
-
 
206
      /* removed for the time being.
-
 
207
      // serial number is fairly new, so it is not a critical error
-
 
208
      // it will be set in getMachineID if we have it here, but not there
-
 
209
      if ( empty ( $this->report['system']['serial'] ) ) {
-
 
210
         $this->messages[] = 'No Serial Number';
-
 
211
      } else {
-
 
212
         $this->serialNumber = $this->report['system']['serial'];
-
 
213
      }
-
 
214
      */
-
 
215
      
-
 
216
   } // function validateReport
-
 
217
 
138
 
-
 
139
function recordMessage( $message ) {
-
 
140
   global $results;
-
 
141
   $results[] = $message;
-
 
142
}
218
 
143
 
219
   /* 
-
 
220
    * Name: getMachineID
-
 
221
    * Parameters: none
-
 
222
    * Returns: true if found, false if not
-
 
223
    * Modifies: 
-
 
224
    *    clientID - index value of client in database
-
 
225
    *    machineID - index value of machine in database
-
 
226
    */
-
 
227
   private function getMachineID () {
-
 
228
      $this->clientID = getClientID( $this->clientName );
-
 
229
      if ( $this->clientID ) {
-
 
230
         $this->machineID = getMachineID( $this->machineName, $this->clientID, $this->serialNumber );
-
 
231
      }
-
 
232
      if ( empty( $this->machineID ) ) {
-
 
233
         $this->messages[] = $this->makeUnknown( $this->clientName, $this->machineName, $this->reportDateSQL );
-
 
234
         return false;
-
 
235
      }
-
 
236
      if ( $this->machineID == -1 ) {
-
 
237
         $this->messages[] = "Duplicate serial number found for serial [$this->serialNumber], aborting";
-
 
238
         return false;
-
 
239
      }
-
 
240
      return true;
-
 
241
   } // function getMachineID
-
 
242
   
-
 
243
   /* 
-
 
244
    * checks for a duplicate report, ie one that has already been run.
-
 
245
    * if this computer has a report already for this date/time
-
 
246
    */ 
-
 
247
   private function checkDuplicate() {
-
 
248
      $count = getOneDBValue("select count(*) from sysinfo_report where device_id = $this->machineID and report_date = '$this->reportDateSQL'");
-
 
249
      if ( $this->processDuplicates ) { $count = 0; } // for testing
-
 
250
      if ( $count ) {
-
 
251
         $this->messages[] = "Duplicate Report for $this->machineName (id $this->machineID) on $this->reportDateSQL";
-
 
252
         $this->returnCode = 4;
-
 
253
         $this->FATAL = true;
-
 
254
         return false;
-
 
255
      }
-
 
256
      return true;
-
 
257
   } // recordReport
-
 
258
   
-
 
259
   
-
 
260
   /* 
-
 
261
    * Creates an entry in the sysinfo_report table
-
 
262
    */ 
-
 
263
   private function recordReport() {
-
 
264
      $version = $this->report['report']['version'];
-
 
265
      $messages = makeSafeSQLValue( $this->dumpMessages() );
-
 
266
      // if we made it this far, we are ok, so just add the report id
-
 
267
      queryDatabaseExtended("insert into sysinfo_report(device_id,version,report_date, notes,added_date) values ($this->machineID ,'$version','$this->reportDateSQL',$messages,now())");
-
 
268
      $this->reportID = getOneDBValue("select max( sysinfo_report_id ) from sysinfo_report where device_id = $this->machineID and report_date = '$this->reportDateSQL'");
-
 
269
      return true;
-
 
270
   } // recordReport
-
 
271
   
-
 
272
   
-
 
273
   function makeUnknown( $clientName, $machineName, $reportDate ) {
-
 
274
      $result = getOneDBValue("select report_date from unknown_entry where client_name = '$clientName' and device_name = '$machineName'");
-
 
275
      if ( empty( $result ) ) {
-
 
276
         queryDatabaseExtended( "insert into unknown_entry(client_name,device_name,report_date) values ('$clientName', '$machineName', '$reportDate')");
-
 
277
         $this->returnCode = 5;
-
 
278
         return "New entry, client=$clientName, device=$machineName. You must update Camp before this report can be processed";
-
 
279
      } else {
-
 
280
         $this->returnCode = 6;
-
 
281
         return "New entry detected, but entry already made. You must update Camp before this can be processed";
-
 
282
      }
-
 
283
   }
-
 
284
   
-
 
285
   // simply used to get an attrib_id. If it does not exit, will create it
-
 
286
 
144
 
-
 
145
/* 
-
 
146
 * checks for a duplicate report, ie one that has already been run.
-
 
147
 * if this computer has a report already for this date/time
-
 
148
 */ 
287
   private function getAttributeID ( $attributeName, $reportDate ) {
149
function checkDuplicate( $backups_id, $report_date) {
-
 
150
   $sql = "select count(*) from backups_run where backups_id = $backups_id and report_date = $report_date";
288
      $attributeName = makeSafeSQLValue( $attributeName );
151
   $count = getOneDBValue( $sql );
-
 
152
   return $count ? "3\tDuplicate Report for $backups_id on $report_date" : null;
-
 
153
} // recordReport
-
 
154
   
-
 
155
 
-
 
156
function findServer( $name ) {
289
      $result = getOneDBValue( "select attrib_id from attrib where name = $attributeName and removed_date is null" );
157
   $sql = "select distinct( device_id ) from (select device_id from device where name = '$name' union select device_id from device_alias where alias = '$name') a";
-
 
158
   $device_id = getOneDBValue( $sql );
290
      if ( !isset( $result) ) {
159
   if ( ! isset( $device_id ) ) {
291
         $result = queryDatabaseExtended( "insert into attrib (name,added_date) values ($attributeName,'$reportDate')");
160
      recordMessage( "Could not locate device $name, not processing record" );
-
 
161
      return null;
-
 
162
   }
292
         $this->messages[] = "Added a new attribute type [$attributeName]";
163
   $sql = "select backups_id from backups where device_id = $device_id";
-
 
164
   $backups_id = getOneDBValue( $sql );
-
 
165
   if ( isset( $backups_id ) ) {
293
         $result = $result['insert_id'];
166
      return $backups_id;
294
      }
167
   } else {
-
 
168
      recordMessage( "Adding server $name to backups" );
-
 
169
      $sql = "insert into backups ( device_id,backups_server_id,notes ) values ( $device_id, 1, 'Automatically Added' )";
-
 
170
      $results = queryDatabaseExtended( $sql );
295
      return $result;
171
      return $results['insert_id'];
296
   }
172
   }
-
 
173
}
297
 
174
 
298
   /*
-
 
299
    * Checks an attribute from the device_attriburtes table. If the value has
-
 
300
    * changed, sets the old one's removed_date to this report date, then adds
-
 
301
    * new record for new value.
-
 
302
    * If the record does not exist, simply creates it
-
 
303
    */
-
 
304
   public function checkAndUpdateAttribute( $attribute, $value ) {
-
 
305
      if ( !isset($attribute) || !isset($value ) ) {
-
 
306
         $this->messages[] = "Error: attempt to use null value for [$attribute], value [$value] for ID $this->machineID in checkAndUPdateAttribute";
-
 
307
         return false;
-
 
308
      }
-
 
309
      $value = makeSafeSQLValue($value); # we want to always quote the value on this particular one
-
 
310
      //$attribute = makeSafeSQLValue( $attribute );
-
 
311
      $attrib_id = $this->getAttributeID( $attribute, $this->reportDateSQL );
-
 
312
      $result = getOneDBValue( "select device_attrib.value
-
 
313
         from device_attrib join attrib using (attrib_id)
-
 
314
         where device_attrib.device_id = $this->machineID
-
 
315
               and device_attrib.removed_date is null
-
 
316
               and attrib.attrib_id = $attrib_id
-
 
317
         ");
-
 
318
      $result = makeSafeSQLValue( $result ); # we must do this since we are comparing to $value which has had this done
-
 
319
      if ( isset( $result ) ) { # got it, now see if it compares ok
-
 
320
         if ( $value != $result ) { # nope, this has changed. Note, must use fixDatabaseValue for escapes already in $value
-
 
321
            $this->messages[] = "New value [$value] for $attribute for device $this->machineID, voiding previous";
-
 
322
            queryDatabaseExtended( "update device_attrib
-
 
323
                                       set removed_date = '$this->reportDateSQL'
-
 
324
                                    where device_id = $this->machineID
-
 
325
                                          and attrib_id = $attrib_id
-
 
326
                                          and removed_date is null");
-
 
327
            unset( $result ); # this will force the insert in the next block of code
-
 
328
         } # if $result ne $value
-
 
329
      } # if ($result)
-
 
330
      if ( ! isset( $result ) ) { # we have no valid entry for this attribute
-
 
331
         //$this->messages[] = "In checkAndUpdateAttribute, adding new record with insert into device_attrib(device_id,attrib_id,value,added_date) values ($this->machineID,$attrib_id,$value,$this->reportDateSQL)";
-
 
332
         queryDatabaseExtended( "insert into device_attrib(device_id,attrib_id,value,added_date)
-
 
333
                                 values ($this->machineID,$attrib_id,$value,'$this->reportDateSQL')");
-
 
334
         return true;
-
 
335
      }
-
 
336
      return false;
-
 
337
   } // checkAndUpdateAttribute
-
 
338
   
-
 
339
   # simply verifies some attributes of the computer
-
 
340
   private function updateComputerMakeup() {
-
 
341
      $this->checkAndUpdateAttribute('Memory',        $this->report['system']['memory']);
-
 
342
      $this->checkAndUpdateAttribute('Number of CPUs',$this->report['system']['num_cpu']);
-
 
343
      $this->checkAndUpdateAttribute('CPU Type',      $this->report['system']['cpu_type']);
-
 
344
      $this->checkAndUpdateAttribute('CPU SubType',   $this->report['system']['cpu_sub']);
-
 
345
      $this->checkAndUpdateAttribute('CPU Speed',     $this->report['system']['cpu_speed']);
-
 
346
   } // updateComputerMakeup
-
 
347
   
-
 
348
   // This is kind of funky, because column = null does not work, it must be column is null, so we have to look for it.
-
 
349
   function makeSQLEquals ( $field, $value ) {
-
 
350
      return "$field " . ( $value == 'null' ? 'is null' : '=' . $value );
-
 
351
   }
-
 
352
         
-
 
353
   
-
 
354
   private function updateOS () {
-
 
355
      // find os
-
 
356
      $osName =         makeSafeSQLValue( isset($this->report['operatingsystem']['os_name'])         ? $this->report['operatingsystem']['os_name'] : '');
-
 
357
      $kernel =         makeSafeSQLValue( isset($this->report['operatingsystem']['kernel'])          ? $this->report['operatingsystem']['kernel'] : '');
-
 
358
      $distro_name =    makeSafeSQLValue( isset($this->report['operatingsystem']['os_distribution']) ? $this->report['operatingsystem']['distribution'] : '');
-
 
359
      $release =        makeSafeSQLValue( isset($this->report['operatingsystem']['os_release'])      ? $this->report['operatingsystem']['release'] : '');
-
 
360
      $version =        makeSafeSQLValue( isset($this->report['operatingsystem']['os_version'])      ? $this->report['operatingsystem']['os_version'] : '');
-
 
361
      $description =    makeSafeSQLValue( isset($this->report['operatingsystem']['description'])     ? $this->report['operatingsystem']['description'] : '');
-
 
362
      $codename =       makeSafeSQLValue( isset($this->report['operatingsystem']['codename'])        ? $this->report['operatingsystem']['codename'] : '');
-
 
363
      
-
 
364
      $osID = getOneDBValue( "select operating_system_id from operating_system
-
 
365
               where " . $this->makeSQLEquals( 'name', $osName ) . "
-
 
366
                  and " . $this->makeSQLEquals( 'kernel', $kernel ) . "
-
 
367
                  and " . $this->makeSQLEquals( 'distro', $distro_name ) . "
-
 
368
                  and " . $this->makeSQLEquals( 'distro_release', $release ) );
-
 
369
      if ( !isset( $osID ) ) {
-
 
370
         $this->messages[] = "Creating a new OS with name = $osName, kernel = $kernel, distro = $distro_name,  distro_release = $release";
-
 
371
         $result = queryDatabaseExtended( "insert into operating_system (name,version,kernel,distro,distro_description,distro_release,distro_codename, added_date) values
-
 
372
                                          ($osName,$version,$kernel,$distro_name,$description,$release,$codename, '$this->reportDateSQL')" );
-
 
373
         $osID = $result['insert_id'];
-
 
374
      }
-
 
375
 
175
 
-
 
176
/* 
376
      # verify the operating system
177
 * Creates an entry in the backups_run table
377
      $registeredOS = getOneDBValue( "select operating_system_id from device_operating_system where device_id = $this->machineID and removed_date is null" );
-
 
-
 
178
 */ 
378
      if ( ! $registeredOS || $registeredOS != $osID ) {
179
function recordReport( $report ) {
379
         if ( $registeredOS ) { #we have the same computer, but a new OS???
-
 
380
            queryDatabaseExtended( "update device_operating_system set removed_date = '$this->reportDateSQL' where device_id = $this->machineID and removed_date is null");
-
 
381
            $this->messages[] = "Computer $this->machineName has a new OS";
-
 
382
         }
180
   
383
         queryDatabaseExtended( "insert into device_operating_system( device_id,operating_system_id,added_date) values ($this->machineID,$osID,'$this->reportDateSQL')");
-
 
384
      }
181
   $keys = array();
385
   }
182
   $values = array();
386
   
183
   
387
   /* every time we get a report, we need to see if the computer was rebooted
184
   foreach ( $report as $keyfield => $value ) {
388
    * There is some slop in the last reboot date, so we assume if it is less than
185
      if ( $keyfield == 'server_name' ) {
389
    * $fuzzyRebootTimes, it was not rebooted. $fuzzyRebootTimes is calculated in
-
 
390
    * seconds. Since most of our machines take a minimum of 5 minutes to reboot
-
 
391
    * we'll go with that (300), though it would be just as good to go with a day
-
 
392
    * (86400) since we only run this report daily
186
         $keys[] = 'backups_id';
393
    * When one is found, we remove the old report and add a new one.
187
         $device_id = findServer( $value );
394
    */
-
 
395
   private function updateBootTime() {
188
         if ( isset( $device_id ) ) {
396
      $fuzzyRebootTimes = 300; // this allows slop of this many seconds before we assume a machine has been rebooted, ie
-
 
397
      $lastReboot;
189
            $values[] = $device_id;
398
      if ( isset( $this->report['system']['last_boot'] ) ) {
190
            $duplicate = checkDuplicate( $device_id, $report['report_date'] );
399
         $lastReboot = strftime( '%F %T',$this->report['system']['last_boot'] ); // convert unix timestamp to sql value
-
 
400
         if ( isset( $lastReboot ) ) {
191
            if ( $duplicate )
401
            //if ( ! getOneDBValue( "select computer_uptime_id from computer_uptime where device_id = $this->machineID and last_reboot = '$lastReboot'" ) ) {
-
 
402
            if ( ! getOneDBValue( "select computer_uptime_id from computer_uptime where abs(TIME_TO_SEC(timediff( last_reboot, '$lastReboot' ))) < 3600 and device_id = $this->machineID" ) ) {
-
 
403
               $this->messages[] = "Computer was rebooted at $lastReboot";
192
               return $report['file_name'] . "\t$duplicate";
404
               queryDatabaseExtended( "update computer_uptime set removed_date = '$this->reportDateSQL' where device_id = $this->machineID and removed_date is null" );
-
 
405
               queryDatabaseExtended( "insert into computer_uptime (device_id,added_date,last_reboot) values ($this->machineID,'$this->reportDateSQL','$lastReboot')");
-
 
406
            }
-
 
407
         } else {
193
         } else {
408
            $this->messages[] = 'Invalid reboot time [' . $this->Report['system']['last_boot'] . ']';
194
            return $report['file_name'] . "\t4\tServer not found";
409
         }
195
         }
410
      } else {
196
      } else {
411
         $this->messages[] = 'No Boot time given';
-
 
412
      }
-
 
413
   }
-
 
414
 
-
 
415
 
-
 
416
   // checks if the report and the database values are the same
-
 
417
   private function checkInterfaceEquals( $report, $database ) {
-
 
418
      //var_dump( $report );
-
 
419
      //var_dump( $database );
-
 
420
      return ( 
-
 
421
         $report['address'] == $database['address'] and
-
 
422
         $report['netmask'] == $database['netmask'] and
-
 
423
         $report['ip6address'] == $database['ip6'] and
-
 
424
         $report['ip6networkbits'] == $database['ip6net'] and
-
 
425
         $report['mtu'] == $database['mtu'] and
-
 
426
         $report['mac'] == $database['mac'] 
-
 
427
         );
-
 
428
   } // checkInterfaceEquals
-
 
429
 
-
 
430
 
-
 
431
   /*
-
 
432
    * routine will check for all IP addresses reported and check against those recorded in the
-
 
433
    * database. It will remove any no longer in the database, and add any new ones
-
 
434
    */
-
 
435
   private function doIPAddresses () {
-
 
436
      /*
-
 
437
       * get all interfaces from the database
-
 
438
       * remove any interfaces from database which are not in report
-
 
439
       * add any interfaces from report which are not in database or which have changed
-
 
440
       */
-
 
441
      $network = $this->report['network']; // make a copy so we don't modify the original report
-
 
442
      // we won't process lo
-
 
443
      unset ($network['lo']);
-
 
444
      // at this point, we could get rid of tun's also, if we wanted to
-
 
445
      
-
 
446
      // let's ensure that all rows in report have the minimum required data
-
 
447
      foreach ( array_keys( $network ) as $interface ) {
-
 
448
         foreach ( array( 'address','netmask','ip6address','ip6networkbits','mtu','mac' ) as $required ) {
-
 
449
            if ( ! isset( $network[$interface][$required] ) ) { 
-
 
450
               $network[$interface][$required]  = NULL; 
-
 
451
            }
-
 
452
         } // checking all keys
-
 
453
      } // checking all report rows
-
 
454
      // var_dump( $network );   
-
 
455
 
-
 
456
      // get current information on all active interfaces in the database
-
 
457
      $dbInterfaces = queryDatabaseExtended( "select network_id,interface,address,netmask,ip6,ip6net,mac,mtu from network where device_id = $this->machineID and removed_date is null" );
-
 
458
      //print "select network_id,interface,address,netmask,ip6,ip6net,mac,mtu from network where device_id = $this->machineID and removed_date is null\n";
-
 
459
      //var_dump($dbInterfaces);
-
 
460
 
-
 
461
      // now, get rid of any interfaces which are no longer in the database
-
 
462
      // get a list of interfaces being passed in by report as a comma delimited list for processing.
-
 
463
      foreach ( array_keys( $network) as $temp ) {
-
 
464
         $interfaces[] = "'$temp'";
197
         $keys[] = $keyfield;
465
      }
-
 
466
      $interfaces = implode( ',', $interfaces );
-
 
467
      if ( $interfaces ) { // are there any? Then simply remove anything not in their set.
-
 
468
         queryDatabaseExtended( "update network set removed_date = '$this->reportDateSQL' where device_id = $this->machineID and removed_date is null and interface not in ($interfaces)");
-
 
469
         // print "update network set removed_date = '$this->reportDateSQL' where device_id = $this->machineID and removed_date is null and interface not in ($interfaces)\n";
-
 
470
         // reload the database results to exclude the ones we removed above
-
 
471
         $dbInterfaces = queryDatabaseExtended( "select network_id,interface,address,netmask,ip6,ip6net,mac,mtu from network where device_id = $this->machineID and removed_date is null" );
-
 
472
         // print "select network_id,interface,address,netmask,ip6,ip6net,mac,mtu from network where device_id = $this->machineID and removed_date is null\n";
-
 
473
      } // if
-
 
474
      // at this point, the database is a subset of the report, ie there are no entries in the database which are not also in the report.
-
 
475
      // let's remove the ones which are the same from both sets.
-
 
476
      // we can take a shortcut since the database is a subset of the report, ie we can remove entries from the report as we process
-
 
477
      if ( $dbInterfaces ) { // do we have anything in the database?
-
 
478
         foreach ( $dbInterfaces['data'] as $row => $value ) {
-
 
479
            // print "checking if " . $network[$value['interface']] . " equals $value\n";
-
 
480
            if ( $this->checkInterfaceEquals( $network[$value['interface']], $value ) ) { // compare the two entries
-
 
481
               // print "\tIt Does, so deleting it from updates\n";
-
 
482
               unset( $network[$value['interface']] );
-
 
483
            } else { // they are not equal. We will simply void out the existing one and it will treat the report entry as a new entry.
-
 
484
               // print "\tit is an update, so setting to removed in database\n";
-
 
485
               queryDatabaseExtended( "update network set removed_date = '$this->reportDateSQL' where device_id = $this->machineID and removed_date is null and interface = '" . $value['interface'] . "'");
-
 
486
               // print "update network set removed_date = '$this->reportDateSQL' where device_id = $this->machineID and removed_date is null and interface = '" . $value['interface'] . "'\n";
-
 
487
            } // if..else
-
 
488
         } // foreach
-
 
489
      }
-
 
490
      // finally, we should have only new entries, or entries which have changed and have been voided
-
 
491
      // a new row should be created for anything left.
-
 
492
      foreach ( $network as $interface => $values ) {
-
 
493
         //var_dump( $values );
-
 
494
         $sql = implode ( ',', array( 
-
 
495
                              $this->machineID,
-
 
496
                              makeSafeSQLValue($this->reportDateSQL),
-
 
497
                              makeSafeSQLValue($interface),
-
 
498
                              makeSafeSQLValue($values['address']),
-
 
499
                              makeSafeSQLValue($values['netmask']),
-
 
500
                              makeSafeSQLValue($values['ip6address']),
-
 
501
                              makeSafeSQLValue($values['ip6networkbits']),
-
 
502
                              makeSafeSQLValue($values['mtu']),
198
         $values[] = makeSafeSQLValue( $value );
503
                              makeSafeSQLValue($values['mac'])
-
 
504
                              )
-
 
505
                         );
-
 
506
         $sql = "insert into network (device_id,added_date,interface,address,netmask,ip6,ip6net,mtu,mac) values (" . $sql . ")";
-
 
507
         //$this->messages[] = $sql;
-
 
508
         queryDatabaseExtended( $sql );
-
 
509
         $this->messages[] = "Network Device $interface was added/modified";
-
 
510
      }
199
      }
511
   } // doIPAddresses
-
 
512
   
-
 
513
 
-
 
514
   /*
-
 
515
    * function looks through every element of $report, for a subkey
-
 
516
    * named 'keyfield'. It turns those into a string appropriate for
-
 
517
    * inclusion in a query as 
-
 
518
    * where fieldname in ( $keylist )
-
 
519
    * For example, with values a, b, c, 54, q'
-
 
520
    * returns 'a','b','c','54','q\''
-
 
521
    * where $keylist is generated by this function
-
 
522
    * returns null if no values found
-
 
523
    */ 
-
 
524
   function getKeyList ( $report ) {
-
 
525
      $keys = array();
-
 
526
      $keyset = null;
-
 
527
      // every row should have a key 'keyfield'.Since we don't know 
-
 
528
      // what they are, be sure to make sure they are SQL Safe
-
 
529
      foreach ( $report as $key => $value ) {
-
 
530
         $keys[] = makeSafeSQLValue( $value['keyfield'] );
-
 
531
      }
-
 
532
      return $keys ? implode( ",\n", $keys ) : null;
-
 
533
   }
200
   }
534
 
-
 
535
   /*
-
 
536
    * function checks all keys in $first and $second to see if they
-
 
537
    * match. If they do, returns true, else returns false
-
 
538
    * ignores any keys passed in as array $ignore
-
 
539
    */
-
 
540
   function rowMatches ( $first, $second, $ignore = array() ) {
-
 
541
      foreach ( $first as $fkey => $fValue ) {
-
 
542
         if ( in_array( $fkey, $ignore ) )
-
 
543
            continue;
-
 
544
         if ( $fValue == $second[$fkey] )
-
 
545
            continue;
-
 
546
         return false;
-
 
547
      }
-
 
548
      return true;
-
 
549
   } // rowMatches
-
 
550
 
-
 
551
   /* Generic function that will 
-
 
552
    * delete items in database not found in report
-
 
553
    * Clean up report to contain only those items which are to be added
-
 
554
    * Return a copy of the report.
-
 
555
    * 
-
 
556
    * NOTE: since we are deleting items not found in the report, we will then
-
 
557
    * subsequently add them. This is the update process since we never actually
-
 
558
    * "delete" anything from the database.
-
 
559
    * 
-
 
560
    * Requires the report, and report must have a key for each entry named
-
 
561
    * 'keyfield' which the query below may use (as special tag <keys>
-
 
562
    * Also uses the following queries. If a query does not exist, that
-
 
563
    * process is ignored
-
 
564
    * 'remove old' - should have an entry as <device_id> which will have the current
-
 
565
    *       machine ID placed in it
-
 
566
    * 'delete' - <ids> which will be replaced with a list of keys from the 
-
 
567
    *         report.
-
 
568
    * 'find' - should return a column named 'id' which is a primary key on the
-
 
569
    *          table (used by delete query), and a column named 'keyfield'
-
 
570
    *          which matches the same one in the report. Any other fields in
-
 
571
    *          the query are checked against the report, and the report and
-
 
572
    *          database entry are only considered matching if all query fields
-
 
573
    *          match a report entry.
-
 
574
    * 
-
 
575
    * Before passing in report, you should go through the entries and create
-
 
576
    * a new one called 'keyfield' for each entry which will be a unique key
-
 
577
    * for an entry. For example, software packages may be the package name
-
 
578
    * and the version.
-
 
579
    */
-
 
580
   private function AddDeleteUpdate ( $report, $queries, $reportLabel, $testing=false ) {
-
 
581
 
-
 
582
      if ( $testing ) {
-
 
583
         print "*****************Starting\n"; 
-
 
584
         print_r( $report ); 
-
 
585
         print "*****************Starting\n";
-
 
586
      }
-
 
587
      $database = null;
-
 
588
      $keySet = $this->getKeyList( $report );
-
 
589
      if ( is_null( $keySet ) ) // bail if we don't have any data
-
 
590
         return null;
-
 
591
         
-
 
592
      // find values which are in database but not in report and delete them from database
-
 
593
      if ( $queries['remove old'] ) {
-
 
594
         $queries['remove old'] = str_replace( '<keys>', $keySet, $queries['remove old'] );
-
 
595
         $queries['remove old'] = str_replace( '<device_id>', $this->machineID, $queries['remove old'] );
-
 
596
         if ( $testing )
-
 
597
            print "Remove Query***************************\n" . $queries['remove old'] . "\n***********************************\n";
-
 
598
         else {
-
 
599
            $database = queryDatabaseExtended( $queries['remove old'] );
-
 
600
            if ( $database and $database['affected_rows'] ) 
-
 
601
               $this->messages[] = $database['affected_rows'] . " $reportLabel removed from database because they were removed for superceded";
-
 
602
         } // else
-
 
603
      } // if
-
 
604
 
-
 
605
      // now, let's get all the values left in the database
-
 
606
      if ( $queries['find'] ) {
-
 
607
         $queries['find'] = str_replace( '<keys>', $keySet, $queries['find'] );
-
 
608
         $queries['find'] = str_replace( '<device_id>', $this->machineID, $queries['find'] );
-
 
609
         if ( $testing )
-
 
610
            print "Find Query***************************\n" . $queries['find'] . "\n***********************************\n";
-
 
611
         else
-
 
612
            $database = queryDatabaseExtended( $queries['find'] );
-
 
613
      }
-
 
614
      if ( $database ) { // there were entries in the database still
-
 
615
         $database = $database['data']; // get to the data
-
 
616
         $keysToDelete = array();
-
 
617
         // find values which are different in report, and delete the database entry
-
 
618
         foreach ( $database as $row => $entries ) {
-
 
619
            foreach ( $report as $key => $values ) {
-
 
620
               if ( $report[$key]['keyfield'] != $entries['keyfield'] )
-
 
621
                  continue;
-
 
622
               // if we made it here, our keyfields match, so we check
-
 
623
               // the contents of the other fields
-
 
624
               if ( $this->rowMatches( $entries, $values, array( 'keyfield', 'id' ) ) ) {
-
 
625
                  // they match, so remove it from the report
-
 
626
                  unset( $report[$key] );
-
 
627
               } else { // they are different in the report, so remove from database
-
 
628
                  $keysToDelete[] = $entries['id'];
-
 
629
               }
-
 
630
            } // inner foreach
-
 
631
         } // outer foreach
-
 
632
         if ( $keysToDelete and $queries['delete'] ) {
-
 
633
            $queries['delete'] = str_replace( '<ids>', implode( ',', $keysToDelete ), $queries['delete'] );
201
   $sql = 'insert into backups_run (' . implode( ',', $keys ) . ') values (' . implode( ',', $values ) . ')';
634
            if ( $testing )
-
 
635
               print "Delete Query***************************\n" . $queries['delete'] . "\n***********************************\n";
-
 
636
            else {
-
 
637
               $updates = queryDatabaseExtended( $queries['delete'] );
-
 
638
               $this->messages[] = $updates['affected_rows'] . " $reportLabel modified";
-
 
639
            }
-
 
640
         }
-
 
641
      } // if $database
-
 
642
      // return items to be added
-
 
643
      if ( $testing ) {
-
 
644
         print "*****************Ending\n"; 
-
 
645
         print_r( $report ); 
-
 
646
         print "*****************Ending\n";
-
 
647
      }
-
 
648
      return $report;
-
 
649
   } // function AddDeleteUpdate
-
 
650
 
-
 
651
 
-
 
652
   /*
-
 
653
    * routine to ensure the hardware returned as PCI hardware is in the attributes area
-
 
654
    */ 
-
 
655
   private function processPCI ( ) {
-
 
656
      // following are some of the synonyms we will use from the PCI
-
 
657
      // tables for the "name" of the device. They are listed in the
-
 
658
      // order of priority (ie, first one found is chosen).
-
 
659
      $nameSynomyms = array('name','device','sdevice','device0');
-
 
660
 
-
 
661
      // query which removes devices from database that are not in report
-
 
662
      // we assume if the report doesn't have it, it has been removed
-
 
663
      $queries['remove old'] = 
-
 
664
                    "update device
-
 
665
                        set removed_date = '$this->reportDateSQL'
-
 
666
                        where device_id in (
-
 
667
                           select device_id from (
-
 
668
                              select
-
 
669
                                    device_id
-
 
670
                                 from
-
 
671
                                    device join device_type using (device_type_id)
-
 
672
                                 where
-
 
673
                                    device.part_of = <device_id>
-
 
674
                                    and device_type.show_as_system <> 'Y'
-
 
675
                                    and device.removed_date is null
-
 
676
                                    and device.name not in ( <keys> )
-
 
677
                              ) as b
-
 
678
                              )";
-
 
679
      
-
 
680
      
-
 
681
      $queries['find'] = 
-
 
682
                    "select
-
 
683
                        device_id id,
-
 
684
                        device.name  'keyfield',
-
 
685
                        device.notes 'info'
-
 
686
                     from device join device_type using (device_type_id) 
-
 
687
                     where
-
 
688
                        device_type.name = 'PCI Card' 
-
 
689
                        and device.removed_date is null
-
 
690
                        and device.part_of = <device_id>";
-
 
691
                        
-
 
692
      $queries['delete'] =
-
 
693
                    "update device
-
 
694
                        set removed_date = '$this->reportDateSQL'
-
 
695
                        where device_id in ( <ids> )";
-
 
696
 
-
 
697
 
-
 
698
      if ( ! isset( $this->report['pci'] ) ) return;
-
 
699
      // make a local copy so we can modify as needed
-
 
700
      $pciHash = $this->report['pci'];
-
 
701
      # normalize the data
-
 
702
      foreach ( array_keys( $pciHash ) as $key ) {
-
 
703
         if ( ! is_array( $pciHash[$key] ) ) {
-
 
704
            $this->messages[] = 'Invalid PCI format, not recording';
-
 
705
            return false;
-
 
706
         }
-
 
707
         if ( ! isset( $pciHash[$key]['slot'] ) ) { // doesn't have a slot field
-
 
708
            $slotField = '';
-
 
709
            foreach ( array_keys( $pciHash[$key] ) as $subkey ) { // scan through all keys and see if there is something with a "slot looking" value in it
-
 
710
               if ( preg_match ( '/^[0-9a-f:.]+$/' , $pciHash[$key][$subkey] ) )
-
 
711
                  $slotField = $subkey;
-
 
712
            }
-
 
713
            if ( $slotField ) {
-
 
714
               $pciHash[$key]['slot'] = $pciHash[$key][$slotField];
-
 
715
            } else {
-
 
716
               $pciHash[$key]['slot'] = 'Unknown';
-
 
717
            }
-
 
718
         }
-
 
719
         // Each entry must have a name. Use 'device' if it doesn't exist
-
 
720
         // Basically, we try each option in turn, with the first test having
-
 
721
         // priority.
-
 
722
         
-
 
723
         if ( ! isset( $pciHash[$key]['name'] ) ) {
-
 
724
            // if there is no name, try to use one of the synonyms
202
   // if we made it this far, we are ok, so just add the report id
725
            foreach ( $nameSynomyms as $testName ) {
-
 
726
               if ( isset ( $pciHash[$key][$testName] ) ) {
-
 
727
                  $pciHash[$key]['name'] = $pciHash[$key][$testName];
-
 
728
                  break;
-
 
729
               } // if
-
 
730
            } // foreach
-
 
731
            if ( empty( $pciHash[$key]['name'] ) ) {
-
 
732
               $this->messages[] = "No name given for one or more PCI devices at normalize, Computer ID: [$this->machineID], Report Date: [$this->reportDate]";
-
 
733
               //print_r( $pciHash ); 
-
 
734
               //die;
-
 
735
               return;
-
 
736
            }
-
 
737
         } elseif ( $pciHash[$key]['name'] == $pciHash[$key]['slot'] ) {
-
 
738
            $pciHash[$key]['name'] = $pciHash[$key]['device'];
-
 
739
         } // if..else
-
 
740
         // Following is what will actually be put in the device table, ie device.name
-
 
741
         $pciHash[$key]['keyfield'] = $pciHash[$key]['slot'] . ' - ' . $pciHash[$key]['name'];
-
 
742
         ksort( $pciHash[$key] );
-
 
743
         $ignore = array( 'keyfield' );
-
 
744
         $info = '';
-
 
745
         foreach ( $pciHash[$key] as $subkey => $value ) {
-
 
746
            if ( in_array( $subkey, $ignore ) )
-
 
747
               continue;
-
 
748
            $info .= "[$subkey]=$value\n";
-
 
749
         }
-
 
750
         $pciHash[$key]['info'] = $info;
-
 
751
      } // foreach
-
 
752
      // at this point, we should have a slot and a name field in all pci devices
-
 
753
      $toAdd = $this->AddDeleteUpdate( $pciHash, $queries, 'PCI Devices' );
-
 
754
      if ( $toAdd ) {
-
 
755
         $pciCardID = getOneDBValue( "select device_type_id from device_type where name = 'PCI Card'");
-
 
756
         $count = 0;
-
 
757
         foreach ( $toAdd as $entry => $values ) {
-
 
758
            $keyfield = makeSafeSQLValue( $values['keyfield'] );
-
 
759
            $info = makeSafeSQLValue( $values['info'] );
-
 
760
            $query = "insert into device 
-
 
761
                        select 
-
 
762
                           null,
-
 
763
                           site_id,
-
 
764
                           $pciCardID,
-
 
765
                           $keyfield,
-
 
766
                           $info,
-
 
767
                           device_id,
-
 
768
                           '$this->reportDateSQL',
-
 
769
                           null,
-
 
770
                           null 
-
 
771
                        from device 
-
 
772
                        where device_id = $this->machineID";
-
 
773
            queryDatabaseExtended( $query );
203
   $result = queryDatabaseExtended( $sql );
774
            $count++;
-
 
775
         } // foreach
-
 
776
         $this->messages[] = "$count PCI devices added/modified";
-
 
777
      } // if
-
 
778
   } // processPCI
-
 
779
 
-
 
780
   function getSoftwareID ( $packageName,$versionInfo,$description ) {
-
 
781
      $packageName = makeSafeSQLValue( $packageName );
-
 
782
      $versionInfo = makeSafeSQLValue( $versionInfo );
-
 
783
      $description = makeSafeSQLValue( $description );
-
 
784
      // does the package exist?
-
 
785
      $packageID = getOneDBValue("select software_id from software where package_name = $packageName and removed_date is null");
-
 
786
      if ( !$packageID ) { # NO, package doesn't exist, so add it to the database
-
 
787
         $packageID = queryDatabaseExtended( "insert into software (package_name,description, added_date) values ($packageName,$description, '$this->reportDateSQL')");
-
 
788
         if ( $packageID['insert_id'] )
-
 
789
            $packageID = $packageID['insert_id'];
-
 
790
         else {
-
 
791
            $this->messages[] = "ERROR: Software Packages - Could not find version $packageName and could not add to database";
-
 
792
            $packageID = null;
-
 
793
         }
-
 
794
      }
-
 
795
      // does this version number exist?
-
 
796
      $versionID = getOneDBValue( "select software_version_id from software_version where version = $versionInfo and removed_date is null" );
-
 
797
      if ( ! $versionID ) { # nope, so add it
-
 
798
         $versionID = queryDatabaseExtended( "insert into software_version ( version,added_date ) values ($versionInfo,'$this->reportDateSQL')");
-
 
799
         if ( $versionID['insert_id'] )
-
 
800
            $versionID = $versionID['insert_id'];
-
 
801
         else {
-
 
802
            $this->messages[] = "ERROR: Software Packages - Could not find version $versionInfo and could not add to database";
-
 
803
            $versionID = null;
-
 
804
         }
-
 
805
      }
-
 
806
      return array( 'package id' => $packageID,'version id' => $versionID);
-
 
807
   } // getSoftwareID
-
 
808
 
-
 
809
 
-
 
810
   function processSoftwarePackages (  ) {
-
 
811
      // query which removes devices from database that are not in report
-
 
812
      // we assume if the report doesn't have it, it has been removed
-
 
813
      $queries['remove old'] = 
-
 
814
                    "update installed_packages
-
 
815
                        set removed_date = '$this->reportDateSQL'
-
 
816
                        where installed_packages_id in (
-
 
817
                           select installed_packages_id from (
-
 
818
                              select
-
 
819
                                    installed_packages_id
-
 
820
                              from 
-
 
821
                                 installed_packages 
-
 
822
                                 join software using ( software_id )
-
 
823
                                 join software_version using (software_version_id)
-
 
824
                              where
-
 
825
                                    installed_packages.device_id = <device_id>
-
 
826
                                    and installed_packages.removed_date is null
-
 
827
                                    and concat(software.package_name,software_version.version) not in ( <keys> )
-
 
828
                              ) as b
-
 
829
                              )";
-
 
830
      $queries['find'] = 
-
 
831
           "select 
-
 
832
               installed_packages.installed_packages_id 'id',
-
 
833
               concat(software.package_name,software_version.version) 'keyfield'
-
 
834
            from 
-
 
835
               installed_packages 
-
 
836
               join software using ( software_id )
-
 
837
               join software_version using (software_version_id)
-
 
838
            where 
-
 
839
               device_id = <device_id>
-
 
840
               and installed_packages.removed_date is null";
-
 
841
      $queries['delete'] =
-
 
842
                    "update installed_packages
-
 
843
                        set removed_date = '$this->reportDateSQL'
-
 
844
                        where installed_packages_id in ( <ids> )";
-
 
845
 
-
 
846
      if ( ! isset( $this->report['software'] ) ) return;
204
   return $report['file_name'] . "\t0\tok";
847
      // make a local copy so we can modify as needed
-
 
848
      $softwareHash = $this->report['software'];
-
 
849
      foreach ( array_keys( $softwareHash ) as $key ) {
-
 
850
         if ( ! isset( $softwareHash[$key]['name'] ) )
-
 
851
            $softwareHash[$key]['name'] = $key;
-
 
852
         if ( ! isset( $softwareHash[$key]['description'] ) )
-
 
853
            $softwareHash[$key]['description'] = '';
-
 
854
         if ( isset( $softwareHash[$key]['release'] ) ) // some of them have a release number, so we just add that to the version
-
 
855
            $softwareHash[$key]['version'] = $softwareHash[$key]['version'] . '-r' . $softwareHash[$key]['release'];
-
 
856
         // This is needed for matching
-
 
857
         $softwareHash[$key]['keyfield'] = $softwareHash[$key]['name'] . $softwareHash[$key]['version'];
-
 
858
      } // foreach
-
 
859
      // at this point, we should have a slot and a name field in all pci devices
-
 
860
      $toAdd = $this->AddDeleteUpdate( $softwareHash, $queries, 'Software Packages' );
-
 
861
      if ( $toAdd ) {
-
 
862
         $count = 0;
-
 
863
         foreach ( $toAdd as $key => $value ) {
-
 
864
            $ids = $this->getSoftwareID ( $value['name'],$value['version'],$value['description'] );
-
 
865
            if ( is_null( $ids['package id'] ) or is_null( $ids['version id'] ) ) {
-
 
866
               $this->messages[] = "Could not create entry for package " . $value['name'] . ", version " . $value['version'];
-
 
867
            } else {
-
 
868
               $insertValues = implode( ',', array( $this->machineID, $ids['package id'], $ids['version id'], "'$this->reportDateSQL'" ) );
-
 
869
               $query = "insert into installed_packages
-
 
870
                           (device_id,software_id,software_version_id,added_date) 
-
 
871
                           values 
-
 
872
                           ( $insertValues )";
-
 
873
               $database = queryDatabaseExtended( $query );
-
 
874
               if ( $database )
-
 
875
                  $count++;
-
 
876
            } // if..else
-
 
877
         } // foreach
-
 
878
         if ( $count )
-
 
879
            $this->messages[] = "$count software packages added/updated";
-
 
880
      }
-
 
881
   } // processSoftwarePackages
-
 
882
 
-
 
883
} // class sysinfo
205
} // recordReport
884
 
-
 
885
 
206
 
886
 
207
 
887
/*
208
/*
888
 * we don't know where the configuration file will be, so we have a list
209
 * we don't know where the configuration file will be, so we have a list
889
 * below (searchPaths) to look for it. It will load the first one it 
210
 * below (searchPaths) to look for it. It will load the first one it 
890
 * finds, then exit. THUS, you could have multiple configuration files
211
 * finds, then exit. THUS, you could have multiple configuration files
891
 * but only the first one in the list will be used
212
 * but only the first one in the list will be used
892
 */
213
 */
893
 
214
 
894
$confFileName = "sysinfoRead.conf.yaml";
215
$confFileName = "rsbackupRead.conf.yaml";
895
$searchPaths = array( '/etc/camp', '/opt/camp', '/opt/camp/sysinfo', $_SERVER['SCRIPT_FILENAME'], getcwd() );
216
$searchPaths = array( '/etc/camp', '/opt/camp', '/opt/camp/rsbackup', $_SERVER['SCRIPT_FILENAME'], getcwd() );
896
$configuration = array();
217
$configuration = array();
897
foreach ( $searchPaths as $path ) {
218
foreach ( $searchPaths as $path ) {
898
   if ( file_exists( "$path/$confFileName" ) ) {
219
   if ( file_exists( "$path/$confFileName" ) ) {
899
      #print "Found $path/$confFileName\n";
-
 
900
      $configuration = yaml_parse_file( "$path/$confFileName" );
220
      $configuration = yaml_parse_file( "$path/$confFileName" );
901
      #require "$path/$confFileName";
-
 
902
      break; // exit out of the loop; we don't try to load it more than once
221
      break; // exit out of the loop; we don't try to load it more than once
903
   } // if
222
   } // if
904
} // foreach
223
} // foreach
905
 
224
 
-
 
225
 
906
mysql_connect( $configuration['database']['databaseServer'], $configuration['database']['databaseUsername'], $configuration['database']['databasePassword'] ) or die(mysql_error());
226
mysql_connect( $configuration['database']['databaseServer'], $configuration['database']['databaseUsername'], $configuration['database']['databasePassword'] ) or die(mysql_error());
907
mysql_select_db( $configuration['database']['database'] ) or die(mysql_error());
227
mysql_select_db( $configuration['database']['database'] ) or die(mysql_error());
908
 
228
 
909
 
229
 
910
$thisReport = new sysinfo( $configuration['bodyContents'] );
-
 
911
$result; 
-
 
912
 
230
 
913
$result = $thisReport->loadFromFile( $argc > 1 ? $argv[1] : "php://stdin" );
231
for ( $i = 1 ; $i < count( $argv ); $i++ ) {
914
if ( $result == 'ini' ) {
232
   $filename = $argv[$i];
-
 
233
   $report = parseFile( $filename, $configuration['datapath'] . '/' . $configuration['unprocessed_path'] );
-
 
234
   if ( isset( $report['error'] ) ) { // we had an error processing the report
915
   print $thisReport->dumpMessages();
235
      $result[] = "$filename\t" . $report['error'];
916
   exit(0);
236
   } else {
-
 
237
      $result[] = recordReport( $report );
-
 
238
   }
917
}
239
}
918
if ( ! $result )
-
 
919
   exit ( 1 );
240
 
920
$result = $thisReport->processReport();
-
 
921
print $thisReport->dumpMessages();
-
 
922
//var_dump( $thisReport );
-
 
923
exit ( $result );
241
print implode( "\n", $result );
924
 
242
 
925
?>
243
?>