summaryrefslogtreecommitdiff
path: root/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
diff options
context:
space:
mode:
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c')
-rw-r--r--Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c78
1 files changed, 58 insertions, 20 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
index d06c391a8..a9bfa808c 100644
--- a/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
+++ b/Utilities/cmlibarchive/libarchive/archive_write_set_format_cpio_newc.c
@@ -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,37 +324,51 @@ 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);
- cpio->padding = PAD4(cpio->entry_bytes_remaining);
+ cpio->padding = (int)PAD4(cpio->entry_bytes_remaining);
/* 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);
}
@@ -343,7 +380,7 @@ archive_write_newc_data(struct archive_write *a, const void *buff, size_t s)
cpio = (struct cpio *)a->format_data;
if (s > cpio->entry_bytes_remaining)
- s = cpio->entry_bytes_remaining;
+ s = (size_t)cpio->entry_bytes_remaining;
ret = __archive_write_output(a, buff, s);
cpio->entry_bytes_remaining -= s;
@@ -416,5 +453,6 @@ archive_write_newc_finish_entry(struct archive_write *a)
struct cpio *cpio;
cpio = (struct cpio *)a->format_data;
- return (__archive_write_nulls(a, cpio->entry_bytes_remaining + cpio->padding));
+ return (__archive_write_nulls(a,
+ (size_t)cpio->entry_bytes_remaining + cpio->padding));
}