Completed
Push — master ( 853573...80a2ca )
by Kevin
12:02
created

html/inc/host.inc::vbox_desc()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 6
nop 1
dl 0
loc 18
rs 8.4444
c 0
b 0
f 0
1
<?php
2
// This file is part of BOINC.
3
// http://boinc.berkeley.edu
4
// Copyright (C) 2008 University of California
5
//
6
// BOINC is free software; you can redistribute it and/or modify it
7
// under the terms of the GNU Lesser General Public License
8
// as published by the Free Software Foundation,
9
// either version 3 of the License, or (at your option) any later version.
10
//
11
// BOINC is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
// See the GNU Lesser General Public License for more details.
15
//
16
// You should have received a copy of the GNU Lesser General Public License
17
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
18
19
require_once("../inc/credit.inc");
20
require_once("../inc/stats_sites.inc");
21
require_once("../inc/boinc_db.inc");
22
require_once("../inc/user.inc");
23
24
function link_to_results($host) {
25
    if (!$host) return tra("No host");
26
    $config = get_config();
27
    if (!parse_bool($config, "show_results")) return tra("Unavailable");
28
    $nresults = host_nresults($host);
29
    if (!$nresults) return "0";
30
    return "<a href=results.php?hostid=$host->id>$nresults</a>";
31
}
32
33
function sched_log_name($x) {
34
    if ($x == 0) return "NO_SUCH_LOG";
35
    return gmdate('Y-m-d_H/Y-m-d_H:i', $x) . ".txt";
36
}
37
38
function sched_log_link($x) {
39
    if (file_exists("sched_logs")) {
40
        return "<a href=\"../sched_logs/" . sched_log_name($x) . "\">" . time_str($x) . "</a>";
41
    } else {
42
        return time_str($x);
43
    }
44
}
45
46
function location_form($host) {
47
    $none = "selected";
48
    $h=$w=$s=$m="";
0 ignored issues
show
Unused Code introduced by
$m is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
49
    if ($host->venue == "home") $h = "selected";
50
    if ($host->venue == "work") $w = "selected";
51
    if ($host->venue == "school") $s = "selected";
52
    $x = "<form action=host_venue_action.php>
53
        <input type=hidden name=hostid value=$host->id>
54
        <select class=\"form-control\" name=venue>
55
        <option value=\"\" $none>---
56
        <option value=home $h>".tra("Home")."
57
        <option value=work $w>".tra("Work")."
58
        <option value=school $s>".tra("School")."
59
        </select>
60
        <p></p>
61
        <input class=\"btn btn-primary btn-sm\" type=submit value=\"".tra("Update location")."\">
62
        </form>
63
    ";
64
    return $x;
65
}
66
67
function cross_project_links($host) {
68
    global $host_sites;
69
    $x = "";
70
    foreach ($host_sites as $h) {
71
        $url = $h[0];
72
        $name = $h[1];
73
        $img = $h[2];
74
        $x .= "<a href=$url".$host->host_cpid."><img class=\"icon\" border=2 src=img/$img alt=\"$name\"></a> ";
75
    }
76
    return $x;
77
}
78
79
// Show full-page description of $host.
80
// If $user is non-null, it's both the owner of the host
81
// and the logged in user (so show some extra fields)
82
//
83
function show_host($host, $user, $ipprivate) {
84
    start_table();
85
    row1(tra("Computer information"));
86
    $anonymous = false;
87
    if ($user) {
88
        if ($ipprivate) {
89
            row2(tra("IP address"), "$host->last_ip_addr<br>".tra("(same the last %1 times)", $host->nsame_ip_addr));
90
            if ($host->last_ip_addr != $host->external_ip_addr) {
91
                row2(tra("External IP address"), $host->external_ip_addr);
92
            }
93
        } else { 
94
            row2(tra("IP address"), "<a href=show_host_detail.php?hostid=$host->id&ipprivate=1>".tra("Show IP address")."</a>");
95
        }
96
        row2(tra("Domain name"), $host->domain_name);
97
        if ($host->product_name) {
98
            row2(tra("Product name"), $host->product_name);
99
        }
100
        $x = $host->timezone/3600;
101
        if ($x >= 0) $x="+$x";
102
        row2(tra("Local Standard Time"), tra("UTC %1 hours", $x));
103
    } else {
104
        $owner = BoincUser::lookup_id($host->userid);
105
        if ($owner && $owner->show_hosts) {
106
            row2(tra("Owner"), user_links($owner, BADGE_HEIGHT_MEDIUM));
107
        } else {
108
            row2(tra("Owner"), tra("Anonymous"));
109
            $anonymous = true;
110
        }
111
    }
112
    row2(tra("Created"), time_str($host->create_time));
113 View Code Duplication
    if (!NO_STATS) {
114
        row2(tra("Total credit"), format_credit_large($host->total_credit));
115
        row2(tra("Average credit"), format_credit($host->expavg_credit));
116
        if (!$anonymous) {
117
            row2(tra("Cross project credit"), cross_project_links($host));
118
        }
119
    }
120
    row2(tra("CPU type"), "$host->p_vendor <br> $host->p_model");
121
    row2(tra("Number of processors"), $host->p_ncpus);
122
    if ($host->serialnum) {
123
        row2(tra("Coprocessors"), gpu_desc($host->serialnum));
124
    }
125
    row2(tra("Virtualization"), vbox_desc($host->serialnum));
126
    row2(tra("Operating System"), "$host->os_name <br> $host->os_version");
127
    $v = boinc_version($host->serialnum);
128
    if ($v) {
129
        row2(tra("BOINC version"), $v);
130
    }
131
    $x = $host->m_nbytes/GIGA;
132
    $y = round($x, 2);
133
    row2(tra("Memory"), tra("%1 GB", $y));
134
    if ($host->m_cache > 0) {
135
        $x = $host->m_cache/KILO;
136
        $y = round($x, 2);
137
        row2(tra("Cache"), tra("%1 KB", $y));
138
    }
139
140
    if ($user) {
141
        $x = $host->m_swap/GIGA;
142
        $y = round($x, 2);
143
        row2(tra("Swap space"), tra("%1 GB", $y));
144
        $x = $host->d_total/GIGA;
145
        $y = round($x, 2);
146
        row2(tra("Total disk space"), tra("%1 GB", $y));
147
        $x = $host->d_free/GIGA;
148
        $y = round($x, 2);
149
        row2(tra("Free Disk Space"), tra("%1 GB", $y));
150
    }
151
    $x = $host->p_fpops/1e9;
152
    $y = round($x, 2);
153
    row2(tra("Measured floating point speed"), tra("%1 billion ops/sec", $y));
154
    $x = $host->p_iops/1e9;
155
    $y = round($x, 2);
156
    row2(tra("Measured integer speed"), tra("%1 billion ops/sec", $y));
157
    $x = $host->n_bwup/KILO;
158
    $y = round($x, 2);
159 View Code Duplication
    if ($y > 0) {
160
        row2(tra("Average upload rate"), tra("%1 KB/sec", $y));
161
    } else {
162
        row2(tra("Average upload rate"), tra("Unknown"));
163
    }
164
    $x = $host->n_bwdown/KILO;
165
    $y = round($x, 2);
166 View Code Duplication
    if ($y > 0) {
167
        row2(tra("Average download rate"), tra("%1 KB/sec", $y));
168
    } else {
169
        row2(tra("Average download rate"), tra("Unknown"));
170
    }
171
    $x = $host->avg_turnaround/86400;
172
    if (!NO_COMPUTING) {
173
        row2(tra("Average turnaround time"), tra("%1 days", round($x, 2)));
174
        row2(tra("Application details"),
175
            "<a href=host_app_versions.php?hostid=$host->id>".tra("Show")."</a>"
176
        );
177
        $config = get_config();
178
        if (parse_bool($config, "show_results")) {
179
            $nresults = host_nresults($host);
180
            if ($nresults) {
181
                $results = "<a href=results.php?hostid=$host->id>$nresults</a>";
182
            } else {
183
                $results = "0";
184
            }
185
            row2(tra("Tasks"), $results);
186
        }
187
    }
188
189
    if ($user) {
190
        row2(tra("Number of times client has contacted server"), $host->rpc_seqno);
191
        row2(tra("Last time contacted server"), sched_log_link($host->rpc_time));
192
        row2(tra("Fraction of time BOINC is running"), number_format(100*$host->on_frac, 2)."%");
193
        if ($host->connected_frac > 0) {
194
            row2(tra("While BOINC is running, fraction of time computer has an Internet connection"), number_format(100*$host->connected_frac, 2)."%");
195
        }
196
        row2(tra("While BOINC is running, fraction of time computing is allowed"), number_format(100*$host->active_frac, 2)."%");
197
        row2(tra("While is BOINC running, fraction of time GPU computing is allowed"), number_format(100*$host->gpu_active_frac, 2)."%");
198
        if ($host->cpu_efficiency) {
199
            row2(tra("Average CPU efficiency"), $host->cpu_efficiency);
200
        }
201
        if (!NO_COMPUTING) {
202
            if ($host->duration_correction_factor) {
203
                row2(tra("Task duration correction factor"), $host->duration_correction_factor);
204
            }
205
        }
206
        row2(tra("Location"), location_form($host));
207
        if ($nresults == 0) {
0 ignored issues
show
Bug introduced by
The variable $nresults does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
208
            $x = " &middot; <a href=host_delete.php?hostid=$host->id".url_tokens($user->authenticator).">".tra("Delete this computer")."</a> ";
209
        } else {
210
            $x = "";
211
        }
212
        row2(tra("Merge duplicate records of this computer"), "<a class=\"btn btn-primary btn-sm\" href=host_edit_form.php?hostid=$host->id>".tra("Merge")."</a> $x");
213
    } else {
214
        row2(tra("Number of times client has contacted server"), $host->rpc_seqno);
215
        row2(tra("Last contact"), date_str($host->rpc_time));
216
    }
217
    echo "</table>\n";
218
219
}
220
221
// the following is used for list of top hosts
222
//
223
function top_host_table_start($sort_by) {
224
    global $host_sites;
225
    shuffle($host_sites);
226
    start_table('table-striped');
227
    $x = array(
228
        tra("Computer info"),
229
        tra("Rank"),
230
        tra("Owner"),
231
    );
232 View Code Duplication
    if (!NO_STATS) {
233
        if ($sort_by == 'total_credit') {
234
            $x[] = "<a href=top_hosts.php?sort_by=expavg_credit>".tra("Avg. credit")."</a>";
235
            $x[] = tra("Total credit");
236
        } else {
237
            $x[] = tra("Recent average credit");
238
            $x[] = "<a href=top_hosts.php?sort_by=total_credit>".tra("Total credit")."</a>";
239
        }
240
    }
241
    $x[] = tra("BOINC version");
242
    $x[] = tra("CPU");
243
    $x[] = tra("GPU");
244
    $x[] = tra("Operating system");
245
    $s = 'style="text-align:right;"';
246
    $a = array("", "", "", $s, $s, "", "", "", "");
247
    row_heading_array($x, $a, "bg-default");
248
}
249
250
function host_nresults($host) {
251
    return BoincResult::count("hostid=$host->id");
252
}
253
254
255
// Parse the Virtualbox version information from inside the serialnum field.
256
// Prior to BOINC commit 6121ce1, the DB entry looked like e.g. "[vbox|5.0.0]"
257
// where 5.0.0 gave the Virtualbox version number. After 6121ce1, the entry was
258
// "[vbox|5.0.0|1|1]", where now two additional flags give information about
259
// hardware virtualization support. Older clients may have the old-style
260
// serialnum in the DB despite the server being upgraded.
261
function vbox_desc($x){
262
    if (preg_match("/\[vbox\|(.*?)(\|([01])\|([01]))?\]/",$x,$matches)){
263
        $desc = "Virtualbox (".$matches[1].") ".tra("installed");
264
        if (sizeof($matches)>2){
265
            if ($matches[3]=="1" and $matches[4]=="1") {
266
                return $desc.tra(", CPU has hardware virtualization support and it is enabled");
267
            } elseif ($matches[3]=="1" and $matches[4]=="0") {
268
                return $desc.tra(", CPU has hardware virtualization support but it is disabled");
269
            } elseif ($matches[3]=="0") {
270
                return $desc.tra(", CPU does not have hardware virtualization support");
271
            }
272
        } else {
273
            return $desc;
274
        }
275
    } else {
276
        return tra("None");
277
    }
278
}
279
280
// Given string of the form [BOINC|vers][type|model|count|RAM|driver-vers][vbox|vers],
281
// return a human-readable version of the GPU info
282
//
283
function gpu_desc($x, $detail=true) {
284
    $descs = explode("]", $x);
285
    array_pop($descs);
286
    $str = "";
287
    foreach ($descs as $desc) {
288
        $desc = trim($desc, "[");
289
        $d = explode("|", $desc);
290
        //print_r($d);
291
        if ($d[0] == "BOINC") continue;
292
        if ($d[0] == "vbox") continue;
293
        if ($str) $str .= "<p>";
294
        if ($d[2]!="" && $d[2]!="1") $str .= "[".$d[2]."] ";
295
        if ($d[0] == "CUDA") {
296
            $str .= "NVIDIA";
297
        } else if ($d[0] == "CAL") {
298
            $str .= "AMD";
299
        } else if ($d[0] == "opencl_gpu") {
300
            $str .= "OpenCL GPU";
301
        } else {
302
            $str .= $d[0];
303
        }
304
        $str .= " ".$d[1];
305
        if ($detail) {
306
            $str .= " (".$d[3].")";
307 View Code Duplication
            if (array_key_exists(4, $d)) {
308
                if ($d[4] != "" && $d[4] != 0) {
309
                    // if version has no '.', assume it's in 100*maj+min form
310
                    //
311
                    if (strchr($d[4], '.')) {
312
                        $str .= " driver: ".$d[4];
313
                    } else {
314
                        $i = (int)$d[4];
315
                        $maj = (int)($i/100);
316
                        $min = $i%100;
317
                        $str .= sprintf(" driver: %d.%02d", $maj, $min);
318
                    }
319
                }
320
            }
321 View Code Duplication
            if (array_key_exists(5, $d)) {
322
                if ($d[5] != "" && $d[5] != 0) {
323
                    if (strchr($d[5], '.')) {
324
                        $str .= " OpenCL: ".$d[5];
325
                    } else {
326
                        $i = (int)$d[5];
327
                        $maj = (int)($i/100);
328
                        $min = $i%100;
329
                        $str .= sprintf(" OpenCL: %d.%d", $maj, $min);
330
                    }
331
                }
332
            }
333
        }
334
    }
335
    if (!$str) $str = "---";
336
    return $str;
337
}
338
339
// Given the same string as above, return the BOINC version
340
//
341
function boinc_version($x) {
342
    $y = strstr($x, 'BOINC');
343
    if (!$y) return '';
344
    $z = explode("]", $y, 2);
345
    $a = explode('|', $z[0]);
346
    $v = $a[1];
347
    if (array_key_exists(2, $a)) {
348
        $brand = $a[2];
349
        $v .= " ($brand)";
350
    }
351
    return $v;
352
}
353
354
function cpu_desc($host) {
355
    return "$host->p_vendor<br>$host->p_model<br>".tra("(%1 processors)", $host->p_ncpus)."\n";
356
}
357
358
// If private is true, we're showing the host to its owner,
359
// so it's OK to show the domain name etc.
360
// If private is false, show the owner's name only if they've given permission
361
//
362
function show_host_row($host, $i, $private, $show_owner, $any_product_name) {
363
    $anonymous = false;
364
    if (!$private) {
365
        if ($show_owner) {
366
            $user = BoincUser::lookup_id($host->userid);
367
            if ($user && $user->show_hosts) {
368
            } else {
369
                $anonymous = true;
370
            }
371
        }
372
    }
373
    echo "<tr><td>ID: $host->id
374
        <br><a href=show_host_detail.php?hostid=$host->id>".tra("Details")."</a>
375
    ";
376
    if (!NO_COMPUTING) {
377
        echo "
378
        | <a href=results.php?hostid=$host->id>".tra("Tasks")."</a>
379
        ";
380
    }
381
    if (!NO_STATS) {
382
        if (!$anonymous) {
383
            echo "
384
                <br><nobr><small>".tra("Cross-project stats:")."</small></nobr><br>".cross_project_links($host);
385
        }
386
    }
387
    echo "
388
        </td>
389
    ";
390
    if ($private) {
391
        echo "<td>$host->domain_name</td>\n";
392
        if ($any_product_name) {
393
            echo "<td>$host->product_name</td>\n";
394
        }
395
        echo "<td>$host->venue</td>\n";
396
    } else {
397
        echo "<td>$i</td>\n";
398
        if ($show_owner) {
399
            if ($anonymous) {
400
                echo "<td>".tra("Anonymous")."</td>\n";
401
            } else {
402
                echo "<td>", user_links($user, BADGE_HEIGHT_MEDIUM), "</td>\n";
0 ignored issues
show
Bug introduced by
The variable $user does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
403
            }
404
        }
405
    }
406
    if ($show_owner) {
407
        // This is used in the "top computers" display
408
        //
409
        if (!NO_STATS) {
410
            printf("
411
                <td align=right>%s</td>
412
                <td align=right>%s</td>",
413
                format_credit($host->expavg_credit),
414
                format_credit_large($host->total_credit)
415
            );
416
        }
417
        printf("
418
            <td>%s</td>
419
            <td>%s</td>
420
            <td>%s</td>
421
            <td>%s <br> %s</td>",
422
            boinc_version($host->serialnum),
423
            cpu_desc($host),
424
            gpu_desc($host->serialnum),
425
            $host->os_name, $host->os_version
426
        );
427
    } else {
428
        // This is used to show the computers of a given user
429
        //
430
        if (!NO_STATS) {
431
            printf("
432
                <td align=right>%s</td>
433
                <td align=right>%s</td>",
434
                format_credit($host->expavg_credit),
435
                format_credit_large($host->total_credit)
436
            );
437
        }
438
        printf("
439
            <td>%s</td>
440
            <td>%s</td>
441
            <td>%s</td>
442
            <td>%s<br><small>%s</small></td>
443
            <td>%s</td>
444
            ",
445
            boinc_version($host->serialnum),
446
            cpu_desc($host),
447
            gpu_desc($host->serialnum),
448
            $host->os_name, $host->os_version,
449
            sched_log_link($host->rpc_time)
450
        );
451
    }
452
453
    echo "</tr>\n";
454
}
455
456
// Logic for deciding whether two host records might actually
457
// be the same machine, based on CPU info
458
//
459
// p_vendor is typically either AuthenticAMD or GenuineIntel.
460
// Over time we've changed the contents of p_model.
461
// Some examples:
462
// Intel(R) Core(TM)2 Duo CPU  E7300  @ 2.66GHz [Family 6 Model 23 Stepping 6]
463
// AMD Athlon(tm) II X2 250 Processor [Family 16 Model 6 Stepping 3]
464
// Intel(R) Xeon(R) CPU X5650 @ 2.67GHz [x86 Family 6 Model 44 Stepping 2]
465
// Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz [Intel64 Family 6 Model 42 Stepping 7]
466
//
467
// in the last 2 cases, let's call x86 and Intel64 the "architecture"
468
//
469
// so, here's the policy:
470
//
471
// if p_ncpus different, return false
472
// if p_vendor different, return false
473
// if both have family/model/stepping info
474
//    if info disagrees, return false
475
//    if both have GHz info, and they disagree, return false
476
//    if both have architecture, and they disagree, return false
477
//    return true
478
// if p_model different, return false
479
// return true
480
//
481
482
// parse p_model to produce the following structure:
483
// x->speed     "3.00GHz" etc. or null
484
// x->arch      "x86" etc. or null
485
// x->info      "Family 6 Model 23 Stepping 6" etc. or null
486
//
487
function parse_model($model) {
488
    $y = explode(" ", $model);
489
    $x = new StdClass;
490
    $x->speed = null;
491
    $x->arch = null;
492
    $x->info = null;
493
    foreach ($y as $z) {
494
        if (strstr($z, "GHz")) $x->speed = $z;
495
        if (strstr($z, "MHz")) $x->speed = $z;
496
    }
497
    $pos1 = strpos($model, '[');
498
    if ($pos1 === false) return $x;
499
    $pos2 = strpos($model, ']');
500
    if ($pos2 === false) return $x;
501
    $a = substr($model, $pos1+1, $pos2-$pos1-1);
502
    $y = explode(" ", $a);
503
    if (count($y) == 0) return $x;
504
    if ($y[0] == "Family") {
505
        $x->info = $a;
506
    } else {
507
        $x->arch = $y[0];
508
        $x->info = substr($a, strlen($y[0])+1);
509
    }
510
    return $x;
511
}
512
513
function cpus_compatible($host1, $host2) {
514
    if ($host1->p_ncpus != $host2->p_ncpus) return false;
515
    if ($host1->p_vendor != $host2->p_vendor) return false;
516
    $x1 = parse_model($host1->p_model);
517
    $x2 = parse_model($host2->p_model);
518
    if ($x1->info && $x2->info) {
519
        if ($x1->info != $x2->info) return false;
520
        if ($x1->speed && $x2->speed) {
521
            if ($x1->speed != $x2->speed) return false;
522
        }
523
        if ($x1->arch && $x2->arch) {
524
            if ($x1->arch != $x2->arch) return false;
525
        }
526
        return true;
527
    }
528
    if ($host1->p_model != $host2->p_model) return false;
529
    return true;
530
}
531
532
// does one host strictly precede the other?
533
//
534
function times_disjoint($host1, $host2) {
535
    if ($host1->rpc_time < $host2->create_time) return true;
536
    if ($host2->rpc_time < $host1->create_time) return true;
537
    return false;
538
}
539
540
function os_compatible($host1, $host2) {
541
    if (strstr($host1->os_name, "Windows") && strstr($host2->os_name, "Windows")) return true;
542
    if (strstr($host1->os_name, "Linux") && strstr($host2->os_name, "Linux")) return true;
543
    if (strstr($host1->os_name, "Darwin") && strstr($host2->os_name, "Darwin")) return true;
544
    if (strstr($host1->os_name, "SunOS") && strstr($host2->os_name, "SunOS")) return true;
545
    if ($host1->os_name == $host2->os_name) return true;
546
    return false;
547
}
548
549
// Return true if it's possible that the two host records
550
// correspond to the same host
551
// NOTE: the cheat-proofing comes from checking
552
// that their time intervals are disjoint.
553
// So the CPU/OS checks don't have to be very strict.
554
//
555
function hosts_compatible($host1, $host2, $show_detail) {
556
    // A host is "new" if it has no credit and no results.
557
    // Skip disjoint-time check if one host or other is new
558
    //
559
    $new1 = !$host1->total_credit && !host_nresults($host1);
560
    $new2 = !$host2->total_credit && !host_nresults($host2);
561
    if (!$new1 && !$new2) {
562
        if (!times_disjoint($host1, $host2)) {
563
            if ($show_detail) {
564
                $c1 = date_str($host1->create_time);
565
                $r1 = date_str($host1->rpc_time);
566
                $c2 = date_str($host2->create_time);
567
                $r2 = date_str($host2->rpc_time);
568
                echo "<br>".tra("Host %1 has overlapping lifetime:", $host2->id)." ($c1 - $r1), ($c2 - $r2)";
569
            }
570
            return false;
571
        }
572
    }
573
    if (!os_compatible($host1, $host2)) {
574
        if ($show_detail) {
575
            echo "<br>".tra("Host %1 has an incompatible OS:", $host2->id)." ($host1->os_name, $host2->os_name)\n";
576
        }
577
        return false;
578
    }
579
    if (!cpus_compatible($host1, $host2)) {
580
        if ($show_detail) {
581
            echo "<br>".tra("Host %1 has an incompatible CPU:", $host2->id)." ($host1->p_vendor $host1->p_model, $host2->p_vendor $host2->p_model)\n";
582
        }
583
        return false;
584
    }
585
    return true;
586
}
587
588
// recompute host's average credit by scanning results.
589
// Could be expensive if lots of results!
590
//
591
function host_update_credit($hostid) {
592
    $total = 0;
593
    $avg = 0;
594
    $avg_time = 0;
595
596
    $results = BoincResult::enum("hostid=$hostid order by received_time");
597
    foreach($results as $result) {
598
        if ($result->granted_credit <= 0) continue;
599
        $total += $result->granted_credit;
600
601
        update_average(
602
            $result->received_time,
603
            $result->sent_time,
604
            $result->granted_credit,
605
            $avg,
606
            $avg_time
607
        );
608
609
        //echo "<br>$avg\n";
610
    }
611
612
    // do a final decay
613
    //
614
    $now = time();
615
    update_average(now, 0, 0, $avg, $avg_time);
616
617
    $host = new BoincHost();
618
    $host->id = hostid;
0 ignored issues
show
Bug introduced by
The property id does not seem to exist in BoincHost.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
619
    $host->update("total_credit=$total, expavg_credit=$avg, expavg_time=$now");
620
}
621
622
// decay a host's average credit
623
//
624 View Code Duplication
function host_decay_credit($host) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
625
    $avg = $host->expavg_credit;
