diff -dPNur zip-2.32/unix/dsrecode.h zip-2.32-2/unix/dsrecode.h --- zip-2.32/unix/dsrecode.h 1970-01-01 01:00:00.000000000 +0100 +++ zip-2.32-2/unix/dsrecode.h 2008-10-07 11:22:48.000000000 +0200 @@ -0,0 +1,130 @@ +/******* WARNING: Multi-byte output encodings isn't supported! Comments +may been striped!!!! +I don't close 2 opened iconv descriptors. I think this wouldn't cause any +problem. *******/ + +#include +#include +#include + +#define CHARSET_MAX_STRING_SIZE 4096 +#define LOCALE_STRING_LENGTH 64 +#define CHARSET_MAX_ERRORS 0 +#define ENV_VARIABLE "LC_CTYPE" +#define LOCALE_VARIABLE LC_CTYPE + +static iconv_t ds_oem = (iconv_t)-1; +static iconv_t ds_iso = (iconv_t)-1; + +extern int errno; +static char xmms_charset_tmp[CHARSET_MAX_STRING_SIZE]; +static char charset_default[LOCALE_STRING_LENGTH]=""; + +// Multi-byte strings still unsupported +static void iconv_copysymbol(char **in_buf, size_t *in_left, char **out_buf, size_t *out_left) { + if ((out_left>0)&&(in_left>0)) { + (**out_buf)=(**in_buf); + (*out_buf)++; + (*in_buf)++; + (*in_left)--; + (*out_left)--; + } +} + +static char *ds_recode(iconv_t icnv, char *buf, size_t len, size_t *rlen) { + char *in_buf, *out_buf, *res, err; + size_t in_left, out_left, olen; + int errors=0; + + if (!len) { + len=strlen(buf); + } else { + olen=strlen(buf); + if (olen0) goto loop; + } else return NULL; + } else return NULL; + } + + olen = CHARSET_MAX_STRING_SIZE - out_left; + res = malloc(olen+1); + if (!res) return NULL; + + memcpy(res,xmms_charset_tmp,olen); + res[olen]=0; + if (rlen) *rlen=olen; + return res; +} + + +static void charset_setdefault() { + char *str1, *str2; + str1 = (char*)setlocale(LOCALE_VARIABLE, NULL); + if (str1) { + if (!strcasecmp(str1,"C")) { + setlocale(LC_ALL, ""); + str1 = setlocale(LOCALE_VARIABLE, NULL); + } + } else str1 = getenv(ENV_VARIABLE); + if (str1) { + str2 = strrchr(str1,'.'); + if (str2) { + strncpy(charset_default,str2+1,LOCALE_STRING_LENGTH); + charset_default[LOCALE_STRING_LENGTH-1]=0; + str2 = strchr(charset_default,'@'); + if (str2) *str2 = 0; + } else { + strcpy(charset_default,"KOI8-R"); + } + } else { + strcpy(charset_default,"KOI8-R"); + } +} + +void ds_ex2in(char *string) { + char *str; + if (ds_oem == (iconv_t)-1) { + if (!charset_default[0]) charset_setdefault(); + ds_oem = iconv_open("CP866",charset_default); + if (!ds_oem) return; + } + str=ds_recode(ds_oem,string,0,NULL); + if (str) { + strncpy(string,str,strlen(string)+1); + free(str); + } +} + +void ds_in2ex(char *dst, char *string) { + char *str; + if (ds_iso == (iconv_t)-1) { + if (!charset_default[0]) charset_setdefault(); + ds_iso = iconv_open(charset_default, "CP866"); + if (!ds_iso) return; + } + str=ds_recode(ds_iso,string,0,NULL); + if (str) { + strncpy(dst,str,strlen(string)+1); + free(str); + } else { + strncpy(dst,string,strlen(string)+1); + } +} diff -dPNur zip-2.32/unix/unix.c zip-2.32-2/unix/unix.c --- zip-2.32/unix/unix.c 2006-05-30 00:35:00.000000000 +0200 +++ zip-2.32-2/unix/unix.c 2008-10-07 11:23:45.000000000 +0200 @@ -219,6 +219,8 @@ return ZE_OK; } +#include "dsrecode.h" + char *ex2in(x, isdir, pdosflag) char *x; /* external file name */ int isdir; /* input: x is a directory */ @@ -266,6 +268,8 @@ #ifdef EBCDIC strtoasc(n, n); /* here because msname() needs native coding */ +#else + ds_ex2in(n); #endif /* Returned malloc'ed name */ @@ -288,7 +292,8 @@ #ifdef EBCDIC strtoebc(x, n); #else - strcpy(x, n); +// strcpy(x, n); + ds_in2ex(x,n); #endif return x; }