Update libarchive's vendor dist to latest changes in release branch.
Git branch: release Git commit: e2cc36190d7d733b3ac6744ec860d09776c9da02 Obtained from: https://github.com/libarchive/libarchive.git
This commit is contained in:
parent
3d633235ca
commit
b312534184
@ -606,6 +606,37 @@ ELSE(LIBXML2_FOUND)
|
||||
ENDIF(EXPAT_FOUND)
|
||||
ENDIF(LIBXML2_FOUND)
|
||||
|
||||
#
|
||||
# Find Libregex
|
||||
#
|
||||
FIND_PATH(REGEX_INCLUDE_DIR regex.h)
|
||||
IF(REGEX_INCLUDE_DIR)
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBC)
|
||||
#
|
||||
# If libc does not provide regex, find libregex.
|
||||
#
|
||||
IF(NOT HAVE_REGCOMP_LIBC)
|
||||
FIND_LIBRARY(REGEX_LIBRARY regex)
|
||||
IF(REGEX_LIBRARY)
|
||||
SET(CMAKE_REQUIRED_LIBRARIES ${REGEX_LIBRARY})
|
||||
CHECK_FUNCTION_EXISTS_GLIBC(regcomp HAVE_REGCOMP_LIBREGEX)
|
||||
IF(HAVE_REGCOMP_LIBREGEX)
|
||||
LIST(APPEND ADDITIONAL_LIBS ${REGEX_LIBRARY})
|
||||
#
|
||||
# If regex.h is not found, retry looking for regex.h at
|
||||
# REGEX_INCLUDE_DIR
|
||||
#
|
||||
IF(NOT HAVE_REGEX_H)
|
||||
UNSET(HAVE_REGEX_H CACHE)
|
||||
INCLUDE_DIRECTORIES(${REGEX_INCLUDE_DIR})
|
||||
SET(CMAKE_REQUIRED_INCLUDES ${REGEX_INCLUDE_DIR})
|
||||
LA_CHECK_INCLUDE_FILE("regex.h" HAVE_REGEX_H)
|
||||
ENDIF(NOT HAVE_REGEX_H)
|
||||
ENDIF(HAVE_REGCOMP_LIBREGEX)
|
||||
ENDIF(REGEX_LIBRARY)
|
||||
ENDIF(NOT HAVE_REGCOMP_LIBC)
|
||||
ENDIF(REGEX_INCLUDE_DIR)
|
||||
|
||||
#
|
||||
# Check functions
|
||||
#
|
||||
|
@ -322,6 +322,15 @@ if test "x$ac_cv_header_libxml_xmlreader_h" != "xyes"; then
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_ARG_WITH([libregex],
|
||||
AS_HELP_STRING([--without-libregex], [Don't build support for regex through libregex]))
|
||||
|
||||
if test "x$with_libregex" != "xno"; then
|
||||
if test "x$ac_cv_header_regex_h" != "xno"; then
|
||||
AC_CHECK_FUNC(regcomp, , [AC_CHECK_LIB(regex,regcomp)])
|
||||
fi
|
||||
fi
|
||||
|
||||
# TODO: Give the user the option of using a pre-existing system
|
||||
# libarchive. This will define HAVE_LIBARCHIVE which will cause
|
||||
# bsdtar_platform.h to use #include <...> for the libarchive headers.
|
||||
|
66
cpio/cpio.c
66
cpio/cpio.c
@ -119,6 +119,7 @@ static void mode_in(struct cpio *);
|
||||
static void mode_list(struct cpio *);
|
||||
static void mode_out(struct cpio *);
|
||||
static void mode_pass(struct cpio *, const char *);
|
||||
static const char *remove_leading_slash(const char *);
|
||||
static int restore_time(struct cpio *, struct archive_entry *,
|
||||
const char *, int fd);
|
||||
static void usage(void);
|
||||
@ -155,9 +156,9 @@ main(int argc, char *argv[])
|
||||
else {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
lafe_progname = strrchr(*argv, '\\');
|
||||
#else
|
||||
lafe_progname = strrchr(*argv, '/');
|
||||
if (strrchr(*argv, '/') > lafe_progname)
|
||||
#endif
|
||||
lafe_progname = strrchr(*argv, '/');
|
||||
if (lafe_progname != NULL)
|
||||
lafe_progname++;
|
||||
else
|
||||
@ -574,6 +575,49 @@ mode_out(struct cpio *cpio)
|
||||
archive_write_free(cpio->archive);
|
||||
}
|
||||
|
||||
static const char *
|
||||
remove_leading_slash(const char *p)
|
||||
{
|
||||
const char *rp;
|
||||
|
||||
/* Remove leading "//./" or "//?/" or "//?/UNC/"
|
||||
* (absolute path prefixes used by Windows API) */
|
||||
if ((p[0] == '/' || p[0] == '\\') &&
|
||||
(p[1] == '/' || p[1] == '\\') &&
|
||||
(p[2] == '.' || p[2] == '?') &&
|
||||
(p[3] == '/' || p[3] == '\\'))
|
||||
{
|
||||
if (p[2] == '?' &&
|
||||
(p[4] == 'U' || p[4] == 'u') &&
|
||||
(p[5] == 'N' || p[5] == 'n') &&
|
||||
(p[6] == 'C' || p[6] == 'c') &&
|
||||
(p[7] == '/' || p[7] == '\\'))
|
||||
p += 8;
|
||||
else
|
||||
p += 4;
|
||||
}
|
||||
do {
|
||||
rp = p;
|
||||
/* Remove leading drive letter from archives created
|
||||
* on Windows. */
|
||||
if (((p[0] >= 'a' && p[0] <= 'z') ||
|
||||
(p[0] >= 'A' && p[0] <= 'Z')) &&
|
||||
p[1] == ':') {
|
||||
p += 2;
|
||||
}
|
||||
/* Remove leading "/../", "//", etc. */
|
||||
while (p[0] == '/' || p[0] == '\\') {
|
||||
if (p[1] == '.' && p[2] == '.' &&
|
||||
(p[3] == '/' || p[3] == '\\')) {
|
||||
p += 3; /* Remove "/..", leave "/"
|
||||
* for next pass. */
|
||||
} else
|
||||
p += 1; /* Remove "/". */
|
||||
}
|
||||
} while (rp != p);
|
||||
return (p);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used by both out mode (to copy objects from disk into
|
||||
* an archive) and pass mode (to copy objects from disk to
|
||||
@ -585,7 +629,6 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
|
||||
const char *destpath;
|
||||
struct archive_entry *entry, *spare;
|
||||
size_t len;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
/*
|
||||
@ -639,10 +682,7 @@ file_to_archive(struct cpio *cpio, const char *srcpath)
|
||||
"Can't allocate path buffer");
|
||||
}
|
||||
strcpy(cpio->pass_destpath, cpio->destdir);
|
||||
p = srcpath;
|
||||
while (p[0] == '/')
|
||||
++p;
|
||||
strcat(cpio->pass_destpath, p);
|
||||
strcat(cpio->pass_destpath, remove_leading_slash(srcpath));
|
||||
destpath = cpio->pass_destpath;
|
||||
}
|
||||
if (cpio->option_rename)
|
||||
@ -1139,12 +1179,24 @@ cpio_rename(const char *name)
|
||||
static char buff[1024];
|
||||
FILE *t;
|
||||
char *p, *ret;
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
FILE *to;
|
||||
|
||||
t = fopen("CONIN$", "r");
|
||||
if (t == NULL)
|
||||
return (name);
|
||||
to = fopen("CONOUT$", "w");
|
||||
if (to == NULL)
|
||||
return (name);
|
||||
fprintf(to, "%s (Enter/./(new name))? ", name);
|
||||
fclose(to);
|
||||
#else
|
||||
t = fopen("/dev/tty", "r+");
|
||||
if (t == NULL)
|
||||
return (name);
|
||||
fprintf(t, "%s (Enter/./(new name))? ", name);
|
||||
fflush(t);
|
||||
#endif
|
||||
|
||||
p = fgets(buff, sizeof(buff), t);
|
||||
fclose(t);
|
||||
|
@ -2289,7 +2289,15 @@ main(int argc, char **argv)
|
||||
j++;
|
||||
}
|
||||
testprogdir[i] = '\0';
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if (testprogdir[0] != '/' && testprogdir[0] != '\\' &&
|
||||
!(((testprogdir[0] >= 'a' && testprogdir[0] <= 'z') ||
|
||||
(testprogdir[0] >= 'A' && testprogdir[0] <= 'Z')) &&
|
||||
testprogdir[1] == ':' &&
|
||||
(testprogdir[2] == '/' || testprogdir[2] == '\\')))
|
||||
#else
|
||||
if (testprogdir[0] != '/')
|
||||
#endif
|
||||
{
|
||||
/* Fixup path for relative directories. */
|
||||
if ((testprogdir = (char *)realloc(testprogdir,
|
||||
@ -2298,8 +2306,9 @@ main(int argc, char **argv)
|
||||
fprintf(stderr, "ERROR: Out of memory.");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(testprogdir + strlen(pwd) + 1, testprogdir);
|
||||
strcpy(testprogdir, pwd);
|
||||
memmove(testprogdir + strlen(pwd) + 1, testprogdir,
|
||||
strlen(testprogdir));
|
||||
memcpy(testprogdir, pwd, strlen(pwd));
|
||||
testprogdir[strlen(pwd)] = '/';
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ _archive_set_option(struct archive *a,
|
||||
int magic, const char *fn, option_handler use_option)
|
||||
{
|
||||
const char *mp, *op, *vp;
|
||||
int r;
|
||||
|
||||
archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
|
||||
|
||||
@ -47,10 +48,24 @@ _archive_set_option(struct archive *a,
|
||||
|
||||
if (op == NULL && vp == NULL)
|
||||
return (ARCHIVE_OK);
|
||||
if (op == NULL)
|
||||
if (op == NULL) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC, "Empty option");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
|
||||
return use_option(a, mp, op, vp);
|
||||
r = use_option(a, mp, op, vp);
|
||||
if (r == ARCHIVE_WARN - 1) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown module name: `%s'", mp);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_WARN) {
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Undefined option: `%s%s%s%s%s%s'",
|
||||
vp?"":"!", mp?mp:"", mp?":":"", op, vp?"=":"", vp?vp:"");
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
|
||||
int
|
||||
@ -102,6 +117,25 @@ _archive_set_options(struct archive *a, const char *options,
|
||||
free(data);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
if (r == ARCHIVE_FAILED && mod != NULL) {
|
||||
free(data);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_WARN - 1) {
|
||||
/* The module name is wrong. */
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Unknown module name: `%s'", mod);
|
||||
free(data);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_WARN) {
|
||||
/* The option name is wrong. No-one used this. */
|
||||
archive_set_error(a, ARCHIVE_ERRNO_MISC,
|
||||
"Undefined option: `%s%s%s'",
|
||||
mod?mod:"", mod?":":"", opt);
|
||||
free(data);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (r == ARCHIVE_OK)
|
||||
anyok = 1;
|
||||
else
|
||||
|
@ -633,7 +633,7 @@ archive_read_data(struct archive *_a, void *buff, size_t s)
|
||||
}
|
||||
|
||||
/* Compute the amount of zero padding needed. */
|
||||
if (a->read_data_output_offset + s <
|
||||
if (a->read_data_output_offset + (int64_t)s <
|
||||
a->read_data_offset) {
|
||||
len = s;
|
||||
} else if (a->read_data_output_offset <
|
||||
|
@ -64,7 +64,7 @@ pad_to(struct archive *a, int fd, int can_lseek,
|
||||
}
|
||||
while (target_offset > actual_offset) {
|
||||
to_write = nulls_size;
|
||||
if (target_offset < actual_offset + nulls_size)
|
||||
if (target_offset < actual_offset + (int64_t)nulls_size)
|
||||
to_write = (size_t)(target_offset - actual_offset);
|
||||
bytes_written = write(fd, nulls, to_write);
|
||||
if (bytes_written < 0) {
|
||||
|
@ -733,7 +733,7 @@ _archive_read_data_block(struct archive *_a, const void **buff,
|
||||
t->entry_buff_size = t->current_filesystem->buff_size;
|
||||
|
||||
buffbytes = t->entry_buff_size;
|
||||
if (buffbytes > t->current_sparse->length)
|
||||
if ((int64_t)buffbytes > t->current_sparse->length)
|
||||
buffbytes = t->current_sparse->length;
|
||||
|
||||
/*
|
||||
|
@ -78,7 +78,7 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_format_descriptor *format;
|
||||
size_t i;
|
||||
int r, rv = ARCHIVE_FAILED;
|
||||
int r, rv = ARCHIVE_WARN;
|
||||
|
||||
for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
|
||||
format = &a->formats[i];
|
||||
@ -102,6 +102,10 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
|
||||
if (r == ARCHIVE_OK)
|
||||
rv = ARCHIVE_OK;
|
||||
}
|
||||
/* If the format name didn't match, return a special code for
|
||||
* _archive_set_option[s]. */
|
||||
if (rv == ARCHIVE_WARN && m != NULL)
|
||||
rv = ARCHIVE_WARN - 1;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
@ -112,7 +116,7 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
|
||||
struct archive_read *a = (struct archive_read *)_a;
|
||||
struct archive_read_filter *filter;
|
||||
struct archive_read_filter_bidder *bidder;
|
||||
int r, rv = ARCHIVE_FAILED;
|
||||
int r, rv = ARCHIVE_WARN;
|
||||
|
||||
for (filter = a->filter; filter != NULL; filter = filter->upstream) {
|
||||
bidder = filter->bidder;
|
||||
@ -135,6 +139,10 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
|
||||
if (r == ARCHIVE_OK)
|
||||
rv = ARCHIVE_OK;
|
||||
}
|
||||
/* If the filter name didn't match, return a special code for
|
||||
* _archive_set_option[s]. */
|
||||
if (rv == ARCHIVE_WARN && m != NULL)
|
||||
rv = ARCHIVE_WARN - 1;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2010-2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -478,11 +478,13 @@ archive_read_format_cab_options(struct archive_read *a,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"cab: unknown keyword ``%s''", key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -2066,6 +2068,7 @@ lzx_decode_init(struct lzx_stream *strm, int w_bits)
|
||||
struct lzx_dec *ds;
|
||||
int slot, w_size, w_slot;
|
||||
int base, footer;
|
||||
int base_inc[18];
|
||||
|
||||
if (strm->ds == NULL) {
|
||||
strm->ds = calloc(1, sizeof(*strm->ds));
|
||||
@ -2100,13 +2103,15 @@ lzx_decode_init(struct lzx_stream *strm, int w_bits)
|
||||
lzx_huffman_free(&(ds->mt));
|
||||
}
|
||||
|
||||
for (footer = 0; footer < 18; footer++)
|
||||
base_inc[footer] = 1 << footer;
|
||||
base = footer = 0;
|
||||
for (slot = 0; slot < w_slot; slot++) {
|
||||
int n;
|
||||
if (footer == 0)
|
||||
base = slot;
|
||||
else
|
||||
base += 1 << footer;
|
||||
base += base_inc[footer];
|
||||
if (footer < 17) {
|
||||
footer = -2;
|
||||
for (n = base; n; n >>= 1)
|
||||
@ -2180,11 +2185,11 @@ lzx_translation(struct lzx_stream *strm, void *p, size_t size, uint32_t offset)
|
||||
end = b + size - 10;
|
||||
while (b < end && (b = memchr(b, 0xE8, end - b)) != NULL) {
|
||||
size_t i = b - (unsigned char *)p;
|
||||
long cp, displacement, value;
|
||||
int32_t cp, displacement, value;
|
||||
|
||||
cp = offset + i;
|
||||
value = archive_le32dec(&b[1]);
|
||||
if (value >= -cp && value < (long)ds->translation_size) {
|
||||
if (value >= -cp && value < (int32_t)ds->translation_size) {
|
||||
if (value >= 0)
|
||||
displacement = value - cp;
|
||||
else
|
||||
@ -2475,7 +2480,10 @@ lzx_read_blocks(struct lzx_stream *strm, int last)
|
||||
*/
|
||||
/* Skip padding to align following field on
|
||||
* 16-bit boundary. */
|
||||
lzx_br_consume_unalined_bits(br);
|
||||
if (br->cache_avail == 32 || br->cache_avail == 16)
|
||||
lzx_br_consume(br, 16);
|
||||
else
|
||||
lzx_br_consume_unalined_bits(br);
|
||||
/* Preparation to read repeated offsets R0,R1 and R2. */
|
||||
ds->rbytes_avail = 0;
|
||||
ds->state = ST_RD_R0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2010-2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -325,7 +325,7 @@ archive_read_format_cpio_options(struct archive_read *a,
|
||||
if (strcmp(key, "compat-2x") == 0) {
|
||||
/* Handle filnames as libarchive 2.x */
|
||||
cpio->init_default_conversion = (val != NULL)?1:0;
|
||||
ret = ARCHIVE_OK;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "hdrcharset") == 0) {
|
||||
if (val == NULL || val[0] == 0)
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
@ -339,11 +339,13 @@ archive_read_format_cpio_options(struct archive_read *a,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"cpio: unknown keyword ``%s''", key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2008-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -445,11 +445,13 @@ archive_read_format_lha_options(struct archive_read *a,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"lha: unknown keyword ``%s''", key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -757,11 +757,13 @@ archive_read_format_rar_options(struct archive_read *a,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"rar: unknown keyword ``%s''", key);
|
||||
|
||||
return (ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -369,7 +369,7 @@ archive_read_format_tar_options(struct archive_read *a,
|
||||
/* Handle UTF-8 filnames as libarchive 2.x */
|
||||
tar->compat_2x = (val != NULL)?1:0;
|
||||
tar->init_default_conversion = tar->compat_2x;
|
||||
ret = ARCHIVE_OK;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "hdrcharset") == 0) {
|
||||
if (val == NULL || val[0] == 0)
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
@ -383,11 +383,13 @@ archive_read_format_tar_options(struct archive_read *a,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"tar: unknown keyword ``%s''", key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/* utility function- this exists to centralize the logic of tracking
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2004 Tim Kientzle
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -441,7 +441,7 @@ archive_read_format_zip_options(struct archive_read *a,
|
||||
if (strcmp(key, "compat-2x") == 0) {
|
||||
/* Handle filnames as libarchive 2.x */
|
||||
zip->init_default_conversion = (val != NULL) ? 1 : 0;
|
||||
ret = ARCHIVE_OK;
|
||||
return (ARCHIVE_OK);
|
||||
} else if (strcmp(key, "hdrcharset") == 0) {
|
||||
if (val == NULL || val[0] == 0)
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
@ -456,11 +456,13 @@ archive_read_format_zip_options(struct archive_read *a,
|
||||
} else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"zip: unknown keyword ``%s''", key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2011 Tim Kientzle
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -849,7 +849,7 @@ archive_string_append_from_wcs(struct archive_string *as,
|
||||
}
|
||||
}
|
||||
as->length += r;
|
||||
if (wp == NULL || (wp - wpp) >= nwc)
|
||||
if (wp == NULL || (wp - wpp) >= (int64_t)nwc)
|
||||
break;
|
||||
/* Get a remaining WCS lenth. */
|
||||
nwc -= wp - wpp;
|
||||
@ -2333,7 +2333,7 @@ best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
|
||||
{
|
||||
size_t remaining;
|
||||
char *outp;
|
||||
const char *inp;
|
||||
const uint8_t *inp;
|
||||
size_t avail;
|
||||
int return_value = 0; /* success */
|
||||
|
||||
@ -2357,11 +2357,11 @@ best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
|
||||
return (-1);
|
||||
|
||||
remaining = length;
|
||||
inp = (const char *)_p;
|
||||
inp = (const uint8_t *)_p;
|
||||
outp = as->s + as->length;
|
||||
avail = as->buffer_length - as->length -1;
|
||||
while (*inp && remaining > 0) {
|
||||
if (*inp < 0 && (sc->flag & SCONV_TO_UTF8)) {
|
||||
if (*inp > 127 && (sc->flag & SCONV_TO_UTF8)) {
|
||||
if (avail < UTF8_R_CHAR_SIZE) {
|
||||
as->length = outp - as->s;
|
||||
if (NULL == archive_string_ensure(as,
|
||||
@ -2381,13 +2381,13 @@ best_effort_strncat_in_locale(struct archive_string *as, const void *_p,
|
||||
inp++;
|
||||
remaining--;
|
||||
return_value = -1;
|
||||
} else if (*inp < 0) {
|
||||
} else if (*inp > 127) {
|
||||
*outp++ = '?';
|
||||
inp++;
|
||||
remaining--;
|
||||
return_value = -1;
|
||||
} else {
|
||||
*outp++ = *inp++;
|
||||
*outp++ = (char)*inp++;
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@
|
||||
|
||||
#include "archive_platform.h"
|
||||
#include "archive_private.h"
|
||||
#include "archive_entry.h"
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
@ -639,6 +640,113 @@ __la_write(int fd, const void *buf, size_t nbytes)
|
||||
return (bytes_written);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace the Windows path separator '\' with '/'.
|
||||
*/
|
||||
static int
|
||||
replace_pathseparator(struct archive_wstring *ws, const wchar_t *wp)
|
||||
{
|
||||
wchar_t *w;
|
||||
size_t path_length;
|
||||
|
||||
if (wp == NULL)
|
||||
return(0);
|
||||
if (wcschr(wp, L'\\') == NULL)
|
||||
return(0);
|
||||
path_length = wcslen(wp);
|
||||
if (archive_wstring_ensure(ws, path_length) == NULL)
|
||||
return(-1);
|
||||
archive_wstrncpy(ws, wp, path_length);
|
||||
for (w = ws->s; *w; w++) {
|
||||
if (*w == L'\\')
|
||||
*w = L'/';
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
fix_pathseparator(struct archive_entry *entry)
|
||||
{
|
||||
struct archive_wstring ws;
|
||||
const wchar_t *wp;
|
||||
int ret = ARCHIVE_OK;
|
||||
|
||||
archive_string_init(&ws);
|
||||
wp = archive_entry_pathname_w(entry);
|
||||
switch (replace_pathseparator(&ws, wp)) {
|
||||
case 0: /* Not replaced. */
|
||||
break;
|
||||
case 1: /* Replaced. */
|
||||
archive_entry_copy_pathname_w(entry, ws.s);
|
||||
break;
|
||||
default:
|
||||
ret = ARCHIVE_FAILED;
|
||||
}
|
||||
wp = archive_entry_hardlink_w(entry);
|
||||
switch (replace_pathseparator(&ws, wp)) {
|
||||
case 0: /* Not replaced. */
|
||||
break;
|
||||
case 1: /* Replaced. */
|
||||
archive_entry_copy_hardlink_w(entry, ws.s);
|
||||
break;
|
||||
default:
|
||||
ret = ARCHIVE_FAILED;
|
||||
}
|
||||
wp = archive_entry_symlink_w(entry);
|
||||
switch (replace_pathseparator(&ws, wp)) {
|
||||
case 0: /* Not replaced. */
|
||||
break;
|
||||
case 1: /* Replaced. */
|
||||
archive_entry_copy_symlink_w(entry, ws.s);
|
||||
break;
|
||||
default:
|
||||
ret = ARCHIVE_FAILED;
|
||||
}
|
||||
archive_wstring_free(&ws);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
struct archive_entry *
|
||||
__la_win_entry_in_posix_pathseparator(struct archive_entry *entry)
|
||||
{
|
||||
struct archive_entry *entry_main;
|
||||
const wchar_t *wp;
|
||||
int has_backslash = 0;
|
||||
int ret;
|
||||
|
||||
wp = archive_entry_pathname_w(entry);
|
||||
if (wp != NULL && wcschr(wp, L'\\') != NULL)
|
||||
has_backslash = 1;
|
||||
if (!has_backslash) {
|
||||
wp = archive_entry_hardlink_w(entry);
|
||||
if (wp != NULL && wcschr(wp, L'\\') != NULL)
|
||||
has_backslash = 1;
|
||||
}
|
||||
if (!has_backslash) {
|
||||
wp = archive_entry_symlink_w(entry);
|
||||
if (wp != NULL && wcschr(wp, L'\\') != NULL)
|
||||
has_backslash = 1;
|
||||
}
|
||||
/*
|
||||
* If there is no backslach chars, return the original.
|
||||
*/
|
||||
if (!has_backslash)
|
||||
return (entry);
|
||||
|
||||
/* Copy entry so we can modify it as needed. */
|
||||
entry_main = archive_entry_clone(entry);
|
||||
if (entry_main == NULL)
|
||||
return (NULL);
|
||||
/* Replace the Windows path-separator '\' with '/'. */
|
||||
ret = fix_pathseparator(entry_main);
|
||||
if (ret < ARCHIVE_WARN) {
|
||||
archive_entry_free(entry_main);
|
||||
return (NULL);
|
||||
}
|
||||
return (entry_main);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following function was modified from PostgreSQL sources and is
|
||||
* subject to the copyright below.
|
||||
|
@ -261,6 +261,8 @@ extern wchar_t *__la_win_permissive_name(const char *name);
|
||||
extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
|
||||
extern void __la_dosmaperr(unsigned long e);
|
||||
#define la_dosmaperr(e) __la_dosmaperr(e)
|
||||
extern struct archive_entry *__la_win_entry_in_posix_pathseparator(
|
||||
struct archive_entry *);
|
||||
|
||||
|
||||
#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */
|
||||
|
@ -208,6 +208,9 @@ archive_compressor_bzip2_options(struct archive_write_filter *f,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
|
@ -220,6 +220,10 @@ archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
|
||||
data->compression_level = value[0] - '0';
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2009,2010 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2003-2010 Tim Kientzle
|
||||
* Copyright (c) 2009-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -365,6 +365,9 @@ archive_compressor_xz_options(struct archive_write_filter *f,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
|
@ -1434,7 +1434,7 @@ restore_entry(struct archive_write_disk *a)
|
||||
|
||||
if (en) {
|
||||
/* Everything failed; give up here. */
|
||||
archive_set_error(&a->archive, en, "Can't create '%s'",
|
||||
archive_set_error(&a->archive, en, "Can't create '%ls'",
|
||||
a->name);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
@ -1844,7 +1844,7 @@ check_symlinks(struct archive_write_disk *a)
|
||||
*/
|
||||
if (disk_unlink(a->name)) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Could not remove symlink %s",
|
||||
"Could not remove symlink %ls",
|
||||
a->name);
|
||||
pn[0] = c;
|
||||
return (ARCHIVE_FAILED);
|
||||
@ -1858,7 +1858,7 @@ check_symlinks(struct archive_write_disk *a)
|
||||
*/
|
||||
if (!S_ISLNK(a->mode)) {
|
||||
archive_set_error(&a->archive, 0,
|
||||
"Removing symlink %s",
|
||||
"Removing symlink %ls",
|
||||
a->name);
|
||||
}
|
||||
/* Symlink gone. No more problem! */
|
||||
@ -1868,15 +1868,15 @@ check_symlinks(struct archive_write_disk *a)
|
||||
/* User asked us to remove problems. */
|
||||
if (disk_unlink(a->name) != 0) {
|
||||
archive_set_error(&a->archive, 0,
|
||||
"Cannot remove intervening symlink %s",
|
||||
a->name);
|
||||
"Cannot remove intervening "
|
||||
"symlink %ls", a->name);
|
||||
pn[0] = c;
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
a->pst = NULL;
|
||||
} else {
|
||||
archive_set_error(&a->archive, 0,
|
||||
"Cannot extract through symlink %s",
|
||||
"Cannot extract through symlink %ls",
|
||||
a->name);
|
||||
pn[0] = c;
|
||||
return (ARCHIVE_FAILED);
|
||||
@ -2147,19 +2147,20 @@ create_dir(struct archive_write_disk *a, wchar_t *path)
|
||||
return (ARCHIVE_OK);
|
||||
if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
|
||||
archive_set_error(&a->archive, EEXIST,
|
||||
"Can't create directory '%s'", path);
|
||||
"Can't create directory '%ls'", path);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
if (disk_unlink(path) != 0) {
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't create directory '%s': "
|
||||
"Can't create directory '%ls': "
|
||||
"Conflicting file cannot be removed",
|
||||
path);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
} else if (errno != ENOENT && errno != ENOTDIR) {
|
||||
/* Stat failed? */
|
||||
archive_set_error(&a->archive, errno, "Can't test directory '%s'", path);
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't test directory '%ls'", path);
|
||||
return (ARCHIVE_FAILED);
|
||||
} else if (slash != NULL) {
|
||||
*slash = '\0';
|
||||
@ -2211,7 +2212,7 @@ create_dir(struct archive_write_disk *a, wchar_t *path)
|
||||
if (file_information(a, path, &st, &st_mode, 0) == 0 && S_ISDIR(st_mode))
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
|
||||
archive_set_error(&a->archive, errno, "Failed to create dir '%ls'",
|
||||
path);
|
||||
return (ARCHIVE_FAILED);
|
||||
}
|
||||
@ -2240,7 +2241,7 @@ set_ownership(struct archive_write_disk *a)
|
||||
}
|
||||
|
||||
archive_set_error(&a->archive, errno,
|
||||
"Can't set user=%jd/group=%jd for %s",
|
||||
"Can't set user=%jd/group=%jd for %ls",
|
||||
(intmax_t)a->uid, (intmax_t)a->gid, a->name);
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
@ -413,7 +413,10 @@ _7z_options(struct archive_write *a, const char *key, const char *value)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
return (ARCHIVE_FAILED);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1587,7 +1590,8 @@ file_init_register_empty(struct _7zip *zip)
|
||||
zip->empty_list.last = &(zip->empty_list.first);
|
||||
}
|
||||
|
||||
#if !defined(HAVE_BZLIB_H) || !defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
|
||||
#if !defined(HAVE_ZLIB_H) || !defined(HAVE_BZLIB_H) ||\
|
||||
!defined(BZ_CONFIG_ERROR) || !defined(HAVE_LZMA_H)
|
||||
static int
|
||||
compression_unsupported_encoder(struct archive *a,
|
||||
struct la_zstream *lastrm, const char *name)
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -147,11 +148,13 @@ archive_write_cpio_options(struct archive_write *a, const char *key,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"%s: unknown keyword ``%s''", a->format_name, key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -278,18 +281,37 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
int64_t ino;
|
||||
char h[76];
|
||||
struct archive_string_conv *sconv;
|
||||
struct archive_entry *entry_main;
|
||||
size_t len;
|
||||
|
||||
cpio = (struct cpio *)a->format_data;
|
||||
ret_final = ARCHIVE_OK;
|
||||
sconv = get_sconv(a);
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Make sure the path separators in pahtname, hardlink and symlink
|
||||
* are all slash '/', not the Windows path separator '\'. */
|
||||
entry_main = __la_win_entry_in_posix_pathseparator(entry);
|
||||
if (entry_main == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate ustar data");
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
if (entry != entry_main)
|
||||
entry = entry_main;
|
||||
else
|
||||
entry_main = NULL;
|
||||
#else
|
||||
entry_main = NULL;
|
||||
#endif
|
||||
|
||||
ret = archive_entry_pathname_l(entry, &path, &len, sconv);
|
||||
if (ret != 0) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Pathname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Can't translate pathname '%s' to %s",
|
||||
@ -308,11 +330,13 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
if (ino < 0) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"No memory for ino translation table");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
} else if (ino > 0777777) {
|
||||
archive_set_error(&a->archive, ERANGE,
|
||||
"Too many files for this cpio format");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
format_octal(ino & 0777777, h + c_ino_offset, c_ino_size);
|
||||
|
||||
@ -339,7 +363,8 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Linkname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Can't translate linkname '%s' to %s",
|
||||
@ -356,25 +381,35 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
if (ret) {
|
||||
archive_set_error(&a->archive, ERANGE,
|
||||
"File is too large for cpio format.");
|
||||
return (ARCHIVE_FAILED);
|
||||
ret_final = ARCHIVE_FAILED;
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
ret = __archive_write_output(a, h, sizeof(h));
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
ret = __archive_write_output(a, path, pathlength);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
cpio->entry_bytes_remaining = archive_entry_size(entry);
|
||||
|
||||
/* Write the symlink now. */
|
||||
if (p != NULL && *p != '\0') {
|
||||
ret = __archive_write_output(a, p, strlen(p));
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
}
|
||||
exit_write_header:
|
||||
if (entry_main)
|
||||
archive_entry_free(entry_main);
|
||||
return (ret_final);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2006 Rudolf Marek SYSGO s.r.o.
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -154,11 +155,13 @@ archive_write_newc_options(struct archive_write *a, const char *key,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"%s: unknown keyword ``%s''", a->format_name, key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static struct archive_string_conv *
|
||||
@ -220,6 +223,7 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
int pathlength, ret, ret_final;
|
||||
char h[c_header_size];
|
||||
struct archive_string_conv *sconv;
|
||||
struct archive_entry *entry_main;
|
||||
size_t len;
|
||||
int pad;
|
||||
|
||||
@ -227,12 +231,30 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
ret_final = ARCHIVE_OK;
|
||||
sconv = get_sconv(a);
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Make sure the path separators in pahtname, hardlink and symlink
|
||||
* are all slash '/', not the Windows path separator '\'. */
|
||||
entry_main = __la_win_entry_in_posix_pathseparator(entry);
|
||||
if (entry_main == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate ustar data");
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
if (entry != entry_main)
|
||||
entry = entry_main;
|
||||
else
|
||||
entry_main = NULL;
|
||||
#else
|
||||
entry_main = NULL;
|
||||
#endif
|
||||
|
||||
ret = archive_entry_pathname_l(entry, &path, &len, sconv);
|
||||
if (ret != 0) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Pathname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Can't translate pathname '%s' to %s",
|
||||
@ -284,7 +306,8 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Likname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Can't translate linkname '%s' to %s",
|
||||
@ -301,22 +324,29 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
if (ret) {
|
||||
archive_set_error(&a->archive, ERANGE,
|
||||
"File is too large for this format.");
|
||||
return (ARCHIVE_FAILED);
|
||||
ret_final = ARCHIVE_FAILED;
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
ret = __archive_write_output(a, h, c_header_size);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
/* Pad pathname to even length. */
|
||||
ret = __archive_write_output(a, path, pathlength);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
pad = PAD4(pathlength + c_header_size);
|
||||
if (pad) {
|
||||
ret = __archive_write_output(a, "\0\0\0", pad);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
}
|
||||
|
||||
cpio->entry_bytes_remaining = archive_entry_size(entry);
|
||||
@ -325,13 +355,20 @@ write_header(struct archive_write *a, struct archive_entry *entry)
|
||||
/* Write the symlink now. */
|
||||
if (p != NULL && *p != '\0') {
|
||||
ret = __archive_write_output(a, p, strlen(p));
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
pad = PAD4(strlen(p));
|
||||
ret = __archive_write_output(a, "\0\0\0", pad);
|
||||
if (ret != ARCHIVE_OK)
|
||||
return (ARCHIVE_FATAL);
|
||||
if (ret != ARCHIVE_OK) {
|
||||
ret_final = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
}
|
||||
exit_write_header:
|
||||
if (entry_main)
|
||||
archive_entry_free(entry_main);
|
||||
return (ret_final);
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
* Author: Jonas Gastal <jgastal@profusion.mobi>
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -177,7 +177,8 @@ archive_write_set_format_gnutar(struct archive *_a)
|
||||
|
||||
gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar));
|
||||
if (gnutar == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM, "Can't allocate gnutar data");
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate gnutar data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
a->format_data = gnutar;
|
||||
@ -213,11 +214,13 @@ archive_write_gnutar_options(struct archive_write *a, const char *key,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"%s: unknown keyword ``%s''", a->format_name, key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -275,6 +278,7 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
int tartype;
|
||||
struct gnutar *gnutar;
|
||||
struct archive_string_conv *sconv;
|
||||
struct archive_entry *entry_main;
|
||||
|
||||
gnutar = (struct gnutar *)a->format_data;
|
||||
|
||||
@ -298,33 +302,95 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
|
||||
if (AE_IFDIR == archive_entry_filetype(entry)) {
|
||||
const char *p;
|
||||
char *t;
|
||||
size_t path_length;
|
||||
/*
|
||||
* Ensure a trailing '/'. Modify the entry so
|
||||
* the client sees the change.
|
||||
*/
|
||||
p = archive_entry_pathname(entry);
|
||||
if (p[strlen(p) - 1] != '/') {
|
||||
t = (char *)malloc(strlen(p) + 2);
|
||||
if (t == NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
const wchar_t *wp;
|
||||
|
||||
wp = archive_entry_pathname_w(entry);
|
||||
if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
|
||||
struct archive_wstring ws;
|
||||
|
||||
archive_string_init(&ws);
|
||||
path_length = wcslen(wp);
|
||||
if (archive_wstring_ensure(&ws,
|
||||
path_length + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate gnutar data");
|
||||
"Can't allocate ustar data");
|
||||
archive_wstring_free(&ws);
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
strcpy(t, p);
|
||||
strcat(t, "/");
|
||||
archive_entry_copy_pathname(entry, t);
|
||||
free(t);
|
||||
/* Should we keep '\' ? */
|
||||
if (wp[path_length -1] == L'\\')
|
||||
path_length--;
|
||||
archive_wstrncpy(&ws, wp, path_length);
|
||||
archive_wstrappend_wchar(&ws, L'/');
|
||||
archive_entry_copy_pathname_w(entry, ws.s);
|
||||
archive_wstring_free(&ws);
|
||||
p = NULL;
|
||||
} else
|
||||
#endif
|
||||
p = archive_entry_pathname(entry);
|
||||
/*
|
||||
* On Windows, this is a backup operation just in
|
||||
* case getting WCS failed. On POSIX, this is a
|
||||
* normal operation.
|
||||
*/
|
||||
if (p != NULL && p[strlen(p) - 1] != '/') {
|
||||
struct archive_string as;
|
||||
|
||||
archive_string_init(&as);
|
||||
path_length = strlen(p);
|
||||
if (archive_string_ensure(&as,
|
||||
path_length + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate ustar data");
|
||||
archive_string_free(&as);
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* NOTE: This might break the pathname
|
||||
* if the current code page is CP932 and
|
||||
* the pathname includes a character '\'
|
||||
* as a part of its multibyte pathname. */
|
||||
if (p[strlen(p) -1] == '\\')
|
||||
path_length--;
|
||||
else
|
||||
#endif
|
||||
archive_strncpy(&as, p, path_length);
|
||||
archive_strappend_char(&as, '/');
|
||||
archive_entry_copy_pathname(entry, as.s);
|
||||
archive_string_free(&as);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Make sure the path separators in pahtname, hardlink and symlink
|
||||
* are all slash '/', not the Windows path separator '\'. */
|
||||
entry_main = __la_win_entry_in_posix_pathseparator(entry);
|
||||
if (entry_main == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate ustar data");
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
if (entry != entry_main)
|
||||
entry = entry_main;
|
||||
else
|
||||
entry_main = NULL;
|
||||
#else
|
||||
entry_main = NULL;
|
||||
#endif
|
||||
r = archive_entry_pathname_l(entry, &(gnutar->pathname),
|
||||
&(gnutar->pathname_length), sconv);
|
||||
if (r != 0) {
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Pathame");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"Can't translate pathname '%s' to %s",
|
||||
@ -338,7 +404,8 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Uname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -353,7 +420,8 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Gname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -370,7 +438,8 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Linkname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -386,7 +455,8 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
if (errno == ENOMEM) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate memory for Linkname");
|
||||
return (ARCHIVE_FATAL);
|
||||
ret = ARCHIVE_FATAL;
|
||||
goto exit_write_header;
|
||||
}
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -409,18 +479,18 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
archive_entry_set_size(temp, gnutar->linkname_length + 1);
|
||||
ret = archive_format_gnutar_header(a, buff, temp, 'K');
|
||||
if (ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_output(a, buff, 512);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
archive_entry_free(temp);
|
||||
/* Write as many 512 bytes blocks as needed to write full name. */
|
||||
ret = __archive_write_output(a, gnutar->linkname, todo);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
|
||||
if (ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
/* If pathname is longer than 100 chars we need to add an 'L' header. */
|
||||
@ -438,18 +508,18 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
archive_entry_set_size(temp, gnutar->pathname_length + 1);
|
||||
ret = archive_format_gnutar_header(a, buff, temp, 'L');
|
||||
if (ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_output(a, buff, 512);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
archive_entry_free(temp);
|
||||
/* Write as many 512 bytes blocks as needed to write full name. */
|
||||
ret = __archive_write_output(a, pathname, todo);
|
||||
if(ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
ret = __archive_write_nulls(a, 0x1ff & (-(ssize_t)todo));
|
||||
if (ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
if (archive_entry_hardlink(entry) != NULL) {
|
||||
@ -466,28 +536,35 @@ archive_write_gnutar_header(struct archive_write *a,
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"tar format cannot archive socket");
|
||||
return (ARCHIVE_FAILED);
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_write_header;
|
||||
default:
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
"tar format cannot archive this (mode=0%lo)",
|
||||
(unsigned long)archive_entry_mode(entry));
|
||||
return (ARCHIVE_FAILED);
|
||||
ret = ARCHIVE_FAILED;
|
||||
goto exit_write_header;
|
||||
}
|
||||
|
||||
ret = archive_format_gnutar_header(a, buff, entry, tartype);
|
||||
if (ret < ARCHIVE_WARN)
|
||||
return (ret);
|
||||
goto exit_write_header;
|
||||
if (ret2 < ret)
|
||||
ret = ret2;
|
||||
ret2 = __archive_write_output(a, buff, 512);
|
||||
if (ret2 < ARCHIVE_WARN)
|
||||
return (ret2);
|
||||
if (ret2 < ARCHIVE_WARN) {
|
||||
ret = ret2;
|
||||
goto exit_write_header;
|
||||
}
|
||||
if (ret2 < ret)
|
||||
ret = ret2;
|
||||
|
||||
gnutar->entry_bytes_remaining = archive_entry_size(entry);
|
||||
gnutar->entry_padding = 0x1ff & (-(int64_t)gnutar->entry_bytes_remaining);
|
||||
exit_write_header:
|
||||
if (entry_main)
|
||||
archive_entry_free(entry_main);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2009-2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2009-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1507,6 +1507,11 @@ iso9660_options(struct archive_write *a, const char *key, const char *value)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
|
||||
invalid_value:
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"Invalid value for option ``%s''", key);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2009,2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2008 Joerg Sonnenberger
|
||||
* Copyright (c) 2009-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -1222,7 +1222,10 @@ archive_write_mtree_options(struct archive_write *a, const char *key,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
return (ARCHIVE_FAILED);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2010-2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -187,11 +187,13 @@ archive_write_pax_options(struct archive_write *a, const char *key,
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"pax: invalid charset name");
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"pax: unknown keyword ``%s''", key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -463,7 +465,6 @@ archive_write_pax_header(struct archive_write *a,
|
||||
{
|
||||
struct archive_entry *entry_main;
|
||||
const char *p;
|
||||
char *t;
|
||||
const char *suffix;
|
||||
int need_extension, r, ret;
|
||||
int sparse_count;
|
||||
@ -541,24 +542,73 @@ archive_write_pax_header(struct archive_write *a,
|
||||
case AE_IFREG:
|
||||
break;
|
||||
case AE_IFDIR:
|
||||
{
|
||||
/*
|
||||
* Ensure a trailing '/'. Modify the original
|
||||
* entry so the client sees the change.
|
||||
*/
|
||||
p = archive_entry_pathname(entry_original);
|
||||
if (p[strlen(p) - 1] != '/') {
|
||||
t = (char *)malloc(strlen(p) + 2);
|
||||
if (t == NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
const wchar_t *wp;
|
||||
|
||||
wp = archive_entry_pathname_w(entry_original);
|
||||
if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
|
||||
struct archive_wstring ws;
|
||||
|
||||
archive_string_init(&ws);
|
||||
path_length = wcslen(wp);
|
||||
if (archive_wstring_ensure(&ws,
|
||||
path_length + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate pax data");
|
||||
"Can't allocate pax data");
|
||||
archive_wstring_free(&ws);
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
strcpy(t, p);
|
||||
strcat(t, "/");
|
||||
archive_entry_copy_pathname(entry_original, t);
|
||||
free(t);
|
||||
/* Should we keep '\' ? */
|
||||
if (wp[path_length -1] == L'\\')
|
||||
path_length--;
|
||||
archive_wstrncpy(&ws, wp, path_length);
|
||||
archive_wstrappend_wchar(&ws, L'/');
|
||||
archive_entry_copy_pathname_w(
|
||||
entry_original, ws.s);
|
||||
archive_wstring_free(&ws);
|
||||
p = NULL;
|
||||
} else
|
||||
#endif
|
||||
p = archive_entry_pathname(entry_original);
|
||||
/*
|
||||
* On Windows, this is a backup operation just in
|
||||
* case getting WCS failed. On POSIX, this is a
|
||||
* normal operation.
|
||||
*/
|
||||
if (p != NULL && p[strlen(p) - 1] != '/') {
|
||||
struct archive_string as;
|
||||
|
||||
archive_string_init(&as);
|
||||
path_length = strlen(p);
|
||||
if (archive_string_ensure(&as,
|
||||
path_length + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate pax data");
|
||||
archive_string_free(&as);
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* NOTE: This might break the pathname
|
||||
* if the current code page is CP932 and
|
||||
* the pathname includes a character '\'
|
||||
* as a part of its multibyte pathname. */
|
||||
if (p[strlen(p) -1] == '\\')
|
||||
path_length--;
|
||||
else
|
||||
#endif
|
||||
archive_strncpy(&as, p, path_length);
|
||||
archive_strappend_char(&as, '/');
|
||||
archive_entry_copy_pathname(
|
||||
entry_original, as.s);
|
||||
archive_string_free(&as);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AE_IFSOCK:
|
||||
archive_set_error(&a->archive,
|
||||
ARCHIVE_ERRNO_FILE_FORMAT,
|
||||
@ -655,7 +705,20 @@ archive_write_pax_header(struct archive_write *a,
|
||||
}
|
||||
|
||||
/* Copy entry so we can modify it as needed. */
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Make sure the path separators in pahtname, hardlink and symlink
|
||||
* are all slash '/', not the Windows path separator '\'. */
|
||||
entry_main = __la_win_entry_in_posix_pathseparator(entry_original);
|
||||
if (entry_main == entry_original)
|
||||
entry_main = archive_entry_clone(entry_original);
|
||||
#else
|
||||
entry_main = archive_entry_clone(entry_original);
|
||||
#endif
|
||||
if (entry_main == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate pax data");
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
archive_string_empty(&(pax->pax_header)); /* Blank our work area. */
|
||||
archive_string_empty(&(pax->sparse_map));
|
||||
sparse_total = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 2003-2007 Tim Kientzle
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -224,11 +224,13 @@ archive_write_ustar_options(struct archive_write *a, const char *key,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"%s: unknown keyword ``%s''", a->format_name, key);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (ret);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -237,6 +239,7 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
|
||||
char buff[512];
|
||||
int ret, ret2;
|
||||
struct ustar *ustar;
|
||||
struct archive_entry *entry_main;
|
||||
struct archive_string_conv *sconv;
|
||||
|
||||
ustar = (struct ustar *)a->format_data;
|
||||
@ -267,37 +270,106 @@ archive_write_ustar_header(struct archive_write *a, struct archive_entry *entry)
|
||||
|
||||
if (AE_IFDIR == archive_entry_filetype(entry)) {
|
||||
const char *p;
|
||||
char *t;
|
||||
size_t path_length;
|
||||
/*
|
||||
* Ensure a trailing '/'. Modify the entry so
|
||||
* the client sees the change.
|
||||
*/
|
||||
p = archive_entry_pathname(entry);
|
||||
if (p[strlen(p) - 1] != '/') {
|
||||
t = (char *)malloc(strlen(p) + 2);
|
||||
if (t == NULL) {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
const wchar_t *wp;
|
||||
|
||||
wp = archive_entry_pathname_w(entry);
|
||||
if (wp != NULL && wp[wcslen(wp) -1] != L'/') {
|
||||
struct archive_wstring ws;
|
||||
|
||||
archive_string_init(&ws);
|
||||
path_length = wcslen(wp);
|
||||
if (archive_wstring_ensure(&ws,
|
||||
path_length + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate ustar data");
|
||||
"Can't allocate ustar data");
|
||||
archive_wstring_free(&ws);
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
strcpy(t, p);
|
||||
strcat(t, "/");
|
||||
archive_entry_copy_pathname(entry, t);
|
||||
free(t);
|
||||
/* Should we keep '\' ? */
|
||||
if (wp[path_length -1] == L'\\')
|
||||
path_length--;
|
||||
archive_wstrncpy(&ws, wp, path_length);
|
||||
archive_wstrappend_wchar(&ws, L'/');
|
||||
archive_entry_copy_pathname_w(entry, ws.s);
|
||||
archive_wstring_free(&ws);
|
||||
p = NULL;
|
||||
} else
|
||||
#endif
|
||||
p = archive_entry_pathname(entry);
|
||||
/*
|
||||
* On Windows, this is a backup operation just in
|
||||
* case getting WCS failed. On POSIX, this is a
|
||||
* normal operation.
|
||||
*/
|
||||
if (p != NULL && p[strlen(p) - 1] != '/') {
|
||||
struct archive_string as;
|
||||
|
||||
archive_string_init(&as);
|
||||
path_length = strlen(p);
|
||||
if (archive_string_ensure(&as,
|
||||
path_length + 2) == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate ustar data");
|
||||
archive_string_free(&as);
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* NOTE: This might break the pathname
|
||||
* if the current code page is CP932 and
|
||||
* the pathname includes a character '\'
|
||||
* as a part of its multibyte pathname. */
|
||||
if (p[strlen(p) -1] == '\\')
|
||||
path_length--;
|
||||
else
|
||||
#endif
|
||||
archive_strncpy(&as, p, path_length);
|
||||
archive_strappend_char(&as, '/');
|
||||
archive_entry_copy_pathname(entry, as.s);
|
||||
archive_string_free(&as);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Make sure the path separators in pahtname, hardlink and symlink
|
||||
* are all slash '/', not the Windows path separator '\'. */
|
||||
entry_main = __la_win_entry_in_posix_pathseparator(entry);
|
||||
if (entry_main == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate ustar data");
|
||||
return(ARCHIVE_FATAL);
|
||||
}
|
||||
if (entry != entry_main)
|
||||
entry = entry_main;
|
||||
else
|
||||
entry_main = NULL;
|
||||
#else
|
||||
entry_main = NULL;
|
||||
#endif
|
||||
ret = __archive_write_format_header_ustar(a, buff, entry, -1, 1, sconv);
|
||||
if (ret < ARCHIVE_WARN)
|
||||
if (ret < ARCHIVE_WARN) {
|
||||
if (entry_main)
|
||||
archive_entry_free(entry_main);
|
||||
return (ret);
|
||||
}
|
||||
ret2 = __archive_write_output(a, buff, 512);
|
||||
if (ret2 < ARCHIVE_WARN)
|
||||
if (ret2 < ARCHIVE_WARN) {
|
||||
if (entry_main)
|
||||
archive_entry_free(entry_main);
|
||||
return (ret2);
|
||||
}
|
||||
if (ret2 < ret)
|
||||
ret = ret2;
|
||||
|
||||
ustar->entry_bytes_remaining = archive_entry_size(entry);
|
||||
ustar->entry_padding = 0x1ff & (-(int64_t)ustar->entry_bytes_remaining);
|
||||
if (entry_main)
|
||||
archive_entry_free(entry_main);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2010-2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2010-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -498,7 +498,10 @@ xar_options(struct archive_write *a, const char *key, const char *value)
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
return (ARCHIVE_FAILED);
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2008 Anselm Strauss
|
||||
* Copyright (c) 2009 Joerg Sonnenberger
|
||||
* Copyright (c) 2011 Michihiro NAKAJIMA
|
||||
* Copyright (c) 2011-2012 Michihiro NAKAJIMA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -238,6 +238,7 @@ archive_write_zip_options(struct archive_write *a, const char *key,
|
||||
zip->compression = COMPRESSION_STORE;
|
||||
ret = ARCHIVE_OK;
|
||||
}
|
||||
return (ret);
|
||||
} else if (strcmp(key, "hdrcharset") == 0) {
|
||||
if (val == NULL || val[0] == 0) {
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
@ -251,10 +252,13 @@ archive_write_zip_options(struct archive_write *a, const char *key,
|
||||
else
|
||||
ret = ARCHIVE_FATAL;
|
||||
}
|
||||
} else
|
||||
archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
|
||||
"%s: unknown keyword ``%s''", a->format_name, key);
|
||||
return (ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
return (ARCHIVE_WARN);
|
||||
}
|
||||
|
||||
int
|
||||
@ -381,7 +385,21 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
|
||||
"Can't allocate zip header data");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
/* Make sure the path separators in pahtname, hardlink and symlink
|
||||
* are all slash '/', not the Windows path separator '\'. */
|
||||
l->entry = __la_win_entry_in_posix_pathseparator(entry);
|
||||
if (l->entry == entry)
|
||||
l->entry = archive_entry_clone(entry);
|
||||
#else
|
||||
l->entry = archive_entry_clone(entry);
|
||||
#endif
|
||||
if (l->entry == NULL) {
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
"Can't allocate zip header data");
|
||||
free(l);
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
l->flags = zip->flags;
|
||||
if (zip->opt_sconv != NULL)
|
||||
sconv = zip->opt_sconv;
|
||||
|
@ -79,10 +79,12 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
|
||||
|
||||
if (a->format_name == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
/* If the format name didn't match, return a special code for
|
||||
* _archive_set_option[s]. */
|
||||
if (m != NULL && strcmp(m, a->format_name) != 0)
|
||||
return (ARCHIVE_FAILED);
|
||||
return (ARCHIVE_WARN - 1);
|
||||
if (a->format_options == NULL)
|
||||
return (ARCHIVE_FAILED);
|
||||
return (ARCHIVE_WARN);
|
||||
return a->format_options(a, o, v);
|
||||
}
|
||||
|
||||
@ -92,7 +94,7 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
|
||||
{
|
||||
struct archive_write *a = (struct archive_write *)_a;
|
||||
struct archive_write_filter *filter;
|
||||
int r, rv = ARCHIVE_FAILED;
|
||||
int r, rv = ARCHIVE_WARN;
|
||||
|
||||
for (filter = a->filter_first; filter != NULL; filter = filter->next_filter) {
|
||||
if (filter->options == NULL)
|
||||
@ -111,6 +113,10 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
|
||||
if (r == ARCHIVE_OK)
|
||||
rv = ARCHIVE_OK;
|
||||
}
|
||||
/* If the filter name didn't match, return a special code for
|
||||
* _archive_set_option[s]. */
|
||||
if (rv == ARCHIVE_WARN && m != NULL)
|
||||
rv = ARCHIVE_WARN - 1;
|
||||
return (rv);
|
||||
}
|
||||
|
||||
|
@ -2287,7 +2287,15 @@ main(int argc, char **argv)
|
||||
j++;
|
||||
}
|
||||
testprogdir[i] = '\0';
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if (testprogdir[0] != '/' && testprogdir[0] != '\\' &&
|
||||
!(((testprogdir[0] >= 'a' && testprogdir[0] <= 'z') ||
|
||||
(testprogdir[0] >= 'A' && testprogdir[0] <= 'Z')) &&
|
||||
testprogdir[1] == ':' &&
|
||||
(testprogdir[2] == '/' || testprogdir[2] == '\\')))
|
||||
#else
|
||||
if (testprogdir[0] != '/')
|
||||
#endif
|
||||
{
|
||||
/* Fixup path for relative directories. */
|
||||
if ((testprogdir = (char *)realloc(testprogdir,
|
||||
@ -2296,8 +2304,9 @@ main(int argc, char **argv)
|
||||
fprintf(stderr, "ERROR: Out of memory.");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(testprogdir + strlen(pwd) + 1, testprogdir);
|
||||
strcpy(testprogdir, pwd);
|
||||
memmove(testprogdir + strlen(pwd) + 1, testprogdir,
|
||||
strlen(testprogdir));
|
||||
memcpy(testprogdir, pwd, strlen(pwd));
|
||||
testprogdir[strlen(pwd)] = '/';
|
||||
}
|
||||
|
||||
|
@ -33,14 +33,13 @@ static void
|
||||
test(int pristine)
|
||||
{
|
||||
struct archive* a = archive_read_new();
|
||||
int halfempty_options_rv = pristine ? ARCHIVE_WARN : ARCHIVE_OK;
|
||||
int halfempty_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
|
||||
int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
|
||||
int mixed_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_WARN;
|
||||
|
||||
if (!pristine) {
|
||||
archive_read_support_filter_all(a);
|
||||
archive_read_support_format_all(a);
|
||||
}
|
||||
}
|
||||
|
||||
/* NULL and "" denote `no option', so they're ok no matter
|
||||
* what, if any, formats are registered */
|
||||
@ -49,25 +48,73 @@ test(int pristine)
|
||||
|
||||
/* unknown modules and options */
|
||||
should(a, ARCHIVE_FAILED, "fubar:snafu");
|
||||
assertEqualString("Unknown module name: `fubar'",
|
||||
archive_error_string(a));
|
||||
should(a, ARCHIVE_FAILED, "fubar:snafu=betcha");
|
||||
assertEqualString("Unknown module name: `fubar'",
|
||||
archive_error_string(a));
|
||||
|
||||
/* unknown modules and options */
|
||||
should(a, ARCHIVE_FAILED, "snafu");
|
||||
assertEqualString("Undefined option: `snafu'",
|
||||
archive_error_string(a));
|
||||
should(a, ARCHIVE_FAILED, "snafu=betcha");
|
||||
assertEqualString("Undefined option: `snafu'",
|
||||
archive_error_string(a));
|
||||
|
||||
/* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
|
||||
/* ARCHIVE_OK with iso9660 loaded, ARCHIVE_FAILED otherwise */
|
||||
should(a, known_option_rv, "iso9660:joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Unknown module name: `iso9660'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, known_option_rv, "iso9660:joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Unknown module name: `iso9660'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, known_option_rv, "joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, known_option_rv, "!joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
should(a, ARCHIVE_OK, ",");
|
||||
should(a, ARCHIVE_OK, ",,");
|
||||
|
||||
should(a, halfempty_options_rv, ",joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, halfempty_options_rv, "joliet,");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
should(a, mixed_options_rv, "joliet,snafu");
|
||||
should(a, ARCHIVE_FAILED, "joliet,snafu");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
} else {
|
||||
assertEqualString("Undefined option: `snafu'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
should(a, ARCHIVE_FAILED, "iso9660:snafu");
|
||||
if (pristine) {
|
||||
assertEqualString("Unknown module name: `iso9660'",
|
||||
archive_error_string(a));
|
||||
} else {
|
||||
assertEqualString("Undefined option: `iso9660:snafu'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
archive_read_finish(a);
|
||||
}
|
||||
|
@ -33,14 +33,13 @@ static void
|
||||
test(int pristine)
|
||||
{
|
||||
struct archive* a = archive_write_new();
|
||||
int halfempty_options_rv = pristine ? ARCHIVE_WARN : ARCHIVE_OK;
|
||||
int halfempty_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
|
||||
int known_option_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_OK;
|
||||
int mixed_options_rv = pristine ? ARCHIVE_FAILED : ARCHIVE_WARN;
|
||||
|
||||
if (!pristine) {
|
||||
archive_write_set_compression_gzip(a);
|
||||
archive_write_set_format_iso9660(a);
|
||||
}
|
||||
}
|
||||
|
||||
/* NULL and "" denote `no option', so they're ok no matter
|
||||
* what, if any, formats are registered */
|
||||
@ -49,25 +48,73 @@ test(int pristine)
|
||||
|
||||
/* unknown modules and options */
|
||||
should(a, ARCHIVE_FAILED, "fubar:snafu");
|
||||
assertEqualString("Unknown module name: `fubar'",
|
||||
archive_error_string(a));
|
||||
should(a, ARCHIVE_FAILED, "fubar:snafu=betcha");
|
||||
assertEqualString("Unknown module name: `fubar'",
|
||||
archive_error_string(a));
|
||||
|
||||
/* unknown modules and options */
|
||||
should(a, ARCHIVE_FAILED, "snafu");
|
||||
assertEqualString("Undefined option: `snafu'",
|
||||
archive_error_string(a));
|
||||
should(a, ARCHIVE_FAILED, "snafu=betcha");
|
||||
assertEqualString("Undefined option: `snafu'",
|
||||
archive_error_string(a));
|
||||
|
||||
/* ARCHIVE_OK with iso9660 loaded, ARCHIVE_WARN otherwise */
|
||||
/* ARCHIVE_OK with iso9660 loaded, ARCHIVE_FAILED otherwise */
|
||||
should(a, known_option_rv, "iso9660:joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Unknown module name: `iso9660'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, known_option_rv, "iso9660:joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Unknown module name: `iso9660'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, known_option_rv, "joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, known_option_rv, "!joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
should(a, ARCHIVE_OK, ",");
|
||||
should(a, ARCHIVE_OK, ",,");
|
||||
|
||||
should(a, halfempty_options_rv, ",joliet");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
should(a, halfempty_options_rv, "joliet,");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
should(a, mixed_options_rv, "joliet,snafu");
|
||||
should(a, ARCHIVE_FAILED, "joliet,snafu");
|
||||
if (pristine) {
|
||||
assertEqualString("Undefined option: `joliet'",
|
||||
archive_error_string(a));
|
||||
} else {
|
||||
assertEqualString("Undefined option: `snafu'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
should(a, ARCHIVE_FAILED, "iso9660:snafu");
|
||||
if (pristine) {
|
||||
assertEqualString("Unknown module name: `iso9660'",
|
||||
archive_error_string(a));
|
||||
} else {
|
||||
assertEqualString("Undefined option: `iso9660:snafu'",
|
||||
archive_error_string(a));
|
||||
}
|
||||
|
||||
archive_write_finish(a);
|
||||
}
|
||||
|
@ -40,6 +40,15 @@ DEFINE_TEST(test_write_compress_program)
|
||||
skipping("Cannot run 'gzip'");
|
||||
return;
|
||||
}
|
||||
/* NOTE: Setting blocksize=1024 will cause gunzip failure because
|
||||
* it add extra bytes that gunzip ignores with its warning and
|
||||
* exit code 1. So we should set blocksize=1 in order not to
|
||||
* yield the extra bytes when using gunzip. */
|
||||
assert((a = archive_read_new()) != NULL);
|
||||
r = archive_read_support_filter_gzip(a);
|
||||
if (r != ARCHIVE_OK && canGunzip())
|
||||
blocksize = 1;
|
||||
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
|
||||
|
||||
/* Create a new archive in memory. */
|
||||
/* Write it through an external "gzip" program. */
|
||||
|
@ -183,9 +183,9 @@ main(int argc, char **argv)
|
||||
else {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
lafe_progname = strrchr(*argv, '\\');
|
||||
#else
|
||||
lafe_progname = strrchr(*argv, '/');
|
||||
if (strrchr(*argv, '/') > lafe_progname)
|
||||
#endif
|
||||
lafe_progname = strrchr(*argv, '/');
|
||||
if (lafe_progname != NULL)
|
||||
lafe_progname++;
|
||||
else
|
||||
|
@ -2289,7 +2289,15 @@ main(int argc, char **argv)
|
||||
j++;
|
||||
}
|
||||
testprogdir[i] = '\0';
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
if (testprogdir[0] != '/' && testprogdir[0] != '\\' &&
|
||||
!(((testprogdir[0] >= 'a' && testprogdir[0] <= 'z') ||
|
||||
(testprogdir[0] >= 'A' && testprogdir[0] <= 'Z')) &&
|
||||
testprogdir[1] == ':' &&
|
||||
(testprogdir[2] == '/' || testprogdir[2] == '\\')))
|
||||
#else
|
||||
if (testprogdir[0] != '/')
|
||||
#endif
|
||||
{
|
||||
/* Fixup path for relative directories. */
|
||||
if ((testprogdir = (char *)realloc(testprogdir,
|
||||
@ -2298,8 +2306,9 @@ main(int argc, char **argv)
|
||||
fprintf(stderr, "ERROR: Out of memory.");
|
||||
exit(1);
|
||||
}
|
||||
strcpy(testprogdir + strlen(pwd) + 1, testprogdir);
|
||||
strcpy(testprogdir, pwd);
|
||||
memmove(testprogdir + strlen(pwd) + 1, testprogdir,
|
||||
strlen(testprogdir));
|
||||
memcpy(testprogdir, pwd, strlen(pwd));
|
||||
testprogdir[strlen(pwd)] = '/';
|
||||
}
|
||||
|
||||
|
@ -55,33 +55,35 @@ DEFINE_TEST(test_option_s)
|
||||
* Test 1: Filename substitution when creating archives.
|
||||
*/
|
||||
assertMakeDir("test1", 0755);
|
||||
systemf("%s -cf - -s /foo/bar/ in/d1/foo | %s -xf - -C test1",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test1_1.tar -s /foo/bar/ in/d1/foo", testprog);
|
||||
systemf("%s -xf test1_1.tar -C test1", testprog);
|
||||
assertFileContents("foo", 3, "test1/in/d1/bar");
|
||||
systemf("%s -cf - -s /d1/d2/ in/d1/foo | %s -xf - -C test1",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test1_2.tar -s /d1/d2/ in/d1/foo", testprog);
|
||||
systemf("%s -xf test1_2.tar -C test1", testprog);
|
||||
assertFileContents("foo", 3, "test1/in/d2/foo");
|
||||
|
||||
/*
|
||||
* Test 2: Basic substitution when extracting archive.
|
||||
*/
|
||||
assertMakeDir("test2", 0755);
|
||||
systemf("%s -cf - in/d1/foo | %s -xf - -s /foo/bar/ -C test2",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test2.tar in/d1/foo", testprog);
|
||||
systemf("%s -xf test2.tar -s /foo/bar/ -C test2", testprog);
|
||||
assertFileContents("foo", 3, "test2/in/d1/bar");
|
||||
|
||||
/*
|
||||
* Test 3: Files with empty names shouldn't be archived.
|
||||
*/
|
||||
systemf("%s -cf - -s ,in/d1/foo,, in/d1/foo | %s -tvf - > in.lst",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test3.tar -s ,in/d1/foo,, in/d1/foo", testprog);
|
||||
systemf("%s -tvf test3.tar > in.lst", testprog);
|
||||
assertEmptyFile("in.lst");
|
||||
|
||||
/*
|
||||
* Test 4: Multiple substitutions when extracting archive.
|
||||
*/
|
||||
assertMakeDir("test4", 0755);
|
||||
systemf("%s -cf - in/d1/foo in/d1/bar | %s -xf - -s /foo/bar/ -s }bar}baz} -C test4",
|
||||
systemf("%s -cf test4.tar in/d1/foo in/d1/bar",
|
||||
testprog, testprog);
|
||||
systemf("%s -xf test4.tar -s /foo/bar/ -s }bar}baz} -C test4",
|
||||
testprog, testprog);
|
||||
assertFileContents("foo", 3, "test4/in/d1/bar");
|
||||
assertFileContents("bar", 3, "test4/in/d1/baz");
|
||||
@ -90,7 +92,9 @@ DEFINE_TEST(test_option_s)
|
||||
* Test 5: Name-switching substitutions when extracting archive.
|
||||
*/
|
||||
assertMakeDir("test5", 0755);
|
||||
systemf("%s -cf - in/d1/foo in/d1/bar | %s -xf - -s /foo/bar/ -s }bar}foo} -C test5",
|
||||
systemf("%s -cf test5.tar in/d1/foo in/d1/bar",
|
||||
testprog, testprog);
|
||||
systemf("%s -xf test5.tar -s /foo/bar/ -s }bar}foo} -C test5",
|
||||
testprog, testprog);
|
||||
assertFileContents("foo", 3, "test5/in/d1/bar");
|
||||
assertFileContents("bar", 3, "test5/in/d1/foo");
|
||||
@ -140,13 +144,13 @@ DEFINE_TEST(test_option_s)
|
||||
*/
|
||||
/* At extraction time. */
|
||||
assertMakeDir("test8a", 0755);
|
||||
systemf("%s -cf - in/d1 | %s -xf - -s /d1/d2/ -C test8a",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test8a.tar in/d1", testprog);
|
||||
systemf("%s -xf test8a.tar -s /d1/d2/ -C test8a", testprog);
|
||||
assertIsHardlink("test8a/in/d2/hardlink1", "test8a/in/d2/hardlink2");
|
||||
/* At creation time. */
|
||||
assertMakeDir("test8b", 0755);
|
||||
systemf("%s -cf - -s /d1/d2/ in/d1 | %s -xf - -C test8b",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test8b.tar -s /d1/d2/ in/d1", testprog);
|
||||
systemf("%s -xf test8b.tar -C test8b", testprog);
|
||||
assertIsHardlink("test8b/in/d2/hardlink1", "test8b/in/d2/hardlink2");
|
||||
|
||||
/*
|
||||
@ -154,23 +158,27 @@ DEFINE_TEST(test_option_s)
|
||||
*/
|
||||
/* At extraction. (assuming hardlink2 is the hardlink entry) */
|
||||
assertMakeDir("test9a", 0755);
|
||||
systemf("%s -cf - in/d1 | %s -xf - -s /hardlink1/hardlink1-renamed/ -C test9a",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test9a.tar in/d1", testprog);
|
||||
systemf("%s -xf test9a.tar -s /hardlink1/hardlink1-renamed/ -C test9a",
|
||||
testprog);
|
||||
assertIsHardlink("test9a/in/d1/hardlink1-renamed", "test9a/in/d1/hardlink2");
|
||||
/* At extraction. (assuming hardlink1 is the hardlink entry) */
|
||||
assertMakeDir("test9b", 0755);
|
||||
systemf("%s -cf - in/d1 | %s -xf - -s /hardlink2/hardlink2-renamed/ -C test9b",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test9b.tar in/d1", testprog);
|
||||
systemf("%s -xf test9b.tar -s /hardlink2/hardlink2-renamed/ -C test9b",
|
||||
testprog);
|
||||
assertIsHardlink("test9b/in/d1/hardlink1", "test9b/in/d1/hardlink2-renamed");
|
||||
/* At creation. (assuming hardlink2 is the hardlink entry) */
|
||||
assertMakeDir("test9c", 0755);
|
||||
systemf("%s -cf - -s /hardlink1/hardlink1-renamed/ in/d1 | %s -xf - -C test9c",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test9c.tar -s /hardlink1/hardlink1-renamed/ in/d1",
|
||||
testprog);
|
||||
systemf("%s -xf test9c.tar -C test9c", testprog);
|
||||
assertIsHardlink("test9c/in/d1/hardlink1-renamed", "test9c/in/d1/hardlink2");
|
||||
/* At creation. (assuming hardlink1 is the hardlink entry) */
|
||||
assertMakeDir("test9d", 0755);
|
||||
systemf("%s -cf - -s /hardlink2/hardlink2-renamed/ in/d1 | %s -xf - -C test9d",
|
||||
testprog, testprog);
|
||||
systemf("%s -cf test9d.tar -s /hardlink2/hardlink2-renamed/ in/d1",
|
||||
testprog);
|
||||
systemf("%s -xf test9d.tar -C test9d", testprog);
|
||||
assertIsHardlink("test9d/in/d1/hardlink1", "test9d/in/d1/hardlink2-renamed");
|
||||
|
||||
/*
|
||||
@ -224,8 +232,8 @@ DEFINE_TEST(test_option_s)
|
||||
*/
|
||||
extract_reference_file("test_option_s.tar.Z");
|
||||
assertMakeDir("test12a", 0755);
|
||||
systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/H -s /foo/hardlink1/ -C test12a",
|
||||
testprog);
|
||||
systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/H -s /foo/hardlink1/ %s -C test12a",
|
||||
testprog, canSymlink()?"":"--exclude in/d1/symlink");
|
||||
assertFileContents("foo", 3, "test12a/in/d1/hardlink1");
|
||||
assertFileContents("hardlinkedfile", 14, "test12a/in/d1/foo");
|
||||
assertFileContents("foo", 3, "test12a/in/d1/hardlink2");
|
||||
@ -243,8 +251,8 @@ DEFINE_TEST(test_option_s)
|
||||
*/
|
||||
extract_reference_file("test_option_s.tar.Z");
|
||||
assertMakeDir("test13a", 0755);
|
||||
systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/Rh -s /foo/hardlink1/Rh -C test13a",
|
||||
testprog);
|
||||
systemf("%s -xf test_option_s.tar.Z -s /hardlink1/foo/Rh -s /foo/hardlink1/Rh %s -C test13a",
|
||||
testprog, canSymlink()?"":"--exclude in/d1/symlink");
|
||||
assertFileContents("foo", 3, "test13a/in/d1/foo");
|
||||
assertFileContents("hardlinkedfile", 14, "test13a/in/d1/hardlink1");
|
||||
assertFileContents("foo", 3, "test13a/in/d1/hardlink2");
|
||||
|
Loading…
Reference in New Issue
Block a user