123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- $OpenBSD: iconv-unix_unix_c,v 1.1 2015/05/11 21:19:23 czarkoff Exp $
- --- unix/unix.c.orig Sat Jan 24 00:31:26 2009
- +++ unix/unix.c Sat May 9 13:31:19 2015
- @@ -30,6 +30,9 @@
- #define UNZIP_INTERNAL
- #include "unzip.h"
-
- +#include <iconv.h>
- +#include <langinfo.h>
- +
- #ifdef SCO_XENIX
- # define SYSNDIR
- #else /* SCO Unix, AIX, DNIX, TI SysV, Coherent 4.x, ... */
- @@ -1874,3 +1877,102 @@ static void qlfix(__G__ ef_ptr, ef_len)
- }
- }
- #endif /* QLZIP */
- +
- +
- +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" },
- + { "UTF-8", "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. */
- +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;
- + }
- + }
- +}
- +
- +/* Convert a string from one encoding to the current locale using iconv().
- + * Be as non-intrusive as possible. If error is encountered during covertion
- + * just leave the string intact. */
- +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 = strlen(string);
- + s = string;
- +
- + /* Make sure OUTBUFSIZ + 1 never ends up smaller than FILNAMSIZ
- + * as this function also gets called with G.outbuf in fileio.c
- + */
- + buflen = FILNAMSIZ;
- + if (OUTBUFSIZ + 1 < FILNAMSIZ)
- + {
- + buflen = OUTBUFSIZ + 1;
- + }
- +
- + d = buf = malloc(buflen);
- + if(!d)
- + goto cleanup;
- +
- + bzero(buf,buflen);
- + dlen = buflen - 1;
- +
- + 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. */
- +inline void oem_intern(char *string)
- +{
- + charset_to_intern(string, OEM_CP);
- +}
- +
- +/* Convert a string from ISO_CP to the current locale charset. */
- +inline void iso_intern(char *string)
- +{
- + charset_to_intern(string, ISO_CP);
- +}
|