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 = &in;
 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: }

Defined functions

alloc defined in line 358; used 2 times
clrblock defined in line 520; used 1 times
descend defined in line 82; used 2 times
entry defined in line 253; used 3 times
getnum defined in line 203; used 5 times
getstr defined in line 223; used 4 times
gmode defined in line 190; used 3 times
ialloc defined in line 410; used 1 times
iput defined in line 314; used 1 times
isblock defined in line 491; used 1 times
main defined in line 47; never used
newblk defined in line 293; used 2 times
rdfs defined in line 447; used 7 times
wtfs defined in line 469; used 8 times

Defined variables

copyright defined in line 8; never used
errs defined in line 42; used 6 times
fs defined in line 37; used 59 times
fscs defined in line 38; used 7 times
fsi defined in line 39; used 4 times
fso defined in line 39; used 5 times
ino defined in line 43; used 2 times
sccsid defined in line 14; never used
token defined in line 41; used 15 times

Defined macros

acg defined in line 36; used 20 times
sblock defined in line 31; used 37 times
Last modified: 1985-05-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1959
Valid CSS Valid XHTML 1.0 Strict