From: Robert Nelson Date: Wed, 26 Jul 2006 01:36:23 +0000 (+0000) Subject: Strip pathname portion off all message routines that print filename:line. X-Git-Tag: Release-2.0.0~724 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=251f41238a447899fca9c0814c2ecf314782e145;p=bacula%2Fbacula Strip pathname portion off all message routines that print filename:line. Print additional messages show the elapsed time and transfer rate for the spool portion of a spooled backup job and also for the tape write portion. Add DriveType directive to the Director's Include Option FileSet resource. Allowed values are: fixed, removable, cdrom, and remote. There is only an implementation for Windows because it is the only platform that has the concept of drives. Adds EnhancedWild directive to the Director's Include Option FileSet resource. Allowed values are: yes and no. When EnhancedWild is enabled then the processing of the Wild, WildDir and WildFile is changed in the following ways. Patterns conform to Posix \ is not a special character in character classification [] To match a - it must be the first or last character To match a ] it must be the first character fnmatch option FNM_FILE_NAME is specified * doesn't match a / so it won't match multiple directory levels in a path Relative WildFile patterns (ones without a leading /) match against the filename portion This in combination with the FNM_FILE_NAME fnmatch() flag makes directives such as WildFile = abc*.def work as expected. Adds support for the shell's feature of brace expansion. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3178 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index e7ba378dd4..59cb3873c3 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -663,6 +663,15 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm for (j=0; jnum_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; kregex.size(); k++) { sendit(sock, " R %s\n", fo->regex.get(k)); } @@ -681,12 +690,18 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm for (k=0; kwildfile.size(); k++) { sendit(sock, " WF %s\n", fo->wildfile.get(k)); } + for (k=0; kwildbase.size(); k++) { + sendit(sock, " W%c %s\n", enhanced_wild ? 'B' : 'F', fo->wildbase.get(k)); + } for (k=0; kbase.size(); k++) { sendit(sock, " B %s\n", fo->base.get(k)); } for (k=0; kfstype.size(); k++) { sendit(sock, " X %s\n", fo->fstype.get(k)); } + for (k=0; kdrivetype.size(); k++) { + sendit(sock, " XD %s\n", fo->drivetype.get(k)); + } if (fo->reader) { sendit(sock, " D %s\n", fo->reader); } @@ -866,8 +881,10 @@ static void free_incexe(INCEXE *incexe) 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); } diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index f4387202c3..6695df9085 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -372,8 +372,10 @@ struct FOPTS { 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 */ }; diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 6615a39d07..566428ee68 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -274,6 +274,15 @@ static bool send_fileset(JCR *jcr) for (j=0; jnum_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; kregex.size(); k++) { bnet_fsend(fd, "R %s\n", fo->regex.get(k)); } @@ -292,12 +301,18 @@ static bool send_fileset(JCR *jcr) for (k=0; kwildfile.size(); k++) { bnet_fsend(fd, "WF %s\n", fo->wildfile.get(k)); } + for (k=0; kwildbase.size(); k++) { + bnet_fsend(fd, "W%c %s\n", enhanced_wild ? 'B' : 'F', fo->wildbase.get(k)); + } for (k=0; kbase.size(); k++) { bnet_fsend(fd, "B %s\n", fo->base.get(k)); } for (k=0; kfstype.size(); k++) { bnet_fsend(fd, "X %s\n", fo->fstype.get(k)); } + for (k=0; kdrivetype.size(); k++) { + bnet_fsend(fd, "XD %s\n", fo->drivetype.get(k)); + } if (fo->reader) { bnet_fsend(fd, "D %s\n", fo->reader); } diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 3b5e0d8d52..f0b9c144b1 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -37,6 +37,7 @@ static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass); 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); @@ -104,6 +105,8 @@ static RES_ITEM options_items[] = { {"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} }; @@ -128,7 +131,8 @@ enum { INC_KW_ACL, INC_KW_IGNORECASE, INC_KW_HFSPLUS, - INC_KW_NOATIME + INC_KW_NOATIME, + INC_KW_ENHANCEDWILD }; /* @@ -156,6 +160,7 @@ static struct s_kw FS_option_kw[] = { {"ignorecase", INC_KW_IGNORECASE}, {"hfsplussupport", INC_KW_HFSPLUS}, {"noatime", INC_KW_NOATIME}, + {"enhancedwild", INC_KW_ENHANCEDWILD}, {NULL, 0} }; @@ -219,6 +224,8 @@ static struct s_fs_opt FS_options[] = { {"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} }; @@ -488,9 +495,15 @@ static void store_wild(LEX *lc, RES_ITEM *item, int index, int pass) 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)); @@ -529,6 +542,29 @@ static void store_fstype(LEX *lc, RES_ITEM *item, int index, int pass) 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 @@ -657,8 +693,10 @@ static void setup_current_opts(void) 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 *)); diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 450a65578a..ad0843ceb1 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -250,6 +250,10 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr, bool top_level) 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; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 9142c8e818..ee00e1e31e 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -260,8 +260,10 @@ void *handle_client_request(void *dirp) 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); } @@ -285,8 +287,10 @@ void *handle_client_request(void *dirp) 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(); @@ -549,8 +553,10 @@ static findFOPTS *start_options(FF_PKT *ff) 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); } @@ -717,8 +723,14 @@ static void add_fileset(JCR *jcr, const char *item) 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); @@ -729,6 +741,8 @@ static void add_fileset(JCR *jcr, const char *item) 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; } @@ -787,12 +801,18 @@ static bool term_fileset(JCR *jcr) for (k=0; kwildfile.size(); k++) { Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k)); } + for (k=0; kwildbase.size(); k++) { + Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k)); + } for (k=0; kbase.size(); k++) { Dmsg1(400, "B %s\n", (char *)fo->base.get(k)); } for (k=0; kfstype.size(); k++) { Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k)); } + for (k=0; kdrivetype.size(); k++) { + Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k)); + } if (fo->reader) { Dmsg1(400, "D %s\n", fo->reader); } @@ -827,12 +847,18 @@ static bool term_fileset(JCR *jcr) for (k=0; kwildfile.size(); k++) { Dmsg1(400, "WF %s\n", (char *)fo->wildfile.get(k)); } + for (k=0; kwildbase.size(); k++) { + Dmsg1(400, "WB %s\n", (char *)fo->wildbase.get(k)); + } for (k=0; kbase.size(); k++) { Dmsg1(400, "B %s\n", (char *)fo->base.get(k)); } for (k=0; kfstype.size(); k++) { Dmsg1(400, "X %s\n", (char *)fo->fstype.get(k)); } + for (k=0; kdrivetype.size(); k++) { + Dmsg1(400, "XD %s\n", (char *)fo->drivetype.get(k)); + } } for (j=0; jname_list.size(); j++) { Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j)); @@ -940,6 +966,9 @@ static void set_options(findFOPTS *fo, const char *opts) 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'; diff --git a/bacula/src/findlib/Makefile.in b/bacula/src/findlib/Makefile.in index a9e4a4ff76..2a84fc9253 100644 --- a/bacula/src/findlib/Makefile.in +++ b/bacula/src/findlib/Makefile.in @@ -23,9 +23,9 @@ dummy: # 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: diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index 8fde075a35..c8e4e9aeed 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -174,6 +174,7 @@ find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt, bool t 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; jname_list.size(); j++) { @@ -191,9 +192,22 @@ find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt, bool t 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; jopts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); @@ -202,10 +216,14 @@ static bool accept_file(FF_PKT *ff) 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; kwilddir.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); @@ -216,7 +234,7 @@ static bool accept_file(FF_PKT *ff) } } else { for (k=0; kwildfile.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); @@ -225,9 +243,20 @@ static bool accept_file(FF_PKT *ff) return true; /* accept file */ } } + + for (k=0; kwildbase.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; kwild.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); @@ -276,7 +305,8 @@ static bool accept_file(FF_PKT *ff) 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 */ } } @@ -286,18 +316,18 @@ static bool accept_file(FF_PKT *ff) findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); for (j=0; jopts_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; kwild.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; jname_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 */ } diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 31ec519eb9..0217dfc988 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -42,6 +42,7 @@ struct utimbuf { #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" @@ -92,6 +93,7 @@ enum { #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; @@ -135,8 +137,10 @@ struct findFOPTS { 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 */ }; @@ -200,6 +204,7 @@ struct FF_PKT { 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 */ diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index b4e5831f87..152cda924b 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -108,6 +108,34 @@ static int accept_fstype(FF_PKT *ff, void *dummy) { 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... @@ -176,7 +204,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, 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)) { @@ -184,7 +212,29 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, 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); diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h index 0c2837ecbe..ff40dfdc3a 100644 --- a/bacula/src/findlib/protos.h +++ b/bacula/src/findlib/protos.h @@ -70,4 +70,7 @@ int make_path(JCR *jcr, const char *argpath, int mode, /* 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 */ diff --git a/bacula/src/lib/Makefile.in b/bacula/src/lib/Makefile.in index 6225e71eca..827d52f539 100644 --- a/bacula/src/lib/Makefile.in +++ b/bacula/src/lib/Makefile.in @@ -38,7 +38,7 @@ LIBSRCS = alloc.c attr.c base64.c berrno.c bsys.c bget_msg.c \ 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 \ diff --git a/bacula/src/lib/message.c b/bacula/src/lib/message.c index 1bd6f8eb90..44070a79e5 100755 --- a/bacula/src/lib/message.c +++ b/bacula/src/lib/message.c @@ -773,9 +773,14 @@ d_msg(const char *file, int line, int level, const char *fmt,...) /* 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; } @@ -850,7 +855,14 @@ p_msg(const char *file, int line, int level, const char *fmt,...) #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; } @@ -895,7 +907,14 @@ t_msg(const char *file, int line, int level, const char *fmt,...) #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; } @@ -926,6 +945,14 @@ e_msg(const char *file, int line, int type, int level, const char *fmt,...) 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 @@ -937,23 +964,23 @@ e_msg(const char *file, int line, int type, int level, const char *fmt,...) 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); @@ -1087,9 +1114,16 @@ void j_msg(const char *file, int line, JCR *jcr, int type, time_t mtime, const c 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; @@ -1116,7 +1150,15 @@ int m_msg(const char *file, int line, POOLMEM **pool_buf, const char *fmt, ...) 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; @@ -1137,7 +1179,15 @@ int m_msg(const char *file, int line, POOLMEM *&pool_buf, const char *fmt, ...) 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; diff --git a/bacula/src/stored/append.c b/bacula/src/stored/append.c index eeae53420b..b82d023dcc 100644 --- a/bacula/src/stored/append.c +++ b/bacula/src/stored/append.c @@ -43,6 +43,7 @@ bool do_append_data(JCR *jcr) char buf1[100], buf2[100]; DCR *dcr = jcr->dcr; DEVICE *dev; + char ec[50]; if (!dcr) { @@ -240,6 +241,7 @@ bool do_append_data(JCR *jcr) 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"), @@ -249,6 +251,15 @@ bool do_append_data(JCR *jcr) } } + 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); diff --git a/bacula/src/stored/spool.c b/bacula/src/stored/spool.c index 62675c67c2..5923279c02 100644 --- a/bacula/src/stored/spool.c +++ b/bacula/src/stored/spool.c @@ -237,6 +237,8 @@ static bool despool_data(DCR *dcr, bool commit) 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; @@ -256,6 +258,16 @@ static bool despool_data(DCR *dcr, bool commit) } 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 */ diff --git a/bacula/src/tools/Makefile.in b/bacula/src/tools/Makefile.in index 84591abe14..e1677fcc7a 100644 --- a/bacula/src/tools/Makefile.in +++ b/bacula/src/tools/Makefile.in @@ -38,7 +38,7 @@ EXTRAOBJS = @OBJLIST@ 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 @@ -68,6 +68,9 @@ dbcheck: dbcheck.o ../lib/libbac.a ../cats/libsql.a $(DIRCONFOBJS) 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)