1: /* 2: * Copyright (c) 1980 Regents of the University of California. 3: * All rights reserved. The Berkeley software License Agreement 4: * specifies the terms and conditions for redistribution. 5: */ 6: 7: #ifndef lint 8: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)df.c 5.1 (Berkeley) 4/30/85"; 15: #endif not lint 16: 17: #include <sys/param.h> 18: #include <sys/fs.h> 19: #include <sys/stat.h> 20: #include <errno.h> 21: 22: #include <stdio.h> 23: #include <fstab.h> 24: #include <mtab.h> 25: 26: /* 27: * df 28: */ 29: struct mtab mtab[NMOUNT]; 30: char root[32]; 31: char *mpath(); 32: 33: int iflag; 34: 35: union { 36: struct fs iu_fs; 37: char dummy[SBSIZE]; 38: } sb; 39: #define sblock sb.iu_fs 40: 41: int fi; 42: daddr_t alloc(); 43: char *strcpy(); 44: 45: main(argc, argv) 46: int argc; 47: char **argv; 48: { 49: int i; 50: 51: while (argc > 1 && argv[1][0]=='-') { 52: switch (argv[1][1]) { 53: 54: case 'i': 55: iflag++; 56: break; 57: 58: default: 59: fprintf(stderr, "usage: df [ -i ] [ filsys... ]\n"); 60: exit(0); 61: } 62: argc--, argv++; 63: } 64: i = open("/etc/mtab", 0); 65: if (i >= 0) { 66: (void) read(i, (char *)mtab, sizeof (mtab)); 67: (void) close(i); 68: } 69: sync(); 70: printf("Filesystem kbytes used avail capacity"); 71: if (iflag) 72: printf(" iused ifree %%iused"); 73: printf(" Mounted on\n"); 74: if (argc <= 1) { 75: struct fstab *fsp; 76: 77: if (setfsent() == 0) 78: perror(FSTAB), exit(1); 79: while (fsp = getfsent()) { 80: if (strcmp(fsp->fs_type, FSTAB_RW) && 81: strcmp(fsp->fs_type, FSTAB_RO) && 82: strcmp(fsp->fs_type, FSTAB_RQ)) 83: continue; 84: if (root[0] == 0) 85: (void) strcpy(root, fsp->fs_spec); 86: dfree(fsp->fs_spec, 1); 87: } 88: endfsent(); 89: exit(0); 90: } 91: for (i=1; i<argc; i++) 92: dfree(argv[i], 0); 93: } 94: 95: dfree(file, infsent) 96: char *file; 97: int infsent; 98: { 99: long totalblks, availblks, avail, free, used; 100: struct stat stbuf; 101: struct fstab *fsp; 102: 103: if (stat(file, &stbuf) == 0 && 104: (stbuf.st_mode&S_IFMT) != S_IFCHR && 105: (stbuf.st_mode&S_IFMT) != S_IFBLK) { 106: if (infsent) { 107: fprintf(stderr, "%s: screwy /etc/fstab entry\n", file); 108: return; 109: } 110: setfsent(); 111: while (fsp = getfsent()) { 112: struct stat stb; 113: 114: if (stat(fsp->fs_spec, &stb) == 0 && 115: stb.st_rdev == stbuf.st_dev) { 116: file = fsp->fs_spec; 117: endfsent(); 118: goto found; 119: } 120: } 121: endfsent(); 122: fprintf(stderr, "%s: mounted on unknown device\n", file); 123: return; 124: } 125: found: 126: fi = open(file, 0); 127: if (fi < 0) { 128: perror(file); 129: return; 130: } 131: if (bread(SBLOCK, (char *)&sblock, SBSIZE) == 0) { 132: (void) close(fi); 133: return; 134: } 135: printf("%-12.12s", file); 136: totalblks = sblock.fs_dsize; 137: free = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag + 138: sblock.fs_cstotal.cs_nffree; 139: used = totalblks - free; 140: availblks = totalblks * (100 - sblock.fs_minfree) / 100; 141: avail = availblks > used ? availblks - used : 0; 142: printf("%8d%8d%8d", totalblks * sblock.fs_fsize / 1024, 143: used * sblock.fs_fsize / 1024, avail * sblock.fs_fsize / 1024); 144: printf("%6.0f%%", 145: availblks == 0 ? 0.0 : (double) used / (double) availblks * 100.0); 146: if (iflag) { 147: int inodes = sblock.fs_ncg * sblock.fs_ipg; 148: used = inodes - sblock.fs_cstotal.cs_nifree; 149: printf("%8ld%8ld%6.0f%% ", used, sblock.fs_cstotal.cs_nifree, 150: inodes == 0 ? 0.0 : (double)used / (double)inodes * 100.0); 151: } else 152: printf(" "); 153: printf(" %s\n", mpath(file)); 154: (void) close(fi); 155: } 156: 157: long lseek(); 158: 159: bread(bno, buf, cnt) 160: daddr_t bno; 161: char *buf; 162: { 163: int n; 164: extern errno; 165: 166: (void) lseek(fi, (long)(bno * DEV_BSIZE), 0); 167: if ((n=read(fi, buf, cnt)) != cnt) { 168: /* probably a dismounted disk if errno == EIO */ 169: if (errno != EIO) { 170: printf("\nread error bno = %ld\n", bno); 171: printf("count = %d; errno = %d\n", n, errno); 172: } 173: return (0); 174: } 175: return (1); 176: } 177: 178: /* 179: * Given a name like /dev/rrp0h, returns the mounted path, like /usr. 180: */ 181: char * 182: mpath(file) 183: char *file; 184: { 185: register struct mtab *mp; 186: 187: if (eq(file, root)) 188: return ("/"); 189: for (mp = mtab; mp < mtab + NMOUNT; mp++) 190: if (eq(file, mp->m_dname)) 191: return (mp->m_path); 192: return ""; 193: } 194: 195: eq(f1, f2) 196: char *f1, *f2; 197: { 198: 199: if (strncmp(f1, "/dev/", 5) == 0) 200: f1 += 5; 201: if (strncmp(f2, "/dev/", 5) == 0) 202: f2 += 5; 203: if (!strcmp(f1, f2)) 204: return (1); 205: if (*f1 == 'r' && !strcmp(f1+1, f2)) 206: return (1); 207: if (*f2 == 'r' && !strcmp(f1, f2+1)) 208: return (1); 209: if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0) 210: return (1); 211: return (0); 212: }