xref: /illumos-gate/usr/src/lib/libnsl/nss/parse.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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 
23 /*
24  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 #pragma ident	"%Z%%M%	%I%	%E% SMI"
29 
30 #include "mt.h"
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <strings.h>
34 
35 char *_strpbrk_escape(char *, char *);
36 
37 /*
38  * _strtok_escape()
39  *   Like strtok_r, except we don't break on a token if it is escaped
40  *   with the escape character (\).
41  */
42 char *
43 _strtok_escape(char *string, char *sepset, char **lasts)
44 {
45 	char	*r;
46 
47 	/* first or subsequent call */
48 	if (string == NULL)
49 		string = *lasts;
50 
51 	if (string == 0)		/* return if no tokens remaining */
52 		return (NULL);
53 
54 	if (*string == '\0')		/* return if no tokens remaining */
55 		return (NULL);
56 
57 	/* move past token */
58 	if ((r = _strpbrk_escape(string, sepset)) == NULL)
59 		*lasts = 0;	/* indicate this is last token */
60 	else {
61 		*r = '\0';
62 		*lasts = r+1;
63 	}
64 	return (string);
65 }
66 
67 /*
68  * Return ptr to first occurrence of any non-escaped character from `brkset'
69  * in the character string `string'; NULL if none exists.
70  */
71 char *
72 _strpbrk_escape(char *string, char *brkset)
73 {
74 	const char *p;
75 
76 	do {
77 		for (p = brkset; *p != '\0' && *p != *string; ++p)
78 			;
79 		if (p == string)
80 			return ((char *)string);
81 		if (*p != '\0') {
82 			if (*(string-1) != '\\')
83 				return ((char *)string);
84 		}
85 	} while (*string++);
86 
87 	return (NULL);
88 }
89 
90 
91 char   *
92 _escape(char *s, char *esc)
93 {
94 	int	nescs = 0;	/* number of escapes to place in s */
95 	int	i, j;
96 	int	len_s;
97 	char	*tmp;
98 
99 	if (s == NULL || esc == NULL)
100 		return (NULL);
101 
102 	len_s = strlen(s);
103 	for (i = 0; i < len_s; i++)
104 		if (strchr(esc, s[i]))
105 			nescs++;
106 	if ((tmp = malloc(nescs + len_s + 1)) == NULL)
107 		return (NULL);
108 	for (i = 0, j = 0; i < len_s; i++) {
109 		if (strchr(esc, s[i])) {
110 			tmp[j++] = '\\';
111 		}
112 		tmp[j++] = s[i];
113 	}
114 	tmp[len_s + nescs] = '\0';
115 	return (tmp);
116 }
117 
118 
119 char *
120 _unescape(char *s, char *esc)
121 {
122 	int	len_s;
123 	int	i, j;
124 	char	*tmp;
125 
126 	if (s == NULL || esc == NULL)
127 		return (NULL);
128 
129 	len_s = strlen(s);
130 	if ((tmp = malloc(len_s + 1)) == NULL)
131 		return (NULL);
132 	for (i = 0, j = 0; i < len_s; i++) {
133 		if (s[i] == '\\' && strchr(esc, s[i + 1]))
134 			tmp[j++] = s[++i];
135 		else
136 			tmp[j++] = s[i];
137 	}
138 	tmp[j] = NULL;
139 	return (tmp);
140 }
141 
142 char *
143 _strdup_null(char *s)
144 {
145 	return (strdup(s ? s : ""));
146 }
147 
148 
149 /*
150  * read a line into buffer from a mmap'ed file.
151  * return length of line read.
152  */
153 int
154 _readbufline(char *mapbuf,	/* input mmap buffer */
155     int mapsize,		/* input size */
156     char *buffer,		/* output storage */
157     int buflen,			/* output size */
158     int *lastlen)		/* input read till here last time */
159 {
160 	int	linelen;
161 
162 	for (;;) {
163 		linelen = 0;
164 		while (linelen < buflen - 1) {	/* "- 1" saves room for \n\0 */
165 			if (*lastlen >= mapsize) {
166 				if (linelen == 0 ||
167 					buffer[linelen - 1] == '\\') {
168 						return (-1);
169 					} else {
170 						buffer[linelen] = '\n';
171 						buffer[linelen + 1] = '\0';
172 						return (linelen);
173 					}
174 			}
175 			switch (mapbuf[*lastlen]) {
176 			case '\n':
177 				(*lastlen)++;
178 				if (linelen > 0 &&
179 				    buffer[linelen - 1] == '\\') {
180 					--linelen;	/* remove the '\\' */
181 				} else {
182 					buffer[linelen] = '\n';
183 					buffer[linelen + 1] = '\0';
184 					return (linelen);
185 				}
186 				break;
187 			default:
188 				buffer[linelen] = mapbuf[*lastlen];
189 				(*lastlen)++;
190 				linelen++;
191 			}
192 		}
193 		/* Buffer overflow -- eat rest of line and loop again */
194 		while (mapbuf[*lastlen] != '\n') {
195 			if (mapbuf[*lastlen] == EOF) {
196 				return (-1);
197 			}
198 			(*lastlen)++;
199 		};
200 	}
201 	/* NOTREACHED */
202 }
203