13d91be41SRobert Watson /*- 2d57486e2SRobert Watson * Copyright (c) 2007-2011 Robert N. M. Watson 33d91be41SRobert Watson * All rights reserved. 43d91be41SRobert Watson * 53d91be41SRobert Watson * Redistribution and use in source and binary forms, with or without 63d91be41SRobert Watson * modification, are permitted provided that the following conditions 73d91be41SRobert Watson * are met: 83d91be41SRobert Watson * 1. Redistributions of source code must retain the above copyright 93d91be41SRobert Watson * notice, this list of conditions and the following disclaimer. 103d91be41SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 113d91be41SRobert Watson * notice, this list of conditions and the following disclaimer in the 123d91be41SRobert Watson * documentation and/or other materials provided with the distribution. 133d91be41SRobert Watson * 143d91be41SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 153d91be41SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 163d91be41SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 173d91be41SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 183d91be41SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 193d91be41SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 203d91be41SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 213d91be41SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 223d91be41SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 233d91be41SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 243d91be41SRobert Watson * SUCH DAMAGE. 253d91be41SRobert Watson * 263d91be41SRobert Watson * $FreeBSD$ 273d91be41SRobert Watson */ 283d91be41SRobert Watson 29e1f323f3SRobert Watson #include <sys/param.h> 30d57486e2SRobert Watson #include <sys/capability.h> 313d91be41SRobert Watson #include <sys/socket.h> 323d91be41SRobert Watson #include <sys/sysctl.h> 333d91be41SRobert Watson #include <sys/un.h> 343d91be41SRobert Watson #include <sys/user.h> 353d91be41SRobert Watson 363d91be41SRobert Watson #include <netinet/in.h> 373d91be41SRobert Watson 383d91be41SRobert Watson #include <arpa/inet.h> 393d91be41SRobert Watson 40821df508SXin LI #include <err.h> 410daf62d9SStanislav Sedov #include <libprocstat.h> 423d91be41SRobert Watson #include <inttypes.h> 433d91be41SRobert Watson #include <stdio.h> 443d91be41SRobert Watson #include <stdlib.h> 453d91be41SRobert Watson #include <string.h> 463d91be41SRobert Watson 473d91be41SRobert Watson #include "procstat.h" 483d91be41SRobert Watson 493d91be41SRobert Watson static const char * 503d91be41SRobert Watson protocol_to_string(int domain, int type, int protocol) 513d91be41SRobert Watson { 523d91be41SRobert Watson 533d91be41SRobert Watson switch (domain) { 543d91be41SRobert Watson case AF_INET: 553d91be41SRobert Watson case AF_INET6: 563d91be41SRobert Watson switch (protocol) { 573d91be41SRobert Watson case IPPROTO_TCP: 583d91be41SRobert Watson return ("TCP"); 593d91be41SRobert Watson case IPPROTO_UDP: 603d91be41SRobert Watson return ("UDP"); 613d91be41SRobert Watson case IPPROTO_ICMP: 625a246d29SRobert Watson return ("ICM"); 633d91be41SRobert Watson case IPPROTO_RAW: 643d91be41SRobert Watson return ("RAW"); 653d91be41SRobert Watson case IPPROTO_SCTP: 665a246d29SRobert Watson return ("SCT"); 675a246d29SRobert Watson case IPPROTO_DIVERT: 685a246d29SRobert Watson return ("IPD"); 693d91be41SRobert Watson default: 705a246d29SRobert Watson return ("IP?"); 713d91be41SRobert Watson } 723d91be41SRobert Watson 733d91be41SRobert Watson case AF_LOCAL: 743d91be41SRobert Watson switch (type) { 753d91be41SRobert Watson case SOCK_STREAM: 765a246d29SRobert Watson return ("UDS"); 773d91be41SRobert Watson case SOCK_DGRAM: 785a246d29SRobert Watson return ("UDD"); 793d91be41SRobert Watson default: 805a246d29SRobert Watson return ("UD?"); 813d91be41SRobert Watson } 823d91be41SRobert Watson default: 835a246d29SRobert Watson return ("?"); 843d91be41SRobert Watson } 853d91be41SRobert Watson } 863d91be41SRobert Watson 873d91be41SRobert Watson static void 883d91be41SRobert Watson addr_to_string(struct sockaddr_storage *ss, char *buffer, int buflen) 893d91be41SRobert Watson { 903d91be41SRobert Watson char buffer2[INET6_ADDRSTRLEN]; 913d91be41SRobert Watson struct sockaddr_in6 *sin6; 923d91be41SRobert Watson struct sockaddr_in *sin; 933d91be41SRobert Watson struct sockaddr_un *sun; 943d91be41SRobert Watson 953d91be41SRobert Watson switch (ss->ss_family) { 963d91be41SRobert Watson case AF_LOCAL: 973d91be41SRobert Watson sun = (struct sockaddr_un *)ss; 983d91be41SRobert Watson if (strlen(sun->sun_path) == 0) 993d91be41SRobert Watson strlcpy(buffer, "-", buflen); 1003d91be41SRobert Watson else 1013d91be41SRobert Watson strlcpy(buffer, sun->sun_path, buflen); 1023d91be41SRobert Watson break; 1033d91be41SRobert Watson 1043d91be41SRobert Watson case AF_INET: 1053d91be41SRobert Watson sin = (struct sockaddr_in *)ss; 1063d91be41SRobert Watson snprintf(buffer, buflen, "%s:%d", inet_ntoa(sin->sin_addr), 1073d91be41SRobert Watson ntohs(sin->sin_port)); 1083d91be41SRobert Watson break; 1093d91be41SRobert Watson 1103d91be41SRobert Watson case AF_INET6: 1113d91be41SRobert Watson sin6 = (struct sockaddr_in6 *)ss; 1123d91be41SRobert Watson if (inet_ntop(AF_INET6, &sin6->sin6_addr, buffer2, 1133d91be41SRobert Watson sizeof(buffer2)) != NULL) 1143d91be41SRobert Watson snprintf(buffer, buflen, "%s.%d", buffer2, 1153d91be41SRobert Watson ntohs(sin6->sin6_port)); 1163d91be41SRobert Watson else 1173d91be41SRobert Watson strlcpy(buffer, "-", sizeof(buffer)); 1183d91be41SRobert Watson break; 1193d91be41SRobert Watson 1203d91be41SRobert Watson default: 1213d91be41SRobert Watson strlcpy(buffer, "", buflen); 1223d91be41SRobert Watson break; 1233d91be41SRobert Watson } 1243d91be41SRobert Watson } 1253d91be41SRobert Watson 1263d91be41SRobert Watson static void 1273d91be41SRobert Watson print_address(struct sockaddr_storage *ss) 1283d91be41SRobert Watson { 1293d91be41SRobert Watson char addr[PATH_MAX]; 1303d91be41SRobert Watson 1313d91be41SRobert Watson addr_to_string(ss, addr, sizeof(addr)); 1325a246d29SRobert Watson printf("%s", addr); 1333d91be41SRobert Watson } 1343d91be41SRobert Watson 135d57486e2SRobert Watson static struct cap_desc { 136d57486e2SRobert Watson cap_rights_t cd_right; 137d57486e2SRobert Watson const char *cd_desc; 138d57486e2SRobert Watson } cap_desc[] = { 139d57486e2SRobert Watson /* General file I/O. */ 140d57486e2SRobert Watson { CAP_READ, "rd" }, 141d57486e2SRobert Watson { CAP_WRITE, "wr" }, 1422609222aSPawel Jakub Dawidek { CAP_SEEK, "se" }, 143d57486e2SRobert Watson { CAP_MMAP, "mm" }, 1442609222aSPawel Jakub Dawidek { CAP_CREATE, "cr" }, 145d57486e2SRobert Watson { CAP_FEXECVE, "fe" }, 146d57486e2SRobert Watson { CAP_FSYNC, "fy" }, 147d57486e2SRobert Watson { CAP_FTRUNCATE, "ft" }, 148d57486e2SRobert Watson 149d57486e2SRobert Watson /* VFS methods. */ 150d57486e2SRobert Watson { CAP_FCHDIR, "cd" }, 1512609222aSPawel Jakub Dawidek { CAP_FCHFLAGS, "cf" }, 152d57486e2SRobert Watson { CAP_FCHMOD, "cm" }, 153d57486e2SRobert Watson { CAP_FCHOWN, "cn" }, 154d57486e2SRobert Watson { CAP_FCNTL, "fc" }, 155d57486e2SRobert Watson { CAP_FLOCK, "fl" }, 1562609222aSPawel Jakub Dawidek { CAP_FPATHCONF, "fp" }, 157d57486e2SRobert Watson { CAP_FSCK, "fk" }, 158d57486e2SRobert Watson { CAP_FSTAT, "fs" }, 159d57486e2SRobert Watson { CAP_FSTATFS, "sf" }, 160d57486e2SRobert Watson { CAP_FUTIMES, "fu" }, 1612609222aSPawel Jakub Dawidek { CAP_LINKAT, "li" }, 1622609222aSPawel Jakub Dawidek { CAP_MKDIRAT, "md" }, 1632609222aSPawel Jakub Dawidek { CAP_MKFIFOAT, "mf" }, 1642609222aSPawel Jakub Dawidek { CAP_MKNODAT, "mn" }, 1652609222aSPawel Jakub Dawidek { CAP_RENAMEAT, "rn" }, 1662609222aSPawel Jakub Dawidek { CAP_SYMLINKAT, "sl" }, 1672609222aSPawel Jakub Dawidek { CAP_UNLINKAT, "un" }, 168d57486e2SRobert Watson 1692609222aSPawel Jakub Dawidek /* Lookups - used to constrain *at() calls. */ 170d57486e2SRobert Watson { CAP_LOOKUP, "lo" }, 171d57486e2SRobert Watson 172d57486e2SRobert Watson /* Extended attributes. */ 173d57486e2SRobert Watson { CAP_EXTATTR_GET, "eg" }, 174d57486e2SRobert Watson { CAP_EXTATTR_SET, "es" }, 175d57486e2SRobert Watson { CAP_EXTATTR_DELETE, "ed" }, 176d57486e2SRobert Watson { CAP_EXTATTR_LIST, "el" }, 177d57486e2SRobert Watson 178d57486e2SRobert Watson /* Access Control Lists. */ 179d57486e2SRobert Watson { CAP_ACL_GET, "ag" }, 180d57486e2SRobert Watson { CAP_ACL_SET, "as" }, 181d57486e2SRobert Watson { CAP_ACL_DELETE, "ad" }, 182d57486e2SRobert Watson { CAP_ACL_CHECK, "ac" }, 183d57486e2SRobert Watson 184d57486e2SRobert Watson /* Socket operations. */ 185d57486e2SRobert Watson { CAP_ACCEPT, "at" }, 186d57486e2SRobert Watson { CAP_BIND, "bd" }, 187d57486e2SRobert Watson { CAP_CONNECT, "co" }, 188d57486e2SRobert Watson { CAP_GETPEERNAME, "pn" }, 189d57486e2SRobert Watson { CAP_GETSOCKNAME, "sn" }, 190d57486e2SRobert Watson { CAP_GETSOCKOPT, "gs" }, 191d57486e2SRobert Watson { CAP_LISTEN, "ln" }, 192d57486e2SRobert Watson { CAP_PEELOFF, "pf" }, 193d57486e2SRobert Watson { CAP_SETSOCKOPT, "ss" }, 194d57486e2SRobert Watson { CAP_SHUTDOWN, "sh" }, 195d57486e2SRobert Watson 196d57486e2SRobert Watson /* Mandatory Access Control. */ 197d57486e2SRobert Watson { CAP_MAC_GET, "mg" }, 198d57486e2SRobert Watson { CAP_MAC_SET, "ms" }, 199d57486e2SRobert Watson 200d57486e2SRobert Watson /* Methods on semaphores. */ 201d57486e2SRobert Watson { CAP_SEM_GETVALUE, "sg" }, 202d57486e2SRobert Watson { CAP_SEM_POST, "sp" }, 203d57486e2SRobert Watson { CAP_SEM_WAIT, "sw" }, 204d57486e2SRobert Watson 205d57486e2SRobert Watson /* Event monitoring and posting. */ 206d57486e2SRobert Watson { CAP_POLL_EVENT, "po" }, 207d57486e2SRobert Watson { CAP_POST_EVENT, "ev" }, 208d57486e2SRobert Watson 209d57486e2SRobert Watson /* Strange and powerful rights that should not be given lightly. */ 210d57486e2SRobert Watson { CAP_IOCTL, "io" }, 211d57486e2SRobert Watson { CAP_TTYHOOK, "ty" }, 212d57486e2SRobert Watson 2136a9f247cSPawel Jakub Dawidek /* Process management via process descriptors. */ 214d57486e2SRobert Watson { CAP_PDGETPID, "pg" }, 2156a9f247cSPawel Jakub Dawidek { CAP_PDWAIT, "pw" }, 216d57486e2SRobert Watson { CAP_PDKILL, "pk" }, 2172609222aSPawel Jakub Dawidek 218*7493f24eSPawel Jakub Dawidek /* 219*7493f24eSPawel Jakub Dawidek * Rights that allow to use bindat(2) and connectat(2) syscalls on a 220*7493f24eSPawel Jakub Dawidek * directory descriptor. 221*7493f24eSPawel Jakub Dawidek */ 222*7493f24eSPawel Jakub Dawidek { CAP_BINDAT, "ba" }, 223*7493f24eSPawel Jakub Dawidek { CAP_CONNECTAT, "ca" }, 224*7493f24eSPawel Jakub Dawidek 2252609222aSPawel Jakub Dawidek /* Aliases and defines that combine multiple rights. */ 2262609222aSPawel Jakub Dawidek { CAP_PREAD, "prd" }, 2272609222aSPawel Jakub Dawidek { CAP_PWRITE, "pwr" }, 2282609222aSPawel Jakub Dawidek 2292609222aSPawel Jakub Dawidek { CAP_MMAP_R, "mmr" }, 2302609222aSPawel Jakub Dawidek { CAP_MMAP_W, "mmw" }, 2312609222aSPawel Jakub Dawidek { CAP_MMAP_X, "mmx" }, 2322609222aSPawel Jakub Dawidek { CAP_MMAP_RW, "mrw" }, 2332609222aSPawel Jakub Dawidek { CAP_MMAP_RX, "mrx" }, 2342609222aSPawel Jakub Dawidek { CAP_MMAP_WX, "mwx" }, 2352609222aSPawel Jakub Dawidek { CAP_MMAP_RWX, "mma" }, 2362609222aSPawel Jakub Dawidek 2372609222aSPawel Jakub Dawidek { CAP_RECV, "re" }, 2382609222aSPawel Jakub Dawidek { CAP_SEND, "sd" }, 2392609222aSPawel Jakub Dawidek 2402609222aSPawel Jakub Dawidek { CAP_SOCK_CLIENT, "scl" }, 2412609222aSPawel Jakub Dawidek { CAP_SOCK_SERVER, "ssr" }, 242d57486e2SRobert Watson }; 243d57486e2SRobert Watson static const u_int cap_desc_count = sizeof(cap_desc) / 244d57486e2SRobert Watson sizeof(cap_desc[0]); 245d57486e2SRobert Watson 246d57486e2SRobert Watson static u_int 247d57486e2SRobert Watson width_capability(cap_rights_t rights) 248d57486e2SRobert Watson { 249d57486e2SRobert Watson u_int count, i, width; 250d57486e2SRobert Watson 251d57486e2SRobert Watson count = 0; 252d57486e2SRobert Watson width = 0; 253d57486e2SRobert Watson for (i = 0; i < cap_desc_count; i++) { 2542609222aSPawel Jakub Dawidek if ((cap_desc[i].cd_right & ~rights) == 0) { 255d57486e2SRobert Watson width += strlen(cap_desc[i].cd_desc); 256d57486e2SRobert Watson if (count) 257d57486e2SRobert Watson width++; 258d57486e2SRobert Watson count++; 259d57486e2SRobert Watson } 260d57486e2SRobert Watson } 261d57486e2SRobert Watson return (width); 262d57486e2SRobert Watson } 263d57486e2SRobert Watson 264d57486e2SRobert Watson static void 265d57486e2SRobert Watson print_capability(cap_rights_t rights, u_int capwidth) 266d57486e2SRobert Watson { 267d57486e2SRobert Watson u_int count, i, width; 268d57486e2SRobert Watson 269d57486e2SRobert Watson count = 0; 270d57486e2SRobert Watson width = 0; 271d57486e2SRobert Watson for (i = width_capability(rights); i < capwidth; i++) { 272d57486e2SRobert Watson if (rights || i != 0) 273d57486e2SRobert Watson printf(" "); 274d57486e2SRobert Watson else 275d57486e2SRobert Watson printf("-"); 276d57486e2SRobert Watson } 277d57486e2SRobert Watson for (i = 0; i < cap_desc_count; i++) { 2782609222aSPawel Jakub Dawidek if ((cap_desc[i].cd_right & ~rights) == 0) { 279d57486e2SRobert Watson printf("%s%s", count ? "," : "", cap_desc[i].cd_desc); 280d57486e2SRobert Watson width += strlen(cap_desc[i].cd_desc); 281d57486e2SRobert Watson if (count) 282d57486e2SRobert Watson width++; 283d57486e2SRobert Watson count++; 284d57486e2SRobert Watson } 285d57486e2SRobert Watson } 286d57486e2SRobert Watson } 287d57486e2SRobert Watson 2883d91be41SRobert Watson void 2890daf62d9SStanislav Sedov procstat_files(struct procstat *procstat, struct kinfo_proc *kipp) 2903d91be41SRobert Watson { 2910daf62d9SStanislav Sedov struct sockstat sock; 2920daf62d9SStanislav Sedov struct filestat_list *head; 2930daf62d9SStanislav Sedov struct filestat *fst; 2943d91be41SRobert Watson const char *str; 2950daf62d9SStanislav Sedov struct vnstat vn; 296d57486e2SRobert Watson u_int capwidth, width; 2970daf62d9SStanislav Sedov int error; 2983d91be41SRobert Watson 299d57486e2SRobert Watson /* 300d57486e2SRobert Watson * To print the header in capability mode, we need to know the width 301d57486e2SRobert Watson * of the widest capability string. Even if we get no processes 302d57486e2SRobert Watson * back, we will print the header, so we defer aborting due to a lack 303d57486e2SRobert Watson * of processes until after the header logic. 304d57486e2SRobert Watson */ 305d57486e2SRobert Watson capwidth = 0; 3060daf62d9SStanislav Sedov head = procstat_getfiles(procstat, kipp, 0); 307d57486e2SRobert Watson if (head != NULL && Cflag) { 308d57486e2SRobert Watson STAILQ_FOREACH(fst, head, next) { 309d57486e2SRobert Watson width = width_capability(fst->fs_cap_rights); 310d57486e2SRobert Watson if (width > capwidth) 311d57486e2SRobert Watson capwidth = width; 312d57486e2SRobert Watson } 313d57486e2SRobert Watson if (capwidth < strlen("CAPABILITIES")) 314d57486e2SRobert Watson capwidth = strlen("CAPABILITIES"); 315d57486e2SRobert Watson } 316d57486e2SRobert Watson 317d57486e2SRobert Watson if (!hflag) { 318d57486e2SRobert Watson if (Cflag) 319d57486e2SRobert Watson printf("%5s %-16s %4s %1s %-9s %-*s " 320d57486e2SRobert Watson "%-3s %-12s\n", "PID", "COMM", "FD", "T", 321d57486e2SRobert Watson "FLAGS", capwidth, "CAPABILITIES", "PRO", 322d57486e2SRobert Watson "NAME"); 323d57486e2SRobert Watson else 324d57486e2SRobert Watson printf("%5s %-16s %4s %1s %1s %-9s " 325d57486e2SRobert Watson "%3s %7s %-3s %-12s\n", "PID", "COMM", "FD", "T", 326d57486e2SRobert Watson "V", "FLAGS", "REF", "OFFSET", "PRO", "NAME"); 327d57486e2SRobert Watson } 328d57486e2SRobert Watson 3290daf62d9SStanislav Sedov if (head == NULL) 33008afefa8SJoe Marcus Clarke return; 3310daf62d9SStanislav Sedov STAILQ_FOREACH(fst, head, next) { 3320daf62d9SStanislav Sedov printf("%5d ", kipp->ki_pid); 3335a246d29SRobert Watson printf("%-16s ", kipp->ki_comm); 3340daf62d9SStanislav Sedov if (fst->fs_uflags & PS_FST_UFLAG_CTTY) 3350daf62d9SStanislav Sedov printf("ctty "); 3360daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_CDIR) 337f2805949SJoe Marcus Clarke printf(" cwd "); 3380daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_JAIL) 339f2805949SJoe Marcus Clarke printf("jail "); 3400daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_RDIR) 3410daf62d9SStanislav Sedov printf("root "); 3420daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_TEXT) 3430daf62d9SStanislav Sedov printf("text "); 3440daf62d9SStanislav Sedov else if (fst->fs_uflags & PS_FST_UFLAG_TRACE) 3450daf62d9SStanislav Sedov printf("trace "); 3460daf62d9SStanislav Sedov else 3470daf62d9SStanislav Sedov printf("%4d ", fst->fs_fd); 348f2805949SJoe Marcus Clarke 3490daf62d9SStanislav Sedov switch (fst->fs_type) { 3500daf62d9SStanislav Sedov case PS_FST_TYPE_VNODE: 3513d91be41SRobert Watson str = "v"; 3523d91be41SRobert Watson break; 3533d91be41SRobert Watson 3540daf62d9SStanislav Sedov case PS_FST_TYPE_SOCKET: 3553d91be41SRobert Watson str = "s"; 3563d91be41SRobert Watson break; 3573d91be41SRobert Watson 3580daf62d9SStanislav Sedov case PS_FST_TYPE_PIPE: 3593d91be41SRobert Watson str = "p"; 3603d91be41SRobert Watson break; 3613d91be41SRobert Watson 3620daf62d9SStanislav Sedov case PS_FST_TYPE_FIFO: 3633d91be41SRobert Watson str = "f"; 3643d91be41SRobert Watson break; 3653d91be41SRobert Watson 3660daf62d9SStanislav Sedov case PS_FST_TYPE_KQUEUE: 3673d91be41SRobert Watson str = "k"; 3683d91be41SRobert Watson break; 3693d91be41SRobert Watson 3700daf62d9SStanislav Sedov case PS_FST_TYPE_CRYPTO: 3713d91be41SRobert Watson str = "c"; 3723d91be41SRobert Watson break; 3733d91be41SRobert Watson 3740daf62d9SStanislav Sedov case PS_FST_TYPE_MQUEUE: 3753d91be41SRobert Watson str = "m"; 3763d91be41SRobert Watson break; 3773d91be41SRobert Watson 3780daf62d9SStanislav Sedov case PS_FST_TYPE_SHM: 37987cb56f6SRobert Watson str = "h"; 38087cb56f6SRobert Watson break; 38187cb56f6SRobert Watson 3820daf62d9SStanislav Sedov case PS_FST_TYPE_PTS: 383bc093719SEd Schouten str = "t"; 384bc093719SEd Schouten break; 385bc093719SEd Schouten 3860daf62d9SStanislav Sedov case PS_FST_TYPE_SEM: 3876bc1e9cdSJohn Baldwin str = "e"; 3886bc1e9cdSJohn Baldwin break; 3896bc1e9cdSJohn Baldwin 3900daf62d9SStanislav Sedov case PS_FST_TYPE_NONE: 3910daf62d9SStanislav Sedov case PS_FST_TYPE_UNKNOWN: 3923d91be41SRobert Watson default: 3933d91be41SRobert Watson str = "?"; 3943d91be41SRobert Watson break; 3953d91be41SRobert Watson } 3963d91be41SRobert Watson printf("%1s ", str); 397d57486e2SRobert Watson if (!Cflag) { 3983d91be41SRobert Watson str = "-"; 3990daf62d9SStanislav Sedov if (fst->fs_type == PS_FST_TYPE_VNODE) { 400d57486e2SRobert Watson error = procstat_get_vnode_info(procstat, fst, 401d57486e2SRobert Watson &vn, NULL); 4020daf62d9SStanislav Sedov switch (vn.vn_type) { 4030daf62d9SStanislav Sedov case PS_FST_VTYPE_VREG: 4043d91be41SRobert Watson str = "r"; 4053d91be41SRobert Watson break; 4063d91be41SRobert Watson 4070daf62d9SStanislav Sedov case PS_FST_VTYPE_VDIR: 4083d91be41SRobert Watson str = "d"; 4093d91be41SRobert Watson break; 4103d91be41SRobert Watson 4110daf62d9SStanislav Sedov case PS_FST_VTYPE_VBLK: 4123d91be41SRobert Watson str = "b"; 4133d91be41SRobert Watson break; 4143d91be41SRobert Watson 4150daf62d9SStanislav Sedov case PS_FST_VTYPE_VCHR: 4163d91be41SRobert Watson str = "c"; 4173d91be41SRobert Watson break; 4183d91be41SRobert Watson 4190daf62d9SStanislav Sedov case PS_FST_VTYPE_VLNK: 4203d91be41SRobert Watson str = "l"; 4213d91be41SRobert Watson break; 4223d91be41SRobert Watson 4230daf62d9SStanislav Sedov case PS_FST_VTYPE_VSOCK: 4243d91be41SRobert Watson str = "s"; 4253d91be41SRobert Watson break; 4263d91be41SRobert Watson 4270daf62d9SStanislav Sedov case PS_FST_VTYPE_VFIFO: 4283d91be41SRobert Watson str = "f"; 4293d91be41SRobert Watson break; 4303d91be41SRobert Watson 4310daf62d9SStanislav Sedov case PS_FST_VTYPE_VBAD: 4323d91be41SRobert Watson str = "x"; 4333d91be41SRobert Watson break; 4343d91be41SRobert Watson 4350daf62d9SStanislav Sedov case PS_FST_VTYPE_VNON: 4360daf62d9SStanislav Sedov case PS_FST_VTYPE_UNKNOWN: 4373d91be41SRobert Watson default: 4383d91be41SRobert Watson str = "?"; 4393d91be41SRobert Watson break; 4403d91be41SRobert Watson } 4413d91be41SRobert Watson } 4423d91be41SRobert Watson printf("%1s ", str); 443d57486e2SRobert Watson } 4440daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_READ ? "r" : "-"); 4450daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_WRITE ? "w" : "-"); 4460daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_APPEND ? "a" : "-"); 4470daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_ASYNC ? "s" : "-"); 4480daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_SYNC ? "f" : "-"); 4490daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_NONBLOCK ? "n" : "-"); 4500daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_DIRECT ? "d" : "-"); 4510daf62d9SStanislav Sedov printf("%s", fst->fs_fflags & PS_FST_FFLAG_HASLOCK ? "l" : "-"); 452d57486e2SRobert Watson if (!Cflag) { 4530daf62d9SStanislav Sedov if (fst->fs_ref_count > -1) 4540daf62d9SStanislav Sedov printf("%3d ", fst->fs_ref_count); 455f2805949SJoe Marcus Clarke else 456f2805949SJoe Marcus Clarke printf("%3c ", '-'); 4570daf62d9SStanislav Sedov if (fst->fs_offset > -1) 4580daf62d9SStanislav Sedov printf("%7jd ", (intmax_t)fst->fs_offset); 459f2805949SJoe Marcus Clarke else 460f2805949SJoe Marcus Clarke printf("%7c ", '-'); 461d57486e2SRobert Watson } 462d57486e2SRobert Watson if (Cflag) { 463d57486e2SRobert Watson print_capability(fst->fs_cap_rights, capwidth); 464d57486e2SRobert Watson printf(" "); 465d57486e2SRobert Watson } 4660daf62d9SStanislav Sedov switch (fst->fs_type) { 4670daf62d9SStanislav Sedov case PS_FST_TYPE_SOCKET: 4680daf62d9SStanislav Sedov error = procstat_get_socket_info(procstat, fst, &sock, NULL); 4690daf62d9SStanislav Sedov if (error != 0) 4700daf62d9SStanislav Sedov break; 4715a246d29SRobert Watson printf("%-3s ", 4720daf62d9SStanislav Sedov protocol_to_string(sock.dom_family, 4730daf62d9SStanislav Sedov sock.type, sock.proto)); 4743d91be41SRobert Watson /* 4753d91be41SRobert Watson * While generally we like to print two addresses, 4763d91be41SRobert Watson * local and peer, for sockets, it turns out to be 4773d91be41SRobert Watson * more useful to print the first non-nul address for 4783d91be41SRobert Watson * local sockets, as typically they aren't bound and 4793d91be41SRobert Watson * connected, and the path strings can get long. 4803d91be41SRobert Watson */ 4810daf62d9SStanislav Sedov if (sock.dom_family == AF_LOCAL) { 4823d91be41SRobert Watson struct sockaddr_un *sun = 4830daf62d9SStanislav Sedov (struct sockaddr_un *)&sock.sa_local; 4843d91be41SRobert Watson 4853d91be41SRobert Watson if (sun->sun_path[0] != 0) 4860daf62d9SStanislav Sedov print_address(&sock.sa_local); 4873d91be41SRobert Watson else 4880daf62d9SStanislav Sedov print_address(&sock.sa_peer); 4893d91be41SRobert Watson } else { 4900daf62d9SStanislav Sedov print_address(&sock.sa_local); 4913d91be41SRobert Watson printf(" "); 4920daf62d9SStanislav Sedov print_address(&sock.sa_peer); 4933d91be41SRobert Watson } 4943d91be41SRobert Watson break; 4953d91be41SRobert Watson 4963d91be41SRobert Watson default: 497e506e182SJohn Baldwin printf("%-3s ", "-"); 498e506e182SJohn Baldwin printf("%-18s", fst->fs_path != NULL ? fst->fs_path : "-"); 4993d91be41SRobert Watson } 5003d91be41SRobert Watson 5013d91be41SRobert Watson printf("\n"); 5023d91be41SRobert Watson } 50339f6ca65SMikolaj Golub procstat_freefiles(procstat, head); 5043d91be41SRobert Watson } 505