}
}
#endif
- Dmsg3(200, "Create %s Replace=%c FT=%d\n", attr->ofname, (char)replace, attr->type);
+
+ Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
if (lstat(attr->ofname, &mstatp) == 0) {
exists = true;
- /*
- * For directories we do not apply the replace options, because
- * we must always create directories that do not exist, and thus
- * when the directory end record comes, the directory exists. So
- * we always apply the FT_DIREND record for directories.
- */
- if (attr->type != FT_DIREND) {
- switch (replace) {
- case REPLACE_IFNEWER:
- if (attr->statp.st_mtime <= mstatp.st_mtime) {
- Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
- return CF_SKIP;
- }
- break;
-
- case REPLACE_IFOLDER:
- if (attr->statp.st_mtime >= mstatp.st_mtime) {
- Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
- return CF_SKIP;
- }
- break;
+ switch (replace) {
+ case REPLACE_IFNEWER:
+ if (attr->statp.st_mtime <= mstatp.st_mtime) {
+ Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not newer: %s\n"), attr->ofname);
+ return CF_SKIP;
+ }
+ break;
- case REPLACE_NEVER:
- Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
+ case REPLACE_IFOLDER:
+ if (attr->statp.st_mtime >= mstatp.st_mtime) {
+ Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Not older: %s\n"), attr->ofname);
return CF_SKIP;
+ }
+ break;
- case REPLACE_ALWAYS:
+ case REPLACE_NEVER:
+ /* Set attributes if we created this directory */
+ if (attr->type == FT_DIREND && path_list_lookup(jcr, attr->ofname)) {
break;
}
+ Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
+ return CF_SKIP;
+
+ case REPLACE_ALWAYS:
+ break;
}
}
switch (attr->type) {
attr->ofname[pnl] = 0; /* terminate path */
if (!path_already_seen(jcr, attr->ofname, pnl)) {
+ Dmsg1(400, "Make path %s\n", attr->ofname);
/*
* 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.
*/
- Dmsg1(400, "makepath %s\n", attr->ofname);
if (!makepath(attr, attr->ofname, parent_mode, parent_mode, uid, gid, 1)) {
Dmsg1(10, "Could not make path. %s\n", attr->ofname);
attr->ofname[pnl] = savechr; /* restore full name */
ff->strip_path = fo->strip_path;
ff->fstypes = fo->fstype;
ff->drivetypes = fo->drivetype;
+ ff->plugin = fo->plugin; /* TODO: generate a plugin event ? */
+ ff->opt_plugin = (ff->plugin != NULL)? true : false;
bstrncat(ff->VerifyOpts, fo->VerifyOpts, sizeof(ff->VerifyOpts));
if (fo->AccurateOpts[0]) {
bstrncpy(ff->AccurateOpts, fo->AccurateOpts, sizeof(ff->AccurateOpts));
char VerifyOpts[MAX_FOPTS]; /* verify options */
char AccurateOpts[MAX_FOPTS]; /* accurate mode options */
char BaseJobOpts[MAX_FOPTS]; /* basejob mode options */
+ char *plugin; /* Plugin that handle this section */
alist regex; /* regex string(s) */
alist regexdir; /* regex string(s) for directories */
alist regexfile; /* regex string(s) for files */
char *link; /* link if file linked */
char *object_name; /* Object name */
char *object; /* restore object */
+ char *plugin; /* Current Options{Plugin=} name */
POOLMEM *sys_fname; /* system filename */
POOLMEM *fname_save; /* save when stripping path */
POOLMEM *link_save; /* save when stripping path */
int Compress_level; /* compression level */
int strip_path; /* strip path count */
bool cmd_plugin; /* set if we have a command plugin */
+ bool opt_plugin; /* set if we have an option plugin */
alist fstypes; /* allowed file system types */
alist drivetypes; /* allowed drive types */
#include "bacula.h"
#include "jcr.h"
+#define dbglvl 50
+
+typedef struct PrivateCurDir {
+ hlink link;
+ char fname[1];
+} CurDir;
+
+/* Initialize the path hash table */
+static bool path_list_init(JCR *jcr)
+{
+ CurDir *elt = NULL;
+ jcr->path_list = (htable *)malloc(sizeof(htable));
+
+ /* Hard to know in advance how many directories will
+ * be stored in this hash
+ */
+ jcr->path_list->init(elt, &elt->link, 10000);
+ return true;
+}
+
+/* Add a path to the hash when we create a directory
+ * with the replace=NEVER option
+ */
+bool path_list_add(JCR *jcr, uint32_t len, char *fname)
+{
+ bool ret = true;
+ CurDir *item;
+
+ if (!jcr->path_list) {
+ path_list_init(jcr);
+ }
+
+ /* we store CurDir, fname in the same chunk */
+ item = (CurDir *)jcr->path_list->hash_malloc(sizeof(CurDir)+len+1);
+
+ memset(item, 0, sizeof(CurDir));
+ memcpy(item->fname, fname, len+1);
+
+ jcr->path_list->insert(item->fname, item);
+
+ Dmsg1(dbglvl, "add fname=<%s>\n", fname);
+ return ret;
+}
+
+void free_path_list(JCR *jcr)
+{
+ if (jcr->path_list) {
+ jcr->path_list->destroy();
+ free(jcr->path_list);
+ jcr->path_list = NULL;
+ }
+}
+
+bool path_list_lookup(JCR *jcr, char *fname)
+{
+ bool found=false;
+ char bkp;
+
+ if (!jcr->path_list) {
+ return false;
+ }
+
+ /* Strip trailing / */
+ int len = strlen(fname);
+ if (len == 0) {
+ return false;
+ }
+ len--;
+ bkp = fname[len];
+ if (fname[len] == '/') { /* strip any trailing slash */
+ fname[len] = 0;
+ }
+
+ CurDir *temp = (CurDir *)jcr->path_list->lookup(fname);
+ if (temp) {
+ found=true;
+ }
+
+ Dmsg2(dbglvl, "lookup <%s> %s\n", fname, found?"ok":"not ok");
+
+ fname[len] = bkp; /* restore last / */
+ return found;
+}
+
static bool makedir(JCR *jcr, char *path, mode_t mode, int *created)
{
struct stat statp;
}
return true; /* directory exists */
}
+
+ if (jcr->keep_path_list) {
+ /* When replace=NEVER, we keep track of all directories newly created */
+ path_list_add(jcr, strlen(path), path);
+ }
+
*created = true;
return true;
}
if (!makedir(jcr, path, tmode, &created)) {
goto bail_out;
}
- Dmsg2(400, "makedir: created=%d %s\n", created, path);
if (ndir < max_dirs) {
new_dir[ndir++] = created;
}
if (!makedir(jcr, path, tmode, &created)) {
goto bail_out;
}
- Dmsg2(400, "makedir: created=%d %s\n", created, path);
if (ndir < max_dirs) {
new_dir[ndir++] = created;
}
/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
/*
* Prototypes for finlib directory of Bacula
*
- * Version $Id$
*/
/* from attribs.c */
bool makepath(ATTR *attr, const char *path, mode_t mode,
mode_t parent_mode, uid_t owner, gid_t group,
int keep_dir_modes);
+void free_path_list(JCR *jcr);
+bool path_list_lookup(JCR *jcr, char *fname);
+bool path_list_add(JCR *jcr, uint32_t len, char *fname);
+
/* from fstype.c */
bool fstype(const char *fname, char *fs, int fslen);