]> wimlib.net Git - wimlib/blobdiff - src/unix_capture.c
wimlib-imagex: Allow specifying LZMS compression
[wimlib] / src / unix_capture.c
index 4164a6246bf066ade122dabade0f4d1b77bca071..d16eae6d367105ae4ec16c9efe72ba397330213a 100644 (file)
 
 #ifndef __WIN32__
 
-#include "wimlib_internal.h"
-#include "dentry.h"
-#include "lookup_table.h"
-#include "timestamp.h"
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
 
 #include <dirent.h>
 #include <errno.h>
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "wimlib/capture.h"
+#include "wimlib/dentry.h"
+#include "wimlib/error.h"
+#include "wimlib/lookup_table.h"
+#include "wimlib/paths.h"
+#include "wimlib/reparse.h"
+#include "wimlib/timestamp.h"
+
 static int
 unix_capture_regular_file(const char *path,
                          u64 size,
@@ -57,7 +64,7 @@ unix_capture_regular_file(const char *path,
                }
                lte->file_on_disk = file_on_disk;
                lte->resource_location = RESOURCE_IN_FILE_ON_DISK;
-               lte->resource_entry.original_size = size;
+               lte->size = size;
                lookup_table_insert_unhashed(lookup_table, lte, inode, 0);
                inode->i_lte = lte;
        }
@@ -138,12 +145,9 @@ unix_capture_symlink(struct wim_dentry **root_p,
        inode->i_attributes = FILE_ATTRIBUTE_REPARSE_POINT;
        inode->i_reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK;
 
-       /* The idea here is to call readlink() to get the UNIX target of
-        * the symbolic link, then turn the target into a reparse point
-        * data buffer that contains a relative or absolute symbolic
-        * link (NOT a junction point or *full* path symbolic link with
-        * drive letter).
-        */
+       /* The idea here is to call readlink() to get the UNIX target of the
+        * symbolic link, then turn the target into a reparse point data buffer
+        * that contains a relative or absolute symbolic link. */
        deref_name_len = readlink(path, deref_name_buf,
                                  sizeof(deref_name_buf) - 1);
        if (deref_name_len >= 0) {
@@ -197,30 +201,17 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret,
                                 struct add_image_params *params)
 {
        struct wim_dentry *root = NULL;
-       int ret = 0;
+       int ret;
        struct wim_inode *inode;
 
+       params->progress.scan.cur_path = path;
+
        if (exclude_path(path, path_len, params->config, true)) {
-               if ((params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE)
-                   && params->progress_func)
-               {
-                       union wimlib_progress_info info;
-                       info.scan.cur_path = path;
-                       info.scan.excluded = true;
-                       params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
-               }
+               do_capture_progress(params, WIMLIB_SCAN_DENTRY_EXCLUDED);
+               ret = 0;
                goto out;
        }
 
-       if ((params->add_flags & WIMLIB_ADD_FLAG_VERBOSE)
-           && params->progress_func)
-       {
-               union wimlib_progress_info info;
-               info.scan.cur_path = path;
-               info.scan.excluded = false;
-               params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, &info);
-       }
-
        struct stat stbuf;
        int (*stat_fn)(const char *restrict, struct stat *restrict);
        if ((params->add_flags & WIMLIB_ADD_FLAG_DEREFERENCE) ||
@@ -237,12 +228,19 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret,
        }
        if (!S_ISREG(stbuf.st_mode) && !S_ISDIR(stbuf.st_mode)
            && !S_ISLNK(stbuf.st_mode)) {
-               ERROR("`%s' is not a regular file, directory, or symbolic link.",
-                     path);
-               ret = WIMLIB_ERR_SPECIAL_FILE;
+               if (params->add_flags & WIMLIB_ADD_FLAG_NO_UNSUPPORTED_EXCLUDE)
+               {
+                       ERROR("Can't archive unsupported file \"%s\"", path);
+                       ret = WIMLIB_ERR_UNSUPPORTED_FILE;
+                       goto out;
+               }
+               do_capture_progress(params, WIMLIB_SCAN_DENTRY_UNSUPPORTED);
+               ret = 0;
                goto out;
        }
 
+       do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK);
+
        ret = inode_table_new_dentry(&params->inode_table,
                                     path_basename_with_len(path, path_len),
                                     stbuf.st_ino, stbuf.st_dev, false, &root);
@@ -251,8 +249,11 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret,
 
        inode = root->d_inode;
 
-       if (inode->i_nlink > 1) /* Already captured this inode? */
+       if (inode->i_nlink > 1) {
+               /* Already captured this inode? */
+               ret = 0;
                goto out;
+       }
 
 #ifdef HAVE_STAT_NANOSECOND_PRECISION
        inode->i_creation_time = timespec_to_wim_timestamp(stbuf.st_mtim);
@@ -281,18 +282,22 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret,
                ret = unix_capture_directory(root, path, path_len, params);
        else
                ret = unix_capture_symlink(&root, path, inode, params);
+
+       if (ret)
+               goto out;
+
 out:
-       if (ret == 0)
-               *root_ret = root;
-       else
+       if (ret)
                free_dentry_tree(root, params->lookup_table);
+       else
+               *root_ret = root;
        return ret;
 }
 
 /*
  * unix_build_dentry_tree():
- *     Builds a tree of WIM dentries from an on-disk directory tree (UNIX
- *     version; no NTFS-specific data is captured).
+ *     Builds a tree of WIM dentries from an on-disk directory tree (UNIX
+ *     version; no NTFS-specific data is captured).
  *
  * @root_ret:   Place to return a pointer to the root of the dentry tree.  Only
  *             modified if successful.  Set to NULL if the file or directory was
@@ -343,7 +348,7 @@ unix_build_dentry_tree(struct wim_dentry **root_ret,
        if (path_len >= path_bufsz)
                return WIMLIB_ERR_INVALID_PARAM;
 
-       path_buf = MALLOC(path_bufsz);
+       path_buf = MALLOC(path_bufsz);
        if (!path_buf)
                return WIMLIB_ERR_NOMEM;
        memcpy(path_buf, root_disk_path, path_len + 1);