This commit was manufactured by cvs2svn to create tag 'FreeBSD-release/1.0'.
[unix-history] / usr.sbin / mtree / create.c
index 649da1f..ec21de6 100644 (file)
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)create.c   5.16 (Berkeley) 3/12/91";
+static char sccsid[] = "@(#)create.c   5.19 (Berkeley) 3/2/92";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <time.h>
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <time.h>
+#include <fcntl.h>
 #include <fts.h>
 #include <dirent.h>
 #include <fts.h>
 #include <dirent.h>
+#include <grp.h>
+#include <pwd.h>
 #include <errno.h>
 #include <errno.h>
+#include <unistd.h>
 #include <stdio.h>
 #include "mtree.h"
 #include <stdio.h>
 #include "mtree.h"
+#include "extern.h"
 
 
-#define        LABEL \
-       if (label++) \
-               (void)putchar(' '); \
+#define        INDENTNAMELEN   15
+#define        MAXLINELEN      80
 
 
-int ftsoptions = FTS_PHYSICAL;
+extern int crc_total, ftsoptions;
+extern int dflag, sflag;
+extern u_short keys;
+extern char fullpath[MAXPATHLEN];
 
 
+static gid_t gid;
+static uid_t uid;
+static mode_t mode;
+
+static int     dsort __P((const FTSENT **, const FTSENT **));
+static void    output __P((int *, const char *, ...));
+static int     statd __P((FTS *, FTSENT *, uid_t *, gid_t *, mode_t *));
+static void    statf __P((FTSENT *));
+
+void
 cwalk()
 {
 cwalk()
 {
-       extern int dflag;
        register FTS *t;
        register FTSENT *p;
        register FTS *t;
        register FTSENT *p;
-       register int cnt, label, notset;
        time_t clock;
        time_t clock;
-       uid_t uid;
-       gid_t gid;
-       mode_t mode;
-       int tabs, dsort();
-       char *argv[2];
-       char curp[MAXPATHLEN], *inotype(), *getlogin(), *rlink();
-
-       if (!getwd(curp)) {
-               (void)fprintf(stderr, "mtree: %s\n", curp);
-               exit(1);
-       }
+       char *argv[2], host[MAXHOSTNAMELEN];
+
        (void)time(&clock);
        (void)time(&clock);
-       (void)printf("#\t  fs: %s\n#\t  by: %s\n#\tdate: %s\n",
-           curp, getlogin(), ctime(&clock));
+       (void)gethostname(host, sizeof(host));
+       (void)printf(
+           "#\t   user: %s\n#\tmachine: %s\n#\t   tree: %s\n#\t   date: %s",
+           getlogin(), host, fullpath, ctime(&clock));
 
        argv[0] = ".";
 
        argv[0] = ".";
-       argv[1] = (char *)NULL;
-       if (!(t = fts_open(argv, ftsoptions, dsort))) {
-               (void)fprintf(stderr,
-                   "mtree: fts_open: %s.\n", strerror(errno));
-               exit(1);
-       }
-       while (p = fts_read(t)) {
+       argv[1] = NULL;
+       if ((t = fts_open(argv, ftsoptions, dsort)) == NULL)
+               err("fts_open: %s", strerror(errno));
+       while (p = fts_read(t))
                switch(p->fts_info) {
                case FTS_D:
                switch(p->fts_info) {
                case FTS_D:
-                       if (dflag)
-                               notset = 1;
-                       else
-                               notset =
-                                   statdir(t, p, &uid, &gid, &mode, &tabs);
-                       if (!strcmp(p->fts_name, "."))
-                               continue;
+                       (void)printf("\n# %s\n", p->fts_path);
+                       statd(t, p, &uid, &gid, &mode);
+                       statf(p);
                        break;
                case FTS_DP:
                        break;
                case FTS_DP:
-                       if (p->fts_level <= 0)
-                               continue;
-                       for (cnt = p->fts_level - 1; cnt-- > 0; )
-                               (void)putchar('\t');
-                       (void)printf("..\n");
-                       continue;
+                       if (p->fts_level > 0)
+                               (void)printf("# %s\n..\n\n", p->fts_path);
+                       break;
                case FTS_DNR:
                case FTS_ERR:
                case FTS_NS:
                case FTS_DNR:
                case FTS_ERR:
                case FTS_NS:
-                       (void)fprintf(stderr, "mtree: %s: %s.\n",
-                           p->fts_path, strerror(errno));
-                       continue;
+                       (void)fprintf(stderr,
+                           "mtree: %s: %s\n", p->fts_path, strerror(errno));
+                       break;
                default:
                default:
-                       if (dflag)
-                               continue;
+                       if (!dflag)
+                               statf(p);
+                       break;
+                       
                }
                }
+       (void)fts_close(t);
+       if (sflag && keys & F_CKSUM)
+               (void)fprintf(stderr,
+                   "mtree: %s checksum: %lu\n", fullpath, crc_total);
+}
 
 
-               for (cnt = p->fts_level - 1; cnt-- > 0; )
-                       (void)putchar('\t');
-               (void)printf("%s", p->fts_name);
-               if (p->fts_info == FTS_D)
-                       (void)putchar('\t');
-               else {
-                       if (tabs > 1 && p->fts_namelen < 8)
-                               (void)putchar('\t');
-                       (void)putchar('\t');
-               }
+static void
+statf(p)
+       FTSENT *p;
+{
+       struct group *gr;
+       struct passwd *pw;
+       u_long len, val;
+       int fd, indent;
 
 
-               label = 0;
-               if (!S_ISREG(p->fts_statb.st_mode) || notset) {
-                       LABEL;
-                       (void)printf("type=%s", inotype(p->fts_statb.st_mode));
-               }
-               if (p->fts_statb.st_uid != uid || notset) {
-                       LABEL;
-                       (void)printf("owner=%u", p->fts_statb.st_uid);
-               }
-               if (p->fts_statb.st_gid != gid || notset) {
-                       LABEL;
-                       (void)printf("group=%u", p->fts_statb.st_gid);
-               }
-               if ((p->fts_statb.st_mode & MBITS) != mode || notset) {
-                       LABEL;
-                       (void)printf("mode=%#o", p->fts_statb.st_mode & MBITS);
-               }
-               if (p->fts_statb.st_nlink != 1 || notset) {
-                       LABEL;
-                       (void)printf("nlink=%u", p->fts_statb.st_nlink);
-               }
-               LABEL;
-               (void)printf("size=%ld", p->fts_statb.st_size);
-               LABEL;
-               (void)printf("time=%ld", p->fts_statb.st_mtime);
-
-               if (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE) {
-                       LABEL;
-                       (void)printf("link=%s", rlink(p->fts_accpath));
-               }
-               (void)putchar('\n');
+       if (S_ISDIR(p->fts_statp->st_mode))
+               indent = printf("%s", p->fts_name); 
+       else
+               indent = printf("    %s", p->fts_name);
+
+       if (indent > INDENTNAMELEN)
+               indent = MAXLINELEN;
+       else
+               indent += printf("%*s", INDENTNAMELEN - indent, "");
+
+       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, "gid=%s", gr->gr_name);
+               else /* if (keys & F_GID) */
+                       output(&indent, "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);
+       if (keys & F_NLINK && p->fts_statp->st_nlink != 1)
+               output(&indent, "nlink=%u", p->fts_statp->st_nlink);
+       if (keys & F_SIZE)
+               output(&indent, "size=%ld", p->fts_statp->st_size);
+       if (keys & F_TIME)
+               output(&indent, "time=%ld", p->fts_statp->st_mtime);
+       if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) {
+               if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 ||
+                   crc(fd, &val, &len))
+                       err("%s: %s", p->fts_accpath, strerror(errno));
+               (void)close(fd);
+               output(&indent, "cksum=%lu", val);
        }
        }
