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 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
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 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 // 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
29 #include "console_thread.h" // class's header file
31 #include <wx/wxprec.h>
33 #include <wx/thread.h>
38 #include "console_conf.h"
44 char OK_msg[] = "2000 OK\n";
45 char TERM_msg[] = "2999 Terminate\n";
48 /* Imported functions */
49 int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
51 bool console_thread::inited = false;
52 bool console_thread::configloaded = false;
53 wxString console_thread::working_dir = wxT(".");
55 void console_thread::SetWorkingDirectory(wxString w_dir) {
56 if ((w_dir.Last() == '/') || (w_dir.Last() == '\\')) {
57 console_thread::working_dir = w_dir.Mid(0, w_dir.Length()-1);
60 console_thread::working_dir = w_dir;
64 void console_thread::InitLib() {
65 if (WSA_Init() != 0) {
66 csprint("Error while initializing windows sockets...\n");
72 my_name_is(0, NULL, "wx-console");
73 //textdomain("bacula-console");
74 working_directory = (const char*) console_thread::working_dir.GetData();
79 void console_thread::FreeLib() {
81 if (WSACleanup() != 0) {
82 csprint("Error while cleaning up windows sockets...\n");
90 * Format a scanner error message
92 static void scan_err(const char *file, int line, LEX *lc, const char *msg, ...)
99 va_start(arg_ptr, msg);
100 bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
103 if (lc->line_no > lc->begin_line_no) {
104 bsnprintf(more, sizeof(more),
105 _("Problem probably begins at line %d.\n"), lc->begin_line_no);
110 err.Format(wxT("Config error: %s\n : line %d, col %d of file %s\n%s\n%s"),
111 buf, lc->line_no, lc->col_no, lc->fname, lc->line, more);
116 wxString console_thread::LoadConfig(wxString configfile) {
120 return wxT("Error while initializing library.");
123 free_config_resources();
125 MSGS* msgs = (MSGS *)malloc(sizeof(MSGS));
126 memset(msgs, 0, sizeof(MSGS));
127 for (int i=1; i<=M_MAX; i++) {
129 add_msg_dest(msgs, MD_STDOUT, i, NULL, NULL);
131 add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
132 add_msg_dest(msgs, MD_CONSOLE, i, NULL, NULL);
135 init_msg(NULL, msgs);
136 init_console_msg(console_thread::working_dir.mb_str(*wxConvCurrent));
139 if (!parse_config(configfile.mb_str(*wxConvCurrent), &scan_err)) {
140 configloaded = false;
146 wxRemoveFile(console_thread::working_dir + wxT("/wx-console.conmsg"));
147 init_msg(NULL, NULL);
155 console_thread::console_thread() {
157 choosingdirector = false;
161 console_thread::~console_thread() {
163 bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
172 void* console_thread::Entry() {
174 csprint("Error : Library not initialized\n");
175 csprint(NULL, CS_END);
176 csprint(NULL, CS_DISCONNECTED);
177 csprint(NULL, CS_TERMINATED);
185 csprint("Error : No configuration file loaded\n");
186 csprint(NULL, CS_END);
187 csprint(NULL, CS_DISCONNECTED);
188 csprint(NULL, CS_TERMINATED);
195 csprint("Connecting...\n");
198 DIRRES* res[16]; /* Maximum 16 directors */
202 foreach_res(dir, R_DIRECTOR) {
212 csprint("Error : No director defined in config file.\n");
213 csprint(NULL, CS_END);
214 csprint(NULL, CS_DISCONNECTED);
215 csprint(NULL, CS_TERMINATED);
221 else if (count == 1) {
226 csprint("Multiple directors found in your config file.\n");
227 for (int i = 0; i < count; i++) {
229 csprint(wxString(wxT(" ")) << (i+1) << wxT(": ") << wxString(res[i]->hdr.name,*wxConvCurrent) << wxT("\n"));
232 csprint(wxString(wxT(" ")) << (i+1) << wxT(": ") << wxString(res[i]->hdr.name,*wxConvCurrent) << wxT("\n"));
235 csprint(wxString(wxT("Please choose a director (1-")) << count << wxT(") : "),CS_DATA);
236 csprint(NULL, CS_PROMPT);
237 choosingdirector = true;
238 directorchoosen = -1;
239 while(directorchoosen == -1) {
240 bmicrosleep(0, 2000);
243 choosingdirector = false;
244 if (directorchoosen != 0) {
250 memset(&jcr, 0, sizeof(jcr));
252 jcr.dequeuing = 1; /* TODO: catch messages */
254 UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon",
255 res[directorchoosen-1]->address, NULL, res[directorchoosen-1]->DIRport, 0);
257 if (UA_sock == NULL) {
258 csprint("Failed to connect to the director\n");
259 csprint(NULL, CS_END);
260 csprint(NULL, CS_DISCONNECTED);
261 csprint(NULL, CS_TERMINATED);
268 csprint("Connected\n");
270 jcr.dir_bsock = UA_sock;
272 /* If cons==NULL, default console will be used */
273 CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
275 if (!authenticate_director(&jcr, res[directorchoosen-1], cons)) {
277 csprint(UA_sock->msg);
278 csprint(NULL, CS_END);
279 csprint(NULL, CS_DISCONNECTED);
280 csprint(NULL, CS_TERMINATED);
287 csprint(NULL, CS_CONNECTED);
289 Write(".messages\n");
294 while(!TestDestroy()) { /* Tests if thread has been ended */
295 if ((stat = bnet_recv(UA_sock)) >= 0) {
296 csprint(UA_sock->msg);
298 else if (stat == BNET_SIGNAL) {
299 if (UA_sock->msglen == BNET_PROMPT) {
300 csprint(NULL, CS_PROMPT);
302 else if (UA_sock->msglen == BNET_EOD) {
303 csprint(NULL, CS_END);
305 else if (UA_sock->msglen == BNET_HEARTBEAT) {
306 bnet_sig(UA_sock, BNET_HB_RESPONSE);
307 csprint("<< Heartbeat signal received, answered. >>\n", CS_DEBUG);
310 csprint("<< Unexpected signal received : ", CS_DEBUG);
311 csprint(bnet_sig_to_ascii(UA_sock), CS_DEBUG);
312 csprint(">>\n", CS_DEBUG);
315 else { /* BNET_HARDEOF || BNET_ERROR */
316 csprint(NULL, CS_END);
320 if (is_bnet_stop(UA_sock)) {
321 csprint(NULL, CS_END);
322 break; /* error or term */
326 csprint(NULL, CS_DISCONNECTED);
328 csprint("Connection terminated\n");
332 csprint(NULL, CS_TERMINATED);
341 void console_thread::Write(const char* str) {
343 UA_sock->msglen = strlen(str);
344 pm_strcpy(&UA_sock->msg, str);
347 else if (choosingdirector) {
349 // wxString number = str;
350 // number.RemoveLast(); /* Removes \n */
353 // if (number.ToLong(&val)) {
354 if (val = atol(str)) {
355 directorchoosen = (int)val;
363 void console_thread::Delete() {
366 bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
369 /*csprint(NULL, CS_END);
370 csprint(NULL, CS_DISCONNECTED);
371 csprint(NULL, CS_TERMINATED);*/