1: #
2: /*
3: */
4:
5: #include "../param.h"
6: #include "../user.h"
7: #include "../filsys.h"
8: #include "../file.h"
9: #include "../conf.h"
10: #include "../inode.h"
11: #include "../reg.h"
12:
13: /*
14: * Convert a user supplied
15: * file descriptor into a pointer
16: * to a file structure.
17: * Only task is to check range
18: * of the descriptor.
19: */
20: getf(f)
21: {
22: register *fp, rf;
23:
24: rf = f;
25: if(rf<0 || rf>=NOFILE)
26: goto bad;
27: fp = u.u_ofile[rf];
28: if(fp != NULL)
29: return(fp);
30: bad:
31: u.u_error = EBADF;
32: return(NULL);
33: }
34:
35: /*
36: * Internal form of close.
37: * Decrement reference count on
38: * file structure and call closei
39: * on last closef.
40: * Also make sure the pipe protocol
41: * does not constipate.
42: */
43: closef(fp)
44: int *fp;
45: {
46: register *rfp, *ip;
47:
48: rfp = fp;
49: if(rfp->f_flag&FPIPE) {
50: ip = rfp->f_inode;
51: ip->i_mode =& ~(IREAD|IWRITE);
52: wakeup(ip+1);
53: wakeup(ip+2);
54: }
55: if(rfp->f_count <= 1)
56: closei(rfp->f_inode, rfp->f_flag&FWRITE);
57: rfp->f_count--;
58: }
59:
60: /*
61: * Decrement reference count on an
62: * inode due to the removal of a
63: * referencing file structure.
64: * On the last closei, switchout
65: * to the close entry point of special
66: * device handler.
67: * Note that the handler gets called
68: * on every open and only on the last
69: * close.
70: */
71: closei(ip, rw)
72: int *ip;
73: {
74: register *rip;
75: register dev, maj;
76:
77: rip = ip;
78: dev = rip->i_addr[0];
79: maj = rip->i_addr[0].d_major;
80: if(rip->i_count <= 1)
81: switch(rip->i_mode&IFMT) {
82:
83: case IFCHR:
84: (*cdevsw[maj].d_close)(dev, rw);
85: break;
86:
87: case IFBLK:
88: (*bdevsw[maj].d_close)(dev, rw);
89: }
90: iput(rip);
91: }
92:
93: /*
94: * openi called to allow handler
95: * of special files to initialize and
96: * validate before actual IO.
97: * Called on all sorts of opens
98: * and also on mount.
99: */
100: openi(ip, rw)
101: int *ip;
102: {
103: register *rip;
104: register dev, maj;
105:
106: rip = ip;
107: dev = rip->i_addr[0];
108: maj = rip->i_addr[0].d_major;
109: switch(rip->i_mode&IFMT) {
110:
111: case IFCHR:
112: if(maj >= nchrdev)
113: goto bad;
114: (*cdevsw[maj].d_open)(dev, rw);
115: break;
116:
117: case IFBLK:
118: if(maj >= nblkdev)
119: goto bad;
120: (*bdevsw[maj].d_open)(dev, rw);
121: }
122: return;
123:
124: bad:
125: u.u_error = ENXIO;
126: }
127:
128: /*
129: * Check mode permission on inode pointer.
130: * Mode is READ, WRITE or EXEC.
131: * In the case of WRITE, the
132: * read-only status of the file
133: * system is checked.
134: * Also in WRITE, prototype text
135: * segments cannot be written.
136: * The mode is shifted to select
137: * the owner/group/other fields.
138: * The super user is granted all
139: * permissions except for EXEC where
140: * at least one of the EXEC bits must
141: * be on.
142: */
143: access(aip, mode)
144: int *aip;
145: {
146: register *ip, m;
147:
148: ip = aip;
149: m = mode;
150: if(m == IWRITE) {
151: if(getfs(ip->i_dev)->s_ronly != 0) {
152: u.u_error = EROFS;
153: return(1);
154: }
155: if(ip->i_flag & ITEXT) {
156: u.u_error = ETXTBSY;
157: return(1);
158: }
159: }
160: if(u.u_uid == 0) {
161: if(m == IEXEC && (ip->i_mode &
162: (IEXEC | (IEXEC>>3) | (IEXEC>>6))) == 0)
163: goto bad;
164: return(0);
165: }
166: if(u.u_uid != ip->i_uid) {
167: m =>> 3;
168: if(u.u_gid != ip->i_gid)
169: m =>> 3;
170: }
171: if((ip->i_mode&m) != 0)
172: return(0);
173:
174: bad:
175: u.u_error = EACCES;
176: return(1);
177: }
178:
179: /*
180: * Look up a pathname and test if
181: * the resultant inode is owned by the
182: * current user.
183: * If not, try for super-user.
184: * If permission is granted,
185: * return inode pointer.
186: */
187: owner()
188: {
189: register struct inode *ip;
190: extern uchar();
191:
192: if ((ip = namei(uchar, 0)) == NULL)
193: return(NULL);
194: if(u.u_uid == ip->i_uid)
195: return(ip);
196: if (suser())
197: return(ip);
198: iput(ip);
199: return(NULL);
200: }
201:
202: /*
203: * Test if the current user is the
204: * super user.
205: */
206: suser()
207: {
208:
209: if(u.u_uid == 0)
210: return(1);
211: u.u_error = EPERM;
212: return(0);
213: }
214:
215: /*
216: * Allocate a user file descriptor.
217: */
218: ufalloc()
219: {
220: register i;
221:
222: for (i=0; i<NOFILE; i++)
223: if (u.u_ofile[i] == NULL) {
224: u.u_ar0[R0] = i;
225: return(i);
226: }
227: u.u_error = EMFILE;
228: return(-1);
229: }
230:
231: /*
232: * Allocate a user file descriptor
233: * and a file structure.
234: * Initialize the descriptor
235: * to point at the file structure.
236: *
237: * no file -- if there are no available
238: * file structures.
239: */
240: falloc()
241: {
242: register struct file *fp;
243: register i;
244:
245: if ((i = ufalloc()) < 0)
246: return(NULL);
247: for (fp = &file[0]; fp < &file[NFILE]; fp++)
248: if (fp->f_count==0) {
249: u.u_ofile[i] = fp;
250: fp->f_count++;
251: fp->f_offset[0] = 0;
252: fp->f_offset[1] = 0;
253: return(fp);
254: }
255: printf("no file\n");
256: u.u_error = ENFILE;
257: return(NULL);
258: }
Defined functions
getf
defined in line
20; used 6 times