xref: /illumos-gate/usr/src/cmd/pgrep/psexp.c (revision a4568e19224dbd8e405999c57ff8d4e4fd0d877f)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <string.h>
28 #include <stdlib.h>
29 #include <alloca.h>
30 #include <libuutil.h>
31 
32 #include "idtab.h"
33 #include "psexp.h"
34 
35 void
36 psexp_create(psexp_t *psexp)
37 {
38 	idtab_create(&psexp->ps_euids);
39 	idtab_create(&psexp->ps_ruids);
40 	idtab_create(&psexp->ps_rgids);
41 	idtab_create(&psexp->ps_ppids);
42 	idtab_create(&psexp->ps_pgids);
43 	idtab_create(&psexp->ps_sids);
44 	idtab_create(&psexp->ps_ttys);
45 	idtab_create(&psexp->ps_projids);
46 	idtab_create(&psexp->ps_taskids);
47 	idtab_create(&psexp->ps_zoneids);
48 	idtab_create(&psexp->ps_ctids);
49 
50 	psexp->ps_pat = NULL;
51 }
52 
53 void
54 psexp_destroy(psexp_t *psexp)
55 {
56 	idtab_destroy(&psexp->ps_euids);
57 	idtab_destroy(&psexp->ps_ruids);
58 	idtab_destroy(&psexp->ps_rgids);
59 	idtab_destroy(&psexp->ps_ppids);
60 	idtab_destroy(&psexp->ps_pgids);
61 	idtab_destroy(&psexp->ps_sids);
62 	idtab_destroy(&psexp->ps_ttys);
63 	idtab_destroy(&psexp->ps_projids);
64 	idtab_destroy(&psexp->ps_taskids);
65 	idtab_destroy(&psexp->ps_zoneids);
66 	idtab_destroy(&psexp->ps_ctids);
67 
68 	if (psexp->ps_pat)
69 		regfree(&psexp->ps_reg);
70 }
71 
72 int
73 psexp_compile(psexp_t *psexp)
74 {
75 	size_t nbytes;
76 	char *buf;
77 	int err;
78 
79 	idtab_sort(&psexp->ps_euids);
80 	idtab_sort(&psexp->ps_ruids);
81 	idtab_sort(&psexp->ps_rgids);
82 	idtab_sort(&psexp->ps_ppids);
83 	idtab_sort(&psexp->ps_pgids);
84 	idtab_sort(&psexp->ps_sids);
85 	idtab_sort(&psexp->ps_ttys);
86 	idtab_sort(&psexp->ps_projids);
87 	idtab_sort(&psexp->ps_taskids);
88 	idtab_sort(&psexp->ps_zoneids);
89 	idtab_sort(&psexp->ps_ctids);
90 
91 	if (psexp->ps_pat != NULL) {
92 		if ((err = regcomp(&psexp->ps_reg, psexp->ps_pat,
93 		    REG_EXTENDED)) != 0) {
94 
95 			nbytes = regerror(err, &psexp->ps_reg, NULL, 0);
96 			buf = alloca(nbytes + 1);
97 			(void) regerror(err, &psexp->ps_reg, buf, nbytes);
98 			(void) strcat(buf, "\n");
99 			uu_warn(buf);
100 			return (-1);
101 		}
102 	}
103 
104 	return (0);
105 }
106 
107 #define	NOMATCH(__f1, __f2) \
108 	psexp->__f1.id_data && !idtab_search(&psexp->__f1, psinfo->__f2)
109 
110 int
111 psexp_match(psexp_t *psexp, psinfo_t *psinfo, int flags)
112 {
113 	regmatch_t pmatch;
114 	const char *s;
115 
116 	if (NOMATCH(ps_euids, pr_euid))
117 		return (0);
118 	if (NOMATCH(ps_ruids, pr_uid))
119 		return (0);
120 	if (NOMATCH(ps_rgids, pr_gid))
121 		return (0);
122 	if (NOMATCH(ps_ppids, pr_ppid))
123 		return (0);
124 	if (NOMATCH(ps_pgids, pr_pgid))
125 		return (0);
126 	if (NOMATCH(ps_sids, pr_sid))
127 		return (0);
128 	if (NOMATCH(ps_ttys, pr_ttydev))
129 		return (0);
130 	if (NOMATCH(ps_projids, pr_projid))
131 		return (0);
132 	if (NOMATCH(ps_taskids, pr_taskid))
133 		return (0);
134 	if (NOMATCH(ps_zoneids, pr_zoneid))
135 		return (0);
136 	if (NOMATCH(ps_ctids, pr_contract))
137 		return (0);
138 
139 	if (psexp->ps_pat != NULL) {
140 		s = (flags & PSEXP_PSARGS) ?
141 		    psinfo->pr_psargs : psinfo->pr_fname;
142 
143 		if (regexec(&psexp->ps_reg, s, 1, &pmatch, 0) != 0)
144 			return (0);
145 
146 		if ((flags & PSEXP_EXACT) &&
147 		    (pmatch.rm_so != 0 || s[pmatch.rm_eo] != '\0'))
148 			return (0);
149 	}
150 
151 	return (1);
152 }
153