1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright (c) 1999 by Sun Microsystems, Inc.
24*0Sstevel@tonic-gate  * All rights reserved.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <strings.h>
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate char *_strpbrk_escape(char *, char *);
34*0Sstevel@tonic-gate 
35*0Sstevel@tonic-gate /*
36*0Sstevel@tonic-gate  * _strtok_escape()
37*0Sstevel@tonic-gate  *   Like strtok_r, except we don't break on a token if it is escaped
38*0Sstevel@tonic-gate  *   with the escape character (\).
39*0Sstevel@tonic-gate  */
40*0Sstevel@tonic-gate char *
41*0Sstevel@tonic-gate _strtok_escape(char *string, char *sepset, char **lasts)
42*0Sstevel@tonic-gate {
43*0Sstevel@tonic-gate 	char	*q, *r;
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate 	/* first or subsequent call */
46*0Sstevel@tonic-gate 	if (string == NULL)
47*0Sstevel@tonic-gate 		string = *lasts;
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate 	if (string == 0)		/* return if no tokens remaining */
50*0Sstevel@tonic-gate 		return (NULL);
51*0Sstevel@tonic-gate 
52*0Sstevel@tonic-gate 	if (*string == '\0')		/* return if no tokens remaining */
53*0Sstevel@tonic-gate 		return (NULL);
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate 	if ((r = _strpbrk_escape(string, sepset)) == NULL)/* move past token */
56*0Sstevel@tonic-gate 		*lasts = 0;	/* indicate this is last token */
57*0Sstevel@tonic-gate 	else {
58*0Sstevel@tonic-gate 		*r = '\0';
59*0Sstevel@tonic-gate 		*lasts = r+1;
60*0Sstevel@tonic-gate 	}
61*0Sstevel@tonic-gate 	return (string);
62*0Sstevel@tonic-gate }
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate /*
65*0Sstevel@tonic-gate  * Return ptr to first occurrence of any non-escaped character from `brkset'
66*0Sstevel@tonic-gate  * in the character string `string'; NULL if none exists.
67*0Sstevel@tonic-gate  */
68*0Sstevel@tonic-gate char *
69*0Sstevel@tonic-gate _strpbrk_escape(char *string, char *brkset)
70*0Sstevel@tonic-gate {
71*0Sstevel@tonic-gate 	const char *p;
72*0Sstevel@tonic-gate 	const char *first = string;
73*0Sstevel@tonic-gate 
74*0Sstevel@tonic-gate 	do {
75*0Sstevel@tonic-gate 		for (p = brkset; *p != '\0' && *p != *string; ++p)
76*0Sstevel@tonic-gate 			;
77*0Sstevel@tonic-gate 		if (p == string)
78*0Sstevel@tonic-gate 			return ((char *)string);
79*0Sstevel@tonic-gate 		if (*p != '\0') {
80*0Sstevel@tonic-gate 			if (*(string-1) != '\\')
81*0Sstevel@tonic-gate 				return ((char *)string);
82*0Sstevel@tonic-gate 		}
83*0Sstevel@tonic-gate 	} while (*string++);
84*0Sstevel@tonic-gate 
85*0Sstevel@tonic-gate 	return (NULL);
86*0Sstevel@tonic-gate }
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate char   *
90*0Sstevel@tonic-gate _escape(char *s, char *esc)
91*0Sstevel@tonic-gate {
92*0Sstevel@tonic-gate 	int	nescs = 0;	/* number of escapes to place in s */
93*0Sstevel@tonic-gate 	int	i, j;
94*0Sstevel@tonic-gate 	int	len_s;
95*0Sstevel@tonic-gate 	char	*tmp;
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate 	if (s == NULL || esc == NULL)
98*0Sstevel@tonic-gate 		return (NULL);
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate 	len_s = strlen(s);
101*0Sstevel@tonic-gate 	for (i = 0; i < len_s; i++)
102*0Sstevel@tonic-gate 		if (strchr(esc, s[i]))
103*0Sstevel@tonic-gate 			nescs++;
104*0Sstevel@tonic-gate 	if ((tmp = (char *) malloc(nescs + len_s + 1)) == NULL)
105*0Sstevel@tonic-gate 		return (NULL);
106*0Sstevel@tonic-gate 	for (i = 0, j = 0; i < len_s; i++) {
107*0Sstevel@tonic-gate 		if (strchr(esc, s[i])) {
108*0Sstevel@tonic-gate 			tmp[j++] = '\\';
109*0Sstevel@tonic-gate 		}
110*0Sstevel@tonic-gate 		tmp[j++] = s[i];
111*0Sstevel@tonic-gate 	}
112*0Sstevel@tonic-gate 	tmp[len_s + nescs] = '\0';
113*0Sstevel@tonic-gate 	return (tmp);
114*0Sstevel@tonic-gate }
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate char *
118*0Sstevel@tonic-gate _unescape(char *s, char *esc)
119*0Sstevel@tonic-gate {
120*0Sstevel@tonic-gate 	int	len_s;
121*0Sstevel@tonic-gate 	int	i, j;
122*0Sstevel@tonic-gate 	char	*tmp;
123*0Sstevel@tonic-gate 
124*0Sstevel@tonic-gate 	if (s == NULL || esc == NULL)
125*0Sstevel@tonic-gate 		return ((char *)NULL);
126*0Sstevel@tonic-gate 
127*0Sstevel@tonic-gate 	len_s = strlen(s);
128*0Sstevel@tonic-gate 	if ((tmp = (char *) malloc(len_s + 1)) == NULL)
129*0Sstevel@tonic-gate 		return ((char *)NULL);
130*0Sstevel@tonic-gate 	for (i = 0, j = 0; i < len_s; i++) {
131*0Sstevel@tonic-gate 		if (s[i] == '\\' && strchr(esc, s[i + 1]))
132*0Sstevel@tonic-gate 			tmp[j++] = s[++i];
133*0Sstevel@tonic-gate 		else
134*0Sstevel@tonic-gate 			tmp[j++] = s[i];
135*0Sstevel@tonic-gate 	}
136*0Sstevel@tonic-gate 	tmp[j] = NULL;
137*0Sstevel@tonic-gate 	return (tmp);
138*0Sstevel@tonic-gate }
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate char *
141*0Sstevel@tonic-gate _strdup_null(char *s)
142*0Sstevel@tonic-gate {
143*0Sstevel@tonic-gate 	return (strdup(s ? s : ""));
144*0Sstevel@tonic-gate }
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate /*
148*0Sstevel@tonic-gate  * read a line into buffer from a mmap'ed file.
149*0Sstevel@tonic-gate  * return length of line read.
150*0Sstevel@tonic-gate  */
151*0Sstevel@tonic-gate int
152*0Sstevel@tonic-gate _readbufline(char *mapbuf,	/* input mmap buffer */
153*0Sstevel@tonic-gate     int mapsize,		/* input size */
154*0Sstevel@tonic-gate     char *buffer,		/* output storage */
155*0Sstevel@tonic-gate     int buflen,			/* output size */
156*0Sstevel@tonic-gate     int *lastlen)		/* input read till here last time */
157*0Sstevel@tonic-gate {
158*0Sstevel@tonic-gate 	int	linelen;
159*0Sstevel@tonic-gate 
160*0Sstevel@tonic-gate 	while (1) {
161*0Sstevel@tonic-gate 		linelen = 0;
162*0Sstevel@tonic-gate 		while (linelen < buflen - 1) {	/* "- 1" saves room for \n\0 */
163*0Sstevel@tonic-gate 			if (*lastlen >= mapsize) {
164*0Sstevel@tonic-gate 				if (linelen == 0 ||
165*0Sstevel@tonic-gate 					buffer[linelen - 1] == '\\') {
166*0Sstevel@tonic-gate 						return (-1);
167*0Sstevel@tonic-gate 					} else {
168*0Sstevel@tonic-gate 						buffer[linelen] = '\n';
169*0Sstevel@tonic-gate 						buffer[linelen + 1] = '\0';
170*0Sstevel@tonic-gate 						return (linelen);
171*0Sstevel@tonic-gate 					}
172*0Sstevel@tonic-gate 			}
173*0Sstevel@tonic-gate 			switch (mapbuf[*lastlen]) {
174*0Sstevel@tonic-gate 			case '\n':
175*0Sstevel@tonic-gate 				(*lastlen)++;
176*0Sstevel@tonic-gate 				if (linelen > 0 &&
177*0Sstevel@tonic-gate 				    buffer[linelen - 1] == '\\') {
178*0Sstevel@tonic-gate 					--linelen;	/* remove the '\\' */
179*0Sstevel@tonic-gate 				} else {
180*0Sstevel@tonic-gate 					buffer[linelen] = '\n';
181*0Sstevel@tonic-gate 					buffer[linelen + 1] = '\0';
182*0Sstevel@tonic-gate 					return (linelen);
183*0Sstevel@tonic-gate 				}
184*0Sstevel@tonic-gate 				break;
185*0Sstevel@tonic-gate 			default:
186*0Sstevel@tonic-gate 				buffer[linelen] = mapbuf[*lastlen];
187*0Sstevel@tonic-gate 				(*lastlen)++;
188*0Sstevel@tonic-gate 				linelen++;
189*0Sstevel@tonic-gate 			}
190*0Sstevel@tonic-gate 		}
191*0Sstevel@tonic-gate 		/* Buffer overflow -- eat rest of line and loop again */
192*0Sstevel@tonic-gate 		while (mapbuf[*lastlen] != '\n') {
193*0Sstevel@tonic-gate 			if (mapbuf[*lastlen] == EOF) {
194*0Sstevel@tonic-gate 				return (-1);
195*0Sstevel@tonic-gate 			}
196*0Sstevel@tonic-gate 			(*lastlen)++;
197*0Sstevel@tonic-gate 		};
198*0Sstevel@tonic-gate 	}
199*0Sstevel@tonic-gate }
200