Blame nss/cmd/modutil/modutil.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
Packit 40b132
/* To edit this file, set TABSTOPS to 4 spaces. 
Packit 40b132
 * This is not the normal NSS convention. 
Packit 40b132
 */
Packit 40b132
Packit 40b132
#include "modutil.h"
Packit 40b132
#include "install.h"
Packit 40b132
#include <plstr.h>
Packit 40b132
#include "certdb.h" /* for CERT_DB_FILE_VERSION */
Packit 40b132
#include "nss.h"
Packit 40b132
Packit 40b132
static void install_error(char *message);
Packit 40b132
static char* PR_fgets(char *buf, int size, PRFileDesc *file);
Packit 40b132
static char *progName;
Packit 40b132
Packit 40b132
Packit 40b132
/* This enum must be kept in sync with the commandNames list */
Packit 40b132
typedef enum {
Packit 40b132
	NO_COMMAND,
Packit 40b132
	ADD_COMMAND,
Packit 40b132
	CHANGEPW_COMMAND,
Packit 40b132
	CREATE_COMMAND,
Packit 40b132
	DEFAULT_COMMAND,
Packit 40b132
	DELETE_COMMAND,
Packit 40b132
	DISABLE_COMMAND,
Packit 40b132
	ENABLE_COMMAND,
Packit 40b132
	FIPS_COMMAND,
Packit 40b132
	JAR_COMMAND,
Packit 40b132
	LIST_COMMAND,
Packit 40b132
	RAW_LIST_COMMAND,
Packit 40b132
	RAW_ADD_COMMAND,
Packit 40b132
	CHKFIPS_COMMAND,
Packit 40b132
	UNDEFAULT_COMMAND
Packit 40b132
} Command;
Packit 40b132
Packit 40b132
/* This list must be kept in sync with the Command enum */
Packit 40b132
static char *commandNames[] = {
Packit 40b132
	"(no command)",
Packit 40b132
	"-add",
Packit 40b132
	"-changepw",
Packit 40b132
	"-create",
Packit 40b132
	"-default",
Packit 40b132
	"-delete",
Packit 40b132
	"-disable",
Packit 40b132
	"-enable",
Packit 40b132
	"-fips",
Packit 40b132
	"-jar",
Packit 40b132
	"-list",
Packit 40b132
	"-rawlist",
Packit 40b132
	"-rawadd",
Packit 40b132
	"-chkfips",
Packit 40b132
	"-undefault"
Packit 40b132
};
Packit 40b132
Packit 40b132
Packit 40b132
/* this enum must be kept in sync with the optionStrings list */
Packit 40b132
typedef enum {
Packit 40b132
	ADD_ARG=0,
Packit 40b132
	RAW_ADD_ARG,
Packit 40b132
	CHANGEPW_ARG,
Packit 40b132
	CIPHERS_ARG,
Packit 40b132
	CREATE_ARG,
Packit 40b132
	DBDIR_ARG,
Packit 40b132
	DBPREFIX_ARG,
Packit 40b132
	DEFAULT_ARG,
Packit 40b132
	DELETE_ARG,
Packit 40b132
	DISABLE_ARG,
Packit 40b132
	ENABLE_ARG,
Packit 40b132
	FIPS_ARG,
Packit 40b132
	FORCE_ARG,
Packit 40b132
	JAR_ARG,
Packit 40b132
	LIBFILE_ARG,
Packit 40b132
	LIST_ARG,
Packit 40b132
	RAW_LIST_ARG,
Packit 40b132
	MECHANISMS_ARG,
Packit 40b132
	NEWPWFILE_ARG,
Packit 40b132
	PWFILE_ARG,
Packit 40b132
	SLOT_ARG,
Packit 40b132
	UNDEFAULT_ARG,
Packit 40b132
	INSTALLDIR_ARG,
Packit 40b132
	TEMPDIR_ARG,
Packit 40b132
	SECMOD_ARG,
Packit 40b132
	NOCERTDB_ARG,
Packit 40b132
	STRING_ARG,
Packit 40b132
	CHKFIPS_ARG,
Packit 40b132
Packit 40b132
	NUM_ARGS	/* must be last */
Packit 40b132
} Arg;
Packit 40b132
Packit 40b132
/* This list must be kept in sync with the Arg enum */
Packit 40b132
static char *optionStrings[] = {
Packit 40b132
	"-add",
Packit 40b132
	"-rawadd",
Packit 40b132
	"-changepw",
Packit 40b132
	"-ciphers",
Packit 40b132
	"-create",
Packit 40b132
	"-dbdir",
Packit 40b132
	"-dbprefix",
Packit 40b132
	"-default",
Packit 40b132
	"-delete",
Packit 40b132
	"-disable",
Packit 40b132
	"-enable",
Packit 40b132
	"-fips",
Packit 40b132
	"-force",
Packit 40b132
	"-jar",
Packit 40b132
	"-libfile",
Packit 40b132
	"-list",
Packit 40b132
	"-rawlist",
Packit 40b132
	"-mechanisms",
Packit 40b132
	"-newpwfile",
Packit 40b132
	"-pwfile",
Packit 40b132
	"-slot",
Packit 40b132
	"-undefault",
Packit 40b132
	"-installdir",
Packit 40b132
	"-tempdir",
Packit 40b132
	"-secmod",
Packit 40b132
	"-nocertdb",
Packit 40b132
	"-string",
Packit 40b132
	"-chkfips",
Packit 40b132
};
Packit 40b132
Packit 40b132
/* Increment i if doing so would have i still be less than j.  If you
Packit 40b132
   are able to do this, return 0.  Otherwise return 1. */
