]> git.sur5r.net Git - bacula/bacula/commitdiff
Fix directory times, modes on restore
authorKern Sibbald <kern@sibbald.com>
Sun, 13 Apr 2003 14:47:31 +0000 (14:47 +0000)
committerKern Sibbald <kern@sibbald.com>
Sun, 13 Apr 2003 14:47:31 +0000 (14:47 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@438 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/findlib/create_file.c
bacula/src/findlib/find.h
bacula/src/findlib/find_one.c

index 2169ad03431b7bdc28412ea5995295300f436c8e..bca0d9f29be7406dfd367fbffd7363ee7cbddcf3 100644 (file)
@@ -38,6 +38,9 @@
 #define O_CTG 0
 #endif
 
+static int separate_path_and_file(void *jcr, char *fname, char *ofile);
+static int path_already_seen(char *path, int pnl);
+
 
 /*
  * Create the file, or the directory
@@ -66,8 +69,7 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
    uid_t uid;
    gid_t gid;
    int stat = 0;
-   int fnl, pnl;
-   char *f, *p, savechr;
+   int pnl;
 
    binit(ofd);
    new_mode = statp->st_mode;
@@ -102,79 +104,122 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
    }
    switch (type) {
    case FT_LNKSAVED:                 /* Hard linked, file already saved */
-      Dmsg2(130, "Hard link %s => %s\n", ofile, lname);
-      if (link(lname, ofile) != 0) {
-         Jmsg3(jcr, M_ERROR, 0, _("Could not hard link %s ==> %s: ERR=%s\n"), 
-              ofile, lname, strerror(errno));
-        return CF_ERROR;
-      }
-      return CF_CREATED;
+   case FT_LNK:
+   case FT_RAW:
+   case FT_FIFO:
+   case FT_SPEC:
    case FT_REGE:                     /* empty file */
    case FT_REG:                      /* regular file */
-      /* Separate pathname and filename */
-      for (p=f=ofile; *p; p++) {
-         if (*p == '/') {
-           f = p;                    /* possible filename */
-        }
-      }
-      if (*f == '/') {
-        f++;
-      }
-
-      fnl = p - f;
-      if (fnl == 0) {
-        /* The filename length must not be zero here because we
-         *  are dealing with a file (i.e. FT_REGE or FT_REG).
-         */
-         Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
+      /* 
+       * Here we do some preliminary work for all the above
+       *   types to create the path to the file if it does
+       *   not already exist.  Below, we will split to
+       *   do the file type specific work
+       */
+      pnl = separate_path_and_file(jcr, fname, ofile);
+      if (pnl < 0) {
         return CF_ERROR;
       }
 
-      pnl = f - ofile - 1;    
-
       /*
        * If path length is <= 0 we are making a file in the root
        *  directory. Assume that the directory already exists.
        */
       if (pnl > 0) {
+        char savechr;
         savechr = ofile[pnl];
         ofile[pnl] = 0;                 /* terminate path */
 
-         Dmsg1(50, "Make path %s\n", ofile);
-        /*
-         * If we need to make the directory, ensure that it is with
-         * execute bit set (i.e. parent_mode), and preserve what already
-         * exists. Normally, this should do nothing.
-         */
-        stat = !make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL);
-        if (stat == 0) {
-            Dmsg1(0, "Could not make path. %s\n", ofile);
-            Jmsg1(jcr, M_ERROR, 0, _("Could not make path. %s\n"), ofile);
-           return CF_ERROR;
+        if (!path_already_seen(ofile, pnl)) {
+            Dmsg1(50, "Make path %s\n", ofile);
+           /*
+            * If we need to make the directory, ensure that it is with
+            * execute bit set (i.e. parent_mode), and preserve what already
+            * exists. Normally, this should do nothing.
+            */
+           stat = !make_path(jcr, ofile, parent_mode, parent_mode, uid, gid, 1, NULL);
+           if (stat == 0) {
+               Dmsg1(0, "Could not make path. %s\n", ofile);
+               Jmsg1(jcr, M_ERROR, 0, _("Could not make path. %s\n"), ofile);
+              return CF_ERROR;
+           }
         }
-      
         ofile[pnl] = savechr;           /* restore full name */
       }
 
-      Dmsg1(100, "Create file %s\n", ofile);
-      mode =  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /*  O_NOFOLLOW; */
-      if (IS_CTG(statp->st_mode)) {
-        mode |= O_CTG;               /* set contiguous bit if needed */
-      }
-      Dmsg1(50, "Create file: %s\n", ofile);
-      if ((bopen(ofd, ofile, mode, S_IRUSR | S_IWUSR)) < 0) {
-         Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), ofile, strerror(errno));
-        return CF_ERROR;
-      }
-      return CF_EXTRACT;
-   case FT_LNK:
-      Dmsg2(130, "FT_LNK should restore: %s -> %s\n", ofile, lname);
-      if (symlink(lname, ofile) != 0 && errno != EEXIST) {
-         Jmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), 
-           ofile, lname, strerror(errno));
+      /* Now we do the specific work for each file type */
+      switch(type) {
+      case FT_REGE:
+      case FT_REG:
+         Dmsg1(100, "Create file %s\n", ofile);
+        mode =  O_WRONLY | O_CREAT | O_TRUNC | O_BINARY; /*  O_NOFOLLOW; */
+        if (IS_CTG(statp->st_mode)) {
+           mode |= O_CTG;               /* set contiguous bit if needed */
+        }
+         Dmsg1(50, "Create file: %s\n", ofile);
+        if ((bopen(ofd, ofile, mode, S_IRUSR | S_IWUSR)) < 0) {
+            Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), ofile, strerror(errno));
+           return CF_ERROR;
+        }
+        return CF_EXTRACT;
+
+      case FT_RAW:                   /* Bacula raw device e.g. /dev/sda1 */
+      case FT_FIFO:                  /* Bacula fifo to save data */
+      case FT_SPEC:                     
+        if (S_ISFIFO(statp->st_mode)) {
+            Dmsg1(200, "Restore fifo: %s\n", ofile);
+           if (mkfifo(ofile, statp->st_mode) != 0 && errno != EEXIST) {
+               Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), ofile, strerror(errno));
+              return CF_ERROR;
+           }
+        } else {          
+            Dmsg1(200, "Restore node: %s\n", ofile);
+           if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0 && errno != EEXIST) {
+               Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), ofile, strerror(errno));
+              return CF_ERROR;
+           }
+        }       
+        if (type == FT_RAW || type == FT_FIFO) {
+           btimer_id tid;
+            Dmsg1(200, "FT_RAW|FT_FIFO %s\n", ofile);
+           mode =  O_WRONLY | O_BINARY;
+           /* Timeout open() in 60 seconds */
+           if (type == FT_FIFO) {
+              tid = start_thread_timer(pthread_self(), 60);
+           } else {
+              tid = NULL;
+           }
+           if ((bopen(ofd, ofile, mode, 0)) < 0) {
+               Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), ofile, strerror(errno));
+              stop_thread_timer(tid);
+              return CF_ERROR;
+           }
+           stop_thread_timer(tid);
+           return CF_EXTRACT;
+        }
+         Dmsg1(200, "FT_SPEC %s\n", ofile);
+        return CF_CREATED;
+
+      case FT_LNK:
+         Dmsg2(130, "FT_LNK should restore: %s -> %s\n", ofile, lname);
+        if (symlink(lname, ofile) != 0 && errno != EEXIST) {
+            Jmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), 
+              ofile, lname, strerror(errno));
+           return CF_ERROR;
+        }
+        return CF_CREATED;
+
+      case FT_LNKSAVED:                 /* Hard linked, file already saved */
+      Dmsg2(130, "Hard link %s => %s\n", ofile, lname);
+      if (link(lname, ofile) != 0) {
+         Jmsg3(jcr, M_ERROR, 0, _("Could not hard link %s ==> %s: ERR=%s\n"), 
+              ofile, lname, strerror(errno));
         return CF_ERROR;
       }
       return CF_CREATED;
