]> wimlib.net Git - wimlib/blobdiff - src/mount_image.c
wimlib_mount_image(): Correctly handle unnamed stream in ADS entries
[wimlib] / src / mount_image.c
index d54fd23671389adc861dc4db9e5309e0371e5bd3..ce4a58432d51f081256a26c550c1fb5d369895fa 100644 (file)
@@ -46,7 +46,6 @@
 #include "wimlib/paths.h"
 #include "wimlib/reparse.h"
 #include "wimlib/resource.h"
-#include "wimlib/swm.h"
 #include "wimlib/timestamp.h"
 #include "wimlib/version.h"
 #include "wimlib/write.h"
@@ -483,7 +482,7 @@ create_staging_file(char **name_ret, struct wimfs_context *ctx)
        static const size_t STAGING_FILE_NAME_LEN = 20;
 
        name_len = ctx->staging_dir_name_len + 1 + STAGING_FILE_NAME_LEN;
-       name = MALLOC(name_len + 1);
+       name = MALLOC(name_len + 1);
        if (!name) {
                errno = ENOMEM;
                return -1;
@@ -567,7 +566,8 @@ extract_resource_to_staging_dir(struct wim_inode *inode,
 
        /* Extract the stream to the staging file (possibly truncated) */
        if (old_lte) {
-               struct filedes wimlib_fd = {.fd = fd};
+               struct filedes wimlib_fd;
+               filedes_init(&wimlib_fd, fd);
                extract_size = min(wim_resource_size(old_lte), size);
                ret = extract_wim_resource_to_fd(old_lte, &wimlib_fd,
                                                 extract_size);
@@ -864,7 +864,7 @@ set_message_queue_names(struct wimfs_context *ctx, const char *mount_dir)
        char *p;
        int ret;
 
-       dir_path = realpath(mount_dir, NULL);
+       dir_path = realpath(mount_dir, NULL);
        if (!dir_path) {
                ERROR_WITH_ERRNO("Failed to resolve path \"%s\"", mount_dir);
                if (errno == ENOMEM)
@@ -1539,8 +1539,8 @@ wimfs_chmod(const char *path, mode_t mask)
        if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
                return -EPERM;
 
-       ret = lookup_resource(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
-                             &dentry, NULL, NULL);
+       ret = wim_pathname_to_stream(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
+                                    &dentry, NULL, NULL);
        if (ret)
                return ret;
 
@@ -1560,8 +1560,8 @@ wimfs_chown(const char *path, uid_t uid, gid_t gid)
        if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
                return -EPERM;
 
-       ret = lookup_resource(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
-                             &dentry, NULL, NULL);
+       ret = wim_pathname_to_stream(ctx->wim, path, LOOKUP_FLAG_DIRECTORY_OK,
+                                    &dentry, NULL, NULL);
        if (ret)
                return ret;
 
@@ -1621,9 +1621,10 @@ wimfs_getattr(const char *path, struct stat *stbuf)
        int ret;
        struct wimfs_context *ctx = wimfs_get_context();
 
-       ret = lookup_resource(ctx->wim, path,
-                             get_lookup_flags(ctx) | LOOKUP_FLAG_DIRECTORY_OK,
-                             &dentry, &lte, NULL);
+       ret = wim_pathname_to_stream(ctx->wim, path,
+                                    get_lookup_flags(ctx) |
+                                       LOOKUP_FLAG_DIRECTORY_OK,
+                                    &dentry, &lte, NULL);
        if (ret != 0)
                return ret;
        return inode_to_stbuf(dentry->d_inode, lte, stbuf);
@@ -1645,7 +1646,7 @@ wimfs_getxattr(const char *path, const char *name, char *value,
        if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR))
                return -ENOTSUP;
 
-       if (strlen(name) < 5 || memcmp(name, "user.", 5) != 0)
+       if (strlen(name) <= 5 || memcmp(name, "user.", 5) != 0)
                return -ENOATTR;
        name += 5;
 
@@ -1667,9 +1668,12 @@ wimfs_getxattr(const char *path, const char *name, char *value,
                return -ERANGE;
 
        ret = read_full_resource_into_buf(lte, value);
-       if (ret)
-               return -errno;
-
+       if (ret) {
+               if (errno)
+                       return -errno;
+               else
+                       return -EIO;
+       }
        return res_size;
 }
 #endif
@@ -1736,6 +1740,10 @@ wimfs_listxattr(const char *path, char *list, size_t size)
 
        p = list;
        for (i = 0; i < inode->i_num_ads; i++) {
+
+               if (!ads_entry_is_named_stream(&inode->i_ads_entries[i]))
+                       continue;
+
                char *stream_name_mbs;
                size_t stream_name_mbs_nbytes;
                int ret;
@@ -1825,8 +1833,8 @@ wimfs_open(const char *path, struct fuse_file_info *fi)
        struct wimfs_context *ctx = wimfs_get_context();
        struct wim_lookup_table_entry **back_ptr;
 
-       ret = lookup_resource(ctx->wim, path, get_lookup_flags(ctx),
-                             &dentry, &lte, &stream_idx);
+       ret = wim_pathname_to_stream(ctx->wim, path, get_lookup_flags(ctx),
+                                    &dentry, &lte, &stream_idx);
        if (ret)
                return ret;
 
@@ -2116,7 +2124,7 @@ wimfs_setxattr(const char *path, const char *name,
        if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_XATTR))
                return -ENOTSUP;
 
-       if (strlen(name) < 5 || memcmp(name, "user.", 5) != 0)
+       if (strlen(name) <= 5 || memcmp(name, "user.", 5) != 0)
                return -ENOATTR;
        name += 5;
 
@@ -2183,8 +2191,8 @@ wimfs_truncate(const char *path, off_t size)
        struct wim_inode *inode;
        struct wimfs_context *ctx = wimfs_get_context();
 
-       ret = lookup_resource(ctx->wim, path, get_lookup_flags(ctx),
-                             &dentry, &lte, &stream_idx);
+       ret = wim_pathname_to_stream(ctx->wim, path, get_lookup_flags(ctx),
+                                    &dentry, &lte, &stream_idx);
 
        if (ret != 0)
                return ret;
@@ -2192,7 +2200,7 @@ wimfs_truncate(const char *path, off_t size)
        if (lte == NULL && size == 0)
                return 0;
 
-       if (lte->resource_location == RESOURCE_IN_STAGING_FILE) {
+       if (lte != NULL && lte->resource_location == RESOURCE_IN_STAGING_FILE) {
                ret = truncate(lte->staging_file_name, size);
                if (ret)
                        ret = -errno;
@@ -2228,13 +2236,13 @@ wimfs_unlink(const char *path)
        u16 stream_idx;
        struct wimfs_context *ctx = wimfs_get_context();
 
-       ret = lookup_resource(ctx->wim, path, get_lookup_flags(ctx),
-                             &dentry, &lte, &stream_idx);
+       ret = wim_pathname_to_stream(ctx->wim, path, get_lookup_flags(ctx),
+                                    &dentry, &lte, &stream_idx);
 
        if (ret != 0)
                return ret;
 
-       if (stream_idx == 0)
+       if (inode_stream_name_nbytes(dentry->d_inode, stream_idx) == 0)
                remove_dentry(dentry, ctx->wim->lookup_table);
        else
                inode_remove_ads(dentry->d_inode, stream_idx - 1,
@@ -2255,7 +2263,7 @@ wimfs_utimens(const char *path, const struct timespec tv[2])
        struct wim_inode *inode;
        WIMStruct *wim = wimfs_get_WIMStruct();
 
-       dentry = get_dentry(wim, path);
+       dentry = get_dentry(wim, path);
        if (!dentry)
                return -errno;
        inode = dentry->d_inode;
@@ -2282,7 +2290,7 @@ wimfs_utime(const char *path, struct utimbuf *times)
        struct wim_inode *inode;
        WIMStruct *wim = wimfs_get_WIMStruct();
 
-       dentry = get_dentry(wim, path);
+       dentry = get_dentry(wim, path);
        if (!dentry)
                return -errno;
        inode = dentry->d_inode;
@@ -2386,9 +2394,7 @@ static struct fuse_operations wimfs_operations = {
 /* API function documented in wimlib.h  */
 WIMLIBAPI int
 wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
-                  int mount_flags, WIMStruct **additional_swms,
-                  unsigned num_additional_swms,
-                  const char *staging_dir)
+                  int mount_flags, const char *staging_dir)
 {
        int argc;
        char *argv[16];
@@ -2401,27 +2407,18 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
        DEBUG("Mount: wim = %p, image = %d, dir = %s, flags = %d, ",
              wim, image, dir, mount_flags);
 
-       if (!wim || !dir) {
-               ret = WIMLIB_ERR_INVALID_PARAM;
-               goto out;
-       }
-
-       ret = verify_swm_set(wim, additional_swms, num_additional_swms);
-       if (ret)
-               goto out;
+       if (!wim || !dir)
+               return WIMLIB_ERR_INVALID_PARAM;
 
        if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
                ret = can_delete_from_wim(wim);
                if (ret)
-                       goto out;
+                       return ret;
        }
 
-       if (num_additional_swms)
-               merge_lookup_tables(wim, additional_swms, num_additional_swms);
-
        ret = select_wim_image(wim, image);
        if (ret)
-               goto out_restore_lookup_table;
+               return ret;
 
        DEBUG("Selected image %d", image);
 
@@ -2430,21 +2427,19 @@ wimlib_mount_image(WIMStruct *wim, int image, const char *dir,
        if (imd->refcnt != 1) {
                ERROR("Cannot mount image that was just exported with "
                      "wimlib_export_image()");
-               ret = WIMLIB_ERR_INVALID_PARAM;
-               goto out_restore_lookup_table;
+               return WIMLIB_ERR_INVALID_PARAM;
        }
 
        if (imd->modified) {
                ERROR("Cannot mount image that was added "
                      "with wimlib_add_image()");
-               ret = WIMLIB_ERR_INVALID_PARAM;
-               goto out_restore_lookup_table;
+               return WIMLIB_ERR_INVALID_PARAM;
        }
 
        if (mount_flags & WIMLIB_MOUNT_FLAG_READWRITE) {
                ret = lock_wim(wim, wim->in_fd.fd);
                if (ret)
-                       goto out_restore_lookup_table;
+                       return ret;
        }
 
        /* Use default stream interface if one was not specified */
@@ -2568,10 +2563,6 @@ out_unlock:
        wim->wim_locked = 0;
 out_free_message_queue_names:
        free_message_queue_names(&ctx);
-out_restore_lookup_table:
-       if (num_additional_swms)
-               unmerge_lookup_table(wim);
-out:
        return ret;
 }
 
@@ -2648,9 +2639,7 @@ wimlib_unmount_image(const tchar *dir, int unmount_flags,
 
 WIMLIBAPI int
 wimlib_mount_image(WIMStruct *wim, int image, const tchar *dir,
-                  int mount_flags, WIMStruct **additional_swms,
-                  unsigned num_additional_swms,
-                  const tchar *staging_dir)
+                  int mount_flags, const tchar *staging_dir)
 {
        return mount_unsupported_error();
 }