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