3 * Bacula Director -- User Agent Server
5 * Kern Sibbald, September MM
9 Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
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.
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.
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,
32 /* Imported subroutines */
33 extern void run_job(JCR *jcr);
35 /* Imported variables */
38 extern struct s_res resources[];
39 extern int console_msg_pending;
41 extern char my_name[];
43 /* Static variables */
45 /* Exported variables */
46 int quit_cmd_thread = 0;
48 /* Imported functions */
50 /* Forward referenced functions */
52 static void *connect_thread(void *arg);
53 static void handle_UA_client_request(void *arg);
56 /* Global variables */
57 static int started = FALSE;
58 static workq_t ua_workq;
60 /* Called here by Director daemon to start UA (user agent)
61 * command thread. This routine creates the thread and then
64 void start_UA_server(int UA_port)
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));
77 static void *connect_thread(void *arg)
79 int UA_port = (int)arg;
81 pthread_detach(pthread_self());
83 bnet_thread_server(UA_port, 5, &ua_workq, handle_UA_client_request);
88 * Handle Director User Agent commands
91 static void handle_UA_client_request(void *arg)
94 static char cmd[1000];
96 BSOCK *UA_sock = (BSOCK *) arg;
98 pthread_detach(pthread_self());
100 memset(&ua, 0, sizeof(ua));
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);
109 create_unique_job_name(ua.jcr, "*Console*");
110 ua.jcr->sched_time = ua.jcr->start_time;
111 ua.jcr->JobType = JT_CONSOLE;
113 bnet_recv(ua.UA_sock); /* Get first message */
114 if (!authenticate_user_agent(ua.UA_sock)) {
120 stat = bnet_recv(ua.UA_sock);
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);
128 quit = !do_a_command(&ua, cmd);
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;
139 bnet_sig(ua.UA_sock, BNET_EOD); /* send end of command */
141 } else if (stat == 0) {
142 if (ua.UA_sock->msglen == BNET_TERMINATE) {
145 bnet_sig(ua.UA_sock, BNET_POLL);
147 break; /* error, exit */
153 bnet_close(ua.UA_sock);
157 close_db(&ua); /* do this before freeing JCR */
167 free_pool_memory(ua.cmd);
170 free_pool_memory(ua.args);
176 * Called from main Bacula thread
178 void term_ua_server()
183 quit_cmd_thread = TRUE;