]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/wx-console/console_thread.cpp
- wxbMainFrame : reconnecting/disconnecting implemented
[bacula/bacula] / bacula / src / wx-console / console_thread.cpp
1 /*
2  *
3  *    Interaction thread between director and the GUI
4  *
5  *    Nicolas Boichat, April 2004
6  *
7  */
8 /*
9    Copyright (C) 2004 Kern Sibbald and John Walker
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    as published by the Free Software Foundation; either version 2
14    of the License, or (at your option) any later version.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 // 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
27
28 #include "console_thread.h" // class's header file
29
30 #include <wx/wxprec.h>
31
32 #include <wx/thread.h>
33 #include <wx/file.h>
34 #include <bacula.h>
35 #include <jcr.h>
36
37 #include "console_conf.h"
38
39 #include "csprint.h"
40
41 #ifdef HAVE_WIN32
42 #include <windows.h>
43 DWORD  g_platform_id = VER_PLATFORM_WIN32_WINDOWS;
44 char OK_msg[]   = "2000 OK\n";
45 char TERM_msg[] = "2999 Terminate\n";
46 #endif
47
48 /* Imported functions */
49 int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
50
51 bool console_thread::inited = false;
52 bool console_thread::configloaded = false;
53
54 void console_thread::InitLib() {
55    if (WSA_Init() != 0) {
56       csprint("Error while initializing windows sockets...\n");
57       inited = false;
58       return;
59    }
60    
61    init_stack_dump();
62    my_name_is(0, NULL, "wx-console");
63    //textdomain("bacula-console");
64    
65    inited = true;
66 }
67
68 void console_thread::FreeLib() {
69    if (inited) {
70       if (WSACleanup() != 0) {
71          csprint("Error while cleaning up windows sockets...\n");
72       }
73    }
74 }
75
76 wxString console_thread::LoadConfig(wxString configfile) {
77    if (!inited) {
78       InitLib();
79       if (!inited)
80          return "Error while initializing library.";
81    }
82    
83    MSGS* msgs = (MSGS *)malloc(sizeof(MSGS));
84    memset(msgs, 0, sizeof(MSGS));
85    for (int i=1; i<=M_MAX; i++) {
86 #ifndef WIN32
87       add_msg_dest(msgs, MD_STDOUT, i, NULL, NULL);
88 #endif
89       add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
90       add_msg_dest(msgs, MD_CONSOLE, i, NULL, NULL);
91    }
92    
93    init_msg(NULL, msgs);
94    init_console_msg(".");
95
96    /* TODO (#4#): Allow the user to choose his config file. */
97    if (!parse_config(configfile.c_str(), 0)) {
98       configloaded = false;
99       wxFile file("./wx-console.conmsg");
100       if (!file.IsOpened())
101          return "Unable to retrieve error message.";
102       wxString err = "";
103       wxChar buffer[513];
104       off_t len;
105       while ((len = file.Read(buffer, 512)) > -1) {
106          buffer[len] = (wxChar)0;
107          err += buffer;
108          if (file.Eof())
109             break;
110       }
111       file.Close();
112       term_msg();
113       wxRemoveFile("./wx-console.conmsg");
114       return err;
115    }
116    
117    term_msg();
118    wxRemoveFile("./wx-console.conmsg");
119    init_msg(NULL, NULL);
120    
121    configloaded = true;
122    
123    return "";
124 }
125
126 // class constructor
127 console_thread::console_thread() {
128    UA_sock = NULL;
129 }
130
131 // class destructor
132 console_thread::~console_thread() {
133    if (UA_sock) {
134       bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
135       bnet_close(UA_sock);
136       UA_sock = NULL;
137    }
138 }
139
140 /*
141  * Thread entry point
142  */
143 void* console_thread::Entry() {
144    if (!inited) {
145       csprint("Error : Library not initialized\n");
146       csprint(NULL, CS_END);
147       csprint(NULL, CS_DISCONNECTED);
148       csprint(NULL, CS_TERMINATED);
149       #ifdef HAVE_WIN32
150          Exit();
151       #endif
152       return NULL;
153    }
154    
155    if (!configloaded) {
156       csprint("Error : No configuration file loaded\n");
157       csprint(NULL, CS_END);
158       csprint(NULL, CS_DISCONNECTED);
159       csprint(NULL, CS_TERMINATED);
160       #ifdef HAVE_WIN32
161          Exit();
162       #endif
163       return NULL;
164    }
165    
166    csprint("Connecting...\n");
167   
168    LockRes();
169    DIRRES *dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
170    UnlockRes();
171
172    memset(&jcr, 0, sizeof(jcr));
173    
174    jcr.dequeuing = 1; /* TODO: catch messages */
175
176    UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon", dir->address, NULL, dir->DIRport, 0);
177    if (UA_sock == NULL) {
178       csprint("Failed to connect to the director\n");
179       csprint(NULL, CS_END);
180       csprint(NULL, CS_DISCONNECTED);
181       csprint(NULL, CS_TERMINATED);
182       #ifdef HAVE_WIN32
183          Exit();
184       #endif
185       return NULL;
186    }
187
188    csprint("Connected\n");
189
190    jcr.dir_bsock = UA_sock;
191    LockRes();
192    /* If cons==NULL, default console will be used */
193    CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
194    UnlockRes();
195    if (!authenticate_director(&jcr, dir, cons)) {
196       csprint("ERR=");
197       csprint(UA_sock->msg);
198       csprint(NULL, CS_END);
199       csprint(NULL, CS_DISCONNECTED);
200       csprint(NULL, CS_TERMINATED);
201       #ifdef HAVE_WIN32
202          Exit();
203       #endif
204       return NULL;
205    }
206    
207    csprint(NULL, CS_CONNECTED);
208    
209    Write("messages\n");
210
211    int stat;
212
213    /* main loop */
214    while(!TestDestroy()) {   /* Tests if thread has been ended */
215       if ((stat = bnet_recv(UA_sock)) >= 0) {
216          csprint(UA_sock->msg);
217       }
218       else if (stat == BNET_SIGNAL) {
219          if (UA_sock->msglen == BNET_PROMPT) {
220             csprint(NULL, CS_PROMPT);
221          }
222          else if (UA_sock->msglen == BNET_EOD) {
223             csprint(NULL, CS_END);
224          }
225          else if (UA_sock->msglen == BNET_HEARTBEAT) {
226             bnet_sig(UA_sock, BNET_HB_RESPONSE);
227             csprint("<< Heartbeat signal received, answered. >>\n", CS_DEBUG);
228          }
229          else {
230             csprint("<< Unexpected signal received : ", CS_DEBUG);
231             csprint(bnet_sig_to_ascii(UA_sock), CS_DEBUG);
232             csprint(">>\n", CS_DEBUG);
233          }
234       }
235       else { /* BNET_HARDEOF || BNET_ERROR */
236          csprint(NULL, CS_END);
237          break;
238       }
239            
240       if (is_bnet_stop(UA_sock)) {
241          csprint(NULL, CS_END);
242          break;            /* error or term */
243       }
244    }
245    
246    csprint(NULL, CS_DISCONNECTED);
247
248    csprint("Connection terminated\n");
249    
250    UA_sock = NULL;
251
252    csprint(NULL, CS_TERMINATED);
253
254    #ifdef HAVE_WIN32
255       Exit();
256    #endif
257    
258    return NULL;
259 }
260
261 void console_thread::Write(const char* str) {
262    if (UA_sock) {
263        UA_sock->msglen = strlen(str);
264        pm_strcpy(&UA_sock->msg, str);
265        bnet_send(UA_sock);
266    }
267 }
268
269 void console_thread::Delete() {
270    Write("quit\n");
271    if (UA_sock) {
272       bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
273       bnet_close(UA_sock);
274       UA_sock = NULL;
275       csprint(NULL, CS_END);
276       csprint(NULL, CS_DISCONNECTED);
277       csprint(NULL, CS_TERMINATED);
278    }
279 }