~ubuntu-branches/ubuntu/precise/boinc/precise

« back to all changes in this revision

Viewing changes to sched/server_types.cpp

Tags: 6.12.8+dfsg-1
* New upstream release.
* Simplified debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// This file is part of BOINC.
2
 
// http://boinc.berkeley.edu
3
 
// Copyright (C) 2008 University of California
4
 
//
5
 
// BOINC is free software; you can redistribute it and/or modify it
6
 
// under the terms of the GNU Lesser General Public License
7
 
// as published by the Free Software Foundation,
8
 
// either version 3 of the License, or (at your option) any later version.
9
 
//
10
 
// BOINC is distributed in the hope that it will be useful,
11
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 
// See the GNU Lesser General Public License for more details.
14
 
//
15
 
// You should have received a copy of the GNU Lesser General Public License
16
 
// along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
17
 
 
18
 
#include "config.h"
19
 
#include <cassert>
20
 
#include <vector>
21
 
#include <string>
22
 
#include <cstring>
23
 
using namespace std;
24
 
 
25
 
#include "parse.h"
26
 
#include "error_numbers.h"
27
 
#include "str_util.h"
28
 
#include "util.h"
29
 
#include "main.h"
30
 
#include "sched_util.h"
31
 
#include "sched_msgs.h"
32
 
#include "time_stats_log.h"
33
 
#include "server_types.h"
34
 
 
35
 
#ifdef _USING_FCGI_
36
 
#include "boinc_fcgi.h"
37
 
#endif
38
 
 
39
 
// remove (by truncating) any quotes from the given string.
40
 
// This is for things (e.g. authenticator) that will be used in
41
 
// a SQL query, to prevent SQL injection attacks
42
 
//
43
 
void remove_quotes(char* p) {
44
 
    int i, n=strlen(p);
45
 
    for (i=0; i<n; i++) {
46
 
        if (p[i]=='\'' || p[i]=='"') {
47
 
            p[i] = 0;
48
 
            return;
49
 
        }
50
 
    }
51
 
}
52
 
 
53
 
int CLIENT_APP_VERSION::parse(FILE* f) {
54
 
    char buf[256];
55
 
 
56
 
    while (fgets(buf, sizeof(buf), f)) {
57
 
        if (match_tag(buf, "</app_version>")) return 0;
58
 
        if (parse_str(buf, "<app_name>", app_name, 256)) continue;
59
 
        if (parse_int(buf, "<version_num>", version_num)) continue;
60
 
    }
61
 
    return ERR_XML_PARSE;
62
 
}
63
 
 
64
 
int FILE_INFO::parse(FILE* f) {
65
 
    char buf[256];
66
 
 
67
 
    memset(this, 0, sizeof(FILE_INFO));
68
 
    while (fgets(buf, sizeof(buf), f)) {
69
 
        if (match_tag(buf, "</file_info>")) {
70
 
            if (!strlen(name)) return ERR_XML_PARSE;
71
 
            return 0;
72
 
        }
73
 
        if (parse_str(buf, "<name>", name, 256)) continue;
74
 
    }
75
 
    return ERR_XML_PARSE;
76
 
}
77
 
 
78
 
int OTHER_RESULT::parse(FILE* f) {
79
 
    char buf[256];
80
 
 
81
 
    name = "";
82
 
    while (fgets(buf, sizeof(buf), f)) {
83
 
        if (match_tag(buf, "</other_result>")) {
84
 
            if (name=="") return ERR_XML_PARSE;
85
 
            return 0;
86
 
        }
87
 
        if (parse_str(buf, "<name>", name)) continue;
88
 
    }
89
 
    return ERR_XML_PARSE;
90
 
}
91
 
 
92
 
int IP_RESULT::parse(FILE* f) {
93
 
    char buf[256];
94
 
 
95
 
    report_deadline = 0;
96
 
    cpu_time_remaining = 0;
97
 
    strcpy(name, "");
98
 
    while (fgets(buf, sizeof(buf), f)) {
99
 
        if (match_tag(buf, "</ip_result>")) return 0;
100
 
        if (parse_str(buf, "<name>", name, sizeof(name))) continue;
101
 
        if (parse_double(buf, "<report_deadline>", report_deadline)) continue;
102
 
        if (parse_double(buf, "<cpu_time_remaining>", cpu_time_remaining)) continue;
103
 
    }
104
 
    return ERR_XML_PARSE;
105
 
}
106
 
 
107
 
int CLIENT_PLATFORM::parse(FILE* fin) {
108
 
    char buf[256];
109
 
    strcpy(name, "");
110
 
    while (fgets(buf, sizeof(buf), fin)) {
111
 
        if (match_tag(buf, "</alt_platform>")) return 0;
112
 
        if (parse_str(buf, "<name>", name, sizeof(name))) continue;
113
 
    }
114
 
    return ERR_XML_PARSE;
115
 
}
116
 
 
117
 
 
118
 
void WORK_REQ::insert_no_work_message(USER_MESSAGE& um) {
119
 
    bool found = false;
120
 
    for (unsigned int i=0; i<no_work_messages.size(); i++) {
121
 
        if (!strcmp(um.message.c_str(), no_work_messages.at(i).message.c_str())){
122
 
            found = true;
123
 
            break;
124
 
        }
125
 
    }
126
 
    if (!found) no_work_messages.push_back(um);
127
 
}
128
 
 
129
 
 
130
 
SCHEDULER_REQUEST::SCHEDULER_REQUEST() {
131
 
}
132
 
 
133
 
SCHEDULER_REQUEST::~SCHEDULER_REQUEST() {
134
 
}
135
 
 
136
 
// return an error message or NULL
137
 
//
138
 