Packit 40b132
#define TRY_INC(i,j)  ( ((i+1)
Packit 40b132
Packit 40b132
/********************************************************************
Packit 40b132
 *
Packit 40b132
 * file-wide variables obtained from the command line
Packit 40b132
 */
Packit 40b132
static Command command = NO_COMMAND;
Packit 40b132
static char* pwFile = NULL;
Packit 40b132
static char* newpwFile = NULL;
Packit 40b132
static char* moduleName = NULL;
Packit 40b132
static char* moduleSpec = NULL;
Packit 40b132
static char* slotName = NULL;
Packit 40b132
static char* secmodName = NULL;
Packit 40b132
static char* tokenName = NULL;
Packit 40b132
static char* libFile = NULL;
Packit 40b132
static char* dbdir = NULL;
Packit 40b132
static char* dbprefix = "";
Packit 40b132
static char* secmodString = NULL;
Packit 40b132
static char* mechanisms = NULL;
Packit 40b132
static char* ciphers = NULL;
Packit 40b132
static char* fipsArg = NULL;
Packit 40b132
static char* jarFile = NULL;
Packit 40b132
static char* installDir = NULL;
Packit 40b132
static char* tempDir = NULL;
Packit 40b132
static short force = 0;
Packit 40b132
static PRBool nocertdb = PR_FALSE;
Packit 40b132
Packit 40b132
/*******************************************************************
Packit 40b132
 *
Packit 40b132
 * p a r s e _ a r g s
Packit 40b132
 */
