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