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 }