]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_dotcmds.c
ebl add Error status in update volume=xxx status=yyyy
[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    Bacula® - The Network Backup Solution
15
16    Copyright (C) 2002-2006 Free Software Foundation Europe e.V.
17
18    The main author of Bacula is Kern Sibbald, with contributions from
19    many others, a complete list can be found in the file AUTHORS.
20    This program is Free Software; you can redistribute it and/or
21    modify it under the terms of version two of the GNU General Public
22    License as published by the Free Software Foundation plus additions
23    that are listed in the file LICENSE.
24
25    This program is distributed in the hope that it will be useful, but
26    WITHOUT ANY WARRANTY; without even the implied warranty of
27    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28    General Public License for more details.
29
30    You should have received a copy of the GNU General Public License
31    along with this program; if not, write to the Free Software
32    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33    02110-1301, USA.
34
35    Bacula® is a registered trademark of John Walker.
36    The licensor of Bacula is the Free Software Foundation Europe
37    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
38    Switzerland, email:ftf@fsfeurope.org.
39 */
40
41 #include "bacula.h"
42 #include "dird.h"
43
44 /* Imported variables */
45 extern int r_first;
46 extern int r_last;
47 extern struct s_res resources[];
48
49 /* Imported functions */
50 extern void do_messages(UAContext *ua, const char *cmd);
51 extern int quit_cmd(UAContext *ua, const char *cmd);
52 extern int qhelp_cmd(UAContext *ua, const char *cmd);
53 extern int qstatus_cmd(UAContext *ua, const char *cmd);
54
55 /* Forward referenced functions */
56 static int diecmd(UAContext *ua, const char *cmd);
57 static int jobscmd(UAContext *ua, const char *cmd);
58 static int filesetscmd(UAContext *ua, const char *cmd);
59 static int clientscmd(UAContext *ua, const char *cmd);
60 static int msgscmd(UAContext *ua, const char *cmd);
61 static int poolscmd(UAContext *ua, const char *cmd);
62 static int storagecmd(UAContext *ua, const char *cmd);
63 static int defaultscmd(UAContext *ua, const char *cmd);
64 static int typescmd(UAContext *ua, const char *cmd);
65 static int backupscmd(UAContext *ua, const char *cmd);
66 static int levelscmd(UAContext *ua, const char *cmd);
67 static int getmsgscmd(UAContext *ua, const char *cmd);
68
69 struct cmdstruct { const char *key; int (*func)(UAContext *ua, const char *cmd); const char *help; };
70 static struct cmdstruct commands[] = {
71  { NT_(".backups"),    backupscmd,   NULL},
72  { NT_(".clients"),    clientscmd,   NULL},
73  { NT_(".defaults"),   defaultscmd,  NULL},
74  { NT_(".die"),        diecmd,       NULL},
75  { NT_(".exit"),       quit_cmd,     NULL},
76  { NT_(".filesets"),   filesetscmd,  NULL},
77  { NT_(".help"),       qhelp_cmd,    NULL},
78  { NT_(".jobs"),       jobscmd,      NULL},
79  { NT_(".levels"),     levelscmd,    NULL},
80  { NT_(".messages"),   getmsgscmd,   NULL},
81  { NT_(".msgs"),       msgscmd,      NULL},
82  { NT_(".pools"),      poolscmd,     NULL},
83  { NT_(".quit"),       quit_cmd,     NULL},
84  { NT_(".status"),     qstatus_cmd,  NULL},
85  { NT_(".storage"),    storagecmd,   NULL},
86  { NT_(".types"),      typescmd,     NULL} 
87              };
88 #define comsize (sizeof(commands)/sizeof(struct cmdstruct))
89
90 /*
91  * Execute a command from the UA
92  */
93 int do_a_dot_command(UAContext *ua, const char *cmd)
94 {
95    int i;
96    int len, stat;
97    bool found = false;
98
99    stat = 1;
100
101    Dmsg1(1400, "Dot command: %s\n", ua->UA_sock->msg);
102    if (ua->argc == 0) {
103       return 1;
104    }
105
106    len = strlen(ua->argk[0]);
107    if (len == 1) {
108       return 1;                       /* no op */
109    }
110    for (i=0; i<(int)comsize; i++) {     /* search for command */
111       if (strncasecmp(ua->argk[0],  _(commands[i].key), len) == 0) {
112          stat = (*commands[i].func)(ua, cmd);   /* go execute command */
113          found = true;
114          break;
115       }
116    }
117    if (!found) {
118       pm_strcat(ua->UA_sock->msg, _(": is an illegal command\n"));
119       ua->UA_sock->msglen = strlen(ua->UA_sock->msg);
120       bnet_send(ua->UA_sock);
121    }
122    return stat;
123 }
124
125 static int getmsgscmd(UAContext *ua, const char *cmd)
126 {
127    if (console_msg_pending) {
128       do_messages(ua, cmd);
129    }
130    return 1;
131 }
132
133 /*
134  * Create segmentation fault
135  */
136 static int diecmd(UAContext *ua, const char *cmd)
137 {
138    JCR *jcr = NULL;
139    int a;
140
141    bsendmsg(ua, _("The Director will segment fault.\n"));
142    a = jcr->JobId; /* ref NULL pointer */
143    jcr->JobId = 1000; /* another ref NULL pointer */
144    return 0;
145 }
146
147 static int jobscmd(UAContext *ua, const char *cmd)
148 {
149    JOB *job = NULL;
150    LockRes();
151    while ( (job = (JOB *)GetNextRes(R_JOB, (RES *)job)) ) {
152       if (acl_access_ok(ua, Job_ACL, job->hdr.name)) {
153          bsendmsg(ua, "%s\n", job->hdr.name);
154       }
155    }
156    UnlockRes();
157    return 1;
158 }
159
160 static int filesetscmd(UAContext *ua, const char *cmd)
161 {
162    FILESET *fs = NULL;
163    LockRes();
164    while ( (fs = (FILESET *)GetNextRes(R_FILESET, (RES *)fs)) ) {
165       if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) {
166          bsendmsg(ua, "%s\n", fs->hdr.name);
167       }
168    }
169    UnlockRes();
170    return 1;
171 }
172
173 static int clientscmd(UAContext *ua, const char *cmd)
174 {
175    CLIENT *client = NULL;
176    LockRes();
177    while ( (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)) ) {
178       if (acl_access_ok(ua, Client_ACL, client->hdr.name)) {
179          bsendmsg(ua, "%s\n", client->hdr.name);
180       }
181    }
182    UnlockRes();
183    return 1;
184 }
185
186 static int msgscmd(UAContext *ua, const char *cmd)
187 {
188    MSGS *msgs = NULL;
189    LockRes();
190    while ( (msgs = (MSGS *)GetNextRes(R_MSGS, (RES *)msgs)) ) {
191       bsendmsg(ua, "%s\n", msgs->hdr.name);
192    }
193    UnlockRes();
194    return 1;
195 }
196
197 static int poolscmd(UAContext *ua, const char *cmd)
198 {
199    POOL *pool = NULL;
200    LockRes();
201    while ( (pool = (POOL *)GetNextRes(R_POOL, (RES *)pool)) ) {
202       if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
203          bsendmsg(ua, "%s\n", pool->hdr.name);
204       }
205    }
206    UnlockRes();
207    return 1;
208 }
209
210 static int storagecmd(UAContext *ua, const char *cmd)
211 {
212    STORE *store = NULL;
213    LockRes();
214    while ( (store = (STORE *)GetNextRes(R_STORAGE, (RES *)store)) ) {
215       if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
216          bsendmsg(ua, "%s\n", store->hdr.name);
217       }
218    }
219    UnlockRes();
220    return 1;
221 }
222
223
224 static int typescmd(UAContext *ua, const char *cmd)
225 {
226    bsendmsg(ua, "Backup\n");
227    bsendmsg(ua, "Restore\n");
228    bsendmsg(ua, "Admin\n");
229    bsendmsg(ua, "Verify\n");
230    return 1;
231 }
232
233 static int client_backups_handler(void *ctx, int num_field, char **row)
234 {
235    UAContext *ua = (UAContext *)ctx;
236    bsendmsg(ua, "| %s | %s | %s | %s | %s | %s | %s | %s |\n",
237       row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]);
238    return 0;
239 }
240
241 static int backupscmd(UAContext *ua, const char *cmd)
242 {
243    if (!open_db(ua)) {
244       return 1;
245    }
246    if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 || strcmp(ua->argk[2], "fileset") != 0) {
247       return 1;
248    }
249    if (!acl_access_ok(ua, Client_ACL, ua->argv[1]) ||
250        !acl_access_ok(ua, FileSet_ACL, ua->argv[2])) {
251       return 1;
252    }
253    Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
254    if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
255       bsendmsg(ua, _("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
256       return 1;
257    }
258    return 1;
259 }
260
261
262 static int levelscmd(UAContext *ua, const char *cmd)
263 {
264    bsendmsg(ua, "Incremental\n");
265    bsendmsg(ua, "Full\n");
266    bsendmsg(ua, "Differential\n");
267    bsendmsg(ua, "Catalog\n");
268    bsendmsg(ua, "InitCatalog\n");
269    bsendmsg(ua, "VolumeToCatalog\n");
270    return 1;
271 }
272
273 /*
274  * Return default values for a job
275  */
276 static int defaultscmd(UAContext *ua, const char *cmd)
277 {
278    JOB *job;
279    CLIENT *client;
280    STORE *storage;
281    POOL *pool;
282
283    if (ua->argc != 2 || !ua->argv[1]) {
284       return 1;
285    }
286
287    /* Job defaults */   
288    if (strcmp(ua->argk[1], "job") == 0) {
289       if (!acl_access_ok(ua, Job_ACL, ua->argv[1])) {
290          return 1;
291       }
292       job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
293       if (job) {
294          STORE *store;
295          bsendmsg(ua, "job=%s", job->hdr.name);
296          bsendmsg(ua, "pool=%s", job->pool->hdr.name);
297          bsendmsg(ua, "messages=%s", job->messages->hdr.name);
298          bsendmsg(ua, "client=%s", job->client->hdr.name);
299          store = (STORE *)job->storage->first();
300          bsendmsg(ua, "storage=%s", store->hdr.name);
301          bsendmsg(ua, "where=%s", job->RestoreWhere?job->RestoreWhere:"");
302          bsendmsg(ua, "level=%s", level_to_str(job->JobLevel));
303          bsendmsg(ua, "type=%s", job_type_to_str(job->JobType));
304          bsendmsg(ua, "fileset=%s", job->fileset->hdr.name);
305          bsendmsg(ua, "enabled=%d", job->enabled);
306       }
307    } 
308    /* Client defaults */
309    else if (strcmp(ua->argk[1], "client") == 0) {
310      if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
311         return 1;   
312      }
313      client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
314      if (client) {
315        bsendmsg(ua, "client=%s", client->hdr.name);
316        bsendmsg(ua, "address=%s", client->address);
317        bsendmsg(ua, "fdport=%d", client->FDport);
318        bsendmsg(ua, "file_retention=%d", client->FileRetention);
319        bsendmsg(ua, "job_retention=%d", client->JobRetention);
320        bsendmsg(ua, "autoprune=%d", client->AutoPrune);
321      }
322    }
323    /* Storage defaults */
324    else if (strcmp(ua->argk[1], "storage") == 0) {
325      if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
326         return 1;
327      }
328      storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
329      DEVICE *device;
330      if (storage) {
331        bsendmsg(ua, "storage=%s", storage->hdr.name);
332        bsendmsg(ua, "address=%s", storage->address);
333        bsendmsg(ua, "enabled=%d", storage->enabled);
334        bsendmsg(ua, "media_type=%s", storage->media_type);
335        bsendmsg(ua, "sdport=%d", storage->SDport);
336        device = (DEVICE *)storage->device->first();
337        bsendmsg(ua, "device=%s", device->hdr.name);
338        if (storage->device->size() > 1) {
339          while ((device = (DEVICE *)storage->device->next()))
340            bsendmsg(ua, ",%s", device->hdr.name);
341        }
342      }
343    }
344    /* Pool defaults */
345    else if (strcmp(ua->argk[1], "pool") == 0) {
346      if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
347         return 1;
348      }
349      pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
350      if (pool) {
351        bsendmsg(ua, "pool=%s", pool->hdr.name);
352        bsendmsg(ua, "pool_type=%s", pool->pool_type);
353        bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:"");
354        bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once);
355        bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume);
356        bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume);
357        bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume);
358        bsendmsg(ua, "max_volumes=%d", pool->max_volumes);
359        bsendmsg(ua, "vol_retention=%d", pool->VolRetention);
360        bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration);
361        bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs);
362        bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles);
363        bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes);
364        bsendmsg(ua, "auto_prune=%d", pool->AutoPrune);
365        bsendmsg(ua, "recycle=%d", pool->Recycle);
366      }
367    }
368    return 1;
369 }