const char* SCHEDULER_REQUEST::parse(FILE* fin) {
139
 
    char buf[256];
140
 
    RESULT result;
141
 
    int retval;
142
 
 
143
 
    strcpy(authenticator, "");
144
 
    strcpy(platform.name, "");
145
 
    strcpy(cross_project_id, "");
146
 
    hostid = 0;
147
 
    core_client_major_version = 0;
148
 
    core_client_minor_version = 0;
149
 
    core_client_release = 0;
150
 
    rpc_seqno = 0;
151
 
    work_req_seconds = 0;
152
 
    resource_share_fraction = 1.0;
153
 
    rrs_fraction = 1.0;
154
 
    prrs_fraction = 1.0;
155
 
    estimated_delay = 0;
156
 
    strcpy(global_prefs_xml, "");
157
 
    strcpy(working_global_prefs_xml, "");
158
 
    strcpy(code_sign_key, "");
159
 
    anonymous_platform = false;
160
 
    memset(&global_prefs, 0, sizeof(global_prefs));
161
 
    memset(&host, 0, sizeof(host));
162
 
    have_other_results_list = false;
163
 
    have_ip_results_list = false;
164
 
    have_time_stats_log = false;
165
 
    client_cap_plan_class = false;
166
 
    sandbox = -1;
167
 
 
168
 
    fgets(buf, sizeof(buf), fin);
169
 
    if (!match_tag(buf, "<scheduler_request>")) return "no start tag";
170
 
    while (fgets(buf, sizeof(buf), fin)) {
171
 
        // If a line is too long, ignore it.
172
 
        // This can happen e.g. if the client has bad global_prefs.xml
173
 
        // This won't be necessary if we rewrite this using XML_PARSER
174
 
        //
175
 
        if (!strchr(buf, '\n')) {
176
 
            while (fgets(buf, sizeof(buf), fin)) {
177
 
                if (strchr(buf, '\n')) break;
178
 
            }
179
 
            continue;
180
 
        }
181
 
 
182
 
        if (match_tag(buf, "</scheduler_request>")) {
183
 
            core_client_version = 100*core_client_major_version + core_client_minor_version;
184
 
            return NULL;
185
 
        }
186
 
        if (parse_str(buf, "<authenticator>", authenticator, sizeof(authenticator))) {
187
 
            remove_quotes(authenticator);
188
 
            continue;
189
 
        }
190
 
        if (parse_str(buf, "<cross_project_id>", cross_project_id, sizeof(cross_project_id))) continue;
191
 
        if (parse_int(buf, "<hostid>", hostid)) continue;
192
 
        if (parse_int(buf, "<rpc_seqno>", rpc_seqno)) continue;
193
 
        if (parse_str(buf, "<platform_name>", platform.name, sizeof(platform.name))) continue;
194
 
        if (match_tag(buf, "<alt_platform>")) {
195
 
            CLIENT_PLATFORM cp;
196
 
            retval = cp.parse(fin);
197
 
            if (!retval) {
198
 
                alt_platforms.push_back(cp);
199
 
            }
200
 
            continue;
201
 
        }
202
 
        if (match_tag(buf, "<app_versions>")) {
203
 
            while (fgets(buf, sizeof(buf), fin)) {
204
 
                if (match_tag(buf, "</app_versions>")) break;
205
 
                if (match_tag(buf, "<app_version>")) {
206
 
                    CLIENT_APP_VERSION cav;
207
 
                    cav.parse(fin);
208
 
                    client_app_versions.push_back(cav);
209
 
                }
210
 
            }
211
 
            continue;
212
 
        }
213
 
        if (parse_int(buf, "<core_client_major_version>", core_client_major_version)) continue;
214
 
        if (parse_int(buf, "<core_client_minor_version>", core_client_minor_version)) continue;
215
 
        if (parse_int(buf, "<core_client_release>", core_client_release)) continue;
216
 
        if (parse_double(buf, "<work_req_seconds>", work_req_seconds)) continue;
217
 
        if (parse_double(buf, "<resource_share_fraction>", resource_share_fraction)) continue;
218
 
        if (parse_double(buf, "<rrs_fraction>", rrs_fraction)) continue;
219
 
        if (parse_double(buf, "<prrs_fraction>", prrs_fraction)) continue;
220
 
        if (parse_double(buf, "<estimated_delay>", estimated_delay)) continue;
221
 
        if (parse_double(buf, "<duration_correction_factor>", host.duration_correction_factor)) continue;
222
 
        if (match_tag(buf, "<global_preferences>")) {
223
 
            strcpy(global_prefs_xml, "<global_preferences>\n");
224
 
            while (fgets(buf, sizeof(buf), fin)) {
225
 
                if (strstr(buf, "</global_preferences>")) break;
226
 
                safe_strcat(global_prefs_xml, buf);
227
 
            }
228
 
            safe_strcat(global_prefs_xml, "</global_preferences>\n");
229
 
            continue;
230
 
        }
231
 
        if (match_tag(buf, "<working_global_preferences>")) {
232
 
            while (fgets(buf, sizeof(buf), fin)) {
233
 
                if (strstr(buf, "</working_global_preferences>")) break;
234
 
                safe_strcat(working_global_prefs_xml, buf);
235
 
            }
236
 
            continue;
237
 
        }
238
 
        if (parse_str(buf, "<global_prefs_source_email_hash>", global_prefs_source_email_hash, sizeof(global_prefs_source_email_hash))) continue;
239
 
        if (match_tag(buf, "<host_info>")) {
240
 
            host.parse(fin);
241
 
            continue;
242
 
        }
243
 
        if (match_tag(buf, "<time_stats>")) {
244
 
            host.parse_time_stats(fin);
245
 
            continue;
246
 
        }
247
 
        if (match_tag(buf, "<time_stats_log>")) {
248
 
            handle_time_stats_log(fin);
249
 
            have_time_stats_log = true;
250
 
            continue;
251
 
        }
252
 
        if (match_tag(buf, "<net_stats>")) {
253
 
            host.parse_net_stats(fin);
254
 
            continue;
255
 
        }
256
 
        if (match_tag(buf, "<disk_usage>")) {
257
 
            host.parse_disk_usage(fin);
258
 
            continue;
259
 
        }
260
 
        if (match_tag(buf, "<result>")) {
261
 
            result.parse_from_client(fin);
262
 
            results.push_back(result);
263
 
            continue;
264
 
        }
265
 
        if (match_tag(buf, "<code_sign_key>")) {
266
 
            copy_element_contents(fin, "</code_sign_key>", code_sign_key, sizeof(code_sign_key));
267
 
            continue;
268
 
        }
269
 
        if (match_tag(buf, "<msg_from_host>")) {
270
 
            MSG_FROM_HOST_DESC md;
271
 
            retval = md.parse(fin);
272
 
            if (!retval) {
273
 
                msgs_from_host.push_back(md);
274
 
            }
275
 
            continue;
276
 
        }
277
 
        if (match_tag(buf, "<file_info>")) {
278
 
            FILE_INFO fi;
279
 
            retval = fi.parse(fin);
280
 
            if (!retval) {
281
 
                file_infos.push_back(fi);
282
 
            }
283
 
            continue;
284
 
        }
285
 
        if (match_tag(buf, "<host_venue>")) {
286
 
            continue;
287
 
        }
288
 
        if (match_tag(buf, "<other_results>")) {
289
 
            have_other_results_list = true;
290
 
            while (fgets(buf, sizeof(buf), fin)) {
291
 
                if (match_tag(buf, "</other_results>")) break;
292
 
                if (match_tag(buf, "<other_result>")) {
293
 
                    OTHER_RESULT o_r;
294
 
                    retval = o_r.parse(fin);
295
 
                    if (!retval) {
296
 
                        other_results.push_back(o_r);
297
 
                    }
298
 
                }
299
 
            }
300
 
            continue;
301
 
        }
302
 
        if (match_tag(buf, "<in_progress_results>")) {
303
 
            have_ip_results_list = true;
304
 
            int i = 0;
305
 
            double now = time(0);
306
 
            while (fgets(buf, sizeof(buf), fin)) {
307
 
                if (match_tag(buf, "</in_progress_results>")) break;
308
 
                if (match_tag(buf, "<ip_result>")) {
309
 
                    IP_RESULT ir;
310
 
                    retval = ir.parse(fin);
311
 
                    if (!retval) {
312
 
                        if (!strlen(ir.name)) {
313
 
                            sprintf(ir.name, "ip%d", i++);
314
 
                        }
315
 
                        ir.report_deadline -= now;
316
 
                        ip_results.push_back(ir);
317
 
                    }
318
 
                }
319
 
            }
320
 
            continue;
321
 
        }
322
 
        if (match_tag(buf, "coprocs")) {
323
 
            coprocs.parse(fin);
324
 
            continue;
325
 
        }
326
 
        if (parse_bool(buf, "client_cap_plan_class", client_cap_plan_class)) continue;
327
 
        if (parse_int(buf, "<sandbox>", sandbox)) continue;
328
 
 
329
 
        if (match_tag(buf, "<active_task_set>")) continue;
330
 
        if (match_tag(buf, "<app>")) continue;
331
 
        if (match_tag(buf, "<app_version>")) continue;
332
 
        if (match_tag(buf, "<duration_variability>")) continue;
333
 
        if (match_tag(buf, "<new_version_check_time>")) continue;
334
 
        if (match_tag(buf, "<newer_version>")) continue;
335
 
        if (match_tag(buf, "<project>")) continue;
336
 
        if (match_tag(buf, "<project_files>")) continue;
337
 
        if (match_tag(buf, "<proxy_info>")) continue;
338
 
        if (match_tag(buf, "<user_network_request>")) continue;
339
 
        if (match_tag(buf, "<user_run_request>")) continue;
340
 
        if (match_tag(buf, "<master_url>")) continue;
341
 
        if (match_tag(buf, "<project_name>")) continue;
342
 
        if (match_tag(buf, "<user_name>")) continue;
343
 
        if (match_tag(buf, "<team_name>")) continue;
344
 
        if (match_tag(buf, "<email_hash>")) continue;
345
 
        if (match_tag(buf, "<user_total_credit>")) continue;
346
 
        if (match_tag(buf, "<user_expavg_credit>")) continue;
347
 
        if (match_tag(buf, "<user_create_time>")) continue;
348
 
        if (match_tag(buf, "<host_total_credit>")) continue;
349
 
        if (match_tag(buf, "<host_expavg_credit>")) continue;
350
 
        if (match_tag(buf, "<host_create_time>")) continue;
351
 
        if (match_tag(buf, "<nrpc_failures>")) continue;
352
 
        if (match_tag(buf, "<master_fetch_failures>")) continue;
353
 
        if (match_tag(buf, "<min_rpc_time>")) continue;
354
 
        if (match_tag(buf, "<short_term_debt>")) continue;
355
 
        if (match_tag(buf, "<long_term_debt>")) continue;
356
 
        if (match_tag(buf, "<resource_share>")) continue;
357
 
        if (match_tag(buf, "<scheduler_url>")) continue;
358
 
        if (match_tag(buf, "</project>")) continue;
359
 
        if (match_tag(buf, "<?xml")) continue;
360
 
        strip_whitespace(buf);
361
 
        if (!strlen(buf)) continue;
362
 
 
363
 
        log_messages.printf(MSG_NORMAL,
364
 
            "SCHEDULER_REQUEST::parse(): unrecognized: %s\n", buf
365
 
        );
366
 
        MIOFILE mf;
367
 
        mf.init_file(fin);
368
 
        retval = skip_unrecognized(buf, mf);
369
 
        if (retval) return "unterminated unrecognized XML";
370
 
    }
371
 
    return "no end tag";
372
 
}
373
 
 
374
 