626
    $avg_time = $host->expavg_time;
627
    $now = time(0);
628
    update_average($now, 0, 0, $avg, $avg_time);
629
    $host->update("expavg_credit=$avg, expavg_time=$now");
630
}
631
632
// if the host hasn't received new credit for ndays,
633
// decay its average and return true
634
//
635
function host_inactive_ndays($host, $ndays) {
636
    $diff = time() - $host->expavg_time;
637
    if ($diff > $ndays*86400) {
638
        host_decay_credit($host);
639
        return true;
640
    }
641
    return false;
642
}
643
644
// invariant: old_host.create_time < new_host.create_time
645
//
646
function merge_hosts($old_host, $new_host) {
647
    if ($old_host->id == $new_host->id) {
648
        return tra("same host");
649
    }
650
    if (!hosts_compatible($old_host, $new_host, false)) {
651
        return tra("Can't merge host %1 into %2 - they're incompatible", $old_host->id, $new_host->id);
652
    }
653
654
    echo "<br>".tra("Merging host %1 into host %2", $old_host->id, $new_host->id)."\n";
655
656
    // decay the average credit of both hosts
657
    //
658
    $now = time();
659
    update_average($now, 0, 0, $old_host->expavg_credit, $old_host->expavg_time);
660
    update_average($now, 0, 0, $new_host->expavg_credit, $new_host->expavg_time);
661
662
    // update the database:
663
    // - add credit from old to new host
664
    // - change results to refer to new host
665
    // - put old host in "zombie" state (userid=0, rpc_seqno=new host ID)
666
    //
667
    $total_credit = $old_host->total_credit + $new_host->total_credit;
668
    $recent_credit = $old_host->expavg_credit + $new_host->expavg_credit;
669
    $result = $new_host->update("total_credit=$total_credit, expavg_credit=$recent_credit, expavg_time=$now");
670
    if (!$result) {
671
        return tra("Couldn't update credit of new computer");
672
    }
673
    $result = BoincResult::update_aux("hostid=$new_host->id where hostid=$old_host->id");
674
    if (!$result) {
675
        return tra("Couldn't update results");
676
    }
677
678
    $result = $old_host->update("total_credit=0, expavg_credit=0, userid=0, rpc_seqno=$new_host->id");
679
    if (!$result) {
680
        return tra("Couldn't retire old computer");
681
    }
682
    echo "<br>".tra("Retired old computer %1", $old_host->id)."\n";
683
    return 0;
684
}
685
686
//////////////// helper functions for hosts_user.php ////////////////
687
688
function link_url($sort, $rev, $show_all) {
689
    global $userid;
690
    $x = $userid ? "&userid=$userid":"";
691
    return "hosts_user.php?sort=$sort&rev=$rev&show_all=$show_all$x";
692
}
693
694
function link_url_rev($actual_sort, $sort, $rev, $show_all) {
695
    if ($actual_sort == $sort) {
696
        $rev = 1 - $rev;
697
    }
698
    return link_url($sort, $rev, $show_all);
699
}
700
701
function more_or_less($sort, $rev, $show_all) {
702
    echo "<p>";
703
    if ($show_all) {
704
        $url = link_url($sort, $rev, 0);
705
        echo tra("Show:")." ".tra("All computers")." &middot; <a href=$url>".tra("Only computers active in past 30 days")."</a>";
706
    } else {
707
        $url = link_url($sort, $rev, 1);
708
        echo tra("Show:")." <a href=$url>".tra("All computers")."</a> &middot; ".tra("Only computers active in past 30 days");
709
    }
710
    echo "<p>";
711
}
712
713
function user_host_table_start(
714
    $private, $sort, $rev, $show_all, $any_product_name
715
) {
716
    start_table('table-striped');
717
    $x = array();
718
    $a = array();
719
720
    $url = link_url_rev($sort, "id", $rev, $show_all);
721
    $x[] = "<a href=$url>".tra("Computer ID")."</a>";
722
    $a[] = '';
723
724
    if ($private) {
725
        $url = link_url_rev($sort, "name", $rev, $show_all);
726
        $x[] = "<a href=$url>".tra("Name")."</a>";
727
        $a[] = null;
728
        $url = link_url_rev($sort, "venue", $rev, $show_all);
729
        if ($any_product_name) {
730
            $x[] = tra("Model");
731
            $a[] = null;
732
        }
733
        $x[] = "<a href=$url>".tra("Location")."</a>";
734
        $a[] = null;
735
    } else {
736
        $x[] = tra("Rank");
737
        $a[] = null;
738
    }
739
    if (!NO_STATS) {
740
        $url = link_url_rev($sort, "expavg_credit", $rev, $show_all);
741
        $x[] = "<a href=$url>".tra("Avg. credit")."</a>";
742
        $a[] = ALIGN_RIGHT;
743
        $url = link_url_rev($sort, "total_credit", $rev, $show_all);
744
        $x[] = "<a href=$url>".tra("Total credit")."</a>";
745
        $a[] = ALIGN_RIGHT;
746
    }
747
    $x[] = tra("BOINC<br>version");
748
    $a[] = null;
749
    $url = link_url_rev($sort, "cpu", $rev, $show_all);
750
    $x[] = "<a href=$url>".tra("CPU")."</a>";
751
    $a[] = null;
752
    $x[] = tra("GPU");
753
    $a[] = null;
754
    $url = link_url_rev($sort, "os", $rev, $show_all);
755
    $x[] = "<a href=$url>".tra("Operating System")."</a>";
756
    $a[] = null;
757
    $url = link_url_rev($sort, "rpc_time", $rev, $show_all);
758
    $x[] = "<a href=$url>".tra("Last contact")."</a>";
759
    $a[] = null;
760
    row_heading_array($x, $a, "bg-default");
761
}
762
763
function show_user_hosts($userid, $private, $show_all, $sort, $rev) {
764
    $desc = false;  // whether the sort order's default is decreasing
765
    switch ($sort) {
766
    case "total_credit": $sort_clause = "total_credit"; $desc = true; break;
767
    case "expavg_credit": $sort_clause = "expavg_credit"; $desc = true; break;
768
    case "name": $sort_clause = "domain_name"; break;
769
    case "id": $sort_clause = "id"; break;
770
    case "cpu": $sort_clause = "p_vendor"; break;
771
    case "gpu": $sort_clause = "serialnum"; break;
772
    case "os": $sort_clause = "os_name"; break;
773
    case "venue": $sort_clause = "venue"; break;
774
    default:
775
        // default value -- sort by RPC time
776
        $sort = "rpc_time";
777
        $sort_clause = "rpc_time"; 
778
        $desc = true;
779
    }
780
781
    if ($rev != $desc) {
782
        $sort_clause .= " desc";
783
    }
784
    more_or_less($sort, $rev, $show_all);
785
786
    $now = time();
787
    $old_hosts=0;
788
    $i = 1;
789
    $hosts = BoincHost::enum("userid=$userid order by $sort_clause");
790
    $any_product_name = false;
791
    foreach ($hosts as $host) {
792
        if ($host->product_name) {
793
            $any_product_name = true;
794
            break;
795
        }
796
    }
797
    user_host_table_start($private, $sort, $rev, $show_all, $any_product_name);
798
    foreach ($hosts as $host) {
799
        $is_old=false;
800
        if (($now - $host->rpc_time) > 30*86400) {
801
            $is_old=true;
802
            $old_hosts++;
803
        }
804
        if (!$show_all && $is_old) continue;
805
        show_host_row($host, $i, $private, false, $any_product_name);
806
        $i++;
807
    }
808
    end_table();
809
810
    if ($old_hosts>0) {
811
        more_or_less($sort, $rev, $show_all);
812
    }
813
814
    if ($private) {
815
        echo "
816
            <a href=merge_by_name.php>".tra("Merge computers by name")."</a>
817
        ";
818
    }
819
}
820
821
// remove user-specific info from a user's hosts
822
//
823
function anonymize_hosts($user) {
824
    $hosts = BoincHost::enum("userid=$user->id");
825
    foreach ($hosts as $h) {
826
        $h->update("domain_name='deleted', last_ip_addr=''");
827
    }
828
}
829
830
$cvs_version_tracker[]="\$Id$";  //Generated automatically - do not edit
831
832
?>
833