Packit 40b132
static Error
Packit 40b132
parse_args(int argc, char *argv[])
Packit 40b132
{
Packit 40b132
	int i;
Packit 40b132
	char *arg;
Packit 40b132
	int optionType;
Packit 40b132
Packit 40b132
	/* Loop over all arguments */
Packit 40b132
	for(i=1; i < argc; i++) {
Packit 40b132
		arg = argv[i];
Packit 40b132
Packit 40b132
		/* Make sure this is an option and not some floating argument */
Packit 40b132
		if(arg[0] != '-') {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[UNEXPECTED_ARG_ERR], argv[i]);
Packit 40b132
			return UNEXPECTED_ARG_ERR;
Packit 40b132
		}
Packit 40b132
Packit 40b132
		/* Find which option this is */
Packit 40b132
		for(optionType=0; optionType < NUM_ARGS; optionType++) {
Packit 40b132
			if(! strcmp(arg, optionStrings[optionType])) {
Packit 40b132
				break;
Packit 40b132
			}
Packit 40b132
		}
Packit 40b132
		
Packit 40b132
		/* Deal with this specific option */
Packit 40b132
		switch(optionType) {
Packit 40b132
		case NUM_ARGS:
Packit 40b132
		default:
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[UNKNOWN_OPTION_ERR], arg);
Packit 40b132
			return UNKNOWN_OPTION_ERR;
Packit 40b132
			break;
Packit 40b132
		case ADD_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = ADD_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			moduleName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case CHANGEPW_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = CHANGEPW_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			tokenName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case CIPHERS_ARG:
Packit 40b132
			if(ciphers != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			ciphers = argv[i];
Packit 40b132
			break;
Packit 40b132
		case CREATE_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = CREATE_COMMAND;
Packit 40b132
			break;
Packit 40b132
		case DBDIR_ARG:
Packit 40b132
			if(dbdir != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			dbdir = argv[i];
Packit 40b132
			break;
Packit 40b132
		case DBPREFIX_ARG:
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			dbprefix = argv[i];
Packit 40b132
			break;
Packit 40b132
		case UNDEFAULT_ARG:
Packit 40b132
		case DEFAULT_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			if(optionType == DEFAULT_ARG) {
Packit 40b132
				command = DEFAULT_COMMAND;
Packit 40b132
			} else {
Packit 40b132
				command = UNDEFAULT_COMMAND;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			moduleName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case DELETE_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = DELETE_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			moduleName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case DISABLE_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = DISABLE_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			moduleName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case ENABLE_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = ENABLE_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			moduleName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case FIPS_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = FIPS_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			fipsArg = argv[i];
Packit 40b132
			break;
Packit 40b132
		case CHKFIPS_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = CHKFIPS_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			fipsArg = argv[i];
Packit 40b132
			break;
Packit 40b132
		case FORCE_ARG:
Packit 40b132
			force = 1;
Packit 40b132
			break;
Packit 40b132
		case NOCERTDB_ARG:
Packit 40b132
			nocertdb = PR_TRUE;
Packit 40b132
			break;
Packit 40b132
		case INSTALLDIR_ARG:
Packit 40b132
			if(installDir != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			installDir = argv[i];
Packit 40b132
			break;
Packit 40b132
		case TEMPDIR_ARG:
Packit 40b132
			if(tempDir != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			tempDir = argv[i];
Packit 40b132
			break;
Packit 40b132
		case JAR_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = JAR_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			jarFile = argv[i];
Packit 40b132
			break;
Packit 40b132
		case LIBFILE_ARG:
Packit 40b132
			if(libFile != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			libFile = argv[i];
Packit 40b132
			break;
Packit 40b132
		case LIST_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = LIST_COMMAND;
Packit 40b132
			/* This option may or may not have an argument */
Packit 40b132
			if( (i+1 < argc) && (argv[i+1][0] != '-') ) {
Packit 40b132
				moduleName = argv[++i];
Packit 40b132
			}
Packit 40b132
			break;
Packit 40b132
		case RAW_LIST_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = RAW_LIST_COMMAND;
Packit 40b132
			/* This option may or may not have an argument */
Packit 40b132
			if( (i+1 < argc) && (argv[i+1][0] != '-') ) {
Packit 40b132
				moduleName = argv[++i];
Packit 40b132
			}
Packit 40b132
			break;
Packit 40b132
		case RAW_ADD_ARG:
Packit 40b132
			if(command != NO_COMMAND) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[MULTIPLE_COMMAND_ERR], arg);
Packit 40b132
				return MULTIPLE_COMMAND_ERR;
Packit 40b132
			}
Packit 40b132
			command = RAW_ADD_COMMAND;
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			moduleSpec = argv[i];
Packit 40b132
			break;
Packit 40b132
		case MECHANISMS_ARG:
Packit 40b132
			if(mechanisms != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			mechanisms = argv[i];
Packit 40b132
			break;
Packit 40b132
		case NEWPWFILE_ARG:
Packit 40b132
			if(newpwFile != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			newpwFile = argv[i];
Packit 40b132
			break;
Packit 40b132
		case PWFILE_ARG:
Packit 40b132
			if(pwFile != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			pwFile = argv[i];
Packit 40b132
			break;
Packit 40b132
		case SLOT_ARG:
Packit 40b132
			if(slotName != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			slotName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case SECMOD_ARG:
Packit 40b132
			if(secmodName != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			secmodName = argv[i];
Packit 40b132
			break;
Packit 40b132
		case STRING_ARG:
Packit 40b132
			if(secmodString != NULL) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[DUPLICATE_OPTION_ERR], arg);
Packit 40b132
				return DUPLICATE_OPTION_ERR;
Packit 40b132
			}
Packit 40b132
			if(TRY_INC(i, argc)) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[OPTION_NEEDS_ARG_ERR], arg);
Packit 40b132
				return OPTION_NEEDS_ARG_ERR;
Packit 40b132
			}
Packit 40b132
			secmodString = argv[i];
Packit 40b132
			break;
Packit 40b132
		}
Packit 40b132
	}
Packit 40b132
	return SUCCESS;
Packit 40b132
}
Packit 40b132
Packit 40b132
/************************************************************************
Packit 40b132
 *
Packit 40b132
 * v e r i f y _ p a r a m s
Packit 40b132
 */
Packit 40b132
static Error
Packit 40b132
verify_params()
Packit 40b132
{
Packit 40b132
	switch(command) {
Packit 40b132
	case ADD_COMMAND:
Packit 40b132
		if(libFile == NULL) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR],
Packit 40b132
				commandNames[ADD_COMMAND], optionStrings[LIBFILE_ARG]);
Packit 40b132
			return MISSING_PARAM_ERR;
Packit 40b132
		}
Packit 40b132
		break;
Packit 40b132
	case CHANGEPW_COMMAND:
Packit 40b132
		break;
Packit 40b132
	case CREATE_COMMAND:
Packit 40b132
		break;
Packit 40b132
	case DELETE_COMMAND:
Packit 40b132
		break;
Packit 40b132
	case DISABLE_COMMAND:
Packit 40b132
		break;
Packit 40b132
	case ENABLE_COMMAND:
Packit 40b132
		break;
Packit 40b132
	case FIPS_COMMAND:
Packit 40b132
	case CHKFIPS_COMMAND:
Packit 40b132
		if(PL_strcasecmp(fipsArg, "true") &&
Packit 40b132
			PL_strcasecmp(fipsArg, "false")) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
Packit 40b132
			return INVALID_FIPS_ARG;
Packit 40b132
		}
Packit 40b132
		break;
Packit 40b132
	case JAR_COMMAND:
Packit 40b132
		if(installDir == NULL) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR],
