2 * main.c - common main function for lsof
4 * V. Abell, Purdue University
9 * Copyright 1994 Purdue Research Foundation, West Lafayette, Indiana
10 * 47907. All rights reserved.
12 * Written by Victor A. Abell
14 * This software is not subject to any license of the American Telephone
15 * and Telegraph Company or the Regents of the University of California.
17 * Permission is granted to anyone to use this software for any purpose on
18 * any computer system, and to alter it and redistribute it freely, subject
19 * to the following restrictions:
21 * 1. Neither the authors nor Purdue University are responsible for any
22 * consequences of the use of this software.
24 * 2. The origin of this software must not be misrepresented, either by
25 * explicit claim or by omission. Credit to the authors and Purdue
26 * University must appear in documentation and sources.
28 * 3. Altered versions must be plainly marked as such, and must not be
29 * misrepresented as being the original software.
31 * 4. This notice may not be removed or altered.
35 static char copyright[] =
36 "@(#) Copyright 1994 Purdue Research Foundation.\nAll rights reserved.\n";
37 static char *rcsid = "$Id: main.c,v 1.55 2011/09/07 19:13:49 abe Exp $";
48 static int GObk[] = { 1, 1 }; /* option backspace values */
49 static char GOp; /* option prefix -- '+' or '-' */
50 static char *GOv = (char *)NULL; /* option `:' value pointer */
51 static int GOx1 = 1; /* first opt[][] index */
52 static int GOx2 = 0; /* second opt[][] index */
55 _PROTOTYPE(static int GetOpt,(int ct, char *opt[], char *rules, int *err));
56 _PROTOTYPE(static char *sv_fmt_str,(char *f));
60 * main() - main function for lsof
68 int ad, c, i, n, rv, se1, se2, ss;
73 char *fmtr = (char *)NULL;
77 struct nwad *np, *npn;
82 struct lproc **slp = (struct lproc **)NULL;
84 struct str_lst *str, *strt;
88 #if defined(HAS_STRFTIME)
89 char *fmt = (char *)NULL;
91 #endif /* defined(HAS_STRFTIME) */
95 #endif /* defined(HASZONES) */
97 #if defined(HASSELINUX)
99 * This stanza must be immediately before the "Save progam name." code, since
100 * it contains code itself.
104 CntxStatus = is_selinux_enabled() ? 1 : 0;
105 #endif /* defined(HASSELINUX) */
110 if ((Pn = strrchr(argv[0], '/')))
115 * Close all file descriptors above 2.
117 * Make sure stderr, stdout, and stdin are open descriptors. Open /dev/null
118 * for ones that aren't. Be terse.
120 * Make sure umask allows lsof to define its own file permissions.
122 for (i = 3, n = GET_MAX_FD(); i < n; i++)
124 while (((i = open("/dev/null", O_RDWR, 0)) >= 0) && (i < 2))
132 #if defined(HASSETLOCALE)
134 * Set locale to environment's definition.
136 (void) setlocale(LC_CTYPE, "");
137 #endif /* defined(HASSETLOCALE) */
140 * Common initialization.
143 if ((Mygid = (gid_t)getgid()) != getegid())
146 if ((Myuid = (uid_t)getuid()) && !Euid)
148 if (!(Namech = (char *)malloc(MAXPATHLEN + 1))) {
149 (void) fprintf(stderr, "%s: no space for name buffer\n", Pn);
152 Namechl = (size_t)(MAXPATHLEN + 1);
154 * Create option mask.
156 (void) snpf(options, sizeof(options),
157 "?a%sbc:%sD:d:%sf:F:g:hi:%s%slL:%s%snNo:Op:Pr:%ss:S:tT:u:UvVwx:%s%s%s",
159 #if defined(HAS_AFS) && defined(HASAOPT)
161 #else /* !defined(HAS_AFS) || !defined(HASAOPT) */
163 #endif /* defined(HAS_AFS) && defined(HASAOPT) */
165 #if defined(HASNCACHE)
167 #else /* !defined(HASNCACHE) */
169 #endif /* defined(HASNCACHE) */
173 #else /* !defined(HASEOPT) */
175 #endif /* defined(HASEOPT) */
179 #else /* !defined(HASKOPT) */
181 #endif /* defined(HASKOPT) */
183 #if defined(HASTASKS)
185 #else /* !defined(HASTASKS) */
187 #endif /* defined(HASTASKS) */
189 #if defined(HASMOPT) || defined(HASMNTSUP)
191 #else /* !defined(HASMOPT) && !defined(HASMNTSUP) */
193 #endif /* defined(HASMOPT) || defined(HASMNTSUP) */
195 #if defined(HASNORPC_H)
197 #else /* !defined(HASNORPC_H) */
199 #endif /* defined(HASNORPC_H) */
203 #else /* !defined(HASPPID) */
205 #endif /* defined(HASPPID) */
208 # if defined(HASXOPT_ROOT)
209 (Myuid == 0) ? "X" : "",
210 # else /* !defined(HASXOPT_ROOT) */
212 # endif /* defined(HASXOPT_ROOT) */
213 #else /* !defined(HASXOPT) */
215 #endif /* defined(HASXOPT) */
217 #if defined(HASZONES)
219 #else /* !defined(HASZONES) */
221 #endif /* defined(HASZONES) */
223 #if defined(HASSELINUX)
225 #else /* !defined(HASSELINUX) */
227 #endif /* defined(HASSELINUX) */
231 * Loop through options.
233 while ((c = GetOpt(argc, argv, options, &rv)) != EOF) {
243 #if defined(HAS_AFS) && defined(HASAOPT)
245 if (!GOv || *GOv == '-' || *GOv == '+') {
246 (void) fprintf(stderr, "%s: -A not followed by path\n", Pn);
255 #endif /* defined(HAS_AFS) && defined(HASAOPT) */
262 if (!GOv || (*GOv == '-') || (*GOv == '+')
263 || !isdigit((int)*GOv))
265 (void) fprintf(stderr,
266 "%s: +c not followed by width number\n", Pn);
275 #if defined(MAXSYSCMDL)
276 if (CmdLim > MAXSYSCMDL) {
277 (void) fprintf(stderr,
278 "%s: +c %d > what system provides (%d)\n",
279 Pn, CmdLim, MAXSYSCMDL);
282 #endif /* defined(MAXSYSCMDL) */
287 if (GOv && (*GOv == '/')) {
288 if (enter_cmd_rx(GOv))
291 if (enter_str_lst("-c", GOv, &Cmdl, &Cmdni, &Cmdnx))
294 #if defined(MAXSYSCMDL)
295 else if (Cmdl->len > MAXSYSCMDL) {
296 (void) fprintf(stderr, "%s: \"-c ", Pn);
297 (void) safestrprt(Cmdl->str, stderr, 2);
298 (void) fprintf(stderr, "\" length (%d) > what system",
300 (void) fprintf(stderr, " provides (%d)\n",
302 Cmdl->len = 0; /* (to avoid later error report) */
305 #endif /* defined(MAXSYSCMDL) */
310 #if defined(HASNCACHE)
312 Fncache = (GOp == '-') ? 0 : 1;
314 #endif /* defined(HASNCACHE) */
318 if (enter_efsys(GOv, ((GOp == '+') ? 1 : 0)))
321 #endif /* defined(HASEOPT) */
325 if (enter_dir(GOv, 0))
338 if (enter_dir(GOv, 1))
346 #if defined(HASDCACHE)
347 if (ctrl_dcache(GOv))
349 #else /* !defined(HASDCACHE) */
350 (void) fprintf(stderr, "%s: unsupported option: -D\n", Pn);
352 #endif /* defined(HASDCACHE) */
357 if (!GOv || *GOv == '-' || *GOv == '+') {
358 Ffilesys = (GOp == '+') ? 2 : 1;
366 #if defined(HASFSTRUCT)
367 for (; *GOv; GOv++) {
370 # if !defined(HASNOFSCOUNT)
377 Fsv &= (unsigned char)~FSV_CT;
379 # endif /* !defined(HASNOFSCOUNT) */
381 # if !defined(HASNOFSADDR)
388 Fsv &= (unsigned char)~FSV_FA;
390 # endif /* !defined(HASNOFSADDR) */
392 # if !defined(HASNOFSFLAGS)
399 Fsv &= (unsigned char)~FSV_FG;
400 FsvFlagX = (*GOv == 'G') ? 1 : 0;
402 # endif /* !defined(HASNOFSFLAGS) */
404 # if !defined(HASNOFSNADDR)
411 Fsv &= (unsigned char)~FSV_NI;
413 # endif /* !defined(HASNOFSNADDR */
416 (void) fprintf(stderr,
417 "%s: unknown file struct option: %c\n", Pn, *GOv);
421 #else /* !defined(HASFSTRUCT) */
422 (void) fprintf(stderr,
423 "%s: unknown string for %cf: %s\n", Pn, GOp, GOv);
425 #endif /* defined(HASFSTRUCT) */
429 if (!GOv || *GOv == '-' || *GOv == '+'
430 || strcmp(GOv, "0") == 0) {
432 if (*GOv == '-' || *GOv == '+') {
435 } else if (*GOv == '0')
438 for (i = 0; FieldSel[i].nm; i++) {
440 #if !defined(HASPPID)
441 if (FieldSel[i].id == LSOF_FID_PPID)
443 #endif /* !defined(HASPPID) */
445 #if !defined(HASFSTRUCT)
446 if (FieldSel[i].id == LSOF_FID_CT
447 || FieldSel[i].id == LSOF_FID_FA
448 || FieldSel[i].id == LSOF_FID_FG
449 || FieldSel[i].id == LSOF_FID_NI)
451 #endif /* !defined(HASFSTRUCT) */
453 #if defined(HASSELINUX)
454 if ((FieldSel[i].id == LSOF_FID_CNTX) && !CntxStatus)
456 #else /* !defined(HASSELINUX) */
457 if (FieldSel[i].id == LSOF_FID_CNTX)
459 #endif /* !defined(HASSELINUX) */
461 if (FieldSel[i].id == LSOF_FID_RDEV)
462 continue; /* for compatibility */
464 #if !defined(HASTASKS)
465 if (FieldSel[i].id == LSOF_FID_TID)
467 #endif /* !defined(HASTASKS) */
469 #if !defined(HASZONES)
470 if (FieldSel[i].id == LSOF_FID_ZONE)
472 #endif /* !defined(HASZONES) */
475 if (FieldSel[i].opt && FieldSel[i].ov)
476 *(FieldSel[i].opt) |= FieldSel[i].ov;
479 #if defined(HASFSTRUCT)
480 Ffield = FsvFlagX = 1;
481 #else /* !defined(HASFSTRUCT) */
483 #endif /* defined(HASFSTRUCT) */
487 if (strcmp(GOv, "?") == 0) {
491 for (; *GOv; GOv++) {
492 for (i = 0; FieldSel[i].nm; i++) {
494 #if !defined(HASPPID)
495 if (FieldSel[i].id == LSOF_FID_PPID)
497 #endif /* !defined(HASPPID) */
499 #if !defined(HASFSTRUCT)
500 if (FieldSel[i].id == LSOF_FID_CT
501 || FieldSel[i].id == LSOF_FID_FA
502 || FieldSel[i].id == LSOF_FID_FG
503 || FieldSel[i].id == LSOF_FID_NI)
505 #endif /* !defined(HASFSTRUCT) */
507 #if !defined(HASTASKS)
508 if (FieldSel[i].id == LSOF_FID_TID)
510 #endif /* !defined(HASTASKS) */
512 if (FieldSel[i].id == *GOv) {
514 if (FieldSel[i].opt && FieldSel[i].ov)
515 *(FieldSel[i].opt) |= FieldSel[i].ov;
517 #if defined(HASFSTRUCT)
518 if (i == LSOF_FIX_FG)
520 #endif /* defined(HASFSTRUCT) */
522 if (i == LSOF_FIX_TERM)
527 if ( ! FieldSel[i].nm) {
528 (void) fprintf(stderr,
529 "%s: unknown field: %c\n", Pn, *GOv);
537 if (*GOv == '-' || *GOv == '+') {
540 } else if (enter_id(PGID, GOv))
550 if (!GOv || *GOv == '-' || *GOv == '+') {
559 if (enter_network_address(GOv))
565 if (!GOv || *GOv == '-' || *GOv == '+') {
566 (void) fprintf(stderr, "%s: -k not followed by path\n", Pn);
575 #endif /* defined(HASKOPT) */
577 #if defined(HASTASKS)
582 #endif /* defined(HASTASKS) */
588 Fnlink = (GOp == '+') ? 1 : 0;
589 if (!GOv || *GOv == '-' || *GOv == '+') {
597 for (cp = GOv, l = 0l, n = 0; *cp; cp++) {
598 if (!isdigit((unsigned char)*cp))
600 l = (l * 10l) + ((long)*cp - (long)'0');
605 (void) fprintf(stderr,
606 "%s: no number may follow -L\n", Pn);
610 Selflags |= SELNLINK;
620 #if defined(HASMOPT) || defined(HASMNTSUP)
624 # if defined(HASMOPT)
625 if (!GOv || *GOv == '-' || *GOv == '+') {
626 (void) fprintf(stderr,
627 "%s: -m not followed by path\n", Pn);
635 # else /* !defined(HASMOPT) */
636 (void) fprintf(stderr, "%s: -m not supported\n", Pn);
638 # endif /* defined(HASMOPT) */
640 } else if (GOp == '+') {
642 # if defined(HASMNTSUP)
643 if (!GOv || *GOv == '-' || *GOv == '+') {
653 # else /* !defined(HASMNTSUP) */
654 (void) fprintf(stderr, "%s: +m not supported\n", Pn);
656 # endif /* defined(HASMNTSUP) */
659 (void) fprintf(stderr, "%s: %cm not supported\n", Pn, GOp);
663 #endif /* defined(HASMOPT) || defined(HASMNTSUP) */
665 #if !defined(HASNORPC_H)
667 FportMap = (GOp == '+') ? 1 : 0;
669 #endif /* !defined(HASNORPC_H) */
672 Fhost = (GOp == '-') ? 0 : 1;
678 if (!GOv || *GOv == '-' || *GOv == '+') {
686 for (cp = GOv, i = n = 0; *cp; cp++) {
687 if (!isdigit((unsigned char)*cp))
689 i = (i * 10) + ((int)*cp - '0');
702 Fovhd = (GOp == '-') ? 1 : 0;
705 if (enter_id(PID, GOv))
709 Fport = (GOp == '-') ? 0 : 1;
714 if (!GOv || *GOv == '-' || *GOv == '+') {
722 for (cp = GOv, i = n = 0; *cp; cp++) {
723 if (!isdigit((unsigned char)*cp))
725 i = (i * 10) + ((int)*cp - '0');
734 while(*cp && (*cp == ' '))
736 if (*cp != LSOF_FID_MARK) {
742 #if defined(HAS_STRFTIME)
745 * Collect the strftime(3) format and test it.
748 if ((fmtl = strlen(cp) + 1) < 1) {
749 (void) fprintf(stderr, "%s: <fmt> too short: \"%s\"\n",
754 fmtl = (fmtl * 8) + 1;
755 if (!(fmtr = (char *)malloc((MALLOC_S)fmtl))) {
756 (void) fprintf(stderr,
757 "%s: no space (%d) for <fmt> result: \"%s\"\n",
761 if (util_strftime(fmtr, fmtl - 1, fmt) < 1) {
762 (void) fprintf(stderr, "%s: illegal <fmt>: \"%s\"\n",
768 #else /* !defined(HAS_STRFTIME) */
769 (void) fprintf(stderr, "%s: m<fmt> not supported: \"%s\"\n",
772 #endif /* defined(HAS_STRFTIME) */
780 #endif /* defined(HASPPID) */
784 #if defined(HASTCPUDPSTATE)
785 if (!GOv || *GOv == '-' || *GOv == '+') {
792 if (enter_state_spec(GOv))
795 #else /* !defined(HASTCPUDPSTATE) */
797 #endif /* defined(HASTCPUDPSTATE) */
801 if (!GOv || *GOv == '-' || *GOv == '+') {
809 for (cp = GOv, i = n = 0; *cp; cp++) {
810 if (!isdigit((unsigned char)*cp))
812 i = (i * 10) + ((int)*cp - '0');
823 if (TmLimit < TMLIMMIN) {
824 (void) fprintf(stderr,
825 "%s: WARNING: -S time (%d) changed to %d\n",
826 Pn, TmLimit, TMLIMMIN);
834 if (!GOv || *GOv == '-' || *GOv == '+') {
835 Ftcptpi = (GOp == '-') ? 0 : TCPTPI_STATE;
842 for (Ftcptpi = 0; *GOv; GOv++) {
845 #if defined(HASSOOPT) || defined(HASSOSTATE) || defined(HASTCPOPT)
847 Ftcptpi |= TCPTPI_FLAGS;
849 #endif /* defined(HASSOOPT) || defined(HASSOSTATE) || defined(HASTCPOPT) */
851 #if defined(HASTCPTPIQ)
853 Ftcptpi |= TCPTPI_QUEUES;
855 #endif /* defined(HASTCPTPIQ) */
858 Ftcptpi |= TCPTPI_STATE;
861 #if defined(HASTCPTPIW)
863 Ftcptpi |= TCPTPI_WINDOWS;
865 #endif /* defined(HASTCPTPIW) */
868 (void) fprintf(stderr,
869 "%s: unsupported TCP/TPI info selection: %c\n",
889 Fwarn = (GOp == '+') ? 0 : 1;
892 if (!GOv || *GOv == '-' || *GOv == '+') {
900 for (; *GOv; GOv++) {
903 Fxover |= XO_FILESYS;
906 Fxover |= XO_SYMLINK;
909 (void) fprintf(stderr,
910 "%s: unknown cross-over option: %c\n",
920 Fxopt = Fxopt ? 0 : 1;
922 #endif /* defined(HASXOPT) */
924 #if defined(HASZONES)
927 if (GOv && (*GOv != '-') && (*GOv != '+')) {
930 * Add to the zone name argument hash.
932 if (enter_zone_arg(GOv))
939 #endif /* defined(HASZONES) */
941 #if defined(HASSELINUX)
944 (void) fprintf(stderr, "%s: -Z limited to SELinux\n", Pn);
948 if (GOv && (*GOv != '-') && (*GOv != '+')) {
951 * Add to the context name argument hash.
953 if (enter_cntx_arg(GOv))
961 #endif /* defined(HASSELINUX) */
964 (void) fprintf(stderr, "%s: unknown option (%c)\n", Pn, c);
969 * Check for argument consistency.
971 if (Cmdnx && Cmdni) {
974 * Check for command inclusion/exclusion conflicts.
976 for (str = Cmdl; str; str = str->next) {
978 for (strt = Cmdl; strt; strt = strt->next) {
980 if (!strcmp(str->str, strt->str)) {
981 (void) fprintf(stderr,
982 "%s: -c^%s and -c%s conflict.\n",
983 Pn, str->str, strt->str);
992 #if defined(HASTCPUDPSTATE)
993 if (TcpStXn && TcpStIn) {
996 * Check for excluded and included TCP states.
998 for (i = 0; i < TcpNstates; i++) {
999 if (TcpStX[i] && TcpStI[i]) {
1000 (void) fprintf(stderr,
1001 "%s: can't include and exclude TCP state: %s\n",
1007 if (UdpStXn && UdpStIn) {
1010 * Check for excluded and included UDP states.
1012 for (i = 0; i < UdpNstates; i++) {
1013 if (UdpStX[i] && UdpStI[i]) {
1014 (void) fprintf(stderr,
1015 "%s: can't include and exclude UDP state: %s\n",
1021 #endif /* defined(HASTCPUDPSTATE) */
1023 if (Fsize && Foffset) {
1024 (void) fprintf(stderr, "%s: -o and -s are mutually exclusive\n",
1030 (void) fprintf(stderr,
1031 "%s: -F and -t are mutually exclusive\n", Pn);
1034 FieldSel[LSOF_FIX_PID].st = 1;
1036 #if defined(HAS_STRFTIME)
1040 * The field output marker format can't contain "%n" new line
1043 for (cp = strchr(fmt, '%'); cp; cp = strchr(cp, '%')) {
1045 (void) fprintf(stderr,
1046 "%s: %%n illegal in -r m<fmt> when -F has", Pn);
1047 (void) fprintf(stderr,
1048 " been specified: \"%s\"\n", fmt);
1051 } else if (*cp == '%')
1055 #endif /* defined(HAS_STRFTIME) */
1058 if (Fxover && !xover) {
1059 (void) fprintf(stderr, "%s: -x must accompany +d or +D\n", Pn);
1063 #if defined(HASEOPT)
1067 * If there are file systems specified by -e options, check them.
1069 efsys_list_t *ep; /* Efsysl pointer */
1070 struct mounts *mp, *mpw; /* local mount table pointers */
1072 if ((mp = readmnt())) {
1073 for (ep = Efsysl; ep; ep = ep->next) {
1074 for (mpw = mp; mpw; mpw = mpw->next) {
1075 if (!strcmp(mpw->dir, ep->path)) {
1081 (void) fprintf(stderr,
1082 "%s: \"-e %s\" is not a mounted file system.\n",
1089 #endif /* defined(HASEOPT) */
1091 if (DChelp || err || Fhelp || fh || version)
1092 usage(err ? 1 : 0, fh, version);
1094 * Reduce the size of Suid[], if necessary.
1096 if (Suid && Nuid && Nuid < Mxuid) {
1097 if (!(Suid = (struct seluid *)realloc((MALLOC_P *)Suid,
1098 (MALLOC_S)(sizeof(struct seluid) * Nuid))))
1100 (void) fprintf(stderr, "%s: can't realloc UID table\n", Pn);
1106 * Compute the selection flags.
1108 if ((Cmdl && Cmdni) || CmdRx)
1111 #if defined(HASSELINUX)
1113 Selflags |= SELCNTX;
1114 #endif /* defined(HASSELINUX) */
1124 if (Npgid && Npgidi)
1125 Selflags |= SELPGID;
1128 if (Nuid && Nuidincl)
1133 #if defined(HASZONES)
1135 Selflags |= SELZONE;
1136 #endif /* defined(HASZONES) */
1140 if (Selflags == 0) {
1142 (void) fprintf(stderr,
1143 "%s: no select options to AND via -a\n", Pn);
1148 if (GOx1 >= argc && (Selflags & (SELNA|SELNET)) != 0
1149 && (Selflags & ~(SELNA|SELNET)) == 0)
1154 * Get the device for DEVDEV_PATH.
1156 if (stat(DEVDEV_PATH, &sb)) {
1158 if ((ad = strcmp(DEVDEV_PATH, "/dev"))) {
1159 if ((ss = stat("/dev", &sb)))
1168 (void) fprintf(stderr, "%s: can't stat(%s): %s\n", Pn,
1169 DEVDEV_PATH, strerror(se1));
1171 (void) fprintf(stderr, "%s: can't stat(/dev): %s\n", Pn,
1179 * Process the file arguments.
1182 if (ck_file_arg(GOx1, argc, argv, Ffilesys, 0, (struct stat *)NULL))
1186 * Do dialect-specific initialization.
1192 #if defined(WILLDROPGID)
1194 * If this process isn't setuid(root), but it is setgid(not_real_gid),
1195 * relinquish the setgid power. (If it hasn't already been done.)
1198 #endif /* defined(WILLDROPGID) */
1201 #if defined(HASDCACHE)
1203 * If there is a device cache, prepare the device table.
1207 #endif /* defined(HASDCACHE) */
1210 * Define the size and offset print formats.
1212 (void) snpf(options, sizeof(options), "%%%su", INODEPSPEC);
1213 InodeFmt_d = sv_fmt_str(options);
1214 (void) snpf(options, sizeof(options), "%%#%sx", INODEPSPEC);
1215 InodeFmt_x = sv_fmt_str(options);
1216 (void) snpf(options, sizeof(options), "0t%%%su", SZOFFPSPEC);
1217 SzOffFmt_0t = sv_fmt_str(options);
1218 (void) snpf(options, sizeof(options), "%%%su", SZOFFPSPEC);
1219 SzOffFmt_d = sv_fmt_str(options);
1220 (void) snpf(options, sizeof(options), "%%*%su", SZOFFPSPEC);
1221 SzOffFmt_dv = sv_fmt_str(options);
1222 (void) snpf(options, sizeof(options), "%%#%sx", SZOFFPSPEC);
1223 SzOffFmt_x = sv_fmt_str(options);
1225 #if defined(HASMNTSUP)
1227 * Report mount supplement information, as requested.
1233 #endif /* defined(HASMNTSUP) */
1236 * Gather and report process information every RptTm seconds.
1243 * Gather information about processes.
1247 * If the local process table has more than one entry, sort it by PID.
1251 len = (MALLOC_S)(Nlproc * sizeof(struct lproc *));
1254 slp = (struct lproc **)malloc(len);
1256 slp = (struct lproc **)realloc((MALLOC_P *)slp, len);
1258 (void) fprintf(stderr,
1259 "%s: no space for %d sort pointers\n", Pn, Nlproc);
1263 for (i = 0; i < Nlproc; i++) {
1266 (void) qsort((QSORT_P *)slp, (size_t)Nlproc,
1267 (size_t)sizeof(struct lproc *), comppid);
1271 #if defined(HASNCACHE)
1273 * If using the kernel name cache, force its reloading.
1276 #endif /* defined(HASNCACHE) */
1279 * Print the selected processes and count them.
1281 * Lf contents must be preserved, since they may point to a
1282 * malloc()'d area, and since Lf is used throughout the print
1285 for (lf = Lf, print_init(); PrPass < 2; PrPass++) {
1286 for (i = n = 0; i < Nlproc; i++) {
1287 Lp = (Nlproc > 1) ? slp[i] : &Lproc[i];
1292 if (RptTm && PrPass)
1293 (void) free_lproc(Lp);
1299 * If a repeat time is set, sleep for the specified time.
1301 * If conditional repeat mode is in effect, see if it's time to exit.
1311 #if defined(HAS_STRFTIME)
1315 * Format the marker line.
1317 (void) util_strftime(fmtr, fmtl - 1, fmt);
1318 fmtr[fmtl - 1] = '\0';
1320 #endif /* defined(HAS_STRFTIME) */
1323 putchar(LSOF_FID_MARK);
1325 #if defined(HAS_STRFTIME)
1327 (void) printf("%s", fmtr);
1328 #endif /* defined(HAS_STRFTIME) */
1330 putchar(Terminator);
1331 if (Terminator != '\n')
1335 #if defined(HAS_STRFTIME)
1339 #endif /* defined(HAS_STRFTIME) */
1344 (void) fflush(stdout);
1346 (void) sleep(RptTm);
1352 * See if all requested information was displayed. Return zero if it
1353 * was; one, if not. If -V was specified, report what was not displayed.
1357 for (str = Cmdl; str; str = str->next) {
1360 * Check command specifications.
1366 (void) printf("%s: command not located: ", Pn);
1367 safestrprt(str->str, stdout, 1);
1370 for (i = 0; i < NCmdRxU; i++) {
1373 * Check command regular expressions.
1379 (void) printf("%s: no command found for regex: ", Pn);
1380 safestrprt(CmdRx[i].exp, stdout, 1);
1383 for (sfp = Sfile; sfp; sfp = sfp->next) {
1386 * Check file specifications.
1392 (void) printf("%s: no file%s use located: ", Pn,
1393 sfp->type ? "" : " system");
1394 safestrprt(sfp->aname, stdout, 1);
1398 #if defined(HASPROCFS)
1400 * Report on proc file system search results.
1402 if (Procsrch && !Procfind) {
1405 (void) printf("%s: no file system use located: ", Pn);
1406 safestrprt(Mtprocfs ? Mtprocfs->dir : HASPROCFS, stdout, 1);
1410 struct procfsid *pfi;
1412 for (pfi = Procfsid; pfi; pfi = pfi->next) {
1416 (void) printf("%s: no file use located: ", Pn);
1417 safestrprt(pfi->nm, stdout, 1);
1422 #endif /* defined(HASPROCFS) */
1427 * Check Internet address specifications.
1429 * If any Internet address derived from the same argument was found,
1430 * consider all derivations found. If no derivation from the same
1431 * argument was found, report only the first failure.
1434 for (; np; np = np->next) {
1435 if (!(cp = np->arg))
1437 for (npn = np->next; npn; npn = npn->next) {
1440 if (!strcmp(cp, npn->arg)) {
1443 * If either of the duplicate specifications was found,
1444 * mark them both found. If neither was found, mark all
1445 * but the first one found.
1456 for (np = Nwad; np; np = np->next) {
1457 if (!np->f && (cp = np->arg)) {
1460 (void) printf("%s: Internet address not located: ", Pn);
1461 safestrprt(cp ? cp : "(unknown)", stdout, 1);
1466 if (Fnet && Fnet < 2) {
1469 * Report no Internet files located.
1473 (void) printf("%s: no Internet files located\n", Pn);
1476 #if defined(HASTCPUDPSTATE)
1480 * Check for included TCP states not located.
1482 for (i = 0; i < TcpNstates; i++) {
1483 if (TcpStI[i] == 1) {
1486 (void) printf("%s: TCP state not located: %s\n",
1494 * Check for included UDP states not located.
1496 for (i = 0; i < UdpNstates; i++) {
1497 if (UdpStI[i] == 1) {
1500 (void) printf("%s: UDP state not located: %s\n",
1505 #endif /* defined(HASTCPUDPSTATE) */
1507 if (Fnfs && Fnfs < 2) {
1510 * Report no NFS files located.
1514 (void) printf("%s: no NFS files located\n", Pn);
1516 for (i = 0; i < Npid; i++) {
1519 * Check inclusionary process ID specifications.
1521 if (Spid[i].f || Spid[i].x)
1525 (void) printf("%s: process ID not located: %d\n",
1529 #if defined(HASTASKS)
1530 if (Ftask && Ftask < 2) {
1533 * Report no tasks located.
1537 (void) printf("%s: no tasks located\n", Pn);
1539 #endif /* defined(HASTASKS) */
1541 #if defined(HASZONES)
1545 * Check zone argument results.
1547 for (i = 0; i < HASHZONE; i++) {
1548 for (zp = ZoneArg[i]; zp; zp = zp->next) {
1552 (void) printf("%s: zone not located: ", Pn);
1553 safestrprt(zp->zn, stdout, 1);
1559 #endif /* defined(HASZONES) */
1561 #if defined(HASSELINUX)
1565 * Check context argument results.
1567 for (cntxp = CntxArg; cntxp; cntxp = cntxp->next) {
1571 (void) printf("%s: context not located: ", Pn);
1572 safestrprt(cntxp->cntx, stdout, 1);
1577 #endif /* defined(HASSELINUX) */
1579 for (i = 0; i < Npgid; i++) {
1582 * Check inclusionary process group ID specifications.
1584 if (Spgid[i].f || Spgid[i].x)
1588 (void) printf("%s: process group ID not located: %d\n",
1591 for (i = 0; i < Nuid; i++) {
1594 * Check inclusionary user ID specifications.
1596 if (Suid[i].excl || Suid[i].f)
1601 (void) printf("%s: login name (UID %lu) not located: ",
1602 Pn, (unsigned long)Suid[i].uid);
1603 safestrprt(Suid[i].lnm, stdout, 1);
1605 (void) printf("%s: user ID not located: %lu\n", Pn,
1606 (unsigned long)Suid[i].uid);
1614 return(rv); /* to make code analyzers happy */
1619 * GetOpt() -- Local get option
1621 * Liberally adapted from the public domain AT&T getopt() source,
1622 * distributed at the 1985 UNIFORM conference in Dallas
1624 * The modifications allow `?' to be an option character and allow
1625 * the caller to decide that an option that may be followed by a
1626 * value doesn't have one -- e.g., has a default instead.
1630 GetOpt(ct, opt, rules, err)
1631 int ct; /* option count */
1632 char *opt[]; /* options */
1633 char *rules; /* option rules */
1634 int *err; /* error return */
1637 register char *cp = (char *)NULL;
1642 * Move to a new entry of the option array.
1646 * Option list has been exhausted;
1647 * Next option doesn't start with `-' or `+';
1648 * Next option has nothing but `-' or `+';
1649 * Next option is ``--'' or ``++''.
1652 || (opt[GOx1][0] != '-' && opt[GOx1][0] != '+')
1655 if (strcmp(opt[GOx1], "--") == 0 || strcmp(opt[GOx1], "++") == 0) {
1663 * Flag `:' option character as an error.
1665 * Check for a rule on this option character.
1668 if ((c = opt[GOx1][GOx2]) == ':') {
1669 (void) fprintf(stderr,
1670 "%s: colon is an illegal option character.\n", Pn);
1672 } else if (!(cp = strchr(rules, c))) {
1673 (void) fprintf(stderr, "%s: illegal option character: %c\n", Pn, c);
1679 * An error was detected.
1681 * Advance to the next option character.
1683 * Return the character causing the error.
1685 if (opt[GOx1][++GOx2] == '\0') {
1691 if (*(cp + 1) == ':') {
1694 * The option may have a following value. The caller decides
1697 * Save the position of the possible value in case the caller
1698 * decides it does not belong to the option and wants it
1699 * reconsidered as an option character. The caller does that
1701 * GOx1 = GObk[0]; GOx2 = GObk[1];
1703 * Don't indicate that an option of ``--'' is a possible value.
1705 * Finally, on the assumption that the caller will decide that
1706 * the possible value belongs to the option, position to the
1707 * option following the possible value, so that the next call
1708 * to GetOpt() will find it.
1710 if(opt[GOx1][GOx2 + 1] != '\0') {
1713 GOv = &opt[GOx1++][GOx2];
1714 } else if (++GOx1 >= ct)
1720 if (strcmp(GOv, "--") == 0)
1729 * The option character stands alone with no following value.
1731 * Advance to the next option character.
1733 if (opt[GOx1][++GOx2] == '\0') {
1740 * Return the option character.
1747 * sv_fmt_str() - save format string
1752 char *f; /* format string */
1757 l = (MALLOC_S)(strlen(f) + 1);
1758 if (!(cp = (char *)malloc(l))) {
1759 (void) fprintf(stderr,
1760 "%s: can't allocate %d bytes for format: %s\n", Pn, (int)l, f);
1763 (void) snpf(cp, l, "%s", f);