Items to note: !!!!!
+- Recycle Oldest Volume has changed to be Purge Oldest Volume
+ Please change your Director's .conf file.
- The default time interval is now days instead of seconds. Please
check your .conf files!
- For MySQL users, you must have the thread safe client libraries
(./create_mys... ./make_my...).
- Document c:/working directory better than /working directory.
- Document all the status codes JobLevel, JobType, JobStatus.
+- Document update volume: jobid, current, before, all
+- Document run "yes".
+- Document that bscan does not work with multiple simultaneous jobs.
Testing to do: (painful)
- Figure out how to use ssh or stunnel to protect Bacula communications.
For 1.31 release:
-- Non-fatal errors are not correct counting attribs.c:277
- In Win portable restore the directory is not create
27-Jun-2003 16:52 tibs-fd: kernsrestore.2003-06-27_16.52.20 Error:
create_file.c:175 Could not create
- Make Restore report an error if FD or SD term codes are not OK.
- To link with mysqlclient_r may require -lssl -lcrypto
- Document Heart beat code
+- Non-fatal errors are not correct counting attribs.c:277
#define _(s) gettext((s))
#define N_(s) (s)
#else
+#undef _
#define _(s) (s)
+#undef N_
#define N_(s) (s)
+#undef textdomain
#define textdomain(d)
-#define bindtextdomain(p, d)
+/* #define bindtextdomain(p, d) */
#endif
int8_t, int16_t, int32_t, int64_t
uint8_t, uint16_t, uint32_t, uint64_t
- float32_t, float64_t
Also, we define types such as file address lengths.
#define mp_chr(x) x
#ifdef xxxxx
#define mp_chr(x) ((char*)(x))
-struct POOLMEM { };
+struct POOLMEM {
+ POOLMEM() {}
+ operator const char*() const { return (char *)this; }
+};
#endif
+
/* Types */
/* If sys/types.h does not supply intXX_t, supply them ourselves */
at_prompt = FALSE;
/* @ => internal command for us */
if (UA_sock->msg[0] == '@') {
- parse_args(UA_sock->msg, args, &argc, argk, argv, MAX_CMD_ARGS);
+ parse_args(UA_sock->msg, &args, &argc, argk, argv, MAX_CMD_ARGS);
if (!do_a_command(input, UA_sock)) {
break;
}
#include "dird.h"
/* Forward referenced functions */
-static RBSR *sort_bsr(RBSR *bsr);
static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd);
}
}
-static void write_findex(UAContext *ua, RBSR_FINDEX *fi, FILE *fd)
+/*
+ * Our data structures were not designed completely
+ * correctly, so the file indexes cover the full
+ * range regardless of volume. The FirstIndex and LastIndex
+ * passed in here are for the current volume, so when
+ * writing out the fi, constrain them to those values.
+ */
+static void write_findex(UAContext *ua, RBSR_FINDEX *fi,
+ int32_t FirstIndex, int32_t LastIndex, FILE *fd)
{
if (fi) {
- if (fi->findex == fi->findex2) {
- fprintf(fd, "FileIndex=%d\n", fi->findex);
+ int32_t findex, findex2;
+ findex = fi->findex < FirstIndex ? FirstIndex : fi->findex;
+ findex2 = fi->findex2 > LastIndex ? LastIndex : fi->findex2;
+ if (findex == findex2) {
+ fprintf(fd, "FileIndex=%d\n", findex);
} else {
- fprintf(fd, "FileIndex=%d-%d\n", fi->findex, fi->findex2);
+ fprintf(fd, "FileIndex=%d-%d\n", findex, findex2);
}
- write_findex(ua, fi->next, fd);
+ write_findex(ua, fi->next, FirstIndex, LastIndex, fd);
}
}
+static bool is_volume_selected(RBSR_FINDEX *fi,
+ int32_t FirstIndex, int32_t LastIndex)
+{
+ if (fi) {
+ if ((fi->findex >= FirstIndex && fi->findex <= LastIndex) ||
+ (fi->findex2 >= FirstIndex && fi->findex2 <= LastIndex)) {
+ return true;
+ }
+ return is_volume_selected(fi->next, FirstIndex, LastIndex);
+ }
+ return false;
+}
+
+
static void print_findex(UAContext *ua, RBSR_FINDEX *fi)
{
*/
int complete_bsr(UAContext *ua, RBSR *bsr)
{
- JOB_DBR jr;
-
if (bsr) {
+ JOB_DBR jr;
memset(&jr, 0, sizeof(jr));
jr.JobId = bsr->JobId;
if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
free_pool_memory(fname);
return 0;
}
- /* Sort the bsr chain */
- bsr = sort_bsr(bsr);
/* Write them to file */
write_bsr(ua, bsr, fd);
stat = !ferror(fd);
return stat;
}
-/*
- * First sort the bsr chain, then sort the VolParams
- */
-static RBSR *sort_bsr(RBSR *bsr)
-{
- if (!bsr) {
- return bsr;
- }
- /* ****FIXME**** sort the bsr chain */
- for (RBSR *nbsr=bsr; nbsr; nbsr=nbsr->next) {
- }
- return bsr;
-}
-
static void write_bsr(UAContext *ua, RBSR *bsr, FILE *fd)
{
if (bsr) {
for (int i=0; i < bsr->VolCount; i++) {
+ if (!is_volume_selected(bsr->fi, bsr->VolParams[i].FirstIndex,
+ bsr->VolParams[i].LastIndex)) {
+ continue;
+ }
fprintf(fd, "Volume=\"%s\"\n", bsr->VolParams[i].VolumeName);
fprintf(fd, "VolSessionId=%u\n", bsr->VolSessionId);
fprintf(fd, "VolSessionTime=%u\n", bsr->VolSessionTime);
bsr->VolParams[i].EndFile);
fprintf(fd, "VolBlock=%u-%u\n", bsr->VolParams[i].StartBlock,
bsr->VolParams[i].EndBlock);
- write_findex(ua, bsr->fi, fd);
+
+// Dmsg2(000, "bsr VolParam FI=%u LI=%u\n",
+// bsr->VolParams[i].FirstIndex, bsr->VolParams[i].LastIndex);
+ write_findex(ua, bsr->fi, bsr->VolParams[i].FirstIndex,
+ bsr->VolParams[i].LastIndex, fd);
}
write_bsr(ua, bsr->next, fd);
}
}
}
- if (!ok && jcr->pool->recycle_oldest_volume) {
- Dmsg1(200, "No next volume found. RecycleOldest=%d\n",
- jcr->pool->recycle_oldest_volume);
+ if (!ok && jcr->pool->purge_oldest_volume) {
+ Dmsg1(200, "No next volume found. PurgeOldest=%d\n",
+ jcr->pool->purge_oldest_volume);
/* Find oldest volume to recycle */
ok = db_find_next_volume(jcr, jcr->db, -1, &mr);
Dmsg1(400, "Find oldest=%d\n", ok);
Dmsg0(400, "Try purge.\n");
/* Try to purge oldest volume */
ua = new_ua_context(jcr);
- Jmsg(jcr, M_INFO, 0, _("Recycling oldest volume \"%s\"\n"), mr.VolumeName);
+ Jmsg(jcr, M_INFO, 0, _("Purging oldest volume \"%s\"\n"), mr.VolumeName);
ok = purge_jobs_from_volume(ua, &mr);
free_ua_context(ua);
if (ok) {
* 1. The generic lexical scanner in lib/lex.c and lib/lex.h
*
* 2. The generic config scanner in lib/parse_config.c and
- * lib/parse_config.h.
- * These files contain the parser code, some utility
- * routines, and the common store routines (name, int,
- * string).
+ * lib/parse_config.h.
+ * These files contain the parser code, some utility
+ * routines, and the common store routines (name, int,
+ * string).
*
* 3. The daemon specific file, which contains the Resource
- * definitions as well as any specific store routines
- * for the resource records.
+ * definitions as well as any specific store routines
+ * for the resource records.
*
* Kern Sibbald, January MM
*
/*
* Director Resource
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items dir_items[] = {
{"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0},
/*
* Console Resource
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items con_items[] = {
{"name", store_name, ITEM(res_con.hdr.name), 0, ITEM_REQUIRED, 0},
/*
* Client or File daemon resource
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items cli_items[] = {
/* Storage daemon resource
*
- * name handler value code flags default_value
+ * 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},
/*
* Catalog Resource Directives
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items cat_items[] = {
{"name", store_name, ITEM(res_cat.hdr.name), 0, ITEM_REQUIRED, 0},
/*
* Job Resource Directives
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items job_items[] = {
{"name", store_name, ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0},
/* FileSet resource
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items fs_items[] = {
{"name", store_name, ITEM(res_fs.hdr.name), 0, ITEM_REQUIRED, 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},
- {NULL, NULL, NULL, 0, 0, 0}
+ {NULL, NULL, NULL, 0, 0, 0}
};
/* Schedule -- see run_conf.c */
/* Schedule
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items sch_items[] = {
{"name", store_name, ITEM(res_sch.hdr.name), 0, ITEM_REQUIRED, 0},
/* Group resource -- not implemented
*
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items group_items[] = {
{"name", store_name, ITEM(res_group.hdr.name), 0, ITEM_REQUIRED, 0},
/* Pool resource
*
- * name handler value code flags default_value
+ * 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},
{"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},
- {"recycleoldestvolume", store_yesno, ITEM(res_pool.recycle_oldest_volume), 1, 0, 0},
+ {"purgeoldestvolume", store_yesno, ITEM(res_pool.purge_oldest_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},
/*
* Counter Resource
- * name handler value code flags default_value
+ * name handler value code flags default_value
*/
static struct res_items counter_items[] = {
{"name", store_name, ITEM(res_counter.hdr.name), 0, ITEM_REQUIRED, 0},
* This is the master resource definition.
* It must have one item for each of the resources.
*
- * name items rcode res_head
+ * name items rcode res_head
*/
struct s_res resources[] = {
{"director", dir_items, R_DIRECTOR, NULL},
{"pool", pool_items, R_POOL, NULL},
{"messages", msgs_items, R_MSGS, NULL},
{"counter", counter_items, R_COUNTER, NULL},
- {NULL, NULL, 0, NULL}
+ {NULL, NULL, 0, NULL}
};
/* Keywords (RHS) permitted in Job Level records
*
- * level_name level job_type
+ * level_name level job_type
*/
struct s_jl joblevels[] = {
{"Full", L_FULL, JT_BACKUP},
{"Initcatalog", L_VERIFY_INIT, JT_VERIFY},
{"VolumeToCatalog", L_VERIFY_VOLUME_TO_CATALOG, JT_VERIFY},
{"Data", L_VERIFY_DATA, JT_VERIFY},
- {NULL, 0}
+ {NULL, 0}
};
/* Keywords (RHS) permitted in Job type records
*
- * type_name job_type
+ * type_name job_type
*/
struct s_jt jobtypes[] = {
{"backup", JT_BACKUP},
{"admin", JT_ADMIN},
{"verify", JT_VERIFY},
{"restore", JT_RESTORE},
- {NULL, 0}
+ {NULL, 0}
};
{"client", 'C'},
{"fileset", 'F'},
{"level", 'L'},
- {NULL, 0}
+ {NULL, 0}
};
/* Keywords (RHS) permitted in Restore records */
{"where", 'W'}, /* root of restore */
{"replace", 'R'}, /* replacement options */
{"bootstrap", 'B'}, /* bootstrap file */
- {NULL, 0}
+ {NULL, 0}
};
/* Options permitted in Restore replace= */
{"ifnewer", REPLACE_IFNEWER},
{"ifolder", REPLACE_IFOLDER},
{"never", REPLACE_NEVER},
- {NULL, 0}
+ {NULL, 0}
};
char *level_to_str(int level)
sprintf(level_no, "%d", level); /* default if not found */
for (i=0; joblevels[i].level_name; i++) {
if (level == joblevels[i].level) {
- str = joblevels[i].level_name;
- break;
+ str = joblevels[i].level_name;
+ break;
}
}
return str;
sendit(sock, "No %s resource defined\n", res_to_str(type));
return;
}
- if (type < 0) { /* no recursion */
+ if (type < 0) { /* no recursion */
type = - type;
recurse = 0;
}
switch (type) {
case R_DIRECTOR:
sendit(sock, "Director: name=%s MaxJobs=%d FDtimeout=%s SDtimeout=%s\n",
- reshdr->name, res->res_dir.MaxConcurrentJobs,
- edit_uint64(res->res_dir.FDConnectTimeout, ed1),
- edit_uint64(res->res_dir.SDConnectTimeout, ed2));
+ reshdr->name, res->res_dir.MaxConcurrentJobs,
+ edit_uint64(res->res_dir.FDConnectTimeout, ed1),
+ edit_uint64(res->res_dir.SDConnectTimeout, ed2));
if (res->res_dir.query_file) {
sendit(sock, " query_file=%s\n", res->res_dir.query_file);
}
if (res->res_dir.messages) {
sendit(sock, " --> ");
- dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock);
+ dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock);
}
break;
case R_CONSOLE:
sendit(sock, "Console: name=%s SSL=%d\n",
- res->res_con.hdr.name, res->res_con.enable_ssl);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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,
- res->res_client.AutoPrune);
+ res->res_client.JobRetention, res->res_client.FileRetention,
+ res->res_client.AutoPrune);
if (res->res_client.catalog) {
sendit(sock, " --> ");
- dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock);
+ dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock);
}
break;
case R_STORAGE:
sendit(sock, "Storage: name=%s address=%s SDport=%d MaxJobs=%u\n\
DeviceName=%s MediaType=%s\n",
- res->res_store.hdr.name, res->res_store.address, res->res_store.SDport,
- res->res_store.MaxConcurrentJobs,
- res->res_store.dev_name, res->res_store.media_type);
+ res->res_store.hdr.name, res->res_store.address, res->res_store.SDport,
+ res->res_store.MaxConcurrentJobs,
+ res->res_store.dev_name, res->res_store.media_type);
break;
case R_CATALOG:
sendit(sock, "Catalog: name=%s address=%s DBport=%d db_name=%s\n\
db_user=%s\n",
- res->res_cat.hdr.name, NPRT(res->res_cat.db_address),
- res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user));
+ res->res_cat.hdr.name, NPRT(res->res_cat.db_address),
+ 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",
- res->res_job.hdr.name, res->res_job.JobType,
- level_to_str(res->res_job.level), res->res_job.MaxConcurrentJobs);
+ res->res_job.hdr.name, res->res_job.JobType,
+ level_to_str(res->res_job.level), 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));
+ res->res_job.RescheduleOnError, res->res_job.RescheduleTimes,
+ edit_uint64_with_commas(res->res_job.RescheduleInterval, ed1));
if (res->res_job.client) {
sendit(sock, " --> ");
- dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock);
+ dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock);
}
if (res->res_job.fileset) {
sendit(sock, " --> ");
- dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock);
+ dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock);
}
if (res->res_job.schedule) {
sendit(sock, " --> ");
- dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock);
+ dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock);
}
if (res->res_job.RestoreWhere) {
sendit(sock, " --> Where=%s\n", NPRT(res->res_job.RestoreWhere));
}
if (res->res_job.storage) {
sendit(sock, " --> ");
- dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock);
+ dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock);
}
if (res->res_job.pool) {
sendit(sock, " --> ");
- dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock);
+ dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock);
} else {
sendit(sock, "!!! No Pool resource\n");
}
if (res->res_job.messages) {
sendit(sock, " --> ");
- dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock);
+ dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock);
}
break;
case R_FILESET:
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++) {
+ 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 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++) {
+ 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]);
- }
+ }
}
break;
case R_SCHEDULE:
if (res->res_sch.run) {
- int i;
- RUN *run = res->res_sch.run;
- char buf[1000], num[10];
+ int i;
+ RUN *run = res->res_sch.run;
+ char buf[1000], num[10];
sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
- if (!run) {
- break;
- }
+ if (!run) {
+ break;
+ }
next_run:
sendit(sock, " --> Run Level=%s\n", level_to_str(run->level));
strcpy(buf, " hour=");
- for (i=0; i<24; i++) {
- if (bit_is_set(i, run->hour)) {
+ for (i=0; i<24; i++) {
+ if (bit_is_set(i, run->hour)) {
sprintf(num, "%d ", i);
- strcat(buf, num);
- }
- }
+ strcat(buf, num);
+ }
+ }
strcat(buf, "\n");
- sendit(sock, buf);
+ sendit(sock, buf);
strcpy(buf, " mday=");
- for (i=0; i<31; i++) {
- if (bit_is_set(i, run->mday)) {
+ for (i=0; i<31; i++) {
+ if (bit_is_set(i, run->mday)) {
sprintf(num, "%d ", i+1);
- strcat(buf, num);
- }
- }
+ strcat(buf, num);
+ }
+ }
strcat(buf, "\n");
- sendit(sock, buf);
+ sendit(sock, buf);
strcpy(buf, " month=");
- for (i=0; i<12; i++) {
- if (bit_is_set(i, run->month)) {
+ for (i=0; i<12; i++) {
+ if (bit_is_set(i, run->month)) {
sprintf(num, "%d ", i+1);
- strcat(buf, num);
- }
- }
+ strcat(buf, num);
+ }
+ }
strcat(buf, "\n");
- sendit(sock, buf);
+ sendit(sock, buf);
strcpy(buf, " wday=");
- for (i=0; i<7; i++) {
- if (bit_is_set(i, run->wday)) {
+ for (i=0; i<7; i++) {
+ if (bit_is_set(i, run->wday)) {
sprintf(num, "%d ", i+1);
- strcat(buf, num);
- }
- }
+ strcat(buf, num);
+ }
+ }
strcat(buf, "\n");
- sendit(sock, buf);
+ sendit(sock, buf);
strcpy(buf, " wpos=");
- for (i=0; i<5; i++) {
- if (bit_is_set(i, run->wpos)) {
+ for (i=0; i<5; i++) {
+ if (bit_is_set(i, run->wpos)) {
sprintf(num, "%d ", i+1);
- strcat(buf, num);
- }
- }
+ strcat(buf, num);
+ }
+ }
strcat(buf, "\n");
- sendit(sock, buf);
+ sendit(sock, buf);
sendit(sock, " mins=%d\n", run->minute);
- if (run->pool) {
+ if (run->pool) {
sendit(sock, " --> ");
- dump_resource(-R_POOL, (RES *)run->pool, sendit, sock);
- }
- if (run->storage) {
+ dump_resource(-R_POOL, (RES *)run->pool, sendit, sock);
+ }
+ if (run->storage) {
sendit(sock, " --> ");
- dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock);
- }
- if (run->msgs) {
+ dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock);
+ }
+ if (run->msgs) {
sendit(sock, " --> ");
- dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock);
- }
- /* If another Run record is chained in, go print it */
- if (run->next) {
- run = run->next;
- goto next_run;
- }
+ dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock);
+ }
+ /* If another Run record is chained in, go print it */
+ if (run->next) {
+ run = run->next;
+ goto next_run;
+ }
} else {
sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
}
break;
case R_POOL:
sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name,
- res->res_pool.pool_type);
+ res->res_pool.pool_type);
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);
+ 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",
- res->res_pool.max_volumes, res->res_pool.AutoPrune,
- res->res_pool.VolRetention);
+ res->res_pool.max_volumes, res->res_pool.AutoPrune,
+ res->res_pool.VolRetention);
sendit(sock, " recycle=%d LabelFormat=%s\n", res->res_pool.Recycle,
- NPRT(res->res_pool.label_format));
+ NPRT(res->res_pool.label_format));
sendit(sock, " CleaningPrefix=%s\n",
- NPRT(res->res_pool.cleaning_prefix));
+ NPRT(res->res_pool.cleaning_prefix));
sendit(sock, " recyleOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n",
- res->res_pool.recycle_oldest_volume,
- res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles);
+ res->res_pool.purge_oldest_volume,
+ res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles);
break;
case R_MSGS:
sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name);
}
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) {
switch (type) {
case R_DIRECTOR:
if (res->res_dir.working_directory) {
- free(res->res_dir.working_directory);
+ free(res->res_dir.working_directory);
}
if (res->res_dir.pid_directory) {
- free(res->res_dir.pid_directory);
+ free(res->res_dir.pid_directory);
}
if (res->res_dir.subsys_directory) {
- free(res->res_dir.subsys_directory);
+ free(res->res_dir.subsys_directory);
}
if (res->res_dir.password) {
- free(res->res_dir.password);
+ free(res->res_dir.password);
}
if (res->res_dir.query_file) {
- free(res->res_dir.query_file);
+ free(res->res_dir.query_file);
}
if (res->res_dir.DIRaddr) {
- free(res->res_dir.DIRaddr);
+ free(res->res_dir.DIRaddr);
}
break;
case R_COUNTER:
break;
case R_CONSOLE:
if (res->res_con.password) {
- free(res->res_con.password);
+ free(res->res_con.password);
}
break;
case R_CLIENT:
if (res->res_client.address) {
- free(res->res_client.address);
+ free(res->res_client.address);
}
if (res->res_client.password) {
- free(res->res_client.password);
+ free(res->res_client.password);
}
break;
case R_STORAGE:
if (res->res_store.address) {
- free(res->res_store.address);
+ free(res->res_store.address);
}
if (res->res_store.password) {
- free(res->res_store.password);
+ free(res->res_store.password);
}
if (res->res_store.media_type) {
- free(res->res_store.media_type);
+ free(res->res_store.media_type);
}
if (res->res_store.dev_name) {
- free(res->res_store.dev_name);
+ free(res->res_store.dev_name);
}
break;
case R_CATALOG:
if (res->res_cat.db_address) {
- free(res->res_cat.db_address);
+ free(res->res_cat.db_address);
}
if (res->res_cat.db_socket) {
- free(res->res_cat.db_socket);
+ free(res->res_cat.db_socket);
}
if (res->res_cat.db_user) {
- free(res->res_cat.db_user);
+ free(res->res_cat.db_user);
}
if (res->res_cat.db_name) {
- free(res->res_cat.db_name);
+ free(res->res_cat.db_name);
}
if (res->res_cat.db_password) {
- free(res->res_cat.db_password);
+ free(res->res_cat.db_password);
}
break;
case R_FILESET:
if ((num=res->res_fs.num_includes)) {
- while (--num >= 0) {
- free_incexe(res->res_fs.include_items[num]);
- }
- free(res->res_fs.include_items);
+ while (--num >= 0) {
+ free_incexe(res->res_fs.include_items[num]);
+ }
+ free(res->res_fs.include_items);
}
res->res_fs.num_includes = 0;
if ((num=res->res_fs.num_excludes)) {
- while (--num >= 0) {
- free_incexe(res->res_fs.exclude_items[num]);
- }
- free(res->res_fs.exclude_items);
+ while (--num >= 0) {
+ free_incexe(res->res_fs.exclude_items[num]);
+ }
+ free(res->res_fs.exclude_items);
}
res->res_fs.num_excludes = 0;
break;
case R_POOL:
if (res->res_pool.pool_type) {
- free(res->res_pool.pool_type);
+ free(res->res_pool.pool_type);
}
if (res->res_pool.label_format) {
- free(res->res_pool.label_format);
+ free(res->res_pool.label_format);
}
if (res->res_pool.cleaning_prefix) {
- free(res->res_pool.cleaning_prefix);
+ free(res->res_pool.cleaning_prefix);
}
break;
case R_SCHEDULE:
if (res->res_sch.run) {
- RUN *nrun, *next;
- nrun = res->res_sch.run;
- while (nrun) {
- next = nrun->next;
- free(nrun);
- nrun = next;
- }
+ RUN *nrun, *next;
+ nrun = res->res_sch.run;
+ while (nrun) {
+ next = nrun->next;
+ free(nrun);
+ nrun = next;
+ }
}
break;
case R_JOB:
if (res->res_job.RestoreWhere) {
- free(res->res_job.RestoreWhere);
+ free(res->res_job.RestoreWhere);
}
if (res->res_job.RestoreBootstrap) {
- free(res->res_job.RestoreBootstrap);
+ free(res->res_job.RestoreBootstrap);
}
if (res->res_job.WriteBootstrap) {
- free(res->res_job.WriteBootstrap);
+ free(res->res_job.WriteBootstrap);
}
if (res->res_job.RunBeforeJob) {
- free(res->res_job.RunBeforeJob);
+ free(res->res_job.RunBeforeJob);
}
if (res->res_job.RunAfterJob) {
- free(res->res_job.RunAfterJob);
+ free(res->res_job.RunAfterJob);
}
break;
case R_MSGS:
if (res->res_msgs.mail_cmd)
- free(res->res_msgs.mail_cmd);
+ free(res->res_msgs.mail_cmd);
if (res->res_msgs.operator_cmd)
- free(res->res_msgs.operator_cmd);
+ free(res->res_msgs.operator_cmd);
free_msgs_res((MSGS *)res); /* free message resource */
res = NULL;
break;
*/
for (i=0; items[i].name; i++) {
if (items[i].flags & ITEM_REQUIRED) {
- if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
+ if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {
Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n",
- items[i].name, resources[rindex]);
- }
+ items[i].name, resources[rindex]);
+ }
}
/* If this triggers, take a look at lib/parse_conf.h */
if (i >= MAX_RES_ITEMS) {
case R_POOL:
case R_MSGS:
case R_FILESET:
- break;
+ break;
/* Resources containing another resource */
case R_DIRECTOR:
- if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) {
+ if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name);
- }
- res->res_dir.messages = res_all.res_dir.messages;
- break;
+ }
+ res->res_dir.messages = res_all.res_dir.messages;
+ break;
case R_JOB:
- if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) {
+ if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find Job resource %s\n", res_all.res_dir.hdr.name);
- }
- res->res_job.messages = res_all.res_job.messages;
- res->res_job.schedule = res_all.res_job.schedule;
- res->res_job.client = res_all.res_job.client;
- res->res_job.fileset = res_all.res_job.fileset;
- res->res_job.storage = res_all.res_job.storage;
- res->res_job.pool = res_all.res_job.pool;
- if (res->res_job.JobType == 0) {
+ }
+ res->res_job.messages = res_all.res_job.messages;
+ res->res_job.schedule = res_all.res_job.schedule;
+ res->res_job.client = res_all.res_job.client;
+ res->res_job.fileset = res_all.res_job.fileset;
+ res->res_job.storage = res_all.res_job.storage;
+ res->res_job.pool = res_all.res_job.pool;
+ if (res->res_job.JobType == 0) {
Emsg1(M_ERROR_TERM, 0, "Job Type not defined for Job resource %s\n", res_all.res_dir.hdr.name);
- }
- if (res->res_job.level != 0) {
- int i;
- for (i=0; joblevels[i].level_name; i++) {
- if (joblevels[i].level == res->res_job.level &&
- joblevels[i].job_type == res->res_job.JobType) {
- i = 0;
- break;
- }
- }
- if (i != 0) {
+ }
+ if (res->res_job.level != 0) {
+ int i;
+ for (i=0; joblevels[i].level_name; i++) {
+ if (joblevels[i].level == res->res_job.level &&
+ joblevels[i].job_type == res->res_job.JobType) {
+ i = 0;
+ break;
+ }
+ }
+ if (i != 0) {
Emsg1(M_ERROR_TERM, 0, "Inappropriate level specified in Job resource %s\n",
- res_all.res_dir.hdr.name);
- }
- }
- break;
+ res_all.res_dir.hdr.name);
+ }
+ }
+ break;
case R_COUNTER:
- if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
+ if ((res = (URES *)GetResWithName(R_COUNTER, res_all.res_counter.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find Counter resource %s\n", res_all.res_counter.hdr.name);
- }
- res->res_counter.Catalog = res_all.res_counter.Catalog;
- res->res_counter.WrapCounter = res_all.res_counter.WrapCounter;
- break;
+ }
+ res->res_counter.Catalog = res_all.res_counter.Catalog;
+ res->res_counter.WrapCounter = res_all.res_counter.WrapCounter;
+ break;
case R_CLIENT:
- if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) {
+ if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find Client resource %s\n", res_all.res_client.hdr.name);
- }
- res->res_client.catalog = res_all.res_client.catalog;
- break;
+ }
+ res->res_client.catalog = res_all.res_client.catalog;
+ break;
case R_SCHEDULE:
- /* Schedule is a bit different in that it contains a RUN record
+ /* Schedule is a bit different in that it contains a RUN record
* chain which isn't a "named" resource. This chain was linked
- * in by run_conf.c during pass 2, so here we jam the pointer
- * into the Schedule resource.
- */
- if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) {
+ * in by run_conf.c during pass 2, so here we jam the pointer
+ * into the Schedule resource.
+ */
+ if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) {
Emsg1(M_ERROR_TERM, 0, "Cannot find Schedule resource %s\n", res_all.res_client.hdr.name);
- }
- res->res_sch.run = res_all.res_sch.run;
- break;
+ }
+ res->res_sch.run = res_all.res_sch.run;
+ break;
default:
Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type);
- error = 1;
- break;
+ error = 1;
+ break;
}
/* Note, the resource name was already saved during pass 1,
* so here, we can just release it.
*/
if (res_all.res_dir.hdr.name) {
- free(res_all.res_dir.hdr.name);
- res_all.res_dir.hdr.name = NULL;
+ free(res_all.res_dir.hdr.name);
+ res_all.res_dir.hdr.name = NULL;
}
if (res_all.res_dir.hdr.desc) {
- free(res_all.res_dir.hdr.desc);
- res_all.res_dir.hdr.desc = NULL;
+ free(res_all.res_dir.hdr.desc);
+ res_all.res_dir.hdr.desc = NULL;
}
return;
}
res = (URES *)malloc(size);
memcpy(res, &res_all, size);
if (!resources[rindex].res_head) {
- resources[rindex].res_head = (RES *)res; /* store first entry */
+ resources[rindex].res_head = (RES *)res; /* store first entry */
Dmsg3(200, "Inserting first %s res: %s index=%d\n", res_to_str(type),
- res->res_dir.hdr.name, rindex);
+ res->res_dir.hdr.name, rindex);
} else {
- RES *next;
- /* Add new res to end of chain */
- for (next=resources[rindex].res_head; next->next; next=next->next)
- { }
- next->next = (RES *)res;
+ RES *next;
+ /* Add new res to end of chain */
+ for (next=resources[rindex].res_head; next->next; next=next->next)
+ { }
+ next->next = (RES *)res;
Dmsg3(200, "Inserting %s res: %s index=%d\n", res_to_str(type),
- res->res_dir.hdr.name, rindex);
+ res->res_dir.hdr.name, rindex);
}
}
}
/* Store the type both pass 1 and pass 2 */
for (i=0; jobtypes[i].type_name; i++) {
if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) {
- ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
- i = 0;
- break;
+ ((JOB *)(item->value))->JobType = jobtypes[i].job_type;
+ i = 0;
+ break;
}
}
if (i != 0) {
/* Store the level pass 2 so that type is defined */
for (i=0; joblevels[i].level_name; i++) {
if (strcasecmp(lc->str, joblevels[i].level_name) == 0) {
- ((JOB *)(item->value))->level = joblevels[i].level;
- i = 0;
- break;
+ ((JOB *)(item->value))->level = joblevels[i].level;
+ i = 0;
+ break;
}
}
if (i != 0) {
/* Scan Replacement options */
for (i=0; ReplaceOptions[i].name; i++) {
if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) {
- *(int *)(item->value) = ReplaceOptions[i].token;
- i = 0;
- break;
+ *(int *)(item->value) = ReplaceOptions[i].token;
+ i = 0;
+ break;
}
}
if (i != 0) {
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;
- if (lex_get_token(lc, T_ALL) != T_EQUALS) {
+ if (strcasecmp(lc->str, BakVerFields[i].name) == 0) {
+ 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);
+ }
+ token = lex_get_token(lc, T_NAME);
Dmsg1(190, "Got value: %s\n", lc->str);
- switch (BakVerFields[i].token) {
+ switch (BakVerFields[i].token) {
case 'C':
- /* Find Client Resource */
- if (pass == 2) {
- res = GetResWithName(R_CLIENT, lc->str);
- if (res == NULL) {
+ /* 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;
+ 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) {
+ /* 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;
+ 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;
- }
- }
- if (i != 0) {
+ /* 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;
+ }
+ }
+ if (i != 0) {
scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str);
- }
- break;
- } /* end switch */
- break;
- } /* end if strcmp() */
+ }
+ break;
+ } /* end switch */
+ break;
+ } /* end if strcmp() */
} /* end for */
if (!found) {
scan_err1(lc, "%s not a valid Backup/verify keyword", lc->str);
}
} /* end while */
- lc->options = options; /* reset original options */
+ lc->options = options; /* reset original options */
set_bit(index, res_all.hdr.item_present);
}
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;
- if (lex_get_token(lc, T_ALL) != T_EQUALS) {
+ if (strcasecmp(lc->str, RestoreFields[i].name) == 0) {
+ 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);
+ }
+ token = lex_get_token(lc, T_ALL);
Dmsg1(190, "Restore value=%s\n", lc->str);
- switch (RestoreFields[i].token) {
+ switch (RestoreFields[i].token) {
case 'B':
- /* Bootstrap */
- if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+ /* 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;
+ }
+ 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) {
+ /* 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;
+ 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) {
+ /* 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;
+ lc->str);
+ }
+ res_all.res_job.fileset = (FILESET *)res;
+ }
+ break;
case 'J':
- /* JobId */
- if (token != T_NUMBER) {
+ /* 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);
+ }
+ 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) {
+ if (errno != 0) {
scan_err1(lc, "expected an integer number, got: %s", lc->str);
- }
- break;
+ }
+ break;
case 'W':
- /* Where */
- if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
+ /* 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;
+ }
+ 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) {
+ /* 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;
- }
- }
- if (i != 0) {
+ }
+ /* 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;
+ }
+ }
+ if (i != 0) {
scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str);
- }
- break;
- } /* end switch */
- break;
- } /* end if strcmp() */
+ }
+ break;
+ } /* end switch */
+ break;
+ } /* end if strcmp() */
} /* end for */
if (!found) {
scan_err1(lc, "%s not a valid Restore keyword", lc->str);
}
} /* end while */
- lc->options = options; /* reset original options */
+ lc->options = options; /* reset original options */
set_bit(index, res_all.hdr.item_present);
}
#define MAX_FOPTS 30
-struct s_fopts_item {
+/* File options structure */
+struct FOPTS {
char opts[MAX_FOPTS]; /* options string */
- char *match; /* match string */
- char **base_list; /* list of base job names */
- int num_base; /* number of bases in list */
+ alist match; /* match string(s) */
+ alist base_list; /* list of base names */
};
-typedef struct s_fopts_item FOPTS;
/* This is either an include item or an exclude item */
-struct s_incexc_item {
+struct INCEXE {
FOPTS *current_opts; /* points to current options structure */
FOPTS **opts_list; /* options list */
int num_opts; /* number of options items */
int max_names; /* malloc'ed size of name list */
int num_names; /* number of names in the list */
};
-typedef struct s_incexc_item INCEXE;
/*
* FileSet Resource
int catalog_files; /* maintain file entries in catalog */
int use_volume_once; /* write on volume only once */
int accept_any_volume; /* accept any volume */
- int recycle_oldest_volume; /* recycle oldest volume */
+ int purge_oldest_volume; /* purge oldest volume */
uint32_t max_volumes; /* max number of volumes */
utime_t VolRetention; /* volume retention period in seconds */
utime_t VolUseDuration; /* duration volume can be used */
* Send Level command to File daemon
*/
switch (jcr->JobLevel) {
- case L_BASE:
- bnet_fsend(fd, levelcmd, "base", " ", 0);
- break;
- case L_FULL:
- bnet_fsend(fd, levelcmd, "full", " ", 0);
- break;
- case L_DIFFERENTIAL:
- case L_INCREMENTAL:
- bnet_fsend(fd, levelcmd, "since ", jcr->stime, 0);
- break;
- case L_SINCE:
- default:
- Jmsg2(jcr, M_FATAL, 0, _("Unimplemented backup level %d %c\n"),
- jcr->JobLevel, jcr->JobLevel);
- return 0;
+ case L_BASE:
+ bnet_fsend(fd, levelcmd, "base", " ", 0);
+ break;
+ case L_FULL:
+ bnet_fsend(fd, levelcmd, "full", " ", 0);
+ break;
+ case L_DIFFERENTIAL:
+ case L_INCREMENTAL:
+ bnet_fsend(fd, levelcmd, "since ", jcr->stime, 0);
+ break;
+ case L_SINCE:
+ default:
+ Jmsg2(jcr, M_FATAL, 0, _("Unimplemented backup level %d %c\n"),
+ jcr->JobLevel, jcr->JobLevel);
+ return 0;
}
Dmsg1(120, ">filed: %s", fd->msg);
if (!response(jcr, fd, OKlevel, "Level", DISPLAY_ERROR)) {
char *p;
int optlen, stat;
INCEXE *ie;
+ FOPTS *fo;
+
if (list == INC_LIST) {
ie = fileset->include_items[i];
} else {
ie = fileset->exclude_items[i];
}
+ fo = ie->opts_list[0];
+ for (int j=0; j<fo->match.size(); j++) {
+ Dmsg1(000, "Match=%s\n", fo->match.get(j));
+ }
for (int j=0; j<ie->num_names; j++) {
p = ie->name_list[j];
switch (*p) {
*/
token = lex_get_token(lc, T_ALL);
switch (token) {
- case T_IDENTIFIER:
- case T_UNQUOTED_STRING:
- case T_QUOTED_STRING:
- setup_current_opts();
- if (res_incexe.current_opts->match) {
- scan_err0(lc, _("More than one match specified.\n"));
- }
- res_incexe.current_opts->match = bstrdup(lc->str);
- break;
- default:
- scan_err1(lc, _("Expected a filename, got: %s\n"), lc->str);
+ case T_IDENTIFIER:
+ case T_UNQUOTED_STRING:
+ case T_QUOTED_STRING:
+ setup_current_opts();
+ res_incexe.current_opts->match.append(bstrdup(lc->str));
+ break;
+ default:
+ scan_err1(lc, _("Expected a filename, got: %s\n"), lc->str);
}
} else { /* pass 2 */
lex_get_token(lc, T_ALL);
static void store_base(LEX *lc, struct res_items *item, int index, int pass)
{
int token;
- FOPTS *copt;
if (pass == 1) {
setup_current_opts();
* Pickup Base Job Name
*/
token = lex_get_token(lc, T_NAME);
- copt = res_incexe.current_opts;
- if (copt->base_list == NULL) {
- copt->base_list = (char **)malloc(sizeof(char *));
- } else {
- copt->base_list = (char **)realloc(copt->base_list,
- sizeof(char *) * (copt->num_base+1));
- }
- copt->base_list[copt->num_base++] = bstrdup(lc->str);
+ res_incexe.current_opts->base_list.append(bstrdup(lc->str));
} else { /* pass 2 */
lex_get_token(lc, T_ALL);
}
if (pass == 1) {
setup_current_opts();
-
bstrncat(res_incexe.current_opts->opts, inc_opts, MAX_FOPTS);
}
#include "dird.h"
/* Commands sent to File daemon */
-static char restorecmd[] = "restore replace=%c where=%s\n";
+static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
static char storaddr[] = "storage address=%s port=%d ssl=0\n";
static char sessioncmd[] = "session %s %ld %ld %ld %ld %ld %ld\n";
where = ""; /* None */
}
bash_spaces(where);
- bnet_fsend(fd, restorecmd, replace, where);
+ bnet_fsend(fd, restorecmd, replace, jcr->prefix_links, where);
unbash_spaces(where);
if (!response(jcr, fd, OKrestore, "Restore", DISPLAY_ERROR)) {
}
switch (find_arg_keyword(ua, kw)) {
- case 0:
- case 1:
- update_volume(ua);
- return 1;
- case 2:
- update_pool(ua);
- return 1;
- case 3:
- update_slots(ua);
- return 1;
- default:
- break;
+ case 0:
+ case 1:
+ update_volume(ua);
+ return 1;
+ case 2:
+ update_pool(ua);
+ return 1;
+ case 3:
+ update_slots(ua);
+ return 1;
+ default:
+ break;
}
start_prompt(ua, _("Update choice:\n"));
add_prompt(ua, _("Pool from resource"));
add_prompt(ua, _("Slots from autochanger"));
switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) {
- case 0:
- update_volume(ua);
- break;
- case 1:
- update_pool(ua);
- break;
- case 2:
- update_slots(ua);
- break;
- default:
- break;
+ case 0:
+ update_volume(ua);
+ break;
+ case 1:
+ update_pool(ua);
+ break;
+ case 2:
+ update_slots(ua);
+ break;
+ default:
+ break;
}
return 1;
}
+static void update_volstatus(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+ POOLMEM *query = get_pool_memory(PM_MESSAGE);
+ bstrncpy(mr->VolStatus, val, sizeof(mr->VolStatus));
+ Mmsg(&query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%u",
+ mr->VolStatus, mr->MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ } else {
+ bsendmsg(ua, _("New Volume status is: %s\n"), mr->VolStatus);
+ }
+ free_pool_memory(query);
+}
+
+static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+ char ed1[50];
+ POOLMEM *query = get_pool_memory(PM_MESSAGE);
+ if (!duration_to_utime(val, &mr->VolRetention)) {
+ bsendmsg(ua, _("Invalid retention period specified.\n"));
+ return;
+ }
+ Mmsg(&query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%u",
+ edit_uint64(mr->VolRetention, ed1), mr->MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ } else {
+ bsendmsg(ua, _("New retention seconds is: %s\n"),
+ edit_utime(mr->VolRetention, ed1));
+ }
+ free_pool_memory(query);
+}
+
+static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+ char ed1[50];
+ POOLMEM *query = get_pool_memory(PM_MESSAGE);
+ if (!duration_to_utime(val, &mr->VolUseDuration)) {
+ bsendmsg(ua, _("Invalid use duration specified.\n"));
+ return;
+ }
+ query = get_pool_memory(PM_MESSAGE);
+ Mmsg(&query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%u",
+ edit_uint64(mr->VolUseDuration, ed1), mr->MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ } else {
+ bsendmsg(ua, _("New use duration is: %s\n"),
+ edit_utime(mr->VolUseDuration, ed1));
+ }
+ free_pool_memory(query);
+}
+
+static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+ POOLMEM *query = get_pool_memory(PM_MESSAGE);
+ Mmsg(&query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%u",
+ val, mr->MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ } else {
+ bsendmsg(ua, _("New max jobs is: %s\n"), val);
+ }
+ free_pool_memory(query);
+}
+
+static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+ POOLMEM *query = get_pool_memory(PM_MESSAGE);
+ Mmsg(&query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%u",
+ val, mr->MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ } else {
+ bsendmsg(ua, _("New max files is: %s\n"), val);
+ }
+ free_pool_memory(query);
+}
+
+static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+ uint64_t maxbytes;
+ char ed1[50];
+ POOLMEM *query = get_pool_memory(PM_MESSAGE);
+ if (!size_to_uint64(val, strlen(val), &maxbytes)) {
+ bsendmsg(ua, _("Invalid byte size specification.\n"));
+ return;
+ }
+ Mmsg(&query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%u",
+ edit_uint64(maxbytes, ed1), mr->MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ } else {
+ bsendmsg(ua, _("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
+ }
+ free_pool_memory(query);
+}
+
+static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
+{
+ int recycle;
+ POOLMEM *query = get_pool_memory(PM_MESSAGE);
+ if (strcasecmp(val, _("yes")) == 0) {
+ recycle = 1;
+ } else if (strcasecmp(val, _("no")) == 0) {
+ recycle = 0;
+ } else {
+ bsendmsg(ua, _("Invalid value. It must by yes or no.\n"));
+ return;
+ }
+ Mmsg(&query, "UPDATE Media SET Recycle=%d WHERE MediaId=%u",
+ recycle, mr->MediaId);
+ if (!db_sql_query(ua->db, query, NULL, NULL)) {
+ bsendmsg(ua, "%s", db_strerror(ua->db));
+ } else {
+ bsendmsg(ua, _("New recycle flag is: %s\n"),
+ mr->Recycle==1?_("yes"):_("no"));
+ }
+ free_pool_memory(query);
+}
+
/*
* Update a media record -- allows you to change the
* Volume status. E.g. if you want Bacula to stop
MEDIA_DBR mr;
POOLMEM *query;
char ed1[30];
+ bool done = false;
+ char *kw[] = {
+ N_("VolStatus"),
+ N_("VolRetention"),
+ N_("VolUse"),
+ N_("MaxVolJobs"),
+ N_("MaxVolFiles"),
+ N_("Recycle"),
+ NULL };
+ if (!select_media_dbr(ua, &mr)) {
+ return 0;
+ }
+ for (int i=0; kw[i]; i++) {
+ if (find_arg_with_value(ua, kw[i]) > 0) {
+ switch (i) {
+ case 0:
+ update_volstatus(ua, ua->argv[i], &mr);
+ break;
+ }
+ done = true;
+ }
+ }
- for (int done=0; !done; ) {
+ for ( ; !done; ) {
if (!select_media_dbr(ua, &mr)) {
return 0;
}
if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
return 1;
}
- bstrncpy(mr.VolStatus, ua->cmd, sizeof(mr.VolStatus));
- query = get_pool_memory(PM_MESSAGE);
- Mmsg(&query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%u",
- mr.VolStatus, mr.MediaId);
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
- bsendmsg(ua, _("New Volume status is: %s\n"), mr.VolStatus);
- }
- free_pool_memory(query);
+ update_volstatus(ua, ua->cmd, &mr);
break;
case 1: /* Retention */
bsendmsg(ua, _("Current retention seconds is: %s\n"),
if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
return 0;
}
- if (!duration_to_utime(ua->cmd, &mr.VolRetention)) {
- bsendmsg(ua, _("Invalid retention period specified.\n"));
- break;
- }
- query = get_pool_memory(PM_MESSAGE);
- Mmsg(&query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%u",
- edit_uint64(mr.VolRetention, ed1), mr.MediaId);
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
- bsendmsg(ua, _("New retention seconds is: %s\n"),
- edit_utime(mr.VolRetention, ed1));
- }
- free_pool_memory(query);
+ update_volretention(ua, ua->cmd, &mr);
break;
case 2: /* Use Duration */
if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
return 0;
}
- if (!duration_to_utime(ua->cmd, &mr.VolUseDuration)) {
- bsendmsg(ua, _("Invalid use duration specified.\n"));
- break;
- }
- query = get_pool_memory(PM_MESSAGE);
- Mmsg(&query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%u",
- edit_uint64(mr.VolUseDuration, ed1), mr.MediaId);
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
- bsendmsg(ua, _("New use duration is: %s\n"),
- edit_utime(mr.VolUseDuration, ed1));
- }
- free_pool_memory(query);
+ update_voluseduration(ua, ua->cmd, &mr);
break;
case 3: /* Max Jobs */
- int32_t maxjobs;
bsendmsg(ua, _("Current max jobs is: %u\n"), mr.MaxVolJobs);
if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
return 0;
}
- maxjobs = ua->pint32_val;
- query = get_pool_memory(PM_MESSAGE);
- Mmsg(&query, "UPDATE Media SET MaxVolJobs=%u WHERE MediaId=%u",
- maxjobs, mr.MediaId);
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
- bsendmsg(ua, _("New max jobs is: %u\n"), maxjobs);
- }
- free_pool_memory(query);
+ update_volmaxjobs(ua, ua->cmd, &mr);
break;
case 4: /* Max Files */
- int32_t maxfiles;
bsendmsg(ua, _("Current max files is: %u\n"), mr.MaxVolFiles);
if (!get_pint(ua, _("Enter new Maximum Files: "))) {
return 0;
}
- maxfiles = ua->pint32_val;
- query = get_pool_memory(PM_MESSAGE);
- Mmsg(&query, "UPDATE Media SET MaxVolFiles=%u WHERE MediaId=%u",
- maxfiles, mr.MediaId);
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
- bsendmsg(ua, _("New max files is: %u\n"), maxfiles);
- }
- free_pool_memory(query);
+ update_volmaxfiles(ua, ua->cmd, &mr);
break;
case 5: /* Max Bytes */
- uint64_t maxbytes;
bsendmsg(ua, _("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
return 0;
}
- if (!size_to_uint64(ua->cmd, strlen(ua->cmd), &maxbytes)) {
- bsendmsg(ua, _("Invalid byte size specification.\n"));
- break;
- }
- query = get_pool_memory(PM_MESSAGE);
- Mmsg(&query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%u",
- edit_uint64(maxbytes, ed1), mr.MediaId);
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
- bsendmsg(ua, _("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
- }
- free_pool_memory(query);
+ update_volmaxbytes(ua, ua->cmd, &mr);
break;
case 6: /* Recycle */
- int recycle;
bsendmsg(ua, _("Current recycle flag is: %s\n"),
mr.Recycle==1?_("yes"):_("no"));
if (!get_yesno(ua, _("Enter new Recycle status: "))) {
return 0;
}
- recycle = ua->pint32_val;
- query = get_pool_memory(PM_MESSAGE);
- Mmsg(&query, "UPDATE Media SET Recycle=%d WHERE MediaId=%u",
- recycle, mr.MediaId);
- if (!db_sql_query(ua->db, query, NULL, NULL)) {
- bsendmsg(ua, "%s", db_strerror(ua->db));
- } else {
- bsendmsg(ua, _("New recycle flag is: %s\n"),
- mr.Recycle==1?_("yes"):_("no"));
- }
- free_pool_memory(query);
+ update_volrecycle(ua, ua->cmd, &mr);
break;
case 7: /* Slot */
POOL *pool;
POOLMEM *query;
-
pool = get_pool_resource(ua);
if (!pool) {
return 0;
bnet_sig(fd, BNET_TERMINATE);
bnet_close(fd);
ua->jcr->file_bsock = NULL;
-
return;
}
add_prompt(ua, _("Client"));
add_prompt(ua, _("All"));
switch(do_prompt(ua, "", _("Select daemon type to set debug level"), NULL, 0)) {
- case 0: /* Director */
- debug_level = level;
- break;
- case 1:
- store = get_storage_resource(ua, 0);
- if (store) {
- do_storage_setdebug(ua, store, level);
- }
- break;
- case 2:
- client = select_client_resource(ua);
- if (client) {
- do_client_setdebug(ua, client, level);
- }
- break;
- case 3:
- do_all_setdebug(ua, level);
- break;
- default:
- break;
+ case 0: /* Director */
+ debug_level = level;
+ break;
+ case 1:
+ store = get_storage_resource(ua, 0);
+ if (store) {
+ do_storage_setdebug(ua, store, level);
+ }
+ break;
+ case 2:
+ client = select_client_resource(ua);
+ if (client) {
+ do_client_setdebug(ua, client, level);
+ }
+ break;
+ case 3:
+ do_all_setdebug(ua, level);
+ break;
+ default:
+ break;
}
return 1;
}
"Pool or a Volume since they may contain data.\n\n"));
switch (find_arg_keyword(ua, keywords)) {
- case 0:
- delete_volume(ua);
- return 1;
- case 1:
- delete_pool(ua);
- return 1;
- default:
- break;
+ case 0:
+ delete_volume(ua);
+ return 1;
+ case 1:
+ delete_pool(ua);
+ return 1;
+ default:
+ break;
}
switch (do_keyword_prompt(ua, _("Choose catalog item to delete"), keywords)) {
- case 0:
- delete_volume(ua);
- break;
- case 1:
- delete_pool(ua);
- break;
- default:
- bsendmsg(ua, _("Nothing done.\n"));
- break;
+ case 0:
+ delete_volume(ua);
+ break;
+ case 1:
+ delete_pool(ua);
+ break;
+ default:
+ bsendmsg(ua, _("Nothing done.\n"));
+ break;
}
return 1;
}
void parse_ua_args(UAContext *ua)
{
- parse_args(ua->cmd, ua->args, &ua->argc, ua->argk, ua->argv, MAX_CMD_ARGS);
+ parse_args(ua->cmd, &ua->args, &ua->argc, ua->argk, ua->argv, MAX_CMD_ARGS);
}
static void get_storage_from_mediatype(UAContext *ua, NAME_LIST *name_list, JOBIDS *ji);
static int select_backups_before_date(UAContext *ua, JOBIDS *ji, char *date);
-
/*
* Restore files
*
if (!db_sql_query(ua->db, query, unique_name_list_handler, (void *)&name_list)) {
bsendmsg(ua, "%s", db_strerror(ua->db));
}
-
}
bsendmsg(ua, "%d item%s inserted into the tree and marked for extraction.\n",
items, items==1?"":"s");
get_storage_from_mediatype(ua, &name_list, &ji);
free_name_list(&name_list);
- /* Let the user select which files to restore */
- user_select_files_from_tree(&tree);
+ if (find_arg(ua, _("all")) < 0) {
+ /* Let the user select which files to restore */
+ user_select_files_from_tree(&tree);
+ }
/*
* Walk down through the tree finding all files marked to be
JobId_t JobId;
JOB_DBR jr;
POOLMEM *query;
- int done = 0;
+ bool done = false;
+ int i;
char *list[] = {
"List last 20 Jobs run",
"List Jobs where a given File is saved",
"Cancel",
NULL };
- bsendmsg(ua, _("\nFirst you select one or more JobIds that contain files\n"
+ char *kw[] = {
+ "jobid", /* 0 */
+ "current", /* 1 */
+ "before", /* 2 */
+ NULL
+ };
+
+ switch (find_arg_keyword(ua, kw)) {
+ case 0: /* jobid */
+ i = find_arg_with_value(ua, _("jobid"));
+ if (i < 0) {
+ return 0;
+ }
+ bstrncpy(ji->JobIds, ua->argv[i], sizeof(ji->JobIds));
+ done = true;
+ break;
+ case 1: /* current */
+ bstrutime(date, sizeof(date), time(NULL));
+ if (!select_backups_before_date(ua, ji, date)) {
+ return 0;
+ }
+ done = true;
+ break;
+ case 2: /* before */
+ i = find_arg_with_value(ua, _("before"));
+ if (i < 0) {
+ return 0;
+ }
+ if (str_to_utime(ua->argv[i]) == 0) {
+ bsendmsg(ua, _("Improper date format: %s\n"), ua->argv[i]);
+ return 0;
+ }
+ bstrncpy(date, ua->argv[i], sizeof(date));
+ if (!select_backups_before_date(ua, ji, date)) {
+ return 0;
+ }
+ done = true;
+ break;
+ default:
+ break;
+ }
+
+ if (!done) {
+ bsendmsg(ua, _("\nFirst you select one or more JobIds that contain files\n"
"to be restored. You will be presented several methods\n"
"of specifying the JobIds. Then you will be allowed to\n"
"select which files from those JobIds are to be restored.\n\n"));
+ }
+ /* If choice not already made above, prompt */
for ( ; !done; ) {
start_prompt(ua, _("To select the JobIds, you have the following choices:\n"));
for (int i=0; list[i]; i++) {
add_prompt(ua, list[i]);
}
- done = 1;
+ done = true;
switch (do_prompt(ua, "", _("Select item: "), NULL, 0)) {
case -1: /* error */
return 0;
case 0: /* list last 20 Jobs run */
db_list_sql_query(ua->jcr, ua->db, uar_list_jobs, prtit, ua, 1, HORZ_LIST);
- done = 0;
+ done = false;
break;
case 1: /* list where a file is saved */
char *fname;
free(fname);
db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
free_pool_memory(query);
- done = 0;
+ done = false;
break;
case 2: /* enter a list of JobIds */
if (!get_cmd(ua, _("Enter JobId(s), comma separated, to restore: "))) {
return 0;
}
db_list_sql_query(ua->jcr, ua->db, ua->cmd, prtit, ua, 1, HORZ_LIST);
- done = 0;
+ done = false;
break;
case 4: /* Select the most recent backups */
bstrutime(date, sizeof(date), time(NULL));
return stat;
}
-
+/* Return next JobId from comma separated list */
static int next_jobid_from_list(char **p, uint32_t *JobId)
{
char jobid[30];
- int i;
char *q = *p;
jobid[0] = 0;
- for (i=0; i<(int)sizeof(jobid); i++) {
+ for (int i=0; i<(int)sizeof(jobid); i++) {
if (*q == ',' || *q == 0) {
q++;
break;
{
JOBIDS *ji = (JOBIDS *)ctx;
+ /* Concatenate a JobId if it does not exceed array size */
if (strlen(ji->JobIds)+strlen(row[0])+2 < sizeof(ji->JobIds)) {
if (ji->JobIds[0] != 0) {
strcat(ji->JobIds, ",");
}
strcat(ji->JobIds, row[0]);
}
-
return 0;
}
*/
static void print_name_list(UAContext *ua, NAME_LIST *name_list)
{
- int i;
-
- for (i=0; i < name_list->num_ids; i++) {
+ for (int i=0; i < name_list->num_ids; i++) {
bsendmsg(ua, "%s\n", name_list->name[i]);
}
}
*/
static void free_name_list(NAME_LIST *name_list)
{
- int i;
-
- for (i=0; i < name_list->num_ids; i++) {
+ for (int i=0; i < name_list->num_ids; i++) {
free(name_list->name[i]);
}
if (name_list->name) {
free_jcr(jcr);
return 0;
}
+
+ /* Run without prompting? */
+ if (find_arg(ua, _("yes")) > 0) {
+ Dmsg1(200, "Calling run_job job=%x\n", jcr->job);
+ run_job(jcr);
+ bsendmsg(ua, _("Run command submitted.\n"));
+ return 1;
+ }
+
if (!get_cmd(ua, _("OK to run? (yes/mod/no): "))) {
free_jcr(jcr);
return 0; /* do not run */
free_jcr(jcr);
return 0; /* error do no run Job */
}
+
if (strncasecmp(ua->cmd, _("yes"), strlen(ua->cmd)) == 0) {
Dmsg1(200, "Calling run_job job=%x\n", jcr->job);
run_job(jcr);
*/
int find_arg_keyword(UAContext *ua, char **list)
{
- int i, j;
- for (i=1; i<ua->argc; i++) {
- for(j=0; list[j]; j++) {
+ for (int i=1; i<ua->argc; i++) {
+ for(int j=0; list[j]; j++) {
if (strcasecmp(_(list[j]), ua->argk[i]) == 0) {
return j;
}
return -1;
}
-/*
- * Given a single keyword, find it in the argument list.
- * Returns: -1 if not found
- * list index (base 0) on success
- */
int find_arg(UAContext *ua, char *keyword)
{
for (int i=1; i<ua->argc; i++) {
return -1;
}
+/*
+ * Given a single keyword, find it in the argument list, but
+ * it must have a value
+ * Returns: -1 if not found or no value
+ * list index (base 0) on success
+ */
int find_arg_with_value(UAContext *ua, char *keyword)
{
for (int i=1; i<ua->argc; i++) {
return -1;
}
-
-
/*
* Given a list of keywords, prompt the user
* to choose one.
while (!ua->quit) {
stat = bnet_recv(ua->UA_sock);
if (stat >= 0) {
- ua->cmd = check_pool_memory_size(ua->cmd, ua->UA_sock->msglen+1);
- bstrncpy(ua->cmd, ua->UA_sock->msg, ua->UA_sock->msglen+1);
+ pm_strcpy(&ua->cmd, ua->UA_sock->msg);
parse_ua_args(ua);
if (ua->argc > 0 && ua->argk[0][0] == '.') {
do_a_dot_command(ua, ua->cmd);
static char jobcmd[] = "JobId=%d Job=%127s SDid=%d SDtime=%d Authorization=%100s";
static char storaddr[] = "storage address=%s port=%d ssl=%d\n";
static char sessioncmd[] = "session %127s %ld %ld %ld %ld %ld %ld\n";
-static char restorecmd[] = "restore replace=%c where=%s\n";
-static char restorecmd1[] = "restore replace=%c where=\n";
+static char restorecmd[] = "restore replace=%c prelinks=%d where=%s\n";
+static char restorecmd1[] = "restore replace=%c prelinks=%d where=\n";
static char verifycmd[] = "verify level=%30s\n";
static char estimatecmd[] = "estimate listing=%d\n";
BSOCK *dir = jcr->dir_bsock;
BSOCK *sd = jcr->store_bsock;
POOLMEM *where;
+ int prefix_links;
char replace;
char ed1[50], ed2[50];
where = get_memory(dir->msglen+1);
*where = 0;
- if (sscanf(dir->msg, restorecmd, &replace, where) != 2) {
- if (sscanf(dir->msg, restorecmd1, &replace) != 1) {
+ if (sscanf(dir->msg, restorecmd, &replace, &prefix_links, where) != 3) {
+ if (sscanf(dir->msg, restorecmd1, &replace, &prefix_links) != 2) {
pm_strcpy(&jcr->errmsg, dir->msg);
Jmsg(jcr, M_FATAL, 0, _("Bad replace command. CMD=%s\n"), jcr->errmsg);
return 0;
jcr->where = bstrdup(where);
free_pool_memory(where);
jcr->replace = replace;
+ jcr->prefix_links = prefix_links;
bnet_fsend(dir, OKrestore);
Dmsg1(110, "bfiled>dird: %s", dir->msg);
* Definition of the find_files packet passed as the
* first argument to the find_files callback subroutine.
*/
-typedef struct s_ff {
+struct FF_PKT {
char *fname; /* filename */
char *link; /* link if file linked */
POOLMEM *sys_fname; /* system filename */
struct stat statp; /* stat packet */
- uint32_t FileIndex; /* FileIndex of this file */
- uint32_t LinkFI; /* FileIndex of main hard linked file */
- struct f_link *linked; /* Set if we are hard linked */
+ int32_t FileIndex; /* FileIndex of this file */
+ int32_t LinkFI; /* FileIndex of main hard linked file */
+ struct f_link *linked; /* Set if this file is hard linked */
int type; /* FT_ type from above */
uint32_t flags; /* control flags */
int ff_errno; /* errno */
struct s_excluded_file *excluded_files_list;
struct s_excluded_file *excluded_paths_list;
+ /* List of all hard linked files found */
struct f_link *linklist; /* hard linked files */
-} FF_PKT;
+};
#include "protos.h"
if (prefixed) {
for (p=fname; *p && *p != ' '; p++) {
switch (*p) {
- case 'a': /* alway replace */
- case '0': /* no option */
- break;
- case 'f':
- inc->options |= FO_MULTIFS;
- break;
- case 'h': /* no recursion */
- inc->options |= FO_NO_RECURSION;
- break;
- case 'M': /* MD5 */
- inc->options |= FO_MD5;
- break;
- case 'n':
- inc->options |= FO_NOREPLACE;
- break;
- case 'p': /* use portable data format */
- inc->options |= FO_PORTABLE;
- break;
- case 'r': /* read fifo */
- inc->options |= FO_READFIFO;
- break;
- case 'S':
- inc->options |= FO_SHA1;
- break;
- case 's':
- inc->options |= FO_SPARSE;
- break;
- case 'V': /* verify options */
- /* Copy Verify Options */
- for (j=0; *p && *p != ':'; p++) {
- inc->VerifyOpts[j] = *p;
- if (j < (int)sizeof(inc->VerifyOpts) - 1) {
- j++;
- }
+ case 'a': /* alway replace */
+ case '0': /* no option */
+ break;
+ case 'f':
+ inc->options |= FO_MULTIFS;
+ break;
+ case 'h': /* no recursion */
+ inc->options |= FO_NO_RECURSION;
+ break;
+ case 'M': /* MD5 */
+ inc->options |= FO_MD5;
+ break;
+ case 'n':
+ inc->options |= FO_NOREPLACE;
+ break;
+ case 'p': /* use portable data format */
+ inc->options |= FO_PORTABLE;
+ break;
+ case 'r': /* read fifo */
+ inc->options |= FO_READFIFO;
+ break;
+ case 'S':
+ inc->options |= FO_SHA1;
+ break;
+ case 's':
+ inc->options |= FO_SPARSE;
+ break;
+ case 'V': /* verify options */
+ /* Copy Verify Options */
+ for (j=0; *p && *p != ':'; p++) {
+ inc->VerifyOpts[j] = *p;
+ if (j < (int)sizeof(inc->VerifyOpts) - 1) {
+ j++;
}
- inc->VerifyOpts[j] = 0;
- break;
- case 'w':
- inc->options |= FO_IF_NEWER;
- break;
- case 'Z': /* gzip compression */
- inc->options |= FO_GZIP;
- inc->level = *++p - '0';
- Dmsg1(200, "Compression level=%d\n", inc->level);
- break;
- default:
- Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p);
- break;
+ }
+ inc->VerifyOpts[j] = 0;
+ break;
+ case 'w':
+ inc->options |= FO_IF_NEWER;
+ break;
+ case 'Z': /* gzip compression */
+ inc->options |= FO_GZIP;
+ inc->level = *++p - '0';
+ Dmsg1(200, "Compression level=%d\n", inc->level);
+ break;
+ default:
+ Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p);
+ break;
}
}
/* Skip past space(s) */
*/
+#ifndef __MEM_POOL_H_
+#define __MEM_POOL_H_
+
+
#ifdef SMARTALLOC
#define get_pool_memory(pool) sm_get_pool_memory(__FILE__, __LINE__, pool)
#define PM_MESSAGE 3 /* daemon message */
#define PM_EMSG 4 /* error message */
#define PM_MAX PM_EMSG /* Number of types */
+
+#endif
struct JCR;
/* attr.c */
-ATTR *new_attr();
-void free_attr(ATTR *attr);
-int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr);
-void build_attr_output_fnames(JCR *jcr, ATTR *attr);
-void print_ls_output(JCR *jcr, ATTR *attr);
+ATTR *new_attr();
+void free_attr(ATTR *attr);
+int unpack_attributes_record(JCR *jcr, int32_t stream, char *rec, ATTR *attr);
+void build_attr_output_fnames(JCR *jcr, ATTR *attr);
+void print_ls_output(JCR *jcr, ATTR *attr);
/* base64.c */
-void base64_init (void);
-int to_base64 (intmax_t value, char *where);
-int from_base64 (intmax_t *value, char *where);
-int bin_to_base64 (char *buf, char *bin, int len);
+void base64_init (void);
+int to_base64 (intmax_t value, char *where);
+int from_base64 (intmax_t *value, char *where);
+int bin_to_base64 (char *buf, char *bin, int len);
/* bsys.c */
-char *bstrncpy (char *dest, const char *src, int maxlen);
-char *bstrncat (char *dest, const char *src, int maxlen);
-void *b_malloc (char *file, int line, size_t size);
+char *bstrncpy (char *dest, const char *src, int maxlen);
+char *bstrncat (char *dest, const char *src, int maxlen);
+void *b_malloc (char *file, int line, size_t size);
#ifndef DEBUG
-void *bmalloc (size_t size);
+void *bmalloc (size_t size);
#endif
-void *brealloc (void *buf, size_t size);
-void *bcalloc (size_t size1, size_t size2);
-int bsnprintf (char *str, size_t size, const char *format, ...);
-int bvsnprintf (char *str, size_t size, const char *format, va_list ap);
-int pool_sprintf (char *pool_buf, char *fmt, ...);
-void create_pid_file (char *dir, char *progname, int port);
-int delete_pid_file (char *dir, char *progname, int port);
-void drop (char *uid, char *gid);
-int bmicrosleep (time_t sec, long msec);
-char *bfgets (char *s, int size, FILE *fd);
+void *brealloc (void *buf, size_t size);
+void *bcalloc (size_t size1, size_t size2);
+int bsnprintf (char *str, size_t size, const char *format, ...);
+int bvsnprintf (char *str, size_t size, const char *format, va_list ap);
+int pool_sprintf (char *pool_buf, char *fmt, ...);
+void create_pid_file (char *dir, char *progname, int port);
+int delete_pid_file (char *dir, char *progname, int port);
+void drop (char *uid, char *gid);
+int bmicrosleep (time_t sec, long msec);
+char *bfgets (char *s, int size, FILE *fd);
#ifndef HAVE_STRTOLL
-long long int strtoll (const char *ptr, char **endptr, int base);
+long long int strtoll (const char *ptr, char **endptr, int base);
#endif
/* bnet.c */
-int32_t bnet_recv (BSOCK *bsock);
-int bnet_send (BSOCK *bsock);
-int bnet_fsend (BSOCK *bs, char *fmt, ...);
-int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
-int bnet_sig (BSOCK *bs, int sig);
-int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
-int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need);
-BSOCK * bnet_connect (JCR *jcr, int retry_interval,
- int max_retry_time, char *name, char *host, char *service,
- int port, int verbose);
-void bnet_close (BSOCK *bsock);
-BSOCK * init_bsock (JCR *jcr, int sockfd, char *who, char *ip, int port);
-BSOCK * dup_bsock (BSOCK *bsock);
-void term_bsock (BSOCK *bsock);
-char * bnet_strerror (BSOCK *bsock);
-char * bnet_sig_to_ascii (BSOCK *bsock);
-int bnet_wait_data (BSOCK *bsock, int sec);
-int bnet_wait_data_intr (BSOCK *bsock, int sec);
-int bnet_despool (BSOCK *bsock);
-int is_bnet_stop (BSOCK *bsock);
-int is_bnet_error (BSOCK *bsock);
-void bnet_suppress_error_messages(BSOCK *bsock, int flag);
+int32_t bnet_recv (BSOCK *bsock);
+int bnet_send (BSOCK *bsock);
+int bnet_fsend (BSOCK *bs, char *fmt, ...);
+int bnet_set_buffer_size (BSOCK *bs, uint32_t size, int rw);
+int bnet_sig (BSOCK *bs, int sig);
+int bnet_ssl_server (BSOCK *bsock, char *password, int ssl_need, int ssl_has);
+int bnet_ssl_client (BSOCK *bsock, char *password, int ssl_need);
+BSOCK * bnet_connect (JCR *jcr, int retry_interval,
+ int max_retry_time, char *name, char *host, char *service,
+ int port, int verbose);
+void bnet_close (BSOCK *bsock);
+BSOCK * init_bsock (JCR *jcr, int sockfd, char *who, char *ip, int port);
+BSOCK * dup_bsock (BSOCK *bsock);
+void term_bsock (BSOCK *bsock);
+char * bnet_strerror (BSOCK *bsock);
+char * bnet_sig_to_ascii (BSOCK *bsock);
+int bnet_wait_data (BSOCK *bsock, int sec);
+int bnet_wait_data_intr (BSOCK *bsock, int sec);
+int bnet_despool (BSOCK *bsock);
+int is_bnet_stop (BSOCK *bsock);
+int is_bnet_error (BSOCK *bsock);
+void bnet_suppress_error_messages(BSOCK *bsock, int flag);
/* bget_msg.c */
-int bget_msg(BSOCK *sock);
+int bget_msg(BSOCK *sock);
/* bpipe.c */
-BPIPE * open_bpipe(char *prog, int wait, char *mode);
-int close_wpipe(BPIPE *bpipe);
-int close_bpipe(BPIPE *bpipe);
+BPIPE * open_bpipe(char *prog, int wait, char *mode);
+int close_wpipe(BPIPE *bpipe);
+int close_bpipe(BPIPE *bpipe);
/* cram-md5.c */
int cram_md5_get_auth(BSOCK *bs, char *password, int ssl_need);
int cram_md5_auth(BSOCK *bs, char *password, int ssl_need);
void hmac_md5(uint8_t* text, int text_len, uint8_t* key,
- int key_len, uint8_t *hmac);
+ int key_len, uint8_t *hmac);
/* crc32.c */
uint32_t bcrc32(uint8_t *buf, int len);
/* daemon.c */
-void daemon_start ();
+void daemon_start ();
/* edit.c */
-uint64_t str_to_uint64(char *str);
-int64_t str_to_int64(char *str);
-char * edit_uint64_with_commas (uint64_t val, char *buf);
-char * add_commas (char *val, char *buf);
-char * edit_uint64 (uint64_t val, char *buf);
-int duration_to_utime (char *str, utime_t *value);
-int size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
-char *edit_utime (utime_t val, char *buf);
-int is_a_number (const char *num);
-int is_an_integer (const char *n);
+uint64_t str_to_uint64(char *str);
+int64_t str_to_int64(char *str);
+char * edit_uint64_with_commas (uint64_t val, char *buf);
+char * add_commas (char *val, char *buf);
+char * edit_uint64 (uint64_t val, char *buf);
+int duration_to_utime (char *str, utime_t *value);
+int size_to_uint64(char *str, int str_len, uint64_t *rtn_value);
+char *edit_utime (utime_t val, char *buf);
+int is_a_number (const char *num);
+int is_an_integer (const char *n);
/* lex.c */
-LEX * lex_close_file (LEX *lf);
-LEX * lex_open_file (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
-int lex_get_char (LEX *lf);
-void lex_unget_char (LEX *lf);
-char * lex_tok_to_str (int token);
-int lex_get_token (LEX *lf, int expect);
+LEX * lex_close_file (LEX *lf);
+LEX * lex_open_file (LEX *lf, char *fname, LEX_ERROR_HANDLER *scan_error);
+int lex_get_char (LEX *lf);
+void lex_unget_char (LEX *lf);
+char * lex_tok_to_str (int token);
+int lex_get_token (LEX *lf, int expect);
/* message.c */
-void my_name_is (int argc, char *argv[], char *name);
-void init_msg (JCR *jcr, MSGS *msg);
-void term_msg (void);
-void close_msg (JCR *jcr);
-void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code);
-void rem_msg_dest (MSGS *msg, int dest, int type, char *where);
-void Jmsg (JCR *jcr, int type, int level, char *fmt, ...);
-void dispatch_message (JCR *jcr, int type, int level, char *buf);
-void init_console_msg (char *wd);
-void free_msgs_res (MSGS *msgs);
-int open_spool_file (JCR *jcr, BSOCK *bs);
-int close_spool_file (JCR *jcr, BSOCK *bs);
+void my_name_is (int argc, char *argv[], char *name);
+void init_msg (JCR *jcr, MSGS *msg);
+void term_msg (void);
+void close_msg (JCR *jcr);
+void add_msg_dest (MSGS *msg, int dest, int type, char *where, char *dest_code);
+void rem_msg_dest (MSGS *msg, int dest, int type, char *where);
+void Jmsg (JCR *jcr, int type, int level, char *fmt, ...);
+void dispatch_message (JCR *jcr, int type, int level, char *buf);
+void init_console_msg (char *wd);
+void free_msgs_res (MSGS *msgs);
+int open_spool_file (JCR *jcr, BSOCK *bs);
+int close_spool_file (JCR *jcr, BSOCK *bs);
/* bnet_server.c */
-void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq,
- void *handle_client_request(void *bsock));
-void bnet_server (int port, void handle_client_request(BSOCK *bsock));
-int net_connect (int port);
-BSOCK * bnet_bind (int port);
-BSOCK * bnet_accept (BSOCK *bsock, char *who);
+void bnet_thread_server(char *bind_addr, int port, int max_clients, workq_t *client_wq,
+ void *handle_client_request(void *bsock));
+void bnet_server (int port, void handle_client_request(BSOCK *bsock));
+int net_connect (int port);
+BSOCK * bnet_bind (int port);
+BSOCK * bnet_accept (BSOCK *bsock, char *who);
/* signal.c */
-void init_signals (void terminate(int sig));
-void init_stack_dump (void);
+void init_signals (void terminate(int sig));
+void init_stack_dump (void);
/* scan.c */
-void strip_trailing_junk (char *str);
-void strip_trailing_slashes (char *dir);
-int skip_spaces (char **msg);
-int skip_nonspaces (char **msg);
-int fstrsch (char *a, char *b);
-int parse_args(POOLMEM *cmd, POOLMEM *args, int *argc,
- char **argk, char **argv, int max_args);
-char *next_arg(char **s);
+void strip_trailing_junk (char *str);
+void strip_trailing_slashes (char *dir);
+int skip_spaces (char **msg);
+int skip_nonspaces (char **msg);
+int fstrsch (char *a, char *b);
+int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
+ char **argk, char **argv, int max_args);
+char *next_arg(char **s);
/* util.c */
-int is_buf_zero (char *buf, int len);
-void lcase (char *str);
-void bash_spaces (char *str);
-void unbash_spaces (char *str);
-char * encode_time (time_t time, char *buf);
-char * encode_mode (mode_t mode, char *buf);
-int do_shell_expansion (char *name, int name_len);
-void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen);
-void pm_strcat (POOLMEM **pm, char *str);
-void pm_strcpy (POOLMEM **pm, char *str);
-int run_program (char *prog, int wait, POOLMEM *results);
-char * job_type_to_str (int type);
-char * job_status_to_str (int stat);
-char * job_level_to_str (int level);
-void make_session_key (char *key, char *seed, int mode);
-POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to);
-void set_working_directory(char *wd);
+int is_buf_zero (char *buf, int len);
+void lcase (char *str);
+void bash_spaces (char *str);
+void unbash_spaces (char *str);
+char * encode_time (time_t time, char *buf);
+char * encode_mode (mode_t mode, char *buf);
+int do_shell_expansion (char *name, int name_len);
+void jobstatus_to_ascii (int JobStatus, char *msg, int maxlen);
+void pm_strcat (POOLMEM **pm, char *str);
+void pm_strcpy (POOLMEM **pm, char *str);
+int run_program (char *prog, int wait, POOLMEM *results);
+char * job_type_to_str (int type);
+char * job_status_to_str (int stat);
+char * job_level_to_str (int level);
+void make_session_key (char *key, char *seed, int mode);
+POOLMEM *edit_job_codes(JCR *jcr, char *omsg, char *imsg, char *to);
+void set_working_directory(char *wd);
/* watchdog.c */
* argv[2] =
*/
-int parse_args(POOLMEM *cmd, POOLMEM *args, int *argc,
+int parse_args(POOLMEM *cmd, POOLMEM **args, int *argc,
char **argk, char **argv, int max_args)
{
char *p, *q, *n;
- int len;
- len = strlen(cmd) + 1;
- args = check_pool_memory_size(args, len);
- bstrncpy(args, cmd, len);
- strip_trailing_junk(args);
+ pm_strcpy(args, cmd);
+ strip_trailing_junk(*args);
+ p = *args;
*argc = 0;
- p = args;
/* Pick up all arguments */
while (*argc < max_args) {
n = next_arg(&p);
}
argv[i] = p; /* save ptr to value or NULL */
}
- return 1;
#ifdef xxxx
- for (i=0; i<argc; i++) {
+ for (int i=0; i < *argc; i++) {
Dmsg3(000, "Arg %d: kw=%s val=%s\n", i, argk[i], argv[i]?argv[i]:"NULL");
}
#endif
+ return 1;
}
* file. 1. for the Attributes, 2. for the file data if any,
* and 3. for the MD5 if any.
*/
- jcr->VolFirstIndex = 0;
+ jcr->VolFirstIndex = jcr->VolLastIndex = 0;
jcr->run_time = time(NULL); /* start counting time for rates */
for (last_file_index = 0; ok && !job_canceled(jcr); ) {
}
if (file_index != last_file_index) {
jcr->JobFiles = file_index;
- if (jcr->VolFirstIndex == 0) {
- jcr->VolFirstIndex = file_index;
- }
- jcr->VolLastIndex = file_index;
last_file_index = file_index;
}
static BSR *bsr = NULL;
static int extract = FALSE;
static int non_support_data = 0;
-static int non_support_attr = 0;
static long total = 0;
static ATTR *attr;
static char *where;
block->read_len = 0;
block->write_failed = false;
block->block_read = false;
+ block->FirstIndex = block->LastIndex = 0;
}
/*
return 0;
}
- /* Do housekeeping */
+ /* We successfully wrote the block, now do housekeeping */
dev->VolCatInfo.VolCatBytes += block->binbuf;
dev->VolCatInfo.VolCatBlocks++;
jcr->EndBlock = (uint32_t)dev->file_addr;
jcr->EndFile = (uint32_t)(dev->file_addr >> 32);
}
+ if (jcr->VolFirstIndex == 0 && block->FirstIndex > 0) {
+ jcr->VolFirstIndex = block->FirstIndex;
+ }
+ if (block->LastIndex > 0) {
+ jcr->VolLastIndex = block->LastIndex;
+ }
jcr->WroteVol = true;
Dmsg2(190, "write_block: wrote block %d bytes=%d\n", dev->block_num,
}
dev->state &= ~(ST_EOF|ST_SHORT); /* clear EOF and short block */
- dev->block_num++;
dev->VolCatInfo.VolCatReads++;
dev->VolCatInfo.VolCatRBytes += block->read_len;
+ dev->VolCatInfo.VolCatBytes += block->block_len;
+ dev->VolCatInfo.VolCatBlocks++;
+ dev->file_addr += block->block_len;
+ dev->EndBlock = dev->block_num;
+ dev->EndFile = dev->file;
+ dev->block_num++;
+ block->BlockNumber++;
+
+ /* Update jcr values */
+ if (dev->state & ST_TAPE) {
+ jcr->EndBlock = dev->EndBlock;
+ jcr->EndFile = dev->EndFile;
+ } else {
+ jcr->EndBlock = (uint32_t)dev->file_addr;
+ jcr->EndFile = (uint32_t)(dev->file_addr >> 32);
+ }
+
/*
* If we read a short block on disk,
* seek to beginning of next block. This saves us
int BlockVer; /* block version 1 or 2 */
bool write_failed; /* set if write failed */
bool block_read; /* set when block read */
+ int32_t FirstIndex; /* first index this block */
+ int32_t LastIndex; /* last index this block */
char *bufp; /* pointer into buffer */
POOLMEM *buf; /* actual data buffer */
};
case VOL_LABEL:
unser_volume_label(dev, rec);
/* Check Pool info */
- strcpy(pr.Name, dev->VolHdr.PoolName);
- strcpy(pr.PoolType, dev->VolHdr.PoolType);
+ bstrncpy(pr.Name, dev->VolHdr.PoolName, sizeof(pr.Name));
+ bstrncpy(pr.PoolType, dev->VolHdr.PoolType, sizeof(pr.PoolType));
if (db_get_pool_record(bjcr, db, &pr)) {
if (verbose) {
Pmsg1(000, _("Pool record for %s found in DB.\n"), pr.Name);
/* Check Media Info */
memset(&mr, 0, sizeof(mr));
- strcpy(mr.VolumeName, dev->VolHdr.VolName);
+ bstrncpy(mr.VolumeName, dev->VolHdr.VolName, sizeof(mr.VolumeName));
mr.PoolId = pr.PoolId;
if (db_get_media_record(bjcr, db, &mr)) {
if (verbose) {
Pmsg1(000, _("VOL_LABEL: Media record not found for Volume: %s\n"),
mr.VolumeName);
}
- strcpy(mr.MediaType, dev->VolHdr.MediaType);
+ bstrncpy(mr.MediaType, dev->VolHdr.MediaType, sizeof(mr.MediaType));
create_media_record(db, &mr, &dev->VolHdr);
}
if (strcmp(mr.MediaType, dev->VolHdr.MediaType) != 0) {
return;
}
+ mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
+ if (!mjcr) {
+ if (mr.VolJobs > 0) {
+ Pmsg2(000, _("Could not find Job for SessId=%d SessTime=%d record.\n"),
+ rec->VolSessionId, rec->VolSessionTime);
+ } else {
+ ignored_msgs++;
+ }
+ return;
+ }
+ if (mjcr->VolFirstIndex == 0) {
+ mjcr->VolFirstIndex = block->FirstIndex;
+ }
/* File Attributes stream */
switch (rec->Stream) {
build_attr_output_fnames(bjcr, attr);
print_ls_output(bjcr, attr);
}
- mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
- if (!mjcr) {
- if (mr.VolJobs > 0) {
- Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Attributes record.\n"),
- rec->VolSessionId, rec->VolSessionTime);
- } else {
- ignored_msgs++;
- }
- return;
- }
fr.JobId = mjcr->JobId;
fr.FileId = 0;
if (db_get_file_attributes_record(bjcr, db, attr->fname, &fr)) {
case STREAM_WIN32_DATA:
case STREAM_FILE_DATA:
case STREAM_SPARSE_DATA:
- mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
- if (!mjcr) {
- if (mr.VolJobs > 0) {
- Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for File Data record.\n"),
- rec->VolSessionId, rec->VolSessionTime);
- } else {
- ignored_msgs++;
- }
- return;
- }
mjcr->JobBytes += rec->data_len;
if (rec->Stream == STREAM_SPARSE_DATA) {
mjcr->JobBytes -= sizeof(uint64_t);
break;
case STREAM_GZIP_DATA:
- mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
- if (!mjcr) {
- if (mr.VolJobs > 0) {
- Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for GZIP Data record.\n"),
- rec->VolSessionId, rec->VolSessionTime);
- } else {
- ignored_msgs++;
- }
- return;
- }
mjcr->JobBytes += rec->data_len; /* No correct, we should expand it */
free_jcr(mjcr); /* done using JCR */
break;
case STREAM_SPARSE_GZIP_DATA:
- mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
- if (!mjcr) {
- if (mr.VolJobs > 0) {
- Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Sparse GZIP Data record.\n"),
- rec->VolSessionId, rec->VolSessionTime);
- } else {
- ignored_msgs++;
- }
- return;
- }
mjcr->JobBytes += rec->data_len - sizeof(uint64_t); /* No correct, we should expand it */
free_jcr(mjcr); /* done using JCR */
break;
/* Win32 GZIP stream */
case STREAM_WIN32_GZIP_DATA:
- mjcr = get_jcr_by_session(rec->VolSessionId, rec->VolSessionTime);
- if (!mjcr) {
- if (mr.VolJobs > 0) {
- Pmsg2(000, _("Could not find Job SessId=%d SessTime=%d for Win32 GZIP Data record.\n"),
- rec->VolSessionId, rec->VolSessionTime);
- } else {
- ignored_msgs++;
- }
- return;
- }
mjcr->JobBytes += rec->data_len;
free_jcr(mjcr); /* done using JCR */
break;
void create_session_label(JCR *jcr, DEV_RECORD *rec, int label)
{
ser_declare;
- struct date_time dt;
rec->sync = 1; /* wait for completion */
rec->VolSessionId = jcr->VolSessionId;
ser_uint32(jcr->JobId);
- if (BaculaTapeVersion >= 11) {
- ser_btime(get_current_btime());
- ser_float64(0);
- } else {
- /* OLD WAY DEPRECATED */
- get_current_time(&dt);
- ser_float64(dt.julian_day_number);
- ser_float64(dt.julian_day_fraction);
- }
+ /* Changed in VerNum 11 */
+ ser_btime(get_current_btime());
+ ser_float64(0);
ser_string(jcr->pool_name);
ser_string(jcr->pool_type);
ser_string(jcr->fileset_name);
ser_uint32(jcr->JobType);
ser_uint32(jcr->JobLevel);
- if (BaculaTapeVersion >= 11) {
- ser_string(jcr->fileset_md5);
- }
+ /* Added in VerNum 11 */
+ ser_string(jcr->fileset_md5);
if (label == EOS_LABEL) {
ser_uint32(jcr->JobFiles);
rec = new_record();
Dmsg1(90, "session_label record=%x\n", rec);
switch (label) {
- case SOS_LABEL:
- if (dev->state & ST_TAPE) {
- jcr->StartBlock = dev->block_num;
- jcr->StartFile = dev->file;
- } else {
- jcr->StartBlock = (uint32_t)dev->file_addr;
- jcr->StartFile = (uint32_t)(dev->file_addr >> 32);
- }
- break;
- case EOS_LABEL:
- if (dev->state & ST_TAPE) {
- jcr->EndBlock = dev->EndBlock;
- jcr->EndFile = dev->EndFile;
- } else {
- jcr->EndBlock = (uint32_t)dev->file_addr;
- jcr->EndFile = (uint32_t)(dev->file_addr >> 32);
- }
- break;
- default:
- Jmsg1(jcr, M_ABORT, 0, _("Bad session label = %d\n"), label);
- break;
+ case SOS_LABEL:
+ if (dev->state & ST_TAPE) {
+ jcr->StartBlock = dev->block_num;
+ jcr->StartFile = dev->file;
+ } else {
+ jcr->StartBlock = (uint32_t)dev->file_addr;
+ jcr->StartFile = (uint32_t)(dev->file_addr >> 32);
+ }
+ break;
+ case EOS_LABEL:
+ if (dev->state & ST_TAPE) {
+ jcr->EndBlock = dev->EndBlock;
+ jcr->EndFile = dev->EndFile;
+ } else {
+ jcr->EndBlock = (uint32_t)dev->file_addr;
+ jcr->EndFile = (uint32_t)(dev->file_addr >> 32);
+ }
+ break;
+ default:
+ Jmsg1(jcr, M_ABORT, 0, _("Bad session label = %d\n"), label);
+ break;
}
create_session_label(jcr, rec, label);
rec->FileIndex = label;
dev->state &= ~(ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
- jcr->VolFirstIndex = jcr->JobFiles; /* first update of Vol FileIndex */
for ( ;; ) {
int vol_label_status;
autochanger = autoload_device(jcr, dev, 1, NULL);
if (remlen >= WRITE_RECHDR_LENGTH) {
ser_begin(block->bufp, WRITE_RECHDR_LENGTH);
if (BLOCK_VER == 1) {
- ser_uint32(rec->VolSessionId);
- ser_uint32(rec->VolSessionTime);
+ ser_uint32(rec->VolSessionId);
+ ser_uint32(rec->VolSessionTime);
} else {
block->VolSessionId = rec->VolSessionId;
block->VolSessionTime = rec->VolSessionTime;
block->binbuf += WRITE_RECHDR_LENGTH;
remlen -= WRITE_RECHDR_LENGTH;
rec->remainder = rec->data_len;
+ if (rec->FileIndex > 0) {
+ /* If data record, update what we have in this block */
+ if (block->FirstIndex == 0) {
+ block->FirstIndex = rec->FileIndex;
+ }
+ block->LastIndex = rec->FileIndex;
+ }
} else {
rec->remainder = rec->data_len + WRITE_RECHDR_LENGTH;
return 0;
*/
ser_begin(block->bufp, WRITE_RECHDR_LENGTH);
if (BLOCK_VER == 1) {
- ser_uint32(rec->VolSessionId);
- ser_uint32(rec->VolSessionTime);
+ ser_uint32(rec->VolSessionId);
+ ser_uint32(rec->VolSessionTime);
} else {
block->VolSessionId = rec->VolSessionId;
block->VolSessionTime = rec->VolSessionTime;
block->bufp += WRITE_RECHDR_LENGTH;
block->binbuf += WRITE_RECHDR_LENGTH;
remlen -= WRITE_RECHDR_LENGTH;
+ if (rec->FileIndex > 0) {
+ /* If data record, update what we have in this block */
+ if (block->FirstIndex == 0) {
+ block->FirstIndex = rec->FileIndex;
+ }
+ block->LastIndex = rec->FileIndex;
+ }
}
if (remlen == 0) {
return 0; /* partial transfer */
unser_begin(block->bufp, WRITE_RECHDR_LENGTH);
if (block->BlockVer == 1) {
- unser_uint32(VolSessionId);
- unser_uint32(VolSessionTime);
+ unser_uint32(VolSessionId);
+ unser_uint32(VolSessionTime);
} else {
VolSessionId = block->VolSessionId;
VolSessionTime = block->VolSessionTime;
rec->VolSessionId = VolSessionId;
rec->VolSessionTime = VolSessionTime;
rec->FileIndex = FileIndex;
+ if (FileIndex > 0) {
+ if (block->FirstIndex == 0) {
+ block->FirstIndex = FileIndex;
+ }
+ block->LastIndex = FileIndex;
+ }
- Dmsg6(100, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n\
-remlen=%d data_len=%d\n",
+ Dmsg6(100, "rd_rec_blk() got FI=%s SessId=%d Strm=%s len=%u\n"
+ "remlen=%d data_len=%d\n",
FI_to_ascii(rec->FileIndex), rec->VolSessionId,
stream_to_ascii(rec->Stream, rec->FileIndex), data_bytes, remlen,
rec->data_len);
/* */
#define VERSION "1.31"
#define VSTRING "1"
-#define BDATE "26 Jun 2003"
-#define LSMDATE "26Jun03"
+#define BDATE "02 Jul 2003"
+#define LSMDATE "02Jul03"
/* Debug flags */
#define DEBUG 1