]> git.sur5r.net Git - bacula/bacula/commitdiff
Ignore replace=xx for directories. Corrects (not total solution) ticket 2317 and...
authorKern Sibbald <kern@sibbald.com>
Wed, 12 Jan 2011 17:49:37 +0000 (18:49 +0100)
committerKern Sibbald <kern@sibbald.com>
Sat, 20 Apr 2013 12:39:49 +0000 (14:39 +0200)
bacula/src/findlib/create_file.c
bacula/src/findlib/mkpath.c

index e4f6920054970b8fc34dc96e7c7d4212de162ac9..6a4fddd5683d9a21f286a5b2d97cc37321ad1146 100644 (file)
@@ -1,7 +1,7 @@
 /*
    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.
@@ -114,31 +114,38 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
       }
    }
 #endif
-
-   Dmsg2(400, "Replace=%c %d\n", (char)replace, replace);
+   Dmsg3(200, "Create %s Replace=%c FT=%d\n", attr->ofname, (char)replace, attr->type);
    if (lstat(attr->ofname, &mstatp) == 0) {
       exists = true;
-      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;
+      /*
+       * 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;
+         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_NEVER:
-         Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
-         return CF_SKIP;
+         case REPLACE_NEVER:
+            Qmsg(jcr, M_SKIPPED, 0, _("File skipped. Already exists: %s\n"), attr->ofname);
+            return CF_SKIP;
 
-      case REPLACE_ALWAYS:
-         break;
+         case REPLACE_ALWAYS:
+            break;
+         }
       }
    }
    switch (attr->type) {
@@ -186,12 +193,12 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
          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 */
@@ -226,7 +233,7 @@ int create_file(JCR *jcr, ATTR *attr, BFILE *bfd, int replace)
          }
          return CF_EXTRACT;
 
-#ifndef HAVE_WIN32  // none of these exists on MS Windows
+#ifndef HAVE_WIN32  // none of these exist in MS Windows
       case FT_RAW:                    /* Bacula raw device e.g. /dev/sda1 */
       case FT_FIFO:                   /* Bacula fifo to save data */
       case FT_SPEC:
index 0c39a42b1b172b4f594a02efd7b0dfca9e6449bc..4e4dfb57b357101a256cfbe35f382a27aa6f89f0 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2007-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.
  *  This is tricky code, especially when writing from scratch. Fortunately,
  *    a non-copyrighted version of mkdir was available to consult.
  *
- *  Version $Id$
+ * ***FIXME*** the mkpath code could be significantly optimized by
+ *   walking up the path chain from the bottom until it either gets
+ *   to the top or finds an existing directory then walk back down
+ *   creating the path components.  Currently, it always starts at
+ *   the top, which can be rather inefficient for long path names.
+ *
  */
 #include "bacula.h"
 #include "jcr.h"
@@ -169,6 +174,7 @@ bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode,
       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;
       }
@@ -181,6 +187,7 @@ bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode,
    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;
    }