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