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