]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Switch archive_string character set conversion over to use iconv()
authorTim Kientzle <kientzle@gmail.com>
Mon, 7 Mar 2011 03:55:37 +0000 (22:55 -0500)
committerTim Kientzle <kientzle@gmail.com>
Mon, 7 Mar 2011 03:55:37 +0000 (22:55 -0500)
when it's available.
See Issue 66 and Issue 132 for more discussion.

SVN-Revision: 2992

25 files changed:
CMakeLists.txt
build/cmake/config.h.in
configure.ac
libarchive/archive_acl.c
libarchive/archive_acl_private.h
libarchive/archive_entry.c
libarchive/archive_entry.h
libarchive/archive_entry_private.h
libarchive/archive_private.h
libarchive/archive_read.c
libarchive/archive_read_disk_posix.c
libarchive/archive_read_support_format_cab.c
libarchive/archive_read_support_format_lha.c
libarchive/archive_string.c
libarchive/archive_string.h
libarchive/archive_string_sprintf.c
libarchive/archive_util.c
libarchive/archive_write.c
libarchive/archive_write_disk.c
libarchive/archive_write_set_format_cpio.c
libarchive/archive_write_set_format_gnutar.c
libarchive/archive_write_set_format_iso9660.c
libarchive/archive_write_set_format_pax.c
libarchive/archive_write_set_format_xar.c
libarchive/test/test_pax_filename_encoding_freebsd.c

index bccb62c4f59e6ebd99e24f3c298defe30a3e5d4e..8df0708937942902a3343370fb7801d6c32cbb7f 100644 (file)
@@ -441,6 +441,25 @@ CHECK_MD(SHA384 "LIBC;LIBC2;LIBC3;LIBSYSTEM;OPENSSL")
 CHECK_MD(SHA512 "LIBC;LIBC2;LIBC3;LIBSYSTEM;OPENSSL")
 CHECK_HASH_WIN("MD5;SHA1;SHA256;SHA384;SHA512")
 
+#
+# Find iconv
+#
+LA_CHECK_INCLUDE_FILE("iconv.h" HAVE_ICONV_H)   
+IF(HAVE_ICONV_H)
+  FIND_PATH(ICONV_INCLUDE_DIR iconv.h) 
+ENDIF(HAVE_ICONV_H)
+CHECK_FUNCTION_EXISTS(iconv HAVE_ICONV_IN_LIBC) 
+IF(HAVE_ICONV_IN_LIBC)
+  SET(HAVE_ICONV true)
+ELSE(HAVE_ICONV_IN_LIBC)
+  # iconv isn't in libc, try libiconv
+  CHECK_LIBRARY_EXISTS(iconv iconv "" HAVE_ICONV_IN_LIBICONV)
+  IF(HAVE_ICONV_IN_LIBICONV)
+    SET(HAVE_ICONV true) 
+    LIST(APPEND ADDITIONAL_LIBS "iconv")
+  ENDIF(HAVE_ICONV_IN_LIBICONV)
+ENDIF(HAVE_ICONV_IN_LIBC)
+
 #
 # Find Libxml2
 #
@@ -450,10 +469,6 @@ IF(LIBXML2_FOUND)
   LIST(APPEND ADDITIONAL_LIBS ${LIBXML2_LIBRARIES})
   SET(HAVE_LIBXML2 1)
   # libxml2's include files use iconv.h
-  # We need a directory path of iconv.h so that it won't fail to check
-  # "libxml/xmlreader.h".
-  FIND_PATH(ICONV_INCLUDE_DIR iconv.h)
-  INCLUDE_DIRECTORIES(${ICONV_INCLUDE_DIR})
   SET(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
   CHECK_INCLUDE_FILES("libxml/xmlreader.h" HAVE_LIBXML_XMLREADER_H)
   CHECK_INCLUDE_FILES("libxml/xmlwriter.h" HAVE_LIBXML_XMLWRITER_H)
@@ -466,7 +481,7 @@ ELSE(LIBXML2_FOUND)
   IF(EXPAT_FOUND)
     INCLUDE_DIRECTORIES(${EXPAT_INCLUDE_DIR})
     LIST(APPEND ADDITIONAL_LIBS ${EXPAT_LIBRARIES})
-    SET(HAVE_LIBEXPAT 1)
+   SET(HAVE_LIBEXPAT 1)
     LA_CHECK_INCLUDE_FILE("expat.h" HAVE_EXPAT_H)
   ENDIF(EXPAT_FOUND)
 ENDIF(LIBXML2_FOUND)
@@ -768,8 +783,6 @@ ENDIF(HAVE_SIZEOF_WCHAR_T)
 #
 CHECK_FILE_OFFSET_BITS()
 
-
-
 #
 # Check for Extended Attribute libraries, headers, and functions
 #
@@ -778,7 +791,7 @@ IF(ENABLE_XATTR)
   LA_CHECK_INCLUDE_FILE(sys/xattr.h      HAVE_SYS_XATTR_H)
   LA_CHECK_INCLUDE_FILE(sys/extattr.h      HAVE_SYS_EXTATTR_H)
   CHECK_LIBRARY_EXISTS(attr "setxattr" "" HAVE_ATTR_LIB)
 IF(HAVE_ATTR_LIB)
+ IF(HAVE_ATTR_LIB)
     SET(CMAKE_REQUIRED_LIBRARIES "attr")
   ENDIF(HAVE_ATTR_LIB)
   CHECK_SYMBOL_EXISTS(EXTATTR_NAMESPACE_USER "sys/types.h;sys/extattr.h" HAVE_DECL_EXTATTR_NAMESPACE_USER)
index 1ee8de69c4cf3a626c10e7c4ab2f65c567698612..0d11590324d36e90800f528f0aed05960aa385ca 100644 (file)
@@ -492,6 +492,12 @@ typedef uint64_t uintmax_t;
 /* Define to 1 if you have the <grp.h> header file. */
 #cmakedefine HAVE_GRP_H 1
 
+/* Define to 1 if you have the `iconv' function. */
+#cmakedefine HAVE_ICONV 1
+
+/* Define to 1 if you have the <iconv.h> header file. */
+#cmakedefine HAVE_ICONV_H 1
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #cmakedefine HAVE_INTTYPES_H 1
 
index da4c667776a76f30bd138561250e731760c5b7e5..d198af2e8d87ef776a93afdcf0d4568da424893c 100644 (file)
@@ -195,7 +195,7 @@ esac
 AC_HEADER_DIRENT
 AC_HEADER_SYS_WAIT
 AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h copyfile.h ctype.h errno.h])
-AC_CHECK_HEADERS([ext2fs/ext2_fs.h fcntl.h grp.h])
+AC_CHECK_HEADERS([ext2fs/ext2_fs.h fcntl.h grp.h iconv.h])
 AC_CHECK_HEADERS([inttypes.h io.h langinfo.h limits.h])
 AC_CHECK_HEADERS([linux/fiemap.h linux/fs.h linux/magic.h])
 AC_CHECK_HEADERS([locale.h paths.h poll.h pwd.h regex.h signal.h stdarg.h])
@@ -427,7 +427,7 @@ AC_CHECK_FUNCS([chflags chown chroot ctime_r])
 AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fdopendir fork])
 AC_CHECK_FUNCS([fstat fstatat fstatfs fstatvfs ftruncate futimens futimes])
 AC_CHECK_FUNCS([geteuid getpid getgrgid_r getgrnam_r])
-AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r])
+AC_CHECK_FUNCS([getpwnam_r getpwuid_r getvfsbyname gmtime_r iconv])
 AC_CHECK_FUNCS([lchflags lchmod lchown link localtime_r lstat])
 AC_CHECK_FUNCS([lutimes mbrtowc memmove memset mkdir mkfifo mknod mkstemp])
 AC_CHECK_FUNCS([nl_langinfo openat pipe poll readlink readlinkat])
index 41591766211cfca6d163e69638265d0e76ac6a0f..c01372182182b553b32bedc34a84ca5fcd4b02e9 100644 (file)
@@ -314,7 +314,7 @@ archive_acl_reset(struct archive_acl *acl, int want_type)
  * standard permissions and include them in the returned list.
  */
 int
-archive_acl_next(struct archive_acl *acl, int want_type, int *type,
+archive_acl_next(struct archive *a, struct archive_acl *acl, int want_type, int *type,
     int *permset, int *tag, int *id, const char **name)
 {
        *name = NULL;
@@ -370,7 +370,7 @@ archive_acl_next(struct archive_acl *acl, int want_type, int *type,
        *permset = acl->acl_p->permset;
        *tag = acl->acl_p->tag;
        *id = acl->acl_p->id;
-       *name = archive_mstring_get_mbs(&acl->acl_p->name);
+       *name = archive_mstring_get_mbs(a, &acl->acl_p->name);
        acl->acl_p = acl->acl_p->next;
        return (ARCHIVE_OK);
 }
@@ -380,7 +380,7 @@ archive_acl_next(struct archive_acl *acl, int want_type, int *type,
  * the style of the generated ACL.
  */
 const wchar_t *
-archive_acl_text_w(struct archive_acl *acl, int flags)
+archive_acl_text_w(struct archive *a, struct archive_acl *acl, int flags)
 {
        int count;
        size_t length;
@@ -408,7 +408,7 @@ archive_acl_text_w(struct archive_acl *acl, int flags)
                                length += 8; /* "default:" */
                        length += 5; /* tag name */
                        length += 1; /* colon */
-                       wname = archive_mstring_get_wcs(&ap->name);
+                       wname = archive_mstring_get_wcs(a, &ap->name);
                        if (wname != NULL)
                                length += wcslen(wname);
                        else
@@ -450,7 +450,7 @@ archive_acl_text_w(struct archive_acl *acl, int flags)
                ap = acl->acl_head;
                while (ap != NULL) {
                        if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
-                               wname = archive_mstring_get_wcs(&ap->name);
+                               wname = archive_mstring_get_wcs(a, &ap->name);
                                *wp++ = separator;
                                if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
                                        id = ap->id;
@@ -474,7 +474,7 @@ archive_acl_text_w(struct archive_acl *acl, int flags)
                count = 0;
                while (ap != NULL) {
                        if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) {
-                               wname = archive_mstring_get_wcs(&ap->name);
+                               wname = archive_mstring_get_wcs(a, &ap->name);
                                if (count > 0)
                                        *wp++ = separator;
                                if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)
index d86f433ef15827d584559f2abbf521668ba36323..4a967a8540ba82b58ec78199bc82f395a4a5014e 100644 (file)
@@ -56,14 +56,14 @@ void archive_acl_clear(struct archive_acl *);
 void archive_acl_copy(struct archive_acl *, struct archive_acl *);
 int archive_acl_count(struct archive_acl *, int);
 int archive_acl_reset(struct archive_acl *, int);
-int archive_acl_next(struct archive_acl *, int,
+int archive_acl_next(struct archive *, struct archive_acl *, int,
     int *, int *, int *, int *, const char **);
 
 int archive_acl_add_entry(struct archive_acl *, int, int, int, int, const char *);
 int archive_acl_add_entry_w_len(struct archive_acl *,
     int, int, int, int, const wchar_t *, size_t);
 
-const wchar_t *archive_acl_text_w(struct archive_acl *, int);
+const wchar_t *archive_acl_text_w(struct archive *, struct archive_acl *, int);
 
 /*
  * Private ACL parser.  This is private because it handles some
index 3f56bde3795150c29e789bcb69f7e3988b5bdd02..17ba5b64874a566f41ceee7964fcb073f8d4924f 100644 (file)
@@ -180,13 +180,17 @@ archive_entry_clone(struct archive_entry *entry)
        const void *p;
 
        /* Allocate new structure and copy over all of the fields. */
-       entry2 = archive_entry_new();
+       /* TODO: Should we copy the archive over?  Or require a new archive
+        * as an argument? */
+       entry2 = archive_entry_new2(entry->archive);
        if (entry2 == NULL)
                return (NULL);
        entry2->ae_stat = entry->ae_stat;
        entry2->ae_fflags_set = entry->ae_fflags_set;
        entry2->ae_fflags_clear = entry->ae_fflags_clear;
 
+       /* TODO: XXX If clone can have a different archive, what do we do here if
+        * character sets are different? XXX */
        archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text);
        archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname);
        archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink);
@@ -231,6 +235,12 @@ archive_entry_free(struct archive_entry *entry)
 
 struct archive_entry *
 archive_entry_new(void)
+{
+       return archive_entry_new2(NULL);
+}
+
+struct archive_entry *
+archive_entry_new2(struct archive *a)
 {
        struct archive_entry *entry;
 
@@ -238,6 +248,7 @@ archive_entry_new(void)
        if (entry == NULL)
                return (NULL);
        memset(entry, 0, sizeof(*entry));
+       entry->archive = a;
        return (entry);
 }
 
@@ -356,7 +367,7 @@ archive_entry_fflags_text(struct archive_entry *entry)
        const char *f;
        char *p;
 
-       f = archive_mstring_get_mbs(&entry->ae_fflags_text);
+       f = archive_mstring_get_mbs(entry->archive, &entry->ae_fflags_text);
        if (f != NULL)
                return (f);
 
@@ -369,7 +380,7 @@ archive_entry_fflags_text(struct archive_entry *entry)
 
        archive_mstring_copy_mbs(&entry->ae_fflags_text, p);
        free(p);
-       f = archive_mstring_get_mbs(&entry->ae_fflags_text);
+       f = archive_mstring_get_mbs(entry->archive, &entry->ae_fflags_text);
        return (f);
 }
 
@@ -387,20 +398,20 @@ archive_entry_gid(struct archive_entry *entry)
 const char *
 archive_entry_gname(struct archive_entry *entry)
 {
-       return (archive_mstring_get_mbs(&entry->ae_gname));
+       return (archive_mstring_get_mbs(entry->archive, &entry->ae_gname));
 }
 
 const wchar_t *
 archive_entry_gname_w(struct archive_entry *entry)
 {
-       return (archive_mstring_get_wcs(&entry->ae_gname));
+       return (archive_mstring_get_wcs(entry->archive, &entry->ae_gname));
 }
 
 const char *
 archive_entry_hardlink(struct archive_entry *entry)
 {
        if (entry->ae_set & AE_SET_HARDLINK)
-               return (archive_mstring_get_mbs(&entry->ae_hardlink));
+               return (archive_mstring_get_mbs(entry->archive, &entry->ae_hardlink));
        return (NULL);
 }
 
@@ -408,7 +419,7 @@ const wchar_t *
 archive_entry_hardlink_w(struct archive_entry *entry)
 {
        if (entry->ae_set & AE_SET_HARDLINK)
-               return (archive_mstring_get_wcs(&entry->ae_hardlink));
+               return (archive_mstring_get_wcs(entry->archive, &entry->ae_hardlink));
        return (NULL);
 }
 
@@ -465,13 +476,13 @@ archive_entry_nlink(struct archive_entry *entry)
 const char *
 archive_entry_pathname(struct archive_entry *entry)
 {
-       return (archive_mstring_get_mbs(&entry->ae_pathname));
+       return (archive_mstring_get_mbs(entry->archive, &entry->ae_pathname));
 }
 
 const wchar_t *
 archive_entry_pathname_w(struct archive_entry *entry)
 {
-       return (archive_mstring_get_wcs(&entry->ae_pathname));
+       return (archive_mstring_get_wcs(entry->archive, &entry->ae_pathname));
 }
 
 mode_t
@@ -523,14 +534,14 @@ archive_entry_size_is_set(struct archive_entry *entry)
 const char *
 archive_entry_sourcepath(struct archive_entry *entry)
 {
-       return (archive_mstring_get_mbs(&entry->ae_sourcepath));
+       return (archive_mstring_get_mbs(entry->archive, &entry->ae_sourcepath));
 }
 
 const char *
 archive_entry_symlink(struct archive_entry *entry)
 {
        if (entry->ae_set & AE_SET_SYMLINK)
-               return (archive_mstring_get_mbs(&entry->ae_symlink));
+               return (archive_mstring_get_mbs(entry->archive, &entry->ae_symlink));
        return (NULL);
 }
 
@@ -538,7 +549,7 @@ const wchar_t *
 archive_entry_symlink_w(struct archive_entry *entry)
 {
        if (entry->ae_set & AE_SET_SYMLINK)
-               return (archive_mstring_get_wcs(&entry->ae_symlink));
+               return (archive_mstring_get_wcs(entry->archive, &entry->ae_symlink));
        return (NULL);
 }
 
@@ -556,13 +567,13 @@ archive_entry_uid(struct archive_entry *entry)
 const char *
 archive_entry_uname(struct archive_entry *entry)
 {
-       return (archive_mstring_get_mbs(&entry->ae_uname));
+       return (archive_mstring_get_mbs(entry->archive, &entry->ae_uname));
 }
 
 const wchar_t *
 archive_entry_uname_w(struct archive_entry *entry)
 {
-       return (archive_mstring_get_wcs(&entry->ae_uname));
+       return (archive_mstring_get_wcs(entry->archive, &entry->ae_uname));
 }
 
 /*
@@ -637,7 +648,7 @@ archive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name)
 int
 archive_entry_update_gname_utf8(struct archive_entry *entry, const char *name)
 {
-       return (archive_mstring_update_utf8(&entry->ae_gname, name));
+       return (archive_mstring_update_utf8(entry->archive, &entry->ae_gname, name));
 }
 
 #if ARCHIVE_VERSION_NUMBER < 3000000
@@ -700,7 +711,7 @@ archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *targ
                entry->ae_set |= AE_SET_HARDLINK;
        else
                entry->ae_set &= ~AE_SET_HARDLINK;
-       return (archive_mstring_update_utf8(&entry->ae_hardlink, target));
+       return (archive_mstring_update_utf8(entry->archive, &entry->ae_hardlink, target));
 }
 
 void
@@ -812,9 +823,9 @@ int
 archive_entry_update_link_utf8(struct archive_entry *entry, const char *target)
 {
        if (entry->ae_set & AE_SET_SYMLINK)
-               return (archive_mstring_update_utf8(&entry->ae_symlink, target));
+               return (archive_mstring_update_utf8(entry->archive, &entry->ae_symlink, target));
        else
-               return (archive_mstring_update_utf8(&entry->ae_hardlink, target));
+               return (archive_mstring_update_utf8(entry->archive, &entry->ae_hardlink, target));
 }
 
 void
@@ -869,7 +880,7 @@ archive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name)
 int
 archive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name)
 {
-       return (archive_mstring_update_utf8(&entry->ae_pathname, name));
+       return (archive_mstring_update_utf8(entry->archive, &entry->ae_pathname, name));
 }
 
 void
@@ -962,7 +973,7 @@ archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkn
                entry->ae_set |= AE_SET_SYMLINK;
        else
                entry->ae_set &= ~AE_SET_SYMLINK;
-       return (archive_mstring_update_utf8(&entry->ae_symlink, linkname));
+       return (archive_mstring_update_utf8(entry->archive, &entry->ae_symlink, linkname));
 }
 
 #if ARCHIVE_VERSION_NUMBER < 3000000
@@ -998,7 +1009,7 @@ archive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name)
 int
 archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name)
 {
-       return (archive_mstring_update_utf8(&entry->ae_uname, name));
+       return (archive_mstring_update_utf8(entry->archive, &entry->ae_uname, name));
 }
 
 const void *
@@ -1095,7 +1106,7 @@ int
 archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
     int *permset, int *tag, int *id, const char **name)
 {
-       return archive_acl_next(&entry->acl, want_type, type, permset, tag, id, name);
+       return archive_acl_next(entry->archive, &entry->acl, want_type, type, permset, tag, id, name);
 }
 
 /*
@@ -1105,7 +1116,7 @@ archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type,
 const wchar_t *
 archive_entry_acl_text_w(struct archive_entry *entry, int flags)
 {
-       return archive_acl_text_w(&entry->acl, flags);
+       return archive_acl_text_w(entry->archive, &entry->acl, flags);
 }
 
 /*
index 7587e1519ca6cbd5a8310b1e58a472ad3e8e806e..c2b9d6f6c079609d0b76257801e1d15d96310e3a 100644 (file)
@@ -125,6 +125,7 @@ extern "C" {
  * applications (e.g., a package manager could attach special
  * package-management attributes to each entry).
  */
+struct archive;
 struct archive_entry;
 
 /*
@@ -167,6 +168,15 @@ __LA_DECL struct archive_entry     *archive_entry_clone(struct archive_entry *);
 __LA_DECL void                  archive_entry_free(struct archive_entry *);
 __LA_DECL struct archive_entry *archive_entry_new(void);
 
+/*
+ * This form of archive_entry_new2() will pull character-set
+ * conversion information from the specified archive handle.  The
+ * older archive_entry_new(void) form is equivalent to calling
+ * archive_entry_new2(NULL) and will result in the use of an internal
+ * default character-set conversion.
+ */
+__LA_DECL struct archive_entry *archive_entry_new2(struct archive *);
+
 /*
  * Retrieve fields from an archive_entry.
  *
index 8c65d52f6d0f392551aee10b0323be8839e85e2c..6aa73e1bc0a51a5257f78fda3afaab2256b640c1 100644 (file)
@@ -71,6 +71,8 @@ struct ae_sparse {
  * TODO: Design a good API for handling sparse files.
  */
 struct archive_entry {
+       struct archive *archive;
+
        /*
         * Note that ae_stat.st_mode & AE_IFMT  can be  0!
         *
index ab148ee935f64ae498a982eddb419273029e7a61..888c828897e9c699fc7953d7fc4f96ba1ba657f1 100644 (file)
 #ifndef ARCHIVE_PRIVATE_H_INCLUDED
 #define        ARCHIVE_PRIVATE_H_INCLUDED
 
+#if HAVE_ICONV_H
+#include <iconv.h>
+#endif
+
 #include "archive.h"
 #include "archive_string.h"
 
@@ -107,6 +111,12 @@ struct archive {
        int               archive_error_number;
        const char       *error;
        struct archive_string   error_string;
+
+#if HAVE_ICONV
+       iconv_t          unicode_to_current;
+       iconv_t          current_to_unicode;
+       char *current_code;
+#endif
 };
 
 /* Check magic value and state; return(ARCHIVE_FATAL) if it isn't valid. */
index caa3a09f4e5b86716e17186d1fa0e4518338ca30..b1f36f42dba54d5e994aaf445eef5e56aac5cb65 100644 (file)
@@ -110,7 +110,7 @@ archive_read_new(void)
        a->archive.magic = ARCHIVE_READ_MAGIC;
 
        a->archive.state = ARCHIVE_STATE_NEW;
-       a->entry = archive_entry_new();
+       a->entry = archive_entry_new2(&a->archive);
        a->archive.vtable = archive_read_vtable();
 
        return (&a->archive);
@@ -857,6 +857,7 @@ _archive_read_free(struct archive *_a)
        if (a->entry)
                archive_entry_free(a->entry);
        a->archive.magic = 0;
+       __archive_clean(&a->archive);
        free(a);
        return (r);
 }
index b7f211cc096340c9c607b17969a7d489eec539d6..98803cc76b39cf35cc7ed9b4bd4f89125125b4c0 100644 (file)
@@ -490,6 +490,7 @@ _archive_read_free(struct archive *_a)
                (a->cleanup_uname)(a->lookup_uname_data);
        archive_string_free(&a->archive.error_string);
        a->archive.magic = 0;
+       __archive_clean(&a->archive);
        free(a);
        return (r);
 }
index 3aa06d49b81497f53814cf8da590635309f9c673..ddf1419848f3c3a26cac99914512a4fac8303666 100644 (file)
@@ -525,8 +525,8 @@ cab_read_ahead_remaining(struct archive_read *a, size_t min, ssize_t *avail)
 
 /* Convert a path separator '\' -> '/' */
 static void
-cab_convert_path_separator(struct cab *cab, struct archive_string *pathname,
-    unsigned char attr)
+cab_convert_path_separator(struct archive_read *a, struct cab *cab,
+    struct archive_string *pathname, unsigned char attr)
 {
        int l, r;
 
@@ -534,7 +534,7 @@ cab_convert_path_separator(struct cab *cab, struct archive_string *pathname,
                return;
 
        if ((attr & ATTR_NAME_IS_UTF) != 0 ||
-           archive_wstrcpy_mbs(&(cab->ws), pathname) != 0) {
+           archive_wstrcpy_mbs(&a->archive, &(cab->ws), pathname) != 0) {
                for (l = 0; pathname->s[l] != '\0'; l++) {
                        if (pathname->s[l] == '\\')
                                pathname->s[l] = '/';
@@ -551,7 +551,7 @@ cab_convert_path_separator(struct cab *cab, struct archive_string *pathname,
        }
        if (r) {
                archive_string_empty(&cab->mbs);
-               archive_strappend_w_mbs(&cab->mbs, cab->ws.s);
+               archive_strappend_w_mbs(&a->archive, &cab->mbs, cab->ws.s);
                /* If mbs length is different to pathname, we broke the
                 * pathname. We shouldn't use it. */
                if (archive_strlen(&cab->mbs) == archive_strlen(pathname))
@@ -756,8 +756,7 @@ cab_read_header(struct archive_read *a)
                __archive_read_consume(a, len + 1);
                cab->cab_offset += len + 1;
                /* Convert a path separator '\' -> '/' */
-               cab_convert_path_separator(cab, &(file->pathname),
-                   file->attr);
+               cab_convert_path_separator(a, cab, &(file->pathname), file->attr);
 
                /*
                 * Sanity check if each data is acceptable.
index b6920ad188d87657385c71508bd6ae7c48edb91f..24f8a213c6c6eaf425028c20eca2a1d9b44a7520 100644 (file)
@@ -669,7 +669,7 @@ archive_read_format_lha_read_header(struct archive_read *a,
  * set for a filename in an archive.
  */
 static void
-lha_replace_path_separator(struct lha *lha, struct archive_string *fn)
+lha_replace_path_separator(struct archive_read *a, struct lha *lha, struct archive_string *fn)
 {
        size_t i;
 
@@ -688,7 +688,7 @@ lha_replace_path_separator(struct lha *lha, struct archive_string *fn)
         */
 
        /* If converting to wide character failed, force a replacement. */
-       if (!archive_wstrcpy_mbs(&(lha->ws), fn)) {
+       if (!archive_wstrcpy_mbs(&a->archive, &(lha->ws), fn)) {
                for (i = 0; i < archive_strlen(fn); i++) {
                        if (fn->s[i] == '\\')
                                fn->s[i] = '/';
@@ -705,7 +705,7 @@ lha_replace_path_separator(struct lha *lha, struct archive_string *fn)
         * Sanity check that we surely did not break a filename.
         */
        archive_string_empty(&(lha->mbs));
-       archive_strappend_w_mbs(&(lha->mbs), lha->ws.s);
+       archive_strappend_w_mbs(&a->archive, &(lha->mbs), lha->ws.s);
        /* If mbs length is different to fn, we broke the
         * filename and we shouldn't use it. */
        if (archive_strlen(&(lha->mbs)) == archive_strlen(fn))
@@ -768,7 +768,7 @@ lha_read_file_header_0(struct archive_read *a, struct lha *lha)
                return (truncated_error(a));
 
        archive_strncpy(&lha->filename, p + H0_FILE_NAME_OFFSET, namelen);
-       lha_replace_path_separator(lha, &lha->filename);
+       lha_replace_path_separator(a, lha, &lha->filename);
        lha->crc = archive_le16dec(p + H0_FILE_NAME_OFFSET + namelen);
        sum_calculated = lha_calcsum(0, p, 2, lha->header_size - 2);
 
index e73c7512bbf44e0f6fab50bdf5ba7de1e7a33b20..d257781ac861a31b505fe9e9cdf5c94017a6b1a8 100644 (file)
@@ -35,6 +35,15 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
  * without incurring additional memory allocations.
  */
 
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_ICONV_H
+#include <iconv.h>
+#endif
+#ifdef HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
 #endif
@@ -51,6 +60,12 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_string.c 201095 2009-12-28 02:33
 #include "archive_private.h"
 #include "archive_string.h"
 
+#if SIZEOF_WCHAR_T == 2
+#define __LA_UNICODE "UCS-2-INTERNAL"
+#else
+#define __LA_UNICODE "UCS-4-INTERNAL"
+#endif
+
 static struct archive_string *
 archive_string_append(struct archive_string *as, const char *p, size_t s)
 {
@@ -238,9 +253,23 @@ archive_wstrappend_wchar(struct archive_wstring *as, wchar_t c)
 }
 
 /*
- * 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.
+ * Character set conversion functions.
+ *
+ * Conversions involving MBS use the "current locale" as
+ * stored in the archive object passed in.  Conversions
+ * between UTF8 and Unicode do not require any such help,
+ * of course.
+ *
+ * TODO: Provide utility functions to set the current locale.
+ * Remember that Windows stores character encoding as an int,
+ * POSIX typically uses a string.  I'd rather not bother trying
+ * to translate between the two.
+ */
+
+/*
+ * Unicode to UTF-8.
+ * Note: returns NULL if conversion fails, but still leaves a best-effort
+ * conversion in the argument as.
  */
 struct archive_string *
 archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
@@ -302,6 +331,14 @@ archive_strappend_w_utf8(struct archive_string *as, const wchar_t *w)
        return (return_val);
 }
 
+/*
+ * UTF-8  ===>  Unicode
+ *
+ */
+
+/*
+ * Utility to convert a single UTF-8 sequence.
+ */
 static int
 utf8_to_unicode(int *pwc, const char *s, size_t n)
 {
@@ -412,9 +449,102 @@ archive_wstrappend_utf8(struct archive_wstring *dest, struct archive_string *src
        return (0);
 }
 
+#if HAVE_ICONV
+
+/*
+ * Get the "current character set" name to use with iconv.
+ * On FreeBSD, the empty character set name "" chooses
+ * the correct character encoding for the current locale,
+ * so this isn't necessary.
+ * But iconv on Mac OS 10.6 doesn't seem to handle this correctly;
+ * on that system, we have to explicitly call nl_langinfo()
+ * to get the right name.  Not sure about other platforms.
+ */
+static const char *
+default_iconv_charset(const char *charset) {
+       if (charset != NULL && charset[0] != '\0')
+               return charset;
+#if HAVE_NL_LANGINFO
+       return nl_langinfo(CODESET);
+#else
+       return "";
+#endif
+}
 
+/*
+ * Translates from the current locale character set to Unicode
+ * and appends to the archive_wstring.  Note: returns NULL if conversion
+ * fails.
+ *
+ * This version uses the POSIX iconv() function.
+ */
 int
-archive_wstrcpy_mbs(struct archive_wstring *dest,
+archive_wstrcpy_mbs(struct archive *a, struct archive_wstring *dest, struct archive_string *src)
+{
+       char *p;
+       char buff[256];
+       size_t remaining;
+       iconv_t cd;
+
+       if (a == NULL) {
+               cd = iconv_open(__LA_UNICODE, default_iconv_charset(NULL));
+       } else if (a->unicode_to_current == (iconv_t)(0))
+               cd = iconv_open(__LA_UNICODE, default_iconv_charset(a->current_code));
+       else {
+               /* Use the cached conversion descriptor after resetting it. */
+               cd = a->current_to_unicode;
+               iconv(cd, NULL, NULL, NULL, NULL);
+       }
+       if (cd == (iconv_t)(-1)) {
+               /* XXX do something here XXX */
+               return -1;
+       }
+
+       p = src->s;
+       remaining = archive_strlen(src);
+       for (;;) {
+               size_t avail = sizeof(buff);
+               char *outp = buff;
+               size_t result = iconv(cd, &p, &remaining, &outp, &avail);
+
+               if (avail < sizeof(buff))
+                       archive_wstring_append(dest,
+                           (const wchar_t *)buff,
+                           (sizeof(buff) - avail) / sizeof(wchar_t));
+               if (result != (size_t)-1) {
+                       break; /* Conversion completed. */
+               } else if (errno == EILSEQ) {
+                       /* Skip the illegal input wchar. */
+                       archive_wstrappend_wchar(dest, L'?');
+                       archive_wstrappend_wchar(dest, p[0]);
+                       p += 1;
+                       remaining -= 1;
+               } else if (errno == E2BIG) {
+                       /* Flush the output and do some more. */
+                       continue;
+               } else if (errno == EINVAL) {
+                       /* Final character is invalid. */
+                       archive_wstrappend_wchar(dest, L'?');
+                       archive_wstrappend_wchar(dest, p[0]);
+                       break;
+               }
+       }
+       /* Dispose of the conversion descriptor or cache it. */
+       if (a == NULL)
+               iconv_close(cd);
+       else if (a->current_to_unicode == (iconv_t)(0))
+               a->current_to_unicode = cd;
+       return (0);
+}
+
+
+#else
+
+/*
+ * Convert MBS to Unicode.
+ */
+int
+archive_wstrcpy_mbs(struct archive *a, struct archive_wstring *dest,
                         struct archive_string *src)
 {
        size_t r;
@@ -434,12 +564,13 @@ archive_wstrcpy_mbs(struct archive_wstring *dest,
        return (-1);
 }
 
+#endif
+
 #if defined(_WIN32) && !defined(__CYGWIN__)
 
 /*
- * Translates a wide character string into current locale character set
- * and appends to the archive_string.  Note: returns NULL if conversion
- * fails.
+ * Unicode ==> MBS.
+ * Note: returns NULL if conversion fails.
  *
  * Win32 builds use WideCharToMultiByte from the Windows API.
  * (Maybe Cygwin should too?  WideCharToMultiByte will know a
@@ -447,12 +578,15 @@ archive_wstrcpy_mbs(struct archive_wstring *dest,
  * wrapper is going to know.)
  */
 struct archive_string *
-archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
+archive_strappend_w_mbs(struct archive *a, struct archive_string *as, const wchar_t *w)
 {
        char *p;
        int l, wl;
        BOOL useDefaultChar = FALSE;
 
+       /* TODO: XXX use codepage preference from a XXX */
+       (void)a; /* UNUSED */
+
        wl = (int)wcslen(w);
        l = wl * 4 + 4;
        p = malloc(l);
@@ -474,6 +608,71 @@ archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
        return (as);
 }
 
+#elif HAVE_ICONV
+
+/*
+ * Translates a wide character string into current locale character set
+ * and appends to the archive_string.  Note: returns NULL if conversion
+ * fails.
+ *
+ * This version uses the POSIX iconv() function.
+ */
+struct archive_string *
+archive_strappend_w_mbs(struct archive *a, struct archive_string *as, const wchar_t *w)
+{
+       char *p;
+       char buff[256];
+       size_t remaining;
+       iconv_t cd;
+
+       if (a == NULL)
+               cd = iconv_open(default_iconv_charset(""), __LA_UNICODE);
+       else if (a->unicode_to_current == (iconv_t)(0))
+               cd = iconv_open(default_iconv_charset(a->current_code), __LA_UNICODE);
+       else {
+               /* Use the cached conversion descriptor after resetting it. */
+               cd = a->unicode_to_current;
+               iconv(cd, NULL, NULL, NULL, NULL);
+       }
+       if (cd == (iconv_t)(-1)) {
+               /* XXX do something here XXX */
+               return NULL;
+       }
+
+       p = (char *)(uintptr_t)w;
+       remaining = wcslen(w) * sizeof(wchar_t);
+       for (;;) {
+               size_t avail = sizeof(buff);
+               char *outp = buff;
+               size_t result = iconv(cd, &p, &remaining, &outp, &avail);
+
+               if (avail < sizeof(buff))
+                       archive_string_append(as, buff, sizeof(buff) - avail);
+               if (result >= 0) {
+                       break; /* Conversion completed. */
+               } else if (errno == EILSEQ) {
+                       /* Skip the illegal input wchar. */
+                       archive_strappend_char(as, '?');
+                       p += sizeof(wchar_t);
+                       remaining -= sizeof(wchar_t);
+               } else if (errno == E2BIG) {
+                       /* Flush the output and do some more. */
+                       continue;
+               } else if (errno == EINVAL) {
+                       /* Final character is invalid. */
+                       archive_strappend_char(as, '?');
+                       break;
+               }
+       }
+       /* Dispose of the conversion descriptor or cache it. */
+       if (a == NULL)
+               iconv_close(cd);
+       else if (a->unicode_to_current == (iconv_t)(0))
+               a->unicode_to_current = cd;
+       return (as);
+}
+
+
 #else
 
 /*
@@ -486,7 +685,7 @@ archive_strappend_w_mbs(struct archive_string *as, const wchar_t *w)
  * 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)
+archive_strappend_w_mbs(struct archive *a, struct archive_string *as, const wchar_t *w)
 {
 #if !defined(HAVE_WCTOMB) && !defined(HAVE_WCRTOMB)
        /* If there's no built-in locale support, fall back to UTF8 always. */
@@ -564,14 +763,39 @@ archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src)
 }
 
 const char *
-archive_mstring_get_mbs(struct archive_mstring *aes)
+archive_mstring_get_utf8(struct archive *a, struct archive_mstring *aes)
+{
+       const wchar_t *wc;
+
+       /* If we already have a UTF8 form, return that immediately. */
+       if (aes->aes_set & AES_SET_UTF8)
+               return (aes->aes_utf8.s);
+       /* If there's a Unicode form, convert that. */
+       if ((aes->aes_set & AES_SET_WCS)
+           && archive_strappend_w_utf8(&(aes->aes_utf8), aes->aes_wcs.s) != NULL) {
+               aes->aes_set |= AES_SET_UTF8;
+               return (aes->aes_utf8.s);
+       }
+       /* TODO: Convert MBS to UTF8 in one step instead of two. */
+       wc = archive_mstring_get_wcs(a, aes);
+       if (wc != NULL) {
+               archive_string_empty(&(aes->aes_utf8));
+               archive_strappend_w_utf8(&(aes->aes_utf8), wc);
+               aes->aes_set |= AES_SET_UTF8;
+               return (aes->aes_utf8.s);
+       }
+       return (NULL);
+}
+
+const char *
+archive_mstring_get_mbs(struct archive *a, struct archive_mstring *aes)
 {
        /* If we already have an MBS form, return that immediately. */
        if (aes->aes_set & AES_SET_MBS)
                return (aes->aes_mbs.s);
        /* If there's a WCS form, try converting with the native locale. */
        if ((aes->aes_set & AES_SET_WCS)
-           && archive_strappend_w_mbs(&(aes->aes_mbs), aes->aes_wcs.s) != NULL) {
+           && archive_strappend_w_mbs(a, &(aes->aes_mbs), aes->aes_wcs.s) != NULL) {
                aes->aes_set |= AES_SET_MBS;
                return (aes->aes_mbs.s);
        }
@@ -587,7 +811,7 @@ archive_mstring_get_mbs(struct archive_mstring *aes)
 }
 
 const wchar_t *
-archive_mstring_get_wcs(struct archive_mstring *aes)
+archive_mstring_get_wcs(struct archive *a, struct archive_mstring *aes)
 {
        /* Return WCS form if we already have it. */
        if (aes->aes_set & AES_SET_WCS)
@@ -600,7 +824,7 @@ archive_mstring_get_wcs(struct archive_mstring *aes)
        }
        /* Try converting MBS to WCS using native locale. */
        if ((aes->aes_set & AES_SET_MBS)
-           && !archive_wstrcpy_mbs(&(aes->aes_wcs), &(aes->aes_mbs))) {
+           && !archive_wstrcpy_mbs(a, &(aes->aes_wcs), &(aes->aes_mbs))) {
                aes->aes_set |= AES_SET_WCS;
                return (aes->aes_wcs.s);
        }
@@ -651,7 +875,7 @@ archive_mstring_copy_wcs_len(struct archive_mstring *aes, const wchar_t *wcs, si
  * usable values even if some of the character conversions are failing.)
  */
 int
-archive_mstring_update_utf8(struct archive_mstring *aes, const char *utf8)
+archive_mstring_update_utf8(struct archive *a, struct archive_mstring *aes, const char *utf8)
 {
        if (utf8 == NULL) {
                aes->aes_set = 0;
@@ -679,7 +903,7 @@ archive_mstring_update_utf8(struct archive_mstring *aes, const char *utf8)
        aes->aes_set = AES_SET_UTF8 | AES_SET_WCS; /* Both UTF8 and WCS set. */
 
        /* Try converting WCS to MBS, return false on failure. */
-       if (archive_strappend_w_mbs(&(aes->aes_mbs), aes->aes_wcs.s) == NULL)
+       if (archive_strappend_w_mbs(a, &(aes->aes_mbs), aes->aes_wcs.s) == NULL)
                return (0);
        aes->aes_set = AES_SET_UTF8 | AES_SET_WCS | AES_SET_MBS;
 
index 6250ecf23e5d37eaae743d723f138ac185fa1370..d24c1879433ace707667e5632ad11ba628ed2baf 100644 (file)
@@ -84,7 +84,7 @@ archive_strappend_w_utf8(struct archive_string *, const wchar_t *);
 /* Convert a Unicode string to current locale and append the result. */
 /* Returns NULL if conversion fails. */
 struct archive_string *
-archive_strappend_w_mbs(struct archive_string *, const wchar_t *);
+archive_strappend_w_mbs(struct archive *, struct archive_string *, const wchar_t *);
 
 /* Copy one archive_string to another */
 #define        archive_string_copy(dest, src) \
@@ -155,8 +155,8 @@ int archive_wstrappend_utf8(struct archive_wstring *dest,
 
 /* Translates from MBS in src to Unicode in dest. */
 /* Returns non-zero if conversion failed in any way. */
-int archive_wstrcpy_mbs(struct archive_wstring *dest,
-                             struct archive_string *src);
+int archive_wstrcpy_mbs(struct archive *,
+    struct archive_wstring *dest, struct archive_string *src);
 
 
 /* A "multistring" can hold Unicode, UTF8, or MBS versions of
@@ -180,12 +180,14 @@ struct archive_mstring {
 
 void   archive_mstring_clean(struct archive_mstring *);
 void   archive_mstring_copy(struct archive_mstring *dest, struct archive_mstring *src);
-const char *   archive_mstring_get_mbs(struct archive_mstring *);
-const wchar_t *        archive_mstring_get_wcs(struct archive_mstring *);
+const char *   archive_mstring_get_mbs(struct archive *, struct archive_mstring *);
+const char *   archive_mstring_get_utf8(struct archive *, struct archive_mstring *);
+const wchar_t *        archive_mstring_get_wcs(struct archive *, struct archive_mstring *);
 int    archive_mstring_copy_mbs(struct archive_mstring *, const char *mbs);
+int    archive_mstring_copy_utf8(struct archive_mstring *, const char *utf8);
 int    archive_mstring_copy_wcs(struct archive_mstring *, const wchar_t *wcs);
 int    archive_mstring_copy_wcs_len(struct archive_mstring *, const wchar_t *wcs, size_t);
-int     archive_mstring_update_utf8(struct archive_mstring *aes, const char *utf8);
+int     archive_mstring_update_utf8(struct archive *, struct archive_mstring *aes, const char *utf8);
 
 
 #endif
index 48add6e14b98744355d4ab51d9cae20968b14808..909fd2f4f6de83f5126272e64612a4e86a3b9365 100644 (file)
@@ -141,7 +141,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
                        switch(long_flag) {
                        case 'l':
                                pw = va_arg(ap, wchar_t *);
-                               archive_strappend_w_mbs(as, pw);
+                               archive_strappend_w_mbs(NULL, as, pw);
                                break;
                        default:
                                p2 = va_arg(ap, char *);
@@ -151,7 +151,7 @@ archive_string_vsprintf(struct archive_string *as, const char *fmt,
                        break;
                case 'S':
                        pw = va_arg(ap, wchar_t *);
-                       archive_strappend_w_mbs(as, pw);
+                       archive_strappend_w_mbs(NULL, as, pw);
                        break;
                case 'o': case 'u': case 'x': case 'X':
                        /* Common handling for unsigned integer formats. */
index 21ea2d9f2355cf4bd486b8609dc4479d4ff176d6..6d7ef169395c4cfba9ba751637e787c7a5b51591 100644 (file)
@@ -47,36 +47,18 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:1
 #include "archive_private.h"
 #include "archive_string.h"
 
-#if ARCHIVE_VERSION_NUMBER < 3000000
-/* These disappear in libarchive 3.0 */
-/* Deprecated. */
-int
-archive_api_feature(void)
-{
-       return (ARCHIVE_API_FEATURE);
-}
-
-/* Deprecated. */
-int
-archive_api_version(void)
-{
-       return (ARCHIVE_API_VERSION);
-}
-
-/* Deprecated synonym for archive_version_number() */
-int
-archive_version_stamp(void)
-{
-       return (archive_version_number());
-}
-
-/* Deprecated synonym for archive_version_string() */
-const char *
-archive_version(void)
+/* Generic initialization of 'struct archive' objects. */
+void
+__archive_clean(struct archive *a)
 {
-       return (archive_version_string());
-}
+#if HAVE_ICONV
+       free(a->current_code);
+       if (a->unicode_to_current != (iconv_t)0)
+               iconv_close(a->unicode_to_current);
+       if (a->current_to_unicode != (iconv_t)0)
+               iconv_close(a->current_to_unicode);
 #endif
+}
 
 int
 archive_version_number(void)
index d55d3a996467522f9736583711813377cafc2025..b191975224222e5c1bbe7eed3f4afef44be80140 100644 (file)
@@ -590,6 +590,7 @@ _archive_write_free(struct archive *_a)
        free((void *)(uintptr_t)(const void *)a->nulls);
        archive_string_free(&a->archive.error_string);
        a->archive.magic = 0;
+       __archive_clean(&a->archive);
        free(a);
        return (r);
 }
index 90824a444226aa380dacda36d2ccd66c23229d29..212febcdfecd93e65d66f274f7d63f47199b450f 100644 (file)
@@ -1458,6 +1458,7 @@ _archive_write_disk_free(struct archive *_a)
        archive_string_free(&a->archive.error_string);
        archive_string_free(&a->path_safe);
        a->archive.magic = 0;
+       __archive_clean(&a->archive);
        free(a);
        return (ret);
 }
index 550923983778cfd22c0fc0115fb2a83a6ee620e4..95a06d9eec72532fbf97ad047be4720d6b56e98b 100644 (file)
@@ -334,7 +334,7 @@ archive_write_cpio_close(struct archive_write *a)
        int er;
        struct archive_entry *trailer;
 
-       trailer = archive_entry_new();
+       trailer = archive_entry_new2(NULL);
        /* nlink = 1 here for GNU cpio compat. */
        archive_entry_set_nlink(trailer, 1);
        archive_entry_set_size(trailer, 0);
index e04482e35e6cc46a3330b75c17b87b6c56983556..6414341b1bc87b03999e1f58c7686b1bc2ecb497 100644 (file)
@@ -268,7 +268,7 @@ archive_write_gnutar_header(struct archive_write *a, struct archive_entry *entry
                linkname = archive_entry_symlink(entry);
        if (linkname != NULL && strlen(linkname) > GNUTAR_linkname_size) {
                size_t todo = strlen(linkname);
-               struct archive_entry *temp = archive_entry_new();
+               struct archive_entry *temp = archive_entry_new2(&a->archive);
 
                /* Uname/gname here don't really matter since noone reads them;
                 * these are the values that GNU tar happens to use on FreeBSD. */
@@ -297,7 +297,7 @@ archive_write_gnutar_header(struct archive_write *a, struct archive_entry *entry
        if (strlen(archive_entry_pathname(entry)) > GNUTAR_name_size) {
                const char *pathname = archive_entry_pathname(entry);
                size_t todo = strlen(pathname);
-               struct archive_entry *temp = archive_entry_new();
+               struct archive_entry *temp = archive_entry_new2(&a->archive);
 
                /* Uname/gname here don't really matter since noone reads them;
                 * these are the values that GNU tar happens to use on FreeBSD. */
index fe104de709960c0a1ccb74d880b4de3b190f7e50..69d12a7f3459ed0e0151bccf12d1df2c1afd3742 100644 (file)
@@ -944,7 +944,7 @@ static void calculate_path_table_size(struct vdd *);
 static void    isofile_init_entry_list(struct iso9660 *);
 static void    isofile_add_entry(struct iso9660 *, struct isofile *);
 static void    isofile_free_all_entries(struct iso9660 *);
-static struct isofile * isofile_new(struct archive_entry *);
+static struct isofile * isofile_new(struct archive_write *, struct archive_entry *);
 static void    isofile_free(struct isofile *);
 static void    isofile_gen_utility_names(struct isofile *);
 #ifdef HAVE_ZLIB_H
@@ -962,7 +962,7 @@ static int  isoent_clone_tree(struct archive_write *,
                    struct isoent **, struct isoent *);
 static void    _isoent_free(struct isoent *isoent);
 static void    isoent_free_all(struct isoent *);
-static struct isoent * isoent_create_virtual_dir(struct iso9660 *,
+static struct isoent * isoent_create_virtual_dir(struct archive_write *, struct iso9660 *,
                    const char *);
 static int     isoent_cmp_node(const struct archive_rb_node *,
                    const struct archive_rb_node *);
@@ -1135,7 +1135,7 @@ archive_write_set_format_iso9660(struct archive *_a)
 
        /* Create the root directory. */
        iso9660->primary.rootent =
-           isoent_create_virtual_dir(iso9660, "");
+           isoent_create_virtual_dir(a, iso9660, "");
        if (iso9660->primary.rootent == NULL) {
                free(iso9660);
                archive_set_error(&a->archive, ENOMEM,
@@ -1522,7 +1522,7 @@ iso9660_write_header(struct archive_write *a, struct archive_entry *entry)
                iso9660->need_multi_extent = 1;
        }
 
-       file = isofile_new(entry);
+       file = isofile_new(a, entry);
        if (file == NULL) {
                archive_set_error(&a->archive, ENOMEM,
                    "Can't allocate data");
@@ -4410,7 +4410,7 @@ isofile_free_all_entries(struct iso9660 *iso9660)
 }
 
 static struct isofile *
-isofile_new(struct archive_entry *entry)
+isofile_new(struct archive_write *a, struct archive_entry *entry)
 {
        struct isofile *file;
 
@@ -4421,7 +4421,7 @@ isofile_new(struct archive_entry *entry)
        if (entry != NULL)
                file->entry = archive_entry_clone(entry);
        else
-               file->entry = archive_entry_new();
+               file->entry = archive_entry_new2(&a->archive);
        if (file->entry == NULL) {
                free(file);
                return (NULL);
@@ -4860,12 +4860,12 @@ isoent_free_all(struct isoent *isoent)
 }
 
 static struct isoent *
-isoent_create_virtual_dir(struct iso9660 *iso9660, const char *pathname)
+isoent_create_virtual_dir(struct archive_write *a, struct iso9660 *iso9660, const char *pathname)
 {
        struct isofile *file;
        struct isoent *isoent;
 
-       file = isofile_new(NULL);
+       file = isofile_new(a, NULL);
        if (file == NULL)
                return (NULL);
        archive_entry_set_pathname(file->entry, pathname);
@@ -5322,7 +5322,7 @@ isoent_tree(struct archive_write *a, struct isoent **isoentpp)
                                as.s[as.length-1] = '\0';
                                as.length--;
                        }
-                       vp = isoent_create_virtual_dir(iso9660, as.s);
+                       vp = isoent_create_virtual_dir(a, iso9660, as.s);
                        if (vp == NULL) {
                                archive_string_free(&as);
                                archive_set_error(&a->archive, ENOMEM,
@@ -6343,7 +6343,7 @@ isoent_rr_move_dir(struct archive_write *a, struct isoent **rr_moved,
                /* There isn't rr_move entry.
                 * Create rr_move entry and insert it into the root entry.
                 */
-               rrmoved = isoent_create_virtual_dir(iso9660, "rr_moved");
+               rrmoved = isoent_create_virtual_dir(a, iso9660, "rr_moved");
                if (rrmoved == NULL) {
                        archive_set_error(&a->archive, ENOMEM,
                            "Can't allocate memory");
@@ -6772,7 +6772,7 @@ isoent_create_boot_catalog(struct archive_write *a, struct isoent *rootent)
        /*
         * Create the entry which is the "boot.catalog" file.
         */
-       file = isofile_new(NULL);
+       file = isofile_new(a, NULL);
        if (file == NULL) {
                archive_set_error(&a->archive, ENOMEM,
                    "Can't allocate memory");
index e2d1a239c244781ce54d0fbf3b64bb56ddaada23..a5492909522ca08d42c6b6626f74b2f8d99bc313 100644 (file)
@@ -518,7 +518,7 @@ archive_write_pax_header(struct archive_write *a,
                const char *oname;
                char *name, *bname;
                size_t name_length;
-               struct archive_entry *extra = archive_entry_new();
+               struct archive_entry *extra = archive_entry_new2(&a->archive);
 
                oname = archive_entry_pathname(entry_original);
                name_length = strlen(oname);
@@ -1077,7 +1077,7 @@ archive_write_pax_header(struct archive_write *a,
                int64_t uid, gid;
                int mode;
 
-               pax_attr_entry = archive_entry_new();
+               pax_attr_entry = archive_entry_new2(&a->archive);
                p = entry_name.s;
                archive_entry_set_pathname(pax_attr_entry,
                    build_pax_attribute_name(pax_entry_name, p));
index c80716397f942728d5efa725c6d90b2c21261c14..9daecdfde1dcf8bef5c9d11cbac2cbe8486e3c0f 100644 (file)
@@ -283,9 +283,9 @@ static int  xar_finish_entry(struct archive_write *);
 static int     xar_close(struct archive_write *);
 static int     xar_free(struct archive_write *);
 
-static struct file *file_new(struct archive_entry *);
+static struct file *file_new(struct archive_write *a, struct archive_entry *);
 static void    file_free(struct file *);
-static struct file *file_create_virtual_dir(struct xar *,
+static struct file *file_create_virtual_dir(struct archive_write *a, struct xar *,
                    const char *);
 static int     file_add_child_tail(struct file *, struct file *);
 static struct file *file_find_child(struct file *, const char *);
@@ -364,7 +364,7 @@ archive_write_set_format_xar(struct archive *_a)
        /*
         * Create the root directory.
         */
-       xar->root = file_create_virtual_dir(xar, "");
+       xar->root = file_create_virtual_dir(a, xar, "");
        if (xar->root == NULL) {
                free(xar);
                archive_set_error(&a->archive, ENOMEM,
@@ -513,7 +513,7 @@ xar_write_header(struct archive_write *a, struct archive_entry *entry)
        xar->cur_file = NULL;
        xar->bytes_remaining = 0;
 
-       file = file_new(entry);
+       file = file_new(a, entry);
        if (file == NULL) {
                archive_set_error(&a->archive, ENOMEM,
                    "Can't allocate data");
@@ -1852,7 +1852,7 @@ file_cmp_key(const struct archive_rb_node *n, const void *key)
 }
 
 static struct file *
-file_new(struct archive_entry *entry)
+file_new(struct archive_write *a, struct archive_entry *entry)
 {
        struct file *file;
        static const struct archive_rb_tree_ops rb_ops = {
@@ -1866,7 +1866,7 @@ file_new(struct archive_entry *entry)
        if (entry != NULL)
                file->entry = archive_entry_clone(entry);
        else
-               file->entry = archive_entry_new();
+               file->entry = archive_entry_new2(&a->archive);
        if (file->entry == NULL) {
                free(file);
                return (NULL);
@@ -1905,11 +1905,11 @@ file_free(struct file *file)
 }
 
 static struct file *
-file_create_virtual_dir(struct xar *xar, const char *pathname)
+file_create_virtual_dir(struct archive_write *a, struct xar *xar, const char *pathname)
 {
        struct file *file;
 
-       file = file_new(NULL);
+       file = file_new(a, NULL);
        if (file == NULL)
                return (NULL);
        archive_entry_set_pathname(file->entry, pathname);
@@ -2232,7 +2232,7 @@ file_tree(struct archive_write *a, struct file **filepp)
                                as.s[as.length-1] = '\0';
                                as.length--;
                        }
-                       vp = file_create_virtual_dir(xar, as.s);
+                       vp = file_create_virtual_dir(a, xar, as.s);
                        if (vp == NULL) {
                                archive_string_free(&as);
                                archive_set_error(&a->archive, ENOMEM,
index 6faf4c81a6d9fea7bf6aee3e7c964eac8848457b..e8532091c271a97282be14e8cac2a51b438b8ab4 100644 (file)
@@ -35,10 +35,6 @@ __FBSDID("$FreeBSD: head/lib/libarchive/test/test_pax_filename_encoding.c 201247
 
 DEFINE_TEST(test_pax_filename_encoding_freebsd)
 {
-#if !defined(__FreeBSD__)
-       /* TODO: This test can probably be enabled on other systems as well. */
-       skipping("FreeBSD-specific locale test");
-#else
        struct archive *a;
        struct archive_entry *entry;
        char buff[4096];
@@ -64,5 +60,4 @@ DEFINE_TEST(test_pax_filename_encoding_freebsd)
        /* Above three characters in KOI8-R should translate to the following
         * three characters (two bytes each) in UTF-8. */
        assertEqualMem(buff + 512, "15 path=\xD0\xBF\xD1\x80\xD0\xB8\x0A", 15);
-#endif
 }