summaryrefslogtreecommitdiffstats
path: root/app-arch/ruszip/files/zip232-ds-recoderus.patch
blob: de3e337029d711a27a1e830816e8b72156ef1c95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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 <iconv.h>
+#include <errno.h>
+#include <locale.h>
+
+#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 (olen<len) len=olen;
+    }
+
+    if (iconv(icnv, NULL, NULL, NULL, NULL) == -1) return NULL;
+
+    in_buf = buf;
+    in_left = len;
+    out_buf = xmms_charset_tmp;
+    out_left = CHARSET_MAX_STRING_SIZE;
+
+loop:
+    err=iconv(icnv, &in_buf, &in_left, &out_buf, &out_left);
+    if (err<0) {
+        if (errno==E2BIG) {
+    	    *(int*)(xmms_charset_tmp+(CHARSET_MAX_STRING_SIZE-sizeof(int)))=0;
+	} else if (errno==EILSEQ) {
+	    if (errors<CHARSET_MAX_ERRORS) {
+	        errors++;
+		iconv_copysymbol(&in_buf, &in_left, &out_buf, &out_left);
+		if (in_left>0) 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;
 }