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)
169 if (!open_client_db(ua)) {
173 int pos = find_arg_with_value(ua, "jobid");
174 if (pos != -1 && is_a_number_list(ua->argv[pos])) {
176 pm_strcpy(jobids, ua->argv[pos]);
177 bvfs_update_path_hierarchy_cache(ua->jcr, ua->db, jobids.c_str());
179 /* update cache for all jobids */
180 bvfs_update_cache(ua->jcr, ua->db);
185 static int bvfs_result_handler(void *ctx, int fields, char **row)
187 UAContext *ua = (UAContext *)ctx;
190 char *fileid=row[BVFS_FileId];
191 char *lstat=row[BVFS_LStat];
192 char *jobid=row[BVFS_JobId];
194 char empty[] = "A A A A A A A A A A A A A A";
197 /* We need to deal with non existant path */
198 if (!fileid || !is_a_number(fileid)) {
204 memset(&statp, 0, sizeof(struct stat));
205 decode_stat(lstat, &statp, &LinkFI);
207 Dmsg1(100, "type=%s\n", row[0]);
208 if (bvfs_is_dir(row)) {
209 char *path = bvfs_basename_dir(row[BVFS_Name]);
210 ua->send_msg("%s\t0\t%s\t%s\t%s\t%s\n", row[BVFS_PathId], fileid,
213 } else if (bvfs_is_file(row)) {
214 ua->send_msg("%s\t%s\t%s\t%s\t%s\t%s\n", row[BVFS_PathId],
215 row[BVFS_FilenameId], fileid, jobid,
216 lstat, row[BVFS_Name]);
222 static bool bvfs_parse_arg(UAContext *ua,
223 DBId_t *pathid, char **path, char **jobid,
224 int *limit, int *offset)
232 for (int i=1; i<ua->argc; i++) {
233 if (strcasecmp(ua->argk[i], NT_("pathid")) == 0) {
234 if (is_a_number(ua->argv[i])) {
235 *pathid = str_to_int64(ua->argv[i]);
238 if (strcasecmp(ua->argk[i], NT_("path")) == 0) {
242 if (strcasecmp(ua->argk[i], NT_("jobid")) == 0) {
243 if (is_a_number_list(ua->argv[i])) {
244 *jobid = ua->argv[i];
248 if (strcasecmp(ua->argk[i], NT_("limit")) == 0) {
249 if (is_a_number(ua->argv[i])) {
250 *limit = str_to_int64(ua->argv[i]);
254 if (strcasecmp(ua->argk[i], NT_("offset")) == 0) {
255 if (is_a_number(ua->argv[i])) {
256 *offset = str_to_int64(ua->argv[i]);
261 if (!((*pathid || *path) && *jobid)) {
265 if (!open_client_db(ua)) {
273 * .bvfs_lsfiles jobid=1,2,3,4 pathid=10
274 * .bvfs_lsfiles jobid=1,2,3,4 path=/
276 static bool dot_bvfs_lsfiles(UAContext *ua, const char *cmd)
279 int limit=2000, offset=0;
280 char *path=NULL, *jobid=NULL;
282 if (!bvfs_parse_arg(ua, &pathid, &path, &jobid,
285 ua->error_msg("Can't find jobid, pathid or path argument\n");
286 return true; /* not enough param */
289 Bvfs fs(ua->jcr, ua->db);
290 fs.set_jobids(jobid);
291 fs.set_handler(bvfs_result_handler, ua);
300 fs.set_offset(offset);
308 * .bvfs_lsdirs jobid=1,2,3,4 pathid=10
309 * .bvfs_lsdirs jobid=1,2,3,4 path=/
310 * .bvfs_lsdirs jobid=1,2,3,4 path=
312 static bool dot_bvfs_lsdirs(UAContext *ua, const char *cmd)
315 int limit=2000, offset=0;
316 char *path=NULL, *jobid=NULL;
318 if (!bvfs_parse_arg(ua, &pathid, &path, &jobid,
321 ua->error_msg("Can't find jobid, pathid or path argument\n");
322 return true; /* not enough param */
325 Bvfs fs(ua->jcr, ua->db);
326 fs.set_jobids(jobid);
328 fs.set_handler(bvfs_result_handler, ua);
336 fs.set_offset(offset);
338 fs.ls_special_dirs();
344 static bool dot_quit_cmd(UAContext *ua, const char *cmd)
350 static bool dot_help_cmd(UAContext *ua, const char *cmd)
356 static bool getmsgscmd(UAContext *ua, const char *cmd)
358 if (console_msg_pending) {
359 do_messages(ua, cmd);
365 static void do_storage_die(UAContext *ua, STORE *store, const char *cmd)
371 lstore.store = store;
372 pm_strcpy(lstore.store_source, _("unknown source"));
373 set_wstorage(jcr, &lstore);
374 /* Try connecting for up to 15 seconds */
375 ua->send_msg(_("Connecting to Storage daemon %s at %s:%d\n"),
376 store->name(), store->address, store->SDport);
377 if (!connect_to_storage_daemon(jcr, 1, 15, 0)) {
378 ua->error_msg(_("Failed to connect to Storage daemon.\n"));
381 Dmsg0(120, _("Connected to storage daemon\n"));
382 sd = jcr->store_bsock;
383 sd->fsend("%s", cmd);
384 if (sd->recv() >= 0) {
385 ua->send_msg("%s", sd->msg);
387 sd->signal(BNET_TERMINATE);
389 jcr->store_bsock = NULL;
393 static void do_client_die(UAContext *ua, CLIENT *client, const char *cmd)
397 /* Connect to File daemon */
399 ua->jcr->client = client;
400 /* Try to connect for 15 seconds */
401 ua->send_msg(_("Connecting to Client %s at %s:%d\n"),
402 client->name(), client->address, client->FDport);
403 if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
404 ua->error_msg(_("Failed to connect to Client.\n"));
407 Dmsg0(120, "Connected to file daemon\n");
408 fd = ua->jcr->file_bsock;
409 fd->fsend("%s", cmd);
410 if (fd->recv() >= 0) {
411 ua->send_msg("%s", fd->msg);
413 fd->signal(BNET_TERMINATE);
415 ua->jcr->file_bsock = NULL;
420 * Create segmentation fault
422 static bool diecmd(UAContext *ua, const char *cmd)
424 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
428 bool do_deadlock=false;
429 const char *remote_cmd=".die";
434 Dmsg1(120, "diecmd:%s:\n", cmd);
437 for (i=1; i<ua->argc; i++) {
438 if (strcasecmp(ua->argk[i], "deadlock") == 0) {
440 remote_cmd = ".die deadlock";
442 if (strcasecmp(ua->argk[i], "dir") == 0 ||
443 strcasecmp(ua->argk[i], "director") == 0) {
446 if (strcasecmp(ua->argk[i], "client") == 0 ||
447 strcasecmp(ua->argk[i], "fd") == 0) {
450 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
453 client = select_client_resource(ua);
457 if (strcasecmp(ua->argk[i], NT_("store")) == 0 ||
458 strcasecmp(ua->argk[i], NT_("storage")) == 0 ||
459 strcasecmp(ua->argk[i], NT_("sd")) == 0) {
462 store = (STORE *)GetResWithName(R_STORAGE, ua->argv[i]);
465 store = get_storage_resource(ua, false/*no default*/);
470 if (!dir && !store && !client) {
472 * We didn't find an appropriate keyword above, so
475 start_prompt(ua, _("Available daemons are: \n"));
476 add_prompt(ua, _("Director"));
477 add_prompt(ua, _("Storage"));
478 add_prompt(ua, _("Client"));
479 switch(do_prompt(ua, "", _("Select daemon type to make die"), NULL, 0)) {
480 case 0: /* Director */
484 store = get_storage_resource(ua, false/*no default*/);
487 client = select_client_resource(ua);
495 do_storage_die(ua, store, remote_cmd);
499 do_client_die(ua, client, remote_cmd);
504 ua->send_msg(_("The Director will generate a deadlock.\n"));
508 ua->send_msg(_("The Director will segment fault.\n"));
509 a = jcr->JobId; /* ref NULL pointer */
510 jcr->JobId = 1000; /* another ref NULL pointer */
519 * Dummy routine for non-development version
521 static bool diecmd(UAContext *ua, const char *cmd)
529 * Can use an argument to filter on JobType
532 static bool jobscmd(UAContext *ua, const char *cmd)
537 if ((pos = find_arg_with_value(ua, "type")) >= 0) {
538 type = ua->argv[pos][0];
541 foreach_res(job, R_JOB) {
542 if (!type || type == job->JobType) {
543 if (acl_access_ok(ua, Job_ACL, job->name())) {
544 ua->send_msg("%s\n", job->name());
552 static bool filesetscmd(UAContext *ua, const char *cmd)
556 foreach_res(fs, R_FILESET) {
557 if (acl_access_ok(ua, FileSet_ACL, fs->name())) {
558 ua->send_msg("%s\n", fs->name());
565 static bool clientscmd(UAContext *ua, const char *cmd)
569 foreach_res(client, R_CLIENT) {
570 if (acl_access_ok(ua, Client_ACL, client->name())) {
571 ua->send_msg("%s\n", client->name());
578 static bool msgscmd(UAContext *ua, const char *cmd)
582 foreach_res(msgs, R_MSGS) {
583 ua->send_msg("%s\n", msgs->name());
589 static bool poolscmd(UAContext *ua, const char *cmd)
593 foreach_res(pool, R_POOL) {
594 if (acl_access_ok(ua, Pool_ACL, pool->name())) {
595 ua->send_msg("%s\n", pool->name());
602 static bool storagecmd(UAContext *ua, const char *cmd)
606 foreach_res(store, R_STORAGE) {
607 if (acl_access_ok(ua, Storage_ACL, store->name())) {
608 ua->send_msg("%s\n", store->name());
615 static bool aopcmd(UAContext *ua, const char *cmd)
617 ua->send_msg("None\n");
618 ua->send_msg("Truncate\n");
622 static bool typescmd(UAContext *ua, const char *cmd)
624 ua->send_msg("Backup\n");
625 ua->send_msg("Restore\n");
626 ua->send_msg("Admin\n");
627 ua->send_msg("Verify\n");
628 ua->send_msg("Migrate\n");
633 * If this command is called, it tells the director that we
634 * are a program that wants a sort of API, and hence,
635 * we will probably suppress certain output, include more
636 * error codes, and most of all send back a good number
637 * of new signals that indicate whether or not the command
640 static bool api_cmd(UAContext *ua, const char *cmd)
643 ua->api = atoi(ua->argk[1]);
650 static int client_backups_handler(void *ctx, int num_field, char **row)
652 UAContext *ua = (UAContext *)ctx;
653 ua->send_msg("| %s | %s | %s | %s | %s | %s | %s | %s |\n",
654 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]);
659 * Return the backups for this client
661 * .backups client=xxx fileset=yyy
664 static bool backupscmd(UAContext *ua, const char *cmd)
666 if (!open_client_db(ua)) {
669 if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 ||
670 strcmp(ua->argk[2], "fileset") != 0) {
673 if (!acl_access_ok(ua, Client_ACL, ua->argv[1]) ||
674 !acl_access_ok(ua, FileSet_ACL, ua->argv[2])) {
675 ua->error_msg(_("Access to specified Client or FileSet not allowed.\n"));
678 Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
679 if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
680 ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
686 static int sql_handler(void *ctx, int num_field, char **row)
688 UAContext *ua = (UAContext *)ctx;
689 POOL_MEM rows(PM_MESSAGE);
691 /* Check for nonsense */
692 if (num_field == 0 || row == NULL || row[0] == NULL) {
693 return 0; /* nothing returned */
695 for (int i=0; num_field--; i++) {
697 pm_strcpy(rows, NPRT(row[0]));
699 pm_strcat(rows, NPRT(row[i]));
701 pm_strcat(rows, "\t");
703 if (!rows.c_str() || !*rows.c_str()) {
706 ua->send_msg("%s", rows.c_str());
711 static bool sql_cmd(UAContext *ua, const char *cmd)
714 if (!open_client_db(ua)) {
717 index = find_arg_with_value(ua, "query");
719 ua->error_msg(_("query keyword not found.\n"));
722 if (!db_sql_query(ua->db, ua->argv[index], sql_handler, (void *)ua)) {
723 Dmsg1(100, "Query failed: ERR=%s\n", db_strerror(ua->db));
724 ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
730 static int one_handler(void *ctx, int num_field, char **row)
732 UAContext *ua = (UAContext *)ctx;
733 ua->send_msg("%s\n", row[0]);
737 static bool mediatypescmd(UAContext *ua, const char *cmd)
739 if (!open_client_db(ua)) {
742 if (!db_sql_query(ua->db,
743 "SELECT DISTINCT MediaType FROM MediaType ORDER BY MediaType",
744 one_handler, (void *)ua))
746 ua->error_msg(_("List MediaType failed: ERR=%s\n"), db_strerror(ua->db));
751 static bool mediacmd(UAContext *ua, const char *cmd)
753 if (!open_client_db(ua)) {
756 if (!db_sql_query(ua->db,
757 "SELECT DISTINCT Media.VolumeName FROM Media ORDER BY VolumeName",
758 one_handler, (void *)ua))
760 ua->error_msg(_("List Media failed: ERR=%s\n"), db_strerror(ua->db));
765 static bool locationscmd(UAContext *ua, const char *cmd)
767 if (!open_client_db(ua)) {
770 if (!db_sql_query(ua->db,
771 "SELECT DISTINCT Location FROM Location ORDER BY Location",
772 one_handler, (void *)ua))
774 ua->error_msg(_("List Location failed: ERR=%s\n"), db_strerror(ua->db));
779 static bool levelscmd(UAContext *ua, const char *cmd)
781 ua->send_msg("Incremental\n");
782 ua->send_msg("Full\n");
783 ua->send_msg("Differential\n");
784 ua->send_msg("VirtualFull\n");
785 ua->send_msg("Catalog\n");
786 ua->send_msg("InitCatalog\n");
787 ua->send_msg("VolumeToCatalog\n");
791 static bool volstatuscmd(UAContext *ua, const char *cmd)
793 ua->send_msg("Append\n");
794 ua->send_msg("Full\n");
795 ua->send_msg("Used\n");
796 ua->send_msg("Recycle\n");
797 ua->send_msg("Purged\n");
798 ua->send_msg("Cleaning\n");
799 ua->send_msg("Error\n");
804 * Return default values for a job
806 static bool defaultscmd(UAContext *ua, const char *cmd)
814 if (ua->argc != 2 || !ua->argv[1]) {
819 if (strcmp(ua->argk[1], "job") == 0) {
820 if (!acl_access_ok(ua, Job_ACL, ua->argv[1])) {
823 job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
826 ua->send_msg("job=%s", job->name());
827 ua->send_msg("pool=%s", job->pool->name());
828 ua->send_msg("messages=%s", job->messages->name());
829 ua->send_msg("client=%s", job->client->name());
830 get_job_storage(&store, job, NULL);
831 ua->send_msg("storage=%s", store.store->name());
832 ua->send_msg("where=%s", job->RestoreWhere?job->RestoreWhere:"");
833 ua->send_msg("level=%s", level_to_str(job->JobLevel));
834 ua->send_msg("type=%s", job_type_to_str(job->JobType));
835 ua->send_msg("fileset=%s", job->fileset->name());
836 ua->send_msg("enabled=%d", job->enabled);
837 ua->send_msg("catalog=%s", job->client->catalog->name());
840 /* Client defaults */
841 else if (strcmp(ua->argk[1], "client") == 0) {
842 if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
845 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
847 ua->send_msg("client=%s", client->name());
848 ua->send_msg("address=%s", client->address);
849 ua->send_msg("fdport=%d", client->FDport);
850 ua->send_msg("file_retention=%s", edit_uint64(client->FileRetention, ed1));
851 ua->send_msg("job_retention=%s", edit_uint64(client->JobRetention, ed1));
852 ua->send_msg("autoprune=%d", client->AutoPrune);
853 ua->send_msg("catalog=%s", client->catalog->name());
856 /* Storage defaults */
857 else if (strcmp(ua->argk[1], "storage") == 0) {
858 if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
861 storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
864 ua->send_msg("storage=%s", storage->name());
865 ua->send_msg("address=%s", storage->address);
866 ua->send_msg("enabled=%d", storage->enabled);
867 ua->send_msg("media_type=%s", storage->media_type);
868 ua->send_msg("sdport=%d", storage->SDport);
869 device = (DEVICE *)storage->device->first();
870 ua->send_msg("device=%s", device->name());
871 if (storage->device->size() > 1) {
872 while ((device = (DEVICE *)storage->device->next())) {
873 ua->send_msg(",%s", device->name());
879 else if (strcmp(ua->argk[1], "pool") == 0) {
880 if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
883 pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
885 ua->send_msg("pool=%s", pool->name());
886 ua->send_msg("pool_type=%s", pool->pool_type);
887 ua->send_msg("label_format=%s", pool->label_format?pool->label_format:"");
888 ua->send_msg("use_volume_once=%d", pool->use_volume_once);
889 ua->send_msg("purge_oldest_volume=%d", pool->purge_oldest_volume);
890 ua->send_msg("recycle_oldest_volume=%d", pool->recycle_oldest_volume);
891 ua->send_msg("recycle_current_volume=%d", pool->recycle_current_volume);
892 ua->send_msg("max_volumes=%d", pool->max_volumes);
893 ua->send_msg("vol_retention=%s", edit_uint64(pool->VolRetention, ed1));
894 ua->send_msg("vol_use_duration=%s", edit_uint64(pool->VolUseDuration, ed1));
895 ua->send_msg("max_vol_jobs=%d", pool->MaxVolJobs);
896 ua->send_msg("max_vol_files=%d", pool->MaxVolFiles);
897 ua->send_msg("max_vol_bytes=%s", edit_uint64(pool->MaxVolBytes, ed1));
898 ua->send_msg("auto_prune=%d", pool->AutoPrune);
899 ua->send_msg("recycle=%d", pool->Recycle);
900 ua->send_msg("file_retention=%s", edit_uint64(pool->FileRetention, ed1));
901 ua->send_msg("job_retention=%s", edit_uint64(pool->JobRetention, ed1));