]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_dotcmds.c
Modify .backups command to get a fileset parameter (fix bug #444).
[bacula/bacula] / bacula / src / dird / ua_dotcmds.c
1 /*
2  *
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.
8  *
9  *     Kern Sibbald, April MMII
10  *
11  *   Version $Id$
12  */
13 /*
14    Copyright (C) 2002-2005 Kern Sibbald
15
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.
20
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.
25
26  */
27
28 #include "bacula.h"
29 #include "dird.h"
30
31 /* Imported variables */
32 extern int r_first;
33 extern int r_last;
34 extern struct s_res resources[];
35 extern char my_name[];
36 extern const char *client_backups;
37
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);
43
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);
56
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}
75              };
76 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
77
78 /*
79  * Execute a command from the UA
80  */
81 int do_a_dot_command(UAContext *ua, const char *cmd)
82 {
83    int i;
84    int len, stat;
85    bool found = false;
86
87    stat = 1;
88
89    Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
90    if (ua->argc == 0) {
91       return 1;
92    }
93
94    len = strlen(ua->argk[0]);
95    if (len == 1) {
96       return 1;                       /* no op */
97    }
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 */
101          found = true;
102          break;
103       }
104    }
105    if (!found) {
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);
109    }
110    return stat;
111 }
112
113 /*
114  * Create segmentation fault
115  */
116 static int diecmd(UAContext *ua, const char *cmd)
117 {
118    JCR *jcr = NULL;
119    int a;
120
121    bsendmsg(ua, _("The Director will segment fault.\n"));
122    a = jcr->JobId; /* ref NULL pointer */
123    jcr->JobId = 1000; /* another ref NULL pointer */
124    return 0;
125 }
126
127 static int jobscmd(UAContext *ua, const char *cmd)
128 {
129    JOB *job = NULL;
130    LockRes();
131    while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) {
132       bsendmsg(ua, "%s\n", job->hdr.name);
133    }
134    UnlockRes();
135    return 1;
136 }
137
138 static int filesetscmd(UAContext *ua, const char *cmd)
139 {
140    FILESET *fs = NULL;
141    LockRes();
142    while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) {
143       bsendmsg(ua, "%s\n", fs->hdr.name);
144    }
145    UnlockRes();
146    return 1;
147 }
148
149 static int clientscmd(UAContext *ua, const char *cmd)
150 {
151    CLIENT *client = NULL;
152    LockRes();
153    while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) {
154       bsendmsg(ua, "%s\n", client->hdr.name);
155    }
156    UnlockRes();
157    return 1;
158 }
159
160 static int msgscmd(UAContext *ua, const char *cmd)
161 {
162    MSGS *msgs = NULL;
163    LockRes();
164    while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) {
165       bsendmsg(ua, "%s\n", msgs->hdr.name);
166    }
167    UnlockRes();
168    return 1;
169 }
170
171 static int poolscmd(UAContext *ua, const char *cmd)
172 {
173    POOL *pool = NULL;
174    LockRes();
175    while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) {
176       bsendmsg(ua, "%s\n", pool->hdr.name);
177    }
178    UnlockRes();
179    return 1;
180 }
181
182 static int storagecmd(UAContext *ua, const char *cmd)
183 {
184    STORE *store = NULL;
185    LockRes();
186    while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) {
187       bsendmsg(ua, "%s\n", store->hdr.name);
188    }
189    UnlockRes();
190    return 1;
191 }
192
193
194 static int typescmd(UAContext *ua, const char *cmd)
195 {
196    bsendmsg(ua, "Backup\n");
197    bsendmsg(ua, "Restore\n");
198    bsendmsg(ua, "Admin\n");
199    bsendmsg(ua, "Verify\n");
200    return 1;
201 }
202
203 static int client_backups_handler(void *ctx, int num_field, char **row)
204 {
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]);
208    return 0;
209 }
210
211 static int backupscmd(UAContext *ua, const char *cmd)
212 {
213    if (!open_db(ua)) {
214       return 1;
215    }
216    if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 || strcmp(ua->argk[2], "fileset") != 0) {
217       return 1;
218    }
219    Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
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));
222       return 1;
223    }
224    return 1;
225 }
226
227
228 static int levelscmd(UAContext *ua, const char *cmd)
229 {
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");
236    return 1;
237 }
238
239
240
241 /*
242  * Return default values for a job
243  */
244 static int defaultscmd(UAContext *ua, const char *cmd)
245 {
246    JOB *job;
247    if (ua->argc == 2 && strcmp(ua->argk[1], "job") == 0) {
248       job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
249       if (job) {
250          STORE *store;
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);
261       }
262    }
263    return 1;
264 }