]> Zhao Yanbai Git Server - minix.git/commitdiff
mkfs.mfs, mkproto: minor features 61/1161/1
authorBen Gras <ben@minix3.org>
Tue, 19 Nov 2013 15:58:05 +0000 (15:58 +0000)
committerBen Gras <ben@minix3.org>
Tue, 19 Nov 2013 15:58:05 +0000 (15:58 +0000)
. mkfs.mfs: -T option to set timestamp of files on FS
. mkproto: normalize (sort) order of directory entries
. mkproto bugfix: always print mode in 3 digits (%03o)

Change-Id: Ice06d5f05500cd2ac9b063156c340b8f78fe6441

usr.sbin/mkfs.mfs/mkfs.c
usr.sbin/mkfs.mfs/v3/mkfs.mfs.1
usr.sbin/mkproto/Makefile
usr.sbin/mkproto/mkproto.c

index 36f506cf441ebf0a15fad48f62912d32b0201630..8fd95c3a58311b9c9958124be0eb4363348c50bd 100644 (file)
@@ -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.
index f939708441620308c388d173bcd11f61b97df7f7..aabf46db6544a1b7ea30a3b10e9e67f951333387 100644 (file)
@@ -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
index baa5da16cf889f2abcc5f58312705f3b3406f4d9..8b569e047b5be376f629be9a8c946cbe533cc072 100644 (file)
@@ -1,4 +1,7 @@
 PROG=  mkproto
 MAN=
 
+LDADD+= -lminlib
+DPADD+= ${LIBMINLIB}
+
 .include <bsd.prog.mk>
index 8c6ab56e3d78d9b62582cfb7d87b52283e1b0fe3..477d6dc71f9d90a0455ae23f617331459bbb47dd 100644 (file)
@@ -4,12 +4,15 @@
 
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <minix/minlib.h>
 #include <limits.h>
 #include <dirent.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <assert.h>
+#include <err.h>
 
 /* 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' :