X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmodify.c;h=3dc0de44542827cb5f6f1cf30c75a20515840cd3;hb=e32babce0a18a34620630264857ad12fcad13d31;hp=ff6e106cfba9b9eeb6e2e2bedb2214f10a93c8bf;hpb=950967a62753439aadd271b64e31deecf21ea275;p=wimlib diff --git a/src/modify.c b/src/modify.c index ff6e106c..3dc0de44 100644 --- a/src/modify.c +++ b/src/modify.c @@ -13,16 +13,16 @@ * This file is part of wimlib, a library for working with WIM files. * * wimlib is free software; you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) * any later version. * * wimlib is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU General Public License * along with wimlib; if not, see http://www.gnu.org/licenses/. */ @@ -41,7 +41,7 @@ #include /** Private flag: Used to mark that we currently adding the root directory of - * the WIM. */ + * the WIM image. */ #define WIMLIB_ADD_IMAGE_FLAG_ROOT 0x80000000 void destroy_image_metadata(struct image_metadata *imd,struct lookup_table *lt) @@ -85,6 +85,7 @@ static int build_dentry_tree(struct dentry **root_ret, const char *root_disk_pat int ret = 0; int (*stat_fn)(const char *restrict, struct stat *restrict); struct dentry *root; + const char *filename; if (exclude_path(root_disk_path, config, true)) { if (add_flags & WIMLIB_ADD_IMAGE_FLAG_VERBOSE) @@ -117,11 +118,17 @@ static int build_dentry_tree(struct dentry **root_ret, const char *root_disk_pat } if (!S_ISREG(root_stbuf.st_mode) && !S_ISDIR(root_stbuf.st_mode) && !S_ISLNK(root_stbuf.st_mode)) { - ERROR("`%s' is not a regular file, directory, or symbolic link."); + ERROR("`%s' is not a regular file, directory, or symbolic link.", + root_disk_path); return WIMLIB_ERR_SPECIAL_FILE; } - root = new_dentry(path_basename(root_disk_path)); + if (add_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) + filename = ""; + else + filename = path_basename(root_disk_path); + + root = new_dentry(filename); if (!root) return WIMLIB_ERR_NOMEM; @@ -166,7 +173,6 @@ static int build_dentry_tree(struct dentry **root_ret, const char *root_disk_pat closedir(dir); } else if (dentry_is_symlink(root)) { /* Archiving a symbolic link */ - size_t symlink_buf_len; char deref_name_buf[4096]; ssize_t deref_name_len; @@ -286,6 +292,7 @@ static int add_lte_to_dest_wim(struct dentry *dentry, void *arg) * * @w: The WIMStruct for the WIM file. * @root_dentry: The root of the directory tree for the image. + * @sd: The security data for the image. */ static int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry, struct wim_security_data *sd) @@ -313,7 +320,7 @@ static int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry, lgt = new_link_group_table(9001); if (!lgt) - goto out_free_security_data; + goto out_free_metadata_lte; metadata_lte->resource_entry.flags = WIM_RESHDR_FLAG_METADATA; random_hash(metadata_lte->hash); @@ -333,8 +340,6 @@ static int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry, /* Change the current image to the new one. */ return wimlib_select_image(w, w->hdr.image_count); -out_free_security_data: - FREE(sd); out_free_metadata_lte: FREE(metadata_lte); out_free_imd: @@ -518,6 +523,7 @@ enum pattern_type { ALIGNMENT_LIST, }; +/* Default capture configuration file when none is specified. */ static const char *default_config = "[ExclusionList]\n" "\\$ntfs.log\n" @@ -565,6 +571,8 @@ static int pattern_list_add_pattern(struct pattern_list *list, return 0; } +/* Parses the contents of the image capture configuration file and fills in a + * `struct capture_config'. */ static int init_capture_config(const char *_config_str, size_t config_len, const char *_prefix, struct capture_config *config) { @@ -573,7 +581,6 @@ static int init_capture_config(const char *_config_str, size_t config_len, char *p; char *eol; char *next_p; - size_t next_bytes_remaining; size_t bytes_remaining; enum pattern_type type = NONE; int ret; @@ -627,6 +634,7 @@ static int init_capture_config(const char *_config_str, size_t config_len, if (eol - p > 2 && isalpha(*p) && *(p + 1) == ':') p += 2; + ret = 0; if (strcmp(p, "[ExclusionList]") == 0) type = EXCLUSION_LIST; else if (strcmp(p, "[ExclusionException]") == 0) @@ -635,7 +643,11 @@ static int init_capture_config(const char *_config_str, size_t config_len, type = COMPRESSION_EXCLUSION_LIST; else if (strcmp(p, "[AlignmentList]") == 0) type = ALIGNMENT_LIST; - else switch (type) { + else if (p[0] == '[' && strrchr(p, ']')) { + ERROR("Unknown capture configuration section `%s'", p); + ret = WIMLIB_ERR_INVALID_CAPTURE_CONFIG; + goto out_destroy; + } else switch (type) { case EXCLUSION_LIST: DEBUG("Adding pattern \"%s\" to exclusion list", p); ret = pattern_list_add_pattern(&config->exclusion_list, p); @@ -714,6 +726,15 @@ static void print_capture_config(const struct capture_config *config) } } +/* Return true if the image capture configuration file indicates we should + * exclude the filename @path from capture. + * + * If @exclude_prefix is %true, the part of the path up and including the name + * of the directory being captured is not included in the path for matching + * purposes. This allows, for example, a pattern like /hiberfil.sys to match a + * file /mnt/windows7/hiberfil.sys if we are capturing the /mnt/windows7 + * directory. + */ bool exclude_path(const char *path, const struct capture_config *config, bool exclude_prefix) { @@ -731,6 +752,18 @@ bool exclude_path(const char *path, const struct capture_config *config, +/* + * Adds an image to the WIM, delegating the capture of the dentry tree and + * security data to the function @capture_tree passed as a parameter. + * Currently, @capture_tree may be build_dentry_tree() for capturing a "regular" + * directory tree on disk, or build_dentry_tree_ntfs() for capturing a WIM image + * directory from a NTFS volume using libntfs-3g. + * + * The @capture_tree function is also expected to create lookup table entries + * for all the file streams it captures and insert them into @lookup_table, + * being careful to look for identical entries that already exist and simply + * increment the reference count for them rather than duplicating the entry. + */ int do_add_image(WIMStruct *w, const char *dir, const char *name, const char *config_str, size_t config_len, int flags, @@ -742,19 +775,19 @@ int do_add_image(WIMStruct *w, const char *dir, const char *name, void *extra_arg) { struct dentry *root_dentry = NULL; - struct image_metadata *imd; struct wim_security_data *sd; struct capture_config config; + struct link_group_table *lgt; int ret; - DEBUG("Adding dentry tree from dir `%s'.", dir); + DEBUG("Adding dentry tree from directory or NTFS volume `%s'.", dir); if (!name || !*name) { ERROR("Must specify a non-empty string for the image name"); return WIMLIB_ERR_INVALID_PARAM; } if (!dir) { - ERROR("Must specify the name of a directory"); + ERROR("Must specify the name of a directory or NTFS volume"); return WIMLIB_ERR_INVALID_PARAM; } @@ -803,13 +836,20 @@ int do_add_image(WIMStruct *w, const char *dir, const char *name, if (ret != 0) goto out_free_dentry_tree; + lgt = w->image_metadata[w->hdr.image_count - 1].lgt; DEBUG("Inserting dentries into hard link group table"); - ret = for_dentry_in_tree(root_dentry, link_group_table_insert, - w->image_metadata[w->hdr.image_count - 1].lgt); + ret = for_dentry_in_tree(root_dentry, link_group_table_insert, lgt); + if (ret != 0) goto out_destroy_imd; - DEBUG("Assigning hard link groups"); - assign_link_groups(w->image_metadata[w->hdr.image_count - 1].lgt); + + DEBUG("Cleanup up the hard link groups"); + ret = fix_link_groups(lgt); + if (ret != 0) + goto out_destroy_imd; + + DEBUG("Assigning hard link group IDs"); + assign_link_group_ids(w->image_metadata[w->hdr.image_count - 1].lgt); if (flags & WIMLIB_ADD_IMAGE_FLAG_BOOT) wimlib_set_boot_idx(w, w->hdr.image_count); @@ -826,7 +866,6 @@ out_destroy_imd: return ret; out_free_dentry_tree: free_dentry_tree(root_dentry, w->lookup_table); -out_free_sd: free_security_data(sd); out_destroy_config: destroy_capture_config(&config);