diff options
Diffstat (limited to 'lib/libarchive')
21 files changed, 250 insertions, 220 deletions
diff --git a/lib/libarchive/archive.h b/lib/libarchive/archive.h index 23b9a9de3666..da31d4030e3d 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 e1d35c540d0f..8f1fa2f00adb 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 37fc37b49911..4cafce27067c 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 93925a94bd50..a2748fdff67a 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 9c96f1946aed..68e80747f62f 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 44632558cfa7..d405e3b78d56 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 120c12783feb..111dcb1291de 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 0d841561ee55..60fa227ad586 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 39f58910bad6..532942539d94 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 3615021881ec..e612f3be9225 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 2910a0d82c74..0043030dd244 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 62a0a3f0f9ce..01a081705ef1 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 fcac91ad285e..539c8262cb5f 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 e368398e4689..ce10440df54b 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 b58b364a8418..887ddfde6852 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 f56dc6c0fe81..b2b8e5dbfdc7 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 72c94443cc43..c0b22e58a125 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 03304d4f0037..0d7b894b4ecd 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 f9bcfae6cbc2..2ab242093a61 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 87e2a2d168aa..3d9be27e5964 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 4c014b164057..d41748907b8f 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); |