]> wimlib.net Git - wimlib/blobdiff - src/add_image.c
Move default capture config policy to library users
[wimlib] / src / add_image.c
index 082c5023ae8bc5a5259a174a36cc231432ef6946..61ed013225ef696fc009228c2964eea3b2ea5d07 100644 (file)
 #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;
-       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)
@@ -102,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.
@@ -133,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,
@@ -145,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) {
@@ -215,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 = 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)
@@ -283,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) {
@@ -334,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
@@ -367,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 {
@@ -393,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"
@@ -408,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)
 {
@@ -580,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.
  *
@@ -624,25 +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 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
@@ -686,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");
 
@@ -730,14 +730,14 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *source,
        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)