3 * Interaction thread between director and the GUI
5 * Nicolas Boichat, April 2004
10 Copyright (C) 2004-2005 Kern Sibbald
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 version 2 as ammended with additional clauses defined in the
15 file LICENSE in the main source directory.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 the file LICENSE for additional details.
24 // http://66.102.9.104/search?q=cache:Djc1mPF3hRoJ:cvs.sourceforge.net/viewcvs.py/audacity/audacity-src/src/AudioIO.cpp%3Frev%3D1.102+macos+x+wxthread&hl=fr
26 #include "console_thread.h" // class's header file
28 #include <wx/wxprec.h>
30 #include <wx/thread.h>
35 #include "console_conf.h"
41 char OK_msg[] = "2000 OK\n";
42 char TERM_msg[] = "2999 Terminate\n";
45 /* Imported functions */
46 int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
48 bool console_thread::inited = false;
49 bool console_thread::configloaded = false;
50 wxString console_thread::working_dir = wxT(".");
52 void console_thread::SetWorkingDirectory(wxString w_dir) {
53 if ((w_dir.Last() == '/') || (w_dir.Last() == '\\')) {
54 console_thread::working_dir = w_dir.Mid(0, w_dir.Length()-1);
57 console_thread::working_dir = w_dir;
61 void console_thread::InitLib() {
62 if (WSA_Init() != 0) {
63 csprint("Error while initializing windows sockets...\n");
69 my_name_is(0, NULL, "wx-console");
70 //textdomain("bacula-console");
71 working_directory = (const char*) console_thread::working_dir.GetData();
76 void console_thread::FreeLib() {
78 if (WSACleanup() != 0) {
79 csprint("Error while cleaning up windows sockets...\n");
87 * Format a scanner error message
89 static void scan_err(const char *file, int line, LEX *lc, const char *msg, ...)
96 va_start(arg_ptr, msg);
97 bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
100 if (lc->line_no > lc->begin_line_no) {
101 bsnprintf(more, sizeof(more),
102 _("Problem probably begins at line %d.\n"), lc->begin_line_no);
107 err.Format(wxT("Config error: %s\n : line %d, col %d of file %s\n%s\n%s"),
108 buf, lc->line_no, lc->col_no, lc->fname, lc->line, more);
113 wxString console_thread::LoadConfig(wxString configfile) {
117 return wxT("Error while initializing library.");
120 free_config_resources();
122 MSGS* msgs = (MSGS *)malloc(sizeof(MSGS));
123 memset(msgs, 0, sizeof(MSGS));
124 for (int i=1; i<=M_MAX; i++) {
126 add_msg_dest(msgs, MD_STDOUT, i, NULL, NULL);
128 // add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
129 add_msg_dest(msgs, MD_CONSOLE, i, NULL, NULL);
132 init_msg(NULL, msgs);
133 init_console_msg(console_thread::working_dir.mb_str(*wxConvCurrent));
136 if (!parse_config(configfile.mb_str(*wxConvCurrent), &scan_err)) {
137 configloaded = false;
143 wxRemoveFile(console_thread::working_dir + wxT("/wx-console.conmsg"));
144 init_msg(NULL, NULL);
152 console_thread::console_thread() {
154 choosingdirector = false;
158 console_thread::~console_thread() {
160 bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
169 void* console_thread::Entry() {
171 csprint("Error : Library not initialized\n");
172 csprint(NULL, CS_END);
173 csprint(NULL, CS_DISCONNECTED);
174 csprint(NULL, CS_TERMINATED);
182 csprint("Error : No configuration file loaded\n");
183 csprint(NULL, CS_END);
184 csprint(NULL, CS_DISCONNECTED);
185 csprint(NULL, CS_TERMINATED);
192 csprint("Connecting...\n");
195 DIRRES* res[16]; /* Maximum 16 directors */
199 foreach_res(dir, R_DIRECTOR) {
209 csprint("Error : No director defined in config file.\n");
210 csprint(NULL, CS_END);
211 csprint(NULL, CS_DISCONNECTED);
212 csprint(NULL, CS_TERMINATED);
218 else if (count == 1) {
223 csprint("Multiple directors found in your config file.\n");
224 for (int i = 0; i < count; i++) {
226 csprint(wxString(wxT(" ")) << (i+1) << wxT(": ") << wxString(res[i]->hdr.name,*wxConvCurrent) << wxT("\n"));
229 csprint(wxString(wxT(" ")) << (i+1) << wxT(": ") << wxString(res[i]->hdr.name,*wxConvCurrent) << wxT("\n"));
232 csprint(wxString(wxT("Please choose a director (1-")) << count << wxT(") : "),CS_DATA);
233 csprint(NULL, CS_PROMPT);
234 choosingdirector = true;
235 directorchoosen = -1;
236 while(directorchoosen == -1) {
237 bmicrosleep(0, 2000);
240 choosingdirector = false;
241 if (directorchoosen != 0) {
247 memset(&jcr, 0, sizeof(jcr));
249 jcr.dequeuing = 1; /* TODO: catch messages */
251 UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon",
252 res[directorchoosen-1]->address, NULL, res[directorchoosen-1]->DIRport, 0);
254 if (UA_sock == NULL) {
255 csprint("Failed to connect to the director\n");
256 csprint(NULL, CS_END);
257 csprint(NULL, CS_DISCONNECTED);
258 csprint(NULL, CS_TERMINATED);
265 csprint("Connected\n");
267 jcr.dir_bsock = UA_sock;
269 /* If cons==NULL, default console will be used */
270 CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
272 if (!authenticate_director(&jcr, res[directorchoosen-1], cons)) {
274 csprint(UA_sock->msg);
275 csprint(NULL, CS_END);
276 csprint(NULL, CS_DISCONNECTED);
277 csprint(NULL, CS_TERMINATED);
284 csprint(NULL, CS_CONNECTED);
286 Write(".messages\n");
291 while(!TestDestroy()) { /* Tests if thread has been ended */
292 if ((stat = bnet_recv(UA_sock)) >= 0) {
293 csprint(UA_sock->msg);
295 else if (stat == BNET_SIGNAL) {
296 if (UA_sock->msglen == BNET_PROMPT) {
297 csprint(NULL, CS_PROMPT);
299 else if (UA_sock->msglen == BNET_EOD) {
300 csprint(NULL, CS_END);
302 else if (UA_sock->msglen == BNET_HEARTBEAT) {
303 bnet_sig(UA_sock, BNET_HB_RESPONSE);
304 csprint("<< Heartbeat signal received, answered. >>\n", CS_DEBUG);
307 csprint("<< Unexpected signal received : ", CS_DEBUG);
308 csprint(bnet_sig_to_ascii(UA_sock), CS_DEBUG);
309 csprint(">>\n", CS_DEBUG);
312 else { /* BNET_HARDEOF || BNET_ERROR */
313 csprint(NULL, CS_END);
317 if (is_bnet_stop(UA_sock)) {
318 csprint(NULL, CS_END);
319 break; /* error or term */
323 csprint(NULL, CS_DISCONNECTED);
325 csprint("Connection terminated\n");
329 csprint(NULL, CS_TERMINATED);
338 void console_thread::Write(const char* str) {
340 UA_sock->msglen = strlen(str);
341 pm_strcpy(&UA_sock->msg, str);
344 else if (choosingdirector) {
346 // wxString number = str;
347 // number.RemoveLast(); /* Removes \n */
350 // if (number.ToLong(&val)) {
351 if (val = atol(str)) {
352 directorchoosen = (int)val;
360 void console_thread::Delete() {
363 bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
366 /*csprint(NULL, CS_END);
367 csprint(NULL, CS_DISCONNECTED);
368 csprint(NULL, CS_TERMINATED);*/