2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula Director -- User Agent Server
23 * Kern Sibbald, September MM
30 /* Imported variables */
33 /* Forward referenced functions */
34 extern "C" void *connect_thread(void *arg);
35 static void *handle_UA_client_request(void *arg);
38 /* Global variables */
39 static int started = FALSE;
40 static workq_t ua_workq;
47 /* Called here by Director daemon to start UA (user agent)
48 * command thread. This routine creates the thread and then
51 void start_UA_server(dlist *addrs)
55 static dlist *myaddrs = addrs;
57 if ((status=pthread_create(&thid, NULL, connect_thread, (void *)myaddrs)) != 0) {
59 Emsg1(M_ABORT, 0, _("Cannot create UA thread: %s\n"), be.bstrerror(status));
66 void *connect_thread(void *arg)
68 pthread_detach(pthread_self());
69 set_jcr_in_tsd(INVALID_JCR);
71 /* Permit MaxConsoleConnect console connections */
72 bnet_thread_server((dlist*)arg, director->MaxConsoleConnect, &ua_workq, handle_UA_client_request);
77 * Create a Job Control Record for a control "job",
78 * filling in all the appropriate fields.
80 JCR *new_control_jcr(const char *base_name, int job_type)
83 jcr = new_jcr(sizeof(JCR), dird_free_jcr);
85 * The job and defaults are not really used, but
86 * we set them up to ensure that everything is correctly
90 jcr->job = (JOB *)GetNextRes(R_JOB, NULL);
91 set_jcr_defaults(jcr, jcr->job);
93 jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */
94 create_unique_job_name(jcr, base_name);
95 jcr->sched_time = jcr->start_time;
96 jcr->setJobType(job_type);
97 jcr->setJobLevel(L_NONE);
98 jcr->setJobStatus(JS_Running);
104 * Handle Director User Agent commands
107 static void *handle_UA_client_request(void *arg)
112 BSOCK *user = (BSOCK *)arg;
114 pthread_detach(pthread_self());
116 jcr = new_control_jcr("-Console-", JT_CONSOLE);
118 ua = new_ua_context(jcr);
120 set_jcr_in_tsd(INVALID_JCR);
122 user->recv(); /* Get first message */
123 if (!authenticate_user_agent(ua)) {
128 if (ua->api) user->signal(BNET_MAIN_PROMPT);
131 pm_strcpy(ua->cmd, ua->UA_sock->msg);
133 if (ua->argc > 0 && ua->argk[0][0] == '.') {
134 do_a_dot_command(ua);
138 dequeue_messages(ua->jcr);
140 if (console_msg_pending && acl_access_ok(ua, Command_ACL, "messages", 8)) {
141 if (ua->auto_display_messages) {
142 pm_strcpy(ua->cmd, "messages");
143 qmessagescmd(ua, ua->cmd);
144 ua->user_notified_msg_pending = false;
145 } else if (!ua->gui && !ua->user_notified_msg_pending && console_msg_pending) {
147 user->signal(BNET_MSGS_PENDING);
149 bsendmsg(ua, _("You have messages.\n"));
151 ua->user_notified_msg_pending = true;
154 if (!ua->api) user->signal(BNET_EOD); /* send end of command */
156 } else if (user->is_stop()) {
158 } else { /* signal */
159 user->signal(BNET_POLL);
162 /* At the end of each command, revert to the main shared SQL link */
163 ua->db = ua->shared_db;
175 * Create a UAContext for a Job that is running so that
176 * it can the User Agent routines and
177 * to ensure that the Job gets the proper output.
178 * This is a sort of mini-kludge, and should be
179 * unified at some point.
181 UAContext *new_ua_context(JCR *jcr)
185 ua = (UAContext *)malloc(sizeof(UAContext));
186 memset(ua, 0, sizeof(UAContext));
188 ua->shared_db = ua->db = jcr->db;
189 ua->cmd = get_pool_memory(PM_FNAME);
190 ua->args = get_pool_memory(PM_FNAME);
191 ua->errmsg = get_pool_memory(PM_FNAME);
193 ua->automount = true;
197 void free_ua_context(UAContext *ua)
200 free_pool_memory(ua->cmd);
203 free_pool_memory(ua->args);
206 free_pool_memory(ua->errmsg);
214 free_bsock(ua->UA_sock);
220 * Called from main Bacula thread
222 void term_ua_server()