function revalidate($clause) { $nwus = 0; $nresults = 0; $wus = BoincWorkunit::enum($clause); foreach ($wus as $wu) { $results = BoincResult::enum("workunitid={$wu->id}"); $n = 0; foreach ($results as $result) { if ($result->server_state != 5) { continue; } if ($result->outcome != 1) { continue; } if ($result->validate_state < 2) { continue; } $result->update("validate_state=0"); echo "<br>updated result {$result->id}\n"; $n++; $nresults++; } if ($n) { $wu->update("need_validate=1"); echo "<br>updated wu {$wu->id}\n"; $nwus++; } } echo "Examined " . count($wus) . " jobs.\n"; echo "{$nwus} jobs and {$nresults} instances were marked for revalidation"; }
function reset_all() { BoincUserSubmit::update_aux("logical_start_time=0"); BoincBatch::update_aux("logical_start_time=0, logical_end_time=0"); BoincWorkunit::update_aux("priority=0"); BoincResult::update_aux("priority=0"); }
function get_gpu_list($vendor, $alt_vendor = null) { $clause = "plan_class like '%{$vendor}%'"; if ($alt_vendor) { $clause .= " or plan_class like '%{$alt_vendor}%'"; } $avs = BoincAppVersion::enum($clause); if (count($avs) == 0) { return null; } $av_ids = ""; foreach ($avs as $av) { $av_ids .= "{$av->id}, "; } $av_ids .= "0"; $t = time() - 30 * 86400; //echo "start enum $vendor $av_ids\n"; $results = BoincResult::enum("app_version_id in ({$av_ids}) and create_time > {$t} and elapsed_time>100 limit 500"); //echo "end enum\n"; $total = array(); $win = array(); $linux = array(); $mac = array(); foreach ($results as $r) { $h = BoincHost::lookup_id($r->hostid); if (!$h) { continue; } $wu = BoincWorkunit::lookup_id($r->workunitid); if (!$wu) { continue; } $v = $vendor == "cuda" ? "CUDA" : "CAL"; $model = get_gpu_model($h->serialnum, $v); if (!$model) { continue; } add_model($model, $r, $wu, $total); if (strstr($h->os_name, "Windows")) { add_model($model, $r, $wu, $win); } if (strstr($h->os_name, "Linux")) { add_model($model, $r, $wu, $linux); } if (strstr($h->os_name, "Darwin")) { add_model($model, $r, $wu, $mac); } } $x = null; $x->total = $total; $x->win = $win; $x->linux = $linux; $x->mac = $mac; return $x; }
function host_history($hostid, $avid) { $rs = BoincResult::enum("hostid={$hostid} and app_version_id={$avid} and validate_state=1 order by id desc limit 100"); echo "<pre>Results for host {$hostid}\n"; $n = 0; $total = 0; foreach ($rs as $r) { $raw_credit = $r->elapsed_time * $r->flops_estimate * COBB_SCALE; $n++; $total += $raw_credit; echo "ID <a href=credit.php?resultid={$r->id}>{$r->id}</a> raw {$raw_credit}\n"; } $avg = $total / $n; echo "avg: {$avg}\n"; echo "</pre>\n"; }
function handle_get_output($r, $batch) { $wus = BoincWorkUnit::enum("batch={$batch->id}"); $outdir = "/tmp/tree_threader_output_" . $batch->id; @mkdir($outdir); foreach ($wus as $wu) { if (!$wu->canonical_resultid) { continue; } $result = BoincResult::lookup_id($wu->canonical_resultid); if (!$result) { continue; } $paths = get_outfile_paths($result); if (sizeof($paths) < 1) { continue; } // there's only one output file // $path = $paths[0]; // unzip it into a directory in /tmp // $dir = "/tmp/{$wu->name}"; @mkdir($dir); $cmd = "cd {$dir}; unzip -q {$path}"; $ret = system($cmd); if ($ret === false) { error("can't unzip output file"); } $cmd = "cp {$dir}/ali/* {$outdir}"; $ret = system($cmd); if ($ret === false) { error("can't copy output files"); } //system("rm -rf $dir"); } $cmd = "zip -r -q {$outdir} {$outdir}"; $ret = system($cmd); if ($ret === false) { error("can't zip output files"); } $fname = "tree_threader_output_" . $batch->id . ".zip"; @symlink($outdir, "../../download/{$fname}"); $config = simplexml_load_string(file_get_contents("../../config.xml")); $download_url = trim((string) $config->config->download_url); echo "<tt_reply>\n<url>{$download_url}/{$fname}</url>\n</tt_reply>\n"; }
function show_batch($user) { $batch_id = get_int('batch_id'); $batch = BoincBatch::lookup_id($batch_id); if (!$batch || $batch->user_id != $user->id) { error_page("no batch"); } page_head("Batch {$batch->id}"); $results = BoincResult::enum("batch={$batch->id} order by workunitid"); $i = 0; result_table_start(true, true, null); foreach ($results as $result) { show_result_row($result, true, true, true, $i++); } end_table(); page_tail(); }
function possibly_delete_user($user) { if ($user->total_credit > 0.0) { admin_error_page("Cannot delete user: User has credit."); } // Don't delete user if they have any outstanding Results // if (BoincResult::count("userid={$user->id}")) { admin_error_page("Cannot delete user: User has count results in the database."); } // Don't delete user if they have posted to the forums // if (BoincPost::count("user={$user->id}")) { admin_error_page("Cannot delete user: User has forum posts."); } if ($user->teamid) { user_quit_team($user); } delete_user($user); }
// Copyright (C) 2008 University of California // // BOINC is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License // as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see <http://www.gnu.org/licenses/>. // show a result require_once "../inc/util.inc"; require_once "../inc/result.inc"; $x = get_int("resultid", true); if ($x) { $result = BoincResult::lookup_id($x); } else { $x = get_str("result_name"); $result = BoincResult::lookup_name($x); } if (!$result) { error_page(tra("No such task:") . " " . htmlspecialchars($x)); // the htmlspecialchars prevents XSS } page_head(tra("Task") . " " . htmlspecialchars($x)); show_result($result); page_tail();
if ($wu->canonical_resultid) { row2('canonical result', '<a href="result.php?resultid=$wu->canonical_resultid">$wu->canonical_resultid</a>'); row2("granted credit", format_credit($wu->canonical_credit)); } // if app is using adaptive replication and no canonical result yet, // don't show anything more // (so that bad guys can't tell if they have an unreplicated job) if ($app->target_nresults > 0 && !$wu->canonical_resultid) { row2("Tasks in progress", "suppressed pending completion"); end_table(); } else { row2("minimum quorum", $wu->min_quorum); row2("initial replication", $wu->target_nresults); row2("max # of error/total/success tasks", "{$wu->max_error_results}, {$wu->max_total_results}, {$wu->max_success_results}"); if ($wu->error_mask) { row2("errors", wu_error_mask_str($wu->error_mask)); } if ($wu->need_validate) { row2("validation", "Pending"); } end_table(); project_workunit($wu); result_table_start(false, true, null); $results = BoincResult::enum("workunitid={$wuid}"); $i = 0; foreach ($results as $result) { show_result_row($result, false, true, false, $i++); } echo "</table>\n"; } page_tail();
page_head(tra("Tasks for computer %1", $host->id)); } else { if ($userid) { $user = get_logged_in_user(); if ($userid != $user->id) { error_page(tra("No access")); } $clause = "userid={$userid}"; page_head(tra("Tasks for {$user->name}")); } else { error_page(tra("Missing user ID or host ID")); } } $clause2 = $clause . $state_clause[$state]; $query = "{$clause2} order by id desc limit {$offset}," . ($results_per_page + 1); $results = BoincResult::enum($query); $info = null; $info->number_of_results = count($results); $info->clause = $clause; $info->results_per_page = $results_per_page; $info->offset = $offset; $info->show_names = $show_names; $info->state = $state; echo show_result_navigation($info); result_table_start(true, false, $info); $i = 0; foreach ($results as $result) { if ($i >= $results_per_page) { break; } show_result_row($result, true, false, $show_names, $i);
function delete_results() { db_init(); $f = fopen('dbc_out.dat', 'r'); while (1) { $x = fgets($f); if (!$x) { break; } $n = sscanf($x, "%d", $resid); if ($n != 1) { echo "bad line: {$x}\n"; continue; } $result = BoincResult::lookup_id($resid); if (!$result) { echo "no result {$resultid}\n"; continue; } $wu = BoincWorkunit::lookup_id($result->workunitid); if ($wu) { echo "result has WU: {$resid}\n"; continue; } echo "deleting {$resid}\n"; // uncomment the following to actually delete die("edit script to enable deletion\n"); //_mysql_query("delete from result where id=$resid"); } }
function get_wu_output_files($wu_id, $auth_str) { $wu = BoincWorkunit::lookup_id($wu_id); if (!$wu) { die("no workunit {$wu_id}"); } $batch = BoincBatch::lookup_id($wu->batch); if (!$batch) { die("no batch {$wu->batch}"); } $user = BoincUser::lookup_id($batch->user_id); if (!$user) { die("no user {$batch->user_id}"); } $x = md5($user->authenticator . $wu_id); echo "user authenticator= {$user->authenticator}, wu_id={$wu_id}<br/>"; if ($x != $auth_str) { die("bad auth str: x={$x}, auth_str={$auth_str}"); } $zip_basename = tempnam("/tmp", "boinc_wu_" . $wu->name . "_"); $zip_filename = $zip_basename . ".zip"; $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); $upload_dir = parse_config(get_config(), "<upload_dir>"); if (!$wu->canonical_resultid) { die("no canonical result for wu {$wu->name}"); } $result = BoincResult::lookup_id($wu->canonical_resultid); $names = get_outfile_names($result); foreach ($names as $name) { $path = dir_hier_path($name, $upload_dir, $fanout); if (is_file($path)) { system("nice -9 zip -jq {$zip_basename} {$path}"); } } do_download($zip_filename); unlink($zip_filename); unlink($zip_basename); }
function query_completed_job($r) { xml_start_tag("query_completed_job"); list($user, $user_submit) = authenticate_user($r, null); $job_name = (string) $r->job_name; $job_name = BoincDb::escape_string($job_name); $wu = BoincWorkunit::lookup("name='{$job_name}'"); if (!$wu) { xml_error(-1, "no such job"); } $batch = BoincBatch::lookup_id($wu->batch); if ($batch->user_id != $user->id) { xml_error(-1, "not owner"); } echo "<completed_job>\n"; echo " <error_mask>{$wu->error_mask}</error_mask>\n"; if ($wu->canonical_resultid) { $result = BoincResult::lookup_id($wu->canonical_resultid); echo " <canonical_resultid>{$wu->canonical_resultid}</canonical_resultid>\n"; } else { $results = BoincResult::enum("workunitid={$job_id}"); foreach ($results as $r) { switch ($r->outcome) { case 1: case 3: case 6: $result = $r; break; } } if ($result) { echo " <error_resultid>{$result->id}</error_resultid>\n"; } } if ($result) { echo " <exit_status>{$result->exit_status}</exit_status>\n"; echo " <elapsed_time>{$result->elapsed_time}</elapsed_time>\n"; echo " <cpu_time>{$result->cpu_time}</cpu_time>\n"; echo " <stderr_out><![CDATA[\n"; echo htmlspecialchars($result->stderr_out); echo " ]]></stderr_out>\n"; } echo "</completed_job>\n </query_completed_job>\n "; }
function show_av($av_id) { $av = BoincAppVersion::lookup_id($av_id); $app = BoincApp::lookup_id($av->appid); $plat = BoincPlatform::lookup_id($av->platformid); $av_desc = "{$plat->name} {$av->plan_class}"; page_head("App version {$av_desc} credit"); start_table(); row2("PFC samples", $av->pfc_n); row2("PFC average", $av->pfc_avg); row2("PFC scale", $av->pfc_scale); row2("App", $app->user_friendly_name); end_table(); $results = BoincResult::enum("app_version_id={$av_id} and validate_state=1"); start_table(); table_header("Host/App_version", "Elapsed", "FLOPS est"); foreach ($results as $r) { $avs = av_string($r->app_version_id); table_row("<a href=credit.php?host_id={$r->hostid}&a_id={$r->app_version_id}> host {$r->hostid} AV {$avs}</a>", $r->elapsed_time, $r->flops_estimate); } end_table(); page_tail(); }
function query_job($r) { list($user, $user_submit) = authenticate_user($r, null); $job_id = (int) $r->job_id; $wu = BoincWorkunit::lookup_id($job_id); if (!$wu) { error("no such job"); } $batch = BoincBatch::lookup_id($wu->batch); if ($batch->user_id != $user->id) { error("not owner"); } echo "<job>\n"; $results = BoincResult::enum("workunitid={$job_id}"); foreach ($results as $result) { echo " <instance>\n <name>{$result->name}</name>\n <id>{$result->id}</id>\n <state>" . state_string($result) . "</state>\n"; if ($result->server_state == 5) { // over? $paths = get_outfile_paths($result); foreach ($paths as $path) { if (is_file($path)) { $size = filesize($path); echo " <outfile>\n <size>{$size}</size>\n </outfile>\n"; } } } echo "</instance>\n"; } echo "</job>\n"; }
// BOINC is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with BOINC. If not, see <http://www.gnu.org/licenses/>. // delete results without a corresponding workunit. // (in principle these shouldn't exist) error_reporting(E_ALL); ini_set('display_errors', true); ini_set('display_startup_errors', true); require_once "../inc/boinc_db.inc"; $ndel = 0; while (1) { $rs = BoincResult::enum("true order by id limit 100"); $found = false; foreach ($rs as $r) { $wu = BoincWorkunit::lookup_id($r->workunitid); if ($wu) { echo "{$r->id} has a WU\n"; $found = true; break; } else { echo "{$r->id} has no WU - deleting\n"; $ndel++; $r->delete(); } } if ($found) { break;
function handle_query_job($user) { $wuid = get_int('wuid'); $wu = BoincWorkunit::lookup_id($wuid); if (!$wu) { error_page("no such job"); } page_head("Job {$wuid}"); echo "\n <a href=workunit.php?wuid={$wuid}>Workunit details</a> ·\n <a href=submit.php?action=query_batch&batch_id={$wu->batch}>Batch {$wu->batch}</a>\n "; // show input files // echo "<h2>Input files</h2>\n"; $x = "<in>" . $wu->xml_doc . "</in>"; $x = simplexml_load_string($x); start_table(); table_header("Logical name<br><p class=\"text-muted\">(click to view)</p>", "Size (bytes)", "MD5"); foreach ($x->workunit->file_ref as $fr) { $pname = (string) $fr->file_name; $lname = (string) $fr->open_name; foreach ($x->file_info as $fi) { if ((string) $fi->name == $pname) { table_row("<a href={$fi->url}>{$lname}</a>", $fi->nbytes, $fi->md5_cksum); break; } } } end_table(); echo "<h2>Instances</h2>\n"; start_table(); table_header("Instance ID<br><p class=\"text-muted\">click for result page</p>", "State", "Output files<br><p class=\"text-muted\">click to view the file</p>"); $results = BoincResult::enum("workunitid={$wuid}"); $upload_dir = parse_config(get_config(), "<upload_dir>"); $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); foreach ($results as $result) { echo "<tr>\n <td><a href=result.php?resultid={$result->id}>{$result->id} · {$result->name} </a></td>\n <td>" . state_string($result) . "</td>\n <td>\n"; $i = 0; if ($result->server_state == 5) { $names = get_outfile_names($result); $i = 0; foreach ($names as $name) { $url = boinc_get_output_file_url($user, $result, $i++); $path = dir_hier_path($name, $upload_dir, $fanout); $s = stat($path); $size = $s['size']; echo "<a href={$url}>{$name} </a> (" . number_format($size) . " bytes)<br/>"; } $i++; } echo "</td></tr>\n"; } end_table(); echo "<p><a href=submit.php>Return to job control page</a>\n"; page_tail(); }
function handle_get_output($r, $batch) { global $log; $timestamp = date("Y-m-d H:i", time()); $wus = BoincWorkUnit::enum("batch={$batch->id}"); $outdir = "/tmp/treeThreader_result_" . $batch->id; @mkdir($outdir); foreach ($wus as $wu) { if (!$wu->canonical_resultid) { continue; } $result = BoincResult::lookup_id($wu->canonical_resultid); if (!$result) { continue; } $paths = get_outfile_paths($result); if (sizeof($paths) < 1) { continue; } // there's only one output file // $path = $paths[0]; // unzip it into a directory in /tmp // $dir = "/tmp/{$wu->name}"; @mkdir($dir); $cmd = "cd {$dir}; unzip -q {$path}"; system($cmd, $ret); if ($ret != 0) { error("can't unzip output file"); } $cmd = "cp {$dir}/Aln/* {$outdir}"; system($cmd, $ret); if ($ret != 0) { error("can't copy output files"); } system("rm -rf {$dir}"); } $cmd = "zip -r -q {$outdir} {$outdir}"; system($cmd, $ret); if ($ret != $ret) { error("can't zip output files"); } $fname = "treeThreader_result_" . $batch->id . ".zip"; $treeThreader_dir = "treeThreaderResult"; if (!is_dir("../../download/{$treeThreader_dir}")) { mkdir("../../download/{$treeThreader_dir}"); } @symlink("/tmp/{$fname}", "../../download/{$treeThreader_dir}/{$fname}"); system("rm -fr {$outdir}"); $config = simplexml_load_string(file_get_contents("../../config.xml")); $download_url = trim((string) $config->config->download_url); echo "<tt_reply>\n<url>{$download_url}/{$treeThreader_dir}/{$fname}</url>\n</tt_reply>\n"; $log_msg = "{$timestamp}\tuser {$batch->user_id} downloads results for batch {$batch->id} : {$download_url}/{$treeThreader_dir}/{$fname}\n"; fwrite($log, $log_msg); }
function get_job_status() { $s = unserialize(get_cached_data(STATUS_PAGE_TTL, "job_status")); if ($s) { return $s; } $s = new StdClass(); $apps = BoincApp::enum("deprecated=0"); foreach ($apps as $app) { $info = BoincDB::get()->lookup_fields("result", "stdClass", "ceil(avg(elapsed_time)/3600*100)/100 as avg,\n ceil(min(elapsed_time)/3600*100)/100 as min,\n ceil(max(elapsed_time)/3600*100)/100 as max,\n count(distinct userid) as users", "appid = {$app->id}\n AND validate_state=1\n AND received_time > (unix_timestamp()-86400)\n "); $app->info = $info; $app->unsent = BoincResult::count("appid={$app->id} and server_state=2"); $app->in_progress = BoincResult::count("appid={$app->id} and server_state=4"); } $s->apps = $apps; $s->results_ready_to_send = BoincResult::count("server_state=2"); $s->results_in_progress = BoincResult::count("server_state=4"); $s->results_need_file_delete = BoincResult::count("file_delete_state=1"); $s->wus_need_validate = BoincWorkunit::count("need_validate=1"); $s->wus_need_assimilate = BoincWorkunit::count("assimilate_state=1"); $s->wus_need_file_delete = BoincWorkunit::count("file_delete_state=1"); $x = BoincDB::get()->lookup_fields("workunit", "stdClass", "MIN(transition_time) as min", "TRUE"); $gap = (time() - $x->min) / 3600; if ($gap < 0 || $x->min == 0) { $gap = 0; } $s->transitioner_backlog = $gap; $s->users_with_recent_credit = BoincUser::count("expavg_credit>1"); $s->users_with_credit = BoincUser::count("total_credit>1"); $s->users_past_24_hours = BoincUser::count("create_time > (unix_timestamp() - 86400)"); $s->hosts_with_recent_credit = BoincHost::count("expavg_credit>1"); $s->hosts_with_credit = BoincHost::count("total_credit>1"); $s->hosts_past_24_hours = BoincHost::count("create_time > (unix_timestamp() - 86400)"); $s->flops = BoincUser::sum("expavg_credit") / 200; $s->db_revision = null; if (file_exists("../../db_revision")) { $s->db_revision = trim(file_get_contents("../../db_revision")); } $s->cached_time = time(); $e = set_cached_data(STATUS_PAGE_TTL, serialize($s), "job_status"); if ($e) { echo "set_cached_data(): {$e}\n"; } return $s; }
function handle_query_job($user) { $wuid = get_int('wuid'); page_head("Job {$wuid}"); echo "<a href=workunit.php?wuid={$wuid}>View workunit page</a>\n"; // show input files // echo "<h2>Input files</h2>\n"; $wu = BoincWorkunit::lookup_id($wuid); $x = "<in>" . $wu->xml_doc . "</in>"; $x = simplexml_load_string($x); start_table(); table_header("Logical name<br><span class=note>(click to view)</span>", "Size (bytes)", "MD5"); $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); foreach ($x->workunit->file_ref as $fr) { $pname = (string) $fr->file_name; $lname = (string) $fr->open_name; $dir = filename_hash($pname, $fanout); $path = "../../download/{$dir}/{$pname}"; $md5 = md5_file($path); $s = stat($path); $size = $s['size']; table_row("<a href=/download/{$dir}/{$pname}>{$lname}</a>", $size, $md5); } end_table(); echo "<h2>Instances</h2>\n"; start_table(); table_header("Instance ID<br><span class=note>click for result page</span>", "State", "Output files<br><span class=note>click to view the file</span>"); $results = BoincResult::enum("workunitid={$wuid}"); foreach ($results as $result) { echo "<tr>\n <td><a href=result.php?resultid={$result->id}>{$result->id} | {$result->name} </a></td>\n <td>" . state_string($result) . "</td>\n <td>\n"; $i = 0; if ($result->server_state == 5) { $names = get_outfile_names($result); $fanout = parse_config(get_config(), "<uldl_dir_fanout>"); $i = 0; foreach ($names as $name) { $url = boinc_get_output_file_url($user, $result, $i++); $path = dir_hier_path($name, "../../upload", $fanout); $s = stat($path); $size = $s['size']; echo "<a href={$url}>{$name} </a> (" . number_format($size) . " bytes)<br/>"; } $i++; } echo "</td></tr>\n"; } end_table(); echo "<p><a href=submit.php>Return to job control page</a>\n"; page_tail(); }
echo " <workunitid>" . $result->workunitid . "</workunitid>\n"; echo " <hostid>" . $result->hostid . "</hostid>\n"; echo " <claimed_credit>" . $result->claimed_credit . "</claimed_credit>\n"; echo " <received_time>" . $result->received_time . "</received_time>\n"; echo "</result>\n"; $sum += $result->claimed_credit; } echo "<total_claimed_credit>" . $sum . "</total_claimed_credit>\n"; echo "</pending_credit>\n"; } else { $user = get_logged_in_user(); $sum = 0; page_head(tra("Pending credit")); start_table(); echo "<tr><th>" . tra("Result ID") . "</th><th>" . tra("Workunit ID") . "</th><th>" . tra("Host ID") . "</th><th>" . tra("Claimed credit") . "</th></tr>\n"; $results = BoincResult::enum("userid={$user->id} AND (validate_state=0 OR validate_state=4) AND claimed_credit > 0"); foreach ($results as $result) { echo "<tr>\n"; echo "<td><a href=\"result.php?resultid={$result->id}\">{$result->id}</a></td>\n"; echo "<td><a href=\"workunit.php?wuid={$result->workunitid}\">{$result->workunitid}</a></td>\n"; echo "<td><a href=\"show_host_detail.php?hostid={$result->hostid}\">{$result->hostid}</a></td>\n"; echo "<td>" . format_credit($result->claimed_credit) . "</td>\n"; echo "</tr>\n"; $sum += $result->claimed_credit; } end_table(); echo tra("Pending credit: %1", format_credit($sum)); page_tail(); } $cvs_version_tracker[] = "\$Id\$"; //Generated automatically - do not edit
require_once "../inc/util.inc"; require_once "../inc/result.inc"; $ncodes = get_int('ncodes', true); if (!$ncodes) { $ncodes = 10; } $nresults_per_code = get_int('nresults_per_code', true); if (!$nresults_per_code) { $nresults_per_code = 10; } function compare($x, $y) { return $x->count < $y->count; } $t = time() - 7 * 86400; $results = BoincResult::enum_fields("id, exit_status", "server_state=5 and outcome=3 and exit_status<>0 and received_time>{$t}", ""); $error_codes = array(); foreach ($results as $r) { $e = $r->exit_status; if (array_key_exists($e, $error_codes)) { $x = $error_codes[$e]; $x->count++; $x->results[] = $r; $error_codes[$e] = $x; } else { $x = new StdClass(); $x->count = 1; $x->results = array($r); $error_codes[$e] = $x; } }