|
|
1.1 root 1: #include "sys/param.h"
2: #include "sys/user.h"
3: #include "sys/filsys.h"
4: #include "sys/file.h"
5: #include "sys/conf.h"
6: #include "sys/inode.h"
7: #include "sys/stream.h"
8: #include "sys/buf.h"
9: #include "sys/acct.h"
10:
11: /*
12: * Convert a user supplied
13: * file descriptor into a pointer
14: * to a file structure.
15: * Only task is to check range
16: * of the descriptor.
17: */
18:
19: #ifndef getf /* done inline */
20:
21: struct file *
22: getf(f)
23: register int f;
24: {
25: register struct file *fp;
26:
27: if ((unsigned)f >= NOFILE || (fp = u.u_ofile[f]) == NULL)
28: return (NULL);
29: return (fp);
30: }
31:
32: #endif
33:
34: /*
35: * Internal form of close.
36: * Decrement reference count on
37: * file structure.
38: * Decrement reference count on the inode following
39: * removal to the referencing file structure.
40: */
41: closef(fp)
42: register struct file *fp;
43: {
44: struct inode *ip;
45:
46: if(fp == NULL)
47: return;
48: if (fp->f_count > 1) {
49: fp->f_count--;
50: return;
51: }
52: ip = fp->f_inode;
53: plock(ip);
54: iput(ip);
55: fp->f_count = 0;
56: }
57:
58: /*
59: * close the file opened on ip
60: * called from iput when last reference is removed;
61: * ip is locked, and i_count == 1
62: *
63: * free files with no links;
64: * call device driver for special files
65: */
66:
67: extern int rootfstyp;
68: extern dev_t rootdev;
69:
70: closei(ip)
71: register struct inode *ip;
72: {
73: register dev_t dev;
74: register int (*cfunc)();
75:
76: if (ip->i_sptr)
77: stclose(ip, 1);
78: if ((ip->i_flag & IOPEN) == 0)
79: return;
80: ip->i_flag &=~ IOPEN;
81: if(ip->i_fstyp) /* temporary hack */
82: return;
83: dev = (dev_t)ip->i_un.i_rdev;
84: switch(ip->i_mode & IFMT) {
85:
86: case IFCHR:
87: cfunc = cdevsw[major(dev)]->d_close;
88: break;
89:
90: case IFBLK:
91: if (rootfstyp == 0 && rootdev == dev) /* awful hack: root is not open */
92: return;
93: bflush(dev);
94: binval(dev);
95: cfunc = bdevsw[major(dev)]->d_close;
96: break;
97:
98: default:
99: return;
100: }
101: (*cfunc)(dev);
102: }
103:
104: /*
105: * the default open routine for the file system switch entry `t_open'
106: */
107: struct inode *
108: nullopen(ip, rw)
109: struct inode *ip;
110: {
111: return(ip);
112: }
113:
114: /*
115: * openi called to allow handler
116: * of special files to initialize and
117: * validate before actual IO.
118: * returns the inode,
119: * NULL if error.
120: * may return an alternate inode,
121: * in which event the original has been put.
122: *
123: * responsibilities of open routines (fs and stream):
124: * if an inode is returned, it is unlocked,
125: * and any other inode has been put.
126: * if an error happens, NULL is returned and ip is put.
127: */
128: struct inode *
129: openi(ip, rw)
130: register struct inode *ip;
131: {
132: register dev_t dev;
133:
134: dev = (dev_t)ip->i_un.i_rdev;
135: if (ip->i_sptr) /* stream is attached */
136: ip = stopen(cdevsw[major(dev)]->qinfo, dev, rw, ip);
137: else
138: ip = (*fstypsw[ip->i_fstyp]->t_open)(ip, rw);
139: if (ip)
140: ip->i_flag |= IOPEN;
141: else if (u.u_error == 0) /* temporary firewall */
142: panic("openi");
143: return (ip);
144: }
145:
146: /*
147: * Check mode permission on inode pointer.
148: * Mode is READ, WRITE or EXEC.
149: * In the case of WRITE, the
150: * read-only status of the file
151: * system is checked.
152: * Also in WRITE, prototype text
153: * segments cannot be written.
154: * The mode is shifted to select
155: * the owner/group/other fields.
156: * The super user is granted all
157: * permissions.
158: */
159: access(ip, mode)
160: register struct inode *ip;
161: {
162: register m;
163: register short *gp;
164:
165: m = mode;
166: if(m == IWRITE) {
167: if(ip->i_fstyp==0 && ip->i_un.i_bufp->b_un.b_filsys->s_ronly != 0) {
168: u.u_error = EROFS;
169: return(1);
170: }
171: if (ip->i_flag&ITEXT) /* try to free text */
172: xrele(ip);
173: if(ip->i_flag & ITEXT) {
174: u.u_error = ETXTBSY;
175: return(1);
176: }
177: }
178: if(u.u_uid == 0)
179: return(0);
180: if(u.u_uid != ip->i_uid) {
181: m >>= 3;
182: if(u.u_gid == ip->i_gid)
183: goto found;
184: gp = u.u_groups;
185: for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
186: if (ip->i_gid == *gp)
187: goto found;
188: m >>= 3;
189: }
190: found:
191: if((ip->i_mode&m) != 0)
192: return(0);
193:
194: u.u_error = EACCES;
195: return(1);
196: }
197:
198: /*
199: * check inode ownership.
200: * succeeds if the current user owns the file,
201: * or is the super-user.
202: */
203: accowner(ip)
204: register struct inode *ip;
205: {
206:
207: if(u.u_uid == ip->i_uid)
208: return(1);
209: if(suser())
210: return(1);
211: return(0);
212: }
213:
214: /*
215: * Return 0 if the file isn't open for writing, 1 if it is
216: */
217: writers(ip)
218: register struct inode *ip;
219: {
220: register struct file *fp;
221:
222: for (fp = file; fp < fileNFILE; fp++)
223: if (fp->f_count!=0 && fp->f_inode==ip && (fp->f_flag&FWRITE))
224: return(1);
225: return(0);
226: }
227:
228: /*
229: * Control concurrent access to a file. The possibile types are:
230: * - 1 writer and n readers (I1WNR)
231: * - 1 writer or n readers (ILCKD)
232: * The file pointers are searched. If an open with the given mode
233: * would result in a violation, errno is set to ECONC.
234: */
235: concurrency(ip, mode)
236: register struct inode *ip;
237: int mode;
238: {
239: switch(ip->i_mode&ICCTYP) {
240: case ISYNC:
241: if ((mode&FWRITE) && writers(ip))
242: u.u_error = ECONC;
243: break;
244: case IEXCL:
245: if ((mode&FWRITE) || writers(ip))
246: u.u_error = ECONC;
247: break;
248: }
249: }
250:
251: /*
252: * Test if the current user is the
253: * super user.
254: */
255: suser()
256: {
257:
258: if(u.u_uid == 0) {
259: u.u_acflag |= ASU;
260: return(1);
261: }
262: u.u_error = EPERM;
263: return(0);
264: }
265:
266: /*
267: * Allocate a user file descriptor.
268: */
269: ufalloc()
270: {
271: register i;
272:
273: for(i=0; i<NOFILE; i++)
274: if(u.u_ofile[i] == NULL) {
275: u.u_r.r_val1 = i;
276: u.u_pofile[i] = 0;
277: return(i);
278: }
279: u.u_error = EMFILE;
280: return(-1);
281: }
282:
283: struct file *lastf;
284: /*
285: * Allocate a user file descriptor
286: * and a file structure.
287: * Initialize the descriptor
288: * to point at the file structure.
289: */
290: struct file *
291: falloc()
292: {
293: register struct file *fp;
294: register i;
295:
296: i = ufalloc();
297: if (i < 0)
298: return(NULL);
299: if ((fp = allocfile()) == NULL) {
300: u.u_error = ENFILE;
301: return(NULL);
302: }
303: u.u_ofile[i] = fp;
304: return (fp);
305: }
306:
307: /*
308: * allocate file structure
309: */
310: struct file *
311: allocfile()
312: {
313: register struct file *fp;
314:
315: if (lastf == 0)
316: lastf = file;
317: for (fp = lastf; fp < fileNFILE; fp++)
318: if (fp->f_count == 0)
319: goto gotit;
320: for (fp = file; fp < lastf; fp++)
321: if (fp->f_count == 0)
322: goto gotit;
323: tablefull("file");
324: return (NULL);
325: gotit:
326: lastf = fp + 1;
327: fp->f_count++;
328: fp->f_offset = ltoL(0);
329: return(fp);
330: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.