X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fcapture_common.c;h=419786120f746c48a6962e44e894addc9ff31cb6;hb=f5725c14ca24988b9d8c3ad9b67c63135cdabc51;hp=ef4fa5d63f1d1bd52ba47930dccf0987b19a18c1;hpb=bb40342796df9c677f6903b596abf4e9e5769845;p=wimlib diff --git a/src/capture_common.c b/src/capture_common.c index ef4fa5d6..41978612 100644 --- a/src/capture_common.c +++ b/src/capture_common.c @@ -1,3 +1,7 @@ +/* + * capture_common.c - Mostly code to handle excluding paths from capture. + */ + /* * Copyright (C) 2013 Eric Biggers * @@ -17,35 +21,38 @@ * along with wimlib; if not, see http://www.gnu.org/licenses/. */ -#include "wimlib_internal.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -#include +#include "wimlib/assert.h" +#include "wimlib/capture.h" +#include "wimlib/dentry.h" +#include "wimlib/error.h" +#include "wimlib/lookup_table.h" +#include "wimlib/paths.h" +#include "wimlib/wildcard.h" -#ifdef __WIN32__ -# include "win32.h" -#else -# include -#endif +#include static int -canonicalize_pat(tchar **pat_p) +canonicalize_pattern(const tchar *pat, tchar **canonical_pat_ret) { - tchar *pat = *pat_p; - - /* Turn all backslashes in the pattern into forward slashes. */ - zap_backslashes(pat); + tchar *canonical_pat; - if (*pat != T('/') && *pat != T('\0') && *(pat + 1) == T(':')) { + if (!is_any_path_separator(pat[0]) && + pat[0] != T('\0') && pat[1] == T(':')) + { /* Pattern begins with drive letter */ - if (*(pat + 2) != T('/')) { + if (!is_any_path_separator(pat[2])) { /* Something like c:file, which is actually a path * relative to the current working directory on the c: * drive. We require paths with drive letters to be * absolute. */ ERROR("Invalid path \"%"TS"\"; paths including drive letters " "must be absolute!", pat); - ERROR("Maybe try \"%"TC":/%"TS"\"?", - *pat, pat + 2); + ERROR("Maybe try \"%"TC":\\%"TS"\"?", + pat[0], pat + 2); return WIMLIB_ERR_INVALID_CAPTURE_CONFIG; } @@ -53,17 +60,32 @@ canonicalize_pat(tchar **pat_p) "being removed.", pat); /* Strip the drive letter */ pat += 2; - *pat_p = pat; } + canonical_pat = canonicalize_fs_path(pat); + if (!canonical_pat) + return WIMLIB_ERR_NOMEM; + + /* Translate all possible path separators into the operating system's + * preferred path separator. */ + for (tchar *p = canonical_pat; *p; p++) + if (is_any_path_separator(*p)) + *p = OS_PREFERRED_PATH_SEPARATOR; + *canonical_pat_ret = canonical_pat; return 0; } static int -canonicalize_pat_list(struct wimlib_pattern_list *pat_list) +copy_and_canonicalize_pattern_list(const struct wimlib_pattern_list *list, + struct wimlib_pattern_list *copy) { int ret = 0; - for (size_t i = 0; i < pat_list->num_pats; i++) { - ret = canonicalize_pat(&pat_list->pats[i]); + + copy->pats = CALLOC(list->num_pats, sizeof(list->pats[0])); + if (!copy->pats) + return WIMLIB_ERR_NOMEM; + copy->num_pats = list->num_pats; + for (size_t i = 0; i < list->num_pats; i++) { + ret = canonicalize_pattern(list->pats[i], ©->pats[i]); if (ret) break; } @@ -71,49 +93,31 @@ canonicalize_pat_list(struct wimlib_pattern_list *pat_list) } int -canonicalize_capture_config(struct wimlib_capture_config *config) +copy_and_canonicalize_capture_config(const struct wimlib_capture_config *config, + struct wimlib_capture_config **config_copy_ret) { - int ret = canonicalize_pat_list(&config->exclusion_pats); - if (ret) - return ret; - return canonicalize_pat_list(&config->exclusion_exception_pats); -} + struct wimlib_capture_config *config_copy; + int ret; -static bool -copy_pattern_list(struct wimlib_pattern_list *copy, - const struct wimlib_pattern_list *list) -{ - copy->pats = CALLOC(list->num_pats, sizeof(list->pats[0])); - if (!copy->pats) - return false; - copy->num_pats = list->num_pats; - for (size_t i = 0; i < list->num_pats; i++) { - copy->pats[i] = TSTRDUP(list->pats[i]); - if (!copy->pats[i]) - return false; + config_copy = CALLOC(1, sizeof(struct wimlib_capture_config)); + if (!config_copy) { + ret = WIMLIB_ERR_NOMEM; + goto out_free_capture_config; } - return true; -} - -struct wimlib_capture_config * -copy_capture_config(const struct wimlib_capture_config *config) -{ - struct wimlib_capture_config *copy; - - copy = CALLOC(1, sizeof(struct wimlib_capture_config)); - if (!copy) - goto oom; - if (!copy_pattern_list(©->exclusion_pats, &config->exclusion_pats)) - goto oom; - if (!copy_pattern_list(©->exclusion_exception_pats, - &config->exclusion_exception_pats)) - goto oom; + ret = copy_and_canonicalize_pattern_list(&config->exclusion_pats, + &config_copy->exclusion_pats); + if (ret) + goto out_free_capture_config; + ret = copy_and_canonicalize_pattern_list(&config->exclusion_exception_pats, + &config_copy->exclusion_exception_pats); + if (ret) + goto out_free_capture_config; + *config_copy_ret = config_copy; goto out; -oom: - free_capture_config(copy); - copy = NULL; +out_free_capture_config: + free_capture_config(config_copy); out: - return copy; + return ret; } static void @@ -144,11 +148,11 @@ match_pattern(const tchar *path, const tchar *pat = list->pats[i]; const tchar *string; - if (*pat == T('/')) { + if (*pat == OS_PREFERRED_PATH_SEPARATOR) { /* Absolute path from root of capture */ string = path; } else { - if (tstrchr(pat, T('/'))) + if (tstrchr(pat, OS_PREFERRED_PATH_SEPARATOR)) /* Relative path from root of capture */ string = path + 1; else @@ -160,21 +164,51 @@ match_pattern(const tchar *path, * replacement function in win32.c. */ if (fnmatch(pat, string, FNM_PATHNAME | FNM_NOESCAPE #ifdef FNM_CASEFOLD - | FNM_CASEFOLD + | FNM_CASEFOLD #endif ) == 0) { DEBUG("\"%"TS"\" matches the pattern \"%"TS"\"", string, pat); return true; - } else { - DEBUG2("\"%"TS"\" does not match the pattern \"%"TS"\"", - string, pat); } } return false; } +void +do_capture_progress(struct add_image_params *params, int status, + const struct wim_inode *inode) +{ + switch (status) { + case WIMLIB_SCAN_DENTRY_OK: + if (!(params->add_flags & WIMLIB_ADD_FLAG_VERBOSE)) + return; + case WIMLIB_SCAN_DENTRY_UNSUPPORTED: + case WIMLIB_SCAN_DENTRY_EXCLUDED: + case WIMLIB_SCAN_DENTRY_EXCLUDED_SYMLINK: + if (!(params->add_flags & WIMLIB_ADD_FLAG_EXCLUDE_VERBOSE)) + return; + } + params->progress.scan.status = status; + if (status == WIMLIB_SCAN_DENTRY_OK && inode->i_nlink == 1) { + const struct wim_lookup_table_entry *lte; + for (unsigned i = 0; i <= inode->i_num_ads; i++) { + lte = inode_stream_lte_resolved(inode, i); + if (lte != NULL) + params->progress.scan.num_bytes_scanned += lte->size; + } + if (inode->i_attributes & FILE_ATTRIBUTE_DIRECTORY) + params->progress.scan.num_dirs_scanned++; + else + params->progress.scan.num_nondirs_scanned++; + } + if (params->progress_func) { + params->progress_func(WIMLIB_PROGRESS_MSG_SCAN_DENTRY, + ¶ms->progress); + } +} + /* Return true if the image capture configuration file indicates we should * exclude the filename @path from capture. * @@ -188,11 +222,13 @@ bool exclude_path(const tchar *path, size_t path_len, const struct wimlib_capture_config *config, bool exclude_prefix) { + if (!config) + return false; const tchar *basename = path_basename_with_len(path, path_len); if (exclude_prefix) { wimlib_assert(path_len >= config->_prefix_num_tchars); if (!tmemcmp(config->_prefix, path, config->_prefix_num_tchars) && - path[config->_prefix_num_tchars] == T('/')) + path[config->_prefix_num_tchars] == OS_PREFERRED_PATH_SEPARATOR) { path += config->_prefix_num_tchars; }