Bug Summary

File:src/usr.sbin/pstat/pstat.c
Warning:line 411, column 8
Null pointer passed as 1st argument to string comparison function

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name pstat.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.sbin/pstat/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/pstat/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.sbin/pstat/pstat.c
1/* $OpenBSD: pstat.c,v 1.129 2022/02/22 17:35:01 deraadt Exp $ */
2/* $NetBSD: pstat.c,v 1.27 1996/10/23 22:50:06 cgd Exp $ */
3
4/*-
5 * Copyright (c) 1980, 1991, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h> /* DEV_BSIZE */
34#include <sys/types.h>
35#include <sys/signal.h>
36#include <sys/proc.h>
37#include <sys/time.h>
38#include <sys/vnode.h>
39#include <sys/ucred.h>
40#include <sys/stat.h>
41#define _KERNEL
42#include <sys/file.h>
43#include <ufs/ufs/quota.h>
44#include <ufs/ufs/inode.h>
45#include <sys/mount.h>
46#undef _KERNEL
47#include <nfs/nfsproto.h>
48#include <nfs/rpcv2.h>
49#include <nfs/nfsnode.h>
50#include <sys/ioctl.h>
51#include <sys/tty.h>
52#include <sys/conf.h>
53#include <sys/device.h>
54#include <sys/swap.h>
55
56#include <sys/sysctl.h>
57
58#include <stdint.h>
59#include <endian.h>
60#include <err.h>
61#include <fcntl.h>
62#include <kvm.h>
63#include <limits.h>
64#include <nlist.h>
65#include <paths.h>
66#include <stdio.h>
67#include <stdlib.h>
68#include <string.h>
69#include <unistd.h>
70
71struct nlist vnodenl[] = {
72#define FNL_NFILE0 0 /* sysctl */
73 {"_numfiles"},
74#define FNL_MAXFILE1 1 /* sysctl */
75 {"_maxfiles"},
76#define TTY_NTTY2 2 /* sysctl */
77 {"_tty_count"},
78#define V_NUMV3 3 /* sysctl */
79 { "_numvnodes" },
80#define TTY_TTYLIST4 4 /* sysctl */
81 {"_ttylist"},
82#define V_MOUNTLIST5 5 /* no sysctl */
83 { "_mountlist" },
84 { NULL((void *)0) }
85};
86
87struct itty *globalitp;
88struct kinfo_file *kf;
89struct nlist *globalnl;
90
91struct e_vnode {
92 struct vnode *vptr;
93 struct vnode vnode;
94};
95
96int kflag;
97int totalflag;
98int usenumflag;
99int hideroot;
100int maxfile;
101int need_nlist;
102int nfile;
103int ntty;
104int numvnodes;
105char *nlistf = NULL((void *)0);
106char *memf = NULL((void *)0);
107kvm_t *kd = NULL((void *)0);
108
109#define SVAR(var)"var" __STRING(var)"var" /* to force expansion */
110#define KGET(idx, var)if (kvm_read(kd, (u_long)(globalnl[idx].n_value), &var, sizeof
(var)) != sizeof(var)) warnx("cannot read %s: %s", "var", kvm_geterr
(kd))
\
111 KGET1(idx, &var, sizeof(var), SVAR(var))if (kvm_read(kd, (u_long)(globalnl[idx].n_value), &var, sizeof
(var)) != sizeof(var)) warnx("cannot read %s: %s", "var", kvm_geterr
(kd))
112#define KGET1(idx, p, s, msg)if (kvm_read(kd, (u_long)(globalnl[idx].n_value), p, s) != s)
warnx("cannot read %s: %s", msg, kvm_geterr(kd))
\
113 KGET2(globalnl[idx].n_value, p, s, msg)if (kvm_read(kd, (u_long)(globalnl[idx].n_value), p, s) != s)
warnx("cannot read %s: %s", msg, kvm_geterr(kd))
114#define KGET2(addr, p, s, msg)if (kvm_read(kd, (u_long)(addr), p, s) != s) warnx("cannot read %s: %s"
, msg, kvm_geterr(kd))
\
115 if (kvm_read(kd, (u_long)(addr), p, s) != s) \
116 warnx("cannot read %s: %s", msg, kvm_geterr(kd))
117#define KGETRET(addr, p, s, msg)if (kvm_read(kd, (u_long)(addr), p, s) != s) { warnx("cannot read %s: %s"
, msg, kvm_geterr(kd)); return (0); }
\
118 if (kvm_read(kd, (u_long)(addr), p, s) != s) { \
119 warnx("cannot read %s: %s", msg, kvm_geterr(kd)); \
120 return (0); \
121 }
122
123void filemode(void);
124void filemodeprep(void);
125struct mount *
126 getmnt(struct mount *);
127struct e_vnode *
128 kinfo_vnodes(void);
129void mount_print(struct mount *);
130void nfs_header(void);
131int nfs_print(struct vnode *);
132void swapmode(void);
133void ttymode(void);
134void ttymodeprep(void);
135void ttyprt(struct itty *);
136void tty2itty(struct tty *tp, struct itty *itp);
137void ufs_header(void);
138int ufs_print(struct vnode *);
139void ext2fs_header(void);
140int ext2fs_print(struct vnode *);
141static void __dead__attribute__((__noreturn__)) usage(void);
142void vnode_header(void);
143void vnode_print(struct vnode *, struct vnode *);
144void vnodemode(void);
145void vnodemodeprep(void);
146
147
148int
149main(int argc, char *argv[])
150{
151 int fileflag = 0, swapflag = 0, ttyflag = 0, vnodeflag = 0, ch;
152 char buf[_POSIX2_LINE_MAX2048];
153 const char *dformat = NULL((void *)0);
154 int i;
155
156 hideroot = getuid();
157
158 while ((ch = getopt(argc, argv, "d:TM:N:fiknstv")) != -1)
1
Assuming the condition is true
2
Loop condition is true. Entering loop body
4
Execution continues on line 158
5
Assuming the condition is false
6
Loop condition is false. Execution continues on line 194
159 switch (ch) {
3
Control jumps to 'case 102:' at line 163
160 case 'd':
161 dformat = optarg;
162 break;
163 case 'f':
164 fileflag = 1;
165 break;
166 case 'M':
167 memf = optarg;
168 break;
169 case 'N':
170 nlistf = optarg;
171 break;
172 case 'n':
173 usenumflag = 1;
174 break;
175 case 's':
176 swapflag = 1;
177 break;
178 case 'T':
179 totalflag = 1;
180 break;
181 case 't':
182 ttyflag = 1;
183 break;
184 case 'k':
185 kflag = 1;
186 break;
187 case 'v':
188 case 'i': /* Backward compatibility. */
189 vnodeflag = 1;
190 break;
191 default:
192 usage();
193 }
194 argc -= optind;
195 argv += optind;
196
197 if (dformat
6.1
'dformat' is null
&& getuid())
198 errx(1, "Only root can use -d");
199
200 if ((dformat
6.2
'dformat' is equal to NULL
== NULL((void *)0) && argc > 0) || (dformat
7.1
'dformat' is null
&& argc == 0))
7
Assuming 'argc' is <= 0
201 usage();
202
203 need_nlist = dformat
7.2
'dformat' is null
|| vnodeflag;
204
205 if (nlistf
7.3
'nlistf' is equal to NULL
!= NULL((void *)0) || memf
7.4
'memf' is equal to NULL
!= NULL((void *)0)) {
206 if (fileflag || totalflag)
207 need_nlist = 1;
208 }
209
210 if (vnodeflag
7.5
'vnodeflag' is 0
|| fileflag
7.6
'fileflag' is 1
|| dformat || need_nlist)
211 if ((kd = kvm_openfiles(nlistf, memf, NULL((void *)0),
9
Assuming the condition is false
10
Taking false branch
212 O_RDONLY0x0000 | (need_nlist
7.7
'need_nlist' is 0
? 0 : KVM_NO_FILES0x80000000), buf)) == 0
)
8
'?' condition is false
213 errx(1, "kvm_openfiles: %s", buf);
214
215 if (need_nlist
10.1
'need_nlist' is 0
)
216 if (kvm_nlist(kd, vnodenl) == -1)
217 errx(1, "kvm_nlist: %s", kvm_geterr(kd));
218
219 if (!(fileflag | vnodeflag | ttyflag | swapflag | totalflag || dformat))
11
Assuming the condition is true
12
Taking false branch
220 usage();
221
222 if(!dformat
12.1
'dformat' is null
) {
223 if (fileflag
12.2
'fileflag' is 1
|| totalflag)
224 filemodeprep();
225 if (vnodeflag
12.3
'vnodeflag' is 0
|| totalflag
12.4
'totalflag' is not equal to 0
)
13
Taking true branch
226 vnodemodeprep();
227 if (ttyflag
13.1
'ttyflag' is 0
)
14
Taking false branch
228 ttymodeprep();
229 }
230
231 if (unveil(_PATH_DEVDB"/var/run/dev.db", "r") == -1)
15
Assuming the condition is false
16
Taking false branch
232 err(1, "unveil %s", _PATH_DEVDB"/var/run/dev.db");
233 if (pledge("stdio rpath vminfo", NULL((void *)0)) == -1)
17
Assuming the condition is false
18
Taking false branch
234 err(1, "pledge");
235
236 if (dformat
18.1
'dformat' is null
) {
237 struct nlist *nl;
238 int longformat = 0, stringformat = 0, error = 0, n;
239 uint32_t mask = ~0;
240 char format[10], buf[1024];
241
242 n = strlen(dformat);
243 if (n == 0)
244 errx(1, "illegal format");
245
246 /*
247 * Support p, c, s, and {l, ll, h, hh, j, t, z, }[diouxX]
248 */
249 if (strcmp(dformat, "p") == 0)
250 longformat = sizeof(long) == 8;
251 else if (strcmp(dformat, "c") == 0)
252 mask = 0xff;
253 else if (strcmp(dformat, "s") == 0)
254 stringformat = 1;
255 else if (strchr("diouxX", dformat[n - 1])) {
256 char *ptbl[]= {"l", "ll", "h", "hh", "j", "t", "z", ""};
257 int i;
258
259 char *mod;
260 for (i = 0; i < sizeof(ptbl)/sizeof(ptbl[0]); i++) {
261 mod = ptbl[i];
262 if (strlen(mod) == n - 1 &&
263 strncmp(mod, dformat, strlen(mod)) == 0)
264 break;
265 }
266 if (i == sizeof(ptbl)/sizeof(ptbl[0])
267 && dformat[1] != '\0')
268 errx(1, "illegal format");
269 if (strcmp(mod, "l") == 0)
270 longformat = sizeof(long) == sizeof(long long);
271 else if (strcmp(mod, "h") == 0)
272 mask = 0xffff;
273 else if (strcmp(mod, "hh") == 0)
274 mask = 0xff;
275 else if (strcmp(mod, "") != 0)
276 longformat = 1;
277
278 } else
279 errx(1, "illegal format");
280
281 if (*dformat == 's') {
282 stringformat = 1;
283 snprintf(format, sizeof(format), "%%.%zus",
284 sizeof buf);
285 } else
286 snprintf(format, sizeof(format), "%%%s", dformat);
287
288 nl = calloc(argc + 1, sizeof *nl);
289 if (!nl)
290 err(1, "calloc nl: ");
291 for (i = 0; i < argc; i++) {
292 if (asprintf(&nl[i].n_name, "_%s",
293 argv[i]) == -1)
294 warn("asprintf");
295 }
296 kvm_nlist(kd, nl);
297 globalnl = nl;
298 for (i = 0; i < argc; i++) {
299 uint64_t v;
300
301 printf("%s ", argv[i]);
302 if (!nl[i].n_value && argv[i][0] == '0') {
303 nl[i].n_value = strtoul(argv[i], NULL((void *)0), 16);
304 nl[i].n_type = N_DATA0x06;
305 }
306 if (!nl[i].n_value) {
307 printf("not found\n");
308 error++;
309 continue;
310 }
311
312 printf("at %p: ", (void *)nl[i].n_value);
313 if ((nl[i].n_type & N_TYPE0x1e) == N_DATA0x06 ||
314 (nl[i].n_type & N_TYPE0x1e) == N_COMM0x12) {
315 if (stringformat) {
316 KGET1(i, &buf, sizeof(buf), argv[i])if (kvm_read(kd, (u_long)(globalnl[i].n_value), &buf, sizeof
(buf)) != sizeof(buf)) warnx("cannot read %s: %s", argv[i], kvm_geterr
(kd))
;
317 buf[sizeof(buf) - 1] = '\0';
318 } else
319 KGET1(i, &v, sizeof(v), argv[i])if (kvm_read(kd, (u_long)(globalnl[i].n_value), &v, sizeof
(v)) != sizeof(v)) warnx("cannot read %s: %s", argv[i], kvm_geterr
(kd))
;
320 if (stringformat)
321 printf(format, &buf);
322 else if (longformat)
323 printf(format, v);
324 else {
325#if BYTE_ORDER1234 == BIG_ENDIAN4321
326 switch (mask) {
327 case 0xff:
328 v >>= 8;
329 /* FALLTHROUGH */
330 case 0xffff:
331 v >>= 16;
332 /* FALLTHROUGH */
333 case 0xffffffff:
334 v >>= 32;
335 break;
336 }
337#endif
338 printf(format, ((uint32_t)v) & mask);
339 }
340 }
341 printf("\n");
342 }
343 for (i = 0; i < argc; i++)
344 free(nl[i].n_name);
345 free(nl);
346 return error;
347 }
348
349 if (fileflag
18.2
'fileflag' is 1
|| totalflag)
350 filemode();
351 if (vnodeflag
18.3
'vnodeflag' is 0
|| totalflag
18.4
'totalflag' is not equal to 0
)
19
Taking true branch
352 vnodemode();
20
Calling 'vnodemode'
353 if (ttyflag)
354 ttymode();
355 if (swapflag || totalflag)
356 swapmode();
357 return 0;
358}
359
360void
361vnodemode(void)
362{
363 struct e_vnode *e_vnodebase, *endvnode, *evp;
364 struct vnode *vp;
365 struct mount *maddr, *mp = NULL((void *)0);
366
367 globalnl = vnodenl;
368
369 e_vnodebase = kinfo_vnodes();
370 if (totalflag) {
21
Assuming 'totalflag' is 0
22
Taking false branch
371 (void)printf("%7d vnodes\n", numvnodes);
372 return;
373 }
374 if (!e_vnodebase)
23
Assuming 'e_vnodebase' is non-null
24
Taking false branch
375 return;
376 endvnode = e_vnodebase + numvnodes;
377 (void)printf("%d active vnodes\n", numvnodes);
378
379 maddr = NULL((void *)0);
380 for (evp = e_vnodebase; evp < endvnode; evp++) {
25
Loop condition is true. Entering loop body
381 vp = &evp->vnode;
382 if (vp->v_mount != maddr) {
26
Assuming 'maddr' is equal to field 'v_mount'
27
Taking false branch
383 /*
384 * New filesystem
385 */
386 if ((mp = getmnt(vp->v_mount)) == NULL((void *)0))
387 continue;
388 maddr = vp->v_mount;
389 mount_print(mp);
390 vnode_header();
391 if (!strncmp(mp->mnt_stat.f_fstypename, MOUNT_FFS"ffs", MFSNAMELEN16) ||
392 !strncmp(mp->mnt_stat.f_fstypename, MOUNT_MFS"mfs", MFSNAMELEN16)) {
393 ufs_header();
394 } else if (!strncmp(mp->mnt_stat.f_fstypename, MOUNT_NFS"nfs",
395 MFSNAMELEN16)) {
396 nfs_header();
397 } else if (!strncmp(mp->mnt_stat.f_fstypename, MOUNT_EXT2FS"ext2fs",
398 MFSNAMELEN16)) {
399 ext2fs_header();
400 }
401 (void)printf("\n");
402 }
403 vnode_print(evp->vptr, vp);
404
405 /* Syncer vnodes have no associated fs-specific data */
406 if (vp->v_data == NULL((void *)0)) {
28
Assuming field 'v_data' is not equal to NULL
407 printf(" %6c %5c %7c\n", '-', '-', '-');
408 continue;
409 }
410
411 if (!strncmp(mp->mnt_stat.f_fstypename, MOUNT_FFS"ffs", MFSNAMELEN16) ||
29
Null pointer passed as 1st argument to string comparison function
412 !strncmp(mp->mnt_stat.f_fstypename, MOUNT_MFS"mfs", MFSNAMELEN16)) {
413 ufs_print(vp);
414 } else if (!strncmp(mp->mnt_stat.f_fstypename, MOUNT_NFS"nfs", MFSNAMELEN16)) {
415 nfs_print(vp);
416 } else if (!strncmp(mp->mnt_stat.f_fstypename, MOUNT_EXT2FS"ext2fs",
417 MFSNAMELEN16)) {
418 ext2fs_print(vp);
419 }
420 (void)printf("\n");
421 }
422 free(e_vnodebase);
423}
424
425void
426vnodemodeprep(void)
427{
428 int mib[2];
429 size_t num;
430
431 if (kd == NULL((void *)0)) {
432 mib[0] = CTL_KERN1;
433 mib[1] = KERN_NUMVNODES58;
434 num = sizeof(numvnodes);
435 if (sysctl(mib, 2, &numvnodes, &num, NULL((void *)0), 0) < 0)
436 err(1, "sysctl(KERN_NUMVNODES) failed");
437 }
438}
439
440void
441vnode_header(void)
442{
443 (void)printf("%*s TYP VFLAG USE HOLD", 2 * (int)sizeof(long), "ADDR");
444}
445
446void
447vnode_print(struct vnode *avnode, struct vnode *vp)
448{
449 char *type, flags[16];
450 char *fp;
451 int flag;
452
453 /*
454 * set type
455 */
456 switch (vp->v_type) {
457 case VNON:
458 type = "non"; break;
459 case VREG:
460 type = "reg"; break;
461 case VDIR:
462 type = "dir"; break;
463 case VBLK:
464 type = "blk"; break;
465 case VCHR:
466 type = "chr"; break;
467 case VLNK:
468 type = "lnk"; break;
469 case VSOCK:
470 type = "soc"; break;
471 case VFIFO:
472 type = "fif"; break;
473 case VBAD:
474 type = "bad"; break;
475 default:
476 type = "unk"; break;
477 }
478 /*
479 * gather flags
480 */
481 fp = flags;
482 flag = vp->v_flag;
483 if (flag & VROOT0x0001)
484 *fp++ = 'R';
485 if (flag & VTEXT0x0002)
486 *fp++ = 'T';
487 if (flag & VSYSTEM0x0004)
488 *fp++ = 'S';
489 if (flag & VISTTY0x0008)
490 *fp++ = 'I';
491 if (flag & VXLOCK0x0100)
492 *fp++ = 'L';
493 if (flag & VXWANT0x0200)
494 *fp++ = 'W';
495 if (vp->v_bioflag & VBIOWAIT0x0001)
496 *fp++ = 'B';
497 if (flag & VALIASED0x0800)
498 *fp++ = 'A';
499 if (vp->v_bioflag & VBIOONFREELIST0x0004)
500 *fp++ = 'F';
501 if (flag & VLOCKSWORK0x4000)
502 *fp++ = 'l';
503 if (vp->v_bioflag & VBIOONSYNCLIST0x0002)
504 *fp++ = 's';
505 if (fp == flags)
506 *fp++ = '-';
507 *fp = '\0';
508 (void)printf("%0*lx %s %5s %4d %4u",
509 2 * (int)sizeof(long), hideroot ? 0L : (long)avnode,
510 type, flags, vp->v_usecount, vp->v_holdcnt);
511}
512
513void
514ufs_header(void)
515{
516 (void)printf(" FILEID IFLAG RDEV|SZ");
517}
518
519int
520ufs_print(struct vnode *vp)
521{
522 int flag;
523 struct inode inode, *ip = &inode;
524 struct ufs1_dinode di1;
525 char flagbuf[16], *flags = flagbuf;
526 char *name;
527 mode_t type;
528
529 KGETRET(VTOI(vp), &inode, sizeof(struct inode), "vnode's inode")if (kvm_read(kd, (u_long)(((struct inode *)(vp)->v_data)),
&inode, sizeof(struct inode)) != sizeof(struct inode)) {
warnx("cannot read %s: %s", "vnode's inode", kvm_geterr(kd))
; return (0); }
;
530 KGETRET(inode.i_din1, &di1, sizeof(struct ufs1_dinode),if (kvm_read(kd, (u_long)(inode.dinode_u.ffs1_din), &di1,
sizeof(struct ufs1_dinode)) != sizeof(struct ufs1_dinode)) {
warnx("cannot read %s: %s", "vnode's dinode", kvm_geterr(kd)
); return (0); }
531 "vnode's dinode")if (kvm_read(kd, (u_long)(inode.dinode_u.ffs1_din), &di1,
sizeof(struct ufs1_dinode)) != sizeof(struct ufs1_dinode)) {
warnx("cannot read %s: %s", "vnode's dinode", kvm_geterr(kd)
); return (0); }
;
532
533 inode.i_din1dinode_u.ffs1_din = &di1;
534 flag = ip->i_flag;
535#if 0
536 if (flag & IN_LOCKED)
537 *flags++ = 'L';
538 if (flag & IN_WANTED)
539 *flags++ = 'W';
540 if (flag & IN_LWAIT)
541 *flags++ = 'Z';
542#endif
543 if (flag & IN_ACCESS0x0001)
544 *flags++ = 'A';
545 if (flag & IN_CHANGE0x0002)
546 *flags++ = 'C';
547 if (flag & IN_UPDATE0x0004)
548 *flags++ = 'U';
549 if (flag & IN_MODIFIED0x0008)
550 *flags++ = 'M';
551 if (flag & IN_LAZYMOD0x0080)
552 *flags++ = 'm';
553 if (flag & IN_RENAME0x0010)
554 *flags++ = 'R';
555 if (flag & IN_SHLOCK0x0020)
556 *flags++ = 'S';
557 if (flag & IN_EXLOCK0x0040)
558 *flags++ = 'E';
559 if (flag == 0)
560 *flags++ = '-';
561 *flags = '\0';
562
563 (void)printf(" %6d %5s", ip->i_number, flagbuf);
564 type = ip->i_ffs1_modedinode_u.ffs1_din->di_mode & S_IFMT0170000;
565 if (S_ISCHR(ip->i_ffs1_mode)((ip->dinode_u.ffs1_din->di_mode & 0170000) == 0020000
)
|| S_ISBLK(ip->i_ffs1_mode)((ip->dinode_u.ffs1_din->di_mode & 0170000) == 0060000
)
)
566 if (usenumflag ||
567 ((name = devname(ip->i_ffs1_rdevdinode_u.ffs1_din->di_db[0], type)) == NULL((void *)0)))
568 (void)printf(" %2u,%-2u",
569 major(ip->i_ffs1_rdev)(((unsigned)(ip->dinode_u.ffs1_din->di_db[0]) >> 8
) & 0xff)
, minor(ip->i_ffs1_rdev)((unsigned)((ip->dinode_u.ffs1_din->di_db[0]) & 0xff
) | (((ip->dinode_u.ffs1_din->di_db[0]) & 0xffff0000
) >> 8))
);
570 else
571 (void)printf(" %7s", name);
572 else
573 (void)printf(" %7lld", (long long)ip->i_ffs1_sizedinode_u.ffs1_din->di_size);
574 return (0);
575}
576
577void
578ext2fs_header(void)
579{
580 (void)printf(" FILEID IFLAG SZ");
581}
582
583int
584ext2fs_print(struct vnode *vp)
585{
586 int flag;
587 struct inode inode, *ip = &inode;
588 struct ext2fs_dinode di;
589 char flagbuf[16], *flags = flagbuf;
590
591 KGETRET(VTOI(vp), &inode, sizeof(struct inode), "vnode's inode")if (kvm_read(kd, (u_long)(((struct inode *)(vp)->v_data)),
&inode, sizeof(struct inode)) != sizeof(struct inode)) {
warnx("cannot read %s: %s", "vnode's inode", kvm_geterr(kd))
; return (0); }
;
592 KGETRET(inode.i_e2din, &di, sizeof(struct ext2fs_dinode),if (kvm_read(kd, (u_long)(inode.dinode_u.e2fs_din), &di, sizeof
(struct ext2fs_dinode)) != sizeof(struct ext2fs_dinode)) { warnx
("cannot read %s: %s", "vnode's dinode", kvm_geterr(kd)); return
(0); }
593 "vnode's dinode")if (kvm_read(kd, (u_long)(inode.dinode_u.e2fs_din), &di, sizeof
(struct ext2fs_dinode)) != sizeof(struct ext2fs_dinode)) { warnx
("cannot read %s: %s", "vnode's dinode", kvm_geterr(kd)); return
(0); }
;
594
595 inode.i_e2dindinode_u.e2fs_din = &di;
596 flag = ip->i_flag;
597
598#if 0
599 if (flag & IN_LOCKED)
600 *flags++ = 'L';
601 if (flag & IN_WANTED)
602 *flags++ = 'W';
603 if (flag & IN_LWAIT)
604 *flags++ = 'Z';
605#endif
606 if (flag & IN_ACCESS0x0001)
607 *flags++ = 'A';
608 if (flag & IN_CHANGE0x0002)
609 *flags++ = 'C';
610 if (flag & IN_UPDATE0x0004)
611 *flags++ = 'U';
612 if (flag & IN_MODIFIED0x0008)
613 *flags++ = 'M';
614 if (flag & IN_RENAME0x0010)
615 *flags++ = 'R';
616 if (flag & IN_SHLOCK0x0020)
617 *flags++ = 'S';
618 if (flag & IN_EXLOCK0x0040)
619 *flags++ = 'E';
620 if (flag == 0)
621 *flags++ = '-';
622 *flags = '\0';
623
624 (void)printf(" %6d %5s %2d", ip->i_number, flagbuf, ip->i_e2fs_sizedinode_u.e2fs_din->e2di_size);
625 return (0);
626}
627
628void
629nfs_header(void)
630{
631 (void)printf(" FILEID NFLAG RDEV|SZ");
632}
633
634int
635nfs_print(struct vnode *vp)
636{
637 struct nfsnode nfsnode, *np = &nfsnode;
638 char flagbuf[16], *flags = flagbuf;
639 int flag;
640 char *name;
641 mode_t type;
642
643 KGETRET(VTONFS(vp), &nfsnode, sizeof(nfsnode), "vnode's nfsnode")if (kvm_read(kd, (u_long)(((struct nfsnode *)(vp)->v_data)
), &nfsnode, sizeof(nfsnode)) != sizeof(nfsnode)) { warnx
("cannot read %s: %s", "vnode's nfsnode", kvm_geterr(kd)); return
(0); }
;
644 flag = np->n_flag;
645 if (flag & NFLUSHWANT0x0001)
646 *flags++ = 'W';
647 if (flag & NFLUSHINPROG0x0002)
648 *flags++ = 'P';
649 if (flag & NMODIFIED0x0004)
650 *flags++ = 'M';
651 if (flag & NWRITEERR0x0008)
652 *flags++ = 'E';
653 if (flag & NACC0x0100)
654 *flags++ = 'A';
655 if (flag & NUPD0x0200)
656 *flags++ = 'U';
657 if (flag & NCHG0x0400)
658 *flags++ = 'C';
659 if (flag == 0)
660 *flags++ = '-';
661 *flags = '\0';
662
663 (void)printf(" %6lld %5s", (long long)np->n_vattr.va_fileid, flagbuf);
664 type = np->n_vattr.va_mode & S_IFMT0170000;
665 if (S_ISCHR(np->n_vattr.va_mode)((np->n_vattr.va_mode & 0170000) == 0020000) || S_ISBLK(np->n_vattr.va_mode)((np->n_vattr.va_mode & 0170000) == 0060000))
666 if (usenumflag ||
667 ((name = devname(np->n_vattr.va_rdev, type)) == NULL((void *)0)))
668 (void)printf(" %2u,%-2u", major(np->n_vattr.va_rdev)(((unsigned)(np->n_vattr.va_rdev) >> 8) & 0xff),
669 minor(np->n_vattr.va_rdev)((unsigned)((np->n_vattr.va_rdev) & 0xff) | (((np->
n_vattr.va_rdev) & 0xffff0000) >> 8))
);
670 else
671 (void)printf(" %7s", name);
672 else
673 (void)printf(" %7lld", (long long)np->n_size);
674 return (0);
675}
676
677/*
678 * Given a pointer to a mount structure in kernel space,
679 * read it in and return a usable pointer to it.
680 */
681struct mount *
682getmnt(struct mount *maddr)
683{
684 static struct mtab {
685 struct mtab *next;
686 struct mount *maddr;
687 struct mount mount;
688 } *mhead = NULL((void *)0);
689 struct mtab *mt;
690
691 for (mt = mhead; mt != NULL((void *)0); mt = mt->next)
692 if (maddr == mt->maddr)
693 return (&mt->mount);
694 if ((mt = malloc(sizeof(struct mtab))) == NULL((void *)0))
695 err(1, "malloc: mount table");
696 KGETRET(maddr, &mt->mount, sizeof(struct mount), "mount table")if (kvm_read(kd, (u_long)(maddr), &mt->mount, sizeof(struct
mount)) != sizeof(struct mount)) { warnx("cannot read %s: %s"
, "mount table", kvm_geterr(kd)); return (0); }
;
697 mt->maddr = maddr;
698 mt->next = mhead;
699 mhead = mt;
700 return (&mt->mount);
701}
702
703void
704mount_print(struct mount *mp)
705{
706 int flags;
707
708 (void)printf("*** MOUNT ");
709 (void)printf("%.*s %s on %s", MFSNAMELEN16,
710 mp->mnt_stat.f_fstypename, mp->mnt_stat.f_mntfromname,
711 mp->mnt_stat.f_mntonname);
712 if ((flags = mp->mnt_flag)) {
713 char *comma = "(";
714
715 putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
716 /* user visible flags */
717 if (flags & MNT_RDONLY0x00000001) {
718 (void)printf("%srdonly", comma);
719 flags &= ~MNT_RDONLY0x00000001;
720 comma = ",";
721 }
722 if (flags & MNT_SYNCHRONOUS0x00000002) {
723 (void)printf("%ssynchronous", comma);
724 flags &= ~MNT_SYNCHRONOUS0x00000002;
725 comma = ",";
726 }
727 if (flags & MNT_NOEXEC0x00000004) {
728 (void)printf("%snoexec", comma);
729 flags &= ~MNT_NOEXEC0x00000004;
730 comma = ",";
731 }
732 if (flags & MNT_NOSUID0x00000008) {
733 (void)printf("%snosuid", comma);
734 flags &= ~MNT_NOSUID0x00000008;
735 comma = ",";
736 }
737 if (flags & MNT_NODEV0x00000010) {
738 (void)printf("%snodev", comma);
739 flags &= ~MNT_NODEV0x00000010;
740 comma = ",";
741 }
742 if (flags & MNT_ASYNC0x00000040) {
743 (void)printf("%sasync", comma);
744 flags &= ~MNT_ASYNC0x00000040;
745 comma = ",";
746 }
747 if (flags & MNT_EXRDONLY0x00000080) {
748 (void)printf("%sexrdonly", comma);
749 flags &= ~MNT_EXRDONLY0x00000080;
750 comma = ",";
751 }
752 if (flags & MNT_EXPORTED0x00000100) {
753 (void)printf("%sexport", comma);
754 flags &= ~MNT_EXPORTED0x00000100;
755 comma = ",";
756 }
757 if (flags & MNT_DEFEXPORTED0x00000200) {
758 (void)printf("%sdefdexported", comma);
759 flags &= ~MNT_DEFEXPORTED0x00000200;
760 comma = ",";
761 }
762 if (flags & MNT_EXPORTANON0x00000400) {
763 (void)printf("%sexportanon", comma);
764 flags &= ~MNT_EXPORTANON0x00000400;
765 comma = ",";
766 }
767 if (flags & MNT_WXALLOWED0x00000800) {
768 (void)printf("%swxallowed", comma);
769 flags &= ~MNT_WXALLOWED0x00000800;
770 comma = ",";
771 }
772 if (flags & MNT_LOCAL0x00001000) {
773 (void)printf("%slocal", comma);
774 flags &= ~MNT_LOCAL0x00001000;
775 comma = ",";
776 }
777 if (flags & MNT_QUOTA0x00002000) {
778 (void)printf("%squota", comma);
779 flags &= ~MNT_QUOTA0x00002000;
780 comma = ",";
781 }
782 if (flags & MNT_ROOTFS0x00004000) {
783 (void)printf("%srootfs", comma);
784 flags &= ~MNT_ROOTFS0x00004000;
785 comma = ",";
786 }
787 if (flags & MNT_NOATIME0x00008000) {
788 (void)printf("%snoatime", comma);
789 flags &= ~MNT_NOATIME0x00008000;
790 comma = ",";
791 }
792 /* filesystem control flags */
793 if (flags & MNT_UPDATE0x00010000) {
794 (void)printf("%supdate", comma);
795 flags &= ~MNT_UPDATE0x00010000;
796 comma = ",";
797 }
798 if (flags & MNT_DELEXPORT0x00020000) {
799 (void)printf("%sdelexport", comma);
800 flags &= ~MNT_DELEXPORT0x00020000;
801 comma = ",";
802 }
803 if (flags & MNT_RELOAD0x00040000) {
804 (void)printf("%sreload", comma);
805 flags &= ~MNT_RELOAD0x00040000;
806 comma = ",";
807 }
808 if (flags & MNT_FORCE0x00080000) {
809 (void)printf("%sforce", comma);
810 flags &= ~MNT_FORCE0x00080000;
811 comma = ",";
812 }
813 if (flags & MNT_WANTRDWR0x02000000) {
814 (void)printf("%swantrdwr", comma);
815 flags &= ~MNT_WANTRDWR0x02000000;
816 comma = ",";
817 }
818 if (flags & MNT_SOFTDEP0x04000000) {
819 (void)printf("%ssoftdep", comma);
820 flags &= ~MNT_SOFTDEP0x04000000;
821 comma = ",";
822 }
823 if (flags)
824 (void)printf("%sunknown_flags:%x", comma, flags);
825 (void)printf(")");
826 }
827 (void)printf("\n");
828}
829
830/*
831 * simulate what a running kernel does in kinfo_vnode
832 */
833struct e_vnode *
834kinfo_vnodes(void)
835{
836 struct mntlist kvm_mountlist;
837 struct mount *mp, mount;
838 struct vnode *vp, vnode;
839 char *vbuf, *evbuf, *bp;
840 size_t num;
841
842 if (kd != NULL((void *)0))
843 KGET(V_NUMV, numvnodes)if (kvm_read(kd, (u_long)(globalnl[3].n_value), &numvnodes
, sizeof(numvnodes)) != sizeof(numvnodes)) warnx("cannot read %s: %s"
, "numvnodes", kvm_geterr(kd))
;
844 if (totalflag)
845 return NULL((void *)0);
846 if ((vbuf = calloc(numvnodes + 20,
847 sizeof(struct vnode *) + sizeof(struct vnode))) == NULL((void *)0))
848 err(1, "malloc: vnode buffer");
849 bp = vbuf;
850 evbuf = vbuf + (numvnodes + 20) *
851 (sizeof(struct vnode *) + sizeof(struct vnode));
852 KGET(V_MOUNTLIST, kvm_mountlist)if (kvm_read(kd, (u_long)(globalnl[5].n_value), &kvm_mountlist
, sizeof(kvm_mountlist)) != sizeof(kvm_mountlist)) warnx("cannot read %s: %s"
, "kvm_mountlist", kvm_geterr(kd))
;
853 num = 0;
854 for (mp = TAILQ_FIRST(&kvm_mountlist)((&kvm_mountlist)->tqh_first); mp != NULL((void *)0);
855 mp = TAILQ_NEXT(&mount, mnt_list)((&mount)->mnt_list.tqe_next)) {
856 KGETRET(mp, &mount, sizeof(mount), "mount entry")if (kvm_read(kd, (u_long)(mp), &mount, sizeof(mount)) != sizeof
(mount)) { warnx("cannot read %s: %s", "mount entry", kvm_geterr
(kd)); return (0); }
;
857 for (vp = TAILQ_FIRST(&mount.mnt_vnodelist)((&mount.mnt_vnodelist)->tqh_first);
858 vp != NULL((void *)0); vp = TAILQ_NEXT(&vnode, v_mntvnodes)((&vnode)->v_mntvnodes.tqe_next)) {
859 KGETRET(vp, &vnode, sizeof(vnode), "vnode")if (kvm_read(kd, (u_long)(vp), &vnode, sizeof(vnode)) != sizeof
(vnode)) { warnx("cannot read %s: %s", "vnode", kvm_geterr(kd
)); return (0); }
;
860 if ((bp + sizeof(struct vnode *) +
861 sizeof(struct vnode)) > evbuf)
862 /* XXX - should realloc */
863 errx(1, "no more room for vnodes");
864 memmove(bp, &vp, sizeof(struct vnode *));
865 bp += sizeof(struct vnode *);
866 memmove(bp, &vnode, sizeof(struct vnode));
867 bp += sizeof(struct vnode);
868 num++;
869 }
870 }
871 numvnodes = num;
872 return ((struct e_vnode *)vbuf);
873}
874
875const char hdr[] =
876" LINE RAW CAN OUT HWT LWT COL STATE SESS PGID DISC\n";
877
878void
879tty2itty(struct tty *tp, struct itty *itp)
880{
881 itp->t_dev = tp->t_dev;
882 itp->t_rawq_c_cc = tp->t_rawq.c_cc;
883 itp->t_canq_c_cc = tp->t_canq.c_cc;
884 itp->t_outq_c_cc = tp->t_outq.c_cc;
885 itp->t_hiwat = tp->t_hiwat;
886 itp->t_lowat = tp->t_lowat;
887 itp->t_column = tp->t_column;
888 itp->t_state = tp->t_state;
889 itp->t_session = tp->t_session;
890 if (tp->t_pgrp != NULL((void *)0))
891 KGET2(&tp->t_pgrp->pg_id, &itp->t_pgrp_pg_id, sizeof(pid_t), "pgid")if (kvm_read(kd, (u_long)(&tp->t_pgrp->pg_id), &
itp->t_pgrp_pg_id, sizeof(pid_t)) != sizeof(pid_t)) warnx(
"cannot read %s: %s", "pgid", kvm_geterr(kd))
;
892 itp->t_line = tp->t_line;
893}
894
895void
896ttymode(void)
897{
898 struct ttylist_head tty_head;
899 struct tty *tp, tty;
900 int i;
901 struct itty itty;
902
903 if (need_nlist)
904 KGET(TTY_NTTY, ntty)if (kvm_read(kd, (u_long)(globalnl[2].n_value), &ntty, sizeof
(ntty)) != sizeof(ntty)) warnx("cannot read %s: %s", "ntty", kvm_geterr
(kd))
;
905 (void)printf("%d terminal device%s\n", ntty, ntty == 1 ? "" : "s");
906 (void)printf("%s", hdr);
907 if (!need_nlist) {
908 for (i = 0; i < ntty; i++)
909 ttyprt(&globalitp[i]);
910 free(globalitp);
911 } else {
912 KGET(TTY_TTYLIST, tty_head)if (kvm_read(kd, (u_long)(globalnl[4].n_value), &tty_head
, sizeof(tty_head)) != sizeof(tty_head)) warnx("cannot read %s: %s"
, "tty_head", kvm_geterr(kd))
;
913 for (tp = TAILQ_FIRST(&tty_head)((&tty_head)->tqh_first); tp;
914 tp = TAILQ_NEXT(&tty, tty_link)((&tty)->tty_link.tqe_next)) {
915 KGET2(tp, &tty, sizeof tty, "tty struct")if (kvm_read(kd, (u_long)(tp), &tty, sizeof tty) != sizeof
tty) warnx("cannot read %s: %s", "tty struct", kvm_geterr(kd
))
;
916 tty2itty(&tty, &itty);
917 ttyprt(&itty);
918 }
919 }
920}
921
922void
923ttymodeprep(void)
924{
925 int mib[3];
926 size_t nlen;
927
928 if (!need_nlist) {
929 mib[0] = CTL_KERN1;
930 mib[1] = KERN_TTYCOUNT57;
931 nlen = sizeof(ntty);
932 if (sysctl(mib, 2, &ntty, &nlen, NULL((void *)0), 0) < 0)
933 err(1, "sysctl(KERN_TTYCOUNT) failed");
934
935 mib[0] = CTL_KERN1;
936 mib[1] = KERN_TTY44;
937 mib[2] = KERN_TTY_INFO5;
938 if ((globalitp = reallocarray(NULL((void *)0), ntty, sizeof(struct itty))) == NULL((void *)0))
939 err(1, "malloc");
940 nlen = ntty * sizeof(struct itty);
941 if (sysctl(mib, 3, globalitp, &nlen, NULL((void *)0), 0) < 0)
942 err(1, "sysctl(KERN_TTY_INFO) failed");
943 }
944}
945
946struct {
947 int flag;
948 char val;
949} ttystates[] = {
950 { TS_WOPEN0x00200, 'W'},
951 { TS_ISOPEN0x00020, 'O'},
952 { TS_CARR_ON0x00008, 'C'},
953 { TS_TIMEOUT0x00080, 'T'},
954 { TS_FLUSH0x00010, 'F'},
955 { TS_BUSY0x00004, 'B'},
956 { TS_ASLEEP0x00001, 'A'},
957 { TS_XCLUDE0x00400, 'X'},
958 { TS_TTSTOP0x00100, 'S'},
959 { TS_TBLOCK0x00040, 'K'},
960 { TS_ASYNC0x00002, 'Y'},
961 { TS_BKSL0x00800, 'D'},
962 { TS_ERASE0x02000, 'E'},
963 { TS_LNCH0x04000, 'L'},
964 { TS_TYPEN0x08000, 'P'},
965 { TS_CNTTB0x01000, 'N'},
966 { 0, '\0'},
967};
968
969void
970ttyprt(struct itty *tp)
971{
972 char *name, state[20];
973 int i, j;
974
975 if (usenumflag || (name = devname(tp->t_dev, S_IFCHR0020000)) == NULL((void *)0))
976 (void)printf("%2u,%-3u ", major(tp->t_dev)(((unsigned)(tp->t_dev) >> 8) & 0xff), minor(tp->t_dev)((unsigned)((tp->t_dev) & 0xff) | (((tp->t_dev) &
0xffff0000) >> 8))
);
977 else
978 (void)printf("%7s ", name);
979 (void)printf("%3d %4d ", tp->t_rawq_c_cc, tp->t_canq_c_cc);
980 (void)printf("%4d %4d %3d %6d ", tp->t_outq_c_cc,
981 tp->t_hiwat, tp->t_lowat, tp->t_column);
982 for (i = j = 0; ttystates[i].flag; i++)
983 if (tp->t_state&ttystates[i].flag)
984 state[j++] = ttystates[i].val;
985 if (j == 0)
986 state[j++] = '-';
987 state[j] = '\0';
988 (void)printf("%-6s %8lx", state,
989 hideroot ? 0 : (u_long)tp->t_session & 0xffffffff);
990 (void)printf("%6d ", tp->t_pgrp_pg_id);
991 switch (tp->t_line) {
992 case TTYDISC0:
993 (void)printf("term\n");
994 break;
995 case PPPDISC5:
996 (void)printf("ppp\n");
997 break;
998 case NMEADISC7:
999 (void)printf("nmea\n");
1000 break;
1001 default:
1002 (void)printf("%d\n", tp->t_line);
1003 break;
1004 }
1005}
1006
1007void
1008filemode(void)
1009{
1010 char flagbuf[16], *fbp;
1011 static char *dtypes[] = { "???", "inode", "socket", "pipe", "kqueue", "???", "???" };
1012
1013 globalnl = vnodenl;
1014
1015 if (nlistf != NULL((void *)0) || memf != NULL((void *)0)) {
1016 KGET(FNL_MAXFILE, maxfile)if (kvm_read(kd, (u_long)(globalnl[1].n_value), &maxfile,
sizeof(maxfile)) != sizeof(maxfile)) warnx("cannot read %s: %s"
, "maxfile", kvm_geterr(kd))
;
1017 if (totalflag) {
1018 KGET(FNL_NFILE, nfile)if (kvm_read(kd, (u_long)(globalnl[0].n_value), &nfile, sizeof
(nfile)) != sizeof(nfile)) warnx("cannot read %s: %s", "nfile"
, kvm_geterr(kd))
;
1019 (void)printf("%3d/%3d files\n", nfile, maxfile);
1020 return;
1021 }
1022 }
1023
1024 (void)printf("%d/%d open files\n", nfile, maxfile);
1025 if (totalflag)
1026 return;
1027
1028 (void)printf("%*s TYPE FLG CNT MSG %*s OFFSET\n",
1029 2 * (int)sizeof(long), "LOC", 2 * (int)sizeof(long), "DATA");
1030 for (; nfile-- > 0; kf++) {
1031 (void)printf("%0*llx ", 2 * (int)sizeof(long),
1032 hideroot ? 0LL : kf->f_fileaddr);
1033 (void)printf("%-8.8s", dtypes[
1034 (kf->f_type >= (sizeof(dtypes)/sizeof(dtypes[0])))
1035 ? 0 : kf->f_type]);
1036 fbp = flagbuf;
1037 if (kf->f_flag & FREAD0x0001)
1038 *fbp++ = 'R';
1039 if (kf->f_flag & FWRITE0x0002)
1040 *fbp++ = 'W';
1041 if (kf->f_flag & FAPPEND0x0008)
1042 *fbp++ = 'A';
1043 if (kf->f_flag & FASYNC0x0040)
1044 *fbp++ = 'I';
1045
1046 if (kf->f_iflags & FIF_HASLOCK0x01)
1047 *fbp++ = 'L';
1048
1049 *fbp = '\0';
1050 (void)printf("%6s %3ld", flagbuf, (long)kf->f_count);
1051 (void)printf(" %3ld", (long)kf->f_msgcount);
1052 (void)printf(" %0*lx", 2 * (int)sizeof(long),
1053 hideroot ? 0L : (long)kf->f_data);
1054
1055 if (kf->f_offset == (uint64_t)-1)
1056 (void)printf(" *\n");
1057 else if (kf->f_offset > INT64_MAX0x7fffffffffffffffLL) {
1058 /* would have been negative */
1059 (void)printf(" %llx\n",
1060 hideroot ? 0LL : (long long)kf->f_offset);
1061 } else
1062 (void)printf(" %lld\n",
1063 hideroot ? 0LL : (long long)kf->f_offset);
1064 }
1065}
1066
1067void
1068filemodeprep(void)
1069{
1070 int mib[2];
1071 size_t len;
1072
1073 if (nlistf == NULL((void *)0) && memf == NULL((void *)0)) {
1074 mib[0] = CTL_KERN1;
1075 mib[1] = KERN_MAXFILES7;
1076 len = sizeof(maxfile);
1077 if (sysctl(mib, 2, &maxfile, &len, NULL((void *)0), 0) < 0)
1078 err(1, "sysctl(KERN_MAXFILES) failed");
1079 if (totalflag) {
1080 mib[0] = CTL_KERN1;
1081 mib[1] = KERN_NFILES56;
1082 len = sizeof(nfile);
1083 if (sysctl(mib, 2, &nfile, &len, NULL((void *)0), 0) < 0)
1084 err(1, "sysctl(KERN_NFILES) failed");
1085 }
1086 }
1087
1088 if (!totalflag) {
1089 kf = kvm_getfiles(kd, KERN_FILE_BYFILE1, 0, sizeof *kf, &nfile);
1090 if (kf == NULL((void *)0)) {
1091 warnx("kvm_getfiles: %s", kvm_geterr(kd));
1092 return;
1093 }
1094 }
1095}
1096
1097/*
1098 * swapmode is based on a program called swapinfo written
1099 * by Kevin Lahey <kml@rokkaku.atl.ga.us>.
1100 */
1101void
1102swapmode(void)
1103{
1104 char *header;
1105 int hlen = 10, nswap;
1106 int bdiv, i, avail, nfree, npfree, used;
1107 long blocksize;
1108 struct swapent *swdev;
1109
1110 if (kflag) {
1111 header = "1K-blocks";
1112 blocksize = 1024;
1113 hlen = strlen(header);
1114 } else
1115 header = getbsize(&hlen, &blocksize);
1116
1117 nswap = swapctl(SWAP_NSWAP3, 0, 0);
1118 if (nswap == 0) {
1119 if (!totalflag)
1120 (void)printf("%-11s %*s %8s %8s %8s %s\n",
1121 "Device", hlen, header,
1122 "Used", "Avail", "Capacity", "Priority");
1123 (void)printf("%-11s %*d %8d %8d %5.0f%%\n",
1124 "Total", hlen, 0, 0, 0, 0.0);
1125 return;
1126 }
1127 if ((swdev = calloc(nswap, sizeof(*swdev))) == NULL((void *)0))
1128 err(1, "malloc");
1129 if (swapctl(SWAP_STATS4, swdev, nswap) == -1)
1130 err(1, "swapctl");
1131
1132 if (!totalflag)
1133 (void)printf("%-11s %*s %8s %8s %8s %s\n",
1134 "Device", hlen, header,
1135 "Used", "Avail", "Capacity", "Priority");
1136
1137 /* Run through swap list, doing the funky monkey. */
1138 bdiv = blocksize / DEV_BSIZE(1 << 9);
1139 avail = nfree = npfree = 0;
1140 for (i = 0; i < nswap; i++) {
1141 int xsize, xfree;
1142
1143 if (!(swdev[i].se_flags & SWF_ENABLE0x00000002))
1144 continue;
1145
1146 if (!totalflag) {
1147 if (usenumflag)
1148 (void)printf("%2u,%-2u %*d ",
1149 major(swdev[i].se_dev)(((unsigned)(swdev[i].se_dev) >> 8) & 0xff),
1150 minor(swdev[i].se_dev)((unsigned)((swdev[i].se_dev) & 0xff) | (((swdev[i].se_dev
) & 0xffff0000) >> 8))
,
1151 hlen, swdev[i].se_nblks / bdiv);
1152 else
1153 (void)printf("%-11s %*d ", swdev[i].se_path,
1154 hlen, swdev[i].se_nblks / bdiv);
1155 }
1156
1157 xsize = swdev[i].se_nblks;
1158 used = swdev[i].se_inuse;
1159 xfree = xsize - used;
1160 nfree += (xsize - used);
1161 npfree++;
1162 avail += xsize;
1163 if (totalflag)
1164 continue;
1165 (void)printf("%8d %8d %5.0f%% %d\n",
1166 used / bdiv, xfree / bdiv,
1167 (double)used / (double)xsize * 100.0,
1168 swdev[i].se_priority);
1169 }
1170 free(swdev);
1171
1172 /*
1173 * If only one partition has been set up via swapon(8), we don't
1174 * need to bother with totals.
1175 */
1176 used = avail - nfree;
1177 if (totalflag) {
1178 (void)printf("%dM/%dM swap space\n",
1179 used / (1048576 / DEV_BSIZE(1 << 9)),
1180 avail / (1048576 / DEV_BSIZE(1 << 9)));
1181 return;
1182 }
1183 if (npfree > 1) {
1184 (void)printf("%-11s %*d %8d %8d %5.0f%%\n",
1185 "Total", hlen, avail / bdiv, used / bdiv, nfree / bdiv,
1186 (double)used / (double)avail * 100.0);
1187 }
1188}
1189
1190static void __dead__attribute__((__noreturn__))
1191usage(void)
1192{
1193 (void)fprintf(stderr(&__sF[2]), "usage: "
1194 "pstat [-fknsTtv] [-M core] [-N system] [-d format symbol ...]\n");
1195 exit(1);
1196}