|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.