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