|
|
1.1 root 1: /*
2: * Mount a filesystem
3: */
4:
5: char helpmessage[] = "\
6: \
7: mount -- mount file system\n\
8: Usage: /etc/mount [ special directory [-fru] ]\n\
9: Options:\n\
10: -r Mount is read only\n\
11: -u No mount, just update '/etc/mnttab' and/or '/etc/mtab'\n\
12: The file system residing on the block special file 'special' becomes\n\
13: accessible through the pathname 'directory'.\n\
14: With no arguments, lists the currently mount file systems.\n\
15: If /etc/mtab appears out of date, due to reboot, the fact is noted.\n\
16: If /etc/mnttab is present, then the dates of mounting will be reported.\n\
17: \
18: ";
19:
20: #include <stdio.h>
21: #include <mtab.h>
22: #include <mnttab.h>
23: #include <sys/mount.h>
24: #include <errno.h>
25: #include <sys/filsys.h>
26: #include <canon.h>
27: #include <sys/stat.h>
28: #include <sys/timeb.h>
29:
30: int uflag; /* Update mount table only */
31: int rflag; /* Read-only mount */
32: int qmtab; /* Mtab is out of date */
33: char mtabf[] = "/etc/mtab";
34: char mnttabf[] = "/etc/mnttab"; /* System 5 style */
35: struct mtab mtab;
36: struct mnttab mnttab;
37: struct stat sbuf;
38: char mspec[MNAMSIZ];
39: extern FILE *getmtab();
40: extern FILE *getmnttab();
41: char *ctime();
42:
43: main(argc, argv)
44: char *argv[];
45: {
46: if (argc == 1)
47: mlist();
48: else {
49: if (argc==4 && *argv[3]=='-') {
50: getflags(argv[3]+1);
51: argc -= 1;
52: }
53: if (argc==3) {
54: domount(argv[1], argv[2], rflag);
55: } else
56: usage();
57: }
58: return (0);
59: }
60:
61: getflags(ap)
62: register char *ap;
63: {
64: register int c;
65:
66: while ((c = *ap++) != '\0')
67: switch (c) {
68: case 'r':
69: rflag = MFRON;
70: continue;
71:
72: case 'u':
73: uflag++;
74: continue;
75:
76: default:
77: usage();
78: }
79: }
80:
81: usage()
82: {
83: fprintf(stderr, helpmessage);
84: exit(1);
85: }
86:
87: merror(f)
88: char *f;
89: {
90: register int err;
91:
92: err = errno;
93: fprintf(stderr, "mount: %r", &f);
94: if (err == EBUSY)
95: fprintf(stderr, ": mount device or directory busy\n");
96: else if (err > 0 && err < sys_nerr)
97: fprintf(stderr, ": %s\n", sys_errlist[err]);
98: else
99: fprintf(stderr, ": unrecognized error\n");
100: exit(1);
101: }
102:
103: domount(special, name, flag)
104: char *special;
105: char *name;
106: int flag;
107: {
108: register FILE *fp;
109: register int openerr;
110: extern time_t time();
111:
112: chkname(name);
113: if (!uflag) {
114: chkspec(special);
115: if (mount(special, name, flag) != 0)
116: merror("%s on %s", special, name);
117: }
118: if ((fp = getmnttab()) == NULL) {
119: openerr |= 1;
120: } else {
121: mcopy(special, mspec);
122: while (fread(&mnttab, sizeof(mnttab), 1, fp) == 1) {
123: if (mnttab.mt_dev[0] == '\0'
124: || strncmp(mnttab.mt_filsys, mspec, MNTNSIZ) == 0) {
125: fseek(fp, (long)(-sizeof(mnttab)), 1);
126: break;
127: }
128: }
129: strncpy(mnttab.mt_dev, name, MNTNSIZ);
130: strncpy(mnttab.mt_filsys, mspec, MNTNSIZ);
131: mnttab.mt_ro_flg = flag;
132: mnttab.mt_time = time(NULL);
133: if (fwrite(&mnttab, sizeof(mnttab), 1, fp) != 1)
134: merror("writing %s", mnttabf);
135: fclose(fp);
136: }
137: if ((fp = getmtab()) == NULL) {
138: openerr |= 2;
139: } else {
140: mcopy(special, mspec);
141: while (fread(&mtab, sizeof(mtab), 1, fp) == 1) {
142: if (mtab.mt_name[0] == '\0'
143: || strncmp(mtab.mt_special, mspec, MNAMSIZ) == 0) {
144: fseek(fp, (long)(-sizeof(mtab)), 1);
145: break;
146: }
147: }
148: strncpy(mtab.mt_name, name, MNAMSIZ);
149: strncpy(mtab.mt_special, mspec, MNAMSIZ);
150: mtab.mt_flags = flag;
151: if (fwrite(&mtab, sizeof(mtab), 1, fp) != 1)
152: merror("writing %s", mtabf);
153: fclose(fp);
154: }
155: if (openerr == 3 && uflag)
156: merror("could not open %s or %s", mnttabf, mtabf);
157: }
158:
159: mlist()
160: {
161: register FILE *fp;
162:
163: if ((fp = getmnttab()) != NULL) {
164: while (fread(&mnttab, sizeof(mnttab), 1, fp) == 1)
165: if (*mnttab.mt_dev != '\0') {
166: printf("/dev/%.*s on %.*s", MNTNSIZ,
167: mnttab.mt_filsys, MNTNSIZ, mnttab.mt_dev);
168: if (mnttab.mt_ro_flg & MFRON)
169: printf(" (read only)");
170: else
171: printf(" (writeable)");
172: printf(" since %s", ctime(&mnttab.mt_time));
173: }
174: return;
175: }
176: if ((fp = getmtab()) != NULL) {
177: if (qmtab)
178: fprintf(stderr,
179: "mount: /etc/mtab older than /etc/boottime\n");
180: while (fread(&mtab, sizeof(mtab), 1, fp) == 1)
181: if (*mtab.mt_name != '\0') {
182: printf("/dev/%.*s on %.*s", MNAMSIZ,
183: mtab.mt_special, MNAMSIZ, mtab.mt_name);
184: if (mtab.mt_flags & MFRON)
185: printf(" (read only)");
186: printf("\n");
187: }
188: }
189: }
190:
191: FILE *
192: getmnttab()
193: {
194: return (fopen(mnttabf, "r+w"));
195: }
196:
197: FILE *
198: getmtab()
199: {
200: time_t boottime;
201:
202: if (stat("/etc/boottime", &sbuf) != 0)
203: boottime = (time_t)0;
204: else
205: boottime = sbuf.st_mtime;
206: if (stat(mtabf, &sbuf) != 0)
207: return (NULL);
208: if (sbuf.st_mtime < boottime)
209: qmtab = 1;
210: return (fopen(mtabf, "r+w"));
211: }
212:
213: chkname(name)
214: char *name;
215: {
216: if (stat(name, &sbuf) < 0)
217: merror("%s", name);
218: if ((sbuf.st_mode&S_IFMT) != S_IFDIR) {
219: errno = ENOTDIR;
220: merror("%s", name);
221: }
222: }
223:
224: chkspec(special)
225: char *special;
226: {
227: register FILE *fp;
228: struct filsys f;
229:
230: if (stat(special, &sbuf) < 0)
231: merror("%s", special);
232: if ((sbuf.st_mode&S_IFMT) != S_IFBLK) {
233: errno = ENOTBLK;
234: merror("%s", special);
235: }
236: if ((fp = fopen(special, "r")) == NULL)
237: merror("opening %s", special);
238: fseek(fp, (long)SUPERI*BSIZE, 0);
239: if (fread(&f, sizeof(f), 1, fp) != 1)
240: merror("%s", special);
241: canf(&f);
242: if ( ! tstf(&f)) {
243: fprintf(stderr,
244: "mount: %s: badly formed file system\n", special);
245: exit(1);
246: }
247: }
248:
249: canf(fp)
250: register struct filsys *fp;
251: {
252: register daddr_t *dp;
253: register ino_t *ip;
254:
255: canshort(fp->s_isize);
256: candaddr(fp->s_fsize);
257: canshort(fp->s_nfree);
258: for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
259: candaddr(*dp);
260: canshort(fp->s_ninode);
261: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
262: canino(*ip);
263: candaddr(fp->s_tfree);
264: canino(fp->s_tinode);
265: }
266:
267: tstf(fp)
268: register struct filsys *fp;
269: {
270: register daddr_t *dp;
271: register ino_t *ip;
272: register ino_t maxinode;
273:
274: maxinode = (fp->s_isize - INODEI) * INOPB + 1;
275: if (fp->s_isize >= fp->s_fsize)
276: return (0);
277: if (fp->s_tfree < fp->s_nfree
278: || fp->s_tfree >= fp->s_fsize - fp->s_isize + 1)
279: return (0);
280: if (fp->s_tinode < fp->s_ninode
281: || fp->s_tinode >= maxinode-1)
282: return (0);
283: for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
284: if (*dp < fp->s_isize || *dp >= fp->s_fsize)
285: return (0);
286: for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
287: if (*ip < 1 || *ip > maxinode)
288: return (0);
289: return (1);
290: }
291:
292: /*
293: * Copy special pathname (stripped of
294: * leading directories) into a fixed
295: * size buffer.
296: */
297: mcopy(ms, buf)
298: char *ms, *buf;
299: {
300: register char *p1, *p2;
301:
302: for (p1=p2=ms; *p1 != '\0'; )
303: if (*p1++ == '/')
304: p2 = p1;
305: p1 = buf;
306: while (*p1++ = *p2++)
307: ;
308: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.