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 /* Copyright (c) 1988 AT&T */
23 /* All Rights Reserved */
24
25
26 /*
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
29 */
30
31 /*
32 * Copyright (c) 2018, Joyent, Inc.
33 */
34
35 #include <sys/types.h>
36 #include <stdlib.h>
37 #include <unistd.h>
38 #include "utility.h"
39
40 /*
41 * this code was taken from regcmp(3C)
42 */
43 /*VARARGS*/
44 /*ARGSUSED*/
45
46 #define SSIZE 50
47 #define TGRP 48
48 #define A256 01
49 #define A512 02
50 #define A768 03
51 #define NBRA 10
52 #define CIRCFL 32
53
54 #define CBRA 60
55 #define GRP 40
56 #define SGRP 56
57 #define PGRP 68
58 #define EGRP 44
59 #define RNGE 03
60 #define CCHR 20
61 #define CDOT 64
62 #define CCL 24
63 #define NCCL 8
64 #define CDOL 28
65 #define FCEOF 52 /* This was originally CEOF but it clashes with the header */
66 /* definition so it was changed to FCEOF */
67 #define CKET 12
68
69 #define STAR 01
70 #define PLUS 02
71 #define MINUS 16
72
73 char *__braslist[NBRA];
74 char *__braelist[NBRA];
75 extern char *__loc1;
76 intptr_t __bravar[NBRA];
77 intptr_t *__st[SSIZE + 1];
78 intptr_t *__eptr_, *__lptr_;
79 intptr_t __cflg;
80
81 char *
libform_regex(char * addrc,char * addrl,char * a1)82 libform_regex(char *addrc, char *addrl, char *a1)
83 {
84 intptr_t cur, in;
85 intptr_t *adx;
86 char *p1, *p2;
87
88 for (in = 0; in < NBRA; in++) {
89 __braslist[in] = 0;
90 __bravar[in] = -1;
91 }
92 __cflg = 0;
93 cur = __execute(addrc, addrl);
94 adx = (intptr_t *)&a1;
95 for (in = 0; in < NBRA; in++) {
96 if (((p1 = __braslist[in]) != 0) && (__bravar[in] >= 0)) {
97 p2 = (char *)adx[__bravar[in]];
98 while (p1 < __braelist[in]) *p2++ = *p1++;
99 *p2 = '\0';
100 }
101 }
102 if (!__cflg)
103 return ((addrl == (char *)cur) ? (char *)0 : (char *)cur);
104 else
105 return ((char *)cur);
106 }
107
108 intptr_t
__execute(char * addrc,char * addrl)109 __execute(char *addrc, char *addrl)
110 {
111 char *p1, *p2, c;
112 intptr_t i;
113
114 p1 = addrl;
115 p2 = addrc;
116 __eptr_ = (intptr_t *)&__st[SSIZE];
117 __lptr_ = (intptr_t *)&__st[0];
118 if (*p2 == CIRCFL) {
119 __loc1 = p1;
120 return ((i = __advance(p1, ++p2)) ? i : (intptr_t)addrl);
121 }
122 /* fast check for first character */
123 if (*p2 == CCHR) {
124 c = p2[1];
125 do {
126 if (*p1 != c)
127 continue;
128 __eptr_ = (intptr_t *)&__st[SSIZE];
129 __lptr_ = (intptr_t *)&__st[0];
130 if (i = __advance(p1, p2)) {
131 __loc1 = p1;
132 return (i);
133 }
134 } while (*p1++);
135 return ((intptr_t)addrl);
136 }
137 /* regular algorithm */
138 do {
139 __eptr_ = (intptr_t *)&__st[SSIZE];
140 __lptr_ = (intptr_t *)&__st[0];
141 if (i = __advance(p1, p2)) {
142 __loc1 = p1;
143 return (i);
144 }
145 } while (*p1++);
146 return ((intptr_t)addrl);
147 }
148
149 intptr_t
__advance(char * alp,char * aep)150 __advance(char *alp, char *aep)
151 {
152 char *lp, *ep, *curlp;
153 char *sep, *dp;
154 intptr_t i, lcnt, dcnt, gflg;
155
156 lp = alp;
157 ep = aep;
158 gflg = 0;
159 for (; ; ) {
160 switch (*ep++) {
161
162 case CCHR:
163 if (*ep++ == *lp++)
164 continue;
165 return (0);
166
167 case EGRP|RNGE:
168 return ((intptr_t)lp);
169 case EGRP:
170 case GRP:
171 ep++;
172 continue;
173
174 case EGRP|STAR:
175 (void) __xpop(0);
176 /* FALLTHROUGH */
177 case EGRP|PLUS:
178 (void) __xpush(0, ++ep);
179 return ((intptr_t)lp);
180
181 case CDOT:
182 if (*lp++)
183 continue;
184 return (0);
185
186 case CDOL:
187 if (*lp == 0)
188 continue;
189 lp++;
190 return (0);
191
192 case FCEOF:
193 __cflg = 1;
194 return ((intptr_t)lp);
195
196 case TGRP:
197 case TGRP|A768:
198 case TGRP|A512:
199 case TGRP|A256:
200 i = (((ep[-1] & 03) << 8) + (*ep) & 0377);
201 ep++;
202 (void) __xpush(0, ep + i + 2);
203 (void) __xpush(0, ++ep);
204 (void) __xpush(0, ++ep);
205 gflg = 1;
206 (void) __getrnge(&lcnt, &dcnt, &ep[i]);
207 while (lcnt--)
208 if (!(lp = (char *)__advance(lp, ep)))
209 return (0);
210 (void) __xpush(1, curlp = lp);
211 while (dcnt--)
212 if (!(dp = (char *)__advance(lp, ep))) break;
213 else
214 (void) __xpush(1, lp = dp);
215 ep = (char *)__xpop(0);
216 goto star;
217 case CCHR|RNGE:
218 sep = ep++;
219 (void) __getrnge(&lcnt, &dcnt, ep);
220 while (lcnt--)
221 if (*lp++ != *sep)
222 return (0);
223 curlp = lp;
224 while (dcnt--)
225 if (*lp++ != *sep) break;
226 if (dcnt < 0) lp++;
227 ep += 2;
228 goto star;
229 case CDOT|RNGE:
230 (void) __getrnge(&lcnt, &dcnt, ep);
231 while (lcnt--)
232 if (*lp++ == '\0')
233 return (0);
234 curlp = lp;
235 while (dcnt--)
236 if (*lp++ == '\0') break;
237 if (dcnt < 0) lp++;
238 ep += 2;
239 goto star;
240 case CCL|RNGE:
241 case NCCL|RNGE:
242 (void) __getrnge(&lcnt, &dcnt, (ep + (*ep & 0377)));
243 while (lcnt--)
244 if (!__cclass(ep, *lp++, ep[-1] == (CCL | RNGE)))
245 return (0);
246 curlp = lp;
247 while (dcnt--)
248 if (!__cclass(ep, *lp++, ep[-1] == (CCL|RNGE)))
249 break;
250 if (dcnt < 0) lp++;
251 ep += (*ep + 2);
252 goto star;
253 case CCL:
254 if (__cclass(ep, *lp++, 1)) {
255 ep += *ep;
256 continue;
257 }
258 return (0);
259
260 case NCCL:
261 if (__cclass(ep, *lp++, 0)) {
262 ep += *ep;
263 continue;
264 }
265 return (0);
266
267 case CBRA:
268 __braslist[*ep++] = lp;
269 continue;
270
271 case CKET:
272 __braelist[*ep] = lp;
273 __bravar[*ep] = ep[1];
274 ep += 2;
275 continue;
276
277 case CDOT|PLUS:
278 if (*lp++ == '\0')
279 return (0);
280 /* FALLTHROUGH */
281 case CDOT|STAR:
282 curlp = lp;
283 while (*lp++)
284 ;
285 goto star;
286
287 case CCHR|PLUS:
288 if (*lp++ != *ep)
289 return (0);
290 /* FALLTHROUGH */
291 case CCHR|STAR:
292 curlp = lp;
293 while (*lp++ == *ep)
294 ;
295 ep++;
296 goto star;
297
298 case PGRP:
299 case PGRP|A256:
300 case PGRP|A512:
301 case PGRP|A768:
302 if (!(lp = (char *)__advance(lp, ep+1)))
303 return (0);
304 /* FALLTHROUGH */
305 case SGRP|A768:
306 case SGRP|A512:
307 case SGRP|A256:
308 case SGRP:
309 i = (((ep[-1]&03) << 8) + (*ep & 0377));
310 ep++;
311 (void) __xpush(0, ep + i);
312 (void) __xpush(1, curlp = lp);
313 while (i = __advance(lp, ep))
314 (void) __xpush(1, lp = (char *)i);
315 ep = (char *)__xpop(0);
316 gflg = 1;
317 goto star;
318
319 case CCL|PLUS:
320 case NCCL|PLUS:
321 if (!__cclass(ep, *lp++, ep[-1] == (CCL | PLUS)))
322 return (0);
323 /* FALLTHROUGH */
324 case CCL|STAR:
325 case NCCL|STAR:
326 curlp = lp;
327 while (__cclass(ep, *lp++, ((ep[-1] == (CCL | STAR)) ||
328 (ep[-1] == (CCL | PLUS)))))
329 ;
330 ep += *ep;
331 goto star;
332
333 star:
334 do {
335 if (!gflg) lp--;
336 else if (!(lp = (char *)__xpop(1))) break;
337 if (i = __advance(lp, ep))
338 return (i);
339 } while (lp > curlp);
340 return (0);
341
342 default:
343 return (0);
344 }
345 }
346 }
347
348 intptr_t
__cclass(char * aset,char ac,intptr_t af)349 __cclass(char *aset, char ac, intptr_t af)
350 {
351 char *set, c;
352 intptr_t n;
353
354 set = (char *)aset;
355 if ((c = ac) == 0)
356 return (0);
357 n = *set++;
358 while (--n) {
359 if (*set == MINUS) {
360 if ((set[2] - set[1]) < 0)
361 return (0);
362 if (*++set <= c) {
363 if (c <= *++set)
364 return (af);
365 } else
366 ++set;
367 ++set;
368 n -= 2;
369 continue;
370 }
371 if (*set++ == c)
372 return (af);
373 }
374 return (!af);
375 }
376
377 intptr_t
__xpush(intptr_t i,char * p)378 __xpush(intptr_t i, char *p)
379 {
380 if (__lptr_ >= __eptr_) {
381 (void) write(2, "stack overflow\n", 15);
382 (void) exit(1);
383 }
384 if (i)
385 *__lptr_++ = (intptr_t)p;
386 else
387 *__eptr_-- = (intptr_t)p;
388 return (1);
389 }
390
391 intptr_t
__xpop(intptr_t i)392 __xpop(intptr_t i)
393 {
394 if (i)
395 return ((__lptr_ < (intptr_t *)&__st[0]) ? 0 : *--__lptr_);
396 else
397 return ((__eptr_ > (intptr_t *)&__st[SSIZE]) ? 0 : *++__eptr_);
398 }
399
400 intptr_t
__getrnge(intptr_t * i,intptr_t * j,char * k)401 __getrnge(intptr_t *i, intptr_t *j, char *k)
402 {
403 *i = (*k++&0377);
404 if (*k == (char)-1)
405 *j = 20000;
406 else
407 *j = ((*k&0377) - *i);
408 return (1);
409 }
410