diff options
Diffstat (limited to 'sys/lib/libsa/ufs.c')
-rw-r--r-- | sys/lib/libsa/ufs.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/sys/lib/libsa/ufs.c b/sys/lib/libsa/ufs.c index e768beaef24..9ba26a49048 100644 --- a/sys/lib/libsa/ufs.c +++ b/sys/lib/libsa/ufs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufs.c,v 1.26 2016/11/25 17:00:33 reyk Exp $ */ +/* $OpenBSD: ufs.c,v 1.27 2019/08/03 15:22:17 deraadt Exp $ */ /* $NetBSD: ufs.c,v 1.16 1996/09/30 16:01:22 ws Exp $ */ /*- @@ -81,6 +81,7 @@ struct file { off_t f_seekp; /* seek pointer */ struct fs *f_fs; /* pointer to super-block */ struct ufs1_dinode f_di; /* copy of on-disk inode */ + ufsino_t f_ino; /* our inode number */ int f_nindir[NIADDR]; /* number of blocks mapped by indirect block at level i */ @@ -95,6 +96,7 @@ struct file { }; static int read_inode(ufsino_t, struct open_file *); +static int chmod_inode(ufsino_t, struct open_file *, mode_t); static int block_map(struct open_file *, daddr32_t, daddr32_t *); static int buf_read_file(struct open_file *, char **, size_t *); static int search_directory(char *, struct open_file *, ufsino_t *); @@ -154,6 +156,50 @@ out: } /* + * Read a new inode into a file structure. + */ +static int +chmod_inode(ufsino_t inumber, struct open_file *f, mode_t mode) +{ + struct file *fp = (struct file *)f->f_fsdata; + struct fs *fs = fp->f_fs; + char *buf; + size_t rsize; + int rc; + + /* + * Read inode and save it. + */ + buf = alloc(fs->fs_bsize); + twiddle(); + rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ, + fsbtodb(fs, (daddr32_t)ino_to_fsba(fs, inumber)), fs->fs_bsize, + buf, &rsize); + if (rc) + goto out; + if (rsize != (size_t)fs->fs_bsize) { + rc = EIO; + goto out; + } + + { + struct ufs1_dinode *dp; + + dp = &((struct ufs1_dinode *)buf)[ino_to_fsbo(fs, inumber)]; + dp->di_mode = mode; + } + + twiddle(); + rc = (f->f_dev->dv_strategy)(f->f_devdata, F_WRITE, + fsbtodb(fs, (daddr32_t)ino_to_fsba(fs, inumber)), fs->fs_bsize, + buf, NULL); + +out: + free(buf, fs->fs_bsize); + return (rc); +} + +/* * Given an offset in a file, find the disk block number that * contains that block. */ @@ -522,6 +568,7 @@ ufs_open(char *path, struct open_file *f) /* * Found terminal component. */ + fp->f_ino = inumber; rc = 0; out: if (buf) @@ -639,6 +686,14 @@ ufs_stat(struct open_file *f, struct stat *sb) return (0); } +int +ufs_fchmod(struct open_file *f, mode_t mode) +{ + struct file *fp = (struct file *)f->f_fsdata; + + return chmod_inode(fp->f_ino, f, mode); +} + #ifndef NO_READDIR int ufs_readdir(struct open_file *f, char *name) |