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