]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add support for charset option to xar reader although we expect
authorMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sat, 26 Mar 2011 06:13:43 +0000 (02:13 -0400)
committerMichihiro NAKAJIMA <ggcueroad@gmail.com>
Sat, 26 Mar 2011 06:13:43 +0000 (02:13 -0400)
charset=UTF-8-MAC is specified.

SVN-Revision: 3080

libarchive/archive_read_support_format_xar.c

index 0d5f1fc6043692384a96054494ecc7ac5e670a21..18fe4e7ca1a45d69f190a267c747d87850266436 100644 (file)
@@ -357,6 +357,8 @@ struct xar {
        enum enctype             entry_encoding;
        struct chksumval         entry_a_sum;
        struct chksumval         entry_e_sum;
+
+       char                    *charset;
 };
 
 struct xmlattr {
@@ -371,6 +373,7 @@ struct xmlattr_list {
 };
 
 static int     xar_bid(struct archive_read *);
+static int     xar_options(struct archive_read *, const char *, const char *);
 static int     xar_read_header(struct archive_read *,
                    struct archive_entry *);
 static int     xar_read_data(struct archive_read *,
@@ -443,12 +446,13 @@ archive_read_support_format_xar(struct archive *_a)
                    "Can't allocate xar data");
                return (ARCHIVE_FATAL);
        }
+       xar->charset = strdup("UTF-8");
 
        r = __archive_read_register_format(a,
            xar,
            "xar",
            xar_bid,
-           NULL,
+           xar_options,
            xar_read_header,
            xar_read_data,
            xar_read_data_skip,
@@ -503,6 +507,34 @@ xar_bid(struct archive_read *a)
        return (bid);
 }
 
+static int
+xar_options(struct archive_read *a, const char *key, const char *val)
+{
+       struct xar *xar;
+       int ret = ARCHIVE_FAILED;
+
+       xar = (struct xar *)(a->format->data);
+       if (strcmp(key, "charset")  == 0) {
+               if (val == NULL || val[0] == 0)
+                       archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                           "xar: charset option needs a character-set name");
+               else if (archive_string_conversion_from_charset(
+                   &a->archive, val) == 0) {
+                       /*
+                        * TODO: Should we allow UTF-8-MAC only ? 
+                        */
+                       free(xar->charset);
+                       xar->charset = strdup(val);
+                       ret = ARCHIVE_OK;
+               } else
+                       ret = ARCHIVE_FATAL;
+       } else
+               archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+                   "xar: unknown keyword ``%s''", key);
+
+       return (ret);
+}
+
 static int
 read_toc(struct archive_read *a)
 {
@@ -673,14 +705,14 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
        archive_entry_set_mtime(entry, file->mtime, 0);
        archive_entry_set_gid(entry, file->gid);
        if (file->gname.length > 0)
-               archive_entry_update_gname_utf8(entry, file->gname.s);
+               archive_entry_set_gname(entry, file->gname.s);
        archive_entry_set_uid(entry, file->uid);
        if (file->uname.length > 0)
-               archive_entry_update_uname_utf8(entry, file->uname.s);
+               archive_entry_set_uname(entry, file->uname.s);
        archive_entry_set_mode(entry, file->mode);
-       archive_entry_update_pathname_utf8(entry, file->pathname.s);
+       archive_entry_set_pathname(entry, file->pathname.s);
        if (file->symlink.length > 0)
-               archive_entry_update_symlink_utf8(entry, file->symlink.s);
+               archive_entry_set_symlink(entry, file->symlink.s);
        /* Set proper nlink. */
        if ((file->mode & AE_IFMT) == AE_IFDIR)
                archive_entry_set_nlink(entry, file->subdirs + 2);
@@ -688,8 +720,7 @@ xar_read_header(struct archive_read *a, struct archive_entry *entry)
                archive_entry_set_nlink(entry, file->nlink);
        archive_entry_set_size(entry, file->size);
        if (archive_strlen(&(file->hardlink)) > 0)
-               archive_entry_update_hardlink_utf8(entry,
-                       file->hardlink.s);
+               archive_entry_set_hardlink(entry, file->hardlink.s);
        archive_entry_set_ino64(entry, file->ino64);
        if (file->has & HAS_DEV)
                archive_entry_set_dev(entry, file->dev);
@@ -867,6 +898,7 @@ xar_cleanup(struct archive_read *a)
                archive_string_free(&(tag->name));
                free(tag);
        }
+       free(xar->charset);
        free(xar);
        a->format->data = NULL;
        return (r);
@@ -2493,7 +2525,8 @@ static const int base64[256] = {
 };
 
 static void
-strappend_base64(struct archive_string *as, const char *s, size_t l)
+strappend_base64(struct archive_read *a, struct xar *xar,
+    struct archive_string *as, const char *s, size_t l)
 {
        unsigned char buff[256];
        unsigned char *out;
@@ -2538,7 +2571,8 @@ strappend_base64(struct archive_string *as, const char *s, size_t l)
                }
        }
        if (len > 0)
-               archive_strncat(as, (const char *)buff, len);
+               archive_strncat_from_locale(&(a->archive), as,
+                   (const char *)buff, len, xar->charset);
 }
 
 static void
@@ -2582,13 +2616,16 @@ xml_data(void *userData, const char *s, int len)
                }
                xar->file->has |= HAS_PATHNAME;
                if (xar->base64text)
-                       strappend_base64(&(xar->file->pathname), s, len);
+                       strappend_base64(a, xar,
+                           &(xar->file->pathname), s, len);
                else
-                       archive_strncat(&(xar->file->pathname), s, len);
+                       archive_strncat_from_locale(&(a->archive),
+                           &(xar->file->pathname), s, len, xar->charset);
                break;
        case FILE_LINK:
                xar->file->has |= HAS_SYMLINK;
-               archive_strncpy(&(xar->file->symlink), s, len);
+               archive_strncpy_from_locale(&(a->archive),
+                   &(xar->file->symlink), s, len, xar->charset);
                break;
        case FILE_TYPE:
                if (strncmp("file", s, len) == 0 ||
@@ -2639,7 +2676,8 @@ xml_data(void *userData, const char *s, int len)
                break;
        case FILE_GROUP:
                xar->file->has |= HAS_GID;
-               archive_strncpy(&(xar->file->gname), s, len);
+               archive_strncpy_from_locale(&(a->archive),
+                   &(xar->file->gname), s, len, xar->charset);
                break;
        case FILE_GID:
                xar->file->has |= HAS_GID;
@@ -2647,7 +2685,8 @@ xml_data(void *userData, const char *s, int len)
                break;
        case FILE_USER:
                xar->file->has |= HAS_UID;
-               archive_strncpy(&(xar->file->uname), s, len);
+               archive_strncpy_from_locale(&(a->archive),
+                   &(xar->file->uname), s, len, xar->charset);
                break;
        case FILE_UID:
                xar->file->has |= HAS_UID;