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
// boinclog: 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"
27
#if defined(_WIN32) && !defined(__CYGWIN32__)
28
#define snprintf _snprintf
29
#define strdate _strdate
30
#define strtime _strtime
48
#include "gui_rpc_client.h"
49
#include "error_numbers.h"
52
#include "str_replace.h"
55
#include "common_defs.h"
58
#define ARGX2(s1,s2) (!strcmp(argv[i], s1)||!strcmp(argv[i], s2))
59
#define ARG(S) ARGX2("-"#S, "--"#S)
63
char g_log_filename[256];
64
int g_message_sequence;
67
printf("boinclog, built from %s \n", PACKAGE_STRING );
73
usage: boinclog [--host hostname] [--passwd passwd] [commands]\n\n\
75
--version, -V show version of the logging tool\n\
76
--datadir <directory> where the data directory is located\n\
82
void show_error(int retval) {
83
fprintf(stderr, "Error %d: %s\n", retval, boincerror(retval));
86
const char* prio_name(int prio) {
88
case MSG_INFO: return "low";
89
case MSG_USER_ALERT: return "user notification";
90
case MSG_INTERNAL_ERROR: return "internal error";
96
void update_display() {
98
printf("BOINC Log Conversion Client %s\n", PACKAGE_VERSION);
99
printf("Log file: %s\n", g_log_filename);
100
printf("%d message(s) processed.\n\n", g_message_sequence);
101
printf("Press CTRL-C to exit application.\n");
105
int main(int argc, char** argv) {
112
char hostname_buf[256], passwd_buf[256];
113
char *hostname = 0, *passwd = passwd_buf, *p;
117
std::string msg_datetime;
118
std::string msg_project;
119
std::string msg_priority;
120
std::string msg_type;
121
std::string msg_body;
126
strcpy(hostname_buf, "");
127
strcpy(passwd_buf, "");
128
strcpy(g_log_filename, "");
129
g_message_sequence = 0;
131
#if defined(_WIN32) && defined(USE_WINSOCK)
133
retval = WSAStartup( MAKEWORD( 1, 1 ), &wsdata);
135
fprintf(stderr, "WinsockInitialize: %d\n", retval);
140
for (i=1; i<(unsigned int)argc; i++) {
144
} else if (ARG(help)) {
148
} else if (ARG(version)) {
150
} else if (ARG(host)) {
151
if ((i+1) == (unsigned int)argc) usage();
152
hostname = hostname_buf;
153
safe_strcpy(hostname_buf, argv[++i]);
154
p = strchr(hostname, ':');
159
} else if (ARG(passwd)) {
160
if ((i+1) == (unsigned int)argc) usage();
161
safe_strcpy(passwd_buf, argv[++i]);
162
} else if (ARG(datadir)) {
163
if ((i+1) == (unsigned int)argc) usage();
164
safe_strcpy(datadir, argv[++i]);
166
printf("Unknown option: %s\n", argv[i]);
171
if (strlen(datadir)) {
179
read_gui_rpc_password(passwd_buf);
181
retval = rpc.init(hostname, port);
183
fprintf(stderr, "can't connect to %s\n", hostname?hostname:"local host");
189
retval = rpc.authorize(passwd);
191
fprintf(stderr, "authorization failure: %d\n", retval);
198
// Construct a unique filename for the output.
200
ptm = localtime(×tamp);
201
strftime(g_log_filename, sizeof(g_log_filename), "%Y%m%d%H%M.log", ptm);
203
// Open the new log file for output
204
f = fopen(g_log_filename, "w");
212
rpc.get_messages(g_message_sequence, msgs);
214
for (i=0; i<msgs.messages.size(); i++) {
215
MESSAGE* pMsg = msgs.messages[i];
217
msg_datetime.clear();
219
msg_priority.clear();
223
msg_datetime = time_to_string(double(pMsg->timestamp));
224
msg_project = pMsg->project;
225
msg_priority = prio_name(pMsg->priority);
226
msg_body = pMsg->body;
227
if (pMsg->body[0] == '[') {
228
msg_type = pMsg->body.substr(1, pMsg->body.find(']') - 1);
231
// If a message type is found in the message body, remove it from
233
if (!msg_type.empty()) {
234
msg_tmp = std::string("[") + msg_type + std::string("] ");
235
msg_body.replace(0, msg_tmp.size(), "");
238
// If the last character if the message body is a newline character,
239
// remove it before continueing on. Standard BOINC messages contain
240
// a newline character at the end.
241
if (msg_body[msg_body.size() - 1] == '\n') {
242
msg_body[msg_body.size() - 1] = ' ';
245
// If line feeds are detected in the message body, replace them with
247
for (unsigned int j = 0; j < msg_body.size(); j++) {
248
if (msg_body[j] == '\n') {
253
// Dump to tab delimited file
255
"%s\t%s\t%s\t%s\t%s\n",
256
msg_datetime.c_str(),
257
msg_priority.c_str(),
263
g_message_sequence = pMsg->seqno;
269
#if defined(_WIN32) && defined(USE_WINSOCK)