19b50d902SRodney W. Grimes /*- 20daf62d9SStanislav Sedov * Copyright (c) 2009 Stanislav Sedov <stas@FreeBSD.org> 39b50d902SRodney W. Grimes * Copyright (c) 1988, 1993 49b50d902SRodney W. Grimes * The Regents of the University of California. All rights reserved. 59b50d902SRodney W. Grimes * 69b50d902SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 79b50d902SRodney W. Grimes * modification, are permitted provided that the following conditions 89b50d902SRodney W. Grimes * are met: 99b50d902SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 109b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 119b50d902SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 129b50d902SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 139b50d902SRodney W. Grimes * documentation and/or other materials provided with the distribution. 149b50d902SRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 159b50d902SRodney W. Grimes * may be used to endorse or promote products derived from this software 169b50d902SRodney W. Grimes * without specific prior written permission. 179b50d902SRodney W. Grimes * 189b50d902SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 199b50d902SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 209b50d902SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 219b50d902SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 229b50d902SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 239b50d902SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 249b50d902SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 259b50d902SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 269b50d902SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 279b50d902SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 289b50d902SRodney W. Grimes * SUCH DAMAGE. 299b50d902SRodney W. Grimes */ 309b50d902SRodney W. Grimes 31e026a48cSDavid E. O'Brien #include <sys/cdefs.h> 32e026a48cSDavid E. O'Brien __FBSDID("$FreeBSD$"); 339b50d902SRodney W. Grimes 349b50d902SRodney W. Grimes #include <sys/param.h> 359b50d902SRodney W. Grimes #include <sys/user.h> 369b50d902SRodney W. Grimes #include <sys/stat.h> 379b50d902SRodney W. Grimes #include <sys/socket.h> 389b50d902SRodney W. Grimes #include <sys/socketvar.h> 399b50d902SRodney W. Grimes #include <sys/sysctl.h> 40d2bccb9fSDavid Greenman #include <sys/queue.h> 419b50d902SRodney W. Grimes 429b50d902SRodney W. Grimes #include <netinet/in.h> 439b50d902SRodney W. Grimes 440daf62d9SStanislav Sedov #include <assert.h> 459b50d902SRodney W. Grimes #include <ctype.h> 46c1e65942SPhilippe Charnier #include <err.h> 470daf62d9SStanislav Sedov #include <libprocstat.h> 48df3f5d9dSPeter Wemm #include <limits.h> 499b50d902SRodney W. Grimes #include <pwd.h> 5076db9ccfSWarner Losh #include <stdint.h> 519b50d902SRodney W. Grimes #include <stdio.h> 529b50d902SRodney W. Grimes #include <stdlib.h> 5305427aafSKonstantin Belousov #include <stddef.h> 549b50d902SRodney W. Grimes #include <string.h> 55df3f5d9dSPeter Wemm #include <unistd.h> 560b7a57ddSRuslan Ermilov #include <netdb.h> 579b50d902SRodney W. Grimes 580daf62d9SStanislav Sedov #include "functions.h" 599b50d902SRodney W. Grimes 60357050fcSEd Schouten static int fsflg, /* show files on same filesystem as file(s) argument */ 619b50d902SRodney W. Grimes pflg, /* show files open by a particular pid */ 629b50d902SRodney W. Grimes uflg; /* show files open by a particular (effective) user */ 63357050fcSEd Schouten static int checkfile; /* restrict to particular files or filesystems */ 64357050fcSEd Schouten static int nflg; /* (numerical) display f.s. and rdev as dev_t */ 65357050fcSEd Schouten static int mflg; /* include memory-mapped files */ 66357050fcSEd Schouten static int vflg; /* be verbose */ 679b50d902SRodney W. Grimes 680daf62d9SStanislav Sedov typedef struct devs { 690daf62d9SStanislav Sedov struct devs *next; 700daf62d9SStanislav Sedov uint32_t fsid; 710daf62d9SStanislav Sedov uint64_t ino; 720daf62d9SStanislav Sedov const char *name; 730daf62d9SStanislav Sedov } DEVS; 749b50d902SRodney W. Grimes 75357050fcSEd Schouten static DEVS *devs; 76357050fcSEd Schouten static char *memf, *nlistf; 779b50d902SRodney W. Grimes 780daf62d9SStanislav Sedov static int getfname(const char *filename); 790daf62d9SStanislav Sedov static void dofiles(struct procstat *procstat, struct kinfo_proc *p); 800daf62d9SStanislav Sedov static void print_access_flags(int flags); 810daf62d9SStanislav Sedov static void print_file_info(struct procstat *procstat, 820daf62d9SStanislav Sedov struct filestat *fst, const char *uname, const char *cmd, int pid); 830daf62d9SStanislav Sedov static void print_pipe_info(struct procstat *procstat, 840daf62d9SStanislav Sedov struct filestat *fst); 850daf62d9SStanislav Sedov static void print_pts_info(struct procstat *procstat, 860daf62d9SStanislav Sedov struct filestat *fst); 87*e506e182SJohn Baldwin static void print_shm_info(struct procstat *procstat, 88*e506e182SJohn Baldwin struct filestat *fst); 890daf62d9SStanislav Sedov static void print_socket_info(struct procstat *procstat, 900daf62d9SStanislav Sedov struct filestat *fst); 910daf62d9SStanislav Sedov static void print_vnode_info(struct procstat *procstat, 920daf62d9SStanislav Sedov struct filestat *fst); 930daf62d9SStanislav Sedov static void usage(void) __dead2; 941c17fc99SPeter Wemm 951c17fc99SPeter Wemm int 960daf62d9SStanislav Sedov do_fstat(int argc, char **argv) 979b50d902SRodney W. Grimes { 980daf62d9SStanislav Sedov struct kinfo_proc *p; 9927d57ea9SDavid Malone struct passwd *passwd; 1000daf62d9SStanislav Sedov struct procstat *procstat; 1019b50d902SRodney W. Grimes int arg, ch, what; 1020daf62d9SStanislav Sedov int cnt, i; 1039b50d902SRodney W. Grimes 1049b50d902SRodney W. Grimes arg = 0; 105f9feee17SEd Maste what = KERN_PROC_PROC; 1069b50d902SRodney W. Grimes nlistf = memf = NULL; 107d0482be8SBrian Feldman while ((ch = getopt(argc, argv, "fmnp:u:vN:M:")) != -1) 1089b50d902SRodney W. Grimes switch((char)ch) { 1099b50d902SRodney W. Grimes case 'f': 1109b50d902SRodney W. Grimes fsflg = 1; 1119b50d902SRodney W. Grimes break; 1129b50d902SRodney W. Grimes case 'M': 1139b50d902SRodney W. Grimes memf = optarg; 1149b50d902SRodney W. Grimes break; 1159b50d902SRodney W. Grimes case 'N': 1169b50d902SRodney W. Grimes nlistf = optarg; 1179b50d902SRodney W. Grimes break; 118d0482be8SBrian Feldman case 'm': 119d0482be8SBrian Feldman mflg = 1; 120d0482be8SBrian Feldman break; 1219b50d902SRodney W. Grimes case 'n': 1229b50d902SRodney W. Grimes nflg = 1; 1239b50d902SRodney W. Grimes break; 1249b50d902SRodney W. Grimes case 'p': 1259b50d902SRodney W. Grimes if (pflg++) 1269b50d902SRodney W. Grimes usage(); 1279b50d902SRodney W. Grimes if (!isdigit(*optarg)) { 128c1e65942SPhilippe Charnier warnx("-p requires a process id"); 1299b50d902SRodney W. Grimes usage(); 1309b50d902SRodney W. Grimes } 1319b50d902SRodney W. Grimes what = KERN_PROC_PID; 1329b50d902SRodney W. Grimes arg = atoi(optarg); 1339b50d902SRodney W. Grimes break; 1349b50d902SRodney W. Grimes case 'u': 1359b50d902SRodney W. Grimes if (uflg++) 1369b50d902SRodney W. Grimes usage(); 137c1e65942SPhilippe Charnier if (!(passwd = getpwnam(optarg))) 138c1e65942SPhilippe Charnier errx(1, "%s: unknown uid", optarg); 1399b50d902SRodney W. Grimes what = KERN_PROC_UID; 1409b50d902SRodney W. Grimes arg = passwd->pw_uid; 1419b50d902SRodney W. Grimes break; 1429b50d902SRodney W. Grimes case 'v': 1439b50d902SRodney W. Grimes vflg = 1; 1449b50d902SRodney W. Grimes break; 1459b50d902SRodney W. Grimes case '?': 1469b50d902SRodney W. Grimes default: 1479b50d902SRodney W. Grimes usage(); 1489b50d902SRodney W. Grimes } 1499b50d902SRodney W. Grimes 1509b50d902SRodney W. Grimes if (*(argv += optind)) { 1519b50d902SRodney W. Grimes for (; *argv; ++argv) { 1529b50d902SRodney W. Grimes if (getfname(*argv)) 1539b50d902SRodney W. Grimes checkfile = 1; 1549b50d902SRodney W. Grimes } 155487ac9acSUlrich Spörlein if (!checkfile) /* file(s) specified, but none accessible */ 1569b50d902SRodney W. Grimes exit(1); 1579b50d902SRodney W. Grimes } 1589b50d902SRodney W. Grimes 1599b50d902SRodney W. Grimes if (fsflg && !checkfile) { 1609b50d902SRodney W. Grimes /* -f with no files means use wd */ 1619b50d902SRodney W. Grimes if (getfname(".") == 0) 1629b50d902SRodney W. Grimes exit(1); 1639b50d902SRodney W. Grimes checkfile = 1; 1649b50d902SRodney W. Grimes } 1659b50d902SRodney W. Grimes 1661f910d6cSDag-Erling Smørgrav if (memf != NULL) 1670daf62d9SStanislav Sedov procstat = procstat_open_kvm(nlistf, memf); 1681f910d6cSDag-Erling Smørgrav else 1690daf62d9SStanislav Sedov procstat = procstat_open_sysctl(); 1700daf62d9SStanislav Sedov if (procstat == NULL) 1710daf62d9SStanislav Sedov errx(1, "procstat_open()"); 1720daf62d9SStanislav Sedov p = procstat_getprocs(procstat, what, arg, &cnt); 1730daf62d9SStanislav Sedov if (p == NULL) 1740daf62d9SStanislav Sedov errx(1, "procstat_getprocs()"); 1751f910d6cSDag-Erling Smørgrav 1760daf62d9SStanislav Sedov /* 1770daf62d9SStanislav Sedov * Print header. 1780daf62d9SStanislav Sedov */ 1791f910d6cSDag-Erling Smørgrav if (nflg) 1801f910d6cSDag-Erling Smørgrav printf("%s", 1811f910d6cSDag-Erling Smørgrav "USER CMD PID FD DEV INUM MODE SZ|DV R/W"); 1821f910d6cSDag-Erling Smørgrav else 1831f910d6cSDag-Erling Smørgrav printf("%s", 1841f910d6cSDag-Erling Smørgrav "USER CMD PID FD MOUNT INUM MODE SZ|DV R/W"); 1851f910d6cSDag-Erling Smørgrav if (checkfile && fsflg == 0) 1861f910d6cSDag-Erling Smørgrav printf(" NAME\n"); 1871f910d6cSDag-Erling Smørgrav else 1881f910d6cSDag-Erling Smørgrav putchar('\n'); 1890daf62d9SStanislav Sedov 1900daf62d9SStanislav Sedov /* 1910daf62d9SStanislav Sedov * Go through the process list. 1920daf62d9SStanislav Sedov */ 1930daf62d9SStanislav Sedov for (i = 0; i < cnt; i++) { 1940daf62d9SStanislav Sedov if (p[i].ki_stat == SZOMB) 1950daf62d9SStanislav Sedov continue; 1960daf62d9SStanislav Sedov dofiles(procstat, &p[i]); 1970daf62d9SStanislav Sedov } 1980daf62d9SStanislav Sedov procstat_freeprocs(procstat, p); 1990daf62d9SStanislav Sedov procstat_close(procstat); 2000daf62d9SStanislav Sedov return (0); 2011f910d6cSDag-Erling Smørgrav } 2021f910d6cSDag-Erling Smørgrav 2031f910d6cSDag-Erling Smørgrav static void 2040daf62d9SStanislav Sedov dofiles(struct procstat *procstat, struct kinfo_proc *kp) 2051f910d6cSDag-Erling Smørgrav { 2060daf62d9SStanislav Sedov const char *cmd; 2070daf62d9SStanislav Sedov const char *uname; 2080daf62d9SStanislav Sedov struct filestat *fst; 2090daf62d9SStanislav Sedov struct filestat_list *head; 2100daf62d9SStanislav Sedov int pid; 2111f910d6cSDag-Erling Smørgrav 2120daf62d9SStanislav Sedov uname = user_from_uid(kp->ki_uid, 0); 2130daf62d9SStanislav Sedov pid = kp->ki_pid; 2140daf62d9SStanislav Sedov cmd = kp->ki_comm; 2151f910d6cSDag-Erling Smørgrav 2160daf62d9SStanislav Sedov head = procstat_getfiles(procstat, kp, mflg); 2170daf62d9SStanislav Sedov if (head == NULL) 2180daf62d9SStanislav Sedov return; 2190daf62d9SStanislav Sedov STAILQ_FOREACH(fst, head, next) 2200daf62d9SStanislav Sedov print_file_info(procstat, fst, uname, cmd, pid); 2210daf62d9SStanislav Sedov procstat_freefiles(procstat, head); 2229b50d902SRodney W. Grimes } 2230daf62d9SStanislav Sedov 2241f910d6cSDag-Erling Smørgrav 2251f910d6cSDag-Erling Smørgrav static void 2260daf62d9SStanislav Sedov print_file_info(struct procstat *procstat, struct filestat *fst, 2270daf62d9SStanislav Sedov const char *uname, const char *cmd, int pid) 2281f910d6cSDag-Erling Smørgrav { 2290daf62d9SStanislav Sedov struct vnstat vn; 23027d57ea9SDavid Malone DEVS *d; 2310daf62d9SStanislav Sedov const char *filename; 2320daf62d9SStanislav Sedov int error, fsmatch = 0; 2330daf62d9SStanislav Sedov char errbuf[_POSIX2_LINE_MAX]; 2349b50d902SRodney W. Grimes 2350daf62d9SStanislav Sedov filename = NULL; 2360daf62d9SStanislav Sedov if (checkfile != 0) { 237b4fe201cSSergey Kandaurov if (fst->fs_type != PS_FST_TYPE_VNODE && 238b4fe201cSSergey Kandaurov fst->fs_type != PS_FST_TYPE_FIFO) 239e22c40faSSergey Kandaurov return; 240b4fe201cSSergey Kandaurov error = procstat_get_vnode_info(procstat, fst, &vn, errbuf); 2410daf62d9SStanislav Sedov if (error != 0) 2420daf62d9SStanislav Sedov return; 2430daf62d9SStanislav Sedov 2449b50d902SRodney W. Grimes for (d = devs; d != NULL; d = d->next) 2450daf62d9SStanislav Sedov if (d->fsid == vn.vn_fsid) { 2469b50d902SRodney W. Grimes fsmatch = 1; 2470daf62d9SStanislav Sedov if ((unsigned)d->ino == vn.vn_fileid) { 2489b50d902SRodney W. Grimes filename = d->name; 2499b50d902SRodney W. Grimes break; 2509b50d902SRodney W. Grimes } 2519b50d902SRodney W. Grimes } 2529b50d902SRodney W. Grimes if (fsmatch == 0 || (filename == NULL && fsflg == 0)) 2539b50d902SRodney W. Grimes return; 2549b50d902SRodney W. Grimes } 2559b50d902SRodney W. Grimes 2560daf62d9SStanislav Sedov /* 2570daf62d9SStanislav Sedov * Print entry prefix. 2580daf62d9SStanislav Sedov */ 2590daf62d9SStanislav Sedov printf("%-8.8s %-10s %5d", uname, cmd, pid); 2600daf62d9SStanislav Sedov if (fst->fs_uflags & PS_FST_UFLAG_TEXT) 2610daf62d9SStanislav Sedov printf(" text"); 2620daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_CDIR) 2630daf62d9SStanislav Sedov printf(" wd"); 2640daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_RDIR) 2650daf62d9SStanislav Sedov printf(" root"); 2660daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_TRACE) 2670daf62d9SStanislav Sedov printf(" tr"); 2680daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_MMAP) 2690daf62d9SStanislav Sedov printf(" mmap"); 2700daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_JAIL) 2710daf62d9SStanislav Sedov printf(" jail"); 2720daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_CTTY) 2730daf62d9SStanislav Sedov printf(" ctty"); 2740daf62d9SStanislav Sedov else 2750daf62d9SStanislav Sedov printf(" %4d", fst->fs_fd); 2760daf62d9SStanislav Sedov 2770daf62d9SStanislav Sedov /* 2780daf62d9SStanislav Sedov * Print type-specific data. 2790daf62d9SStanislav Sedov */ 2800daf62d9SStanislav Sedov switch (fst->fs_type) { 2810daf62d9SStanislav Sedov case PS_FST_TYPE_FIFO: 2820daf62d9SStanislav Sedov case PS_FST_TYPE_VNODE: 2830daf62d9SStanislav Sedov print_vnode_info(procstat, fst); 2849b50d902SRodney W. Grimes break; 2850daf62d9SStanislav Sedov case PS_FST_TYPE_SOCKET: 2860daf62d9SStanislav Sedov print_socket_info(procstat, fst); 2870daf62d9SStanislav Sedov break; 2880daf62d9SStanislav Sedov case PS_FST_TYPE_PIPE: 2890daf62d9SStanislav Sedov print_pipe_info(procstat, fst); 2900daf62d9SStanislav Sedov break; 2910daf62d9SStanislav Sedov case PS_FST_TYPE_PTS: 2920daf62d9SStanislav Sedov print_pts_info(procstat, fst); 2930daf62d9SStanislav Sedov break; 294*e506e182SJohn Baldwin case PS_FST_TYPE_SHM: 295*e506e182SJohn Baldwin print_shm_info(procstat, fst); 296*e506e182SJohn Baldwin break; 2979b50d902SRodney W. Grimes default: 2980daf62d9SStanislav Sedov if (vflg) 2990daf62d9SStanislav Sedov fprintf(stderr, 3000daf62d9SStanislav Sedov "unknown file type %d for file %d of pid %d\n", 3010daf62d9SStanislav Sedov fst->fs_type, fst->fs_fd, pid); 3029b50d902SRodney W. Grimes } 3039b50d902SRodney W. Grimes if (filename && !fsflg) 3049b50d902SRodney W. Grimes printf(" %s", filename); 3059b50d902SRodney W. Grimes putchar('\n'); 3069b50d902SRodney W. Grimes } 3079b50d902SRodney W. Grimes 3080daf62d9SStanislav Sedov static void 3090daf62d9SStanislav Sedov print_socket_info(struct procstat *procstat, struct filestat *fst) 3109b50d902SRodney W. Grimes { 31127d57ea9SDavid Malone static const char *stypename[] = { 3129b50d902SRodney W. Grimes "unused", /* 0 */ 3139b50d902SRodney W. Grimes "stream", /* 1 */ 3149b50d902SRodney W. Grimes "dgram", /* 2 */ 3159b50d902SRodney W. Grimes "raw", /* 3 */ 3169b50d902SRodney W. Grimes "rdm", /* 4 */ 3179b50d902SRodney W. Grimes "seqpak" /* 5 */ 3189b50d902SRodney W. Grimes }; 3199b50d902SRodney W. Grimes #define STYPEMAX 5 3200daf62d9SStanislav Sedov struct sockstat sock; 3210daf62d9SStanislav Sedov struct protoent *pe; 3220daf62d9SStanislav Sedov char errbuf[_POSIX2_LINE_MAX]; 3230daf62d9SStanislav Sedov int error; 3240daf62d9SStanislav Sedov static int isopen; 3259b50d902SRodney W. Grimes 3260daf62d9SStanislav Sedov error = procstat_get_socket_info(procstat, fst, &sock, errbuf); 3270daf62d9SStanislav Sedov if (error != 0) { 3280daf62d9SStanislav Sedov printf("* error"); 3290daf62d9SStanislav Sedov return; 3309b50d902SRodney W. Grimes } 3310daf62d9SStanislav Sedov if (sock.type > STYPEMAX) 3320daf62d9SStanislav Sedov printf("* %s ?%d", sock.dname, sock.type); 3339b50d902SRodney W. Grimes else 3340daf62d9SStanislav Sedov printf("* %s %s", sock.dname, stypename[sock.type]); 3359b50d902SRodney W. Grimes 3369b50d902SRodney W. Grimes /* 3379b50d902SRodney W. Grimes * protocol specific formatting 3389b50d902SRodney W. Grimes * 3399b50d902SRodney W. Grimes * Try to find interesting things to print. For tcp, the interesting 3409b50d902SRodney W. Grimes * thing is the address of the tcpcb, for udp and others, just the 3419b50d902SRodney W. Grimes * inpcb (socket pcb). For unix domain, its the address of the socket 3429b50d902SRodney W. Grimes * pcb and the address of the connected pcb (if connected). Otherwise 3439b50d902SRodney W. Grimes * just print the protocol number and address of the socket itself. 3449b50d902SRodney W. Grimes * The idea is not to duplicate netstat, but to make available enough 3459b50d902SRodney W. Grimes * information for further analysis. 3469b50d902SRodney W. Grimes */ 3470daf62d9SStanislav Sedov switch (sock.dom_family) { 3489b50d902SRodney W. Grimes case AF_INET: 349677e00c0SYoshinobu Inoue case AF_INET6: 3500daf62d9SStanislav Sedov if (!isopen) 3510daf62d9SStanislav Sedov setprotoent(++isopen); 3520daf62d9SStanislav Sedov if ((pe = getprotobynumber(sock.proto)) != NULL) 3530daf62d9SStanislav Sedov printf(" %s", pe->p_name); 3540daf62d9SStanislav Sedov else 3550daf62d9SStanislav Sedov printf(" %d", sock.proto); 3560daf62d9SStanislav Sedov if (sock.proto == IPPROTO_TCP ) { 3570daf62d9SStanislav Sedov if (sock.inp_ppcb != 0) 3580daf62d9SStanislav Sedov printf(" %lx", (u_long)sock.inp_ppcb); 3599b50d902SRodney W. Grimes } 3600daf62d9SStanislav Sedov else if (sock.so_pcb != 0) 3610daf62d9SStanislav Sedov printf(" %lx", (u_long)sock.so_pcb); 3629b50d902SRodney W. Grimes break; 3639b50d902SRodney W. Grimes case AF_UNIX: 3649b50d902SRodney W. Grimes /* print address of pcb and connected pcb */ 3650daf62d9SStanislav Sedov if (sock.so_pcb != 0) { 3660daf62d9SStanislav Sedov printf(" %lx", (u_long)sock.so_pcb); 3670daf62d9SStanislav Sedov if (sock.unp_conn) { 3689b50d902SRodney W. Grimes char shoconn[4], *cp; 3699b50d902SRodney W. Grimes 3709b50d902SRodney W. Grimes cp = shoconn; 3710daf62d9SStanislav Sedov if (!(sock.so_rcv_sb_state & SBS_CANTRCVMORE)) 3729b50d902SRodney W. Grimes *cp++ = '<'; 3739b50d902SRodney W. Grimes *cp++ = '-'; 3740daf62d9SStanislav Sedov if (!(sock.so_snd_sb_state & SBS_CANTSENDMORE)) 3759b50d902SRodney W. Grimes *cp++ = '>'; 3769b50d902SRodney W. Grimes *cp = '\0'; 377df94d4d2SMatt Jacob printf(" %s %lx", shoconn, 3780daf62d9SStanislav Sedov (u_long)sock.unp_conn); 3799b50d902SRodney W. Grimes } 3809b50d902SRodney W. Grimes } 3819b50d902SRodney W. Grimes break; 3829b50d902SRodney W. Grimes default: 3839b50d902SRodney W. Grimes /* print protocol number and socket address */ 3840daf62d9SStanislav Sedov printf(" %d %lx", sock.proto, (u_long)sock.so_addr); 3859b50d902SRodney W. Grimes } 3869b50d902SRodney W. Grimes } 3879b50d902SRodney W. Grimes 3880daf62d9SStanislav Sedov static void 3890daf62d9SStanislav Sedov print_pipe_info(struct procstat *procstat, struct filestat *fst) 390bc093719SEd Schouten { 3910daf62d9SStanislav Sedov struct pipestat ps; 3920daf62d9SStanislav Sedov char errbuf[_POSIX2_LINE_MAX]; 3930daf62d9SStanislav Sedov int error; 3940daf62d9SStanislav Sedov 3950daf62d9SStanislav Sedov error = procstat_get_pipe_info(procstat, fst, &ps, errbuf); 3960daf62d9SStanislav Sedov if (error != 0) { 3970daf62d9SStanislav Sedov printf("* error"); 3980daf62d9SStanislav Sedov return; 3990daf62d9SStanislav Sedov } 4000daf62d9SStanislav Sedov printf("* pipe %8lx <-> %8lx", (u_long)ps.addr, (u_long)ps.peer); 4010daf62d9SStanislav Sedov printf(" %6zd", ps.buffer_cnt); 4020daf62d9SStanislav Sedov print_access_flags(fst->fs_fflags); 4030daf62d9SStanislav Sedov } 4040daf62d9SStanislav Sedov 4050daf62d9SStanislav Sedov static void 4060daf62d9SStanislav Sedov print_pts_info(struct procstat *procstat, struct filestat *fst) 4070daf62d9SStanislav Sedov { 4080daf62d9SStanislav Sedov struct ptsstat pts; 4090daf62d9SStanislav Sedov char errbuf[_POSIX2_LINE_MAX]; 4100daf62d9SStanislav Sedov int error; 4110daf62d9SStanislav Sedov 4120daf62d9SStanislav Sedov error = procstat_get_pts_info(procstat, fst, &pts, errbuf); 4130daf62d9SStanislav Sedov if (error != 0) { 4140daf62d9SStanislav Sedov printf("* error"); 4150daf62d9SStanislav Sedov return; 4160daf62d9SStanislav Sedov } 4170daf62d9SStanislav Sedov printf("* pseudo-terminal master "); 4180daf62d9SStanislav Sedov if (nflg || !*pts.devname) { 4199f365aa1SEd Schouten printf("%#10jx", (uintmax_t)pts.dev); 4200daf62d9SStanislav Sedov } else { 4210daf62d9SStanislav Sedov printf("%10s", pts.devname); 4220daf62d9SStanislav Sedov } 4230daf62d9SStanislav Sedov print_access_flags(fst->fs_fflags); 4240daf62d9SStanislav Sedov } 4250daf62d9SStanislav Sedov 4260daf62d9SStanislav Sedov static void 427*e506e182SJohn Baldwin print_shm_info(struct procstat *procstat, struct filestat *fst) 428*e506e182SJohn Baldwin { 429*e506e182SJohn Baldwin struct shmstat shm; 430*e506e182SJohn Baldwin char errbuf[_POSIX2_LINE_MAX]; 431*e506e182SJohn Baldwin char mode[15]; 432*e506e182SJohn Baldwin int error; 433*e506e182SJohn Baldwin 434*e506e182SJohn Baldwin error = procstat_get_shm_info(procstat, fst, &shm, errbuf); 435*e506e182SJohn Baldwin if (error != 0) { 436*e506e182SJohn Baldwin printf("* error"); 437*e506e182SJohn Baldwin return; 438*e506e182SJohn Baldwin } 439*e506e182SJohn Baldwin if (nflg) { 440*e506e182SJohn Baldwin printf(" "); 441*e506e182SJohn Baldwin (void)snprintf(mode, sizeof(mode), "%o", shm.mode); 442*e506e182SJohn Baldwin } else { 443*e506e182SJohn Baldwin printf(" %-15s", fst->fs_path != NULL ? fst->fs_path : "-"); 444*e506e182SJohn Baldwin strmode(shm.mode, mode); 445*e506e182SJohn Baldwin } 446*e506e182SJohn Baldwin printf(" %10s %6ju", mode, shm.size); 447*e506e182SJohn Baldwin print_access_flags(fst->fs_fflags); 448*e506e182SJohn Baldwin } 449*e506e182SJohn Baldwin 450*e506e182SJohn Baldwin static void 4510daf62d9SStanislav Sedov print_vnode_info(struct procstat *procstat, struct filestat *fst) 4520daf62d9SStanislav Sedov { 4530daf62d9SStanislav Sedov struct vnstat vn; 4540daf62d9SStanislav Sedov char errbuf[_POSIX2_LINE_MAX]; 4550daf62d9SStanislav Sedov char mode[15]; 4560daf62d9SStanislav Sedov const char *badtype; 4570daf62d9SStanislav Sedov int error; 4580daf62d9SStanislav Sedov 4590daf62d9SStanislav Sedov badtype = NULL; 4600daf62d9SStanislav Sedov error = procstat_get_vnode_info(procstat, fst, &vn, errbuf); 4610daf62d9SStanislav Sedov if (error != 0) 4620daf62d9SStanislav Sedov badtype = errbuf; 4630daf62d9SStanislav Sedov else if (vn.vn_type == PS_FST_VTYPE_VBAD) 4640daf62d9SStanislav Sedov badtype = "bad"; 4650daf62d9SStanislav Sedov else if (vn.vn_type == PS_FST_VTYPE_VNON) 4660daf62d9SStanislav Sedov badtype = "none"; 4670daf62d9SStanislav Sedov if (badtype != NULL) { 4680daf62d9SStanislav Sedov printf(" - - %10s -", badtype); 4690daf62d9SStanislav Sedov return; 4700daf62d9SStanislav Sedov } 4710daf62d9SStanislav Sedov 4720daf62d9SStanislav Sedov if (nflg) 47305806a06SEd Schouten printf(" %#5jx", (uintmax_t)vn.vn_fsid); 4740daf62d9SStanislav Sedov else if (vn.vn_mntdir != NULL) 4750daf62d9SStanislav Sedov (void)printf(" %-8s", vn.vn_mntdir); 4760daf62d9SStanislav Sedov 4770daf62d9SStanislav Sedov /* 4780daf62d9SStanislav Sedov * Print access mode. 4790daf62d9SStanislav Sedov */ 4800daf62d9SStanislav Sedov if (nflg) 4810daf62d9SStanislav Sedov (void)snprintf(mode, sizeof(mode), "%o", vn.vn_mode); 4820daf62d9SStanislav Sedov else { 4830daf62d9SStanislav Sedov strmode(vn.vn_mode, mode); 4840daf62d9SStanislav Sedov } 48576db9ccfSWarner Losh (void)printf(" %6jd %10s", (intmax_t)vn.vn_fileid, mode); 4860daf62d9SStanislav Sedov 4870daf62d9SStanislav Sedov if (vn.vn_type == PS_FST_VTYPE_VBLK || vn.vn_type == PS_FST_VTYPE_VCHR) { 4880daf62d9SStanislav Sedov if (nflg || !*vn.vn_devname) 4899f365aa1SEd Schouten printf(" %#6jx", (uintmax_t)vn.vn_dev); 4900daf62d9SStanislav Sedov else { 4910daf62d9SStanislav Sedov printf(" %6s", vn.vn_devname); 4920daf62d9SStanislav Sedov } 4930daf62d9SStanislav Sedov } else 4948d917b4bSWarner Losh printf(" %6ju", (uintmax_t)vn.vn_size); 4950daf62d9SStanislav Sedov print_access_flags(fst->fs_fflags); 4960daf62d9SStanislav Sedov } 4970daf62d9SStanislav Sedov 4980daf62d9SStanislav Sedov static void 4990daf62d9SStanislav Sedov print_access_flags(int flags) 5000daf62d9SStanislav Sedov { 501bc093719SEd Schouten char rw[3]; 502bc093719SEd Schouten 503bc093719SEd Schouten rw[0] = '\0'; 5040daf62d9SStanislav Sedov if (flags & PS_FST_FFLAG_READ) 505bc093719SEd Schouten strcat(rw, "r"); 5060daf62d9SStanislav Sedov if (flags & PS_FST_FFLAG_WRITE) 507bc093719SEd Schouten strcat(rw, "w"); 5080daf62d9SStanislav Sedov printf(" %2s", rw); 5099b50d902SRodney W. Grimes } 5109b50d902SRodney W. Grimes 5111c17fc99SPeter Wemm int 5121e925017SDavid Malone getfname(const char *filename) 5139b50d902SRodney W. Grimes { 5149b50d902SRodney W. Grimes struct stat statbuf; 5159b50d902SRodney W. Grimes DEVS *cur; 5169b50d902SRodney W. Grimes 5179b50d902SRodney W. Grimes if (stat(filename, &statbuf)) { 518c1e65942SPhilippe Charnier warn("%s", filename); 5199b50d902SRodney W. Grimes return (0); 5209b50d902SRodney W. Grimes } 521c1e65942SPhilippe Charnier if ((cur = malloc(sizeof(DEVS))) == NULL) 522c1e65942SPhilippe Charnier err(1, NULL); 5239b50d902SRodney W. Grimes cur->next = devs; 5249b50d902SRodney W. Grimes devs = cur; 5259b50d902SRodney W. Grimes 5269b50d902SRodney W. Grimes cur->ino = statbuf.st_ino; 527b628b0dcSDavid Malone cur->fsid = statbuf.st_dev; 5289b50d902SRodney W. Grimes cur->name = filename; 5299b50d902SRodney W. Grimes return (1); 5309b50d902SRodney W. Grimes } 5319b50d902SRodney W. Grimes 5320daf62d9SStanislav Sedov static void 5331e925017SDavid Malone usage(void) 5349b50d902SRodney W. Grimes { 5359b50d902SRodney W. Grimes (void)fprintf(stderr, 536f682f10cSRuslan Ermilov "usage: fstat [-fmnv] [-M core] [-N system] [-p pid] [-u user] [file ...]\n"); 5379b50d902SRodney W. Grimes exit(1); 5389b50d902SRodney W. Grimes } 539