/* * extract from the archive * and copy to the filesystem * relative to the directory the archive's in */ int extract2fs(ARCHIVE_STATUS *status, TOC *ptoc) { FILE *out; unsigned char *data = extract(status, ptoc); if (pyi_create_temp_path(status) == -1){ return -1; } out = pyi_open_target(status->temppath, ptoc->name); if (out == NULL) { FATALERROR("%s could not be extracted!\n", ptoc->name); return -1; } else { fwrite(data, ntohl(ptoc->ulen), 1, out); #ifndef WIN32 fchmod(fileno(out), S_IRUSR | S_IWUSR | S_IXUSR); #endif fclose(out); } free(data); return 0; }
/* * Look for the archive identified by path into the ARCHIVE_STATUS pool archive_pool. * If the archive is found, a pointer to the associated ARCHIVE_STATUS is returned * otherwise the needed archive is opened and added to the pool and then returned. * If an error occurs, returns NULL. * * Having several archives is useful for sharing binary dependencies with several * executables (multipackage feature). */ static ARCHIVE_STATUS * _get_archive(ARCHIVE_STATUS *archive_pool[], const char *path) { ARCHIVE_STATUS *archive = NULL; int index = 0; int SELF = 0; VS("LOADER: Getting file from archive.\n"); if (pyi_create_temp_path(archive_pool[SELF]) == -1) { return NULL; } for (index = 1; archive_pool[index] != NULL; index++) { if (strcmp(archive_pool[index]->archivename, path) == 0) { VS("LOADER: Archive found: %s\n", path); return archive_pool[index]; } VS("LOADER: Checking next archive in the list...\n"); } archive = (ARCHIVE_STATUS *) malloc(sizeof(ARCHIVE_STATUS)); if (archive == NULL) { FATAL_PERROR("malloc", "Error allocating memory for status\n"); return NULL; } strncpy(archive->archivename, path, PATH_MAX); strncpy(archive->homepath, archive_pool[SELF]->homepath, PATH_MAX); strncpy(archive->temppath, archive_pool[SELF]->temppath, PATH_MAX); if (archive->archivename[PATH_MAX-1] != '\0' || archive->homepath[PATH_MAX-1] != '\0' || archive->temppath[PATH_MAX-1] != '\0') { FATALERROR("Archive path exceeds PATH_MAX\n"); free(archive); return NULL; } /* * Setting this flag prevents creating another temp directory and * the directory from the main archive status is used. */ archive->has_temp_directory = archive_pool[SELF]->has_temp_directory; if (pyi_arch_open(archive)) { FATAL_PERROR("malloc", "Error opening archive %s\n", path); free(archive); return NULL; } archive_pool[index] = archive; return archive; }
/* Copy the dependencies file from a directory to the tempdir */ static int copyDependencyFromDir(ARCHIVE_STATUS *status, const char *srcpath, const char *filename) { if (pyi_create_temp_path(status) == -1){ return -1; } VS("LOADER: Coping file %s to %s\n", srcpath, status->temppath); if (pyi_copy_file(srcpath, status->temppath, filename) == -1) { return -1; } return 0; }
/* Look for the archive identified by path into the ARCHIVE_STATUS pool status_list. * If the archive is found, a pointer to the associated ARCHIVE_STATUS is returned * otherwise the needed archive is opened and added to the pool and then returned. * If an error occurs, returns NULL. */ static ARCHIVE_STATUS *get_archive(ARCHIVE_STATUS *status_list[], const char *path) { ARCHIVE_STATUS *status = NULL; int i = 0; VS("Getting file from archive.\n"); if (pyi_create_temp_path(status_list[SELF]) == -1){ return NULL; } for (i = 1; status_list[i] != NULL; i++){ if (strcmp(status_list[i]->archivename, path) == 0) { VS("Archive found: %s\n", path); return status_list[i]; } VS("Checking next archive in the list...\n"); } if ((status = (ARCHIVE_STATUS *) calloc(1, sizeof(ARCHIVE_STATUS))) == NULL) { FATALERROR("Error allocating memory for status\n"); return NULL; } strcpy(status->archivename, path); strcpy(status->homepath, status_list[SELF]->homepath); strcpy(status->temppath, status_list[SELF]->temppath); #ifdef WIN32 strcpy(status->homepathraw, status_list[SELF]->homepathraw); strcpy(status->temppathraw, status_list[SELF]->temppathraw); #endif if (openArchive(status)) { FATALERROR("Error openning archive %s\n", path); free(status); return NULL; } status_list[i] = status; return status; }