X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fmount_image.c;h=168ee8523bc9bc038a9c678bdbf9c2f50fce62e9;hb=1ea0ec53c60c4b34b594d1d4785f00fbef76c366;hp=e1ff886f583d89298eacd851e3da8d61bf528dd6;hpb=b5b9681794d1f5f13350e3567f6f6e74f5c779cf;p=wimlib diff --git a/src/mount_image.c b/src/mount_image.c index e1ff886f..168ee852 100644 --- a/src/mount_image.c +++ b/src/mount_image.c @@ -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;