summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/archive.h4
-rw-r--r--lib/libarchive/archive_check_magic.c4
-rw-r--r--lib/libarchive/archive_entry.c2
-rw-r--r--lib/libarchive/archive_entry.h4
-rw-r--r--lib/libarchive/archive_read_disk_set_standard_lookup.c6
-rw-r--r--lib/libarchive/archive_read_support_compression_program.c2
-rw-r--r--lib/libarchive/archive_string.c291
-rw-r--r--lib/libarchive/archive_write_disk.c24
-rw-r--r--lib/libarchive/archive_write_disk_set_standard_lookup.c4
-rw-r--r--lib/libarchive/archive_write_set_compression_program.c2
-rw-r--r--lib/libarchive/archive_write_set_format_mtree.c6
-rw-r--r--lib/libarchive/test/main.c12
-rw-r--r--lib/libarchive/test/test.h13
-rw-r--r--lib/libarchive/test/test_read_disk.c6
-rw-r--r--lib/libarchive/test/test_read_extract.c6
-rw-r--r--lib/libarchive/test/test_tar_large.c35
-rw-r--r--lib/libarchive/test/test_write_disk.c18
-rw-r--r--lib/libarchive/test/test_write_disk_failures.c2
-rw-r--r--lib/libarchive/test/test_write_disk_hardlink.c21
-rw-r--r--lib/libarchive/test/test_write_disk_perms.c4
-rw-r--r--lib/libarchive/test/test_write_disk_secure.c4
21 files changed, 250 insertions, 220 deletions
diff --git a/lib/libarchive/archive.h b/lib/libarchive/archive.h
index 23b9a9d..da31d40 100644
--- a/lib/libarchive/archive.h
+++ b/lib/libarchive/archive.h
@@ -46,7 +46,7 @@
/* Get appropriate definitions of standard POSIX-style types. */
/* These should match the types used in 'struct stat' */
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
#define __LA_INT64_T __int64
# if defined(_WIN64)
# define __LA_SSIZE_T __int64
@@ -68,7 +68,7 @@
* .lib. The default here assumes you're building a DLL. Only
* libarchive source should ever define __LIBARCHIVE_BUILD.
*/
-#if ((defined __WIN32__) || (defined _WIN32)) && (!defined LIBARCHIVE_STATIC)
+#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
# ifdef __LIBARCHIVE_BUILD
# ifdef __GNUC__
# define __LA_DECL __attribute__((dllexport)) extern
diff --git a/lib/libarchive/archive_check_magic.c b/lib/libarchive/archive_check_magic.c
index e1d35c5..8f1fa2f 100644
--- a/lib/libarchive/archive_check_magic.c
+++ b/lib/libarchive/archive_check_magic.c
@@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#include <winbase.h>
#endif
@@ -56,7 +56,7 @@ errmsg(const char *m)
static void
diediedie(void)
{
-#if defined(_WIN32) && defined(_DEBUG)
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
/* Cause a breakpoint exception */
DebugBreak();
#endif
diff --git a/lib/libarchive/archive_entry.c b/lib/libarchive/archive_entry.c
index 37fc37b..4cafce2 100644
--- a/lib/libarchive/archive_entry.c
+++ b/lib/libarchive/archive_entry.c
@@ -83,7 +83,7 @@ __FBSDID("$FreeBSD$");
#elif defined makedev
/* There's a "makedev" macro. */
#define ae_makedev(maj, min) makedev((maj), (min))
-#elif defined mkdev || defined _WIN32 || defined __WIN32__
+#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__))
/* Windows. <sigh> */
#define ae_makedev(maj, min) mkdev((maj), (min))
#else
diff --git a/lib/libarchive/archive_entry.h b/lib/libarchive/archive_entry.h
index 93925a9..a2748fd 100644
--- a/lib/libarchive/archive_entry.h
+++ b/lib/libarchive/archive_entry.h
@@ -42,7 +42,7 @@
/* Get appropriate definitions of standard POSIX-style types. */
/* These should match the types used in 'struct stat' */
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
#define __LA_INT64_T __int64
#define __LA_UID_T unsigned int
#define __LA_GID_T unsigned int
@@ -71,7 +71,7 @@
* .lib. The default here assumes you're building a DLL. Only
* libarchive source should ever define __LIBARCHIVE_BUILD.
*/
-#if ((defined __WIN32__) || (defined _WIN32)) && (!defined LIBARCHIVE_STATIC)
+#if ((defined __WIN32__) || (defined _WIN32) || defined(__CYGWIN__)) && (!defined LIBARCHIVE_STATIC)
# ifdef __LIBARCHIVE_BUILD
# ifdef __GNUC__
# define __LA_DECL __attribute__((dllexport)) extern
diff --git a/lib/libarchive/archive_read_disk_set_standard_lookup.c b/lib/libarchive/archive_read_disk_set_standard_lookup.c
index 9c96f19..68e8074 100644
--- a/lib/libarchive/archive_read_disk_set_standard_lookup.c
+++ b/lib/libarchive/archive_read_disk_set_standard_lookup.c
@@ -47,14 +47,14 @@ __FBSDID("$FreeBSD$");
#include "archive.h"
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
int
archive_read_disk_set_standard_lookup(struct archive *a)
{
archive_set_error(a, -1, "Standard lookups not available on Windows");
return (ARCHIVE_FATAL);
}
-#else
+#else /* ! (_WIN32 && !__CYGWIN__) */
#define name_cache_size 127
static const char * const NO_NAME = "(noname)";
@@ -226,4 +226,4 @@ lookup_gname_helper(struct archive *a, id_t id)
return strdup(grent.gr_name);
}
-#endif /* _WIN32 */
+#endif /* ! (_WIN32 && !__CYGWIN__) */
diff --git a/lib/libarchive/archive_read_support_compression_program.c b/lib/libarchive/archive_read_support_compression_program.c
index 4463255..d405e3b 100644
--- a/lib/libarchive/archive_read_support_compression_program.c
+++ b/lib/libarchive/archive_read_support_compression_program.c
@@ -61,7 +61,7 @@ archive_read_support_compression_program(struct archive *a, const char *cmd)
/* This capability is only available on POSIX systems. */
#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
- !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && !defined(_WIN32)
+ !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
/*
* On non-Posix systems, allow the program to build, but choke if
diff --git a/lib/libarchive/archive_string.c b/lib/libarchive/archive_string.c
index 120c127..111dcb1 100644
--- a/lib/libarchive/archive_string.c
+++ b/lib/libarchive/archive_string.c
@@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
#include <windows.h>
#endif
@@ -165,56 +165,18 @@ __archive_strappend_char(struct archive_string *as, char c)
return (__archive_string_append(as, &c, 1));
}
-#ifndef _WIN32
/*
- * Home-grown wctomb for UTF-8.
+ * Translates a wide character string into UTF-8 and appends
+ * to the archive_string. Note: returns NULL if conversion fails,
+ * but still leaves a best-effort conversion in the argument as.
*/
-static int
-my_wctomb_utf8(char *p, wchar_t wc)
-{
- if (p == NULL)
- /* UTF-8 doesn't use shift states. */
- return (0);
- if (wc <= 0x7f) {
- p[0] = (char)wc;
- return (1);
- }
- if (wc <= 0x7ff) {
- p[0] = 0xc0 | ((wc >> 6) & 0x1f);
- p[1] = 0x80 | (wc & 0x3f);
- return (2);
- }
- if (wc <= 0xffff) {
- p[0] = 0xe0 | ((wc >> 12) & 0x0f);
- p[1] = 0x80 | ((wc >> 6) & 0x3f);
- p[2] = 0x80 | (wc & 0x3f);
- return (3);
- }
- if (wc <= 0x1fffff) {
- p[0] = 0xf0 | ((wc >> 18) & 0x07);
- p[1] = 0x80 | ((wc >> 12) & 0x3f);
- p[2] = 0x80 | ((wc >> 6) & 0x3f);
- p[3] = 0x80 | (wc & 0x3f);
- return (4);
- }
- /* Unicode has no codes larger than 0x1fffff. */
- /*
- * Awkward point: UTF-8 <-> wchar_t conversions
- * can actually fail.
- */
- return (-1);
-}
-
-static int
-my_wcstombs(struct archive_string *as, const wchar_t *w,
- int (*func)(char *, wchar_t))
+struct archive_string *
+__archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
{
- int n;
char *p;
+ unsigned wc;
char buff[256];
-
- /* Clear the shift state before starting. */
- (*func)(NULL, L'\0');
+ struct archive_string *return_val = as;
/*
* Convert one wide char at a time into 'buff', whenever that
@@ -229,67 +191,50 @@ my_wcstombs(struct archive_string *as, const wchar_t *w,
archive_strcat(as, buff);
p = buff;
}
- n = (*func)(p, *w++);
- if (n == -1)
- return (-1);
- p += n;
+ wc = *w++;
+ /* If this is a surrogate pair, assemble the full code point.*/
+ /* Note: wc must not be wchar_t here, because the full code
+ * point can be more than 16 bits! */
+ if (wc >= 0xD800 && wc <= 0xDBff
+ && *w >= 0xDC00 && *w <= 0xDFFF) {
+ wc -= 0xD800;
+ wc *= 0x400;
+ wc += (*w - 0xDC00);
+ wc += 0x10000;
+ ++w;
+ }
+ /* Translate code point to UTF8 */
+ if (wc <= 0x7f) {
+ *p++ = (char)wc;
+ } else if (wc <= 0x7ff) {
+ *p++ = 0xc0 | ((wc >> 6) & 0x1f);
+ *p++ = 0x80 | (wc & 0x3f);
+ } else if (wc <= 0xffff) {
+ *p++ = 0xe0 | ((wc >> 12) & 0x0f);
+ *p++ = 0x80 | ((wc >> 6) & 0x3f);
+ *p++ = 0x80 | (wc & 0x3f);
+ } else if (wc <= 0x1fffff) {
+ *p++ = 0xf0 | ((wc >> 18) & 0x07);
+ *p++ = 0x80 | ((wc >> 12) & 0x3f);
+ *p++ = 0x80 | ((wc >> 6) & 0x3f);
+ *p++ = 0x80 | (wc & 0x3f);
+ } else {
+ /* Unicode has no codes larger than 0x1fffff. */
+ /* TODO: use \uXXXX escape here instead of ? */
+ *p++ = '?';
+ return_val = NULL;
+ }
}
*p = '\0';
archive_strcat(as, buff);
- return (0);
+ return (return_val);
}
-/*
- * Translates a wide character string into UTF-8 and appends
- * to the archive_string. Note: returns NULL if conversion fails.
- */
-struct archive_string *
-__archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
-{
- if (my_wcstombs(as, w, my_wctomb_utf8))
- return (NULL);
- return (as);
-}
-
-/*
- * Translates a wide character string into current locale character set
- * and appends to the archive_string. Note: returns NULL if conversion
- * fails.
- */
-struct archive_string *
-__archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
-{
-#if HAVE_WCTOMB
- if (my_wcstombs(as, w, wctomb))
- return (NULL);
-#else
- /* TODO: Can we do better than this? Are there platforms
- * that have locale support but don't have wctomb()? */
- if (my_wcstombs(as, w, my_wctomb_utf8))
- return (NULL);
-#endif
- return (as);
-}
-
-
-/*
- * Home-grown mbtowc for UTF-8. Some systems lack UTF-8
- * (or even lack mbtowc()) and we need UTF-8 support for pax
- * format. So please don't replace this with a call to the
- * standard mbtowc() function!
- */
static int
-my_mbtowc_utf8(wchar_t *pwc, const char *s, size_t n)
+utf8_to_unicode(int *pwc, const char *s, size_t n)
{
int ch;
- /* Standard behavior: a NULL value for 's' just resets shift state. */
- if (s == NULL)
- return (0);
- /* If length argument is zero, don't look at the first character. */
- if (n <= 0)
- return (-1);
-
/*
* Decode 1-4 bytes depending on the value of the first byte.
*/
@@ -335,13 +280,15 @@ my_mbtowc_utf8(wchar_t *pwc, const char *s, size_t n)
}
/*
- * Return a wide-character string by converting this archive_string
- * from UTF-8.
+ * Return a wide-character Unicode string by converting this archive_string
+ * from UTF-8. We assume that systems with 16-bit wchar_t always use
+ * UTF16 and systems with 32-bit wchar_t can accept UCS4.
*/
wchar_t *
__archive_string_utf8_w(struct archive_string *as)
{
wchar_t *ws, *dest;
+ int wc, wc2;/* Must be large enough for a 21-bit Unicode code point. */
const char *src;
int n;
int err;
@@ -353,25 +300,68 @@ __archive_string_utf8_w(struct archive_string *as)
dest = ws;
src = as->s;
while (*src != '\0') {
- n = my_mbtowc_utf8(dest, src, 8);
+ n = utf8_to_unicode(&wc, src, 8);
if (n == 0)
break;
if (n < 0) {
free(ws);
return (NULL);
}
- dest++;
src += n;
+ if (wc >= 0xDC00 && wc <= 0xDBFF) {
+ /* This is a leading surrogate; some idiot
+ * has translated UTF16 to UTF8 without combining
+ * surrogates; rebuild the full code point before
+ * continuing. */
+ n = utf8_to_unicode(&wc2, src, 8);
+ if (n < 0) {
+ free(ws);
+ return (NULL);
+ }
+ if (n == 0) /* Ignore the leading surrogate */
+ break;
+ if (wc2 < 0xDC00 || wc2 > 0xDFFF) {
+ /* If the second character isn't a
+ * trailing surrogate, then someone
+ * has really screwed up and this is
+ * invalid. */
+ free(ws);
+ return (NULL);
+ } else {
+ src += n;
+ wc -= 0xD800;
+ wc *= 0x400;
+ wc += wc2 - 0xDC00;
+ wc += 0x10000;
+ }
+ }
+ if ((sizeof(wchar_t) < 4) && (wc > 0xffff)) {
+ /* We have a code point that won't fit into a
+ * wchar_t; convert it to a surrogate pair. */
+ wc -= 0x10000;
+ *dest++ = ((wc >> 10) & 0x3ff) + 0xD800;
+ *dest++ = (wc & 0x3ff) + 0xDC00;
+ } else
+ *dest++ = wc;
}
*dest++ = L'\0';
return (ws);
}
-#else
+#if defined(_WIN32) && !defined(__CYGWIN__)
-static struct archive_string *
-my_archive_strappend_w(struct archive_string *as,
- unsigned int codepage, const wchar_t *w)
+/*
+ * Translates a wide character string into current locale character set
+ * and appends to the archive_string. Note: returns NULL if conversion
+ * fails.
+ *
+ * Win32 builds use WideCharToMultiByte from the Windows API.
+ * (Maybe Cygwin should too? WideCharToMultiByte will know a
+ * lot more about local character encodings than the wcrtomb()
+ * wrapper is going to know.)
+ */
+struct archive_string *
+__archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
{
char *p;
int l, wl;
@@ -388,9 +378,8 @@ my_archive_strappend_w(struct archive_string *as,
* And to set NULL for last argument is necessary when a codepage
* is not CP_ACP(current locale).
*/
- l = WideCharToMultiByte(codepage, 0, w, wl, p, l, NULL,
- (codepage == CP_ACP) ? &useDefaultChar : NULL);
- if (l == 0 || useDefaultChar) {
+ l = WideCharToMultiByte(CP_ACP, 0, w, wl, p, l, NULL, &useDefaultChar);
+ if (l == 0) {
free(p);
return (NULL);
}
@@ -399,50 +388,68 @@ my_archive_strappend_w(struct archive_string *as,
return (as);
}
-/*
- * Translates a wide character string into UTF-8 and appends
- * to the archive_string. Note: returns NULL if conversion fails.
- */
-struct archive_string *
-__archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
-{
-
- return (my_archive_strappend_w(as, CP_UTF8, w));
-}
+#else
/*
* Translates a wide character string into current locale character set
* and appends to the archive_string. Note: returns NULL if conversion
* fails.
+ *
+ * Non-Windows uses ISO C wcrtomb() or wctomb() to perform the conversion
+ * one character at a time. If a non-Windows platform doesn't have
+ * either of these, fall back to the built-in UTF8 conversion.
*/
struct archive_string *
__archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
{
-
- return (my_archive_strappend_w(as, CP_ACP, w));
-}
-
-/*
- * Return a wide-character string by converting this archive_string
- * from UTF-8.
- */
-wchar_t *
-__archive_string_utf8_w(struct archive_string *as)
-{
- wchar_t *ws;
+#if !defined(HAVE_WCTOMB) && !defined(HAVE_WCRTOMB)
+ /* If there's no built-in locale support, fall back to UTF8 always. */
+ return __archive_strappend_w_utf8(as, w);
+#else
+ /* We cannot use the standard wcstombs() here because it
+ * cannot tell us how big the output buffer should be. So
+ * I've built a loop around wcrtomb() or wctomb() that
+ * converts a character at a time and resizes the string as
+ * needed. We prefer wcrtomb() when it's available because
+ * it's thread-safe. */
int n;
+ char *p;
+ char buff[256];
+#if HAVE_WCRTOMB
+ mbstate_t shift_state;
- ws = (wchar_t *)malloc((as->length + 1) * sizeof(wchar_t));
- if (ws == NULL)
- __archive_errx(1, "Out of memory");
- n = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS,
- as->s, (int)as->length, ws, (int)as->length);
- if (n == 0) {
- free(ws);
- return (NULL);
+ memset(&shift_state, 0, sizeof(shift_state));
+#else
+ /* Clear the shift state before starting. */
+ wctomb(NULL, L'\0');
+#endif
+
+ /*
+ * Convert one wide char at a time into 'buff', whenever that
+ * fills, append it to the string.
+ */
+ p = buff;
+ while (*w != L'\0') {
+ /* Flush the buffer when we have <=16 bytes free. */
+ /* (No encoding has a single character >16 bytes.) */
+ if ((size_t)(p - buff) >= (size_t)(sizeof(buff) - MB_CUR_MAX)) {
+ *p = '\0';
+ archive_strcat(as, buff);
+ p = buff;
+ }
+#if HAVE_WCRTOMB
+ n = wcrtomb(p, *w++, &shift_state);
+#else
+ n = wctomb(p, *w++);
+#endif
+ if (n == -1)
+ return (NULL);
+ p += n;
}
- ws[n] = L'\0';
- return (ws);
+ *p = '\0';
+ archive_strcat(as, buff);
+ return (as);
+#endif
}
-#endif /* !_WIN32 */
+#endif /* _WIN32 && ! __CYGWIN__ */
diff --git a/lib/libarchive/archive_write_disk.c b/lib/libarchive/archive_write_disk.c
index 0d84156..60fa227 100644
--- a/lib/libarchive/archive_write_disk.c
+++ b/lib/libarchive/archive_write_disk.c
@@ -36,6 +36,9 @@ __FBSDID("$FreeBSD$");
#ifdef HAVE_SYS_EXTATTR_H
#include <sys/extattr.h>
#endif
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
#ifdef HAVE_ATTR_XATTR_H
#include <attr/xattr.h>
#endif
@@ -414,7 +417,7 @@ _archive_write_header(struct archive *_a, struct archive_entry *entry)
a->mode &= ~S_ISVTX;
a->mode &= ~a->user_umask;
}
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER)
a->todo |= TODO_OWNER;
#endif
@@ -1217,7 +1220,7 @@ _archive_write_close(struct archive *_a)
if (p->fixup & TODO_TIMES) {
#ifdef HAVE_UTIMES
/* {f,l,}utimes() are preferred, when available. */
-#ifdef __timeval
+#if defined(_WIN32) && !defined(__CYGWIN__)
struct __timeval times[2];
#else
struct timeval times[2];
@@ -1474,7 +1477,7 @@ check_symlinks(struct archive_write_disk *a)
return (ARCHIVE_OK);
}
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
/*
* 1. Convert a path separator from '\' to '/' .
* We shouldn't check multi-byte character directly because some
@@ -1544,7 +1547,7 @@ cleanup_pathname(struct archive_write_disk *a)
return (ARCHIVE_FAILED);
}
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
cleanup_pathname_win(a);
#endif
/* Skip leading '/'. */
@@ -1758,12 +1761,17 @@ create_dir(struct archive_write_disk *a, char *path)
static int
set_ownership(struct archive_write_disk *a)
{
+#ifndef __CYGWIN__
+/* unfortunately, on win32 there is no 'root' user with uid 0,
+ so we just have to try the chown and see if it works */
+
/* If we know we can't change it, don't bother trying. */
if (a->user_uid != 0 && a->user_uid != a->uid) {
archive_set_error(&a->archive, errno,
"Can't set UID=%d", a->uid);
return (ARCHIVE_WARN);
}
+#endif
#ifdef HAVE_FCHOWN
/* If we have an fd, we can avoid a race. */
@@ -1807,7 +1815,7 @@ set_time(int fd, int mode, const char *name,
time_t atime, long atime_nsec,
time_t mtime, long mtime_nsec)
{
-#ifdef __timeval
+#if defined(_WIN32) && !defined(__CYGWIN__)
struct __timeval times[2];
#else
struct timeval times[2];
@@ -1944,7 +1952,7 @@ set_mode(struct archive_write_disk *a, int mode)
return (r);
if (a->pst->st_gid != a->gid) {
mode &= ~ S_ISGID;
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER) {
/*
* This is only an error if you
@@ -1963,7 +1971,7 @@ set_mode(struct archive_write_disk *a, int mode)
if (a->pst->st_uid != a->uid
&& (a->todo & TODO_SUID)) {
mode &= ~ S_ISUID;
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER) {
archive_set_error(&a->archive, -1,
"Can't restore SUID bit");
@@ -1981,7 +1989,7 @@ set_mode(struct archive_write_disk *a, int mode)
*/
if (a->user_uid != a->uid) {
mode &= ~ S_ISUID;
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
if (a->flags & ARCHIVE_EXTRACT_OWNER) {
archive_set_error(&a->archive, -1,
"Can't make file SUID");
diff --git a/lib/libarchive/archive_write_disk_set_standard_lookup.c b/lib/libarchive/archive_write_disk_set_standard_lookup.c
index 39f5891..5329425 100644
--- a/lib/libarchive/archive_write_disk_set_standard_lookup.c
+++ b/lib/libarchive/archive_write_disk_set_standard_lookup.c
@@ -122,7 +122,7 @@ lookup_gid(void *private_data, const char *gname, gid_t gid)
if (grent != NULL)
gid = grent->gr_gid;
}
-#elif _WIN32
+#elif defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: do a gname->gid lookup for Windows. */
#endif
b->id = gid;
@@ -159,7 +159,7 @@ lookup_uid(void *private_data, const char *uname, uid_t uid)
if (pwent != NULL)
uid = pwent->pw_uid;
}
-#elif _WIN32
+#elif defined(_WIN32) && !defined(__CYGWIN__)
/* TODO: do a uname->uid lookup for Windows. */
#endif
b->id = uid;
diff --git a/lib/libarchive/archive_write_set_compression_program.c b/lib/libarchive/archive_write_set_compression_program.c
index 3615021..e612f3b 100644
--- a/lib/libarchive/archive_write_set_compression_program.c
+++ b/lib/libarchive/archive_write_set_compression_program.c
@@ -29,7 +29,7 @@ __FBSDID("$FreeBSD$");
/* This capability is only available on POSIX systems. */
#if (!defined(HAVE_PIPE) || !defined(HAVE_FCNTL) || \
- !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && !defined(_WIN32)
+ !(defined(HAVE_FORK) || defined(HAVE_VFORK))) && (!defined(_WIN32) || defined(__CYGWIN__))
#include "archive.h"
/*
diff --git a/lib/libarchive/archive_write_set_format_mtree.c b/lib/libarchive/archive_write_set_format_mtree.c
index 2910a0d..0043030 100644
--- a/lib/libarchive/archive_write_set_format_mtree.c
+++ b/lib/libarchive/archive_write_set_format_mtree.c
@@ -320,7 +320,7 @@ mtree_indent(struct mtree_writer *mtree)
archive_string_empty(&mtree->ebuf);
}
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
static size_t
dir_len(struct archive_entry *entry)
{
@@ -334,7 +334,7 @@ dir_len(struct archive_entry *entry)
return (r - path + 1);
}
-#else
+#else /* _WIN32 && !__CYGWIN__ */
/*
* Note: We should use wide-character for findng '\' character,
* a directory separator on Windows, because some character-set have
@@ -376,7 +376,7 @@ alen:
return (0);
return (al + 1);
}
-#endif /* _WIN32 */
+#endif /* _WIN32 && !__CYGWIN__ */
static int
parent_dir_changed(struct archive_string *dir, struct archive_entry *entry)
diff --git a/lib/libarchive/test/main.c b/lib/libarchive/test/main.c
index 62a0a3f..01a0817 100644
--- a/lib/libarchive/test/main.c
+++ b/lib/libarchive/test/main.c
@@ -33,7 +33,7 @@
#include <locale.h>
#include <stdarg.h>
#include <time.h>
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
#include <crtdbg.h>
#include <windows.h>
#include <winbase.h>
@@ -93,7 +93,7 @@ static int assertions = 0;
static const char *refdir;
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
static void
invalid_parameter_handler(const wchar_t * expression,
@@ -798,7 +798,7 @@ static int test_run(int i, const char *tmpdir)
/* If there were no failures, we can remove the work dir. */
if (failures == failures_before) {
if (!keep_temp_files && chdir(tmpdir) == 0) {
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
systemf("rm -rf %s", tests[i].name);
#else
systemf("rmdir /S /Q %s", tests[i].name);
@@ -894,7 +894,7 @@ extract_reference_file(const char *name)
fclose(in);
}
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
#define DEV_NULL "NUL"
#else
#define DEV_NULL "/dev/null"
@@ -966,7 +966,7 @@ get_refdir(void)
strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1);
}
-#if defined(_WIN32) && defined(_DEBUG)
+#if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG)
DebugBreak();
#endif
printf("Unable to locate known reference file %s\n", KNOWNREF);
@@ -992,7 +992,7 @@ int main(int argc, char **argv)
(void)argc; /* UNUSED */
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
/* To stop to run the default invalid parameter handler. */
_set_invalid_parameter_handler(invalid_parameter_handler);
/* for open() to a binary mode. */
diff --git a/lib/libarchive/test/test.h b/lib/libarchive/test/test.h
index fcac91a..539c826 100644
--- a/lib/libarchive/test/test.h
+++ b/lib/libarchive/test/test.h
@@ -37,7 +37,7 @@
#elif defined(__FreeBSD__)
/* Building as part of FreeBSD system requires a pre-built config.h. */
#include "config_freebsd.h"
-#elif defined(_WIN32)
+#elif defined(_WIN32) && !defined(__CYGWIN__)
/* Win32 can't run the 'configure' script. */
#include "config_windows.h"
#else
@@ -45,7 +45,7 @@
#error Oops: No config.h and no pre-built configuration in test.h.
#endif
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
#include <dirent.h>
#else
#include <direct.h>
@@ -56,7 +56,7 @@
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
#include <unistd.h>
#endif
#include <wchar.h>
@@ -69,10 +69,15 @@
#ifdef __FreeBSD__
#include <sys/cdefs.h> /* For __FBSDID */
#else
+/* Some non-FreeBSD platforms such as newlib-derived ones like
+ * cygwin, have __FBSDID, so this definition must be guarded.
+ */
+#ifndef __FBSDID
#define __FBSDID(a) /* null */
#endif
+#endif
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
#define snprintf sprintf_s
#define LOCALE_DE "deu"
#else
diff --git a/lib/libarchive/test/test_read_disk.c b/lib/libarchive/test/test_read_disk.c
index e368398..ce10440 100644
--- a/lib/libarchive/test/test_read_disk.c
+++ b/lib/libarchive/test/test_read_disk.c
@@ -111,6 +111,11 @@ DEFINE_TEST(test_read_disk)
if (archive_read_disk_set_standard_lookup(a) != ARCHIVE_OK) {
skipping("standard uname/gname lookup");
} else {
+#if defined(__CYGWIN__)
+ skipping("standard uname/gname lookup; typically no user with uid=0 on cygwin platform");
+ i = 0;
+ p = zero_groups[0]; /* avoid unused warnings */
+#else
/* XXX Someday, we may need to generalize this the
* same way we generalized the group name check below.
* That's needed only if we encounter a system where
@@ -135,6 +140,7 @@ DEFINE_TEST(test_read_disk)
failure("group 0 didn't have any of the expected names");
assertEqualString(p, zero_groups[0]);
}
+#endif
}
/* Deregister again and verify the default lookups again. */
diff --git a/lib/libarchive/test/test_read_extract.c b/lib/libarchive/test/test_read_extract.c
index b58b364..887ddfd 100644
--- a/lib/libarchive/test/test_read_extract.c
+++ b/lib/libarchive/test/test_read_extract.c
@@ -32,13 +32,13 @@ DEFINE_TEST(test_read_extract)
{
struct archive_entry *ae;
struct archive *a;
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
struct stat st;
#endif
size_t used;
int i;
char *buff, *file_buff;
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
int fd;
ssize_t bytes_read;
#endif
@@ -138,7 +138,7 @@ DEFINE_TEST(test_read_extract)
assert(0 == archive_read_finish(a));
#endif
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
/* Test the entries on disk. */
/* This first entry was extracted with ARCHIVE_EXTRACT_PERM,
* so the permissions should have been restored exactly,
diff --git a/lib/libarchive/test/test_tar_large.c b/lib/libarchive/test/test_tar_large.c
index f56dc6c..b2b8e5d 100644
--- a/lib/libarchive/test/test_tar_large.c
+++ b/lib/libarchive/test/test_tar_large.c
@@ -53,7 +53,7 @@ struct memblock {
struct memblock *next;
size_t size;
void *buff;
- off_t filebytes;
+ int64_t filebytes;
};
/*
@@ -61,17 +61,17 @@ struct memblock {
* some accounting overhead.
*/
struct memdata {
- off_t filebytes;
+ int64_t filebytes;
void *buff;
struct memblock *first;
struct memblock *last;
};
/* The following size definitions simplify things below. */
-#define KB ((off_t)1024)
-#define MB ((off_t)1024 * KB)
-#define GB ((off_t)1024 * MB)
-#define TB ((off_t)1024 * GB)
+#define KB ((int64_t)1024)
+#define MB ((int64_t)1024 * KB)
+#define GB ((int64_t)1024 * MB)
+#define TB ((int64_t)1024 * GB)
#if ARCHIVE_VERSION_NUMBER < 2000000
static ssize_t memory_read_skip(struct archive *, void *, size_t request);
@@ -100,7 +100,7 @@ memory_write(struct archive *a, void *_private, const void *buff, size_t size)
if ((const char *)filedata <= (const char *)buff
&& (const char *)buff < (const char *)filedata + filedatasize) {
/* We don't need to store a block of file data. */
- private->last->filebytes += (off_t)size;
+ private->last->filebytes += (int64_t)size;
} else {
/* Yes, we're assuming the very first write is metadata. */
/* It's header or metadata, copy and save it. */
@@ -140,7 +140,7 @@ memory_read(struct archive *a, void *_private, const void **buff)
* We're returning file bytes, simulate it by
* passing blocks from the template data.
*/
- if (private->filebytes > (off_t)filedatasize)
+ if (private->filebytes > (int64_t)filedatasize)
size = (ssize_t)filedatasize;
else
size = (ssize_t)private->filebytes;
@@ -202,7 +202,7 @@ memory_read_skip(struct archive *a, void *_private, off_t skip)
DEFINE_TEST(test_tar_large)
{
/* The sizes of the entries we're going to generate. */
- static off_t tests[] = {
+ static int64_t tests[] = {
/* Test for 32-bit signed overflow. */
2 * GB - 1, 2 * GB, 2 * GB + 1,
/* Test for 32-bit unsigned overflow. */
@@ -218,7 +218,8 @@ DEFINE_TEST(test_tar_large)
struct memdata memdata;
struct archive_entry *ae;
struct archive *a;
- off_t filesize, writesize;
+ int64_t filesize;
+ size_t writesize;
filedatasize = (size_t)(1 * MB);
filedata = malloc(filedatasize);
@@ -243,11 +244,6 @@ DEFINE_TEST(test_tar_large)
archive_entry_set_mode(ae, S_IFREG | 0755);
filesize = tests[i];
- if (filesize < 0) {
- archive_entry_free(ae);
- skipping("32-bit off_t doesn't permit testing of very large files.");
- return;
- }
archive_entry_set_size(ae, filesize);
assertA(0 == archive_write_header(a, ae));
@@ -257,10 +253,11 @@ DEFINE_TEST(test_tar_large)
* Write the actual data to the archive.
*/
while (filesize > 0) {
- writesize = (off_t)filedatasize;
- if (writesize > filesize)
- writesize = filesize;
- assertA(writesize == archive_write_data(a, filedata, writesize));
+ writesize = filedatasize;
+ if ((int64_t)writesize > filesize)
+ writesize = (size_t)filesize;
+ assertA((int)writesize
+ == archive_write_data(a, filedata, writesize));
filesize -= writesize;
}
}
diff --git a/lib/libarchive/test/test_write_disk.c b/lib/libarchive/test/test_write_disk.c
index 72c9444..c0b22e5 100644
--- a/lib/libarchive/test/test_write_disk.c
+++ b/lib/libarchive/test/test_write_disk.c
@@ -52,7 +52,7 @@ static void create(struct archive_entry *ae, const char *msg)
* that automatically. */
if (archive_entry_filetype(ae) == AE_IFDIR)
st.st_mode &= ~S_ISGID;
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
assertEqualInt(st.st_mode, archive_entry_mode(ae) & ~UMASK);
#endif
}
@@ -99,7 +99,7 @@ static void create_reg_file(struct archive_entry *ae, const char *msg)
assert(0 == stat(archive_entry_pathname(ae), &st));
failure("st.st_mode=%o archive_entry_mode(ae)=%o",
st.st_mode, archive_entry_mode(ae));
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
#endif
assertEqualInt(st.st_size, sizeof(data));
@@ -146,7 +146,7 @@ static void create_reg_file2(struct archive_entry *ae, const char *msg)
assert(0 == stat(archive_entry_pathname(ae), &st));
failure("st.st_mode=%o archive_entry_mode(ae)=%o",
st.st_mode, archive_entry_mode(ae));
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
#endif
assertEqualInt(st.st_size, i);
@@ -183,7 +183,7 @@ static void create_reg_file3(struct archive_entry *ae, const char *msg)
assert(0 == stat(archive_entry_pathname(ae), &st));
failure("st.st_mode=%o archive_entry_mode(ae)=%o",
st.st_mode, archive_entry_mode(ae));
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
#endif
assertEqualInt(st.st_size, 5);
@@ -212,14 +212,14 @@ static void create_reg_file4(struct archive_entry *ae, const char *msg)
assert(0 == stat(archive_entry_pathname(ae), &st));
failure("st.st_mode=%o archive_entry_mode(ae)=%o",
st.st_mode, archive_entry_mode(ae));
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK));
#endif
failure(msg);
assertEqualInt(st.st_size, sizeof(data));
}
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
static void create_reg_file_win(struct archive_entry *ae, const char *msg)
{
static const char data[]="abcdefghijklmnopqrstuvwxyz";
@@ -257,7 +257,7 @@ static void create_reg_file_win(struct archive_entry *ae, const char *msg)
st.st_mode, archive_entry_mode(ae));
assertEqualInt(st.st_size, sizeof(data));
}
-#endif /* _WIN32 */
+#endif /* _WIN32 && !__CYGWIN__ */
#endif
DEFINE_TEST(test_write_disk)
@@ -326,7 +326,7 @@ DEFINE_TEST(test_write_disk)
create(ae, "Test creating a file over an existing dir.");
archive_entry_free(ae);
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__CYGWIN__)
/* A file with unusable characters in its file name. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "f:i*l?e\"f<i>l|e");
@@ -342,6 +342,6 @@ DEFINE_TEST(test_write_disk)
create_reg_file_win(ae, "Test creating a regular file"
" with unusable characters in its file name");
archive_entry_free(ae);
-#endif /* _WIN32 */
+#endif /* _WIN32 && !__CYGWIN__ */
#endif
}
diff --git a/lib/libarchive/test/test_write_disk_failures.c b/lib/libarchive/test/test_write_disk_failures.c
index 03304d4..0d7b894 100644
--- a/lib/libarchive/test/test_write_disk_failures.c
+++ b/lib/libarchive/test/test_write_disk_failures.c
@@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$");
DEFINE_TEST(test_write_disk_failures)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000 || defined(_WIN32)
+#if ARCHIVE_VERSION_NUMBER < 1009000 || (defined(_WIN32) && !defined(__CYGWIN__))
skipping("archive_write_disk interface");
#else
struct archive_entry *ae;
diff --git a/lib/libarchive/test/test_write_disk_hardlink.c b/lib/libarchive/test/test_write_disk_hardlink.c
index f9bcfae..2ab2420 100644
--- a/lib/libarchive/test/test_write_disk_hardlink.c
+++ b/lib/libarchive/test/test_write_disk_hardlink.c
@@ -25,7 +25,14 @@
#include "test.h"
__FBSDID("$FreeBSD$");
+#if defined(_WIN32) && !defined(__CYGWIN__)
+/* Execution bits, Group members bits and others bits do not work. */
+#define UMASK 0177
+#define E_MASK (~0177)
+#else
#define UMASK 022
+#define E_MASK (~0)
+#endif
/*
* Exercise hardlink recreation.
@@ -36,7 +43,7 @@ __FBSDID("$FreeBSD$");
*/
DEFINE_TEST(test_write_disk_hardlink)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000 || defined(_WIN32)
+#if ARCHIVE_VERSION_NUMBER < 1009000
skipping("archive_write_disk_hardlink tests");
#else
static const char data[]="abcdefghijklmnopqrstuvwxyz";
@@ -175,7 +182,7 @@ DEFINE_TEST(test_write_disk_hardlink)
* doesn't carry data for it, we consider it to be
* non-authoritive for meta data as well. This is consistent
* with GNU tar and BSD pax. */
- assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK);
+ assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
assertEqualInt(st.st_size, sizeof(data));
assertEqualInt(st.st_nlink, 2);
@@ -194,7 +201,7 @@ DEFINE_TEST(test_write_disk_hardlink)
* common file formats that store a size of zero for
* hardlinks. */
assert(0 == stat("link2a", &st));
- assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK);
+ assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
assertEqualInt(st.st_size, sizeof(data));
assertEqualInt(st.st_nlink, 2);
@@ -207,12 +214,12 @@ DEFINE_TEST(test_write_disk_hardlink)
/* Test #3 */
assert(0 == stat("link3a", &st));
- assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK);
+ assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
assertEqualInt(st.st_size, sizeof(data));
assertEqualInt(st.st_nlink, 2);
assert(0 == stat("link3b", &st2));
- assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK);
+ assertEqualInt(st2.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
assertEqualInt(st2.st_size, sizeof(data));
assertEqualInt(st2.st_nlink, 2);
assertEqualInt(st.st_ino, st2.st_ino);
@@ -220,12 +227,12 @@ DEFINE_TEST(test_write_disk_hardlink)
/* Test #4 */
assert(0 == stat("link4a", &st));
- assertEqualInt(st.st_mode, (S_IFREG | 0755) & ~UMASK);
+ assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
assertEqualInt(st.st_size, sizeof(data));
assertEqualInt(st.st_nlink, 2);
assert(0 == stat("link4b", &st2));
- assertEqualInt(st2.st_mode, (S_IFREG | 0755) & ~UMASK);
+ assertEqualInt(st2.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK);
assertEqualInt(st2.st_size, sizeof(data));
assertEqualInt(st2.st_nlink, 2);
assertEqualInt(st.st_ino, st2.st_ino);
diff --git a/lib/libarchive/test/test_write_disk_perms.c b/lib/libarchive/test/test_write_disk_perms.c
index 87e2a2d..3d9be27 100644
--- a/lib/libarchive/test/test_write_disk_perms.c
+++ b/lib/libarchive/test/test_write_disk_perms.c
@@ -25,7 +25,7 @@
#include "test.h"
__FBSDID("$FreeBSD$");
-#if ARCHIVE_VERSION_NUMBER >= 1009000 && !defined(_WIN32)
+#if ARCHIVE_VERSION_NUMBER >= 1009000 && (!defined(_WIN32) || defined(__CYGWIN__))
#define UMASK 022
@@ -125,7 +125,7 @@ defaultgid(void)
DEFINE_TEST(test_write_disk_perms)
{
-#if ARCHIVE_VERSION_NUMBER < 1009000 || defined(_WIN32)
+#if ARCHIVE_VERSION_NUMBER < 1009000 || (defined(_WIN32) && !defined(__CYGWIN__))
skipping("archive_write_disk interface");
#else
struct archive *a;
diff --git a/lib/libarchive/test/test_write_disk_secure.c b/lib/libarchive/test/test_write_disk_secure.c
index 4c014b1..d417489 100644
--- a/lib/libarchive/test/test_write_disk_secure.c
+++ b/lib/libarchive/test/test_write_disk_secure.c
@@ -55,7 +55,7 @@ DEFINE_TEST(test_write_disk_secure)
archive_entry_free(ae);
assert(0 == archive_write_finish_entry(a));
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
/* Write a symlink to the dir above. */
assert((ae = archive_entry_new()) != NULL);
archive_entry_copy_pathname(ae, "link_to_dir");
@@ -187,7 +187,7 @@ DEFINE_TEST(test_write_disk_secure)
assert(0 == archive_write_finish(a));
#endif
-#ifndef _WIN32
+#if !defined(_WIN32) || defined(__CYGWIN__)
/* Test the entries on disk. */
assert(0 == lstat("dir", &st));
failure("dir: st.st_mode=%o", st.st_mode);
OpenPOWER on IntegriCloud