/*
* Main configuration file parser for Bacula Directors,
* some parts may be split into separate files such as
- * the schedule configuration (sch_config.c).
+ * the schedule configuration (run_config.c).
*
* Note, the configuration file parser consists of three parts
*
*/
int r_first = R_FIRST;
int r_last = R_LAST;
+
pthread_mutex_t res_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Imported subroutines */
{"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},
+ {"fdaddress", store_str, ITEM(res_client.address), 0, 0, 0},
{"fdport", store_pint, ITEM(res_client.FDport), 0, ITEM_DEFAULT, 9102},
{"password", store_password, ITEM(res_client.password), 0, ITEM_REQUIRED, 0},
+ {"fdpassword", store_password, ITEM(res_client.password), 0, 0, 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},
{"jobretention", store_time, ITEM(res_client.JobRetention), 0, ITEM_DEFAULT, 60*60*24*180},
* name handler value code flags default_value
*/
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_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},
- {"enablessl", store_yesno, ITEM(res_store.enable_ssl), 1, ITEM_DEFAULT, 0},
+ {"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_DEFAULT, 9103},
+ {"address", store_str, ITEM(res_store.address), 0, ITEM_REQUIRED, 0},
+ {"sdaddress", store_str, ITEM(res_store.address), 0, 0, 0},
+ {"password", store_password, ITEM(res_store.password), 0, ITEM_REQUIRED, 0},
+ {"sdpassword", store_password, ITEM(res_store.password), 0, 0, 0},
+ {"device", store_strname, ITEM(res_store.dev_name), 0, ITEM_REQUIRED, 0},
+ {"sddevicename", store_strname, ITEM(res_store.dev_name), 0, 0, 0},
+ {"mediatype", store_strname, ITEM(res_store.media_type), 0, ITEM_REQUIRED, 0},
+ {"autochanger", store_yesno, ITEM(res_store.autochanger), 1, ITEM_DEFAULT, 0},
+ {"enablessl", store_yesno, ITEM(res_store.enable_ssl), 1, ITEM_DEFAULT, 0},
{"maximumconcurrentjobs", store_pint, ITEM(res_store.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1},
+ {"sddport", store_pint, ITEM(res_store.SDDport), 0, 0, 0}, /* deprecated */
{NULL, NULL, NULL, 0, 0, 0}
};
{"dbport", store_pint, ITEM(res_cat.db_port), 0, 0, 0},
/* keep this password as store_str for the moment */
{"password", store_str, ITEM(res_cat.db_password), 0, 0, 0},
+ {"dbpassword", store_str, ITEM(res_cat.db_password), 0, 0, 0},
{"user", store_str, ITEM(res_cat.db_user), 0, 0, 0},
{"dbname", store_str, ITEM(res_cat.db_name), 0, ITEM_REQUIRED, 0},
{"dbsocket", store_str, ITEM(res_cat.db_socket), 0, 0, 0},
{"prunevolumes", store_yesno, ITEM(res_job.PruneVolumes), 1, ITEM_DEFAULT, 0},
{"runbeforejob", store_str, ITEM(res_job.RunBeforeJob), 0, 0, 0},
{"runafterjob", store_str, ITEM(res_job.RunAfterJob), 0, 0, 0},
+ {"clientrunbeforejob", store_str, ITEM(res_job.ClientRunBeforeJob), 0, 0, 0},
+ {"clientrunafterjob", store_str, ITEM(res_job.ClientRunAfterJob), 0, 0, 0},
{"spoolattributes", store_yesno, ITEM(res_job.SpoolAttributes), 1, ITEM_DEFAULT, 0},
{"writebootstrap", store_dir, ITEM(res_job.WriteBootstrap), 0, 0, 0},
{"maximumconcurrentjobs", store_pint, ITEM(res_job.MaxConcurrentJobs), 0, ITEM_DEFAULT, 1},
{"rescheduleonerror", store_yesno, ITEM(res_job.RescheduleOnError), 1, ITEM_DEFAULT, 0},
{"rescheduleinterval", store_time, ITEM(res_job.RescheduleInterval), 0, ITEM_DEFAULT, 60 * 30},
{"rescheduletimes", store_pint, ITEM(res_job.RescheduleTimes), 0, 0, 0},
+ {"priority", store_pint, ITEM(res_job.Priority), 0, ITEM_DEFAULT, 10},
{NULL, NULL, NULL, 0, 0, 0}
};
static struct res_items fs_items[] = {
{"name", store_name, ITEM(res_fs.hdr.name), 0, ITEM_REQUIRED, 0},
{"description", store_str, ITEM(res_fs.hdr.desc), 0, 0, 0},
- {"include", store_inc, NULL, 0, 0, 0},
- {"finclude", store_finc, NULL, 0, ITEM_NO_EQUALS, 0},
- {"exclude", store_inc, NULL, 1, 0, 0},
- {"fexclude", store_finc, NULL, 1, ITEM_NO_EQUALS, 0},
+ {"include", store_inc, NULL, 0, ITEM_NO_EQUALS, 0},
+ {"exclude", store_inc, NULL, 1, ITEM_NO_EQUALS, 0},
{NULL, NULL, NULL, 0, 0, 0}
};
{"cleaningprefix", store_strname, ITEM(res_pool.cleaning_prefix), 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},
+ {"purgeoldestvolume", store_yesno, ITEM(res_pool.purge_oldest_volume), 1, 0, 0},
{"recycleoldestvolume", store_yesno, ITEM(res_pool.recycle_oldest_volume), 1, 0, 0},
+ {"recyclecurrentvolume", store_yesno, ITEM(res_pool.recycle_current_volume), 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},
* This is the master resource definition.
* It must have one item for each of the resources.
*
+ * NOTE!!! keep it in the same order as the R_codes
+ * or eliminate all resources[rindex].name
+ *
* name items rcode res_head
*/
struct s_res resources[] = {
{"director", dir_items, R_DIRECTOR, NULL},
- {"console", con_items, R_CONSOLE, NULL},
{"client", cli_items, R_CLIENT, NULL},
{"job", job_items, R_JOB, NULL},
{"storage", store_items, R_STORAGE, NULL},
{"pool", pool_items, R_POOL, NULL},
{"messages", msgs_items, R_MSGS, NULL},
{"counter", counter_items, R_COUNTER, NULL},
+ {"console", con_items, R_CONSOLE, NULL},
{NULL, NULL, 0, NULL}
};
{"Differential", L_DIFFERENTIAL, JT_BACKUP},
{"Since", L_SINCE, JT_BACKUP},
{"Catalog", L_VERIFY_CATALOG, JT_VERIFY},
- {"Initcatalog", L_VERIFY_INIT, JT_VERIFY},
+ {"InitCatalog", L_VERIFY_INIT, JT_VERIFY},
{"VolumeToCatalog", L_VERIFY_VOLUME_TO_CATALOG, JT_VERIFY},
{"Data", L_VERIFY_DATA, JT_VERIFY},
{NULL, 0}
{
URES *res = (URES *)reshdr;
int recurse = 1;
- char ed1[30], ed2[30];
+ char ed1[100], ed2[100];
if (res == NULL) {
sendit(sock, "No %s resource defined\n", res_to_str(type));
res->res_con.hdr.name, res->res_con.enable_ssl);
break;
case R_COUNTER:
- sendit(sock, "Counter: name=%s min=%d max=%d\n",
- res->res_counter.hdr.name, res->res_counter.MinValue,
- res->res_counter.MaxValue);
+ if (res->res_counter.WrapCounter) {
+ sendit(sock, "Counter: name=%s min=%d max=%d cur=%d wrapcntr=%s\n",
+ res->res_counter.hdr.name, res->res_counter.MinValue,
+ res->res_counter.MaxValue, res->res_counter.CurrentValue,
+ res->res_counter.WrapCounter->hdr.name);
+ } else {
+ sendit(sock, "Counter: name=%s min=%d max=%d\n",
+ res->res_counter.hdr.name, res->res_counter.MinValue,
+ res->res_counter.MaxValue);
+ }
if (res->res_counter.Catalog) {
sendit(sock, " --> ");
dump_resource(-R_CATALOG, (RES *)res->res_counter.Catalog, sendit, sock);
}
- if (res->res_counter.WrapCounter) {
- sendit(sock, " --> ");
- dump_resource(-R_COUNTER, (RES *)res->res_counter.WrapCounter, sendit, sock);
- }
-
-
+ break;
- break;
case R_CLIENT:
sendit(sock, "Client: name=%s address=%s FDport=%d MaxJobs=%u\n",
res->res_client.hdr.name, res->res_client.address, res->res_client.FDport,
res->res_client.MaxConcurrentJobs);
- sendit(sock, " JobRetention=%" lld " FileRetention=%" lld " AutoPrune=%d\n",
- res->res_client.JobRetention, res->res_client.FileRetention,
+ sendit(sock, " JobRetention=%s FileRetention=%s AutoPrune=%d\n",
+ edit_utime(res->res_client.JobRetention, ed1),
+ edit_utime(res->res_client.FileRetention, ed2),
res->res_client.AutoPrune);
if (res->res_client.catalog) {
sendit(sock, " --> ");
res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user));
break;
case R_JOB:
- sendit(sock, "Job: name=%s JobType=%d level=%s MaxJobs=%u\n",
+ sendit(sock, "Job: name=%s JobType=%d level=%s Priority=%d MaxJobs=%u\n",
res->res_job.hdr.name, res->res_job.JobType,
- level_to_str(res->res_job.level), res->res_job.MaxConcurrentJobs);
+ level_to_str(res->res_job.level), res->res_job.Priority,
+ res->res_job.MaxConcurrentJobs);
sendit(sock, " Resched=%d Times=%d Interval=%s\n",
res->res_job.RescheduleOnError, res->res_job.RescheduleTimes,
edit_uint64_with_commas(res->res_job.RescheduleInterval, ed1));
sendit(sock, "FileSet: name=%s\n", res->res_fs.hdr.name);
for (int i=0; i<res->res_fs.num_includes; i++) {
INCEXE *incexe = res->res_fs.include_items[i];
- for (int j=0; j<incexe->num_names; j++) {
- sendit(sock, " Inc: %s\n", incexe->name_list[j]);
+ for (int j=0; j<incexe->name_list.size(); j++) {
+ sendit(sock, " Inc: %s\n", incexe->name_list.get(j));
}
}
for (int i=0; i<res->res_fs.num_excludes; i++) {
INCEXE *incexe = res->res_fs.exclude_items[i];
- for (int j=0; j<incexe->num_names; j++) {
- sendit(sock, " Exc: %s\n", incexe->name_list[j]);
+ for (int j=0; j<incexe->name_list.size(); j++) {
+ sendit(sock, " Exc: %s\n", incexe->name_list.get(j));
}
}
break;
}
next_run:
sendit(sock, " --> Run Level=%s\n", level_to_str(run->level));
- strcpy(buf, " hour=");
+ bstrncpy(buf, " hour=", sizeof(buf));
for (i=0; i<24; i++) {
if (bit_is_set(i, run->hour)) {
sprintf(num, "%d ", i);
- strcat(buf, num);
+ bstrncat(buf, num, sizeof(buf));
}
}
strcat(buf, "\n");
sendit(sock, " use_cat=%d use_once=%d acpt_any=%d cat_files=%d\n",
res->res_pool.use_catalog, res->res_pool.use_volume_once,
res->res_pool.accept_any_volume, res->res_pool.catalog_files);
- sendit(sock, " max_vols=%d auto_prune=%d VolRetention=%" lld "\n",
+ sendit(sock, " max_vols=%d auto_prune=%d VolRetention=%s\n",
res->res_pool.max_volumes, res->res_pool.AutoPrune,
- res->res_pool.VolRetention);
- sendit(sock, " recycle=%d LabelFormat=%s\n", res->res_pool.Recycle,
+ edit_utime(res->res_pool.VolRetention, ed1));
+ sendit(sock, " VolUse=%s recycle=%d LabelFormat=%s\n",
+ edit_utime(res->res_pool.VolUseDuration, ed1),
+ res->res_pool.Recycle,
NPRT(res->res_pool.label_format));
sendit(sock, " CleaningPrefix=%s\n",
NPRT(res->res_pool.cleaning_prefix));
sendit(sock, " recyleOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n",
- res->res_pool.recycle_oldest_volume,
+ res->res_pool.purge_oldest_volume,
res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles);
break;
case R_MSGS:
*/
static void free_incexe(INCEXE *incexe)
{
- for (int i=0; i<incexe->num_names; i++) {
- free(incexe->name_list[i]);
- }
- if (incexe->name_list) {
- free(incexe->name_list);
- }
+ incexe->name_list.destroy();
for (int i=0; i<incexe->num_opts; i++) {
FOPTS *fopt = incexe->opts_list[i];
- if (fopt->match) {
- free(fopt->match);
- }
- for (int j=0; j<fopt->num_base; j++) {
- free(fopt->base_list[j]);
- }
- if (fopt->base_list) {
- free(fopt->base_list);
- }
+ fopt->match.destroy();
+ fopt->base_list.destroy();
free(fopt);
}
if (incexe->opts_list) {
if (res->res_job.RunAfterJob) {
free(res->res_job.RunAfterJob);
}
+ if (res->res_job.ClientRunBeforeJob) {
+ free(res->res_job.ClientRunBeforeJob);
+ }
+ if (res->res_job.ClientRunAfterJob) {
+ free(res->res_job.ClientRunAfterJob);
+ }
break;
case R_MSGS:
- if (res->res_msgs.mail_cmd)
+ if (res->res_msgs.mail_cmd) {
free(res->res_msgs.mail_cmd);
- if (res->res_msgs.operator_cmd)
+ }
+ if (res->res_msgs.operator_cmd) {
free(res->res_msgs.operator_cmd);
+ }
free_msgs_res((MSGS *)res); /* free message resource */
res = NULL;
break;
return;
}
- /* The following code is only executed for pass 1 */
+ /*
+ * The following code is only executed during pass 1
+ */
switch (type) {
case R_DIRECTOR:
size = sizeof(DIRRES);
} else {
RES *next;
/* Add new res to end of chain */
- for (next=resources[rindex].res_head; next->next; next=next->next)
- { }
+ for (next=resources[rindex].res_head; next->next; next=next->next) {
+ if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+ Emsg2(M_ERROR_TERM, 0,
+ _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
+ resources[rindex].name, res->res_dir.hdr.name);
+ }
+ }
next->next = (RES *)res;
- Dmsg3(200, "Inserting %s res: %s index=%d\n", res_to_str(type),
- res->res_dir.hdr.name, rindex);
+ Dmsg4(200, "Inserting %s res: %s index=%d pass=%d\n", res_to_str(type),
+ res->res_dir.hdr.name, rindex, pass);
}
}
}
((JOB *)(item->value))->JobType = item->code;
while ((token = lex_get_token(lc, T_ALL)) != T_EOL) {
- int found;
+ bool found = false;
Dmsg1(150, "store_backup got token=%s\n", lex_tok_to_str(token));
scan_err1(lc, "Expected a backup/verify keyword, got: %s", lc->str);
}
Dmsg1(190, "Got keyword: %s\n", lc->str);
- found = FALSE;
for (i=0; BakVerFields[i].name; i++) {
if (strcasecmp(lc->str, BakVerFields[i].name) == 0) {
- found = TRUE;
+ found = true;
if (lex_get_token(lc, T_ALL) != T_EQUALS) {
scan_err1(lc, "Expected an equals, got: %s", lc->str);
}
token = lex_get_token(lc, T_NAME);
Dmsg1(190, "Got value: %s\n", lc->str);
switch (BakVerFields[i].token) {
- case 'C':
- /* Find Client Resource */
- if (pass == 2) {
- res = GetResWithName(R_CLIENT, lc->str);
- if (res == NULL) {
- scan_err1(lc, "Could not find specified Client Resource: %s",
- lc->str);
- }
- res_all.res_job.client = (CLIENT *)res;
+ case 'C':
+ /* Find Client Resource */
+ if (pass == 2) {
+ res = GetResWithName(R_CLIENT, lc->str);
+ if (res == NULL) {
+ scan_err1(lc, "Could not find specified Client Resource: %s",
+ lc->str);
}
- break;
- case 'F':
- /* Find FileSet Resource */
- if (pass == 2) {
- res = GetResWithName(R_FILESET, lc->str);
- if (res == NULL) {
- scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
- lc->str);
- }
- res_all.res_job.fileset = (FILESET *)res;
- }
- break;
- case 'L':
- /* Get level */
- for (i=0; joblevels[i].level_name; i++) {
- if (joblevels[i].job_type == item->code &&
- strcasecmp(lc->str, joblevels[i].level_name) == 0) {
- ((JOB *)(item->value))->level = joblevels[i].level;
- i = 0;
- break;
- }
+ res_all.res_job.client = (CLIENT *)res;
+ }
+ break;
+ case 'F':
+ /* Find FileSet Resource */
+ if (pass == 2) {
+ res = GetResWithName(R_FILESET, lc->str);
+ if (res == NULL) {
+ scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
+ lc->str);
}
- if (i != 0) {
- scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
+ res_all.res_job.fileset = (FILESET *)res;
+ }
+ break;
+ case 'L':
+ /* Get level */
+ for (i=0; joblevels[i].level_name; i++) {
+ if (joblevels[i].job_type == item->code &&
+ strcasecmp(lc->str, joblevels[i].level_name) == 0) {
+ ((JOB *)(item->value))->level = joblevels[i].level;
+ i = 0;
+ break;
}
- break;
+ }
+ if (i != 0) {
+ scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
+ }
+ break;
} /* end switch */
break;
} /* end if strcmp() */
((JOB *)(item->value))->JobType = item->code;
while ((token = lex_get_token(lc, T_ALL)) != T_EOL) {
- int found;
+ bool found = false;
if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
scan_err1(lc, "expected a name, got: %s", lc->str);
}
- found = FALSE;
for (i=0; RestoreFields[i].name; i++) {
Dmsg1(190, "Restore kw=%s\n", lc->str);
if (strcasecmp(lc->str, RestoreFields[i].name) == 0) {
- found = TRUE;
+ found = true;
if (lex_get_token(lc, T_ALL) != T_EQUALS) {
scan_err1(lc, "Expected an equals, got: %s", lc->str);
}
token = lex_get_token(lc, T_ALL);
Dmsg1(190, "Restore value=%s\n", lc->str);
switch (RestoreFields[i].token) {
- case 'B':
- /* Bootstrap */
- if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
- scan_err1(lc, "Expected a Restore bootstrap file, got: %s", lc->str);
- }
- if (pass == 1) {
- res_all.res_job.RestoreBootstrap = bstrdup(lc->str);
- }
- break;
- case 'C':
- /* Find Client Resource */
- if (pass == 2) {
- res = GetResWithName(R_CLIENT, lc->str);
- if (res == NULL) {
- scan_err1(lc, "Could not find specified Client Resource: %s",
- lc->str);
- }
- res_all.res_job.client = (CLIENT *)res;
- }
- break;
- case 'F':
- /* Find FileSet Resource */
- if (pass == 2) {
- res = GetResWithName(R_FILESET, lc->str);
- if (res == NULL) {
- scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
- lc->str);
- }
- res_all.res_job.fileset = (FILESET *)res;
- }
- break;
- case 'J':
- /* JobId */
- if (token != T_NUMBER) {
- scan_err1(lc, "expected an integer number, got: %s", lc->str);
- }
- errno = 0;
- res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0);
- Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId);
- if (errno != 0) {
- scan_err1(lc, "expected an integer number, got: %s", lc->str);
- }
- break;
- case 'W':
- /* Where */
- if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
- scan_err1(lc, "Expected a Restore root directory, got: %s", lc->str);
- }
- if (pass == 1) {
- res_all.res_job.RestoreWhere = bstrdup(lc->str);
- }
- break;
- case 'R':
- /* Replacement options */
- if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
- scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
+ case 'B':
+ /* Bootstrap */
+ if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+ scan_err1(lc, "Expected a Restore bootstrap file, got: %s", lc->str);
+ }
+ if (pass == 1) {
+ res_all.res_job.RestoreBootstrap = bstrdup(lc->str);
+ }
+ break;
+ case 'C':
+ /* Find Client Resource */
+ if (pass == 2) {
+ res = GetResWithName(R_CLIENT, lc->str);
+ if (res == NULL) {
+ scan_err1(lc, "Could not find specified Client Resource: %s",
+ lc->str);
}
- /* Fix to 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;
- }
+ res_all.res_job.client = (CLIENT *)res;
+ }
+ break;
+ case 'F':
+ /* Find FileSet Resource */
+ if (pass == 2) {
+ res = GetResWithName(R_FILESET, lc->str);
+ if (res == NULL) {
+ scan_err1(lc, "Could not find specified FileSet Resource: %s\n",
+ lc->str);
}
- if (i != 0) {
- scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str);
+ res_all.res_job.fileset = (FILESET *)res;
+ }
+ break;
+ case 'J':
+ /* JobId */
+ if (token != T_NUMBER) {
+ scan_err1(lc, "expected an integer number, got: %s", lc->str);
+ }
+ errno = 0;
+ res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0);
+ Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId);
+ if (errno != 0) {
+ scan_err1(lc, "expected an integer number, got: %s", lc->str);
+ }
+ break;
+ case 'W':
+ /* Where */
+ if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+ scan_err1(lc, "Expected a Restore root directory, got: %s", lc->str);
+ }
+ if (pass == 1) {
+ res_all.res_job.RestoreWhere = bstrdup(lc->str);
+ }
+ break;
+ case 'R':
+ /* Replacement options */
+ if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+ scan_err1(lc, "Expected a keyword name, got: %s", lc->str);
+ }
+ /* Fix to 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;
}
- break;
+ }
+ if (i != 0) {
+ scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str);
+ }
+ break;
} /* end switch */
break;
} /* end if strcmp() */