1
// This file is part of BOINC.
2
// http://boinc.berkeley.edu
3
// Copyright (C) 2008 University of California
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.
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.
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/>.
18
// boinccmd: command-line interface to a BOINC core client,
21
// usage: boinccmd [--host hostname] [--passwd passwd] command
23
#if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
24
#include "boinc_win.h"
41
#include "gui_rpc_client.h"
42
#include "error_numbers.h"
45
#include "str_replace.h"
48
#include "common_defs.h"
51
printf("boinccmd, built from %s \n", PACKAGE_STRING );
57
usage: boinccmd [--host hostname] [--passwd passwd] command\n\n\
59
--create_account URL email passwd name\n\
60
--file_transfer URL filename op file transfer operation\n\
63
--get_disk_usage show disk usage\n\
64
--get_file_transfers show file transfers\n\
66
--get_message_count show largest message seqno\n\
67
--get_messages [ seqno ] show messages > seqno\n\
68
--get_notices [ seqno ] show notices > seqno\n\
69
--get_project_config URL\n\
70
--get_project_config_poll\n\
71
--get_project_status show status of all attached projects\n\
72
--get_proxy_settings\n\
73
--get_simple_gui_info show status of projects and active tasks\n\
74
--get_state show entire state\n\
75
--get_tasks show tasks\n\
76
--join_acct_mgr URL name passwd attach account manager\n\
77
--lookup_account URL email passwd\n\
78
--network_available\n\
79
--project URL op project operation\n\
80
op = reset | detach | update | suspend | resume | nomorework | allowmorework\n\
81
--project_attach URL auth attach to project\n\
82
--quit tell client to exit\n\
83
--quit_acct_mgr quit current account manager\n\
85
--read_global_prefs_override\n\
87
--set_debts URL1 std1 ltd1 [URL2 std2 ltd2 ...]\n\
88
--set_gpu_mode mode duration set GPU run mode for given duration\n\
89
mode = always | auto | never\n\
90
--set_network_mode mode duration\n\
91
--set_proxy_settings\n\
92
--set_run_mode mode duration set run mode for given duration\n\
93
mode = always | auto | never\n\
94
--task url task_name op task operation\n\
95
op = suspend | resume | abort | graphics_window | graphics_fullscreen\n\
96
--version, -V show core client version\n\
102
void parse_display_args(char** argv, int& i, DISPLAY_INFO& di) {
103
strcpy(di.window_station, "winsta0");
104
strcpy(di.desktop, "default");
105
strcpy(di.display, "");
107
if (!strcmp(argv[i], "--window_station")) {
108
strlcpy(di.window_station, argv[++i], sizeof(di.window_station));
109
} else if (!strcpy(argv[i], "--desktop")) {
110
strlcpy(di.desktop, argv[++i], sizeof(di.desktop));
111
} else if (!strcpy(argv[i], "--display")) {
112
strlcpy(di.display, argv[++i], sizeof(di.display));
118
void show_error(int retval) {
119
fprintf(stderr, "Error %d: %s\n", retval, boincerror(retval));
122
char* next_arg(int argc, char** argv, int& i) {
124
fprintf(stderr, "Missing command-line argument\n");
131
const char* prio_name(int prio) {
133
case MSG_INFO: return "low";
134
case MSG_USER_ALERT: return "user notification";
135
case MSG_INTERNAL_ERROR: return "internal error";
140
int main(int argc, char** argv) {
142
int i, retval, port=0;
145
char passwd_buf[256], hostname_buf[256], *hostname=0;
146
char* passwd = passwd_buf, *p;
151
strcpy(passwd_buf, "");
152
read_gui_rpc_password(passwd_buf);
154
#if defined(_WIN32) && defined(USE_WINSOCK)
156
retval = WSAStartup( MAKEWORD( 1, 1 ), &wsdata);
158
fprintf(stderr, "WinsockInitialize: %d\n", retval);
162
if (argc < 2) usage();
164
if (!strcmp(argv[i], "--help")) usage();
165
if (!strcmp(argv[i], "-h")) usage();
166
if (!strcmp(argv[i], "--version")) version();
167
if (!strcmp(argv[i], "-V")) version();
169
if (!strcmp(argv[i], "--host")) {
170
if (++i == argc) usage();
171
strlcpy(hostname_buf, argv[i], sizeof(hostname_buf));
172
hostname = hostname_buf;
173
p = strchr(hostname, ':');
180
if ((i<argc)&& !strcmp(argv[i], "--passwd")) {
181
if (++i == argc) usage();
186
// change the following to debug GUI RPC's asynchronous connection mechanism
189
retval = rpc.init(hostname, port);
191
fprintf(stderr, "can't connect to %s\n", hostname?hostname:"local host");
195
retval = rpc.init_asynch(hostname, 60., false);
197
retval = rpc.init_poll();
199
if (retval == ERR_RETRY) {
200
printf("sleeping\n");
204
fprintf(stderr, "can't connect: %d\n", retval);
207
printf("connected\n");
210
if (strlen(passwd)) {
211
retval = rpc.authorize(passwd);
213
fprintf(stderr, "Authorization failure: %d\n", retval);
218
char* cmd = next_arg(argc, argv, i);
219
if (!strcmp(cmd, "--get_state")) {
221
retval = rpc.get_state(state);
222
if (!retval) state.print();
223
} else if (!strcmp(cmd, "--get_tasks")) {
225
retval = rpc.get_results(results);
226
if (!retval) results.print();
227
} else if (!strcmp(cmd, "--get_file_transfers")) {
229
retval = rpc.get_file_transfers(ft);
230
if (!retval) ft.print();
231
} else if (!strcmp(cmd, "--get_project_status")) {
233
retval = rpc.get_project_status(ps);
234
if (!retval) ps.print();
235
} else if (!strcmp(cmd, "--get_simple_gui_info")) {
236
SIMPLE_GUI_INFO info;
237
retval = rpc.get_simple_gui_info(info);
238
if (!retval) info.print();
239
} else if (!strcmp(cmd, "--get_disk_usage")) {
241
retval = rpc.get_disk_usage(du);
242
if (!retval) du.print();
243
} else if (!strcmp(cmd, "--task")) {
245
char* project_url = next_arg(argc, argv, i);
246
strcpy(result.project_url, project_url);
247
char* name = next_arg(argc, argv, i);
248
strcpy(result.name, name);
249
char* op = next_arg(argc, argv, i);
250
if (!strcmp(op, "suspend")) {
251
retval = rpc.result_op(result, "suspend");
252
} else if (!strcmp(op, "resume")) {
253
retval = rpc.result_op(result, "resume");
254
} else if (!strcmp(op, "abort")) {
255
retval = rpc.result_op(result, "abort");
256
} else if (!strcmp(op, "graphics_window")) {
258
parse_display_args(argv, i, di);
259
retval = rpc.show_graphics(project_url, name, MODE_WINDOW, di);
260
} else if (!strcmp(op, "graphics_fullscreen")) {
262
parse_display_args(argv, i, di);
263
retval = rpc.show_graphics(project_url, name, MODE_FULLSCREEN, di);
265
fprintf(stderr, "Unknown op %s\n", op);
267
} else if (!strcmp(cmd, "--project")) {
269
strcpy(project.master_url, next_arg(argc, argv, i));
270
canonicalize_master_url(project.master_url);
271
char* op = next_arg(argc, argv, i);
272
if (!strcmp(op, "reset")) {
273
retval = rpc.project_op(project, "reset");
274
} else if (!strcmp(op, "suspend")) {
275
retval = rpc.project_op(project, "suspend");
276
} else if (!strcmp(op, "resume")) {
277
retval = rpc.project_op(project, "resume");
278
} else if (!strcmp(op, "detach")) {
279
retval = rpc.project_op(project, "detach");
280
} else if (!strcmp(op, "update")) {
281
retval = rpc.project_op(project, "update");
282
} else if (!strcmp(op, "suspend")) {
283
retval = rpc.project_op(project, "suspend");
284
} else if (!strcmp(op, "resume")) {
285
retval = rpc.project_op(project, "resume");
286
} else if (!strcmp(op, "nomorework")) {
287
retval = rpc.project_op(project, "nomorework");
288
} else if (!strcmp(op, "allowmorework")) {
289
retval = rpc.project_op(project, "allowmorework");
290
} else if (!strcmp(op, "detach_when_done")) {
291
retval = rpc.project_op(project, "detach_when_done");
292
} else if (!strcmp(op, "dont_detach_when_done")) {
293
retval = rpc.project_op(project, "dont_detach_when_done");
295
fprintf(stderr, "Unknown op %s\n", op);
297
} else if (!strcmp(cmd, "--project_attach")) {
299
strcpy(url, next_arg(argc, argv, i));
300
canonicalize_master_url(url);
301
char* auth = next_arg(argc, argv, i);
302
retval = rpc.project_attach(url, auth, "");
303
} else if (!strcmp(cmd, "--file_transfer")) {
306
ft.project_url = next_arg(argc, argv, i);
307
ft.name = next_arg(argc, argv, i);
308
char* op = next_arg(argc, argv, i);
309
if (!strcmp(op, "retry")) {
310
retval = rpc.file_transfer_op(ft, "retry");
311
} else if (!strcmp(op, "abort")) {
312
retval = rpc.file_transfer_op(ft, "abort");
314
fprintf(stderr, "Unknown op %s\n", op);
316
} else if (!strcmp(cmd, "--set_run_mode")) {
317
char* op = next_arg(argc, argv, i);
319
if (i >= argc || (argv[i][0] == '-')) {
322
duration = atof(next_arg(argc, argv, i));
324
if (!strcmp(op, "always")) {
325
retval = rpc.set_run_mode(RUN_MODE_ALWAYS, duration);
326
} else if (!strcmp(op, "auto")) {
327
retval = rpc.set_run_mode(RUN_MODE_AUTO, duration);
328
} else if (!strcmp(op, "never")) {
329
retval = rpc.set_run_mode(RUN_MODE_NEVER, duration);
331
fprintf(stderr, "Unknown op %s\n", op);
333
} else if (!strcmp(cmd, "--set_gpu_mode")) {
334
char* op = next_arg(argc, argv, i);
336
if (i >= argc || (argv[i][0] == '-')) {
339
duration = atof(next_arg(argc, argv, i));
341
if (!strcmp(op, "always")) {
342
retval = rpc.set_gpu_mode(RUN_MODE_ALWAYS, duration);
343
} else if (!strcmp(op, "auto")) {
344
retval = rpc.set_gpu_mode(RUN_MODE_AUTO, duration);
345
} else if (!strcmp(op, "never")) {
346
retval = rpc.set_gpu_mode(RUN_MODE_NEVER, duration);
348
fprintf(stderr, "Unknown op %s\n", op);
350
} else if (!strcmp(cmd, "--set_network_mode")) {
351
char* op = next_arg(argc, argv, i);
353
if (i >= argc || (argv[i][0] == '-')) {
356
duration = atof(next_arg(argc, argv, i));
358
if (!strcmp(op, "always")) {
359
retval = rpc.set_network_mode(RUN_MODE_ALWAYS, duration);
360
} else if (!strcmp(op, "auto")) {
361
retval = rpc.set_network_mode(RUN_MODE_AUTO, duration);
362
} else if (!strcmp(op, "never")) {
363
retval = rpc.set_network_mode(RUN_MODE_NEVER, duration);
365
fprintf(stderr, "Unknown op %s\n", op);
367
} else if (!strcmp(cmd, "--get_proxy_settings")) {
369
retval = rpc.get_proxy_settings(pi);
370
if (!retval) pi.print();
371
} else if (!strcmp(cmd, "--set_proxy_settings")) {
373
pi.http_server_name = next_arg(argc, argv, i);
374
pi.http_server_port = atoi(next_arg(argc, argv, i));
375
pi.http_user_name = next_arg(argc, argv, i);
376
pi.http_user_passwd = next_arg(argc, argv, i);
377
pi.socks_server_name = next_arg(argc, argv, i);
378
pi.socks_server_port = atoi(next_arg(argc, argv, i));
379
pi.socks_version = atoi(next_arg(argc, argv, i));
380
pi.socks5_user_name = next_arg(argc, argv, i);
381
pi.socks5_user_passwd = next_arg(argc, argv, i);
382
pi.noproxy_hosts = next_arg(argc, argv, i);
383
if (pi.http_server_name.size()) pi.use_http_proxy = true;
384
if (pi.http_user_name.size()) pi.use_http_authentication = true;
385
if (pi.socks_server_name.size()) pi.use_socks_proxy = true;
386
retval = rpc.set_proxy_settings(pi);
387
} else if (!strcmp(cmd, "--get_message_count")) {
389
retval = rpc.get_message_count(seqno);
391
printf("Greatest message sequence number: %d\n", seqno);
393
} else if (!strcmp(cmd, "--get_messages")) {
398
seqno = atoi(next_arg(argc, argv, i));
400
retval = rpc.get_messages(seqno, messages);
403
for (j=0; j<messages.messages.size(); j++) {
404
MESSAGE& md = *messages.messages[j];
405
strip_whitespace(md.body);
406
printf("%d: %s (%s) [%s] %s\n",
408
time_to_string(md.timestamp),
409
prio_name(md.priority),
415
} else if (!strcmp(cmd, "--get_notices")) {
420
seqno = atoi(next_arg(argc, argv, i));
422
retval = rpc.get_notices(seqno, notices);
425
for (j=0; j<notices.notices.size(); j++) {
426
NOTICE& n = *notices.notices[j];
427
strip_whitespace(n.description);
428
printf("%d: (%s) %s\n",
430
time_to_string(n.create_time),
431
n.description.c_str()
435
} else if (!strcmp(cmd, "--get_host_info")) {
437
retval = rpc.get_host_info(hi);
438
if (!retval) hi.print();
439
} else if (!strcmp(cmd, "--join_acct_mgr")) {
440
char* am_url = next_arg(argc, argv, i);
441
char* am_name = next_arg(argc, argv, i);
442
char* am_passwd = next_arg(argc, argv, i);
443
retval = rpc.acct_mgr_rpc(am_url, am_name, am_passwd);
446
ACCT_MGR_RPC_REPLY amrr;
447
retval = rpc.acct_mgr_rpc_poll(amrr);
449
printf("poll status: %s\n", boincerror(retval));
451
if (amrr.error_num) {
452
printf("poll status: %s\n", boincerror(amrr.error_num));
453
if (amrr.error_num != ERR_IN_PROGRESS) break;
456
int j, n = (int)amrr.messages.size();
458
printf("Messages from account manager:\n");
459
for (j=0; j<n; j++) {
460
printf("%s\n", amrr.messages[j].c_str());
468
} else if (!strcmp(cmd, "--quit_acct_mgr")) {
469
retval = rpc.acct_mgr_rpc("", "", "");
470
} else if (!strcmp(cmd, "--run_benchmarks")) {
471
retval = rpc.run_benchmarks();
472
} else if (!strcmp(cmd, "--get_project_config")) {
473
char* gpc_url = next_arg(argc, argv,i);
474
retval = rpc.get_project_config(string(gpc_url));
475
} else if (!strcmp(cmd, "--get_project_config_poll")) {
477
retval = rpc.get_project_config_poll(pc);
479
printf("retval: %d\n", retval);
483
} else if (!strcmp(cmd, "--lookup_account")) {
485
lai.url = next_arg(argc, argv, i);
486
lai.email_addr = next_arg(argc, argv, i);
487
lai.passwd = next_arg(argc, argv, i);
488
retval = rpc.lookup_account(lai);
489
printf("status: %s\n", boincerror(retval));
493
retval = rpc.lookup_account_poll(lao);
495
printf("poll status: %s\n", boincerror(retval));
498
printf("poll status: %s\n", boincerror(lao.error_num));
499
if (lao.error_num != ERR_IN_PROGRESS) break;
508
} else if (!strcmp(cmd, "--create_account")) {
510
cai.url = next_arg(argc, argv, i);
511
cai.email_addr = next_arg(argc, argv, i);
512
cai.passwd = next_arg(argc, argv, i);
513
cai.user_name = next_arg(argc, argv, i);
514
retval = rpc.create_account(cai);
515
printf("status: %s\n", boincerror(retval));
519
retval = rpc.create_account_poll(lao);
521
printf("poll status: %s\n", boincerror(retval));
524
printf("poll status: %s\n", boincerror(lao.error_num));
525
if (lao.error_num != ERR_IN_PROGRESS) break;
534
} else if (!strcmp(cmd, "--read_global_prefs_override")) {
535
retval = rpc.read_global_prefs_override();
536
} else if (!strcmp(cmd, "--read_cc_config")) {
537
retval = rpc.read_cc_config();
538
printf("retval %d\n", retval);
539
} else if (!strcmp(cmd, "--network_available")) {
540
retval = rpc.network_available();
541
} else if (!strcmp(cmd, "--get_cc_status")) {
543
retval = rpc.get_cc_status(cs);
545
retval = cs.network_status;
548
} else if (!strcmp(cmd, "--set_debts")) {
549
vector<PROJECT>projects;
552
strcpy(proj.master_url, next_arg(argc, argv, i));
553
int std = atoi(next_arg(argc, argv, i));
554
proj.cpu_short_term_debt = std;
555
proj.cuda_short_term_debt = std;
556
proj.ati_short_term_debt = std;
557
int ltd = atoi(next_arg(argc, argv, i));
558
proj.cpu_long_term_debt = ltd;
559
proj.cuda_debt = ltd;
561
projects.push_back(proj);
563
retval = rpc.set_debts(projects);
564
} else if (!strcmp(cmd, "--quit")) {
573
#if defined(_WIN32) && defined(USE_WINSOCK)