]> wimlib.net Git - wimlib/blobdiff - src/mount_image.c
extract.c: Warn when UNIX metadata is not being extracted
[wimlib] / src / mount_image.c
index e1ff886f583d89298eacd851e3da8d61bf528dd6..168ee8523bc9bc038a9c678bdbf9c2f50fce62e9 100644 (file)
@@ -50,6 +50,7 @@
 #include "wimlib/reparse.h"
 #include "wimlib/resource.h"
 #include "wimlib/timestamp.h"
+#include "wimlib/unix_data.h"
 #include "wimlib/version.h"
 #include "wimlib/write.h"
 #include "wimlib/xml.h"
@@ -314,7 +315,8 @@ fuse_mask_mode(mode_t mode, struct fuse_context *fuse_ctx)
  */
 static int
 create_dentry(struct fuse_context *fuse_ctx, const char *path,
-             mode_t mode, int attributes, struct wim_dentry **dentry_ret)
+             mode_t mode, dev_t rdev, int attributes,
+             struct wim_dentry **dentry_ret)
 {
        struct wim_dentry *parent;
        struct wim_dentry *new;
@@ -342,9 +344,19 @@ create_dentry(struct fuse_context *fuse_ctx, const char *path,
        new->d_inode->i_attributes = attributes;
 
        if (wimfs_ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA) {
-               new->d_inode->i_unix_data.uid = fuse_ctx->uid;
-               new->d_inode->i_unix_data.gid = fuse_ctx->gid;
-               new->d_inode->i_unix_data.mode = fuse_mask_mode(mode, fuse_ctx);
+               struct wimlib_unix_data unix_data;
+
+               unix_data.uid = fuse_ctx->uid;
+               unix_data.gid = fuse_ctx->gid;
+               unix_data.mode = fuse_mask_mode(mode, fuse_ctx);
+               unix_data.rdev = rdev;
+
+               if (!inode_set_unix_data(new->d_inode, &unix_data,
+                                        UNIX_DATA_ALL))
+               {
+                       free_dentry(new);
+                       return -ENOMEM;
+               }
        }
        dentry_add_child(parent, new);
        list_add_tail(&new->d_inode->i_list, wimfs_ctx->image_inode_list);
@@ -410,18 +422,21 @@ inode_to_stbuf(const struct wim_inode *inode,
               struct stat *stbuf)
 {
        const struct wimfs_context *ctx = wimfs_get_context();
+       struct wimlib_unix_data unix_data;
 
        memset(stbuf, 0, sizeof(struct stat));
        if ((ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA) &&
-           inode_has_unix_data(inode))
+           inode_get_unix_data(inode, &unix_data))
        {
-               stbuf->st_uid = inode->i_unix_data.uid;
-               stbuf->st_gid = inode->i_unix_data.gid;
-               stbuf->st_mode = inode->i_unix_data.mode;
+               stbuf->st_uid = unix_data.uid;
+               stbuf->st_gid = unix_data.gid;
+               stbuf->st_mode = unix_data.mode;
+               stbuf->st_rdev = unix_data.rdev;
        } else {
                stbuf->st_uid = ctx->default_uid;
                stbuf->st_gid = ctx->default_gid;
                stbuf->st_mode = inode_default_unix_mode(inode);
+               stbuf->st_rdev = 0;
        }
        stbuf->st_ino = (ino_t)inode->i_ino;
        stbuf->st_nlink = inode->i_nlink;
@@ -1609,6 +1624,7 @@ wimfs_chmod(const char *path, mode_t mask)
        struct wim_dentry *dentry;
        struct wim_inode *inode;
        struct wimfs_context *ctx = wimfs_get_context();
+       struct wimlib_unix_data unix_data;
        int ret;
 
        if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
@@ -1621,11 +1637,13 @@ wimfs_chmod(const char *path, mode_t mask)
 
        inode = dentry->d_inode;
 
-       if (!inode_has_unix_data(inode)) {
-               inode->i_unix_data.uid = ctx->default_uid;
-               inode->i_unix_data.gid = ctx->default_gid;
-       }
-       inode->i_unix_data.mode = mask;
+       unix_data.uid = ctx->default_uid;
+       unix_data.gid = ctx->default_gid;
+       unix_data.mode = mask;
+       unix_data.rdev = 0;
+       if (!inode_set_unix_data(inode, &unix_data, UNIX_DATA_MODE))
+               return -ENOMEM;
+
        return 0;
 }
 
@@ -1635,6 +1653,8 @@ wimfs_chown(const char *path, uid_t uid, gid_t gid)
        struct wim_dentry *dentry;
        struct wim_inode *inode;
        struct wimfs_context *ctx = wimfs_get_context();
+       int which;
+       struct wimlib_unix_data unix_data;
        int ret;
 
        if (!(ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
@@ -1647,10 +1667,26 @@ wimfs_chown(const char *path, uid_t uid, gid_t gid)
 
        inode = dentry->d_inode;
 
-       if (!inode_has_unix_data(inode))
-               inode->i_unix_data.mode = inode_default_unix_mode(inode);
-       inode->i_unix_data.uid = uid;
-       inode->i_unix_data.gid = gid;
+       which = 0;
+
+       if (uid != (uid_t)-1)
+               which |= UNIX_DATA_UID;
+       else
+               uid = ctx->default_uid;
+
+       if (gid != (gid_t)-1)
+               which |= UNIX_DATA_GID;
+       else
+               gid = ctx->default_gid;
+
+
+       unix_data.uid = uid;
+       unix_data.gid = gid;
+       unix_data.mode = inode_default_unix_mode(inode);
+       unix_data.rdev = 0;
+       if (!inode_set_unix_data(inode, &unix_data, which))
+               return -ENOMEM;
+
        return 0;
 }
 
@@ -1859,11 +1895,12 @@ wimfs_listxattr(const char *path, char *list, size_t size)
 static int
 wimfs_mkdir(const char *path, mode_t mode)
 {
-       return create_dentry(fuse_get_context(), path, mode | S_IFDIR,
+       return create_dentry(fuse_get_context(), path, mode | S_IFDIR, 0,
                             FILE_ATTRIBUTE_DIRECTORY, NULL);
 }
 
-/* Create a regular file or alternate data stream in the WIM image. */
+/* Create a non-directory, non-symbolic-link file or alternate data stream in
+ * the WIM image.  */
 static int
 wimfs_mknod(const char *path, mode_t mode, dev_t rdev)
 {
@@ -1871,11 +1908,12 @@ wimfs_mknod(const char *path, mode_t mode, dev_t rdev)
        struct fuse_context *fuse_ctx = fuse_get_context();
        struct wimfs_context *wimfs_ctx = WIMFS_CTX(fuse_ctx);
 
-       if (!S_ISREG(mode))
-               return -EPERM;
-
        if ((wimfs_ctx->mount_flags & WIMLIB_MOUNT_FLAG_STREAM_INTERFACE_WINDOWS)
             && (stream_name = path_stream_name(path))) {
+
+               if (!S_ISREG(mode))
+                       return -EPERM;
+
                /* Make an alternate data stream */
                struct wim_ads_entry *new_entry;
                struct wim_inode *inode;
@@ -1896,8 +1934,12 @@ wimfs_mknod(const char *path, mode_t mode, dev_t rdev)
                        return -ENOMEM;
                return 0;
        } else {
-               /* Make a normal file (not an alternate data stream) */
-               return create_dentry(fuse_ctx, path, mode | S_IFREG,
+               if (!S_ISREG(mode) &&
+                   !(wimfs_ctx->mount_flags & WIMLIB_MOUNT_FLAG_UNIX_DATA))
+                       return -EPERM;
+
+               /* Make a regular file, device node, named pipe, or socket.  */
+               return create_dentry(fuse_ctx, path, mode, rdev,
                                     FILE_ATTRIBUTE_NORMAL, NULL);
        }
 }
@@ -2234,7 +2276,7 @@ wimfs_symlink(const char *to, const char *from)
        struct wim_dentry *dentry;
        int ret;
 
-       ret = create_dentry(fuse_ctx, from, S_IFLNK | 0777,
+       ret = create_dentry(fuse_ctx, from, S_IFLNK | 0777, 0,
                            FILE_ATTRIBUTE_REPARSE_POINT, &dentry);
        if (ret == 0) {
                dentry->d_inode->i_reparse_tag = WIM_IO_REPARSE_TAG_SYMLINK;