install.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 980 行 · 第 1/2 页
C
980 行
#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] = '\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_ErrorDoInstall(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 = '\0'; 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 = '\0'; 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 intrm_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 %s\n", 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 intmake_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 = '\0'; 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 intdir_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;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?