From 4e172c4588e87b34cb99a8d6d43360568a52b5ec Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Fri, 30 Apr 2004 10:01:26 +0000 Subject: [PATCH] Start FileSet filtering git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1327 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/baconfig.h | 3 +- bacula/src/filed/backup.c | 8 +- bacula/src/filed/estimate.c | 3 +- bacula/src/filed/verify.c | 6 +- bacula/src/findlib/attribs.c | 2 +- bacula/src/findlib/bfile.h | 2 +- bacula/src/findlib/enable_priv.c | 2 +- bacula/src/findlib/find.c | 225 +++++++++++++++++--------- bacula/src/findlib/find.h | 6 +- bacula/src/findlib/find_one.c | 262 ++++++++++++++++--------------- bacula/src/findlib/match.c | 2 +- bacula/src/findlib/protos.h | 2 +- bacula/src/tools/testfind.c | 4 +- bacula/src/tools/testls.c | 4 +- 14 files changed, 316 insertions(+), 215 deletions(-) diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index e1155c2d2a..009211762b 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -141,7 +141,7 @@ #define FT_REGE 2 /* Regular file but empty */ #define FT_REG 3 /* Regular file */ #define FT_LNK 4 /* Soft Link */ -#define FT_DIR 5 /* Directory */ +#define FT_DIREND 5 /* Directory at end (saved) */ #define FT_SPEC 6 /* Special file -- chr, blk, fifo, sock */ #define FT_NOACCESS 7 /* Not able to access */ #define FT_NOFOLLOW 8 /* Could not follow link */ @@ -154,6 +154,7 @@ #define FT_NOOPEN 15 /* Could not open directory */ #define FT_RAW 16 /* Raw block device */ #define FT_FIFO 17 /* Raw fifo device */ +#define FT_DIRBEGIN 18 /* Directory at beginning (not saved) */ /* Definitions for upper part of type word (see above). */ #define AR_DATA_STREAM (1<<16) /* Data stream id present */ diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 20e3eecd50..0e7a69627d 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -148,7 +148,9 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) case FT_LNK: Dmsg2(130, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; - case FT_DIR: + case FT_DIRBEGIN: + return 1; /* not used */ + case FT_DIREND: Dmsg1(130, "FT_DIR saving: %s\n", ff_pkt->link); break; case FT_SPEC: @@ -214,7 +216,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && ff_pkt->statp.st_size > 0) || ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO || - (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIR)) { + (!is_portable_backup(&ff_pkt->bfd) && ff_pkt->type == FT_DIREND)) { btimer_t *tid; if (ff_pkt->type == FT_FIFO) { tid = start_thread_timer(pthread_self(), 60); @@ -279,7 +281,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) stat = bnet_fsend(sd, "%ld %d %s%c%s%c%s%c%s%c", jcr->JobFiles, ff_pkt->type, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0, attribsEx, 0); - } else if (ff_pkt->type == FT_DIR) { + } else if (ff_pkt->type == FT_DIREND) { /* Here link is the canonical filename (i.e. with trailing slash) */ stat = bnet_fsend(sd, "%ld %d %s%c%s%c%c%s%c", jcr->JobFiles, ff_pkt->type, ff_pkt->link, 0, attribs, 0, 0, attribsEx, 0); diff --git a/bacula/src/filed/estimate.c b/bacula/src/filed/estimate.c index 39650087fe..d53accddf5 100644 --- a/bacula/src/filed/estimate.c +++ b/bacula/src/filed/estimate.c @@ -64,11 +64,12 @@ static int tally_file(FF_PKT *ff_pkt, void *ijcr) case FT_REGE: case FT_REG: case FT_LNK: - case FT_DIR: + case FT_DIREND: case FT_SPEC: case FT_RAW: case FT_FIFO: break; + case FT_DIRBEGIN: case FT_NOACCESS: case FT_NOFOLLOW: case FT_NOSTAT: diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index bf65d87597..7f919e039a 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -94,7 +94,9 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) case FT_LNK: Dmsg2(30, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; - case FT_DIR: + case FT_DIRBEGIN: + return 1; /* ignored */ + case FT_DIREND: Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname); break; case FT_SPEC: @@ -179,7 +181,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) stat = bnet_fsend(dir, "%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs, 0, ff_pkt->link, 0); - } else if (ff_pkt->type == FT_DIR) { + } else if (ff_pkt->type == FT_DIREND) { /* Here link is the canonical filename (i.e. with trailing slash) */ stat = bnet_fsend(dir,"%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link, diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index d73622e821..0c6e6cb840 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -9,7 +9,7 @@ * */ /* - Copyright (C) 2000-2004 Kern Sibbald and John Walker + Copyright (C) 2002-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/findlib/bfile.h b/bacula/src/findlib/bfile.h index 66123fd5d4..0e25f7de5a 100644 --- a/bacula/src/findlib/bfile.h +++ b/bacula/src/findlib/bfile.h @@ -6,7 +6,7 @@ * Kern Sibbald May MMIII */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2000-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/findlib/enable_priv.c b/bacula/src/findlib/enable_priv.c index 5a35d842ee..9c23183774 100755 --- a/bacula/src/findlib/enable_priv.c +++ b/bacula/src/findlib/enable_priv.c @@ -7,7 +7,7 @@ * */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2003-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/findlib/find.c b/bacula/src/findlib/find.c index 45a5228d1f..bbf9a14984 100644 --- a/bacula/src/findlib/find.c +++ b/bacula/src/findlib/find.c @@ -5,7 +5,7 @@ * Kern E. Sibbald, MM */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2000-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -29,14 +29,16 @@ #include "find.h" -int32_t name_max; /* filename max length */ -int32_t path_max; /* path name max length */ +int32_t name_max; /* filename max length */ +int32_t path_max; /* path name max length */ /* ****FIXME**** debug until stable */ #undef bmalloc #define bmalloc(x) sm_malloc(__FILE__, __LINE__, x) static void set_options(FF_PKT *ff, const char *opts); +static int our_callback(FF_PKT *ff, void *hpkt); +static bool accept_file(FF_PKT *ff); /* @@ -44,14 +46,14 @@ static void set_options(FF_PKT *ff, const char *opts); */ FF_PKT *init_find_files() { - FF_PKT *ff; + FF_PKT *ff; ff = (FF_PKT *)bmalloc(sizeof(FF_PKT)); memset(ff, 0, sizeof(FF_PKT)); ff->sys_fname = get_pool_memory(PM_FNAME); - init_include_exclude_files(ff); /* init lists */ + init_include_exclude_files(ff); /* init lists */ /* Get system path and filename maximum lengths */ path_max = pathconf(".", _PC_PATH_MAX); @@ -63,8 +65,8 @@ FF_PKT *init_find_files() if (name_max < 1024) { name_max = 1024; } - path_max++; /* add for EOS */ - name_max++; /* add for EOS */ + path_max++; /* add for EOS */ + name_max++; /* add for EOS */ Dmsg1(100, "init_find_files ff=%p\n", ff); return ff; @@ -84,9 +86,9 @@ set_find_options(FF_PKT *ff, int incremental, time_t save_time) Dmsg0(100, "Leave set_find_options()\n"); } + /* - * Find all specified files (determined by calls to - * name_add() + * Find all specified files (determined by calls to name_add() * This routine calls the (handle_file) subroutine with all * sorts of good information for the final disposition of * the file. @@ -104,47 +106,124 @@ set_find_options(FF_PKT *ff, int incremental, time_t save_time) int find_files(JCR *jcr, FF_PKT *ff, int callback(FF_PKT *ff_pkt, void *hpkt), void *his_pkt) { - struct s_included_file *inc = NULL; - - /* This is the old deprecated way */ - while (!job_canceled(jcr) && (inc = get_next_included_file(ff, inc))) { - /* Copy options for this file */ - bstrncpy(ff->VerifyOpts, inc->VerifyOpts, sizeof(ff->VerifyOpts)); - Dmsg1(50, "find_files: file=%s\n", inc->fname); - if (!file_is_excluded(ff, inc->fname)) { - if (!find_one_file(jcr, ff, callback, his_pkt, inc->fname, (dev_t)-1, 1)) { - return 0; /* error return */ - } - } - } + ff->callback = callback; /* This is the new way */ findFILESET *fileset = ff->fileset; if (fileset) { int i, j; for (i=0; iinclude_list.size(); i++) { - findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); - /* - * 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); + findINCEXE *incexe = (findINCEXE *)fileset->include_list.get(i); + fileset->incexe = incexe; + /* + * 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); Dmsg1(400, "Find global options O %s\n", fo->opts); - set_options(ff, fo->opts); - } - for (j=0; jname_list.size(); j++) { + set_options(ff, fo->opts); + } + for (j=0; jname_list.size(); j++) { Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j)); - char *fname = (char *)incexe->name_list.get(j); - if (!find_one_file(jcr, ff, callback, his_pkt, fname, (dev_t)-1, 1)) { - return 0; /* error return */ - } - } + char *fname = (char *)incexe->name_list.get(j); + if (!find_one_file(jcr, ff, our_callback, his_pkt, fname, (dev_t)-1, 1)) { + return 0; /* error return */ + } + } + } + } else { + struct s_included_file *inc = NULL; + + /* This is the old deprecated way */ + while (!job_canceled(jcr) && (inc = get_next_included_file(ff, inc))) { + /* Copy options for this file */ + bstrncpy(ff->VerifyOpts, inc->VerifyOpts, sizeof(ff->VerifyOpts)); + Dmsg1(50, "find_files: file=%s\n", inc->fname); + if (!file_is_excluded(ff, inc->fname)) { + if (!find_one_file(jcr, ff, callback, his_pkt, inc->fname, (dev_t)-1, 1)) { + return 0; /* error return */ + } + } } } return 1; } +static bool accept_file(FF_PKT *ff) +{ + int i, j, k; + findFILESET *fileset = ff->fileset; + findINCEXE *incexe = fileset->incexe; + + for (j=0; jopts_list.size(); j++) { + findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); + for (k=0; kwild.size(); k++) { + + } + } + + for (i=0; iexclude_list.size(); i++) { + findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i); + for (j=0; jopts_list.size(); j++) { + findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j); + for (k=0; kwild.size(); k++) { + Dmsg1(400, "W %s\n", (char *)fo->wild.get(k)); + if (fnmatch((char *)fo->wild.get(k), ff->fname, FNM_PATHNAME) == 0) { + Dmsg1(000, "Reject wild: %s\n", ff->fname); + return false; /* reject file */ + } + } + } + for (j=0; jname_list.size(); j++) { + Dmsg1(400, "F %s\n", (char *)incexe->name_list.get(j)); + if (fnmatch((char *)incexe->name_list.get(j), ff->fname, FNM_PATHNAME) == 0) { + Dmsg1(000, "Reject: %s\n", ff->fname); + return false; /* reject file */ + } + } + } + Dmsg1(000, "Accept: %s\n", ff->fname); + return true; +} + +/* + * The code comes here for each file examined. + * We filter the files, then call the user's callback if + * the file is included. + */ +static int our_callback(FF_PKT *ff, void *hpkt) +{ + switch (ff->type) { + case FT_NOACCESS: + case FT_NOFOLLOW: + case FT_NOSTAT: + case FT_NOCHG: + case FT_ISARCH: + case FT_NORECURSE: + case FT_NOFSCHG: + case FT_NOOPEN: + Dmsg1(000, "File=%s\n", ff->fname); + return ff->callback(ff, hpkt); + + /* These items can be filtered */ + case FT_LNKSAVED: + case FT_REGE: + case FT_REG: + case FT_LNK: + case FT_DIRBEGIN: + case FT_DIREND: + case FT_SPEC: + if (accept_file(ff)) { + return ff->callback(ff, hpkt); + } else { + return 0; + } + } + return 0; +} + + /* * As an optimization, we should do this during * "compile" time in filed/job.c, and keep only a bit mask @@ -159,61 +238,61 @@ static void set_options(FF_PKT *ff, const char *opts) switch (*p) { case 'a': /* alway replace */ case '0': /* no option */ - break; + break; case 'e': - ff->flags |= FO_EXCLUDE; - break; + ff->flags |= FO_EXCLUDE; + break; case 'f': - ff->flags |= FO_MULTIFS; - break; + ff->flags |= FO_MULTIFS; + break; case 'h': /* no recursion */ - ff->flags |= FO_NO_RECURSION; - break; + ff->flags |= FO_NO_RECURSION; + break; case 'M': /* MD5 */ - ff->flags |= FO_MD5; - break; + ff->flags |= FO_MD5; + break; case 'n': - ff->flags |= FO_NOREPLACE; - break; + ff->flags |= FO_NOREPLACE; + break; case 'p': /* use portable data format */ - ff->flags |= FO_PORTABLE; - break; + ff->flags |= FO_PORTABLE; + break; case 'r': /* read fifo */ - ff->flags |= FO_READFIFO; - break; + ff->flags |= FO_READFIFO; + break; case 'S': - ff->flags |= FO_SHA1; - break; + ff->flags |= FO_SHA1; + break; case 's': - ff->flags |= FO_SPARSE; - break; + ff->flags |= FO_SPARSE; + break; case 'm': - ff->flags |= FO_MTIMEONLY; - break; + ff->flags |= FO_MTIMEONLY; + break; case 'k': - ff->flags |= FO_KEEPATIME; - break; + ff->flags |= FO_KEEPATIME; + break; case 'V': /* verify options */ - /* Copy Verify Options */ + /* Copy Verify Options */ for (j=0; *p && *p != ':'; p++) { - ff->VerifyOpts[j] = *p; - if (j < (int)sizeof(ff->VerifyOpts) - 1) { - j++; - } - } - ff->VerifyOpts[j] = 0; - break; + ff->VerifyOpts[j] = *p; + if (j < (int)sizeof(ff->VerifyOpts) - 1) { + j++; + } + } + ff->VerifyOpts[j] = 0; + break; case 'w': - ff->flags |= FO_IF_NEWER; - break; + ff->flags |= FO_IF_NEWER; + break; case 'Z': /* gzip compression */ - ff->flags |= FO_GZIP; + ff->flags |= FO_GZIP; ff->GZIP_level = *++p - '0'; Dmsg1(200, "Compression level=%d\n", ff->GZIP_level); - break; + break; default: Emsg1(M_ERROR, 0, "Unknown include/exclude option: %c\n", *p); - break; + break; } } } diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index c3698fd29c..15c4f8a2e7 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -4,7 +4,7 @@ * Kern Sibbald MIM */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2000-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -121,6 +121,9 @@ enum { /* File options structure */ struct findFOPTS { char opts[MAX_FOPTS]; /* options string */ + uint32_t flags; /* options in bits */ + int GZIP_level; /* GZIP level */ + char VerifyOpts[MAX_FOPTS]; /* verify options */ alist regex; /* regex string(s) */ alist wild; /* wild card strings */ alist base; /* list of base names */ @@ -172,6 +175,7 @@ struct FF_PKT { struct s_excluded_file *excluded_files_list; struct s_excluded_file *excluded_paths_list; findFILESET *fileset; + int (*callback)(FF_PKT *, void *); /* User's callback */ /* List of all hard linked files found */ struct f_link *linklist; /* hard linked files */ diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index cbd48f0724..bb0a2635e9 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -1,5 +1,5 @@ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2000-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -28,8 +28,8 @@ #include "bacula.h" #include "find.h" -extern int32_t name_max; /* filename max length */ -extern int32_t path_max; /* path name max length */ +extern int32_t name_max; /* filename max length */ +extern int32_t path_max; /* path name max length */ /* * Structure for keeping track of hard linked files, we @@ -40,11 +40,11 @@ extern int32_t path_max; /* path name max length */ */ struct f_link { struct f_link *next; - dev_t dev; /* device */ - ino_t ino; /* inode with device is unique */ + dev_t dev; /* device */ + ino_t ino; /* inode with device is unique */ short linkcount; - uint32_t FileIndex; /* Bacula FileIndex of this file */ - char name[1]; /* The name */ + uint32_t FileIndex; /* Bacula FileIndex of this file */ + char name[1]; /* The name */ }; static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt) @@ -56,7 +56,7 @@ static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt) } /* - * Find a single file. + * Find a single file. * handle_file is the callback for handling the file. * p is the filename * parent_device is the device we are currently on @@ -65,7 +65,7 @@ static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt) */ int find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), - void *pkt, char *fname, dev_t parent_device, int top_level) + void *pkt, char *fname, dev_t parent_device, int top_level) { struct utimbuf restore_times; int rtn_stat; @@ -97,11 +97,11 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), Dmsg1(300, "Non-directory incremental: %s\n", ff_pkt->fname); /* Not a directory */ if (ff_pkt->statp.st_mtime < ff_pkt->save_time - && ((ff_pkt->flags & FO_MTIMEONLY) || - ff_pkt->statp.st_ctime < ff_pkt->save_time)) { - /* Incremental option, file not changed */ - ff_pkt->type = FT_NOCHG; - return handle_file(ff_pkt, pkt); + && ((ff_pkt->flags & FO_MTIMEONLY) || + ff_pkt->statp.st_ctime < ff_pkt->save_time)) { + /* Incremental option, file not changed */ + ff_pkt->type = FT_NOCHG; + return handle_file(ff_pkt, pkt); } } @@ -123,27 +123,27 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), */ if (ff_pkt->statp.st_nlink > 1 && (S_ISREG(ff_pkt->statp.st_mode) - || S_ISCHR(ff_pkt->statp.st_mode) - || S_ISBLK(ff_pkt->statp.st_mode) - || S_ISFIFO(ff_pkt->statp.st_mode) - || S_ISSOCK(ff_pkt->statp.st_mode))) { + || S_ISCHR(ff_pkt->statp.st_mode) + || S_ISBLK(ff_pkt->statp.st_mode) + || S_ISFIFO(ff_pkt->statp.st_mode) + || S_ISSOCK(ff_pkt->statp.st_mode))) { struct f_link *lp; /* Search link list of hard linked files */ for (lp = ff_pkt->linklist; lp; lp = lp->next) - if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) { + if (lp->ino == ff_pkt->statp.st_ino && lp->dev == ff_pkt->statp.st_dev) { /* If we have already backed up the hard linked file don't do it again */ - if (strcmp(lp->name, fname) == 0) { + if (strcmp(lp->name, fname) == 0) { Jmsg1(jcr, M_WARNING, 0, _("Attempt to backup hard linked file %s twice ignored.\n"), - fname); - return 1; /* ignore */ - } - ff_pkt->link = lp->name; - ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */ - ff_pkt->LinkFI = lp->FileIndex; - return handle_file(ff_pkt, pkt); - } + fname); + return 1; /* ignore */ + } + ff_pkt->link = lp->name; + ff_pkt->type = FT_LNKSAVED; /* Handle link, file already saved */ + ff_pkt->LinkFI = lp->FileIndex; + return handle_file(ff_pkt, pkt); + } /* File not previously dumped. Chain it into our list. */ lp = (struct f_link *)bmalloc(sizeof(struct f_link) + strlen(fname) +1); @@ -152,7 +152,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), strcpy(lp->name, fname); lp->next = ff_pkt->linklist; ff_pkt->linklist = lp; - ff_pkt->linked = lp; /* mark saved link */ + ff_pkt->linked = lp; /* mark saved link */ } else { ff_pkt->linked = NULL; } @@ -164,16 +164,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), sizeleft = ff_pkt->statp.st_size; /* Don't bother opening empty, world readable files. Also do not open - files when archive is meant for /dev/null. */ + files when archive is meant for /dev/null. */ if (ff_pkt->null_output_device || (sizeleft == 0 - && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) { - ff_pkt->type = FT_REGE; + && MODE_RALL == (MODE_RALL & ff_pkt->statp.st_mode))) { + ff_pkt->type = FT_REGE; } else { - ff_pkt->type = FT_REG; + ff_pkt->type = FT_REG; } rtn_stat = handle_file(ff_pkt, pkt); if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } return rtn_stat; @@ -184,21 +184,21 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), size = readlink(fname, buffer, path_max + name_max + 101); if (size < 0) { - /* Could not follow link */ - ff_pkt->type = FT_NOFOLLOW; - ff_pkt->ff_errno = errno; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - return rtn_stat; + /* Could not follow link */ + ff_pkt->type = FT_NOFOLLOW; + ff_pkt->ff_errno = errno; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + return rtn_stat; } buffer[size] = 0; - ff_pkt->link = buffer; /* point to link */ - ff_pkt->type = FT_LNK; /* got a real link */ + ff_pkt->link = buffer; /* point to link */ + ff_pkt->type = FT_LNK; /* got a real link */ rtn_stat = handle_file(ff_pkt, pkt); if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; } return rtn_stat; @@ -207,7 +207,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), struct dirent *entry, *result; char *link; int link_len; - int len; + int len; int status; dev_t our_device = ff_pkt->statp.st_dev; @@ -217,16 +217,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * in principle, we should be able to access everything. */ if (!have_win32_api() || (ff_pkt->flags & FO_PORTABLE)) { - if (access(fname, R_OK) == -1 && geteuid() != 0) { - /* Could not access() directory */ - ff_pkt->type = FT_NOACCESS; - ff_pkt->ff_errno = errno; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - return rtn_stat; - } + if (access(fname, R_OK) == -1 && geteuid() != 0) { + /* Could not access() directory */ + ff_pkt->type = FT_NOACCESS; + ff_pkt->ff_errno = errno; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + return rtn_stat; + } } /* Build a canonical directory name with a trailing slash in link var */ @@ -236,18 +236,26 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), bstrncpy(link, fname, link_len); /* Strip all trailing slashes */ while (len >= 1 && link[len - 1] == '/') - len--; + len--; link[len++] = '/'; /* add back one */ link[len] = 0; ff_pkt->link = link; if (ff_pkt->incremental && - (ff_pkt->statp.st_mtime < ff_pkt->save_time && - ff_pkt->statp.st_ctime < ff_pkt->save_time)) { - /* Incremental option, directory entry not changed */ - ff_pkt->type = FT_DIRNOCHG; + (ff_pkt->statp.st_mtime < ff_pkt->save_time && + ff_pkt->statp.st_ctime < ff_pkt->save_time)) { + /* Incremental option, directory entry not changed */ + ff_pkt->type = FT_DIRNOCHG; } else { - ff_pkt->type = FT_DIR; + ff_pkt->type = FT_DIRBEGIN; + } + /* Send off Directory packet now */ + if (!handle_file(ff_pkt, pkt)) { + free(link); + return 0; /* Do not save this directory */ + } + if (ff_pkt->type == FT_DIRBEGIN) { + ff_pkt->type = FT_DIREND; } /* @@ -268,7 +276,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), dir_ff_pkt->excluded_files_list = NULL; dir_ff_pkt->excluded_paths_list = NULL; dir_ff_pkt->linklist = NULL; - + ff_pkt->link = ff_pkt->fname; /* reset "link" */ /* @@ -276,15 +284,15 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * user has turned it off for this directory. */ if (ff_pkt->flags & FO_NO_RECURSION) { - /* No recursion into this directory */ - ff_pkt->type = FT_NORECURSE; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - free(link); - free_dir_ff_pkt(dir_ff_pkt); - return rtn_stat; + /* No recursion into this directory */ + ff_pkt->type = FT_NORECURSE; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + free(link); + free_dir_ff_pkt(dir_ff_pkt); + return rtn_stat; } /* @@ -292,16 +300,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * avoid doing so if the user only wants to dump one file system. */ if (!top_level && !(ff_pkt->flags & FO_MULTIFS) && - parent_device != ff_pkt->statp.st_dev) { - /* returning here means we do not handle this directory */ - ff_pkt->type = FT_NOFSCHG; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - free(link); - free_dir_ff_pkt(dir_ff_pkt); - return rtn_stat; + parent_device != ff_pkt->statp.st_dev) { + /* returning here means we do not handle this directory */ + ff_pkt->type = FT_NOFSCHG; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + free(link); + free_dir_ff_pkt(dir_ff_pkt); + return rtn_stat; } /* * Decend into or "recurse" into the directory to read @@ -309,15 +317,15 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), */ errno = 0; if ((directory = opendir(fname)) == NULL) { - ff_pkt->type = FT_NOOPEN; - ff_pkt->ff_errno = errno; - rtn_stat = handle_file(ff_pkt, pkt); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - free(link); - free_dir_ff_pkt(dir_ff_pkt); - return rtn_stat; + ff_pkt->type = FT_NOOPEN; + ff_pkt->ff_errno = errno; + rtn_stat = handle_file(ff_pkt, pkt); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + free(link); + free_dir_ff_pkt(dir_ff_pkt); + return rtn_stat; } /* @@ -328,38 +336,38 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), rtn_stat = 1; entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100); for ( ; !job_canceled(jcr); ) { - char *p, *q; - int i; + char *p, *q; + int i; - status = readdir_r(directory, entry, &result); - if (status != 0 || result == NULL) { + status = readdir_r(directory, entry, &result); + if (status != 0 || result == NULL) { // Dmsg2(99, "readdir returned stat=%d result=0x%x\n", -// status, (long)result); - break; - } - ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry)); - p = entry->d_name; +// status, (long)result); + break; + } + ASSERT(name_max+1 > (int)sizeof(struct dirent) + (int)NAMELEN(entry)); + p = entry->d_name; /* Skip `.', `..', and excluded file names. */ if (p[0] == '\0' || (p[0] == '.' && (p[1] == '\0' || (p[1] == '.' && p[2] == '\0')))) { - continue; - } - - if ((int)NAMELEN(entry) + len >= link_len) { - link_len = len + NAMELEN(entry) + 1; - link = (char *)brealloc(link, link_len + 1); - } - q = link + len; - for (i=0; i < (int)NAMELEN(entry); i++) { - *q++ = *p++; - } - *q = 0; - if (!file_is_excluded(ff_pkt, link)) { - rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0); - if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = ff_pkt->FileIndex; - } - } + continue; + } + + if ((int)NAMELEN(entry) + len >= link_len) { + link_len = len + NAMELEN(entry) + 1; + link = (char *)brealloc(link, link_len + 1); + } + q = link + len; + for (i=0; i < (int)NAMELEN(entry); i++) { + *q++ = *p++; + } + *q = 0; + if (!file_is_excluded(ff_pkt, link)) { + rtn_stat = find_one_file(jcr, ff_pkt, handle_file, pkt, link, our_device, 0); + if (ff_pkt->linked) { + ff_pkt->linked->FileIndex = ff_pkt->FileIndex; + } + } } closedir(directory); free(link); @@ -372,14 +380,14 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), * the directory modes and dates. Temp directory values * were used without this record. */ - handle_file(dir_ff_pkt, pkt); /* handle directory entry */ + handle_file(dir_ff_pkt, pkt); /* handle directory entry */ if (ff_pkt->linked) { - ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex; + ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex; } free_dir_ff_pkt(dir_ff_pkt); if (ff_pkt->flags & FO_KEEPATIME) { - utime(fname, &restore_times); + utime(fname, &restore_times); } return rtn_stat; } /* end check for directory */ @@ -392,8 +400,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), #ifdef HAVE_FREEBSD_OS /* * On FreeBSD, all block devices are character devices, so - * to be able to read a raw disk, we need the check for - * a character device. + * to be able to read a raw disk, we need the check for + * a character device.     * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/ad0s3     * crw-r-----  1 root  operator  - 116, 0x00040002 Jun  9 19:32 /dev/rad0s3 */ @@ -401,9 +409,9 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt), #else if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) { #endif - ff_pkt->type = FT_RAW; /* raw partition */ + ff_pkt->type = FT_RAW; /* raw partition */ } else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) && - ff_pkt->flags & FO_READFIFO) { + ff_pkt->flags & FO_READFIFO) { ff_pkt->type = FT_FIFO; } else { /* The only remaining types are special (character, ...) files */ @@ -426,8 +434,8 @@ int term_find_one(FF_PKT *ff) lc = lp; lp = lp->next; if (lc) { - free(lc); - count++; + free(lc); + count++; } } return count; diff --git a/bacula/src/findlib/match.c b/bacula/src/findlib/match.c index 95a574572f..9581567144 100644 --- a/bacula/src/findlib/match.c +++ b/bacula/src/findlib/match.c @@ -6,7 +6,7 @@ * */ /* - Copyright (C) 2001-2003 Kern Sibbald and John Walker + Copyright (C) 2001-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h index 98d1abafc9..5f87bf4b0f 100644 --- a/bacula/src/findlib/protos.h +++ b/bacula/src/findlib/protos.h @@ -4,7 +4,7 @@ * Version $Id$ */ /* - Copyright (C) 2000-2003 Kern Sibbald and John Walker + Copyright (C) 2000-2004 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as diff --git a/bacula/src/tools/testfind.c b/bacula/src/tools/testfind.c index a9f9afa231..61e64a2717 100644 --- a/bacula/src/tools/testfind.c +++ b/bacula/src/tools/testfind.c @@ -206,7 +206,9 @@ static int print_file(FF_PKT *ff, void *pkt) } count_files(ff); break; - case FT_DIR: + case FT_DIRBEGIN: + return 1; + case FT_DIREND: if (debug_level == 1) { printf("%s\n", ff->fname); } else if (debug_level > 1) { diff --git a/bacula/src/tools/testls.c b/bacula/src/tools/testls.c index 7ecd5fb9bc..667ab80088 100755 --- a/bacula/src/tools/testls.c +++ b/bacula/src/tools/testls.c @@ -164,10 +164,12 @@ static int print_file(FF_PKT *ff, void *pkt) case FT_REGE: case FT_REG: case FT_LNK: - case FT_DIR: + case FT_DIREND: case FT_SPEC: print_ls_output(ff->fname, ff->link, ff->type, &ff->statp); break; + case FT_DIRBEGIN: + break; case FT_NOACCESS: printf(_("Err: Could not access %s: %s\n"), ff->fname, strerror(errno)); break; -- 2.39.5