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");
630 ua->send_msg("Copy\n");
635 * If this command is called, it tells the director that we
636 * are a program that wants a sort of API, and hence,
637 * we will probably suppress certain output, include more
638 * error codes, and most of all send back a good number
639 * of new signals that indicate whether or not the command
642 static bool api_cmd(UAContext *ua, const char *cmd)
645 ua->api = atoi(ua->argk[1]);
652 static int client_backups_handler(void *ctx, int num_field, char **row)
654 UAContext *ua = (UAContext *)ctx;
655 ua->send_msg("| %s | %s | %s | %s | %s | %s | %s | %s |\n",
656 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8]);
661 * Return the backups for this client
663 * .backups client=xxx fileset=yyy
666 static bool backupscmd(UAContext *ua, const char *cmd)
668 if (!open_client_db(ua)) {
671 if (ua->argc != 3 || strcmp(ua->argk[1], "client") != 0 ||
672 strcmp(ua->argk[2], "fileset") != 0) {
675 if (!acl_access_ok(ua, Client_ACL, ua->argv[1]) ||
676 !acl_access_ok(ua, FileSet_ACL, ua->argv[2])) {
677 ua->error_msg(_("Access to specified Client or FileSet not allowed.\n"));
680 Mmsg(ua->cmd, client_backups, ua->argv[1], ua->argv[2]);
681 if (!db_sql_query(ua->db, ua->cmd, client_backups_handler, (void *)ua)) {
682 ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
688 static int sql_handler(void *ctx, int num_field, char **row)
690 UAContext *ua = (UAContext *)ctx;
691 POOL_MEM rows(PM_MESSAGE);
693 /* Check for nonsense */
694 if (num_field == 0 || row == NULL || row[0] == NULL) {
695 return 0; /* nothing returned */
697 for (int i=0; num_field--; i++) {
699 pm_strcpy(rows, NPRT(row[0]));
701 pm_strcat(rows, NPRT(row[i]));
703 pm_strcat(rows, "\t");
705 if (!rows.c_str() || !*rows.c_str()) {
708 ua->send_msg("%s", rows.c_str());
713 static bool sql_cmd(UAContext *ua, const char *cmd)
716 if (!open_client_db(ua)) {
719 index = find_arg_with_value(ua, "query");
721 ua->error_msg(_("query keyword not found.\n"));
724 if (!db_sql_query(ua->db, ua->argv[index], sql_handler, (void *)ua)) {
725 Dmsg1(100, "Query failed: ERR=%s\n", db_strerror(ua->db));
726 ua->error_msg(_("Query failed: %s. ERR=%s\n"), ua->cmd, db_strerror(ua->db));
732 static int one_handler(void *ctx, int num_field, char **row)
734 UAContext *ua = (UAContext *)ctx;
735 ua->send_msg("%s\n", row[0]);
739 static bool mediatypescmd(UAContext *ua, const char *cmd)
741 if (!open_client_db(ua)) {
744 if (!db_sql_query(ua->db,
745 "SELECT DISTINCT MediaType FROM MediaType ORDER BY MediaType",
746 one_handler, (void *)ua))
748 ua->error_msg(_("List MediaType failed: ERR=%s\n"), db_strerror(ua->db));
753 static bool mediacmd(UAContext *ua, const char *cmd)
755 if (!open_client_db(ua)) {
758 if (!db_sql_query(ua->db,
759 "SELECT DISTINCT Media.VolumeName FROM Media ORDER BY VolumeName",
760 one_handler, (void *)ua))
762 ua->error_msg(_("List Media failed: ERR=%s\n"), db_strerror(ua->db));
767 static bool locationscmd(UAContext *ua, const char *cmd)
769 if (!open_client_db(ua)) {
772 if (!db_sql_query(ua->db,
773 "SELECT DISTINCT Location FROM Location ORDER BY Location",
774 one_handler, (void *)ua))
776 ua->error_msg(_("List Location failed: ERR=%s\n"), db_strerror(ua->db));
781 static bool levelscmd(UAContext *ua, const char *cmd)
783 ua->send_msg("Incremental\n");
784 ua->send_msg("Full\n");
785 ua->send_msg("Differential\n");
786 ua->send_msg("VirtualFull\n");
787 ua->send_msg("Catalog\n");
788 ua->send_msg("InitCatalog\n");
789 ua->send_msg("VolumeToCatalog\n");
790 ua->send_msg("Base\n");
794 static bool volstatuscmd(UAContext *ua, const char *cmd)
796 ua->send_msg("Append\n");
797 ua->send_msg("Full\n");
798 ua->send_msg("Used\n");
799 ua->send_msg("Recycle\n");
800 ua->send_msg("Purged\n");
801 ua->send_msg("Cleaning\n");
802 ua->send_msg("Error\n");
807 * Return default values for a job
809 static bool defaultscmd(UAContext *ua, const char *cmd)
817 if (ua->argc != 2 || !ua->argv[1]) {
822 if (strcmp(ua->argk[1], "job") == 0) {
823 if (!acl_access_ok(ua, Job_ACL, ua->argv[1])) {
826 job = (JOB *)GetResWithName(R_JOB, ua->argv[1]);
829 ua->send_msg("job=%s", job->name());
830 ua->send_msg("pool=%s", job->pool->name());
831 ua->send_msg("messages=%s", job->messages->name());
832 ua->send_msg("client=%s", job->client->name());
833 get_job_storage(&store, job, NULL);
834 ua->send_msg("storage=%s", store.store->name());
835 ua->send_msg("where=%s", job->RestoreWhere?job->RestoreWhere:"");
836 ua->send_msg("level=%s", level_to_str(job->JobLevel));
837 ua->send_msg("type=%s", job_type_to_str(job->JobType));
838 ua->send_msg("fileset=%s", job->fileset->name());
839 ua->send_msg("enabled=%d", job->enabled);
840 ua->send_msg("catalog=%s", job->client->catalog->name());
843 /* Client defaults */
844 else if (strcmp(ua->argk[1], "client") == 0) {
845 if (!acl_access_ok(ua, Client_ACL, ua->argv[1])) {
848 client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[1]);
850 ua->send_msg("client=%s", client->name());
851 ua->send_msg("address=%s", client->address);
852 ua->send_msg("fdport=%d", client->FDport);
853 ua->send_msg("file_retention=%s", edit_uint64(client->FileRetention, ed1));
854 ua->send_msg("job_retention=%s", edit_uint64(client->JobRetention, ed1));
855 ua->send_msg("autoprune=%d", client->AutoPrune);
856 ua->send_msg("catalog=%s", client->catalog->name());
859 /* Storage defaults */
860 else if (strcmp(ua->argk[1], "storage") == 0) {
861 if (!acl_access_ok(ua, Storage_ACL, ua->argv[1])) {
864 storage = (STORE *)GetResWithName(R_STORAGE, ua->argv[1]);
867 ua->send_msg("storage=%s", storage->name());
868 ua->send_msg("address=%s", storage->address);
869 ua->send_msg("enabled=%d", storage->enabled);
870 ua->send_msg("media_type=%s", storage->media_type);
871 ua->send_msg("sdport=%d", storage->SDport);
872 device = (DEVICE *)storage->device->first();
873 ua->send_msg("device=%s", device->name());
874 if (storage->device->size() > 1) {
875 while ((device = (DEVICE *)storage->device->next())) {
876 ua->send_msg(",%s", device->name());
882 else if (strcmp(ua->argk[1], "pool") == 0) {
883 if (!acl_access_ok(ua, Pool_ACL, ua->argv[1])) {
886 pool = (POOL *)GetResWithName(R_POOL, ua->argv[1]);
888 ua->send_msg("pool=%s", pool->name());
889 ua->send_msg("pool_type=%s", pool->pool_type);
890 ua->send_msg("label_format=%s", pool->label_format?pool->label_format:"");
891 ua->send_msg("use_volume_once=%d", pool->use_volume_once);
892 ua->send_msg("purge_oldest_volume=%d", pool->purge_oldest_volume);
893 ua->send_msg("recycle_oldest_volume=%d", pool->recycle_oldest_volume);
894 ua->send_msg("recycle_current_volume=%d", pool->recycle_current_volume);
895 ua->send_msg("max_volumes=%d", pool->max_volumes);
896 ua->send_msg("vol_retention=%s", edit_uint64(pool->VolRetention, ed1));
897 ua->send_msg("vol_use_duration=%s", edit_uint64(pool->VolUseDuration, ed1));
898 ua->send_msg("max_vol_jobs=%d", pool->MaxVolJobs);
899 ua->send_msg("max_vol_files=%d", pool->MaxVolFiles);
900 ua->send_msg("max_vol_bytes=%s", edit_uint64(pool->MaxVolBytes, ed1));
901 ua->send_msg("auto_prune=%d", pool->AutoPrune);
902 ua->send_msg("recycle=%d", pool->Recycle);
903 ua->send_msg("file_retention=%s", edit_uint64(pool->FileRetention, ed1));
904 ua->send_msg("job_retention=%s", edit_uint64(pool->JobRetention, ed1));