]> wimlib.net Git - wimlib/blobdiff - src/add_image.c
xpress_decode_match(): Allow lengths encoded in unnecessary bytes
[wimlib] / src / add_image.c
index 085fd044e386d1626bc2e9f649da704ee799ce2c..d10e5a3302108d6474ad6215bc3f6742fce6b7cc 100644 (file)
  * @sd:                  The security data for the image.
  */
 int add_new_dentry_tree(WIMStruct *w, struct dentry *root_dentry,
-                              struct wim_security_data *sd)
+                       struct wim_security_data *sd)
 {
        struct lookup_table_entry *metadata_lte;
        struct image_metadata *imd;
        struct image_metadata *new_imd;
-       int ret;
 
        wimlib_assert(root_dentry != NULL);
 
@@ -87,18 +86,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:
@@ -193,9 +186,20 @@ static int build_dentry_tree(struct dentry **root_ret,
        }
 
        if ((add_image_flags & WIMLIB_ADD_IMAGE_FLAG_ROOT) &&
-             !S_ISDIR(root_stbuf.st_mode)) {
-               ERROR("`%s' is not a directory", root_disk_path);
-               return WIMLIB_ERR_NOTDIR;
+             !S_ISDIR(root_stbuf.st_mode))
+       {
+               /* Do a dereference-stat in case the root is a symbolic link.
+                * This case is allowed, provided that the symbolic link points
+                * to a directory. */
+               ret = stat(root_disk_path, &root_stbuf);
+               if (ret != 0) {
+                       ERROR_WITH_ERRNO("Failed to stat `%s'", root_disk_path);
+                       return WIMLIB_ERR_STAT;
+               }
+               if (!S_ISDIR(root_stbuf.st_mode)) {
+                       ERROR("`%s' is not a directory", root_disk_path);
+                       return WIMLIB_ERR_NOTDIR;
+               }
        }
        if (!S_ISREG(root_stbuf.st_mode) && !S_ISDIR(root_stbuf.st_mode)
            && !S_ISLNK(root_stbuf.st_mode)) {
@@ -210,8 +214,14 @@ 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;
 
@@ -231,7 +241,7 @@ static int build_dentry_tree(struct dentry **root_ret,
                                   ((u64)root_stbuf.st_dev << ((sizeof(ino_t) * 8) & 63));
 
        add_image_flags &= ~WIMLIB_ADD_IMAGE_FLAG_ROOT;
-       inode->resolved = true;
+       inode->resolved = 1;
 
        if (S_ISREG(root_stbuf.st_mode)) { /* Archiving a regular file */
 
@@ -629,8 +639,7 @@ WIMLIBAPI int wimlib_add_image(WIMStruct *w, const char *source,
        struct dentry *root_dentry = NULL;
        struct wim_security_data *sd;
        struct capture_config config;
-       struct inode_table inode_tab;
-       struct hlist_head inode_list;
+       struct image_metadata *imd;
        int ret;
 
        if (add_image_flags & WIMLIB_ADD_IMAGE_FLAG_NTFS) {
@@ -726,21 +735,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)