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