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 Copyright (C) 2002-2006 Kern Sibbald
16 This program is free software; you can redistribute it and/or
17 modify it under the terms of the GNU General Public License
18 version 2 as amended with additional clauses defined in the
19 file LICENSE in the main source directory.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 the file LICENSE for additional details.
31 /* Imported variables */
34 extern struct s_res resources[];
35 extern char my_name[];
36 extern const char *client_backups;
37 extern int console_msg_pending;
39 /* Imported functions */
40 extern int do_messages(UAContext *ua, const char *cmd);
41 extern int quit_cmd(UAContext *ua, const char *cmd);
42 extern int qhelp_cmd(UAContext *ua, const char *cmd);
43 extern int qstatus_cmd(UAContext *ua, const char *cmd);
45 /* Forward referenced functions */
46 static int diecmd(UAContext *ua, const char *cmd);
47 static int jobscmd(UAContext *ua, const char *cmd);
48 static int filesetscmd(UAContext *ua, const char *cmd);
49 static int clientscmd(UAContext *ua, const char *cmd);
50 static int msgscmd(UAContext *ua, const char *cmd);
51 static int poolscmd(UAContext *ua, const char *cmd);
52 static int storagecmd(UAContext *ua, const char *cmd);
53 static int defaultscmd(UAContext *ua, const char *cmd);
54 static int typescmd(UAContext *ua, const char *cmd);
55 static int backupscmd(UAContext *ua, const char *cmd);
56 static int levelscmd(UAContext *ua, const char *cmd);
57 static int getmsgscmd(UAContext *ua, const char *cmd);
59 struct cmdstruct { const char *key; int (*func)(UAContext *ua, const char *cmd); const char *help; };
60 static struct cmdstruct commands[] = {
61 { N_(".die"), diecmd, NULL},
62 { N_(".jobs"), jobscmd, NULL},
63 { N_(".filesets"), filesetscmd, NULL},
64 { N_(".clients"), clientscmd, NULL},
65 { N_(".msgs"), msgscmd, NULL},
66 { N_(".pools"), poolscmd, NULL},
67 { N_(".types"), typescmd, NULL},
68 { N_(".backups"), backupscmd, NULL},
69 { N_(".levels"), levelscmd, NULL},
70 { N_(".status"), qstatus_cmd, NULL},
71 { N_(".storage"), storagecmd, NULL},
72 { N_(".defaults"), defaultscmd, NULL},
73 { N_(".messages"), getmsgscmd, NULL},
74 { N_(".help"), qhelp_cmd, NULL},
75 { N_(".quit"), quit_cmd, NULL},
76 { N_(".exit"), quit_cmd, NULL}
78 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
81 * Execute a command from the UA
83 int do_a_dot_command(UAContext *ua, const char *cmd)
91 Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
96 len = strlen(ua->argk[0]);
100 for (i=0; i<(int)comsize; i++) { /* search for command */
101 if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) {
102 stat = (*commands[i].func)(ua, cmd); /* go execute command */
108 pm_strcat(ua->UA_sock->msg, _(": is an illegal command\n"));
109 ua->UA_sock->msglen = strlen(ua->UA_sock->msg);
110 bnet_send(ua->UA_sock);
115 static int getmsgscmd(UAContext *ua, const char *cmd)
117 if (console_msg_pending) {
118 do_messages(ua, cmd);
124 * Create segmentation fault
126 static int diecmd(UAContext *ua, const char *cmd)
131 bsendmsg(ua, _("The Director will segment fault.\n"));
132 a = jcr->JobId; /* ref NULL pointer */
133 jcr->JobId = 1000; /* another ref NULL pointer */
137 static int jobscmd(UAContext *ua, const char *cmd)
141 while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) {
142 bsendmsg(ua, "%s\n", job->hdr.name);
148 static int filesetscmd(UAContext *ua, const char *cmd)
152 while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) {
153 bsendmsg(ua, "%s\n", fs->hdr.name);
159 static int clientscmd(UAContext *ua, const char *cmd)
161 CLIENT *client = NULL;
163 while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) {
164 bsendmsg(ua, "%s\n", client->hdr.name);
170 static int msgscmd(UAContext *ua, const char *cmd)
174 while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) {
175 bsendmsg(ua, "%s\n", msgs->hdr.name);
181 static int poolscmd(UAContext *ua, const char *cmd)
185 while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) {
186 bsendmsg(ua, "%s\n", pool->hdr.name);
192 static int storagecmd(UAContext *ua, const char *cmd)
196 while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) {
197 bsendmsg(ua, "%s\n", store->hdr.name);
204 static int typescmd(UAContext *ua, const char *cmd)
206 bsendmsg(ua, "Backup\n");
207 bsendmsg(ua, "Restore\n");
208 bsendmsg(ua, "Admin\n");
209 bsendmsg(ua, "Verify\n");
213 static int client_backups_handler(void *ctx, int num_field, char **row)
215 UAContext *ua = (UAContext *)ctx;
216 bsendmsg(ua, "| %s | %s | %s | %s | %s | %s | %s |\n",
217 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
221 static int backupscmd(UAContext *ua, const char *cmd)
226 if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 || strcmp(ua->argk[2], "fileset") != 0) {
229 Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
230 if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
231 bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
238 static int levelscmd(UAContext *ua, const char *cmd)
240 bsendmsg(ua, "Incremental\n");
241 bsendmsg(ua, "Full\n");
242 bsendmsg(ua, "Differential\n");
243 bsendmsg(ua, "Catalog\n");
244 bsendmsg(ua, "InitCatalog\n");
245 bsendmsg(ua, "VolumeToCatalog\n");
252 * Return default values for a job
254 static int defaultscmd(UAContext *ua, const char *cmd)
261 if (ua->argc != 2 || !ua->argv[1]) {
266 if (strcmp(ua->argk[1], "job") == 0) {
267 job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
270 bsendmsg(ua, "job=%s", job->hdr.name);
271 bsendmsg(ua, "pool=%s", job->pool->hdr.name);
272 bsendmsg(ua, "messages=%s", job->messages->hdr.name);
273 bsendmsg(ua, "client=%s", job->client->hdr.name);
274 store = (STORE *)job->storage->first();
275 bsendmsg(ua, "storage=%s", store->hdr.name);
276 bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
277 bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
278 bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
279 bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
280 bsendmsg(ua, "enabled=%d", job->enabled);
283 /* Client defaults */
284 else if (strcmp(ua->argk[1], "client") == 0) {
285 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
287 bsendmsg(ua, "client=%s", client->hdr.name);
288 bsendmsg(ua, "address=%s", client->address);
289 bsendmsg(ua, "fdport=%d", client->FDport);
290 bsendmsg(ua, "file_retention=%d", client->FileRetention);
291 bsendmsg(ua, "job_retention=%d", client->JobRetention);
292 bsendmsg(ua, "autoprune=%d", client->AutoPrune);
295 /* Storage defaults */
296 else if (strcmp(ua->argk[1], "storage") == 0) {
297 storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
300 bsendmsg(ua, "storage=%s", storage->hdr.name);
301 bsendmsg(ua, "address=%s", storage->address);
302 bsendmsg(ua, "enabled=%d", storage->enabled);
303 bsendmsg(ua, "media_type=%s", storage->media_type);
304 bsendmsg(ua, "sdport=%d", storage->SDport);
305 device = (DEVICE *)storage->device->first();
306 bsendmsg(ua, "device=%s", device->hdr.name);
307 if (storage->device->size() > 1) {
308 while ((device = (DEVICE *)storage->device->next()))
309 bsendmsg(ua, ",%s", device->hdr.name);
314 else if (strcmp(ua->argk[1], "pool") == 0) {
315 pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
317 bsendmsg(ua, "pool=%s", pool->hdr.name);
318 bsendmsg(ua, "pool_type=%s", pool->pool_type);
319 bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:"");
320 bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once);
321 bsendmsg(ua, "accept_any_volume=%d", pool->accept_any_volume);
322 bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume);
323 bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume);
324 bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume);
325 bsendmsg(ua, "max_volumes=%d", pool->max_volumes);
326 bsendmsg(ua, "vol_retention=%d", pool->VolRetention);
327 bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration);
328 bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs);
329 bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles);
330 bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes);
331 bsendmsg(ua, "auto_prune=%d", pool->AutoPrune);
332 bsendmsg(ua, "recycle=%d", pool->Recycle);