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