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