Packit 40b132
				commandNames[JAR_COMMAND], optionStrings[INSTALLDIR_ARG]);
Packit 40b132
			return MISSING_PARAM_ERR;
Packit 40b132
		}
Packit 40b132
		break;
Packit 40b132
	case LIST_COMMAND:
Packit 40b132
	case RAW_LIST_COMMAND:
Packit 40b132
		break;
Packit 40b132
	case RAW_ADD_COMMAND:
Packit 40b132
		break;
Packit 40b132
	case UNDEFAULT_COMMAND:
Packit 40b132
	case DEFAULT_COMMAND:
Packit 40b132
		if(mechanisms == NULL) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[MISSING_PARAM_ERR],
Packit 40b132
				commandNames[command], optionStrings[MECHANISMS_ARG]);
Packit 40b132
			return MISSING_PARAM_ERR;
Packit 40b132
		}
Packit 40b132
		break;
Packit 40b132
	default:
Packit 40b132
		/* Ignore this here */
Packit 40b132
		break;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	return SUCCESS;
Packit 40b132
}
Packit 40b132
Packit 40b132
/********************************************************************
Packit 40b132
 *
Packit 40b132
 * i n i t _ c r y p t o
Packit 40b132
 *
Packit 40b132
 * Does crypto initialization that all commands will require.
Packit 40b132
 * If -nocertdb option is specified, don't open key or cert db (we don't
Packit 40b132
 * need them if we aren't going to be verifying signatures).  This is
Packit 40b132
 * because serverland doesn't always have cert and key database files
Packit 40b132
 * available.
Packit 40b132
 *
Packit 40b132
 * This function is ill advised. Names and locations of databases are
Packit 40b132
 * private to NSS proper. Such functions only confuse other users.
Packit 40b132
 *
Packit 40b132
 */
