From: Kern Sibbald Date: Sun, 13 Apr 2003 14:47:31 +0000 (+0000) Subject: Fix directory times, modes on restore X-Git-Tag: Release-1.30~29 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=cc05c945351c855c74656db03fb804cb7c0008c6;p=bacula%2Fbacula Fix directory times, modes on restore git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@438 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index 2169ad0343..bca0d9f29b 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -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; +} diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 8800e49827..4d1e4b2a1d 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -32,8 +32,16 @@ #include #define NAMELEN(dirent) (strlen((dirent)->d_name)) #endif + #include +#if HAVE_UTIME_H #include +#else +struct utimbuf { + long actime; + long modtime; +}; +#endif #define MODE_RALL (S_IRUSR|S_IRGRP|S_IROTH) @@ -45,46 +53,51 @@ #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 @@ -96,21 +109,21 @@ #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; diff --git a/bacula/src/findlib/find_one.c b/bacula/src/findlib/find_one.c index 68525dc1ef..f08548ec78 100755 --- a/bacula/src/findlib/find_one.c +++ b/bacula/src/findlib/find_one.c @@ -28,15 +28,9 @@ #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 -#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); }