int SCHEDULER_REQUEST::write(FILE* fout) {
375
 
    unsigned int i;
376
 
 
377
 
    fprintf(fout,
378
 
        "<scheduler_request>\n"
379
 
        "  <authenticator>%s</authentiicator>\n"
380
 
        "  <platform_name>%s</platform_name>\n"
381
 
        "  <cross_project_id>%s</cross_project_id>\n"
382
 
        "  <hostid>%d</hostid>\n"
383
 
        "  <core_client_major_version>%d</core_client_major_version>\n"
384
 
        "  <core_client_minor_version>%d</core_client_minor_version>\n"
385
 
        "  <core_client_release>%d</core_client_release>\n"
386
 
        "  <rpc_seqno>%d</rpc_seqno>\n"
387
 
        "  <work_req_seconds>%.15f</work_req_seconds>\n"
388
 
        "  <resource_share_fraction>%.15f</resource_share_fraction>\n"
389
 
        "  <rrs_fraction>%.15f</rrs_fraction>\n"
390
 
        "  <prrs_fraction>%.15f</prrs_fraction>\n"
391
 
        "  <estimated_delay>%.15f</estimated_delay>\n"
392
 
        "  <code_sign_key>%s</code_sign_key>\n"
393
 
        "  <anonymous_platform>%s</anonymous_platform>\n",
394
 
        authenticator,
395
 
        platform.name,
396
 
        cross_project_id,
397
 
        hostid,
398
 
        core_client_major_version,
399
 
        core_client_minor_version,
400
 
        core_client_release,
401
 
        rpc_seqno,
402
 
        work_req_seconds,
403
 
        resource_share_fraction,
404
 
        rrs_fraction,
405
 
        prrs_fraction,
406
 
        estimated_delay,
407
 
        code_sign_key,
408
 
        anonymous_platform?"true":"false"
409
 
    );
410
 
 
411
 
    for (i=0; i<client_app_versions.size(); i++) {
412
 
        fprintf(fout,
413
 
            "  <app_version>\n"
414
 
            "    <app_name>%s</app_name>\n"
415
 
            "    <version_num>%d</version_num>\n"
416
 
            "  </app_version>\n",
417
 
            client_app_versions[i].app_name,
418
 
            client_app_versions[i].version_num
419
 
        );
420
 
    }
421
 
 
422
 
    fprintf(fout,
423
 
        "  <global_prefs_xml>\n"
424
 
        "    %s"
425
 
        "  </globals_prefs_xml>\n",
426
 
        global_prefs_xml
427
 
    );
428
 
  
429
 
    fprintf(fout,
430
 
        "  <global_prefs_source_email_hash>%s</global_prefs_source_email_hash>\n",
431
 
        global_prefs_source_email_hash
432
 
    );
433
 
  
434
 
    fprintf(fout,
435
 
        "  <host>\n"
436
 
        "    <id>%d</id>\n"
437
 
        "    <rpc_time>%d</rpc_time>\n"
438
 
        "    <timezone>%d</timezone>\n"
439
 
        "    <d_total>%.15f</d_total>\n"
440
 
        "    <d_free>%.15f</d_free>\n"
441
 
        "    <d_boinc_used_total>%.15f</d_boinc_used_total>\n"
442
 
        "    <d_boinc_used_project>%.15f</d_boinc_used_project>\n"
443
 
        "    <d_boinc_max>%.15f</d_boinc_max>\n",
444
 
        host.id,
445
 
        host.rpc_time,
446
 
        host.timezone,
447
 
        host.d_total,
448
 
        host.d_free,
449
 
        host.d_boinc_used_total,
450
 
        host.d_boinc_used_project,
451
 
        host.d_boinc_max
452
 
    );
453
 
 
454
 
    for (i=0; i<results.size(); i++) {
455
 
        fprintf(fout,
456
 
            "  <result>\n"
457
 
            "    <name>%s</name>\n"
458
 
            "    <client_state>%d</client_state>\n"
459
 
            "    <cpu_time>%.15f</cpu_time>\n"
460
 
            "    <exit_status>%d</exit_status>\n"
461
 
            "    <app_version_num>%d</app_version_num>\n"
462
 
            "  </result>\n",
463
 
            results[i].name,
464
 
            results[i].client_state,
465
 
            results[i].cpu_time,
466
 
            results[i].exit_status,
467
 
            results[i].app_version_num
468
 
        );
469
 
    }
470
 
  
471
 
    for (i=0; i<msgs_from_host.size(); i++) {
472
 
        fprintf(fout,
473
 
            "  <msg_from_host>\n"
474
 
            "    <variety>%s</variety>\n"
475
 
            "    <msg_text>%s</msg_text>\n"
476
 
            "  </msg_from_host>\n",
477
 
            msgs_from_host[i].variety,
478
 
            msgs_from_host[i].msg_text.c_str()
479
 
        );
480
 
    }
481
 
 
482
 
    for (i=0; i<file_infos.size(); i++) {
483
 
        fprintf(fout,
484
 
            "  <file_info>\n"
485
 
            "    <name>%s</name>\n"
486
 
            "  </file_info>\n",
487
 
            file_infos[i].name
488
 
        );
489
 
        fprintf(fout, "</scheduler_request>\n");
490
 
    }
491
 
    return 0;
492
 
}
493
 
 
494
 
