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