+
+      } /* End inner switch */
+
    case FT_DIR:
       Dmsg2(300, "Make dir mode=%o dir=%s\n", new_mode, ofile);
       if (make_path(jcr, ofile, new_mode, parent_mode, uid, gid, 0, NULL) != 0) {
@@ -182,42 +227,6 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
         return CF_ERROR;
       }
       return CF_CREATED;
-   case FT_RAW:
-   case FT_FIFO:
-   case FT_SPEC:
-      if (S_ISFIFO(statp->st_mode)) {
-         Dmsg1(200, "Restore fifo: %s\n", ofile);
-        if (mkfifo(ofile, statp->st_mode) != 0 && errno != EEXIST) {
-            Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), ofile, strerror(errno));
-           return CF_ERROR;
-        }
-      } else {         
-         Dmsg1(200, "Restore node: %s\n", ofile);
-        if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0 && errno != EEXIST) {
-            Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), ofile, strerror(errno));
-           return CF_ERROR;
-        }
-      }       
-      if (type == FT_RAW || type == FT_FIFO) {
-        btimer_id tid;
-         Dmsg1(200, "FT_RAW|FT_FIFO %s\n", ofile);
-        mode =  O_WRONLY | O_BINARY;
-        /* Timeout open() in 60 seconds */
-        if (type == FT_FIFO) {
-           tid = start_thread_timer(pthread_self(), 60);
-        } else {
-           tid = NULL;
-        }
-        if ((bopen(ofd, ofile, mode, 0)) < 0) {
-            Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), ofile, strerror(errno));
-           stop_thread_timer(tid);
-           return CF_ERROR;
-        }
-        stop_thread_timer(tid);
-        return CF_EXTRACT;
-      }
-      Dmsg1(200, "FT_SPEC %s\n", ofile);
-      return CF_CREATED;
 
    /* The following should not occur */
    case FT_NOACCESS:
