/* ufs_vnops.c 4.41 82/10/19 */
#include "../h/descrip.h"
#include "../h/socketvar.h"
register struct inode
**ipp
;
register struct inode
*ip
;
if((ip
->i_mode
&IFMT
) != IFDIR
) {
register struct inode
*ip
;
int checkpermissions
= 1;
uap
= (struct a
*)u
.u_ap
;
if (uap
->flags
&FCREATE
) {
ip
= maknode(uap
->mode
&07777&(~ISVTX
));
uap
->flags
&= ~FTRUNCATE
;
open1(ip
, ++uap
->flags
, checkpermissions
);
register struct inode
*ip
;
uap
= (struct a
*)u
.u_ap
;
ip
= maknode(uap
->fmode
&07777&(~ISVTX
));
open1(ip
, FWRITE
|FTRUNCATE
, 0);
* Common code for open and creat.
* Check permissions (if we haven't done so already),
* allocate an open file structure, and call
* the device open routine, if any.
open1(ip
, mode
, checkpermissions
)
register struct inode
*ip
;
register struct file
*fp
;
if ((ip
->i_mode
&IFMT
) == IFDIR
) {
* Check locking on inode. Release "inode lock"
* while doing so in case we block inside flocki.
if (mode
&(FRDLOCK
|FWRLOCK
)) {
flags
= flocki(ip
, 0, mode
);
if ((fp
= falloc()) == NULL
)
fp
->f_flag
= mode
& FMODES
;
u
.u_error
= openi(ip
, mode
);
register struct inode
*ip
;
uap
= (struct a
*)u
.u_ap
;
ip
= maknode(uap
->fmode
);
* Want to be able to use this to make badblock
* inodes, so don't truncate the dev number.
ip
->i_flag
|= IACC
|IUPD
|ICHG
;
register struct inode
*ip
, *xp
;
uap
= (struct a
*)u
.u_ap
;
ip
= namei(uchar
, 0, 1); /* well, this routine is doomed anyhow */
if ((ip
->i_mode
&IFMT
)==IFDIR
&& !suser()) {
iupdat(ip
, &time
, &time
, 1);
u
.u_dirp
= (caddr_t
)uap
->linkname
;
if (u
.u_pdir
->i_dev
!= ip
->i_dev
) {
* symlink -- make a symbolic link
register struct inode
*ip
;
uap
= (struct a
*)u
.u_ap
;
u
.u_dirp
= uap
->linkname
;
ip
= maknode(IFLNK
| 0777);
u
.u_error
= rdwri(UIO_WRITE
, ip
, uap
->target
, nc
, 0, 0, (int *)0);
* Hard to avoid races here, especially
* in unlinking directories.
register struct inode
*ip
, *pp
;
* to avoid hanging on the iget
if (pp
->i_number
== u
.u_dent
.d_ino
) {
ip
= iget(pp
->i_dev
, pp
->i_fs
, u
.u_dent
.d_ino
);
if((ip
->i_mode
&IFMT
)==IFDIR
&& !suser())
* Don't unlink a mounted file.
if (ip
->i_dev
!= pp
->i_dev
) {
xrele(ip
); /* try once to free text */
register struct file
*fp
;
uap
= (struct a
*)u
.u_ap
;
if (fp
->f_type
== DTYPE_SOCKET
) {
if (uap
->sbase
== FSEEK_RELATIVE
)
uap
->off
+= fp
->f_offset
;
else if (uap
->sbase
== FSEEK_EOF
)
uap
->off
+= fp
->f_inode
->i_size
;
register struct inode
*ip
;
uap
= (struct a
*)u
.u_ap
;
if (uap
->fmode
&FACCESS_READ
&& access(ip
, IREAD
))
if (uap
->fmode
&FACCESS_WRITE
&& access(ip
, IWRITE
))
if (uap
->fmode
&FACCESS_EXECUTE
&& access(ip
, IEXEC
))
register struct file
*fp
;
uap
= (struct a
*)u
.u_ap
;
if (fp
->f_type
== DTYPE_SOCKET
)
u
.u_error
= sostat(fp
->f_socket
, uap
->sb
);
stat1(fp
->f_inode
, uap
->sb
);
* Stat system call. This version follows links.
register struct inode
*ip
;
uap
= (struct a
*)u
.u_ap
;
* Lstat system call. This version does not follow links.
register struct inode
*ip
;
uap
= (struct a
*)u
.u_ap
;
* The basic routine for fstat and stat:
* get the inode and pass appropriate parts back.
register struct inode
*ip
;
IUPDAT(ip
, &time
, &time
, 0);
ds
.st_ino
= ip
->i_number
;
ds
.st_nlink
= ip
->i_nlink
;
ds
.st_rdev
= (dev_t
)ip
->i_rdev
;
ds
.st_atime
= ip
->i_atime
;
ds
.st_mtime
= ip
->i_mtime
;
ds
.st_ctime
= ip
->i_ctime
;
/* this doesn't belong here */
if ((ip
->i_mode
&IFMT
) == IFBLK
)
ds
.st_blksize
= BLKDEV_IOSIZE
;
else if ((ip
->i_mode
&IFMT
) == IFCHR
)
ds
.st_blksize
= MAXBSIZE
;
ds
.st_blksize
= ip
->i_fs
->fs_bsize
;
if (copyout((caddr_t
)&ds
, (caddr_t
)ub
, sizeof(ds
)) < 0)
* Return target name of a symbolic link
register struct inode
*ip
;
} *uap
= (struct a
*)u
.u_ap
;
if ((ip
->i_mode
&IFMT
) != IFLNK
) {
u
.u_error
= rdwri(UIO_READ
, ip
, uap
->buf
, uap
->count
, 0, 0, &resid
);
u
.u_r
.r_val1
= uap
->count
- resid
;
uap
= (struct a
*)u
.u_ap
;
if ((ip
= owner(1)) == NULL
)
register struct inode
*ip
;
register struct file
*fp
;
uap
= (struct a
*)u
.u_ap
;
if (fp
->f_type
== DTYPE_SOCKET
) {
if (u
.u_uid
!= ip
->i_uid
&& !suser()) {
register struct inode
*ip
;
for (gp
= u
.u_groups
; gp
< &u
.u_groups
[NGROUPS
]; gp
++)
if (u
.u_quota
->q_syflags
& QF_UMASK
&& u
.u_uid
!= 0 &&
(ip
->i_mode
& IFMT
) != IFCHR
)
ip
->i_mode
|= mode
&07777;
if (ip
->i_flag
&ITEXT
&& (ip
->i_mode
&ISVTX
)==0)
uap
= (struct a
*)u
.u_ap
;
if (!suser() || (ip
= owner(0)) == NULL
)
chown1(ip
, uap
->uid
, uap
->gid
);
register struct inode
*ip
;
register struct file
*fp
;
uap
= (struct a
*)u
.u_ap
;
if (fp
->f_type
== DTYPE_SOCKET
) {
chown1(ip
, uap
->uid
, uap
->gid
);
* Perform chown operation on inode ip;
* inode must be locked prior to call.
register struct inode
*ip
;
* This doesn't allow for holes in files (which hopefully don't
* happen often in files that we chown), and is not accurate anyway
* (eg: it totally ignores 3 level indir blk files - but hopefully
* noone who can make a file that big will have a quota)
register struct fs
*fs
= ip
->i_fs
;
if (ip
->i_size
> (change
= NDADDR
* fs
->fs_bsize
)) {
size
= blkroundup(fs
, ip
->i_size
) - change
;
/* this assumes NIADDR <= 2 */
if (size
> NINDIR(fs
) * fs
->fs_bsize
)
change
= fragroundup(fs
, ip
->i_size
);
chkiq(ip
->i_dev
, ip
, ip
->i_uid
, 1);
* keep uid/gid's in sane range -- no err,
* so chown(file, uid, -1) will do something useful
if (uid
>= 0 && uid
<= 32767) /* should have a constant */
if (gid
>= 0 && gid
<= 32767) /* same here */
ip
->i_mode
&= ~(ISUID
|ISGID
);
ip
->i_dquot
= inoquota(ip
);
chkiq(ip
->i_dev
, NULL
, uid
, 1);
* Set IUPD and IACC times on file.
register struct inode
*ip
;
uap
= (struct a
*)u
.u_ap
;
if ((ip
= owner(1)) == NULL
)
if (copyin((caddr_t
)uap
->tptr
, (caddr_t
)tv
, sizeof(tv
))) {
ip
->i_flag
|= IACC
|IUPD
|ICHG
;
tv0
.tv_sec
= tv
[0]; tv0
.tv_usec
= 0;
tv1
.tv_sec
= tv
[1]; tv1
.tv_usec
= 0;
iupdat(ip
, &tv0
, &tv1
, 0);
register struct file
*fp
;
uap
= (struct a
*)u
.u_ap
;
if (fp
->f_type
== DTYPE_SOCKET
) { /* XXX */
flags
= u
.u_pofile
[uap
->fd
] & (RDLOCK
|WRLOCK
);
funlocki(fp
->f_inode
, flags
);
u
.u_pofile
[uap
->fd
] &= ~(RDLOCK
|WRLOCK
);
* No reason to write lock a file we've already
* write locked, similarly with a read lock.
if ((flags
&WRLOCK
) && (cmd
&FWRLOCK
) ||
(flags
&RDLOCK
) && (cmd
&FRDLOCK
))
u
.u_pofile
[uap
->fd
] = flocki(fp
->f_inode
, u
.u_pofile
[uap
->fd
], cmd
);
} *uap
= (struct a
*)u
.u_ap
;
if ((ip
->i_mode
&IFMT
) == IFDIR
) {
} *uap
= (struct a
*)u
.u_ap
;
if (fp
->f_type
== DTYPE_SOCKET
) {
if ((fp
->f_flag
&FWRITE
) == 0) {
register struct inode
*ip
;
if ((mode
& IFMT
) == IFDIR
)
ipref
= dirpref(u
.u_pdir
->i_fs
);
ipref
= u
.u_pdir
->i_number
;
ip
= ialloc(u
.u_pdir
, ipref
, mode
);
if (ip
->i_dquot
!= NODQUOT
)
ip
->i_flag
|= IACC
|IUPD
|ICHG
;
ip
->i_mode
= mode
& ~u
.u_cmask
;
ip
->i_gid
= u
.u_pdir
->i_gid
;
ip
->i_dquot
= inoquota(ip
);
* Make sure inode goes to disk before directory entry.
iupdat(ip
, &time
, &time
, 1);
* write error occurred trying to update directory
* so must deallocate the inode