X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fdird_conf.c;h=bebf9c27adfa92ba3b4b7ecc88e6199e7ac1ea08;hb=3cd7f14201e385fe8025a58a07dd151bb27c13e3;hp=d737a7e08cd56bbe854e2b92d14d3cc56287b18a;hpb=c369a18cfaa0cb4fe7c93398f8c55a356f857719;p=bacula%2Fbacula diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index d737a7e08c..bebf9c27ad 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -22,7 +22,7 @@ * 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 @@ -63,6 +63,7 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass); 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 @@ -173,6 +174,7 @@ static struct res_items job_items[] = { {"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}, @@ -225,16 +227,20 @@ static struct res_items group_items[] = { * 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} @@ -288,7 +294,6 @@ struct s_jl joblevels[] = { {"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}, @@ -330,10 +335,11 @@ static struct s_kw RestoreFields[] = { }; /* 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} }; @@ -350,6 +356,7 @@ static struct s_kw ReplaceOptions[] = { #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[] = { @@ -361,6 +368,7 @@ 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} }; @@ -396,6 +404,8 @@ static struct s_fs_opt FS_options[] = { {"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} }; @@ -536,7 +546,7 @@ next_run: 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); } } @@ -569,6 +579,15 @@ next_run: } 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, " --> "); @@ -990,7 +1009,24 @@ static void store_level(LEX *lc, struct res_items *item, int index, int pass) 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 @@ -1170,7 +1206,7 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass) /* 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; } @@ -1197,44 +1233,41 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass) * 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 */ + } } @@ -1251,7 +1284,7 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) 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++) { @@ -1267,15 +1300,18 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) 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);