1 /* 2 * Copyright (c) 1980, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 char copyright[] = 10 "@(#) Copyright (c) 1980, 1990 The Regents of the University of California.\n\ 11 All rights reserved.\n"; 12 #endif /* not lint */ 13 14 #ifndef lint 15 static char sccsid[] = "@(#)df.c 5.23 (Berkeley) 02/25/91"; 16 #endif /* not lint */ 17 18 /* 19 * df 20 */ 21 #include <sys/param.h> 22 #include <sys/stat.h> 23 #include <sys/mount.h> 24 #include <fcntl.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 #include <string.h> 28 #include <unistd.h> 29 30 char *getmntpt(); 31 void ufs_df(), prtstat(); 32 int iflag, kflag, nflag; 33 struct ufs_args mdev; 34 35 int 36 main(argc, argv) 37 int argc; 38 char **argv; 39 { 40 extern int errno, optind; 41 int err, ch, i; 42 long width, maxwidth, mntsize; 43 char *mntpt, *mktemp(); 44 struct stat stbuf; 45 struct statfs statfsbuf, *mntbuf; 46 47 while ((ch = getopt(argc, argv, "ikn")) != EOF) 48 switch(ch) { 49 case 'i': 50 iflag = 1; 51 break; 52 case 'k': 53 kflag = 1; 54 break; 55 case 'n': 56 nflag = 1; 57 break; 58 case '?': 59 default: 60 fprintf(stderr, 61 "usage: df [-ikn] [file | file_system ...]\n"); 62 exit(1); 63 } 64 argc -= optind; 65 argv += optind; 66 67 mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); 68 maxwidth = 0; 69 for (i = 0; i < mntsize; i++) { 70 width = strlen(mntbuf[i].f_mntfromname); 71 if (width > maxwidth) 72 maxwidth = width; 73 } 74 if (!*argv) { 75 mntsize = getmntinfo(&mntbuf, (nflag ? MNT_NOWAIT : MNT_WAIT)); 76 for (i = 0; i < mntsize; i++) 77 prtstat(&mntbuf[i], maxwidth); 78 exit(0); 79 } 80 for (; *argv; argv++) { 81 if (stat(*argv, &stbuf) < 0) { 82 err = errno; 83 if ((mntpt = getmntpt(*argv)) == 0) { 84 fprintf(stderr, "df: %s: %s\n", *argv, 85 strerror(err)); 86 continue; 87 } 88 } else if ((stbuf.st_mode & S_IFMT) == S_IFCHR) { 89 ufs_df(*argv, maxwidth); 90 continue; 91 } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) { 92 if ((mntpt = getmntpt(*argv)) == 0) { 93 mntpt = mktemp("/tmp/df.XXXXXX"); 94 mdev.fspec = *argv; 95 if (mkdir(mntpt, DEFFILEMODE) != 0) { 96 fprintf(stderr, "df: %s: %s\n", 97 mntpt, strerror(errno)); 98 continue; 99 } 100 if (mount(MOUNT_UFS, mntpt, MNT_RDONLY, 101 &mdev) != 0) { 102 ufs_df(*argv, maxwidth); 103 (void)rmdir(mntpt); 104 continue; 105 } else if (statfs(mntpt, &statfsbuf)) { 106 statfsbuf.f_mntonname[0] = '\0'; 107 prtstat(&statfsbuf, maxwidth); 108 } else 109 fprintf(stderr, "df: %s: %s\n", 110 *argv, strerror(errno)); 111 (void)unmount(mntpt, MNT_NOFORCE); 112 (void)rmdir(mntpt); 113 continue; 114 } 115 } else 116 mntpt = *argv; 117 /* 118 * Statfs does not take a `wait' flag, so we cannot 119 * implement nflag here. 120 */ 121 if (statfs(mntpt, &statfsbuf) < 0) { 122 fprintf(stderr, 123 "df: %s: %s\n", mntpt, strerror(errno)); 124 continue; 125 } 126 if (argc == 1) 127 maxwidth = strlen(statfsbuf.f_mntfromname) + 1; 128 prtstat(&statfsbuf, maxwidth); 129 } 130 return (0); 131 } 132 133 char * 134 getmntpt(name) 135 char *name; 136 { 137 long mntsize, i; 138 struct statfs *mntbuf; 139 140 mntsize = getmntinfo(&mntbuf, (nflag ? MNT_NOWAIT : MNT_WAIT)); 141 for (i = 0; i < mntsize; i++) { 142 if (!strcmp(mntbuf[i].f_mntfromname, name)) 143 return (mntbuf[i].f_mntonname); 144 } 145 return (0); 146 } 147 148 /* 149 * Print out status about a filesystem. 150 */ 151 void 152 prtstat(sfsp, maxwidth) 153 register struct statfs *sfsp; 154 long maxwidth; 155 { 156 long used, availblks, inodes; 157 static int timesthrough; 158 159 if (maxwidth < 11) 160 maxwidth = 11; 161 if (++timesthrough == 1) { 162 printf("%-*.*s%s used avail capacity", 163 maxwidth, maxwidth, "Filesystem", 164 kflag ? " kbytes" : "512-blks"); 165 if (iflag) 166 printf(" iused ifree %%iused"); 167 printf(" Mounted on\n"); 168 } 169 printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname); 170 used = sfsp->f_blocks - sfsp->f_bfree; 171 availblks = sfsp->f_bavail + used; 172 printf("%8ld%8ld%8ld", 173 sfsp->f_blocks * sfsp->f_fsize / (kflag ? 1024 : 512), 174 used * sfsp->f_fsize / (kflag ? 1024 : 512), 175 sfsp->f_bavail * sfsp->f_fsize / (kflag ? 1024 : 512)); 176 printf("%6.0f%%", 177 availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0); 178 if (iflag) { 179 inodes = sfsp->f_files; 180 used = inodes - sfsp->f_ffree; 181 printf("%8ld%8ld%6.0f%% ", used, sfsp->f_ffree, 182 inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0); 183 } else 184 printf(" "); 185 printf(" %s\n", sfsp->f_mntonname); 186 } 187 188 /* 189 * This code constitutes the old df code for extracting 190 * information from filesystem superblocks. 191 */ 192 #include <ufs/fs.h> 193 #include <errno.h> 194 #include <fstab.h> 195 196 union { 197 struct fs iu_fs; 198 char dummy[SBSIZE]; 199 } sb; 200 #define sblock sb.iu_fs 201 202 int fi; 203 int bread(); 204 205 void 206 ufs_df(file, maxwidth) 207 char *file; 208 long maxwidth; 209 { 210 extern int errno; 211 struct statfs statfsbuf; 212 register struct statfs *sfsp; 213 char *mntpt; 214 static int synced; 215 216 if (synced++ == 0) 217 sync(); 218 219 if ((fi = open(file, O_RDONLY)) < 0) { 220 fprintf(stderr, "df: %s: %s\n", file, strerror(errno)); 221 return; 222 } 223 if (bread((long)SBOFF, (char *)&sblock, SBSIZE) == 0) { 224 (void) close(fi); 225 return; 226 } 227 sfsp = &statfsbuf; 228 sfsp->f_type = MOUNT_UFS; 229 sfsp->f_flags = 0; 230 sfsp->f_fsize = sblock.fs_fsize; 231 sfsp->f_bsize = sblock.fs_bsize; 232 sfsp->f_blocks = sblock.fs_dsize; 233 sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag + 234 sblock.fs_cstotal.cs_nffree; 235 sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) - 236 (sblock.fs_dsize - sfsp->f_bfree); 237 if (sfsp->f_bavail < 0) 238 sfsp->f_bavail = 0; 239 sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg; 240 sfsp->f_ffree = sblock.fs_cstotal.cs_nifree; 241 sfsp->f_fsid.val[0] = 0; 242 sfsp->f_fsid.val[1] = 0; 243 if ((mntpt = getmntpt(file)) == 0) 244 mntpt = ""; 245 bcopy((caddr_t)mntpt, (caddr_t)&sfsp->f_mntonname[0], MNAMELEN); 246 bcopy((caddr_t)file, (caddr_t)&sfsp->f_mntfromname[0], MNAMELEN); 247 prtstat(sfsp, maxwidth); 248 (void) close(fi); 249 } 250 251 long lseek(); 252 253 int 254 bread(off, buf, cnt) 255 long off; 256 char *buf; 257 int cnt; 258 { 259 int n; 260 extern errno; 261 262 (void) lseek(fi, off, SEEK_SET); 263 if ((n=read(fi, buf, cnt)) != cnt) { 264 /* probably a dismounted disk if errno == EIO */ 265 if (errno != EIO) { 266 printf("\nread error off = %ld\n", off); 267 printf("count = %d; errno = %d\n", n, errno); 268 } 269 return (0); 270 } 271 return (1); 272 } 273