diff options
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.c | 78 |
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)); } |