X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fcapture_common.c;h=35aaee69a789724584b6d5f1cc8e55eca4e3e1bf;hp=0a6ba44d2b98ea7f3c3a1be58e5b9ee889c97dc7;hb=0230cefb4cee3580a705364232feb72258994237;hpb=ebe0206c700963ee0ace86cc55fca6570b03cac3 diff --git a/src/capture_common.c b/src/capture_common.c index 0a6ba44d..35aaee69 100644 --- a/src/capture_common.c +++ b/src/capture_common.c @@ -27,130 +27,128 @@ #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/textfile.h" +#include "wimlib/wildcard.h" -#ifdef __WIN32__ -# include "wimlib/win32.h" /* for fnmatch() equivalent */ -#else -# include -#endif #include +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); + } +} static int -canonicalize_pattern(const tchar *pat, tchar **canonical_pat_ret) +mangle_pat(tchar *pat, const tchar *path, unsigned long line_no) { - tchar *canonical_pat; - - if (pat[0] != T('/') && pat[0] != T('\\') && + if (!is_any_path_separator(pat[0]) && pat[0] != T('\0') && pat[1] == T(':')) { /* Pattern begins with drive letter */ - if (pat[2] != T('/') && 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[0], pat + 2); + ERROR("%"TS":%lu: Invalid path \"%"TS"\"; paths including " + "drive letters must be absolute!\n" + " Maybe try \"%"TC":\\%"TS"\"?", + path, line_no, pat, pat[0], &pat[2]); return WIMLIB_ERR_INVALID_CAPTURE_CONFIG; } - WARNING("Pattern \"%"TS"\" starts with a drive letter, which is " - "being removed.", pat); - /* Strip the drive letter */ - pat += 2; - } - canonical_pat = canonicalize_fs_path(pat); - if (!canonical_pat) - return WIMLIB_ERR_NOMEM; - zap_backslashes(canonical_pat); - *canonical_pat_ret = canonical_pat; - return 0; -} + WARNING("%"TS":%lu: Pattern \"%"TS"\" starts with a drive " + "letter, which is being removed.", + path, line_no, pat); -static int -copy_and_canonicalize_pattern_list(const struct wimlib_pattern_list *list, - struct wimlib_pattern_list *copy) -{ - int ret = 0; - - 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; + /* Strip the drive letter. */ + tmemmove(pat, pat + 2, tstrlen(pat + 2) + 1); } - return ret; + + /* Translate all possible path separators into the operating system's + * preferred path separator. */ + for (tchar *p = pat; *p; p++) + if (is_any_path_separator(*p)) + *p = OS_PREFERRED_PATH_SEPARATOR; + return 0; } int -copy_and_canonicalize_capture_config(const struct wimlib_capture_config *config, - struct wimlib_capture_config **config_copy_ret) +do_read_capture_config_file(const tchar *config_file, tchar *buf, size_t buflen, + struct capture_config *config) { - struct wimlib_capture_config *config_copy; int ret; - - config_copy = CALLOC(1, sizeof(struct wimlib_capture_config)); - if (!config_copy) { - ret = WIMLIB_ERR_NOMEM; - goto out_free_capture_config; - } - ret = copy_and_canonicalize_pattern_list(&config->exclusion_pats, - &config_copy->exclusion_pats); + struct text_file_section sections[] = { + {T("ExclusionList"), + &config->exclusion_pats}, + {T("ExclusionException"), + &config->exclusion_exception_pats}, + }; + + ret = do_load_text_file(config_file, buf, buflen, &buf, + sections, ARRAY_LEN(sections), + LOAD_TEXT_FILE_REMOVE_QUOTES, mangle_pat); 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; -out_free_capture_config: - free_capture_config(config_copy); -out: - return ret; -} + return ret; -static void -destroy_pattern_list(struct wimlib_pattern_list *list) -{ - for (size_t i = 0; i < list->num_pats; i++) - FREE(list->pats[i]); - FREE(list->pats); + config->buf = buf; + return 0; } void -free_capture_config(struct wimlib_capture_config *config) +destroy_capture_config(struct capture_config *config) { - if (config) { - destroy_pattern_list(&config->exclusion_pats); - destroy_pattern_list(&config->exclusion_exception_pats); - FREE(config); - } + FREE(config->exclusion_pats.strings); + FREE(config->exclusion_exception_pats.strings); + FREE(config->buf); } static bool match_pattern(const tchar *path, const tchar *path_basename, - const struct wimlib_pattern_list *list) + const struct string_set *list) { - for (size_t i = 0; i < list->num_pats; i++) { + for (size_t i = 0; i < list->num_strings; i++) { - const tchar *pat = list->pats[i]; + const tchar *pat = list->strings[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 @@ -162,16 +160,13 @@ 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; @@ -188,17 +183,17 @@ match_pattern(const tchar *path, */ bool exclude_path(const tchar *path, size_t path_len, - const struct wimlib_capture_config *config, bool exclude_prefix) + const struct 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('/')) + wimlib_assert(path_len >= config->prefix_num_tchars); + if (!tmemcmp(config->prefix, path, config->prefix_num_tchars) && + path[config->prefix_num_tchars] == OS_PREFERRED_PATH_SEPARATOR) { - path += config->_prefix_num_tchars; + path += config->prefix_num_tchars; } } return match_pattern(path, basename, &config->exclusion_pats) &&