950
|
1 /*****************************************************************************/
|
|
2 /* charset-conv.c - contains functions for performing conversions between */
|
|
3 /* character sets. */
|
|
4 /* Copyright (C) 1998-2008 Brian Masney <masneyb@gftp.org> */
|
|
5 /* */
|
|
6 /* This program is free software; you can redistribute it and/or modify */
|
|
7 /* it under the terms of the GNU General Public License as published by */
|
|
8 /* the Free Software Foundation; either version 2 of the License, or */
|
|
9 /* (at your option) any later version. */
|
|
10 /* */
|
|
11 /* This program is distributed in the hope that it will be useful, */
|
|
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
|
|
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
|
|
14 /* GNU General Public License for more details. */
|
|
15 /* */
|
|
16 /* You should have received a copy of the GNU General Public License */
|
|
17 /* along with this program; if not, write to the Free Software */
|
|
18 /* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA */
|
|
19 /*****************************************************************************/
|
|
20
|
|
21 #include "gftp.h"
|
|
22 static const char cvsid[] = "$Id: protocols.c 952 2008-01-24 23:31:26Z masneyb $";
|
|
23
|
|
24 #if GLIB_MAJOR_VERSION > 1
|
|
25
|
|
26 static /*@null@*/ char *
|
|
27 _gftp_get_next_charset (char **curpos)
|
|
28 {
|
|
29 char *ret, *endpos;
|
|
30 size_t len, retlen;
|
|
31
|
|
32 if (**curpos == '\0')
|
|
33 return (NULL);
|
|
34
|
|
35 for (; **curpos == ' ' || **curpos == '\t'; (*curpos)++);
|
|
36
|
|
37 if ((endpos = strchr (*curpos, ',')) == NULL)
|
|
38 len = strlen (*curpos) - 1; /* the trailing ',' should be omitted */
|
|
39 else
|
|
40 len = endpos - *curpos;
|
|
41
|
|
42 for (retlen = len - 1;
|
|
43 (*curpos)[retlen - 1] == ' ' || (*curpos)[retlen - 1] == '\t';
|
|
44 retlen--);
|
|
45
|
|
46 retlen++; /* Needed due to the len - 1 above... */
|
|
47 ret = g_malloc0 (retlen + 1);
|
|
48 memcpy (ret, *curpos, retlen);
|
|
49
|
|
50 for (*curpos += len; **curpos == ','; (*curpos)++);
|
|
51
|
|
52 return (ret);
|
|
53 }
|
|
54
|
|
55
|
|
56 static void
|
|
57 _do_show_iconv_error (const char *str, char *charset, int from_utf8,
|
|
58 GError * error)
|
|
59 {
|
|
60 const char *fromset, *toset;
|
|
61
|
|
62 if (from_utf8)
|
|
63 {
|
|
64 fromset = "UTF-8";
|
|
65 toset = charset;
|
|
66 }
|
|
67 else
|
|
68 {
|
|
69 fromset = charset;
|
|
70 toset = "UTF-8";
|
|
71 }
|
|
72
|
|
73 printf (_("Error converting string '%s' from character set %s to character set %s: %s\n"),
|
|
74 str, fromset, toset, error->message);
|
|
75 }
|
|
76
|
|
77
|
|
78 /*@null@*/ static char *
|
|
79 _do_convert_string (gftp_request * request, int is_filename, int force_local,
|
|
80 const char *str, size_t *dest_len, int from_utf8)
|
|
81 {
|
|
82 char *remote_charsets, *ret, *fromset, *toset, *stpos, *cur_charset;
|
|
83 GError * error;
|
|
84 gsize bread;
|
|
85
|
|
86 if (request == NULL)
|
|
87 return (NULL);
|
|
88
|
|
89 if (g_utf8_validate (str, -1, NULL) != from_utf8)
|
|
90 return (NULL);
|
|
91
|
|
92 error = NULL;
|
|
93 gftp_lookup_request_option (request, "remote_charsets", &remote_charsets);
|
|
94 if (*remote_charsets == '\0' || request->use_local_encoding ||
|
|
95 force_local == 1)
|
|
96 {
|
|
97 if (from_utf8)
|
|
98 {
|
|
99 if (is_filename)
|
|
100 ret = g_filename_from_utf8 (str, -1, &bread, dest_len, &error);
|
|
101 else
|
|
102 ret = g_locale_from_utf8 (str, -1, &bread, dest_len, &error);
|
|
103 }
|
|
104 else
|
|
105 {
|
|
106 if (is_filename)
|
|
107 ret = g_filename_to_utf8 (str, -1, &bread, dest_len, &error);
|
|
108 else
|
|
109 ret = g_locale_to_utf8 (str, -1, &bread, dest_len, &error);
|
|
110 }
|
|
111
|
|
112 if (ret == NULL)
|
|
113 _do_show_iconv_error (str, request->iconv_charset, from_utf8, error);
|
|
114
|
|
115 return (ret);
|
|
116 }
|
|
117
|
|
118 if (from_utf8)
|
|
119 {
|
|
120 if (request->iconv_from_initialized)
|
|
121 {
|
|
122 ret = g_convert_with_iconv (str, -1, request->iconv_from, &bread, dest_len,
|
|
123 &error);
|
|
124 if (ret == NULL)
|
|
125 _do_show_iconv_error (str, request->iconv_charset, from_utf8, error);
|
|
126
|
|
127 return (ret);
|
|
128 }
|
|
129 }
|
|
130 else
|
|
131 {
|
|
132 if (request->iconv_to_initialized)
|
|
133 {
|
|
134 ret = g_convert_with_iconv (str, -1, request->iconv_to, &bread, dest_len,
|
|
135 &error);
|
|
136 if (ret == NULL)
|
|
137 _do_show_iconv_error (str, request->iconv_charset, from_utf8, error);
|
|
138
|
|
139 return (ret);
|
|
140 }
|
|
141 }
|
|
142
|
|
143 stpos = remote_charsets;
|
|
144 while ((cur_charset = _gftp_get_next_charset (&stpos)) != NULL)
|
|
145 {
|
|
146 if (from_utf8)
|
|
147 {
|
|
148 fromset = "UTF-8";
|
|
149 toset = cur_charset;
|
|
150 if ((request->iconv_from = g_iconv_open (toset, fromset)) == (GIConv) -1)
|
|
151 {
|
|
152 g_free (cur_charset);
|
|
153 continue;
|
|
154 }
|
|
155
|
|
156 error = NULL;
|
|
157 if ((ret = g_convert_with_iconv (str, -1, request->iconv_from, &bread,
|
|
158 dest_len, &error)) == NULL)
|
|
159 {
|
|
160 g_iconv_close (request->iconv_from);
|
|
161 request->iconv_from = NULL;
|
|
162 _do_show_iconv_error (str, cur_charset, from_utf8, error);
|
|
163 g_free (cur_charset);
|
|
164 continue;
|
|
165 }
|
|
166
|
|
167 request->iconv_from_initialized = 1;
|
|
168 }
|
|
169 else
|
|
170 {
|
|
171 fromset = cur_charset;
|
|
172 toset = "UTF-8";
|
|
173 if ((request->iconv_to = g_iconv_open (toset, fromset)) == (GIConv) -1)
|
|
174 {
|
|
175 g_free (cur_charset);
|
|
176 continue;
|
|
177 }
|
|
178
|
|
179 error = NULL;
|
|
180 if ((ret = g_convert_with_iconv (str, -1, request->iconv_to, &bread,
|
|
181 dest_len, &error)) == NULL)
|
|
182 {
|
|
183 g_iconv_close (request->iconv_to);
|
|
184 request->iconv_to = NULL;
|
|
185 _do_show_iconv_error (str, cur_charset, from_utf8, error);
|
|
186 g_free (cur_charset);
|
|
187 continue;
|
|
188 }
|
|
189
|
|
190 request->iconv_to_initialized = 1;
|
|
191 }
|
|
192
|
|
193 request->iconv_charset = cur_charset;
|
|
194 return (ret);
|
|
195 }
|
|
196
|
|
197 return (NULL);
|
|
198 }
|
|
199
|
|
200 char *
|
|
201 gftp_string_to_utf8 (gftp_request * request, const char *str, size_t *dest_len)
|
|
202 {
|
|
203 return (_do_convert_string (request, 0, 0, str, dest_len, 0));
|
|
204 }
|
|
205
|
|
206
|
|
207 char *
|
|
208 gftp_string_from_utf8 (gftp_request * request, int force_local, const char *str,
|
|
209 size_t *dest_len)
|
|
210 {
|
|
211 return (_do_convert_string (request, 0, force_local, str, dest_len, 1));
|
|
212 }
|
|
213
|
|
214
|
|
215 char *
|
|
216 gftp_filename_to_utf8 (gftp_request * request, const char *str,
|
|
217 size_t *dest_len)
|
|
218 {
|
|
219 return (_do_convert_string (request, 1, 0, str, dest_len, 0));
|
|
220 }
|
|
221
|
|
222
|
|
223 char *
|
|
224 gftp_filename_from_utf8 (gftp_request * request, const char *str,
|
|
225 size_t *dest_len)
|
|
226 {
|
|
227 return (_do_convert_string (request, 1, 0, str, dest_len, 1));
|
|
228 }
|
|
229
|
|
230 #else
|
|
231
|
|
232 char *
|
|
233 gftp_string_to_utf8 (gftp_request * request, const char *str, size_t dest_len)
|
|
234 {
|
|
235 return (NULL);
|
|
236 }
|
|
237
|
|
238
|
|
239 char *
|
|
240 gftp_string_from_utf8 (gftp_request * request, int force_local, const char *str,
|
|
241 size_t dest_len)
|
|
242 {
|
|
243 return (NULL);
|
|
244 }
|
|
245
|
|
246
|
|
247 char *
|
|
248 gftp_filename_to_utf8 (gftp_request * request, const char *str, size_t dest_len)
|
|
249 {
|
|
250 return (NULL);
|
|
251 }
|
|
252
|
|
253
|
|
254 char *
|
|
255 gftp_filename_from_utf8 (gftp_request * request, int force_local,
|
|
256 const char *str, size_t dest_len)
|
|
257 {
|
|
258 return (NULL);
|
|
259 }
|
|
260
|
|
261 #endif
|
|
262
|
|
263
|