]> wimlib.net Git - wimlib/blobdiff - src/add_image.c
unix_capture_directory(): Add missing ret=0
[wimlib] / src / add_image.c
index b50b05b55400c6c01fe6d0dac616118abd73ce4a..89721052d3a6156effd77fa1f07d873409312e3c 100644 (file)
@@ -146,6 +146,7 @@ unix_capture_directory(struct wim_dentry *dir_dentry,
        }
 
        /* Recurse on directory contents */
+       ret = 0;
        for (;;) {
                errno = 0;
                entry = readdir(dir);
@@ -256,11 +257,6 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret,
        struct wim_inode *inode;
 
        if (exclude_path(path, path_len, params->config, true)) {
-               if (params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) {
-                       ERROR("Cannot exclude the root directory from capture");
-                       ret = WIMLIB_ERR_INVALID_CAPTURE_CONFIG;
-                       goto out;
-               }
                if ((params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_EXCLUDE_VERBOSE)
                    && params->progress_func)
                {
@@ -388,7 +384,9 @@ unix_build_dentry_tree(struct wim_dentry **root_ret,
                        return WIMLIB_ERR_STAT;
                }
 
-               if (!S_ISDIR(root_stbuf.st_mode)) {
+               if ((params->add_image_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) &&
+                   !S_ISDIR(root_stbuf.st_mode))
+               {
                        ERROR("Root of capture \"%s\" is not a directory",
                              root_disk_path);
                        return WIMLIB_ERR_NOTDIR;
@@ -623,9 +621,7 @@ new_filler_directory(const tchar *name, struct wim_dentry **dentry_ret)
        return ret;
 }
 
-/* Transfers the children of @branch to @target.  It is an error if @target is
- * not a directory or if both @branch and @target contain a child dentry with
- * the same name. */
+/* Overlays @branch onto @target, both of which must be directories. */
 static int
 do_overlay(struct wim_dentry *target, struct wim_dentry *branch)
 {
@@ -634,30 +630,36 @@ do_overlay(struct wim_dentry *target, struct wim_dentry *branch)
        DEBUG("Doing overlay \"%"WS"\" => \"%"WS"\"",
              branch->file_name, target->file_name);
 
-       if (!dentry_is_directory(target)) {
-               ERROR("Cannot overlay directory \"%"WS"\" "
-                     "over non-directory", branch->file_name);
+       if (!dentry_is_directory(branch) || !dentry_is_directory(target)) {
+               ERROR("Cannot overlay \"%"WS"\" onto existing dentry: "
+                     "is not directory-on-directory!", branch->file_name);
                return WIMLIB_ERR_INVALID_OVERLAY;
        }
 
        rb_root = &branch->d_inode->i_children;
        while (rb_root->rb_node) { /* While @branch has children... */
                struct wim_dentry *child = rbnode_dentry(rb_root->rb_node);
+               struct wim_dentry *existing;
+
                /* Move @child to the directory @target */
                unlink_dentry(child);
-               if (!dentry_add_child(target, child)) {
-                       /* Revert the change to avoid leaking the directory tree
-                        * rooted at @child */
-                       dentry_add_child(branch, child);
-                       ERROR("Overlay error: file \"%"WS"\" already exists "
-                             "as a child of \"%"WS"\"",
-                             child->file_name, target->file_name);
-                       return WIMLIB_ERR_INVALID_OVERLAY;
+               existing = dentry_add_child(target, child);
+
+               /* File or directory with same name already exists */
+               if (existing) {
+                       int ret;
+                       ret = do_overlay(existing, child);
+                       if (ret) {
+                               /* Overlay failed.  Revert the change to avoid
+                                * leaking the directory tree rooted at @child.
+                                * */
+                               dentry_add_child(branch, child);
+                               return ret;
+                       }
                }
        }
        free_dentry(branch);
        return 0;
-
 }
 
 /* Attach or overlay a branch onto the WIM image.