diff --git a/usr.sbin/mkfs.mfs/mkfs.c b/usr.sbin/mkfs.mfs/mkfs.c index 36f506cf4..8fd95c3a5 100644 --- a/usr.sbin/mkfs.mfs/mkfs.c +++ b/usr.sbin/mkfs.mfs/mkfs.c @@ -142,7 +142,7 @@ static ssize_t mkfs_write(void * buf, size_t count); int main(int argc, char *argv[]) { - int nread, mode, usrid, grpid, ch, extra_space_percent; + int nread, mode, usrid, grpid, ch, extra_space_percent, Tflag = 0; block_t blocks, maxblocks, bblocks; ino_t inodes, root_inum; char *token[MAX_TOKENS], line[LINE_LEN], *sfx; @@ -160,7 +160,7 @@ main(int argc, char *argv[]) #endif zone_shift = 0; extra_space_percent = 0; - while ((ch = getopt(argc, argv, "B:b:di:ltvx:z:I:")) != EOF) + while ((ch = getopt(argc, argv, "B:b:di:ltvx:z:I:T:")) != EOF) switch (ch) { #ifndef MFS_STATIC_BLOCK_SIZE case 'B': @@ -189,6 +189,10 @@ main(int argc, char *argv[]) case 'b': blocks = bblocks = strtoul(optarg, (char **) NULL, 0); break; + case 'T': + Tflag = 1; + current_time = strtoul(optarg, (char **) NULL, 0); + break; case 'd': dflag = 1; break; @@ -212,12 +216,17 @@ main(int argc, char *argv[]) * identical. First you set the time of the mkfs binary to what you * want, then go. */ - current_time = time((time_t *) 0); /* time mkfs is being run */ - if(dflag) { + if(Tflag) { + if(dflag) + errx(1, "-T and -d both specify a time and so are mutually exclusive"); + } else if(dflag) { struct stat statbuf; if (stat(progname, &statbuf)) { - perror("stat of itself"); - } else current_time = statbuf.st_mtime; + err(1, "stat of itself"); + } + current_time = statbuf.st_mtime; + } else { + current_time = time((time_t *) 0); /* time mkfs is being run */ } /* Percentage of extra size must be nonnegative. diff --git a/usr.sbin/mkfs.mfs/v3/mkfs.mfs.1 b/usr.sbin/mkfs.mfs/v3/mkfs.mfs.1 index f93970844..aabf46db6 100644 --- a/usr.sbin/mkfs.mfs/v3/mkfs.mfs.1 +++ b/usr.sbin/mkfs.mfs/v3/mkfs.mfs.1 @@ -13,6 +13,7 @@ .Op Fl z Ar zone_shift .Op Fl x Ar extra_space .Op Fl I Ar fs_offset +.Op Fl T Ar timestamp .Ar special .Op Ar prototype .Sh OPTIONS @@ -38,6 +39,8 @@ Filesystem block size (in bytes) Filesystem size (in blocks) .It Fl I Ar fs_offset Write filesystem starting at offset (in bytes) +.It Fl T Ar timestamp +Use timestamp for inode times .It Fl x Ar extra_space Extra space after dynamic sizing (blocks and inodes) .It Fl z Ar zone_shift diff --git a/usr.sbin/mkproto/Makefile b/usr.sbin/mkproto/Makefile index baa5da16c..8b569e047 100644 --- a/usr.sbin/mkproto/Makefile +++ b/usr.sbin/mkproto/Makefile @@ -1,4 +1,7 @@ PROG= mkproto MAN= +LDADD+= -lminlib +DPADD+= ${LIBMINLIB} + .include diff --git a/usr.sbin/mkproto/mkproto.c b/usr.sbin/mkproto/mkproto.c index 8c6ab56e3..477d6dc71 100644 --- a/usr.sbin/mkproto/mkproto.c +++ b/usr.sbin/mkproto/mkproto.c @@ -4,12 +4,15 @@ #include #include +#include #include #include #include #include #include #include +#include +#include /* The default values for the prototype file */ #define DEF_UID 2 /* bin */ @@ -41,6 +44,74 @@ void display_attrib(const char *name, struct stat *st); void usage(char *binname); void open_outfile(void); +/* Returned by minix_readdir */ +#define ME_MAXNAME 256 +struct me_dirent { + char d_name[ME_MAXNAME]; +}; + +struct me_dirent *minix_readdir(DIR *, int *n); +void minix_free_readdir(struct me_dirent *md, int n); + + +/* Compare dirent objects for order */ +static int cmp_dirent(const void *d1, const void *d2) +{ + struct me_dirent *dp1 = (struct me_dirent *) d1, + *dp2 = (struct me_dirent *) d2; + return strcmp(dp1->d_name, dp2->d_name); +} + +/* Return array of me_dirents. */ +struct me_dirent *minix_readdir(DIR *dirp, int *n) +{ + struct dirent *rdp; + struct me_dirent *dp; + struct me_dirent *dirents = NULL; + int reserved_dirents = 0; + int entries = 0; + + while((rdp = readdir(dirp)) != NULL) { + if(entries >= reserved_dirents) { + struct me_dirent *newdirents; + int newreserved = (2*(reserved_dirents+1)); + if(!(newdirents = realloc(dirents, newreserved * + sizeof(*dirents)))) { + free(dirents); + return NULL; + } + dirents = newdirents; + reserved_dirents = newreserved; + } + + assert(entries < reserved_dirents); + assert(strlen(rdp->d_name) < sizeof(dp->d_name)); + dp = &dirents[entries]; + memset(dp, 0, sizeof(*dp)); + strcpy(dp->d_name, rdp->d_name); + entries++; + } + + /* Assume directories contain at least "." and "..", and + * therefore the array exists. + */ + assert(entries > 0); + assert(dirents); + + /* normalize (sort) them */ + qsort(dirents, entries, sizeof(*dp), cmp_dirent); + + /* Return no. of entries. */ + *n = entries; + + return dirents; +} + +void minix_free_readdir(struct me_dirent *md, int n) +{ + free(md); +} + int main(argc, argv) int argc; char *argv[]; @@ -131,12 +202,14 @@ char *argv[]; void descend(dirname) char *dirname; { - struct dirent *dp; + struct me_dirent *dirents; DIR *dirp; char *name, *temp, *tempend; int i; struct stat st; mode_t mode; + int entries = 0, orig_entries; + struct me_dirent *dp; dirp = opendir(dirname); if (dirp == NULL) { @@ -148,8 +221,14 @@ char *dirname; strcpy(temp, dirname); strcat(temp, "/"); tempend = &temp[strlen(temp)]; + + /* read all directory entries */ + if(!(dirents = minix_readdir(dirp, &entries))) + errx(1, "minix_readdir failed"); + orig_entries = entries; + closedir(dirp); - for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + for (dp = dirents; entries > 0; dp++, entries--) { name = dp->d_name; count++; @@ -202,8 +281,8 @@ char *dirname; fprintf(outfile, " /dev/null"); fprintf(stderr,"File\n\t%s\n has an invalid mode, made empty.\n",temp); } - closedir(dirp); free(temp); + minix_free_readdir(dirents, orig_entries); tabs--; } @@ -221,7 +300,7 @@ struct stat *st; if (same_prot) prot = st->st_mode & 0777; /***** This one is a bit shady *****/ for (i = 0; i < tabs; i++) fprintf(outfile, "%s", indentstr); - fprintf(outfile, "%s%s%c%c%c%3o %d %d", + fprintf(outfile, "%s%s%c%c%c%03o %d %d", name, *name == '\0' ? "" : indentstr, /* stop the tab for a null name */ (st->st_mode & S_IFMT) == S_IFDIR ? 'd' :