for (j=0; j<incexe->num_opts; j++) {
FOPTS *fo = incexe->opts_list[j];
sendit(sock, " O %s\n", fo->opts);
+
+ bool enhanced_wild = false;
+ for (k=0; fo->opts[k]!='\0'; k++) {
+ if (fo->opts[k]=='W') {
+ enhanced_wild = true;
+ break;
+ }
+ }
+
for (k=0; k<fo->regex.size(); k++) {
sendit(sock, " R %s\n", fo->regex.get(k));
}
for (k=0; k<fo->wildfile.size(); k++) {
sendit(sock, " WF %s\n", fo->wildfile.get(k));
}
+ for (k=0; k<fo->wildbase.size(); k++) {
+ sendit(sock, " W%c %s\n", enhanced_wild ? 'B' : 'F', fo->wildbase.get(k));
+ }
for (k=0; k<fo->base.size(); k++) {
sendit(sock, " B %s\n", fo->base.get(k));
}
for (k=0; k<fo->fstype.size(); k++) {
sendit(sock, " X %s\n", fo->fstype.get(k));
}
+ for (k=0; k<fo->drivetype.size(); k++) {
+ sendit(sock, " XD %s\n", fo->drivetype.get(k));
+ }
if (fo->reader) {
sendit(sock, " D %s\n", fo->reader);
}
fopt->wild.destroy();
fopt->wilddir.destroy();
fopt->wildfile.destroy();
+ fopt->wildbase.destroy();
fopt->base.destroy();
fopt->fstype.destroy();
+ fopt->drivetype.destroy();
if (fopt->reader) {
free(fopt->reader);
}
alist wild; /* wild card strings */
alist wilddir; /* wild card strings for directories */
alist wildfile; /* wild card strings for files */
+ alist wildbase; /* wild card strings for files without '/' */
alist base; /* list of base names */
alist fstype; /* file system type limitation */
+ alist drivetype; /* drive type limitation */
char *reader; /* reader program */
char *writer; /* writer program */
};
for (j=0; j<ie->num_opts; j++) {
FOPTS *fo = ie->opts_list[j];
bnet_fsend(fd, "O %s\n", fo->opts);
+
+ bool enhanced_wild = false;
+ for (k=0; fo->opts[k]!='\0'; k++) {
+ if (fo->opts[k]=='W') {
+ enhanced_wild = true;
+ break;
+ }
+ }
+
for (k=0; k<fo->regex.size(); k++) {
bnet_fsend(fd, "R %s\n", fo->regex.get(k));
}
for (k=0; k<fo->wildfile.size(); k++) {
bnet_fsend(fd, "WF %s\n", fo->wildfile.get(k));
}
+ for (k=0; k<fo->wildbase.size(); k++) {
+ bnet_fsend(fd, "W%c %s\n", enhanced_wild ? 'B' : 'F', fo->wildbase.get(k));
+ }
for (k=0; k<fo->base.size(); k++) {
bnet_fsend(fd, "B %s\n", fo->base.get(k));
}
for (k=0; k<fo->fstype.size(); k++) {
bnet_fsend(fd, "X %s\n", fo->fstype.get(k));
}
+ for (k=0; k<fo->drivetype.size(); k++) {
+ bnet_fsend(fd, "XD %s\n", fo->drivetype.get(k));
+ }
if (fo->reader) {
bnet_fsend(fd, "D %s\n", fo->reader);
}
static void store_regex(LEX *lc, RES_ITEM *item, int index, int pass);
static void store_wild(LEX *lc, RES_ITEM *item, int index, int pass);
static void store_fstype(LEX *lc, RES_ITEM *item, int index, int pass);
+static void store_drivetype(LEX *lc, RES_ITEM *item, int index, int pass);
static void store_opts(LEX *lc, RES_ITEM *item, int index, int pass);
static void store_fname(LEX *lc, RES_ITEM *item, int index, int pass);
static void options_res(LEX *lc, RES_ITEM *item, int index, int pass);
{"fstype", store_fstype, {0}, 0, 0, 0},
{"hfsplussupport", store_opts, {0}, 0, 0, 0},
{"noatime", store_opts, {0}, 0, 0, 0},
+ {"enhancedwild", store_opts, {0}, 0, 0, 0},
+ {"drivetype", store_drivetype, {0}, 0, 0, 0},
{NULL, NULL, {0}, 0, 0, 0}
};
INC_KW_ACL,
INC_KW_IGNORECASE,
INC_KW_HFSPLUS,
- INC_KW_NOATIME
+ INC_KW_NOATIME,
+ INC_KW_ENHANCEDWILD
};
/*
{"ignorecase", INC_KW_IGNORECASE},
{"hfsplussupport", INC_KW_HFSPLUS},
{"noatime", INC_KW_NOATIME},
+ {"enhancedwild", INC_KW_ENHANCEDWILD},
{NULL, 0}
};
{"no", INC_KW_HFSPLUS, "0"},
{"yes", INC_KW_NOATIME, "K"},
{"no", INC_KW_NOATIME, "0"},
+ {"yes", INC_KW_ENHANCEDWILD, "K"},
+ {"no", INC_KW_ENHANCEDWILD, "0"},
{NULL, 0, 0}
};
res_incexe.current_opts->wilddir.append(bstrdup(lc->str));
newsize = res_incexe.current_opts->wilddir.size();
} else if (item->code == 2) {
- type = "wildfile";
- res_incexe.current_opts->wildfile.append(bstrdup(lc->str));
- newsize = res_incexe.current_opts->wildfile.size();
+ if (strchr(lc->str, '/') != NULL) {
+ type = "wildfile";
+ res_incexe.current_opts->wildfile.append(bstrdup(lc->str));
+ newsize = res_incexe.current_opts->wildfile.size();
+ } else {
+ type = "wildbase";
+ res_incexe.current_opts->wildbase.append(bstrdup(lc->str));
+ newsize = res_incexe.current_opts->wildbase.size();
+ }
} else {
type = "wild";
res_incexe.current_opts->wild.append(bstrdup(lc->str));
scan_to_eol(lc);
}
+/* Store drivetype info */
+static void store_drivetype(LEX *lc, RES_ITEM *item, int index, int pass)
+{
+ int token;
+
+ token = lex_get_token(lc, T_SKIP_EOL);
+ if (pass == 1) {
+ /* Pickup drivetype string */
+ switch (token) {
+ case T_IDENTIFIER:
+ case T_UNQUOTED_STRING:
+ case T_QUOTED_STRING:
+ res_incexe.current_opts->drivetype.append(bstrdup(lc->str));
+ Dmsg3(900, "set drivetype %p size=%d %s\n",
+ res_incexe.current_opts, res_incexe.current_opts->drivetype.size(), lc->str);
+ break;
+ default:
+ scan_err1(lc, _("Expected an drivetype string, got: %s\n"), lc->str);
+ }
+ }
+ scan_to_eol(lc);
+}
+
/*
* Store Filename info. Note, for minor efficiency reasons, we
* always increase the name buffer by 10 items because we expect
fo->wild.init(1, true);
fo->wilddir.init(1, true);
fo->wildfile.init(1, true);
+ fo->wildbase.init(1, true);
fo->base.init(1, true);
fo->fstype.init(1, true);
+ fo->drivetype.init(1, true);
res_incexe.current_opts = fo;
if (res_incexe.num_opts == 0) {
res_incexe.opts_list = (FOPTS **)malloc(sizeof(FOPTS *));
ff_pkt->fname);
ff_pkt->type = FT_DIREND; /* Backup only the directory entry */
break;
+ case FT_INVALIDDT:
+ Jmsg(jcr, M_INFO, 1, _(" Disallowed drive type. Will not descend into %s\n"),
+ ff_pkt->fname);
+ break;
case FT_DIREND:
Dmsg1(130, "FT_DIREND: %s\n", ff_pkt->link);
break;
fo->wild.destroy();
fo->wilddir.destroy();
fo->wildfile.destroy();
+ fo->wildbase.destroy();
fo->base.destroy();
fo->fstype.destroy();
+ fo->drivetype.destroy();
if (fo->reader) {
free(fo->reader);
}
fo->wild.destroy();
fo->wilddir.destroy();
fo->wildfile.destroy();
+ fo->wildbase.destroy();
fo->base.destroy();
fo->fstype.destroy();
+ fo->drivetype.destroy();
}
incexe->opts_list.destroy();
incexe->name_list.destroy();
fo->wild.init(1, true);
fo->wilddir.init(1, true);
fo->wildfile.init(1, true);
+ fo->wildbase.init(1, true);
fo->base.init(1, true);
fo->fstype.init(1, true);
+ fo->drivetype.init(1, true);
incexe->current_opts = fo;
incexe->opts_list.append(fo);
}
break;
case 'X':
current_opts = start_options(ff);
- current_opts->fstype.append(bstrdup(item));
state = state_options;
+ if (subcode == ' ') {
+ current_opts->fstype.append(bstrdup(item));
+ } else if (subcode == 'D') {
+ current_opts->drivetype.append(bstrdup(item));
+ } else {
+ state = state_error;
+ }
break;
case 'W':
current_opts = start_options(ff);
current_opts->wilddir.append(bstrdup(item));
} else if (subcode == 'F') {
current_opts->wildfile.append(bstrdup(item));
+ } else if (subcode == 'B') {
+ current_opts->wildbase.append(bstrdup(item));
} else {
state = state_error;
}
for (k=0; k<fo->wildfile.size(); k++) {
Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
}
+ for (k=0; k<fo->wildbase.size(); k++) {
+ Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
+ }
for (k=0; k<fo->base.size(); k++) {
Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
}
for (k=0; k<fo->fstype.size(); k++) {
Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
}
+ for (k=0; k<fo->drivetype.size(); k++) {
+ Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
+ }
if (fo->reader) {
Dmsg1(400, "D %s\n", fo->reader);
}
for (k=0; k<fo->wildfile.size(); k++) {
Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k));
}
+ for (k=0; k<fo->wildbase.size(); k++) {
+ Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k));
+ }
for (k=0; k<fo->base.size(); k++) {
Dmsg1(400, "B %s\n", (char *)fo->base.get(k));
}
for (k=0; k<fo->fstype.size(); k++) {
Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k));
}
+ for (k=0; k<fo->drivetype.size(); k++) {
+ Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k));
+ }
}
for (j=0; j<incexe->name_list.size(); j++) {
Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j));
case 'w':
fo->flags |= FO_IF_NEWER;
break;
+ case 'W':
+ fo->flags |= FO_ENHANCEDWILD;
+ break;
case 'Z': /* gzip compression */
fo->flags |= FO_GZIP;
fo->GZIP_level = *++p - '0';
#
LIBSRCS = find.c match.c find_one.c attibs.c create_file.c \
- bfile.c enable_priv.c fstype.c makepath.c save-cwd.c
+ bfile.c drivetype.c enable_priv.c fstype.c makepath.c save-cwd.c
LIBOBJS = find.o match.o find_one.o attribs.o create_file.o \
- bfile.o enable_priv.o fstype.o makepath.o save-cwd.o
+ bfile.o drivetype.o enable_priv.o fstype.o makepath.o save-cwd.o
.SUFFIXES: .c .o
.PHONY:
ff->flags |= fo->flags;
ff->GZIP_level = fo->GZIP_level;
ff->fstypes = fo->fstype;
+ ff->drivetypes = fo->drivetype;
bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts));
}
for (j=0; j<incexe->name_list.size(); j++) {
static bool accept_file(FF_PKT *ff)
{
int i, j, k;
- int ic;
+ int fnm_flags;
findFILESET *fileset = ff->fileset;
findINCEXE *incexe = fileset->incexe;
+ const char *basename;
+ int (*match_func)(const char *pattern, const char *string, int flags);
+
+ if (ff->flags & FO_ENHANCEDWILD) {
+ match_func = enh_fnmatch;
+ if ((basename = strrchr(ff->fname, '/')) != NULL)
+ basename++;
+ else
+ basename = ff->fname;
+ } else {
+ match_func = fnmatch;
+ basename = ff->fname;
+ }
for (j=0; j<incexe->opts_list.size(); j++) {
findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
ff->reader = fo->reader;
ff->writer = fo->writer;
ff->fstypes = fo->fstype;
- ic = (ff->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
+ ff->drivetypes = fo->drivetype;
+
+ fnm_flags = (ff->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
+ fnm_flags |= (ff->flags & FO_ENHANCEDWILD) ? FNM_PATHNAME : 0;
+
if (S_ISDIR(ff->statp.st_mode)) {
for (k=0; k<fo->wilddir.size(); k++) {
- if (fnmatch((char *)fo->wilddir.get(k), ff->fname, fnmode|ic) == 0) {
+ if (match_func((char *)fo->wilddir.get(k), ff->fname, fnmode|fnm_flags) == 0) {
if (ff->flags & FO_EXCLUDE) {
Dmsg2(100, "Exclude wilddir: %s file=%s\n", (char *)fo->wilddir.get(k),
ff->fname);
}
} else {
for (k=0; k<fo->wildfile.size(); k++) {
- if (fnmatch((char *)fo->wildfile.get(k), ff->fname, fnmode|ic) == 0) {
+ if (match_func((char *)fo->wildfile.get(k), ff->fname, fnmode|fnm_flags) == 0) {
if (ff->flags & FO_EXCLUDE) {
Dmsg2(100, "Exclude wildfile: %s file=%s\n", (char *)fo->wildfile.get(k),
ff->fname);
return true; /* accept file */
}
}
+
+ for (k=0; k<fo->wildbase.size(); k++) {
+ if (match_func((char *)fo->wildbase.get(k), basename, fnmode|fnm_flags) == 0) {
+ if (ff->flags & FO_EXCLUDE) {
+ Dmsg2(100, "Exclude wildbase: %s file=%s\n", (char *)fo->wildbase.get(k),
+ basename);
+ return false; /* reject file */
+ }
+ return true; /* accept file */
+ }
+ }
}
for (k=0; k<fo->wild.size(); k++) {
- if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|ic) == 0) {
+ if (match_func((char *)fo->wild.get(k), ff->fname, fnmode|fnm_flags) == 0) {
if (ff->flags & FO_EXCLUDE) {
Dmsg2(100, "Exclude wild: %s file=%s\n", (char *)fo->wild.get(k),
ff->fname);
if (ff->flags & FO_EXCLUDE &&
fo->regex.size() == 0 && fo->wild.size() == 0 &&
fo->regexdir.size() == 0 && fo->wilddir.size() == 0 &&
- fo->regexfile.size() == 0 && fo->wildfile.size() == 0) {
+ fo->regexfile.size() == 0 && fo->wildfile.size() == 0 &&
+ fo->wildbase.size() == 0) {
return false; /* reject file */
}
}
findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
for (j=0; j<incexe->opts_list.size(); j++) {
findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
- ic = (fo->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
+ fnm_flags = (fo->flags & FO_IGNORECASE) ? FNM_CASEFOLD : 0;
for (k=0; k<fo->wild.size(); k++) {
- if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|ic) == 0) {
+ if (fnmatch((char *)fo->wild.get(k), ff->fname, fnmode|fnm_flags) == 0) {
Dmsg1(100, "Reject wild1: %s\n", ff->fname);
return false; /* reject file */
}
}
}
- ic = (incexe->current_opts != NULL && incexe->current_opts->flags & FO_IGNORECASE)
+ fnm_flags = (incexe->current_opts != NULL && incexe->current_opts->flags & FO_IGNORECASE)
? FNM_CASEFOLD : 0;
for (j=0; j<incexe->name_list.size(); j++) {
- if (fnmatch((char *)incexe->name_list.get(j), ff->fname, fnmode|ic) == 0) {
+ if (fnmatch((char *)incexe->name_list.get(j), ff->fname, fnmode|fnm_flags) == 0) {
Dmsg1(100, "Reject wild2: %s\n", ff->fname);
return false; /* reject file */
}
#define MODE_RALL (S_IRUSR|S_IRGRP|S_IROTH)
#include "lib/fnmatch.h"
+#include "lib/enh_fnmatch.h"
#ifndef HAVE_REGEX_H
#include "lib/bregex.h"
#define FO_SHA512 (1<<20) /* Do SHA512 checksum */
#define FO_ENCRYPT (1<<21) /* Encrypt data stream */
#define FO_NOATIME (1<<22) /* Use O_NOATIME to prevent atime change */
+#define FO_ENHANCEDWILD (1<<23) /* Enhanced wild card processing */
struct s_included_file {
struct s_included_file *next;
alist wild; /* wild card strings */
alist wilddir; /* wild card strings for directories */
alist wildfile; /* wild card strings for files */
+ alist wildbase; /* wild card strings for basenames */
alist base; /* list of base names */
alist fstype; /* file system type limitation */
+ alist drivetype; /* drive type limitation */
char *reader; /* reader program */
char *writer; /* writer program */
};
char *reader; /* reader program */
char *writer; /* writer program */
alist fstypes; /* allowed file system types */
+ alist drivetypes; /* allowed drive types */
/* List of all hard linked files found */
struct f_link **linkhash; /* hard linked files */
return accept;
}
+/*
+ * Check to see if we allow the drive type of a file or directory.
+ * If we do not have a list of drive types, we accept anything.
+ */
+static int accept_drivetype(FF_PKT *ff, void *dummy) {
+ int i;
+ char dt[100];
+ bool accept = true;
+
+ if (ff->drivetypes.size()) {
+ accept = false;
+ if (!drivetype(ff->fname, dt, sizeof(dt))) {
+ Dmsg1(50, "Cannot determine drive type for \"%s\"\n", ff->fname);
+ } else {
+ for (i = 0; i < ff->drivetypes.size(); ++i) {
+ if (strcmp(dt, (char *)ff->drivetypes.get(i)) == 0) {
+ Dmsg2(100, "Accepting drive type %s for \"%s\"\n", dt, ff->fname);
+ accept = true;
+ break;
+ }
+ Dmsg3(200, "drive type %s for \"%s\" does not match %s\n", dt,
+ ff->fname, ff->drivetypes.get(i));
+ }
+ }
+ }
+ return accept;
+}
+
/*
* This function determines whether we can use getattrlist()
* It's odd, but we have to use the function to determine that...
restore_times.modtime = ff_pkt->statp.st_mtime;
/*
- * We check for allowed fstypes at top_level and fstype change (below).
+ * We check for allowed fstypes and drivetypes at top_level and fstype change (below).
*/
if (top_level) {
if (!accept_fstype(ff_pkt, NULL)) {
if (ff_pkt->flags & FO_KEEPATIME) {
utime(fname, &restore_times);
}
- Jmsg1(jcr, M_ERROR, 0, _("Top level directory \"%s\" has an unlisted fstype\n"), fname);
+
+ char fs[100];
+
+ if (!fstype(ff_pkt->fname, fs, sizeof(fs))) {
+ bstrncpy(fs, "unknown", sizeof(fs));
+ }
+
+ Jmsg(jcr, M_INFO, 0, _("Top level directory \"%s\" has unlisted fstype \"%s\"\n"), fname, fs);
+ return 1; /* Just ignore this error - or the whole backup is cancelled */
+ }
+ if (!accept_drivetype(ff_pkt, NULL)) {
+ ff_pkt->type = FT_INVALIDDT;
+ if (ff_pkt->flags & FO_KEEPATIME) {
+ utime(fname, &restore_times);
+ }
+
+ char dt[100];
+
+ if (!drivetype(ff_pkt->fname, dt, sizeof(dt))) {
+ bstrncpy(dt, "unknown", sizeof(dt));
+ }
+
+ Jmsg(jcr, M_INFO, 0, _("Top level directory \"%s\" has an unlisted drive type \"%s\"\n"), fname, dt);
return 1; /* Just ignore this error - or the whole backup is cancelled */
}
ff_pkt->volhas_attrlist = volume_has_attrlist(fname);
/* from fstype.c */
bool fstype(const char *fname, char *fs, int fslen);
+/* from drivetype.c */
+bool drivetype(const char *fname, char *fs, int fslen);
+
/* from bfile.c -- see bfile.h */
LIBOBJS = alloc.o attr.o base64.o berrno.o bsys.o bget_msg.o \
bnet.o bnet_server.o runscript.o \
bpipe.o bsnprintf.o btime.o \
- cram-md5.o crc32.o crypto.o daemon.o edit.o fnmatch.o \
+ cram-md5.o crc32.o crypto.o daemon.o edit.o enh_fnmatch.o fnmatch.o \
hmac.o idcache.o jcr.o lex.o alist.o dlist.o \
md5.o message.o mem_pool.o openssl.o parse_conf.o \
queue.o bregex.o \
/* visual studio passes the whole path to the file as well
* which makes for very long lines
*/
- const char *f = strrchr(file, '\\');
- if (f) file = f + 1;
- len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
+ const char *basename;
+
+ if ((basename = strrchr(file, '\\')) == NULL) {
+ basename = file;
+ } else {
+ basename++;
+ }
+ len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, basename, line);
} else {
len = 0;
}
#ifdef FULL_LOCATION
if (level >= 0) {
- len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
+ const char *basename;
+
+ if ((basename = strrchr(file, '\\')) == NULL) {
+ basename = file;
+ } else {
+ basename++;
+ }
+ len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, basename, line);
} else {
len = 0;
}
#ifdef FULL_LOCATION
if (details) {
- len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, file, line);
+ const char *basename;
+
+ if ((basename = strrchr(file, '\\')) == NULL) {
+ basename = file;
+ } else {
+ basename++;
+ }
+ len = bsnprintf(buf, sizeof(buf), "%s: %s:%d ", my_name, basename, line);
} else {
len = 0;
}
va_list arg_ptr;
int len;
+ const char *basename;
+
+ if ((basename = strrchr(file, '\\')) == NULL) {
+ basename = file;
+ } else {
+ basename++;
+ }
+
/*
* Check if we have a message destination defined.
* We always report M_ABORT and M_ERROR_TERM
switch (type) {
case M_ABORT:
len = bsnprintf(buf, sizeof(buf), _("%s: ABORTING due to ERROR in %s:%d\n"),
- my_name, file, line);
+ my_name, basename, line);
break;
case M_ERROR_TERM:
len = bsnprintf(buf, sizeof(buf), _("%s: ERROR TERMINATION at %s:%d\n"),
- my_name, file, line);
+ my_name, basename, line);
break;
case M_FATAL:
if (level == -1) /* skip details */
len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error because: "), my_name);
else
- len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error at %s:%d because:\n"), my_name, file, line);
+ len = bsnprintf(buf, sizeof(buf), _("%s: Fatal Error at %s:%d because:\n"), my_name, basename, line);
break;
case M_ERROR:
if (level == -1) /* skip details */
len = bsnprintf(buf, sizeof(buf), _("%s: ERROR: "), my_name);
else
- len = bsnprintf(buf, sizeof(buf), _("%s: ERROR in %s:%d "), my_name, file, line);
+ len = bsnprintf(buf, sizeof(buf), _("%s: ERROR in %s:%d "), my_name, basename, line);
break;
case M_WARNING:
len = bsnprintf(buf, sizeof(buf), _("%s: Warning: "), my_name);
va_list arg_ptr;
int i, len, maxlen;
POOLMEM *pool_buf;
+ const char *basename;
+
+ if ((basename = strrchr(file, '\\')) == NULL) {
+ basename = file;
+ } else {
+ basename++;
+ }
pool_buf = get_pool_memory(PM_EMSG);
- i = Mmsg(pool_buf, "%s:%d ", file, line);
+ i = Mmsg(pool_buf, "%s:%d ", basename, line);
for (;;) {
maxlen = sizeof_pool_memory(pool_buf) - i - 1;
va_list arg_ptr;
int i, len, maxlen;
- i = sprintf(*pool_buf, "%s:%d ", file, line);
+ const char *basename;
+
+ if ((basename = strrchr(file, '\\')) == NULL) {
+ basename = file;
+ } else {
+ basename++;
+ }
+
+ i = sprintf(*pool_buf, "%s:%d ", basename, line);
for (;;) {
maxlen = sizeof_pool_memory(*pool_buf) - i - 1;
va_list arg_ptr;
int i, len, maxlen;
- i = sprintf(pool_buf, "%s:%d ", file, line);
+ const char *basename;
+
+ if ((basename = strrchr(file, '\\')) == NULL) {
+ basename = file;
+ } else {
+ basename++;
+ }
+
+ i = sprintf(pool_buf, "%s:%d ", basename, line);
for (;;) {
maxlen = sizeof_pool_memory(pool_buf) - i - 1;
char buf1[100], buf2[100];
DCR *dcr = jcr->dcr;
DEVICE *dev;
+ char ec[50];
if (!dcr) {
Dmsg0(650, "Enter bnet_get\n");
}
Dmsg1(650, "End read loop with FD. Stat=%d\n", n);
+
if (is_bnet_error(ds)) {
Dmsg1(350, "Network read error from FD. ERR=%s\n", bnet_strerror(ds));
Jmsg1(jcr, M_FATAL, 0, _("Network error on data channel. ERR=%s\n"),
}
}
+ time_t job_elapsed = time(NULL) - jcr->run_time;
+
+ if (job_elapsed == 0)
+ job_elapsed = 1;
+
+ Jmsg(dcr->jcr, M_INFO, 0, _("Job write elapsed time = %02d:%02d:%02d, Transfer rate = %s bytes/second\n"),
+ job_elapsed / 3600, job_elapsed % 3600 / 60, job_elapsed % 60,
+ edit_uint64_with_commas(jcr->dcr->job_spool_size / job_elapsed, ec));
+
/* Create Job status for end of session label */
set_jcr_job_status(jcr, ok?JS_Terminated:JS_ErrorTerminated);
Dmsg1(800, "read/write block size = %d\n", block->buf_len);
lseek(rdcr->spool_fd, 0, SEEK_SET); /* rewind */
+ time_t despool_start = time(NULL);
+
for ( ; ok; ) {
if (job_canceled(jcr)) {
ok = false;
}
Dmsg3(800, "Write block ok=%d FI=%d LI=%d\n", ok, block->FirstIndex, block->LastIndex);
}
+
+ time_t despool_elapsed = time(NULL) - despool_start;
+
+ if (despool_elapsed == 0)
+ despool_elapsed = 1;
+
+ Jmsg(dcr->jcr, M_INFO, 0, _("Despooling elapsed time = %02d:%02d:%02d, Transfer rate = %s bytes/second\n"),
+ despool_elapsed / 3600, despool_elapsed % 3600 / 60, despool_elapsed % 60,
+ edit_uint64_with_commas(jcr->dcr->job_spool_size / despool_elapsed, ec1));
+
dcr->block = block; /* reset block */
lseek(rdcr->spool_fd, 0, SEEK_SET); /* rewind */
DIRCONFOBJS = ../dird/dird_conf.o ../dird/run_conf.o ../dird/inc_conf.o
NODIRTOOLS = bsmtp
-DIRTOOLS = bsmtp dbcheck fstype testfind testls bregex bwild
+DIRTOOLS = bsmtp dbcheck drivetype fstype testfind testls bregex bwild
TOOLS = $(@DIR_TOOLS@)
INSNODIRTOOLS = bsmtp
fstype: fstype.o ../lib/libbac.a ../findlib/libfind.a
$(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ fstype.o -lfind -lbac -lm $(DLIB) $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
+drivetype: drivetype.o ../lib/libbac.a ../findlib/libfind.a
+ $(CXX) $(LDFLAGS) -L../lib -L../findlib -o $@ drivetype.o -lfind -lbac -lm $(DLIB) $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)
+
testfind: ../findlib/libfind.a ../lib/libbac.a $(FINDOBJS)
$(CXX) -g $(LDFLAGS) -L. -L../lib -L../findlib -o $@ $(FINDOBJS) \
$(DLIB) -lfind -lbac -lm $(LIBS) $(GETTEXT_LIBS) $(OPENSSL_LIBS)