X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fadd_image.c;h=61ed013225ef696fc009228c2964eea3b2ea5d07;hp=8f3724cd77a91e8c45b1fba3bed9f05ea91d0ca9;hb=1d8b904a7424f6e38bcba0b2c3a3078f43781029;hpb=61975c56f685c4ed003f3b8fd6b88a8dbfb4b696 diff --git a/src/add_image.c b/src/add_image.c index 8f3724cd..61ed0132 100644 --- a/src/add_image.c +++ b/src/add_image.c @@ -39,32 +39,21 @@ #define WIMLIB_ADD_IMAGE_FLAG_ROOT 0x80000000 /* - * Adds an image (given by its dentry tree) to the image metadata array of a WIM - * file, adds an entry to the lookup table for the image metadata, updates the - * image count in the header, and selects the new image. - * - * Does not update the XML data. - * - * On failure, WIMLIB_ERR_NOMEM is returned and no changes are made. Otherwise, - * 0 is returned and the image metadata array of @w is modified. - * - * @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. + * Adds the dentry tree and security data for a new image to the image metadata + * array of the WIMStruct. */ -int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry, - struct wim_security_data *sd) +int add_new_dentry_tree(WIMStruct *w, struct wim_dentry *root_dentry, + struct wim_security_data *sd) { - struct lookup_table_entry *metadata_lte; - struct image_metadata *imd; - struct image_metadata *new_imd; - int ret; + struct wim_lookup_table_entry *metadata_lte; + struct wim_image_metadata *imd; + struct wim_image_metadata *new_imd; wimlib_assert(root_dentry != NULL); DEBUG("Reallocating image metadata array for image_count = %u", w->hdr.image_count + 1); - imd = CALLOC((w->hdr.image_count + 1), sizeof(struct image_metadata)); + imd = CALLOC((w->hdr.image_count + 1), sizeof(struct wim_image_metadata)); if (!imd) { ERROR("Failed to allocate memory for new image metadata array"); @@ -72,7 +61,7 @@ int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry, } memcpy(imd, w->image_metadata, - w->hdr.image_count * sizeof(struct image_metadata)); + w->hdr.image_count * sizeof(struct wim_image_metadata)); metadata_lte = new_lookup_table_entry(); if (!metadata_lte) @@ -87,18 +76,12 @@ int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry, new_imd->root_dentry = root_dentry; new_imd->metadata_lte = metadata_lte; new_imd->security_data = sd; - new_imd->modified = true; + new_imd->modified = 1; FREE(w->image_metadata); - w->image_metadata = imd; + w->image_metadata = imd; w->hdr.image_count++; - - /* Change the current image to the new one. There should not be any - * ways for this to fail, since the image is valid and the dentry tree - * is already in memory. */ - ret = select_wim_image(w, w->hdr.image_count); - wimlib_assert(ret == 0); - return ret; + return 0; err_free_imd: FREE(imd); err: @@ -108,11 +91,12 @@ err: /* - * Recursively builds a dentry tree from a directory tree on disk, outside the - * WIM file. + * build_dentry_tree(): + * Recursively builds a tree of WIM dentries from an on-disk directory + * tree. * * @root_ret: Place to return a pointer to the root of the dentry tree. Only - * modified if successful. NULL if the file or directory was + * modified if successful. Set to NULL if the file or directory was * excluded from capture. * * @root_disk_path: The path to the root of the directory tree on disk. @@ -139,9 +123,9 @@ err: * the on-disk files during a call to wimlib_write() or * wimlib_overwrite(). */ -static int build_dentry_tree(struct dentry **root_ret, +static int build_dentry_tree(struct wim_dentry **root_ret, const char *root_disk_path, - struct lookup_table *lookup_table, + struct wim_lookup_table *lookup_table, struct wim_security_data *sd, const struct capture_config *config, int add_image_flags, @@ -151,9 +135,9 @@ static int build_dentry_tree(struct dentry **root_ret, struct stat root_stbuf; int ret = 0; int (*stat_fn)(const char *restrict, struct stat *restrict); - struct dentry *root; + struct wim_dentry *root; const char *filename; - struct inode *inode; + struct wim_inode *inode; if (exclude_path(root_disk_path, config, true)) { if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) { @@ -221,35 +205,48 @@ static int build_dentry_tree(struct dentry **root_ret, filename = path_basename(root_disk_path); root = new_dentry_with_timeless_inode(filename); - if (!root) - return WIMLIB_ERR_NOMEM; + if (!root) { + if (errno == EILSEQ) + return WIMLIB_ERR_INVALID_UTF8_STRING; + else if (errno == ENOMEM) + return WIMLIB_ERR_NOMEM; + else + return WIMLIB_ERR_ICONV_NOT_AVAILABLE; + } inode = root->d_inode; #ifdef HAVE_STAT_NANOSECOND_PRECISION - inode->creation_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); - inode->last_write_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); - inode->last_access_time = timespec_to_wim_timestamp(&root_stbuf.st_atim); + inode->i_creation_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); + inode->i_last_write_time = timespec_to_wim_timestamp(&root_stbuf.st_mtim); + inode->i_last_access_time = timespec_to_wim_timestamp(&root_stbuf.st_atim); #else - inode->creation_time = unix_timestamp_to_wim(root_stbuf.st_mtime); - inode->last_write_time = unix_timestamp_to_wim(root_stbuf.st_mtime); - inode->last_access_time = unix_timestamp_to_wim(root_stbuf.st_atime); + inode->i_creation_time = unix_timestamp_to_wim(root_stbuf.st_mtime); + inode->i_last_write_time = unix_timestamp_to_wim(root_stbuf.st_mtime); + inode->i_last_access_time = unix_timestamp_to_wim(root_stbuf.st_atime); #endif if (sizeof(ino_t) >= 8) - inode->ino = (u64)root_stbuf.st_ino; + inode->i_ino = (u64)root_stbuf.st_ino; else - inode->ino = (u64)root_stbuf.st_ino | + inode->i_ino = (u64)root_stbuf.st_ino | ((u64)root_stbuf.st_dev << ((sizeof(ino_t) * 8) & 63)); - + inode->i_resolved = 1; + if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA) { + ret = inode_set_unix_data(inode, root_stbuf.st_uid, + root_stbuf.st_gid, + root_stbuf.st_mode, + lookup_table, + UNIX_DATA_ALL | UNIX_DATA_CREATE); + if (ret) + goto out; + } add_image_flags &= ~WIMLIB_ADD_IMAGE_FLAG_ROOT; - inode->resolved = true; - if (S_ISREG(root_stbuf.st_mode)) { /* Archiving a regular file */ - struct lookup_table_entry *lte; + struct wim_lookup_table_entry *lte; u8 hash[SHA1_HASH_SIZE]; - inode->attributes = FILE_ATTRIBUTE_NORMAL; + inode->i_attributes = FILE_ATTRIBUTE_NORMAL; /* Empty files do not have to have a lookup table entry. */ if (root_stbuf.st_size == 0) @@ -289,14 +286,14 @@ static int build_dentry_tree(struct dentry **root_ret, copy_hash(lte->hash, hash); lookup_table_insert(lookup_table, lte); } - root->d_inode->lte = lte; + root->d_inode->i_lte = lte; } else if (S_ISDIR(root_stbuf.st_mode)) { /* Archiving a directory */ - inode->attributes = FILE_ATTRIBUTE_DIRECTORY; + inode->i_attributes = FILE_ATTRIBUTE_DIRECTORY; DIR *dir; struct dirent entry, *result; - struct dentry *child; + struct wim_dentry *child; dir = opendir(root_disk_path); if (!dir) { @@ -340,8 +337,8 @@ static int build_dentry_tree(struct dentry **root_ret, } closedir(dir); } else { /* Archiving a symbolic link */ - inode->attributes = FILE_ATTRIBUTE_REPARSE_POINT; - inode->reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK; + 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 @@ -373,7 +370,7 @@ static int build_dentry_tree(struct dentry **root_ret, if (stat(root_disk_path, &stbuf) == 0 && S_ISDIR(stbuf.st_mode)) { - inode->attributes |= FILE_ATTRIBUTE_DIRECTORY; + inode->i_attributes |= FILE_ATTRIBUTE_DIRECTORY; } } } else { @@ -399,8 +396,13 @@ enum pattern_type { ALIGNMENT_LIST, }; +#define COMPAT_DEFAULT_CONFIG + /* Default capture configuration file when none is specified. */ static const char *default_config = +#ifdef COMPAT_DEFAULT_CONFIG /* XXX: This policy is being moved to library + users. The next ABI-incompatible library + version will default to the empty string here. */ "[ExclusionList]\n" "\\$ntfs.log\n" "\\hiberfil.sys\n" @@ -414,6 +416,9 @@ static const char *default_config = "*.zip\n" "*.cab\n" "\\WINDOWS\\inf\\*.pnf\n"; +#else +""; +#endif static void destroy_pattern_list(struct pattern_list *list) { @@ -586,21 +591,6 @@ static bool match_pattern(const char *path, const char *path_basename, return false; } -static void print_pattern_list(const struct pattern_list *list) -{ - for (size_t i = 0; i < list->num_pats; i++) - printf(" %s\n", list->pats[i]); -} - -static void print_capture_config(const struct capture_config *config) -{ - if (config->exclusion_list.num_pats) { - puts("Files or folders excluded from image capture:"); - print_pattern_list(&config->exclusion_list); - putchar('\n'); - } -} - /* Return true if the image capture configuration file indicates we should * exclude the filename @path from capture. * @@ -630,26 +620,30 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *source, size_t config_len, int add_image_flags, wimlib_progress_func_t progress_func) { - int (*capture_tree)(struct dentry **, const char *, - struct lookup_table *, + int (*capture_tree)(struct wim_dentry **, const char *, + struct wim_lookup_table *, struct wim_security_data *, const struct capture_config *, int, wimlib_progress_func_t, void *); void *extra_arg; - struct dentry *root_dentry = NULL; + struct wim_dentry *root_dentry = NULL; struct wim_security_data *sd; struct capture_config config; - struct inode_table inode_tab; - struct hlist_head inode_list; + struct wim_image_metadata *imd; int ret; if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_NTFS) { #ifdef WITH_NTFS_3G - if (add_image_flags & (WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE)) { + if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_DEREFERENCE) { ERROR("Cannot dereference files when capturing directly from NTFS"); return WIMLIB_ERR_INVALID_PARAM; } + if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_UNIX_DATA) { + ERROR("Capturing UNIX owner and mode not supported " + "when capturing directly from NTFS"); + return WIMLIB_ERR_INVALID_PARAM; + } capture_tree = build_dentry_tree_ntfs; extra_arg = &w->ntfs_vol; #else @@ -693,7 +687,6 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *source, ret = init_capture_config(config_str, config_len, source, &config); if (ret != 0) return ret; - print_capture_config(&config); DEBUG("Allocating security data"); @@ -737,21 +730,14 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *source, if (ret != 0) goto out_free_dentry_tree; - DEBUG("Inserting dentries into inode table"); - ret = init_inode_table(&inode_tab, 9001); - if (ret != 0) - goto out_destroy_imd; - - for_dentry_in_tree(root_dentry, inode_table_insert, &inode_tab); + imd = &w->image_metadata[w->hdr.image_count - 1]; - DEBUG("Cleaning up the hard link groups"); - ret = fix_inodes(&inode_tab, &inode_list); - destroy_inode_table(&inode_tab); + ret = dentry_tree_fix_inodes(root_dentry, &imd->inode_list); if (ret != 0) goto out_destroy_imd; DEBUG("Assigning hard link group IDs"); - assign_inode_numbers(&inode_list); + assign_inode_numbers(&imd->inode_list); ret = xml_add_image(w, name); if (ret != 0)