diff --git a/adaptive_compress.c b/adaptive_compress.c index 27ef558..01b8dd3 100644 --- a/adaptive_compress.c +++ b/adaptive_compress.c @@ -345,7 +345,13 @@ adapt_decompress(void *src, uint64_t srclen, void *dst, return (bzip2_decompress(src, srclen, dst, dstlen, level, chdr, btype, NULL)); } else if (cmp_flags == ADAPT_COMPRESS_PPMD) { - return (ppmd_decompress(src, srclen, dst, dstlen, level, chdr, btype, adat->ppmd_data)); + int rv; + rv = ppmd_alloc(adat->ppmd_data); + if (rv < 0) + return (rv); + rv = ppmd_decompress(src, srclen, dst, dstlen, level, chdr, btype, adat->ppmd_data); + ppmd_free(adat->ppmd_data); + return (rv); } else if (cmp_flags == ADAPT_COMPRESS_BSC) { #ifdef ENABLE_PC_LIBBSC diff --git a/archive/pc_archive.c b/archive/pc_archive.c index d118d1d..042e5f3 100644 --- a/archive/pc_archive.c +++ b/archive/pc_archive.c @@ -375,6 +375,7 @@ read_next_path(pc_ctx_t *pctx, char *fpath, char **namechars, int *fpathlen) short namelen; ssize_t rbytes; uchar_t *buf; + int n; if (pctx->enable_archive_sort) { member_entry_t *mem1, *mem2; @@ -436,7 +437,7 @@ read_next_path(pc_ctx_t *pctx, char *fpath, char **namechars, int *fpathlen) * new mmap. */ if (pctx->temp_mmap_len > 0) { - int retried, n; + int retried; if (pctx->temp_file_pos < pctx->temp_mmap_pos || pctx->temp_file_pos - pctx->temp_mmap_pos > pctx->temp_mmap_len || @@ -508,6 +509,13 @@ do_mmap: return (-1); } fpath[namelen] = '\0'; + *fpathlen = namelen; + + n = namelen-1; + while (fpath[n] == '/' && n > 0) n--; + while (fpath[n] != '/' && fpath[n] != '\\' && n > 0) n--; + *namechars = &fpath[n+1]; + printf("%s\n", fpath); } return (rbytes); } @@ -788,11 +796,16 @@ setup_archiver(pc_ctx_t *pctx, struct stat *sbuf) creat_write_callback, creat_close_callback); pctx->archive_ctx = arc; pctx->archive_members_fd = fd; - pctx->temp_mmap_len = TEMP_MMAP_SIZE; - pctx->temp_mmap_buf = mmap(NULL, pctx->temp_mmap_len, PROT_READ, - MAP_SHARED, pctx->archive_members_fd, 0); - if (pctx->temp_mmap_buf == NULL) { - log_msg(LOG_WARN, 1, "Unable to mmap pathlist file, switching to read()."); + if (pctx->enable_archive_sort) { + pctx->temp_mmap_len = TEMP_MMAP_SIZE; + pctx->temp_mmap_buf = mmap(NULL, pctx->temp_mmap_len, PROT_READ, + MAP_SHARED, pctx->archive_members_fd, 0); + if (pctx->temp_mmap_buf == NULL) { + log_msg(LOG_WARN, 1, "Unable to mmap pathlist file, switching to read()."); + pctx->temp_mmap_len = 0; + } + } else { + pctx->temp_mmap_buf = NULL; pctx->temp_mmap_len = 0; } pctx->temp_mmap_pos = 0; @@ -1235,11 +1248,6 @@ extractor_thread_func(void *dat) { got_cwd = 0; } - if (chdir(pctx->to_filename) == -1) { - log_msg(LOG_ERR, 1, "Cannot change to dir: %s", pctx->to_filename); - goto done; - } - ctr = 1; awd = archive_write_disk_new(); archive_write_disk_set_options(awd, flags); @@ -1247,6 +1255,15 @@ extractor_thread_func(void *dat) { arc = (struct archive *)(pctx->archive_ctx); archive_read_open(arc, pctx, arc_open_callback, extract_read_callback, extract_close_callback); + /* + * Change directory after opening the archive, otherwise archive_read_open() can fail + * for relative paths. + */ + if (chdir(pctx->to_filename) == -1) { + log_msg(LOG_ERR, 1, "Cannot change to dir: %s", pctx->to_filename); + goto done; + } + /* * Read archive entries and extract to disk. */ diff --git a/pcompress.c b/pcompress.c index 6eed6e3..a53f6b8 100644 --- a/pcompress.c +++ b/pcompress.c @@ -834,11 +834,16 @@ start_decompress(pc_ctx_t *pctx, const char *filename, char *to_filename) err = 1; goto uncomp_done; } - if (mkdir(to_filename, S_IRUSR|S_IWUSR) == -1) { + if (mkdir(to_filename, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) == -1) { log_msg(LOG_ERR, 1, "Unable to create target directory %s.", to_filename); err = 1; goto uncomp_done; } + if (stat(to_filename, &sbuf) == -1) { + log_msg(LOG_ERR, 1, "Unable to correctly create target directory %s.", to_filename); + err = 1; + goto uncomp_done; + } } if (!S_ISDIR(sbuf.st_mode)) { log_msg(LOG_ERR, 0, "Target path is not a directory.", to_filename); @@ -3039,7 +3044,7 @@ init_pc_context(pc_ctx_t *pctx, int argc, char *argv[]) * unless it is explicitly disabled via '-n'. */ if (pctx->enable_archive_sort != -1 && pctx->do_compress) { - if ((memcmp(pctx->algo, "lz4", 3) == 0 && pctx->level > 2) || pctx->level > 6) + if ((memcmp(pctx->algo, "lz4", 3) == 0 && pctx->level > 1) || pctx->level > 4) pctx->enable_archive_sort = 1; } else { pctx->enable_archive_sort = 0;