# 2.11BSD#431 - /usr/src/usr.sbin/mkproto/mkproto.c

##### Functions

    alloc             X
    descend           X
    entry             X
    getnum            X
    getstr            X
    gmode             X
    ialloc            X
    iput              X
    main              X
    newblk            X
    rdfs              X
    wtfs              X

##### Variables

    copyright         X
    errs              X
    flshroot          X
    fs                X
    fsi               X
    fso               X
    ino               X
    token             X

##### Macros

    sblock            X

       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

- in line 42, 302, 334

descend defined in line 69; used 2 times

- in line 64, 164

entry defined in line 241; used 3 times

- in line 156-157(2), 163

getnum defined in line 191; used 5 times

- in line 40, 92(2), 140-141(2)

getstr defined in line 211; used 4 times

- in line 79, 119, 160, 197

gmode defined in line 178; used 3 times

- in line 80-82(3)

ialloc defined in line 391; used 1 times

- in line 100

iput defined in line 314; used 1 times

- in line 174

main defined in line 45; never used
newblk defined in line 294; used 3 times

- in line 128, 170, 280

rdfs defined in line 403; used 5 times

- in line 62, 104, 112, 353, 376

wtfs defined in line 425; used 6 times

- in line 65, 168, 276, 303, 339, 357

#### Defined variables

copyright defined in line 8; never used
errs defined in line 37; used 6 times

- in line 66, 87, 123, 187, 203, 308

flshroot defined in line 39; used 4 times

- in line 113, 167, 274-275(2)

fs defined in line 33; used 5 times

- in line 29-32(2), 61-65(3)

fsi defined in line 34; used 4 times

- in line 56-57(2), 409-414(2)

fso defined in line 34; used 4 times

- in line 55-57(2), 431-436(2)

ino defined in line 38; used 2 times

- in line 163, 396

sccsid defined in line 11; never used
token defined in line 36; used 15 times

- in line 80-86(5), 120-122(2), 161-163(3), 186, 200-202(2), 235-238(2)

#### Defined macros

sblock defined in line 32; used 8 times

- in line 61, 370-379(7)

Last modified: 1993-01-20 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2221 |