use library versions of err/warn
[unix-history] / usr / src / usr.bin / du / du.c
index e906b98..2cece57 100644 (file)
@@ -15,65 +15,85 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)du.c       5.10 (Berkeley) %G%";
+static char sccsid[] = "@(#)du.c       5.20 (Berkeley) %G%";
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/stat.h>
 #endif /* not lint */
 
 #include <sys/param.h>
 #include <sys/stat.h>
-#include <sys/errno.h>
+
 #include <dirent.h>
 #include <dirent.h>
-#include <stdio.h>
+#include <err.h>
+#include <errno.h>
 #include <fts.h>
 #include <fts.h>
-#include <string.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <string.h>
+
+char   *getbsize __P((char *, int *, long *));
+int     linkchk __P((FTSENT *));
+void    usage __P((void));
 
 
+int
 main(argc, argv)
        int argc;
 main(argc, argv)
        int argc;
-       char **argv;
+       char *argv[];
 {
 {
-       extern int optind;
        register FTS *fts;
        register FTSENT *p;
        register FTS *fts;
        register FTSENT *p;
-       register int kvalue, listdirs, listfiles;
-       int ch, ftsoptions;
+       register int listdirs, listfiles;
+       long blocksize;
+       int aflag, ch, ftsoptions, notused, sflag;
        char **save;
 
        ftsoptions = FTS_PHYSICAL;
        char **save;
 
        ftsoptions = FTS_PHYSICAL;
-       kvalue = listfiles = 0;
-       listdirs = 1;
        save = argv;
        save = argv;
-       while ((ch = getopt(argc, argv, "aksx")) != EOF)
+       aflag = sflag = 0;
+       while ((ch = getopt(argc, argv, "Hahsx")) != EOF)
                switch(ch) {
                switch(ch) {
+               case 'H':
+                       ftsoptions |= FTS_COMFOLLOW;
+                       break;
                case 'a':
                case 'a':
-                       listfiles = 1;
+                       aflag = 1;
                        break;
                        break;
-               case 'k':
-                       kvalue = 1;
+               case 'h':
+                       ftsoptions &= ~FTS_PHYSICAL;
+                       ftsoptions |= FTS_LOGICAL;
                        break;
                case 's':
                        break;
                case 's':
-                       listfiles = listdirs = 0;
+                       sflag = 1;
                        break;
                case 'x':
                        ftsoptions |= FTS_XDEV;
                        break;
                case '?':
                default:
                        break;
                case 'x':
                        ftsoptions |= FTS_XDEV;
                        break;
                case '?':
                default:
-                       (void)fprintf(stderr,
-                           "usage: du [-aksx] [name ...]\n");
-                       exit(1);
+                       usage();
                }
        argv += optind;
 
                }
        argv += optind;
 
+       if (aflag) {
+               if (sflag)
+                       usage();
+               listdirs = listfiles = 1;
+       } else if (sflag)
+               listdirs = listfiles = 0;
+       else {
+               listfiles = 0;
+               listdirs = 1;
+       }
+
        if (!*argv) {
                argv = save;
                argv[0] = ".";
                argv[1] = NULL;
        }
 
        if (!*argv) {
                argv = save;
                argv[0] = ".";
                argv[1] = NULL;
        }
 
-       if (!(fts = fts_open(argv, ftsoptions, (int (*)())NULL))) {
-               (void)fprintf(stderr, "du: %s.\n", strerror(errno));
-               exit(1);
-       }
+       (void)getbsize("du", &notused, &blocksize);
+       blocksize /= 512;
+
+       if ((fts = fts_open(argv, ftsoptions, NULL)) == NULL)
+               err(1, "");
 
        while (p = fts_read(fts))
                switch(p->fts_info) {
 
        while (p = fts_read(fts))
                switch(p->fts_info) {
@@ -81,36 +101,37 @@ main(argc, argv)
                        break;
                case FTS_DP:
                        p->fts_parent->fts_number += 
                        break;
                case FTS_DP:
                        p->fts_parent->fts_number += 
-                           p->fts_number += p->fts_statb.st_blocks;
+                           p->fts_number += p->fts_statp->st_blocks;
                        /*
                         * If listing each directory, or not listing files
                         * or directories and this is post-order of the
                         * root of a traversal, display the total.
                         */
                        if (listdirs || !listfiles && !p->fts_level)
                        /*
                         * If listing each directory, or not listing files
                         * or directories and this is post-order of the
                         * root of a traversal, display the total.
                         */
                        if (listdirs || !listfiles && !p->fts_level)
-                               (void)printf("%ld\t%s\n", kvalue ?
-                                   howmany(p->fts_number, 2) :
-                                   p->fts_number, p->fts_path);
+                               (void)printf("%ld\t%s\n",
+                                   howmany(p->fts_number, blocksize),
+                                   p->fts_path);
                        break;
                case FTS_DNR:
                case FTS_ERR:
                case FTS_NS:
                        break;
                case FTS_DNR:
                case FTS_ERR:
                case FTS_NS:
-                       (void)fprintf(stderr,
-                           "du: %s: %s.\n", p->fts_path, strerror(errno));
+                       warn("%s", p->fts_path);
                        break;
                default:
                        break;
                default:
-                       if (p->fts_statb.st_nlink > 1 && linkchk(p))
+                       if (p->fts_statp->st_nlink > 1 && linkchk(p))
                                break;
                        /*
                         * If listing each file, or a non-directory file was
                         * the root of a traversal, display the total.
                         */
                        if (listfiles || !p->fts_level)
                                break;
                        /*
                         * If listing each file, or a non-directory file was
                         * the root of a traversal, display the total.
                         */
                        if (listfiles || !p->fts_level)
-                               (void)printf("%ld\t%s\n", kvalue ?
-                                   howmany(p->fts_statb.st_blocks, 2) :
-                                   p->fts_statb.st_blocks, p->fts_path);
-                       p->fts_parent->fts_number += p->fts_statb.st_blocks;
+                               (void)printf("%qd\t%s\n",
+                                   howmany(p->fts_statp->st_blocks, blocksize),
+                                   p->fts_path);
+                       p->fts_parent->fts_number += p->fts_statp->st_blocks;
                }
                }
+       if (errno)
+               err(1, "");
        exit(0);
 }
 
        exit(0);
 }
 
