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-2005 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;
38 /* Imported functions */
39 extern int qmessagescmd(UAContext *ua, const char *cmd);
40 extern int quit_cmd(UAContext *ua, const char *cmd);
41 extern int qhelp_cmd(UAContext *ua, const char *cmd);
42 extern int qstatus_cmd(UAContext *ua, const char *cmd);
44 /* Forward referenced functions */
45 static int diecmd(UAContext *ua, const char *cmd);
46 static int jobscmd(UAContext *ua, const char *cmd);
47 static int filesetscmd(UAContext *ua, const char *cmd);
48 static int clientscmd(UAContext *ua, const char *cmd);
49 static int msgscmd(UAContext *ua, const char *cmd);
50 static int poolscmd(UAContext *ua, const char *cmd);
51 static int storagecmd(UAContext *ua, const char *cmd);
52 static int defaultscmd(UAContext *ua, const char *cmd);
53 static int typescmd(UAContext *ua, const char *cmd);
54 static int backupscmd(UAContext *ua, const char *cmd);
55 static int levelscmd(UAContext *ua, const char *cmd);
57 struct cmdstruct { const char *key; int (*func)(UAContext *ua, const char *cmd); const char *help; };
58 static struct cmdstruct commands[] = {
59 { N_(".die"), diecmd, NULL},
60 { N_(".jobs"), jobscmd, NULL},
61 { N_(".filesets"), filesetscmd, NULL},
62 { N_(".clients"), clientscmd, NULL},
63 { N_(".msgs"), msgscmd, NULL},
64 { N_(".pools"), poolscmd, NULL},
65 { N_(".types"), typescmd, NULL},
66 { N_(".backups"), backupscmd, NULL},
67 { N_(".levels"), levelscmd, NULL},
68 { N_(".status"), qstatus_cmd, NULL},
69 { N_(".storage"), storagecmd, NULL},
70 { N_(".defaults"), defaultscmd, NULL},
71 { N_(".messages"), qmessagescmd, NULL},
72 { N_(".help"), qhelp_cmd, NULL},
73 { N_(".quit"), quit_cmd, NULL},
74 { N_(".exit"), quit_cmd, NULL}
76 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
79 * Execute a command from the UA
81 int do_a_dot_command(UAContext *ua, const char *cmd)
89 Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
94 len = strlen(ua->argk[0]);
98 for (i=0; i<(int)comsize; i++) { /* search for command */
99 if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) {
100 stat = (*commands[i].func)(ua, cmd); /* go execute command */
106 pm_strcat(ua->UA_sock->msg, _(": is an illegal command\n"));
107 ua->UA_sock->msglen = strlen(ua->UA_sock->msg);
108 bnet_send(ua->UA_sock);
114 * Create segmentation fault
116 static int diecmd(UAContext *ua, const char *cmd)
121 bsendmsg(ua, "The Director will segment fault.\n");
122 a = jcr->JobId; /* ref NULL pointer */
123 jcr->JobId = 1000; /* another ref NULL pointer */
127 static int jobscmd(UAContext *ua, const char *cmd)
131 while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) {
132 bsendmsg(ua, "%s\n", job->hdr.name);
138 static int filesetscmd(UAContext *ua, const char *cmd)
142 while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) {
143 bsendmsg(ua, "%s\n", fs->hdr.name);
149 static int clientscmd(UAContext *ua, const char *cmd)
151 CLIENT *client = NULL;
153 while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) {
154 bsendmsg(ua, "%s\n", client->hdr.name);
160 static int msgscmd(UAContext *ua, const char *cmd)
164 while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) {
165 bsendmsg(ua, "%s\n", msgs->hdr.name);
171 static int poolscmd(UAContext *ua, const char *cmd)
175 while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) {
176 bsendmsg(ua, "%s\n", pool->hdr.name);
182 static int storagecmd(UAContext *ua, const char *cmd)
186 while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) {
187 bsendmsg(ua, "%s\n", store->hdr.name);
194 static int typescmd(UAContext *ua, const char *cmd)
196 bsendmsg(ua, "Backup\n");
197 bsendmsg(ua, "Restore\n");
198 bsendmsg(ua, "Admin\n");
199 bsendmsg(ua, "Verify\n");
203 static int client_backups_handler(void *ctx, int num_field, char **row)
205 UAContext *ua = (UAContext *)ctx;
206 bsendmsg(ua, "| %s | %s | %s | %s | %s | %s | %s |\n",
207 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
211 static int backupscmd(UAContext *ua, const char *cmd)
216 if (ua->argc == 2 && strcmp(ua->argk[1], "client") != 0) {
219 Mmsg(ua->cmd, client_backups, ua->argv[1]);
220 if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
221 bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
228 static int levelscmd(UAContext *ua, const char *cmd)
230 bsendmsg(ua, "Incremental\n");
231 bsendmsg(ua, "Full\n");
232 bsendmsg(ua, "Differential\n");
233 bsendmsg(ua, "Catalog\n");
234 bsendmsg(ua, "InitCatalog\n");
235 bsendmsg(ua, "VolumeToCatalog\n");
242 * Return default values for a job
244 static int defaultscmd(UAContext *ua, const char *cmd)
247 if (ua->argc == 2 && strcmp(ua->argk[1], "job") == 0) {
248 job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
251 bsendmsg(ua, "job=%s", job->hdr.name);
252 bsendmsg(ua, "pool=%s", job->pool->hdr.name);
253 bsendmsg(ua, "messages=%s", job->messages->hdr.name);
254 bsendmsg(ua, "client=%s", job->client->hdr.name);
255 store = (STORE *)job->storage->first();
256 bsendmsg(ua, "storage=%s", store->hdr.name);
257 bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
258 bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
259 bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
260 bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);