mkfs.mfs, mkproto: minor features
. 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
This commit is contained in:
parent
2f7c930a6b
commit
a4a97fe8c9
4 changed files with 104 additions and 10 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
PROG= mkproto
|
||||
MAN=
|
||||
|
||||
LDADD+= -lminlib
|
||||
DPADD+= ${LIBMINLIB}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
|
|
@ -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' :
|
||||
|
|
Loading…
Reference in a new issue