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

« back to all changes in this revision

Viewing changes to client/boinc_log.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
// boinclog: command-line interface to a BOINC core client,
 
19
// using GUI RPCs.
 
20
//
 
21
// usage: boinccmd [--host hostname] [--passwd passwd] command
 
22
 
 
23
#if defined(_WIN32) && !defined(__STDWX_H__) && !defined(_BOINC_WIN_) && !defined(_AFX_STDAFX_H_)
 
24
#include "boinc_win.h"
 
25
#endif
 
26
 
 
27
#if defined(_WIN32) && !defined(__CYGWIN32__)
 
28
#define snprintf    _snprintf
 
29
#define strdate     _strdate
 
30
#define strtime     _strtime
 
31
#define chdir       _chdir
 
32
#endif
 
33
 
 
34
#ifdef _WIN32
 
35
#include "win_util.h"
 
36
#else
 
37
#include "config.h"
 
38
#include <cstdio>
 
39
#include <cstring>
 
40
#include <unistd.h>
 
41
#endif
 
42
 
 
43
#include <vector>
 
44
#include <string>
 
45
using std::vector;
 
46
using std::string;
 
47
 
 
48
#include "gui_rpc_client.h"
 
49
#include "error_numbers.h"
 
50
#include "util.h"
 
51
#include "str_util.h"
 
52
#include "str_replace.h"
 
53
#include "url.h"
 
54
#include "version.h"
 
55
#include "common_defs.h"
 
56
 
 
57
 
 
58
#define ARGX2(s1,s2) (!strcmp(argv[i], s1)||!strcmp(argv[i], s2))
 
59
#define ARG(S) ARGX2("-"#S, "--"#S)
 
60
 
 
61
 
 
62
// Global variables
 
63
char  g_log_filename[256];
 
64
int   g_message_sequence;
 
65
 
 
66
void version(){
 
67
    printf("boinclog,  built from %s \n", PACKAGE_STRING );
 
68
    exit(0);
 
69
}
 
70
 
 
71
void usage() {
 
72
    fprintf(stderr, "\n\
 
73
usage: boinclog [--host hostname] [--passwd passwd] [commands]\n\n\
 
74
Commands:\n\
 
75
 --version, -V                      show version of the logging tool\n\
 
76
 --datadir <directory>              where the data directory is located\n\
 
77
"
 
78
);
 
79
    exit(1);
 
80
}
 
81
 
 
82
void show_error(int retval) {
 
83
    fprintf(stderr, "Error %d: %s\n", retval, boincerror(retval));
 
84
}
 
85
 
 
86
const char* prio_name(int prio) {
 
87
    switch (prio) {
 
88
    case MSG_INFO: return "low";
 
89
    case MSG_USER_ALERT: return "user notification";
 
90
    case MSG_INTERNAL_ERROR: return "internal error";
 
91
    }
 
92
    return "unknown";
 
93
}
 
94
 
 
95
 
 
96
void update_display() {
 
97
    system("cls");
 
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");
 
102
}
 
103
 
 
104
 
 
105
int main(int argc, char** argv) {
 
106
    unsigned int i;
 
107
    int retval, port=0;
 
108
    RPC_CLIENT rpc;
 
109
    MESSAGES msgs;
 
110
    char buf[256];
 
111
    char datadir[256];
 
112
        char hostname_buf[256], passwd_buf[256];
 
113
    char *hostname = 0, *passwd = passwd_buf, *p;
 
114
    struct tm* ptm;
 
115
    time_t timestamp;
 
116
    FILE* f = NULL;
 
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;
 
122
    std::string msg_tmp;
 
123
 
 
124
        strcpy(buf, "");
 
125
        strcpy(datadir, "");
 
126
        strcpy(hostname_buf, "");
 
127
        strcpy(passwd_buf, "");
 
128
        strcpy(g_log_filename, "");
 
129
    g_message_sequence = 0;
 
130
 
 
131
#if defined(_WIN32) && defined(USE_WINSOCK)
 
132
    WSADATA wsdata;
 
133
    retval = WSAStartup( MAKEWORD( 1, 1 ), &wsdata);
 
134
    if (retval) {
 
135
        fprintf(stderr, "WinsockInitialize: %d\n", retval);
 
136
        exit(1);
 
137
    }
 
138
#endif
 
139
 
 
140
    for (i=1; i<(unsigned int)argc; i++) {
 
141
        if (0) {
 
142
        } else if (ARG(h)) {
 
143
            usage();
 
144
        } else if (ARG(help)) {
 
145
            usage();
 
146
        } else if (ARG(V)) {
 
147
            version();
 
148
        } else if (ARG(version)) {
 
149
            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, ':');
 
155
            if (p) {
 
156
                port = atoi(p+1);
 
157
                *p=0;
 
158
            }
 
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]);
 
