| @@ -1,520 +1,520 @@ | | | @@ -1,520 +1,520 @@ |
1 | /* $NetBSD: df.c,v 1.92 2016/03/05 08:15:01 kamil Exp $ */ | | 1 | /* $NetBSD: df.c,v 1.93 2018/08/26 23:34:52 sevan Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1980, 1990, 1993, 1994 | | 4 | * Copyright (c) 1980, 1990, 1993, 1994 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * (c) UNIX System Laboratories, Inc. | | 6 | * (c) UNIX System Laboratories, Inc. |
7 | * All or some portions of this file are derived from material licensed | | 7 | * All or some portions of this file are derived from material licensed |
8 | * to the University of California by American Telephone and Telegraph | | 8 | * to the University of California by American Telephone and Telegraph |
9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with | | 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with |
10 | * the permission of UNIX System Laboratories, Inc. | | 10 | * the permission of UNIX System Laboratories, Inc. |
11 | * | | 11 | * |
12 | * Redistribution and use in source and binary forms, with or without | | 12 | * Redistribution and use in source and binary forms, with or without |
13 | * modification, are permitted provided that the following conditions | | 13 | * modification, are permitted provided that the following conditions |
14 | * are met: | | 14 | * are met: |
15 | * 1. Redistributions of source code must retain the above copyright | | 15 | * 1. Redistributions of source code must retain the above copyright |
16 | * notice, this list of conditions and the following disclaimer. | | 16 | * notice, this list of conditions and the following disclaimer. |
17 | * 2. Redistributions in binary form must reproduce the above copyright | | 17 | * 2. Redistributions in binary form must reproduce the above copyright |
18 | * notice, this list of conditions and the following disclaimer in the | | 18 | * notice, this list of conditions and the following disclaimer in the |
19 | * documentation and/or other materials provided with the distribution. | | 19 | * documentation and/or other materials provided with the distribution. |
20 | * 3. Neither the name of the University nor the names of its contributors | | 20 | * 3. Neither the name of the University nor the names of its contributors |
21 | * may be used to endorse or promote products derived from this software | | 21 | * may be used to endorse or promote products derived from this software |
22 | * without specific prior written permission. | | 22 | * without specific prior written permission. |
23 | * | | 23 | * |
24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | | 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | | 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
34 | * SUCH DAMAGE. | | 34 | * SUCH DAMAGE. |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | #ifndef lint | | 38 | #ifndef lint |
39 | __COPYRIGHT( | | 39 | __COPYRIGHT( |
40 | "@(#) Copyright (c) 1980, 1990, 1993, 1994\ | | 40 | "@(#) Copyright (c) 1980, 1990, 1993, 1994\ |
41 | The Regents of the University of California. All rights reserved."); | | 41 | The Regents of the University of California. All rights reserved."); |
42 | #endif /* not lint */ | | 42 | #endif /* not lint */ |
43 | | | 43 | |
44 | #ifndef lint | | 44 | #ifndef lint |
45 | #if 0 | | 45 | #if 0 |
46 | static char sccsid[] = "@(#)df.c 8.7 (Berkeley) 4/2/94"; | | 46 | static char sccsid[] = "@(#)df.c 8.7 (Berkeley) 4/2/94"; |
47 | #else | | 47 | #else |
48 | __RCSID("$NetBSD: df.c,v 1.92 2016/03/05 08:15:01 kamil Exp $"); | | 48 | __RCSID("$NetBSD: df.c,v 1.93 2018/08/26 23:34:52 sevan Exp $"); |
49 | #endif | | 49 | #endif |
50 | #endif /* not lint */ | | 50 | #endif /* not lint */ |
51 | | | 51 | |
52 | #include <sys/param.h> | | 52 | #include <sys/param.h> |
53 | #include <sys/stat.h> | | 53 | #include <sys/stat.h> |
54 | #include <sys/mount.h> | | 54 | #include <sys/mount.h> |
55 | | | 55 | |
56 | #include <assert.h> | | 56 | #include <assert.h> |
57 | #include <err.h> | | 57 | #include <err.h> |
58 | #include <errno.h> | | 58 | #include <errno.h> |
59 | #include <fcntl.h> | | 59 | #include <fcntl.h> |
60 | #include <locale.h> | | 60 | #include <locale.h> |
61 | #include <util.h> | | 61 | #include <util.h> |
62 | #include <stdio.h> | | 62 | #include <stdio.h> |
63 | #include <stdlib.h> | | 63 | #include <stdlib.h> |
64 | #include <string.h> | | 64 | #include <string.h> |
65 | #include <unistd.h> | | 65 | #include <unistd.h> |
66 | #include <util.h> | | 66 | #include <util.h> |
67 | | | 67 | |
68 | static char *getmntpt(const char *); | | 68 | static char *getmntpt(const char *); |
69 | static void prtstat(struct statvfs *, int); | | 69 | static void prtstat(struct statvfs *, int); |
70 | static int selected(const char *, size_t); | | 70 | static int selected(const char *, size_t); |
71 | static void maketypelist(char *); | | 71 | static void maketypelist(char *); |
72 | static size_t regetmntinfo(struct statvfs **, size_t); | | 72 | static size_t regetmntinfo(struct statvfs **, size_t); |
73 | __dead static void usage(void); | | 73 | __dead static void usage(void); |
74 | static void prthumanval(int64_t, const char *); | | 74 | static void prthumanval(int64_t, const char *); |
75 | static void prthuman(struct statvfs *, int64_t, int64_t); | | 75 | static void prthuman(struct statvfs *, int64_t, int64_t); |
76 | | | 76 | |
77 | static int aflag, gflag, hflag, iflag, lflag, nflag, Pflag; | | 77 | static int aflag, gflag, hflag, iflag, lflag, nflag, Pflag; |
78 | static long usize; | | 78 | static long usize; |
79 | static char **typelist; | | 79 | static char **typelist; |
80 | | | 80 | |
81 | int | | 81 | int |
82 | main(int argc, char *argv[]) | | 82 | main(int argc, char *argv[]) |
83 | { | | 83 | { |
84 | struct stat stbuf; | | 84 | struct stat stbuf; |
85 | struct statvfs *mntbuf; | | 85 | struct statvfs *mntbuf; |
86 | long mntsize; | | 86 | long mntsize; |
87 | int ch, i, maxwidth, width; | | 87 | int ch, i, maxwidth, width; |
88 | char *mntpt; | | 88 | char *mntpt; |
89 | | | 89 | |
90 | setprogname(argv[0]); | | 90 | setprogname(argv[0]); |
91 | (void)setlocale(LC_ALL, ""); | | 91 | (void)setlocale(LC_ALL, ""); |
92 | | | 92 | |
93 | while ((ch = getopt(argc, argv, "aGghiklmnPt:")) != -1) | | 93 | while ((ch = getopt(argc, argv, "aGghiklmnPt:")) != -1) |
94 | switch (ch) { | | 94 | switch (ch) { |
95 | case 'a': | | 95 | case 'a': |
96 | aflag = 1; | | 96 | aflag = 1; |
97 | break; | | 97 | break; |
98 | case 'g': | | 98 | case 'g': |
99 | hflag = 0; | | 99 | hflag = 0; |
100 | usize = 1024 * 1024 * 1024; | | 100 | usize = 1024 * 1024 * 1024; |
101 | break; | | 101 | break; |
102 | case 'G': | | 102 | case 'G': |
103 | gflag = 1; | | 103 | gflag = 1; |
104 | break; | | 104 | break; |
105 | case 'h': | | 105 | case 'h': |
106 | hflag = 1; | | 106 | hflag = 1; |
107 | usize = 0; | | 107 | usize = 0; |
108 | break; | | 108 | break; |
109 | case 'i': | | 109 | case 'i': |
110 | iflag = 1; | | 110 | iflag = 1; |
111 | break; | | 111 | break; |
112 | case 'k': | | 112 | case 'k': |
113 | hflag = 0; | | 113 | hflag = 0; |
114 | usize = 1024; | | 114 | usize = 1024; |
115 | break; | | 115 | break; |
116 | case 'l': | | 116 | case 'l': |
117 | lflag = 1; | | 117 | lflag = 1; |
118 | break; | | 118 | break; |
119 | case 'm': | | 119 | case 'm': |
120 | hflag = 0; | | 120 | hflag = 0; |
121 | usize = 1024 * 1024; | | 121 | usize = 1024 * 1024; |
122 | break; | | 122 | break; |
123 | case 'n': | | 123 | case 'n': |
124 | nflag = 1; | | 124 | nflag = 1; |
125 | break; | | 125 | break; |
126 | case 'P': | | 126 | case 'P': |
127 | Pflag = 1; | | 127 | Pflag = 1; |
128 | break; | | 128 | break; |
129 | case 't': | | 129 | case 't': |
130 | if (typelist != NULL) | | 130 | if (typelist != NULL) |
131 | errx(EXIT_FAILURE, | | 131 | errx(EXIT_FAILURE, |
132 | "only one -t option may be specified."); | | 132 | "only one -t option may be specified."); |
133 | maketypelist(optarg); | | 133 | maketypelist(optarg); |
134 | break; | | 134 | break; |
135 | case '?': | | 135 | case '?': |
136 | default: | | 136 | default: |
137 | usage(); | | 137 | usage(); |
138 | } | | 138 | } |
139 | | | 139 | |
140 | if (gflag && (Pflag || iflag)) | | 140 | if (gflag && (Pflag || iflag)) |
141 | errx(EXIT_FAILURE, | | 141 | errx(EXIT_FAILURE, |
142 | "only one of -G and -P or -i may be specified"); | | 142 | "only one of -G and -P or -i may be specified"); |
143 | if (Pflag && iflag) | | 143 | if (Pflag && iflag) |
144 | errx(EXIT_FAILURE, | | 144 | errx(EXIT_FAILURE, |
145 | "only one of -P and -i may be specified"); | | 145 | "only one of -P and -i may be specified"); |
146 | #if 0 | | 146 | #if 0 |
147 | /* | | 147 | /* |
148 | * The block size cannot be checked until after getbsize() is called. | | 148 | * The block size cannot be checked until after getbsize() is called. |
149 | */ | | 149 | */ |
150 | if (Pflag && (hflag || (usize != 1024 && usize != 512))) | | 150 | if (Pflag && (hflag || (usize != 1024 && usize != 512))) |
151 | errx(EXIT_FAILURE, | | 151 | errx(EXIT_FAILURE, |
152 | "non-standard block size incompatible with -P"); | | 152 | "non-standard block size incompatible with -P"); |
153 | #endif | | 153 | #endif |
154 | argc -= optind; | | 154 | argc -= optind; |
155 | argv += optind; | | 155 | argv += optind; |
156 | | | 156 | |
157 | mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); | | 157 | mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); |
158 | if (mntsize == 0) | | 158 | if (mntsize == 0) |
159 | err(EXIT_FAILURE, | | 159 | err(EXIT_FAILURE, |
160 | "retrieving information on mounted file systems"); | | 160 | "retrieving information on mounted file systems"); |
161 | | | 161 | |
162 | if (*argv == NULL) { | | 162 | if (*argv == NULL) { |
163 | mntsize = regetmntinfo(&mntbuf, mntsize); | | 163 | mntsize = regetmntinfo(&mntbuf, mntsize); |
164 | } else { | | 164 | } else { |
165 | if ((mntbuf = malloc(argc * sizeof(*mntbuf))) == NULL) | | 165 | if ((mntbuf = malloc(argc * sizeof(*mntbuf))) == NULL) |
166 | err(EXIT_FAILURE, "can't allocate statvfs array"); | | 166 | err(EXIT_FAILURE, "can't allocate statvfs array"); |
167 | mntsize = 0; | | 167 | mntsize = 0; |
168 | for (/*EMPTY*/; *argv != NULL; argv++) { | | 168 | for (/*EMPTY*/; *argv != NULL; argv++) { |
169 | if (stat(*argv, &stbuf) < 0) { | | 169 | if (stat(*argv, &stbuf) < 0) { |
170 | if ((mntpt = getmntpt(*argv)) == 0) { | | 170 | if ((mntpt = getmntpt(*argv)) == 0) { |
171 | warn("%s", *argv); | | 171 | warn("%s", *argv); |
172 | continue; | | 172 | continue; |
173 | } | | 173 | } |
174 | } else if (S_ISBLK(stbuf.st_mode)) { | | 174 | } else if (S_ISBLK(stbuf.st_mode)) { |
175 | if ((mntpt = getmntpt(*argv)) == 0) | | 175 | if ((mntpt = getmntpt(*argv)) == 0) |
176 | mntpt = *argv; | | 176 | mntpt = *argv; |
177 | } else | | 177 | } else |
178 | mntpt = *argv; | | 178 | mntpt = *argv; |
179 | /* | | 179 | /* |
180 | * Statfs does not take a `wait' flag, so we cannot | | 180 | * Statfs does not take a `wait' flag, so we cannot |
181 | * implement nflag here. | | 181 | * implement nflag here. |
182 | */ | | 182 | */ |
183 | if (!statvfs(mntpt, &mntbuf[mntsize])) | | 183 | if (!statvfs(mntpt, &mntbuf[mntsize])) |
184 | if (lflag && | | 184 | if (lflag && |
185 | (mntbuf[mntsize].f_flag & MNT_LOCAL) == 0) | | 185 | (mntbuf[mntsize].f_flag & MNT_LOCAL) == 0) |
186 | warnx("Warning: %s is not a local %s", | | 186 | warnx("Warning: %s is not a local %s", |
187 | *argv, "file system"); | | 187 | *argv, "file system"); |
188 | else if | | 188 | else if |
189 | (!selected(mntbuf[mntsize].f_fstypename, | | 189 | (!selected(mntbuf[mntsize].f_fstypename, |
190 | sizeof(mntbuf[mntsize].f_fstypename))) | | 190 | sizeof(mntbuf[mntsize].f_fstypename))) |
191 | warnx("Warning: %s mounted as a %s %s", | | 191 | warnx("Warning: %s mounted as a %s %s", |
192 | *argv, | | 192 | *argv, |
193 | mntbuf[mntsize].f_fstypename, | | 193 | mntbuf[mntsize].f_fstypename, |
194 | "file system"); | | 194 | "file system"); |
195 | else | | 195 | else |
196 | ++mntsize; | | 196 | ++mntsize; |
197 | else | | 197 | else |
198 | warn("%s", *argv); | | 198 | warn("%s", *argv); |
199 | } | | 199 | } |
200 | } | | 200 | } |
201 | | | 201 | |
202 | maxwidth = 0; | | 202 | maxwidth = 0; |
203 | for (i = 0; i < mntsize; i++) { | | 203 | for (i = 0; i < mntsize; i++) { |
204 | width = (int)strlen(mntbuf[i].f_mntfromname); | | 204 | width = (int)strlen(mntbuf[i].f_mntfromname); |
205 | if (width > maxwidth) | | 205 | if (width > maxwidth) |
206 | maxwidth = width; | | 206 | maxwidth = width; |
207 | } | | 207 | } |
208 | for (i = 0; i < mntsize; i++) | | 208 | for (i = 0; i < mntsize; i++) |
209 | prtstat(&mntbuf[i], maxwidth); | | 209 | prtstat(&mntbuf[i], maxwidth); |
210 | return 0; | | 210 | return 0; |
211 | } | | 211 | } |
212 | | | 212 | |
213 | static char * | | 213 | static char * |
214 | getmntpt(const char *name) | | 214 | getmntpt(const char *name) |
215 | { | | 215 | { |
216 | size_t mntsize, i; | | 216 | size_t mntsize, i; |
217 | struct statvfs *mntbuf; | | 217 | struct statvfs *mntbuf; |
218 | | | 218 | |
219 | mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); | | 219 | mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); |
220 | if (mntsize == 0) | | 220 | if (mntsize == 0) |
221 | err(EXIT_FAILURE, "Can't get mount information"); | | 221 | err(EXIT_FAILURE, "Can't get mount information"); |
222 | for (i = 0; i < mntsize; i++) { | | 222 | for (i = 0; i < mntsize; i++) { |
223 | if (!strcmp(mntbuf[i].f_mntfromname, name)) | | 223 | if (!strcmp(mntbuf[i].f_mntfromname, name)) |
224 | return mntbuf[i].f_mntonname; | | 224 | return mntbuf[i].f_mntonname; |
225 | } | | 225 | } |
226 | return 0; | | 226 | return 0; |
227 | } | | 227 | } |
228 | | | 228 | |
229 | static enum { IN_LIST, NOT_IN_LIST } which; | | 229 | static enum { IN_LIST, NOT_IN_LIST } which; |
230 | | | 230 | |
231 | static int | | 231 | static int |
232 | selected(const char *type, size_t len) | | 232 | selected(const char *type, size_t len) |
233 | { | | 233 | { |
234 | char **av; | | 234 | char **av; |
235 | | | 235 | |
236 | /* If no type specified, it's always selected. */ | | 236 | /* If no type specified, it's always selected. */ |
237 | if (typelist == NULL) | | 237 | if (typelist == NULL) |
238 | return 1; | | 238 | return 1; |
239 | for (av = typelist; *av != NULL; ++av) | | 239 | for (av = typelist; *av != NULL; ++av) |
240 | if (!strncmp(type, *av, len)) | | 240 | if (!strncmp(type, *av, len)) |
241 | return which == IN_LIST ? 1 : 0; | | 241 | return which == IN_LIST ? 1 : 0; |
242 | return which == IN_LIST ? 0 : 1; | | 242 | return which == IN_LIST ? 0 : 1; |
243 | } | | 243 | } |
244 | | | 244 | |
245 | static void | | 245 | static void |
246 | maketypelist(char *fslist) | | 246 | maketypelist(char *fslist) |
247 | { | | 247 | { |
248 | size_t i; | | 248 | size_t i; |
249 | char *nextcp, **av; | | 249 | char *nextcp, **av; |
250 | | | 250 | |
251 | if ((fslist == NULL) || (fslist[0] == '\0')) | | 251 | if ((fslist == NULL) || (fslist[0] == '\0')) |
252 | errx(EXIT_FAILURE, "empty type list"); | | 252 | errx(EXIT_FAILURE, "empty type list"); |
253 | | | 253 | |
254 | /* | | 254 | /* |
255 | * XXX | | 255 | * XXX |
256 | * Note: the syntax is "noxxx,yyy" for no xxx's and | | 256 | * Note: the syntax is "noxxx,yyy" for no xxx's and |
257 | * no yyy's, not the more intuitive "noyyy,noyyy". | | 257 | * no yyy's, not the more intuitive "noyyy,noyyy". |
258 | */ | | 258 | */ |
259 | if (fslist[0] == 'n' && fslist[1] == 'o') { | | 259 | if (fslist[0] == 'n' && fslist[1] == 'o') { |
260 | fslist += 2; | | 260 | fslist += 2; |
261 | which = NOT_IN_LIST; | | 261 | which = NOT_IN_LIST; |
262 | } else | | 262 | } else |
263 | which = IN_LIST; | | 263 | which = IN_LIST; |
264 | | | 264 | |
265 | /* Count the number of types. */ | | 265 | /* Count the number of types. */ |
266 | for (i = 1, nextcp = fslist; | | 266 | for (i = 1, nextcp = fslist; |
267 | (nextcp = strchr(nextcp, ',')) != NULL; i++) | | 267 | (nextcp = strchr(nextcp, ',')) != NULL; i++) |
268 | ++nextcp; | | 268 | ++nextcp; |
269 | | | 269 | |
270 | /* Build an array of that many types. */ | | 270 | /* Build an array of that many types. */ |
271 | if ((av = typelist = malloc((i + 1) * sizeof(*av))) == NULL) | | 271 | if ((av = typelist = malloc((i + 1) * sizeof(*av))) == NULL) |
272 | err(EXIT_FAILURE, "can't allocate type array"); | | 272 | err(EXIT_FAILURE, "can't allocate type array"); |
273 | av[0] = fslist; | | 273 | av[0] = fslist; |
274 | for (i = 1, nextcp = fslist; | | 274 | for (i = 1, nextcp = fslist; |
275 | (nextcp = strchr(nextcp, ',')) != NULL; i++) { | | 275 | (nextcp = strchr(nextcp, ',')) != NULL; i++) { |
276 | *nextcp = '\0'; | | 276 | *nextcp = '\0'; |
277 | av[i] = ++nextcp; | | 277 | av[i] = ++nextcp; |
278 | } | | 278 | } |
279 | /* Terminate the array. */ | | 279 | /* Terminate the array. */ |
280 | av[i] = NULL; | | 280 | av[i] = NULL; |
281 | } | | 281 | } |
282 | | | 282 | |
283 | /* | | 283 | /* |
284 | * Make a pass over the filesystem info in ``mntbuf'' filtering out | | 284 | * Make a pass over the filesystem info in ``mntbuf'' filtering out |
285 | * filesystem types not in ``fsmask'' and possibly re-stating to get | | 285 | * filesystem types not in ``fsmask'' and possibly re-stating to get |
286 | * current (not cached) info. Returns the new count of valid statvfs bufs. | | 286 | * current (not cached) info. Returns the new count of valid statvfs bufs. |
287 | */ | | 287 | */ |
288 | static size_t | | 288 | static size_t |
289 | regetmntinfo(struct statvfs **mntbufp, size_t mntsize) | | 289 | regetmntinfo(struct statvfs **mntbufp, size_t mntsize) |
290 | { | | 290 | { |
291 | size_t i, j; | | 291 | size_t i, j; |
292 | struct statvfs *mntbuf; | | 292 | struct statvfs *mntbuf; |
293 | | | 293 | |
294 | if (!lflag && typelist == NULL && aflag) | | 294 | if (!lflag && typelist == NULL && aflag) |
295 | return nflag ? mntsize : (size_t)getmntinfo(mntbufp, MNT_WAIT); | | 295 | return nflag ? mntsize : (size_t)getmntinfo(mntbufp, MNT_WAIT); |
296 | | | 296 | |
297 | mntbuf = *mntbufp; | | 297 | mntbuf = *mntbufp; |
298 | j = 0; | | 298 | j = 0; |
299 | for (i = 0; i < mntsize; i++) { | | 299 | for (i = 0; i < mntsize; i++) { |
300 | if (!aflag && (mntbuf[i].f_flag & MNT_IGNORE) != 0) | | 300 | if (!aflag && (mntbuf[i].f_flag & MNT_IGNORE) != 0) |
301 | continue; | | 301 | continue; |
302 | if (lflag && (mntbuf[i].f_flag & MNT_LOCAL) == 0) | | 302 | if (lflag && (mntbuf[i].f_flag & MNT_LOCAL) == 0) |
303 | continue; | | 303 | continue; |
304 | if (!selected(mntbuf[i].f_fstypename, | | 304 | if (!selected(mntbuf[i].f_fstypename, |
305 | sizeof(mntbuf[i].f_fstypename))) | | 305 | sizeof(mntbuf[i].f_fstypename))) |
306 | continue; | | 306 | continue; |
307 | if (nflag) | | 307 | if (nflag) |
308 | mntbuf[j] = mntbuf[i]; | | 308 | mntbuf[j] = mntbuf[i]; |
309 | else { | | 309 | else { |
310 | struct statvfs layerbuf = mntbuf[i]; | | 310 | struct statvfs layerbuf = mntbuf[i]; |
311 | (void)statvfs(mntbuf[i].f_mntonname, &mntbuf[j]); | | 311 | (void)statvfs(mntbuf[i].f_mntonname, &mntbuf[j]); |
312 | /* | | 312 | /* |
313 | * If the FS name changed, then new data is for | | 313 | * If the FS name changed, then new data is for |
314 | * a different layer and we don't want it. | | 314 | * a different layer and we don't want it. |
315 | */ | | 315 | */ |
316 | if (memcmp(layerbuf.f_mntfromname, | | 316 | if (memcmp(layerbuf.f_mntfromname, |
317 | mntbuf[j].f_mntfromname, MNAMELEN)) | | 317 | mntbuf[j].f_mntfromname, MNAMELEN)) |
318 | mntbuf[j] = layerbuf; | | 318 | mntbuf[j] = layerbuf; |
319 | } | | 319 | } |
320 | j++; | | 320 | j++; |
321 | } | | 321 | } |
322 | return j; | | 322 | return j; |
323 | } | | 323 | } |
324 | | | 324 | |
325 | static void | | 325 | static void |
326 | prthumanval(int64_t bytes, const char *pad) | | 326 | prthumanval(int64_t bytes, const char *pad) |
327 | { | | 327 | { |
328 | char buf[6]; | | 328 | char buf[6]; |
329 | | | 329 | |
330 | (void)humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), | | 330 | (void)humanize_number(buf, sizeof(buf) - (bytes < 0 ? 0 : 1), |
331 | bytes, "", HN_AUTOSCALE, | | 331 | bytes, "", HN_AUTOSCALE, |
332 | HN_B | HN_NOSPACE | HN_DECIMAL); | | 332 | HN_B | HN_NOSPACE | HN_DECIMAL); |
333 | | | 333 | |
334 | (void)printf("%s %6s", pad, buf); | | 334 | (void)printf("%s %6s", pad, buf); |
335 | } | | 335 | } |
336 | | | 336 | |
337 | static void | | 337 | static void |
338 | prthuman(struct statvfs *sfsp, int64_t used, int64_t bavail) | | 338 | prthuman(struct statvfs *sfsp, int64_t used, int64_t bavail) |
339 | { | | 339 | { |
340 | | | 340 | |
341 | prthumanval((int64_t)(sfsp->f_blocks * sfsp->f_frsize), " "); | | 341 | prthumanval((int64_t)(sfsp->f_blocks * sfsp->f_frsize), " "); |
342 | prthumanval((int64_t)(used * sfsp->f_frsize), " "); | | 342 | prthumanval((int64_t)(used * sfsp->f_frsize), " "); |
343 | prthumanval((int64_t)(bavail * sfsp->f_frsize), " "); | | 343 | prthumanval((int64_t)(bavail * sfsp->f_frsize), " "); |
344 | } | | 344 | } |
345 | | | 345 | |
346 | /* | | 346 | /* |
347 | * Convert statvfs returned filesystem size into BLOCKSIZE units. | | 347 | * Convert statvfs returned filesystem size into BLOCKSIZE units. |
348 | * Attempts to avoid overflow for large filesystems. | | 348 | * Attempts to avoid overflow for large filesystems. |
349 | */ | | 349 | */ |
350 | #define fsbtoblk(num, fsbs, bs) \ | | 350 | #define fsbtoblk(num, fsbs, bs) \ |
351 | (((fsbs) != 0 && (uint64_t)(fsbs) < (uint64_t)(bs)) ? \ | | 351 | (((fsbs) != 0 && (uint64_t)(fsbs) < (uint64_t)(bs)) ? \ |
352 | (int64_t)(num) / (int64_t)((bs) / (fsbs)) : \ | | 352 | (int64_t)(num) / (int64_t)((bs) / (fsbs)) : \ |
353 | (int64_t)(num) * (int64_t)((fsbs) / (bs))) | | 353 | (int64_t)(num) * (int64_t)((fsbs) / (bs))) |
354 | | | 354 | |
355 | /* | | 355 | /* |
356 | * Print out status about a filesystem. | | 356 | * Print out status about a filesystem. |
357 | */ | | 357 | */ |
358 | static void | | 358 | static void |
359 | prtstat(struct statvfs *sfsp, int maxwidth) | | 359 | prtstat(struct statvfs *sfsp, int maxwidth) |
360 | { | | 360 | { |
361 | static long blocksize; | | 361 | static long blocksize; |
362 | static int headerlen, timesthrough; | | 362 | static int headerlen, timesthrough; |
363 | static const char *header; | | 363 | static const char *header; |
364 | static const char full[] = "100"; | | 364 | static const char full[] = "100"; |
365 | static const char empty[] = " 0"; | | 365 | static const char empty[] = " 0"; |
366 | int64_t used, availblks, inodes; | | 366 | int64_t used, availblks, inodes; |
367 | int64_t bavail; | | 367 | int64_t bavail; |
368 | char pb[64]; | | 368 | char pb[64]; |
369 | | | 369 | |
370 | if (gflag) { | | 370 | if (gflag) { |
371 | /* | | 371 | /* |
372 | * From SunOS-5.6: | | 372 | * From SunOS-5.6: |
373 | * | | 373 | * |
374 | * /var (/dev/dsk/c0t0d0s3 ): 8192 block size 1024 frag size | | 374 | * /var (/dev/dsk/c0t0d0s3 ): 8192 block size 1024 frag size |
375 | * 984242 total blocks 860692 free blocks 859708 available 249984 total files | | 375 | * 984242 total blocks 860692 free blocks 859708 available 249984 total files |
376 | * 248691 free files 8388611 filesys id | | 376 | * 248691 free files 8388611 filesys id |
377 | * ufs fstype 0x00000004 flag 255 filename length | | 377 | * ufs fstype 0x00000004 flag 255 filename length |
378 | * | | 378 | * |
379 | */ | | 379 | */ |
380 | (void)printf("%10s (%-12s): %7ld block size %12ld frag size\n", | | 380 | (void)printf("%10s (%-12s): %7ld block size %12ld frag size\n", |
381 | sfsp->f_mntonname, sfsp->f_mntfromname, | | 381 | sfsp->f_mntonname, sfsp->f_mntfromname, |
382 | sfsp->f_bsize, /* On UFS/FFS systems this is | | 382 | sfsp->f_bsize, /* On UFS/FFS systems this is |
383 | * also called the "optimal | | 383 | * also called the "optimal |
384 | * transfer block size" but it | | 384 | * transfer block size" but it |
385 | * is of course the file | | 385 | * is of course the file |
386 | * system's block size too. | | 386 | * system's block size too. |
387 | */ | | 387 | */ |
388 | sfsp->f_frsize); /* not so surprisingly the | | 388 | sfsp->f_frsize); /* not so surprisingly the |
389 | * "fundamental file system | | 389 | * "fundamental file system |
390 | * block size" is the frag | | 390 | * block size" is the frag |
391 | * size. | | 391 | * size. |
392 | */ | | 392 | */ |
393 | (void)printf("%10" PRId64 " total blocks %10" PRId64 | | 393 | (void)printf("%10" PRId64 " total blocks %10" PRId64 |
394 | " free blocks %10" PRId64 " available\n", | | 394 | " free blocks %10" PRId64 " available\n", |
395 | (uint64_t)sfsp->f_blocks, (uint64_t)sfsp->f_bfree, | | 395 | (uint64_t)sfsp->f_blocks, (uint64_t)sfsp->f_bfree, |
396 | (uint64_t)sfsp->f_bavail); | | 396 | (uint64_t)sfsp->f_bavail); |
397 | (void)printf("%10" PRId64 " total files %10" PRId64 | | 397 | (void)printf("%10" PRId64 " total files %10" PRId64 |
398 | " free files %12lx filesys id\n", | | 398 | " free files %12lx filesys id\n", |
399 | (uint64_t)sfsp->f_ffree, (uint64_t)sfsp->f_files, | | 399 | (uint64_t)sfsp->f_ffree, (uint64_t)sfsp->f_files, |
400 | sfsp->f_fsid); | | 400 | sfsp->f_fsid); |
401 | (void)printf("%10s fstype %#15lx flag %17ld filename " | | 401 | (void)printf("%10s fstype %#15lx flag %17ld filename " |
402 | "length\n", sfsp->f_fstypename, sfsp->f_flag, | | 402 | "length\n", sfsp->f_fstypename, sfsp->f_flag, |
403 | sfsp->f_namemax); | | 403 | sfsp->f_namemax); |
404 | (void)printf("%10lu owner %17" PRId64 " syncwrites %12" PRId64 | | 404 | (void)printf("%10lu owner %17" PRId64 " syncwrites %12" PRId64 |
405 | " asyncwrites\n\n", (unsigned long)sfsp->f_owner, | | 405 | " asyncwrites\n\n", (unsigned long)sfsp->f_owner, |
406 | sfsp->f_syncwrites, sfsp->f_asyncwrites); | | 406 | sfsp->f_syncwrites, sfsp->f_asyncwrites); |
407 | | | 407 | |
408 | /* | | 408 | /* |
409 | * a concession by the structured programming police to the | | 409 | * a concession by the structured programming police to the |
410 | * indentation police.... | | 410 | * indentation police.... |
411 | */ | | 411 | */ |
412 | return; | | 412 | return; |
413 | } | | 413 | } |
414 | if (maxwidth < 12) | | 414 | if (maxwidth < 12) |
415 | maxwidth = 12; | | 415 | maxwidth = 12; |
416 | if (++timesthrough == 1) { | | 416 | if (++timesthrough == 1) { |
417 | switch (blocksize = usize) { | | 417 | switch (blocksize = usize) { |
418 | case 1024: | | 418 | case 1024: |
419 | header = Pflag ? "1024-blocks" : "1K-blocks"; | | 419 | header = Pflag ? "1024-blocks" : "1K-blocks"; |
420 | headerlen = (int)strlen(header); | | 420 | headerlen = (int)strlen(header); |
421 | break; | | 421 | break; |
422 | case 1024 * 1024: | | 422 | case 1024 * 1024: |
423 | header = "1M-blocks"; | | 423 | header = "1M-blocks"; |
424 | headerlen = (int)strlen(header); | | 424 | headerlen = (int)strlen(header); |
425 | break; | | 425 | break; |
426 | case 1024 * 1024 * 1024: | | 426 | case 1024 * 1024 * 1024: |
427 | header = "1G-blocks"; | | 427 | header = "1G-blocks"; |
428 | headerlen = (int)strlen(header); | | 428 | headerlen = (int)strlen(header); |
429 | break; | | 429 | break; |
430 | default: | | 430 | default: |
431 | if (hflag) { | | 431 | if (hflag) { |
432 | header = "Size"; | | 432 | header = "Size"; |
433 | headerlen = (int)strlen(header); | | 433 | headerlen = (int)strlen(header); |
434 | } else | | 434 | } else |
435 | header = getbsize(&headerlen, &blocksize); | | 435 | header = getbsize(&headerlen, &blocksize); |
436 | break; | | 436 | break; |
437 | } | | 437 | } |
438 | if (Pflag) { | | 438 | if (Pflag) { |
439 | /* | | 439 | /* |
440 | * either: | | 440 | * either: |
441 | * "Filesystem 1024-blocks Used Available Capacity Mounted on\n" | | 441 | * "Filesystem 1024-blocks Used Available Capacity Mounted on\n" |
442 | * or: | | 442 | * or: |
443 | * "Filesystem 512-blocks Used Available Capacity Mounted on\n" | | 443 | * "Filesystem 512-blocks Used Available Capacity Mounted on\n" |
444 | */ | | 444 | */ |
445 | if (blocksize != 1024 && blocksize != 512) | | 445 | if (blocksize != 1024 && blocksize != 512) |
446 | errx(EXIT_FAILURE, | | 446 | errx(EXIT_FAILURE, |
447 | "non-standard block size incompatible with -P"); | | 447 | "non-standard block size incompatible with -P"); |
448 | (void)printf("Filesystem %s Used Available Capacity " | | 448 | (void)printf("Filesystem %s Used Available Capacity " |
449 | "Mounted on\n", header); | | 449 | "Mounted on\n", header); |
450 | } else { | | 450 | } else { |
451 | (void)printf("%-*.*s %s Used Avail %%Cap", | | 451 | (void)printf("%-*.*s %s Used Avail %%Cap", |
452 | maxwidth - (headerlen - 10), | | 452 | maxwidth - (headerlen - 10), |
453 | maxwidth - (headerlen - 10), | | 453 | maxwidth - (headerlen - 10), |
454 | "Filesystem", header); | | 454 | "Filesystem", header); |
455 | if (iflag) | | 455 | if (iflag) |
456 | (void)printf(" iUsed iAvail %%iCap"); | | 456 | (void)printf(" iUsed iAvail %%iCap"); |
457 | (void)printf(" Mounted on\n"); | | 457 | (void)printf(" Mounted on\n"); |
458 | } | | 458 | } |
459 | } | | 459 | } |
460 | used = sfsp->f_blocks - sfsp->f_bfree; | | 460 | used = sfsp->f_blocks - sfsp->f_bfree; |
461 | bavail = sfsp->f_bfree - sfsp->f_bresvd; | | 461 | bavail = sfsp->f_bfree - sfsp->f_bresvd; |
462 | availblks = bavail + used; | | 462 | availblks = bavail + used; |
463 | if (Pflag) { | | 463 | if (Pflag) { |
464 | assert(hflag == 0); | | 464 | assert(hflag == 0); |
465 | assert(blocksize > 0); | | 465 | assert(blocksize > 0); |
466 | /* | | 466 | /* |
467 | * "%s %d %d %d %s %s\n", <file system name>, <total space>, | | 467 | * "%s %d %d %d %s %s\n", <file system name>, <total space>, |
468 | * <space used>, <space free>, <percentage used>, | | 468 | * <space used>, <space free>, <percentage used>, |
469 | * <file system root> | | 469 | * <file system root> |
470 | */ | | 470 | */ |
471 | (void)printf("%s %" PRId64 " %" PRId64 " %" PRId64 " %s%% %s\n", | | 471 | (void)printf("%s %" PRId64 " %" PRId64 " %" PRId64 " %s%% %s\n", |
472 | sfsp->f_mntfromname, | | 472 | sfsp->f_mntfromname, |
473 | fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize), | | 473 | fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize), |
474 | fsbtoblk(used, sfsp->f_frsize, blocksize), | | 474 | fsbtoblk(used, sfsp->f_frsize, blocksize), |
475 | fsbtoblk(bavail, sfsp->f_frsize, blocksize), | | 475 | fsbtoblk(bavail, sfsp->f_frsize, blocksize), |
476 | availblks == 0 ? full : strspct(pb, sizeof(pb), used, | | 476 | availblks == 0 ? full : strspct(pb, sizeof(pb), used, |
477 | availblks, 0), sfsp->f_mntonname); | | 477 | availblks, 0), sfsp->f_mntonname); |
478 | /* | | 478 | /* |
479 | * another concession by the structured programming police to | | 479 | * another concession by the structured programming police to |
480 | * the indentation police.... | | 480 | * the indentation police.... |
481 | * | | 481 | * |
482 | * Note iflag cannot be set when Pflag is set. | | 482 | * Note iflag cannot be set when Pflag is set. |
483 | */ | | 483 | */ |
484 | return; | | 484 | return; |
485 | } | | 485 | } |
486 | | | 486 | |
487 | (void)printf("%-*.*s ", maxwidth, maxwidth, sfsp->f_mntfromname); | | 487 | (void)printf("%-*.*s ", maxwidth, maxwidth, sfsp->f_mntfromname); |
488 | | | 488 | |
489 | if (hflag) | | 489 | if (hflag) |
490 | prthuman(sfsp, used, bavail); | | 490 | prthuman(sfsp, used, bavail); |
491 | else | | 491 | else |
492 | (void)printf("%10" PRId64 " %10" PRId64 " %10" PRId64, | | 492 | (void)printf("%10" PRId64 " %10" PRId64 " %10" PRId64, |
493 | fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize), | | 493 | fsbtoblk(sfsp->f_blocks, sfsp->f_frsize, blocksize), |
494 | fsbtoblk(used, sfsp->f_frsize, blocksize), | | 494 | fsbtoblk(used, sfsp->f_frsize, blocksize), |
495 | fsbtoblk(bavail, sfsp->f_frsize, blocksize)); | | 495 | fsbtoblk(bavail, sfsp->f_frsize, blocksize)); |
496 | (void)printf(" %3s%%", | | 496 | (void)printf(" %3s%%", |
497 | availblks == 0 ? full : | | 497 | availblks == 0 ? full : |
498 | strspct(pb, sizeof(pb), used, availblks, 0)); | | 498 | strspct(pb, sizeof(pb), used, availblks, 0)); |
499 | if (iflag) { | | 499 | if (iflag) { |
500 | inodes = sfsp->f_files; | | 500 | inodes = sfsp->f_files; |
501 | used = inodes - sfsp->f_ffree; | | 501 | used = inodes - sfsp->f_ffree; |
502 | (void)printf(" %8jd %8jd %4s%%", | | 502 | (void)printf(" %8jd %8jd %4s%%", |
503 | (intmax_t)used, (intmax_t)sfsp->f_ffree, | | 503 | (intmax_t)used, (intmax_t)sfsp->f_ffree, |
504 | inodes == 0 ? (used == 0 ? empty : full) : | | 504 | inodes == 0 ? (used == 0 ? empty : full) : |
505 | strspct(pb, sizeof(pb), used, inodes, 0)); | | 505 | strspct(pb, sizeof(pb), used, inodes, 0)); |
506 | } | | 506 | } |
507 | (void)printf(" %s\n", sfsp->f_mntonname); | | 507 | (void)printf(" %s\n", sfsp->f_mntonname); |
508 | } | | 508 | } |
509 | | | 509 | |
510 | static void | | 510 | static void |
511 | usage(void) | | 511 | usage(void) |
512 | { | | 512 | { |
513 | | | 513 | |
514 | (void)fprintf(stderr, | | 514 | (void)fprintf(stderr, |
515 | "Usage: %s [-aGgln] [-hkm|-ihkm|-Pk] [-t type] [file | " | | 515 | "Usage: %s [-agln] [-Ghkm|-ihkm|-Pk] [-t type] [file | " |
516 | "file_system ...]\n", | | 516 | "file_system ...]\n", |
517 | getprogname()); | | 517 | getprogname()); |
518 | exit(1); | | 518 | exit(1); |
519 | /* NOTREACHED */ | | 519 | /* NOTREACHED */ |
520 | } | | 520 | } |