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