]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_dotcmds.c
Minor tweaks to Migration
[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-2006 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
36 /* Imported functions */
37 extern void do_messages(UAContext *ua, const char *cmd);
38 extern int quit_cmd(UAContext *ua, const char *cmd);
39 extern int qhelp_cmd(UAContext *ua, const char *cmd);
40 extern int qstatus_cmd(UAContext *ua, const char *cmd);
41
42 /* Forward referenced functions */
43 static int diecmd(UAContext *ua, const char *cmd);
44 static int jobscmd(UAContext *ua, const char *cmd);
45 static int filesetscmd(UAContext *ua, const char *cmd);
46 static int clientscmd(UAContext *ua, const char *cmd);
47 static int msgscmd(UAContext *ua, const char *cmd);
48 static int poolscmd(UAContext *ua, const char *cmd);
49 static int storagecmd(UAContext *ua, const char *cmd);
50 static int defaultscmd(UAContext *ua, const char *cmd);
51 static int typescmd(UAContext *ua, const char *cmd);
52 static int backupscmd(UAContext *ua, const char *cmd);
53 static int levelscmd(UAContext *ua, const char *cmd);
54 static int getmsgscmd(UAContext *ua, const char *cmd);
55
56 struct cmdstruct { const char *key; int (*func)(UAContext *ua, const char *cmd); const char *help; };
57 static struct cmdstruct commands[] = {
58  { NT_(".die"),        diecmd,       NULL},
59  { NT_(".jobs"),       jobscmd,      NULL},
60  { NT_(".filesets"),   filesetscmd,  NULL},
61  { NT_(".clients"),    clientscmd,   NULL},
62  { NT_(".msgs"),       msgscmd,      NULL},
63  { NT_(".pools"),      poolscmd,     NULL},
64  { NT_(".types"),      typescmd,     NULL},
65  { NT_(".backups"),    backupscmd,   NULL},
66  { NT_(".levels"),     levelscmd,    NULL},
67  { NT_(".status"),     qstatus_cmd,  NULL},
68  { NT_(".storage"),    storagecmd,   NULL},
69  { NT_(".defaults"),   defaultscmd,  NULL},
70  { NT_(".messages"),   getmsgscmd,   NULL},
71  { NT_(".help"),       qhelp_cmd,    NULL},
72  { NT_(".quit"),       quit_cmd,     NULL},
73  { NT_(".exit"),       quit_cmd,     NULL}
74              };
75 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
76
77 /*
78  * Execute a command from the UA
79  */
80 int do_a_dot_command(UAContext *ua, const char *cmd)
81 {
82    int i;
83    int len, stat;
84    bool found = false;
85
86    stat = 1;
87
88    Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
89    if (ua->argc == 0) {
90       return 1;
91    }
92
93    len = strlen(ua->argk[0]);
94    if (len == 1) {
95       return 1;                       /* no op */
96    }
97    for (i=0; i<(int)comsize; i++) {     /* search for command */
98       if (strncasecmp(ua->argk[0],  _(commands[i].key), len) == 0) {
99          stat = (*commands[i].func)(ua, cmd);   /* go execute command */
100          found = true;
101          break;
102       }
103    }
104    if (!found) {
105       pm_strcat(ua->UA_sock->msg, _(": is an illegal command\n"));
106       ua->UA_sock->msglen = strlen(ua->UA_sock->msg);
107       bnet_send(ua->UA_sock);
108    }
109    return stat;
110 }
111
112 static int getmsgscmd(UAContext *ua, const char *cmd)
113 {
114    if (console_msg_pending) {
115       do_messages(ua, cmd);
116    }
117    return 1;
118 }
119
120 /*
121  * Create segmentation fault
122  */
123 static int diecmd(UAContext *ua, const char *cmd)
124 {
125    JCR *jcr = NULL;
126    int a;
127
128    bsendmsg(ua, _("The Director will segment fault.\n"));
129    a = jcr->JobId; /* ref NULL pointer */
130    jcr->JobId = 1000; /* another ref NULL pointer */
131    return 0;
132 }
133
134 static int jobscmd(UAContext *ua, const char *cmd)
135 {
136    JOB *job = NULL;
137    LockRes();
138    while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) {
139       if (acl_access_ok(ua, Job_ACL, job->hdr.name)) {
140          bsendmsg(ua, "%s\n", job->hdr.name);
141       }
142    }
143    UnlockRes();
144    return 1;
145 }
146
147 static int filesetscmd(UAContext *ua, const char *cmd)
148 {
149    FILESET *fs = NULL;
150    LockRes();
151    while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) {
152       if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) {
153          bsendmsg(ua, "%s\n", fs->hdr.name);
154       }
155    }
156    UnlockRes();
157    return 1;
158 }
159
160 static int clientscmd(UAContext *ua, const char *cmd)
161 {
162    CLIENT *client = NULL;
163    LockRes();
164    while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) {
165       if (acl_access_ok(ua, Client_ACL, client->hdr.name)) {
166          bsendmsg(ua, "%s\n", client->hdr.name);
167       }
168    }
169    UnlockRes();
170    return 1;
171 }
172
173 static int msgscmd(UAContext *ua, const char *cmd)
174 {
175    MSGS *msgs = NULL;
176    LockRes();
177    while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) {
178       bsendmsg(ua, "%s\n", msgs->hdr.name);
179    }
180    UnlockRes();
181    return 1;
182 }
183
184 static int poolscmd(UAContext *ua, const char *cmd)
185 {
186    POOL *pool = NULL;
187    LockRes();
188    while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) {
189       if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
190          bsendmsg(ua, "%s\n", pool->hdr.name);
191       }
192    }
193    UnlockRes();
194    return 1;
195 }
196
197 static int storagecmd(UAContext *ua, const char *cmd)
198 {
199    STORE *store = NULL;
200    LockRes();
201    while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) {
202       if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
203          bsendmsg(ua, "%s\n", store->hdr.name);
204       }
205    }
206    UnlockRes();
207    return 1;
208 }
209
210
211 static int typescmd(UAContext *ua, const char *cmd)
212 {
213    bsendmsg(ua, "Backup\n");
214    bsendmsg(ua, "Restore\n");
215    bsendmsg(ua, "Admin\n");
216    bsendmsg(ua, "Verify\n");
217    return 1;
218 }
219
220 static int client_backups_handler(void *ctx, int num_field, char **row)
221 {
222    UAContext *ua = (UAContext *)ctx;
223    bsendmsg(ua, "| %s | %s | %s | %s | %s | %s | %s |\n",
224       row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7]);
225    return 0;
226 }
227
228 static int backupscmd(UAContext *ua, const char *cmd)
229 {
230    if (!open_db(ua)) {
231       return 1;
232    }
233    if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 || strcmp(ua->argk[2], "fileset") != 0) {
234       return 1;
235    }
236    if (!acl_access_ok(ua, Client_ACL, ua->argv[1]) ||
237        !acl_access_ok(ua, FileSet_ACL, ua->argv[2])) {
238       return 1;
239    }
240    Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
241    if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
242       bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
243       return 1;
244    }
245    return 1;
246 }
247
248
249 static int levelscmd(UAContext *ua, const char *cmd)
250 {
251    bsendmsg(ua, "Incremental\n");
252    bsendmsg(ua, "Full\n");
253    bsendmsg(ua, "Differential\n");
254    bsendmsg(ua, "Catalog\n");
255    bsendmsg(ua, "InitCatalog\n");
256    bsendmsg(ua, "VolumeToCatalog\n");
257    return 1;
258 }
259
260 /*
261  * Return default values for a job
262  */
263 static int defaultscmd(UAContext *ua, const char *cmd)
264 {
265    JOB *job;
266    CLIENT *client;
267    STORE *storage;
268    POOL *pool;
269
270    if (ua->argc != 2 || !ua->argv[1]) {
271       return 1;
272    }
273
274    /* Job defaults */   
275    if (strcmp(ua->argk[1], "job") == 0) {
276       if (!acl_access_ok(ua, Job_ACL, ua->argv[1])) {
277          return 1;
278       }
279       job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
280       if (job) {
281          STORE *store;
282          bsendmsg(ua, "job=%s", job->hdr.name);
283          bsendmsg(ua, "pool=%s", job->pool->hdr.name);
284          bsendmsg(ua, "messages=%s", job->messages->hdr.name);
285          bsendmsg(ua, "client=%s", job->client->hdr.name);
286          store = (STORE *)job->storage->first();
287          bsendmsg(ua, "storage=%s", store->hdr.name);
288          bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
289          bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
290          bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
291          bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
292          bsendmsg(ua, "enabled=%d", job->enabled);
293       }
294    } 
295    /* Client defaults */
296    else if (strcmp(ua->argk[1], "client") == 0) {
297      if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
298         return 1;   
299      }
300      client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
301      if (client) {
302        bsendmsg(ua, "client=%s", client->hdr.name);
303        bsendmsg(ua, "address=%s", client->address);
304        bsendmsg(ua, "fdport=%d", client->FDport);
305        bsendmsg(ua, "file_retention=%d", client->FileRetention);
306        bsendmsg(ua, "job_retention=%d", client->JobRetention);
307        bsendmsg(ua, "autoprune=%d", client->AutoPrune);
308      }
309    }
310    /* Storage defaults */
311    else if (strcmp(ua->argk[1], "storage") == 0) {
312      if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
313         return 1;
314      }
315      storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
316      DEVICE *device;
317      if (storage) {
318        bsendmsg(ua, "storage=%s", storage->hdr.name);
319        bsendmsg(ua, "address=%s", storage->address);
320        bsendmsg(ua, "enabled=%d", storage->enabled);
321        bsendmsg(ua, "media_type=%s", storage->media_type);
322        bsendmsg(ua, "sdport=%d", storage->SDport);
323        device = (DEVICE *)storage->device->first();
324        bsendmsg(ua, "device=%s", device->hdr.name);
325        if (storage->device->size() > 1) {
326          while ((device = (DEVICE *)storage->device->next()))
327            bsendmsg(ua, ",%s", device->hdr.name);
328        }
329      }
330    }
331    /* Pool defaults */
332    else if (strcmp(ua->argk[1], "pool") == 0) {
333      if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
334         return 1;
335      }
336      pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
337      if (pool) {
338        bsendmsg(ua, "pool=%s", pool->hdr.name);
339        bsendmsg(ua, "pool_type=%s", pool->pool_type);
340        bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:"");
341        bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once);
342        bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume);
343        bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume);
344        bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume);
345        bsendmsg(ua, "max_volumes=%d", pool->max_volumes);
346        bsendmsg(ua, "vol_retention=%d", pool->VolRetention);
347        bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration);
348        bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs);
349        bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles);
350        bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes);
351        bsendmsg(ua, "auto_prune=%d", pool->AutoPrune);
352        bsendmsg(ua, "recycle=%d", pool->Recycle);
353      }
354    }
355    return 1;
356 }