-       (void)fts_close(t);
+       if (keys & F_SLINK &&
+           (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE))
+               output(&indent, "link=%s", rlink(p->fts_accpath));
+       (void)putchar('\n');
 }
 
 #define        MAXGID  5000
 #define        MAXUID  5000
 #define        MAXMODE MBITS + 1
 
 }
 
 #define        MAXGID  5000
 #define        MAXUID  5000
 #define        MAXMODE MBITS + 1
 
-statdir(t, parent, puid, pgid, pmode, tabs)
+static int
+statd(t, parent, puid, pgid, pmode)
        FTS *t;
        FTSENT *parent;
        uid_t *puid;
        gid_t *pgid;
        mode_t *pmode;
        FTS *t;
        FTSENT *parent;
        uid_t *puid;
        gid_t *pgid;
        mode_t *pmode;
-       int *tabs;
 {
        register FTSENT *p;
 {
        register FTSENT *p;
-       register gid_t gid;
-       register uid_t uid;
-       register mode_t mode;
+       register gid_t sgid;
+       register uid_t suid;
+       register mode_t smode;
+       struct group *gr;
+       struct passwd *pw;
        gid_t savegid;
        uid_t saveuid;
        mode_t savemode;
        u_short maxgid, maxuid, maxmode, g[MAXGID], u[MAXUID], m[MAXMODE];
 
        gid_t savegid;
        uid_t saveuid;
        mode_t savemode;
        u_short maxgid, maxuid, maxmode, g[MAXGID], u[MAXUID], m[MAXMODE];
 
-       if (!(p = fts_children(t))) {
-               if (errno) {
-                       (void)fprintf(stderr, "mtree: %s: %s.\n",
-                           RP(parent), strerror(errno));
-                       exit(1);
-               }
-               return(1);
+       if ((p = fts_children(t, 0)) == NULL) {
+               if (errno)
+                       err("%s: %s", RP(parent), strerror(errno));
+               return (1);
        }
 
        bzero(g, sizeof(g));
        bzero(u, sizeof(u));
        bzero(m, sizeof(m));
 
        }
 
        bzero(g, sizeof(g));
        bzero(u, sizeof(u));
        bzero(m, sizeof(m));
 
-       *tabs = 1;
        maxuid = maxgid = maxmode = 0;
        for (; p; p = p->fts_link) {
        maxuid = maxgid = maxmode = 0;
        for (; p; p = p->fts_link) {
-               mode = p->fts_statb.st_mode & MBITS;
-               if (mode < MAXMODE && ++m[mode] > maxmode) {
-                       savemode = mode;
-                       maxmode = m[mode];
+               smode = p->fts_statp->st_mode & MBITS;
+               if (smode < MAXMODE && ++m[smode] > maxmode) {
+                       savemode = smode;
+                       maxmode = m[smode];
                }
                }
-               gid = p->fts_statb.st_gid;
-               if (gid < MAXGID && ++g[gid] > maxgid) {
-                       savegid = gid;
-                       maxgid = g[gid];
+               sgid = p->fts_statp->st_gid;
+               if (sgid < MAXGID && ++g[sgid] > maxgid) {
+                       savegid = sgid;
+                       maxgid = g[sgid];
                }
                }
-               uid = p->fts_statb.st_uid;
-               if (uid < MAXUID && ++u[uid] > maxuid) {
-                       saveuid = uid;
-                       maxuid = u[uid];
+               suid = p->fts_statp->st_uid;
+               if (suid < MAXUID && ++u[suid] > maxuid) {
+                       saveuid = suid;
+                       maxuid = u[suid];
                }
                }
-               if (p->fts_namelen > 7)
-                       *tabs = 2;
        }
        }
-       (void)printf("\n/set group=%u mode=%#o nlink=1 owner=%u type=file\n",
-           savegid, savemode, saveuid);
+       (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);
+               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;
        *puid = saveuid;
        *pgid = savegid;
        *pmode = savemode;
-       return(0);
+       return (0);
 }
 
 }
 
