]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/wx-console/console_thread.cpp
- console_thread : Added support for the new parse_config which returns a status...
[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 #include "console_thread.h" // class's header file
27
28 #include <wx/wxprec.h>
29
30 #include <wx/thread.h>
31 #include <bacula.h>
32 #include <jcr.h>
33
34 #include "console_conf.h"
35
36 #include "csprint.h"
37
38 #ifdef HAVE_WIN32
39 #include <windows.h>
40 DWORD  g_platform_id = VER_PLATFORM_WIN32_WINDOWS;
41 char OK_msg[]   = "2000 OK\n";
42 char TERM_msg[] = "2999 Terminate\n";
43 #endif
44
45 /* Imported functions */
46 int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
47
48 // class constructor
49 console_thread::console_thread(wxString configfile) {
50    UA_sock = NULL;
51    this->configfile = configfile;
52 }
53
54 // class destructor
55 console_thread::~console_thread() {
56    if (UA_sock) {
57       bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
58       bnet_close(UA_sock);
59       UA_sock = NULL;
60    }
61    if (WSACleanup() == 0) {
62       //csprint("Windows sockets cleaned up successfully...\n");
63    }
64    else {
65       csprint("Error while cleaning up windows sockets...\n");
66    }
67 }
68
69 /*
70  * Thread entry point
71  */
72 void* console_thread::Entry() {
73    if (WSA_Init() == 0) {
74       //csprint("Windows sockets initialized successfully...\n");
75    }
76    else {
77       csprint("Error while initializing windows sockets...\n");
78    }
79
80    csprint("Connecting...\n");
81
82    init_stack_dump();
83    my_name_is(0, NULL, "wx-console");
84    //textdomain("bacula-console");
85    
86    MSGS* msgs = (MSGS *)malloc(sizeof(MSGS));
87    memset(msgs, 0, sizeof(MSGS));
88    for (int i=1; i<=M_MAX; i++) {
89 #ifndef WIN32
90       add_msg_dest(msgs, MD_STDOUT, i, NULL, NULL);
91 #endif
92       add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
93       add_msg_dest(msgs, MD_CONSOLE, i, NULL, NULL);
94    }
95    
96    init_msg(NULL, msgs);
97    init_console_msg(".");
98
99    /* TODO (#4#): Allow the user to choose his config file. */
100    if (!parse_config(configfile.c_str(), 0)) {
101       csprint("Unable to read configuration file.\n");
102       csprint(NULL, CS_END);
103       csprint(NULL, CS_DISCONNECTED);
104       csprint(NULL, CS_TERMINATED);
105       #ifdef HAVE_WIN32
106          Exit();
107       #endif
108       return NULL;
109    }
110    
111    init_msg(NULL, NULL);
112    
113    LockRes();
114    DIRRES *dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
115    UnlockRes();
116
117    memset(&jcr, 0, sizeof(jcr));
118    
119    jcr.dequeuing = 1; /* TODO: catch messages */
120
121    UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon", dir->address, NULL, dir->DIRport, 0);
122    if (UA_sock == NULL) {
123       csprint("Failed to connect to the director\n");
124       csprint(NULL, CS_END);
125       csprint(NULL, CS_DISCONNECTED);
126       csprint(NULL, CS_TERMINATED);
127       #ifdef HAVE_WIN32
128          Exit();
129       #endif
130       return NULL;
131    }
132
133    csprint("Connected\n");
134
135    jcr.dir_bsock = UA_sock;
136    LockRes();
137    /* If cons==NULL, default console will be used */
138    CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
139    UnlockRes();
140    if (!authenticate_director(&jcr, dir, cons)) {
141       csprint("ERR=");
142       csprint(UA_sock->msg);
143       csprint(NULL, CS_END);
144       csprint(NULL, CS_DISCONNECTED);
145       csprint(NULL, CS_TERMINATED);
146       #ifdef HAVE_WIN32
147          Exit();
148       #endif
149       return NULL;
150    }
151    
152    csprint(NULL, CS_CONNECTED);
153    
154    Write("messages\n");
155
156    int stat;
157
158    /* main loop */
159    while(!TestDestroy()) {   /* Tests if thread has been ended */
160       if ((stat = bnet_recv(UA_sock)) >= 0) {
161          csprint(UA_sock->msg);
162       }
163       else if (stat == BNET_SIGNAL) {
164          if (UA_sock->msglen == BNET_PROMPT) {
165             csprint(NULL, CS_PROMPT);
166          }
167          else if (UA_sock->msglen == BNET_EOD) {
168             csprint(NULL, CS_END);
169          }
170          else if (UA_sock->msglen == BNET_HEARTBEAT) {
171             bnet_sig(UA_sock, BNET_HB_RESPONSE);
172             csprint("<< Heartbeat signal received, answered. >>\n", CS_DEBUG);
173          }
174          else {
175             csprint("<< Unexpected signal received : ", CS_DEBUG);
176             csprint(bnet_sig_to_ascii(UA_sock), CS_DEBUG);
177             csprint(">>\n", CS_DEBUG);
178          }
179       }
180       else { /* BNET_HARDEOF || BNET_ERROR */
181          csprint(NULL, CS_END);
182          break;
183       }
184            
185       if (is_bnet_stop(UA_sock)) {
186          csprint(NULL, CS_END);
187          break;            /* error or term */
188       }
189    }
190    
191    csprint(NULL, CS_DISCONNECTED);
192
193    csprint("Connection terminated\n");
194    
195    UA_sock = NULL;
196
197    csprint(NULL, CS_TERMINATED);
198
199    #ifdef HAVE_WIN32
200       Exit();
201    #endif
202    
203    return NULL;
204 }
205
206 void console_thread::Write(const char* str) {
207    if (UA_sock) {
208        UA_sock->msglen = strlen(str);
209        pm_strcpy(&UA_sock->msg, str);
210        bnet_send(UA_sock);
211    }
212 }
213
214 void console_thread::Delete() {
215    Write("quit\n");
216    if (UA_sock) {
217       bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
218       bnet_close(UA_sock);
219       UA_sock = NULL;
220       csprint(NULL, CS_END);
221       csprint(NULL, CS_DISCONNECTED);
222       csprint(NULL, CS_TERMINATED);
223    }
224 }