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) {
112 stat = (*commands[i].func)(ua, cmd); /* go execute command */
118 pm_strcat(ua->UA_sock->msg, _(": is an illegal command\n"));
119 ua->UA_sock->msglen = strlen(ua->UA_sock->msg);
120 bnet_send(ua->UA_sock);
125 static int getmsgscmd(UAContext *ua, const char *cmd)
127 if (console_msg_pending) {
128 do_messages(ua, cmd);
134 * Create segmentation fault
136 static int diecmd(UAContext *ua, const char *cmd)
141 bsendmsg(ua, _("The Director will segment fault.\n"));
142 a = jcr->JobId; /* ref NULL pointer */
143 jcr->JobId = 1000; /* another ref NULL pointer */
147 static int jobscmd(UAContext *ua, const char *cmd)
151 while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) {
152 if (acl_access_ok(ua, Job_ACL, job->hdr.name)) {
153 bsendmsg(ua, "%s\n", job->hdr.name);
160 static int filesetscmd(UAContext *ua, const char *cmd)
164 while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) {
165 if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) {
166 bsendmsg(ua, "%s\n", fs->hdr.name);
173 static int clientscmd(UAContext *ua, const char *cmd)
175 CLIENT *client = NULL;
177 while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) {
178 if (acl_access_ok(ua, Client_ACL, client->hdr.name)) {
179 bsendmsg(ua, "%s\n", client->hdr.name);
186 static int msgscmd(UAContext *ua, const char *cmd)
190 while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) {
191 bsendmsg(ua, "%s\n", msgs->hdr.name);
197 static int poolscmd(UAContext *ua, const char *cmd)
201 while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) {
202 if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
203 bsendmsg(ua, "%s\n", pool->hdr.name);
210 static int storagecmd(UAContext *ua, const char *cmd)
214 while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) {
215 if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
216 bsendmsg(ua, "%s\n", store->hdr.name);
224 static int typescmd(UAContext *ua, const char *cmd)
226 bsendmsg(ua, "Backup\n");
227 bsendmsg(ua, "Restore\n");
228 bsendmsg(ua, "Admin\n");
229 bsendmsg(ua, "Verify\n");
233 static int client_backups_handler(void *ctx, int num_field, char **row)
235 UAContext *ua = (UAContext *)ctx;
236 bsendmsg(ua, "| %s | %s | %s | %s | %s | %s | %s | %s |\n",
237 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]);
241 static int backupscmd(UAContext *ua, const char *cmd)
246 if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 || strcmp(ua->argk[2], "fileset") != 0) {
249 if (!acl_access_ok(ua, Client_ACL, ua->argv[1]) ||
250 !acl_access_ok(ua, FileSet_ACL, ua->argv[2])) {
253 Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
254 if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
255 bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
262 static int levelscmd(UAContext *ua, const char *cmd)
264 bsendmsg(ua, "Incremental\n");
265 bsendmsg(ua, "Full\n");
266 bsendmsg(ua, "Differential\n");
267 bsendmsg(ua, "Catalog\n");
268 bsendmsg(ua, "InitCatalog\n");
269 bsendmsg(ua, "VolumeToCatalog\n");
274 * Return default values for a job
276 static int defaultscmd(UAContext *ua, const char *cmd)
283 if (ua->argc != 2 || !ua->argv[1]) {
288 if (strcmp(ua->argk[1], "job") == 0) {
289 if (!acl_access_ok(ua, Job_ACL, ua->argv[1])) {
292 job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
295 bsendmsg(ua, "job=%s", job->hdr.name);
296 bsendmsg(ua, "pool=%s", job->pool->hdr.name);
297 bsendmsg(ua, "messages=%s", job->messages->hdr.name);
298 bsendmsg(ua, "client=%s", job->client->hdr.name);
299 store = (STORE *)job->storage->first();
300 bsendmsg(ua, "storage=%s", store->hdr.name);
301 bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
302 bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
303 bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
304 bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
305 bsendmsg(ua, "enabled=%d", job->enabled);
308 /* Client defaults */
309 else if (strcmp(ua->argk[1], "client") == 0) {
310 if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
313 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
315 bsendmsg(ua, "client=%s", client->hdr.name);
316 bsendmsg(ua, "address=%s", client->address);
317 bsendmsg(ua, "fdport=%d", client->FDport);
318 bsendmsg(ua, "file_retention=%d", client->FileRetention);
319 bsendmsg(ua, "job_retention=%d", client->JobRetention);
320 bsendmsg(ua, "autoprune=%d", client->AutoPrune);
323 /* Storage defaults */
324 else if (strcmp(ua->argk[1], "storage") == 0) {
325 if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
328 storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
331 bsendmsg(ua, "storage=%s", storage->hdr.name);
332 bsendmsg(ua, "address=%s", storage->address);
333 bsendmsg(ua, "enabled=%d", storage->enabled);
334 bsendmsg(ua, "media_type=%s", storage->media_type);
335 bsendmsg(ua, "sdport=%d", storage->SDport);
336 device = (DEVICE *)storage->device->first();
337 bsendmsg(ua, "device=%s", device->hdr.name);
338 if (storage->device->size() > 1) {
339 while ((device = (DEVICE *)storage->device->next()))
340 bsendmsg(ua, ",%s", device->hdr.name);
345 else if (strcmp(ua->argk[1], "pool") == 0) {
346 if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
349 pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
351 bsendmsg(ua, "pool=%s", pool->hdr.name);
352 bsendmsg(ua, "pool_type=%s", pool->pool_type);
353 bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:"");
354 bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once);
355 bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume);
356 bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume);
357 bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume);
358 bsendmsg(ua, "max_volumes=%d", pool->max_volumes);
359 bsendmsg(ua, "vol_retention=%d", pool->VolRetention);
360 bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration);
361 bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs);
362 bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles);
363 bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes);
364 bsendmsg(ua, "auto_prune=%d", pool->AutoPrune);
365 bsendmsg(ua, "recycle=%d", pool->Recycle);