#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,
+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;
+ 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");
}
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)
/*
- * 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.
* 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,
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) {
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 = 1;
-
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)
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) {
}
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
if (stat(root_disk_path, &stbuf) == 0 &&
S_ISDIR(stbuf.st_mode))
{
- inode->attributes |= FILE_ATTRIBUTE_DIRECTORY;
+ inode->i_attributes |= FILE_ATTRIBUTE_DIRECTORY;
}
}
} else {
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"
"*.zip\n"
"*.cab\n"
"\\WINDOWS\\inf\\*.pnf\n";
+#else
+"";
+#endif
static void destroy_pattern_list(struct pattern_list *list)
{
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.
*
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 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
ret = init_capture_config(config_str, config_len, source, &config);
if (ret != 0)
return ret;
- print_capture_config(&config);
DEBUG("Allocating security data");
if (ret != 0)
goto out_free_dentry_tree;
+ imd = &w->image_metadata[w->hdr.image_count - 1];
- ret = dentry_tree_fix_inodes(root_dentry, &inode_list);
+ 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);
- w->image_metadata[w->hdr.image_count - 1].inode_list = inode_list;
+ assign_inode_numbers(&imd->inode_list);
ret = xml_add_image(w, name);
if (ret != 0)