2 Bacula® - The Network Backup Solution
4 Copyright (C) 2002-2009 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version two of the GNU General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- User Agent Commands
31 * These are "dot" commands, i.e. commands preceded
32 * by a period. These commands are meant to be used
33 * by a program, so there is no prompting, and the
34 * returned results are (supposed to be) predictable.
36 * Kern Sibbald, April MMII
42 #include "cats/bvfs.h"
43 #include "findlib/find.h"
45 /* Imported variables */
47 /* Imported functions */
48 extern void do_messages(UAContext *ua, const char *cmd);
49 extern int quit_cmd(UAContext *ua, const char *cmd);
50 extern int qhelp_cmd(UAContext *ua, const char *cmd);
51 extern bool dot_status_cmd(UAContext *ua, const char *cmd);
54 /* Forward referenced functions */
55 static bool diecmd(UAContext *ua, const char *cmd);
56 static bool jobscmd(UAContext *ua, const char *cmd);
57 static bool filesetscmd(UAContext *ua, const char *cmd);
58 static bool clientscmd(UAContext *ua, const char *cmd);
59 static bool msgscmd(UAContext *ua, const char *cmd);
60 static bool poolscmd(UAContext *ua, const char *cmd);
61 static bool storagecmd(UAContext *ua, const char *cmd);
62 static bool defaultscmd(UAContext *ua, const char *cmd);
63 static bool typescmd(UAContext *ua, const char *cmd);
64 static bool backupscmd(UAContext *ua, const char *cmd);
65 static bool levelscmd(UAContext *ua, const char *cmd);
66 static bool getmsgscmd(UAContext *ua, const char *cmd);
67 static bool volstatuscmd(UAContext *ua, const char *cmd);
68 static bool mediatypescmd(UAContext *ua, const char *cmd);
69 static bool locationscmd(UAContext *ua, const char *cmd);
70 static bool mediacmd(UAContext *ua, const char *cmd);
71 static bool aopcmd(UAContext *ua, const char *cmd);
73 static bool dot_bvfs_lsdirs(UAContext *ua, const char *cmd);
74 static bool dot_bvfs_lsfiles(UAContext *ua, const char *cmd);
75 static bool dot_bvfs_update(UAContext *ua, const char *cmd);
77 static bool api_cmd(UAContext *ua, const char *cmd);
78 static bool sql_cmd(UAContext *ua, const char *cmd);
79 static bool dot_quit_cmd(UAContext *ua, const char *cmd);
80 static bool dot_help_cmd(UAContext *ua, const char *cmd);
82 struct cmdstruct { const char *key; bool (*func)(UAContext *ua, const char *cmd); const char *help;const bool use_in_rs;};
83 static struct cmdstruct commands[] = { /* help */ /* can be used in runscript */
84 { NT_(".api"), api_cmd, NULL, false},
85 { NT_(".backups"), backupscmd, NULL, false},
86 { NT_(".clients"), clientscmd, NULL, true},
87 { NT_(".defaults"), defaultscmd, NULL, false},
88 { NT_(".die"), diecmd, NULL, false},
89 { NT_(".exit"), dot_quit_cmd, NULL, false},
90 { NT_(".filesets"), filesetscmd, NULL, false},
91 { NT_(".help"), dot_help_cmd, NULL, false},
92 { NT_(".jobs"), jobscmd, NULL, true},
93 { NT_(".levels"), levelscmd, NULL, false},
94 { NT_(".messages"), getmsgscmd, NULL, false},
95 { NT_(".msgs"), msgscmd, NULL, false},
96 { NT_(".pools"), poolscmd, NULL, true},
97 { NT_(".quit"), dot_quit_cmd, NULL, false},
98 { NT_(".sql"), sql_cmd, NULL, false},
99 { NT_(".status"), dot_status_cmd, NULL, false},
100 { NT_(".storage"), storagecmd, NULL, true},
101 { NT_(".volstatus"), volstatuscmd, NULL, true},
102 { NT_(".media"), mediacmd, NULL, true},
103 { NT_(".mediatypes"), mediatypescmd, NULL, true},
104 { NT_(".locations"), locationscmd, NULL, true},
105 { NT_(".actiononpurge"),aopcmd, NULL, true},
106 { NT_(".bvfs_lsdirs"), dot_bvfs_lsdirs, NULL, true},
107 { NT_(".bvfs_lsfiles"),dot_bvfs_lsfiles,NULL, true},
108 { NT_(".bvfs_update"), dot_bvfs_update, NULL, true},
109 { NT_(".types"), typescmd, NULL, false}
111 #define comsize ((int)(sizeof(commands)/sizeof(struct cmdstruct)))
114 * Execute a command from the UA
116 bool do_a_dot_command(UAContext *ua)
122 BSOCK *user = ua->UA_sock;
124 Dmsg1(1400, "Dot command: %s\n", user->msg);
129 len = strlen(ua->argk[0]);
131 if (ua->api) user->signal(BNET_CMD_BEGIN);
132 if (ua->api) user->signal(BNET_CMD_OK);
133 return true; /* no op */
135 for (i=0; i<comsize; i++) { /* search for command */
136 if (strncasecmp(ua->argk[0], _(commands[i].key), len) == 0) {
137 /* Check if this command is authorized in RunScript */
138 if (ua->runscript && !commands[i].use_in_rs) {
139 ua->error_msg(_("Can't use %s command in a runscript"), ua->argk[0]);
143 /* Check if command permitted, but "quit" is always OK */
144 if (strcmp(ua->argk[0], NT_(".quit")) != 0 &&
145 !acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
148 Dmsg1(100, "Cmd: %s\n", ua->cmd);
150 if (ua->api) user->signal(BNET_CMD_BEGIN);
151 ok = (*commands[i].func)(ua, ua->cmd); /* go execute command */
152 if (ua->api) user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
159 pm_strcat(user->msg, _(": is an invalid command.\n"));
160 ua->error_msg("%s", user->msg);
166 static bool dot_bvfs_update(UAContext *ua, const char *cmd)
168 if (!open_new_client_db(ua)) {
172 int pos = find_arg_with_value(ua, "jobid");
173 if (pos != -1 && is_a_number_list(ua->argv[pos])) {
175 pm_strcpy(jobids, ua->argv[pos]);
176 bvfs_update_path_hierarchy_cache(ua->jcr, ua->db, jobids.c_str());
178 /* update cache for all jobids */
179 bvfs_update_cache(ua->jcr, ua->db);
186 static int bvfs_result_handler(void *ctx, int fields, char **row)
188 UAContext *ua = (UAContext *)ctx;
191 char *fileid=row[BVFS_FileId];
192 char *lstat=row[BVFS_LStat];
193 char *jobid=row[BVFS_JobId];
195 char empty[] = "A A A A A A A A A A A A A A";
198 /* We need to deal with non existant path */
199 if (!fileid || !is_a_number(fileid)) {
205 memset(&statp, 0, sizeof(struct stat));
206 decode_stat(lstat, &statp, &LinkFI);
208 Dmsg1(100, "type=%s\n", row[0]);
209 if (bvfs_is_dir(row)) {
210 char *path = bvfs_basename_dir(row[BVFS_Name]);
211 ua->send_msg("%s\t0\t%s\t%s\t%s\t%s\n", row[BVFS_PathId], fileid,
214 } else if (bvfs_is_file(row)) {
215 ua->send_msg("%s\t%s\t%s\t%s\t%s\t%s\n", row[BVFS_PathId],
216 row[BVFS_FilenameId], fileid, jobid,
217 lstat, row[BVFS_Name]);
223 static bool bvfs_parse_arg(UAContext *ua,
224 DBId_t *pathid, char **path, char **jobid,
225 int *limit, int *offset)
233 for (int i=1; i<ua->argc; i++) {
234 if (strcasecmp(ua->argk[i], NT_("pathid")) == 0) {
235 if (is_a_number(ua->argv[i])) {
236 *pathid = str_to_int64(ua->argv[i]);
239 if (strcasecmp(ua->argk[i], NT_("path")) == 0) {
243 if (strcasecmp(ua->argk[i], NT_("jobid")) == 0) {
244 if (is_a_number_list(ua->argv[i])) {
245 *jobid = ua->argv[i];
249 if (strcasecmp(ua->argk[i], NT_("limit")) == 0) {
250 if (is_a_number(ua->argv[i])) {
251 *limit = str_to_int64(ua->argv[i]);
255 if (strcasecmp(ua->argk[i], NT_("offset")) == 0) {
256 if (is_a_number(ua->argv[i])) {
257 *offset = str_to_int64(ua->argv[i]);
262 if (!((*pathid || *path) && *jobid)) {
266 if (!open_client_db(ua)) {
274 * .bvfs_lsfiles jobid=1,2,3,4 pathid=10
275 * .bvfs_lsfiles jobid=1,2,3,4 path=/
277 static bool dot_bvfs_lsfiles(UAContext *ua, const char *cmd)
280 int limit=2000, offset=0;
281 char *path=NULL, *jobid=NULL;
283 if (!bvfs_parse_arg(ua, &pathid, &path, &jobid,
286 ua->error_msg("Can't find jobid, pathid or path argument\n");
287 return true; /* not enough param */
290 Bvfs fs(ua->jcr, ua->db);
291 fs.set_jobids(jobid);
292 fs.set_handler(bvfs_result_handler, ua);
301 fs.set_offset(offset);
309 * .bvfs_lsdirs jobid=1,2,3,4 pathid=10
310 * .bvfs_lsdirs jobid=1,2,3,4 path=/
311 * .bvfs_lsdirs jobid=1,2,3,4 path=
313 static bool dot_bvfs_lsdirs(UAContext *ua, const char *cmd)
316 int limit=2000, offset=0;
317 char *path=NULL, *jobid=NULL;
319 if (!bvfs_parse_arg(ua, &pathid, &path, &jobid,
322 ua->error_msg("Can't find jobid, pathid or path argument\n");
323 return true; /* not enough param */
326 Bvfs fs(ua->jcr, ua->db);
327 fs.set_jobids(jobid);
329 fs.set_handler(bvfs_result_handler, ua);
337 fs.set_offset(offset);
339 fs.ls_special_dirs();
345 static bool dot_quit_cmd(UAContext *ua, const char *cmd)
351 static bool dot_help_cmd(UAContext *ua, const char *cmd)
357 static bool getmsgscmd(UAContext *ua, const char *cmd)
359 if (console_msg_pending) {
360 do_messages(ua, cmd);
366 static void do_storage_die(UAContext *ua, STORE *store, const char *cmd)
372 lstore.store = store;
373 pm_strcpy(lstore.store_source, _("unknown source"));
374 set_wstorage(jcr, &lstore);
375 /* Try connecting for up to 15 seconds */
376 ua->send_msg(_("Connecting to Storage daemon %s at %s:%d\n"),
377 store->name(), store->address, store->SDport);
378 if (!connect_to_storage_daemon(jcr, 1, 15, 0)) {
379 ua->error_msg(_("Failed to connect to Storage daemon.\n"));
382 Dmsg0(120, _("Connected to storage daemon\n"));
383 sd = jcr->store_bsock;
384 sd->fsend("%s", cmd);
385 if (sd->recv() >= 0) {
386 ua->send_msg("%s", sd->msg);
388 sd->signal(BNET_TERMINATE);
390 jcr->store_bsock = NULL;
394 static void do_client_die(UAContext *ua, CLIENT *client, const char *cmd)
398 /* Connect to File daemon */
400 ua->jcr->client = client;
401 /* Try to connect for 15 seconds */
402 ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
403 client->name(), client->address, client->FDport);
404 if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
405 ua->error_msg(_("Failed to connect to Client.\n"));
408 Dmsg0(120, "Connected to file daemon\n");
409 fd = ua->jcr->file_bsock;
410 fd->fsend("%s", cmd);
411 if (fd->recv() >= 0) {
412 ua->send_msg("%s", fd->msg);
414 fd->signal(BNET_TERMINATE);
416 ua->jcr->file_bsock = NULL;
421 * Create segmentation fault
423 static bool diecmd(UAContext *ua, const char *cmd)
425 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
429 bool do_deadlock=false;
430 const char *remote_cmd=".die";
435 Dmsg1(120, "diecmd:%s:\n", cmd);
438 for (i=1; i<ua->argc; i++) {
439 if (strcasecmp(ua->argk[i], "deadlock") == 0) {
441 remote_cmd = ".die deadlock";
443 if (strcasecmp(ua->argk[i], "dir") == 0 ||
444 strcasecmp(ua->argk[i], "director") == 0) {
447 if (strcasecmp(ua->argk[i], "client") == 0 ||
448 strcasecmp(ua->argk[i], "fd") == 0) {
451 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
454 client = select_client_resource(ua);
458 if (strcasecmp(ua->argk[i], NT_("store")) == 0 ||
459 strcasecmp(ua->argk[i], NT_("storage")) == 0 ||
460 strcasecmp(ua->argk[i], NT_("sd")) == 0) {
463 store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
466 store = get_storage_resource(ua, false/*no default*/);
471 if (!dir && !store && !client) {
473 * We didn't find an appropriate keyword above, so
476 start_prompt(ua, _("Available daemons are: \n"));
477 add_prompt(ua, _("Director"));
478 add_prompt(ua, _("Storage"));
479 add_prompt(ua, _("Client"));
480 switch(do_prompt(ua, "", _("Select daemon type to make die"), NULL, 0)) {
481 case 0: /* Director */
485 store = get_storage_resource(ua, false/*no default*/);
488 client = select_client_resource(ua);
496 do_storage_die(ua, store, remote_cmd);
500 do_client_die(ua, client, remote_cmd);
505 ua->send_msg(_("The Director will generate a deadlock.\n"));
509 ua->send_msg(_("The Director will segment fault.\n"));
510 a = jcr->JobId; /* ref NULL pointer */
511 jcr->JobId = 1000; /* another ref NULL pointer */
520 * Dummy routine for non-development version
522 static bool diecmd(UAContext *ua, const char *cmd)
530 * Can use an argument to filter on JobType
533 static bool jobscmd(UAContext *ua, const char *cmd)
538 if ((pos = find_arg_with_value(ua, "type")) >= 0) {
539 type = ua->argv[pos][0];
542 foreach_res(job, R_JOB) {
543 if (!type || type == job->JobType) {
544 if (acl_access_ok(ua, Job_ACL, job->name())) {
545 ua->send_msg("%s\n", job->name());
553 static bool filesetscmd(UAContext *ua, const char *cmd)
557 foreach_res(fs, R_FILESET) {
558 if (acl_access_ok(ua, FileSet_ACL, fs->name())) {
559 ua->send_msg("%s\n", fs->name());
566 static bool clientscmd(UAContext *ua, const char *cmd)
570 foreach_res(client, R_CLIENT) {
571 if (acl_access_ok(ua, Client_ACL, client->name())) {
572 ua->send_msg("%s\n", client->name());
579 static bool msgscmd(UAContext *ua, const char *cmd)
583 foreach_res(msgs, R_MSGS) {
584 ua->send_msg("%s\n", msgs->name());
590 static bool poolscmd(UAContext *ua, const char *cmd)
594 foreach_res(pool, R_POOL) {
595 if (acl_access_ok(ua, Pool_ACL, pool->name())) {
596 ua->send_msg("%s\n", pool->name());
603 static bool storagecmd(UAContext *ua, const char *cmd)
607 foreach_res(store, R_STORAGE) {
608 if (acl_access_ok(ua, Storage_ACL, store->name())) {
609 ua->send_msg("%s\n", store->name());
616 static bool aopcmd(UAContext *ua, const char *cmd)
618 ua->send_msg("None\n");
619 ua->send_msg("Truncate\n");
623 static bool typescmd(UAContext *ua, const char *cmd)
625 ua->send_msg("Backup\n");
626 ua->send_msg("Restore\n");
627 ua->send_msg("Admin\n");
628 ua->send_msg("Verify\n");
629 ua->send_msg("Migrate\n");
634 * If this command is called, it tells the director that we
635 * are a program that wants a sort of API, and hence,
636 * we will probably suppress certain output, include more
637 * error codes, and most of all send back a good number
638 * of new signals that indicate whether or not the command
641 static bool api_cmd(UAContext *ua, const char *cmd)
644 ua->api = atoi(ua->argk[1]);
651 static int client_backups_handler(void *ctx, int num_field, char **row)
653 UAContext *ua = (UAContext *)ctx;
654 ua->send_msg("| %s | %s | %s | %s | %s | %s | %s | %s |\n",
655 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]);
660 * Return the backups for this client
662 * .backups client=xxx fileset=yyy
665 static bool backupscmd(UAContext *ua, const char *cmd)
667 if (!open_client_db(ua)) {
670 if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 ||
671 strcmp(ua->argk[2], "fileset") != 0) {
674 if (!acl_access_ok(ua, Client_ACL, ua->argv[1]) ||
675 !acl_access_ok(ua, FileSet_ACL, ua->argv[2])) {
676 ua->error_msg(_("Access to specified Client or FileSet not allowed.\n"));
679 Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
680 if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
681 ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
687 static int sql_handler(void *ctx, int num_field, char **row)
689 UAContext *ua = (UAContext *)ctx;
690 POOL_MEM rows(PM_MESSAGE);
692 /* Check for nonsense */
693 if (num_field == 0 || row == NULL || row[0] == NULL) {
694 return 0; /* nothing returned */
696 for (int i=0; num_field--; i++) {
698 pm_strcpy(rows, NPRT(row[0]));
700 pm_strcat(rows, NPRT(row[i]));
702 pm_strcat(rows, "\t");
704 if (!rows.c_str() || !*rows.c_str()) {
707 ua->send_msg("%s", rows.c_str());
712 static bool sql_cmd(UAContext *ua, const char *cmd)
715 if (!open_client_db(ua)) {
718 index = find_arg_with_value(ua, "query");
720 ua->error_msg(_("query keyword not found.\n"));
723 if (!db_sql_query(ua->db, ua->argv[index], sql_handler, (void *)ua)) {
724 Dmsg1(100, "Query failed: ERR=%s\n", db_strerror(ua->db));
725 ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
731 static int one_handler(void *ctx, int num_field, char **row)
733 UAContext *ua = (UAContext *)ctx;
734 ua->send_msg("%s\n", row[0]);
738 static bool mediatypescmd(UAContext *ua, const char *cmd)
740 if (!open_client_db(ua)) {
743 if (!db_sql_query(ua->db,
744 "SELECT DISTINCT MediaType FROM MediaType ORDER BY MediaType",
745 one_handler, (void *)ua))
747 ua->error_msg(_("List MediaType failed: ERR=%s\n"), db_strerror(ua->db));
752 static bool mediacmd(UAContext *ua, const char *cmd)
754 if (!open_client_db(ua)) {
757 if (!db_sql_query(ua->db,
758 "SELECT DISTINCT Media.VolumeName FROM Media ORDER BY VolumeName",
759 one_handler, (void *)ua))
761 ua->error_msg(_("List Media failed: ERR=%s\n"), db_strerror(ua->db));
766 static bool locationscmd(UAContext *ua, const char *cmd)
768 if (!open_client_db(ua)) {
771 if (!db_sql_query(ua->db,
772 "SELECT DISTINCT Location FROM Location ORDER BY Location",
773 one_handler, (void *)ua))
775 ua->error_msg(_("List Location failed: ERR=%s\n"), db_strerror(ua->db));
780 static bool levelscmd(UAContext *ua, const char *cmd)
782 ua->send_msg("Incremental\n");
783 ua->send_msg("Full\n");
784 ua->send_msg("Differential\n");
785 ua->send_msg("VirtualFull\n");
786 ua->send_msg("Catalog\n");
787 ua->send_msg("InitCatalog\n");
788 ua->send_msg("VolumeToCatalog\n");
792 static bool volstatuscmd(UAContext *ua, const char *cmd)
794 ua->send_msg("Append\n");
795 ua->send_msg("Full\n");
796 ua->send_msg("Used\n");
797 ua->send_msg("Recycle\n");
798 ua->send_msg("Purged\n");
799 ua->send_msg("Cleaning\n");
800 ua->send_msg("Error\n");
805 * Return default values for a job
807 static bool defaultscmd(UAContext *ua, const char *cmd)
815 if (ua->argc != 2 || !ua->argv[1]) {
820 if (strcmp(ua->argk[1], "job") == 0) {
821 if (!acl_access_ok(ua, Job_ACL, ua->argv[1])) {
824 job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
827 ua->send_msg("job=%s", job->name());
828 ua->send_msg("pool=%s", job->pool->name());
829 ua->send_msg("messages=%s", job->messages->name());
830 ua->send_msg("client=%s", job->client->name());
831 get_job_storage(&store, job, NULL);
832 ua->send_msg("storage=%s", store.store->name());
833 ua->send_msg("where=%s", job->RestoreWhere?job->RestoreWhere:"");
834 ua->send_msg("level=%s", level_to_str(job->JobLevel));
835 ua->send_msg("type=%s", job_type_to_str(job->JobType));
836 ua->send_msg("fileset=%s", job->fileset->name());
837 ua->send_msg("enabled=%d", job->enabled);
838 ua->send_msg("catalog=%s", job->client->catalog->name());
841 /* Client defaults */
842 else if (strcmp(ua->argk[1], "client") == 0) {
843 if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
846 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
848 ua->send_msg("client=%s", client->name());
849 ua->send_msg("address=%s", client->address);
850 ua->send_msg("fdport=%d", client->FDport);
851 ua->send_msg("file_retention=%s", edit_uint64(client->FileRetention, ed1));
852 ua->send_msg("job_retention=%s", edit_uint64(client->JobRetention, ed1));
853 ua->send_msg("autoprune=%d", client->AutoPrune);
854 ua->send_msg("catalog=%s", client->catalog->name());
857 /* Storage defaults */
858 else if (strcmp(ua->argk[1], "storage") == 0) {
859 if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
862 storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
865 ua->send_msg("storage=%s", storage->name());
866 ua->send_msg("address=%s", storage->address);
867 ua->send_msg("enabled=%d", storage->enabled);
868 ua->send_msg("media_type=%s", storage->media_type);
869 ua->send_msg("sdport=%d", storage->SDport);
870 device = (DEVICE *)storage->device->first();
871 ua->send_msg("device=%s", device->name());
872 if (storage->device->size() > 1) {
873 while ((device = (DEVICE *)storage->device->next())) {
874 ua->send_msg(",%s", device->name());
880 else if (strcmp(ua->argk[1], "pool") == 0) {
881 if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
884 pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
886 ua->send_msg("pool=%s", pool->name());
887 ua->send_msg("pool_type=%s", pool->pool_type);
888 ua->send_msg("label_format=%s", pool->label_format?pool->label_format:"");
889 ua->send_msg("use_volume_once=%d", pool->use_volume_once);
890 ua->send_msg("purge_oldest_volume=%d", pool->purge_oldest_volume);
891 ua->send_msg("recycle_oldest_volume=%d", pool->recycle_oldest_volume);
892 ua->send_msg("recycle_current_volume=%d", pool->recycle_current_volume);
893 ua->send_msg("max_volumes=%d", pool->max_volumes);
894 ua->send_msg("vol_retention=%s", edit_uint64(pool->VolRetention, ed1));
895 ua->send_msg("vol_use_duration=%s", edit_uint64(pool->VolUseDuration, ed1));
896 ua->send_msg("max_vol_jobs=%d", pool->MaxVolJobs);
897 ua->send_msg("max_vol_files=%d", pool->MaxVolFiles);
898 ua->send_msg("max_vol_bytes=%s", edit_uint64(pool->MaxVolBytes, ed1));
899 ua->send_msg("auto_prune=%d", pool->AutoPrune);
900 ua->send_msg("recycle=%d", pool->Recycle);
901 ua->send_msg("file_retention=%s", edit_uint64(pool->FileRetention, ed1));
902 ua->send_msg("job_retention=%s", edit_uint64(pool->JobRetention, ed1));