]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/dird/ua_dotcmds.c
kes Add dynamic dll entry point for SHGetFolderPath to Win32 code.
[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->name())) {
156          bsendmsg(ua, "%s\n", job->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->name())) {
169          bsendmsg(ua, "%s\n", fs->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->name())) {
182          bsendmsg(ua, "%s\n", client->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->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->name())) {
206          bsendmsg(ua, "%s\n", pool->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->name())) {
219          bsendmsg(ua, "%s\n", store->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_client_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->name());
300          bsendmsg(ua, "pool=%s", job->pool->name());
301          bsendmsg(ua, "messages=%s", job->messages->name());
302          bsendmsg(ua, "client=%s", job->client->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->name());
309          bsendmsg(ua, "enabled=%d", job->enabled);
310          bsendmsg(ua, "catalog=%s", job->client->catalog->name());
311       }
312    } 
313    /* Client defaults */
314    else if (strcmp(ua->argk[1], "client") == 0) {
315       if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
316          return 1;   
317       }
318       client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
319       if (client) {
320          bsendmsg(ua, "client=%s", client->name());
321          bsendmsg(ua, "address=%s", client->address);
322          bsendmsg(ua, "fdport=%d", client->FDport);
323          bsendmsg(ua, "file_retention=%d", client->FileRetention);
324          bsendmsg(ua, "job_retention=%d", client->JobRetention);
325          bsendmsg(ua, "autoprune=%d", client->AutoPrune);
326          bsendmsg(ua, "catalog=%s", client->catalog->name());
327       }
328    }
329    /* Storage defaults */
330    else if (strcmp(ua->argk[1], "storage") == 0) {
331       if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
332          return 1;
333       }
334       storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
335       DEVICE *device;
336       if (storage) {
337          bsendmsg(ua, "storage=%s", storage->name());
338          bsendmsg(ua, "address=%s", storage->address);
339          bsendmsg(ua, "enabled=%d", storage->enabled);
340          bsendmsg(ua, "media_type=%s", storage->media_type);
341          bsendmsg(ua, "sdport=%d", storage->SDport);
342          device = (DEVICE *)storage->device->first();
343          bsendmsg(ua, "device=%s", device->name());
344          if (storage->device->size() > 1) {
345             while ((device = (DEVICE *)storage->device->next())) {
346                bsendmsg(ua, ",%s", device->name());
347             }
348          }
349       }
350    }
351    /* Pool defaults */
352    else if (strcmp(ua->argk[1], "pool") == 0) {
353       if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
354          return 1;
355       }
356       pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
357       if (pool) {
358          bsendmsg(ua, "pool=%s", pool->name());
359          bsendmsg(ua, "pool_type=%s", pool->pool_type);
360          bsendmsg(ua, "label_format=%s", pool->label_format?pool->label_format:"");
361          bsendmsg(ua, "use_volume_once=%d", pool->use_volume_once);
362          bsendmsg(ua, "purge_oldest_volume=%d", pool->purge_oldest_volume);
363          bsendmsg(ua, "recycle_oldest_volume=%d", pool->recycle_oldest_volume);
364          bsendmsg(ua, "recycle_current_volume=%d", pool->recycle_current_volume);
365          bsendmsg(ua, "max_volumes=%d", pool->max_volumes);
366          bsendmsg(ua, "vol_retention=%d", pool->VolRetention);
367          bsendmsg(ua, "vol_use_duration=%d", pool->VolUseDuration);
368          bsendmsg(ua, "max_vol_jobs=%d", pool->MaxVolJobs);
369          bsendmsg(ua, "max_vol_files=%d", pool->MaxVolFiles);
370          bsendmsg(ua, "max_vol_bytes=%d", pool->MaxVolBytes);
371          bsendmsg(ua, "auto_prune=%d", pool->AutoPrune);
372          bsendmsg(ua, "recycle=%d", pool->Recycle);
373       }
374    }
375    return 1;
376 }