17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bdstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bdstevel@tonic-gate * (the "License").  You may not use this file except in compliance
77c478bdstevel@tonic-gate * with the License.
87c478bdstevel@tonic-gate *
97c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bdstevel@tonic-gate * See the License for the specific language governing permissions
127c478bdstevel@tonic-gate * and limitations under the License.
137c478bdstevel@tonic-gate *
147c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bdstevel@tonic-gate *
207c478bdstevel@tonic-gate * CDDL HEADER END
217c478bdstevel@tonic-gate */
227c478bdstevel@tonic-gate/*	Copyright (c) 1988 AT&T	*/
237c478bdstevel@tonic-gate/*	  All Rights Reserved  	*/
247c478bdstevel@tonic-gate
257c478bdstevel@tonic-gate
267c478bdstevel@tonic-gate/*
277c478bdstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
287c478bdstevel@tonic-gate * Use is subject to license terms.
297c478bdstevel@tonic-gate */
307c478bdstevel@tonic-gate
31981fe1bJohn Levon/*
32981fe1bJohn Levon * Copyright (c) 2018, Joyent, Inc.
33981fe1bJohn Levon */
347c478bdstevel@tonic-gate
357c478bdstevel@tonic-gate/*LINTLIBRARY*/
367c478bdstevel@tonic-gate
377c478bdstevel@tonic-gate#include <sys/types.h>
387c478bdstevel@tonic-gate#include <stdlib.h>
397c478bdstevel@tonic-gate#include "utility.h"
407c478bdstevel@tonic-gate
417c478bdstevel@tonic-gate/* this code was taken from REGCMP(3X) */
427c478bdstevel@tonic-gate
437c478bdstevel@tonic-gate#define	SSIZE	16
447c478bdstevel@tonic-gate#define	TGRP	48
457c478bdstevel@tonic-gate#define	A256	02
467c478bdstevel@tonic-gate#define	ZERO	01
477c478bdstevel@tonic-gate#define	NBRA	10
487c478bdstevel@tonic-gate#define	CIRCFL	32;
497c478bdstevel@tonic-gate#define	SLOP	5
507c478bdstevel@tonic-gate#define	FEOF	0 /* This was originally EOF but it clashes with the header */
517c478bdstevel@tonic-gate			/* definition so it was changed to FEOF */
527c478bdstevel@tonic-gate
537c478bdstevel@tonic-gate#define	CBRA	60
547c478bdstevel@tonic-gate#define	GRP	40
557c478bdstevel@tonic-gate#define	SGRP	56
567c478bdstevel@tonic-gate#define	PGRP	68
577c478bdstevel@tonic-gate#define	EGRP	44
587c478bdstevel@tonic-gate#define	RNGE	03
597c478bdstevel@tonic-gate#define	CCHR	20
607c478bdstevel@tonic-gate#define	CDOT	64
617c478bdstevel@tonic-gate#define	CCL	24
627c478bdstevel@tonic-gate#define	NCCL	8
637c478bdstevel@tonic-gate#define	CDOL	28
647c478bdstevel@tonic-gate#define	FCEOF	52 /* This was originally CEOF but it clashes with the header */
657c478bdstevel@tonic-gate			/* definition so it was changed to FCEOF */
667c478bdstevel@tonic-gate#define	CKET	12
677c478bdstevel@tonic-gate
687c478bdstevel@tonic-gate#define	STAR	01
697c478bdstevel@tonic-gate#define	PLUS	02
707c478bdstevel@tonic-gate#define	MINUS	16
717c478bdstevel@tonic-gate
727c478bdstevel@tonic-gateintptr_t	*__sp_;
737c478bdstevel@tonic-gateintptr_t	*__stmax;
747c478bdstevel@tonic-gateint	__i_size;
757c478bdstevel@tonic-gate
767c478bdstevel@tonic-gate/*ARGSUSED2*/
777c478bdstevel@tonic-gatechar *
787c478bdstevel@tonic-gatelibform_regcmp(char *cs1, char *cs2)
797c478bdstevel@tonic-gate{
807c478bdstevel@tonic-gate	char c;
817c478bdstevel@tonic-gate	char *ep, *sp;
827c478bdstevel@tonic-gate	int *adx;
837c478bdstevel@tonic-gate	int i, cflg;
847c478bdstevel@tonic-gate	char *lastep, *sep, *eptr;
857c478bdstevel@tonic-gate	int nbra, ngrp;
867c478bdstevel@tonic-gate	int cclcnt;
877c478bdstevel@tonic-gate	intptr_t stack[SSIZE];
887c478bdstevel@tonic-gate
897c478bdstevel@tonic-gate	__sp_ = stack;
907c478bdstevel@tonic-gate	*__sp_ = -1;
917c478bdstevel@tonic-gate	__stmax = &stack[SSIZE];
927c478bdstevel@tonic-gate
937c478bdstevel@tonic-gate	adx = (int *)&cs1;
947c478bdstevel@tonic-gate	i = nbra = ngrp = 0;
957c478bdstevel@tonic-gate	while (*adx)
967c478bdstevel@tonic-gate		i += __size((char *)(intptr_t)*adx++);
977c478bdstevel@tonic-gate	adx = (int *)&cs1;
987c478bdstevel@tonic-gate	sp = (char *)(intptr_t)*adx++;
997c478bdstevel@tonic-gate	if ((sep = ep = malloc((unsigned)(2 * i + SLOP))) == NULL)
1007c478bdstevel@tonic-gate		return (NULL);
1017c478bdstevel@tonic-gate	if ((c = *sp++) == FEOF)
1027c478bdstevel@tonic-gate		goto cerror;
1037c478bdstevel@tonic-gate	if (c == '^') {
1047c478bdstevel@tonic-gate		c = *sp++;
1057c478bdstevel@tonic-gate		*ep++ = CIRCFL;
1067c478bdstevel@tonic-gate	}
1077c478bdstevel@tonic-gate	if ((c == '*') || (c == '+') || (c == '{'))
1087c478bdstevel@tonic-gate		goto cerror;
1097c478bdstevel@tonic-gate	sp--;
1107c478bdstevel@tonic-gate	for (;;) {
1117c478bdstevel@tonic-gate		if ((c = *sp++) == FEOF) {
1127c478bdstevel@tonic-gate			if (*adx) {
1137c478bdstevel@tonic-gate				sp = (char *)(intptr_t)*adx++;
1147c478bdstevel@tonic-gate				continue;
1157c478bdstevel@tonic-gate			}
1167c478bdstevel@tonic-gate			*ep++ = FCEOF;
1177c478bdstevel@tonic-gate			if (--nbra > NBRA || *__sp_ != -1)
1187c478bdstevel@tonic-gate				goto cerror;
1197c478bdstevel@tonic-gate			__i_size = (int) (ep - sep);
1207c478bdstevel@tonic-gate			return (sep);
1217c478bdstevel@tonic-gate		}
1227c478bdstevel@tonic-gate		if ((c != '*') && (c != '{') && (c != '+'))
1237c478bdstevel@tonic-gate			lastep = ep;
1247c478bdstevel@tonic-gate		switch (c) {
1257c478bdstevel@tonic-gate
1267c478bdstevel@tonic-gate		case '(':
1277c478bdstevel@tonic-gate			if (!__rpush(ep)) goto cerror;
1287c478bdstevel@tonic-gate			*ep++ = CBRA;
1297c478bdstevel@tonic-gate			*ep++ = -1;
1307c478bdstevel@tonic-gate			continue;
1317c478bdstevel@tonic-gate		case ')':
1327c478bdstevel@tonic-gate			if (!(eptr = (char *)__rpop())) goto cerror;
1337c478bdstevel@tonic-gate			if ((c = *sp++) == '$') {
1347c478bdstevel@tonic-gate				if ('0' > (c = *sp++) || c > '9')
1357c478bdstevel@tonic-gate					goto cerror;
1367c478bdstevel@tonic-gate				*ep++ = CKET;
1377c478bdstevel@tonic-gate				*ep++ = *++eptr = nbra++;
1387c478bdstevel@tonic-gate				*ep++ = (c-'0');
1397c478bdstevel@tonic-gate				continue;
1407c478bdstevel@tonic-gate			}
1417c478bdstevel@tonic-gate			*ep++ = EGRP;
1427c478bdstevel@tonic-gate			*ep++ = ngrp++;
1437c478bdstevel@tonic-gate			sp--;
1447c478bdstevel@tonic-gate			switch (c) {
1457c478bdstevel@tonic-gate			case '+':
1467c478bdstevel@tonic-gate				*eptr = PGRP;
1477c478bdstevel@tonic-gate				break;
1487c478bdstevel@tonic-gate			case '*':
1497c478bdstevel@tonic-gate				*eptr = SGRP;
1507c478bdstevel@tonic-gate				break;
1517c478bdstevel@tonic-gate			case '{':
1527c478bdstevel@tonic-gate				*eptr = TGRP;
1537c478bdstevel@tonic-gate				break;
1547c478bdstevel@tonic-gate			default:
1557c478bdstevel@tonic-gate				*eptr = GRP;
1567c478bdstevel@tonic-gate				continue;
1577c478bdstevel@tonic-gate			}
1587c478bdstevel@tonic-gate			i = (int) (ep - eptr - 2);
1597c478bdstevel@tonic-gate			for (cclcnt = 0; i >= 256; cclcnt++)
1607c478bdstevel@tonic-gate				i -= 256;
1617c478bdstevel@tonic-gate			if (cclcnt > 3) goto cerror;
1627c478bdstevel@tonic-gate			*eptr |= cclcnt;
1637c478bdstevel@tonic-gate			*++eptr = (char) i;
1647c478bdstevel@tonic-gate			continue;
1657c478bdstevel@tonic-gate
1667c478bdstevel@tonic-gate		case '\\':
1677c478bdstevel@tonic-gate			*ep++ = CCHR;
1687c478bdstevel@tonic-gate			if ((c = *sp++) == FEOF)
1697c478bdstevel@tonic-gate				goto cerror;
1707c478bdstevel@tonic-gate			*ep++ = c;
1717c478bdstevel@tonic-gate			continue;
1727c478bdstevel@tonic-gate
1737c478bdstevel@tonic-gate		case '{':
1747c478bdstevel@tonic-gate			*lastep |= RNGE;
1757c478bdstevel@tonic-gate			cflg = 0;
1767c478bdstevel@tonic-gate		nlim:
1777c478bdstevel@tonic-gate			if ((c = *sp++) == '}') goto cerror;
1787c478bdstevel@tonic-gate			i = 0;
1797c478bdstevel@tonic-gate			do {
1807c478bdstevel@tonic-gate				if ('0' <= c && c <= '9')
1817c478bdstevel@tonic-gate					i = (i*10+(c-'0'));
1827c478bdstevel@tonic-gate				else goto cerror;
1837c478bdstevel@tonic-gate			} while (((c = *sp++) != '}') && (c != ','));
1847c478bdstevel@tonic-gate			if (i > 255) goto cerror;
1857c478bdstevel@tonic-gate			*ep++ = (char) i;
1867c478bdstevel@tonic-gate			if (c == ',') {
1877c478bdstevel@tonic-gate				if (cflg++) goto cerror;
1887c478bdstevel@tonic-gate				if ((c = *sp++) == '}') {
1897c478bdstevel@tonic-gate					*ep++ = -1;
1907c478bdstevel@tonic-gate					continue;
1917c478bdstevel@tonic-gate				} else {
1927c478bdstevel@tonic-gate					sp--;
1937c478bdstevel@tonic-gate					goto nlim;
1947c478bdstevel@tonic-gate				}
1957c478bdstevel@tonic-gate			}
1967c478bdstevel@tonic-gate			if (!cflg)
1977c478bdstevel@tonic-gate				*ep++ = (char) i;
1987c478bdstevel@tonic-gate			else if ((ep[-1]&0377) < (ep[-2]&0377))
1997c478bdstevel@tonic-gate				goto cerror;
2007c478bdstevel@tonic-gate			continue;
2017c478bdstevel@tonic-gate
2027c478bdstevel@tonic-gate		case '.':
2037c478bdstevel@tonic-gate			*ep++ = CDOT;
2047c478bdstevel@tonic-gate			continue;
2057c478bdstevel@tonic-gate
2067c478bdstevel@tonic-gate		case '+':
2077c478bdstevel@tonic-gate			if (*lastep == CBRA || *lastep == CKET)
2087c478bdstevel@tonic-gate				goto cerror;
2097c478bdstevel@tonic-gate			*lastep |= PLUS;
2107c478bdstevel@tonic-gate			continue;
2117c478bdstevel@tonic-gate
2127c478bdstevel@tonic-gate		case '*':
2137c478bdstevel@tonic-gate			if (*lastep == CBRA || *lastep == CKET)
214981fe1bJohn Levon				goto cerror;
2157c478bdstevel@tonic-gate			*lastep |= STAR;
2167c478bdstevel@tonic-gate			continue;
2177c478bdstevel@tonic-gate
2187c478bdstevel@tonic-gate		case '$':
2197c478bdstevel@tonic-gate			if ((*sp != FEOF) || (*adx))
2207c478bdstevel@tonic-gate				goto defchar;
2217c478bdstevel@tonic-gate			*ep++ = CDOL;
2227c478bdstevel@tonic-gate			continue;
2237c478bdstevel@tonic-gate
2247c478bdstevel@tonic-gate		case '[':
2257c478bdstevel@tonic-gate			*ep++ = CCL;
2267c478bdstevel@tonic-gate			*ep++ = 0;
2277c478bdstevel@tonic-gate			cclcnt = 1;
2287c478bdstevel@tonic-gate			if ((c = *sp++) == '^') {
2297c478bdstevel@tonic-gate				c = *sp++;
2307c478bdstevel@tonic-gate				ep[-2] = NCCL;
2317c478bdstevel@tonic-gate			}
2327c478bdstevel@tonic-gate			do {
2337c478bdstevel@tonic-gate				if (c == FEOF)
2347c478bdstevel@tonic-gate					goto cerror;
2357c478bdstevel@tonic-gate				if ((c == '-') && (cclcnt > 1) &&
2367c478bdstevel@tonic-gate				    (*sp != ']')) {
2377c478bdstevel@tonic-gate					*ep = ep[-1];
2387c478bdstevel@tonic-gate					ep++;
2397c478bdstevel@tonic-gate					ep[-2] = MINUS;
2407c478bdstevel@tonic-gate					cclcnt++;
2417c478bdstevel@tonic-gate					continue;
2427c478bdstevel@tonic-gate				}
2437c478bdstevel@tonic-gate				*ep++ = c;
2447c478bdstevel@tonic-gate				cclcnt++;
2457c478bdstevel@tonic-gate			} while ((c = *sp++) != ']');
2467c478bdstevel@tonic-gate			lastep[1] = (char) cclcnt;
2477c478bdstevel@tonic-gate			continue;
2487c478bdstevel@tonic-gate
2497c478bdstevel@tonic-gate		defchar:
2507c478bdstevel@tonic-gate		default:
2517c478bdstevel@tonic-gate			*ep++ = CCHR;
2527c478bdstevel@tonic-gate			*ep++ = c;
2537c478bdstevel@tonic-gate		}
2547c478bdstevel@tonic-gate	}
2557c478bdstevel@tonic-gatecerror:
2567c478bdstevel@tonic-gate	free(sep);
2577c478bdstevel@tonic-gate	return (0);
2587c478bdstevel@tonic-gate}
2597c478bdstevel@tonic-gate
2607c478bdstevel@tonic-gateint
2617c478bdstevel@tonic-gate__size(char *strg)
2627c478bdstevel@tonic-gate{
2637c478bdstevel@tonic-gate	int	i;
2647c478bdstevel@tonic-gate
2657c478bdstevel@tonic-gate	i = 1;
2667c478bdstevel@tonic-gate	while (*strg++)
2677c478bdstevel@tonic-gate		i++;
2687c478bdstevel@tonic-gate	return (i);
2697c478bdstevel@tonic-gate}
2707c478bdstevel@tonic-gate
2717c478bdstevel@tonic-gateintptr_t
2727c478bdstevel@tonic-gate__rpop(void)
2737c478bdstevel@tonic-gate{
2747c478bdstevel@tonic-gate	return ((*__sp_ == -1)?0:*__sp_--);
2757c478bdstevel@tonic-gate}
2767c478bdstevel@tonic-gate
2777c478bdstevel@tonic-gateint
2787c478bdstevel@tonic-gate__rpush(char *ptr)
2797c478bdstevel@tonic-gate{
2807c478bdstevel@tonic-gate	if (__sp_ >= __stmax)
2817c478bdstevel@tonic-gate		return (0);
2827c478bdstevel@tonic-gate	*++__sp_ = (intptr_t)ptr;
2837c478bdstevel@tonic-gate	return (1);
2847c478bdstevel@tonic-gate}
285