install.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:24k
- /*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
- #include "install.h"
- #include "install-ds.h"
- #include <prlock.h>
- #include <prio.h>
- #include <prmem.h>
- #include <prprf.h>
- #include <prsystem.h>
- #include <prproces.h>
- /*extern "C" {*/
- #include <jar.h>
- /*}*/
- extern /*"C"*/
- int Pk11Install_AddNewModule(char* moduleName, char* dllPath,
- unsigned long defaultMechanismFlags,
- unsigned long cipherEnableFlags);
- extern /*"C"*/
- short Pk11Install_UserVerifyJar(JAR *jar, PRFileDesc *out,
- PRBool query);
- extern /*"C"*/
- char* mySECU_ErrorString(int16);
- extern
- int Pk11Install_yyparse();
- #define INSTALL_METAINFO_TAG "Pkcs11_install_script"
- #define SCRIPT_TEMP_FILE "pkcs11inst.tmp"
- #define ROOT_MARKER "%root%"
- #define TEMP_MARKER "%temp%"
- #define PRINTF_ROOT_MARKER "%%root%%"
- #define TEMPORARY_DIRECTORY_NAME "pk11inst.dir"
- #define JAR_BASE_END (JAR_BASE+100)
- static PRLock* errorHandlerLock=NULL;
- static Pk11Install_ErrorHandler errorHandler=NULL;
- static char* PR_Strdup(const char* str);
- static int rm_dash_r (char *path);
- static int make_dirs(char *path, int file_perms);
- static int dir_perms(int perms);
- static Pk11Install_Error DoInstall(JAR *jar, const char *installDir,
- const char* tempDir, Pk11Install_Platform *platform,
- PRFileDesc *feedback, PRBool noverify);
- static char *errorString[]= {
- "Operation was successful", /* PK11_INSTALL_NO_ERROR */
- "Directory "%s" does not exist", /* PK11_INSTALL_DIR_DOESNT_EXIST */
- "File "%s" does not exist", /* PK11_INSTALL_FILE_DOESNT_EXIST */
- "File "%s" is not readable", /* PK11_INSTALL_FILE_NOT_READABLE */
- "%s", /* PK11_INSTALL_ERROR_STRING */
- "Error in JAR file %s: %s", /* PK11_INSTALL_JAR_ERROR */
- "No Pkcs11_install_script specified in JAR metainfo file",
- /* PK11_INSTALL_NO_INSTALLER_SCRIPT */
- "Could not delete temporary file "%s"",
- /*PK11_INSTALL_DELETE_TEMP_FILE */
- "Could not open temporary file "%s"", /*PK11_INSTALL_OPEN_SCRIPT_FILE*/
- "%s: %s", /* PK11_INSTALL_SCRIPT_PARSE */
- "Error in script: %s",
- "Unable to obtain system platform information",
- "Installer script has no information about the current platform (%s)",
- "Relative directory "%s" does not contain "PRINTF_ROOT_MARKER,
- "Module File "%s" not found",
- "Error occurred installing module "%s" into database",
- "Error extracting "%s" from JAR file: %s",
- "Directory "%s" is not writeable",
- "Could not create directory "%s"",
- "Could not remove directory "%s"",
- "Unable to execute "%s"",
- "Unable to wait for process "%s"",
- ""%s" returned error code %d",
- "User aborted operation",
- "Unspecified error"
- };
- enum {
- INSTALLED_FILE_MSG=0,
- INSTALLED_MODULE_MSG,
- INSTALLER_SCRIPT_NAME,
- MY_PLATFORM_IS,
- USING_PLATFORM,
- PARSED_INSTALL_SCRIPT,
- EXEC_FILE_MSG,
- EXEC_SUCCESS,
- INSTALLATION_COMPLETE_MSG,
- USER_ABORT
- };
- static char *msgStrings[] = {
- "Installed file %s to %sn",
- "Installed module "%s" into module databasen",
- "Using installer script "%s"n",
- "Current platform is %sn",
- "Using installation parameters for platform %sn",
- "Successfully parsed installation scriptn",
- "Executing "%s"...n",
- ""%s" executed successfullyn",
- "nInstallation completed successfullyn",
- "nAborting...n"
- };
- /**************************************************************************
- * S t r i n g N o d e
- */
- typedef struct StringNode_str {
- char *str;
- struct StringNode_str* next;
- } StringNode;
- StringNode* StringNode_new()
- {
- StringNode* new_this;
- new_this = (StringNode*)malloc(sizeof(StringNode));
- new_this->str=NULL;
- new_this->next=NULL;
- return new_this;
- }
- void StringNode_delete(StringNode* s)
- {
- if(s->str) {
- PR_Free(s->str);
- s->str=NULL;
- }
- }
- /*************************************************************************
- * S t r i n g L i s t
- */
- typedef struct StringList_str {
- StringNode* head;
- StringNode* tail;
- } StringList;
- void StringList_new(StringList* list)
- {
- list->head=NULL;
- list->tail=NULL;
- }
- void StringList_delete(StringList* list)
- {
- StringNode *tmp;
- while(list->head) {
- tmp = list->head;
- list->head = list->head->next;
- StringNode_delete(tmp);
- }
- }
- void
- StringList_Append(StringList* list, char* str)
- {
- if(!str) {
- return;
- }
- if(!list->tail) {
- /* This is the first element */
- list->head = list->tail = StringNode_new();
- } else {
- list->tail->next = StringNode_new();
- list->tail = list->tail->next;
- }
- list->tail->str = PR_Strdup(str);
- list->tail->next = NULL; /* just to be sure */
- }
- /**************************************************************************
- *
- * P k 1 1 I n s t a l l _ S e t E r r o r H a n d l e r
- *
- * Sets the error handler to be used by the library. Returns the current
- * error handler function.
- */
- Pk11Install_ErrorHandler
- Pk11Install_SetErrorHandler(Pk11Install_ErrorHandler handler)
- {
- Pk11Install_ErrorHandler old;
- if(!errorHandlerLock) {
- errorHandlerLock = PR_NewLock();
- }
- PR_Lock(errorHandlerLock);
- old = errorHandler;
- errorHandler = handler;
- PR_Unlock(errorHandlerLock);
- return old;
- }
- /**************************************************************************
- *
- * P k 1 1 I n s t a l l _ I n i t
- *
- * Does initialization that otherwise would be done on the fly. Only
- * needs to be called by multithreaded apps, before they make any calls
- * to this library.
- */
- void
- Pk11Install_Init()
- {
- if(!errorHandlerLock) {
- errorHandlerLock = PR_NewLock();
- }
- }
- /**************************************************************************
- *
- * P k 1 1 I n s t a l l _ R e l e a s e
- *
- * Releases static data structures used by the library. Don't use the
- * library after calling this, unless you call Pk11Install_Init()
- * first. This function doesn't have to be called at all unless you're
- * really anal about freeing memory before your program exits.
- */
- void
- Pk11Install_Release()
- {
- if(errorHandlerLock) {
- PR_Free(errorHandlerLock);
- errorHandlerLock = NULL;
- }
- }
- /*************************************************************************
- *
- * e r r o r
- *
- * Takes an error code and its arguments, creates the error string,
- * and sends the string to the handler function if it exists.
- */
- #ifdef OSF1
- /* stdarg has already been pulled in from NSPR */
- #undef va_start
- #undef va_end
- #undef va_arg
- #include <varargs.h>
- #else
- #include <stdarg.h>
- #endif
- #ifdef OSF1
- static void
- error(long va_alist, ...)
- #else
- static void
- error(Pk11Install_Error errcode, ...)
- #endif
- {
- va_list ap;
- char *errstr;
- Pk11Install_ErrorHandler handler;
- if(!errorHandlerLock) {
- errorHandlerLock = PR_NewLock();
- }
- PR_Lock(errorHandlerLock);
- handler = errorHandler;
- PR_Unlock(errorHandlerLock);
- if(handler) {
- #ifdef OSF1
- va_start(ap);
- errstr = PR_vsmprintf(errorString[va_arg(ap, Pk11Install_Error)], ap);
- #else
- va_start(ap, errcode);
- errstr = PR_vsmprintf(errorString[errcode], ap);
- #endif
- handler(errstr);
- PR_smprintf_free(errstr);
- va_end(ap);
- }
- }
- /*************************************************************************
- *
- * j a r _ c a l l b a c k
- */
- static int
- jar_callback(int status, JAR *foo, const char *bar, char *pathname,
- char *errortext) {
- char *string;
- string = PR_smprintf("JAR error %d: %s in file %sn", status, errortext,
- pathname);
- error(PK11_INSTALL_ERROR_STRING, string);
- PR_smprintf_free(string);
- return 0;
- }
-
- /*************************************************************************
- *
- * P k 1 1 I n s t a l l _ D o I n s t a l l
- *
- * jarFile is the path of a JAR in the PKCS #11 module JAR format.
- * installDir is the directory relative to which files will be
- * installed.
- */
- Pk11Install_Error
- Pk11Install_DoInstall(char *jarFile, const char *installDir,
- const char *tempDir, PRFileDesc *feedback, short force, PRBool noverify)
- {
- JAR *jar;
- char *installer;
- unsigned long installer_len;
- int status;
- Pk11Install_Error ret;
- PRBool made_temp_file;
- Pk11Install_Info installInfo;
- Pk11Install_Platform *platform;
- char* errMsg;
- char sysname[SYS_INFO_BUFFER_LENGTH], release[SYS_INFO_BUFFER_LENGTH],
- arch[SYS_INFO_BUFFER_LENGTH];
- char *myPlatform;
- jar=NULL;
- ret = PK11_INSTALL_UNSPECIFIED;
- made_temp_file=PR_FALSE;
- errMsg=NULL;
- Pk11Install_Info_init(&installInfo);
- /*
- printf("Inside DoInstall, jarFile=%s, installDir=%s, tempDir=%sn",
- jarFile, installDir, tempDir);
- */
- /*
- * Check out jarFile and installDir for validity
- */
- if( PR_Access(installDir, PR_ACCESS_EXISTS) != PR_SUCCESS ) {
- error(PK11_INSTALL_DIR_DOESNT_EXIST, installDir);
- return PK11_INSTALL_DIR_DOESNT_EXIST;
- }
- if(!tempDir) {
- tempDir = ".";
- }
- if( PR_Access(tempDir, PR_ACCESS_EXISTS) != PR_SUCCESS ) {
- error(PK11_INSTALL_DIR_DOESNT_EXIST, tempDir);
- return PK11_INSTALL_DIR_DOESNT_EXIST;
- }
- if( PR_Access(tempDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS ) {
- error(PK11_INSTALL_DIR_NOT_WRITEABLE, tempDir);
- return PK11_INSTALL_DIR_NOT_WRITEABLE;
- }
- if( (PR_Access(jarFile, PR_ACCESS_EXISTS) != PR_SUCCESS) ) {
- error(PK11_INSTALL_FILE_DOESNT_EXIST, jarFile);
- return PK11_INSTALL_FILE_DOESNT_EXIST;
- }
- if( PR_Access(jarFile, PR_ACCESS_READ_OK) != PR_SUCCESS ) {
- error(PK11_INSTALL_FILE_NOT_READABLE, jarFile);
- return PK11_INSTALL_FILE_NOT_READABLE;
- }
- /*
- * Extract the JAR file
- */
- jar = JAR_new();
- JAR_set_callback(JAR_CB_SIGNAL, jar, jar_callback);
- if(noverify) {
- status = JAR_pass_archive_unverified(jar, jarArchGuess, jarFile, "url");
- } else {
- status = JAR_pass_archive(jar, jarArchGuess, jarFile, "url");
- }
- if( (status < 0) || (jar->valid < 0) ) {
- if (status >= JAR_BASE && status <= JAR_BASE_END) {
- error(PK11_INSTALL_JAR_ERROR, jarFile, JAR_get_error(status));
- } else {
- error(PK11_INSTALL_JAR_ERROR, jarFile,
- mySECU_ErrorString((int16) PORT_GetError()) );
- }
- ret=PK11_INSTALL_JAR_ERROR;
- goto loser;
- }
- /*printf("passed the archiven");*/
- /*
- * Show the user security information, allow them to abort or continue
- */
- if( Pk11Install_UserVerifyJar(jar, PR_STDOUT,
- force?PR_FALSE:PR_TRUE) && !force) {
- if(feedback) {
- PR_fprintf(feedback, msgStrings[USER_ABORT]);
- }
- ret=PK11_INSTALL_USER_ABORT;
- goto loser;
- }
- /*
- * Get the name of the installation file
- */
- if( JAR_get_metainfo(jar, NULL, INSTALL_METAINFO_TAG, (void**)&installer,
- (unsigned long*)&installer_len) ) {
- error(PK11_INSTALL_NO_INSTALLER_SCRIPT);
- ret=PK11_INSTALL_NO_INSTALLER_SCRIPT;
- goto loser;
- }
- if(feedback) {
- PR_fprintf(feedback, msgStrings[INSTALLER_SCRIPT_NAME], installer);
- }
- /*
- * Extract the installation file
- */
- if( PR_Access(SCRIPT_TEMP_FILE, PR_ACCESS_EXISTS) == PR_SUCCESS) {
- if( PR_Delete(SCRIPT_TEMP_FILE) != PR_SUCCESS) {
- error(PK11_INSTALL_DELETE_TEMP_FILE, SCRIPT_TEMP_FILE);
- ret=PK11_INSTALL_DELETE_TEMP_FILE;
- goto loser;
- }
- }
- if(noverify) {
- status = JAR_extract(jar, installer, SCRIPT_TEMP_FILE);
- } else {
- status = JAR_verified_extract(jar, installer, SCRIPT_TEMP_FILE);
- }
- if(status) {
- if (status >= JAR_BASE && status <= JAR_BASE_END) {
- error(PK11_INSTALL_JAR_EXTRACT, installer, JAR_get_error(status));
- } else {
- error(PK11_INSTALL_JAR_EXTRACT, installer,
- mySECU_ErrorString((int16) PORT_GetError()) );
- }
- ret = PK11_INSTALL_JAR_EXTRACT;
- goto loser;
- } else {
- made_temp_file = PR_TRUE;
- }
- /*
- * Parse the installation file into a syntax tree
- */
- Pk11Install_FD = PR_Open(SCRIPT_TEMP_FILE, PR_RDONLY, 0);
- if(!Pk11Install_FD) {
- error(PK11_INSTALL_OPEN_SCRIPT_FILE, SCRIPT_TEMP_FILE);
- ret=PK11_INSTALL_OPEN_SCRIPT_FILE;
- goto loser;
- }
- if(Pk11Install_yyparse()) {
- error(PK11_INSTALL_SCRIPT_PARSE, installer,
- Pk11Install_yyerrstr ? Pk11Install_yyerrstr : "");
- ret=PK11_INSTALL_SCRIPT_PARSE;
- goto loser;
- }
- #if 0
- /* for debugging */
- Pk11Install_valueList->Print(0);
- #endif
- /*
- * From the syntax tree, build a semantic structure
- */
- errMsg = Pk11Install_Info_Generate(&installInfo,Pk11Install_valueList);
- if(errMsg) {
- error(PK11_INSTALL_SEMANTIC, errMsg);
- ret=PK11_INSTALL_SEMANTIC;
- goto loser;
- }
- #if 0
- installInfo.Print(0);
- #endif
- if(feedback) {
- PR_fprintf(feedback, msgStrings[PARSED_INSTALL_SCRIPT]);
- }
- /*
- * Figure out which platform to use
- */
- {
- sysname[0] = release[0] = arch[0] = ' ';
- if( (PR_GetSystemInfo(PR_SI_SYSNAME, sysname, SYS_INFO_BUFFER_LENGTH)
- != PR_SUCCESS) ||
- (PR_GetSystemInfo(PR_SI_RELEASE, release, SYS_INFO_BUFFER_LENGTH)
- != PR_SUCCESS) ||
- (PR_GetSystemInfo(PR_SI_ARCHITECTURE, arch, SYS_INFO_BUFFER_LENGTH)
- != PR_SUCCESS) ) {
- error(PK11_INSTALL_SYSINFO);
- ret=PK11_INSTALL_SYSINFO;
- goto loser;
- }
- myPlatform = PR_smprintf("%s:%s:%s", sysname, release, arch);
- platform = Pk11Install_Info_GetBestPlatform(&installInfo,myPlatform);
- if(!platform) {
- error(PK11_INSTALL_NO_PLATFORM, myPlatform);
- PR_smprintf_free(myPlatform);
- ret=PK11_INSTALL_NO_PLATFORM;
- goto loser;
- }
- if(feedback) {
- PR_fprintf(feedback, msgStrings[MY_PLATFORM_IS], myPlatform);
- PR_fprintf(feedback, msgStrings[USING_PLATFORM],
- Pk11Install_PlatformName_GetString(&platform->name));
- }
- PR_smprintf_free(myPlatform);
- }
- /* Run the install for that platform */
- ret = DoInstall(jar, installDir, tempDir, platform, feedback, noverify);
- if(ret) {
- goto loser;
- }
- ret = PK11_INSTALL_SUCCESS;
- loser:
- if(Pk11Install_valueList) {
- Pk11Install_ValueList_delete(Pk11Install_valueList);
- PR_Free(Pk11Install_valueList);
- Pk11Install_valueList = NULL;
- }
- if(jar) {
- JAR_destroy(jar);
- }
- if(made_temp_file) {
- PR_Delete(SCRIPT_TEMP_FILE);
- }
- if(errMsg) {
- PR_smprintf_free(errMsg);
- }
- return ret;
- }
- /*
- /////////////////////////////////////////////////////////////////////////
- // actually run the installation, copying files to and fro
- */
- static Pk11Install_Error
- DoInstall(JAR *jar, const char *installDir, const char *tempDir,
- Pk11Install_Platform *platform, PRFileDesc *feedback, PRBool noverify)
- {
- Pk11Install_File *file;
- Pk11Install_Error ret;
- char *reldir;
- char *dest;
- char *modDest;
- char *cp;
- int i;
- int status;
- char *tempname, *temp;
- StringList executables;
- StringNode *execNode;
- PRProcessAttr *attr;
- PRProcess *proc;
- char *argv[2];
- char *envp[1];
- int errcode;
- ret=PK11_INSTALL_UNSPECIFIED;
- reldir=NULL;
- dest=NULL;
- modDest=NULL;
- tempname=NULL;
- StringList_new(&executables);
- /*
- // Create Temporary directory
- */
- tempname = PR_smprintf("%s/%s", tempDir, TEMPORARY_DIRECTORY_NAME);
- if( PR_Access(tempname, PR_ACCESS_EXISTS)==PR_SUCCESS ) {
- /* Left over from previous run? Delete it. */
- rm_dash_r(tempname);
- }
- if(PR_MkDir(tempname, 0700) != PR_SUCCESS) {
- error(PK11_INSTALL_CREATE_DIR, tempname);
- ret = PK11_INSTALL_CREATE_DIR;
- goto loser;
- }
- /*
- // Install all the files
- */
- for(i=0; i < platform->numFiles; i++) {
- file = &platform->files[i];
- if(file->relativePath) {
- PRBool foundMarker = PR_FALSE;
- reldir = PR_Strdup(file->relativePath);
- /* Replace all the markers with the directories for which they stand */
- while(1) {
- if( (cp=PL_strcasestr(reldir, ROOT_MARKER)) ) {
- /* Has a %root% marker */
- *cp = ' ';
- temp = PR_smprintf("%s%s%s", reldir, installDir,
- cp+strlen(ROOT_MARKER));
- PR_Free(reldir);
- reldir = temp;
- foundMarker = PR_TRUE;
- } else if( (cp = PL_strcasestr(reldir, TEMP_MARKER)) ) {
- /* Has a %temp% marker */
- *cp = ' ';
- temp = PR_smprintf("%s%s%s", reldir, tempname,
- cp+strlen(TEMP_MARKER));
- PR_Free(reldir);
- reldir = temp;
- foundMarker = PR_TRUE;
- } else {
- break;
- }
- }
- if(!foundMarker) {
- /* Has no markers...this isn't really a relative directory */
- error(PK11_INSTALL_BOGUS_REL_DIR, file->relativePath);
- ret = PK11_INSTALL_BOGUS_REL_DIR;
- goto loser;
- }
- dest = reldir;
- reldir = NULL;
- } else if(file->absolutePath) {
- dest = PR_Strdup(file->absolutePath);
- }
- /* Remember if this is the module file, we'll need to add it later */
- if(i == platform->modFile) {
- modDest = PR_Strdup(dest);
- }
- /* Remember is this is an executable, we'll need to run it later */
- if(file->executable) {
- StringList_Append(&executables,dest);
- /*executables.Append(dest);*/
- }
- /* Make sure the directory we are targetting exists */
- if( make_dirs(dest, file->permissions) ) {
- ret=PK11_INSTALL_CREATE_DIR;
- goto loser;
- }
- /* Actually extract the file onto the filesystem */
- if(noverify) {
- status = JAR_extract(jar, (char*)file->jarPath, dest);
- } else {
- status = JAR_verified_extract(jar, (char*)file->jarPath, dest);
- }
- if(status) {
- if (status >= JAR_BASE && status <= JAR_BASE_END) {
- error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
- JAR_get_error(status));
- } else {
- error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
- mySECU_ErrorString((int16) PORT_GetError()) );
- }
- ret=PK11_INSTALL_JAR_EXTRACT;
- goto loser;
- }
- if(feedback) {
- PR_fprintf(feedback, msgStrings[INSTALLED_FILE_MSG],
- file->jarPath, dest);
- }
- /* no NSPR command to change permissions? */
- #ifdef XP_UNIX
- chmod(dest, file->permissions);
- #endif
- /* Memory clean-up tasks */
- if(reldir) {
- PR_Free(reldir);
- reldir = NULL;
- }
- if(dest) {
- PR_Free(dest);
- dest = NULL;
- }
- }
- /* Make sure we found the module file */
- if(!modDest) {
- /* Internal problem here, since every platform is supposed to have
- a module file */
- error(PK11_INSTALL_NO_MOD_FILE, platform->moduleName);
- ret=PK11_INSTALL_NO_MOD_FILE;
- goto loser;
- }
- /*
- // Execute any executable files
- */
- {
- argv[1] = NULL;
- envp[0] = NULL;
- for(execNode = executables.head; execNode; execNode = execNode->next) {
- attr = PR_NewProcessAttr();
- argv[0] = PR_Strdup(execNode->str);
- /* Announce our intentions */
- if(feedback) {
- PR_fprintf(feedback, msgStrings[EXEC_FILE_MSG], execNode->str);
- }
- /* start the process */
- if( !(proc=PR_CreateProcess(execNode->str, argv, envp, attr)) ) {
- PR_Free(argv[0]);
- PR_DestroyProcessAttr(attr);
- error(PK11_INSTALL_EXEC_FILE, execNode->str);
- ret=PK11_INSTALL_EXEC_FILE;
- goto loser;
- }
- /* wait for it to finish */
- if( PR_WaitProcess(proc, &errcode) != PR_SUCCESS) {
- PR_Free(argv[0]);
- PR_DestroyProcessAttr(attr);
- error(PK11_INSTALL_WAIT_PROCESS, execNode->str);
- ret=PK11_INSTALL_WAIT_PROCESS;
- goto loser;
- }
- /* What happened? */
- if(errcode) {
- /* process returned an error */
- error(PK11_INSTALL_PROC_ERROR, execNode->str, errcode);
- } else if(feedback) {
- /* process ran successfully */
- PR_fprintf(feedback, msgStrings[EXEC_SUCCESS], execNode->str);
- }
- PR_Free(argv[0]);
- PR_DestroyProcessAttr(attr);
- }
- }
- /*
- // Add the module
- */
- status = Pk11Install_AddNewModule((char*)platform->moduleName,
- (char*)modDest, platform->mechFlags, platform->cipherFlags );
- if(status != SECSuccess) {
- error(PK11_INSTALL_ADD_MODULE, platform->moduleName);
- ret=PK11_INSTALL_ADD_MODULE;
- goto loser;
- }
- if(feedback) {
- PR_fprintf(feedback, msgStrings[INSTALLED_MODULE_MSG],
- platform->moduleName);
- }
- if(feedback) {
- PR_fprintf(feedback, msgStrings[INSTALLATION_COMPLETE_MSG]);
- }
- ret = PK11_INSTALL_SUCCESS;
- loser:
- if(reldir) {
- PR_Free(reldir);
- }
- if(dest) {
- PR_Free(dest);
- }
- if(modDest) {
- PR_Free(modDest);
- }
- if(tempname) {
- PRFileInfo info;
- if(PR_GetFileInfo(tempname, &info) == PR_SUCCESS) {
- if((info.type == PR_FILE_DIRECTORY)) {
- /* Recursively remove temporary directory */
- if(rm_dash_r(tempname)) {
- error(PK11_INSTALL_REMOVE_DIR,
- tempname);
- ret=PK11_INSTALL_REMOVE_DIR;
- }
-
- }
- }
- PR_Free(tempname);
- }
- StringList_delete(&executables);
- return ret;
- }
- /*
- //////////////////////////////////////////////////////////////////////////
- */
- static char*
- PR_Strdup(const char* str)
- {
- char *tmp = (char*) PR_Malloc(strlen(str)+1);
- strcpy(tmp, str);
- return tmp;
- }
- /*
- * r m _ d a s h _ r
- *
- * Remove a file, or a directory recursively.
- *
- */
- static int
- rm_dash_r (char *path)
- {
- PRDir *dir;
- PRDirEntry *entry;
- PRFileInfo fileinfo;
- char filename[240];
- if(PR_GetFileInfo(path, &fileinfo) != PR_SUCCESS) {
- /*fprintf(stderr, "Error: Unable to access %sn", filename);*/
- return -1;
- }
- if(fileinfo.type == PR_FILE_DIRECTORY) {
- dir = PR_OpenDir(path);
- if(!dir) {
- return -1;
- }
- /* Recursively delete all entries in the directory */
- while((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
- sprintf(filename, "%s/%s", path, entry->name);
- if(rm_dash_r(filename)) return -1;
- }
- if(PR_CloseDir(dir) != PR_SUCCESS) {
- return -1;
- }
- /* Delete the directory itself */
- if(PR_RmDir(path) != PR_SUCCESS) {
- return -1;
- }
- } else {
- if(PR_Delete(path) != PR_SUCCESS) {
- return -1;
- }
- }
- return 0;
- }
- /***************************************************************************
- *
- * m a k e _ d i r s
- *
- * Ensure that the directory portion of the path exists. This may require
- * making the directory, and its parent, and its parent's parent, etc.
- */
- static int
- make_dirs(char *path, int file_perms)
- {
- char *Path;
- char *start;
- char *sep;
- int ret = 0;
- PRFileInfo info;
- if(!path) {
- return 0;
- }
- Path = PR_Strdup(path);
- start = strpbrk(Path, "/\");
- if(!start) {
- return 0;
- }
- start++; /* start right after first slash */
- /* Each time through the loop add one more directory. */
- while( (sep=strpbrk(start, "/\")) ) {
- *sep = ' ';
- if( PR_GetFileInfo(Path, &info) != PR_SUCCESS) {
- /* No such dir, we have to create it */
- if( PR_MkDir(Path, dir_perms(file_perms)) != PR_SUCCESS) {
- error(PK11_INSTALL_CREATE_DIR, Path);
- ret = PK11_INSTALL_CREATE_DIR;
- goto loser;
- }
- } else {
- /* something exists by this name, make sure it's a directory */
- if( info.type != PR_FILE_DIRECTORY ) {
- error(PK11_INSTALL_CREATE_DIR, Path);
- ret = PK11_INSTALL_CREATE_DIR;
- goto loser;
- }
- }
- /* If this is the lowest directory level, make sure it is writeable */
- if(!strpbrk(sep+1, "/\")) {
- if( PR_Access(Path, PR_ACCESS_WRITE_OK)!=PR_SUCCESS) {
- error(PK11_INSTALL_DIR_NOT_WRITEABLE, Path);
- ret = PK11_INSTALL_DIR_NOT_WRITEABLE;
- goto loser;
- }
- }
- start = sep+1; /* start after the next slash */
- *sep = '/';
- }
- loser:
- PR_Free(Path);
- return ret;
- }
- /*************************************************************************
- * d i r _ p e r m s
- *
- * Guesses the desired permissions on a directory based on the permissions
- * of a file that will be stored in it. Give read, write, and
- * execute to the owner (so we can create the file), read and
- * execute to anyone who has read permissions on the file, and write
- * to anyone who has write permissions on the file.
- */
- static int
- dir_perms(int perms)
- {
- int ret = 0;
- /* owner */
- ret |= 0700;
- /* group */
- if(perms & 0040) {
- /* read on the file -> read and execute on the directory */
- ret |= 0050;
- }
- if(perms & 0020) {
- /* write on the file -> write on the directory */
- ret |= 0020;
- }
- /* others */
- if(perms & 0004) {
- /* read on the file -> read and execute on the directory */
- ret |= 0005;
- }
- if(perms & 0002) {
- /* write on the file -> write on the directory */
- ret |= 0002;
- }
- return ret;
- }