X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffindlib%2Ffind.c;h=95ee92e1499b2530444903ca8401edc15df6fef7;hb=f8f848fdb5aace95292d905dc60fe0de45521859;hp=ce6d210a73b804daaabba9aa095b7deddb13b8db;hpb=011cb2c216b6de9f656fed85a24ac9d9537c04bf;p=bacula%2Fbacula diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index ce6d210a73..95ee92e149 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -10,11 +10,11 @@ * 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 - version 2 as ammended with additional clauses defined in the + 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, @@ -38,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 @@ -103,7 +97,7 @@ get_win32_driveletters(FF_PKT *ff, char* szDrives) { /* szDrives must be at least 27 bytes long */ -#ifndef WIN32 +#if !defined(HAVE_WIN32) return 0; #endif @@ -121,8 +115,8 @@ get_win32_driveletters(FF_PKT *ff, char* szDrives) for (j=0; jname_list.size(); j++) { char *fname = (char *)incexe->name_list.get(j); /* fname should match x:/ */ - if (strlen (fname) > 3 && B_ISALPHA(fname[0]) - && fname[1] == ':' && fname[2] == '/') { + if (strlen(fname) >= 2 && B_ISALPHA(fname[0]) + && fname[1] == ':') { /* always add in uppercase */ char ch = toupper(fname[0]); @@ -180,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 */ } } @@ -197,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); @@ -208,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); @@ -231,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); @@ -242,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; @@ -276,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 @@ -284,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 */ } } @@ -294,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 */ } @@ -333,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);