@@ -235,3 +244,59 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname,
    }
    return CF_ERROR;
 }
+
+/*
+ *  Returns: > 0 index into path where last path char is.
+ *          0  no path
+ *          -1 filename is zero
+ */ 
+static int separate_path_and_file(void *jcr, char *fname, char *ofile)
+{
+   char *f, *p;
+   int fnl, pnl;
+
+   /* Separate pathname and filename */
+   for (p=f=ofile; *p; p++) {
+      if (*p == '/') {
+        f = p;                    /* possible filename */
+      }
+   }
+   if (*f == '/') {
+      f++;
+   }
+
+   fnl = p - f;
+   if (fnl == 0) {
+      /* The filename length must not be zero here because we
+       *  are dealing with a file (i.e. FT_REGE or FT_REG).
+       */
+      Jmsg1(jcr, M_ERROR, 0, _("Zero length filename: %s\n"), fname);
+      return -1;
+   }
+   pnl = f - ofile - 1;    
+   return pnl;
+}
+
+static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* 
+ * Primitive caching of path to prevent recreating a pathname 
+ *   each time as long as we remain in the same directory.
+ */
+static int path_already_seen(char *path, int pnl)
+{
+   static int cached_pnl = 0;
+   static char cached_path[1000];
+
+   P(mutex);
+   if (cached_pnl == pnl && strcmp(path, cached_path) == 0) {
+      V(mutex);
+      return 1;
+   }
+   if (pnl < (int)(sizeof(cached_path)-1)) {
+      strcpy(cached_path, path);
+      cached_pnl = pnl;
+   }
+   V(mutex);
+   return 0;
+}
index 8800e49827e9e39bdacc8886e93f8f74ff6547cd..4d1e4b2a1dbd9e40ff4dac0b8c95cd1bc37c1bdc 100755 (executable)
 #include <dirent.h>
 #define NAMELEN(dirent) (strlen((dirent)->d_name))
 #endif
+
 #include <sys/file.h>
+#if HAVE_UTIME_H
 #include <utime.h>
+#else
+struct utimbuf {
+    long actime;
+    long modtime;
+};
+#endif
 
 #define MODE_RALL (S_IRUSR|S_IRGRP|S_IROTH)
 
 
 #include "save-cwd.h"
 
+#ifndef HAVE_READDIR_R
+int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
+#endif
+
+
 /* 
  * Status codes returned by create_file()
  */
-#define CF_SKIP       1               /* skip file (not newer or something) */
-#define CF_ERROR      2               /* error creating file */
-#define CF_EXTRACT    3               /* file created, data to extract */
-#define CF_CREATED    4               /* file created, no data to extract */
+#define CF_SKIP       1              /* skip file (not newer or something) */
+#define CF_ERROR      2              /* error creating file */
+#define CF_EXTRACT    3              /* file created, data to extract */
+#define CF_CREATED    4              /* file created, no data to extract */
 
 /* 
  *  NOTE!!! These go on the tape, so don't change them. If 
  *  need be, add to them.
  */
