1: /*
2: * SCCS id @(#)sys3.c 2.1 (Berkeley) 9/4/83
3: */
4:
5: #include "param.h"
6: #include <sys/systm.h>
7: #include <sys/ino.h>
8: #include <sys/reg.h>
9: #include <sys/buf.h>
10: #include <sys/filsys.h>
11: #include <sys/mount.h>
12: #include <sys/dir.h>
13: #include <sys/user.h>
14: #include <sys/inode.h>
15: #include <sys/file.h>
16: #include <sys/conf.h>
17: #include <sys/stat.h>
18: #include <sys/inline.h>
19:
20:
21: /*
22: * the fstat system call.
23: */
24: fstat()
25: {
26: register struct file *fp;
27: register struct a {
28: int fdes;
29: struct stat *sb;
30: } *uap;
31:
32: uap = (struct a *)u.u_ap;
33: fp = getf(uap->fdes);
34: if (fp == NULL)
35: return;
36: #ifdef UCB_NET
37: if (fp->f_flag & FSOCKET)
38: u.u_error = sostat(fp->f_socket, uap->sb);
39: else
40: #endif
41: stat1(fp->f_inode, uap->sb, fp->f_flag & FPIPE? fp->f_un.f_offset: (off_t) 0);
42: }
43:
44: /*
45: * the stat system call.
46: */
47: stat()
48: {
49: register struct inode *ip;
50: register struct a {
51: char *fname;
52: struct stat *sb;
53: } *uap;
54:
55: uap = (struct a *)u.u_ap;
56: #ifndef UCB_SYMLINKS
57: ip = namei(uchar, LOOKUP);
58: #else
59: ip = namei(uchar, LOOKUP, 1);
60: #endif
61: if (ip == NULL)
62: return;
63: stat1(ip, uap->sb, (off_t)0);
64: iput(ip);
65: }
66:
67: #ifdef UCB_SYMLINKS
68: /*
69: * Lstat system call; like stat but doesn't follow links.
70: */
71: lstat()
72: {
73: register struct inode *ip;
74: register struct a {
75: char *fname;
76: struct stat *sb;
77: } *uap;
78:
79: uap = (struct a *)u.u_ap;
80: ip = namei(uchar, 0, 0);
81: if (ip == NULL)
82: return;
83: stat1(ip, uap->sb, (off_t)0);
84: iput(ip);
85: }
86: #endif
87:
88: /*
89: * The basic routine for fstat and stat:
90: * get the inode and pass appropriate parts back.
91: */
92: stat1(ip, ub, pipeadj)
93: register struct inode *ip;
94: struct stat *ub;
95: off_t pipeadj;
96: {
97: register struct dinode *dp;
98: register struct buf *bp;
99: struct stat ds;
100:
101: #ifdef UCB_FSFIX
102: IUPDAT(ip, &time, &time, 0);
103: #else
104: IUPDAT(ip, &time, &time);
105: #endif
106: /*
107: * first copy from inode table
108: */
109: ds.st_dev = ip->i_dev;
110: ds.st_ino = ip->i_number;
111: ds.st_mode = ip->i_mode;
112: ds.st_nlink = ip->i_nlink;
113: ds.st_uid = ip->i_uid;
114: ds.st_gid = ip->i_gid;
115: ds.st_rdev = (dev_t)ip->i_un.i_rdev;
116: ds.st_size = ip->i_size - pipeadj;
117: /*
118: * next the dates in the disk
119: */
120: bp = bread(ip->i_dev, itod(ip->i_number));
121: dp = (struct dinode *) mapin(bp);
122: dp += itoo(ip->i_number);
123: ds.st_atime = dp->di_atime;
124: ds.st_mtime = dp->di_mtime;
125: ds.st_ctime = dp->di_ctime;
126: mapout(bp);
127: brelse(bp);
128: if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
129: u.u_error = EFAULT;
130: }
131:
132: /*
133: * the dup system call.
134: */
135: dup()
136: {
137: register struct file *fp;
138: register struct a {
139: int fdes;
140: int fdes2;
141: } *uap;
142: register i, m;
143:
144: uap = (struct a *)u.u_ap;
145: m = uap->fdes & ~077;
146: uap->fdes &= 077;
147: fp = getf(uap->fdes);
148: if (fp == NULL)
149: return;
150: if ((m&0100) == 0) {
151: if ((i = ufalloc()) < 0)
152: return;
153: } else {
154: i = uap->fdes2;
155: if (i<0 || i>=NOFILE) {
156: u.u_error = EBADF;
157: return;
158: }
159: u.u_r.r_val1 = i;
160: }
161: if (i!=uap->fdes) {
162: if (u.u_ofile[i]!=NULL)
163: #ifndef UCB_NET
164: closef(u.u_ofile[i]);
165: #else
166: closef(u.u_ofile[i],0);
167: #endif
168: u.u_ofile[i] = fp;
169: fp->f_count++;
170: }
171: }
172:
173: /*
174: * the mount system call.
175: */
176: smount()
177: {
178: dev_t dev;
179: char *cp;
180: register struct inode *ip;
181: register struct mount *mp;
182: struct mount *smp;
183: register struct filsys *fp;
184: struct buf *bp;
185: register struct a {
186: char *fspec;
187: char *freg;
188: int ronly;
189: } *uap;
190:
191: uap = (struct a *)u.u_ap;
192: dev = getmdev();
193: if (u.u_error || !suser())
194: return;
195: u.u_dirp = (caddr_t)uap->freg;
196: #ifndef UCB_SYMLINKS
197: ip = namei(uchar, LOOKUP);
198: #else
199: ip = namei(uchar, LOOKUP, 1);
200: #endif
201: if (ip == NULL)
202: return;
203: if (ip->i_count != 1 || (ip->i_mode & (IFBLK & IFCHR)) != 0)
204: goto out;
205: smp = NULL;
206: for(mp = mount; mp < mountNMOUNT; mp++) {
207: if (mp->m_inodp != NULL) {
208: if (dev == mp->m_dev)
209: goto out;
210: } else
211: if (smp == NULL)
212: smp = mp;
213: }
214: mp = smp;
215: if (mp == NULL)
216: goto out;
217: (*bdevsw[major(dev)].d_open)(dev, !uap->ronly);
218: if (u.u_error)
219: goto out;
220: bp = bread(dev, SUPERB);
221: if (u.u_error) {
222: brelse(bp);
223: goto out1;
224: }
225: mp->m_inodp = ip;
226: mp->m_dev = dev;
227: fp = &mp->m_filsys;
228: bcopy((caddr_t) mapin(bp), (caddr_t)fp, sizeof(struct filsys));
229: mapout(bp);
230: fp->s_ilock = 0;
231: fp->s_flock = 0;
232: fp->s_ronly = uap->ronly & 1;
233: #ifdef UCB_IHASH
234: fp->s_nbehind = 0;
235: fp->s_lasti = 1;
236: #endif
237: u.u_dirp = uap->freg;
238: for (cp = fp->s_fsmnt; cp < &fp->s_fsmnt[sizeof(fp->s_fsmnt) - 1];)
239: if ((*cp++ = uchar()) == 0)
240: u.u_dirp--; /* get 0 again */
241: *cp = 0;
242: brelse(bp);
243: ip->i_flag |= IMOUNT;
244: prele(ip);
245: return;
246:
247: out:
248: u.u_error = EBUSY;
249: out1:
250: iput(ip);
251: }
252:
253: /*
254: * the umount system call.
255: */
256: sumount()
257: {
258: dev_t dev;
259: register struct inode *ip;
260: register struct mount *mp;
261: register struct buf *bp;
262: struct buf *dp;
263:
264: dev = getmdev();
265: if (u.u_error || !suser())
266: return;
267: xumount(dev); /* remove unused sticky files from text table */
268: update();
269: for (mp = mount; mp < mountNMOUNT; mp++)
270: if (mp->m_inodp != NULL && dev == mp->m_dev) {
271: for(ip = inode; ip < inodeNINODE; ip++)
272: if (ip->i_number != 0 && dev == ip->i_dev) {
273: u.u_error = EBUSY;
274: return;
275: }
276: (*bdevsw[major(dev)].d_close)(dev, 0);
277: dp = bdevsw[major(dev)].d_tab;
278: for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) {
279: (void) _spl6();
280: if (bp->b_dev == dev) {
281: #ifdef UCB_BHASH
282: bunhash(bp);
283: #endif
284: bp->b_dev = NODEV;
285: }
286: (void) _spl0();
287: }
288: ip = mp->m_inodp;
289: ip->i_flag &= ~IMOUNT;
290: plock(ip);
291: iput(ip);
292: mp->m_inodp = NULL;
293: return;
294: }
295:
296: u.u_error = EINVAL;
297: }
298:
299: /*
300: * Common code for mount and umount.
301: * Check that the user's argument is a reasonable
302: * thing on which to mount, and return the device number if so.
303: */
304: dev_t
305: getmdev()
306: {
307: register dev_t dev;
308: register struct inode *ip;
309:
310: #ifndef UCB_SYMLINKS
311: ip = namei(uchar, LOOKUP);
312: #else
313: ip = namei(uchar, LOOKUP, 1);
314: #endif
315: if (ip == NULL)
316: return(NODEV);
317: if ((ip->i_mode&IFMT) != IFBLK)
318: u.u_error = ENOTBLK;
319: dev = (dev_t)ip->i_un.i_rdev;
320: if (major(dev) >= nblkdev)
321: u.u_error = ENXIO;
322: iput(ip);
323: return(dev);
324: }
325:
326: #ifdef UCB_SYMLINKS
327: /*
328: * Return target name of a symbolic link
329: */
330: readlink()
331: {
332: register struct inode *ip;
333: register struct a {
334: char *name;
335: char *buf;
336: int count;
337: } *uap;
338:
339: ip = namei(uchar, 0, 0);
340: if (ip == NULL)
341: return;
342: if ((ip->i_mode&IFMT) != IFLNK) {
343: u.u_error = ENXIO;
344: goto out;
345: }
346: uap = (struct a *)u.u_ap;
347: u.u_offset = 0;
348: u.u_base = uap->buf;
349: u.u_count = uap->count;
350: u.u_segflg = 0;
351: readi(ip);
352: out:
353: iput(ip);
354: u.u_r.r_val1 = uap->count - u.u_count;
355: }
356:
357: /*
358: * symlink -- make a symbolic link
359: */
360: symlink()
361: {
362: register struct a {
363: char *target;
364: char *linkname;
365: } *uap;
366: register struct inode *ip;
367: register char *tp;
368: register c, nc;
369:
370: uap = (struct a *)u.u_ap;
371: tp = uap->target;
372: nc = 0;
373: while (c = fubyte(tp)) {
374: if (c < 0) {
375: u.u_error = EFAULT;
376: return;
377: }
378: tp++;
379: nc++;
380: }
381: u.u_dirp = uap->linkname;
382: ip = namei(uchar, 1, 0);
383: if (ip) {
384: iput(ip);
385: u.u_error = EEXIST;
386: return;
387: }
388: if (u.u_error)
389: return;
390: ip = maknode(IFLNK | 0777);
391: if (ip == NULL)
392: return;
393: u.u_base = uap->target;
394: u.u_count = nc;
395: u.u_offset = 0;
396: u.u_segflg = 0;
397: writei(ip);
398: iput(ip);
399: }
400: #endif UCB_SYMLINKS
Defined functions
dup
defined in line
135; used 2 times
fstat
defined in line
24; used 2 times
lstat
defined in line
71;
never used
stat
defined in line
47; used 2 times
stat1
defined in line
92; used 3 times
Defined struct's
a
defined in line
362; used 14 times