-dsort(p1, p2)
-       FTSENT **p1, **p2;
+static int
+dsort(a, b)
+       const FTSENT **a, **b;
 {
 {
-       register FTSENT *a, *b;
+       if (S_ISDIR((*a)->fts_statp->st_mode)) {
+               if (!S_ISDIR((*b)->fts_statp->st_mode))
+                       return (1);
+       } else if (S_ISDIR((*b)->fts_statp->st_mode))
+               return (-1);
+       return (strcmp((*a)->fts_name, (*b)->fts_name));
+}
 
 
-       a = *p1;
-       b = *p2;
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
 
 
-       if (S_ISDIR(a->fts_statb.st_mode)) {
-               if (!S_ISDIR(b->fts_statb.st_mode))
-                       return(1);
-       } else if (S_ISDIR(b->fts_statb.st_mode))
-               return(-1);
-       return(strcmp(a->fts_name, b->fts_name));
+void
+#if __STDC__
+output(int *offset, const char *fmt, ...)
+#else
+output(offset, fmt, va_alist)
+       int *offset;
+       char *fmt;
+        va_dcl
+#endif
+{
+       va_list ap;
+       int len;
+       char buf[1024];
+#if __STDC__
+       va_start(ap, fmt);
+#else
+       va_start(ap);
+#endif
+       len = vsnprintf(buf, sizeof(buf), fmt, ap);
+       va_end(ap);
+
+       if (*offset + len > MAXLINELEN - 3) {
+               (void)printf(" \\\n%*s", INDENTNAMELEN, "");
+               *offset = INDENTNAMELEN;
+       }
+       *offset += printf(" %s", buf) + 1;
 }
 }