X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fmodify.c;h=141f2dd8aac45cb0de271803cb2a6d71a4258f8e;hp=e6e9f2cd8c58be61f2ecfc61fd6180dce99946ab;hb=1dde5fb0d809f2f5e032e4d5241d1cb15ff3eb65;hpb=28e195e762f05766ade7d5f04881ba1d5e04c1dd diff --git a/src/modify.c b/src/modify.c index e6e9f2cd..141f2dd8 100644 --- a/src/modify.c +++ b/src/modify.c @@ -37,6 +37,7 @@ #include #include #include +#include #include /** Private flag: Used to mark that we currently adding the root directory of @@ -85,12 +86,11 @@ static int build_dentry_tree(struct dentry **root_ret, const char *root_disk_pat int (*stat_fn)(const char *restrict, struct stat *restrict); struct dentry *root; - DEBUG("%s", root_disk_path); - - if (exclude_path(root_disk_path, config)) { + if (exclude_path(root_disk_path, config, true)) { if (add_flags & WIMLIB_ADD_IMAGE_FLAG_VERBOSE) printf("Excluding file `%s' from capture\n", root_disk_path); + *root_ret = NULL; return 0; } @@ -158,9 +158,10 @@ static int build_dentry_tree(struct dentry **root_ret, const char *root_disk_pat ret = build_dentry_tree(&child, name, lookup_table, sd, config, add_flags, extra_arg); - link_dentry(child, root); if (ret != 0) break; + if (child) + link_dentry(child, root); } closedir(dir); } else if (dentry_is_symlink(root)) { @@ -517,7 +518,7 @@ static const char *default_config = "\\$ntfs.log\n" "\\hiberfil.sys\n" "\\pagefile.sys\n" -"\"\\System Volume Information\"\n" +"\\System Volume Information\n" "\\RECYCLER\n" "\\Windows\\CSC\n" "\n" @@ -539,6 +540,7 @@ static void destroy_capture_config(struct capture_config *config) destroy_pattern_list(&config->compression_exclusion_list); destroy_pattern_list(&config->alignment_list); FREE(config->config_str); + FREE(config->prefix); memset(config, 0, sizeof(*config)); } @@ -559,9 +561,10 @@ static int pattern_list_add_pattern(struct pattern_list *list, } static int init_capture_config(const char *_config_str, size_t config_len, - struct capture_config *config) + const char *_prefix, struct capture_config *config) { char *config_str; + char *prefix; char *p; char *eol; char *next_p; @@ -579,9 +582,17 @@ static int init_capture_config(const char *_config_str, size_t config_len, ERROR("Could not duplicate capture config string"); return WIMLIB_ERR_NOMEM; } + prefix = STRDUP(_prefix); + if (!prefix) { + FREE(config_str); + return WIMLIB_ERR_NOMEM; + } + memcpy(config_str, _config_str, config_len); next_p = config_str; config->config_str = config_str; + config->prefix = prefix; + config->prefix_len = strlen(prefix); while (bytes_remaining) { line_no++; p = next_p; @@ -607,6 +618,10 @@ static int init_capture_config(const char *_config_str, size_t config_len, if (*pp == '\\') *pp = '/'; + /* Remove drive letter */ + if (eol - p > 2 && isalpha(*p) && *(p + 1) == ':') + p += 2; + if (strcmp(p, "[ExclusionList]") == 0) type = EXCLUSION_LIST; else if (strcmp(p, "[ExclusionException]") == 0) @@ -655,10 +670,22 @@ static bool match_pattern(const char *path, const char *path_basename, const char *pat = list->pats[i]; const char *string; if (pat[0] == '/') + /* Absolute path from root of capture */ string = path; - else - string = path_basename; - if (fnmatch(pat, string, FNM_PATHNAME) == 0) { + else { + if (strchr(pat, '/')) + /* Relative path from root of capture */ + string = path + 1; + else + /* A file name pattern */ + string = path_basename; + } + if (fnmatch(pat, string, FNM_PATHNAME + #ifdef FNM_CASEFOLD + | FNM_CASEFOLD + #endif + ) == 0) + { DEBUG("`%s' matches the pattern \"%s\"", string, pat); return true; @@ -682,9 +709,16 @@ static void print_capture_config(const struct capture_config *config) } } -bool exclude_path(const char *path, const struct capture_config *config) +bool exclude_path(const char *path, const struct capture_config *config, + bool exclude_prefix) { const char *basename = path_basename(path); + if (exclude_prefix) { + wimlib_assert(strlen(path) >= config->prefix_len); + if (memcmp(config->prefix, path, config->prefix_len) == 0 + && path[config->prefix_len] == '/') + path += config->prefix_len; + } return match_pattern(path, basename, &config->exclusion_list) && !match_pattern(path, basename, &config->exclusion_exception); @@ -693,7 +727,6 @@ bool exclude_path(const char *path, const struct capture_config *config) int do_add_image(WIMStruct *w, const char *dir, const char *name, - const char *description, const char *flags_element, const char *config_str, size_t config_len, int flags, int (*capture_tree)(struct dentry **, const char *, @@ -732,7 +765,7 @@ int do_add_image(WIMStruct *w, const char *dir, const char *name, config_str = default_config; config_len = strlen(default_config); } - ret = init_capture_config(config_str, config_len, &config); + ret = init_capture_config(config_str, config_len, dir, &config); if (ret != 0) return ret; print_capture_config(&config); @@ -776,7 +809,7 @@ int do_add_image(WIMStruct *w, const char *dir, const char *name, if (flags & WIMLIB_ADD_IMAGE_FLAG_BOOT) wimlib_set_boot_idx(w, w->hdr.image_count); - ret = xml_add_image(w, root_dentry, name, description, flags_element); + ret = xml_add_image(w, root_dentry, name); if (ret != 0) goto out_destroy_imd; @@ -799,12 +832,9 @@ out_destroy_config: * Adds an image to a WIM file from a directory tree on disk. */ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *dir, - const char *name, const char *description, - const char *flags_element, - const char *config_str, + const char *name, const char *config_str, size_t config_len, int flags) { - return do_add_image(w, dir, name, description, flags_element, - config_str, config_len, flags, + return do_add_image(w, dir, name, config_str, config_len, flags, build_dentry_tree, NULL); }