X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffindlib%2Ffind.c;h=95ee92e1499b2530444903ca8401edc15df6fef7;hb=f8f848fdb5aace95292d905dc60fe0de45521859;hp=c948bc47ff80427fb6d3f5a4b16ba26da6035b47;hpb=2f54e36537e67addb3156d28eed881cd6343afae;p=bacula%2Fbacula diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index c948bc47ff..95ee92e149 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -10,22 +10,17 @@ * Version $Id$ */ /* - Copyright (C) 2000-2005 Kern Sibbald + Copyright (C) 2000-2006 Kern Sibbald This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. + modify it under the terms of the GNU General Public License + version 2 as amended with additional clauses defined in the + file LICENSE in the main source directory. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program; if not, write to the Free - Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, - MA 02111-1307, USA. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + the file LICENSE for additional details. */ @@ -43,13 +38,7 @@ int32_t path_max; /* path name max length */ static int our_callback(FF_PKT *ff, void *hpkt, bool top_level); static bool accept_file(FF_PKT *ff); -/* Fold case in fnmatch() on Win32 */ -#ifdef WIN32 -static const int fnmode = FNM_CASEFOLD; -#else static const int fnmode = 0; -#endif - /* * Initialize the find files "global" variables @@ -94,6 +83,55 @@ set_find_options(FF_PKT *ff, int incremental, time_t save_time) Dmsg0(100, "Leave set_find_options()\n"); } +/* + * For VSS we need to know which windows drives + * are used, because we create a snapshot of all used + * drives before operation + * + * the function returns the number of used drives and + * fills "drives" with up to 26 (A..Z) drive names + * + */ +int +get_win32_driveletters(FF_PKT *ff, char* szDrives) +{ + /* szDrives must be at least 27 bytes long */ + +#if !defined(HAVE_WIN32) + return 0; +#endif + + szDrives[0] = 0; /* make empty */ + int nCount = 0; + + findFILESET *fileset = ff->fileset; + if (fileset) { + int i, j; + + for (i=0; iinclude_list.size(); i++) { + findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); + + /* look through all files and check */ + for (j=0; jname_list.size(); j++) { + char *fname = (char *)incexe->name_list.get(j); + /* fname should match x:/ */ + if (strlen(fname) >= 2 && B_ISALPHA(fname[0]) + && fname[1] == ':') { + + /* always add in uppercase */ + char ch = toupper(fname[0]); + /* if not found in string, add drive letter */ + if (!strchr(szDrives,ch)) { + szDrives[nCount] = ch; + szDrives[nCount+1] = 0; + nCount++; + } + } + } + } + } + return nCount; +} /* * Find all specified files (determined by calls to name_add() @@ -136,12 +174,13 @@ 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++) { Dmsg1(100, "F %s\n", (char *)incexe->name_list.get(j)); - char *fname = (char *)incexe->name_list.get(j); - if (find_one_file(jcr, ff, our_callback, his_pkt, fname, (dev_t)-1, true) == 0) { + ff->top_fname = (char *)incexe->name_list.get(j); + if (find_one_file(jcr, ff, our_callback, his_pkt, ff->top_fname, (dev_t)-1, true) == 0) { return 0; /* error return */ } } @@ -153,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); @@ -164,21 +216,25 @@ 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); - return false; /* reject file */ + return false; /* reject dir */ } - return true; /* accept file */ + return true; /* accept dir */ } } } 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); @@ -187,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); @@ -198,7 +265,6 @@ static bool accept_file(FF_PKT *ff) return true; /* accept file */ } } -#ifndef WIN32 if (S_ISDIR(ff->statp.st_mode)) { for (k=0; kregexdir.size(); k++) { const int nmatch = 30; @@ -232,7 +298,6 @@ static bool accept_file(FF_PKT *ff) return true; /* accept file */ } } -#endif /* * If we have an empty Options clause with exclude, then * exclude the file @@ -240,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 */ } } @@ -250,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 */ } @@ -289,6 +355,7 @@ static int our_callback(FF_PKT *ff, void *hpkt, bool top_level) case FT_NORECURSE: case FT_NOFSCHG: case FT_INVALIDFS: + case FT_INVALIDDT: case FT_NOOPEN: // return ff->callback(ff, hpkt, top_level); @@ -304,6 +371,7 @@ static int our_callback(FF_PKT *ff, void *hpkt, bool top_level) case FT_SPEC: case FT_DIRNOCHG: if (accept_file(ff)) { +// Dmsg2(000, "Accept file %s; reader=%s\n", ff->fname, NPRT(ff->reader)); return ff->callback(ff, hpkt, top_level); } else { Dmsg1(100, "Skip file %s\n", ff->fname);