Packit 40b132
static Error
Packit 40b132
check_crypto(PRBool create, PRBool readOnly)
Packit 40b132
{
Packit 40b132
	char *dir;
Packit 40b132
	char *moddbname=NULL;
Packit 40b132
	Error retval;
Packit 40b132
	static const char multiaccess[] = { "multiaccess:" };
Packit 40b132
Packit 40b132
	dir = SECU_ConfigDirectory(dbdir); /* dir is never NULL */
Packit 40b132
	if (dir[0] == '\0') {
Packit 40b132
		PR_fprintf(PR_STDERR, errStrings[NO_DBDIR_ERR]);
Packit 40b132
		retval=NO_DBDIR_ERR;
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
	if (strncmp(dir, multiaccess, sizeof multiaccess - 1) == 0) {
Packit 40b132
		/* won't attempt to handle the multiaccess case. */
Packit 40b132
		return SUCCESS;
Packit 40b132
	}
Packit 40b132
#ifdef notdef
Packit 40b132
	/* Make sure db directory exists and is readable */
Packit 40b132
	if(PR_Access(dir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
Packit 40b132
		PR_fprintf(PR_STDERR, errStrings[DIR_DOESNT_EXIST_ERR], dir);
Packit 40b132
		retval = DIR_DOESNT_EXIST_ERR;
Packit 40b132
		goto loser;
Packit 40b132
	} else if(PR_Access(dir, PR_ACCESS_READ_OK) != PR_SUCCESS) {
Packit 40b132
		PR_fprintf(PR_STDERR, errStrings[DIR_NOT_READABLE_ERR], dir);
Packit 40b132
		retval = DIR_NOT_READABLE_ERR;
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	if (secmodName == NULL) {
Packit 40b132
		secmodName = "secmod.db";
Packit 40b132
	}
Packit 40b132
Packit 40b132
	moddbname = PR_smprintf("%s/%s", dir, secmodName);
Packit 40b132
	if (!moddbname)
Packit 40b132
	    return OUT_OF_MEM_ERR;
Packit 40b132
Packit 40b132
	/* Check for the proper permissions on databases */
Packit 40b132
	if(create) {
Packit 40b132
		/* Make sure dbs don't already exist, and the directory is
Packit 40b132
			writeable */
Packit 40b132
		if(PR_Access(moddbname, PR_ACCESS_EXISTS)==PR_SUCCESS) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[FILE_ALREADY_EXISTS_ERR],
Packit 40b132
			           moddbname);
Packit 40b132
			retval=FILE_ALREADY_EXISTS_ERR;
Packit 40b132
			goto loser;
Packit 40b132
		} else 
Packit 40b132
		if(PR_Access(dir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[DIR_NOT_WRITEABLE_ERR], dir);
Packit 40b132
			retval=DIR_NOT_WRITEABLE_ERR;
Packit 40b132
			goto loser;
Packit 40b132
		}
Packit 40b132
	} else {
Packit 40b132
		/* Make sure dbs are readable and writeable */
Packit 40b132
		if(PR_Access(moddbname, PR_ACCESS_READ_OK) != PR_SUCCESS) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[FILE_NOT_READABLE_ERR], moddbname);
Packit 40b132
			retval=FILE_NOT_READABLE_ERR;
Packit 40b132
			goto loser;
Packit 40b132
		}
Packit 40b132
Packit 40b132
		/* Check for write access if we'll be making changes */
Packit 40b132
		if( !readOnly ) {
Packit 40b132
			if(PR_Access(moddbname, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
Packit 40b132
				PR_fprintf(PR_STDERR, errStrings[FILE_NOT_WRITEABLE_ERR],
Packit 40b132
							moddbname);
Packit 40b132
				retval=FILE_NOT_WRITEABLE_ERR;
Packit 40b132
				goto loser;
Packit 40b132
			}
Packit 40b132
		}
Packit 40b132
		PR_fprintf(PR_STDOUT, msgStrings[USING_DBDIR_MSG],
Packit 40b132
		  SECU_ConfigDirectory(NULL));
Packit 40b132
	}
Packit 40b132
#endif
Packit 40b132
	retval=SUCCESS;
Packit 40b132
loser:
Packit 40b132
	if (moddbname) {
Packit 40b132
		PR_Free(moddbname);
Packit 40b132
	}
Packit 40b132
	return retval;
Packit 40b132
}
Packit 40b132
Packit 40b132
static Error
Packit 40b132
init_crypto(PRBool create, PRBool readOnly)
Packit 40b132
{
Packit 40b132
Packit 40b132
	PRUint32  flags = 0;
Packit 40b132
	SECStatus rv;
Packit 40b132
	Error     retval;
Packit 40b132
	/* Open/create key database */
Packit 40b132
Packit 40b132
	if (readOnly) flags |= NSS_INIT_READONLY;
Packit 40b132
	if (nocertdb) flags |= NSS_INIT_NOCERTDB;
Packit 40b132
	rv = NSS_Initialize(SECU_ConfigDirectory(NULL), dbprefix, dbprefix,
Packit 40b132
		       secmodName, flags);
Packit 40b132
	if (rv != SECSuccess) {
Packit 40b132
		SECU_PrintPRandOSError(progName);
Packit 40b132
		retval=NSS_INITIALIZE_FAILED_ERR;
Packit 40b132
	} else 
Packit 40b132
		retval=SUCCESS;
Packit 40b132
Packit 40b132
	return retval;
Packit 40b132
}
Packit 40b132
Packit 40b132
/*************************************************************************
Packit 40b132
 *
Packit 40b132
 * u s a g e
Packit 40b132
 */
