Annotation of coherent/b/bin/df.c, revision 1.1.1.1

1.1       root        1: /*
                      2: Steve: I made changes to df.c based on the sources you posted to the
                      3: hp to erradicate OLDSTYLE. With the new headers, the old methods for
                      4: reading directories disappear forever. I have therefore changed the source
                      5: to use readdir(), opendir() and closedir().
                      6: 
                      7: I submit th is for your blessing....
                      8: bob h.
                      9:  */
                     10: /*
                     11:  * df.c
                     12:  * 7/28/93
                     13:  * Usage: df [-fitv] [directory ...] [filesystem ...]
                     14:  *    or: df [-ait] [directory ...] [filesystem ...]     (if DF_OLD is set)
                     15:  * Print information regarding the
                     16:  * remaining space available on a file system.
                     17:  * This command also considers a directory
                     18:  * to represent the filesystem.
                     19:  *
                     20:  * 4-24-92 Fixed minor bug for looking /etc/mtab table. Vlad
                     21:  */
                     22: 
                     23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <sys/filsys.h>
                     26: #include <sys/stat.h>
                     27: #include <dirent.h>
                     28: #include <mnttab.h>
                     29: #include <canon.h>
                     30: #if 1
                     31: #include <mtab.h>
                     32: #endif
                     33: 
                     34: #define        NMOUNT  64                      /* Maximum mounted file systems */
                     35: #define DIRSIZ MAXNAMLEN
                     36: 
                     37: /* New format options */
                     38: int    fflag;                          /* supress information on i-nodes */
                     39: int    vflag;                          /* Print % blocks used */
                     40: int    tflag;                          /* Print total device size */
                     41: int    iflag;                          /* Print information on i-nodes */
                     42: 
                     43: /* Old format options  - also -t and -i are valid */
                     44: int    aflag;                          /* Print for each mounted fs */
                     45: int    oflag;                          /* switch to old style */
                     46: 
                     47: char   buf[BSIZE];                     /* Basic file system reading buffer */
                     48: struct mnttab  m_tab[NMOUNT];
                     49: struct mnttab  *emtabp;
                     50: int    noarg;                          /* Was df called without any options */
                     51: 
                     52: char   *devname();
                     53: 
                     54: main(argc, argv)
                     55: int argc;
                     56: char *argv[];
                     57: {
                     58:        register char *ap;
                     59:        register int i;
                     60:        register int estat = 0;
                     61:        char *s;
                     62: 
                     63:        if ((s = getenv("DF_OLD")) != NULL && strcmp(s, "0") != 0)
                     64:                oflag++;
                     65: 
                     66:        while (argc > 1 && *argv[1] == '-') {
                     67:                for (ap = &argv[1][1]; *ap != '\0'; ap++)
                     68:                        switch (*ap) {
                     69:                        case 'a':
                     70:                                if (oflag)
                     71:                                        aflag++;
                     72:                                else
                     73:                                        usage("illegal option -a");
                     74:                                break;
                     75: 
                     76:                        case 'f':
                     77:                                if (!oflag)
                     78:                                        fflag++;
                     79:                                else
                     80:                                        usage("illegal option -f");
                     81:                                break;
                     82: 
                     83:                        case 'i':
                     84:                                iflag++;
                     85:                                break;
                     86: 
                     87:                        case 't':
                     88:                                tflag++;
                     89:                                break;
                     90: 
                     91:                        case 'v':
                     92:                                vflag++;
                     93:                                break;
                     94: 
                     95:                        default:
                     96:                                usage("illegal option");
                     97:                        }
                     98:                argc--;
                     99:                argv++;
                    100:        }
                    101: 
                    102:        if (!oflag)
                    103:        {
                    104:                if (vflag && iflag)
                    105:                        usage("Cannot use -v with -i");
                    106:                else if (vflag)
                    107:                        printf("Mount Dir      Filesystem                blocks    "
                    108:                                                 " used      free     %%used\n");
                    109:                else if (iflag)
                    110:                        printf("Mount Dir      Filesystem                 iused     i"
                    111:                                                   "free    itotal   %%iused\n");
                    112:        }
                    113:        minit();
                    114:        sync();
                    115:        if (argc < 2) {
                    116:                if (!oflag || aflag)
                    117:                        estat = dfmtab();
                    118:                else {
                    119:                        noarg = 1;
                    120:                        estat = df(".", NULL);
                    121:                 }
                    122:        } else {
                    123:                for (i = 1; i < argc; i++)
                    124:                        estat |= df(argv[i], NULL);
                    125:                if (aflag)
                    126:                        estat |= dfmtab();
                    127:        }
                    128:        exit(estat);
                    129: }
                    130: 
                    131: /*
                    132:  * Read the mount table, looking for file systems
                    133:  * to run df on.
                    134:  */
                    135: dfmtab()
                    136: {
                    137:        register struct mnttab *mp;
                    138:        int estat;
                    139:        int name[MNAMSIZ + 10];
                    140: 
                    141:        estat = 0;
                    142:        for (mp = m_tab; mp < emtabp; mp++) {
                    143:                if (mp->mt_dev[0]=='\0' || mp->mt_filsys[0]=='\0')
                    144:                        continue;
                    145:                sprintf(name, "/dev/%s", mp->mt_filsys);
                    146:                estat |= df(name, mp->mt_dev);
                    147:        }
                    148:        return (estat);
                    149: }
                    150: 
                    151: /*
                    152:  * Look at the file system
                    153:  * and find out free space.
                    154:  */
                    155: df(fs, name)
                    156: register char *fs, *name;
                    157: {
                    158:        register struct filsys *sbp;
                    159:        struct stat sb;
                    160:        int fd;
                    161:        long    btotal;
                    162:        long    bfree;
                    163:        long    itotal;
                    164:        long    ifree;
                    165:        long    percent;
                    166:        char    *nfs = fs;
                    167: 
                    168: 
                    169:        if (stat(fs, &sb) < 0) {
                    170:                cmsg("cannot stat '%s'", fs);
                    171:                return (1);
                    172:        }
                    173:        switch (sb.st_mode & S_IFMT) {
                    174:        case S_IFDIR:
                    175:        {
                    176:                if ((nfs = devname(sb.st_dev)) == NULL) {
                    177:                        cmsg("no file system device found for directory '%s'",
                    178:                            fs);
                    179:                        return (1);
                    180:                }
                    181:                if (noarg)
                    182:                        fs = nfs;
                    183:                break;
                    184:        }
                    185: 
                    186:        case S_IFBLK:
                    187:        case S_IFCHR:
                    188:                break;
                    189: 
                    190:        default:
                    191:                cmsg("unknown file type '%s'", fs);
                    192:                return (1);
                    193:        }
                    194:        if ((fd = open(nfs, 0)) < 0) {
                    195:                cmsg("cannot open '%s'", nfs);
                    196:                return (1);
                    197:        }
                    198:        lseek(fd, (long)BSIZE * SUPERI, 0);
                    199:        if (read(fd, buf, BSIZE) != BSIZE) {
                    200:                cmsg("read error on '%s'", nfs);
                    201:                close(fd);
                    202:                return (1);
                    203:        }
                    204:        close(fd);
                    205:        sbp = &buf[0];
                    206:        canf(sbp);
                    207:        if (tstf(sbp) == 0) {
                    208:                cmsg("badly formed super block on '%s'", nfs);
                    209:                return (1);
                    210:        }
                    211: 
                    212:        bfree = sbp->s_tfree;
                    213:        btotal = sbp->s_fsize - sbp->s_isize;
                    214:        itotal = (sbp->s_isize-INODEI)*INOPB;
                    215:        ifree = sbp->s_tinode;
                    216: 
                    217: 
                    218:         if (!oflag)
                    219:        {
                    220:                printf("%-12s   (%-20s): ", name == NULL ? fs : name, nfs);
                    221:                if (vflag)
                    222:                {
                    223:                        percent = ((btotal - bfree) * 1000L) / btotal;
                    224:                        printf(" %7lu   %7lu   %7lu    %2ld.%1ld%%", btotal,
                    225:                              btotal - bfree, bfree, percent/10L, percent%10L);
                    226:                }
                    227:                else if (iflag)
                    228:                {
                    229:                        percent = ((itotal - ifree) * 1000L) / itotal;
                    230:                        printf(" %7lu   %7lu   %7lu    %2ld.%1ld%%",
                    231:                         itotal-ifree, ifree, itotal, percent/10L, percent%10L);
                    232:                }
                    233:                else
                    234:                 {
                    235:                        printf(" %7lu blocks", bfree);
                    236:                        if (!fflag)
                    237:                                printf("   %7lu inodes", ifree);
                    238:                        if (tflag)
                    239:                        {
                    240:                                printf("\n\t\t\t\tTotal:\t%7lu blocks", btotal);
                    241:                                if (!fflag)
                    242:                                        printf("   %7lu inodes", itotal);
                    243:                        }
                    244:                }
                    245:        }
                    246:        else
                    247:        {
                    248:                printf("%-11s", nfs);
                    249:                report(bfree, btotal);
                    250:                if (iflag)
                    251:                {
                    252:                        printf(", ");
                    253:                        report(ifree, itotal);
                    254:                }
                    255:                if (tflag)
                    256:                        printf(", %lu", sbp->s_fsize);
                    257:        }       
                    258:        printf("\n");
                    259:        return (0);
                    260: }
                    261: 
                    262: report(free, total)
                    263: long free;
                    264: long total;
                    265: {
                    266:        long percent;
                    267: 
                    268:        printf(" %6lu", free);
                    269:        percent = (free * 1000L) / total;
                    270:        printf("/%6lu = %2ld.%1ld%%", total , percent/10L, percent%10L);
                    271: }
                    272: 
                    273: /*
                    274:  * Initialise mount table
                    275:  * in memory.
                    276:  */
                    277: minit()
                    278: {
                    279:        register int fd;
                    280:        register int n;
                    281: 
                    282:        emtabp = &m_tab[0];
                    283:        if ((fd = open("/etc/mnttab", 0)) >= 0) {
                    284:                if ((n = read(fd, (char *)&m_tab[0], sizeof m_tab)) > 0)
                    285:                        emtabp = (char *)(&m_tab[0]) + n;
                    286:                close(fd);
                    287:                return;
                    288:        }
                    289: #if 1
                    290:        if ((fd = open("/etc/mtab", 0)) >= 0) {
                    291:                while (read(fd, (char *)emtabp, sizeof(struct mtab))
                    292:                                                == sizeof(struct mtab))
                    293:                        emtabp++;
                    294:                close(fd);
                    295:        }
                    296: #endif
                    297: }
                    298: 
                    299: /*
                    300:  * Return the name of the block special file
                    301:  * (in directory '/dev') which corresponds to
                    302:  * the device given in argument.
                    303:  */
                    304: char *
                    305: devname(dev)
                    306: dev_t dev;
                    307: {
                    308:        register struct dirent *n;
                    309:        DIR *fd;
                    310: 
                    311:        static char name[25];
                    312:        struct stat sb;
                    313: 
                    314:        if ((fd = opendir("/dev", 0)) < 0)
                    315:                return (NULL);
                    316:        while ( (n = readdir(fd)) != NULL ) {
                    317:                        canino(n->d_ino);
                    318:                        if (n->d_ino == 0)
                    319:                                continue;
                    320:                        strcpy(name, "/dev/");
                    321:                        strncat(name, n->d_name, DIRSIZ);
                    322:                        if (stat(name, &sb) < 0)
                    323:                                continue;
                    324:                        if ((sb.st_mode & S_IFMT) != S_IFBLK)
                    325:                                continue;
                    326:                        if (sb.st_rdev != dev)
                    327:                                continue;
                    328:                        closedir(fd);
                    329:                        return (name);
                    330:        }
                    331:        close(fd);
                    332:        return (NULL);
                    333: }
                    334: 
                    335: /*
                    336:  * Canonicalize and check superblock for consistency.
                    337:  */
                    338: canf(fp)
                    339: register struct filsys *fp;
                    340: {
                    341:        register daddr_t *dp;
                    342:        register ino_t *ip;
                    343: 
                    344:        canshort(fp->s_isize);
                    345:        candaddr(fp->s_fsize);
                    346:        canshort(fp->s_nfree);
                    347:        for (dp = &fp->s_free[0]; dp < &fp->s_free[NICFREE]; dp += 1)
                    348:                candaddr(*dp);
                    349:        canshort(fp->s_ninode);
                    350:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[NICINOD]; ip += 1)
                    351:                canino(*ip);
                    352:        candaddr(fp->s_tfree);
                    353:        canino(fp->s_tinode);
                    354: }
                    355: 
                    356: tstf(fp)
                    357: register struct filsys *fp;
                    358: {
                    359:        register daddr_t *dp;
                    360:        register ino_t *ip;
                    361:        register ino_t maxinode;
                    362: 
                    363:        maxinode = (fp->s_isize - INODEI) * INOPB + 1;
                    364:        if (fp->s_isize >= fp->s_fsize)
                    365:                return (0);
                    366:        if (fp->s_tfree < fp->s_nfree
                    367:         || fp->s_tfree >= fp->s_fsize - fp->s_isize + 1)
                    368:                return (0);
                    369:        if (fp->s_tinode < fp->s_ninode
                    370:         || fp->s_tinode >= maxinode-1)
                    371:                return (0);
                    372:        for (dp = &fp->s_free[0]; dp < &fp->s_free[fp->s_nfree]; dp += 1)
                    373:                if (*dp < fp->s_isize || *dp >= fp->s_fsize)
                    374:                        return (0);
                    375:        for (ip = &fp->s_inode[0]; ip < &fp->s_inode[fp->s_ninode]; ip += 1)
                    376:                if (*ip < 1 || *ip > maxinode)
                    377:                        return (0);
                    378:        return (1);
                    379: }
                    380: 
                    381: 
                    382: /*
                    383:  * Errors and warnings.
                    384:  */
                    385: /* VARARGS */
                    386: cerr(arg)
                    387: char *arg;
                    388: {
                    389:        fprintf(stderr, "df: %r\n", &arg);
                    390:        exit(1);
                    391: }
                    392: 
                    393: /* VARARGS */
                    394: cmsg(arg)
                    395: char *arg;
                    396: {
                    397:        fprintf(stderr, "df: %r\n", &arg);
                    398: }
                    399: 
                    400: usage(str)
                    401: char *str;
                    402: {
                    403: 
                    404:                fprintf(stderr, "df: %s\n", str);
                    405:        fprintf(stderr, "Usage: df [-%s] [directory ...] [filesystem ...]\n",
                    406:                oflag ? "ait" : "fitv");
                    407:        exit(1);
                    408: }
                    409: 
                    410: /* end of df.c */

unix.superglobalmegacorp.com

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