]> git.sur5r.net Git - bacula/bacula/commitdiff
Start FileSet filtering
authorKern Sibbald <kern@sibbald.com>
Fri, 30 Apr 2004 10:01:26 +0000 (10:01 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 30 Apr 2004 10:01:26 +0000 (10:01 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1327 91ce42f0-d328-0410-95d8-f526ca767f89

14 files changed:
bacula/src/baconfig.h
bacula/src/filed/backup.c
bacula/src/filed/estimate.c
bacula/src/filed/verify.c
bacula/src/findlib/attribs.c
bacula/src/findlib/bfile.h
bacula/src/findlib/enable_priv.c
bacula/src/findlib/find.c
bacula/src/findlib/find.h
bacula/src/findlib/find_one.c
bacula/src/findlib/match.c
bacula/src/findlib/protos.h
bacula/src/tools/testfind.c
bacula/src/tools/testls.c

index e1155c2d2a5023a38624314ef625b88136ef2a36..009211762b15b1597a476dfaccc82eb4d0bbf210 100644 (file)
 #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 */
 #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 */
index 20e3eecd50f9b35ccdccf8b73a1295eab9174e96..0e7a69627d53ff99f590a22e4132cd755e75c8ef 100644 (file)
@@ -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);
index 39650087fee4948a283c4fba1d03591f91a7e078..d53accddf5b3811d7970766140d31f929d6a08e1 100644 (file)
@@ -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:
index bf65d87597ed2f90d61ff6988207e5907008724b..7f919e039a23243cb37dc858f0adcd73183429b0 100644 (file)
@@ -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, 
index d73622e8219021ec98032db14a641b5cfd7b291f..0c6e6cb840cabb1471689681f80da64ee9e036dc 100755 (executable)
@@ -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
index 66123fd5d4b38a2fce50b1824348d96c31e41510..0e25f7de5ade068ceed29e4dc00abfd18663aaec 100644 (file)
@@ -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
index 5a35d842eeb165bdcf729398b2490e739e73a275..9c23183774bf316ca13ef7a665a2582ff2bb82a8 100755 (executable)
@@ -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
index 45a5228d1f38230a829d6581c1454a09b14f01ab..bbf9a14984128e4fc62711a764c74d8110b173c1 100644 (file)
@@ -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
 #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; i<fileset->include_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; j<incexe->opts_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; j<incexe->opts_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; j<incexe->name_list.size(); j++) {
+            set_options(ff, fo->opts);
+         }
+         for (j=0; j<incexe->name_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; j<incexe->opts_list.size(); j++) {
+      findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+      for (k=0; k<fo->wild.size(); k++) {
+         
+      }
+   }
+
+   for (i=0; i<fileset->exclude_list.size(); i++) {
+      findINCEXE *incexe = (findINCEXE *)fileset->exclude_list.get(i);
+      for (j=0; j<incexe->opts_list.size(); j++) {
+         findFOPTS *fo = (findFOPTS *)incexe->opts_list.get(j);
+         for (k=0; k<fo->wild.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; j<incexe->name_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;
       }
    }
 }
index c3698fd29c9e429ffb71043418bc957cc449fd37..15c4f8a2e72b52fd24c94ebf7f17906aeb2fee2e 100755 (executable)
@@ -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 */
index cbd48f07245cc55153a53994001803f521e600b1..bb0a2635e97400cacb979cae87dffbf0e05f117d 100755 (executable)
@@ -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;
index 95a574572f846610c02b7e8a425dcd6c4f7cccb0..9581567144266c37673c5d6c045a17035afa0223 100644 (file)
@@ -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
index 98d1abafc9adcda6eae9ce0adab010889554f0d7..5f87bf4b0f27819fecdf94db3b2e26399fbd19b5 100644 (file)
@@ -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
index a9f9afa2315642fb96467ee3c2720720f7024938..61e64a271780ab1a24c60f92bde3fdaa581a1f9e 100644 (file)
@@ -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) {
index 7ecd5fb9bce54213c2142e58dfdef7b03c1bae53..667ab80088eda0a9fdce6a3b65d91a0fd626365c 100755 (executable)
@@ -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;