Fix compiler warnings about static vs external declarations.
[unix-history] / bin / df / df.c
CommitLineData
d958d4cb
RG
1/*
2 * Copyright (c) UNIX System Laboratories, Inc. All or some portions
3 * of this file are derived from material licensed to the
4 * University of California by American Telephone and Telegraph Co.
5 * or UNIX System Laboratories, Inc. and are reproduced herein with
6 * the permission of UNIX System Laboratories, Inc.
7 *
8 * $Id$
9 */
15637ed4
RG
10/*
11 * Copyright (c) 1980, 1990 The Regents of the University of California.
12 * All rights reserved.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * 3. All advertising materials mentioning features or use of this software
23 * must display the following acknowledgement:
24 * This product includes software developed by the University of
25 * California, Berkeley and its contributors.
26 * 4. Neither the name of the University nor the names of its contributors
27 * may be used to endorse or promote products derived from this software
28 * without specific prior written permission.
29 *
30 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
31 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 * SUCH DAMAGE.
41 */
42
43#ifndef lint
44char copyright[] =
45"@(#) Copyright (c) 1980, 1990 The Regents of the University of California.\n\
46 All rights reserved.\n";
47#endif /* not lint */
48
49#ifndef lint
4e97a0eb 50static char sccsid[] = "@(#)df.c 5.30 (Berkeley) 4/23/92";
15637ed4
RG
51#endif /* not lint */
52
15637ed4
RG
53#include <sys/param.h>
54#include <sys/stat.h>
55#include <sys/mount.h>
4e97a0eb 56#include <errno.h>
15637ed4
RG
57#include <fcntl.h>
58#include <stdio.h>
59#include <stdlib.h>
60#include <string.h>
61#include <unistd.h>
62
4e97a0eb
NW
63int bread __P((long, char *, int));
64char *getbsize __P((char *, int *, long *));
65char *getmntpt __P((char *));
66void prtstat __P((struct statfs *, long));
67void ufs_df __P((char *, long));
68void usage __P((void));
69
ad401f1c 70int iflag, kflag, nflag;
15637ed4
RG
71struct ufs_args mdev;
72
73int
74main(argc, argv)
75 int argc;
4e97a0eb 76 char *argv[];
15637ed4 77{
15637ed4
RG
78 struct stat stbuf;
79 struct statfs statfsbuf, *mntbuf;
4e97a0eb
NW
80 long width, maxwidth, mntsize;
81 int err, ch, i;
82 char *mntpt;
15637ed4 83
ad401f1c
NW
84 iflag = kflag = nflag = 0;
85 while ((ch = getopt(argc, argv, "ikn")) != EOF)
15637ed4
RG
86 switch(ch) {
87 case 'i':
88 iflag = 1;
89 break;
ad401f1c
NW
90 case 'k':
91 kflag = 1;
92 break;
15637ed4
RG
93 case 'n':
94 nflag = 1;
95 break;
96 case '?':
97 default:
4e97a0eb 98 usage();
15637ed4
RG
99 }
100 argc -= optind;
101 argv += optind;
102
103 mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
104 maxwidth = 0;
105 for (i = 0; i < mntsize; i++) {
106 width = strlen(mntbuf[i].f_mntfromname);
107 if (width > maxwidth)
108 maxwidth = width;
109 }
110 if (!*argv) {
111 mntsize = getmntinfo(&mntbuf, (nflag ? MNT_NOWAIT : MNT_WAIT));
112 for (i = 0; i < mntsize; i++)
113 prtstat(&mntbuf[i], maxwidth);
114 exit(0);
115 }
116 for (; *argv; argv++) {
117 if (stat(*argv, &stbuf) < 0) {
118 err = errno;
119 if ((mntpt = getmntpt(*argv)) == 0) {
120 fprintf(stderr, "df: %s: %s\n", *argv,
121 strerror(err));
122 continue;
123 }
124 } else if ((stbuf.st_mode & S_IFMT) == S_IFCHR) {
125 ufs_df(*argv, maxwidth);
126 continue;
127 } else if ((stbuf.st_mode & S_IFMT) == S_IFBLK) {
128 if ((mntpt = getmntpt(*argv)) == 0) {
129 mntpt = mktemp(strdup("/tmp/df.XXXXXX"));
130 mdev.fspec = *argv;
131 if (mkdir(mntpt, DEFFILEMODE) != 0) {
132 fprintf(stderr, "df: %s: %s\n",
133 mntpt, strerror(errno));
134 continue;
135 }
136 if (mount(MOUNT_UFS, mntpt, MNT_RDONLY,
137 &mdev) != 0) {
138 ufs_df(*argv, maxwidth);
139 (void)rmdir(mntpt);
140 continue;
141 } else if (statfs(mntpt, &statfsbuf)) {
142 statfsbuf.f_mntonname[0] = '\0';
143 prtstat(&statfsbuf, maxwidth);
144 } else
145 fprintf(stderr, "df: %s: %s\n",
146 *argv, strerror(errno));
147 (void)unmount(mntpt, MNT_NOFORCE);
148 (void)rmdir(mntpt);
149 continue;
150 }
151 } else
152 mntpt = *argv;
153 /*
154 * Statfs does not take a `wait' flag, so we cannot
155 * implement nflag here.
156 */
157 if (statfs(mntpt, &statfsbuf) < 0) {
158 fprintf(stderr,
159 "df: %s: %s\n", mntpt, strerror(errno));
160 continue;
161 }
162 if (argc == 1)
163 maxwidth = strlen(statfsbuf.f_mntfromname) + 1;
164 prtstat(&statfsbuf, maxwidth);
165 }
166 return (0);
167}
168
169char *
170getmntpt(name)
171 char *name;
172{
173 long mntsize, i;
174 struct statfs *mntbuf;
175
176 mntsize = getmntinfo(&mntbuf, (nflag ? MNT_NOWAIT : MNT_WAIT));
177 for (i = 0; i < mntsize; i++) {
178 if (!strcmp(mntbuf[i].f_mntfromname, name))
179 return (mntbuf[i].f_mntonname);
180 }
181 return (0);
182}
183
184/*
185 * Print out status about a filesystem.
186 */
187void
188prtstat(sfsp, maxwidth)
189 register struct statfs *sfsp;
190 long maxwidth;
191{
4e97a0eb
NW
192 static long blocksize;
193 static int headerlen, timesthrough;
194 static char *header;
15637ed4 195 long used, availblks, inodes;
15637ed4
RG
196
197 if (maxwidth < 11)
198 maxwidth = 11;
199 if (++timesthrough == 1) {
4e97a0eb
NW
200 header = getbsize("df", &headerlen, &blocksize);
201 (void)printf("%-*.*s %s Used Avail Capacity",
202 maxwidth, maxwidth, "Filesystem", header);
15637ed4 203 if (iflag)
4e97a0eb
NW
204 (void)printf(" iused ifree %%iused");
205 (void)printf(" Mounted on\n");
15637ed4 206 }
4e97a0eb 207 (void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
15637ed4
RG
208 used = sfsp->f_blocks - sfsp->f_bfree;
209 availblks = sfsp->f_bavail + used;
4e97a0eb 210 (void)printf(" %*ld %7ld %7ld", headerlen,
96eb1fc1
SW
211 (long)((double)sfsp->f_blocks * (double)sfsp->f_fsize / (double)blocksize),
212 (long)((double)used * (double)sfsp->f_fsize / (double)blocksize),
213 (long)((double)sfsp->f_bavail * (double)sfsp->f_fsize / (double)blocksize));
4e97a0eb 214 (void)printf(" %5.0f%%",
15637ed4
RG
215 availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
216 if (iflag) {
217 inodes = sfsp->f_files;
218 used = inodes - sfsp->f_ffree;
4e97a0eb 219 (void)printf(" %7ld %7ld %5.0f%% ", used, sfsp->f_ffree,
15637ed4
RG
220 inodes == 0 ? 100.0 : (double)used / (double)inodes * 100.0);
221 } else
4e97a0eb
NW
222 (void)printf(" ");
223 (void)printf(" %s\n", sfsp->f_mntonname);
15637ed4
RG
224}
225
226/*
227 * This code constitutes the old df code for extracting
228 * information from filesystem superblocks.
229 */
230#include <ufs/fs.h>
231#include <errno.h>
232#include <fstab.h>
233
234union {
235 struct fs iu_fs;
236 char dummy[SBSIZE];
237} sb;
238#define sblock sb.iu_fs
239
240int fi;
15637ed4
RG
241
242void
243ufs_df(file, maxwidth)
244 char *file;
245 long maxwidth;
246{
15637ed4
RG
247 struct statfs statfsbuf;
248 register struct statfs *sfsp;
249 char *mntpt;
250 static int synced;
251
252 if (synced++ == 0)
253 sync();
254
255 if ((fi = open(file, O_RDONLY)) < 0) {
4e97a0eb 256 (void)fprintf(stderr, "df: %s: %s\n", file, strerror(errno));
15637ed4
RG
257 return;
258 }
259 if (bread((long)SBOFF, (char *)&sblock, SBSIZE) == 0) {
4e97a0eb 260 (void)close(fi);
15637ed4
RG
261 return;
262 }
263 sfsp = &statfsbuf;
264 sfsp->f_type = MOUNT_UFS;
265 sfsp->f_flags = 0;
4e97a0eb
NW
266 sfsp->f_bsize = sblock.fs_fsize;
267#ifdef notyet
268 sfsp->f_iosize = sblock.fs_bsize;
269#endif
15637ed4
RG
270 sfsp->f_blocks = sblock.fs_dsize;
271 sfsp->f_bfree = sblock.fs_cstotal.cs_nbfree * sblock.fs_frag +
272 sblock.fs_cstotal.cs_nffree;
273 sfsp->f_bavail = (sblock.fs_dsize * (100 - sblock.fs_minfree) / 100) -
274 (sblock.fs_dsize - sfsp->f_bfree);
275 if (sfsp->f_bavail < 0)
276 sfsp->f_bavail = 0;
277 sfsp->f_files = sblock.fs_ncg * sblock.fs_ipg;
278 sfsp->f_ffree = sblock.fs_cstotal.cs_nifree;
279 sfsp->f_fsid.val[0] = 0;
280 sfsp->f_fsid.val[1] = 0;
281 if ((mntpt = getmntpt(file)) == 0)
282 mntpt = "";
283 bcopy((caddr_t)mntpt, (caddr_t)&sfsp->f_mntonname[0], MNAMELEN);
284 bcopy((caddr_t)file, (caddr_t)&sfsp->f_mntfromname[0], MNAMELEN);
285 prtstat(sfsp, maxwidth);
286 (void) close(fi);
287}
288
15637ed4
RG
289int
290bread(off, buf, cnt)
291 long off;
292 char *buf;
293 int cnt;
294{
295 int n;
15637ed4
RG
296
297 (void) lseek(fi, off, SEEK_SET);
298 if ((n=read(fi, buf, cnt)) != cnt) {
299 /* probably a dismounted disk if errno == EIO */
300 if (errno != EIO) {
4e97a0eb
NW
301 (void)printf("\nread error off = %ld\n", off);
302 (void)printf("count = %d: %s\n", n, strerror(errno));
15637ed4
RG
303 }
304 return (0);
305 }
306 return (1);
307}
4e97a0eb
NW
308
309void
310usage()
311{
312 (void)fprintf(stderr, "usage: df [-in] [file | file_system ...]\n");
313 exit(1);
314}