Imported Upstream version 3.3.0
[debian/amanda] / server-src / amadmin.c
index 10d8dea4c342454568b41579646d1a8a73ba7f0f..216f46ad43f22aa45a343bac8b47205e2b89f887 100644 (file)
 #include "find.h"
 #include "util.h"
 #include "timestamp.h"
+#include "server_util.h"
 
 disklist_t diskq;
 
 int main(int argc, char **argv);
 void usage(void);
+static void estimate(int argc, char **argv);
+static void estimate_one(disk_t *dp);
 void force(int argc, char **argv);
 void force_one(disk_t *dp);
 void unforce(int argc, char **argv);
@@ -75,6 +78,8 @@ static int next_level0(disk_t *dp, info_t *info);
 int bump_thresh(int level);
 void export_db(int argc, char **argv);
 void import_db(int argc, char **argv);
+void hosts(int argc, char **argv);
+void dles(int argc, char **argv);
 void disklist(int argc, char **argv);
 void disklist_one(disk_t *dp);
 void show_version(int argc, char **argv);
@@ -93,6 +98,8 @@ static const struct {
        T_("\t\t\t\t\t# Show version info.") },
     { "config", show_config,
        T_("\t\t\t\t\t# Show configuration.") },
+    { "estimate", estimate,
+       T_(" [<hostname> [<disks>]* ]*\t# Print server estimate.") },
     { "force", force,
        T_(" [<hostname> [<disks>]* ]+\t\t# Force level 0 at next run.") },
     { "unforce", unforce,
@@ -105,6 +112,10 @@ static const struct {
        T_(" [<hostname> [<disks>]* ]+\t# Clear bump command.") },
     { "disklist", disklist,
        T_(" [<hostname> [<disks>]* ]*\t# Debug disklist entries.") },
+    { "hosts", hosts,
+       T_("\t\t\t\t\t# Show all distinct hosts in disklist.") },
+    { "dles", dles,
+       T_("\t\t\t\t\t# Show all dles in disklist, one per line.") },
     { "reuse", reuse,
        T_(" <tapelabel> ...\t\t # re-use this tape.") },
     { "no-reuse", noreuse,
@@ -120,9 +131,9 @@ static const struct {
     { "due", due,
        T_(" [<hostname> [<disks>]* ]*\t # Show due date.") },
     { "balance", balance,
-       T_(" [-days <num>]\t\t # Show nightly dump size balance.") },
+       T_(" [--days <num>]\t\t # Show nightly dump size balance.") },
     { "tape", tape,
-       T_(" [-days <num>]\t\t # Show which tape is due next.") },
+       T_(" [--days <num>]\t\t # Show which tape is due next.") },
     { "bumpsize", bumpsize,
        T_("\t\t\t # Show current bump thresholds.") },
     { "export", export_db,
@@ -140,7 +151,7 @@ main(
     int i;
     char *conf_diskfile;
     char *conf_infofile;
-    config_overwrites_t *cfg_ovr = NULL;
+    config_overrides_t *cfg_ovr = NULL;
 
     /*
      * Configure program for internationalization:
@@ -161,30 +172,34 @@ main(
 
     dbopen(DBG_SUBDIR_SERVER);
 
-    erroutput_type = ERR_INTERACTIVE;
+    add_amanda_log_handler(amanda_log_stderr);
 
-    cfg_ovr = extract_commandline_config_overwrites(&argc, &argv);
+    cfg_ovr = extract_commandline_config_overrides(&argc, &argv);
 
     if(argc < 3) usage();
 
+    set_config_overrides(cfg_ovr);
+    config_init(CONFIG_INIT_EXPLICIT_NAME, argv[1]);
+
     if(strcmp(argv[2],"version") == 0) {
        show_version(argc, argv);
        goto done;
     }
 
-    config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_FATAL, argv[1]);
-    apply_config_overwrites(cfg_ovr);
+    conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
+    read_diskfile(conf_diskfile, &diskq);
+    amfree(conf_diskfile);
 
-    dbrename(config_name, DBG_SUBDIR_SERVER);
+    if (config_errors(NULL) >= CFGERR_WARNINGS) {
+       config_print_errors();
+       if (config_errors(NULL) >= CFGERR_ERRORS) {
+           g_critical(_("errors processing config file"));
+       }
+    }
 
-    check_running_as(RUNNING_AS_DUMPUSER);
+    dbrename(get_config_name(), DBG_SUBDIR_SERVER);
 
-    conf_diskfile = config_dir_relative(getconf_str(CNF_DISKFILE));
-    if (read_diskfile(conf_diskfile, &diskq) < 0) {
-       error(_("could not load disklist \"%s\""), conf_diskfile);
-       /*NOTREACHED*/
-    }
-    amfree(conf_diskfile);
+    check_running_as(RUNNING_AS_DUMPUSER);
 
     conf_tapelist = config_dir_relative(getconf_str(CNF_TAPELIST));
     if(read_tapelist(conf_tapelist)) {
@@ -231,8 +246,8 @@ usage(void)
 {
     int i;
 
-    g_fprintf(stderr, _("\nUsage: %s%s <conf> <command> {<args>} [-o configoption]* ...\n"),
-           get_pname(), versionsuffix());
+    g_fprintf(stderr, _("\nUsage: %s [-o configoption]* <conf> <command> {<args>} ...\n"),
+           get_pname());
     g_fprintf(stderr, _("    Valid <command>s are:\n"));
     for (i = 0; i < NCMDS; i++)
        g_fprintf(stderr, "\t%s%s\n", cmdtab[i].name, _(cmdtab[i].usage));
@@ -329,6 +344,64 @@ diskloop(
 /* ----------------------------------------------- */
 
 
+static void
+estimate_one(
+    disk_t *   dp)
+{
+    char   *hostname = dp->host->hostname;
+    char   *diskname = dp->name;
+    char   *qhost = quote_string(hostname);
+    char   *qdisk = quote_string(diskname);
+    info_t  info;
+    int     stats;
+    gint64  size;
+
+    get_info(hostname, diskname, &info);
+
+    size = internal_server_estimate(dp, &info, 0, &stats);
+    if (stats) {
+       printf("%s %s %d %jd\n", qhost, qdisk, 0, (intmax_t)size);
+    }
+
+    if (info.last_level > 0) {
+       size = internal_server_estimate(dp, &info, info.last_level, &stats);
+       if (stats) {
+           printf("%s %s %d %jd\n", qhost, qdisk, info.last_level,
+                  (intmax_t)size);
+       }
+    }
+
+    if (info.last_level > -1) {
+       size = internal_server_estimate(dp, &info, info.last_level+1, &stats);
+       if (stats) {
+           printf("%s %s %d %jd\n", qhost, qdisk, info.last_level+1,
+                  (intmax_t)size);
+       }
+    }
+
+    amfree(qhost);
+    amfree(qdisk);
+}
+
+
+static void
+estimate(
+    int                argc,
+    char **    argv)
+{
+    disk_t *dp;
+
+    if(argc >= 4)
+       diskloop(argc, argv, "estimate", estimate_one);
+    else
+       for(dp = diskq.head; dp != NULL; dp = dp->next)
+           estimate_one(dp);
+}
+
+
+/* ----------------------------------------------- */
+
+
 void
 force_one(
     disk_t *   dp)
@@ -765,9 +838,12 @@ tape(
     int                argc,
     char **    argv)
 {
-    tape_t *tp, *lasttp;
-    int runtapes, i, j;
-    int nb_days = 1;
+    int     nb_days = 1;
+    int     runtapes;
+    tape_t *tp;
+    int     i, j;
+    int     skip;
+    int     nb_new_tape;
 
     if(argc > 4 && strcmp(argv[3],"--days") == 0) {
        nb_days = atoi(argv[4]);
@@ -781,54 +857,41 @@ tape(
 
     runtapes = getconf_int(CNF_RUNTAPES);
     tp = lookup_last_reusable_tape(0);
+    skip = 0;
 
     for ( j=0 ; j < nb_days ; j++ ) {
+       nb_new_tape=0;
        for ( i=0 ; i < runtapes ; i++ ) {
            if(i==0)
-               g_printf(_("The next Amanda run should go onto "));
-           else
-               g_printf("                                   ");
+               g_fprintf(stdout, _("The next Amanda run should go onto "));
            if(tp != NULL) {
-               g_printf(_("tape %s or a new tape.\n"), tp->label);
+               if (nb_new_tape > 0) {
+                   if (nb_new_tape == 1)
+                       g_fprintf(stdout, _("1 new tape.\n"));
+                   else
+                       g_fprintf(stdout, _("%d new tapes.\n"), nb_new_tape);
+                   g_fprintf(stdout, "                                   ");
+                   nb_new_tape = 0;
+               }
+               g_fprintf(stdout, _("tape %s or a new tape.\n"), tp->label);
+               if (i < runtapes-1)
+                   g_fprintf(stdout, "                                   ");
            } else {
-               if (runtapes - i == 1)
-                   g_printf(_("1 new tape.\n"));
-               else
-                   g_printf(_("%d new tapes.\n"), runtapes - i);
-               i = runtapes;
+               nb_new_tape++;
            }
-       
-           tp = lookup_last_reusable_tape(i + 1);
-       }
-    }
-    lasttp = lookup_tapepos(lookup_nb_tape());
-    i = runtapes;
-    if(lasttp && i > 0 && strcmp(lasttp->datestamp,"0") == 0) {
-       int c = 0;
-       while(lasttp && i > 0 && strcmp(lasttp->datestamp,"0") == 0) {
-           c++;
-           lasttp = lasttp->prev;
-           i--;
-       }
-       lasttp = lookup_tapepos(lookup_nb_tape());
-       i = runtapes;
-       if(c == 1) {
-           g_printf(_("The next new tape already labelled is: %s.\n"),
-                  lasttp->label);
+           skip++;
+
+           tp = lookup_last_reusable_tape(skip);
        }
-       else {
-           g_printf(_("The next %d new tapes already labelled are: %s"), c,
-                  lasttp->label);
-           lasttp = lasttp->prev;
-           c--;
-           while(lasttp && c > 0 && strcmp(lasttp->datestamp,"0") == 0) {
-               g_printf(", %s", lasttp->label);
-               lasttp = lasttp->prev;
-               c--;
-           }
-           g_printf(".\n");
+       if (nb_new_tape > 0) {
+           if (nb_new_tape == 1)
+               g_fprintf(stdout, _("1 new tape.\n"));
+           else
+               g_fprintf(stdout, _("%d new tapes.\n"), nb_new_tape);
        }
     }
+
+    print_new_tapes(stdout, nb_days * runtapes);
 }
 
 /* ----------------------------------------------- */
@@ -1043,10 +1106,12 @@ find(
     char *sort_order = NULL;
     find_result_t *output_find;
     char *errstr;
+    char **output_find_log;
+    char **name;
 
     if(argc < 3) {
        g_fprintf(stderr,
-               _("%s: expecting \"find [--sort <hkdlpbf>] [hostname [<disk>]]*\"\n"),
+               _("%s: expecting \"find [--sort <hkdlpbfw>] [hostname [<disk>]]*\"\n"),
                get_pname());
        usage();
     }
@@ -1072,6 +1137,8 @@ find(
            case 'P':
            case 'b':
            case 'B':
+           case 'w':
+           case 'W':
                    break;
            default: valid_sort=0;
            }
@@ -1087,21 +1154,42 @@ find(
        start_argc=4;
     }
     errstr = match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
-    if (errstr) {
-       g_printf("%s", errstr);
-       amfree(errstr);
+
+    /* check all log file exists */
+    output_find_log = find_log();
+    for (name = output_find_log; *name != NULL; name++) {
+        amfree(*name);
     }
+    amfree(output_find_log);
 
-    output_find = find_dump(&diskq);
+    output_find = find_dump(&diskq); /* Add deleted dump to diskq */
     if(argc-(start_argc-1) > 0) {
-       free_find_result(&output_find);
+       find_result_t *afind = NULL;
+       find_result_t *afind_next = NULL;
+       find_result_t *new_output_find = NULL;
+       disk_t *dp;
+
+       amfree(errstr);
        errstr = match_disklist(&diskq, argc-(start_argc-1),
                                        argv+(start_argc-1));
        if (errstr) {
            g_printf("%s", errstr);
            amfree(errstr);
        }
-       output_find = find_dump(NULL);
+       for (afind = output_find; afind; afind = afind_next) {
+           afind_next = afind->next;
+           dp = lookup_disk(afind->hostname, afind->diskname);
+           if (dp->todo) {
+               afind->next = new_output_find;
+               new_output_find = afind;
+           } else {
+               amfree(afind);
+           }
+       }
+       output_find = new_output_find;
+    } else if (errstr) {
+       g_printf("%s", errstr);
+       amfree(errstr);
     }
 
     sort_find_result(sort_order, &output_find);
@@ -1238,14 +1326,16 @@ remove_holding_file_from_catalog(
     }
 
     if (get_info(file.name, file.disk, &info) == -1) {
-           g_printf(_("WARNING: No curinfo record for %s:%s\n"), file.name, file.disk);
-           return 1; /* not an error */
+       g_printf(_("WARNING: No curinfo record for %s:%s\n"), file.name, file.disk);
+       dumpfile_free_data(&file);
+       return 1; /* not an error */
     }
 
     matching_hist_idx = holding_file_find_history(&info, &file);
 
     if (matching_hist_idx == -1) {
         g_printf(_("WARNING: No dump matching %s found in curinfo.\n"), filename);
+       dumpfile_free_data(&file);
        return 1; /* not an error */
     }
 
@@ -1253,7 +1343,7 @@ remove_holding_file_from_catalog(
     matching_hist = info.history[matching_hist_idx];
 
     /* Remove the history element itself before doing the stats */
-    for (i = matching_hist_idx; i <= NB_HISTORY; i++) {
+    for (i = matching_hist_idx; i < NB_HISTORY; i++) {
         info.history[i] = info.history[i+1];
     }
     info.history[NB_HISTORY].level = -1;
@@ -1327,10 +1417,12 @@ remove_holding_file_from_catalog(
 
     /* write out the changes */
     if (put_info(file.name, file.disk, &info) == -1) {
-           g_printf(_("Could not write curinfo record for %s:%s\n"), file.name, file.disk);
-           return 0;
+       g_printf(_("Could not write curinfo record for %s:%s\n"), file.name, file.disk);
+       dumpfile_free_data(&file);
+       return 0;
     }
 
+    dumpfile_free_data(&file);
     return 1;
 }
 
@@ -1412,8 +1504,9 @@ holding(
                    }
                }
                 amfree(dumpstr);
+               dumpfile_free_data(&file);
             }
-            g_slist_free_full(file_list);
+            slist_free_full(file_list, g_free);
             break;
 
         case HOLDING_DELETE:
@@ -1431,7 +1524,7 @@ holding(
                     error(_("Could not delete '%s'"), (char *)li->data);
                 }
             }
-            g_slist_free_full(file_list);
+            slist_free_full(file_list, g_free);
             break;
     }
 }
@@ -1513,7 +1606,7 @@ export_db(
     char hostname[MAX_HOSTNAME_LENGTH+1];
     int i;
 
-    g_printf(_("CURINFO Version %s CONF %s\n"), version(), getconf_str(CNF_ORG));
+    g_printf(_("CURINFO Version %s CONF %s\n"), VERSION, getconf_str(CNF_ORG));
 
     curtime = time(0);
     if(gethostname(hostname, SIZEOF(hostname)-1) == -1) {
@@ -1543,13 +1636,16 @@ export_one(
 {
     info_t info;
     int i,l;
+    char *qhost, *qdisk;
 
     if(get_info(dp->host->hostname, dp->name, &info)) {
        g_fprintf(stderr, _("Warning: no curinfo record for %s:%s\n"),
                dp->host->hostname, dp->name);
        return;
     }
-    g_printf(_("host: %s\ndisk: %s\n"), dp->host->hostname, dp->name);
+    qhost = quote_string(dp->host->hostname);
+    qdisk = quote_string(dp->name);
+    g_printf(_("host: %s\ndisk: %s\n"), qhost, qdisk);
     g_printf(_("command: %u\n"), info.command);
     g_printf(_("last_level: %d\n"),info.last_level);
     g_printf(_("consecutive_runs: %d\n"),info.consecutive_runs);
@@ -1581,6 +1677,8 @@ export_one(
               (intmax_t)info.history[l].date);
     }
     g_printf("//\n");
+    amfree(qhost);
+    amfree(qdisk);
 }
 
 /* ----------------------------------------------- */
@@ -1727,9 +1825,9 @@ import_one(void)
     skip_whitespace(s, ch);
     if(ch == '\0') goto parse_err;
     fp = s-1;
-    skip_non_whitespace(s, ch);
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
-    hostname = stralloc(fp);
+    hostname = unquote_string(fp);
     s[-1] = (char)ch;
 
     skip_whitespace(s, ch);
@@ -1744,9 +1842,9 @@ import_one(void)
     skip_whitespace(s, ch);
     if(ch == '\0') goto parse_err;
     fp = s-1;
-    skip_non_whitespace(s, ch);
+    skip_quoted_string(s, ch);
     s[-1] = '\0';
-    diskname = stralloc(fp);
+    diskname = unquote_string(fp);
     s[-1] = (char)ch;
 
     amfree(line);
@@ -1988,6 +2086,9 @@ disklist_one(
     am_host_t *hp;
     netif_t *ip;
     sle_t *excl;
+    identlist_t pp_scriptlist;
+    estimatelist_t  estimates;
+    dumptype_t *dtype = lookup_dumptype(dp->dtype_name);
 
     hp = dp->host;
     ip = hp->netif;
@@ -1998,17 +2099,20 @@ disklist_one(
     g_printf("        interface %s\n",
           interface_name(ip->config)[0] ? interface_name(ip->config) : "default");
     g_printf("    disk %s:\n", dp->name);
-    if(dp->device) g_printf("        device %s\n", dp->device);
+    if (dp->device) g_printf("        device %s\n", dp->device);
 
     g_printf("        program \"%s\"\n", dp->program);
-    if(dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
+    if (dp->application)
+       g_printf("        application \"%s\"\n", dp->application);
+    g_printf("        data-path %s\n", data_path_to_string(dp->data_path));
+    if (dp->exclude_file != NULL && dp->exclude_file->nb_element > 0) {
        g_printf("        exclude file");
        for(excl = dp->exclude_file->first; excl != NULL; excl = excl->next) {
            g_printf(" \"%s\"", excl->name);
        }
        g_printf("\n");
     }
-    if(dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
+    if (dp->exclude_list != NULL && dp->exclude_list->nb_element > 0) {
        g_printf("        exclude list");
        if(dp->exclude_optional) g_printf(" optional");
        for(excl = dp->exclude_list->first; excl != NULL; excl = excl->next) {
@@ -2016,16 +2120,16 @@ disklist_one(
        }
        g_printf("\n");
     }
-    if(dp->include_file != NULL && dp->include_file->nb_element > 0) {
+    if (dp->include_file != NULL && dp->include_file->nb_element > 0) {
        g_printf("        include file");
        for(excl = dp->include_file->first; excl != NULL; excl = excl->next) {
            g_printf(" \"%s\"", excl->name);
        }
        g_printf("\n");
     }
-    if(dp->include_list != NULL && dp->include_list->nb_element > 0) {
+    if (dp->include_list != NULL && dp->include_list->nb_element > 0) {
        g_printf("        include list");
-       if(dp->include_optional) g_printf(" optional");
+       if (dp->include_optional) g_printf(" optional");
        for(excl = dp->include_list->first; excl != NULL; excl = excl->next) {
            g_printf(" \"%s\"", excl->name);
        }
@@ -2035,7 +2139,7 @@ disklist_one(
     g_printf("        dumpcycle %d\n", dp->dumpcycle);
     g_printf("        maxdumps %d\n", dp->maxdumps);
     g_printf("        maxpromoteday %d\n", dp->maxpromoteday);
-    if(dp->bumppercent > 0) {
+    if (dp->bumppercent > 0) {
        g_printf("        bumppercent %d\n", dp->bumppercent);
     }
     else {
@@ -2068,17 +2172,26 @@ disklist_one(
     }
     g_printf("        ignore %s\n", (dp->ignore? "YES" : "NO"));
     g_printf("        estimate ");
-    switch(dp->estimate) {
-    case ES_CLIENT:
-       g_printf("CLIENT\n");
-       break;
-    case ES_SERVER:
-       g_printf("SERVER\n");
-       break;
-    case ES_CALCSIZE:
-       g_printf("CALCSIZE\n");
-       break;
+    estimates = dp->estimatelist;
+    while (estimates) {
+       switch((estimate_t)GPOINTER_TO_INT(estimates->data)) {
+       case ES_CLIENT:
+           g_printf("CLIENT");
+           break;
+       case ES_SERVER:
+           g_printf("SERVER");
+           break;
+       case ES_CALCSIZE:
+           g_printf("CALCSIZE");
+           break;
+       case ES_ES:
+           break;
+       }
+       estimates = estimates->next;
+       if (estimates)
+           g_printf(", ");
     }
+    g_printf("\n");
 
     g_printf("        compress ");
     switch(dp->compress) {
@@ -2091,12 +2204,22 @@ disklist_one(
     case COMP_BEST:
        g_printf("CLIENT BEST\n");
        break;
+    case COMP_CUST:
+       g_printf("CLIENT CUSTOM\n");
+       g_printf("        client-custom-compress \"%s\"\n",
+                   dp->clntcompprog? dp->clntcompprog : "");
+       break;
     case COMP_SERVER_FAST:
        g_printf("SERVER FAST\n");
        break;
     case COMP_SERVER_BEST:
        g_printf("SERVER BEST\n");
        break;
+    case COMP_SERVER_CUST:
+       g_printf("SERVER CUSTOM\n");
+       g_printf("        server-custom-compress \"%s\"\n",
+                   dp->srvcompprog? dp->srvcompprog : "");
+       break;
     }
     if(dp->compress != COMP_NONE) {
        g_printf("        comprate %.2lf %.2lf\n",
@@ -2110,17 +2233,26 @@ disklist_one(
        break;
     case ENCRYPT_CUST:
        g_printf("CLIENT\n");
+       g_printf("        client-encrypt \"%s\"\n",
+                   dp->clnt_encrypt? dp->clnt_encrypt : "");
+       g_printf("        client-decrypt-option \"%s\"\n",
+                   dp->clnt_decrypt_opt? dp->clnt_decrypt_opt : "");
        break;
     case ENCRYPT_SERV_CUST:
        g_printf("SERVER\n");
+       g_printf("        server-encrypt \"%s\"\n",
+                   dp->srv_encrypt? dp->srv_encrypt : "");
+       g_printf("        server-decrypt-option \"%s\"\n",
+                   dp->srv_decrypt_opt? dp->srv_decrypt_opt : "");
        break;
     }
 
-    g_printf("        auth %s\n", dp->security_driver);
+    g_printf("        auth \"%s\"\n", dp->auth);
     g_printf("        kencrypt %s\n", (dp->kencrypt? "YES" : "NO"));
-    g_printf("        amandad_path %s\n", dp->amandad_path);
-    g_printf("        client_username %s\n", dp->client_username);
-    g_printf("        ssh_keys %s\n", dp->ssh_keys);
+    g_printf("        amandad-path \"%s\"\n", dp->amandad_path);
+    g_printf("        client-username \"%s\"\n", dp->client_username);
+    g_printf("        client-port \"%s\"\n", dp->client_port);
+    g_printf("        ssh-keys \"%s\"\n", dp->ssh_keys);
 
     g_printf("        holdingdisk ");
     switch(dp->to_holdingdisk) {
@@ -2139,19 +2271,55 @@ disklist_one(
     g_printf("        index %s\n", (dp->index? "YES" : "NO"));
     g_printf("        starttime %04d\n", (int)dp->starttime);
     if(dp->tape_splitsize > (off_t)0) {
-       g_printf("        tape_splitsize %lld\n",
+       g_printf("        tape-splitsize %lld\n",
               (long long)dp->tape_splitsize);
     }
     if(dp->split_diskbuffer) {
-       g_printf("        split_diskbuffer %s\n", dp->split_diskbuffer);
+       g_printf("        split-diskbuffer %s\n", dp->split_diskbuffer);
     }
     if(dp->fallback_splitsize > (off_t)0) {
-       g_printf("        fallback_splitsize %lldMb\n",
+       g_printf("        fallback-splitsize %lldMb\n",
               (long long)(dp->fallback_splitsize / (off_t)1024));
     }
     g_printf("        skip-incr %s\n", (dp->skip_incr? "YES" : "NO"));
     g_printf("        skip-full %s\n", (dp->skip_full? "YES" : "NO"));
+    g_printf("        allow-split %s\n", (dp->allow_split ? "YES" : "NO"));
+    if (dumptype_seen(dtype, DUMPTYPE_RECOVERY_LIMIT)) {
+       char **rl, **r1;
+       rl = val_t_display_strs(dumptype_getconf((dtype),
+                               DUMPTYPE_RECOVERY_LIMIT), 1);
+       for(r1 = rl; *r1 != NULL; r1++) {
+           g_printf("        recovery-limit %s\n", *r1);
+       free(*r1);
+       }
+    }
+    if (dumptype_seen(dtype, DUMPTYPE_DUMP_LIMIT)) {
+       char **rl, **r1;
+       rl = val_t_display_strs(dumptype_getconf((dtype),
+                               DUMPTYPE_DUMP_LIMIT), 1);
+       for(r1 = rl; *r1 != NULL; r1++) {
+           g_printf("        dump-limit %s\n", *r1);
+       free(*r1);
+       }
+    }
     g_printf("        spindle %d\n", dp->spindle);
+    pp_scriptlist = dp->pp_scriptlist;
+    while (pp_scriptlist != NULL) {
+       g_printf("        script \"%s\"\n", (char *)pp_scriptlist->data);
+       pp_scriptlist = pp_scriptlist->next;
+    }
+
+    {
+       char **prop, **p1;;
+
+       prop = val_t_display_strs(dumptype_getconf((dtype), DUMPTYPE_PROPERTY),
+                                 0);
+       for(p1 = prop; *p1 != NULL; p1++) {
+           g_printf("        property %s\n", *p1);
+           free(*p1);
+       }
+       amfree(prop);
+    }
 
     g_printf("\n");
 }
@@ -2170,6 +2338,44 @@ disklist(
            disklist_one(dp);
 }
 
+/* ----------------------------------------------- */
+
+void
+hosts(
+    int                argc G_GNUC_UNUSED,
+    char **    argv G_GNUC_UNUSED)
+{
+    disk_t *dp;
+    gint sentinel = 1;
+    GHashTable *seen = g_hash_table_new(g_str_hash, g_str_equal);
+
+    /* enumerate all hosts, skipping those that have been seen (since
+     * there may be more than one DLE on a host */
+    for(dp = diskq.head; dp != NULL; dp = dp->next) {
+       char *hostname = dp->host->hostname;
+       if (g_hash_table_lookup(seen, hostname))
+           continue;
+       g_printf("%s\n", hostname);
+       g_hash_table_insert(seen, hostname, &sentinel);
+    }
+    g_hash_table_destroy(seen);
+}
+
+/* ----------------------------------------------- */
+
+void
+dles(
+    int                argc G_GNUC_UNUSED,
+    char **    argv G_GNUC_UNUSED)
+{
+    disk_t *dp;
+
+    for(dp = diskq.head; dp != NULL; dp = dp->next)
+       g_printf("%s %s\n", dp->host->hostname, dp->name);
+}
+
+/* ----------------------------------------------- */
+
 void
 show_version(
     int                argc,