int MSG_FROM_HOST_DESC::parse(FILE* fin) {
495
 
    char buf[256];
496
 
 
497
 
    msg_text = "";
498
 
    while (fgets(buf, sizeof(buf), fin)) {
499
 
        if (match_tag(buf, "</msg_from_host>")) return 0;
500
 
        if (parse_str(buf, "<variety>", variety, sizeof(variety))) continue;
501
 
        msg_text += buf;
502
 
    }
503
 
    return ERR_XML_PARSE;
504
 
}
505
 
 
506
 
SCHEDULER_REPLY::SCHEDULER_REPLY() {
507
 
    memset(&wreq, 0, sizeof(wreq));
508
 
    memset(&disk_limits, 0, sizeof(disk_limits));
509
 
    request_delay = 0;
510
 
    hostid = 0;
511
 
    send_global_prefs = false;
512
 
    strcpy(code_sign_key, "");
513
 
    strcpy(code_sign_key_signature, "");
514
 
    memset(&user, 0, sizeof(user));
515
 
    memset(&host, 0, sizeof(host));
516
 
    memset(&team, 0, sizeof(team));
517
 
    nucleus_only = false;
518
 
    project_is_down = false;
519
 
    send_msg_ack = false;
520
 
    strcpy(email_hash, "");
521
 
}
522
 
 
523
 
SCHEDULER_REPLY::~SCHEDULER_REPLY() {
524
 
}
525
 
 
526
 
