#include "bacula.h"
#include "find.h"
-extern size_t name_max; /* filename max length */
-extern size_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
char name[1]; /* The name */
};
+static void free_dir_ff_pkt(FF_PKT *dir_ff_pkt)
+{
+ free(dir_ff_pkt->fname);
+ free(dir_ff_pkt->link);
+ free_pool_memory(dir_ff_pkt->sys_fname);
+ free(dir_ff_pkt);
+}
+
/*
* Find a single file.
* handle_file is the callback for handling the file.
return handle_file(ff_pkt, pkt);
}
- Dmsg1(60, "File ----: %s\n", fname);
+ Dmsg1(300, "File ----: %s\n", fname);
/* Save current times of this directory in case we need to
* reset them because the user doesn't want them changed.
* or Incremental.
*/
if (ff_pkt->incremental && !S_ISDIR(ff_pkt->statp.st_mode)) {
- Dmsg1(100, "Non-directory incremental: %s\n", ff_pkt->fname);
+ 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->mtime_only ||
int status;
dev_t our_device = ff_pkt->statp.st_dev;
- 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;
+ /*
+ * If we are using Win32 (non-portable) backup API, don't check
+ * access as everything is more complicated, and
+ * 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;
}
- return rtn_stat;
}
/* Build a canonical directory name with a trailing slash in link var */
} else {
ff_pkt->type = FT_DIR;
}
- FF_PKT *dir_ff_pkt;
- dir_ff_pkt = (FF_PKT *)bmalloc(sizeof(FF_PKT));
+
+ /*
+ * Create a temporary ff packet for this directory
+ * entry, and defer handling the directory until
+ * we have recursed into it. This saves the
+ * directory after all files have been processed, and
+ * during the restore, the directory permissions will
+ * be reset after all the files have been restored.
+ */
+ Dmsg1(300, "Create temp ff packet for dir: %s\n", ff_pkt->fname);
+ 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);
+ dir_ff_pkt->sys_fname = get_pool_memory(PM_FNAME);
+ dir_ff_pkt->included_files_list = NULL;
+ 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" */
* user has turned it off for this directory.
*/
if (ff_pkt->flags & FO_NO_RECURSION) {
- free(link);
/* 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(dir_ff_pkt->fname);
- free(dir_ff_pkt->link);
- free(dir_ff_pkt);
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
return rtn_stat;
}
*/
if (!top_level && !(ff_pkt->flags & FO_MULTIFS) &&
parent_device != ff_pkt->statp.st_dev) {
- free(link);
/* 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(dir_ff_pkt->fname);
- free(dir_ff_pkt->link);
- free(dir_ff_pkt);
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
return rtn_stat;
}
/*
- * Open directory for reading files within
+ * Decend into or "recurse" into the directory to read
+ * all the files in it.
*/
errno = 0;
if ((directory = opendir(fname)) == NULL) {
- free(link);
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(dir_ff_pkt->fname);
- free(dir_ff_pkt->link);
- free(dir_ff_pkt);
+ free(link);
+ free_dir_ff_pkt(dir_ff_pkt);
return rtn_stat;
}
if (status != 0 || result == NULL) {
break;
}
- ASSERT(name_max+1 > sizeof(struct dirent) + (int)NAMELEN(entry));
+ 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' ||
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);
+ free_dir_ff_pkt(dir_ff_pkt);
if (ff_pkt->atime_preserve) {
utime(fname, &restore_times);
* a block device, we do a raw backup of it or if it is
* a fifo, we simply read it.
*/
+#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.
+ * 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
+ */
+ if (top_level && (S_ISBLK(ff_pkt->statp.st_mode) || S_ISCHR(ff_pkt->statp.st_mode))) {
+#else
if (top_level && S_ISBLK(ff_pkt->statp.st_mode)) {
+#endif
ff_pkt->type = FT_RAW; /* raw partition */
} else if (top_level && S_ISFIFO(ff_pkt->statp.st_mode) &&
ff_pkt->flags & FO_READFIFO) {