| Index: nss/lib/util/utilmod.c | 
| diff --git a/nss/lib/util/utilmod.c b/nss/lib/util/utilmod.c | 
| deleted file mode 100644 | 
| index 230b5c97dd5ac9d1c13d007e899b25f8aae5b95f..0000000000000000000000000000000000000000 | 
| --- a/nss/lib/util/utilmod.c | 
| +++ /dev/null | 
| @@ -1,738 +0,0 @@ | 
| -/* This Source Code Form is subject to the terms of the Mozilla Public | 
| - * License, v. 2.0. If a copy of the MPL was not distributed with this | 
| - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | 
| -/* | 
| - * The following code handles the storage of PKCS 11 modules used by the | 
| - * NSS. For the rest of NSS, only one kind of database handle exists: | 
| - * | 
| - *     SFTKDBHandle | 
| - * | 
| - * There is one SFTKDBHandle for each key database and one for each cert | 
| - * database. These databases are opened as associated pairs, one pair per | 
| - * slot. SFTKDBHandles are reference counted objects. | 
| - * | 
| - * Each SFTKDBHandle points to a low level database handle (SDB). This handle | 
| - * represents the underlying physical database. These objects are not | 
| - * reference counted, and are 'owned' by their respective SFTKDBHandles. | 
| - */ | 
| - | 
| -#include "prprf.h" | 
| -#include "prsystem.h" | 
| -#include "secport.h" | 
| -#include "utilpars.h" | 
| -#include "secerr.h" | 
| - | 
| -#if defined (_WIN32) | 
| -#include <io.h> | 
| -#endif | 
| -#ifdef XP_UNIX | 
| -#include <unistd.h> | 
| -#endif | 
| - | 
| -#include <sys/types.h> | 
| -#include <sys/stat.h> | 
| -#include <fcntl.h> | 
| - | 
| -#if defined (_WIN32) | 
| -#define os_open _open | 
| -#define os_fdopen _fdopen | 
| -#define os_stat _stat | 
| -#define os_truncate_open_flags _O_CREAT|_O_RDWR|_O_TRUNC | 
| -#define os_append_open_flags _O_CREAT|_O_RDWR|_O_APPEND | 
| -#define os_open_permissions_type int | 
| -#define os_open_permissions_default _S_IREAD | _S_IWRITE | 
| -#define os_stat_type struct _stat | 
| -#else | 
| -#define os_open open | 
| -#define os_fdopen fdopen | 
| -#define os_stat stat | 
| -#define os_truncate_open_flags O_CREAT|O_RDWR|O_TRUNC | 
| -#define os_append_open_flags O_CREAT|O_RDWR|O_APPEND | 
| -#define os_open_permissions_type mode_t | 
| -#define os_open_permissions_default 0600 | 
| -#define os_stat_type struct stat | 
| -#endif | 
| - | 
| -/**************************************************************** | 
| - * | 
| - * Secmod database. | 
| - * | 
| - * The new secmod database is simply a text file with each of the module | 
| - * entries in the following form: | 
| - * | 
| - * # | 
| - * # This is a comment The next line is the library to load | 
| - * library=libmypkcs11.so | 
| - * name="My PKCS#11 module" | 
| - * params="my library's param string" | 
| - * nss="NSS parameters" | 
| - * other="parameters for other libraries and applications" | 
| - * | 
| - * library=libmynextpk11.so | 
| - * name="My other PKCS#11 module" | 
| - */ | 
| - | 
| - | 
| -/* | 
| - * Smart string cat functions. Automatically manage the memory. | 
| - * The first parameter is the destination string. If it's null, we | 
| - * allocate memory for it. If it's not, we reallocate memory | 
| - * so the the concanenated string fits. | 
| - */ | 
| -static char * | 
| -nssutil_DupnCat(char *baseString, const char *str, int str_len) | 
| -{ | 
| -    int baseStringLen = baseString ? PORT_Strlen(baseString) : 0; | 
| -    int len = baseStringLen + 1; | 
| -    char *newString; | 
| - | 
| -    len += str_len; | 
| -    newString = (char *) PORT_Realloc(baseString,len); | 
| -    if (newString == NULL) { | 
| -	PORT_Free(baseString); | 
| -	return NULL; | 
| -    } | 
| -    PORT_Memcpy(&newString[baseStringLen], str, str_len); | 
| -    newString[len - 1] = 0; | 
| -    return newString; | 
| -} | 
| - | 
| -/* Same as nssutil_DupnCat except it concatenates the full string, not a | 
| - * partial one */ | 
| -static char * | 
| -nssutil_DupCat(char *baseString, const char *str) | 
| -{ | 
| -    return nssutil_DupnCat(baseString, str, PORT_Strlen(str)); | 
| -} | 
| - | 
| -/* function to free up all the memory associated with a null terminated | 
| - * array of module specs */ | 
| -static SECStatus | 
| -nssutil_releaseSpecList(char **moduleSpecList) | 
| -{ | 
| -    if (moduleSpecList) { | 
| -	char **index; | 
| -	for(index = moduleSpecList; *index; index++) { | 
| -	    PORT_Free(*index); | 
| -	} | 
| -	PORT_Free(moduleSpecList); | 
| -    } | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -#define SECMOD_STEP 10 | 
| -static SECStatus | 
| -nssutil_growList(char ***pModuleList, int *useCount, int last) | 
| -{ | 
| -    char **newModuleList; | 
| - | 
| -    *useCount += SECMOD_STEP; | 
| -    newModuleList = (char **)PORT_Realloc(*pModuleList, | 
| -					  *useCount*sizeof(char *)); | 
| -    if (newModuleList == NULL) { | 
| -	return SECFailure; | 
| -    } | 
| -    PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP); | 
| -    *pModuleList = newModuleList; | 
| -    return SECSuccess; | 
| -} | 
| - | 
| -static | 
| -char *_NSSUTIL_GetOldSecmodName(const char *dbname,const char *filename) | 
| -{ | 
| -    char *file = NULL; | 
| -    char *dirPath = PORT_Strdup(dbname); | 
| -    char *sep; | 
| - | 
| -    sep = PORT_Strrchr(dirPath,*NSSUTIL_PATH_SEPARATOR); | 
| -#ifdef _WIN32 | 
| -    if (!sep) { | 
| -	/* utilparst.h defines NSSUTIL_PATH_SEPARATOR as "/" for all | 
| -	 * platforms. */ | 
| -	sep = PORT_Strrchr(dirPath,'\\'); | 
| -    } | 
| -#endif | 
| -    if (sep) { | 
| -	*sep = 0; | 
| -	file = PR_smprintf("%s"NSSUTIL_PATH_SEPARATOR"%s", dirPath, filename); | 
| -    } else { | 
| -	file = PR_smprintf("%s", filename); | 
| -    } | 
| -    PORT_Free(dirPath); | 
| -    return file; | 
| -} | 
| - | 
| -static SECStatus nssutil_AddSecmodDBEntry(const char *appName, | 
| -                                          const char *filename, | 
| -                                          const char *dbname, | 
| -                                          const char *module, PRBool rw); | 
| - | 
| -enum lfopen_mode { lfopen_truncate, lfopen_append }; | 
| - | 
| -FILE * | 
| -lfopen(const char *name, enum lfopen_mode om, os_open_permissions_type open_perms) | 
| -{ | 
| -    int fd; | 
| -    FILE *file; | 
| - | 
| -    fd = os_open(name, | 
| -                 (om == lfopen_truncate) ? os_truncate_open_flags : os_append_open_flags, | 
| -                 open_perms); | 
| -    if (fd < 0) { | 
| -	return NULL; | 
| -    } | 
| -    file = os_fdopen(fd, (om == lfopen_truncate) ? "w+" : "a+"); | 
| -    if (!file) { | 
| -	close(fd); | 
| -    } | 
| -    /* file inherits fd */ | 
| -    return file; | 
| -} | 
| - | 
| -#define MAX_LINE_LENGTH 2048 | 
| - | 
| -/* | 
| - * Read all the existing modules in out of the file. | 
| - */ | 
| -static char ** | 
| -nssutil_ReadSecmodDB(const char *appName, | 
| -		    const char *filename, const char *dbname, | 
| -		    char *params, PRBool rw) | 
| -{ | 
| -    FILE *fd = NULL; | 
| -    char **moduleList = NULL; | 
| -    int moduleCount = 1; | 
| -    int useCount = SECMOD_STEP; | 
| -    char line[MAX_LINE_LENGTH]; | 
| -    PRBool internal = PR_FALSE; | 
| -    PRBool skipParams = PR_FALSE; | 
| -    char *moduleString = NULL; | 
| -    char *paramsValue=NULL; | 
| -    PRBool failed = PR_TRUE; | 
| - | 
| -    moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char *)); | 
| -    if (moduleList == NULL) return NULL; | 
| - | 
| -    if (dbname == NULL) { | 
| -	goto return_default; | 
| -    } | 
| - | 
| -    /* do we really want to use streams here */ | 
| -    fd = fopen(dbname, "r"); | 
| -    if (fd == NULL) goto done; | 
| - | 
| -    /* | 
| -     * the following loop takes line separated config lines and collapses | 
| -     * the lines to a single string, escaping and quoting as necessary. | 
| -     */ | 
| -    /* loop state variables */ | 
| -    moduleString = NULL;  /* current concatenated string */ | 
| -    internal = PR_FALSE;	     /* is this an internal module */ | 
| -    skipParams = PR_FALSE;	   /* did we find an override parameter block*/ | 
| -    paramsValue = NULL;		   /* the current parameter block value */ | 
| -    while (fgets(line, sizeof(line), fd) != NULL) { | 
| -	int len = PORT_Strlen(line); | 
| - | 
| -	/* remove the ending newline */ | 
| -	if (len && line[len-1] == '\n') { | 
| -	    len--; | 
| -	    line[len] = 0; | 
| -	} | 
| -	if (*line == '#') { | 
| -	    continue; | 
| -	} | 
| -	if (*line != 0) { | 
| -	    /* | 
| -	     * The PKCS #11 group standard assumes blocks of strings | 
| -	     * separated by new lines, clumped by new lines. Internally | 
| -	     * we take strings separated by spaces, so we may need to escape | 
| -	     * certain spaces. | 
| -	     */ | 
| -	    char *value = PORT_Strchr(line,'='); | 
| - | 
| -	    /* there is no value, write out the stanza as is */ | 
| -	    if (value == NULL || value[1] == 0) { | 
| -		if (moduleString) { | 
| -		    moduleString = nssutil_DupnCat(moduleString," ", 1); | 
| -		    if (moduleString == NULL) goto loser; | 
| -		} | 
| -	        moduleString = nssutil_DupCat(moduleString, line); | 
| -		if (moduleString == NULL) goto loser; | 
| -	    /* value is already quoted, just write it out */ | 
| -	    } else if (value[1] == '"') { | 
| -		if (moduleString) { | 
| -		    moduleString = nssutil_DupnCat(moduleString," ", 1); | 
| -		    if (moduleString == NULL) goto loser; | 
| -		} | 
| -	        moduleString = nssutil_DupCat(moduleString, line); | 
| -		if (moduleString == NULL) goto loser; | 
| -		/* we have an override parameter section, remember that | 
| -		 * we found this (see following comment about why this | 
| -		 * is necessary). */ | 
| -	        if (PORT_Strncasecmp(line, "parameters", 10) == 0) { | 
| -			skipParams = PR_TRUE; | 
| -		} | 
| -	    /* | 
| -	     * The internal token always overrides it's parameter block | 
| -	     * from the passed in parameters, so wait until then end | 
| -	     * before we include the parameter block in case we need to | 
| -	     * override it. NOTE: if the parameter block is quoted with ("), | 
| -	     * this override does not happen. This allows you to override | 
| -	     * the application's parameter configuration. | 
| -	     * | 
| -	     * parameter block state is controlled by the following variables: | 
| -	     *  skipParams - Bool : set to true of we have an override param | 
| -	     *    block (all other blocks, either implicit or explicit are | 
| -	     *    ignored). | 
| -	     *  paramsValue - char * : pointer to the current param block. In | 
| -	     *    the absence of overrides, paramsValue is set to the first | 
| -	     *    parameter block we find. All subsequent blocks are ignored. | 
| -	     *    When we find an internal token, the application passed | 
| -	     *    parameters take precident. | 
| -	     */ | 
| -	    } else if (PORT_Strncasecmp(line, "parameters", 10) == 0) { | 
| -		/* already have parameters */ | 
| -		if (paramsValue) { | 
| -			continue; | 
| -		} | 
| -		paramsValue = NSSUTIL_Quote(&value[1], '"'); | 
| -		if (paramsValue == NULL) goto loser; | 
| -		continue; | 
| -	    } else { | 
| -	    /* may need to quote */ | 
| -	        char *newLine; | 
| -		if (moduleString) { | 
| -		    moduleString = nssutil_DupnCat(moduleString," ", 1); | 
| -		    if (moduleString == NULL) goto loser; | 
| -		} | 
| -		moduleString = nssutil_DupnCat(moduleString,line,value-line+1); | 
| -		if (moduleString == NULL)  goto loser; | 
| -	        newLine = NSSUTIL_Quote(&value[1],'"'); | 
| -		if (newLine == NULL) goto loser; | 
| -		moduleString = nssutil_DupCat(moduleString,newLine); | 
| -	        PORT_Free(newLine); | 
| -		if (moduleString == NULL) goto loser; | 
| -	    } | 
| - | 
| -	    /* check to see if it's internal? */ | 
| -	    if (PORT_Strncasecmp(line, "NSS=", 4) == 0) { | 
| -		/* This should be case insensitive! reviewers make | 
| -		 * me fix it if it's not */ | 
| -		if (PORT_Strstr(line,"internal")) { | 
| -		    internal = PR_TRUE; | 
| -		    /* override the parameters */ | 
| -		    if (paramsValue) { | 
| -			PORT_Free(paramsValue); | 
| -		    } | 
| -		    paramsValue = NSSUTIL_Quote(params, '"'); | 
| -		} | 
| -	    } | 
| -	    continue; | 
| -	} | 
| -	if ((moduleString == NULL) || (*moduleString == 0)) { | 
| -	    continue; | 
| -	} | 
| - | 
| -	/* | 
| -	 * if we are here, we have found a complete stanza. Now write out | 
| -	 * any param section we may have found. | 
| -	 */ | 
| -	if (paramsValue) { | 
| -	    /* we had an override */ | 
| -	    if (!skipParams) { | 
| -		moduleString = nssutil_DupnCat(moduleString," parameters=", 12); | 
| -		if (moduleString == NULL) goto loser; | 
| -		moduleString = nssutil_DupCat(moduleString, paramsValue); | 
| -		if (moduleString == NULL) goto loser; | 
| -	    } | 
| -	    PORT_Free(paramsValue); | 
| -	    paramsValue = NULL; | 
| -	} | 
| - | 
| -	if ((moduleCount+1) >= useCount) { | 
| -	    SECStatus rv; | 
| -	    rv = nssutil_growList(&moduleList, &useCount,  moduleCount+1); | 
| -	    if (rv != SECSuccess) { | 
| -		goto loser; | 
| -	    } | 
| -	} | 
| - | 
| -	if (internal) { | 
| -	    moduleList[0] = moduleString; | 
| -	} else { | 
| -	    moduleList[moduleCount] = moduleString; | 
| -	    moduleCount++; | 
| -	} | 
| -	moduleString = NULL; | 
| -	internal = PR_FALSE; | 
| -	skipParams = PR_FALSE; | 
| -    } | 
| - | 
| -    if (moduleString) { | 
| -	PORT_Free(moduleString); | 
| -	moduleString = NULL; | 
| -    } | 
| -done: | 
| -    /* if we couldn't open a pkcs11 database, look for the old one */ | 
| -    if (fd == NULL) { | 
| -	char *olddbname = _NSSUTIL_GetOldSecmodName(dbname,filename); | 
| -	PRStatus status; | 
| - | 
| -	/* couldn't get the old name */ | 
| -	if (!olddbname) { | 
| -	    goto bail; | 
| -	} | 
| - | 
| -	/* old one exists */ | 
| -	status = PR_Access(olddbname, PR_ACCESS_EXISTS); | 
| -	if (status == PR_SUCCESS) { | 
| -	    PR_smprintf_free(olddbname); | 
| -	    PORT_ZFree(moduleList, useCount*sizeof(char *)); | 
| -	    PORT_SetError(SEC_ERROR_LEGACY_DATABASE); | 
| -	    return NULL; | 
| -	} | 
| - | 
| -bail: | 
| -	if (olddbname) { | 
| -	    PR_smprintf_free(olddbname); | 
| -	} | 
| -    } | 
| - | 
| -return_default: | 
| - | 
| -    if (!moduleList[0]) { | 
| -	char * newParams; | 
| -	moduleString = PORT_Strdup(NSSUTIL_DEFAULT_INTERNAL_INIT1); | 
| -	newParams = NSSUTIL_Quote(params,'"'); | 
| -	if (newParams == NULL) goto loser; | 
| -	moduleString = nssutil_DupCat(moduleString, newParams); | 
| -	PORT_Free(newParams); | 
| -	if (moduleString == NULL) goto loser; | 
| -	moduleString = nssutil_DupCat(moduleString, | 
| -					NSSUTIL_DEFAULT_INTERNAL_INIT2); | 
| -	if (moduleString == NULL) goto loser; | 
| -	moduleString = nssutil_DupCat(moduleString, | 
| -					NSSUTIL_DEFAULT_SFTKN_FLAGS); | 
| -	if (moduleString == NULL) goto loser; | 
| -	moduleString = nssutil_DupCat(moduleString, | 
| -					NSSUTIL_DEFAULT_INTERNAL_INIT3); | 
| -	if (moduleString == NULL) goto loser; | 
| -	moduleList[0] = moduleString; | 
| -	moduleString = NULL; | 
| -    } | 
| -    failed = PR_FALSE; | 
| - | 
| -loser: | 
| -    /* | 
| -     * cleanup | 
| -     */ | 
| -    /* deal with trust cert db here */ | 
| -    if (moduleString) { | 
| -	PORT_Free(moduleString); | 
| -	moduleString = NULL; | 
| -    } | 
| -    if (paramsValue) { | 
| -	PORT_Free(paramsValue); | 
| -	paramsValue = NULL; | 
| -    } | 
| -    if (failed || (moduleList[0] == NULL)) { | 
| -	/* This is wrong! FIXME */ | 
| -	nssutil_releaseSpecList(moduleList); | 
| -	moduleList = NULL; | 
| -	failed = PR_TRUE; | 
| -    } | 
| -    if (fd != NULL) { | 
| -	fclose(fd); | 
| -    } else if (!failed && rw) { | 
| -	/* update our internal module */ | 
| -	nssutil_AddSecmodDBEntry(appName, filename, dbname, moduleList[0], rw); | 
| -    } | 
| -    return moduleList; | 
| -} | 
| - | 
| -static SECStatus | 
| -nssutil_ReleaseSecmodDBData(const char *appName, | 
| -			const char *filename, const char *dbname, | 
| -			char **moduleSpecList, PRBool rw) | 
| -{ | 
| -    if (moduleSpecList) { | 
| -	nssutil_releaseSpecList(moduleSpecList); | 
| -    } | 
| -    return SECSuccess; | 
| -} | 
| - | 
| - | 
| -/* | 
| - * Delete a module from the Data Base | 
| - */ | 
| -static SECStatus | 
| -nssutil_DeleteSecmodDBEntry(const char *appName, | 
| -                            const char *filename, | 
| -                            const char *dbname, | 
| -                            const char *args, | 
| -                            PRBool rw) | 
| -{ | 
| -    /* SHDB_FIXME implement */ | 
| -    os_stat_type stat_existing; | 
| -    os_open_permissions_type file_mode; | 
| -    FILE *fd = NULL; | 
| -    FILE *fd2 = NULL; | 
| -    char line[MAX_LINE_LENGTH]; | 
| -    char *dbname2 = NULL; | 
| -    char *block = NULL; | 
| -    char *name = NULL; | 
| -    char *lib = NULL; | 
| -    int name_len = 0, lib_len = 0; | 
| -    PRBool skip = PR_FALSE; | 
| -    PRBool found = PR_FALSE; | 
| - | 
| -    if (dbname == NULL) { | 
| -	PORT_SetError(SEC_ERROR_INVALID_ARGS); | 
| -	return SECFailure; | 
| -    } | 
| - | 
| -    if (!rw) { | 
| -	PORT_SetError(SEC_ERROR_READ_ONLY); | 
| -	return SECFailure; | 
| -    } | 
| - | 
| -    dbname2 = PORT_Strdup(dbname); | 
| -    if (dbname2 == NULL) goto loser; | 
| -    dbname2[strlen(dbname)-1]++; | 
| - | 
| -    /* get the permissions of the existing file, or use the default */ | 
| -    if (!os_stat(dbname, &stat_existing)) { | 
| -	file_mode = stat_existing.st_mode; | 
| -    } else { | 
| -	file_mode = os_open_permissions_default; | 
| -    } | 
| - | 
| -    /* do we really want to use streams here */ | 
| -    fd = fopen(dbname, "r"); | 
| -    if (fd == NULL) goto loser; | 
| - | 
| -    fd2 = lfopen(dbname2, lfopen_truncate, file_mode); | 
| - | 
| -    if (fd2 == NULL) goto loser; | 
| - | 
| -    name = NSSUTIL_ArgGetParamValue("name",args); | 
| -    if (name) { | 
| -	name_len = PORT_Strlen(name); | 
| -    } | 
| -    lib = NSSUTIL_ArgGetParamValue("library",args); | 
| -    if (lib) { | 
| -	lib_len = PORT_Strlen(lib); | 
| -    } | 
| - | 
| - | 
| -    /* | 
| -     * the following loop takes line separated config files and collapses | 
| -     * the lines to a single string, escaping and quoting as necessary. | 
| -     */ | 
| -    /* loop state variables */ | 
| -    block = NULL; | 
| -    skip = PR_FALSE; | 
| -    while (fgets(line, sizeof(line), fd) != NULL) { | 
| -	/* If we are processing a block (we haven't hit a blank line yet */ | 
| -	if (*line != '\n') { | 
| -	    /* skip means we are in the middle of a block we are deleting */ | 
| -	    if (skip) { | 
| -		continue; | 
| -	    } | 
| -	    /* if we haven't found the block yet, check to see if this block | 
| -	     * matches our requirements */ | 
| -	    if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && | 
| -		 (PORT_Strncmp(line+5,name,name_len) == 0))  || | 
| -	        (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && | 
| -		 (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { | 
| - | 
| -		/* yup, we don't need to save any more data, */ | 
| -		PORT_Free(block); | 
| -		block=NULL; | 
| -		/* we don't need to collect more of this block */ | 
| -		skip = PR_TRUE; | 
| -		/* we don't need to continue searching for the block */ | 
| -		found =PR_TRUE; | 
| -		continue; | 
| -	    } | 
| -	    /* not our match, continue to collect data in this block */ | 
| -	    block = nssutil_DupCat(block,line); | 
| -	    continue; | 
| -	} | 
| -	/* we've collected a block of data that wasn't the module we were | 
| -	 * looking for, write it out */ | 
| -	if (block) { | 
| -	    fwrite(block, PORT_Strlen(block), 1, fd2); | 
| -	    PORT_Free(block); | 
| -	    block = NULL; | 
| -	} | 
| -	/* If we didn't just delete the this block, keep the blank line */ | 
| -	if (!skip) { | 
| -	    fputs(line,fd2); | 
| -	} | 
| -	/* we are definately not in a deleted block anymore */ | 
| -	skip = PR_FALSE; | 
| -    } | 
| -    fclose(fd); | 
| -    fclose(fd2); | 
| -    if (found) { | 
| -	/* rename dbname2 to dbname */ | 
| -	PR_Delete(dbname); | 
| -	PR_Rename(dbname2,dbname); | 
| -    } else { | 
| -	PR_Delete(dbname2); | 
| -    } | 
| -    PORT_Free(dbname2); | 
| -    PORT_Free(lib); | 
| -    PORT_Free(name); | 
| -    PORT_Free(block); | 
| -    return SECSuccess; | 
| - | 
| -loser: | 
| -    if (fd != NULL) { | 
| -	fclose(fd); | 
| -    } | 
| -    if (fd2 != NULL) { | 
| -	fclose(fd2); | 
| -    } | 
| -    if (dbname2) { | 
| -	PR_Delete(dbname2); | 
| -	PORT_Free(dbname2); | 
| -    } | 
| -    PORT_Free(lib); | 
| -    PORT_Free(name); | 
| -    return SECFailure; | 
| -} | 
| - | 
| -/* | 
| - * Add a module to the Data base | 
| - */ | 
| -static SECStatus | 
| -nssutil_AddSecmodDBEntry(const char *appName, | 
| -                        const char *filename, const char *dbname, | 
| -                        const char *module, PRBool rw) | 
| -{ | 
| -    os_stat_type stat_existing; | 
| -    os_open_permissions_type file_mode; | 
| -    FILE *fd = NULL; | 
| -    char *block = NULL; | 
| -    PRBool libFound = PR_FALSE; | 
| - | 
| -    if (dbname == NULL) { | 
| -	PORT_SetError(SEC_ERROR_INVALID_ARGS); | 
| -	return SECFailure; | 
| -    } | 
| - | 
| -    /* can't write to a read only module */ | 
| -    if (!rw) { | 
| -	PORT_SetError(SEC_ERROR_READ_ONLY); | 
| -	return SECFailure; | 
| -    } | 
| - | 
| -    /* remove the previous version if it exists */ | 
| -    (void) nssutil_DeleteSecmodDBEntry(appName, filename, dbname, module, rw); | 
| - | 
| -    /* get the permissions of the existing file, or use the default */ | 
| -    if (!os_stat(dbname, &stat_existing)) { | 
| -	file_mode = stat_existing.st_mode; | 
| -    } else { | 
| -	file_mode = os_open_permissions_default; | 
| -    } | 
| - | 
| -    fd = lfopen(dbname, lfopen_append, file_mode); | 
| -    if (fd == NULL) { | 
| -	return SECFailure; | 
| -    } | 
| -    module = NSSUTIL_ArgStrip(module); | 
| -    while (*module) { | 
| -	int count; | 
| -	char *keyEnd = PORT_Strchr(module,'='); | 
| -	char *value; | 
| - | 
| -	if (PORT_Strncmp(module, "library=", 8) == 0) { | 
| -	   libFound=PR_TRUE; | 
| -	} | 
| -	if (keyEnd == NULL) { | 
| -	    block = nssutil_DupCat(block, module); | 
| -	    break; | 
| -	} | 
| -	block = nssutil_DupnCat(block, module, keyEnd-module+1); | 
| -	if (block == NULL) { goto loser; } | 
| -	value = NSSUTIL_ArgFetchValue(&keyEnd[1], &count); | 
| -	if (value) { | 
| -	    block = nssutil_DupCat(block, NSSUTIL_ArgStrip(value)); | 
| -	    PORT_Free(value); | 
| -	} | 
| -	if (block == NULL) { goto loser; } | 
| -	block = nssutil_DupnCat(block, "\n", 1); | 
| -	module = keyEnd + 1 + count; | 
| -	module = NSSUTIL_ArgStrip(module); | 
| -    } | 
| -    if (block) { | 
| -	if (!libFound) { | 
| -	    fprintf(fd,"library=\n"); | 
| -	} | 
| -	fwrite(block, PORT_Strlen(block), 1, fd); | 
| -	fprintf(fd,"\n"); | 
| -	PORT_Free(block); | 
| -	block = NULL; | 
| -    } | 
| -    fclose(fd); | 
| -    return SECSuccess; | 
| - | 
| -loser: | 
| -    PORT_Free(block); | 
| -    fclose(fd); | 
| -    return SECFailure; | 
| -} | 
| - | 
| - | 
| -char ** | 
| -NSSUTIL_DoModuleDBFunction(unsigned long function,char *parameters, void *args) | 
| -{ | 
| -    char *secmod = NULL; | 
| -    char *appName = NULL; | 
| -    char *filename = NULL; | 
| -    NSSDBType dbType = NSS_DB_TYPE_NONE; | 
| -    PRBool rw; | 
| -    static char *success="Success"; | 
| -    char **rvstr = NULL; | 
| - | 
| - | 
| -    secmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &appName, | 
| -				    &filename, &rw); | 
| -    if ((dbType == NSS_DB_TYPE_LEGACY) || | 
| -	 (dbType == NSS_DB_TYPE_MULTIACCESS)) { | 
| -	/* we can't handle the old database, only softoken can */ | 
| -	PORT_SetError(SEC_ERROR_LEGACY_DATABASE); | 
| -	rvstr =  NULL; | 
| -	goto done; | 
| -    } | 
| - | 
| -    switch (function) { | 
| -    case SECMOD_MODULE_DB_FUNCTION_FIND: | 
| -        rvstr = nssutil_ReadSecmodDB(appName,filename, | 
| -				     secmod,(char *)parameters,rw); | 
| -        break; | 
| -    case SECMOD_MODULE_DB_FUNCTION_ADD: | 
| -        rvstr = (nssutil_AddSecmodDBEntry(appName, filename, | 
| -                                          secmod, (char *)args, rw) | 
| -                 == SECSuccess) ? &success: NULL; | 
| -        break; | 
| -    case SECMOD_MODULE_DB_FUNCTION_DEL: | 
| -        rvstr = (nssutil_DeleteSecmodDBEntry(appName, filename, | 
| -                                             secmod, (char *)args, rw) | 
| -                 == SECSuccess) ? &success: NULL; | 
| -        break; | 
| -    case SECMOD_MODULE_DB_FUNCTION_RELEASE: | 
| -        rvstr = (nssutil_ReleaseSecmodDBData(appName, filename, | 
| -                                             secmod, (char **)args, rw) | 
| -                 == SECSuccess) ? &success: NULL; | 
| -        break; | 
| -    } | 
| -done: | 
| -    if (secmod) PR_smprintf_free(secmod); | 
| -    if (appName) PORT_Free(appName); | 
| -    if (filename) PORT_Free(filename); | 
| -    return rvstr; | 
| -} | 
|  |