Packit 40b132
static void
Packit 40b132
usage()
Packit 40b132
{
Packit 40b132
	PR_fprintf(PR_STDOUT,
Packit 40b132
"\nNetscape Cryptographic Module Utility\n"
Packit 40b132
"Usage: modutil [command] [options]\n\n"
Packit 40b132
"                            COMMANDS\n"
Packit 40b132
"---------------------------------------------------------------------------\n"
Packit 40b132
"-add MODULE_NAME                 Add the named module to the module database\n"
Packit 40b132
"   -libfile LIBRARY_FILE         The name of the file (.so or .dll)\n"
Packit 40b132
"                                 containing the implementation of PKCS #11\n"
Packit 40b132
"   [-ciphers CIPHER_LIST]        Enable the given ciphers on this module\n"
Packit 40b132
"   [-mechanisms MECHANISM_LIST]  Make the module a default provider of the\n"
Packit 40b132
"                                 given mechanisms\n"
Packit 40b132
"   [-string CONFIG_STRING]       Pass a configuration string to this module\n"
Packit 40b132
"-changepw TOKEN                  Change the password on the named token\n"
Packit 40b132
"   [-pwfile FILE]                The old password is in this file\n"
Packit 40b132
"   [-newpwfile FILE]             The new password is in this file\n"
Packit 40b132
"-chkfips [ true | false ]        If true, verify  FIPS mode.  If false,\n"
Packit 40b132
"                                 verify not FIPS mode\n"
Packit 40b132
"-create                          Create a new set of security databases\n"
Packit 40b132
"-default MODULE                  Make the given module a default provider\n"
Packit 40b132
"   -mechanisms MECHANISM_LIST    of the given mechanisms\n"
Packit 40b132
"   [-slot SLOT]                  limit change to only the given slot\n"
Packit 40b132
"-delete MODULE                   Remove the named module from the module\n"
Packit 40b132
"                                 database\n"
Packit 40b132
"-disable MODULE                  Disable the named module\n"
Packit 40b132
"   [-slot SLOT]                  Disable only the named slot on the module\n"
Packit 40b132
"-enable MODULE                   Enable the named module\n"
Packit 40b132
"   [-slot SLOT]                  Enable only the named slot on the module\n"
Packit 40b132
"-fips [ true | false ]           If true, enable FIPS mode.  If false,\n"
Packit 40b132
"                                 disable FIPS mode\n"
Packit 40b132
"-force                           Do not run interactively\n"
Packit 40b132
"-jar JARFILE                     Install a PKCS #11 module from the given\n"
Packit 40b132
"                                 JAR file in the PKCS #11 JAR format\n"
Packit 40b132
"   -installdir DIR               Use DIR as the root directory of the\n"
Packit 40b132
"                                 installation\n"
Packit 40b132
"   [-tempdir DIR]                Use DIR as the temporary installation\n"
Packit 40b132
"                                 directory. If not specified, the current\n"
Packit 40b132
"                                 directory is used\n"
Packit 40b132
"-list [MODULE]                   Lists information about the specified module\n"
Packit 40b132
"                                 or about all modules if none is specified\n"
Packit 40b132
"-rawadd MODULESPEC               Add module spec string to secmod DB\n"
Packit 40b132
"-rawlist [MODULE]                Display module spec(s) for one or all\n"
Packit 40b132
"                                 loadable modules\n"
Packit 40b132
"-undefault MODULE                The given module is NOT a default provider\n"
Packit 40b132
"   -mechanisms MECHANISM_LIST    of the listed mechanisms\n"
Packit 40b132
"   [-slot SLOT]                  limit change to only the given slot\n"
Packit 40b132
"---------------------------------------------------------------------------\n"
Packit 40b132
"\n"
Packit 40b132
"                             OPTIONS\n"
Packit 40b132
"---------------------------------------------------------------------------\n"
Packit 40b132
"-dbdir DIR                       Directory DIR contains the security databases\n"
Packit 40b132
"-dbprefix prefix                 Prefix for the security databases\n"
Packit 40b132
"-nocertdb                        Do not load certificate or key databases. No\n"
Packit 40b132
"                                 verification will be performed on JAR files.\n"
Packit 40b132
"-secmod secmodName               Name of the security modules file\n"
Packit 40b132
"---------------------------------------------------------------------------\n"
Packit 40b132
"\n"
Packit 40b132
"Mechanism lists are colon-separated.  The following mechanisms are recognized:\n"
Packit 40b132
"RSA, DSA, DH, RC2, RC4, RC5, AES, CAMELLIA, DES, MD2, MD5, SHA1, SHA256, SHA512,\n"
Packit 40b132
"SSL, TLS, RANDOM, and FRIENDLY\n"
Packit 40b132
"\n"
Packit 40b132
"Cipher lists are colon-separated.  The following ciphers are recognized:\n"
Packit 40b132
"\n"
Packit 40b132
"\nQuestions or bug reports should be sent to modutil-support@netscape.com.\n"
Packit 40b132
);
Packit 40b132
Packit 40b132
}
Packit 40b132
Packit 40b132
/*************************************************************************
Packit 40b132
 *
Packit 40b132
 * m a i n
Packit 40b132
 */
