]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_server.c
86dbc0f36d17b29a52e51e58bb561171c90e0a08
[bacula/bacula] / bacula / src / dird / ua_server.c
1 /*
2  *
3  *   Bacula Director -- User Agent Server
4  *
5  *     Kern Sibbald, September MM
6  *
7  *    Version $Id$
8  */
9
10 /*
11    Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License as
15    published by the Free Software Foundation; either version 2 of
16    the License, or (at your option) any later version.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21    General Public License for more details.
22
23    You should have received a copy of the GNU General Public
24    License along with this program; if not, write to the Free
25    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26    MA 02111-1307, USA.
27
28  */
29
30 #include "bacula.h"
31 #include "dird.h"
32 #include "ua.h"
33
34 /* Imported subroutines */
35 extern void run_job(JCR *jcr);
36
37 /* Imported variables */
38 extern int r_first;
39 extern int r_last;
40 extern struct s_res resources[];
41 extern int console_msg_pending;
42 extern FILE *con_fd;
43 extern char my_name[];
44
45 /* Static variables */
46
47 /* Exported variables */
48 int quit_cmd_thread = 0;
49
50 /* Imported functions */
51
52 /* Forward referenced functions */
53
54 static void *connect_thread(void *arg);
55 static void handle_UA_client_request(void *arg);
56
57
58 /* Global variables */
59 static int started = FALSE;
60 static workq_t ua_workq;
61
62 /* Called here by Director daemon to start UA (user agent)
63  * command thread. This routine creates the thread and then
64  * returns.
65  */
66 void start_UA_server(int UA_port)
67 {
68    pthread_t thid;
69    int status;
70
71    set_thread_concurrency(4);
72    if ((status=pthread_create(&thid, NULL, connect_thread, (void *)UA_port)) != 0) {
73       Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), strerror(status));
74    }
75    started = TRUE;
76    return;
77 }
78
79 static void *connect_thread(void *arg)
80 {
81    int UA_port = (int)arg;
82
83    pthread_detach(pthread_self());
84
85    bnet_thread_server(UA_port, 5, &ua_workq, handle_UA_client_request);
86    return NULL;
87 }
88
89 /*
90  * Handle Director User Agent commands   
91  *
92  */
93 static void handle_UA_client_request(void *arg)
94 {
95    int stat;
96    static char cmd[1000];
97    UAContext ua;
98    BSOCK *UA_sock = (BSOCK *) arg;
99
100    pthread_detach(pthread_self());
101
102    memset(&ua, 0, sizeof(ua));
103    ua.automount = TRUE;
104    ua.verbose = 1;
105    ua.jcr = new_jcr(sizeof(JCR), dird_free_jcr);
106    ua.jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */
107    ua.UA_sock = UA_sock;
108    ua.cmd = get_pool_memory(PM_FNAME);
109    ua.args = get_pool_memory(PM_FNAME);
110
111    create_unique_job_name(ua.jcr, "*Console*");
112    ua.jcr->sched_time = ua.jcr->start_time;
113    ua.jcr->JobType = JT_CONSOLE;
114
115    bnet_recv(ua.UA_sock);          /* Get first message */
116    if (!authenticate_user_agent(ua.UA_sock)) {
117       goto getout;
118    }
119
120    while (!ua.quit) {
121       stat = bnet_recv(ua.UA_sock);
122       if (stat > 0) {
123          strncpy(cmd, ua.UA_sock->msg, sizeof(cmd));
124          cmd[sizeof(cmd)-1] = 0;       /* ensure it is terminated/trucated */
125          parse_command_args(&ua);
126          if (ua.argc > 0 && ua.argk[0][0] == '.') {
127             do_a_dot_command(&ua, cmd);
128          } else {
129             do_a_command(&ua, cmd);
130          }
131          if (!ua.quit) {
132             if (ua.auto_display_messages) {
133                strcpy(cmd, "messages");
134                qmessagescmd(&ua, cmd);
135                ua.user_notified_msg_pending = FALSE;
136             } else if (!ua.user_notified_msg_pending && console_msg_pending) {
137                bsendmsg(&ua, _("You have messages.\n"));
138                ua.user_notified_msg_pending = TRUE;
139             }
140             bnet_sig(ua.UA_sock, BNET_EOD); /* send end of command */
141          }
142       } else if (stat == 0) {
143          if (ua.UA_sock->msglen == BNET_TERMINATE) {
144             ua.quit = TRUE;
145             break;
146          }
147          bnet_sig(ua.UA_sock, BNET_POLL);
148       } else {
149          break;                    /* error, exit */
150       }
151    }
152
153 getout:
154    if (ua.UA_sock) {
155       bnet_close(ua.UA_sock);
156       ua.UA_sock = NULL;
157    }
158
159    close_db(&ua);                     /* do this before freeing JCR */
160
161    if (ua.jcr) {
162       free_jcr(ua.jcr);
163       ua.jcr = NULL;
164    }
165    if (ua.prompt) {
166       free(ua.prompt);
167    }
168    if (ua.cmd) {
169       free_pool_memory(ua.cmd);
170    }
171    if (ua.args) {
172       free_pool_memory(ua.args);
173    }
174    return;
175 }
176
177 /*
178  * Called from main Bacula thread 
179  */
180 void term_ua_server()
181 {
182    if (!started) {
183       return;
184    }
185    quit_cmd_thread = TRUE;
186 }