merge of 4.1b and 4.1c
[unix-history] / usr / src / sys / kern / vfs_vnops.c
CommitLineData
4f083fd7 1/* vfs_vnops.c 4.30 82/11/13 */
fc96c615
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/dir.h"
6#include "../h/user.h"
6459ebe0 7#include "../h/fs.h"
fc96c615
BJ
8#include "../h/file.h"
9#include "../h/conf.h"
10#include "../h/inode.h"
11#include "../h/reg.h"
12#include "../h/acct.h"
f5b8937b 13#include "../h/mount.h"
ae921915
BJ
14#include "../h/socket.h"
15#include "../h/socketvar.h"
f3156a73 16#include "../h/proc.h"
4f083fd7 17#include "../h/nami.h"
fc96c615 18
fc96c615 19/*
fdd90ee3 20 * Openi called to allow handler
fc96c615
BJ
21 * of special files to initialize and
22 * validate before actual IO.
23 */
6b4c7376 24openi(ip, mode)
fdd90ee3 25 register struct inode *ip;
fc96c615 26{
f356c336
BJ
27 dev_t dev = (dev_t)ip->i_rdev;
28 register u_int maj = major(dev);
fc96c615 29
fdd90ee3 30 switch (ip->i_mode&IFMT) {
fc96c615
BJ
31
32 case IFCHR:
fdd90ee3 33 if (maj >= nchrdev)
f356c336
BJ
34 return (ENXIO);
35 return ((*cdevsw[maj].d_open)(dev, mode));
fc96c615
BJ
36
37 case IFBLK:
fdd90ee3 38 if (maj >= nblkdev)
f356c336
BJ
39 return (ENXIO);
40 return ((*bdevsw[maj].d_open)(dev, mode));
fc96c615 41 }
f356c336 42 return (0);
fc96c615
BJ
43}
44
45/*
46 * Check mode permission on inode pointer.
47 * Mode is READ, WRITE or EXEC.
48 * In the case of WRITE, the
49 * read-only status of the file
50 * system is checked.
51 * Also in WRITE, prototype text
52 * segments cannot be written.
53 * The mode is shifted to select
54 * the owner/group/other fields.
55 * The super user is granted all
56 * permissions.
57 */
58access(ip, mode)
fdd90ee3
BJ
59 register struct inode *ip;
60 int mode;
fc96c615
BJ
61{
62 register m;
197da11b 63 register int *gp;
fc96c615
BJ
64
65 m = mode;
fdd90ee3 66 if (m == IWRITE) {
6459ebe0 67 if (ip->i_fs->fs_ronly != 0) {
77cc8249
BJ
68 if ((ip->i_mode & IFMT) != IFCHR &&
69 (ip->i_mode & IFMT) != IFBLK) {
70 u.u_error = EROFS;
71 return (1);
72 }
fc96c615
BJ
73 }
74 if (ip->i_flag&ITEXT) /* try to free text */
75 xrele(ip);
fdd90ee3 76 if (ip->i_flag & ITEXT) {
fc96c615 77 u.u_error = ETXTBSY;
fdd90ee3 78 return (1);
fc96c615
BJ
79 }
80 }
fdd90ee3
BJ
81 if (u.u_uid == 0)
82 return (0);
83 if (u.u_uid != ip->i_uid) {
fc96c615 84 m >>= 3;
197da11b
BJ
85 for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++)
86 if (ip->i_gid != *gp)
87 goto found;
88 m >>= 3;
89found:
90 ;
fc96c615 91 }
fdd90ee3
BJ
92 if ((ip->i_mode&m) != 0)
93 return (0);
fc96c615 94 u.u_error = EACCES;
fdd90ee3 95 return (1);
fc96c615
BJ
96}
97
98/*
99 * Look up a pathname and test if
100 * the resultant inode is owned by the
101 * current user.
102 * If not, try for super-user.
103 * If permission is granted,
104 * return inode pointer.
105 */
106struct inode *
5485e062
BJ
107owner(follow)
108 int follow;
fc96c615
BJ
109{
110 register struct inode *ip;
111
4f083fd7 112 ip = namei(uchar, LOOKUP, follow);
fdd90ee3
BJ
113 if (ip == NULL)
114 return (NULL);
115 if (u.u_uid == ip->i_uid)
116 return (ip);
117 if (suser())
118 return (ip);
fc96c615 119 iput(ip);
fdd90ee3 120 return (NULL);
fc96c615
BJ
121}
122
123/*
124 * Test if the current user is the
125 * super user.
126 */
127suser()
128{
129
fdd90ee3 130 if (u.u_uid == 0) {
fc96c615 131 u.u_acflag |= ASU;
fdd90ee3 132 return (1);
fc96c615
BJ
133 }
134 u.u_error = EPERM;
fdd90ee3 135 return (0);
fc96c615 136}