diff --git a/00DIST b/00DIST index d5f24d23..f808146b 100644 --- a/00DIST +++ b/00DIST @@ -5563,6 +5563,11 @@ Supplement Regenerated the 4.04 distribution to correct a non- [aix] Suppress warnings properly on AIX version greater than 5.0. Closes #187. + + Introduce alpha version of liblsof which allows users to use + lsof functionality via C functions instead of spawning a + subprocess and parsing the output. This version may contain BUGs + and memory leaks, and the API may change before it stablizes. 4.9?.? ????????? ??, ???? diff --git a/Makefile.am b/Makefile.am index e356d3da..c777a99f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,21 +1,19 @@ -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/lsof.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 +25,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 +37,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 +48,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 +59,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 +71,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 +84,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 +97,28 @@ 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 -# 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 +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 +# TODO: link to dynamic library instead after internal functions are no longer used +lsof_SOURCES += $(liblsof_la_SOURCES) +#lsof_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 # 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 \ @@ -193,3 +197,24 @@ 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 +check_PROGRAMS += tests/LTbasic2 +tests_LTbasic2_CFLAGS = -I$(top_srcdir)/include +tests_LTbasic2_LDADD = liblsof.la + +# 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 \ No newline at end of file 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 2ad063ed..f8f4d480 100644 --- a/include/lsof.h +++ b/include/lsof.h @@ -35,6 +35,7 @@ #if !defined(LSOF_H) # define LSOF_H 1 +# include # include /** lsof error returns */ @@ -230,6 +231,160 @@ enum lsof_file_type { LSOF_FILE_VNODE_VPORT, /**< The vnode represents a port */ }; +/** @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, +}; + +/** 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; + + /* NAME column */ + /** File name or description */ + char *name; +}; + +/** 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 @@ -274,7 +429,7 @@ struct lsof_context *lsof_new(); * \since API version 1 */ enum lsof_error lsof_set_output_stream(struct lsof_context *ctx, FILE *fp, - char *program_name, int warn); + char *program_name, int warn); /** Ask lsof to avoid using blocking functions * @@ -317,4 +472,49 @@ enum lsof_error lsof_logic_and(struct lsof_context *ctx); enum lsof_error lsof_select_process(struct lsof_context *ctx, char *command, int exclude); +/** Freeze the lsof context + * + * You can only call it once per context. After this call, no more options can + * be changed. + * + * The function allows liblsof to do some preprocessing to improve performance. + * + * \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()` + * + * If the context is not frozen, lsof_freeze() will be called. + * + * \return LSOF_INVALID_ARGUMENT if either pointer argument is NULL + * + * \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 \ No newline at end of file diff --git a/lib/common.h b/lib/common.h index b555ac48..8c45df8f 100644 --- a/lib/common.h +++ b/lib/common.h @@ -671,7 +671,6 @@ struct str_lst { short x; /* exclusion (if non-zero) */ struct str_lst *next; /* next list entry */ }; -extern int CmdLim; typedef struct cntxlist { char *cntx; /* zone name */ @@ -694,8 +693,6 @@ extern int NcacheReload; # endif /* defined(HASNCACHE) */ extern int Fnlink; -extern int Foffset; - extern int Fport; # if !defined(HASNORPC_H) @@ -705,11 +702,8 @@ extern int FportMap; 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 Ftcptpi; extern int Fterse; extern int Funix; @@ -748,10 +742,10 @@ struct lfile { 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 + * 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 */ @@ -960,7 +954,6 @@ extern struct NLIST_TYPE *Nl; extern int Nll; # endif /* defined(HASNLIST) */ extern char *Nmlst; -extern int Ntype; struct nwad { char *arg; /* argument */ @@ -1001,7 +994,6 @@ extern int Procsrch; # endif /* defined(HASPROCFS) */ extern int PrPass; -extern int RptTm; extern int RptMaxCount; extern char *SzOffFmt_0t; extern char *SzOffFmt_d; @@ -1167,9 +1159,15 @@ struct lsof_context { /* zone arguments supplied with -z */ znhash_t **sel_zone; + /* command name limit */ + int cmd_limit; + /** When frozen, parameters must not be changed */ uint8_t frozen; + /* node type (see N_* symbols) */ + int node_type; + /* device table pointer */ struct l_dev *dev_table; int dev_table_size; /* number of entries in dev_table[] */ @@ -1302,6 +1300,21 @@ struct lsof_context { * AF_INET==IPv4 * AF_INET6==IPv6 */ + /* Fsv was set by +f */ + int fsv_set_f; + + /* hex format status for FSV_FG */ + int fsv_hex; + + /* repeat time -- set by -r */ + int repeat_time; + + /* -o option status */ + int show_offset; + + /* -s option status */ + int show_size; + /** Temporary */ /* name characters for printing */ char *name_buf; @@ -1501,6 +1514,20 @@ struct lsof_context { # define HbyCdCt (ctx->sfile_hash_clone_count) /* solaris zone */ # define ZoneArg (ctx->sel_zone) +/* command name limit */ +# define CmdLim (ctx->cmd_limit) +/* node type */ +# define Ntype (ctx->node_type) +/* Fsv was set by +f */ +# define FsvByf (ctx->fsv_set_f) +/* hex format status for FSV_FG */ +# define FsvFlagX (ctx->fsv_hex) +/* repeat time */ +# define RptTm (ctx->repeat_time) +/* -o option status */ +# define Foffset (ctx->show_offset) +/* -s option status */ +# define Fsize (ctx->show_size) /* Utility macro to free if non-null and set the pointer to null */ # define CLEAN(ptr) \ diff --git a/lib/dialects/freebsd/dstore.c b/lib/dialects/freebsd/dstore.c index 6f5b709b..fe709340 100644 --- a/lib/dialects/freebsd/dstore.c +++ b/lib/dialects/freebsd/dstore.c @@ -112,3 +112,11 @@ 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/linux/dmnt.c b/lib/dialects/linux/dmnt.c index 15ad8f2b..9d3fa217 100644 --- a/lib/dialects/linux/dmnt.c +++ b/lib/dialects/linux/dmnt.c @@ -675,6 +675,7 @@ 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) Lmi = mp; diff --git a/lib/dialects/linux/dnode.c b/lib/dialects/linux/dnode.c index 94dd810a..725c52ee 100644 --- a/lib/dialects/linux/dnode.c +++ b/lib/dialects/linux/dnode.c @@ -679,7 +679,7 @@ 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)snpf(buf, sizeof(buf), "%" INODEPSPEC "u", inode); (void)fprintf( stderr, "%s: can't allocate llock: PID %d; dev %x; inode %s\n", Pn, pid, (int)dev, buf); diff --git a/lib/dialects/linux/dproc.c b/lib/dialects/linux/dproc.c index b9bfc8de..cb6bb64f 100644 --- a/lib/dialects/linux/dproc.c +++ b/lib/dialects/linux/dproc.c @@ -659,13 +659,6 @@ void initialize(struct lsof_context *ctx) { 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 @@ -1132,35 +1125,32 @@ static int process_id(struct lsof_context *ctx, /* context */ /* * Process the PID's SELinux context. */ - if (Fcntx) { + /* + * 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); + } + } + } else if (CntxArg) { /* - * If the -Z (cntx) option was specified, match the valid contexts. + * See if context includes the process. */ - 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); - } - } - } 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; - } + 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; } } } @@ -1597,8 +1587,8 @@ process_proc_map(struct lsof_context *ctx, /* context */ } else sep = "(path "; if ((INODETYPE)sb.st_ino != inode) { - (void)snpf(fmtbuf, sizeof(fmtbuf), "%%sinode=%s)", - InodeFmt_d); + (void)snpf(fmtbuf, sizeof(fmtbuf), + "%%sinode=%%" INODEPSPEC "u)"); (void)snpf(nmabuf, sizeof(nmabuf), fmtbuf, sep, (INODETYPE)sb.st_ino); nmabuf[sizeof(nmabuf) - 1] = '\0'; diff --git a/lib/dialects/linux/dsock.c b/lib/dialects/linux/dsock.c index 29b20f1e..297a22a2 100644 --- a/lib/dialects/linux/dsock.c +++ b/lib/dialects/linux/dsock.c @@ -1081,7 +1081,7 @@ static void prt_uxs(struct lsof_context *ctx, uxsin_t *p, /* peer info */ (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 "u", p->inode); (void)add_nma(ctx, nma, strlen(nma)); for (pp = p->pxinfo; pp; pp = pp->next) { @@ -3412,136 +3412,6 @@ static void print_ipxinfo(struct lsof_context *ctx, /* context */ Lf->nma = cp; } -/* - * 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, /* context */ - 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'); -} - /* * process_proc_sock() - process /proc-based socket */ @@ -3781,7 +3651,8 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ (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 "u", + (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); } @@ -4026,7 +3897,8 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, pr); 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 "u", + (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); Lf->inode = (INODETYPE)s->st_ino; @@ -4139,7 +4011,8 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ (void)snpf(Lf->iproto, sizeof(Lf->iproto), "%.*s", IPROTOL - 1, pr); 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 "u", + (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); Lf->inode = (INODETYPE)s->st_ino; @@ -4193,7 +4066,7 @@ void process_proc_sock(struct lsof_context *ctx, /* context */ Lf->type = LSOF_FILE_SOCKET; (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); + (void)snpf(tbuf, sizeof(tbuf), "%" INODEPSPEC "u", (INODETYPE)s->st_ino); tbuf[sizeof(tbuf) - 1] = '\0'; enter_dev_ch(ctx, tbuf); Namech[0] = '\0'; @@ -4564,35 +4437,6 @@ 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(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) */ - /* * ethernet_proto_to_str() -- convert ethernet protocol number to a string * diff --git a/lib/lsof.c b/lib/lsof.c index d284f425..f0d570fc 100644 --- a/lib/lsof.c +++ b/lib/lsof.c @@ -55,6 +55,12 @@ struct lsof_context *lsof_new() { /* Initialization */ memset(ctx, 0, sizeof(struct lsof_context)); + if (!(Namech = (char *)malloc(MAXPATHLEN + 1))) { + free(ctx); + return NULL; + } + Namechl = (size_t)(MAXPATHLEN + 1); + #if defined(WARNINGSTATE) /* suppress warnings */ Fwarn = 1; @@ -88,6 +94,9 @@ struct lsof_context *lsof_new() { /* device cache state: 3 = update; read and rebuild if necessary */ DCstate = 3; + + /* COMMAND column width limit */ + CmdLim = CMDL; } return ctx; } @@ -196,7 +205,7 @@ enum lsof_error lsof_select_process(struct lsof_context *ctx, char *command, API_EXPORT enum lsof_error lsof_set_output_stream(struct lsof_context *ctx, FILE *fp, - char *program_name, int warn) { + char *program_name, int warn) { if (!ctx) { return LSOF_ERROR_INVALID_ARGUMENT; } @@ -204,4 +213,541 @@ enum lsof_error lsof_set_output_stream(struct lsof_context *ctx, FILE *fp, ctx->program_name = mkstrcpy(program_name, NULL); ctx->warn = warn; return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_freeze(struct lsof_context *ctx) { + if (ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + 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 LSOF_SUCCESS; +} + +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_freeze(ctx); + if (ret != LSOF_SUCCESS) + return ret; + } + + gather_proc_info(ctx); + + /* Cleanup orphaned cur_file, if any*/ + if (ctx->cur_file) { + CLEAN(ctx->cur_file->dev_ch); + CLEAN(ctx->cur_file->nm); + CLEAN(ctx->cur_file->nma); + 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->inp_ty == 1 || lf->inp_ty == 3) { + f->flags |= LSOF_FILE_FLAG_INODE_VALID; + } + + /* NAME column */ + f->name = lf->nm; + lf->nm = NULL; + } + 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 +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); + + 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(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); } \ No newline at end of file diff --git a/lib/misc.c b/lib/misc.c index 97532caa..3bf71872 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -1027,7 +1027,7 @@ char *Readlink(struct lsof_context *ctx, (void)fprintf(stderr, "): -b was specified.\n"); } op = (char *)NULL; - return (arg); + return mkstrcpy(arg, NULL); } /* * Save the original path. @@ -1131,7 +1131,7 @@ char *Readlink(struct lsof_context *ctx, } sx = 0; op = (char *)NULL; - return (arg); + return mkstrcpy(arg, NULL); } /* * If the assembled path and argument are different, add it to the diff --git a/lib/print.c b/lib/print.c index 96581523..f9feef0c 100644 --- a/lib/print.c +++ b/lib/print.c @@ -439,4 +439,1045 @@ void file_type_to_string(enum lsof_file_type type, (void)snpf(buf, buf_len, "UNNM"); break; } -} \ No newline at end of file +} + +/* + * 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); +} + +void __attribute__((weak)) +usage(struct lsof_context *ctx, /* context */ + int err, /* it is called as part of error handlng? */ + int fh, /* ``-F ?'' status */ + int version) /* ``-v'' status */ +{ + // do nothing in liblsof +} + +#if !defined(HASPRIVPRIPP) +/* + * printiproto() - print Internet protocol name + */ + +void printiproto(struct lsof_context *ctx, /* context */ + 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) */ + +/* + * 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; +} diff --git a/lib/proc.c b/lib/proc.c index 05a3c506..aab349c3 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -79,36 +79,6 @@ 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 */ @@ -481,14 +451,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. */ @@ -612,7 +574,7 @@ int is_file_sel(struct lsof_context *ctx, /* context */ { if (!lf || !lf->sf) return (0); - if (Lf->sf & SELEXCLF) + if (lf->sf & SELEXCLF) return (0); #if defined(HASSECURITY) && defined(HASNOSOCKSECURITY) @@ -1243,327 +1205,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; - char fd[FDLEN]; - char type[TYPEL]; - /* - * 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(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(ctx, 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) { - - fd_to_string(Lf->fd_type, Lf->fd_num, fd); - (void)printf("%c%s%c", LSOF_FID_FD, fd, 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, lock_to_char(Lf->lock), - Terminator); - lc++; - } - if (FieldSel[LSOF_FIX_TYPE].st) { - if (Lf->type != LSOF_FILE_NONE) { - file_type_to_string(Lf->type, Lf->unknown_file_type_number, - type, TYPEL); - (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->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 diff --git a/lib/proto.h b/lib/proto.h index bf686254..83dfb149 100644 --- a/lib/proto.h +++ b/lib/proto.h @@ -183,7 +183,7 @@ extern char *mkstrcat(char *s1, int l1, char *s2, int l2, char *s3, int l3, 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_init(void); +extern void print_init(struct lsof_context *ctx); extern void printname(struct lsof_context *ctx, int nl); extern char *print_kptr(KA_T kp, char *buf, size_t bufl); extern int print_proc(struct lsof_context *ctx); diff --git a/m4/.gitignore b/m4/.gitignore new file mode 100644 index 00000000..f10a1b56 --- /dev/null +++ b/m4/.gitignore @@ -0,0 +1,2 @@ +*.m4 +!header.m4 diff --git a/src/dialects/linux/dprint.c b/src/dialects/linux/dprint.c index e69de29b..f8d84226 100644 --- a/src/dialects/linux/dprint.c +++ b/src/dialects/linux/dprint.c @@ -0,0 +1,199 @@ +/* + * 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, /* context */ + 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/main.c b/src/main.c index 8e2f2c14..adb80085 100644 --- a/src/main.c +++ b/src/main.c @@ -147,11 +147,6 @@ int main(int argc, char *argv[]) { 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. */ @@ -1229,6 +1224,15 @@ int main(int argc, char *argv[]) { * Do dialect-specific initialization. */ initialize(ctx); +#if defined(LINUX_LSOF_H) + if (Fsv && (OffType != OFFSET_FDINFO)) { + if (!Fwarn && FsvByf) + (void)fprintf( + stderr, + "%s: WARNING: can't report file flags; disregarding +f.\n", Pn); + Fsv = 0; + } +#endif if (Sfile) (void)hashSfile(ctx); @@ -1451,7 +1455,7 @@ int main(int argc, char *argv[]) { * malloc()'d area, and since Lf is used throughout the print * process. */ - for (lf = Lf, print_init(); PrPass < 2; PrPass++) { + for (lf = Lf, print_init(ctx); PrPass < 2; PrPass++) { for (i = n = 0; i < Nlproc; i++) { Lp = (Nlproc > 1) ? slp[i] : &Lproc[i]; if (Lp->pss) { diff --git a/src/print.c b/src/print.c index 09f01420..421c34bd 100644 --- a/src/print.c +++ b/src/print.c @@ -93,21 +93,6 @@ static char *lkup_svcnam(struct lsof_context *ctx, int h, int p, int pr, static int printinaddr(struct lsof_context *ctx); 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 @@ -1254,7 +1239,7 @@ static int printinaddr(struct lsof_context *ctx) { * print_init() - initialize for printing */ -void print_init() { +void print_init(struct lsof_context *ctx) { /* * Preset standard values. @@ -1320,660 +1305,6 @@ void print_init() { #endif /* defined(HASZONES) */ } -#if !defined(HASPRIVPRIPP) -/* - * printiproto() - print Internet protocol name - */ - -void printiproto(struct lsof_context *ctx, /* context */ - 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 */ @@ -2384,370 +1715,6 @@ 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 @@ -2819,3 +1786,352 @@ int human_readable_size(SZOFFTYPE sz, int print, int col) { } return strlen(buf); } + +/* + * 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; + char fd[FDLEN]; + char type[TYPEL]; + /* + * 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(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(ctx, 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) { + + fd_to_string(Lf->fd_type, Lf->fd_num, fd); + (void)printf("%c%s%c", LSOF_FID_FD, fd, 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, lock_to_char(Lf->lock), + Terminator); + lc++; + } + if (FieldSel[LSOF_FIX_TYPE].st) { + if (Lf->type != LSOF_FILE_NONE) { + file_type_to_string(Lf->type, Lf->unknown_file_type_number, + type, TYPEL); + (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->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(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) */ + +#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) */ \ No newline at end of file diff --git a/src/store.c b/src/store.c index f58c5d02..8e7dfd25 100644 --- a/src/store.c +++ b/src/store.c @@ -42,7 +42,6 @@ struct clone *Clone = (struct clone *)NULL; #endif /* defined(HAS_STD_CLONE) */ int CmdColW; /* COMMAND column width */ -int CmdLim = CMDL; /* COMMAND column width limit */ #if defined(HASSELINUX) int CntxColW; /* security context column width */ @@ -77,7 +76,6 @@ int FgColW; /* FILE-FLAG column width */ int Fhelp = 0; /* -h option status */ int Fhost = 1; /* -H option status */ int Fnlink = 0; /* -L option status */ -int Foffset = 0; /* -o option status */ int Fport = 1; /* -P option status */ #if !defined(HASNORPC_H) @@ -90,12 +88,9 @@ int FportMap = 0; /* +|-M option status */ int Fpgid = 0; /* -g option status */ int Fppid = 0; /* -R option status */ -int Fsize = 0; /* -s option status */ int Fhuman = 0; /* -H option status */ 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 NiColW; /* NODE-ID column width */ char *NiTtl = NITTL; /* NODE-ID column title */ int FsearchErr = 1; /* -Q option status */ @@ -152,7 +147,6 @@ int LastPid = -1; /* last PID listed (for eliminating duplicates int NlColW; /* NLINK column width */ int NmColW; /* NAME column width */ int NodeColW; /* NODE column width */ -int Ntype; /* node type (see N_* symbols) */ int OffDecDig = OFFDECDIG; /* offset decimal form (0t...) digit limit */ int OffColW; /* OFFSET column width */ int PgidColW; /* PGID column width */ @@ -161,7 +155,6 @@ 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 */ int SzColW; /* SIZE column width */ diff --git a/tests/LTbasic.c b/tests/LTbasic.c index a8b3b31f..3db186bd 100644 --- a/tests/LTbasic.c +++ b/tests/LTbasic.c @@ -140,6 +140,7 @@ static char *tstlsof(char **texec, /* result of the executable test */ char **tproc) /* result of the lsof process test */ { char buf[2048]; /* temporary buffer */ + char buf2[2048] = {}; /* temporary buffer */ char *cem; /* current error message pointer */ LTfldo_t *cmdp; /* command pointer */ LTdev_t cwddc; /* CWD device components */ @@ -172,7 +173,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