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