int SCHEDULER_REPLY::write(FILE* fout, SCHEDULER_REQUEST& sreq) {
527
 
    unsigned int i;
528
 
    char buf[BLOB_SIZE];
529
 
 
530
 
    // Note: at one point we had
531
 
    // "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
532
 
    // after the Content-type (to make it legit XML),
533
 
    // but this broke 4.19 clients
534
 
    //
535
 
    fprintf(fout,
536
 
        "Content-type: text/xml\n\n"
537
 
        "<scheduler_reply>\n"
538
 
        "<scheduler_version>%d</scheduler_version>\n",
539
 
        BOINC_MAJOR_VERSION*100+BOINC_MINOR_VERSION
540
 
    );
541
 
    if (strlen(config.master_url)) {
542
 
        fprintf(fout,
543
 
            "<master_url>%s</master_url>\n",
544
 
            config.master_url
545
 
        );
546
 
    }
547
 
    if (config.ended) {
548
 
        fprintf(fout, "   <ended>1</ended>\n");
549
 
    }
550
 
 
551
 
    // if the scheduler has requested a delay OR the sysadmin has configured
552
 
    // the scheduler with a minimum time between RPCs, send a delay request.
553
 
    // Make it 1% larger than the min required to take care of time skew.
554
 
    // If this is less than one second bigger, bump up by one sec.
555
 
    //
556
 
    if (request_delay || config.min_sendwork_interval) {
557
 
        double min_delay_needed = 1.01*config.min_sendwork_interval;
558
 
        if (min_delay_needed < config.min_sendwork_interval+1) {
559
 
            min_delay_needed = config.min_sendwork_interval+1;
560
 
        }
561
 
        if (request_delay<min_delay_needed) {
562
 
            request_delay=min_delay_needed; 
563
 
        }
564
 
        fprintf(fout, "<request_delay>%f</request_delay>\n", request_delay);
565
 
    }
566
 
    log_messages.printf(MSG_NORMAL,
567
 
        "Sending reply to [HOST#%d]: %d results, delay req %f [scheduler ran %f seconds]\n",
568
 
        host.id, wreq.nresults, request_delay, elapsed_wallclock_time() 
569
 
    );
570
 
 
571
 
    if (sreq.core_client_version <= 419) {
572
 
        std::string msg;
573
 
        std::string pri = "low";
574
 
        for (i=0; i<messages.size(); i++) {
575
 
            USER_MESSAGE& um = messages[i];
576
 
            msg += um.message + std::string(" ");
577
 
            if (um.priority == "high") {
578
 
                pri = "high";
579
 
            }
580
 
        }
581
 
        if (messages.size()>0) {
582
 
            // any newlines will break message printing under 4.19 and under!
583
 
            // replace them with spaces.
584
 
            //
585
 
            while (1) {
586
 
                string::size_type pos = msg.find("\n", 0);
587
 
                if (pos == string::npos) break;
588
 
                msg.replace(pos, 1, " ");
589
 
            }
590
 
            fprintf(fout,
591
 
                "<message priority=\"%s\">%s</message>\n",
592
 
                pri.c_str(), msg.c_str()
593
 
            );
594
 
        }
595
 
    } else {
596
 
        for (i=0; i<messages.size(); i++) {
597
 
            USER_MESSAGE& um = messages[i];
598
 
            fprintf(fout,
599
 
                "<message priority=\"%s\">%s</message>\n",
600
 
                um.priority.c_str(),
601
 
                um.message.c_str()
602
 
            );
603
 
        }
604
 
    }
605
 
    fprintf(fout,
606
 
        "<project_name>%s</project_name>\n",
607
 
        config.long_name
608
 
    );
609
 
 
610
 
    if (config.request_time_stats_log) {
611
 
        if (!have_time_stats_log(*this)) {
612
 
            fprintf(fout, "<send_time_stats_log>1</send_time_stats_log>\n");
613
 
        }
614
 
    }
615
 
 
616
 
    if (project_is_down) {
617
 
        fprintf(fout,"<project_is_down/>\n");
618
 
        goto end;
619
 
    }
620
 
 
621
 
    if (nucleus_only) goto end;
622
 
 
623
 
    if (strlen(config.symstore)) {
624
 
        fprintf(fout, "<symstore>%s</symstore>\n", config.symstore);
625
 
    }
626
 
    if (config.next_rpc_delay) {
627
 
        fprintf(fout, "<next_rpc_delay>%f</next_rpc_delay>\n", config.next_rpc_delay);
628
 
    }
629
 
    if (user.id) {
630
 
        xml_escape(user.name, buf, sizeof(buf));
631
 
        fprintf(fout,
632
 
            "<user_name>%s</user_name>\n"
633
 
            "<user_total_credit>%f</user_total_credit>\n"
634
 
            "<user_expavg_credit>%f</user_expavg_credit>\n"
635
 
            "<user_create_time>%d</user_create_time>\n",
636
 
            buf,
637
 
            user.total_credit,
638
 
            user.expavg_credit,
639
 
            user.create_time
640
 
        );
641
 
        // be paranoid about the following to avoid sending null
642
 
        //
643
 
        if (strlen(email_hash)) {
644
 
            fprintf(fout,
645
 
                "<email_hash>%s</email_hash>\n",
646
 
                email_hash
647
 
            );
648
 
        }
649
 
        if (strlen(user.cross_project_id)) {
650
 
            fprintf(fout,
651
 
                "<cross_project_id>%s</cross_project_id>\n",
652
 
                user.cross_project_id
653
 
            );
654
 
        }
655
 
 
656
 
        if (send_global_prefs) {
657
 
            fputs(user.global_prefs, fout);
658
 
            fputs("\n", fout);
659
 
        }
660
 
 
661
 
        // always send project prefs
662
 
        //
663
 
        fputs(user.project_prefs, fout);
664
 
        fputs("\n", fout);
665
 
 
666
 
    }
667
 
    if (hostid) {
668
 
        fprintf(fout,
669
 
            "<hostid>%d</hostid>\n",
670
 
            hostid
671
 
        );
672
 
    }
673
 
    fprintf(fout,
674
 
        "<host_total_credit>%f</host_total_credit>\n"
675
 
        "<host_expavg_credit>%f</host_expavg_credit>\n"
676
 
        "<host_venue>%s</host_venue>\n"
677
 
        "<host_create_time>%d</host_create_time>\n",
678
 
        host.total_credit,
679
 
        host.expavg_credit,
680
 
        host.venue,
681
 
        host.create_time
682
 
    );
683
 
 
684
 
    // might want to send team credit too.
685
 
    //
686
 
    if (team.id) {
687
 
        xml_escape(team.name, buf, sizeof(buf));
688
 
        fprintf(fout,
689
 
            "<team_name>%s</team_name>\n",
690
 
            buf
691
 
        );
692
 
    } else {
693
 
        fprintf(fout,
694
 
            "<team_name></team_name>\n"
695
 
        );
696
 
    }
697
 
 
698
 
    // acknowledge results
699
 
    //
700
 
    for (i=0; i<result_acks.size(); i++) {
701
 
        fprintf(fout,
702
 
            "<result_ack>\n"
703
 
            "    <name>%s</name>\n"
704
 
            "</result_ack>\n",
705
 
            result_acks[i].c_str()
706
 
        );
707
 
    }
708
 
 
709
 
    // abort results
710
 
    //
711
 
    for (i=0; i<result_aborts.size(); i++) {
712
 
        fprintf(fout,
713
 
            "<result_abort>\n"
714
 
            "    <name>%s</name>\n"
715
 
            "</result_abort>\n",
716
 
            result_aborts[i].c_str()
717
 
        );
718
 
    }
719
 
 
720
 
    // abort results not started
721
 
    //
722
 
    for (i=0; i<result_abort_if_not_starteds.size(); i++) {
723
 
        fprintf(fout,
724
 
            "<result_abort_if_not_started>\n"
725
 
            "    <name>%s</name>\n"
726
 
            "</result_abort_if_not_started>\n",
727
 
            result_abort_if_not_starteds[i].c_str()
728
 
        );
729
 
    }
730
 
 
731
 
    for (i=0; i<apps.size(); i++) {
732
 
        apps[i].write(fout);
733
 
    }
734
 
 
735
 
    for (i=0; i<app_versions.size(); i++) {
736
 
        app_versions[i].write(fout);
737
 
    }
738
 
 
739
 
    for (i=0; i<wus.size(); i++) {
740
 
        fputs(wus[i].xml_doc, fout);
741
 
    }
742
 
 
743
 
    for (i=0; i<results.size(); i++) {
744
 
        results[i].write_to_client(fout);
745
 
    }
746
 
 
747
 
    if (strlen(code_sign_key)) {
748
 
        fputs("<code_sign_key>\n", fout);
749
 
        fputs(code_sign_key, fout);
750
 
        fputs("</code_sign_key>\n", fout);
751
 
    }
752
 
 
753
 
    if (strlen(code_sign_key_signature)) {
754
 
        fputs("<code_sign_key_signature>\n", fout);
755
 
        fputs(code_sign_key_signature, fout);
756
 
        fputs("</code_sign_key_signature>\n", fout);
757
 
    }
758
 
 
759
 
    if (send_msg_ack) {
760
 
        fputs("<message_ack/>\n", fout);
761
 
    }
762
 
 
763
 
    for (i=0; i<msgs_to_host.size(); i++) {
764
 
        MSG_TO_HOST& md = msgs_to_host[i];
765
 
        fprintf(fout, "%s\n", md.xml);
766
 
    }
767
 
 
768
 
    if (config.non_cpu_intensive) {
769
 
        fprintf(fout, "<non_cpu_intensive/>\n");
770
 
    }
771
 
 
772
 
    if (config.verify_files_on_app_start) {
773
 
        fprintf(fout, "<verify_files_on_app_start/>\n");
774
 
    }
775
 
 
776
 
    for (i=0; i<file_deletes.size(); i++) {
777
 
        fprintf(fout,
778
 
            "<delete_file_info>%s</delete_file_info>\n",
779
 
            file_deletes[i].name
780
 
        );
781
 
    }
782
 
 
783
 
    gui_urls.get_gui_urls(user, host, team, buf);
784
 
    fputs(buf, fout);
785
 
    if (project_files.text) {
786
 
        fputs(project_files.text, fout);
787
 
        fprintf(fout, "\n");
788
 
    }
789
 
 
790
 
end:
791
 
    fprintf(fout,
792
 
        "</scheduler_reply>\n"
793
 
    );
794
 
    return 0;
795
 
}
796
 
 
797
 