-#define FT_LNKSAVED   1               /* hard link to file already saved */  
-#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_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_NOSTAT     9               /* Could not stat file */
-#define FT_NOCHG     10               /* Incremental option, file not changed */
-#define FT_DIRNOCHG  11               /* Incremental option, directory not changed */
-#define FT_ISARCH    12               /* Trying to save archive file */
-#define FT_NORECURSE 13               /* No recursion into directory */
-#define FT_NOFSCHG   14               /* Different file system, prohibited */
-#define FT_NOOPEN    15               /* Could not open directory */
-#define FT_RAW       16               /* Raw block device */
-#define FT_FIFO      17               /* Raw fifo device */
+#define FT_LNKSAVED   1              /* hard link to file already saved */  
+#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_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_NOSTAT     9              /* Could not stat file */
+#define FT_NOCHG     10              /* Incremental option, file not changed */
+#define FT_DIRNOCHG  11              /* Incremental option, directory not changed */
+#define FT_ISARCH    12              /* Trying to save archive file */
+#define FT_NORECURSE 13              /* No recursion into directory */
+#define FT_NOFSCHG   14              /* Different file system, prohibited */
+#define FT_NOOPEN    15              /* Could not open directory */
+#define FT_RAW      16               /* Raw block device */
+#define FT_FIFO      17              /* Raw fifo device */
 
 /* Options saved in "flag" of ff packet */
-#define FO_MD5          0x001         /* Do MD5 checksum */
-#define FO_GZIP         0x002         /* Do Zlib compression */
-#define FO_NO_RECURSION 0x004         /* no recursion in directories */
-#define FO_MULTIFS      0x008         /* multiple file systems */
-#define FO_SPARSE       0x010         /* do sparse file checking */
-#define FO_IF_NEWER     0x020         /* replace if newer */
-#define FO_NOREPLACE    0x040         /* never replace */
-#define FO_READFIFO     0x080         /* read data from fifo */
-#define FO_SHA1         0x100         /* Do SHA1 checksum */
+#define FO_MD5         0x001         /* Do MD5 checksum */
+#define FO_GZIP        0x002         /* Do Zlib compression */
+#define FO_NO_RECURSION 0x004        /* no recursion in directories */
+#define FO_MULTIFS     0x008         /* multiple file systems */
+#define FO_SPARSE      0x010         /* do sparse file checking */
+#define FO_IF_NEWER    0x020         /* replace if newer */
+#define FO_NOREPLACE   0x040         /* never replace */
+#define FO_READFIFO    0x080         /* read data from fifo */
+#define FO_SHA1        0x100         /* Do SHA1 checksum */
 
 /*
  * Options saved in "options" of include list
 #define OPT_compute_MD5       0x01    /* compute MD5 of file's data */
 #define OPT_GZIP_compression  0x02    /* use GZIP compression */
 #define OPT_no_recursion      0x04    /* no recursion in directories */
-#define OPT_multifs           0x08    /* multiple file systems */
-#define OPT_sparse            0x10    /* do sparse file checking */
+#define OPT_multifs          0x08    /* multiple file systems */
+#define OPT_sparse           0x10    /* do sparse file checking */
 #define OPT_replace_if_newer  0x20    /* replace file if newer */
 #define OPT_never_replace     0x40    /* never replace */
-#define OPT_read_fifo         0x80    /* read data from fifo (named pipe) */
+#define OPT_read_fifo        0x80    /* read data from fifo (named pipe) */
 #define OPT_compute_SHA1     0x100    /* compute SHA1 of file's data */
 
 
 struct s_included_file {
    struct s_included_file *next;
-   int options;                       /* backup options */
-   int level;                         /* compression level */
-   int len;                           /* length of fname */
-   int pattern;                       /* set if pattern */
-   char VerifyOpts[20];               /* Options for verify */
+   int options;                      /* backup options */
+   int level;                        /* compression level */
+   int len;                          /* length of fname */
+   int pattern;                      /* set if pattern */
+   char VerifyOpts[20];              /* Options for verify */
    char fname[1];
 };
 
@@ -121,7 +134,7 @@ struct s_excluded_file {
 };
 
 typedef struct s_bfile {
-   int fid;                           /* file id on Unix */
+   int fid;                          /* file id on Unix */
 } BFILE;
 
 
