Annotation of 43BSDReno/usr.bin/du/du.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Chris Newcomb.
                      7:  *
                      8:  * Redistribution and use in source and binary forms are permitted
                      9:  * provided that: (1) source distributions retain this entire copyright
                     10:  * notice and comment, and (2) distributions including binaries display
                     11:  * the following acknowledgement:  ``This product includes software
                     12:  * developed by the University of California, Berkeley and its contributors''
                     13:  * in the documentation or other materials provided with the distribution
                     14:  * and in all advertising materials mentioning features or use of this
                     15:  * software. Neither the name of the University nor the names of its
                     16:  * contributors may be used to endorse or promote products derived
                     17:  * from this software without specific prior written permission.
                     18:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     19:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     20:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     21:  */
                     22: 
                     23: #ifndef lint
                     24: char copyright[] =
                     25: "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
                     26:  All rights reserved.\n";
                     27: #endif /* not lint */
                     28: 
                     29: #ifndef lint
                     30: static char sccsid[] = "@(#)du.c       5.6 (Berkeley) 6/1/90";
                     31: #endif /* not lint */
                     32: 
                     33: #include <sys/param.h>
                     34: #include <sys/stat.h>
                     35: #include <dirent.h>
                     36: #include <string.h>
                     37: #include <stdio.h>
                     38: 
                     39: typedef struct _ID {
                     40:        dev_t   dev;
                     41:        ino_t   inode;
                     42: } ID;
                     43: 
                     44: ID *files;
                     45: dev_t device;
                     46: int crossmounts, kvalue, listdirs, listfiles, maxfiles, numfiles;
                     47: char path[MAXPATHLEN + 1];
                     48: 
                     49: main(argc, argv)
                     50:        int argc;
                     51:        char **argv;
                     52: {
                     53:        extern int optind, errno;
                     54:        int ch;
                     55:        char *malloc(), top[MAXPATHLEN + 1];
                     56: 
                     57:        listdirs = crossmounts = 1;
                     58:        while ((ch = getopt(argc, argv, "aksx")) != EOF)
                     59:                switch(ch) {
                     60:                case 'a':
                     61:                        listfiles = 1;
                     62:                        break;
                     63:                case 'k':
                     64:                        kvalue = 1;
                     65:                        break;
                     66:                case 's':
                     67:                        listfiles = listdirs = 0;
                     68:                        break;
                     69:                case 'x':
                     70:                        crossmounts = 0;
                     71:                        break;
                     72:                case '?':
                     73:                default:
                     74:                        (void)fprintf(stderr,
                     75:                            "usage: du [-aksx] [name ...]\n");
                     76:                        exit(1);
                     77:                }
                     78:        argv += optind;
                     79: 
                     80:        files = (ID *)malloc((u_int)(sizeof(ID) * (maxfiles = 128)));
                     81: 
                     82:        if (!*argv)
                     83:                du(".");
                     84:        else {
                     85:                if (argv[1])
                     86:                        (void)getwd(top);
                     87:                for (;;) {
                     88:                        du(*argv);
                     89:                        if (!*++argv)
                     90:                                break;
                     91:                        if (chdir(top)) {
                     92:                                (void)fprintf(stderr, "du: %s: %s\n",
                     93:                                    top, strerror(errno));
                     94:                                exit(1);
                     95:                        }
                     96:                }
                     97:        }
                     98:        exit(0);
                     99: }
                    100: 
                    101: struct stat info;
                    102: 
                    103: du(arg)
                    104:        register char *arg;
                    105: {
                    106:        extern int errno;
                    107:        u_long total, descend();
                    108: 
                    109:        if (lstat(arg, &info)) {
                    110:                (void)fprintf(stderr, "du: %s: %s\n", arg, strerror(errno));
                    111:                return;
                    112:        }
                    113:        if ((info.st_mode&S_IFMT) != S_IFDIR) {
                    114:                (void)printf("%ld\t%s\n", kvalue ?
                    115:                    howmany(info.st_blocks, 2) : info.st_blocks, arg);
                    116:                return;
                    117:        }
                    118:        device = info.st_dev;
                    119:        (void)strcpy(path, arg);
                    120:        total = descend(path);
                    121:        if (!listfiles && !listdirs)
                    122:                (void)printf("%lu\t%s\n",
                    123:                    kvalue ? howmany(total, 2) : total, path);
                    124: }
                    125: 
                    126: u_long
                    127: descend(endp)
                    128:        register char *endp;
                    129: {
                    130:        extern int errno;
                    131:        register DIR *dir;
                    132:        register ID *fp;
                    133:        register struct dirent *dp;
                    134:        u_long total;
                    135:        char *realloc();
                    136: 
                    137:        if (info.st_nlink > 1) {
                    138:                for (fp = files + numfiles - 1; fp >= files; --fp)
                    139:                        if (info.st_ino == fp->inode &&
                    140:                            info.st_dev == fp->dev)
                    141:                                return(0L);
                    142:                if (numfiles == maxfiles)
                    143:                        files = (ID *)realloc((char *)files,
                    144:                            (u_int)(sizeof(ID) * (maxfiles += 128)));
                    145:                files[numfiles].inode = info.st_ino;
                    146:                files[numfiles].dev = info.st_dev;
                    147:                ++numfiles;
                    148:        }
                    149:        total = info.st_blocks;
                    150:        if ((info.st_mode&S_IFMT) == S_IFDIR) {
                    151:                if (info.st_dev != device && !crossmounts)
                    152:                        return(0L);
                    153:                if (chdir(endp) || !(dir = opendir("."))) {
                    154:                        (void)fprintf(stderr, "du: %s: %s\n",
                    155:                            path, strerror(errno));
                    156:                        return(total);
                    157:                } 
                    158:                for (; *endp; ++endp);
                    159:                if (endp[-1] != '/')
                    160:                        *endp++ = '/';
                    161:                while (dp = readdir(dir)) {
                    162:                        if (dp->d_name[0] == '.' && (!dp->d_name[1] ||
                    163:                            dp->d_name[1] == '.' && !dp->d_name[2]))
                    164:                                continue;
                    165:                        bcopy(dp->d_name, endp, dp->d_namlen + 1);
                    166:                        if (lstat(dp->d_name, &info)) {
                    167:                                (void)fprintf(stderr, "du: %s: %s\n", path,
                    168:                                    strerror(errno));
                    169:                                continue;
                    170:                        }
                    171:                        total += descend(endp);
                    172:                }
                    173:                closedir(dir);
                    174:                if (chdir("..")) {
                    175:                        (void)fprintf(stderr, "du: ..: %s\n", strerror(errno));
                    176:                        exit(1);
                    177:                }
                    178:                *--endp = '\0';
                    179:                if (listdirs)
                    180:                        (void)printf("%lu\t%s\n",
                    181:                            kvalue ? howmany(total, 2) : total, path);
                    182:        }
                    183:        else if (listfiles)
                    184:                (void)printf("%lu\t%s\n",
                    185:                    kvalue ? howmany(total, 2) : total, path);
                    186:        return(total);
                    187: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.