diff --git a/00PORTING b/00PORTING index 46cd142e..5e0c61ad 100644 --- a/00PORTING +++ b/00PORTING @@ -1066,11 +1066,6 @@ possibilities pointer to the file, and returns non-zero if it prints a cached name to stdout. - HASPRIVPRIPP is defined for dialects that have a private - function for printing the IP protocol name. - When this is not defined, the function to - do that defaults to printiproto(). - HASPROCFS defines the name (if any) of the process file system -- e.g., /proc. diff --git a/Makefile.am b/Makefile.am index 79335061..e39b37cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,21 +1,20 @@ -bin_PROGRAMS = lsof - -# Documentation -EXTRA_DIST = 00.README.FIRST 00CREDITS 00DCACHE 00DIALECTS 00DIST 00FAQ 00LSOF-L 00MANIFEST 00PORTING 00QUICKSTART 00README 00TEST 00XCONFIG -# Testing -EXTRA_DIST += tests/00README tests/TestDB tests/CkTestDB tests/Makefile tests/LsofTest.h check.bash +# liblsof +lib_LTLIBRARIES = liblsof.la # Dialect neutral sources -lsof_SOURCES = src/arg.c src/main.c lib/node.c src/print.c src/ptti.c src/store.c src/usage.c src/util.c \ - lib/ckkv.c lib/cvfs.c lib/dvch.c lib/fino.c lib/isfn.c lib/lkud.c lib/misc.c lib/pdvn.c lib/prfp.c lib/print.c lib/proc.c lib/ptti.c lib/rdev.c lib/rnmt.c lib/rmnt.c lib/rnam.c lib/rnch.c lib/rnmh.c -lsof_SOURCES += lib/common.h include/lsof_fields.h lib/proto.h lib/hash.h src/cli.h +liblsof_la_SOURCES = lib/ckkv.c lib/cvfs.c lib/dvch.c lib/fino.c lib/isfn.c lib/lkud.c lib/lsof.c lib/misc.c lib/node.c lib/pdvn.c lib/prfp.c lib/print.c lib/proc.c lib/ptti.c lib/rdev.c lib/rnmt.c lib/rmnt.c lib/rnam.c lib/rnch.c lib/rnmh.c +liblsof_la_SOURCES += lib/common.h lib/proto.h lib/hash.h include_HEADERS = include/lsof.h include/lsof_fields.h + +# Hide internal functions +AM_CFLAGS = -fvisibility=hidden + DIALECT_ROOT = $(top_srcdir)/lib/dialects DIALECT_PATH = $(DIALECT_ROOT)/$(LSOF_DIALECT_DIR) # Dialect specific sources if LINUX -lsof_SOURCES += lib/dialects/linux/dfile.c \ +liblsof_la_SOURCES += lib/dialects/linux/dfile.c \ lib/dialects/linux/dmnt.c \ lib/dialects/linux/dnode.c \ lib/dialects/linux/dproc.c \ @@ -27,7 +26,7 @@ lsof_SOURCES += lib/dialects/linux/dfile.c \ endif if DARWIN -lsof_SOURCES += lib/dialects/darwin/ddev.c \ +liblsof_la_SOURCES += lib/dialects/darwin/ddev.c \ lib/dialects/darwin/dfile.c \ lib/dialects/darwin/dmnt.c \ lib/dialects/darwin/dproc.c \ @@ -39,7 +38,7 @@ lsof_SOURCES += lib/dialects/darwin/ddev.c \ endif if FREEBSD -lsof_SOURCES += lib/dialects/freebsd/dmnt.c \ +liblsof_la_SOURCES += lib/dialects/freebsd/dmnt.c \ lib/dialects/freebsd/dnode.c \ lib/dialects/freebsd/dproc.c \ lib/dialects/freebsd/dsock.c \ @@ -50,7 +49,7 @@ lsof_SOURCES += lib/dialects/freebsd/dmnt.c \ endif if NETBSD -lsof_SOURCES += lib/dialects/netbsd/dmnt.c \ +liblsof_la_SOURCES += lib/dialects/netbsd/dmnt.c \ lib/dialects/netbsd/dnode.c \ lib/dialects/netbsd/dproc.c \ lib/dialects/netbsd/dsock.c \ @@ -61,7 +60,7 @@ lsof_SOURCES += lib/dialects/netbsd/dmnt.c \ endif if OPENBSD -lsof_SOURCES += lib/dialects/openbsd/dfile.c \ +liblsof_la_SOURCES += lib/dialects/openbsd/dfile.c \ lib/dialects/openbsd/dmnt.c \ lib/dialects/openbsd/dnode.c \ lib/dialects/openbsd/dproc.c \ @@ -73,7 +72,7 @@ lsof_SOURCES += lib/dialects/openbsd/dfile.c \ endif if SOLARIS -lsof_SOURCES += lib/dialects/sun/ddev.c \ +liblsof_la_SOURCES += lib/dialects/sun/ddev.c \ lib/dialects/sun/dfile.c \ lib/dialects/sun/dmnt.c \ lib/dialects/sun/dnode.c \ @@ -86,7 +85,7 @@ lsof_SOURCES += lib/dialects/sun/ddev.c \ endif if AIX -lsof_SOURCES += lib/dialects/aix/ddev.c \ +liblsof_la_SOURCES += lib/dialects/aix/ddev.c \ lib/dialects/aix/dfile.c \ lib/dialects/aix/dmnt.c \ lib/dialects/aix/dnode.c \ @@ -99,22 +98,35 @@ lsof_SOURCES += lib/dialects/aix/ddev.c \ lib/dialects/aix/machine.h endif -lsof_CPPFLAGS = -I$(DIALECT_PATH) -Iautotools -I$(top_srcdir)/lib -I$(top_srcdir)/include -lsof_CPPFLAGS += -DAUTOTOOLS +# Binary +bin_PROGRAMS = lsof lsof-netstat + +lsof_SOURCES = src/arg.c src/main.c src/print.c src/ptti.c src/store.c src/usage.c src/util.c +lsof_SOURCES += src/cli.h + +if LINUX +lsof_SOURCES += src/dialects/linux/dprint.c +endif +if DARWIN +lsof_SOURCES += src/dialects/darwin/dprint.c +endif +if SOLARIS +lsof_SOURCES += src/dialects/sun/dprint.c +endif +# TODO: link to dynamic library instead after internal functions are no longer used +lsof_SOURCES += $(liblsof_la_SOURCES) +#lsof_LDADD = liblsof.la +lsof_netstat_SOURCES = src/netstat.c +lsof_netstat_LDADD = liblsof.la + +liblsof_la_CPPFLAGS = -I$(DIALECT_PATH) -Iautotools -DAUTOTOOLS -I$(top_srcdir)/lib -I$(top_srcdir)/include +lsof_CPPFLAGS = -I$(DIALECT_PATH) -Iautotools -DAUTOTOOLS -I$(top_srcdir)/lib -I$(top_srcdir)/include -I$(top_srcdir)/src +lsof_netstat_CPPFLAGS = -I$(DIALECT_PATH) -Iautotools -DAUTOTOOLS -I$(top_srcdir)/lib -I$(top_srcdir)/include -I$(top_srcdir)/src -# Manpages -lsof.man: Lsof.8 version 00DIALECTS - soelim < Lsof.8 > $@ -man8_MANS = lsof.man -EXTRA_DIST += Lsof.8 -# Fix distcheck error -clean-local: - rm -rf lsof.man -distclean-local: - rm -rf lockf_owner.h lockf.h # Testing scripts AM_TESTS_ENVIRONMENT = export LSOF_DIALECT_DIR=$(LSOF_DIALECT_DIR); export LSOF_DIALECT=$(LSOF_DIALECT); +EXTRA_DIST = # Dialect neutral DIALECT_NEUTRAL_TESTS = tests/case-00-hello.bash \ tests/case-01-version.bash \ @@ -124,7 +136,8 @@ DIALECT_NEUTRAL_TESTS = tests/case-00-hello.bash \ tests/case-20-offset-field.bash \ tests/case-20-repeat-count.bash \ tests/case-21-exit-Q-status.bash \ - tests/case-22-empty-process-name.bash + tests/case-22-empty-process-name.bash \ + tests/case-23-c-option.bash TESTS = $(DIALECT_NEUTRAL_TESTS) EXTRA_DIST += $(DIALECT_NEUTRAL_TESTS) \ tests/case-13-classic.bash \ @@ -193,3 +206,36 @@ tests_LTszoff_SOURCES = tests/LTszoff.c tests/LTlib.c tests_LTszoff_CFLAGS = @LSOF_TEST_CFLAGS@ -I$(top_srcdir)/include tests_LTunix_SOURCES = tests/LTunix.c tests/LTlib.c tests_LTunix_CFLAGS = @LSOF_TEST_CFLAGS@ -I$(top_srcdir)/include + +TESTS += tests/LTbasic2 tests/LTszoff2 tests/LTunix2 tests/LTshm2 +check_PROGRAMS += tests/LTbasic2 tests/LTszoff2 tests/LTunix2 tests/LTshm2 +tests_LTbasic2_CFLAGS = -I$(top_srcdir)/include +tests_LTbasic2_LDADD = liblsof.la +tests_LTszoff2_CFLAGS = -I$(top_srcdir)/include +tests_LTszoff2_LDADD = liblsof.la +tests_LTunix2_CFLAGS = -I$(top_srcdir)/include +tests_LTunix2_LDADD = liblsof.la +tests_LTshm2_CFLAGS = -I$(top_srcdir)/include +tests_LTshm2_LDADD = liblsof.la +if LINUX +tests_LTshm2_LDADD += -lrt +endif +if NETBSD +tests_LTshm2_LDADD += -lrt +endif + +# Documentation +EXTRA_DIST += 00.README.FIRST 00CREDITS 00DCACHE 00DIALECTS 00DIST 00FAQ 00LSOF-L 00MANIFEST 00PORTING 00QUICKSTART 00README 00TEST 00XCONFIG +# Testing +EXTRA_DIST += tests/00README tests/TestDB tests/CkTestDB tests/Makefile tests/LsofTest.h check.bash + +# Manpages +lsof.man: Lsof.8 version 00DIALECTS + soelim < Lsof.8 > $@ +man8_MANS = lsof.man +EXTRA_DIST += Lsof.8 +# Fix distcheck error +clean-local: + rm -rf lsof.man +distclean-local: + rm -rf lockf_owner.h lockf.h diff --git a/configure.ac b/configure.ac index 04751f4d..96c08622 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,6 @@ AC_INIT([lsof],[4.98.0]) AM_INIT_AUTOMAKE([subdir-objects]) +LT_INIT([disable-fast-install]) # avoid lt-lsof naming # Locate custom m4 macros AC_CONFIG_MACRO_DIR([m4]) @@ -247,6 +248,10 @@ CFLAGS="$CFLAGS -DLSOF_VSTR=\\\"$LSOF_TMP\\\"" AC_SUBST([LSOF_DIALECT]) AC_SUBST([LSOF_DIALECT_DIR]) +# Export public function with default visibility +AC_DEFINE([API_EXPORT], [__attribute__ ((visibility ("default")))], + [Set visibility to default for exported API functions.]) + # --enable-security to define HASSECURITY AC_ARG_ENABLE(security, AS_HELP_STRING([--enable-security], [allow only the root user to list all open files @<:@default=no@:>@]), [], [enable_security=no]) diff --git a/include/lsof.h b/include/lsof.h index f07cd886..295fc946 100644 --- a/include/lsof.h +++ b/include/lsof.h @@ -29,12 +29,38 @@ */ /* - * $Id: lsof.h,v 1.70 2018/03/26 21:50:45 abe Exp $ + * $Id: common.h,v 1.70 2018/03/26 21:50:45 abe Exp $ */ #if !defined(LSOF_H) # define LSOF_H 1 +# include +# include +# include +# include + +/** \mainpage + * liblsof provides a cross platform mechanism to list open files. To use + * liblsof, you should: + * + * 1. Check if compile-time and run-time API versions match. + * 2. Create a context via `lsof_new()`. + * 3. Set options of the context via `lsof_select_process()` etc. + * 4. freeze context via `lsof_freeze()`. + * 5. List open files via `lsof_gather()`, you can call `lsof_gather()` multiple + * times. Remember to free the result via `lsof_free_result()`. + * 6. Destroy the context via `lsof_destroy()`. + */ + +/** lsof error returns */ +enum lsof_error { + LSOF_SUCCESS = 0, /**< Success */ + LSOF_ERROR_INVALID_ARGUMENT, /**< Invalid argument */ + LSOF_ERROR_NO_MEMORY, /**< No memory */ + LSOF_ERROR_UNSUPPORTED, /**< Unsupported operation */ +}; + /** File access mode */ enum lsof_file_access_mode { LSOF_FILE_ACCESS_NONE = 0, /**< None */ @@ -44,4 +70,977 @@ enum lsof_file_access_mode { LSOF_FILE_ACCESS_READ | LSOF_FILE_ACCESS_WRITE, /**< Read and write */ }; -#endif \ No newline at end of file +/** File lock mode */ +enum lsof_lock_mode { + LSOF_LOCK_NONE, /**< None */ + LSOF_LOCK_UNKNOWN, /**< Unknown */ + LSOF_LOCK_READ_PARTIAL, /**< Read lock on part of the file */ + LSOF_LOCK_READ_FULL, /**< Read lock on the entire file */ + LSOF_LOCK_WRITE_PARTIAL, /**< Write lock on part of the file */ + LSOF_LOCK_WRITE_FULL, /**< Write lock on the entire file */ + LSOF_LOCK_READ_WRITE, /**< Read and write lock */ + LSOF_LOCK_SOLARIS_NFS, /**< Solaris NFS lock */ + LSOF_LOCK_SCO_PARTIAL, /**< SCO OpenServer Xenix lock on part of the file */ + LSOF_LOCK_SCO_FULL, /**< SCO OpenServer Xenix lock on the entire file */ +}; + +/** File descriptor type */ +enum lsof_fd_type { + LSOF_FD_NUMERIC, /**< Numeric fd, e.g fd returned by open() in process */ + LSOF_FD_UNKNOWN, /**< Unknown fd type */ + LSOF_FD_CWD, /**< Current working directory */ + LSOF_FD_ERROR, /**< Failed to get fd information */ + LSOF_FD_ROOT_DIR, /**< Root directory */ + LSOF_FD_PARENT_DIR, /**< Parent directory */ + LSOF_FD_PROGRAM_TEXT, /**< Program text */ + LSOF_FD_MEMORY, /**< Memory */ + LSOF_FD_DELETED, /**< Deleted file */ + LSOF_FD_FILEPORT, /**< Darwin fileport */ + LSOF_FD_TASK_CWD, /**< Per task/thread cwd */ + LSOF_FD_CTTY, /**< Character TTY */ + LSOF_FD_JAIL_DIR, /**< Jail directory */ +}; + +/** File type */ +enum lsof_file_type { + /* struct stat S_IFMT modes */ + LSOF_FILE_FIFO, /**< FIFO special file */ + LSOF_FILE_CHAR, /**< Character special file */ + LSOF_FILE_DIR, /**< Directory */ + LSOF_FILE_BLOCK, /**< Block special file */ + LSOF_FILE_REGULAR, /**< Regular file */ + LSOF_FILE_LINK, /**< Symolic link */ + LSOF_FILE_SOCKET, /**< Socket of unknown domain */ + + /* Network */ + LSOF_FILE_IPV4, /**< IPv4 socket */ + LSOF_FILE_IPV6, /**< IPv6 socket */ + LSOF_FILE_AX25, /**< AX.25 socket */ + LSOF_FILE_INET, /**< Internet(either IPv4 or IPv6) socket */ + LSOF_FILE_LINK_LEVEL_ACCESS, /**< HP-UX link level access file */ + LSOF_FILE_ROUTE, /**< AF_ROUTE socket */ + LSOF_FILE_UNIX, /**< UNIX domain socket */ + LSOF_FILE_X25, /**< HP-UX x.25 socket */ + LSOF_FILE_APPLETALK, /**< Appletalk socket */ + LSOF_FILE_NET_DRIVER, /**< AF_NDRV network driver raw socket */ + LSOF_FILE_INTERNAL_KEY, /**< Darwin internal key-management socket */ + LSOF_FILE_SYSTEM, /**< AF_SYSTEM kernel event messages socket */ + LSOF_FILE_PPP, /**< PPP socket */ + LSOF_FILE_IPX, /**< IPX socket */ + LSOF_FILE_RAW, /**< raw socket */ + LSOF_FILE_RAW6, /**< raw IPv6 socket */ + LSOF_FILE_NETLINK, /**< netlink socket */ + LSOF_FILE_PACKET, /**< packet socket */ + LSOF_FILE_ICMP, /**< icmp socket */ + + /* procfs */ + LSOF_FILE_PROC_AS, /**< Solaris /proc//as file */ + LSOF_FILE_PROC_AUXV, /**< /proc//auxv file */ + LSOF_FILE_PROC_CRED, /**< Solaris /proc//cred file */ + LSOF_FILE_PROC_CTRL, /**< /proc//ctl control file */ + LSOF_FILE_PROC_CUR_PROC, /**< NetBSD /proc/curproc file */ + LSOF_FILE_PROC_CWD, /**< Solaris /proc//cwd current working directory + */ + LSOF_FILE_PROC_DIR, /**< /proc directory */ + LSOF_FILE_PROC_PID, /**< /proc/ directory */ + LSOF_FILE_PROC_EXEC_TYPE, /**< FreeBSD /proc executable type (etype) */ + LSOF_FILE_PROC_FD, /**< /proc//fd/ file */ + LSOF_FILE_PROC_FD_DIR, /**< /proc//fd directory */ + LSOF_FILE_PROC_FILE, /**< /proc//file executable file */ + LSOF_FILE_PROC_FP_REGS, /**< /proc//fpregs floating point register set + */ + LSOF_FILE_PROC_PAGE_DATA, /**< Solaris /proc//pagedata file */ + LSOF_FILE_PROC_GROUP_NOTIFIER, /**< /proc//notepg group notifier file + */ + LSOF_FILE_PROC_LDT, /**< Solaris /proc//ldt file */ + LSOF_FILE_PROC_LPS_INFO, /**< Solaris /proc//lpsinfo file */ + LSOF_FILE_PROC_LSTATUS, /**< Solaris /proc//lstatus file */ + LSOF_FILE_PROC_LUSAGE, /**< Solaris /proc//lusage file */ + LSOF_FILE_PROC_LWP_GWINDOWS, /**< Solaris /proc//lwp//gwindows + * file + */ + LSOF_FILE_PROC_LWP_CTL, /**< Solaris /proc//lwp//lwpctl file */ + LSOF_FILE_PROC_LWP_DIR, /**< Solaris /proc//lwp or + /proc//lwp/ directory */ + LSOF_FILE_PROC_LWP_SINFO, /**< Solaris /proc//lwp//lwpsinfo file + */ + LSOF_FILE_PROC_LWP_STATUS, /**< Solaris /proc//lwp//lwpstatus + file */ + LSOF_FILE_PROC_LWP_USAGE, /**< Solaris /proc//lwp//lwpusage file + */ + LSOF_FILE_PROC_LWP_XREGS, /**< Solaris /proc//lwp//xregs file */ + LSOF_FILE_PROC_MAP, /**< /proc//map memory mapping file */ + LSOF_FILE_PROC_MAPS, /**< /proc//maps memory mapping file */ + LSOF_FILE_PROC_MEMORY, /**< /proc//mem memory image file */ + LSOF_FILE_PROC_PROC_NOTIFIER, /**< /proc//note process notifier file */ + LSOF_FILE_PROC_OBJ, /**< Solaris /proc//object file */ + LSOF_FILE_PROC_OBJ_DIR, /**< Solaris /proc//object directory */ + LSOF_FILE_PROC_OLD_LWP, /**< Solaris old format /proc/ file */ + LSOF_FILE_PROC_OLD_PID, /**< Solaris old format /proc/ file */ + LSOF_FILE_PROC_OLD_PAGE, /**< Solaris old format /proc/ page data file + */ + LSOF_FILE_PROC_REGS, /**< /proc//regs register set */ + LSOF_FILE_PROC_RMAP, /**< Solaris /proc//rmap file */ + LSOF_FILE_PROC_ROOT, /**< Solaris /proc//root root directory */ + LSOF_FILE_PROC_SIGACT, /**< Solaris /proc//sigact file */ + LSOF_FILE_PROC_PSINFO, /**< Solaris /proc//psinfo file */ + LSOF_FILE_PROC_STATUS, /**< /proc//status status file */ + LSOF_FILE_PROC_USAGE, /**< Solaris /proc//usage file */ + LSOF_FILE_PROC_WATCH, /**< Solaris /proc//watch file */ + LSOF_FILE_PROC_XMAP, /**< Solaris /proc//xmap file */ + + /* Others */ + LSOF_FILE_ANON_INODE, /**< anonymous inode */ + LSOF_FILE_DEL, /**< Linux map file that has been deleted */ + LSOF_FILE_DOOR, /**< Solaris VDOOR file */ + LSOF_FILE_KQUEUE, /**< BSD style kernel event file */ + LSOF_FILE_FSEVENTS, /**< fsevents file */ + LSOF_FILE_EVENTFD, /**< eventfd file */ + LSOF_FILE_PROCDESC, /**< process descriptor file */ + LSOF_FILE_MULTIPLEXED_BLOCK, /**< SCO OpenServer multiplexed block file */ + LSOF_FILE_MULTIPLEXED_CHAR, /**< SCO OpenServer multiplexed character file + */ + LSOF_FILE_UNKNOWN_DELETED, /**< Linux unknown deleted file */ + LSOF_FILE_UNKNOWN_MEMORY, /**< Linux unknown memory file */ + LSOF_FILE_UNKNOWN_FD, /**< Linux unknown fd */ + LSOF_FILE_UNKNOWN_CWD, /**< Linux unknown cwd */ + LSOF_FILE_UNKNOWN_ROOT_DIR, /**< Linux unknown root dir */ + LSOF_FILE_UNKNOWN_PROGRAM_TEXT, /**< Linux unknown program text */ + LSOF_FILE_PIPE, /**< pipes */ + LSOF_FILE_PORT, /**< Solaris SYSV named pipe */ + LSOF_FILE_POSIX_MQ, /**< POSIX named message queue file */ + LSOF_FILE_POSIX_SEMA, /**< POSIX named semaphore file */ + LSOF_FILE_POSIX_SHM, /**< POSIX named shared memory file */ + LSOF_FILE_SHM, /**< SystemV shared memory file */ + LSOF_FILE_PTS, /**< FreeBSD /dev/pts file */ + LSOF_FILE_SHARED_MEM_TRANSPORT, /**< AIX Shared memory transport file */ + LSOF_FILE_STREAM, /**< HP-UX streams */ + LSOF_FILE_STREAM_SOCKET, /**< HP-UX stream socket */ + LSOF_FILE_SCO_UNKNOWN, /**< SCO OpenServer Xenix special file of unknown + type */ + LSOF_FILE_SCO_SEMA, /**< SCO OpenServer Xenix semaphore file */ + LSOF_FILE_SCO_SHARED, /**< SCO OpenServer Xenix shared data file */ + LSOF_FILE_UNSUPPORTED, /**< unsupported file type */ + + /* types from struct vnode */ + LSOF_FILE_VNODE_VNON, /**< The vnode has no type */ + LSOF_FILE_VNODE_VREG, /**< The vnode represents a regular file */ + LSOF_FILE_VNODE_VDIR, /**< The vnode represents a directory */ + LSOF_FILE_VNODE_VBLK, /**< The vnode represents a block special device */ + LSOF_FILE_VNODE_VCHR, /**< The vnode represents a character special device + */ + LSOF_FILE_VNODE_VLNK, /**< The vnode represents a symbolic link */ + LSOF_FILE_VNODE_VSOCK, /**< The vnode represents a socket */ + LSOF_FILE_VNODE_VFIFO, /**< The vnode represents a pipe */ + LSOF_FILE_VNODE_VBAD, /**< The vnode represents a bad file */ + LSOF_FILE_VNODE_VMPC, /**< The vnode represents a multiplexed character + special device */ + LSOF_FILE_VNODE_VUNNAMED, /**< The vnode represents an unnamed file */ + + /* Unknown, see unknown_file_type_number for raw value */ + LSOF_FILE_UNKNOWN, /**< Unknown file type, only raw numbers provided */ +}; + +/** Network protocol */ +enum lsof_protocol { + LSOF_PROTOCOL_INVALID, /**< No network protocol */ + LSOF_PROTOCOL_UNKNOWN, /**< Unknown network protocol, only raw numbers + provided */ + LSOF_PROTOCOL_IP, /**< IP */ + /* Follow ip protocol numbers order */ + LSOF_PROTOCOL_HOPOPTS, /**< IPv6 hop-by-hop(0) */ + LSOF_PROTOCOL_ICMP, /**< ICMP(1) */ + LSOF_PROTOCOL_IGMP, /**< IGMP(2) */ + LSOF_PROTOCOL_GGP, /**< GGP(3) */ + LSOF_PROTOCOL_IPIP, /**< IPIP(4) */ + LSOF_PROTOCOL_IPV4, /**< IPV4(4) */ + LSOF_PROTOCOL_TCP, /**< TCP(6) */ + LSOF_PROTOCOL_ST, /**< ST(7) */ + LSOF_PROTOCOL_EGP, /**< EGP(8) */ + LSOF_PROTOCOL_PIGP, /**< PIGP(9) */ + LSOF_PROTOCOL_RCCMON, /**< RCC Monitor(10) */ + LSOF_PROTOCOL_NVPII, /**< NPV-II(11) */ + LSOF_PROTOCOL_PUP, /**< PUP(12) */ + LSOF_PROTOCOL_ARGUS, /**< ARGUS(13) */ + LSOF_PROTOCOL_EMCON, /**< EMCON(14) */ + LSOF_PROTOCOL_XNET, /**< XNET(15) */ + LSOF_PROTOCOL_CHAOS, /**< CHAOS(16) */ + LSOF_PROTOCOL_UDP, /**< UDP(17) */ + LSOF_PROTOCOL_MUX, /**< MUX(18) */ + LSOF_PROTOCOL_MEAS, /**< MEAS(19) */ + LSOF_PROTOCOL_HMP, /**< HMP(20) */ + LSOF_PROTOCOL_PRM, /**< PRM(21) */ + LSOF_PROTOCOL_IDP, /**< IDP(22) */ + LSOF_PROTOCOL_TRUNK1, /**< TRUNK1(23) */ + LSOF_PROTOCOL_TRUNK2, /**< TRUNK2(24) */ + LSOF_PROTOCOL_LEAF1, /**< LEAF1(25) */ + LSOF_PROTOCOL_LEAF2, /**< LEAF2(26) */ + LSOF_PROTOCOL_RDP, /**< RDP(27) */ + LSOF_PROTOCOL_IRTP, /**< IRTP(28) */ + LSOF_PROTOCOL_TP, /**< TP(29) */ + LSOF_PROTOCOL_BLT, /**< BLT(30) */ + LSOF_PROTOCOL_NSP, /**< NSP(31) */ + LSOF_PROTOCOL_INP, /**< INP(32) */ + LSOF_PROTOCOL_DCCP, /**< DCCP(33) */ + LSOF_PROTOCOL_SEP, /**< SEP(33) */ + LSOF_PROTOCOL_3PC, /**< 3PC(34) */ + LSOF_PROTOCOL_IDPR, /**< IDPR(35) */ + LSOF_PROTOCOL_XTP, /**< XTP(36) */ + LSOF_PROTOCOL_DDP, /**< DDP(37) */ + LSOF_PROTOCOL_CMTP, /**< CMTP(38) */ + LSOF_PROTOCOL_TPXX, /**< TPXX(39) */ + LSOF_PROTOCOL_IL, /**< IL(40) */ + LSOF_PROTOCOL_IPV6, /**< IPv6(41) */ + LSOF_PROTOCOL_SDRP, /**< SDRP(42) */ + LSOF_PROTOCOL_ROUTING, /**< IPv6-Route(43) */ + LSOF_PROTOCOL_FRAGMENT, /**< IPv6-Frag(44) */ + LSOF_PROTOCOL_IDRP, /**< IDRP(45) */ + LSOF_PROTOCOL_RSVP, /**< RSVP(46) */ + LSOF_PROTOCOL_GRE, /**< GRE(47) */ + LSOF_PROTOCOL_MHRP, /**< MHRP(48) */ + LSOF_PROTOCOL_BHA, /**< BHA(49) */ + LSOF_PROTOCOL_ESP, /**< ESP(50) */ + LSOF_PROTOCOL_AH, /**< AH(51) */ + LSOF_PROTOCOL_INLSP, /**< INLSP(52) */ + LSOF_PROTOCOL_SWIPE, /**< SWIPE(53) */ + LSOF_PROTOCOL_NHRP, /**< NHRP(54) */ + LSOF_PROTOCOL_MOBILE, /**< MOBILE(55) */ + LSOF_PROTOCOL_TLSP, /**< TLSP(56) */ + LSOF_PROTOCOL_SKIP, /**< SKIP(57) */ + LSOF_PROTOCOL_ICMPV6, /**< ICMPv6(58) */ + LSOF_PROTOCOL_NONE, /**< IPv6-NoNxt(59) */ + LSOF_PROTOCOL_DSTOPTS, /**< IPv6-Opts(60) */ + LSOF_PROTOCOL_AHIP, /**< AHIP(61) */ + LSOF_PROTOCOL_CFTP, /**< CFTP(62) */ + LSOF_PROTOCOL_HELLO, /**< HELLO(63) */ + LSOF_PROTOCOL_SATEXPAK, /**< SATEXPAK(64) */ + LSOF_PROTOCOL_KRYPTOLAN, /**< KRYPTOLAN(65) */ + LSOF_PROTOCOL_RVD, /**< RVD(66) */ + LSOF_PROTOCOL_IPPC, /**< IPPC(67) */ + LSOF_PROTOCOL_ADFS, /**< ADFS(68) */ + LSOF_PROTOCOL_SATMON, /**< SATMON(69) */ + LSOF_PROTOCOL_VISA, /**< VISA(70) */ + LSOF_PROTOCOL_IPCV, /**< IPCV(71) */ + LSOF_PROTOCOL_CPNX, /**< CPNX(72) */ + LSOF_PROTOCOL_CPHB, /**< CPHB(73) */ + LSOF_PROTOCOL_WSN, /**< WSN(74) */ + LSOF_PROTOCOL_PVP, /**< PVP(75) */ + LSOF_PROTOCOL_BRSATMON, /**< BRSATMON(76) */ + LSOF_PROTOCOL_ND, /**< ND(77) */ + LSOF_PROTOCOL_WBMON, /**< WBMON(78) */ + LSOF_PROTOCOL_WBEXPAK, /**< WBEXPAK(79) */ + LSOF_PROTOCOL_EON, /**< EON(80) */ + LSOF_PROTOCOL_VMTP, /**< VMTP(81) */ + LSOF_PROTOCOL_SVMTP, /**< SVMTP(82) */ + LSOF_PROTOCOL_VINES, /**< VINES(83) */ + LSOF_PROTOCOL_TTP, /**< TTP(84) */ + LSOF_PROTOCOL_IGP, /**< IGP(85) */ + LSOF_PROTOCOL_DGP, /**< DGP(86) */ + LSOF_PROTOCOL_TCF, /**< TCF(87) */ + LSOF_PROTOCOL_IGRP, /**< IGRP(88) */ + LSOF_PROTOCOL_OSPFIGP, /**< OSPFIGP(89) */ + LSOF_PROTOCOL_SRPC, /**< SRPC(90) */ + LSOF_PROTOCOL_LARP, /**< LARP(91) */ + LSOF_PROTOCOL_MTP, /**< MTP(92) */ + LSOF_PROTOCOL_AX25, /**< AX.25(93) */ + LSOF_PROTOCOL_BEETPH, /**< BEETPH(94) */ + LSOF_PROTOCOL_IPEIP, /**< IPEIP(94) */ + LSOF_PROTOCOL_MICP, /**< MICP(95) */ + LSOF_PROTOCOL_SCCSP, /**< SCCSP(96) */ + LSOF_PROTOCOL_ETHERIP, /**< ETHERIP(97) */ + LSOF_PROTOCOL_ENCAP, /**< ENCAP(98) */ + LSOF_PROTOCOL_APES, /**< APES(99) */ + LSOF_PROTOCOL_GMTP, /**< GMTP(100) */ + LSOF_PROTOCOL_PIM, /**< PIM(103) */ + LSOF_PROTOCOL_COMP, /**< COMP(108) */ + LSOF_PROTOCOL_IPCOMP, /**< IPCOMP(108) */ + LSOF_PROTOCOL_CARP, /**< CARP(112) */ + LSOF_PROTOCOL_PGM, /**< PGM(113) */ + LSOF_PROTOCOL_SCTP, /**< SCTP(132) */ + LSOF_PROTOCOL_MH, /**< Mobility Header(135) */ + LSOF_PROTOCOL_UDPLITE, /**< UDPLITE(136) */ + LSOF_PROTOCOL_MPLS, /**< MPLS(137) */ + LSOF_PROTOCOL_HIP, /**< HIP(139) */ + LSOF_PROTOCOL_SHIM6, /**< SHIM6(140) */ + LSOF_PROTOCOL_ETHERNET, /**< Ethernet(143) */ + LSOF_PROTOCOL_PFSYNC, /**< PFSYNC(240) */ + LSOF_PROTOCOL_RESERVED_253, /**< RESERVED_253(253) */ + LSOF_PROTOCOL_RESERVED_254, /**< RESERVED_254(254) */ + LSOF_PROTOCOL_OLD_DIVERT, /**< OLD_DIVERT(254) */ + LSOF_PROTOCOL_RAW, /**< Raw(255) */ + LSOF_PROTOCOL_MAX, /**< MAX(256) */ + LSOF_PROTOCOL_DONE, /**< DONE(257) */ + LSOF_PROTOCOL_SEND, /**< SEND(259) */ + LSOF_PROTOCOL_MPTCP, /**< MPTCP(262) */ + LSOF_PROTOCOL_SPACER, /**< SPACER(32767) */ + /* Follow ethernet type order */ + LSOF_PROTOCOL_802_3, /**< 802.3(0x0001) */ + LSOF_PROTOCOL_ALL, /**< All(0x0003) */ + LSOF_PROTOCOL_802_2, /**< 802.2(0x0004) */ + LSOF_PROTOCOL_SNAP, /**< SNAP(0x0005) */ + LSOF_PROTOCOL_DDCMP, /**< DDCMP(0x0006) */ + LSOF_PROTOCOL_WAN_PPP, /**< WAN PPP(0x0007) */ + LSOF_PROTOCOL_PPP_MP, /**< PPP MP(0x0008) */ + LSOF_PROTOCOL_LOCALTALK, /**< LOCALTALK(0x0009) */ + LSOF_PROTOCOL_CAN, /**< CAN(0x000C) */ + LSOF_PROTOCOL_CANFD, /**< CANFD(0x000D) */ + LSOF_PROTOCOL_CANXL, /**< CANXL(0x000E) */ + LSOF_PROTOCOL_PPPTALK, /**< ATALK over PPP(0x0010) */ + LSOF_PROTOCOL_TR_802_2, /**< 802.2(0x0011) */ + LSOF_PROTOCOL_MOBITEX, /**< MOBITEX(0x0015) */ + LSOF_PROTOCOL_CONTROL, /**< CONTROL(0x0016) */ + LSOF_PROTOCOL_IRDA, /**< IRDA(0x0017) */ + LSOF_PROTOCOL_ECONET, /**< ECONET(0x0018) */ + LSOF_PROTOCOL_HDLC, /**< HDLC(0x0019) */ + LSOF_PROTOCOL_ARCNET, /**< ARCNET(0x001A) */ + LSOF_PROTOCOL_DSA, /**< DSA(0x001B) */ + LSOF_PROTOCOL_TRAILER, /**< TRAILER(0x001C) */ + LSOF_PROTOCOL_LOOP, /**< LOOP(0x0060) */ + LSOF_PROTOCOL_PHONET, /**< PHONET(0x00F5) */ + LSOF_PROTOCOL_IEEE802154, /**< IEEE 802.15.4(0x00F6) */ + LSOF_PROTOCOL_CAIF, /**< CAIF(0x00F7) */ + LSOF_PROTOCOL_XDSA, /**< XDSA(0x00F8) */ + LSOF_PROTOCOL_MAP, /**< MAP(0x00F9) */ + LSOF_PROTOCOL_MCTP, /**< MCTP(0x00FA) */ + LSOF_PROTOCOL_PUPAT, /**< PUPAT(0x0201) */ + LSOF_PROTOCOL_802_3_MIN, /**< 802_3_MIN(0x0600) */ + LSOF_PROTOCOL_X25, /**< X25(0x0805) */ + LSOF_PROTOCOL_ARP, /**< ARP(0x0806) */ + LSOF_PROTOCOL_BPQ, /**< BPQ(0x08FF) */ + LSOF_PROTOCOL_IEEEPUP, /**< IEEEPUP(0x0A00) */ + LSOF_PROTOCOL_IEEEPUPAT, /**< IEEEPUPAT(0x0A01) */ + LSOF_PROTOCOL_ERSPAN2, /**< ERSPAN2(0x22EB) */ + LSOF_PROTOCOL_TSN, /**< TSN(0x22F0) */ + LSOF_PROTOCOL_BATMAN, /**< BATMAN(0x4305) */ + LSOF_PROTOCOL_DEC, /**< DEC(0x6000) */ + LSOF_PROTOCOL_DNA_DL, /**< DNA_DL(0x6001) */ + LSOF_PROTOCOL_DNA_RC, /**< DNA_RC(0x6002) */ + LSOF_PROTOCOL_DNA_RT, /**< DNA_RT(0x6003) */ + LSOF_PROTOCOL_LAT, /**< LAT(0x6004) */ + LSOF_PROTOCOL_DIAG, /**< DIAG(0x6005) */ + LSOF_PROTOCOL_CUST, /**< CUST(0x6006) */ + LSOF_PROTOCOL_SCA, /**< SCA(0x6007) */ + LSOF_PROTOCOL_TEB, /**< TEB(0x6558) */ + LSOF_PROTOCOL_RARP, /**< RARP(0x8035) */ + LSOF_PROTOCOL_ATALK, /**< ATALK(0x809B) */ + LSOF_PROTOCOL_AARP, /**< AARP(0x80F3) */ + LSOF_PROTOCOL_8021Q, /**< 8021Q(0x8100) */ + LSOF_PROTOCOL_IPX, /**< IPX(0x8137) */ + LSOF_PROTOCOL_PAUSE, /**< PAUSE(0x8808) */ + LSOF_PROTOCOL_SLOW, /**< SLOW(0x8809) */ + LSOF_PROTOCOL_WCCP, /**< WCCP(0x883E) */ + LSOF_PROTOCOL_MPLS_UC, /**< MPLS_UC(0x8847) */ + LSOF_PROTOCOL_MPLS_MC, /**< MPLS_MC(0x8848) */ + LSOF_PROTOCOL_ATMMPOA, /**< ATMMPOA(0x884C) */ + LSOF_PROTOCOL_PPP_DISC, /**< PPP_DISC(0x8863) */ + LSOF_PROTOCOL_PPP_SES, /**< PPP_SES(0x8864) */ + LSOF_PROTOCOL_LINK_CTL, /**< LINK_CTL(0x886C) */ + LSOF_PROTOCOL_ATMFATE, /**< ATMFATE(0x8884) */ + LSOF_PROTOCOL_PAE, /**< PAE(0x888E) */ + LSOF_PROTOCOL_PROFINET, /**< PROFINET(0x8892) */ + LSOF_PROTOCOL_REALTEK, /**< REALTEK(0x8899) */ + LSOF_PROTOCOL_AOE, /**< AOE(0x88A2) */ + LSOF_PROTOCOL_ETHERCAT, /**< ETHERCAT(0x88A4) */ + LSOF_PROTOCOL_8021AD, /**< 8021AD(0x88A8) */ + LSOF_PROTOCOL_802_EX1, /**< 802_EX1(0x88B5) */ + LSOF_PROTOCOL_ERSPAN, /**< ERSPAN(0x88BE) */ + LSOF_PROTOCOL_PREAUTH, /**< PREAUTH(0x88C7) */ + LSOF_PROTOCOL_TIPC, /**< TIPC(0x88CA) */ + LSOF_PROTOCOL_LLDP, /**< LLDP(0x88CC) */ + LSOF_PROTOCOL_MRP, /**< MRP(0x88E3) */ + LSOF_PROTOCOL_MACSEC, /**< MACSEC(0x88E5) */ + LSOF_PROTOCOL_8021AH, /**< 8021AH(0x88E7) */ + LSOF_PROTOCOL_MVRP, /**< MVRP(0x88F5) */ + LSOF_PROTOCOL_1588, /**< 1588(0x88F7) */ + LSOF_PROTOCOL_NCSI, /**< NCSI(0x88F8) */ + LSOF_PROTOCOL_PRP, /**< PRP(0x88FB) */ + LSOF_PROTOCOL_CFM, /**< CFM(0x8902) */ + LSOF_PROTOCOL_FCOE, /**< FCOE(0x8906) */ + LSOF_PROTOCOL_TDLS, /**< TDLS(0x890D) */ + LSOF_PROTOCOL_FIP, /**< FIP(0x8914) */ + LSOF_PROTOCOL_IBOE, /**< IBOE(0x8915) */ + LSOF_PROTOCOL_80221, /**< 802.21(0x8917) */ + LSOF_PROTOCOL_HSR, /**< HSR(0x892F) */ + LSOF_PROTOCOL_NSH, /**< NSH(0x894F) */ + LSOF_PROTOCOL_LOOPBACK, /**< LOOPBACK(0x9000) */ + LSOF_PROTOCOL_QINQ1, /**< QINQ1(0x9100) */ + LSOF_PROTOCOL_QINQ2, /**< QINQ2(0x9200) */ + LSOF_PROTOCOL_QINQ3, /**< QINQ3(0x9300) */ + LSOF_PROTOCOL_EDSA, /**< EDSA(0xDADA) */ + LSOF_PROTOCOL_DSA_8021Q, /**< DSA 802.1Q(0xDADB) */ + LSOF_PROTOCOL_DSA_A5PSW, /**< DSA_A5PSW(0xE001) */ + LSOF_PROTOCOL_IFE, /**< IFE(0xED3E) */ + LSOF_PROTOCOL_AF_IUCV, /**< AF_IUCV(0xFBFB) */ + /* others */ + LSOF_PROTOCOL_8025, /**< 802.5 */ + LSOF_PROTOCOL_CCITT, /**< CCITT */ + LSOF_PROTOCOL_STR, /**< stream */ + LSOF_PROTOCOL_SHARED, /**< shared */ +}; + +/** @struct lsof_context + * Hidden struct of lsof context, use `lsof_new()` to get one + */ +struct lsof_context; + +/** @enum struct lsof_file flags */ +enum lsof_file_flag { + LSOF_FILE_FLAG_NONE, + /** \ref struct lsof_file.dev field is valid */ + LSOF_FILE_FLAG_DEV_VALID = 0x00000001, + /** \ref struct lsof_file.rdev field is valid */ + LSOF_FILE_FLAG_RDEV_VALID = 0x00000002, + /** \ref struct lsof_file.size field is valid */ + LSOF_FILE_FLAG_SIZE_VALID = 0x00000004, + /** \ref struct lsof_file.offset field is valid */ + LSOF_FILE_FLAG_OFFSET_VALID = 0x00000008, + /** \ref struct lsof_file.num_links field is valid */ + LSOF_FILE_FLAG_NUM_LINKS_VALID = 0x00000010, + /** \ref struct lsof_file.inode field is valid */ + LSOF_FILE_FLAG_INODE_VALID = 0x00000020, + /** \ref struct lsof_file.tcp_tpi field is valid */ + LSOF_FILE_FLAG_TCP_TPI_VALID = 0x00000040, +}; + +/** @enum struct lsof_tcp_tpi flags */ +enum lsof_tcp_tpi_flag { + LSOF_TCP_TPI_FLAG_NONE, + /** \ref struct lsof_tcp_tpi.send_queue_len field is valid */ + LSOF_TCP_TPI_FLAG_SEND_QUEUE_LEN_VALID = 0x00000001, + /** \ref struct lsof_tcp_tpi.recv_queue_len field is valid */ + LSOF_TCP_TPI_FLAG_RECV_QUEUE_LEN_VALID = 0x00000002, +}; + +/** TCP/TPI(Transport Provider Interface) information + */ +struct lsof_tcp_tpi { + /** Flags, see \ref lsof_tcp_tpi_flag */ + uint64_t flags; + + /** Protocol state, NULL if unknown */ + char *state; + + /** Recv queue length, valid if \ref flags & \ref + * LSOF_TCP_TPI_FLAG_RECV_QUEUE_LEN_VALID */ + uint64_t recv_queue_len; + + /** Send queue length, valid if \ref flags & \ref + * LSOF_TCP_TPI_FLAG_SEND_QUEUE_LEN_VALID */ + uint64_t send_queue_len; +}; + +/** An open file + */ +struct lsof_file { + /** Flags, see \ref lsof_file_flag */ + uint64_t flags; + + /* FD column */ + /** File desciptor type */ + enum lsof_fd_type fd_type; + + /** File descriptor number, valid if \ref fd_type == \ref LSOF_FD_NUMERIC */ + uint32_t fd_num; + + /** File access mode */ + enum lsof_file_access_mode access; + + /** File lock mode */ + enum lsof_lock_mode lock; + + /* TYPE column */ + /** File type */ + enum lsof_file_type file_type; + /** Store raw file type number when \ref file_type == \ref LSOF_FILE_UNKNOWN + */ + uint32_t unknown_file_type_number; + + /* DEVICE column */ + /** Device ID of device containing file, use major() and minor() to extract + * components. Valid if \ref flags & \ref LSOF_FILE_FLAG_DEV_VALID */ + uint64_t dev; + /** Device ID of special character/block file, use major() and minor() to + * extract components. Valid if \ref flags & \ref + * LSOF_FILE_FLAG_RDEV_VALID */ + uint64_t rdev; + + /* SIZE, SIZE/OFF, OFFSET column */ + /** File size, valid if \ref flags & \ref LSOF_FILE_FLAG_SIZE_VALID */ + uint64_t size; + + /** File offset, valid if \ref flags & \ref LSOF_FILE_FLAG_OFFSET_VALID */ + uint64_t offset; + + /* NLINK column */ + /** Link count, valid if \ref flags & \ref LSOF_FILE_FLAG_NUM_LINKS_VALID */ + uint64_t num_links; + + /* NODE column */ + /** File inode, valid if \ref flags & \ref LSOF_FILE_FLAG_INODE_VALID */ + uint64_t inode; + + /** Network protocol */ + enum lsof_protocol protocol; + + /** Store proto number when \ref protocol == \ref LSOF_PROTOCOL_UNKNOWN */ + uint32_t unknown_proto_number; + + /* NAME column */ + /** File name or description */ + char *name; + + /* Additional information */ + /** Local network address, valid if ss_family is non-zero */ + struct sockaddr_storage net_local; + + /** Foreign network address, valid if ss_family is non-zero */ + struct sockaddr_storage net_foreign; + + /** TCP/TPI(Transport Provider Interface) information, valid if \ref flags & + * \ref LSOF_FILE_FLAG_TCP_TPI_VALID */ + struct lsof_tcp_tpi tcp_tpi; +}; + +/** The result of lsof_gather(), grouped by process + * + * For each process, you can find a linked list of open files at `files` + */ +struct lsof_process { + /* COMMAND column */ + char *command; /**< command name */ + /* PID column */ + uint32_t pid; /**< process ID */ + + /* TID column */ + uint32_t tid; /**< task ID */ + /* TASKCMD column */ + char *task_cmd; /**< task command name */ + + /* ZONES column */ + char *solaris_zone; /**< solaris zone name */ + /* SECURITY-CONTEXT column */ + char *selinux_context; /**< seLinux context name */ + + /* PGID column */ + uint32_t pgid; /**< process group ID */ + /* PPID column */ + uint32_t ppid; /**< parent process ID */ + /* USER column */ + uint32_t uid; /**< user ID */ + + uint32_t num_files; /**< length of files array */ + struct lsof_file *files; /**< array of open files */ +}; + +/** selection types */ +enum lsof_selection_type { + LSOF_SELECTION_COMMAND, /**< select by command */ + LSOF_SELECTION_COMMAND_REGEX, /**< select by command regex */ + LSOF_SELECTION_PATH, /**< select by file path */ + LSOF_SELECTION_FILE_SYSTEM, /**< select by file system */ + LSOF_SELECTION_NETWORK_ADDRESS, /**< select by network address */ + LSOF_SELECTION_INTERNET, /**< select by internet protocol */ + LSOF_SELECTION_PROTOCOL_STATE, /**< select by tcp/tpi state */ + LSOF_SELECTION_NFS, /**< select by nfs */ + LSOF_SELECTION_PID, /**< select by pid */ + LSOF_SELECTION_PGID, /**< select by pgid */ + LSOF_SELECTION_UID, /**< select by uid */ + LSOF_SELECTION_TASK, /**< select by tasks */ + LSOF_SELECTION_SOLARIS_ZONE, /**< select by Solaris zones */ + LSOF_SELECTION_SELINUX_CONTEXT, /**< select by SELinux context */ +}; + +/** Report selection status */ +struct lsof_selection { + enum lsof_selection_type type; /**< selection type */ + int found; /**< whether selection matches file */ + /** string selection argument, valid if type is one of + * LSOF_SELECTION_COMMAND, LSOF_SELECTION_COMMAND_REGEX, + * LSOF_SELECTION_PATH, LSOF_SELECTION_FILE_SYSTEM, + * LSOF_SELECTION_NETWORK_ADDRESS, LSOF_SELECTION_PROTOCOL_STATE, + * LSOF_SELECTION_UID, LSOF_SELECTION_SOLARIS_ZONE, + * LSOF_SELECTION_SELINUX_CONTEXT + */ + char *string; + /** integer selection argument, valid if type is one of + * LSOF_SELECTION_PID, LSOF_SELECTION_PGID, LSOF_SELECTION_UID + */ + uint64_t integer; +}; + +/** The result of lsof_gather() */ +struct lsof_result { + size_t num_processes; /**< length of processes array */ + struct lsof_process *processes; /**< array of processes */ + + /* Report selection status */ + size_t num_selections; /**< length of selections array */ + struct lsof_selection *selections; /**< array of selections */ +}; + +/** API version of liblsof + * you may use this macro to check the existence of + * functions + */ +# define LSOF_API_VERSION 1 + +/** Get runtime API version of liblsof + * + * liblsof might not function properly if API version mismatched between compile + * time and runtime. + * + * \since API version 1 + */ +int lsof_get_api_version(); + +/** Get library version of liblsof + * + * \return a string like "4.xx.x". The caller must not free it. + * + * \since API version 1 + */ +char *lsof_get_library_version(); + +/** Create a new lsof context + * + * The context should be freed via `lsof_destroy()`. + * + * \since API version 1 + */ +struct lsof_context *lsof_new(); + +/** Set output stream for warning and error messages + * + * lsof may want to print warning and error messages to the user. You can allow + * printing by setting the output stream and whether prints warning or not. You + * should also supply `program_name` so that the output starts with your program + * name. + * + * By default, the output is suppressed. You can set fp to NULL to suppress + * output. + * + * \since API version 1 + */ +enum lsof_error lsof_output_stream(struct lsof_context *ctx, FILE *fp, + char *program_name, int warn); + +/** Exit program upon fatal error + * + * Call this function to exit the program upon fatal error. It is useful in lsof + * cli to simplify error handling. + * + * \since API version 1 + */ +enum lsof_error lsof_exit_on_fatal(struct lsof_context *ctx, int exit); + +/** Ask lsof to avoid using blocking functions + * + * lsof may block when calling lstat(), readlink() or stat(). Call this function + * with `avoid=1` to let lsof avoid calling these functions. + * + * \since API version 1 + */ +enum lsof_error lsof_avoid_blocking(struct lsof_context *ctx, int avoid); + +/** Ask lsof to avoid forking + * + * To avoid being blocked by some kernel operations, liblsof does them in forked + * child processes. Call this function to change this behavior. + * + * \since API version 1 + */ +enum lsof_error lsof_avoid_forking(struct lsof_context *ctx, int avoid); + +/** Ask lsof to AND the selections + * + * By default, lsof OR the selections, for example, if you call + * lsof_select_unix_socket() and lsof_select_login(), it will report unix + * sockets OR open files by the user. If lsof_logic_and() is called, it will + * report unix sockets open by the specified user. + * + * \since API version 1 + */ +enum lsof_error lsof_logic_and(struct lsof_context *ctx); + +/** Ask lsof to select process by command + * + * Select process executing the command that begins with the characters of + * `command`. You can specify exclusion by setting `exclude` to 1. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_process(struct lsof_context *ctx, char *command, + int exclude); + +/** Ask lsof to select process by matching regex + * + * Select process executing the command that matches with the + * `regex`. + * + * `regex` must begin and end with a slash ('/'), the characters between the + * slashes are interpreted as a regular expression. + * + * The closing slash may be followed by these modifiers: + * - b the regular expression is a basic one. + * - i ignore the case of letters. + * - x the regular expression is an extended one (default). + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_process_regex(struct lsof_context *ctx, + char *regex); + +/** Ask lsof to select process by pid (process id) + * + * Select process by comparing pid. You can specify exclusion by setting + * `exclude` to 1. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_pid(struct lsof_context *ctx, uint32_t pid, + int exclude); + +/** Ask lsof to select process by pgid (process group id) + * + * Select process by comparing pgid. You can specify exclusion by setting + * `exclude` to 1. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_pgid(struct lsof_context *ctx, uint32_t pgid, + int exclude); + +/** Ask lsof to select process by uid + * + * Select process whose user id equals to or not equals to `uid` + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_uid(struct lsof_context *ctx, uint32_t uid, + int exclude); + +/** Ask lsof to select process by user loginc + * + * Select process whose user login name equals to or not equals to `login` + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_login(struct lsof_context *ctx, char *login, + int exclude); + +/** Ask lsof to select process by fd type/number + * + * Select fd by type(cwd, txt, etc.) or by number(0, 1, 2, etc.). If you want to + * select fd by type, `fd_num_hi` and `fd_num_lo` paramters are ignored. If you + * want to select fd by num, set `fd_type` to `LSOF_FD_NUMERIC` and pass the + * lower and higher bound of fd number. + * + * A mixture of exclusions and inclusions is not allowed. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_fd(struct lsof_context *ctx, + enum lsof_fd_type fd_type, int fd_num_lo, + int fd_num_hi, int exclude); + +/** Ask lsof to select internet sockets by ip version + * + * Select internet socket by ip version: AF_UNSPEC means any, AF_INET means IPv4 + * only, AF_INET6 means IPv6 only. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_ip(struct lsof_context *ctx, int af); + +/** Ask lsof to select internet sockets by protocol, address and port + * + * \arg `af`: AF_UNSPEC means IPv4/IPv6, AF_INET means IPv4 only, AF_INET6 means + * IPv6 only. + * + * \arg `proto`: \ref LSOF_PROTOCOL_INVALID means all, \ref LSOF_PROTOCOL_TCP + * for TCP, \ref LSOF_PROTOCOL_UDP for UDP, etc. + * + * \arg `addr`: If `addr_len` is non-zero and `addr` is not NULL, select by + * address. If `addr` is not NULL, it should point to either `struct in_addr` + * or `struct in6_addr` and match the address family `af`. + * + * \arg `port_lo` and `port_hi`: Lower bound and upper bound of port range. Use + * `-1` if all ports are allowed. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_inet(struct lsof_context *ctx, int af, + enum lsof_protocol proto, size_t addr_len, + void *addr, int port_lo, int port_hi); + +/** Ask lsof to select internet sockets by string argument + * + * The Internet address is specified in the form (items in square brackets are + * optional.): + * + * [46][protocol][@hostname|hostaddr][:service|port] + * + * Refer to the documentation of `-i` option in lsof cli for detailed + * information. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_inet_string(struct lsof_context *ctx, char *addr); + +/** Ask lsof to select unix sockets + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_unix_socket(struct lsof_context *ctx); + +/** Ask lsof to select tasks(threads) + * + * lsof can report tasks(threads) of processes. Set `show` to 1 to report + * tasks, or 0 to ignore tasks. + * + * \since API version 1 + */ +enum lsof_error lsof_select_task(struct lsof_context *ctx, int show); + +/** Ask lsof to select by protocol(TCP/UDP) states + * + * Select internet socket by protocol states, for example, TCP sockets in LISTEN + * state. For TCP, see `tcp` to 1, otherwise 0 for UDP. + * + * \since API version 1 + */ +enum lsof_error lsof_select_proto_state(struct lsof_context *ctx, int tcp, + char *state, int exclude); + +/** Ask lsof to select files in NFS + * + * \since API version 1 + */ +enum lsof_error lsof_select_nfs(struct lsof_context *ctx); + +/** Ask lsof to select files by num links + * + * Select files whose number of links are less than `threshold`. Set `threshold` + * to 0 to undo the selection. + * + * \since API version 1 + */ +enum lsof_error lsof_select_num_links(struct lsof_context *ctx, int threshold); + +/** Ask lsof to select Solaris zones + * + * \since API version 1 + */ +enum lsof_error lsof_select_solaris_zone(struct lsof_context *ctx, char *zone); + +/** Ask lsof to select SELinux context + * + * \since API version 1 + */ +enum lsof_error lsof_select_selinux_context(struct lsof_context *ctx, + char *context); + +/** flags for lsof_select_file() */ +enum lsof_select_file_flags { + /** The path must point to files */ + LSOF_SELECT_FILE_ONLY_FILES = 0x00000001, + /** The path must point to file system */ + LSOF_SELECT_FILE_ONLY_FILE_SYSTEMS = 0x00000002, + /** Accepted deleted paths */ + LSOF_SELECT_FILE_ACCEPT_DELETED = 0x00000004 +}; + +/** Ask lsof to select files by path + * + * The path can point to a file or a file system. If the path matches a + * mounted-on directory of a file system, liblsof will list all files open on + * the file system. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_file(struct lsof_context *ctx, char *path, + int flags); + +/** Ask lsof to exempt file system for blocking stat, lstat and readlink + * calls + * + * If `avoid_readlink` is non-zero, lsof will avoid readlink calls. + * + * \since API version 1 + */ +enum lsof_error lsof_exempt_fs(struct lsof_context *ctx, char *path, + int avoid_readlink); + +/** Ask lsof to enable or disable getting file path from kernel vfs name cache + * + * \since API version 1 + */ +enum lsof_error lsof_use_name_cache(struct lsof_context *ctx, int enable); + +/** Freeze the lsof context + * + * You can only call it once per context. After this call, no more options can + * be changed. + * + * \since API version 1 + */ +enum lsof_error lsof_freeze(struct lsof_context *ctx); + +/** List open files, grouped by processes + * + * The result is a struct lsof_result, saved into `result` paramter. + * + * You should not alter the content of `result`, nor call `free()` to + * pointers within. You should free `result` by calling + * `lsof_free_result()` + * + * \return LSOF_INVALID_ARGUMENT if either pointer argument is NULL, or the + * context is not frozen. + * + * \since API version 1 + */ +enum lsof_error lsof_gather(struct lsof_context *ctx, + struct lsof_result **result); + +/** Destroy a lsof context + * + * You should call `lsof_free_result` to free all `struct lsof_result` + * before destorying the context. + * + * You must not use the context anymore after this call. + * + * \since API version 1 + */ +void lsof_destroy(struct lsof_context *ctx); + +/** Free struct lsof_result + * + * \since API version 1 + */ +void lsof_free_result(struct lsof_result *result); + +#endif /* LSOF_H */ diff --git a/lib/ckkv.c b/lib/ckkv.c index 45260489..a941d6bf 100644 --- a/lib/ckkv.c +++ b/lib/ckkv.c @@ -43,7 +43,8 @@ void ckkv(struct lsof_context *ctx, /* context */ char *d, /* dialect */ char *er, /* expected revision; NULL, no test */ char *ev, /* expected version; NULL, no test */ - char *ea) /* expected architecture; NULL, no test */ + char *ea) /* expected architecture; NULL, no + * test */ { # if defined(HASKERNIDCK) @@ -55,22 +56,25 @@ void ckkv(struct lsof_context *ctx, /* context */ * Read the system information via uname(2). */ if (uname(&u) < 0) { - (void)fprintf(stderr, "%s: uname error: %s\n", Pn, strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: uname error: %s\n", Pn, + strerror(errno)); Error(ctx); + return; } - if (er && strcmp(er, u.release)) { - (void)fprintf(stderr, + if (er && strcmp(er, u.release) && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: compiled for %s release %s; this is %s.\n", Pn, d, er, u.release); } - if (ev && strcmp(ev, u.version)) { - (void)fprintf(stderr, + if (ev && strcmp(ev, u.version) && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: compiled for %s version %s; this is %s.\n", Pn, d, ev, u.version); } - if (ea && strcmp(ea, u.machine)) { + if (ea && strcmp(ea, u.machine) && ctx->err) { (void)fprintf( - stderr, + ctx->err, "%s: WARNING: compiled for %s architecture %s; this is %s.\n", Pn, d, ea, u.machine); } diff --git a/lib/common.h b/lib/common.h index 14194bcf..fcb7a499 100644 --- a/lib/common.h +++ b/lib/common.h @@ -29,10 +29,9 @@ */ /* - * $Id: lsof.h,v 1.70 2018/03/26 21:50:45 abe Exp $ + * $Id: common.h,v 1.70 2018/03/26 21:50:45 abe Exp $ */ -#include "lsof.h" #if !defined(COMMON_H) # define COMMON_H 1 @@ -254,7 +253,7 @@ struct l_dev { # include /* just in case -- because utmp.h * may need it */ -# include +# include "./regex.h" # if defined(EMPTY) # undef EMPTY @@ -308,11 +307,9 @@ extern int optind; * -- MUST BE A POWER OF 2!!! */ # endif /* defined(HASSELINUX) */ -# if defined(HASZONES) -# define HASHZONE \ - 128 /* zone hash bucket count -- MUST BE \ - * A POWER OF 2!!! */ -# endif /* defined(HASZONES) */ +# define HASHZONE \ + 128 /* zone hash bucket count -- MUST BE \ + * A POWER OF 2!!! */ # define IDINCR 10 /* PID/PGID table malloc() increment */ @@ -584,10 +581,9 @@ extern int ZoneColW; */ enum ExitStatus { - LSOF_SUCCESS, - LSOF_ERROR, + LSOF_EXIT_SUCCESS, + LSOF_EXIT_ERROR, }; -# define LSOF_SEARCH_FAILURE (FsearchErr ? LSOF_ERROR : LSOF_SUCCESS) /* * Structure definitions @@ -604,8 +600,6 @@ struct afsnode { /* AFS pseudo-node structure */ }; # endif /* defined(HAS_AFS) */ -extern int AllProc; - # if defined(HAS_STD_CLONE) struct clone { int dx; /* index of device entry in Devtp[] */ @@ -634,8 +628,6 @@ typedef struct efsys_list { struct mounts *mp; /* local mount table entry pointer */ struct efsys_list *next; /* next efsys_list entry pointer */ } efsys_list_t; -extern efsys_list_t *Efsysl; /* file systems for which kernel blocks - * are to be eliminated */ struct int_lst { int i; /* integer argument */ @@ -649,8 +641,6 @@ typedef struct lsof_rx { /* regular expression table entry */ regex_t cx; /* compiled expression */ int mc; /* match count */ } lsof_rx_t; -extern lsof_rx_t *CmdRx; -extern int NCmdRxU; # if defined(HASFSTRUCT) struct pff_tab { /* print file flags table structure */ @@ -667,11 +657,6 @@ struct seluid { * (meaningful only if excl == 0) */ }; -# if defined(HASBLKDEV) -extern struct l_dev *BDevtp, **BSdev; -extern int BNdev; -# endif /* defined(HASBLKDEV) */ - extern int CkPasswd; struct str_lst { @@ -681,130 +666,67 @@ struct str_lst { short x; /* exclusion (if non-zero) */ struct str_lst *next; /* next list entry */ }; -extern struct str_lst *Cmdl; -extern int CmdLim; -extern int Cmdni; -extern int Cmdnx; -# if defined(HASSELINUX) typedef struct cntxlist { char *cntx; /* zone name */ int f; /* "find" flag (used only in CntxArg) */ struct cntxlist *next; /* next zone hash entry */ } cntxlist_t; -extern cntxlist_t *CntxArg; -extern int CntxStatus; -# endif /* defined(HASSELINUX) */ # if defined(HASDCACHE) extern unsigned DCcksum; extern int DCfd; extern FILE *DCfs; -extern char *DCpathArg; -extern char *DCpath[]; -extern int DCpathX; extern int DCrebuilt; extern int DCstate; extern int DCunsafe; # endif /* defined(HASDCACHE) */ extern int DChelp; -extern dev_t DevDev; -extern struct l_dev *Devtp; extern char **Dstk; extern int Dstkn; extern int Dstkx; -extern int ErrStat; extern uid_t Euid; -extern int Fand; -extern int Fblock; -extern int Fcntx; -extern int Ffield; -extern int Ffilesys; -extern int Fhelp; -extern int Fhost; # if defined(HASNCACHE) -extern int Fncache; extern int NcacheReload; # endif /* defined(HASNCACHE) */ -extern int Fnet; -extern int FnetTy; -extern int Fnfs; -extern int Fnlink; -extern int Foffset; -extern int Fovhd; -extern int FeptE; - -extern int Fport; - -# if !defined(HASNORPC_H) -extern int FportMap; -# endif /* !defined(HASNORPC_H) */ - -extern int Fpgid; -extern int Fppid; -extern int FsearchErr; -extern int Fsize; -extern int Fhuman; -extern int Fsv; -extern int FsvByf; -extern int FsvFlagX; -extern int Ftask; -extern int Ftcptpi; -extern int Fterse; -extern int Funix; -extern int Futol; -extern int Fverbose; -extern int Fwarn; - -# if defined(HASXOPT_VALUE) -extern int Fxopt; -# endif /* defined(HASXOPT_VALUE) */ - -extern int Fxover; -extern int Fzone; +# include "lsof.h" struct fd_lst { - char *nm; /* file descriptor name -- range if - * NULL */ - int lo; /* range start (if nm NULL) */ - int hi; /* range end (if nm NULL) */ + enum lsof_fd_type fd_type; /* file descriptor type -- range if + * LSOF_FD_NUMERIC */ + int lo; /* range start (if nm NULL) */ + int hi; /* range end (if nm NULL) */ struct fd_lst *next; }; -extern struct fd_lst *Fdl; -extern int FdlTy; /* Fdl[] type: -1 == none - * 0 == include - * 1 == exclude */ - -struct fieldsel { - char id; /* field ID character */ - unsigned char st; /* field status */ - char *nm; /* field name */ - int *opt; /* option variable address */ - int ov; /* value to OR with option variable */ -}; -extern struct fieldsel FieldSel[]; extern int Hdr; enum IDType { PGID, PID }; -extern int IgnTasks; -extern char *InodeFmt_d; -extern char *InodeFmt_x; extern int LastPid; +/* local Internet address information */ +struct linaddr { + int af; /* address family: 0 for none; AF_INET; + * or AF_INET6 */ + int p; /* port */ + union { + struct in_addr a4; /* AF_INET Internet address */ + +# if defined(HASIPv6) + struct in6_addr a6; /* AF_INET6 Internet address */ +# endif /* defined(HASIPv6) */ + + } ia; +}; + +/** lsof private file struct */ struct lfile { enum lsof_file_access_mode access; - char lock; + enum lsof_lock_mode lock; unsigned char dev_def; /* device number definition status */ - unsigned char inp_ty; /* inode/iproto type - * 0: neither inode nor iproto - * 1: print inode in decimal - * 2: iproto contains string - * 3: print inode in hex - */ unsigned char is_com; /* common stream status */ unsigned char is_nfs; /* NFS file status */ unsigned char is_stream; /* stream device status */ @@ -841,9 +763,18 @@ struct lfile { unsigned char fsv; /* file struct value status */ # endif /* defined(HASFSTRUCT) */ - char fd[FDLEN]; - char iproto[IPROTOL]; - char type[TYPEL]; + /* FD column */ + enum lsof_fd_type fd_type; + int fd_num; /* stores fd number when fd_type == LSOF_FD_NUMERIC, otherwise + -1 */ + + enum lsof_protocol iproto; + uint32_t unknown_proto_number; /* store proto number when iproto == + LSOF_PROTOCOL_UNKNOWN */ + enum lsof_file_type type; + uint32_t unknown_file_type_number; /* store file type when type == + LSOF_FILE_UNKNOWN */ + unsigned int sf; /* select flags -- SEL* symbols */ int ch; /* VMPC channel: -1 = none */ int ntype; /* node type -- N_* value */ @@ -852,29 +783,23 @@ struct lfile { dev_t dev; dev_t rdev; INODETYPE inode; - long nlink; /* link count */ + unsigned char inode_def; /* inode definition status */ + long nlink; /* link count */ char *dev_ch; - char *fsdir; /* file system directory */ - char *fsdev; /* file system device */ + + /* fsdir and fsdev are borrowed from struct mounts/l_vfs, do not free() */ + char *fsdir; /* file system directory, */ + char *fsdev; /* file system device, do not free() */ # if defined(HASFSINO) INODETYPE fs_ino; /* file system inode number */ # endif /* defined HASFSINO) */ - struct linaddr { /* local Internet address information */ - int af; /* address family: 0 for none; AF_INET; - * or AF_INET6 */ - int p; /* port */ - union { - struct in_addr a4; /* AF_INET Internet address */ - -# if defined(HASIPv6) - struct in6_addr a6; /* AF_INET6 Internet address */ -# endif /* defined(HASIPv6) */ + /* local Internet address information */ + /* li[0]: local + * li[1]: foreign */ + struct linaddr li[2]; - } ia; - } li[2]; /* li[0]: local - * li[1]: foreign */ struct ltstate { /* local TCP/TPI state */ int type; /* state type: * -1 == none @@ -955,8 +880,8 @@ struct lfile { struct lfile *next; }; -extern struct lfile *Lf, *Plf; +/** lsof private proc struct */ struct lproc { char *cmd; /* command name */ @@ -989,52 +914,16 @@ struct lproc { struct lfile *file; /* open files of process */ }; -extern struct lproc *Lp, *Lproc; - -extern int MaxFd; -extern char *Memory; -extern int MntSup; -extern char *MntSupP; - -# if defined(HASPROCFS) -extern struct mounts *Mtprocfs; -# endif - -extern int Mxpgid; -extern int Mxpid; -extern int Mxuid; -extern gid_t Mygid; -extern int Mypid; -extern uid_t Myuid; -extern char *Namech; -extern size_t Namechl; -extern int Ndev; # if defined(HASNLIST) # if !defined(NLIST_TYPE) # define NLIST_TYPE nlist # endif /* !defined(NLIST_TYPE) */ -extern struct NLIST_TYPE *Nl; -extern int Nll; -# endif /* defined(HASNLIST) */ -extern long Nlink; -extern int Nlproc; -extern char *Nmlst; -extern int Npgid; -extern int Npgidi; -extern int Npgidx; -extern int Npid; -extern int Npidi; -extern int Npidx; -extern int Npuns; -extern int Ntype; -extern int Nuid; -extern int Nuidexcl; -extern int Nuidincl; +# endif /* defined(HASNLIST) */ struct nwad { char *arg; /* argument */ - char *proto; /* protocol */ + enum lsof_protocol proto; /* protocol */ int af; /* address family -- e.g., * AF_INET, AF_INET6 */ unsigned char a[MAX_AF_ADDR]; /* address */ @@ -1043,10 +932,6 @@ struct nwad { int f; /* find state */ struct nwad *next; /* forward link */ }; -extern struct nwad *Nwad; - -extern int OffDecDig; -extern char *Pn; # if defined(HASFSTRUCT) extern struct pff_tab Pff_tab[]; /* file flags table */ @@ -1066,25 +951,11 @@ struct procfsid { struct procfsid *next; /* forward link */ }; -extern int Procfind; -extern struct procfsid *Procfsid; -extern int Procsrch; # endif /* defined(HASPROCFS) */ extern int PrPass; -extern int RptTm; -extern int RptMaxCount; -extern struct l_dev **Sdev; -extern int SelAll; -extern int Selflags; -extern int SelProc; extern int Setgid; -extern int Selinet; extern int Setuidroot; -extern struct sfile *Sfile; -extern struct int_lst *Spgid; -extern struct int_lst *Spid; -extern struct seluid *Suid; extern char *SzOffFmt_0t; extern char *SzOffFmt_d; extern char *SzOffFmt_dv; @@ -1092,38 +963,470 @@ extern char *SzOffFmt_x; extern int TaskCmdLim; extern int TaskPrtCmd; extern int TaskPrtTid; -extern int TcpStAlloc; -extern unsigned char *TcpStI; -extern int TcpStIn; -extern int TcpStOff; -extern unsigned char *TcpStX; -extern int TcpStXn; -extern int TcpNstates; -extern char **TcpSt; -extern char Terminator; -extern int TmLimit; -extern int UdpStAlloc; -extern unsigned char *UdpStI; -extern int UdpStIn; -extern int UdpStOff; -extern unsigned char *UdpStX; -extern int UdpStXn; -extern int UdpNstates; -extern char **UdpSt; -# if defined(HASZONES) +struct hsfile { + struct sfile *s; /* the Sfile table address */ + struct hsfile *next; /* the next hash bucket entry */ +}; + typedef struct znhash { char *zn; /* zone name */ int f; /* "find" flag (used only in ZoneArg) */ struct znhash *next; /* next zone hash entry */ } znhash_t; -extern znhash_t **ZoneArg; -# endif /* defined(HASZONES) */ struct lsof_context { + /** Parameters */ + /** Linked list of files to search */ + struct sfile *select_files; + + /* selection flags -- see SEL* macros */ + int sel_flags; + /* SELPROC flags, modified by IgnTasks */ + int sel_proc; + + /* allocated (possibly unused) entries in TCP + * state tables */ + int tcp_state_alloc; + /* included TCP states */ + unsigned char *tcp_state_incl; + int tcp_state_incl_num; /* number of entries in tcp_state_incl[] */ + int tcp_state_off; /* offset for TCP state number to adjust + * negative numbers to an index into tcp_states[], + * tcp_state_incl[] and tcp_state_excl[] */ + /* excluded TCP states */ + unsigned char *tcp_state_excl; + int tcp_state_excl_num; /* number of entries in tcp_state_excl[] */ + int tcp_num_states; /* number of TCP states -- either in + * tcpstates[] or tcp_states[] */ + char **tcp_states; /* local TCP state names, indexed by system + * state value */ + + /* allocated (possibly unused) entries in UDP + * state tables */ + int udp_state_alloc; + /* included UDP states */ + unsigned char *udp_state_incl; + int udp_state_incl_num; /* number of entries in udp_state_incl[] */ + int udp_state_off; /* offset for UDP state number to adjust + * negative numbers to an index into udp_states[], + * udp_state_incl[] and udp_state_excl[] */ + unsigned char *udp_state_excl; + /* excluded UDP states */ + int udp_state_excl_num; /* number of entries in udp_state_excl[] */ + int udp_num_states; /* number of UDP states in udp_states[] */ + char **udp_states; /* local UDP state names, indexed by system + * state number */ + + /* -N option status: 0==none, 1==find all, + * 2==some found*/ + int sel_nfs; + + /* mount supplement state: 0 == none + * 1 == create + * 2 == read */ + int mnt_sup_state; + /* mount supplement path -- if MntSup == 2 */ + char *mnt_sup_path; + + /* command regular expression table for -c option */ + lsof_rx_t *cmd_regex; + int cmd_regex_size; /* number of cmd_regex[] entries */ + int cmd_regex_cap; /* capacity of cmd_regex[] */ + + /* User IDs to include or exclude */ + struct seluid *sel_uid; + /* -u option count */ + int sel_uid_size; + /* capacity of sel_uid */ + int sel_uid_cap; + /* -u option count of UIDs excluded */ + int num_uid_excluded; + /* -u option count of UIDs included */ + int num_uid_included; + + /* Whether all processes are selected */ + int sel_all_proc; + + /* command names selected with -c */ + struct str_lst *sel_cmds; + int sel_cmd_incl; /* number of command name inclusions selected with -c */ + int sel_cmd_excl; /* number of command name exclusions selected with -c */ + + int time_limit; /* Readlink() and stat() timeout (seconds) */ + + /* process group IDs to search for */ + struct int_lst *sel_pgid; + int sel_pgid_size; /* -g option count */ + int sel_pgid_cap; /* capacity of sel_pgid */ + int sel_pgid_incl_num; /* -g option inclusion count */ + int sel_pgid_excl_num; /* -g option exclusion count */ + + /* Process IDs to search for */ + struct int_lst *sel_pid; + int sel_pid_size; /* -p option count */ + int num_unsel_pid; /* number of unselected PIDs (starts at sel_pid_size) for + optimization in examine_lproc() */ + int sel_pid_cap; /* capacity of sel_pid */ + int sel_pid_incl_num; /* -p option inclusion count */ + int sel_pid_excl_num; /* -p option exclusion count */ + + int sel_all; /* SELALL flags, modified by IgnTasks */ + int sel_inet; /* select only Internet socket files */ + + int my_pid; /* lsof's process ID */ + uid_t my_uid; /* real UID of this lsof process */ + gid_t my_gid; /* real GID of this lsof process */ + int setgid; /* setgid state */ + int setuid_root; /* setuid-root state */ + + long nlink; /* report nlink values below this number + * (0 = report all nlink values) */ + + /* select by network address */ + struct nwad *sel_net_addr; + + int max_fd; /* maximum file descriptors to close */ + + int ign_tasks; /* ignore tasks when non-zero */ + + int x_opt; /* -X option status */ + + int sel_task; /* -K option value */ + int unix_socket; /* -U option status */ + + dev_t dev_dev; /* device number of /dev or its equivalent */ + + /* file systems for which kernel blocks are + * to be eliminated */ + efsys_list_t *elim_fs_list; + + int logic_and; /* -a option status */ + int avoid_blocking; /* -b option status */ + + /* file descriptors selected with -d */ + struct fd_lst *fd_list; + int fd_list_ty; /* fd_list[] type: -1 == none + * 0 == include + * 1 == exclude */ + + int endpoint_status; /* -E option status: 0==none, 1==info, + * 2==info+files */ + int net; /* -i option status: 0==none + * 1==find all + * 2==some found*/ + int net_type; /* Fnet type request: AF_UNSPEC==all + * AF_INET==IPv4 + * AF_INET6==IPv6 */ + int avoid_forking; /* -O option status */ + + /* security context arguments supplied with -Z */ + cntxlist_t *sel_selinux_context; + +# if defined(HASPROCFS) + /* /proc mount entry */ + struct mounts *procfs_mount; + int procfs_found; /* 1 when searching for an proc file system + * file and one was found */ + /* proc file system PID search table */ + struct procfsid *procfs_table; + /* 1 if searching for any proc file system + * file */ + int procfs_search; +# endif /* defined(HASPROCFS) */ + + /* zone arguments supplied with -z */ + znhash_t **sel_zone; + + /** When frozen, paramters must not be changed */ + uint8_t frozen; + + /** Temporary */ + /* name characters for printing */ + char *name_buf; + /* sizeof(name_buf) */ + size_t name_buf_size; + /* directory stack */ + char **dir_stack; /* the directory stack */ + int dir_stack_index; /* dir_stack[] index */ + int dir_stack_size; /* dir_stack[] entries allocated */ + + /* device table pointer */ + struct l_dev *dev_table; + int dev_table_size; /* number of entries in dev_table[] */ + /* pointer to dev_table[] pointers, sorted + * by device */ + struct l_dev **dev_table_sorted; + + /* block device table pointer */ + struct l_dev *block_dev_table; + int block_dev_table_size; /* number of entries in block_dev_table[] */ + /* pointer to BDevtp[] pointers, sorted + * by device */ + struct l_dev **block_dev_table_sorted; + + /* device cache paths, indexed by DCpathX + * when it's >= 0 */ + char *dev_cache_paths[4]; + int dev_cache_path_index; /* device cache path index: + * -1 = path not defined + * 0 = defined via -D + * 1 = defined via HASENVDC + * 2 = defined via HASSYSDC + * 3 = defined via HASPERSDC and + * HASPERSDCPATH */ + char *dev_cache_path_arg; /* device cache path from -D[b|r|u] */ + unsigned dev_cache_checksum; /* device cache file checksum */ + int dev_cache_fd; /* device cache file descriptor */ + FILE *dev_cache_fp; /* stream pointer for DCfd */ + int dev_cache_rebuilt; /* an unsafe device cache file has been + * rebuilt */ + int dev_cache_state; /* device cache state: + * 0 = ignore (-Di) + * 1 = build (-Db[path]) + * 2 = read; don't rebuild (-Dr[path]) + * 3 = update; read and rebuild if + * necessary (-Du[path]) + */ + int dev_cache_unsafe; /* device cache file is potentially unsafe, + * (The [cm]time check failed.) */ + +# if defined(HASNLIST) + /* kernel name list */ + struct NLIST_TYPE *name_list; + int name_list_size; +# endif /* defined(HASNLIST) */ + char *name_list_path; /* namelist file path */ + char *core_file_path; /* core file path */ + + /* name cache */ + int name_cache_enable; /* -C option status */ + + /* local mount info */ + struct mounts *local_mount_info; + int local_mount_info_valid; + + /** hashSfile() buckets */ + /* hash by file (dev,ino) buckets */ + struct hsfile *sfile_hash_file_dev_inode; + int sfile_hash_file_dev_inode_count; + /* hash by file raw device buckets */ + struct hsfile *sfile_hash_file_raw_device; + int sfile_hash_file_raw_device_count; + /* hash by file system buckets */ + struct hsfile *sfile_hash_file_system; + int sfile_hash_file_system_count; + /* hash by name buckets */ + struct hsfile *sfile_hash_name; + int sfile_hash_name_count; + + /* control Error(ctx) behavior */ + int exit_on_fatal; + + /** Output */ + /** Pointer to current process */ + struct lproc *cur_proc; + /** Pointer to all processes */ + struct lproc *procs; + /** length and capacity of `proc` */ + size_t procs_size; + size_t procs_cap; + + /** Pointer to current file */ + struct lfile *cur_file; + /** Pointer to previous file */ + struct lfile *prev_file; + + /** Warnings and errors */ + FILE *err; + char *program_name; + int warn; + + /** dialect specific fields, see dlsof.h */ + struct lsof_context_dialect dialect; }; +/** Convenience macros to access context */ +/* Local process */ +# define Lp (ctx->cur_proc) +/* All local processes */ +# define Lproc (ctx->procs) +/* Local file */ +# define Lf (ctx->cur_file) +/* Previous local file */ +# define Plf (ctx->prev_file) +/* Length of local processes */ +# define Nlproc (ctx->procs_size) +/* Dialect specific context */ +# define ctxd (ctx->dialect) +/* Error output */ +# define Pn (ctx->program_name) +# define Fwarn (ctx->warn) +/* Name buffer */ +# define Namech (ctx->name_buf) +# define Namechl (ctx->name_buf_size) +/* Selection flags */ +# define SelAll (ctx->sel_all) +# define Selflags (ctx->sel_flags) +# define SelProc (ctx->sel_proc) +# define Selinet (ctx->sel_inet) +/* Node type */ +# define Ntype (Lf->ntype) +/* dev_t of /dev */ +# define DevDev (ctx->dev_dev) +/* TCP states */ +# define TcpNstates (ctx->tcp_num_states) +# define TcpSt (ctx->tcp_states) +# define TcpStI (ctx->tcp_state_incl) +# define TcpStIn (ctx->tcp_state_incl_num) +# define TcpStX (ctx->tcp_state_excl) +# define TcpStXn (ctx->tcp_state_excl_num) +# define TcpStOff (ctx->tcp_state_off) +# define TcpStAlloc (ctx->tcp_state_alloc) +/* UDP states */ +# define UdpNstates (ctx->udp_num_states) +# define UdpSt (ctx->udp_states) +# define UdpStI (ctx->udp_state_incl) +# define UdpStIn (ctx->udp_state_incl_num) +# define UdpStX (ctx->udp_state_excl) +# define UdpStXn (ctx->udp_state_excl_num) +# define UdpStOff (ctx->udp_state_off) +# define UdpStAlloc (ctx->udp_state_alloc) +/* select unix socket */ +# define Funix (ctx->unix_socket) +/* select inet socket */ +# define Fnet (ctx->net) +# define FnetTy (ctx->net_type) +/* select nfs files */ +# define Fnfs (ctx->sel_nfs) +/* -a option */ +# define Fand (ctx->logic_and) +/* -x option */ +# define Fxopt (ctx->x_opt) +/* pid/uid/gid of current process */ +# define Mypid (ctx->my_pid) +# define Myuid (ctx->my_uid) +# define Mygid (ctx->my_gid) +/* setgid state */ +# define Setgid (ctx->setgid) +/* setuid-root state */ +# define Setuidroot (ctx->setuid_root) +/* avoid blocking */ +# define Fblock (ctx->avoid_blocking) +/* avoid forking overhead */ +# define Fovhd (ctx->avoid_forking) +/* endpoint status */ +# define FeptE (ctx->endpoint_status) +/* select tasks */ +# define Ftask (ctx->sel_task) +/* fd list */ +# define Fdl (ctx->fd_list) +# define FdlTy (ctx->fd_list_ty) +/* ignore tasks */ +# define IgnTasks (ctx->ign_tasks) +/* maximum fd number */ +# define MaxFd (ctx->max_fd) +/* mount supplement */ +# define MntSup (ctx->mnt_sup_state) +# define MntSupP (ctx->mnt_sup_path) +/* nlink limit */ +# define Nlink (ctx->nlink) +/* Time limit */ +# define TmLimit (ctx->time_limit) +/* number of unselected PIDs */ +# define Npuns (ctx->num_unsel_pid) +/* directory stack */ +# define Dstk (ctx->dir_stack) +# define Dstkx (ctx->dir_stack_index) +# define Dstkn (ctx->dir_stack_size) +/* selection files */ +# define Sfile (ctx->select_files) +/* fs to eliminate blocking syscalls */ +# define Efsysl (ctx->elim_fs_list) +/* select uid */ +# define Suid (ctx->sel_uid) +# define Nuid (ctx->sel_uid_size) +# define Nuidincl (ctx->num_uid_included) +# define Nuidexcl (ctx->num_uid_excluded) +# define Mxuid (ctx->sel_uid_cap) +/* select pid */ +# define Spid (ctx->sel_pid) +# define Npid (ctx->sel_pid_size) +# define Npidi (ctx->sel_pid_incl_num) +# define Npidx (ctx->sel_pid_excl_num) +# define Mxpid (ctx->sel_pid_cap) +/* select pgid */ +# define Spgid (ctx->sel_pgid) +# define Npgid (ctx->sel_pgid_size) +# define Npgidi (ctx->sel_pgid_incl_num) +# define Npgidx (ctx->sel_pgid_excl_num) +# define Mxpgid (ctx->sel_pgid_cap) +/* select all procs */ +# define AllProc (ctx->sel_all_proc) +/* select command */ +# define Cmdl (ctx->sel_cmds) +# define Cmdni (ctx->sel_cmd_incl) +# define Cmdnx (ctx->sel_cmd_excl) +# define CmdRx (ctx->cmd_regex) +# define NCmdRxU (ctx->cmd_regex_size) +/* select by network address */ +# define Nwad (ctx->sel_net_addr) +/* block device table */ +# define BDevtp (ctx->block_dev_table) +# define BNdev (ctx->block_dev_table_size) +# define BSdev (ctx->block_dev_table_sorted) +/* device table pointer */ +# define Devtp (ctx->dev_table) +# define Ndev (ctx->dev_table_size) +# define Sdev (ctx->dev_table_sorted) +/* select selinux context */ +# define CntxArg (ctx->sel_selinux_context) +/* device cache */ +# define DCpath (ctx->dev_cache_paths) +# define DCpathArg (ctx->dev_cache_path_arg) +# define DCpathX (ctx->dev_cache_path_index) +# define DCcksum (ctx->dev_cache_checksum) +# define DCfd (ctx->dev_cache_fd) +# define DCfs (ctx->dev_cache_fp) +# define DCrebuilt (ctx->dev_cache_rebuilt) +# define DCstate (ctx->dev_cache_state) +# define DCunsafe (ctx->dev_cache_unsafe) +/* name list */ +# define Nl (ctx->name_list) +# define Nll (ctx->name_list_size) +# define Nmlst (ctx->name_list_path) +# define Memory (ctx->core_file_path) +/* procfs */ +# define Mtprocfs (ctx->procfs_mount) +# define Procsrch (ctx->procfs_search) +# define Procfsid (ctx->procfs_table) +# define Procfind (ctx->procfs_found) +/* name cache */ +# define Fncache (ctx->name_cache_enable) +/* local mount info */ +# define Lmi (ctx->local_mount_info) +# define Lmist (ctx->local_mount_info_valid) +/* hash buckets in hashSfile() */ +# define HbyFdi (ctx->sfile_hash_file_dev_inode) +# define HbyFdiCt (ctx->sfile_hash_file_dev_inode_count) +# define HbyFrd (ctx->sfile_hash_file_raw_device) +# define HbyFrdCt (ctx->sfile_hash_file_raw_device_count) +# define HbyFsd (ctx->sfile_hash_file_system) +# define HbyFsdCt (ctx->sfile_hash_file_system_count) +# define HbyNm (ctx->sfile_hash_name) +# define HbyNmCt (ctx->sfile_hash_name_count) +/* solaris zone */ +# define ZoneArg (ctx->sel_zone) + +/* Utility macro to free if non-null and set the pointer to null */ +# define CLEAN(ptr) \ + do { \ + if ((ptr)) \ + free(ptr); \ + ptr = NULL; \ + } while (0); + # include "proto.h" # include "dproto.h" -#endif /* LSOF_H */ +#endif /* COMMON_H */ diff --git a/lib/dialects/aix/dfile.c b/lib/dialects/aix/dfile.c index 0d7cbf12..02215142 100644 --- a/lib/dialects/aix/dfile.c +++ b/lib/dialects/aix/dfile.c @@ -39,30 +39,13 @@ static char copyright[] = * Local structures */ -struct hsfile { - struct sfile *s; /* the Sfile table address */ - struct hsfile *next; /* the next hash bucket entry */ -}; - /* * Local static variables */ -static struct hsfile *HbyFdi = /* hash by file buckets */ - (struct hsfile *)NULL; -static int HbyFdiCt = 0; /* HbyFdi entry count */ -static struct hsfile *HbyFrd = /* hash by file raw device buckets */ - (struct hsfile *)NULL; -static int HbyFrdCt = 0; /* HbyFrd entry count */ -static struct hsfile *HbyFsd = /* hash by file system buckets */ - (struct hsfile *)NULL; -static int HbyFsdCt = 0; /* HbyFsd entry count */ static struct hsfile *HbyMPC = /* hash by MPC file buckets */ (struct hsfile *)NULL; -static int HbyMPCCt = 0; /* HbyMPC entry count */ -static struct hsfile *HbyNm = /* hash by name buckets */ - (struct hsfile *)NULL; -static int HbyNmCt = 0; /* HbyNm entry count */ +static int HbyMPCCt = 0; /* HbyMPC entry count */ /* * Local definitions @@ -260,7 +243,7 @@ int is_file_named(struct lsof_context *ctx, /* context */ */ if (ic && HbyFdiCt && CloneMaj >= 0 && (Lf->dev_def && (maj = dmaj) && (min == dmin)) && Lf->rdev_def && - (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + Lf->inode_def) { for (sh = &HbyFdi[SFHASHDEVINO(CloneMaj, rmaj, Lf->inode, SFDIHASH)]; sh; sh = sh->next) { if ((s = sh->s) && (GET_MAJ_DEV(s->rdev) == CloneMaj) && @@ -301,7 +284,7 @@ int is_file_named(struct lsof_context *ctx, /* context */ /* * Check for a regular file. */ - if (!f && HbyFdiCt && Lf->dev_def && (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + if (!f && HbyFdiCt && Lf->dev_def && Lf->inode_def) { for (sh = &HbyFdi[SFHASHDEVINO(maj, min, Lf->inode, SFDIHASH)]; sh; sh = sh->next) { if ((s = sh->s) && (maj == GET_MAJ_DEV(s->dev)) && @@ -329,7 +312,7 @@ int is_file_named(struct lsof_context *ctx, /* context */ */ if (!f && HbyFrdCt && ((ty == VCHR) || (ty == VBLK)) && (Lf->dev_def && (maj == dmaj) && (min == dmin)) && Lf->rdev_def && - (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + Lf->inode_def) { for (sh = &HbyFrd[SFHASHRDEVI(maj, min, rmaj, rmin, Lf->inode, SFRDHASH)]; sh; sh = sh->next) { @@ -383,6 +366,7 @@ int is_file_named(struct lsof_context *ctx, /* context */ char *print_dev(struct lfile *lf, /* file whose device to be printed */ dev_t *dev) /* pointer to device to be printed */ + { static char buf[128]; int maj = GET_MAJ_DEV(*dev); diff --git a/lib/dialects/aix/dlsof.h b/lib/dialects/aix/dlsof.h index 58aae4e7..f5c5df6d 100644 --- a/lib/dialects/aix/dlsof.h +++ b/lib/dialects/aix/dlsof.h @@ -272,8 +272,12 @@ typedef u_longlong_t KA_T; */ # if AIXV >= 4140 -# define DCACHE_CLONE rw_clone_sect /* clone function for read_dcache \ - */ +# define DCACHE_CLONE \ + rw_clone_sect /* clone function for read_dcache \ + */ +# define DCACHE_CLONE \ + rw_clone_sect /* clone function for read_dcache \ + */ # define DCACHE_CLR \ clr_sect /* function to clear clone and \ * pseudo caches when reading the \ diff --git a/lib/dialects/aix/dmnt.c b/lib/dialects/aix/dmnt.c index 98e2e877..dc2d2fe7 100644 --- a/lib/dialects/aix/dmnt.c +++ b/lib/dialects/aix/dmnt.c @@ -39,9 +39,6 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ diff --git a/lib/dialects/aix/dnode.c b/lib/dialects/aix/dnode.c index 7e0791fa..7aadc187 100644 --- a/lib/dialects/aix/dnode.c +++ b/lib/dialects/aix/dnode.c @@ -117,15 +117,15 @@ struct rnode { * isglocked() - is a gnode locked */ -char isglocked(struct lsof_context *ctx, /* context */ - struct gnode *ga) /* local gnode address */ +enum lsof_lock_mode isglocked(struct lsof_context *ctx, /* context */ + struct gnode *ga) /* local gnode address */ { struct filock *cfp, f, *ffp; int l; if (!(ffp = ga->gn_filocks)) - return (' '); + return LSOF_LOCK_NONE; cfp = ffp; #if AIXV >= 4140 @@ -133,7 +133,7 @@ char isglocked(struct lsof_context *ctx, /* context */ #endif /* AIXV>=4140 */ if (kread(ctx, (KA_T)cfp, (char *)&f, sizeof(f))) - return (' '); + return LSOF_LOCK_NONE; #if AIXV >= 4140 if (f.set.l_sysid || f.set.l_pid != (pid_t)Lp->pid) @@ -155,17 +155,17 @@ char isglocked(struct lsof_context *ctx, /* context */ switch (f.set.l_type & (F_RDLCK | F_WRLCK)) { case F_RDLCK: - return ((l) ? 'R' : 'r'); + return (l) ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL; case F_WRLCK: - return ((l) ? 'W' : 'w'); + return (l) ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL; case (F_RDLCK + F_WRLCK): - return ('u'); + return LSOF_LOCK_READ_WRITE; } - return (' '); + return LSOF_LOCK_NONE; #if AIXV >= 4140 } while ((cfp = f.FL_NEXT) && cfp != ffp); - return (' '); + return (LSOF_LOCK_NONE); #endif /* AIXV>=4140 */ } @@ -186,7 +186,8 @@ void process_node(struct lsof_context *ctx, /* context */ struct vfs *la = NULL; int rdevs = 0; size_t sz; - char tbuf[32], *ty; + char tbuf[32]; + enum lsof_file_type ty; enum vtype type; struct l_vfs *vfs; static struct vnode *v = (struct vnode *)NULL; @@ -429,7 +430,7 @@ void process_node(struct lsof_context *ctx, /* context */ */ ic = 1; Lf->inode = cl->cd.inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; if (ClonePtc >= 0 && GET_MAJ_DEV(g.gn_rdev) == ClonePtc) { if (Selinet) { @@ -494,7 +495,7 @@ void process_node(struct lsof_context *ctx, /* context */ * pointer. Process the stream as a socket. */ Namech[0] = '\0'; - Lf->inp_ty = 0; + Lf->inode_def = 0; (void)process_socket(ka); return; } @@ -838,7 +839,7 @@ void process_node(struct lsof_context *ctx, /* context */ case N_AFS: if (an.ino_st) { Lf->inode = (INODETYPE)an.inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HAS_AFS) */ @@ -847,7 +848,7 @@ void process_node(struct lsof_context *ctx, /* context */ case N_NFS: if (nfss) { Lf->inode = (INODETYPE)nfs_attr.va_serialno; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HAS_NFS) */ @@ -861,7 +862,7 @@ void process_node(struct lsof_context *ctx, /* context */ * IBM makes the SANFS header files available in /usr/include. */ /* Lf->inode = ??? DEBUG */ - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HAS_SANFS) */ @@ -876,7 +877,7 @@ void process_node(struct lsof_context *ctx, /* context */ case N_REGLR: if (ins) { Lf->inode = (INODETYPE)i.number; - Lf->inp_ty = i.number_def; + Lf->inode_def = i.number_def; } } /* @@ -1014,7 +1015,7 @@ void process_node(struct lsof_context *ctx, /* context */ switch (type) { case VNON: - ty = "VNON"; + ty = LSOF_FILE_VNODE_VNON; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -1022,14 +1023,14 @@ void process_node(struct lsof_context *ctx, /* context */ break; case VREG: case VDIR: - ty = (type == VREG) ? "VREG" : "VDIR"; + ty = (type == VREG) ? LSOF_FILE_VNODE_VREG : LSOF_FILE_VNODE_VDIR; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; case VBLK: - ty = "VBLK"; + ty = LSOF_FILE_VNODE_VBLK; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -1037,7 +1038,7 @@ void process_node(struct lsof_context *ctx, /* context */ Ntype = N_BLK; break; case VCHR: - ty = "VCHR"; + ty = LSOF_FILE_VNODE_VCHR; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -1045,7 +1046,7 @@ void process_node(struct lsof_context *ctx, /* context */ Ntype = N_CHR; break; case VLNK: - ty = "VLNK"; + ty = LSOF_FILE_VNODE_VLNK; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -1054,7 +1055,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(VSOCK) case VSOCK: - ty = "SOCK"; + ty = LSOF_FILE_VNODE_VSOCK; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -1063,7 +1064,7 @@ void process_node(struct lsof_context *ctx, /* context */ #endif case VBAD: - ty = "VBAD"; + ty = LSOF_FILE_VNODE_VBAD; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -1076,7 +1077,7 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->rdev = rdev; Lf->rdev_def = rdevs; } - ty = "FIFO"; + ty = LSOF_FILE_VNODE_VFIFO; break; case VMPC: Lf->rdev = g.gn_rdev; @@ -1088,39 +1089,36 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->ch = g.gn_chan; #if AIXV < 3200 - Lf->inp_ty = 0; + Lf->inode_def = 0; #endif /* AIXV<3200 */ Ntype = N_CHR; - ty = "VMPC"; + ty = LSOF_FILE_VNODE_VMPC; break; default: Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); - ty = (char *)NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = type; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); - Lf->ntype = Ntype; #if defined(HASBLKDEV) /* * If this is a VBLK file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VBLK)) - find_bl_ino(ctx); + if (!Lf->inode_def && (type == VBLK)) + find_bl_ino(); #endif /* defined(HASBLKDEV) */ /* * If this is a VCHR file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VCHR)) - find_ch_ino(ctx); + if (!Lf->inode_def && (type == VCHR)) + find_ch_ino(); /* * Test for specified file. */ @@ -1161,10 +1159,10 @@ void process_shmt(struct lsof_context *ctx, /* context */ return; } /* - * Set type to " SMT" and put shmtnode structure address in device column. + * Set type to SMT and put shmtnode structure address in device column. */ - (void)snpf(Lf->type, sizeof(Lf->type), " SMT"); - if (!sa || kread(ctx, (KA_T)sa, (char *)&mn, sizeof(mn))) { + Lf->type = LSOF_FILE_SHARED_MEM_TRANSPORT; + if (!sa || kread((KA_T)sa, (char *)&mn, sizeof(mn))) { (void)snpf(Namech, Namechl, "can't read shmtnode: %s", print_kptr(sa, (char *)NULL, 0)); enter_nm(ctx, Namech); diff --git a/lib/dialects/aix/dproc.c b/lib/dialects/aix/dproc.c index ab32831b..73788ba3 100644 --- a/lib/dialects/aix/dproc.c +++ b/lib/dialects/aix/dproc.c @@ -28,6 +28,7 @@ * 4. This notice may not be removed or altered. */ +#include "lsof.h" #ifndef lint static char copyright[] = "@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n"; @@ -646,7 +647,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Save current working directory information. */ if (!ckscko && cdir) { - alloc_lfile(ctx, CWD, -1); + alloc_lfile(ctx, LSOF_FD_CWD, -1); process_node(ctx, cdir); if (Lf->sf) link_lfile(ctx); @@ -655,7 +656,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Save root directory information. */ if (!ckscko && rdir) { - alloc_lfile(ctx, RTD, -1); + alloc_lfile(ctx, LSOF_FD_ROOT_DIR, -1); process_node(ctx, rdir); if (Lf->sf) link_lfile(ctx); @@ -666,7 +667,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Save parent directory information. */ if (!ckscko && pdir) { - alloc_lfile(ctx, " pd", -1); + alloc_lfile(ctx, LSOF_FD_PARENT_DIR, -1); process_node(ctx, pdir); if (Lf->sf) link_lfile(ctx); @@ -721,7 +722,7 @@ void gather_proc_info(struct lsof_context *ctx) { #endif /* AIXV<4300 */ if (fp) { - alloc_lfile(ctx, (char *)NULL, i); + alloc_lfile(ctx, LSOF_FD_NUMERIC, i); process_file(ctx, fp); if (Lf->sf) { @@ -1191,7 +1192,7 @@ static void process_text(struct lsof_context *ctx, /* context */ # endif /* AIXV<4300 */ { - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); if ((le = getle(ctx, ll, sid, &err))) { if ((xf = le->fp)) { process_file(ctx, (KA_T)xf); @@ -1307,9 +1308,9 @@ static void process_text(pid_t pid) /* process PID */ */ if (la->exec && !kread(ctx, (KA_T)la->exec, (char *)&le, sizeof(le)) && le.fp) { - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); process_file(ctx, (KA_T)le.fp); - if (Lf->dev_def && (Lf->inp_ty == 1)) { + if (Lf->dev_def && Lf->inode_def) { xdev = Lf->dev; xnode = Lf->inode; xs = 1; @@ -1366,10 +1367,10 @@ static void process_text(pid_t pid) /* process PID */ */ (void)snpf(fd, sizeof(fd), "L%02d", i++); alloc_lfile(ctx, fd, -1); - Lf->dev_def = Lf->inp_ty = Lf->nlink_def = 1; + Lf->dev_def = Lf->inode_def = Lf->nlink_def = 1; Lf->dev = sb.st_dev; Lf->inode = (INODETYPE)sb.st_ino; - (void)snpf(Lf->type, sizeof(Lf->type), "VREG"); + Lf->type = LSOF_FILE_VNODE_VREG; /* * Look for a match on device and node numbers in the *.so cache. */ diff --git a/lib/dialects/aix/dproto.h b/lib/dialects/aix/dproto.h index 70b15685..5a628b67 100644 --- a/lib/dialects/aix/dproto.h +++ b/lib/dialects/aix/dproto.h @@ -45,13 +45,15 @@ extern int readafsnode(struct lsof_context *ctx, KA_T va, struct vnode *v, # endif /* defined(HAS_AFS) */ # if defined(HAS_JFS2) -extern int readj2lino(struct lsof_context *ctx, struct gnode *ga, struct l_ino *li); +extern int readj2lino(struct gnode *ga, struct l_ino *li); # endif /* defined(HAS_JFS2) */ extern int getchan(char *p); -extern int is_file_named(struct lsof_context *ctx, char *p, enum vtype ty, chan_t ch, int ic); +extern int is_file_named(struct lsof_context *ctx, char *p, enum vtype ty, + chan_t ch, int ic); extern char isglocked(struct lsof_context *ctx, struct gnode *ga); -extern int readlino(struct lsof_context *ctx, struct gnode *ga, struct l_ino *li); +extern int readlino(struct lsof_context *ctx, struct gnode *ga, + struct l_ino *li); extern struct l_vfs *readvfs(struct lsof_context *ctx, struct vnode *vn); # if AIXV >= 4200 diff --git a/lib/dialects/aix/dsock.c b/lib/dialects/aix/dsock.c index e776ddeb..9a2f8798 100644 --- a/lib/dialects/aix/dsock.c +++ b/lib/dialects/aix/dsock.c @@ -74,8 +74,7 @@ void process_socket(struct lsof_context *ctx, /* context */ /* * Set socket file variables. */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_VNODE_SOCK; /* * Read socket and protocol switch structures. */ @@ -109,6 +108,7 @@ void process_socket(struct lsof_context *ctx, /* context */ else Lf->sz = (SZOFFTYPE)(s.so_rcv.sb_cc + s.so_snd.sb_cc); Lf->sz_def = 1; + Lf->off_def = 1; #if defined(HASTCPTPIQ) Lf->lts.rq = s.so_rcv.sb_cc; @@ -205,22 +205,15 @@ void process_socket(struct lsof_context *ctx, /* context */ /* * Set SELNET flag for the file, as requested. */ - if (!FnetTy || ((FnetTy == 4) && (fam == AF_INET)) - -#if defined(HASIPv6) - || ((FnetTy == 6) && (fam == AF_INET6)) -#endif /* defined(HASIPv6) */ - ) - + if (FnetTy == AF_UNSPEC || (FnetTy == fam)) Lf->sf |= SELNET; } - printiproto(p.pr_protocol); + enter_ip_proto(p.pr_protocol); #if defined(HASIPv6) - (void)snpf(Lf->type, sizeof(Lf->type), - fam == AF_INET ? "IPv4" : "IPv6"); + Lf->type = fam == AF_INET ? LSOF_FILE_IPV4 : LSOF_FILE_IPV6; #else /* !defined(HASIPv6) */ - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); + Lf->type = LSOF_FILE_INET; #endif /* defined(HASIPv6) */ /* @@ -299,11 +292,12 @@ void process_socket(struct lsof_context *ctx, /* context */ * Process a ROUTE domain socket. */ case AF_ROUTE: - (void)snpf(Lf->type, sizeof(Lf->type), "rte"); + Lf->type = LSOF_FILE_ROUTE; if (s.so_pcb) enter_dev_ch(ctx, print_kptr((KA_T)(s.so_pcb), (char *)NULL, 0)); else (void)snpf(Namech, Namechl, "no protocol control block"); + Lf->off_def = 1; break; /* * Process a Unix domain socket. @@ -311,7 +305,7 @@ void process_socket(struct lsof_context *ctx, /* context */ case AF_UNIX: if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; /* * Read Unix protocol control block and the Unix address structure. */ @@ -397,7 +391,7 @@ void process_socket(struct lsof_context *ctx, /* context */ Lf->dev_ch = (char *)NULL; } Lf->inode = (INODETYPE)i.number; - Lf->inp_ty = i.number_def; + Lf->inode_def = i.number_def; } if (ua->sun_path[0]) { if (mb.m_len > sizeof(struct sockaddr_un)) diff --git a/lib/dialects/aix/machine.h b/lib/dialects/aix/machine.h index 3c6a9556..1c26ad1e 100644 --- a/lib/dialects/aix/machine.h +++ b/lib/dialects/aix/machine.h @@ -168,7 +168,7 @@ typedef long long aligned_offset_t __attribute__((aligned(8))); /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ /* #define HASFSINO 1 */ @@ -178,7 +178,7 @@ typedef long long aligned_offset_t __attribute__((aligned(8))); * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -364,14 +364,6 @@ typedef long long aligned_offset_t __attribute__((aligned(8))); /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -553,7 +545,7 @@ typedef long long aligned_offset_t __attribute__((aligned(8))); /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -593,6 +585,7 @@ typedef long long aligned_offset_t __attribute__((aligned(8))); # define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */ /* #define USE_LIB_READDEV 1 rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ /* #define USE_LIB_RNCH 1 rnch.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ diff --git a/lib/dialects/darwin/ddev.c b/lib/dialects/darwin/ddev.c index 1615d59a..d30be68f 100644 --- a/lib/dialects/darwin/ddev.c +++ b/lib/dialects/darwin/ddev.c @@ -153,8 +153,9 @@ int printdevname(struct lsof_context *ctx, /* context */ ttl = (nty == N_BLK) ? LIKE_BLK_SPEC : LIKE_CHR_SPEC; len = (int)(1 + strlen(ttl) + 1 + strlen(dp->name) + 1); if (!(cp = (char *)malloc((MALLOC_S)(len + 1)))) { - (void)fprintf(stderr, "%s: no nma space for: (%s %s)\n", Pn, ttl, - dp->name); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no nma space for: (%s %s)\n", Pn, + ttl, dp->name); Error(ctx); } (void)snpf(cp, len + 1, "(%s %s)", ttl, dp->name); @@ -203,9 +204,9 @@ void readdev(struct lsof_context *ctx, /* context */ if (!(dfp = OpenDir(Dstk[Dstkx]))) { #if defined(WARNDEVACCESS) - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: can't open: ", Pn); - safestrprt(Dstk[Dstkx], stderr, 1); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: WARNING: can't open: ", Pn); + safestrprt(Dstk[Dstkx], ctx->err, 1); } #endif /* defined(WARNDEVACCESS) */ @@ -219,8 +220,10 @@ void readdev(struct lsof_context *ctx, /* context */ } if (!(path = mkstrcat(Dstk[Dstkx], -1, "/", 1, (char *)NULL, -1, &pl))) { - (void)fprintf(stderr, "%s: no space for: ", Pn); - safestrprt(Dstk[Dstkx], stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for: ", Pn); + safestrprt(Dstk[Dstkx], ctx->err, 1); + } Error(ctx); } (void)free((FREE_P *)Dstk[Dstkx]); @@ -241,9 +244,11 @@ void readdev(struct lsof_context *ctx, /* context */ } if (!(fp = mkstrcat(path, pl, dp->d_name, dnamlen, (char *)NULL, -1, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for: ", Pn); - safestrprt(path, stderr, 0); - safestrprtn(dp->d_name, dnamlen, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for: ", Pn); + safestrprt(path, ctx->err, 0); + safestrprtn(dp->d_name, dnamlen, ctx->err, 1); + } Error(ctx); } if (STATFN(fp, &sb) != 0) { @@ -251,12 +256,12 @@ void readdev(struct lsof_context *ctx, /* context */ continue; #if defined(WARNDEVACCESS) - if (!Fwarn) { + if (ctx->err && !Fwarn) { int errno_save = errno; - (void)fprintf(stderr, "%s: can't stat ", Pn); - safestrprt(fp, stderr, 0); - (void)fprintf(stderr, ": %s\n", strerror(errno_save)); + (void)fprintf(ctx->err, "%s: can't stat ", Pn); + safestrprt(fp, ctx->err, 0); + (void)fprintf(ctx->err, ": %s\n", strerror(errno_save)); } #endif /* defined(WARNDEVACCESS) */ @@ -297,16 +302,21 @@ void readdev(struct lsof_context *ctx, /* context */ (MALLOC_P *)Devtp, (MALLOC_S)(sizeof(struct l_dev) * Ndev)); if (!Devtp) { - (void)fprintf( - stderr, "%s: no space for character device\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no space for character device\n", + Pn); Error(ctx); } } Devtp[i].rdev = sb.st_rdev; Devtp[i].inode = (INODETYPE)sb.st_ino; if (!(Devtp[i].name = mkstrcpy(fp, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for device name: ", Pn); - safestrprt(fp, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for device name: ", Pn); + safestrprt(fp, ctx->err, 1); + } Error(ctx); } Devtp[i].v = 0; @@ -329,8 +339,10 @@ void readdev(struct lsof_context *ctx, /* context */ (MALLOC_P *)BDevtp, (MALLOC_S)(sizeof(struct l_dev) * BNdev)); if (!BDevtp) { - (void)fprintf(stderr, "%s: no space for block device\n", - Pn); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no space for block device\n", + Pn); Error(ctx); } } @@ -374,7 +386,8 @@ void readdev(struct lsof_context *ctx, /* context */ */ sz = (MALLOC_S)(ADevU * sizeof(dev_t)); if (!(ADev = (dev_t *)realloc((MALLOC_P *)ADev, sz))) { - (void)fprintf(stderr, "%s: can't reduce ADev[]\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't reduce ADev[]\n", Pn); Error(ctx); } } @@ -402,8 +415,10 @@ void readdev(struct lsof_context *ctx, /* context */ } if (!(BSdev = (struct l_dev **)malloc( (MALLOC_S)(sizeof(struct l_dev *) * BNdev)))) { - (void)fprintf(stderr, - "%s: no space for block device sort pointers\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no space for block device sort pointers\n", + Pn); Error(ctx); } for (j = 0; j < BNdev; j++) { @@ -416,8 +431,9 @@ void readdev(struct lsof_context *ctx, /* context */ # if !defined(NOWARNBLKDEV) else { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: no block devices found\n", Pn); + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, "%s: WARNING: no block devices found\n", + Pn); } # endif /* !defined(NOWARNBLKDEV) */ #endif /* defined(HASBLKDEV) */ @@ -430,9 +446,10 @@ void readdev(struct lsof_context *ctx, /* context */ } if (!(Sdev = (struct l_dev **)malloc( (MALLOC_S)(sizeof(struct l_dev *) * Ndev)))) { - (void)fprintf(stderr, - "%s: no space for character device sort pointers\n", - Pn); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: no space for character device sort pointers\n", Pn); Error(ctx); } for (i = 0; i < Ndev; i++) { @@ -442,7 +459,8 @@ void readdev(struct lsof_context *ctx, /* context */ (size_t)sizeof(struct l_dev *), compdev); Ndev = rmdupdev(ctx, &Sdev, Ndev, "char"); } else { - (void)fprintf(stderr, "%s: no character devices found\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no character devices found\n", Pn); Error(ctx); } } @@ -473,7 +491,9 @@ static int rmdupdev(struct lsof_context *ctx, /* context */ return (n); if (!(*dp = (struct l_dev **)realloc( (MALLOC_P *)*dp, (MALLOC_S)(j * sizeof(struct l_dev *))))) { - (void)fprintf(stderr, "%s: can't realloc %s device pointers\n", Pn, nm); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't realloc %s device pointers\n", + Pn, nm); Error(ctx); } return (j); @@ -482,6 +502,7 @@ static int rmdupdev(struct lsof_context *ctx, /* context */ /* * saveADev() - save additional device number appearing inside DDEV_DEVPATH */ + static void saveADev(struct lsof_context *ctx, /* context */ struct stat *s) /* stat(2) buffer for file */ { @@ -519,7 +540,8 @@ static void saveADev(struct lsof_context *ctx, /* context */ else ADev = (dev_t *)malloc(sz); if (!ADev) { - (void)fprintf(stderr, "%s: no space for ADev[]\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for ADev[]\n", Pn); Error(ctx); } } diff --git a/lib/dialects/darwin/dfile.c b/lib/dialects/darwin/dfile.c index f62d745b..cfe9b6bd 100644 --- a/lib/dialects/darwin/dfile.c +++ b/lib/dialects/darwin/dfile.c @@ -38,10 +38,6 @@ static char copyright[] = "@(#) Copyright 2005-2007 Apple Inc. and Purdue " #include "common.h" -#if defined(PROC_FP_GUARDED) -extern struct pff_tab Pgf_tab[]; -#endif /* defined(PROC_FP_GUARDED) */ - /* * enter_file_info() -- enter file information */ @@ -88,51 +84,49 @@ void enter_vnode_info( struct lsof_context *ctx, /* context */ struct vnode_info_path *vip) /* pointer to vnode info with path */ { - char buf[32], *cp; + char buf[32]; dev_t dev = 0; int devs = 0; struct mounts *mp; + /* * Derive file type. */ switch ((int)(vip->vip_vi.vi_stat.vst_mode & S_IFMT)) { case S_IFIFO: - cp = "FIFO"; + Lf->type = LSOF_FILE_FIFO; Ntype = N_FIFO; break; case S_IFCHR: - cp = "CHR"; + Lf->type = LSOF_FILE_CHAR; Ntype = N_CHR; break; case S_IFDIR: - cp = "DIR"; + Lf->type = LSOF_FILE_DIR; Ntype = N_REGLR; break; case S_IFBLK: - cp = "BLK"; + Lf->type = LSOF_FILE_BLOCK; Ntype = N_BLK; break; #if defined(S_IFLNK) case S_IFLNK: - cp = "LINK"; + Lf->type = LSOF_FILE_LINK; Ntype = N_REGLR; break; #endif /* defined(S_IFLNK) */ case S_IFREG: - cp = "REG"; + Lf->type = LSOF_FILE_REGULAR; Ntype = N_REGLR; break; default: - (void)snpf(buf, sizeof(buf), "%04o", - (((vip->vip_vi.vi_stat.vst_mode & S_IFMT) >> 12) & 0xfff)); - cp = buf; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = vip->vip_vi.vi_stat.vst_mode; Ntype = N_REGLR; } - if (!Lf->type[0]) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", cp); - Lf->ntype = Ntype; + /* * Save device number and path */ @@ -159,7 +153,7 @@ void enter_vnode_info( * Save node number. */ Lf->inode = (INODETYPE)vip->vip_vi.vi_stat.vst_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; /* * Save link count, as requested. */ @@ -187,6 +181,7 @@ void enter_vnode_info( switch (Ntype) { case N_CHR: case N_FIFO: + Lf->off_def = 1; break; default: Lf->sz = (SZOFFTYPE)vip->vip_vi.vi_stat.vst_size; @@ -210,6 +205,7 @@ void enter_vnode_info( /* * err2nm() -- convert errno to a message in Namech */ + void err2nm(struct lsof_context *ctx, /* context */ char *pfx) /* Namech message prefix */ { @@ -241,72 +237,10 @@ void err2nm(struct lsof_context *ctx, /* context */ enter_nm(ctx, Namech); } -/* - * print_nm() -- print Name column - */ -void print_nm(struct lsof_context *ctx, struct lfile *lf) { - unsigned char extra = 0; - - printname(ctx, 0); - -#if defined(PROC_PIDLISTFILEPORTS) - if (lf->fileport) - extra++; -#endif /* defined(PROC_PIDLISTFILEPORTS) */ - -#if defined(PROC_FP_GUARDED) - if (lf->guardflags) - extra++; -#endif /* defined(PROC_FP_GUARDED) */ - - if (extra) - (void)printf(" ("); - -#if defined(PROC_PIDLISTFILEPORTS) - if (lf->fileport) - (void)printf("fileport=0x%04x", lf->fileport); -#endif /* defined(PROC_PIDLISTFILEPORTS) */ - -#if defined(PROC_FP_GUARDED) - if (extra > 1) - putchar(','); - if (lf->guardflags) { - struct pff_tab *tp; - long gf; - - (void)printf("guard="); - tp = Pgf_tab; - gf = lf->guardflags; - while (gf && !FsvFlagX) { - while (tp->nm) { - if (gf & tp->val) - break; - tp++; - } - if (!tp->nm) - break; - gf &= ~(tp->val); - (void)printf("%s%s", tp->nm, gf ? "," : ""); - } - /* - * If flag bits remain, print them in hex. If hex output was - * specified with +fG, print all flag values, including zero, - * in hex. - */ - if (gf || FsvFlagX) - (void)printf("0x%lx", gf); - } -#endif /* defined(PROC_FP_GUARDED) */ - - if (extra) - (void)printf(")\n"); - else - putchar('\n'); -} - /* * print_v_path() -- print vnode's path */ + int print_v_path(struct lsof_context *ctx, struct lfile *lf) { if (lf->V_path) { safestrprt(lf->V_path, stdout, 0); @@ -318,27 +252,30 @@ int print_v_path(struct lsof_context *ctx, struct lfile *lf) { /* * process_atalk() -- process an Apple Talk file */ + void process_atalk(struct lsof_context *ctx, /* context */ int pid, /* PID */ int32_t fd) /* FD */ { - (void)snpf(Lf->type, sizeof(Lf->type), "ATALK"); + Lf->type = LSOF_FILE_APPLETALK; return; } /* * process_fsevents() -- process a file system events file */ + void process_fsevents(struct lsof_context *ctx, /* context */ int pid, /* PID */ int32_t fd) /* FD */ { - (void)snpf(Lf->type, sizeof(Lf->type), "FSEVENTS"); + Lf->type = LSOF_FILE_FSEVENTS; } /* * process_kqueue() -- process a kernel queue file */ + void process_kqueue(struct lsof_context *ctx, /* context */ int pid, /* PID */ int32_t fd) /* FD */ @@ -348,18 +285,21 @@ void process_kqueue(struct lsof_context *ctx, /* context */ /* * Get the kernel queue file information. */ - (void)snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); + Lf->type = LSOF_FILE_KQUEUE; nb = proc_pidfdinfo(pid, fd, PROC_PIDFDKQUEUEINFO, &kq, sizeof(kq)); if (nb <= 0) { (void)err2nm(ctx, "kqueue"); return; } else if (nb < sizeof(kq)) { - (void)fprintf( - stderr, - "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDKQUEUEINFO);\n", Pn, - pid, fd); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(kq), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDKQUEUEINFO);\n", + Pn, pid, fd); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(kq), nb); + } Error(ctx); } /* @@ -378,12 +318,13 @@ void process_kqueue(struct lsof_context *ctx, /* context */ /* * process_pipe() -- process pipe file */ + static void process_pipe_common(struct lsof_context *ctx, struct pipe_fdinfo *pi) { char dev_ch[32], *ep; size_t sz; - (void)snpf(Lf->type, sizeof(Lf->type), "PIPE"); + Lf->type = LSOF_FILE_PIPE; /* * Enter the pipe handle as the device. */ @@ -393,6 +334,7 @@ static void process_pipe_common(struct lsof_context *ctx, /* * Enable offset or size reporting. */ + Lf->off_def = 1; Lf->sz = (SZOFFTYPE)pi->pipeinfo.pipe_stat.vst_blksize; Lf->sz_def = 1; /* @@ -429,11 +371,15 @@ void process_pipe(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "pipe"); return; } else if (nb < sizeof(pi)) { - (void)fprintf( - stderr, "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPIPEINFO);\n", - Pn, pid, fd); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(pi), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPIPEINFO);\n", Pn, + pid, fd); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(pi), nb); + } Error(ctx); } @@ -456,12 +402,15 @@ void process_fileport_pipe(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "pipe"); return; } else if (nb < sizeof(pi)) { - (void)fprintf(stderr, - "%s: PID %d, FILEPORT %u; " - "proc_pidfileportinfo(PROC_PIDFILEPORTPIPEINFO);\n", - Pn, pid, fp); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(pi), nb); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: PID %d, FILEPORT %u; " + "proc_pidfileportinfo(PROC_PIDFILEPORTPIPEINFO);\n", + Pn, pid, fp); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(pi), nb); + } Error(ctx); } @@ -472,6 +421,7 @@ void process_fileport_pipe(struct lsof_context *ctx, /* context */ /* * process_psem() -- process a POSIX semaphore file */ + void process_psem(struct lsof_context *ctx, /* context */ int pid, /* PID */ int32_t fd) /* FD */ @@ -479,19 +429,23 @@ void process_psem(struct lsof_context *ctx, /* context */ int nb; struct psem_fdinfo ps; /* - * Get the semaphore file information. + * Get the sempaphore file information. */ - (void)snpf(Lf->type, sizeof(Lf->type), "PSXSEM"); + Lf->type = LSOF_FILE_POSIX_SEMA; nb = proc_pidfdinfo(pid, fd, PROC_PIDFDPSEMINFO, &ps, sizeof(ps)); if (nb <= 0) { (void)err2nm(ctx, "semaphore"); return; } else if (nb < sizeof(ps)) { - (void)fprintf( - stderr, "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPSEMINFO);\n", - Pn, pid, fd); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(ps), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPSEMINFO);\n", Pn, + pid, fd); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(ps), nb); + } Error(ctx); } /* @@ -506,21 +460,27 @@ void process_psem(struct lsof_context *ctx, /* context */ (void)snpf(Namech, Namechl, "%s", ps.pseminfo.psem_name); enter_nm(ctx, Namech); } + /* + * Unless file size has been specifically requested, enable the printing of + * file offset. + */ + Lf->off_def = 1; } /* * process_pshm() -- process POSIX shared memory file */ + static void process_pshm_common(struct lsof_context *ctx, struct pshm_fdinfo *ps) { - (void)snpf(Lf->type, sizeof(Lf->type), "PSXSHM"); + Lf->type = LSOF_FILE_POSIX_SHM; /* * Enter the POSIX shared memory file information. */ enter_file_info(ctx, &ps->pfi); /* - * If the POSIX shared memory file has a path name, enter it; otherwise, - * if it has a mapping address, enter that. + * If the POSIX shared memory file has a path name, enter it; otherwise, if + * it has a mapping address, enter that. */ if (ps->pshminfo.pshm_name[0]) { ps->pshminfo.pshm_name[sizeof(ps->pshminfo.pshm_name) - 1] = '\0'; @@ -535,6 +495,7 @@ static void process_pshm_common(struct lsof_context *ctx, /* * Enable offset or size reporting. */ + Lf->off_def = 1; Lf->sz = (SZOFFTYPE)ps->pshminfo.pshm_stat.vst_size; Lf->sz_def = 1; } @@ -553,11 +514,15 @@ void process_pshm(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "POSIX shared memory"); return; } else if (nb < sizeof(ps)) { - (void)fprintf( - stderr, "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPSHMINFO);\n", - Pn, pid, fd); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(ps), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d, FD %d; proc_pidfdinfo(PROC_PIDFDPSHMINFO);\n", Pn, + pid, fd); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(ps), nb); + } Error(ctx); } @@ -580,12 +545,15 @@ void process_fileport_pshm(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "POSIX shared memory"); return; } else if (nb < sizeof(ps)) { - (void)fprintf(stderr, - "%s: PID %d, FILEPORT %u; " - "proc_pidfileportinfo(PROC_PIDFILEPORTPSHMINFO);\n", - Pn, pid, fp); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(ps), nb); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: PID %d, FILEPORT %u; " + "proc_pidfileportinfo(PROC_PIDFILEPORTPSHMINFO);\n", + Pn, pid, fp); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(ps), nb); + } Error(ctx); } @@ -596,6 +564,7 @@ void process_fileport_pshm(struct lsof_context *ctx, /* context */ /* * process_vnode() -- process a vnode file */ + static void process_vnode_common(struct lsof_context *ctx, struct vnode_fdinfowithpath *vi) { /* @@ -618,8 +587,8 @@ void process_vnode(struct lsof_context *ctx, /* context */ /* * The file descriptor's vnode may have been revoked. This is a - * bit of a hack, since an ENOENT error might not always mean - * the descriptor's vnode has been revoked. As the libproc API + * bit of a hack, since an ENOENT error might not always mean the + * descriptor's vnode has been revoked. As the libproc API * matures, this code may need to be revisited. */ enter_nm(ctx, "(revoked)"); @@ -627,12 +596,15 @@ void process_vnode(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "vnode"); return; } else if (nb < sizeof(vi)) { - (void)fprintf( - stderr, - "%s: PID %d, FD %d: proc_pidfdinfo(PROC_PIDFDVNODEPATHINFO);\n", Pn, - pid, fd); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(vi), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d, FD %d: proc_pidfdinfo(PROC_PIDFDVNODEPATHINFO);\n", + Pn, pid, fd); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(vi), nb); + } Error(ctx); } @@ -654,8 +626,8 @@ void process_fileport_vnode(struct lsof_context *ctx, /* context */ /* * The file descriptor's vnode may have been revoked. This is a - * bit of a hack, since an ENOENT error might not always mean - * the descriptor's vnode has been revoked. As the libproc API + * bit of a hack, since an ENOENT error might not always mean the + * descriptor's vnode has been revoked. As the libproc API * matures, this code may need to be revisited. */ enter_nm(ctx, "(revoked)"); @@ -663,12 +635,15 @@ void process_fileport_vnode(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "vnode"); return; } else if (nb < sizeof(vi)) { - (void)fprintf(stderr, - "%s: PID %d, FILEPORT %u: " - "proc_pidfdinfo(PROC_PIDFDVNODEPATHINFO);\n", - Pn, pid, fp); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(vi), nb); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: PID %d, FILEPORT %u: " + "proc_pidfdinfo(PROC_PIDFDVNODEPATHINFO);\n", + Pn, pid, fp); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(vi), nb); + } Error(ctx); } diff --git a/lib/dialects/darwin/dlsof.h b/lib/dialects/darwin/dlsof.h index df38e487..60d9384c 100644 --- a/lib/dialects/darwin/dlsof.h +++ b/lib/dialects/darwin/dlsof.h @@ -128,4 +128,7 @@ struct sfile { # define offsetof(type, member) ((size_t)(&((type *)0)->member)) # endif /* !defined(offsetof) */ +struct lsof_context_dialect { +}; + #endif /* DARWIN_LSOF_H */ diff --git a/lib/dialects/darwin/dmnt.c b/lib/dialects/darwin/dmnt.c index 42af045f..f2a3b29b 100644 --- a/lib/dialects/darwin/dmnt.c +++ b/lib/dialects/darwin/dmnt.c @@ -43,9 +43,6 @@ static char copyright[] = "@(#) Copyright 2005 Apple Computer, Inc. and " * Local static information */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() -- read mount table */ @@ -71,7 +68,8 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Access mount information. */ if ((n = getmntinfo(&mb, MNT_NOWAIT)) <= 0) { - (void)fprintf(stderr, "%s: no mount information\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no mount information\n", Pn); return (0); } /* @@ -110,16 +108,19 @@ struct mounts *readmnt(struct lsof_context *ctx) { no_space_for_mount: - (void)fprintf(stderr, "%s: no space for mount at ", Pn); - safestrprt(mb->f_mntonname, stderr, 0); - (void)fprintf(stderr, " ("); - safestrprt(mb->f_mntfromname, stderr, 0); - (void)fprintf(stderr, ")\n"); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for mount at ", Pn); + safestrprt(mb->f_mntonname, ctx->err, 0); + (void)fprintf(ctx->err, " ("); + safestrprt(mb->f_mntfromname, ctx->err, 0); + (void)fprintf(ctx->err, ")\n"); + } Error(ctx); + return NULL; } if (!(ln = Readlink(ctx, dn))) { - if (!Fwarn) { - (void)fprintf(stderr, + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } continue; @@ -134,21 +135,21 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Stat() the directory. */ if (statsafely(ctx, dn, &sb)) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: can't stat() ", Pn); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: WARNING: can't stat() ", Pn); - safestrprt(mb->f_fstypename, stderr, 0); + safestrprt(mb->f_fstypename, ctx->err, 0); - (void)fprintf(stderr, " file system "); - safestrprt(mb->f_mntonname, stderr, 1); - (void)fprintf(stderr, + (void)fprintf(ctx->err, " file system "); + safestrprt(mb->f_mntonname, ctx->err, 1); + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } (void)bzero((char *)&sb, sizeof(sb)); sb.st_dev = (dev_t)mb->f_fsid.val[0]; sb.st_mode = S_IFDIR | 0777; - if (!Fwarn) { - (void)fprintf(stderr, + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, " assuming \"dev=%x\" from mount table\n", sb.st_dev); } diff --git a/lib/dialects/darwin/dproc.c b/lib/dialects/darwin/dproc.c index 19bb6709..fb14012b 100644 --- a/lib/dialects/darwin/dproc.c +++ b/lib/dialects/darwin/dproc.c @@ -107,6 +107,7 @@ static void process_fileports(struct lsof_context *ctx, int pid, int ckscko); /* * enter_vn_text() -- enter vnode information text reference */ + static void enter_vn_text(struct lsof_context *ctx, /* context */ struct vnode_info_path *vip, /* vnode info */ int *n) /* number of vips[] entries in use */ @@ -124,7 +125,7 @@ static void enter_vn_text(struct lsof_context *ctx, /* context */ /* * Save the text file information. */ - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); Cfp = (struct file *)NULL; (void)enter_vnode_info(ctx, vip); if (Lf->sf) @@ -145,9 +146,11 @@ static void enter_vn_text(struct lsof_context *ctx, /* context */ Vips = (struct vips_info *)realloc((MALLOC_P *)Vips, (MALLOC_S)NbVips); if (!Vips) { - (void)fprintf(stderr, "%s: PID %d: no text recording space\n", Pn, - Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, "%s: PID %d: no text recording space\n", + Pn, Lp->pid); Error(ctx); + return; } } /* @@ -161,6 +164,7 @@ static void enter_vn_text(struct lsof_context *ctx, /* context */ /* * gather_proc_info() -- gather process information */ + void gather_proc_info(struct lsof_context *ctx) { short cckreg; /* conditional status of regular file * checking: @@ -231,9 +235,11 @@ void gather_proc_info(struct lsof_context *ctx) { * extra); then read the list of PIDs. */ if ((nb = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0)) <= 0) { - (void)fprintf(stderr, "%s: can't get PID byte count: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't get PID byte count: %s\n", Pn, + strerror(errno)); Error(ctx); + return; } if (nb > NbPids) { while (nb > NbPids) { @@ -244,9 +250,12 @@ void gather_proc_info(struct lsof_context *ctx) { else Pids = (int *)realloc((MALLOC_P *)Pids, (MALLOC_S)NbPids); if (!Pids) { - (void)fprintf(stderr, "%s: can't allocate space for %d PIDs\n", Pn, - (int)(NbPids / sizeof(int *))); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate space for %d PIDs\n", Pn, + (int)(NbPids / sizeof(int *))); Error(ctx); + return; } } /* @@ -254,9 +263,11 @@ void gather_proc_info(struct lsof_context *ctx) { */ for (ef = 0; !ef;) { if ((nb = proc_listpids(PROC_ALL_PIDS, 0, Pids, NbPids)) <= 0) { - (void)fprintf(stderr, "%s: can't get list of PIDs: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't get list of PIDs: %s\n", Pn, + strerror(errno)); Error(ctx); + return; } if ((nb + sizeof(int)) < NbPids) { @@ -274,9 +285,12 @@ void gather_proc_info(struct lsof_context *ctx) { NbPids += PIDS_INCR; Pids = (int *)realloc((MALLOC_P *)Pids, (MALLOC_S)NbPids); if (!Pids) { - (void)fprintf(stderr, "%s: can't allocate space for %d PIDs\n", - Pn, (int)(NbPids / sizeof(int *))); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate space for %d PIDs\n", Pn, + (int)(NbPids / sizeof(int *))); Error(ctx); + return; } } } @@ -290,18 +304,23 @@ void gather_proc_info(struct lsof_context *ctx) { if (nb <= 0) { if ((errno == EPERM) || (errno == ESRCH)) continue; - if (!Fwarn) { - (void)fprintf(stderr, "%s: PID %d information error: %s\n", Pn, - pid, strerror(errno)); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: PID %d information error: %s\n", + Pn, pid, strerror(errno)); } continue; } else if (nb < sizeof(tai)) { - (void)fprintf(stderr, - "%s: PID %d: proc_pidinfo(PROC_PIDTASKALLINFO);\n", - Pn, pid); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(tai), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d: proc_pidinfo(PROC_PIDTASKALLINFO);\n", Pn, + pid); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(tai), nb); + } Error(ctx); + return; } /* * Check for process or command exclusion. @@ -336,14 +355,17 @@ void gather_proc_info(struct lsof_context *ctx) { cre = errno; cres = 1; } else if (nb < sizeof(vpi)) { - (void)fprintf( - stderr, - "%s: PID %d: proc_pidinfo(PROC_PIDVNODEPATHINFO);\n", Pn, - pid); - (void)fprintf(stderr, - " too few bytes; expected %ld, got %d\n", - sizeof(vpi), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d: proc_pidinfo(PROC_PIDVNODEPATHINFO);\n", + Pn, pid); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(vpi), nb); + } Error(ctx); + return; } else cres = 0; } @@ -364,7 +386,7 @@ void gather_proc_info(struct lsof_context *ctx) { */ if (!ckscko) { if (cres || vpi.pvi_cdir.vip_path[0]) { - alloc_lfile(ctx, CWD, -1); + alloc_lfile(ctx, LSOF_FD_CWD, -1); Cfp = (struct file *)NULL; if (cres) { @@ -375,7 +397,7 @@ void gather_proc_info(struct lsof_context *ctx) { */ if (cre != ESRCH) { (void)snpf(Namech, Namechl, "%s|%s info error: %s", - CWD + 1, RTD + 1, strerror(cre)); + &CWD[1], &RTD[1], strerror(cre)); Namech[Namechl - 1] = '\0'; enter_nm(ctx, Namech); if (Lf->sf) @@ -393,7 +415,7 @@ void gather_proc_info(struct lsof_context *ctx) { */ if (!ckscko) { if (!cres && vpi.pvi_rdir.vip_path[0]) { - alloc_lfile(ctx, RTD, -1); + alloc_lfile(ctx, LSOF_FD_ROOT_DIR, -1); Cfp = (struct file *)NULL; (void)enter_vnode_info(ctx, &vpi.pvi_rdir); if (Lf->sf) @@ -443,9 +465,16 @@ void gather_proc_info(struct lsof_context *ctx) { void initialize(struct lsof_context *ctx) {} +/* + * deinitialize() -- perform all cleanup + */ + +void deinitialize(struct lsof_context *ctx) {} + /* * process_fds() -- process file descriptors */ + static void process_fds(struct lsof_context *ctx, /* context */ int pid, /* PID of interest */ uint32_t n, /* max FDs */ @@ -468,9 +497,12 @@ static void process_fds(struct lsof_context *ctx, /* context */ Fds = (struct proc_fdinfo *)realloc((MALLOC_P *)Fds, (MALLOC_S)NbFds); } if (!Fds) { - (void)fprintf(stderr, "%s: PID %d: can't allocate space for %d FDs\n", - Pn, pid, (int)(NbFds / sizeof(struct proc_fdinfo))); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: PID %d: can't allocate space for %d FDs\n", Pn, + pid, (int)(NbFds / sizeof(struct proc_fdinfo))); Error(ctx); + return; } /* * Get FD information for the process. @@ -487,7 +519,7 @@ static void process_fds(struct lsof_context *ctx, /* context */ /* * Make a dummy file entry with an error message in its NAME column. */ - alloc_lfile(ctx, " err", -1); + alloc_lfile(ctx, LSOF_FD_ERROR, -1); (void)snpf(Namech, Namechl, "FD info error: %s", strerror(errno)); Namech[Namechl - 1] = '\0'; enter_nm(ctx, Namech); @@ -501,7 +533,7 @@ static void process_fds(struct lsof_context *ctx, /* context */ */ for (i = 0; i < nf; i++) { fdp = &Fds[i]; - alloc_lfile(ctx, NULL, (int)fdp->proc_fd); + alloc_lfile(ctx, LSOF_FD_NUMERIC, (int)fdp->proc_fd); /* * Process the file by its type. */ @@ -555,6 +587,7 @@ static void process_fds(struct lsof_context *ctx, /* context */ /* * process_fileports() -- process fileports */ + static void process_fileports(struct lsof_context *ctx, /* context */ int pid, /* PID of interest */ int ckscko) /* check socket files only */ @@ -584,7 +617,7 @@ static void process_fileports(struct lsof_context *ctx, /* context */ /* * Make a dummy file entry with an error message in its NAME column. */ - alloc_lfile(ctx, " err", -1); + alloc_lfile(ctx, LSOF_FD_ERROR, -1); (void)snpf(Namech, Namechl, "FILEPORT info error: %s", strerror(errno)); Namech[Namechl - 1] = '\0'; @@ -602,9 +635,12 @@ static void process_fileports(struct lsof_context *ctx, /* context */ } else { if (Fps && ((nb = proc_pidinfo(pid, PROC_PIDLISTFILEPORTS, 0, NULL, 0)) <= 0)) { - (void)fprintf(stderr, "%s: can't get fileport byte count: %s\n", - Pn, strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't get fileport byte count: %s\n", Pn, + strerror(errno)); Error(ctx); + return; } /* @@ -631,7 +667,7 @@ static void process_fileports(struct lsof_context *ctx, /* context */ * fileport reported as "fp." with "(fileport=0xXXXX)" in the Name * column */ - alloc_lfile(ctx, " fp.", -1); + alloc_lfile(ctx, LSOF_FD_FILEPORT, -1); Lf->fileport = fpi->proc_fileport; /* * Process the file by its type. @@ -670,6 +706,7 @@ static void process_fileports(struct lsof_context *ctx, /* context */ /* * process_text() -- process text information */ + static void process_text(struct lsof_context *ctx, /* context */ int pid) /* PID */ { @@ -691,7 +728,7 @@ static void process_text(struct lsof_context *ctx, /* context */ /* * Warn about all other errors via a NAME column message. */ - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); Cfp = (struct file *)NULL; (void)snpf(Namech, Namechl, "region info error: %s", strerror(errno)); @@ -701,12 +738,17 @@ static void process_text(struct lsof_context *ctx, /* context */ link_lfile(ctx); return; } else if (nb < sizeof(rwpi)) { - (void)fprintf(stderr, - "%s: PID %d: proc_pidinfo(PROC_PIDREGIONPATHINFO);\n", - Pn, pid); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(rwpi), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d: proc_pidinfo(PROC_PIDREGIONPATHINFO);\n", Pn, + pid); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(rwpi), nb); + } Error(ctx); + return; } if (rwpi.prp_vip.vip_path[0]) enter_vn_text(ctx, &rwpi.prp_vip, &n); @@ -742,9 +784,12 @@ static void process_threads(struct lsof_context *ctx, /* context */ Threads = (uint64_t *)realloc((MALLOC_P *)Threads, (MALLOC_S)NbThreads); if (!Threads) { - (void)fprintf(stderr, "%s: can't allocate space for %d Threads\n", - Pn, (int)(NbThreads / sizeof(int *))); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate space for %d Threads\n", Pn, + (int)(NbThreads / sizeof(int *))); Error(ctx); + return; } } /* @@ -783,7 +828,7 @@ static void process_threads(struct lsof_context *ctx, /* context */ /* * Warn about all other errors via a NAME column message. */ - alloc_lfile(ctx, TWD, -1); + alloc_lfile(ctx, LSOF_FD_TASK_CWD, -1); Cfp = (struct file *)NULL; (void)snpf(Namech, Namechl, "thread info error: %s", strerror(errno)); @@ -793,15 +838,19 @@ static void process_threads(struct lsof_context *ctx, /* context */ link_lfile(ctx); return; } else if (nb < sizeof(tpi)) { - (void)fprintf(stderr, - "%s: PID %d: proc_pidinfo(PROC_PIDTHREADPATHINFO);\n", - Pn, pid); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: PID %d: proc_pidinfo(PROC_PIDTHREADPATHINFO);\n", Pn, + pid); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", sizeof(tpi), nb); Error(ctx); + return; } if (tpi.pvip.vip_path[0]) { - alloc_lfile(ctx, TWD, -1); + alloc_lfile(ctx, LSOF_FD_TASK_CWD, -1); Cfp = (struct file *)NULL; (void)enter_vnode_info(ctx, &tpi.pvip); if (Lf->sf) diff --git a/lib/dialects/darwin/dsock.c b/lib/dialects/darwin/dsock.c index 4f6c9eda..aa6c8f47 100644 --- a/lib/dialects/darwin/dsock.c +++ b/lib/dialects/darwin/dsock.c @@ -59,8 +59,7 @@ static void process_socket_common(struct lsof_context *ctx, /* * Enter basic socket values. */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_SOCKET; /* * Enter basic file information. */ @@ -75,6 +74,7 @@ static void process_socket_common(struct lsof_context *ctx, else Lf->sz = (SZOFFTYPE)(si->psi.soi_rcv.sbi_cc + si->psi.soi_snd.sbi_cc); Lf->sz_def = 1; + Lf->off_def = 1; #if defined(HASTCPTPIQ) /* @@ -117,8 +117,7 @@ static void process_socket_common(struct lsof_context *ctx, /* * Process IPv[46] sockets. */ - (void)snpf(Lf->type, sizeof(Lf->type), - (fam == AF_INET) ? "IPv4" : "IPv6"); + Lf->type = (fam == AF_INET) ? LSOF_FILE_IPV4 : LSOF_FILE_IPV6; if ((si->psi.soi_kind != SOCKINFO_IN) && (si->psi.soi_kind != SOCKINFO_TCP)) { break; @@ -150,11 +149,10 @@ static void process_socket_common(struct lsof_context *ctx, * Process an Internet domain socket. */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (fam == AF_INET)) || - ((FnetTy == 6) && (fam == AF_INET6))) + if (FnetTy == AF_UNSPEC || (FnetTy == fam)) Lf->sf |= SELNET; } - printiproto(si->psi.soi_protocol); + enter_ip_proto(ctx, si->psi.soi_protocol); if ((si->psi.soi_kind == SOCKINFO_TCP) && si->psi.soi_proto.pri_tcp.tcpsi_tp) { enter_dev_ch(ctx, @@ -279,7 +277,7 @@ static void process_socket_common(struct lsof_context *ctx, /* * Process a UNIX domain socket. */ - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; if (si->psi.soi_kind != SOCKINFO_UN) break; if (Funix) @@ -333,14 +331,15 @@ static void process_socket_common(struct lsof_context *ctx, /* * Process a ROUTE domain socket. */ - (void)snpf(Lf->type, sizeof(Lf->type), "rte"); + Lf->type = LSOF_FILE_ROUTE; + Lf->off_def = 1; break; case AF_NDRV: /* * Process an NDRV domain socket. */ - (void)snpf(Lf->type, sizeof(Lf->type), "ndrv"); + Lf->type = LSOF_FILE_NET_DRIVER; if (si->psi.soi_kind != SOCKINFO_NDRV) break; enter_dev_ch(ctx, print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0)); @@ -356,7 +355,7 @@ static void process_socket_common(struct lsof_context *ctx, /* * Process an [internal] key-management function socket. */ - (void)snpf(Lf->type, sizeof(Lf->type), "key"); + Lf->type = LSOF_FILE_INTERNAL_KEY; enter_dev_ch(ctx, print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0)); break; case AF_SYSTEM: @@ -364,7 +363,7 @@ static void process_socket_common(struct lsof_context *ctx, /* * Process a SYSTEM domain socket. */ - (void)snpf(Lf->type, sizeof(Lf->type), "systm"); + Lf->type = LSOF_FILE_SYSTEM; switch (si->psi.soi_kind) { case SOCKINFO_KERN_EVENT: enter_dev_ch(ctx, @@ -389,7 +388,7 @@ static void process_socket_common(struct lsof_context *ctx, /* * Process a PPP domain socket. */ - (void)snpf(Lf->type, sizeof(Lf->type), "ppp"); + Lf->type = LSOF_FILE_PPP; enter_dev_ch(ctx, print_kptr((KA_T)si->psi.soi_pcb, (char *)NULL, 0)); break; default: @@ -416,13 +415,17 @@ void process_socket(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "socket"); return; } else if (nb < sizeof(si)) { - (void)fprintf( - stderr, - "%s: PID %d, FD %d: proc_pidfdinfo(PROC_PIDFDSOCKETINFO);\n", Pn, - pid, fd); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(si), nb); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: PID %d, FD %d: proc_pidfdinfo(PROC_PIDFDSOCKETINFO);\n", + Pn, pid, fd); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(si), nb); + } Error(ctx); + return; } process_socket_common(ctx, &si); @@ -444,13 +447,17 @@ void process_fileport_socket(struct lsof_context *ctx, /* context */ (void)err2nm(ctx, "socket"); return; } else if (nb < sizeof(si)) { - (void)fprintf(stderr, - "%s: PID %d, FILEPORT %u: " - "proc_pidfileportinfo(PROC_PIDFILEPORTSOCKETINFO);\n", - Pn, pid, fp); - (void)fprintf(stderr, " too few bytes; expected %ld, got %d\n", - sizeof(si), nb); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: PID %d, FILEPORT %u: " + "proc_pidfileportinfo(PROC_PIDFILEPORTSOCKETINFO);\n", + Pn, pid, fp); + (void)fprintf(ctx->err, + " too few bytes; expected %ld, got %d\n", + sizeof(si), nb); + } Error(ctx); + return; } process_socket_common(ctx, &si); diff --git a/lib/dialects/darwin/dstore.c b/lib/dialects/darwin/dstore.c index a6ee10a1..e726c4a0 100644 --- a/lib/dialects/darwin/dstore.c +++ b/lib/dialects/darwin/dstore.c @@ -85,16 +85,3 @@ struct pff_tab Pof_tab[] = { {(long)0, NULL}}; #endif /* defined(HASFSTRUCT) */ - -#if defined(PROC_FP_GUARDED) -/* - * Pgf_tab[] - table for print process open file guard flags - */ - -struct pff_tab Pgf_tab[] = {{(long)PROC_FI_GUARD_CLOSE, "CLOSE"}, - {(long)PROC_FI_GUARD_DUP, "DUP"}, - {(long)PROC_FI_GUARD_SOCKET_IPC, "SOCKET"}, - {(long)PROC_FI_GUARD_FILEPORT, "FILEPORT"}, - - {(long)0, NULL}}; -#endif /* defined(PROC_FP_GUARDED) */ diff --git a/lib/dialects/darwin/machine.h b/lib/dialects/darwin/machine.h index 0220b01e..e776ec05 100644 --- a/lib/dialects/darwin/machine.h +++ b/lib/dialects/darwin/machine.h @@ -134,7 +134,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ # define HASFSINO 1 @@ -144,7 +144,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -340,14 +340,6 @@ # define HASPRIVNMCACHE print_v_path -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -505,7 +497,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -542,6 +534,7 @@ # define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */ /* #define USE_LIB_READDEV 1 rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ /* #define USE_LIB_RNCH 1 rnch.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ diff --git a/lib/dialects/freebsd/dlsof.h b/lib/dialects/freebsd/dlsof.h index a8efa59c..4ef3784a 100644 --- a/lib/dialects/freebsd/dlsof.h +++ b/lib/dialects/freebsd/dlsof.h @@ -384,8 +384,6 @@ typedef u_long KA_T; extern struct file *Cfp; -extern kvm_t *Kd; - # if defined(P_ADDR) extern KA_T Kpa; # endif /* defined(P_ADDR) */ @@ -403,7 +401,6 @@ struct l_vfs { char *fsname; /* file system name */ struct l_vfs *next; /* forward link */ }; -extern struct l_vfs *Lvfs; struct mounts { char *dir; /* directory (mounted on) */ @@ -425,10 +422,6 @@ extern KA_T X_bfopsa; # define X_NCSIZE "ncsize" # define NL_NAME n_name -extern int Np; /* number of kernel processes */ - -extern struct kinfo_proc *P; /* local process table copy */ - struct sfile { char *aname; /* argument file name */ char *name; /* file name (after readlink()) */ @@ -539,4 +532,13 @@ struct namecache { # include +struct lsof_context_dialect { + /* local vfs structure table */ + struct l_vfs *local_vfs; + /* kvm descriptor */ + kvm_t *kvm; +}; +# define Lvfs (ctxd.local_vfs) +# define Kd (ctxd.kvm) + #endif /* defined(FREEBSD_LSOF_H) */ diff --git a/lib/dialects/freebsd/dmnt.c b/lib/dialects/freebsd/dmnt.c index 5144fbc9..2f0367a0 100644 --- a/lib/dialects/freebsd/dmnt.c +++ b/lib/dialects/freebsd/dmnt.c @@ -39,9 +39,6 @@ static char copyright[] = * Local static information */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - #undef HAS_MNT_NAMES #if defined(MOUNT_NONE) @@ -68,7 +65,8 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Access mount information. */ if ((n = getmntinfo(&mb, MNT_NOWAIT)) <= 0) { - (void)fprintf(stderr, "%s: no mount information\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no mount information\n", Pn); return (0); } /* @@ -92,16 +90,18 @@ struct mounts *readmnt(struct lsof_context *ctx) { no_space_for_mount: - (void)fprintf(stderr, "%s: no space for mount at ", Pn); - safestrprt(mb->f_mntonname, stderr, 0); - (void)fprintf(stderr, " ("); - safestrprt(mb->f_mntfromname, stderr, 0); - (void)fprintf(stderr, ")\n"); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for mount at ", Pn); + safestrprt(mb->f_mntonname, ctx->err, 0); + (void)fprintf(ctx->err, " ("); + safestrprt(mb->f_mntfromname, ctx->err, 0); + (void)fprintf(ctx->err, ")\n"); + } Error(ctx); } if (!(ln = Readlink(ctx, dn))) { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } continue; @@ -116,25 +116,25 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Stat() the directory. */ if (statsafely(ctx, dn, &sb)) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: can't stat() ", Pn); + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: can't stat() ", Pn); #if defined(HAS_MNT_NAMES) - safestrprt(mnt_names[mb->f_type], stderr, 0); + safestrprt(mnt_names[mb->f_type], ctx->err, 0); #else /* !defined(HAS_MNT_NAMES) */ - safestrprt(mb->f_fstypename, stderr, 0); + safestrprt(mb->f_fstypename, ctx->err, 0); #endif /* defined(HAS_MNT_NAMES) */ - (void)fprintf(stderr, " file system "); - safestrprt(mb->f_mntonname, stderr, 1); - (void)fprintf(stderr, + (void)fprintf(ctx->err, " file system "); + safestrprt(mb->f_mntonname, ctx->err, 1); + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } (void)bzero((char *)&sb, sizeof(sb)); sb.st_dev = (dev_t)mb->f_fsid.val[0]; sb.st_mode = S_IFDIR | 0777; - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, " assuming \"dev=%lx\" from mount table\n", (unsigned long)sb.st_dev); } @@ -226,13 +226,16 @@ struct l_vfs *readvfs(struct lsof_context *ctx, uint64_t fsid, return (vp); } if (!(vp = (struct l_vfs *)malloc(sizeof(struct l_vfs)))) { - (void)fprintf(stderr, "%s: PID %d, no space for vfs\n", Pn, Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, "%s: PID %d, no space for vfs\n", Pn, + Lp->pid); Error(ctx); } if (!(vp->dir = mkstrcpy(m.f_mntonname, (MALLOC_S *)NULL)) || !(vp->fsname = mkstrcpy(m.f_mntfromname, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: PID %d, no space for mount names\n", Pn, - Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, "%s: PID %d, no space for mount names\n", + Pn, Lp->pid); Error(ctx); } vp->fsid = fsid; @@ -248,12 +251,15 @@ struct l_vfs *readvfs(struct lsof_context *ctx, uint64_t fsid, len = MFSNAMELEN - 1; if (!(vp->typnm = mkstrcat(m.f_fstypename, len, (char *)NULL, -1, (char *)NULL, -1, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for fs type name: ", Pn); - safestrprt(m.f_fstypename, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for fs type name: ", Pn); + safestrprt(m.f_fstypename, ctx->err, 1); + } Error(ctx); } } else - vp->typnm = ""; + vp->typnm = mkstrcpy("", (MALLOC_S *)NULL); } #endif /* defined(MOUNT_NONE) */ diff --git a/lib/dialects/freebsd/dnode.c b/lib/dialects/freebsd/dnode.c index fc73e643..8ce909b8 100644 --- a/lib/dialects/freebsd/dnode.c +++ b/lib/dialects/freebsd/dnode.c @@ -50,7 +50,8 @@ static void get_lock_state_kvm(struct lsof_context *ctx, KA_T f); */ #ifdef KERN_LOCKF -static void get_lock_state_sysctl(struct kinfo_file *kf, +static void get_lock_state_sysctl(struct lsof_context *ctx, + struct kinfo_file *kf, struct lock_list *locks) { struct kinfo_lockf key, *lock; @@ -63,9 +64,11 @@ static void get_lock_state_sysctl(struct kinfo_file *kf, if (lock != NULL) { int whole_file = (lock->kl_start == 0 && lock->kl_len == 0); if (lock->kl_rw == KLOCKF_RW_READ) - Lf->lock = whole_file ? 'R' : 'r'; + Lf->lock = + whole_file ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL; else if (lock->kl_rw == KLOCKF_RW_WRITE) - Lf->lock = whole_file ? 'W' : 'w'; + Lf->lock = + whole_file ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL; } } #endif /* KERN_LOCKF */ @@ -98,9 +101,9 @@ static void get_lock_state_kvm(struct lsof_context *ctx, /* context */ else lt = 0; if (le.lf_type == F_RDLCK) - Lf->lock = lt ? 'R' : 'r'; + Lf->lock = lt ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL; else if (le.lf_type == F_WRLCK) - Lf->lock = lt ? 'W' : 'w'; + Lf->lock = lt ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL; return; } } while ((lep = (KA_T)le.lf_link.le_next) && (lep != lef)); @@ -139,9 +142,9 @@ static void get_lock_state_kvm(struct lsof_context *ctx, /* context */ else lt = 0; if (lf.lf_type == F_RDLCK) - Lf->lock = lt ? 'R' : 'r'; + Lf->lock = lt ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL; else if (lf.lf_type == F_WRLCK) - Lf->lock = lt ? 'W' : 'w'; + Lf->lock = lt ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL; break; } while ((lfp = (KA_T)lf.lf_next) && (lfp != f)); } @@ -156,14 +159,14 @@ static void get_lock_state_kvm(struct lsof_context *ctx, /* context */ * a file processing function. However, the Net and Open BSD sources don't * require a dfile.c, so this is the next best location for the function. */ -void process_kf_kqueue(struct lsof_context *ctx, /* context */ - struct kinfo_file *kf, /* kernel file*/ - KA_T ka /* kernel address */) { + +void process_kf_kqueue(struct lsof_context *ctx, struct kinfo_file *kf, + KA_T ka) { # if __FreeBSD_version < 1400062 struct kqueue kq; /* kqueue structure */ # endif /* __FreeBSD_version < 1400062 */ - (void)snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); + Lf->type = LSOF_FILE_KQUEUE; enter_dev_ch(ctx, print_kptr(ka, (char *)NULL, 0)); # if __FreeBSD_version >= 1400062 (void)snpf(Namech, Namechl, "count=%d, state=%#x", @@ -181,7 +184,7 @@ void process_kf_kqueue(struct lsof_context *ctx, /* context */ #if defined(KF_TYPE_EVENTFD) void process_eventfd(struct lsof_context *ctx, struct kinfo_file *kf) { - (void)snpf(Lf->type, sizeof(Lf->type), "EVENTFD"); + Lf->type = LSOF_FILE_EVENTFD; # if __FreeBSD_version >= 1400062 enter_dev_ch( ctx, print_kptr(kf->kf_un.kf_eventfd.kf_eventfd_addr, (char *)NULL, 0)); @@ -194,13 +197,13 @@ void process_eventfd(struct lsof_context *ctx, struct kinfo_file *kf) { #endif /* defined(KF_TYPE_EVENTFD) */ void process_shm(struct lsof_context *ctx, struct kinfo_file *kf) { - (void)snpf(Lf->type, sizeof(Lf->type), "SHM"); + Lf->type = LSOF_FILE_POSIX_SHM; Lf->sz = kf->kf_un.kf_file.kf_file_size; Lf->sz_def = 1; Lf->off_def = 0; if (kf->kf_un.kf_file.kf_file_fileid != VNOVAL) { Lf->inode = kf->kf_un.kf_file.kf_file_fileid; - Lf->inp_ty = 1; + Lf->inode_def = 1; } if (kf->kf_path[0]) { snpf(Namech, Namechl, "%s", kf->kf_path); @@ -211,7 +214,7 @@ void process_shm(struct lsof_context *ctx, struct kinfo_file *kf) { void process_procdesc(struct lsof_context *ctx, struct kinfo_file *kf) { char pidstr[50]; - snpf(Lf->type, sizeof(Lf->type), "PROCDSC"); + Lf->type = LSOF_FILE_PROCDESC; snpf(pidstr, sizeof(pidstr), "pid=%d", kf->kf_un.kf_proc.kf_pid); add_nma(ctx, pidstr, strlen(pidstr)); if (kf->kf_path[0]) { @@ -220,42 +223,43 @@ void process_procdesc(struct lsof_context *ctx, struct kinfo_file *kf) { } } -static const char *parse_proc_path(struct kinfo_file *kf, int *proc_pid) { - const char *ty; +static enum lsof_file_type parse_proc_path(struct kinfo_file *kf, + int *proc_pid) { + enum lsof_file_type ty; char *basename; - ty = (char *)NULL; + ty = LSOF_FILE_UNKNOWN; basename = strrchr(kf->kf_path, '/'); if (basename) { ++basename; if (!strcmp(basename, "cmdline")) { } else if (!strcmp(basename, "dbregs")) { } else if (!strcmp(basename, "etype")) { - ty = "PETY"; + ty = LSOF_FILE_PROC_EXEC_TYPE; } else if (!strcmp(basename, "file")) { - ty = "PFIL"; + ty = LSOF_FILE_PROC_FILE; } else if (!strcmp(basename, "fpregs")) { - ty = "PFPR"; + ty = LSOF_FILE_PROC_FP_REGS; } else if (!strcmp(basename, "map")) { - ty = "PMAP"; + ty = LSOF_FILE_PROC_MAP; } else if (!strcmp(basename, "mem")) { - ty = "PMEM"; + ty = LSOF_FILE_PROC_MEMORY; } else if (!strcmp(basename, "note")) { - ty = "PNTF"; + ty = LSOF_FILE_PROC_PROC_NOTIFIER; } else if (!strcmp(basename, "notepg")) { - ty = "PGID"; + ty = LSOF_FILE_PROC_GROUP_NOTIFIER; } else if (!strcmp(basename, "osrel")) { } else if (!strcmp(basename, "regs")) { - ty = "PREG"; + ty = LSOF_FILE_PROC_REGS; } else if (!strcmp(basename, "rlimit")) { } else if (!strcmp(basename, "status")) { - ty = "PSTA"; + ty = LSOF_FILE_PROC_STATUS; } else { /* we're excluded all files - must be a directory, either * /proc/ or /proc itself */ - ty = "PDIR"; + ty = LSOF_FILE_PROC_DIR; } - if (ty && strcmp(ty, "PDIR") != 0) { + if (ty && ty != LSOF_FILE_PROC_DIR) { char *parent_dir; --basename; *basename = '\0'; @@ -277,7 +281,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, dev_t dev = 0, rdev = 0; unsigned char devs; unsigned char rdevs; - const char *ty; + enum lsof_file_type ty; KA_T va; struct vnode *v, vb; struct l_vfs *vfs; @@ -385,7 +389,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, } #ifdef KERN_LOCKF - get_lock_state_sysctl(kf, locks); + get_lock_state_sysctl(ctx, kf, locks); #elif defined(HAS_V_LOCKF) if (v && v->v_lockf) (void)get_lock_state_kvm(ctx, (KA_T)v->v_lockf); @@ -463,14 +467,16 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, */ if (kf->kf_un.kf_file.kf_file_fileid != VNOVAL) { Lf->inode = kf->kf_un.kf_file.kf_file_fileid; - Lf->inp_ty = 1; + Lf->inode_def = 1; } /* * Obtain the file size. */ + Lf->off_def = 1; switch (Ntype) { case N_FIFO: + Lf->off_def = 1; break; case N_PROC: Lf->sz = kf->kf_un.kf_file.kf_file_size; @@ -489,6 +495,8 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, if (kf_vtype == KF_VTYPE_VREG || kf_vtype == KF_VTYPE_VDIR) { Lf->sz = kf->kf_un.kf_file.kf_file_size; Lf->sz_def = 1; + } else if ((kf_vtype == KF_VTYPE_VCHR || kf_vtype == KF_VTYPE_VBLK)) { + Lf->off_def = 1; } break; default: @@ -533,39 +541,39 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, Lf->rdev_def = rdevs; switch (kf_vtype) { case KF_VTYPE_VNON: - ty = "VNON"; + Lf->type = LSOF_FILE_VNODE_VNON; break; case KF_VTYPE_VREG: + Lf->type = LSOF_FILE_VNODE_VREG; + break; case KF_VTYPE_VDIR: - ty = (kf_vtype == KF_VTYPE_VREG) ? "VREG" : "VDIR"; + Lf->type = LSOF_FILE_VNODE_VDIR; break; case KF_VTYPE_VBLK: - ty = "VBLK"; + Lf->type = LSOF_FILE_VNODE_VBLK; Ntype = N_BLK; break; case KF_VTYPE_VCHR: - ty = "VCHR"; + Lf->type = LSOF_FILE_VNODE_VCHR; Ntype = N_CHR; break; case KF_VTYPE_VLNK: - ty = "VLNK"; + Lf->type = LSOF_FILE_VNODE_VLNK; break; case KF_VTYPE_VSOCK: - ty = "SOCK"; + Lf->type = LSOF_FILE_VNODE_VSOCK; break; case KF_VTYPE_VBAD: - ty = "VBAD"; + Lf->type = LSOF_FILE_VNODE_VBAD; break; case KF_VTYPE_VFIFO: - ty = "FIFO"; + Lf->type = LSOF_FILE_VNODE_VFIFO; break; default: - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", (kf_vtype & 0xfff)); - ty = (char *)NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = kf_vtype; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); - Lf->ntype = Ntype; + /* * Handle some special cases: * @@ -579,8 +587,9 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, else if (Ntype == N_PROC) { ty = parse_proc_path(kf, &proc_pid); - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); + if (ty != LSOF_FILE_UNKNOWN) { + Lf->type = ty; + } } #if defined(HASBLKDEV) @@ -588,7 +597,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, * If this is a VBLK file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (kf_vtype == KF_VTYPE_VBLK)) + if (!Lf->inode_def && (kf_vtype == KF_VTYPE_VBLK)) find_bl_ino(); #endif /* defined(HASBLKDEV) */ @@ -596,7 +605,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, * If this is a VCHR file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (kf_vtype == KF_VTYPE_VCHR)) + if (!Lf->inode_def && (kf_vtype == KF_VTYPE_VCHR)) find_ch_ino(ctx); /* * Test for specified file. @@ -611,7 +620,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, if ((pfi->pid && proc_pid && pfi->pid == proc_pid) #if defined(HASPINODEN) - || (Lf->inp_ty == 1 && Lf->inode == pfi->inode) + || (Lf->inode_def && Lf->inode == pfi->inode) #else /* !defined(HASPINODEN) */ if (pfi->pid == p->pfs_pid) #endif /* defined(HASPINODEN) */ @@ -663,10 +672,11 @@ void process_pipe(struct lsof_context *ctx, struct kinfo_file *kf, KA_T pa) { int have_kpipe = (pa && kread(ctx, pa, (char *)&p, sizeof(p)) == 0); #endif - (void)snpf(Lf->type, sizeof(Lf->type), "PIPE"); + Lf->type = LSOF_FILE_PIPE; (void)snpf(dev_ch, sizeof(dev_ch), "%s", print_kptr(kf->kf_un.kf_pipe.kf_pipe_addr, (char *)NULL, 0)); enter_dev_ch(ctx, dev_ch); + Lf->off_def = 1; #if __FreeBSD_version >= 1400062 Lf->sz = (SZOFFTYPE)kf->kf_un.kf_pipe.kf_pipe_buffer_size; Lf->sz_def = 1; @@ -718,7 +728,7 @@ void process_pipe(struct lsof_context *ctx, struct kinfo_file *kf, KA_T pa) { */ void process_pts(struct lsof_context *ctx, struct kinfo_file *kf) { - (void)snpf(Lf->type, sizeof(Lf->type), "PTS"); + Lf->type = LSOF_FILE_PTS; /* * Convert the tty's cdev from kernel to user form. * -- already done in the kernel, file sys/kern/tty_pts.c, function @@ -738,8 +748,9 @@ void process_pts(struct lsof_context *ctx, struct kinfo_file *kf) { */ Lf->dev = DevDev; Lf->inode = (INODETYPE)kf->kf_un.kf_pts.kf_pts_dev; - Lf->inp_ty = Lf->dev_def = Lf->rdev_def = 1; - Lf->ntype = N_CHR; + Lf->inode_def = Lf->dev_def = Lf->rdev_def = 1; + Ntype = N_CHR; + Lf->off_def = 1; Lf->rdev = kf->kf_un.kf_pts.kf_pts_dev; DCunsafe = 1; } diff --git a/lib/dialects/freebsd/dproc.c b/lib/dialects/freebsd/dproc.c index b8b65c7a..0812d5b0 100644 --- a/lib/dialects/freebsd/dproc.c +++ b/lib/dialects/freebsd/dproc.c @@ -162,7 +162,6 @@ static void process_kinfo_file(struct lsof_context *ctx, struct kinfo_file *kf, struct xfile *xfile, struct pcb_lists *pcbs, struct lock_list *locks) { Lf->off = kf->kf_offset; - Lf->off_def = 1; if (kf->kf_ref_count) { if ((kf->kf_flags & (KF_FLAG_READ | KF_FLAG_WRITE)) == KF_FLAG_READ) Lf->access = LSOF_FILE_ACCESS_READ; @@ -179,9 +178,11 @@ static void process_kinfo_file(struct lsof_context *ctx, struct kinfo_file *kf, if (xfile) { Lf->fsa = xfile->xf_file; Lf->fsv |= FSV_FA; + Lf->fna = (KA_T)xfile->xf_data; Lf->fsv |= FSV_NI; } + if (xfile) Lf->ffg = (long)xfile->xf_flag; else @@ -253,36 +254,36 @@ static void process_file_descriptors(struct lsof_context *ctx, bsearch(&key, xfiles, n_xfiles, sizeof(*xfiles), cmp_xfiles_pid_fd); if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_CWD) { - alloc_lfile(ctx, CWD, -1); + alloc_lfile(ctx, LSOF_FD_CWD, -1); process_vnode(ctx, &kfiles[i], xfile, locks); if (Lf->sf) link_lfile(ctx); } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_ROOT) { - alloc_lfile(ctx, RTD, -1); + alloc_lfile(ctx, LSOF_FD_ROOT_DIR, -1); process_vnode(ctx, &kfiles[i], xfile, locks); if (Lf->sf) link_lfile(ctx); } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_JAIL) { - alloc_lfile(ctx, " jld", -1); + alloc_lfile(ctx, LSOF_FD_JAIL_DIR, -1); process_vnode(ctx, &kfiles[i], xfile, locks); if (Lf->sf) link_lfile(ctx); } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_TEXT) { - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); process_vnode(ctx, &kfiles[i], xfile, locks); if (Lf->sf) link_lfile(ctx); } else if (!ckscko && kfiles[i].kf_fd == KF_FD_TYPE_CTTY) { - alloc_lfile(ctx, "ctty", -1); + alloc_lfile(ctx, LSOF_FD_CTTY, -1); process_vnode(ctx, &kfiles[i], xfile, locks); if (Lf->sf) link_lfile(ctx); } else if (!ckscko && kfiles[i].kf_fd < 0) { - if (!Fwarn) - fprintf(stderr, "%s: WARNING -- unsupported fd type %d\n", Pn, + if (!Fwarn && ctx->err) + fprintf(ctx->err, "%s: WARNING -- unsupported fd type %d\n", Pn, kfiles[i].kf_fd); } else { - alloc_lfile(ctx, NULL, kfiles[i].kf_fd); + alloc_lfile(ctx, LSOF_FD_NUMERIC, kfiles[i].kf_fd); process_kinfo_file(ctx, &kfiles[i], xfile, pcbs, locks); if (Lf->sf) link_lfile(ctx); @@ -322,6 +323,8 @@ void gather_proc_info(struct lsof_context *ctx) { size_t n_xfiles; struct pcb_lists *pcbs; struct lock_list locks; + struct kinfo_proc *procs = NULL; /* local process table copy */ + int num_procs = 0; /* number of kernel processes */ #if defined(HASFSTRUCT) && !defined(HAS_FILEDESCENT) static char *pof = (char *)NULL; @@ -390,31 +393,31 @@ void gather_proc_info(struct lsof_context *ctx) { mib[2] = Ftask ? KERN_PROC_ALL : KERN_PROC_PROC; len = 0; if (sysctl(mib, 3, NULL, &len, NULL, 0) == 0) { - P = malloc(len); - if (P) { - if (sysctl(mib, 3, P, &len, NULL, 0) < 0) { - free(P); - P = NULL; + procs = malloc(len); + if (procs) { + if (sysctl(mib, 3, procs, &len, NULL, 0) < 0) { + CLEAN(procs); } } } - if (P == NULL) { - (void)fprintf(stderr, "%s: can't read process table: %s\n", Pn, - strerror(errno)); + if (procs == NULL) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't read process table: %s\n", Pn, + strerror(errno)); Error(ctx); } - Np = len / sizeof(struct kinfo_proc); - if (read_xfiles(&xfiles, &n_xfiles) && !Fwarn) - fprintf(stderr, "%s: WARNING -- reading xfile list failed: %s\n", Pn, + num_procs = len / sizeof(struct kinfo_proc); + if (read_xfiles(&xfiles, &n_xfiles) && !Fwarn && ctx->err) + fprintf(ctx->err, "%s: WARNING -- reading xfile list failed: %s\n", Pn, strerror(errno)); qsort(xfiles, n_xfiles, sizeof(*xfiles), cmp_xfiles_pid_fd); pcbs = read_pcb_lists(); - if (!pcbs && !Fwarn) - fprintf(stderr, "%s: WARNING -- reading PCBs failed: %s\n", Pn, + if (!pcbs && !Fwarn && ctx->err) + fprintf(ctx->err, "%s: WARNING -- reading PCBs failed: %s\n", Pn, strerror(errno)); #ifdef KERN_LOCKF - if (read_lockf(&locks.locks, &locks.n_locks) && !Fwarn) - fprintf(stderr, "%s: WARNING -- reading lockf list failed: %s\n", Pn, + if (read_lockf(&locks.locks, &locks.n_locks) && !Fwarn && ctx->err) + fprintf(ctx->err, "%s: WARNING -- reading lockf list failed: %s\n", Pn, strerror(errno)); qsort(locks.locks, locks.n_locks, sizeof(*locks.locks), cmp_kinfo_lockf); #endif @@ -423,9 +426,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Examine proc structures and their associated information. */ - for (p = P, px = 0; px < Np; p++, px++) - - { + for (p = procs, px = 0; px < num_procs; p++, px++) { if (p->P_STAT == 0 || p->P_STAT == SZOMB) continue; @@ -447,7 +448,7 @@ void gather_proc_info(struct lsof_context *ctx) { /* * See if process is excluded. */ - if (is_proc_excl(ctx, p->P_PID, pgid, (UID_ARG)uid, &pss, &sf)) + if (is_proc_excl(p->P_PID, pgid, (UID_ARG)uid, &pss, &sf)) continue; #endif /* defined(HASTASKS) */ @@ -497,6 +498,7 @@ void gather_proc_info(struct lsof_context *ctx) { free(xfiles); free_pcb_lists(pcbs); + CLEAN(procs); #ifdef KERN_LOCKF free(locks.locks); #endif @@ -522,7 +524,9 @@ static void get_kernel_access(struct lsof_context *ctx) { #else /* !defined(N_UNIX) */ { if (!(Nmlst = get_nlist_path(ctx, 1))) { - (void)fprintf(stderr, "%s: can't get kernel name list path\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't get kernel name list path\n", + Pn); Error(ctx); } } @@ -539,8 +543,8 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * See if the non-KMEM memory and the name list files are readable. */ - if ((Memory && !is_readable(Memory, 1)) || - (Nmlst && !is_readable(Nmlst, 1))) + if ((Memory && !is_readable(ctx, Memory, 1)) || + (Nmlst && !is_readable(ctx, Nmlst, 1))) Error(ctx); #endif /* defined(WILLDROPGID) */ @@ -551,26 +555,29 @@ static void get_kernel_access(struct lsof_context *ctx) { if ((Kd = kvm_open(Nmlst, Memory, NULL, O_RDONLY, NULL)) == NULL) { - (void)fprintf(stderr, "%s: kvm_open%s(execfile=%s, corefile=%s): %s\n", - Pn, + if (ctx->err) + (void)fprintf(ctx->err, + "%s: kvm_open%s(execfile=%s, corefile=%s): %s\n", Pn, - "", + "", - Nmlst ? Nmlst : "default", - Memory ? Memory : + Nmlst ? Nmlst : "default", + Memory ? Memory : #if defined(_PATH_MEM) - _PATH_MEM, + _PATH_MEM, #else /* !defined(_PATH_MEM) */ - "default", + "default", #endif /* defined(_PATH_MEM) */ - strerror(errno)); + strerror(errno)); return; } (void)build_Nl(ctx, Drive_Nl); if (kvm_nlist(Kd, Nl) < 0) { - (void)fprintf(stderr, "%s: can't read namelist from %s\n", Pn, Nmlst); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't read namelist from %s\n", Pn, + Nmlst); Error(ctx); } @@ -578,7 +585,8 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * Get kernel's badfileops address (for process_file()). */ - if (get_Nl_value(X_BADFILEOPS, (struct drive_Nl *)NULL, &X_bfopsa) < 0 || + if (get_Nl_value(ctx, X_BADFILEOPS, (struct drive_Nl *)NULL, &X_bfopsa) < + 0 || !X_bfopsa) { X_bfopsa = (KA_T)0; } @@ -598,14 +606,14 @@ static void get_kernel_access(struct lsof_context *ctx) { * get_nlist_path() - get kernel name list path */ -char *get_nlist_path(struct lsof_context *ctx, +char *get_nlist_path(struct lsof_context *ctx, /* context */ int ap) /* on success, return an allocated path * string pointer if 1; return a * constant character pointer if 0; * return NULL if failure */ { const char *bf; - static char *bfc; + char *bfc; MALLOC_S bfl; /* * Get bootfile name. @@ -615,9 +623,11 @@ char *get_nlist_path(struct lsof_context *ctx, return (""); bfl = (MALLOC_S)(strlen(bf) + 1); if (!(bfc = (char *)malloc(bfl))) { - (void)fprintf( - stderr, "%s: can't allocate %d bytes for boot file path: %s\n", - Pn, (int)bfl, bf); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for boot file path: %s\n", Pn, + (int)bfl, bf); Error(ctx); } (void)snpf(bfc, bfl, "%s", bf); @@ -637,6 +647,30 @@ void initialize(struct lsof_context *ctx) { #endif /* __FreeBSD_version < 1400062 */ } +/* + * deinitialize() - perform all cleanup + */ + +void deinitialize(struct lsof_context *ctx) { + /* Free Lvfs */ + struct l_vfs *vp, *vp_next; + for (vp = Lvfs; vp; vp = vp_next) { + vp_next = vp->next; +#if !defined(MOUNT_NONE) + CLEAN(vp->typnm); +#endif /* !defined(MOUNT_NONE) */ + CLEAN(vp->dir); + CLEAN(vp->fsname); + CLEAN(vp); + } + Lvfs = NULL; + + if (Kd) { + kvm_close(Kd); + Kd = NULL; + } +} + /* * kread() - read from kernel memory */ diff --git a/lib/dialects/freebsd/dproto.h b/lib/dialects/freebsd/dproto.h index a5d970a6..fa6fe5f5 100644 --- a/lib/dialects/freebsd/dproto.h +++ b/lib/dialects/freebsd/dproto.h @@ -35,7 +35,7 @@ */ #if !defined(N_UNIX) -extern char *get_nlist_path(struct lsof_context *ctx, int ap); +extern char *get_nlist_path(struct lsof_context * ctx, int ap); #endif /* !defined(N_UNIX) */ extern int is_file_named(struct lsof_context *ctx, char *p, int cd); @@ -65,11 +65,6 @@ extern void process_pipe(struct lsof_context *ctx, struct kinfo_file *kf, extern void process_shm(struct lsof_context *ctx, struct kinfo_file *kf); extern void process_procdesc(struct lsof_context *ctx, struct kinfo_file *kf); -#if defined(HAS9660FS) -extern int read_iso_node(struct vnode *v, dev_t *d, int *dd, INODETYPE *ino, - long *nl, SZOFFTYPE *sz); -#endif /* defined(HAS9660FS) */ - #if defined(HASMSDOSFS) extern int read_msdos_node(struct vnode *v, dev_t *d, int *dd, INODETYPE *ino, long *nl, SZOFFTYPE *sz); diff --git a/lib/dialects/freebsd/dsock.c b/lib/dialects/freebsd/dsock.c index 56bfb37d..569e9661 100644 --- a/lib/dialects/freebsd/dsock.c +++ b/lib/dialects/freebsd/dsock.c @@ -82,7 +82,7 @@ static char copyright[] = * Local function prototypes */ -static int ckstate(struct xtcpcb *pcb, int fam); +static int ckstate(struct lsof_context *ctx, struct xtcpcb *pcb, int fam); static int cmp_xunpcb_sock_pcb(const void *a, const void *b) { const struct xunpcb *pcb1 = (const struct xunpcb *)a; @@ -267,7 +267,7 @@ void free_pcb_lists(struct pcb_lists *pcbs) { * 1 == stop processing file */ -static int ckstate(struct xtcpcb *pcb, int fam) { +static int ckstate(struct lsof_context *ctx, struct xtcpcb *pcb, int fam) { #if __FreeBSD_version >= 1200026 int tsnx; @@ -302,10 +302,7 @@ static int ckstate(struct xtcpcb *pcb, int fam) { * See if this TCP file should be selected. */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (fam == AF_INET)) || - ((FnetTy == 6) && (fam == AF_INET6)) - - ) { + if (FnetTy == AF_UNSPEC || FnetTy == fam) { Lf->sf |= SELNET; } } @@ -380,8 +377,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, int unl; - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_SOCKET; /* * Read the socket, protocol, and domain structures. */ @@ -399,6 +395,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, Lf->sz = (SZOFFTYPE)kf->kf_un.kf_sock.kf_sock_recvq + (SZOFFTYPE)kf->kf_un.kf_sock.kf_sock_sendq; Lf->sz_def = 1; + Lf->off_def = 1; # if defined(HASTCPTPIQ) Lf->lts.rq = kf->kf_un.kf_sock.kf_sock_recvq; @@ -438,16 +435,14 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, case AF_INET6: if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (fam == AF_INET)) || - ((FnetTy == 6) && (fam == AF_INET6))) { + if (FnetTy == AF_UNSPEC || FnetTy == fam) { if (!TcpStIn && !UdpStIn) Lf->sf |= SELNET; } } - printiproto(kf->kf_sock_protocol); + enter_ip_proto(ctx, kf->kf_sock_protocol); - (void)snpf(Lf->type, sizeof(Lf->type), - (fam == AF_INET) ? "IPv4" : "IPv6"); + Lf->type = (fam == AF_INET) ? LSOF_FILE_IPV4 : LSOF_FILE_IPV6; if (fam == AF_INET6) { struct sockaddr_in6 *local_addr6, *foreign_addr6; @@ -467,7 +462,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, * Save IPv6 address information. */ if (kf->kf_sock_protocol == IPPROTO_TCP) { - if ((ts = ckstate((struct xtcpcb *)pcb, fam)) == 1) { + if ((ts = ckstate(ctx, (struct xtcpcb *)pcb, fam)) == 1) { return; } } @@ -505,7 +500,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, return; } if (kf->kf_sock_protocol == IPPROTO_TCP) { - if ((ts = ckstate((struct xtcpcb *)pcb, fam)) == 1) + if ((ts = ckstate(ctx, (struct xtcpcb *)pcb, fam)) == 1) return; } enter_dev_ch(ctx, @@ -567,11 +562,12 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, * Process a ROUTE domain socket. */ case AF_ROUTE: - (void)snpf(Lf->type, sizeof(Lf->type), "rte"); + Lf->type = LSOF_FILE_ROUTE; if (s && s->so_pcb) enter_dev_ch(ctx, print_kptr((KA_T)(s->so_pcb), (char *)NULL, 0)); else (void)snpf(Namech, Namechl, "no protocol control block"); + Lf->off_def = 1; break; /* * Process a Unix domain socket. @@ -580,7 +576,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, struct xunpcb *unix_pcb = (struct xunpcb *)pcb; if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; /* * Read Unix protocol control block and the Unix address structure. */ diff --git a/lib/dialects/freebsd/dstore.c b/lib/dialects/freebsd/dstore.c index 6f5b709b..098b677e 100644 --- a/lib/dialects/freebsd/dstore.c +++ b/lib/dialects/freebsd/dstore.c @@ -39,7 +39,7 @@ struct file *Cfp; /* curent file's file struct pointer */ /* * Drive_Nl -- table to drive the building of Nl[] via build_Nl() - * (See lsof.h and misc.c.) + * (See common.h and misc.c.) */ struct drive_Nl Drive_Nl[] = { @@ -53,18 +53,10 @@ struct drive_Nl Drive_Nl[] = { {"", ""}, {NULL, NULL}}; -kvm_t *Kd = NULL; /* kvm descriptor */ - #if defined(P_ADDR) KA_T Kpa; /* kernel proc struct address */ #endif /* defined(P_ADDR) */ -struct l_vfs *Lvfs = NULL; /* local vfs structure table */ - -int Np = 0; /* number of kernel processes */ - -struct kinfo_proc *P = NULL; /* local process table copy */ - #if defined(HASFSTRUCT) /* * Pff_tab[] - table for printing file flags @@ -112,3 +104,10 @@ struct pff_tab Pof_tab[] = { */ KA_T X_bfopsa; /* badfileops kernel address */ + +/* FreeBSD 12 has a bug that leaves undefined symbol __start_set_pcpu and + * __stop_set_pcpu but not actually using it. Workaround the issue like + * https://github.com/freebsd/freebsd-src/commit/56e8cb87c6054a302503c33b39a4bd658f505c4a + */ +uintptr_t *__start_set_pcpu; +uintptr_t *__stop_set_pcpu; diff --git a/lib/dialects/freebsd/machine.h b/lib/dialects/freebsd/machine.h index 5c9bb185..9e2fc089 100644 --- a/lib/dialects/freebsd/machine.h +++ b/lib/dialects/freebsd/machine.h @@ -156,7 +156,7 @@ typedef _Bool bool; /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ /* #define HASFSINO 1 */ @@ -166,7 +166,7 @@ typedef _Bool bool; * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -350,14 +350,6 @@ typedef _Bool bool; /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. For FreeBSD 2.0 and @@ -537,7 +529,7 @@ typedef _Bool bool; /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -575,6 +567,7 @@ typedef _Bool bool; # define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */ # define USE_LIB_READDEV 1 /* rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ # define USE_LIB_RNMH 1 /* rnmh.c */ diff --git a/lib/dialects/hpux/kmem/Makefile b/lib/dialects/hpux/kmem/Makefile index 080063da..1a67dae2 100644 --- a/lib/dialects/hpux/kmem/Makefile +++ b/lib/dialects/hpux/kmem/Makefile @@ -21,7 +21,7 @@ CFLAGS= ${CDEFS} ${INCL} ${DEBUG} GRP= -HDR= lsof.h lsof_fields.h dlsof.h machine.h proto.h dproto.h +HDR= common.h lsof_fields.h dlsof.h machine.h proto.h dproto.h SRC= dfile.c dmnt.c dnode.c dnode1.c dnode2.c dproc.c dsock.c \ dstore.c \ diff --git a/lib/dialects/hpux/kmem/dfile.c b/lib/dialects/hpux/kmem/dfile.c index fd9cf2b3..08fa3b24 100644 --- a/lib/dialects/hpux/kmem/dfile.c +++ b/lib/dialects/hpux/kmem/dfile.c @@ -69,8 +69,9 @@ int get_max_fd() { * print_dev() - print device */ -char *print_dev(struct lfile *lf, /* file whose device is to be printed */ - dev_t *dev) /* device to be printed */ +char *print_dev(lf, dev) +struct lfile *lf; /* file whose device is to be printed */ +dev_t *dev; /* device to be printed */ { static char buf[128]; @@ -88,14 +89,13 @@ void process_file(fp) KA_T fp; /* kernel file structure address */ struct file f; int flag; - if (kread(ctx, (KA_T)fp, (char *)&f, sizeof(f))) { + if (kread((KA_T)fp, (char *)&f, sizeof(f))) { (void)snpf(Namech, Namechl, "can't read file struct from %s", print_kptr(fp, (char *)NULL, 0)); enter_nm(Namech); return; } Lf->off = (SZOFFTYPE)f.f_offset; - Lf->off_def = 1; if (f.f_count) { @@ -105,10 +105,13 @@ void process_file(fp) KA_T fp; /* kernel file structure address */ */ Lf->fct = (long)f.f_count; Lf->fsv |= FSV_CT; + Lf->fsa = fp; Lf->fsv |= FSV_FA; + Lf->ffg = (long)f.f_flag; Lf->fsv |= FSV_FG; + Lf->fna = (KA_T)f.f_data; Lf->fsv |= FSV_NI; #endif /* defined(HASFSTRUCT) */ @@ -161,11 +164,10 @@ void process_file(fp) KA_T fp; /* kernel file structure address */ * block at the beginning of this file. */ -int read_mi(sh, ip, pcb, pn) -KA_T sh; /* stream head address */ -KA_T *ip; /* returned IP q_ptr */ -KA_T *pcb; /* returned TCP or UDP q_ptr */ -char **pn; /* returned protocol name */ +int read_mi(KA_T sh, /* stream head address */ + KA_T *ip, /* returned IP q_ptr */ + KA_T *pcb, /* returned TCP or UDP q_ptr */ + enum lsof_protocol *pn) /* returned protocol name */ { struct l_dev *dp; char *ep = Namech; @@ -179,7 +181,7 @@ char **pn; /* returned protocol name */ struct qinit qi; size_t sz = Namechl; - if (!sh || kread(ctx, sh, (char *)&hd, sizeof(hd))) { + if (!sh || kread(sh, (char *)&hd, sizeof(hd))) { (void)snpf(Namech, Namechl, "can't read stream head: %s", print_kptr(sh, (char *)NULL, 0)); return (1); @@ -209,14 +211,13 @@ char **pn; /* returned protocol name */ *ip = *pcb = (KA_T)NULL; qa = (KA_T)hd.sth_wq; for (i = 0; i < 20; i++, qa = (KA_T)q.q_next) { - if (!qa || kread(ctx, qa, (char *)&q, sizeof(q))) + if (!qa || kread(qa, (char *)&q, sizeof(q))) break; - if (!(ka = (KA_T)q.q_qinfo) || kread(ctx, ka, (char *)&qi, sizeof(qi))) + if (!(ka = (KA_T)q.q_qinfo) || kread(ka, (char *)&qi, sizeof(qi))) continue; - if (!(ka = (KA_T)qi.qi_minfo) || - kread(ctx, ka, (char *)&mi, sizeof(mi))) + if (!(ka = (KA_T)qi.qi_minfo) || kread(ka, (char *)&mi, sizeof(mi))) continue; - if (!(ka = (KA_T)mi.mi_idname) || kread(ctx, ka, mn, ml)) + if (!(ka = (KA_T)mi.mi_idname) || kread(ka, mn, ml)) continue; if ((len = strlen(mn)) < 1) continue; @@ -232,12 +233,12 @@ char **pn; /* returned protocol name */ } if (!*pcb && !strcmp(mn, "tcpm")) { *pcb = (KA_T)q.q_ptr; - *pn = "TCP"; + *pn = LSOF_PROTOCOL_TCP; continue; } if (!*pcb && !strcmp(mn, "udpm")) { *pcb = (KA_T)q.q_ptr; - *pn = "UDP"; + *pn = LSOF_PROTOCOL_UDP; } } return (0); diff --git a/lib/dialects/hpux/kmem/dmnt.c b/lib/dialects/hpux/kmem/dmnt.c index b5d3d64f..9ec6ec53 100644 --- a/lib/dialects/hpux/kmem/dmnt.c +++ b/lib/dialects/hpux/kmem/dmnt.c @@ -44,8 +44,6 @@ typedef int time_t; * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ - /* * completevfs() - complete local vfs structure */ @@ -140,7 +138,8 @@ dev_t *dev; /* device */ * readvfs() - read vfs structure */ -struct l_vfs *readvfs(struct vnode *lv) /* local vnode */ +struct l_vfs *readvfs(lv) +struct vnode *lv; /* local vnode */ { struct mount m; struct mntinfo mi; @@ -167,7 +166,7 @@ struct l_vfs *readvfs(struct vnode *lv) /* local vnode */ vp->fs_ino = 0; #endif /* defined(HASFSINO) */ - if (lv->v_vfsp && kread(ctx, (KA_T)lv->v_vfsp, (char *)&v, sizeof(v))) { + if (lv->v_vfsp && kread((KA_T)lv->v_vfsp, (char *)&v, sizeof(v))) { (void)free((FREE_P *)vp); return ((struct l_vfs *)NULL); } @@ -181,7 +180,7 @@ struct l_vfs *readvfs(struct vnode *lv) /* local vnode */ * private data pointer to an mntinfo structure. */ if (v.vfs_data && - kread(ctx, (KA_T)v.vfs_data, (char *)&mi, sizeof(mi)) == 0) { + kread((KA_T)v.vfs_data, (char *)&mi, sizeof(mi)) == 0) { #if HPUXV < 1020 td = (dev_t)makedev(255, (int)mi.mi_mntno); @@ -197,7 +196,7 @@ struct l_vfs *readvfs(struct vnode *lv) /* local vnode */ } } else { if (v.vfs_data) { - if (kread(ctx, (KA_T)v.vfs_data, (char *)&m, sizeof(m)) == 0) + if (kread((KA_T)v.vfs_data, (char *)&m, sizeof(m)) == 0) ms = 1; else ms = 0; diff --git a/lib/dialects/hpux/kmem/dnode.c b/lib/dialects/hpux/kmem/dnode.c index a07d0343..38ba6143 100644 --- a/lib/dialects/hpux/kmem/dnode.c +++ b/lib/dialects/hpux/kmem/dnode.c @@ -70,7 +70,7 @@ static void enter_nma(b) char *b; /* addition buffer */ * islocked() - is node locked? */ -static int islocked(lp) +static enum lsof_lock_mode islocked(lp) KA_T lp; /* local locklist struct pointer */ { static int ety = -1; @@ -81,7 +81,7 @@ KA_T lp; /* local locklist struct pointer */ KA_T llf, llp; if (!(llf = (KA_T)lp)) - return ((int)' '); + return (LSOF_LOCK_NONE); llp = llf; /* * Compute the end test value the first time through. @@ -107,8 +107,8 @@ KA_T lp; /* local locklist struct pointer */ * Search the locklist chain for this process. */ do { - if (kread(ctx, llp, (char *)&ll, sizeof(ll))) - return ((int)' '); + if (kread(llp, (char *)&ll, sizeof(ll))) + return (LSOF_LOCK_NONE); # if !defined(L_REMOTE) # define L_REMOTE 0x1 /* from HP-UX 9.01 */ @@ -135,10 +135,10 @@ KA_T lp; /* local locklist struct pointer */ } } if (ll.ll_type == F_WRLCK) - return ((int)(l ? 'W' : 'w')); + return ((l ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL)); else if (ll.ll_type == F_RDLCK) - return ((int)(l ? 'R' : 'r')); - return ((int)' '); + return ((l ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL)); + return (' '); } # if HPUXV < 1010 @@ -147,7 +147,7 @@ KA_T lp; /* local locklist struct pointer */ while ((llp = (KA_T)ll.ll_fwd) && llp != llf); # endif /* HPUXV<1010 */ - return ((int)' '); + return (LSOF_LOCK_NONE); } #endif /* HPUXV>=900 */ @@ -155,7 +155,8 @@ KA_T lp; /* local locklist struct pointer */ * getnodety() - get node type */ -static int getnodety(struct vnode *v) /* local vnode copy */ +static int getnodety(v) +struct vnode *v; /* local vnode copy */ { #if defined(HAS_AFS) @@ -386,11 +387,11 @@ void process_node(va) KA_T va; /* vnode kernel space address */ #if HPUXV < 900 if (v->v_shlockc || v->v_exlockc) { if (v->v_shlockc && v->v_exlockc) - Lf->lock = 'u'; + Lf->lock = LSOF_LOCK_READ_WRITE; else if (v->v_shlockc) - Lf->lock = 'R'; + Lf->lock = LSOF_LOCK_READ_FULL; else - Lf->lock = 'W'; + Lf->lock = LSOF_LOCK_WRITE_FULL; } #else /* HPUXV>900 */ # if HPUXV >= 1000 @@ -436,7 +437,7 @@ void process_node(va) KA_T va; /* vnode kernel space address */ #if HPUXV >= 1000 case N_CDFS: - if (!v->v_data || kread(ctx, (KA_T)v->v_data, (char *)&c, sizeof(c))) { + if (!v->v_data || kread((KA_T)v->v_data, (char *)&c, sizeof(c))) { (void)snpf(Namech, Namechl, "vnode at %s: can't read cdnode (%s)", print_kptr(va, tbuf, sizeof(tbuf)), print_kptr((KA_T)v->v_data, (char *)NULL, 0)); @@ -446,7 +447,7 @@ void process_node(va) KA_T va; /* vnode kernel space address */ break; case N_FIFO: case N_PIPE: - if (!v->v_data || kread(ctx, (KA_T)v->v_data, (char *)&f, sizeof(f))) { + if (!v->v_data || kread((KA_T)v->v_data, (char *)&f, sizeof(f))) { (void)snpf(Namech, Namechl, "vnode at %s: can't read fifonode (%s)", print_kptr(va, tbuf, sizeof(tbuf)), print_kptr((KA_T)v->v_data, (char *)NULL, 0)); @@ -454,8 +455,7 @@ void process_node(va) KA_T va; /* vnode kernel space address */ return; } fns = 1; - if (f.fn_vap && - kread(ctx, (KA_T)f.fn_vap, (char *)&vat, sizeof(vat)) == 0) + if (f.fn_vap && kread((KA_T)f.fn_vap, (char *)&vat, sizeof(vat)) == 0) vats = 1; break; #endif /* HPUXV>=1000 */ @@ -669,14 +669,14 @@ void process_node(va) KA_T va; /* vnode kernel space address */ case N_AFS: if (an.ino_st) { Lf->inode = (INODETYPE)an.inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HAS_AFS) */ case N_MVFS: Lf->inode = (INODETYPE)m.m_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; case N_NFS: @@ -686,22 +686,22 @@ void process_node(va) KA_T va; /* vnode kernel space address */ Lf->inode = (INODETYPE)r.r_attr.va_nodeid; #endif /* HPUXV<1030 */ - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if HPUXV >= 1000 case N_CDFS: Lf->inode = (INODETYPE)c.cd_num; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; case N_FIFO: case N_PIPE: if (vats) { Lf->inode = (INODETYPE)vat.va_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; } else { Lf->inode = (INODETYPE)v->v_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* HPUXV>=1000 */ @@ -718,7 +718,7 @@ void process_node(va) KA_T va; /* vnode kernel space address */ # if HPUXV >= 900 if (rns) { Lf->inode = (INODETYPE)r.r_nfsattr.na_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; } # endif /* HPUXV>=900 */ @@ -731,7 +731,7 @@ void process_node(va) KA_T va; /* vnode kernel space address */ case N_SPEC: if (ins) { Lf->inode = (INODETYPE)i.i_number; - Lf->inp_ty = 1; + Lf->inode_def = 1; } } @@ -760,7 +760,9 @@ void process_node(va) KA_T va; /* vnode kernel space address */ /* * Obtain the file size. */ + Lf->off_def = 1; switch (Ntype) { + #if defined(HAS_AFS) case N_AFS: Lf->sz = (SZOFFTYPE)an.size; @@ -799,8 +801,8 @@ void process_node(va) KA_T va; /* vnode kernel space address */ } # endif /* HPUXV<1000 */ - if (Lf->access != LSOF_FILE_ACCESS_READ && - Lf->access != LSOF_FILE_ACCESS_WRITE) { + if ((Lf->access != LSOF_FILE_ACCESS_READ && + Lf->access != LSOF_FILE_ACCESS_WRITE)) { if (fns || ins) { (void)snpf(fb, sizeof(fb), "rd=%#x; wr=%#x", rp, wp); (void)enter_nma(fb); @@ -815,12 +817,12 @@ void process_node(va) KA_T va; /* vnode kernel space address */ Lf->off = (unsigned long)((Lf->access == LSOF_FILE_ACCESS_READ) ? rp : wp); - Lf->off_def = 1; (void)snpf(fb, sizeof(fb), "%s=%#x", (Lf->access == LSOF_FILE_ACCESS_READ) ? "rd" : "wr", (Lf->access == LSOF_FILE_ACCESS_READ) ? rp : wp); (void)enter_nma(fb); } + Lf->off_def = 1; break; #endif /* HPUXV>=900 */ @@ -846,7 +848,9 @@ void process_node(va) KA_T va; /* vnode kernel space address */ case N_SPEC: case N_REGLR: - if (!(type == VCHR || type == VBLK) && ins) { + if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; + else if (ins) { Lf->sz = (SZOFFTYPE)i.i_size; Lf->sz_def = 1; } @@ -938,63 +942,62 @@ void process_node(va) KA_T va; /* vnode kernel space address */ Lf->rdev_def = rdevs; switch (type) { case VNON: - ty = "VNON"; + Lf->type = LSOF_FILE_VNODE_VNON; break; case VREG: + Lf->type = LSOF_FILE_VNODE_VREG; + break; case VDIR: - ty = (type == VREG) ? "VREG" : "VDIR"; + Lf->type = LSOF_FILE_VNODE_VDIR; break; case VBLK: - ty = "VBLK"; + Lf->type = LSOF_FILE_VNODE_VBLK; Ntype = N_BLK; break; case VCHR: - ty = "VCHR"; + Lf->type = LSOF_FILE_VNODE_VCHR; Ntype = N_CHR; break; case VLNK: - ty = "VLNK"; + Lf->type = LSOF_FILE_VNODE_VLNK; break; #if defined(VSOCK) case VSOCK: - ty = "SOCK"; + Lf->type = LSOF_FILE_VNODE_VSOCK; break; #endif /* defined(VSOCK) */ case VBAD: - ty = "VBAD"; + Lf->type = LSOF_FILE_VNODE_VBAD; break; case VFIFO: switch (Ntype) { #if HPUXV >= 1000 case N_FIFO: - ty = "FIFO"; + Lf->type = LSOF_FILE_FIFO; break; case N_PIPE: - ty = "PIPE"; + Lf->type = LSOF_FILE_PIPE; break; #endif /* HPUXV>=1000 */ default: - ty = "FIFO"; + Lf->type = LSOF_FILE_FIFO; } break; default: - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); - ty = (char *)NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_type_type = type; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); - Lf->ntype = Ntype; #if defined(HASBLKDEV) /* * If this is a VBLK file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VBLK)) + if (!Lf->inode_def && (type == VBLK)) find_bl_ino(); #endif /* defined(HASBLKDEV) */ @@ -1002,7 +1005,7 @@ void process_node(va) KA_T va; /* vnode kernel space address */ * If this is a VCHR file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VCHR)) + if (!Lf->inode_def && (type == VCHR)) find_ch_ino(); /* * Test for specified file. @@ -1025,7 +1028,7 @@ static int readinode(ia, i) KA_T ia; /* inode kernel address */ struct inode *i; /* inode buffer */ { - if (kread(ctx, (KA_T)ia, (char *)i, sizeof(struct inode))) { + if (kread((KA_T)ia, (char *)i, sizeof(struct inode))) { (void)snpf(Namech, Namechl, "can't read inode at %s", print_kptr(ia, (char *)NULL, 0)); return (1); @@ -1044,7 +1047,7 @@ struct mvfsnode *m; /* mvfsnode receiver */ { char tbuf[32]; - if (!ma || kread(ctx, (KA_T)ma, (char *)m, sizeof(struct mvfsnode))) { + if (!ma || kread((KA_T)ma, (char *)m, sizeof(struct mvfsnode))) { (void)snpf(Namech, Namechl, "node at %s: can't read mvfsnode: %s", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr(ma, (char *)NULL, 0)); diff --git a/lib/dialects/hpux/kmem/dnode1.c b/lib/dialects/hpux/kmem/dnode1.c index e187c50f..aa71c3ff 100644 --- a/lib/dialects/hpux/kmem/dnode1.c +++ b/lib/dialects/hpux/kmem/dnode1.c @@ -45,7 +45,7 @@ typedef int ino_t; typedef int time_t; # endif /* defined(HPUXKERNBITS) && HPUXKERNBITS>=64 */ -# include "lsof.h" +# include "common.h" /* * HP-UX versions below 10.20: @@ -98,16 +98,17 @@ typedef int time_t; * read_vxnode() - read Veritas file system inode information */ -int read_vxnode(struct vnode *v, /* local containing vnode */ - struct l_vfs *vfs, /* local vfs structure */ - dev_t *dev, /* device number receiver */ - int *devs, /* device status receiver */ - dev_t *rdev, /* raw device number receiver */ - int *rdevs) /* raw device status receiver */ +int read_vxnode(v, vfs, dev, devs, rdev, rdevs) +struct vnode *v; /* local containing vnode */ +struct l_vfs *vfs; /* local vfs structure */ +dev_t *dev; /* device number receiver */ +int *devs; /* device status receiver */ +dev_t *rdev; /* raw device number receiver */ +int *rdevs; /* raw device status receiver */ { struct vx_inode i; - if (!v->v_data || kread(ctx, (KA_T)v->v_data, (char *)&i, sizeof(i))) + if (!v->v_data || kread((KA_T)v->v_data, (char *)&i, sizeof(i))) return (1); /* * Return device numbers. @@ -125,11 +126,13 @@ int read_vxnode(struct vnode *v, /* local containing vnode */ * Record inode number. */ Lf->inode = (INODETYPE)i.i_number; - Lf->inp_ty = 1; + Lf->inode_def = 1; /* * Record size. */ - if (!(v->v_type == VCHR || v->v_type == VBLK)) { + if (((v->v_type == VCHR || v->v_type == VBLK))) + Lf->off_def = 1; + else { Lf->sz = (SZOFFTYPE)i.i_size; Lf->sz_def = 1; } diff --git a/lib/dialects/hpux/kmem/dnode2.c b/lib/dialects/hpux/kmem/dnode2.c index 240fabe4..1c94e8c5 100644 --- a/lib/dialects/hpux/kmem/dnode2.c +++ b/lib/dialects/hpux/kmem/dnode2.c @@ -42,7 +42,7 @@ typedef int ino_t; typedef int time_t; # endif /* defined(HPUXKERNBITS) && HPUXKERNBITS>=64 */ -# include "lsof.h" +# include "common.h" # include # include # undef __dontcare__ @@ -73,8 +73,8 @@ typedef struct afs_lock afs_rwlock_t; * Local function prototypes */ -static struct volume *getvolume(struct VenusFid *f, int *vols); -static int is_rootFid(struct vcache *vc, int *rfid); +static struct volume *getvolume, (struct VenusFid * f int *vols); +static int is_rootFid, (struct vcache * vc int *rfid); /* * alloc_vcache() - allocate space for vcache structure @@ -101,7 +101,7 @@ void ckAFSsym(nl) struct nlist *nl; /* copy of Nl[] when empty */ /* * See if the alternate AFS name list file can be read. */ - if (!is_readable(path, 0)) { + if (!is_readable(ctx, path, 0)) { if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: can't access AFS name list file: %s\n", @@ -140,8 +140,9 @@ void ckAFSsym(nl) struct nlist *nl; /* copy of Nl[] when empty */ * getvolume() - get volume structure */ -static struct volume *getvolume(struct VenusFid *f, /* file ID pointer */ - int *vols) /* afs_volumes status return */ +static struct volume *getvolume(f, vols) +struct VenusFid *f; /* file ID pointer */ +int *vols; /* afs_volumes status return */ { int i; static KA_T ka = 0; @@ -167,10 +168,10 @@ static struct volume *getvolume(struct VenusFid *f, /* file ID pointer */ *vols = 1; i = (NVOLS - 1) & f->Fid.Volume; kh = (KA_T)((char *)ka + (i * sizeof(struct volume *))); - if (kread(ctx, kh, (char *)&vp, sizeof(vp))) + if (kread(kh, (char *)&vp, sizeof(vp))) return ((struct volume *)NULL); while (vp) { - if (kread(ctx, (KA_T)vp, (char *)&v, sizeof(v))) + if (kread((KA_T)vp, (char *)&v, sizeof(v))) return ((struct volume *)NULL); if (v.volume == f->Fid.Volume && v.cell == f->Cell) return (&v); @@ -183,7 +184,8 @@ static struct volume *getvolume(struct VenusFid *f, /* file ID pointer */ * hasAFS() - test for AFS presence via vfs structure */ -int hasAFS(struct vnode *vp) /* vnode pointer */ +int hasAFS(vp) +struct vnode *vp; /* vnode pointer */ { struct vfs v; /* @@ -200,7 +202,7 @@ int hasAFS(struct vnode *vp) /* vnode pointer */ if (AFSVfsp && !vp->v_data && vp->v_vfsp == AFSVfsp) return (1); if (vp->v_data || !vp->v_vfsp || - kread(ctx, (KA_T)vp->v_vfsp, (char *)&v, sizeof(v)) || v.vfs_data || + kread((KA_T)vp->v_vfsp, (char *)&v, sizeof(v)) || v.vfs_data || strcmp(v.vfs_name, "AFS") != 0) return (0); AFSVfsp = vp->v_vfsp; @@ -216,8 +218,9 @@ int hasAFS(struct vnode *vp) /* vnode pointer */ * 1 if root file ID structure address available */ -static int is_rootFid(struct vcache *vc, /* vcache structure */ - int *rfid) /* root file ID pointer status return */ +static int is_rootFid(vc, rfid) +struct vcache *vc; /* vcache structure */ +int *rfid; /* root file ID pointer status return */ { char *err; static int f = 0; /* rootFID structure status: @@ -258,7 +261,7 @@ static int is_rootFid(struct vcache *vc, /* vcache structure */ *rfid = 0; return (0); } - if (kread(ctx, (KA_T)v, (char *)&r, sizeof(r))) { + if (kread((KA_T)v, (char *)&r, sizeof(r))) { err = "can't read from kernel"; goto rfid_unavailable; } @@ -293,7 +296,7 @@ struct afsnode *an; /* afsnode recipient */ cp = ((char *)v + sizeof(struct vnode)); ka = (KA_T)((char *)va + sizeof(struct vnode)); len = sizeof(struct vcache) - sizeof(struct vnode); - if (kread(ctx, ka, cp, len)) { + if (kread(ka, cp, len)) { (void)snpf(Namech, Namechl, "vnode at %s: can't read vcache remainder from %s", print_kptr(va, tbuf, sizeof(tbuf)), diff --git a/lib/dialects/hpux/kmem/dproc.c b/lib/dialects/hpux/kmem/dproc.c index 0e55bde5..917072f3 100644 --- a/lib/dialects/hpux/kmem/dproc.c +++ b/lib/dialects/hpux/kmem/dproc.c @@ -128,10 +128,10 @@ static MALLOC_S Nva = 0; /* number of entries allocated to static KA_T *Vp = (KA_T *)NULL; /* vnode address cache */ #endif /* HPUXV>=800 */ -static void get_kernel_access(void); +static void get_kernel_access (void); #if HPUXV >= 800 -static void process_text(KA_T vasp); +static void process_text (KA_T vasp); #endif /* HPUXV>=800 */ /* @@ -221,7 +221,7 @@ void gather_proc_info() { */ if (!oftp) { if ((get_Nl_value("chunksz", Drive_Nl, &v) >= 0) && v) { - if (kread(ctx, v, (char *)&oftsz, sizeof(oftsz))) { + if (kread(v, (char *)&oftsz, sizeof(oftsz))) { (void)fprintf(stderr, "%s: can't get FD chunk size\n", Pn); Error(ctx); } @@ -258,7 +258,7 @@ void gather_proc_info() { { Kpa = Kp + (KA_T)(px * sizeof(struct proc)); - if (kread(ctx, Kpa, (char *)&pbuf, sizeof(pbuf))) + if (kread(Kpa, (char *)&pbuf, sizeof(pbuf))) continue; if (p->p_stat == 0 || p->p_stat == SZOMB) continue; @@ -341,7 +341,7 @@ void gather_proc_info() { # if defined(hp9000s300) pte_off = (KA_T)&Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1]; - if (kread(ctx, pte_off, (char *)&pte1, sizeof(pte1))) + if (kread(pte_off, (char *)&pte1, sizeof(pte1))) continue; pte_addr = (KA_T)(ctob(pte1.pg_pfnum + 1) - ((UPAGES + FLOAT) * sizeof(pte2))); @@ -353,7 +353,7 @@ void gather_proc_info() { # endif /* defined(hp9000s300) */ # if defined(hp9000s800) - if (kread(ctx, (KA_T)uvadd((struct proc *)Kpa), (char *)u, + if (kread((KA_T)uvadd((struct proc *)Kpa), (char *)u, sizeof(struct user))) continue; } @@ -409,8 +409,8 @@ void gather_proc_info() { #if HPUXV >= 800 if (j >= SFDCHUNK) { - if (!pfp || kread(ctx, (KA_T)pfp, (char *)&ofp, sizeof(ofp)) || - !ofp || kread(ctx, (KA_T)ofp, oftp, oftsz)) + if (!pfp || kread((KA_T)pfp, (char *)&ofp, sizeof(ofp)) || + !ofp || kread((KA_T)ofp, oftp, oftsz)) break; j = 0; pfp += sizeof(KA_T); @@ -446,7 +446,7 @@ void gather_proc_info() { ; if (k >= NFDCHUNKS) break; - if (kread(ctx, (KA_T)u->u_ofilep[k], (char *)&u->u_ofile, + if (kread((KA_T)u->u_ofilep[k], (char *)&u->u_ofile, sizeof(struct ofile_t))) { break; } @@ -547,7 +547,7 @@ static void get_kernel_access() { /* * See if the non-KMEM memory file is readable. */ - if (Memory && !is_readable(Memory, 1)) + if (Memory && !is_readable(ctx, Memory, 1)) Error(ctx); #endif /* defined(WILLDROPGID) */ @@ -573,7 +573,7 @@ static void get_kernel_access() { /* * See if the name list file is readable. */ - if (Nmlst && !is_readable(Nmlst, 1)) + if (Nmlst && !is_readable(ctx, Nmlst, 1)) Error(ctx); #endif /* defined(WILLDROPGID) */ @@ -604,9 +604,9 @@ static void get_kernel_access() { Error(ctx); } if (get_Nl_value("proc", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&Kp, sizeof(Kp)) || + kread((KA_T)v, (char *)&Kp, sizeof(Kp)) || get_Nl_value("nproc", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&Np, sizeof(Np)) || !Kp || Np < 1) { + kread((KA_T)v, (char *)&Np, sizeof(Np)) || !Kp || Np < 1) { (void)fprintf(stderr, "%s: can't read proc table info\n", Pn); Error(ctx); } @@ -631,7 +631,7 @@ static void get_kernel_access() { Error(ctx); } if (get_Nl_value("npids", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&npids, sizeof(npids))) { + kread((KA_T)v, (char *)&npids, sizeof(npids))) { (void)fprintf(stderr, "%s: can't get kernel's npids\n", Pn); Error(ctx); } @@ -639,7 +639,7 @@ static void get_kernel_access() { #if HPUXV >= 1030 if (get_Nl_value("clmaj", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&CloneMaj, sizeof(CloneMaj))) + kread((KA_T)v, (char *)&CloneMaj, sizeof(CloneMaj))) HaveCloneMaj = 0; else HaveCloneMaj = 1; @@ -673,10 +673,10 @@ void initialize() { get_kernel_access(); } * kread() - read from kernel memory */ -int kread(struct lsof_context *ctx, /* context */ - KA_T addr, /* kernel memory address */ - char *buf, /* buffer to receive data */ - READLEN_T len) /* length to read */ +int kread(addr, buf, len) +KA_T addr; /* kernel memory address */ +char *buf; /* buffer to receive data */ +READLEN_T len; /* length to read */ { int br; @@ -724,7 +724,7 @@ static void process_text(vasp) KA_T vasp; /* kernel's virtual address space /* * Read virtual address space pointer. */ - if (kread(ctx, vasp, (char *)&v, sizeof(v))) + if (kread(vasp, (char *)&v, sizeof(v))) return; /* * Follow the virtual address space pregion structure chain. @@ -745,9 +745,9 @@ static void process_text(vasp) KA_T vasp; /* kernel's virtual address space /* * Read the pregion and region. */ - if (kread(ctx, prp, (char *)&p, sizeof(p))) + if (kread(prp, (char *)&p, sizeof(p))) return; - if (kread(ctx, (KA_T)p.p_reg, (char *)&r, sizeof(r))) + if (kread((KA_T)p.p_reg, (char *)&r, sizeof(r))) return; /* * Skip file entries with no file pointers. diff --git a/lib/dialects/hpux/kmem/dsock.c b/lib/dialects/hpux/kmem/dsock.c index e9457a44..90f016dc 100644 --- a/lib/dialects/hpux/kmem/dsock.c +++ b/lib/dialects/hpux/kmem/dsock.c @@ -413,13 +413,12 @@ void process_lla(la) KA_T la; /* link level CB address in kernel */ struct lla_cb lcb; size_t sz; - (void)snpf(Lf->type, sizeof(Lf->type), "lla"); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_LINK_LEVEL_ACCESS; enter_dev_ch(print_kptr(la, (char *)NULL, 0)); /* * Read link level access control block. */ - if (!la || kread(ctx, (KA_T)la, (char *)&lcb, sizeof(lcb))) { + if (!la || kread((KA_T)la, (char *)&lcb, sizeof(lcb))) { (void)snpf(Namech, Namechl, "can't read LLA CB (%s)", print_kptr(la, (char *)NULL, 0)); enter_nm(Namech); @@ -438,9 +437,9 @@ void process_lla(la) KA_T la; /* link level CB address in kernel */ * Determine the open mode, if possible. */ if (lcb.lla_flags & LLA_IS_ETHER) - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "Ether"); + Lf->iproto = LSOF_PROTOCOL_ETHERNET; else if (lcb.lla_flags & (LLA_IS_8025 | LLA_IS_SNAP8025 | LLA_IS_FA8025)) { - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "802.5"); + Lf->iproto = LSOF_PROTOCOL_8025; if (lcb.lla_flags & LLA_IS_SNAP8025) (void)snpf(Namech, Namechl, "SNAP"); else if (lcb.lla_flags & LLA_IS_FA8025) @@ -500,8 +499,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ # endif /* HPUXV<1030 */ #endif /* HPUXV>=800 */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_SOCKET; /* * Read socket structure. */ @@ -509,7 +507,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ enter_nm("no socket address"); return; } - if (kread(ctx, (KA_T)sa, (char *)&s, sizeof(s))) { + if (kread((KA_T)sa, (char *)&s, sizeof(s))) { (void)snpf(Namech, Namechl, "can't read socket struct from %s", print_kptr(sa, (char *)NULL, 0)); enter_nm(Namech); @@ -523,14 +521,14 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ enter_nm(Namech); return; } - if (!s.so_proto || kread(ctx, (KA_T)s.so_proto, (char *)&p, sizeof(p))) { + if (!s.so_proto || kread((KA_T)s.so_proto, (char *)&p, sizeof(p))) { (void)snpf(Namech, Namechl, "no protocol switch"); enter_nm(Namech); return; } #if HPUXV >= 800 - if (kread(ctx, (KA_T)p.pr_domain, (char *)&d, sizeof(d))) { + if (kread((KA_T)p.pr_domain, (char *)&d, sizeof(d))) { (void)snpf(Namech, Namechl, "can't read domain struct from %s", print_kptr((KA_T)p.pr_domain, (char *)NULL, 0)); enter_nm(Namech); @@ -549,6 +547,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ else Lf->sz = (SZOFFTYPE)(s.so_rcv.sb_cc + s.so_snd.sb_cc); Lf->sz_def = 1; + Lf->off_def = 1; # if defined(HASTCPTPIQ) Lf->lts.rq = s.so_rcv.sb_cc; @@ -576,12 +575,12 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ case AF_CCITT: if (Fnet) Lf->sf |= SELNET; - (void)snpf(Lf->type, sizeof(Lf->type), "x.25"); - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL, "CCITT"); + Lf->type = LSOF_FILE_X25; + Lf->iproto = LSOF_PROTOCOL_CCITT; /* * Get the X25 PCB and its extension. */ - if (!s.so_pcb || kread(ctx, (KA_T)s.so_pcb, (char *)&xp, sizeof(xp))) { + if (!s.so_pcb || kread((KA_T)s.so_pcb, (char *)&xp, sizeof(xp))) { (void)snpf(Namech, Namechl, "can't read x.25 pcb at %s", print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); enter_nm(Namech); @@ -589,7 +588,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ } enter_dev_ch(print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); if (!xp.x25pcb_extend || - kread(ctx, (KA_T)xp.x25pcb_extend, (char *)&xpe, sizeof(xpe))) { + kread((KA_T)xp.x25pcb_extend, (char *)&xpe, sizeof(xpe))) { (void)snpf(Namech, Namechl, "can't read x.25 pcb (%s) extension at %s", print_kptr((KA_T)s.so_pcb, tbuf, sizeof(tbuf)), @@ -641,8 +640,8 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ case AF_INET: if (Fnet) Lf->sf |= SELNET; - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); - printiproto(p.pr_protocol); + Lf->type = LSOF_FILE_INET; + enter_ip_proto(p.pr_protocol); #if HPUXV >= 1030 /* @@ -651,7 +650,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ if (s.so_sth) { KA_T ip, pcb; - char *pn = (char *)NULL; + enum lsof_protocol pn = LSOF_PROTOCOL_INVALID; /* * Read module information. */ @@ -704,7 +703,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ /* * Print raw socket information. */ - if (kread(ctx, (KA_T)s.so_pcb, (char *)&raw, sizeof(raw)) || + if (kread((KA_T)s.so_pcb, (char *)&raw, sizeof(raw)) || (struct socket *)sa != (struct socket *)raw.rcb_socket) { (void)snpf(Namech, Namechl, "can't read rawcb at %s", print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); @@ -731,7 +730,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ /* * Print Internet socket information. */ - if (kread(ctx, (KA_T)s.so_pcb, (char *)&inp, sizeof(inp))) { + if (kread((KA_T)s.so_pcb, (char *)&inp, sizeof(inp))) { (void)snpf(Namech, Namechl, "can't read inpcb at %s", print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); enter_nm(Namech); @@ -749,7 +748,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ if (fa || la) (void)ent_inaddr(la, lp, fa, fp, AF_INET); if (p.pr_protocol == IPPROTO_TCP && inp.inp_ppcb && - kread(ctx, (KA_T)inp.inp_ppcb, (char *)&t, sizeof(t)) == 0) { + kread((KA_T)inp.inp_ppcb, (char *)&t, sizeof(t)) == 0) { Lf->lts.type = 0; Lf->lts.state.i = (int)t.t_state; } @@ -763,15 +762,15 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ case AF_UNIX: if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; #if HPUXV >= 1030 /* * Save size information for HP-UX 10.30 and above. */ - if (!s.so_rcv || kread(ctx, (KA_T)s.so_rcv, (char *)&rb, sizeof(rb))) + if (!s.so_rcv || kread((KA_T)s.so_rcv, (char *)&rb, sizeof(rb))) rb.sb_cc = 0; - if (!s.so_snd || kread(ctx, (KA_T)s.so_snd, (char *)&sb, sizeof(sb))) + if (!s.so_snd || kread((KA_T)s.so_snd, (char *)&sb, sizeof(sb))) sb.sb_cc = 0; if (Lf->access == LSOF_FILE_ACCESS_READ) Lf->sz = (SZOFFTYPE)rb.sb_cc; @@ -780,13 +779,14 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ else Lf->sz = (SZOFFTYPE)(rb.sb_cc + sb.sb_cc); Lf->sz_def = 1; + Lf->off_def = 1; #endif /* HPUXV>=1030 */ /* * Read Unix protocol control block and the Unix address structure. */ enter_dev_ch(print_kptr(sa, (char *)NULL, 0)); - if (kread(ctx, (KA_T)s.so_pcb, (char *)&unp, sizeof(unp))) { + if (kread((KA_T)s.so_pcb, (char *)&unp, sizeof(unp))) { (void)snpf(Namech, Namechl, "can't read unpcb at %s", print_kptr((KA_T)s.so_pcb, (char *)NULL, 0)); break; @@ -802,7 +802,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ * Read UNIX domain socket address information for HP-UX below 10.30. */ if (unp.unp_addr) { - if (kread(ctx, (KA_T)unp.unp_addr, (char *)&mb, sizeof(mb))) { + if (kread((KA_T)unp.unp_addr, (char *)&mb, sizeof(mb))) { (void)snpf(Namech, Namechl, "can't read unp_addr at %s", print_kptr((KA_T)unp.unp_addr, (char *)NULL, 0)); break; @@ -817,14 +817,14 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ */ if (unp.unp_ino) { Lf->inode = (INODETYPE)unp.unp_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } ua = (struct sockaddr_un *)NULL; mbl = 0; if (unp.unp_addr && - kread(ctx, (KA_T)unp.unp_addr, (char *)&mb, sizeof(mb)) == 0 && + kread((KA_T)unp.unp_addr, (char *)&mb, sizeof(mb)) == 0 && mb.b_datap && - kread(ctx, (KA_T)mb.b_datap, (char *)&db, sizeof(db)) == 0) { + kread((KA_T)mb.b_datap, (char *)&db, sizeof(db)) == 0) { if (db.db_base) { if (dbl < (db.db_size + 1)) { dbl = db.db_size + 1; @@ -840,7 +840,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ Error(ctx); } } - if (kread(ctx, (KA_T)db.db_base, dbf, db.db_size) == 0) { + if (kread((KA_T)db.db_base, dbf, db.db_size) == 0) { mbl = db.db_size; dbf[mbl] = '\0'; ua = (struct sockaddr_un *)dbf; @@ -862,7 +862,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ if (ua->sun_family != AF_UNIX) { if (ua->sun_family == AF_UNSPEC) { if (unp.unp_conn) { - if (kread(ctx, (KA_T)unp.unp_conn, (char *)&uc, sizeof(uc))) + if (kread((KA_T)unp.unp_conn, (char *)&uc, sizeof(uc))) (void)snpf( Namech, Namechl, "can't read unp_conn at %s", print_kptr((KA_T)unp.unp_conn, (char *)NULL, 0)); @@ -900,10 +900,10 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ * process_stream_sock() - process stream socket */ -void process_stream_sock(ip, pcb, pn, vt) KA_T ip; /* IP module's q_ptr */ -KA_T pcb; /* protocol's q_ptr */ -char *pn; /* protocol name */ -enum vtype vt; /* vnode type */ +void process_stream_sock(KA_T ip, /* IP module's q_ptr */ + KA_T pcb, /* protocol's q_ptr */ + enum lsof_protocol pn, /* protocol name */ + enum vtype vt) /* vnode type */ { unsigned char *fa = (unsigned char *)NULL; char *ep; @@ -921,11 +921,10 @@ enum vtype vt; /* vnode type */ */ if (Fnet) Lf->sf |= SELNET; - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); - if (pn) { - (void)snpf(Lf->iproto, sizeof(Lf->iproto), pn); - Lf->inp_ty = 2; - } else if (Sfile && (vt != VNON) && Lf->dev_def && (Lf->inp_ty == 1)) { + Lf->type = LSOF_FILE_INET; + if (pn != LSOF_PROTOCOL_INVALID) { + Lf->iproto = pn; + } else if (Sfile && (vt != VNON) && Lf->dev_def && Lf->inode_def) { /* * If the protocol name isn't known and this stream socket's vnode type @@ -939,7 +938,7 @@ enum vtype vt; /* vnode type */ * Get IP structure. */ *Namech = '\0'; - if (!ip || kread(ctx, ip, (char *)&ic, sizeof(ic))) { + if (!ip || kread(ip, (char *)&ic, sizeof(ic))) { ep = endnm(&sz); (void)snpf(ep, sz, "%scan't read IP control structure from %s", sz ? " " : "", print_kptr(ip, (char *)NULL, 0)); @@ -967,7 +966,7 @@ enum vtype vt; /* vnode type */ /* * Process TCP socket. */ - if (kread(ctx, pcb, (char *)&tc, sizeof(tc))) { + if (kread(pcb, (char *)&tc, sizeof(tc))) { ep = endnm(&sz); (void)snpf(ep, sz, "%scan't read TCP PCB from %s", sz ? " " : "", print_kptr(pcb, (char *)NULL, 0)); @@ -988,7 +987,7 @@ enum vtype vt; /* vnode type */ */ la = (unsigned char *)&tc.tcp_u.tcp_u_iph.iph_src[0]; if (tc.tcp_hdr_len && tc.tcp_tcph && - kread(ctx, (KA_T)tc.tcp_tcph, (char *)&th, sizeof(th)) == 0) + kread((KA_T)tc.tcp_tcph, (char *)&th, sizeof(th)) == 0) pt = (u_short)th.th_lport; } lp = (int)ntohs(pt); @@ -1030,51 +1029,59 @@ enum vtype vt; /* vnode type */ else Lf->sz = (SZOFFTYPE)(rq + sq); Lf->sz_def = 1; + Lf->off_def = 1; +# else /* !defined(HASTCPTPIQ) && !defined(HASTCPTPIW) */ + Lf->off_def = 1; # endif /* defined(HASTCPTPIQ) || defined(HASTCPTPIW) */ # if defined(HASTCPOPT) + if (Ftcptpi & TCPTPI_FLAGS) { - /* - * Save TCP options and values.. - */ - if (tc.tcp_naglim == (uint)1) - Lf->lts.topt |= TF_NODELAY; - Lf->lts.mss = (unsigned long)tc.tcp_mss; - Lf->lts.msss = (unsigned char)1; + /* + * Save TCP options and values.. + */ + if (tc.tcp_naglim == (uint)1) + Lf->lts.topt |= TF_NODELAY; + Lf->lts.mss = (unsigned long)tc.tcp_mss; + Lf->lts.msss = (unsigned char)1; + } # endif /* defined(HASTCPOPT) */ # if defined(HASSOOPT) + if (Ftcptpi & TCPTPI_FLAGS) { - /* - * Save socket options. - */ - if (tc.tcp_broadcast) - Lf->lts.opt |= SO_BROADCAST; - if (tc.tcp_so_debug) - Lf->lts.opt |= SO_DEBUG; - if (tc.tcp_dontroute) - Lf->lts.opt |= SO_DONTROUTE; - if (tc.tcp_keepalive_intrvl && (tc.tcp_keepalive_intrvl != 7200000)) { - Lf->lts.opt |= SO_KEEPALIVE; - Lf->lts.kai = (unsigned int)tc.tcp_keepalive_intrvl; - } - if (tc.tcp_lingering) { - Lf->lts.opt |= SO_LINGER; - Lf->lts.ltm = (unsigned int)tc.tcp_linger; + /* + * Save socket options. + */ + if (tc.tcp_broadcast) + Lf->lts.opt |= SO_BROADCAST; + if (tc.tcp_so_debug) + Lf->lts.opt |= SO_DEBUG; + if (tc.tcp_dontroute) + Lf->lts.opt |= SO_DONTROUTE; + if (tc.tcp_keepalive_intrvl && + (tc.tcp_keepalive_intrvl != 7200000)) { + Lf->lts.opt |= SO_KEEPALIVE; + Lf->lts.kai = (unsigned int)tc.tcp_keepalive_intrvl; + } + if (tc.tcp_lingering) { + Lf->lts.opt |= SO_LINGER; + Lf->lts.ltm = (unsigned int)tc.tcp_linger; + } + if (tc.tcp_oobinline) + Lf->lts.opt |= SO_OOBINLINE; + if (tc.tcp_reuseaddr) + Lf->lts.opt |= SO_REUSEADDR; + if (tc.tcp_reuseport) + Lf->lts.opt |= SO_REUSEPORT; + if (tc.tcp_useloopback) + Lf->lts.opt |= SO_USELOOPBACK; + Lf->lts.qlen = (unsigned int)tc.tcp_conn_ind_cnt; + Lf->lts.qlim = (unsigned int)tc.tcp_conn_ind_max; + if (Lf->lts.qlen || Lf->lts.qlim) + Lf->lts.qlens = Lf->lts.qlims = (unsigned char)1; } - if (tc.tcp_oobinline) - Lf->lts.opt |= SO_OOBINLINE; - if (tc.tcp_reuseaddr) - Lf->lts.opt |= SO_REUSEADDR; - if (tc.tcp_reuseport) - Lf->lts.opt |= SO_REUSEPORT; - if (tc.tcp_useloopback) - Lf->lts.opt |= SO_USELOOPBACK; - Lf->lts.qlen = (unsigned int)tc.tcp_conn_ind_cnt; - Lf->lts.qlim = (unsigned int)tc.tcp_conn_ind_max; - if (Lf->lts.qlen || Lf->lts.qlim) - Lf->lts.qlens = Lf->lts.qlims = (unsigned char)1; # endif /* defined(HASSOOPT) */ Namech[0] = '\0'; @@ -1084,7 +1091,7 @@ enum vtype vt; /* vnode type */ /* * Process UDP socket. */ - if (kread(ctx, pcb, (char *)&ud, sizeof(ud))) { + if (kread(pcb, (char *)&ud, sizeof(ud))) { ep = endnm(&sz); (void)snpf(ep, sz, "%scan't read UDP PCB from %s", sz ? " " : "", print_kptr(pcb, (char *)NULL, 0)); @@ -1106,6 +1113,7 @@ enum vtype vt; /* vnode type */ } (void)ent_inaddr(la, (int)ntohs(pt), (unsigned char *)NULL, -1, AF_INET); + Lf->off_def = 1; Lf->lts.type = 1; Lf->lts.state.ui = (unsigned int)ud.udp_state; Namech[0] = '\0'; diff --git a/lib/dialects/hpux/kmem/dstore.c b/lib/dialects/hpux/kmem/dstore.c index 74415eed..db470c47 100644 --- a/lib/dialects/hpux/kmem/dstore.c +++ b/lib/dialects/hpux/kmem/dstore.c @@ -54,7 +54,7 @@ int CloneMaj; /* clone major device number */ /* * Drive_Nl -- table to drive the building of Nl[] via build_Nl() - * (See lsof.h and misc.c.) + * (See common.h and misc.c.) */ struct drive_Nl Drive_Nl[] = { diff --git a/lib/dialects/hpux/kmem/machine.h b/lib/dialects/hpux/kmem/machine.h index 2fc875ce..89d54104 100644 --- a/lib/dialects/hpux/kmem/machine.h +++ b/lib/dialects/hpux/kmem/machine.h @@ -161,7 +161,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ # define HASFSINO 1 @@ -171,7 +171,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -355,14 +355,6 @@ /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -524,7 +516,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -570,10 +562,11 @@ # define USE_LIB_READDEV 1 /* rdev.c */ # define USE_LIB_READMNT 1 /* rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ # define USE_LIB_RNCH 1 /* rnch.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ -/* #define USE_LIB_SNPF 1 snpf.c */ + # define snpf snprintf /* use the system's snprintf() */ /* diff --git a/lib/dialects/hpux/pstat/Makefile b/lib/dialects/hpux/pstat/Makefile index 9eace673..f3e0058d 100644 --- a/lib/dialects/hpux/pstat/Makefile +++ b/lib/dialects/hpux/pstat/Makefile @@ -21,7 +21,7 @@ CFLAGS= ${CDEFS} ${INCL} ${DEBUG} GRP= -HDR= lsof.h lsof_fields.h dlsof.h machine.h proto.h dproto.h +HDR= common.h lsof_fields.h dlsof.h machine.h proto.h dproto.h SRC= dfile.c dproc.c dsock.c dstore.c \ arg.c main.c misc.c node.c print.c proc.c store.c usage.c util.c diff --git a/lib/dialects/hpux/pstat/dfile.c b/lib/dialects/hpux/pstat/dfile.c index 27afe35a..37dfb5ef 100644 --- a/lib/dialects/hpux/pstat/dfile.c +++ b/lib/dialects/hpux/pstat/dfile.c @@ -119,10 +119,10 @@ static int Nzpss = 0; /* Nzps status: 1 = zeroed */ * Local function prototypes */ -static struct l_nc *ncache_addr(struct psfileid *ps); -static void ncache_free(void); -static int ncache_isroot(struct psfileid *ps); -static void ncache_size(void); +static struct l_nc *ncache_addr (struct psfileid * ps); +static void ncache_free (void); +static int ncache_isroot (struct psfileid * ps); +static void ncache_size (void); #endif /* defined(HASNCACHE) */ #if defined(HASIPv6) @@ -133,9 +133,9 @@ static void ncache_size(void); * getipnodebyname() functions */ -extern struct hostent * -gethostbyname2(char *nm, /* host name */ - int prot) /* protocol -- AF_INET or AF_INET6 */ +extern struct hostent *gethostbyname2(nm, prot) +char *nm; /* host name */ +int prot; /* protocol -- AF_INET or AF_INET6 */ { int err; @@ -170,7 +170,8 @@ int get_max_fd() { * ncache_addr() -- get ncache entry address */ -static struct l_nc *ncache_addr(struct psfileid *ps) /* parent's psfileid */ +static struct l_nc *ncache_addr(ps) +struct psfileid *ps; /* parent's psfileid */ { struct l_nc **hp, *lc; @@ -249,14 +250,15 @@ static void ncache_free() { * ncache_isroot() -- does psfileid represent the root of a file system? */ -static int ncache_isroot(struct psfileid *ps) /* psfileid */ +static int ncache_isroot(ps) +struct psfileid *ps; /* psfileid */ { if (!ps->psf_fsid.psfs_id && !ps->psf_fsid.psfs_type && ps->psf_fileid == -1) return (1); # if defined(HASFSINO) - if (!Lf->fs_ino || (Lf->inp_ty != 1) || !Lf->dev_def) + if (!Lf->fs_ino || !Lf->inode_def || !Lf->dev_def) return (0); if ((Lf->dev == (dev_t)ps->psf_fsid.psfs_id) && (Lf->fs_ino == (unsigned long)ps->psf_fileid)) @@ -288,8 +290,9 @@ void ncache_load() { * ncache_loadfs() -- load the name cache for a file system */ -struct l_fic *ncache_loadfs(struct psfsid *fsid, /* ID of file system to add */ - struct l_fic **fh) /* Ncfsid hash bucket */ +struct l_fic *ncache_loadfs(fsid, fh) +struct psfsid *fsid; /* ID of file system to add */ +struct l_fic **fh; /* Ncfsid hash bucket */ { char *cp; struct l_fic *f; @@ -390,9 +393,10 @@ struct l_fic *ncache_loadfs(struct psfsid *fsid, /* ID of file system to add */ * ncache_lookup() -- look up a node's name in the kernel's name cache */ -char *ncache_lookup(char *buf, /* receiving name buffer */ - int blen, /* receiving buffer length */ - int *fp) /* full path reply */ +char *ncache_lookup(buf, blen, fp) +char *buf; /* receiving name buffer */ +int blen; /* receiving buffer length */ +int *fp; /* full path reply */ { char *cp = buf; int ef; @@ -410,7 +414,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * file system mount point, return an empty path reply. That tells the * caller that the already-printed system mount point name is sufficient. */ - if (Lf->inp_ty == 1 && Lf->fs_ino && Lf->inode == Lf->fs_ino) + if (Lf->inode_def && Lf->fs_ino && Lf->inode == Lf->fs_ino) return (cp); # endif /* defined(HASFSINO) */ @@ -440,7 +444,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ */ # if defined(HASFSINO) - if (Lf->fs_ino && (Lf->inp_ty == 1) && (Lf->fs_ino == Lf->inode)) + if (Lf->fs_ino && Lf->inode_def && (Lf->fs_ino == Lf->inode)) return (cp); # endif /* defined(HASFSINO) */ @@ -577,8 +581,9 @@ static void ncache_size() { * print_dev() -- print device */ -char *print_dev(struct lfile *lf, /* file whose device is to be printed */ - dev_t *dev) /* device to be printed */ +char *print_dev(lf, dev) +struct lfile *lf; /* file whose device is to be printed */ +dev_t *dev; /* device to be printed */ { static char buf[128]; @@ -597,7 +602,7 @@ struct pst_fid *opfid; /* opaque file ID for this file */ struct psfileid *psfid; /* PSTAT file ID for this file */ KA_T na; /* node address */ { - char *cp, buf[32]; + char buf[32]; dev_t dev; int devs = 0; int32_t lk; @@ -622,48 +627,44 @@ KA_T na; /* node address */ * Construct lock code. */ if ((lk = pd->psfd_lckflag) & PS_FPARTRDLCK) - Lf->lock = 'r'; + Lf->lock = LSOF_LOCK_READ_PARTIAL; else if (lk & PS_FPARTWRLCK) - Lf->lock = 'w'; + Lf->lock = LSOF_LOCK_WRITE_PARTIAL; else if (lk & PS_FFULLRDLCK) - Lf->lock = 'R'; + Lf->lock = LSOF_LOCK_READ_FULL; else if (lk & PS_FFULLWRLCK) - Lf->lock = 'W'; + Lf->lock = LSOF_LOCK_WRITE_FULL; else - Lf->lock = ' '; + Lf->lock = LSOF_LOCK_NONE; /* * Derive type from modes. */ switch ((int)(pd->psfd_mode & PS_IFMT)) { case PS_IFREG: - cp = "REG"; + Lf->type = LSOF_FILE_REGULAR; Ntype = N_REGLR; break; case PS_IFBLK: - cp = "BLK"; + Lf->type = LSOF_FILE_BLOCK; Ntype = N_BLK; break; case PS_IFDIR: - cp = "DIR"; + Lf->type = LSOF_FILE_DIR; Ntype = N_REGLR; break; case PS_IFCHR: - cp = "CHR"; + Lf->type = LSOF_FILE_CHAR; Ntype = N_CHR; break; case PS_IFIFO: - cp = "FIFO"; + Lf->type = LSOF_FILE_FIFO; Ntype = N_FIFO; break; default: - (void)snpf(buf, sizeof(buf), "%04o", - (unsigned int)(((pd->psfd_mode & PS_IFMT) >> 12) & 0xfff)); - cp = buf; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = pd->psfd_mode; Ntype = N_REGLR; } - if (!Lf->type[0]) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", cp); - Lf->ntype = Ntype; /* * Save device number. */ @@ -683,7 +684,7 @@ KA_T na; /* node address */ * Save node number. */ Lf->inode = (INODETYPE)pd->psfd_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; /* * Save link count. */ @@ -717,10 +718,12 @@ KA_T na; /* node address */ * If no offset has been activated and no size saved, activate the offset or * save the size. */ - if (!Lf->sz_def) { + if (!Lf->off_def && !Lf->sz_def) { + Lf->off_def = 1; switch (Ntype) { case N_CHR: case N_FIFO: + Lf->off_def = 1; break; default: Lf->sz = (SZOFFTYPE)pd->psfd_size; diff --git a/lib/dialects/hpux/pstat/dproc.c b/lib/dialects/hpux/pstat/dproc.c index 31ab3201..be7a3991 100644 --- a/lib/dialects/hpux/pstat/dproc.c +++ b/lib/dialects/hpux/pstat/dproc.c @@ -110,11 +110,11 @@ static struct psfileid RtPsfid; /* "/" psfileid */ * Local function prototypes */ -static void get_kernel_access(void); -static void process_text(struct pst_status *p); -static struct pst_fileinfo2 *read_files(struct pst_status *p, int *n); -static struct pst_status *read_proc(int *n); -static struct pst_vm_status *read_vmreg(struct pst_status *p, int *n); +static void get_kernel_access (void); +static void process_text (struct pst_status * p); +static struct pst_fileinfo2 *read_files (struct pst_status * p, int *n); +static struct pst_status *read_proc (int *n); +static struct pst_vm_status *read_vmreg (struct pst_status * p, int *n); /* * gather_proc_info() -- gather process information @@ -335,10 +335,12 @@ void gather_proc_info() { */ Lf->fct = (long)f->psf_count; Lf->fsv |= FSV_CT; + ka = (((KA_T)(f->psf_hi_fileid & 0xffffffff) << 32) | (KA_T)(f->psf_lo_fileid & 0xffffffff)); if ((Lf->fsa = ka)) Lf->fsv |= FSV_FA; + Lf->ffg = flag; Lf->fsv |= FSV_FG; Lf->pof = (long)(f->psf_flag & PS_FEXCLOS); @@ -354,7 +356,6 @@ void gather_proc_info() { #else /* !defined(_PSTAT64) */ Lf->off = (SZOFFTYPE)f->psf_offset; #endif /* defined(_PSTAT64) */ - Lf->off_def = 1; /* * Process the file by its type. @@ -395,15 +396,15 @@ void gather_proc_info() { (void)process_stream(f, (int)ckscko); break; case PS_TYPE_UNKNOWN: - (void)snpf(Lf->type, sizeof(Lf->type), "UNKN"); + Lf->type = LSOF_FILE_UNKNOWN; (void)enter_nm("no more information"); break; case PS_TYPE_UNSP: - (void)snpf(Lf->type, sizeof(Lf->type), "UNSP"); + Lf->type = LSOF_FILE_UNSUPPORTED; (void)enter_nm("no more information"); break; case PS_TYPE_LLA: - (void)snpf(Lf->type, sizeof(Lf->type), "LLA"); + Lf->type = LSOF_FILE_LINK_LEVEL_ACCESS; (void)enter_nm("no more information"); break; } @@ -628,12 +629,13 @@ static void process_text(p) struct pst_status *p; /* pst_status for process */ * read_det() -- read the pst_filedetails structure */ -KA_T read_det(struct pst_fid *ki, /* kernel file ID */ - uint32_t hf, /* high file ID bits */ - uint32_t lf, /* low file ID bits */ - uint32_t hn, /* high node ID bits */ - uint32_t ln, /* low node ID bits */ - struct pst_filedetails *pd) /* details receiver */ +KA_T read_det(ki, hf, lf, hn, ln, pd) +struct pst_fid *ki; /* kernel file ID */ +uint32_t hf; /* high file ID bits */ +uint32_t lf; /* low file ID bits */ +uint32_t hn; /* high node ID bits */ +uint32_t ln; /* low node ID bits */ +struct pst_filedetails *pd; /* details receiver */ { KA_T na; @@ -650,9 +652,9 @@ KA_T read_det(struct pst_fid *ki, /* kernel file ID */ * read_files() -- read the file descriptor information for a process */ -static struct pst_fileinfo2 * -read_files(struct pst_status *p, /* pst_status for the process */ - int *n) /* returned fi[] entry count */ +static struct pst_fileinfo2 *read_files(p, n) +struct pst_status *p; /* pst_status for the process */ +int *n; /* returned fi[] entry count */ { size_t ec; static struct pst_fileinfo2 *fi = (struct pst_fileinfo2 *)NULL; @@ -702,7 +704,8 @@ read_files(struct pst_status *p, /* pst_status for the process */ * read_proc() -- read process table status information */ -static struct pst_status *read_proc(int *n) /* returned ps[] entry count */ +static struct pst_status *read_proc(n) +int *n; /* returned ps[] entry count */ { size_t el; int i = 0; @@ -748,14 +751,6 @@ static struct pst_status *read_proc(int *n) /* returned ps[] entry count */ rc = 0; } } while (rc > 0); - /* - * Reduce ps[] to a minimum, unless repeat mode is in effect. - */ - if (!RptTm && ps && np && (np < npa)) { - nb = (MALLOC_S)(np * sizeof(struct pst_status)); - if (!(ps = (struct pst_status *)realloc((MALLOC_P *)ps, nb))) - goto ps_alloc_error; - } *n = np; return (ps); } @@ -764,9 +759,9 @@ static struct pst_status *read_proc(int *n) /* returned ps[] entry count */ * read_vmreg() -- read info about the VM regions of a process */ -static struct pst_vm_status * -read_vmreg(struct pst_status *p, /* pst_status for process */ - int *n) /* returned region count */ +static struct pst_vm_status *read_vmreg(p, n) +struct pst_status *p; /* pst_status for process */ +int *n; /* returned region count */ { size_t ec = (size_t)p->pst_pid; MALLOC_S nb; diff --git a/lib/dialects/hpux/pstat/dproto.h b/lib/dialects/hpux/pstat/dproto.h index 6e17a1fa..9fd805b0 100644 --- a/lib/dialects/hpux/pstat/dproto.h +++ b/lib/dialects/hpux/pstat/dproto.h @@ -45,7 +45,7 @@ extern KA_T read_det(struct pst_fid *ki, uint32_t hf, uint32_t lf, uint32_t hn, extern struct pst_socket *read_sock(struct pst_fileinfo2 *f); #if defined(HASIPv6) -extern struct hostent *gethostbyname2(char *nm, int proto); +extern struct hostent *gethostbyname2, (char *nm int proto); #endif /* defined(HASIPv6) */ #if defined(HASVXFS) diff --git a/lib/dialects/hpux/pstat/dsock.c b/lib/dialects/hpux/pstat/dsock.c index 557c827f..3d54a985 100644 --- a/lib/dialects/hpux/pstat/dsock.c +++ b/lib/dialects/hpux/pstat/dsock.c @@ -445,82 +445,70 @@ struct pst_socket *s; /* constructed socket */ static void printpsproto(p) uint32_t p; /* protocol number */ { - int i; - static int m = -1; - char *s; - switch (p) { case PS_PROTO_IP: - s = "IP"; + Lf->iproto = LSOF_PROTOCOL_IP; break; case PS_PROTO_ICMP: - s = "ICMP"; + Lf->iproto = LSOF_PROTOCOL_ICMP; break; case PS_PROTO_IGMP: - s = "IGMP"; + Lf->iproto = LSOF_PROTOCOL_IGMP; break; case PS_PROTO_GGP: - s = "GGP"; + Lf->iproto = LSOF_PROTOCOL_GGP; break; case PS_PROTO_IPIP: - s = "IPIP"; + Lf->iproto = LSOF_PROTOCOL_IPIP; break; case PS_PROTO_TCP: - s = "TCP"; + Lf->iproto = LSOF_PROTOCOL_TCP; break; case PS_PROTO_EGP: - s = "EGP"; + Lf->iproto = LSOF_PROTOCOL_EGP; break; case PS_PROTO_IGP: - s = "IGP"; + Lf->iproto = LSOF_PROTOCOL_IGP; break; case PS_PROTO_PUP: - s = "PUP"; + Lf->iproto = LSOF_PROTOCOL_PUP; break; case PS_PROTO_UDP: - s = "UDP"; + Lf->iproto = LSOF_PROTOCOL_UDP; break; case PS_PROTO_IDP: s = "IDP"; + Lf->iproto = LSOF_PROTOCOL_IDP; break; case PS_PROTO_XTP: s = "XTP"; + Lf->iproto = LSOF_PROTOCOL_XTP; break; case PS_PROTO_ESP: - s = "ESP"; + Lf->iproto = LSOF_PROTOCOL_ESP; break; case PS_PROTO_AH: - s = "AH"; + Lf->iproto = LSOF_PROTOCOL_AH; break; case PS_PROTO_OSPF: - s = "OSPF"; + Lf->iproto = LSOF_PROTOCOL_OSPF; break; case PS_PROTO_IPENCAP: - s = "IPENCAP"; + Lf->iproto = LSOF_PROTOCOL_IPENCAP; break; case PS_PROTO_ENCAP: - s = "ENCAP"; + Lf->iproto = LSOF_PROTOCOL_ENCAP; break; case PS_PROTO_PXP: - s = "PXP"; + Lf->iproto = LSOF_PROTOCOL_PXP; break; case PS_PROTO_RAW: - s = "RAW"; + Lf->iproto = LSOF_PROTOCOL_RAW; break; default: - s = (char *)NULL; - } - if (s) - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, s); - else { - if (m < 0) { - for (i = 0, m = 1; i < IPROTOL - 2; i++) - m *= 10; - } - if (m > p) - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%d?", p); - else - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "*%d?", p % (m / 10)); + Lf->iproto = LSOF_PROTOCOL_UNKNOWN; + Lf->unknown_proto_number = p; + break; } } @@ -1046,8 +1034,7 @@ struct pst_socket *s; /* optional socket information /* * Set default type. */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_SOCKET; /* * Generate and save node ID. */ @@ -1056,8 +1043,10 @@ struct pst_socket *s; /* optional socket information #if defined(HASFSTRUCT) if (na) { - Lf->fna = na; - Lf->fsv |= FSV_NI; + if (na) { + Lf->fna = na; + Lf->fsv |= FSV_NI; + } } #endif /* defined(HASFSTRUCT) */ @@ -1071,6 +1060,7 @@ struct pst_socket *s; /* optional socket information else Lf->sz = (SZOFFTYPE)(s->pst_idata + s->pst_odata); Lf->sz_def = 1; + Lf->off_def = 1; #if defined(HASTCPTPIQ) /* @@ -1121,17 +1111,16 @@ struct pst_socket *s; /* optional socket information */ switch (s->pst_family) { case PS_AF_INET: - if (Fnet && (!FnetTy || (FnetTy != 6))) + if (Fnet && (FnetTy == AF_UNSPEC || FnetTy == AF_INET)) Lf->sf |= SELNET; - (void)snpf(Lf->type, sizeof(Lf->type), - + Lf->type = #if defined(HASIPv6) - "IPv4" + LSOF_FILE_IPV4 #else /* !defined(HASIPv6) */ - "inet" + LSOF_FILE_INET #endif /* defined(HASIPv6) */ + ; - ); printpsproto(s->pst_protocol); enter_dev_ch(print_kptr(na, (char *)NULL, 0)); switch (s->pst_protocol) { @@ -1166,9 +1155,9 @@ struct pst_socket *s; /* optional socket information #if defined(HASIPv6) case PS_AF_INET6: af = AF_INET6; - if (Fnet && (!FnetTy || (FnetTy != 4))) + if (Fnet && (FnetTy == AF_UNSPEC || FnetTy == AF_INET6)) Lf->sf |= SELNET; - (void)snpf(Lf->type, sizeof(Lf->type), "IPv6"); + Lf->type = LSOF_FILE_IPV6; printpsproto(s->pst_protocol); enter_dev_ch(print_kptr(na, (char *)NULL, 0)); switch (s->pst_protocol) { @@ -1214,7 +1203,7 @@ struct pst_socket *s; /* optional socket information case PS_AF_UNIX: if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; if (((len = (size_t)s->pst_boundaddr_len) > 0) && (len <= sizeof(struct sockaddr_un))) { ua = (struct sockaddr_un *)s->pst_boundaddr; @@ -1335,7 +1324,6 @@ int ckscko; /* socket file only checking * if 1 */ { struct clone *cl; - char *cp; struct l_dev *dp = (struct l_dev *)NULL; int hx, i, ncx, nsn, nsr; size_t nb, nl; @@ -1374,18 +1362,17 @@ int ckscko; /* socket file only checking */ switch (f->psf_ftype) { case PS_TYPE_STREAMS: - cp = "STR"; + Lf->type = LSOF_FILE_STREAM; break; case PS_TYPE_SOCKET: if (f->psf_subtype == PS_SUBTYPE_SOCKSTR) { - cp = "STSO"; + Lf->type = LSOF_FILE_STREAM_SOCKET; break; } /* fall through */ default: - cp = "unkn"; + Lf->type = LSOF_FILE_UNKNOWN; } - (void)snpf(Lf->type, sizeof(Lf->type), "%s", cp); /* * Allocate sufficient space for stream structures, then read them. */ @@ -1527,12 +1514,12 @@ int ckscko; /* socket file only checking (void)snpf(Namech, Namechl, "%s", dp->name); ncx = strlen(Namech); Lf->inode = (INODETYPE)dp->inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; } else { ncx = (size_t)0; if (f->psf_id.psf_fileid > 0) { Lf->inode = (INODETYPE)f->psf_id.psf_fileid; - Lf->inp_ty = 1; + Lf->inode_def = 1; } } /* @@ -1558,8 +1545,9 @@ int ckscko; /* socket file only checking * Set offset defined if file size not requested or if no size was * obtained from the stream head. */ - Lf->ntype = N_STREAM; + Ntype = N_STREAM; Lf->is_stream = 1; + Lf->off_def = 1; /* * Test for specified file. */ @@ -1581,7 +1569,8 @@ int ckscko; /* socket file only checking * read_sock() -- read pst_socket info for file */ -struct pst_socket *read_sock(struct pst_fileinfo2 *f) /* file information */ +struct pst_socket *read_sock(f) +struct pst_fileinfo2 *f; /* file information */ { static struct pst_socket s; diff --git a/lib/dialects/hpux/pstat/machine.h b/lib/dialects/hpux/pstat/machine.h index f132d1f7..7ab021d2 100644 --- a/lib/dialects/hpux/pstat/machine.h +++ b/lib/dialects/hpux/pstat/machine.h @@ -150,7 +150,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ # define HASFSINO 1 @@ -160,7 +160,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -348,14 +348,6 @@ /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -# define HASPRIVPRIPP 1 - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -513,7 +505,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -552,6 +544,7 @@ /* #define USE_LIB_PRINT_TCPTPI 1 ptti.c */ # define USE_LIB_READDEV 1 /* rdev.c */ # define USE_LIB_READMNT 1 /* rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ /* #define USE_LIB_RNCH 1 rnch.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ diff --git a/lib/dialects/linux/dfile.c b/lib/dialects/linux/dfile.c index 78ecde9c..fa35578d 100644 --- a/lib/dialects/linux/dfile.c +++ b/lib/dialects/linux/dfile.c @@ -30,32 +30,6 @@ #include "common.h" -/* - * Local structures - */ - -struct hsfile { - struct sfile *s; /* the Sfile table address */ - struct hsfile *next; /* the next hash bucket entry */ -}; - -/* - * Local static variables - */ - -static struct hsfile *HbyFdi = /* hash by file (dev,ino) buckets */ - (struct hsfile *)NULL; -static int HbyFdiCt = 0; /* HbyFdi entry count */ -static struct hsfile *HbyFrd = /* hash by file raw device buckets */ - (struct hsfile *)NULL; -static int HbyFrdCt = 0; /* HbyFrd entry count */ -static struct hsfile *HbyFsd = /* hash by file system buckets */ - (struct hsfile *)NULL; -static int HbyFsdCt = 0; /* HbyFsd entry count */ -static struct hsfile *HbyNm = /* hash by name buckets */ - (struct hsfile *)NULL; -static int HbyNmCt = 0; /* HbyNm entry count */ - /* * Local definitions */ @@ -92,7 +66,6 @@ static int HbyNmCt = 0; /* HbyNm entry count */ * hashSfile() - hash Sfile entries for use in is_file_named() searches */ void hashSfile(struct lsof_context *ctx) { - static int hs = 0; int i; struct sfile *s; struct hsfile *sh, *sn; @@ -100,7 +73,7 @@ void hashSfile(struct lsof_context *ctx) { * Do nothing if there are no file search arguments cached or if the * hashes have already been constructed. */ - if (!Sfile || hs) + if (!Sfile || ctxd.sfile_valid) return; /* * Allocate hash buckets by (device,inode), file system device, and file @@ -108,33 +81,49 @@ void hashSfile(struct lsof_context *ctx) { */ if (!(HbyFdi = (struct hsfile *)calloc((MALLOC_S)SFDIHASH, sizeof(struct hsfile)))) { - (void)fprintf( - stderr, "%s: can't allocate space for %d (dev,ino) hash buckets\n", - Pn, SFDIHASH); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate space for %d (dev,ino) hash buckets\n", Pn, + SFDIHASH); + } Error(ctx); + return; } if (!(HbyFrd = (struct hsfile *)calloc((MALLOC_S)SFRDHASH, sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate space for %d rdev hash buckets\n", Pn, - SFRDHASH); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't allocate space for %d rdev hash buckets\n", + Pn, SFRDHASH); + } Error(ctx); + return; } if (!(HbyFsd = (struct hsfile *)calloc((MALLOC_S)SFFSHASH, sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate space for %d file sys hash buckets\n", - Pn, SFFSHASH); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate space for %d file sys hash buckets\n", Pn, + SFFSHASH); + } Error(ctx); + return; } if (!(HbyNm = (struct hsfile *)calloc((MALLOC_S)SFNMHASH, sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate space for %d name hash buckets\n", Pn, - SFNMHASH); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't allocate space for %d name hash buckets\n", + Pn, SFNMHASH); + } Error(ctx); + return; } - hs++; + + ctxd.sfile_valid = 1; + /* * Scan the Sfile chain, building file, file system, raw device, and file * name hash bucket chains. @@ -182,10 +171,14 @@ void hashSfile(struct lsof_context *ctx) { } else { if (!(sn = (struct hsfile *)malloc( (MALLOC_S)sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate hsfile bucket for: %s\n", - Pn, s->aname); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate hsfile bucket for: %s\n", Pn, + s->aname); + } Error(ctx); + return; } sn->s = s; sn->next = sh->next; @@ -198,28 +191,26 @@ void hashSfile(struct lsof_context *ctx) { /* * is_file_named() - is this file named? */ -int is_file_named( - /* context */ - struct lsof_context *ctx, - /* search type: 0 = only by device - * and inode - * 1 = by device and - * inode, or by file - * system device and - * path for NFS file - * systems - * 2 = only by path - */ - int search_type, - /* path name (device and inode are - * identified via *Lf) */ - char *path, - /* NFS file system (NULL if not) */ - struct mounts *nfs_mount, - /* character or block type file -- - * VCHR or VBLK vnode, or S_IFCHR - * or S_IFBLK inode */ - int cd) { +int is_file_named(struct lsof_context *ctx, + /* search type: 0 = only by device + * and inode + * 1 = by device and + * inode, or by file + * system device and + * path for NFS file + * systems + * 2 = only by path + */ + int search_type, + /* path name (device and inode are + * identified via *Lf) */ + char *path, + /* NFS file system (NULL if not) */ + struct mounts *nfs_mount, + /* character or block type file -- + * VCHR or VBLK vnode, or S_IFCHR + * or S_IFBLK inode */ + int cd) { char *ep; int f = 0; struct mounts *smp; @@ -242,8 +233,7 @@ int is_file_named( /* * Check for a regular file by device and inode number. */ - if (!f && (search_type < 2) && HbyFdiCt && Lf->dev_def && - (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + if (!f && (search_type < 2) && HbyFdiCt && Lf->dev_def && Lf->inode_def) { for (sh = &HbyFdi[SFHASHDEVINO(GET_MAJ_DEV(Lf->dev), GET_MIN_DEV(Lf->dev), Lf->inode, SFDIHASH)]; @@ -263,7 +253,7 @@ int is_file_named( GET_MIN_DEV(Lf->dev), 0, SFFSHASH)]; sh; sh = sh->next) { if ((s = sh->s) && (s->dev == Lf->dev)) { - if (Lf->ntype != N_NFS) { + if (Ntype != N_NFS) { /* * A non-NFS file matches to a non-NFS file system by @@ -298,8 +288,7 @@ int is_file_named( * Check for a character or block device match. */ if (!f && !search_type && HbyFrdCt && cd && Lf->dev_def && - (Lf->dev == DevDev) && Lf->rdev_def && - (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + (Lf->dev == DevDev) && Lf->rdev_def && Lf->inode_def) { for (sh = &HbyFrd[SFHASHRDEVI( GET_MAJ_DEV(Lf->dev), GET_MIN_DEV(Lf->dev), GET_MAJ_DEV(Lf->rdev), GET_MIN_DEV(Lf->rdev), Lf->inode, @@ -348,11 +337,10 @@ int is_file_named( * since it is called by printname() in print.c, an ersatz one * is provided here. */ -int printdevname(struct lsof_context *ctx, /* context */ - dev_t *dev, /* device */ - dev_t *rdev, /* raw device */ - int newline, /* 1 = follow with '\n' */ - int node_type) /* node type: N_BLK or N_chr */ +int printdevname(struct lsof_context *ctx, dev_t *dev, /* device */ + dev_t *rdev, /* raw device */ + int newline, /* 1 = follow with '\n' */ + int node_type) /* node type: N_BLK or N_chr */ { char buf[128]; diff --git a/lib/dialects/linux/dlsof.h b/lib/dialects/linux/dlsof.h index 25db6581..ae6c13ba 100644 --- a/lib/dialects/linux/dlsof.h +++ b/lib/dialects/linux/dlsof.h @@ -136,6 +136,8 @@ typedef unsigned long KA_T; # define XDR_PMAPLIST (xdrproc_t) xdr_pmaplist # define XDR_VOID (xdrproc_t) xdr_void +# include "lsof.h" + /* * Global storage definitions (including their structure definitions) */ @@ -185,9 +187,6 @@ typedef struct pxinfo { /* hashed pipe, UNIX socket or pseudo- } pxinfo_t; # endif /* defined(HASEPTOPTS) */ -extern int HasNFS; -extern dev_t MqueueDev; - /* offset type: * 0 == unknown * 1 == lstat's st_size @@ -196,6 +195,319 @@ extern dev_t MqueueDev; # define OFFSET_UNKNOWN 0 # define OFFSET_LSTAT 1 # define OFFSET_FDINFO 2 -extern int OffType; + +typedef struct mntsup { + char *dir_name; /* mounted directory name */ + size_t dir_name_len; /* strlen(dir_name) */ + dev_t dev; /* device number */ + int ln; /* line on which defined */ + struct mntsup *next; /* next entry */ +} mntsup_t; + +/* local lock structure */ +struct llock { + int pid; + dev_t dev; + INODETYPE inode; + enum lsof_lock_mode type; + struct llock *next; +}; + +/* AX25 socket information */ +struct ax25sin { + char *da; /* destination address */ + char *dev_ch; /* device characters */ + char *sa; /* source address */ + INODETYPE inode; + unsigned long sq, rq; /* send and receive queue values */ + unsigned char sqs, rqs; /* send and receive queue states */ + int state; + struct ax25sin *next; +}; + +struct icmpin { + INODETYPE inode; /* node number */ + char *la; /* local address */ + char *ra; /* remote address */ + MALLOC_S lal; /* strlen(la) */ + MALLOC_S ral; /* strlen(ra) */ + struct icmpin *next; +}; + +/* IPX socket information */ +struct ipxsin { + INODETYPE inode; + char *la; /* local address */ + char *ra; /* remote address */ + int state; + unsigned long txq, rxq; /* transmit and receive queue values */ + struct ipxsin *next; +}; + +/* Netlink socket information */ +struct nlksin { + INODETYPE inode; /* node number */ + unsigned int pr; /* protocol */ + struct nlksin *next; +}; + +/* packet information */ +struct packin { + INODETYPE inode; + int ty; /* socket type */ + int pr; /* protocol */ + struct packin *next; +}; + +/* raw socket information */ +struct rawsin { + INODETYPE inode; + char *la; /* local address */ + char *ra; /* remote address */ + char *sp; /* state characters */ + MALLOC_S lal; /* strlen(la) */ + MALLOC_S ral; /* strlen(ra) */ + MALLOC_S spl; /* strlen(sp) */ + struct rawsin *next; +}; + +/* SCTP socket information */ +struct sctpsin { + INODETYPE inode; + int type; /* type: 0 = assoc + * 1 = eps + * 2 assoc and eps */ + char *addr; /* association or endpoint address */ + char *assocID; /* association ID */ + char *lport; /* local port */ + char *rport; /* remote port */ + char *laddrs; /* local address */ + char *raddrs; /* remote address */ + struct sctpsin *next; +}; + +/* IPv4 TCP and UDP socket + * information */ +struct tcp_udp { + INODETYPE inode; + unsigned long faddr, laddr; /* foreign & local IPv4 addresses */ + int fport, lport; /* foreign & local ports */ + unsigned long txq, rxq; /* transmit & receive queue values */ + int proto; /* 0 = TCP, 1 = UDP, 2 = UDPLITE */ + int state; /* protocol state */ + struct tcp_udp *next; /* in TcpUdp inode hash table */ +# if defined(HASEPTOPTS) + pxinfo_t *pxinfo; /* inode information */ + struct tcp_udp *ipc_next; /* in TcpUdp local ipc hash table */ + struct tcp_udp *ipc_peer; /* locally connected peer(s) info */ +# endif /* defined(HASEPTOPTS) */ +}; + +# if defined(HASIPv6) +/* IPv6 TCP and UDP socket + * information */ +struct tcp_udp6 { + INODETYPE inode; + struct in6_addr faddr, laddr; /* foreign & local IPv6 addresses */ + int fport, lport; /* foreign & local ports */ + unsigned long txq, rxq; /* transmit & receive queue values */ + int proto; /* 0 = TCP, 1 = UDP, 2 = UDPLITE */ + int state; /* protocol state */ + struct tcp_udp6 *next; +# if defined(HASEPTOPTS) + pxinfo_t *pxinfo; /* inode information */ + struct tcp_udp6 *ipc_next; /* in TcpUdp6 local ipc hash table */ + struct tcp_udp6 *ipc_peer; /* locally connected peer(s) info */ +# endif /* defined(HASEPTOPTS) */ +}; +# endif /* defined(HASIPv6) */ + +/* UNIX socket information */ +typedef struct uxsin { + INODETYPE inode; /* node number */ + char *pcb; /* protocol control block */ + char *path; /* file path */ + unsigned char sb_def; /* stat(2) buffer definitions */ + dev_t sb_dev; /* stat(2) buffer device */ + INODETYPE sb_ino; /* stat(2) buffer node number */ + dev_t sb_rdev; /* stat(2) raw device number */ + uint32_t ty; /* socket type */ + unsigned int opt; /* socket options */ + unsigned int ss; /* socket state */ + +# if defined(HASEPTOPTS) && defined(HASUXSOCKEPT) + struct uxsin *icons; /* incoming socket conections */ + unsigned int icstat; /* incoming connection status + * 0 == none */ + pxinfo_t *pxinfo; /* inode information */ + struct uxsin *peer; /* connected peer(s) info */ +# endif /* defined(HASEPTOPTS) && defined(HASUXSOCKEPT) */ + + struct uxsin *next; +} uxsin_t; + +struct lsof_context_dialect { + /* pipe endpoint hash buckets */ + pxinfo_t **pipe_endpoint_buckets; + /* pseudoterminal endpoint hash buckets */ + pxinfo_t **pty_endpoint_buckets; + /* posix msg queue endpoint hash buckets */ + pxinfo_t **posix_msg_queue_endpoint_buckets; + /* eventfd endpoint hash buckets */ + pxinfo_t **eventfd_endpoint_buckets; + + /* NFS mount point status: + * 1 == there is an NFS mount point, + * but its device number is + * unknown + * 2 == there is an NFS mount point + * and its device number is + * known + */ + int nfs_status; + + /* validity of the hashSfile() hash buckets */ + uint8_t sfile_valid; + + /* mount supplement + * hash buckets */ + mntsup_t **mount_sup_hash; + /* error reading mout supplement file */ + int mount_sup_error; + + /* buffer for get_fields() */ + char **get_fields_buffer; + size_t get_fields_buffer_size; + + /* PID-hashed locks */ + struct llock **locks; + + /* conditional status of regular file + * checking: + * 0 = unconditionally check + * 1 = conditionally check */ + uint8_t check_regular; + + /* socket file only checking status: + * 0 = none + * 1 = check only socket files */ + uint8_t check_only_socket; + + /* The number for the device behind + * mqueue mount point */ + dev_t mqueue_dev; + + /* offset type: + * 0 == unknown + * 1 == lstat's st_size + * 2 == from /proc//fdinfo + */ + int offset_type; + + /* AX25 socket info, hashed by inode */ + struct ax25sin **ax25_sin; + int ax25_valid; + + /* ICMP socket info, hashed by inode */ + struct icmpin **icmp_sin; + int icmp_valid; + + /* IPX socket info, hashed by inode */ + struct ipxsin **ipx_sin; + int ipx_valid; + + /* Netlink socket info, hashed by + * inode */ + struct nlksin **netlink_sin; + int netlink_valid; + + /* packet info, hashed by inode */ + struct packin **packet_sin; + int packet_valid; + + /* raw socket info, hashed by inode */ + struct rawsin **raw_sin; + int raw_valid; + + /* SCTP info, hashed by inode */ + struct sctpsin **sctp_sin; + int sctp_valid; + + /* IPv4 TCP & UDP info, hashed by + * inode */ + struct tcp_udp **tcp_udp; + /* dynamically sized hash bucket + * count for TCP and UDP -- will + * be a power of two */ + int tcp_udp_buckets; + int tcp_valid; + int udp_valid; + int udplite_valid; + /* IPv4 TCP & UDP info for socket used + for IPC, hashed by (addr, port paris + and protocol */ + struct tcp_udp **tcp_udp_ipc; + +# if defined(HASIPv6) + /* IPv6 raw socket info, hashed by + * inode */ + struct rawsin **raw6_sin; + int raw6_valid; + + /* IPv6 TCP & UDP info, hashed by + * inode */ + struct tcp_udp6 **tcp_udp6; + /* dynamically sized hash bucket + * count for IPv6 TCP and UDP -- will + * be a power of two */ + int tcp_udp6_buckets; + int tcp6_valid; + int udp6_valid; + int udplite6_valid; + /* IPv6 TCP & UDP info for socket used + for IPC, hashed by (addr, port paris + and protocol */ + struct tcp_udp6 **tcp_udp6_ipc; +# endif /* defined(HASIPv6) */ + + /* UNIX socket info, hashed by inode */ + uxsin_t **unix_sin; + int unix_valid; +}; +/* Convenience macros */ +/* mount supplement */ +# define MSHash (ctxd.mount_sup_hash) +/* endpoint buckets */ +# define Pinfo (ctxd.pipe_endpoint_buckets) +# define PtyInfo (ctxd.pty_endpoint_buckets) +# define PSXMQinfo (ctxd.posix_msg_queue_endpoint_buckets) +# define EvtFDinfo (ctxd.eventfd_endpoint_buckets) +/* locks */ +# define LckH (ctxd.locks) +/* NFS status */ +# define HasNFS (ctxd.nfs_status) +/* mqueue dev */ +# define MqueueDev (ctxd.mqueue_dev) +/* offset type */ +# define OffType (ctxd.offset_type) +/* check regular file or socket only */ +# define Cckreg (ctxd.check_regular) +# define Ckscko (ctxd.check_only_socket) +/* socket info */ +# define AX25sin (ctxd.ax25_sin) +# define Icmpin (ctxd.icmp_sin) +# define Ipxsin (ctxd.ipx_sin) +# define Nlksin (ctxd.netlink_sin) +# define Packin (ctxd.packet_sin) +# define Rawsin (ctxd.raw_sin) +# define SCTPsin (ctxd.sctp_sin) +# define TcpUdp (ctxd.tcp_udp) +# define TcpUdp_bucks (ctxd.tcp_udp_buckets) +# define TcpUdpIPC (ctxd.tcp_udp_ipc) +# define Rawsin6 (ctxd.raw6_sin) +# define TcpUdp6 (ctxd.tcp_udp6) +# define TcpUdp6_bucks (ctxd.tcp_udp6_buckets) +# define TcpUdp6IPC (ctxd.tcp_udp6_ipc) +# define Uxsin (ctxd.unix_sin) #endif /* LINUX_LSOF_H */ diff --git a/lib/dialects/linux/dmnt.c b/lib/dialects/linux/dmnt.c index 892dc3e0..ca9585cf 100644 --- a/lib/dialects/linux/dmnt.c +++ b/lib/dialects/linux/dmnt.c @@ -56,29 +56,10 @@ static int hash_mnt(char *dir_name); * Local structure definitions. */ -#if defined(HASMNTSUP) -typedef struct mntsup { - char *dir_name; /* mounted directory name */ - size_t dir_name_len; /* strlen(dir_name) */ - dev_t dev; /* device number */ - int ln; /* line on which defined */ - struct mntsup *next; /* next entry */ -} mntsup_t; -#endif /* defined(HASMNTSUP) */ - -/* - * Local static definitions - */ - -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ -static mntsup_t **MSHash = (mntsup_t **)NULL; /* mount supplement - * hash buckets */ - /* * convert_octal_escaped() -- convert octal-escaped characters in string */ -static char *convert_octal_escaped(struct lsof_context *ctx, /* context */ +static char *convert_octal_escaped(struct lsof_context *ctx, char *orig_str /* original string */) { int cur_ch, cvt_len, cvt_idx, orig_len, orig_idx, temp_idx; char *cvt_str; @@ -91,10 +72,13 @@ static char *convert_octal_escaped(struct lsof_context *ctx, /* context */ if (!(orig_len = (int)strlen(orig_str))) return ((char *)NULL); if (!(cvt_str = (char *)malloc(orig_len + 1))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for octal-escaping.\n", Pn, - orig_len + 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't allocate %d bytes for octal-escaping.\n", + Pn, orig_len + 1); + } Error(ctx); + return ((char *)NULL); } /* * Copy the string, replacing octal-escaped characters as they are found. @@ -144,10 +128,14 @@ static char *convert_octal_escaped(struct lsof_context *ctx, /* context */ */ cvt_len += 64; /* (Make an arbitrary increase.) */ if (!(cvt_str = (char *)realloc(cvt_str, cvt_len + 1))) { - (void)fprintf( - stderr, "%s: can't realloc %d bytes for octal-escaping.\n", - Pn, cvt_len + 1); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't realloc %d bytes for octal-escaping.\n", Pn, + cvt_len + 1); + } Error(ctx); + return NULL; } } @@ -167,22 +155,25 @@ static char *convert_octal_escaped(struct lsof_context *ctx, /* context */ #if defined(HASMNTSUP) /* * getmntdev() - get mount device from mount supplement + * + * returns 1 if found */ static int -getmntdev(struct lsof_context *ctx, /* context */ - char *dir_name, /* mounted directory name */ - size_t dir_name_len, /* strlen(dir_name) */ - struct stat *s, /* stat(2) buffer receptor */ - int *ss /* stat(2) status result -- i.e., SB_* - * values */) +getmntdev(struct lsof_context *ctx, + char *dir_name, /* mounted directory name */ + size_t dir_name_len, /* strlen(dir_name) */ + struct stat *s, /* stat(2) buffer receptor */ + int *ss /* stat(2) status result -- i.e., SB_* + * values */) { - static int err = 0; int h; - mntsup_t *mp, *mpn; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + mntsup_t *mp, *mpn = NULL; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; + int ret = 0; + FILE *fs = NULL; - if (err) + if (ctxd.mount_sup_error) return (0); if (!MSHash) { @@ -192,30 +183,31 @@ getmntdev(struct lsof_context *ctx, /* context */ */ char buf[(MAXPATHLEN * 2) + 1], *dp, path[(MAXPATHLEN * 2) + 1]; dev_t dev; - FILE *fs; int ln = 0; size_t sz; - if ((MntSup != 2) || !MntSupP) - return (0); - if (!is_readable(MntSupP, 1)) { - + if ((MntSup != 2) || !MntSupP) { + ret = 0; + goto cleanup; + } + if (!is_readable(ctx, MntSupP, 1)) { /* * The mount supplement file isn't readable. */ - err = 1; - return (0); + ctxd.mount_sup_error = 1; + ret = 0; + goto cleanup; } - if (!(fs = open_proc_stream(ctx, MntSupP, "r", &vbuf, &vsz, 0))) { - + if (!(fs = open_proc_stream(ctx, MntSupP, "r", &vbuf, &vsz))) { /* * The mount supplement file can't be opened for reading. */ - if (!Fwarn) - (void)fprintf(stderr, "%s: can't open(%s): %s\n", Pn, MntSupP, + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, "%s: can't open(%s): %s\n", Pn, MntSupP, strerror(errno)); - err = 1; - return (0); + ctxd.mount_sup_error = 1; + ret = 0; + goto cleanup; } buf[sizeof(buf) - 1] = '\0'; /* @@ -231,10 +223,10 @@ getmntdev(struct lsof_context *ctx, /* context */ * The mount supplement line doesn't begin with the absolute * path character '/'. */ - if (!Fwarn) - (void)fprintf(stderr, "%s: %s line %d: no path: \"%s\"\n", + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, "%s: %s line %d: no path: \"%s\"\n", Pn, MntSupP, ln, buf); - err = 1; + ctxd.mount_sup_error = 1; continue; } if (!(dp = strchr(buf, ' ')) || strncmp(dp + 1, "0x", 2)) { @@ -243,10 +235,11 @@ getmntdev(struct lsof_context *ctx, /* context */ * The path on the mount supplement line isn't followed by * " 0x". */ - if (!Fwarn) - (void)fprintf(stderr, "%s: %s line %d: no device: \"%s\"\n", - Pn, MntSupP, ln, buf); - err = 1; + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, + "%s: %s line %d: no device: \"%s\"\n", Pn, + MntSupP, ln, buf); + ctxd.mount_sup_error = 1; continue; } sz = (size_t)(dp - buf); @@ -269,11 +262,11 @@ getmntdev(struct lsof_context *ctx, /* context */ /* * The device number couldn't be assembled. */ - if (!Fwarn) - (void)fprintf(stderr, + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, "%s: %s line %d: illegal device: \"%s\"\n", Pn, MntSupP, ln, buf); - err = 1; + ctxd.mount_sup_error = 1; continue; } /* @@ -283,10 +276,15 @@ getmntdev(struct lsof_context *ctx, /* context */ if (!MSHash) { if (!(MSHash = (mntsup_t **)calloc(HASHMNT, sizeof(mntsup_t *)))) { - (void)fprintf( - stderr, - "%s: no space for mount supplement hash buckets\n", Pn); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: no space for mount supplement hash buckets\n", + Pn); + } Error(ctx); + ret = 0; + goto cleanup; } } h = hash_mnt(path); @@ -303,10 +301,12 @@ getmntdev(struct lsof_context *ctx, /* context */ * a warning. */ if (mp->dev != dev) { - (void)fprintf( - stderr, "%s: %s line %d path duplicate of %d: \"%s\"\n", - Pn, MntSupP, ln, mp->ln, buf); - err = 1; + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: %s line %d path duplicate of %d: \"%s\"\n", Pn, + MntSupP, ln, mp->ln, buf); + ctxd.mount_sup_error = 1; } continue; } @@ -314,18 +314,26 @@ getmntdev(struct lsof_context *ctx, /* context */ * Allocate and fill a new mount supplement hash entry. */ if (!(mpn = (mntsup_t *)malloc(sizeof(mntsup_t)))) { - (void)fprintf( - stderr, - "%s: no space for mount supplement entry: %d \"%s\"\n", Pn, - ln, buf); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: no space for mount supplement entry: %d \"%s\"\n", + Pn, ln, buf); + } Error(ctx); + ret = 0; + goto cleanup; } if (!(mpn->dir_name = (char *)malloc(sz + 1))) { - (void)fprintf( - stderr, - "%s: no space for mount supplement path: %d \"%s\"\n", Pn, - ln, buf); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: no space for mount supplement path: %d \"%s\"\n", + Pn, ln, buf); + } Error(ctx); + ret = 0; + goto cleanup; } (void)strcpy(mpn->dir_name, path); mpn->dir_name_len = sz; @@ -333,14 +341,17 @@ getmntdev(struct lsof_context *ctx, /* context */ mpn->ln = ln; mpn->next = MSHash[h]; MSHash[h] = mpn; + mpn = NULL; } if (ferror(fs)) { - if (!Fwarn) - (void)fprintf(stderr, "%s: error reading %s\n", Pn, MntSupP); - err = 1; + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, "%s: error reading %s\n", Pn, MntSupP); + ctxd.mount_sup_error = 1; } (void)fclose(fs); - if (err) { + fs = NULL; + CLEAN(vbuf); + if (ctxd.mount_sup_error) { if (MSHash) { for (h = 0; h < HASHMNT; h++) { for (mp = MSHash[h]; mp; mp = mpn) { @@ -350,10 +361,11 @@ getmntdev(struct lsof_context *ctx, /* context */ (void)free((MALLOC_P *)mp); } } - (void)free((MALLOC_P *)MSHash); - MSHash = (mntsup_t **)NULL; + CLEAN(MSHash); + mpn = NULL; } - return (0); + ret = 0; + goto cleanup; } } @@ -361,8 +373,10 @@ getmntdev(struct lsof_context *ctx, /* context */ * If no errors have been detected reading the mount supplement file, search * its hash buckets for the supplied directory path. */ - if (err) - return (0); + if (ctxd.mount_sup_error) { + ret = 0; + goto cleanup; + } h = hash_mnt(dir_name); for (mp = MSHash[h]; mp; mp = mp->next) { if ((dir_name_len == mp->dir_name_len) && @@ -370,10 +384,18 @@ getmntdev(struct lsof_context *ctx, /* context */ zeromem((char *)s, sizeof(struct stat)); s->st_dev = mp->dev; *ss |= SB_DEV; - return (1); + ret = 1; + goto cleanup; } } - return (0); + ret = 0; + +cleanup: + if (fs) + fclose(fs); + CLEAN(vbuf); + CLEAN(mpn); + return ret; } /* @@ -405,14 +427,15 @@ struct mounts *readmnt(struct lsof_context *ctx) { char *fp0 = (char *)NULL; char *fp1 = (char *)NULL; int fr, ignrdl, ignstat; - char *ln; - struct mounts *mp; - FILE *ms; + char *ln = NULL; + struct mounts *mp = NULL; + FILE *ms = NULL; int nfs; int mqueue; struct stat sb; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; + struct mounts *ret = NULL; if (Lmi || Lmist) return (Lmi); @@ -420,7 +443,11 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Open access to /proc/mounts, assigning a page size buffer to its stream. */ (void)snpf(buf, sizeof(buf), "%s/mounts", PROCFS); - ms = open_proc_stream(ctx, buf, "r", &vbuf, &vsz, 1); + if (!(ms = open_proc_stream(ctx, buf, "r", &vbuf, &vsz))) { + ret = NULL; + goto cleanup; + } + /* * Read mount table entries. */ @@ -484,7 +511,7 @@ struct mounts *readmnt(struct lsof_context *ctx) { } } else -#endif /* defined(HASEOPT */ +#endif /* defined(HASEOPT) */ ignrdl = ignstat = 0; @@ -493,9 +520,9 @@ struct mounts *readmnt(struct lsof_context *ctx) { */ if (!ignrdl) { if (!(ln = Readlink(ctx, dn))) { - if (!Fwarn) { + if (ctx->err && !Fwarn) { (void)fprintf( - stderr, + ctx->err, " Output information may be incomplete.\n"); } continue; @@ -503,6 +530,7 @@ struct mounts *readmnt(struct lsof_context *ctx) { if (ln != dn) { (void)free((FREE_P *)dn); dn = ln; + ln = NULL; } } if (*dn != '/') @@ -549,13 +577,13 @@ struct mounts *readmnt(struct lsof_context *ctx) { fr = 1; else { if ((fr = statsafely(ctx, dn, &sb))) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: can't stat() ", Pn); - safestrprt(fp[2], stderr, 0); - (void)fprintf(stderr, " file system "); - safestrprt(dn, stderr, 1); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: WARNING: can't stat() ", Pn); + safestrprt(fp[2], ctx->err, 0); + (void)fprintf(ctx->err, " file system "); + safestrprt(dn, ctx->err, 1); (void)fprintf( - stderr, + ctx->err, " Output information may be incomplete.\n"); } } else @@ -572,9 +600,11 @@ struct mounts *readmnt(struct lsof_context *ctx) { if ((MntSup == 2) && MntSupP) { ds = 0; if (getmntdev(ctx, dn, dnl, &sb, &ds) || !(ds & SB_DEV)) { - (void)fprintf(stderr, - "%s: assuming dev=%#lx for %s from %s\n", Pn, - (long)sb.st_dev, dn, MntSupP); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: assuming dev=%#lx for %s from %s\n", + Pn, (long)sb.st_dev, dn, MntSupP); + } } } else { if (!ignstat) @@ -604,13 +634,21 @@ struct mounts *readmnt(struct lsof_context *ctx) { (void)free((FREE_P *)mp->fsname); mp->fsname = (char *)NULL; } + if (mp->fsnmres) { + (void)free((FREE_P *)mp->fsnmres); + mp->fsnmres = (char *)NULL; + } } else { ne = 1; if (!(mp = (struct mounts *)malloc(sizeof(struct mounts)))) { - (void)fprintf(stderr, - "%s: can't allocate mounts struct for: ", Pn); - safestrprt(dn, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't allocate mounts struct for: ", Pn); + safestrprt(dn, ctx->err, 1); + } Error(ctx); + ret = NULL; + goto cleanup; } } mp->dir = dn; @@ -661,14 +699,19 @@ struct mounts *readmnt(struct lsof_context *ctx) { */ if (ignrdl || (*dn != '/')) { if (!(ln = mkstrcpy(dn, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: can't allocate space for: ", Pn); - safestrprt(dn, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't allocate space for: ", Pn); + safestrprt(dn, ctx->err, 1); + } Error(ctx); + ret = NULL; + goto cleanup; } ignstat = 1; } else ln = Readlink(ctx, dn); - dn = (char *)NULL; + dn = NULL; /* * Stat() the file system (mounted-on) name and add file system @@ -677,21 +720,50 @@ struct mounts *readmnt(struct lsof_context *ctx) { if (ignstat || !ln || statsafely(ctx, ln, &sb)) sb.st_mode = 0; mp->fsnmres = ln; + ln = NULL; mp->fs_mode = sb.st_mode; - if (ne) + if (ne) { Lmi = mp; + mp = NULL; + } } /* * Clean up and return the local mount info table address. */ - (void)fclose(ms); - if (dn) - (void)free((FREE_P *)dn); - if (fp0) - (void)free((FREE_P *)fp0); - if (fp1) - (void)free((FREE_P *)fp1); Lmist = 1; - return (Lmi); + ret = Lmi; + +cleanup: + if (ms) + (void)fclose(ms); + CLEAN(vbuf); + CLEAN(dn); + CLEAN(fp0); + CLEAN(fp1); + CLEAN(ln); + CLEAN(mp); + return ret; } + +void clean_mnt(struct lsof_context *ctx) { + struct mounts *mp; + struct mounts *mp_next; + + if (!Lmist) { + return; + } + Lmist = 0; + + /* Cleanup */ + for (mp = Lmi; mp; mp = mp_next) { + CLEAN(mp->dir); + CLEAN(mp->fsname); + CLEAN(mp->fsnmres); + + mp_next = mp->next; + free(mp); + } + + Lmi = NULL; +} \ No newline at end of file diff --git a/lib/dialects/linux/dnode.c b/lib/dialects/linux/dnode.c index dde55bb1..90345c0b 100644 --- a/lib/dialects/linux/dnode.c +++ b/lib/dialects/linux/dnode.c @@ -47,24 +47,6 @@ #define HASHPID(pid) (((int)((pid * 31415) >> 3)) & (PIDBUCKS - 1)) #define HASHPINFO(ino) (((int)((ino * 31415) >> 3)) & (PINFOBUCKS - 1)) -/* - * Local structure definitions - */ - -struct llock { - int pid; - dev_t dev; - INODETYPE inode; - char type; - struct llock *next; -}; - -/* - * Local definitions - */ - -struct llock **LckH = (struct llock **)NULL; /* PID-hashed locks */ - /* * Local function prototypes */ @@ -79,18 +61,6 @@ static void enter_pinfo(struct lsof_context *ctx); * Local storage */ -#if defined(HASEPTOPTS) -static pxinfo_t **Pinfo = (pxinfo_t **)NULL; /* pipe endpoint hash buckets */ -# if defined(HASPTYEPT) -static pxinfo_t **PtyInfo = (pxinfo_t **)NULL; /* pseudoterminal endpoint hash - * buckets */ -# endif /* defined(HASPTYEPT) */ -static pxinfo_t **PSXMQinfo = - (pxinfo_t **)NULL; /* posix msg queue endpoint hash buckets */ -static pxinfo_t **EvtFDinfo = - (pxinfo_t **)NULL; /* envetfd endpoint hash buckets */ -#endif /* defined(HASEPTOPTS) */ - /* * check_lock() - check lock for file *Lf, process *Lp */ @@ -128,7 +98,6 @@ static void endpoint_pxinfo_hash(pxinfo_t **pinfo_hash, const size_t nbuckets, } } } - static void endpoint_enter(struct lsof_context *ctx, pxinfo_t **pinfo_hash, const char *table_name, int id) { int h; @@ -144,7 +113,8 @@ static void endpoint_enter(struct lsof_context *ctx, pxinfo_t **pinfo_hash, lf = pi->lf; lp = &Lproc[pi->lpx]; if (pi->ino == id) { - if ((lp->pid == Lp->pid) && !strcmp(lf->fd, Lf->fd)) + if ((lp->pid == Lp->pid) && (lf->fd_type == Lf->fd_type) && + (lf->fd_num == Lf->fd_num)) return; } } @@ -153,10 +123,12 @@ static void endpoint_enter(struct lsof_context *ctx, pxinfo_t **pinfo_hash, * to the end of the pty device hash chain. */ if (!(np = (pxinfo_t *)malloc(sizeof(pxinfo_t)))) { - (void)fprintf(stderr, - "%s: no space for pipeinfo for %s, PID %d, FD %s\n", - table_name, Pn, Lp->pid, Lf->fd); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no space for pipeinfo for %s, PID %d, FD %d\n", + table_name, Pn, Lp->pid, Lf->fd_num); Error(ctx); + return; } np->ino = id; np->lf = Lf; @@ -170,7 +142,7 @@ static void endpoint_enter(struct lsof_context *ctx, pxinfo_t **pinfo_hash, static pxinfo_t * endpoint_find(struct lsof_context *ctx, pxinfo_t **pinfo_hash, - int (*is_acceptable)(struct lsof_context *, pxinfo_t *, int, + int (*is_acceptable)(struct lsof_context *ctx, pxinfo_t *, int, struct lfile *), int pid, struct lfile *lf, int id, pxinfo_t *pp) { int h; /* hash result */ @@ -196,13 +168,13 @@ endpoint_find(struct lsof_context *ctx, pxinfo_t **pinfo_hash, * endpoint_accept_other_than_self() -- a helper function return true if * fd associated with pi is not the same as fd associated with lf. */ - static int endpoint_accept_other_than_self(struct lsof_context *ctx, pxinfo_t *pi, int pid, struct lfile *lf) { struct lfile *ef = pi->lf; struct lproc *ep = &Lproc[pi->lpx]; - return (strcmp(lf->fd, ef->fd)) || (pid != ep->pid); + return lf->fd_type != ef->fd_type || lf->fd_num != ef->fd_num || + (pid != ep->pid); } /* @@ -226,9 +198,13 @@ static void enter_pinfo(struct lsof_context *ctx) { * Allocate pipe info hash buckets. */ if (!(Pinfo = (pxinfo_t **)calloc(PINFOBUCKS, sizeof(pxinfo_t *)))) { - (void)fprintf(stderr, "%s: no space for %d pipe info buckets\n", Pn, - PINFOBUCKS); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for %d pipe info buckets\n", Pn, + PINFOBUCKS); + } Error(ctx); + return; } } endpoint_enter(ctx, Pinfo, "pipeinfo", Lf->inode); @@ -237,8 +213,7 @@ static void enter_pinfo(struct lsof_context *ctx) { /* * find_pepti() -- find pipe end point info */ - -pxinfo_t *find_pepti(struct lsof_context *ctx, /* context */ +pxinfo_t *find_pepti(struct lsof_context *ctx, int pid, /* pid of the process owning lf */ struct lfile *lf, /* pipe's lfile */ pxinfo_t *pp) /* previous pipe info (NULL == none) */ @@ -264,17 +239,20 @@ void clear_ptyinfo(struct lsof_context *ctx) { * Lp = local process structure pointer */ -void enter_ptmxi(struct lsof_context *ctx, /* context */ - int mn) /* minor number of device */ +void enter_ptmxi(struct lsof_context *ctx, int mn) /* minor number of device */ { /* * Allocate pipe info hash buckets (but used for pty). */ if (!PtyInfo) { if (!(PtyInfo = (pxinfo_t **)calloc(PINFOBUCKS, sizeof(pxinfo_t *)))) { - (void)fprintf(stderr, "%s: no space for %d pty info buckets\n", Pn, - PINFOBUCKS); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for %d pty info buckets\n", Pn, + PINFOBUCKS); + } Error(ctx); + return; } } endpoint_enter(ctx, PtyInfo, "pty", mn); @@ -306,14 +284,13 @@ static int ptyepti_accept_slave(struct lsof_context *ctx, pxinfo_t *pi, int pid, * find_ptyepti() -- find pseudoterminal end point info */ -pxinfo_t *find_ptyepti(struct lsof_context *ctx, /* context */ - int pid, /* PID*/ - struct lfile *lf, /* pseudoterminal's lfile */ - int m, /* minor number type: - * 0 == use tty_index - * 1 == use minor device */ - pxinfo_t *pp) /* previous pseudoterminal info - * (NULL == none) */ +pxinfo_t *find_ptyepti(struct lsof_context *ctx, int pid, + struct lfile *lf, /* pseudoterminal's lfile */ + int m, /* minor number type: + * 0 == use tty_index + * 1 == use minor device */ + pxinfo_t *pp) /* previous pseudoterminal info + * (NULL == none) */ { return endpoint_find(ctx, PtyInfo, m ? ptyepti_accept_ptmx : ptyepti_accept_slave, pid, @@ -324,7 +301,8 @@ pxinfo_t *find_ptyepti(struct lsof_context *ctx, /* context */ * is_pty_slave() -- is a pseudoterminal a slave device */ -int is_pty_slave(int sm) /* slave major device number */ +int is_pty_slave(sm) +int sm; /* slave major device number */ { /* linux/Documentation/admin-guide/devices.txt ------------------------------------------- @@ -350,7 +328,8 @@ int is_pty_slave(int sm) /* slave major device number */ * is_pty_ptmx() -- is a pseudoterminal a master clone device */ -int is_pty_ptmx(dev_t dev) /* device number */ +int is_pty_ptmx(dev) +dev_t dev; /* device number */ { if ((GET_MAJ_DEV(dev) == TTYAUX_MAJOR) && (GET_MIN_DEV(dev) == 2)) return 1; @@ -380,9 +359,13 @@ void enter_psxmqinfo(struct lsof_context *ctx) { */ if (!(PSXMQinfo = (pxinfo_t **)calloc(PINFOBUCKS, sizeof(pxinfo_t *)))) { - (void)fprintf(stderr, "%s: no space for %d posix mq info buckets\n", - Pn, PINFOBUCKS); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for %d posix mq info buckets\n ", + Pn, PINFOBUCKS); + } Error(ctx); + return; } } endpoint_enter(ctx, PSXMQinfo, "psxmqinfo", Lf->inode); @@ -393,10 +376,10 @@ void enter_psxmqinfo(struct lsof_context *ctx) { */ pxinfo_t * -find_psxmqinfo(struct lsof_context *ctx, /* context */ - int pid, /* pid of the process owning lf */ - struct lfile *lf, /* posix mq's lfile */ - pxinfo_t *pp) /* previous posix mq info (NULL == none) */ +find_psxmqinfo(struct lsof_context *ctx, + int pid, /* pid of the process owning lf */ + struct lfile *lf, /* posix mq's lfile */ + pxinfo_t *pp) /* previous posix mq info (NULL == none) */ { return endpoint_find(ctx, PSXMQinfo, endpoint_accept_other_than_self, pid, lf, lf->inode, pp); @@ -424,9 +407,13 @@ void enter_evtfdinfo(struct lsof_context *ctx, int id) { */ if (!(EvtFDinfo = (pxinfo_t **)calloc(PINFOBUCKS, sizeof(pxinfo_t *)))) { - (void)fprintf(stderr, "%s: no space for %d envet fd info buckets\n", - Pn, PINFOBUCKS); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for %d envet fd info buckets\n", Pn, + PINFOBUCKS); + } Error(ctx); + return; } } endpoint_enter(ctx, EvtFDinfo, "evtfdinfo", id); @@ -437,37 +424,35 @@ void enter_evtfdinfo(struct lsof_context *ctx, int id) { */ pxinfo_t * -find_evtfdinfo(struct lsof_context *ctx, /* context */ - int pid, /* pid of the process owning lf */ - struct lfile *lf, /* eventfd's lfile */ - pxinfo_t *pp) /* previous eventfd info (NULL == none) */ +find_evtfdinfo(struct lsof_context *ctx, + int pid, /* pid of the process owning lf */ + struct lfile *lf, /* eventfd's lfile */ + pxinfo_t *pp) /* previous eventfd info (NULL == none) */ { void *r = endpoint_find(ctx, EvtFDinfo, endpoint_accept_other_than_self, pid, lf, lf->eventfd_id, pp); return r; } + #endif /* defined(HASEPTOPTS) */ /* * get_fields() - separate a line into fields */ -int get_fields(struct lsof_context *ctx, /* context */ - char *ln, /* input line */ - char *sep, /* separator list */ - char ***fr, /* field pointer return address */ - int *eb, /* indexes of fields where blank or an - * entry from the separator list may be - * embedded and are not separators - * (may be NULL) */ - int en) /* number of entries in eb[] (may be - * zero) */ +int get_fields(struct lsof_context *ctx, char *ln, /* input line */ + char *sep, /* separator list */ + char ***fr, /* field pointer return address */ + int *eb, /* indexes of fields where blank or an + * entry from the separator list may be + * embedded and are not separators + * (may be NULL) */ + int en) /* number of entries in eb[] (may be + * zero) */ { char *bp, *cp, *sp; int i, j, n; MALLOC_S len; - static char **fp = (char **)NULL; - static int nfpa = 0; for (cp = ln, n = 0; cp && *cp;) { for (bp = cp; *bp && (*bp == ' ' || *bp == '\t'); bp++) @@ -531,23 +516,28 @@ int get_fields(struct lsof_context *ctx, /* context */ } if (*cp) *cp++ = '\0'; - if (n >= nfpa) { - nfpa += 32; - len = (MALLOC_S)(nfpa * sizeof(char *)); - if (fp) - fp = (char **)realloc((MALLOC_P *)fp, len); + if (n >= ctxd.get_fields_buffer_size) { + ctxd.get_fields_buffer_size += 32; + len = (MALLOC_S)(ctxd.get_fields_buffer_size * sizeof(char *)); + if (ctxd.get_fields_buffer) + ctxd.get_fields_buffer = + (char **)realloc((MALLOC_P *)ctxd.get_fields_buffer, len); else - fp = (char **)malloc(len); - if (!fp) { - (void)fprintf( - stderr, "%s: can't allocate %d bytes for field pointers.\n", - Pn, (int)len); + ctxd.get_fields_buffer = (char **)malloc(len); + if (!ctxd.get_fields_buffer) { + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for field pointers.\n", Pn, + (int)len); + } Error(ctx); + return (0); } } - fp[n++] = bp; + ctxd.get_fields_buffer[n++] = bp; } - *fr = fp; + *fr = ctxd.get_fields_buffer; return (n); } @@ -555,8 +545,7 @@ int get_fields(struct lsof_context *ctx, /* context */ * get_locks() - get lock information from /proc/locks */ -void get_locks(struct lsof_context *ctx, /* context */ - char *p) /* /proc lock path */ +void get_locks(struct lsof_context *ctx, char *p) /* /proc lock path */ { unsigned long bp, ep; char buf[MAXPATHLEN], *ec, **fp; @@ -566,9 +555,9 @@ void get_locks(struct lsof_context *ctx, /* context */ struct llock *lp, *np; FILE *ls; long maj, min; - char type; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + enum lsof_lock_mode type; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; /* * Destroy previous lock information. */ @@ -588,16 +577,19 @@ void get_locks(struct lsof_context *ctx, /* context */ LckH = (struct llock **)calloc((MALLOC_S)PIDBUCKS, sizeof(struct llock *)); if (!LckH) { - (void)fprintf(stderr, "%s: can't allocate %d lock hash bytes\n", Pn, - (int)(sizeof(struct llock *) * PIDBUCKS)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d lock hash bytes\n", Pn, + (int)(sizeof(struct llock *) * PIDBUCKS)); Error(ctx); + return; } } /* * Open the /proc lock file, assign a page size buffer to its stream, * and read it. */ - if (!(ls = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(ls = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf), ls)) { if (get_fields(ctx, buf, ":", &fp, (int *)NULL, 0) < 10) @@ -657,9 +649,9 @@ void get_locks(struct lsof_context *ctx, /* context */ } ex = ((off_t)bp == (off_t)0 && (off_t)ep == OFFSET_MAX) ? 1 : 0; if (mode) - type = ex ? 'W' : 'w'; + type = ex ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL; else - type = ex ? 'R' : 'r'; + type = ex ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL; /* * Look for this lock via the hash buckets. */ @@ -675,11 +667,15 @@ void get_locks(struct lsof_context *ctx, /* context */ * Allocate a new llock structure and link it to the PID hash bucket. */ if (!(lp = (struct llock *)malloc(sizeof(struct llock)))) { - (void)snpf(buf, sizeof(buf), InodeFmt_d, inode); - (void)fprintf( - stderr, "%s: can't allocate llock: PID %d; dev %x; inode %s\n", - Pn, pid, (int)dev, buf); + (void)snpf(buf, sizeof(buf), "%" INODEPSPEC "d", inode); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate llock: PID %d; dev %x; inode %s\n", Pn, + pid, (int)dev, buf); + } Error(ctx); + return; } lp->pid = pid; lp->dev = dev; @@ -689,14 +685,37 @@ void get_locks(struct lsof_context *ctx, /* context */ LckH[h] = lp; } (void)fclose(ls); + if (vbuf) + free(vbuf); +} + +/* + * clean_locks() - cleanup lock information + */ + +void clean_locks(struct lsof_context *ctx) { + struct llock *lp, *np; + int i; + if (LckH) { + for (i = 0; i < PIDBUCKS; i++) { + for (lp = LckH[i]; lp; lp = np) { + np = lp->next; + (void)free((FREE_P *)lp); + } + LckH[i] = (struct llock *)NULL; + } + + free(LckH); + LckH = NULL; + } } /* * process_proc_node() - process file node */ -void process_proc_node(struct lsof_context *ctx, /* context */ - char *p, /* node's readlink() path */ +void process_proc_node(struct lsof_context *ctx, + char *p, /* node's readlink() path */ char *pbr, /* node's path before readlink() */ struct stat *s, /* stat() result for path */ int ss, /* *s status -- i.e., SB_* values */ @@ -709,7 +728,6 @@ void process_proc_node(struct lsof_context *ctx, /* context */ char *cp; struct mounts *mp = (struct mounts *)NULL; size_t sz; - char *tn; /* * Set the access mode, if possible. */ @@ -728,21 +746,21 @@ void process_proc_node(struct lsof_context *ctx, /* context */ type = s->st_mode & S_IFMT; switch (type) { case S_IFBLK: - Lf->ntype = Ntype = N_BLK; + Ntype = N_BLK; break; case S_IFCHR: - Lf->ntype = Ntype = N_CHR; + Ntype = N_CHR; break; case S_IFIFO: - Lf->ntype = Ntype = N_FIFO; + Ntype = N_FIFO; break; case S_IFSOCK: - /* Lf->ntype = Ntype = N_REGLR; by alloc_lfile() */ + Ntype = N_REGLR; process_proc_sock(ctx, p, pbr, s, ss, l, ls); return; case 0: if (!strcmp(p, "anon_inode")) - Lf->ntype = Ntype = N_ANON_INODE; + Ntype = N_ANON_INODE; break; } } @@ -774,7 +792,7 @@ void process_proc_node(struct lsof_context *ctx, /* context */ if ((mp->ty == N_NFS) && (mp->ds & SB_DEV) && Lf->dev_def && (Lf->dev == mp->dev) && (mp->dir && mp->dirl && !strncmp(mp->dir, p, mp->dirl))) { - Lf->ntype = Ntype = N_NFS; + Ntype = N_NFS; break; } } @@ -784,10 +802,10 @@ void process_proc_node(struct lsof_context *ctx, /* context */ */ if (ss & SB_INO) { Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; #if defined(HASEPTOPTS) - if ((Lf->ntype == N_FIFO) && FeptE) { + if ((Ntype == N_FIFO) && FeptE) { (void)enter_pinfo(ctx); Lf->sf |= SELPINFO; } else if ((Lf->dev == MqueueDev) && FeptE) { @@ -799,7 +817,7 @@ void process_proc_node(struct lsof_context *ctx, /* context */ /* * Check for a lock. */ - if (Lf->dev_def && (Lf->inp_ty == 1)) + if (Lf->dev_def && Lf->inode_def) (void)check_lock(ctx); /* * Save the file size. @@ -838,42 +856,37 @@ void process_proc_node(struct lsof_context *ctx, /* context */ if (ss & SB_MODE) { switch (type) { case S_IFBLK: - tn = "BLK"; + Lf->type = LSOF_FILE_BLOCK; break; case S_IFCHR: - tn = "CHR"; + Lf->type = LSOF_FILE_CHAR; break; case S_IFDIR: - tn = "DIR"; + Lf->type = LSOF_FILE_DIR; break; case S_IFIFO: - tn = "FIFO"; + Lf->type = LSOF_FILE_FIFO; break; case S_IFREG: if (Lf->dev == MqueueDev) - tn = "PSXMQ"; + Lf->type = LSOF_FILE_POSIX_MQ; else - tn = "REG"; + Lf->type = LSOF_FILE_REGULAR; break; case S_IFLNK: - tn = "LINK"; - break; - case S_ISVTX: - tn = "VTXT"; + Lf->type = LSOF_FILE_LINK; break; default: if (Ntype == N_ANON_INODE) - tn = "a_inode"; + Lf->type = LSOF_FILE_ANON_INODE; else { - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", - ((type >> 12) & 0xf)); - tn = (char *)NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = type; } } } else - tn = "unknown"; - if (tn) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", tn); + Lf->type = LSOF_FILE_UNKNOWN; + /* * Record an NFS file selection. */ diff --git a/lib/dialects/linux/dproc.c b/lib/dialects/linux/dproc.c index b6af36e0..de90828e 100644 --- a/lib/dialects/linux/dproc.c +++ b/lib/dialects/linux/dproc.c @@ -101,25 +101,16 @@ struct l_fdinfo { * Local variables */ -static short Cckreg; /* conditional status of regular file - * checking: - * 0 = unconditionally check - * 1 = conditionally check */ -static short Ckscko; /* socket file only checking status: - * 0 = none - * 1 = check only socket files */ - /* * Local function prototypes */ -static MALLOC_S alloc_cbf(struct lsof_context *ctx, MALLOC_S len, char **cbf, - MALLOC_S cbfa); static int get_fdinfo(struct lsof_context *ctx, char *p, int msk, struct l_fdinfo *fi); static int getlinksrc(char *ln, char *src, int srcl, char **rest); -static int isefsys(struct lsof_context *ctx, char *path, char *type, int l, - efsys_list_t **rep, struct lfile **lfr); +static int isefsys(struct lsof_context *ctx, char *path, + enum lsof_file_type type, int l, efsys_list_t **rep, + struct lfile **lfr); static int nm2id(char *nm, int *id, int *idl); static int read_id_stat(struct lsof_context *ctx, char *p, int id, char **cmd, int *ppid, int *pgid); @@ -133,75 +124,9 @@ static int statEx(struct lsof_context *ctx, char *p, struct stat *s, int *ss); static void snp_eventpoll(char *p, int len, int *tfds, int tfd_count); #if defined(HASSELINUX) -static int cmp_cntx_eq(char *pcntx, char *ucntx); - -# include - -/* - * cmp_cntx_eq -- compare program and user security contexts - */ - -static int cmp_cntx_eq(char *pcntx, /* program context */ - char *ucntx) /* user supplied context */ -{ - return !fnmatch(ucntx, pcntx, 0); -} - -/* - * enter_cntx_arg() - enter name ecurity context argument - */ - -int enter_cntx_arg(struct lsof_context *ctx, /* context */ - char *cntx) /* context */ -{ - cntxlist_t *cntxp; - /* - * Search the argument list for a duplicate. - */ - for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) { - if (!strcmp(cntxp->cntx, cntx)) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: duplicate context: %s\n", Pn, cntx); - } - return (1); - } - } - /* - * Create and link a new context argument list entry. - */ - if (!(cntxp = (cntxlist_t *)malloc((MALLOC_S)sizeof(cntxlist_t)))) { - (void)fprintf(stderr, "%s: no space for context: %s\n", Pn, cntx); - Error(ctx); - } - cntxp->f = 0; - cntxp->cntx = cntx; - cntxp->next = CntxArg; - CntxArg = cntxp; - return (0); -} +extern int cmp_cntx_eq(char *pcntx, char *ucntx); #endif /* defined(HASSELINUX) */ -/* - * alloc_cbf() -- allocate a command buffer - */ - -static MALLOC_S alloc_cbf(struct lsof_context *ctx, /* context */ - MALLOC_S len, /* required length */ - char **cbf, /* current buffer */ - MALLOC_S cbfa) /* current buffer allocation */ -{ - if (*cbf) - *cbf = (char *)realloc((MALLOC_P *)*cbf, len); - else - *cbf = (char *)malloc(len); - if (!*cbf) { - (void)fprintf(stderr, "%s: can't allocate command %d bytes\n", Pn, - (int)len); - Error(ctx); - } - return (len); -} - /* * gather_proc_info() -- gather process information */ @@ -211,42 +136,66 @@ void gather_proc_info(struct lsof_context *ctx) { char cmdbuf[MAXPATHLEN]; struct dirent *dp; unsigned char ht, pidts; - int n, nl, pgid, pid, ppid, prv, rv, tid, tpgid, tppid, tx; - static char *path = (char *)NULL; - static int pathl = 0; - static char *pidpath = (char *)NULL; - static MALLOC_S pidpathl = 0; - static MALLOC_S pidx = 0; - static DIR *ps = (DIR *)NULL; + int i, n, nl, pgid = 0, pid = 0, ppid = 0, prv, rv, tid = 0, tpgid = 0, + tppid = 0, tx; + + char *path = (char *)NULL; + int pathl = 0; + + char *pidpath = (char *)NULL; + char *temp = (char *)NULL; + MALLOC_S pidpathl = 0; + + MALLOC_S pidx = 0; + DIR *ps = (DIR *)NULL; struct stat sb; - static char *taskpath = (char *)NULL; - static int taskpathl = 0; - static char *tidpath = (char *)NULL; - static int tidpathl = 0; + + char *taskpath = (char *)NULL; + int taskpathl = 0; + + char *tidpath = (char *)NULL; + int tidpathl = 0; + DIR *ts; UID_ARG uid; + /* Cleanup endpoint info */ + (void)clear_pinfo(ctx); + (void)clear_psxmqinfo(ctx); +#if defined(HASUXSOCKEPT) + (void)clear_uxsinfo(ctx); +#endif /* defined(HASUXSOCKEPT) */ +#if defined(HASPTYEPT) + (void)clear_ptyinfo(ctx); +#endif /* defined(HASPTYEPT) */ + (void)clear_netsinfo(ctx); +#if defined(HASIPv6) + (void)clear_nets6info(ctx); +#endif /* defined(HASIPv6) */ + (void)clear_evtfdinfo(ctx); + /* * Do one-time setup. */ - if (!pidpath) { - pidx = strlen(PROCFS) + 1; - pidpathl = pidx + 64 + 1; /* 64 is growth room */ - if (!(pidpath = (char *)malloc(pidpathl))) { - (void)fprintf(stderr, + pidx = strlen(PROCFS) + 1; + pidpathl = pidx + 64 + 1; /* 64 is growth room */ + if (!(pidpath = (char *)malloc(pidpathl))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: can't allocate %d bytes for \"%s/\"\n", Pn, (int)pidpathl, PROCFS); - Error(ctx); } - (void)snpf(pidpath, pidpathl, "%s/", PROCFS); + Error(ctx); + goto cleanup; } + (void)snpf(pidpath, pidpathl, "%s/", PROCFS); + /* * Get lock and net information. */ (void)make_proc_path(ctx, pidpath, pidx, &path, &pathl, "locks"); (void)get_locks(ctx, path); - (void)make_proc_path(ctx, pidpath, pidx, &path, &pathl, "net/"); - (void)set_net_paths(ctx, path, strlen(path)); + (void)refresh_socket_info(ctx); /* * If only socket files have been selected, or socket files have been * selected ANDed with other selection options, enable the skipping of @@ -297,13 +246,13 @@ void gather_proc_info(struct lsof_context *ctx) { * Read /proc, looking for PID directories. Open each one and * gather its process and file information. */ - if (!ps) { - if (!(ps = opendir(PROCFS))) { - (void)fprintf(stderr, "%s: can't open %s\n", Pn, PROCFS); - Error(ctx); - } - } else - (void)rewinddir(ps); + if (!(ps = opendir(PROCFS))) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't open %s\n", Pn, PROCFS); + Error(ctx); + goto cleanup; + } + while ((dp = readdir(ps))) { if (nm2id(dp->d_name, &pid, &n)) continue; @@ -312,12 +261,18 @@ void gather_proc_info(struct lsof_context *ctx) { */ if ((pidx + n + 1 + 1) > pidpathl) { pidpathl = pidx + n + 1 + 1 + 64; - if (!(pidpath = (char *)realloc((MALLOC_P *)pidpath, pidpathl))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for \"%s/%s/\"\n", - Pn, (int)pidpathl, PROCFS, dp->d_name); + /* Beware: don't override pidpath before checking for NULL */ + if (!(temp = (char *)realloc((MALLOC_P *)pidpath, pidpathl))) { + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for \"%s/%s/\"\n", Pn, + (int)pidpathl, PROCFS, dp->d_name); + } Error(ctx); + goto cleanup; } + pidpath = temp; } (void)snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name); n += (pidx + 1); @@ -334,7 +289,6 @@ void gather_proc_info(struct lsof_context *ctx) { (void)make_proc_path(ctx, pidpath, n, &path, &pathl, "stat"); if ((prv = read_id_stat(ctx, path, pid, &cmd, &ppid, &pgid)) < 0) cmd = NULL; /* NULL means failure to get command name */ - #if defined(HASTASKS) /* * Task reporting has been selected, so save the process' command @@ -345,20 +299,10 @@ void gather_proc_info(struct lsof_context *ctx) { * options work properly. */ else if (!IgnTasks && (Selflags & SELTASK)) { - /* - * Copy cmd before next call to read_id_stat due to static - * variables - */ - if (cmd) { - strncpy(cmdbuf, cmd, sizeof(cmdbuf) - 1); - cmdbuf[sizeof(cmdbuf) - 1] = '\0'; - cmd = cmdbuf; - } - (void)make_proc_path(ctx, pidpath, n, &taskpath, &taskpathl, "task"); tx = n + 4; - if ((ts = opendir(taskpath))) { + if (taskpath && (ts = opendir(taskpath))) { /* * Process the PID's tasks. Record the open files of those @@ -383,18 +327,23 @@ void gather_proc_info(struct lsof_context *ctx) { if ((tx + 1 + nl + 1 + 4) > tidpathl) { tidpathl = tx + 1 + n + 1 + 4 + 64; if (tidpath) - tidpath = + temp = (char *)realloc((MALLOC_P *)tidpath, tidpathl); else - tidpath = (char *)malloc((MALLOC_S)tidpathl); - if (!tidpath) { - (void)fprintf(stderr, - "%s: can't allocate %d task bytes", - Pn, tidpathl); - (void)fprintf(stderr, " for \"%s/%s/stat\"\n", - taskpath, dp->d_name); + temp = (char *)malloc((MALLOC_S)tidpathl); + if (!temp) { + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate %d task bytes", Pn, + tidpathl); + (void)fprintf(ctx->err, " for \"%s/%s/stat\"\n", + taskpath, dp->d_name); + } Error(ctx); + goto cleanup; } + tidpath = temp; } (void)snpf(tidpath, tidpathl, "%s/%s/stat", taskpath, dp->d_name); @@ -433,21 +382,158 @@ void gather_proc_info(struct lsof_context *ctx) { Lp->tid = 0; } } + + CLEAN(cmd); } + + /* + * If endpoint info has been requested, make sure it is coded for + * printing. + * + * Lf contents must be preserved, since they may point to a + * malloc()'d area, and since Lf is used throughout the printing + * of the selected processes. + */ + if (FeptE) { + /* + * Scan all selected processes. + */ + for (i = 0; i < Nlproc; i++) { + Lp = &Lproc[i]; + + /* + * For processes that have been selected for printing + * and have files that are the end point(s) of pipe(s), + * process the file endpoints. + */ + if (Lp->pss && (Lp->ept & EPT_PIPE)) + (void)process_pinfo(ctx, 0); + /* + * Process POSIX MQ endpoints. + */ + if (Lp->ept & EPT_PSXMQ) + (void)process_psxmqinfo(ctx, 0); + +#if defined(HASUXSOCKEPT) + /* + * For processes that have been selected for printing + * and have files that are the end point(s) of UNIX + * socket(s), process the file endpoints. + */ + if (Lp->pss && (Lp->ept & EPT_UXS)) + (void)process_uxsinfo(ctx, 0); +#endif /* defined(HASUXSOCKEPT) */ + +#if defined(HASPTYEPT) + /* + * For processes that have been selected for printing + * and have files that are the end point(s) of pseudo- + * terminal files(s), process the file endpoints. + */ + if (Lp->pss && (Lp->ept & EPT_PTY)) + (void)process_ptyinfo(ctx, 0); +#endif /* defined(HASPTYEPT) */ + + /* + * Process INET socket endpoints. + */ + if (Lp->ept & EPT_NETS) + (void)process_netsinfo(ctx, 0); + +#if defined(HASIPv6) + /* + * Process INET6 socket endpoints. + */ + if (Lp->ept & EPT_NETS6) + (void)process_nets6info(ctx, 0); +#endif /* defined(HASIPv6) */ + /* + * Process eventfd endpoints. + */ + if (Lp->ept & EPT_EVTFD) + (void)process_evtfdinfo(ctx, 0); + } + /* + * In a second pass, look for unselected endpoint files, + * possibly selecting them for printing. + */ + for (i = 0; i < Nlproc; i++) { + Lp = &Lproc[i]; + + /* + * Process pipe endpoints. + */ + if (Lp->ept & EPT_PIPE_END) + (void)process_pinfo(ctx, 1); + /* + * Process POSIX MQ endpoints. + */ + if (Lp->ept & EPT_PSXMQ_END) + (void)process_psxmqinfo(ctx, 1); + +#if defined(HASUXSOCKEPT) + /* + * Process UNIX socket endpoints. + */ + if (Lp->ept & EPT_UXS_END) + (void)process_uxsinfo(ctx, 1); +#endif /* defined(HASUXSOCKEPT) */ + +#if defined(HASPTYEPT) + /* + * Process pseudo-terminal endpoints. + */ + if (Lp->ept & EPT_PTY_END) + (void)process_ptyinfo(ctx, 1); +#endif /* defined(HASPTYEPT) */ + + /* + * Process INET socket endpoints. + */ + if (Lp->ept & EPT_NETS_END) + (void)process_netsinfo(ctx, 1); + +#if defined(HASIPv6) + /* + * Process INET6 socket endpoints. + */ + if (Lp->ept & EPT_NETS6_END) + (void)process_nets6info(ctx, 1); +#endif /* defined(HASIPv6) */ + + /* + * Process envetfd endpoints. + */ + if (Lp->ept & EPT_EVTFD_END) + (void)process_evtfdinfo(ctx, 1); + } + } + +cleanup: + CLEAN(pidpath); + CLEAN(path); + CLEAN(taskpath); + CLEAN(tidpath); + if (ps) { + closedir(ps); + ps = NULL; + } + + return; } /* * get_fdinfo() - get values from /proc/fdinfo/FD */ -static int get_fdinfo(struct lsof_context *ctx, /* context */ - char *p, /* path to fdinfo file */ +static int get_fdinfo(struct lsof_context *ctx, + char *p, /* path to fdinfo file */ int msk, /* mask for information type: e.g., * the FDINFO_* definition */ struct l_fdinfo *fi) /* pointer to local fdinfo values * return structure */ { - char buf[MAXPATHLEN + 1], *ep, **fp; + char buf[MAXPATHLEN + 1], *ep, **fp = NULL; FILE *fs; int rv = 0; unsigned long ul; @@ -558,8 +644,8 @@ static int get_fdinfo(struct lsof_context *ctx, /* context */ if (( /* There can be more than one tfd: lines. - So even if we found one, we can not exit the loop. - However, we can assume tfd lines are continuous. */ + So even if we found one, we can not exit the loop. + However, we can assume tfd lines are continuous. */ opt_flg != FDINFO_TFD && (rv == msk || (rv & FDINFO_TFD))) || ( @@ -580,19 +666,20 @@ static int get_fdinfo(struct lsof_context *ctx, /* context */ * getlinksrc() - get the source path name for the /proc//fd/ link */ -static int getlinksrc(char *ln, /* link path */ - char *src, /* link source path return address */ - int srcl, /* length of src[] */ - char **rest) /* pointer to what follows the ':' in - * the link source path (NULL if no - * return requested) */ +static int getlinksrc(ln, src, srcl, rest) +char *ln; /* link path */ +char *src; /* link source path return address */ +int srcl; /* length of src[] */ +char **rest; /* pointer to what follows the ':' in + * the link source path (NULL if no + * return requested) */ { char *cp; int ll; if (rest) *rest = (char *)NULL; - if ((ll = readlink(ln, src, srcl - 1)) < 1 || ll >= srcl) + if (!ln || (ll = readlink(ln, src, srcl - 1)) < 1 || ll >= srcl) return (-1); src[ll] = '\0'; if (*src == '/') @@ -609,18 +696,21 @@ static int getlinksrc(char *ln, /* link path */ /* * initialize() - perform all initialization */ - void initialize(struct lsof_context *ctx) { int fd; struct l_fdinfo fi; char path[MAXPATHLEN]; struct stat sb; + + MqueueDev = -1; /* * Test for -i and -X option conflict. */ if (Fxopt && (Fnet || Nwad)) { - (void)fprintf(stderr, "%s: -i is useless when -X is specified.\n", Pn); - usage(ctx, 1, 0, 0); + if (ctx->err) + (void)fprintf(ctx->err, "%s: -i is useless when -X is specified.\n", + Pn); + Error(ctx); } /* * Open LSTAT_TEST_FILE and seek to byte LSTAT_TEST_SEEK, then lstat the @@ -650,32 +740,42 @@ void initialize(struct lsof_context *ctx) { } (void)close(fd); } - if (OffType == OFFSET_UNKNOWN) { - if (Foffset && !Fwarn) - (void)fprintf( - stderr, "%s: WARNING: can't report offset; disregarding -o.\n", - Pn); - Foffset = 0; - Fsize = 1; - } - if (Fsv && (OffType != OFFSET_FDINFO)) { - if (!Fwarn && FsvByf) - (void)fprintf( - stderr, - "%s: WARNING: can't report file flags; disregarding +f.\n", Pn); - Fsv = 0; - } + /* * Make sure the local mount info table is loaded if doing anything other - * than just Internet lookups. (HasNFS is defined during the loading of the - * local mount table.) + * than just Internet lookups. (HasNFS is defined during the + * loading of the local mount table.) */ if (Selinet == 0) (void)readmnt(ctx); } /* - * make_proc_path() - make a path in a /proc directory + * deinitialize() - perform all cleanup + */ +void deinitialize(struct lsof_context *ctx) { + clean_mnt(ctx); + clean_locks(ctx); + CLEAN(ctxd.get_fields_buffer); + ctxd.get_fields_buffer_size = 0; + + clean_ax25(ctx); + clean_icmp(ctx); + clean_ipx(ctx); + clean_netlink(ctx); + clean_pack(ctx); + clean_raw(ctx); + clean_sctp(ctx); + clean_unix(ctx); + clean_tcpudp(ctx, 1); +#if defined(HASIPv6) + clean_raw6(ctx); + clean_tcpudp6(ctx, 1); +#endif +} + +/* + * make_proc_path(ctx, ) - make a path in a /proc directory * * entry: * pp = pointer to /proc prefix @@ -688,7 +788,7 @@ void initialize(struct lsof_context *ctx) { * np = updated with new path * nl = updated with new buffer size */ -int make_proc_path(struct lsof_context *ctx, /* context */ +int make_proc_path(struct lsof_context *ctx, char *pp, /* path prefix -- e.g., /proc// */ int pl, /* strlen(pp) */ char **np, /* malloc'd receiving buffer */ @@ -705,9 +805,13 @@ int make_proc_path(struct lsof_context *ctx, /* context */ else cp = (char *)malloc(rl); if (!cp) { - (void)fprintf(stderr, "%s: can't allocate %d bytes for %s%s\n", Pn, - (int)rl, pp, sf); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't allocate %d bytes for %s%s\n", Pn, + (int)rl, pp, sf); + } Error(ctx); + return (0); } *nl = rl; *np = cp; @@ -723,13 +827,11 @@ int make_proc_path(struct lsof_context *ctx, /* context */ * Note: alloc_lfile() must have been called in advance. */ -static int isefsys(struct lsof_context *ctx, /* context */ - char *path, /* path to file */ - char *type, /* unknown file type */ - int l, /* link request: 0 = report - * 1 = link */ - efsys_list_t **rep, /* returned Efsysl pointer, if not - * NULL */ +static int isefsys(struct lsof_context *ctx, char *path, /* path to file */ + enum lsof_file_type type, int l, /* link request: 0 = report + * 1 = link */ + efsys_list_t **rep, /* returned Efsysl pointer, if + * not NULL */ struct lfile **lfr) /* allocated struct lfile pointer */ { efsys_list_t *ep; @@ -772,8 +874,8 @@ static int isefsys(struct lsof_context *ctx, /* context */ } if (!ds) (void)enter_dev_ch(ctx, "UNKNOWN"); - Lf->ntype = N_UNKN; - (void)snpf(Lf->type, sizeof(Lf->type), "%s", (type ? type : "UNKN")); + Ntype = N_UNKN; + Lf->type = type; (void)enter_nm(ctx, path); (void)snpf(nmabuf, sizeof(nmabuf), "(%ce %s)", ep->rdlnk ? '+' : '-', ep->path); @@ -794,9 +896,10 @@ static int isefsys(struct lsof_context *ctx, /* context */ * nm2id() - convert a name to an integer ID */ -static int nm2id(char *nm, /* pointer to name */ - int *id, /* pointer to ID receiver */ - int *idl) /* pointer to ID length receiver */ +static int nm2id(nm, id, idl) +char *nm; /* pointer to name */ +int *id; /* pointer to ID receiver */ +int *idl; /* pointer to ID length receiver */ { int tid, tidl; int invalid; @@ -823,18 +926,13 @@ static int nm2id(char *nm, /* pointer to name */ * open_proc_stream() -- open a /proc stream */ -FILE *open_proc_stream(struct lsof_context *ctx, /* context */ - char *p, /* pointer to path to open */ +FILE *open_proc_stream(struct lsof_context *ctx, + char *p, /* pointer to path to open */ char *m, /* pointer to mode -- e.g., "r" */ char **buf, /* pointer tp setvbuf() address * (NULL if none) */ - size_t *sz, /* setvbuf() size (0 if none or if + size_t *sz) /* setvbuf() size (0 if none or if * getpagesize() desired */ - int act) /* fopen() failure action: - * 0 : return (FILE *)NULL - * <>0 : fprintf() an error message - * and Error() - */ { FILE *fs; /* opened stream */ static size_t psz = (size_t)0; /* page size */ @@ -843,11 +941,7 @@ FILE *open_proc_stream(struct lsof_context *ctx, /* context */ * Open the stream. */ if (!(fs = fopen(p, m))) { - if (!act) - return ((FILE *)NULL); - (void)fprintf(stderr, "%s: can't fopen(%s, \"%s\"): %s\n", Pn, p, m, - strerror(errno)); - Error(ctx); + return ((FILE *)NULL); } /* * Return the stream if no buffer change is required. @@ -867,10 +961,14 @@ FILE *open_proc_stream(struct lsof_context *ctx, /* context */ */ if (!*buf) { if (!(*buf = (char *)malloc((MALLOC_S)tsz))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for %s stream buffer\n", - Pn, (int)tsz, p); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for %s stream buffer\n", Pn, + (int)tsz, p); + } Error(ctx); + return NULL; } *sz = tsz; } @@ -878,9 +976,13 @@ FILE *open_proc_stream(struct lsof_context *ctx, /* context */ * Assign the buffer to the stream. */ if (setvbuf(fs, *buf, _IOFBF, tsz)) { - (void)fprintf(stderr, "%s: setvbuf(%s)=%d failure: %s\n", Pn, p, - (int)tsz, strerror(errno)); + CLEAN(*buf); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: setvbuf(%s)=%d failure: %s\n", Pn, p, + (int)tsz, strerror(errno)); + } Error(ctx); + return NULL; } return (fs); } @@ -892,8 +994,8 @@ FILE *open_proc_stream(struct lsof_context *ctx, /* context */ * 1 == ID not processed */ -static int process_id(struct lsof_context *ctx, /* context */ - char *idp, /* pointer to ID's path */ +static int process_id(struct lsof_context *ctx, + char *idp, /* pointer to ID's path */ int idpl, /* pointer to ID's path length */ char *cmd, /* pointer to ID's command */ UID_ARG uid, /* ID's UID */ @@ -904,23 +1006,23 @@ static int process_id(struct lsof_context *ctx, /* context */ char *tcmd) /* task command, if non-NULL) */ { int av = 0; - static char *dpath = (char *)NULL; - static int dpathl = 0; + char *dpath = (char *)NULL; + int dpathl = 0; short efs, enls, enss, lnk, oty, pn, pss, sf; int fd, i, ls = 0, n, ss, sv; struct l_fdinfo fi; DIR *fdp; struct dirent *fp; - static char *ipath = (char *)NULL; - static int ipathl = 0; + char *ipath = (char *)NULL; + int ipathl = 0; int j = 0; struct lfile *lfr; struct stat lsb, sb; char nmabuf[MAXPATHLEN + 1], pbuf[MAXPATHLEN + 1]; - static char *path = (char *)NULL; - static int pathl = 0; - static char *pathi = (char *)NULL; - static int pathil = 0; + char *path = (char *)NULL; + int pathl = 0; + char *pathi = (char *)NULL; + int pathil = 0; char *rest; int txts = 0; @@ -960,10 +1062,12 @@ static int process_id(struct lsof_context *ctx, /* context */ Lp->tid = tid; if (tid && tcmd) { if (!(Lp->tcmd = mkstrcpy(tcmd, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, - "%s: PID %d, TID %d, no space for task name: ", Pn, - pid, tid); - safestrprt(tcmd, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: PID %d, TID %d, no space for task name: ", + Pn, pid, tid); + safestrprt(tcmd, ctx->err, 1); + } Error(ctx); } } @@ -975,46 +1079,49 @@ static int process_id(struct lsof_context *ctx, /* context */ efs = 0; if (!Ckscko) { (void)make_proc_path(ctx, idp, idpl, &path, &pathl, "cwd"); - alloc_lfile(ctx, CWD, -1); - if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) { - if (!Fwarn) { - zeromem((char *)&sb, sizeof(sb)); - lnk = ss = 0; - (void)snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)", - strerror(errno)); - nmabuf[sizeof(nmabuf) - 1] = '\0'; - (void)add_nma(ctx, nmabuf, strlen(nmabuf)); - pn = 1; - } else - pn = 0; - } else { - lnk = pn = 1; - if (Efsysl && !isefsys(ctx, pbuf, "UNKNcwd", 1, NULL, &lfr)) { - efs = 1; - pn = 0; - } else { - ss = SB_ALL; - if (HasNFS) { - if ((sv = statsafely(ctx, path, &sb))) - sv = statEx(ctx, pbuf, &sb, &ss); + if (path) { + alloc_lfile(ctx, LSOF_FD_CWD, -1); + if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) { + if (!Fwarn) { + zeromem((char *)&sb, sizeof(sb)); + lnk = ss = 0; + (void)snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)", + strerror(errno)); + nmabuf[sizeof(nmabuf) - 1] = '\0'; + (void)add_nma(ctx, nmabuf, strlen(nmabuf)); + pn = 1; } else - sv = stat(path, &sb); - if (sv) { - ss = 0; - if (!Fwarn) { - (void)snpf(nmabuf, sizeof(nmabuf), "(stat: %s)", - strerror(errno)); - nmabuf[sizeof(nmabuf) - 1] = '\0'; - (void)add_nma(ctx, nmabuf, strlen(nmabuf)); + pn = 0; + } else { + lnk = pn = 1; + if (Efsysl && + !isefsys(ctx, pbuf, LSOF_FILE_UNKNOWN_CWD, 1, NULL, &lfr)) { + efs = 1; + pn = 0; + } else { + ss = SB_ALL; + if (HasNFS) { + if ((sv = statsafely(ctx, path, &sb))) + sv = statEx(ctx, pbuf, &sb, &ss); + } else + sv = stat(path, &sb); + if (sv) { + ss = 0; + if (!Fwarn) { + (void)snpf(nmabuf, sizeof(nmabuf), "(stat: %s)", + strerror(errno)); + nmabuf[sizeof(nmabuf) - 1] = '\0'; + (void)add_nma(ctx, nmabuf, strlen(nmabuf)); + } } } } - } - if (pn) { - (void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, - (struct stat *)NULL, 0); - if (Lf->sf) - link_lfile(ctx); + if (pn) { + (void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, + (struct stat *)NULL, 0); + if (Lf->sf) + link_lfile(ctx); + } } } /* @@ -1023,44 +1130,47 @@ static int process_id(struct lsof_context *ctx, /* context */ lnk = ss = 0; if (!Ckscko) { (void)make_proc_path(ctx, idp, idpl, &path, &pathl, "root"); - alloc_lfile(ctx, RTD, -1); - if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) { - if (!Fwarn) { - zeromem((char *)&sb, sizeof(sb)); - (void)snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)", - strerror(errno)); - nmabuf[sizeof(nmabuf) - 1] = '\0'; - (void)add_nma(ctx, nmabuf, strlen(nmabuf)); - pn = 1; - } else - pn = 0; - } else { - lnk = pn = 1; - if (Efsysl && !isefsys(ctx, pbuf, "UNKNrtd", 1, NULL, NULL)) - pn = 0; - else { - ss = SB_ALL; - if (HasNFS) { - if ((sv = statsafely(ctx, path, &sb))) - sv = statEx(ctx, pbuf, &sb, &ss); + if (path) { + alloc_lfile(ctx, LSOF_FD_ROOT_DIR, -1); + if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) { + if (!Fwarn) { + zeromem((char *)&sb, sizeof(sb)); + (void)snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)", + strerror(errno)); + nmabuf[sizeof(nmabuf) - 1] = '\0'; + (void)add_nma(ctx, nmabuf, strlen(nmabuf)); + pn = 1; } else - sv = stat(path, &sb); - if (sv) { - ss = 0; - if (!Fwarn) { - (void)snpf(nmabuf, sizeof(nmabuf), "(stat: %s)", - strerror(errno)); - nmabuf[sizeof(nmabuf) - 1] = '\0'; - (void)add_nma(ctx, nmabuf, strlen(nmabuf)); + pn = 0; + } else { + lnk = pn = 1; + if (Efsysl && !isefsys(ctx, pbuf, LSOF_FILE_UNKNOWN_ROOT_DIR, 1, + NULL, NULL)) + pn = 0; + else { + ss = SB_ALL; + if (HasNFS) { + if ((sv = statsafely(ctx, path, &sb))) + sv = statEx(ctx, pbuf, &sb, &ss); + } else + sv = stat(path, &sb); + if (sv) { + ss = 0; + if (!Fwarn) { + (void)snpf(nmabuf, sizeof(nmabuf), "(stat: %s)", + strerror(errno)); + nmabuf[sizeof(nmabuf) - 1] = '\0'; + (void)add_nma(ctx, nmabuf, strlen(nmabuf)); + } } } } - } - if (pn) { - (void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, - (struct stat *)NULL, 0); - if (Lf->sf) - link_lfile(ctx); + if (pn) { + (void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, + (struct stat *)NULL, 0); + if (Lf->sf) + link_lfile(ctx); + } } } /* @@ -1069,50 +1179,54 @@ static int process_id(struct lsof_context *ctx, /* context */ lnk = ss = txts = 0; if (!Ckscko) { (void)make_proc_path(ctx, idp, idpl, &path, &pathl, "exe"); - alloc_lfile(ctx, "txt", -1); - if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) { - zeromem((void *)&sb, sizeof(sb)); - if (!Fwarn) { - if ((errno != ENOENT) || uid) { - (void)snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)", - strerror(errno)); - nmabuf[sizeof(nmabuf) - 1] = '\0'; - (void)add_nma(ctx, nmabuf, strlen(nmabuf)); - } - pn = 1; - } else - pn = 0; - } else { - lnk = pn = 1; - if (Efsysl && !isefsys(ctx, pbuf, "UNKNtxt", 1, NULL, NULL)) - pn = 0; - else { - ss = SB_ALL; - if (HasNFS) { - if ((sv = statsafely(ctx, path, &sb))) { - sv = statEx(ctx, pbuf, &sb, &ss); - if (!sv && (ss & SB_DEV) && (ss & SB_INO)) - txts = 1; - } - } else - sv = stat(path, &sb); - if (sv) { - ss = 0; - if (!Fwarn) { - (void)snpf(nmabuf, sizeof(nmabuf), "(stat: %s)", + if (path) { + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); + if (getlinksrc(path, pbuf, sizeof(pbuf), (char **)NULL) < 1) { + zeromem((void *)&sb, sizeof(sb)); + if (!Fwarn) { + if ((errno != ENOENT) || uid) { + (void)snpf(nmabuf, sizeof(nmabuf), "(readlink: %s)", strerror(errno)); nmabuf[sizeof(nmabuf) - 1] = '\0'; (void)add_nma(ctx, nmabuf, strlen(nmabuf)); } + pn = 1; } else - txts = 1; + pn = 0; + } else { + lnk = pn = 1; + if (Efsysl && + !isefsys(ctx, pbuf, LSOF_FILE_UNKNOWN_PROGRAM_TEXT, 1, NULL, + NULL)) + pn = 0; + else { + ss = SB_ALL; + if (HasNFS) { + if ((sv = statsafely(ctx, path, &sb))) { + sv = statEx(ctx, pbuf, &sb, &ss); + if (!sv && (ss & SB_DEV) && (ss & SB_INO)) + txts = 1; + } + } else + sv = stat(path, &sb); + if (sv) { + ss = 0; + if (!Fwarn) { + (void)snpf(nmabuf, sizeof(nmabuf), "(stat: %s)", + strerror(errno)); + nmabuf[sizeof(nmabuf) - 1] = '\0'; + (void)add_nma(ctx, nmabuf, strlen(nmabuf)); + } + } else + txts = 1; + } + } + if (pn) { + (void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, + (struct stat *)NULL, 0); + if (Lf->sf) + link_lfile(ctx); } - } - if (pn) { - (void)process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, - (struct stat *)NULL, 0); - if (Lf->sf) - link_lfile(ctx); } } /* @@ -1120,43 +1234,45 @@ static int process_id(struct lsof_context *ctx, /* context */ */ if (!Ckscko) { (void)make_proc_path(ctx, idp, idpl, &path, &pathl, "maps"); - (void)process_proc_map(ctx, path, txts ? &sb : (struct stat *)NULL, - txts ? ss : 0); + if (path) + (void)process_proc_map(ctx, path, txts ? &sb : (struct stat *)NULL, + txts ? ss : 0); } #if defined(HASSELINUX) /* * Process the PID's SELinux context. */ - if (Fcntx) { - /* - * If the -Z (cntx) option was specified, match the valid contexts. - */ - errno = 0; - if (getpidcon(pid, &Lp->cntx) == -1) { - Lp->cntx = (char *)NULL; - if (!Fwarn) { - (void)snpf(nmabuf, sizeof(nmabuf), "(getpidcon: %s)", - strerror(errno)); - if (!(Lp->cntx = strdup(nmabuf))) { - (void)fprintf(stderr, "%s: no context error space: PID %ld", - Pn, (long)Lp->pid); - Error(ctx); - } + /* + * match the valid contexts. + */ + errno = 0; + if (getpidcon(pid, &Lp->cntx) == -1) { + Lp->cntx = (char *)NULL; + if (!Fwarn) { + (void)snpf(nmabuf, sizeof(nmabuf), "(getpidcon: %s)", + strerror(errno)); + if (!(Lp->cntx = strdup(nmabuf))) { + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no context error space: PID %ld", Pn, + (long)Lp->pid); + Error(ctx); + return 0; } - } else if (CntxArg) { + } + } else if (CntxArg) { - /* - * See if context includes the process. - */ - for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) { - if (cmp_cntx_eq(Lp->cntx, cntxp->cntx)) { - cntxp->f = 1; - Lp->pss |= PS_PRI; - Lp->sf |= SELCNTX; - break; - } + /* + * See if context includes the process. + */ + for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) { + if (cmp_cntx_eq(Lp->cntx, cntxp->cntx)) { + cntxp->f = 1; + Lp->pss |= PS_PRI; + Lp->sf |= SELCNTX; + break; } } } @@ -1177,19 +1293,21 @@ static int process_id(struct lsof_context *ctx, /* context */ if (!Fwarn) { (void)snpf(nmabuf, sizeof(nmabuf), "%s (opendir: %s)", dpath, strerror(errno)); - alloc_lfile(ctx, "NOFD", -1); + alloc_lfile(ctx, LSOF_FD_ERROR, -1); nmabuf[sizeof(nmabuf) - 1] = '\0'; (void)add_nma(ctx, nmabuf, strlen(nmabuf)); link_lfile(ctx); } - return (0); + goto cleanup; } dpath[i - 1] = '/'; while ((fp = readdir(fdp))) { if (nm2id(fp->d_name, &fd, &n)) continue; (void)make_proc_path(ctx, dpath, i, &path, &pathl, fp->d_name); - (void)alloc_lfile(ctx, (char *)NULL, fd); + if (!path) + continue; + (void)alloc_lfile(ctx, LSOF_FD_NUMERIC, fd); if (getlinksrc(path, pbuf, sizeof(pbuf), &rest) < 1) { zeromem((char *)&sb, sizeof(sb)); lnk = ss = 0; @@ -1204,7 +1322,8 @@ static int process_id(struct lsof_context *ctx, /* context */ pn = 0; } else { lnk = 1; - if (Efsysl && !isefsys(ctx, pbuf, "UNKNfd", 1, NULL, &lfr)) { + if (Efsysl && + !isefsys(ctx, pbuf, LSOF_FILE_UNKNOWN_FD, 1, NULL, &lfr)) { efs = 1; pn = 0; } else { @@ -1254,7 +1373,7 @@ static int process_id(struct lsof_context *ctx, /* context */ /* Clear fi in case oty == 0 */ fi.eventfd_id = -1; fi.pid = -1; - fi.tfd_count = -1; + fi.tfd_count = 0; if (oty) { int fdinfo_mask = FDINFO_BASE; @@ -1306,7 +1425,7 @@ static int process_id(struct lsof_context *ctx, /* context */ if (pn) { process_proc_node(ctx, lnk ? pbuf : path, path, &sb, ss, &lsb, ls); - if (Lf->ntype == N_ANON_INODE) { + if (Ntype == N_ANON_INODE) { if (rest && *rest) { #if defined(HASEPTOPTS) if (fi.eventfd_id != -1 && @@ -1349,13 +1468,22 @@ static int process_id(struct lsof_context *ctx, /* context */ } } } - (void)closedir(fdp); + +cleanup: + if (fdp) { + (void)closedir(fdp); + } + CLEAN(path); + CLEAN(pathi); + CLEAN(dpath); + CLEAN(ipath); return (0); } /* compare mount namespace of this lsof process and the target process */ -static int compare_mntns(int pid) /* pid of the target process */ +static int compare_mntns(pid) +int pid; /* pid of the target process */ { char nspath[NS_PATH_LENGTH]; struct stat sb_self, sb_target; @@ -1382,8 +1510,8 @@ static int compare_mntns(int pid) /* pid of the target process */ */ static void -process_proc_map(struct lsof_context *ctx, /* context */ - char *p, /* path to process maps file */ +process_proc_map(struct lsof_context *ctx, + char *p, /* path to process maps file */ struct stat *s, /* executing text file state buffer */ int ss) /* *s status -- i.e., SB_* values */ { @@ -1401,17 +1529,18 @@ process_proc_map(struct lsof_context *ctx, /* context */ dev_t dev; INODETYPE inode; }; - static struct saved_map *sm = (struct saved_map *)NULL; + struct saved_map *sm = (struct saved_map *)NULL; + struct saved_map *temp_sm = (struct saved_map *)NULL; efsys_list_t *rep; - static int sma = 0; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + int sma = 0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; int diff_mntns = 0; /* * Open the /proc//maps file, assign a page size buffer to its stream, * and read it/ */ - if (!(ms = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(ms = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; /* target process in a different mount namespace from lsof process. */ @@ -1479,16 +1608,19 @@ process_proc_map(struct lsof_context *ctx, /* context */ sma += 10; len = (MALLOC_S)(sma * sizeof(struct saved_map)); if (sm) - sm = (struct saved_map *)realloc(sm, len); + temp_sm = (struct saved_map *)realloc(sm, len); else - sm = (struct saved_map *)malloc(len); - if (!sm) { - (void)fprintf( - stderr, - "%s: can't allocate %d bytes for saved maps, PID %d\n", Pn, - (int)len, Lp->pid); + temp_sm = (struct saved_map *)malloc(len); + if (!temp_sm) { + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for saved maps, PID %d\n", + Pn, (int)len, Lp->pid); Error(ctx); + goto cleanup; } + sm = temp_sm; } sm[ns].dev = dev; sm[ns++].inode = inode; @@ -1497,8 +1629,8 @@ process_proc_map(struct lsof_context *ctx, /* context */ * for it. Skip the stat(2) operation if this is on an exempt file * system. */ - alloc_lfile(ctx, "mem", -1); - if (Efsysl && !isefsys(ctx, fp[6], (char *)NULL, 0, &rep, NULL)) + alloc_lfile(ctx, LSOF_FD_MEMORY, -1); + if (Efsysl && !isefsys(ctx, fp[6], LSOF_FILE_UNKNOWN, 0, &rep, NULL)) efs = sv = 1; else efs = 0; @@ -1557,7 +1689,7 @@ process_proc_map(struct lsof_context *ctx, /* context */ sb.st_mode = S_IFREG; mss = SB_DEV | SB_INO | SB_MODE; if (ds) - alloc_lfile(ctx, "DEL", -1); + alloc_lfile(ctx, LSOF_FD_DELETED, -1); else if (!efs && !Fwarn) { (void)snpf(nmabuf, sizeof(nmabuf), "(stat: %s)", strerror(en)); nmabuf[sizeof(nmabuf) - 1] = '\0'; @@ -1578,7 +1710,7 @@ process_proc_map(struct lsof_context *ctx, /* context */ * information. */ if (ds) - alloc_lfile(ctx, "DEL", -1); + alloc_lfile(ctx, LSOF_FD_DELETED, -1); else if (!Fwarn) { char *sep; @@ -1593,7 +1725,7 @@ process_proc_map(struct lsof_context *ctx, /* context */ sep = "(path "; if ((INODETYPE)sb.st_ino != inode) { (void)snpf(fmtbuf, sizeof(fmtbuf), "%%sinode=%s)", - InodeFmt_d); + "%" INODEPSPEC "d"); (void)snpf(nmabuf, sizeof(nmabuf), fmtbuf, sep, (INODETYPE)sb.st_ino); nmabuf[sizeof(nmabuf) - 1] = '\0'; @@ -1621,11 +1753,12 @@ process_proc_map(struct lsof_context *ctx, /* context */ * the NAME column. */ Lf->dev = sb.st_dev; + Lf->dev_def = 1; Lf->inode = (ino_t)sb.st_ino; - Lf->dev_def = Lf->inp_ty = 1; + Lf->inode_def = 1; (void)enter_nm(ctx, fp[6]); - (void)snpf(Lf->type, sizeof(Lf->type), "%s", - (ds ? "UNKNdel" : "UNKNmem")); + Lf->type = + (ds ? LSOF_FILE_UNKNOWN_DELETED : LSOF_FILE_UNKNOWN_MEMORY); (void)snpf(nmabuf, sizeof(nmabuf), "(%ce %s)", rep->rdlnk ? '+' : '-', rep->path); nmabuf[sizeof(nmabuf) - 1] = '\0'; @@ -1634,7 +1767,10 @@ process_proc_map(struct lsof_context *ctx, /* context */ if (Lf->sf) link_lfile(ctx); } +cleanup: (void)fclose(ms); + CLEAN(sm); + CLEAN(vbuf); } /* @@ -1643,35 +1779,40 @@ process_proc_map(struct lsof_context *ctx, /* context */ * return: -1 == ID is unavailable * 0 == ID OK * 1 == ID is a zombie - * 2 == ID is a thread + * 2 == ID is a thread */ -static int read_id_stat(struct lsof_context *ctx, /* context */ - char *p, /* path to status file */ - int id, /* ID: PID or LWP */ - char **cmd, /* malloc'd command name */ - int *ppid, /* returned parent PID for PID type */ - int *pgid) /* returned process group ID for PID - * type */ +static int read_id_stat(struct lsof_context *ctx, + char *p, /* path to status file */ + int id, /* ID: PID or LWP */ + char **cmd, /* malloc'd command name, NULL if failure */ + int *ppid, /* returned parent PID for PID type */ + int *pgid) /* returned process group ID for PID + * type */ { + int ret = 0; char buf[MAXPATHLEN], *cp, *cp1, **fp; int ch, cx, es, pc; - static char *cbf = (char *)NULL; - static MALLOC_S cbfa = 0; + char *cbf = (char *)NULL; + char *temp = (char *)NULL; + MALLOC_S cbfa = 0; FILE *fs; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; + + /* NULL means failure to get command name */ + *cmd = NULL; + /* * Open the stat file path, assign a page size buffer to its stream, * and read the file's first line. */ - if (!(fs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) - return (-1); + if (!(fs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) { + ret = -1; + goto cleanup; + } if (!(cp = fgets(buf, sizeof(buf), fs))) { - - read_id_stat_exit: - - (void)fclose(fs); - return (-1); + ret = -1; + goto cleanup; } /* * Skip to the first field, and make sure it is a matching ID. @@ -1681,8 +1822,10 @@ static int read_id_stat(struct lsof_context *ctx, /* context */ cp++; if (*cp) *cp = '\0'; - if (atoi(cp1) != id) - goto read_id_stat_exit; + if (atoi(cp1) != id) { + ret = -1; + goto cleanup; + } /* * The second field should contain the command, enclosed in parentheses. * If it also has embedded '\n' characters, replace them with '?' @@ -1692,18 +1835,13 @@ static int read_id_stat(struct lsof_context *ctx, /* context */ */ for (++cp; *cp && (*cp == ' '); cp++) ; - if (!cp || (*cp != '(')) - goto read_id_stat_exit; + if (!cp || (*cp != '(')) { + ret = -1; + goto cleanup; + } cp++; pc = 1; /* start the parenthesis balance count at 1 */ - /* empty process name to avoid leaking previous process name, - * see issue #246 - */ - if (cbf) { - cbf[0] = '\0'; - } - /* * Enter the command characters safely. Supply them from the initial read * of the stat file line, a '\n' if the initial read didn't yield a ')' @@ -1716,8 +1854,10 @@ static int read_id_stat(struct lsof_context *ctx, /* context */ if (!es) ch = *cp++; else { - if ((ch = fgetc(fs)) == EOF) - goto read_id_stat_exit; + if ((ch = fgetc(fs)) == EOF) { + ret = -1; + goto cleanup; + } } if (ch == '(') /* a '(' advances the balance count */ pc++; @@ -1731,15 +1871,30 @@ static int read_id_stat(struct lsof_context *ctx, /* context */ if (!pc) break; } - if ((cx + 2) > cbfa) - cbfa = alloc_cbf(ctx, (cx + 2), &cbf, cbfa); + if ((cx + 2) > cbfa) { + cbfa = cx + 2; + if (cbf) + temp = (char *)realloc((MALLOC_P *)cbf, cbfa); + else + temp = (char *)malloc(cbfa); + if (!temp) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't allocate command %d bytes\n", Pn, + (int)cbfa); + } + Error(ctx); + ret = -1; + goto cleanup; + } + cbf = temp; + } cbf[cx] = ch; cx++; cbf[cx] = '\0'; if (!es && !*cp) es = 1; /* Switch to fgetc() when a '\0' appears. */ } - *cmd = cbf; /* * Read the remainder of the stat line if it was necessary to read command * characters individually from the stat file. @@ -1748,31 +1903,53 @@ static int read_id_stat(struct lsof_context *ctx, /* context */ */ if (es) cp = fgets(buf, sizeof(buf), fs); - (void)fclose(fs); - if (!cp || !*cp) - return (-1); - if (get_fields(ctx, cp, (char *)NULL, &fp, (int *)NULL, 0) < 3) - return (-1); + if (!cp || !*cp) { + ret = -1; + goto cleanup; + } + if (get_fields(ctx, cp, (char *)NULL, &fp, (int *)NULL, 0) < 3) { + ret = -1; + goto cleanup; + } /* * Convert and return parent process (fourth field) and process group (fifth * field) IDs. */ if (fp[1] && *fp[1]) *ppid = atoi(fp[1]); - else - return (-1); + else { + ret = -1; + goto cleanup; + } if (fp[2] && *fp[2]) *pgid = atoi(fp[2]); - else - return (-1); + else { + ret = -1; + goto cleanup; + } + + /* Pass command name to caller */ + *cmd = cbf; + cbf = NULL; + /* * Check the state in the third field. If it is 'Z', return that * indication. */ - if (fp[0] && !strcmp(fp[0], "Z")) - return (1); - else if (fp[0] && !strcmp(fp[0], "T")) - return (2); + if (fp[0] && !strcmp(fp[0], "Z")) { + ret = 1; + goto cleanup; + } else if (fp[0] && !strcmp(fp[0], "T")) { + ret = 2; + goto cleanup; + } +cleanup: + if (fs) { + (void)fclose(fs); + fs = NULL; + } + CLEAN(vbuf); + CLEAN(cbf); return (0); } @@ -1788,14 +1965,12 @@ static int read_id_stat(struct lsof_context *ctx, /* context */ * This function should be used only when links have been successfully * resolved in the /proc path by getlinksrc(). */ -static int statEx(struct lsof_context *ctx, /* context */ - char *p, /* file path */ - struct stat *s, /* stat() result -- NULL if none - * wanted */ - int *ss) /* stat() status -- SB_* values */ +static int statEx(struct lsof_context *ctx, char *p, /* file path */ + struct stat *s, /* stat() result -- NULL if none + * wanted */ + int *ss) /* stat() status -- SB_* values */ { - static size_t ca = 0; - static char *cb = NULL; + char *cb = NULL; char *cp; int ensv = ENOENT; struct stat sb; @@ -1805,17 +1980,13 @@ static int statEx(struct lsof_context *ctx, /* context */ * Make a copy of the path. */ sz = strlen(p); - if ((sz + 1) > ca) { - if (cb) - cb = (char *)realloc((MALLOC_P *)cb, sz + 1); - else - cb = (char *)malloc(sz + 1); - if (!cb) { - (void)fprintf(stderr, "%s: PID %ld: no statEx path space: %s\n", Pn, - (long)Lp->pid, p); - Error(ctx); - } - ca = sz + 1; + cb = (char *)malloc(sz + 1); + if (!cb) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: PID %ld: no statEx path space: %s\n", + Pn, (long)Lp->pid, p); + Error(ctx); + return (1); } (void)strcpy(cb, p); /* @@ -1839,6 +2010,7 @@ static int statEx(struct lsof_context *ctx, /* context */ * containing only the device and raw device numbers. */ zeromem((char *)s, sizeof(struct stat)); + CLEAN(cb); if (st) { errno = 0; s->st_dev = sb.st_dev; diff --git a/lib/dialects/linux/dproto.h b/lib/dialects/linux/dproto.h index defa7b81..810d889a 100644 --- a/lib/dialects/linux/dproto.h +++ b/lib/dialects/linux/dproto.h @@ -34,10 +34,6 @@ * $Id: dproto.h,v 1.9 2013/01/02 17:02:36 abe Exp $ */ -#if defined(HASSELINUX) -extern int enter_cntx_arg(struct lsof_context *ctx, char *cnxt); -#endif /* defined(HASSELINUX) */ - extern int get_fields(struct lsof_context *ctx, char *ln, char *sep, char ***fr, int *eb, int en); extern void get_locks(struct lsof_context *ctx, char *p); @@ -60,10 +56,9 @@ extern int is_file_named(struct lsof_context *ctx, int ty, char *p, extern int make_proc_path(struct lsof_context *ctx, char *pp, int lp, char **np, int *npl, char *sf); extern FILE *open_proc_stream(struct lsof_context *ctx, char *p, char *mode, - char **buf, size_t *sz, int act); + char **buf, size_t *sz); extern void process_proc_node(struct lsof_context *ctx, char *p, char *pbr, struct stat *s, int ss, struct stat *l, int ls); extern void process_proc_sock(struct lsof_context *ctx, char *p, char *pbr, struct stat *s, int ss, struct stat *l, int ls); -extern void set_net_paths(struct lsof_context *ctx, char *p, int pl); -extern void refresh_socket_info(struct lsof_context *ctx); \ No newline at end of file +extern void refresh_socket_info(struct lsof_context *ctx); diff --git a/lib/dialects/linux/dsock.c b/lib/dialects/linux/dsock.c index c5c84c52..5a83f6e7 100644 --- a/lib/dialects/linux/dsock.c +++ b/lib/dialects/linux/dsock.c @@ -96,137 +96,10 @@ * Local structures */ -struct ax25sin { /* AX25 socket information */ - char *da; /* destination address */ - char *dev_ch; /* device characters */ - char *sa; /* source address */ - INODETYPE inode; - unsigned long sq, rq; /* send and receive queue values */ - unsigned char sqs, rqs; /* send and receive queue states */ - int state; - struct ax25sin *next; -}; - -struct icmpin { - INODETYPE inode; /* node number */ - char *la; /* local address */ - char *ra; /* remote address */ - MALLOC_S lal; /* strlen(la) */ - MALLOC_S ral; /* strlen(ra) */ - struct icmpin *next; -}; - -struct ipxsin { /* IPX socket information */ - INODETYPE inode; - char *la; /* local address */ - char *ra; /* remote address */ - int state; - unsigned long txq, rxq; /* transmit and receive queue values */ - struct ipxsin *next; -}; - -struct nlksin { /* Netlink socket information */ - INODETYPE inode; /* node number */ - unsigned int pr; /* protocol */ - struct nlksin *next; -}; - -struct packin { /* packet information */ - INODETYPE inode; - int ty; /* socket type */ - int pr; /* protocol */ - struct packin *next; -}; - -struct rawsin { /* raw socket information */ - INODETYPE inode; - char *la; /* local address */ - char *ra; /* remote address */ - char *sp; /* state characters */ - MALLOC_S lal; /* strlen(la) */ - MALLOC_S ral; /* strlen(ra) */ - MALLOC_S spl; /* strlen(sp) */ - struct rawsin *next; -}; - -struct sctpsin { /* SCTP socket information */ - INODETYPE inode; - int type; /* type: 0 = assoc - * 1 = eps - * 2 assoc and eps */ - char *addr; /* association or endpoint address */ - char *assocID; /* association ID */ - char *lport; /* local port */ - char *rport; /* remote port */ - char *laddrs; /* local address */ - char *raddrs; /* remote address */ - struct sctpsin *next; -}; - -struct tcp_udp { /* IPv4 TCP and UDP socket - * information */ - INODETYPE inode; - unsigned long faddr, laddr; /* foreign & local IPv4 addresses */ - int fport, lport; /* foreign & local ports */ - unsigned long txq, rxq; /* transmit & receive queue values */ - int proto; /* 0 = TCP, 1 = UDP, 2 = UDPLITE */ - int state; /* protocol state */ - struct tcp_udp *next; /* in TcpUdp inode hash table */ -#if defined(HASEPTOPTS) - pxinfo_t *pxinfo; /* inode information */ - struct tcp_udp *ipc_next; /* in TcpUdp local ipc hash table */ - struct tcp_udp *ipc_peer; /* locally connected peer(s) info */ -#endif /* defined(HASEPTOPTS) */ -}; - -#if defined(HASIPv6) -struct tcp_udp6 { /* IPv6 TCP and UDP socket - * information */ - INODETYPE inode; - struct in6_addr faddr, laddr; /* foreign & local IPv6 addresses */ - int fport, lport; /* foreign & local ports */ - unsigned long txq, rxq; /* transmit & receive queue values */ - int proto; /* 0 = TCP, 1 = UDP, 2 = UDPLITE */ - int state; /* protocol state */ - struct tcp_udp6 *next; -# if defined(HASEPTOPTS) - pxinfo_t *pxinfo; /* inode information */ - struct tcp_udp6 *ipc_next; /* in TcpUdp6 local ipc hash table */ - struct tcp_udp6 *ipc_peer; /* locally connected peer(s) info */ -# endif /* defined(HASEPTOPTS) */ -}; -#endif /* defined(HASIPv6) */ - -typedef struct uxsin { /* UNIX socket information */ - INODETYPE inode; /* node number */ - char *pcb; /* protocol control block */ - char *path; /* file path */ - unsigned char sb_def; /* stat(2) buffer definitions */ - dev_t sb_dev; /* stat(2) buffer device */ - INODETYPE sb_ino; /* stat(2) buffer node number */ - dev_t sb_rdev; /* stat(2) raw device number */ - uint32_t ty; /* socket type */ - unsigned int opt; /* socket options */ - unsigned int ss; /* socket state */ - -#if defined(HASEPTOPTS) && defined(HASUXSOCKEPT) - struct uxsin *icons; /* incoming socket conections */ - unsigned int icstat; /* incoming connection status - * 0 == none */ - pxinfo_t *pxinfo; /* inode information */ - struct uxsin *peer; /* connected peer(s) info */ -#endif /* defined(HASEPTOPTS) && defined(HASUXSOCKEPT) */ - - struct uxsin *next; -} uxsin_t; - /* * Local static values */ -static char *AX25path = (char *)NULL; /* path to AX25 /proc information */ -/* AX25 socket info, hashed by inode */ -static struct ax25sin **AX25sin = (struct ax25sin **)NULL; static char *ax25st[] = { "LISTENING", /* 0 */ "SABM SENT", /* 1 */ @@ -235,85 +108,20 @@ static char *ax25st[] = { "RECOVERY" /* 4 */ }; #define NAX25ST (sizeof(ax25st) / sizeof(char *)) -static char *ICMPpath = (char *)NULL; /* path to ICMP /proc information */ -/* ICMP socket info, hashed by inode */ -static struct icmpin **Icmpin = (struct icmpin **)NULL; -static char *Ipxpath = (char *)NULL; /* path to IPX /proc information */ -/* IPX socket info, hashed by inode */ -static struct ipxsin **Ipxsin = (struct ipxsin **)NULL; -static char *Nlkpath = (char *)NULL; /* path to Netlink /proc information */ -/* Netlink socket info, hashed by - * inode */ -static struct nlksin **Nlksin = (struct nlksin **)NULL; -/* packet info, hashed by inode */ -static struct packin **Packin = (struct packin **)NULL; -static char *Packpath = (char *)NULL; /* path to packet /proc information */ -static char *Rawpath = (char *)NULL; /* path to raw socket /proc - * information */ -/* raw socket info, hashed by inode */ -static struct rawsin **Rawsin = (struct rawsin **)NULL; static char *SCTPPath[] = { /* paths to /proc/net STCP info */ - (char *)NULL, /* 0 = /proc/net/sctp/assocs */ - (char *)NULL /* 1 = /proc/net/sctp/eps */ + PROCFS "/net/sctp/assocs", /* 0 = /proc/net/sctp/assocs */ + PROCFS "/net/sctp/eps" /* 1 = /proc/net/sctp/eps */ }; #define NSCTPPATHS sizeof(SCTPPath) / sizeof(char *) -static char *SCTPSfx[] = { - /* /proc/net suffixes */ - "sctp/assocs", /* 0 = /proc/net/sctp/assocs */ - "sctp/eps" /* 1 = /proc/net/sctp/eps */ -}; -/* SCTP info, hashed by inode */ -static struct sctpsin **SCTPsin = (struct sctpsin **)NULL; /* path to /proc/net socket status */ -static char *SockStatPath = (char *)NULL; -static char *TCPpath = (char *)NULL; /* path to TCP /proc information */ -/* IPv4 TCP & UDP info, hashed by - * inode */ -static struct tcp_udp **TcpUdp = (struct tcp_udp **)NULL; -static int TcpUdp_bucks = 0; /* dynamically sized hash bucket - * count for TCP and UDP -- will - * be a power of two */ -#if defined(HASEPTOPTS) -/* IPv4 TCP & UDP info for socket used - for IPC, hashed by (addr, port paris - and protocol */ -static struct tcp_udp **TcpUdpIPC = (struct tcp_udp **)NULL; -#endif /* defined(HASEPTOPTS) */ +static char *SockStatPath = PROCFS "/net/sockstat"; #if defined(HASIPv6) -static char *Raw6path = (char *)NULL; /* path to raw IPv6 /proc information */ -/* IPv6 raw socket info, hashed by - * inode */ -static struct rawsin **Rawsin6 = (struct rawsin **)NULL; /* path to /proc/net IPv6 socket * status */ -static char *SockStatPath6 = (char *)NULL; -static char *TCP6path = (char *)NULL; /* path to IPv6 TCP /proc information */ -/* IPv6 TCP & UDP info, hashed by - * inode */ -static struct tcp_udp6 **TcpUdp6 = (struct tcp_udp6 **)NULL; -static int TcpUdp6_bucks = 0; /* dynamically sized hash bucket - * count for IPv6 TCP and UDP -- will - * be a power of two */ -static char *UDP6path = (char *)NULL; /* path to IPv6 UDP /proc information */ -/* path to IPv6 UDPLITE /proc - * information */ -static char *UDPLITE6path = (char *)NULL; -# if defined(HASEPTOPTS) -/* IPv4 TCP & UDP info for socket used - for IPC, hashed by (addr, port paris - and protocol */ -static struct tcp_udp6 **TcpUdp6IPC = (struct tcp_udp6 **)NULL; -# endif /* defined(HASEPTOPTS) */ -#endif /* defined(HASIPv6) */ - -static char *UDPpath = (char *)NULL; /* path to UDP /proc information */ -/* path to UDPLITE /proc information */ -static char *UDPLITEpath = (char *)NULL; -static char *UNIXpath = (char *)NULL; /* path to UNIX /proc information */ -/* UNIX socket info, hashed by inode */ -static uxsin_t **Uxsin = (uxsin_t **)NULL; +static char *SockStatPath6 = PROCFS "/net/sockstat6"; +#endif /* defined(HASIPv6) */ /* * Local function prototypes @@ -351,7 +159,7 @@ static struct packin *check_pack(struct lsof_context *ctx, INODETYPE i); static struct rawsin *check_raw(struct lsof_context *ctx, INODETYPE i); static struct sctpsin *check_sctp(struct lsof_context *ctx, INODETYPE i); static struct tcp_udp *check_tcpudp(struct lsof_context *ctx, INODETYPE i, - char **p); + enum lsof_protocol *p); static uxsin_t *check_unix(struct lsof_context *ctx, INODETYPE i); static void get_ax25(struct lsof_context *ctx, char *p); static void get_icmp(struct lsof_context *ctx, char *p); @@ -368,15 +176,12 @@ static void print_ax25info(struct lsof_context *ctx, struct ax25sin *ap); static void print_ipxinfo(struct lsof_context *ctx, struct ipxsin *ip); static char *socket_type_to_str(uint32_t ty, int *rf); static char *netlink_proto_to_str(unsigned int pr); -#if defined(HASSOSTATE) -static char *socket_state_to_str(unsigned int ss); -#endif /* defined(HASSOSTATE) */ -static char *ethernet_proto_to_str(unsigned int pr); +static enum lsof_protocol ethernet_proto_convert(unsigned int pr); #if defined(HASIPv6) static struct rawsin *check_raw6(struct lsof_context *ctx, INODETYPE i); static struct tcp_udp6 *check_tcpudp6(struct lsof_context *ctx, INODETYPE i, - char **p); + enum lsof_protocol *p); static void get_raw6(struct lsof_context *ctx, char *p); static void get_tcpudp6(struct lsof_context *ctx, char *p, int pr, int clr); static int hex_ipv6_to_in6(char *as, struct in6_addr *ad); @@ -401,6 +206,11 @@ void build_IPstates(struct lsof_context *ctx) { (void)enter_IPstate(ctx, "TCP", "CLOSED", 0); (void)enter_IPstate(ctx, "TCP", (char *)NULL, 0); } + /* Linux kernel reuses tcp state for udp sockets */ + if (!UdpSt) { + (void)enter_IPstate(ctx, "UDP", "CLOSE", TCP_CLOSE); + (void)enter_IPstate(ctx, "UDP", (char *)NULL, 0); + } } /* @@ -473,8 +283,8 @@ static struct sctpsin *check_sctp(struct lsof_context *ctx, */ static struct tcp_udp * check_tcpudp(struct lsof_context *ctx, - INODETYPE i, /* socket file's inode number */ - char **p) /* protocol return */ + INODETYPE i, /* socket file's inode number */ + enum lsof_protocol *p) /* protocol return */ { struct tcp_udp *tp; tp = HASH_FIND_ELEMENT(TcpUdp, TCPUDPHASH, struct tcp_udp, inode, i); @@ -482,16 +292,16 @@ check_tcpudp(struct lsof_context *ctx, if (tp) { switch (tp->proto) { case 0: - *p = "TCP"; + *p = LSOF_PROTOCOL_TCP; break; case 1: - *p = "UDP"; + *p = LSOF_PROTOCOL_UDP; break; case 2: - *p = "UDPLITE"; + *p = LSOF_PROTOCOL_UDPLITE; break; default: - *p = "unknown"; + *p = LSOF_PROTOCOL_UNKNOWN; } } return tp; @@ -558,8 +368,8 @@ static struct rawsin *check_raw6(struct lsof_context *ctx, */ static struct tcp_udp6 * check_tcpudp6(struct lsof_context *ctx, - INODETYPE i, /* socket file's inode number */ - char **p) /* protocol return */ + INODETYPE i, /* socket file's inode number */ + enum lsof_protocol *p) /* protocol return */ { struct tcp_udp6 *tp6; tp6 = HASH_FIND_ELEMENT(TcpUdp6, TCPUDP6HASH, struct tcp_udp6, inode, i); @@ -567,16 +377,16 @@ check_tcpudp6(struct lsof_context *ctx, if (tp6) { switch (tp6->proto) { case 0: - *p = "TCP"; + *p = LSOF_PROTOCOL_TCP; break; case 1: - *p = "UDP"; + *p = LSOF_PROTOCOL_UDP; break; case 2: - *p = "UDPLITE"; + *p = LSOF_PROTOCOL_UDPLITE; break; default: - *p = "unknown"; + *p = LSOF_PROTOCOL_UNKNOWN; } } return tp6; @@ -677,6 +487,27 @@ void clear_uxsinfo(struct lsof_context *ctx) { } } +/* + * clean_ax25() - cleanup /proc/net/ax25 info + */ +void clean_ax25(struct lsof_context *ctx) { + struct ax25sin *ap, *np; + int h; + if (AX25sin) { + for (h = 0; h < INOBUCKS; h++) { + for (ap = AX25sin[h]; ap; ap = np) { + np = ap->next; + CLEAN(ap->da); + CLEAN(ap->dev_ch); + CLEAN(ap->sa); + CLEAN(ap); + } + AX25sin[h] = (struct ax25sin *)NULL; + } + CLEAN(AX25sin); + } +} + /* * get_ax25() - get /proc/net/ax25 info */ @@ -685,45 +516,32 @@ static void get_ax25(struct lsof_context *ctx, { struct ax25sin *ap, *np; FILE *as; - char buf[MAXPATHLEN], *da, *dev_ch, *ep, **fp, *sa; + char buf[MAXPATHLEN], *da = NULL, *dev_ch = NULL, *ep, **fp, *sa = NULL; int h; INODETYPE inode; unsigned long rq, sq, state; MALLOC_S len; unsigned char rqs, sqs; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; /* * Do second time cleanup or first time setup. */ - if (AX25sin) { - for (h = 0; h < INOBUCKS; h++) { - for (ap = AX25sin[h]; ap; ap = np) { - np = ap->next; - if (ap->da) - (void)free((FREE_P *)ap->da); - if (ap->dev_ch) - (void)free((FREE_P *)ap->dev_ch); - if (ap->sa) - (void)free((FREE_P *)ap->sa); - (void)free((FREE_P *)ap); - } - AX25sin[h] = (struct ax25sin *)NULL; - } - } else { - AX25sin = (struct ax25sin **)calloc(INOBUCKS, sizeof(struct ax25sin *)); - if (!AX25sin) { - (void)fprintf(stderr, + clean_ax25(ctx); + AX25sin = (struct ax25sin **)calloc(INOBUCKS, sizeof(struct ax25sin *)); + if (!AX25sin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d AX25 hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct ax25sin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/ax25 file, assign a page size buffer to the stream, * and read it. Store AX25 socket info in the AX25sin[] hash buckets. */ - if (!(as = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(as = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf) - 1, as)) { if (get_fields(ctx, buf, (char *)NULL, &fp, (int *)NULL, 0) < 24) @@ -778,11 +596,13 @@ static void get_ax25(struct lsof_context *ctx, da = (char *)NULL; else if ((len = strlen(fp[3]))) { if (!(da = (char *)malloc(len + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d destination AX25 addr bytes: %s\n", - Pn, (int)(len + 1), fp[3]); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d destination AX25 addr " + "bytes: %s\n", + Pn, (int)(len + 1), fp[3]); Error(ctx); + goto cleanup; } (void)snpf(da, len + 1, "%s", fp[3]); } else @@ -794,11 +614,13 @@ static void get_ax25(struct lsof_context *ctx, sa = (char *)NULL; else if ((len = strlen(fp[2]))) { if (!(sa = (char *)malloc(len + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d source AX25 address bytes: %s\n", Pn, - (int)(len + 1), fp[2]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d source AX25 address bytes: %s\n", + Pn, (int)(len + 1), fp[2]); Error(ctx); + goto cleanup; } (void)snpf(sa, len + 1, "%s", fp[2]); } else @@ -810,11 +632,13 @@ static void get_ax25(struct lsof_context *ctx, dev_ch = (char *)NULL; else if ((len = strlen(fp[1]))) { if (!(dev_ch = (char *)malloc(len + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d destination AX25 dev bytes: %s\n", - Pn, (int)(len + 1), fp[1]); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d destination AX25 dev " + "bytes: %s\n", + Pn, (int)(len + 1), fp[1]); Error(ctx); + goto cleanup; } (void)snpf(dev_ch, len + 1, "%s", fp[1]); } else @@ -824,23 +648,34 @@ static void get_ax25(struct lsof_context *ctx, * hash bucket. */ if (!(ap = (struct ax25sin *)malloc(sizeof(struct ax25sin)))) { - (void)fprintf(stderr, - "%s: can't allocate %d byte ax25sin structure\n", Pn, - (int)sizeof(struct ax25sin)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d byte ax25sin structure\n", + Pn, (int)sizeof(struct ax25sin)); Error(ctx); + goto cleanup; } ap->da = da; + da = NULL; ap->dev_ch = dev_ch; + dev_ch = NULL; ap->inode = inode; ap->rq = rq; ap->rqs = rqs; ap->sa = sa; + sa = NULL; ap->sq = sq; ap->sqs = sqs; ap->state = (int)state; HASH_INSERT_ELEMENT(AX25sin, INOHASH, ap, inode); } - (void)fclose(as); +cleanup: + if (as) + (void)fclose(as); + CLEAN(vbuf); + CLEAN(da); + CLEAN(sa); + CLEAN(dev_ch); } #if defined(HASEPTOPTS) && defined(HASUXSOCKEPT) @@ -859,14 +694,18 @@ static void enter_uxsinfo(struct lsof_context *ctx, uxsin_t *up) { lf = pi->lf; lp = &Lproc[pi->lpx]; if (pi->ino == Lf->inode) { - if ((lp->pid == Lp->pid) && !strcmp(lf->fd, Lf->fd)) + if ((lp->pid == Lp->pid) && (lf->fd_type == Lf->fd_type) && + (lf->fd_num == Lf->fd_num)) return; } } if (!(np = (pxinfo_t *)malloc(sizeof(pxinfo_t)))) { - (void)fprintf(stderr, "%s: no space for pipeinfo in uxsinfo, PID %d\n", - Pn, Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no space for pipeinfo in uxsinfo, PID %d\n", Pn, + Lp->pid); Error(ctx); + return; } np->ino = Lf->inode; np->lf = Lf; @@ -979,16 +818,19 @@ static void get_uxpeeri(struct lsof_context *ctx) { * Get a netlink socket. */ if ((ns = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_SOCK_DIAG)) == -1) { - (void)fprintf(stderr, "%s: netlink socket error: %s\n", Pn, - strerror(errno)); - Error(ctx); + if (ctx->err) + (void)fprintf(ctx->err, "%s: netlink socket error: %s\n", Pn, + strerror(errno)); + return; + return; } /* * Request peer information. */ if (get_diagmsg(ns) < 0) { - (void)fprintf(stderr, "%s: netlink peer request error: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: netlink peer request error: %s\n", Pn, + strerror(errno)); goto get_uxpeeri_exit; } /* @@ -1002,9 +844,10 @@ static void get_uxpeeri(struct lsof_context *ctx) { if (hp->nlmsg_type == NLMSG_DONE) goto get_uxpeeri_exit; if (hp->nlmsg_type == NLMSG_ERROR) { - (void)fprintf(stderr, - "%s: netlink UNIX socket msg peer info error\n", - Pn); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: netlink UNIX socket msg peer info error\n", Pn); goto get_uxpeeri_exit; } dm = (struct unix_diag_msg *)NLMSG_DATA(hp); @@ -1044,8 +887,10 @@ static void parse_diag(struct lsof_context *ctx, switch (rp->rta_type) { case UNIX_DIAG_PEER: if (len < 4) { - (void)fprintf(stderr, "%s: unix_diag: msg length (%d) < 4)\n", - Pn, len); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: unix_diag: msg length (%d) < 4)\n", Pn, + len); return; } if ((inoc = *(uint32_t *)RTA_DATA(rp))) { @@ -1076,10 +921,11 @@ static void prt_uxs(struct lsof_context *ctx, uxsin_t *p, /* peer info */ int len; /* string length */ char nma[1024]; /* character buffer */ pxinfo_t *pp; /* previous pipe info of socket */ + char fd[FDLEN]; (void)strcpy(nma, "->INO="); len = (int)strlen(nma); - (void)snpf(&nma[len], sizeof(nma) - len - 1, InodeFmt_d, p->inode); + (void)snpf(&nma[len], sizeof(nma) - len - 1, "%" INODEPSPEC "d", p->inode); (void)add_nma(ctx, nma, strlen(nma)); for (pp = p->pxinfo; pp; pp = pp->next) { @@ -1089,12 +935,9 @@ static void prt_uxs(struct lsof_context *ctx, uxsin_t *p, /* peer info */ */ ep = &Lproc[pp->lpx]; ef = pp->lf; - for (i = 0; i < (FDLEN - 1); i++) { - if (ef->fd[i] != ' ') - break; - } - (void)snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c", ep->pid, CmdLim, - ep->cmd, &ef->fd[i], access_to_char(ef->access)); + print_fd(ef->fd_type, ef->fd_num, fd); + (void)snpf(nma, sizeof(nma) - 1, "%d,%s,%s%c", ep->pid, ep->cmd, fd, + print_access(ef->access)); (void)add_nma(ctx, nma, strlen(nma)); if (mk && FeptE == 2) { @@ -1125,7 +968,7 @@ void process_uxsinfo(struct lsof_context *ctx, if (!FeptE) return; for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (strcmp(Lf->type, "unix")) + if (Lf->type != LSOF_FILE_UNIX) continue; switch (f) { case 0: @@ -1133,7 +976,7 @@ void process_uxsinfo(struct lsof_context *ctx, /* * Process already selected socket. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than its @@ -1162,7 +1005,7 @@ void process_uxsinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_UXS)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_UXS)) { /* * This is an unselected end point UNIX socket file. Select it @@ -1215,14 +1058,18 @@ static void enter_netsinfo_common(struct lsof_context *ctx, void *tp, lf = pi->lf; lp = &Lproc[pi->lpx]; if (pi->ino == Lf->inode) { - if ((lp->pid == Lp->pid) && !strcmp(lf->fd, Lf->fd)) + if ((lp->pid == Lp->pid) && (lf->fd_type == Lf->fd_type) && + (lf->fd_num == Lf->fd_num)) return; } } if (!(np = (pxinfo_t *)malloc(sizeof(pxinfo_t)))) { - (void)fprintf(stderr, "%s: no space for pipeinfo in netsinfo, PID %d\n", - Pn, Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no space for pipeinfo in netsinfo, PID %d\n", Pn, + Lp->pid); Error(ctx); + return; } np->ino = Lf->inode; np->lf = Lf; @@ -1244,6 +1091,7 @@ static void prt_nets_common(struct lsof_context *ctx, void *p, /* peer info */ int i; /* temporary index */ char nma[1024]; /* character buffer */ pxinfo_t *pp; /* previous pipe info of socket */ + char fd[FDLEN]; for (pp = (*get_pxinfo)(p); pp; pp = pp->next) { @@ -1253,12 +1101,9 @@ static void prt_nets_common(struct lsof_context *ctx, void *p, /* peer info */ */ ep = &Lproc[pp->lpx]; ef = pp->lf; - for (i = 0; i < (FDLEN - 1); i++) { - if (ef->fd[i] != ' ') - break; - } - (void)snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c", ep->pid, CmdLim, - ep->cmd, &ef->fd[i], access_to_char(ef->access)); + print_fd(ef->fd_type, ef->fd_num, fd); + (void)snpf(nma, sizeof(nma) - 1, "%d,%s,%s%c", ep->pid, ep->cmd, fd, + print_access(ef->access)); (void)add_nma(ctx, nma, strlen(nma)); if (mk && FeptE == 2) { @@ -1293,7 +1138,7 @@ static void enter_netsinfo(struct lsof_context *ctx, struct tcp_udp *tp) { /* * find_netsepti(lf) -- find locally used INET socket endpoint info */ -static struct tcp_udp *find_netsepti(struct lsof_context *ctx, /* context */ +static struct tcp_udp *find_netsepti(struct lsof_context *ctx, struct lfile *lf) /* socket's lfile */ { struct tcp_udp *tp; @@ -1331,9 +1176,9 @@ static void get_netpeeri(struct lsof_context *ctx) { /* * prt_nets() -- print locally used INET socket information */ -static void prt_nets(struct lsof_context *ctx, /* context */ - struct tcp_udp *p, /* peer info */ - int mk) /* 1 == mark for later processing */ +static void prt_nets(struct lsof_context *ctx, + struct tcp_udp *p, /* peer info */ + int mk) /* 1 == mark for later processing */ { prt_nets_common(ctx, p, mk, tcp_udp_get_pxinfo, CHEND_NETS, EPT_NETS_END); } @@ -1343,11 +1188,11 @@ static void prt_nets(struct lsof_context *ctx, /* context */ * it to selected INET socket files and selecting INET * socket end point files (if requested) */ -void process_netsinfo(struct lsof_context *ctx, /* context */ - int f) /* function: - * 0 == process selected socket - * 1 == process socket end point - */ +void process_netsinfo(struct lsof_context *ctx, + int f) /* function: + * 0 == process selected socket + * 1 == process socket end point + */ { struct tcp_udp *p; /* peer INET socket info pointer */ @@ -1355,11 +1200,11 @@ void process_netsinfo(struct lsof_context *ctx, /* context */ return; for (Lf = Lp->file; Lf; Lf = Lf->next) { # if defined(HASIPv6) - char *type = "IPv4"; + enum lsof_file_type type = LSOF_FILE_IPV4; # else /* !defined(HASIPv6) */ - char *type = "inet"; + enum lsof_file_type type = LSOF_FILE_INET; # endif /* defined(HASIPv6) */ - if (strcmp(Lf->type, type)) + if (Lf->type != type) continue; switch (f) { case 0: @@ -1367,7 +1212,7 @@ void process_netsinfo(struct lsof_context *ctx, /* context */ /* * Process already selected socket. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than its @@ -1379,7 +1224,7 @@ void process_netsinfo(struct lsof_context *ctx, /* context */ } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_NETS)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_NETS)) { /* * This is an unselected end point INET socket file. Select it @@ -1421,7 +1266,7 @@ static void enter_nets6info(struct lsof_context *ctx, struct tcp_udp6 *tp) { /* * find_nets6epti(lf) -- find locally used INET6 socket endpoint info */ -static struct tcp_udp6 *find_nets6epti(struct lsof_context *ctx, /* context */ +static struct tcp_udp6 *find_nets6epti(struct lsof_context *ctx, struct lfile *lf) /* socket's lfile */ { struct tcp_udp6 *tp; @@ -1460,9 +1305,9 @@ static void get_net6peeri(struct lsof_context *ctx) { /* * prt_nets6() -- print locally used INET6 socket information */ -static void prt_nets6(struct lsof_context *ctx, /* context */ - struct tcp_udp6 *p, /* peer info */ - int mk) /* 1 == mark for later processing */ +static void prt_nets6(struct lsof_context *ctx, + struct tcp_udp6 *p, /* peer info */ + int mk) /* 1 == mark for later processing */ { prt_nets_common(ctx, p, mk, tcp_udp6_get_pxinfo, CHEND_NETS6, EPT_NETS6_END); @@ -1473,18 +1318,18 @@ static void prt_nets6(struct lsof_context *ctx, /* context */ * it to selected INET6 socket files and selecting INET6 * socket end point files (if requested) */ -void process_nets6info(struct lsof_context *ctx, /* context */ - int f) /* function: - * 0 == process selected socket - * 1 == process socket end point - */ +void process_nets6info(struct lsof_context *ctx, + int f) /* function: + * 0 == process selected socket + * 1 == process socket end point + */ { struct tcp_udp6 *p; /* peer INET6 socket info pointer */ if (!FeptE) return; for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (strcmp(Lf->type, "IPv6")) + if (Lf->type != LSOF_FILE_IPV6) continue; switch (f) { case 0: @@ -1492,7 +1337,7 @@ void process_nets6info(struct lsof_context *ctx, /* context */ /* * Process already selected socket. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than its * being a socket. Look up the socket's endpoints. @@ -1503,7 +1348,7 @@ void process_nets6info(struct lsof_context *ctx, /* context */ } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_NETS6)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_NETS6)) { /* * This is an unselected end point INET6 socket file. Select it @@ -1523,46 +1368,59 @@ void process_nets6info(struct lsof_context *ctx, /* context */ # endif /* defined(HASEPTOPTS) */ #endif /* defined(HASIPv6) */ +/* + * clean_icmp() - cleanup ICMP net info + */ +void clean_icmp(struct lsof_context *ctx) { + struct icmpin *np, *icmpp; + int h; + if (Icmpin) { + for (h = 0; h < INOBUCKS; h++) { + for (icmpp = Icmpin[h]; icmpp; icmpp = np) { + np = icmpp->next; + CLEAN(icmpp->la); + CLEAN(icmpp->ra); + CLEAN(icmpp); + } + Icmpin[h] = (struct icmpin *)NULL; + } + CLEAN(Icmpin); + } +} + /* * get_icmp() - get ICMP net info */ -static void get_icmp(struct lsof_context *ctx, /* context */ - char *p) /* /proc/net/icmp path */ +static void get_icmp(struct lsof_context *ctx, + char *p) /* /proc/net/icmp path */ { - char buf[MAXPATHLEN], *ep, **fp, *la, *ra; + char buf[MAXPATHLEN], *ep, **fp, *la = NULL, *ra = NULL; int fl = 1; int h; INODETYPE inode; struct icmpin *np, *icmpp; MALLOC_S lal, ral; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; FILE *xs; /* * Do second time cleanup or first time setup. */ - if (Icmpin) { - for (h = 0; h < INOBUCKS; h++) { - for (icmpp = Icmpin[h]; icmpp; icmpp = np) { - np = icmpp->next; - (void)free((FREE_P *)icmpp); - } - Icmpin[h] = (struct icmpin *)NULL; - } - } else { - Icmpin = (struct icmpin **)calloc(INOBUCKS, sizeof(struct icmpin *)); - if (!Icmpin) { - (void)fprintf(stderr, + clean_icmp(ctx); + Icmpin = (struct icmpin **)calloc(INOBUCKS, sizeof(struct icmpin *)); + if (!Icmpin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d icmp hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct icmpin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/icmp file, assign a page size buffer to its stream, * and read the file. Store icmp info in the Icmpin[] hash buckets. */ - if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf) - 1, xs)) { if (get_fields(ctx, buf, (char *)NULL, &fp, (int *)NULL, 0) < 11) @@ -1583,9 +1441,10 @@ static void get_icmp(struct lsof_context *ctx, /* context */ if (!fp[1] || strcmp(fp[1], "local_address") || !fp[2] || strcmp(fp[2], "rem_address") || !fp[11] || strcmp(fp[11], "inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -1611,11 +1470,13 @@ static void get_icmp(struct lsof_context *ctx, /* context */ lal = (MALLOC_S)0; } else { if (!(la = (char *)malloc(lal + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d local icmp address bytes: %s\n", Pn, - (int)(lal + 1), fp[1]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d local icmp address bytes: %s\n", + Pn, (int)(lal + 1), fp[1]); Error(ctx); + goto cleanup; } (void)snpf(la, lal + 1, "%s", fp[1]); } @@ -1624,11 +1485,13 @@ static void get_icmp(struct lsof_context *ctx, /* context */ ral = (MALLOC_S)0; } else { if (!(ra = (char *)malloc(ral + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d remote icmp address bytes: %s\n", Pn, - (int)(ral + 1), fp[2]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d remote icmp address bytes: %s\n", + Pn, (int)(ral + 1), fp[2]); Error(ctx); + goto cleanup; } (void)snpf(ra, ral + 1, "%s", fp[2]); } @@ -1637,65 +1500,82 @@ static void get_icmp(struct lsof_context *ctx, /* context */ * hash bucket. */ if (!(icmpp = (struct icmpin *)malloc(sizeof(struct icmpin)))) { - (void)fprintf(stderr, "%s: can't allocate %d byte icmp structure\n", - Pn, (int)sizeof(struct icmpin)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d byte icmp structure\n", Pn, + (int)sizeof(struct icmpin)); Error(ctx); + goto cleanup; } icmpp->inode = inode; icmpp->la = la; + la = NULL; icmpp->lal = lal; icmpp->ra = ra; + ra = NULL; icmpp->ral = ral; HASH_INSERT_ELEMENT(Icmpin, INOHASH, icmpp, inode); } +cleanup: (void)fclose(xs); + CLEAN(vbuf); + CLEAN(ra); + CLEAN(la); +} + +/* + * clean_ipx() - cleanup IPX net info + */ +void clean_ipx(struct lsof_context *ctx) { + struct ipxsin *ip, *np; + int h; + if (Ipxsin) { + for (h = 0; h < INOBUCKS; h++) { + for (ip = Ipxsin[h]; ip; ip = np) { + np = ip->next; + CLEAN(ip->la); + CLEAN(ip->ra); + CLEAN(ip); + } + Ipxsin[h] = (struct ipxsin *)NULL; + } + CLEAN(Ipxsin); + } } /* * get_ipx() - get /proc/net/ipx info */ -static void get_ipx(struct lsof_context *ctx, /* context */ - char *p) /* /proc/net/ipx path */ +static void get_ipx(struct lsof_context *ctx, char *p) /* /proc/net/ipx path */ { - char buf[MAXPATHLEN], *ep, **fp, *la, *ra; + char buf[MAXPATHLEN], *ep, **fp, *la = NULL, *ra = NULL; int fl = 1; int h; INODETYPE inode; unsigned long rxq, state, txq; struct ipxsin *ip, *np; MALLOC_S len; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; FILE *xs; /* * Do second time cleanup or first time setup. */ - if (Ipxsin) { - for (h = 0; h < INOBUCKS; h++) { - for (ip = Ipxsin[h]; ip; ip = np) { - np = ip->next; - if (ip->la) - (void)free((FREE_P *)ip->la); - if (ip->ra) - (void)free((FREE_P *)ip->ra); - (void)free((FREE_P *)ip); - } - Ipxsin[h] = (struct ipxsin *)NULL; - } - } else { - Ipxsin = (struct ipxsin **)calloc(INOBUCKS, sizeof(struct ipxsin *)); - if (!Ipxsin) { - (void)fprintf(stderr, + clean_ipx(ctx); + Ipxsin = (struct ipxsin **)calloc(INOBUCKS, sizeof(struct ipxsin *)); + if (!Ipxsin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d IPX hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct ipxsin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/ipx file, assign a page size buffer to the stream, * and read it. Store IPX socket info in the Ipxsin[] hash buckets. */ - if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf) - 1, xs)) { if (get_fields(ctx, buf, (char *)NULL, &fp, (int *)NULL, 0) < 7) @@ -1711,9 +1591,10 @@ static void get_ipx(struct lsof_context *ctx, /* context */ strcmp(fp[3], "Rx_Queue") || !fp[4] || strcmp(fp[4], "State") || !fp[5] || strcmp(fp[5], "Uid") || !fp[6] || strcmp(fp[6], "Inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -1753,11 +1634,13 @@ static void get_ipx(struct lsof_context *ctx, /* context */ la = (char *)NULL; else if ((len = strlen(fp[0]))) { if (!(la = (char *)malloc(len + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d local IPX address bytes: %s\n", Pn, - (int)(len + 1), fp[0]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d local IPX address bytes: %s\n", + Pn, (int)(len + 1), fp[0]); Error(ctx); + goto cleanup; } (void)snpf(la, len + 1, "%s", fp[0]); } else @@ -1769,11 +1652,13 @@ static void get_ipx(struct lsof_context *ctx, /* context */ ra = (char *)NULL; else if ((len = strlen(fp[1]))) { if (!(ra = (char *)malloc(len + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d remote IPX address bytes: %s\n", Pn, - (int)(len + 1), fp[1]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d remote IPX address bytes: %s\n", + Pn, (int)(len + 1), fp[1]); Error(ctx); + goto cleanup; } (void)snpf(ra, len + 1, "%s", fp[1]); } else @@ -1783,61 +1668,80 @@ static void get_ipx(struct lsof_context *ctx, /* context */ * hash bucket. */ if (!(ip = (struct ipxsin *)malloc(sizeof(struct ipxsin)))) { - (void)fprintf(stderr, - "%s: can't allocate %d byte ipxsin structure\n", Pn, - (int)sizeof(struct ipxsin)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d byte ipxsin structure\n", + Pn, (int)sizeof(struct ipxsin)); Error(ctx); + goto cleanup; } ip->inode = inode; ip->la = la; + la = NULL; ip->ra = ra; + ra = NULL; ip->txq = txq; ip->rxq = rxq; ip->state = (int)state; HASH_INSERT_ELEMENT(Ipxsin, INOHASH, ip, inode); } +cleanup: (void)fclose(xs); + CLEAN(vbuf); + CLEAN(la); + CLEAN(ra); +} + +/* + * clean_netlink() - cleanup netlink net info + */ +void clean_netlink(struct lsof_context *ctx) { + struct nlksin *np, *lp; + int h; + if (Nlksin) { + for (h = 0; h < INOBUCKS; h++) { + for (lp = Nlksin[h]; lp; lp = np) { + np = lp->next; + CLEAN(lp); + } + Nlksin[h] = (struct nlksin *)NULL; + } + CLEAN(Nlksin); + } } /* * get_netlink() - get /proc/net/netlink info */ -static void get_netlink(struct lsof_context *ctx, /* context */ - char *p) /* /proc/net/netlink path */ +static void get_netlink(struct lsof_context *ctx, + char *p) /* /proc/net/netlink path */ { char buf[MAXPATHLEN], *ep, **fp; int fr = 1; int h, pr; INODETYPE inode; struct nlksin *np, *lp; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; FILE *xs; /* * Do second time cleanup or first time setup. */ - if (Nlksin) { - for (h = 0; h < INOBUCKS; h++) { - for (lp = Nlksin[h]; lp; lp = np) { - np = lp->next; - (void)free((FREE_P *)lp); - } - Nlksin[h] = (struct nlksin *)NULL; - } - } else { - Nlksin = (struct nlksin **)calloc(INOBUCKS, sizeof(struct nlksin *)); - if (!Nlksin) { - (void)fprintf(stderr, + clean_netlink(ctx); + Nlksin = (struct nlksin **)calloc(INOBUCKS, sizeof(struct nlksin *)); + if (!Nlksin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d netlink hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct nlksin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/netlink file, assign a page size buffer to its stream, * and read the file. Store Netlink info in the Nlksin[] hash buckets. */ - if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf) - 1, xs)) { if (get_fields(ctx, buf, (char *)NULL, &fp, (int *)NULL, 0) < 10) @@ -1849,9 +1753,10 @@ static void get_netlink(struct lsof_context *ctx, /* context */ */ if (!fp[1] || strcmp(fp[1], "Eth") || !fp[9] || strcmp(fp[9], "Inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -1880,23 +1785,44 @@ static void get_netlink(struct lsof_context *ctx, /* context */ * hash bucket. */ if (!(lp = (struct nlksin *)malloc(sizeof(struct nlksin)))) { - (void)fprintf(stderr, - "%s: can't allocate %d byte Netlink structure\n", Pn, - (int)sizeof(struct nlksin)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d byte Netlink structure\n", + Pn, (int)sizeof(struct nlksin)); Error(ctx); + goto cleanup; } lp->inode = inode; lp->pr = pr; HASH_INSERT_ELEMENT(Nlksin, INOHASH, lp, inode); } +cleanup: (void)fclose(xs); + CLEAN(vbuf); +} + +/* + * clean_pack() - cleanup packet net info + */ +void clean_pack(struct lsof_context *ctx) { + struct packin *np, *pp; + int h; + if (Packin) { + for (h = 0; h < INOBUCKS; h++) { + for (pp = Packin[h]; pp; pp = np) { + np = pp->next; + (void)free((FREE_P *)pp); + } + Packin[h] = (struct packin *)NULL; + } + CLEAN(Packin); + } } /* * get_pack() - get /proc/net/packet info */ -static void get_pack(struct lsof_context *ctx, /* context */ - char *p) /* /proc/net/raw path */ +static void get_pack(struct lsof_context *ctx, char *p) /* /proc/net/raw path */ { char buf[MAXPATHLEN], *ep, **fp; int fl = 1; @@ -1904,34 +1830,27 @@ static void get_pack(struct lsof_context *ctx, /* context */ INODETYPE inode; struct packin *np, *pp; unsigned long pr; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; FILE *xs; /* * Do second time cleanup or first time setup. */ - if (Packin) { - for (h = 0; h < INOBUCKS; h++) { - for (pp = Packin[h]; pp; pp = np) { - np = pp->next; - (void)free((FREE_P *)pp); - } - Packin[h] = (struct packin *)NULL; - } - } else { - Packin = (struct packin **)calloc(INOBUCKS, sizeof(struct packin *)); - if (!Packin) { - (void)fprintf(stderr, + clean_pack(ctx); + Packin = (struct packin **)calloc(INOBUCKS, sizeof(struct packin *)); + if (!Packin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d packet hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct packin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/packet file, assign a page size buffer to its stream, * and read the file. Store packet info in the Packin[] hash buckets. */ - if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf) - 1, xs)) { if (get_fields(ctx, buf, (char *)NULL, &fp, (int *)NULL, 0) < 9) @@ -1943,9 +1862,10 @@ static void get_pack(struct lsof_context *ctx, /* context */ */ if (!fp[2] || strcmp(fp[2], "Type") || !fp[3] || strcmp(fp[3], "Proto") || !fp[8] || strcmp(fp[8], "Inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -1978,63 +1898,75 @@ static void get_pack(struct lsof_context *ctx, /* context */ * hash bucket. */ if (!(pp = (struct packin *)malloc(sizeof(struct packin)))) { - (void)fprintf(stderr, - "%s: can't allocate %d byte packet structure\n", Pn, - (int)sizeof(struct packin)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d byte packet structure\n", + Pn, (int)sizeof(struct packin)); Error(ctx); + goto cleanup; } pp->inode = inode; pp->pr = (int)pr; pp->ty = ty; HASH_INSERT_ELEMENT(Packin, INOHASH, pp, inode); } +cleanup: (void)fclose(xs); + CLEAN(vbuf); +} + +/* + * clean_raw() - cleanup raw net info + */ +void clean_raw(struct lsof_context *ctx) { + struct rawsin *np, *rp; + int h; + if (Rawsin) { + for (h = 0; h < INOBUCKS; h++) { + for (rp = Rawsin[h]; rp; rp = np) { + np = rp->next; + CLEAN(rp->la); + CLEAN(rp->ra); + (void)free((FREE_P *)rp); + } + Rawsin[h] = (struct rawsin *)NULL; + } + CLEAN(Rawsin); + } } /* * get_raw() - get /proc/net/raw info */ -static void get_raw(struct lsof_context *ctx, /* context */ - char *p) /* /proc/net/raw path */ +static void get_raw(struct lsof_context *ctx, char *p) /* /proc/net/raw path */ { - char buf[MAXPATHLEN], *ep, **fp, *la, *ra, *sp; + char buf[MAXPATHLEN], *ep, **fp, *la = NULL, *ra = NULL, *sp = NULL; int h; INODETYPE inode; int nf = 12; struct rawsin *np, *rp; MALLOC_S lal, ral, spl; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; FILE *xs; /* * Do second time cleanup or first time setup. */ - if (Rawsin) { - for (h = 0; h < INOBUCKS; h++) { - for (rp = Rawsin[h]; rp; rp = np) { - np = rp->next; - if (rp->la) - (void)free((FREE_P *)rp->la); - if (rp->ra) - (void)free((FREE_P *)rp->ra); - (void)free((FREE_P *)rp); - } - Rawsin[h] = (struct rawsin *)NULL; - } - } else { - Rawsin = (struct rawsin **)calloc(INOBUCKS, sizeof(struct rawsin *)); - if (!Rawsin) { - (void)fprintf(stderr, + clean_raw(ctx); + Rawsin = (struct rawsin **)calloc(INOBUCKS, sizeof(struct rawsin *)); + if (!Rawsin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d raw hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct rawsin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/raw file, assign a page size buffer to its stream, * and read the file. Store raw socket info in the Rawsin[] hash buckets. */ - if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf) - 1, xs)) { if (get_fields(ctx, buf, (char *)NULL, &fp, (int *)NULL, 0) < nf) @@ -2047,9 +1979,10 @@ static void get_raw(struct lsof_context *ctx, /* context */ if (!fp[1] || strcmp(fp[1], "local_address") || !fp[2] || strcmp(fp[2], "rem_address") || !fp[3] || strcmp(fp[3], "st") || !fp[11] || strcmp(fp[11], "inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -2075,11 +2008,13 @@ static void get_raw(struct lsof_context *ctx, /* context */ lal = (MALLOC_S)0; } else { if (!(la = (char *)malloc(lal + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d local raw address bytes: %s\n", Pn, - (int)(lal + 1), fp[1]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d local raw address bytes: %s\n", + Pn, (int)(lal + 1), fp[1]); Error(ctx); + goto cleanup; } (void)snpf(la, lal + 1, "%s", fp[1]); } @@ -2088,11 +2023,13 @@ static void get_raw(struct lsof_context *ctx, /* context */ ral = (MALLOC_S)0; } else { if (!(ra = (char *)malloc(ral + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d remote raw address bytes: %s\n", Pn, - (int)(ral + 1), fp[2]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d remote raw address bytes: %s\n", + Pn, (int)(ral + 1), fp[2]); Error(ctx); + goto cleanup; } (void)snpf(ra, ral + 1, "%s", fp[2]); } @@ -2101,11 +2038,13 @@ static void get_raw(struct lsof_context *ctx, /* context */ spl = (MALLOC_S)0; } else { if (!(sp = (char *)malloc(spl + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d remote raw state bytes: %s\n", Pn, - (int)(spl + 1), fp[2]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d remote raw state bytes: %s\n", + Pn, (int)(spl + 1), fp[2]); Error(ctx); + goto cleanup; } (void)snpf(sp, spl + 1, "%s", fp[3]); } @@ -2114,73 +2053,89 @@ static void get_raw(struct lsof_context *ctx, /* context */ * hash bucket. */ if (!(rp = (struct rawsin *)malloc(sizeof(struct rawsin)))) { - (void)fprintf(stderr, - "%s: can't allocate %d byte rawsin structure\n", Pn, - (int)sizeof(struct rawsin)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d byte rawsin structure\n", + Pn, (int)sizeof(struct rawsin)); Error(ctx); + goto cleanup; } rp->inode = inode; rp->la = la; + la = NULL; rp->lal = lal; rp->ra = ra; + ra = NULL; rp->ral = ral; rp->sp = sp; + sp = NULL; rp->spl = spl; HASH_INSERT_ELEMENT(Rawsin, INOHASH, rp, inode); } +cleanup: (void)fclose(xs); + CLEAN(vbuf); + CLEAN(la); + CLEAN(ra); + CLEAN(sp); +} + +/* + * clean_sctp() - cleanup sctp net info + */ +void clean_sctp(struct lsof_context *ctx) { + struct sctpsin *sp, *np; + int h; + if (SCTPsin) { + for (h = 0; h < INOBUCKS; h++) { + for (sp = SCTPsin[h]; sp; sp = np) { + np = sp->next; + CLEAN(sp->addr); + CLEAN(sp->assocID); + CLEAN(sp->lport); + CLEAN(sp->rport); + CLEAN(sp->laddrs); + CLEAN(sp->raddrs); + (void)free((FREE_P *)sp); + } + SCTPsin[h] = (struct sctpsin *)NULL; + } + CLEAN(SCTPsin); + } } /* * get_sctp() - get /proc/net/sctp/assocs info */ static void get_sctp(struct lsof_context *ctx) { - char buf[MAXPATHLEN], *a, *ep, **fp, *id, *la, *lp, *ra, *rp, *ta; + char buf[MAXPATHLEN], *a = NULL, *ep, **fp, *id = NULL, *la = NULL, + *lp = NULL, *ra = NULL, *rp = NULL, *ta = NULL; int d, err, fl, h, i, j, nf, ty, x; INODETYPE inode; MALLOC_S len, plen; struct sctpsin *sp, *np; FILE *ss; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; /* * Do second time cleanup or first time setup. */ - if (SCTPsin) { - for (h = 0; h < INOBUCKS; h++) { - for (sp = SCTPsin[h]; sp; sp = np) { - np = sp->next; - if (sp->addr) - (void)free((FREE_P *)sp->addr); - if (sp->assocID) - (void)free((FREE_P *)sp->assocID); - if (sp->lport) - (void)free((FREE_P *)sp->lport); - if (sp->rport) - (void)free((FREE_P *)sp->rport); - if (sp->laddrs) - (void)free((FREE_P *)sp->laddrs); - if (sp->raddrs) - (void)free((FREE_P *)sp->raddrs); - (void)free((FREE_P *)sp); - } - SCTPsin[h] = (struct sctpsin *)NULL; - } - } else { - SCTPsin = (struct sctpsin **)calloc(INOBUCKS, sizeof(struct sctpsin *)); - if (!SCTPsin) { - (void)fprintf(stderr, + clean_sctp(ctx); + SCTPsin = (struct sctpsin **)calloc(INOBUCKS, sizeof(struct sctpsin *)); + if (!SCTPsin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d SCTP hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct sctpsin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/sctp files, assign a page size buffer to the streams, * and read them. Store SCTP socket info in the SCTPsin[] hash buckets. */ for (i = 0; i < NSCTPPATHS; i++) { - if (!(ss = open_proc_stream(ctx, SCTPPath[i], "r", &vbuf, &vsz, 0))) + if (!(ss = open_proc_stream(ctx, SCTPPath[i], "r", &vbuf, &vsz))) continue; fl = 1; while (fgets(buf, sizeof(buf) - 1, ss)) { @@ -2216,8 +2171,8 @@ static void get_sctp(struct lsof_context *ctx) { } } if (err) { - if (!Fwarn) - (void)fprintf(stderr, + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, "%s: WARNING: unsupported format: %s\n", Pn, SCTPPath[i]); break; @@ -2248,12 +2203,12 @@ static void get_sctp(struct lsof_context *ctx) { * * The association or endpoint address is in the first field. */ - a = sp ? sp->addr : (char *)NULL; + a = NULL; if (fp[0] && *fp[0] && (len = strlen(fp[0]))) { - if (a) { - if (isainb(fp[0], a)) { - plen = strlen(a); - a = (char *)realloc((MALLOC_P *)a, plen + len + 2); + if (sp && sp->addr) { + if (isainb(fp[0], sp->addr)) { + plen = strlen(sp->addr); + a = (char *)malloc(plen + len + 2); d = 0; } else d = 1; @@ -2262,15 +2217,18 @@ static void get_sctp(struct lsof_context *ctx) { a = (char *)malloc(len + 1); d = 0; } - if (!a) { - (void)fprintf( - stderr, "%s: can't allocate %d SCTP ASSOC bytes: %s\n", - Pn, (int)(len + 1), fp[0]); - Error(ctx); - } if (!d) { + if (!a) { + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d SCTP ASSOC bytes: %s\n", + Pn, (int)(len + 1), fp[0]); + Error(ctx); + goto cleanup; + } if (plen) - (void)snpf((a + plen), len + 2, ",%s", fp[0]); + (void)snpf(a, plen + len + 2, "%s,%s", sp->addr, fp[0]); else (void)snpf(a, len + 1, "%s", fp[0]); } @@ -2278,12 +2236,12 @@ static void get_sctp(struct lsof_context *ctx) { /* * The association ID is in the seventh field. */ - id = sp ? sp->assocID : (char *)NULL; + id = NULL; if (!i && fp[6] && *fp[6] && (len = strlen(fp[6]))) { - if (id) { - if (isainb(fp[6], id)) { - plen = strlen(id); - id = (char *)realloc((MALLOC_P *)id, plen + len + 2); + if (sp && sp->assocID) { + if (isainb(fp[6], sp->assocID)) { + plen = strlen(sp->assocID); + id = (char *)malloc(plen + len + 2); d = 0; } else d = 1; @@ -2292,16 +2250,19 @@ static void get_sctp(struct lsof_context *ctx) { id = (char *)malloc(len + 1); d = 0; } - if (!id) { - (void)fprintf( - stderr, - "%s: can't allocate %d SCTP ASSOC-ID bytes: %s\n", Pn, - (int)(len + 1), fp[6]); - Error(ctx); - } if (!d) { + if (!id) { + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d SCTP ASSOC-ID " + "bytes: %s\n", + Pn, (int)(len + 1), fp[6]); + Error(ctx); + goto cleanup; + } if (plen) - (void)snpf((id + plen), len + 2, ",%s", fp[6]); + (void)snpf(id, plen + len + 2, "%s,%s", sp->assocID, + fp[6]); else (void)snpf(id, len + 1, "%s", fp[6]); } @@ -2310,12 +2271,12 @@ static void get_sctp(struct lsof_context *ctx) { * The field number for the local port depends on the entry type. */ j = i ? 5 : 11; - lp = sp ? sp->lport : (char *)NULL; + lp = NULL; if (fp[j] && *fp[j] && (len = strlen(fp[j]))) { - if (lp) { - if (isainb(fp[j], lp)) { - plen = strlen(lp); - lp = (char *)realloc((MALLOC_P *)lp, plen + len + 2); + if (sp && sp->lport) { + if (isainb(fp[j], sp->lport)) { + plen = strlen(sp->lport); + lp = (char *)malloc(plen + len + 2); d = 0; } else d = 1; @@ -2324,15 +2285,19 @@ static void get_sctp(struct lsof_context *ctx) { lp = (char *)malloc(len + 1); d = 0; } - if (!lp) { - (void)fprintf( - stderr, "%s: can't allocate %d SCTP LPORT bytes: %s\n", - Pn, (int)(len + 1), fp[j]); - Error(ctx); - } if (!d) { + if (!lp) { + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d SCTP LPORT bytes: %s\n", + Pn, (int)(len + 1), fp[j]); + Error(ctx); + goto cleanup; + } if (plen) - (void)snpf((lp + plen), len + 2, ",%s", fp[j]); + (void)snpf(lp, plen + len + 2, "%s,%s", sp->lport, + fp[j]); else (void)snpf(lp, len + 1, "%s", fp[j]); } @@ -2340,12 +2305,12 @@ static void get_sctp(struct lsof_context *ctx) { /* * The field number for the remote port depends on the entry type. */ - rp = sp ? sp->rport : (char *)NULL; + rp = NULL; if (!i && fp[12] && *fp[12] && (len = strlen(fp[12]))) { - if (rp) { - if (isainb(fp[12], rp)) { - plen = strlen(rp); - rp = (char *)realloc((MALLOC_P *)rp, plen + len + 2); + if (sp && sp->rport) { + if (isainb(fp[12], sp->rport)) { + plen = strlen(sp->rport); + rp = (char *)malloc(plen + len + 2); d = 0; } else d = 1; @@ -2354,15 +2319,19 @@ static void get_sctp(struct lsof_context *ctx) { rp = (char *)malloc(len + 1); d = 0; } - if (!rp) { - (void)fprintf( - stderr, "%s: can't allocate %d SCTP RPORT bytes: %s\n", - Pn, (int)(len + 1), fp[12]); - Error(ctx); - } if (!d) { + if (!rp) { + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d SCTP RPORT bytes: %s\n", + Pn, (int)(len + 1), fp[12]); + Error(ctx); + goto cleanup; + } if (plen) - (void)snpf((rp + plen), len + 2, ",%s", fp[12]); + (void)snpf(rp, plen + len + 2, "%s,%s", sp->rport, + fp[12]); else (void)snpf(rp, len + 1, "%s", fp[12]); } @@ -2372,63 +2341,75 @@ static void get_sctp(struct lsof_context *ctx) { * the entry type. */ j = i ? 8 : 13; - la = sp ? sp->laddrs : (char *)NULL; + la = NULL; x = 0; if (fp[j] && *fp[j] && (len = strlen(fp[j]))) { if (!(ta = get_sctpaddrs(fp, j, nf, &x))) { - (void)fprintf(stderr, - "%s: can't allocate %d SCTP LADDRS bytes\n", - Pn, (int)len); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d SCTP LADDRS bytes\n", Pn, + (int)len); Error(ctx); + goto cleanup; } - if (la) { - if (isainb(ta, la)) { + if (sp && sp->laddrs) { + if (isainb(ta, sp->laddrs)) { len = strlen(ta); - plen = strlen(la); - if (!(la = (char *)realloc((MALLOC_P *)la, - plen + len + 2))) { - (void)fprintf( - stderr, - "%s: can't reallocate %d SCTP LADDRS bytes\n", - Pn, (int)len); + plen = strlen(sp->laddrs); + if (!(la = (char *)malloc(plen + len + 2))) { + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't reallocate %d SCTP " + "LADDRS bytes\n", + Pn, (int)len); Error(ctx); + goto cleanup; } - (void)snpf(la + plen, len + 2, ",%s", ta); - (void)free((FREE_P *)ta); + (void)snpf(la, plen + len + 2, "%s,%s", sp->laddrs, ta); } - } else + CLEAN(ta); + } else { la = ta; + ta = NULL; + } } /* * The remote addresses begin after the local addresses, but only * for the ASSOC type. */ - ra = sp ? sp->raddrs : (char *)NULL; + ra = NULL; if (!i && x && fp[x + 1] && *fp[x + 1] && (len = strlen(fp[x + 1]))) { if (!(ta = get_sctpaddrs(fp, x + 1, nf, &x))) { - (void)fprintf(stderr, - "%s: can't allocate %d SCTP RADDRS bytes\n", - Pn, (int)len); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d SCTP RADDRS bytes\n", Pn, + (int)len); Error(ctx); + goto cleanup; } - if (ra) { - if (isainb(ta, ra)) { + if (sp && sp->raddrs) { + if (isainb(ta, sp->raddrs)) { len = strlen(ta); - plen = strlen(ra); - if (!(ra = (char *)realloc((MALLOC_P *)ra, - plen + len + 2))) { - (void)fprintf( - stderr, - "%s: can't reallocate %d SCTP RADDRS bytes\n", - Pn, (int)len); + plen = strlen(sp->raddrs); + if (!(ra = (char *)malloc(plen + len + 2))) { + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't reallocate %d SCTP " + "RADDRS bytes\n", + Pn, (int)len); Error(ctx); + goto cleanup; } - (void)snpf(ra + plen, len + 2, ",%s", ta); - (void)free((FREE_P *)ta); + (void)snpf(ra, plen + len + 2, "%s,%s", sp->raddrs, ta); } - } else + CLEAN(ta); + } else { ra = ta; + ta = NULL; + } } /* * If no matching sctpsin entry was found for this inode, allocate @@ -2437,25 +2418,62 @@ static void get_sctp(struct lsof_context *ctx) { */ if (!sp) { if (!(sp = (struct sctpsin *)malloc(sizeof(struct sctpsin)))) { - (void)fprintf( - stderr, - "%s: can't allocate %d byte sctpsin structure\n", Pn, - (int)sizeof(struct sctpsin)); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d byte sctpsin structure\n", + Pn, (int)sizeof(struct sctpsin)); Error(ctx); + goto cleanup; } sp->inode = inode; HASH_INSERT_ELEMENT(SCTPsin, INOHASH, sp, inode); } - sp->addr = a; - sp->assocID = id; - sp->lport = lp; - sp->rport = rp; - sp->laddrs = la; - sp->raddrs = ra; + if (a) { + CLEAN(sp->addr); + sp->addr = a; + a = NULL; + } + if (id) { + CLEAN(sp->assocID); + sp->assocID = id; + id = NULL; + } + if (lp) { + CLEAN(sp->lport); + sp->lport = lp; + lp = NULL; + } + if (rp) { + CLEAN(sp->rport); + sp->rport = rp; + rp = NULL; + } + if (la) { + CLEAN(sp->laddrs); + sp->laddrs = la; + la = NULL; + } + if (ra) { + CLEAN(sp->raddrs); + sp->raddrs = ra; + ra = NULL; + } sp->type = ty; } (void)fclose(ss); + ss = NULL; } +cleanup: + if (ss) + (void)fclose(ss); + CLEAN(a); + CLEAN(id); + CLEAN(lp); + CLEAN(rp); + CLEAN(ta); + CLEAN(la); + CLEAN(ra); } static char *get_sctpaddrs(char **fp, /* field pointers */ @@ -2465,6 +2483,7 @@ static char *get_sctpaddrs(char **fp, /* field pointers */ { MALLOC_S al = (MALLOC_S)0; char *cp = (char *)NULL; + char *temp; MALLOC_S tl; *x = 0; @@ -2477,12 +2496,17 @@ static char *get_sctpaddrs(char **fp, /* field pointers */ } if (!strchr(fp[i], (int)'.') && !strchr(fp[i], (int)':')) break; + if (cp) - cp = (char *)realloc((MALLOC_P *)cp, al + tl + 1); + temp = (char *)realloc((MALLOC_P *)cp, al + tl + 1); else - cp = (char *)malloc(al + tl + 1); - if (!cp) + temp = (char *)malloc(al + tl + 1); + if (!temp) { + CLEAN(cp); break; + } + cp = temp; + if (al) *(cp + al - 1) = ','; (void)strncpy(al ? (cp + al) : cp, fp[i], tl); @@ -2492,14 +2516,51 @@ static char *get_sctpaddrs(char **fp, /* field pointers */ return (cp); } +/* + * clean_tcpudp() - cleanup tcpudp net info + */ +void clean_tcpudp(struct lsof_context *ctx, int free_array) { + int h; + struct tcp_udp *np, *tp; +#if defined(HASEPTOPTS) + pxinfo_t *pp, *pnp; +#endif /* defined(HASEPTOPTS) */ + if (TcpUdp) { + for (h = 0; h < TcpUdp_bucks; h++) { + for (tp = TcpUdp[h]; tp; tp = np) { + np = tp->next; + +#if defined(HASEPTOPTS) + for (pp = tp->pxinfo; pp; pp = pnp) { + pnp = pp->next; + (void)free((FREE_P *)pp); + } +#endif /* defined(HASEPTOPTS) */ + + (void)free((FREE_P *)tp); + } + TcpUdp[h] = (struct tcp_udp *)NULL; + } +#if defined(HASEPTOPTS) + if (FeptE) + for (h = 0; h < IPCBUCKS; h++) + TcpUdpIPC[h] = (struct tcp_udp *)NULL; +#endif /* defined(HASEPTOPTS) */ + if (free_array) { + CLEAN(TcpUdp); + CLEAN(TcpUdpIPC); + } + } +} + /* * get_tcpudp() - get IPv4 TCP, UDP or UDPLITE net info */ -static void get_tcpudp(struct lsof_context *ctx, /* context */ - char *p, /* /proc/net/{tcp,udp} path */ - int pr, /* protocol: 0 = TCP, 1 = UDP, - * 2 = UDPLITE */ - int clr) /* 1 == clear the table */ +static void get_tcpudp(struct lsof_context *ctx, + char *p, /* /proc/net/{tcp,udp} path */ + int pr, /* protocol: 0 = TCP, 1 = UDP, + * 2 = UDPLITE */ + int clr) /* 1 == clear the table */ { char buf[MAXPATHLEN], *ep, **fp; unsigned long faddr, fport, laddr, lport, rxq, state, txq; @@ -2507,8 +2568,8 @@ static void get_tcpudp(struct lsof_context *ctx, /* context */ int h, nf; INODETYPE inode; struct tcp_udp *np, *tp; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; #if defined(HASEPTOPTS) pxinfo_t *pp, *pnp; @@ -2519,26 +2580,7 @@ static void get_tcpudp(struct lsof_context *ctx, /* context */ */ if (TcpUdp) { if (clr) { - for (h = 0; h < TcpUdp_bucks; h++) { - for (tp = TcpUdp[h]; tp; tp = np) { - np = tp->next; - -#if defined(HASEPTOPTS) - for (pp = tp->pxinfo; pp; pp = pnp) { - pnp = pp->next; - (void)free((FREE_P *)pp); - } -#endif /* defined(HASEPTOPTS) */ - - (void)free((FREE_P *)tp); - } - TcpUdp[h] = (struct tcp_udp *)NULL; - } -#if defined(HASEPTOPTS) - if (FeptE) - for (h = 0; h < IPCBUCKS; h++) - TcpUdpIPC[h] = (struct tcp_udp *)NULL; -#endif /* defined(HASEPTOPTS) */ + clean_tcpudp(ctx, 0); } /* * If no hash buckets have been allocated, do so now. @@ -2565,23 +2607,29 @@ static void get_tcpudp(struct lsof_context *ctx, /* context */ break; } (void)fclose(fs); + fs = NULL; } if (!(TcpUdp = (struct tcp_udp **)calloc(TcpUdp_bucks, sizeof(struct tcp_udp *)))) { - (void)fprintf( - stderr, - "%s: can't allocate %d bytes for TCP&UDP hash buckets\n", Pn, - (int)(TcpUdp_bucks * sizeof(struct tcp_udp *))); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for TCP&UDP hash buckets\n", + Pn, (int)(TcpUdp_bucks * sizeof(struct tcp_udp *))); Error(ctx); + goto cleanup; } #if defined(HASEPTOPTS) if (FeptE && (!(TcpUdpIPC = (struct tcp_udp **)calloc( IPCBUCKS, sizeof(struct tcp_udp *))))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for TCP&UDP local IPC " - "hash buckets\n", - Pn, (int)(IPCBUCKS * sizeof(struct tcp_udp *))); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for TCP&UDP local IPC " + "hash buckets\n", + Pn, (int)(IPCBUCKS * sizeof(struct tcp_udp *))); Error(ctx); + goto cleanup; } #endif /* defined(HASEPTOPTS) */ } @@ -2589,8 +2637,9 @@ static void get_tcpudp(struct lsof_context *ctx, /* context */ * Open the /proc/net file, assign a page size buffer to the stream, and * read it. */ - if (!(fs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) - return; + if (!(fs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) { + goto cleanup; + } nf = 12; while (fgets(buf, sizeof(buf) - 1, fs)) { if (get_fields(ctx, buf, (nf == 12) ? (char *)NULL : ":", &fp, @@ -2602,9 +2651,10 @@ static void get_tcpudp(struct lsof_context *ctx, /* context */ !fp[4] || strcmp(fp[4], "tx_queue") || !fp[5] || strcmp(fp[5], "rx_queue") || !fp[11] || strcmp(fp[11], "inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -2658,10 +2708,13 @@ static void get_tcpudp(struct lsof_context *ctx, /* context */ * Create a new entry and link it to its hash bucket. */ if (!(tp = (struct tcp_udp *)malloc(sizeof(struct tcp_udp)))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for tcp_udp struct\n", - Pn, (int)sizeof(struct tcp_udp)); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for tcp_udp struct\n", Pn, + (int)sizeof(struct tcp_udp)); Error(ctx); + goto cleanup; } tp->inode = inode; tp->faddr = faddr; @@ -2694,56 +2747,65 @@ static void get_tcpudp(struct lsof_context *ctx, /* context */ get_netpeeri(ctx); #endif /* defined(HASEPTOPTS) */ +cleanup: (void)fclose(fs); + CLEAN(vbuf); } #if defined(HASIPv6) +/* + * clean_raw6() - cleanup raw6 net info + */ +void clean_raw6(struct lsof_context *ctx) { + struct rawsin *np, *rp; + int h; + if (Rawsin6) { + for (h = 0; h < INOBUCKS; h++) { + for (rp = Rawsin6[h]; rp; rp = np) { + np = rp->next; + CLEAN(rp->la); + CLEAN(rp->ra); + CLEAN(rp->sp); + (void)free((FREE_P *)rp); + } + Rawsin6[h] = (struct rawsin *)NULL; + } + CLEAN(Rawsin6); + } +} + /* * get_raw6() - get /proc/net/raw6 info */ -static void get_raw6(struct lsof_context *ctx, /* context */ - char *p) /* /proc/net/raw path */ +static void get_raw6(struct lsof_context *ctx, char *p) /* /proc/net/raw path */ { - char buf[MAXPATHLEN], *ep, **fp, *la, *ra, *sp; + char buf[MAXPATHLEN], *ep, **fp, *la = NULL, *ra = NULL, *sp = NULL; int h; INODETYPE inode; int nf = 12; struct rawsin *np, *rp; MALLOC_S lal, ral, spl; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; FILE *xs; /* * Do second time cleanup or first time setup. */ - if (Rawsin6) { - for (h = 0; h < INOBUCKS; h++) { - for (rp = Rawsin6[h]; rp; rp = np) { - np = rp->next; - if (rp->la) - (void)free((FREE_P *)rp->la); - if (rp->ra) - (void)free((FREE_P *)rp->ra); - if (rp->sp) - (void)free((FREE_P *)rp->sp); - (void)free((FREE_P *)rp); - } - Rawsin6[h] = (struct rawsin *)NULL; - } - } else { - Rawsin6 = (struct rawsin **)calloc(INOBUCKS, sizeof(struct rawsin *)); - if (!Rawsin6) { - (void)fprintf(stderr, + clean_raw6(ctx); + Rawsin6 = (struct rawsin **)calloc(INOBUCKS, sizeof(struct rawsin *)); + if (!Rawsin6) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d raw6 hash pointer bytes\n", Pn, (int)(INOBUCKS * sizeof(struct rawsin *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/raw6 file, assign a page size buffer to the stream, * and read it. Store raw6 socket info in the Rawsin6[] hash buckets. */ - if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) + if (!(xs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) return; while (fgets(buf, sizeof(buf) - 1, xs)) { if (get_fields(ctx, buf, (char *)NULL, &fp, (int *)NULL, 0) < nf) @@ -2756,9 +2818,10 @@ static void get_raw6(struct lsof_context *ctx, /* context */ if (!fp[1] || strcmp(fp[1], "local_address") || !fp[2] || strcmp(fp[2], "remote_address") || !fp[3] || strcmp(fp[3], "st") || !fp[11] || strcmp(fp[11], "inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -2784,11 +2847,13 @@ static void get_raw6(struct lsof_context *ctx, /* context */ lal = (MALLOC_S)0; } else { if (!(la = (char *)malloc(lal + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d local raw6 address bytes: %s\n", Pn, - (int)(lal + 1), fp[1]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d local raw6 address bytes: %s\n", + Pn, (int)(lal + 1), fp[1]); Error(ctx); + goto cleanup; } (void)snpf(la, lal + 1, "%s", fp[1]); } @@ -2797,11 +2862,13 @@ static void get_raw6(struct lsof_context *ctx, /* context */ ral = (MALLOC_S)0; } else { if (!(ra = (char *)malloc(ral + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d remote raw6 address bytes: %s\n", Pn, - (int)(ral + 1), fp[2]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d remote raw6 address bytes: %s\n", + Pn, (int)(ral + 1), fp[2]); Error(ctx); + goto cleanup; } (void)snpf(ra, ral + 1, "%s", fp[2]); } @@ -2810,11 +2877,13 @@ static void get_raw6(struct lsof_context *ctx, /* context */ spl = (MALLOC_S)0; } else { if (!(sp = (char *)malloc(spl + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d remote raw6 state bytes: %s\n", Pn, - (int)(spl + 1), fp[2]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d remote raw6 state bytes: %s\n", + Pn, (int)(spl + 1), fp[2]); Error(ctx); + goto cleanup; } (void)snpf(sp, spl + 1, "%s", fp[3]); } @@ -2823,29 +2892,77 @@ static void get_raw6(struct lsof_context *ctx, /* context */ * hash bucket. */ if (!(rp = (struct rawsin *)malloc(sizeof(struct rawsin)))) { - (void)fprintf( - stderr, - "%s: can't allocate %d byte rawsin structure for IPv6\n", Pn, - (int)sizeof(struct rawsin)); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d byte rawsin structure for IPv6\n", + Pn, (int)sizeof(struct rawsin)); Error(ctx); + goto cleanup; } rp->inode = inode; rp->la = la; + la = NULL; rp->lal = lal; rp->ra = ra; + ra = NULL; rp->ral = ral; rp->sp = sp; + sp = NULL; rp->spl = spl; HASH_INSERT_ELEMENT(Rawsin6, INOHASH, rp, inode); } +cleanup: (void)fclose(xs); + CLEAN(vbuf); + CLEAN(la); + CLEAN(ra); + CLEAN(sp); +} + +/* + * clean_tcpudp6() - cleanup tcpudp6 net info + */ +void clean_tcpudp6(struct lsof_context *ctx, int free_array) { + struct tcp_udp6 *np6, *tp6; + int h; +# if defined(HASEPTOPTS) + pxinfo_t *pp, *pnp; +# endif /* defined(HASEPTOPTS) */ + if (TcpUdp6) { + for (h = 0; h < TcpUdp6_bucks; h++) { + for (tp6 = TcpUdp6[h]; tp6; tp6 = np6) { + np6 = tp6->next; + +# if defined(HASEPTOPTS) + for (pp = tp6->pxinfo; pp; pp = pnp) { + pnp = pp->next; + (void)free((FREE_P *)pp); + } +# endif /* defined(HASEPTOPTS) */ + + (void)free((FREE_P *)tp6); + } + TcpUdp6[h] = (struct tcp_udp6 *)NULL; + } +# if defined(HASEPTOPTS) + if (FeptE) + for (h = 0; h < IPCBUCKS; h++) + TcpUdp6IPC[h] = (struct tcp_udp6 *)NULL; +# endif /* defined(HASEPTOPTS) */ + + if (free_array) { + CLEAN(TcpUdp6); + CLEAN(TcpUdp6IPC); + } + } } /* * get_tcpudp6() - get IPv6 TCP, UDP or UDPLITE net info */ -static void get_tcpudp6(struct lsof_context *ctx, /* context */ - char *p, /* /proc/net/{tcp,udp} path */ +static void get_tcpudp6(struct lsof_context *ctx, + char *p, /* /proc/net/{tcp,udp} path */ int pr, /* protocol: 0 = TCP, 1 = UDP */ int clr) /* 1 == clear the table */ { @@ -2856,8 +2973,8 @@ static void get_tcpudp6(struct lsof_context *ctx, /* context */ int h, i, nf; INODETYPE inode; struct tcp_udp6 *np6, *tp6; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; # if defined(HASEPTOPTS) pxinfo_t *pp, *pnp; @@ -2868,26 +2985,7 @@ static void get_tcpudp6(struct lsof_context *ctx, /* context */ */ if (TcpUdp6) { if (clr) { - for (h = 0; h < TcpUdp6_bucks; h++) { - for (tp6 = TcpUdp6[h]; tp6; tp6 = np6) { - np6 = tp6->next; - -# if defined(HASEPTOPTS) - for (pp = tp6->pxinfo; pp; pp = pnp) { - pnp = pp->next; - (void)free((FREE_P *)pp); - } -# endif /* defined(HASEPTOPTS) */ - - (void)free((FREE_P *)tp6); - } - TcpUdp6[h] = (struct tcp_udp6 *)NULL; - } -# if defined(HASEPTOPTS) - if (FeptE) - for (h = 0; h < IPCBUCKS; h++) - TcpUdp6IPC[h] = (struct tcp_udp6 *)NULL; -# endif /* defined(HASEPTOPTS) */ + clean_tcpudp6(ctx, 0); } } else { @@ -2924,23 +3022,29 @@ static void get_tcpudp6(struct lsof_context *ctx, /* context */ } } (void)fclose(fs); + fs = NULL; } if (!(TcpUdp6 = (struct tcp_udp6 **)calloc( TcpUdp6_bucks, sizeof(struct tcp_udp6 *)))) { - (void)fprintf( - stderr, - "%s: can't allocate %d bytes for TCP6&UDP6 hash buckets\n", Pn, - (int)(TcpUdp6_bucks * sizeof(struct tcp_udp6 *))); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for TCP6&UDP6 hash buckets\n", + Pn, (int)(TcpUdp6_bucks * sizeof(struct tcp_udp6 *))); Error(ctx); + goto cleanup; } # if defined(HASEPTOPTS) if (FeptE && (!(TcpUdp6IPC = (struct tcp_udp6 **)calloc( IPCBUCKS, sizeof(struct tcp_udp6 *))))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for TCP6&UDP6 local IPC " - "hash buckets\n", - Pn, (int)(IPCBUCKS * sizeof(struct tcp_udp6 *))); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for TCP6&UDP6 local IPC " + "hash buckets\n", + Pn, (int)(IPCBUCKS * sizeof(struct tcp_udp6 *))); Error(ctx); + goto cleanup; } # endif /* defined(HASEPTOPTS) */ } @@ -2948,8 +3052,9 @@ static void get_tcpudp6(struct lsof_context *ctx, /* context */ * Open the /proc/net file, assign a page size buffer to the stream, * and read it. */ - if (!(fs = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) - return; + if (!(fs = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) { + goto cleanup; + } nf = 12; while (fgets(buf, sizeof(buf) - 1, fs)) { if (get_fields(ctx, buf, (nf == 12) ? (char *)NULL : ":", &fp, @@ -2961,9 +3066,10 @@ static void get_tcpudp6(struct lsof_context *ctx, /* context */ strcmp(fp[3], "st") || !fp[4] || strcmp(fp[4], "tx_queue") || !fp[5] || strcmp(fp[5], "rx_queue") || !fp[11] || strcmp(fp[11], "inode")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -3014,10 +3120,13 @@ static void get_tcpudp6(struct lsof_context *ctx, /* context */ * Create a new entry and link it to its hash bucket. */ if (!(tp6 = (struct tcp_udp6 *)malloc(sizeof(struct tcp_udp6)))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for tcp_udp6 struct\n", - Pn, (int)sizeof(struct tcp_udp6)); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for tcp_udp6 struct\n", Pn, + (int)sizeof(struct tcp_udp6)); Error(ctx); + goto cleanup; } tp6->inode = inode; tp6->faddr = faddr; @@ -3049,34 +3158,22 @@ static void get_tcpudp6(struct lsof_context *ctx, /* context */ get_net6peeri(ctx); # endif /* defined(HASEPTOPTS) */ - (void)fclose(fs); +cleanup: + if (fs) + (void)fclose(fs); + CLEAN(vbuf); } #endif /* defined(HASIPv6) */ /* - * get_unix() - get UNIX net info + * clean_unix() - cleanup raw6 net info */ -static void get_unix(struct lsof_context *ctx, /* context */ - char *p) /* /proc/net/unix path */ -{ - char buf[MAXPATHLEN], *ep, **fp, *path, *pcb; - int fl = 1; /* First line */ - int h, nf; - INODETYPE inode; - MALLOC_S len; +void clean_unix(struct lsof_context *ctx) { + int h; uxsin_t *np, *up; - FILE *us; - uint32_t ty; - static char *vbuf = (char *)NULL; - static size_t vsz = (size_t)0; - #if defined(HASEPTOPTS) && defined(HASUXSOCKEPT) pxinfo_t *pp, *pnp; #endif /* defined(HASEPTOPTS) && defined(HASUXSOCKEPT) */ - - /* - * Do second time cleanup or first time setup. - */ if (Uxsin) { for (h = 0; h < INOBUCKS; h++) { for (up = Uxsin[h]; up; up = np) { @@ -3097,21 +3194,51 @@ static void get_unix(struct lsof_context *ctx, /* context */ } Uxsin[h] = (uxsin_t *)NULL; } - } else { - Uxsin = (uxsin_t **)calloc(INOBUCKS, sizeof(uxsin_t *)); - if (!Uxsin) { - (void)fprintf(stderr, + CLEAN(Uxsin); + } +} + +/* + * get_unix() - get UNIX net info + */ +static void get_unix(struct lsof_context *ctx, + char *p) /* /proc/net/unix path */ +{ + char buf[MAXPATHLEN], *ep, **fp, *path = NULL, *pcb = NULL; + int fl = 1; /* First line */ + int h, nf; + INODETYPE inode; + MALLOC_S len; + uxsin_t *np, *up; + FILE *us; + uint32_t ty; + char *vbuf = (char *)NULL; + size_t vsz = (size_t)0; + +#if defined(HASEPTOPTS) && defined(HASUXSOCKEPT) + pxinfo_t *pp, *pnp; +#endif /* defined(HASEPTOPTS) && defined(HASUXSOCKEPT) */ + + /* + * Do second time cleanup or first time setup. + */ + clean_unix(ctx); + Uxsin = (uxsin_t **)calloc(INOBUCKS, sizeof(uxsin_t *)); + if (!Uxsin) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't allocate %d bytes for Unix socket info\n", Pn, (int)(INOBUCKS * sizeof(uxsin_t *))); - Error(ctx); - } + Error(ctx); + return; } /* * Open the /proc/net/unix file, assign a page size buffer to the stream, * read the file's contents, and add them to the Uxsin hash buckets. */ - if (!(us = open_proc_stream(ctx, p, "r", &vbuf, &vsz, 0))) - return; + if (!(us = open_proc_stream(ctx, p, "r", &vbuf, &vsz))) { + goto cleanup; + } while (fgets(buf, sizeof(buf) - 1, us)) { if ((nf = get_fields(ctx, buf, ":", &fp, (int *)NULL, 0)) < 7) continue; @@ -3126,9 +3253,10 @@ static void get_unix(struct lsof_context *ctx, /* context */ !fp[4] || strcmp(fp[4], "Type") || !fp[5] || strcmp(fp[5], "St") || !fp[6] || strcmp(fp[6], "Inode") || nf < 8 || !fp[7] || strcmp(fp[7], "Path")) { - if (!Fwarn) { - (void)fprintf( - stderr, "%s: WARNING: unsupported format: %s\n", Pn, p); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: WARNING: unsupported format: %s\n", Pn, + p); } break; } @@ -3151,20 +3279,25 @@ static void get_unix(struct lsof_context *ctx, /* context */ else { len = strlen(fp[0]) + 2; if (!(pcb = (char *)malloc(len + 1))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for UNIX PCB: %s\n", - Pn, (int)(len + 1), fp[0]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for UNIX PCB: %s\n", Pn, + (int)(len + 1), fp[0]); Error(ctx); + goto cleanup; } (void)snpf(pcb, len + 1, "0x%s", fp[0]); } if (nf >= 8 && fp[7] && *fp[7] && (len = strlen(fp[7]))) { if (!(path = (char *)malloc(len + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d bytes for UNIX path \"%s\"\n", Pn, - (int)(len + 1), fp[7]); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for UNIX path \"%s\"\n", + Pn, (int)(len + 1), fp[7]); Error(ctx); + goto cleanup; } (void)snpf(path, len + 1, "%s", fp[7]); } else @@ -3198,14 +3331,17 @@ static void get_unix(struct lsof_context *ctx, /* context */ * hash bucket. */ if (!(up = (uxsin_t *)malloc(sizeof(uxsin_t)))) { - (void)fprintf(stderr, - "%s: can't allocate %d bytes for uxsin struct\n", Pn, - (int)sizeof(uxsin_t)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate %d bytes for uxsin struct\n", + Pn, (int)sizeof(uxsin_t)); Error(ctx); + goto cleanup; } up->inode = inode; up->next = (uxsin_t *)NULL; up->pcb = pcb; + pcb = NULL; up->sb_def = 0; up->ty = ty; up->opt = (unsigned int)proc_flags; @@ -3231,6 +3367,7 @@ static void get_unix(struct lsof_context *ctx, /* context */ up->sb_rdev = sb.st_rdev; } } + path = NULL; #if defined(HASEPTOPTS) && defined(HASUXSOCKEPT) /* @@ -3252,7 +3389,12 @@ static void get_unix(struct lsof_context *ctx, /* context */ get_uxpeeri(ctx); #endif /* defined(HASEPTOPTS) && defined(HASUXSOCKEPT) */ - (void)fclose(us); +cleanup: + if (us) + (void)fclose(us); + CLEAN(vbuf); + CLEAN(pcb); + CLEAN(path); } #if defined(HASIPv6) @@ -3344,8 +3486,8 @@ static int isainb(char *a, /*string a */ /* * print_ax25info() - print AX25 socket info */ -static void print_ax25info(struct lsof_context *ctx, /* context */ - struct ax25sin *ap) /* AX25 socket info */ +static void print_ax25info(struct lsof_context *ctx, + struct ax25sin *ap) /* AX25 socket info */ { char *cp, pbuf[1024]; int ds; @@ -3380,11 +3522,13 @@ static void print_ax25info(struct lsof_context *ctx, /* context */ cp ? cp : ""); pl = strlen(pbuf); if (!(cp = (char *)malloc(pl + 1))) { - (void)fprintf( - stderr, - "%s: can't allocate %d bytes for AX25 sock state, PID: %d\n", Pn, - (int)(pl + 1), Lp->pid); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for AX25 sock state, PID: %d\n", + Pn, (int)(pl + 1), Lp->pid); Error(ctx); + return; } (void)snpf(cp, pl + 1, "%s", pbuf); Lf->nma = cp; @@ -3393,8 +3537,8 @@ static void print_ax25info(struct lsof_context *ctx, /* context */ /* * print_ipxinfo() - print IPX socket info */ -static void print_ipxinfo(struct lsof_context *ctx, /* context */ - struct ipxsin *ip) /* IPX socket info */ +static void print_ipxinfo(struct lsof_context *ctx, + struct ipxsin *ip) /* IPX socket info */ { char *cp, pbuf[256]; MALLOC_S pl; @@ -3405,150 +3549,23 @@ static void print_ipxinfo(struct lsof_context *ctx, /* context */ ip->rxq, ip->state); pl = strlen(pbuf); if (!(cp = (char *)malloc(pl + 1))) { - (void)fprintf( - stderr, "%s: can't allocate %d bytes for IPX sock state, PID: %d\n", - Pn, (int)(pl + 1), Lp->pid); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for IPX sock state, PID: %d\n", Pn, + (int)(pl + 1), Lp->pid); Error(ctx); + return; } (void)snpf(cp, pl + 1, "%s", pbuf); Lf->nma = cp; } -/* - * print_unix() - print state of UNIX domain socket e.g. UNCONNECTED - */ -static void print_unix(int nl) { - if (Ftcptpi & TCPTPI_STATE) { -#if defined(HASSOSTATE) && defined(HASSOOPT) - char *cp = (Lf->lts.opt == __SO_ACCEPTCON) - ? "LISTEN" - : socket_state_to_str(Lf->lts.ss); - - if (Ffield) - (void)printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator); - else { - putchar('('); - (void)fputs(cp, stdout); - putchar(')'); - } -#endif /* defined(HASSOSTATE) && defined(HASSOOPT) */ - } - if (nl) - putchar('\n'); -} - -/* - * print_tcptpi() - print TCP/TPI state e.g. ESTBALISHED - */ -void print_tcptpi(struct lsof_context *ctx, /* context */ - int nl) /* 1 == '\n' required */ -{ - char buf[128]; - char *cp = (char *)NULL; - int ps = 0; - int s; - - if (!strcmp(Lf->type, "unix")) { - print_unix(nl); - return; - } - if ((Ftcptpi & TCPTPI_STATE) && Lf->lts.type == 0) { - if (!TcpSt) - (void)build_IPstates(ctx); - if ((s = Lf->lts.state.i + TcpStOff) < 0 || s >= TcpNstates) { - (void)snpf(buf, sizeof(buf), "UNKNOWN_TCP_STATE_%d", - Lf->lts.state.i); - cp = buf; - } else - cp = TcpSt[s]; - if (cp) { - if (Ffield) - (void)printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator); - else { - putchar('('); - (void)fputs(cp, stdout); - } - ps++; - } - } - -#if defined(HASTCPTPIQ) - if (Ftcptpi & TCPTPI_QUEUES) { - if (Lf->lts.rqs) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("QR=%lu", Lf->lts.rq); - if (Ffield) - putchar(Terminator); - ps++; - } - if (Lf->lts.sqs) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("QS=%lu", Lf->lts.sq); - if (Ffield) - putchar(Terminator); - ps++; - } - } -#endif /* defined(HASTCPTPIQ) */ - -#if defined(HASTCPTPIW) - if (Ftcptpi & TCPTPI_WINDOWS) { - if (Lf->lts.rws) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("WR=%lu", Lf->lts.rw); - if (Ffield) - putchar(Terminator); - ps++; - } - if (Lf->lts.wws) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("WW=%lu", Lf->lts.ww); - if (Ffield) - putchar(Terminator); - ps++; - } - } -#endif /* defined(HASTCPTPIW) */ - - if (!Ffield && ps) - putchar(')'); - if (nl) - putchar('\n'); -} - /* * process_proc_sock() - process /proc-based socket */ -void process_proc_sock(struct lsof_context *ctx, /* context */ - char *p, /* node's readlink() path */ +void process_proc_sock(struct lsof_context *ctx, + char *p, /* node's readlink() path */ char *pbr, /* node's path before readlink() */ struct stat *s, /* stat() result for path */ int ss, /* *s status -- i.e, SB_* values */ @@ -3558,6 +3575,7 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ { struct ax25sin *ap; char *cp, *path = (char *)NULL, tbuf[64]; + enum lsof_protocol proto; unsigned char *fa, *la; struct in_addr fs, ls; struct icmpin *icmpp; @@ -3566,10 +3584,10 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ struct nlksin *np; struct packin *pp; char *pr; - static char *prp = (char *)NULL; + char *prp = (char *)NULL; struct rawsin *rp; struct sctpsin *sp; - static ssize_t sz; + ssize_t sz; struct tcp_udp *tp; uxsin_t *up; @@ -3589,10 +3607,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ /* * Check for socket's inode presence in the protocol info caches. */ - if (AX25path) { - (void)get_ax25(ctx, AX25path); - (void)free((FREE_P *)AX25path); - AX25path = (char *)NULL; + if (!ctxd.ax25_valid) { + (void)get_ax25(ctx, PROCFS "/net/ax25"); + ctxd.ax25_valid = 1; } if ((ss & SB_INO) && (ap = check_ax25(ctx, (INODETYPE)s->st_ino))) { @@ -3603,19 +3620,18 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * save the destination and source addresses; save the send and receive * queue sizes; and save the connection state. */ - (void)snpf(Lf->type, sizeof(Lf->type), "ax25"); + Lf->type = LSOF_FILE_AX25; if (ap->dev_ch) (void)enter_dev_ch(ctx, ap->dev_ch); Lf->inode = ap->inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; print_ax25info(ctx, ap); return; } - if (Ipxpath) { - (void)get_ipx(ctx, Ipxpath); - (void)free((FREE_P *)Ipxpath); - Ipxpath = (char *)NULL; + if (!ctxd.ipx_valid) { + (void)get_ipx(ctx, PROCFS "/net/ipx"); + ctxd.ipx_valid = 1; } if ((ss & SB_INO) && (ip = check_ipx(ctx, (INODETYPE)s->st_ino))) { /* @@ -3624,9 +3640,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * Set the type to "ipx"; enter the inode and device numbers; store * the addresses, queue sizes, and state in the NAME column. */ - (void)snpf(Lf->type, sizeof(Lf->type), "ipx"); + Lf->type = LSOF_FILE_IPX; Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; if (ss & SB_DEV) { Lf->dev = s->st_dev; @@ -3670,10 +3686,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ return; } - if (Rawpath) { - (void)get_raw(ctx, Rawpath); - (void)free((FREE_P *)Rawpath); - Rawpath = (char *)NULL; + if (!ctxd.raw_valid) { + (void)get_raw(ctx, PROCFS "/net/raw"); + ctxd.raw_valid = 1; } if ((ss & SB_INO) && (rp = check_raw(ctx, (INODETYPE)s->st_ino))) { /* @@ -3682,9 +3697,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * Set the type to "raw"; enter the inode number; store the local * address, remote address, and state in the NAME column. */ - (void)snpf(Lf->type, sizeof(Lf->type), "raw"); + Lf->type = LSOF_FILE_RAW; Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; cp = Namech; nl = Namechl - 2; @@ -3730,10 +3745,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ return; } - if (Nlkpath) { - (void)get_netlink(ctx, Nlkpath); - (void)free((FREE_P *)Nlkpath); - Nlkpath = (char *)NULL; + if (!ctxd.netlink_valid) { + (void)get_netlink(ctx, PROCFS "/net/netlink"); + ctxd.netlink_valid = 1; } if ((ss & SB_INO) && (np = check_netlink(ctx, (INODETYPE)s->st_ino))) { /* @@ -3743,7 +3757,7 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * column. Save the inode number. */ - (void)snpf(Lf->type, sizeof(Lf->type), "netlink"); + Lf->type = LSOF_FILE_NETLINK; cp = netlink_proto_to_str(np->pr); if (cp) (void)snpf(Namech, Namechl, "%s", cp); @@ -3751,16 +3765,15 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ (void)snpf(Namech, Namechl, "unknown protocol: %d", np->pr); Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; if (Namech[0]) enter_nm(ctx, Namech); return; } - if (Packpath) { - (void)get_pack(ctx, Packpath); - (void)free((FREE_P *)Packpath); - Packpath = (char *)NULL; + if (!ctxd.packet_valid) { + (void)get_pack(ctx, PROCFS "/net/packet"); + ctxd.packet_valid = 1; } if ((ss & SB_INO) && (pp = check_pack(ctx, (INODETYPE)s->st_ino))) { /* @@ -3770,20 +3783,17 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * column. Put the protocol name in the NODE column and the inode * number in the DEVICE column. */ - (void)snpf(Lf->type, sizeof(Lf->type), "pack"); + Lf->type = LSOF_FILE_PACKET; cp = socket_type_to_str(pp->ty, &rf); (void)snpf(Namech, Namechl, "type=%s%s", rf ? "" : "SOCK_", cp); - cp = ethernet_proto_to_str(pp->pr); - if (!cp) { - /* Unknown ethernet proto */ - (void)snpf(tbuf, sizeof(tbuf) - 1, "%d", pp->pr); - tbuf[sizeof(tbuf) - 1] = '\0'; - cp = tbuf; + proto = ethernet_proto_convert(pp->pr); + Lf->iproto = proto; + if (Lf->iproto == LSOF_PROTOCOL_UNKNOWN) { + Lf->unknown_proto_number = pp->pr; } - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, cp); - Lf->inp_ty = 2; if (ss & SB_INO) { - (void)snpf(tbuf, sizeof(tbuf), InodeFmt_d, (INODETYPE)s->st_ino); + (void)snpf(tbuf, sizeof(tbuf), "%" INODEPSPEC "d", + (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); } @@ -3792,10 +3802,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ return; } - if (UNIXpath) { - (void)get_unix(ctx, UNIXpath); - (void)free((FREE_P *)UNIXpath); - UNIXpath = (char *)NULL; + if (!ctxd.unix_valid) { + (void)get_unix(ctx, PROCFS "/net/unix"); + ctxd.unix_valid = 1; } if ((ss & SB_INO) && (up = check_unix(ctx, (INODETYPE)s->st_ino))) { @@ -3807,11 +3816,11 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ */ if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; if (up->pcb) enter_dev_ch(ctx, up->pcb); Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; Lf->lts.type = up->ty; #if defined(HASSOOPT) @@ -3833,7 +3842,6 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ Namech[Namechl - 1] = '\0'; (void)enter_nm(ctx, Namech); if (Sfile) { - /* * See if this UNIX domain socket was specified as a search * argument. @@ -3852,20 +3860,20 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * Note: that requires the saving, temporary modification and * restoration of some *Lf values. */ - unsigned char sv_dev_def; /* saved dev_def */ - unsigned char sv_inp_ty; /* saved inp_ty */ - unsigned char sv_rdev_def; /* saved rdev_def */ - dev_t sv_dev; /* saved dev */ - INODETYPE sv_inode; /* saved inode */ - dev_t sv_rdev; /* saved rdev */ + unsigned char sv_dev_def; /* saved dev_def */ + unsigned char sv_inode_def; /* saved inode_def */ + unsigned char sv_rdev_def; /* saved rdev_def */ + dev_t sv_dev; /* saved dev */ + INODETYPE sv_inode; /* saved inode */ + dev_t sv_rdev; /* saved rdev */ sv_dev_def = Lf->dev_def; sv_dev = Lf->dev; sv_inode = Lf->inode; - sv_inp_ty = Lf->inp_ty; + sv_inode_def = Lf->inode_def; sv_rdev_def = Lf->rdev_def; sv_rdev = Lf->rdev; - Lf->dev_def = Lf->inp_ty = Lf->rdev_def = 1; + Lf->dev_def = Lf->inode_def = Lf->rdev_def = 1; Lf->dev = up->sb_dev; Lf->inode = up->sb_ino; Lf->rdev = up->sb_rdev; @@ -3876,7 +3884,7 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ Lf->dev_def = sv_dev_def; Lf->dev = sv_dev; Lf->inode = sv_inode; - Lf->inp_ty = sv_inp_ty; + Lf->inode_def = sv_inode_def; Lf->rdev_def = sv_rdev_def; Lf->rdev = sv_rdev; } @@ -3899,11 +3907,10 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ } #if defined(HASIPv6) - if (Raw6path) { + if (!ctxd.raw6_valid) { if (!Fxopt) - (void)get_raw6(ctx, Raw6path); - (void)free((FREE_P *)Raw6path); - Raw6path = (char *)NULL; + (void)get_raw6(ctx, PROCFS "/net/raw6"); + ctxd.raw6_valid = 1; } if (!Fxopt && (ss & SB_INO) && (rp = check_raw6(ctx, (INODETYPE)s->st_ino))) { @@ -3914,10 +3921,10 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * Set the type to "raw6"; enter the inode number; store the local * address, remote address, and state in the NAME column. */ - (void)snpf(Lf->type, sizeof(Lf->type), "raw6"); + Lf->type = LSOF_FILE_RAW6; if (ss & SB_INO) { Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } cp = Namech; nl = MAXPATHLEN - 2; @@ -3963,29 +3970,26 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ return; } - if (TCP6path) { + if (!ctxd.tcp6_valid) { if (!Fxopt) - (void)get_tcpudp6(ctx, TCP6path, 0, 1); - (void)free((FREE_P *)TCP6path); - TCP6path = (char *)NULL; + (void)get_tcpudp6(ctx, PROCFS "/net/tcp6", 0, 1); + ctxd.tcp6_valid = 1; } - if (UDP6path) { + if (!ctxd.udp6_valid) { if (!Fxopt) - (void)get_tcpudp6(ctx, UDP6path, 1, 0); - (void)free((FREE_P *)UDP6path); - UDP6path = (char *)NULL; + (void)get_tcpudp6(ctx, PROCFS "/net/udp6", 1, 0); + ctxd.udp6_valid = 1; } - if (UDPLITE6path) { + if (!ctxd.udplite6_valid) { if (!Fxopt) - (void)get_tcpudp6(ctx, UDPLITE6path, 2, 0); - (void)free((FREE_P *)UDPLITE6path); - UDPLITE6path = (char *)NULL; + (void)get_tcpudp6(ctx, PROCFS "/net/udplite6", 2, 0); + ctxd.udplite6_valid = 1; } if (!Fxopt && (ss & SB_INO) && - (tp6 = check_tcpudp6(ctx, (INODETYPE)s->st_ino, &pr))) { + (tp6 = check_tcpudp6(ctx, (INODETYPE)s->st_ino, &proto))) { /* * The inode is connected to an IPv6 TCP or UDP /proc record. @@ -4022,13 +4026,13 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ } } } - if (Fnet && (FnetTy != 4)) + if (Fnet && FnetTy != AF_INET) Lf->sf |= SELNET; - (void)snpf(Lf->type, sizeof(Lf->type), "IPv6"); - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, pr); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_IPV6; + Lf->iproto = proto; if (ss & SB_INO) { - (void)snpf(tbuf, sizeof(tbuf), InodeFmt_d, (INODETYPE)s->st_ino); + (void)snpf(tbuf, sizeof(tbuf), "%" INODEPSPEC "d", + (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); Lf->inode = (INODETYPE)s->st_ino; @@ -4070,29 +4074,26 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ } #endif /* defined(HASIPv6) */ - if (TCPpath) { + if (!ctxd.tcp_valid) { if (!Fxopt) - (void)get_tcpudp(ctx, TCPpath, 0, 1); - (void)free((FREE_P *)TCPpath); - TCPpath = (char *)NULL; + (void)get_tcpudp(ctx, PROCFS "/net/tcp", 0, 1); + ctxd.tcp_valid = 1; } - if (UDPpath) { + if (!ctxd.udp_valid) { if (!Fxopt) - (void)get_tcpudp(ctx, UDPpath, 1, 0); - (void)free((FREE_P *)UDPpath); - UDPpath = (char *)NULL; + (void)get_tcpudp(ctx, PROCFS "/net/udp", 1, 0); + ctxd.udp_valid = 1; } - if (UDPLITEpath) { + if (!ctxd.udplite_valid) { if (!Fxopt) - (void)get_tcpudp(ctx, UDPLITEpath, 2, 0); - (void)free((FREE_P *)UDPLITEpath); - UDPLITEpath = (char *)NULL; + (void)get_tcpudp(ctx, PROCFS "/net/udplite", 2, 0); + ctxd.udplite_valid = 1; } if (!Fxopt && (ss & SB_INO) && - (tp = check_tcpudp(ctx, (INODETYPE)s->st_ino, &pr))) { + (tp = check_tcpudp(ctx, (INODETYPE)s->st_ino, &proto))) { /* * The inode is connected to an IPv4 TCP or UDP /proc record. @@ -4129,19 +4130,19 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ } } } - if (Fnet && (FnetTy != 6)) + if (Fnet && (FnetTy != AF_INET6)) Lf->sf |= SELNET; #if defined(HASIPv6) - (void)snpf(Lf->type, sizeof(Lf->type), "IPv4"); + Lf->type = LSOF_FILE_IPV4; #else /* !defined(HASIPv6) */ - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); + Lf->type = LSOF_FILE_INET; #endif /* defined(HASIPv6) */ - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, pr); - Lf->inp_ty = 2; + Lf->iproto = proto; if (ss & SB_INO) { - (void)snpf(tbuf, sizeof(tbuf), InodeFmt_d, (INODETYPE)s->st_ino); + (void)snpf(tbuf, sizeof(tbuf), "%" INODEPSPEC "d", + (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); Lf->inode = (INODETYPE)s->st_ino; @@ -4176,12 +4177,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ return; } - if (SCTPPath[0]) { + if (!ctxd.sctp_valid) { (void)get_sctp(ctx); - for (i = 0; i < NSCTPPATHS; i++) { - (void)free((FREE_P *)SCTPPath[i]); - SCTPPath[i] = (char *)NULL; - } + ctxd.sctp_valid = 1; } if ((ss & SB_INO) && (sp = check_sctp(ctx, (INODETYPE)s->st_ino))) { @@ -4192,10 +4190,10 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * column; set the protocol to SCTP; and fill in the NAME column * with ASSOC, ASSOC-ID, ENDPT, LADDRS, LPORT, RADDRS and RPORT. */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, "SCTP"); - Lf->inp_ty = 2; - (void)snpf(tbuf, sizeof(tbuf), InodeFmt_d, (INODETYPE)s->st_ino); + Lf->type = LSOF_FILE_SOCKET; + Lf->iproto = LSOF_PROTOCOL_SCTP; + (void)snpf(tbuf, sizeof(tbuf), "%" INODEPSPEC "d", + (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); Namech[0] = '\0'; @@ -4231,10 +4229,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ return; } - if (ICMPpath) { - (void)get_icmp(ctx, ICMPpath); - (void)free((FREE_P *)ICMPpath); - ICMPpath = (char *)NULL; + if (!ctxd.icmp_valid) { + (void)get_icmp(ctx, PROCFS "/net/icmp"); + ctxd.icmp_valid = 1; } if ((ss & SB_INO) && (icmpp = check_icmp(ctx, (INODETYPE)s->st_ino))) { @@ -4244,9 +4241,9 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ * Set the type to "icmp" and store the type in the NAME * column. Save the inode number. */ - (void)snpf(Lf->type, sizeof(Lf->type), "icmp"); + Lf->type = LSOF_FILE_ICMP; Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; cp = Namech; nl = Namechl - 2; *cp = '\0'; @@ -4282,10 +4279,10 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ /* * The socket's protocol can't be identified. */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); + Lf->type = LSOF_FILE_SOCKET; if (ss & SB_INO) { Lf->inode = (INODETYPE)s->st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } if (ss & SB_DEV) { Lf->dev = s->st_dev; @@ -4308,55 +4305,29 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ } /* - * set_net_paths() - set /proc/net paths + * refresh_socket_info() - refresh socket info */ -void set_net_paths(struct lsof_context *ctx, /* context */ - char *p, /* path to /proc/net/ */ - int pl) /* strlen(p) */ -{ - int i; - int pathl; - - pathl = 0; - (void)make_proc_path(ctx, p, pl, &AX25path, &pathl, "ax25"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &ICMPpath, &pathl, "icmp"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &Ipxpath, &pathl, "ipx"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &Nlkpath, &pathl, "netlink"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &Packpath, &pathl, "packet"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &Rawpath, &pathl, "raw"); - for (i = 0; i < NSCTPPATHS; i++) { - pathl = 0; - (void)make_proc_path(ctx, p, pl, &SCTPPath[i], &pathl, SCTPSfx[i]); - } - pathl = 0; - (void)make_proc_path(ctx, p, pl, &SockStatPath, &pathl, "sockstat"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &TCPpath, &pathl, "tcp"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &UDPpath, &pathl, "udp"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &UDPLITEpath, &pathl, "udplite"); +void refresh_socket_info(struct lsof_context *ctx) { + /* Refresh socket info */ + ctxd.ax25_valid = 0; + ctxd.icmp_valid = 0; + ctxd.ipx_valid = 0; + ctxd.netlink_valid = 0; + ctxd.packet_valid = 0; + ctxd.raw_valid = 0; + ctxd.sctp_valid = 0; + ctxd.tcp_valid = 0; + ctxd.udp_valid = 0; + ctxd.udplite_valid = 0; #if defined(HASIPv6) - pathl = 0; - (void)make_proc_path(ctx, p, pl, &Raw6path, &pathl, "raw6"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &SockStatPath6, &pathl, "sockstat6"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &TCP6path, &pathl, "tcp6"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &UDP6path, &pathl, "udp6"); - pathl = 0; - (void)make_proc_path(ctx, p, pl, &UDPLITE6path, &pathl, "udplite6"); + ctxd.raw6_valid = 0; + ctxd.tcp6_valid = 0; + ctxd.udp6_valid = 0; + ctxd.udplite6_valid = 0; #endif /* defined(HASIPv6) */ - pathl = 0; - (void)make_proc_path(ctx, p, pl, &UNIXpath, &pathl, "unix"); + ctxd.unix_valid = 0; } /* @@ -4566,605 +4537,573 @@ static char *netlink_proto_to_str(unsigned int pr) { return cp; } -#if defined(HASSOSTATE) -/* - * socket_state_to_str() -- convert socket state number to a string - * - * returns "UNKNOWN" for unknown state. - */ -static char *socket_state_to_str(unsigned int ss) { - char *sr; - switch (Lf->lts.ss) { - case SS_UNCONNECTED: - sr = "UNCONNECTED"; - break; - case SS_CONNECTING: - sr = "CONNECTING"; - break; - case SS_CONNECTED: - sr = "CONNECTED"; - break; - case SS_DISCONNECTING: - sr = "DISCONNECTING"; - break; - default: - sr = "UNKNOWN"; - break; - } - return sr; -} -#endif /* defined(HASSOSTATE) */ - /* - * ethernet_proto_to_str() -- convert ethernet protocol number to a string - * - * The string should not exceed 7 characters. - * - * return NULL if the number is unknown. + * ethernet_proto_convert() -- convert ethernet protocol number to enum + * lsof_protocol */ -static char *ethernet_proto_to_str(unsigned int pr) { - char *cp = NULL; +static enum lsof_protocol ethernet_proto_convert(unsigned int pr) { + enum lsof_protocol cp = LSOF_PROTOCOL_UNKNOWN; switch (pr) { #if defined(ETH_P_LOOP) case ETH_P_LOOP: - cp = "LOOP"; + cp = LSOF_PROTOCOL_LOOP; break; #endif /* defined(ETH_P_LOOP) */ #if defined(ETH_P_PUP) case ETH_P_PUP: - cp = "PUP"; + cp = LSOF_PROTOCOL_PUP; break; #endif /* defined(ETH_P_PUP) */ #if defined(ETH_P_PUPAT) case ETH_P_PUPAT: - cp = "PUPAT"; + cp = LSOF_PROTOCOL_PUPAT; break; #endif /* defined(ETH_P_PUPAT) */ #if defined(ETH_P_TSN) case ETH_P_TSN: - cp = "TSN"; + cp = LSOF_PROTOCOL_TSN; break; #endif /* defined(ETH_P_TSN) */ #if defined(ETH_P_ERSPAN2) case ETH_P_ERSPAN2: - cp = "ERSPAN2"; + cp = LSOF_PROTOCOL_ERSPAN2; break; #endif /* defined(ETH_P_ERSPAN2) */ #if defined(ETH_P_IP) case ETH_P_IP: - cp = "IP"; + cp = LSOF_PROTOCOL_IP; break; #endif /* defined(ETH_P_IP) */ #if defined(ETH_P_X25) case ETH_P_X25: - cp = "X25"; + cp = LSOF_PROTOCOL_X25; break; #endif /* defined(ETH_P_X25) */ #if defined(ETH_P_ARP) case ETH_P_ARP: - cp = "ARP"; + cp = LSOF_PROTOCOL_ARP; break; #endif /* defined(ETH_P_ARP) */ #if defined(ETH_P_BPQ) case ETH_P_BPQ: - cp = "BPQ"; + cp = LSOF_PROTOCOL_BPQ; break; #endif /* defined(ETH_P_BPQ) */ #if defined(ETH_P_IEEEPUP) case ETH_P_IEEEPUP: - cp = "I3EPUP"; + cp = LSOF_PROTOCOL_IEEEPUP; break; #endif /* defined(ETH_P_IEEEPUP) */ #if defined(ETH_P_IEEEPUPAT) case ETH_P_IEEEPUPAT: - cp = "I3EPUPA"; + cp = LSOF_PROTOCOL_IEEEPUPAT; break; #endif /* defined(ETH_P_IEEEPUPAT) */ #if defined(ETH_P_BATMAN) case ETH_P_BATMAN: - cp = "BATMAN"; + cp = LSOF_PROTOCOL_BATMAN; break; #endif /* defined(ETH_P_BATMAN) */ #if defined(ETH_P_DEC) case ETH_P_DEC: - cp = "DEC"; + cp = LSOF_PROTOCOL_DEC; break; #endif /* defined(ETH_P_DEC) */ #if defined(ETH_P_DNA_DL) case ETH_P_DNA_DL: - cp = "DNA_DL"; + cp = LSOF_PROTOCOL_DNA_DL; break; #endif /* defined(ETH_P_DNA_DL) */ #if defined(ETH_P_DNA_RC) case ETH_P_DNA_RC: - cp = "DNA_RC"; + cp = LSOF_PROTOCOL_DNA_RC; break; #endif /* defined(ETH_P_DNA_RC) */ #if defined(ETH_P_DNA_RT) case ETH_P_DNA_RT: - cp = "DNA_RT"; + cp = LSOF_PROTOCOL_DNA_RT; break; #endif /* defined(ETH_P_DNA_RT) */ #if defined(ETH_P_LAT) case ETH_P_LAT: - cp = "LAT"; + cp = LSOF_PROTOCOL_LAT; break; #endif /* defined(ETH_P_LAT) */ #if defined(ETH_P_DIAG) case ETH_P_DIAG: - cp = "DIAG"; + cp = LSOF_PROTOCOL_DIAG; break; #endif /* defined(ETH_P_DIAG) */ #if defined(ETH_P_CUST) case ETH_P_CUST: - cp = "CUST"; + cp = LSOF_PROTOCOL_CUST; break; #endif /* defined(ETH_P_CUST) */ #if defined(ETH_P_SCA) case ETH_P_SCA: - cp = "SCA"; + cp = LSOF_PROTOCOL_SCA; break; #endif /* defined(ETH_P_SCA) */ #if defined(ETH_P_TEB) case ETH_P_TEB: - cp = "TEB"; + cp = LSOF_PROTOCOL_TEB; break; #endif /* defined(ETH_P_TEB) */ #if defined(ETH_P_RARP) case ETH_P_RARP: - cp = "RARP"; + cp = LSOF_PROTOCOL_RARP; break; #endif /* defined(ETH_P_RARP) */ #if defined(ETH_P_ATALK) case ETH_P_ATALK: - cp = "ATALK"; + cp = LSOF_PROTOCOL_ATALK; break; #endif /* defined(ETH_P_ATALK) */ #if defined(ETH_P_AARP) case ETH_P_AARP: - cp = "AARP"; + cp = LSOF_PROTOCOL_AARP; break; #endif /* defined(ETH_P_AARP) */ #if defined(ETH_P_8021Q) case ETH_P_8021Q: - cp = "8021Q"; + cp = LSOF_PROTOCOL_8021Q; break; #endif /* defined(ETH_P_8021Q) */ #if defined(ETH_P_ERSPAN) case ETH_P_ERSPAN: - cp = "ERSPAN"; + cp = LSOF_PROTOCOL_ERSPAN; break; #endif /* defined(ETH_P_ERSPAN) */ #if defined(ETH_P_IPX) case ETH_P_IPX: - cp = "IPX"; + cp = LSOF_PROTOCOL_IPX; break; #endif /* defined(ETH_P_IPX) */ #if defined(ETH_P_IPV6) case ETH_P_IPV6: - cp = "IPV6"; + cp = LSOF_PROTOCOL_IPV6; break; #endif /* defined(ETH_P_IPV6) */ #if defined(ETH_P_PAUSE) case ETH_P_PAUSE: - cp = "PAUSE"; + cp = LSOF_PROTOCOL_PAUSE; break; #endif /* defined(ETH_P_PAUSE) */ #if defined(ETH_P_SLOW) case ETH_P_SLOW: - cp = "SLOW"; + cp = LSOF_PROTOCOL_SLOW; break; #endif /* defined(ETH_P_SLOW) */ #if defined(ETH_P_WCCP) case ETH_P_WCCP: - cp = "WCCP"; + cp = LSOF_PROTOCOL_WCCP; break; #endif /* defined(ETH_P_WCCP) */ #if defined(ETH_P_MPLS_UC) case ETH_P_MPLS_UC: - cp = "MPLS_UC"; + cp = LSOF_PROTOCOL_MPLS_UC; break; #endif /* defined(ETH_P_MPLS_UC) */ #if defined(ETH_P_MPLS_MC) case ETH_P_MPLS_MC: - cp = "MPLS_MC"; + cp = LSOF_PROTOCOL_MPLS_MC; break; #endif /* defined(ETH_P_MPLS_MC) */ #if defined(ETH_P_ATMMPOA) case ETH_P_ATMMPOA: - cp = "ATMMPOA"; + cp = LSOF_PROTOCOL_ATMMPOA; break; #endif /* defined(ETH_P_ATMMPOA) */ #if defined(ETH_P_PPP_DISC) case ETH_P_PPP_DISC: - cp = "PPP_DIS"; + cp = LSOF_PROTOCOL_PPP_DISC; break; #endif /* defined(ETH_P_PPP_DISC) */ #if defined(ETH_P_PPP_SES) case ETH_P_PPP_SES: - cp = "PPP_SES"; + cp = LSOF_PROTOCOL_PPP_SES; break; #endif /* defined(ETH_P_PPP_SES) */ #if defined(ETH_P_LINK_CTL) case ETH_P_LINK_CTL: - cp = "LINKCTL"; + cp = LSOF_PROTOCOL_LINK_CTL; break; #endif /* defined(ETH_P_LINK_CTL) */ #if defined(ETH_P_ATMFATE) case ETH_P_ATMFATE: - cp = "ATMFATE"; + cp = LSOF_PROTOCOL_ATMFATE; break; #endif /* defined(ETH_P_ATMFATE) */ #if defined(ETH_P_PAE) case ETH_P_PAE: - cp = "PAE"; + cp = LSOF_PROTOCOL_PAE; break; #endif /* defined(ETH_P_PAE) */ #if defined(ETH_P_AOE) case ETH_P_AOE: - cp = "AOE"; + cp = LSOF_PROTOCOL_AOE; break; #endif /* defined(ETH_P_AOE) */ #if defined(ETH_P_8021AD) case ETH_P_8021AD: - cp = "8021AD"; + cp = LSOF_PROTOCOL_8021AD; break; #endif /* defined(ETH_P_8021AD) */ #if defined(ETH_P_802_EX1) case ETH_P_802_EX1: - cp = "802_EX1"; + cp = LSOF_PROTOCOL_802_EX1; break; #endif /* defined(ETH_P_802_EX1) */ #if defined(ETH_P_PREAUTH) case ETH_P_PREAUTH: - cp = "PREAUTH"; + cp = LSOF_PROTOCOL_PREAUTH; break; #endif /* defined(ETH_P_PREAUTH) */ #if defined(ETH_P_TIPC) case ETH_P_TIPC: - cp = "TIPC"; + cp = LSOF_PROTOCOL_TIPC; break; #endif /* defined(ETH_P_TIPC) */ #if defined(ETH_P_LLDP) case ETH_P_LLDP: - cp = "LLDP"; + cp = LSOF_PROTOCOL_LLDP; break; #endif /* defined(ETH_P_LLDP) */ #if defined(ETH_P_MRP) case ETH_P_MRP: - cp = "MRP"; + cp = LSOF_PROTOCOL_MRP; break; #endif /* defined(ETH_P_MRP) */ #if defined(ETH_P_MACSEC) case ETH_P_MACSEC: - cp = "MACSEC"; + cp = LSOF_PROTOCOL_MACSEC; break; #endif /* defined(ETH_P_MACSEC) */ #if defined(ETH_P_8021AH) case ETH_P_8021AH: - cp = "8021AH"; + cp = LSOF_PROTOCOL_8021AH; break; #endif /* defined(ETH_P_8021AH) */ #if defined(ETH_P_MVRP) case ETH_P_MVRP: - cp = "MVRP"; + cp = LSOF_PROTOCOL_MVRP; break; #endif /* defined(ETH_P_MVRP) */ #if defined(ETH_P_1588) case ETH_P_1588: - cp = "1588"; + cp = LSOF_PROTOCOL_1588; break; #endif /* defined(ETH_P_1588) */ #if defined(ETH_P_NCSI) case ETH_P_NCSI: - cp = "NCSI"; + cp = LSOF_PROTOCOL_NCSI; break; #endif /* defined(ETH_P_NCSI) */ #if defined(ETH_P_PRP) case ETH_P_PRP: - cp = "PRP"; + cp = LSOF_PROTOCOL_PRP; break; #endif /* defined(ETH_P_PRP) */ #if defined(ETH_P_FCOE) case ETH_P_FCOE: - cp = "FCOE"; + cp = LSOF_PROTOCOL_FCOE; break; #endif /* defined(ETH_P_FCOE) */ #if defined(ETH_P_IBOE) case ETH_P_IBOE: - cp = "IBOE"; + cp = LSOF_PROTOCOL_IBOE; break; #endif /* defined(ETH_P_IBOE) */ #if defined(ETH_P_TDLS) case ETH_P_TDLS: - cp = "TDLS"; + cp = LSOF_PROTOCOL_TDLS; break; #endif /* defined(ETH_P_TDLS) */ #if defined(ETH_P_FIP) case ETH_P_FIP: - cp = "FIP"; + cp = LSOF_PROTOCOL_FIP; break; #endif /* defined(ETH_P_FIP) */ #if defined(ETH_P_80221) case ETH_P_80221: - cp = "802.21"; + cp = LSOF_PROTOCOL_80221; break; #endif /* defined(ETH_P_80221) */ #if defined(ETH_P_HSR) case ETH_P_HSR: - cp = "HSR"; + cp = LSOF_PROTOCOL_HSR; break; #endif /* defined(ETH_P_HSR) */ #if defined(ETH_P_NSH) case ETH_P_NSH: - cp = "NSH"; + cp = LSOF_PROTOCOL_NSH; break; #endif /* defined(ETH_P_NSH) */ #if defined(ETH_P_LOOPBACK) case ETH_P_LOOPBACK: - cp = "LOOPBACK"; + cp = LSOF_PROTOCOL_LOOPBACK; break; #endif /* defined(ETH_P_LOOPBACK) */ #if defined(ETH_P_QINQ1) case ETH_P_QINQ1: - cp = "QINQ1"; + cp = LSOF_PROTOCOL_QINQ1; break; #endif /* defined(ETH_P_QINQ1) */ #if defined(ETH_P_QINQ2) case ETH_P_QINQ2: - cp = "QINQ2"; + cp = LSOF_PROTOCOL_QINQ2; break; #endif /* defined(ETH_P_QINQ2) */ #if defined(ETH_P_QINQ3) case ETH_P_QINQ3: - cp = "QINQ3"; + cp = LSOF_PROTOCOL_QINQ3; break; #endif /* defined(ETH_P_QINQ3) */ #if defined(ETH_P_EDSA) case ETH_P_EDSA: - cp = "EDSA"; + cp = LSOF_PROTOCOL_EDSA; break; #endif /* defined(ETH_P_EDSA) */ #if defined(ETH_P_DSA_8021Q) case ETH_P_DSA_8021Q: - cp = "DSAD1Q"; + cp = LSOF_PROTOCOL_DSA_8021Q; break; #endif /* defined(ETH_P_DSA_8021Q) */ #if defined(ETH_P_IFE) case ETH_P_IFE: - cp = "IFE"; + cp = LSOF_PROTOCOL_IFE; break; #endif /* defined(ETH_P_IFE) */ #if defined(ETH_P_AF_IUCV) case ETH_P_AF_IUCV: - cp = "AF_IUCV"; + cp = LSOF_PROTOCOL_AF_IUCV; break; #endif /* defined(ETH_P_AF_IUCV) */ #if defined(ETH_P_802_3) case ETH_P_802_3: - cp = "802.3"; + cp = LSOF_PROTOCOL_802_3; break; #endif /* defined(ETH_P_802_3) */ #if defined(ETH_P_AX25) case ETH_P_AX25: - cp = "AX25"; + cp = LSOF_PROTOCOL_AX25; break; #endif /* defined(ETH_P_AX25) */ #if defined(ETH_P_ALL) case ETH_P_ALL: - cp = "ALL"; + cp = LSOF_PROTOCOL_ALL; break; #endif /* defined(ETH_P_ALL) */ #if defined(ETH_P_802_2) case ETH_P_802_2: - cp = "802.2"; + cp = LSOF_PROTOCOL_802_2; break; #endif /* defined(ETH_P_802_2) */ #if defined(ETH_P_SNAP) case ETH_P_SNAP: - cp = "SNAP"; + cp = LSOF_PROTOCOL_SNAP; break; #endif /* defined(ETH_P_SNAP) */ #if defined(ETH_P_DDCMP) case ETH_P_DDCMP: - cp = "DDCMP"; + cp = LSOF_PROTOCOL_DDCMP; break; #endif /* defined(ETH_P_DDCMP) */ #if defined(ETH_P_WAN_PPP) case ETH_P_WAN_PPP: - cp = "WAN_PPP"; + cp = LSOF_PROTOCOL_WAN_PPP; break; #endif /* defined(ETH_P_WAN_PPP) */ #if defined(ETH_P_PPP_MP) case ETH_P_PPP_MP: - cp = "PPP MP"; + cp = LSOF_PROTOCOL_PPP_MP; break; #endif /* defined(ETH_P_PPP_MP) */ #if defined(ETH_P_LOCALTALK) case ETH_P_LOCALTALK: - cp = "LCLTALK"; + cp = LSOF_PROTOCOL_LOCALTALK; break; #endif /* defined(ETH_P_LOCALTALK) */ #if defined(ETH_P_CAN) case ETH_P_CAN: - cp = "CAN"; + cp = LSOF_PROTOCOL_CAN; break; #endif /* defined(ETH_P_CAN) */ #if defined(ETH_P_CANFD) case ETH_P_CANFD: - cp = "CANFD"; + cp = LSOF_PROTOCOL_CANFD; break; #endif /* defined(ETH_P_CANFD) */ #if defined(ETH_P_PPPTALK) case ETH_P_PPPTALK: - cp = "PPPTALK"; + cp = LSOF_PROTOCOL_PPPTALK; break; #endif /* defined(ETH_P_PPPTALK) */ #if defined(ETH_P_TR_802_2) case ETH_P_TR_802_2: - cp = "802.2"; + cp = LSOF_PROTOCOL_TR_802_2; break; #endif /* defined(ETH_P_TR_802_2) */ #if defined(ETH_P_MOBITEX) case ETH_P_MOBITEX: - cp = "MOBITEX"; + cp = LSOF_PROTOCOL_MOBITEX; break; #endif /* defined(ETH_P_MOBITEX) */ #if defined(ETH_P_CONTROL) case ETH_P_CONTROL: - cp = "CONTROL"; + cp = LSOF_PROTOCOL_CONTROL; break; #endif /* defined(ETH_P_CONTROL) */ #if defined(ETH_P_IRDA) case ETH_P_IRDA: - cp = "IRDA"; + cp = LSOF_PROTOCOL_IRDA; break; #endif /* defined(ETH_P_IRDA) */ #if defined(ETH_P_ECONET) case ETH_P_ECONET: - cp = "ECONET"; + cp = LSOF_PROTOCOL_ECONET; break; #endif /* defined(ETH_P_ECONET) */ #if defined(ETH_P_HDLC) case ETH_P_HDLC: - cp = "HDLC"; + cp = LSOF_PROTOCOL_HDLC; break; #endif /* defined(ETH_P_HDLC) */ #if defined(ETH_P_ARCNET) case ETH_P_ARCNET: - cp = "ARCNET"; + cp = LSOF_PROTOCOL_ARCNET; break; #endif /* defined(ETH_P_ARCNET) */ #if defined(ETH_P_DSA) case ETH_P_DSA: - cp = "DSA"; + cp = LSOF_PROTOCOL_DSA; break; #endif /* defined(ETH_P_DSA) */ #if defined(ETH_P_TRAILER) case ETH_P_TRAILER: - cp = "TRAILER"; + cp = LSOF_PROTOCOL_TRAILER; break; #endif /* defined(ETH_P_TRAILER) */ #if defined(ETH_P_PHONET) case ETH_P_PHONET: - cp = "PHONET"; + cp = LSOF_PROTOCOL_PHONET; break; #endif /* defined(ETH_P_PHONET) */ #if defined(ETH_P_IEEE802154) case ETH_P_IEEE802154: - cp = "802154"; + cp = LSOF_PROTOCOL_IEEE802154; break; #endif /* defined(ETH_P_IEEE802154) */ #if defined(ETH_P_CAIF) case ETH_P_CAIF: - cp = "CAIF"; + cp = LSOF_PROTOCOL_CAIF; break; #endif /* defined(ETH_P_CAIF) */ #if defined(ETH_P_XDSA) case ETH_P_XDSA: - cp = "XDSA"; + cp = LSOF_PROTOCOL_XDSA; break; #endif /* defined(ETH_P_XDSA) */ #if defined(ETH_P_MAP) case ETH_P_MAP: - cp = "MAP"; + cp = LSOF_PROTOCOL_MAP; break; #endif /* defined(ETH_P_MAP) */ default: - cp = NULL; + cp = LSOF_PROTOCOL_UNKNOWN; break; } return cp; diff --git a/lib/dialects/linux/dstore.c b/lib/dialects/linux/dstore.c index 9cea7d46..8acf666f 100644 --- a/lib/dialects/linux/dstore.c +++ b/lib/dialects/linux/dstore.c @@ -30,23 +30,6 @@ #include "common.h" -int HasNFS = 0; /* NFS mount point status: - * 1 == there is an NFS mount point, - * but its device number is - * unknown - * 2 == there is an NFS mount point - * and its device number is - * known - */ -dev_t MqueueDev = -1; /* The number for the device behind - * mqueue mount point */ -/* offset type: - * 0 == unknown - * 1 == lstat's st_size - * 2 == from /proc//fdinfo - */ -int OffType = OFFSET_UNKNOWN; - /* * Pff_tab[] - table for printing file flags */ diff --git a/lib/dialects/linux/machine.h b/lib/dialects/linux/machine.h index fd9793b7..eafbc508 100644 --- a/lib/dialects/linux/machine.h +++ b/lib/dialects/linux/machine.h @@ -135,7 +135,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ /* #define HASFSINO 1 */ @@ -145,7 +145,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -341,14 +341,6 @@ /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -507,7 +499,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -545,6 +537,7 @@ /* #define USE_LIB_PRINT_TCPTPI 1 ptti.c */ /* #define USE_LIB_READDEV 1 rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ /* #define USE_LIB_RNCH 1 rnch.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ diff --git a/lib/dialects/netbsd/dlsof.h b/lib/dialects/netbsd/dlsof.h index c82fc95b..4d966011 100644 --- a/lib/dialects/netbsd/dlsof.h +++ b/lib/dialects/netbsd/dlsof.h @@ -457,10 +457,6 @@ typedef u_long KA_T; * Global storage definitions (including their structure definitions) */ -extern struct file *Cfp; -extern kvm_t *Kd; -extern KA_T Kpa; - struct l_vfs { KA_T addr; /* kernel address */ fsid_t fsid; /* file system ID */ @@ -475,7 +471,6 @@ struct l_vfs { char *fsname; /* file system name */ struct l_vfs *next; /* forward link */ }; -extern struct l_vfs *Lvfs; struct mounts { char *dir; /* directory (mounted on) */ @@ -495,14 +490,6 @@ struct mounts { # define X_NCSIZE "ncsize" # define NL_NAME n_name -extern int Np; /* number of kernel processes */ - -# if defined(HASKVMGETPROC2) -struct kinfo_proc2 *P; /* local process table copy */ -# else /* ! defined(HASKVMGETPROC2) */ -struct kinfo_proc *P; /* local process table copy */ -# endif /* defined(HASKVMGETPROC2) */ - extern int pgshift; /* kernel's page shift */ struct sfile { @@ -568,4 +555,32 @@ struct sfile { # define NCACHE_VROOT VROOT # endif /* VV_ROOT */ +struct lsof_context_dialect { + /* local vfs structure table */ + struct l_vfs *local_vfs; + /* kvm descriptor */ + kvm_t *kvm; + /* current file's file struct pointer */ + struct file *cur_file; + + /* number of kernel processes */ + int num_procs; +# if defined(HASKVMGETPROC2) + /* local process table copy */ + struct kinfo_proc2 *procs; +# else /* !defined(HASKVMGETPROC2) */ + /* local process table copy */ + struct kinfo_proc *procs; +# endif /* defined(HASKVMGETPROC2) */ + + /* kernel proc struct address */ + KA_T kernel_proc_addr; +}; +# define Lvfs (ctxd.local_vfs) +# define Kd (ctxd.kvm) +# define Cfp (ctxd.cur_file) +# define P (ctxd.procs) +# define Np (ctxd.num_procs) +# define Kpa (ctxd.kernel_proc_addr) + #endif /* NETBSD_LSOF_H */ diff --git a/lib/dialects/netbsd/dmnt.c b/lib/dialects/netbsd/dmnt.c index 7ff0e024..6659b804 100644 --- a/lib/dialects/netbsd/dmnt.c +++ b/lib/dialects/netbsd/dmnt.c @@ -60,9 +60,6 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ @@ -90,7 +87,8 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Access mount information. */ if ((n = getmntinfo(&mb, MNT_NOWAIT)) <= 0) { - (void)fprintf(stderr, "%s: no mount information\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no mount information\n", Pn); return (0); } /* @@ -114,16 +112,18 @@ struct mounts *readmnt(struct lsof_context *ctx) { no_space_for_mount: - (void)fprintf(stderr, "%s: no space for mount at ", Pn); - safestrprt(mb->f_mntonname, stderr, 0); - (void)fprintf(stderr, " ("); - safestrprt(mb->f_mntfromname, stderr, 0); - (void)fprintf(stderr, ")\n"); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for mount at ", Pn); + safestrprt(mb->f_mntonname, ctx->err, 0); + (void)fprintf(ctx->err, " ("); + safestrprt(mb->f_mntfromname, ctx->err, 0); + (void)fprintf(ctx->err, ")\n"); + } Error(ctx); } if ((ln = Readlink(ctx, dn)) == NULL) { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } continue; @@ -138,12 +138,12 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Stat() the directory. */ if (statsafely(ctx, dn, &sb)) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: can't stat() ", Pn); - safestrprt(mb->f_fstypename, stderr, 0); - (void)fprintf(stderr, " file system "); - safestrprt(mb->f_mntonname, stderr, 1); - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: can't stat() ", Pn); + safestrprt(mb->f_fstypename, ctx->err, 0); + (void)fprintf(ctx->err, " file system "); + safestrprt(mb->f_mntonname, ctx->err, 1); + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } (void)bzero((char *)&sb, sizeof(sb)); @@ -155,8 +155,8 @@ struct mounts *readmnt(struct lsof_context *ctx) { #endif /* defined(HASSTATVFS) */ sb.st_mode = S_IFDIR | 0777; - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, " assuming \"dev=%x\" from mount table\n", sb.st_dev); } @@ -220,7 +220,7 @@ struct mounts *readmnt(struct lsof_context *ctx) { * readvfs() - read vfs structure */ -struct l_vfs *readvfs(struct lsof_context *ctx, /* context */ +struct l_vfs *readvfs(struct lsof_context *ctx, KA_T vm) /* kernel mount address from vnode */ { struct mount m; @@ -238,13 +238,16 @@ struct l_vfs *readvfs(struct lsof_context *ctx, /* context */ if (kread(ctx, vm, (char *)&m, sizeof(m)) != 0) return ((struct l_vfs *)NULL); if (!(vp = (struct l_vfs *)malloc(sizeof(struct l_vfs)))) { - (void)fprintf(stderr, "%s: PID %d, no space for vfs\n", Pn, Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, "%s: PID %d, no space for vfs\n", Pn, + Lp->pid); Error(ctx); } if (!(vp->dir = mkstrcpy(m.m_stat.f_mntonname, (MALLOC_S *)NULL)) || !(vp->fsname = mkstrcpy(m.m_stat.f_mntfromname, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: PID %d, no space for mount names\n", Pn, - Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, "%s: PID %d, no space for mount names\n", + Pn, Lp->pid); Error(ctx); } vp->addr = vm; diff --git a/lib/dialects/netbsd/dnode.c b/lib/dialects/netbsd/dnode.c index bb6c0ac5..e4913a7f 100644 --- a/lib/dialects/netbsd/dnode.c +++ b/lib/dialects/netbsd/dnode.c @@ -65,8 +65,7 @@ static void getmemsz(struct lsof_context *ctx, pid_t pid); * getmemsz() - get memory size of a /proc//mem entry */ -static void getmemsz(struct lsof_context *ctx, pid_t pid) -{ +static void getmemsz(struct lsof_context *ctx, pid_t pid) { int n; struct vmspace vm; @@ -95,7 +94,7 @@ static void getmemsz(struct lsof_context *ctx, pid_t pid) * lkup_dev_tty() - look up /dev/tty */ -static int lkup_dev_tty(struct lsof_context *ctx, /* context */ +static int lkup_dev_tty(struct lsof_context *ctx, dev_t *dr, /* place to return device number */ INODETYPE *ir) /* place to return inode number */ { @@ -143,11 +142,10 @@ static int lkup_dev_tty(struct lsof_context *ctx, /* context */ * require a dfile.c, so this is the next best location for the function. */ -void process_kqueue(struct lsof_context *ctx, /* context */ +void process_kqueue(struct lsof_context *ctx, KA_T ka) /* kqueue file structure address */ { - - (void)snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); + Lf->type = LSOF_FILE_KQUEUE; enter_dev_ch(ctx, print_kptr(ka, (char *)NULL, 0)); } #endif /* defined(HASKQUEUE) */ @@ -156,15 +154,15 @@ void process_kqueue(struct lsof_context *ctx, /* context */ * process_node() - process vnode */ -void process_node(struct lsof_context *ctx, /* context */ - KA_T va) /* vnode kernel space address */ +void process_node(struct lsof_context *ctx, + KA_T va) /* vnode kernel space address */ { dev_t dev, rdev; unsigned char devs; unsigned char lt; unsigned char ns; unsigned char rdevs; - char *ep, *ty; + char *ep; #if defined(HAS_LOCKF_H) struct lockf lf, *lff, *lfp; #endif @@ -441,7 +439,7 @@ void process_node(struct lsof_context *ctx, /* context */ ksb.st_ino = (ino_t)2; ksb.st_size = DEV_BSIZE; ksbs = 1; - } else if (Namech[0] && statsafely(Namech, &ksb) == 0) + } else if (Namech[0] && statsafely(ctx, Namech, &ksb) == 0) ksbs = 1; nty = KERNFSNODE; break; @@ -653,11 +651,13 @@ void process_node(struct lsof_context *ctx, /* context */ else lt = 0; if (lf.lf_type == F_RDLCK) - Lf->lock = lt ? 'R' : 'r'; + Lf->lock = + lt ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL; else if (lf.lf_type == F_WRLCK) - Lf->lock = lt ? 'W' : 'w'; + Lf->lock = + lt ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL; else if (lf.lf_type == (F_RDLCK | F_WRLCK)) - Lf->lock = 'u'; + Lf->lock = LSOF_LOCK_READ_WRITE; break; } while ((lfp = lf.lf_next) && lfp != lff); } @@ -700,8 +700,9 @@ void process_node(struct lsof_context *ctx, /* context */ if (f_tty_s == 1) { dev = DevDev; rdev = f_tty_dev; + devs = rdevs = 1; Lf->inode = f_tty_ino; - devs = Lf->inp_ty = rdevs = 1; + Lf->inode_def = 1; } } break; @@ -847,7 +848,7 @@ void process_node(struct lsof_context *ctx, /* context */ nn += (INODETYPE)(d.de_diroffset / sizeof(struct direntry)); } Lf->inode = nn; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HASMSDOSFS) */ @@ -858,14 +859,14 @@ void process_node(struct lsof_context *ctx, /* context */ case INODE: Lf->inode = (INODETYPE)i.i_number; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if defined(HASKERNFS) case KERNFSNODE: if (ksbs) { Lf->inode = (INODETYPE)ksb.st_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HASKERNFS) */ @@ -874,20 +875,20 @@ void process_node(struct lsof_context *ctx, /* context */ case CDFSNODE: if (iso_stat) { Lf->inode = iso_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HAS9660FS) */ case NFSNODE: Lf->inode = (INODETYPE)NVATTR.va_fileid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if defined(HASPROCFS) case PFSNODE: Lf->inode = (INODETYPE)p.pfs_fileno; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #endif /* defined(HASPROCFS) */ @@ -900,14 +901,14 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->inode = (INODETYPE)(pt.ptyfs_fileno - 1); } else Lf->inode = (INODETYPE)pt.ptyfs_fileno; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #endif /* defined(HASPTYFS) */ #if defined(HASTMPFS) case TMPFSNODE: Lf->inode = (INODETYPE)tmp.tn_id; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #endif /* defined(HASTMPFS) */ } @@ -915,7 +916,9 @@ void process_node(struct lsof_context *ctx, /* context */ /* * Obtain the file size. */ + Lf->off_def = 1; switch (Ntype) { + #if defined(HAS9660FS) case N_CDFS: if (iso_stat) { @@ -926,6 +929,7 @@ void process_node(struct lsof_context *ctx, /* context */ #endif /* defined(HAS9660FS) */ case N_FIFO: + Lf->off_def = 1; break; #if defined(HASKERNFS) @@ -1042,7 +1046,8 @@ void process_node(struct lsof_context *ctx, /* context */ break; #endif /* defined(HASEXT2FS) */ } - } + } else if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; break; } /* @@ -1169,45 +1174,42 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->rdev_def = rdevs; switch (type) { case VNON: - ty = "VNON"; + Lf->type = LSOF_FILE_VNODE_VNON; break; case VREG: - ty = "VREG"; + Lf->type = LSOF_FILE_VNODE_VREG; break; case VDIR: - ty = "VDIR"; + Lf->type = LSOF_FILE_VNODE_VDIR; break; case VBLK: - ty = "VBLK"; + Lf->type = LSOF_FILE_VNODE_VBLK; Ntype = N_BLK; break; case VCHR: - ty = "VCHR"; + Lf->type = LSOF_FILE_VNODE_VCHR; Ntype = N_CHR; break; case VLNK: - ty = "VLNK"; + Lf->type = LSOF_FILE_VNODE_VLNK; break; #if defined(VSOCK) case VSOCK: - ty = "SOCK"; + Lf->type = LSOF_FILE_VNODE_VSOCK; break; #endif /* defined(VSOCK) */ case VBAD: - ty = "VBAD"; + Lf->type = LSOF_FILE_VNODE_VBAD; break; case VFIFO: - ty = "FIFO"; + Lf->type = LSOF_FILE_VNODE_VFIFO; break; default: - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); - ty = NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = type; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); - Lf->ntype = Ntype; /* * Handle some special cases: * @@ -1229,93 +1231,90 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HASPROCFS) else if (nty == PFSNODE) { Lf->dev_def = Lf->rdev_def = 0; - ty = NULL; (void)snpf(Namech, Namechl, "/%s", HASPROCFS); switch (p.pfs_type) { case Proot: - ty = "PDIR"; + Lf->type = LSOF_FILE_PROC_DIR; break; case Pcurproc: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/curproc"); - ty = "PCUR"; + Lf->type = LSOF_FILE_PROC_CUR_PROC; break; case Pproc: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d", p.pfs_pid); - ty = "PDIR"; + Lf->type = LSOF_FILE_PROC_PID; break; case Pfile: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d/file", p.pfs_pid); - ty = "PFIL"; + Lf->type = LSOF_FILE_PROC_FILE; break; case Pmem: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d/mem", p.pfs_pid); - ty = "PMEM"; + Lf->type = LSOF_FILE_PROC_MEMORY; break; case Pregs: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d/regs", p.pfs_pid); - ty = "PREG"; + Lf->type = LSOF_FILE_PROC_REGS; break; case Pfpregs: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d/fpregs", p.pfs_pid); - ty = "PFPR"; + Lf->type = LSOF_FILE_PROC_FP_REGS; break; # if defined(Pctl) case Pctl: - ep = endnm(ctx, &sz); + ep = endnm(&sz); (void)snpf(ep, sz, "/%d/ctl", p.pfs_pid); - ty = "PCTL"; + Lf->type = LSOF_FILE_PROC_CTRL; break; # endif /* defined(Pctl) */ case Pstatus: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d/status", p.pfs_pid); - ty = "PSTA"; + Lf->type = LSOF_FILE_PROC_STATUS; break; case Pnote: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d/note", p.pfs_pid); - ty = "PNTF"; + Lf->type = LSOF_FILE_PROC_PROC_NOTIFIER; break; case Pnotepg: ep = endnm(ctx, &sz); (void)snpf(ep, sz, "/%d/notepg", p.pfs_pid); - ty = "PGID"; + Lf->type = LSOF_FILE_PROC_GROUP_NOTIFIER; break; # if defined(Pfd) case Pfd: - ep = endnm(ctx, &sz); + ep = endnm(&sz); (void)snpf(ep, sz, "/%d/fd", p.pfs_pid); - ty = "PFD"; + Lf->type = LSOF_FILE_PROC_FD_DIR; break; # endif /* defined(Pfd) */ # if defined(Pmap) case Pmap: - ep = endnm(ctx, &sz); + ep = endnm(&sz); (void)snpf(ep, sz, "/%d/map", p.pfs_pid); - ty = "PMAP"; + Lf->type = LSOF_FILE_PROC_MAP; break; # endif /* defined(Pmap) */ # if defined(Pmaps) case Pmaps: - ep = endnm(ctx, &sz); + ep = endnm(&sz); (void)snpf(ep, sz, "/%d/maps", p.pfs_pid); - ty = "PMPS"; + Lf->type = LSOF_FILE_PROC_MAPS; break; # endif /* defined(Pmaps) */ } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), ty); } #endif /* defined(HASPROCFS) */ @@ -1338,8 +1337,6 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->sz_def = 1; break; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), ty); } #endif /* defined(HASPTYFS) */ @@ -1348,7 +1345,7 @@ void process_node(struct lsof_context *ctx, /* context */ * If this is a VBLK file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VBLK)) + if (!Lf->inode_def && (type == VBLK)) find_bl_ino(ctx); #endif /* defined(HASBLKDEV) */ @@ -1356,7 +1353,7 @@ void process_node(struct lsof_context *ctx, /* context */ * If this is a VCHR file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VCHR)) + if (!Lf->inode_def && (type == VCHR)) find_ch_ino(ctx); /* * Test for specified file. @@ -1372,7 +1369,7 @@ void process_node(struct lsof_context *ctx, /* context */ if ((pfi->pid && pfi->pid == p.pfs_pid) # if defined(HASPINODEN) - || ((Lf->inp_ty == 1) && (pfi->inode == Lf->inode)) + || (Lf->inode_def && (pfi->inode == Lf->inode)) # endif /* defined(HASPINODEN) */ ) { @@ -1413,8 +1410,8 @@ void process_node(struct lsof_context *ctx, /* context */ * process_pipe() - process a file structure whose type is DTYPE_PIPE */ -void process_pipe(struct lsof_context *ctx, /* context */ - KA_T pa) /* pipe structure kernel address */ +void process_pipe(struct lsof_context *ctx, + KA_T pa) /* pipe structure kernel address */ { char *ep; struct pipe p; @@ -1426,8 +1423,9 @@ void process_pipe(struct lsof_context *ctx, /* context */ enter_nm(ctx, Namech); return; } - (void)snpf(Lf->type, sizeof(Lf->type), "PIPE"); + Lf->type = LSOF_FILE_PIPE; enter_dev_ch(ctx, print_kptr(pa, (char *)NULL, 0)); + Lf->off_def = 1; Lf->sz = (SZOFFTYPE)p.pipe_buffer.size; Lf->sz_def = 1; if (p.pipe_peer) diff --git a/lib/dialects/netbsd/dnode1.c b/lib/dialects/netbsd/dnode1.c index 71825309..7eaf948f 100644 --- a/lib/dialects/netbsd/dnode1.c +++ b/lib/dialects/netbsd/dnode1.c @@ -71,12 +71,12 @@ static char copyright[] = * read_iso_node() -- read CD 9660 iso_node */ -int read_iso_node(struct lsof_context *ctx, /* context */ - struct vnode *v, /* containing vnode */ - dev_t *d, /* returned device number */ - INODETYPE *ino, /* returned inode number */ - long *nl, /* returned link count */ - SZOFFTYPE *sz) /* returned size */ +int read_iso_node(struct lsof_context *ctx, + struct vnode *v, /* containing vnode */ + dev_t *d, /* returned device number */ + INODETYPE *ino, /* returned inode number */ + long *nl, /* returned link count */ + SZOFFTYPE *sz) /* returned size */ { struct iso_node i; diff --git a/lib/dialects/netbsd/dproc.c b/lib/dialects/netbsd/dproc.c index 07fc0693..b0988892 100644 --- a/lib/dialects/netbsd/dproc.c +++ b/lib/dialects/netbsd/dproc.c @@ -78,11 +78,10 @@ static KA_T *Vp = NULL; /* vnode address cache */ * ckkv - check kernel version */ -void ckkv(struct lsof_context *ctx, /* context */ - char *d, /* dialect */ - char *er, /* expected release */ - char *ev, /* expected version */ - char *ea) /* expected architecture */ +void ckkv(struct lsof_context *ctx, char *d, /* dialect */ + char *er, /* expected release */ + char *ev, /* expected version */ + char *ea) /* expected architecture */ { #if defined(HASKERNIDCK) @@ -99,17 +98,21 @@ void ckkv(struct lsof_context *ctx, /* context */ m[1] = KERN_OSRELEASE; l = sizeof(v); if (sysctl(m, 2, v, &l, NULL, 0) < 0) { - (void)fprintf(stderr, "%s: CTL_KERN, KERN_OSRELEASE: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: CTL_KERN, KERN_OSRELEASE: %s\n", Pn, + strerror(errno)); Error(ctx); } /* * Warn if the actual and expected releases don't match. */ - if (!er || strcmp(v, er)) - (void)fprintf(stderr, - "%s: WARNING: compiled for %s release %s; this is %s.\n", - Pn, d, er ? er : "UNKNOWN", v); + if (!er || strcmp(v, er)) { + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: WARNING: compiled for %s release %s; this is %s.\n", Pn, d, + er ? er : "UNKNOWN", v); + } #endif /* defined(HASKERNIDCK) */ } @@ -117,9 +120,8 @@ void ckkv(struct lsof_context *ctx, /* context */ * enter_vn_text() - enter a vnode text reference */ -static void enter_vn_text(struct lsof_context *ctx, /* context */ - KA_T va, /* vnode address */ - int *n) /* Vp[] entries in use */ +static void enter_vn_text(struct lsof_context *ctx, KA_T va, /* vnode address */ + int *n) /* Vp[] entries in use */ { int i; /* @@ -132,7 +134,7 @@ static void enter_vn_text(struct lsof_context *ctx, /* context */ /* * Save the text file information. */ - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); Cfp = (struct file *)NULL; process_node(ctx, (KA_T)va); if (Lf->sf) @@ -147,8 +149,8 @@ static void enter_vn_text(struct lsof_context *ctx, /* context */ Vp = (KA_T *)malloc((MALLOC_S)(sizeof(struct vnode *) * 10)); else Vp = (KA_T *)realloc((MALLOC_P *)Vp, (MALLOC_S)(Nv * sizeof(KA_T))); - if (!Vp) { - (void)fprintf(stderr, "%s: no txt ptr space, PID %d\n", Pn, + if (!Vp && ctx->err) { + (void)fprintf(ctx->err, "%s: no txt ptr space, PID %d\n", Pn, Lp->pid); Error(ctx); } @@ -203,14 +205,17 @@ void gather_proc_info(struct lsof_context *ctx) { * Read the process table. */ + if (!Kd) + return; + #if defined(HASKVMGETPROC2) P = kvm_getproc2(Kd, KERN_PROC_ALL, 0, KVMPROCSZ2, &Np); #else /* !defined(HASKVMGETPROC2) */ P = kvm_getprocs(Kd, KERN_PROC_ALL, 0, &Np); #endif /* defined(HASKVMGETPROC2) */ - if (!P) { - (void)fprintf(stderr, "%s: can't read process table: %s\n", Pn, + if (!P && ctx->err) { + (void)fprintf(ctx->err, "%s: can't read process table: %s\n", Pn, kvm_geterr(Kd)); Error(ctx); } @@ -263,7 +268,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Save current working directory information. */ if (CDIR) { - alloc_lfile(ctx, CWD, -1); + alloc_lfile(ctx, LSOF_FD_CWD, -1); Cfp = (struct file *)NULL; process_node(ctx, (KA_T)CDIR); if (Lf->sf) @@ -273,7 +278,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Save root directory information. */ if (RDIR) { - alloc_lfile(ctx, RTD, -1); + alloc_lfile(ctx, LSOF_FD_ROOT_DIR, -1); Cfp = (struct file *)NULL; process_node(ctx, (KA_T)RDIR); if (Lf->sf) @@ -296,8 +301,8 @@ void gather_proc_info(struct lsof_context *ctx) { ofb = (FILESTRUCT **)malloc(nb); else ofb = (FILESTRUCT **)realloc((MALLOC_P *)ofb, nb); - if (!ofb) { - (void)fprintf(stderr, "%s: PID %d, no file * space\n", Pn, + if (!ofb && ctx->err) { + (void)fprintf(ctx->err, "%s: PID %d, no file * space\n", Pn, p->P_PID); Error(ctx); } @@ -313,8 +318,8 @@ void gather_proc_info(struct lsof_context *ctx) { pof = (char *)malloc(nb); else pof = (char *)realloc((MALLOC_P *)pof, nb); - if (!pof) { - (void)fprintf(stderr, "%s: PID %d, no file flag space\n", Pn, + if (!pof && ctx->err) { + (void)fprintf(ctx->err, "%s: PID %d, no file flag space\n", Pn, p->P_PID); Error(ctx); } @@ -343,7 +348,7 @@ void gather_proc_info(struct lsof_context *ctx) { #else /* ! HAVE_STRUCT_FDFILE */ Cfp = ofb[i]; #endif /* ! HAVE_STRUCT_FDFILE */ - alloc_lfile(ctx, NULL, i); + alloc_lfile(ctx, LSOF_FD_NUMERIC, i); process_file(ctx, (KA_T)Cfp); if (Lf->sf) { @@ -383,8 +388,11 @@ static void get_kernel_access(struct lsof_context *ctx) { #else /* !defined(N_UNIX) */ { if (!(Nmlst = get_nlist_path(ctx, 1))) { - (void)fprintf(stderr, "%s: can't get kernel name list path\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't get kernel name list path\n", + Pn); Error(ctx); + return; } } #endif /* defined(N_UNIX) */ @@ -400,33 +408,40 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * See if the non-KMEM memory and name list files are readable. */ - if ((Memory && !is_readable(Memory, 1)) || - (Nmlst && !is_readable(Nmlst, 1))) + if ((Memory && !is_readable(ctx, Memory, 1)) || + (Nmlst && !is_readable(ctx, Nmlst, 1))) { Error(ctx); + return; + } #endif /* defined(WILLDROPGID) */ /* * Open kernel memory access. */ if ((Kd = kvm_openfiles(Nmlst, Memory, NULL, O_RDONLY, NULL)) == NULL) { - (void)fprintf(stderr, - "%s: kvm_openfiles(execfile=%s, corefile=%s): %s\n", Pn, - Nmlst, - Memory ? Memory : + if (ctx->err) + (void)fprintf(ctx->err, + "%s: kvm_openfiles(execfile=%s, corefile=%s): %s\n", + Pn, Nmlst, + Memory ? Memory : #if defined(_PATH_MEM) - _PATH_MEM, + _PATH_MEM, #else /* !defined(_PATH_MEM) */ - "default", + "default", #endif /* defined(_PATH_MEM) */ - strerror(errno)); + strerror(errno)); Error(ctx); + return; } (void)build_Nl(ctx, Drive_Nl); if (kvm_nlist(Kd, Nl) < 0) { - (void)fprintf(stderr, "%s: can't read namelist from %s\n", Pn, Nmlst); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't read namelist from %s\n", Pn, + Nmlst); Error(ctx); + return; } #if defined(WILLDROPGID) @@ -440,7 +455,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * Read the kernel's page shift amount, if possible. */ - if (get_Nl_value("pgshift", Drive_Nl, &v) < 0 || !v || + if (get_Nl_value(ctx, "pgshift", Drive_Nl, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&pgshift, sizeof(pgshift))) pgshift = 0; } @@ -450,7 +465,7 @@ static void get_kernel_access(struct lsof_context *ctx) { * get_nlist_path() - get kernel name list path */ -char *get_nlist_path(struct lsof_context *ctx, /* context */ +char *get_nlist_path(struct lsof_context *ctx, int ap) /* on success, return an allocated path * string pointer if 1; return a * constant character pointer if 0; @@ -467,9 +482,11 @@ char *get_nlist_path(struct lsof_context *ctx, /* context */ return (""); bfl = (MALLOC_S)(strlen(bf) + 1); if (!(bfc = (char *)malloc(bfl))) { - (void)fprintf( - stderr, "%s: can't allocate %d bytes for boot file path: %s\n", - Pn, bfl, bf); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes for boot file path: %s\n", Pn, + bfl, bf); Error(ctx); } (void)snpf(bfc, bfl, "%s", bf); @@ -485,14 +502,33 @@ char *get_nlist_path(struct lsof_context *ctx, /* context */ void initialize(struct lsof_context *ctx) { get_kernel_access(ctx); } +/* + * deinitialize() - perform all cleanup + */ +void deinitialize(struct lsof_context *ctx) { + /* Free Lvfs */ + struct l_vfs *vp, *vp_next; + for (vp = Lvfs; vp; vp = vp_next) { + vp_next = vp->next; + CLEAN(vp->dir); + CLEAN(vp->fsname); + CLEAN(vp); + } + Lvfs = NULL; + + if (Kd) { + kvm_close(Kd); + Kd = NULL; + } +} + /* * kread() - read from kernel memory */ -int kread(struct lsof_context *ctx, /* context */ - KA_T addr, /* kernel memory address */ - char *buf, /* buffer to receive data */ - READLEN_T len) /* length to read */ +int kread(struct lsof_context *ctx, KA_T addr, /* kernel memory address */ + char *buf, /* buffer to receive data */ + READLEN_T len) /* length to read */ { int br; @@ -503,8 +539,8 @@ int kread(struct lsof_context *ctx, /* context */ /* * process_text() - process text information */ -void process_text(struct lsof_context *ctx, /* context */ - KA_T vm) /* kernel vm space pointer */ +void process_text(struct lsof_context *ctx, + KA_T vm) /* kernel vm space pointer */ { int i, j; KA_T ka; diff --git a/lib/dialects/netbsd/dproto.h b/lib/dialects/netbsd/dproto.h index 897b1559..ef0841aa 100644 --- a/lib/dialects/netbsd/dproto.h +++ b/lib/dialects/netbsd/dproto.h @@ -35,11 +35,11 @@ */ #if !defined(N_UNIX) -extern char *get_nlist_path(struct lsof_context *ctx, int ap); +extern char *get_nlist_path(struct lsof_context * ctx, int ap); #endif /* !defined(N_UNIX) */ extern int is_file_named(struct lsof_context *ctx, char *p, int cd); -extern struct l_vfs *readvfs(struct lsof_context *ctx, KA_T vm); +extern struct l_vfs *readvfs(struct lsof_context * ctx, KA_T vm); #if defined(HAS_SYS_PIPEH) extern void process_pipe(struct lsof_context *ctx, KA_T pa); diff --git a/lib/dialects/netbsd/dsock.c b/lib/dialects/netbsd/dsock.c index 79977c45..3c937dd1 100644 --- a/lib/dialects/netbsd/dsock.c +++ b/lib/dialects/netbsd/dsock.c @@ -49,8 +49,8 @@ static char copyright[] = * process_socket() - process socket */ -void process_socket(struct lsof_context *ctx, /* context */ - KA_T sa) /* socket address in kernel */ +void process_socket(struct lsof_context *ctx, + KA_T sa) /* socket address in kernel */ { #if NETBSDV >= 9099104 # define NETBSD_MERGED_INPCB @@ -92,8 +92,7 @@ void process_socket(struct lsof_context *ctx, /* context */ struct mbuf mb; #endif /* defined(UNPADDR_IN_MBUF) */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); - Lf->inp_ty = 2; + Lf->type = LSOF_FILE_SOCKET; /* * Read the socket, protocol, and domain structures. */ @@ -133,6 +132,7 @@ void process_socket(struct lsof_context *ctx, /* context */ else Lf->sz = (SZOFFTYPE)(s.so_rcv.sb_cc + s.so_snd.sb_cc); Lf->sz_def = 1; + Lf->off_def = 1; #if defined(HASTCPTPIQ) Lf->lts.rq = s.so_rcv.sb_cc; @@ -170,22 +170,15 @@ void process_socket(struct lsof_context *ctx, /* context */ #endif /* defined(HASIPv6) */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (fam == AF_INET)) - -#if defined(HASIPv6) - || ((FnetTy == 6) && (fam == AF_INET6)) -#endif /* defined(HASIPv6) */ - ) - + if (FnetTy == AF_UNSPEC || FnetTy == fam) Lf->sf |= SELNET; } - printiproto(p.pr_protocol); + enter_ip_proto(ctx, p.pr_protocol); #if defined(HASIPv6) - (void)snpf(Lf->type, sizeof(Lf->type), - (fam == AF_INET) ? "IPv4" : "IPv6"); + Lf->type = (fam == AF_INET) ? LSOF_FILE_IPV4 : LSOF_FILE_IPV6; #else /* !defined(HASIPv6) */ - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); + Lf->type = LSOF_FILE_INET; #endif /* defined(HASIPv6) */ #if defined(HASIPv6) && defined(NETBSDV) && !defined(HASINRIAIPv6) @@ -335,11 +328,12 @@ void process_socket(struct lsof_context *ctx, /* context */ * Process a ROUTE domain socket. */ case AF_ROUTE: - (void)snpf(Lf->type, sizeof(Lf->type), "rte"); + Lf->type = LSOF_FILE_ROUTE; if (s.so_pcb) enter_dev_ch(ctx, print_kptr((KA_T)(s.so_pcb), (char *)NULL, 0)); else (void)snpf(Namech, Namechl, "no protocol control block"); + Lf->off_def = 1; break; /* * Process a Unix domain socket. @@ -347,7 +341,7 @@ void process_socket(struct lsof_context *ctx, /* context */ case AF_UNIX: if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; /* * Read Unix protocol control block and the Unix address structure. */ diff --git a/lib/dialects/netbsd/dstore.c b/lib/dialects/netbsd/dstore.c index 1a460152..9e1ae543 100644 --- a/lib/dialects/netbsd/dstore.c +++ b/lib/dialects/netbsd/dstore.c @@ -35,11 +35,9 @@ static char copyright[] = #include "common.h" -struct file *Cfp; /* current file's file struct pointer */ - /* * Drive_Nl -- table to drive the building of Nl[] via build_Nl() - * (See lsof.h and misc.c.) + * (See common.h and misc.c.) */ struct drive_Nl Drive_Nl[] = { @@ -72,24 +70,10 @@ struct drive_Nl Drive_Nl[] = { {"", ""}, {NULL, NULL}}; -kvm_t *Kd; /* kvm descriptor */ -KA_T Kpa; /* kernel proc struct address */ - -struct l_vfs *Lvfs = NULL; /* local vfs structure table */ - -int Np = 0; /* number of kernel processes */ - -#if defined(HASKVMGETPROC2) -struct kinfo_proc2 *P = NULL; /* local process table copy */ -#else /* !defined(HASKVMGETPROC2) */ -struct kinfo_proc *P = NULL; /* local process table copy */ -#endif /* defined(HASKVMGETPROC2) */ - #if defined(HASFSTRUCT) /* * Pff_tab[] - table for printing file flags */ - struct pff_tab Pff_tab[] = {{(long)FREAD, FF_READ}, {(long)FWRITE, FF_WRITE}, {(long)FNONBLOCK, FF_NBLOCK}, diff --git a/lib/dialects/netbsd/machine.h b/lib/dialects/netbsd/machine.h index 18400ca5..de519b8b 100644 --- a/lib/dialects/netbsd/machine.h +++ b/lib/dialects/netbsd/machine.h @@ -127,7 +127,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ /* #define HASFSINO 1 */ @@ -137,7 +137,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -323,14 +323,6 @@ /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. For FreeBSD, NetBSD, @@ -492,7 +484,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -530,6 +522,7 @@ # define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */ # define USE_LIB_READDEV 1 /* rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ # if defined(NETBSDV) && NETBSDV >= 9099000 # define USE_LIB_RNMT 1 /* rnmt.c */ diff --git a/lib/dialects/openbsd/Makefile b/lib/dialects/openbsd/Makefile index 5b566fc0..512a56ce 100644 --- a/lib/dialects/openbsd/Makefile +++ b/lib/dialects/openbsd/Makefile @@ -24,11 +24,11 @@ GRP= HDR= lib/common.h include/lsof_fields.h dlsof.h machine.h lib/proto.h dproto.h SRC= dfile.c dmnt.c dnode.c dproc.c dsock.c dstore.c \ - arg.c main.c print.c ptti.c store.c usage.c \ + arg.c main.c node.c print.c ptti.c store.c usage.c \ util.c OBJ= dfile.o dmnt.o dnode.o dproc.o dsock.o dstore.o \ - arg.o main.o print.o ptti.o store.o usage.o \ + arg.o main.o node.o print.o ptti.o store.o usage.o \ util.o MAN= lsof.8 diff --git a/lib/dialects/openbsd/dfile.c b/lib/dialects/openbsd/dfile.c index 8ccd83a3..5ab5cafa 100644 --- a/lib/dialects/openbsd/dfile.c +++ b/lib/dialects/openbsd/dfile.c @@ -43,10 +43,15 @@ void process_kqueue_file(struct lsof_context *ctx, struct kinfo_file *file) { int flag; /* Alloc Lf and set fd */ - alloc_lfile(ctx, NULL, file->fd_fd); + alloc_lfile(ctx, LSOF_FD_NUMERIC, file->fd_fd); - /* Fill type name*/ - (void)snpf(Lf->type, sizeof(Lf->type), "KQUEUE"); + /* Fill type name */ + Lf->type = LSOF_FILE_KQUEUE; + + /* Display count and state */ + (void)snpf(Namech, Namechl, "count=%d, state=%#x", file->kq_count, + file->kq_state); + enter_nm(ctx, Namech); /* Fill dev with f_data if available */ if (file->f_data) { @@ -54,6 +59,10 @@ void process_kqueue_file(struct lsof_context *ctx, struct kinfo_file *file) { enter_dev_ch(ctx, buf); } + /* Fill offset */ + Lf->off = 0; + Lf->off_def = 1; + /* * Construct access code. */ @@ -72,4 +81,45 @@ void process_kqueue_file(struct lsof_context *ctx, struct kinfo_file *file) { /* * process_pipe() - process a file structure whose type is DTYPE_PIPE */ -void process_pipe(struct lsof_context *ctx, struct kinfo_file *file) {} \ No newline at end of file +void process_pipe(struct lsof_context *ctx, struct kinfo_file *file) { + char buf[64]; + int flag; + + /* Alloc Lf and set fd */ + alloc_lfile(ctx, LSOF_FD_NUMERIC, file->fd_fd); + + /* Fill type name */ + Lf->type = LSOF_FILE_PIPE; + + /* Fill dev with f_data if available */ + if (file->f_data) { + (void)snpf(buf, sizeof(buf), "0x%" PRIx64, file->f_data); + enter_dev_ch(ctx, buf); + } + + /* Display peer and state */ + if (file->pipe_peer) + (void)snpf(Namech, Namechl, "->0x%" PRIx64 ", state=%d", + file->pipe_peer, file->pipe_state); + else + (void)snpf(Namech, Namechl, "state=%d", file->pipe_state); + enter_nm(ctx, Namech); + + /* Fill offset */ + Lf->off = 0; + Lf->off_def = 1; + + /* + * Construct access code. + */ + if ((flag = (file->f_flag & (FREAD | FWRITE))) == FREAD) + Lf->access = LSOF_FILE_ACCESS_READ; + else if (flag == FWRITE) + Lf->access = LSOF_FILE_ACCESS_WRITE; + else if (flag == (FREAD | FWRITE)) + Lf->access = LSOF_FILE_ACCESS_READ_WRITE; + + /* Finish */ + if (Lf->sf) + link_lfile(ctx); +} \ No newline at end of file diff --git a/lib/dialects/openbsd/dlsof.h b/lib/dialects/openbsd/dlsof.h index 20dedb4e..77346c12 100644 --- a/lib/dialects/openbsd/dlsof.h +++ b/lib/dialects/openbsd/dlsof.h @@ -153,4 +153,6 @@ struct sfile { # define DIRTYPE dirent # define HASDNAMLEN 1 /* struct DIRTYPE has d_namlen element */ +struct lsof_context_dialect {}; + #endif /* OPENBSD_LSOF_H */ diff --git a/lib/dialects/openbsd/dmnt.c b/lib/dialects/openbsd/dmnt.c index 50949865..0074c168 100644 --- a/lib/dialects/openbsd/dmnt.c +++ b/lib/dialects/openbsd/dmnt.c @@ -39,9 +39,6 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ @@ -60,7 +57,8 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Access mount information. */ if ((n = getmntinfo(&mb, MNT_NOWAIT)) <= 0) { - (void)fprintf(stderr, "%s: no mount information\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no mount information\n", Pn); return (0); } /* @@ -79,16 +77,19 @@ struct mounts *readmnt(struct lsof_context *ctx) { no_space_for_mount: - (void)fprintf(stderr, "%s: no space for mount at ", Pn); - safestrprt(mb->f_mntonname, stderr, 0); - (void)fprintf(stderr, " ("); - safestrprt(mb->f_mntfromname, stderr, 0); - (void)fprintf(stderr, ")\n"); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for mount at ", Pn); + safestrprt(mb->f_mntonname, ctx->err, 0); + (void)fprintf(ctx->err, " ("); + safestrprt(mb->f_mntfromname, ctx->err, 0); + (void)fprintf(ctx->err, ")\n"); + } Error(ctx); + return NULL; } if ((ln = Readlink(ctx, dn)) == NULL) { - if (!Fwarn) { - (void)fprintf(stderr, + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } continue; @@ -103,12 +104,12 @@ struct mounts *readmnt(struct lsof_context *ctx) { * Stat() the directory. */ if (statsafely(ctx, dn, &sb)) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: can't stat() ", Pn); - safestrprt(mb->f_fstypename, stderr, 0); - (void)fprintf(stderr, " file system "); - safestrprt(mb->f_mntonname, stderr, 1); - (void)fprintf(stderr, + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: WARNING: can't stat() ", Pn); + safestrprt(mb->f_fstypename, ctx->err, 0); + (void)fprintf(ctx->err, " file system "); + safestrprt(mb->f_mntonname, ctx->err, 1); + (void)fprintf(ctx->err, " Output information may be incomplete.\n"); } (void)bzero((char *)&sb, sizeof(sb)); @@ -116,8 +117,8 @@ struct mounts *readmnt(struct lsof_context *ctx) { sb.st_dev = (dev_t)mb->f_fsid.val[0]; sb.st_mode = S_IFDIR | 0777; - if (!Fwarn) { - (void)fprintf(stderr, + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, " assuming \"dev=%x\" from mount table\n", sb.st_dev); } diff --git a/lib/dialects/openbsd/dnode.c b/lib/dialects/openbsd/dnode.c index 8ac05afd..6dfb639b 100644 --- a/lib/dialects/openbsd/dnode.c +++ b/lib/dialects/openbsd/dnode.c @@ -39,31 +39,30 @@ static char copyright[] = * process_vnode() - process vnode */ void process_vnode(struct lsof_context *ctx, struct kinfo_file *file) { - char *nm = NULL; + enum lsof_fd_type fd_type; int num = -1; uint32_t flag; - char *type_name = NULL; int mib[3]; size_t size; - char path[PATH_MAX]; + char path[PATH_MAX] = {0}; /* Alloc Lf and set fd */ switch (file->fd_fd) { case KERN_FILE_TEXT: - nm = "txt"; + fd_type = LSOF_FD_PROGRAM_TEXT; break; case KERN_FILE_CDIR: - nm = "cwd"; - + fd_type = LSOF_FD_CWD; break; case KERN_FILE_RDIR: - nm = "rtd"; + fd_type = LSOF_FD_ROOT_DIR; break; default: + fd_type = LSOF_FD_NUMERIC; num = file->fd_fd; break; } - alloc_lfile(ctx, nm, num); + alloc_lfile(ctx, fd_type, num); if (file->fd_fd == KERN_FILE_CDIR) { /* @@ -108,7 +107,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *file) { /* Fill inode */ Lf->inode = file->va_fileid; - Lf->inp_ty = 1; + Lf->inode_def = 1; /* Fill dev && rdef */ Lf->dev = file->va_fsid; @@ -121,23 +120,25 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *file) { /* Fill type */ switch (file->v_type) { case VREG: - Lf->ntype = N_REGLR; - type_name = "REG"; + Ntype = N_REGLR; + Lf->type = LSOF_FILE_VNODE_VREG; break; case VDIR: - type_name = "DIR"; + Lf->type = LSOF_FILE_VNODE_VDIR; + break; + case VBLK: + Ntype = N_BLK; + Lf->type = LSOF_FILE_VNODE_VBLK; break; case VCHR: - Lf->ntype = N_CHR; - type_name = "CHR"; + Ntype = N_CHR; + Lf->type = LSOF_FILE_VNODE_VCHR; break; case VFIFO: - Lf->ntype = N_FIFO; - type_name = "FIFO"; + Ntype = N_FIFO; + Lf->type = LSOF_FILE_VNODE_VFIFO; break; } - if (type_name) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", type_name); /* No way to read file path, request mount info */ Lf->lmi_srch = 1; @@ -152,7 +153,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *file) { /* Handle name match, must be done late, because if_file_named checks * Lf->dev etc. */ - if (is_file_named(ctx, nm, 0)) { + if (is_file_named(ctx, path, 0)) { Lf->sf |= SELNM; } diff --git a/lib/dialects/openbsd/dproc.c b/lib/dialects/openbsd/dproc.c index 5038f796..ba2f07bf 100644 --- a/lib/dialects/openbsd/dproc.c +++ b/lib/dialects/openbsd/dproc.c @@ -37,6 +37,7 @@ static char copyright[] = static void process_kinfo_file(struct lsof_context *ctx, struct kinfo_file *file); +static void process_tty(struct lsof_context *ctx, struct kinfo_proc *proc); /* * Local static values @@ -84,9 +85,11 @@ void gather_proc_info(struct lsof_context *ctx) { /* Probe number of entries */ if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) { - (void)fprintf(stderr, "%s: can't read process table: %d\n", Pn, - errno); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't read process table: %d\n", + Pn, errno); Error(ctx); + return; } /* Alloc more to handle new processes in the meantime */ @@ -99,8 +102,10 @@ void gather_proc_info(struct lsof_context *ctx) { procs = (struct kinfo_proc *)realloc(procs, size); } if (!procs) { - (void)fprintf(stderr, "%s: no kinfo_proc * space\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no kinfo_proc * space\n", Pn); Error(ctx); + return; } mib[5] = size / sizeof(struct kinfo_proc); /* elem_count */ @@ -109,9 +114,11 @@ void gather_proc_info(struct lsof_context *ctx) { num_procs = size / sizeof(struct kinfo_proc); break; } else if (res < 0 && errno != ENOMEM) { - (void)fprintf(stderr, "%s: can't read process table: %d\n", Pn, - errno); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't read process table: %d\n", + Pn, errno); Error(ctx); + return; } }; @@ -164,9 +171,11 @@ void gather_proc_info(struct lsof_context *ctx) { /* Probe number of entries */ if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) { - (void)fprintf(stderr, "%s: can't read file table: %d\n", Pn, - errno); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't read file table: %d\n", + Pn, errno); Error(ctx); + return; } /* Alloc more to handle new processes in the meantime */ @@ -179,8 +188,10 @@ void gather_proc_info(struct lsof_context *ctx) { files = (struct kinfo_file *)realloc(files, size); } if (!files) { - (void)fprintf(stderr, "%s: no kinfo_file * space\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no kinfo_file * space\n", Pn); Error(ctx); + return; } mib[5] = size / sizeof(struct kinfo_file); /* elem_count */ @@ -189,12 +200,15 @@ void gather_proc_info(struct lsof_context *ctx) { num_files = size / sizeof(struct kinfo_file); break; } else if (res < 0 && errno != ENOMEM) { - (void)fprintf(stderr, "%s: can't read file table: %d\n", Pn, - errno); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't read file table: %d\n", + Pn, errno); Error(ctx); + return; } }; + process_tty(ctx, proc); for (file = files, fx = 0; fx < num_files; fx++, file++) { process_kinfo_file(ctx, file); } @@ -212,6 +226,11 @@ void gather_proc_info(struct lsof_context *ctx) { */ void initialize(struct lsof_context *ctx) {} +/* + * deinitialize() - perform all cleanup + */ +void deinitialize(struct lsof_context *ctx) {} + /* * process_kinfo_file() - process kinfo_file */ @@ -230,4 +249,49 @@ void process_kinfo_file(struct lsof_context *ctx, struct kinfo_file *file) { process_kqueue_file(ctx, file); break; } +} + +/* + * process_tty() - process tty of kinfo_proc + */ +static void process_tty(struct lsof_context *ctx, struct kinfo_proc *proc) { + char *dev; + struct stat st; + if ((proc->p_eflag & EPROC_CTTY) == 0) + return; + + /* Alloc Lf */ + alloc_lfile(ctx, LSOF_FD_CTTY, -1); + + /* Fill type name */ + Lf->type = LSOF_FILE_CHAR; + + /* rdev is known, dev is /dev */ + Lf->rdev = proc->p_tdev; + Lf->rdev_def = 1; + + /* we don't know inode or dev of the tty, so we have to get name via + * devname() */ + if ((dev = devname(Lf->rdev, S_IFCHR))) { + (void)snpf(Namech, Namechl, "/dev/%s", dev); + enter_nm(ctx, Namech); + + /* stat() to get inode */ + if (stat(Namech, &st) == 0 && st.st_rdev == Lf->rdev) { + Lf->inode = st.st_ino; + Lf->inode_def = 1; + + Lf->dev = st.st_dev; + Lf->dev_def = 1; + } + } + + /* Handle name match */ + if (is_file_named(ctx, NULL, 1)) { + Lf->sf |= SELNM; + } + + /* Finish */ + if (Lf->sf) + link_lfile(ctx); } \ No newline at end of file diff --git a/lib/dialects/openbsd/dproto.h b/lib/dialects/openbsd/dproto.h index 138ca13a..ca05fdb5 100644 --- a/lib/dialects/openbsd/dproto.h +++ b/lib/dialects/openbsd/dproto.h @@ -34,10 +34,9 @@ * $Id: dproto.h,v 1.11 2005/08/08 19:53:24 abe Exp $ */ -extern int is_file_named(struct lsof_context *ctx, char *p, int cd); +extern int is_file_named (struct lsof_context * ctx, char *p, int cd); -extern void process_vnode(struct lsof_context *ctx, struct kinfo_file *file); -extern void process_socket(struct lsof_context *ctx, struct kinfo_file *file); -extern void process_pipe(struct lsof_context *ctx, struct kinfo_file *file); -extern void process_kqueue_file(struct lsof_context *ctx, - struct kinfo_file *file); +extern void process_vnode (struct lsof_context * ctx, struct kinfo_file *file); +extern void process_socket (struct lsof_context * ctx, struct kinfo_file *file); +extern void process_pipe (struct lsof_context * ctx, struct kinfo_file *file); +extern void process_kqueue_file (struct lsof_context * ctx, struct kinfo_file *file); diff --git a/lib/dialects/openbsd/dsock.c b/lib/dialects/openbsd/dsock.c index f43ff9f9..016326d3 100644 --- a/lib/dialects/openbsd/dsock.c +++ b/lib/dialects/openbsd/dsock.c @@ -39,33 +39,29 @@ static char copyright[] = * process_socket() - process socket */ void process_socket(struct lsof_context *ctx, struct kinfo_file *file) { - char *type_name = NULL; - char *proto = NULL; char *type = NULL; char buf[64]; int flag; uint32_t lport, fport; /* Alloc Lf and set fd */ - alloc_lfile(ctx, NULL, file->fd_fd); + alloc_lfile(ctx, LSOF_FD_NUMERIC, file->fd_fd); /* Type name */ switch (file->so_family) { case AF_INET: - type_name = "IPv4"; + Lf->type = LSOF_FILE_IPV4; break; case AF_INET6: - type_name = "IPv6"; + Lf->type = LSOF_FILE_IPV6; break; case AF_UNIX: - type_name = "unix"; + Lf->type = LSOF_FILE_UNIX; break; case AF_ROUTE: - type_name = "rte"; + Lf->type = LSOF_FILE_ROUTE; break; } - if (type_name) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", type_name); /* * Construct access code. @@ -82,31 +78,26 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *file) { /* Fill iproto */ switch (file->so_type) { case SOCK_STREAM: - proto = "TCP"; + Lf->iproto = LSOF_PROTOCOL_TCP; break; case SOCK_DGRAM: - proto = "UDP"; + Lf->iproto = LSOF_PROTOCOL_UDP; break; case SOCK_RAW: - proto = "RAW"; + Lf->iproto = LSOF_PROTOCOL_RAW; break; } - if (proto) { - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%s", proto); - Lf->inp_ty = 2; - } + + /* Fill offset, always zero */ + Lf->off = 0; + Lf->off_def = 1; if (file->so_family == AF_INET || file->so_family == AF_INET6) { /* Show this entry if -i */ if (Fnet) { /* Handle v4/v6 only */ - if (FnetTy == 4 && file->so_family == AF_INET) { - Lf->sf |= SELNET; - } else if (FnetTy == 6 && file->so_family == AF_INET6) { + if (FnetTy == AF_UNSPEC || FnetTy == file->so_family) Lf->sf |= SELNET; - } else if (FnetTy == 0) { - Lf->sf |= SELNET; - } } /* Fill internet address info */ @@ -122,10 +113,14 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *file) { file->so_family); } - /* Fill TCP state */ + /* Fill TCP state and window */ if (file->so_type == SOCK_STREAM) { Lf->lts.type = 0; Lf->lts.state.i = file->t_state; + Lf->lts.rws = 1; + Lf->lts.rw = file->t_rcv_wnd; + Lf->lts.wws = 1; + Lf->lts.ww = file->t_snd_wnd; } /* Fill dev with pcb if available */ @@ -165,12 +160,6 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *file) { file->unp_path[0] ? " " : "", type); (void)enter_nm(ctx, Namech); - /* Fill TCP state */ - if (file->so_type == SOCK_STREAM) { - Lf->lts.type = 0; - Lf->lts.state.i = file->t_state; - } - /* Fill dev with so_pcb if available */ if (file->so_pcb && file->so_pcb != (uint64_t)(-1)) { (void)snpf(buf, sizeof(buf), "0x%" PRIx64, file->so_pcb); diff --git a/lib/dialects/openbsd/machine.h b/lib/dialects/openbsd/machine.h index ac2e98cf..b71b2bed 100644 --- a/lib/dialects/openbsd/machine.h +++ b/lib/dialects/openbsd/machine.h @@ -124,7 +124,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ /* #define HASFSINO 1 */ @@ -134,7 +134,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -320,14 +320,6 @@ /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. For FreeBSD, NetBSD, @@ -457,7 +449,7 @@ * TCP/TPI send and receive window sizes produced by netstat. */ -/* #define HASTCPTPIW 1 */ +#define HASTCPTPIW 1 /* * HASTMPNODE is defined for those dialects that have tmpnodes. @@ -485,7 +477,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -523,6 +515,7 @@ # define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */ # define USE_LIB_READDEV 1 /* rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNMT 1 rnmt.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ diff --git a/lib/dialects/openbsd/tests/case-00-openbsd-hello.bash b/lib/dialects/openbsd/tests/case-00-openbsd-hello.bash deleted file mode 100755 index ca916d09..00000000 --- a/lib/dialects/openbsd/tests/case-00-openbsd-hello.bash +++ /dev/null @@ -1 +0,0 @@ -exit 0 diff --git a/lib/dialects/osr/Makefile b/lib/dialects/osr/Makefile index 79c38dfd..0ca096e6 100644 --- a/lib/dialects/osr/Makefile +++ b/lib/dialects/osr/Makefile @@ -21,7 +21,7 @@ CFLAGS= ${CDEFS} ${INCL} ${DEBUG} GRP= -HDR= lsof.h lsof_fields.h dlsof.h machine.h proto.h dproto.h +HDR= common.h lsof_fields.h dlsof.h machine.h proto.h dproto.h MODE= 2755 diff --git a/lib/dialects/osr/dfile.c b/lib/dialects/osr/dfile.c index 8169f345..e65ea511 100644 --- a/lib/dialects/osr/dfile.c +++ b/lib/dialects/osr/dfile.c @@ -62,8 +62,9 @@ int get_max_fd() { * print_dev() - print dev */ -char *print_dev(struct lfile *lf, /* file whose device is to be printed */ - dev_t *dev) /* device to be printed */ +char *print_dev(lf, dev) +struct lfile *lf; /* file whose device is to be printed */ +dev_t *dev; /* device to be printed */ { static char buf[128]; @@ -77,7 +78,8 @@ char *print_dev(struct lfile *lf, /* file whose device is to be printed */ * print_ino() - print inode */ -char *print_ino(struct lfile *lf) /* file whose device is to be printed */ +char *print_ino(lf) +struct lfile *lf; /* file whose device is to be printed */ { static char buf[128]; @@ -95,14 +97,13 @@ void process_file(fp) KA_T fp; /* kernel file structure address */ struct file f; int flag; - if (kread(ctx, fp, (char *)&f, sizeof(f))) { + if (kread(fp, (char *)&f, sizeof(f))) { (void)snpf(Namech, Namechl, "can't read file struct from %s", print_kptr(fp, (char *)NULL, 0)); enter_nm(Namech); return; } Lf->off = (SZOFFTYPE)f.f_offset; - Lf->off_def = 1; if (f.f_count) { @@ -125,10 +126,13 @@ void process_file(fp) KA_T fp; /* kernel file structure address */ */ Lf->fct = (long)f.f_count; Lf->fsv |= FSV_CT; + Lf->fsa = fp; Lf->fsv |= FSV_FA; + Lf->ffg = (long)f.f_flag; Lf->fsv |= FSV_FG; + Lf->fna = (KA_T)f.f_inode; Lf->fsv |= FSV_NI; #endif /* defined(HASFSTRUCT) */ diff --git a/lib/dialects/osr/dmnt.c b/lib/dialects/osr/dmnt.c index 202aa7b2..18258ddd 100644 --- a/lib/dialects/osr/dmnt.c +++ b/lib/dialects/osr/dmnt.c @@ -39,9 +39,6 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ diff --git a/lib/dialects/osr/dnode.c b/lib/dialects/osr/dnode.c index 3abe346f..156b3d65 100644 --- a/lib/dialects/osr/dnode.c +++ b/lib/dialects/osr/dnode.c @@ -41,9 +41,10 @@ static struct l_dev *finddev(dev_t *dev, dev_t *rdev, int stream); * finddev() - look up device by device number */ -static struct l_dev *finddev(dev_t *dev, /* device */ - dev_t *rdev, /* raw device */ - int stream) /* stream if 1 */ +static struct l_dev *finddev(dev, rdev, stream) +dev_t *dev; /* device */ +dev_t *rdev; /* raw device */ +int stream; /* stream if 1 */ { struct clone *c; struct l_dev *dp; @@ -106,7 +107,6 @@ void process_node(na) KA_T na; /* inode kernel space address */ struct queue q; struct qinit qi; struct stdata sd; - char *tn; int type; struct udpdev udp; short udptm = 0; @@ -229,7 +229,7 @@ void process_node(na) KA_T na; /* inode kernel space address */ if ((flf = (KA_T)i.i_filocks)) { flp = flf; do { - if ((kread(ctx, flp, (char *)&fl, sizeof(fl)))) + if ((kread(flp, (char *)&fl, sizeof(fl)))) break; if (fl.set.l_pid != (pid_t)Lp->pid) continue; @@ -245,13 +245,13 @@ void process_node(na) KA_T na; /* inode kernel space address */ if (fl.flags & F_XOUT) #endif /* OSRV<500 */ - Lf->lock = l ? 'X' : 'x'; + Lf->lock = l ? LSOF_LOCK_SCO_FULL : LSOF_LOCK_SCO_PARTIAL; else if (fl.set.l_type == F_RDLCK) - Lf->lock = l ? 'R' : 'r'; + Lf->lock = l ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL; else if (fl.set.l_type == F_WRLCK) - Lf->lock = l ? 'W' : 'w'; + Lf->lock = l ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL; else if (fl.set.l_type == (F_RDLCK | F_WRLCK)) - Lf->lock = 'u'; + Lf->lock = LSOF_LOCK_READ_WRITE; break; } while ((flp = (KA_T)fl.next) && flp != flf); } @@ -264,7 +264,7 @@ void process_node(na) KA_T na; /* inode kernel space address */ hpps = 1; if (i.i_fsptr) { enter_dev_ch(print_kptr((KA_T)i.i_fsptr, (char)NULL, 0)); - if (kread(ctx, (KA_T)i.i_fsptr, (char *)&pi, sizeof(pi)) == 0) + if (kread((KA_T)i.i_fsptr, (char *)&pi, sizeof(pi)) == 0) hpps = 2; } } @@ -325,20 +325,20 @@ void process_node(na) KA_T na; /* inode kernel space address */ * cdevsw[].d_name. */ p = (KA_T)NULL; - if (!kread(ctx, (KA_T)i.i_sptr, (char *)&sd, sizeof(sd))) { + if (!kread((KA_T)i.i_sptr, (char *)&sd, sizeof(sd))) { dl = sizeof(tbuf) - 1; tbuf[dl] = '\0'; qp = (KA_T)sd.sd_wrq; for (j = 0; qp && j < 20; j++, qp = (KA_T)q.q_next) { - if (kread(ctx, qp, (char *)&q, sizeof(q))) + if (kread(qp, (char *)&q, sizeof(q))) break; if (!(ka = (KA_T)q.q_qinfo) || - kread(ctx, ka, (char *)&qi, sizeof(qi))) + kread(ka, (char *)&qi, sizeof(qi))) continue; if (!(ka = (KA_T)qi.qi_minfo) || - kread(ctx, ka, (char *)&mi, sizeof(mi))) + kread(ka, (char *)&mi, sizeof(mi))) continue; - if (!(ka = (KA_T)mi.mi_idname) || kread(ctx, ka, tbuf, dl)) + if (!(ka = (KA_T)mi.mi_idname) || kread(ka, tbuf, dl)) continue; if ((l = strlen(tbuf)) < 1) continue; @@ -354,12 +354,10 @@ void process_node(na) KA_T na; /* inode kernel space address */ */ if (strcasecmp(cp, "tcp") == 0) { pt = 0; - (void)snpf(Lf->iproto, sizeof(Lf->iproto), - "TCP"); + Lf->iproto = LSOF_PROTOCOL_TCP; } else if (strcasecmp(cp, "udp") == 0) { pt = 1; - (void)snpf(Lf->iproto, sizeof(Lf->iproto), - "UDP"); + Lf->iproto = LSOF_PROTOCOL_UDP; } if (pt >= 0) p = (KA_T)q.q_ptr; @@ -386,7 +384,7 @@ void process_node(na) KA_T na; /* inode kernel space address */ * If the stream has a TCP or UDP module with a PCB pointer, * print any associated local and foreign Internet addresses. */ - if (kread(ctx, p, (char *)&pcb, sizeof(pcb))) + if (kread(p, (char *)&pcb, sizeof(pcb))) break; if (Fnet) Lf->sf |= SELNET; @@ -398,8 +396,8 @@ void process_node(na) KA_T na; /* inode kernel space address */ * If this is a UDP stream, get the udpdev structure at the * PCB's per-protocol address. It may contain addresses. */ - if (kread(ctx, (KA_T)pcb.inp_ppcb, (char *)&udp, - sizeof(udp)) == 0) { + if (kread((KA_T)pcb.inp_ppcb, (char *)&udp, sizeof(udp)) == + 0) { #if OSRV >= 500 if (udp.ud_lsin.sin_addr.s_addr != INADDR_ANY || @@ -452,8 +450,6 @@ void process_node(na) KA_T na; /* inode kernel space address */ if (udptm && !Lf->nma) (void)udp_tm(udp.ud_ftime); } - if (!i.i_number) - Lf->inp_ty = 2; } } else { if (ity) { @@ -503,7 +499,7 @@ void process_node(na) KA_T na; /* inode kernel space address */ if ((Lf->inode = (unsigned long)i.i_number)) #endif /* OSRV<500 */ - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if defined(HAS_NFS) @@ -512,17 +508,17 @@ void process_node(na) KA_T na; /* inode kernel space address */ # if OSRV < 500 n = (unsigned short *)&r.r_fh.fh_pad[14]; if ((Lf->inode = (unsigned long)ntohs(*n))) - Lf->inp_ty = 1; + Lf->inode_def = 1; else if ((Lf->inode = (unsigned long)r.r_fh.fh_u.fh_fgen_u)) # else /* OSRV>=500 */ n = (unsigned short *)&r.r_fh.fh_u.fh_fid_u[4]; n1 = (unsigned short *)&r.r_fh.fh_u.fh_fid_u[2]; if ((Lf->inode = (unsigned long)*n)) - Lf->inp_ty = 1; + Lf->inode_def = 1; else if ((Lf->inode = (unsigned long)*n1)) # endif /* OSRV<500 */ - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #endif /* defined(HAS_NFS) */ @@ -546,18 +542,21 @@ void process_node(na) KA_T na; /* inode kernel space address */ if (i.i_number) { Lf->inode = (unsigned long)i.i_number; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; } /* * Determine the file size. */ + Lf->off_def = 1; switch (Ntype) { case N_BLK: + Lf->off_def = 1; break; case N_CHR: case N_COM: + Lf->off_def = 1; break; case N_FIFO: @@ -568,6 +567,8 @@ void process_node(na) KA_T na; /* inode kernel space address */ break; } #endif /* OSRV>=500 */ + + Lf->off_def = 1; break; case N_HSFS: @@ -597,50 +598,48 @@ void process_node(na) KA_T na; /* inode kernel space address */ */ switch (type) { case IFDIR: - tn = "DIR"; + Lf->type = LSOF_FILE_DIR; break; case IFBLK: - tn = "BLK"; + Lf->type = LSOF_FILE_BLOCK; break; case IFCHR: - tn = "CHR"; + Lf->type = LSOF_FILE_CHAR; break; case IFREG: - tn = "REG"; + Lf->type = LSOF_FILE_REGULAR; break; case IFMPC: - tn = "MPC"; + Lf->type = LSOF_FILE_MULTIPLEXED_CHAR; break; case IFMPB: - tn = "MPB"; + Lf->type = LSOF_FILE_MULTIPLEXED_BLOCK; break; case IFNAM: if (i.i_rdev == S_INSEM) - tn = "XSEM"; + Lf->type = LSOF_FILE_SCO_SEMA; else if (i.i_rdev == S_INSHD) - tn = "XSD"; + Lf->type = LSOF_FILE_SCO_SHARED; else { - tn = "XNAM"; + Lf->type = LSOF_FILE_SCO_UNKNOWN; (void)snpf(Namech, Namechl, "unknown Xenix special file type: %x", i.i_rdev); } break; case IFIFO: - tn = "FIFO"; + Lf->type = LSOF_FILE_FIFO; break; #if defined(IFLNK) case IFLNK: - tn = "LINK"; + Lf->type = LSOF_FILE_LINK; break; #endif /* defined(IFLNK) */ default: - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", ((type >> 12) & 0xfff)); - tn = NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = type; } - if (tn) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", tn); /* * Save the file system names. */ @@ -665,14 +664,13 @@ void process_node(na) KA_T na; /* inode kernel space address */ } break; } - Lf->ntype = Ntype; #if defined(HASBLKDEV) /* * If this is a IFBLK file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == IFBLK)) + if (!Lf->inode_def && (type == IFBLK)) find_bl_ino(); #endif /* defined(HASBLKDEV) */ @@ -680,7 +678,7 @@ void process_node(na) KA_T na; /* inode kernel space address */ * If this is a IFCHR file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == IFCHR)) + if (!Lf->inode_def && (type == IFCHR)) find_ch_ino(); /* * Test for specified file. diff --git a/lib/dialects/osr/dproc.c b/lib/dialects/osr/dproc.c index 157fa613..3fdb0e8f 100644 --- a/lib/dialects/osr/dproc.c +++ b/lib/dialects/osr/dproc.c @@ -152,7 +152,7 @@ void gather_proc_info() { i = Var.v_proc - px; if (i > PROCBFRD) i = PROCBFRD; - j = kread(ctx, (KA_T)(Kp + (px * sizeof(struct proc))), pb, + j = kread((KA_T)(Kp + (px * sizeof(struct proc))), pb, sizeof(struct proc) * i); pbc = px + i; p = (struct proc *)pb; @@ -238,11 +238,11 @@ void gather_proc_info() { pofb = (char *)realloc((MALLOC_P *)pofb, (MALLOC_S)nf); if (!pofb) { (void)fprintf(stderr, "%s: no pofile space\n", Pn); - Error(); + Error(ctx); } npofb = nf; } - if (kread(ctx, (KA_T)u->u_pofile, pofb, nf)) + if (kread((KA_T)u->u_pofile, pofb, nf)) pof = (char *)NULL; else pof = pofb; @@ -289,7 +289,7 @@ void get_cdevsw() { */ if (get_Nl_value("cdev", Drive_Nl, &v[0]) < 0 || get_Nl_value("ncdev", Drive_Nl, &v[1]) < 0 || !v[0] || !v[1] || - kread(ctx, v[1], (char *)&Cdevcnt, sizeof(Cdevcnt)) || Cdevcnt < 1) + kread(v[1], (char *)&Cdevcnt, sizeof(Cdevcnt)) || Cdevcnt < 1) return; /* * Allocate cache space. @@ -308,7 +308,7 @@ void get_cdevsw() { Cdevcnt); Error(ctx); } - if (kread(ctx, (KA_T)v[0], (char *)tmp, i)) { + if (kread((KA_T)v[0], (char *)tmp, i)) { (void)free((FREE_P *)Cdevsw); Cdevsw = (char **)NULL; Cdevcnt = 0; @@ -325,7 +325,7 @@ void get_cdevsw() { Cdevsw[i] = (char *)NULL; if (!c->d_name) continue; - if (kread(ctx, (KA_T)c->d_name, buf, j)) { + if (kread((KA_T)c->d_name, buf, j)) { (void)fprintf(stderr, "%s: WARNING: can't read name for cdevsw[%d]: %#x\n", Pn, i, c->d_name); @@ -370,7 +370,7 @@ static void get_kernel_access() { /* * See if the name list file is readable. */ - if (Nmlst && !is_readable(Nmlst, 1)) + if (Nmlst && !is_readable(ctx, Nmlst, 1)) Error(ctx); /* * Access kernel symbols. @@ -413,7 +413,7 @@ static void get_kernel_access() { */ v = (KA_T)0; if (get_Nl_value("pregpp", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&Npp, sizeof(Npp)) || Npp < 1) { + kread(v, (char *)&Npp, sizeof(Npp)) || Npp < 1) { (void)fprintf(stderr, "%s: can't read pregion count (%d) from %s\n", Pn, Npp, print_kptr(v, (char *)NULL, 0)); Error(ctx); @@ -430,7 +430,7 @@ static void get_kernel_access() { * Read system configuration information. */ if (get_Nl_value("var", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&Var, sizeof(Var))) { + kread((KA_T)v, (char *)&Var, sizeof(Var))) { (void)fprintf(stderr, "%s: can't read system configuration info\n", Pn); Error(ctx); } @@ -439,14 +439,14 @@ static void get_kernel_access() { */ v = (KA_T)0; if (get_Nl_value("hz", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&Hz, sizeof(Hz))) { + kread(v, (char *)&Hz, sizeof(Hz))) { if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: can't read Hz from %s\n", Pn, print_kptr(v, (char *)NULL, 0)); Hz = -1; } if (get_Nl_value("lbolt", Drive_Nl, &Lbolt) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&lbolt, sizeof(lbolt))) { + kread((KA_T)v, (char *)&lbolt, sizeof(lbolt))) { if (!Fwarn) (void)fprintf( stderr, @@ -458,7 +458,7 @@ static void get_kernel_access() { * Get socket device number and socket table address. */ if (get_Nl_value("sockd", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&Sockdev, sizeof(Sockdev))) { + kread(v, (char *)&Sockdev, sizeof(Sockdev))) { (void)fprintf(stderr, "%s: WARNING: can't identify socket device.\n", Pn); (void)fprintf(stderr, " Socket output may be incomplete.\n"); @@ -480,7 +480,7 @@ static void get_kernel_access() { */ v = (KA_T)0; if (get_Nl_value("nxdm", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&nxdevmaps, sizeof(nxdevmaps)) || nxdevmaps < 0) { + kread(v, (char *)&nxdevmaps, sizeof(nxdevmaps)) || nxdevmaps < 0) { (void)fprintf(stderr, "%s: bad extended device table size (%d) at %s.\n", Pn, nxdevmaps, print_kptr(v, (char *)NULL, 0)); @@ -494,7 +494,7 @@ static void get_kernel_access() { } v = (KA_T)0; if (get_Nl_value("xdm", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)Xdevmap, len)) { + kread((KA_T)v, (char *)Xdevmap, len)) { (void)fprintf(stderr, "%s: can't read %d byte xdevmap table at #x\n", Pn, len, v); Error(ctx); @@ -512,10 +512,11 @@ static void get_kernel_access() { * boot path's name list will have been loaded into Nl[]. */ -char *get_nlist_path(int ap) /* on success, return an allocated path - * string pointer if 1; return a - * constant character pointer if 0; - * return NULL if failure */ +char *get_nlist_path(ap) +int ap; /* on success, return an allocated path + * string pointer if 1; return a + * constant character pointer if 0; + * return NULL if failure */ { FILE *bf; char *bfp, b1[MAXPATHLEN + 1], b2[MAXPATHLEN + 1], *pp, *tp; @@ -621,8 +622,7 @@ void initialize() { get_kernel_access(); get_cdevsw(); readfsinfo(); - if (Fsv & FSV_NI) - NiTtl = "INODE-ADDR"; + NiTtl = "INODE-ADDR"; } #if !defined(N_UNIX) @@ -640,7 +640,7 @@ is_boot(p) char *p; /* specified path */ } s1, s2; /* * Get the scoutsname structure via __scoinfo() to use as a reference - * against the one obtained via kread(ctx, )'ing from the + * against the one obtained via kread()'ing from the * nlist() address. If __scoinfo() fails, return the * default boot path. */ @@ -664,7 +664,7 @@ is_boot(p) char *p; /* specified path */ if (open_kmem(1)) return (0); } - if (kread(ctx, ka, (char *)&s2.s, sizeof(s2.s))) + if (kread(ka, (char *)&s2.s, sizeof(s2.s))) return (0); for (i = 0; i < sizeof(struct scoutsname); i++) { if (s1.sc[i] != s2.sc[i]) @@ -678,10 +678,10 @@ is_boot(p) char *p; /* specified path */ * kread() - read from kernel memory */ -int kread(struct lsof_context *ctx, /* context */ - KA_T addr, /* kernel memory address */ - char *buf, /* buffer to receive data */ - READLEN_T len) /* length to read */ +int kread(addr, buf, len) +KA_T addr; /* kernel memory address */ +char *buf; /* buffer to receive data */ +READLEN_T len; /* length to read */ { int br; @@ -696,14 +696,15 @@ int kread(struct lsof_context *ctx, /* context */ * open_kmem() - open kernel memory access */ -static int open_kmem(int nx) /* no Error(ctx) if 1 */ +static int open_kmem(nx) +int nx; /* no Error(ctx) if 1 */ { if (Kd >= 0) return (0); /* * See if the non-KMEM memory file is readable. */ - if (Memory && !is_readable(Memory, 1)) { + if (Memory && !is_readable(ctx, Memory, 1)) { if (nx) return (1); Error(ctx); @@ -743,7 +744,7 @@ static void process_text(prp) KA_T prp; /* process region pointer */ */ #if OSRV < 500 - if (kread(ctx, prp, (char *)Pr, Prsz)) + if (kread(prp, (char *)Pr, Prsz)) return; for (i = j = 0, p = Pr; i < Npp; i++, p++) #else /* OSRV>=500 */ @@ -763,7 +764,7 @@ static void process_text(prp) KA_T prp; /* process region pointer */ Pn, Lp->pid); return; } - if ((i && pc == prp) || kread(ctx, (KA_T)pc, (char *)p, sizeof(ps))) + if ((i && pc == prp) || kread((KA_T)pc, (char *)p, sizeof(ps))) return; #endif /* OSRV>=500 */ @@ -773,7 +774,7 @@ static void process_text(prp) KA_T prp; /* process region pointer */ * Read the region. * Skip entries with no node pointers and duplicate node addresses. */ - if (kread(ctx, (KA_T)p->p_reg, (char *)&r, sizeof(r))) + if (kread((KA_T)p->p_reg, (char *)&r, sizeof(r))) continue; if (!(na = (KA_T)r.r_iptr)) continue; @@ -986,7 +987,7 @@ static struct lnch *LNC_nc = (struct lnch *)NULL; * Local function prototypes */ -static struct lnch *DIN_addr(dev_t *d, unsigned long i); +static struct lnch *DIN_addr, (dev_t * d unsigned long i); # if OSRV >= 500 # if OSRV >= 504 @@ -1014,8 +1015,9 @@ static void SYSV_load(); * DIN_addr() - look up a node's local device-inode address */ -static struct lnch *DIN_addr(dev_t *d, /* device number */ - unsigned long i) /* inode number */ +static struct lnch *DIN_addr(d, i) +dev_t *d; /* device number */ +unsigned long i; /* inode number */ { struct lnch_hh *hh = DIN_hash(*d, i); struct lnch *lc = hh->hp[0]; @@ -1071,14 +1073,14 @@ static void DNLC_load() { * get the array's address. If that fails, return without comment * and without further action. */ - if (kread(ctx, ka, (char *)&ka, sizeof(ka))) + if (kread(ka, (char *)&ka, sizeof(ka))) return; } /* * Get the kernel's DNLC name cache size. */ if (get_Nl_value("ndnlc", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&dnlce, sizeof(dnlce)) || dnlce < 1) + kread(v, (char *)&dnlce, sizeof(dnlce)) || dnlce < 1) return; /* * Allocate space for a copy of a portion ("chunk") of the kernel's @@ -1112,7 +1114,7 @@ static void DNLC_load() { */ ccs = ((dnlce - i) < cha) ? (dnlce - i) : cha; ccl = sizeof(struct dnlc__cachent) * ccs; - if (kread(ctx, (KA_T)wa, (char *)dnlc, ccl)) + if (kread((KA_T)wa, (char *)dnlc, ccl)) break; /* * Process the "chunk". @@ -1174,7 +1176,7 @@ static void DTFS_load() { * Get the kernel's DTFS name cache size. */ if (get_Nl_value("ndtnc", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&dtnce, sizeof(dtnce)) || dtnce < 1) + kread(v, (char *)&dtnce, sizeof(dtnce)) || dtnce < 1) return; /* * Allocate space for a copy of the kernel's DTFS name cache. @@ -1190,7 +1192,7 @@ static void DTFS_load() { /* * Read the kernel's DTFS name cache. */ - if (!dtnc || !kcl || !ka || kread(ctx, ka, (char *)dtnc, kcl)) + if (!dtnc || !kcl || !ka || kread(ka, (char *)dtnc, kcl)) return; /* * Build a local copy of the kernel's DTFS name cache. @@ -1251,7 +1253,7 @@ static void HTFS_load() { * Get the kernel's HTFS name cache size. */ if (get_Nl_value("nhtnc", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&htnce, sizeof(htnce)) || htnce < 1) + kread(v, (char *)&htnce, sizeof(htnce)) || htnce < 1) return; /* * Allocate space for a copy of the kernel's HTFS name cache. @@ -1267,7 +1269,7 @@ static void HTFS_load() { /* * Read the kernel's HTFS name cache. */ - if (!htnc || !kcl || !ka || kread(ctx, ka, (char *)htnc, kcl)) + if (!htnc || !kcl || !ka || kread(ka, (char *)htnc, kcl)) return; /* * Build a local copy of the kernel's HTFS name cache. @@ -1305,10 +1307,11 @@ static void HTFS_load() { * LNC_enter() - make a local name cache entry */ -static int LNC_enter(struct lnch *le, /* skeleton local entry */ - char *nm, /* name */ - int nl, /* name length */ - char *fs) /* file system name */ +static int LNC_enter(le, nm, nl, fs) +struct lnch *le; /* skeleton local entry */ +char *nm; /* name */ +int nl; /* name length */ +char *fs; /* file system name */ { struct lnch *lc; MALLOC_S len; @@ -1540,9 +1543,10 @@ void ncache_load() { * ncache_lookup() - look up a node's name in the kernel's name caches */ -char *ncache_lookup(char *buf, /* receiving name buffer */ - int blen, /* receiving buffer length */ - int *fp) /* full path reply */ +char *ncache_lookup(buf, blen, fp) +char *buf; /* receiving name buffer */ +int blen; /* receiving buffer length */ +int *fp; /* full path reply */ { char *cp = buf; int nl, rlen; @@ -1555,7 +1559,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * file system mount point, return an empty path reply. That tells the * caller to print the file system mount point name only. */ - if (Lf->inp_ty == 1 && Lf->fs_ino && Lf->inode == Lf->fs_ino) + if (Lf->inode_def && Lf->fs_ino && Lf->inode == Lf->fs_ino) return (cp); if (!LNC_nc) return ((char *)NULL); @@ -1606,8 +1610,8 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ /* * Look up the device-inode name cache entry. */ - if (Lf->dev_def && Lf->inp_ty == 1 && - (lc = DIN_addr(&Lf->dev, Lf->inode)) && !lc->dup) { + if (Lf->dev_def && Lf->inode_def && (lc = DIN_addr(&Lf->dev, Lf->inode)) && + !lc->dup) { if ((nl = (int)lc->nl) > (blen - 1)) return (*cp ? cp : (char *)NULL); cp = buf + blen - nl - 1; @@ -1696,7 +1700,7 @@ static void NFS_load() { * Get the kernel's NFS name cache size. */ if (get_Nl_value("nnfnc", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&nfnce, sizeof(nfnce)) || nfnce < 1) + kread(v, (char *)&nfnce, sizeof(nfnce)) || nfnce < 1) return; /* * Allocate space for a copy of the kernel's NFS name cache. @@ -1712,7 +1716,7 @@ static void NFS_load() { /* * Read the kernel's NFS name cache. */ - if (!nfnc || !kcl || !ka || kread(ctx, ka, (char *)nfnc, kcl)) + if (!nfnc || !kcl || !ka || kread(ka, (char *)nfnc, kcl)) return; /* * Build a local copy of the kernel's NFS name cache. @@ -1774,7 +1778,7 @@ KA_T r; /* node's rnode address */ /* * Read rnode and get the node number. */ - if (kread(ctx, r, (char *)&rn, sizeof(rn))) + if (kread(r, (char *)&rn, sizeof(rn))) return (0); # if OSRV < 500 @@ -1846,7 +1850,7 @@ static void SYSV_load() { s5nce = Var.v_s5cacheents; # else /* OSRV>=500 */ if (get_Nl_value("nsfnc", Drive_Nl, &v) < 0 || !v || - kread(ctx, v, (char *)&s5nce, sizeof(s5nce))) + kread(v, (char *)&s5nce, sizeof(s5nce))) return; # endif /* OSRV<500 */ @@ -1866,7 +1870,7 @@ static void SYSV_load() { /* * Read the kernel's SYSV name cache. */ - if (!s5nc || !kcl || !ka || kread(ctx, ka, (char *)s5nc, kcl)) + if (!s5nc || !kcl || !ka || kread(ka, (char *)s5nc, kcl)) return; /* * Build a local copy of the kernel's SYSV name cache. diff --git a/lib/dialects/osr/dsock.c b/lib/dialects/osr/dsock.c index aa3f3cc9..f5601c67 100644 --- a/lib/dialects/osr/dsock.c +++ b/lib/dialects/osr/dsock.c @@ -68,7 +68,7 @@ void process_socket(i) struct inode *i; /* inode pointer */ struct un_dev ud; #endif /* OSRV<500 */ - (void)snpf(Lf->type, sizeof(Lf->type), "sock"); + Lf->type = LSOF_TYPE_SOCKET; /* * Read socket. */ @@ -77,12 +77,12 @@ void process_socket(i) struct inode *i; /* inode pointer */ return; } spa = Socktab + (GET_MIN_DEV(i->i_rdev) * sizeof(struct socket *)); - if (kread(ctx, spa, (char *)&sa, sizeof(sa))) { + if (kread(spa, (char *)&sa, sizeof(sa))) { (void)snpf(Namech, Namechl, "can't read socket pointer at %s", print_kptr(spa, (char *)NULL, 0)); enter_nm(Namech); } - if (kread(ctx, sa, (char *)&s, sizeof(s))) { + if (kread(sa, (char *)&s, sizeof(s))) { (void)snpf(Namech, Namechl, "can't read socket structure at %s", print_kptr(sa, (char *)NULL, 0)); enter_nm(Namech); @@ -92,7 +92,7 @@ void process_socket(i) struct inode *i; /* inode pointer */ * Read domain structure. */ if (!s.so_proto.pr_domain || - kread(ctx, (KA_T)s.so_proto.pr_domain, (char *)&d, sizeof(d))) { + kread((KA_T)s.so_proto.pr_domain, (char *)&d, sizeof(d))) { (void)snpf(Namech, Namechl, "can't read protocol domain from %s", print_kptr((KA_T)s.so_proto.pr_domain, (char *)NULL, 0)); enter_nm(Namech); @@ -105,9 +105,8 @@ void process_socket(i) struct inode *i; /* inode pointer */ case AF_INET: if (Fnet) Lf->sf |= SELNET; - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); - printiproto((int)s.so_proto.pr_protocol); - Lf->inp_ty = 2; + Lf->type = LSOF_TYPE_INET; + enter_ip_proto((int)s.so_proto.pr_protocol); /* * Get protocol control block address from stream head queue structure. */ @@ -116,21 +115,21 @@ void process_socket(i) struct inode *i; /* inode pointer */ shs = 1; if (shs && sh.q_ptr) { enter_dev_ch(print_kptr((KA_T)sh.q_ptr, (char *)NULL, 0)); - if (kread(ctx, (KA_T)sh.q_ptr, (char *)&pcb, sizeof(pcb)) == 0) + if (kread((KA_T)sh.q_ptr, (char *)&pcb, sizeof(pcb)) == 0) pcbs = 1; } /* * Print local and remote addresses. */ if (pcbs) { - if (pcb.inp_ppcb && strcasecmp(Lf->iproto, "udp") == 0) { + if (pcb.inp_ppcb && Lf->iproto == LSOF_PROTOCOL_UDP) { /* * If this is a UDP socket file, get the udpdev structure * at the PCB's per-protocol control block address. It * may contain a foreign address. */ - if (!kread(ctx, (KA_T)pcb.inp_ppcb, (char *)&udp, sizeof(udp))) { + if (!kread((KA_T)pcb.inp_ppcb, (char *)&udp, sizeof(udp))) { #if OSRV >= 500 if (udp.ud_lsin.sin_addr.s_addr != INADDR_ANY || @@ -183,8 +182,8 @@ void process_socket(i) struct inode *i; /* inode pointer */ if (udptm && !Lf->nma) (void)udp_tm(udp.ud_ftime); } - if (pcb.inp_ppcb && strcasecmp(Lf->iproto, "tcp") == 0 && - kread(ctx, (KA_T)pcb.inp_ppcb, (char *)&t, sizeof(t)) == 0) { + if (pcb.inp_ppcb && Lf->iproto == LSOF_PROTOCOL_TCP && + kread((KA_T)pcb.inp_ppcb, (char *)&t, sizeof(t)) == 0) { ts = 1; /* * Save the TCP state from its control block. @@ -206,11 +205,11 @@ void process_socket(i) struct inode *i; /* inode pointer */ } } #else /* OSRV>=500 */ - if (s.so_name && !kread(ctx, (KA_T)s.so_name, (char *)&si, sizeof(si))) { + if (s.so_name && !kread((KA_T)s.so_name, (char *)&si, sizeof(si))) { la = (unsigned char *)&si.sin_addr; lp = (int)ntohs(si.sin_port); } - if (s.so_peer && !kread(ctx, (KA_T)s.so_peer, (char *)&si, sizeof(si))) { + if (s.so_peer && !kread((KA_T)s.so_peer, (char *)&si, sizeof(si))) { if (si.sin_addr.s_addr != INADDR_ANY || si.sin_port != 0) { fa = (unsigned char *)&si.sin_addr; fp = (int)ntohs(si.sin_port); @@ -262,24 +261,28 @@ void process_socket(i) struct inode *i; /* inode pointer */ else Lf->sz = (SZOFFTYPE)(t.t_iqsize + t.t_qsize); Lf->sz_def = 1; + Lf->off_def = 1; } else if (shs) { Lf->sz = (SZOFFTYPE)sh.q_count; Lf->sz_def = 1; - } + Lf->off_def = 1; + } else + Lf->off_def = 1; break; #if OSRV >= 500 case AF_UNIX: if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_TYPE_UNIX; /* * Read Unix protocol control block and the Unix address structure. */ enter_dev_ch(print_kptr(sa, (char *)NULL, 0)); + Lf->off_def = 1; if (s.so_stp && !readstdata((KA_T)s.so_stp, &sd) && !readsthead((KA_T)sd.sd_wrq, &sh)) { - if (!sh.q_ptr || kread(ctx, (KA_T)sh.q_ptr, (char *)&ud, sizeof(ud))) { + if (!sh.q_ptr || kread((KA_T)sh.q_ptr, (char *)&ud, sizeof(ud))) { (void)snpf(Namech, Namechl, "can't read un_dev from %s", print_kptr((KA_T)sh.q_ptr, (char *)NULL, 0)); break; @@ -288,7 +291,7 @@ void process_socket(i) struct inode *i; /* inode pointer */ enter_dev_ch(print_kptr((KA_T)ud.so_rq, (char *)NULL, 0)); if (ud.local_addr.sun_family == AF_UNIX) { Lf->inode = (unsigned long)ud.bnd_param.user_addr.inode_no; - Lf->inp_ty = 1; + Lf->inode_def = 1; ud.local_addr.sun_path[sizeof(ud.local_addr.sun_path) - 1] = '\0'; if (Sfile && is_file_named(ud.local_addr.sun_path, 0)) @@ -297,7 +300,7 @@ void process_socket(i) struct inode *i; /* inode pointer */ (void)snpf(Namech, Namechl, "%s", ud.local_addr.sun_path); } else if (ud.for_addr.sun_family == AF_UNIX) { Lf->inode = (unsigned long)ud.bnd_param.user_addr.inode_no; - Lf->inp_ty = 1; + Lf->inode_def = 1; ud.for_addr.sun_path[sizeof(ud.for_addr.sun_path) - 1] = '\0'; if (Sfile && is_file_named(ud.for_addr.sun_path, 0)) Lf->sf |= SELNM; @@ -337,7 +340,7 @@ void udp_tm(tm) time_t tm; /* time when packet was sent */ */ if (!Lbolt) return; - if (Hz < 0 || kread(ctx, (KA_T)Lbolt, (char *)&lbolt, sizeof(lbolt)) || + if (Hz < 0 || kread((KA_T)Lbolt, (char *)&lbolt, sizeof(lbolt)) || tm >= lbolt || (et = (time_t)((lbolt - tm) / Hz)) == 0) return; /* diff --git a/lib/dialects/osr/dstore.c b/lib/dialects/osr/dstore.c index c5d6ceb7..6b816f05 100644 --- a/lib/dialects/osr/dstore.c +++ b/lib/dialects/osr/dstore.c @@ -41,7 +41,7 @@ int CloneMajor; /* clone major device */ /* * Drive_Nl -- table to drive the building of Nl[] via build_Nl() - * (See lsof.h and misc.c.) + * (See common.h and misc.c.) */ struct drive_Nl Drive_Nl[] = {{"ncdev", "cdevcnt"}, diff --git a/lib/dialects/osr/machine.h b/lib/dialects/osr/machine.h index 2bae2d3d..c1102d31 100644 --- a/lib/dialects/osr/machine.h +++ b/lib/dialects/osr/machine.h @@ -121,7 +121,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ # define HASFSINO 1 @@ -131,7 +131,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -315,14 +315,6 @@ /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -478,7 +470,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -515,10 +507,11 @@ # define USE_LIB_PRINT_TCPTPI 1 /* ptti.c */ # define USE_LIB_READDEV 1 /* rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ /* #define USE_LIB_RNCH 1 rnch.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ -/* #define USE_LIB_SNPF 1 snpf.c */ + # define snpf snprintf /* use the system's snprintf() */ /* diff --git a/lib/dialects/sun/Makefile b/lib/dialects/sun/Makefile index c3e0cd4b..3c931f76 100644 --- a/lib/dialects/sun/Makefile +++ b/lib/dialects/sun/Makefile @@ -12,18 +12,18 @@ P= CDEF= CDEFS= ${CDEF} ${CFGF} -INCL= ${DINC} +INCL= ${DINC} -Iinclude -Ilib -Isrc -I. CFLAGS= ${CDEFS} ${INCL} ${DEBUG} -HDR= lsof.h lsof_fields.h dlsof.h machine.h proto.h dproto.h +HDR= lib/common.h include/lsof_fields.h dlsof.h machine.h lib/proto.h dproto.h -SRC= ddev.c dfile.c dmnt.c dnode.c dnode1.c dnode2.c dproc.c dsock.c \ +SRC= ddev.c dfile.c dmnt.c dnode.c dnode1.c dnode2.c dprint.c dproc.c dsock.c \ dstore.c \ - arg.c main.c misc.c node.c print.c proc.c store.c usage.c util.c + arg.c main.c print.c store.c usage.c util.c -OBJ= ddev.o dfile.o dmnt.o dnode.o dnode1.o dnode2.o dproc.o dsock.o \ +OBJ= ddev.o dfile.o dmnt.o dnode.o dnode1.o dnode2.o dprint.o dproc.o dsock.o \ dstore.o \ - arg.o main.o misc.o node.o print.o proc.o store.o usage.o util.o + arg.o main.o print.o store.o usage.o util.o MAN= lsof.8 @@ -132,7 +132,7 @@ dnode1.o: ${HDR} dnode1.c dnode2.o: ${HDR} dnode2.c -dproc.o: ${HDR} kernelbase.h dproc.c +dproc.o: ${HDR} dproc.c dsock.o: ${HDR} dsock.c diff --git a/lib/dialects/sun/Mksrc b/lib/dialects/sun/Mksrc index 78ad2561..bf5851ad 100755 --- a/lib/dialects/sun/Mksrc +++ b/lib/dialects/sun/Mksrc @@ -25,3 +25,13 @@ D=lib/dialects/sun L="ddev.c dfile.c dlsof.h dmnt.c dnode.c dnode1.c dnode2.c dproc.c dproto.h dsock.c dstore.c machine.h" mksrc + +D=src +L="arg.c main.c print.c ptti.c store.c usage.c util.c" + +mksrc + +D=src/dialects/linux +L="dprint.c" + +mksrc diff --git a/lib/dialects/sun/ddev.c b/lib/dialects/sun/ddev.c index 559c43db..fe229c67 100644 --- a/lib/dialects/sun/ddev.c +++ b/lib/dialects/sun/ddev.c @@ -60,9 +60,9 @@ static int rmdupdev(struct lsof_context *ctx, struct l_dev ***dp, int n, * make_devtp() - make Devtp[] entry */ -static void make_devtp(struct lsof_context *ctx, /* context */ - struct stat *s, /* device lstat() buffer */ - char *p) /* device path name */ +static void make_devtp(struct lsof_context *ctx, + struct stat *s, /* device lstat() buffer */ + char *p) /* device path name */ { /* @@ -99,11 +99,10 @@ static void make_devtp(struct lsof_context *ctx, /* context */ * printdevname() - print block or character device name */ -int printdevname(struct lsof_context *ctx, /* context */ - dev_t *dev, /* device */ - dev_t *rdev, /* raw device */ - int f, /* 1 = print trailing '\n' */ - int nty) /* node type: N_BLK or N_CHR */ +int printdevname(struct lsof_context *ctx, dev_t *dev, /* device */ + dev_t *rdev, /* raw device */ + int f, /* 1 = print trailing '\n' */ + int nty) /* node type: N_BLK or N_CHR */ { struct clone *c; struct l_dev *dp; @@ -380,8 +379,8 @@ void read_clone(struct lsof_context *ctx) { * or /device (Solaris) */ -void readdev(struct lsof_context *ctx, /* context */ - int skip) /* skip device cache read if 1 */ +void readdev(struct lsof_context *ctx, + int skip) /* skip device cache read if 1 */ { #if defined(HASDCACHE) @@ -640,7 +639,7 @@ void readdev(struct lsof_context *ctx, /* context */ * clr_sect() - clear cached clone and pseudo sections */ -void clr_sect(struct lsof_context *ctx) { +void clr_sect() { if (Clone) { struct clone *c, *c1; @@ -795,7 +794,7 @@ int rw_clone_sect(struct lsof_context *ctx, for (c = Clone, n = 0; c; c = c->next, n++) ; (void)snpf(buf, sizeof(buf), "clone section: %d\n", n); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); /* * Write the clone section lines. @@ -808,7 +807,7 @@ int rw_clone_sect(struct lsof_context *ctx, for (c = Clone; c; c = c->next) { (void)snpf(buf, sizeof(buf), " %lx %d %ld %s\n", (long)c->cd.rdev, c->n, (long)c->cd.inode, c->cd.name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); } return (0); @@ -827,11 +826,11 @@ int rw_clone_sect(struct lsof_context *ctx, void rereaddev(struct lsof_context *ctx) { (void)clr_devtab(ctx); - (void)clr_sect(ctx); + (void)clr_sect(); Devx = 0; # if defined(DCACHE_CLR) - (void)DCACHE_CLR(ctx); + (void)DCACHE_CLR(); # endif /* defined(DCACHE_CLR) */ readdev(ctx, 1); @@ -959,7 +958,7 @@ int rw_pseudo_sect(struct lsof_context *ctx, for (p = Pseudo, n = 0; p; p = p->next, n++) ; (void)snpf(buf, sizeof(buf), "pseudo section: %d\n", n); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); /* * Write the pseudo section lines. @@ -972,7 +971,7 @@ int rw_pseudo_sect(struct lsof_context *ctx, for (p = Pseudo; p; p = p->next) { (void)snpf(buf, sizeof(buf), " %lx %ld %s\n", (long)p->pd.rdev, (long)p->pd.inode, p->pd.name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); } return (0); @@ -990,8 +989,8 @@ int rw_pseudo_sect(struct lsof_context *ctx, * Note: rereads entire device table when an entry can't be verified. */ -int vfy_dev(struct lsof_context *ctx, /* context */ - struct l_dev *dp) /* device table pointer */ +int vfy_dev(struct lsof_context *ctx, + struct l_dev *dp) /* device table pointer */ { struct stat sb; @@ -1017,7 +1016,7 @@ int vfy_dev(struct lsof_context *ctx, /* context */ * rmdupdev() - remove duplicate (major/minor/inode) devices */ -static int rmdupdev(struct lsof_context *ctx, /* context */ +static int rmdupdev(struct lsof_context *ctx, struct l_dev ***dp, /* device table pointers address */ int n, /* number of pointers */ int ty) /* type: 0 = block, 1 = char */ diff --git a/lib/dialects/sun/dfile.c b/lib/dialects/sun/dfile.c index 3545cd33..9ecee1b1 100644 --- a/lib/dialects/sun/dfile.c +++ b/lib/dialects/sun/dfile.c @@ -39,30 +39,13 @@ static char copyright[] = * Local structures */ -struct hsfile { - struct sfile *s; /* the Sfile table address */ - struct hsfile *next; /* the next hash bucket entry */ -}; - /* * Local static variables */ static struct hsfile *HbyCd = /* hash by clone buckets */ (struct hsfile *)NULL; -static int HbyCdCt = 0; /* HbyCd entry count */ -static struct hsfile *HbyFdi = /* hash by file buckets */ - (struct hsfile *)NULL; -static int HbyFdiCt = 0; /* HbyFdi entry count */ -static struct hsfile *HbyFrd = /* hash by file raw device buckets */ - (struct hsfile *)NULL; -static int HbyFrdCt = 0; /* HbyFrd entry count */ -static struct hsfile *HbyFsd = /* hash by file system buckets */ - (struct hsfile *)NULL; -static int HbyFsdCt = 0; /* HbyFsd entry count */ -static struct hsfile *HbyNm = /* hash by name buckets */ - (struct hsfile *)NULL; -static int HbyNmCt = 0; /* HbyNm entry count */ +static int HbyCdCt = 0; /* HbyCd entry count */ /* * Local definitions @@ -237,8 +220,8 @@ void hashSfile(struct lsof_context *ctx) { * is_file_named() - is this file named? */ -int is_file_named(struct lsof_context *ctx, /* context */ - char *p, /* path name; NULL = search by device +int is_file_named(struct lsof_context *ctx, + char *p, /* path name, NULL = search by device * and inode (from *Lf) */ int nt, /* node type -- e.g., N_* */ enum vtype vt, /* vnode type */ @@ -278,7 +261,7 @@ int is_file_named(struct lsof_context *ctx, /* context */ /* * Check for a regular file. */ - if (!f && HbyFdiCt && Lf->dev_def && (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + if (!f && HbyFdiCt && Lf->dev_def && Lf->inode_def) { for (sh = &HbyFdi[SFHASHDEVINO(GET_MAJ_DEV(Lf->dev), GET_MIN_DEV(Lf->dev), Lf->inode, SFDIHASH)]; @@ -306,8 +289,7 @@ int is_file_named(struct lsof_context *ctx, /* context */ * Check for a character or block device match. */ if (!f && HbyFrdCt && ((vt = VCHR) || (vt = VBLK)) && Lf->dev_def && - (Lf->dev == DevDev) && Lf->rdev_def && - (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + (Lf->dev == DevDev) && Lf->rdev_def && Lf->inode_def) { for (sh = &HbyFrd[SFHASHRDEVI( GET_MAJ_DEV(Lf->dev), GET_MIN_DEV(Lf->dev), GET_MAJ_DEV(Lf->rdev), GET_MIN_DEV(Lf->rdev), Lf->inode, @@ -332,7 +314,8 @@ int is_file_named(struct lsof_context *ctx, /* context */ /* * If the search argument isn't a file system, propagate it - * to Namech[]; otherwise, let printname() compose the name. + * to Namech[]; otherwise, let printname() compose the + * name. */ (void)snpf(Namech, Namechl, "%s", s->name); if (s->devnm) { @@ -352,8 +335,9 @@ int is_file_named(struct lsof_context *ctx, /* context */ * print_dev() - print device */ -char *print_dev(struct lfile *lf, /* file whose device is to be printed */ - dev_t *dev) /* device to be printed */ +char *print_dev(lf, dev) +struct lfile *lf; /* file whose device is to be printed */ +dev_t *dev; /* device to be printed */ { static char buf[128]; /* @@ -402,7 +386,7 @@ extern int print_v_path(struct lsof_context *ctx, # endif /* defined(HASMNTSTAT) */ # if defined(HASVXFS) && defined(HASVXFSRNL) - if (lf->is_vxfs && (lf->inp_ty == 1) && lf->fsdir) { + if (lf->is_vxfs && Lf->inode_def && lf->fsdir) { if (print_vxfs_rnl_path(lf)) return (1); } @@ -412,7 +396,7 @@ extern int print_v_path(struct lsof_context *ctx, if (buf[0]) { # if defined(HASMNTSTAT) - if (!lf->mnt_stat && lf->dev_def && (lf->inp_ty == 1)) { + if (!lf->mnt_stat && lf->dev_def && lf->inode_def) { /* * No problem was detected in applying stat(2) to this mount point. @@ -537,8 +521,8 @@ extern void read_v_path(struct lsof_context *ctx, * process_file() - process file */ -void process_file(struct lsof_context *ctx, /* context */ - KA_T fp) /* kernel file structure address */ +void process_file(struct lsof_context *ctx, + KA_T fp) /* kernel file structure address */ { struct file f; int flag; @@ -554,7 +538,6 @@ void process_file(struct lsof_context *ctx, /* context */ return; } Lf->off = (SZOFFTYPE)f.f_offset; - Lf->off_def = 1; if (f.f_count) { @@ -574,10 +557,13 @@ void process_file(struct lsof_context *ctx, /* context */ */ Lf->fct = (long)f.f_count; Lf->fsv |= FSV_CT; + Lf->fsa = fp; Lf->fsv |= FSV_FA; + Lf->ffg = (long)f.f_flag; Lf->fsv |= FSV_FG; + Lf->fna = (KA_T)f.f_vnode; Lf->fsv |= FSV_NI; #endif /* defined(HASFSTRUCT) */ diff --git a/lib/dialects/sun/dlsof.h b/lib/dialects/sun/dlsof.h index 34617338..ee21f0a0 100644 --- a/lib/dialects/sun/dlsof.h +++ b/lib/dialects/sun/dlsof.h @@ -520,7 +520,7 @@ typedef struct CTF_request { # define CTF_MEMBER(name) \ { #name, CTF_MEMBER_UNDEF } # define CTF_MEMBER_READ(ka, s, members, member) \ - kread(ctx, (KA_T)(ka) + members[MX_##member].m_offset, \ + kread(ctx, (KA_T)(ka) + members[MX_##member].m_offset, \ (char *)&s->member, sizeof(s->member)) # endif /* defined(HAS_LIBCTF) */ @@ -692,4 +692,6 @@ extern int Unof; /* u_nofiles value */ # endif /* solaris>=80000 */ # endif /* defined(HASNCACHE) */ +struct lsof_context_dialect {}; + #endif /* SOLARIS_LSOF_H */ diff --git a/lib/dialects/sun/dmnt.c b/lib/dialects/sun/dmnt.c index c417396b..62594929 100644 --- a/lib/dialects/sun/dmnt.c +++ b/lib/dialects/sun/dmnt.c @@ -39,22 +39,18 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - -static char *getmntdev(struct lsof_context *ctx, char *o, int l, struct stat *s, - char *f); +static char *getmntdev, (char *o, int l, struct stat *s char *f); /* * getmntdev() - get mount entry's device number */ -static char *getmntdev(struct lsof_context *ctx, /* context */ - char *o, /* start of device option */ - int l, /* length of device keyword (not - * including `=') */ - struct stat *s, /* pointer to stat buffer to create */ - char *f) /* file system type */ +static char *getmntdev(o, l, s, f) +char *o; /* start of device option */ +int l; /* length of device keyword (not + * including `=') */ +struct stat *s; /* pointer to stat buffer to create */ +char *f; /* file system type */ { char *opte; @@ -183,7 +179,7 @@ struct mounts *readmnt(struct lsof_context *ctx) { */ dopt = hasmntopt(mp, MNTOPT_DEV); if (ignore) { - if (!dopt || !(dopte = getmntdev(ctx, dopt, devl, &sb, + if (!dopt || !(dopte = getmntdev(dopt, devl, &sb, #if defined(HASFSTYPE) mp->mnt_fstype @@ -196,7 +192,7 @@ struct mounts *readmnt(struct lsof_context *ctx) { stat = 1; } else if (statsafely(ctx, dn, &sb)) { if (dopt) { - if (!(dopte = getmntdev(ctx, dopt, devl, &sb, + if (!(dopte = getmntdev(dopt, devl, &sb, #if defined(HASFSTYPE) mp->mnt_fstype @@ -336,7 +332,7 @@ struct mounts *readmnt(struct lsof_context *ctx) { * readvfs() - read vfs structure */ -struct l_vfs *readvfs(struct lsof_context *ctx, /* context */ +struct l_vfs *readvfs(struct lsof_context *ctx, KA_T ka, /* vfs structure kernel address, if * must be read from kernel */ struct vfs *la, /* local vfs structure address, non- diff --git a/lib/dialects/sun/dnode.c b/lib/dialects/sun/dnode.c index e28fecf1..285b8080 100644 --- a/lib/dialects/sun/dnode.c +++ b/lib/dialects/sun/dnode.c @@ -411,7 +411,8 @@ static v_optab_t **Voptab = (v_optab_t **)NULL; */ static void build_Voptab(struct lsof_context *ctx); -static char isvlocked(struct lsof_context *ctx, struct vnode *va); +static enum lsof_lock_mode isvlocked(struct lsof_context *ctx, + struct vnode *va); static int readinode(struct lsof_context *ctx, KA_T ia, struct inode *i); static void read_mi(struct lsof_context *ctx, KA_T s, dev_t *dev, caddr_t so, int *so_st, KA_T *so_ad, struct l_dev **sdp); @@ -422,10 +423,10 @@ static int read_nan(struct lsof_context *ctx, KA_T na, KA_T aa, struct fnnode *rn); static int read_nson(struct lsof_context *ctx, KA_T na, KA_T sa, struct sonode *sn); -static int read_nusa(struct lsof_context *ctx, struct soaddr *so, - struct sockaddr_un *ua); +static int read_nusa(struct lsof_context *ctx, + struct soaddr *so struct sockaddr_un *ua); # else /* solaris<20600 */ -static int read_nan(struct lsof_context *ctx, KA_T na, KA_T aa, +static int read_nan(struct lsof_context *ctxKA_T na, KA_T aa, struct autonode *a); # endif /* solaris>=20600 */ static int idoorkeep(struct lsof_context *ctx, struct door_node *d); @@ -471,15 +472,14 @@ static int read_npi(struct lsof_context *ctx, KA_T na, struct vnode *v, struct pid *pids); #endif /* defined(HASPROCFS) */ -static char *ent_fa(KA_T *a1, KA_T *a2, char *d, int *len); +static char *ent_fa, (KA_T * a1, KA_T *a2, char *d int *len); static int is_socket(struct lsof_context *ctx, struct vnode *v); static int read_cni(struct lsof_context *ctx, struct snode *s, struct vnode *rv, struct vnode *v, struct snode *rs, struct dev_info *di, char *din, int dinl); #if defined(HASCACHEFS) -static int read_ncn(struct lsof_context *ctx, KA_T na, KA_T ca, - struct cnode *cn); +static int read_ncn(KA_T na, KA_T ca, struct cnode *cn); #endif /* defined(HASCACHEFS) */ static int read_nln(struct lsof_context *ctx, KA_T na, KA_T la, @@ -518,13 +518,13 @@ static KA_T Vvops[VXVOP_NUM]; /* addresses of: #if defined(VOPNAME_OPEN) && solaris >= 100000 # define GETVOPS(name, nl, ops) \ - if (get_Nl_value(name, nl, &ops) < 0) \ + if (get_Nl_value(ctx, name, nl, &ops) < 0) \ ops = (KA_T)0; \ else if (kread(ctx, ops, (char *)&ops, sizeof(ops))) \ ops = (KA_T)0 #else /* !defined(VOPNAME_OPEN) || solaris<100000 */ # define GETVOPS(name, nl, ops) \ - if (get_Nl_value(name, nl, &ops) < 0) \ + if (get_Nl_value(ctx, name, nl, &ops) < 0) \ ops = (KA_T)0 #endif /* defined(VOPNAME_OPEN) && solaris>=100000 */ @@ -698,11 +698,10 @@ static void build_Voptab(struct lsof_context *ctx) { * CTF_getmem() -- get CTF members */ -int CTF_getmem(struct lsof_context *ctx, /* context*/ - ctf_file_t *f, /* CTF file handle */ - const char *mod, /* module name */ - const char *ty, /* type */ - CTF_member_t *mem) /* member table */ +int CTF_getmem(struct lsof_context *ctx, ctf_file_t *f, /* CTF file handle */ + const char *mod, /* module name */ + const char *ty, /* type */ + CTF_member_t *mem) /* member table */ { int err; /* error flag */ ctf_id_t id; /* CTF ID */ @@ -770,10 +769,9 @@ int CTF_getmem(struct lsof_context *ctx, /* context*/ * CTF_init - initialize CTF library access */ -void CTF_init(struct lsof_context *ctx, /* context */ - int *i, /* initialization status */ - char *t, /* kernel module template */ - CTF_request_t *r) /* CTF requests */ +void CTF_init(struct lsof_context *ctx, int *i, /* initialization status */ + char *t, /* kernel module template */ + CTF_request_t *r) /* CTF requests */ { int err; /* error status */ ctf_file_t *f; /* CTF file info handle */ @@ -868,10 +866,11 @@ void CTF_init(struct lsof_context *ctx, /* context */ * CTF_memCB() - Callback function for ctf_member_iter() */ -int CTF_memCB(const char *name, /* structure member name */ - ctf_id_t id, /* CTF ID */ - ulong_t offset, /* member offset */ - void *arg) /* member table */ +int CTF_memCB(name, id, offset, arg) const + char *name; /* structure member name */ +ctf_id_t id; /* CTF ID */ +ulong_t offset; /* member offset */ +void *arg; /* member table */ { CTF_member_t *mp; /* @@ -891,10 +890,11 @@ int CTF_memCB(const char *name, /* structure member name */ * ent_fa() - enter fattach addresses in NAME column addition */ -static char *ent_fa(KA_T *a1, /* first fattach address (NULL OK) */ - KA_T *a2, /* second fattach address */ - char *d, /* direction ("->" or "<-") */ - int *len) /* returned description length */ +static char *ent_fa(a1, a2, d, len) +KA_T *a1; /* first fattach address (NULL OK) */ +KA_T *a2; /* second fattach address */ +char *d; /* direction ("->" or "<-") */ +int *len; /* returned description length */ { static char buf[1024]; size_t bufl = sizeof(buf); @@ -930,8 +930,8 @@ static char *ent_fa(KA_T *a1, /* first fattach address (NULL OK) */ * is_socket() - is the stream a socket? */ -static int is_socket(struct lsof_context *ctx, /* context */ - struct vnode *v) /* vnode pointer */ +static int is_socket(struct lsof_context *ctx, + struct vnode *v) /* vnode pointer */ { char *cp, *ep, *pf; int i, j, len, n, pfl; @@ -1022,8 +1022,8 @@ static int is_socket(struct lsof_context *ctx, /* context */ * isvlocked() - is Solaris vnode locked? */ -static char isvlocked(struct lsof_context *ctx, /* context */ - struct vnode *va) /* local vnode address */ +static enum lsof_lock_mode isvlocked(struct lsof_context *ctx, + struct vnode *va) /* local vnode address */ { #if solaris < 20500 @@ -1056,7 +1056,7 @@ static char isvlocked(struct lsof_context *ctx, /* context */ #endif /* solaris>=20300 */ if (va->v_filocks == NULL) - return (' '); + return (LSOF_LOCK_NONE); #if solaris < 20500 # if solaris > 20300 || \ @@ -1070,7 +1070,7 @@ static char isvlocked(struct lsof_context *ctx, /* context */ i = 0; do { if (kread(ctx, fp, (char *)&f, sizeof(f))) - return (' '); + return (LSOF_LOCK_NONE); i++; if (f.set.l_pid != (pid_t)Lp->pid) continue; @@ -1081,13 +1081,13 @@ static char isvlocked(struct lsof_context *ctx, /* context */ l = 0; switch (f.set.l_type & (F_RDLCK | F_WRLCK)) { case F_RDLCK: - return (l ? 'R' : 'r'); + return (l ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL); case F_WRLCK: - return (l ? 'W' : 'w'); + return (l ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL); case F_RDLCK | F_WRLCK: - return ('u'); + return (LSOF_LOCK_READ_WRITE); default: - return ('N'); + return (LSOF_LOCK_SOLARIS_NFS); } } while ((fp = (KA_T)f.next) && (fp != ff) && (i < 10000)); } @@ -1098,7 +1098,7 @@ static char isvlocked(struct lsof_context *ctx, /* context */ i = 0; do { if (kread(ctx, lp, (char *)&ld, sizeof(ld))) - return (' '); + return (LSOF_LOCK_NONE); i++; if (!(LOCK_FLAGS & ACTIVE_LOCK) || LOCK_OWNER != (pid_t)Lp->pid) continue; @@ -1116,16 +1116,17 @@ static char isvlocked(struct lsof_context *ctx, /* context */ l = 0; switch (LOCK_TYPE) { case F_RDLCK: - return (l ? 'R' : 'r'); + return (l ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL); case F_WRLCK: - return (l ? 'W' : 'w'); + return (l ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL); case (F_RDLCK | F_WRLCK): - return ('u'); + return (LSOF_LOCK_READ_WRITE); default: - return ('L'); + /* It was 'L' since 1997, dunno what is it */ + return (LSOF_LOCK_UNKNOWN); } } while ((lp = (KA_T)LOCK_NEXT) && (lp != lf) && (i < 10000)); - return (' '); + return (LSOF_LOCK_NONE); #endif /* solaris>=20300 */ } @@ -1133,11 +1134,10 @@ static char isvlocked(struct lsof_context *ctx, /* context */ * finddev() - look up device by device number */ -static struct l_dev *finddev(struct lsof_context *ctx, /* context */ - dev_t *dev, /* device */ - dev_t *rdev, /* raw device */ - int flags) /* look flags -- see LOOKDEV_* symbol - * definitions */ +static struct l_dev *finddev(struct lsof_context *ctx, dev_t *dev, /* device */ + dev_t *rdev, /* raw device */ + int flags) /* look flags -- see LOOKDEV_* symbol + * definitions */ { struct clone *c; struct l_dev *dp; @@ -1199,8 +1199,8 @@ static struct l_dev *finddev(struct lsof_context *ctx, /* context */ * idoorkeep() -- identify door keeper process */ -static int idoorkeep(struct lsof_context *ctx, /* context */ - struct door_node *d) /* door's node */ +static int idoorkeep(struct lsof_context *ctx, + struct door_node *d) /* door's node */ { char buf[1024]; size_t bufl = sizeof(buf); @@ -1236,8 +1236,8 @@ static int idoorkeep(struct lsof_context *ctx, /* context */ * process_node() - process vnode */ -void process_node(struct lsof_context *ctx, /* context */ - KA_T va) /* vnode kernel space address */ +void process_node(struct lsof_context *ctx, + KA_T va) /* vnode kernel space address */ { #if defined(HASCACHEFS) @@ -1261,6 +1261,7 @@ void process_node(struct lsof_context *ctx, /* context */ struct dev_info di; char din[DINAMEL]; char *ep; + char *ty; struct fifonode f; char *fa = (char *)NULL; int fal; @@ -1296,7 +1297,7 @@ void process_node(struct lsof_context *ctx, /* context */ struct l_dev *sdp = (struct l_dev *)NULL; size_t sz; struct tmpnode t; - char tbuf[128], *ty, ubuf[128]; + char tbuf[128], ubuf[128]; int tbufx; enum vtype type; struct sockaddr_un ua; @@ -1742,11 +1743,11 @@ void process_node(struct lsof_context *ctx, /* context */ if (Lf->inode >= (unsigned long)0xbaddcafe) # endif /* defined(_LP64) */ - Lf->inp_ty = 0; + Lf->inode_def = 0; else #endif /* solaris>=80000 Solaris 8 and above hack! */ - Lf->inp_ty = 1; + Lf->inode_def = 1; enter_dev_ch(ctx, print_kptr((KA_T)v->v_data, (char *)NULL, 0)); if (f.fn_flag & ISPIPE) { (void)snpf(tbuf, sizeof(tbuf), "PIPE"); @@ -1869,7 +1870,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HASVXFS) case N_VXFS: - if (read_vxnode(ctx, va, v, vfs, fx, &vx, Vvops)) + if (read_vxnode(va, v, vfs, fx, &vx, Vvops)) return; break; #endif /* defined(HASVXFS) */ @@ -1963,7 +1964,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HAS_AFS) case N_AFS: - if (readafsnode(ctx, va, v, &an)) + if (readafsnode(va, v, &an)) return; break; #endif /* defined(HAS_AFS) */ @@ -2003,7 +2004,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HASCACHEFS) case N_CACHE: - if (read_ncn(ctx, va, (KA_T)v->v_data, &cn)) + if (read_ncn(va, (KA_T)v->v_data, &cn)) return; break; #endif /* defined(HASCACHEFS) */ @@ -2116,7 +2117,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HASVXFS) case N_VXFS: - if (read_vxnode(ctx, va, v, vfs, fx, &vx, Vvops)) + if (read_vxnode(va, v, vfs, fx, &vx, Vvops)) return; break; #endif /* defined(HASVXFS) */ @@ -2359,7 +2360,7 @@ void process_node(struct lsof_context *ctx, /* context */ trdev = sdp->rdev; devs = rdevs = trdevs = 1; Lf->inode = (INODETYPE)sdp->inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; (void)snpf(nm, nmrl, "%s", sdp->name); tl = strlen(nm); nm += tl; @@ -2480,9 +2481,9 @@ void process_node(struct lsof_context *ctx, /* context */ * Locate its device numbers; * Enter the sonode address as the device (netstat's local * address); - * Get a non-NULL local sockaddr_un and enter it in Namech; - * Get a non-NULL foreign sockaddr_un and enter it in Namech; - * Check for matches on sockaddr_un.sun_path names. + * Get a non-NULL local sockaddr_un and enter it in + *Namech; Get a non-NULL foreign sockaddr_un and enter it in + *Namech; Check for matches on sockaddr_un.sun_path names. */ if (!sdp) @@ -2508,7 +2509,7 @@ void process_node(struct lsof_context *ctx, /* context */ trdev = sdp->rdev; devs = rdevs = trdevs = 1; Lf->inode = (INODETYPE)sdp->inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; (void)snpf(Namech, Namechl - 1, "%s", sdp->name); Namech[Namechl - 1] = '\0'; } else @@ -2516,7 +2517,7 @@ void process_node(struct lsof_context *ctx, /* context */ nl = snl = (int)strlen(Namech); if ((len = read_nusa(&so.so_laddr, &ua))) { - if (Sfile && is_file_named(ctx, ua.sun_path, Ntype, VSOCK, 0)) + if (Sfile && is_file_named(ua.sun_path, Ntype, VSOCK, 0)) Lf->sf |= SELNM; sepl = Namech[0] ? 2 : 0; if (len > (Namechl - nl - sepl - 1)) @@ -2529,7 +2530,7 @@ void process_node(struct lsof_context *ctx, /* context */ } } if ((len = read_nusa(&so.so_faddr, &ua))) { - if (Sfile && is_file_named(ctx, ua.sun_path, Ntype, VSOCK, 0)) + if (Sfile && is_file_named(ua.sun_path, Ntype, VSOCK, 0)) Lf->sf |= SELNM; sepl = Namech[0] ? 2 : 0; if (len > (Namechl - nl - sepl - 1)) @@ -2636,7 +2637,7 @@ void process_node(struct lsof_context *ctx, /* context */ rdev = sdp->rdev; rdevs = 1; Lf->inode = (INODETYPE)sdp->inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; (void)snpf(ubuf, sizeof(ubuf), "(%s%s%s)", print_kptr(so_ad[0], (char *)NULL, 0), so_ad[1] ? "->" : "", @@ -2644,7 +2645,7 @@ void process_node(struct lsof_context *ctx, /* context */ ? print_kptr(so_ad[1], tbuf, sizeof(tbuf)) : ""); } else { - enter_dev_ch(print_kptr(so_ad[0], (char *)NULL, 0)); + enter_dev_ch(ctx, print_kptr(so_ad[0], (char *)NULL, 0)); if (so_ad[1]) (void)snpf(ubuf, sizeof(ubuf), "(->%s)", print_kptr(so_ad[1], (char *)NULL, 0)); @@ -2672,7 +2673,7 @@ void process_node(struct lsof_context *ctx, /* context */ # endif /* solaris<20400 */ dc = (dl << 16) | dr; - enter_dev_ch(print_kptr((KA_T)dc, (char *)NULL, 0)); + enter_dev_ch(ctx, print_kptr((KA_T)dc, (char *)NULL, 0)); devs = 0; } if (soso.laddr.buf && soso.laddr.len == sizeof(ua)) { @@ -2680,8 +2681,7 @@ void process_node(struct lsof_context *ctx, /* context */ 0) { ua.sun_path[sizeof(ua.sun_path) - 1] = '\0'; if (ua.sun_path[0]) { - if (Sfile && - is_file_named(ctx, ua.sun_path, Ntype, type, 0)) + if (Sfile && is_file_named(ua.sun_path, Ntype, type, 0)) Lf->sf |= SELNM; len = (int)strlen(ua.sun_path); nl = (int)strlen(Namech); @@ -2783,7 +2783,7 @@ void process_node(struct lsof_context *ctx, /* context */ case N_AFS: if (an.ino_st) { Lf->inode = (INODETYPE)an.inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HAS_AFS) */ @@ -2797,26 +2797,26 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->inode = (INODETYPE)fnn.fn_nodeid; # endif /* solaris<20600 */ - Lf->inp_ty = 1; + Lf->inode_def = 1; break; # if solaris >= 100000 case N_DEV: if (dvs) { Lf->inode = (INODETYPE)dv.dv_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; # endif /* solaris>=100000 */ case N_DOOR: if (nns && (Lf->inode = (INODETYPE)nn.nm_vattr.va_nodeid)) { - Lf->inp_ty = 1; + Lf->inode_def = 1; break; } if (dns) { if ((Lf->inode = (INODETYPE)dn.door_index)) - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* solaris>=20500 */ @@ -2824,7 +2824,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HASCACHEFS) case N_CACHE: Lf->inode = (INODETYPE)cn.c_fileno; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #endif /* defined(HASCACHEFS) */ @@ -2849,11 +2849,11 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->inode = (INODETYPE)2; else Lf->inode = (INODETYPE)(GET_MIN_DEV(v->v_rdev) * 100); - Lf->inp_ty = 1; + Lf->inode_def = 1; break; case N_HSFS: Lf->inode = (INODETYPE)h.hs_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; case N_MNT: @@ -2861,30 +2861,30 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HASFSINO) if (vfs) { Lf->inode = vfs->fs_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } #endif /* defined(HASFSINO) */ break; case N_MVFS: Lf->inode = (INODETYPE)m.m_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; case N_NFS: Lf->inode = (INODETYPE)r.r_attr.va_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if solaris >= 100000 case N_NFS4: Lf->inode = (INODETYPE)r4.r_attr.va_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #endif /* solaris>=100000 */ case N_NM: Lf->inode = (INODETYPE)nn.nm_vattr.va_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if defined(HASPROCFS) @@ -2924,17 +2924,17 @@ void process_node(struct lsof_context *ctx, /* context */ &pc.pc_entry, pcfs.pcfs_entps); #endif /* solaris>=70000 */ - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; case N_REGLR: if (nns) { if ((Lf->inode = (INODETYPE)nn.nm_vattr.va_nodeid)) - Lf->inp_ty = 1; + Lf->inode_def = 1; } else if (ins) { if ((Lf->inode = (INODETYPE)i.i_number)) - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; case N_SAMFS: @@ -2944,20 +2944,19 @@ void process_node(struct lsof_context *ctx, /* context */ case N_SDEV: if (sdns) { Lf->inode = (INODETYPE)sdva.va_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* solaris>=110000 */ case N_SHARED: - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "SHARED"); - Lf->inp_ty = 2; + Lf->iproto = LSOF_PROTOCOL_SHARED; break; case N_STREAM: #if solaris < 100000 if (so_st && soso.lux_dev.addr.tu_addr.ino) { - if (Lf->inp_ty) { + if (Lf->inode_def) { nl = Lf->nma ? (int)strlen(Lf->nma) : 0; (void)snpf(ubuf, sizeof(ubuf), "%s(Inode=%lu)", nl ? " " : "", (unsigned long)soso.lux_dev.addr.tu_addr.ino); @@ -2970,7 +2969,7 @@ void process_node(struct lsof_context *ctx, /* context */ (void)snpf(&Lf->nma[nl], len - nl, "%s", ubuf); } else { Lf->inode = (INODETYPE)soso.lux_dev.addr.tu_addr.ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } } #endif /* solaris<100000 */ @@ -2978,14 +2977,14 @@ void process_node(struct lsof_context *ctx, /* context */ break; case N_TMP: Lf->inode = (INODETYPE)t.tn_attr.va_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if defined(HASVXFS) case N_VXFS: if (vx.ino_def) { Lf->inode = (INODETYPE)vx.ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } else if (type == VCHR) pnl = 1; break; @@ -2995,7 +2994,7 @@ void process_node(struct lsof_context *ctx, /* context */ case N_ZFS: if (zns) { Lf->inode = (INODETYPE)zn.z_id; - Lf->inp_ty = 1; + Lf->inode_def = 1; } break; #endif /* defined(HAS_ZFS) */ @@ -3003,6 +3002,7 @@ void process_node(struct lsof_context *ctx, /* context */ /* * Obtain the file size. */ + Lf->off_def = 1; switch (Ntype) { #if defined(HAS_AFS) @@ -3058,6 +3058,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if solaris >= 20600 case N_SOCK: + Lf->off_def = 1; break; #endif /* solaris>=20600 */ @@ -3072,11 +3073,13 @@ void process_node(struct lsof_context *ctx, /* context */ #if solaris >= 100000 case N_DEV: + Lf->off_def = 1; break; #endif /* solaris>=100000 */ case N_DOOR: case N_FIFO: + Lf->off_def = 1; break; case N_MNT: @@ -3087,12 +3090,15 @@ void process_node(struct lsof_context *ctx, /* context */ } else #endif /* defined(CVFS_SZSAVE) */ - break; + Lf->off_def = 1; + break; case N_MVFS: /* The location of file size isn't known. */ break; case N_NFS: - if (!(type == VCHR || type == VBLK)) { + if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; + else { Lf->sz = (SZOFFTYPE)r.r_size; Lf->sz_def = 1; } @@ -3100,7 +3106,9 @@ void process_node(struct lsof_context *ctx, /* context */ #if solaris >= 100000 case N_NFS4: - if (!(type == VCHR || type == VBLK)) { + if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; + else { Lf->sz = (SZOFFTYPE)r4.r_size; Lf->sz_def = 1; } @@ -3135,7 +3143,8 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->sz = (SZOFFTYPE)(nns ? nn.nm_vattr.va_size : i.i_size); Lf->sz_def = 1; } - } + } else if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; break; #if solaris >= 110000 @@ -3144,7 +3153,8 @@ void process_node(struct lsof_context *ctx, /* context */ if (type == VREG || type == VDIR) { Lf->sz = (SZOFFTYPE)sdva.va_size; Lf->sz_def = 1; - } + } else if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; } break; #endif /* solaris>=110000 */ @@ -3154,6 +3164,7 @@ void process_node(struct lsof_context *ctx, /* context */ case N_SHARED: break; /* No more sharedfs information is available. */ case N_STREAM: + Lf->off_def = 1; break; case N_TMP: Lf->sz = (SZOFFTYPE)t.tn_attr.va_size; @@ -3165,7 +3176,8 @@ void process_node(struct lsof_context *ctx, /* context */ if (type == VREG || type == VDIR) { Lf->sz = (SZOFFTYPE)vx.sz; Lf->sz_def = vx.sz_def; - } + } else if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; break; #endif /* defined(HASVXFS) */ @@ -3175,7 +3187,8 @@ void process_node(struct lsof_context *ctx, /* context */ if (type == VREG || type == VDIR) { Lf->sz = (SZOFFTYPE)zn.z_size; Lf->sz_def = 1; - } + } else if ((type == VCHR || type == VBLK)) + Lf->off_def = 1; } break; #endif /* defined(HAS_ZFS) */ @@ -3403,7 +3416,7 @@ void process_node(struct lsof_context *ctx, /* context */ * If there's a namenode and its device and node number match this one, * use the nm_mountpt's address for name cache lookups. */ - if (nns && devs && (dev == nn.nm_vattr.va_fsid) && (Lf->inp_ty == 1) && + if (nns && devs && (dev == nn.nm_vattr.va_fsid) && Lf->inode_def && (Lf->inode == (INODETYPE)nn.nm_vattr.va_nodeid)) Lf->na = (KA_T)nn.nm_mountpt; # endif /* defined(HASNCACHE) */ @@ -3446,7 +3459,7 @@ void process_node(struct lsof_context *ctx, /* context */ switch (type) { case VNON: - ty = "VNON"; + Lf->type = LSOF_FILE_VNODE_VNON; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -3454,14 +3467,14 @@ void process_node(struct lsof_context *ctx, /* context */ break; case VREG: case VDIR: - ty = (type == VREG) ? "VREG" : "VDIR"; + Lf->type = (type == VREG) ? LSOF_FILE_VNODE_VREG : LSOF_FILE_VNODE_VDIR; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; case VBLK: - ty = "VBLK"; + Lf->type = LSOF_FILE_VNODE_VBLK; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -3469,15 +3482,15 @@ void process_node(struct lsof_context *ctx, /* context */ Ntype = N_BLK; break; case VCHR: + Lf->type = LSOF_FILE_VNODE_VCHR; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; if (unix_sock) { - ty = "unix"; + Lf->type = LSOF_FILE_UNIX; break; } - ty = "VCHR"; if (Lf->is_stream == 0 && Lf->is_com == 0) Ntype = N_CHR; break; @@ -3488,14 +3501,14 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; - ty = "DOOR"; + Lf->type = LSOF_FILE_DOOR; if (dns) (void)idoorkeep(ctx, &dn); break; #endif /* solaris>=20500 */ case VLNK: - ty = "VLNK"; + Lf->type = LSOF_FILE_VNODE_VLNK; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -3504,7 +3517,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if solaris >= 100000 case VPORT: - ty = "PORT"; + Lf->type = LSOF_FILE_PORT; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; @@ -3522,7 +3535,7 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; - ty = (char *)NULL; + Lf->type = LSOF_FILE_UNKNOWN; break; #endif /* solaris>=20600 */ @@ -3531,40 +3544,40 @@ void process_node(struct lsof_context *ctx, /* context */ # if solaris >= 20600 if (so.so_family == AF_UNIX) { - ty = "unix"; + Lf->type = LSOF_FILE_UNIX; if (Funix) Lf->sf |= SELUNX; } else { if (so.so_family == AF_INET) { # if defined(HASIPv6) - ty = "IPv4"; + Lf->type = LSOF_FILE_IPV4; # else /* !defined(HASIPv6) */ - ty = "inet"; + Lf->type = LSOF_FILE_INET; # endif /* defined(HASIPv6) */ (void)snpf(Namech, Namechl - 1, printsockty(so.so_type)); Namech[Namechl - 1] = '\0'; if (TcpStIn || UdpStIn || TcpStXn || UdpStXn) Lf->sf |= SELEXCLF; - else if (Fnet && (FnetTy != 6)) + else if (Fnet && (FnetTy != AF_INET6)) Lf->sf |= SELNET; } # if defined(HASIPv6) else if (so.so_family == AF_INET6) { - ty = "IPv6"; + Lf->type = LSOF_FILE_IPV6; (void)snpf(Namech, Namechl - 1, printsockty(so.so_type)); Namech[Namechl - 1] = '\0'; if (TcpStIn || UdpStIn || TcpStXn || UdpStXn) Lf->sf |= SELEXCLF; - else if (Fnet && (FnetTy != 4)) + else if (Fnet && (FnetTy != AF_INET)) Lf->sf |= SELNET; } # endif /* defined(HASIPv6) */ else { - ty = "sock"; + Lf->type = LSOF_FILE_SOCKET; (void)printunkaf(ctx, so.so_family, 0); ep = endnm(ctx, &sz); (void)snpf(ep, sz, ", %s", printsockty(so.so_type)); @@ -3580,14 +3593,14 @@ void process_node(struct lsof_context *ctx, /* context */ #endif /* defined(HAS_VSOCK) */ case VBAD: - ty = "VBAD"; + Lf->type = LSOF_FILE_VNODE_VBAD; Lf->dev = dev; Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; break; case VFIFO: - ty = "FIFO"; + Lf->type = LSOF_FILE_VNODE_VFIFO; if (!Lf->dev_ch || Lf->dev_ch[0] == '\0') { Lf->dev = dev; Lf->dev_def = devs; @@ -3600,17 +3613,14 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->dev_def = devs; Lf->rdev = rdev; Lf->rdev_def = rdevs; - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); - ty = (char *)NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = type; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); - Lf->ntype = Ntype; /* * If this a Solaris common vnode/snode void some information. */ if (Lf->is_com) - Lf->sz_def = Lf->inp_ty = 0; + Lf->sz_def = Lf->inode_def = 0; /* * If a file attach description remains, put it in the NAME column addition. */ @@ -3622,7 +3632,7 @@ void process_node(struct lsof_context *ctx, /* context */ * If this is a VBLK file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VBLK)) + if (!Lf->inode_def && (type == VBLK)) find_bl_ino(ctx); #endif /* defined(HASBLKDEV) */ @@ -3630,7 +3640,7 @@ void process_node(struct lsof_context *ctx, /* context */ * If this is a VCHR file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VCHR)) { + if (!Lf->inode_def && (type == VCHR)) { find_ch_ino(ctx); /* * If the VCHR inode number still isn't known and this is a COMMON @@ -3641,7 +3651,7 @@ void process_node(struct lsof_context *ctx, /* context */ * If it can, save the pseudo or clone device for temporary * use when searching for a match with a named file argument. */ - if ((Lf->inp_ty == 0) && (Lf->is_com || Lf->is_stream || pnl) && + if (!Lf->inode_def && (Lf->is_com || Lf->is_stream || pnl) && (Clone || Pseudo)) { if (!sdp) { if (rdevs || devs) { @@ -3687,7 +3697,7 @@ void process_node(struct lsof_context *ctx, /* context */ */ trdev = sdp->rdev; Lf->inode = sdp->inode; - Lf->inp_ty = trdevs = 1; + Lf->inode_def = trdevs = 1; if (!Namech[0] || Lf->is_com) { (void)snpf(Namech, Namechl - 1, "%s", sdp->name); Namech[Namechl - 1] = '\0'; @@ -3697,8 +3707,8 @@ void process_node(struct lsof_context *ctx, /* context */ if (!(Lf->nma = (char *)malloc(len))) { (void)fprintf( stderr, - "%s: no space for (COMMON): PID %d; FD %s\n", Pn, - Lp->pid, Lf->fd); + "%s: no space for (COMMON): PID %d; FD %d\n", Pn, + Lp->pid, Lf->fd_num); Error(ctx); } (void)snpf(Lf->nma, len, "(COMMON)"); @@ -3707,13 +3717,8 @@ void process_node(struct lsof_context *ctx, /* context */ } } /* - * Record stream status. + * Test for specified file. */ - if (Lf->inp_ty == 0 && Lf->is_stream && strcmp(Lf->iproto, "STR") == 0) - Lf->inp_ty = 2; - /* - * Test for specified file. - */ #if defined(HASPROCFS) if (Ntype == N_PROC) { @@ -3725,7 +3730,7 @@ void process_node(struct lsof_context *ctx, /* context */ if ((pfi->pid && pfi->pid == pids.pid_id) # if defined(HASPINODEN) - || (Lf->inp_ty == 1 && Lf->inode == pfi->inode) + || (Lf->inode_def && Lf->inode == pfi->inode) # endif /* defined(HASPINODEN) */ ) { @@ -3769,14 +3774,14 @@ void process_node(struct lsof_context *ctx, /* context */ * read_cni() - read common snode information */ -static int read_cni(struct lsof_context *ctx, /* context */ - struct snode *s, /* starting snode */ - struct vnode *rv, /* "real" vnode receiver */ - struct vnode *v, /* starting vnode */ - struct snode *rs, /* "real" snode receiver */ - struct dev_info *di, /* dev_info structure receiver */ - char *din, /* device info name receiver */ - int dinl) /* sizeof(*din) */ +static int read_cni(struct lsof_context *ctx, + struct snode *s, /* starting snode */ + struct vnode *rv, /* "real" vnode receiver */ + struct vnode *v, /* starting vnode */ + struct snode *rs, /* "real" snode receiver */ + struct dev_info *di, /* dev_info structure receiver */ + char *din, /* device info name receiver */ + int dinl) /* sizeof(*din) */ { char tbuf[32]; @@ -3806,9 +3811,9 @@ static int read_cni(struct lsof_context *ctx, /* context */ * readinode() - read inode */ -static int readinode(struct lsof_context *ctx, /* context */ - KA_T ia, /* inode kernel address */ - struct inode *i) /* inode buffer */ +static int readinode(struct lsof_context *ctx, + KA_T ia, /* inode kernel address */ + struct inode *i) /* inode buffer */ { if (kread(ctx, (KA_T)ia, (char *)i, sizeof(struct inode))) { (void)snpf(Namech, Namechl - 1, "can't read inode at %s", @@ -3825,10 +3830,10 @@ static int readinode(struct lsof_context *ctx, /* context */ * read_ndn() - read node's door node */ -static int read_ndn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing vnode's address */ - KA_T da, /* door node's address */ - struct door_node *dn) /* door node receiver */ +static int read_ndn(struct lsof_context *ctx, + KA_T na, /* containing vnode's address */ + KA_T da, /* door node's address */ + struct door_node *dn) /* door node receiver */ { char tbuf[32]; @@ -3848,7 +3853,7 @@ static int read_ndn(struct lsof_context *ctx, /* context */ * read_mi() - read stream's module information */ -static void read_mi(struct lsof_context *ctx, /* context */ +static void read_mi(struct lsof_context *ctx, KA_T s, /* kernel stream pointer address */ dev_t *rdev, /* raw device pointer */ caddr_t so, /* so_so return (Solaris) */ @@ -3898,7 +3903,7 @@ static void read_mi(struct lsof_context *ctx, /* context */ k = (int)strlen(Namech); *sdp = dp; } else - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "STR"); + Lf->iproto = LSOF_PROTOCOL_STR; nl = sizeof(mn) - 1; mn[nl] = '\0'; qp = (KA_T)sd.sd_wrq; @@ -3958,9 +3963,9 @@ static void read_mi(struct lsof_context *ctx, /* context */ * read_nan(na, ca, cn) - read node's autofs node */ -static int read_nan(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T aa, /* autofs node address */ +static int read_nan(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T aa, /* autofs node address */ # if solaris < 20600 struct autonode *rn) /* autofs node receiver */ @@ -4001,10 +4006,10 @@ static int read_nan(struct lsof_context *ctx, /* context */ * read_ncn(na, ca, cn) - read node's cache node */ -static int read_ncn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T ca, /* cache node address */ - struct cnode *cn) /* cache node receiver */ +static int read_ncn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T ca, /* cache node address */ + struct cnode *cn) /* cache node receiver */ { char tbuf[32]; @@ -4025,7 +4030,7 @@ static int read_ncn(struct lsof_context *ctx, /* context */ * read_nctfsn(ty, na, ca, cn) - read node's cache node */ -static int read_nctfsn(struct lsof_context *ctx, /* context */ +static int read_nctfsn(struct lsof_context *ctx, int ty, /* node type -- i.e., N_CTFS* */ KA_T na, /* containing node's address */ KA_T ca, /* cache node address */ @@ -4102,10 +4107,10 @@ static int read_nctfsn(struct lsof_context *ctx, /* context */ * read_nfn() - read node's fifonode */ -static int read_nfn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T fa, /* fifonode address */ - struct fifonode *f) /* fifonode receiver */ +static int read_nfn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T fa, /* fifonode address */ + struct fifonode *f) /* fifonode receiver */ { char tbuf[32]; @@ -4124,10 +4129,10 @@ static int read_nfn(struct lsof_context *ctx, /* context */ * read_nhn() - read node's High Sierra node */ -static int read_nhn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T ha, /* hsnode address */ - struct hsnode *h) /* hsnode receiver */ +static int read_nhn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T ha, /* hsnode address */ + struct hsnode *h) /* hsnode receiver */ { char tbuf[32]; @@ -4146,10 +4151,10 @@ static int read_nhn(struct lsof_context *ctx, /* context */ * read_nin() - read node's inode */ -static int read_nin(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T ia, /* kernel inode address */ - struct inode *i) /* inode receiver */ +static int read_nin(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T ia, /* kernel inode address */ + struct inode *i) /* inode receiver */ { char tbuf[32]; @@ -4168,10 +4173,10 @@ static int read_nin(struct lsof_context *ctx, /* context */ * read_nln(na, la, ln) - read node's loopback node */ -static int read_nln(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T la, /* loopback node address */ - struct lnode *ln) /* loopback node receiver */ +static int read_nln(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T la, /* loopback node address */ + struct lnode *ln) /* loopback node receiver */ { char tbuf[32]; @@ -4190,10 +4195,10 @@ static int read_nln(struct lsof_context *ctx, /* context */ * read_nnn() - read node's namenode */ -static int read_nnn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T nna, /* namenode address */ - struct namenode *nn) /* namenode receiver */ +static int read_nnn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T nna, /* namenode address */ + struct namenode *nn) /* namenode receiver */ { char tbuf[32]; @@ -4212,10 +4217,10 @@ static int read_nnn(struct lsof_context *ctx, /* context */ * read_nmn() - read node's mvfsnode */ -static int read_nmn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T ma, /* kernel mvfsnode address */ - struct mvfsnode *m) /* mvfsnode receiver */ +static int read_nmn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T ma, /* kernel mvfsnode address */ + struct mvfsnode *m) /* mvfsnode receiver */ { char tbuf[32]; @@ -4235,10 +4240,10 @@ static int read_nmn(struct lsof_context *ctx, /* context */ * read_npi() - read node's /proc file system information */ -static int read_npi(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - struct vnode *v, /* containing vnode */ - struct pid *pids) /* pid structure receiver */ +static int read_npi(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + struct vnode *v, /* containing vnode */ + struct pid *pids) /* pid structure receiver */ { struct as as; struct proc p; @@ -4252,7 +4257,6 @@ static int read_npi(struct lsof_context *ctx, /* context */ kthread_t thread; pid_t prpid; id_t prtid; - char *ty = (char *)NULL; # endif /* solaris>=20600 */ if (!v->v_data || kread(ctx, (KA_T)v->v_data, (char *)&pr, sizeof(pr))) { @@ -4278,12 +4282,12 @@ static int read_npi(struct lsof_context *ctx, /* context */ Namech[Namechl - 1] = '\0'; enter_nm(ctx, Namech); Lf->inode = (INODETYPE)PR_ROOTINO; - Lf->inp_ty = 1; + Lf->inode_def = 1; } else { (void)snpf(Namech, Namechl - 1, "/%s/", HASPROCFS); Namech[Namechl - 1] = '\0'; enter_nm(ctx, Namech); - Lf->inp_ty = 0; + Lf->inode_def = 0; } return (0); } @@ -4311,13 +4315,13 @@ static int read_npi(struct lsof_context *ctx, /* context */ (void)snpf(Namech, Namechl, "/%s/%d", HASPROCFS, (int)pids->pid_id); Namech[Namechl - 1] = '\0'; Lf->inode = (INODETYPE)ptoi(pids->pid_id); - Lf->inp_ty = 1; + Lf->inode_def = 1; # else /* solaris>=20600 */ /* * Enter the >= Solaris 2.6 inode number. */ Lf->inode = (INODETYPE)pr.pr_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; /* * Read the >= Solaris 2.6 prnode common structures. * @@ -4370,15 +4374,15 @@ static int read_npi(struct lsof_context *ctx, /* context */ switch (pr.pr_type) { case PR_PROCDIR: (void)snpf(Namech, Namechl - 1, "/%s", HASPROCFS); - ty = "PDIR"; + Lf->type = LSOF_FILE_PROC_DIR; break; case PR_PIDDIR: (void)snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); - ty = "PDIR"; + Lf->type = LSOF_FILE_PROC_PID; break; case PR_AS: (void)snpf(Namech, Namechl - 1, "/%s/%d/as", HASPROCFS, (int)prpid); - ty = "PAS"; + Lf->type = LSOF_FILE_PROC_AS; if (prpcs && kread(ctx, (KA_T)pc.prc_proc, (char *)&p, sizeof(p)) == 0 && p.p_as && kread(ctx, (KA_T)p.p_as, (char *)&as, sizeof(as)) == 0) { @@ -4388,174 +4392,171 @@ static int read_npi(struct lsof_context *ctx, /* context */ break; case PR_CTL: (void)snpf(Namech, Namechl - 1, "/%s/%d/ctl", HASPROCFS, (int)prpid); - ty = "PCTL"; + Lf->type = LSOF_FILE_PROC_CTRL; break; case PR_STATUS: (void)snpf(Namech, Namechl - 1, "/%s/%d/status", HASPROCFS, (int)prpid); - ty = "PSTA"; + Lf->type = LSOF_FILE_PROC_STATUS; break; case PR_LSTATUS: (void)snpf(Namech, Namechl - 1, "/%s/%d/lstatus", HASPROCFS, (int)prpid); - ty = "PLST"; + Lf->type = LSOF_FILE_PROC_LSTATUS; break; case PR_PSINFO: (void)snpf(Namech, Namechl - 1, "/%s/%d/psinfo", HASPROCFS, (int)prpid); - ty = "PSIN"; + Lf->type = LSOF_FILE_PROC_PSINFO; break; case PR_LPSINFO: (void)snpf(Namech, Namechl - 1, "/%s/%d/lpsinfo", HASPROCFS, (int)prpid); - ty = "PLPI"; + Lf->type = LSOF_FILE_PROC_LPS_INFO; break; case PR_MAP: (void)snpf(Namech, Namechl - 1, "/%s/%d/map", HASPROCFS, (int)prpid); - ty = "PMAP"; + Lf->type = LSOF_FILE_PROC_MAP; break; case PR_RMAP: (void)snpf(Namech, Namechl - 1, "/%s/%d/rmap", HASPROCFS, (int)prpid); - ty = "PRMP"; + Lf->type = LSOF_FILE_PROC_RMAP; break; case PR_XMAP: (void)snpf(Namech, Namechl - 1, "/%s/%d/xmap", HASPROCFS, (int)prpid); - ty = "PXMP"; + Lf->type = LSOF_FILE_PROC_XMAP; break; case PR_CRED: (void)snpf(Namech, Namechl - 1, "/%s/%d/cred", HASPROCFS, (int)prpid); - ty = "PCRE"; + Lf->type = LSOF_FILE_PROC_CRED; break; case PR_SIGACT: (void)snpf(Namech, Namechl - 1, "/%s/%d/sigact", HASPROCFS, (int)prpid); - ty = "PSGA"; + Lf->type = LSOF_FILE_PROC_SIGACT; break; case PR_AUXV: (void)snpf(Namech, Namechl - 1, "/%s/%d/auxv", HASPROCFS, (int)prpid); - ty = "PAXV"; + Lf->type = LSOF_FILE_PROC_AUXV; break; # if defined(HASPR_LDT) case PR_LDT: (void)snpf(Namech, Namechl - 1, "/%s/%d/ldt", HASPROCFS, (int)prpid); - ty = "PLDT"; + Lf->type = LSOF_FILE_PROC_LDT; break; # endif /* defined(HASPR_LDT) */ case PR_USAGE: (void)snpf(Namech, Namechl - 1, "/%s/%d/usage", HASPROCFS, (int)prpid); - ty = "PUSG"; + Lf->type = LSOF_FILE_PROC_USAGE; break; case PR_LUSAGE: (void)snpf(Namech, Namechl - 1, "/%s/%d/lusage", HASPROCFS, (int)prpid); - ty = "PLU"; + Lf->type = LSOF_FILE_PROC_LUSAGE; break; case PR_PAGEDATA: (void)snpf(Namech, Namechl - 1, "/%s/%d/pagedata", HASPROCFS, (int)prpid); - ty = "PGD"; + Lf->type = LSOF_FILE_PROC_PAGE_DATA; break; case PR_WATCH: (void)snpf(Namech, Namechl - 1, "/%s/%d/watch", HASPROCFS, (int)prpid); - ty = "PW"; + Lf->type = LSOF_FILE_PROC_WATCH; break; case PR_CURDIR: (void)snpf(Namech, Namechl - 1, "/%s/%d/cwd", HASPROCFS, (int)prpid); - ty = "PCWD"; + Lf->type = LSOF_FILE_PROC_CWD; break; case PR_ROOTDIR: (void)snpf(Namech, Namechl - 1, "/%s/%d/root", HASPROCFS, (int)prpid); - ty = "PRTD"; + Lf->type = LSOF_FILE_PROC_ROOT; break; case PR_FDDIR: (void)snpf(Namech, Namechl - 1, "/%s/%d/fd", HASPROCFS, (int)prpid); - ty = "PFDR"; + Lf->type = LSOF_FILE_PROC_FD_DIR; break; case PR_FD: (void)snpf(Namech, Namechl - 1, "/%s/%d/fd/%d", HASPROCFS, (int)prpid, pr.pr_index); - ty = "PFD"; + Lf->type = LSOF_FILE_PROC_FD; break; case PR_OBJECTDIR: (void)snpf(Namech, Namechl - 1, "/%s/%d/object", HASPROCFS, (int)prpid); - ty = "PODR"; + Lf->type = LSOF_FILE_PROC_OBJ_DIR; break; case PR_OBJECT: - (void)snpf(Namech, Namechl - 1, "/%s/%d/object/", HASPROCFS, - (int)prpid); - ty = "POBJ"; + (void)snpf(Namech, Namechl - 1, "/%s/%d/object", HASPROCFS, (int)prpid); + Lf->type = LSOF_FILE_PROC_OBJ; break; case PR_LWPDIR: - (void)snpf(Namech, Namechl - 1, "/%s/%d/lpw", HASPROCFS, (int)prpid); - ty = "PLDR"; + (void)snpf(Namech, Namechl - 1, "/%s/%d/lwp", HASPROCFS, (int)prpid); + Lf->type = LSOF_FILE_PROC_LWP_DIR; break; case PR_LWPIDDIR: (void)snpf(Namech, Namechl, "/%s/%d/lwp/%d", HASPROCFS, (int)prpid, (int)prtid); - ty = "PLDR"; + Lf->type = LSOF_FILE_PROC_LWP_DIR; break; case PR_LWPCTL: (void)snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpctl", HASPROCFS, (int)prpid, (int)prtid); - ty = "PLC"; + Lf->type = LSOF_FILE_PROC_LWP_CTL; break; case PR_LWPSTATUS: (void)snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpstatus", HASPROCFS, (int)prpid, (int)prtid); - ty = "PLWS"; + Lf->type = LSOF_FILE_PROC_LWP_STATUS; break; case PR_LWPSINFO: (void)snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpsinfo", HASPROCFS, (int)prpid, (int)prtid); - ty = "PLWI"; + Lf->type = LSOF_FILE_PROC_LWP_SINFO; break; case PR_LWPUSAGE: (void)snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/lwpusage", HASPROCFS, (int)prpid, (int)prtid); - ty = "PLWU"; + Lf->type = LSOF_FILE_PROC_LWP_USAGE; break; case PR_XREGS: (void)snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/xregs", HASPROCFS, (int)prpid, (int)prtid); - ty = "PLWX"; + Lf->type = LSOF_FILE_PROC_LWP_XREGS; break; # if defined(HASPR_GWINDOWS) case PR_GWINDOWS: (void)snpf(Namech, Namechl - 1, "/%s/%d/lwp/%d/gwindows", HASPROCFS, (int)prpid, (int)prtid); - ty = "PLWG"; + Lf->type = LSOF_FILE_PROC_LWP_GWINDOWS; break; # endif /* defined(HASPR_GWINDOWS) */ # if defined(PR_PIDFILE) case PR_PIDFILE: (void)snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); - ty = "POPF"; + Lf->type = LSOF_FILE_PROC_OLD_PID; break; # endif /* defined(PR_PIDFILE) */ # if defined(PR_LWPIDFILE) case PR_LWPIDFILE: (void)snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); - ty = "POLP"; + Lf->type = LSOF_FILE_PROC_OLD_LWP; break; # endif /* defined(PR_LWPIDFILE) */ case PR_OPAGEDATA: (void)snpf(Namech, Namechl - 1, "/%s/%d", HASPROCFS, (int)prpid); - ty = "POPG"; + Lf->type = LSOF_FILE_PROC_OLD_PAGE; break; default: - ty = (char *)NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = pr.pr_type; + break; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); - else - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", (pr.pr_type & 0xfff)); /* * Record the Solaris 2.6 /proc file system inode number. */ Lf->inode = (INODETYPE)pr.pr_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; # endif /* solaris<20600 */ Namech[Namechl - 1] = '\0'; @@ -4568,10 +4569,10 @@ static int read_npi(struct lsof_context *ctx, /* context */ * read_npn() - read node's pcnode */ -static int read_npn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T pa, /* pcnode address */ - struct pcnode *p) /* pcnode receiver */ +static int read_npn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T pa, /* pcnode address */ + struct pcnode *p) /* pcnode receiver */ { char tbuf[32]; @@ -4591,10 +4592,10 @@ static int read_npn(struct lsof_context *ctx, /* context */ * read_nprtn() - read node's port node */ -static int read_nprtn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T pa, /* port node address */ - port_t *p) /* port node receiver */ +static int read_nprtn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T pa, /* port node address */ + port_t *p) /* port node receiver */ { char tbuf[32]; @@ -4614,10 +4615,10 @@ static int read_nprtn(struct lsof_context *ctx, /* context */ * read_nrn() - read node's rnode */ -static int read_nrn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T ra, /* rnode address */ - struct rnode *r) /* rnode receiver */ +static int read_nrn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T ra, /* rnode address */ + struct rnode *r) /* rnode receiver */ { char tbuf[32]; @@ -4637,10 +4638,10 @@ static int read_nrn(struct lsof_context *ctx, /* context */ * read_nrn4() - read node's rnode4 */ -static int read_nrn4(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T ra, /* rnode address */ - struct rnode4 *r) /* rnode receiver */ +static int read_nrn4(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T ra, /* rnode address */ + struct rnode4 *r) /* rnode receiver */ { char tbuf[32]; @@ -4661,11 +4662,11 @@ static int read_nrn4(struct lsof_context *ctx, /* context */ * read_nsdn() - read node's sdev_node */ -static int read_nsdn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's adress */ - KA_T sa, /* sdev_node address */ - struct sdev_node *sdn, /* sdev_node receiver */ - struct vattr *sdva) /* sdev_node's vattr receiver */ +static int read_nsdn(struct lsof_context *ctx, + KA_T na, /* containing node's adress */ + KA_T sa, /* sdev_node address */ + struct sdev_node *sdn, /* sdev_node receiver */ + struct vattr *sdva) /* sdev_node's vattr receiver */ { KA_T va; char tbuf[32], tbuf1[32]; @@ -4698,11 +4699,10 @@ static int read_nsdn(struct lsof_context *ctx, /* context */ * read_nson() - read node's sonode */ -static int read_nson(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T sa, /* sonode address */ - struct sonode *sn) /* sonode receiver */ - +static int read_nson(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T sa, /* sonode address */ + struct sonode *sn) /* sonode receiver */ { char tbuf[32]; @@ -4722,10 +4722,10 @@ static int read_nson(struct lsof_context *ctx, /* context */ * read_nsn() - read node's snode */ -static int read_nsn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T sa, /* snode address */ - struct snode *s) /* snode receiver */ +static int read_nsn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T sa, /* snode address */ + struct snode *s) /* snode receiver */ { char tbuf[32]; @@ -4745,9 +4745,9 @@ static int read_nsn(struct lsof_context *ctx, /* context */ * read_nsti() - read socket node's info */ -static int read_nsti(struct lsof_context *ctx, /* context */ - struct sonode *so, /* socket's sonode */ - sotpi_info_t *stpi) /* local socket info receiver */ +static int read_nsti(struct lsof_context *ctx, + struct sonode *so, /* socket's sonode */ + sotpi_info_t *stpi) /* local socket info receiver */ { char tbuf[32]; @@ -4774,10 +4774,10 @@ static int read_nsti(struct lsof_context *ctx, /* context */ * read_ntn() - read node's tmpnode */ -static int read_ntn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T ta, /* tmpnode address */ - struct tmpnode *t) /* tmpnode receiver */ +static int read_ntn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T ta, /* tmpnode address */ + struct tmpnode *t) /* tmpnode receiver */ { char tbuf[32]; @@ -4797,7 +4797,7 @@ static int read_ntn(struct lsof_context *ctx, /* context */ * read_nusa() - read sondode's UNIX socket address */ -static int read_nusa(struct lsof_context *ctx, /* context */ +static int read_nusa(struct lsof_context *ctx, struct soaddr *so, /* kernel socket info structure */ struct sockaddr_un *ua) /* local sockaddr_un address */ { @@ -4823,10 +4823,9 @@ static int read_nusa(struct lsof_context *ctx, /* context */ * read_nvn() - read node's vnode */ -static int read_nvn(struct lsof_context *ctx, /* context */ - KA_T na, /* node's address */ - KA_T va, /* vnode address */ - struct vnode *v) /* vnode receiver */ +static int read_nvn(struct lsof_context *ctx, KA_T na, /* node's address */ + KA_T va, /* vnode address */ + struct vnode *v) /* vnode receiver */ { char tbuf[32]; @@ -4846,10 +4845,10 @@ static int read_nvn(struct lsof_context *ctx, /* context */ * read_nzn() - read node's ZFS node */ -static int read_nzn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing node's address */ - KA_T nza, /* znode address */ - znode_t *zn) /* znode receiver */ +static int read_nzn(struct lsof_context *ctx, + KA_T na, /* containing node's address */ + KA_T nza, /* znode address */ + znode_t *zn) /* znode receiver */ { int err = 0; /* error flag */ CTF_member_t *mp; /* member pointer */ @@ -4910,10 +4909,10 @@ static int read_nzn(struct lsof_context *ctx, /* context */ * read_nznp() - read znode's persistent znode */ -static int read_nznp(struct lsof_context *ctx, /* context */ - KA_T nza, /* containing znode's address */ - KA_T nzpa, /* persistent znode address */ - znode_phys_t *zp) /* persistent znode receiver */ +static int read_nznp(struct lsof_context *ctx, + KA_T nza, /* containing znode's address */ + KA_T nzpa, /* persistent znode address */ + znode_phys_t *zp) /* persistent znode receiver */ { char tbuf[32]; @@ -4936,10 +4935,10 @@ static int read_nznp(struct lsof_context *ctx, /* context */ * read_nzvfs() - read znode's associated vfs */ -static int read_nzvfs(struct lsof_context *ctx, /* context */ - KA_T nza, /* containing znode's address */ - KA_T nzva, /* associated vfs address */ - zfsvfs_t *zv) /* associated vfs receiver */ +static int read_nzvfs(struct lsof_context *ctx, + KA_T nza, /* containing znode's address */ + KA_T nzva, /* associated vfs address */ + zfsvfs_t *zv) /* associated vfs receiver */ { char tbuf[32]; @@ -4962,9 +4961,10 @@ static int read_nzvfs(struct lsof_context *ctx, /* context */ */ static void -savesockmod(struct so_so *so, /* new so_so structure pointer */ - struct so_so *sop, /* previous so_so structure pointer */ - int *so_st) /* status of *sop (0 if not loaded) */ + savesockmod(so, sop, + so_st) struct so_so *so; /* new so_so structure pointer */ +struct so_so *sop; /* previous so_so structure pointer */ +int *so_st; /* status of *sop (0 if not loaded) */ { # if solaris < 20500 @@ -5121,9 +5121,8 @@ savesockmod(struct so_so *so, /* new so_so structure pointer */ * vop2ty() - convert vnode operation switch address to internal type */ -int vop2ty(struct lsof_context *ctx, /* context */ - struct vnode *vp, /* local vnode pointer */ - int fx) /* file system index (-1 if none) */ +int vop2ty(struct lsof_context *ctx, struct vnode *vp, /* local vnode pointer */ + int fx) /* file system index (-1 if none) */ { int h; register int i; @@ -5208,13 +5207,13 @@ int vop2ty(struct lsof_context *ctx, /* context */ * read_ndvn() -- read node's dv_node */ -static int read_ndvn(struct lsof_context *ctx, /* context */ - KA_T na, /* containing vnode's address */ - KA_T da, /* containing vnode's v_data */ - struct dv_node *dv, /* dv_node receiver */ - dev_t *dev, /* underlying file system device - * number receptor */ - unsigned char *devs) /* status of *dev */ +static int read_ndvn(struct lsof_context *ctx, + KA_T na, /* containing vnode's address */ + KA_T da, /* containing vnode's v_data */ + struct dv_node *dv, /* dv_node receiver */ + dev_t *dev, /* underlying file system device + * number receptor */ + unsigned char *devs) /* status of *dev */ { struct vnode rv; struct snode s; diff --git a/lib/dialects/sun/dnode1.c b/lib/dialects/sun/dnode1.c index 58785dc3..489524c3 100644 --- a/lib/dialects/sun/dnode1.c +++ b/lib/dialects/sun/dnode1.c @@ -34,7 +34,7 @@ static char copyright[] = #endif #if defined(HAS_AFS) -# include "lsof.h" +# include "common.h" # include # define __XDR_INCLUDE__ @@ -112,8 +112,8 @@ typedef struct afs_bozoLock afs_bozoLock_t; * Local function prototypes */ -static struct volume *getvolume(struct VenusFid *f, int *vols); -static int is_rootFid(struct vcache *vc, int *rfid); +static struct volume *getvolume, (struct VenusFid * f int *vols); +static int is_rootFid, (struct vcache * vc int *rfid); /* * alloc_vcache() - allocate space for vcache structure @@ -127,7 +127,7 @@ struct vnode *alloc_vcache() { * ckAFSsym() - check for missing X_AFS_* symbols in AFS name list file */ -void ckAFSsym(struct nlist *nl) /* copy of Nl[] when empty */ +void ckAFSsym(nl) struct nlist *nl; /* copy of Nl[] when empty */ { char *path = AFSAPATHDEF; int i; @@ -141,7 +141,7 @@ void ckAFSsym(struct nlist *nl) /* copy of Nl[] when empty */ /* * If an alternate AFS name list file was specified, see if it can be read. */ - if (!is_readable(path, 0)) { + if (!is_readable(ctx, path, 0)) { if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: can't access AFS name list file: %s\n", @@ -179,8 +179,9 @@ void ckAFSsym(struct nlist *nl) /* copy of Nl[] when empty */ * getvolume() - get volume structure */ -static struct volume *getvolume(struct VenusFid *f, /* file ID pointer */ - int *vols) /* afs_volumes status return */ +static struct volume *getvolume(f, vols) +struct VenusFid *f; /* file ID pointer */ +int *vols; /* afs_volumes status return */ { int i; static KA_T ka = 0; @@ -223,7 +224,8 @@ static struct volume *getvolume(struct VenusFid *f, /* file ID pointer */ * hasAFS() - test for AFS presence via vfs structure */ -int hasAFS(struct vnode *vp) /* vnode pointer */ +int hasAFS(vp) +struct vnode *vp; /* vnode pointer */ { struct mounts *mp; int n; @@ -282,8 +284,9 @@ int hasAFS(struct vnode *vp) /* vnode pointer */ * 1 if root file ID structure address available */ -static int is_rootFid(struct vcache *vc, /* vcache structure */ - int *rfid) /* root file ID pointer status return */ +static int is_rootFid(vc, rfid) +struct vcache *vc; /* vcache structure */ +int *rfid; /* root file ID pointer status return */ { KA_T arFid; char *err; @@ -345,9 +348,10 @@ static int is_rootFid(struct vcache *vc, /* vcache structure */ * readafsnode() - read AFS node */ -int readafsnode(KA_T va, /* kernel vnode address */ - struct vnode *v, /* vnode buffer pointer */ - struct afsnode *an) /* afsnode recipient */ +int readafsnode(va, v, an) +KA_T va; /* kernel vnode address */ +struct vnode *v; /* vnode buffer pointer */ +struct afsnode *an; /* afsnode recipient */ { char *cp, tbuf[32]; KA_T ka; diff --git a/lib/dialects/sun/dnode2.c b/lib/dialects/sun/dnode2.c index 8ecbde2d..4311767a 100644 --- a/lib/dialects/sun/dnode2.c +++ b/lib/dialects/sun/dnode2.c @@ -44,7 +44,7 @@ static char copyright[] = # include # define EMSGPFX "vx_inode: " -static char *add2em(char *em, char *fmt, char *arg); +static char *add2em, (char *em, char *fmt char *arg); static char *ckptr(char *em, char *ptr, int len, int slen, char *nm); static char *getioffs(char **vx, int *vxl, char **dev, int *devl, char **ino, int *inol, char **nl, int *nll, char **sz, int *szl); @@ -117,9 +117,10 @@ extern int access_vxfs_ioffsets() { * add2em() - add to error message */ -static char *add2em(char *em, /* current error message */ - char *fmt, /* message format */ - char *arg) /* format's single string argument */ +static char *add2em(em, fmt, arg) +char *em; /* current error message */ +char *fmt; /* message format */ +char *arg; /* format's single string argument */ { MALLOC_S al, eml, nl; char msg[1024]; @@ -153,11 +154,12 @@ static char *add2em(char *em, /* current error message */ * ckptr() - check pointer and length */ -static char *ckptr(char *em, /* pointer to previous error message */ - char *ptr, /* pointer to check */ - int len, /* pointer's value length */ - int slen, /* value's storage length */ - char *nm) /* element name */ +static char *ckptr(em, ptr, len, slen, nm) +char *em; /* pointer to previous error message */ +char *ptr; /* pointer to check */ +int len; /* pointer's value length */ +int slen; /* value's storage length */ +char *nm; /* element name */ { # if defined(_LP64) @@ -188,16 +190,17 @@ static char *ckptr(char *em, /* pointer to previous error message */ * getioffs() - get the vx_inode offsets */ -static char *getioffs(char **vx, /* pointer to allocated vx_inode space */ - int *vxl, /* sizeof(*vx) */ - char **dev, /* pointer to device number element of *vx */ - int *devl, /* sizeof(*dev) */ - char **ino, /* pointer to node number element of *vx */ - int *inol, /* sizeof(*ino) */ - char **nl, /* pointer to nlink element of *vx */ - int *nll, /* sizeof(*nl) */ - char **sz, /* pointer to size element of *vx */ - int *szl) /* sizeof(*sz) */ +static char *getioffs(vx, vxl, dev, devl, ino, inol, nl, nll, sz, szl) +char **vx; /* pointer to allocated vx_inode space */ +int *vxl; /* sizeof(*vx) */ +char **dev; /* pointer to device number element of *vx */ +int *devl; /* sizeof(*dev) */ +char **ino; /* pointer to node number element of *vx */ +int *inol; /* sizeof(*ino) */ +char **nl; /* pointer to nlink element of *vx */ +int *nll; /* sizeof(*nl) */ +char **sz; /* pointer to size element of *vx */ +int *szl; /* sizeof(*sz) */ { char *tv; int tvl; @@ -239,7 +242,8 @@ static char *getioffs(char **vx, /* pointer to allocated vx_inode space */ * print_vxfs_rnl_path() -- print VxFS RNL path */ -int print_vxfs_rnl_path(struct lfile *lf) /* file whose name is to be printed */ +int print_vxfs_rnl_path(lf) +struct lfile *lf; /* file whose name is to be printed */ { char **bp = (char **)NULL; int i, j, n, p; @@ -257,7 +261,7 @@ int print_vxfs_rnl_path(struct lfile *lf) /* file whose name is to be printed */ * This must be a VxFS file, it must have an inode and its mount point must * be known. */ - if (!lf->is_vxfs || (lf->inp_ty != 1) || !lf->fsdir) + if (!lf->is_vxfs || !lf->inode_def || !lf->fsdir) return (0); /* * Locate or create an RNL mount point cache entry. @@ -329,12 +333,13 @@ int print_vxfs_rnl_path(struct lfile *lf) /* file whose name is to be printed */ * read_vxnode() - read Veritas file system inode information */ -int read_vxnode(KA_T va, /* containing vnode's address */ - struct vnode *v, /* containing vnode */ - struct l_vfs *vfs, /* local vfs structure */ - int fx, /* file system index (-1 if none) */ - struct l_ino *li, /* local inode value receiver */ - KA_T *vnops) /* table of VxFS v_op values */ +int read_vxnode(va, v, vfs, fx, li, vnops) +KA_T va; /* containing vnode's address */ +struct vnode *v; /* containing vnode */ +struct l_vfs *vfs; /* local vfs structure */ +int fx; /* file system index (-1 if none) */ +struct l_ino *li; /* local inode value receiver */ +KA_T *vnops; /* table of VxFS v_op values */ { struct vnode cv; char tbuf[32]; diff --git a/lib/dialects/sun/dproc.c b/lib/dialects/sun/dproc.c index bbaeda3d..c5b893f5 100644 --- a/lib/dialects/sun/dproc.c +++ b/lib/dialects/sun/dproc.c @@ -151,11 +151,11 @@ static void readkam(struct lsof_context *ctx, KA_T addr); #endif /* solaris>=20501 */ #if solaris >= 20501 && solaris < 70000 -extern u_longlong_t kvm_physaddr(kvm_t *, struct as *, u_int); +extern u_longlong_t kvm_physaddr(kvm_t *, struct as *u_int); #endif /* solaris>=20501 && solaris<70000 */ #if defined(HASZONES) -static int hash_zn(char *zn); +extern int hash_zn(char *zn); #endif /* defined(HASZONES) */ /* @@ -237,7 +237,7 @@ void gather_proc_info(struct lsof_context *ctx) { /* * Get the segment vnodeops address. */ - if (get_Nl_value("sgvops", Drive_Nl, &Sgvops) < 0) + if (get_Nl_value(ctx, "sgvops", Drive_Nl, &Sgvops) < 0) Sgvops = (KA_T)NULL; ft = 0; } else if (!HasALLKMEM) { @@ -321,10 +321,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Get the process ID. */ - if (Fpgid) - pgid = Pgid[px]; - else - pgid = 0; + pgid = Pgid[px]; pid = Pid[px]; #if solaris < 20500 @@ -348,14 +345,11 @@ void gather_proc_info(struct lsof_context *ctx) { /* * If the -z (zone) option was specified, get the zone name. */ - if (Fzone) { - zn[0] = zn[sizeof(zn) - 1] = '\0'; - if (p->p_zone && - !kread(ctx, (KA_T)p->p_zone, (char *)&z, sizeof(z))) { - if (!z.zone_name || - kread(ctx, (KA_T)z.zone_name, (char *)&zn, sizeof(zn) - 1)) - zn[0] = '\0'; - } + zn[0] = zn[sizeof(zn) - 1] = '\0'; + if (p->p_zone && !kread(ctx, (KA_T)p->p_zone, (char *)&z, sizeof(z))) { + if (!z.zone_name || + kread(ctx, (KA_T)z.zone_name, (char *)&zn, sizeof(zn) - 1)) + zn[0] = '\0'; } #endif /* defined(HASZONES) */ @@ -389,7 +383,7 @@ void gather_proc_info(struct lsof_context *ctx) { * o Skip processes excluded by zone name. * o Save zone name. */ - if (Fzone && zn[0]) { + if (zn[0]) { zh = hash_zn(zn); if (ZoneArg) { @@ -453,7 +447,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Save current working directory information. */ if (!ckscko && u->u_cdir) { - alloc_lfile(ctx, CWD, -1); + alloc_lfile(ctx, LSOF_FD_CWD, -1); #if defined(FILEPTR) FILEPTR = (struct file *)NULL; @@ -467,7 +461,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Save root directory information. */ if (!ckscko && u->u_rdir) { - alloc_lfile(ctx, RTD, -1); + alloc_lfile(ctx, LSOF_FD_ROOT_DIR, -1); #if defined(FILEPTR) FILEPTR = (struct file *)NULL; @@ -528,11 +522,11 @@ void gather_proc_info(struct lsof_context *ctx) { #endif /* solaris<20400 */ continue; - alloc_lfile(ctx, (char *)NULL, i); + alloc_lfile(ctx, LSOF_FD_NUMERIC, i); #if solaris < 20400 pofv = (long)u->u_flist.uf_pofile[j - 1]; - process_file(ctx, (KA_T)u->u_flist.uf_ofile[j - 1]); + process_file((KA_T)u->u_flist.uf_ofile[j - 1]); #else /* solaris>=20400 */ pofv = uf[j - 1].uf_pofile; process_file(ctx, (KA_T)uf[j - 1].uf_ofile); @@ -619,7 +613,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * Get kernel symbols. */ - if (Nmlst && !is_readable(Nmlst, 1)) + if (Nmlst && !is_readable(ctx, Nmlst, 1)) Error(ctx); (void)build_Nl(ctx, Drive_Nl); @@ -654,9 +648,9 @@ static void get_kernel_access(struct lsof_context *ctx) { * the AFS modload file. Make sure that other symbols that appear in * both name list files have the same values. */ - if ((get_Nl_value("arFID", Drive_Nl, &v) >= 0 && !v) || - (get_Nl_value("avops", Drive_Nl, &v) >= 0 && !v) || - (get_Nl_value("avol", Drive_Nl, &v) >= 0 && !v)) + if ((get_Nl_value(ctx, "arFID", Drive_Nl, &v) >= 0 && !v) || + (get_Nl_value(ctx, "avops", Drive_Nl, &v) >= 0 && !v) || + (get_Nl_value(ctx, "avol", Drive_Nl, &v) >= 0 && !v)) (void)ckAFSsym(nl); (void)free((MALLOC_P *)nl); } @@ -716,7 +710,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * See if the non-KMEM memory file is readable. */ - if (Memory && !is_readable(Memory, 1)) + if (Memory && !is_readable(ctx, Memory, 1)) Error(ctx); #endif /* defined(WILLDROPGID) */ @@ -730,7 +724,7 @@ static void get_kernel_access(struct lsof_context *ctx) { * Get the kernel's KERNELBASE value for Solaris 2.5 and above. */ v = (KA_T)0; - if (get_Nl_value("kbase", Drive_Nl, &v) < 0 || !v || + if (get_Nl_value(ctx, "kbase", Drive_Nl, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&Kb, sizeof(Kb))) { (void)fprintf(stderr, "%s: can't read kernel base address from %s\n", Pn, print_kptr(v, (char *)NULL, 0)); @@ -742,8 +736,8 @@ static void get_kernel_access(struct lsof_context *ctx) { * Get the Solaris clone major device number, if possible. */ v = (KA_T)0; - if ((get_Nl_value("clmaj", Drive_Nl, &v) < 0) || !v) { - if (get_Nl_value("clmaj_alt", Drive_Nl, &v) < 0) + if ((get_Nl_value(ctx, "clmaj", Drive_Nl, &v) < 0) || !v) { + if (get_Nl_value(ctx, "clmaj_alt", Drive_Nl, &v) < 0) v = (KA_T)0; } if (v && kread(ctx, (KA_T)v, (char *)&CloneMaj, sizeof(CloneMaj)) == 0) @@ -753,7 +747,7 @@ static void get_kernel_access(struct lsof_context *ctx) { * active process chain. If it's not available, clear the ALLKMEM status. */ if (HasALLKMEM) { - if ((get_Nl_value("pract", Drive_Nl, &PrAct) < 0) || !PrAct) + if ((get_Nl_value(ctx, "pract", Drive_Nl, &PrAct) < 0) || !PrAct) HasALLKMEM = 0; } @@ -763,7 +757,7 @@ static void get_kernel_access(struct lsof_context *ctx) { * physical map structure for Solaris 2.5.1 and above. */ if (!HasALLKMEM) { - if (get_Nl_value("kasp", Drive_Nl, &v) >= 0 && v) { + if (get_Nl_value(ctx, "kasp", Drive_Nl, &v) >= 0 && v) { PageSz = getpagesize(); PSMask = PageSz - 1; for (i = 1, PSShft = 0; i < PageSz; i <<= 1, PSShft++) @@ -784,80 +778,9 @@ static void get_kernel_access(struct lsof_context *ctx) { #endif /* defined(WILLDROPGID) */ } -#if defined(HASZONES) -/* - * enter_zone_arg() - enter zone name argument - */ - -int enter_zone_arg(struct lsof_context *ctx, /* context */ - char *zn) /* zone name */ -{ - int zh; - znhash_t *zp, *zpn; - /* - * Allocate zone argument hash space, as required. - */ - if (!ZoneArg) { - if (!(ZoneArg = (znhash_t **)calloc(HASHZONE, sizeof(znhash_t *)))) { - (void)fprintf(stderr, "%s: no space for zone arg hash\n", Pn); - Error(ctx); - } - } - /* - * Hash the zone name and search the argument hash. - */ - zh = hash_zn(zn); - for (zp = ZoneArg[zh]; zp; zp = zp->next) { - if (!strcmp(zp->zn, zn)) - break; - } - if (zp) { - - /* - * Process a duplicate. - */ - if (!Fwarn) - (void)fprintf(stderr, "%s: duplicate zone name: %s\n", Pn, zn); - return (1); - } - /* - * Create a new hash entry and link it to its bucket. - */ - if (!(zpn = (znhash_t *)malloc((MALLOC_S)sizeof(znhash_t)))) { - (void)fprintf(stderr, "%s no hash space for zone: %s\n", Pn, zn); - Error(ctx); - } - zpn->f = 0; - zpn->zn = zn; - zpn->next = ZoneArg[zh]; - ZoneArg[zh] = zpn; - return (0); -} - -/* - * hash_zn() - hash zone name - */ - -static int hash_zn(char *zn) /* zone name */ -{ - register int i, h; - size_t l; - - if (!(l = strlen(zn))) - return (0); - if (l == 1) - return ((int)*zn & (HASHZONE - 1)); - for (i = h = 0; i < (int)(l - 1); i++) { - h ^= ((int)zn[i] * (int)zn[i + 1]) << ((i * 3) % 13); - } - return (h & (HASHZONE - 1)); -} -#endif /* defined(HASZONES) */ - /* * initialize() - perform all initialization */ - void initialize(struct lsof_context *ctx) { get_kernel_access(ctx); /* @@ -874,14 +797,18 @@ void initialize(struct lsof_context *ctx) { #endif /*defined(HASDCACHE) */ } +/* + * deinitialize() - perform all cleanup + */ +void deinitialize(struct lsof_context *ctx) {} + /* * kread() - read from kernel memory */ -int kread(struct lsof_context *ctx, /* context */ - KA_T addr, /* kernel memory address */ - char *buf, /* buffer to receive data */ - READLEN_T len) /* length to read */ +int kread(struct lsof_context *ctx, KA_T addr, /* kernel memory address */ + char *buf, /* buffer to receive data */ + READLEN_T len) /* length to read */ { register int br; /* @@ -986,7 +913,7 @@ int kread(struct lsof_context *ctx, /* context */ #endif /* solaris>=20501 */ /* - * Use kvm_read for Solaris < 2.5; use kvm_kread() Solaris >= 2.5. + * Use kvm_read for Solaris < 2.5; use kvm_kread(ctx, ) Solaris >= 2.5. */ br = KVMREAD(Kd, (u_long)addr, buf, len); return (((READLEN_T)br == len) ? 0 : 1); @@ -1111,7 +1038,7 @@ static int get_next_seg(struct lsof_context *ctx, avl_tree_t *av, return -1; } -static void process_text(struct lsof_context *ctx, /* context */ +static void process_text(struct lsof_context *ctx, KA_T pa) /* address space description pointer */ { struct as as; @@ -1124,7 +1051,7 @@ static void process_text(struct lsof_context *ctx, /* context */ * Get address space description. */ if (kread(ctx, (KA_T)pa, (char *)&as, sizeof(as))) { - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); (void)snpf(Namech, Namechl, "can't read text segment list (%s)", print_kptr(pa, (char *)NULL, 0)); enter_nm(ctx, Namech); @@ -1159,7 +1086,7 @@ static void process_text(struct lsof_context *ctx, /* context */ } if (k >= i) { v[i++] = (KA_T)vn.vp; - alloc_lfile(ctx, " txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); # if defined(FILEPTR) FILEPTR = (struct file *)NULL; @@ -1182,8 +1109,7 @@ static void process_text(struct lsof_context *ctx, /* context */ # define S_NEXT s_next # endif /* solaris>=20400 */ -static void process_text(struct lsof_context *ctx, /* context */ - KA_T pa) /* address space description pointer */ +static void process_text(pa) KA_T pa; /* address space description pointer */ { struct as as; int i, j, k; @@ -1194,12 +1120,12 @@ static void process_text(struct lsof_context *ctx, /* context */ * Get address space description. */ if (kread(ctx, (KA_T)pa, (char *)&as, sizeof(as))) { - alloc_lfile(" txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); (void)snpf(Namech, Namechl, "can't read text segment list (%s)", print_kptr(pa, (char *)NULL, 0)); enter_nm(ctx, Namech); if (Lf->sf) - link_lfile(); + link_lfile(ctx); return; } /* @@ -1228,7 +1154,7 @@ static void process_text(struct lsof_context *ctx, /* context */ } if (k >= i) { v[i++] = (KA_T)vn.vp; - alloc_lfile(" txt", -1); + alloc_lfile(ctx, LSOF_FD_PROGRAM_TEXT, -1); # if defined(FILEPTR) FILEPTR = (struct file *)NULL; @@ -1236,7 +1162,7 @@ static void process_text(struct lsof_context *ctx, /* context */ process_node(ctx, (KA_T)vn.vp); if (Lf->sf) - link_lfile(); + link_lfile(ctx); } } } @@ -1307,8 +1233,8 @@ static void readfsinfo(struct lsof_context *ctx) { * readkam() - read kernel's address map structure */ -static void readkam(struct lsof_context *ctx, /* context */ - KA_T addr) /* kernel virtual address */ +static void readkam(struct lsof_context *ctx, + KA_T addr) /* kernel virtual address */ { register int i; register kvmhash_t *kp, *kpp; @@ -1370,7 +1296,7 @@ static void read_proc(struct lsof_context *ctx) { /* * Get a proc structure count estimate. */ - if (get_Nl_value("nproc", Drive_Nl, &pa) < 0 || !pa || + if (get_Nl_value(ctx, "nproc", Drive_Nl, &pa) < 0 || !pa || kread(ctx, pa, (char *)&knp, sizeof(knp)) || knp < 1) knp = PROCDFLT; /* @@ -1395,15 +1321,13 @@ static void read_proc(struct lsof_context *ctx) { * Pre-allocate PGID and PID number space. */ len = (MALLOC_S)(n * sizeof(int)); - if (Fpgid) { - if (Pgid) - Pgid = (int *)realloc((MALLOC_P *)Pgid, len); - else - Pgid = (int *)malloc(len); - if (!Pgid) { - (void)fprintf(stderr, "%s: no PGID table space\n", Pn); - Error(ctx); - } + if (Pgid) + Pgid = (int *)realloc((MALLOC_P *)Pgid, len); + else + Pgid = (int *)malloc(len); + if (!Pgid) { + (void)fprintf(stderr, "%s: no PGID table space\n", Pn); + Error(ctx); } if (Pid) Pid = (int *)realloc((MALLOC_P *)Pid, len); @@ -1462,12 +1386,10 @@ static void read_proc(struct lsof_context *ctx) { * Expand the PGID and PID tables. */ len = (MALLOC_S)(Npa * sizeof(int)); - if (Fpgid) { - if (!(Pgid = (int *)realloc((MALLOC_P *)Pgid, len))) { - (void)fprintf(stderr, "%s: no more (%d) PGID space\n", - Pn, Npa); - Error(ctx); - } + if (!(Pgid = (int *)realloc((MALLOC_P *)Pgid, len))) { + (void)fprintf(stderr, "%s: no more (%d) PGID space\n", Pn, + Npa); + Error(ctx); } if (!(Pid = (int *)realloc((MALLOC_P *)Pid, len))) { (void)fprintf(stderr, "%s: no more (%d) PID space\n", Pn, @@ -1523,19 +1445,16 @@ static void read_proc(struct lsof_context *ctx) { /* * Read Solaris PGID and PID numbers. */ - if (Fpgid) { - if (!p->p_pgidp || - kread(ctx, (KA_T)p->p_pgidp, (char *)&pg, sizeof(pg))) - continue; - } + if (!p->p_pgidp || + kread(ctx, (KA_T)p->p_pgidp, (char *)&pg, sizeof(pg))) + continue; if (!p->p_pidp || kread(ctx, (KA_T)p->p_pidp, (char *)&pids, sizeof(pids))) continue; /* * Save the PGID and PID numbers in local tables. */ - if (Fpgid) - Pgid[Np] = (int)pg.pid_id; + Pgid[Np] = (int)pg.pid_id; Pid[Np] = (int)pids.pid_id; /* * If the proc structure came from kvm_getproc(), save it in the @@ -1566,7 +1485,7 @@ static void read_proc(struct lsof_context *ctx) { (void)fprintf(stderr, "%s: can't read proc table\n", Pn); Error(ctx); } - if (Np < Npa && !RptTm) { + if (Np < Npa) { /* * Reduce the local proc structure table size to its minimum if @@ -1583,12 +1502,10 @@ static void read_proc(struct lsof_context *ctx) { * not in repeat mode. */ len = (MALLOC_S)(Np * sizeof(int)); - if (Fpgid) { - if (!(Pgid = (int *)realloc((MALLOC_P *)Pgid, len))) { - (void)fprintf(stderr, "%s: can't reduce PGID table to %d\n", Pn, - Np); - Error(ctx); - } + if (!(Pgid = (int *)realloc((MALLOC_P *)Pgid, len))) { + (void)fprintf(stderr, "%s: can't reduce PGID table to %d\n", Pn, + Np); + Error(ctx); } if (!(Pid = (int *)realloc((MALLOC_P *)Pid, len))) { (void)fprintf(stderr, "%s: can't reduce PID table to %d\n", Pn, Np); @@ -1645,7 +1562,7 @@ static struct l_nch *ncache_addr(KA_T v); # define ncachehash(v) Nchash + ((((int)(v) >> 2) * 31415) & Mhl) -static int ncache_isroot(KA_T va, char *cp); +static int ncache_isroot(struct lsof_context *ctx, KA_T va, char *cp); # define LNCHINCRSZ 64 /* local size increment */ # define XNC \ @@ -1660,7 +1577,8 @@ static int ncache_isroot(KA_T va, char *cp); static struct l_nch * -ncache_addr(KA_T v) /* vnode's address */ +ncache_addr(v) +KA_T v; /* vnode's address */ { struct l_nch **hp; @@ -1675,7 +1593,8 @@ ncache_addr(KA_T v) /* vnode's address */ * ncache_isroot() - is head of name cache path a file system root? */ -static int ncache_isroot(KA_T va, /* kernel vnode address */ +static int ncache_isroot(struct lsof_context *ctx, + KA_T va, /* kernel vnode address */ char *cp) /* partial path */ { char buf[MAXPATHLEN]; @@ -1713,12 +1632,12 @@ static int ncache_isroot(KA_T va, /* kernel vnode address */ /* * The vnode tests failed. Try the inode tests. */ - if (Lf->inp_ty != 1 || !Lf->inode || !Lf->fsdir || + if (!Lf->inode_def || !Lf->inode || !Lf->fsdir || (len = strlen(Lf->fsdir)) < 1) return (0); if ((len + 1 + strlen(cp) + 1) > sizeof(buf)) return (0); - for (mtp = readmnt(); mtp; mtp = mtp->next) { + for (mtp = readmnt(ctx); mtp; mtp = mtp->next) { if (!mtp->dir || !mtp->inode) continue; if (strcmp(Lf->fsdir, mtp->dir) == 0) @@ -1730,7 +1649,7 @@ static int ncache_isroot(KA_T va, /* kernel vnode address */ if (buf[len - 1] != '/') buf[len++] = '/'; (void)strcpy(&buf[len], cp); - if (statsafely(buf, &sb) != 0 || (INODETYPE)sb.st_ino != Lf->inode) + if (statsafely(ctx, buf, &sb) != 0 || (INODETYPE)sb.st_ino != Lf->inode) return (0); } /* @@ -1756,7 +1675,7 @@ static int ncache_isroot(KA_T va, /* kernel vnode address */ * ncache_load() - load the kernel's name cache */ -void ncache_load() { +void ncache_load(struct lsof_context *ctx) { char *cp; struct l_nch **hp, *lc; int h, i, len, n, xl; @@ -1783,8 +1702,8 @@ void ncache_load() { * Establish DNLC hash size. */ v = (KA_T)0; - if (get_Nl_value(X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&Nch, sizeof(Nch))) { + if (get_Nl_value(ctx, X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || + !v || kread(ctx, (KA_T)v, (char *)&Nch, sizeof(Nch))) { if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: can't read DNLC hash size: %s\n", @@ -1802,13 +1721,15 @@ void ncache_load() { /* * Get negative vnode address. */ - if (get_Nl_value(NCACHE_NEGVN, (struct drive_Nl *)NULL, &NegVN) < 0) + if (get_Nl_value(ctx, NCACHE_NEGVN, (struct drive_Nl *)NULL, &NegVN) < + 0) NegVN = (KA_T)NULL; /* * Establish DNLC hash address. */ v = (KA_T)0; - if (get_Nl_value(X_NCACHE, (struct drive_Nl *)NULL, (KA_T *)&v) < 0 || + if (get_Nl_value(ctx, X_NCACHE, (struct drive_Nl *)NULL, (KA_T *)&v) < + 0 || !v || kread(ctx, v, (char *)&kha, sizeof(kha)) || !kha) { if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: no DNLC hash address\n", @@ -1841,7 +1762,8 @@ void ncache_load() { * hash table count and the current average hash length. */ v = (KA_T)0; - if ((get_Nl_value("hshav", (struct drive_Nl *)NULL, (KA_T *)&v) < 0) || + if ((get_Nl_value(ctx, "hshav", (struct drive_Nl *)NULL, (KA_T *)&v) < + 0) || !v || kread(ctx, v, (char *)&i, sizeof(i)) || (i < 1)) { i = 16; if (!Fwarn) { @@ -1991,7 +1913,7 @@ void ncache_load() { /* * No DNLC entries were located, an unexpected result. */ - if (!RptTm && Ncache) { + if (Ncache) { /* * If not in repeat mode, free the space that has been malloc'd @@ -2011,7 +1933,7 @@ void ncache_load() { iNch = Nch = 0; return; } - if ((Nlu < Nla) && !RptTm) { + if (Nlu < Nla) { len = Nlu * sizeof(struct l_nch); if (!(Ncache = (struct l_nch *)realloc(Ncache, len))) goto no_local_space; @@ -2060,7 +1982,8 @@ void ncache_load() { * ncache_lookup() - look up a node's name in the kernel's name cache */ -char *ncache_lookup(char *buf, /* receiving name buffer */ +char *ncache_lookup(struct lsof_context *ctx, + char *buf, /* receiving name buffer */ int blen, /* receiving buffer length */ int *fp) /* full path reply */ { @@ -2078,7 +2001,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * file system mount point, return an empty path reply. That tells the * caller to print the file system mount point name only. */ - if (Lf->inp_ty == 1 && Lf->fs_ino && Lf->inode == Lf->fs_ino) + if (Lf->inode_def && Lf->fs_ino && Lf->inode == Lf->fs_ino) return (cp); # endif /* defined(HASFSINO) */ @@ -2091,9 +2014,9 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * If the node has no cache entry, see if it's the mount * point of a known file system. */ - if (!Lf->fsdir || !Lf->dev_def || Lf->inp_ty != 1) + if (!Lf->fsdir || !Lf->dev_def || !Lf->inode_def) return ((char *)NULL); - for (mtp = readmnt(); mtp; mtp = mtp->next) { + for (mtp = readmnt(ctx); mtp; mtp = mtp->next) { if (!mtp->dir || !mtp->inode) continue; if (Lf->dev == mtp->dev && mtp->inode == Lf->inode && @@ -2119,7 +2042,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ */ for (;;) { if (!lc->pa) { - if (ncache_isroot(lc->dp, cp)) + if (ncache_isroot(ctx, lc->dp, cp)) *fp = 1; break; } diff --git a/lib/dialects/sun/dproto.h b/lib/dialects/sun/dproto.h index 014c28f2..4330fe7e 100644 --- a/lib/dialects/sun/dproto.h +++ b/lib/dialects/sun/dproto.h @@ -51,8 +51,8 @@ extern int CTF_memCB(const char *name, ctf_id_t id, ulong_t offset, void *arg); extern int is_file_named(struct lsof_context *ctx, char *p, int nt, enum vtype vt, int ps); -extern struct l_vfs *readvfs(struct lsof_context *ctx, KA_T ka, struct vfs *la, - struct vnode *lv); +extern struct l_vfs *readvfs, + (struct lsof_context * ctx, KA_T ka struct vfs *la, struct vnode *lv); extern int vop2ty(struct lsof_context *ctx, struct vnode *vp, int fx); #if defined(HAS_AFS) @@ -64,12 +64,12 @@ extern int readafsnode(KA_T va, struct vnode *v, struct afsnode *an); #if defined(HASDCACHE) extern int rw_clone_sect(struct lsof_context *ctx, int m); -extern void clr_sect(struct lsof_context *ctx); +extern void clr_sect(void); extern int rw_pseudo_sect(struct lsof_context *ctx, int m); #endif /* defined(HASDCACHE) */ #if defined(HASIPv6) -extern struct hostent *gethostbyname2(const char *nm, int proto); +extern struct hostent *gethostbyname2, (const char *nm int proto); #endif /* defined(HASIPv6) */ #if defined(HAS_V_PATH) @@ -79,25 +79,20 @@ extern void read_v_path(struct lsof_context *ctx, KA_T ka, char *rb, #endif /* defined(HAS_V_PATH) */ #if defined(HASVXFS) -extern int read_vxnode(struct lsof_context *ctx, KA_T va, struct vnode *v, - struct l_vfs *vfs, int fx, struct l_ino *li, - KA_T *vnops); +extern int read_vxnode(KA_T va, struct vnode *v, struct l_vfs *vfs, int fx, + struct l_ino *li, KA_T *vnops); # if defined(HASVXFSRNL) extern int print_vxfs_rnl_path(struct lfile *lf); # endif /* defined(HASVXFSRNL) */ #endif /* defined(HASVXFS) */ -#if defined(HASZONES) -extern int enter_zone_arg(struct lsof_context *ctx, char *zn); -#endif /* defined(HASZONES) */ - extern void close_kvm(struct lsof_context *ctx); extern void open_kvm(struct lsof_context *ctx); extern void process_socket(struct lsof_context *ctx, KA_T sa, char *ty); #if solaris >= 110000 -extern int process_VSOCK(struct lsof_context *ctx, KA_T va, struct vnode *v, - struct sonode *so); +extern int process_VSOCK, + (struct lsof_context * ctx, KA_T va struct vnode *v, struct sonode *so); #endif /* solaris>=11000 */ extern void read_clone(struct lsof_context *ctx); diff --git a/lib/dialects/sun/dsock.c b/lib/dialects/sun/dsock.c index 7463b90b..0139bbee 100644 --- a/lib/dialects/sun/dsock.c +++ b/lib/dialects/sun/dsock.c @@ -301,8 +301,9 @@ typedef struct tcpb { * Local function prototypes */ -static void save_TCP_size(tcp_t *tc); -static void save_TCP_states(tcp_t *tc, caddr_t *fa, tcpb_t *tb, caddr_t *xp); +static void save_TCP_size, (struct lsof_context * ctx tcp_t * tc); +static void save_TCP_states, + (struct lsof_context * ctx, tcp_t *tc caddr_t *fa, tcpb_t *tb, caddr_t *xp); /* * build_IPstates() -- build the TCP and UDP state tables @@ -347,322 +348,6 @@ void build_IPstates(struct lsof_context *ctx) { } } -/* - * print_tcptpi() - print TCP/TPI info - */ - -void print_tcptpi(struct lsof_context *ctx, /* context */ - int nl) /* 1 == '\n' required */ -{ - char *cp = (char *)NULL; - char sbuf[128]; - int i; - int ps = 0; - unsigned int u; - - if (Ftcptpi & TCPTPI_STATE) { - switch (Lf->lts.type) { - case 0: /* TCP */ - if (!TcpSt) - (void)build_IPstates(ctx); - if ((i = Lf->lts.state.i + TcpStOff) < 0 || i >= TcpNstates) { - (void)snpf(sbuf, sizeof(sbuf), "UNKNOWN_TCP_STATE_%d", - Lf->lts.state.i); - cp = sbuf; - } else - cp = TcpSt[i]; - break; - case 1: /* TPI */ - if (!UdpSt) - (void)build_IPstates(ctx); - if ((u = Lf->lts.state.ui + UdpStOff) < 0 || u >= UdpNstates) { - (void)snpf(sbuf, sizeof(sbuf), "UNKNOWN_UDP_STATE_%u", - Lf->lts.state.ui); - cp = sbuf; - } else - cp = UdpSt[u]; - } - if (cp) { - if (Ffield) - (void)printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator); - else { - putchar('('); - (void)fputs(cp, stdout); - } - ps++; - } - } - -#if defined(HASTCPTPIQ) - if (Ftcptpi & TCPTPI_QUEUES) { - if (Lf->lts.rqs) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("QR=%lu", Lf->lts.rq); - if (Ffield) - putchar(Terminator); - ps++; - } - if (Lf->lts.sqs) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("QS=%lu", Lf->lts.sq); - if (Ffield) - putchar(Terminator); - ps++; - } - } -#endif /* defined(HASTCPTPIQ) */ - -#if defined(HASSOOPT) - if (Ftcptpi & TCPTPI_FLAGS) { - int opt; - - if ((opt = Lf->lts.opt) || Lf->lts.pqlens || Lf->lts.qlens || - Lf->lts.qlims || Lf->lts.rbszs || Lf->lts.sbsz) { - char sep = ' '; - - if (Ffield) - sep = LSOF_FID_TCPTPI; - else if (!ps) - sep = '('; - (void)printf("%cSO", sep); - ps++; - sep = '='; - -# if defined(SO_BROADCAST) - if (opt & SO_BROADCAST) { - (void)printf("%cBROADCAST", sep); - opt &= ~SO_BROADCAST; - sep = ','; - } -# endif /* defined(SO_BROADCAST) */ - -# if defined(SO_DEBUG) - if (opt & SO_DEBUG) { - (void)printf("%cDEBUG", sep); - opt &= ~SO_DEBUG; - sep = ','; - } -# endif /* defined(SO_DEBUG) */ - -# if defined(SO_DGRAM_ERRIND) - if (opt & SO_DGRAM_ERRIND) { - (void)printf("%cDGRAM_ERRIND", sep); - opt &= ~SO_DGRAM_ERRIND; - sep = ','; - } -# endif /* defined(SO_DGRAM_ERRIND) */ - -# if defined(SO_DONTROUTE) - if (opt & SO_DONTROUTE) { - (void)printf("%cDONTROUTE", sep); - opt &= ~SO_DONTROUTE; - sep = ','; - } -# endif /* defined(SO_DONTROUTE) */ - -# if defined(SO_KEEPALIVE) - if (opt & SO_KEEPALIVE) { - (void)printf("%cKEEPALIVE", sep); - if (Lf->lts.kai) - (void)printf("=%d", Lf->lts.kai); - opt &= ~SO_KEEPALIVE; - sep = ','; - } -# endif /* defined(SO_KEEPALIVE) */ - -# if defined(SO_LINGER) - if (opt & SO_LINGER) { - (void)printf("%cLINGER", sep); - if (Lf->lts.ltm) - (void)printf("=%d", Lf->lts.ltm); - opt &= ~SO_LINGER; - sep = ','; - } -# endif /* defined(SO_LINGER) */ - -# if defined(SO_OOBINLINE) - if (opt & SO_OOBINLINE) { - (void)printf("%cOOBINLINE", sep); - opt &= ~SO_OOBINLINE; - sep = ','; - } -# endif /* defined(SO_OOBINLINE) */ - - if (Lf->lts.pqlens) { - (void)printf("%cPQLEN=%u", sep, Lf->lts.pqlen); - sep = ','; - } - if (Lf->lts.qlens) { - (void)printf("%cQLEN=%u", sep, Lf->lts.qlen); - sep = ','; - } - if (Lf->lts.qlims) { - (void)printf("%cQLIM=%u", sep, Lf->lts.qlim); - sep = ','; - } - if (Lf->lts.rbszs) { - (void)printf("%cRCVBUF=%lu", sep, Lf->lts.rbsz); - sep = ','; - } - -# if defined(SO_REUSEADDR) - if (opt & SO_REUSEADDR) { - (void)printf("%cREUSEADDR", sep); - opt &= ~SO_REUSEADDR; - sep = ','; - } -# endif /* defined(SO_REUSEADDR) */ - - if (Lf->lts.sbszs) { - (void)printf("%cSNDBUF=%lu", sep, Lf->lts.sbsz); - sep = ','; - } - -# if defined(SO_TIMESTAMP) - if (opt & SO_TIMESTAMP) { - (void)printf("%cTIMESTAMP", sep); - opt &= ~SO_TIMESTAMP; - sep = ','; - } -# endif /* defined(SO_TIMESTAMP) */ - -# if defined(SO_USELOOPBACK) - if (opt & SO_USELOOPBACK) { - (void)printf("%cUSELOOPBACK", sep); - opt &= ~SO_USELOOPBACK; - sep = ','; - } -# endif /* defined(SO_USELOOPBACK) */ - - if (opt) - (void)printf("%cUNKNOWN=%#x", sep, opt); - if (Ffield) - putchar(Terminator); - } - } -#endif /* defined(HASSOOPT) */ - -#if defined(HASTCPOPT) - if (Ftcptpi & TCPTPI_FLAGS) { - int topt; - - if ((topt = Lf->lts.topt) || Lf->lts.msss) { - char sep = ' '; - - if (Ffield) - sep = LSOF_FID_TCPTPI; - else if (!ps) - sep = '('; - (void)printf("%cTF", sep); - ps++; - sep = '='; - -# if defined(TF_ACKNOW) - if (topt & TF_ACKNOW) { - (void)printf("%cACKNOW", sep); - topt &= ~TF_ACKNOW; - sep = ','; - } -# endif /* defined(TF_ACKNOW) */ - -# if defined(TF_DELACK) - if (topt & TF_DELACK) { - (void)printf("%cDELACK", sep); - topt &= ~TF_DELACK; - sep = ','; - } -# endif /* defined(TF_DELACK) */ - - if (Lf->lts.msss) { - (void)printf("%cMSS=%lu", sep, Lf->lts.mss); - sep = ','; - } - -# if defined(TF_NODELAY) - if (topt & TF_NODELAY) { - (void)printf("%cNODELAY", sep); - topt &= ~TF_NODELAY; - sep = ','; - } -# endif /* defined(TF_NODELAY) */ - -# if defined(TF_NOOPT) - if (topt & TF_NOOPT) { - (void)printf("%cNOOPT", sep); - topt &= ~TF_NOOPT; - sep = ','; - } -# endif /* defined(TF_NOOPT) */ - -# if defined(TF_SENTFIN) - if (topt & TF_SENTFIN) { - (void)printf("%cSENTFIN", sep); - topt &= ~TF_SENTFIN; - sep = ','; - } -# endif /* defined(TF_SENTFIN) */ - - if (topt) - (void)printf("%cUNKNOWN=%#x", sep, topt); - if (Ffield) - putchar(Terminator); - } - } -#endif /* defined(HASTCPOPT) */ - -#if defined(HASTCPTPIW) - if (Ftcptpi & TCPTPI_WINDOWS) { - if (Lf->lts.rws) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("WR=%lu", Lf->lts.rw); - if (Ffield) - putchar(Terminator); - ps++; - } - if (Lf->lts.wws) { - if (Ffield) - putchar(LSOF_FID_TCPTPI); - else { - if (ps) - putchar(' '); - else - putchar('('); - } - (void)printf("WW=%lu", Lf->lts.ww); - if (Ffield) - putchar(Terminator); - ps++; - } - } -#endif /* defined(HASTCPTPIW) */ - - if (Ftcptpi && !Ffield && ps) - putchar(')'); - if (nl) - putchar('\n'); -} - #if solaris >= 110000 /* * procss_VSOCK() -- process a VSOCK socket @@ -679,10 +364,10 @@ void print_tcptpi(struct lsof_context *ctx, /* context */ # define conn_src V4_PART_OF_V6(connua_v6addr.connua_laddr) # endif /* defined(HAS_CONN_NEW) */ -int process_VSOCK(struct lsof_context *ctx, /* context */ - KA_T va, /* containing vnode address */ - struct vnode *v, /* pointer to containing vnode */ - struct sonode *so) /* pointer to socket's sonode */ +int process_VSOCK(struct lsof_context *ctx, + KA_T va, /* containing vnode address */ + struct vnode *v, /* pointer to containing vnode */ + struct sonode *so) /* pointer to socket's sonode */ { int af; /* address family */ struct conn_s cs; /* connection info */ @@ -710,7 +395,6 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ tcph_t *tha = (tcph_t *)NULL; /* TCP header structure address */ # endif /* defined(HAS_CONN_NEW) */ - char *ty; /* TCP type */ udp_t uc; /* local UDP control structure */ /* * Read VSOCK's connection information. Enter its address as the protocol @@ -740,10 +424,9 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ * Set INET type -- IPv4 or IPv6. */ if (af == AF_INET) - ty = "IPv4"; + Lf->type = LSOF_FILE_IPV4; else - ty = "IPv6"; - (void)snpf(Lf->type, sizeof(Lf->type), ty); + Lf->type = LSOF_FILE_IPV6; switch (cs.conn_ulp) { case IPPROTO_TCP: @@ -763,9 +446,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ /* * Set TCP protcol name in Lf->iproto[]. */ - (void)snpf(Lf->iproto, IPROTOL - 1, "%s", "TCP"); - Lf->iproto[IPROTOL - 1] = '\0'; - Lf->inp_ty = 2; + Lf->iproto = LSOF_PROTOCOL_TCP; /* * Check for TCP state inclusion or exclusion. */ @@ -792,8 +473,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ * Set network file selection status. */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (af == AF_INET)) || - ((FnetTy == 6) && (af == AF_INET6))) { + if (FnetTy == AF_UNSPEC || FnetTy == af) { Lf->sf |= SELNET; } } @@ -836,7 +516,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ !kread(ctx, ka, (char *)&xa, sizeof(xa))) { xp = (caddr_t *)&xa; } - (void)save_TCP_states(&tc, (caddr_t *)&cs, (tcpb_t *)NULL, xp); + (void)save_TCP_states(ctx, &tc, (caddr_t *)&cs, (tcpb_t *)NULL, xp); # else /* !defined(HAS_CONN_NEW) */ if (tc.tcp_tcp_hdr_len && (ka = (KA_T)tc.tcp_tcph) && !kread(ctx, ka, (char *)&th, sizeof(th))) { @@ -851,7 +531,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ /* * Save TCP size information. */ - (void)save_TCP_size(&tc); + (void)save_TCP_size(ctx, &tc); break; case IPPROTO_UDP: @@ -870,9 +550,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ /* * Set UDP protcol name in Lf->iproto[]. */ - (void)snpf(Lf->iproto, IPROTOL - 1, "%s", "UDP"); - Lf->iproto[IPROTOL - 1] = '\0'; - Lf->inp_ty = 2; + Lf->iproto = LSOF_PROTOCOL_UDP; /* * Check for UDP state inclusion or exclusion. */ @@ -899,8 +577,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ * Set network file selection status. */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (af == AF_INET)) || - ((FnetTy == 6) && (af == AF_INET6))) { + if (FnetTy == AF_UNSPEC || FnetTy == af) { Lf->sf |= SELNET; } } @@ -923,6 +600,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ /* * Save UDP state and size information. */ + Lf->off_def = 1; Lf->lts.type = 1; Lf->lts.state.ui = (unsigned int)uc.udp_state; @@ -966,12 +644,9 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ * Set protocol name. */ if (cs.conn_ulp == IPPROTO_ICMP) - ty = "ICMP"; + Lf->iproto = LSOF_PROTOCOL_ICMP; else - ty = "ICMP6"; - (void)snpf(Lf->iproto, IPROTOL - 1, "%s", ty); - Lf->iproto[IPROTOL - 1] = '\0'; - Lf->inp_ty = 2; + Lf->iproto = LSOF_PROTOCOL_ICMPV6; /* * Read the ICMP control structure. */ @@ -981,14 +656,14 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ /* * Save ICMP size and state information. */ + Lf->off_def = 1; Lf->lts.type = 1; Lf->lts.state.ui = (unsigned int)ic.icmp_state; /* * Set network file selection status. */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (af == AF_INET)) || - ((FnetTy == 6) && (af == AF_INET6))) { + if (FnetTy == AF_UNSPEC || FnetTy == af) { Lf->sf |= SELNET; } } @@ -1042,16 +717,13 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ * Set INET type -- IPv4 or IPv6. */ if (af == AF_INET) - ty = "IPv4"; + Lf->type = LSOF_FILE_IPV4; else - ty = "IPv6"; - (void)snpf(Lf->type, sizeof(Lf->type), ty); + Lf->type = LSOF_FILE_IPV6; /* * Set protocol name. */ - (void)strncpy(Lf->iproto, "ROUTE", IPROTOL - 1); - Lf->iproto[IPROTOL - 1] = '\0'; - Lf->inp_ty = 2; + Lf->iproto = LSOF_PROTOCOL_ROUTING; /* * Read routing control structure. @@ -1062,14 +734,14 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ /* * Save AF_ROUTE size and state information. */ + Lf->off_def = 1; Lf->lts.type = 1; Lf->lts.state.i = (int)rt.rts_state; /* * Set network file selection status. */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (af == AF_INET)) || - ((FnetTy == 6) && (af == AF_INET6))) { + if (FnetTy == AF_UNSPEC || FnetTy == af) { Lf->sf |= SELNET; } } @@ -1092,12 +764,11 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ break; default: - (void)printiproto((int)cs.conn_ulp); + (void)enter_ip_proto(ctx, (int)cs.conn_ulp); (void)snpf(Namech, Namechl - 1, "unsupported socket family: %u", so->so_family); Namech[Namechl - 1] = '\0'; enter_nm(ctx, Namech); - Lf->inp_ty = 2; } return (1); } @@ -1107,7 +778,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ * process_socket() - process Solaris socket */ -void process_socket(struct lsof_context *ctx, /* context */ +void process_socket(struct lsof_context *ctx, KA_T sa, /* stream's data address in kernel */ char *ty) /* socket type name */ { @@ -1246,14 +917,14 @@ void process_socket(struct lsof_context *ctx, /* context */ #if defined(HASIPv6) if (strrchr(ty, '6')) { - (void)snpf(Lf->type, sizeof(Lf->type), "IPv6"); + Lf->type = LSOF_FILE_IPV6; af = AF_INET6; } else { - (void)snpf(Lf->type, sizeof(Lf->type), "IPv4"); + Lf->type = LSOF_FILE_IPV4; af = AF_INET; } #else /* !defined(HASIPv6) */ - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); + Lf->type = LSOF_FILE_INET; af = AF_INET; #endif /* defined(HASIPv6) */ @@ -1261,31 +932,21 @@ void process_socket(struct lsof_context *ctx, /* context */ * Set network file selection status. */ if (Fnet) { - if (!FnetTy || ((FnetTy == 4) && (af == AF_INET)) - -#if defined(HASIPv6) - || ((FnetTy == 6) && (af == AF_INET6)) -#endif /* defined(HASIPv6) */ - - ) { + if (FnetTy == AF_UNSPEC || FnetTy == af) { if (!TcpStIn && !UdpStIn) Lf->sf |= SELNET; } } - Lf->inp_ty = 2; /* * Convert type to upper case protocol name. */ - if (ty) { - for (i = 0; (ty[i] != '\0') && (i < IPROTOL) && (i < 3); i++) { - if (islower((unsigned char)ty[i])) - Lf->iproto[i] = toupper((unsigned char)ty[i]); - else - Lf->iproto[i] = ty[i]; - } - } else - i = 0; - Lf->iproto[i] = '\0'; + if (strcasecmp(ty, "TCP") == 0) { + Lf->iproto = LSOF_PROTOCOL_TCP; + } else if (strcasecmp(ty, "UDP") == 0) { + Lf->iproto = LSOF_PROTOCOL_UDP; + } else { + Lf->iproto = LSOF_PROTOCOL_UNKNOWN; + } /* * Read stream queue entries to obtain private IP, TCP, and UDP structures. */ @@ -1381,13 +1042,7 @@ void process_socket(struct lsof_context *ctx, /* context */ } if (!(Lf->sf & SELNET) && !TcpStIn && UdpStIn) { if (Fnet) { - if (!FnetTy || (FnetTy == 4) && (af == AF_INET) - -#if defined(HASIPv6) - || (FnetTy == 6) && (af == AF_INET6) -#endif /* defined(HASIPv6) */ - - ) { + if (FnetTy == AF_UNSPEC || FnetTy == af) { Lf->sf |= SELNET; } } @@ -1437,13 +1092,7 @@ void process_socket(struct lsof_context *ctx, /* context */ } if (!(Lf->sf & SELNET) && TcpStIn && !UdpStIn) { if (Fnet) { - if (!FnetTy || (FnetTy == 4) && (af == AF_INET) - -#if defined(HASIPv6) - || (FnetTy == 6) && (af == AF_INET6) -#endif /* defined(HASIPv6) */ - - ) { + if (FnetTy == AF_UNSPEC || FnetTy == af) { Lf->sf |= SELNET; } } @@ -1458,7 +1107,7 @@ void process_socket(struct lsof_context *ctx, /* context */ */ if (pcb) enter_dev_ch(ctx, print_kptr(pcb, (char *)NULL, 0)); - if (strncmp(Lf->iproto, "UDP", 3) == 0) { + if (Lf->iproto == LSOF_PROTOCOL_UDP) { /* * Save UDP address and TPI state. @@ -1515,11 +1164,12 @@ void process_socket(struct lsof_context *ctx, /* context */ (void)ent_inaddr(ctx, la, (int)ntohs(p), (unsigned char *)NULL, -1, af); + Lf->off_def = 1; if (ucs) { Lf->lts.type = 1; Lf->lts.state.ui = (unsigned int)uc.udp_state; } - } else if (strncmp(Lf->iproto, "TCP", 3) == 0) { + } else if (Lf->iproto == LSOF_PROTOCOL_TCP) { if (ics) { /* @@ -1661,7 +1311,7 @@ void process_socket(struct lsof_context *ctx, /* context */ * Save TCP state information. */ if (tcs) { - (void)save_TCP_states(&tc, (caddr_t *)tha, tcbp, + (void)save_TCP_states(ctx, &tc, (caddr_t *)tha, tcbp, (caddr_t *)NULL); Lf->lts.type = 0; Lf->lts.state.i = (int)tc.tcp_state; @@ -1671,7 +1321,7 @@ void process_socket(struct lsof_context *ctx, /* context */ */ if (tcs) - (void)save_TCP_size(&tc); + (void)save_TCP_size(ctx, &tc); } } else (void)strcat(Namech, "no TCP/UDP/IP information available"); @@ -1687,7 +1337,7 @@ void process_socket(struct lsof_context *ctx, /* context */ * read_icmp_t() - read connections icmp_t info */ -static int read_icmp_t(struct lsof_context *ctx, /* context */ +static int read_icmp_t(struct lsof_context *ctx, KA_T va, /* containing vnode kernel address */ KA_T ph, /* containing protocol handle kernel * address */ @@ -1755,7 +1405,7 @@ static int read_icmp_t(struct lsof_context *ctx, /* context */ * read_rts_t() - read connections rts_t info */ -static int read_rts_t(struct lsof_context *ctx, /* context */ +static int read_rts_t(struct lsof_context *ctx, KA_T va, /* containing vnode kernel address */ KA_T ph, /* containing protocol handle kernel * address */ @@ -1819,9 +1469,9 @@ static int read_rts_t(struct lsof_context *ctx, /* context */ * read_udp_t() - read UDP control structure */ -static int read_udp_t(struct lsof_context *ctx, /* context */ - KA_T ua, /* ucp_t kernel address */ - udp_t *uc) /* receiving udp_t structure */ +static int read_udp_t(struct lsof_context *ctx, + KA_T ua, /* ucp_t kernel address */ + udp_t *uc) /* receiving udp_t structure */ { (void)CTF_init(ctx, &IRU_ctfs, IRU_MOD_FORMAT, IRU_requests); if (!ua || CTF_MEMBER_READ(ua, uc, udp_t_members, udp_state) @@ -1852,7 +1502,8 @@ static int read_udp_t(struct lsof_context *ctx, /* context */ * save_TCP_size() -- save TCP size information */ -static void save_TCP_size(tcp_t *tc) /* pointer to TCP control structure */ +static void save_TCP_size(struct lsof_context *ctx, + tcp_t *tc) /* pointer to TCP control structure */ { int rq, sq; @@ -1881,6 +1532,9 @@ static void save_TCP_size(tcp_t *tc) /* pointer to TCP control structure */ else Lf->sz = (SZOFFTYPE)(rq + sq); Lf->sz_def = 1; + Lf->off_def = 1; +#else /* !defined(HASTCPTPIQ) && !defined(HASTCPTPIW) */ + Lf->off_def = 1; #endif /* defined(HASTCPTPIQ) || defined(HASTCPTPIW) */ } @@ -1888,7 +1542,8 @@ static void save_TCP_size(tcp_t *tc) /* pointer to TCP control structure */ * save_TCP_states() - save TCP states */ -static void save_TCP_states(tcp_t *tc, /* pointer to TCP control structure */ +static void save_TCP_states(struct lsof_context *ctx, + tcp_t *tc, /* pointer to TCP control structure */ caddr_t *fa, /* flags address (may be NULL): * if HAS_CONN_NEW: conn_s * * if !CONN_HAS_NEW: tcph_t * @@ -1933,7 +1588,7 @@ static void save_TCP_states(tcp_t *tc, /* pointer to TCP control structure */ if (cs->conn_useloopback) Lf->lts.opt |= SO_USELOOPBACK; # else /* !defined(HAS_CONN_NEW) */ - if (1) { + if (Ftcptpi & TCPTPI_FLAGS) { if (tc->tcp_broadcast) Lf->lts.opt |= SO_BROADCAST; if (tc->tcp_debug) diff --git a/lib/dialects/sun/dstore.c b/lib/dialects/sun/dstore.c index 9e600ca6..74ddff62 100644 --- a/lib/dialects/sun/dstore.c +++ b/lib/dialects/sun/dstore.c @@ -58,7 +58,7 @@ major_t CloneMaj; /* clone major device number */ /* * Drive_Nl -- table to drive the building of Nl[] via build_Nl() - * (See lsof.h and misc.c.) + * (See common.h and misc.c.) */ struct drive_Nl Drive_Nl[] = {{"afsops", "afs_ops"}, diff --git a/lib/dialects/sun/machine.h b/lib/dialects/sun/machine.h index b385241a..01fca3bd 100644 --- a/lib/dialects/sun/machine.h +++ b/lib/dialects/sun/machine.h @@ -78,7 +78,7 @@ typedef struct aio_req { /* * must be #include'd for Solaris >= 2.6 while _KMEMUSER is * defined. Since also #include's and - * is #include'd from lsof.h, we must perform some early #include magic + * is #include'd from common.h, we must perform some early #include magic * here to set things up properly. */ @@ -217,7 +217,7 @@ typedef struct pad_mutex { /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ # define HASFSINO 1 @@ -227,7 +227,7 @@ typedef struct pad_mutex { * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * If any file structure value is unavailable, its use may be suppressed * with any of the following definitions: @@ -348,7 +348,7 @@ typedef struct pad_mutex { # define HASNCACHE 1 # endif /* solaris>=10000 && defined(HAS_V_PATH) */ -# define NCACHELDPFX open_kvm(); /* do before calling ncache_load() */ +# define NCACHELDPFX open_kvm(ctx); /* do before calling ncache_load() */ /* #define NCACHELDSFX ??? */ @@ -435,14 +435,6 @@ typedef struct pad_mutex { # endif /* defined(HASVXFSRNL) */ # endif /* solaris>=10000 && defined(HAS_V_PATH) */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -614,7 +606,7 @@ typedef struct pad_mutex { /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -654,6 +646,7 @@ typedef struct pad_mutex { /* #define USE_LIB_PRINT_TCPTPI 1 ptti.c */ /* #define USE_LIB_READDEV 1 rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ # if solaris < 90000 @@ -661,7 +654,7 @@ typedef struct pad_mutex { # endif /* solaris<90000 */ /* #define USE_LIB_RNMH 1 rnmh.c */ -/* #define USE_LIB_SNPF 1 snpf.c */ + # define snpf snprintf /* use the system's snprintf() */ /* diff --git a/lib/dialects/sun/solaris_kaddr_filters b/lib/dialects/sun/solaris_kaddr_filters index 7fcd692d..7fa4582a 100644 --- a/lib/dialects/sun/solaris_kaddr_filters +++ b/lib/dialects/sun/solaris_kaddr_filters @@ -13,7 +13,7 @@ kernel, but not all bad addresses. For example, the virtual address 0x657a682e passes this test on a sun4u machine, but on at least one sun4u that virtual address translates to the physical address 0x1cf08c30000, which is the address of a register of a qfe interface -on the machine. There is some evidence that a kvm_kread() call for +on the machine. There is some evidence that a kvm_kread(ctx, ) call for the 0x657a682e address may crash that sun4u. Lsof 4.71 and above use no filter if they detect that /dev/allkmem @@ -122,7 +122,7 @@ Caching To recover the performance lost by kvm_physaddr() on Solaris 2.5.1, I added virtual-to-physical address caching to lsof's kernel read -function, kread(). This improves Solaris 2.6, 7, and 8 performance, +function, kread(ctx, ). This improves Solaris 2.6, 7, and 8 performance, too, but by a smaller amount. It turns out that a typical lsof run may require reading from 16,000 @@ -145,7 +145,7 @@ depend on the machine architecture type. Once lsof has kernel physical addresses, on Solaris 2.5.1 and 2.6 it seeks to those addresses with llseek() and reads from them via the /dev/mem device. This contrasts with lsof's pre-4.50 behavior -where it fed kernel virtual addresses to kvm_kread(), letting it +where it fed kernel virtual addresses to kvm_kread(ctx, ), letting it and the kernel do the virtual to physical translations -- and letting that combined process crash that one unlucky sun4u via its qfe interface. @@ -161,7 +161,7 @@ so it opens one of its own. On Solaris 2.6 for one test system, a 4 CPU E4000 sun4u, doing physical kernel address reads from /dev/mem turned out to be faster -than using kvm_kread(). It was marginally faster on a sun4d, and +than using kvm_kread(ctx, ). It was marginally faster on a sun4d, and marginally slower on two sun4m's. kvm_pread() @@ -179,11 +179,11 @@ it, and using read(2) to obtain physical address contents. The bonus of kvm_pread() is two-fold: 1) it does positioning as well as reading, so there's one less function call; and 2) its combined operation appears to be faster than llseek() plus read() -- or even -kvm_kread(). +kvm_kread(ctx, ). Combined with the virtual-to-physical address caching, the performance boost of kvm_pread() makes lsof faster on Solaris 7 and 8 than -previous revisions, using only kernelbase filtering and kvm_kread(). +previous revisions, using only kernelbase filtering and kvm_kread(ctx, ). Remaining Risks =============== @@ -203,7 +203,7 @@ possible failure scenarios: * Because lsof must read the kernel address map from kernel virtual memory to pass it to the Solaris 2.5.1 - and 2.6 kvm_physaddr() functions, lsof must use kvm_kread() + and 2.6 kvm_physaddr() functions, lsof must use kvm_kread(ctx, ) to read the map. There's also the chance that lsof could pass a stale diff --git a/lib/dialects/uw/Makefile b/lib/dialects/uw/Makefile index cf9f38e6..14fcb865 100644 --- a/lib/dialects/uw/Makefile +++ b/lib/dialects/uw/Makefile @@ -19,7 +19,7 @@ CDEFS= ${CDEF} ${CFGF} INCL= ${DINC} CFLAGS= ${CDEFS} ${INCL} ${DEBUG} -HDR= lsof.h lsof_fields.h dlsof.h machine.h proto.h dproto.h +HDR= common.h lsof_fields.h dlsof.h machine.h proto.h dproto.h SRC= dfile.c dmnt.c dnode.c dnode1.c dnode2.c dnode3.c dproc.c \ dsock.c dstore.c \ diff --git a/lib/dialects/uw/dfile.c b/lib/dialects/uw/dfile.c index f5a174e3..f009a829 100644 --- a/lib/dialects/uw/dfile.c +++ b/lib/dialects/uw/dfile.c @@ -51,8 +51,7 @@ int get_max_fd() { * process_file() - process file */ -void process_file(struct lsof_context *ctx, /* context */ - KA_T fp) /* kernel file structure address */ +void process_file(fp) KA_T fp; /* kernel file structure address */ { struct file f; int flag; @@ -61,7 +60,7 @@ void process_file(struct lsof_context *ctx, /* context */ FILEPTR = &f; #endif /* defined(FILEPTR) */ - if (kread(ctx, fp, (char *)&f, sizeof(f))) { + if (kread(fp, (char *)&f, sizeof(f))) { (void)snpf(Namech, Namechl, "can't read file struct from %s", print_kptr(fp, (char *)NULL, 0)); enter_nm(Namech); @@ -93,10 +92,13 @@ void process_file(struct lsof_context *ctx, /* context */ */ Lf->fct = (long)f.f_count; Lf->fsv |= FSV_CT; + Lf->fsa = fp; Lf->fsv |= FSV_FA; + Lf->ffg = (long)f.f_flag; Lf->fsv |= FSV_FG; + Lf->fna = (KA_T)f.f_vnode; Lf->fsv |= FSV_NI; #endif /* defined(HASFSTRUCT) */ @@ -150,7 +152,9 @@ static short CIMap[] = { * strcasecmp() - case insentitive character compare (from BSD) */ -int strcasecmp(char *s1, char *s2) { +int strcasecmp(s1, s2) +char *s1, *s2; +{ short *mp = CIMap; unsigned char *cp1 = (unsigned char *)s1; unsigned char *cp2 = (unsigned char *)s2; @@ -168,7 +172,10 @@ int strcasecmp(char *s1, char *s2) { * (from BSD) */ -int strncasecmp(char *s1, char *s2, int n) { +int strncasecmp(s1, s2, n) +char *s1, *s2; +int n; +{ short *mp = CIMap; unsigned char *cp1, *cp2; diff --git a/lib/dialects/uw/dlsof.h b/lib/dialects/uw/dlsof.h index 668bf2db..b005bfd1 100644 --- a/lib/dialects/uw/dlsof.h +++ b/lib/dialects/uw/dlsof.h @@ -126,10 +126,11 @@ # if defined(HASIPv6) # include # if !defined(IN6_ARE_ADDR_EQUAL) -# define IN6_ARE_ADDR_EQUAL IN6_ADDR_EQUAL /* required by RFC2292 \ - */ -# endif /* !defined(IN6_ARE_ADDR_EQUAL) */ -# endif /* defined(HASIPv6) */ +# define IN6_ARE_ADDR_EQUAL \ + IN6_ADDR_EQUAL /* required by RFC2292 \ + */ +# endif /* !defined(IN6_ARE_ADDR_EQUAL) */ +# endif /* defined(HASIPv6) */ # include # include diff --git a/lib/dialects/uw/dmnt.c b/lib/dialects/uw/dmnt.c index 3cea99fe..99bedac2 100644 --- a/lib/dialects/uw/dmnt.c +++ b/lib/dialects/uw/dmnt.c @@ -39,14 +39,11 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ -struct mounts *readmnt(struct lsof_context *ctx) { +struct mounts *readmnt() { char *dn = (char *)NULL; char *ln; struct mnttab me; diff --git a/lib/dialects/uw/dnode.c b/lib/dialects/uw/dnode.c index d923b595..a493b074 100644 --- a/lib/dialects/uw/dnode.c +++ b/lib/dialects/uw/dnode.c @@ -59,7 +59,7 @@ static int get_vty(struct vnode *v, KA_T va, struct vfs *kv, int *fx); static int examine_stream(KA_T vs, struct queue *q, char *mn, char *sn, KA_T *sqp); #else /* UNIXWAREV>=70103 */ -static int examine_stream(KA_T vs, struct queue *q, char **mch, char **mn, +static int examine_stream(KA_T vs, struct queue *q, char **mch char **mn, char *sn, KA_T *sqp); static struct l_dev *findspdev(dev_t *dev, dev_t *rdev); static void getspdev(void); @@ -77,14 +77,16 @@ static int readlino(int fx, struct vnode *v, struct l_ino *i); */ static struct protos { - char *module; /* stream module name */ - char *proto; /* TCP/IP protocol name */ + char *module; /* stream module name */ + enum lsof_protocol proto; /* TCP/IP protocol name */ } Protos[] = { - {"tcpu", "TCP"}, {"udpu", "UDP"}, {"tcpl", "TCP"}, {"tcp", "TCP"}, - {"udpl", "UDP"}, {"udp", "UDP"}, + {"tcpu", LSOF_PROTOCOL_TCP}, {"udpu", LSOF_PROTOCOL_UDP}, + {"tcpl", LSOF_PROTOCOL_TCP}, {"tcp", LSOF_PROTOCOL_TCP}, + {"udpl", LSOF_PROTOCOL_UDP}, {"udp", LSOF_PROTOCOL_UDP}, #if UNIXWAREV < 70103 - {"icmp", "ICMP"}, {"ipu", "IP"}, {"ipl", "IP"}, {"ip", "IP"}, + {"icmp", LSOF_PROTOCOL_ICMP}, {"ipu", LSOF_PROTOCOL_IP}, + {"ipl", LSOF_PROTOCOL_IP}, {"ip", LSOF_PROTOCOL_IP}, #endif /* UNIXWAREV<70103 */ }; @@ -137,21 +139,28 @@ char *d; /* direction ("->" or "<-") */ * examine_stream() - examine stream */ -static int examine_stream(struct lsof_context *ctx, /* context */ - KA_T vs, /* stream head's stdata kernel - * address */ - struct queue *q, /* queue structure buffer */ +static int + +#if UNIXWAREV < 70103 +examine_stream(vs, q, mn, sn, sqp) +#else /* UNIXWAREV>=70103 */ +examine_stream(vs, q, mch, mn, sn, sqp) +#endif /* UNIXWAREV<70103 */ + +KA_T vs; /* stream head's stdata kernel + * address */ +struct queue *q; /* queue structure buffer */ #if UNIXWAREV >= 70103 - char **mch, /* important stream module name chain, - * module names separated by "->" */ - char **mn, /* pointer to module name receiver */ -#else /* UNIXWAREV<70103 */ - char *mn, /* module name receiver */ -#endif /* UNIXWAREV>=70103 */ - - char *sn, /* special module name */ - KA_T *sqp) /* special module's q_ptr */ +char **mch; /* important stream module name chain, + * module names separated by "->" */ +char **mn; /* pointer to module name receiver */ +#else /* UNIXWAREV<70103 */ +char *mn; /* module name receiver */ +#endif /* UNIXWAREV>=70103 */ + +char *sn; /* special module name */ +KA_T *sqp; /* special module's q_ptr */ { struct module_info mi; KA_T qp; @@ -197,7 +206,7 @@ static int examine_stream(struct lsof_context *ctx, /* context */ /* * Read stream queue entry. */ - if (kread(ctx, qp, (char *)q, sizeof(struct queue))) { + if (kread(qp, (char *)q, sizeof(struct queue))) { (void)snpf(Namech, Namechl, "can't read stream queue from %s", print_kptr(qp, (char *)NULL, 0)); enter_nm(Namech); @@ -228,9 +237,9 @@ static int examine_stream(struct lsof_context *ctx, /* context */ */ #if UNIXWAREV < 70103 - if (!mi.mi_idname || kread(ctx, (KA_T)mi.mi_idname, mn, STRNML - 1)) + if (!mi.mi_idname || kread((KA_T)mi.mi_idname, mn, STRNML - 1)) #else /* UNIXWAREV>=70103 */ - if (!mi.mi_idname || kread(ctx, (KA_T)mi.mi_idname, tmnb, STRNML)) + if (!mi.mi_idname || kread((KA_T)mi.mi_idname, tmnb, STRNML)) #endif /* UNIXWAREV<70103 */ { @@ -305,8 +314,9 @@ static int examine_stream(struct lsof_context *ctx, /* context */ * findspdev() - find special device by raw major device number */ -static struct l_dev *findspdev(dev_t *dev, /* containing device */ - dev_t *rdev) /* raw device */ +static struct l_dev *findspdev(dev, rdev) +dev_t *dev; /* containing device */ +dev_t *rdev; /* raw device */ { int i; struct l_dev *dp; @@ -329,8 +339,9 @@ static struct l_dev *findspdev(dev_t *dev, /* containing device */ * findstrdev() - look up stream device by device number */ -static struct l_dev *findstrdev(dev_t *dev, /* device */ - dev_t *rdev) /* raw device */ +static struct l_dev *findstrdev(dev, rdev) +dev_t *dev; /* device */ +dev_t *rdev; /* raw device */ { struct clone *c; struct l_dev *dp; @@ -415,11 +426,11 @@ static void getspdev() { * -3 if the vfs structure can't be read */ -static int get_vty(struct lsof_context *ctx, /* context */ - struct vnode *v, /* vnode to test */ - KA_T va, /* vnode's kernel address */ - struct vfs *kv, /* copy of vnode's kernel vfs struct */ - int *fx) /* file system type index */ +static int get_vty(v, va, kv, fx) +struct vnode *v; /* vnode to test */ +KA_T va; /* vnode's kernel address */ +struct vfs *kv; /* copy of vnode's kernel vfs struct */ +int *fx; /* file system type index */ { int fxt; int nty = N_REGLR; @@ -435,7 +446,7 @@ static int get_vty(struct lsof_context *ctx, /* context */ return (N_STREAM); return (N_REGLR); } - if (!kread(ctx, (KA_T)v->v_vfsp, (char *)kv, sizeof(struct vfs))) { + if (!kread((KA_T)v->v_vfsp, (char *)kv, sizeof(struct vfs))) { /* * Check the file system type. @@ -484,10 +495,11 @@ static int get_vty(struct lsof_context *ctx, /* context */ * ismouse() - is vnode attached to /dev/mouse */ -static struct l_dev *ismouse(struct vnode *va, /* local vnode address */ - struct l_ino *i, /* local inode structure */ - int fx, /* file system index */ - struct vfs *kv) /* copy of kernel VFS structure */ +static struct l_dev *ismouse(va, i, fx, kv) +struct vnode *va; /* local vnode address */ +struct l_ino *i; /* local inode structure */ +int fx; /* file system index */ +struct vfs *kv; /* copy of kernel VFS structure */ { struct l_dev *dp; int j; @@ -516,21 +528,21 @@ static struct l_dev *ismouse(struct vnode *va, /* local vnode address */ * isvlocked() - is a vnode locked */ -static char isvlocked(struct lsof_context *ctx, /* context */ - struct vnode *va) /* local vnode address */ +static enum lsof_lock_mode isvlocked(va) +struct vnode *va; /* local vnode address */ { struct filock f; KA_T flf, flp; int i, l; if (!(flf = (KA_T)va->v_filocks)) - return (' '); + return (LSOF_LOCK_NONE); flp = flf; i = 0; do { if (i++ > 1000) break; - if (kread(ctx, flp, (char *)&f, sizeof(f))) + if (kread(flp, (char *)&f, sizeof(f))) break; if (f.set.l_sysid || f.set.l_pid != (pid_t)Lp->pid) continue; @@ -552,13 +564,13 @@ static char isvlocked(struct lsof_context *ctx, /* context */ l = 0; switch (f.set.l_type & (F_RDLCK | F_WRLCK)) { case F_RDLCK: - return ((l) ? 'R' : 'r'); + return ((l) ? LSOF_LOCK_READ_FULL : LSOF_LOCK_READ_PARTIAL); case F_WRLCK: - return ((l) ? 'W' : 'w'); + return ((l) ? LSOF_LOCK_WRITE_FULL : LSOF_LOCK_WRITE_PARTIAL); case (F_RDLCK + F_WRLCK): - return ('u'); + return (LSOF_LOCK_READ_WRITE); default: - return (' '); + return (LSOF_LOCK_NONE); } } while (flp != (KA_T)f.next && (flp = (KA_T)f.next) && flp != flf); return (' '); @@ -568,8 +580,7 @@ static char isvlocked(struct lsof_context *ctx, /* context */ * process_node() - process node */ -void process_node(struct lsof_context *ctx, /* context */ - KA_T na) /* vnode kernel space address */ +void process_node(na) KA_T na; /* vnode kernel space address */ { char *cp, *ep; dev_t dev, rdev; @@ -604,7 +615,7 @@ void process_node(struct lsof_context *ctx, /* context */ struct so_so so; KA_T sqp = (KA_T)NULL; size_t sz; - char tbuf[32], *ty; + char tbuf[32]; enum vtype type; struct sockaddr_un ua; @@ -705,7 +716,7 @@ void process_node(struct lsof_context *ctx, /* context */ } break; case N_NM: - if (!v.v_data || kread(ctx, (KA_T)v.v_data, (char *)&nn, sizeof(nn))) { + if (!v.v_data || kread((KA_T)v.v_data, (char *)&nn, sizeof(nn))) { (void)snpf(Namech, Namechl, "vnode@%s: no namenode (%s)", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr((KA_T)v.v_data, (char *)NULL, 0)); @@ -722,7 +733,7 @@ void process_node(struct lsof_context *ctx, /* context */ * The name node is mounted over/to another vnode. Process that node. */ (void)ent_fa(&na, (KA_T *)&nn.nm_mountpt, "->"); - if (kread(ctx, (KA_T)nn.nm_mountpt, (char *)&rv, sizeof(rv))) { + if (kread((KA_T)nn.nm_mountpt, (char *)&rv, sizeof(rv))) { (void)snpf(Namech, Namechl, "vnode@%s: can't read namenode's mounted vnode (%s)", print_kptr(na, tbuf, sizeof(tbuf)), @@ -748,7 +759,7 @@ void process_node(struct lsof_context *ctx, /* context */ #if defined(HASPROCFS) case N_PROC: ni = 1; - if (!v.v_data || kread(ctx, (KA_T)v.v_data, (char *)&pr, sizeof(pr))) { + if (!v.v_data || kread((KA_T)v.v_data, (char *)&pr, sizeof(pr))) { (void)snpf(Namech, Namechl, "vnode@%s: can't read prnode (%s)", print_kptr(na, tbuf, sizeof(tbuf)), print_kptr((KA_T)v.v_data, (char *)NULL, 0)); @@ -760,7 +771,7 @@ void process_node(struct lsof_context *ctx, /* context */ i.number = (INODETYPE)pr.pr_ino; sd = 0; if (pr.pr_common && - !kread(ctx, (KA_T)pr.pr_common, (char *)&prc, sizeof(prc))) { + !kread((KA_T)pr.pr_common, (char *)&prc, sizeof(prc))) { pid = (long)prc.prc_pid; switch (pr.pr_type) { case PR_PIDDIR: @@ -820,15 +831,14 @@ void process_node(struct lsof_context *ctx, /* context */ i.number = (INODETYPE)0; break; } - if (kread(ctx, (KA_T)pr.pr_proc, (char *)&p, sizeof(p))) { + if (kread((KA_T)pr.pr_proc, (char *)&p, sizeof(p))) { (void)snpf(Namech, Namechl, "prnode@%s: can't read proc (%s)", print_kptr((KA_T)v.v_data, tbuf, sizeof(tbuf)), print_kptr((KA_T)pr.pr_proc, (char *)NULL, 0)); enter_nm(Namech); return; } - if (!p.p_pidp || - kread(ctx, (KA_T)p.p_pidp, (char *)&pids, sizeof(pids))) { + if (!p.p_pidp || kread((KA_T)p.p_pidp, (char *)&pids, sizeof(pids))) { (void)snpf(Namech, Namechl, "proc struct at %s: can't read pid (%s)", print_kptr((KA_T)pr.pr_proc, tbuf, sizeof(tbuf)), @@ -839,7 +849,7 @@ void process_node(struct lsof_context *ctx, /* context */ pid = (long)pids.pid_id; (void)snpf(Namech, Namechl, "/%s/%ld", HASPROCFS, pid); i.number = (INODETYPE)(pid + PR_INOBIAS); - if (!p.p_as || kread(ctx, (KA_T)p.p_as, (char *)&as, sizeof(as))) + if (!p.p_as || kread((KA_T)p.p_as, (char *)&as, sizeof(as))) sd = 0; else i.size = as.a_size; @@ -886,7 +896,7 @@ void process_node(struct lsof_context *ctx, /* context */ * If this stream has a "sockmod" module with a non-NULL q_ptr, * try to use it to read an so_so structure. */ - if (sqp && kread(ctx, sqp, (char *)&so, sizeof(so)) == 0) + if (sqp && kread(sqp, (char *)&so, sizeof(so)) == 0) break; sqp = (KA_T)NULL; (void)snpf(Namech, Namechl, "STR"); @@ -898,7 +908,7 @@ void process_node(struct lsof_context *ctx, /* context */ */ if ((dp = findstrdev(&DevDev, (dev_t *)&v.v_rdev))) { Lf->inode = dp->inode; - Lf->inp_ty = 1; + Lf->inode_def = 1; Namech[j++] = ':'; k = strlen(dp->name); if ((j + k) <= (Namechl - 1)) { @@ -1104,13 +1114,13 @@ void process_node(struct lsof_context *ctx, /* context */ case N_NFS: Lf->inode = (INODETYPE)r.r_attr.va_nodeid; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #if defined(HASPROCFS) case N_PROC: Lf->inode = i.number; - Lf->inp_ty = 1; + Lf->inode_def = 1; break; #endif /* defined(HASPROCFS) */ @@ -1118,7 +1128,7 @@ void process_node(struct lsof_context *ctx, /* context */ if (!f.fn_realvp) { enter_dev_ch(print_kptr((KA_T)v.v_data, (char *)NULL, 0)); Lf->inode = (INODETYPE)f.fn_ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; if (f.fn_flag & ISPIPE) (void)snpf(Namech, Namechl, "PIPE"); if (f.fn_mate) { @@ -1133,22 +1143,24 @@ void process_node(struct lsof_context *ctx, /* context */ case N_REGLR: if (!ni) { Lf->inode = i.number; - Lf->inp_ty = (Ntype == N_CFS) ? i.number_def : 1; + Lf->inode_def = (Ntype == N_CFS) ? i.number_def : 1; } break; case N_STREAM: if (sqp && so.lux_dev.size >= 8) { Lf->inode = (INODETYPE)so.lux_dev.addr.tu_addr.ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } } /* * Obtain the file size. */ + Lf->off_def = 1; switch (Ntype) { case N_FIFO: case N_STREAM: + Lf->off_def = 1; break; case N_NFS: Lf->sz = (SZOFFTYPE)r.r_attr.va_size; @@ -1176,7 +1188,8 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->sz = (SZOFFTYPE)i.size; Lf->sz_def = (Ntype == N_CFS) ? i.size_def : sd; } - } + } else if (((type == VBLK) || (type == VCHR))) + Lf->off_def = 1; break; } /* @@ -1228,35 +1241,35 @@ void process_node(struct lsof_context *ctx, /* context */ } switch (type) { case VNON: - ty = "VNON"; + Lf->type = LSOF_FILE_VNODE_VNON; break; case VREG: - ty = "VREG"; + Lf->type = LSOF_FILE_VNODE_VREG; break; case VDIR: - ty = "VDIR"; + Lf->type = LSOF_FILE_VNODE_VDIR; break; case VBLK: - ty = "VBLK"; + Lf->type = LSOF_FILE_VNODE_VBLK; Ntype = N_BLK; break; case VCHR: - ty = "VCHR"; + Lf->type = LSOF_FILE_VNODE_VCHR; if (Lf->is_stream == 0) Ntype = N_CHR; break; case VLNK: - ty = "VLNK"; + Lf->type = LSOF_FILE_VNODE_VLNK; break; #if defined(VSOCK) case VSOCK: - ty = "SOCK"; + Lf->type = LSOF_FILE_VNODE_VSOCK; break; #endif /* VSOCK */ case VBAD: - ty = "VBAD"; + Lf->type = LSOF_FILE_VNODE_VBAD; break; case VFIFO: if (!Lf->dev_ch || Lf->dev_ch[0] == '\0') { @@ -1265,29 +1278,27 @@ void process_node(struct lsof_context *ctx, /* context */ Lf->rdev = rdev; Lf->rdev_def = rdevs; } - ty = "FIFO"; + Lf->type = LSOF_FILE_VNODE_VFIFO; break; case VUNNAMED: - ty = "UNNM"; + Lf->type = LSOF_FILE_VNODE_VUNNAMED; break; default: - (void)snpf(Lf->type, sizeof(Lf->type), "%04o", (type & 0xfff)); - ty = NULL; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = type; + break; } - if (ty) - (void)snpf(Lf->type, sizeof(Lf->type), "%s", ty); - Lf->ntype = Ntype; /* * If this is a VBLK file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (Lf->ntype == N_BLK)) + if (!Lf->inode_def && (Ntype == N_BLK)) find_bl_ino(); /* * If this is a VCHR file and it's missing an inode number, try to * supply one. */ - if ((Lf->inp_ty == 0) && (type == VCHR)) + if (!Lf->inode_def && (type == VCHR)) find_ch_ino(); /* * If this is a stream with a "sockmod" module whose q_ptr leads to an @@ -1297,16 +1308,16 @@ void process_node(struct lsof_context *ctx, /* context */ if (Ntype == N_STREAM && sqp) { if (Funix) Lf->sf |= SELUNX; - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); + Lf->type = LSOF_FILE_UNIX; if (!Namech[0] && so.laddr.buf && so.laddr.len == sizeof(ua) && - !kread(ctx, (KA_T)so.laddr.buf, (char *)&ua, sizeof(ua))) { + !kread((KA_T)so.laddr.buf, (char *)&ua, sizeof(ua))) { ua.sun_path[sizeof(ua.sun_path) - 1] = '\0'; (void)snpf(Namech, Namechl, "%s", ua.sun_path); if (Sfile && is_file_named(Namech, 0)) Lf->sf = SELNM; if (so.lux_dev.size >= 8) { Lf->inode = (INODETYPE)so.lux_dev.addr.tu_addr.ino; - Lf->inp_ty = 1; + Lf->inode_def = 1; } } if (so.so_conn) { @@ -1331,7 +1342,7 @@ void process_node(struct lsof_context *ctx, /* context */ if ((pfi->pid && pid && pfi->pid == (pid_t)pid) # if defined(HASPINODEN) - || ((Lf->inp_ty == 1) && (Lf->inode == pfi->inode)) + || (Lf->inode_def && (Lf->inode == pfi->inode)) # endif /* defined(HASPINODEN) */ ) { @@ -1379,9 +1390,10 @@ void process_node(struct lsof_context *ctx, /* context */ * readlino() - read local inode information */ -static int readlino(struct lsof_context *ctx, int fx, /* file system index */ - struct vnode *v, /* vnode pointing to inode */ - struct l_ino *i) /* local inode */ +static int readlino(fx, v, i) +int fx; /* file system index */ +struct vnode *v; /* vnode pointing to inode */ +struct l_ino *i; /* local inode */ { #if defined(HAS_UW_CFS) @@ -1401,7 +1413,7 @@ static int readlino(struct lsof_context *ctx, int fx, /* file system index */ return (1); if (!strcmp(Fsinfo[fx - 1], "fifofs") || !strcmp(Fsinfo[fx - 1], "sfs") || !strcmp(Fsinfo[fx - 1], "ufs")) { - if (kread(ctx, (KA_T)v->v_data, (char *)&sn, sizeof(sn))) + if (kread((KA_T)v->v_data, (char *)&sn, sizeof(sn))) return (1); i->dev = sn.i_dev; i->dev_def = 1; @@ -1418,7 +1430,7 @@ static int readlino(struct lsof_context *ctx, int fx, /* file system index */ #if defined(HAS_UW_CFS) else if (!strcmp(Fsinfo[fx - 1], "nsc_cfs")) { - if (kread(ctx, (KA_T)v->v_data, (char *)&cn, sizeof(cn))) + if (kread((KA_T)v->v_data, (char *)&cn, sizeof(cn))) return (1); if (cn.c_attr.va_mask & AT_FSID) { i->dev = cn.c_attr.va_fsid; @@ -1457,7 +1469,7 @@ static int readlino(struct lsof_context *ctx, int fx, /* file system index */ #if defined(HASXNAMNODE) else if (!strcmp(Fsinfo[fx - 1], "xnamfs") || !strcmp(Fsinfo[fx - 1], "XENIX")) { - if (kread(ctx, (KA_T)v->v_data, (char *)&xn, sizeof(xn))) + if (kread((KA_T)v->v_data, (char *)&xn, sizeof(xn))) return (1); i->dev = xn.x_dev; i->nlink = (long)xn.x_count; @@ -1470,7 +1482,7 @@ static int readlino(struct lsof_context *ctx, int fx, /* file system index */ #endif /* defined(HASXNAMNODE) */ else if (!strcmp(Fsinfo[fx - 1], "memfs")) { - if (kread(ctx, (KA_T)v->v_data, (char *)&mn, sizeof(mn))) + if (kread((KA_T)v->v_data, (char *)&mn, sizeof(mn))) return (1); i->dev = mn.mno_fsid; i->dev_def = 1; diff --git a/lib/dialects/uw/dnode1.c b/lib/dialects/uw/dnode1.c index b24f7d92..ed67fd71 100644 --- a/lib/dialects/uw/dnode1.c +++ b/lib/dialects/uw/dnode1.c @@ -66,12 +66,13 @@ static char copyright[] = * reads5lino() - read s5 inode's local inode information */ -int reads5lino(struct lsof_context *ctx, struct vnode *v, /* containing vnode */ - struct l_ino *i) /* local inode information */ +int reads5lino(v, i) +struct vnode *v; /* containing vnode */ +struct l_ino *i; /* local inode information */ { struct inode s5i; - if (kread(ctx, (KA_T)v->v_data, (char *)&s5i, sizeof(s5i))) + if (kread((KA_T)v->v_data, (char *)&s5i, sizeof(s5i))) return (1); i->dev = s5i.i_dev; i->dev_def = 1; diff --git a/lib/dialects/uw/dnode2.c b/lib/dialects/uw/dnode2.c index 2cd9d3d4..a8079e25 100644 --- a/lib/dialects/uw/dnode2.c +++ b/lib/dialects/uw/dnode2.c @@ -76,15 +76,15 @@ struct vx_inode { * readvxfslino() - read vxfs inode's local inode information */ -int readvxfslino(struct lsof_context *ctx, - struct vnode *v, /* containing vnode */ - struct l_ino *i) /* local inode information */ +int readvxfslino(v, i) +struct vnode *v; /* containing vnode */ +struct l_ino *i; /* local inode information */ { #if defined(HASVXFS) struct vx_inode vx; - if (kread(ctx, (KA_T)v->v_data, (char *)&vx, sizeof(vx))) + if (kread((KA_T)v->v_data, (char *)&vx, sizeof(vx))) return (1); i->dev = vx.i_dev; i->dev_def = 1; diff --git a/lib/dialects/uw/dnode3.c b/lib/dialects/uw/dnode3.c index fc198627..59f34dc6 100644 --- a/lib/dialects/uw/dnode3.c +++ b/lib/dialects/uw/dnode3.c @@ -108,16 +108,16 @@ static unsigned char Dos2Unix[] = { * readbfslino() - read bfs inode's local inode information */ -int readbfslino(struct lsof_context *ctx, /* context */ - struct vnode *v, /* containing vnode */ - struct l_ino *i) /* local inode information */ +int readbfslino(v, i) +struct vnode *v; /* containing vnode */ +struct l_ino *i; /* local inode information */ { struct inode b; struct vfs kv; - if (kread(ctx, (KA_T)v->v_data, (char *)&b, sizeof(b))) + if (kread((KA_T)v->v_data, (char *)&b, sizeof(b))) return (1); - if (!v->v_vfsp || kread(ctx, (KA_T)v->v_vfsp, (char *)&kv, sizeof(kv))) + if (!v->v_vfsp || kread((KA_T)v->v_vfsp, (char *)&kv, sizeof(kv))) return (1); i->dev = kv.vfs_dev; i->dev_def = 1; @@ -140,9 +140,9 @@ int readbfslino(struct lsof_context *ctx, /* context */ * Adapted from work by Eric Dumazet . */ -int readcdfslino(struct lsof_context *ctx, /* context */ - struct vnode *v, /* containing vnode */ - struct l_ino *i) /* local inode information */ +int readcdfslino(v, i) +struct vnode *v; /* containing vnode */ +struct l_ino *i; /* local inode information */ { cdfs_inode_t ci; TYPELOGSECSHIFT lss; @@ -151,9 +151,9 @@ int readcdfslino(struct lsof_context *ctx, /* context */ /* * Read the CDFs node. Fill in return values from its contents. */ - if (!v->v_data || kread(ctx, (KA_T)v->v_data, (char *)&ci, sizeof(ci))) + if (!v->v_data || kread((KA_T)v->v_data, (char *)&ci, sizeof(ci))) return (1); - if (!v->v_vfsp || kread(ctx, (KA_T)v->v_vfsp, (char *)&kv, sizeof(kv))) + if (!v->v_vfsp || kread((KA_T)v->v_vfsp, (char *)&kv, sizeof(kv))) return (1); i->dev = kv.vfs_dev; i->dev_def = 1; @@ -178,7 +178,7 @@ int readcdfslino(struct lsof_context *ctx, /* context */ if (!(ka = (KA_T)kv.vfs_data)) return (0); ka = (KA_T)((char *)ka + offsetof(struct cdfs, cdfs_LogSecShift)); - if (!kread(ctx, ka, (char *)&lss, sizeof(lss))) { + if (!kread(ka, (char *)&lss, sizeof(lss))) { i->number = (INODETYPE)((ci.i_Fid.fid_SectNum << lss) + ci.i_Fid.fid_Offset); i->number_def = 1; @@ -192,9 +192,9 @@ int readcdfslino(struct lsof_context *ctx, /* context */ * Adapted from work by Eric Dumazet . */ -int readdosfslino(struct lsof_context *ctx, /* context */ - struct vnode *v, /* containing vnode */ - struct l_ino *i) /* local inode information */ +int readdosfslino(v, i) +struct vnode *v; /* containing vnode */ +struct l_ino *i; /* local inode information */ { struct dosfs_inode { int pad1[19]; @@ -213,7 +213,7 @@ int readdosfslino(struct lsof_context *ctx, /* context */ /* * Read the DOSFS node. Fill in return values from its contents. */ - if (!v->v_data || kread(ctx, (KA_T)v->v_data, (char *)&di, sizeof(di))) + if (!v->v_data || kread((KA_T)v->v_data, (char *)&di, sizeof(di))) return (1); i->dev = (dev_t)di.device; i->dev_def = 1; diff --git a/lib/dialects/uw/dproc.c b/lib/dialects/uw/dproc.c index 7ed95e54..eb524a2e 100644 --- a/lib/dialects/uw/dproc.c +++ b/lib/dialects/uw/dproc.c @@ -68,7 +68,7 @@ static void process_text(KA_T pa); * gather_proc_info() -- gather process information */ -void gather_proc_info(struct lsof_context *ctx) { +void gather_proc_info() { struct cred cr; struct execinfo ex; static struct fd_entry *fe; @@ -103,21 +103,19 @@ void gather_proc_info(struct lsof_context *ctx) { /* * Get Process ID, Process group ID, and User ID. */ - if (!p->p_pidp || - kread(ctx, (KA_T)p->p_pidp, (char *)&pids, sizeof(pids))) + if (!p->p_pidp || kread((KA_T)p->p_pidp, (char *)&pids, sizeof(pids))) continue; pid = (int)pids.pid_id; #if defined(HAS_P_PGID) pgid = (int)p->p_pgid; #else /* !defined(HAS_P_PGID) */ - if (!p->p_pgidp || - kread(ctx, (KA_T)p->p_pgidp, (char *)&pids, sizeof(pids))) + if (!p->p_pgidp || kread((KA_T)p->p_pgidp, (char *)&pids, sizeof(pids))) continue; pgid = (int)pids.pid_id; #endif /* defined(HAS_P_PGID) */ - if (!p->p_cred || kread(ctx, (KA_T)p->p_cred, (char *)&cr, sizeof(cr))) + if (!p->p_cred || kread((KA_T)p->p_cred, (char *)&cr, sizeof(cr))) continue; uid = cr.cr_uid; if (is_proc_excl(pid, pgid, (UID_ARG)uid, &pss, &sf)) @@ -126,7 +124,7 @@ void gather_proc_info(struct lsof_context *ctx) { * Get the execution information -- for the command name. */ if (!p->p_execinfo || - kread(ctx, (KA_T)p->p_execinfo, (char *)&ex, sizeof(ex))) + kread((KA_T)p->p_execinfo, (char *)&ex, sizeof(ex))) continue; /* * Allocate a local process structure. @@ -178,14 +176,14 @@ void gather_proc_info(struct lsof_context *ctx) { } nfea = nf; } - if (kread(ctx, (KA_T)p->p_fdtab.fdt_entrytab, (char *)fe, len)) + if (kread((KA_T)p->p_fdtab.fdt_entrytab, (char *)fe, len)) continue; for (f = fe, i = 0; i < nf; f++, i++) { if ((fa = (KA_T)f->fd_file) && (f->fd_status & FD_INUSE)) { #if UNIXWAREV >= 70103 if (f->fd_flag & FPOLLED) { - if (kread(ctx, fa, (char *)&plx, sizeof(plx)) || + if (kread(fa, (char *)&plx, sizeof(plx)) || !(fa = (KA_T)plx.px_fp)) continue; } @@ -215,7 +213,7 @@ void gather_proc_info(struct lsof_context *ctx) { * get_clonemaj() - get clone major device number */ -static int get_clonemaj(struct lsof_context *ctx) { +static int get_clonemaj() { KA_T v; #if UNIXWAREV < 70000 @@ -228,7 +226,7 @@ static int get_clonemaj(struct lsof_context *ctx) { * Read the cdevsw[] size and allocate temporary space for it. */ if (get_Nl_value("ncdev", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&sz, sizeof(sz)) || !sz) + kread((KA_T)v, (char *)&sz, sizeof(sz)) || !sz) return (rv); len = (MALLOC_S)(sz * sizeof(struct cdevsw)); if (!(cd = (struct cdevsw *)malloc(len))) { @@ -239,7 +237,7 @@ static int get_clonemaj(struct lsof_context *ctx) { * Read the cdevsw[] from kernel memory. */ if (get_Nl_value("cdev", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)cd, (int)len)) { + kread((KA_T)v, (char *)cd, (int)len)) { (void)free((MALLOC_P *)cd); return (rv); } @@ -250,7 +248,7 @@ static int get_clonemaj(struct lsof_context *ctx) { len = sizeof(buf) - 1; buf[len] = '\0'; for (c = cd, i = 0; i < sz; c++, i++) { - if (!c->d_name || kread(ctx, (KA_T)c->d_name, buf, len) || + if (!c->d_name || kread((KA_T)c->d_name, buf, len) || strcmp(buf, "clone") != 0) continue; CloneMaj = i; @@ -265,7 +263,7 @@ static int get_clonemaj(struct lsof_context *ctx) { * clonemajor variable. */ if (get_Nl_value("cmaj", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&CloneMaj, sizeof(CloneMaj))) + kread((KA_T)v, (char *)&CloneMaj, sizeof(CloneMaj))) return (0); return ((HaveCloneMaj = 1)); #endif /* UNIXWAREV<70000 */ @@ -275,7 +273,7 @@ static int get_clonemaj(struct lsof_context *ctx) { * get_kernel_access() - get access to kernel memory */ -static void get_kernel_access(struct lsof_context *ctx) { +static void get_kernel_access() { KA_T v; /* * Check kernel version. @@ -293,7 +291,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * See if the non-KMEM memory file is readable. */ - if (Memory && !is_readable(Memory, 1)) + if (Memory && !is_readable(ctx, Memory, 1)) Error(ctx); #endif /* defined(WILLDROPGID) */ @@ -316,7 +314,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * See if the name list file is readable. */ - if (Nmlst && !is_readable(Nmlst, 1)) + if (Nmlst && !is_readable(ctx, Nmlst, 1)) Error(ctx); #endif /* defined(WILLDROPGID) */ @@ -330,7 +328,7 @@ static void get_kernel_access(struct lsof_context *ctx) { Error(ctx); } if (get_Nl_value("var", Drive_Nl, &v) < 0 || !v || - kread(ctx, (KA_T)v, (char *)&Var, sizeof(Var))) { + kread((KA_T)v, (char *)&Var, sizeof(Var))) { (void)fprintf(stderr, "%s: can't read system configuration info\n", Pn); Error(ctx); } @@ -358,18 +356,19 @@ static void get_kernel_access(struct lsof_context *ctx) { * initialize() - perform all initialization */ -void initialize(struct lsof_context *ctx) { +void initialize() { get_kernel_access(); - readfsinfo(struct lsof_context * ctx); + readfsinfo(); } /* * kread() - read from kernel memory */ -int kread(struct lsof_context *ctx, KA_T addr, /* kernel memory address */ - char *buf, /* buffer to receive data */ - READLEN_T len) /* length to read */ +int kread(addr, buf, len) +KA_T addr; /* kernel memory address */ +char *buf; /* buffer to receive data */ +READLEN_T len; /* length to read */ { READLEN_T br; @@ -402,7 +401,7 @@ static void process_text(pa) KA_T pa; /* kernel address space description /* * Get address space description. */ - if (kread(ctx, pa, (char *)&as, sizeof(as))) + if (kread(pa, (char *)&as, sizeof(as))) return; /* * Loop through the segments. The loop should stop when the segment @@ -411,7 +410,7 @@ static void process_text(pa) KA_T pa; /* kernel address space description */ s.s_next = as.a_segs; for (i = j = k = 0; i < MAXSEGS && j < 2 * MAXSEGS; j++) { - if (!s.s_next || kread(ctx, (KA_T)s.s_next, (char *)&s, sizeof(s))) + if (!s.s_next || kread((KA_T)s.s_next, (char *)&s, sizeof(s))) break; fd = (char *)NULL; vp = (KA_T)NULL; @@ -420,7 +419,7 @@ static void process_text(pa) KA_T pa; /* kernel address space description /* * Process a virtual node segment. */ - if (kread(ctx, (KA_T)s.s_data, (char *)&vn, sizeof(vn))) + if (kread((KA_T)s.s_data, (char *)&vn, sizeof(vn))) break; if ((vp = (KA_T)vn.svd_vp)) { if ((vn.svd_flags & SEGVN_PGPROT) || (vn.svd_prot & PROT_EXEC)) @@ -433,7 +432,7 @@ static void process_text(pa) KA_T pa; /* kernel address space description /* * Process a special device segment. */ - if (kread(ctx, (KA_T)s.s_data, (char *)&dv, sizeof(dv))) + if (kread((KA_T)s.s_data, (char *)&dv, sizeof(dv))) break; if ((vp = (KA_T)dv.vp)) fd = "mmap"; @@ -471,7 +470,7 @@ static void process_text(pa) KA_T pa; /* kernel address space description * readfsinfo() - read file system information */ -static void readfsinfo(struct lsof_context *ctx) { +static void readfsinfo() { char buf[FSTYPSZ + 1]; int i, len; @@ -507,7 +506,7 @@ static void readfsinfo(struct lsof_context *ctx) { * read_proc() - read the process table */ -static void read_proc(struct lsof_context *ctx) { +static void read_proc() { MALLOC_S len; struct proc *p; KA_T pa; @@ -541,7 +540,7 @@ static void read_proc(struct lsof_context *ctx) { * Read the active process chain head. */ pa = (KA_T)NULL; - if (!Pract || kread(ctx, (KA_T)Pract, (char *)&pa, sizeof(pa)) || !pa) { + if (!Pract || kread((KA_T)Pract, (char *)&pa, sizeof(pa)) || !pa) { if (!Fwarn) (void)fprintf( stderr, "%s: active proc chain ptr err; addr=%s, val=%s\n", @@ -569,7 +568,7 @@ static void read_proc(struct lsof_context *ctx) { } p = &P[Np]; } - if (kread(ctx, pa, (char *)p, sizeof(struct proc))) + if (kread(pa, (char *)p, sizeof(struct proc))) break; pa = (KA_T)p->p_next; if ((p->p_flag & P_DESTROY) || (p->p_flag & P_GONE) || !p->p_pidp diff --git a/lib/dialects/uw/dsock.c b/lib/dialects/uw/dsock.c index b309b52f..be28cd9d 100644 --- a/lib/dialects/uw/dsock.c +++ b/lib/dialects/uw/dsock.c @@ -749,12 +749,11 @@ void print_tcptpi(nl) int nl; /* 1 == '\n' required */ * process_socket() - process socket */ -void process_socket(struct lsof_context *ctx, /* context */ - char *pr, /* protocol name */ - struct queue *q) /* queue at end of stream */ +void process_socket(enum lsof_protocol pr, /* protocol name */ + struct queue *q) /* queue at end of stream */ { unsigned char *fa = (unsigned char *)NULL; - int fp, ipv, lp; + int fp, af, lp; struct inpcb inp; unsigned char *la = (unsigned char *)NULL; struct tcpcb t; @@ -765,407 +764,402 @@ void process_socket(struct lsof_context *ctx, /* context */ /* * Process protocol specification. */ - Lf->inp_ty = 2; - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%s", pr); + Lf->iproto = pr; Lf->is_stream = 0; - if (strcasecmp(pr, "TCP") == 0) { - ipv = 4; + if (pr == LSOF_PROTOCOL_TCP) { + af = AF_INET; tcp = 1; - } else if (strcasecmp(pr, "UDP") == 0) { - ipv = 4; + } else if (pr == LSOF_PROTOCOL_UDP) { + af = AF_INET; udp = 1; } -#if defined(HASIPv6) - else if (strcasecmp(pr, "TCP6") == 0) { - ipv = 6; - tcp = 1; - Lf->iproto[3] = '\0'; - } else if (strcasecmp(pr, "UDP6") == 0) { - ipv = 6; - udp = 1; - Lf->iproto[3] = '\0'; - } -#endif /* defined(HASIPv6) */ - if (Fnet && (tcp || udp)) { - if (!FnetTy || (FnetTy == ipv)) + if (FnetTy == AF_UNSPEC || FnetTy == af) { Lf->sf |= SELNET; - } + } #if defined(HASIPv6) - (void)snpf(Lf->type, sizeof(Lf->type), (ipv == 6) ? "IPv6" : "IPv4"); + Lf->type = (af == AF_INET6) ? LSOF_FILE_IPV6 : LSOF_FILE_IPV4; #else /* !defined(HASIPv6) */ - (void)snpf(Lf->type, sizeof(Lf->type), "inet"); + Lf->type = LSOF_FILE_INET; #endif /* defined(HASIPv6) */ - /* - * The PCB address is found in the private data structure at the end - * of the queue. - */ - if (q->q_ptr) { - enter_dev_ch(print_kptr((KA_T)q->q_ptr, (char *)NULL, 0)); - if (tcp || udp) { - if (kread(ctx, (KA_T)q->q_ptr, (char *)&inp, sizeof(inp))) { - (void)snpf(Namech, Namechl, "can't read inpcb from %s", - print_kptr((KA_T)q->q_ptr, (char *)NULL, 0)); - enter_nm(Namech); - return; - } - la = (unsigned char *)&inp.inp_laddr; - lp = (int)ntohs(inp.inp_lport); - if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport != 0) { - fa = (unsigned char *)&inp.inp_faddr; - fp = (int)ntohs(inp.inp_fport); - } - if (fa || la) - (void)ent_inaddr(la, lp, fa, fp, AF_INET); - if (tcp) { - if (inp.inp_ppcb && - !kread(ctx, (KA_T)inp.inp_ppcb, (char *)&t, sizeof(t))) { - ts = 1; - Lf->lts.type = 0; - Lf->lts.state.i = (int)t.t_state; + /* + * The PCB address is found in the private data structure at the end + * of the queue. + */ + if (q->q_ptr) { + enter_dev_ch(print_kptr((KA_T)q->q_ptr, (char *)NULL, 0)); + if (tcp || udp) { + if (kread((KA_T)q->q_ptr, (char *)&inp, sizeof(inp))) { + (void)snpf(Namech, Namechl, "can't read inpcb from %s", + print_kptr((KA_T)q->q_ptr, (char *)NULL, 0)); + enter_nm(Namech); + return; } - } else { - Lf->lts.type = 1; - Lf->lts.state.i = (int)inp.inp_tstate; - } + la = (unsigned char *)&inp.inp_laddr; + lp = (int)ntohs(inp.inp_lport); + if (inp.inp_faddr.s_addr != INADDR_ANY || inp.inp_fport != 0) { + fa = (unsigned char *)&inp.inp_faddr; + fp = (int)ntohs(inp.inp_fport); + } + if (fa || la) + (void)ent_inaddr(la, lp, fa, fp, AF_INET); + if (tcp) { + if (inp.inp_ppcb && + !kread((KA_T)inp.inp_ppcb, (char *)&t, sizeof(t))) { + ts = 1; + Lf->lts.type = 0; + Lf->lts.state.i = (int)t.t_state; + } + } else { + Lf->lts.type = 1; + Lf->lts.state.i = (int)inp.inp_tstate; + } + } else + enter_nm("no address for this protocol"); } else - enter_nm("no address for this protocol"); - } else - enter_nm("no address"); - /* - * Save size information. - */ - if (ts) { + enter_nm("no address"); + /* + * Save size information. + */ + if (ts) { #if UNIXWAREV >= 70000 # define t_outqsize t_qsize #endif /* UNIXWAREV>=70000 */ - if (Lf->access == LSOF_FILE_ACCESS_READ) - Lf->sz = (SZOFFTYPE)t.t_iqsize; - else if (Lf->access == LSOF_FILE_ACCESS_WRITE) - Lf->sz = (SZOFFTYPE)t.t_outqsize; - else - Lf->sz = (SZOFFTYPE)(t.t_iqsize + t.t_outqsize); - Lf->sz_def = 1; + if (Lf->access == LSOF_FILE_ACCESS_READ) + Lf->sz = (SZOFFTYPE)t.t_iqsize; + else if (Lf->access == LSOF_FILE_ACCESS_WRITE) + Lf->sz = (SZOFFTYPE)t.t_outqsize; + else + Lf->sz = (SZOFFTYPE)(t.t_iqsize + t.t_outqsize); + Lf->sz_def = 1; + + Lf->off_def = 1; #if defined(HASTCPTPIQ) - Lf->lts.rq = (unsigned long)t.t_iqsize; - Lf->lts.sq = (unsigned long)t.t_outqsize; - Lf->lts.rqs = Lf->lts.sqs = 1; + Lf->lts.rq = (unsigned long)t.t_iqsize; + Lf->lts.sq = (unsigned long)t.t_outqsize; + Lf->lts.rqs = Lf->lts.sqs = 1; #endif /* defined(HASTCPTPIQ) */ #if defined(HASSOOPT) - Lf->lts.opt = (unsigned int)inp.inp_protoopt; - Lf->lts.ltm = (unsigned int)inp.inp_linger; - Lf->lts.pqlen = (unsigned int)t.t_q0len; - Lf->lts.qlen = (unsigned int)t.t_qlen; - Lf->lts.qlim = (unsigned int)t.t_qlimit; - Lf->lts.rbsz = (unsigned long)inp.inp_rbufsize; - Lf->lts.sbsz = (unsigned long)inp.inp_sbufsize; - Lf->lts.pqlens = Lf->lts.qlens = Lf->lts.qlims = Lf->lts.rbszs = - Lf->lts.sbszs = (unsigned char)1; + Lf->lts.opt = (unsigned int)inp.inp_protoopt; + Lf->lts.ltm = (unsigned int)inp.inp_linger; + Lf->lts.pqlen = (unsigned int)t.t_q0len; + Lf->lts.qlen = (unsigned int)t.t_qlen; + Lf->lts.qlim = (unsigned int)t.t_qlimit; + Lf->lts.rbsz = (unsigned long)inp.inp_rbufsize; + Lf->lts.sbsz = (unsigned long)inp.inp_sbufsize; + Lf->lts.pqlens = Lf->lts.qlens = Lf->lts.qlims = Lf->lts.rbszs = + Lf->lts.sbszs = (unsigned char)1; #endif /* defined(HASSOOPT) */ #if defined(HASSOSTATE) - Lf->lts.ss = (unsigned int)inp.inp_state; + Lf->lts.ss = (unsigned int)inp.inp_state; #endif /* defined(HASSOSTATE) */ #if defined(HASTCPOPT) - Lf->lts.mss = (unsigned long)t.t_maxseg; - Lf->lts.msss = (unsigned char)1; - Lf->lts.topt = (unsigned int)t.t_flags; + Lf->lts.mss = (unsigned long)t.t_maxseg; + Lf->lts.msss = (unsigned char)1; + Lf->lts.topt = (unsigned int)t.t_flags; #endif /* defined(HASTCPOPT) */ - } else { - Lf->sz = (SZOFFTYPE)q->q_count; - Lf->sz_def = 1; + } else { + Lf->sz = (SZOFFTYPE)q->q_count; + Lf->sz_def = 1; + Lf->off_def = 1; + } + enter_nm(Namech); + return; } - enter_nm(Namech); - return; -} #if UNIXWAREV >= 70101 -/* - * process_unix_sockstr() - process a UNIX socket stream, if applicable - */ + /* + * process_unix_sockstr() - process a UNIX socket stream, if applicable + */ -int process_unix_sockstr(struct lsof_context *ctx, - struct vnode *v, /* the stream's vnode */ - KA_T na) /* kernel vnode address */ -{ - int as; - char *ep, tbuf[32], tbuf1[32], *ty; - KA_T ka, sa, sh; - struct stdata sd; - struct ss_socket ss; - size_t sz; + int process_unix_sockstr(v, na) struct vnode *v; /* the stream's vnode */ + KA_T na; /* kernel vnode address */ + { + int as; + char *ep, tbuf[32], tbuf1[32], *ty; + KA_T ka, sa, sh; + struct stdata sd; + struct ss_socket ss; + size_t sz; # if UNIXWAREV < 70103 - struct sockaddr_un *la, *ra; + struct sockaddr_un *la, *ra; # else /* UNIXWAREV>=70103 */ - struct sockaddr_un la, ra; - unsigned char las = 0; - unsigned char ras = 0; - int up = (int)(sizeof(la.sun_path) - 1); - /* - * It's serious if the sizeof(sun_path) in sockaddr_un isn't greater than - * zero. - */ - if (up < 0) { - (void)snpf(Namech, Namechl, "sizeof(sun_path) < 1 (%d)", up); - enter_nm(Namech); - return (1); - } + struct sockaddr_un la, ra; + unsigned char las = 0; + unsigned char ras = 0; + int up = (int)(sizeof(la.sun_path) - 1); + /* + * It's serious if the sizeof(sun_path) in sockaddr_un isn't greater + * than zero. + */ + if (up < 0) { + (void)snpf(Namech, Namechl, "sizeof(sun_path) < 1 (%d)", up); + enter_nm(Namech); + return (1); + } # endif /* UNIXWAREV<70103 */ - /* - * Read the stream head, if possible. - */ - if (!(sh = (KA_T)v->v_stream)) - return (0); - if (readstdata(sh, &sd)) { - (void)snpf(Namech, Namechl, "vnode at %s; can't read stream head at %s", - print_kptr(na, (char *)NULL, 0), - print_kptr(sh, tbuf, sizeof(tbuf))); - enter_nm(Namech); - return (1); - } - /* - * If the stream head has pointer to a socket, read the socket structure - */ - if (!(sa = (KA_T)sd.sd_socket)) - return (0); - if (kread(ctx, sa, (char *)&ss, sizeof(ss))) { - (void)snpf(Namech, Namechl, - "vnode at %s; stream head at %s; can't read socket at %s", - print_kptr(na, (char *)NULL, 0), - print_kptr(sh, tbuf, sizeof(tbuf)), - print_kptr(sa, tbuf1, sizeof(tbuf1))); - enter_nm(Namech); - return (1); - } - /* - * If the socket is bound to the PF_UNIX protocol family, process it as - * a UNIX socket. Otherwise, return and let the vnode be processed as a - * stream. - */ - if (ss.family != PF_UNIX) - return (0); - (void)snpf(Lf->type, sizeof(Lf->type), "unix"); - if (Funix) - Lf->sf |= SELUNX; - Lf->is_stream = 0; - enter_dev_ch(print_kptr(sa, (char *)NULL, 0)); - /* - * Process the local address. - */ + /* + * Read the stream head, if possible. + */ + if (!(sh = (KA_T)v->v_stream)) + return (0); + if (readstdata(sh, &sd)) { + (void)snpf(Namech, Namechl, + "vnode at %s; can't read stream head at %s", + print_kptr(na, (char *)NULL, 0), + print_kptr(sh, tbuf, sizeof(tbuf))); + enter_nm(Namech); + return (1); + } + /* + * If the stream head has pointer to a socket, read the socket structure + */ + if (!(sa = (KA_T)sd.sd_socket)) + return (0); + if (kread(sa, (char *)&ss, sizeof(ss))) { + (void)snpf( + Namech, Namechl, + "vnode at %s; stream head at %s; can't read socket at %s", + print_kptr(na, (char *)NULL, 0), + print_kptr(sh, tbuf, sizeof(tbuf)), + print_kptr(sa, tbuf1, sizeof(tbuf1))); + enter_nm(Namech); + return (1); + } + /* + * If the socket is bound to the PF_UNIX protocol family, process it as + * a UNIX socket. Otherwise, return and let the vnode be processed as a + * stream. + */ + if (ss.family != PF_UNIX) + return (0); + Lf->type = LSOF_FILE_UNIX; + if (Funix) + Lf->sf |= SELUNX; + Lf->is_stream = 0; + Lf->off_def = 1; + enter_dev_ch(print_kptr(sa, (char *)NULL, 0)); + /* + * Process the local address. + */ # if UNIXWAREV < 70103 - if ((la = find_unix_sockaddr_un((KA_T)sd.sd_socket))) { - if (Sfile && is_file_named(la->sun_path, 0)) - Lf->sf = SELNM; - } + if ((la = find_unix_sockaddr_un((KA_T)sd.sd_socket))) { + if (Sfile && is_file_named(la->sun_path, 0)) + Lf->sf = SELNM; + } # else /* UNIXWAREV>=70103 */ - if (((as = (KA_T)ss.local_addrsz) > 0) && (ka = (KA_T)ss.local_addr)) { - if (as > sizeof(la)) - as = (int)sizeof(la); - if (!kread(ctx, ka, (char *)&la, as)) { - la.sun_path[up] = '\0'; - if (la.sun_path[0]) { - las = 1; - if (Sfile && is_file_named(la.sun_path, 0)) - Lf->sf = SELNM; + if (((as = (KA_T)ss.local_addrsz) > 0) && (ka = (KA_T)ss.local_addr)) { + if (as > sizeof(la)) + as = (int)sizeof(la); + if (!kread(ka, (char *)&la, as)) { + la.sun_path[up] = '\0'; + if (la.sun_path[0]) { + las = 1; + if (Sfile && is_file_named(la.sun_path, 0)) + Lf->sf = SELNM; + } } } - } # endif /* UNIXWAREV<70103 */ - /* - * Process the remote address. - */ + /* + * Process the remote address. + */ # if UNIXWAREV < 70103 - if ((ra = find_unix_sockaddr_un((KA_T)ss.conn_ux))) { - if (Sfile && is_file_named(ra->sun_path, 0)) - Lf->sf = SELNM; - } + if ((ra = find_unix_sockaddr_un((KA_T)ss.conn_ux))) { + if (Sfile && is_file_named(ra->sun_path, 0)) + Lf->sf = SELNM; + } # else /* UNIXWAREV>=70103 */ - if (((as = (KA_T)ss.remote_addrsz) > 0) && (ka = (KA_T)ss.remote_addr)) { - if (as > sizeof(la)) - as = (int)sizeof(ra); - if (!kread(ctx, ka, (char *)&ra, as)) { - ra.sun_path[up] = '\0'; - if (ra.sun_path[0]) { - ras = 1; - if (Sfile && is_file_named(ra.sun_path, 0)) - Lf->sf = SELNM; + if (((as = (KA_T)ss.remote_addrsz) > 0) && + (ka = (KA_T)ss.remote_addr)) { + if (as > sizeof(la)) + as = (int)sizeof(ra); + if (!kread(ka, (char *)&ra, as)) { + ra.sun_path[up] = '\0'; + if (ra.sun_path[0]) { + ras = 1; + if (Sfile && is_file_named(ra.sun_path, 0)) + Lf->sf = SELNM; + } } } - } # endif /* UNIXWAREV<70103 */ - /* - * Start Namech[] with the service type, converted to a name, ala netstat. - */ - switch (ss.servtype) { - case T_COTS: - case T_COTS_ORD: - ty = "stream"; - break; - case T_CLTS: - ty = "dgram"; - break; - default: - ty = (char *)NULL; - } - if (ty) { - (void)snpf(Namech, Namechl, "%s", ty); - ty = ":"; - } else { - Namech[0] = '\0'; - ty = ""; - } - /* - * Add names to Namech[]. - */ + /* + * Start Namech[] with the service type, converted to a name, ala + * netstat. + */ + switch (ss.servtype) { + case T_COTS: + case T_COTS_ORD: + ty = "stream"; + break; + case T_CLTS: + ty = "dgram"; + break; + default: + ty = (char *)NULL; + } + if (ty) { + (void)snpf(Namech, Namechl, "%s", ty); + ty = ":"; + } else { + Namech[0] = '\0'; + ty = ""; + } + /* + * Add names to Namech[]. + */ # if UNIXWAREV < 70103 - if (la && la->sun_path[0]) { - ep = endnm(&sz); - (void)snpf(ep, sz, "%s%s", ty, la->sun_path); - } + if (la && la->sun_path[0]) { + ep = endnm(&sz); + (void)snpf(ep, sz, "%s%s", ty, la->sun_path); + } # else /* UNIXWAREV>=70103 */ - if (las) { - ep = endnm(&sz); - (void)snpf(ep, sz, "%s%s", ty, la.sun_path); - } + if (las) { + ep = endnm(&sz); + (void)snpf(ep, sz, "%s%s", ty, la.sun_path); + } # endif /* UNIXWAREV<70103 */ - ep = endnm(&sz); + ep = endnm(&sz); # if UNIXWAREV < 70103 - if (ra && ra->sun_path[0]) - (void)snpf(ep, sz, "->%s", ra->sun_path); + if (ra && ra->sun_path[0]) + (void)snpf(ep, sz, "->%s", ra->sun_path); # else /* UNIXWAREV>=70103 */ - if (ras) - (void)snpf(ep, sz, "->%s", ra.sun_path); + if (ras) + (void)snpf(ep, sz, "->%s", ra.sun_path); # endif /* UNIXWAREV<70103 */ - else if ((ka = (KA_T)ss.conn_ux)) - (void)snpf(ep, sz, "->%s", print_kptr(ka, (char *)NULL, 0)); - if (Namech[0]) - enter_nm(Namech); - return (1); -} + else if ((ka = (KA_T)ss.conn_ux)) + (void)snpf(ep, sz, "->%s", print_kptr(ka, (char *)NULL, 0)); + if (Namech[0]) + enter_nm(Namech); + return (1); + } # if UNIXWAREV < 70103 -/* - * find_unix_sockaddr_un() -- find UNIX socket address structure - * - */ - -static struct sockaddr_un *find_unix_sockaddr_un(ka) -KA_T ka; /* socket's kernel address */ -{ - static struct soreq *al = (struct soreq *)NULL; - static int alct = 0; - int i; - - if (!al) { - MALLOC_S alen, len; - char *ch = (char *)NULL; - int ct, pct; - struct strioctl ioc; - int sock = -1; - - if (alct < 0) - return ((struct sockaddr_un *)NULL); - /* - * If there has been no attempt to acquire the address list yet, - * do so. - * - * Get a SOCK_STREAM PF_UNIX socket descriptor and use ioctl() to - * send a stream message to acquire the list of PF_UNIX addresses. - */ - if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { + /* + * find_unix_sockaddr_un() -- find UNIX socket address structure + * + */ + static struct sockaddr_un *find_unix_sockaddr_un(ka) + KA_T ka; /* socket's kernel address */ + { + static struct soreq *al = (struct soreq *)NULL; + static int alct = 0; + int i; + + if (!al) { + MALLOC_S alen, len; + char *ch = (char *)NULL; + int ct, pct; + struct strioctl ioc; + int sock = -1; + + if (alct < 0) + return ((struct sockaddr_un *)NULL); /* - * Some error was detected. Return allocated resources and - * indicate that no further attempts need be made. + * If there has been no attempt to acquire the address list yet, + * do so. + * + * Get a SOCK_STREAM PF_UNIX socket descriptor and use ioctl() to + * send a stream message to acquire the list of PF_UNIX addresses. */ - - find_err_exit: - - alct = -1; - if (sock >= 0) - close(sock); - if (ch) - (void)free((FREE_P *)ch); - return ((struct sockaddr_un *)NULL); - } - /* - * Read the address list. Before starting, get an estimate of its - * size and add a small safety margin. - */ - if ((ct = ioctl(sock, SI_UX_COUNT, 0)) < 0) - goto find_err_exit; - ct += 32; - pct = 0; - do { - if (ct > pct) { + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { /* - * If the previously allocated space is insufficient, - * or if none has been allocated, allocate space. + * Some error was detected. Return allocated resources and + * indicate that no further attempts need be made. */ - alen = (MALLOC_S)(ct * sizeof(struct soreq)); + + find_err_exit: + + alct = -1; + if (sock >= 0) + close(sock); if (ch) - ch = (char *)realloc((MALLOC_P *)ch, alen); - else - ch = (char *)malloc(alen); - if (!ch) - goto find_err_exit; - pct = ct; + (void)free((FREE_P *)ch); + return ((struct sockaddr_un *)NULL); } /* - * Read the address list into the allocated space. + * Read the address list. Before starting, get an estimate of its + * size and add a small safety margin. */ - ioc.ic_cmd = SI_UX_LIST; - ioc.ic_dp = ch; - ioc.ic_len = (int)alen; - ioc.ic_timout = 0; - if ((ct = ioctl(sock, I_STR, &ioc)) < 0) + if ((ct = ioctl(sock, SI_UX_COUNT, 0)) < 0) goto find_err_exit; - } while (ct > pct); + ct += 32; + pct = 0; + do { + if (ct > pct) { + + /* + * If the previously allocated space is insufficient, + * or if none has been allocated, allocate space. + */ + alen = (MALLOC_S)(ct * sizeof(struct soreq)); + if (ch) + ch = (char *)realloc((MALLOC_P *)ch, alen); + else + ch = (char *)malloc(alen); + if (!ch) + goto find_err_exit; + pct = ct; + } + /* + * Read the address list into the allocated space. + */ + ioc.ic_cmd = SI_UX_LIST; + ioc.ic_dp = ch; + ioc.ic_len = (int)alen; + ioc.ic_timout = 0; + if ((ct = ioctl(sock, I_STR, &ioc)) < 0) + goto find_err_exit; + } while (ct > pct); + /* + * The list has been acquired. Free any excess space pre-allocated + * to it, then save its address. Close the stream socket. + */ + alct = ct; + if ((len = (MALLOC_S)(alct * sizeof(struct soreq))) < alen) { + if (!(ch = (char *)realloc((MALLOC_P *)ch, len))) + goto find_err_exit; + } + al = (struct soreq *)ch; + close(sock); + } /* - * The list has been acquired. Free any excess space pre-allocated to - * it, then save its address. Close the stream socket. + * Search a previously acquired address list, based on the supplied + * kernel socket address. If an entry is found, return a pointer to it, + * making sure the path it contains is terminated. */ - alct = ct; - if ((len = (MALLOC_S)(alct * sizeof(struct soreq))) < alen) { - if (!(ch = (char *)realloc((MALLOC_P *)ch, len))) - goto find_err_exit; + for (i = 0; i < alct; i++) { + if ((KA_T)al[i].so_addr == ka) + break; } - al = (struct soreq *)ch; - close(sock); - } - /* - * Search a previously acquired address list, based on the supplied kernel - * socket address. If an entry is found, return a pointer to it, making - * sure the path it contains is terminated. - */ - for (i = 0; i < alct; i++) { - if ((KA_T)al[i].so_addr == ka) - break; + if (i >= alct || !al[i].sockaddr.sun_path[0]) + return ((struct sockaddr_un *)NULL); + al[i].sockaddr.sun_path[(int)(sizeof(al[i].sockaddr.sun_path) - 1)] = + '\0'; + return (&al[i].sockaddr); } - if (i >= alct || !al[i].sockaddr.sun_path[0]) - return ((struct sockaddr_un *)NULL); - al[i].sockaddr.sun_path[(int)(sizeof(al[i].sockaddr.sun_path) - 1)] = '\0'; - return (&al[i].sockaddr); -} # endif /* UNIXWAREV<70103 */ #endif /* UNIXWAREV>=70101 */ diff --git a/lib/dialects/uw/dstore.c b/lib/dialects/uw/dstore.c index dc412e67..4bdaa750 100644 --- a/lib/dialects/uw/dstore.c +++ b/lib/dialects/uw/dstore.c @@ -40,7 +40,7 @@ int CloneMaj; /* clone major device number (see /* * Drive_Nl -- table to drive the building of Nl[] via build_Nl() - * (See lsof.h and misc.c.) + * (See common.h and misc.c.) */ struct drive_Nl Drive_Nl[] = {{"cdev", "cdevsw"}, /* UW < 7 */ diff --git a/lib/dialects/uw/machine.h b/lib/dialects/uw/machine.h index 868657d1..e336b531 100644 --- a/lib/dialects/uw/machine.h +++ b/lib/dialects/uw/machine.h @@ -134,7 +134,7 @@ /* * HASFSINO is defined for those dialects that have the file system - * inode element, fs_ino, in the lfile structure definition in lsof.h. + * inode element, fs_ino, in the lfile structure definition in common.h. */ # define HASFSINO 1 @@ -144,7 +144,7 @@ * * FSV_DEFAULT defines the default set of file structure values to list. * It defaults to zero (0), but may be made up of a combination of the - * FSV_* symbols from lsof.h. + * FSV_* symbols from common.h. * * HASNOFSADDR -- has no file structure address * HASNOFSFLAGS -- has no file structure flags @@ -330,14 +330,6 @@ /* #define HASPRIVNMCACHE */ -/* - * HASPRIVPRIPP is defined for dialects that have a private function for - * printing IP protocol names. When HASPRIVPRIPP isn't defined, the - * IP protocol name printing function defaults to printiprto(). - */ - -/* #define HASPRIVPRIPP 1 */ - /* * HASPROCFS is defined for those dialects that have a proc file system -- * usually /proc and usually in SYSV4 derivatives. @@ -494,7 +486,7 @@ /* * INODETYPE and INODEPSPEC define the internal node number type and its - * printf specification modifier. These need not be defined and lsof.h + * printf specification modifier. These need not be defined and common.h * can be allowed to define defaults. * * These are defined here, because they must be used in dlsof.h. @@ -534,6 +526,7 @@ /* #define USE_LIB_PRINT_TCPTPI 1 ptti.c */ # define USE_LIB_READDEV 1 /* rdev.c */ /* #define USE_LIB_READMNT 1 rmnt.c */ +/* #define USE_LIB_REGEX 1 regex.c */ /* #define USE_LIB_RNAM 1 rnam.c */ # define USE_LIB_RNCH 1 /* rnch.c */ /* #define USE_LIB_RNMH 1 rnmh.c */ diff --git a/lib/dvch.c b/lib/dvch.c index 11f2e4e9..9d5eea9c 100644 --- a/lib/dvch.c +++ b/lib/dvch.c @@ -112,12 +112,15 @@ static int rw_clone_sect(int m); void alloc_bdcache(struct lsof_context *ctx) { if (!(BDevtp = (struct l_dev *)calloc((MALLOC_S)BNdev, sizeof(struct l_dev)))) { - (void)fprintf(stderr, "%s: no space for block devices\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for block devices\n", Pn); Error(ctx); } if (!(BSdev = (struct l_dev **)malloc( (MALLOC_S)(sizeof(struct l_dev *) * BNdev)))) { - (void)fprintf(stderr, "%s: no space for block device pointers\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for block device pointers\n", + Pn); Error(ctx); } } @@ -130,12 +133,14 @@ void alloc_bdcache(struct lsof_context *ctx) { void alloc_dcache(struct lsof_context *ctx) { if (!(Devtp = (struct l_dev *)calloc((MALLOC_S)Ndev, sizeof(struct l_dev)))) { - (void)fprintf(stderr, "%s: no space for devices\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for devices\n", Pn); Error(ctx); } if (!(Sdev = (struct l_dev **)malloc( (MALLOC_S)(sizeof(struct l_dev *) * Ndev)))) { - (void)fprintf(stderr, "%s: no space for device pointers\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for device pointers\n", Pn); Error(ctx); } } @@ -204,9 +209,9 @@ static void clr_sect() { * crc(b, l, s) - compute a crc for a block of bytes */ -void crc(char *b, /* block address */ - int l, /* length */ - unsigned *s) /* sum */ +void crc(b, l, s) char *b; /* block address */ +int l; /* length */ +unsigned *s; /* sum */ { char *cp; /* character pointer */ char *lm; /* character limit pointer */ @@ -292,17 +297,21 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ if ((cp1 = getenv(HASENVDC)) && (l = strlen(cp1)) > 0 && !Setuidroot && Myuid && (rw == 1 || !Setgid)) { if (!(cp2 = mkstrcpy(cp1, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for device cache path: %s=", Pn, - HASENVDC); - safestrprt(cp1, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for device cache path: %s=", Pn, + HASENVDC); + safestrprt(cp1, ctx->err, 1); + } merr = 1; } else DCpath[1] = cp2; } else if (cp1 && l > 0) { - if (!Fwarn && wenv) { - (void)fprintf(stderr, "%s: WARNING: ignoring environment: %s=", Pn, + if (!Fwarn && wenv && ctx->err) { + (void)fprintf(ctx->err, + "%s: WARNING: ignoring environment: %s=", Pn, HASENVDC); - safestrprt(cp1, stderr, 1); + safestrprt(cp1, ctx->err, 1); } wenv = 0; } @@ -386,10 +395,11 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ case 'h': if (!p && !(p = getpwuid(Myuid))) { - if (!Fwarn) + if (!Fwarn && ctx->err) (void)fprintf( - stderr, "%s: WARNING: can't get home dir for UID: %d\n", - Pn, (int)Myuid); + ctx->err, + "%s: WARNING: can't get home dir for UID: %d\n", Pn, + (int)Myuid); ierr = 1; break; } @@ -421,9 +431,9 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ case 'l': case 'L': if (gethostname(hn, sizeof(hn) - 1) < 0) { - if (!Fwarn) + if (!Fwarn && ctx->err) (void)fprintf( - stderr, + ctx->err, "%s: WARNING: no gethostname for %%l or %%L: %s\n", Pn, strerror(errno)); ierr = 1; @@ -474,18 +484,18 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ ierr = 2; } else { if (cp2 && l > 0) { - if (!Fwarn && wpp) { - (void)fprintf(stderr, + if (!Fwarn && wpp && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: ignoring environment: %s", Pn, HASPERSDCPATH); - safestrprt(cp2, stderr, 1); + safestrprt(cp2, ctx->err, 1); } wpp = 0; } } # else /* !defined(HASPERSDCPATH) */ - if (!Fwarn && wpp) - (void)fprintf(stderr, + if (!Fwarn && wpp && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: HASPERSDCPATH disabled: %s\n", Pn, HASPERSDC); ierr = 1; @@ -501,9 +511,9 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ case 'u': if (!p && !(p = getpwuid(Myuid))) { - if (!Fwarn) + if (!Fwarn && ctx->err) (void)fprintf( - stderr, + ctx->err, "%s: WARNING: can't get login name for UID: %d\n", Pn, (int)Myuid); ierr = 1; @@ -531,8 +541,8 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ } break; default: - if (!Fwarn) - (void)fprintf(stderr, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: bad conversion (%%%c): %s\n", Pn, *cp1, HASPERSDC); ierr = 1; @@ -548,8 +558,8 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ * warning message. A type 2 intermediate error requires the * issuing of a buffer overlow warning message. */ - if (ierr == 2 && !Fwarn) - (void)fprintf(stderr, + if (ierr == 2 && !Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: device cache path too large: %s\n", Pn, HASPERSDC); i = 0; @@ -561,8 +571,11 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ */ if (i) { if (!(cp1 = mkstrcpy(buf, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for device cache path: ", Pn); - safestrprt(buf, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for device cache path: ", Pn); + safestrprt(buf, ctx->err, 1); + } merr = 1; } else DCpath[3] = cp1; @@ -573,8 +586,10 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ * Quit if there was a malloc() error. The appropriate error message * will have been issued to stderr. */ - if (merr) + if (merr) { Error(ctx); + return (-1); + } /* * Return the index of the first defined path. Since DCpath[] is arranged * in priority order, searching it beginning to end follows priority. @@ -584,9 +599,9 @@ int dcpath(struct lsof_context *ctx, int rw, /* read (1) or write (2) mode */ if (DCpath[i]) return (i); } - if (!Fwarn && npw) - (void)fprintf(stderr, "%s: WARNING: can't form any device cache path\n", - Pn); + if (!Fwarn && npw && ctx->err) + (void)fprintf(ctx->err, + "%s: WARNING: can't form any device cache path\n", Pn); return (-1); } @@ -616,11 +631,11 @@ int open_dcache(struct lsof_context *ctx, int m, /* mode: 1 = read; 2 = write */ /* * Check for access permission. */ - if (!is_readable(DCpath[DCpathX], 0)) { + if (!is_readable(ctx, DCpath[DCpathX], 0)) { if (DCpathX == 2 && errno == ENOENT) return (2); - if (!Fwarn) - (void)fprintf(stderr, ACCESSERRFMT, Pn, DCpath[DCpathX], + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, ACCESSERRFMT, Pn, DCpath[DCpathX], strerror(errno)); return (1); } @@ -632,15 +647,16 @@ int open_dcache(struct lsof_context *ctx, int m, /* mode: 1 = read; 2 = write */ return (1); cant_open: - (void)fprintf(stderr, "%s: WARNING: can't open %s: %s\n", Pn, - DCpath[DCpathX], strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't open %s: %s\n", Pn, + DCpath[DCpathX], strerror(errno)); return (1); } if (stat(DCpath[DCpathX], s) != 0) { cant_stat: - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: can't stat(%s): %s\n", Pn, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't stat(%s): %s\n", Pn, DCpath[DCpathX], strerror(errno)); close_exit: (void)close(DCfd); @@ -656,8 +672,8 @@ int open_dcache(struct lsof_context *ctx, int m, /* mode: 1 = read; 2 = write */ else if (!s->st_size) w = "is empty"; if (w) { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: %s %s.\n", Pn, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: %s %s.\n", Pn, DCpath[DCpathX], w); goto close_exit; } @@ -670,9 +686,10 @@ int open_dcache(struct lsof_context *ctx, int m, /* mode: 1 = read; 2 = write */ */ if (unlink(DCpath[DCpathX]) < 0) { if (errno != ENOENT) { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: can't unlink %s: %s\n", - Pn, DCpath[DCpathX], strerror(errno)); + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, + "%s: WARNING: can't unlink %s: %s\n", Pn, + DCpath[DCpathX], strerror(errno)); return (1); } } @@ -691,15 +708,15 @@ int open_dcache(struct lsof_context *ctx, int m, /* mode: 1 = read; 2 = write */ # endif /* defined(DVCH_CHOWN) */ { - if (!Fwarn) + if (!Fwarn && ctx->err) (void)fprintf( - stderr, + ctx->err, "%s: WARNING: can't change ownerships of %s: %s\n", Pn, DCpath[DCpathX], strerror(errno)); } } - if (!Fwarn && DCstate != 1 && !DCunsafe) - (void)fprintf(stderr, + if (!Fwarn && DCstate != 1 && !DCunsafe && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: created device cache file: %s\n", Pn, DCpath[DCpathX]); if (stat(DCpath[DCpathX], s) != 0) { @@ -712,7 +729,9 @@ int open_dcache(struct lsof_context *ctx, int m, /* mode: 1 = read; 2 = write */ /* * Oops! */ - (void)fprintf(stderr, "%s: internal error: open_dcache=%d\n", Pn, m); + if (ctx->err) + (void)fprintf(ctx->err, "%s: internal error: open_dcache=%d\n", Pn, + m); Error(ctx); } return (1); @@ -749,16 +768,16 @@ int read_dcache(struct lsof_context *ctx) { * DVCH_DEVPATH's mtime/ctime, ignore it, unless -Dr was specified. */ if (stat(DVCH_DEVPATH, &devsb) != 0) { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: can't stat(%s): %s\n", Pn, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't stat(%s): %s\n", Pn, DVCH_DEVPATH, strerror(errno)); } else { if (sb.st_mtime <= devsb.st_mtime || sb.st_ctime <= devsb.st_ctime) DCunsafe = 1; } if (!(DCfs = fdopen(DCfd, "r"))) { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: can't fdopen(%s)\n", Pn, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't fdopen(%s)\n", Pn, DCpath[DCpathX]); (void)close(DCfd); DCfd = -1; @@ -771,8 +790,8 @@ int read_dcache(struct lsof_context *ctx) { if (!fgets(buf, sizeof(buf), DCfs)) { cant_read: - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: can't fread %s: %s\n", Pn, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't fread %s: %s\n", Pn, DCpath[DCpathX], strerror(errno)); read_close: (void)fclose(DCfs); @@ -781,7 +800,7 @@ int read_dcache(struct lsof_context *ctx) { (void)clr_devtab(ctx); # if defined(DCACHE_CLR) - (void)DCACHE_CLR(ctx); + (void)DCACHE_CLR(); # endif /* defined(DCACHE_CLR) */ return (1); @@ -811,19 +830,19 @@ int read_dcache(struct lsof_context *ctx) { len = strlen(cbuf); (void)snpf(&cbuf[len], sizeof(cbuf) - len, ", dev=%lx\n", (long)DevDev); if (!strncmp(buf, cbuf, len) && (buf[len] == '\n')) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: no /dev device in %s: line ", + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: no /dev device in %s: line ", Pn, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } if (strcmp(buf, cbuf)) { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: bad section count line in %s: line ", Pn, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -837,11 +856,11 @@ int read_dcache(struct lsof_context *ctx) { if (strncmp(buf, "device section: ", len) != 0) { read_dhdr: - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: bad device section header in %s: line ", Pn, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -857,8 +876,8 @@ int read_dcache(struct lsof_context *ctx) { */ for (i = 0; i < Ndev; i++) { if (!fgets(buf, sizeof(buf), DCfs)) { - if (!Fwarn) - (void)fprintf(stderr, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't read device %d from %s\n", Pn, i + 1, DCpath[DCpathX]); goto read_close; @@ -868,10 +887,11 @@ int read_dcache(struct lsof_context *ctx) { * Convert hexadecimal device number. */ if (!(cp = x2dev(buf, &Devtp[i].rdev)) || *cp != ' ') { - if (!Fwarn) { - (void)fprintf(stderr, "%s: device %d: bad device in %s: line ", - Pn, i + 1, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, + "%s: device %d: bad device in %s: line ", Pn, + i + 1, DCpath[DCpathX]); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -880,12 +900,12 @@ int read_dcache(struct lsof_context *ctx) { */ for (cp++, Devtp[i].inode = (INODETYPE)0; *cp != ' '; cp++) { if (*cp < '0' || *cp > '9') { - if (!Fwarn) { + if (!Fwarn && ctx->err) { (void)fprintf( - stderr, + ctx->err, "%s: WARNING: device %d: bad inode # in %s: line ", Pn, i + 1, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -898,19 +918,22 @@ int read_dcache(struct lsof_context *ctx) { * pointer to Devtp[]. */ if ((len = strlen(++cp)) < 2 || *(cp + len - 1) != '\n') { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: device %d: bad path in %s: line ", Pn, i + 1, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } *(cp + len - 1) = '\0'; if (!(Devtp[i].name = mkstrcpy(cp, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: device %d: no space for path: line ", Pn, - i + 1); - safestrprt(buf, stderr, 1 + 4 + 8); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: device %d: no space for path: line ", Pn, + i + 1); + safestrprt(buf, ctx->err, 1 + 4 + 8); + } Error(ctx); } Devtp[i].v = 0; @@ -926,12 +949,12 @@ int read_dcache(struct lsof_context *ctx) { (void)crc(buf, strlen(buf), &DCcksum); len = strlen("block device section: "); if (strncmp(buf, "block device section: ", len) != 0) { - if (!Fwarn) { + if (!Fwarn && ctx->err) { (void)fprintf( - stderr, + ctx->err, "%s: WARNING: bad block device section header in %s: line ", Pn, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -946,9 +969,9 @@ int read_dcache(struct lsof_context *ctx) { */ for (i = 0; i < BNdev; i++) { if (!fgets(buf, sizeof(buf), DCfs)) { - if (!Fwarn) + if (!Fwarn && ctx->err) (void)fprintf( - stderr, + ctx->err, "%s: WARNING: can't read block device %d from %s\n", Pn, i + 1, DCpath[DCpathX]); goto read_close; @@ -958,11 +981,11 @@ int read_dcache(struct lsof_context *ctx) { * Convert hexadecimal device number. */ if (!(cp = x2dev(buf, &BDevtp[i].rdev)) || *cp != ' ') { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: block dev %d: bad device in %s: line ", Pn, i + 1, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -971,12 +994,12 @@ int read_dcache(struct lsof_context *ctx) { */ for (cp++, BDevtp[i].inode = (INODETYPE)0; *cp != ' '; cp++) { if (*cp < '0' || *cp > '9') { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: block dev %d: bad inode # " "in %s: line ", Pn, i + 1, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -989,21 +1012,23 @@ int read_dcache(struct lsof_context *ctx) { * pointer to BDevtp[]. */ if ((len = strlen(++cp)) < 2 || *(cp + len - 1) != '\n') { - if (!Fwarn) { + if (!Fwarn && ctx->err) { (void)fprintf( - stderr, + ctx->err, "%s: WARNING: block dev %d: bad path in %s: line", Pn, i + 1, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } *(cp + len - 1) = '\0'; if (!(BDevtp[i].name = mkstrcpy(cp, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, - "%s: block dev %d: no space for path: line", Pn, - i + 1); - safestrprt(buf, stderr, 1 + 4 + 8); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: block dev %d: no space for path: line", + Pn, i + 1); + safestrprt(buf, ctx->err, 1 + 4 + 8); + } Error(ctx); } BDevtp[i].v = 0; @@ -1033,19 +1058,19 @@ int read_dcache(struct lsof_context *ctx) { */ (void)snpf(cbuf, sizeof(cbuf), "CRC section: %x\n", DCcksum); if (!fgets(buf, sizeof(buf), DCfs) || strcmp(buf, cbuf) != 0) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: WARNING: bad CRC section in %s: line ", + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: bad CRC section in %s: line ", Pn, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } if (fgets(buf, sizeof(buf), DCfs)) { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: WARNING: data follows CRC section in %s: line ", Pn, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } goto read_close; } @@ -1063,8 +1088,8 @@ int read_dcache(struct lsof_context *ctx) { # endif /* defined(DVCH_EXPDEV) */ || sb.st_ino != Devtp[i].inode) { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: device cache mismatch: %s\n", + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: device cache mismatch: %s\n", Pn, Devtp[i].name); goto read_close; } @@ -1082,8 +1107,8 @@ int read_dcache(struct lsof_context *ctx) { * rw_clone_sect() - read/write the device cache file clone section */ -static int rw_clone_sect(struct lsof_context *ctx, - int m) /* mode: 1 = read; 2 = write */ +static int rw_clone_sect(m) +int m; /* mode: 1 = read; 2 = write */ { char buf[MAXPATHLEN * 2], *cp, *cp1; struct clone *c; @@ -1098,11 +1123,11 @@ static int rw_clone_sect(struct lsof_context *ctx, if (!fgets(buf, sizeof(buf), DCfs)) { bad_clone_sect: - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: bad clone section header in %s: line ", Pn, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } return (1); } @@ -1117,10 +1142,10 @@ static int rw_clone_sect(struct lsof_context *ctx, */ for (i = 0; i < n; i++) { if (fgets(buf, sizeof(buf), DCfs) == NULL) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: no %d clone line in %s: line ", + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: no %d clone line in %s: line ", Pn, i + 1, DCpath[DCpathX]); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } return (1); } @@ -1132,12 +1157,12 @@ static int rw_clone_sect(struct lsof_context *ctx, if (*cp < '0' || *cp > '9') { bad_clone_index: - if (!Fwarn) { + if (!Fwarn && ctx->err) { (void)fprintf( - stderr, + ctx->err, "%s: clone %d: bad cached device index: line ", Pn, i + 1); - safestrprt(buf, stderr, 1 + 4 + 8); + safestrprt(buf, ctx->err, 1 + 4 + 8); } return (1); } @@ -1151,10 +1176,13 @@ static int rw_clone_sect(struct lsof_context *ctx, * Allocate and complete a clone structure. */ if (!(c = (struct clone *)malloc(sizeof(struct clone)))) { - (void)fprintf(stderr, - "%s: clone %d: no space for cached clone: line ", - Pn, i + 1); - safestrprt(buf, stderr, 1 + 4 + 8); + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: clone %d: no space for cached clone: line ", Pn, + i + 1); + safestrprt(buf, ctx->err, 1 + 4 + 8); + } Error(ctx); } c->dx = j; @@ -1170,7 +1198,7 @@ static int rw_clone_sect(struct lsof_context *ctx, for (c = Clone, n = 0; c; c = c->next, n++) ; (void)snpf(buf, sizeof(buf), "clone section: %d\n", n); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); /* * Write the clone section lines. @@ -1181,10 +1209,10 @@ static int rw_clone_sect(struct lsof_context *ctx, break; } if (j >= Ndev) { - if (!Fwarn) { - (void)fprintf(stderr, + if (!Fwarn && ctx->err) { + (void)fprintf(ctx->err, "%s: can't make index for clone: ", Pn); - safestrprt(dp->name, stderr, 1); + safestrprt(dp->name, ctx->err, 1); } (void)unlink(DCpath[DCpathX]); (void)close(DCfd); @@ -1192,7 +1220,7 @@ static int rw_clone_sect(struct lsof_context *ctx, return (1); } (void)snpf(buf, sizeof(buf), "%d %s\n", j, dp->name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); } return (0); @@ -1200,7 +1228,9 @@ static int rw_clone_sect(struct lsof_context *ctx, /* * A shouldn't-happen case: mode neither 1 nor 2. */ - (void)fprintf(stderr, "%s: internal rw_clone_sect error: %d\n", Pn, m); + if (ctx->err) + (void)fprintf(ctx->err, "%s: internal rw_clone_sect error: %d\n", Pn, + m); Error(ctx); return (1); /* This useless return(1) keeps some * compilers happy. */ @@ -1243,19 +1273,19 @@ void write_dcache(struct lsof_context *ctx) { (long)DevDev); (void)crcbld(); DCcksum = 0; - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; /* * Write the device section from the contents of Sdev[] and Devtp[]. */ (void)snpf(buf, sizeof(buf), "device section: %d\n", Ndev); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; for (i = 0; i < Ndev; i++) { dp = Sdev[i]; (void)snpf(buf, sizeof(buf), "%lx %ld %s\n", (long)dp->rdev, (long)dp->inode, dp->name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; } @@ -1264,14 +1294,14 @@ void write_dcache(struct lsof_context *ctx) { * Write the block device section from the contents of BSdev[] and BDevtp[]. */ (void)snpf(buf, sizeof(buf), "block device section: %d\n", BNdev); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; if (BNdev) { for (i = 0; i < BNdev; i++) { dp = BSdev[i]; (void)snpf(buf, sizeof(buf), "%lx %ld %s\n", (long)dp->rdev, (long)dp->inode, dp->name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; } } @@ -1297,11 +1327,11 @@ void write_dcache(struct lsof_context *ctx) { * Write the CRC section and close the file. */ (void)snpf(buf, sizeof(buf), "CRC section: %x\n", DCcksum); - if (wr2DCfd(buf, (unsigned *)NULL)) + if (wr2DCfd(ctx, buf, (unsigned *)NULL)) return; if (close(DCfd) != 0) { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: can't close %s: %s\n", Pn, + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't close %s: %s\n", Pn, DCpath[DCpathX], strerror(errno)); (void)unlink(DCpath[DCpathX]); DCfd = -1; @@ -1322,8 +1352,8 @@ void write_dcache(struct lsof_context *ctx) { * wr2DCfd() - write to the DCfd file descriptor */ -int wr2DCfd(char *b, /* buffer */ - unsigned *c) /* checksum receiver */ +int wr2DCfd(struct lsof_context *ctx, char *b, /* buffer */ + unsigned *c) /* checksum receiver */ { int bl, bw; @@ -1332,8 +1362,8 @@ int wr2DCfd(char *b, /* buffer */ (void)crc(b, bl, c); while (bl > 0) { if ((bw = write(DCfd, b, bl)) < 0) { - if (!Fwarn) - (void)fprintf(stderr, "%s: WARNING: can't write to %s: %s\n", + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: can't write to %s: %s\n", Pn, DCpath[DCpathX], strerror(errno)); (void)unlink(DCpath[DCpathX]); (void)close(DCfd); @@ -1345,7 +1375,4 @@ int wr2DCfd(char *b, /* buffer */ } return (0); } -#else /* !defined(HASDCACHE) */ -char dvch_d1[] = "d"; -char *dvch_d2 = dvch_d1; #endif /* defined(HASDCACHE) */ diff --git a/lib/fino.c b/lib/fino.c index 693fba38..78af05ef 100644 --- a/lib/fino.c +++ b/lib/fino.c @@ -38,12 +38,8 @@ #include "common.h" #include "machine.h" - #if defined(HASBLKDEV) || defined(USE_LIB_FIND_CH_INO) -#else /* !defined(HASBLKDEV) && !defined(USE_LIB_FIND_CH_INO) */ -char fino_d1[] = "d"; -char *fino_d2 = fino_d1; #endif /* defined(HASBLKDEV) || defined(USE_LIB_FIND_CH_INO) */ #if defined(HASBLKDEV) @@ -81,8 +77,7 @@ void find_bl_ino(struct lsof_context *ctx) { # endif /* defined(HASDCACHE) */ Lf->inode = BSdev[mid]->inode; - if (Lf->inp_ty == 0) - Lf->inp_ty = 1; + Lf->inode_def = 1; return; } } @@ -124,8 +119,6 @@ void find_ch_ino(struct lsof_context *ctx) { # endif /* defined(HASDCACHE) */ Lf->inode = Sdev[mid]->inode; - if (Lf->inp_ty == 0) - Lf->inp_ty = 1; return; } } diff --git a/lib/isfn.c b/lib/isfn.c index 2dc2c3a2..aa19417a 100644 --- a/lib/isfn.c +++ b/lib/isfn.c @@ -60,11 +60,6 @@ * Local structures */ -struct hsfile { - struct sfile *s; /* the Sfile table address */ - struct hsfile *next; /* the next hash bucket entry */ -}; - /* * Local static variables */ @@ -75,19 +70,6 @@ static struct hsfile *HbyCd = /* hash by clone buckets */ static int HbyCdCt = 0; /* HbyCd entry count */ # endif /* defined(HAVECLONEMAJ) */ -static struct hsfile *HbyFdi = /* hash by file (dev,ino) buckets */ - (struct hsfile *)NULL; -static int HbyFdiCt = 0; /* HbyFdi entry count */ -static struct hsfile *HbyFrd = /* hash by file raw device buckets */ - (struct hsfile *)NULL; -static int HbyFrdCt = 0; /* HbyFrd entry count */ -static struct hsfile *HbyFsd = /* hash by file system buckets */ - (struct hsfile *)NULL; -static int HbyFsdCt = 0; /* HbyFsd entry count */ -static struct hsfile *HbyNm = /* hash by name buckets */ - (struct hsfile *)NULL; -static int HbyNmCt = 0; /* HbyNm entry count */ - /* * Local definitions */ @@ -152,9 +134,11 @@ void hashSfile(struct lsof_context *ctx) { if (HAVECLONEMAJ) { if (!(HbyCd = (struct hsfile *)calloc((MALLOC_S)SFCDHASH, sizeof(struct hsfile)))) { - (void)fprintf( - stderr, "%s: can't allocate space for %d clone hash buckets\n", - Pn, SFCDHASH); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate space for %d clone hash buckets\n", Pn, + SFCDHASH); Error(ctx); } sfplm++; @@ -163,30 +147,36 @@ void hashSfile(struct lsof_context *ctx) { if (!(HbyFdi = (struct hsfile *)calloc((MALLOC_S)SFDIHASH, sizeof(struct hsfile)))) { - (void)fprintf( - stderr, "%s: can't allocate space for %d (dev,ino) hash buckets\n", - Pn, SFDIHASH); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate space for %d (dev,ino) hash buckets\n", Pn, + SFDIHASH); Error(ctx); } if (!(HbyFrd = (struct hsfile *)calloc((MALLOC_S)SFRDHASH, sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate space for %d rdev hash buckets\n", Pn, - SFRDHASH); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate space for %d rdev hash buckets\n", + Pn, SFRDHASH); Error(ctx); } if (!(HbyFsd = (struct hsfile *)calloc((MALLOC_S)SFFSHASH, sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate space for %d file sys hash buckets\n", - Pn, SFFSHASH); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate space for %d file sys hash buckets\n", Pn, + SFFSHASH); Error(ctx); } if (!(HbyNm = (struct hsfile *)calloc((MALLOC_S)SFNMHASH, sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate space for %d name hash buckets\n", Pn, - SFNMHASH); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't allocate space for %d name hash buckets\n", + Pn, SFNMHASH); Error(ctx); } hs++; @@ -242,9 +232,11 @@ void hashSfile(struct lsof_context *ctx) { } else { if (!(sn = (struct hsfile *)malloc( (MALLOC_S)sizeof(struct hsfile)))) { - (void)fprintf(stderr, - "%s: can't allocate hsfile bucket for: %s\n", - Pn, s->aname); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate hsfile bucket for: %s\n", Pn, + s->aname); Error(ctx); } sn->s = s; @@ -260,7 +252,7 @@ void hashSfile(struct lsof_context *ctx) { */ int is_file_named(struct lsof_context *ctx, - char *p, /* path name; NULL = search by device + char *p, /* path name, NULL = search by device * and inode (from *Lf) */ int cd) /* character or block type file -- * VCHR or VBLK vnode, or S_IFCHR @@ -303,7 +295,7 @@ int is_file_named(struct lsof_context *ctx, /* * Check for a regular file. */ - if (!f && HbyFdiCt && Lf->dev_def && (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + if (!f && HbyFdiCt && Lf->dev_def && Lf->inode_def) { for (sh = &HbyFdi[SFHASHDEVINO(GET_MAJ_DEV(Lf->dev), GET_MIN_DEV(Lf->dev), Lf->inode, SFDIHASH)]; @@ -331,7 +323,7 @@ int is_file_named(struct lsof_context *ctx, * Check for a character or block device match. */ if (!f && HbyFrdCt && cd && Lf->dev_def && (Lf->dev == DevDev) && - Lf->rdev_def && (Lf->inp_ty == 1 || Lf->inp_ty == 3)) { + Lf->rdev_def && Lf->inode_def) { for (sh = &HbyFrd[SFHASHRDEVI( GET_MAJ_DEV(Lf->dev), GET_MIN_DEV(Lf->dev), GET_MAJ_DEV(Lf->rdev), GET_MIN_DEV(Lf->rdev), Lf->inode, @@ -376,7 +368,4 @@ int is_file_named(struct lsof_context *ctx, s->f = 1; return (1); } -#else /* !defined(USE_LIB_IS_FILE_NAMED) */ -char isfn_d1[] = "d"; -char *isfn_d2 = isfn_d1; #endif /* defined(USE_LIB_IS_FILE_NAMED) */ diff --git a/lib/lkud.c b/lib/lkud.c index 221b7046..bc9a5b14 100644 --- a/lib/lkud.c +++ b/lib/lkud.c @@ -38,12 +38,8 @@ #include "common.h" #include "machine.h" - #if defined(HASBLKDEV) || defined(USE_LIB_LKUPDEV) -#else /* !defined(HASBLKDEV) && !defined(USE_LIB_LKUPDEV) */ -char lkud_d1[] = "d"; -char *lkud_d2 = lkud_d1; #endif /* defined(HASBLKDEV) || defined(USE_LIB_LKUPDEV) */ #if defined(HASBLKDEV) @@ -64,13 +60,14 @@ struct l_dev *lkupbdev(struct lsof_context *ctx, int low, hi, mid; struct l_dev *dp; int ty = 0; + int inode_def = 0; if (*dev != DevDev) return ((struct l_dev *)NULL); readdev(ctx, 0); if (i) { inode = Lf->inode; - ty = Lf->inp_ty; + inode_def = Lf->inode_def; } /* * Search block device table for match. @@ -92,7 +89,7 @@ struct l_dev *lkupbdev(struct lsof_context *ctx, else if (*rdev > dp->rdev) low = mid + 1; else { - if ((i == 0) || (ty != 1) || (inode == dp->inode)) { + if ((i == 0) || !inode_def || (inode == dp->inode)) { # if defined(HASDCACHE) if (DCunsafe && !dp->v && !vfy_dev(ctx, dp)) @@ -137,13 +134,14 @@ struct l_dev *lkupdev(struct lsof_context *ctx, int low, hi, mid; struct l_dev *dp; int ty = 0; + int inode_def = 0; if (*dev != DevDev) return ((struct l_dev *)NULL); readdev(ctx, 0); if (i) { inode = Lf->inode; - ty = Lf->inp_ty; + inode_def = Lf->inode_def; } /* * Search device table for match. @@ -165,7 +163,7 @@ struct l_dev *lkupdev(struct lsof_context *ctx, else if (*rdev > dp->rdev) low = mid + 1; else { - if ((i == 0) || (ty != 1) || (inode == dp->inode)) { + if ((i == 0) || !inode_def || (inode == dp->inode)) { # if defined(HASDCACHE) if (DCunsafe && !dp->v && !vfy_dev(ctx, dp)) diff --git a/lib/lsof.c b/lib/lsof.c index e69de29b..cc67e8e7 100644 --- a/lib/lsof.c +++ b/lib/lsof.c @@ -0,0 +1,2833 @@ +/* + * lsof.c -- implement lsof_* functions() for liblsof + */ + +/* + * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by Victor A. Abell + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#ifdef AUTOTOOLS +# include "config.h" +#endif +#include "common.h" +#include "lsof.h" +#include + +#ifndef API_EXPORT +# define API_EXPORT +#endif + +API_EXPORT +int lsof_get_api_version() { return LSOF_API_VERSION; } + +#ifdef AUTOTOOLS +API_EXPORT +char *lsof_get_library_version() { return PACKAGE_VERSION; } +#endif + +API_EXPORT +struct lsof_context *lsof_new() { + int se1, se2, ss = 0, ad; + struct stat sb; + struct lsof_context *ctx = + (struct lsof_context *)malloc(sizeof(struct lsof_context)); + if (ctx) { + // Initialization + memset(ctx, 0, sizeof(struct lsof_context)); + if (!(Namech = (char *)malloc(MAXPATHLEN + 1))) { + free(ctx); + return NULL; + } + Namechl = (size_t)(MAXPATHLEN + 1); + /* all processes are selected (default) */ + AllProc = 1; + /* Readlink() and stat() timeout (seconds) */ + TmLimit = TMLIMIT; + /* Fdl[] type: -1 == none */ + FdlTy = -1; + /* get pid */ + Mypid = getpid(); + /* Initialize selection flags */ + SelAll = SELALL; + SelProc = SELPROC; + /* device cache path index: -1 = path not defined */ + ctx->dev_cache_path_index = -1; + ctx->dev_cache_fd = -1; + /* device cache state: + * 3 = update; read and rebuild if + * necessary (-Du[path]) */ + ctx->dev_cache_state = 3; + /* enable name cache by default */ + Fncache = 1; + +#if defined(WARNINGSTATE) + Fwarn = 1; /* +|-w option status */ +#else /* !defined(WARNINGSTATE) */ + Fwarn = 0; /* +|-w option status */ +#endif /* defined(WARNINGSTATE) */ + + /* + * Get the device for DEVDEV_PATH. + */ + if (stat(DEVDEV_PATH, &sb)) { + se1 = errno; + if ((ad = strcmp(DEVDEV_PATH, "/dev"))) { + if ((ss = stat("/dev", &sb))) + se2 = errno; + else { + DevDev = sb.st_dev; + se2 = 0; + } + } else { + se2 = 0; + ss = 1; + } + if (ss) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't stat(%s): %s\n", Pn, + DEVDEV_PATH, strerror(se1)); + if (ad && ctx->err) { + (void)fprintf(ctx->err, "%s: can't stat(/dev): %s\n", Pn, + strerror(se2)); + } + Error(ctx); + } + } else { + DevDev = sb.st_dev; + } + } + return ctx; +} + +API_EXPORT +enum lsof_error lsof_freeze(struct lsof_context *ctx) { + enum lsof_error ret = LSOF_SUCCESS; + if (ctx->frozen) { + ret = LSOF_ERROR_INVALID_ARGUMENT; + } else { + if (Selflags == 0) { + Selflags = SelAll; + } else { + if ((Selflags & (SELNA | SELNET)) != 0 && + (Selflags & ~(SELNA | SELNET)) == 0) + Selinet = 1; + AllProc = 0; + } + + initialize(ctx); + hashSfile(ctx); + ctx->frozen = 1; + } + return ret; +} + +static struct sockaddr_storage fill_sockaddr(struct linaddr li) { + struct sockaddr_storage ret; + struct sockaddr_in *in = (struct sockaddr_in *)&ret; + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)&ret; + + memset(&ret, 0, sizeof(ret)); + if (li.af == AF_INET) { + in->sin_family = AF_INET; + in->sin_port = htons(li.p); + in->sin_addr = li.ia.a4; + } else if (li.af == AF_INET6) { + in6->sin6_family = AF_INET6; + in6->sin6_port = htons(li.p); + in6->sin6_addr = li.ia.a6; + } + return ret; +} + +API_EXPORT +enum lsof_error lsof_gather(struct lsof_context *ctx, + struct lsof_result **result) { + enum lsof_error ret = LSOF_SUCCESS; + int pi = 0; /* proc index */ + int upi = 0; /* user proc index */ + struct lsof_process *p; + struct lproc *lp; + int fi = 0; /* file index */ + size_t num_files; + struct lsof_file *f; + struct lfile *lf; + struct lfile *lf_next; + size_t sel_procs = 0; + char *cp; + char buf[64]; + int s; + struct str_lst *str; + struct sfile *sfp; + struct nwad *np, *npn; +#if defined(HASPROCFS) + struct procfsid *pfi; +#endif /* defined(HASPROCFS) */ +#if defined(HASZONES) + znhash_t *zp; +#endif /* defined(HASZONES) */ +#if defined(HASSELINUX) + cntxlist_t *cntxp; +#endif /* defined(HASSELINUX) */ + int pass; + int i; + struct lsof_selection *selections; + size_t num_selections = 0; + + if (!result) { + ret = LSOF_ERROR_INVALID_ARGUMENT; + return ret; + } else if (!ctx->frozen) { + ret = LSOF_ERROR_INVALID_ARGUMENT; + return ret; + } + + gather_proc_info(ctx); + + /* Cleanup orphaned cur_file, if any*/ + if (ctx->cur_file) { + clean_lfile(ctx, ctx->cur_file); + CLEAN(ctx->cur_file); + } + + /* Count selected procs */ + for (pi = 0; pi < ctx->procs_size; pi++) { + lp = &ctx->procs[pi]; + if (lp->pss) { + sel_procs++; + } + } + + /* Fill result */ + struct lsof_result *res = + (struct lsof_result *)malloc(sizeof(struct lsof_result)); + struct lsof_process *user_procs = + (struct lsof_process *)malloc(sizeof(struct lsof_process) * sel_procs); + memset(user_procs, 0, sizeof(struct lsof_process) * sel_procs); + + for (pi = 0, upi = 0; pi < ctx->procs_size; pi++) { + /* Copy fields from lproc */ + lp = &ctx->procs[pi]; + if (lp->pss) { + /* selected process */ + p = &user_procs[upi++]; + + p->command = lp->cmd; + lp->cmd = NULL; + p->pid = lp->pid; + +#if defined(HASTASKS) + p->tid = lp->tid; + p->task_cmd = lp->tcmd; + lp->tcmd = NULL; +#endif +#if defined(HASZONES) + p->solaris_zone = lp->zn; + lp->zn = NULL; +#endif +#if defined(HASSELINUX) + p->selinux_context = lp->cntx; + lp->cntx = NULL; +#endif + + p->pgid = lp->pgid; + p->ppid = lp->ppid; + p->uid = lp->uid; + + /* Compute number of files in the linked list */ + num_files = 0; + for (lf = lp->file; lf; lf = lf->next) { + if (!is_file_sel(ctx, lp, lf)) + continue; + num_files++; + } + + p->files = (struct lsof_file *)malloc(sizeof(struct lsof_file) * + num_files); + memset(p->files, 0, sizeof(struct lsof_file) * num_files); + p->num_files = num_files; + for (fi = 0, lf = lp->file; lf; lf = lf_next) { + if (is_file_sel(ctx, lp, lf)) { + /* Copy fields from lfile */ + f = &p->files[fi++]; + f->flags = 0; + + /* FD column */ + f->fd_type = lf->fd_type; + f->fd_num = lf->fd_num; + f->access = lf->access; + f->lock = lf->lock; + + /* TYPE column */ + f->file_type = lf->type; + f->unknown_file_type_number = lf->unknown_file_type_number; + + /* DEVICE column */ + f->dev = lf->dev; + if (lf->dev_def) { + f->flags |= LSOF_FILE_FLAG_DEV_VALID; + } + f->rdev = lf->rdev; + if (lf->rdev_def) { + f->flags |= LSOF_FILE_FLAG_RDEV_VALID; + } + + /* SIZE, SIZE/OFF, OFFSET column */ + f->size = lf->sz; + if (lf->sz_def) { + f->flags |= LSOF_FILE_FLAG_SIZE_VALID; + } + f->offset = lf->off; + if (lf->off_def) { + f->flags |= LSOF_FILE_FLAG_OFFSET_VALID; + } + + /* NLINK column */ + f->num_links = lf->nlink; + if (lf->nlink_def) { + f->flags |= LSOF_FILE_FLAG_NUM_LINKS_VALID; + } + + /* NODE column */ + f->inode = lf->inode; + if (lf->inode_def) { + f->flags |= LSOF_FILE_FLAG_INODE_VALID; + } + f->protocol = lf->iproto; + f->unknown_proto_number = lf->unknown_proto_number; + + /* NAME column */ + f->name = lf->nm; + lf->nm = NULL; + + /* network address */ + f->net_local = fill_sockaddr(lf->li[0]); + f->net_foreign = fill_sockaddr(lf->li[1]); + + /* tcp/tpi state */ + if (lf->lts.type != -1) { + f->flags |= LSOF_FILE_FLAG_TCP_TPI_VALID; + if (lf->lts.type == 0) { + /* TCP */ + if (!TcpSt) + (void)build_IPstates(ctx); + if ((s = lf->lts.state.i + TcpStOff) < 0 || + s >= TcpNstates) { + (void)snpf(buf, sizeof(buf), + "UNKNOWN_TCP_STATE_%d", + lf->lts.state.i); + cp = buf; + } else + cp = TcpSt[s]; + } else { + /* TPI */ + if (!UdpSt) + (void)build_IPstates(ctx); + if ((s = lf->lts.state.i + UdpStOff) < 0 || + s >= UdpNstates) { + (void)snpf(buf, sizeof(buf), + "UNKNOWN_TPI_STATE_%d", + lf->lts.state.i); + cp = buf; + } else + cp = UdpSt[s]; + } + f->tcp_tpi.state = mkstrcpy(cp, NULL); + +#if defined(HASTCPTPIQ) + if (lf->lts.rqs) { + f->tcp_tpi.recv_queue_len = lf->lts.rq; + f->tcp_tpi.flags |= + LSOF_TCP_TPI_FLAG_RECV_QUEUE_LEN_VALID; + } + if (lf->lts.sqs) { + f->tcp_tpi.send_queue_len = lf->lts.sq; + f->tcp_tpi.flags |= + LSOF_TCP_TPI_FLAG_SEND_QUEUE_LEN_VALID; + } +#endif /* defined(HASTCPTPIQ) */ + } + } + lf_next = lf->next; + } + } + + for (lf = lp->file; lf; lf = lf_next) { + /* free lf */ + lf_next = lf->next; + CLEAN(lf->nma); + CLEAN(lf->dev_ch); +#if defined(CLRLFILEADD) + CLRLFILEADD(lf) +#endif /* defined(CLRLFILEADD) */ + CLEAN(lf); + } + lp->file = NULL; + + /* skip and free */ + CLEAN(lp->cmd); +#if defined(HASTASKS) + CLEAN(lp->tcmd); +#endif +#if defined(HASSELINUX) + CLEAN(lp->cntx); +#endif /* defined(HASSELINUX) */ + continue; + } + + /* Cleanup */ + CLEAN(ctx->procs); + ctx->cur_proc = NULL; + + res->processes = user_procs; + res->num_processes = sel_procs; + + ctx->procs_size = ctx->procs_cap = 0; + ctx->cur_file = ctx->prev_file = NULL; + + /* Collect selection result */ + for (pass = 0; pass < 2; pass++) { + num_selections = 0; + + /* command */ + for (str = Cmdl; str; str = str->next) { + if (pass) { + selections[num_selections].type = LSOF_SELECTION_COMMAND; + selections[num_selections].found = str->f; + selections[num_selections].string = str->str; + } + num_selections++; + } + + /* command regex */ + for (i = 0; i < NCmdRxU; i++) { + if (pass) { + selections[num_selections].type = LSOF_SELECTION_COMMAND_REGEX; + selections[num_selections].found = CmdRx[i].mc > 0; + selections[num_selections].string = CmdRx[i].exp; + } + num_selections++; + } + + /* select file or file system */ + for (sfp = Sfile; sfp; sfp = sfp->next) { + if (pass) { + selections[num_selections].type = + sfp->type ? LSOF_SELECTION_PATH + : LSOF_SELECTION_FILE_SYSTEM; + selections[num_selections].found = sfp->f; + selections[num_selections].string = sfp->aname; + } + num_selections++; + } + +#if defined(HASPROCFS) + /* procfs */ + if (Procsrch) { + if (pass) { + selections[num_selections].type = LSOF_SELECTION_FILE_SYSTEM; + selections[num_selections].found = Procfind; + selections[num_selections].string = + Mtprocfs ? Mtprocfs->dir : HASPROCFS; + } + num_selections++; + } + + for (pfi = Procfsid; pfi; pfi = pfi->next) { + if (pass) { + selections[num_selections].type = LSOF_SELECTION_PATH; + selections[num_selections].found = pfi->f; + selections[num_selections].string = pfi->nm; + } + num_selections++; + } +#endif /* defined(HASPROCFS) */ + + /* network address */ + for (np = Nwad; np;) { + int found = np->f; + if (!(cp = np->arg)) { + np = np->next; + continue; + } + for (npn = np->next; npn; npn = npn->next) { + if (!npn->arg) + continue; + if (!strcmp(cp, npn->arg)) { + /* Found duplicate specification */ + found |= npn->f; + } else { + break; + } + } + + if (pass) { + selections[num_selections].type = + LSOF_SELECTION_NETWORK_ADDRESS; + selections[num_selections].found = found; + selections[num_selections].string = np->arg; + } + num_selections++; + np = npn; + } + + /* ip protocol */ + if (Fnet) { + if (pass) { + selections[num_selections].type = LSOF_SELECTION_INTERNET; + selections[num_selections].found = Fnet == 2; + } + num_selections++; + } + +#if defined(HASTCPUDPSTATE) + /* tcp/tpi protocol state */ + if (TcpStIn) { + for (i = 0; i < TcpNstates; i++) { + if (TcpStI[i]) { + if (pass) { + selections[num_selections].type = + LSOF_SELECTION_PROTOCOL_STATE; + selections[num_selections].found = TcpStI[i] == 2; + selections[num_selections].string = TcpSt[i]; + } + num_selections++; + } + } + } + if (UdpStIn) { + for (i = 0; i < UdpNstates; i++) { + if (UdpStI[i]) { + if (pass) { + selections[num_selections].type = + LSOF_SELECTION_PROTOCOL_STATE; + selections[num_selections].found = UdpStI[i] == 2; + selections[num_selections].string = UdpSt[i]; + } + num_selections++; + } + } + } +#endif /* defined(HASTCPUDPSTATE) */ + + /* nfs */ + if (Fnfs) { + if (pass) { + selections[num_selections].type = LSOF_SELECTION_NFS; + selections[num_selections].found = Fnfs == 2; + } + num_selections++; + } + + /* pid */ + for (i = 0; i < Npid; i++) { + if (Spid[i].x) + continue; + if (pass) { + selections[num_selections].type = LSOF_SELECTION_PID; + selections[num_selections].found = Spid[i].f; + selections[num_selections].integer = Spid[i].i; + } + num_selections++; + } + + /* pgid */ + for (i = 0; i < Npgid; i++) { + if (Spgid[i].x) + continue; + if (pass) { + selections[num_selections].type = LSOF_SELECTION_PGID; + selections[num_selections].found = Spgid[i].f; + selections[num_selections].integer = Spgid[i].i; + } + num_selections++; + } + + /* uid */ + for (i = 0; i < Nuid; i++) { + if (Suid[i].excl) + continue; + if (pass) { + selections[num_selections].type = LSOF_SELECTION_UID; + selections[num_selections].found = Suid[i].f; + selections[num_selections].string = Suid[i].lnm; + selections[num_selections].integer = Suid[i].uid; + } + num_selections++; + } + +#if defined(HASTASKS) + /* tasks */ + if (Ftask) { + if (pass) { + selections[num_selections].type = LSOF_SELECTION_TASK; + selections[num_selections].found = Ftask == 2; + } + num_selections++; + } +#endif /* defined(HASTASKS) */ + +#if defined(HASZONES) + /* solaris zones */ + if (ZoneArg) { + for (i = 0; i < HASHZONE; i++) { + for (zp = ZoneArg[i]; zp; zp = zp->next) { + if (pass) { + selections[num_selections].type = + LSOF_SELECTION_SOLARIS_ZONE; + selections[num_selections].found = zp->f; + selections[num_selections].string = zp->zn; + } + num_selections++; + } + } + } +#endif /* defined(HASZONES) */ + +#if defined(HASSELINUX) + /* SELinux context */ + if (CntxArg) { + for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) { + if (pass) { + selections[num_selections].type = + LSOF_SELECTION_SELINUX_CONTEXT; + selections[num_selections].found = cntxp->f; + selections[num_selections].string = cntxp->cntx; + } + num_selections++; + } + } +#endif /* defined(HASSELINUX) */ + + /* allocation selections array */ + if (pass == 0) { + selections = (struct lsof_selection *)malloc( + sizeof(struct lsof_selection) * num_selections); + memset(selections, 0, + sizeof(struct lsof_selection) * num_selections); + res->selections = selections; + res->num_selections = num_selections; + } + } + + /* Params */ + *result = res; + + return ret; +} + +API_EXPORT +enum lsof_error lsof_output_stream(struct lsof_context *ctx, FILE *fp, + char *program_name, int warn) { + if (!ctx) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + ctx->err = fp; + ctx->program_name = mkstrcpy(program_name, NULL); + ctx->warn = warn; + return LSOF_SUCCESS; +} + +API_EXPORT +void lsof_destroy(struct lsof_context *ctx) { + int i; + struct str_lst *str_lst, *str_lst_next; + struct int_lst *int_lst, *int_lst_next; + struct mounts *mnt, *mnt_next; + if (!ctx) { + return; + } + /* Free parameters */ + for (str_lst = Cmdl; str_lst; str_lst = str_lst_next) { + str_lst_next = str_lst->next; + CLEAN(str_lst->str); + CLEAN(str_lst); + } + CLEAN(Spid); + CLEAN(Spgid); + for (i = 0; i < Nuid; i++) { + CLEAN(Suid[i].lnm); + } + CLEAN(Suid); + CLEAN(Nmlst); + + /* Free temporary */ + CLEAN(Namech); +#if defined(HASNLIST) + CLEAN(Nl); + Nll = 0; +#endif /* defined(HASNLIST) */ + + /* Free local mount info */ + if (Lmist) { + for (mnt = Lmi; mnt; mnt = mnt_next) { + mnt_next = mnt->next; + CLEAN(mnt->dir); + CLEAN(mnt->fsname); + CLEAN(mnt->fsnmres); +#if defined(HASFSTYPE) + CLEAN(mnt->fstype); +#endif + CLEAN(mnt); + } + Lmi = NULL; + Lmist = 0; + } + + /* state table */ +#if !defined(USE_LIB_PRINT_TCPTPI) + for (i = 0; i < TcpNstates; i++) { + CLEAN(TcpSt[i]); + } + CLEAN(TcpSt); +#endif /* !defined(USE_LIB_PRINT_TCPTPI) */ + for (i = 0; i < UdpNstates; i++) { + CLEAN(UdpSt[i]); + } + CLEAN(UdpSt); + CLEAN(Pn); + + /* dialect specific free */ + deinitialize(ctx); + CLEAN(ctx); +} + +API_EXPORT +void lsof_free_result(struct lsof_result *result) { + int pi, fi; + struct lsof_process *p; + struct lsof_file *f; + for (pi = 0; pi < result->num_processes; pi++) { + p = &result->processes[pi]; + /* Free files */ + for (fi = 0; fi < p->num_files; fi++) { + f = &p->files[fi]; + CLEAN(f->name); + CLEAN(f->tcp_tpi.state); + } + CLEAN(p->files); + + /* Free process fields */ + CLEAN(p->command); + CLEAN(p->task_cmd); + CLEAN(p->solaris_zone); + CLEAN(p->selinux_context); + } + CLEAN(result->processes); + CLEAN(result->selections); + CLEAN(result); +} + +API_EXPORT +enum lsof_error lsof_select_process(struct lsof_context *ctx, char *command, + int exclude) { + char *cp; /* command copy */ + MALLOC_S len; + struct str_lst *lpt, *str; + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Check for command inclusion/exclusion conflicts. + */ + for (str = Cmdl; str; str = str->next) { + if (str->x != exclude) { + if (!strcmp(str->str, command)) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: -c^%s and -c%s conflict.\n", + Pn, str->str, command); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + } + } + + if (!(cp = mkstrcpy(command, &len))) { + return LSOF_ERROR_NO_MEMORY; + } + +#if defined(MAXSYSCMDL) + if (len > MAXSYSCMDL) { + /* Impossible to match */ + if (ctx->err) { + (void)fprintf(ctx->err, "%s: \"-c ", Pn); + (void)safestrprt(command, ctx->err, 2); + (void)fprintf(ctx->err, "\" length (%zu) > what system", len); + (void)fprintf(ctx->err, " provides (%d)\n", MAXSYSCMDL); + } + CLEAN(cp); + return LSOF_ERROR_INVALID_ARGUMENT; + } +#endif + + if ((lpt = (struct str_lst *)malloc(sizeof(struct str_lst))) == NULL) { + CLEAN(cp); + return LSOF_ERROR_NO_MEMORY; + } + + /* Insert into list */ + lpt->f = 0; + lpt->str = cp; + lpt->len = (int)len; + lpt->x = exclude; + if (exclude) { + Cmdnx++; + } else { + Cmdni++; + /* Update selection flag for inclusions */ + Selflags |= SELCMD; + } + lpt->next = Cmdl; + Cmdl = lpt; + + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_process_regex(struct lsof_context *ctx, char *x) { + int bmod = 0; + int bxmod = 0; + int i, re; + int imod = 0; + int xmod = 0; + int co = REG_NOSUB | REG_EXTENDED; + char reb[256], *xb, *xe, *xm; + MALLOC_S xl; + char *xp = (char *)NULL; + enum lsof_error ret = LSOF_SUCCESS; + + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Make sure the supplied string starts a regular expression. + */ + if (!*x || (*x != '/')) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: regexp doesn't begin with '/': ", Pn); + if (x) + safestrprt(x, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + + /* + * Skip to the end ('/') of the regular expression. + */ + xb = x + 1; + for (xe = xb; *xe; xe++) { + if (*xe == '/') + break; + } + if (*xe != '/') { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: regexp doesn't end with '/': ", Pn); + safestrprt(x, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + + /* + * Decode any regular expression modifiers. + */ + for (i = 0, xm = xe + 1; *xm; xm++) { + switch (*xm) { + case 'b': /* This is a basic expression. */ + if (++bmod > 1) { + if (bmod == 2 && ctx->err) { + (void)fprintf(ctx->err, + "%s: b regexp modifier already used: ", Pn); + safestrprt(x, ctx->err, 1); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } else if (xmod) { + if (++bxmod == 1 && ctx->err) { + (void)fprintf( + ctx->err, + "%s: b and x regexp modifiers conflict: ", Pn); + safestrprt(x, ctx->err, 1); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } else + co &= ~REG_EXTENDED; + break; + case 'i': /* Ignore case. */ + if (++imod > 1) { + if (imod == 2 && ctx->err) { + (void)fprintf(ctx->err, + "%s: i regexp modifier already used: ", Pn); + safestrprt(x, ctx->err, 1); + } + i = 1; + } else + co |= REG_ICASE; + break; + case 'x': /* This is an extended expression. */ + if (++xmod > 1) { + if (xmod == 2 && ctx->err) { + (void)fprintf(ctx->err, + "%s: x regexp modifier already used: ", Pn); + safestrprt(x, ctx->err, 1); + } + i = 1; + } else if (bmod) { + if (++bxmod == 1 && ctx->err) { + (void)fprintf( + ctx->err, + "%s: b and x regexp modifiers conflict: ", Pn); + safestrprt(x, ctx->err, 1); + } + i = 1; + } else + co |= REG_EXTENDED; + break; + default: + if (ctx->err) + (void)fprintf(ctx->err, "%s: invalid regexp modifier: %c\n", Pn, + (int)*xm); + i = 1; + } + } + if (i) { + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + + /* + * Allocate space to hold expression and copy it there. + */ + xl = (MALLOC_S)(xe - xb); + if (!(xp = (char *)malloc(xl + 1))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no regexp space for: ", Pn); + safestrprt(x, ctx->err, 1); + } + Error(ctx); + ret = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + (void)strncpy(xp, xb, xl); + xp[(int)xl] = '\0'; + /* + * Assign a new CmdRx[] slot for this expression. + */ + if (ctx->cmd_regex_cap <= NCmdRxU) { + /* + * More CmdRx[] space must be assigned. + */ + ctx->cmd_regex_cap += 32; + xl = (MALLOC_S)(ctx->cmd_regex_cap * sizeof(lsof_rx_t)); + if (CmdRx) + CmdRx = (lsof_rx_t *)realloc((MALLOC_P *)CmdRx, xl); + else + CmdRx = (lsof_rx_t *)malloc(xl); + if (!CmdRx) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for regexp: ", Pn); + safestrprt(x, ctx->err, 1); + } + Error(ctx); + ret = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + } + i = NCmdRxU; + CmdRx[i].exp = xp; + /* + * Compile the expression. + */ + if ((re = regcomp(&CmdRx[i].cx, xp, co))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: regexp error: ", Pn); + safestrprt(x, ctx->err, 0); + (void)regerror(re, &CmdRx[i].cx, &reb[0], sizeof(reb)); + (void)fprintf(ctx->err, ": %s\n", reb); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + /* + * Complete the CmdRx[] table entry. + */ + CmdRx[i].mc = 0; + CmdRx[i].exp = xp; + NCmdRxU++; + + /** Update selection flags for inclusion */ + if (CmdRx) + Selflags |= SELCMD; + ret = LSOF_SUCCESS; +cleanup: + CLEAN(xp); + return ret; +} + +/* Internal helper for lsof_select_uid/lsof_select_login*/ +enum lsof_error lsof_select_uid_login(struct lsof_context *ctx, uint32_t uid, + char *login, int exclude) { + int i, j; + MALLOC_S len; + char *lp; + + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Avoid entering duplicates. + */ + for (i = 0; i < Nuid; i++) { + if (uid != Suid[i].uid) + continue; + /* Duplicate */ + if (Suid[i].excl == exclude) { + return LSOF_SUCCESS; + } + + /* Conflict */ + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: UID %d has been included and excluded.\n", Pn, + (int)uid); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Allocate space for User IDentifier. + */ + if (Nuid >= Mxuid) { + Mxuid += 10; + len = (MALLOC_S)(Mxuid * sizeof(struct seluid)); + if (!Suid) + Suid = (struct seluid *)malloc(len); + else + Suid = (struct seluid *)realloc((MALLOC_P *)Suid, len); + if (!Suid) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for UIDs", Pn); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + } + if (login) { + if (!(lp = mkstrcpy(login, (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for login: ", Pn); + safestrprt(login, ctx->err, 1); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + Suid[Nuid].lnm = lp; + } else + Suid[Nuid].lnm = (char *)NULL; + Suid[Nuid].f = 0; + Suid[Nuid].uid = uid; + Suid[Nuid++].excl = exclude; + if (exclude) + Nuidexcl++; + else { + Nuidincl++; + Selflags |= SELUID; + } + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_uid(struct lsof_context *ctx, uint32_t uid, + int exclude) { + return lsof_select_uid_login(ctx, uid, NULL, exclude); +} + +API_EXPORT +enum lsof_error lsof_select_login(struct lsof_context *ctx, char *login, + int exclude) { + struct passwd *pw; + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* Convert login to uid, then call lsof_select_uid_login */ + if ((pw = getpwnam(login)) == NULL) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: can't get UID for ", Pn); + safestrprt(login, ctx->err, 1); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + return lsof_select_uid_login(ctx, pw->pw_uid, login, exclude); +} + +API_EXPORT +enum lsof_error lsof_avoid_blocking(struct lsof_context *ctx, int avoid) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Fblock = avoid; + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_logic_and(struct lsof_context *ctx) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Fand = 1; + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_fd(struct lsof_context *ctx, + enum lsof_fd_type fd_type, int fd_num_lo, + int fd_num_hi, int exclude) { + char buf[256]; + char fd[FDLEN]; + struct fd_lst *f, *ft; + + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Don't allow a mixture of exclusions and inclusions. + */ + if (FdlTy >= 0) { + if (FdlTy != exclude) { + if (ctx->err) { + /* + * Report a mixture. + */ + if (fd_type != LSOF_FD_NUMERIC) { + print_fd(fd_type, 0, fd); + (void)snpf(buf, sizeof(buf) - 1, "%s%s", exclude ? "^" : "", + fd); + } else { + if (fd_num_lo != fd_num_hi) { + (void)snpf(buf, sizeof(buf) - 1, "%s%d-%d", + exclude ? "^" : "", fd_num_lo, fd_num_hi); + } else { + (void)snpf(buf, sizeof(buf) - 1, "%s%d", + exclude ? "^" : "", fd_num_lo); + } + } + buf[sizeof(buf) - 1] = '\0'; + (void)fprintf(ctx->err, "%s: %s in an %s -d list: %s\n", Pn, + exclude ? "exclude" : "include", + FdlTy ? "exclude" : "include", buf); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + } + + /* + * Allocate an fd_lst entry. + */ + if (!(f = (struct fd_lst *)malloc((MALLOC_S)sizeof(struct fd_lst)))) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for FD list entry\n", Pn); + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + + /* + * Skip duplicates. + */ + for (ft = Fdl; ft; ft = ft->next) { + if (ft->fd_type != fd_type) + continue; + if (ft->fd_type == LSOF_FD_NUMERIC) { + if ((fd_num_lo != ft->lo) || (fd_num_hi != ft->hi)) + continue; + } + (void)free((FREE_P *)f); + return LSOF_SUCCESS; + } + + /* + * Complete the fd_lst entry and link it to the head of the chain. + */ + f->fd_type = fd_type; + f->hi = fd_num_hi; + f->lo = fd_num_lo; + f->next = Fdl; + Fdl = f; + FdlTy = exclude; + + /* Update selection flag */ + Selflags |= SELFD; + return LSOF_SUCCESS; +} + +/* Internel helper for lsof_select_pid/pgid */ +enum lsof_error lsof_select_pid_pgid(struct lsof_context *ctx, int32_t id, + struct int_lst **sel, int *cap, int *size, + int *incl_num, int *excl_num, int exclude, + int is_pid) { + int i, j; + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Avoid entering duplicates and conflicts. + */ + for (i = 0; i < *size; i++) { + if (id == (*sel)[i].i) { + if (exclude == (*sel)[i].x) { + return LSOF_SUCCESS; + } + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: P%sID %d has been included and excluded.\n", + Pn, is_pid ? "" : "G", id); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + } + + /* + * Allocate table table space. + */ + if (*size >= *cap) { + *cap += 10; + if (!(*sel)) + *sel = (struct int_lst *)malloc( + (MALLOC_S)(sizeof(struct int_lst) * (*cap))); + else + *sel = (struct int_lst *)realloc( + (MALLOC_P *)(*sel), + (MALLOC_S)(sizeof(struct int_lst) * (*cap))); + if (!(*sel)) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for %d process%s IDs", Pn, + *cap, is_pid ? "" : " group"); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + } + + /* Insert selection into sel_pid/sel_pgid*/ + (*sel)[*size].f = 0; + (*sel)[*size].i = id; + (*sel)[(*size)++].x = exclude; + if (exclude) + (*excl_num)++; + else { + (*incl_num)++; + /* Update selection flags */ + Selflags |= is_pid ? SELPID : SELPGID; + } + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_pid(struct lsof_context *ctx, uint32_t pid, + int exclude) { + enum lsof_error res = lsof_select_pid_pgid(ctx, pid, &Spid, &Mxpid, &Npid, + &Npidi, &Npidx, exclude, 1); + /* Record number of unselected PIDs for optimization */ + Npuns = Npid; + return res; +} + +API_EXPORT +enum lsof_error lsof_select_pgid(struct lsof_context *ctx, uint32_t pgid, + int exclude) { + return lsof_select_pid_pgid(ctx, pgid, &Spgid, &Mxpgid, &Npgid, &Npgidi, + &Npgidx, exclude, 0); +} + +API_EXPORT +enum lsof_error lsof_select_ip(struct lsof_context *ctx, int af) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + if (af != AF_UNSPEC && af != AF_INET && af != AF_INET6) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Sequential -i, -i4, and -i6 specifications interact logically -- e.g., + * -i[46] followed by -i[64] is the same as -i. Specifying -i4, or -i6 + * after -i is the same as specifying -i4 or -i6 by itself. + */ + if (!Fnet) { + Fnet = 1; + FnetTy = af; + /* Selection flags */ + Selflags |= SELNET; + } else { + if (FnetTy != AF_UNSPEC) { + if (FnetTy != af) + FnetTy = AF_UNSPEC; + } else + FnetTy = af; + } + return LSOF_SUCCESS; +} + +enum lsof_error lsof_select_inet_internal(struct lsof_context *ctx, char *arg, + enum lsof_protocol proto, int af, + size_t addr_len, void *addr, + int port_lo, int port_hi) { + int ac; + unsigned char *ap; + struct nwad nc; + struct nwad *np; + struct nwad *n = NULL; + enum lsof_error ret = LSOF_SUCCESS; + + /* + * Test address specification -- it must contain at least one of: + * protocol, Internet address or port. If correct, link into search + * list. + */ + if (proto == LSOF_PROTOCOL_INVALID && !addr && port_lo == -1 && + port_hi == -1) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: incomplete Internet address specification: -i ", + Pn); + safestrprt(arg, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + + if (!(n = (struct nwad *)malloc(sizeof(struct nwad)))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for network address from: -i ", Pn); + safestrprt(arg, ctx->err, 1); + } + Error(ctx); + ret = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + + /* + * Construct and link the address specification. + */ + n->proto = proto; + n->af = af; + n->sport = port_lo; + n->eport = port_hi; + n->f = 0; + n->next = Nwad; + + if (af == AF_INET6 && addr) { + /* + * Copy an AF_INET6 address. + */ + if (addr_len != sizeof(struct in6_addr)) { + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + (void)memcpy((void *)&n->a[0], (void *)addr, sizeof(struct in6_addr)); + } else if (af == AF_INET && addr) { + /* + * Copy an AF_INET address. + */ + if (addr_len != sizeof(struct in_addr)) { + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + (void)memcpy((void *)&n->a[0], (void *)addr, sizeof(struct in_addr)); + } + + /* + * Allocate space for the argument specification. + */ + if (arg) { + if (!(n->arg = mkstrcpy(arg, (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for Internet argument: -i ", Pn); + safestrprt(arg, ctx->err, 1); + } + Error(ctx); + ret = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + } else + n->arg = (char *)NULL; + + Nwad = n; + n = NULL; + + /* Update selection flags */ + Selflags |= SELNA; + +cleanup: + CLEAN(n); + return ret; +} + +API_EXPORT +enum lsof_error lsof_select_inet(struct lsof_context *ctx, int af, + enum lsof_protocol proto, size_t addr_len, + void *addr, int port_lo, int port_hi) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + return lsof_select_inet_internal(ctx, "lsof_select_inet()", proto, af, + addr_len, addr, port_lo, port_hi); +} + +/* + * isIPv4addr() - is host name an IPv4 address + */ +static char *isIPv4addr(char *hn, /* host name */ + unsigned char *a, /* address receptor */ + int al) /* address receptor length */ +{ + int dc = 0; /* dot count */ + int i; /* temorary index */ + int ov[MIN_AF_ADDR]; /* octet values */ + int ovx = 0; /* ov[] index */ + /* + * The host name must begin with a number and the return octet value + * arguments must be acceptable. + */ + if ((*hn < '0') || (*hn > '9')) + return ((char *)NULL); + if (!a || (al < MIN_AF_ADDR)) + return ((char *)NULL); + /* + * Start the first octet assembly, then parse tge remainder of the host + * name for four octets, separated by dots. + */ + ov[0] = (int)(*hn++ - '0'); + while (*hn && (*hn != ':')) { + if (*hn == '.') { + + /* + * Count a dot. Make sure a preceding octet value has been + * assembled. Don't assemble more than MIN_AF_ADDR octets. + */ + dc++; + if ((ov[ovx] < 0) || (ov[ovx] > 255)) + return ((char *)NULL); + if (++ovx > (MIN_AF_ADDR - 1)) + return ((char *)NULL); + ov[ovx] = -1; + } else if ((*hn >= '0') && (*hn <= '9')) { + + /* + * Assemble an octet. + */ + if (ov[ovx] < 0) + ov[ovx] = (int)(*hn - '0'); + else + ov[ovx] = (ov[ovx] * 10) + (int)(*hn - '0'); + } else { + + /* + * A non-address character has been detected. + */ + return ((char *)NULL); + } + hn++; + } + /* + * Make sure there were three dots and four non-null octets. + */ + if ((dc != 3) || (ovx != (MIN_AF_ADDR - 1)) || (ov[ovx] < 0) || + (ov[ovx] > 255)) + return ((char *)NULL); + /* + * Copy the octets as unsigned characters and return the ending host name + * character position. + */ + for (i = 0; i < MIN_AF_ADDR; i++) { + a[i] = (unsigned char)ov[i]; + } + return (hn); +} + +/* + * lkup_hostnm() - look up host name + */ +static struct addrinfo * +lkup_hostnm(char *hn, /* host name */ + struct nwad *n) /* network address destination */ +{ + unsigned char *ap; + struct addrinfo *he = NULL; + struct addrinfo hint; + int ln; + int res; + + /* + * Get hostname structure pointer. Return NULL if there is none. + */ + memset(&hint, 0, sizeof(hint)); + hint.ai_family = n->af; + + res = getaddrinfo(hn, NULL, &hint, &he); + + if (!he || !he->ai_addr) + return (he); + + /* + * Copy first hostname structure address to destination structure. + */ + +#if defined(HASIPv6) + if (n->af != he->ai_family) + return ((struct addrinfo *)NULL); + if (n->af == AF_INET6) { + /* + * Copy an AF_INET6 address. + */ + if (he->ai_addrlen != sizeof(struct sockaddr_in6)) + return ((struct addrinfo *)NULL); + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)he->ai_addr; + (void)memcpy((void *)&n->a[0], (void *)&in6->sin6_addr, MAX_AF_ADDR); + return (he); + } +#endif /* defined(HASIPv6) */ + + /* + * Copy an AF_INET address. + */ + if (he->ai_addrlen != sizeof(struct sockaddr_in)) + return ((struct addrinfo *)NULL); + struct sockaddr_in *in = (struct sockaddr_in *)he->ai_addr; + ap = (unsigned char *)&in->sin_addr; + n->a[0] = *ap++; + n->a[1] = *ap++; + n->a[2] = *ap++; + n->a[3] = *ap; + if ((ln = MAX_AF_ADDR - 4) > 0) + zeromem((char *)&n->a[4], ln); + return (he); +} + +API_EXPORT +enum lsof_error lsof_select_inet_string(struct lsof_context *ctx, char *na) { + int ae, i, pr; + int ft = 0; + struct addrinfo *he = NULL; + struct addrinfo hint; + char *hn = (char *)NULL; + MALLOC_S l; + char *p, *wa; + int pt = 0; + int pu = 0; + struct servent *se, *se1; + char *sn = (char *)NULL; + MALLOC_S snl = 0; + char *str_proto = NULL; + enum lsof_error ret = LSOF_SUCCESS; + + size_t addr_len = 0; + void *addr = NULL; + + /* arguments of lsof_select_inet_internal */ + int af = AF_UNSPEC; + enum lsof_protocol proto = LSOF_PROTOCOL_INVALID; + unsigned char a[MAX_AF_ADDR]; + int sp = -1; + int ep = -1; + +#if defined(HASIPv6) + char *cp; +#endif /* defined(HASIPv6) */ + + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + if (!na) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: no network address specified\n", Pn); + return LSOF_ERROR_INVALID_ARGUMENT; + } + + wa = na; + + /* + * Process an IP version type specification, IPv4 or IPv6, optionally + * followed by a '@' and a host name or Internet address, or a ':' and a + * service name or port number. + */ + if ((*wa == '4') || (*wa == '6')) { + if (*wa == '4') + af = AF_INET; + else if (*wa == '6') { + +#if defined(HASIPv6) + af = AF_INET6; +#else /* !defined(HASIPv6) */ + if (ctx->err) { + (void)fprintf(ctx->err, "%s: IPv6 not supported: -i ", Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_UNSUPPORTED; + goto cleanup; +#endif /* defined(HASIPv6) */ + } + wa++; + if (!*wa) { + + /* + * If nothing follows 4 or 6, then all network files of the + * specified IP version are selected. + */ + return lsof_select_ip(ctx, af); + } + } + + /* + * Process protocol name, optionally followed by a '@' and a host name or + * Internet address, or a ':' and a service name or port number. + */ + if (*wa && *wa != '@' && *wa != ':') { + for (p = wa; *wa && *wa != '@' && *wa != ':'; wa++) + ; + if ((l = wa - p)) { + if (!(str_proto = mkstrcat(p, l, (char *)NULL, -1, (char *)NULL, -1, + (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for protocol name from: -i ", + Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + /* + * The protocol name should be "tcp", "udp" or "udplite". + */ + if (strcasecmp(str_proto, "tcp") == 0) { + proto = LSOF_PROTOCOL_TCP; + } else if (strcasecmp(str_proto, "udp") == 0) { + proto = LSOF_PROTOCOL_UDP; + } else if (strcasecmp(str_proto, "udplite") == 0) { + proto = LSOF_PROTOCOL_UDPLITE; + } else { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: unknown protocol name (%s) in: -i ", Pn, + str_proto); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + /* + * Convert protocol name to lower case. + */ + for (p = str_proto; *p; p++) { + if (*p >= 'A' && *p <= 'Z') + *p = *p - 'A' + 'a'; + } + } + } + + /* + * Process an IPv4 address (1.2.3.4), IPv6 address ([1:2:3:4:5:6:7:8]), + * or host name, preceded by a '@' and optionally followed by a colon + * and a service name or port number. + */ + if (*wa == '@') { + wa++; + if (!*wa || *wa == ':') { + +#if defined(HASIPv6) + unacc_address: +#endif /* defined(HASIPv6) */ + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: unacceptable Internet address in: -i ", Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + + if ((p = isIPv4addr(wa, a, sizeof(a)))) { + + /* + * Process IPv4 address. + */ + if (af == AF_INET6) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: IPv4 addresses are prohibited: -i ", Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + wa = p; + af = AF_INET; + } else if (*wa == '[') { + +#if defined(HASIPv6) + /* + * Make sure IPv6 addresses are permitted. If they are, assemble + * one. + */ + if (af == AF_INET) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: IPv6 addresses are prohibited: -i ", Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + if (!(cp = strrchr(++wa, ']'))) + goto unacc_address; + *cp = '\0'; + i = inet_pton(AF_INET6, wa, (void *)&a); + *cp = ']'; + if (i != 1) + goto unacc_address; + for (ae = i = 0; i < MAX_AF_ADDR; i++) { + if ((ae |= a[i])) + break; + } + if (!ae) + goto unacc_address; + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)&a[0])) { + if (af == AF_INET6) { + if (ctx->err) { + + (void)fprintf(ctx->err, + "%s: IPv4 addresses are prohibited: -i ", + Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + for (i = 0; i < 4; i++) { + a[i] = a[i + 12]; + } + af = AF_INET; + } else + af = AF_INET6; + wa = cp + 1; +#else /* !defined(HASIPv6) */ + if (ctx->err) { + (void)fprintf(ctx->err, "%s: unsupported IPv6 address in: -i ", + Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_UNSUPPORTED; + goto cleanup; +#endif /* defined(HASIPv6) */ + + } else { + + /* + * Assemble host name. + */ + for (p = wa; *p && *p != ':'; p++) + ; + if ((l = p - wa)) { + if (!(hn = mkstrcat(wa, l, (char *)NULL, -1, (char *)NULL, -1, + (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for host name: -i ", Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + + /* Resolve hostnames */ + memset(&hint, 0, sizeof(hint)); + hint.ai_family = af; + + if (getaddrinfo(hn, NULL, &hint, &he)) { + if (ctx->err) { + fprintf(ctx->err, "%s: unknown host name (%s) in: -i ", + Pn, hn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + } + wa = p; + } + } + /* + * If there is no port number, enter the address. + */ + if (!*wa) + goto nwad_enter; + /* + * Process a service name or port number list, preceded by a colon. + * + * Entries of the list are separated with commas; elements of a numeric + * range are specified with a separating minus sign (`-'); all service names + * must belong to the same protocol; embedded spaces are not allowed. An + * embedded minus sign in a name is taken to be part of the name, the + * starting entry of a range can't be a service name. + */ + if (*wa != ':' || *(wa + 1) == '\0') { + + unacc_port: + if (ctx->err) { + + (void)fprintf(ctx->err, + "%s: unacceptable port specification in: -i ", Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + for (++wa; wa && *wa; wa++) { + for (ep = pr = sp = 0; *wa; wa++) { + if (*wa < '0' || *wa > '9') { + + /* + * Convert service name to port number, using already-specified + * protocol name. A '-' is taken to be part of the name; hence + * the starting entry of a range can't be a service name. + */ + for (p = wa; *wa && *wa != ','; wa++) + ; + if (!(l = wa - p)) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: invalid service name: -i ", + Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + if (sn) { + if (l > snl) { + sn = (char *)realloc((MALLOC_P *)sn, l + 1); + snl = l; + } + } else { + sn = (char *)malloc(l + 1); + snl = l; + } + if (!sn) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for service name: -i ", Pn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + (void)strncpy(sn, p, l); + *(sn + l) = '\0'; + if (proto != LSOF_PROTOCOL_INVALID) { + /* + * If the protocol has been specified, look up the port + * number for the service name for the specified protocol. + */ + if (!(se = getservbyname(sn, str_proto))) { + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: unknown service %s for %s in: -i ", Pn, sn, + str_proto); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + pt = (int)ntohs(se->s_port); + } else { + + /* + * If no protocol has been specified, look up the port + * numbers for the service name for both TCP and UDP. + */ + if ((se = getservbyname(sn, "tcp"))) + pt = (int)ntohs(se->s_port); + if ((se1 = getservbyname(sn, "udp"))) + pu = (int)ntohs(se1->s_port); + if (!se && !se1) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: unknown service %s in: -i ", Pn, + sn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + if (se && se1 && pt != pu) { + if (ctx->err) { + (void)fprintf( + ctx->err, + "%s: TCP=%d and UDP=%d %s ports conflict;\n", + Pn, pt, pu, sn); + (void)fprintf( + ctx->err, + " specify \"tcp:%s\" or \"udp:%s\": -i ", + sn, sn); + safestrprt(na, ctx->err, 1); + } + ret = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + if (!se && se1) + pt = pu; + } + if (pr) + ep = pt; + else { + sp = pt; + if (*wa == '-') + pr++; + } + } else { + + /* + * Assemble port number. + */ + for (; *wa && *wa != ','; wa++) { + if (*wa == '-') { + if (pr) + goto unacc_port; + pr++; + break; + } + if (*wa < '0' || *wa > '9') + goto unacc_port; + if (pr) + ep = (ep * 10) + *wa - '0'; + else + sp = (sp * 10) + *wa - '0'; + } + } + if (!*wa || *wa == ',') + break; + if (pr) + continue; + goto unacc_port; + } + if (!pr) + ep = sp; + if (ep < sp) + goto unacc_port; + /* + * Enter completed port or port range specification. + */ + + nwad_enter: + + for (; he; he = he->ai_next) { + if (he->ai_family == AF_INET && + he->ai_addrlen == sizeof(struct sockaddr_in) && he->ai_addr) { + struct sockaddr_in *in = (struct sockaddr_in *)he->ai_addr; + addr_len = sizeof(struct in_addr); + addr = &in->sin_addr; + } else if (he->ai_family == AF_INET6 && + he->ai_addrlen == sizeof(struct sockaddr_in6) && + he->ai_addr) { + struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)he->ai_addr; + addr_len = sizeof(struct in6_addr); + addr = &in6->sin6_addr; + } else { + continue; + } + if ((ret = lsof_select_inet_internal(ctx, na, proto, he->ai_family, + addr_len, addr, sp, ep))) { + goto cleanup; + } + } + if (!*wa) + break; + } + +cleanup: + if (he) { + freeaddrinfo(he); + } + CLEAN(str_proto); + CLEAN(hn); + CLEAN(sn); + return ret; +} + +API_EXPORT +enum lsof_error lsof_select_unix_socket(struct lsof_context *ctx) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + Funix = 1; + /* Selection flags */ + Selflags |= SELUNX; + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_task(struct lsof_context *ctx, int show) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + if (show) { + Ftask = 1; + IgnTasks = 0; + Selflags |= SELTASK; + } else { + Ftask = 0; + IgnTasks = 1; + Selflags &= ~SELTASK; + } + + /* + * If IgnTasks is set, remove SELTASK from SelAll and + * SelProc. + */ + SelAll = IgnTasks ? (SELALL & ~SELTASK) : SELALL; + SelProc = IgnTasks ? (SELPROC & ~SELTASK) : SELPROC; + + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_proto_state(struct lsof_context *ctx, int tcp, + char *state, int exclude) { + int num_states; + char **states; + unsigned char **state_incl; + int *state_incl_num; + unsigned char **state_excl; + int *state_excl_num; + char *ty; + int found; + int i; + + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + (void)build_IPstates(ctx); + + if (tcp) { + ty = "TCP"; + num_states = TcpNstates; + states = TcpSt; + state_incl = &TcpStI; + state_incl_num = &TcpStIn; + state_excl = &TcpStX; + state_excl_num = &TcpStXn; + } else { + ty = "UDP"; + num_states = UdpNstates; + states = UdpSt; + state_incl = &UdpStI; + state_incl_num = &UdpStIn; + state_excl = &UdpStX; + state_excl_num = &UdpStXn; + } + + /* Allocate incl/excl array */ + if (num_states) { + if (!*state_incl) { + if (!(*state_incl = (unsigned char *)calloc( + (MALLOC_S)num_states, sizeof(unsigned char)))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no %s state inclusion table space\n", Pn, + ty); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + } + if (!*state_excl) { + if (!(*state_excl = (unsigned char *)calloc( + (MALLOC_S)num_states, sizeof(unsigned char)))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no %s state exclusion table space\n", Pn, + ty); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + } + } else { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no %s state names available: %s\n", Pn, + ty, state); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + + found = 0; + /* Find match */ + if (num_states) { + for (i = 0; i < num_states; i++) { + if (!strcasecmp(state, states[i])) { + found = 1; + break; + } + } + } + + if (!found) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: unknown %s state name: %s\n", Pn, ty, + state); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* Find duplicate and conflict */ + if (exclude) { + if ((*state_incl)[i]) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't include and exclude %s state: %s\n", + Pn, ty, states[i]); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } else if (!(*state_excl)[i]) { + (*state_excl)[i] = 1; + (*state_excl_num)++; + } + } else { + if ((*state_excl)[i]) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: can't include and exclude %s state: %s\n", + Pn, ty, states[i]); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } else if (!(*state_incl)[i]) { + (*state_incl)[i] = 1; + (*state_incl_num)++; + } + } + + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_nfs(struct lsof_context *ctx) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Fnfs = 1; + /* Selection flags */ + Selflags |= SELNFS; + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_num_links(struct lsof_context *ctx, int threshold) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Nlink = threshold; + /* Selection flags */ + if (Nlink) { + Selflags |= SELNLINK; + } + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_exempt_fs(struct lsof_context *ctx, char *orig_path, + int avoid_readlink) { + char *ec; /* pointer to copy of path */ + efsys_list_t *ep; /* file system path list pointer */ + int i; /* temporary index */ + char *path; /* Readlink() of file system path */ + struct mounts *mp = NULL, *mpw; /* local mount table pointers */ + + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + if (!orig_path || (*orig_path != '/')) { + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, + "%s: -e not followed by a file system path: \"%s\"\n", + Pn, orig_path); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + if (!(ec = mkstrcpy(orig_path, (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for -e string: ", Pn); + safestrprt(orig_path, ctx->err, 1); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + if (avoid_readlink) + path = ec; + else { + if (!(path = Readlink(ctx, ec))) + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Remove terminating `/' characters from paths longer than one. + */ + for (i = (int)strlen(path); (i > 1) && (path[i - 1] == '/'); i--) { + path[i - 1] = '\0'; + } + /* + * Enter file system path on list, avoiding duplicates. + */ + for (ep = Efsysl; ep; ep = ep->next) { + if (!strcmp(ep->path, path)) { + (void)free((FREE_P *)path); + return LSOF_SUCCESS; + } + } + + /* + * If there are file systems specified by -e options, check them. + */ + + if ((mpw = readmnt(ctx))) { + for (; mpw; mpw = mpw->next) { + if (!strcmp(mpw->dir, path)) { + mp = mpw; + break; + } + } + if (!mp) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: \"-e %s\" is not a mounted file system.\n", + Pn, path); + return LSOF_ERROR_INVALID_ARGUMENT; + } + } + } + + if (!(ep = (efsys_list_t *)malloc((MALLOC_S)(sizeof(efsys_list_t))))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for \"-e %s\" entry\n", Pn, + orig_path); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + ep->path = path; + ep->pathl = i; + ep->rdlnk = avoid_readlink; + ep->mp = mp; + ep->next = Efsysl; + Efsysl = ep; + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_avoid_forking(struct lsof_context *ctx, int avoid) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Fovhd = avoid; + return LSOF_SUCCESS; +} + +enum lsof_error lsof_exit_on_fatal(struct lsof_context *ctx, int exit) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + ctx->exit_on_fatal = exit; + return LSOF_SUCCESS; +} + +/* + * hash_zn() - hash zone name + */ +int hash_zn(char *zn) /* zone name */ +{ + int i, h; + size_t l; + + if (!(l = strlen(zn))) + return (0); + if (l == 1) + return ((int)*zn & (HASHZONE - 1)); + for (i = h = 0; i < (int)(l - 1); i++) { + h ^= ((int)zn[i] * (int)zn[i + 1]) << ((i * 3) % 13); + } + return (h & (HASHZONE - 1)); +} + +enum lsof_error lsof_select_solaris_zone(struct lsof_context *ctx, char *zn) { +#if defined(HASZONES) + int zh; + znhash_t *zp, *zpn; + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Allocate zone argument hash space, as required. + */ + if (!ZoneArg) { + if (!(ZoneArg = (znhash_t **)calloc(HASHZONE, sizeof(znhash_t *)))) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for zone arg hash\n", Pn); + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + } + /* + * Hash the zone name and search the argument hash. + */ + zh = hash_zn(zn); + for (zp = ZoneArg[zh]; zp; zp = zp->next) { + if (!strcmp(zp->zn, zn)) + break; + } + if (zp) { + /* + * Process a duplicate. + */ + if (ctx->err && !Fwarn) + (void)fprintf(ctx->err, "%s: duplicate zone name: %s\n", Pn, zn); + return LSOF_SUCCESS; + } + /* + * Create a new hash entry and link it to its bucket. + */ + if (!(zpn = (znhash_t *)malloc((MALLOC_S)sizeof(znhash_t)))) { + (void)fprintf(ctx->err, "%s no hash space for zone: %s\n", Pn, zn); + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + zpn->f = 0; + zpn->zn = zn; + zpn->next = ZoneArg[zh]; + ZoneArg[zh] = zpn; + + /* Update selection flags */ + Selflags |= SELZONE; + + return LSOF_SUCCESS; +#else + return LSOF_ERROR_UNSUPPORTED; +#endif /* defined(HASZONES) */ +} + +#if defined(HASSELINUX) +extern int cmp_cntx_eq(char *pcntx, char *ucntx); + +# include + +/* + * cmp_cntx_eq -- compare program and user security contexts + */ +int cmp_cntx_eq(char *pcntx, /* program context */ + char *ucntx) /* user supplied context */ +{ + return !fnmatch(ucntx, pcntx, 0); +} + +#endif /* defined(HASSELINUX) */ + +enum lsof_error lsof_select_selinux_context(struct lsof_context *ctx, + char *cntx) { +#if defined(HASSELINUX) + cntxlist_t *cntxp; + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Search the argument list for a duplicate. + */ + for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) { + if (!strcmp(cntxp->cntx, cntx)) { + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: duplicate context: %s\n", Pn, + cntx); + } + return LSOF_SUCCESS; + } + } + + /* + * Create and link a new context argument list entry. + */ + if (!(cntxp = (cntxlist_t *)malloc((MALLOC_S)sizeof(cntxlist_t)))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for context: %s\n", Pn, cntx); + } + Error(ctx); + return LSOF_ERROR_NO_MEMORY; + } + cntxp->f = 0; + cntxp->cntx = cntx; + cntxp->next = CntxArg; + CntxArg = cntxp; + + /* Update selection flags */ + Selflags |= SELCNTX; + return LSOF_SUCCESS; +#else + return LSOF_ERROR_UNSUPPORTED; +#endif /* defined(HASSELINUX) */ +} + +/* + * ck_file_arg() - check file arguments + */ +enum lsof_error +ck_file_arg(struct lsof_context *ctx, char *arg, /* argument */ + int fv, /* Ffilesys value (real or temporary) + * 0 = paths may be file systems + * 1 = paths are just files + * 2 = paths must be file systems + */ + int rs, /* Readlink() status if argument count == 1: + * 0 = undone, 1 = done */ + struct stat *sbp, /* if non-NULL, pointer to stat(2) buffer + * when argument count == 1 */ + int accept_deleted_file) /* if non-zero, don't report an error + * even when the file doesn't exist. */ +{ + char *ap, *fnm, *fsnm, *path; + enum lsof_error err = LSOF_SUCCESS; + int fsm, ftype, j, k; + MALLOC_S l; + struct mounts *mp; + struct mounts **mmp = (struct mounts **)NULL; + int mx, nm; + static int nma = 0; + struct stat sb; + struct sfile *sfp; + short ss = 0; + int err_stat = 0; + +#if defined(HASPROCFS) + unsigned char ad, an; + int pfsnl = -1; + pid_t pid; + struct procfsid *pfi; +#endif /* defined(HASPROCFS) */ + + if (rs) + path = arg; + else { + if (!(path = Readlink(ctx, arg))) { + err_stat = 1; + err = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + } + /* + * Remove terminating `/' characters from paths longer than one. + */ + j = k = strlen(path); + while ((k > 1) && (path[k - 1] == '/')) { + k--; + } + if (k < j) { + if (path != arg) + path[k] = '\0'; + else { + if (!(ap = (char *)malloc((MALLOC_S)(k + 1)))) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for copy of %s\n", Pn, + path); + Error(ctx); + err = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + (void)strncpy(ap, path, k); + ap[k] = '\0'; + path = ap; + ap = NULL; + } + } + /* + * Check for file system argument. + */ + for (ftype = 1, mp = readmnt(ctx), nm = 0; (fv != 1) && mp; mp = mp->next) { + fsm = 0; + if (strcmp(mp->dir, path) == 0) + fsm++; + else if (fv == 2 || (mp->fs_mode & S_IFMT) == S_IFBLK) { + if (mp->fsnmres && strcmp(mp->fsnmres, path) == 0) + fsm++; + } + if (!fsm) + continue; + ftype = 0; + /* + * Skip duplicates. + */ + for (mx = 0; mx < nm; mx++) { + if (strcmp(mp->dir, mmp[mx]->dir) == 0 && mp->dev == mmp[mx]->dev && + mp->rdev == mmp[mx]->rdev && mp->inode == mmp[mx]->inode) + break; + } + if (mx < nm) + continue; + /* + * Allocate space for and save another mount point match and + * the type of match -- directory name (mounted) or file system + * name (mounted-on). + */ + if (nm >= nma) { + nma += 5; + l = (MALLOC_S)(nma * sizeof(struct mounts *)); + if (mmp) + mmp = (struct mounts **)realloc((MALLOC_P *)mmp, l); + else + mmp = (struct mounts **)malloc(l); + if (!mmp) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for mount pointers\n", + Pn); + Error(ctx); + err = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + } + mmp[nm++] = mp; + } + if (fv == 2 && nm == 0) { + if (!accept_deleted_file) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: not a file system: ", Pn); + safestrprt(arg, ctx->err, 1); + } + } + err_stat = 1; + err = LSOF_ERROR_INVALID_ARGUMENT; + goto cleanup; + } + /* + * Loop through the file system matches. If there were none, make one + * pass through the loop, using simply the path name. + */ + mx = 0; + do { + + /* + * Allocate an sfile structure and fill in the type and link. + */ + if (!(sfp = (struct sfile *)malloc(sizeof(struct sfile)))) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: no space for files\n", Pn); + Error(ctx); + err = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + sfp->next = Sfile; + Sfile = sfp; + sfp->f = 0; + if ((sfp->type = ftype)) { + + /* + * For a non-file system path, use the path as the file name + * and set a NULL file system name. + */ + fnm = path; + fsnm = (char *)NULL; + /* + * Stat the path to obtain its characteristics. + */ + if (sbp) + sb = *sbp; + else { + if (statsafely(ctx, fnm, &sb) != 0) { + int en = errno; + if (!accept_deleted_file && ctx->err) { + (void)fprintf(ctx->err, "%s: status error on ", Pn); + safestrprt(fnm, ctx->err, 0); + (void)fprintf(ctx->err, ": %s\n", strerror(en)); + } + Sfile = sfp->next; + err_stat = 1; + CLEAN(sfp); + CLEAN(path); + continue; + } + +#if defined(HASSPECDEVD) + (void)HASSPECDEVD(ctx, fnm, &sb); +#endif /* defined(HASSPECDEVD) */ + } + sfp->i = (INODETYPE)sb.st_ino; + sfp->mode = sb.st_mode & S_IFMT; + + sfp->dev = sb.st_dev; + sfp->rdev = sb.st_rdev; + +#if defined(CKFA_MPXCHAN) + /* + * Save a (possible) multiplexed channel number. (This is an + * AIX artifact.) + */ + sfp->ch = getchan(path); +#endif /* defined(CKFA_MPXCHAN) */ + + } else { + +#if defined(SAVE_MP_IN_SFILE) + sfp->mp = mp = mmp[mx++]; +#else /* !defined(SAVE_MP_IN_SFILE) */ + mp = mmp[mx++]; +#endif /* defined(SAVE_MP_IN_SFILE) */ + + ss++; + +#if defined(HASPROCFS) + /* + * If this is a /proc file system, set the search flag and + * abandon the sfile entry. + */ + if (mp == Mtprocfs) { + Sfile = sfp->next; + CLEAN(sfp); + Procsrch = 1; + continue; + } +#endif /* defined(HASPROCFS) */ + + /* + * Derive file name and file system name for a mount point. + * + * Save the device numbers, inode number, and modes. + */ + fnm = mp->dir; + fsnm = mp->fsname; + sfp->dev = mp->dev; + sfp->rdev = mp->rdev; + sfp->i = mp->inode; + sfp->mode = mp->mode & S_IFMT; + } + ss = 1; /* indicate a "safe" stat() */ + /* + * Store the file name and file system name pointers in the sfile + * structure, allocating space as necessary. + */ + if (!fnm || fnm == path) { + sfp->name = fnm; + +#if defined(HASPROCFS) + an = 0; +#endif /* defined(HASPROCFS) */ + + } else { + if (!(sfp->name = mkstrcpy(fnm, (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for file name: ", Pn); + safestrprt(fnm, ctx->err, 1); + } + Error(ctx); + err = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + +#if defined(HASPROCFS) + an = 1; +#endif /* defined(HASPROCFS) */ + } + if (!fsnm || fsnm == path) { + sfp->devnm = fsnm; + +#if defined(HASPROCFS) + ad = 0; +#endif /* defined(HASPROCFS) */ + + } else { + if (!(sfp->devnm = mkstrcpy(fsnm, (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for file system name: ", Pn); + safestrprt(fsnm, ctx->err, 1); + } + Error(ctx); + err = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + +#if defined(HASPROCFS) + ad = 1; +#endif /* defined(HASPROCFS) */ + } + if (!(sfp->aname = mkstrcpy(arg, (MALLOC_S *)NULL))) { + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for argument file name: ", Pn); + safestrprt(arg, ctx->err, 1); + } + Error(ctx); + err = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + +#if defined(HASPROCFS) + /* + * See if this is an individual member of a proc file system. + */ + if (!Mtprocfs || Procsrch) + continue; + +# if defined(HASFSTYPE) && HASFSTYPE == 1 + if (strcmp(sb.st_fstype, HASPROCFS) != 0) + continue; +# endif /* defined(HASFSTYPE) && HASFSTYPE==1 */ + + if (pfsnl == -1) + pfsnl = strlen(Mtprocfs->dir); + if (!pfsnl) + continue; + if (strncmp(Mtprocfs->dir, path, pfsnl) != 0) + continue; + if (path[pfsnl] != '/') + +# if defined(HASPINODEN) + pid = 0; +# else /* !defined(HASPINODEN) */ + continue; +# endif /* defined(HASPINODEN) */ + + else { + for (j = pfsnl + 1; path[j]; j++) { + if (!isdigit((unsigned char)path[j])) + break; + } + if (path[j] || (j - pfsnl - 1) < 1 || + (sfp->mode & S_IFMT) != S_IFREG) + +# if defined(HASPINODEN) + pid = 0; +# else /* !defined(HASPINODEN) */ + continue; +# endif /* defined(HASPINODEN) */ + + else + pid = atoi(&path[pfsnl + 1]); + } + if (!(pfi = (struct procfsid *)malloc( + (MALLOC_S)sizeof(struct procfsid)))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for %s ID: ", Pn, + Mtprocfs->dir); + safestrprt(path, ctx->err, 1); + } + Error(ctx); + err = LSOF_ERROR_NO_MEMORY; + goto cleanup; + } + pfi->pid = pid; + pfi->f = 0; + pfi->nm = sfp->aname; + pfi->next = Procfsid; + Procfsid = pfi; + +# if defined(HASPINODEN) + pfi->inode = (INODETYPE)sfp->i; +# endif /* defined(HASPINODEN) */ + + /* + * Abandon the Sfile entry, lest it be used in is_file_named(). + */ + Sfile = sfp->next; + if (ad) + (void)free((FREE_P *)sfp->devnm); + if (an) + (void)free((FREE_P *)sfp->name); + CLEAN(sfp); +#endif /* defined(HASPROCFS) */ + + } while (mx < nm); + +cleanup: + CLEAN(path); + CLEAN(mmp); + if (err == LSOF_SUCCESS) { + if (accept_deleted_file) { + if (!ss && err_stat == 0) + err = LSOF_ERROR_INVALID_ARGUMENT; + } else if (!ss) { + err = LSOF_ERROR_INVALID_ARGUMENT; + } + } + + /* Update selection flags */ + if (err == LSOF_SUCCESS) + Selflags |= SELNM; + return err; +} + +enum lsof_error lsof_select_file(struct lsof_context *ctx, char *path, + int flags) { + + int fv = 0; + int accept_deleted_file = 0; + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + if (flags & + (LSOF_SELECT_FILE_ONLY_FILES | LSOF_SELECT_FILE_ONLY_FILE_SYSTEMS)) { + /* conflcit */ + return LSOF_ERROR_INVALID_ARGUMENT; + } else if (flags & LSOF_SELECT_FILE_ONLY_FILES) { + /* paths are files */ + fv = 1; + } else if (flags & LSOF_SELECT_FILE_ONLY_FILE_SYSTEMS) { + /* paths are file systems */ + fv = 2; + } + + if (flags & LSOF_SELECT_FILE_ACCEPT_DELETED) { + accept_deleted_file = 1; + } + + return ck_file_arg(ctx, path, fv, 0, NULL, accept_deleted_file); +} + +enum lsof_error lsof_use_name_cache(struct lsof_context *ctx, int enable) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + Fncache = enable; + + return LSOF_SUCCESS; +} \ No newline at end of file diff --git a/lib/misc.c b/lib/misc.c index e7ad9f25..029432d2 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -1,5 +1,5 @@ /* - * misc.c - common miscellaneous functions for lsof + * misc.c - common miscellaneous functions for liblsof */ /* @@ -29,7 +29,7 @@ */ #include "common.h" -#include "dlsof.h" +#include "lsof.h" #if defined(HASWIDECHAR) # if defined(WIDECHARINCL) @@ -74,6 +74,7 @@ static jmp_buf Jmp_buf; /* jump buffer */ static int Pipes[] = /* pipes for child process */ {-1, -1, -1, -1}; static int CtSigs[] = {0, SIGINT, SIGKILL}; + /* child termination signals (in order * of application) -- the first is a * dummy to allow pipe closure to @@ -85,8 +86,8 @@ static int CtSigs[] = {0, SIGINT, SIGKILL}; * build-Nl() - build kernel name list table */ -static struct drive_Nl *Build_Nl = (struct drive_Nl *)NULL; /* the default Drive_Nl address */ +static struct drive_Nl *Build_Nl = (struct drive_Nl *)NULL; void build_Nl(struct lsof_context *ctx, struct drive_Nl *d) /* data to drive the construction */ @@ -97,16 +98,18 @@ void build_Nl(struct lsof_context *ctx, for (dp = d, n = 0; dp->nn; dp++, n++) ; if (n < 1) { - (void)fprintf(stderr, "%s: can't calculate kernel name list length\n", - Pn); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't calculate kernel name list length\n", Pn); Error(ctx); } if (!(Nl = (struct NLIST_TYPE *)calloc((n + 1), sizeof(struct NLIST_TYPE)))) { - (void)fprintf( - stderr, - "%s: can't allocate %d bytes to kernel name list structure\n", Pn, - (int)((n + 1) * sizeof(struct NLIST_TYPE))); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: can't allocate %d bytes to kernel name list structure\n", + Pn, (int)((n + 1) * sizeof(struct NLIST_TYPE))); Error(ctx); } for (dp = d, i = 0; i < n; dp++, i++) { @@ -153,9 +156,9 @@ void childx(struct lsof_context *ctx) { (void)signal(SIGALRM, SIG_DFL); if (sx < (NCTSIGS - 1)) continue; - if (!Fwarn) + if (!Fwarn && ctx->err) (void)fprintf( - stderr, + ctx->err, "%s: WARNING -- child process %d may be hung.\n", Pn, (int)Cpid); break; @@ -217,7 +220,7 @@ int compdev(COMP_P *a1, COMP_P *a2) { /* * closefrom_shim() -- provide closefrom() when unavailable */ -void closefrom_shim(int low) { +void closefrom_shim(struct lsof_context *ctx, int low) { int i; #if defined(HAS_CLOSEFROM) (void)closefrom(low); @@ -237,19 +240,18 @@ void closefrom_shim(int low) { * doinchild() -- do a function in a child process */ -static int doinchild(struct lsof_context *ctx, - int (*fn)(), /* function to perform */ - char *fp, /* function parameter */ - char *rbuf, /* response buffer */ - int rbln) /* response buffer length */ +int doinchild(struct lsof_context *ctx, int (*fn)(), /* function to perform */ + char *fp, /* function parameter */ + char *rbuf, /* response buffer */ + int rbln) /* response buffer length */ { int en, rv; /* * Check reply buffer size. */ - if (!Fovhd && rbln > MAXPATHLEN) { - (void)fprintf(stderr, + if (!Fovhd && rbln > MAXPATHLEN && ctx->err) { + (void)fprintf(ctx->err, "%s: doinchild error; response buffer too large: %d\n", Pn, rbln); Error(ctx); @@ -277,8 +279,9 @@ static int doinchild(struct lsof_context *ctx, * process. */ if (pipe(Pipes) < 0 || pipe(&Pipes[2]) < 0) { - (void)fprintf(stderr, "%s: can't open pipes: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't open pipes: %s\n", Pn, + strerror(errno)); Error(ctx); } /* @@ -311,21 +314,23 @@ static int doinchild(struct lsof_context *ctx, rc = dup2(Pipes[0], 0); if (rc < 0) { - (void)fprintf(stderr, - "%s: can't dup Pipes[0] to fd 0: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't dup Pipes[0] to fd 0: %s\n", + Pn, strerror(errno)); Error(ctx); } Pipes[0] = 0; rc = dup2(Pipes[3], 1); if (rc < 0) { - (void)fprintf(stderr, - "%s: can't dup Pipes.[3] to fd 1: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't dup Pipes.[3] to fd 1: %s\n", + Pn, strerror(errno)); Error(ctx); } Pipes[3] = 1; - (void)closefrom_shim(2); + (void)closefrom_shim(ctx, 2); Pipes[1] = -1; Pipes[2] = -1; @@ -381,8 +386,9 @@ static int doinchild(struct lsof_context *ctx, * Continue in the parent process to finish the setup. */ if (Cpid < 0) { - (void)fprintf(stderr, "%s: can't fork: %s\n", Pn, - strerror(errno)); + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't fork: %s\n", Pn, + strerror(errno)); Error(ctx); } (void)close(Pipes[0]); @@ -470,23 +476,6 @@ static int dostat(char *path, /* path */ return (stat(path, (struct stat *)rbuf)); } -#if defined(WILLDROPGID) -/* - * dropgid() - drop setgid permission - */ - -void dropgid(struct lsof_context *ctx) { - if (!Setuidroot && Setgid) { - if (setgid(Mygid) < 0) { - (void)fprintf(stderr, "%s: can't setgid(%d): %s\n", Pn, (int)Mygid, - strerror(errno)); - Error(ctx); - } - Setgid = 0; - } -} -#endif /* defined(WILLDROPGID) */ - /* * enter_dev_ch() - enter device characters in file structure */ @@ -497,9 +486,11 @@ void enter_dev_ch(struct lsof_context *ctx, char *m) { if (!m || *m == '\0') return; if (!(mp = mkstrcpy(m, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no more dev_ch space at PID %d: \n", Pn, - Lp->pid); - safestrprt(m, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no more dev_ch space at PID %d: \n", + Pn, Lp->pid); + safestrprt(m, ctx->err, 1); + } Error(ctx); } if (Lf->dev_ch) @@ -521,23 +512,29 @@ void enter_IPstate(struct lsof_context *ctx, char *ty, /* type -- TCP or UDP */ #else /* !defined(USE_LIB_PRINT_TCPTPI) */ int al, i, j, oc, nn, ns, off, tx; - char *cp; + char *cp = NULL; + char **temp; MALLOC_S len; /* * Check the type name and set the type index. */ if (!ty) { - (void)fprintf(stderr, "%s: no type specified to enter_IPstate()\n", Pn); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no type specified to enter_IPstate()\n", Pn); Error(ctx); + return; } if (!strcmp(ty, "TCP")) tx = 0; else if (!strcmp(ty, "UDP")) tx = 1; else { - (void)fprintf(stderr, "%s: unknown type for enter_IPstate: %s\n", Pn, - ty); + if (ctx->err) + (void)fprintf(ctx->err, "%s: unknown type for enter_IPstate: %s\n", + Pn, ty); Error(ctx); + return; } /* * If the name argument is NULL, reduce the allocated table to its minimum @@ -552,10 +549,14 @@ void enter_IPstate(struct lsof_context *ctx, char *ty, /* type -- TCP or UDP */ } if (UdpNstates < UdpStAlloc) { len = (MALLOC_S)(UdpNstates * sizeof(char *)); - if (!(UdpSt = (char **)realloc((MALLOC_P *)UdpSt, len))) { - (void)fprintf(stderr, "%s: can't reduce UdpSt[]\n", Pn); + if (!(temp = (char **)realloc((MALLOC_P *)UdpSt, len))) { + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't reduce UdpSt[]\n", Pn); Error(ctx); + return; } + UdpSt = temp; } UdpStAlloc = UdpNstates; } @@ -567,10 +568,14 @@ void enter_IPstate(struct lsof_context *ctx, char *ty, /* type -- TCP or UDP */ } if (TcpNstates < TcpStAlloc) { len = (MALLOC_S)(TcpNstates * sizeof(char *)); - if (!(TcpSt = (char **)realloc((MALLOC_P *)TcpSt, len))) { - (void)fprintf(stderr, "%s: can't reduce TcpSt[]\n", Pn); + if (!(temp = (char **)realloc((MALLOC_P *)TcpSt, len))) { + if (ctx->err) + (void)fprintf(ctx->err, + "%s: can't reduce TcpSt[]\n", Pn); Error(ctx); + return; } + TcpSt = temp; } TcpStAlloc = TcpNstates; } @@ -581,17 +586,21 @@ void enter_IPstate(struct lsof_context *ctx, char *ty, /* type -- TCP or UDP */ * Check the name and number. */ if (strlen(nm) < 1) { - (void)fprintf(stderr, "%s: bad %s name (\"%s\"), number=%d\n", Pn, ty, - nm, nr); + if (ctx->err) + (void)fprintf(ctx->err, "%s: bad %s name (\"%s\"), number=%d\n", Pn, + ty, nm, nr); Error(ctx); + return; } /* * Make a copy of the name. */ if (!(cp = mkstrcpy(nm, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: enter_IPstate(): no %s space for %s\n", Pn, - ty, nm); + if (ctx->err) + (void)fprintf(ctx->err, "%s: enter_IPstate(): no %s space for %s\n", + Pn, ty, nm); Error(ctx); + return; } /* * Set the necessary offset for using nr as an index. If it is @@ -614,12 +623,14 @@ void enter_IPstate(struct lsof_context *ctx, char *ty, /* type -- TCP or UDP */ } len = (MALLOC_S)(al * sizeof(char *)); if (tx) { - if (!(UdpSt = (char **)realloc((MALLOC_P *)UdpSt, len))) + if (!(temp = (char **)realloc((MALLOC_P *)UdpSt, len))) goto no_IP_space; + UdpSt = temp; UdpStAlloc = al; } else { - if (!(TcpSt = (char **)realloc((MALLOC_P *)TcpSt, len))) + if (!(temp = (char **)realloc((MALLOC_P *)TcpSt, len))) goto no_IP_space; + TcpSt = temp; TcpStAlloc = al; } for (i = 0, j = oc; i < oc; i++, j++) { @@ -660,25 +671,29 @@ void enter_IPstate(struct lsof_context *ctx, char *ty, /* type -- TCP or UDP */ len = (MALLOC_S)(al * sizeof(char *)); if (tx) { if (UdpSt) - UdpSt = (char **)realloc((MALLOC_P *)UdpSt, len); + temp = (char **)realloc((MALLOC_P *)UdpSt, len); else - UdpSt = (char **)malloc(len); - if (!UdpSt) { + temp = (char **)malloc(len); + if (!temp) { no_IP_space: - (void)fprintf(stderr, "%s: no %s state space\n", Pn, ty); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no %s state space\n", Pn, ty); Error(ctx); + goto cleanup; } + UdpSt = temp; UdpNstates = nn; UdpStAlloc = al; } else { if (TcpSt) - TcpSt = (char **)realloc((MALLOC_P *)TcpSt, len); + temp = (char **)realloc((MALLOC_P *)TcpSt, len); else - TcpSt = (char **)malloc(len); - if (!TcpSt) + temp = (char **)malloc(len); + if (!temp) goto no_IP_space; + TcpSt = temp; TcpNstates = nn; TcpStAlloc = al; } @@ -703,17 +718,24 @@ void enter_IPstate(struct lsof_context *ctx, char *ty, /* type -- TCP or UDP */ dup_IP_state: - (void)fprintf( - stderr, "%s: duplicate %s state %d (already %s): %s\n", Pn, ty, - nr, tx ? UdpSt[nr + UdpStOff] : TcpSt[nr + TcpStOff], nm); + if (ctx->err) + (void)fprintf( + ctx->err, "%s: duplicate %s state %d (already %s): %s\n", + Pn, ty, nr, + tx ? UdpSt[nr + UdpStOff] : TcpSt[nr + TcpStOff], nm); Error(ctx); + goto cleanup; } UdpSt[nr + UdpStOff] = cp; + cp = NULL; } else { if (TcpSt[nr + TcpStOff]) goto dup_IP_state; TcpSt[nr + TcpStOff] = cp; + cp = NULL; } +cleanup: + CLEAN(cp); #endif /* defined(USE_LIB_PRINT_TCPTPI) */ } @@ -727,9 +749,11 @@ void enter_nm(struct lsof_context *ctx, char *m) { if (!m || *m == '\0') return; if (!(mp = mkstrcpy(m, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no more nm space at PID %d for: ", Pn, - Lp->pid); - safestrprt(m, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no more nm space at PID %d for: ", Pn, + Lp->pid); + safestrprt(m, ctx->err, 1); + } Error(ctx); } if (Lf->nm) @@ -737,34 +761,13 @@ void enter_nm(struct lsof_context *ctx, char *m) { Lf->nm = mp; } -/* - * Exit() - do a clean exit() - */ - -void Exit(struct lsof_context *ctx, enum ExitStatus xv) /* exit() value */ -{ - (void)childx(ctx); - -#if defined(HASDCACHE) - if (DCrebuilt && !Fwarn) - (void)fprintf(stderr, "%s: WARNING: %s was updated.\n", Pn, - DCpath[DCpathX]); -#endif /* defined(HASDCACHE) */ - - exit(xv); -} - -/* - * Error() - exit with an error status - */ -void Error(struct lsof_context *ctx) { Exit(ctx, LSOF_ERROR); } - #if defined(HASNLIST) /* * get_Nl_value() - get Nl value for nickname */ -int get_Nl_value(char *nn, /* nickname of requested entry */ +int get_Nl_value(struct lsof_context *ctx, + char *nn, /* nickname of requested entry */ struct drive_Nl *d, /* drive_Nl table that built Nl * (if NULL, use Build_Nl) */ KA_T *v) /* returned value (if NULL, @@ -824,7 +827,8 @@ int hashbyname(char *nm, /* pointer to NUL-terminated name */ * is_nw_addr() - is this network address selected? */ -int is_nw_addr(unsigned char *ia, /* Internet address */ +int is_nw_addr(struct lsof_context *ctx, + unsigned char *ia, /* Internet address */ int p, /* port */ int af) /* address family -- e.g., AF_INET, * AF_INET6 */ @@ -835,7 +839,7 @@ int is_nw_addr(unsigned char *ia, /* Internet address */ return (0); for (; n; n = n->next) { if (n->proto) { - if (strcasecmp(n->proto, Lf->iproto) != 0) + if (n->proto != Lf->iproto) continue; } if (af && n->af && af != n->af) @@ -967,12 +971,12 @@ char *mkstrcat(char *s1, /* source string 1 */ * is_readable() -- is file readable */ -int is_readable(char *path, /* file path */ - int msg) /* issue warning message if 1 */ +int is_readable(struct lsof_context *ctx, char *path, /* file path */ + int msg) /* issue warning message if 1 */ { if (access(path, R_OK) < 0) { - if (!Fwarn && msg == 1) - (void)fprintf(stderr, ACCESSERRFMT, Pn, path, strerror(errno)); + if (ctx->err && !Fwarn && msg == 1) + (void)fprintf(ctx->err, ACCESSERRFMT, Pn, path, strerror(errno)); return (0); } return (1); @@ -986,65 +990,43 @@ int lstatsafely(struct lsof_context *ctx, char *path, /* file path */ struct stat *buf) /* stat buffer address */ { if (Fblock) { - if (!Fwarn) - (void)fprintf(stderr, "%s: avoiding stat(%s): -b was specified.\n", - Pn, path); + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, + "%s: avoiding stat(%s): -b was specified.\n", Pn, + path); errno = EWOULDBLOCK; return (1); } return (doinchild(ctx, dolstat, path, (char *)buf, sizeof(struct stat))); } -/* - * Readlink() - read and interpret file system symbolic links - */ - -char *Readlink(struct lsof_context *ctx, - char *arg) /* argument to be interpreted */ -{ +/* internal recursive function */ +char *readlink_inner(struct lsof_context *ctx, + char *arg, /* argument to be interpreted */ + char *orig_path, int recursion_depth) { char abuf[MAXPATHLEN + 1]; int alen; char *ap; char *argp1, *argp2; int i, len, llen, slen; char lbuf[MAXPATHLEN + 1]; - static char *op = (char *)NULL; - static int ss = 0; - char *s1; - static char **stk = (char **)NULL; - static int sx = 0; char tbuf[MAXPATHLEN + 1]; - /* - * See if avoiding kernel blocks. - */ - if (Fblock) { - if (!Fwarn) { - (void)fprintf(stderr, "%s: avoiding readlink(", Pn); - safestrprt(arg, stderr, 0); - (void)fprintf(stderr, "): -b was specified.\n"); - } - op = (char *)NULL; - return (arg); - } - /* - * Save the original path. - */ - if (!op) - op = arg; + char *s1; + char *res; /* * Evaluate each component of the argument for a symbolic link. */ + abuf[0] = '\0'; for (alen = 0, ap = abuf, argp1 = argp2 = arg; *argp2; argp1 = argp2) { for (argp2 = argp1 + 1; *argp2 && *argp2 != '/'; argp2++) ; if ((len = argp2 - arg) >= (int)sizeof(tbuf)) { path_too_long: - if (!Fwarn) { - (void)fprintf(stderr, "%s: readlink() path too long: ", Pn); - safestrprt(op ? op : arg, stderr, 1); + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: readlink() path too long: ", Pn); + safestrprt(orig_path, ctx->err, 1); } - op = (char *)NULL; return ((char *)NULL); } (void)strncpy(tbuf, arg, len); @@ -1117,68 +1099,51 @@ char *Readlink(struct lsof_context *ctx, alen += (llen + slen - 1); } /* - * If the assembled path and argument are the same, free all but the - * last string in the stack, and return the argument. + * If the assembled path and argument are the same return the argument. */ if (strcmp(arg, abuf) == 0) { - for (i = 0; i < sx; i++) { - if (i < (sx - 1)) - (void)free((FREE_P *)stk[i]); - stk[i] = (char *)NULL; - } - sx = 0; - op = (char *)NULL; - return (arg); + return mkstrcpy(arg, NULL); } /* - * If the assembled path and argument are different, add it to the - * string stack, then Readlink() it. + * If the assembled path and argument are different, readlink_inner() it. */ - if (!(s1 = mkstrcpy(abuf, (MALLOC_S *)NULL))) { - - no_readlink_space: - - (void)fprintf(stderr, "%s: no Readlink string space for ", Pn); - safestrprt(abuf, stderr, 1); - Error(ctx); - } - if (sx >= MAXSYMLINKS) { - + if (recursion_depth >= MAXSYMLINKS) { /* * If there are too many symbolic links, report an error, clear * the stack, and return no path. */ - if (!Fwarn) { + if (ctx->err && !Fwarn) { (void)fprintf( - stderr, + ctx->err, "%s: too many (> %d) symbolic links in readlink() path: ", Pn, MAXSYMLINKS); - safestrprt(op ? op : arg, stderr, 1); - } - for (i = 0; i < sx; i++) { - (void)free((FREE_P *)stk[i]); - stk[i] = (char *)NULL; + safestrprt(orig_path, ctx->err, 1); } - (void)free((FREE_P *)stk); - (void)free((FREE_P *)s1); - stk = (char **)NULL; - ss = sx = 0; - s1 = (char *)NULL; - op = (char *)NULL; return ((char *)NULL); } - if (++sx > ss) { - if (!stk) - stk = (char **)malloc((MALLOC_S)(sizeof(char *) * sx)); - else - stk = (char **)realloc((MALLOC_P *)stk, - (MALLOC_S)(sizeof(char *) * sx)); - if (!stk) - goto no_readlink_space; - ss = sx; + return (readlink_inner(ctx, abuf, orig_path, recursion_depth)); +} + +/* + * Readlink() - read and interpret file system symbolic links + * + * caller should free() the return value if non-NULL + */ +char *Readlink(struct lsof_context *ctx, + char *arg) /* argument to be interpreted */ +{ + /* + * See if avoiding kernel blocks. + */ + if (Fblock) { + if (ctx->err && !Fwarn) { + (void)fprintf(ctx->err, "%s: avoiding readlink(", Pn); + safestrprt(arg, ctx->err, 0); + (void)fprintf(ctx->err, "): -b was specified.\n"); + } + return mkstrcpy(arg, NULL); } - stk[sx - 1] = s1; - return (Readlink(ctx, s1)); + return readlink_inner(ctx, arg, arg, 0); } #if defined(HASSTREAMS) @@ -1186,9 +1151,9 @@ char *Readlink(struct lsof_context *ctx, * readstdata() - read stream's stdata structure */ -int readstdata(struct lsof_context *ctx, /* context */ - KA_T addr, /* stdata address in kernel*/ - struct stdata *buf) /* buffer addess */ +int readstdata(struct lsof_context *ctx, + KA_T addr, /* stdata address in kernel*/ + struct stdata *buf) /* buffer addess */ { if (!addr || kread(ctx, addr, (char *)buf, sizeof(struct stdata))) { (void)snpf(Namech, Namechl, "no stream data in %s", @@ -1202,9 +1167,9 @@ int readstdata(struct lsof_context *ctx, /* context */ * readsthead() - read stream head */ -int readsthead(struct lsof_context *ctx, /* context */ - KA_T addr, /* starting queue pointer in kernel */ - struct queue *buf) /* buffer for queue head */ +int readsthead(struct lsof_context *ctx, + KA_T addr, /* starting queue pointer in kernel */ + struct queue *buf) /* buffer for queue head */ { KA_T qp; @@ -1226,10 +1191,10 @@ int readsthead(struct lsof_context *ctx, /* context */ * readstidnm() - read stream module ID name */ -int readstidnm(struct lsof_context *ctx, /* context */ - KA_T addr, /* module ID name address in kernel */ - char *buf, /* receiving buffer address */ - READLEN_T len) /* buffer length */ +int readstidnm(struct lsof_context *ctx, + KA_T addr, /* module ID name address in kernel */ + char *buf, /* receiving buffer address */ + READLEN_T len) /* buffer length */ { if (!addr || kread(ctx, addr, buf, len)) { (void)snpf(Namech, Namechl, "can't read module ID name from %s", @@ -1243,9 +1208,9 @@ int readstidnm(struct lsof_context *ctx, /* context */ * readstmin() - read stream's module info */ -int readstmin(struct lsof_context *ctx, /* context */ - KA_T addr, /* module info address in kernel */ - struct module_info *buf) /* receiving buffer address */ +int readstmin(struct lsof_context *ctx, + KA_T addr, /* module info address in kernel */ + struct module_info *buf) /* receiving buffer address */ { if (!addr || kread(ctx, addr, (char *)buf, sizeof(struct module_info))) { (void)snpf(Namech, Namechl, "can't read module info from %s", @@ -1259,9 +1224,9 @@ int readstmin(struct lsof_context *ctx, /* context */ * readstqinit() - read stream's queue information structure */ -int readstqinit(struct lsof_context *ctx, /* context */ - KA_T addr, /* queue info address in kernel */ - struct qinit *buf) /* receiving buffer address */ +int readstqinit(struct lsof_context *ctx, + KA_T addr, /* queue info address in kernel */ + struct qinit *buf) /* receiving buffer address */ { if (!addr || kread(ctx, addr, (char *)buf, sizeof(struct qinit))) { (void)snpf(Namech, Namechl, "can't read queue info from %s", @@ -1496,9 +1461,10 @@ int statsafely(struct lsof_context *ctx, char *path, /* file path */ struct stat *buf) /* stat buffer address */ { if (Fblock) { - if (!Fwarn) - (void)fprintf(stderr, "%s: avoiding stat(%s): -b was specified.\n", - Pn, path); + if (!Fwarn && ctx->err) + (void)fprintf(ctx->err, + "%s: avoiding stat(%s): -b was specified.\n", Pn, + path); errno = EWOULDBLOCK; return (1); } @@ -1523,8 +1489,11 @@ void stkdir(struct lsof_context *ctx, char *p) /* directory path */ else Dstk = (char **)realloc((MALLOC_P *)Dstk, len); if (!Dstk) { - (void)fprintf(stderr, "%s: no space for directory stack at: ", Pn); - safestrprt(p, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: no space for directory stack at: ", Pn); + safestrprt(p, ctx->err, 1); + } Error(ctx); } } @@ -1533,8 +1502,10 @@ void stkdir(struct lsof_context *ctx, char *p) /* directory path */ * stack. */ if (!(Dstk[Dstkx] = mkstrcpy(p, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for: ", Pn); - safestrprt(p, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no space for: ", Pn); + safestrprt(p, ctx->err, 1); + } Error(ctx); } Dstkx++; @@ -1601,3 +1572,21 @@ char *x2dev(char *s, /* ASCII string */ *d = r; return (s); } + +#if defined(WILLDROPGID) +/* + * dropgid() - drop setgid permission + */ + +void dropgid(struct lsof_context *ctx) { + if (!Setuidroot && Setgid) { + if (setgid(Mygid) < 0) { + if (ctx->err) + (void)fprintf(ctx->err, "%s: can't setgid(%d): %s\n", Pn, + (int)Mygid, strerror(errno)); + Error(ctx); + } + Setgid = 0; + } +} +#endif /* defined(WILLDROPGID) */ \ No newline at end of file diff --git a/lib/node.c b/lib/node.c index be2df866..408483d0 100644 --- a/lib/node.c +++ b/lib/node.c @@ -30,30 +30,16 @@ #include "common.h" -/* - * print_kptr() - print kernel pointer - */ - -char *print_kptr(KA_T kp, /* kernel pointer address */ - char *buf, /* optional destination buffer */ - size_t bufl) /* size of buf[] */ -{ - static char dbuf[32]; - - (void)snpf(buf ? buf : dbuf, buf ? bufl : sizeof(dbuf), KA_T_FMT_X, kp); - return (buf ? buf : dbuf); -} - #if defined(HASCDRNODE) /* * readcdrnode() - read CD-ROM node */ -int readcdrnode(struct lsof_context *ctx, /* context */ - KA_T ca, /* cdrnode kernel address */ - struct cdrnode *c) /* cdrnode buffer */ +int readcdrnode(ca, c) +KA_T ca; /* cdrnode kernel address */ +struct cdrnode *c; /* cdrnode buffer */ { - if (kread(ctx, (KA_T)ca, (char *)c, sizeof(struct cdrnode))) { + if (kread((KA_T)ca, (char *)c, sizeof(struct cdrnode))) { (void)snpf(Namech, Namechl, "can't read cdrnode at %s", print_kptr(ca, (char *)NULL, 0)); return (1); @@ -67,9 +53,9 @@ int readcdrnode(struct lsof_context *ctx, /* context */ * readfifonode() - read fifonode */ -int readfifonode(struct lsof_context *ctx, /* context */ - KA_T fa, /* fifonode kernel address */ - struct fifonode *f) /* fifonode buffer */ +int readfifonode(struct lsof_context *ctx, + KA_T fa, /* fifonode kernel address */ + struct fifonode *f) /* fifonode buffer */ { if (kread(ctx, (KA_T)fa, (char *)f, sizeof(struct fifonode))) { (void)snpf(Namech, Namechl, "can't read fifonode at %s", @@ -85,11 +71,11 @@ int readfifonode(struct lsof_context *ctx, /* context */ * readgnode() - read gnode */ -int readgnode(struct lsof_context *ctx, /* context */ - KA_T ga, /* gnode kernel address */ - struct gnode *g) /* gnode buffer */ +int readgnode(ga, g) +KA_T ga; /* gnode kernel address */ +struct gnode *g; /* gnode buffer */ { - if (kread(ctx, (KA_T)ga, (char *)g, sizeof(struct gnode))) { + if (kread((KA_T)ga, (char *)g, sizeof(struct gnode))) { (void)snpf(Namech, Namechl, "can't read gnode at %s", print_kptr(ga, (char *)NULL, 0)); return (1); @@ -103,9 +89,8 @@ int readgnode(struct lsof_context *ctx, /* context */ * readhsnode() - read High Sierra file system node */ -int readhsnode(struct lsof_context *ctx, /* context */ - KA_T ha, /* hsnode kernel address */ - struct hsnode *h) /* hsnode buffer */ +int readhsnode(struct lsof_context *ctx, KA_T ha, /* hsnode kernel address */ + struct hsnode *h) /* hsnode buffer */ { if (kread(ctx, (KA_T)ha, (char *)h, sizeof(struct hsnode))) { (void)snpf(Namech, Namechl, "can't read hsnode at %s", @@ -121,9 +106,8 @@ int readhsnode(struct lsof_context *ctx, /* context */ * readinode() - read inode */ -int readinode(struct lsof_context *ctx, /* context */ - KA_T ia, /* inode kernel address */ - struct inode *i) /* inode buffer */ +int readinode(struct lsof_context *ctx, KA_T ia, /* inode kernel address */ + struct inode *i) /* inode buffer */ { if (kread(ctx, (KA_T)ia, (char *)i, sizeof(struct inode))) { (void)snpf(Namech, Namechl, "can't read inode at %s", @@ -139,11 +123,11 @@ int readinode(struct lsof_context *ctx, /* context */ * readpipenode() - read pipe node */ -int readpipenode(struct lsof_context *ctx, /* context */ - KA_T pa, /* pipe node kernel address */ - struct pipenode *p) /* pipe node buffer */ +int readpipenode(pa, p) +KA_T pa; /* pipe node kernel address */ +struct pipenode *p; /* pipe node buffer */ { - if (kread(ctx, (KA_T)pa, (char *)p, sizeof(struct pipenode))) { + if (kread((KA_T)pa, (char *)p, sizeof(struct pipenode))) { (void)snpf(Namech, Namechl, "can't read pipenode at %s", print_kptr(pa, (char *)NULL, 0)); return (1); @@ -157,9 +141,9 @@ int readpipenode(struct lsof_context *ctx, /* context */ * readrnode() - read rnode */ -int readrnode(struct lsof_context *ctx, /* context */ - KA_T ra, /* rnode kernel space address */ - struct rnode *r) /* rnode buffer pointer */ +int readrnode(struct lsof_context *ctx, + KA_T ra, /* rnode kernel space address */ + struct rnode *r) /* rnode buffer pointer */ { if (kread(ctx, (KA_T)ra, (char *)r, sizeof(struct rnode))) { (void)snpf(Namech, Namechl, "can't read rnode at %s", @@ -175,9 +159,9 @@ int readrnode(struct lsof_context *ctx, /* context */ * readsnode() - read snode */ -int readsnode(struct lsof_context *ctx, /* context */ - KA_T sa, /* snode kernel space address */ - struct snode *s) /* snode buffer pointer */ +int readsnode(struct lsof_context *ctx, + KA_T sa, /* snode kernel space address */ + struct snode *s) /* snode buffer pointer */ { if (kread(ctx, (KA_T)sa, (char *)s, sizeof(struct snode))) { (void)snpf(Namech, Namechl, "can't read snode at %s", @@ -193,9 +177,9 @@ int readsnode(struct lsof_context *ctx, /* context */ * readtnode() - read tmpnode */ -int readtnode(struct lsof_context *ctx, /* context */ - KA_T ta, /* tmpnode kernel space address */ - struct tmpnode *t) /* tmpnode buffer pointer */ +int readtnode(struct lsof_context *ctx, + KA_T ta, /* tmpnode kernel space address */ + struct tmpnode *t) /* tmpnode buffer pointer */ { if (kread(ctx, (KA_T)ta, (char *)t, sizeof(struct tmpnode))) { (void)snpf(Namech, Namechl, "can't read tmpnode at %s", @@ -204,22 +188,4 @@ int readtnode(struct lsof_context *ctx, /* context */ } return (0); } -#endif /* defined(HASTMPNODE) */ - -#if defined(HASVNODE) -/* - * readvnode() - read vnode - */ - -int readvnode(struct lsof_context *ctx, /* context */ - KA_T va, /* vnode kernel space address */ - struct vnode *v) /* vnode buffer pointer */ -{ - if (kread(ctx, (KA_T)va, (char *)v, sizeof(struct vnode))) { - (void)snpf(Namech, Namechl, "can't read vnode at %s", - print_kptr(va, (char *)NULL, 0)); - return (1); - } - return (0); -} -#endif /* defined(HASVNODE) */ +#endif /* defined(HASTMPNODE) */ \ No newline at end of file diff --git a/lib/pdvn.c b/lib/pdvn.c index d553f673..409a00fa 100644 --- a/lib/pdvn.c +++ b/lib/pdvn.c @@ -34,8 +34,6 @@ #if defined(USE_LIB_PRINTDEVNAME) #else /* !defined(USE_LIB_PRINTDEVNAME) */ -char pdvn_d1[] = "d"; -char *pdvn_d2 = pdvn_d1; #endif /* defined(USE_LIB_PRINTDEVNAME) */ /* @@ -141,8 +139,9 @@ int printdevname(struct lsof_context *ctx, dev_t *dev, /* device */ ttl = (nty == N_BLK) ? LIKE_BLK_SPEC : LIKE_CHR_SPEC; len = (int)(1 + strlen(ttl) + 1 + strlen(dp->name) + 1); if (!(cp = (char *)malloc((MALLOC_S)(len + 1)))) { - (void)fprintf(stderr, "%s: no nma space for: (%s %s)\n", Pn, ttl, - dp->name); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no nma space for: (%s %s)\n", Pn, + ttl, dp->name); Error(ctx); } (void)snpf(cp, len + 1, "(%s %s)", ttl, dp->name); diff --git a/lib/prfp.c b/lib/prfp.c index 6e573911..9679e970 100644 --- a/lib/prfp.c +++ b/lib/prfp.c @@ -71,7 +71,6 @@ void process_file(struct lsof_context *ctx, return; } Lf->off = (SZOFFTYPE)f.f_offset; - Lf->off_def = 1; if (f.f_count) { /* @@ -90,23 +89,31 @@ void process_file(struct lsof_context *ctx, */ # if !defined(HASNOFSCOUNT) - Lf->fct = (long)f.f_count; - Lf->fsv |= FSV_CT; + if (FSV_CT) { + Lf->fct = (long)f.f_count; + Lf->fsv |= FSV_CT; + } # endif /* !defined(HASNOFSCOUNT) */ # if !defined(HASNOFSADDR) - Lf->fsa = fp; - Lf->fsv |= FSV_FA; + if (FSV_FA) { + Lf->fsa = fp; + Lf->fsv |= FSV_FA; + } # endif /* !defined(HASNOFSADDR) */ # if !defined(HASNOFSFLAGS) - Lf->ffg = (long)f.f_flag; - Lf->fsv |= FSV_FG; + if (FSV_FG) { + Lf->ffg = (long)f.f_flag; + Lf->fsv |= FSV_FG; + } # endif /* !defined(HASNOFSFLAGS) */ # if !defined(HASNOFSNADDR) - Lf->fna = (KA_T)f.f_data; - Lf->fsv |= FSV_NI; + if (FSV_NI) { + Lf->fna = (KA_T)f.f_data; + Lf->fsv |= FSV_NI; + } # endif /* !defined(HASNOFSNADDR) */ # endif /* defined(HASFSTRUCT) */ @@ -127,7 +134,7 @@ void process_file(struct lsof_context *ctx, # if defined(DTYPE_PTS) case DTYPE_PTS: # if defined(HASPTSFN) - HASPTSFN(ctx, (KA_T)f.f_data); + HASPTSFN((KA_T)f.f_data); # endif /* defined(HASPTSFN) */ return; # endif /* defined(DTYPE_PIPE) */ @@ -171,19 +178,19 @@ void process_file(struct lsof_context *ctx, # if defined(HASPSXSEM) case DTYPE_PSXSEM: - process_psxsem(ctx, (KA_T)f.f_data); + process_psxsem((KA_T)f.f_data); return; # endif /* defined(HASPSXSEM) */ # if defined(HASPSXSHM) case DTYPE_PSXSHM: - process_psxshm(ctx, (KA_T)f.f_data); + process_psxshm((KA_T)f.f_data); return; # endif /* defined(HASPSXSHM) */ # if defined(HASPRIVFILETYPE) case PRIVFILETYPE: - HASPRIVFILETYPE(ctx, (KA_T)f.f_data); + HASPRIVFILETYPE((KA_T)f.f_data); return; # endif /* defined(HASPRIVFILETYPE) */ @@ -210,7 +217,4 @@ void process_file(struct lsof_context *ctx, } enter_nm(ctx, "no more information"); } -#else /* !defined(USE_LIB_PROCESS_FILE) */ -char prfp_d1[] = "d"; -char *prfp_d2 = prfp_d1; #endif /* defined(USE_LIB_PROCESS_FILE) */ diff --git a/lib/print.c b/lib/print.c index d9f37dec..aa5e2c5a 100644 --- a/lib/print.c +++ b/lib/print.c @@ -36,9 +36,1033 @@ */ /* - * access_to_char() - convert enum lsof_file_access_mode to char + * endnm() - locate end of Namech */ -char access_to_char(enum lsof_file_access_mode access) { + +char *endnm(struct lsof_context *ctx, size_t *sz) /* returned remaining size */ +{ + register char *s; + register size_t tsz; + + for (s = Namech, tsz = Namechl; *s; s++, tsz--) + ; + *sz = tsz; + return (s); +} + +/* + * print_kptr() - print kernel pointer + */ + +char *print_kptr(KA_T kp, /* kernel pointer address */ + char *buf, /* optional destination buffer */ + size_t bufl) /* size of buf[] */ +{ + static char dbuf[32]; + + (void)snpf(buf ? buf : dbuf, buf ? bufl : sizeof(dbuf), KA_T_FMT_X, kp); + return (buf ? buf : dbuf); +} + +/* + * enter_ip_proto() - set iproto from IP protocol + */ + +void enter_ip_proto(struct lsof_context *ctx, int p) /* protocol number */ +{ + switch (p) { + +#if defined(IPPROTO_TCP) + case IPPROTO_TCP: + Lf->iproto = LSOF_PROTOCOL_TCP; + break; +#endif /* defined(IPPROTO_TCP) */ + +#if defined(IPPROTO_UDP) + case IPPROTO_UDP: + Lf->iproto = LSOF_PROTOCOL_UDP; + break; +#endif /* defined(IPPROTO_UDP) */ + +#if defined(IPPROTO_IP) +# if !defined(IPPROTO_HOPOPTS) || IPPROTO_IP != IPPROTO_HOPOPTS + case IPPROTO_IP: + Lf->iproto = LSOF_PROTOCOL_IP; + break; +# endif /* !defined(IPPROTO_HOPOPTS) || IPPROTO_IP!=IPPROTO_HOPOPTS */ +#endif /* defined(IPPROTO_IP) */ + +#if defined(IPPROTO_ICMP) + case IPPROTO_ICMP: + Lf->iproto = LSOF_PROTOCOL_ICMP; + break; +#endif /* defined(IPPROTO_ICMP) */ + +#if defined(IPPROTO_ICMPV6) + case IPPROTO_ICMPV6: + Lf->iproto = LSOF_PROTOCOL_ICMPV6; + break; +#endif /* defined(IPPROTO_ICMPV6) */ + +#if defined(IPPROTO_IGMP) + case IPPROTO_IGMP: + Lf->iproto = LSOF_PROTOCOL_IGMP; + break; +#endif /* defined(IPPROTO_IGMP) */ + +#if defined(IPPROTO_GGP) + case IPPROTO_GGP: + Lf->iproto = LSOF_PROTOCOL_GGP; + break; +#endif /* defined(IPPROTO_GGP) */ + +#if defined(IPPROTO_EGP) + case IPPROTO_EGP: + Lf->iproto = LSOF_PROTOCOL_EGP; + break; +#endif /* defined(IPPROTO_EGP) */ + +#if defined(IPPROTO_PUP) + case IPPROTO_PUP: + Lf->iproto = LSOF_PROTOCOL_PUP; + break; +#endif /* defined(IPPROTO_PUP) */ + +#if defined(IPPROTO_IDP) + case IPPROTO_IDP: + Lf->iproto = LSOF_PROTOCOL_IDP; + break; +#endif /* defined(IPPROTO_IDP) */ + +#if defined(IPPROTO_ND) + case IPPROTO_ND: + Lf->iproto = LSOF_PROTOCOL_ND; + break; +#endif /* defined(IPPROTO_ND) */ + +#if defined(IPPROTO_RAW) + case IPPROTO_RAW: + Lf->iproto = LSOF_PROTOCOL_RAW; + break; +#endif /* defined(IPPROTO_RAW) */ + +#if defined(IPPROTO_HELLO) + case IPPROTO_HELLO: + Lf->iproto = LSOF_PROTOCOL_HELLO; + break; +#endif /* defined(IPPROTO_HELLO) */ + +#if defined(IPPROTO_PXP) + case IPPROTO_PXP: + Lf->iproto = LSOF_PROTOCOL_PXP; + break; +#endif /* defined(IPPROTO_PXP) */ + +#if defined(IPPROTO_RAWIP) + case IPPROTO_RAWIP: + Lf->iproto = LSOF_PROTOCOL_RAWIP; + break; +#endif /* defined(IPPROTO_RAWIP) */ + +#if defined(IPPROTO_RAWIF) + case IPPROTO_RAWIF: + Lf->iproto = LSOF_PROTOCOL_RAWIF; + break; +#endif /* defined(IPPROTO_RAWIF) */ + +#if defined(IPPROTO_HOPOPTS) + case IPPROTO_HOPOPTS: + Lf->iproto = LSOF_PROTOCOL_HOPOPTS; + break; +#endif /* defined(IPPROTO_HOPOPTS) */ + +#if defined(IPPROTO_IPIP) + case IPPROTO_IPIP: + Lf->iproto = LSOF_PROTOCOL_IPIP; + break; +#endif /* defined(IPPROTO_IPIP) */ + +#if defined(IPPROTO_ST) + case IPPROTO_ST: + Lf->iproto = LSOF_PROTOCOL_ST; + break; +#endif /* defined(IPPROTO_ST) */ + +#if defined(IPPROTO_PIGP) + case IPPROTO_PIGP: + Lf->iproto = LSOF_PROTOCOL_PIGP; + break; +#endif /* defined(IPPROTO_PIGP) */ + +#if defined(IPPROTO_RCCMON) + case IPPROTO_RCCMON: + Lf->iproto = LSOF_PROTOCOL_RCCMON; + break; +#endif /* defined(IPPROTO_RCCMON) */ + +#if defined(IPPROTO_NVPII) + case IPPROTO_NVPII: + Lf->iproto = LSOF_PROTOCOL_NVPII; + break; +#endif /* defined(IPPROTO_NVPII) */ + +#if defined(IPPROTO_ARGUS) + case IPPROTO_ARGUS: + Lf->iproto = LSOF_PROTOCOL_ARGUS; + break; +#endif /* defined(IPPROTO_ARGUS) */ + +#if defined(IPPROTO_EMCON) + case IPPROTO_EMCON: + Lf->iproto = LSOF_PROTOCOL_EMCON; + break; +#endif /* defined(IPPROTO_EMCON) */ + +#if defined(IPPROTO_XNET) + case IPPROTO_XNET: + Lf->iproto = LSOF_PROTOCOL_XNET; + break; +#endif /* defined(IPPROTO_XNET) */ + +#if defined(IPPROTO_CHAOS) + case IPPROTO_CHAOS: + Lf->iproto = LSOF_PROTOCOL_CHAOS; + break; +#endif /* defined(IPPROTO_CHAOS) */ + +#if defined(IPPROTO_MUX) + case IPPROTO_MUX: + Lf->iproto = LSOF_PROTOCOL_MUX; + break; +#endif /* defined(IPPROTO_MUX) */ + +#if defined(IPPROTO_MEAS) + case IPPROTO_MEAS: + Lf->iproto = LSOF_PROTOCOL_MEAS; + break; +#endif /* defined(IPPROTO_MEAS) */ + +#if defined(IPPROTO_HMP) + case IPPROTO_HMP: + Lf->iproto = LSOF_PROTOCOL_HMP; + break; +#endif /* defined(IPPROTO_HMP) */ + +#if defined(IPPROTO_PRM) + case IPPROTO_PRM: + Lf->iproto = LSOF_PROTOCOL_PRM; + break; +#endif /* defined(IPPROTO_PRM) */ + +#if defined(IPPROTO_TRUNK1) + case IPPROTO_TRUNK1: + Lf->iproto = LSOF_PROTOCOL_TRUNK1; + break; +#endif /* defined(IPPROTO_TRUNK1) */ + +#if defined(IPPROTO_TRUNK2) + case IPPROTO_TRUNK2: + Lf->iproto = LSOF_PROTOCOL_TRUNK2; + break; +#endif /* defined(IPPROTO_TRUNK2) */ + +#if defined(IPPROTO_LEAF1) + case IPPROTO_LEAF1: + Lf->iproto = LSOF_PROTOCOL_LEAF1; + break; +#endif /* defined(IPPROTO_LEAF1) */ + +#if defined(IPPROTO_LEAF2) + case IPPROTO_LEAF2: + Lf->iproto = LSOF_PROTOCOL_LEAF2; + break; +#endif /* defined(IPPROTO_LEAF2) */ + +#if defined(IPPROTO_RDP) + case IPPROTO_RDP: + Lf->iproto = LSOF_PROTOCOL_RDP; + break; +#endif /* defined(IPPROTO_RDP) */ + +#if defined(IPPROTO_IRTP) + case IPPROTO_IRTP: + Lf->iproto = LSOF_PROTOCOL_IRTP; + break; +#endif /* defined(IPPROTO_IRTP) */ + +#if defined(IPPROTO_TP) + case IPPROTO_TP: + Lf->iproto = LSOF_PROTOCOL_TP; + break; +#endif /* defined(IPPROTO_TP) */ + +#if defined(IPPROTO_BLT) + case IPPROTO_BLT: + Lf->iproto = LSOF_PROTOCOL_BLT; + break; +#endif /* defined(IPPROTO_BLT) */ + +#if defined(IPPROTO_NSP) + case IPPROTO_NSP: + Lf->iproto = LSOF_PROTOCOL_NSP; + break; +#endif /* defined(IPPROTO_NSP) */ + +#if defined(IPPROTO_INP) + case IPPROTO_INP: + Lf->iproto = LSOF_PROTOCOL_INP; + break; +#endif /* defined(IPPROTO_INP) */ + +#if defined(IPPROTO_SEP) + case IPPROTO_SEP: + Lf->iproto = LSOF_PROTOCOL_SEP; + break; +#endif /* defined(IPPROTO_SEP) */ + +#if defined(IPPROTO_3PC) + case IPPROTO_3PC: + Lf->iproto = LSOF_PROTOCOL_3PC; + break; +#endif /* defined(IPPROTO_3PC) */ + +#if defined(IPPROTO_IDPR) + case IPPROTO_IDPR: + Lf->iproto = LSOF_PROTOCOL_IDPR; + break; +#endif /* defined(IPPROTO_IDPR) */ + +#if defined(IPPROTO_XTP) + case IPPROTO_XTP: + Lf->iproto = LSOF_PROTOCOL_XTP; + break; +#endif /* defined(IPPROTO_XTP) */ + +#if defined(IPPROTO_DDP) + case IPPROTO_DDP: + Lf->iproto = LSOF_PROTOCOL_DDP; + break; +#endif /* defined(IPPROTO_DDP) */ + +#if defined(IPPROTO_CMTP) + case IPPROTO_CMTP: + Lf->iproto = LSOF_PROTOCOL_CMTP; + break; +#endif /* defined(IPPROTO_CMTP) */ + +#if defined(IPPROTO_TPXX) + case IPPROTO_TPXX: + Lf->iproto = LSOF_PROTOCOL_TPXX; + break; +#endif /* defined(IPPROTO_TPXX) */ + +#if defined(IPPROTO_IL) + case IPPROTO_IL: + Lf->iproto = LSOF_PROTOCOL_IL; + break; +#endif /* defined(IPPROTO_IL) */ + +#if defined(IPPROTO_IPV6) + case IPPROTO_IPV6: + Lf->iproto = LSOF_PROTOCOL_IPV6; + break; +#endif /* defined(IPPROTO_IPV6) */ + +#if defined(IPPROTO_SDRP) + case IPPROTO_SDRP: + Lf->iproto = LSOF_PROTOCOL_SDRP; + break; +#endif /* defined(IPPROTO_SDRP) */ + +#if defined(IPPROTO_ROUTING) + case IPPROTO_ROUTING: + Lf->iproto = LSOF_PROTOCOL_ROUTING; + break; +#endif /* defined(IPPROTO_ROUTING) */ + +#if defined(IPPROTO_FRAGMENT) + case IPPROTO_FRAGMENT: + Lf->iproto = LSOF_PROTOCOL_FRAGMENT; + break; +#endif /* defined(IPPROTO_FRAGMENT) */ + +#if defined(IPPROTO_IDRP) + case IPPROTO_IDRP: + Lf->iproto = LSOF_PROTOCOL_IDRP; + break; +#endif /* defined(IPPROTO_IDRP) */ + +#if defined(IPPROTO_RSVP) + case IPPROTO_RSVP: + Lf->iproto = LSOF_PROTOCOL_RSVP; + break; +#endif /* defined(IPPROTO_RSVP) */ + +#if defined(IPPROTO_GRE) + case IPPROTO_GRE: + Lf->iproto = LSOF_PROTOCOL_GRE; + break; +#endif /* defined(IPPROTO_GRE) */ + +#if defined(IPPROTO_MHRP) + case IPPROTO_MHRP: + Lf->iproto = LSOF_PROTOCOL_MHRP; + break; +#endif /* defined(IPPROTO_MHRP) */ + +#if defined(IPPROTO_BHA) + case IPPROTO_BHA: + Lf->iproto = LSOF_PROTOCOL_BHA; + break; +#endif /* defined(IPPROTO_BHA) */ + +#if defined(IPPROTO_ESP) + case IPPROTO_ESP: + Lf->iproto = LSOF_PROTOCOL_ESP; + break; +#endif /* defined(IPPROTO_ESP) */ + +#if defined(IPPROTO_AH) + case IPPROTO_AH: + Lf->iproto = LSOF_PROTOCOL_AH; + break; +#endif /* defined(IPPROTO_AH) */ + +#if defined(IPPROTO_INLSP) + case IPPROTO_INLSP: + Lf->iproto = LSOF_PROTOCOL_INLSP; + break; +#endif /* defined(IPPROTO_INLSP) */ + +#if defined(IPPROTO_SWIPE) + case IPPROTO_SWIPE: + Lf->iproto = LSOF_PROTOCOL_SWIPE; + break; +#endif /* defined(IPPROTO_SWIPE) */ + +#if defined(IPPROTO_NHRP) + case IPPROTO_NHRP: + Lf->iproto = LSOF_PROTOCOL_NHRP; + break; +#endif /* defined(IPPROTO_NHRP) */ + +#if defined(IPPROTO_NONE) + case IPPROTO_NONE: + Lf->iproto = LSOF_PROTOCOL_NONE; + break; +#endif /* defined(IPPROTO_NONE) */ + +#if defined(IPPROTO_DSTOPTS) + case IPPROTO_DSTOPTS: + Lf->iproto = LSOF_PROTOCOL_DSTOPTS; + break; +#endif /* defined(IPPROTO_DSTOPTS) */ + +#if defined(IPPROTO_AHIP) + case IPPROTO_AHIP: + Lf->iproto = LSOF_PROTOCOL_AHIP; + break; +#endif /* defined(IPPROTO_AHIP) */ + +#if defined(IPPROTO_CFTP) + case IPPROTO_CFTP: + Lf->iproto = LSOF_PROTOCOL_CFTP; + break; +#endif /* defined(IPPROTO_CFTP) */ + +#if defined(IPPROTO_SATEXPAK) + case IPPROTO_SATEXPAK: + Lf->iproto = LSOF_PROTOCOL_SATEXPAK; + break; +#endif /* defined(IPPROTO_SATEXPAK) */ + +#if defined(IPPROTO_KRYPTOLAN) + case IPPROTO_KRYPTOLAN: + Lf->iproto = LSOF_PROTOCOL_KRYPTOLAN; + break; +#endif /* defined(IPPROTO_KRYPTOLAN) */ + +#if defined(IPPROTO_RVD) + case IPPROTO_RVD: + Lf->iproto = LSOF_PROTOCOL_RVD; + break; +#endif /* defined(IPPROTO_RVD) */ + +#if defined(IPPROTO_IPPC) + case IPPROTO_IPPC: + Lf->iproto = LSOF_PROTOCOL_IPPC; + break; +#endif /* defined(IPPROTO_IPPC) */ + +#if defined(IPPROTO_ADFS) + case IPPROTO_ADFS: + Lf->iproto = LSOF_PROTOCOL_ADFS; + break; +#endif /* defined(IPPROTO_ADFS) */ + +#if defined(IPPROTO_SATMON) + case IPPROTO_SATMON: + Lf->iproto = LSOF_PROTOCOL_SATMON; + break; +#endif /* defined(IPPROTO_SATMON) */ + +#if defined(IPPROTO_VISA) + case IPPROTO_VISA: + Lf->iproto = LSOF_PROTOCOL_VISA; + break; +#endif /* defined(IPPROTO_VISA) */ + +#if defined(IPPROTO_IPCV) + case IPPROTO_IPCV: + Lf->iproto = LSOF_PROTOCOL_IPCV; + break; +#endif /* defined(IPPROTO_IPCV) */ + +#if defined(IPPROTO_CPNX) + case IPPROTO_CPNX: + Lf->iproto = LSOF_PROTOCOL_CPNX; + break; +#endif /* defined(IPPROTO_CPNX) */ + +#if defined(IPPROTO_CPHB) + case IPPROTO_CPHB: + Lf->iproto = LSOF_PROTOCOL_CPHB; + break; +#endif /* defined(IPPROTO_CPHB) */ + +#if defined(IPPROTO_WSN) + case IPPROTO_WSN: + Lf->iproto = LSOF_PROTOCOL_WSN; + break; +#endif /* defined(IPPROTO_WSN) */ + +#if defined(IPPROTO_PVP) + case IPPROTO_PVP: + Lf->iproto = LSOF_PROTOCOL_PVP; + break; +#endif /* defined(IPPROTO_PVP) */ + +#if defined(IPPROTO_BRSATMON) + case IPPROTO_BRSATMON: + Lf->iproto = LSOF_PROTOCOL_BRSATMON; + break; +#endif /* defined(IPPROTO_BRSATMON) */ + +#if defined(IPPROTO_WBMON) + case IPPROTO_WBMON: + Lf->iproto = LSOF_PROTOCOL_WBMON; + break; +#endif /* defined(IPPROTO_WBMON) */ + +#if defined(IPPROTO_WBEXPAK) + case IPPROTO_WBEXPAK: + Lf->iproto = LSOF_PROTOCOL_WBEXPAK; + break; +#endif /* defined(IPPROTO_WBEXPAK) */ + +#if defined(IPPROTO_EON) + case IPPROTO_EON: + Lf->iproto = LSOF_PROTOCOL_EON; + break; +#endif /* defined(IPPROTO_EON) */ + +#if defined(IPPROTO_VMTP) + case IPPROTO_VMTP: + Lf->iproto = LSOF_PROTOCOL_VMTP; + break; +#endif /* defined(IPPROTO_VMTP) */ + +#if defined(IPPROTO_SVMTP) + case IPPROTO_SVMTP: + Lf->iproto = LSOF_PROTOCOL_SVMTP; + break; +#endif /* defined(IPPROTO_SVMTP) */ + +#if defined(IPPROTO_VINES) + case IPPROTO_VINES: + Lf->iproto = LSOF_PROTOCOL_VINES; + break; +#endif /* defined(IPPROTO_VINES) */ + +#if defined(IPPROTO_TTP) + case IPPROTO_TTP: + Lf->iproto = LSOF_PROTOCOL_TTP; + break; +#endif /* defined(IPPROTO_TTP) */ + +#if defined(IPPROTO_IGP) + case IPPROTO_IGP: + Lf->iproto = LSOF_PROTOCOL_IGP; + break; +#endif /* defined(IPPROTO_IGP) */ + +#if defined(IPPROTO_DGP) + case IPPROTO_DGP: + Lf->iproto = LSOF_PROTOCOL_DGP; + break; +#endif /* defined(IPPROTO_DGP) */ + +#if defined(IPPROTO_TCF) + case IPPROTO_TCF: + Lf->iproto = LSOF_PROTOCOL_TCF; + break; +#endif /* defined(IPPROTO_TCF) */ + +#if defined(IPPROTO_IGRP) + case IPPROTO_IGRP: + Lf->iproto = LSOF_PROTOCOL_IGRP; + break; +#endif /* defined(IPPROTO_IGRP) */ + +#if defined(IPPROTO_OSPFIGP) + case IPPROTO_OSPFIGP: + Lf->iproto = LSOF_PROTOCOL_OSPFIGP; + break; +#endif /* defined(IPPROTO_OSPFIGP) */ + +#if defined(IPPROTO_SRPC) + case IPPROTO_SRPC: + Lf->iproto = LSOF_PROTOCOL_SRPC; + break; +#endif /* defined(IPPROTO_SRPC) */ + +#if defined(IPPROTO_LARP) + case IPPROTO_LARP: + Lf->iproto = LSOF_PROTOCOL_LARP; + break; +#endif /* defined(IPPROTO_LARP) */ + +#if defined(IPPROTO_MTP) + case IPPROTO_MTP: + Lf->iproto = LSOF_PROTOCOL_MTP; + break; +#endif /* defined(IPPROTO_MTP) */ + +#if defined(IPPROTO_AX25) + case IPPROTO_AX25: + Lf->iproto = LSOF_PROTOCOL_AX25; + break; +#endif /* defined(IPPROTO_AX25) */ + +#if defined(IPPROTO_IPEIP) + case IPPROTO_IPEIP: + Lf->iproto = LSOF_PROTOCOL_IPEIP; + break; +#endif /* defined(IPPROTO_IPEIP) */ + +#if defined(IPPROTO_MICP) + case IPPROTO_MICP: + Lf->iproto = LSOF_PROTOCOL_MICP; + break; +#endif /* defined(IPPROTO_MICP) */ + +#if defined(IPPROTO_SCCSP) + case IPPROTO_SCCSP: + Lf->iproto = LSOF_PROTOCOL_SCCSP; + break; +#endif /* defined(IPPROTO_SCCSP) */ + +#if defined(IPPROTO_ETHERIP) + case IPPROTO_ETHERIP: + Lf->iproto = LSOF_PROTOCOL_ETHERIP; + break; +#endif /* defined(IPPROTO_ETHERIP) */ + +#if defined(IPPROTO_ENCAP) +# if !defined(IPPROTO_IPIP) || IPPROTO_IPIP != IPPROTO_ENCAP + case IPPROTO_ENCAP: + Lf->iproto = LSOF_PROTOCOL_ENCAP; + break; +# endif /* !defined(IPPROTO_IPIP) || IPPROTO_IPIP!=IPPROTO_ENCAP */ +#endif /* defined(IPPROTO_ENCAP) */ + +#if defined(IPPROTO_APES) + case IPPROTO_APES: + Lf->iproto = LSOF_PROTOCOL_APES; + break; +#endif /* defined(IPPROTO_APES) */ + +#if defined(IPPROTO_GMTP) + case IPPROTO_GMTP: + Lf->iproto = LSOF_PROTOCOL_GMTP; + break; +#endif /* defined(IPPROTO_GMTP) */ + + default: + Lf->iproto = LSOF_PROTOCOL_UNKNOWN; + Lf->unknown_proto_number = p; + break; + } +} + +/* + * printunkaf() - print unknown address family + */ + +void printunkaf(struct lsof_context *ctx, int fam, /* unknown address family */ + int ty) /* output type: 0 = terse; 1 = full */ +{ + char *p, *s; + + p = ""; + switch (fam) { + +#if defined(AF_UNSPEC) + case AF_UNSPEC: + s = "UNSPEC"; + break; +#endif /* defined(AF_UNSPEC) */ + +#if defined(AF_UNIX) + case AF_UNIX: + s = "UNIX"; + break; +#endif /* defined(AF_UNIX) */ + +#if defined(AF_INET) + case AF_INET: + s = "INET"; + break; +#endif /* defined(AF_INET) */ + +#if defined(AF_INET6) + case AF_INET6: + s = "INET6"; + break; +#endif /* defined(AF_INET6) */ + +#if defined(AF_IMPLINK) + case AF_IMPLINK: + s = "IMPLINK"; + break; +#endif /* defined(AF_IMPLINK) */ + +#if defined(AF_PUP) + case AF_PUP: + s = "PUP"; + break; +#endif /* defined(AF_PUP) */ + +#if defined(AF_CHAOS) + case AF_CHAOS: + s = "CHAOS"; + break; +#endif /* defined(AF_CHAOS) */ + +#if defined(AF_NS) + case AF_NS: + s = "NS"; + break; +#endif /* defined(AF_NS) */ + +#if defined(AF_ISO) + case AF_ISO: + s = "ISO"; + break; +#endif /* defined(AF_ISO) */ + +#if defined(AF_NBS) +# if !defined(AF_ISO) || AF_NBS != AF_ISO + case AF_NBS: + s = "NBS"; + break; +# endif /* !defined(AF_ISO) || AF_NBS!=AF_ISO */ +#endif /* defined(AF_NBS) */ + +#if defined(AF_ECMA) + case AF_ECMA: + s = "ECMA"; + break; +#endif /* defined(AF_ECMA) */ + +#if defined(AF_DATAKIT) + case AF_DATAKIT: + s = "DATAKIT"; + break; +#endif /* defined(AF_DATAKIT) */ + +#if defined(AF_CCITT) + case AF_CCITT: + s = "CCITT"; + break; +#endif /* defined(AF_CCITT) */ + +#if defined(AF_SNA) + case AF_SNA: + s = "SNA"; + break; +#endif /* defined(AF_SNA) */ + +#if defined(AF_DECnet) + case AF_DECnet: + s = "DECnet"; + break; +#endif /* defined(AF_DECnet) */ + +#if defined(AF_DLI) + case AF_DLI: + s = "DLI"; + break; +#endif /* defined(AF_DLI) */ + +#if defined(AF_LAT) + case AF_LAT: + s = "LAT"; + break; +#endif /* defined(AF_LAT) */ + +#if defined(AF_HYLINK) + case AF_HYLINK: + s = "HYLINK"; + break; +#endif /* defined(AF_HYLINK) */ + +#if defined(AF_APPLETALK) + case AF_APPLETALK: + s = "APPLETALK"; + break; +#endif /* defined(AF_APPLETALK) */ + +#if defined(AF_BSC) + case AF_BSC: + s = "BSC"; + break; +#endif /* defined(AF_BSC) */ + +#if defined(AF_DSS) + case AF_DSS: + s = "DSS"; + break; +#endif /* defined(AF_DSS) */ + +#if defined(AF_ROUTE) + case AF_ROUTE: + s = "ROUTE"; + break; +#endif /* defined(AF_ROUTE) */ + +#if defined(AF_RAW) + case AF_RAW: + s = "RAW"; + break; +#endif /* defined(AF_RAW) */ + +#if defined(AF_LINK) + case AF_LINK: + s = "LINK"; + break; +#endif /* defined(AF_LINK) */ + +#if defined(pseudo_AF_XTP) + case pseudo_AF_XTP: + p = "pseudo_"; + s = "XTP"; + break; +#endif /* defined(pseudo_AF_XTP) */ + +#if defined(AF_RMP) + case AF_RMP: + s = "RMP"; + break; +#endif /* defined(AF_RMP) */ + +#if defined(AF_COIP) + case AF_COIP: + s = "COIP"; + break; +#endif /* defined(AF_COIP) */ + +#if defined(AF_CNT) + case AF_CNT: + s = "CNT"; + break; +#endif /* defined(AF_CNT) */ + +#if defined(pseudo_AF_RTIP) + case pseudo_AF_RTIP: + p = "pseudo_"; + s = "RTIP"; + break; +#endif /* defined(pseudo_AF_RTIP) */ + +#if defined(AF_NETMAN) + case AF_NETMAN: + s = "NETMAN"; + break; +#endif /* defined(AF_NETMAN) */ + +#if defined(AF_INTF) + case AF_INTF: + s = "INTF"; + break; +#endif /* defined(AF_INTF) */ + +#if defined(AF_NETWARE) + case AF_NETWARE: + s = "NETWARE"; + break; +#endif /* defined(AF_NETWARE) */ + +#if defined(AF_NDD) + case AF_NDD: + s = "NDD"; + break; +#endif /* defined(AF_NDD) */ + +#if defined(AF_NIT) +# if !defined(AF_ROUTE) || AF_ROUTE != AF_NIT + case AF_NIT: + s = "NIT"; + break; +# endif /* !defined(AF_ROUTE) || AF_ROUTE!=AF_NIT */ +#endif /* defined(AF_NIT) */ + +#if defined(AF_802) +# if !defined(AF_RAW) || AF_RAW != AF_802 + case AF_802: + s = "802"; + break; +# endif /* !defined(AF_RAW) || AF_RAW!=AF_802 */ +#endif /* defined(AF_802) */ + +#if defined(AF_X25) + case AF_X25: + s = "X25"; + break; +#endif /* defined(AF_X25) */ + +#if defined(AF_CTF) + case AF_CTF: + s = "CTF"; + break; +#endif /* defined(AF_CTF) */ + +#if defined(AF_WAN) + case AF_WAN: + s = "WAN"; + break; +#endif /* defined(AF_WAN) */ + +#if defined(AF_OSINET) +# if defined(AF_INET) && AF_INET != AF_OSINET + case AF_OSINET: + s = "OSINET"; + break; +# endif /* defined(AF_INET) && AF_INET!=AF_OSINET */ +#endif /* defined(AF_OSINET) */ + +#if defined(AF_GOSIP) + case AF_GOSIP: + s = "GOSIP"; + break; +#endif /* defined(AF_GOSIP) */ + +#if defined(AF_SDL) + case AF_SDL: + s = "SDL"; + break; +#endif /* defined(AF_SDL) */ + +#if defined(AF_IPX) + case AF_IPX: + s = "IPX"; + break; +#endif /* defined(AF_IPX) */ + +#if defined(AF_SIP) + case AF_SIP: + s = "SIP"; + break; +#endif /* defined(AF_SIP) */ + +#if defined(psuedo_AF_PIP) + case psuedo_AF_PIP: + p = "pseudo_"; + s = "PIP"; + break; +#endif /* defined(psuedo_AF_PIP) */ + +#if defined(AF_OTS) + case AF_OTS: + s = "OTS"; + break; +#endif /* defined(AF_OTS) */ + +#if defined(pseudo_AF_BLUE) + case pseudo_AF_BLUE: /* packets for Blue box */ + p = "pseudo_"; + s = "BLUE"; + break; +#endif /* defined(pseudo_AF_BLUE) */ + +#if defined(AF_NDRV) /* network driver raw access */ + case AF_NDRV: + s = "NDRV"; + break; +#endif /* defined(AF_NDRV) */ + +#if defined(AF_SYSTEM) /* kernel event messages */ + case AF_SYSTEM: + s = "SYSTEM"; + break; +#endif /* defined(AF_SYSTEM) */ + +#if defined(AF_USER) + case AF_USER: + s = "USER"; + break; +#endif /* defined(AF_USER) */ + +#if defined(pseudo_AF_KEY) + case pseudo_AF_KEY: + p = "pseudo_"; + s = "KEY"; + break; +#endif /* defined(pseudo_AF_KEY) */ + +#if defined(AF_KEY) /* Security Association DB socket */ + case AF_KEY: + s = "KEY"; + break; +#endif /* defined(AF_KEY) */ + +#if defined(AF_NCA) /* NCA socket */ + case AF_NCA: + s = "NCA"; + break; +#endif /* defined(AF_NCA) */ + +#if defined(AF_POLICY) /* Security Policy DB socket */ + case AF_POLICY: + s = "POLICY"; + break; +#endif /* defined(AF_POLICY) */ + +#if defined(AF_PPP) /* PPP socket */ + case AF_PPP: + s = "PPP"; + break; +#endif /* defined(AF_PPP) */ + + default: + if (!ty) + (void)snpf(Namech, Namechl, "%#x", fam); + else + (void)snpf(Namech, Namechl, "no further information on family %#x", + fam); + return; + } + if (!ty) + (void)snpf(Namech, Namechl, "%sAF_%s", p, s); + else + (void)snpf(Namech, Namechl, "no further information on %sAF_%s", p, s); + return; +} + +/* + * print_access() - print enum lsof_file_access_mode + */ +char print_access(enum lsof_file_access_mode access) { switch (access) { default: case LSOF_FILE_ACCESS_NONE: @@ -50,4 +1074,1136 @@ char access_to_char(enum lsof_file_access_mode access) { case LSOF_FILE_ACCESS_READ_WRITE: return 'u'; } -} \ No newline at end of file +} + +/* + * print_lock() - print enum lsof_lock_mode + */ +char print_lock(enum lsof_lock_mode lock) { + switch (lock) { + default: + case LSOF_LOCK_NONE: + return ' '; + case LSOF_LOCK_UNKNOWN: + return 'U'; + case LSOF_LOCK_READ_PARTIAL: + return 'r'; + case LSOF_LOCK_READ_FULL: + return 'R'; + case LSOF_LOCK_WRITE_PARTIAL: + return 'w'; + case LSOF_LOCK_WRITE_FULL: + return 'W'; + case LSOF_LOCK_READ_WRITE: + return 'u'; + case LSOF_LOCK_SOLARIS_NFS: + return 'N'; + case LSOF_LOCK_SCO_PARTIAL: + return 'x'; + case LSOF_LOCK_SCO_FULL: + return 'X'; + } +} + +/* + * print_file_type() - print enum lsof_file_type + */ +void print_file_type(enum lsof_file_type type, + uint32_t unknown_file_type_number, char *buf, + size_t buf_len) { + switch (type) { + default: + case LSOF_FILE_UNKNOWN: + (void)snpf(buf, buf_len, "%04o", (unknown_file_type_number & 0xfff)); + break; + case LSOF_FILE_FIFO: + (void)snpf(buf, buf_len, "FIFO"); + break; + case LSOF_FILE_CHAR: + (void)snpf(buf, buf_len, "CHR"); + break; + case LSOF_FILE_DIR: + (void)snpf(buf, buf_len, "DIR"); + break; + case LSOF_FILE_BLOCK: + (void)snpf(buf, buf_len, "BLK"); + break; + case LSOF_FILE_REGULAR: + (void)snpf(buf, buf_len, "REG"); + break; + case LSOF_FILE_LINK: + (void)snpf(buf, buf_len, "LNK"); + break; + /* Use lower case for network-related files except IPv4/IPv6 for + * compatibility */ + case LSOF_FILE_SOCKET: + (void)snpf(buf, buf_len, "sock"); + break; + case LSOF_FILE_IPV4: + (void)snpf(buf, buf_len, "IPv4"); + break; + case LSOF_FILE_IPV6: + (void)snpf(buf, buf_len, "IPv6"); + break; + case LSOF_FILE_AX25: + (void)snpf(buf, buf_len, "ax25"); + break; + case LSOF_FILE_INET: + (void)snpf(buf, buf_len, "inet"); + break; + case LSOF_FILE_LINK_LEVEL_ACCESS: + (void)snpf(buf, buf_len, "lla"); + break; + case LSOF_FILE_ROUTE: + (void)snpf(buf, buf_len, "rte"); + break; + case LSOF_FILE_UNIX: + (void)snpf(buf, buf_len, "unix"); + break; + case LSOF_FILE_X25: + (void)snpf(buf, buf_len, "x.25"); + break; + case LSOF_FILE_APPLETALK: + (void)snpf(buf, buf_len, "atalk"); + break; + case LSOF_FILE_NET_DRIVER: + (void)snpf(buf, buf_len, "ndrv"); + break; + case LSOF_FILE_INTERNAL_KEY: + (void)snpf(buf, buf_len, "key"); + break; + case LSOF_FILE_SYSTEM: + (void)snpf(buf, buf_len, "systm"); + break; + case LSOF_FILE_PPP: + (void)snpf(buf, buf_len, "ppp"); + break; + case LSOF_FILE_IPX: + (void)snpf(buf, buf_len, "ipx"); + break; + case LSOF_FILE_RAW: + (void)snpf(buf, buf_len, "raw"); + break; + case LSOF_FILE_RAW6: + (void)snpf(buf, buf_len, "raw6"); + break; + case LSOF_FILE_NETLINK: + (void)snpf(buf, buf_len, "netlink"); + break; + case LSOF_FILE_PACKET: + (void)snpf(buf, buf_len, "pack"); + break; + case LSOF_FILE_ICMP: + (void)snpf(buf, buf_len, "icmp"); + break; + + case LSOF_FILE_PROC_AS: + (void)snpf(buf, buf_len, "PAS"); + break; + case LSOF_FILE_PROC_AUXV: + (void)snpf(buf, buf_len, "PAXV"); + break; + case LSOF_FILE_PROC_CRED: + (void)snpf(buf, buf_len, "PCRE"); + break; + case LSOF_FILE_PROC_CTRL: + (void)snpf(buf, buf_len, "PCTL"); + break; + case LSOF_FILE_PROC_CUR_PROC: + (void)snpf(buf, buf_len, "PCUR"); + break; + case LSOF_FILE_PROC_CWD: + (void)snpf(buf, buf_len, "PCWD"); + break; + case LSOF_FILE_PROC_DIR: + (void)snpf(buf, buf_len, "PDIR"); + break; + case LSOF_FILE_PROC_PID: + (void)snpf(buf, buf_len, "PPID"); + break; + case LSOF_FILE_PROC_EXEC_TYPE: + (void)snpf(buf, buf_len, "PETY"); + break; + case LSOF_FILE_PROC_FD: + (void)snpf(buf, buf_len, "PFD"); + break; + case LSOF_FILE_PROC_FD_DIR: + (void)snpf(buf, buf_len, "PFDR"); + break; + case LSOF_FILE_PROC_FILE: + (void)snpf(buf, buf_len, "PFIL"); + break; + case LSOF_FILE_PROC_FP_REGS: + (void)snpf(buf, buf_len, "PFPR"); + break; + case LSOF_FILE_PROC_PAGE_DATA: + (void)snpf(buf, buf_len, "PGD"); + break; + case LSOF_FILE_PROC_GROUP_NOTIFIER: + (void)snpf(buf, buf_len, "PGID"); + break; + case LSOF_FILE_PROC_LDT: + (void)snpf(buf, buf_len, "PLDT"); + break; + case LSOF_FILE_PROC_LPS_INFO: + (void)snpf(buf, buf_len, "PLPI"); + break; + case LSOF_FILE_PROC_LSTATUS: + (void)snpf(buf, buf_len, "PLST"); + break; + case LSOF_FILE_PROC_LUSAGE: + (void)snpf(buf, buf_len, "PLU"); + break; + case LSOF_FILE_PROC_LWP_GWINDOWS: + (void)snpf(buf, buf_len, "PLWG"); + break; + case LSOF_FILE_PROC_LWP_CTL: + (void)snpf(buf, buf_len, "PLC"); + break; + case LSOF_FILE_PROC_LWP_DIR: + (void)snpf(buf, buf_len, "PLDR"); + break; + case LSOF_FILE_PROC_LWP_SINFO: + (void)snpf(buf, buf_len, "PLWI"); + break; + case LSOF_FILE_PROC_LWP_STATUS: + (void)snpf(buf, buf_len, "PLWS"); + break; + case LSOF_FILE_PROC_LWP_USAGE: + (void)snpf(buf, buf_len, "PLWU"); + break; + case LSOF_FILE_PROC_LWP_XREGS: + (void)snpf(buf, buf_len, "PLWX"); + break; + case LSOF_FILE_PROC_MAP: + (void)snpf(buf, buf_len, "PMAP"); + break; + case LSOF_FILE_PROC_MAPS: + (void)snpf(buf, buf_len, "PMPS"); + break; + case LSOF_FILE_PROC_MEMORY: + (void)snpf(buf, buf_len, "PMEM"); + break; + case LSOF_FILE_PROC_PROC_NOTIFIER: + (void)snpf(buf, buf_len, "PNTF"); + break; + case LSOF_FILE_PROC_OBJ: + (void)snpf(buf, buf_len, "POBJ"); + break; + case LSOF_FILE_PROC_OBJ_DIR: + (void)snpf(buf, buf_len, "PODR"); + break; + case LSOF_FILE_PROC_OLD_LWP: + (void)snpf(buf, buf_len, "POLP"); + break; + case LSOF_FILE_PROC_OLD_PID: + (void)snpf(buf, buf_len, "POPF"); + break; + case LSOF_FILE_PROC_OLD_PAGE: + (void)snpf(buf, buf_len, "POPG"); + break; + case LSOF_FILE_PROC_REGS: + (void)snpf(buf, buf_len, "PREG"); + break; + case LSOF_FILE_PROC_RMAP: + (void)snpf(buf, buf_len, "PRMP"); + break; + case LSOF_FILE_PROC_ROOT: + (void)snpf(buf, buf_len, "PRTD"); + break; + case LSOF_FILE_PROC_SIGACT: + (void)snpf(buf, buf_len, "PSGA"); + break; + case LSOF_FILE_PROC_PSINFO: + (void)snpf(buf, buf_len, "PSIN"); + break; + case LSOF_FILE_PROC_STATUS: + (void)snpf(buf, buf_len, "PSTA"); + break; + case LSOF_FILE_PROC_USAGE: + (void)snpf(buf, buf_len, "PUSG"); + break; + case LSOF_FILE_PROC_WATCH: + (void)snpf(buf, buf_len, "PW"); + break; + case LSOF_FILE_PROC_XMAP: + (void)snpf(buf, buf_len, "PXMP"); + break; + + /* Others */ + case LSOF_FILE_ANON_INODE: + (void)snpf(buf, buf_len, "a_inode"); + break; + case LSOF_FILE_DEL: + (void)snpf(buf, buf_len, "DEL"); + break; + case LSOF_FILE_DOOR: + (void)snpf(buf, buf_len, "DOOR"); + break; + case LSOF_FILE_KQUEUE: + (void)snpf(buf, buf_len, "KQUEUE"); + break; + case LSOF_FILE_FSEVENTS: + (void)snpf(buf, buf_len, "FSEVENTS"); + break; + case LSOF_FILE_EVENTFD: + (void)snpf(buf, buf_len, "EVENTFD"); + break; + case LSOF_FILE_PROCDESC: + (void)snpf(buf, buf_len, "PROCDSC"); + break; + case LSOF_FILE_MULTIPLEXED_BLOCK: + (void)snpf(buf, buf_len, "MPB"); + break; + case LSOF_FILE_MULTIPLEXED_CHAR: + (void)snpf(buf, buf_len, "MPC"); + break; + case LSOF_FILE_UNKNOWN_DELETED: + (void)snpf(buf, buf_len, "UNKNdel"); + break; + case LSOF_FILE_UNKNOWN_MEMORY: + (void)snpf(buf, buf_len, "UNKNmem"); + break; + case LSOF_FILE_UNKNOWN_FD: + (void)snpf(buf, buf_len, "UNKNfd"); + break; + case LSOF_FILE_UNKNOWN_CWD: + (void)snpf(buf, buf_len, "UNKNcwd"); + break; + case LSOF_FILE_UNKNOWN_ROOT_DIR: + (void)snpf(buf, buf_len, "UNKNrtd"); + break; + case LSOF_FILE_UNKNOWN_PROGRAM_TEXT: + (void)snpf(buf, buf_len, "UNKNtxt"); + break; + case LSOF_FILE_PIPE: + (void)snpf(buf, buf_len, "PIPE"); + break; + case LSOF_FILE_PORT: + (void)snpf(buf, buf_len, "PORT"); + break; + case LSOF_FILE_POSIX_MQ: + (void)snpf(buf, buf_len, "PSXMQ"); + break; + case LSOF_FILE_POSIX_SEMA: + (void)snpf(buf, buf_len, "PSXSEM"); + break; + case LSOF_FILE_POSIX_SHM: + (void)snpf(buf, buf_len, "PSXSHM"); + break; + case LSOF_FILE_SHM: + (void)snpf(buf, buf_len, "SHM"); + break; + case LSOF_FILE_PTS: + (void)snpf(buf, buf_len, "PTS"); + break; + case LSOF_FILE_SHARED_MEM_TRANSPORT: + (void)snpf(buf, buf_len, "SMT"); + break; + case LSOF_FILE_STREAM: + (void)snpf(buf, buf_len, "STR"); + break; + case LSOF_FILE_STREAM_SOCKET: + (void)snpf(buf, buf_len, "STSO"); + break; + case LSOF_FILE_SCO_UNKNOWN: + (void)snpf(buf, buf_len, "XNAM"); + break; + case LSOF_FILE_SCO_SEMA: + (void)snpf(buf, buf_len, "XSEM"); + break; + case LSOF_FILE_SCO_SHARED: + (void)snpf(buf, buf_len, "XSD"); + break; + case LSOF_FILE_UNSUPPORTED: + (void)snpf(buf, buf_len, "UNSP"); + break; + + /* vnode */ + case LSOF_FILE_VNODE_VNON: + (void)snpf(buf, buf_len, "VNON"); + break; + case LSOF_FILE_VNODE_VREG: + (void)snpf(buf, buf_len, "VREG"); + break; + case LSOF_FILE_VNODE_VDIR: + (void)snpf(buf, buf_len, "VDIR"); + break; + case LSOF_FILE_VNODE_VBLK: + (void)snpf(buf, buf_len, "VBLK"); + break; + case LSOF_FILE_VNODE_VCHR: + (void)snpf(buf, buf_len, "VCHR"); + break; + case LSOF_FILE_VNODE_VLNK: + (void)snpf(buf, buf_len, "VLNK"); + break; + case LSOF_FILE_VNODE_VSOCK: + (void)snpf(buf, buf_len, "VSOCK"); + break; + case LSOF_FILE_VNODE_VFIFO: + (void)snpf(buf, buf_len, "VFIFO"); + break; + case LSOF_FILE_VNODE_VBAD: + (void)snpf(buf, buf_len, "VBAD"); + break; + case LSOF_FILE_VNODE_VMPC: + (void)snpf(buf, buf_len, "VMPC"); + break; + case LSOF_FILE_VNODE_VUNNAMED: + (void)snpf(buf, buf_len, "VUNNM"); + break; + } +} + +/* + * print_file_type() - print enum lsof_protocol + */ +void print_iproto(enum lsof_protocol proto, uint32_t unknown_proto_number, + char *buf, size_t buf_len) { + int i, m; + switch (proto) { + default: + case LSOF_PROTOCOL_UNKNOWN: + for (i = 0, m = 1; i < IPROTOL - 2; i++) + m *= 10; + if (m > unknown_proto_number) + (void)snpf(buf, buf_len, "%d?", unknown_proto_number); + else + (void)snpf(buf, buf_len, "*%d?", unknown_proto_number % (m / 10)); + break; + case LSOF_PROTOCOL_INVALID: + (void)snpf(buf, buf_len, ""); + break; + + /* Copied from scripts/lsof_proto.c */ + case LSOF_PROTOCOL_IP: + (void)snpf(buf, buf_len, "IP"); + break; + case LSOF_PROTOCOL_HOPOPTS: + (void)snpf(buf, buf_len, "HOPOPTS"); + break; + case LSOF_PROTOCOL_ICMP: + (void)snpf(buf, buf_len, "ICMP"); + break; + case LSOF_PROTOCOL_IGMP: + (void)snpf(buf, buf_len, "IGMP"); + break; + case LSOF_PROTOCOL_GGP: + (void)snpf(buf, buf_len, "GGP"); + break; + case LSOF_PROTOCOL_IPIP: + (void)snpf(buf, buf_len, "IPIP"); + break; + case LSOF_PROTOCOL_IPV4: + (void)snpf(buf, buf_len, "IPV4"); + break; + case LSOF_PROTOCOL_TCP: + (void)snpf(buf, buf_len, "TCP"); + break; + case LSOF_PROTOCOL_ST: + (void)snpf(buf, buf_len, "ST"); + break; + case LSOF_PROTOCOL_EGP: + (void)snpf(buf, buf_len, "EGP"); + break; + case LSOF_PROTOCOL_PIGP: + (void)snpf(buf, buf_len, "PIGP"); + break; + case LSOF_PROTOCOL_RCCMON: + (void)snpf(buf, buf_len, "RCCMON"); + break; + case LSOF_PROTOCOL_NVPII: + (void)snpf(buf, buf_len, "NVPII"); + break; + case LSOF_PROTOCOL_PUP: + (void)snpf(buf, buf_len, "PUP"); + break; + case LSOF_PROTOCOL_ARGUS: + (void)snpf(buf, buf_len, "ARGUS"); + break; + case LSOF_PROTOCOL_EMCON: + (void)snpf(buf, buf_len, "EMCON"); + break; + case LSOF_PROTOCOL_XNET: + (void)snpf(buf, buf_len, "XNET"); + break; + case LSOF_PROTOCOL_CHAOS: + (void)snpf(buf, buf_len, "CHAOS"); + break; + case LSOF_PROTOCOL_UDP: + (void)snpf(buf, buf_len, "UDP"); + break; + case LSOF_PROTOCOL_MUX: + (void)snpf(buf, buf_len, "MUX"); + break; + case LSOF_PROTOCOL_MEAS: + (void)snpf(buf, buf_len, "MEAS"); + break; + case LSOF_PROTOCOL_HMP: + (void)snpf(buf, buf_len, "HMP"); + break; + case LSOF_PROTOCOL_PRM: + (void)snpf(buf, buf_len, "PRM"); + break; + case LSOF_PROTOCOL_IDP: + (void)snpf(buf, buf_len, "IDP"); + break; + case LSOF_PROTOCOL_TRUNK1: + (void)snpf(buf, buf_len, "TRUNK1"); + break; + case LSOF_PROTOCOL_TRUNK2: + (void)snpf(buf, buf_len, "TRUNK2"); + break; + case LSOF_PROTOCOL_LEAF1: + (void)snpf(buf, buf_len, "LEAF1"); + break; + case LSOF_PROTOCOL_LEAF2: + (void)snpf(buf, buf_len, "LEAF2"); + break; + case LSOF_PROTOCOL_RDP: + (void)snpf(buf, buf_len, "RDP"); + break; + case LSOF_PROTOCOL_IRTP: + (void)snpf(buf, buf_len, "IRTP"); + break; + case LSOF_PROTOCOL_TP: + (void)snpf(buf, buf_len, "TP"); + break; + case LSOF_PROTOCOL_BLT: + (void)snpf(buf, buf_len, "BLT"); + break; + case LSOF_PROTOCOL_NSP: + (void)snpf(buf, buf_len, "NSP"); + break; + case LSOF_PROTOCOL_INP: + (void)snpf(buf, buf_len, "INP"); + break; + case LSOF_PROTOCOL_DCCP: + (void)snpf(buf, buf_len, "DCCP"); + break; + case LSOF_PROTOCOL_3PC: + (void)snpf(buf, buf_len, "3PC"); + break; + case LSOF_PROTOCOL_IDPR: + (void)snpf(buf, buf_len, "IDPR"); + break; + case LSOF_PROTOCOL_XTP: + (void)snpf(buf, buf_len, "XTP"); + break; + case LSOF_PROTOCOL_DDP: + (void)snpf(buf, buf_len, "DDP"); + break; + case LSOF_PROTOCOL_CMTP: + (void)snpf(buf, buf_len, "CMTP"); + break; + case LSOF_PROTOCOL_TPXX: + (void)snpf(buf, buf_len, "TPXX"); + break; + case LSOF_PROTOCOL_IL: + (void)snpf(buf, buf_len, "IL"); + break; + case LSOF_PROTOCOL_IPV6: + (void)snpf(buf, buf_len, "IPV6"); + break; + case LSOF_PROTOCOL_SDRP: + (void)snpf(buf, buf_len, "SDRP"); + break; + case LSOF_PROTOCOL_ROUTING: + (void)snpf(buf, buf_len, "ROUTING"); + break; + case LSOF_PROTOCOL_FRAGMENT: + (void)snpf(buf, buf_len, "FRAGMNT"); + break; + case LSOF_PROTOCOL_IDRP: + (void)snpf(buf, buf_len, "IDRP"); + break; + case LSOF_PROTOCOL_RSVP: + (void)snpf(buf, buf_len, "RSVP"); + break; + case LSOF_PROTOCOL_GRE: + (void)snpf(buf, buf_len, "GRE"); + break; + case LSOF_PROTOCOL_MHRP: + (void)snpf(buf, buf_len, "MHRP"); + break; + case LSOF_PROTOCOL_BHA: + (void)snpf(buf, buf_len, "BHA"); + break; + case LSOF_PROTOCOL_ESP: + (void)snpf(buf, buf_len, "ESP"); + break; + case LSOF_PROTOCOL_AH: + (void)snpf(buf, buf_len, "AH"); + break; + case LSOF_PROTOCOL_INLSP: + (void)snpf(buf, buf_len, "INLSP"); + break; + case LSOF_PROTOCOL_SWIPE: + (void)snpf(buf, buf_len, "SWIPE"); + break; + case LSOF_PROTOCOL_NHRP: + (void)snpf(buf, buf_len, "NHRP"); + break; + case LSOF_PROTOCOL_MOBILE: + (void)snpf(buf, buf_len, "MOBILE"); + break; + case LSOF_PROTOCOL_TLSP: + (void)snpf(buf, buf_len, "TLSP"); + break; + case LSOF_PROTOCOL_SKIP: + (void)snpf(buf, buf_len, "SKIP"); + break; + case LSOF_PROTOCOL_ICMPV6: + (void)snpf(buf, buf_len, "ICMPV6"); + break; + case LSOF_PROTOCOL_NONE: + (void)snpf(buf, buf_len, "NONE"); + break; + case LSOF_PROTOCOL_DSTOPTS: + (void)snpf(buf, buf_len, "DSTOPTS"); + break; + case LSOF_PROTOCOL_AHIP: + (void)snpf(buf, buf_len, "AHIP"); + break; + case LSOF_PROTOCOL_CFTP: + (void)snpf(buf, buf_len, "CFTP"); + break; + case LSOF_PROTOCOL_HELLO: + (void)snpf(buf, buf_len, "HELLO"); + break; + case LSOF_PROTOCOL_SATEXPAK: + (void)snpf(buf, buf_len, "STEXPAK"); + break; + case LSOF_PROTOCOL_KRYPTOLAN: + (void)snpf(buf, buf_len, "KRYPTLN"); + break; + case LSOF_PROTOCOL_RVD: + (void)snpf(buf, buf_len, "RVD"); + break; + case LSOF_PROTOCOL_IPPC: + (void)snpf(buf, buf_len, "IPPC"); + break; + case LSOF_PROTOCOL_ADFS: + (void)snpf(buf, buf_len, "ADFS"); + break; + case LSOF_PROTOCOL_SATMON: + (void)snpf(buf, buf_len, "SATMON"); + break; + case LSOF_PROTOCOL_VISA: + (void)snpf(buf, buf_len, "VISA"); + break; + case LSOF_PROTOCOL_IPCV: + (void)snpf(buf, buf_len, "IPCV"); + break; + case LSOF_PROTOCOL_CPNX: + (void)snpf(buf, buf_len, "CPNX"); + break; + case LSOF_PROTOCOL_CPHB: + (void)snpf(buf, buf_len, "CPHB"); + break; + case LSOF_PROTOCOL_WSN: + (void)snpf(buf, buf_len, "WSN"); + break; + case LSOF_PROTOCOL_PVP: + (void)snpf(buf, buf_len, "PVP"); + break; + case LSOF_PROTOCOL_BRSATMON: + (void)snpf(buf, buf_len, "BRSTMON"); + break; + case LSOF_PROTOCOL_ND: + (void)snpf(buf, buf_len, "ND"); + break; + case LSOF_PROTOCOL_WBMON: + (void)snpf(buf, buf_len, "WBMON"); + break; + case LSOF_PROTOCOL_WBEXPAK: + (void)snpf(buf, buf_len, "WBEXPAK"); + break; + case LSOF_PROTOCOL_EON: + (void)snpf(buf, buf_len, "EON"); + break; + case LSOF_PROTOCOL_VMTP: + (void)snpf(buf, buf_len, "VMTP"); + break; + case LSOF_PROTOCOL_SVMTP: + (void)snpf(buf, buf_len, "SVMTP"); + break; + case LSOF_PROTOCOL_VINES: + (void)snpf(buf, buf_len, "VINES"); + break; + case LSOF_PROTOCOL_TTP: + (void)snpf(buf, buf_len, "TTP"); + break; + case LSOF_PROTOCOL_IGP: + (void)snpf(buf, buf_len, "IGP"); + break; + case LSOF_PROTOCOL_DGP: + (void)snpf(buf, buf_len, "DGP"); + break; + case LSOF_PROTOCOL_TCF: + (void)snpf(buf, buf_len, "TCF"); + break; + case LSOF_PROTOCOL_IGRP: + (void)snpf(buf, buf_len, "IGRP"); + break; + case LSOF_PROTOCOL_OSPFIGP: + (void)snpf(buf, buf_len, "OSPFIGP"); + break; + case LSOF_PROTOCOL_SRPC: + (void)snpf(buf, buf_len, "SRPC"); + break; + case LSOF_PROTOCOL_LARP: + (void)snpf(buf, buf_len, "LARP"); + break; + case LSOF_PROTOCOL_MTP: + (void)snpf(buf, buf_len, "MTP"); + break; + case LSOF_PROTOCOL_AX25: + (void)snpf(buf, buf_len, "AX25"); + break; + case LSOF_PROTOCOL_BEETPH: + (void)snpf(buf, buf_len, "BEETPH"); + break; + case LSOF_PROTOCOL_IPEIP: + (void)snpf(buf, buf_len, "IPEIP"); + break; + case LSOF_PROTOCOL_MICP: + (void)snpf(buf, buf_len, "MICP"); + break; + case LSOF_PROTOCOL_SCCSP: + (void)snpf(buf, buf_len, "SCCSP"); + break; + case LSOF_PROTOCOL_ETHERIP: + (void)snpf(buf, buf_len, "ETHERIP"); + break; + case LSOF_PROTOCOL_ENCAP: + (void)snpf(buf, buf_len, "ENCAP"); + break; + case LSOF_PROTOCOL_APES: + (void)snpf(buf, buf_len, "APES"); + break; + case LSOF_PROTOCOL_GMTP: + (void)snpf(buf, buf_len, "GMTP"); + break; + case LSOF_PROTOCOL_PIM: + (void)snpf(buf, buf_len, "PIM"); + break; + case LSOF_PROTOCOL_COMP: + (void)snpf(buf, buf_len, "COMP"); + break; + case LSOF_PROTOCOL_IPCOMP: + (void)snpf(buf, buf_len, "IPCOMP"); + break; + case LSOF_PROTOCOL_CARP: + (void)snpf(buf, buf_len, "CARP"); + break; + case LSOF_PROTOCOL_PGM: + (void)snpf(buf, buf_len, "PGM"); + break; + case LSOF_PROTOCOL_SCTP: + (void)snpf(buf, buf_len, "SCTP"); + break; + case LSOF_PROTOCOL_MH: + (void)snpf(buf, buf_len, "MH"); + break; + case LSOF_PROTOCOL_UDPLITE: + (void)snpf(buf, buf_len, "UDPLITE"); + break; + case LSOF_PROTOCOL_MPLS: + (void)snpf(buf, buf_len, "MPLS"); + break; + case LSOF_PROTOCOL_HIP: + (void)snpf(buf, buf_len, "HIP"); + break; + case LSOF_PROTOCOL_SHIM6: + (void)snpf(buf, buf_len, "SHIM6"); + break; + case LSOF_PROTOCOL_ETHERNET: + (void)snpf(buf, buf_len, "ETHER"); + break; + case LSOF_PROTOCOL_PFSYNC: + (void)snpf(buf, buf_len, "PFSYNC"); + break; + case LSOF_PROTOCOL_RESERVED_253: + (void)snpf(buf, buf_len, "RSVD253"); + break; + case LSOF_PROTOCOL_RESERVED_254: + (void)snpf(buf, buf_len, "RSVD254"); + break; + case LSOF_PROTOCOL_OLD_DIVERT: + (void)snpf(buf, buf_len, "ODIVERT"); + break; + case LSOF_PROTOCOL_RAW: + (void)snpf(buf, buf_len, "RAW"); + break; + case LSOF_PROTOCOL_MAX: + (void)snpf(buf, buf_len, "MAX"); + break; + case LSOF_PROTOCOL_DONE: + (void)snpf(buf, buf_len, "DONE"); + break; + case LSOF_PROTOCOL_SEND: + (void)snpf(buf, buf_len, "SEND"); + break; + case LSOF_PROTOCOL_MPTCP: + (void)snpf(buf, buf_len, "MPTCP"); + break; + case LSOF_PROTOCOL_SPACER: + (void)snpf(buf, buf_len, "SPACER"); + break; + case LSOF_PROTOCOL_802_3: + (void)snpf(buf, buf_len, "802_3"); + break; + case LSOF_PROTOCOL_ALL: + (void)snpf(buf, buf_len, "ALL"); + break; + case LSOF_PROTOCOL_802_2: + (void)snpf(buf, buf_len, "802_2"); + break; + case LSOF_PROTOCOL_SNAP: + (void)snpf(buf, buf_len, "SNAP"); + break; + case LSOF_PROTOCOL_DDCMP: + (void)snpf(buf, buf_len, "DDCMP"); + break; + case LSOF_PROTOCOL_WAN_PPP: + (void)snpf(buf, buf_len, "WAN_PPP"); + break; + case LSOF_PROTOCOL_PPP_MP: + (void)snpf(buf, buf_len, "PPP_MP"); + break; + case LSOF_PROTOCOL_LOCALTALK: + (void)snpf(buf, buf_len, "LCLTALK"); + break; + case LSOF_PROTOCOL_CAN: + (void)snpf(buf, buf_len, "CAN"); + break; + case LSOF_PROTOCOL_CANFD: + (void)snpf(buf, buf_len, "CANFD"); + break; + case LSOF_PROTOCOL_CANXL: + (void)snpf(buf, buf_len, "CANXL"); + break; + case LSOF_PROTOCOL_PPPTALK: + (void)snpf(buf, buf_len, "PPPTALK"); + break; + case LSOF_PROTOCOL_TR_802_2: + (void)snpf(buf, buf_len, "802.2"); + break; + case LSOF_PROTOCOL_MOBITEX: + (void)snpf(buf, buf_len, "MOBITEX"); + break; + case LSOF_PROTOCOL_CONTROL: + (void)snpf(buf, buf_len, "CONTROL"); + break; + case LSOF_PROTOCOL_IRDA: + (void)snpf(buf, buf_len, "IRDA"); + break; + case LSOF_PROTOCOL_ECONET: + (void)snpf(buf, buf_len, "ECONET"); + break; + case LSOF_PROTOCOL_HDLC: + (void)snpf(buf, buf_len, "HDLC"); + break; + case LSOF_PROTOCOL_ARCNET: + (void)snpf(buf, buf_len, "ARCNET"); + break; + case LSOF_PROTOCOL_DSA: + (void)snpf(buf, buf_len, "DSA"); + break; + case LSOF_PROTOCOL_TRAILER: + (void)snpf(buf, buf_len, "TRAILER"); + break; + case LSOF_PROTOCOL_LOOP: + (void)snpf(buf, buf_len, "LOOP"); + break; + case LSOF_PROTOCOL_PHONET: + (void)snpf(buf, buf_len, "PHONET"); + break; + case LSOF_PROTOCOL_IEEE802154: + (void)snpf(buf, buf_len, "802154"); + break; + case LSOF_PROTOCOL_CAIF: + (void)snpf(buf, buf_len, "CAIF"); + break; + case LSOF_PROTOCOL_XDSA: + (void)snpf(buf, buf_len, "XDSA"); + break; + case LSOF_PROTOCOL_MAP: + (void)snpf(buf, buf_len, "MAP"); + break; + case LSOF_PROTOCOL_MCTP: + (void)snpf(buf, buf_len, "MCTP"); + break; + case LSOF_PROTOCOL_PUPAT: + (void)snpf(buf, buf_len, "PUPAT"); + break; + case LSOF_PROTOCOL_802_3_MIN: + (void)snpf(buf, buf_len, "802.3"); + break; + case LSOF_PROTOCOL_X25: + (void)snpf(buf, buf_len, "X25"); + break; + case LSOF_PROTOCOL_ARP: + (void)snpf(buf, buf_len, "ARP"); + break; + case LSOF_PROTOCOL_BPQ: + (void)snpf(buf, buf_len, "BPQ"); + break; + case LSOF_PROTOCOL_IEEEPUP: + (void)snpf(buf, buf_len, "IEEEPUP"); + break; + case LSOF_PROTOCOL_IEEEPUPAT: + (void)snpf(buf, buf_len, "I3EPUPAT"); + break; + case LSOF_PROTOCOL_ERSPAN2: + (void)snpf(buf, buf_len, "ERSPAN2"); + break; + case LSOF_PROTOCOL_TSN: + (void)snpf(buf, buf_len, "TSN"); + break; + case LSOF_PROTOCOL_BATMAN: + (void)snpf(buf, buf_len, "BATMAN"); + break; + case LSOF_PROTOCOL_DEC: + (void)snpf(buf, buf_len, "DEC"); + break; + case LSOF_PROTOCOL_DNA_DL: + (void)snpf(buf, buf_len, "DNA_DL"); + break; + case LSOF_PROTOCOL_DNA_RC: + (void)snpf(buf, buf_len, "DNA_RC"); + break; + case LSOF_PROTOCOL_DNA_RT: + (void)snpf(buf, buf_len, "DNA_RT"); + break; + case LSOF_PROTOCOL_LAT: + (void)snpf(buf, buf_len, "LAT"); + break; + case LSOF_PROTOCOL_DIAG: + (void)snpf(buf, buf_len, "DIAG"); + break; + case LSOF_PROTOCOL_CUST: + (void)snpf(buf, buf_len, "CUST"); + break; + case LSOF_PROTOCOL_SCA: + (void)snpf(buf, buf_len, "SCA"); + break; + case LSOF_PROTOCOL_TEB: + (void)snpf(buf, buf_len, "TEB"); + break; + case LSOF_PROTOCOL_RARP: + (void)snpf(buf, buf_len, "RARP"); + break; + case LSOF_PROTOCOL_ATALK: + (void)snpf(buf, buf_len, "ATALK"); + break; + case LSOF_PROTOCOL_AARP: + (void)snpf(buf, buf_len, "AARP"); + break; + case LSOF_PROTOCOL_8021Q: + (void)snpf(buf, buf_len, "8021Q"); + break; + case LSOF_PROTOCOL_IPX: + (void)snpf(buf, buf_len, "IPX"); + break; + case LSOF_PROTOCOL_PAUSE: + (void)snpf(buf, buf_len, "PAUSE"); + break; + case LSOF_PROTOCOL_SLOW: + (void)snpf(buf, buf_len, "SLOW"); + break; + case LSOF_PROTOCOL_WCCP: + (void)snpf(buf, buf_len, "WCCP"); + break; + case LSOF_PROTOCOL_MPLS_UC: + (void)snpf(buf, buf_len, "MPLS_UC"); + break; + case LSOF_PROTOCOL_MPLS_MC: + (void)snpf(buf, buf_len, "MPLS_MC"); + break; + case LSOF_PROTOCOL_ATMMPOA: + (void)snpf(buf, buf_len, "ATMMPOA"); + break; + case LSOF_PROTOCOL_PPP_DISC: + (void)snpf(buf, buf_len, "PPPDISC"); + break; + case LSOF_PROTOCOL_PPP_SES: + (void)snpf(buf, buf_len, "PPP_SES"); + break; + case LSOF_PROTOCOL_LINK_CTL: + (void)snpf(buf, buf_len, "LINKCTL"); + break; + case LSOF_PROTOCOL_ATMFATE: + (void)snpf(buf, buf_len, "ATMFATE"); + break; + case LSOF_PROTOCOL_PAE: + (void)snpf(buf, buf_len, "PAE"); + break; + case LSOF_PROTOCOL_PROFINET: + (void)snpf(buf, buf_len, "PROFINT"); + break; + case LSOF_PROTOCOL_REALTEK: + (void)snpf(buf, buf_len, "REALTEK"); + break; + case LSOF_PROTOCOL_AOE: + (void)snpf(buf, buf_len, "AOE"); + break; + case LSOF_PROTOCOL_ETHERCAT: + (void)snpf(buf, buf_len, "ETHCAT"); + break; + case LSOF_PROTOCOL_8021AD: + (void)snpf(buf, buf_len, "8021AD"); + break; + case LSOF_PROTOCOL_802_EX1: + (void)snpf(buf, buf_len, "802_EX1"); + break; + case LSOF_PROTOCOL_ERSPAN: + (void)snpf(buf, buf_len, "ERSPAN"); + break; + case LSOF_PROTOCOL_PREAUTH: + (void)snpf(buf, buf_len, "PREAUTH"); + break; + case LSOF_PROTOCOL_TIPC: + (void)snpf(buf, buf_len, "TIPC"); + break; + case LSOF_PROTOCOL_LLDP: + (void)snpf(buf, buf_len, "LLDP"); + break; + case LSOF_PROTOCOL_MRP: + (void)snpf(buf, buf_len, "MRP"); + break; + case LSOF_PROTOCOL_MACSEC: + (void)snpf(buf, buf_len, "MACSEC"); + break; + case LSOF_PROTOCOL_8021AH: + (void)snpf(buf, buf_len, "8021AH"); + break; + case LSOF_PROTOCOL_MVRP: + (void)snpf(buf, buf_len, "MVRP"); + break; + case LSOF_PROTOCOL_1588: + (void)snpf(buf, buf_len, "1588"); + break; + case LSOF_PROTOCOL_NCSI: + (void)snpf(buf, buf_len, "NCSI"); + break; + case LSOF_PROTOCOL_PRP: + (void)snpf(buf, buf_len, "PRP"); + break; + case LSOF_PROTOCOL_CFM: + (void)snpf(buf, buf_len, "CFM"); + break; + case LSOF_PROTOCOL_FCOE: + (void)snpf(buf, buf_len, "FCOE"); + break; + case LSOF_PROTOCOL_TDLS: + (void)snpf(buf, buf_len, "TDLS"); + break; + case LSOF_PROTOCOL_FIP: + (void)snpf(buf, buf_len, "FIP"); + break; + case LSOF_PROTOCOL_IBOE: + (void)snpf(buf, buf_len, "IBOE"); + break; + case LSOF_PROTOCOL_80221: + (void)snpf(buf, buf_len, "80221"); + break; + case LSOF_PROTOCOL_HSR: + (void)snpf(buf, buf_len, "HSR"); + break; + case LSOF_PROTOCOL_NSH: + (void)snpf(buf, buf_len, "NSH"); + break; + case LSOF_PROTOCOL_LOOPBACK: + (void)snpf(buf, buf_len, "LOOPBAK"); + break; + case LSOF_PROTOCOL_QINQ1: + (void)snpf(buf, buf_len, "QINQ1"); + break; + case LSOF_PROTOCOL_QINQ2: + (void)snpf(buf, buf_len, "QINQ2"); + break; + case LSOF_PROTOCOL_QINQ3: + (void)snpf(buf, buf_len, "QINQ3"); + break; + case LSOF_PROTOCOL_EDSA: + (void)snpf(buf, buf_len, "EDSA"); + break; + case LSOF_PROTOCOL_DSA_8021Q: + (void)snpf(buf, buf_len, "DSAD1Q"); + break; + case LSOF_PROTOCOL_DSA_A5PSW: + (void)snpf(buf, buf_len, "DSA5PSW"); + break; + case LSOF_PROTOCOL_IFE: + (void)snpf(buf, buf_len, "IFE"); + break; + case LSOF_PROTOCOL_AF_IUCV: + (void)snpf(buf, buf_len, "AF_IUCV"); + break; + + /* Others */ + case LSOF_PROTOCOL_8025: + (void)snpf(buf, buf_len, "802.5"); + break; + case LSOF_PROTOCOL_CCITT: + (void)snpf(buf, buf_len, "CCITT"); + break; + case LSOF_PROTOCOL_STR: + (void)snpf(buf, buf_len, "STR"); + break; + case LSOF_PROTOCOL_SHARED: + (void)snpf(buf, buf_len, "SHARED"); + break; + } +} + +/* + * printsockty() - print socket type + */ +char *printsockty(int ty) /* socket type -- e.g., from so_type */ +{ + static char buf[64]; + char *cp; + + switch (ty) { + +#if defined(SOCK_STREAM) + case SOCK_STREAM: + cp = "STREAM"; + break; +#endif /* defined(SOCK_STREAM) */ + +#if defined(SOCK_STREAM) + case SOCK_DGRAM: + cp = "DGRAM"; + break; +#endif /* defined(SOCK_DGRAM) */ + +#if defined(SOCK_RAW) + case SOCK_RAW: + cp = "RAW"; + break; +#endif /* defined(SOCK_RAW) */ + +#if defined(SOCK_RDM) + case SOCK_RDM: + cp = "RDM"; + break; +#endif /* defined(SOCK_RDM) */ + +#if defined(SOCK_SEQPACKET) + case SOCK_SEQPACKET: + cp = "SEQPACKET"; + break; +#endif /* defined(SOCK_SEQPACKET) */ + + default: + (void)snpf(buf, sizeof(buf), "SOCK_%#x", ty); + return (buf); + } + (void)snpf(buf, sizeof(buf), "SOCK_%s", cp); + return (buf); +} diff --git a/lib/proc.c b/lib/proc.c index 2a015885..7112f855 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -1,5 +1,5 @@ /* - * proc.c - common process and file structure functions for lsof + * proc.c - common process and file structure functions for liblsof */ /* @@ -29,7 +29,6 @@ */ #include "common.h" -#include "dlsof.h" #include "lsof.h" #if defined(HASEPTOPTS) @@ -50,6 +49,7 @@ void add_nma(struct lsof_context *ctx, char *cp, /* string to add */ int len) /* string length */ { int nl; + char fd[FDLEN]; if (!cp || !len) return; @@ -62,9 +62,11 @@ void add_nma(struct lsof_context *ctx, char *cp, /* string to add */ Lf->nma = (char *)malloc((MALLOC_S)(len + 1)); } if (!Lf->nma) { - (void)fprintf(stderr, "%s: no name addition space: PID %ld, FD %s", Pn, - (long)Lp->pid, Lf->fd); - Error(ctx); + if (ctx->err) + (void)fprintf(ctx->err, + "%s: no name addition space: PID %ld, FD %s", Pn, + (long)Lp->pid, fd); + return; } if (nl) { Lf->nma[nl] = ' '; @@ -76,44 +78,13 @@ void add_nma(struct lsof_context *ctx, char *cp, /* string to add */ } } -#if defined(HASFSTRUCT) -static char *alloc_fflbuf(struct lsof_context *ctx, char **bp, int *al, int lr); - -/* - * alloc_fflbuf() - allocate file flags print buffer - */ - -static char *alloc_fflbuf(struct lsof_context *ctx, - char **bp, /* current buffer pointer */ - int *al, /* current allocated length */ - int lr) /* length required */ -{ - int sz; - - sz = (int)(lr + 1); /* allocate '\0' space */ - if (*bp && (sz <= *al)) - return (*bp); - if (*bp) - *bp = (char *)realloc((MALLOC_P *)*bp, (MALLOC_S)sz); - else - *bp = (char *)malloc((MALLOC_S)sz); - if (!*bp) { - (void)fprintf(stderr, "%s: no space (%d) for print flags\n", Pn, sz); - Error(ctx); - } - *al = sz; - return (*bp); -} -#endif /* defined(HASFSTRUCT) */ - /* * alloc_lfile() - allocate local file structure space */ - void alloc_lfile(struct lsof_context *ctx, - char *nm, /* file descriptor name (may be NULL) */ - int num) /* file descriptor number -- -1 if - * none */ + enum lsof_fd_type fd_type, /* file descriptor type */ + int num) /* file descriptor number -- -1 if + * none */ { int fds; @@ -122,12 +93,10 @@ void alloc_lfile(struct lsof_context *ctx, * If reusing a previously allocated structure, release any allocated * space it was using. */ - if (Lf->dev_ch) - (void)free((FREE_P *)Lf->dev_ch); - if (Lf->nm) - (void)free((FREE_P *)Lf->nm); - if (Lf->nma) - (void)free((FREE_P *)Lf->nma); + CLEAN(Lf->dev_ch); + CLEAN(Lf->nm); + CLEAN(Lf->nma); + memset(Lf, 0, sizeof(struct lfile)); #if defined(HASLFILEADD) && defined(CLRLFILEADD) CLRLFILEADD(Lf) @@ -137,20 +106,23 @@ void alloc_lfile(struct lsof_context *ctx, * Othwerise, allocate a new structure. */ } else if (!(Lf = (struct lfile *)malloc(sizeof(struct lfile)))) { - (void)fprintf(stderr, "%s: no local file space at PID %d\n", Pn, - Lp->pid); + if (ctx->err) + (void)fprintf(ctx->err, "%s: no local file space at PID %d\n", Pn, + Lp->pid); Error(ctx); + return; } /* * Initialize the structure. */ Lf->access = LSOF_FILE_ACCESS_NONE; - Lf->lock = ' '; - Lf->dev_def = Lf->inp_ty = Lf->is_com = Lf->is_nfs = Lf->is_stream = + Lf->lock = LSOF_LOCK_NONE; + Lf->dev_def = Lf->inode_def = Lf->is_com = Lf->is_nfs = Lf->is_stream = Lf->lmi_srch = Lf->nlink_def = Lf->off_def = Lf->sz_def = Lf->rdev_def = (unsigned char)0; Lf->li[0].af = Lf->li[1].af = 0; Lf->lts.type = -1; + Lf->lts.state.i = 0; Lf->nlink = 0l; #if defined(HASMNTSTAT) @@ -205,17 +177,11 @@ void alloc_lfile(struct lsof_context *ctx, Lf->sf = Lp->sf; else Lf->sf = 0; - Lf->iproto[0] = Lf->type[0] = '\0'; - if (nm) { - (void)strncpy(Lf->fd, nm, FDLEN - 1); - Lf->fd[FDLEN - 1] = '\0'; - } else if (num >= 0) { - if (num < 10000) - (void)snpf(Lf->fd, sizeof(Lf->fd), "%4d", num); - else - (void)snpf(Lf->fd, sizeof(Lf->fd), "*%03d", num % 1000); - } else - Lf->fd[0] = '\0'; + Lf->iproto = LSOF_PROTOCOL_INVALID; + Lf->type = LSOF_FILE_UNKNOWN; + Lf->unknown_file_type_number = 0; + Lf->fd_type = fd_type; + Lf->fd_num = num; Lf->dev_ch = Lf->fsdir = Lf->fsdev = Lf->nm = Lf->nma = (char *)NULL; Lf->ch = -1; @@ -224,7 +190,7 @@ void alloc_lfile(struct lsof_context *ctx, #endif /* defined(HASNCACHE) && HASNCACHE<2 */ Lf->next = (struct lfile *)NULL; - Lf->ntype = Ntype = N_REGLR; + Ntype = N_REGLR; Namech[0] = '\0'; #if defined(HASFSTRUCT) @@ -243,9 +209,9 @@ void alloc_lfile(struct lsof_context *ctx, /* * See if the file descriptor has been selected. */ - if (!Fdl || (!nm && num < 0)) + if (!Fdl || (fd_type == LSOF_FD_NUMERIC && num < 0)) return; - fds = ck_fd_status(ctx, nm, num); + fds = ck_fd_status(ctx, fd_type, num); switch (FdlTy) { case 0: /* inclusion list */ if (fds == 2) @@ -269,25 +235,30 @@ void alloc_lproc(struct lsof_context *ctx, int pid, /* Process ID */ int pss, /* process select state */ int sf) /* process select flags */ { - static int sz = 0; - if (!Lproc) { if (!(Lproc = (struct lproc *)malloc( (MALLOC_S)(LPROCINCR * sizeof(struct lproc))))) { - (void)fprintf(stderr, - "%s: no malloc space for %d local proc structures\n", - Pn, LPROCINCR); + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: no malloc space for %d local proc structures\n", Pn, + LPROCINCR); Error(ctx); + return; } - sz = LPROCINCR; - } else if ((Nlproc + 1) > sz) { - sz += LPROCINCR; + ctx->procs_cap = LPROCINCR; + } else if ((Nlproc + 1) > ctx->procs_cap) { + ctx->procs_cap += LPROCINCR; if (!(Lproc = (struct lproc *)realloc( - (MALLOC_P *)Lproc, (MALLOC_S)(sz * sizeof(struct lproc))))) { - (void)fprintf(stderr, - "%s: no realloc space for %d local proc structures\n", - Pn, sz); + (MALLOC_P *)Lproc, + (MALLOC_S)(ctx->procs_cap * sizeof(struct lproc))))) { + if (ctx->err) + (void)fprintf( + ctx->err, + "%s: no realloc space for %zu local proc structures\n", Pn, + ctx->procs_cap); Error(ctx); + return; } } Lp = &Lproc[Nlproc++]; @@ -312,10 +283,13 @@ void alloc_lproc(struct lsof_context *ctx, int pid, /* Process ID */ * Allocate space for the full command name and copy it there. */ if (!(Lp->cmd = mkstrcpy(cmd, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: PID %d, no space for command name: ", Pn, - pid); - safestrprt(cmd, stderr, 1); + if (ctx->err) { + (void)fprintf(ctx->err, + "%s: PID %d, no space for command name: ", Pn, pid); + safestrprt(cmd, ctx->err, 1); + } Error(ctx); + return; } #if defined(HASZONES) @@ -341,33 +315,29 @@ void alloc_lproc(struct lsof_context *ctx, int pid, /* Process ID */ * 1 == FD is excluded * 2 == FD is included */ - -extern int ck_fd_status(struct lsof_context *ctx, - char *nm, /* file descriptor name (may be NULL) */ - int num) /* file descriptor number -- -1 if - * none */ +int ck_fd_status(struct lsof_context *ctx, + enum lsof_fd_type fd_type, /* file descriptor type */ + int num) /* file descriptor number -- -1 if + * none */ { - char *cp; struct fd_lst *fp; - if (!(fp = Fdl) || (!nm && num < 0)) + if (!(fp = Fdl) || (fd_type == LSOF_FD_NUMERIC && num < 0)) return (0); - if ((cp = nm)) { - while (*cp && *cp == ' ') - cp++; - } + /* * Check for an exclusion match. */ if (FdlTy == 1) { for (; fp; fp = fp->next) { - if (cp) { - if (fp->nm && strcmp(fp->nm, cp) == 0) - return (1); + if (fp->fd_type != fd_type) continue; - } - if (num >= fp->lo && num <= fp->hi) + if (fp->fd_type == LSOF_FD_NUMERIC) { + if (num >= fp->lo && num <= fp->hi) + return (1); + } else { return (1); + } } return (0); } @@ -375,13 +345,14 @@ extern int ck_fd_status(struct lsof_context *ctx, * If Fdl isn't an exclusion list, check for an inclusion match. */ for (; fp; fp = fp->next) { - if (cp) { - if (fp->nm && strcmp(fp->nm, cp) == 0) - return (2); + if (fp->fd_type != fd_type) continue; - } - if (num >= fp->lo && num <= fp->hi) + if (fp->fd_type == LSOF_FD_NUMERIC) { + if (num >= fp->lo && num <= fp->hi) + return (2); + } else { return (2); + } } return (0); } @@ -390,7 +361,9 @@ extern int ck_fd_status(struct lsof_context *ctx, * comppid() - compare PIDs */ -int comppid(COMP_P *a1, COMP_P *a2) { +int comppid(a1, a2) +COMP_P *a1, *a2; +{ struct lproc **p1 = (struct lproc **)a1; struct lproc **p2 = (struct lproc **)a2; @@ -455,8 +428,8 @@ void ent_inaddr(struct lsof_context *ctx, * If network address matching has been selected, check both addresses. */ if ((Selflags & SELNA) && Nwad) { - m = (fa && is_nw_addr(fa, fp, af)) ? 1 : 0; - m |= (la && is_nw_addr(la, lp, af)) ? 1 : 0; + m = (fa && is_nw_addr(ctx, fa, fp, af)) ? 1 : 0; + m |= (la && is_nw_addr(ctx, la, lp, af)) ? 1 : 0; if (m) Lf->sf |= SELNA; } @@ -471,8 +444,6 @@ void ent_inaddr(struct lsof_context *ctx, int examine_lproc(struct lsof_context *ctx) { int sbp = 0; - if (RptTm) - return (0); /* * List the process if the process is selected and: * @@ -487,14 +458,6 @@ int examine_lproc(struct lsof_context *ctx) { Npuns--; } } - if (Lp->pss && Npid == 1 && sbp) { - print_init(); - (void)print_proc(ctx); - PrPass++; - if (PrPass < 2) - (void)print_proc(ctx); - Lp->pss = 0; - } /* * Deprecate an unselected (or listed) process. */ @@ -513,7 +476,8 @@ int examine_lproc(struct lsof_context *ctx) { * free_lproc() - free lproc entry and its associated malloc'd space */ -void free_lproc(struct lproc *lp) { +void free_lproc(lp) struct lproc *lp; +{ struct lfile *lf, *nf; for (lf = lp->file; lf; lf = nf) { @@ -612,12 +576,13 @@ int is_cmd_excl(struct lsof_context *ctx, char *cmd, /* command name */ * is_file_sel() - is file selected? */ -int is_file_sel(struct lproc *lp, /* lproc structure pointer */ +int is_file_sel(struct lsof_context *ctx, + struct lproc *lp, /* lproc structure pointer */ struct lfile *lf) /* lfile structure pointer */ { if (!lf || !lf->sf) return (0); - if (Lf->sf & SELEXCLF) + if (lf->sf & SELEXCLF) return (0); #if defined(HASSECURITY) && defined(HASNOSOCKSECURITY) @@ -642,25 +607,23 @@ int is_proc_excl(struct lsof_context *ctx, int pid, /* Process ID */ int pgid, /* process group ID */ UID_ARG uid, /* User ID */ short *pss, /* process select state for lproc */ + short *sf /* select flags for lproc */ #if defined(HASTASKS) - short *sf, /* select flags for lproc */ - int tid) /* task ID (not a task if zero) */ -#else - short *sf) /* select flags for lproc */ -#endif /* defined(HASTASKS) */ - -{ + , + int tid /* task ID (not a task if zero) */ +#endif /* defined(HASTASKS) */ +) { int i, j; *pss = *sf = 0; #if defined(HASSECURITY) -/* - * The process is excluded by virtue of the security option if it - * isn't owned by the owner of this lsof process, unless the - * HASNOSOCKSECURITY option is also specified. In that case the - * selected socket files of any process may be listed. - */ + /* + * The process is excluded by virtue of the security option if it + * isn't owned by the owner of this lsof process, unless the + * HASNOSOCKSECURITY option is also specified. In that case the + * selected socket files of any process may be listed. + */ # if !defined(HASNOSOCKSECURITY) if (Myuid && Myuid != (uid_t)uid) return (1); @@ -848,7 +811,6 @@ int is_proc_excl(struct lsof_context *ctx, int pid, /* Process ID */ /* * link_lfile() - link local file structures */ - void link_lfile(struct lsof_context *ctx) { if (Lf->sf & SELEXCLF) return; @@ -922,11 +884,11 @@ void link_lfile(struct lsof_context *ctx) { Lf->sf &= ~SELNETS6INFO; } # endif /* defined(HASIPv6) */ - /* - * Process eventfd endpoint files the same way by clearing the - * SELEVTFDINFO flag and setting the EPT_EVTFD flag, letting a later - * call to process_evtfdinfo() set selection flags. - */ + /* + * Process eventfd endpoint files the same way by clearing the + * SELEVTFDINFO flag and setting the EPT_EVTFD flag, letting a later + * call to process_evtfdinfo() set selection flags. + */ if (Lf->sf & SELEVTFDINFO) { Lp->ept |= EPT_EVTFD; Lf->sf &= ~SELEVTFDINFO; @@ -967,7 +929,7 @@ void process_pinfo(struct lsof_context *ctx, if (!FeptE) return; for (Lf = Lp->file; Lf; Lf = Lf->next) { - if ((Lf->ntype != N_FIFO) || (Lf->inp_ty != 1)) + if ((Ntype != N_FIFO) || !Lf->inode_def) continue; pp = (pxinfo_t *)NULL; switch (f) { @@ -976,7 +938,7 @@ void process_pinfo(struct lsof_context *ctx, /* * Process already selected pipe file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -997,7 +959,7 @@ void process_pinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_PIPE)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_PIPE)) { /* * This is an unselected end point file. Select it and add @@ -1030,15 +992,13 @@ static void prt_pinfo(struct lsof_context *ctx, pxinfo_t *pp, /* peer info */ struct lfile *ef; /* pipe endpoint file */ int i; /* temporary index */ char nma[1024]; /* name addition buffer */ + char fd[FDLEN]; ep = &Lproc[pp->lpx]; ef = pp->lf; - for (i = 0; i < (FDLEN - 1); i++) { - if (ef->fd[i] != ' ') - break; - } - (void)snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c", ep->pid, CmdLim, ep->cmd, - &ef->fd[i], access_to_char(ef->access)); + print_fd(ef->fd_type, ef->fd_num, fd); + (void)snpf(nma, sizeof(nma) - 1, "%d,%s,%s%c", ep->pid, ep->cmd, fd, + print_access(ef->access)); (void)add_nma(ctx, nma, strlen(nma)); if (ps) { @@ -1076,7 +1036,7 @@ void process_psxmqinfo(struct lsof_context *ctx, /* * Process already selected posix mq file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -1097,7 +1057,7 @@ void process_psxmqinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_PSXMQ)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_PSXMQ)) { /* * This is an unselected end point file. Select it and add @@ -1131,15 +1091,13 @@ static void prt_psxmqinfo(struct lsof_context *ctx, struct lfile *ef; /* posix mq endpoint file */ int i; /* temporary index */ char nma[1024]; /* name addition buffer */ + char fd[FDLEN]; ep = &Lproc[pp->lpx]; ef = pp->lf; - for (i = 0; i < (FDLEN - 1); i++) { - if (ef->fd[i] != ' ') - break; - } - (void)snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c", ep->pid, CmdLim, ep->cmd, - &ef->fd[i], access_to_char(ef->access)); + print_fd(ef->fd_type, ef->fd_num, fd); + (void)snpf(nma, sizeof(nma) - 1, "%d,%s,%s%c", ep->pid, ep->cmd, fd, + print_access(ef->access)); (void)add_nma(ctx, nma, strlen(nma)); if (ps) { @@ -1168,7 +1126,7 @@ void process_evtfdinfo(struct lsof_context *ctx, if (!FeptE) return; for (Lf = Lp->file; Lf; Lf = Lf->next) { - if ((Lf->ntype != N_ANON_INODE) || (Lf->eventfd_id == -1)) + if ((Ntype != N_ANON_INODE) || (Lf->eventfd_id == -1)) continue; pp = (pxinfo_t *)NULL; switch (f) { @@ -1177,7 +1135,7 @@ void process_evtfdinfo(struct lsof_context *ctx, /* * Process already selected eventfd_id file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -1198,7 +1156,7 @@ void process_evtfdinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_EVTFD)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_EVTFD)) { /* * This is an unselected end point file. Select it and add @@ -1232,15 +1190,13 @@ static void prt_evtfdinfo(struct lsof_context *ctx, struct lfile *ef; /* eventfd endpoint file */ int i; /* temporary index */ char nma[1024]; /* name addition buffer */ + char fd[FDLEN]; ep = &Lproc[pp->lpx]; ef = pp->lf; - for (i = 0; i < (FDLEN - 1); i++) { - if (ef->fd[i] != ' ') - break; - } - (void)snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c", ep->pid, CmdLim, ep->cmd, - &ef->fd[i], access_to_char(ef->access)); + print_fd(ef->fd_type, ef->fd_num, fd); + (void)snpf(nma, sizeof(nma) - 1, "%d,%s,%s%c", ep->pid, ep->cmd, fd, + print_access(ef->access)); (void)add_nma(ctx, nma, strlen(nma)); if (ps) { @@ -1254,330 +1210,6 @@ static void prt_evtfdinfo(struct lsof_context *ctx, } #endif /* defined(HASEPTOPTS) */ -#if defined(HASFSTRUCT) -/* - * print_fflags() - print interpreted f_flag[s] - */ - -char *print_fflags(struct lsof_context *ctx, - long ffg, /* file structure's flags value */ - long pof) /* process open files flags value */ -{ - int al, ct, fx; - static int bl = 0; - static char *bp = (char *)NULL; - char *sep; - int sepl; - struct pff_tab *tp; - long wf; - char xbuf[64]; - /* - * Reduce the supplied flags according to the definitions in Pff_tab[] and - * Pof_tab[]. - */ - for (ct = fx = 0; fx < 2; fx++) { - if (fx == 0) { - sep = ""; - sepl = 0; - tp = Pff_tab; - wf = ffg; - } else { - sep = ";"; - sepl = 1; - tp = Pof_tab; - wf = pof; - } - for (; wf && !FsvFlagX; ct += al) { - while (tp->nm) { - if (wf & tp->val) - break; - tp++; - } - if (!tp->nm) - break; - al = (int)strlen(tp->nm) + sepl; - bp = alloc_fflbuf(ctx, &bp, &bl, al + ct); - (void)snpf(bp + ct, al + 1, "%s%s", sep, tp->nm); - sep = ","; - sepl = 1; - wf &= ~(tp->val); - } - /* - * If flag bits remain, print them in hex. If hex output was - * specified with +fG, print all flag values, including zero, - * in hex. - */ - if (wf || FsvFlagX) { - (void)snpf(xbuf, sizeof(xbuf), "0x%lx", wf); - al = (int)strlen(xbuf) + sepl; - bp = alloc_fflbuf(ctx, &bp, &bl, al + ct); - (void)snpf(bp + ct, al + 1, "%s%s", sep, xbuf); - ct += al; - } - } - /* - * Make sure there is at least a NUL terminated reply. - */ - if (!bp) { - bp = alloc_fflbuf(ctx, &bp, &bl, 0); - *bp = '\0'; - } - return (bp); -} -#endif /* defined(HASFSTRUCT) */ - -/* - * print_proc() - print process - */ - -int print_proc(struct lsof_context *ctx) { - char buf[128], *cp; - int lc, len, st, ty; - int rv = 0; - unsigned long ul; - /* - * If nothing in the process has been selected, skip it. - */ - if (!Lp->pss) - return (0); - if (Fterse) { - if (Lp->pid == LastPid) /* eliminate duplicates */ - return (0); - LastPid = Lp->pid; - /* - * The mode is terse and something in the process appears to have - * been selected. Make sure of that by looking for a selected file, - * so that the HASSECURITY and HASNOSOCKSECURITY option combination - * won't produce a false positive result. - */ - for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (is_file_sel(Lp, Lf)) { - (void)printf("%d\n", Lp->pid); - return (1); - } - } - return (0); - } - /* - * If fields have been selected, output the process-only ones, provided - * that some file has also been selected. - */ - if (Ffield) { - for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (is_file_sel(Lp, Lf)) - break; - } - if (!Lf) - return (rv); - rv = 1; - (void)printf("%c%d%c", LSOF_FID_PID, Lp->pid, Terminator); - -#if defined(HASTASKS) - if (FieldSel[LSOF_FIX_TID].st && Lp->tid) - (void)printf("%c%d%c", LSOF_FID_TID, Lp->tid, Terminator); - if (FieldSel[LSOF_FIX_TCMD].st && Lp->tcmd) - (void)printf("%c%s%c", LSOF_FID_TCMD, Lp->tcmd, Terminator); -#endif /* defined(HASTASKS) */ - -#if defined(HASZONES) - if (FieldSel[LSOF_FIX_ZONE].st && Fzone && Lp->zn) - (void)printf("%c%s%c", LSOF_FID_ZONE, Lp->zn, Terminator); -#endif /* defined(HASZONES) */ - -#if defined(HASSELINUX) - if (FieldSel[LSOF_FIX_CNTX].st && Fcntx && Lp->cntx && CntxStatus) - (void)printf("%c%s%c", LSOF_FID_CNTX, Lp->cntx, Terminator); -#endif /* defined(HASSELINUX) */ - - if (FieldSel[LSOF_FIX_PGID].st && Fpgid) - (void)printf("%c%d%c", LSOF_FID_PGID, Lp->pgid, Terminator); - -#if defined(HASPPID) - if (FieldSel[LSOF_FIX_PPID].st && Fppid) - (void)printf("%c%d%c", LSOF_FID_PPID, Lp->ppid, Terminator); -#endif /* defined(HASPPID) */ - - if (FieldSel[LSOF_FIX_CMD].st) { - putchar(LSOF_FID_CMD); - safestrprt(Lp->cmd ? Lp->cmd : "(unknown)", stdout, 0); - putchar(Terminator); - } - if (FieldSel[LSOF_FIX_UID].st) - (void)printf("%c%d%c", LSOF_FID_UID, (int)Lp->uid, Terminator); - if (FieldSel[LSOF_FIX_LOGIN].st) { - cp = printuid(ctx, (UID_ARG)Lp->uid, &ty); - if (ty == 0) - (void)printf("%c%s%c", LSOF_FID_LOGIN, cp, Terminator); - } - if (Terminator == '\0') - putchar('\n'); - } - /* - * Print files. - */ - for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (!is_file_sel(Lp, Lf)) - continue; - rv = 1; - /* - * If no field output selected, print dialect-specific formatted - * output. - */ - if (!Ffield) { - print_file(ctx); - continue; - } - lc = st = 0; - if (FieldSel[LSOF_FIX_FD].st) { - - /* - * Skip leading spaces in the file descriptor. Print the field - * identifier even if there are no characters after leading - * spaces. - */ - for (cp = Lf->fd; *cp == ' '; cp++) - ; - (void)printf("%c%s%c", LSOF_FID_FD, cp, Terminator); - lc++; - } - /* - * Print selected fields. - */ - if (FieldSel[LSOF_FIX_ACCESS].st) { - (void)printf("%c%c%c", LSOF_FID_ACCESS, access_to_char(Lf->access), - Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_LOCK].st) { - (void)printf("%c%c%c", LSOF_FID_LOCK, Lf->lock, Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_TYPE].st) { - for (cp = Lf->type; *cp == ' '; cp++) - ; - if (*cp) { - (void)printf("%c%s%c", LSOF_FID_TYPE, cp, Terminator); - lc++; - } - } - -#if defined(HASFSTRUCT) - if (FieldSel[LSOF_FIX_FA].st && (Fsv & FSV_FA) && (Lf->fsv & FSV_FA)) { - (void)printf("%c%s%c", LSOF_FID_FA, - print_kptr(Lf->fsa, (char *)NULL, 0), Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_CT].st && (Fsv & FSV_CT) && (Lf->fsv & FSV_CT)) { - (void)printf("%c%ld%c", LSOF_FID_CT, Lf->fct, Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_FG].st && (Fsv & FSV_FG) && (Lf->fsv & FSV_FG) && - (FsvFlagX || Lf->ffg || Lf->pof)) { - (void)printf("%c%s%c", LSOF_FID_FG, - print_fflags(ctx, Lf->ffg, Lf->pof), Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_NI].st && (Fsv & FSV_NI) && (Lf->fsv & FSV_NI)) { - (void)printf("%c%s%c", LSOF_FID_NI, - print_kptr(Lf->fna, (char *)NULL, 0), Terminator); - lc++; - } -#endif /* defined(HASFSTRUCT) */ - - if (FieldSel[LSOF_FIX_DEVCH].st && Lf->dev_ch && Lf->dev_ch[0]) { - for (cp = Lf->dev_ch; *cp == ' '; cp++) - ; - if (*cp) { - (void)printf("%c%s%c", LSOF_FID_DEVCH, cp, Terminator); - lc++; - } - } - if (FieldSel[LSOF_FIX_DEVN].st && Lf->dev_def) { - if (sizeof(unsigned long) > sizeof(dev_t)) - ul = (unsigned long)((unsigned int)Lf->dev); - else - ul = (unsigned long)Lf->dev; - (void)printf("%c0x%lx%c", LSOF_FID_DEVN, ul, Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_RDEV].st && Lf->rdev_def) { - if (sizeof(unsigned long) > sizeof(dev_t)) - ul = (unsigned long)((unsigned int)Lf->rdev); - else - ul = (unsigned long)Lf->rdev; - (void)printf("%c0x%lx%c", LSOF_FID_RDEV, ul, Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_SIZE].st && Lf->sz_def) { - putchar(LSOF_FID_SIZE); - - (void)snpf(buf, sizeof(buf), SzOffFmt_d, Lf->sz); - cp = buf; - - (void)printf("%s", cp); - putchar(Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_OFFSET].st && Lf->off_def) { - putchar(LSOF_FID_OFFSET); - - (void)snpf(buf, sizeof(buf), SzOffFmt_0t, Lf->off); - cp = buf; - - len = strlen(cp); - if (OffDecDig && len > (OffDecDig + 2)) { - - (void)snpf(buf, sizeof(buf), SzOffFmt_x, Lf->off); - cp = buf; - } - (void)printf("%s", cp); - putchar(Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_INODE].st && Lf->inp_ty == 1) { - putchar(LSOF_FID_INODE); - (void)printf(InodeFmt_d, Lf->inode); - putchar(Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_NLINK].st && Lf->nlink_def) { - (void)printf("%c%ld%c", LSOF_FID_NLINK, Lf->nlink, Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_PROTO].st && Lf->inp_ty == 2) { - for (cp = Lf->iproto; *cp == ' '; cp++) - ; - if (*cp) { - (void)printf("%c%s%c", LSOF_FID_PROTO, cp, Terminator); - lc++; - } - } - if (FieldSel[LSOF_FIX_STREAM].st && Lf->nm && Lf->is_stream) { - if (strncmp(Lf->nm, "STR:", 4) == 0 || - strcmp(Lf->iproto, "STR") == 0) { - putchar(LSOF_FID_STREAM); - printname(ctx, 0); - putchar(Terminator); - lc++; - st++; - } - } - if (st == 0 && FieldSel[LSOF_FIX_NAME].st) { - putchar(LSOF_FID_NAME); - printname(ctx, 0); - putchar(Terminator); - lc++; - } - if (Lf->lts.type >= 0 && FieldSel[LSOF_FIX_TCPTPI].st) { - print_tcptpi(ctx, 0); - lc++; - } - if (Terminator == '\0' && lc) - putchar('\n'); - } - return (rv); -} - #if defined(HASPTYEPT) /* * process_ptyinfo() -- process pseudoterminal info, adding it to selected files @@ -1611,7 +1243,7 @@ void process_ptyinfo(struct lsof_context *ctx, /* * Process already selected pseudoterminal file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -1635,7 +1267,7 @@ void process_ptyinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_PTY)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_PTY)) { /* * This is an unselected end point file. Select it and add @@ -1671,20 +1303,18 @@ static void prt_ptyinfo(struct lsof_context *ctx, pxinfo_t *pp, /* peer info */ struct lfile *ef; /* pseudoterminal endpoint file */ int i; /* temporary index */ char nma[1024]; /* name addition buffer */ + char fd[FDLEN]; ep = &Lproc[pp->lpx]; ef = pp->lf; - for (i = 0; i < (FDLEN - 1); i++) { - if (ef->fd[i] != ' ') - break; - } + print_fd(ef->fd_type, ef->fd_num, fd); if (prt_edev) { - (void)snpf(nma, sizeof(nma) - 1, "->/dev/pts/%d %d,%.*s,%s%c", - Lf->tty_index, ep->pid, CmdLim, ep->cmd, &ef->fd[i], - access_to_char(ef->access)); + (void)snpf(nma, sizeof(nma) - 1, "->/dev/pts/%d %d,%s,%s%c", + Lf->tty_index, ep->pid, ep->cmd, fd, + print_access(ef->access)); } else { - (void)snpf(nma, sizeof(nma) - 1, "%d,%.*s,%s%c", ep->pid, CmdLim, - ep->cmd, &ef->fd[i], access_to_char(ef->access)); + (void)snpf(nma, sizeof(nma) - 1, "%d,%s,%s%c", ep->pid, ep->cmd, fd, + print_access(ef->access)); } (void)add_nma(ctx, nma, strlen(nma)); if (ps) { @@ -1698,3 +1328,108 @@ static void prt_ptyinfo(struct lsof_context *ctx, pxinfo_t *pp, /* peer info */ } } #endif /* defined(HASPTYEPT) */ + +/* + * clean_lfile() - free local file structure space + */ +void clean_lfile(struct lsof_context *ctx, struct lfile *lf) { + CLEAN(lf->dev_ch); + CLEAN(lf->nm); + CLEAN(lf->nma); + memset(lf, 0, sizeof(struct lfile)); +} + +/* + * Error(ctx) - exit with an error status when ctx->exit_on_fatal = 1; + */ +void Error(struct lsof_context *ctx) { + if (ctx->exit_on_fatal) + Exit(ctx, LSOF_EXIT_ERROR); +} + +/* + * Exit() - do a clean exit() + */ +void Exit(struct lsof_context *ctx, enum ExitStatus xv) /* exit() value */ +{ + (void)childx(ctx); + +#if defined(HASDCACHE) + if (DCrebuilt && !Fwarn && ctx->err) + (void)fprintf(ctx->err, "%s: WARNING: %s was updated.\n", Pn, + DCpath[DCpathX]); +#endif /* defined(HASDCACHE) */ + + exit(xv); +} + +/* Print lsof_fd_type and fd_num, sizeof(buf) should >= FDLEN */ +void print_fd(enum lsof_fd_type fd_type, int fd_num, char *buf) { + switch (fd_type) { + case LSOF_FD_NUMERIC: + /* strlen("TYPE") == 4, try to match width */ + if (fd_num < 10000) + (void)snpf(buf, FDLEN, "%d", fd_num); + else + (void)snpf(buf, FDLEN, "*%03d", fd_num % 1000); + break; + case LSOF_FD_UNKNOWN: + (void)snpf(buf, FDLEN, "unk"); + break; + case LSOF_FD_CWD: + (void)snpf(buf, FDLEN, "cwd"); + break; + case LSOF_FD_ERROR: + (void)snpf(buf, FDLEN, "err"); + break; + case LSOF_FD_ROOT_DIR: + (void)snpf(buf, FDLEN, "rtd"); + break; + case LSOF_FD_PARENT_DIR: + (void)snpf(buf, FDLEN, "pd"); + break; + case LSOF_FD_PROGRAM_TEXT: + (void)snpf(buf, FDLEN, "txt"); + break; + case LSOF_FD_MEMORY: + (void)snpf(buf, FDLEN, "mem"); + break; + case LSOF_FD_DELETED: + (void)snpf(buf, FDLEN, "del"); + break; + case LSOF_FD_FILEPORT: + (void)snpf(buf, FDLEN, "fp."); + break; + case LSOF_FD_TASK_CWD: + (void)snpf(buf, FDLEN, "twd"); + break; + case LSOF_FD_CTTY: + (void)snpf(buf, FDLEN, "ctty"); + break; + case LSOF_FD_JAIL_DIR: + (void)snpf(buf, FDLEN, "jld"); + break; + default: + fprintf(stderr, "Unknown fd type: %d\n", (int)fd_type); + buf[0] = '\0'; + break; + } +} + +#if defined(HASVNODE) +/* + * readvnode() - read vnode + */ + +int readvnode(struct lsof_context *ctx, + KA_T va, /* vnode kernel space address */ + struct vnode *v) /* vnode buffer pointer */ +{ + if (kread(ctx, (KA_T)va, (char *)v, sizeof(struct vnode))) { + (void)snpf(Namech, Namechl, "can't read vnode at %s", + print_kptr(va, (char *)NULL, 0)); + return (1); + } + return (0); +} +#endif /* defined(HASVNODE) */ \ No newline at end of file diff --git a/lib/proto.h b/lib/proto.h index 31d53b91..2b204db0 100644 --- a/lib/proto.h +++ b/lib/proto.h @@ -50,16 +50,19 @@ # endif /* gcc && gcc>=2.7 */ extern void add_nma(struct lsof_context *ctx, char *cp, int len); -extern void alloc_lfile(struct lsof_context *ctx, char *nm, int num); +extern void alloc_lfile(struct lsof_context *ctx, enum lsof_fd_type fd_type, + int num); +extern void clean_lfile(struct lsof_context *ctx, struct lfile *lf); extern void alloc_lproc(struct lsof_context *ctx, int pid, int pgid, int ppid, UID_ARG uid, char *cmd, int pss, int sf); extern void build_IPstates(struct lsof_context *ctx); extern void childx(struct lsof_context *ctx); -extern void closefrom_shim(int low); -extern int ck_fd_status(struct lsof_context *ctx, char *nm, int num); -extern int ck_file_arg(struct lsof_context *ctx, int i, int ac, char *av[], - int fv, int rs, struct stat *sbp, - int accept_deleted_file); +extern void closefrom_shim(struct lsof_context *ctx, int low); +extern int ck_fd_status(struct lsof_context *ctx, enum lsof_fd_type fd_type, + int num); +extern enum lsof_error ck_file_arg(struct lsof_context *ctx, char *arg, int fv, + int rs, struct stat *sbp, + int accept_deleted_file); extern void ckkv(struct lsof_context *ctx, char *d, char *er, char *ev, char *ea); extern void clr_devtab(struct lsof_context *ctx); @@ -71,32 +74,29 @@ extern void dropgid(struct lsof_context *ctx); # endif /* defined(WILLDROPGID) */ extern char *endnm(struct lsof_context *ctx, size_t *sz); -extern int enter_cmd_rx(struct lsof_context *ctx, char *x); extern void enter_dev_ch(struct lsof_context *ctx, char *m); -extern int enter_dir(struct lsof_context *ctx, char *d, int descend); # if defined(HASEOPT) -extern int enter_efsys(struct lsof_context *ctx, char *e, int rdlnk); +extern int enter_efsys(char *e, int rdlnk); # endif /* defined(HASEOPT) */ -extern int enter_fd(struct lsof_context *ctx, char *f); -extern int enter_network_address(struct lsof_context *ctx, char *na); -extern int enter_id(struct lsof_context *ctx, enum IDType ty, char *p); +extern int enter_fd(char *f); +extern int enter_network_address(char *na); +extern int enter_id(enum IDType ty, char *p); extern void enter_IPstate(struct lsof_context *ctx, char *ty, char *nm, int nr); extern void enter_nm(struct lsof_context *ctx, char *m); # if defined(HASTCPUDPSTATE) -extern int enter_state_spec(struct lsof_context *ctx, char *ss); +extern int enter_state_spec(char *ss); # endif /* defined(HASTCPUDPSTATE) */ -extern int enter_str_lst(char *opt, char *s, struct str_lst **lp, int *incl, - int *excl); -extern int enter_uid(struct lsof_context *ctx, char *us); +extern int enter_cmd(char *opt, char *s); +extern int enter_uid(char *us); extern void ent_inaddr(struct lsof_context *ctx, unsigned char *la, int lp, unsigned char *fa, int fp, int af); extern int examine_lproc(struct lsof_context *ctx); extern void Exit(struct lsof_context *ctx, enum ExitStatus xv) exiting; -extern void Error(struct lsof_context *ctx) exiting; +extern void Error(struct lsof_context *ctx); extern void find_ch_ino(struct lsof_context *ctx); # if defined(HASEPTOPTS) @@ -110,7 +110,7 @@ extern pxinfo_t *find_psxmqinfo(struct lsof_context *ctx, int pid, extern void process_psxmqinfo(struct lsof_context *ctx, int f); # if defined(HASUXSOCKEPT) extern void clear_uxsinfo(struct lsof_context *ctx); -extern struct uxsin *find_uxsepti(struct lfile *lf); +extern struct uxsin *find_uxsepti(struct lsof_context *ctx, struct lfile *lf); extern void process_uxsinfo(struct lsof_context *ctx, int f); # endif /* defined(HASUXSOCKEPT) */ # if defined(HASPTYEPT) @@ -137,7 +137,7 @@ extern void process_nets6info(struct lsof_context *ctx, int f); extern void free_lproc(struct lproc *lp); extern void gather_proc_info(struct lsof_context *ctx); -extern char *gethostnm(struct lsof_context *ctx, unsigned char *ia, int af); +extern char *gethostnm(unsigned char *ia, int af); # if !defined(GET_MAX_FD) /* @@ -154,10 +154,13 @@ extern char *gethostnm(struct lsof_context *ctx, unsigned char *ia, int af); extern int hashbyname(char *nm, int mod); extern void hashSfile(struct lsof_context *ctx); extern void initialize(struct lsof_context *ctx); +extern void deinitialize(struct lsof_context *ctx); extern int is_cmd_excl(struct lsof_context *ctx, char *cmd, short *pss, short *sf); -extern int is_file_sel(struct lproc *lp, struct lfile *lf); -extern int is_nw_addr(unsigned char *ia, int p, int af); +extern int is_file_sel(struct lsof_context *ctx, struct lproc *lp, + struct lfile *lf); +extern int is_nw_addr(struct lsof_context *ctx, unsigned char *ia, int p, + int af); # if defined(HASTASKS) extern int is_proc_excl(struct lsof_context *ctx, int pid, int pgid, @@ -167,7 +170,7 @@ extern int is_proc_excl(struct lsof_context *ctx, int pid, int pgid, UID_ARG uid, short *pss, short *sf); # endif /* defined(HASTASKS) */ -extern int is_readable(char *path, int msg); +extern int is_readable(struct lsof_context *ctx, char *path, int msg); extern int kread(struct lsof_context *ctx, KA_T addr, char *buf, READLEN_T len); extern void link_lfile(struct lsof_context *ctx); extern struct l_dev *lkupdev(struct lsof_context *ctx, dev_t *dev, dev_t *rdev, @@ -179,22 +182,29 @@ extern char *mkstrcat(char *s1, int l1, char *s2, int l2, char *s3, int l3, MALLOC_S *clp); extern int printdevname(struct lsof_context *ctx, dev_t *dev, dev_t *rdev, int f, int nty); -extern void print_file(struct lsof_context *ctx); +extern void print_file(void); extern void print_init(void); -extern void printname(struct lsof_context *ctx, int nl); +extern void printname(int nl); extern char *print_kptr(KA_T kp, char *buf, size_t bufl); -extern int print_proc(struct lsof_context *ctx); -extern void printrawaddr(struct lsof_context *ctx, struct sockaddr *sa); -extern void print_tcptpi(struct lsof_context *ctx, int nl); -extern char *printuid(struct lsof_context *ctx, UID_ARG uid, int *ty); +extern int print_proc(void); +extern void print_fd(enum lsof_fd_type fd_type, int fd_num, char *buf); +extern char *printuid(UID_ARG uid, int *ty); extern void printunkaf(struct lsof_context *ctx, int fam, int ty); -extern char access_to_char(enum lsof_file_access_mode access); +extern char print_access(enum lsof_file_access_mode access); +extern char print_lock(enum lsof_lock_mode lock); +extern void print_file_type(enum lsof_file_type type, + uint32_t unknown_file_type_number, char *buf, + size_t buf_len); +extern void print_iproto(enum lsof_protocol proto, + uint32_t unknown_proto_number, char *buf, + size_t buf_len); extern char *printsockty(int ty); extern void process_file(struct lsof_context *ctx, KA_T fp); extern void process_node(struct lsof_context *ctx, KA_T f); extern char *Readlink(struct lsof_context *ctx, char *arg); extern void readdev(struct lsof_context *ctx, int skip); extern struct mounts *readmnt(struct lsof_context *ctx); +extern void clean_mnt(struct lsof_context *ctx); extern void rereaddev(struct lsof_context *ctx); extern char *safepup(unsigned int c, int *cl); extern int safestrlen(char *sp, int flags); @@ -202,7 +212,7 @@ extern void safestrprtn(char *sp, int len, FILE *fs, int flags); extern void safestrprt(char *sp, FILE *fs, int flags); extern int statsafely(struct lsof_context *ctx, char *path, struct stat *buf); extern void stkdir(struct lsof_context *ctx, char *p); -extern void usage(struct lsof_context *ctx, int err, int fh, int version); +extern void usage(int err, int fh, int version); extern int util_strftime(char *fmtr, int fmtl, char *fmt); extern int vfy_dev(struct lsof_context *ctx, struct l_dev *dp); extern char *x2dev(char *s, dev_t *d); @@ -215,18 +225,18 @@ extern int printbdevname(dev_t *dev, dev_t *rdev, int f); # endif /* defined(HASBLKDEV) */ # if defined(HASCDRNODE) -extern int readcdrnode(struct lsof_context *ctx, KA_T ca, struct cdrnode *c); +extern int readcdrnode(KA_T ca, struct cdrnode *c); # endif /* defined(HASCDRNODE) */ # if defined(HASDCACHE) extern void alloc_dcache(struct lsof_context *ctx); extern void crc(char *b, int l, unsigned *s); extern void crdbld(void); -extern int ctrl_dcache(struct lsof_context *ctx, char *p); +extern int ctrl_dcache(char *p); extern int dcpath(struct lsof_context *ctx, int rw, int npw); extern int open_dcache(struct lsof_context *ctx, int m, int r, struct stat *sb); extern int read_dcache(struct lsof_context *ctx); -extern int wr2DCfd(char *b, unsigned *c); +extern int wr2DCfd(struct lsof_context *ctx, char *b, unsigned *c); extern void write_dcache(struct lsof_context *ctx); # endif /* defined(HASDCACHE) */ @@ -239,7 +249,7 @@ extern char *print_fflags(struct lsof_context *ctx, long ffg, long pof); # endif /* defined(HASFSTRUCT) */ # if defined(HASGNODE) -extern int readgnode(struct lsof_context *ctx, KA_T ga, struct gnode *g); +extern int readgnode(KA_T ga, struct gnode *g); # endif /* defined(HASGNODE) */ # if defined(HASKQUEUE) @@ -262,11 +272,12 @@ extern char *ncache_lookup(struct lsof_context *ctx, char *buf, int blen, # if defined(HASNLIST) extern void build_Nl(struct lsof_context *ctx, struct drive_Nl *d); -extern int get_Nl_value(char *nn, struct drive_Nl *d, KA_T *v); +extern int get_Nl_value(struct lsof_context *ctx, char *nn, struct drive_Nl *d, + KA_T *v); # endif /* defined(HASNLIST) */ # if defined(HASPIPENODE) -extern int readpipenode(struct lsof_context *ctx, KA_T pa, struct pipenode *p); +extern int readpipenode(KA_T pa, struct pipenode *p); # endif /* defined(HASPIPENODE) */ # if defined(HASPRINTDEV) @@ -278,16 +289,14 @@ extern char *HASPRINTINO(struct lfile *lf); # endif /* defined(HASPRINTINO) */ # if defined(HASPRINTNM) -extern void HASPRINTNM(struct lsof_context *ctx, struct lfile *lf); +extern void HASPRINTNM(struct lfile *lf); # endif /* defined(HASPRINTNM) */ # if defined(HASPRIVNMCACHE) extern int HASPRIVNMCACHE(struct lsof_context *ctx, struct lfile *lf); # endif /* defined(HASPRIVNMCACHE) */ -# if !defined(HASPRIVPRIPP) -extern void printiproto(int p); -# endif /* !defined(HASPRIVPRIPP) */ +extern void enter_ip_proto(struct lsof_context *ctx, int p); # if defined(HASRNODE) extern int readrnode(struct lsof_context *ctx, KA_T ra, struct rnode *r); diff --git a/lib/ptti.c b/lib/ptti.c index e69de29b..e27fad32 100644 --- a/lib/ptti.c +++ b/lib/ptti.c @@ -0,0 +1,51 @@ +/* + * ptti.c -- BSD style print_tcptpi() function for lsof library + */ + +/* + * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by Victor A. Abell + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#define TCPSTATES /* activate tcpstates[] */ +#include "common.h" +#include "machine.h" + +#if defined(USE_LIB_PRINT_TCPTPI) + +/* + * build_IPstates() -- build the TCP and UDP state tables + * + * Note: this module does not support a UDP state table. + */ + +void build_IPstates(struct lsof_context *ctx) { + + /* + * Set the TcpNstates global variable. + */ + TcpNstates = TCP_NSTATES; + TcpSt = (char **)&tcpstates; +} +#endif /* defined(USE_LIB_PRINT_TCPTPI) */ \ No newline at end of file diff --git a/lib/rdev.c b/lib/rdev.c index 96a52970..907e6a95 100644 --- a/lib/rdev.c +++ b/lib/rdev.c @@ -69,7 +69,7 @@ static int rmdupdev(struct lsof_context *ctx, struct l_dev ***dp, int n, * #define RDEV_STATFN private_stat * * 6. Define HAS_STD_CLONE to request that clone device information be stored - * in standard clone structures (defined in lsof.h and addressed via + * in standard clone structures (defined in common.h and addressed via * Clone). If HAS_STD_CLONE is defined, these must also be defined: * * a. Define CLONEMAJ to be the name of the constant or @@ -485,7 +485,4 @@ int vfy_dev(struct lsof_context *ctx, return (1); } # endif /* defined(HASDCACHE) */ -#else /* !defined(USE_LIB_READDEV) */ -char rdev_d1[] = "d"; -char *rdev_d2 = rdev_d1; #endif /* defined(USE_LIB_READDEV) */ diff --git a/lib/rmnt.c b/lib/rmnt.c index 36335c87..b4f89b45 100644 --- a/lib/rmnt.c +++ b/lib/rmnt.c @@ -65,14 +65,11 @@ * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ -struct mounts *readmnt(struct lsof_context *ctx) { +struct mounts *readmnt() { char *dn = (char *)NULL; char *ln; FILE *mfp; @@ -222,7 +219,4 @@ struct mounts *readmnt(struct lsof_context *ctx) { Lmist = 1; return (Lmi); } -#else /* !defined(USE_LIB_READMNT) */ -char rmnt_d1[] = "d"; -char *rmnt_d2 = rmnt_d1; #endif /* defined(USE_LIB_READMNT) */ diff --git a/lib/rnam.c b/lib/rnam.c index 312ef757..2679bd26 100644 --- a/lib/rnam.c +++ b/lib/rnam.c @@ -82,7 +82,7 @@ * * Define this prototype for ncache_load(): * - * _PROTOTYPE(static void ncache_load,(void)); + * static void ncache_load(void); */ /* @@ -144,12 +144,13 @@ static int ncache_isroot(KA_T na, char *cp); static struct l_nch * # if defined(NCACHE_NODEID) -ncache_addr(unsigned long i, /* node's capability ID */ -# else /* !defined(NCACHE_NODEID) */ -ncache_addr( -# endif /* defined(NCACHE_NODEID) */ +ncache_addr(i, na) +unsigned long i; /* node's capability ID */ +# else /* !defined(NCACHE_NODEID) */ +ncache_addr(na) +# endif /* defined(NCACHE_NODEID) */ - KA_T na) /* node's address */ +KA_T na; /* node's address */ { struct l_nch **hp; @@ -177,9 +178,9 @@ ncache_addr( * ncache_isroot() - is head of name cache path a file system root? */ -static int ncache_isroot(struct lsof_context *ctx, /* context */ - KA_T na, /* kernel node address */ - char *cp) /* partial path */ +static int ncache_isroot(na, cp) +KA_T na; /* kernel node address */ +char *cp; /* partial path */ { char buf[MAXPATHLEN]; int i; @@ -216,7 +217,7 @@ static int ncache_isroot(struct lsof_context *ctx, /* context */ /* * The vnode tests failed. Try the inode tests. */ - if (Lf->inp_ty != 1 || !Lf->inode || !Lf->fsdir || + if (!Lf->inode_def || !Lf->inode || !Lf->fsdir || (len = strlen(Lf->fsdir)) < 1) return (0); if ((len + 1 + strlen(cp) + 1) > sizeof(buf)) @@ -462,17 +463,8 @@ void ncache_load() { * Reduce memory usage, as required. */ -# if !defined(NCACHE_NXT) - if (!RptTm) - (void)free((FREE_P *)kca); -# endif /* !defined(NCACHE_NXT) */ - if (n < 1) { Nc = 0; - if (!RptTm) { - (void)free((FREE_P *)Ncache); - Ncache = (struct l_nch *)NULL; - } if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: unusable name cache size: %d\n", Pn, n); @@ -480,11 +472,6 @@ void ncache_load() { } if (n < Nc) { Nc = n; - if (!RptTm) { - len = Nc * sizeof(struct l_nch); - if (!(Ncache = (struct l_nch *)realloc(Ncache, len))) - goto no_local_space; - } } /* * Build a hash table to locate Ncache entries. @@ -548,9 +535,10 @@ void ncache_load() { * ncache_lookup() - look up a node's name in the kernel's name cache */ -char *ncache_lookup(char *buf, /* receiving name buffer */ - int blen, /* receiving buffer length */ - int *fp) /* full path reply */ +char *ncache_lookup(buf, blen, fp) +char *buf; /* receiving name buffer */ +int blen; /* receiving buffer length */ +int *fp; /* full path reply */ { char *cp = buf; struct l_nch *lc; @@ -566,7 +554,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * file system mount point, return an empty path reply. That tells the * caller to print the file system mount point name only. */ - if ((Lf->inp_ty == 1) && Lf->fs_ino && (Lf->inode == Lf->fs_ino)) + if (Lf->inode_def && Lf->fs_ino && (Lf->inode == Lf->fs_ino)) return (cp); # endif /* defined(HASFSINO) */ @@ -586,7 +574,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * If the node has no cache entry, see if it's the mount * point of a known file system. */ - if (!Lf->fsdir || !Lf->dev_def || Lf->inp_ty != 1) + if (!Lf->fsdir || !Lf->dev_def || !Lf->inode_def) return ((char *)NULL); for (mtp = readmnt(); mtp; mtp = mtp->next) { if (!mtp->dir || !mtp->inode) @@ -637,7 +625,4 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ # endif /* defined(NCACHE_PARADDR) && defined(NCACHE_PARID) */ return (cp); } -#else /* !defined(HASNCACHE) || !defined(USE_LIB_RNAM) */ -char rnam_d1[] = "d"; -char *rnam_d2 = rnam_d1; #endif /* defined(HASNCACHE) && defined(USE_LIB_RNAM) */ diff --git a/lib/rnch.c b/lib/rnch.c index ef13d1bf..5ac6ca31 100644 --- a/lib/rnch.c +++ b/lib/rnch.c @@ -105,7 +105,7 @@ * * Define this prototype for ncache_load(): * - * _PROTOTYPE(void ncache_load,(void)); + * void ncache_load(void); */ /* @@ -180,11 +180,19 @@ static int ncache_isroot(KA_T va, char *cp); * ncache_addr() - look up a node's local ncache address */ -static struct l_nch *ncache_addr( +static struct l_nch * + +# if defined(NCACHE_NODEID) +ncache_addr(i, v) +# else /* !defined(NCACHE_NODEID) */ +ncache_addr(v) +# endif /* defined(NCACHE_NODEID) */ + # if defined(NCACHE_NODEID) - unsigned long i, /* capability ID */ -# endif /* defined(NCACHE_NODEID) */ - KA_T v) /* vnode's address */ +unsigned long i; /* capability ID */ +# endif /* defined(NCACHE_NODEID) */ + +KA_T v; /* vnode's address */ { struct l_nch **hp; @@ -211,8 +219,9 @@ static struct l_nch *ncache_addr( * ncache_isroot() - is head of name cache path a file system root? */ -static int ncache_isroot(KA_T va, /* kernel vnode address */ - char *cp) /* partial path */ +static int ncache_isroot(va, cp) +KA_T va; /* kernel vnode address */ +char *cp; /* partial path */ { char buf[MAXPATHLEN]; int i; @@ -249,7 +258,7 @@ static int ncache_isroot(KA_T va, /* kernel vnode address */ /* * The vnode tests failed. Try the inode tests. */ - if (Lf->inp_ty != 1 || !Lf->inode || !Lf->fsdir || + if (!Lf->inode_def || !Lf->inode || !Lf->fsdir || (len = strlen(Lf->fsdir)) < 1) return (0); if ((len + 1 + strlen(cp) + 1) > sizeof(buf)) @@ -292,7 +301,7 @@ static int ncache_isroot(KA_T va, /* kernel vnode address */ * ncache_load() - load the kernel's name cache */ -void ncache_load(struct lsof_context *ctx) { +void ncache_load() { char *cp, *np; struct l_nch **hp, *lc; int i, len, n; @@ -584,32 +593,8 @@ void ncache_load(struct lsof_context *ctx) { } # endif /* defined(NCACHE_NXT) */ } - /* - * Reduce memory usage, as required. - */ - -# if !defined(NCACHE_NXT) - if (!RptTm) - (void)free((FREE_P *)kca); -# endif /* !defined(NCACHE_NXT) */ if (n < 1) { - if (!RptTm && Ncache) { - - /* - * If not in repeat mode, free the space that has been malloc'd - * to the local name cache. - */ - for (i = 0, lc = Ncache; i < Nc; i++, lc++) { - if (lc->nm) { - (void)free((FREE_P *)lc->nm); - lc->nm = (char *)NULL; - } - } - (void)free((FREE_P *)Ncache); - Ncache = (struct l_nch *)NULL; - Nc = 0; - } if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: unusable name cache size: %d\n", Pn, n); @@ -617,11 +602,6 @@ void ncache_load(struct lsof_context *ctx) { } if (n < Nc) { Nc = n; - if (!RptTm) { - len = Nc * sizeof(struct l_nch); - if (!(Ncache = (struct l_nch *)realloc(Ncache, len))) - goto no_local_space; - } } /* * Build a hash table to locate Ncache entries. @@ -688,9 +668,10 @@ void ncache_load(struct lsof_context *ctx) { * ncache_lookup() - look up a node's name in the kernel's name cache */ -char *ncache_lookup(char *buf, /* receiving name buffer */ - int blen, /* receiving buffer length */ - int *fp) /* full path reply */ +char *ncache_lookup(buf, blen, fp) +char *buf; /* receiving name buffer */ +int blen; /* receiving buffer length */ +int *fp; /* full path reply */ { char *cp = buf; struct l_nch *lc; @@ -706,7 +687,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * file system mount point, return an empty path reply. That tells the * caller to print the file system mount point name only. */ - if ((Lf->inp_ty == 1) && Lf->fs_ino && (Lf->inode == Lf->fs_ino)) + if (Lf->inode_def && Lf->fs_ino && (Lf->inode == Lf->fs_ino)) return (cp); # endif /* defined(HASFSINO) */ @@ -727,7 +708,7 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ * If the node has no cache entry, see if it's the mount * point of a known file system. */ - if (!Lf->fsdir || !Lf->dev_def || Lf->inp_ty != 1) + if (!Lf->fsdir || !Lf->dev_def || !Lf->inode_def) return ((char *)NULL); for (mtp = readmnt(); mtp; mtp = mtp->next) { if (!mtp->dir || !mtp->inode) @@ -771,7 +752,4 @@ char *ncache_lookup(char *buf, /* receiving name buffer */ } return (cp); } -#else /* !defined(HASNCACHE) || !defined(USE_LIB_RNCH) */ -char rnch_d1[] = "d"; -char *rnch_d2 = rnch_d1; #endif /* defined(HASNCACHE) && defined(USE_LIB_RNCH) */ diff --git a/lib/rnmh.c b/lib/rnmh.c index 8df72d8e..cecbcf8d 100644 --- a/lib/rnmh.c +++ b/lib/rnmh.c @@ -81,7 +81,7 @@ * * Define this prototype for ncache_load(): * - * _PROTOTYPE(static void ncache_load,(void)); + * static void ncache_load(void); * * Define NCACHE_VROOT to be the value of the flag that signifies that * the vnode is the root of its file system. @@ -176,11 +176,13 @@ static int ncache_isroot(struct lsof_context *ctx, KA_T na, char *cp); static struct l_nch * # if defined(NCACHE_NODEID) -ncache_addr(unsigned long i, /* node's capability ID */ -# else /* !defined(NCACHE_NODEID) */ -ncache_addr( -# endif /* defined(NCACHE_NODEID) */ - KA_T na) /* node's address */ +ncache_addr(i, na) +unsigned long i; /* node's capability ID */ +# else /* !defined(NCACHE_NODEID) */ +ncache_addr(na) +# endif /* defined(NCACHE_NODEID) */ + +KA_T na; /* node's address */ { struct l_nch **hp; @@ -247,7 +249,7 @@ static int ncache_isroot(struct lsof_context *ctx, /* * The vnode tests failed. Try the inode tests. */ - if (Lf->inp_ty != 1 || !Lf->inode || !Lf->fsdir || + if (!Lf->inode_def || !Lf->inode || !Lf->fsdir || (len = strlen(Lf->fsdir)) < 1) return (0); if ((len + 1 + strlen(cp) + 1) > sizeof(buf)) @@ -340,7 +342,7 @@ void ncache_load(struct lsof_context *ctx) { * Get kernel cache hash table size */ v = (KA_T)0; - if (get_Nl_value(X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || !v || + if (get_Nl_value(ctx, X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&khsz, sizeof(khsz))) { if (!Fwarn) (void)fprintf(stderr, @@ -361,7 +363,7 @@ void ncache_load(struct lsof_context *ctx) { */ ka = (KA_T)0; v = (KA_T)0; - if (get_Nl_value(X_NCACHE, (struct drive_Nl *)NULL, &v) < 0 || !v || + if (get_Nl_value(ctx, X_NCACHE, (struct drive_Nl *)NULL, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&ka, sizeof(ka)) || !ka) { if (!Fwarn) (void)fprintf( @@ -554,14 +556,6 @@ void ncache_load(struct lsof_context *ctx) { nch++; } } - /* - * Reduce memory usage, as required. - */ - if (!RptTm) { - (void)free((FREE_P *)khp); - khp = (struct NCACHE **)NULL; - khpl = 0; - } if (nch < 1) { if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: unusable name cache size: %d\n", @@ -642,7 +636,7 @@ char *ncache_lookup(struct lsof_context *ctx, * file system mount point, return an empty path reply. That tells the * caller to print the file system mount point name only. */ - if ((Lf->inp_ty == 1) && Lf->fs_ino && (Lf->inode == Lf->fs_ino)) + if (Lf->inode_def && Lf->fs_ino && (Lf->inode == Lf->fs_ino)) return (cp); # endif /* defined(HASFSINO) */ @@ -662,7 +656,7 @@ char *ncache_lookup(struct lsof_context *ctx, * If the node has no cache entry, see if it's the mount * point of a known file system. */ - if (!Lf->fsdir || !Lf->dev_def || Lf->inp_ty != 1) + if (!Lf->fsdir || !Lf->dev_def || !Lf->inode_def) return ((char *)NULL); for (mtp = readmnt(ctx); mtp; mtp = mtp->next) { if (!mtp->dir || !mtp->inode) @@ -710,7 +704,4 @@ char *ncache_lookup(struct lsof_context *ctx, } return (cp); } -#else /* !defined(HASNCACHE) || !defined(USE_LIB_RNMH) */ -char rnmh_d1[] = "d"; -char *rnmh_d2 = rnmh_d1; #endif /* defined(HASNCACHE) && defined(USE_LIB_RNMH) */ diff --git a/lib/rnmt.c b/lib/rnmt.c index 709aad57..52b3be42 100644 --- a/lib/rnmt.c +++ b/lib/rnmt.c @@ -116,8 +116,7 @@ static int sanity_check_namecache(const struct namecache *nc) { return 0; } -static void ncache_walk(struct lsof_context *ctx, KA_T ncp, - const struct lnc *plnc) { +static void ncache_walk(KA_T ncp, const struct lnc *plnc) { struct l_nch *lc; static struct vnode_impl vi; static struct namecache nc; @@ -146,7 +145,7 @@ static void ncache_walk(struct lsof_context *ctx, KA_T ncp, ncache_walk(right, plnc); } -void ncache_load(struct lsof_context *ctx) { +void ncache_load() { KA_T rootvnode_addr; struct vnode_impl vi; diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 00000000..21ff9100 --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,2 @@ +*.m4 +!header.m4 \ No newline at end of file diff --git a/scripts/eth_proto.json b/scripts/eth_proto.json new file mode 100644 index 00000000..e8dde882 --- /dev/null +++ b/scripts/eth_proto.json @@ -0,0 +1,406 @@ +[ + [ + "802_3", + 1 + ], + [ + "AX25", + 2 + ], + [ + "ALL", + 3 + ], + [ + "802_2", + 4 + ], + [ + "SNAP", + 5 + ], + [ + "DDCMP", + 6 + ], + [ + "WAN_PPP", + 7 + ], + [ + "PPP_MP", + 8 + ], + [ + "LOCALTALK", + 9 + ], + [ + "CAN", + 12 + ], + [ + "CANFD", + 13 + ], + [ + "CANXL", + 14 + ], + [ + "PPPTALK", + 16 + ], + [ + "TR_802_2", + 17 + ], + [ + "MOBITEX", + 21 + ], + [ + "CONTROL", + 22 + ], + [ + "IRDA", + 23 + ], + [ + "ECONET", + 24 + ], + [ + "HDLC", + 25 + ], + [ + "ARCNET", + 26 + ], + [ + "DSA", + 27 + ], + [ + "TRAILER", + 28 + ], + [ + "LOOP", + 96 + ], + [ + "PHONET", + 245 + ], + [ + "IEEE802154", + 246 + ], + [ + "CAIF", + 247 + ], + [ + "XDSA", + 248 + ], + [ + "MAP", + 249 + ], + [ + "MCTP", + 250 + ], + [ + "PUP", + 512 + ], + [ + "PUPAT", + 513 + ], + [ + "802_3_MIN", + 1536 + ], + [ + "IP", + 2048 + ], + [ + "X25", + 2053 + ], + [ + "ARP", + 2054 + ], + [ + "BPQ", + 2303 + ], + [ + "IEEEPUP", + 2560 + ], + [ + "IEEEPUPAT", + 2561 + ], + [ + "ERSPAN2", + 8939 + ], + [ + "TSN", + 8944 + ], + [ + "BATMAN", + 17157 + ], + [ + "DEC", + 24576 + ], + [ + "DNA_DL", + 24577 + ], + [ + "DNA_RC", + 24578 + ], + [ + "DNA_RT", + 24579 + ], + [ + "LAT", + 24580 + ], + [ + "DIAG", + 24581 + ], + [ + "CUST", + 24582 + ], + [ + "SCA", + 24583 + ], + [ + "TEB", + 25944 + ], + [ + "RARP", + 32821 + ], + [ + "ATALK", + 32923 + ], + [ + "AARP", + 33011 + ], + [ + "8021Q", + 33024 + ], + [ + "IPX", + 33079 + ], + [ + "IPV6", + 34525 + ], + [ + "PAUSE", + 34824 + ], + [ + "SLOW", + 34825 + ], + [ + "WCCP", + 34878 + ], + [ + "MPLS_UC", + 34887 + ], + [ + "MPLS_MC", + 34888 + ], + [ + "ATMMPOA", + 34892 + ], + [ + "PPP_DISC", + 34915 + ], + [ + "PPP_SES", + 34916 + ], + [ + "LINK_CTL", + 34924 + ], + [ + "ATMFATE", + 34948 + ], + [ + "PAE", + 34958 + ], + [ + "PROFINET", + 34962 + ], + [ + "REALTEK", + 34969 + ], + [ + "AOE", + 34978 + ], + [ + "ETHERCAT", + 34980 + ], + [ + "8021AD", + 34984 + ], + [ + "802_EX1", + 34997 + ], + [ + "ERSPAN", + 35006 + ], + [ + "PREAUTH", + 35015 + ], + [ + "TIPC", + 35018 + ], + [ + "LLDP", + 35020 + ], + [ + "MRP", + 35043 + ], + [ + "MACSEC", + 35045 + ], + [ + "8021AH", + 35047 + ], + [ + "MVRP", + 35061 + ], + [ + "1588", + 35063 + ], + [ + "NCSI", + 35064 + ], + [ + "PRP", + 35067 + ], + [ + "CFM", + 35074 + ], + [ + "FCOE", + 35078 + ], + [ + "TDLS", + 35085 + ], + [ + "FIP", + 35092 + ], + [ + "IBOE", + 35093 + ], + [ + "80221", + 35095 + ], + [ + "HSR", + 35119 + ], + [ + "NSH", + 35151 + ], + [ + "LOOPBACK", + 36864 + ], + [ + "QINQ1", + 37120 + ], + [ + "QINQ2", + 37376 + ], + [ + "QINQ3", + 37632 + ], + [ + "EDSA", + 56026 + ], + [ + "DSA_8021Q", + 56027 + ], + [ + "DSA_A5PSW", + 57345 + ], + [ + "IFE", + 60734 + ], + [ + "AF_IUCV", + 64507 + ] +] \ No newline at end of file diff --git a/scripts/extract_eth_proto.py b/scripts/extract_eth_proto.py new file mode 100644 index 00000000..08c4d5f5 --- /dev/null +++ b/scripts/extract_eth_proto.py @@ -0,0 +1,16 @@ +import re +import json +protos = [] +# Extract ethernet protos from linux header +with open('/usr/include/linux/if_ether.h', 'r') as f: + for line in f: + if re.match('#define\sETH_P_', line): + parts = re.split('\s', line) + parts = list(filter(lambda v: len(v) > 0, parts)) + name = parts[1][6:] + value = int(parts[2], 16) + protos.append((name, value)) + +protos = sorted(protos, key=lambda p: p[1]) +print(protos) +json.dump(protos, open('eth_proto.json', 'w')) diff --git a/scripts/extract_ip_proto.py b/scripts/extract_ip_proto.py new file mode 100644 index 00000000..4abf2352 --- /dev/null +++ b/scripts/extract_ip_proto.py @@ -0,0 +1,30 @@ +import re +import json +import os +protos = dict() +if os.path.exists('ip_proto.json'): + protos = json.load(open('ip_proto.json', 'r')) + +# Extract ip protos from header +path = '/usr/include/netinet/in.h' + +# Darwin +if not os.path.exists(path): + path = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk' + path +with open(path, 'r') as f: + for line in f: + m = re.search('IPPROTO_([A-Z0-9_]+) = ([0-9]+)', line) + if m: + name = m[1] + value = int(m[2]) + protos[name] = value + else: + m = re.search('#define\s+IPPROTO_([A-Z0-9_]+)\s+([0-9]+)', line) + if m: + name = m[1] + value = int(m[2]) + protos[name] = value + +# BSD Private, FreeBSD has 258 while Darwin has 254 +del protos["DIVERT"] +json.dump(protos, open('ip_proto.json', 'w')) diff --git a/scripts/gen_proto.py b/scripts/gen_proto.py new file mode 100644 index 00000000..eca73147 --- /dev/null +++ b/scripts/gen_proto.py @@ -0,0 +1,61 @@ +# Generate lsof_protocol enum from IP and Ethernet protocols + +import json +names = [] +with open('lsof_proto.h', 'w') as f: + print('enum lsof_protocol {', file=f) + ip_protos = json.load(open('ip_proto.json', 'r')) + protos = ip_protos.items() + print(' /* Follow ip protocol numbers order */', file=f) + for proto in sorted(protos, key=lambda p: p[1]): + print( + f' LSOF_PROTOCOL_{proto[0]}, /**< {proto[0]}({proto[1]}) */', file=f) + names.append(proto[0]) + + print(' /* Follow ethernet type order */', file=f) + eth_protos = json.load(open('eth_proto.json', 'r')) + for proto in eth_protos: + if not proto[0] in names: + print( + f' LSOF_PROTOCOL_{proto[0]}, /**< {proto[0]}(0x{proto[1]:04X}) */', file=f) + names.append(proto[0]) + print('};', file=f) + +rename = { + "FRAGMENT": "FRAGMNT", + "LOCALTALK": "LCLTALK", + "ETHERNET": "ETHER", + "TR_802_2": "802.2", + "IEEE802154": "802154", + "802_3_MIN": "802.3", + "IEEEPUPAT": "I3EPUPAT", + "PPP_DISC": "PPPDISC", + "LINK_CTL": "LINKCTL", + "PROFINET": "PROFINT", + "ETHERCAT": "ETHCAT", + "LOOPBACK": "LOOPBAK", + "DSA_8021Q": "DSAD1Q", + "DSA_A5PSW": "DSA5PSW", + "SATEXPAK": "STEXPAK", + "KRYPTOLAN": "KRYPTLN", + "BRSATMON": "BRSTMON", + "RESERVED_253": "RSVD253", + "RESERVED_254": "RSVD254", + "OLD_DIVERT": "ODIVERT", +} + +with open('lsof_proto.c', 'w') as f: + print('void print_iproto() {', file=f) + print(' switch (proto) {', file=f) + for name in names: + visible = name + if len(name) > 7: + if name in rename: + visible = rename[name] + else: + print(f'{name} too long!') + print(f' case LSOF_PROTOCOL_{name}:', file=f) + print(f' (void)snpf(buf, buf_len, "{visible}");', file=f) + print(' break;', file=f) + print(' }', file=f) + print('}', file=f) diff --git a/scripts/ip_proto.json b/scripts/ip_proto.json new file mode 100644 index 00000000..b823ec50 --- /dev/null +++ b/scripts/ip_proto.json @@ -0,0 +1,128 @@ +{ + "IP": 0, + "ICMP": 1, + "IGMP": 2, + "IPIP": 4, + "TCP": 6, + "EGP": 8, + "PUP": 12, + "UDP": 17, + "IDP": 22, + "TP": 29, + "DCCP": 33, + "RSVP": 46, + "GRE": 47, + "ESP": 50, + "AH": 51, + "MTP": 92, + "BEETPH": 94, + "ENCAP": 98, + "PIM": 103, + "COMP": 108, + "SCTP": 132, + "UDPLITE": 136, + "MPLS": 137, + "ETHERNET": 143, + "RAW": 255, + "MPTCP": 262, + "HOPOPTS": 0, + "ROUTING": 43, + "FRAGMENT": 44, + "NONE": 59, + "DSTOPTS": 60, + "MH": 135, + "IPV6": 41, + "ICMPV6": 58, + "GGP": 3, + "IPV4": 4, + "ST": 7, + "PIGP": 9, + "RCCMON": 10, + "NVPII": 11, + "ARGUS": 13, + "EMCON": 14, + "XNET": 15, + "CHAOS": 16, + "MUX": 18, + "MEAS": 19, + "HMP": 20, + "PRM": 21, + "TRUNK1": 23, + "TRUNK2": 24, + "LEAF1": 25, + "LEAF2": 26, + "RDP": 27, + "IRTP": 28, + "BLT": 30, + "NSP": 31, + "INP": 32, + "3PC": 34, + "IDPR": 35, + "XTP": 36, + "DDP": 37, + "CMTP": 38, + "TPXX": 39, + "IL": 40, + "SDRP": 42, + "IDRP": 45, + "MHRP": 48, + "BHA": 49, + "INLSP": 52, + "SWIPE": 53, + "NHRP": 54, + "MOBILE": 55, + "TLSP": 56, + "SKIP": 57, + "AHIP": 61, + "CFTP": 62, + "HELLO": 63, + "SATEXPAK": 64, + "KRYPTOLAN": 65, + "RVD": 66, + "IPPC": 67, + "ADFS": 68, + "SATMON": 69, + "VISA": 70, + "IPCV": 71, + "CPNX": 72, + "CPHB": 73, + "WSN": 74, + "PVP": 75, + "BRSATMON": 76, + "ND": 77, + "WBMON": 78, + "WBEXPAK": 79, + "EON": 80, + "VMTP": 81, + "SVMTP": 82, + "VINES": 83, + "TTP": 84, + "IGP": 85, + "DGP": 86, + "TCF": 87, + "IGRP": 88, + "OSPFIGP": 89, + "SRPC": 90, + "LARP": 91, + "AX25": 93, + "IPEIP": 94, + "MICP": 95, + "SCCSP": 96, + "ETHERIP": 97, + "APES": 99, + "GMTP": 100, + "IPCOMP": 108, + "HIP": 139, + "SHIM6": 140, + "CARP": 112, + "PGM": 113, + "PFSYNC": 240, + "RESERVED_253": 253, + "RESERVED_254": 254, + "OLD_DIVERT": 254, + "MAX": 256, + "DONE": 257, + "SEND": 259, + "SPACER": 32767, + "SEP": 33 +} \ No newline at end of file diff --git a/scripts/lsof_proto.c b/scripts/lsof_proto.c new file mode 100644 index 00000000..0550d1aa --- /dev/null +++ b/scripts/lsof_proto.c @@ -0,0 +1,673 @@ +void print_iproto() { + switch (proto) { + case LSOF_PROTOCOL_IP: + (void)snpf(buf, buf_len, "IP"); + break; + case LSOF_PROTOCOL_HOPOPTS: + (void)snpf(buf, buf_len, "HOPOPTS"); + break; + case LSOF_PROTOCOL_ICMP: + (void)snpf(buf, buf_len, "ICMP"); + break; + case LSOF_PROTOCOL_IGMP: + (void)snpf(buf, buf_len, "IGMP"); + break; + case LSOF_PROTOCOL_GGP: + (void)snpf(buf, buf_len, "GGP"); + break; + case LSOF_PROTOCOL_IPIP: + (void)snpf(buf, buf_len, "IPIP"); + break; + case LSOF_PROTOCOL_IPV4: + (void)snpf(buf, buf_len, "IPV4"); + break; + case LSOF_PROTOCOL_TCP: + (void)snpf(buf, buf_len, "TCP"); + break; + case LSOF_PROTOCOL_ST: + (void)snpf(buf, buf_len, "ST"); + break; + case LSOF_PROTOCOL_EGP: + (void)snpf(buf, buf_len, "EGP"); + break; + case LSOF_PROTOCOL_PIGP: + (void)snpf(buf, buf_len, "PIGP"); + break; + case LSOF_PROTOCOL_RCCMON: + (void)snpf(buf, buf_len, "RCCMON"); + break; + case LSOF_PROTOCOL_NVPII: + (void)snpf(buf, buf_len, "NVPII"); + break; + case LSOF_PROTOCOL_PUP: + (void)snpf(buf, buf_len, "PUP"); + break; + case LSOF_PROTOCOL_ARGUS: + (void)snpf(buf, buf_len, "ARGUS"); + break; + case LSOF_PROTOCOL_EMCON: + (void)snpf(buf, buf_len, "EMCON"); + break; + case LSOF_PROTOCOL_XNET: + (void)snpf(buf, buf_len, "XNET"); + break; + case LSOF_PROTOCOL_CHAOS: + (void)snpf(buf, buf_len, "CHAOS"); + break; + case LSOF_PROTOCOL_UDP: + (void)snpf(buf, buf_len, "UDP"); + break; + case LSOF_PROTOCOL_MUX: + (void)snpf(buf, buf_len, "MUX"); + break; + case LSOF_PROTOCOL_MEAS: + (void)snpf(buf, buf_len, "MEAS"); + break; + case LSOF_PROTOCOL_HMP: + (void)snpf(buf, buf_len, "HMP"); + break; + case LSOF_PROTOCOL_PRM: + (void)snpf(buf, buf_len, "PRM"); + break; + case LSOF_PROTOCOL_IDP: + (void)snpf(buf, buf_len, "IDP"); + break; + case LSOF_PROTOCOL_TRUNK1: + (void)snpf(buf, buf_len, "TRUNK1"); + break; + case LSOF_PROTOCOL_TRUNK2: + (void)snpf(buf, buf_len, "TRUNK2"); + break; + case LSOF_PROTOCOL_LEAF1: + (void)snpf(buf, buf_len, "LEAF1"); + break; + case LSOF_PROTOCOL_LEAF2: + (void)snpf(buf, buf_len, "LEAF2"); + break; + case LSOF_PROTOCOL_RDP: + (void)snpf(buf, buf_len, "RDP"); + break; + case LSOF_PROTOCOL_IRTP: + (void)snpf(buf, buf_len, "IRTP"); + break; + case LSOF_PROTOCOL_TP: + (void)snpf(buf, buf_len, "TP"); + break; + case LSOF_PROTOCOL_BLT: + (void)snpf(buf, buf_len, "BLT"); + break; + case LSOF_PROTOCOL_NSP: + (void)snpf(buf, buf_len, "NSP"); + break; + case LSOF_PROTOCOL_INP: + (void)snpf(buf, buf_len, "INP"); + break; + case LSOF_PROTOCOL_DCCP: + (void)snpf(buf, buf_len, "DCCP"); + break; + case LSOF_PROTOCOL_SEP: + (void)snpf(buf, buf_len, "SEP"); + break; + case LSOF_PROTOCOL_3PC: + (void)snpf(buf, buf_len, "3PC"); + break; + case LSOF_PROTOCOL_IDPR: + (void)snpf(buf, buf_len, "IDPR"); + break; + case LSOF_PROTOCOL_XTP: + (void)snpf(buf, buf_len, "XTP"); + break; + case LSOF_PROTOCOL_DDP: + (void)snpf(buf, buf_len, "DDP"); + break; + case LSOF_PROTOCOL_CMTP: + (void)snpf(buf, buf_len, "CMTP"); + break; + case LSOF_PROTOCOL_TPXX: + (void)snpf(buf, buf_len, "TPXX"); + break; + case LSOF_PROTOCOL_IL: + (void)snpf(buf, buf_len, "IL"); + break; + case LSOF_PROTOCOL_IPV6: + (void)snpf(buf, buf_len, "IPV6"); + break; + case LSOF_PROTOCOL_SDRP: + (void)snpf(buf, buf_len, "SDRP"); + break; + case LSOF_PROTOCOL_ROUTING: + (void)snpf(buf, buf_len, "ROUTING"); + break; + case LSOF_PROTOCOL_FRAGMENT: + (void)snpf(buf, buf_len, "FRAGMNT"); + break; + case LSOF_PROTOCOL_IDRP: + (void)snpf(buf, buf_len, "IDRP"); + break; + case LSOF_PROTOCOL_RSVP: + (void)snpf(buf, buf_len, "RSVP"); + break; + case LSOF_PROTOCOL_GRE: + (void)snpf(buf, buf_len, "GRE"); + break; + case LSOF_PROTOCOL_MHRP: + (void)snpf(buf, buf_len, "MHRP"); + break; + case LSOF_PROTOCOL_BHA: + (void)snpf(buf, buf_len, "BHA"); + break; + case LSOF_PROTOCOL_ESP: + (void)snpf(buf, buf_len, "ESP"); + break; + case LSOF_PROTOCOL_AH: + (void)snpf(buf, buf_len, "AH"); + break; + case LSOF_PROTOCOL_INLSP: + (void)snpf(buf, buf_len, "INLSP"); + break; + case LSOF_PROTOCOL_SWIPE: + (void)snpf(buf, buf_len, "SWIPE"); + break; + case LSOF_PROTOCOL_NHRP: + (void)snpf(buf, buf_len, "NHRP"); + break; + case LSOF_PROTOCOL_MOBILE: + (void)snpf(buf, buf_len, "MOBILE"); + break; + case LSOF_PROTOCOL_TLSP: + (void)snpf(buf, buf_len, "TLSP"); + break; + case LSOF_PROTOCOL_SKIP: + (void)snpf(buf, buf_len, "SKIP"); + break; + case LSOF_PROTOCOL_ICMPV6: + (void)snpf(buf, buf_len, "ICMPV6"); + break; + case LSOF_PROTOCOL_NONE: + (void)snpf(buf, buf_len, "NONE"); + break; + case LSOF_PROTOCOL_DSTOPTS: + (void)snpf(buf, buf_len, "DSTOPTS"); + break; + case LSOF_PROTOCOL_AHIP: + (void)snpf(buf, buf_len, "AHIP"); + break; + case LSOF_PROTOCOL_CFTP: + (void)snpf(buf, buf_len, "CFTP"); + break; + case LSOF_PROTOCOL_HELLO: + (void)snpf(buf, buf_len, "HELLO"); + break; + case LSOF_PROTOCOL_SATEXPAK: + (void)snpf(buf, buf_len, "STEXPAK"); + break; + case LSOF_PROTOCOL_KRYPTOLAN: + (void)snpf(buf, buf_len, "KRYPTLN"); + break; + case LSOF_PROTOCOL_RVD: + (void)snpf(buf, buf_len, "RVD"); + break; + case LSOF_PROTOCOL_IPPC: + (void)snpf(buf, buf_len, "IPPC"); + break; + case LSOF_PROTOCOL_ADFS: + (void)snpf(buf, buf_len, "ADFS"); + break; + case LSOF_PROTOCOL_SATMON: + (void)snpf(buf, buf_len, "SATMON"); + break; + case LSOF_PROTOCOL_VISA: + (void)snpf(buf, buf_len, "VISA"); + break; + case LSOF_PROTOCOL_IPCV: + (void)snpf(buf, buf_len, "IPCV"); + break; + case LSOF_PROTOCOL_CPNX: + (void)snpf(buf, buf_len, "CPNX"); + break; + case LSOF_PROTOCOL_CPHB: + (void)snpf(buf, buf_len, "CPHB"); + break; + case LSOF_PROTOCOL_WSN: + (void)snpf(buf, buf_len, "WSN"); + break; + case LSOF_PROTOCOL_PVP: + (void)snpf(buf, buf_len, "PVP"); + break; + case LSOF_PROTOCOL_BRSATMON: + (void)snpf(buf, buf_len, "BRSTMON"); + break; + case LSOF_PROTOCOL_ND: + (void)snpf(buf, buf_len, "ND"); + break; + case LSOF_PROTOCOL_WBMON: + (void)snpf(buf, buf_len, "WBMON"); + break; + case LSOF_PROTOCOL_WBEXPAK: + (void)snpf(buf, buf_len, "WBEXPAK"); + break; + case LSOF_PROTOCOL_EON: + (void)snpf(buf, buf_len, "EON"); + break; + case LSOF_PROTOCOL_VMTP: + (void)snpf(buf, buf_len, "VMTP"); + break; + case LSOF_PROTOCOL_SVMTP: + (void)snpf(buf, buf_len, "SVMTP"); + break; + case LSOF_PROTOCOL_VINES: + (void)snpf(buf, buf_len, "VINES"); + break; + case LSOF_PROTOCOL_TTP: + (void)snpf(buf, buf_len, "TTP"); + break; + case LSOF_PROTOCOL_IGP: + (void)snpf(buf, buf_len, "IGP"); + break; + case LSOF_PROTOCOL_DGP: + (void)snpf(buf, buf_len, "DGP"); + break; + case LSOF_PROTOCOL_TCF: + (void)snpf(buf, buf_len, "TCF"); + break; + case LSOF_PROTOCOL_IGRP: + (void)snpf(buf, buf_len, "IGRP"); + break; + case LSOF_PROTOCOL_OSPFIGP: + (void)snpf(buf, buf_len, "OSPFIGP"); + break; + case LSOF_PROTOCOL_SRPC: + (void)snpf(buf, buf_len, "SRPC"); + break; + case LSOF_PROTOCOL_LARP: + (void)snpf(buf, buf_len, "LARP"); + break; + case LSOF_PROTOCOL_MTP: + (void)snpf(buf, buf_len, "MTP"); + break; + case LSOF_PROTOCOL_AX25: + (void)snpf(buf, buf_len, "AX25"); + break; + case LSOF_PROTOCOL_BEETPH: + (void)snpf(buf, buf_len, "BEETPH"); + break; + case LSOF_PROTOCOL_IPEIP: + (void)snpf(buf, buf_len, "IPEIP"); + break; + case LSOF_PROTOCOL_MICP: + (void)snpf(buf, buf_len, "MICP"); + break; + case LSOF_PROTOCOL_SCCSP: + (void)snpf(buf, buf_len, "SCCSP"); + break; + case LSOF_PROTOCOL_ETHERIP: + (void)snpf(buf, buf_len, "ETHERIP"); + break; + case LSOF_PROTOCOL_ENCAP: + (void)snpf(buf, buf_len, "ENCAP"); + break; + case LSOF_PROTOCOL_APES: + (void)snpf(buf, buf_len, "APES"); + break; + case LSOF_PROTOCOL_GMTP: + (void)snpf(buf, buf_len, "GMTP"); + break; + case LSOF_PROTOCOL_PIM: + (void)snpf(buf, buf_len, "PIM"); + break; + case LSOF_PROTOCOL_COMP: + (void)snpf(buf, buf_len, "COMP"); + break; + case LSOF_PROTOCOL_IPCOMP: + (void)snpf(buf, buf_len, "IPCOMP"); + break; + case LSOF_PROTOCOL_CARP: + (void)snpf(buf, buf_len, "CARP"); + break; + case LSOF_PROTOCOL_PGM: + (void)snpf(buf, buf_len, "PGM"); + break; + case LSOF_PROTOCOL_SCTP: + (void)snpf(buf, buf_len, "SCTP"); + break; + case LSOF_PROTOCOL_MH: + (void)snpf(buf, buf_len, "MH"); + break; + case LSOF_PROTOCOL_UDPLITE: + (void)snpf(buf, buf_len, "UDPLITE"); + break; + case LSOF_PROTOCOL_MPLS: + (void)snpf(buf, buf_len, "MPLS"); + break; + case LSOF_PROTOCOL_HIP: + (void)snpf(buf, buf_len, "HIP"); + break; + case LSOF_PROTOCOL_SHIM6: + (void)snpf(buf, buf_len, "SHIM6"); + break; + case LSOF_PROTOCOL_ETHERNET: + (void)snpf(buf, buf_len, "ETHER"); + break; + case LSOF_PROTOCOL_PFSYNC: + (void)snpf(buf, buf_len, "PFSYNC"); + break; + case LSOF_PROTOCOL_RESERVED_253: + (void)snpf(buf, buf_len, "RSVD253"); + break; + case LSOF_PROTOCOL_RESERVED_254: + (void)snpf(buf, buf_len, "RSVD254"); + break; + case LSOF_PROTOCOL_OLD_DIVERT: + (void)snpf(buf, buf_len, "ODIVERT"); + break; + case LSOF_PROTOCOL_RAW: + (void)snpf(buf, buf_len, "RAW"); + break; + case LSOF_PROTOCOL_MAX: + (void)snpf(buf, buf_len, "MAX"); + break; + case LSOF_PROTOCOL_DONE: + (void)snpf(buf, buf_len, "DONE"); + break; + case LSOF_PROTOCOL_SEND: + (void)snpf(buf, buf_len, "SEND"); + break; + case LSOF_PROTOCOL_MPTCP: + (void)snpf(buf, buf_len, "MPTCP"); + break; + case LSOF_PROTOCOL_SPACER: + (void)snpf(buf, buf_len, "SPACER"); + break; + case LSOF_PROTOCOL_802_3: + (void)snpf(buf, buf_len, "802_3"); + break; + case LSOF_PROTOCOL_ALL: + (void)snpf(buf, buf_len, "ALL"); + break; + case LSOF_PROTOCOL_802_2: + (void)snpf(buf, buf_len, "802_2"); + break; + case LSOF_PROTOCOL_SNAP: + (void)snpf(buf, buf_len, "SNAP"); + break; + case LSOF_PROTOCOL_DDCMP: + (void)snpf(buf, buf_len, "DDCMP"); + break; + case LSOF_PROTOCOL_WAN_PPP: + (void)snpf(buf, buf_len, "WAN_PPP"); + break; + case LSOF_PROTOCOL_PPP_MP: + (void)snpf(buf, buf_len, "PPP_MP"); + break; + case LSOF_PROTOCOL_LOCALTALK: + (void)snpf(buf, buf_len, "LCLTALK"); + break; + case LSOF_PROTOCOL_CAN: + (void)snpf(buf, buf_len, "CAN"); + break; + case LSOF_PROTOCOL_CANFD: + (void)snpf(buf, buf_len, "CANFD"); + break; + case LSOF_PROTOCOL_CANXL: + (void)snpf(buf, buf_len, "CANXL"); + break; + case LSOF_PROTOCOL_PPPTALK: + (void)snpf(buf, buf_len, "PPPTALK"); + break; + case LSOF_PROTOCOL_TR_802_2: + (void)snpf(buf, buf_len, "802.2"); + break; + case LSOF_PROTOCOL_MOBITEX: + (void)snpf(buf, buf_len, "MOBITEX"); + break; + case LSOF_PROTOCOL_CONTROL: + (void)snpf(buf, buf_len, "CONTROL"); + break; + case LSOF_PROTOCOL_IRDA: + (void)snpf(buf, buf_len, "IRDA"); + break; + case LSOF_PROTOCOL_ECONET: + (void)snpf(buf, buf_len, "ECONET"); + break; + case LSOF_PROTOCOL_HDLC: + (void)snpf(buf, buf_len, "HDLC"); + break; + case LSOF_PROTOCOL_ARCNET: + (void)snpf(buf, buf_len, "ARCNET"); + break; + case LSOF_PROTOCOL_DSA: + (void)snpf(buf, buf_len, "DSA"); + break; + case LSOF_PROTOCOL_TRAILER: + (void)snpf(buf, buf_len, "TRAILER"); + break; + case LSOF_PROTOCOL_LOOP: + (void)snpf(buf, buf_len, "LOOP"); + break; + case LSOF_PROTOCOL_PHONET: + (void)snpf(buf, buf_len, "PHONET"); + break; + case LSOF_PROTOCOL_IEEE802154: + (void)snpf(buf, buf_len, "802154"); + break; + case LSOF_PROTOCOL_CAIF: + (void)snpf(buf, buf_len, "CAIF"); + break; + case LSOF_PROTOCOL_XDSA: + (void)snpf(buf, buf_len, "XDSA"); + break; + case LSOF_PROTOCOL_MAP: + (void)snpf(buf, buf_len, "MAP"); + break; + case LSOF_PROTOCOL_MCTP: + (void)snpf(buf, buf_len, "MCTP"); + break; + case LSOF_PROTOCOL_PUPAT: + (void)snpf(buf, buf_len, "PUPAT"); + break; + case LSOF_PROTOCOL_802_3_MIN: + (void)snpf(buf, buf_len, "802.3"); + break; + case LSOF_PROTOCOL_X25: + (void)snpf(buf, buf_len, "X25"); + break; + case LSOF_PROTOCOL_ARP: + (void)snpf(buf, buf_len, "ARP"); + break; + case LSOF_PROTOCOL_BPQ: + (void)snpf(buf, buf_len, "BPQ"); + break; + case LSOF_PROTOCOL_IEEEPUP: + (void)snpf(buf, buf_len, "IEEEPUP"); + break; + case LSOF_PROTOCOL_IEEEPUPAT: + (void)snpf(buf, buf_len, "I3EPUPAT"); + break; + case LSOF_PROTOCOL_ERSPAN2: + (void)snpf(buf, buf_len, "ERSPAN2"); + break; + case LSOF_PROTOCOL_TSN: + (void)snpf(buf, buf_len, "TSN"); + break; + case LSOF_PROTOCOL_BATMAN: + (void)snpf(buf, buf_len, "BATMAN"); + break; + case LSOF_PROTOCOL_DEC: + (void)snpf(buf, buf_len, "DEC"); + break; + case LSOF_PROTOCOL_DNA_DL: + (void)snpf(buf, buf_len, "DNA_DL"); + break; + case LSOF_PROTOCOL_DNA_RC: + (void)snpf(buf, buf_len, "DNA_RC"); + break; + case LSOF_PROTOCOL_DNA_RT: + (void)snpf(buf, buf_len, "DNA_RT"); + break; + case LSOF_PROTOCOL_LAT: + (void)snpf(buf, buf_len, "LAT"); + break; + case LSOF_PROTOCOL_DIAG: + (void)snpf(buf, buf_len, "DIAG"); + break; + case LSOF_PROTOCOL_CUST: + (void)snpf(buf, buf_len, "CUST"); + break; + case LSOF_PROTOCOL_SCA: + (void)snpf(buf, buf_len, "SCA"); + break; + case LSOF_PROTOCOL_TEB: + (void)snpf(buf, buf_len, "TEB"); + break; + case LSOF_PROTOCOL_RARP: + (void)snpf(buf, buf_len, "RARP"); + break; + case LSOF_PROTOCOL_ATALK: + (void)snpf(buf, buf_len, "ATALK"); + break; + case LSOF_PROTOCOL_AARP: + (void)snpf(buf, buf_len, "AARP"); + break; + case LSOF_PROTOCOL_8021Q: + (void)snpf(buf, buf_len, "8021Q"); + break; + case LSOF_PROTOCOL_IPX: + (void)snpf(buf, buf_len, "IPX"); + break; + case LSOF_PROTOCOL_PAUSE: + (void)snpf(buf, buf_len, "PAUSE"); + break; + case LSOF_PROTOCOL_SLOW: + (void)snpf(buf, buf_len, "SLOW"); + break; + case LSOF_PROTOCOL_WCCP: + (void)snpf(buf, buf_len, "WCCP"); + break; + case LSOF_PROTOCOL_MPLS_UC: + (void)snpf(buf, buf_len, "MPLS_UC"); + break; + case LSOF_PROTOCOL_MPLS_MC: + (void)snpf(buf, buf_len, "MPLS_MC"); + break; + case LSOF_PROTOCOL_ATMMPOA: + (void)snpf(buf, buf_len, "ATMMPOA"); + break; + case LSOF_PROTOCOL_PPP_DISC: + (void)snpf(buf, buf_len, "PPPDISC"); + break; + case LSOF_PROTOCOL_PPP_SES: + (void)snpf(buf, buf_len, "PPP_SES"); + break; + case LSOF_PROTOCOL_LINK_CTL: + (void)snpf(buf, buf_len, "LINKCTL"); + break; + case LSOF_PROTOCOL_ATMFATE: + (void)snpf(buf, buf_len, "ATMFATE"); + break; + case LSOF_PROTOCOL_PAE: + (void)snpf(buf, buf_len, "PAE"); + break; + case LSOF_PROTOCOL_PROFINET: + (void)snpf(buf, buf_len, "PROFINT"); + break; + case LSOF_PROTOCOL_REALTEK: + (void)snpf(buf, buf_len, "REALTEK"); + break; + case LSOF_PROTOCOL_AOE: + (void)snpf(buf, buf_len, "AOE"); + break; + case LSOF_PROTOCOL_ETHERCAT: + (void)snpf(buf, buf_len, "ETHCAT"); + break; + case LSOF_PROTOCOL_8021AD: + (void)snpf(buf, buf_len, "8021AD"); + break; + case LSOF_PROTOCOL_802_EX1: + (void)snpf(buf, buf_len, "802_EX1"); + break; + case LSOF_PROTOCOL_ERSPAN: + (void)snpf(buf, buf_len, "ERSPAN"); + break; + case LSOF_PROTOCOL_PREAUTH: + (void)snpf(buf, buf_len, "PREAUTH"); + break; + case LSOF_PROTOCOL_TIPC: + (void)snpf(buf, buf_len, "TIPC"); + break; + case LSOF_PROTOCOL_LLDP: + (void)snpf(buf, buf_len, "LLDP"); + break; + case LSOF_PROTOCOL_MRP: + (void)snpf(buf, buf_len, "MRP"); + break; + case LSOF_PROTOCOL_MACSEC: + (void)snpf(buf, buf_len, "MACSEC"); + break; + case LSOF_PROTOCOL_8021AH: + (void)snpf(buf, buf_len, "8021AH"); + break; + case LSOF_PROTOCOL_MVRP: + (void)snpf(buf, buf_len, "MVRP"); + break; + case LSOF_PROTOCOL_1588: + (void)snpf(buf, buf_len, "1588"); + break; + case LSOF_PROTOCOL_NCSI: + (void)snpf(buf, buf_len, "NCSI"); + break; + case LSOF_PROTOCOL_PRP: + (void)snpf(buf, buf_len, "PRP"); + break; + case LSOF_PROTOCOL_CFM: + (void)snpf(buf, buf_len, "CFM"); + break; + case LSOF_PROTOCOL_FCOE: + (void)snpf(buf, buf_len, "FCOE"); + break; + case LSOF_PROTOCOL_TDLS: + (void)snpf(buf, buf_len, "TDLS"); + break; + case LSOF_PROTOCOL_FIP: + (void)snpf(buf, buf_len, "FIP"); + break; + case LSOF_PROTOCOL_IBOE: + (void)snpf(buf, buf_len, "IBOE"); + break; + case LSOF_PROTOCOL_80221: + (void)snpf(buf, buf_len, "80221"); + break; + case LSOF_PROTOCOL_HSR: + (void)snpf(buf, buf_len, "HSR"); + break; + case LSOF_PROTOCOL_NSH: + (void)snpf(buf, buf_len, "NSH"); + break; + case LSOF_PROTOCOL_LOOPBACK: + (void)snpf(buf, buf_len, "LOOPBAK"); + break; + case LSOF_PROTOCOL_QINQ1: + (void)snpf(buf, buf_len, "QINQ1"); + break; + case LSOF_PROTOCOL_QINQ2: + (void)snpf(buf, buf_len, "QINQ2"); + break; + case LSOF_PROTOCOL_QINQ3: + (void)snpf(buf, buf_len, "QINQ3"); + break; + case LSOF_PROTOCOL_EDSA: + (void)snpf(buf, buf_len, "EDSA"); + break; + case LSOF_PROTOCOL_DSA_8021Q: + (void)snpf(buf, buf_len, "DSAD1Q"); + break; + case LSOF_PROTOCOL_DSA_A5PSW: + (void)snpf(buf, buf_len, "DSA5PSW"); + break; + case LSOF_PROTOCOL_IFE: + (void)snpf(buf, buf_len, "IFE"); + break; + case LSOF_PROTOCOL_AF_IUCV: + (void)snpf(buf, buf_len, "AF_IUCV"); + break; + } +} diff --git a/scripts/lsof_proto.h b/scripts/lsof_proto.h new file mode 100644 index 00000000..007a3972 --- /dev/null +++ b/scripts/lsof_proto.h @@ -0,0 +1,227 @@ +enum lsof_protocol { + /* Follow ip protocol numbers order */ + LSOF_PROTOCOL_IP, /**< IP(0) */ + LSOF_PROTOCOL_HOPOPTS, /**< HOPOPTS(0) */ + LSOF_PROTOCOL_ICMP, /**< ICMP(1) */ + LSOF_PROTOCOL_IGMP, /**< IGMP(2) */ + LSOF_PROTOCOL_GGP, /**< GGP(3) */ + LSOF_PROTOCOL_IPIP, /**< IPIP(4) */ + LSOF_PROTOCOL_IPV4, /**< IPV4(4) */ + LSOF_PROTOCOL_TCP, /**< TCP(6) */ + LSOF_PROTOCOL_ST, /**< ST(7) */ + LSOF_PROTOCOL_EGP, /**< EGP(8) */ + LSOF_PROTOCOL_PIGP, /**< PIGP(9) */ + LSOF_PROTOCOL_RCCMON, /**< RCCMON(10) */ + LSOF_PROTOCOL_NVPII, /**< NVPII(11) */ + LSOF_PROTOCOL_PUP, /**< PUP(12) */ + LSOF_PROTOCOL_ARGUS, /**< ARGUS(13) */ + LSOF_PROTOCOL_EMCON, /**< EMCON(14) */ + LSOF_PROTOCOL_XNET, /**< XNET(15) */ + LSOF_PROTOCOL_CHAOS, /**< CHAOS(16) */ + LSOF_PROTOCOL_UDP, /**< UDP(17) */ + LSOF_PROTOCOL_MUX, /**< MUX(18) */ + LSOF_PROTOCOL_MEAS, /**< MEAS(19) */ + LSOF_PROTOCOL_HMP, /**< HMP(20) */ + LSOF_PROTOCOL_PRM, /**< PRM(21) */ + LSOF_PROTOCOL_IDP, /**< IDP(22) */ + LSOF_PROTOCOL_TRUNK1, /**< TRUNK1(23) */ + LSOF_PROTOCOL_TRUNK2, /**< TRUNK2(24) */ + LSOF_PROTOCOL_LEAF1, /**< LEAF1(25) */ + LSOF_PROTOCOL_LEAF2, /**< LEAF2(26) */ + LSOF_PROTOCOL_RDP, /**< RDP(27) */ + LSOF_PROTOCOL_IRTP, /**< IRTP(28) */ + LSOF_PROTOCOL_TP, /**< TP(29) */ + LSOF_PROTOCOL_BLT, /**< BLT(30) */ + LSOF_PROTOCOL_NSP, /**< NSP(31) */ + LSOF_PROTOCOL_INP, /**< INP(32) */ + LSOF_PROTOCOL_DCCP, /**< DCCP(33) */ + LSOF_PROTOCOL_SEP, /**< SEP(33) */ + LSOF_PROTOCOL_3PC, /**< 3PC(34) */ + LSOF_PROTOCOL_IDPR, /**< IDPR(35) */ + LSOF_PROTOCOL_XTP, /**< XTP(36) */ + LSOF_PROTOCOL_DDP, /**< DDP(37) */ + LSOF_PROTOCOL_CMTP, /**< CMTP(38) */ + LSOF_PROTOCOL_TPXX, /**< TPXX(39) */ + LSOF_PROTOCOL_IL, /**< IL(40) */ + LSOF_PROTOCOL_IPV6, /**< IPV6(41) */ + LSOF_PROTOCOL_SDRP, /**< SDRP(42) */ + LSOF_PROTOCOL_ROUTING, /**< ROUTING(43) */ + LSOF_PROTOCOL_FRAGMENT, /**< FRAGMENT(44) */ + LSOF_PROTOCOL_IDRP, /**< IDRP(45) */ + LSOF_PROTOCOL_RSVP, /**< RSVP(46) */ + LSOF_PROTOCOL_GRE, /**< GRE(47) */ + LSOF_PROTOCOL_MHRP, /**< MHRP(48) */ + LSOF_PROTOCOL_BHA, /**< BHA(49) */ + LSOF_PROTOCOL_ESP, /**< ESP(50) */ + LSOF_PROTOCOL_AH, /**< AH(51) */ + LSOF_PROTOCOL_INLSP, /**< INLSP(52) */ + LSOF_PROTOCOL_SWIPE, /**< SWIPE(53) */ + LSOF_PROTOCOL_NHRP, /**< NHRP(54) */ + LSOF_PROTOCOL_MOBILE, /**< MOBILE(55) */ + LSOF_PROTOCOL_TLSP, /**< TLSP(56) */ + LSOF_PROTOCOL_SKIP, /**< SKIP(57) */ + LSOF_PROTOCOL_ICMPV6, /**< ICMPV6(58) */ + LSOF_PROTOCOL_NONE, /**< NONE(59) */ + LSOF_PROTOCOL_DSTOPTS, /**< DSTOPTS(60) */ + LSOF_PROTOCOL_AHIP, /**< AHIP(61) */ + LSOF_PROTOCOL_CFTP, /**< CFTP(62) */ + LSOF_PROTOCOL_HELLO, /**< HELLO(63) */ + LSOF_PROTOCOL_SATEXPAK, /**< SATEXPAK(64) */ + LSOF_PROTOCOL_KRYPTOLAN, /**< KRYPTOLAN(65) */ + LSOF_PROTOCOL_RVD, /**< RVD(66) */ + LSOF_PROTOCOL_IPPC, /**< IPPC(67) */ + LSOF_PROTOCOL_ADFS, /**< ADFS(68) */ + LSOF_PROTOCOL_SATMON, /**< SATMON(69) */ + LSOF_PROTOCOL_VISA, /**< VISA(70) */ + LSOF_PROTOCOL_IPCV, /**< IPCV(71) */ + LSOF_PROTOCOL_CPNX, /**< CPNX(72) */ + LSOF_PROTOCOL_CPHB, /**< CPHB(73) */ + LSOF_PROTOCOL_WSN, /**< WSN(74) */ + LSOF_PROTOCOL_PVP, /**< PVP(75) */ + LSOF_PROTOCOL_BRSATMON, /**< BRSATMON(76) */ + LSOF_PROTOCOL_ND, /**< ND(77) */ + LSOF_PROTOCOL_WBMON, /**< WBMON(78) */ + LSOF_PROTOCOL_WBEXPAK, /**< WBEXPAK(79) */ + LSOF_PROTOCOL_EON, /**< EON(80) */ + LSOF_PROTOCOL_VMTP, /**< VMTP(81) */ + LSOF_PROTOCOL_SVMTP, /**< SVMTP(82) */ + LSOF_PROTOCOL_VINES, /**< VINES(83) */ + LSOF_PROTOCOL_TTP, /**< TTP(84) */ + LSOF_PROTOCOL_IGP, /**< IGP(85) */ + LSOF_PROTOCOL_DGP, /**< DGP(86) */ + LSOF_PROTOCOL_TCF, /**< TCF(87) */ + LSOF_PROTOCOL_IGRP, /**< IGRP(88) */ + LSOF_PROTOCOL_OSPFIGP, /**< OSPFIGP(89) */ + LSOF_PROTOCOL_SRPC, /**< SRPC(90) */ + LSOF_PROTOCOL_LARP, /**< LARP(91) */ + LSOF_PROTOCOL_MTP, /**< MTP(92) */ + LSOF_PROTOCOL_AX25, /**< AX25(93) */ + LSOF_PROTOCOL_BEETPH, /**< BEETPH(94) */ + LSOF_PROTOCOL_IPEIP, /**< IPEIP(94) */ + LSOF_PROTOCOL_MICP, /**< MICP(95) */ + LSOF_PROTOCOL_SCCSP, /**< SCCSP(96) */ + LSOF_PROTOCOL_ETHERIP, /**< ETHERIP(97) */ + LSOF_PROTOCOL_ENCAP, /**< ENCAP(98) */ + LSOF_PROTOCOL_APES, /**< APES(99) */ + LSOF_PROTOCOL_GMTP, /**< GMTP(100) */ + LSOF_PROTOCOL_PIM, /**< PIM(103) */ + LSOF_PROTOCOL_COMP, /**< COMP(108) */ + LSOF_PROTOCOL_IPCOMP, /**< IPCOMP(108) */ + LSOF_PROTOCOL_CARP, /**< CARP(112) */ + LSOF_PROTOCOL_PGM, /**< PGM(113) */ + LSOF_PROTOCOL_SCTP, /**< SCTP(132) */ + LSOF_PROTOCOL_MH, /**< MH(135) */ + LSOF_PROTOCOL_UDPLITE, /**< UDPLITE(136) */ + LSOF_PROTOCOL_MPLS, /**< MPLS(137) */ + LSOF_PROTOCOL_HIP, /**< HIP(139) */ + LSOF_PROTOCOL_SHIM6, /**< SHIM6(140) */ + LSOF_PROTOCOL_ETHERNET, /**< ETHERNET(143) */ + LSOF_PROTOCOL_PFSYNC, /**< PFSYNC(240) */ + LSOF_PROTOCOL_RESERVED_253, /**< RESERVED_253(253) */ + LSOF_PROTOCOL_RESERVED_254, /**< RESERVED_254(254) */ + LSOF_PROTOCOL_OLD_DIVERT, /**< OLD_DIVERT(254) */ + LSOF_PROTOCOL_RAW, /**< RAW(255) */ + LSOF_PROTOCOL_MAX, /**< MAX(256) */ + LSOF_PROTOCOL_DONE, /**< DONE(257) */ + LSOF_PROTOCOL_SEND, /**< SEND(259) */ + LSOF_PROTOCOL_MPTCP, /**< MPTCP(262) */ + LSOF_PROTOCOL_SPACER, /**< SPACER(32767) */ + /* Follow ethernet type order */ + LSOF_PROTOCOL_802_3, /**< 802_3(0x0001) */ + LSOF_PROTOCOL_ALL, /**< ALL(0x0003) */ + LSOF_PROTOCOL_802_2, /**< 802_2(0x0004) */ + LSOF_PROTOCOL_SNAP, /**< SNAP(0x0005) */ + LSOF_PROTOCOL_DDCMP, /**< DDCMP(0x0006) */ + LSOF_PROTOCOL_WAN_PPP, /**< WAN_PPP(0x0007) */ + LSOF_PROTOCOL_PPP_MP, /**< PPP_MP(0x0008) */ + LSOF_PROTOCOL_LOCALTALK, /**< LOCALTALK(0x0009) */ + LSOF_PROTOCOL_CAN, /**< CAN(0x000C) */ + LSOF_PROTOCOL_CANFD, /**< CANFD(0x000D) */ + LSOF_PROTOCOL_CANXL, /**< CANXL(0x000E) */ + LSOF_PROTOCOL_PPPTALK, /**< PPPTALK(0x0010) */ + LSOF_PROTOCOL_TR_802_2, /**< TR_802_2(0x0011) */ + LSOF_PROTOCOL_MOBITEX, /**< MOBITEX(0x0015) */ + LSOF_PROTOCOL_CONTROL, /**< CONTROL(0x0016) */ + LSOF_PROTOCOL_IRDA, /**< IRDA(0x0017) */ + LSOF_PROTOCOL_ECONET, /**< ECONET(0x0018) */ + LSOF_PROTOCOL_HDLC, /**< HDLC(0x0019) */ + LSOF_PROTOCOL_ARCNET, /**< ARCNET(0x001A) */ + LSOF_PROTOCOL_DSA, /**< DSA(0x001B) */ + LSOF_PROTOCOL_TRAILER, /**< TRAILER(0x001C) */ + LSOF_PROTOCOL_LOOP, /**< LOOP(0x0060) */ + LSOF_PROTOCOL_PHONET, /**< PHONET(0x00F5) */ + LSOF_PROTOCOL_IEEE802154, /**< IEEE802154(0x00F6) */ + LSOF_PROTOCOL_CAIF, /**< CAIF(0x00F7) */ + LSOF_PROTOCOL_XDSA, /**< XDSA(0x00F8) */ + LSOF_PROTOCOL_MAP, /**< MAP(0x00F9) */ + LSOF_PROTOCOL_MCTP, /**< MCTP(0x00FA) */ + LSOF_PROTOCOL_PUPAT, /**< PUPAT(0x0201) */ + LSOF_PROTOCOL_802_3_MIN, /**< 802_3_MIN(0x0600) */ + LSOF_PROTOCOL_X25, /**< X25(0x0805) */ + LSOF_PROTOCOL_ARP, /**< ARP(0x0806) */ + LSOF_PROTOCOL_BPQ, /**< BPQ(0x08FF) */ + LSOF_PROTOCOL_IEEEPUP, /**< IEEEPUP(0x0A00) */ + LSOF_PROTOCOL_IEEEPUPAT, /**< IEEEPUPAT(0x0A01) */ + LSOF_PROTOCOL_ERSPAN2, /**< ERSPAN2(0x22EB) */ + LSOF_PROTOCOL_TSN, /**< TSN(0x22F0) */ + LSOF_PROTOCOL_BATMAN, /**< BATMAN(0x4305) */ + LSOF_PROTOCOL_DEC, /**< DEC(0x6000) */ + LSOF_PROTOCOL_DNA_DL, /**< DNA_DL(0x6001) */ + LSOF_PROTOCOL_DNA_RC, /**< DNA_RC(0x6002) */ + LSOF_PROTOCOL_DNA_RT, /**< DNA_RT(0x6003) */ + LSOF_PROTOCOL_LAT, /**< LAT(0x6004) */ + LSOF_PROTOCOL_DIAG, /**< DIAG(0x6005) */ + LSOF_PROTOCOL_CUST, /**< CUST(0x6006) */ + LSOF_PROTOCOL_SCA, /**< SCA(0x6007) */ + LSOF_PROTOCOL_TEB, /**< TEB(0x6558) */ + LSOF_PROTOCOL_RARP, /**< RARP(0x8035) */ + LSOF_PROTOCOL_ATALK, /**< ATALK(0x809B) */ + LSOF_PROTOCOL_AARP, /**< AARP(0x80F3) */ + LSOF_PROTOCOL_8021Q, /**< 8021Q(0x8100) */ + LSOF_PROTOCOL_IPX, /**< IPX(0x8137) */ + LSOF_PROTOCOL_PAUSE, /**< PAUSE(0x8808) */ + LSOF_PROTOCOL_SLOW, /**< SLOW(0x8809) */ + LSOF_PROTOCOL_WCCP, /**< WCCP(0x883E) */ + LSOF_PROTOCOL_MPLS_UC, /**< MPLS_UC(0x8847) */ + LSOF_PROTOCOL_MPLS_MC, /**< MPLS_MC(0x8848) */ + LSOF_PROTOCOL_ATMMPOA, /**< ATMMPOA(0x884C) */ + LSOF_PROTOCOL_PPP_DISC, /**< PPP_DISC(0x8863) */ + LSOF_PROTOCOL_PPP_SES, /**< PPP_SES(0x8864) */ + LSOF_PROTOCOL_LINK_CTL, /**< LINK_CTL(0x886C) */ + LSOF_PROTOCOL_ATMFATE, /**< ATMFATE(0x8884) */ + LSOF_PROTOCOL_PAE, /**< PAE(0x888E) */ + LSOF_PROTOCOL_PROFINET, /**< PROFINET(0x8892) */ + LSOF_PROTOCOL_REALTEK, /**< REALTEK(0x8899) */ + LSOF_PROTOCOL_AOE, /**< AOE(0x88A2) */ + LSOF_PROTOCOL_ETHERCAT, /**< ETHERCAT(0x88A4) */ + LSOF_PROTOCOL_8021AD, /**< 8021AD(0x88A8) */ + LSOF_PROTOCOL_802_EX1, /**< 802_EX1(0x88B5) */ + LSOF_PROTOCOL_ERSPAN, /**< ERSPAN(0x88BE) */ + LSOF_PROTOCOL_PREAUTH, /**< PREAUTH(0x88C7) */ + LSOF_PROTOCOL_TIPC, /**< TIPC(0x88CA) */ + LSOF_PROTOCOL_LLDP, /**< LLDP(0x88CC) */ + LSOF_PROTOCOL_MRP, /**< MRP(0x88E3) */ + LSOF_PROTOCOL_MACSEC, /**< MACSEC(0x88E5) */ + LSOF_PROTOCOL_8021AH, /**< 8021AH(0x88E7) */ + LSOF_PROTOCOL_MVRP, /**< MVRP(0x88F5) */ + LSOF_PROTOCOL_1588, /**< 1588(0x88F7) */ + LSOF_PROTOCOL_NCSI, /**< NCSI(0x88F8) */ + LSOF_PROTOCOL_PRP, /**< PRP(0x88FB) */ + LSOF_PROTOCOL_CFM, /**< CFM(0x8902) */ + LSOF_PROTOCOL_FCOE, /**< FCOE(0x8906) */ + LSOF_PROTOCOL_TDLS, /**< TDLS(0x890D) */ + LSOF_PROTOCOL_FIP, /**< FIP(0x8914) */ + LSOF_PROTOCOL_IBOE, /**< IBOE(0x8915) */ + LSOF_PROTOCOL_80221, /**< 80221(0x8917) */ + LSOF_PROTOCOL_HSR, /**< HSR(0x892F) */ + LSOF_PROTOCOL_NSH, /**< NSH(0x894F) */ + LSOF_PROTOCOL_LOOPBACK, /**< LOOPBACK(0x9000) */ + LSOF_PROTOCOL_QINQ1, /**< QINQ1(0x9100) */ + LSOF_PROTOCOL_QINQ2, /**< QINQ2(0x9200) */ + LSOF_PROTOCOL_QINQ3, /**< QINQ3(0x9300) */ + LSOF_PROTOCOL_EDSA, /**< EDSA(0xDADA) */ + LSOF_PROTOCOL_DSA_8021Q, /**< DSA_8021Q(0xDADB) */ + LSOF_PROTOCOL_DSA_A5PSW, /**< DSA_A5PSW(0xE001) */ + LSOF_PROTOCOL_IFE, /**< IFE(0xED3E) */ + LSOF_PROTOCOL_AF_IUCV, /**< AF_IUCV(0xFBFB) */ +}; diff --git a/src/arg.c b/src/arg.c index 69813de0..d442a5e9 100644 --- a/src/arg.c +++ b/src/arg.c @@ -30,31 +30,23 @@ #include "common.h" #include "cli.h" +#include "lsof.h" #include /* * Local definitions */ -#define CMDRXINCR 32 /* CmdRx[] allocation increment */ - /* * Local static variables */ -static int NCmdRxA = 0; /* space allocated to CmdRx[] */ - /* * Local function prototypes */ static int ckfd_range(char *first, char *dash, char *last, int *lo, int *hi); -static int enter_fd_lst(struct lsof_context *ctx, char *nm, int lo, int hi, - int excl); -static int enter_nwad(struct lsof_context *ctx, struct nwad *n, int sp, int ep, - char *s, struct hostent *he); -static struct hostent *lkup_hostnm(char *hn, struct nwad *n); -static char *isIPv4addr(char *hn, unsigned char *a, int al); +static int enter_fd_lst(char *nm, int lo, int hi, int excl); /* * ckfd_range() - check fd range @@ -102,379 +94,13 @@ static int ckfd_range(char *first, /* starting character */ return (0); } -/* - * ck_file_arg() - check file arguments - */ - -int ck_file_arg(struct lsof_context *ctx, int i, /* first file argument index */ - int ac, /* argument count */ - char *av[], /* argument vector */ - int fv, /* Ffilesys value (real or temporary) */ - int rs, /* Readlink() status if argument count == 1: - * 0 = undone; 1 = done */ - struct stat *sbp, /* if non-NULL, pointer to stat(2) buffer - * when argument count == 1 */ - int accept_deleted_file) /* if non-zero, don't report an error - * even when the file doesn't exist. */ -{ - char *ap, *fnm, *fsnm, *path; - short err = 0; - int fsm, ftype, j, k; - MALLOC_S l; - struct mounts *mp; - static struct mounts **mmp = (struct mounts **)NULL; - int mx, nm; - static int nma = 0; - struct stat sb; - struct sfile *sfp; - short ss = 0; - -#if defined(CKFA_EXPDEV) - dev_t dev, rdev; -#endif /* defined(CKFA_EXPDEV) */ - -#if defined(HASPROCFS) - unsigned char ad, an; - int pfsnl = -1; - pid_t pid; - struct procfsid *pfi; -#endif /* defined(HASPROCFS) */ - - /* - * Loop through arguments. - */ - for (; i < ac; i++) { - if (rs && (ac == 1) && (i == 0)) - path = av[i]; - else { - if (!(path = Readlink(ctx, av[i]))) { - ErrStat = 1; - continue; - } - } - /* - * Remove terminating `/' characters from paths longer than one. - */ - j = k = strlen(path); - while ((k > 1) && (path[k - 1] == '/')) { - k--; - } - if (k < j) { - if (path != av[i]) - path[k] = '\0'; - else { - if (!(ap = (char *)malloc((MALLOC_S)(k + 1)))) { - (void)fprintf(stderr, "%s: no space for copy of %s\n", Pn, - path); - Error(ctx); - } - (void)strncpy(ap, path, k); - ap[k] = '\0'; - path = ap; - } - } - /* - * Check for file system argument. - */ - for (ftype = 1, mp = readmnt(ctx), nm = 0; (fv != 1) && mp; - mp = mp->next) { - fsm = 0; - if (strcmp(mp->dir, path) == 0) - fsm++; - else if (fv == 2 || (mp->fs_mode & S_IFMT) == S_IFBLK) { - if (mp->fsnmres && strcmp(mp->fsnmres, path) == 0) - fsm++; - } - if (!fsm) - continue; - ftype = 0; - /* - * Skip duplicates. - */ - for (mx = 0; mx < nm; mx++) { - if (strcmp(mp->dir, mmp[mx]->dir) == 0 && - mp->dev == mmp[mx]->dev && mp->rdev == mmp[mx]->rdev && - mp->inode == mmp[mx]->inode) - break; - } - if (mx < nm) - continue; - /* - * Allocate space for and save another mount point match and - * the type of match -- directory name (mounted) or file system - * name (mounted-on). - */ - if (nm >= nma) { - nma += 5; - l = (MALLOC_S)(nma * sizeof(struct mounts *)); - if (mmp) - mmp = (struct mounts **)realloc((MALLOC_P *)mmp, l); - else - mmp = (struct mounts **)malloc(l); - if (!mmp) { - (void)fprintf(stderr, "%s: no space for mount pointers\n", - Pn); - Error(ctx); - } - } - mmp[nm++] = mp; - } - if (fv == 2 && nm == 0) { - if (!accept_deleted_file) { - (void)fprintf(stderr, "%s: not a file system: ", Pn); - safestrprt(av[i], stderr, 1); - } - ErrStat = 1; - continue; - } - /* - * Loop through the file system matches. If there were none, make one - * pass through the loop, using simply the path name. - */ - mx = 0; - do { - - /* - * Allocate an sfile structure and fill in the type and link. - */ - if (!(sfp = (struct sfile *)malloc(sizeof(struct sfile)))) { - (void)fprintf(stderr, "%s: no space for files\n", Pn); - Error(ctx); - } - sfp->next = Sfile; - Sfile = sfp; - sfp->f = 0; - if ((sfp->type = ftype)) { - - /* - * For a non-file system path, use the path as the file name - * and set a NULL file system name. - */ - fnm = path; - fsnm = (char *)NULL; - /* - * Stat the path to obtain its characteristics. - */ - if (sbp && (ac == 1)) - sb = *sbp; - else { - if (statsafely(ctx, fnm, &sb) != 0) { - int en = errno; - if (!accept_deleted_file) { - (void)fprintf(stderr, "%s: status error on ", Pn); - safestrprt(fnm, stderr, 0); - (void)fprintf(stderr, ": %s\n", strerror(en)); - } - Sfile = sfp->next; - (void)free((FREE_P *)sfp); - ErrStat = 1; - continue; - } - -#if defined(HASSPECDEVD) - (void)HASSPECDEVD(ctx, fnm, &sb); -#endif /* defined(HASSPECDEVD) */ - } - sfp->i = (INODETYPE)sb.st_ino; - sfp->mode = sb.st_mode & S_IFMT; - -#if defined(CKFA_EXPDEV) - /* - * Expand device numbers before saving, so that they match the - * already-expanded local mount info table device numbers. - * (This is an EP/IX 2.1.1 and above artifact.) - */ - sfp->dev = expdev(sb.st_dev); - sfp->rdev = expdev(sb.st_rdev); -#else /* !defined(CKFA_EXPDEV) */ - sfp->dev = sb.st_dev; - sfp->rdev = sb.st_rdev; -#endif /* defined(CKFA_EXPDEV) */ - -#if defined(CKFA_MPXCHAN) - /* - * Save a (possible) multiplexed channel number. (This is an - * AIX artifact.) - */ - sfp->ch = getchan(path); -#endif /* defined(CKFA_MPXCHAN) */ - - } else { - -#if defined(SAVE_MP_IN_SFILE) - sfp->mp = mp = mmp[mx++]; -#else /* !defined(SAVE_MP_IN_SFILE) */ - mp = mmp[mx++]; -#endif /* defined(SAVE_MP_IN_SFILE) */ - - ss++; - -#if defined(HASPROCFS) - /* - * If this is a /proc file system, set the search flag and - * abandon the sfile entry. - */ - if (mp == Mtprocfs) { - Sfile = sfp->next; - (void)free((FREE_P *)sfp); - Procsrch = 1; - continue; - } -#endif /* defined(HASPROCFS) */ - - /* - * Derive file name and file system name for a mount point. - * - * Save the device numbers, inode number, and modes. - */ - fnm = mp->dir; - fsnm = mp->fsname; - sfp->dev = mp->dev; - sfp->rdev = mp->rdev; - sfp->i = mp->inode; - sfp->mode = mp->mode & S_IFMT; - } - ss = 1; /* indicate a "safe" stat() */ - /* - * Store the file name and file system name pointers in the sfile - * structure, allocating space as necessary. - */ - if (!fnm || fnm == path) { - sfp->name = fnm; - -#if defined(HASPROCFS) - an = 0; -#endif /* defined(HASPROCFS) */ - - } else { - if (!(sfp->name = mkstrcpy(fnm, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for file name: ", Pn); - safestrprt(fnm, stderr, 1); - Error(ctx); - } - -#if defined(HASPROCFS) - an = 1; -#endif /* defined(HASPROCFS) */ - } - if (!fsnm || fsnm == path) { - sfp->devnm = fsnm; - -#if defined(HASPROCFS) - ad = 0; -#endif /* defined(HASPROCFS) */ - - } else { - if (!(sfp->devnm = mkstrcpy(fsnm, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, - "%s: no space for file system name: ", Pn); - safestrprt(fsnm, stderr, 1); - Error(ctx); - } - -#if defined(HASPROCFS) - ad = 1; -#endif /* defined(HASPROCFS) */ - } - if (!(sfp->aname = mkstrcpy(av[i], (MALLOC_S *)NULL))) { - (void)fprintf(stderr, - "%s: no space for argument file name: ", Pn); - safestrprt(av[i], stderr, 1); - Error(ctx); - } - -#if defined(HASPROCFS) - /* - * See if this is an individual member of a proc file system. - */ - if (!Mtprocfs || Procsrch) - continue; - -# if defined(HASFSTYPE) && HASFSTYPE == 1 - if (strcmp(sb.st_fstype, HASPROCFS) != 0) - continue; -# endif /* defined(HASFSTYPE) && HASFSTYPE==1 */ - - if (pfsnl == -1) - pfsnl = strlen(Mtprocfs->dir); - if (!pfsnl) - continue; - if (strncmp(Mtprocfs->dir, path, pfsnl) != 0) - continue; - if (path[pfsnl] != '/') - -# if defined(HASPINODEN) - pid = 0; -# else /* !defined(HASPINODEN) */ - continue; -# endif /* defined(HASPINODEN) */ - - else { - for (j = pfsnl + 1; path[j]; j++) { - if (!isdigit((unsigned char)path[j])) - break; - } - if (path[j] || (j - pfsnl - 1) < 1 || - (sfp->mode & S_IFMT) != S_IFREG) - -# if defined(HASPINODEN) - pid = 0; -# else /* !defined(HASPINODEN) */ - continue; -# endif /* defined(HASPINODEN) */ - - else - pid = atoi(&path[pfsnl + 1]); - } - if (!(pfi = (struct procfsid *)malloc( - (MALLOC_S)sizeof(struct procfsid)))) { - (void)fprintf(stderr, "%s: no space for %s ID: ", Pn, - Mtprocfs->dir); - safestrprt(path, stderr, 1); - Error(ctx); - } - pfi->pid = pid; - pfi->f = 0; - pfi->nm = sfp->aname; - pfi->next = Procfsid; - Procfsid = pfi; - -# if defined(HASPINODEN) - pfi->inode = (INODETYPE)sfp->i; -# endif /* defined(HASPINODEN) */ - - /* - * Abandon the Sfile entry, lest it be used in is_file_named(). - */ - Sfile = sfp->next; - if (ad) - (void)free((FREE_P *)sfp->devnm); - if (an) - (void)free((FREE_P *)sfp->name); - (void)free((FREE_P *)sfp); -#endif /* defined(HASPROCFS) */ - - } while (mx < nm); - } - - if (accept_deleted_file) { - if (!ss && ErrStat == 0) - err = 1; - if (ErrStat) - ErrStat = 0; - } else if (!ss) { - err = 1; - } - return ((int)err); -} - #if defined(HASDCACHE) /* * ctrl_dcache() - enter device cache control */ -int ctrl_dcache(struct lsof_context *ctx, /* context */ - char *c) /* control string */ +int ctrl_dcache(c) +char *c; /* control string */ { int rc = 0; @@ -533,7 +159,7 @@ int ctrl_dcache(struct lsof_context *ctx, /* context */ DCstate = 0; return (0); } - /* fall through */ + /* fall through */ default: (void)fprintf(stderr, "%s: unknown -D option: ", Pn); safestrprt(c, stderr, 1); @@ -554,233 +180,18 @@ int ctrl_dcache(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "%s: no space for -D path: ", Pn); safestrprt(c, stderr, 1); Error(ctx); - } - } - return (0); -} -#endif /* defined(HASDCACHE) */ - -/* - * enter_cmd_rx() - enter command regular expression - */ - -int enter_cmd_rx(struct lsof_context *ctx, char *x) /* regular expression */ -{ - int bmod = 0; - int bxmod = 0; - int i, re; - int imod = 0; - int xmod = 0; - int co = REG_NOSUB | REG_EXTENDED; - char reb[256], *xb, *xe, *xm; - MALLOC_S xl; - char *xp = (char *)NULL; - /* - * Make sure the supplied string starts a regular expression. - */ - if (!*x || (*x != '/')) { - (void)fprintf(stderr, "%s: regexp doesn't begin with '/': ", Pn); - if (x) - safestrprt(x, stderr, 1); - return (1); - } - /* - * Skip to the end ('/') of the regular expression. - */ - xb = x + 1; - for (xe = xb; *xe; xe++) { - if (*xe == '/') - break; - } - if (*xe != '/') { - (void)fprintf(stderr, "%s: regexp doesn't end with '/': ", Pn); - safestrprt(x, stderr, 1); - return (1); - } - /* - * Decode any regular expression modifiers. - */ - for (i = 0, xm = xe + 1; *xm; xm++) { - switch (*xm) { - case 'b': /* This is a basic expression. */ - if (++bmod > 1) { - if (bmod == 2) { - (void)fprintf(stderr, - "%s: b regexp modifier already used: ", Pn); - safestrprt(x, stderr, 1); - } - i = 1; - } else if (xmod) { - if (++bxmod == 1) { - (void)fprintf( - stderr, "%s: b and x regexp modifiers conflict: ", Pn); - safestrprt(x, stderr, 1); - } - i = 1; - } else - co &= ~REG_EXTENDED; - break; - case 'i': /* Ignore case. */ - if (++imod > 1) { - if (imod == 2) { - (void)fprintf(stderr, - "%s: i regexp modifier already used: ", Pn); - safestrprt(x, stderr, 1); - } - i = 1; - } else - co |= REG_ICASE; - break; - case 'x': /* This is an extended expression. */ - if (++xmod > 1) { - if (xmod == 2) { - (void)fprintf(stderr, - "%s: x regexp modifier already used: ", Pn); - safestrprt(x, stderr, 1); - } - i = 1; - } else if (bmod) { - if (++bxmod == 1) { - (void)fprintf( - stderr, "%s: b and x regexp modifiers conflict: ", Pn); - safestrprt(x, stderr, 1); - } - i = 1; - } else - co |= REG_EXTENDED; - break; - default: - (void)fprintf(stderr, "%s: invalid regexp modifier: %c\n", Pn, - (int)*xm); - i = 1; - } - } - if (i) - return (1); - /* - * Allocate space to hold expression and copy it there. - */ - xl = (MALLOC_S)(xe - xb); - if (!(xp = (char *)malloc(xl + 1))) { - (void)fprintf(stderr, "%s: no regexp space for: ", Pn); - safestrprt(x, stderr, 1); - Error(ctx); - } - (void)strncpy(xp, xb, xl); - xp[(int)xl] = '\0'; - /* - * Assign a new CmdRx[] slot for this expression. - */ - if (NCmdRxA >= NCmdRxU) { - - /* - * More CmdRx[] space must be assigned. - */ - NCmdRxA += CMDRXINCR; - xl = (MALLOC_S)(NCmdRxA * sizeof(lsof_rx_t)); - if (CmdRx) - CmdRx = (lsof_rx_t *)realloc((MALLOC_P *)CmdRx, xl); - else - CmdRx = (lsof_rx_t *)malloc(xl); - if (!CmdRx) { - (void)fprintf(stderr, "%s: no space for regexp: ", Pn); - safestrprt(x, stderr, 1); - Error(ctx); - } - } - i = NCmdRxU; - CmdRx[i].exp = xp; - /* - * Compile the expression. - */ - if ((re = regcomp(&CmdRx[i].cx, xp, co))) { - (void)fprintf(stderr, "%s: regexp error: ", Pn); - safestrprt(x, stderr, 0); - (void)regerror(re, &CmdRx[i].cx, &reb[0], sizeof(reb)); - (void)fprintf(stderr, ": %s\n", reb); - if (xp) { - (void)free((FREE_P *)xp); - xp = (char *)NULL; - } - return (1); - } - /* - * Complete the CmdRx[] table entry. - */ - CmdRx[i].mc = 0; - CmdRx[i].exp = xp; - NCmdRxU++; - return (0); -} - -#if defined(HASEOPT) -/* - * enter_efsys() -- enter path of file system whose kernel blocks are to be - * eliminated - */ - -int enter_efsys(struct lsof_context *ctx, /* context */ - char *e, /* file system path */ - int rdlnk) /* avoid readlink(2) if non-zero */ -{ - char *ec; /* pointer to copy of path */ - efsys_list_t *ep; /* file system path list pointer */ - int i; /* temporary index */ - char *path; /* Readlink() of file system path */ - - if (!e || (*e != '/')) { - if (!Fwarn) - (void)fprintf(stderr, - "%s: -e not followed by a file system path: \"%s\"\n", - Pn, e); - return (1); - } - if (!(ec = mkstrcpy(e, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for -e string: ", Pn); - safestrprt(e, stderr, 1); - Error(ctx); - } - if (rdlnk) - path = ec; - else { - if (!(path = Readlink(ctx, ec))) return (1); - } - /* - * Remove terminating `/' characters from paths longer than one. - */ - for (i = (int)strlen(path); (i > 1) && (path[i - 1] == '/'); i--) { - path[i - 1] = '\0'; - } - /* - * Enter file system path on list, avoiding duplicates. - */ - for (ep = Efsysl; ep; ep = ep->next) { - if (!strcmp(ep->path, path)) { - (void)free((FREE_P *)path); - return (0); } } - if (!(ep = (efsys_list_t *)malloc((MALLOC_S)(sizeof(efsys_list_t))))) { - (void)fprintf(stderr, "%s: no space for \"-e %s\" entry\n", Pn, e); - Error(ctx); - } - ep->path = path; - ep->pathl = i; - ep->rdlnk = rdlnk; - ep->mp = (struct mounts *)NULL; - ep->next = Efsysl; - Efsysl = ep; return (0); } -#endif /* defined(HASEOPT) */ +#endif /* defined(HASDCACHE) */ /* * enter_fd() - enter file descriptor list for searching */ -int enter_fd(struct lsof_context *ctx, /* context */ - char *f) /* file descriptor list pointer */ +int enter_fd(char *f) /* file descriptor list pointer */ { char c, *cp1, *cp2, *dash; int err, excl, hi, lo; @@ -796,6 +207,7 @@ int enter_fd(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "%s: no space for fd string: ", Pn); safestrprt(f, stderr, 1); Error(ctx); + return (1); } /* * Isolate each file descriptor in the comma-separated list, then enter it @@ -824,11 +236,11 @@ int enter_fd(struct lsof_context *ctx, /* context */ if (ckfd_range(cp1, dash, cp2, &lo, &hi)) err = 1; else { - if (enter_fd_lst(ctx, (char *)NULL, lo, hi, excl)) + if (enter_fd_lst((char *)NULL, lo, hi, excl)) err = 1; } } else { - if (enter_fd_lst(ctx, cp1, 0, 0, excl)) + if (enter_fd_lst(cp1, 0, 0, excl)) err = 1; } } @@ -844,54 +256,16 @@ int enter_fd(struct lsof_context *ctx, /* context */ * enter_fd_lst() - make an entry in the FD list, Fdl */ -static int enter_fd_lst(struct lsof_context *ctx, /* context */ - char *nm, /* FD name (none if NULL) */ +static int enter_fd_lst(char *nm, /* FD name (none if NULL) */ int lo, /* FD low boundary (if nm NULL) */ int hi, /* FD high boundary (if nm NULL) */ int excl) /* exclusion on match */ { char buf[256], *cp; int n; - struct fd_lst *f, *ft; - /* - * Don't allow a mixture of exclusions and inclusions. - */ - if (FdlTy >= 0) { - if (FdlTy != excl) { - if (!Fwarn) { + enum lsof_fd_type fd_type; - /* - * If warnings are enabled, report a mixture. - */ - if (nm) { - (void)snpf(buf, sizeof(buf) - 1, "%s%s", excl ? "^" : "", - nm); - } else { - if (lo != hi) { - (void)snpf(buf, sizeof(buf) - 1, "%s%d-%d", - excl ? "^" : "", lo, hi); - } else { - (void)snpf(buf, sizeof(buf) - 1, "%s%d", - excl ? "^" : "", lo); - } - } - buf[sizeof(buf) - 1] = '\0'; - (void)fprintf(stderr, "%s: %s in an %s -d list: %s\n", Pn, - excl ? "exclude" : "include", - FdlTy ? "exclude" : "include", buf); - } - return (1); - } - } - /* - * Allocate an fd_lst entry. - */ - if (!(f = (struct fd_lst *)malloc((MALLOC_S)sizeof(struct fd_lst)))) { - (void)fprintf(stderr, "%s: no space for FD list entry\n", Pn); - Error(ctx); - } if (nm) { - /* * Process an FD name. First see if it contains only digits; if it * does, convert them to an integer and set the low and high @@ -906,44 +280,47 @@ static int enter_fd_lst(struct lsof_context *ctx, /* context */ n = (n * 10) + (int)(*cp - '0'); } if (*cp) { - if (!(f->nm = mkstrcpy(nm, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for copy of: %s\n", Pn, nm); - Error(ctx); - } lo = 1; hi = 0; + if (strcmp(nm, "unk") == 0) { + fd_type = LSOF_FD_UNKNOWN; + } else if (strcmp(nm, "cwd") == 0) { + fd_type = LSOF_FD_CWD; + } else if (strcmp(nm, "err") == 0) { + fd_type = LSOF_FD_ERROR; + } else if (strcmp(nm, "rtd") == 0) { + fd_type = LSOF_FD_ROOT_DIR; + } else if (strcmp(nm, "pd") == 0) { + fd_type = LSOF_FD_PARENT_DIR; + } else if (strcmp(nm, "txt") == 0) { + fd_type = LSOF_FD_PROGRAM_TEXT; + } else if (strcmp(nm, "mem") == 0) { + fd_type = LSOF_FD_MEMORY; + } else if (strcmp(nm, "del") == 0) { + fd_type = LSOF_FD_DELETED; + } else if (strcmp(nm, "ctty") == 0) { + fd_type = LSOF_FD_CTTY; + } else if (strcmp(nm, "fd") == 0) { + /* pseudo fd type meaning whole range of fd */ + fd_type = LSOF_FD_NUMERIC; + hi = INT_MAX; + lo = 0; + } else { + (void)fprintf(stderr, + "%s: invalid fd type given in -d option\n", Pn); + Error(ctx); + return (1); + } } else { - f->nm = (char *)NULL; + fd_type = LSOF_FD_NUMERIC; lo = hi = n; } } else - f->nm = (char *)NULL; - /* - * Skip duplicates. - */ - for (ft = Fdl; ft; ft = ft->next) { - if (f->nm) { - if (!ft->nm || strcmp(f->nm, ft->nm)) - continue; - } else if ((lo != ft->lo) || (hi != ft->hi)) - continue; - (void)free((FREE_P *)f); - return (0); - } - /* - * Complete the fd_lst entry and link it to the head of the chain. - */ - f->hi = hi; - f->lo = lo; - if (f->nm && strcmp(f->nm, "fd") == 0) { - (void)free((FREE_P *)f->nm); - f->nm = NULL; - f->hi = INT_MAX; - f->lo = 0; + fd_type = LSOF_FD_NUMERIC; + + if (lsof_select_fd(ctx, fd_type, lo, hi, excl)) { + return (1); } - f->next = Fdl; - Fdl = f; - FdlTy = excl; return (0); } @@ -953,11 +330,10 @@ static int enter_fd_lst(struct lsof_context *ctx, /* context */ #define EDDEFFNL 128 /* default file name length */ -int enter_dir(struct lsof_context *ctx, /* context */ - char *d, /* directory path name pointer */ - int descend) /* subdirectory descend flag: - * 0 = don't descend - * 1 = descend */ +int enter_dir(char *d, /* directory path name pointer */ + int descend) /* subdirectory descend flag: + * 0 = don't descend + * 1 = descend */ { char *av[2]; dev_t ddev; @@ -968,6 +344,7 @@ int enter_dir(struct lsof_context *ctx, /* context */ int en, sl; int fct = 0; char *fp = (char *)NULL; + char *temp = (char *)NULL; MALLOC_S fpl = (MALLOC_S)0; MALLOC_S fpli = (MALLOC_S)0; struct stat sb; @@ -1022,7 +399,7 @@ int enter_dir(struct lsof_context *ctx, /* context */ av[0] = (dn == d) ? mkstrcpy(dn, (MALLOC_S *)NULL) : dn; av[1] = (char *)NULL; dn = (char *)NULL; - if (!ck_file_arg(ctx, 0, 1, av, 1, 1, &sb, 0)) { + if (!ck_file_arg(ctx, av[0], 1, 1, &sb, 0)) { av[0] = (char *)NULL; fct++; } @@ -1058,16 +435,18 @@ int enter_dir(struct lsof_context *ctx, /* context */ if ((int)fpli > (int)fpl) { fpl = fpli; if (!fp) - fp = (char *)malloc(fpl); + temp = (char *)malloc(fpl); else - fp = (char *)realloc(fp, fpl); - if (!fp) { + temp = (char *)realloc(fp, fpl); + if (!temp) { (void)fprintf( stderr, "%s: no space for path to entries in directory: %s\n", Pn, dn); Error(ctx); + return (1); } + fp = temp; } (void)snpf(fp, (size_t)fpl, "%s%s", dn, sl ? "/" : ""); (void)free((FREE_P *)dn); @@ -1106,13 +485,15 @@ int enter_dir(struct lsof_context *ctx, /* context */ fpli = (MALLOC_S)(dnamlen - (fpl - dnl - sl - 1)); if ((int)fpli > 0) { fpl += fpli; - if (!(fp = (char *)realloc(fp, fpl))) { + if (!(temp = (char *)realloc(fp, fpl))) { (void)fprintf(stderr, "%s: no space for: ", Pn); safestrprt(dn, stderr, 0); putc('/', stderr); safestrprtn(dp->d_name, dnamlen, stderr, 1); Error(ctx); + return (1); } + fp = temp; } (void)strncpy(fp + dnl + sl, dp->d_name, dnamlen); fp[dnl + sl + dnamlen] = '\0'; @@ -1184,7 +565,7 @@ int enter_dir(struct lsof_context *ctx, /* context */ * Use ck_file_arg() to record the entry for searching. Force it * to consider the entry a file, not a file system. */ - if (!ck_file_arg(ctx, 0, 1, av, 1, 1, &sb, 0)) { + if (!ck_file_arg(ctx, av[0], 1, 1, &sb, 0)) { av[0] = (char *)NULL; fct++; } @@ -1233,9 +614,8 @@ int enter_dir(struct lsof_context *ctx, /* context */ * enter_id() - enter PGID or PID for searching */ -int enter_id(struct lsof_context *ctx, /* context */ - enum IDType ty, /* type: PGID or PID */ - char *p) /* process group ID string pointer */ +int enter_id(enum IDType ty, /* type: PGID or PID */ + char *p) /* process group ID string pointer */ { char *cp; int err, i, id, j, mx, n, ni, nx, x; @@ -1246,30 +626,6 @@ int enter_id(struct lsof_context *ctx, /* context */ (ty == PGID) ? " group" : ""); return (1); } - /* - * Set up variables for the type of ID. - */ - switch (ty) { - case PGID: - mx = Mxpgid; - n = Npgid; - ni = Npgidi; - nx = Npgidx; - s = Spgid; - break; - case PID: - mx = Mxpid; - n = Npid; - ni = Npidi; - nx = Npidx; - s = Spid; - break; - default: - (void)fprintf(stderr, "%s: enter_id \"", Pn); - safestrprt(p, stderr, 0); - (void)fprintf(stderr, "\", invalid type: %d\n", ty); - Error(ctx); - } /* * Convert and store the ID. */ @@ -1303,609 +659,17 @@ int enter_id(struct lsof_context *ctx, /* context */ } if (*cp) cp++; - /* - * Avoid entering duplicates and conflicts. - */ - for (i = j = 0; i < n; i++) { - if (id == s[i].i) { - if (x == s[i].x) { - j = 1; - continue; - } - (void)fprintf(stderr, - "%s: P%sID %d has been included and excluded.\n", - Pn, (ty == PGID) ? "G" : "", id); - err = j = 1; - break; - } - } - if (j) - continue; - /* - * Allocate table table space. - */ - if (n >= mx) { - mx += IDINCR; - if (!s) - s = (struct int_lst *)malloc( - (MALLOC_S)(sizeof(struct int_lst) * mx)); - else - s = (struct int_lst *)realloc( - (MALLOC_P *)s, (MALLOC_S)(sizeof(struct int_lst) * mx)); - if (!s) { - (void)fprintf(stderr, "%s: no space for %d process%s IDs", Pn, - mx, (ty == PGID) ? " group" : ""); - Error(ctx); - } - } - s[n].f = 0; - s[n].i = id; - s[n++].x = x; - if (x) - nx++; - else - ni++; - } - /* - * Save variables for the type of ID. - */ - if (ty == PGID) { - Mxpgid = mx; - Npgid = n; - Npgidi = ni; - Npgidx = nx; - Spgid = s; - } else { - Mxpid = mx; - Npid = Npuns = n; - Npidi = ni; - Npidx = nx; - Spid = s; - } - return (err); -} - -/* - * enter_network_address() - enter Internet address for searching - */ - -int enter_network_address(struct lsof_context *ctx, /* context */ - char *na) /* Internet address string pointer */ -{ - int ae, i, pr; - int ep = -1; - int ft = 0; - struct hostent *he = (struct hostent *)NULL; - char *hn = (char *)NULL; - MALLOC_S l; - struct nwad n; - char *p, *wa; - int pt = 0; - int pu = 0; - struct servent *se, *se1; - char *sn = (char *)NULL; - int sp = -1; - MALLOC_S snl = 0; - -#if defined(HASIPv6) - char *cp; -#endif /* defined(HASIPv6) */ - - if (!na) { - (void)fprintf(stderr, "%s: no network address specified\n", Pn); - return (1); - } - zeromem((char *)&n, sizeof(n)); - wa = na; - /* - * Process an IP version type specification, IPv4 or IPv6, optionally - * followed by a '@' and a host name or Internet address, or a ':' and a - * service name or port number. - */ - if ((*wa == '4') || (*wa == '6')) { - if (*wa == '4') - ft = 4; - else if (*wa == '6') { - -#if defined(HASIPv6) - ft = 6; -#else /* !defined(HASIPv6) */ - (void)fprintf(stderr, "%s: IPv6 not supported: -i ", Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; -#endif /* defined(HASIPv6) */ - } - wa++; - if (!*wa) { - - /* - * If nothing follows 4 or 6, then all network files of the - * specified IP version are selected. Sequential -i, -i4, and - * -i6 specifications interact logically -- e.g., -i[46] followed - * by -i[64] is the same as -i. - */ - if (!Fnet) { - Fnet = 1; - FnetTy = ft; - } else { - if (FnetTy) { - if (FnetTy != ft) - FnetTy = 0; - } else - FnetTy = ft; - } - return (0); - } - } else if (Fnet) - ft = FnetTy; - /* - * If an IP version has been specified, use it to set the address family. - */ - switch (ft) { - case 4: - n.af = AF_INET; - break; - -#if defined(HASIPv6) - case 6: - n.af = AF_INET6; - break; -#endif /* defined(HASIPv6) */ - } - /* - * Process protocol name, optionally followed by a '@' and a host name or - * Internet address, or a ':' and a service name or port number. - */ - if (*wa && *wa != '@' && *wa != ':') { - for (p = wa; *wa && *wa != '@' && *wa != ':'; wa++) - ; - if ((l = wa - p)) { - if (!(n.proto = mkstrcat(p, l, (char *)NULL, -1, (char *)NULL, -1, - (MALLOC_S *)NULL))) { - (void)fprintf(stderr, - "%s: no space for protocol name from: -i ", Pn); - safestrprt(na, stderr, 1); - nwad_exit: - if (n.proto) - (void)free((FREE_P *)n.proto); - if (hn) - (void)free((FREE_P *)hn); - if (sn) - (void)free((FREE_P *)sn); - return (1); - } - /* - * The protocol name should be "tcp", "udp" or "udplite". - */ - if ((strcasecmp(n.proto, "tcp") != 0) && - (strcasecmp(n.proto, "udp") != 0) && - (strcasecmp(n.proto, "udplite") != 0)) { - (void)fprintf(stderr, "%s: unknown protocol name (%s) in: -i ", - Pn, n.proto); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - /* - * Convert protocol name to lower case. - */ - for (p = n.proto; *p; p++) { - if (*p >= 'A' && *p <= 'Z') - *p = *p - 'A' + 'a'; - } - } - } - /* - * Process an IPv4 address (1.2.3.4), IPv6 address ([1:2:3:4:5:6:7:8]), - * or host name, preceded by a '@' and optionally followed by a colon - * and a service name or port number. - */ - if (*wa == '@') { - wa++; - if (!*wa || *wa == ':') { - -#if defined(HASIPv6) - unacc_address: -#endif /* defined(HASIPv6) */ - - (void)fprintf(stderr, "%s: unacceptable Internet address in: -i ", - Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - - if ((p = isIPv4addr(wa, n.a, sizeof(n.a)))) { - - /* - * Process IPv4 address. - */ - if (ft == 6) { - (void)fprintf(stderr, "%s: IPv4 addresses are prohibited: -i ", - Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - wa = p; - n.af = AF_INET; - } else if (*wa == '[') { - -#if defined(HASIPv6) - /* - * Make sure IPv6 addresses are permitted. If they are, assemble - * one. - */ - if (ft == 4) { - (void)fprintf(stderr, "%s: IPv6 addresses are prohibited: -i ", - Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - if (!(cp = strrchr(++wa, ']'))) - goto unacc_address; - *cp = '\0'; - i = inet_pton(AF_INET6, wa, (void *)&n.a); - *cp = ']'; - if (i != 1) - goto unacc_address; - for (ae = i = 0; i < MAX_AF_ADDR; i++) { - if ((ae |= n.a[i])) - break; + if (ty == PGID) { + if (lsof_select_pgid(ctx, id, x)) { + err = 1; } - if (!ae) - goto unacc_address; - if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)&n.a[0])) { - if (ft == 6) { - (void)fprintf(stderr, - "%s: IPv4 addresses are prohibited: -i ", Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - for (i = 0; i < 4; i++) { - n.a[i] = n.a[i + 12]; - } - n.af = AF_INET; - } else - n.af = AF_INET6; - wa = cp + 1; -#else /* !defined(HASIPv6) */ - (void)fprintf(stderr, "%s: unsupported IPv6 address in: -i ", Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; -#endif /* defined(HASIPv6) */ - } else { - - /* - * Assemble host name. - */ - for (p = wa; *p && *p != ':'; p++) - ; - if ((l = p - wa)) { - if (!(hn = mkstrcat(wa, l, (char *)NULL, -1, (char *)NULL, -1, - (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for host name: -i ", - Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - -#if defined(HASIPv6) - - /* - * If no IP version has been specified, look up an IPv6 host - * name first. If that fails, look up an IPv4 host name. - * - * If the IPv6 version has been specified, look up the host - * name only under its IP version specification. - */ - if (!ft) - n.af = AF_INET6; - if (!(he = lkup_hostnm(hn, &n)) && !ft) { - n.af = AF_INET; - he = lkup_hostnm(hn, &n); - } -#else /* !defined(HASIPv6) */ - if (!ft) - n.af = AF_INET; - he = lkup_hostnm(hn, &n); -#endif /* defined(HASIPv6) */ - - if (!he) { - fprintf(stderr, "%s: unknown host name (%s) in: -i ", Pn, - hn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - } - wa = p; - } - } - /* - * If there is no port number, enter the address. - */ - if (!*wa) - goto nwad_enter; - /* - * Process a service name or port number list, preceded by a colon. - * - * Entries of the list are separated with commas; elements of a numeric - * range are specified with a separating minus sign (`-'); all service names - * must belong to the same protocol; embedded spaces are not allowed. An - * embedded minus sign in a name is taken to be part of the name, the - * starting entry of a range can't be a service name. - */ - if (*wa != ':' || *(wa + 1) == '\0') { - - unacc_port: - (void)fprintf(stderr, "%s: unacceptable port specification in: -i ", - Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - for (++wa; wa && *wa; wa++) { - for (ep = pr = sp = 0; *wa; wa++) { - if (*wa < '0' || *wa > '9') { - - /* - * Convert service name to port number, using already-specified - * protocol name. A '-' is taken to be part of the name; hence - * the starting entry of a range can't be a service name. - */ - for (p = wa; *wa && *wa != ','; wa++) - ; - if (!(l = wa - p)) { - (void)fprintf(stderr, "%s: invalid service name: -i ", Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - if (sn) { - if (l > snl) { - sn = (char *)realloc((MALLOC_P *)sn, l + 1); - snl = l; - } - } else { - sn = (char *)malloc(l + 1); - snl = l; - } - if (!sn) { - (void)fprintf(stderr, "%s: no space for service name: -i ", - Pn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - (void)strncpy(sn, p, l); - *(sn + l) = '\0'; - if (n.proto) { - - /* - * If the protocol has been specified, look up the port - * number for the service name for the specified protocol. - */ - if (!(se = getservbyname(sn, n.proto))) { - (void)fprintf(stderr, - "%s: unknown service %s for %s in: -i ", - Pn, sn, n.proto); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - pt = (int)ntohs(se->s_port); - } else { - - /* - * If no protocol has been specified, look up the port - * numbers for the service name for both TCP and UDP. - */ - if ((se = getservbyname(sn, "tcp"))) - pt = (int)ntohs(se->s_port); - if ((se1 = getservbyname(sn, "udp"))) - pu = (int)ntohs(se1->s_port); - if (!se && !se1) { - (void)fprintf(stderr, "%s: unknown service %s in: -i ", - Pn, sn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - if (se && se1 && pt != pu) { - (void)fprintf( - stderr, - "%s: TCP=%d and UDP=%d %s ports conflict;\n", Pn, - pt, pu, sn); - (void)fprintf( - stderr, - " specify \"tcp:%s\" or \"udp:%s\": -i ", sn, - sn); - safestrprt(na, stderr, 1); - goto nwad_exit; - } - if (!se && se1) - pt = pu; - } - if (pr) - ep = pt; - else { - sp = pt; - if (*wa == '-') - pr++; - } - } else { - - /* - * Assemble port number. - */ - for (; *wa && *wa != ','; wa++) { - if (*wa == '-') { - if (pr) - goto unacc_port; - pr++; - break; - } - if (*wa < '0' || *wa > '9') - goto unacc_port; - if (pr) - ep = (ep * 10) + *wa - '0'; - else - sp = (sp * 10) + *wa - '0'; - } - } - if (!*wa || *wa == ',') - break; - if (pr) - continue; - goto unacc_port; - } - if (!pr) - ep = sp; - if (ep < sp) - goto unacc_port; - /* - * Enter completed port or port range specification. - */ - - nwad_enter: - - for (i = 1; i;) { - if (enter_nwad(ctx, &n, sp, ep, na, he)) - goto nwad_exit; - -#if defined(HASIPv6) - /* - * If IPv6 is enabled, a host name was specified, and the - * associated * address is for the AF_INET6 address family, - * try to get and address for the AF_INET family, too, unless - * IPv4 is prohibited. - */ - if (hn && (n.af == AF_INET6) && (ft != 6)) { - n.af = AF_INET; - if ((he = lkup_hostnm(hn, &n))) - continue; - } -#endif /* defined(HASIPv6) */ - - i = 0; - } - if (!*wa) - break; - } - if (sn) - (void)free((FREE_P *)sn); - return (0); -} - -/* - * enter_nwad() - enter nwad structure - */ - -static int enter_nwad(struct lsof_context *ctx, /* context */ - struct nwad *n, /* pointer to partially completed - * nwad (less port) */ - int sp, /* starting port number */ - int ep, /* ending port number */ - char *s, /* string that states the address */ - struct hostent *he) /* pointer to hostent struct from - * which network address came */ -{ - int ac; - unsigned char *ap; - static int na = 0; - struct nwad nc; - struct nwad *np; - /* - * Allocate space for the argument specification. - */ - if (strlen(s)) { - if (!(n->arg = mkstrcpy(s, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for Internet argument: -i ", - Pn); - safestrprt(s, stderr, 1); - Error(ctx); - } - } else - n->arg = (char *)NULL; - /* - * Loop through all hostent addresses. - */ - for (ac = 1, nc = *n;;) { - - /* - * Test address specification -- it must contain at least one of: - * protocol, Internet address or port. If correct, link into search - * list. - */ - if (!nc.proto && !nc.a[0] && !nc.a[1] && !nc.a[2] && !nc.a[3] - -#if defined(HASIPv6) - && (nc.af != AF_INET6 || - (!nc.a[4] && !nc.a[5] && !nc.a[6] && !nc.a[7] && !nc.a[8] && - !nc.a[9] && !nc.a[10] && !nc.a[11] && !nc.a[12] && !nc.a[13] && - !nc.a[14] && !nc.a[15])) -#endif /* defined(HASIPv6) */ - - && sp == -1) { - (void)fprintf(stderr, - "%s: incomplete Internet address specification: -i ", - Pn); - safestrprt(s, stderr, 1); - return (1); - } - /* - * Limit the network address chain length to MAXNWAD for reasons of - * search efficiency. - */ - if (na >= MAXNWAD) { - (void)fprintf(stderr, - "%s: network address limit (%d) exceeded: -i ", Pn, - MAXNWAD); - safestrprt(s, stderr, 1); - return (1); - } - /* - * Allocate space for the address specification. - */ - if ((np = (struct nwad *)malloc(sizeof(struct nwad))) == NULL) { - (void)fprintf(stderr, "%s: no space for network address from: -i ", - Pn); - safestrprt(s, stderr, 1); - return (1); - } - /* - * Construct and link the address specification. - */ - *np = nc; - np->sport = sp; - np->eport = ep; - np->f = 0; - np->next = Nwad; - Nwad = np; - na++; - /* - * If the network address came from gethostbyname(), advance to - * the next address; otherwise quit. - */ - if (!he) - break; - if (!he->h_addr_list[ac - - 1]) /* Check if address list ended prematurely */ - break; - if (!(ap = (unsigned char *)he->h_addr_list[ac++])) - break; - -#if defined(HASIPv6) - { - int i; - - for (i = 0; (i < (he->h_length - 1)) && (i < (MAX_AF_ADDR - 1)); - i++) { - nc.a[i] = *ap++; + if (lsof_select_pid(ctx, id, x)) { + err = 1; } - nc.a[i] = *ap; } -#else /* !defined(HASIPv6) */ - nc.a[0] = *ap++; - nc.a[1] = *ap++; - nc.a[2] = *ap++; - nc.a[3] = *ap; -#endif /* defined(HASIPv6) */ } - return (0); + return (err); } #if defined(HASTCPUDPSTATE) @@ -1913,11 +677,10 @@ static int enter_nwad(struct lsof_context *ctx, /* context */ * enter_state_spec() -- enter TCP and UDP state specifications */ -int enter_state_spec(struct lsof_context *ctx, - char *ss) /* state specification string */ +int enter_state_spec(char *ss) /* state specification string */ { char *cp, *ne, *ns, *pr; - int err, d, f, i, tx, x; + int err, d, f, i, tcp, x; static char *ssc = (char *)NULL; char *ty; /* @@ -1925,13 +688,13 @@ int enter_state_spec(struct lsof_context *ctx, */ if (!strncasecmp(ss, "tcp:", 4)) { pr = "TCP"; - tx = 0; + tcp = 1; } # if !defined(USE_LIB_PRINT_TCPTPI) else if (!strncasecmp(ss, "UDP:", 4)) { pr = "UDP"; - tx = 1; + tcp = 0; } # endif /* !defined(USE_LIB_PRINT_TCPTPI) */ @@ -1945,54 +708,7 @@ int enter_state_spec(struct lsof_context *ctx, (void)fprintf(stderr, "%s: no %s state names in: %s\n", Pn, pr, ss); return (1); } - (void)build_IPstates(ctx); - if (!(tx ? UdpSt : TcpSt)) { - (void)fprintf(stderr, "%s: no %s state names available: %s\n", Pn, pr, - ss); - return (1); - } - /* - * Allocate the inclusion and exclusion tables for the protocol. - */ - if (tx) { - if (UdpNstates) { - if (!UdpStI) { - if (!(UdpStI = (unsigned char *)calloc( - (MALLOC_S)UdpNstates, sizeof(unsigned char)))) { - ty = "UDP state inclusion"; - - no_IorX_space: - (void)fprintf(stderr, "%s: no %s table space\n", Pn, ty); - Error(ctx); - } - } - if (!UdpStX) { - if (!(UdpStX = (unsigned char *)calloc( - (MALLOC_S)UdpNstates, sizeof(unsigned char)))) { - ty = "UDP state exclusion"; - goto no_IorX_space; - } - } - } - } else { - if (TcpNstates) { - if (!TcpStI) { - if (!(TcpStI = (unsigned char *)calloc( - (MALLOC_S)TcpNstates, sizeof(unsigned char)))) { - ty = "TCP state inclusion"; - goto no_IorX_space; - } - } - if (!TcpStX) { - if (!(TcpStX = (unsigned char *)calloc( - (MALLOC_S)TcpNstates, sizeof(unsigned char)))) { - ty = "TCP state exclusion"; - goto no_IorX_space; - } - } - } - } /* * Convert the state names in the rest of the string to state indexes and * record them in the appropriate inclusion or exclusion table. @@ -2003,6 +719,7 @@ int enter_state_spec(struct lsof_context *ctx, (void)fprintf(stderr, "%s: no temporary state argument space for: %s\n", Pn, ss); Error(ctx); + return (1); } cp = ssc; err = 0; @@ -2035,75 +752,7 @@ int enter_state_spec(struct lsof_context *ctx, err = 1; continue; } - /* - * Find the state name in the appropriate table. - */ - f = 0; - if (tx) { - if (UdpSt) { - for (i = 0; i < UdpNstates; i++) { - if (!strcasecmp(ns, UdpSt[i])) { - f = 1; - break; - } - } - } - } else { - if (TcpSt) { - for (i = 0; i < TcpNstates; i++) { - if (!strcasecmp(ns, TcpSt[i])) { - f = 1; - break; - } - } - } - } - if (!f) { - (void)fprintf(stderr, "%s: unknown %s state name: %s\n", Pn, pr, - ns); - err = 1; - continue; - } - /* - * Set the inclusion or exclusion status in the appropriate table. - */ - d = 0; - if (x) { - if (tx) { - if (!UdpStX[i]) { - UdpStX[i] = 1; - UdpStXn++; - } else - d = 1; - } else { - if (!TcpStX[i]) { - TcpStX[i] = 1; - TcpStXn++; - } else - d = 1; - } - } else { - if (tx) { - if (!UdpStI[i]) { - UdpStI[i] = 1; - UdpStIn++; - } else - d = 1; - } else { - if (!TcpStI[i]) { - TcpStI[i] = 1; - TcpStIn++; - } else - d = 1; - } - } - if (d) { - - /* - * Report a duplicate. - */ - (void)fprintf(stderr, "%s: duplicate %s %sclusion: %s\n", Pn, pr, - x ? "ex" : "in", ns); + if (lsof_select_proto_state(ctx, tcp, ns, x)) { err = 1; } } @@ -2119,17 +768,14 @@ int enter_state_spec(struct lsof_context *ctx, #endif /* defined(HASTCPUDPSTATE) */ /* - * enter_str_lst() - enter a string on a list + * enter_cmd() - enter -c option */ -int enter_str_lst(char *opt, /* option name */ - char *s, /* string to enter */ - struct str_lst **lp, /* string's list */ - int *incl, /* included count */ - int *excl) /* excluded count */ +int enter_cmd(char *opt, /* option name */ + char *s) /* string to enter */ { char *cp; - short i, x; + short exclude; MALLOC_S len; struct str_lst *lpt; @@ -2138,34 +784,14 @@ int enter_str_lst(char *opt, /* option name */ return (1); } if (*s == '^') { - i = 0; - x = 1; + exclude = 1; s++; } else { - i = 1; - x = 0; - } - if (!(cp = mkstrcpy(s, &len))) { - (void)fprintf(stderr, "%s: no string copy space: ", Pn); - safestrprt(s, stderr, 1); - return (1); + exclude = 0; } - if ((lpt = (struct str_lst *)malloc(sizeof(struct str_lst))) == NULL) { - (void)fprintf(stderr, "%s: no list space: ", Pn); - safestrprt(s, stderr, 1); - (void)free((FREE_P *)cp); + if (lsof_select_process(ctx, s, exclude)) { return (1); } - lpt->f = 0; - lpt->str = cp; - lpt->len = (int)len; - lpt->x = x; - if (i) - *incl += 1; - if (x) - *excl += 1; - lpt->next = *lp; - *lp = lpt; return (0); } @@ -2173,8 +799,7 @@ int enter_str_lst(char *opt, /* option name */ * enter_uid() - enter User Identifier for searching */ -int enter_uid(struct lsof_context *ctx, /* context */ - char *us) /* User IDentifier string pointer */ +int enter_uid(char *us) /* User IDentifier string pointer */ { int err, i, j, lnml, nn; unsigned char excl; @@ -2230,13 +855,6 @@ int enter_uid(struct lsof_context *ctx, /* context */ continue; if (nn) { lnm[lnml++] = '\0'; - if ((pw = getpwnam(lnm)) == NULL) { - (void)fprintf(stderr, "%s: can't get UID for ", Pn); - safestrprt(lnm, stderr, 1); - err = 1; - continue; - } else - uid = pw->pw_uid; } #if defined(HASSECURITY) && !defined(HASNOSOCKSECURITY) @@ -2256,185 +874,17 @@ int enter_uid(struct lsof_context *ctx, /* context */ } #endif /* defined(HASSECURITY) && !defined(HASNOSOCKSECURITY) */ - /* - * Avoid entering duplicates. - */ - for (i = j = 0; i < Nuid; i++) { - if (uid != Suid[i].uid) - continue; - if (Suid[i].excl == excl) { - j = 1; - continue; - } - (void)fprintf(stderr, - "%s: UID %d has been included and excluded.\n", Pn, - (int)uid); - err = j = 1; - break; - } - if (j) - continue; - /* - * Allocate space for User IDentifier. - */ - if (Nuid >= Mxuid) { - Mxuid += UIDINCR; - len = (MALLOC_S)(Mxuid * sizeof(struct seluid)); - if (!Suid) - Suid = (struct seluid *)malloc(len); - else - Suid = (struct seluid *)realloc((MALLOC_P *)Suid, len); - if (!Suid) { - (void)fprintf(stderr, "%s: no space for UIDs", Pn); - Error(ctx); - } - } if (nn) { - if (!(lp = mkstrcpy(lnm, (MALLOC_S *)NULL))) { - (void)fprintf(stderr, "%s: no space for login: ", Pn); - safestrprt(lnm, stderr, 1); + if (lsof_select_login(ctx, lnm, excl)) { Error(ctx); + return (1); } - Suid[Nuid].lnm = lp; - } else - Suid[Nuid].lnm = (char *)NULL; - Suid[Nuid].uid = uid; - Suid[Nuid++].excl = excl; - if (excl) - Nuidexcl++; - else - Nuidincl++; - } - return (err); -} - -/* - * isIPv4addr() - is host name an IPv4 address - */ - -static char *isIPv4addr(char *hn, /* host name */ - unsigned char *a, /* address receptor */ - int al) /* address receptor length */ -{ - int dc = 0; /* dot count */ - int i; /* temorary index */ - int ov[MIN_AF_ADDR]; /* octet values */ - int ovx = 0; /* ov[] index */ - /* - * The host name must begin with a number and the return octet value - * arguments must be acceptable. - */ - if ((*hn < '0') || (*hn > '9')) - return ((char *)NULL); - if (!a || (al < MIN_AF_ADDR)) - return ((char *)NULL); - /* - * Start the first octet assembly, then parse tge remainder of the host - * name for four octets, separated by dots. - */ - ov[0] = (int)(*hn++ - '0'); - while (*hn && (*hn != ':')) { - if (*hn == '.') { - - /* - * Count a dot. Make sure a preceding octet value has been - * assembled. Don't assemble more than MIN_AF_ADDR octets. - */ - dc++; - if ((ov[ovx] < 0) || (ov[ovx] > 255)) - return ((char *)NULL); - if (++ovx > (MIN_AF_ADDR - 1)) - return ((char *)NULL); - ov[ovx] = -1; - } else if ((*hn >= '0') && (*hn <= '9')) { - - /* - * Assemble an octet. - */ - if (ov[ovx] < 0) - ov[ovx] = (int)(*hn - '0'); - else - ov[ovx] = (ov[ovx] * 10) + (int)(*hn - '0'); } else { - - /* - * A non-address character has been detected. - */ - return ((char *)NULL); + if (lsof_select_uid(ctx, uid, excl)) { + Error(ctx); + return (1); + } } - hn++; - } - /* - * Make sure there were three dots and four non-null octets. - */ - if ((dc != 3) || (ovx != (MIN_AF_ADDR - 1)) || (ov[ovx] < 0) || - (ov[ovx] > 255)) - return ((char *)NULL); - /* - * Copy the octets as unsigned characters and return the ending host name - * character position. - */ - for (i = 0; i < MIN_AF_ADDR; i++) { - a[i] = (unsigned char)ov[i]; - } - return (hn); -} - -/* - * lkup_hostnm() - look up host name - */ - -static struct hostent * -lkup_hostnm(char *hn, /* host name */ - struct nwad *n) /* network address destination */ -{ - unsigned char *ap; - struct hostent *he; - int ln; - /* - * Get hostname structure pointer. Return NULL if there is none. - */ - -#if defined(HASIPv6) - he = gethostbyname2(hn, n->af); -#else /* !defined(HASIPv6) */ - he = gethostbyname(hn); -#endif /* defined(HASIPv6) */ - - if (!he || !he->h_addr) - return (he); - /* - * Copy first hostname structure address to destination structure. - */ - -#if defined(HASIPv6) - if (n->af != he->h_addrtype) - return ((struct hostent *)NULL); - if (n->af == AF_INET6) { - - /* - * Copy an AF_INET6 address. - */ - if (he->h_length > MAX_AF_ADDR) - return ((struct hostent *)NULL); - (void)memcpy((void *)&n->a[0], (void *)he->h_addr, he->h_length); - if ((ln = MAX_AF_ADDR - he->h_length) > 0) - zeromem((char *)&n->a[he->h_length], ln); - return (he); } -#endif /* defined(HASIPv6) */ - - /* - * Copy an AF_INET address. - */ - if (he->h_length != 4) - return ((struct hostent *)NULL); - ap = (unsigned char *)he->h_addr; - n->a[0] = *ap++; - n->a[1] = *ap++; - n->a[2] = *ap++; - n->a[3] = *ap; - if ((ln = MAX_AF_ADDR - 4) > 0) - zeromem((char *)&n->a[4], ln); - return (he); + return (err); } diff --git a/src/cli.h b/src/cli.h index 8c9dfdd3..d751718a 100644 --- a/src/cli.h +++ b/src/cli.h @@ -34,4 +34,59 @@ # include "lsof.h" # include "proto.h" +/* Global ctx in cli */ +extern struct lsof_context *ctx; + +struct fieldsel { + char id; /* field ID character */ + unsigned char st; /* field status */ + char *nm; /* field name */ + int *opt; /* option variable address */ + int ov; /* value to OR with option variable */ +}; +extern struct fieldsel FieldSel[]; + +# define LSOF_SEARCH_FAILURE \ + (FsearchErr ? LSOF_EXIT_ERROR : LSOF_EXIT_SUCCESS) + +extern int CmdLim; + +extern int Fcntx; +extern int Ffield; +extern int Ffilesys; +extern int Fhelp; +extern int Fhuman; +extern int Fhost; +extern int Fnlink; +extern int Foffset; +extern int Fpgid; +extern int Fppid; +extern int Fport; +extern int FsearchErr; +extern int Fsv; +extern int FsvByf; +extern int FsvFlagX; +extern int Fsize; +extern int Fterse; +extern int Ftcptpi; +extern int Futol; +extern int Fverbose; +extern int Fxover; +extern int Fzone; + +extern int CntxStatus; + +extern char Terminator; + +extern int RptTm; +extern int RptMaxCount; + +extern int OffDecDig; + +# if !defined(HASNORPC_H) +extern int FportMap; +# endif /* !defined(HASNORPC_H) */ + +extern void print_tcptpi(struct lsof_context *ctx, int nl); + #endif \ No newline at end of file diff --git a/src/dialects/darwin/dprint.c b/src/dialects/darwin/dprint.c index e69de29b..24a006c4 100644 --- a/src/dialects/darwin/dprint.c +++ b/src/dialects/darwin/dprint.c @@ -0,0 +1,109 @@ +/* + * dprint.c - Darwin printing functions for libproc-based lsof + */ + +/* + * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by Victor A. Abell + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "common.h" +#include "cli.h" + +#if defined(PROC_FP_GUARDED) +/* + * Pgf_tab[] - table for print process open file guard flags + */ + +struct pff_tab Pgf_tab[] = {{(long)PROC_FI_GUARD_CLOSE, "CLOSE"}, + {(long)PROC_FI_GUARD_DUP, "DUP"}, + {(long)PROC_FI_GUARD_SOCKET_IPC, "SOCKET"}, + {(long)PROC_FI_GUARD_FILEPORT, "FILEPORT"}, + + {(long)0, NULL}}; +#endif /* defined(PROC_FP_GUARDED) */ + +/* + * print_nm() -- print Name column + */ +void print_nm(lf) struct lfile *lf; +{ + unsigned char extra = 0; + + printname(0); + +#if defined(PROC_PIDLISTFILEPORTS) + if (lf->fileport) + extra++; +#endif /* defined(PROC_PIDLISTFILEPORTS) */ + +#if defined(PROC_FP_GUARDED) + if (lf->guardflags) + extra++; +#endif /* defined(PROC_FP_GUARDED) */ + + if (extra) + (void)printf(" ("); + +#if defined(PROC_PIDLISTFILEPORTS) + if (lf->fileport) + (void)printf("fileport=0x%04x", lf->fileport); +#endif /* defined(PROC_PIDLISTFILEPORTS) */ + +#if defined(PROC_FP_GUARDED) + if (extra > 1) + putchar(','); + if (lf->guardflags) { + struct pff_tab *tp; + long gf; + + (void)printf("guard="); + tp = Pgf_tab; + gf = lf->guardflags; + while (gf && !FsvFlagX) { + while (tp->nm) { + if (gf & tp->val) + break; + tp++; + } + if (!tp->nm) + break; + gf &= ~(tp->val); + (void)printf("%s%s", tp->nm, gf ? "," : ""); + } + /* + * If flag bits remain, print them in hex. If hex output was + * specified with +fG, print all flag values, including zero, + * in hex. + */ + if (gf || FsvFlagX) + (void)printf("0x%lx", gf); + } +#endif /* defined(PROC_FP_GUARDED) */ + + if (extra) + (void)printf(")\n"); + else + putchar('\n'); +} \ No newline at end of file diff --git a/src/dialects/linux/dprint.c b/src/dialects/linux/dprint.c index e69de29b..48c81df1 100644 --- a/src/dialects/linux/dprint.c +++ b/src/dialects/linux/dprint.c @@ -0,0 +1,198 @@ +/* + * dprint.c - Linux printing functions for /proc-based lsof + */ + +/* + * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by Victor A. Abell + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "common.h" +#include "cli.h" + +#if defined(HASSOSTATE) +# include /* for SS_* */ +#endif /* defined(HASSOSTATE) */ + +#if defined(HASSOSTATE) +static char *socket_state_to_str (struct lsof_context * ctx, unsigned int ss); +#endif /* defined(HASSOSTATE) */ + +/* + * print_unix() - print state of UNIX domain socket e.g. UNCONNECTED + */ +static void print_unix(struct lsof_context *ctx, int nl) { + if (Ftcptpi & TCPTPI_STATE) { +#if defined(HASSOSTATE) && defined(HASSOOPT) + char *cp = (Lf->lts.opt == __SO_ACCEPTCON) + ? "LISTEN" + : socket_state_to_str(ctx, Lf->lts.ss); + + if (Ffield) + (void)printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator); + else { + putchar('('); + (void)fputs(cp, stdout); + putchar(')'); + } +#endif /* defined(HASSOSTATE) && defined(HASSOOPT) */ + } + if (nl) + putchar('\n'); +} + +/* + * print_tcptpi() - print TCP/TPI state e.g. ESTBALISHED + */ +void print_tcptpi(struct lsof_context *ctx, int nl) /* 1 == '\n' required */ +{ + char buf[128]; + char *cp = (char *)NULL; + int ps = 0; + int s; + + if (Lf->type == LSOF_FILE_UNIX) { + print_unix(ctx, nl); + return; + } + if ((Ftcptpi & TCPTPI_STATE) && Lf->lts.type == 0) { + if (!TcpSt) + (void)build_IPstates(ctx); + if ((s = Lf->lts.state.i + TcpStOff) < 0 || s >= TcpNstates) { + (void)snpf(buf, sizeof(buf), "UNKNOWN_TCP_STATE_%d", + Lf->lts.state.i); + cp = buf; + } else + cp = TcpSt[s]; + if (cp) { + if (Ffield) + (void)printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator); + else { + putchar('('); + (void)fputs(cp, stdout); + } + ps++; + } + } + +#if defined(HASTCPTPIQ) + if (Ftcptpi & TCPTPI_QUEUES) { + if (Lf->lts.rqs) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("QR=%lu", Lf->lts.rq); + if (Ffield) + putchar(Terminator); + ps++; + } + if (Lf->lts.sqs) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("QS=%lu", Lf->lts.sq); + if (Ffield) + putchar(Terminator); + ps++; + } + } +#endif /* defined(HASTCPTPIQ) */ + +#if defined(HASTCPTPIW) + if (Ftcptpi & TCPTPI_WINDOWS) { + if (Lf->lts.rws) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("WR=%lu", Lf->lts.rw); + if (Ffield) + putchar(Terminator); + ps++; + } + if (Lf->lts.wws) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("WW=%lu", Lf->lts.ww); + if (Ffield) + putchar(Terminator); + ps++; + } + } +#endif /* defined(HASTCPTPIW) */ + + if (!Ffield && ps) + putchar(')'); + if (nl) + putchar('\n'); +} + +#if defined(HASSOSTATE) +/* + * socket_state_to_str() -- convert socket state number to a string + * + * returns "UNKNOWN" for unknown state. + */ +static char *socket_state_to_str(struct lsof_context *ctx, unsigned int ss) { + char *sr; + switch (Lf->lts.ss) { + case SS_UNCONNECTED: + sr = "UNCONNECTED"; + break; + case SS_CONNECTING: + sr = "CONNECTING"; + break; + case SS_CONNECTED: + sr = "CONNECTED"; + break; + case SS_DISCONNECTING: + sr = "DISCONNECTING"; + break; + default: + sr = "UNKNOWN"; + break; + } + return sr; +} +#endif /* defined(HASSOSTATE) */ \ No newline at end of file diff --git a/src/dialects/sun/dprint.c b/src/dialects/sun/dprint.c new file mode 100644 index 00000000..24b896f8 --- /dev/null +++ b/src/dialects/sun/dprint.c @@ -0,0 +1,347 @@ +/* + * dprint.c - Solaris printing functions for lsof + */ + +/* + * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by Victor A. Abell + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "common.h" +#include "cli.h" + +/* + * print_tcptpi() - print TCP/TPI info + */ + +void print_tcptpi(struct lsof_context *ctx, int nl) /* 1 == '\n' required */ +{ + char *cp = (char *)NULL; + char sbuf[128]; + int i; + int ps = 0; + unsigned int u; + + if (Ftcptpi & TCPTPI_STATE) { + switch (Lf->lts.type) { + case 0: /* TCP */ + if (!TcpSt) + (void)build_IPstates(ctx); + if ((i = Lf->lts.state.i + TcpStOff) < 0 || i >= TcpNstates) { + (void)snpf(sbuf, sizeof(sbuf), "UNKNOWN_TCP_STATE_%d", + Lf->lts.state.i); + cp = sbuf; + } else + cp = TcpSt[i]; + break; + case 1: /* TPI */ + if (!UdpSt) + (void)build_IPstates(ctx); + if ((u = Lf->lts.state.ui + UdpStOff) < 0 || u >= UdpNstates) { + (void)snpf(sbuf, sizeof(sbuf), "UNKNOWN_UDP_STATE_%u", + Lf->lts.state.ui); + cp = sbuf; + } else + cp = UdpSt[u]; + } + if (cp) { + if (Ffield) + (void)printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator); + else { + putchar('('); + (void)fputs(cp, stdout); + } + ps++; + } + } + +#if defined(HASTCPTPIQ) + if (Ftcptpi & TCPTPI_QUEUES) { + if (Lf->lts.rqs) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("QR=%lu", Lf->lts.rq); + if (Ffield) + putchar(Terminator); + ps++; + } + if (Lf->lts.sqs) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("QS=%lu", Lf->lts.sq); + if (Ffield) + putchar(Terminator); + ps++; + } + } +#endif /* defined(HASTCPTPIQ) */ + +#if defined(HASSOOPT) + if (Ftcptpi & TCPTPI_FLAGS) { + int opt; + + if ((opt = Lf->lts.opt) || Lf->lts.pqlens || Lf->lts.qlens || + Lf->lts.qlims || Lf->lts.rbszs || Lf->lts.sbsz) { + char sep = ' '; + + if (Ffield) + sep = LSOF_FID_TCPTPI; + else if (!ps) + sep = '('; + (void)printf("%cSO", sep); + ps++; + sep = '='; + +# if defined(SO_BROADCAST) + if (opt & SO_BROADCAST) { + (void)printf("%cBROADCAST", sep); + opt &= ~SO_BROADCAST; + sep = ','; + } +# endif /* defined(SO_BROADCAST) */ + +# if defined(SO_DEBUG) + if (opt & SO_DEBUG) { + (void)printf("%cDEBUG", sep); + opt &= ~SO_DEBUG; + sep = ','; + } +# endif /* defined(SO_DEBUG) */ + +# if defined(SO_DGRAM_ERRIND) + if (opt & SO_DGRAM_ERRIND) { + (void)printf("%cDGRAM_ERRIND", sep); + opt &= ~SO_DGRAM_ERRIND; + sep = ','; + } +# endif /* defined(SO_DGRAM_ERRIND) */ + +# if defined(SO_DONTROUTE) + if (opt & SO_DONTROUTE) { + (void)printf("%cDONTROUTE", sep); + opt &= ~SO_DONTROUTE; + sep = ','; + } +# endif /* defined(SO_DONTROUTE) */ + +# if defined(SO_KEEPALIVE) + if (opt & SO_KEEPALIVE) { + (void)printf("%cKEEPALIVE", sep); + if (Lf->lts.kai) + (void)printf("=%d", Lf->lts.kai); + opt &= ~SO_KEEPALIVE; + sep = ','; + } +# endif /* defined(SO_KEEPALIVE) */ + +# if defined(SO_LINGER) + if (opt & SO_LINGER) { + (void)printf("%cLINGER", sep); + if (Lf->lts.ltm) + (void)printf("=%d", Lf->lts.ltm); + opt &= ~SO_LINGER; + sep = ','; + } +# endif /* defined(SO_LINGER) */ + +# if defined(SO_OOBINLINE) + if (opt & SO_OOBINLINE) { + (void)printf("%cOOBINLINE", sep); + opt &= ~SO_OOBINLINE; + sep = ','; + } +# endif /* defined(SO_OOBINLINE) */ + + if (Lf->lts.pqlens) { + (void)printf("%cPQLEN=%u", sep, Lf->lts.pqlen); + sep = ','; + } + if (Lf->lts.qlens) { + (void)printf("%cQLEN=%u", sep, Lf->lts.qlen); + sep = ','; + } + if (Lf->lts.qlims) { + (void)printf("%cQLIM=%u", sep, Lf->lts.qlim); + sep = ','; + } + if (Lf->lts.rbszs) { + (void)printf("%cRCVBUF=%lu", sep, Lf->lts.rbsz); + sep = ','; + } + +# if defined(SO_REUSEADDR) + if (opt & SO_REUSEADDR) { + (void)printf("%cREUSEADDR", sep); + opt &= ~SO_REUSEADDR; + sep = ','; + } +# endif /* defined(SO_REUSEADDR) */ + + if (Lf->lts.sbszs) { + (void)printf("%cSNDBUF=%lu", sep, Lf->lts.sbsz); + sep = ','; + } + +# if defined(SO_TIMESTAMP) + if (opt & SO_TIMESTAMP) { + (void)printf("%cTIMESTAMP", sep); + opt &= ~SO_TIMESTAMP; + sep = ','; + } +# endif /* defined(SO_TIMESTAMP) */ + +# if defined(SO_USELOOPBACK) + if (opt & SO_USELOOPBACK) { + (void)printf("%cUSELOOPBACK", sep); + opt &= ~SO_USELOOPBACK; + sep = ','; + } +# endif /* defined(SO_USELOOPBACK) */ + + if (opt) + (void)printf("%cUNKNOWN=%#x", sep, opt); + if (Ffield) + putchar(Terminator); + } + } +#endif /* defined(HASSOOPT) */ + +#if defined(HASTCPOPT) + if (Ftcptpi & TCPTPI_FLAGS) { + int topt; + + if ((topt = Lf->lts.topt) || Lf->lts.msss) { + char sep = ' '; + + if (Ffield) + sep = LSOF_FID_TCPTPI; + else if (!ps) + sep = '('; + (void)printf("%cTF", sep); + ps++; + sep = '='; + +# if defined(TF_ACKNOW) + if (topt & TF_ACKNOW) { + (void)printf("%cACKNOW", sep); + topt &= ~TF_ACKNOW; + sep = ','; + } +# endif /* defined(TF_ACKNOW) */ + +# if defined(TF_DELACK) + if (topt & TF_DELACK) { + (void)printf("%cDELACK", sep); + topt &= ~TF_DELACK; + sep = ','; + } +# endif /* defined(TF_DELACK) */ + + if (Lf->lts.msss) { + (void)printf("%cMSS=%lu", sep, Lf->lts.mss); + sep = ','; + } + +# if defined(TF_NODELAY) + if (topt & TF_NODELAY) { + (void)printf("%cNODELAY", sep); + topt &= ~TF_NODELAY; + sep = ','; + } +# endif /* defined(TF_NODELAY) */ + +# if defined(TF_NOOPT) + if (topt & TF_NOOPT) { + (void)printf("%cNOOPT", sep); + topt &= ~TF_NOOPT; + sep = ','; + } +# endif /* defined(TF_NOOPT) */ + +# if defined(TF_SENTFIN) + if (topt & TF_SENTFIN) { + (void)printf("%cSENTFIN", sep); + topt &= ~TF_SENTFIN; + sep = ','; + } +# endif /* defined(TF_SENTFIN) */ + + if (topt) + (void)printf("%cUNKNOWN=%#x", sep, topt); + if (Ffield) + putchar(Terminator); + } + } +#endif /* defined(HASTCPOPT) */ + +#if defined(HASTCPTPIW) + if (Ftcptpi & TCPTPI_WINDOWS) { + if (Lf->lts.rws) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("WR=%lu", Lf->lts.rw); + if (Ffield) + putchar(Terminator); + ps++; + } + if (Lf->lts.wws) { + if (Ffield) + putchar(LSOF_FID_TCPTPI); + else { + if (ps) + putchar(' '); + else + putchar('('); + } + (void)printf("WW=%lu", Lf->lts.ww); + if (Ffield) + putchar(Terminator); + ps++; + } + } +#endif /* defined(HASTCPTPIW) */ + + if (Ftcptpi && !Ffield && ps) + putchar(')'); + if (nl) + putchar('\n'); +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 58454f8e..00707469 100644 --- a/src/main.c +++ b/src/main.c @@ -31,8 +31,11 @@ */ #include "common.h" +#include "lsof.h" #include "cli.h" +extern int enter_dir(char *d, int descend); + /* * Local definitions */ @@ -44,7 +47,6 @@ static int GOx1 = 1; /* first opt[][] index */ static int GOx2 = 0; /* second opt[][] index */ static int GetOpt(int ct, char *opt[], char *rules, int *err); -static char *sv_fmt_str(struct lsof_context *ctx, char *f); /* * main() - main function for lsof @@ -56,7 +58,7 @@ int main(int argc, char *argv[]) { int ad, c, i, n, se1, se2, ss; char *cp; int err = 0; - enum ExitStatus ev = LSOF_SUCCESS; + enum ExitStatus ev = LSOF_EXIT_SUCCESS; int fh = 0; char *fmtr = (char *)NULL; long l; @@ -73,8 +75,9 @@ int main(int argc, char *argv[]) { int version = 0; int xover = 0; int pr_count = 0; - /** liblsof context */ - struct lsof_context *ctx = NULL; + + int err_stat = 0; /* path stat() error count */ + int good_name = 0; /* success names argument */ #if defined(HAS_STRFTIME) char *fmt = (char *)NULL; @@ -95,13 +98,19 @@ int main(int argc, char *argv[]) { CntxStatus = is_selinux_enabled() ? 1 : 0; #endif /* defined(HASSELINUX) */ + /* Initialize lsof context */ + ctx = lsof_new(); + lsof_exit_on_fatal(ctx, 1); + /* - * Save program name. + * Save program name and set output stream */ if ((Pn = strrchr(argv[0], '/'))) Pn++; else Pn = argv[0]; + lsof_output_stream(ctx, stderr, Pn, 0); + /* * Close enough file descriptors above 2 that library functions will have * open descriptors. @@ -115,7 +124,7 @@ int main(int argc, char *argv[]) { if ((MaxFd = (int)GET_MAX_FD()) < 53) MaxFd = 53; - closefrom_shim(3); + closefrom_shim(ctx, 3); while (((i = open("/dev/null", O_RDWR, 0)) >= 0) && (i < 2)) ; @@ -135,17 +144,11 @@ int main(int argc, char *argv[]) { /* * Common initialization. */ - Mypid = getpid(); if ((Mygid = (gid_t)getgid()) != getegid()) Setgid = 1; Euid = geteuid(); if ((Myuid = (uid_t)getuid()) && !Euid) Setuidroot = 1; - if (!(Namech = (char *)malloc(MAXPATHLEN + 1))) { - (void)fprintf(stderr, "%s: no space for name buffer\n", Pn); - Error(ctx); - } - Namechl = (size_t)(MAXPATHLEN + 1); /* * Create option mask. */ @@ -240,7 +243,7 @@ int main(int argc, char *argv[]) { } switch (c) { case 'a': - Fand = 1; + lsof_logic_and(ctx); break; #if defined(HAS_AFS) && defined(HASAOPT) @@ -258,7 +261,7 @@ int main(int argc, char *argv[]) { #endif /* defined(HAS_AFS) && defined(HASAOPT) */ case 'b': - Fblock = 1; + lsof_avoid_blocking(ctx, 1); break; case 'c': if (GOp == '+') { @@ -286,57 +289,43 @@ int main(int argc, char *argv[]) { break; } if (GOv && (*GOv == '/')) { - if (enter_cmd_rx(ctx, GOv)) + if (lsof_select_process_regex(ctx, GOv)) err = 1; } else { - if (enter_str_lst("-c", GOv, &Cmdl, &Cmdni, &Cmdnx)) + if (enter_cmd("-c", GOv)) err = 1; - -#if defined(MAXSYSCMDL) - else if (Cmdl->len > MAXSYSCMDL) { - (void)fprintf(stderr, "%s: \"-c ", Pn); - (void)safestrprt(Cmdl->str, stderr, 2); - (void)fprintf(stderr, "\" length (%d) > what system", - Cmdl->len); - (void)fprintf(stderr, " provides (%d)\n", MAXSYSCMDL); - Cmdl->len = 0; /* (to avoid later error report) */ - err = 1; - } -#endif /* defined(MAXSYSCMDL) */ } break; #if defined(HASNCACHE) case 'C': - Fncache = (GOp == '-') ? 0 : 1; + lsof_use_name_cache(ctx, (GOp == '-') ? 0 : 1); break; #endif /* defined(HASNCACHE) */ case 'd': if (GOp == '+') { - if (enter_dir(ctx, GOv, 0)) + if (enter_dir(GOv, 0)) err = 1; else { - Selflags |= SELNM; xover = 1; } } else { - if (enter_fd(ctx, GOv)) + if (enter_fd(GOv)) err = 1; } break; case 'D': if (GOp == '+') { - if (enter_dir(ctx, GOv, 1)) + if (enter_dir(GOv, 1)) err = 1; else { - Selflags |= SELNM; xover = 1; } } else { #if defined(HASDCACHE) - if (ctrl_dcache(ctx, GOv)) + if (ctrl_dcache(GOv)) err = 1; #else /* !defined(HASDCACHE) */ (void)fprintf(stderr, "%s: unsupported option: -D\n", Pn); @@ -347,7 +336,7 @@ int main(int argc, char *argv[]) { #if defined(HASEOPT) case 'e': - if (enter_efsys(ctx, GOv, ((GOp == '+') ? 1 : 0))) + if (lsof_exempt_fs(ctx, GOv, ((GOp == '+') ? 1 : 0))) err = 1; break; #endif /* defined(HASEOPT) */ @@ -555,7 +544,7 @@ int main(int argc, char *argv[]) { if (*GOv == '-' || *GOv == '+') { GOx1 = GObk[0]; GOx2 = GObk[1]; - } else if (enter_id(ctx, PGID, GOv)) + } else if (enter_id(PGID, GOv)) err = 1; } Fpgid = 1; @@ -569,15 +558,14 @@ int main(int argc, char *argv[]) { break; case 'i': if (!GOv || *GOv == '-' || *GOv == '+') { - Fnet = 1; - FnetTy = 0; + lsof_select_ip(ctx, AF_UNSPEC); if (GOv) { GOx1 = GObk[0]; GOx2 = GObk[1]; } break; } - if (enter_network_address(ctx, GOv)) + if (lsof_select_inet_string(ctx, GOv)) err = 1; break; @@ -598,18 +586,14 @@ int main(int argc, char *argv[]) { #if defined(HASTASKS) case 'K': if (!GOv || *GOv == '-' || *GOv == '+') { - Ftask = 1; - IgnTasks = 0; - Selflags |= SELTASK; + lsof_select_task(ctx, 1); if (GOv) { GOx1 = GObk[0]; GOx2 = GObk[1]; } } else { if (!strcasecmp(GOv, "i")) { - Ftask = 0; - IgnTasks = 1; - Selflags &= ~SELTASK; + lsof_select_task(ctx, 0); } else { (void)fprintf(stderr, "%s: -K not followed by i (but by %s)\n", Pn, @@ -626,7 +610,7 @@ int main(int argc, char *argv[]) { case 'L': Fnlink = (GOp == '+') ? 1 : 0; if (!GOv || *GOv == '-' || *GOv == '+') { - Nlink = 0l; + lsof_select_num_links(ctx, 0); if (GOv) { GOx1 = GObk[0]; GOx2 = GObk[1]; @@ -644,11 +628,10 @@ int main(int argc, char *argv[]) { (void)fprintf(stderr, "%s: no number may follow -L\n", Pn); err = 1; } else { - Nlink = l; - Selflags |= SELNLINK; + lsof_select_num_links(ctx, l); } } else - Nlink = 0l; + lsof_select_num_links(ctx, 0); if (*cp) { GOx1 = GObk[0]; GOx2 = GObk[1] + n; @@ -709,7 +692,7 @@ int main(int argc, char *argv[]) { Fhost = (GOp == '-') ? 0 : 1; break; case 'N': - Fnfs = 1; + lsof_select_nfs(ctx); break; case 'o': if (!GOv || *GOv == '-' || *GOv == '+') { @@ -736,10 +719,10 @@ int main(int argc, char *argv[]) { } break; case 'O': - Fovhd = (GOp == '-') ? 1 : 0; + lsof_avoid_forking(ctx, (GOp == '-') ? 1 : 0); break; case 'p': - if (enter_id(ctx, PID, GOv)) + if (enter_id(PID, GOv)) err = 1; break; case 'Q': @@ -750,7 +733,7 @@ int main(int argc, char *argv[]) { break; case 'r': if (GOp == '+') { - ev = LSOF_ERROR; + ev = LSOF_EXIT_ERROR; rc = 1; } if (!GOv || *GOv == '-' || *GOv == '+') { @@ -837,7 +820,7 @@ int main(int argc, char *argv[]) { GOx2 = GObk[1]; } } else { - if (enter_state_spec(ctx, GOv)) + if (enter_state_spec(GOv)) err = 1; } #else /* !defined(HASTCPUDPSTATE) */ @@ -921,11 +904,11 @@ int main(int argc, char *argv[]) { } break; case 'u': - if (enter_uid(ctx, GOv)) + if (enter_uid(GOv)) err = 1; break; case 'U': - Funix = 1; + lsof_select_unix_socket(ctx); break; case 'v': version = 1; @@ -977,7 +960,7 @@ int main(int argc, char *argv[]) { /* * Add to the zone name argument hash. */ - if (enter_zone_arg(ctx, GOv)) + if (lsof_select_solaris_zone(ctx, GOv)) err = 1; } else if (GOv) { GOx1 = GObk[0]; @@ -998,7 +981,7 @@ int main(int argc, char *argv[]) { /* * Add to the context name argument hash. */ - if (enter_cntx_arg(ctx, GOv)) + if (lsof_select_selinux_context(ctx, GOv)) err = 1; } else if (GOv) { GOx1 = GObk[0]; @@ -1013,65 +996,9 @@ int main(int argc, char *argv[]) { err = 1; } } - /* - * If IgnTasks is set, remove SELTASK from SelAll and SelProc. - */ - SelAll = IgnTasks ? (SELALL & ~SELTASK) : SELALL; - SelProc = IgnTasks ? (SELPROC & ~SELTASK) : SELPROC; /* * Check for argument consistency. */ - if (Cmdnx && Cmdni) { - - /* - * Check for command inclusion/exclusion conflicts. - */ - for (str = Cmdl; str; str = str->next) { - if (str->x) { - for (strt = Cmdl; strt; strt = strt->next) { - if (!strt->x) { - if (!strcmp(str->str, strt->str)) { - (void)fprintf(stderr, - "%s: -c^%s and -c%s conflict.\n", Pn, - str->str, strt->str); - err++; - } - } - } - } - } - } - -#if defined(HASTCPUDPSTATE) - if (TcpStXn && TcpStIn) { - - /* - * Check for excluded and included TCP states. - */ - for (i = 0; i < TcpNstates; i++) { - if (TcpStX[i] && TcpStI[i]) { - (void)fprintf(stderr, - "%s: can't include and exclude TCP state: %s\n", - Pn, TcpSt[i]); - err = 1; - } - } - } - if (UdpStXn && UdpStIn) { - - /* - * Check for excluded and included UDP states. - */ - for (i = 0; i < UdpNstates; i++) { - if (UdpStX[i] && UdpStI[i]) { - (void)fprintf(stderr, - "%s: can't include and exclude UDP state: %s\n", - Pn, UdpSt[i]); - err = 1; - } - } - } -#endif /* defined(HASTCPUDPSTATE) */ if (Fsize && Foffset) { (void)fprintf(stderr, "%s: -o and -s are mutually exclusive\n", Pn); @@ -1109,134 +1036,32 @@ int main(int argc, char *argv[]) { err++; } -#if defined(HASEOPT) - if (Efsysl) { - - /* - * If there are file systems specified by -e options, check them. - */ - efsys_list_t *ep; /* Efsysl pointer */ - struct mounts *mp, *mpw; /* local mount table pointers */ - - if ((mp = readmnt(ctx))) { - for (ep = Efsysl; ep; ep = ep->next) { - for (mpw = mp; mpw; mpw = mpw->next) { - if (!strcmp(mpw->dir, ep->path)) { - ep->mp = mpw; - break; - } - } - if (!ep->mp) { - (void)fprintf( - stderr, "%s: \"-e %s\" is not a mounted file system.\n", - Pn, ep->path); - err++; - } - } - } - } -#endif /* defined(HASEOPT) */ - if (DChelp || err || Fhelp || fh || version) - usage(ctx, err ? 1 : 0, fh, version); - /* - * Reduce the size of Suid[], if necessary. - */ - if (Suid && Nuid && Nuid < Mxuid) { - if (!(Suid = (struct seluid *)realloc( - (MALLOC_P *)Suid, - (MALLOC_S)(sizeof(struct seluid) * Nuid)))) { - (void)fprintf(stderr, "%s: can't realloc UID table\n", Pn); - Error(ctx); - } - Mxuid = Nuid; - } - /* - * Compute the selection flags. - */ - if ((Cmdl && Cmdni) || CmdRx) - Selflags |= SELCMD; - -#if defined(HASSELINUX) - if (CntxArg) - Selflags |= SELCNTX; -#endif /* defined(HASSELINUX) */ - - if (Fdl) - Selflags |= SELFD; - if (Fnet) - Selflags |= SELNET; - if (Fnfs) - Selflags |= SELNFS; - if (Funix) - Selflags |= SELUNX; - if (Npgid && Npgidi) - Selflags |= SELPGID; - if (Npid && Npidi) - Selflags |= SELPID; - if (Nuid && Nuidincl) - Selflags |= SELUID; - if (Nwad) - Selflags |= SELNA; + usage(err ? 1 : 0, fh, version); -#if defined(HASZONES) - if (ZoneArg) - Selflags |= SELZONE; -#endif /* defined(HASZONES) */ - - if (GOx1 < argc) - Selflags |= SELNM; - if (Selflags == 0) { - if (Fand) { - (void)fprintf(stderr, "%s: no select options to AND via -a\n", Pn); - usage(ctx, 1, 0, 0); - } - Selflags = SelAll; - } else { - if (GOx1 >= argc && (Selflags & (SELNA | SELNET)) != 0 && - (Selflags & ~(SELNA | SELNET)) == 0) - Selinet = 1; - AllProc = 0; + if (Selflags == 0 && Fand) { + (void)fprintf(stderr, "%s: no select options to AND via -a\n", Pn); + usage(1, 0, 0); } - /* - * Get the device for DEVDEV_PATH. - */ - if (stat(DEVDEV_PATH, &sb)) { - se1 = errno; - if ((ad = strcmp(DEVDEV_PATH, "/dev"))) { - if ((ss = stat("/dev", &sb))) - se2 = errno; - else - se2 = 0; - } else { - se2 = 0; - ss = 1; - } - if (ss) { - (void)fprintf(stderr, "%s: can't stat(%s): %s\n", Pn, DEVDEV_PATH, - strerror(se1)); - if (ad) { - (void)fprintf(stderr, "%s: can't stat(/dev): %s\n", Pn, - strerror(se2)); - } - Error(ctx); - } - } - DevDev = sb.st_dev; + /* * Process the file arguments. */ if (GOx1 < argc) { - if (ck_file_arg(ctx, GOx1, argc, argv, Ffilesys, 0, (struct stat *)NULL, - FsearchErr == 0)) + for (i = GOx1; i < argc; i++) { + if (ck_file_arg(ctx, argv[i], Ffilesys, 0, (struct stat *)NULL, + FsearchErr == 0)) { + err_stat += 1; + } else { + good_name += 1; + } + } + if (good_name == 0) { Error(ctx); + } } - /* - * Do dialect-specific initialization. - */ - initialize(ctx); - if (Sfile) - (void)hashSfile(ctx); + /* Freeze context as all args are handled */ + lsof_freeze(ctx); #if defined(WILLDROPGID) /* @@ -1257,18 +1082,10 @@ int main(int argc, char *argv[]) { /* * Define the size and offset print formats. */ - (void)snpf(options, sizeof(options), "%%%su", INODEPSPEC); - InodeFmt_d = sv_fmt_str(ctx, options); - (void)snpf(options, sizeof(options), "%%#%sx", INODEPSPEC); - InodeFmt_x = sv_fmt_str(ctx, options); - (void)snpf(options, sizeof(options), "0t%%%su", SZOFFPSPEC); - SzOffFmt_0t = sv_fmt_str(ctx, options); - (void)snpf(options, sizeof(options), "%%%su", SZOFFPSPEC); - SzOffFmt_d = sv_fmt_str(ctx, options); - (void)snpf(options, sizeof(options), "%%*%su", SZOFFPSPEC); - SzOffFmt_dv = sv_fmt_str(ctx, options); - (void)snpf(options, sizeof(options), "%%#%sx", SZOFFPSPEC); - SzOffFmt_x = sv_fmt_str(ctx, options); + SzOffFmt_0t = "0t%" SZOFFPSPEC "u"; + SzOffFmt_d = "%" SZOFFPSPEC "u"; + SzOffFmt_dv = "%*" SZOFFPSPEC "u"; + SzOffFmt_x = "%#" SZOFFPSPEC "x"; #if defined(HASMNTSUP) /* @@ -1276,7 +1093,7 @@ int main(int argc, char *argv[]) { */ if (MntSup == 1) { (void)readmnt(ctx); - Exit(ctx, LSOF_SUCCESS); + Exit(ctx, LSOF_EXIT_SUCCESS); } #endif /* defined(HASMNTSUP) */ @@ -1303,9 +1120,11 @@ int main(int argc, char *argv[]) { else slp = (struct lproc **)realloc((MALLOC_P *)slp, len); if (!slp) { - (void)fprintf(stderr, "%s: no space for %d sort pointers\n", - Pn, Nlproc); + (void)fprintf(stderr, + "%s: no space for %zu sort pointers\n", Pn, + Nlproc); Error(ctx); + return 1; } } for (i = 0; i < Nlproc; i++) { @@ -1323,133 +1142,6 @@ int main(int argc, char *argv[]) { NcacheReload = 1; #endif /* defined(HASNCACHE) */ -#if defined(HASEPTOPTS) - /* - * If endpoint info has been requested, make sure it is coded for - * printing. - * - * Lf contents must be preserved, since they may point to a - * malloc()'d area, and since Lf is used throughout the printing - * of the selected processes. - */ - if (FeptE) { - lf = Lf; - /* - * Scan all selected processes. - */ - for (i = 0; i < Nlproc; i++) { - Lp = (Nlproc > 1) ? slp[i] : &Lproc[i]; - - /* - * For processes that have been selected for printing - * and have files that are the end point(s) of pipe(s), - * process the file endpoints. - */ - if (Lp->pss && (Lp->ept & EPT_PIPE)) - (void)process_pinfo(ctx, 0); - /* - * Process POSIX MQ endpoints. - */ - if (Lp->ept & EPT_PSXMQ) - (void)process_psxmqinfo(ctx, 0); - -# if defined(HASUXSOCKEPT) - /* - * For processes that have been selected for printing - * and have files that are the end point(s) of UNIX - * socket(s), process the file endpoints. - */ - if (Lp->pss && (Lp->ept & EPT_UXS)) - (void)process_uxsinfo(ctx, 0); -# endif /* defined(HASUXSOCKEPT) */ - -# if defined(HASPTYEPT) - /* - * For processes that have been selected for printing - * and have files that are the end point(s) of pseudo- - * terminal files(s), process the file endpoints. - */ - if (Lp->pss && (Lp->ept & EPT_PTY)) - (void)process_ptyinfo(ctx, 0); -# endif /* defined(HASPTYEPT) */ - - /* - * Process INET socket endpoints. - */ - if (Lp->ept & EPT_NETS) - (void)process_netsinfo(ctx, 0); - -# if defined(HASIPv6) - /* - * Process INET6 socket endpoints. - */ - if (Lp->ept & EPT_NETS6) - (void)process_nets6info(ctx, 0); -# endif /* defined(HASIPv6) */ - /* - * Process eventfd endpoints. - */ - if (Lp->ept & EPT_EVTFD) - (void)process_evtfdinfo(ctx, 0); - } - /* - * In a second pass, look for unselected endpoint files, - * possibly selecting them for printing. - */ - for (i = 0; i < Nlproc; i++) { - Lp = (Nlproc > 1) ? slp[i] : &Lproc[i]; - - /* - * Process pipe endpoints. - */ - if (Lp->ept & EPT_PIPE_END) - (void)process_pinfo(ctx, 1); - /* - * Process POSIX MQ endpoints. - */ - if (Lp->ept & EPT_PSXMQ_END) - (void)process_psxmqinfo(ctx, 1); - -# if defined(HASUXSOCKEPT) - /* - * Process UNIX socket endpoints. - */ - if (Lp->ept & EPT_UXS_END) - (void)process_uxsinfo(ctx, 1); -# endif /* defined(HASUXSOCKEPT) */ - -# if defined(HASPTYEPT) - /* - * Process pseudo-terminal endpoints. - */ - if (Lp->ept & EPT_PTY_END) - (void)process_ptyinfo(ctx, 1); -# endif /* defined(HASPTYEPT) */ - - /* - * Process INET socket endpoints. - */ - if (Lp->ept & EPT_NETS_END) - (void)process_netsinfo(ctx, 1); - -# if defined(HASIPv6) - /* - * Process INET6 socket endpoints. - */ - if (Lp->ept & EPT_NETS6_END) - (void)process_nets6info(ctx, 1); -# endif /* defined(HASIPv6) */ - - /* - * Process envetfd endpoints. - */ - if (Lp->ept & EPT_EVTFD_END) - (void)process_evtfdinfo(ctx, 1); - } - Lf = lf; - } -#endif /* defined(HASEPTOPTS) */ - /* * Print the selected processes and count them. * @@ -1461,7 +1153,7 @@ int main(int argc, char *argv[]) { for (i = n = 0; i < Nlproc; i++) { Lp = (Nlproc > 1) ? slp[i] : &Lproc[i]; if (Lp->pss) { - if (print_proc(ctx)) + if (print_proc()) n++; } if (RptTm && PrPass) @@ -1476,34 +1168,11 @@ int main(int argc, char *argv[]) { * If conditional repeat mode is in effect, see if it's time to exit. */ if (RptTm) { - -#if defined(HASEPTOPTS) - (void)clear_pinfo(ctx); - - (void)clear_psxmqinfo(ctx); - -# if defined(HASUXSOCKEPT) - (void)clear_uxsinfo(ctx); -# endif /* defined(HASUXSOCKEPT) */ - -# if defined(HASPTYEPT) - (void)clear_ptyinfo(ctx); -# endif /* defined(HASPTYEPT) */ - - (void)clear_netsinfo(ctx); - -# if defined(HASIPv6) - (void)clear_nets6info(ctx); -# endif /* defined(HASIPv6) */ - - (void)clear_evtfdinfo(ctx); -#endif /* defined(HASEPTOPTS) */ - if (rc) { if (!n) break; else - ev = LSOF_SUCCESS; + ev = LSOF_EXIT_SUCCESS; } #if defined(HAS_STRFTIME) @@ -1553,7 +1222,7 @@ int main(int argc, char *argv[]) { * was; one, if not. If -V was specified, report what was not displayed. */ (void)childx(ctx); - rv = LSOF_SUCCESS; + rv = LSOF_EXIT_SUCCESS; for (str = Cmdl; str; str = str->next) { /* @@ -1788,7 +1457,6 @@ int main(int argc, char *argv[]) { Spgid[i].i); } for (i = 0; i < Nuid; i++) { - /* * Check inclusionary user ID specifications. */ @@ -1805,10 +1473,11 @@ int main(int argc, char *argv[]) { (unsigned long)Suid[i].uid); } } + lsof_destroy(ctx); if (!rv && rc) rv = ev; - if (!rv && ErrStat) - rv = LSOF_ERROR; + if (!rv && err_stat) + rv = LSOF_EXIT_ERROR; Exit(ctx, rv); return (rv); /* to make code analyzers happy */ } @@ -1936,22 +1605,3 @@ static int GetOpt(int ct, /* option count */ */ return (c); } - -/* - * sv_fmt_str() - save format string - */ - -static char *sv_fmt_str(struct lsof_context *ctx, char *f) /* format string */ -{ - char *cp; - MALLOC_S l; - - l = (MALLOC_S)(strlen(f) + 1); - if (!(cp = (char *)malloc(l))) { - (void)fprintf(stderr, "%s: can't allocate %d bytes for format: %s\n", - Pn, (int)l, f); - Error(ctx); - } - (void)snpf(cp, l, "%s", f); - return (cp); -} diff --git a/src/netstat.c b/src/netstat.c new file mode 100644 index 00000000..5ad22c34 --- /dev/null +++ b/src/netstat.c @@ -0,0 +1,197 @@ +/* + * netstat.c - main function for lsof-netstat + * + * V. Abell, Purdue University + */ + +/* + * Copyright 2002 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by V. Abell. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "lsof.h" +#include +#include +#include +#include +#include + +void print_sockaddr(struct sockaddr_storage sockaddr, char *output, + size_t output_size) { + char buffer[128]; + if (sockaddr.ss_family == AF_INET) { + struct sockaddr_in *in = ((struct sockaddr_in *)&sockaddr); + inet_ntop(sockaddr.ss_family, &in->sin_addr, buffer, sizeof(buffer)); + snprintf(output, output_size, "%s:%d", buffer, ntohs(in->sin_port)); + } else if (sockaddr.ss_family == AF_INET6) { + struct sockaddr_in6 *in6 = ((struct sockaddr_in6 *)&sockaddr); + inet_ntop(sockaddr.ss_family, &in6->sin6_addr, buffer, sizeof(buffer)); + snprintf(output, output_size, "%s:%d", buffer, ntohs(in6->sin6_port)); + } else { + snprintf(output, output_size, ""); + } +} + +int main(int argc, char **argv) { + struct lsof_result *result = NULL; + struct lsof_context *ctx = NULL; + struct lsof_process *p; + struct lsof_file *f; + int res = 0; + int pi, fi; + int print_pass = 0; + char buffer[128]; + int len; + uint64_t recv_queue_len; + uint64_t send_queue_len; + + /* columns */ + char *proto_header = "Proto"; + int proto_width = strlen(proto_header); + char *proto; + char *recv_queue_header = "Recv-Q"; + int recv_queue_width = strlen(recv_queue_header); + char recv_queue[128]; + char *send_queue_header = "Send-Q"; + int send_queue_width = strlen(send_queue_header); + char send_queue[128]; + char *local_addr_header = "Local Address"; + int local_addr_width = strlen(local_addr_header); + char local_addr[128]; + char *foreign_addr_header = "Foreign Address"; + int foreign_addr_width = strlen(foreign_addr_header); + char foreign_addr[128]; + char *state_header = "State"; + int state_width = strlen(state_header); + char *state; + char *pid_program_header = "PID/Program name"; + char pid_program[128]; + int match; + + ctx = lsof_new(); + lsof_select_ip(ctx, AF_UNSPEC); + lsof_freeze(ctx); + lsof_gather(ctx, &result); + + for (print_pass = 0; print_pass < 2; print_pass++) { + for (pi = 0; pi < result->num_processes; pi++) { + p = &result->processes[pi]; + for (fi = 0; fi < p->num_files; fi++) { + f = &p->files[fi]; + match = 0; + if (f->protocol == LSOF_PROTOCOL_TCP && + f->file_type == LSOF_FILE_IPV4) { + match = 1; + proto = "tcp"; + } else if (f->protocol == LSOF_PROTOCOL_TCP && + f->file_type == LSOF_FILE_IPV6) { + match = 1; + proto = "tcp6"; + } else if (f->protocol == LSOF_PROTOCOL_UDP && + f->file_type == LSOF_FILE_IPV4) { + match = 1; + proto = "udp"; + } else if (f->protocol == LSOF_PROTOCOL_UDP && + f->file_type == LSOF_FILE_IPV6) { + match = 1; + proto = "udp6"; + } + + if (match) { + /* local address */ + print_sockaddr(f->net_local, local_addr, + sizeof(local_addr)); + print_sockaddr(f->net_foreign, foreign_addr, + sizeof(foreign_addr)); + snprintf(pid_program, sizeof(pid_program), "%d/%s", p->pid, + p->command); + recv_queue_len = 0; + send_queue_len = 0; + state = ""; + if (f->flags & LSOF_FILE_FLAG_TCP_TPI_VALID) { + if (f->tcp_tpi.flags & + LSOF_TCP_TPI_FLAG_RECV_QUEUE_LEN_VALID) { + recv_queue_len = f->tcp_tpi.recv_queue_len; + } + if (f->tcp_tpi.flags & + LSOF_TCP_TPI_FLAG_SEND_QUEUE_LEN_VALID) { + send_queue_len = f->tcp_tpi.send_queue_len; + } + if (f->tcp_tpi.state) { + state = f->tcp_tpi.state; + } + } + snprintf(recv_queue, sizeof(recv_queue), "%" PRId64, + recv_queue_len); + snprintf(send_queue, sizeof(send_queue), "%" PRId64, + send_queue_len); + + if (print_pass == 0) { + len = strlen(recv_queue); + if (len > recv_queue_width) + recv_queue_width = len; + + len = strlen(send_queue); + if (len > send_queue_width) + send_queue_width = len; + + len = strlen(local_addr); + if (len > local_addr_width) + local_addr_width = len; + + len = strlen(foreign_addr); + if (len > foreign_addr_width) + foreign_addr_width = len; + + len = strlen(state); + if (len > state_width) + state_width = len; + } else { + printf("%-*s %-*s %-*s %-*s %-*s %-*s %s\n", + proto_width, proto, recv_queue_width, recv_queue, + send_queue_width, send_queue, local_addr_width, + local_addr, foreign_addr_width, foreign_addr, + state_width, state, pid_program); + } + } + } + } + + if (print_pass == 0) { + printf("%*s %-*s %-*s %-*s %-*s %-*s %s\n", proto_width, + proto_header, recv_queue_width, recv_queue_header, + send_queue_width, send_queue_header, local_addr_width, + local_addr_header, foreign_addr_width, foreign_addr_header, + state_width, state_header, pid_program_header); + } + } + + if (result) { + lsof_free_result(result); + } + if (ctx) { + lsof_destroy(ctx); + } + return res; +} diff --git a/src/print.c b/src/print.c index 77cd2637..a6f4bf91 100644 --- a/src/print.c +++ b/src/print.c @@ -80,33 +80,16 @@ static struct porttab **Pth[4] = {NULL, NULL, NULL, NULL}; #define HASHPORT(p) (((((int)(p)) * 31415) >> 3) & (PORTHASHBUCKETS - 1)) #if !defined(HASNORPC_H) -static void fill_portmap(struct lsof_context *ctx); -static void update_portmap(struct lsof_context *ctx, struct porttab *pt, - char *pn); +static void fill_portmap(void); +static void update_portmap(struct porttab *pt, char *pn); #endif /* !defined(HASNORPC_H) */ -static void fill_porttab(struct lsof_context *ctx); -static char *lkup_port(struct lsof_context *ctx, int p, int pr, int src); -static char *lkup_svcnam(struct lsof_context *ctx, int h, int p, int pr, - int ss); -static int printinaddr(struct lsof_context *ctx); +static void fill_porttab(void); +static char *lkup_port(int p, int pr, int src); +static char *lkup_svcnam(int h, int p, int pr, int ss); +static int printinaddr(void); static int human_readable_size(SZOFFTYPE sz, int print, int col); -/* - * endnm() - locate end of Namech - */ - -char *endnm(struct lsof_context *ctx, size_t *sz) /* returned remaining size */ -{ - register char *s; - register size_t tsz; - - for (s = Namech, tsz = Namechl; *s; s++, tsz--) - ; - *sz = tsz; - return (s); -} - #if !defined(HASNORPC_H) /* * fill_portmap() -- fill the RPC portmap program name table via a conversation @@ -149,9 +132,9 @@ char *endnm(struct lsof_context *ctx, size_t *sz) /* returned remaining size */ * SUCH DAMAGE. */ -static void fill_portmap(struct lsof_context *ctx) { +static void fill_portmap() { static int already_run = 0; - char buf[128], *cp, *nm; + char buf[128], *cp, *nm = NULL; CLIENT *c; int h, port, pr; MALLOC_S nl; @@ -254,7 +237,7 @@ static void fill_portmap(struct lsof_context *ctx) { Error(ctx); } if (!nl) { - (void)free((FREE_P *)nm); + CLEAN(nm); continue; } /* @@ -266,6 +249,7 @@ static void fill_portmap(struct lsof_context *ctx) { "%s: can't allocate porttab entry for portmap: ", Pn); safestrprt(nm, stderr, 1); Error(ctx); + goto cleanup; } pt->name = nm; pt->nl = nl; @@ -275,6 +259,8 @@ static void fill_portmap(struct lsof_context *ctx) { Pth[pr][h] = pt; } clnt_destroy(c); +cleanup: + CLEAN(nm); } #endif /* !defined(HASNORPC_H) */ @@ -283,10 +269,10 @@ static void fill_portmap(struct lsof_context *ctx) { * getservent() scan */ -static void fill_porttab(struct lsof_context *ctx) { +static void fill_porttab() { int h, p, pr; MALLOC_S nl; - char *nm; + char *nm = NULL; struct porttab *pt; struct servent *se; @@ -327,9 +313,10 @@ static void fill_porttab(struct lsof_context *ctx) { "%s: can't allocate %d bytes for port %d name: %s\n", Pn, (int)(nl + 1), p, se->s_name); Error(ctx); + goto cleanup; } if (!nl) { - (void)free((FREE_P *)nm); + CLEAN(nm); continue; } if (!(pt = (struct porttab *)malloc(sizeof(struct porttab)))) { @@ -337,25 +324,29 @@ static void fill_porttab(struct lsof_context *ctx) { "%s: can't allocate porttab entry for port %d: %s\n", Pn, p, se->s_name); Error(ctx); + goto cleanup; } pt->name = nm; + nm = NULL; pt->nl = nl - 1; pt->port = p; pt->next = Pth[pr][h]; pt->ss = 0; Pth[pr][h] = pt; } +cleanup: (void)endservent(); + CLEAN(nm); } /* * gethostnm() - get host name */ -char *gethostnm(struct lsof_context *ctx, /* context */ - unsigned char *ia, /* Internet address */ - int af) /* address family -- e.g., AF_INET - * or AF_INET6 */ +char *gethostnm(ia, af) +unsigned char *ia; /* Internet address */ +int af; /* address family -- e.g., AF_INET + * or AF_INET6 */ { int al = MIN_AF_ADDR; char hbuf[256]; @@ -427,6 +418,7 @@ char *gethostnm(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "%s: no space for host name: ", Pn); safestrprt(hn, stderr, 1); Error(ctx); + return NULL; } /* * Add address/name entry to cache. Allocate cache space in HCINC chunks. @@ -441,6 +433,7 @@ char *gethostnm(struct lsof_context *ctx, /* context */ if (!hc) { (void)fprintf(stderr, "%s: no space for host cache\n", Pn); Error(ctx); + return NULL; } } hc[hcx].af = af; @@ -455,11 +448,11 @@ char *gethostnm(struct lsof_context *ctx, /* context */ * lkup_port() - look up port for protocol */ -static char *lkup_port(struct lsof_context *ctx, /* context */ - int p, /* port number */ - int pr, /* protocol index: 0 = tcp, 1 = udp */ - int src) /* port source: 0 = local - * 1 = foreign */ +static char *lkup_port(p, pr, src) +int p; /* port number */ +int pr; /* protocol index: 0 = tcp, 1 = udp */ +int src; /* port source: 0 = local + * 1 = foreign */ { int h, nh; MALLOC_S nl; @@ -486,6 +479,7 @@ static char *lkup_port(struct lsof_context *ctx, /* context */ (int)(2 * (PORTHASHBUCKETS * sizeof(struct porttab *))), (h & 1) ? "UDP" : "TCP", (h > 1) ? "portmap" : "port"); Error(ctx); + return NULL; } } } @@ -496,7 +490,7 @@ static char *lkup_port(struct lsof_context *ctx, /* context */ * portmap table has been loaded. */ if (FportMap) - (void)fill_portmap(ctx); + (void)fill_portmap(); #endif /* !defined(HASNORPC_H) */ /* @@ -511,12 +505,12 @@ static char *lkup_port(struct lsof_context *ctx, /* context */ if (pt->port != p) continue; if (!pt->ss) { - pn = Fport ? lkup_svcnam(ctx, h, p, pr, 0) : (char *)NULL; + pn = Fport ? lkup_svcnam(h, p, pr, 0) : (char *)NULL; if (!pn) { (void)snpf(pb, sizeof(pb), "%d", p); pn = pb; } - (void)update_portmap(ctx, pt, pn); + (void)update_portmap(pt, pn); } return (pt->name); } @@ -536,7 +530,7 @@ static char *lkup_port(struct lsof_context *ctx, /* context */ * Don't cache %d conversions; a zero port number is a %d conversion that * is represented by "*". */ - pn = Fport ? lkup_svcnam(ctx, h, p, pr, 1) : (char *)NULL; + pn = Fport ? lkup_svcnam(h, p, pr, 1) : (char *)NULL; if (!pn || !strlen(pn)) { if (p) { (void)snpf(pb, sizeof(pb), "%d", p); @@ -551,6 +545,7 @@ static char *lkup_port(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "%s: can't allocate porttab entry for port %d\n", Pn, p); Error(ctx); + return NULL; } /* * Allocate space for the name; copy it to the porttab entry; and link the @@ -562,6 +557,8 @@ static char *lkup_port(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "%s: can't allocate space for port name: ", Pn); safestrprt(pn, stderr, 1); Error(ctx); + CLEAN(pt); + return NULL; } pt->name = nm; pt->nl = nl; @@ -576,12 +573,12 @@ static char *lkup_port(struct lsof_context *ctx, /* context */ * lkup_svcnam() - look up service name for port */ -static char *lkup_svcnam(struct lsof_context *ctx, /* context */ - int h, /* porttab hash index */ - int p, /* port number */ - int pr, /* protocol: 0 = TCP, 1 = UDP */ - int ss) /* search status: 1 = Pth[pr][h] - * already searched */ +static char *lkup_svcnam(h, p, pr, ss) +int h; /* porttab hash index */ +int p; /* port number */ +int pr; /* protocol: 0 = TCP, 1 = UDP */ +int ss; /* search status: 1 = Pth[pr][h] + * already searched */ { static int fl[PORTTABTHRESH]; static int fln = 0; @@ -630,7 +627,7 @@ static char *lkup_svcnam(struct lsof_context *ctx, /* context */ fl[fln++] = p; return ((char *)NULL); } - (void)fill_porttab(ctx); + (void)fill_porttab(); ptf++; ss = 0; } @@ -641,12 +638,15 @@ static char *lkup_svcnam(struct lsof_context *ctx, /* context */ * print_file() - print file */ -void print_file(struct lsof_context *ctx) { +void print_file() { char buf[128]; + char fd[FDLEN]; char *cp = (char *)NULL; dev_t dev; int devs, len; char access; + char type[TYPEL]; + char lock; if (PrPass && !Hdr) { @@ -840,37 +840,44 @@ void print_file(struct lsof_context *ctx) { * Size or print the user ID or login name. */ if (!PrPass) { - if ((len = strlen(printuid(ctx, (UID_ARG)Lp->uid, NULL))) > UserColW) + if ((len = strlen(printuid((UID_ARG)Lp->uid, NULL))) > UserColW) UserColW = len; } else (void)printf(" %*.*s", UserColW, UserColW, - printuid(ctx, (UID_ARG)Lp->uid, NULL)); + printuid((UID_ARG)Lp->uid, NULL)); /* * Size or print the file descriptor, access mode and lock status. */ - access = access_to_char(Lf->access); + print_fd(Lf->fd_type, Lf->fd_num, fd); + access = print_access(Lf->access); + lock = print_lock(Lf->lock); if (!PrPass) { - (void)snpf(buf, sizeof(buf), "%s%c%c", Lf->fd, - (Lf->lock == ' ') ? access + (void)snpf(buf, sizeof(buf), "%s%c%c", fd, + (lock == ' ') ? access : (access == ' ') ? '-' : access, - Lf->lock); + lock); if ((len = strlen(buf)) > FdColW) FdColW = len; } else - (void)printf(" %*.*s%c%c", FdColW - 2, FdColW - 2, Lf->fd, - (Lf->lock == ' ') ? access + (void)printf(" %*.*s%c%c", FdColW - 2, FdColW - 2, fd, + (lock == ' ') ? access : (access == ' ') ? '-' : access, - Lf->lock); + lock); /* * Size or print the type. */ if (!PrPass) { - if ((len = strlen(Lf->type)) > TypeColW) + print_file_type(Lf->type, Lf->unknown_file_type_number, type, + sizeof(type)); + if ((len = strlen(type)) > TypeColW) TypeColW = len; - } else - (void)printf(" %*.*s", TypeColW, TypeColW, Lf->type); + } else { + print_file_type(Lf->type, Lf->unknown_file_type_number, type, + sizeof(type)); + (void)printf(" %*.*s", TypeColW, TypeColW, type); + } #if defined(HASFSTRUCT) /* @@ -995,7 +1002,6 @@ void print_file(struct lsof_context *ctx) { len = strlen(cp); if (OffDecDig && len > (OffDecDig + 2)) { - (void)snpf(buf, sizeof(buf), SzOffFmt_x, Lf->off); cp = buf; @@ -1012,16 +1018,13 @@ void print_file(struct lsof_context *ctx) { human_readable_size(Lf->sz, 1, SzOffColW); } else { (void)snpf(buf, sizeof(buf), SzOffFmt_d, Lf->sz); - len = strlen(buf); (void)printf(SzOffFmt_dv, SzOffColW, Lf->sz); } } else if (!Fsize && Lf->off_def) { - (void)snpf(buf, sizeof(buf), SzOffFmt_0t, Lf->off); cp = buf; if (OffDecDig && (int)strlen(cp) > (OffDecDig + 2)) { - (void)snpf(buf, sizeof(buf), SzOffFmt_x, Lf->off); cp = buf; } @@ -1047,28 +1050,17 @@ void print_file(struct lsof_context *ctx) { /* * Size or print the inode information. */ - switch (Lf->inp_ty) { - case 1: - + if (Lf->iproto != LSOF_PROTOCOL_INVALID) { + print_iproto(Lf->iproto, Lf->unknown_proto_number, buf, sizeof(buf)); + cp = buf; + } else if (Lf->inode_def) { #if defined(HASPRINTINO) cp = HASPRINTINO(Lf); #else /* !defined(HASPRINTINO) */ - (void)snpf(buf, sizeof(buf), InodeFmt_d, Lf->inode); + (void)snpf(buf, sizeof(buf), "%" INODEPSPEC "d", Lf->inode); cp = buf; #endif /* defined(HASPRINTINO) */ - - break; - case 2: - if (Lf->iproto[0]) - cp = Lf->iproto; - else - cp = ""; - break; - case 3: - (void)snpf(buf, sizeof(buf), InodeFmt_x, Lf->inode); - cp = buf; - break; - default: + } else { cp = ""; } if (!PrPass) { @@ -1085,9 +1077,9 @@ void print_file(struct lsof_context *ctx) { putchar(' '); #if defined(HASPRINTNM) - HASPRINTNM(ctx, Lf); + HASPRINTNM(Lf); #else /* !defined(HASPRINTNM) */ - printname(ctx, 1); + printname(1); #endif /* defined(HASPRINTNM) */ } } @@ -1096,7 +1088,7 @@ void print_file(struct lsof_context *ctx) { * printinaddr() - print Internet addresses */ -static int printinaddr(struct lsof_context *ctx) { +static int printinaddr() { int i, len, src; char *host, *port; int nl = Namechl - 1; @@ -1137,7 +1129,7 @@ static int printinaddr(struct lsof_context *ctx) { (Lf->li[i].af == AF_INET && Lf->li[i].ia.a4.s_addr == INADDR_ANY)) host = "*"; else - host = gethostnm(ctx, (unsigned char *)&Lf->li[i].ia, Lf->li[i].af); + host = gethostnm((unsigned char *)&Lf->li[i].ia, Lf->li[i].af); #else /* !defined(HASIPv6) */ if (Lf->li[i].ia.a4.s_addr == INADDR_ANY) host = "*"; @@ -1201,10 +1193,10 @@ static int printinaddr(struct lsof_context *ctx) { src = 1; #endif /* !defined(HASNORPC_H) */ - if (strcasecmp(Lf->iproto, "TCP") == 0) - port = lkup_port(ctx, Lf->li[i].p, 0, src); - else if (strcasecmp(Lf->iproto, "UDP") == 0) - port = lkup_port(ctx, Lf->li[i].p, 1, src); + if (Lf->iproto == LSOF_PROTOCOL_TCP) + port = lkup_port(Lf->li[i].p, 0, src); + else if (Lf->iproto == LSOF_PROTOCOL_UDP) + port = lkup_port(Lf->li[i].p, 1, src); } if (!port) { (void)snpf(pbuf, sizeof(pbuf), "%d", Lf->li[i].p); @@ -1312,664 +1304,11 @@ void print_init() { #endif /* defined(HASZONES) */ } -#if !defined(HASPRIVPRIPP) -/* - * printiproto() - print Internet protocol name - */ - -void printiproto(p) int p; /* protocol number */ -{ - int i; - static int m = -1; - char *s; - - switch (p) { - -# if defined(IPPROTO_TCP) - case IPPROTO_TCP: - s = "TCP"; - break; -# endif /* defined(IPPROTO_TCP) */ - -# if defined(IPPROTO_UDP) - case IPPROTO_UDP: - s = "UDP"; - break; -# endif /* defined(IPPROTO_UDP) */ - -# if defined(IPPROTO_IP) -# if !defined(IPPROTO_HOPOPTS) || IPPROTO_IP != IPPROTO_HOPOPTS - case IPPROTO_IP: - s = "IP"; - break; -# endif /* !defined(IPPROTO_HOPOPTS) || IPPROTO_IP!=IPPROTO_HOPOPTS */ -# endif /* defined(IPPROTO_IP) */ - -# if defined(IPPROTO_ICMP) - case IPPROTO_ICMP: - s = "ICMP"; - break; -# endif /* defined(IPPROTO_ICMP) */ - -# if defined(IPPROTO_ICMPV6) - case IPPROTO_ICMPV6: - s = "ICMPV6"; - break; -# endif /* defined(IPPROTO_ICMPV6) */ - -# if defined(IPPROTO_IGMP) - case IPPROTO_IGMP: - s = "IGMP"; - break; -# endif /* defined(IPPROTO_IGMP) */ - -# if defined(IPPROTO_GGP) - case IPPROTO_GGP: - s = "GGP"; - break; -# endif /* defined(IPPROTO_GGP) */ - -# if defined(IPPROTO_EGP) - case IPPROTO_EGP: - s = "EGP"; - break; -# endif /* defined(IPPROTO_EGP) */ - -# if defined(IPPROTO_PUP) - case IPPROTO_PUP: - s = "PUP"; - break; -# endif /* defined(IPPROTO_PUP) */ - -# if defined(IPPROTO_IDP) - case IPPROTO_IDP: - s = "IDP"; - break; -# endif /* defined(IPPROTO_IDP) */ - -# if defined(IPPROTO_ND) - case IPPROTO_ND: - s = "ND"; - break; -# endif /* defined(IPPROTO_ND) */ - -# if defined(IPPROTO_RAW) - case IPPROTO_RAW: - s = "RAW"; - break; -# endif /* defined(IPPROTO_RAW) */ - -# if defined(IPPROTO_HELLO) - case IPPROTO_HELLO: - s = "HELLO"; - break; -# endif /* defined(IPPROTO_HELLO) */ - -# if defined(IPPROTO_PXP) - case IPPROTO_PXP: - s = "PXP"; - break; -# endif /* defined(IPPROTO_PXP) */ - -# if defined(IPPROTO_RAWIP) - case IPPROTO_RAWIP: - s = "RAWIP"; - break; -# endif /* defined(IPPROTO_RAWIP) */ - -# if defined(IPPROTO_RAWIF) - case IPPROTO_RAWIF: - s = "RAWIF"; - break; -# endif /* defined(IPPROTO_RAWIF) */ - -# if defined(IPPROTO_HOPOPTS) - case IPPROTO_HOPOPTS: - s = "HOPOPTS"; - break; -# endif /* defined(IPPROTO_HOPOPTS) */ - -# if defined(IPPROTO_IPIP) - case IPPROTO_IPIP: - s = "IPIP"; - break; -# endif /* defined(IPPROTO_IPIP) */ - -# if defined(IPPROTO_ST) - case IPPROTO_ST: - s = "ST"; - break; -# endif /* defined(IPPROTO_ST) */ - -# if defined(IPPROTO_PIGP) - case IPPROTO_PIGP: - s = "PIGP"; - break; -# endif /* defined(IPPROTO_PIGP) */ - -# if defined(IPPROTO_RCCMON) - case IPPROTO_RCCMON: - s = "RCCMON"; - break; -# endif /* defined(IPPROTO_RCCMON) */ - -# if defined(IPPROTO_NVPII) - case IPPROTO_NVPII: - s = "NVPII"; - break; -# endif /* defined(IPPROTO_NVPII) */ - -# if defined(IPPROTO_ARGUS) - case IPPROTO_ARGUS: - s = "ARGUS"; - break; -# endif /* defined(IPPROTO_ARGUS) */ - -# if defined(IPPROTO_EMCON) - case IPPROTO_EMCON: - s = "EMCON"; - break; -# endif /* defined(IPPROTO_EMCON) */ - -# if defined(IPPROTO_XNET) - case IPPROTO_XNET: - s = "XNET"; - break; -# endif /* defined(IPPROTO_XNET) */ - -# if defined(IPPROTO_CHAOS) - case IPPROTO_CHAOS: - s = "CHAOS"; - break; -# endif /* defined(IPPROTO_CHAOS) */ - -# if defined(IPPROTO_MUX) - case IPPROTO_MUX: - s = "MUX"; - break; -# endif /* defined(IPPROTO_MUX) */ - -# if defined(IPPROTO_MEAS) - case IPPROTO_MEAS: - s = "MEAS"; - break; -# endif /* defined(IPPROTO_MEAS) */ - -# if defined(IPPROTO_HMP) - case IPPROTO_HMP: - s = "HMP"; - break; -# endif /* defined(IPPROTO_HMP) */ - -# if defined(IPPROTO_PRM) - case IPPROTO_PRM: - s = "PRM"; - break; -# endif /* defined(IPPROTO_PRM) */ - -# if defined(IPPROTO_TRUNK1) - case IPPROTO_TRUNK1: - s = "TRUNK1"; - break; -# endif /* defined(IPPROTO_TRUNK1) */ - -# if defined(IPPROTO_TRUNK2) - case IPPROTO_TRUNK2: - s = "TRUNK2"; - break; -# endif /* defined(IPPROTO_TRUNK2) */ - -# if defined(IPPROTO_LEAF1) - case IPPROTO_LEAF1: - s = "LEAF1"; - break; -# endif /* defined(IPPROTO_LEAF1) */ - -# if defined(IPPROTO_LEAF2) - case IPPROTO_LEAF2: - s = "LEAF2"; - break; -# endif /* defined(IPPROTO_LEAF2) */ - -# if defined(IPPROTO_RDP) - case IPPROTO_RDP: - s = "RDP"; - break; -# endif /* defined(IPPROTO_RDP) */ - -# if defined(IPPROTO_IRTP) - case IPPROTO_IRTP: - s = "IRTP"; - break; -# endif /* defined(IPPROTO_IRTP) */ - -# if defined(IPPROTO_TP) - case IPPROTO_TP: - s = "TP"; - break; -# endif /* defined(IPPROTO_TP) */ - -# if defined(IPPROTO_BLT) - case IPPROTO_BLT: - s = "BLT"; - break; -# endif /* defined(IPPROTO_BLT) */ - -# if defined(IPPROTO_NSP) - case IPPROTO_NSP: - s = "NSP"; - break; -# endif /* defined(IPPROTO_NSP) */ - -# if defined(IPPROTO_INP) - case IPPROTO_INP: - s = "INP"; - break; -# endif /* defined(IPPROTO_INP) */ - -# if defined(IPPROTO_SEP) - case IPPROTO_SEP: - s = "SEP"; - break; -# endif /* defined(IPPROTO_SEP) */ - -# if defined(IPPROTO_3PC) - case IPPROTO_3PC: - s = "3PC"; - break; -# endif /* defined(IPPROTO_3PC) */ - -# if defined(IPPROTO_IDPR) - case IPPROTO_IDPR: - s = "IDPR"; - break; -# endif /* defined(IPPROTO_IDPR) */ - -# if defined(IPPROTO_XTP) - case IPPROTO_XTP: - s = "XTP"; - break; -# endif /* defined(IPPROTO_XTP) */ - -# if defined(IPPROTO_DDP) - case IPPROTO_DDP: - s = "DDP"; - break; -# endif /* defined(IPPROTO_DDP) */ - -# if defined(IPPROTO_CMTP) - case IPPROTO_CMTP: - s = "CMTP"; - break; -# endif /* defined(IPPROTO_CMTP) */ - -# if defined(IPPROTO_TPXX) - case IPPROTO_TPXX: - s = "TPXX"; - break; -# endif /* defined(IPPROTO_TPXX) */ - -# if defined(IPPROTO_IL) - case IPPROTO_IL: - s = "IL"; - break; -# endif /* defined(IPPROTO_IL) */ - -# if defined(IPPROTO_IPV6) - case IPPROTO_IPV6: - s = "IPV6"; - break; -# endif /* defined(IPPROTO_IPV6) */ - -# if defined(IPPROTO_SDRP) - case IPPROTO_SDRP: - s = "SDRP"; - break; -# endif /* defined(IPPROTO_SDRP) */ - -# if defined(IPPROTO_ROUTING) - case IPPROTO_ROUTING: - s = "ROUTING"; - break; -# endif /* defined(IPPROTO_ROUTING) */ - -# if defined(IPPROTO_FRAGMENT) - case IPPROTO_FRAGMENT: - s = "FRAGMNT"; - break; -# endif /* defined(IPPROTO_FRAGMENT) */ - -# if defined(IPPROTO_IDRP) - case IPPROTO_IDRP: - s = "IDRP"; - break; -# endif /* defined(IPPROTO_IDRP) */ - -# if defined(IPPROTO_RSVP) - case IPPROTO_RSVP: - s = "RSVP"; - break; -# endif /* defined(IPPROTO_RSVP) */ - -# if defined(IPPROTO_GRE) - case IPPROTO_GRE: - s = "GRE"; - break; -# endif /* defined(IPPROTO_GRE) */ - -# if defined(IPPROTO_MHRP) - case IPPROTO_MHRP: - s = "MHRP"; - break; -# endif /* defined(IPPROTO_MHRP) */ - -# if defined(IPPROTO_BHA) - case IPPROTO_BHA: - s = "BHA"; - break; -# endif /* defined(IPPROTO_BHA) */ - -# if defined(IPPROTO_ESP) - case IPPROTO_ESP: - s = "ESP"; - break; -# endif /* defined(IPPROTO_ESP) */ - -# if defined(IPPROTO_AH) - case IPPROTO_AH: - s = "AH"; - break; -# endif /* defined(IPPROTO_AH) */ - -# if defined(IPPROTO_INLSP) - case IPPROTO_INLSP: - s = "INLSP"; - break; -# endif /* defined(IPPROTO_INLSP) */ - -# if defined(IPPROTO_SWIPE) - case IPPROTO_SWIPE: - s = "SWIPE"; - break; -# endif /* defined(IPPROTO_SWIPE) */ - -# if defined(IPPROTO_NHRP) - case IPPROTO_NHRP: - s = "NHRP"; - break; -# endif /* defined(IPPROTO_NHRP) */ - -# if defined(IPPROTO_NONE) - case IPPROTO_NONE: - s = "NONE"; - break; -# endif /* defined(IPPROTO_NONE) */ - -# if defined(IPPROTO_DSTOPTS) - case IPPROTO_DSTOPTS: - s = "DSTOPTS"; - break; -# endif /* defined(IPPROTO_DSTOPTS) */ - -# if defined(IPPROTO_AHIP) - case IPPROTO_AHIP: - s = "AHIP"; - break; -# endif /* defined(IPPROTO_AHIP) */ - -# if defined(IPPROTO_CFTP) - case IPPROTO_CFTP: - s = "CFTP"; - break; -# endif /* defined(IPPROTO_CFTP) */ - -# if defined(IPPROTO_SATEXPAK) - case IPPROTO_SATEXPAK: - s = "SATEXPK"; - break; -# endif /* defined(IPPROTO_SATEXPAK) */ - -# if defined(IPPROTO_KRYPTOLAN) - case IPPROTO_KRYPTOLAN: - s = "KRYPTOL"; - break; -# endif /* defined(IPPROTO_KRYPTOLAN) */ - -# if defined(IPPROTO_RVD) - case IPPROTO_RVD: - s = "RVD"; - break; -# endif /* defined(IPPROTO_RVD) */ - -# if defined(IPPROTO_IPPC) - case IPPROTO_IPPC: - s = "IPPC"; - break; -# endif /* defined(IPPROTO_IPPC) */ - -# if defined(IPPROTO_ADFS) - case IPPROTO_ADFS: - s = "ADFS"; - break; -# endif /* defined(IPPROTO_ADFS) */ - -# if defined(IPPROTO_SATMON) - case IPPROTO_SATMON: - s = "SATMON"; - break; -# endif /* defined(IPPROTO_SATMON) */ - -# if defined(IPPROTO_VISA) - case IPPROTO_VISA: - s = "VISA"; - break; -# endif /* defined(IPPROTO_VISA) */ - -# if defined(IPPROTO_IPCV) - case IPPROTO_IPCV: - s = "IPCV"; - break; -# endif /* defined(IPPROTO_IPCV) */ - -# if defined(IPPROTO_CPNX) - case IPPROTO_CPNX: - s = "CPNX"; - break; -# endif /* defined(IPPROTO_CPNX) */ - -# if defined(IPPROTO_CPHB) - case IPPROTO_CPHB: - s = "CPHB"; - break; -# endif /* defined(IPPROTO_CPHB) */ - -# if defined(IPPROTO_WSN) - case IPPROTO_WSN: - s = "WSN"; - break; -# endif /* defined(IPPROTO_WSN) */ - -# if defined(IPPROTO_PVP) - case IPPROTO_PVP: - s = "PVP"; - break; -# endif /* defined(IPPROTO_PVP) */ - -# if defined(IPPROTO_BRSATMON) - case IPPROTO_BRSATMON: - s = "BRSATMN"; - break; -# endif /* defined(IPPROTO_BRSATMON) */ - -# if defined(IPPROTO_WBMON) - case IPPROTO_WBMON: - s = "WBMON"; - break; -# endif /* defined(IPPROTO_WBMON) */ - -# if defined(IPPROTO_WBEXPAK) - case IPPROTO_WBEXPAK: - s = "WBEXPAK"; - break; -# endif /* defined(IPPROTO_WBEXPAK) */ - -# if defined(IPPROTO_EON) - case IPPROTO_EON: - s = "EON"; - break; -# endif /* defined(IPPROTO_EON) */ - -# if defined(IPPROTO_VMTP) - case IPPROTO_VMTP: - s = "VMTP"; - break; -# endif /* defined(IPPROTO_VMTP) */ - -# if defined(IPPROTO_SVMTP) - case IPPROTO_SVMTP: - s = "SVMTP"; - break; -# endif /* defined(IPPROTO_SVMTP) */ - -# if defined(IPPROTO_VINES) - case IPPROTO_VINES: - s = "VINES"; - break; -# endif /* defined(IPPROTO_VINES) */ - -# if defined(IPPROTO_TTP) - case IPPROTO_TTP: - s = "TTP"; - break; -# endif /* defined(IPPROTO_TTP) */ - -# if defined(IPPROTO_IGP) - case IPPROTO_IGP: - s = "IGP"; - break; -# endif /* defined(IPPROTO_IGP) */ - -# if defined(IPPROTO_DGP) - case IPPROTO_DGP: - s = "DGP"; - break; -# endif /* defined(IPPROTO_DGP) */ - -# if defined(IPPROTO_TCF) - case IPPROTO_TCF: - s = "TCF"; - break; -# endif /* defined(IPPROTO_TCF) */ - -# if defined(IPPROTO_IGRP) - case IPPROTO_IGRP: - s = "IGRP"; - break; -# endif /* defined(IPPROTO_IGRP) */ - -# if defined(IPPROTO_OSPFIGP) - case IPPROTO_OSPFIGP: - s = "OSPFIGP"; - break; -# endif /* defined(IPPROTO_OSPFIGP) */ - -# if defined(IPPROTO_SRPC) - case IPPROTO_SRPC: - s = "SRPC"; - break; -# endif /* defined(IPPROTO_SRPC) */ - -# if defined(IPPROTO_LARP) - case IPPROTO_LARP: - s = "LARP"; - break; -# endif /* defined(IPPROTO_LARP) */ - -# if defined(IPPROTO_MTP) - case IPPROTO_MTP: - s = "MTP"; - break; -# endif /* defined(IPPROTO_MTP) */ - -# if defined(IPPROTO_AX25) - case IPPROTO_AX25: - s = "AX25"; - break; -# endif /* defined(IPPROTO_AX25) */ - -# if defined(IPPROTO_IPEIP) - case IPPROTO_IPEIP: - s = "IPEIP"; - break; -# endif /* defined(IPPROTO_IPEIP) */ - -# if defined(IPPROTO_MICP) - case IPPROTO_MICP: - s = "MICP"; - break; -# endif /* defined(IPPROTO_MICP) */ - -# if defined(IPPROTO_SCCSP) - case IPPROTO_SCCSP: - s = "SCCSP"; - break; -# endif /* defined(IPPROTO_SCCSP) */ - -# if defined(IPPROTO_ETHERIP) - case IPPROTO_ETHERIP: - s = "ETHERIP"; - break; -# endif /* defined(IPPROTO_ETHERIP) */ - -# if defined(IPPROTO_ENCAP) -# if !defined(IPPROTO_IPIP) || IPPROTO_IPIP != IPPROTO_ENCAP - case IPPROTO_ENCAP: - s = "ENCAP"; - break; -# endif /* !defined(IPPROTO_IPIP) || IPPROTO_IPIP!=IPPROTO_ENCAP */ -# endif /* defined(IPPROTO_ENCAP) */ - -# if defined(IPPROTO_APES) - case IPPROTO_APES: - s = "APES"; - break; -# endif /* defined(IPPROTO_APES) */ - -# if defined(IPPROTO_GMTP) - case IPPROTO_GMTP: - s = "GMTP"; - break; -# endif /* defined(IPPROTO_GMTP) */ - -# if defined(IPPROTO_DIVERT) - case IPPROTO_DIVERT: - s = "DIVERT"; - break; -# endif /* defined(IPPROTO_DIVERT) */ - - default: - s = (char *)NULL; - } - if (s) - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, s); - else { - if (m < 0) { - for (i = 0, m = 1; i < IPROTOL - 2; i++) - m *= 10; - } - if (m > p) - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%d?", p); - else - (void)snpf(Lf->iproto, sizeof(Lf->iproto), "*%d?", p % (m / 10)); - } -} -#endif /* !defined(HASPRIVPRIPP) */ - /* * printname() - print output name field */ -void printname(struct lsof_context *ctx, int nl) /* NL status */ +void printname(nl) int nl; /* NL status */ { #if defined(HASNCACHE) @@ -1996,12 +1335,12 @@ void printname(struct lsof_context *ctx, int nl) /* NL status */ /* * If the file has Internet addresses, print them. */ - if (printinaddr(ctx)) + if (printinaddr()) ps++; goto print_nma; } - if (((Lf->ntype == N_BLK) || (Lf->ntype == N_CHR)) && Lf->dev_def && - Lf->rdev_def && printdevname(ctx, &Lf->dev, &Lf->rdev, 0, Lf->ntype)) { + if (((Ntype == N_BLK) || (Ntype == N_CHR)) && Lf->dev_def && Lf->rdev_def && + printdevname(ctx, &Lf->dev, &Lf->rdev, 0, Ntype)) { /* * If this is a block or character device and it has a name, print it. @@ -2205,65 +1544,16 @@ void printrawaddr(struct lsof_context *ctx, (unsigned char)sa->sa_data[13]); } -/* - * printsockty() - print socket type - */ - -char *printsockty(int ty) /* socket type -- e.g., from so_type */ -{ - static char buf[64]; - char *cp; - - switch (ty) { - -#if defined(SOCK_STREAM) - case SOCK_STREAM: - cp = "STREAM"; - break; -#endif /* defined(SOCK_STREAM) */ - -#if defined(SOCK_STREAM) - case SOCK_DGRAM: - cp = "DGRAM"; - break; -#endif /* defined(SOCK_DGRAM) */ - -#if defined(SOCK_RAW) - case SOCK_RAW: - cp = "RAW"; - break; -#endif /* defined(SOCK_RAW) */ - -#if defined(SOCK_RDM) - case SOCK_RDM: - cp = "RDM"; - break; -#endif /* defined(SOCK_RDM) */ - -#if defined(SOCK_SEQPACKET) - case SOCK_SEQPACKET: - cp = "SEQPACKET"; - break; -#endif /* defined(SOCK_SEQPACKET) */ - - default: - (void)snpf(buf, sizeof(buf), "SOCK_%#x", ty); - return (buf); - } - (void)snpf(buf, sizeof(buf), "SOCK_%s", cp); - return (buf); -} - /* * printuid() - print User ID or login name */ -char *printuid(struct lsof_context *ctx, /* context */ - UID_ARG uid, /* User IDentification number */ - int *ty) /* returned UID type pointer (NULL - * (if none wanted). If non-NULL - * then: *ty = 0 = login name - * = 1 = UID number */ +char *printuid(uid, ty) +UID_ARG uid; /* User IDentification number */ +int *ty; /* returned UID type pointer (NULL + * (if none wanted). If non-NULL + * then: *ty = 0 = login name + * = 1 = UID number */ { int i; struct passwd *pw; @@ -2287,6 +1577,7 @@ char *printuid(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "%s: can't stat(/etc/passwd): %s\n", Pn, strerror(errno)); Error(ctx); + return NULL; } } /* @@ -2299,6 +1590,7 @@ char *printuid(struct lsof_context *ctx, /* context */ stderr, "%s: no space for %d byte UID cache hash buckets\n", Pn, (int)(UIDCACHEL * (sizeof(struct uidcache *)))); Error(ctx); + return NULL; } if (CkPasswd) { sbs = sb; @@ -2355,6 +1647,7 @@ char *printuid(struct lsof_context *ctx, /* context */ stderr, "%s: no space for UID cache entry for: %lu, %s)\n", Pn, (unsigned long)uid, pw->pw_name); Error(ctx); + return NULL; } (void)strncpy(upn->nm, pw->pw_name, LOGINML); upn->nm[LOGINML] = '\0'; @@ -2375,379 +1668,14 @@ char *printuid(struct lsof_context *ctx, /* context */ return (user); } -/* - * printunkaf() - print unknown address family - */ - -void printunkaf(struct lsof_context *ctx, int fam, /* unknown address family */ - int ty) /* output type: 0 = terse; 1 = full */ -{ - char *p, *s; - - p = ""; - switch (fam) { - -#if defined(AF_UNSPEC) - case AF_UNSPEC: - s = "UNSPEC"; - break; -#endif /* defined(AF_UNSPEC) */ - -#if defined(AF_UNIX) - case AF_UNIX: - s = "UNIX"; - break; -#endif /* defined(AF_UNIX) */ - -#if defined(AF_INET) - case AF_INET: - s = "INET"; - break; -#endif /* defined(AF_INET) */ - -#if defined(AF_INET6) - case AF_INET6: - s = "INET6"; - break; -#endif /* defined(AF_INET6) */ - -#if defined(AF_IMPLINK) - case AF_IMPLINK: - s = "IMPLINK"; - break; -#endif /* defined(AF_IMPLINK) */ - -#if defined(AF_PUP) - case AF_PUP: - s = "PUP"; - break; -#endif /* defined(AF_PUP) */ - -#if defined(AF_CHAOS) - case AF_CHAOS: - s = "CHAOS"; - break; -#endif /* defined(AF_CHAOS) */ - -#if defined(AF_NS) - case AF_NS: - s = "NS"; - break; -#endif /* defined(AF_NS) */ - -#if defined(AF_ISO) - case AF_ISO: - s = "ISO"; - break; -#endif /* defined(AF_ISO) */ - -#if defined(AF_NBS) -# if !defined(AF_ISO) || AF_NBS != AF_ISO - case AF_NBS: - s = "NBS"; - break; -# endif /* !defined(AF_ISO) || AF_NBS!=AF_ISO */ -#endif /* defined(AF_NBS) */ - -#if defined(AF_ECMA) - case AF_ECMA: - s = "ECMA"; - break; -#endif /* defined(AF_ECMA) */ - -#if defined(AF_DATAKIT) - case AF_DATAKIT: - s = "DATAKIT"; - break; -#endif /* defined(AF_DATAKIT) */ - -#if defined(AF_CCITT) - case AF_CCITT: - s = "CCITT"; - break; -#endif /* defined(AF_CCITT) */ - -#if defined(AF_SNA) - case AF_SNA: - s = "SNA"; - break; -#endif /* defined(AF_SNA) */ - -#if defined(AF_DECnet) - case AF_DECnet: - s = "DECnet"; - break; -#endif /* defined(AF_DECnet) */ - -#if defined(AF_DLI) - case AF_DLI: - s = "DLI"; - break; -#endif /* defined(AF_DLI) */ - -#if defined(AF_LAT) - case AF_LAT: - s = "LAT"; - break; -#endif /* defined(AF_LAT) */ - -#if defined(AF_HYLINK) - case AF_HYLINK: - s = "HYLINK"; - break; -#endif /* defined(AF_HYLINK) */ - -#if defined(AF_APPLETALK) - case AF_APPLETALK: - s = "APPLETALK"; - break; -#endif /* defined(AF_APPLETALK) */ - -#if defined(AF_BSC) - case AF_BSC: - s = "BSC"; - break; -#endif /* defined(AF_BSC) */ - -#if defined(AF_DSS) - case AF_DSS: - s = "DSS"; - break; -#endif /* defined(AF_DSS) */ - -#if defined(AF_ROUTE) - case AF_ROUTE: - s = "ROUTE"; - break; -#endif /* defined(AF_ROUTE) */ - -#if defined(AF_RAW) - case AF_RAW: - s = "RAW"; - break; -#endif /* defined(AF_RAW) */ - -#if defined(AF_LINK) - case AF_LINK: - s = "LINK"; - break; -#endif /* defined(AF_LINK) */ - -#if defined(pseudo_AF_XTP) - case pseudo_AF_XTP: - p = "pseudo_"; - s = "XTP"; - break; -#endif /* defined(pseudo_AF_XTP) */ - -#if defined(AF_RMP) - case AF_RMP: - s = "RMP"; - break; -#endif /* defined(AF_RMP) */ - -#if defined(AF_COIP) - case AF_COIP: - s = "COIP"; - break; -#endif /* defined(AF_COIP) */ - -#if defined(AF_CNT) - case AF_CNT: - s = "CNT"; - break; -#endif /* defined(AF_CNT) */ - -#if defined(pseudo_AF_RTIP) - case pseudo_AF_RTIP: - p = "pseudo_"; - s = "RTIP"; - break; -#endif /* defined(pseudo_AF_RTIP) */ - -#if defined(AF_NETMAN) - case AF_NETMAN: - s = "NETMAN"; - break; -#endif /* defined(AF_NETMAN) */ - -#if defined(AF_INTF) - case AF_INTF: - s = "INTF"; - break; -#endif /* defined(AF_INTF) */ - -#if defined(AF_NETWARE) - case AF_NETWARE: - s = "NETWARE"; - break; -#endif /* defined(AF_NETWARE) */ - -#if defined(AF_NDD) - case AF_NDD: - s = "NDD"; - break; -#endif /* defined(AF_NDD) */ - -#if defined(AF_NIT) -# if !defined(AF_ROUTE) || AF_ROUTE != AF_NIT - case AF_NIT: - s = "NIT"; - break; -# endif /* !defined(AF_ROUTE) || AF_ROUTE!=AF_NIT */ -#endif /* defined(AF_NIT) */ - -#if defined(AF_802) -# if !defined(AF_RAW) || AF_RAW != AF_802 - case AF_802: - s = "802"; - break; -# endif /* !defined(AF_RAW) || AF_RAW!=AF_802 */ -#endif /* defined(AF_802) */ - -#if defined(AF_X25) - case AF_X25: - s = "X25"; - break; -#endif /* defined(AF_X25) */ - -#if defined(AF_CTF) - case AF_CTF: - s = "CTF"; - break; -#endif /* defined(AF_CTF) */ - -#if defined(AF_WAN) - case AF_WAN: - s = "WAN"; - break; -#endif /* defined(AF_WAN) */ - -#if defined(AF_OSINET) -# if defined(AF_INET) && AF_INET != AF_OSINET - case AF_OSINET: - s = "OSINET"; - break; -# endif /* defined(AF_INET) && AF_INET!=AF_OSINET */ -#endif /* defined(AF_OSINET) */ - -#if defined(AF_GOSIP) - case AF_GOSIP: - s = "GOSIP"; - break; -#endif /* defined(AF_GOSIP) */ - -#if defined(AF_SDL) - case AF_SDL: - s = "SDL"; - break; -#endif /* defined(AF_SDL) */ - -#if defined(AF_IPX) - case AF_IPX: - s = "IPX"; - break; -#endif /* defined(AF_IPX) */ - -#if defined(AF_SIP) - case AF_SIP: - s = "SIP"; - break; -#endif /* defined(AF_SIP) */ - -#if defined(psuedo_AF_PIP) - case psuedo_AF_PIP: - p = "pseudo_"; - s = "PIP"; - break; -#endif /* defined(psuedo_AF_PIP) */ - -#if defined(AF_OTS) - case AF_OTS: - s = "OTS"; - break; -#endif /* defined(AF_OTS) */ - -#if defined(pseudo_AF_BLUE) - case pseudo_AF_BLUE: /* packets for Blue box */ - p = "pseudo_"; - s = "BLUE"; - break; -#endif /* defined(pseudo_AF_BLUE) */ - -#if defined(AF_NDRV) /* network driver raw access */ - case AF_NDRV: - s = "NDRV"; - break; -#endif /* defined(AF_NDRV) */ - -#if defined(AF_SYSTEM) /* kernel event messages */ - case AF_SYSTEM: - s = "SYSTEM"; - break; -#endif /* defined(AF_SYSTEM) */ - -#if defined(AF_USER) - case AF_USER: - s = "USER"; - break; -#endif /* defined(AF_USER) */ - -#if defined(pseudo_AF_KEY) - case pseudo_AF_KEY: - p = "pseudo_"; - s = "KEY"; - break; -#endif /* defined(pseudo_AF_KEY) */ - -#if defined(AF_KEY) /* Security Association DB socket */ - case AF_KEY: - s = "KEY"; - break; -#endif /* defined(AF_KEY) */ - -#if defined(AF_NCA) /* NCA socket */ - case AF_NCA: - s = "NCA"; - break; -#endif /* defined(AF_NCA) */ - -#if defined(AF_POLICY) /* Security Policy DB socket */ - case AF_POLICY: - s = "POLICY"; - break; -#endif /* defined(AF_POLICY) */ - -#if defined(AF_PPP) /* PPP socket */ - case AF_PPP: - s = "PPP"; - break; -#endif /* defined(AF_PPP) */ - - default: - if (!ty) - (void)snpf(Namech, Namechl, "%#x", fam); - else - (void)snpf(Namech, Namechl, "no further information on family %#x", - fam); - return; - } - if (!ty) - (void)snpf(Namech, Namechl, "%sAF_%s", p, s); - else - (void)snpf(Namech, Namechl, "no further information on %sAF_%s", p, s); - return; -} - #if !defined(HASNORPC_H) /* * update_portmap() - update a portmap entry with its port number or service * name */ -static void update_portmap(struct lsof_context *ctx, /* context */ - struct porttab *pt, /* porttab entry */ - char *pn) /* port name */ +static void update_portmap(pt, pn) struct porttab *pt; /* porttab entry */ +char *pn; /* port name */ { MALLOC_S al, nl; char *cp; @@ -2810,3 +1738,352 @@ int human_readable_size(SZOFFTYPE sz, int print, int col) { } return strlen(buf); } + +/* + * print_proc() - print process + */ + +int print_proc() { + char buf[128], *cp, type[TYPEL]; + int lc, len, st, ty; + int rv = 0; + unsigned long ul; + char access; + char lock; + + /* + * If nothing in the process has been selected, skip it. + */ + if (!Lp->pss) + return (0); + if (Fterse) { + if (Lp->pid == LastPid) /* eliminate duplicates */ + return (0); + LastPid = Lp->pid; + /* + * The mode is terse and something in the process appears to have + * been selected. Make sure of that by looking for a selected file, + * so that the HASSECURITY and HASNOSOCKSECURITY option combination + * won't produce a false positive result. + */ + for (Lf = Lp->file; Lf; Lf = Lf->next) { + if (is_file_sel(ctx, Lp, Lf)) { + (void)printf("%d\n", Lp->pid); + return (1); + } + } + return (0); + } + /* + * If fields have been selected, output the process-only ones, provided + * that some file has also been selected. + */ + if (Ffield) { + for (Lf = Lp->file; Lf; Lf = Lf->next) { + if (is_file_sel(ctx, Lp, Lf)) + break; + } + if (!Lf) + return (rv); + rv = 1; + (void)printf("%c%d%c", LSOF_FID_PID, Lp->pid, Terminator); + +#if defined(HASTASKS) + if (FieldSel[LSOF_FIX_TID].st && Lp->tid) + (void)printf("%c%d%c", LSOF_FID_TID, Lp->tid, Terminator); + if (FieldSel[LSOF_FIX_TCMD].st && Lp->tcmd) + (void)printf("%c%s%c", LSOF_FID_TCMD, Lp->tcmd, Terminator); +#endif /* defined(HASTASKS) */ + +#if defined(HASZONES) + if (FieldSel[LSOF_FIX_ZONE].st && Fzone && Lp->zn) + (void)printf("%c%s%c", LSOF_FID_ZONE, Lp->zn, Terminator); +#endif /* defined(HASZONES) */ + +#if defined(HASSELINUX) + if (FieldSel[LSOF_FIX_CNTX].st && Fcntx && Lp->cntx && CntxStatus) + (void)printf("%c%s%c", LSOF_FID_CNTX, Lp->cntx, Terminator); +#endif /* defined(HASSELINUX) */ + + if (FieldSel[LSOF_FIX_PGID].st && Fpgid) + (void)printf("%c%d%c", LSOF_FID_PGID, Lp->pgid, Terminator); + +#if defined(HASPPID) + if (FieldSel[LSOF_FIX_PPID].st && Fppid) + (void)printf("%c%d%c", LSOF_FID_PPID, Lp->ppid, Terminator); +#endif /* defined(HASPPID) */ + + if (FieldSel[LSOF_FIX_CMD].st) { + putchar(LSOF_FID_CMD); + safestrprt(Lp->cmd ? Lp->cmd : "(unknown)", stdout, 0); + putchar(Terminator); + } + if (FieldSel[LSOF_FIX_UID].st) + (void)printf("%c%d%c", LSOF_FID_UID, (int)Lp->uid, Terminator); + if (FieldSel[LSOF_FIX_LOGIN].st) { + cp = printuid((UID_ARG)Lp->uid, &ty); + if (cp && ty == 0) + (void)printf("%c%s%c", LSOF_FID_LOGIN, cp, Terminator); + } + if (Terminator == '\0') + putchar('\n'); + } + /* + * Print files. + */ + for (Lf = Lp->file; Lf; Lf = Lf->next) { + if (!is_file_sel(ctx, Lp, Lf)) + continue; + rv = 1; + /* + * If no field output selected, print dialect-specific formatted + * output. + */ + if (!Ffield) { + print_file(); + continue; + } + lc = st = 0; + if (FieldSel[LSOF_FIX_FD].st) { + + /* + * Print the field + * identifier even if there are no characters + */ + print_fd(Lf->fd_type, Lf->fd_num, buf); + (void)printf("%c%s%c", LSOF_FID_FD, buf, Terminator); + lc++; + } + /* + * Print selected fields. + */ + if (FieldSel[LSOF_FIX_ACCESS].st) { + access = print_access(Lf->access); + (void)printf("%c%c%c", LSOF_FID_ACCESS, access, Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_LOCK].st) { + lock = print_lock(Lf->lock); + (void)printf("%c%c%c", LSOF_FID_LOCK, lock, Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_TYPE].st) { + print_file_type(Lf->type, Lf->unknown_file_type_number, type, + sizeof(type)); + (void)printf("%c%s%c", LSOF_FID_TYPE, type, Terminator); + lc++; + } + +#if defined(HASFSTRUCT) + if (FieldSel[LSOF_FIX_FA].st && (Fsv & FSV_FA) && (Lf->fsv & FSV_FA)) { + (void)printf("%c%s%c", LSOF_FID_FA, + print_kptr(Lf->fsa, (char *)NULL, 0), Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_CT].st && (Fsv & FSV_CT) && (Lf->fsv & FSV_CT)) { + (void)printf("%c%ld%c", LSOF_FID_CT, Lf->fct, Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_FG].st && (Fsv & FSV_FG) && (Lf->fsv & FSV_FG) && + (FsvFlagX || Lf->ffg || Lf->pof)) { + (void)printf("%c%s%c", LSOF_FID_FG, + print_fflags(ctx, Lf->ffg, Lf->pof), Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_NI].st && (Fsv & FSV_NI) && (Lf->fsv & FSV_NI)) { + (void)printf("%c%s%c", LSOF_FID_NI, + print_kptr(Lf->fna, (char *)NULL, 0), Terminator); + lc++; + } +#endif /* defined(HASFSTRUCT) */ + + if (FieldSel[LSOF_FIX_DEVCH].st && Lf->dev_ch && Lf->dev_ch[0]) { + for (cp = Lf->dev_ch; *cp == ' '; cp++) + ; + if (*cp) { + (void)printf("%c%s%c", LSOF_FID_DEVCH, cp, Terminator); + lc++; + } + } + if (FieldSel[LSOF_FIX_DEVN].st && Lf->dev_def) { + if (sizeof(unsigned long) > sizeof(dev_t)) + ul = (unsigned long)((unsigned int)Lf->dev); + else + ul = (unsigned long)Lf->dev; + (void)printf("%c0x%lx%c", LSOF_FID_DEVN, ul, Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_RDEV].st && Lf->rdev_def) { + if (sizeof(unsigned long) > sizeof(dev_t)) + ul = (unsigned long)((unsigned int)Lf->rdev); + else + ul = (unsigned long)Lf->rdev; + (void)printf("%c0x%lx%c", LSOF_FID_RDEV, ul, Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_SIZE].st && Lf->sz_def) { + putchar(LSOF_FID_SIZE); + + (void)snpf(buf, sizeof(buf), SzOffFmt_d, Lf->sz); + cp = buf; + + (void)printf("%s", cp); + putchar(Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_OFFSET].st && Lf->off_def) { + putchar(LSOF_FID_OFFSET); + + (void)snpf(buf, sizeof(buf), SzOffFmt_0t, Lf->off); + cp = buf; + + len = strlen(cp); + if (OffDecDig && len > (OffDecDig + 2)) { + (void)snpf(buf, sizeof(buf), SzOffFmt_x, Lf->off); + cp = buf; + } + (void)printf("%s", cp); + putchar(Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_INODE].st && Lf->inode_def) { + putchar(LSOF_FID_INODE); + (void)printf("%" INODEPSPEC "d", Lf->inode); + putchar(Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_NLINK].st && Lf->nlink_def) { + (void)printf("%c%ld%c", LSOF_FID_NLINK, Lf->nlink, Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_PROTO].st && + Lf->iproto != LSOF_PROTOCOL_INVALID) { + print_iproto(Lf->iproto, Lf->unknown_proto_number, buf, + sizeof(buf)); + (void)printf("%c%s%c", LSOF_FID_PROTO, buf, Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_STREAM].st && Lf->nm && Lf->is_stream) { + if (strncmp(Lf->nm, "STR:", 4) == 0 || + Lf->iproto == LSOF_PROTOCOL_STR) { + putchar(LSOF_FID_STREAM); + printname(0); + putchar(Terminator); + lc++; + st++; + } + } + if (st == 0 && FieldSel[LSOF_FIX_NAME].st) { + putchar(LSOF_FID_NAME); + printname(0); + putchar(Terminator); + lc++; + } + if (Lf->lts.type >= 0 && FieldSel[LSOF_FIX_TCPTPI].st) { + print_tcptpi(ctx, 0); + lc++; + } + if (Terminator == '\0' && lc) + putchar('\n'); + } + return (rv); +} + +#if defined(HASFSTRUCT) +static char *alloc_fflbuf(struct lsof_context *ctx, char **bp, int *al, int lr); +/* + * print_fflags() - print interpreted f_flag[s] + */ + +char *print_fflags(struct lsof_context *ctx, + long ffg, /* file structure's flags value */ + long pof) /* process open files flags value */ +{ + int al, ct, fx; + static int bl = 0; + static char *bp = (char *)NULL; + char *sep; + int sepl; + struct pff_tab *tp; + long wf; + char xbuf[64]; + /* + * Reduce the supplied flags according to the definitions in Pff_tab[] and + * Pof_tab[]. + */ + for (ct = fx = 0; fx < 2; fx++) { + if (fx == 0) { + sep = ""; + sepl = 0; + tp = Pff_tab; + wf = ffg; + } else { + sep = ";"; + sepl = 1; + tp = Pof_tab; + wf = pof; + } + for (; wf && !FsvFlagX; ct += al) { + while (tp->nm) { + if (wf & tp->val) + break; + tp++; + } + if (!tp->nm) + break; + al = (int)strlen(tp->nm) + sepl; + bp = alloc_fflbuf(ctx, &bp, &bl, al + ct); + (void)snpf(bp + ct, al + 1, "%s%s", sep, tp->nm); + sep = ","; + sepl = 1; + wf &= ~(tp->val); + } + /* + * If flag bits remain, print them in hex. If hex output was + * specified with +fG, print all flag values, including zero, + * in hex. + */ + if (wf || FsvFlagX) { + (void)snpf(xbuf, sizeof(xbuf), "0x%lx", wf); + al = (int)strlen(xbuf) + sepl; + bp = alloc_fflbuf(ctx, &bp, &bl, al + ct); + (void)snpf(bp + ct, al + 1, "%s%s", sep, xbuf); + ct += al; + } + } + /* + * Make sure there is at least a NUL terminated reply. + */ + if (!bp) { + bp = alloc_fflbuf(ctx, &bp, &bl, 0); + *bp = '\0'; + } + return (bp); +} + +/* + * alloc_fflbuf() - allocate file flags print buffer + */ + +static char *alloc_fflbuf(struct lsof_context *ctx, + char **bp, /* current buffer pointer */ + int *al, /* current allocated length */ + int lr) /* length required */ +{ + int sz; + + sz = (int)(lr + 1); /* allocate '\0' space */ + if (*bp && (sz <= *al)) + return (*bp); + if (*bp) + *bp = (char *)realloc((MALLOC_P *)*bp, (MALLOC_S)sz); + else + *bp = (char *)malloc((MALLOC_S)sz); + if (!*bp) { + (void)fprintf(stderr, "%s: no space (%d) for print flags\n", Pn, sz); + Error(ctx); + } + *al = sz; + return (*bp); +} +#endif /* defined(HASFSTRUCT) */ \ No newline at end of file diff --git a/src/ptti.c b/src/ptti.c index ae3e005d..9311d173 100644 --- a/src/ptti.c +++ b/src/ptti.c @@ -28,27 +28,12 @@ * 4. This notice may not be removed or altered. */ -#define TCPSTATES /* activate tcpstates[] */ - #include "common.h" #include "machine.h" #if defined(USE_LIB_PRINT_TCPTPI) -/* - * build_IPstates() -- build the TCP and UDP state tables - * - * Note: this module does not support a UDP state table. - */ - -void build_IPstates(struct lsof_context *ctx) { - - /* - * Set the TcpNstates global variable. - */ - TcpNstates = TCP_NSTATES; - TcpSt = (char **)&tcpstates; -} +# include "cli.h" /* * print_tcptpi() - print TCP/TPI info @@ -1349,7 +1334,4 @@ void print_tcptpi(struct lsof_context *ctx, int nl) /* 1 == '\n' required */ if (nl) putchar('\n'); } -#else /* !defined(USE_LIB_PRINT_TCPTPI) */ -char ptti_d1[] = "d"; -char *ptti_d2 = ptti_d1; #endif /* defined(USE_LIB_PRINT_TCPTPI) */ diff --git a/src/store.c b/src/store.c index 58abe110..66d331ca 100644 --- a/src/store.c +++ b/src/store.c @@ -29,22 +29,12 @@ */ #include "common.h" +#include "cli.h" /* * Global storage definitions */ -int AllProc = 1; /* all processes are selected (default) */ - -#if defined(HASBLKDEV) -struct l_dev *BDevtp = (struct l_dev *)NULL; -/* block device table pointer */ -int BNdev = 0; /* number of entries in BDevtp[] */ -struct l_dev **BSdev = (struct l_dev **)NULL; -/* pointer to BDevtp[] pointers, sorted - * by device */ -#endif /* defined(HASBLKDEV) */ - int CkPasswd = 0; /* time to check /etc/passwd for change */ #if defined(HAS_STD_CLONE) @@ -52,85 +42,36 @@ struct clone *Clone = (struct clone *)NULL; /* clone device list */ #endif /* defined(HAS_STD_CLONE) */ -int CmdColW; /* COMMAND column width */ -struct str_lst *Cmdl = (struct str_lst *)NULL; -/* command names selected with -c */ +int CmdColW; /* COMMAND column width */ int CmdLim = CMDL; /* COMMAND column width limit */ -int Cmdni = 0; /* command name inclusions selected with -c */ -int Cmdnx = 0; /* command name exclusions selected with -c */ -lsof_rx_t *CmdRx = (lsof_rx_t *)NULL; -/* command regular expression table */ #if defined(HASSELINUX) -cntxlist_t *CntxArg = (cntxlist_t *)NULL; -/* security context arguments supplied with - * -Z */ int CntxColW; /* security context column width */ int CntxStatus = 0; /* security context status: 0 == disabled, * 1 == enabled */ #endif /* defined(HASSELINUX) */ #if defined(HASDCACHE) -unsigned DCcksum; /* device cache file checksum */ -int DCfd = -1; /* device cache file descriptor */ -FILE *DCfs = (FILE *)NULL; /* stream pointer for DCfd */ -char *DCpathArg = (char *)NULL; /* device cache path from -D[b|r|u] */ -char *DCpath[] = { /* device cache paths, indexed by DCpathX - *when it's >= 0 */ - (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL}; -int DCpathX = -1; /* device cache path index: - * -1 = path not defined - * 0 = defined via -D - * 1 = defined via HASENVDC - * 2 = defined via HASSYSDC - * 3 = defined via HASPERSDC and - * HASPERSDCPATH */ -int DCrebuilt = 0; /* an unsafe device cache file has been - * rebuilt */ -int DCstate = 3; /* device cache state: - * 0 = ignore (-Di) - * 1 = build (-Db[path]) - * 2 = read; don't rebuild (-Dr[path]) - * 3 = update; read and rebuild if - * necessary (-Du[path]) - */ -int DCunsafe = 0; /* device cache file is potentially unsafe, - * (The [cm]time check failed.) */ -#endif /* defined(HASDCACHE) */ +#endif /* defined(HASDCACHE) */ int DChelp = 0; /* -D? status */ -int DevColW; /* DEVICE column width */ -dev_t DevDev; /* device number of /dev or its equivalent */ -struct l_dev *Devtp = (struct l_dev *)NULL; -/* device table pointer */ +int DevColW; /* DEVICE column width */ /* * Externals for a stkdir(), dumbed-down for older AIX compilers. */ -char **Dstk = (char **)NULL; /* the directory stack */ -int Dstkx = 0; /* Dstk[] index */ -int Dstkn = 0; /* Dstk[] entries allocated */ -efsys_list_t *Efsysl = (efsys_list_t *)NULL; -/* file systems for which kernel blocks are - * to be eliminated */ -int ErrStat = 0; /* path stat() error count */ uid_t Euid; /* effective UID of this lsof process */ -int Fand = 0; /* -a option status */ -int Fblock = 0; /* -b option status */ int FcColW; /* FCT column width */ int Fcntx = 0; /* -Z option status */ int FdColW; /* FD column width */ -int FeptE = 0; /* -E option status: 0==none, 1==info, - * 2==info+files */ int Ffilesys = 0; /* -f option status: * 0 = paths may be file systems * 1 = paths are just files * 2 = paths must be file systems */ #if defined(HASNCACHE) -int Fncache = 1; /* -C option status */ int NcacheReload = 1; /* 1 == call ncache_load() */ #endif /* defined(HASNCACHE) */ @@ -138,17 +79,8 @@ int Ffield = 0; /* -f and -F status */ int FgColW; /* FILE-FLAG column width */ int Fhelp = 0; /* -h option status */ int Fhost = 1; /* -H option status */ -int Fnet = 0; /* -i option status: 0==none - * 1==find all - * 2==some found*/ -int FnetTy = 0; /* Fnet type request: 0==all - * 4==IPv4 - * 6==IPv6 */ -int Fnfs = 0; /* -N option status: 0==none, 1==find all, - * 2==some found*/ int Fnlink = 0; /* -L option status */ int Foffset = 0; /* -o option status */ -int Fovhd = 0; /* -O option status */ int Fport = 1; /* -P option status */ #if !defined(HASNORPC_H) @@ -167,35 +99,17 @@ int FsColW; /* FSTR-ADDR column width */ int Fsv = FSV_DEFAULT; /* file struct value selections */ int FsvByf = 0; /* Fsv was set by +f */ int FsvFlagX = 0; /* hex format status for FSV_FG */ -int Ftask = 0; /* -K option value */ int NiColW; /* NODE-ID column width */ char *NiTtl = NITTL; /* NODE-ID column title */ int FsearchErr = 1; /* -Q option status */ int Ftcptpi = TCPTPI_STATE; /* -T option status */ int Fterse = 0; /* -t option status */ -int Funix = 0; /* -U option status */ int Futol = 1; /* -l option status */ int Fverbose = 0; /* -V option status */ -#if defined(WARNINGSTATE) -int Fwarn = 1; /* +|-w option status */ -#else /* !defined(WARNINGSTATE) */ -int Fwarn = 0; /* +|-w option status */ -#endif /* defined(WARNINGSTATE) */ - -#if defined(HASXOPT_VALUE) -int Fxopt = HASXOPT_VALUE; /* -X option status */ -#endif /* defined(HASXOPT_VALUE) */ - int Fxover = 0; /* -x option value */ int Fzone = 0; /* -z option status */ -struct fd_lst *Fdl = (struct fd_lst *)NULL; -/* file descriptors selected with -d */ -int FdlTy = -1; /* Fdl[] type: -1 == none - * 0 == include - * 1 == exclude */ - struct fieldsel FieldSel[] = { {LSOF_FID_ACCESS, 0, LSOF_FNM_ACCESS, NULL, 0}, /* 0 */ {LSOF_FID_CMD, 0, LSOF_FNM_CMD, NULL, 0}, /* 1 */ @@ -231,108 +145,27 @@ struct fieldsel FieldSel[] = { {' ', 0, NULL, NULL, 0}}; int Hdr = 0; /* header print status */ -int IgnTasks = 0; /* ignore tasks when non-zero */ -char *InodeFmt_d = (char *)NULL; -/* INODETYPE decimal printf specification */ -char *InodeFmt_x = (char *)NULL; -/* INODETYPE hexadecimal printf specification */ int LastPid = -1; /* last PID listed (for eliminating duplicates * in terse output) */ -struct lfile *Lf = (struct lfile *)NULL; -/* current local file structure */ -struct lproc *Lp = (struct lproc *)NULL; -/* current local process table entry */ -struct lproc *Lproc = (struct lproc *)NULL; -/* local process table */ -int MaxFd; /* maximum file descriptors to close */ -char *Memory = (char *)NULL; /* core file path */ -int MntSup = 0; /* mount supplement state: 0 == none - * 1 == create - * 2 == read */ -char *MntSupP = (char *)NULL; /* mount supplement path -- if MntSup == 2 */ #if defined(HASPROCFS) -struct mounts *Mtprocfs = (struct mounts *)NULL; -/* /proc mount entry */ #endif /* defined(HASPROCFS) */ -int Mxpgid = 0; /* maximum process group ID table entries */ -int Mxpid = 0; /* maximum PID table entries */ -int Mxuid = 0; /* maximum UID table entries */ -gid_t Mygid; /* real GID of this lsof process */ -int Mypid; /* lsof's process ID */ -uid_t Myuid; /* real UID of this lsof process */ -char *Namech = (char *)NULL; /* name characters for printing */ -size_t Namechl = (size_t)0; /* sizeof(Namech) */ -int NCmdRxU = 0; /* number of CmdRx[] entries */ -int Ndev = 0; /* number of entries in Devtp[] */ - -#if defined(HASNLIST) -struct NLIST_TYPE *Nl = (struct NLIST_TYPE *)NULL; -/* kernel name list */ -int Nll = 0; /* Nl calloc'd length */ -#endif /* defined(HASNLIST) */ - -long Nlink = 0l; /* report nlink values below this number - * (0 = report all nlink values) */ -int Nlproc = 0; /* number of entries in Lproc[] */ -int NlColW; /* NLINK column width */ -int NmColW; /* NAME column width */ -char *Nmlst = (char *)NULL; /* namelist file path */ -int NodeColW; /* NODE column width */ -int Npgid = 0; /* -g option count */ -int Npgidi = 0; /* -g option inclusion count */ -int Npgidx = 0; /* -g option exclusion count */ -int Npid = 0; /* -p option count */ -int Npidi = 0; /* -p option inclusion count */ -int Npidx = 0; /* -p option exclusion count */ -int Npuns; /* number of unselected PIDs (starts at Npid) */ -int Ntype; /* node type (see N_* symbols) */ -int Nuid = 0; /* -u option count */ -int Nuidexcl = 0; /* -u option count of UIDs excluded */ -int Nuidincl = 0; /* -u option count of UIDs included */ -struct nwad *Nwad = (struct nwad *)NULL; +int NlColW; /* NLINK column width */ +int NmColW; /* NAME column width */ +int NodeColW; /* NODE column width */ /* list of network addresses */ int OffDecDig = OFFDECDIG; /* offset decimal form (0t...) digit limit */ int OffColW; /* OFFSET column width */ int PgidColW; /* PGID column width */ int PidColW; /* PID column width */ -struct lfile *Plf = (struct lfile *)NULL; -/* previous local file structure */ -char *Pn; /* program name */ -int PpidColW; /* PPID column width */ - -#if defined(HASPROCFS) -int Procfind = 0; /* 1 when searching for an proc file system - * file and one was found */ -struct procfsid *Procfsid = (struct procfsid *)NULL; -/* proc file system PID search table */ -int Procsrch = 0; /* 1 if searching for any proc file system - * file */ -#endif /* defined(HASPROCFS) */ +int PpidColW; /* PPID column width */ -int PrPass = 0; /* print pass: 0 = compute column widths - * 1 = print */ -int RptTm = 0; /* repeat time -- set by -r */ -int RptMaxCount = 0; /* count of repeasts: 0 = no limit - * -- set by -r */ -struct l_dev **Sdev = (struct l_dev **)NULL; -/* pointer to Devtp[] pointers, sorted - * by device */ -int SelAll = 0; /* SELALL flags, modified by IgnTasks */ -int Selflags = 0; /* selection flags -- see SEL* in lsof.h */ -int SelProc = 0; /* SELPROC flags, modified by IgnTasks */ -int Setgid = 0; /* setgid state */ -int Selinet = 0; /* select only Internet socket files */ -int Setuidroot = 0; /* setuid-root state */ -struct sfile *Sfile = (struct sfile *)NULL; -/* chain of files to search for */ -struct int_lst *Spgid = (struct int_lst *)NULL; -/* process group IDs to search for */ -struct int_lst *Spid = (struct int_lst *)NULL; -/* Process IDs to search for */ -struct seluid *Suid = (struct seluid *)NULL; -/* User IDs to include or exclude */ +int PrPass = 0; /* print pass: 0 = compute column widths + * 1 = print */ +int RptTm = 0; /* repeat time -- set by -r */ +int RptMaxCount = 0; /* count of repeasts: 0 = no limit + * -- set by -r */ int SzColW; /* SIZE column width */ int SzOffColW; /* SIZE/OFF column width */ char *SzOffFmt_0t = (char *)NULL; /* SZOFFTYPE 0t%u printf specification */ @@ -344,44 +177,12 @@ int TaskCmdLim = TASKCMDL; /* TASKCMD column width limit (same as * CmdLim) */ int TaskPrtCmd = 0; /* task print task command flag */ int TaskPrtTid = 0; /* task print TID flag */ -int TcpStAlloc = 0; /* allocated (possibly unused) entries in TCP - * state tables */ -unsigned char *TcpStI = (unsigned char *)NULL; -/* included TCP states */ -int TcpStIn = 0; /* number of entries in TcpStI[] */ -int TcpStOff = 0; /* offset for TCP state number to adjust - * negative numbers to an index into TcpSt[], - * TcpStI[] and TcpStX[] */ -unsigned char *TcpStX = (unsigned char *)NULL; -/* excluded TCP states */ -int TcpStXn = 0; /* number of entries in TcpStX[] */ -int TcpNstates = 0; /* number of TCP states -- either in - * tcpstates[] or TcpSt[] */ -char **TcpSt = (char **)NULL; /* local TCP state names, indexed by system - * state value */ -char Terminator = '\n'; /* output field terminator */ -int TaskTidColW = 0; /* task TID column width */ -int TmLimit = TMLIMIT; /* Readlink() and stat() timeout (seconds) */ -int TypeColW; /* TYPE column width */ -int UdpStAlloc = 0; /* allocated (possibly unused) entries in UDP - * state tables */ -unsigned char *UdpStI = (unsigned char *)NULL; -/* included UDP states */ -int UdpStIn = 0; /* number of entries in UdpStI[] */ -int UdpStOff = 0; /* offset for UDP state number to adjust - * negative numbers to an index into UdpSt[], - * UdpStI[] and UdpStX[] */ -unsigned char *UdpStX = (unsigned char *)NULL; -/* excluded UDP states */ -int UdpStXn = 0; /* number of entries in UdpStX[] */ -int UdpNstates = 0; /* number of UDP states in UdpSt[] */ -char **UdpSt = (char **)NULL; /* local UDP state names, indexed by system - * state number */ -int UserColW; /* USER column width */ +char Terminator = '\n'; /* output field terminator */ +int TaskTidColW = 0; /* task TID column width */ +int TypeColW; /* TYPE column width */ +int UserColW; /* USER column width */ -#if defined(HASZONES) -znhash_t **ZoneArg = (znhash_t **)NULL; -/* zone arguments supplied with -z */ -#endif /* defined(HASZONES) */ +int ZoneColW; /* ZONE column width */ -int ZoneColW; /* ZONE column width */ \ No newline at end of file +/** liblsof context */ +struct lsof_context *ctx = NULL; diff --git a/src/usage.c b/src/usage.c index b1dcc1e8..25a45c72 100644 --- a/src/usage.c +++ b/src/usage.c @@ -32,8 +32,8 @@ static char copyright[] = "Copyright 1998 Purdue Research Foundation. All rights reserved."; #include "common.h" -#include "cli.h" #include "version.h" +#include "cli.h" /* * Local function prototypes @@ -41,8 +41,7 @@ static char copyright[] = static char *isnullstr(char *s); static int print_in_col(int col, char *cp); -static void report_HASDCACHE(struct lsof_context *ctx, int type, char *ttl, - char *det); +static void report_HASDCACHE(int type, char *ttl, char *det); static void report_HASKERNIDCK(char *pfx, char *verb); static void report_SECURITY(char *pfx, char *punct); static void report_WARNDEVACCESS(char *pfx, char *verb, char *punct); @@ -51,7 +50,8 @@ static void report_WARNDEVACCESS(char *pfx, char *verb, char *punct); * isnullstr() - is it a null string? */ -static char *isnullstr(char *s) /* string pointer */ +static char *isnullstr(s) +char *s; /* string pointer */ { if (!s) return ((char *)NULL); @@ -67,8 +67,9 @@ static char *isnullstr(char *s) /* string pointer */ * print_in_col() -- print character string in help column */ -static int print_in_col(int col, /* column number */ - char *cp) /* what to print */ +static int print_in_col(col, cp) +int col; /* column number */ +char *cp; /* what to print */ { if (cp && *cp) { switch (col) { @@ -91,13 +92,13 @@ static int print_in_col(int col, /* column number */ * report_HASDCACHE() -- report device cache file state */ -static void report_HASDCACHE(struct lsof_context *ctx, /* context */ - int type, /* type: 0 == read path report - * 1 == full report */ - char *ttl, /* title lines prefix - * (NULL if none) */ - char *det) /* detail lines prefix - * (NULL if none) */ +static void report_HASDCACHE(type, ttl, + det) int type; /* type: 0 == read path report + * 1 == full report */ +char *ttl; /* title lines prefix + * (NULL if none) */ +char *det; /* detail lines prefix + * (NULL if none) */ { #if defined(HASDCACHE) @@ -285,10 +286,10 @@ char *punct; /* punctuation */ * usage() - display usage and exit */ -void usage(struct lsof_context *ctx, /* context */ - int err, /* it is called as part of error handlng? */ - int fh, /* ``-F ?'' status */ - int version) /* ``-v'' status */ +void usage(err, fh, + version) int err; /* it is called as part of error handlng? */ +int fh; /* ``-F ?'' status */ +int version; /* ``-v'' status */ { char buf[MAXPATHLEN + 1], *cp, *cp1, *cp2; int col, i; @@ -450,7 +451,7 @@ void usage(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "Use the ``-h'' option to get more help information.\n"); if (!fh) - Exit(ctx, err ? LSOF_ERROR : LSOF_SUCCESS); + Exit(ctx, err ? LSOF_EXIT_ERROR : LSOF_EXIT_SUCCESS); } if (Fhelp) { (void)fprintf( @@ -797,7 +798,7 @@ void usage(struct lsof_context *ctx, /* context */ (void)report_SECURITY(NULL, "; "); (void)report_WARNDEVACCESS(NULL, NULL, ";"); (void)report_HASKERNIDCK(" k", NULL); - (void)report_HASDCACHE(ctx, 0, NULL, NULL); + (void)report_HASDCACHE(0, NULL, NULL); #if defined(DIALECT_WARNING) (void)fprintf(stderr, "WARNING: %s\n", DIALECT_WARNING); @@ -859,7 +860,7 @@ void usage(struct lsof_context *ctx, /* context */ #if defined(HASDCACHE) if (DChelp) - report_HASDCACHE(ctx, 1, NULL, " "); + report_HASDCACHE(1, NULL, " "); #endif /* defined(HASDCACHE) */ if (version) { @@ -991,7 +992,7 @@ void usage(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, " WARNING: %s\n", DIALECT_WARNING); #endif /* defined(DIALECT_WARNING) */ - (void)report_HASDCACHE(ctx, 1, " ", "\t"); + (void)report_HASDCACHE(1, " ", "\t"); } - Exit(ctx, err ? LSOF_ERROR : LSOF_SUCCESS); + Exit(ctx, err ? LSOF_EXIT_ERROR : LSOF_EXIT_SUCCESS); } diff --git a/src/util.c b/src/util.c index d3fd374f..f618bf96 100644 --- a/src/util.c +++ b/src/util.c @@ -1,6 +1,6 @@ /* * dutil.c - AIX utility functions whose compilation conflicts with the - * general header file tree defined by lsof.h and dlsof.h -- e.g., + * general header file tree defined by common.h and dlsof.h -- e.g., * the conflict between and for the time(2) * and localtime(3) functions * @@ -43,9 +43,10 @@ * file distractions */ -int util_strftime(char *fmtr, /* format output receiver */ - int fmtl, /* sizeof(*fmtr) */ - char *fmt) /* format */ +int util_strftime(fmtr, fmtl, fmt) +char *fmtr; /* format output receiver */ +int fmtl; /* sizeof(*fmtr) */ +char *fmt; /* format */ { #if defined(HAS_STRFTIME) diff --git a/tests/LTbasic.c b/tests/LTbasic.c index a8b3b31f..1d541012 100644 --- a/tests/LTbasic.c +++ b/tests/LTbasic.c @@ -58,8 +58,9 @@ static char *tstlsof(char **texec, char **tkmem, char **tproc); * Main program for dialects that support locking tests. */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char buf[2048]; /* temporary buffer */ char *em; /* error message pointer */ @@ -135,11 +136,13 @@ static void cleanup() {} * tstlsof() -- test for the lsof process */ -static char *tstlsof(char **texec, /* result of the executable test */ - char **tkmem, /* result of the /dev/kmem test */ - char **tproc) /* result of the lsof process test */ +static char *tstlsof(texec, tkmem, tproc) +char **texec; /* result of the executable test */ +char **tkmem; /* result of the /dev/kmem test */ +char **tproc; /* result of the lsof process test */ { char buf[2048]; /* temporary buffer */ + char buf2[2048] = {0}; /* temporary buffer */ char *cem; /* current error message pointer */ LTfldo_t *cmdp; /* command pointer */ LTdev_t cwddc; /* CWD device components */ @@ -172,7 +175,15 @@ static char *tstlsof(char **texec, /* result of the executable test */ /* * Get lsof executable's stat(2) information. */ - if (stat(LsofPath, &lsofsb)) { + /* lsof could be a wrapper script when building with libtool, try + * ./.libs/lsof first */ + (void)snprintf(buf, sizeof(buf) - 1, "%s", LsofPath); + if (strlen(buf) >= 4) { + /* strip lsof suffix */ + buf[strlen(buf) - 4] = '\0'; + (void)snprintf(buf2, sizeof(buf2) - 1, "%s.libs/lsof", buf); + } + if ((buf2[0] && stat(buf2, &lsofsb)) && stat(LsofPath, &lsofsb)) { (void)snprintf(buf, sizeof(buf) - 1, "ERROR!!! stat(%s): %s", LsofPath, strerror(errno)); buf[sizeof(buf) - 1] = '\0'; diff --git a/tests/LTbasic2.c b/tests/LTbasic2.c new file mode 100644 index 00000000..4ad9024d --- /dev/null +++ b/tests/LTbasic2.c @@ -0,0 +1,99 @@ +/* + * LTbasic2.c -- Lsof Test basic tests 2 + * + * The basic tests measure the finding by liblsof of its own open CWD, open + * executable (when possible). + * + * V. Abell + * Purdue University + */ + +/* + * Copyright 2002 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by V. Abell. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "lsof.h" +#include +#include + +int main(int argc, char **argv) { + struct lsof_result *result; + struct lsof_context *ctx; + struct lsof_process *p; + struct lsof_file *f; + int pi, fi; + char buffer[128]; + int exec_found = 0; /* executable found in result */ + int cwd_found = 0; /* cwd found in result */ + struct stat exec_stat; + struct stat cwd_stat; + if (stat(argv[0], &exec_stat)) { + fprintf(stderr, "Cannot stat %s, skipping executable check\n", argv[0]); + exec_found = 1; + } + if (stat(".", &cwd_stat)) { + fprintf(stderr, "Cannot stat '.', skipping cwd check\n"); + cwd_found = 1; + } + + ctx = lsof_new(); + lsof_select_process(ctx, "LTbasic2", 0); + lsof_freeze(ctx); + lsof_gather(ctx, &result); + + for (pi = 0; pi < result->num_processes; pi++) { + p = &result->processes[pi]; + for (fi = 0; fi < p->num_files; fi++) { + f = &p->files[fi]; + if (f->fd_type == LSOF_FD_PROGRAM_TEXT) { + /* check if device and inode matches */ + if ((f->flags & + (LSOF_FILE_FLAG_DEV_VALID | LSOF_FILE_FLAG_INODE_VALID)) && + f->dev == exec_stat.st_dev && + f->inode == exec_stat.st_ino) { + exec_found = 1; + } + } else if (f->fd_type == LSOF_FD_CWD) { + /* check if device and inode matches */ + if ((f->flags & + (LSOF_FILE_FLAG_DEV_VALID | LSOF_FILE_FLAG_INODE_VALID)) && + f->dev == cwd_stat.st_dev && f->inode == cwd_stat.st_ino) { + cwd_found = 1; + } + } + } + } + + lsof_free_result(result); + lsof_destroy(ctx); + + if (!exec_found) { + fprintf(stderr, "ERROR!!! open LTbasic2 executable wasn't found.\n"); + } + if (!cwd_found) { + fprintf(stderr, "ERROR!!! current working directory wasn't found.\n"); + } + return !(exec_found && cwd_found); +} \ No newline at end of file diff --git a/tests/LTbigf.c b/tests/LTbigf.c index f6416328..e1975e67 100644 --- a/tests/LTbigf.c +++ b/tests/LTbigf.c @@ -44,8 +44,9 @@ * Main program for dialects that don't support large files */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char *pn; /* program name */ /* @@ -261,8 +262,9 @@ static int tstwlsof(int tt, char *opt, OFFSET_T sz); * Main program for dialects that support large files */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char buf[2048]; /* temporary buffer */ int do_offt = OFFTST_STAT; /* do offset tests if == 1 */ @@ -509,9 +511,10 @@ static void cleanup() { * tstwlsof() -- test the open file with lsof */ -static int tstwlsof(int tt, /* test type -- i.e., TST_* */ - char *opt, /* additional lsof options */ - OFFSET_T sz) /* expected size (and offset) */ +static int tstwlsof(tt, opt, sz) +int tt; /* test type -- i.e., TST_* */ +char *opt; /* additional lsof options */ +OFFSET_T sz; /* expected size (and offset) */ { char buf[2048], buf1[2048]; /* temporary buffers */ LTfldo_t *cmdp; /* command pointer */ diff --git a/tests/LTdnlc.c b/tests/LTdnlc.c index 3f1b3776..072d878a 100644 --- a/tests/LTdnlc.c +++ b/tests/LTdnlc.c @@ -88,8 +88,9 @@ static char *FindLsofCwd(int *ff, LTdev_t *cwddc, char *ibuf); * Main program */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char buf[2048]; /* temporary buffer */ char cwd[MAXPATHLEN + 1]; /* CWD */ @@ -252,9 +253,10 @@ static void cleanup() {} * FindLsofCwd() -- find the lsof CWD */ -static char *FindLsofCwd(int *ff, /* file-found response receptor */ - LTdev_t *cwddc, /* CWD device components */ - char *ibuf) /* CWD inode number in ASCII */ +static char *FindLsofCwd(ff, cwddc, ibuf) +int *ff; /* file-found response receptor */ +LTdev_t *cwddc; /* CWD device components */ +char *ibuf; /* CWD inode number in ASCII */ { char *cp; /* temporary character pointer */ char *cem; /* current error message pointer */ diff --git a/tests/LTlib.c b/tests/LTlib.c index 6cf8fe58..1913b90e 100644 --- a/tests/LTlib.c +++ b/tests/LTlib.c @@ -145,16 +145,14 @@ # define minor_S(dev) ((int)(dev & L_MAXMIN)) # if defined(LT_DEV64) - # undef X2DEV_T # define X2DEV_T unsigned long long # undef XDINDEV # define XDINDEV 16 -# endif /* !defined(LT_DEV64) */ +# endif /* defined(LT_DEV64) */ # define major_X(dp, em) (major_S(x2dev(dp, em))) # define minor_X(dp, em) (minor_S(x2dev(dp, em))) - #endif /* defined(LT_DIAL_solaris) */ #if defined(LT_DIAL_uw) @@ -318,10 +316,11 @@ static void closepipe() { * Note: this function is dialect-specific. */ -char *ConvLsofDev(char *dev, /* lsof device string -- the value to the - * LSOF_FID_DEVN field of a LSOF_FID_FD block - * (see lsof_fields.h) */ - LTdev_t *ldev) /* results are returned to this structure */ +char *ConvLsofDev(dev, ldev) +char *dev; /* lsof device string -- the value to the + * LSOF_FID_DEVN field of a LSOF_FID_FD block + * (see lsof_fields.h) */ +LTdev_t *ldev; /* results are returned to this structure */ { char *dp; /* device pointer */ char *em; /* error message pointer */ @@ -359,8 +358,9 @@ char *ConvLsofDev(char *dev, /* lsof device string -- the value to the * Note: this function is dialect-specific. */ -char *ConvStatDev(dev_t *dev, /* device number to be converted */ - LTdev_t *ldev) /* results are returned to this structure */ +char *ConvStatDev(dev, ldev) +dev_t *dev; /* device number to be converted */ +LTdev_t *ldev; /* results are returned to this structure */ { /* @@ -384,9 +384,10 @@ char *ConvStatDev(dev_t *dev, /* device number to be converted */ * in a child process */ -char *ExecLsof(char **opt) /* lsof options -- a pointer to an - * array of character pointers, - * terminated by a NULL pointer */ +char *ExecLsof(opt) +char **opt; /* lsof options -- a pointer to an + * array of character pointers, + * terminated by a NULL pointer */ { static char **av = (char **)NULL; /* lsof argument vector, dynamically * allocated */ @@ -556,11 +557,13 @@ static void getlsofpath() { * value doesn't have one -- e.g., has a default instead. */ -static int GetOpt(int ct, /* option count */ - char *opt[], /* options */ - char *rules, /* option rules */ - char **em, /* error message return */ - char *pn) { +static int GetOpt(ct, opt, rules, em, pn) +int ct; /* option count */ +char *opt[]; /* options */ +char *rules; /* option rules */ +char **em; /* error message return */ +char *pn; +{ register int c; /* character value */ register char *cp = (char *)NULL; /* character pointer */ char embf[2048]; /* error message buffer */ @@ -780,8 +783,9 @@ int xv; /* exit value */ * RdFrLsof() -- read from lsof */ -LTfldo_t *RdFrLsof(int *nf, /* number of fields receiver */ - char **em) /* error message pointer receiver */ +LTfldo_t *RdFrLsof(nf, em) +int *nf; /* number of fields receiver */ +char **em; /* error message pointer receiver */ { char buf[2048]; /* temporary buffer */ int bufl = (int)sizeof(buf); /* size of buf[] */ @@ -922,10 +926,11 @@ LTfldo_t *RdFrLsof(int *nf, /* number of fields receiver */ * ScanArg() -- scan arguments */ -int ScanArg(int ac, /* argument count */ - char *av[], /* argument pointers */ - char *opt, /* option string */ - char *pn) /* program name */ +int ScanArg(ac, av, opt, pn) +int ac; /* argument count */ +char *av[]; /* argument pointers */ +char *opt; /* option string */ +char *pn; /* program name */ { char *em; /* pointer to error message returned by * GetOpt() */ @@ -1007,8 +1012,9 @@ void StopLsof() { * x2dev() -- convert hex string to device number */ -static X2DEV_T x2dev(char *x, /* hex string */ - char **em) /* error message receiver */ +static X2DEV_T x2dev(x, em) +char *x; /* hex string */ +char **em; /* error message receiver */ { char buf[2048]; /* temporary message buffer */ int c; /* character holder */ diff --git a/tests/LTlock.c b/tests/LTlock.c index 60aa0f3f..5cb62ed7 100644 --- a/tests/LTlock.c +++ b/tests/LTlock.c @@ -167,8 +167,9 @@ * Main program for dialects that don't support flock() of fcntl() locking. */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char *pn; /* program name */ /* @@ -214,23 +215,25 @@ static char *unlkfile(int ty); * Main program for dialects that support locking tests. */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { - char buf[2048]; /* temporary buffer */ - char *em; /* error message pointer */ - int ti; /* temporary index */ - char *tcp; /* temporary character pointer */ - int tlen; /* temporary length -- e.g., as - * returned by MkStrCpy() */ - char *tstR = (char *)NULL; /* "R" lock test result */ - char *tstr = (char *)NULL; /* "r" lock test result */ - char *tstW = (char *)NULL; /* "W" lock test result */ - char *tstw = (char *)NULL; /* "w" lock test result */ - int xv = 0; /* exit value */ - /* - * Get program name and PID, issue start message, and build space prefix. - */ + char buf[2048]; /* temporary buffer */ + char *em; /* error message pointer */ + int ti; /* temporary index */ + char *tcp; /* temporary character pointer */ + int tlen; /* temporary length -- e.g., as + * returned by MkStrCpy() */ + char *tstR = (char *)NULL; /* "R" lock test result */ + char *tstr = (char *)NULL; /* "r" lock test result */ + char *tstW = (char *)NULL; /* "W" lock test result */ + char *tstw = (char *)NULL; /* "w" lock test result */ + char *tstNFS = (char *)NULL; /* NFS test result */ + int xv = 0; /* exit value */ + /* + * Get program name and PID, issue start message, and build space prefix. + */ if ((Pn = strrchr(argv[0], '/'))) Pn++; else @@ -305,7 +308,7 @@ int main(int argc, /* argument count */ /* * Quit (with a hint) if the test file is on an NFS file system. */ - if (!tstwlsof("-wNa", " ")) { + if (!(tstNFS = tstwlsof("-wNa", " "))) { (void)printf("ERROR!!! %s is NFS-mounted.\n", Path); MsgStat = 1; (void)PrtMsg("Lsof can't report lock information on files that", Pn); @@ -412,7 +415,8 @@ static void cleanup() { * lkfile() -- lock the test file */ -static char *lkfile(int ty) /* a *_*_LOCK requested */ +static char *lkfile(ty) +int ty; /* a *_*_LOCK requested */ { char buf[2048]; /* temporary buffer */ int ti; /* temporary integer */ @@ -496,8 +500,9 @@ static char *lkfile(int ty) /* a *_*_LOCK requested */ * tstwlsof() -- test the open file with lsof */ -static char *tstwlsof(char *opt, /* extra lsof options */ - char *xlk) /* expected lock value */ +static char *tstwlsof(opt, xlk) +char *opt; /* extra lsof options */ +char *xlk; /* expected lock value */ { char buf[2048]; /* temporary buffer */ LTfldo_t *cmdp; /* command pointer */ @@ -675,7 +680,8 @@ static char *tstwlsof(char *opt, /* extra lsof options */ * unlkfile() -- unlock the test file */ -static char *unlkfile(int ty) /* current *_*_LOCK lock typ */ +static char *unlkfile(ty) +int ty; /* current *_*_LOCK lock typ */ { char buf[2048]; /* temporary buffer */ int ti; /* temporary integer */ diff --git a/tests/LTnfs.c b/tests/LTnfs.c index df28412f..730c4c14 100644 --- a/tests/LTnfs.c +++ b/tests/LTnfs.c @@ -77,8 +77,9 @@ static char *FindNFSfile(int *ff, char *szbuf); * Main program */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char buf[2048]; /* temporary buffer */ char *em; /* error message pointer */ @@ -262,9 +263,10 @@ static void cleanup() { * FindNFSfile() -- find the NFS file with lsof */ -static char *FindNFSfile(int *ff, /* file-found response receptor */ - char *szbuf) /* expected file size in ASCII (if - * the file was created by this test */ +static char *FindNFSfile(ff, szbuf) +int *ff; /* file-found response receptor */ +char *szbuf; /* expected file size in ASCII (if + * the file was created by this test */ { char buf[2048]; /* temporary buffer */ char *cem; /* current error message pointer */ diff --git a/tests/LTnlink.c b/tests/LTnlink.c index a61136be..4b1e2094 100644 --- a/tests/LTnlink.c +++ b/tests/LTnlink.c @@ -76,8 +76,9 @@ static char *FindFile(char *opt, int *ff, int ie, LTdev_t *tfdc, char *ibuf, * Main program */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char buf[2048]; /* temporary buffer */ int do_unlink = 1; /* do the unlink test section */ @@ -331,13 +332,14 @@ static void cleanup() { * FindFile() -- find a file with lsof */ -static char *FindFile(char *opt, /* additional lsof options */ - int *ff, /* file-found response receptor */ - int ie, /* ignore errors if == 1 */ - LTdev_t *tfdc, /* test file device components */ - char *ibuf, /* inode number in ASCII */ - char *xlnk, /* expected link count */ - char *szbuf) /* file size in ASCII */ +static char *FindFile(opt, ff, ie, tfdc, ibuf, xlnk, szbuf) +char *opt; /* additional lsof options */ +int *ff; /* file-found response receptor */ +int ie; /* ignore errors if == 1 */ +LTdev_t *tfdc; /* test file device components */ +char *ibuf; /* inode number in ASCII */ +char *xlnk; /* expected link count */ +char *szbuf; /* file size in ASCII */ { char buf[2048]; /* temporary buffer */ char *cem; /* current error message pointer */ diff --git a/tests/LTshm2.c b/tests/LTshm2.c new file mode 100644 index 00000000..9f579820 --- /dev/null +++ b/tests/LTshm2.c @@ -0,0 +1,121 @@ +/* + * LTshm2.c -- Lsof Test POSIX shm test using liblsof + * + * V. Abell + * Purdue University + */ + +/* + * Copyright 2002 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by V. Abell. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "lsof.h" +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + struct lsof_result *result = NULL; + struct lsof_context *ctx = NULL; + struct lsof_process *p; + struct lsof_file *f; + int ti, pi, fi; + char buf[128]; + int my_pid, fd; + int shm_found = 0; + int shm_path_correct = 0; + int res = 0; + char shm_name[128]; + int shm; + + my_pid = getpid(); + (void)snprintf(shm_name, sizeof(shm_name), "/LTshm2%ld.shm", (long)my_pid); + + /* + * Create a named shm + */ + if ((shm = shm_open(shm_name, O_RDONLY | O_CREAT, 0644)) < 0) { + (void)fprintf(stderr, "ERROR!!! can't create shm at %s\n", shm_name); + res = 1; + goto cleanup; + } + + ctx = lsof_new(); + lsof_select_pid(ctx, my_pid, 0); + lsof_freeze(ctx); + lsof_gather(ctx, &result); + + for (pi = 0; pi < result->num_processes; pi++) { + p = &result->processes[pi]; + if (p->pid != my_pid) + continue; + for (fi = 0; fi < p->num_files; fi++) { + f = &p->files[fi]; + if (f->fd_type == LSOF_FD_NUMERIC && f->fd_num == shm) { + /* shm can be implemented as a regular file */ + if (f->file_type != LSOF_FILE_POSIX_SHM && + f->file_type != LSOF_FILE_REGULAR && + f->file_type != LSOF_FILE_VNODE_VREG) { + (void)fprintf(stderr, + "ERROR!!! found non-shm file type %d\n", + f->file_type); + res = 1; + goto cleanup; + } + shm_found = 1; + + /* on Linux, f->name is /dev/shm/LTshm2... */ + if (!f->name || strstr(f->name, shm_name) != NULL) { + shm_path_correct = 1; + } + } + } + } + + if (!shm_found) { + fprintf(stderr, "ERROR!!! shm %s not found by lsof\n", shm_name); + res = 1; + } + if (!shm_path_correct) { + fprintf(stderr, "ERROR!!! shm %s path incorrect\n", shm_name); + res = 1; + } + +cleanup: + if (result) { + lsof_free_result(result); + } + if (ctx) { + lsof_destroy(ctx); + } + if (shm) { + shm_unlink(shm_name); + } + return res; +} diff --git a/tests/LTsock.c b/tests/LTsock.c index 7c582e18..a7fe6ef8 100644 --- a/tests/LTsock.c +++ b/tests/LTsock.c @@ -171,19 +171,20 @@ int Ssock = -1; /* server socket */ * Local function prototypes */ -static void CleanupClnt(void); -static void CleanupSrvr(void); -static SIGHANDLER_T HandleClntAlarm(int sig); -static SIGHANDLER_T HandleSrvrAlarm(int sig); -static char *FindSock(int fn); -static void StartClnt(struct sockaddr_in *cad); +static void CleanupClnt (void); +static void CleanupSrvr (void); +static SIGHANDLER_T HandleClntAlarm (int sig); +static SIGHANDLER_T HandleSrvrAlarm (int sig); +static char *FindSock (int fn); +static void StartClnt (struct sockaddr_in * cad); /* * Main program */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { struct sockaddr_in aa; /* accept address */ struct sockaddr_in ba; /* bind address */ @@ -471,8 +472,10 @@ int main(int argc, /* argument count */ "ERROR!!! no %s socket by host and port: %s@%s", PtNm[ti], host, port); buf[bufl - 1] = '\0'; - if (pem) + if (pem) { (void)PrtMsg(pem, Pn); + free(pem); + } pem = MkStrCpy(buf, &tk); } if (!(tj & LT_FBYIP)) { @@ -484,8 +487,10 @@ int main(int argc, /* argument count */ "ERROR!!! no %s socket by IP and port: %s@%s", PtNm[ti], ipaddr, port); buf[bufl - 1] = '\0'; - if (pem) + if (pem) { (void)PrtMsg(pem, Pn); + free(pem); + } pem = MkStrCpy(buf, &tk); } if (!(tj & LT_FBYPORT)) { @@ -497,14 +502,18 @@ int main(int argc, /* argument count */ "ERROR!!! no %s socket by port: %s", PtNm[ti], port); buf[bufl - 1] = '\0'; - if (pem) + if (pem) { (void)PrtMsg(pem, Pn); + free(pem); + } pem = MkStrCpy(buf, &tk); } } } - if (pem) + if (pem) { (void)PrtMsgX(pem, Pn, CleanupSrvr, 1); + free(pem); + } /* * Exit successfully. */ @@ -561,7 +570,8 @@ static void CleanupSrvr() { * FindSock() -- find sockets with lsof */ -static char *FindSock(int fn) /* function -- an LT_FBY* value */ +static char *FindSock(fn) +int fn; /* function -- an LT_FBY* value */ { char buf[2048]; /* temporary buffer */ int bufl = sizeof(buf); /* size of buf[] */ @@ -629,6 +639,12 @@ static char *FindSock(int fn) /* function -- an LT_FBY* value */ opv[ti] = (char *)NULL; if ((cem = ExecLsof(opv))) return (cem); + + /* Free MkStrCpy space */ + for (tj = 1;tj <= NFDPARA;tj++) { + free(opv[tj]); + } + /* * Read lsof output. */ @@ -764,7 +780,8 @@ static char *FindSock(int fn) /* function -- an LT_FBY* value */ * HandleClntAlarm() -- handle client alarm */ -static SIGHANDLER_T HandleClntAlarm(int sig) /* the signal (SIGALRM) */ +static SIGHANDLER_T HandleClntAlarm(sig) +int sig; /* the signal (SIGALRM) */ { (void)PrtMsgX("ERROR!!! client caught an alarm signal", Pn, CleanupClnt, 1); @@ -774,7 +791,8 @@ static SIGHANDLER_T HandleClntAlarm(int sig) /* the signal (SIGALRM) */ * Handle SrvrAlarm() -- handle server alarm */ -static SIGHANDLER_T HandleSrvrAlarm(int sig) /* the signal (SIGALRM) */ +static SIGHANDLER_T HandleSrvrAlarm(sig) +int sig; /* the signal (SIGALRM) */ { (void)PrtMsgX("ERROR!!! server caught an alarm signal.", Pn, CleanupSrvr, 1); diff --git a/tests/LTszoff.c b/tests/LTszoff.c index 148a8910..56bb4a54 100644 --- a/tests/LTszoff.c +++ b/tests/LTszoff.c @@ -83,8 +83,9 @@ static char *testlsof(int tt, char *opt, char *xval); * Main program */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char buf[2048]; /* temporary buffer */ int do_offt = OFFTST_STAT; /* do offset tests if == 1 */ @@ -273,9 +274,10 @@ static void cleanup() { * testlsof() -- test the open file with lsof */ -static char *testlsof(int tt, /* test type -- TYTST_* symbol */ - char *opt, /* extra lsof options */ - char *xval) /* expected value */ +static char *testlsof(tt, opt, xval) +int tt; /* test type -- TYTST_* symbol */ +char *opt; /* extra lsof options */ +char *xval; /* expected value */ { char buf[2048]; /* temporary buffer */ char *cem; /* current error message pointer */ diff --git a/tests/LTszoff2.c b/tests/LTszoff2.c new file mode 100644 index 00000000..8fcfe325 --- /dev/null +++ b/tests/LTszoff2.c @@ -0,0 +1,154 @@ +/* + * LTszoff2.c -- Lsof Test small file (< 32 bits) size and offset tests + * + * V. Abell + * Purdue University + */ + +/* + * Copyright 2002 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by V. Abell. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "lsof.h" +#include +#include +#include +#include + +#define TSTFSZ 32768 /* test file size */ + +int main(int argc, char **argv) { + struct lsof_result *result = NULL; + struct lsof_context *ctx = NULL; + struct lsof_process *p; + struct lsof_file *f; + int ti, pi, fi; + char path[128], buf[128]; + int my_pid, fd; + int fd_found = 0; + int sz_correct = 0; + int off_correct = 0; + int res = 0; + + my_pid = getpid(); + (void)snprintf(path, sizeof(path), "./config.LTszoff%ld", (long)my_pid); + + /* + * Open a new test file at the specified path. + */ + (void)unlink(path); + if ((fd = open(path, O_RDWR | O_CREAT, 0600)) < 0) { + (void)fprintf(stderr, "ERROR!!! can't open %s\n", path); + res = 1; + goto cleanup; + } + + /* + * Write the test file to its expected size. + */ + for (ti = 0; ti < sizeof(buf); ti++) { + buf[ti] = (char)(ti & 0xff); + } + for (ti = 0; ti < TSTFSZ; ti += sizeof(buf)) { + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) { + (void)fprintf(stderr, "ERROR!!! can't write %d bytes to %s\n", + (int)sizeof(buf), path); + res = 1; + goto cleanup; + } + } + /* + * Fsync() the file. + */ + if (fsync(fd)) { + (void)fprintf(stderr, "ERROR!!! can't fsync %s\n", path); + res = 1; + goto cleanup; + } + + ctx = lsof_new(); + /* filter by PID and FD */ + lsof_select_pid(ctx, my_pid, 0); + lsof_select_fd(ctx, LSOF_FD_NUMERIC, fd, fd, 0); + lsof_logic_and(ctx); + lsof_freeze(ctx); + lsof_gather(ctx, &result); + + for (pi = 0; pi < result->num_processes; pi++) { + p = &result->processes[pi]; + if (p->pid != my_pid) { + (void)fprintf(stderr, "ERROR!!! found not selected pid %d\n", + p->pid); + res = 1; + goto cleanup; + } + for (fi = 0; fi < p->num_files; fi++) { + f = &p->files[fi]; + if (f->fd_type == LSOF_FD_NUMERIC && f->fd_num == fd) { + /* check if fd, size and offset matches */ + fd_found = 1; + if ((f->flags & LSOF_FILE_FLAG_SIZE_VALID) && + f->size == TSTFSZ) { + sz_correct = 1; + } + if ((f->flags & LSOF_FILE_FLAG_OFFSET_VALID) && + f->offset == TSTFSZ) { + off_correct = 1; + } + } else { + (void)fprintf(stderr, "ERROR!!! found not selected fd %d\n", + f->fd_num); + res = 1; + goto cleanup; + } + } + } + + if (!fd_found) { + fprintf(stderr, "ERROR!!! test file %s not found by lsof\n", path); + res = 1; + } + if (!sz_correct) { + fprintf(stderr, "ERROR!!! test file %s size incorrect\n", path); + res = 1; + } + if (!off_correct) { + fprintf(stderr, "ERROR!!! test file %s offset incorrect\n", path); + res = 1; + } + +cleanup: + if (result) { + lsof_free_result(result); + } + if (ctx) { + lsof_destroy(ctx); + } + if (fd >= 0) { + (void)close(fd); + (void)unlink(path); + } + return res; +} \ No newline at end of file diff --git a/tests/LTunix.c b/tests/LTunix.c index 46c544b4..9e794d4b 100644 --- a/tests/LTunix.c +++ b/tests/LTunix.c @@ -59,15 +59,16 @@ char *Path[2] = {(char *)NULL, (char *)NULL}; * Local function prototypes */ -static void cleanup(void); -static char *FindUsocks(void); +static void cleanup (void); +static char *FindUsocks (void); /* * Main program */ -int main(int argc, /* argument count */ - char *argv[]) /* arguments */ +int main(argc, argv) +int argc; /* argument count */ +char *argv[]; /* arguments */ { char buf[2048]; /* temporary buffer */ char cwd[MAXPATHLEN + 1]; /* CWD buffer */ diff --git a/tests/LTunix2.c b/tests/LTunix2.c new file mode 100644 index 00000000..bd3cec89 --- /dev/null +++ b/tests/LTunix2.c @@ -0,0 +1,128 @@ +/* + * LTunix2.c -- Lsof Test UNIX domain socket test using liblsof + * + * V. Abell + * Purdue University + */ + +/* + * Copyright 2002 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by V. Abell. + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#include "lsof.h" +#include +#include +#include +#include +#include +#include + +int main(int argc, char **argv) { + struct lsof_result *result = NULL; + struct lsof_context *ctx = NULL; + struct lsof_process *p; + struct lsof_file *f; + int ti, pi, fi; + char path[128], buf[128]; + int my_pid, fd; + int fd_found = 0; + int path_correct = 0; + int res = 0; + struct sockaddr_un ua; /* UNIX socket address */ + + my_pid = getpid(); + (void)snprintf(path, sizeof(path), "/tmp/config.LTunix%ld", (long)my_pid); + + /* + * Create a unix socket at the specified path + */ + (void)unlink(path); + if ((fd = socket(AF_UNIX, SOCK_STREAM, PF_UNSPEC)) < 0) { + (void)fprintf(stderr, "ERROR!!! can't create unix socket at %s\n", + path); + res = 1; + goto cleanup; + } + (void)memset((void *)&ua, 0, sizeof(ua)); + ua.sun_family = AF_UNIX; + snprintf(ua.sun_path, sizeof(ua.sun_path), "%s", path); + + if (bind(fd, (struct sockaddr *)&ua, sizeof(ua)) != 0) { + (void)fprintf(stderr, "ERROR!!! can't create unix socket at %s\n", + path); + res = 1; + goto cleanup; + } + + ctx = lsof_new(); + lsof_select_unix_socket(ctx); + lsof_freeze(ctx); + lsof_gather(ctx, &result); + + for (pi = 0; pi < result->num_processes; pi++) { + p = &result->processes[pi]; + if (p->pid != my_pid) + continue; + for (fi = 0; fi < p->num_files; fi++) { + f = &p->files[fi]; + if (f->file_type != LSOF_FILE_UNIX) { + (void)fprintf(stderr, "ERROR!!! found non-unix file type %d\n", + f->file_type); + res = 1; + goto cleanup; + } + if (f->fd_type == LSOF_FD_NUMERIC && f->fd_num == fd) { + /* check if name matches, only consider prefix because it can be + * `/some/path type=STREAM` */ + fd_found = 1; + if (strncmp(f->name, path, strlen(path)) == 0) { + path_correct = 1; + } + } + } + } + + if (!fd_found) { + fprintf(stderr, "ERROR!!! test file %s not found by lsof\n", path); + res = 1; + } + if (!path_correct) { + fprintf(stderr, "ERROR!!! test file %s path incorrect\n", path); + res = 1; + } + +cleanup: + if (result) { + lsof_free_result(result); + } + if (ctx) { + lsof_destroy(ctx); + } + if (fd >= 0) { + (void)close(fd); + (void)unlink(path); + } + return res; +} diff --git a/tests/TestDB b/tests/TestDB index ee7c9406..057d807a 100644 --- a/tests/TestDB +++ b/tests/TestDB @@ -149,5 +149,3 @@ LT_BIGF LT_CC LT_DIAL_linux LT_VERS=50009 _FILE_OFFSET_BITS=64 LT_BIGF LT_CC LT_DIAL_linux LT_VERS=60005 _FILE_OFFSET_BITS=64 LT_CC LT_DIAL_darwin LT_VERS=1900 LT_BIGF LT_CC LT_DIAL_darwin LT_VERS=1900 -LT_BIGF LT_CC LT_DIAL_openbsd LT_VERS=7020 -LT_BIGF LT_CC LT_DIAL_openbsd LT_VERS=7030 diff --git a/tests/case-14-classic-opt.bash b/tests/case-14-classic-opt.bash index 61133e92..a151d540 100755 --- a/tests/case-14-classic-opt.bash +++ b/tests/case-14-classic-opt.bash @@ -23,7 +23,7 @@ base=$(pwd) s=1 fi - if [ -n "$CI" ] && { [ "$dialect" = "darwin" ] || [ "$dialect" = "openbsd" ]; }; then + if [ -n "$CI" ] && [ "$dialect" = "darwin" ]; then : # TODO: temporary skip this elif ! grep -q "LTlock \.\.\. OK" $f; then echo '"LTlock ... OK" is not found in the output' >> $report diff --git a/tests/case-23-c-option.bash b/tests/case-23-c-option.bash new file mode 100755 index 00000000..292192a9 --- /dev/null +++ b/tests/case-23-c-option.bash @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +source tests/common.bash + +file=$(mktemp /tmp/case-23-c-option.XXXXXX) + +# lsof -clsof finds itself +$lsof -n -clsof > $file & +pid=$! +wait $pid +cat "$file" | grep "^lsof *${pid}" || exit 1 + +# lsof -c^lsof excludes itself +$lsof -n -c^lsof > $file & +pid=$! +wait $pid +cat "$file" | grep "^lsof *${pid}" && exit 1 + +# lsof -c/lsof/ includes itself +$lsof -n -c/lsof/ > $file & +pid=$! +wait $pid +cat "$file" | grep "^lsof *${pid}" || exit 1 + +# try multiple filters +$lsof -n -clsof -cbash -c/lsof/ > $file & +pid=$! +wait $pid +cat "$file" | grep "^lsof *${pid}" || exit 1 + +# terse output +$lsof -n -clsof -t > $file & +pid=$! +wait $pid +cat "$file" | grep "^${pid}$" || exit 1 \ No newline at end of file