3 * Bacula Director -- User Agent Commands
4 * These are "dot" commands, i.e. commands preceded
5 * by a period. These commands are meant to be used
6 * by a program, so there is no prompting, and the
7 * returned results are (supposed to be) predictable.
9 * Kern Sibbald, April MMII
14 Bacula® - The Network Backup Solution
16 Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
18 The main author of Bacula is Kern Sibbald, with contributions from
19 many others, a complete list can be found in the file AUTHORS.
20 This program is Free Software; you can redistribute it and/or
21 modify it under the terms of version two of the GNU General Public
22 License as published by the Free Software Foundation plus additions
23 that are listed in the file LICENSE.
25 This program is distributed in the hope that it will be useful, but
26 WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 General Public License for more details.
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 Bacula® is a registered trademark of John Walker.
36 The licensor of Bacula is the Free Software Foundation Europe
37 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
38 Switzerland, email:ftf@fsfeurope.org.
44 /* Imported variables */
47 extern struct s_res resources[];
49 /* Imported functions */
50 extern void do_messages(UAContext *ua, const char *cmd);
51 extern int quit_cmd(UAContext *ua, const char *cmd);
52 extern int qhelp_cmd(UAContext *ua, const char *cmd);
53 extern int qstatus_cmd(UAContext *ua, const char *cmd);
55 /* Forward referenced functions */
56 static int diecmd(UAContext *ua, const char *cmd);
57 static int jobscmd(UAContext *ua, const char *cmd);
58 static int filesetscmd(UAContext *ua, const char *cmd);
59 static int clientscmd(UAContext *ua, const char *cmd);
60 static int msgscmd(UAContext *ua, const char *cmd);
61 static int poolscmd(UAContext *ua, const char *cmd);
62 static int storagecmd(UAContext *ua, const char *cmd);
63 static int defaultscmd(UAContext *ua, const char *cmd);
64 static int typescmd(UAContext *ua, const char *cmd);
65 static int backupscmd(UAContext *ua, const char *cmd);
66 static int levelscmd(UAContext *ua, const char *cmd);
67 static int getmsgscmd(UAContext *ua, const char *cmd);
69 struct cmdstruct { const char *key; int (*func)(UAContext *ua, const char *cmd); const char *help; };
70 static struct cmdstruct commands[] = {
71 { NT_(".backups"), backupscmd, NULL},
72 { NT_(".clients"), clientscmd, NULL},
73 { NT_(".defaults"), defaultscmd, NULL},
74 { NT_(".die"), diecmd, NULL},
75 { NT_(".exit"), quit_cmd, NULL},
76 { NT_(".filesets"), filesetscmd, NULL},
77 { NT_(".help"), qhelp_cmd, NULL},
78 { NT_(".jobs"), jobscmd, NULL},
79 { NT_(".levels"), levelscmd, NULL},
80 { NT_(".messages"), getmsgscmd, NULL},
81 { NT_(".msgs"), msgscmd, NULL},
82 { NT_(".pools"), poolscmd, NULL},
83 { NT_(".quit"), quit_cmd, NULL},
84 { NT_(".status"), qstatus_cmd, NULL},
85 { NT_(".storage"), storagecmd, NULL},
86 { NT_(".types"), typescmd, NULL}
88 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
91 * Execute a command from the UA
93 int do_a_dot_command(UAContext *ua, const char *cmd)
101 Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
106 len = strlen(ua->argk[0]);
108 return 1; /* no op */
110 for (i=0; i<(int)comsize; i++) { /* search for command */
111 if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) {
114 stat = (*commands[i].func)(ua, cmd); /* go execute command */
121 pm_strcat(ua->UA_sock->msg, _(": is an invalid command\n"));
122 ua->UA_sock->msglen = strlen(ua->UA_sock->msg);
123 bnet_send(ua->UA_sock);
128 static int getmsgscmd(UAContext *ua, const char *cmd)
130 if (console_msg_pending) {
131 do_messages(ua, cmd);
137 * Create segmentation fault
139 static int diecmd(UAContext *ua, const char *cmd)
144 bsendmsg(ua, _("The Director will segment fault.\n"));
145 a = jcr->JobId; /* ref NULL pointer */
146 jcr->JobId = 1000; /* another ref NULL pointer */
150 static int jobscmd(UAContext *ua, const char *cmd)
154 while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) {
155 if (acl_access_ok(ua, Job_ACL, job->hdr.name)) {
156 bsendmsg(ua, "%s\n", job->hdr.name);
163 static int filesetscmd(UAContext *ua, const char *cmd)
167 while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) {
168 if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) {
169 bsendmsg(ua, "%s\n", fs->hdr.name);
176 static int clientscmd(UAContext *ua, const char *cmd)
178 CLIENT *client = NULL;
180 while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) {
181 if (acl_access_ok(ua, Client_ACL, client->hdr.name)) {
182 bsendmsg(ua, "%s\n", client->hdr.name);
189 static int msgscmd(UAContext *ua, const char *cmd)
193 while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) {
194 bsendmsg(ua, "%s\n", msgs->hdr.name);
200 static int poolscmd(UAContext *ua, const char *cmd)
204 while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) {
205 if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
206 bsendmsg(ua, "%s\n", pool->hdr.name);
213 static int storagecmd(UAContext *ua, const char *cmd)
217 while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) {
218 if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
219 bsendmsg(ua, "%s\n", store->hdr.name);
227 static int typescmd(UAContext *ua, const char *cmd)
229 bsendmsg(ua, "Backup\n");
230 bsendmsg(ua, "Restore\n");
231 bsendmsg(ua, "Admin\n");
232 bsendmsg(ua, "Verify\n");
233 bsendmsg(ua, "Migrate\n");
237 static int client_backups_handler(void *ctx, int num_field, char **row)
239 UAContext *ua = (UAContext *)ctx;
240 bsendmsg(ua, "| %s | %s | %s | %s | %s | %s | %s | %s |\n",
241 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]);
245 static int backupscmd(UAContext *ua, const char *cmd)
250 if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 || strcmp(ua->argk[2], "fileset") != 0) {
253 if (!acl_access_ok(ua, Client_ACL, ua->argv[1]) ||
254 !acl_access_ok(ua, FileSet_ACL, ua->argv[2])) {
257 Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
258 if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
259 bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
266 static int levelscmd(UAContext *ua, const char *cmd)
268 bsendmsg(ua, "Incremental\n");
269 bsendmsg(ua, "Full\n");
270 bsendmsg(ua, "Differential\n");
271 bsendmsg(ua, "Catalog\n");
272 bsendmsg(ua, "InitCatalog\n");
273 bsendmsg(ua, "VolumeToCatalog\n");
278 * Return default values for a job
280 static int defaultscmd(UAContext *ua, const char *cmd)
287 if (ua->argc != 2 || !ua->argv[1]) {
292 if (strcmp(ua->argk[1], "job") == 0) {
293 if (!acl_access_ok(ua, Job_ACL, ua->argv[1])) {
296 job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
299 bsendmsg(ua, "job=%s", job->hdr.name);
300 bsendmsg(ua, "pool=%s", job->pool->hdr.name);
301 bsendmsg(ua, "messages=%s", job->messages->hdr.name);
302 bsendmsg(ua, "client=%s", job->client->hdr.name);
303 get_job_storage(&store, job, NULL);
304 bsendmsg(ua, "storage=%s", store.store->name());
305 bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
306 bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
307 bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
308 bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
309 bsendmsg(ua, "enabled=%d", job->enabled);
312 /* Client defaults */
313 else if (strcmp(ua->argk[1], "client") == 0) {
314 if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
317 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
319 bsendmsg(ua, "client=%s", client->hdr.name);
320 bsendmsg(ua, "address=%s", client->address);
321 bsendmsg(ua, "fdport=%d", client->FDport);
322 bsendmsg(ua, "file_retention=%d", client->FileRetention);
323 bsendmsg(ua, "job_retention=%d", client->JobRetention);
324 bsendmsg(ua, "autoprune=%d", client->AutoPrune);
327 /* Storage defaults */
328 else if (strcmp(ua->argk[1], "storage") == 0) {
329 if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
332 storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
335 bsendmsg(ua, "storage=%s", storage->hdr.name);
336 bsendmsg(ua, "address=%s", storage->address);
337 bsendmsg(ua, "enabled=%d", storage->enabled);
338 bsendmsg(ua, "media_type=%s", storage->media_type);
339 bsendmsg(ua, "sdport=%d", storage->SDport);
340 device = (DEVICE *)storage->device->first();
341 bsendmsg(ua, "device=%s", device->hdr.name);
342 if (storage->device->size() > 1) {
343 while ((device = (DEVICE *)storage->device->next()))
344 bsendmsg(ua, ",%s", device->hdr.name);
349 else if (strcmp(ua->argk[1], "pool") == 0) {
350 if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
353 pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
355 bsendmsg(ua, "pool=%s", pool->hdr.name);
356 bsendmsg(ua, "pool_type=%s", pool->pool_type);
357 bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:"");
358 bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once);
359 bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume);
360 bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume);
361 bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume);
362 bsendmsg(ua, "max_volumes=%d", pool->max_volumes);
363 bsendmsg(ua, "vol_retention=%d", pool->VolRetention);
364 bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration);
365 bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs);
366 bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles);
367 bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes);
368 bsendmsg(ua, "auto_prune=%d", pool->AutoPrune);
369 bsendmsg(ua, "recycle=%d", pool->Recycle);