Packit 40b132
int
Packit 40b132
main(int argc, char *argv[])
Packit 40b132
{
Packit 40b132
	int errcode = SUCCESS;
Packit 40b132
	PRBool createdb, readOnly;
Packit 40b132
#define STDINBUF_SIZE 80
Packit 40b132
	char stdinbuf[STDINBUF_SIZE];
Packit 40b132
Packit 40b132
	progName = strrchr(argv[0], '/');
Packit 40b132
	progName = progName ? progName+1 : argv[0];
Packit 40b132
Packit 40b132
Packit 40b132
	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
Packit 40b132
Packit 40b132
	if(parse_args(argc, argv) != SUCCESS) {
Packit 40b132
		usage();
Packit 40b132
		errcode = INVALID_USAGE_ERR;
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	if(verify_params() != SUCCESS) {
Packit 40b132
		usage();
Packit 40b132
		errcode = INVALID_USAGE_ERR;
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	if(command==NO_COMMAND) {
Packit 40b132
		PR_fprintf(PR_STDERR, errStrings[NO_COMMAND_ERR]);
Packit 40b132
		usage();
Packit 40b132
		errcode = INVALID_USAGE_ERR;
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	/* Set up crypto stuff */
Packit 40b132
	createdb = command==CREATE_COMMAND;
Packit 40b132
	readOnly = ((command == LIST_COMMAND) || 
Packit 40b132
	            (command == CHKFIPS_COMMAND) ||
Packit 40b132
	            (command == RAW_LIST_COMMAND));
Packit 40b132
Packit 40b132
	/* Make sure browser is not running if we're writing to a database */
Packit 40b132
	/* Do this before initializing crypto */
Packit 40b132
	if(!readOnly && !force) {
Packit 40b132
		char *response;
Packit 40b132
Packit 40b132
		PR_fprintf(PR_STDOUT, msgStrings[BROWSER_RUNNING_MSG]);
Packit 40b132
		if( ! PR_fgets(stdinbuf, STDINBUF_SIZE, PR_STDIN)) {
Packit 40b132
			PR_fprintf(PR_STDERR, errStrings[STDIN_READ_ERR]);
Packit 40b132
			errcode = STDIN_READ_ERR;
Packit 40b132
			goto loser;
Packit 40b132
		}
Packit 40b132
		if( (response=strtok(stdinbuf, " \r\n\t")) ) {
Packit 40b132
			if(!PL_strcasecmp(response, "q")) {
Packit 40b132
				PR_fprintf(PR_STDOUT, msgStrings[ABORTING_MSG]);
Packit 40b132
				errcode = SUCCESS;
Packit 40b132
				goto loser;
Packit 40b132
			}
Packit 40b132
		}
Packit 40b132
		PR_fprintf(PR_STDOUT, "\n");
Packit 40b132
	}
Packit 40b132
Packit 40b132
	errcode = check_crypto(createdb, readOnly);
Packit 40b132
	if( errcode != SUCCESS) {
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	if ((command == RAW_LIST_COMMAND) || (command == RAW_ADD_COMMAND)) {
Packit 40b132
		if(!moduleName) {
Packit 40b132
			char *readOnlyStr, *noCertDBStr, *sep;
Packit 40b132
			if (!secmodName) secmodName="secmod.db";
Packit 40b132
			if (!dbprefix) dbprefix = "";
Packit 40b132
			sep = ((command == RAW_LIST_COMMAND) && nocertdb) ? "," : " ";
Packit 40b132
			readOnlyStr = (command == RAW_LIST_COMMAND) ? "readOnly" : "" ;
Packit 40b132
			noCertDBStr = nocertdb ? "noCertDB" : "";
Packit 40b132
			SECU_ConfigDirectory(dbdir);
Packit 40b132
Packit 40b132
			moduleName=PR_smprintf(
Packit 40b132
    "name=\"NSS default Module DB\" parameters=\"configdir=%s certPrefix=%s "
Packit 40b132
    "keyPrefix=%s secmod=%s flags=%s%s%s\" NSS=\"flags=internal,moduleDB,"
Packit 40b132
    "moduleDBOnly,critical\"",
Packit 40b132
			                       SECU_ConfigDirectory(NULL),dbprefix,dbprefix,
Packit 40b132
			                       secmodName, readOnlyStr,sep, noCertDBStr);
Packit 40b132
		}
Packit 40b132
		if (command == RAW_LIST_COMMAND) {
Packit 40b132
			errcode = RawListModule(moduleName);
Packit 40b132
		} else {
Packit 40b132
			PORT_Assert(moduleSpec);
Packit 40b132
			errcode = RawAddModule(moduleName,moduleSpec);
Packit 40b132
		}
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	errcode = init_crypto(createdb, readOnly);
Packit 40b132
	if( errcode != SUCCESS) {
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	errcode = LoadMechanismList();
Packit 40b132
	if (errcode != SUCCESS) {
Packit 40b132
		goto loser;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	/* Execute the command */
Packit 40b132
	switch(command) {
Packit 40b132
	case ADD_COMMAND:
Packit 40b132
		errcode = AddModule(moduleName, libFile, ciphers, mechanisms, secmodString);
Packit 40b132
		break;
Packit 40b132
	case CHANGEPW_COMMAND:
Packit 40b132
		errcode = ChangePW(tokenName, pwFile, newpwFile);
Packit 40b132
		break;
Packit 40b132
	case CREATE_COMMAND:
Packit 40b132
		/* The work was already done in init_crypto() */
Packit 40b132
		break;
Packit 40b132
	case DEFAULT_COMMAND:
Packit 40b132
		errcode = SetDefaultModule(moduleName, slotName, mechanisms);
Packit 40b132
		break;
Packit 40b132
	case DELETE_COMMAND:
Packit 40b132
		errcode = DeleteModule(moduleName);
Packit 40b132
		break;
Packit 40b132
	case DISABLE_COMMAND:
Packit 40b132
		errcode = EnableModule(moduleName, slotName, PR_FALSE);
Packit 40b132
		break;
Packit 40b132
	case ENABLE_COMMAND:
Packit 40b132
		errcode = EnableModule(moduleName, slotName, PR_TRUE);
Packit 40b132
		break;
Packit 40b132
	case FIPS_COMMAND:
Packit 40b132
		errcode = FipsMode(fipsArg);
Packit 40b132
		break;
Packit 40b132
	case CHKFIPS_COMMAND:
Packit 40b132
		errcode = ChkFipsMode(fipsArg);
Packit 40b132
		break;
Packit 40b132
	case JAR_COMMAND:
Packit 40b132
		Pk11Install_SetErrorHandler(install_error);
Packit 40b132
		errcode = Pk11Install_DoInstall(jarFile, installDir, tempDir,
Packit 40b132
		                                PR_STDOUT, force, nocertdb);
Packit 40b132
		break;
Packit 40b132
	case LIST_COMMAND:
Packit 40b132
		if(moduleName) {
Packit 40b132
			errcode = ListModule(moduleName);
Packit 40b132
		} else {
Packit 40b132
			errcode = ListModules();
Packit 40b132
		}
Packit 40b132
		break;
Packit 40b132
	case UNDEFAULT_COMMAND:
Packit 40b132
		errcode = UnsetDefaultModule(moduleName, slotName, mechanisms);
Packit 40b132
		break;
Packit 40b132
	default:
Packit 40b132
		PR_fprintf(PR_STDERR, "This command is not supported yet.\n");
Packit 40b132
		errcode = INVALID_USAGE_ERR;
Packit 40b132
		break;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	if (NSS_Shutdown() != SECSuccess) {
Packit 40b132
		exit(1);
Packit 40b132
	}
Packit 40b132
Packit 40b132
loser:
Packit 40b132
	PR_Cleanup();
Packit 40b132
	return errcode;
Packit 40b132
}
Packit 40b132
Packit 40b132
/************************************************************************
Packit 40b132
 *
Packit 40b132
 * i n s t a l l _ e r r o r
Packit 40b132
 *
Packit 40b132
 * Callback function to handle errors in PK11 JAR file installation.
Packit 40b132
 */
Packit 40b132
static void
Packit 40b132
install_error(char *message)
Packit 40b132
{
Packit 40b132
	PR_fprintf(PR_STDERR, "Install error: %s\n", message);
Packit 40b132
}
Packit 40b132
Packit 40b132
/*************************************************************************
Packit 40b132
 *
Packit 40b132
 * o u t _ o f _ m e m o r y
Packit 40b132
 */
Packit 40b132
void
Packit 40b132
out_of_memory(void)
Packit 40b132
{
Packit 40b132
	PR_fprintf(PR_STDERR, errStrings[OUT_OF_MEM_ERR]);
Packit 40b132
	exit(OUT_OF_MEM_ERR);
Packit 40b132
}
Packit 40b132
Packit 40b132
Packit 40b132
/**************************************************************************
Packit 40b132
 *
Packit 40b132
 * P R _ f g e t s
Packit 40b132
 *
Packit 40b132
 * fgets implemented with NSPR.
Packit 40b132
 */
Packit 40b132
static char*
Packit 40b132
PR_fgets(char *buf, int size, PRFileDesc *file)
Packit 40b132
{
Packit 40b132
	int i;
Packit 40b132
	int status;
Packit 40b132
	char c;
Packit 40b132
Packit 40b132
	i=0;
Packit 40b132
	while(i < size-1) {
Packit 40b132
		status = PR_Read(file, (void*) &c, 1);
Packit 40b132
		if(status==-1) {
Packit 40b132
			return NULL;
Packit 40b132
		} else if(status==0) {
Packit 40b132
			break;
Packit 40b132
		}
Packit 40b132
		buf[i++] = c;
Packit 40b132
		if(c=='\n') {
Packit 40b132
			break;
Packit 40b132
		}
Packit 40b132
	}
Packit 40b132
	buf[i]='\0';
Packit 40b132
Packit 40b132
	return buf;
Packit 40b132
}