Group :: Archiving/Compression
RPM: unarj
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: unarj-2.63c-iconv.patch
Download
Download
--- unarj.c~ 2002-03-11 14:04:23 +0300
+++ unarj.c 2005-10-20 17:48:34 +0400
@@ -58,6 +58,9 @@
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
+#include <iconv.h>
+#include <langinfo.h>
+#include <locale.h>
#else /* !MODERN */
extern void free();
extern void exit();
@@ -284,6 +287,91 @@
exit(EXIT_FAILURE);
}
+#define MAX_CP_NAME 25
+
+typedef struct {
+ char *local_charset;
+ char *archive_charset;
+} CHARSET_MAP;
+
+/* A mapping of local <-> archive charsets used by default to convert filenames
+ * of DOS/Windows Zip archives. Currently very basic. */
+static CHARSET_MAP dos_charset_map[] = {
+ { "ANSI_X3.4-1968", "CP850" },
+ { "ISO-8859-1", "CP850" },
+ { "CP1252", "CP850" },
+ { "CP1251", "CP866" },
+ { "KOI8-R", "CP866" },
+ { "KOI8-U", "CP866" },
+ { "ISO-8859-5", "CP866" }
+};
+
+char OEM_CP[MAX_CP_NAME] = "";
+char ISO_CP[MAX_CP_NAME] = "";
+
+/* Try to guess the default value of OEM_CP based on the current locale.
+ * ISO_CP is left alone for now. */
+static void
+init_conversion_charsets()
+{
+ const char *local_charset;
+ int i;
+
+ /* Make a guess only if OEM_CP not already set. */
+ if(*OEM_CP == '\0') {
+ local_charset = nl_langinfo(CODESET);
+ for(i = 0; i < sizeof(dos_charset_map)/sizeof(CHARSET_MAP); i++)
+ if(!strcasecmp(local_charset, dos_charset_map[i].local_charset)) {
+ strncpy(OEM_CP, dos_charset_map[i].archive_charset,
+ sizeof(OEM_CP));
+ break;
+ }
+ }
+}
+
+static void charset_to_intern(char *string, char *from_charset)
+{
+ iconv_t cd;
+ char *s, *d, *buf;
+ size_t slen, dlen, buflen;
+ const char *local_charset;
+
+ if(*from_charset == '\0')
+ return;
+
+ buf = NULL;
+ local_charset = nl_langinfo(CODESET);
+
+ if((cd = iconv_open(local_charset, from_charset)) == (iconv_t)-1)
+ return;
+
+ slen = dlen = buflen = strlen(string);
+ s = string;
+ d = buf = malloc(buflen + 1);
+ if(!d)
+ goto cleanup;
+
+ if(iconv(cd, &s, &slen, &d, &dlen) == (size_t)-1)
+ goto cleanup;
+ strncpy(string, buf, buflen);
+
+ cleanup:
+ free(buf);
+ iconv_close(cd);
+}
+
+/* Convert a string from OEM_CP to the current locale charset. */
+void oem_intern(char *string)
+{
+ charset_to_intern(string, OEM_CP);
+}
+
+/* Convert a string from ISO_CP to the current locale charset. */
+void iso_intern(char *string)
+{
+ charset_to_intern(string, ISO_CP);
+}
+
static void
strparity(p)
uchar *p;
@@ -636,14 +724,14 @@
hdr_filename = (char *)&header[first_hdr_size];
strncopy(filename, hdr_filename, sizeof(filename));
if (host_os != OS)
- strparity((uchar *)filename);
+ oem_intern(filename);
if ((arj_flags & PATHSYM_FLAG) != 0)
decode_path(filename);
hdr_comment = (char *)&header[first_hdr_size + strlen(hdr_filename) + 1];
strncopy(comment, hdr_comment, sizeof(comment));
if (host_os != OS)
- strparity((uchar *)comment);
+ oem_intern(comment);
/* if extheadersize == 0 then no CRC */
/* otherwise read extheader data and read 4 bytes for CRC */
@@ -989,6 +1077,9 @@
printf(M_VERSION);
+ setlocale(LC_CTYPE, "");
+ init_conversion_charsets();
+
if (argc == 1)
{
help();