X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fdird%2Fdird_conf.c;h=bebf9c27adfa92ba3b4b7ecc88e6199e7ac1ea08;hb=3cd7f14201e385fe8025a58a07dd151bb27c13e3;hp=79b910fd70bf58a93352008e78730e52d2ba8660;hpb=f52955c3e03b6fef083df5b77ce25a75213e2539;p=bacula%2Fbacula diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 79b910fd70..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 @@ -87,8 +88,9 @@ static struct res_items dir_items[] = { {"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0}, {"description", store_str, ITEM(res_dir.hdr.desc), 0, 0, 0}, {"messages", store_res, ITEM(res_dir.messages), R_MSGS, 0, 0}, - {"dirport", store_pint, ITEM(res_dir.DIRport), 0, ITEM_REQUIRED, 0}, - {"queryfile", store_dir, ITEM(res_dir.query_file), 0, 0, 0}, + {"dirport", store_pint, ITEM(res_dir.DIRport), 0, ITEM_DEFAULT, 9101}, + {"diraddress", store_str, ITEM(res_dir.DIRaddr), 0, 0, 0}, + {"queryfile", store_dir, ITEM(res_dir.query_file), 0, ITEM_REQUIRED, 0}, {"workingdirectory", store_dir, ITEM(res_dir.working_directory), 0, ITEM_REQUIRED, 0}, {"piddirectory", store_dir, ITEM(res_dir.pid_directory), 0, ITEM_REQUIRED, 0}, {"subsysdirectory", store_dir, ITEM(res_dir.subsys_directory), 0, ITEM_REQUIRED, 0}, @@ -109,7 +111,7 @@ static struct res_items cli_items[] = { {"name", store_name, ITEM(res_client.hdr.name), 0, ITEM_REQUIRED, 0}, {"description", store_str, ITEM(res_client.hdr.desc), 0, 0, 0}, {"address", store_str, ITEM(res_client.address), 0, ITEM_REQUIRED, 0}, - {"fdport", store_pint, ITEM(res_client.FDport), 0, ITEM_REQUIRED, 0}, + {"fdport", store_pint, ITEM(res_client.FDport), 0, ITEM_DEFAULT, 9102}, {"password", store_password, ITEM(res_client.password), 0, ITEM_REQUIRED, 0}, {"catalog", store_res, ITEM(res_client.catalog), R_CATALOG, 0, 0}, {"fileretention", store_time, ITEM(res_client.FileRetention), 0, ITEM_DEFAULT, 60*60*24*60}, @@ -125,12 +127,13 @@ static struct res_items cli_items[] = { static struct res_items store_items[] = { {"name", store_name, ITEM(res_store.hdr.name), 0, ITEM_REQUIRED, 0}, {"description", store_str, ITEM(res_store.hdr.desc), 0, 0, 0}, - {"sdport", store_pint, ITEM(res_store.SDport), 0, ITEM_REQUIRED, 0}, + {"sdport", store_pint, ITEM(res_store.SDport), 0, ITEM_DEFAULT, 9103}, {"sddport", store_pint, ITEM(res_store.SDDport), 0, 0, 0}, /* deprecated */ {"address", store_str, ITEM(res_store.address), 0, ITEM_REQUIRED, 0}, {"password", store_password, ITEM(res_store.password), 0, ITEM_REQUIRED, 0}, {"device", store_strname, ITEM(res_store.dev_name), 0, ITEM_REQUIRED, 0}, {"mediatype", store_strname, ITEM(res_store.media_type), 0, ITEM_REQUIRED, 0}, + {"autochanger", store_yesno, ITEM(res_store.autochanger), 1, ITEM_DEFAULT, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -171,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}, @@ -180,6 +184,7 @@ static struct res_items job_items[] = { {"runbeforejob", store_str, ITEM(res_job.RunBeforeJob), 0, 0, 0}, {"runafterjob", store_str, ITEM(res_job.RunAfterJob), 0, 0, 0}, {"spoolattributes", store_yesno, ITEM(res_job.SpoolAttributes), 1, ITEM_DEFAULT, 0}, + {"writebootstrap", store_dir, ITEM(res_job.WriteBootstrap), 0, 0, 0}, {NULL, NULL, NULL, 0, 0, 0} }; @@ -222,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}, - {"acceptanyvolume", store_yesno, ITEM(res_pool.accept_any_volume), 1, 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} @@ -285,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}, @@ -327,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} }; @@ -338,22 +347,28 @@ static struct s_kw ReplaceOptions[] = { /* Define FileSet KeyWord values */ -#define FS_KW_NONE 0 -#define FS_KW_COMPRESSION 1 -#define FS_KW_SIGNATURE 2 -#define FS_KW_ENCRYPTION 3 -#define FS_KW_VERIFY 4 -#define FS_KW_ONEFS 5 -#define FS_KW_RECURSE 6 - -/* FileSet keywords */ +#define INC_KW_NONE 0 +#define INC_KW_COMPRESSION 1 +#define INC_KW_SIGNATURE 2 +#define INC_KW_ENCRYPTION 3 +#define INC_KW_VERIFY 4 +#define INC_KW_ONEFS 5 +#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[] = { - {"compression", FS_KW_COMPRESSION}, - {"signature", FS_KW_SIGNATURE}, - {"encryption", FS_KW_ENCRYPTION}, - {"verify", FS_KW_VERIFY}, - {"onefs", FS_KW_ONEFS}, - {"recurse", FS_KW_RECURSE}, + {"compression", INC_KW_COMPRESSION}, + {"signature", INC_KW_SIGNATURE}, + {"encryption", INC_KW_ENCRYPTION}, + {"verify", INC_KW_VERIFY}, + {"onefs", INC_KW_ONEFS}, + {"recurse", INC_KW_RECURSE}, + {"sparse", INC_KW_SPARSE}, + {"replace", INC_KW_REPLACE}, + {"readfifo", INC_KW_READFIFO}, {NULL, 0} }; @@ -367,23 +382,30 @@ struct s_fs_opt { /* Options permitted for each keyword and resulting value */ static struct s_fs_opt FS_options[] = { - {"md5", FS_KW_SIGNATURE, "M"}, - {"gzip", FS_KW_COMPRESSION, "Z6"}, - {"gzip1", FS_KW_COMPRESSION, "Z1"}, - {"gzip2", FS_KW_COMPRESSION, "Z2"}, - {"gzip3", FS_KW_COMPRESSION, "Z3"}, - {"gzip4", FS_KW_COMPRESSION, "Z4"}, - {"gzip5", FS_KW_COMPRESSION, "Z5"}, - {"gzip6", FS_KW_COMPRESSION, "Z6"}, - {"gzip7", FS_KW_COMPRESSION, "Z7"}, - {"gzip8", FS_KW_COMPRESSION, "Z8"}, - {"gzip9", FS_KW_COMPRESSION, "Z9"}, - {"blowfish", FS_KW_ENCRYPTION, "B"}, /* ***FIXME*** not implemented */ - {"3des", FS_KW_ENCRYPTION, "3"}, /* ***FIXME*** not implemented */ - {"yes", FS_KW_ONEFS, "0"}, - {"no", FS_KW_ONEFS, "f"}, - {"yes", FS_KW_RECURSE, "0"}, - {"no", FS_KW_RECURSE, "h"}, + {"md5", INC_KW_SIGNATURE, "M"}, + {"gzip", INC_KW_COMPRESSION, "Z6"}, + {"gzip1", INC_KW_COMPRESSION, "Z1"}, + {"gzip2", INC_KW_COMPRESSION, "Z2"}, + {"gzip3", INC_KW_COMPRESSION, "Z3"}, + {"gzip4", INC_KW_COMPRESSION, "Z4"}, + {"gzip5", INC_KW_COMPRESSION, "Z5"}, + {"gzip6", INC_KW_COMPRESSION, "Z6"}, + {"gzip7", INC_KW_COMPRESSION, "Z7"}, + {"gzip8", INC_KW_COMPRESSION, "Z8"}, + {"gzip9", INC_KW_COMPRESSION, "Z9"}, + {"blowfish", INC_KW_ENCRYPTION, "B"}, /* ***FIXME*** not implemented */ + {"3des", INC_KW_ENCRYPTION, "3"}, /* ***FIXME*** not implemented */ + {"yes", INC_KW_ONEFS, "0"}, + {"no", INC_KW_ONEFS, "f"}, + {"yes", INC_KW_RECURSE, "0"}, + {"no", INC_KW_RECURSE, "h"}, + {"yes", INC_KW_SPARSE, "s"}, + {"no", INC_KW_SPARSE, "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} }; @@ -485,6 +507,9 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... if (res->res_job.RunAfterJob) { sendit(sock, " --> RunAfter=%s\n", NPRT(res->res_job.RunAfterJob)); } + if (res->res_job.WriteBootstrap) { + sendit(sock, " --> WriteBootstrap=%s\n", NPRT(res->res_job.WriteBootstrap)); + } if (res->res_job.storage) { sendit(sock, " --> "); dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock); @@ -521,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); } } @@ -554,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, " --> "); @@ -637,22 +671,32 @@ void free_resource(int type) switch (type) { case R_DIRECTOR: - if (res->res_dir.working_directory) + if (res->res_dir.working_directory) { free(res->res_dir.working_directory); - if (res->res_dir.pid_directory) + } + if (res->res_dir.pid_directory) { free(res->res_dir.pid_directory); - if (res->res_dir.subsys_directory) + } + if (res->res_dir.subsys_directory) { free(res->res_dir.subsys_directory); - if (res->res_dir.password) + } + if (res->res_dir.password) { free(res->res_dir.password); - if (res->res_dir.query_file) + } + if (res->res_dir.query_file) { free(res->res_dir.query_file); + } + if (res->res_dir.DIRaddr) { + free(res->res_dir.DIRaddr); + } break; case R_CLIENT: - if (res->res_client.address) + if (res->res_client.address) { free(res->res_client.address); - if (res->res_client.password) + } + if (res->res_client.password) { free(res->res_client.password); + } break; case R_STORAGE: if (res->res_store.address) @@ -712,6 +756,9 @@ void free_resource(int type) if (res->res_job.RestoreBootstrap) { free(res->res_job.RestoreBootstrap); } + if (res->res_job.WriteBootstrap) { + free(res->res_job.WriteBootstrap); + } if (res->res_job.RunBeforeJob) { free(res->res_job.RunBeforeJob); } @@ -962,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 @@ -1142,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; } @@ -1166,47 +1230,44 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass) /* - * Scan for FileSet options (keyword=option) is converted into one or + * Scan for Include options (keyword=option) is converted into one or * two characters. Verifyopts=xxxx is Vxxxx: */ -static char *scan_fs_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 == FS_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 */ + } } @@ -1223,31 +1284,34 @@ 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 = FS_KW_NONE; + keyword = INC_KW_NONE; for (i=0; FS_option_kw[i].name; i++) { if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) { keyword = FS_option_kw[i].token; break; } } - if (keyword == FS_KW_NONE) { + if (keyword == INC_KW_NONE) { scan_err1(lc, "Expected a FileSet keyword, got: %s", lc->str); } /* Option keyword should be following by =