comparison src/util.c @ 7679:1363f91da9cc

[gaim-migrate @ 8323] The real patch that handles mime email stuff from Felipe Contreras (revo)(shx), after I nagged him a bunch to change some stuff. Thanks! committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 01 Dec 2003 03:41:50 +0000
parents 66d9440db6ec
children db1542e84ee6
comparison
equal deleted inserted replaced
7678:cf6a7939af78 7679:1363f91da9cc
242 242
243 if (size) 243 if (size)
244 *size = len; 244 *size = len;
245 } 245 }
246 246
247 /**************************************************************************
248 * Quoted Printable Functions
249 **************************************************************************/
250 void
251 gaim_quotedp_decode(const char *str, char **ret_str, int *ret_len)
252 {
253 char *p, *n, *new;
254
255 n = new = malloc(strlen (str));
256
257 for (p = (char *)str; *p; p++, n++) {
258 if (*p == '=') {
259 sscanf(p + 1, "%2x\n", (int *)n);
260 p += 2;
261 }
262 else if (*p == '_')
263 *n = ' ';
264 else
265 *n = *p;
266 }
267
268 *n = '\0';
269
270 if (ret_len)
271 *ret_len = n - new;
272
273 /* Resize to take less space */
274 /* new = realloc(new, n - new); */
275
276 *ret_str = new;
277 }
278
279 /**************************************************************************
280 * MIME Functions
281 **************************************************************************/
282 #define OUT_CHARSET "utf-8"
283
284 char *
285 gaim_mime_decode_word(const char *charset, const char *encoding, const char *str)
286 {
287 /* TODO: We need to check for nulls */
288 char *decoded, *converted;
289 int len = 0;
290
291 if (g_ascii_strcasecmp(encoding, "Q") == 0)
292 gaim_quotedp_decode(str, &decoded, &len);
293 else if (g_ascii_strcasecmp(encoding, "B") == 0)
294 gaim_base64_decode(str, &decoded, &len);
295 else
296 return NULL;
297
298 converted = g_convert(decoded, len, OUT_CHARSET, charset, NULL, NULL, NULL);
299 g_free(decoded);
300
301 return converted;
302 }
303
304 char *
305 gaim_mime_decode_field(const char *str)
306 {
307 char *cur, *mark;
308 char *unencoded_start, *unencoded_end;
309 char *charset, *encoding, *word, *decoded;
310 char *n, *new;
311
312 n = new = malloc(strlen(str));
313 charset = word = NULL;
314
315 /* Here we will be looking for encoded words and if they seem to be
316 * valid then decode them */
317
318 for ( unencoded_start = cur = (char *)str;
319 (unencoded_end = cur = strstr(cur, "=?"));
320 unencoded_start = cur)
321 {
322 int len;
323 char *token;
324 GQueue *tokens = g_queue_new();
325
326 for (cur += 2, mark = cur; *cur; cur++) {
327 if (*cur == '?') {
328 token = g_strndup(mark, cur - mark);
329 g_queue_push_head(tokens, token);
330
331 mark = (cur + 1);
332
333 if (mark[0] == '=' && mark[1] == '\0')
334 break;
335 } else {
336 if ((tokens->length == 2) && (*cur == ' '))
337 break;
338 else if ((tokens->length < 2) && (strchr("()<>@,;:/[]", *cur)))
339 break;
340 else if (tokens->length > 2)
341 break;
342 }
343 }
344
345 cur += 2;
346
347 if ((tokens->length == 3) && (*mark == '=')) {
348 len = unencoded_end - unencoded_start;
349 n = strncpy(n, unencoded_start, len) + len;
350
351 charset = g_queue_pop_tail(tokens);
352 encoding = g_queue_pop_tail(tokens);
353 word = g_queue_pop_tail(tokens);
354
355 if ((decoded = gaim_mime_decode_word(charset, encoding, word))) {
356 len = strlen(decoded);
357 n = strncpy(n, decoded, len) + len;
358 g_free(decoded);
359 }
360
361 g_free(charset);
362 g_free(encoding);
363 g_free(word);
364 } else {
365 len = cur - unencoded_start;
366 n = strncpy(n, unencoded_start, len) + len;
367
368 while ((token = g_queue_pop_tail(tokens)))
369 g_free(token);
370 }
371
372 g_queue_free(tokens);
373 }
374
375 *n = '\0';
376
377 if (*unencoded_start)
378 n = strcpy(n, unencoded_start);
379
380 return new;
381 }
247 382
248 /************************************************************************** 383 /**************************************************************************
249 * Date/Time Functions 384 * Date/Time Functions
250 **************************************************************************/ 385 **************************************************************************/
251 const char * 386 const char *