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

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