X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Ffindlib%2Ffind.c;h=47d78123766c3be7025026e2502e075968ccf05a;hb=10cfd798ced2d27f61ead2de6fe9b1bcc8e3468d;hp=7e059e4b2281b5dca5c21a909a55f45e3f3f9b97;hpb=e4644888762b76a04efd4511b335f91485671a0d;p=bacula%2Fbacula diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index 7e059e4b22..47d7812376 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -1,29 +1,20 @@ /* - Bacula® - The Network Backup Solution - - Copyright (C) 2000-2008 Free Software Foundation Europe e.V. - - The main author of Bacula is Kern Sibbald, with contributions from - many others, a complete list can be found in the file AUTHORS. - This program is Free Software; you can redistribute it and/or - modify it under the terms of version two of the GNU General Public - License as published by the Free Software Foundation and included - in the file LICENSE. - - 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., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - - Bacula® is a registered trademark of John Walker. - The licensor of Bacula is the Free Software Foundation Europe - (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich, - Switzerland, email:ftf@fsfeurope.org. + Bacula(R) - The Network Backup Solution + + Copyright (C) 2000-2015 Kern Sibbald + + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. + + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. + + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. */ /* * Main routine for finding files on a file system. @@ -34,13 +25,14 @@ * * Kern E. Sibbald, MM * - * Version $Id$ */ #include "bacula.h" #include "find.h" +static const int dbglvl = 450; + int32_t name_max; /* filename max length */ int32_t path_max; /* path name max length */ @@ -49,7 +41,6 @@ int32_t path_max; /* path name max length */ #define bmalloc(x) sm_malloc(__FILE__, __LINE__, x) #endif static int our_callback(JCR *jcr, FF_PKT *ff, bool top_level); -static bool accept_file(FF_PKT *ff); static const int fnmode = 0; @@ -67,18 +58,18 @@ FF_PKT *init_find_files() /* Get system path and filename maximum lengths */ path_max = pathconf(".", _PC_PATH_MAX); - if (path_max < 1024) { - path_max = 1024; + if (path_max < 2048) { + path_max = 2048; } name_max = pathconf(".", _PC_NAME_MAX); - if (name_max < 1024) { - name_max = 1024; + if (name_max < 2048) { + name_max = 2048; } path_max++; /* add for EOS */ name_max++; /* add for EOS */ - Dmsg1(100, "init_find_files ff=%p\n", ff); + Dmsg1(dbglvl, "init_find_files ff=%p\n", ff); return ff; } @@ -90,68 +81,24 @@ FF_PKT *init_find_files() void set_find_options(FF_PKT *ff, int incremental, time_t save_time) { - Dmsg0(100, "Enter set_find_options()\n"); + Dmsg0(dbglvl, "Enter set_find_options()\n"); ff->incremental = incremental; ff->save_time = save_time; - Dmsg0(100, "Leave set_find_options()\n"); + Dmsg0(dbglvl, "Leave set_find_options()\n"); } void set_find_changed_function(FF_PKT *ff, bool check_fct(JCR *jcr, FF_PKT *ff)) { - Dmsg0(100, "Enter set_find_changed_function()\n"); + Dmsg0(dbglvl, "Enter set_find_changed_function()\n"); ff->check_fct = check_fct; } -/* - * 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) +void +set_find_snapshot_function(FF_PKT *ff, + bool convert_path(JCR *jcr, FF_PKT *ff, dlist *filelist, dlistString *node)) { - /* 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; - dlistString *node; - - for (i=0; iinclude_list.size(); i++) { - findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); - - /* look through all files and check */ - foreach_dlist(node, &incexe->name_list) { - char *fname = node->c_str(); - /* 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; + ff->snapshot_convert_fct = convert_path; } /* @@ -163,7 +110,7 @@ get_win32_driveletters(FF_PKT *ff, char* szDrives) */ int find_files(JCR *jcr, FF_PKT *ff, int file_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level), - int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)) + int plugin_save(JCR *jcr, FF_PKT *ff_pkt, bool top_level)) { ff->file_save = file_save; ff->plugin_save = plugin_save; @@ -172,42 +119,99 @@ find_files(JCR *jcr, FF_PKT *ff, int file_save(JCR *jcr, FF_PKT *ff_pkt, bool to findFILESET *fileset = ff->fileset; if (fileset) { int i, j; + /* TODO: We probably need be move the initialization in the fileset loop, + * at this place flags options are "concatenated" accross Include {} blocks + * (not only Options{} blocks inside a Include{}) + */ ff->flags = 0; - ff->VerifyOpts[0] = 'V'; - ff->VerifyOpts[1] = 0; for (i=0; iinclude_list.size(); i++) { findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); fileset->incexe = incexe; + + /* Here, we reset some values between two different Include{} */ + strcpy(ff->VerifyOpts, "V"); + strcpy(ff->AccurateOpts, "Cmcs"); /* mtime+ctime+size by default */ + strcpy(ff->BaseJobOpts, "Jspug5"); /* size+perm+user+group+chk */ + ff->plugin = NULL; + ff->opt_plugin = false; + /* - * By setting all options, we in effect or the global options + * By setting all options, we in effect OR the global options * which is what we want. */ for (j=0; jopts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); + /* TODO options are "simply" reset by Options block that come next + * For example : + * Options { IgnoreCase = yes } + * ATTN: some plugins use AddOptions() that create extra Option block + * Also see accept_file() below that could suffer of the same problem + */ ff->flags |= fo->flags; - ff->GZIP_level = fo->GZIP_level; + /* If the compress option was set in the previous block, overwrite the + * algorithm only if defined + */ + if ((ff->flags & FO_COMPRESS) && fo->Compress_algo != 0) { + ff->Compress_algo = fo->Compress_algo; + ff->Compress_level = fo->Compress_level; + } ff->strip_path = fo->strip_path; ff->fstypes = fo->fstype; ff->drivetypes = fo->drivetype; - bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts)); + if (fo->plugin != NULL) { + ff->plugin = fo->plugin; /* TODO: generate a plugin event ? */ + ff->opt_plugin = true; + } + bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts)); /* TODO: Concat or replace? */ + if (fo->AccurateOpts[0]) { + bstrncpy(ff->AccurateOpts, fo->AccurateOpts, sizeof(ff->AccurateOpts)); + } + if (fo->BaseJobOpts[0]) { + bstrncpy(ff->BaseJobOpts, fo->BaseJobOpts, sizeof(ff->BaseJobOpts)); + } } + Dmsg4(50, "Verify=<%s> Accurate=<%s> BaseJob=<%s> flags=<%lld>\n", + ff->VerifyOpts, ff->AccurateOpts, ff->BaseJobOpts, ff->flags); dlistString *node; foreach_dlist(node, &incexe->name_list) { char *fname = node->c_str(); - Dmsg1(100, "F %s\n", fname); + Dmsg1(dbglvl, "F %s\n", fname); + ff->top_fname = fname; + /* Convert the filename if needed */ + if (ff->snapshot_convert_fct) { + ff->snapshot_convert_fct(jcr, ff, &incexe->name_list, node); + } + if (find_one_file(jcr, ff, our_callback, ff->top_fname, (dev_t)-1, true) == 0) { return 0; /* error return */ } + + if (job_canceled(jcr)) { + return 0; + } } - if (plugin_save) { - foreach_dlist(node, &incexe->plugin_list) { - char *fname = node->c_str(); - Dmsg1(100, "PluginCommand: %s\n", fname); - ff->top_fname = fname; - ff->cmd_plugin = true; - plugin_save(jcr, ff, true); - ff->cmd_plugin = false; + foreach_dlist(node, &incexe->plugin_list) { + char *fname = node->c_str(); + if (!plugin_save) { + Jmsg(jcr, M_FATAL, 0, _("Plugin: \"%s\" not found.\n"), fname); + return 0; + } + Dmsg1(dbglvl, "PluginCommand: %s\n", fname); + ff->top_fname = fname; + ff->cmd_plugin = true; + + /* Make sure that opt plugin is not set + * The current implementation doesn't allow option plugin + * and command plugin to run at the same time + */ + ff->opt_plugin = false; + ff->plugin = NULL; + + plugin_save(jcr, ff, true); + ff->cmd_plugin = false; + if (job_canceled(jcr)) { + return 0; } } } @@ -217,7 +221,7 @@ find_files(JCR *jcr, FF_PKT *ff, int file_save(JCR *jcr, FF_PKT *ff_pkt, bool to /* * Test if the currently selected directory (in ff->fname) is - * explicitly in the Include list or explicitly in the Exclude + * explicitly in the Include list or explicitly in the Exclude * list. */ bool is_in_fileset(FF_PKT *ff) @@ -232,30 +236,28 @@ bool is_in_fileset(FF_PKT *ff) incexe = (findINCEXE *)fileset->include_list.get(i); foreach_dlist(node, &incexe->name_list) { fname = node->c_str(); - Dmsg2(100, "Inc fname=%s ff->fname=%s\n", fname, ff->fname); + Dmsg2(dbglvl, "Inc fname=%s ff->fname=%s\n", fname, ff->fname); if (strcmp(fname, ff->fname) == 0) { return true; } } } -#ifdef xxx for (i=0; iexclude_list.size(); i++) { incexe = (findINCEXE *)fileset->exclude_list.get(i); foreach_dlist(node, &incexe->name_list) { fname = node->c_str(); - Dmsg2(000, "Exc fname=%s ff->fname=%s\n", fname, ff->fname); + Dmsg2(dbglvl, "Exc fname=%s ff->fname=%s\n", fname, ff->fname); if (strcmp(fname, ff->fname) == 0) { return true; } } } -#endif } return false; } -static bool accept_file(FF_PKT *ff) +bool accept_file(FF_PKT *ff) { int i, j, k; int fnm_flags; @@ -264,6 +266,7 @@ static bool accept_file(FF_PKT *ff) const char *basename; int (*match_func)(const char *pattern, const char *string, int flags); + Dmsg1(dbglvl, "enter accept_file: fname=%s\n", ff->fname); if (ff->flags & FO_ENHANCEDWILD) { // match_func = enh_fnmatch; match_func = fnmatch; @@ -279,7 +282,8 @@ static bool accept_file(FF_PKT *ff) for (j = 0; j < incexe->opts_list.size(); j++) { findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); ff->flags = fo->flags; - ff->GZIP_level = fo->GZIP_level; + ff->Compress_algo = fo->Compress_algo; + ff->Compress_level = fo->Compress_level; ff->fstypes = fo->fstype; ff->drivetypes = fo->drivetype; @@ -290,7 +294,7 @@ static bool accept_file(FF_PKT *ff) for (k=0; kwilddir.size(); k++) { 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), + Dmsg2(dbglvl, "Exclude wilddir: %s file=%s\n", (char *)fo->wilddir.get(k), ff->fname); return false; /* reject dir */ } @@ -301,7 +305,7 @@ static bool accept_file(FF_PKT *ff) for (k=0; kwildfile.size(); k++) { 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), + Dmsg2(dbglvl, "Exclude wildfile: %s file=%s\n", (char *)fo->wildfile.get(k), ff->fname); return false; /* reject file */ } @@ -312,7 +316,7 @@ static bool accept_file(FF_PKT *ff) 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), + Dmsg2(dbglvl, "Exclude wildbase: %s file=%s\n", (char *)fo->wildbase.get(k), basename); return false; /* reject file */ } @@ -323,7 +327,7 @@ static bool accept_file(FF_PKT *ff) for (k=0; kwild.size(); k++) { 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), + Dmsg2(dbglvl, "Exclude wild: %s file=%s\n", (char *)fo->wild.get(k), ff->fname); return false; /* reject file */ } @@ -384,7 +388,7 @@ static bool accept_file(FF_PKT *ff) 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|fnm_flags) == 0) { - Dmsg1(100, "Reject wild1: %s\n", ff->fname); + Dmsg1(dbglvl, "Reject wild1: %s\n", ff->fname); return false; /* reject file */ } } @@ -395,7 +399,7 @@ static bool accept_file(FF_PKT *ff) foreach_dlist(node, &incexe->name_list) { char *fname = node->c_str(); if (fnmatch(fname, ff->fname, fnmode|fnm_flags) == 0) { - Dmsg1(100, "Reject wild2: %s\n", ff->fname); + Dmsg1(dbglvl, "Reject wild2: %s\n", ff->fname); return false; /* reject file */ } } @@ -424,7 +428,6 @@ static int our_callback(JCR *jcr, FF_PKT *ff, bool top_level) case FT_INVALIDFS: case FT_INVALIDDT: case FT_NOOPEN: - case FT_REPARSE: // return ff->file_save(jcr, ff, top_level); /* These items can be filtered */ @@ -438,10 +441,12 @@ static int our_callback(JCR *jcr, FF_PKT *ff, bool top_level) case FT_FIFO: case FT_SPEC: case FT_DIRNOCHG: + case FT_REPARSE: + case FT_JUNCTION: if (accept_file(ff)) { return ff->file_save(jcr, ff, top_level); } else { - Dmsg1(100, "Skip file %s\n", ff->fname); + Dmsg1(dbglvl, "Skip file %s\n", ff->fname); return -1; /* ignore this file */ } @@ -468,6 +473,18 @@ term_find_files(FF_PKT *ff) if (ff->link_save) { free_pool_memory(ff->link_save); } + if (ff->ignoredir_fname) { + free_pool_memory(ff->ignoredir_fname); + } + if (ff->snap_fname) { + free_pool_memory(ff->snap_fname); + } + if (ff->snap_top_fname) { + free_pool_memory(ff->snap_top_fname); + } + if (ff->mtab_list) { + delete ff->mtab_list; + } hard_links = term_find_one(ff); free(ff); return hard_links;