michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: /* michael@0: * The following code handles the storage of PKCS 11 modules used by the michael@0: * NSS. This file is written to abstract away how the modules are michael@0: * stored so we can decide that later. michael@0: */ michael@0: #include "secport.h" michael@0: #include "prprf.h" michael@0: #include "prenv.h" michael@0: #include "utilpars.h" michael@0: #include "utilmodt.h" michael@0: michael@0: /* michael@0: * return the expected matching quote value for the one specified michael@0: */ michael@0: PRBool NSSUTIL_ArgGetPair(char c) { michael@0: switch (c) { michael@0: case '\'': return c; michael@0: case '\"': return c; michael@0: case '<': return '>'; michael@0: case '{': return '}'; michael@0: case '[': return ']'; michael@0: case '(': return ')'; michael@0: default: break; michael@0: } michael@0: return ' '; michael@0: } michael@0: michael@0: PRBool NSSUTIL_ArgIsBlank(char c) { michael@0: return isspace((unsigned char )c); michael@0: } michael@0: michael@0: PRBool NSSUTIL_ArgIsEscape(char c) { michael@0: return c == '\\'; michael@0: } michael@0: michael@0: PRBool NSSUTIL_ArgIsQuote(char c) { michael@0: switch (c) { michael@0: case '\'': michael@0: case '\"': michael@0: case '<': michael@0: case '{': /* } end curly to keep vi bracket matching working */ michael@0: case '(': /* ) */ michael@0: case '[': /* ] */ return PR_TRUE; michael@0: default: break; michael@0: } michael@0: return PR_FALSE; michael@0: } michael@0: michael@0: char *NSSUTIL_ArgStrip(char *c) { michael@0: while (*c && NSSUTIL_ArgIsBlank(*c)) c++; michael@0: return c; michael@0: } michael@0: michael@0: /* michael@0: * find the end of the current tag/value pair. string should be pointing just michael@0: * after the equal sign. Handles quoted characters. michael@0: */ michael@0: char * michael@0: NSSUTIL_ArgFindEnd(char *string) { michael@0: char endChar = ' '; michael@0: PRBool lastEscape = PR_FALSE; michael@0: michael@0: if (NSSUTIL_ArgIsQuote(*string)) { michael@0: endChar = NSSUTIL_ArgGetPair(*string); michael@0: string++; michael@0: } michael@0: michael@0: for (;*string; string++) { michael@0: if (lastEscape) { michael@0: lastEscape = PR_FALSE; michael@0: continue; michael@0: } michael@0: if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { michael@0: lastEscape = PR_TRUE; michael@0: continue; michael@0: } michael@0: if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string)) break; michael@0: if (*string == endChar) { michael@0: break; michael@0: } michael@0: } michael@0: michael@0: return string; michael@0: } michael@0: michael@0: /* michael@0: * get the value pointed to by string. string should be pointing just beyond michael@0: * the equal sign. michael@0: */ michael@0: char * michael@0: NSSUTIL_ArgFetchValue(char *string, int *pcount) michael@0: { michael@0: char *end = NSSUTIL_ArgFindEnd(string); michael@0: char *retString, *copyString; michael@0: PRBool lastEscape = PR_FALSE; michael@0: int len; michael@0: michael@0: len = end - string; michael@0: if (len == 0) { michael@0: *pcount = 0; michael@0: return NULL; michael@0: } michael@0: michael@0: copyString = retString = (char *)PORT_Alloc(len+1); michael@0: michael@0: if (*end) len++; michael@0: *pcount = len; michael@0: if (retString == NULL) return NULL; michael@0: michael@0: michael@0: if (NSSUTIL_ArgIsQuote(*string)) string++; michael@0: for (; string < end; string++) { michael@0: if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { michael@0: lastEscape = PR_TRUE; michael@0: continue; michael@0: } michael@0: lastEscape = PR_FALSE; michael@0: *copyString++ = *string; michael@0: } michael@0: *copyString = 0; michael@0: return retString; michael@0: } michael@0: michael@0: /* michael@0: * point to the next parameter in string michael@0: */ michael@0: char * michael@0: NSSUTIL_ArgSkipParameter(char *string) michael@0: { michael@0: char *end; michael@0: /* look for the end of the = */ michael@0: for (;*string; string++) { michael@0: if (*string == '=') { string++; break; } michael@0: if (NSSUTIL_ArgIsBlank(*string)) return(string); michael@0: } michael@0: michael@0: end = NSSUTIL_ArgFindEnd(string); michael@0: if (*end) end++; michael@0: return end; michael@0: } michael@0: michael@0: /* michael@0: * get the value from that tag value pair. michael@0: */ michael@0: char * michael@0: NSSUTIL_ArgGetParamValue(char *paramName,char *parameters) michael@0: { michael@0: char searchValue[256]; michael@0: int paramLen = strlen(paramName); michael@0: char *returnValue = NULL; michael@0: int next; michael@0: michael@0: if ((parameters == NULL) || (*parameters == 0)) return NULL; michael@0: michael@0: PORT_Assert(paramLen+2 < sizeof(searchValue)); michael@0: michael@0: PORT_Strcpy(searchValue,paramName); michael@0: PORT_Strcat(searchValue,"="); michael@0: while (*parameters) { michael@0: if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) { michael@0: parameters += paramLen+1; michael@0: returnValue = NSSUTIL_ArgFetchValue(parameters,&next); michael@0: break; michael@0: } else { michael@0: parameters = NSSUTIL_ArgSkipParameter(parameters); michael@0: } michael@0: parameters = NSSUTIL_ArgStrip(parameters); michael@0: } michael@0: return returnValue; michael@0: } michael@0: michael@0: /* michael@0: * find the next flag in the parameter list michael@0: */ michael@0: char * michael@0: NSSUTIL_ArgNextFlag(char *flags) michael@0: { michael@0: for (; *flags ; flags++) { michael@0: if (*flags == ',') { michael@0: flags++; michael@0: break; michael@0: } michael@0: } michael@0: return flags; michael@0: } michael@0: michael@0: /* michael@0: * return true if the flag is set in the label parameter. michael@0: */ michael@0: PRBool michael@0: NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters) michael@0: { michael@0: char *flags,*index; michael@0: int len = strlen(flag); michael@0: PRBool found = PR_FALSE; michael@0: michael@0: flags = NSSUTIL_ArgGetParamValue(label,parameters); michael@0: if (flags == NULL) return PR_FALSE; michael@0: michael@0: for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) { michael@0: if (PORT_Strncasecmp(index,flag,len) == 0) { michael@0: found=PR_TRUE; michael@0: break; michael@0: } michael@0: } michael@0: PORT_Free(flags); michael@0: return found; michael@0: } michael@0: michael@0: /* michael@0: * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal michael@0: */ michael@0: long michael@0: NSSUTIL_ArgDecodeNumber(char *num) michael@0: { michael@0: int radix = 10; michael@0: unsigned long value = 0; michael@0: long retValue = 0; michael@0: int sign = 1; michael@0: int digit; michael@0: michael@0: if (num == NULL) return retValue; michael@0: michael@0: num = NSSUTIL_ArgStrip(num); michael@0: michael@0: if (*num == '-') { michael@0: sign = -1; michael@0: num++; michael@0: } michael@0: michael@0: if (*num == '0') { michael@0: radix = 8; michael@0: num++; michael@0: if ((*num == 'x') || (*num == 'X')) { michael@0: radix = 16; michael@0: num++; michael@0: } michael@0: } michael@0: michael@0: michael@0: for ( ;*num; num++ ) { michael@0: if (isdigit(*num)) { michael@0: digit = *num - '0'; michael@0: } else if ((*num >= 'a') && (*num <= 'f')) { michael@0: digit = *num - 'a' + 10; michael@0: } else if ((*num >= 'A') && (*num <= 'F')) { michael@0: digit = *num - 'A' + 10; michael@0: } else { michael@0: break; michael@0: } michael@0: if (digit >= radix) break; michael@0: value = value*radix + digit; michael@0: } michael@0: michael@0: retValue = ((int) value) * sign; michael@0: return retValue; michael@0: } michael@0: michael@0: /* michael@0: * parameters are tag value pairs. This function returns the tag or label (the michael@0: * value before the equal size. michael@0: */ michael@0: char * michael@0: NSSUTIL_ArgGetLabel(char *inString, int *next) michael@0: { michael@0: char *name=NULL; michael@0: char *string; michael@0: int len; michael@0: michael@0: /* look for the end of the