#!/usr/bin/php read($project_name)) { echo "Can not read Gnucomo configuration file for $project_name.\n"; exit(); } openlog("gnucomo", LOG_PID, LOG_DAEMON); //Open an connection to the database $dbms_type = $class_settings->find_parameter("database", "type"); $dbms_host = $class_settings->find_parameter("database", "host"); $dbms_name = $class_settings->find_parameter("database", "name"); $dbms_user = $class_settings->find_parameter("gcm_daemon", "user"); $dbms_password = $class_settings->find_parameter("gcm_daemon", "password"); db_select($dbms_type); $dbms = new db(); $dbms->db_host = $dbms_host; $dbms->db_name = $dbms_name; $dbms->db_user = $dbms_user; $dbms->db_password = $dbms_password; $dbms->db_connect($class_settings->database()); if ($dbms->have_db_connection() == "FALSE") { exit ("Database connection failed."); } if ($purge_date != "") { purge_old_logs($purge_date); } else { // Check the references from the abuse list to the logs $abuse_result = $dbms->query("select source, nr_abuses, masklen(source) from object_abuse where (status='dropped' or status='') and masklen(source)>16 and objectid=11 order by source"); for ($ab = 0; $ab < $dbms->num_rows($abuse_result); $ab++) { $logentries = 0; $abuse = $dbms->fetch_object($abuse_result, $ab); $nr_abuses = $abuse->nr_abuses; $log_res = $dbms->query("select logid from log_abuse where source='" . $abuse->source . "' and objectid=11"); if ($dbms->num_rows($log_res) != $nr_abuses) { echo "Mismatch in nr of abuses. Corrected.\n"; $dbms->query("update object_abuse set nr_abuses=" . $dbms->num_rows($log_res) . " where source='" . $abuse->source . "' and objectid=11"); } if ($dbms->num_rows($log_res) == 0) { echo " Removing ", $abuse->source, "\n"; $dbms->query("delete from object_abuse where source='". $abuse->source . "' and objectid=11"); } else { $logref_res = $dbms->query("select logid from log where logid in (select logid from log_abuse where source='" . $abuse->source . "' and objectid=11)"); $logentries = $dbms->num_rows($logref_res); if ($logentries == 0) { echo "All references to log entries are lost. Purging log_abuse table.\n"; $dbms->query("delete from log_abuse where source='" . $abuse->source . "' and objectid=11"); } } echo $abuse->source . "\t$nr_abuses\t" . $dbms->num_rows($log_res) . "\t" . $logentries . "\n"; } } // Gather the statistics for each object $obj_result = $dbms->query("SELECT objectid FROM object"); for ($obj = 0; $obj < $dbms->num_rows($obj_result); $obj++) { $object = $dbms->fetch_object($obj_result, $obj); echo "Gathering statistics for object " . $object->objectid . "\n"; GatherStatistics($object->objectid); } function purge_old_logs($purge_date) { global $dbms; /* * Make a temporary table with the logids of the old log entries * We don't want to repeat a selection on the large log table itself. */ echo "Purging log entries before $purge_date\n"; $dbms->query("CREATE TABLE gcm_deamon_old_log AS SELECT logid FROM log WHERE timestamp < '$purge_date'"); $dbms->query("SELECT logid FROM gcm_deamon_old_log"); echo $dbms->num_rows() . " log entries found.\n"; // Clean up notifications that are left without reference to the log. $r = $dbms->query("select notificationid from log_notification where logid in (select logid from gcm_deamon_old_log) group by notificationid"); echo "Notifications that may be affected:\n"; $notifications = array(); for ($i=0; $i < $dbms->num_rows(); $i++) { $notif = $dbms->fetch_object($r, $i); $notifications[] = $notif->notificationid; echo $notif->notificationid . "\n"; } $dbms->query("delete from log_notification where logid in (select logid from gcm_deamon_old_log)"); // Clean up any notifications that have no more logs left foreach ($notifications as $notif) { $c = $dbms->fetch_object($dbms->query("select count(*) from log_notification where notificationid=$notif"), 0); echo "Notification $notif has " . $c->count . " log entries left.\n"; if ($c->count == 0) { echo "Cleaning up notification $notif.\n"; $dbms->query("delete from action_user where notificationid=$notif"); $dbms->query("delete from notification where notificationid=$notif"); } } // Clean up abuses that are left without reference to the log. $r = $dbms->query("select source from log_abuse where masklen(source) > 16 and logid in (select logid from gcm_deamon_old_log) group by source"); echo "Abusing IP addresses that may be affected:\n"; $abusers = array(); for ($i = 0; $i < $dbms->num_rows(); $i++) { $ab = $dbms->fetch_object($r, $i); $abusers[] = $ab->source; echo $ab->source . "\n"; } $dbms->query("delete from log_abuse where logid in (select logid from gcm_deamon_old_log)"); foreach ($abusers as $src) { $c = $dbms->fetch_object($dbms->query("select count(*) from log_abuse where source='$src'"), 0); echo "IP address $src has " . $c->count . " log entries left.\n"; if ($c->count == 0) { echo "Cleaning up abusing address $src.\n"; $dbms->query("delete from object_abuse where source='$src' and (status='' or status='dropped')"); } } $dbms->query("delete from log where logid in (select logid from gcm_deamon_old_log)"); $dbms->query("drop table gcm_deamon_old_log"); } /* * Update a single statistic for some object. * If it does not yet exist, it will be created. */ function UpdateStatistic($objectid, $name, $value) { global $dbms; $result = $dbms->query("SELECT objectid FROM object_statistics WHERE objectid='$objectid' AND statname='$name'"); if ($dbms->num_rows() == 0) { $dbms->query("INSERT INTO object_statistics VALUES ('$objectid', '$name', '$value')"); } else { $dbms->query("UPDATE object_statistics SET statvalue='$value' WHERE statname='$name' AND objectid='$objectid'"); } } /* * Gather the statistics for a single object ($objectid). * We count the number of parameters, removed parameters, notifications * closed notifications and log entries. The totals of these are * maintained in a separate table: object_statistics. */ function GatherStatistics($objectid) { global $dbms; // Gather statistics on parameters $r = $dbms->query("SELECT paramid FROM parameter WHERE objectid=CAST('" . $objectid . "' AS BIGINT)"); $nr_parameters = $dbms->num_rows($r); $removed_parameters = 0; for ($p = 0; $p < $nr_parameters; $p++) { $param = pg_fetch_object($r, $p); $qry ="select change_nature from history where paramid= CAST('"; $qry .= $param->paramid . "' AS BIGINT) order by modified desc"; $rhist = $dbms->query($qry); if ($dbms->num_rows($rhist) == 0) { echo "ERROR: No history for parameter id " . $param->paramid . "\n"; } else { $hist = $dbms->fetch_object($rhist, 0); if ($hist->change_nature == "REMOVED") { $removed_parameters++; } } } UpdateStatistic($objectid, 'parameters', $nr_parameters); UpdateStatistic($objectid, 'removed_parameters', $removed_parameters); // Gather statistics on notifications $r = $dbms->query("SELECT count(notificationid) FROM notification WHERE objectid = CAST('" . $objectid . "' AS BIGINT)"); $cnt = $dbms->fetch_object($r, 0); UpdateStatistic($objectid, 'notifications', $cnt->count); $r = $dbms->query("SELECT count(notificationid) FROM notification WHERE objectid = CAST('" . $objectid . "' AS BIGINT) AND statuscode ='cls'"); $cnt = $dbms->fetch_object($r, 0); UpdateStatistic($objectid, 'closed_notifications', $cnt->count); // Gather statistics on log entries $r = $dbms->query("SELECT count(logid) FROM log WHERE objectid = CAST('" . $objectid . "' AS BIGINT)"); $cnt = $dbms->fetch_object($r, 0); UpdateStatistic($objectid, 'logs', $cnt->count); }