X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Funix_capture.c;h=d16eae6d367105ae4ec16c9efe72ba397330213a;hp=4f526f7dda1029815a5cfd553458b83b38dc7696;hb=a6e50e8eb32035d44c94fd63bfae6c3de7481055;hpb=143db75c035e6ecaca451ce70a4ed58a01102b43 diff --git a/src/unix_capture.c b/src/unix_capture.c index 4f526f7d..d16eae6d 100644 --- a/src/unix_capture.c +++ b/src/unix_capture.c @@ -1,5 +1,9 @@ /* - * Copyright (C) 2013 Eric Biggers + * unix_capture.c: Capture a directory tree on UNIX. + */ + +/* + * Copyright (C) 2012, 2013 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * @@ -19,15 +23,23 @@ #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 #include -#include +#include #include +#include + +#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, @@ -52,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; } @@ -82,7 +94,7 @@ unix_capture_directory(struct wim_dentry *dir_dentry, if (!dir) { ERROR_WITH_ERRNO("Failed to open the directory `%s'", path); - return WIMLIB_ERR_OPEN; + return WIMLIB_ERR_OPENDIR; } /* Recurse on directory contents */ @@ -133,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) { @@ -192,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) || @@ -225,19 +221,27 @@ unix_build_dentry_tree_recursive(struct wim_dentry **root_ret, stat_fn = lstat; ret = (*stat_fn)(path, &stbuf); - if (ret != 0) { + if (ret) { ERROR_WITH_ERRNO("Failed to stat `%s'", path); + ret = WIMLIB_ERR_STAT; goto out; } 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; } - ret = inode_table_new_dentry(params->inode_table, + do_capture_progress(params, WIMLIB_SCAN_DENTRY_OK); + + ret = inode_table_new_dentry(¶ms->inode_table, path_basename_with_len(path, path_len), stbuf.st_ino, stbuf.st_dev, false, &root); if (ret) @@ -245,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); @@ -275,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 @@ -337,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);