diff --git a/Makefile.am b/Makefile.am index 79335061..e356d3da 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ EXTRA_DIST += tests/00README tests/TestDB tests/CkTestDB tests/Makefile tests/Ls # Dialect neutral sources lsof_SOURCES = src/arg.c src/main.c lib/node.c src/print.c src/ptti.c src/store.c src/usage.c src/util.c \ - lib/ckkv.c lib/cvfs.c lib/dvch.c lib/fino.c lib/isfn.c lib/lkud.c lib/misc.c lib/pdvn.c lib/prfp.c lib/print.c lib/proc.c lib/ptti.c lib/rdev.c lib/rnmt.c lib/rmnt.c lib/rnam.c lib/rnch.c lib/rnmh.c + 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 include_HEADERS = include/lsof.h include/lsof_fields.h DIALECT_ROOT = $(top_srcdir)/lib/dialects diff --git a/include/lsof.h b/include/lsof.h index 001b24e0..2ad063ed 100644 --- a/include/lsof.h +++ b/include/lsof.h @@ -35,6 +35,16 @@ #if !defined(LSOF_H) # define LSOF_H 1 +# include + +/** lsof error returns */ +enum lsof_error { + LSOF_SUCCESS = 0, /**< Success */ + LSOF_ERROR_INVALID_ARGUMENT, /**< Invalid argument */ + LSOF_ERROR_NO_MEMORY, /**< No memory */ + LSOF_ERROR_UNSUPPORTED, /**< Unsupported operation */ +}; + /** File access mode */ enum lsof_file_access_mode { LSOF_FILE_ACCESS_NONE = 0, /**< None */ @@ -220,4 +230,91 @@ enum lsof_file_type { LSOF_FILE_VNODE_VPORT, /**< The vnode represents a port */ }; +/** API version of liblsof + * you may use this macro to check the existence of + * functions + */ +# define LSOF_API_VERSION 1 + +/** Get runtime API version of liblsof + * + * liblsof might not function properly if API version mismatched between compile + * time and runtime. + * + * \since API version 1 + */ +int lsof_get_api_version(); + +/** Get library version of liblsof + * + * \return a string like "4.xx.x". The caller must not free it. + * + * \since API version 1 + */ +char *lsof_get_library_version(); + +/** Create a new lsof context + * + * The context should be freed via `lsof_destroy()`. + * + * \since API version 1 + */ +struct lsof_context *lsof_new(); + +/** Set output stream for warning and error messages + * + * lsof may want to print warning and error messages to the user. You can allow + * printing by setting the output stream and whether prints warning or not. You + * should also supply `program_name` so that the output starts with your program + * name. + * + * By default, the output is suppressed. You can set fp to NULL to suppress + * output. + * + * \since API version 1 + */ +enum lsof_error lsof_set_output_stream(struct lsof_context *ctx, FILE *fp, + char *program_name, int warn); + +/** Ask lsof to avoid using blocking functions + * + * lsof may block when calling lstat(), readlink() or stat(). Call this function + * with `avoid=1` to let lsof avoid calling these functions. + * + * \since API version 1 + */ +enum lsof_error lsof_avoid_blocking(struct lsof_context *ctx, int avoid); + +/** Ask lsof to avoid forking + * + * To avoid being blocked by some kernel operations, liblsof does them in forked + * child processes. Call this function to change this behavior. + * + * \since API version 1 + */ +enum lsof_error lsof_avoid_forking(struct lsof_context *ctx, int avoid); + +/** Ask lsof to AND the selections + * + * By default, lsof OR the selections, for example, if you call + * lsof_select_unix_socket() and lsof_select_login(), it will report unix + * sockets OR open files by the user. If lsof_logic_and() is called, it will + * report unix sockets open by the specified user. + * + * \since API version 1 + */ +enum lsof_error lsof_logic_and(struct lsof_context *ctx); + +/** Ask lsof to select process by command + * + * Select process executing the command that begins with the characters of + * `command`. You can specify exclusion by setting `exclude` to 1. + * + * You can call this function multiple times to add more search conditions. + * + * \since API version 1 + */ +enum lsof_error lsof_select_process(struct lsof_context *ctx, char *command, + int exclude); + #endif \ No newline at end of file diff --git a/lib/common.h b/lib/common.h index 52da85a6..4018d903 100644 --- a/lib/common.h +++ b/lib/common.h @@ -29,7 +29,7 @@ */ /* - * $Id: lsof.h,v 1.70 2018/03/26 21:50:45 abe Exp $ + * $Id: common.h,v 1.70 2018/03/26 21:50:45 abe Exp $ */ #include "lsof.h" @@ -253,7 +253,7 @@ struct l_dev { # include "dlsof.h" # include /* just in case -- because utmp.h - * may need it */ + * may need it */ # include # if defined(EMPTY) @@ -584,10 +584,11 @@ extern int ZoneColW; */ enum ExitStatus { - LSOF_SUCCESS, - LSOF_ERROR, + LSOF_EXIT_SUCCESS, + LSOF_EXIT_ERROR, }; -# define LSOF_SEARCH_FAILURE (FsearchErr ? LSOF_ERROR : LSOF_SUCCESS) +# define LSOF_SEARCH_FAILURE \ + (FsearchErr ? LSOF_EXIT_ERROR : LSOF_EXIT_SUCCESS) /* * Structure definitions @@ -604,8 +605,6 @@ struct afsnode { /* AFS pseudo-node structure */ }; # endif /* defined(HAS_AFS) */ -extern int AllProc; - # if defined(HAS_STD_CLONE) struct clone { int dx; /* index of device entry in Devtp[] */ @@ -634,8 +633,6 @@ typedef struct efsys_list { struct mounts *mp; /* local mount table entry pointer */ struct efsys_list *next; /* next efsys_list entry pointer */ } efsys_list_t; -extern efsys_list_t *Efsysl; /* file systems for which kernel blocks - * are to be eliminated */ struct int_lst { int i; /* integer argument */ @@ -649,8 +646,6 @@ typedef struct lsof_rx { /* regular expression table entry */ regex_t cx; /* compiled expression */ int mc; /* match count */ } lsof_rx_t; -extern lsof_rx_t *CmdRx; -extern int NCmdRxU; # if defined(HASFSTRUCT) struct pff_tab { /* print file flags table structure */ @@ -667,11 +662,6 @@ struct seluid { * (meaningful only if excl == 0) */ }; -# if defined(HASBLKDEV) -extern struct l_dev *BDevtp, **BSdev; -extern int BNdev; -# endif /* defined(HASBLKDEV) */ - extern int CkPasswd; struct str_lst { @@ -681,43 +671,18 @@ struct str_lst { short x; /* exclusion (if non-zero) */ struct str_lst *next; /* next list entry */ }; -extern struct str_lst *Cmdl; extern int CmdLim; -extern int Cmdni; -extern int Cmdnx; -# if defined(HASSELINUX) typedef struct cntxlist { char *cntx; /* zone name */ int f; /* "find" flag (used only in CntxArg) */ struct cntxlist *next; /* next zone hash entry */ } cntxlist_t; -extern cntxlist_t *CntxArg; extern int CntxStatus; -# endif /* defined(HASSELINUX) */ - -# if defined(HASDCACHE) -extern unsigned DCcksum; -extern int DCfd; -extern FILE *DCfs; -extern char *DCpathArg; -extern char *DCpath[]; -extern int DCpathX; -extern int DCrebuilt; -extern int DCstate; -extern int DCunsafe; -# endif /* defined(HASDCACHE) */ extern int DChelp; -extern dev_t DevDev; -extern struct l_dev *Devtp; -extern char **Dstk; -extern int Dstkn; -extern int Dstkx; extern int ErrStat; extern uid_t Euid; -extern int Fand; -extern int Fblock; extern int Fcntx; extern int Ffield; extern int Ffilesys; @@ -725,17 +690,11 @@ extern int Fhelp; extern int Fhost; # if defined(HASNCACHE) -extern int Fncache; extern int NcacheReload; # endif /* defined(HASNCACHE) */ -extern int Fnet; -extern int FnetTy; -extern int Fnfs; extern int Fnlink; extern int Foffset; -extern int Fovhd; -extern int FeptE; extern int Fport; @@ -751,17 +710,11 @@ extern int Fhuman; extern int Fsv; extern int FsvByf; extern int FsvFlagX; -extern int Ftask; extern int Ftcptpi; extern int Fterse; extern int Funix; extern int Futol; extern int Fverbose; -extern int Fwarn; - -# if defined(HASXOPT_VALUE) -extern int Fxopt; -# endif /* defined(HASXOPT_VALUE) */ extern int Fxover; extern int Fzone; @@ -773,10 +726,6 @@ struct fd_lst { int hi; /* range end (if nm NULL) */ struct fd_lst *next; }; -extern struct fd_lst *Fdl; -extern int FdlTy; /* Fdl[] type: -1 == none - * 0 == include - * 1 == exclude */ struct fieldsel { char id; /* field ID character */ @@ -790,7 +739,6 @@ extern struct fieldsel FieldSel[]; extern int Hdr; enum IDType { PGID, PID }; -extern int IgnTasks; extern char *InodeFmt_d; extern char *InodeFmt_x; extern int LastPid; @@ -964,7 +912,6 @@ struct lfile { struct lfile *next; }; -extern struct lfile *Lf, *Plf; struct lproc { char *cmd; /* command name */ @@ -998,27 +945,13 @@ struct lproc { struct lfile *file; /* open files of process */ }; -extern struct lproc *Lp, *Lproc; -extern int MaxFd; extern char *Memory; -extern int MntSup; -extern char *MntSupP; # if defined(HASPROCFS) extern struct mounts *Mtprocfs; # endif -extern int Mxpgid; -extern int Mxpid; -extern int Mxuid; -extern gid_t Mygid; -extern int Mypid; -extern uid_t Myuid; -extern char *Namech; -extern size_t Namechl; -extern int Ndev; - # if defined(HASNLIST) # if !defined(NLIST_TYPE) # define NLIST_TYPE nlist @@ -1026,20 +959,8 @@ extern int Ndev; extern struct NLIST_TYPE *Nl; extern int Nll; # endif /* defined(HASNLIST) */ -extern long Nlink; -extern int Nlproc; extern char *Nmlst; -extern int Npgid; -extern int Npgidi; -extern int Npgidx; -extern int Npid; -extern int Npidi; -extern int Npidx; -extern int Npuns; extern int Ntype; -extern int Nuid; -extern int Nuidexcl; -extern int Nuidincl; struct nwad { char *arg; /* argument */ @@ -1055,7 +976,6 @@ struct nwad { extern struct nwad *Nwad; extern int OffDecDig; -extern char *Pn; # if defined(HASFSTRUCT) extern struct pff_tab Pff_tab[]; /* file flags table */ @@ -1083,17 +1003,6 @@ extern int Procsrch; extern int PrPass; extern int RptTm; extern int RptMaxCount; -extern struct l_dev **Sdev; -extern int SelAll; -extern int Selflags; -extern int SelProc; -extern int Setgid; -extern int Selinet; -extern int Setuidroot; -extern struct sfile *Sfile; -extern struct int_lst *Spgid; -extern struct int_lst *Spid; -extern struct seluid *Suid; extern char *SzOffFmt_0t; extern char *SzOffFmt_d; extern char *SzOffFmt_dv; @@ -1110,7 +1019,6 @@ extern int TcpStXn; extern int TcpNstates; extern char **TcpSt; extern char Terminator; -extern int TmLimit; extern int UdpStAlloc; extern unsigned char *UdpStI; extern int UdpStIn; @@ -1120,18 +1028,483 @@ extern int UdpStXn; extern int UdpNstates; extern char **UdpSt; -# if defined(HASZONES) typedef struct znhash { char *zn; /* zone name */ int f; /* "find" flag (used only in ZoneArg) */ struct znhash *next; /* next zone hash entry */ } znhash_t; -extern znhash_t **ZoneArg; -# endif /* defined(HASZONES) */ -struct lsof_context {}; +struct lsof_context { + /** Parameters */ + /** Linked list of files to search */ + struct sfile *select_files; + + /* file systems for which kernel blocks are + * to be eliminated */ + efsys_list_t *elim_fs_list; + + /* User IDs to include or exclude */ + struct seluid *sel_uid; + /* -u option count */ + int sel_uid_size; + /* capacity of sel_uid */ + int sel_uid_cap; + /* -u option count of UIDs excluded */ + int num_uid_excluded; + /* -u option count of UIDs included */ + int num_uid_included; + + /* process group IDs to search for */ + struct int_lst *sel_pgid; + int sel_pgid_size; /* -g option count */ + int sel_pgid_cap; /* capacity of sel_pgid */ + int sel_pgid_incl_num; /* -g option inclusion count */ + int sel_pgid_excl_num; /* -g option exclusion count */ + + /* Process IDs to search for */ + struct int_lst *sel_pid; + int sel_pid_size; /* -p option count */ + int num_unsel_pid; /* number of unselected PIDs (starts at sel_pid_size) for + optimization in examine_lproc() */ + int sel_pid_cap; /* capacity of sel_pid */ + int sel_pid_incl_num; /* -p option inclusion count */ + int sel_pid_excl_num; /* -p option exclusion count */ + + /* Whether all processes are selected */ + int sel_all_proc; + + /* command names selected with -c */ + struct str_lst *sel_cmds; + int sel_cmd_incl; /* number of command name inclusions selected with -c */ + int sel_cmd_excl; /* number of command name exclusions selected with -c */ + + /* command regular expression table for -c option */ + lsof_rx_t *cmd_regex; + int cmd_regex_size; /* number of cmd_regex[] entries */ + int cmd_regex_cap; /* capacity of cmd_regex[] */ + + /* select by network address */ + struct nwad *sel_net_addr; + + /* security context arguments supplied with -Z */ + cntxlist_t *sel_selinux_context; + + /* device cache paths, indexed by DCpathX + * when it's >= 0 */ + char *dev_cache_paths[4]; + int dev_cache_path_index; /* device cache path index: + * -1 = path not defined + * 0 = defined via -D + * 1 = defined via HASENVDC + * 2 = defined via HASSYSDC + * 3 = defined via HASPERSDC and + * HASPERSDCPATH */ + char *dev_cache_path_arg; /* device cache path from -D[b|r|u] */ + unsigned dev_cache_checksum; /* device cache file checksum */ + int dev_cache_fd; /* device cache file descriptor */ + FILE *dev_cache_fp; /* stream pointer for DCfd */ + int dev_cache_rebuilt; /* an unsafe device cache file has been + * rebuilt */ + int dev_cache_state; /* device cache state: + * 0 = ignore (-Di) + * 1 = build (-Db[path]) + * 2 = read; don't rebuild (-Dr[path]) + * 3 = update; read and rebuild if + * necessary (-Du[path]) + */ + int dev_cache_unsafe; /* device cache file is potentially unsafe, + * (The [cm]time check failed.) */ + +# if defined(HASNLIST) + /* kernel name list */ + struct NLIST_TYPE *name_list; + int name_list_size; +# endif /* defined(HASNLIST) */ + char *name_list_path; /* namelist file path */ + char *core_file_path; /* core file path */ + +# if defined(HASPROCFS) + /* /proc mount entry */ + struct mounts *procfs_mount; + int procfs_found; /* 1 when searching for an proc file system + * file and one was found */ + /* proc file system PID search table */ + struct procfsid *procfs_table; + /* 1 if searching for any proc file system + * file */ + int procfs_search; +# endif /* defined(HASPROCFS) */ + + /* name cache */ + int name_cache_enable; /* -C option status */ + + /* local mount info */ + struct mounts *local_mount_info; + int local_mount_info_valid; + + /** hashSfile() buckets */ + /* hash by file (dev,ino) buckets */ + struct hsfile *sfile_hash_file_dev_inode; + int sfile_hash_file_dev_inode_count; + /* hash by file raw device buckets */ + struct hsfile *sfile_hash_file_raw_device; + int sfile_hash_file_raw_device_count; + /* hash by file system buckets */ + struct hsfile *sfile_hash_file_system; + int sfile_hash_file_system_count; + /* hash by name buckets */ + struct hsfile *sfile_hash_name; + int sfile_hash_name_count; + /* hash by clone buckets */ + struct hsfile *sfile_hash_clone; + int sfile_hash_clone_count; + + /* zone arguments supplied with -z */ + znhash_t **sel_zone; + + /** When frozen, parameters must not be changed */ + uint8_t frozen; + + /* device table pointer */ + struct l_dev *dev_table; + int dev_table_size; /* number of entries in dev_table[] */ + /* pointer to dev_table[] pointers, sorted + * by device */ + struct l_dev **dev_table_sorted; + + /* block device table pointer */ + struct l_dev *block_dev_table; + int block_dev_table_size; /* number of entries in block_dev_table[] */ + /* pointer to BDevtp[] pointers, sorted + * by device */ + struct l_dev **block_dev_table_sorted; + + /* selection flags -- see SEL* macros */ + int sel_flags; + /* SELPROC flags, modified by IgnTasks */ + int sel_proc; + /* SELALL flags, modified by IgnTasks */ + int sel_all; + /* select only Internet socket files */ + int sel_inet; + + /* -N option status: 0==none, 1==find all, + * 2==some found*/ + int sel_nfs; + + /* -K option value */ + int sel_task; + + /* -a option status */ + int logic_and; + + /* -b option status */ + int avoid_blocking; + + /* -O option status */ + int avoid_forking; + + /* -X option status */ + int x_opt; + + /* -E option status: + * 0==none, + * 1==info, + * 2==info+files */ + int endpoint_status; + + /* ignore tasks when non-zero */ + int ign_tasks; + + /* maximum file descriptors to close */ + int max_fd; + + /* file descriptors selected with -d */ + struct fd_lst *fd_list; + /* fd_list[] type: + * -1 == none + * 0 == include + * 1 == exclude */ + int fd_list_ty; + + /* mount supplement state: + * 0 == none + * 1 == create + * 2 == read */ + int mnt_sup_state; + /* mount supplement path -- if MntSup == 2 */ + char *mnt_sup_path; + + /* report nlink values below this number + * (0 = report all nlink values) */ + long nlink; + + /* Readlink() and stat() timeout (seconds) */ + int time_limit; + + int my_pid; /* lsof's process ID */ + uid_t my_uid; /* real UID of this lsof process */ + gid_t my_gid; /* real GID of this lsof process */ + int setgid; /* setgid state */ + int setuid_root; /* setuid-root state */ + + /* directory stack */ + char **dir_stack; /* the directory stack */ + int dir_stack_index; /* dir_stack[] index */ + int dir_stack_size; /* dir_stack[] entries allocated */ + + /* allocated (possibly unused) entries in TCP + * state tables */ + int tcp_state_alloc; + /* included TCP states */ + unsigned char *tcp_state_incl; + int tcp_state_incl_num; /* number of entries in tcp_state_incl[] */ + int tcp_state_off; /* offset for TCP state number to adjust + * negative numbers to an index into tcp_states[], + * tcp_state_incl[] and tcp_state_excl[] */ + /* excluded TCP states */ + unsigned char *tcp_state_excl; + int tcp_state_excl_num; /* number of entries in tcp_state_excl[] */ + int tcp_num_states; /* number of TCP states -- either in + * tcpstates[] or tcp_states[] */ + char **tcp_states; /* local TCP state names, indexed by system + * state value */ + + /* allocated (possibly unused) entries in UDP + * state tables */ + int udp_state_alloc; + /* included UDP states */ + unsigned char *udp_state_incl; + int udp_state_incl_num; /* number of entries in udp_state_incl[] */ + int udp_state_off; /* offset for UDP state number to adjust + * negative numbers to an index into udp_states[], + * udp_state_incl[] and udp_state_excl[] */ + unsigned char *udp_state_excl; + /* excluded UDP states */ + int udp_state_excl_num; /* number of entries in udp_state_excl[] */ + int udp_num_states; /* number of UDP states in udp_states[] */ + char **udp_states; /* local UDP state names, indexed by system + * state number */ + + int unix_socket; /* -U option status */ + + dev_t dev_dev; /* device number of /dev or its equivalent */ + + int net; /* -i option status: 0==none + * 1==find all + * 2==some found */ + int net_type; /* Fnet type request: AF_UNSPEC==all + * AF_INET==IPv4 + * AF_INET6==IPv6 */ + + /** Temporary */ + /* name characters for printing */ + char *name_buf; + /* sizeof(name_buf) */ + size_t name_buf_size; + + /** Output */ + /** Pointer to current process */ + struct lproc *cur_proc; + /** Pointer to all processes */ + struct lproc *procs; + /** Length and capacity of `procs` */ + size_t procs_size; + size_t procs_cap; + + /** Pointer to current file */ + struct lfile *cur_file; + /** Pointer to previous file */ + struct lfile *prev_file; + + /** Warnings and errors */ + FILE *err; + char *program_name; + int warn; /* 1=suppress warnings */ + + /** dialect specific fields, see dlsof.h */ + struct lsof_context_dialect dialect; +}; + +/** Convenience macros to access context */ +/* Local process */ +# define Lp (ctx->cur_proc) +/* All local processes */ +# define Lproc (ctx->procs) +/* Local file */ +# define Lf (ctx->cur_file) +/* Previous local file */ +# define Plf (ctx->prev_file) +/* Length of local processes */ +# define Nlproc (ctx->procs_size) +/* Error output */ +# define Pn (ctx->program_name) +/* Suppress warnings */ +# define Fwarn (ctx->warn) +/* Name buffer */ +# define Namech (ctx->name_buf) +# define Namechl (ctx->name_buf_size) +/* Selection flags */ +# define SelAll (ctx->sel_all) +# define Selflags (ctx->sel_flags) +# define SelProc (ctx->sel_proc) +# define Selinet (ctx->sel_inet) +/* dev_t of /dev */ +# define DevDev (ctx->dev_dev) +/* TCP states */ +# define TcpNstates (ctx->tcp_num_states) +# define TcpSt (ctx->tcp_states) +# define TcpStI (ctx->tcp_state_incl) +# define TcpStIn (ctx->tcp_state_incl_num) +# define TcpStX (ctx->tcp_state_excl) +# define TcpStXn (ctx->tcp_state_excl_num) +# define TcpStOff (ctx->tcp_state_off) +# define TcpStAlloc (ctx->tcp_state_alloc) +/* UDP states */ +# define UdpNstates (ctx->udp_num_states) +# define UdpSt (ctx->udp_states) +# define UdpStI (ctx->udp_state_incl) +# define UdpStIn (ctx->udp_state_incl_num) +# define UdpStX (ctx->udp_state_excl) +# define UdpStXn (ctx->udp_state_excl_num) +# define UdpStOff (ctx->udp_state_off) +# define UdpStAlloc (ctx->udp_state_alloc) +/* select unix socket */ +# define Funix (ctx->unix_socket) +/* select inet socket */ +# define Fnet (ctx->net) +# define FnetTy (ctx->net_type) +/* select nfs files */ +# define Fnfs (ctx->sel_nfs) +/* -a option */ +# define Fand (ctx->logic_and) +/* -x option */ +# define Fxopt (ctx->x_opt) +/* avoid blocking */ +# define Fblock (ctx->avoid_blocking) +/* avoid forking overhead */ +# define Fovhd (ctx->avoid_forking) +/* endpoint status */ +# define FeptE (ctx->endpoint_status) +/* select tasks */ +# define Ftask (ctx->sel_task) +/* fd list */ +# define Fdl (ctx->fd_list) +# define FdlTy (ctx->fd_list_ty) +/* ignore tasks */ +# define IgnTasks (ctx->ign_tasks) +/* maximum fd number */ +# define MaxFd (ctx->max_fd) +/* mount supplement */ +# define MntSup (ctx->mnt_sup_state) +# define MntSupP (ctx->mnt_sup_path) +/* nlink limit */ +# define Nlink (ctx->nlink) +/* Time limit */ +# define TmLimit (ctx->time_limit) +/* number of unselected PIDs */ +# define Npuns (ctx->num_unsel_pid) +/* pid/uid/gid of current process */ +# define Mypid (ctx->my_pid) +# define Myuid (ctx->my_uid) +# define Mygid (ctx->my_gid) +/* setgid state */ +# define Setgid (ctx->setgid) +/* setuid-root state */ +# define Setuidroot (ctx->setuid_root) +/* directory stack */ +# define Dstk (ctx->dir_stack) +# define Dstkx (ctx->dir_stack_index) +# define Dstkn (ctx->dir_stack_size) +/* selection files */ +# define Sfile (ctx->select_files) +/* fs to eliminate blocking syscalls */ +# define Efsysl (ctx->elim_fs_list) +/* select uid */ +# define Suid (ctx->sel_uid) +# define Nuid (ctx->sel_uid_size) +# define Nuidincl (ctx->num_uid_included) +# define Nuidexcl (ctx->num_uid_excluded) +# define Mxuid (ctx->sel_uid_cap) +/* select pid */ +# define Spid (ctx->sel_pid) +# define Npid (ctx->sel_pid_size) +# define Npidi (ctx->sel_pid_incl_num) +# define Npidx (ctx->sel_pid_excl_num) +# define Mxpid (ctx->sel_pid_cap) +/* select pgid */ +# define Spgid (ctx->sel_pgid) +# define Npgid (ctx->sel_pgid_size) +# define Npgidi (ctx->sel_pgid_incl_num) +# define Npgidx (ctx->sel_pgid_excl_num) +# define Mxpgid (ctx->sel_pgid_cap) +/* select all procs */ +# define AllProc (ctx->sel_all_proc) +/* select command */ +# define Cmdl (ctx->sel_cmds) +# define Cmdni (ctx->sel_cmd_incl) +# define Cmdnx (ctx->sel_cmd_excl) +# define CmdRx (ctx->cmd_regex) +# define NCmdRxU (ctx->cmd_regex_size) +/* select by network address */ +# define Nwad (ctx->sel_net_addr) +/* device table pointer */ +# define Devtp (ctx->dev_table) +# define Ndev (ctx->dev_table_size) +# define Sdev (ctx->dev_table_sorted) +/* block device table */ +# define BDevtp (ctx->block_dev_table) +# define BNdev (ctx->block_dev_table_size) +# define BSdev (ctx->block_dev_table_sorted) +/* select selinux context */ +# define CntxArg (ctx->sel_selinux_context) +/* device cache */ +# define DCpath (ctx->dev_cache_paths) +# define DCpathArg (ctx->dev_cache_path_arg) +# define DCpathX (ctx->dev_cache_path_index) +# define DCcksum (ctx->dev_cache_checksum) +# define DCfd (ctx->dev_cache_fd) +# define DCfs (ctx->dev_cache_fp) +# define DCrebuilt (ctx->dev_cache_rebuilt) +# define DCstate (ctx->dev_cache_state) +# define DCunsafe (ctx->dev_cache_unsafe) +/* name list */ +# define Nl (ctx->name_list) +# define Nll (ctx->name_list_size) +# define Nmlst (ctx->name_list_path) +# define Memory (ctx->core_file_path) +/* procfs */ +# define Mtprocfs (ctx->procfs_mount) +# define Procsrch (ctx->procfs_search) +# define Procfsid (ctx->procfs_table) +# define Procfind (ctx->procfs_found) +/* name cache */ +# define Fncache (ctx->name_cache_enable) +/* local mount info */ +# define Lmi (ctx->local_mount_info) +# define Lmist (ctx->local_mount_info_valid) +/* hash buckets in hashSfile() */ +# define HbyFdi (ctx->sfile_hash_file_dev_inode) +# define HbyFdiCt (ctx->sfile_hash_file_dev_inode_count) +# define HbyFrd (ctx->sfile_hash_file_raw_device) +# define HbyFrdCt (ctx->sfile_hash_file_raw_device_count) +# define HbyFsd (ctx->sfile_hash_file_system) +# define HbyFsdCt (ctx->sfile_hash_file_system_count) +# define HbyNm (ctx->sfile_hash_name) +# define HbyNmCt (ctx->sfile_hash_name_count) +# define HbyCd (ctx->sfile_hash_clone) +# define HbyCdCt (ctx->sfile_hash_clone_count) +/* solaris zone */ +# define ZoneArg (ctx->sel_zone) + +/* Utility macro to free if non-null and set the pointer to null */ +# define CLEAN(ptr) \ + do { \ + free(ptr); \ + ptr = NULL; \ + } while (0); # include "proto.h" # include "dproto.h" -#endif /* LSOF_H */ +#endif /* COMMON_H */ diff --git a/lib/dialects/aix/dlsof.h b/lib/dialects/aix/dlsof.h index 58aae4e7..6293ffc4 100644 --- a/lib/dialects/aix/dlsof.h +++ b/lib/dialects/aix/dlsof.h @@ -427,4 +427,6 @@ static char *tcpstates[] = {"CLOSED", "LISTEN", "SYN_SENT", * in libc.so */ # endif /* AIXA>1 */ +struct lsof_context_dialect {}; + #endif /* AIX_LSOF_H */ diff --git a/lib/dialects/aix/dsock.c b/lib/dialects/aix/dsock.c index f2f845d0..1a130eca 100644 --- a/lib/dialects/aix/dsock.c +++ b/lib/dialects/aix/dsock.c @@ -214,7 +214,7 @@ void process_socket(struct lsof_context *ctx, /* context */ Lf->sf |= SELNET; } - printiproto(p.pr_protocol); + printiproto(ctx, p.pr_protocol); #if defined(HASIPv6) Lf->type = fam == AF_INET ? LSOF_FILE_IPV4 : LSOF_FILE_IPV6; diff --git a/lib/dialects/darwin/dlsof.h b/lib/dialects/darwin/dlsof.h index df38e487..72242f17 100644 --- a/lib/dialects/darwin/dlsof.h +++ b/lib/dialects/darwin/dlsof.h @@ -128,4 +128,6 @@ struct sfile { # define offsetof(type, member) ((size_t)(&((type *)0)->member)) # endif /* !defined(offsetof) */ +struct lsof_context_dialect {}; + #endif /* DARWIN_LSOF_H */ diff --git a/lib/dialects/darwin/dmnt.c b/lib/dialects/darwin/dmnt.c index 42af045f..a1b77e26 100644 --- a/lib/dialects/darwin/dmnt.c +++ b/lib/dialects/darwin/dmnt.c @@ -43,9 +43,6 @@ static char copyright[] = "@(#) Copyright 2005 Apple Computer, Inc. and " * Local static information */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() -- read mount table */ diff --git a/lib/dialects/darwin/dsock.c b/lib/dialects/darwin/dsock.c index 30a63734..b6f55607 100644 --- a/lib/dialects/darwin/dsock.c +++ b/lib/dialects/darwin/dsock.c @@ -153,7 +153,7 @@ static void process_socket_common(struct lsof_context *ctx, ((FnetTy == 6) && (fam == AF_INET6))) Lf->sf |= SELNET; } - printiproto(si->psi.soi_protocol); + printiproto(ctx, si->psi.soi_protocol); if ((si->psi.soi_kind == SOCKINFO_TCP) && si->psi.soi_proto.pri_tcp.tcpsi_tp) { enter_dev_ch(ctx, diff --git a/lib/dialects/freebsd/dlsof.h b/lib/dialects/freebsd/dlsof.h index a8efa59c..7dafc525 100644 --- a/lib/dialects/freebsd/dlsof.h +++ b/lib/dialects/freebsd/dlsof.h @@ -539,4 +539,6 @@ struct namecache { # include +struct lsof_context_dialect {}; + #endif /* defined(FREEBSD_LSOF_H) */ diff --git a/lib/dialects/freebsd/dmnt.c b/lib/dialects/freebsd/dmnt.c index 5144fbc9..06faaa8f 100644 --- a/lib/dialects/freebsd/dmnt.c +++ b/lib/dialects/freebsd/dmnt.c @@ -39,9 +39,6 @@ static char copyright[] = * Local static information */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - #undef HAS_MNT_NAMES #if defined(MOUNT_NONE) diff --git a/lib/dialects/freebsd/dnode.c b/lib/dialects/freebsd/dnode.c index 89085433..115aacd5 100644 --- a/lib/dialects/freebsd/dnode.c +++ b/lib/dialects/freebsd/dnode.c @@ -50,7 +50,8 @@ static void get_lock_state_kvm(struct lsof_context *ctx, KA_T f); */ #ifdef KERN_LOCKF -static void get_lock_state_sysctl(struct kinfo_file *kf, +static void get_lock_state_sysctl(struct lsof_context *ctx, + struct kinfo_file *kf, struct lock_list *locks) { struct kinfo_lockf key, *lock; @@ -387,7 +388,7 @@ void process_vnode(struct lsof_context *ctx, struct kinfo_file *kf, } #ifdef KERN_LOCKF - get_lock_state_sysctl(kf, locks); + get_lock_state_sysctl(ctx, kf, locks); #elif defined(HAS_V_LOCKF) if (v && v->v_lockf) (void)get_lock_state_kvm(ctx, (KA_T)v->v_lockf); diff --git a/lib/dialects/freebsd/dproc.c b/lib/dialects/freebsd/dproc.c index 61a39606..14df6a90 100644 --- a/lib/dialects/freebsd/dproc.c +++ b/lib/dialects/freebsd/dproc.c @@ -578,7 +578,8 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * Get kernel's badfileops address (for process_file()). */ - if (get_Nl_value(X_BADFILEOPS, (struct drive_Nl *)NULL, &X_bfopsa) < 0 || + if (get_Nl_value(ctx, X_BADFILEOPS, (struct drive_Nl *)NULL, &X_bfopsa) < + 0 || !X_bfopsa) { X_bfopsa = (KA_T)0; } diff --git a/lib/dialects/freebsd/dsock.c b/lib/dialects/freebsd/dsock.c index 0efa0cb2..c393dd24 100644 --- a/lib/dialects/freebsd/dsock.c +++ b/lib/dialects/freebsd/dsock.c @@ -83,7 +83,7 @@ static char copyright[] = * Local function prototypes */ -static int ckstate(struct xtcpcb *pcb, int fam); +static int ckstate(struct lsof_context *ctx, struct xtcpcb *pcb, int fam); static int cmp_xunpcb_sock_pcb(const void *a, const void *b) { const struct xunpcb *pcb1 = (const struct xunpcb *)a; @@ -268,7 +268,7 @@ void free_pcb_lists(struct pcb_lists *pcbs) { * 1 == stop processing file */ -static int ckstate(struct xtcpcb *pcb, int fam) { +static int ckstate(struct lsof_context *ctx, struct xtcpcb *pcb, int fam) { #if __FreeBSD_version >= 1200026 int tsnx; @@ -445,7 +445,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, Lf->sf |= SELNET; } } - printiproto(kf->kf_sock_protocol); + printiproto(ctx, kf->kf_sock_protocol); Lf->type = (fam == AF_INET) ? LSOF_FILE_IPV4 : LSOF_FILE_IPV6; @@ -467,7 +467,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, * Save IPv6 address information. */ if (kf->kf_sock_protocol == IPPROTO_TCP) { - if ((ts = ckstate((struct xtcpcb *)pcb, fam)) == 1) { + if ((ts = ckstate(ctx, (struct xtcpcb *)pcb, fam)) == 1) { return; } } @@ -505,7 +505,7 @@ void process_socket(struct lsof_context *ctx, struct kinfo_file *kf, return; } if (kf->kf_sock_protocol == IPPROTO_TCP) { - if ((ts = ckstate((struct xtcpcb *)pcb, fam)) == 1) + if ((ts = ckstate(ctx, (struct xtcpcb *)pcb, fam)) == 1) return; } enter_dev_ch(ctx, diff --git a/lib/dialects/hpux/kmem/dlsof.h b/lib/dialects/hpux/kmem/dlsof.h index ae4f934f..9baed7bc 100644 --- a/lib/dialects/hpux/kmem/dlsof.h +++ b/lib/dialects/hpux/kmem/dlsof.h @@ -434,4 +434,6 @@ extern KA_T Vnfops; # endif /* HPUXV<1000 */ # endif /* defined(HASNCACHE) */ +struct lsof_context_dialect {}; + #endif /* HPUX_LSOF_H */ diff --git a/lib/dialects/hpux/kmem/dsock.c b/lib/dialects/hpux/kmem/dsock.c index 22a10223..9f57bd82 100644 --- a/lib/dialects/hpux/kmem/dsock.c +++ b/lib/dialects/hpux/kmem/dsock.c @@ -642,7 +642,7 @@ void process_socket(sa) KA_T sa; /* socket address in kernel */ if (Fnet) Lf->sf |= SELNET; Lf->type = LSOF_FILE_INET; - printiproto(p.pr_protocol); + printiproto(ctx, p.pr_protocol); #if HPUXV >= 1030 /* diff --git a/lib/dialects/hpux/pstat/dlsof.h b/lib/dialects/hpux/pstat/dlsof.h index 78d7494d..2e123fdc 100644 --- a/lib/dialects/hpux/pstat/dlsof.h +++ b/lib/dialects/hpux/pstat/dlsof.h @@ -200,4 +200,6 @@ extern int HasNFS; # define MOUNTS_STAT_FSTYPE stat_fstype # endif /* defined(HASFSTYPE) && HASFSTYPE==2 */ +struct lsof_context_dialect {}; + #endif /* HPUX_LSOF_H */ diff --git a/lib/dialects/linux/dfile.c b/lib/dialects/linux/dfile.c index 78ecde9c..ae704e9c 100644 --- a/lib/dialects/linux/dfile.c +++ b/lib/dialects/linux/dfile.c @@ -43,18 +43,6 @@ struct hsfile { * Local static variables */ -static struct hsfile *HbyFdi = /* hash by file (dev,ino) buckets */ - (struct hsfile *)NULL; -static int HbyFdiCt = 0; /* HbyFdi entry count */ -static struct hsfile *HbyFrd = /* hash by file raw device buckets */ - (struct hsfile *)NULL; -static int HbyFrdCt = 0; /* HbyFrd entry count */ -static struct hsfile *HbyFsd = /* hash by file system buckets */ - (struct hsfile *)NULL; -static int HbyFsdCt = 0; /* HbyFsd entry count */ -static struct hsfile *HbyNm = /* hash by name buckets */ - (struct hsfile *)NULL; -static int HbyNmCt = 0; /* HbyNm entry count */ /* * Local definitions diff --git a/lib/dialects/linux/dlsof.h b/lib/dialects/linux/dlsof.h index 25db6581..f4504a6a 100644 --- a/lib/dialects/linux/dlsof.h +++ b/lib/dialects/linux/dlsof.h @@ -198,4 +198,6 @@ extern dev_t MqueueDev; # define OFFSET_FDINFO 2 extern int OffType; +struct lsof_context_dialect {}; + #endif /* LINUX_LSOF_H */ diff --git a/lib/dialects/linux/dmnt.c b/lib/dialects/linux/dmnt.c index 892dc3e0..15ad8f2b 100644 --- a/lib/dialects/linux/dmnt.c +++ b/lib/dialects/linux/dmnt.c @@ -70,8 +70,6 @@ typedef struct mntsup { * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ static mntsup_t **MSHash = (mntsup_t **)NULL; /* mount supplement * hash buckets */ @@ -198,7 +196,7 @@ getmntdev(struct lsof_context *ctx, /* context */ if ((MntSup != 2) || !MntSupP) return (0); - if (!is_readable(MntSupP, 1)) { + if (!is_readable(ctx, MntSupP, 1)) { /* * The mount supplement file isn't readable. diff --git a/lib/dialects/linux/dsock.c b/lib/dialects/linux/dsock.c index d9e3f866..29b20f1e 100644 --- a/lib/dialects/linux/dsock.c +++ b/lib/dialects/linux/dsock.c @@ -369,7 +369,7 @@ static void print_ipxinfo(struct lsof_context *ctx, struct ipxsin *ip); static char *socket_type_to_str(uint32_t ty, int *rf); static char *netlink_proto_to_str(unsigned int pr); #if defined(HASSOSTATE) -static char *socket_state_to_str(unsigned int ss); +static char *socket_state_to_str(struct lsof_context *ctx, unsigned int ss); #endif /* defined(HASSOSTATE) */ static char *ethernet_proto_to_str(unsigned int pr); @@ -1132,7 +1132,7 @@ void process_uxsinfo(struct lsof_context *ctx, /* * Process already selected socket. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than its @@ -1161,7 +1161,7 @@ void process_uxsinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_UXS)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_UXS)) { /* * This is an unselected end point UNIX socket file. Select it @@ -1365,7 +1365,7 @@ void process_netsinfo(struct lsof_context *ctx, /* context */ /* * Process already selected socket. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than its @@ -1377,7 +1377,7 @@ void process_netsinfo(struct lsof_context *ctx, /* context */ } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_NETS)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_NETS)) { /* * This is an unselected end point INET socket file. Select it @@ -1490,7 +1490,7 @@ void process_nets6info(struct lsof_context *ctx, /* context */ /* * Process already selected socket. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than its * being a socket. Look up the socket's endpoints. @@ -1501,7 +1501,7 @@ void process_nets6info(struct lsof_context *ctx, /* context */ } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_NETS6)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_NETS6)) { /* * This is an unselected end point INET6 socket file. Select it @@ -3415,12 +3415,12 @@ static void print_ipxinfo(struct lsof_context *ctx, /* context */ /* * print_unix() - print state of UNIX domain socket e.g. UNCONNECTED */ -static void print_unix(int nl) { +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(Lf->lts.ss); + : socket_state_to_str(ctx, Lf->lts.ss); if (Ffield) (void)printf("%cST=%s%c", LSOF_FID_TCPTPI, cp, Terminator); @@ -3447,7 +3447,7 @@ void print_tcptpi(struct lsof_context *ctx, /* context */ int s; if (Lf->type == LSOF_FILE_UNIX) { - print_unix(nl); + print_unix(ctx, nl); return; } if ((Ftcptpi & TCPTPI_STATE) && Lf->lts.type == 0) { @@ -4570,7 +4570,7 @@ static char *netlink_proto_to_str(unsigned int pr) { * * returns "UNKNOWN" for unknown state. */ -static char *socket_state_to_str(unsigned int ss) { +static char *socket_state_to_str(struct lsof_context *ctx, unsigned int ss) { char *sr; switch (Lf->lts.ss) { case SS_UNCONNECTED: diff --git a/lib/dialects/netbsd/dlsof.h b/lib/dialects/netbsd/dlsof.h index c82fc95b..41dd7f24 100644 --- a/lib/dialects/netbsd/dlsof.h +++ b/lib/dialects/netbsd/dlsof.h @@ -568,4 +568,6 @@ struct sfile { # define NCACHE_VROOT VROOT # endif /* VV_ROOT */ +struct lsof_context_dialect {}; + #endif /* NETBSD_LSOF_H */ diff --git a/lib/dialects/netbsd/dmnt.c b/lib/dialects/netbsd/dmnt.c index 7ff0e024..efb6b733 100644 --- a/lib/dialects/netbsd/dmnt.c +++ b/lib/dialects/netbsd/dmnt.c @@ -60,9 +60,6 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ diff --git a/lib/dialects/netbsd/dproc.c b/lib/dialects/netbsd/dproc.c index 867a9ec3..dc9254f9 100644 --- a/lib/dialects/netbsd/dproc.c +++ b/lib/dialects/netbsd/dproc.c @@ -440,7 +440,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * Read the kernel's page shift amount, if possible. */ - if (get_Nl_value("pgshift", Drive_Nl, &v) < 0 || !v || + if (get_Nl_value(ctx, "pgshift", Drive_Nl, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&pgshift, sizeof(pgshift))) pgshift = 0; } diff --git a/lib/dialects/netbsd/dsock.c b/lib/dialects/netbsd/dsock.c index f629d6c5..2c1aacb5 100644 --- a/lib/dialects/netbsd/dsock.c +++ b/lib/dialects/netbsd/dsock.c @@ -179,7 +179,7 @@ void process_socket(struct lsof_context *ctx, /* context */ Lf->sf |= SELNET; } - printiproto(p.pr_protocol); + printiproto(ctx, p.pr_protocol); #if defined(HASIPv6) Lf->type = (fam == AF_INET) ? LSOF_FILE_IPV4 : LSOF_FILE_IPV6; diff --git a/lib/dialects/openbsd/dlsof.h b/lib/dialects/openbsd/dlsof.h index 20dedb4e..77346c12 100644 --- a/lib/dialects/openbsd/dlsof.h +++ b/lib/dialects/openbsd/dlsof.h @@ -153,4 +153,6 @@ struct sfile { # define DIRTYPE dirent # define HASDNAMLEN 1 /* struct DIRTYPE has d_namlen element */ +struct lsof_context_dialect {}; + #endif /* OPENBSD_LSOF_H */ diff --git a/lib/dialects/openbsd/dmnt.c b/lib/dialects/openbsd/dmnt.c index 50949865..2210b603 100644 --- a/lib/dialects/openbsd/dmnt.c +++ b/lib/dialects/openbsd/dmnt.c @@ -39,9 +39,6 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - /* * readmnt() - read mount table */ diff --git a/lib/dialects/osr/dlsof.h b/lib/dialects/osr/dlsof.h index b7fc0233..b54d2d82 100644 --- a/lib/dialects/osr/dlsof.h +++ b/lib/dialects/osr/dlsof.h @@ -244,4 +244,6 @@ extern KA_T Socktab; # define HAS_STD_CLONE 1 /* has standard clone structure */ # define HAVECLONEMAJ HaveCloneMajor /* clone major status variable name */ +struct lsof_context_dialect {}; + #endif /* OSR_LSOF_H */ diff --git a/lib/dialects/osr/dsock.c b/lib/dialects/osr/dsock.c index 2f947340..f1b1a7c9 100644 --- a/lib/dialects/osr/dsock.c +++ b/lib/dialects/osr/dsock.c @@ -106,7 +106,7 @@ void process_socket(i) struct inode *i; /* inode pointer */ if (Fnet) Lf->sf |= SELNET; Lf->type = LSOF_FILE_INET; - printiproto((int)s.so_proto.pr_protocol); + printiproto(ctx, (int)s.so_proto.pr_protocol); Lf->inp_ty = 2; /* * Get protocol control block address from stream head queue structure. diff --git a/lib/dialects/sun/ddev.c b/lib/dialects/sun/ddev.c index 559c43db..53265a04 100644 --- a/lib/dialects/sun/ddev.c +++ b/lib/dialects/sun/ddev.c @@ -795,7 +795,7 @@ int rw_clone_sect(struct lsof_context *ctx, for (c = Clone, n = 0; c; c = c->next, n++) ; (void)snpf(buf, sizeof(buf), "clone section: %d\n", n); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); /* * Write the clone section lines. @@ -808,7 +808,7 @@ int rw_clone_sect(struct lsof_context *ctx, for (c = Clone; c; c = c->next) { (void)snpf(buf, sizeof(buf), " %lx %d %ld %s\n", (long)c->cd.rdev, c->n, (long)c->cd.inode, c->cd.name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); } return (0); @@ -959,7 +959,7 @@ int rw_pseudo_sect(struct lsof_context *ctx, for (p = Pseudo, n = 0; p; p = p->next, n++) ; (void)snpf(buf, sizeof(buf), "pseudo section: %d\n", n); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); /* * Write the pseudo section lines. @@ -972,7 +972,7 @@ int rw_pseudo_sect(struct lsof_context *ctx, for (p = Pseudo; p; p = p->next) { (void)snpf(buf, sizeof(buf), " %lx %ld %s\n", (long)p->pd.rdev, (long)p->pd.inode, p->pd.name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); } return (0); diff --git a/lib/dialects/sun/dfile.c b/lib/dialects/sun/dfile.c index 3545cd33..7d103d26 100644 --- a/lib/dialects/sun/dfile.c +++ b/lib/dialects/sun/dfile.c @@ -48,22 +48,6 @@ struct hsfile { * Local static variables */ -static struct hsfile *HbyCd = /* hash by clone buckets */ - (struct hsfile *)NULL; -static int HbyCdCt = 0; /* HbyCd entry count */ -static struct hsfile *HbyFdi = /* hash by file buckets */ - (struct hsfile *)NULL; -static int HbyFdiCt = 0; /* HbyFdi entry count */ -static struct hsfile *HbyFrd = /* hash by file raw device buckets */ - (struct hsfile *)NULL; -static int HbyFrdCt = 0; /* HbyFrd entry count */ -static struct hsfile *HbyFsd = /* hash by file system buckets */ - (struct hsfile *)NULL; -static int HbyFsdCt = 0; /* HbyFsd entry count */ -static struct hsfile *HbyNm = /* hash by name buckets */ - (struct hsfile *)NULL; -static int HbyNmCt = 0; /* HbyNm entry count */ - /* * Local definitions */ diff --git a/lib/dialects/sun/dlsof.h b/lib/dialects/sun/dlsof.h index 34617338..17725a7b 100644 --- a/lib/dialects/sun/dlsof.h +++ b/lib/dialects/sun/dlsof.h @@ -692,4 +692,6 @@ extern int Unof; /* u_nofiles value */ # endif /* solaris>=80000 */ # endif /* defined(HASNCACHE) */ +struct lsof_context_dialect {}; + #endif /* SOLARIS_LSOF_H */ diff --git a/lib/dialects/sun/dmnt.c b/lib/dialects/sun/dmnt.c index c417396b..de1128b0 100644 --- a/lib/dialects/sun/dmnt.c +++ b/lib/dialects/sun/dmnt.c @@ -39,9 +39,6 @@ static char copyright[] = * Local static definitions */ -static struct mounts *Lmi = (struct mounts *)NULL; /* local mount info */ -static int Lmist = 0; /* Lmi status */ - static char *getmntdev(struct lsof_context *ctx, char *o, int l, struct stat *s, char *f); diff --git a/lib/dialects/sun/dnode.c b/lib/dialects/sun/dnode.c index 00ce3d73..2696571f 100644 --- a/lib/dialects/sun/dnode.c +++ b/lib/dialects/sun/dnode.c @@ -519,13 +519,13 @@ static KA_T Vvops[VXVOP_NUM]; /* addresses of: #if defined(VOPNAME_OPEN) && solaris >= 100000 # define GETVOPS(name, nl, ops) \ - if (get_Nl_value(name, nl, &ops) < 0) \ + if (get_Nl_value(ctx, name, nl, &ops) < 0) \ ops = (KA_T)0; \ else if (kread(ctx, ops, (char *)&ops, sizeof(ops))) \ ops = (KA_T)0 #else /* !defined(VOPNAME_OPEN) || solaris<100000 */ # define GETVOPS(name, nl, ops) \ - if (get_Nl_value(name, nl, &ops) < 0) \ + if (get_Nl_value(ctx, name, nl, &ops) < 0) \ ops = (KA_T)0 #endif /* defined(VOPNAME_OPEN) && solaris>=100000 */ diff --git a/lib/dialects/sun/dproc.c b/lib/dialects/sun/dproc.c index c0e5b8b2..21f91f8b 100644 --- a/lib/dialects/sun/dproc.c +++ b/lib/dialects/sun/dproc.c @@ -237,7 +237,7 @@ void gather_proc_info(struct lsof_context *ctx) { /* * Get the segment vnodeops address. */ - if (get_Nl_value("sgvops", Drive_Nl, &Sgvops) < 0) + if (get_Nl_value(ctx, "sgvops", Drive_Nl, &Sgvops) < 0) Sgvops = (KA_T)NULL; ft = 0; } else if (!HasALLKMEM) { @@ -619,7 +619,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * Get kernel symbols. */ - if (Nmlst && !is_readable(Nmlst, 1)) + if (Nmlst && !is_readable(ctx, Nmlst, 1)) Error(ctx); (void)build_Nl(ctx, Drive_Nl); @@ -654,9 +654,9 @@ static void get_kernel_access(struct lsof_context *ctx) { * the AFS modload file. Make sure that other symbols that appear in * both name list files have the same values. */ - if ((get_Nl_value("arFID", Drive_Nl, &v) >= 0 && !v) || - (get_Nl_value("avops", Drive_Nl, &v) >= 0 && !v) || - (get_Nl_value("avol", Drive_Nl, &v) >= 0 && !v)) + if ((get_Nl_value(ctx, "arFID", Drive_Nl, &v) >= 0 && !v) || + (get_Nl_value(ctx, "avops", Drive_Nl, &v) >= 0 && !v) || + (get_Nl_value(ctx, "avol", Drive_Nl, &v) >= 0 && !v)) (void)ckAFSsym(nl); (void)free((MALLOC_P *)nl); } @@ -716,7 +716,7 @@ static void get_kernel_access(struct lsof_context *ctx) { /* * See if the non-KMEM memory file is readable. */ - if (Memory && !is_readable(Memory, 1)) + if (Memory && !is_readable(ctx, Memory, 1)) Error(ctx); #endif /* defined(WILLDROPGID) */ @@ -730,7 +730,7 @@ static void get_kernel_access(struct lsof_context *ctx) { * Get the kernel's KERNELBASE value for Solaris 2.5 and above. */ v = (KA_T)0; - if (get_Nl_value("kbase", Drive_Nl, &v) < 0 || !v || + if (get_Nl_value(ctx, "kbase", Drive_Nl, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&Kb, sizeof(Kb))) { (void)fprintf(stderr, "%s: can't read kernel base address from %s\n", Pn, print_kptr(v, (char *)NULL, 0)); @@ -742,8 +742,8 @@ static void get_kernel_access(struct lsof_context *ctx) { * Get the Solaris clone major device number, if possible. */ v = (KA_T)0; - if ((get_Nl_value("clmaj", Drive_Nl, &v) < 0) || !v) { - if (get_Nl_value("clmaj_alt", Drive_Nl, &v) < 0) + if ((get_Nl_value(ctx, "clmaj", Drive_Nl, &v) < 0) || !v) { + if (get_Nl_value(ctx, "clmaj_alt", Drive_Nl, &v) < 0) v = (KA_T)0; } if (v && kread(ctx, (KA_T)v, (char *)&CloneMaj, sizeof(CloneMaj)) == 0) @@ -753,7 +753,7 @@ static void get_kernel_access(struct lsof_context *ctx) { * active process chain. If it's not available, clear the ALLKMEM status. */ if (HasALLKMEM) { - if ((get_Nl_value("pract", Drive_Nl, &PrAct) < 0) || !PrAct) + if ((get_Nl_value(ctx, "pract", Drive_Nl, &PrAct) < 0) || !PrAct) HasALLKMEM = 0; } @@ -763,7 +763,7 @@ static void get_kernel_access(struct lsof_context *ctx) { * physical map structure for Solaris 2.5.1 and above. */ if (!HasALLKMEM) { - if (get_Nl_value("kasp", Drive_Nl, &v) >= 0 && v) { + if (get_Nl_value(ctx, "kasp", Drive_Nl, &v) >= 0 && v) { PageSz = getpagesize(); PSMask = PageSz - 1; for (i = 1, PSShft = 0; i < PageSz; i <<= 1, PSShft++) @@ -1370,7 +1370,7 @@ static void read_proc(struct lsof_context *ctx) { /* * Get a proc structure count estimate. */ - if (get_Nl_value("nproc", Drive_Nl, &pa) < 0 || !pa || + if (get_Nl_value(ctx, "nproc", Drive_Nl, &pa) < 0 || !pa || kread(ctx, pa, (char *)&knp, sizeof(knp)) || knp < 1) knp = PROCDFLT; /* @@ -1783,7 +1783,7 @@ void ncache_load() { * Establish DNLC hash size. */ v = (KA_T)0; - if (get_Nl_value(X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || !v || + if (get_Nl_value(ctx, X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&Nch, sizeof(Nch))) { if (!Fwarn) (void)fprintf(stderr, @@ -1802,13 +1802,13 @@ void ncache_load() { /* * Get negative vnode address. */ - if (get_Nl_value(NCACHE_NEGVN, (struct drive_Nl *)NULL, &NegVN) < 0) + if (get_Nl_value(ctx, NCACHE_NEGVN, (struct drive_Nl *)NULL, &NegVN) < 0) NegVN = (KA_T)NULL; /* * Establish DNLC hash address. */ v = (KA_T)0; - if (get_Nl_value(X_NCACHE, (struct drive_Nl *)NULL, (KA_T *)&v) < 0 || + if (get_Nl_value(ctx, X_NCACHE, (struct drive_Nl *)NULL, (KA_T *)&v) < 0 || !v || kread(ctx, v, (char *)&kha, sizeof(kha)) || !kha) { if (!Fwarn) (void)fprintf(stderr, "%s: WARNING: no DNLC hash address\n", @@ -1841,7 +1841,7 @@ void ncache_load() { * hash table count and the current average hash length. */ v = (KA_T)0; - if ((get_Nl_value("hshav", (struct drive_Nl *)NULL, (KA_T *)&v) < 0) || + if ((get_Nl_value(ctx, "hshav", (struct drive_Nl *)NULL, (KA_T *)&v) < 0) || !v || kread(ctx, v, (char *)&i, sizeof(i)) || (i < 1)) { i = 16; if (!Fwarn) { diff --git a/lib/dialects/sun/dsock.c b/lib/dialects/sun/dsock.c index ea259f35..3f9ae622 100644 --- a/lib/dialects/sun/dsock.c +++ b/lib/dialects/sun/dsock.c @@ -301,8 +301,8 @@ typedef struct tcpb { * Local function prototypes */ -static void save_TCP_size(tcp_t *tc); -static void save_TCP_states(tcp_t *tc, caddr_t *fa, tcpb_t *tb, caddr_t *xp); +static void save_TCP_size(struct lsof_context *ctx, tcp_t *tc); +static void save_TCP_states(struct lsof_context *ctx, tcp_t *tc, caddr_t *fa, tcpb_t *tb, caddr_t *xp); /* * build_IPstates() -- build the TCP and UDP state tables @@ -835,13 +835,13 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ !kread(ctx, ka, (char *)&xa, sizeof(xa))) { xp = (caddr_t *)&xa; } - (void)save_TCP_states(&tc, (caddr_t *)&cs, (tcpb_t *)NULL, xp); + (void)save_TCP_states(ctx, &tc, (caddr_t *)&cs, (tcpb_t *)NULL, xp); # else /* !defined(HAS_CONN_NEW) */ if (tc.tcp_tcp_hdr_len && (ka = (KA_T)tc.tcp_tcph) && !kread(ctx, ka, (char *)&th, sizeof(th))) { tha = &th; } - (void)save_TCP_states(&tc, (caddr_t *)tha, (tcpb_t *)NULL, + (void)save_TCP_states(ctx, &tc, (caddr_t *)tha, (tcpb_t *)NULL, (caddr_t *)NULL); # endif /* defined(HAS_CONN_NEW) */ @@ -850,7 +850,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ /* * Save TCP size information. */ - (void)save_TCP_size(&tc); + (void)save_TCP_size(ctx, &tc); break; case IPPROTO_UDP: @@ -1090,7 +1090,7 @@ int process_VSOCK(struct lsof_context *ctx, /* context */ break; default: - (void)printiproto((int)cs.conn_ulp); + (void)printiproto(ctx, (int)cs.conn_ulp); (void)snpf(Namech, Namechl - 1, "unsupported socket family: %u", so->so_family); Namech[Namechl - 1] = '\0'; @@ -1659,7 +1659,7 @@ void process_socket(struct lsof_context *ctx, /* context */ * Save TCP state information. */ if (tcs) { - (void)save_TCP_states(&tc, (caddr_t *)tha, tcbp, + (void)save_TCP_states(ctx, &tc, (caddr_t *)tha, tcbp, (caddr_t *)NULL); Lf->lts.type = 0; Lf->lts.state.i = (int)tc.tcp_state; @@ -1669,7 +1669,7 @@ void process_socket(struct lsof_context *ctx, /* context */ */ if (tcs) - (void)save_TCP_size(&tc); + (void)save_TCP_size(ctx, &tc); } } else (void)strcat(Namech, "no TCP/UDP/IP information available"); @@ -1850,7 +1850,7 @@ static int read_udp_t(struct lsof_context *ctx, /* context */ * save_TCP_size() -- save TCP size information */ -static void save_TCP_size(tcp_t *tc) /* pointer to TCP control structure */ +static void save_TCP_size(struct lsof_context *ctx, tcp_t *tc) /* pointer to TCP control structure */ { int rq, sq; @@ -1886,7 +1886,8 @@ static void save_TCP_size(tcp_t *tc) /* pointer to TCP control structure */ * save_TCP_states() - save TCP states */ -static void save_TCP_states(tcp_t *tc, /* pointer to TCP control structure */ +static void save_TCP_states(struct lsof_context *ctx, /* context */ + tcp_t *tc, /* pointer to TCP control structure */ caddr_t *fa, /* flags address (may be NULL): * if HAS_CONN_NEW: conn_s * * if !CONN_HAS_NEW: tcph_t * diff --git a/lib/dialects/uw/dlsof.h b/lib/dialects/uw/dlsof.h index 668bf2db..12e46991 100644 --- a/lib/dialects/uw/dlsof.h +++ b/lib/dialects/uw/dlsof.h @@ -350,4 +350,6 @@ struct sfile { # include # endif /* defined(HASNCACHE) */ +struct lsof_context_dialect {}; + #endif /* UW_LSOF_H */ diff --git a/lib/dvch.c b/lib/dvch.c index 11f2e4e9..5097882b 100644 --- a/lib/dvch.c +++ b/lib/dvch.c @@ -616,7 +616,7 @@ int open_dcache(struct lsof_context *ctx, int m, /* mode: 1 = read; 2 = write */ /* * Check for access permission. */ - if (!is_readable(DCpath[DCpathX], 0)) { + if (!is_readable(ctx, DCpath[DCpathX], 0)) { if (DCpathX == 2 && errno == ENOENT) return (2); if (!Fwarn) @@ -1170,7 +1170,7 @@ static int rw_clone_sect(struct lsof_context *ctx, for (c = Clone, n = 0; c; c = c->next, n++) ; (void)snpf(buf, sizeof(buf), "clone section: %d\n", n); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); /* * Write the clone section lines. @@ -1192,7 +1192,7 @@ static int rw_clone_sect(struct lsof_context *ctx, return (1); } (void)snpf(buf, sizeof(buf), "%d %s\n", j, dp->name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return (1); } return (0); @@ -1243,19 +1243,19 @@ void write_dcache(struct lsof_context *ctx) { (long)DevDev); (void)crcbld(); DCcksum = 0; - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; /* * Write the device section from the contents of Sdev[] and Devtp[]. */ (void)snpf(buf, sizeof(buf), "device section: %d\n", Ndev); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; for (i = 0; i < Ndev; i++) { dp = Sdev[i]; (void)snpf(buf, sizeof(buf), "%lx %ld %s\n", (long)dp->rdev, (long)dp->inode, dp->name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; } @@ -1264,14 +1264,14 @@ void write_dcache(struct lsof_context *ctx) { * Write the block device section from the contents of BSdev[] and BDevtp[]. */ (void)snpf(buf, sizeof(buf), "block device section: %d\n", BNdev); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; if (BNdev) { for (i = 0; i < BNdev; i++) { dp = BSdev[i]; (void)snpf(buf, sizeof(buf), "%lx %ld %s\n", (long)dp->rdev, (long)dp->inode, dp->name); - if (wr2DCfd(buf, &DCcksum)) + if (wr2DCfd(ctx, buf, &DCcksum)) return; } } @@ -1297,7 +1297,7 @@ void write_dcache(struct lsof_context *ctx) { * Write the CRC section and close the file. */ (void)snpf(buf, sizeof(buf), "CRC section: %x\n", DCcksum); - if (wr2DCfd(buf, (unsigned *)NULL)) + if (wr2DCfd(ctx, buf, (unsigned *)NULL)) return; if (close(DCfd) != 0) { if (!Fwarn) @@ -1322,8 +1322,9 @@ void write_dcache(struct lsof_context *ctx) { * wr2DCfd() - write to the DCfd file descriptor */ -int wr2DCfd(char *b, /* buffer */ - unsigned *c) /* checksum receiver */ +int wr2DCfd(struct lsof_context *ctx, /* context */ + char *b, /* buffer */ + unsigned *c) /* checksum receiver */ { int bl, bw; diff --git a/lib/isfn.c b/lib/isfn.c index 2dc2c3a2..86f85a2b 100644 --- a/lib/isfn.c +++ b/lib/isfn.c @@ -69,25 +69,6 @@ struct hsfile { * Local static variables */ -# if defined(HAVECLONEMAJ) -static struct hsfile *HbyCd = /* hash by clone buckets */ - (struct hsfile *)NULL; -static int HbyCdCt = 0; /* HbyCd entry count */ -# endif /* defined(HAVECLONEMAJ) */ - -static struct hsfile *HbyFdi = /* hash by file (dev,ino) buckets */ - (struct hsfile *)NULL; -static int HbyFdiCt = 0; /* HbyFdi entry count */ -static struct hsfile *HbyFrd = /* hash by file raw device buckets */ - (struct hsfile *)NULL; -static int HbyFrdCt = 0; /* HbyFrd entry count */ -static struct hsfile *HbyFsd = /* hash by file system buckets */ - (struct hsfile *)NULL; -static int HbyFsdCt = 0; /* HbyFsd entry count */ -static struct hsfile *HbyNm = /* hash by name buckets */ - (struct hsfile *)NULL; -static int HbyNmCt = 0; /* HbyNm entry count */ - /* * Local definitions */ diff --git a/lib/lsof.c b/lib/lsof.c index e69de29b..d284f425 100644 --- a/lib/lsof.c +++ b/lib/lsof.c @@ -0,0 +1,207 @@ +/* + * lsof.c -- implement lsof_* functions() for liblsof + */ + +/* + * Copyright 1997 Purdue Research Foundation, West Lafayette, Indiana + * 47907. All rights reserved. + * + * Written by Victor A. Abell + * + * This software is not subject to any license of the American Telephone + * and Telegraph Company or the Regents of the University of California. + * + * Permission is granted to anyone to use this software for any purpose on + * any computer system, and to alter it and redistribute it freely, subject + * to the following restrictions: + * + * 1. Neither the authors nor Purdue University are responsible for any + * consequences of the use of this software. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Credit to the authors and Purdue + * University must appear in documentation and sources. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * + * 4. This notice may not be removed or altered. + */ + +#ifdef AUTOTOOLS +# include "config.h" +#endif +#include "common.h" +#include "lsof.h" +#include + +#ifndef API_EXPORT +# define API_EXPORT +#endif + +API_EXPORT +int lsof_get_api_version() { return LSOF_API_VERSION; } + +#ifdef AUTOTOOLS +API_EXPORT +char *lsof_get_library_version() { return PACKAGE_VERSION; } +#endif + +API_EXPORT +struct lsof_context *lsof_new() { + struct lsof_context *ctx = + (struct lsof_context *)malloc(sizeof(struct lsof_context)); + if (ctx) { + /* Initialization */ + memset(ctx, 0, sizeof(struct lsof_context)); + +#if defined(WARNINGSTATE) + /* suppress warnings */ + Fwarn = 1; +#else /* !defined(WARNINGSTATE) */ + /* display warnings */ + Fwarn = 0; +#endif /* defined(WARNINGSTATE) */ + +#if defined(HASXOPT_VALUE) + /* -X option status */ + Fxopt = HASXOPT_VALUE; +#endif /* defined(HASXOPT_VALUE) */ + + /* -1 == none */ + FdlTy = -1; + + /* Readlink() and stat() timeout (seconds) */ + TmLimit = TMLIMIT; + + /* default */ + AllProc = 1; + + /* -1 == none */ + FdlTy = -1; + + /* device cache file descriptor */ + DCfd = -1; + + /* device cache path index: -1 = path not defined */ + DCpathX = -1; + + /* device cache state: 3 = update; read and rebuild if necessary */ + DCstate = 3; + } + return ctx; +} + +API_EXPORT +enum lsof_error lsof_avoid_blocking(struct lsof_context *ctx, int avoid) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Fblock = avoid; + return LSOF_EXIT_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_avoid_forking(struct lsof_context *ctx, int avoid) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Fovhd = avoid; + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_logic_and(struct lsof_context *ctx) { + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + Fand = 1; + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_select_process(struct lsof_context *ctx, char *command, + int exclude) { + char *cp; /* command copy */ + MALLOC_S len; + struct str_lst *lpt, *str; + if (!ctx || ctx->frozen) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + + /* + * Check for command inclusion/exclusion conflicts. + */ + for (str = Cmdl; str; str = str->next) { + if (str->x != exclude) { + if (!strcmp(str->str, command)) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: -c^%s and -c%s conflict.\n", + Pn, str->str, command); + } + return LSOF_ERROR_INVALID_ARGUMENT; + } + } + } + + if (!(cp = mkstrcpy(command, &len))) { + if (ctx->err) { + (void)fprintf(ctx->err, "%s: no string copy space: ", Pn); + safestrprt(command, ctx->err, 1); + } + return LSOF_ERROR_NO_MEMORY; + } + +#if defined(MAXSYSCMDL) + if (len > MAXSYSCMDL) { + /* Impossible to match */ + if (ctx->err) { + (void)fprintf(ctx->err, "%s: \"-c ", Pn); + (void)safestrprt(command, ctx->err, 2); + (void)fprintf(ctx->err, "\" length (%zu) > what system", len); + (void)fprintf(ctx->err, " provides (%d)\n", MAXSYSCMDL); + } + CLEAN(cp); + return LSOF_ERROR_INVALID_ARGUMENT; + } +#endif + + if ((lpt = (struct str_lst *)malloc(sizeof(struct str_lst))) == NULL) { + if (ctx->err) { + safestrprt(command, ctx->err, 1); + (void)fprintf(ctx->err, "%s: no list space: ", Pn); + safestrprt(command, ctx->err, 1); + } + CLEAN(cp); + return LSOF_ERROR_NO_MEMORY; + } + + /* Insert into list */ + lpt->f = 0; + lpt->str = cp; + lpt->len = (int)len; + lpt->x = exclude; + if (exclude) { + Cmdnx++; + } else { + Cmdni++; + /* Update selection flag for inclusions */ + Selflags |= SELCMD; + } + lpt->next = Cmdl; + Cmdl = lpt; + + return LSOF_SUCCESS; +} + +API_EXPORT +enum lsof_error lsof_set_output_stream(struct lsof_context *ctx, FILE *fp, + char *program_name, int warn) { + if (!ctx) { + return LSOF_ERROR_INVALID_ARGUMENT; + } + ctx->err = fp; + ctx->program_name = mkstrcpy(program_name, NULL); + ctx->warn = warn; + return LSOF_SUCCESS; +} \ No newline at end of file diff --git a/lib/misc.c b/lib/misc.c index e7ad9f25..97532caa 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -217,7 +217,7 @@ int compdev(COMP_P *a1, COMP_P *a2) { /* * closefrom_shim() -- provide closefrom() when unavailable */ -void closefrom_shim(int low) { +void closefrom_shim(struct lsof_context *ctx, int low) { int i; #if defined(HAS_CLOSEFROM) (void)closefrom(low); @@ -325,7 +325,7 @@ static int doinchild(struct lsof_context *ctx, Error(ctx); } Pipes[3] = 1; - (void)closefrom_shim(2); + (void)closefrom_shim(ctx, 2); Pipes[1] = -1; Pipes[2] = -1; @@ -757,18 +757,19 @@ void Exit(struct lsof_context *ctx, enum ExitStatus xv) /* exit() value */ /* * Error() - exit with an error status */ -void Error(struct lsof_context *ctx) { Exit(ctx, LSOF_ERROR); } +void Error(struct lsof_context *ctx) { Exit(ctx, LSOF_EXIT_ERROR); } #if defined(HASNLIST) /* * get_Nl_value() - get Nl value for nickname */ -int get_Nl_value(char *nn, /* nickname of requested entry */ - struct drive_Nl *d, /* drive_Nl table that built Nl - * (if NULL, use Build_Nl) */ - KA_T *v) /* returned value (if NULL, - * return nothing) */ +int get_Nl_value(struct lsof_context *ctx, /* context */ + char *nn, /* nickname of requested entry */ + struct drive_Nl *d, /* drive_Nl table that built Nl + * (if NULL, use Build_Nl) */ + KA_T *v) /* returned value (if NULL, + * return nothing) */ { int i; @@ -824,10 +825,11 @@ int hashbyname(char *nm, /* pointer to NUL-terminated name */ * is_nw_addr() - is this network address selected? */ -int is_nw_addr(unsigned char *ia, /* Internet address */ - int p, /* port */ - int af) /* address family -- e.g., AF_INET, - * AF_INET6 */ +int is_nw_addr(struct lsof_context *ctx, /* context */ + unsigned char *ia, /* Internet address */ + int p, /* port */ + int af) /* address family -- e.g., AF_INET, + * AF_INET6 */ { struct nwad *n; @@ -967,8 +969,9 @@ char *mkstrcat(char *s1, /* source string 1 */ * is_readable() -- is file readable */ -int is_readable(char *path, /* file path */ - int msg) /* issue warning message if 1 */ +int is_readable(struct lsof_context *ctx, /* context */ + char *path, /* file path */ + int msg) /* issue warning message if 1 */ { if (access(path, R_OK) < 0) { if (!Fwarn && msg == 1) diff --git a/lib/node.c b/lib/node.c index be2df866..4da6c67b 100644 --- a/lib/node.c +++ b/lib/node.c @@ -50,8 +50,8 @@ char *print_kptr(KA_T kp, /* kernel pointer address */ */ int readcdrnode(struct lsof_context *ctx, /* context */ - KA_T ca, /* cdrnode kernel address */ - struct cdrnode *c) /* cdrnode buffer */ + KA_T ca, /* cdrnode kernel address */ + struct cdrnode *c) /* cdrnode buffer */ { if (kread(ctx, (KA_T)ca, (char *)c, sizeof(struct cdrnode))) { (void)snpf(Namech, Namechl, "can't read cdrnode at %s", @@ -86,8 +86,8 @@ int readfifonode(struct lsof_context *ctx, /* context */ */ int readgnode(struct lsof_context *ctx, /* context */ - KA_T ga, /* gnode kernel address */ - struct gnode *g) /* gnode buffer */ + KA_T ga, /* gnode kernel address */ + struct gnode *g) /* gnode buffer */ { if (kread(ctx, (KA_T)ga, (char *)g, sizeof(struct gnode))) { (void)snpf(Namech, Namechl, "can't read gnode at %s", diff --git a/lib/print.c b/lib/print.c index 93b3fddf..96581523 100644 --- a/lib/print.c +++ b/lib/print.c @@ -433,7 +433,7 @@ void file_type_to_string(enum lsof_file_type type, (void)snpf(buf, buf_len, "DOOR"); break; case LSOF_FILE_VNODE_VPORT: - + (void)snpf(buf, buf_len, "PORT"); break; case LSOF_FILE_VNODE_VUNNAMED: (void)snpf(buf, buf_len, "UNNM"); diff --git a/lib/proc.c b/lib/proc.c index 4ed3b8a4..05a3c506 100644 --- a/lib/proc.c +++ b/lib/proc.c @@ -449,8 +449,8 @@ void ent_inaddr(struct lsof_context *ctx, * If network address matching has been selected, check both addresses. */ if ((Selflags & SELNA) && Nwad) { - m = (fa && is_nw_addr(fa, fp, af)) ? 1 : 0; - m |= (la && is_nw_addr(la, lp, af)) ? 1 : 0; + m = (fa && is_nw_addr(ctx, fa, fp, af)) ? 1 : 0; + m |= (la && is_nw_addr(ctx, la, lp, af)) ? 1 : 0; if (m) Lf->sf |= SELNA; } @@ -606,8 +606,9 @@ int is_cmd_excl(struct lsof_context *ctx, char *cmd, /* command name */ * is_file_sel() - is file selected? */ -int is_file_sel(struct lproc *lp, /* lproc structure pointer */ - struct lfile *lf) /* lfile structure pointer */ +int is_file_sel(struct lsof_context *ctx, /* context */ + struct lproc *lp, /* lproc structure pointer */ + struct lfile *lf) /* lfile structure pointer */ { if (!lf || !lf->sf) return (0); @@ -970,7 +971,7 @@ void process_pinfo(struct lsof_context *ctx, /* * Process already selected pipe file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -991,7 +992,7 @@ void process_pinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_PIPE)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_PIPE)) { /* * This is an unselected end point file. Select it and add @@ -1068,7 +1069,7 @@ void process_psxmqinfo(struct lsof_context *ctx, /* * Process already selected posix mq file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -1089,7 +1090,7 @@ void process_psxmqinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_PSXMQ)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_PSXMQ)) { /* * This is an unselected end point file. Select it and add @@ -1167,7 +1168,7 @@ void process_evtfdinfo(struct lsof_context *ctx, /* * Process already selected eventfd_id file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -1188,7 +1189,7 @@ void process_evtfdinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_EVTFD)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_EVTFD)) { /* * This is an unselected end point file. Select it and add @@ -1341,7 +1342,7 @@ int print_proc(struct lsof_context *ctx) { * won't produce a false positive result. */ for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { (void)printf("%d\n", Lp->pid); return (1); } @@ -1354,7 +1355,7 @@ int print_proc(struct lsof_context *ctx) { */ if (Ffield) { for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (is_file_sel(Lp, Lf)) + if (is_file_sel(ctx, Lp, Lf)) break; } if (!Lf) @@ -1406,7 +1407,7 @@ int print_proc(struct lsof_context *ctx) { * Print files. */ for (Lf = Lp->file; Lf; Lf = Lf->next) { - if (!is_file_sel(Lp, Lf)) + if (!is_file_sel(ctx, Lp, Lf)) continue; rv = 1; /* @@ -1596,7 +1597,7 @@ void process_ptyinfo(struct lsof_context *ctx, /* * Process already selected pseudoterminal file. */ - if (is_file_sel(Lp, Lf)) { + if (is_file_sel(ctx, Lp, Lf)) { /* * This file has been selected by some criterion other than @@ -1620,7 +1621,7 @@ void process_ptyinfo(struct lsof_context *ctx, } break; case 1: - if (!is_file_sel(Lp, Lf) && (Lf->chend & CHEND_PTY)) { + if (!is_file_sel(ctx, Lp, Lf) && (Lf->chend & CHEND_PTY)) { /* * This is an unselected end point file. Select it and add diff --git a/lib/proto.h b/lib/proto.h index a7e2655c..bf686254 100644 --- a/lib/proto.h +++ b/lib/proto.h @@ -56,7 +56,7 @@ extern void alloc_lproc(struct lsof_context *ctx, int pid, int pgid, int ppid, UID_ARG uid, char *cmd, int pss, int sf); extern void build_IPstates(struct lsof_context *ctx); extern void childx(struct lsof_context *ctx); -extern void closefrom_shim(int low); +extern void closefrom_shim(struct lsof_context *ctx, int low); extern int ck_fd_status(struct lsof_context *ctx, enum lsof_fd_type fd_type, int num); extern int ck_file_arg(struct lsof_context *ctx, int i, int ac, char *av[], @@ -91,8 +91,7 @@ extern void enter_nm(struct lsof_context *ctx, char *m); extern int enter_state_spec(struct lsof_context *ctx, char *ss); # endif /* defined(HASTCPUDPSTATE) */ -extern int enter_str_lst(char *opt, char *s, struct str_lst **lp, int *incl, - int *excl); +extern int enter_cmd(struct lsof_context *ctx, char *opt, char *s); extern int enter_uid(struct lsof_context *ctx, char *us); extern void ent_inaddr(struct lsof_context *ctx, unsigned char *la, int lp, unsigned char *fa, int fp, int af); @@ -158,8 +157,10 @@ extern void hashSfile(struct lsof_context *ctx); extern void initialize(struct lsof_context *ctx); extern int is_cmd_excl(struct lsof_context *ctx, char *cmd, short *pss, short *sf); -extern int is_file_sel(struct lproc *lp, struct lfile *lf); -extern int is_nw_addr(unsigned char *ia, int p, int af); +extern int is_file_sel(struct lsof_context *ctx, struct lproc *lp, + struct lfile *lf); +extern int is_nw_addr(struct lsof_context *ctx, unsigned char *ia, int p, + int af); # if defined(HASTASKS) extern int is_proc_excl(struct lsof_context *ctx, int pid, int pgid, @@ -169,7 +170,7 @@ extern int is_proc_excl(struct lsof_context *ctx, int pid, int pgid, UID_ARG uid, short *pss, short *sf); # endif /* defined(HASTASKS) */ -extern int is_readable(char *path, int msg); +extern int is_readable(struct lsof_context *ctx, char *path, int msg); extern int kread(struct lsof_context *ctx, KA_T addr, char *buf, READLEN_T len); extern void link_lfile(struct lsof_context *ctx); extern struct l_dev *lkupdev(struct lsof_context *ctx, dev_t *dev, dev_t *rdev, @@ -233,7 +234,7 @@ extern int ctrl_dcache(struct lsof_context *ctx, char *p); extern int dcpath(struct lsof_context *ctx, int rw, int npw); extern int open_dcache(struct lsof_context *ctx, int m, int r, struct stat *sb); extern int read_dcache(struct lsof_context *ctx); -extern int wr2DCfd(char *b, unsigned *c); +extern int wr2DCfd(struct lsof_context *ctx, char *b, unsigned *c); extern void write_dcache(struct lsof_context *ctx); # endif /* defined(HASDCACHE) */ @@ -269,7 +270,8 @@ extern char *ncache_lookup(struct lsof_context *ctx, char *buf, int blen, # if defined(HASNLIST) extern void build_Nl(struct lsof_context *ctx, struct drive_Nl *d); -extern int get_Nl_value(char *nn, struct drive_Nl *d, KA_T *v); +extern int get_Nl_value(struct lsof_context *ctx, char *nn, struct drive_Nl *d, + KA_T *v); # endif /* defined(HASNLIST) */ # if defined(HASPIPENODE) @@ -293,7 +295,7 @@ extern int HASPRIVNMCACHE(struct lsof_context *ctx, struct lfile *lf); # endif /* defined(HASPRIVNMCACHE) */ # if !defined(HASPRIVPRIPP) -extern void printiproto(int p); +extern void printiproto(struct lsof_context *ctx, int p); # endif /* !defined(HASPRIVPRIPP) */ # if defined(HASRNODE) diff --git a/lib/rnmh.c b/lib/rnmh.c index 8df72d8e..b2963826 100644 --- a/lib/rnmh.c +++ b/lib/rnmh.c @@ -340,7 +340,7 @@ void ncache_load(struct lsof_context *ctx) { * Get kernel cache hash table size */ v = (KA_T)0; - if (get_Nl_value(X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || !v || + if (get_Nl_value(ctx, X_NCSIZE, (struct drive_Nl *)NULL, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&khsz, sizeof(khsz))) { if (!Fwarn) (void)fprintf(stderr, @@ -361,7 +361,7 @@ void ncache_load(struct lsof_context *ctx) { */ ka = (KA_T)0; v = (KA_T)0; - if (get_Nl_value(X_NCACHE, (struct drive_Nl *)NULL, &v) < 0 || !v || + if (get_Nl_value(ctx, X_NCACHE, (struct drive_Nl *)NULL, &v) < 0 || !v || kread(ctx, (KA_T)v, (char *)&ka, sizeof(ka)) || !ka) { if (!Fwarn) (void)fprintf( diff --git a/src/arg.c b/src/arg.c index d407ca18..9a5dcb47 100644 --- a/src/arg.c +++ b/src/arg.c @@ -49,7 +49,8 @@ static int NCmdRxA = 0; /* space allocated to CmdRx[] */ * Local function prototypes */ -static int ckfd_range(char *first, char *dash, char *last, int *lo, int *hi); +static int ckfd_range(struct lsof_context *ctx, char *first, char *dash, + char *last, int *lo, int *hi); static int enter_fd_lst(struct lsof_context *ctx, char *nm, int lo, int hi, int excl); static int enter_nwad(struct lsof_context *ctx, struct nwad *n, int sp, int ep, @@ -61,11 +62,12 @@ static char *isIPv4addr(char *hn, unsigned char *a, int al); * ckfd_range() - check fd range */ -static int ckfd_range(char *first, /* starting character */ - char *dash, /* '-' location */ - char *last, /* '\0' location */ - int *lo, /* returned low value */ - int *hi) /* returned high value */ +static int ckfd_range(struct lsof_context *ctx, /* context */ + char *first, /* starting character */ + char *dash, /* '-' location */ + char *last, /* '\0' location */ + int *lo, /* returned low value */ + int *hi) /* returned high value */ { char *cp; /* @@ -822,7 +824,7 @@ int enter_fd(struct lsof_context *ctx, /* context */ *cp2 = '\0'; if (cp2 > cp1) { if (dash) { - if (ckfd_range(cp1, dash, cp2, &lo, &hi)) + if (ckfd_range(ctx, cp1, dash, cp2, &lo, &hi)) err = 1; else { if (enter_fd_lst(ctx, (char *)NULL, lo, hi, excl)) @@ -2156,17 +2158,15 @@ int enter_state_spec(struct lsof_context *ctx, #endif /* defined(HASTCPUDPSTATE) */ /* - * enter_str_lst() - enter a string on a list + * enter_cmd() - enter -c option */ -int enter_str_lst(char *opt, /* option name */ - char *s, /* string to enter */ - struct str_lst **lp, /* string's list */ - int *incl, /* included count */ - int *excl) /* excluded count */ +int enter_cmd(struct lsof_context *ctx, /* context */ + char *opt, /* option name */ + char *s) /* string to enter */ { char *cp; - short i, x; + short x; MALLOC_S len; struct str_lst *lpt; @@ -2175,35 +2175,15 @@ int enter_str_lst(char *opt, /* option name */ return (1); } if (*s == '^') { - i = 0; x = 1; s++; } else { - i = 1; x = 0; } - if (!(cp = mkstrcpy(s, &len))) { - (void)fprintf(stderr, "%s: no string copy space: ", Pn); - safestrprt(s, stderr, 1); - return (1); - } - if ((lpt = (struct str_lst *)malloc(sizeof(struct str_lst))) == NULL) { - (void)fprintf(stderr, "%s: no list space: ", Pn); - safestrprt(s, stderr, 1); - (void)free((FREE_P *)cp); - return (1); + if (lsof_select_process(ctx, s, x) != LSOF_SUCCESS) { + return 1; } - lpt->f = 0; - lpt->str = cp; - lpt->len = (int)len; - lpt->x = x; - if (i) - *incl += 1; - if (x) - *excl += 1; - lpt->next = *lp; - *lp = lpt; - return (0); + return 0; } /* diff --git a/src/main.c b/src/main.c index 58454f8e..8e2f2c14 100644 --- a/src/main.c +++ b/src/main.c @@ -43,7 +43,8 @@ static char *GOv = (char *)NULL; /* option `:' value pointer */ static int GOx1 = 1; /* first opt[][] index */ static int GOx2 = 0; /* second opt[][] index */ -static int GetOpt(int ct, char *opt[], char *rules, int *err); +static int GetOpt(struct lsof_context *ctx, int ct, char *opt[], char *rules, + int *err); static char *sv_fmt_str(struct lsof_context *ctx, char *f); /* @@ -56,7 +57,7 @@ int main(int argc, char *argv[]) { int ad, c, i, n, se1, se2, ss; char *cp; int err = 0; - enum ExitStatus ev = LSOF_SUCCESS; + enum ExitStatus ev = LSOF_EXIT_SUCCESS; int fh = 0; char *fmtr = (char *)NULL; long l; @@ -95,6 +96,9 @@ int main(int argc, char *argv[]) { CntxStatus = is_selinux_enabled() ? 1 : 0; #endif /* defined(HASSELINUX) */ + /* Initialize lsof context */ + ctx = lsof_new(); + /* * Save program name. */ @@ -102,6 +106,8 @@ int main(int argc, char *argv[]) { Pn++; else Pn = argv[0]; + lsof_set_output_stream(ctx, stderr, Pn, 0); + /* * Close enough file descriptors above 2 that library functions will have * open descriptors. @@ -115,7 +121,7 @@ int main(int argc, char *argv[]) { if ((MaxFd = (int)GET_MAX_FD()) < 53) MaxFd = 53; - closefrom_shim(3); + closefrom_shim(ctx, 3); while (((i = open("/dev/null", O_RDWR, 0)) >= 0) && (i < 2)) ; @@ -233,7 +239,7 @@ int main(int argc, char *argv[]) { /* * Loop through options. */ - while ((c = GetOpt(argc, argv, options, &gopt_rv)) != EOF) { + while ((c = GetOpt(ctx, argc, argv, options, &gopt_rv)) != EOF) { if (gopt_rv) { err = 1; continue; @@ -258,7 +264,7 @@ int main(int argc, char *argv[]) { #endif /* defined(HAS_AFS) && defined(HASAOPT) */ case 'b': - Fblock = 1; + lsof_avoid_blocking(ctx, 1); break; case 'c': if (GOp == '+') { @@ -289,20 +295,8 @@ int main(int argc, char *argv[]) { if (enter_cmd_rx(ctx, GOv)) err = 1; } else { - if (enter_str_lst("-c", GOv, &Cmdl, &Cmdni, &Cmdnx)) + if (enter_cmd(ctx, "-c", GOv)) err = 1; - -#if defined(MAXSYSCMDL) - else if (Cmdl->len > MAXSYSCMDL) { - (void)fprintf(stderr, "%s: \"-c ", Pn); - (void)safestrprt(Cmdl->str, stderr, 2); - (void)fprintf(stderr, "\" length (%d) > what system", - Cmdl->len); - (void)fprintf(stderr, " provides (%d)\n", MAXSYSCMDL); - Cmdl->len = 0; /* (to avoid later error report) */ - err = 1; - } -#endif /* defined(MAXSYSCMDL) */ } break; @@ -736,7 +730,7 @@ int main(int argc, char *argv[]) { } break; case 'O': - Fovhd = (GOp == '-') ? 1 : 0; + lsof_avoid_forking(ctx, (GOp == '-') ? 1 : 0); break; case 'p': if (enter_id(ctx, PID, GOv)) @@ -750,7 +744,7 @@ int main(int argc, char *argv[]) { break; case 'r': if (GOp == '+') { - ev = LSOF_ERROR; + ev = LSOF_EXIT_ERROR; rc = 1; } if (!GOv || *GOv == '-' || *GOv == '+') { @@ -1276,7 +1270,7 @@ int main(int argc, char *argv[]) { */ if (MntSup == 1) { (void)readmnt(ctx); - Exit(ctx, LSOF_SUCCESS); + Exit(ctx, LSOF_EXIT_SUCCESS); } #endif /* defined(HASMNTSUP) */ @@ -1503,7 +1497,7 @@ int main(int argc, char *argv[]) { if (!n) break; else - ev = LSOF_SUCCESS; + ev = LSOF_EXIT_SUCCESS; } #if defined(HAS_STRFTIME) @@ -1553,7 +1547,7 @@ int main(int argc, char *argv[]) { * was; one, if not. If -V was specified, report what was not displayed. */ (void)childx(ctx); - rv = LSOF_SUCCESS; + rv = LSOF_EXIT_SUCCESS; for (str = Cmdl; str; str = str->next) { /* @@ -1808,7 +1802,7 @@ int main(int argc, char *argv[]) { if (!rv && rc) rv = ev; if (!rv && ErrStat) - rv = LSOF_ERROR; + rv = LSOF_EXIT_ERROR; Exit(ctx, rv); return (rv); /* to make code analyzers happy */ } @@ -1824,10 +1818,11 @@ int main(int argc, char *argv[]) { * value doesn't have one -- e.g., has a default instead. */ -static int GetOpt(int ct, /* option count */ - char *opt[], /* options */ - char *rules, /* option rules */ - int *err) /* error return */ +static int GetOpt(struct lsof_context *ctx, /* context */ + int ct, /* option count */ + char *opt[], /* options */ + char *rules, /* option rules */ + int *err) /* error return */ { register int c; register char *cp = (char *)NULL; diff --git a/src/print.c b/src/print.c index 0174e77f..09f01420 100644 --- a/src/print.c +++ b/src/print.c @@ -1325,7 +1325,8 @@ void print_init() { * printiproto() - print Internet protocol name */ -void printiproto(p) int p; /* protocol number */ +void printiproto(struct lsof_context *ctx, /* context */ + int p) /* protocol number */ { int i; static int m = -1; diff --git a/src/store.c b/src/store.c index 58abe110..f58c5d02 100644 --- a/src/store.c +++ b/src/store.c @@ -34,17 +34,6 @@ * Global storage definitions */ -int AllProc = 1; /* all processes are selected (default) */ - -#if defined(HASBLKDEV) -struct l_dev *BDevtp = (struct l_dev *)NULL; -/* block device table pointer */ -int BNdev = 0; /* number of entries in BDevtp[] */ -struct l_dev **BSdev = (struct l_dev **)NULL; -/* pointer to BDevtp[] pointers, sorted - * by device */ -#endif /* defined(HASBLKDEV) */ - int CkPasswd = 0; /* time to check /etc/passwd for change */ #if defined(HAS_STD_CLONE) @@ -52,85 +41,34 @@ struct clone *Clone = (struct clone *)NULL; /* clone device list */ #endif /* defined(HAS_STD_CLONE) */ -int CmdColW; /* COMMAND column width */ -struct str_lst *Cmdl = (struct str_lst *)NULL; -/* command names selected with -c */ +int CmdColW; /* COMMAND column width */ int CmdLim = CMDL; /* COMMAND column width limit */ -int Cmdni = 0; /* command name inclusions selected with -c */ -int Cmdnx = 0; /* command name exclusions selected with -c */ -lsof_rx_t *CmdRx = (lsof_rx_t *)NULL; -/* command regular expression table */ #if defined(HASSELINUX) -cntxlist_t *CntxArg = (cntxlist_t *)NULL; -/* security context arguments supplied with - * -Z */ int CntxColW; /* security context column width */ int CntxStatus = 0; /* security context status: 0 == disabled, * 1 == enabled */ #endif /* defined(HASSELINUX) */ -#if defined(HASDCACHE) -unsigned DCcksum; /* device cache file checksum */ -int DCfd = -1; /* device cache file descriptor */ -FILE *DCfs = (FILE *)NULL; /* stream pointer for DCfd */ -char *DCpathArg = (char *)NULL; /* device cache path from -D[b|r|u] */ -char *DCpath[] = { /* device cache paths, indexed by DCpathX - *when it's >= 0 */ - (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL}; -int DCpathX = -1; /* device cache path index: - * -1 = path not defined - * 0 = defined via -D - * 1 = defined via HASENVDC - * 2 = defined via HASSYSDC - * 3 = defined via HASPERSDC and - * HASPERSDCPATH */ -int DCrebuilt = 0; /* an unsafe device cache file has been - * rebuilt */ -int DCstate = 3; /* device cache state: - * 0 = ignore (-Di) - * 1 = build (-Db[path]) - * 2 = read; don't rebuild (-Dr[path]) - * 3 = update; read and rebuild if - * necessary (-Du[path]) - */ -int DCunsafe = 0; /* device cache file is potentially unsafe, - * (The [cm]time check failed.) */ -#endif /* defined(HASDCACHE) */ - int DChelp = 0; /* -D? status */ -int DevColW; /* DEVICE column width */ -dev_t DevDev; /* device number of /dev or its equivalent */ -struct l_dev *Devtp = (struct l_dev *)NULL; -/* device table pointer */ +int DevColW; /* DEVICE column width */ /* * Externals for a stkdir(), dumbed-down for older AIX compilers. */ -char **Dstk = (char **)NULL; /* the directory stack */ -int Dstkx = 0; /* Dstk[] index */ -int Dstkn = 0; /* Dstk[] entries allocated */ -efsys_list_t *Efsysl = (efsys_list_t *)NULL; -/* file systems for which kernel blocks are - * to be eliminated */ int ErrStat = 0; /* path stat() error count */ uid_t Euid; /* effective UID of this lsof process */ -int Fand = 0; /* -a option status */ -int Fblock = 0; /* -b option status */ int FcColW; /* FCT column width */ int Fcntx = 0; /* -Z option status */ int FdColW; /* FD column width */ -int FeptE = 0; /* -E option status: 0==none, 1==info, - * 2==info+files */ int Ffilesys = 0; /* -f option status: * 0 = paths may be file systems * 1 = paths are just files * 2 = paths must be file systems */ #if defined(HASNCACHE) -int Fncache = 1; /* -C option status */ int NcacheReload = 1; /* 1 == call ncache_load() */ #endif /* defined(HASNCACHE) */ @@ -138,17 +76,8 @@ int Ffield = 0; /* -f and -F status */ int FgColW; /* FILE-FLAG column width */ int Fhelp = 0; /* -h option status */ int Fhost = 1; /* -H option status */ -int Fnet = 0; /* -i option status: 0==none - * 1==find all - * 2==some found*/ -int FnetTy = 0; /* Fnet type request: 0==all - * 4==IPv4 - * 6==IPv6 */ -int Fnfs = 0; /* -N option status: 0==none, 1==find all, - * 2==some found*/ int Fnlink = 0; /* -L option status */ int Foffset = 0; /* -o option status */ -int Fovhd = 0; /* -O option status */ int Fport = 1; /* -P option status */ #if !defined(HASNORPC_H) @@ -167,35 +96,17 @@ int FsColW; /* FSTR-ADDR column width */ int Fsv = FSV_DEFAULT; /* file struct value selections */ int FsvByf = 0; /* Fsv was set by +f */ int FsvFlagX = 0; /* hex format status for FSV_FG */ -int Ftask = 0; /* -K option value */ int NiColW; /* NODE-ID column width */ char *NiTtl = NITTL; /* NODE-ID column title */ int FsearchErr = 1; /* -Q option status */ int Ftcptpi = TCPTPI_STATE; /* -T option status */ int Fterse = 0; /* -t option status */ -int Funix = 0; /* -U option status */ int Futol = 1; /* -l option status */ int Fverbose = 0; /* -V option status */ -#if defined(WARNINGSTATE) -int Fwarn = 1; /* +|-w option status */ -#else /* !defined(WARNINGSTATE) */ -int Fwarn = 0; /* +|-w option status */ -#endif /* defined(WARNINGSTATE) */ - -#if defined(HASXOPT_VALUE) -int Fxopt = HASXOPT_VALUE; /* -X option status */ -#endif /* defined(HASXOPT_VALUE) */ - int Fxover = 0; /* -x option value */ int Fzone = 0; /* -z option status */ -struct fd_lst *Fdl = (struct fd_lst *)NULL; -/* file descriptors selected with -d */ -int FdlTy = -1; /* Fdl[] type: -1 == none - * 0 == include - * 1 == exclude */ - struct fieldsel FieldSel[] = { {LSOF_FID_ACCESS, 0, LSOF_FNM_ACCESS, NULL, 0}, /* 0 */ {LSOF_FID_CMD, 0, LSOF_FNM_CMD, NULL, 0}, /* 1 */ @@ -230,109 +141,29 @@ struct fieldsel FieldSel[] = { {LSOF_FID_TERM, 0, LSOF_FNM_TERM, NULL, 0}, /* 30 */ {' ', 0, NULL, NULL, 0}}; -int Hdr = 0; /* header print status */ -int IgnTasks = 0; /* ignore tasks when non-zero */ +int Hdr = 0; /* header print status */ char *InodeFmt_d = (char *)NULL; /* INODETYPE decimal printf specification */ char *InodeFmt_x = (char *)NULL; /* INODETYPE hexadecimal printf specification */ int LastPid = -1; /* last PID listed (for eliminating duplicates * in terse output) */ -struct lfile *Lf = (struct lfile *)NULL; -/* current local file structure */ -struct lproc *Lp = (struct lproc *)NULL; -/* current local process table entry */ -struct lproc *Lproc = (struct lproc *)NULL; -/* local process table */ -int MaxFd; /* maximum file descriptors to close */ -char *Memory = (char *)NULL; /* core file path */ -int MntSup = 0; /* mount supplement state: 0 == none - * 1 == create - * 2 == read */ -char *MntSupP = (char *)NULL; /* mount supplement path -- if MntSup == 2 */ -#if defined(HASPROCFS) -struct mounts *Mtprocfs = (struct mounts *)NULL; -/* /proc mount entry */ -#endif /* defined(HASPROCFS) */ - -int Mxpgid = 0; /* maximum process group ID table entries */ -int Mxpid = 0; /* maximum PID table entries */ -int Mxuid = 0; /* maximum UID table entries */ -gid_t Mygid; /* real GID of this lsof process */ -int Mypid; /* lsof's process ID */ -uid_t Myuid; /* real UID of this lsof process */ -char *Namech = (char *)NULL; /* name characters for printing */ -size_t Namechl = (size_t)0; /* sizeof(Namech) */ -int NCmdRxU = 0; /* number of CmdRx[] entries */ -int Ndev = 0; /* number of entries in Devtp[] */ - -#if defined(HASNLIST) -struct NLIST_TYPE *Nl = (struct NLIST_TYPE *)NULL; -/* kernel name list */ -int Nll = 0; /* Nl calloc'd length */ -#endif /* defined(HASNLIST) */ - -long Nlink = 0l; /* report nlink values below this number - * (0 = report all nlink values) */ -int Nlproc = 0; /* number of entries in Lproc[] */ -int NlColW; /* NLINK column width */ -int NmColW; /* NAME column width */ -char *Nmlst = (char *)NULL; /* namelist file path */ -int NodeColW; /* NODE column width */ -int Npgid = 0; /* -g option count */ -int Npgidi = 0; /* -g option inclusion count */ -int Npgidx = 0; /* -g option exclusion count */ -int Npid = 0; /* -p option count */ -int Npidi = 0; /* -p option inclusion count */ -int Npidx = 0; /* -p option exclusion count */ -int Npuns; /* number of unselected PIDs (starts at Npid) */ -int Ntype; /* node type (see N_* symbols) */ -int Nuid = 0; /* -u option count */ -int Nuidexcl = 0; /* -u option count of UIDs excluded */ -int Nuidincl = 0; /* -u option count of UIDs included */ -struct nwad *Nwad = (struct nwad *)NULL; -/* list of network addresses */ +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 */ int PidColW; /* PID column width */ -struct lfile *Plf = (struct lfile *)NULL; -/* previous local file structure */ -char *Pn; /* program name */ -int PpidColW; /* PPID column width */ +int PpidColW; /* PPID column width */ -#if defined(HASPROCFS) -int Procfind = 0; /* 1 when searching for an proc file system - * file and one was found */ -struct procfsid *Procfsid = (struct procfsid *)NULL; -/* proc file system PID search table */ -int Procsrch = 0; /* 1 if searching for any proc file system - * file */ -#endif /* defined(HASPROCFS) */ - -int PrPass = 0; /* print pass: 0 = compute column widths - * 1 = print */ -int RptTm = 0; /* repeat time -- set by -r */ -int RptMaxCount = 0; /* count of repeasts: 0 = no limit - * -- set by -r */ -struct l_dev **Sdev = (struct l_dev **)NULL; -/* pointer to Devtp[] pointers, sorted - * by device */ -int SelAll = 0; /* SELALL flags, modified by IgnTasks */ -int Selflags = 0; /* selection flags -- see SEL* in lsof.h */ -int SelProc = 0; /* SELPROC flags, modified by IgnTasks */ -int Setgid = 0; /* setgid state */ -int Selinet = 0; /* select only Internet socket files */ -int Setuidroot = 0; /* setuid-root state */ -struct sfile *Sfile = (struct sfile *)NULL; -/* chain of files to search for */ -struct int_lst *Spgid = (struct int_lst *)NULL; -/* process group IDs to search for */ -struct int_lst *Spid = (struct int_lst *)NULL; -/* Process IDs to search for */ -struct seluid *Suid = (struct seluid *)NULL; -/* User IDs to include or exclude */ +int PrPass = 0; /* print pass: 0 = compute column widths + * 1 = print */ +int RptTm = 0; /* repeat time -- set by -r */ +int RptMaxCount = 0; /* count of repeasts: 0 = no limit + * -- set by -r */ int SzColW; /* SIZE column width */ int SzOffColW; /* SIZE/OFF column width */ char *SzOffFmt_0t = (char *)NULL; /* SZOFFTYPE 0t%u printf specification */ @@ -344,44 +175,9 @@ int TaskCmdLim = TASKCMDL; /* TASKCMD column width limit (same as * CmdLim) */ int TaskPrtCmd = 0; /* task print task command flag */ int TaskPrtTid = 0; /* task print TID flag */ -int TcpStAlloc = 0; /* allocated (possibly unused) entries in TCP - * state tables */ -unsigned char *TcpStI = (unsigned char *)NULL; -/* included TCP states */ -int TcpStIn = 0; /* number of entries in TcpStI[] */ -int TcpStOff = 0; /* offset for TCP state number to adjust - * negative numbers to an index into TcpSt[], - * TcpStI[] and TcpStX[] */ -unsigned char *TcpStX = (unsigned char *)NULL; -/* excluded TCP states */ -int TcpStXn = 0; /* number of entries in TcpStX[] */ -int TcpNstates = 0; /* number of TCP states -- either in - * tcpstates[] or TcpSt[] */ -char **TcpSt = (char **)NULL; /* local TCP state names, indexed by system - * state value */ -char Terminator = '\n'; /* output field terminator */ -int TaskTidColW = 0; /* task TID column width */ -int TmLimit = TMLIMIT; /* Readlink() and stat() timeout (seconds) */ -int TypeColW; /* TYPE column width */ -int UdpStAlloc = 0; /* allocated (possibly unused) entries in UDP - * state tables */ -unsigned char *UdpStI = (unsigned char *)NULL; -/* included UDP states */ -int UdpStIn = 0; /* number of entries in UdpStI[] */ -int UdpStOff = 0; /* offset for UDP state number to adjust - * negative numbers to an index into UdpSt[], - * UdpStI[] and UdpStX[] */ -unsigned char *UdpStX = (unsigned char *)NULL; -/* excluded UDP states */ -int UdpStXn = 0; /* number of entries in UdpStX[] */ -int UdpNstates = 0; /* number of UDP states in UdpSt[] */ -char **UdpSt = (char **)NULL; /* local UDP state names, indexed by system - * state number */ -int UserColW; /* USER column width */ - -#if defined(HASZONES) -znhash_t **ZoneArg = (znhash_t **)NULL; -/* zone arguments supplied with -z */ -#endif /* defined(HASZONES) */ +char Terminator = '\n'; /* output field terminator */ +int TaskTidColW = 0; /* task TID column width */ +int TypeColW; /* TYPE column width */ +int UserColW; /* USER column width */ -int ZoneColW; /* ZONE column width */ \ No newline at end of file +int ZoneColW; /* ZONE column width */ diff --git a/src/usage.c b/src/usage.c index b1dcc1e8..ec5790b9 100644 --- a/src/usage.c +++ b/src/usage.c @@ -450,7 +450,7 @@ void usage(struct lsof_context *ctx, /* context */ (void)fprintf(stderr, "Use the ``-h'' option to get more help information.\n"); if (!fh) - Exit(ctx, err ? LSOF_ERROR : LSOF_SUCCESS); + Exit(ctx, err ? LSOF_EXIT_ERROR : LSOF_EXIT_SUCCESS); } if (Fhelp) { (void)fprintf( @@ -993,5 +993,5 @@ void usage(struct lsof_context *ctx, /* context */ (void)report_HASDCACHE(ctx, 1, " ", "\t"); } - Exit(ctx, err ? LSOF_ERROR : LSOF_SUCCESS); + Exit(ctx, err ? LSOF_EXIT_ERROR : LSOF_EXIT_SUCCESS); }