diff --git a/usr.sbin/mtree/Makefile b/usr.sbin/mtree/Makefile index c736f13a1880..2e58af2992a0 100644 --- a/usr.sbin/mtree/Makefile +++ b/usr.sbin/mtree/Makefile @@ -1,7 +1,6 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 PROG= mtree -#CFLAGS+=-DDEBUG SRCS= compare.c crc.c create.c misc.c mtree.c spec.c verify.c MAN8= mtree.8 .PATH: ${.CURDIR}/../../usr.bin/cksum diff --git a/usr.sbin/mtree/compare.c b/usr.sbin/mtree/compare.c index b2585727e71d..166fb5b21307 100644 --- a/usr.sbin/mtree/compare.c +++ b/usr.sbin/mtree/compare.c @@ -59,7 +59,7 @@ static char *ftype __P((u_int)); (void)printf("\n"); \ } else { \ tab = ""; \ - (void)printf("%*s", INDENTNAMELEN - len, ""); \ + (void)printf("%*s", INDENTNAMELEN - (int)len, ""); \ } \ } @@ -72,7 +72,7 @@ compare(name, s, p) extern int uflag; u_long len, val; int fd, label; - char *cp, *tab; + char *cp, *tab = ""; label = 0; switch(s->type) { @@ -111,7 +111,7 @@ typeerr: LABEL; /* Set the uid/gid first, then set the mode. */ if (s->flags & (F_UID | F_UNAME) && s->st_uid != p->fts_statp->st_uid) { LABEL; - (void)printf("%suser (%u, %u", + (void)printf("%suser (%lu, %lu", tab, s->st_uid, p->fts_statp->st_uid); if (uflag) if (chown(p->fts_accpath, s->st_uid, -1)) @@ -125,7 +125,7 @@ typeerr: LABEL; } if (s->flags & (F_GID | F_GNAME) && s->st_gid != p->fts_statp->st_gid) { LABEL; - (void)printf("%sgid (%u, %u", + (void)printf("%sgid (%lu, %lu", tab, s->st_gid, p->fts_statp->st_gid); if (uflag) if (chown(p->fts_accpath, -1, s->st_gid)) @@ -169,9 +169,9 @@ typeerr: LABEL; * XXX * Catches nano-second differences, but doesn't display them. */ - if (s->flags & F_TIME && - s->st_mtimespec.ts_sec != p->fts_statp->st_mtimespec.ts_sec || - s->st_mtimespec.ts_nsec != p->fts_statp->st_mtimespec.ts_nsec) { + if ((s->flags & F_TIME && + s->st_mtimespec.ts_sec != p->fts_statp->st_mtimespec.ts_sec) || + (s->st_mtimespec.ts_nsec != p->fts_statp->st_mtimespec.ts_nsec)) { LABEL; (void)printf("%smodification time (%.24s, ", tab, ctime(&s->st_mtimespec.ts_sec)); diff --git a/usr.sbin/mtree/create.c b/usr.sbin/mtree/create.c index 9ce603e0001b..8901f44f0384 100644 --- a/usr.sbin/mtree/create.c +++ b/usr.sbin/mtree/create.c @@ -52,8 +52,9 @@ static char sccsid[] = "@(#)create.c 8.1 (Berkeley) 6/6/93"; #define INDENTNAMELEN 15 #define MAXLINELEN 80 -extern int crc_total, ftsoptions; -extern int dflag, sflag; +extern long int crc_total; +extern int ftsoptions; +extern int dflag, iflag, nflag, sflag; extern u_short keys; extern char fullpath[MAXPATHLEN]; @@ -62,9 +63,9 @@ static uid_t uid; static mode_t mode; static int dsort __P((const FTSENT **, const FTSENT **)); -static void output __P((int *, const char *, ...)); +static void output __P((int, int *, const char *, ...)); static int statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *)); -static void statf __P((FTSENT *)); +static void statf __P((int, FTSENT *)); void cwalk() @@ -73,6 +74,7 @@ cwalk() register FTSENT *p; time_t clock; char *argv[2], host[MAXHOSTNAMELEN]; + int indent = 0; (void)time(&clock); (void)gethostname(host, sizeof(host)); @@ -84,16 +86,24 @@ cwalk() argv[1] = NULL; if ((t = fts_open(argv, ftsoptions, dsort)) == NULL) err("fts_open: %s", strerror(errno)); - while (p = fts_read(t)) + while ((p = fts_read(t))) { + if (iflag) + indent = p->fts_level * 4; switch(p->fts_info) { case FTS_D: - (void)printf("\n# %s\n", p->fts_path); + if (!dflag) + (void)printf("\n"); + if (!nflag) + (void)printf("# %s\n", p->fts_path); statd(t, p, &uid, &gid, &mode); - statf(p); + statf(indent, p); break; case FTS_DP: - if (p->fts_level > 0) - (void)printf("# %s\n..\n\n", p->fts_path); + if (!nflag && (p->fts_level > 0)) + (void)printf("%*s# %s\n", indent, "", p->fts_path); + (void)printf("%*s..\n", indent, ""); + if (!dflag) + (void)printf("\n"); break; case FTS_DNR: case FTS_ERR: @@ -103,10 +113,11 @@ cwalk() break; default: if (!dflag) - statf(p); + statf(indent, p); break; } + } (void)fts_close(t); if (sflag && keys & F_CKSUM) (void)fprintf(stderr, @@ -114,44 +125,59 @@ cwalk() } static void -statf(p) +statf(indent, p) + int indent; FTSENT *p; { struct group *gr; struct passwd *pw; u_long len, val; - int fd, indent; + int fd, offset; - if (S_ISDIR(p->fts_statp->st_mode)) - indent = printf("%s", p->fts_name); + if (iflag || S_ISDIR(p->fts_statp->st_mode)) + offset = printf("%*s%s", indent, "", p->fts_name); else - indent = printf(" %s", p->fts_name); + offset = printf("%*s %s", indent, "", p->fts_name); - if (indent > INDENTNAMELEN) - indent = MAXLINELEN; + if (offset > (INDENTNAMELEN + indent)) + offset = MAXLINELEN; else - indent += printf("%*s", INDENTNAMELEN - indent, ""); + offset += printf("%*s", (INDENTNAMELEN + indent) - offset, ""); - if (!S_ISREG(p->fts_statp->st_mode)) - output(&indent, "type=%s", inotype(p->fts_statp->st_mode)); - if (keys & (F_UID | F_UNAME) && p->fts_statp->st_uid != uid) - if (keys & F_UNAME && (pw = getpwuid(p->fts_statp->st_uid))) - output(&indent, "uname=%s", pw->pw_name); - else /* if (keys & F_UID) */ - output(&indent, "uid=%u", p->fts_statp->st_uid); - if (keys & (F_GID | F_GNAME) && p->fts_statp->st_gid != gid) - if (keys & F_GNAME && (gr = getgrgid(p->fts_statp->st_gid))) - output(&indent, "gname=%s", gr->gr_name); - else /* if (keys & F_GID) */ - output(&indent, "gid=%u", p->fts_statp->st_gid); + if (!S_ISREG(p->fts_statp->st_mode) && !dflag) + output(indent, &offset, "type=%s", inotype(p->fts_statp->st_mode)); + if (p->fts_statp->st_uid != uid) { + if (keys & F_UNAME) { + if ((pw = getpwuid(p->fts_statp->st_uid)) != NULL) { + output(indent, &offset, "uname=%s", pw->pw_name); + } else { + err("could not get uname for uid=%u", + p->fts_statp->st_uid); + } + } + if (keys & F_UID) + output(indent, &offset, "uid=%u", p->fts_statp->st_uid); + } + if (p->fts_statp->st_gid != gid) { + if (keys & F_GNAME) { + if ((gr = getgrgid(p->fts_statp->st_gid)) != NULL) { + output(indent, &offset, "gname=%s", gr->gr_name); + } else { + err("could not get gname for gid=%u", + p->fts_statp->st_gid); + } + } + if (keys & F_GID) + output(indent, &offset, "gid=%u", p->fts_statp->st_gid); + } if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode) - output(&indent, "mode=%#o", p->fts_statp->st_mode & MBITS); + output(indent, &offset, "mode=%#o", p->fts_statp->st_mode & MBITS); if (keys & F_NLINK && p->fts_statp->st_nlink != 1) - output(&indent, "nlink=%u", p->fts_statp->st_nlink); + output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink); if (keys & F_SIZE) - output(&indent, "size=%qd", p->fts_statp->st_size); + output(indent, &offset, "size=%qd", p->fts_statp->st_size); if (keys & F_TIME) - output(&indent, "time=%ld.%ld", + output(indent, &offset, "time=%ld.%ld", p->fts_statp->st_mtimespec.ts_sec, p->fts_statp->st_mtimespec.ts_nsec); if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) { @@ -159,11 +185,11 @@ statf(p) crc(fd, &val, &len)) err("%s: %s", p->fts_accpath, strerror(errno)); (void)close(fd); - output(&indent, "cksum=%lu", val); + output(indent, &offset, "cksum=%lu", val); } if (keys & F_SLINK && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) - output(&indent, "link=%s", rlink(p->fts_accpath)); + output(indent, &offset, "link=%s", rlink(p->fts_accpath)); (void)putchar('\n'); } @@ -185,9 +211,9 @@ statd(t, parent, puid, pgid, pmode) register mode_t smode; struct group *gr; struct passwd *pw; - gid_t savegid; - uid_t saveuid; - mode_t savemode; + gid_t savegid = *pgid; + uid_t saveuid = *puid; + mode_t savemode = *pmode; u_short maxgid, maxuid, maxmode, g[MAXGID], u[MAXUID], m[MAXMODE]; if ((p = fts_children(t, 0)) == NULL) { @@ -202,45 +228,58 @@ statd(t, parent, puid, pgid, pmode) maxuid = maxgid = maxmode = 0; for (; p; p = p->fts_link) { - smode = p->fts_statp->st_mode & MBITS; - if (smode < MAXMODE && ++m[smode] > maxmode) { - savemode = smode; - maxmode = m[smode]; - } - sgid = p->fts_statp->st_gid; - if (sgid < MAXGID && ++g[sgid] > maxgid) { - savegid = sgid; - maxgid = g[sgid]; - } - suid = p->fts_statp->st_uid; - if (suid < MAXUID && ++u[suid] > maxuid) { - saveuid = suid; - maxuid = u[suid]; + if (!dflag || (dflag && S_ISDIR(p->fts_statp->st_mode))) { + smode = p->fts_statp->st_mode & MBITS; + if (smode < MAXMODE && ++m[smode] > maxmode) { + savemode = smode; + maxmode = m[smode]; + } + sgid = p->fts_statp->st_gid; + if (sgid < MAXGID && ++g[sgid] > maxgid) { + savegid = sgid; + maxgid = g[sgid]; + } + suid = p->fts_statp->st_uid; + if (suid < MAXUID && ++u[suid] > maxuid) { + saveuid = suid; + maxuid = u[suid]; + } } } - (void)printf("/set type=file"); - if (keys & F_GID) - (void)printf(" gid=%u", savegid); - if (keys & F_GNAME) - if ((gr = getgrgid(savegid)) != NULL) - (void)printf(" gname=%s", gr->gr_name); + /* + * If the /set record is the same as the last one we do not need to output + * a new one. So first we check to see if anything changed. + */ + if ((((keys & F_UNAME) | (keys & F_UID)) && (*puid != saveuid)) || + (((keys & F_GNAME) | (keys & F_GID)) && (*pgid != savegid)) || + ((keys & F_MODE) && (*pmode != savemode))) { + if (dflag) + (void)printf("/set type=dir"); else - (void)printf(" gid=%u", savegid); - if (keys & F_UNAME) - if ((pw = getpwuid(saveuid)) != NULL) - (void)printf(" uname=%s", pw->pw_name); - else - (void)printf(" uid=%u", saveuid); - if (keys & F_UID) - (void)printf(" uid=%u", saveuid); - if (keys & F_MODE) - (void)printf(" mode=%#o", savemode); - if (keys & F_NLINK) - (void)printf(" nlink=1"); - (void)printf("\n"); - *puid = saveuid; - *pgid = savegid; - *pmode = savemode; + (void)printf("/set type=file"); + if (keys & F_UNAME) + if ((pw = getpwuid(saveuid)) != NULL) + (void)printf(" uname=%s", pw->pw_name); + else + err("could not get uname for uid=%u", saveuid); + if (keys & F_UID) + (void)printf(" uid=%lu", saveuid); + if (keys & F_GNAME) + if ((gr = getgrgid(savegid)) != NULL) + (void)printf(" gname=%s", gr->gr_name); + else + err("could not get gname for gid=%u", savegid); + if (keys & F_GID) + (void)printf(" gid=%lu", savegid); + if (keys & F_MODE) + (void)printf(" mode=%#o", savemode); + if (keys & F_NLINK) + (void)printf(" nlink=1"); + (void)printf("\n"); + *puid = saveuid; + *pgid = savegid; + *pmode = savemode; + } return (0); } @@ -264,9 +303,10 @@ dsort(a, b) void #if __STDC__ -output(int *offset, const char *fmt, ...) +output(int indent, int *offset, const char *fmt, ...) #else -output(offset, fmt, va_alist) +output(indent, offset, fmt, va_alist) + int indent; int *offset; char *fmt; va_dcl @@ -283,8 +323,8 @@ output(offset, fmt, va_alist) va_end(ap); if (*offset + strlen(buf) > MAXLINELEN - 3) { - (void)printf(" \\\n%*s", INDENTNAMELEN, ""); - *offset = INDENTNAMELEN; + (void)printf(" \\\n%*s", INDENTNAMELEN + indent, ""); + *offset = INDENTNAMELEN + indent; } *offset += printf(" %s", buf) + 1; } diff --git a/usr.sbin/mtree/misc.c b/usr.sbin/mtree/misc.c index 31691364de38..ff970840641c 100644 --- a/usr.sbin/mtree/misc.c +++ b/usr.sbin/mtree/misc.c @@ -52,18 +52,18 @@ typedef struct _key { /* NB: the following table must be sorted lexically. */ static KEY keylist[] = { - "cksum", F_CKSUM, NEEDVALUE, - "gid", F_GID, NEEDVALUE, - "gname", F_GNAME, NEEDVALUE, - "ignore", F_IGN, 0, - "link", F_SLINK, NEEDVALUE, - "mode", F_MODE, NEEDVALUE, - "nlink", F_NLINK, NEEDVALUE, - "size", F_SIZE, NEEDVALUE, - "time", F_TIME, NEEDVALUE, - "type", F_TYPE, NEEDVALUE, - "uid", F_UID, NEEDVALUE, - "uname", F_UNAME, NEEDVALUE, + {"cksum", F_CKSUM, NEEDVALUE}, + {"gid", F_GID, NEEDVALUE}, + {"gname", F_GNAME, NEEDVALUE}, + {"ignore", F_IGN, 0}, + {"link", F_SLINK, NEEDVALUE}, + {"mode", F_MODE, NEEDVALUE}, + {"nlink", F_NLINK, NEEDVALUE}, + {"size", F_SIZE, NEEDVALUE}, + {"time", F_TIME, NEEDVALUE}, + {"type", F_TYPE, NEEDVALUE}, + {"uid", F_UID, NEEDVALUE}, + {"uname", F_UNAME, NEEDVALUE}, }; u_int @@ -113,7 +113,8 @@ err(fmt, va_alist) #else va_start(ap); #endif - (void)fprintf(stderr, "mtree: "); + (void)fflush(NULL); + (void)fprintf(stderr, "\nmtree: "); (void)vfprintf(stderr, fmt, ap); va_end(ap); (void)fprintf(stderr, "\n"); diff --git a/usr.sbin/mtree/mtree.8 b/usr.sbin/mtree/mtree.8 index 54729f0fdad5..e8a4cb29a82b 100644 --- a/usr.sbin/mtree/mtree.8 +++ b/usr.sbin/mtree/mtree.8 @@ -39,7 +39,7 @@ .Nd map a directory hierarchy .Sh SYNOPSIS .Nm mtree -.Op Fl cderux +.Op Fl cdeinrux .Op Fl f Ar spec .Op Fl K Ar keywords .Op Fl k Ar keywords @@ -67,12 +67,26 @@ specification. Read the specification from .Ar file , instead of from the standard input. +.It Fl i +Indents the output 4 spaces each time a directory level is descended when +create a specification with the +.Fl c +option. +This does not effect either the /set statements or the comment before each +directory. +It does however effect the comment before the close of each directory. .It Fl K Add the specified (whitespace or comma separated) keywords to the current set of keywords. .It Fl k Use the ``type'' keyword plus the specified (whitespace or comma separated) keywords instead of the current set of keywords. +.It Fl n +Do not emit pathname comments when creating a specification. Normally +a comment is emitted before each directory and before the close of that +directory when using the +.Fl c +option. .It Fl p Use the file hierarchy rooted in .Ar path , diff --git a/usr.sbin/mtree/mtree.c b/usr.sbin/mtree/mtree.c index 17857c5543d3..9f5aad68aebf 100644 --- a/usr.sbin/mtree/mtree.c +++ b/usr.sbin/mtree/mtree.c @@ -50,10 +50,10 @@ static char sccsid[] = "@(#)mtree.c 8.1 (Berkeley) 6/6/93"; #include "mtree.h" #include "extern.h" -extern int crc_total; +extern long int crc_total; int ftsoptions = FTS_PHYSICAL; -int cflag, dflag, eflag, rflag, sflag, uflag; +int cflag, dflag, eflag, iflag, nflag, rflag, sflag, uflag; u_short keys; char fullpath[MAXPATHLEN]; @@ -71,7 +71,7 @@ main(argc, argv) dir = NULL; keys = KEYDEFAULT; - while ((ch = getopt(argc, argv, "cdef:K:k:p:rs:ux")) != EOF) + while ((ch = getopt(argc, argv, "cdef:iK:k:np:rs:ux")) != EOF) switch((char)ch) { case 'c': cflag = 1; @@ -86,6 +86,9 @@ main(argc, argv) if (!(freopen(optarg, "r", stdin))) err("%s: %s", optarg, strerror(errno)); break; + case 'i': + iflag = 1; + break; case 'K': while ((p = strsep(&optarg, " \t,")) != NULL) if (*p != '\0') @@ -97,6 +100,9 @@ main(argc, argv) if (*p != '\0') keys |= parsekey(p, NULL); break; + case 'n': + nflag = 1; + break; case 'p': dir = optarg; break; @@ -141,6 +147,6 @@ static void usage() { (void)fprintf(stderr, -"usage: mtree [-cderux] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n"); +"usage: mtree [-cdeinrux] [-f spec] [-K key] [-k key] [-p path] [-s seed]\n"); exit(1); } diff --git a/usr.sbin/mtree/spec.c b/usr.sbin/mtree/spec.c index a50574fcbf50..a2c5171542c5 100644 --- a/usr.sbin/mtree/spec.c +++ b/usr.sbin/mtree/spec.c @@ -61,7 +61,7 @@ spec() int c_cur, c_next; char buf[2048]; - root = NULL; + centry = last = root = NULL; bzero(&ginfo, sizeof(ginfo)); c_cur = c_next = 0; for (lineno = 1; fgets(buf, sizeof(buf), stdin); @@ -164,14 +164,14 @@ set(t, ip) register NODE *ip; { register int type; - register char *kw, *val; + register char *kw, *val = NULL; struct group *gr; struct passwd *pw; mode_t *m; int value; char *ep; - for (; kw = strtok(t, "= \t\n"); t = NULL) { + for (; (kw = strtok(t, "= \t\n")); t = NULL) { ip->flags |= type = parsekey(kw, &value); if (value && (val = strtok(NULL, " \t\n")) == NULL) err("missing value"); @@ -275,6 +275,6 @@ unset(t, ip) { register char *p; - while (p = strtok(t, "\n\t ")) + while ((p = strtok(t, "\n\t "))) ip->flags &= ~parsekey(p, NULL); } diff --git a/usr.sbin/mtree/verify.c b/usr.sbin/mtree/verify.c index 27d9b90b123d..4abf0fb191f7 100644 --- a/usr.sbin/mtree/verify.c +++ b/usr.sbin/mtree/verify.c @@ -46,7 +46,8 @@ static char sccsid[] = "@(#)verify.c 8.1 (Berkeley) 6/6/93"; #include "mtree.h" #include "extern.h" -extern int crc_total, ftsoptions; +extern long int crc_total; +extern int ftsoptions; extern int dflag, eflag, rflag, sflag, uflag; extern char fullpath[MAXPATHLEN]; @@ -82,7 +83,7 @@ vwalk() err("fts_open: %s", strerror(errno)); level = root; ftsdepth = specdepth = rval = 0; - while (p = fts_read(t)) { + while ((p = fts_read(t))) { switch(p->fts_info) { case FTS_D: ++ftsdepth; @@ -107,8 +108,8 @@ vwalk() } for (ep = level; ep; ep = ep->next) - if (ep->flags & F_MAGIC && - !fnmatch(ep->name, p->fts_name, FNM_PATHNAME) || + if ((ep->flags & F_MAGIC && + !fnmatch(ep->name, p->fts_name, FNM_PATHNAME)) || !strcmp(ep->name, p->fts_name)) { ep->flags |= F_VISIT; if (compare(ep->name, ep, p))