3 * Bacula Director -- User Agent Server
5 * Kern Sibbald, September MM
11 Copyright (C) 2000-2005 Kern Sibbald
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.
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.
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,
33 /* Imported variables */
36 extern struct s_res resources[];
37 extern int console_msg_pending;
38 extern char my_name[];
41 /* Forward referenced functions */
42 extern "C" void *connect_thread(void *arg);
43 static void *handle_UA_client_request(void *arg);
46 /* Global variables */
47 static int started = FALSE;
48 static workq_t ua_workq;
55 /* Called here by Director daemon to start UA (user agent)
56 * command thread. This routine creates the thread and then
59 void start_UA_server(dlist *addrs)
63 static dlist *myaddrs = addrs;
65 if ((status=pthread_create(&thid, NULL, connect_thread, (void *)myaddrs)) != 0) {
67 Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), be.strerror(status));
74 void *connect_thread(void *arg)
76 pthread_detach(pthread_self());
78 /* Permit 10 console connections */
79 bnet_thread_server((dlist*)arg, 10, &ua_workq, handle_UA_client_request);
84 * Create a Job Control Record for a control "job",
85 * filling in all the appropriate fields.
87 JCR *new_control_jcr(const char *base_name, int job_type)
90 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
92 * The job and defaults are not really used, but
93 * we set them up to ensure that everything is correctly
97 jcr->job = (JOB *)GetNextRes(R_JOB, NULL);
98 set_jcr_defaults(jcr, jcr->job);
100 jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */
101 create_unique_job_name(jcr, base_name);
102 jcr->sched_time = jcr->start_time;
103 jcr->JobType = job_type;
104 jcr->JobLevel = L_NONE;
105 jcr->JobStatus = JS_Running;
111 * Handle Director User Agent commands
114 static void *handle_UA_client_request(void *arg)
120 pthread_detach(pthread_self());
122 jcr = new_control_jcr("*Console*", JT_CONSOLE);
124 ua = new_ua_context(jcr);
125 ua->UA_sock = (BSOCK *)arg;
127 bnet_recv(ua->UA_sock); /* Get first message */
128 if (!authenticate_user_agent(ua)) {
133 stat = bnet_recv(ua->UA_sock);
135 pm_strcpy(ua->cmd, ua->UA_sock->msg);
137 if (ua->argc > 0 && ua->argk[0][0] == '.') {
138 do_a_dot_command(ua, ua->cmd);
140 do_a_command(ua, ua->cmd);
143 if (ua->auto_display_messages) {
144 pm_strcpy(ua->cmd, "messages");
145 qmessagescmd(ua, ua->cmd);
146 ua->user_notified_msg_pending = FALSE;
147 } else if (!ua->user_notified_msg_pending && console_msg_pending) {
148 bsendmsg(ua, _("You have messages.\n"));
149 ua->user_notified_msg_pending = TRUE;
151 bnet_sig(ua->UA_sock, BNET_EOD); /* send end of command */
153 } else if (is_bnet_stop(ua->UA_sock)) {
155 } else { /* signal */
156 bnet_sig(ua->UA_sock, BNET_POLL);
169 * Create a UAContext for a Job that is running so that
170 * it can the User Agent routines and
171 * to ensure that the Job gets the proper output.
172 * This is a sort of mini-kludge, and should be
173 * unified at some point.
175 UAContext *new_ua_context(JCR *jcr)
179 ua = (UAContext *)malloc(sizeof(UAContext));
180 memset(ua, 0, sizeof(UAContext));
183 ua->cmd = get_pool_memory(PM_FNAME);
184 ua->args = get_pool_memory(PM_FNAME);
186 ua->automount = TRUE;
190 void free_ua_context(UAContext *ua)
193 free_pool_memory(ua->cmd);
196 free_pool_memory(ua->args);
203 bnet_close(ua->UA_sock);
211 * Called from main Bacula thread
213 void term_ua_server()