@@ -130,30 +143,30 @@ typedef struct s_bfile {
  * first argument to the find_files callback subroutine.
  */
 typedef struct s_ff {
-   char *fname;                       /* filename */
-   char *link;                        /* link if file linked */
-   POOLMEM *sys_fname;                /* system filename */
-   struct stat statp;                 /* stat packet */
-   uint32_t FileIndex;                /* FileIndex of this file */
-   uint32_t LinkFI;                   /* FileIndex of main hard linked file */
-   struct f_link *linked;             /* Set if we are hard linked */
-   int type;                          /* FT_ type from above */
-   int flags;                         /* control flags */
-   int ff_errno;                      /* errno */
-   int incremental;                   /* do incremental save */
-   BFILE bfd;                         /* Bacula file descriptor */
-   time_t save_time;                  /* start of incremental time */
-   int mtime_only;                    /* incremental on mtime_only */
-   int dereference;                   /* follow links */
-   int GZIP_level;                    /* compression level */
-   int atime_preserve;                /* preserve access times */
-   int null_output_device;            /* using null output device */
+   char *fname;                      /* filename */
+   char *link;                       /* link if file linked */
+   POOLMEM *sys_fname;               /* system filename */
+   struct stat statp;                /* stat packet */
+   uint32_t FileIndex;               /* FileIndex of this file */
+   uint32_t LinkFI;                  /* FileIndex of main hard linked file */
+   struct f_link *linked;            /* Set if we are hard linked */
+   int type;                         /* FT_ type from above */
+   int flags;                        /* control flags */
+   int ff_errno;                     /* errno */
+   int incremental;                  /* do incremental save */
+   BFILE bfd;                        /* Bacula file descriptor */
+   time_t save_time;                 /* start of incremental time */
+   int mtime_only;                   /* incremental on mtime_only */
+   int dereference;                  /* follow links */
+   int GZIP_level;                   /* compression level */
+   int atime_preserve;               /* preserve access times */
+   int null_output_device;           /* using null output device */
    char VerifyOpts[20];
    struct s_included_file *included_files_list;
    struct s_excluded_file *excluded_files_list;
    struct s_excluded_file *excluded_paths_list;
 
-   struct f_link *linklist;           /* hard linked files */
+   struct f_link *linklist;          /* hard linked files */
 } FF_PKT;
 
 
index 68525dc1ef6047b2c52c500b270f31f336fd511c..f08548ec7842d463810a06cb048345ad491a622e 100755 (executable)
 #include "bacula.h"
 #include "find.h"
 
-
 extern size_t name_max;              /* filename max length */
 extern size_t path_max;              /* path name max length */
 
-#ifndef HAVE_READDIR_R
-int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
-#endif
-
-
 /*
  * Structure for keeping track of hard linked files, we   
  *   keep an entry for each hardlinked file that we save,
@@ -53,17 +47,6 @@ struct f_link {
     char name[1];                    /* The name */
 };
 
-
-#if HAVE_UTIME_H
-# include <utime.h>
-#else
-struct utimbuf {
-    long actime;
-    long modtime;
-};
-#endif
-
-
 /*
  * Find a single file.                       
  * handle_file is the callback for handling the file.
@@ -89,10 +72,6 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
    }
 
    Dmsg1(60, "File ----: %s\n", fname);
-#ifdef DEBUG
-   if (S_ISLNK(ff_pkt->statp.st_mode))
-      Dmsg1(60, "Link-------------: %s \n", fname);
-#endif
 
    /* Save current times of this directory in case we need to
     * reset them because the user doesn't want them changed.
@@ -114,14 +93,11 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
              ff_pkt->statp.st_ctime < ff_pkt->save_time)) {
         /* Incremental option, file not changed */
         ff_pkt->type = FT_NOCHG;
-         Dmsg1(100, "File not changed: %s\n", ff_pkt->fname);
-         Dmsg4(200, "save_time=%d mtime=%d mtime_only=%d st_ctime=%d\n",
-           ff_pkt->save_time, ff_pkt->statp.st_mtime, 
-           ff_pkt->mtime_only, ff_pkt->statp.st_ctime);
         return handle_file(ff_pkt, pkt);
       }
    }
 
