* Version $Id$
*/
/*
- Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+ Copyright (C) 2000-2003 Kern Sibbald and John Walker
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
static void store_restore(LEX *lc, struct res_items *item, int index, int pass);
static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass);
static void store_level(LEX *lc, struct res_items *item, int index, int pass);
+static void store_replace(LEX *lc, struct res_items *item, int index, int pass);
/* We build the current resource here as we are
{"client", store_res, ITEM(res_job.client), R_CLIENT, 0, 0},
{"fileset", store_res, ITEM(res_job.fileset), R_FILESET, 0, 0},
{"where", store_dir, ITEM(res_job.RestoreWhere), 0, 0, 0},
+ {"replace", store_replace, ITEM(res_job.replace), REPLACE_ALWAYS, ITEM_DEFAULT, 0},
{"bootstrap",store_dir, ITEM(res_job.RestoreBootstrap), 0, 0, 0},
{"maxruntime", store_time, ITEM(res_job.MaxRunTime), 0, 0, 0},
{"maxstartdelay", store_time,ITEM(res_job.MaxStartDelay), 0, 0, 0},
* name handler value code flags default_value
*/
static struct res_items pool_items[] = {
- {"name", store_name, ITEM(res_pool.hdr.name), 0, ITEM_REQUIRED, 0},
- {"description", store_str, ITEM(res_pool.hdr.desc), 0, 0, 0},
- {"pooltype", store_strname, ITEM(res_pool.pool_type), 0, ITEM_REQUIRED, 0},
- {"labelformat", store_strname, ITEM(res_pool.label_format), 0, 0, 0},
+ {"name", store_name, ITEM(res_pool.hdr.name), 0, ITEM_REQUIRED, 0},
+ {"description", store_str, ITEM(res_pool.hdr.desc), 0, 0, 0},
+ {"pooltype", store_strname, ITEM(res_pool.pool_type), 0, ITEM_REQUIRED, 0},
+ {"labelformat", store_strname, ITEM(res_pool.label_format), 0, 0, 0},
{"usecatalog", store_yesno, ITEM(res_pool.use_catalog), 1, ITEM_DEFAULT, 1},
- {"usevolumeonce", store_yesno, ITEM(res_pool.use_volume_once), 1, 0, 0},
- {"maximumvolumes", store_pint, ITEM(res_pool.max_volumes), 0, 0, 0},
+ {"usevolumeonce", store_yesno, ITEM(res_pool.use_volume_once), 1, 0, 0},
+ {"maximumvolumes", store_pint, ITEM(res_pool.max_volumes), 0, 0, 0},
+ {"maximumvolumejobs", store_pint, ITEM(res_pool.MaxVolJobs), 0, 0, 0},
+ {"maximumvolumefiles", store_pint, ITEM(res_pool.MaxVolFiles), 0, 0, 0},
+ {"maximumvolumebytes", store_size, ITEM(res_pool.MaxVolBytes), 0, 0, 0},
{"acceptanyvolume", store_yesno, ITEM(res_pool.accept_any_volume), 1, ITEM_DEFAULT, 1},
{"catalogfiles", store_yesno, ITEM(res_pool.catalog_files), 1, ITEM_DEFAULT, 1},
- {"volumeretention", store_time, ITEM(res_pool.VolRetention), 0, ITEM_DEFAULT, 60*60*24*365},
+ {"volumeretention", store_time, ITEM(res_pool.VolRetention), 0, ITEM_DEFAULT, 60*60*24*365},
+ {"volumeuseduration", store_time, ITEM(res_pool.VolUseDuration),0, 0, 0},
{"autoprune", store_yesno, ITEM(res_pool.AutoPrune), 1, ITEM_DEFAULT, 1},
{"recycle", store_yesno, ITEM(res_pool.Recycle), 1, ITEM_DEFAULT, 1},
{NULL, NULL, NULL, 0, 0, 0}
{"Full", L_FULL, JT_BACKUP},
{"Incremental", L_INCREMENTAL, JT_BACKUP},
{"Differential", L_DIFFERENTIAL, JT_BACKUP},
- {"Level", L_LEVEL, JT_BACKUP},
{"Since", L_SINCE, JT_BACKUP},
{"Catalog", L_VERIFY_CATALOG, JT_VERIFY},
{"Initcatalog", L_VERIFY_INIT, JT_VERIFY},
};
/* Options permitted in Restore replace= */
-static struct s_kw ReplaceOptions[] = {
- {"always", 'a'}, /* always */
- {"ifnewer", 'w'},
- {"never", 'n'},
+struct s_kw ReplaceOptions[] = {
+ {"always", REPLACE_ALWAYS},
+ {"ifnewer", REPLACE_IFNEWER},
+ {"ifolder", REPLACE_IFOLDER},
+ {"never", REPLACE_NEVER},
{NULL, 0}
};
#define INC_KW_RECURSE 6
#define INC_KW_SPARSE 7
#define INC_KW_REPLACE 8 /* restore options */
+#define INC_KW_READFIFO 9 /* Causes fifo data to be read */
/* Include keywords */
static struct s_kw FS_option_kw[] = {
{"recurse", INC_KW_RECURSE},
{"sparse", INC_KW_SPARSE},
{"replace", INC_KW_REPLACE},
+ {"readfifo", INC_KW_READFIFO},
{NULL, 0}
};
{"always", INC_KW_REPLACE, "a"},
{"ifnewer", INC_KW_REPLACE, "w"},
{"never", INC_KW_REPLACE, "n"},
+ {"yes", INC_KW_READFIFO, "r"},
+ {"no", INC_KW_READFIFO, "0"},
{NULL, 0, 0}
};
strcpy(buf, " hour=");
for (i=0; i<24; i++) {
if (bit_is_set(i, run->hour)) {
- sprintf(num, "%d ", i+1);
+ sprintf(num, "%d ", i);
strcat(buf, num);
}
}
}
strcat(buf, "\n");
sendit(sock, buf);
+ strcpy(buf, " wpos=");
+ for (i=0; i<5; i++) {
+ if (bit_is_set(i, run->wpos)) {
+ sprintf(num, "%d ", i+1);
+ strcat(buf, num);
+ }
+ }
+ strcat(buf, "\n");
+ sendit(sock, buf);
sendit(sock, " mins=%d\n", run->minute);
if (run->pool) {
sendit(sock, " --> ");
set_bit(index, res_all.hdr.item_present);
}
-
+static void store_replace(LEX *lc, struct res_items *item, int index, int pass)
+{
+ int token, i;
+ token = lex_get_token(lc, T_NAME);
+ /* Scan Replacement options */
+ for (i=0; ReplaceOptions[i].name; i++) {
+ if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
+ ((JOB *)(item->value))->replace = ReplaceOptions[i].token;
+ i = 0;
+ break;
+ }
+ }
+ if (i != 0) {
+ scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str);
+ }
+ scan_to_eol(lc);
+ set_bit(index, res_all.hdr.item_present);
+}
/*
* Store backup/verify info for Job record
/* Fix to scan Replacement options */
for (i=0; ReplaceOptions[i].name; i++) {
if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
- ((JOB *)(item->value))->RestoreOptions = ReplaceOptions[i].token;
+ ((JOB *)(item->value))->replace = ReplaceOptions[i].token;
i = 0;
break;
}
* Scan for Include options (keyword=option) is converted into one or
* two characters. Verifyopts=xxxx is Vxxxx:
*/
-static char *scan_include_options(LEX *lc, int keyword)
+static void scan_include_options(LEX *lc, int keyword, char *opts, int optlen)
{
int token, i;
- static char opts[100];
char option[3];
option[0] = 0; /* default option = none */
- opts[0] = option[2] = 0; /* terminate options */
- for (;;) {
- token = lex_get_token(lc, T_NAME); /* expect at least one option */
- if (keyword == INC_KW_VERIFY) { /* special case */
- /* ***FIXME**** ensure these are in permitted set */
- strcpy(option, "V"); /* indicate Verify */
- strcat(option, lc->str);
- strcat(option, ":"); /* terminate it */
- } else {
- for (i=0; FS_options[i].name; i++) {
- if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
- option[0] = FS_options[i].option[0];
- option[1] = FS_options[i].option[1];
- i = 0;
- break;
- }
- }
- if (i != 0) {
- scan_err1(lc, "Expected a FileSet option keyword, got: %s", lc->str);
+ option[2] = 0; /* terminate options */
+ token = lex_get_token(lc, T_NAME); /* expect at least one option */
+ if (keyword == INC_KW_VERIFY) { /* special case */
+ /* ***FIXME**** ensure these are in permitted set */
+ bstrncat(opts, "V", optlen); /* indicate Verify */
+ bstrncat(opts, lc->str, optlen);
+ bstrncat(opts, ":", optlen); /* terminate it */
+ } else {
+ for (i=0; FS_options[i].name; i++) {
+ if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) {
+ /* NOTE! maximum 2 letters here or increase option[3] */
+ option[0] = FS_options[i].option[0];
+ option[1] = FS_options[i].option[1];
+ i = 0;
+ break;
}
}
- strcat(opts, option);
-
- /* check if more options are specified */
- if (lc->ch != ',') {
- break; /* no, get out */
+ if (i != 0) {
+ scan_err1(lc, "Expected a FileSet option keyword, got:%s:", lc->str);
+ } else { /* add option */
+ bstrncat(opts, option, optlen);
+ Dmsg3(200, "Catopts=%s option=%s optlen=%d\n", opts, option,optlen);
}
- token = lex_get_token(lc, T_ALL); /* yes, eat comma */
}
- return opts;
+ /* If option terminated by comma, eat it */
+ if (lc->ch == ',') {
+ token = lex_get_token(lc, T_ALL); /* yes, eat comma */
+ }
}
lc->options |= LOPT_NO_IDENT; /* make spaces significant */
/* Get include options */
- strcpy(inc_opts, "0"); /* set no options */
+ inc_opts[0] = 0;
while ((token=lex_get_token(lc, T_ALL)) != T_BOB) {
keyword = INC_KW_NONE;
for (i=0; FS_option_kw[i].name; i++) {
if ((token=lex_get_token(lc, T_ALL)) != T_EQUALS) {
scan_err1(lc, "expected an = following keyword, got: %s", lc->str);
}
- strcat(inc_opts, scan_include_options(lc, keyword));
+ scan_include_options(lc, keyword, inc_opts, sizeof(inc_opts));
if (token == T_BOB) {
break;
}
}
- strcat(inc_opts, " "); /* add field separator */
+ if (!inc_opts[0]) {
+ strcat(inc_opts, "0 "); /* set no options */
+ } else {
+ strcat(inc_opts, " "); /* add field separator */
+ }
inc_opts_len = strlen(inc_opts);
-
if (pass == 1) {
if (!res_all.res_fs.have_MD5) {
MD5Init(&res_all.res_fs.md5c);