#include "util.h"
#include "timestamp.h"
#include "server_util.h"
+#include <getopt.h>
disklist_t diskq;
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);
static char *conf_tapelist = NULL;
static char *displayunit;
static long int unitdivisor;
+static gboolean print_default = 1;
+static gboolean print_source = 0;
+static int opt_days = -1;
+static char *opt_sort = NULL;
+static gboolean opt_long = 0;
+static gboolean opt_outdated = 0;
static const struct {
const char *name;
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,
};
#define NCMDS (int)(sizeof(cmdtab) / sizeof(cmdtab[0]))
+static struct option long_options[] = {
+ {"version" , 0, NULL, 1},
+ {"no-default" , 0, NULL, 2},
+ {"print-source" , 0, NULL, 3},
+ {"days" , 1, NULL, 4},
+ {"sort" , 1, NULL, 5},
+ {NULL, 0, NULL, 0}
+};
+
int
main(
int argc,
cfg_ovr = extract_commandline_config_overrides(&argc, &argv);
+ while (1) {
+ int option_index = 0;
+ int c;
+ c = getopt_long(argc, argv, "ld", long_options, &option_index);
+
+ if (c == -1) {
+ break;
+ }
+
+ switch(c) {
+ case 1: printf("amadmin-%s\n", VERSION);
+ return 0;
+ case 2: print_default = 0;
+ break;
+ case 3: print_source = 1;
+ break;
+ case 4: opt_days = atoi(optarg);
+ break;
+ case 5: opt_sort = g_strdup(optarg);
+ break;
+ case 'l': opt_long = TRUE;
+ break;
+ case 'd': opt_outdated = TRUE;
+ break;
+ default: usage();
+ }
+ }
+ argc -= optind-1, argv += optind-1;
+
if(argc < 3) usage();
set_config_overrides(cfg_ovr);
{
int i;
- g_fprintf(stderr, _("\nUsage: %s <conf> <command> {<args>} [-o configoption]* ...\n"),
+ g_fprintf(stderr, _("\nUsage: %s [--version] [--no-default] [--print-source] [-o configoption]*\n <conf> <command> {<args>} ...\n"),
get_pname());
g_fprintf(stderr, _(" Valid <command>s are:\n"));
for (i = 0; i < NCMDS; i++)
void
balance(
- int argc,
- char ** argv)
+ int argc G_GNUC_UNUSED,
+ char ** argv G_GNUC_UNUSED)
{
disk_t *dp;
struct balance_stats {
overdue = 0;
max_overdue = 0;
- if(argc > 4 && strcmp(argv[3],"--days") == 0) {
- later = atoi(argv[4]);
- if(later < 0) later = conf_dumpcycle;
+ if (opt_days > 0) {
+ later = opt_days;
+ } else if (opt_days == 0) {
+ later = conf_dumpcycle;
}
if(later > 10000) later = 10000;
char *sort_order = NULL;
find_result_t *output_find;
char *errstr;
+ char **output_find_log;
+ char **name;
if(argc < 3) {
g_fprintf(stderr,
sort_order = newstralloc(sort_order, DEFAULT_SORT_ORDER);
- if(argc > 4 && strcmp(argv[3],"--sort") == 0) {
+ if (opt_sort) {
size_t i, valid_sort=1;
- for(i = strlen(argv[4]); i > 0; i--) {
- switch (argv[4][i - 1]) {
+ for(i = strlen(opt_sort); i > 0; i--) {
+ switch (opt_sort[i - 1]) {
case 'h':
case 'H':
case 'k':
}
}
if(valid_sort) {
- sort_order = newstralloc(sort_order, argv[4]);
+ sort_order = newstralloc(sort_order, opt_sort);
} else {
- g_printf(_("Invalid sort order: %s\n"), argv[4]);
+ g_printf(_("Invalid sort order: %s\n"), opt_sort);
g_printf(_("Use default sort order: %s\n"), sort_order);
}
- start_argc=6;
- } else {
- start_argc=4;
}
+ start_argc=4;
errstr = match_disklist(&diskq, argc-(start_argc-1), argv+(start_argc-1));
+ /* 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); /* Add deleted dump to diskq */
if(argc-(start_argc-1) > 0) {
+ find_result_t *afind = NULL;
+ find_result_t *afind_next = NULL;
+ find_result_t *new_output_find = NULL;
+ disk_t *dp;
+
amfree(errstr);
- free_find_result(&output_find);
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);
return;
case HOLDING_LIST:
+ long_list = opt_long;
+ outdated_list = opt_outdated;
argc -= 4; argv += 4;
- while (argc && argv[0][0] == '-') {
- switch (argv[0][1]) {
- case 'l':
- long_list = 1;
- break;
- case 'd': /* have to use '-d', and not '-o', because of parse_config */
- outdated_list = 1;
- break;
- default:
- g_fprintf(stderr, _("Unknown option -%c\n"), argv[0][1]);
- usage();
- return;
- }
- argc--; argv++;
- }
/* header */
if (long_list) {
amfree(dumpstr);
dumpfile_free_data(&file);
}
- g_slist_free_full(file_list);
+ slist_free_full(file_list, g_free);
break;
case HOLDING_DELETE:
error(_("Could not delete '%s'"), (char *)li->data);
}
}
- g_slist_free_full(file_list);
+ slist_free_full(file_list, g_free);
break;
}
}
bump_thresh(
int level)
{
- int bump = getconf_int(CNF_BUMPSIZE);
+ gint64 bump = getconf_int64(CNF_BUMPSIZE);
double mult = getconf_real(CNF_BUMPMULT);
while(--level)
g_printf(_("Current bump parameters:\n"));
if(conf_bumppercent == 0) {
- g_printf(_(" bumpsize %5d KB\t- minimum savings (threshold) to bump level 1 -> 2\n"),
- getconf_int(CNF_BUMPSIZE));
+ g_printf(_(" bumpsize %5jd KB\t- minimum savings (threshold) to bump level 1 -> 2\n"),
+ (intmax_t)getconf_int64(CNF_BUMPSIZE));
g_printf(_(" bumpdays %5d\t- minimum days at each level\n"),
getconf_int(CNF_BUMPDAYS));
g_printf(_(" bumpmult %5.5lg\t- threshold = bumpsize * bumpmult**(level-1)\n\n"),
{
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);
(intmax_t)info.history[l].date);
}
g_printf("//\n");
+ amfree(qhost);
+ amfree(qdisk);
}
/* ----------------------------------------------- */
skip_whitespace(s, ch);
if(ch == '\0'
|| sscanf(s - 1, "%d.%d.%d", &vers_maj, &vers_min, &vers_patch) != 3) {
- goto bad_header;
+ vers_patch = -1;
+ if (sscanf(s - 1, "%d.%d", &vers_maj, &vers_min) != 2) {
+ goto bad_header;
+ }
}
skip_integer(s, ch); /* skip over major */
}
ch = *s++;
skip_integer(s, ch); /* skip over minor */
- if(ch != '.') {
- goto bad_header;
+ if (vers_patch != -1) {
+ if (ch != '.') {
+ goto bad_header;
+ }
+ ch = *s++;
+ skip_integer(s, ch); /* skip over patch */
+ } else {
+ vers_patch = 0;
}
- ch = *s++;
- skip_integer(s, ch); /* skip over patch */
hdr = "comment";
if(ch == '\0') {
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);
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);
{
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;
- g_printf("line %d:\n", dp->line);
+ g_printf("line %d (%s):\n", dp->line, dp->filename);
g_printf(" host %s:\n", hp->hostname);
g_printf(" interface %s\n",
g_printf(" program \"%s\"\n", dp->program);
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) {
- g_printf(" exclude list");
- if(dp->exclude_optional) g_printf(" optional");
- for(excl = dp->exclude_list->first; excl != NULL; excl = excl->next) {
- g_printf(" \"%s\"", excl->name);
- }
- g_printf("\n");
- }
- 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) {
- g_printf(" include list");
- if (dp->include_optional) g_printf(" optional");
- for(excl = dp->include_list->first; excl != NULL; excl = excl->next) {
- g_printf(" \"%s\"", excl->name);
- }
- g_printf("\n");
- }
- g_printf(" priority %d\n", dp->priority);
- 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) {
- g_printf(" bumppercent %d\n", dp->bumppercent);
- }
- else {
- g_printf(" bumpsize %lld\n",
- (long long)dp->bumpsize);
- }
- g_printf(" bumpdays %d\n", dp->bumpdays);
- g_printf(" bumpmult %lf\n", dp->bumpmult);
-
- g_printf(" strategy ");
- switch(dp->strategy) {
- case DS_SKIP:
- g_printf("SKIP\n");
- break;
- case DS_STANDARD:
- g_printf("STANDARD\n");
- break;
- case DS_NOFULL:
- g_printf("NOFULL\n");
- break;
- case DS_NOINC:
- g_printf("NOINC\n");
- break;
- case DS_HANOI:
- g_printf("HANOI\n");
- break;
- case DS_INCRONLY:
- g_printf("INCRONLY\n");
- break;
- }
- g_printf(" ignore %s\n", (dp->ignore? "YES" : "NO"));
- g_printf(" estimate ");
- 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) {
- case COMP_NONE:
- g_printf("NONE\n");
- break;
- case COMP_FAST:
- g_printf("CLIENT FAST\n");
- break;
- 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",
- dp->comprate[0], dp->comprate[1]);
- }
-
- g_printf(" encrypt ");
- switch(dp->encrypt) {
- case ENCRYPT_NONE:
- g_printf("NONE\n");
- 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->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(" client_port \"%s\"\n", dp->client_port);
- g_printf(" ssh_keys \"%s\"\n", dp->ssh_keys);
-
- g_printf(" holdingdisk ");
- switch(dp->to_holdingdisk) {
- case HOLD_NEVER:
- g_printf("NEVER\n");
- break;
- case HOLD_AUTO:
- g_printf("AUTO\n");
- break;
- case HOLD_REQUIRED:
- g_printf("REQUIRED\n");
- break;
- }
-
- g_printf(" record %s\n", (dp->record? "YES" : "NO"));
- 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",
- (long long)dp->tape_splitsize);
- }
- if(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",
- (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"));
+ dump_dumptype(dtype, " ", print_default, print_source);
+
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;
- }
-
- {
- dumptype_t *dtype;
- char **prop, **p1;;
-
- dtype = lookup_dumptype(dp->dtype_name);
- 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");
}
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,
int argc G_GNUC_UNUSED,
char **argv G_GNUC_UNUSED)
{
- dump_configuration();
+ dump_configuration(print_default, print_source);
}