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.5 (Berkeley) 05/09/89"; 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 #include <stdio.h> 22 #include <fstab.h> 23 #include <mtab.h> 24 #include "pathnames.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 extern int errno, optind; 50 int ch, i; 51 char *strerror(); 52 53 while ((ch = getopt(argc, argv, "i")) != EOF) 54 switch(ch) { 55 case 'i': 56 iflag++; 57 break; 58 case '?': 59 default: 60 fprintf(stderr, "usage: df [-i] [filsys ...]\n"); 61 exit(1); 62 } 63 argc -= optind; 64 argv += optind; 65 66 if ((i = open(_PATH_MTAB, 0)) < 0) { 67 fprintf(stderr, "df: %s: %s\n", _PATH_MTAB, strerror(errno)); 68 exit(1); 69 } 70 (void) read(i, (char *)mtab, sizeof (mtab)); 71 (void) close(i); 72 sync(); 73 printf("Filesystem kbytes used avail capacity"); 74 if (iflag) 75 printf(" iused ifree %%iused"); 76 printf(" Mounted on\n"); 77 if (!*argv) { 78 struct fstab *fsp; 79 80 if (setfsent() == 0) 81 perror(FSTAB), exit(1); 82 while (fsp = getfsent()) { 83 if (strcmp(fsp->fs_type, FSTAB_RW) && 84 strcmp(fsp->fs_type, FSTAB_RO) && 85 strcmp(fsp->fs_type, FSTAB_RQ)) 86 continue; 87 if (root[0] == 0) 88 (void) strcpy(root, fsp->fs_spec); 89 dfree(fsp->fs_spec, 1); 90 } 91 (void)endfsent(); 92 exit(0); 93 } 94 while (*argv) 95 dfree(*argv++, 0); 96 } 97 98 dfree(file, infsent) 99 char *file; 100 int infsent; 101 { 102 extern int errno; 103 long totalblks, availblks, avail, free, used; 104 struct stat stbuf; 105 struct fstab *fsp; 106 char *strerror(); 107 108 if (stat(file, &stbuf) == 0 && 109 (stbuf.st_mode&S_IFMT) != S_IFCHR && 110 (stbuf.st_mode&S_IFMT) != S_IFBLK) { 111 if (infsent) { 112 fprintf(stderr, "%s: screwy fstab entry\n", file); 113 return; 114 } 115 (void)setfsent(); 116 while (fsp = getfsent()) { 117 struct stat stb; 118 119 if (stat(fsp->fs_spec, &stb) == 0 && 120 stb.st_rdev == stbuf.st_dev) { 121 file = fsp->fs_spec; 122 (void)endfsent(); 123 goto found; 124 } 125 } 126 (void)endfsent(); 127 fprintf(stderr, "%s: mounted on unknown device\n", file); 128 return; 129 } 130 found: 131 if ((fi = open(file, 0)) < 0) { 132 fprintf(stderr, "df: %s: %s\n", file, strerror(errno)); 133 return; 134 } 135 if (bread((long)SBOFF, (char *)&sblock, SBSIZE) == 0) { 136 (void) close(fi); 137 return; 138 } 139 printf("%-12.12s", file); 140 totalblks = sblock.fs_dsize; 141 free = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag + 142 sblock.fs_cstotal.cs_nffree; 143 used = totalblks - free; 144 availblks = totalblks * (100 - sblock.fs_minfree) / 100; 145 avail = availblks > used ? availblks - used : 0; 146 printf("%8ld%8ld%8ld", totalblks * sblock.fs_fsize / 1024, 147 used * sblock.fs_fsize / 1024, avail * sblock.fs_fsize / 1024); 148 printf("%6.0f%%", 149 availblks == 0 ? 0.0 : (double) used / (double) availblks * 100.0); 150 if (iflag) { 151 int inodes = sblock.fs_ncg * sblock.fs_ipg; 152 used = inodes - sblock.fs_cstotal.cs_nifree; 153 printf("%8ld%8ld%6.0f%% ", used, sblock.fs_cstotal.cs_nifree, 154 inodes == 0 ? 0.0 : (double)used / (double)inodes * 100.0); 155 } else 156 printf(" "); 157 printf(" %s\n", mpath(file)); 158 (void) close(fi); 159 } 160 161 long lseek(); 162 163 bread(off, buf, cnt) 164 long off; 165 char *buf; 166 { 167 int n; 168 extern errno; 169 170 (void) lseek(fi, off, 0); 171 if ((n=read(fi, buf, cnt)) != cnt) { 172 /* probably a dismounted disk if errno == EIO */ 173 if (errno != EIO) { 174 printf("\nread error off = %ld\n", off); 175 printf("count = %d; errno = %d\n", n, errno); 176 } 177 return (0); 178 } 179 return (1); 180 } 181 182 /* 183 * Given a name like /dev/rrp0h, returns the mounted path, like /usr. 184 */ 185 char * 186 mpath(file) 187 char *file; 188 { 189 register struct mtab *mp; 190 191 if (eq(file, root)) 192 return ("/"); 193 for (mp = mtab; mp < mtab + NMOUNT; mp++) 194 if (eq(file, mp->m_dname)) 195 return (mp->m_path); 196 return ""; 197 } 198 199 eq(f1, f2) 200 char *f1, *f2; 201 { 202 203 if (strncmp(f1, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) 204 f1 += 5; 205 if (strncmp(f2, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) 206 f2 += 5; 207 if (!strcmp(f1, f2)) 208 return (1); 209 if (*f1 == 'r' && !strcmp(f1+1, f2)) 210 return (1); 211 if (*f2 == 'r' && !strcmp(f1, f2+1)) 212 return (1); 213 if (*f1 == 'r' && *f2 == 'r' && strcmp(f1+1, f2+1) == 0) 214 return (1); 215 return (0); 216 } 217