@@ -119,6 +140,7 @@ typedef struct _ID {
        ino_t   inode;
 } ID;
 
        ino_t   inode;
 } ID;
 
+int
 linkchk(p)
        register FTSENT *p;
 {
 linkchk(p)
        register FTSENT *p;
 {
@@ -128,20 +150,25 @@ linkchk(p)
        register ino_t ino;
        register dev_t dev;
 
        register ino_t ino;
        register dev_t dev;
 
-       ino = p->fts_statb.st_ino;
-       dev = p->fts_statb.st_dev;
+       ino = p->fts_statp->st_ino;
+       dev = p->fts_statp->st_dev;
        if (start = files)
                for (fp = start + nfiles - 1; fp >= start; --fp)
                        if (ino == fp->inode && dev == fp->dev)
                                return(1);
 
        if (start = files)
                for (fp = start + nfiles - 1; fp >= start; --fp)
                        if (ino == fp->inode && dev == fp->dev)
                                return(1);
 
-       if (nfiles == maxfiles && !(files = (ID *)realloc((char *)files,
-           (u_int)(sizeof(ID) * (maxfiles += 128))))) {
-               (void)fprintf(stderr, "du: %s\n", strerror(errno));
-               exit(1);
-       }
+       if (nfiles == maxfiles && (files = realloc((char *)files,
+           (u_int)(sizeof(ID) * (maxfiles += 128)))) == NULL)
+               err(1, "");
        files[nfiles].inode = ino;
        files[nfiles].dev = dev;
        ++nfiles;
        return(0);
 }
        files[nfiles].inode = ino;
        files[nfiles].dev = dev;
        ++nfiles;
        return(0);
 }
+
+void
+usage()
+{
+       (void)fprintf(stderr, "usage: du [-a | -s] [-Hhx] [file ...]\n");
+       exit(1);
+}