|
|
1.1 root 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: */
6:
7: #ifndef lint
8: char copyright[] =
9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10: All rights reserved.\n";
11: #endif not lint
12:
13: #ifndef lint
14: static char sccsid[] = "@(#)mkproto.c 5.1 (Berkeley) 5/28/85";
15: #endif not lint
16:
17: /*
18: * Make a file system prototype.
19: * usage: mkproto filsys proto
20: */
21: #include <stdio.h>
22: #include <sys/param.h>
23: #include <sys/inode.h>
24: #include <sys/fs.h>
25: #include <sys/dir.h>
26:
27: union {
28: struct fs fs;
29: char fsx[SBSIZE];
30: } ufs;
31: #define sblock ufs.fs
32: union {
33: struct cg cg;
34: char cgx[MAXBSIZE];
35: } ucg;
36: #define acg ucg.cg
37: struct fs *fs;
38: struct csum *fscs;
39: int fso, fsi;
40: FILE *proto;
41: char token[BUFSIZ];
42: int errs;
43: int ino = 10;
44: long getnum();
45: char *strcpy();
46:
47: main(argc, argv)
48: int argc;
49: char *argv[];
50: {
51: int i;
52:
53: if (argc != 3) {
54: fprintf(stderr, "usage: mkproto filsys proto\n");
55: exit(1);
56: }
57: fso = open(argv[1], 1);
58: fsi = open(argv[1], 0);
59: if (fso < 0 || fsi < 0) {
60: perror(argv[1]);
61: exit(1);
62: }
63: fs = &sblock;
64: rdfs(SBLOCK, SBSIZE, (char *)fs);
65: fscs = (struct csum *)calloc(1, fs->fs_cssize);
66: for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
67: rdfs(fsbtodb(fs, fs->fs_csaddr + numfrags(fs, i)),
68: (int)(fs->fs_cssize - i < fs->fs_bsize ?
69: fs->fs_cssize - i : fs->fs_bsize),
70: ((char *)fscs) + i);
71: proto = fopen(argv[2], "r");
72: descend((struct inode *)0);
73: wtfs(SBLOCK, SBSIZE, (char *)fs);
74: for (i = 0; i < fs->fs_cssize; i += fs->fs_bsize)
75: wtfs(fsbtodb(&sblock, fs->fs_csaddr + numfrags(&sblock, i)),
76: (int)(fs->fs_cssize - i < fs->fs_bsize ?
77: fs->fs_cssize - i : fs->fs_bsize),
78: ((char *)fscs) + i);
79: exit(errs);
80: }
81:
82: descend(par)
83: struct inode *par;
84: {
85: struct inode in;
86: int ibc = 0;
87: int i, f, c;
88: struct dinode *dip, inos[MAXBSIZE / sizeof (struct dinode)];
89: daddr_t ib[MAXBSIZE / sizeof (daddr_t)];
90: char buf[MAXBSIZE];
91:
92: getstr();
93: in.i_mode = gmode(token[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
94: in.i_mode |= gmode(token[1], "-u", 0, ISUID, 0, 0);
95: in.i_mode |= gmode(token[2], "-g", 0, ISGID, 0, 0);
96: for (i = 3; i < 6; i++) {
97: c = token[i];
98: if (c < '0' || c > '7') {
99: printf("%c/%s: bad octal mode digit\n", c, token);
100: errs++;
101: c = 0;
102: }
103: in.i_mode |= (c-'0')<<(15-3*i);
104: }
105: in.i_uid = getnum(); in.i_gid = getnum();
106: for (i = 0; i < fs->fs_bsize; i++)
107: buf[i] = 0;
108: for (i = 0; i < NINDIR(fs); i++)
109: ib[i] = (daddr_t)0;
110: in.i_nlink = 1;
111: in.i_size = 0;
112: for (i = 0; i < NDADDR; i++)
113: in.i_db[i] = (daddr_t)0;
114: for (i = 0; i < NIADDR; i++)
115: in.i_ib[i] = (daddr_t)0;
116: if (par != (struct inode *)0) {
117: ialloc(&in);
118: } else {
119: par = ∈
120: i = itod(fs, ROOTINO);
121: rdfs(fsbtodb(fs, i), fs->fs_bsize, (char *)inos);
122: dip = &inos[ROOTINO % INOPB(fs)];
123: in.i_number = ROOTINO;
124: in.i_nlink = dip->di_nlink;
125: in.i_size = dip->di_size;
126: in.i_db[0] = dip->di_db[0];
127: rdfs(fsbtodb(fs, in.i_db[0]), fs->fs_bsize, buf);
128: }
129:
130: switch (in.i_mode&IFMT) {
131:
132: case IFREG:
133: getstr();
134: f = open(token, 0);
135: if (f < 0) {
136: printf("%s: cannot open\n", token);
137: errs++;
138: break;
139: }
140: while ((i = read(f, buf, (int)fs->fs_bsize)) > 0) {
141: in.i_size += i;
142: newblk(buf, &ibc, ib, (int)blksize(fs, &in, ibc));
143: }
144: close(f);
145: break;
146:
147: case IFBLK:
148: case IFCHR:
149: /*
150: * special file
151: * content is maj/min types
152: */
153:
154: i = getnum() & 0377;
155: f = getnum() & 0377;
156: in.i_rdev = (i << 8) | f;
157: break;
158:
159: case IFDIR:
160: /*
161: * directory
162: * put in extra links
163: * call recursively until
164: * name of "$" found
165: */
166:
167: if (in.i_number != ROOTINO) {
168: par->i_nlink++;
169: in.i_nlink++;
170: entry(&in, in.i_number, ".", buf);
171: entry(&in, par->i_number, "..", buf);
172: }
173: for (;;) {
174: getstr();
175: if (token[0]=='$' && token[1]=='\0')
176: break;
177: entry(&in, (ino_t)(ino+1), token, buf);
178: descend(&in);
179: }
180: if (in.i_number != ROOTINO)
181: newblk(buf, &ibc, ib, (int)blksize(fs, &in, 0));
182: else
183: wtfs(fsbtodb(fs, in.i_db[0]), (int)fs->fs_bsize, buf);
184: break;
185: }
186: iput(&in, &ibc, ib);
187: }
188:
189: /*ARGSUSED*/
190: gmode(c, s, m0, m1, m2, m3)
191: char c, *s;
192: {
193: int i;
194:
195: for (i = 0; s[i]; i++)
196: if (c == s[i])
197: return((&m0)[i]);
198: printf("%c/%s: bad mode\n", c, token);
199: errs++;
200: return(0);
201: }
202:
203: long
204: getnum()
205: {
206: int i, c;
207: long n;
208:
209: getstr();
210: n = 0;
211: i = 0;
212: for (i = 0; c=token[i]; i++) {
213: if (c<'0' || c>'9') {
214: printf("%s: bad number\n", token);
215: errs++;
216: return((long)0);
217: }
218: n = n*10 + (c-'0');
219: }
220: return(n);
221: }
222:
223: getstr()
224: {
225: int i, c;
226:
227: loop:
228: switch (c = getc(proto)) {
229:
230: case ' ':
231: case '\t':
232: case '\n':
233: goto loop;
234:
235: case EOF:
236: printf("Unexpected EOF\n");
237: exit(1);
238:
239: case ':':
240: while (getc(proto) != '\n')
241: ;
242: goto loop;
243:
244: }
245: i = 0;
246: do {
247: token[i++] = c;
248: c = getc(proto);
249: } while (c != ' ' && c != '\t' && c != '\n' && c != '\0');
250: token[i] = 0;
251: }
252:
253: entry(ip, inum, str, buf)
254: struct inode *ip;
255: ino_t inum;
256: char *str;
257: char *buf;
258: {
259: register struct direct *dp, *odp;
260: int oldsize, newsize, spacefree;
261:
262: odp = dp = (struct direct *)buf;
263: while ((int)dp - (int)buf < ip->i_size) {
264: odp = dp;
265: dp = (struct direct *)((int)dp + dp->d_reclen);
266: }
267: if (odp != dp)
268: oldsize = DIRSIZ(odp);
269: else
270: oldsize = 0;
271: spacefree = odp->d_reclen - oldsize;
272: dp = (struct direct *)((int)odp + oldsize);
273: dp->d_ino = inum;
274: dp->d_namlen = strlen(str);
275: newsize = DIRSIZ(dp);
276: if (spacefree >= newsize) {
277: odp->d_reclen = oldsize;
278: dp->d_reclen = spacefree;
279: } else {
280: dp = (struct direct *)((int)odp + odp->d_reclen);
281: if ((int)dp - (int)buf >= fs->fs_bsize) {
282: printf("directory too large\n");
283: exit(1);
284: }
285: dp->d_ino = inum;
286: dp->d_namlen = strlen(str);
287: dp->d_reclen = DIRBLKSIZ;
288: }
289: strcpy(dp->d_name, str);
290: ip->i_size = (int)dp - (int)buf + newsize;
291: }
292:
293: newblk(buf, aibc, ib, size)
294: int *aibc;
295: char *buf;
296: daddr_t *ib;
297: int size;
298: {
299: int i;
300: daddr_t bno;
301:
302: bno = alloc(size);
303: wtfs(fsbtodb(fs, bno), (int)fs->fs_bsize, buf);
304: for (i = 0; i < fs->fs_bsize; i++)
305: buf[i] = 0;
306: ib[(*aibc)++] = bno;
307: if (*aibc >= NINDIR(fs)) {
308: printf("indirect block full\n");
309: errs++;
310: *aibc = 0;
311: }
312: }
313:
314: iput(ip, aibc, ib)
315: struct inode *ip;
316: int *aibc;
317: daddr_t *ib;
318: {
319: daddr_t d;
320: int i;
321: struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
322:
323: ip->i_atime = ip->i_mtime = ip->i_ctime = time((long *)0);
324: switch (ip->i_mode&IFMT) {
325:
326: case IFDIR:
327: case IFREG:
328: for (i = 0; i < *aibc; i++) {
329: if (i >= NDADDR)
330: break;
331: ip->i_db[i] = ib[i];
332: }
333: if (*aibc > NDADDR) {
334: ip->i_ib[0] = alloc((int)fs->fs_bsize);
335: for (i = 0; i < NINDIR(fs) - NDADDR; i++) {
336: ib[i] = ib[i+NDADDR];
337: ib[i+NDADDR] = (daddr_t)0;
338: }
339: wtfs(fsbtodb(fs, ip->i_ib[0]),
340: (int)fs->fs_bsize, (char *)ib);
341: }
342: break;
343:
344: case IFBLK:
345: case IFCHR:
346: break;
347:
348: default:
349: printf("bad mode %o\n", ip->i_mode);
350: exit(1);
351: }
352: d = fsbtodb(fs, itod(fs, ip->i_number));
353: rdfs(d, (int)fs->fs_bsize, (char *)buf);
354: buf[itoo(fs, ip->i_number)].di_ic = ip->i_ic;
355: wtfs(d, (int)fs->fs_bsize, (char *)buf);
356: }
357:
358: daddr_t
359: alloc(size)
360: int size;
361: {
362: int i, frag;
363: daddr_t d;
364: static int cg = 0;
365:
366: again:
367: rdfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
368: (char *)&acg);
369: if (acg.cg_magic != CG_MAGIC) {
370: printf("cg %d: bad magic number\n", cg);
371: return (0);
372: }
373: if (acg.cg_cs.cs_nbfree == 0) {
374: cg++;
375: if (cg >= fs->fs_ncg) {
376: printf("ran out of space\n");
377: return (0);
378: }
379: goto again;
380: }
381: for (d = 0; d < acg.cg_ndblk; d += sblock.fs_frag)
382: if (isblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag))
383: goto goth;
384: printf("internal error: can't find block in cyl %d\n", cg);
385: return (0);
386: goth:
387: clrblock(&sblock, (u_char *)acg.cg_free, d / sblock.fs_frag);
388: acg.cg_cs.cs_nbfree--;
389: sblock.fs_cstotal.cs_nbfree--;
390: fscs[cg].cs_nbfree--;
391: acg.cg_btot[cbtocylno(&sblock, d)]--;
392: acg.cg_b[cbtocylno(&sblock, d)][cbtorpos(&sblock, d)]--;
393: if (size != sblock.fs_bsize) {
394: frag = howmany(size, sblock.fs_fsize);
395: fscs[cg].cs_nffree += sblock.fs_frag - frag;
396: sblock.fs_cstotal.cs_nffree += sblock.fs_frag - frag;
397: acg.cg_cs.cs_nffree += sblock.fs_frag - frag;
398: acg.cg_frsum[sblock.fs_frag - frag]++;
399: for (i = frag; i < sblock.fs_frag; i++)
400: setbit(acg.cg_free, d + i);
401: }
402: wtfs(fsbtodb(&sblock, cgtod(&sblock, cg)), (int)sblock.fs_cgsize,
403: (char *)&acg);
404: return (acg.cg_cgx * fs->fs_fpg + d);
405: }
406:
407: /*
408: * Allocate an inode on the disk
409: */
410: ialloc(ip)
411: register struct inode *ip;
412: {
413: struct dinode buf[MAXBSIZE / sizeof (struct dinode)];
414: daddr_t d;
415: int c;
416:
417: ip->i_number = ++ino;
418: c = itog(&sblock, ip->i_number);
419: rdfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
420: (char *)&acg);
421: if (acg.cg_magic != CG_MAGIC) {
422: printf("cg %d: bad magic number\n", c);
423: exit(1);
424: }
425: if (ip->i_mode & IFDIR) {
426: acg.cg_cs.cs_ndir++;
427: sblock.fs_cstotal.cs_ndir++;
428: fscs[c].cs_ndir++;
429: }
430: acg.cg_cs.cs_nifree--;
431: setbit(acg.cg_iused, ip->i_number);
432: wtfs(fsbtodb(&sblock, cgtod(&sblock, c)), (int)sblock.fs_cgsize,
433: (char *)&acg);
434: sblock.fs_cstotal.cs_nifree--;
435: fscs[c].cs_nifree--;
436: if(ip->i_number >= sblock.fs_ipg * sblock.fs_ncg) {
437: printf("fsinit: inode value out of range (%d).\n",
438: ip->i_number);
439: exit(1);
440: }
441: return (ip->i_number);
442: }
443:
444: /*
445: * read a block from the file system
446: */
447: rdfs(bno, size, bf)
448: int bno, size;
449: char *bf;
450: {
451: int n;
452:
453: if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) {
454: printf("seek error: %ld\n", bno);
455: perror("rdfs");
456: exit(1);
457: }
458: n = read(fsi, bf, size);
459: if(n != size) {
460: printf("read error: %ld\n", bno);
461: perror("rdfs");
462: exit(1);
463: }
464: }
465:
466: /*
467: * write a block to the file system
468: */
469: wtfs(bno, size, bf)
470: int bno, size;
471: char *bf;
472: {
473: int n;
474:
475: lseek(fso, bno * DEV_BSIZE, 0);
476: if (lseek(fso, bno * DEV_BSIZE, 0) < 0) {
477: printf("seek error: %ld\n", bno);
478: perror("wtfs");
479: exit(1);
480: }
481: n = write(fso, bf, size);
482: if(n != size) {
483: printf("write error: %D\n", bno);
484: perror("wtfs");
485: exit(1);
486: }
487: }
488: /*
489: * check if a block is available
490: */
491: isblock(fs, cp, h)
492: struct fs *fs;
493: unsigned char *cp;
494: int h;
495: {
496: unsigned char mask;
497:
498: switch (fs->fs_frag) {
499: case 8:
500: return (cp[h] == 0xff);
501: case 4:
502: mask = 0x0f << ((h & 0x1) << 2);
503: return ((cp[h >> 1] & mask) == mask);
504: case 2:
505: mask = 0x03 << ((h & 0x3) << 1);
506: return ((cp[h >> 2] & mask) == mask);
507: case 1:
508: mask = 0x01 << (h & 0x7);
509: return ((cp[h >> 3] & mask) == mask);
510: default:
511: fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
512: return (0);
513: }
514: /*NOTREACHED*/
515: }
516:
517: /*
518: * take a block out of the map
519: */
520: clrblock(fs, cp, h)
521: struct fs *fs;
522: unsigned char *cp;
523: int h;
524: {
525: switch ((fs)->fs_frag) {
526: case 8:
527: cp[h] = 0;
528: return;
529: case 4:
530: cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
531: return;
532: case 2:
533: cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
534: return;
535: case 1:
536: cp[h >> 3] &= ~(0x01 << (h & 0x7));
537: return;
538: default:
539: fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
540: return;
541: }
542: }
543:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.