diff --git a/tools/mkfs.c b/tools/mkfs.c index 973335e..a463044 100644 --- a/tools/mkfs.c +++ b/tools/mkfs.c @@ -1,18 +1,14 @@ /* * Program to create a 1st Edition UNIX filesystem. * (c) 2008 Warren Toomey, GPL3. - * + * * Other contributors, add your name above. - * - * TODO: add large file functionality - * ensure that swap is not used on RF disk images. - * deal with errors instead of exiting :-) - * - * in the long run, have the ability to read from/write to - * existing images, a la an ftp client. - * - * $Revision: 1.22 $ - * $Date: 2008/05/17 02:30:05 $ + * + * TODO: deal with errors instead of exiting :-) + * in the long run, have the ability to read from/write to existing + * images, a la an ftp client. + * + * $Revision: 1.24 $ $Date: 2008/05/17 07:36:00 $ */ #include @@ -26,7 +22,6 @@ #define BLKSIZE 512 /* 512 bytes per block */ #define RF_SIZE 1024 /* Number of blocks on RF11 */ -#define RF_NOSAWPSIZE 944 /* RF11 blocks excluding swap */ #define RF_INODES 512 /* Cold UNIX sets 512 i-nodes on RF */ #define RK_SIZE 4864 /* Number of blocks on RK03, should be 4872 */ #define INODE_RATIO 4 /* Disksize to i-node ratio */ @@ -34,11 +29,13 @@ #define NUMDIRECTBLKS 8 /* Only 8 direct blocks in an i-node */ #define BLKSPERINDIRECT 256 /* 256 block pointers in an indirect block */ -/* V1 UNIX reserves 64 blocks on the end of RF11 for kernel images, then +/* + * V1 UNIX reserves 64 blocks on the end of RF11 for kernel images, then * SWPSIZ blocks per process for swap areas. */ #define KERNBLKS 64 /* Hard coded in V1 kernel source */ -#define SWPSIZ 33 /* Was hard-coded to 17, now 33 for C compiler */ +#define SWPSIZ 33 /* Was hard-coded to 17, now 33 for C + compiler */ #define NPROC 16 /* Hard coded in V1 kernel source */ #define RF_NOSWAPSIZE (RF_SIZE - KERNBLKS - (SWPSIZ*NPROC)) @@ -93,12 +90,12 @@ struct fileperm { /* We read an external file to determine */ uint16_t flags; /* apply to the files which we add to the */ uint8_t uid; /* filesystem. */ uint32_t mtime; -} permlist[PERMLISTSIZE]; +} permlist[PERMLISTSIZE]; unsigned char buf[BLKSIZE]; /* A block buffer */ uint16_t disksize; /* Number of blocks on disk */ -uint16_t icount=0; /* Number of i-nodes created */ +uint16_t icount = 0; /* Number of i-nodes created */ uint16_t nextfreeblock; /* The next free block available */ uint8_t *freemap; /* In-memory free-map */ uint8_t *inodemap; /* In-memory inode bitmap */ @@ -107,14 +104,15 @@ struct v1inode *inodelist; /* In-memory i-node list */ struct directory *rootdir; /* The root directory */ FILE *diskfh; /* Disk filehandle */ -int debug=0; /* Enable debugging output */ +int debug = 0; /* Enable debugging output */ +int makedevflag = 0; /* Do we make the /dev directory? */ /* Write the superblock out to the image */ void write_superblock(void) { - uint16_t freemapsize= disksize / 8; - uint16_t inodemapmapsize= icount / 8; + uint16_t freemapsize = disksize / 8; + uint16_t inodemapmapsize = icount / 8; if (debug) printf("Writing freemap and inodemap from block 0\n"); fseek(diskfh, 0, SEEK_SET); @@ -123,21 +121,20 @@ void write_superblock(void) fwrite(&inodemapmapsize, sizeof(inodemapmapsize), 1, diskfh); fwrite(inodemap, sizeof(uint8_t), ((icount - ROOTDIR_INUM) / 8), diskfh); if (debug) { - long posn= ftell(diskfh); - long block= posn/BLKSIZE; - long off= posn/BLKSIZE; + long posn = ftell(diskfh); + long block = posn / BLKSIZE; + long off = posn / BLKSIZE; printf("ending up at posn %ld, block %ld, offset %ld\n", posn, block, off); printf("Writing inodelist from block 2\n"); } fseek(diskfh, 2 * BLKSIZE, SEEK_SET); - if (debug) - printf("Writing %d inodes, each size %d, total %d\n", - icount, sizeof(struct v1inode), icount * sizeof(struct v1inode)); - fwrite(&inodelist[1], sizeof(struct v1inode), icount-1, diskfh); + if (debug) printf("Writing %d inodes, each size %d, total %d\n", + icount, sizeof(struct v1inode), icount * sizeof(struct v1inode)); + fwrite(&inodelist[1], sizeof(struct v1inode), icount - 1, diskfh); if (debug) { - long posn= ftell(diskfh); - long block= posn/BLKSIZE; - long off= posn/BLKSIZE; + long posn = ftell(diskfh); + long block = posn / BLKSIZE; + long off = posn / BLKSIZE; printf("ending up at posn %ld, block %ld, offset %ld\n", posn, block, off); } } @@ -151,6 +148,7 @@ void block_inuse(int n) if (n >= disksize) { printf("Cannot mark block %d >= disk size %d\n", n, disksize); exit(1); } + offset = n / 8; bitmask = bitmap[n % 8]; freemap[offset] &= bitmask; @@ -165,6 +163,7 @@ void inode_inuse(int n) if (n >= icount) { printf("Cannot mark inode %d >= icount %d\n", n, icount); exit(1); } + inodelist[n].flags |= I_ALLOCATED; offset = (n - ROOTDIR_INUM) / 8; bitmask = bitmap[(n - ROOTDIR_INUM) % 8]; @@ -175,18 +174,20 @@ void inode_inuse(int n) int alloc_inode(void) { int i; + for (i = 42; i < icount; i++) { if (inodelist[i].flags == 0) { - inode_inuse(i); - return (i); + inode_inuse(i); return (i); } } - printf("Cannot allocate a new i-node\n"); exit(1); + + printf("Cannot allocate a new i-node\n"); + exit(1); } /* - * Allocate N contiguous blocks. Returns the first block number, - * or dies if this is impossible. + * Allocate N contiguous blocks. Returns the first block number, or dies if + * this is impossible. */ uint16_t alloc_blocks(int n) { @@ -195,73 +196,81 @@ uint16_t alloc_blocks(int n) if (nextfreeblock + n >= disksize) { printf("Unable to allocate %d more blocks\n", n); exit(1); } - for (i = nextfreeblock; i < n + nextfreeblock; i++) - block_inuse(i); + + for (i = nextfreeblock; i < n + nextfreeblock; i++) block_inuse(i); nextfreeblock += n; return (firstblock); } -/* Allocate N contiguous blocks, and write a single indirect block - * with those block numbers in it. Return the indirect block number; - * the contiguous blocks come directly after the indirect block. +/* + * Allocate N contiguous blocks, and write a single indirect block with those + * block numbers in it. Return the indirect block number; the contiguous + * blocks come directly after the indirect block. */ int alloc_indirect_blocks(int n) { uint16_t blkptr[BLKSPERINDIRECT]; /* Blk pointers in the indirect blk */ - uint16_t indirect_blknum; /* Number of the indirect block */ - uint16_t i,b; + uint16_t indirect_blknum; /* Number of the indirect block */ + uint16_t i, b; - if ( n > BLKSPERINDIRECT) { + if (n > BLKSPERINDIRECT) { printf("Unable to allocate more than %d blocks in indirect\n", n); exit(1); } /* Obtain N+1 blocks, the first will be the indirect block */ - indirect_blknum= alloc_blocks(n+1); + indirect_blknum = alloc_blocks(n + 1); if (debug) - printf("Allocated %d blocks, indirect is block %d\n", n+1, indirect_blknum); + printf("Allocated %d blocks, indirect is block %d\n", + n + 1, indirect_blknum); /* Fill the indirect block with the block numbers */ memset(blkptr, 0, BLKSIZE); - for (i=0,b=indirect_blknum+1; i< n; i++, b++) - blkptr[i]= b; + for (i = 0, b = indirect_blknum + 1; i < n; i++, b++) blkptr[i] = b; /* Write the indirect bock out to the image */ fseek(diskfh, indirect_blknum * BLKSIZE, SEEK_SET); fwrite(blkptr, BLKSIZE, 1, diskfh); - if (debug) - printf("Wrote indirect block at %d\n", indirect_blknum); + if (debug) printf("Wrote indirect block at %d\n", indirect_blknum); /* Return the indirect block number */ - return(indirect_blknum); + return (indirect_blknum); } /* Add a filename and i-number to the given directory */ void add_direntry(struct directory *d, uint16_t inum, char *name) { if (d == NULL) { - printf("I need a struct directory * please\n"); exit(1); + printf("I need a struct directory * please\n"); + exit(1); } + #if 0 /* Removed for /dev/creation */ if (inum < ROOTDIR_INUM) { - printf("Illegal inum %d in add_direntry\n", inum); exit(1); + printf("Illegal inum %d in add_direntry\n", inum); + exit(1); } #endif + if (name && strlen(name) > 8) { - printf("Name %s too long\n", name); exit(1); + printf("Name %s too long\n", name); + exit(1); } /* Find an entry in the directory which is empty */ if (d->nextfree >= d->numentries) { - printf("Unable to add directory entry\n"); exit(1); + printf("Unable to add directory entry\n"); + exit(1); } + d->entry[d->nextfree].inode = inum; strncpy(d->entry[d->nextfree].name, name, 8); d->nextfree++; } -/* Search for an return a struct fileperm pointer, given a directory - * and filename. If no match is found, NULL is returned. +/* + * Search for an return a struct fileperm pointer, given a directory and + * filename. If no match is found, NULL is returned. */ struct fileperm *search_fileperm(char *dir, char *file) { @@ -271,24 +280,26 @@ struct fileperm *search_fileperm(char *dir, char *file) snprintf(name, BLKSIZE, "%s/%s", dir, file); if (debug) printf("Searching permlist for %s\n", name); - for (i=0; permlist[i].name; i++) { + for (i = 0; permlist[i].name; i++) { if (!strcmp(permlist[i].name, name)) { if (debug) printf("Found permlist entry for %s\n", name); - return(&permlist[i]); + return (&permlist[i]); } } - return(NULL); + + return (NULL); } /* * Create a directory with the given name. Allocate an i-node for it, and a - * set of blocks. Attach it to /. Return the struct allocated. If name is - * "/", we are making the root directory itself. + * set of blocks. Attach it to the parent directory. Return the struct + * allocated. If name is "/", we are making the root directory itself. */ -struct directory *create_dir(char *name, int numblocks) +struct directory *create_dir(char *name, int numblocks, + struct directory *parent) { struct directory *d; - uint16_t inum, blk; + uint16_t inum, parent_inum, blk; int i; if (numblocks > 8) { @@ -299,38 +310,46 @@ struct directory *create_dir(char *name, int numblocks) printf("Name %s too long\n", name); exit(1); } - d = (struct directory *)calloc(1, sizeof(struct directory)); - d->numentries= numblocks * DIRENTPERBLOCK; - d->nextfree= 0; - d->entry= (struct v1dirent *)calloc(d->numentries, sizeof(struct v1dirent)); + /* Cold UNIX only uses 1 block for root directory */ + if (!strcmp(name, "/")) numblocks = 1; + + d = (struct directory *)calloc(1, sizeof(struct directory)); + d->numentries = numblocks * DIRENTPERBLOCK; + d->nextfree = 0; + d->entry = (struct v1dirent *)calloc(d->numentries, sizeof(struct v1dirent)); + + /* If the root directory, use the special i-number for it */ + /* Otherwise, allocate an i-node and some blocks for the directory */ + if (!strcmp(name, "/")) { + inum = ROOTDIR_INUM; + rootdir = parent = d; /* So later, root's .. points to itself */ + } else + inum = alloc_inode(); - /* Allocate an i-node and some blocks for the directory */ - if (strcmp(name, "/")) inum = alloc_inode(); - else inum = ROOTDIR_INUM; d->block = alloc_blocks(numblocks); - d->inum= inum; + d->inum = inum; if (debug) printf("In create_dir, got back inum %d blk %d, %d config blks\n", - inum, d->block, numblocks); + inum, d->block, numblocks); /* Mark the i-node as a directory */ inodelist[inum].flags |= I_DIR | I_UREAD | I_UWRITE | I_OREAD; - inodelist[inum].nlinks= 2; /* Size is determined at write-time */ - for (i=0, blk=d->block; i < numblocks; i++, blk++) - inodelist[inum].block[i]= blk; + inodelist[inum].nlinks = 2; /* Size is determined at write-time */ + for (i = 0, blk = d->block; i < numblocks; i++, blk++) + inodelist[inum].block[i] = blk; - /* If the directory is not /, attach it to rootdir */ + /* Attach this directory to its parent, but not if root */ + parent_inum = parent->inum; if (strcmp(name, "/")) { - add_direntry(rootdir, inum, name); - /* Update rootdir's nlinks in its inode */ - inodelist[ROOTDIR_INUM].nlinks++; + add_direntry(parent, inum, name); + /* Update the parent's nlinks */ + inodelist[parent_inum].nlinks++; } - /* and add entries for . and .. */ - add_direntry(d, ROOTDIR_INUM, ".."); + /* Add entries for . and .. */ + add_direntry(d, parent_inum, ".."); add_direntry(d, inum, "."); - if (debug) - printf("Created dir for %s, inum %d\n", name, inum); + if (debug) printf("Created dir for %s, inum %d\n", name, inum); return (d); } @@ -343,16 +362,65 @@ void write_dir(struct directory *d, char *name) if (debug) printf("Writing dir %s, size %d, %d blks from block %d (offset 0x%x) on\n", - name, d->numentries * sizeof(struct v1dirent), - d->numentries / DIRENTPERBLOCK, d->block, - d->block * BLKSIZE); + name, d->numentries * sizeof(struct v1dirent), + d->numentries / DIRENTPERBLOCK, d->block, + d->block * BLKSIZE); /* Directory size is the # of bytes of the in-use directory entries */ - inodelist[d->inum].size= d->nextfree * sizeof(struct v1dirent); + inodelist[d->inum].size = d->nextfree * sizeof(struct v1dirent); fseek(diskfh, d->block * BLKSIZE, SEEK_SET); fwrite(d->entry, d->numentries * sizeof(struct v1dirent), 1, diskfh); } +/* + * Following the cold UNIX rf output, make /dev. In /dev, make devices with + * specific i-nums, which I guess act like early major/minor device numbers. + */ +void add_devdir(void) +{ + struct dev { + char *name; + uint16_t inum; + } devlist[] = { + { "tty", 1 }, + { "ppt", 2 }, + { "mem", 3 }, + { "rf0", 4 }, + { "rk0", 5 }, + { "tap0", 6 }, + { "tap1", 7 }, + { "tap2", 8 }, + { "tap3", 9 }, + { "tap4", 10 }, + { "tap5", 11 }, + { "tap6", 12 }, + { "tap7", 13 }, + { "tty0", 14 }, + { "tty1", 15 }, + { "tty2", 16 }, + { "tty3", 17 }, + { "tty4", 18 }, + { "tty5", 19 }, + { "tty6", 20 }, + { "tty7", 21 }, + { "lpr", 22 }, + { "tty8", 1 }, + { NULL, 0 }, + }; + + struct directory *d; + int i; + + d = create_dir("dev", 1, rootdir); /* Cold UNIX only uses 1 block */ + + for (i = 0; devlist[i].name != NULL; i++) { + add_direntry(d, devlist[i].inum, devlist[i].name); + } + + /* And write the directory out */ + write_dir(d, "dev"); +} + /* Create a file in a given directory. Returns the first block number. */ /* Does not actually copy the file's bits onto the image. */ /* At present we cannot deal with very large files, i.e. > 1 indirect block */ @@ -360,15 +428,17 @@ int create_file(struct directory *d, char *name, int size, struct fileperm *p) { uint16_t inum; uint16_t firstblock; - uint32_t epoch=0; + uint32_t epoch = 0; int i, blk, numblocks; if (d == NULL) { printf("I need a struct directory * please\n"); exit(1); } + if (name == NULL) { printf("I need a filename please\n"); exit(1); } + if (size > BLKSPERINDIRECT * BLKSIZE) { printf("File %s is a very large file, skipping", name); return (0); } @@ -406,19 +476,18 @@ int create_file(struct directory *d, char *name, int size, struct fileperm *p) memcpy(inodelist[inum].mtime, &epoch, sizeof(uint32_t)); memcpy(inodelist[inum].ctime, &epoch, sizeof(uint32_t)); inodelist[inum].flags |= I_MODFILE | I_EXEC | I_UREAD | I_UWRITE | - I_OREAD | I_OWRITE; + I_OREAD | I_OWRITE; } /* Add the i-node and filename to the directory */ add_direntry(d, inum, name); - if (debug) - printf("Created file %s size %d inum %d\n", name, size, inum); + if (debug) printf("Created file %s size %d inum %d\n", name, size, inum); return (firstblock); } /* - * Open up the file given by the fullname, and copy - * size bytes into the image starting at firstblock. + * Open up the file given by the fullname, and copy size bytes into the image + * starting at firstblock. */ void copy_file(char *fullname, int firstblock, int size) { @@ -427,7 +496,7 @@ void copy_file(char *fullname, int firstblock, int size) if (debug) printf("Copying %s size %d to block %d (offset 0x%x) on\n", - fullname, size, firstblock, firstblock * BLKSIZE); + fullname, size, firstblock, firstblock * BLKSIZE); if ((zin = fopen(fullname, "r")) == NULL) { printf("Unable to read %s to copy onto image\n", fullname); exit(1); } @@ -436,14 +505,15 @@ void copy_file(char *fullname, int firstblock, int size) while ((cnt = fread(buf, 1, BLKSIZE, zin)) > 0) fwrite(buf, 1, cnt, diskfh); - fclose(zin); fflush(diskfh); + fclose(zin); + fflush(diskfh); } /* - * Make a directory /dir on the image. Add all the - * files in basedir/dir into /dir on the image. + * Make a directory /dir on the image. Add all the files in basedir/dir into + * /dir on the image. */ -void add_files(char *basedir, char *dir) +void add_files(char *basedir, char *dir, struct directory *parent) { struct directory *d; DIR *D; @@ -452,18 +522,24 @@ void add_files(char *basedir, char *dir) char fullname[BLKSIZE]; uint16_t firstblock; struct fileperm *perms; + char *noslashdir = dir; + + /* If dir is /, trim it for later snprintfs */ + if (!strcmp(dir, "/")) noslashdir = ""; /* Get the full external directory name */ - snprintf(fullname, BLKSIZE, "%s/%s", basedir, dir); + snprintf(fullname, BLKSIZE, "%s/%s", basedir, noslashdir); /* Open the external directory */ D = opendir(fullname); - if (D == NULL) { - printf("Cannot opendir %s\n", fullname); exit(1); - } + if (D == NULL) { printf("Cannot opendir %s\n", fullname); exit(1); } /* Create the image directory */ - d = create_dir(dir, DIRBLOCKS); + d = create_dir(dir, DIRBLOCKS, parent); + + /* Now create the /dev directory by hand */ + if (makedevflag && !strcmp(dir, "/")) + add_devdir(); /* Walk the directory */ while ((dp = readdir(D)) != NULL) { @@ -471,11 +547,20 @@ void add_files(char *basedir, char *dir) if (!strcmp(dp->d_name, "..")) continue; /* Stat the entry found */ - snprintf(fullname, BLKSIZE, "%s/%s/%s", basedir, dir, dp->d_name); + snprintf(fullname, BLKSIZE, "%s/%s/%s", basedir, noslashdir, dp->d_name); if (stat(fullname, &sb) < 0) { printf("Cannot stat %s\n", fullname); continue; } + /* If it is a directory, recursively add it */ + if (S_ISDIR(sb.st_mode)) { + char bdir[BLKSIZE]; + snprintf(bdir, BLKSIZE, "%s/%s", basedir, noslashdir); + if (debug) printf("Recursing into %s/%s\n", bdir, dp->d_name); + add_files(bdir, dp->d_name, d); + if (debug) printf("Back from into %s/%s\n", bdir, dp->d_name); + } + /* Skip if it is not a regular file */ if (!S_ISREG(sb.st_mode)) continue; @@ -490,7 +575,7 @@ void add_files(char *basedir, char *dir) } /* Search for any known permissions for this file */ - perms= search_fileperm(dir, dp->d_name); + perms = search_fileperm(dir, dp->d_name); /* Create the file's i-node */ /* and copy the file into the image */ @@ -503,140 +588,47 @@ void add_files(char *basedir, char *dir) write_dir(d, dir); } -/* Following the cold UNIX rf output, make /dev. In /dev, - * make devices with specific i-nums, which I guess act like - * early major/minor device numbers. - */ -void add_devdir(void) -{ - struct dev { - char *name; - uint16_t inum; - } devlist[] = { - { "tty", 1 }, - { "ppt", 2 }, - { "mem", 3 }, - { "rf0", 4 }, - { "rk0", 5 }, - { "tap0", 6 }, - { "tap1", 7 }, - { "tap2", 8 }, - { "tap3", 9 }, - { "tap4", 10 }, - { "tap5", 11 }, - { "tap6", 12 }, - { "tap7", 13 }, - { "tty0", 14 }, - { "tty1", 15 }, - { "tty2", 16 }, - { "tty3", 17 }, - { "tty4", 18 }, - { "tty5", 19 }, - { "tty6", 20 }, - { "tty7", 21 }, - { "lpr", 22 }, - { "tty8", 1 }, - { NULL, 0 }, - }; - - struct directory *d; - int i; - - d = create_dir("dev", 1); /* cold UNIX only uses 1 block */ - - for (i=0; devlist[i].name !=NULL; i++) { - add_direntry(d, devlist[i].inum, devlist[i].name); - } - - /* And write the directory out */ - write_dir(d, "dev"); -} - /* - * Given a top-level directory, find all of the subdirectories, - * and add them and their files into the image. - */ -void process_topdir(char *topdir) -{ - DIR *D; - struct dirent *dp; - struct stat sb; - char fullname[BLKSIZE]; - - /* Open the top directory */ - D = opendir(topdir); - if (D == NULL) { - printf("Cannot opendir %s\n", topdir); exit(1); - } - - /* Walk the directory */ - while ((dp = readdir(D)) != NULL) { - if (!strcmp(dp->d_name, ".")) continue; /* Skip . and .. */ - if (!strcmp(dp->d_name, "..")) continue; - - /* Stat the entry found */ - snprintf(fullname, BLKSIZE, "%s/%s", topdir, dp->d_name); - if (stat(fullname, &sb) < 0) { - printf("Cannot stat %s\n", fullname); continue; - } - - /* Skip if it is not a directory */ - if (!S_ISDIR(sb.st_mode)) continue; - - /* Skip if the name is too long */ - if (strlen(dp->d_name) > 8) { - printf("Skipping long dirname %s for now\n", fullname); continue; - } - - /* Now process that directory and its files */ - add_files(topdir, dp->d_name); - } - closedir(D); -} - -/* Open and parse the file to obtain a list of V1 file owner/perm/dates. - * The file has a very specific format. Lines before '======' are ignored. - * After that, each line represents one file, and has pcre line format: - * - * - * ^[-xu][-r][-w][-r][-w] +\d+.*\/\S+ *\d+ - * - * First 5 chars represent x=executable, u=setuid, r=read, w=write. - * Spaces separate the permissions and the decimal userid. - * Then we look for a / which begins the full pathname. - * Spaces seperate the full pathname and the timestamp which is in 1/60th - * of a second since the beginning of the year. + * Open and parse the file to obtain a list of V1 file owner/perm/dates. The + * file has a very specific format. Lines before '======' are ignored. After + * that, each line represents one file, and has pcre line format: + * + * + * ^[-xu][-r][-w][-r][-w] +\d+.*\/\S+ *\d+ + * + * First 5 chars represent x=executable, u=setuid, r=read, w=write. Spaces + * separate the permissions and the decimal userid. Then we look for a / + * which begins the full pathname. Spaces seperate the full pathname and the + * timestamp which is in 1/60th of a second since the beginning of the year. */ void read_permsfile(char *file) { FILE *zin; char linebuf[BLKSIZE]; char *cptr, *sptr; - int posn=0; + int posn = 0; - if (file==NULL) return; - if ((zin= fopen(file, "r"))==NULL) return; + if (file == NULL) return; + if ((zin = fopen(file, "r")) == NULL) return; /* Find line beginning with = */ while (1) { - if (fgets(linebuf, BLKSIZE-1, zin)==NULL) { + if (fgets(linebuf, BLKSIZE - 1, zin) == NULL) { fclose(zin); return; } - if (linebuf[0]== '=') break; + if (linebuf[0] == '=') break; } /* Now read and parse each line */ while (1) { - if ((posn >= PERMLISTSIZE) || (fgets(linebuf, BLKSIZE-1, zin)==NULL)) { + if ((posn >= PERMLISTSIZE) || (fgets(linebuf, BLKSIZE - 1, zin) == NULL)) { fclose(zin); return; } - /* Skip if junk permissions */ - if (linebuf[0] != '-' && linebuf[0] != 'x' && linebuf[0] != 'u') - continue; + if (linebuf[0] != '-' && linebuf[0] != 'x' && linebuf[0] != 'u') continue; /* Get the permissions */ - permlist[posn].flags=0; + permlist[posn].flags = 0; if (linebuf[0] == 'x') permlist[posn].flags |= I_EXEC; if (linebuf[0] == 'u') permlist[posn].flags |= I_SETUID | I_EXEC; if (linebuf[1] == 'r') permlist[posn].flags |= I_UREAD; @@ -645,30 +637,31 @@ void read_permsfile(char *file) if (linebuf[4] == 'w') permlist[posn].flags |= I_OWRITE; /* Get the userid */ - permlist[posn].uid= strtol(&linebuf[5], NULL , 10); - + permlist[posn].uid = strtol(&linebuf[5], NULL, 10); + /* Search for the full pathname, skip line if not found */ - if ((cptr= strchr(linebuf, '/'))==NULL) continue; + if ((cptr = strchr(linebuf, '/')) == NULL) continue; /* Find the space after the full name, skip if not found */ /* Null-terminate the filename */ - if ((sptr= strchr(cptr, ' '))==NULL) continue; - *(sptr++)= '\0'; + if ((sptr = strchr(cptr, ' ')) == NULL) continue; + *(sptr++) = '\0'; /* Copy the pathname minus the leading slash */ /* However, if it starts with "/usr/", skip "/usr/" */ if (!strncmp(cptr, "/usr/", 5)) - cptr+= 5; + cptr += 5; else cptr++; - permlist[posn].name= strdup(cptr); + + permlist[posn].name = strdup(cptr); /* Finally get the timestamp */ - permlist[posn].mtime= strtol(sptr, NULL , 10); + permlist[posn].mtime = strtol(sptr, NULL, 10); if (debug) { printf("0%2o %2d %10d %s\n", permlist[posn].flags, permlist[posn].uid, - permlist[posn].mtime, permlist[posn].name); + permlist[posn].mtime, permlist[posn].name); } posn++; } @@ -688,16 +681,17 @@ void usage(void) int main(int argc, char *argv[]) { - int makedevflag=0; /* Do we make the /dev directory? */ - int i,ch; + int i, ch; int numiblocks; - int fs_size; /* Equal to disksize minus any swap */ + int fs_size; /* Equal to disksize minus any swap */ /* Get any optional arguments */ while ((ch = getopt(argc, argv, "dp:")) != -1) { switch (ch) { - case 'd': debug=1; break; - case 'p': read_permsfile(optarg); break; + case 'd': + debug = 1; break; + case 'p': + read_permsfile(optarg); break; } } @@ -717,7 +711,7 @@ int main(int argc, char *argv[]) } else { disksize = RF_SIZE; fs_size = RF_NOSWAPSIZE; - makedevflag=1; + makedevflag = 1; } /* Create the image */ @@ -727,43 +721,43 @@ int main(int argc, char *argv[]) } /* Make the image full-sized */ - for (i = 0; i < fs_size; i++) + for (i = 0; i < disksize; i++) fwrite(buf, BLKSIZE, 1, diskfh); /* Create the free-map: fortunately RK_SIZE and RF_SIZE are divisible by 8 */ /* Make all the blocks free to start with */ - freemap = (uint8_t *)malloc(disksize / 8); + freemap = (uint8_t *) malloc(disksize / 8); for (i = 0; i < disksize / 8; i++) freemap[i] = 0xff; /* Mark blocks 0 and 1 as in-use */ - block_inuse(0); block_inuse(1); + block_inuse(0); + block_inuse(1); /* Choose disksize/INODE_RATIO as the number of i-nodes to allocate */ /* if we haven't already given icount a value. */ /* Make sure that it is divisible by 8 */ - if (icount==0) + if (icount == 0) icount = 8 * (disksize / INODE_RATIO / 8); /* Create the inode bitmap and inode list */ - inodemap = (uint8_t *)calloc(1, (icount - ROOTDIR_INUM) / 8); + inodemap = (uint8_t *) calloc(1, (icount - ROOTDIR_INUM) / 8); inodelist = (struct v1inode *)calloc(icount, sizeof(struct v1inode)); /* Mark special i-nodes 0 to ROOTDIR_INUM-1 as allocated */ /* We follow the output of cold UNIX here. */ for (i = 0; i < ROOTDIR_INUM; i++) { - inodelist[i].flags |= I_ALLOCATED|I_UREAD|I_UWRITE|I_OREAD|I_OWRITE; - inodelist[i].nlinks= 1; - inodelist[i].uid= 1; - inodelist[i].mtime[3]= 0x38; + inodelist[i].flags |= I_ALLOCATED | I_UREAD | I_UWRITE | I_OREAD | I_OWRITE; + inodelist[i].nlinks = 1; + inodelist[i].uid = 1; + inodelist[i].mtime[3] = 0x38; } /* INODEPERBLOCK i-nodes fit into a block, so work out how many blocks the */ /* inodelist occupies. Round up to ensure a partial block => full block */ /* Mark the blocks from 2 up as being in-use */ - numiblocks = (icount + INODEPERBLOCK -1) / INODEPERBLOCK; - if (debug) - printf("%d i-nodes, %d i-node blocks\n", icount, numiblocks); + numiblocks = (icount + INODEPERBLOCK - 1) / INODEPERBLOCK; + if (debug) printf("%d i-nodes, %d i-node blocks\n", icount, numiblocks); nextfreeblock = 2 + numiblocks; for (i = 2; i < nextfreeblock; i++) block_inuse(i); @@ -772,14 +766,9 @@ int main(int argc, char *argv[]) /* Mark the root directory i-node (ROOTDIR_INUM) as in-use */ /* Create the root directory */ inode_inuse(ROOTDIR_INUM); - rootdir = create_dir("/", 1); /* cold UNIX only uses 1 block */ - - /* Now create the /dev directory by hand */ - if (makedevflag) - add_devdir(); /* Walk the top directory argument, dealing with the subdirs */ - process_topdir(argv[0]); + add_files(argv[0], "/", rootdir); /* Write out the root directory */ write_dir(rootdir, "/");