165
        } else {
 
166
            printf("Unknown option: %s\n", argv[i]);
 
167
            usage();
 
168
        }
 
169
    }
 
170
 
 
171
    if (strlen(datadir)) {
 
172
        chdir(datadir);
 
173
    } else {
 
174
#ifdef _WIN32
 
175
        chdir_to_data_dir();
 
176
#endif
 
177
    }
 
178
 
 
179
    read_gui_rpc_password(passwd_buf);
 
180
 
 
181
    retval = rpc.init(hostname, port);
 
182
    if (retval) {
 
183
        fprintf(stderr, "can't connect to %s\n", hostname?hostname:"local host");
 
184
        show_error(retval);
 
185
        exit(1);
 
186
    }
 
187
 
 
188
    if (passwd) {
 
189
        retval = rpc.authorize(passwd);
 
190
        if (retval) {
 
191
            fprintf(stderr, "authorization failure: %d\n", retval);
 
192
            show_error(retval);
 
193
            exit(1);
 
194
        }
 
195
    }
 
196
 
 
197
 
 
198
    // Construct a unique filename for the output.
 
199
    time(&timestamp);
 
200
    ptm = localtime(&timestamp);
 
201
    strftime(g_log_filename, sizeof(g_log_filename), "%Y%m%d%H%M.log", ptm);
 
202
 
 
203
    // Open the new log file for output
 
204
    f = fopen(g_log_filename, "w");
 
205
    setbuf(f, NULL);
 
206
 
 
207
    while(true) {
 
208
        update_display();
 
209
 
 
210
        msgs.clear();
 
211
 
 
212
        rpc.get_messages(g_message_sequence, msgs);
 
213
 
 
214
        for (i=0; i<msgs.messages.size(); i++) {
 
215
            MESSAGE* pMsg = msgs.messages[i];
 
216
 
 
217
            msg_datetime.clear();
 
218
            msg_project.clear();
 
219
            msg_priority.clear();
 
220
            msg_type.clear();
 
221
            msg_body.clear();
 
222
 
 
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);
 
229
            }
 
230
 
 
231
            // If a message type is found in the message body, remove it from
 
232
            // the message body
 
233
            if (!msg_type.empty()) {
 
234
                msg_tmp = std::string("[") + msg_type + std::string("] ");
 
235
                msg_body.replace(0, msg_tmp.size(), "");
 
236
            }
 
237
 
 
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] = ' ';
 
243
            }
 
244
 
 
245
            // If line feeds are detected in the message body, replace them with
 
246
            // the pipe symbol.
 
247
            for (unsigned int j = 0; j < msg_body.size(); j++) {
 
248
                if (msg_body[j] == '\n') {
 
249
                    msg_body[j] = '^';
 
250
                }
 
251
            }
 
252
 
 
253
            // Dump to tab delimited file
 
254
            fprintf(f, 
 
255
                "%s\t%s\t%s\t%s\t%s\n",
 
256
                msg_datetime.c_str(),
 
257
                msg_priority.c_str(),
 
258
                msg_project.c_str(),
 
259
                msg_type.c_str(),
 
260
                msg_body.c_str()
 
261
            );
 
262
 
 
263
            g_message_sequence = pMsg->seqno;
 
264
        }
 
265
 
 
266
        boinc_sleep(1.0);
 
267
    }
 
268
 
 
269
#if defined(_WIN32) && defined(USE_WINSOCK)
 
270
    WSACleanup();
 
271
#endif
 
272
    exit(retval);
 
273
}