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: static char sccsid[] = "@(#)mkproto.c	5.1 (Berkeley) 5/28/85";
  12: #endif not lint
  13: 
  14: /*
  15:  * Make a file system prototype.
  16:  * usage: mkproto filsys proto
  17:  *
  18:  * Files written to the new filesystem may be up to 4kb less than the
  19:  * max single indirect size:  256kb.
  20:  */
  21: #include <stdio.h>
  22: #include <sys/param.h>
  23: #undef  EXTERNALITIMES      /* Need full inode definiton */
  24: #include <sys/inode.h>
  25: #include <sys/fs.h>
  26: #include <sys/dir.h>
  27: 
  28: union {
  29:     struct  fs fs;
  30:     char    fsx[DEV_BSIZE];
  31: } ufs;
  32: #define sblock  ufs.fs
  33: struct  fs *fs;
  34: int fso, fsi;
  35: FILE    *proto;
  36: char    token[BUFSIZ];
  37: int errs;
  38: ino_t   ino = 10;
  39: int flshroot;
  40: long    getnum();
  41: char    *strcpy();
  42: daddr_t alloc();
  43: time_t  time();
  44: 
  45: main(argc, argv)
  46:     int argc;
  47:     char *argv[];
  48: {
  49:     int i;
  50: 
  51:     if (argc != 3) {
  52:         fprintf(stderr, "usage: mkproto filsys proto\n");
  53:         exit(1);
  54:     }
  55:     fso = open(argv[1], 1);
  56:     fsi = open(argv[1], 0);
  57:     if (fso < 0 || fsi < 0) {
  58:         perror(argv[1]);
  59:         exit(1);
  60:     }
  61:     fs = &sblock;
  62:     rdfs(SBLOCK, (char *)fs);
  63:     proto = fopen(argv[2], "r");
  64:     descend((struct inode *)0);
  65:     wtfs(SBLOCK, (char *)fs);
  66:     exit(errs);
  67: }
  68: 
  69: descend(par)
  70:     struct inode *par;
  71: {
  72:     struct inode in;
  73:     int ibc = 0, dbc = 0;
  74:     int i, f, c;
  75:     struct dinode *dip, inos[MAXBSIZE / sizeof (struct dinode)];
  76:     daddr_t ib[MAXBSIZE / sizeof (daddr_t)];
  77:     char buf[MAXBSIZE];
  78: 
  79:     getstr();
  80:     in.i_mode = gmode(token[0], "-bcd", IFREG, IFBLK, IFCHR, IFDIR);
  81:     in.i_mode |= gmode(token[1], "-u", 0, ISUID, 0, 0);
  82:     in.i_mode |= gmode(token[2], "-g", 0, ISGID, 0, 0);
  83:     for (i = 3; i < 6; i++) {
  84:         c = token[i];
  85:         if (c < '0' || c > '7') {
  86:             printf("%c/%s: bad octal mode digit\n", c, token);
  87:             errs++;
  88:             c = 0;
  89:         }
  90:         in.i_mode |= (c-'0')<<(15-3*i);
  91:     }
  92:     in.i_uid = getnum(); in.i_gid = getnum();
  93:     in.i_nlink = 1;
  94:     in.i_size = 0;
  95:     bzero(in.i_addr, NADDR * sizeof (daddr_t));
  96:     bzero(buf, sizeof (buf));
  97:     bzero(ib, sizeof (ib));
  98: 
  99:     if (par != (struct inode *)0) {
 100:         ialloc(&in);
 101:     } else {
 102:         par = &in;
 103:         i = itod(ROOTINO);
 104:         rdfs((daddr_t) i, (char *)inos);
 105:         dip = &inos[itoo(ROOTINO)];
 106:         in.i_number = ROOTINO;
 107:         in.i_nlink = dip->di_nlink;
 108:         in.i_size = dip->di_size;
 109:         in.i_db[0] = dip->di_addr[0];
 110:         ib[0] = in.i_db[0]; /* rootino has 1st block assigned */
 111:         ibc = 1;        /* preserve it when iput is done */
 112:         rdfs(in.i_db[0], buf);
 113:         flshroot = 1;
 114:     }
 115: 
 116:     switch (in.i_mode&IFMT) {
 117: 
 118:     case IFREG:
 119:         getstr();
 120:         f = open(token, 0);
 121:         if (f < 0) {
 122:             printf("%s: cannot open\n", token);
 123:             errs++;
 124:             break;
 125:         }
 126:         while ((i = read(f, buf, DEV_BSIZE)) > 0) {
 127:             in.i_size += i;
 128:             newblk(buf, &ibc, ib, &dbc);
 129:         }
 130:         close(f);
 131:         break;
 132: 
 133:     case IFBLK:
 134:     case IFCHR:
 135:         /*
 136: 		 * special file
 137: 		 * content is maj/min types
 138: 		 */
 139: 
 140:         i = getnum() & 0377;
 141:         f = getnum() & 0377;
 142:         in.i_rdev = (i << 8) | f;
 143:         break;
 144: 
 145:     case IFDIR:
 146:         /*
 147: 		 * directory
 148: 		 * put in extra links
 149: 		 * call recursively until
 150: 		 * name of "$" found
 151: 		 */
 152: 
 153:         if (in.i_number != ROOTINO) {
 154:             par->i_nlink++;
 155:             in.i_nlink++;
 156:             entry(&in, in.i_number, ".", buf, &ibc, ib, &dbc);
 157:             entry(&in, par->i_number, "..", buf, &ibc, ib, &dbc);
 158:         }
 159:         for (;;) {
 160:             getstr();
 161:             if (token[0]=='$' && token[1]=='\0')
 162:                 break;
 163:             entry(&in, ino+1, token, buf, &ibc, ib, &dbc);
 164:             descend(&in);
 165:         }
 166:         if (dbc) {
 167:             if (in.i_number == ROOTINO && flshroot)
 168:                 wtfs(in.i_db[0], buf);
 169:             else
 170:                 newblk(buf, &ibc, ib, &dbc);
 171:         }
 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, aibc, ib, adbc)
 242:     struct inode *ip;
 243:     ino_t inum;
 244:     char *str;
 245:     char *buf;
 246:     int *aibc;
 247:     daddr_t *ib;
 248:     int *adbc;
 249: {
 250:     register struct direct *dp, *odp;
 251:     int oldsize, newsize, spacefree;
 252:     u_short diroff = ip->i_size & DEV_BMASK;
 253: 
 254:     odp = dp = (struct direct *)buf;
 255:     while ((int)dp - (int)buf < diroff) {
 256:         odp = dp;
 257:         dp = (struct direct *)((int)dp + dp->d_reclen);
 258:     }
 259:     if (odp != dp)
 260:         oldsize = DIRSIZ(odp);
 261:     else
 262:         oldsize = 0;
 263:     spacefree = odp->d_reclen - oldsize;
 264:     dp = (struct direct *)((int)odp + oldsize);
 265:     dp->d_ino = inum;
 266:     dp->d_namlen = strlen(str);
 267:     newsize = DIRSIZ(dp);
 268:     if (spacefree >= newsize) {
 269:         odp->d_reclen = oldsize;
 270:         dp->d_reclen = spacefree;
 271:     } else {
 272:         dp = (struct direct *)((int)odp + odp->d_reclen);
 273:         if ((int)dp - (int)buf >= DEV_BSIZE) {
 274:             if (ip->i_number == ROOTINO && flshroot) {
 275:                 flshroot = 0;
 276:                 wtfs(ip->i_addr[0], buf);
 277:                 bzero(buf, DEV_BSIZE);
 278:             }
 279:             else
 280:                 newblk(buf, aibc, ib, adbc);
 281:             dp = (struct direct *)(&buf[DIRBLKSIZ]);
 282:             dp->d_reclen = DIRBLKSIZ;
 283:             dp = (struct direct *)buf;
 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:     (*adbc)++;
 292: }
 293: 
 294: newblk(buf, aibc, ib, adbc)
 295:     int *aibc;
 296:     char *buf;
 297:     daddr_t *ib;
 298:     int *adbc;
 299: {
 300:     daddr_t bno;
 301: 
 302:     bno = alloc();
 303:     wtfs(bno, buf);
 304:     bzero(buf, DEV_BSIZE);
 305:     ib[(*aibc)++] = bno;
 306:     if (*aibc >= NINDIR) {
 307:         printf("indirect block full\n");
 308:         errs++;
 309:         *aibc = 0;
 310:     *adbc = 0;
 311:     }
 312: }
 313: 
 314: iput(ip, aibc, ib)
 315:     register struct inode *ip;
 316:     int *aibc;
 317:     daddr_t *ib;
 318: {
 319:     daddr_t d;
 320:     register int i, off;
 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();
 335:             for (i = 0; i < NINDIR - NDADDR; i++) {
 336:                 ib[i] = ib[i+NDADDR];
 337:                 ib[i+NDADDR] = (daddr_t)0;
 338:             }
 339:             wtfs(ip->i_ib[0], (char *)ib);
 340:         }
 341:         break;
 342: 
 343:     case IFBLK:
 344:     case IFCHR:
 345:         break;
 346: 
 347:     default:
 348:         printf("bad mode %o\n", ip->i_mode);
 349:         exit(1);
 350:     }
 351:     d = itod(ip->i_number);
 352:     off = itoo(ip->i_number);
 353:     rdfs(d, (char *)buf);
 354:     buf[off].di_ic2 = ip->i_ic2;
 355:     bcopy(ip->i_addr,buf[off].di_addr,NADDR*sizeof(daddr_t));
 356:     buf[off].di_ic1 = ip->i_ic1;
 357:     wtfs(d, (char *)buf);
 358: }
 359: 
 360: daddr_t
 361: alloc()
 362: {
 363:     daddr_t bno;
 364:     register i;
 365:     union {
 366:         char    data[DEV_BSIZE];
 367:         struct  fblk frees;
 368:     } fbuf;
 369: 
 370:     if (!sblock.fs_nfree || (bno=sblock.fs_free[--sblock.fs_nfree]) == 0) {
 371:         fprintf(stderr, "Out of space.\n");
 372:         exit(1);
 373:         }
 374:     sblock.fs_tfree--;
 375:     if(sblock.fs_nfree == 0) {
 376:         rdfs(bno, fbuf.data);
 377:         sblock.fs_nfree = fbuf.frees.df_nfree;
 378:         for(i=0;i<NICFREE;i++)
 379:             sblock.fs_free[i] = fbuf.frees.df_free[i];
 380:     }
 381:     return(bno);
 382: }
 383: 
 384: /*
 385:  * Allocate an inode on the disk
 386:  *
 387:  * This assumes a newly created filesystem in which fs_inode
 388:  * is zero filled and fs_ninode is zero.
 389:  */
 390: 
 391: ino_t
 392: ialloc(ip)
 393:     register struct inode *ip;
 394: {
 395: 
 396:     ip->i_number = ++ino;
 397:     return(ip->i_number);
 398: }
 399: 
 400: /*
 401:  * read a block from the file system
 402:  */
 403: rdfs(bno, bf)
 404:     daddr_t bno;
 405:     register char *bf;
 406: {
 407:     register int n;
 408: 
 409:     if (lseek(fsi, bno * DEV_BSIZE, 0) < 0) {
 410:         printf("seek error: %ld\n", bno);
 411:         perror("rdfs");
 412:         exit(1);
 413:     }
 414:     n = read(fsi, bf, DEV_BSIZE);
 415:     if(n != DEV_BSIZE) {
 416:         printf("read error: %ld\n", bno);
 417:         perror("rdfs");
 418:         exit(1);
 419:     }
 420: }
 421: 
 422: /*
 423:  * write a block to the file system
 424:  */
 425: wtfs(bno, bf)
 426:     daddr_t bno;
 427:     register char *bf;
 428: {
 429:     register int n;
 430: 
 431:     if (lseek(fso, bno * DEV_BSIZE, 0) < 0) {
 432:         printf("seek error: %ld\n", bno);
 433:         perror("wtfs");
 434:         exit(1);
 435:     }
 436:     n = write(fso, bf, DEV_BSIZE);
 437:     if(n != DEV_BSIZE) {
 438:         printf("write error: %D\n", bno);
 439:         perror("wtfs");
 440:         exit(1);
 441:     }
 442: }

Defined functions

alloc defined in line 360; used 3 times
descend defined in line 69; used 2 times
entry defined in line 241; used 3 times
getnum defined in line 191; used 5 times
getstr defined in line 211; used 4 times
gmode defined in line 178; used 3 times
ialloc defined in line 391; used 1 times
iput defined in line 314; used 1 times
main defined in line 45; never used
newblk defined in line 294; used 3 times
rdfs defined in line 403; used 5 times
wtfs defined in line 425; used 6 times

Defined variables

copyright defined in line 8; never used
errs defined in line 37; used 6 times
flshroot defined in line 39; used 4 times
fs defined in line 33; used 5 times
fsi defined in line 34; used 4 times
fso defined in line 34; used 4 times
ino defined in line 38; used 2 times
sccsid defined in line 11; never used
token defined in line 36; used 15 times

Defined macros

sblock defined in line 32; used 8 times
Last modified: 1993-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 758
Valid CSS Valid XHTML 1.0 Strict