// set delay to the MAX of the existing value or the requested value
798
 
// never send a delay request longer than two days.
799
 
//
800
 
void SCHEDULER_REPLY::set_delay(double delay) {
801
 
    if (request_delay < delay) {
802
 
        request_delay = delay;
803
 
    }
804
 
    if (request_delay > DELAY_MAX) {
805
 
        request_delay = DELAY_MAX;
806
 
    }
807
 
808
 
 
809
 
 
810
 
void SCHEDULER_REPLY::insert_app_unique(APP& app) {
811
 
    unsigned int i;
812
 
    for (i=0; i<apps.size(); i++) {
813
 
        if (app.id == apps[i].id) return;
814
 
    }
815
 
    apps.push_back(app);
816
 
}
817
 
 
818
 
void SCHEDULER_REPLY::insert_app_version_unique(APP_VERSION& av) {
819
 
    unsigned int i;
820
 
    for (i=0; i<app_versions.size(); i++) {
821
 
        if (av.id == app_versions[i].id) return;
822
 
    }
823
 
    app_versions.push_back(av);
824
 
}
825
 
 
826
 
void SCHEDULER_REPLY::insert_workunit_unique(WORKUNIT& wu) {
827
 
    unsigned int i;
828
 
    for (i=0; i<wus.size(); i++) {
829
 
        if (wu.id == wus[i].id) return;
830
 
    }
831
 
    wus.push_back(wu);
832
 
}
833
 
 
834
 
void SCHEDULER_REPLY::insert_result(RESULT& result) {
835
 
    results.push_back(result);
836
 
}
837
 
 
838
 
void SCHEDULER_REPLY::insert_message(USER_MESSAGE& um) {
839
 
    messages.push_back(um);
840
 
}
841
 
 
842
 
USER_MESSAGE::USER_MESSAGE(const char* m, const char* p) {
843
 
    message = m;
844
 
    priority = p;
845
 
}
846
 
 
847
 
int APP::write(FILE* fout) {
848
 
    fprintf(fout,
849
 
        "<app>\n"
850
 
        "    <name>%s</name>\n"
851
 
        "    <user_friendly_name>%s</user_friendly_name>\n"
852
 
        "</app>\n",
853
 
        name, user_friendly_name
854
 
    );
855
 
    return 0;
856
 
}
857
 
 
858
 
int APP_VERSION::write(FILE* fout) {
859
 
    char buf[APP_VERSION_XML_BLOB_SIZE];
860
 
    unsigned int i;
861
 
 
862
 
    strcpy(buf, xml_doc);
863
 
    char* p = strstr(buf, "</app_version>");
864
 
    if (!p) {
865
 
        fprintf(stderr, "ERROR: app version %d XML has no end tag!\n", id);
866
 
        return -1;
867
 
    }
868
 
    *p = 0;
869
 
    fputs(buf, fout);
870
 
    PLATFORM* pp = ssp->lookup_platform_id(platformid);
871
 
    fprintf(fout, "    <platform>%s</platform>\n", pp->name);
872
 
    if (strlen(plan_class)) {
873
 
        fprintf(fout, "    <plan_class>%s</plan_class>\n", plan_class);
874
 
    }
875
 
    fprintf(fout,
876
 
        "    <avg_ncpus>%f</avg_ncpus>\n"
877
 
        "    <max_ncpus>%f</max_ncpus>\n"
878
 
        "    <flops>%f</flops>\n",
879
 
        bavp->host_usage.avg_ncpus,
880
 
        bavp->host_usage.max_ncpus,
881
 
        bavp->host_usage.flops
882
 
    );
883
 
    if (strlen(bavp->host_usage.cmdline)) {
884
 
        fprintf(fout,
885
 
            "    <cmdline>%s</cmdline>\n",
886
 
            bavp->host_usage.cmdline
887
 
        );
888
 
    }
889
 
    for (i=0; i<bavp->host_usage.coprocs.coprocs.size(); i++) {
890
 
        COPROC* cp = bavp->host_usage.coprocs.coprocs[i];
891
 
        fprintf(fout,
892
 
            "    <coproc>\n"
893
 
            "        <type>%s</type>\n"
894
 
            "        <count>%d</count>\n"
895
 
            "    </coproc>\n",
896
 
            cp->type,
897
 
            cp->count
898
 
        );
899
 
    }
900
 
    fputs("</app_version>\n", fout);
901
 
    return 0;
902
 
}
903
 
 
904
 
int RESULT::write_to_client(FILE* fout) {
905
 
    char buf[BLOB_SIZE];
906
 
 
907
 
    strcpy(buf, xml_doc_in);
908
 
    char* p = strstr(buf, "</result>");
909
 
    if (!p) {
910
 
        fprintf(stderr, "ERROR: result %d XML has no end tag!\n", id);
911
 
        return -1;
912
 
    }
913
 
    *p = 0;
914
 
    fputs(buf, fout);
915
 
 
916
 
    APP_VERSION* avp = bavp->avp;
917
 
    if (avp == (APP_VERSION*)1) avp = NULL;
918
 
    if (avp) {
919
 
        PLATFORM* pp = ssp->lookup_platform_id(avp->platformid);
920
 
        fprintf(fout,
921
 
            "    <platform>%s</platform>\n"
922
 
            "    <version_num>%d</version_num>\n"
923
 
            "    <plan_class>%s</plan_class>\n",
924
 
            pp->name, avp->version_num, avp->plan_class
925
 
        );
926
 
    }
927
 
    fputs("</result>\n", fout);
928
 
    return 0;
929
 
}
930
 
 
931
 
int RESULT::parse_from_client(FILE* fin) {
932
 
    char buf[256];
933
 
 
934
 
    // should be non-zero if exit_status is not found
935
 
    exit_status = ERR_NO_EXIT_STATUS;
936
 
    memset(this, 0, sizeof(RESULT));
937
 
    while (fgets(buf, sizeof(buf), fin)) {
938
 
        if (match_tag(buf, "</result>")) return 0;
939
 
        if (parse_str(buf, "<name>", name, sizeof(name))) continue;
940
 
        if (parse_int(buf, "<state>", client_state)) continue;
941
 
        if (parse_double(buf, "<final_cpu_time>", cpu_time)) continue;
942
 
        if (parse_int(buf, "<exit_status>", exit_status)) continue;
943
 
        if (parse_int(buf, "<app_version_num>", app_version_num)) continue;
944
 
        if (parse_double(buf, "<fpops_per_cpu_sec>", fpops_per_cpu_sec)) continue;
945
 
        if (parse_double(buf, "<fpops_cumulative>", fpops_cumulative)) continue;
946
 
        if (parse_double(buf, "<intops_per_cpu_sec>", intops_per_cpu_sec)) continue;
947
 
        if (parse_double(buf, "<intops_cumulative>", intops_cumulative)) continue;
948
 
        if (match_tag(buf, "<file_info>")) {
949
 
            safe_strcat(xml_doc_out, buf);
950
 
            while (fgets(buf, sizeof(buf), fin)) {
951
 
                safe_strcat(xml_doc_out, buf);
952
 
                if (match_tag(buf, "</file_info>")) break;
953
 
            }
954
 
            continue;
955
 
        }
956
 
        if (match_tag(buf, "<stderr_out>" )) {
957
 
            while (fgets(buf, sizeof(buf), fin)) {
958
 
                if (match_tag(buf, "</stderr_out>")) break;
959
 
                safe_strcat(stderr_out, buf);
960
 
            }
961
 
            continue;
962
 
        }
963
 
        if (match_tag(buf, "<platform>")) continue;
964
 
        if (match_tag(buf, "<version_num>")) continue;
965
 
        if (match_tag(buf, "<plan_class>")) continue;
966
 
        if (match_tag(buf, "<completed_time>")) continue;
967
 
        if (match_tag(buf, "<file_name>")) continue;
968
 
        if (match_tag(buf, "<file_ref>")) continue;
969
 
        if (match_tag(buf, "</file_ref>")) continue;
970
 
        if (match_tag(buf, "<open_name>")) continue;
971
 
        if (match_tag(buf, "<ready_to_report>")) continue;
972
 
        if (match_tag(buf, "<ready_to_report/>")) continue;
973
 
        if (match_tag(buf, "<report_deadline>")) continue;
974
 
        if (match_tag(buf, "<wu_name>")) continue;
975
 
 
976
 
        log_messages.printf(MSG_NORMAL,
977
 
            "RESULT::parse_from_client(): unrecognized: %s\n",
978
 
            buf
979
 
        );
980
 
    }
981
 
    return ERR_XML_PARSE;
982
 
}
983
 
 
984
 
int HOST::parse(FILE* fin) {
985
 
    char buf[1024];
986
 
 
987
 
    p_ncpus = 1;
988
 
    while (fgets(buf, sizeof(buf), fin)) {
989
 
        if (match_tag(buf, "</host_info>")) return 0;
990
 
        if (parse_int(buf, "<timezone>", timezone)) continue;
991
 
        if (parse_str(buf, "<domain_name>", domain_name, sizeof(domain_name))) continue;
992
 
        if (parse_str(buf, "<serialnum>", serialnum, sizeof(serialnum))) continue;
993
 
        if (parse_str(buf, "<ip_addr>", last_ip_addr, sizeof(last_ip_addr))) continue;
994
 
        if (parse_str(buf, "<host_cpid>", host_cpid, sizeof(host_cpid))) continue;
995
 
        if (parse_int(buf, "<p_ncpus>", p_ncpus)) continue;
996
 
        if (parse_str(buf, "<p_vendor>", p_vendor, sizeof(p_vendor))) continue;
997
 
        if (parse_str(buf, "<p_model>", p_model, sizeof(p_model))) continue;
998
 
        if (parse_double(buf, "<p_fpops>", p_fpops)) continue;
999
 
        if (parse_double(buf, "<p_iops>", p_iops)) continue;
1000
 
        if (parse_double(buf, "<p_membw>", p_membw)) continue;
1001
 
        if (parse_str(buf, "<os_name>", os_name, sizeof(os_name))) continue;
1002
 
        if (parse_str(buf, "<os_version>", os_version, sizeof(os_version))) continue;
1003
 
        if (parse_double(buf, "<m_nbytes>", m_nbytes)) continue;
1004
 
        if (parse_double(buf, "<m_cache>", m_cache)) continue;
1005
 
        if (parse_double(buf, "<m_swap>", m_swap)) continue;
1006
 
        if (parse_double(buf, "<d_total>", d_total)) continue;
1007
 
        if (parse_double(buf, "<d_free>", d_free)) continue;
1008
 
        if (parse_double(buf, "<n_bwup>", n_bwup)) continue;
1009
 
        if (parse_double(buf, "<n_bwdown>", n_bwdown)) continue;
1010
 
 
1011
 
        // parse deprecated fields to avoid error messages
1012
 
        //
1013
 
        if (match_tag(buf, "<p_calculated>")) continue;
1014
 
        if (match_tag(buf, "<p_fpop_err>")) continue;
1015
 
        if (match_tag(buf, "<p_iop_err>")) continue;
1016
 
        if (match_tag(buf, "<p_membw_err>")) continue;
1017
 
 
1018
 
        // fields reported by 5.5+ clients, not currently used
1019
 
        //
1020
 
        if (match_tag(buf, "<p_features>")) continue;
1021
 
        if (match_tag(buf, "<p_capabilities>")) continue;
1022
 
        if (match_tag(buf, "<accelerators>")) continue;
1023
 
 
1024
 
#if 1
1025
 
        // not sure where thees fields belong in the above
1026
 
        // categories
1027
 
        //
1028
 
        if (match_tag(buf, "<cpu_caps>")) continue;
1029
 
        if (match_tag(buf, "<cache_l1>")) continue;
1030
 
        if (match_tag(buf, "<cache_l2>")) continue;
1031
 
        if (match_tag(buf, "<cache_l3>")) continue;
1032
 
#endif
1033
 
 
1034
 
        log_messages.printf(MSG_NORMAL,
1035
 
            "HOST::parse(): unrecognized: %s\n", buf
1036
 
        );
1037
 
    }
1038
 
    return ERR_XML_PARSE;
1039
 
}
1040
 
 
1041
 
 
1042
 
int HOST::parse_time_stats(FILE* fin) {
1043
 
    char buf[256];
1044
 
 
1045
 
    while (fgets(buf, sizeof(buf), fin)) {
1046
 
        if (match_tag(buf, "</time_stats>")) return 0;
1047
 
        if (parse_double(buf, "<on_frac>", on_frac)) continue;
1048
 
        if (parse_double(buf, "<connected_frac>", connected_frac)) continue;
1049
 
        if (parse_double(buf, "<active_frac>", active_frac)) continue;
1050
 
        if (match_tag(buf, "<outages>")) continue;
1051
 
        if (match_tag(buf, "<outage>")) continue;
1052
 
        if (match_tag(buf, "<start>")) continue;
1053
 
        if (match_tag(buf, "<end>")) continue;
1054
 
        log_messages.printf(MSG_NORMAL,
1055
 
            "HOST::parse_time_stats(): unrecognized: %s\n",
1056
 
            buf
1057
 
        );
1058
 
    }
1059
 
    return ERR_XML_PARSE;
1060
 
}
1061
 
 
1062
 
int HOST::parse_net_stats(FILE* fin) {
1063
 
    char buf[256];
1064
 
 
1065
 
    while (fgets(buf, sizeof(buf), fin)) {
1066
 
        if (match_tag(buf, "</net_stats>")) return 0;
1067
 
        if (parse_double(buf, "<bwup>", n_bwup)) continue;
1068
 
        if (parse_double(buf, "<bwdown>", n_bwdown)) continue;
1069
 
 
1070
 
        // items reported by 5.10+ clients, not currently used
1071
 
        //
1072
 
        if (match_tag(buf, "<avg_time_up>")) continue;
1073
 
        if (match_tag(buf, "<avg_up>")) continue;
1074
 
        if (match_tag(buf, "<avg_time_down>")) continue;
1075
 
        if (match_tag(buf, "<avg_down>")) continue;
1076
 
 
1077
 
        log_messages.printf(MSG_NORMAL,
1078
 
            "HOST::parse_net_stats(): unrecognized: %s\n",
1079
 
            buf
1080
 
        );
1081
 
    }
1082
 
    return ERR_XML_PARSE;
1083
 
}
1084
 
 
1085
 
int HOST::parse_disk_usage(FILE* fin) {
1086
 
    char buf[256];
1087
 
 
1088
 
    while (fgets(buf, sizeof(buf), fin)) {
1089
 
        if (match_tag(buf, "</disk_usage>")) return 0;
1090
 
        if (parse_double(buf, "<d_boinc_used_total>", d_boinc_used_total)) continue;
1091
 
        if (parse_double(buf, "<d_boinc_used_project>", d_boinc_used_project)) continue;
1092
 
        log_messages.printf(MSG_NORMAL,
1093
 
            "HOST::parse_disk_usage(): unrecognized: %s\n",
1094
 
            buf
1095
 
        );
1096
 
    }
1097
 
    return ERR_XML_PARSE;
1098
 
}
1099
 
 
1100
 
void GLOBAL_PREFS::parse(const char* buf, const char* venue) {
1101
 
    char buf2[BLOB_SIZE];
1102
 
    double dtemp;
1103
 
 
1104
 
    defaults();
1105
 
 
1106
 
    if (parse_double(buf, "<mod_time>", mod_time)) {
1107
 
        // mod_time is outside of venue
1108
 
        if (mod_time > dtime()) mod_time = dtime();
1109
 
    }
1110
 
    extract_venue(buf, venue, buf2);
1111
 
    parse_double(buf2, "<disk_max_used_gb>", disk_max_used_gb);
1112
 
    parse_double(buf2, "<disk_max_used_pct>", disk_max_used_pct);
1113
 
    parse_double(buf2, "<disk_min_free_gb>", disk_min_free_gb);
1114
 
    parse_double(buf2, "<work_buf_min_days>", work_buf_min_days);
1115
 
    if (parse_double(buf2, "<ram_max_used_busy_pct>", dtemp)) {
1116
 
        ram_max_used_busy_frac = dtemp/100.;
1117
 
    }
1118
 
    if (parse_double(buf2, "<ram_max_used_idle_pct>", dtemp)) {
1119
 
        ram_max_used_idle_frac = dtemp/100.;
1120
 
    }
1121
 
    parse_double(buf2, "<max_ncpus_pct>", max_ncpus_pct);
1122
 
}
1123
 
 
1124
 
void GLOBAL_PREFS::defaults() {
1125
 
    memset(this, 0, sizeof(GLOBAL_PREFS));
1126
 
}
1127
 
 
1128
 
void GUI_URLS::init() {
1129
 
    text = 0;
1130
 
    read_file_malloc("../gui_urls.xml", text);
1131
 
}
1132
 
 
1133
 
void GUI_URLS::get_gui_urls(USER& user, HOST& host, TEAM& team, char* buf) {
1134
 
    bool found;
1135
 
    char userid[256], teamid[256], hostid[256];
1136
 
    strcpy(buf, "");
1137
 
    if (!text) return;
1138
 
    strcpy(buf, text);
1139
 
 
1140
 
    sprintf(userid, "%d", user.id);
1141
 
    sprintf(hostid, "%d", host.id);
1142
 
    if (user.teamid) {
1143
 
        sprintf(teamid, "%d", team.id);
1144
 
    } else {
1145
 
        strcpy(teamid, "0");
1146
 
        while (remove_element(buf, "<ifteam>", "</ifteam>")) {
1147
 
            continue;
1148
 
        }
1149
 
 
1150
 
    }
1151
 
    while (1) {
1152
 
        found = false;
1153
 
        found |= str_replace(buf, "<userid/>", userid);
1154
 
        found |= str_replace(buf, "<user_name/>", user.name);
1155
 
        found |= str_replace(buf, "<hostid/>", hostid);
1156
 
        found |= str_replace(buf, "<teamid/>", teamid);
1157
 
        found |= str_replace(buf, "<team_name/>", team.name);
1158
 
        found |= str_replace(buf, "<authenticator/>", user.authenticator);
1159
 
        if (!found) break;
1160
 
    }
1161
 
}
1162
 
 
1163
 
void PROJECT_FILES::init() {
1164
 
    text = 0;
1165
 
    read_file_malloc("../project_files.xml", text);
1166
 
}
1167
 
 
1168
 
const char *BOINC_RCSID_ea659117b3 = "$Id: server_types.cpp 16611 2008-12-03 20:55:22Z romw $";