libarchive 3.0.3.1 → 3.0.3.2
raw patch · 11 files changed
+513/−112 lines, 11 filesdep +bzlibdep +exceptionsdep +lzma-staticdep −hspec-coredep ~bytestringdep ~directorydep ~filepathnew-component:exe:archive
Dependencies added: bzlib, exceptions, lzma-static, time, zlib
Dependencies removed: hspec-core
Dependency ranges changed: bytestring, directory, filepath
Files
- CHANGELOG.md +4/−0
- c/archive.h +2/−2
- c/archive_entry.h +1/−1
- c/archive_read_support_format_rar5.c +93/−52
- c/archive_write_disk_posix.c +108/−21
- c/autoconf-darwin/config.h +8/−8
- c/autoconf-freebsd/config.h +8/−8
- c/autoconf-linux/config.h +8/−8
- c/autoconf-windows/config.h +8/−8
- exe/Main.hs +247/−0
- libarchive.cabal +26/−4
CHANGELOG.md view
@@ -1,5 +1,9 @@ # libarchive +# 3.0.3.2++ * Bundled libarchive 3.5.3+ # 3.0.3.1 * Properly export functions from libarchive 3.5.2.
c/archive.h view
@@ -36,7 +36,7 @@ * assert that ARCHIVE_VERSION_NUMBER >= 2012108. */ /* Note: Compiler will complain if this does not match archive_entry.h! */-#define ARCHIVE_VERSION_NUMBER 3005002+#define ARCHIVE_VERSION_NUMBER 3005003 #include <sys/stat.h> #include <stddef.h> /* for wchar_t */@@ -155,7 +155,7 @@ /* * Textual name/version of the library, useful for version displays. */-#define ARCHIVE_VERSION_ONLY_STRING "3.5.2"+#define ARCHIVE_VERSION_ONLY_STRING "3.5.3" #define ARCHIVE_VERSION_STRING "libarchive " ARCHIVE_VERSION_ONLY_STRING __LA_DECL const char * archive_version_string(void);
c/archive_entry.h view
@@ -30,7 +30,7 @@ #define ARCHIVE_ENTRY_H_INCLUDED /* Note: Compiler will complain if this does not match archive.h! */-#define ARCHIVE_VERSION_NUMBER 3005002+#define ARCHIVE_VERSION_NUMBER 3005003 /* * Note: archive_entry.h is for use outside of libarchive; the
c/archive_read_support_format_rar5.c view
@@ -1012,7 +1012,16 @@ return ret; } -static int read_bits_32(struct rar5* rar, const uint8_t* p, uint32_t* value) {+static int read_bits_32(struct archive_read* a, struct rar5* rar,+ const uint8_t* p, uint32_t* value)+{+ if(rar->bits.in_addr >= rar->cstate.cur_block_size) {+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_PROGRAMMER,+ "Premature end of stream during extraction of data (#1)");+ return ARCHIVE_FATAL;+ }+ uint32_t bits = ((uint32_t) p[rar->bits.in_addr]) << 24; bits |= p[rar->bits.in_addr + 1] << 16; bits |= p[rar->bits.in_addr + 2] << 8;@@ -1023,7 +1032,16 @@ return ARCHIVE_OK; } -static int read_bits_16(struct rar5* rar, const uint8_t* p, uint16_t* value) {+static int read_bits_16(struct archive_read* a, struct rar5* rar,+ const uint8_t* p, uint16_t* value)+{+ if(rar->bits.in_addr >= rar->cstate.cur_block_size) {+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_PROGRAMMER,+ "Premature end of stream during extraction of data (#2)");+ return ARCHIVE_FATAL;+ }+ int bits = (int) ((uint32_t) p[rar->bits.in_addr]) << 16; bits |= (int) p[rar->bits.in_addr + 1] << 8; bits |= (int) p[rar->bits.in_addr + 2];@@ -1039,8 +1057,8 @@ } /* n = up to 16 */-static int read_consume_bits(struct rar5* rar, const uint8_t* p, int n,- int* value)+static int read_consume_bits(struct archive_read* a, struct rar5* rar,+ const uint8_t* p, int n, int* value) { uint16_t v; int ret, num;@@ -1051,7 +1069,7 @@ return ARCHIVE_FATAL; } - ret = read_bits_16(rar, p, &v);+ ret = read_bits_16(a, rar, p, &v); if(ret != ARCHIVE_OK) return ret; @@ -1712,14 +1730,29 @@ } } - /* If we're currently switching volumes, ignore the new definition of- * window_size. */- if(rar->cstate.switch_multivolume == 0) {- /* Values up to 64M should fit into ssize_t on every- * architecture. */- rar->cstate.window_size = (ssize_t) window_size;+ if(rar->cstate.window_size < (ssize_t) window_size &&+ rar->cstate.window_buf)+ {+ /* If window_buf has been allocated before, reallocate it, so+ * that its size will match new window_size. */++ uint8_t* new_window_buf =+ realloc(rar->cstate.window_buf, window_size);++ if(!new_window_buf) {+ archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,+ "Not enough memory when trying to realloc the window "+ "buffer.");+ return ARCHIVE_FATAL;+ }++ rar->cstate.window_buf = new_window_buf; } + /* Values up to 64M should fit into ssize_t on every+ * architecture. */+ rar->cstate.window_size = (ssize_t) window_size;+ if(rar->file.solid > 0 && rar->file.solid_window_size == 0) { /* Solid files have to have the same window_size across whole archive. Remember the window_size parameter@@ -2425,13 +2458,13 @@ static int decode_number(struct archive_read* a, struct decode_table* table, const uint8_t* p, uint16_t* num) {- int i, bits, dist;+ int i, bits, dist, ret; uint16_t bitfield; uint32_t pos; struct rar5* rar = get_context(a); - if(ARCHIVE_OK != read_bits_16(rar, p, &bitfield)) {- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &bitfield))) {+ return ret; } bitfield &= 0xfffe;@@ -2537,14 +2570,6 @@ for(i = 0; i < HUFF_TABLE_SIZE;) { uint16_t num; - if((rar->bits.in_addr + 6) >= rar->cstate.cur_block_size) {- /* Truncated data, can't continue. */- archive_set_error(&a->archive,- ARCHIVE_ERRNO_FILE_FORMAT,- "Truncated data in huffman tables (#2)");- return ARCHIVE_FATAL;- }- ret = decode_number(a, &rar->cstate.bd, p, &num); if(ret != ARCHIVE_OK) { archive_set_error(&a->archive,@@ -2561,8 +2586,8 @@ /* 16..17: repeat previous code */ uint16_t n; - if(ARCHIVE_OK != read_bits_16(rar, p, &n))- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n)))+ return ret; if(num == 16) { n >>= 13;@@ -2590,8 +2615,8 @@ /* other codes: fill with zeroes `n` times */ uint16_t n; - if(ARCHIVE_OK != read_bits_16(rar, p, &n))- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &n)))+ return ret; if(num == 18) { n >>= 13;@@ -2707,22 +2732,22 @@ } /* Convenience function used during filter processing. */-static int parse_filter_data(struct rar5* rar, const uint8_t* p,- uint32_t* filter_data)+static int parse_filter_data(struct archive_read* a, struct rar5* rar,+ const uint8_t* p, uint32_t* filter_data) {- int i, bytes;+ int i, bytes, ret; uint32_t data = 0; - if(ARCHIVE_OK != read_consume_bits(rar, p, 2, &bytes))- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = read_consume_bits(a, rar, p, 2, &bytes)))+ return ret; bytes++; for(i = 0; i < bytes; i++) { uint16_t byte; - if(ARCHIVE_OK != read_bits_16(rar, p, &byte)) {- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = read_bits_16(a, rar, p, &byte))) {+ return ret; } /* Cast to uint32_t will ensure the shift operation will not@@ -2765,16 +2790,17 @@ uint16_t filter_type; struct filter_info* filt = NULL; struct rar5* rar = get_context(ar);+ int ret; /* Read the parameters from the input stream. */- if(ARCHIVE_OK != parse_filter_data(rar, p, &block_start))- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_start)))+ return ret; - if(ARCHIVE_OK != parse_filter_data(rar, p, &block_length))- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = parse_filter_data(ar, rar, p, &block_length)))+ return ret; - if(ARCHIVE_OK != read_bits_16(rar, p, &filter_type))- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = read_bits_16(ar, rar, p, &filter_type)))+ return ret; filter_type >>= 13; skip_bits(rar, 3);@@ -2814,8 +2840,8 @@ if(filter_type == FILTER_DELTA) { int channels; - if(ARCHIVE_OK != read_consume_bits(rar, p, 5, &channels))- return ARCHIVE_EOF;+ if(ARCHIVE_OK != (ret = read_consume_bits(ar, rar, p, 5, &channels)))+ return ret; filt->channels = channels + 1; }@@ -2823,10 +2849,11 @@ return ARCHIVE_OK; } -static int decode_code_length(struct rar5* rar, const uint8_t* p,- uint16_t code)+static int decode_code_length(struct archive_read* a, struct rar5* rar,+ const uint8_t* p, uint16_t code) { int lbits, length = 2;+ if(code < 8) { lbits = 0; length += code;@@ -2838,7 +2865,7 @@ if(lbits > 0) { int add; - if(ARCHIVE_OK != read_consume_bits(rar, p, lbits, &add))+ if(ARCHIVE_OK != read_consume_bits(a, rar, p, lbits, &add)) return -1; length += add;@@ -2933,7 +2960,7 @@ continue; } else if(num >= 262) { uint16_t dist_slot;- int len = decode_code_length(rar, p, num - 262),+ int len = decode_code_length(a, rar, p, num - 262), dbits, dist = 1; @@ -2975,12 +3002,12 @@ uint16_t low_dist; if(dbits > 4) {- if(ARCHIVE_OK != read_bits_32(- rar, p, &add)) {+ if(ARCHIVE_OK != (ret = read_bits_32(+ a, rar, p, &add))) { /* Return EOF if we * can't read more * data. */- return ARCHIVE_EOF;+ return ret; } skip_bits(rar, dbits - 4);@@ -3015,11 +3042,11 @@ /* dbits is one of [0,1,2,3] */ int add; - if(ARCHIVE_OK != read_consume_bits(rar,- p, dbits, &add)) {+ if(ARCHIVE_OK != (ret = read_consume_bits(a, rar,+ p, dbits, &add))) { /* Return EOF if we can't read * more data. */- return ARCHIVE_EOF;+ return ret; } dist += add;@@ -3076,7 +3103,11 @@ return ARCHIVE_FATAL; } - len = decode_code_length(rar, p, len_slot);+ len = decode_code_length(a, rar, p, len_slot);+ if (len == -1) {+ return ARCHIVE_FATAL;+ }+ rar->cstate.last_len = len; if(ARCHIVE_OK != copy_string(a, len, dist))@@ -3598,6 +3629,16 @@ } rar->cstate.initialized = 1;+ }++ /* Don't allow extraction if window_size is invalid. */+ if(rar->cstate.window_size == 0) {+ archive_set_error(&a->archive,+ ARCHIVE_ERRNO_FILE_FORMAT,+ "Invalid window size declaration in this file");++ /* This should never happen in valid files. */+ return ARCHIVE_FATAL; } if(rar->cstate.all_filters_applied == 1) {
c/archive_write_disk_posix.c view
@@ -173,6 +173,7 @@ struct fixup_entry *next; struct archive_acl acl; mode_t mode;+ __LA_MODE_T filetype; int64_t atime; int64_t birthtime; int64_t mtime;@@ -357,6 +358,7 @@ static int la_opendirat(int, const char *); static int la_mktemp(struct archive_write_disk *);+static int la_verify_filetype(mode_t, __LA_MODE_T); static void fsobj_error(int *, struct archive_string *, int, const char *, const char *); static int check_symlinks_fsobj(char *, int *, struct archive_string *,@@ -465,6 +467,39 @@ } static int+la_verify_filetype(mode_t mode, __LA_MODE_T filetype) {+ int ret = 0;++ switch (filetype) {+ case AE_IFREG:+ ret = (S_ISREG(mode));+ break;+ case AE_IFDIR:+ ret = (S_ISDIR(mode));+ break;+ case AE_IFLNK:+ ret = (S_ISLNK(mode));+ break;+ case AE_IFSOCK:+ ret = (S_ISSOCK(mode));+ break;+ case AE_IFCHR:+ ret = (S_ISCHR(mode));+ break;+ case AE_IFBLK:+ ret = (S_ISBLK(mode));+ break;+ case AE_IFIFO:+ ret = (S_ISFIFO(mode));+ break;+ default:+ break;+ }++ return (ret);+}++static int lazy_stat(struct archive_write_disk *a) { if (a->pst != NULL) {@@ -822,6 +857,7 @@ fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL);+ fe->filetype = archive_entry_filetype(entry); fe->fixup |= TODO_MODE_BASE; fe->mode = a->mode; }@@ -832,6 +868,7 @@ fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL);+ fe->filetype = archive_entry_filetype(entry); fe->mode = a->mode; fe->fixup |= TODO_TIMES; if (archive_entry_atime_is_set(entry)) {@@ -865,6 +902,7 @@ fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL);+ fe->filetype = archive_entry_filetype(entry); fe->fixup |= TODO_ACLS; archive_acl_copy(&fe->acl, archive_entry_acl(entry)); }@@ -877,6 +915,7 @@ fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL);+ fe->filetype = archive_entry_filetype(entry); fe->mac_metadata = malloc(metadata_size); if (fe->mac_metadata != NULL) { memcpy(fe->mac_metadata, metadata,@@ -891,6 +930,7 @@ fe = current_fixup(a, archive_entry_pathname(entry)); if (fe == NULL) return (ARCHIVE_FATAL);+ fe->filetype = archive_entry_filetype(entry); fe->fixup |= TODO_FFLAGS; /* TODO: Complete this.. defer fflags from below. */ }@@ -2462,7 +2502,8 @@ struct archive_write_disk *a = (struct archive_write_disk *)_a; struct fixup_entry *next, *p; struct stat st;- int fd, ret;+ char *c;+ int fd, ret, openflags; archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,@@ -2475,24 +2516,70 @@ while (p != NULL) { fd = -1; a->pst = NULL; /* Mark stat cache as out-of-date. */- if (p->fixup &- (TODO_TIMES | TODO_MODE_BASE | TODO_ACLS | TODO_FFLAGS)) {- fd = open(p->name,- O_WRONLY | O_BINARY | O_NOFOLLOW | O_CLOEXEC);- if (fd == -1) {- /* If we cannot lstat, skip entry */- if (lstat(p->name, &st) != 0)++ /* We must strip trailing slashes from the path to avoid+ dereferencing symbolic links to directories */+ c = p->name;+ while (*c != '\0')+ c++;+ while (c != p->name && *(c - 1) == '/') {+ c--;+ *c = '\0';+ }++ if (p->fixup == 0)+ goto skip_fixup_entry;+ else {+ /*+ * We need to verify if the type of the file+ * we are going to open matches the file type+ * of the fixup entry.+ */+ openflags = O_BINARY | O_NOFOLLOW | O_RDONLY+ | O_CLOEXEC;+#if defined(O_DIRECTORY)+ if (p->filetype == AE_IFDIR)+ openflags |= O_DIRECTORY;+#endif+ fd = open(p->name, openflags);++#if defined(O_DIRECTORY)+ /*+ * If we support O_DIRECTORY and open was+ * successful we can skip the file type check+ * for directories. For other file types+ * we need to verify via fstat() or lstat()+ */+ if (fd == -1 || p->filetype != AE_IFDIR) {+#if HAVE_FSTAT+ if (fd > 0 && (+ fstat(fd, &st) != 0 ||+ la_verify_filetype(st.st_mode,+ p->filetype) == 0)) { goto skip_fixup_entry;- /*- * If we deal with a symbolic link, mark- * it in the fixup mode to ensure no- * modifications are made to its target.- */- if (S_ISLNK(st.st_mode)) {- p->mode &= ~S_IFMT;- p->mode |= S_IFLNK;+ } else+#endif+ if (lstat(p->name, &st) != 0 ||+ la_verify_filetype(st.st_mode,+ p->filetype) == 0) {+ goto skip_fixup_entry; } }+#else+#if HAVE_FSTAT+ if (fd > 0 && (+ fstat(fd, &st) != 0 ||+ la_verify_filetype(st.st_mode,+ p->filetype) == 0)) {+ goto skip_fixup_entry;+ } else+#endif+ if (lstat(p->name, &st) != 0 ||+ la_verify_filetype(st.st_mode,+ p->filetype) == 0) {+ goto skip_fixup_entry;+ }+#endif } if (p->fixup & TODO_TIMES) { set_times(a, fd, p->mode, p->name,@@ -2504,14 +2591,13 @@ if (p->fixup & TODO_MODE_BASE) { #ifdef HAVE_FCHMOD if (fd >= 0)- fchmod(fd, p->mode);+ fchmod(fd, p->mode & 07777); else #endif #ifdef HAVE_LCHMOD- lchmod(p->name, p->mode);+ lchmod(p->name, p->mode & 07777); #else- if (!S_ISLNK(p->mode))- chmod(p->name, p->mode);+ chmod(p->name, p->mode & 07777); #endif } if (p->fixup & TODO_ACLS)@@ -2664,7 +2750,7 @@ fe->next = a->fixup_list; a->fixup_list = fe; fe->fixup = 0;- fe->mode = 0;+ fe->filetype = 0; fe->name = strdup(pathname); return (fe); }@@ -3787,6 +3873,7 @@ le = current_fixup(a, a->name); if (le == NULL) return (ARCHIVE_FATAL);+ le->filetype = archive_entry_filetype(a->entry); le->fixup |= TODO_FFLAGS; le->fflags_set = set; /* Store the mode if it's not already there. */
c/autoconf-darwin/config.h view
@@ -170,13 +170,13 @@ /* #undef ARCHIVE_XATTR_LINUX */ /* Version number of bsdcat */-#define BSDCAT_VERSION_STRING "3.5.2"+#define BSDCAT_VERSION_STRING "3.5.3" /* Version number of bsdcpio */-#define BSDCPIO_VERSION_STRING "3.5.2"+#define BSDCPIO_VERSION_STRING "3.5.3" /* Version number of bsdtar */-#define BSDTAR_VERSION_STRING "3.5.2"+#define BSDTAR_VERSION_STRING "3.5.3" /* Define to 1 if the system has the type `ace_t'. */ /* #undef HAVE_ACE_T */@@ -1248,10 +1248,10 @@ /* #undef ICONV_CONST */ /* Version number of libarchive as a single integer */-#define LIBARCHIVE_VERSION_NUMBER "3005002"+#define LIBARCHIVE_VERSION_NUMBER "3005003" /* Version number of libarchive */-#define LIBARCHIVE_VERSION_STRING "3.5.2"+#define LIBARCHIVE_VERSION_STRING "3.5.3" /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */@@ -1281,7 +1281,7 @@ #define PACKAGE_NAME "libarchive" /* Define to the full name and version of this package. */-#define PACKAGE_STRING "libarchive 3.5.2"+#define PACKAGE_STRING "libarchive 3.5.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libarchive"@@ -1290,7 +1290,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */-#define PACKAGE_VERSION "3.5.2"+#define PACKAGE_VERSION "3.5.3" /* Define to 1 if PCRE_STATIC needs to be defined. */ /* #undef PCRE_STATIC */@@ -1330,7 +1330,7 @@ /* Version number of package */-#define VERSION "3.5.2"+#define VERSION "3.5.3" /* Define to '0x0502' for Windows Server 2003 APIs. */ /* #undef WINVER */
c/autoconf-freebsd/config.h view
@@ -165,13 +165,13 @@ /* #undef ARCHIVE_XATTR_LINUX */ /* Version number of bsdcat */-#define BSDCAT_VERSION_STRING "3.5.2"+#define BSDCAT_VERSION_STRING "3.5.3" /* Version number of bsdcpio */-#define BSDCPIO_VERSION_STRING "3.5.2"+#define BSDCPIO_VERSION_STRING "3.5.3" /* Version number of bsdtar */-#define BSDTAR_VERSION_STRING "3.5.2"+#define BSDTAR_VERSION_STRING "3.5.3" /* Define to 1 if the system has the type `ace_t'. */ /* #undef HAVE_ACE_T */@@ -1237,10 +1237,10 @@ /* #undef ICONV_CONST */ /* Version number of libarchive as a single integer */-#define LIBARCHIVE_VERSION_NUMBER "3005002"+#define LIBARCHIVE_VERSION_NUMBER "3005003" /* Version number of libarchive */-#define LIBARCHIVE_VERSION_STRING "3.5.2"+#define LIBARCHIVE_VERSION_STRING "3.5.3" /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */@@ -1270,7 +1270,7 @@ #define PACKAGE_NAME "libarchive" /* Define to the full name and version of this package. */-#define PACKAGE_STRING "libarchive 3.5.2"+#define PACKAGE_STRING "libarchive 3.5.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libarchive"@@ -1279,7 +1279,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */-#define PACKAGE_VERSION "3.5.2"+#define PACKAGE_VERSION "3.5.3" /* Define to 1 if PCRE_STATIC needs to be defined. */ /* #undef PCRE_STATIC */@@ -1319,7 +1319,7 @@ /* Version number of package */-#define VERSION "3.5.2"+#define VERSION "3.5.3" /* Define to '0x0502' for Windows Server 2003 APIs. */ /* #undef WINVER */
c/autoconf-linux/config.h view
@@ -170,13 +170,13 @@ /* #undef ARCHIVE_XATTR_LINUX */ /* Version number of bsdcat */-#define BSDCAT_VERSION_STRING "3.5.2"+#define BSDCAT_VERSION_STRING "3.5.3" /* Version number of bsdcpio */-#define BSDCPIO_VERSION_STRING "3.5.2"+#define BSDCPIO_VERSION_STRING "3.5.3" /* Version number of bsdtar */-#define BSDTAR_VERSION_STRING "3.5.2"+#define BSDTAR_VERSION_STRING "3.5.3" /* Define to 1 if the system has the type `ace_t'. */ /* #undef HAVE_ACE_T */@@ -1248,10 +1248,10 @@ /* #undef ICONV_CONST */ /* Version number of libarchive as a single integer */-#define LIBARCHIVE_VERSION_NUMBER "3005002"+#define LIBARCHIVE_VERSION_NUMBER "3005003" /* Version number of libarchive */-#define LIBARCHIVE_VERSION_STRING "3.5.2"+#define LIBARCHIVE_VERSION_STRING "3.5.3" /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */@@ -1281,7 +1281,7 @@ #define PACKAGE_NAME "libarchive" /* Define to the full name and version of this package. */-#define PACKAGE_STRING "libarchive 3.5.2"+#define PACKAGE_STRING "libarchive 3.5.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libarchive"@@ -1290,7 +1290,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */-#define PACKAGE_VERSION "3.5.2"+#define PACKAGE_VERSION "3.5.3" /* Define to 1 if PCRE_STATIC needs to be defined. */ /* #undef PCRE_STATIC */@@ -1330,7 +1330,7 @@ /* Version number of package */-#define VERSION "3.5.2"+#define VERSION "3.5.3" /* Define to '0x0502' for Windows Server 2003 APIs. */ /* #undef WINVER */
c/autoconf-windows/config.h view
@@ -170,13 +170,13 @@ /* #undef ARCHIVE_XATTR_LINUX */ /* Version number of bsdcat */-#define BSDCAT_VERSION_STRING "3.5.2"+#define BSDCAT_VERSION_STRING "3.5.3" /* Version number of bsdcpio */-#define BSDCPIO_VERSION_STRING "3.5.2"+#define BSDCPIO_VERSION_STRING "3.5.3" /* Version number of bsdtar */-#define BSDTAR_VERSION_STRING "3.5.2"+#define BSDTAR_VERSION_STRING "3.5.3" /* Define to 1 if the system has the type `ace_t'. */ /* #undef HAVE_ACE_T */@@ -1240,10 +1240,10 @@ /* #undef ICONV_CONST */ /* Version number of libarchive as a single integer */-#define LIBARCHIVE_VERSION_NUMBER "3005002"+#define LIBARCHIVE_VERSION_NUMBER "3005003" /* Version number of libarchive */-#define LIBARCHIVE_VERSION_STRING "3.5.2"+#define LIBARCHIVE_VERSION_STRING "3.5.3" /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */@@ -1273,7 +1273,7 @@ #define PACKAGE_NAME "libarchive" /* Define to the full name and version of this package. */-#define PACKAGE_STRING "libarchive 3.5.2"+#define PACKAGE_STRING "libarchive 3.5.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libarchive"@@ -1282,7 +1282,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */-#define PACKAGE_VERSION "3.5.2"+#define PACKAGE_VERSION "3.5.3" /* Define to 1 if PCRE_STATIC needs to be defined. */ /* #undef PCRE_STATIC */@@ -1322,7 +1322,7 @@ /* Version number of package */-#define VERSION "3.5.2"+#define VERSION "3.5.3" /* Define to '0x0502' for Windows Server 2003 APIs. */ #define WINVER 0x0502
+ exe/Main.hs view
@@ -0,0 +1,247 @@+{-# LANGUAGE RecordWildCards #-}++module Main where++import Codec.Archive hiding (unpackToDir)+import Control.Monad (forM_)+import Control.Monad.Catch (Exception, MonadThrow, throwM)+import Data.Char (toUpper)+import Data.Bits (testBit)+import Data.List (isSuffixOf)+import System.IO (stderr, hPutStrLn)+import System.Directory (getCurrentDirectory, setCurrentDirectory)+import System.Console.GetOpt (OptDescr(..), ArgDescr(..), ArgOrder(..),+ getOpt', usageInfo)+import System.Environment (getArgs)+import System.Exit (exitFailure)+import Data.Time (formatTime)+import Data.Time.Clock.POSIX (posixSecondsToUTCTime, POSIXTime)+import Data.Time (defaultTimeLocale)++import qualified Codec.Compression.BZip as BZip+import qualified Codec.Compression.GZip as GZip+import qualified Codec.Compression.Lzma as Lzma+import qualified Data.ByteString.Lazy as BL+import qualified Data.ByteString as BS+++throwEither :: (Exception a, MonadThrow m) => Either a b -> m b+throwEither a = case a of+ Left e -> throwM e+ Right r -> pure r++throwEitherM :: (Exception a, MonadThrow m) => m (Either a b) -> m b+throwEitherM a = a >>= throwEither+++data Compression = None | GZip | BZip | XZ+ deriving (Show, Eq)++compressionFromFileName :: FilePath -> Compression+compressionFromFileName fn+ | ".tar.gz" `isSuffixOf` fn = GZip+ | ".tar.xz" `isSuffixOf` fn = XZ+ | ".tar.bz2" `isSuffixOf` fn = BZip+ | otherwise = None++compress :: Compression -> BL.ByteString -> BL.ByteString+compress GZip = GZip.compress+compress BZip = BZip.compress+compress XZ = Lzma.compress+compress None = id++decompress :: Compression -> BL.ByteString -> BL.ByteString+decompress GZip = GZip.decompress+decompress BZip = BZip.decompress+decompress XZ = Lzma.decompress+decompress None = id++data Verbosity = Verbose | Concise++main' :: Options -> [FilePath] -> IO ()+main' (Options { optFile = file,+ optDir = dir',+ optAction = action,+ optCompression = compression',+ optVerbosity = verbosity }) files =+ case action of+ NoAction -> die ["No action given. Specify one of -c, -t or -x."]+ Help -> printUsage+ Create -> do+ dir <- getDir+ setCurrentDirectory dir+ bs <- packFiles files+ writeOutput . compress compression $ bs+ Extract -> do+ dir <- getDir+ input <- getInput+ throwEitherM . runArchiveM . unpackToDirLazy dir . decompress compression $ input+ List -> do+ input <- getInput+ entries <- throwEither . readArchiveBSL . decompress compression $ input+ printEntries entries+ Append -> die ["Not implemented yet!"]+ where+ getInput = if file == "-" then BL.getContents else BL.readFile file+ writeOutput = if file == "-" then BL.putStr else BL.writeFile file+ getDir = if dir' == "" then getCurrentDirectory else pure dir'+ compression = case compression' of+ None -> compressionFromFileName file+ c -> c+ printEntries entries = forM_ entries printEntry+ printEntry = putStrLn . entryInfo verbosity+++main :: IO ()+main = do+ (opts, files) <- parseOptions =<< getArgs+ main' opts files+++------------------------+-- List archive contents++entryInfo :: Verbosity -> Entry FilePath BS.ByteString -> String+entryInfo Verbose = detailedInfo+entryInfo Concise = filepath++detailedInfo :: Entry FilePath BS.ByteString -> String+detailedInfo Entry{..} =+ unwords [ typeCode : permissions'+ , justify 19 (owner ++ '/' : group) size+ , time'+ , name ++ link ]+ where+ typeCode = case content of+ Hardlink _ -> 'h'+ Symlink _ _ -> 'l'+ Directory -> 'd'+ _ -> '-'+ permissions' = concat [userPerms, groupPerms, otherPerms]+ where+ userPerms = formatPerms 8 7 6 11 's'+ groupPerms = formatPerms 5 4 3 10 's'+ otherPerms = formatPerms 2 1 0 9 't'+ formatPerms r w x s c =+ [if testBit m r then 'r' else '-'+ ,if testBit m w then 'w' else '-'+ ,if testBit m s+ then if testBit m x then c else toUpper c+ else if testBit m x then 'x' else '-']+ m = permissions+ owner = nameOrID ownerName ownerId+ group = nameOrID groupName groupId+ (Ownership ownerName groupName ownerId groupId) = ownership+ nameOrID Nothing i = show i+ nameOrID (Just n) _ = n+ size = case content of+ NormalFile c -> show (BS.length c)+ _ -> "0"++ time' = maybe "unknown" (formatEpochTime "%Y-%m-%d %H:%M") time+ name = filepath+ link = case content of+ Hardlink l -> " link to " ++ l+ Symlink l _ -> " -> " ++ l+ _ -> ""++justify :: Int -> String -> String -> String+justify width left right = left ++ padding ++ right+ where+ padding = replicate padWidth ' '+ padWidth = max 1 (width - length left - length right)++formatEpochTime :: String -> ModTime -> String+formatEpochTime f (t, _) =+ formatTime defaultTimeLocale f . posixSecondsToUTCTime $ (realToFrac t :: POSIXTime)+++------------------------+-- Command line handling (stolen from 'tar')++data Options = Options {+ optFile :: FilePath, -- "-" means stdin/stdout+ optDir :: FilePath,+ optAction :: Action,+ optCompression :: Compression,+ optVerbosity :: Verbosity+ }++defaultOptions :: Options+defaultOptions = Options {+ optFile = "-",+ optDir = "",+ optAction = NoAction,+ optCompression = None,+ optVerbosity = Concise+ }++data Action = NoAction+ | Help+ | Create+ | Extract+ | List+ | Append+ deriving Show++optDescr :: [OptDescr (Options -> Options)]+optDescr =+ [ Option ['c'] ["create"]+ (action Create)+ "Create a new archive."+ , Option ['x'] ["extract", "get"]+ (action Extract)+ "Extract files from an archive."+ , Option ['t'] ["list"]+ (action List)+ "List the contents of an archive."+ , Option ['r'] ["append"]+ (action Append)+ "Append files to the end of an archive."+ , Option ['f'] ["file"]+ (ReqArg (\f o -> o { optFile = f}) "ARCHIVE")+ "Use archive file ARCHIVE."+ , Option ['C'] ["directory"]+ (ReqArg (\d o -> o { optDir = d }) "DIR")+ "Create or extract relative to DIR."+ , Option ['z'] ["gzip", "gunzip", "ungzip"]+ (compression GZip)+ "Use gzip compression."+ , Option ['j'] ["bzip2"]+ (compression BZip)+ "Use bzip2 compression."+ , Option ['J'] ["xz"]+ (compression XZ)+ "Use xz compression."+ , Option ['v'] ["verbose"]+ (NoArg (\o -> o { optVerbosity = Verbose }))+ "Verbosely list files processed."+ , Option ['h', '?'] ["help"]+ (action Help)+ "Print this help output."+ ]+ where+ action a = NoArg (\o -> o { optAction = a })+ compression c = NoArg (\o -> o { optCompression = c })++printUsage :: IO ()+printUsage = putStrLn (usageInfo headder optDescr)+ where+ headder = unlines ["archive creates and extracts TAR archives.",+ "",+ "Usage: archive [OPTION ...] [FILE ...]"]++parseOptions :: [String] -> IO (Options, [FilePath])+parseOptions args =+ let (fs, files, nonopts, errors) = getOpt' Permute optDescr args+ in case (nonopts, errors) of+ ([], []) -> return $ (foldl (flip ($)) defaultOptions fs, files)+ (_ , (_:_)) -> die errors+ (_ , _) -> die (map (("unrecognized option "++).show) nonopts)+++die :: [String] -> IO a+die errs = do+ mapM_ (\e -> hPutStrLn stderr $ "archive: " ++ e) $ errs+ hPutStrLn stderr "Try `archive --help' for more information."+ exitFailure
libarchive.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: libarchive-version: 3.0.3.1+version: 3.0.3.2 license: BSD-3-Clause license-file: LICENSE copyright: Copyright: (c) 2018-2020 Vanessa McHale@@ -8,7 +8,7 @@ author: Vanessa McHale tested-with: ghc ==7.10.3 ghc ==8.0.2 ghc ==8.2.2 ghc ==8.4.4 ghc ==8.6.5- ghc ==8.8.4 ghc ==8.10.7 ghc ==9.0.1+ ghc ==8.8.4 ghc ==8.10.7 ghc ==9.0.2 ghc ==9.2.1 bug-reports: https://github.com/vmchale/libarchive/issues synopsis: Haskell interface to libarchive@@ -55,6 +55,9 @@ description: Use libarchive found with pkg-config rather than the bundled sources +flag no-exe+ description: don't install the archive executables+ library exposed-modules: Codec.Archive@@ -285,8 +288,28 @@ build-depends: unbuildable <0 else- pkgconfig-depends: libarchive (==3.5.0 || >3.5.0) && <4.0+ pkgconfig-depends: libarchive (==3.5.2 || >3.5.2) && <4.0 +executable archive+ main-is: Main.hs+ hs-source-dirs: exe+ default-language: Haskell2010+ ghc-options: -Wall+ build-depends:+ base >=4.8 && <5,+ bytestring >=0.9,+ bzlib >=0.4 && <0.7,+ directory >=1.0,+ exceptions,+ filepath >=1.0,+ libarchive,+ lzma-static,+ time,+ zlib ^>=0.6.2.2++ if flag(no-exe)+ buildable: False+ test-suite libarchive-test type: exitcode-stdio-1.0 main-is: Spec.hs@@ -304,7 +327,6 @@ deepseq, libarchive, hspec,- hspec-core, bytestring, directory >=1.2.5.0, filepath,