+/* ***FIXME*** implement this */
 #if xxxxxxx
    /* See if we are trying to dump the archive.  */
    if (ar_dev && ff_pkt->statp.st_dev == ar_dev && ff_pkt->statp.st_ino == ar_ino) {
@@ -188,11 +164,11 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       return rtn_stat;
 
 
-   } else if (S_ISLNK(ff_pkt->statp.st_mode)) {
+   } else if (S_ISLNK(ff_pkt->statp.st_mode)) {  /* soft link */
       int size;
-      char *buffer = (char *)alloca(path_max + name_max + 2);
+      char *buffer = (char *)alloca(path_max + name_max + 102);
 
-      size = readlink(fname, buffer, path_max + name_max + 1);
+      size = readlink(fname, buffer, path_max + name_max + 101);
       if (size < 0) {
         /* Could not follow link */                             
         ff_pkt->type = FT_NOFOLLOW;
@@ -204,8 +180,8 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
         return rtn_stat;
       }
       buffer[size] = 0;
-      ff_pkt->link = buffer;
-      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;
@@ -217,7 +193,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;
 
@@ -232,7 +208,7 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
         return rtn_stat;
       }
 
-      /* Build a canonical directory name with a trailing slash. */
+      /* Build a canonical directory name with a trailing slash in link var */
       len = strlen(fname);
       link_len = len + 200;
       link = (char *)bmalloc(link_len + 2);
@@ -252,11 +228,12 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       } else {
         ff_pkt->type = FT_DIR;
       }
-      handle_file(ff_pkt, pkt);       /* handle directory entry */
-      if (ff_pkt->linked) {
-        ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
-      }
-
+      FF_PKT *dir_ff_pkt;
+      dir_ff_pkt = (FF_PKT *)bmalloc(sizeof(FF_PKT));
+      memcpy(dir_ff_pkt, ff_pkt, sizeof(FF_PKT));
+      dir_ff_pkt->fname = bstrdup(ff_pkt->fname);
+      dir_ff_pkt->link = bstrdup(ff_pkt->link);
+       
       ff_pkt->link = ff_pkt->fname;     /* reset "link" */
 
       /* 
@@ -271,6 +248,9 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
         if (ff_pkt->linked) {
            ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
         }
+        free(dir_ff_pkt->fname);
+        free(dir_ff_pkt->link);
+        free(dir_ff_pkt);
         return rtn_stat;
       }
 
@@ -287,10 +267,13 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
         if (ff_pkt->linked) {
            ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
         }
+        free(dir_ff_pkt->fname);
+        free(dir_ff_pkt->link);
+        free(dir_ff_pkt);
         return rtn_stat;
       }
       /* 
-       * Now process the files in this directory.
+       * Open directory for reading files within 
        */
       errno = 0;
       if ((directory = opendir(fname)) == NULL) {
@@ -301,12 +284,16 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
         if (ff_pkt->linked) {
            ff_pkt->linked->FileIndex = ff_pkt->FileIndex;
         }
+        free(dir_ff_pkt->fname);
+        free(dir_ff_pkt->link);
+        free(dir_ff_pkt);
         return rtn_stat;
       }
 
       /*
-       * This would possibly run faster if we chdir to the directory
-       * before traversing it.
+       * Process all files in this directory entry (recursing).
+       *    This would possibly run faster if we chdir to the directory
+       *    before traversing it.
        */
       rtn_stat = 1;
       entry = (struct dirent *)malloc(sizeof(struct dirent) + name_max + 100);
@@ -315,8 +302,6 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
         int i;
 
         status  = readdir_r(directory, entry, &result);
-         Dmsg3(200, "readdir stat=%d result=%x name=%s\n", status, result,
-           entry->d_name);
         if (status != 0 || result == NULL) {
            break;
         }
@@ -348,6 +333,21 @@ find_one_file(JCR *jcr, FF_PKT *ff_pkt, int handle_file(FF_PKT *ff, void *hpkt),
       free(link);
       free(entry);
 
+      /*
+       * Now that we have recursed through all the files in the
+       *  directory, we "save" the directory so that after all
+       *  the files are restored, this entry will serve to reset
+       *  the directory modes and dates.  Temp directory values
+       *  were used without this record.
+       */
+      handle_file(dir_ff_pkt, pkt);      /* handle directory entry */
+      if (ff_pkt->linked) {
+        ff_pkt->linked->FileIndex = dir_ff_pkt->FileIndex;
+      }
+      free(dir_ff_pkt->fname);
+      free(dir_ff_pkt->link);
+      free(dir_ff_pkt);
+
       if (ff_pkt->atime_preserve) {
         utime(fname, &restore_times);
       }