X-Git-Url: http://git.claws-mail.org/?p=claws.git;a=blobdiff_plain;f=src%2Fprocmime.c;h=97585cc3c1128c678225241330a30a78f8be88bf;hp=186630393653a1426a4993550cb4b69d0e24ae6e;hb=99a7382d8fc0b91c98475ec8c92c9a86975accc7;hpb=20d157dd6790aa6f3f6709ea918b12d1ae0f9283;ds=sidebyside diff --git a/src/procmime.c b/src/procmime.c index 186630393..97585cc3c 100644 --- a/src/procmime.c +++ b/src/procmime.c @@ -1,6 +1,6 @@ /* * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client - * Copyright (C) 1999-2001 Hiroyuki Yamamoto + * Copyright (C) 1999-2003 Hiroyuki Yamamoto * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ #include "procmime.h" #include "procheader.h" #include "base64.h" +#include "quoted-printable.h" #include "uuencode.h" #include "unmime.h" #include "html.h" @@ -45,7 +46,7 @@ # include "rfc2015.h" #endif -#include "prefs.h" +#include "prefs_gtk.h" static GHashTable *procmime_get_mime_type_table (void); @@ -60,28 +61,6 @@ MimeInfo *procmime_mimeinfo_new(void) return mimeinfo; } -void procmime_mimeinfo_free(MimeInfo *mimeinfo) -{ - if (!mimeinfo) return; - - g_free(mimeinfo->encoding); - g_free(mimeinfo->content_type); - g_free(mimeinfo->charset); - g_free(mimeinfo->name); - g_free(mimeinfo->boundary); - g_free(mimeinfo->content_disposition); - g_free(mimeinfo->filename); -#if USE_GPGME - g_free(mimeinfo->plaintextfile); - g_free(mimeinfo->sigstatus); - g_free(mimeinfo->sigstatus_full); -#endif - - procmime_mimeinfo_free(mimeinfo->sub); - - g_free(mimeinfo); -} - void procmime_mimeinfo_free_all(MimeInfo *mimeinfo) { while (mimeinfo != NULL) { @@ -168,6 +147,12 @@ MimeInfo *procmime_mimeinfo_next(MimeInfo *mimeinfo) if (mimeinfo->next) return mimeinfo->next; + if (mimeinfo->main) { + mimeinfo = mimeinfo->main; + if (mimeinfo->next) + return mimeinfo->next; + } + for (mimeinfo = mimeinfo->parent; mimeinfo != NULL; mimeinfo = mimeinfo->parent) { if (mimeinfo->next) @@ -244,12 +229,12 @@ void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp) return; } - for (npart = 0;; npart++) { MimeInfo *partinfo; gboolean eom = FALSE; prev_fpos = fpos; + debug_print("prev_fpos: %ld\n", fpos); partinfo = procmime_scan_mime_header(fp); if (!partinfo) break; @@ -263,14 +248,20 @@ void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp) partinfo->sub = sub = procmime_scan_mime_header(fp); if (!sub) break; + sub->level = partinfo->level + 1; - sub->parent = partinfo->parent; + sub->parent = partinfo; sub->main = partinfo; - if (sub->mime_type == MIME_MULTIPART) { - if (sub->level < 8) + if (sub->level < 8) { + if (sub->mime_type == MIME_MULTIPART) { procmime_scan_multipart_message (sub, fp); + } else if (sub->mime_type == MIME_MESSAGE_RFC822) { + fseek(fp, sub->fpos, SEEK_SET); + procmime_scan_multipart_message + (sub, fp); + } } } @@ -284,11 +275,23 @@ void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp) break; } } - if (p == NULL) - eom = TRUE; /* broken MIME message */ + if (p == NULL) { + /* broken MIME, or single part MIME message */ + buf[0] = '\0'; + eom = TRUE; + } fpos = ftell(fp); + debug_print("fpos: %ld\n", fpos); partinfo->size = fpos - prev_fpos - strlen(buf); + debug_print("partinfo->size: %d\n", partinfo->size); + if (partinfo->sub && !partinfo->sub->sub && + !partinfo->sub->children) { + partinfo->sub->size = fpos - partinfo->sub->fpos - strlen(buf); + debug_print("partinfo->sub->size: %d\n", + partinfo->sub->size); + } + debug_print("boundary: %s\n", buf); if (eom) break; } @@ -379,7 +382,10 @@ void procmime_scan_content_type(MimeInfo *mimeinfo, const gchar *content_type) Xalloca(tmp, len, return); conv_unmime_header(tmp, len, value, NULL); g_free(mimeinfo->name); - mimeinfo->name = g_strdup(tmp); + /*pgp signatures should NOT have a name */ + if (mimeinfo->content_type + && strcasecmp(mimeinfo->content_type, "application/pgp-signature")) + mimeinfo->name = g_strdup(tmp); } else if (!strcasecmp(attr, "boundary")) mimeinfo->boundary = g_strdup(value); } @@ -443,7 +449,10 @@ void procmime_scan_content_disposition(MimeInfo *mimeinfo, Xalloca(tmp, len, return); conv_unmime_header(tmp, len, value, NULL); g_free(mimeinfo->filename); - mimeinfo->filename = g_strdup(tmp); + /*pgp signatures should NOT have a name */ + if (mimeinfo->content_type + && strcasecmp(mimeinfo->content_type, "application/pgp-signature")) + mimeinfo->filename = g_strdup(tmp); break; } } @@ -456,7 +465,6 @@ void procmime_scan_content_disposition(MimeInfo *mimeinfo, void procmime_scan_content_description(MimeInfo *mimeinfo, const gchar *content_description) { - gchar *delim, *p, *dispos; gchar *buf; gchar *tmp; @@ -475,13 +483,16 @@ void procmime_scan_content_description(MimeInfo *mimeinfo, Xalloca(tmp, blen, return); conv_unmime_header(tmp, blen, buf, NULL); g_free(mimeinfo->name); - mimeinfo->name = g_strdup(tmp); + mimeinfo->name = NULL; + /*pgp signatures should NOT have a name */ + if (mimeinfo->content_type + && strcasecmp(mimeinfo->content_type, "application/pgp-signature")) + mimeinfo->name = g_strdup(tmp); } void procmime_scan_subject(MimeInfo *mimeinfo, const gchar *subject) { - gchar *delim, *p, *dispos; gchar *buf; gchar *tmp; @@ -597,15 +608,12 @@ FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo) } if (mimeinfo->encoding_type == ENC_QUOTED_PRINTABLE) { - gboolean softline = FALSE; - while (fgets(buf, sizeof(buf), infp) != NULL && (!boundary || !IS_BOUNDARY(buf, boundary, boundary_len))) { - guchar *p = buf; - - softline = DoOneQPLine(&p, FALSE, softline); - fwrite(buf, p - (guchar *)buf, 1, outfp); + gint len; + len = qp_decode_line(buf); + fwrite(buf, len, 1, outfp); } } else if (mimeinfo->encoding_type == ENC_BASE64) { gchar outbuf[BUFFSIZE]; @@ -764,7 +772,6 @@ void renderer_read_config(void) void renderer_write_config(void) { - int i; gchar * rcpath; PrefFile *pfile; GList * cur; @@ -772,7 +779,7 @@ void renderer_write_config(void) rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, RENDERER_RC, NULL); if ((pfile = prefs_write_open(rcpath)) == NULL) { - g_warning(_("failed to write configuration to file\n")); + g_warning("failed to write configuration to file\n"); g_free(rcpath); return; } @@ -786,8 +793,8 @@ void renderer_write_config(void) renderer->renderer); } - if (prefs_write_close(pfile) < 0) { - g_warning(_("failed to write configuration to file\n")); + if (prefs_file_close(pfile) < 0) { + g_warning("failed to write configuration to file\n"); return; } } @@ -799,7 +806,6 @@ FILE *procmime_get_text_content(MimeInfo *mimeinfo, FILE *infp) gboolean conv_fail = FALSE; gchar buf[BUFFSIZE]; gchar *str; - int i; struct ContentRenderer * renderer; GList * cur; @@ -898,7 +904,7 @@ FILE *procmime_get_text_content(MimeInfo *mimeinfo, FILE *infp) } if (conv_fail) - g_warning(_("procmime_get_text_content(): Code conversion failed.\n")); + g_warning("procmime_get_text_content(): Code conversion failed.\n"); fclose(tmpfp); rewind(outfp); @@ -1232,21 +1238,66 @@ EncodingType procmime_get_encoding_for_charset(const gchar *charset) else if (!strncasecmp(charset, "ISO-2022-", 9) || !strcasecmp(charset, "US-ASCII")) return ENC_7BIT; + else if (!strcasecmp(charset, "ISO-8859-5") || + !strncasecmp(charset, "KOI8-", 5) || + !strcasecmp(charset, "Windows-1251")) + return ENC_8BIT; + else if (!strncasecmp(charset, "ISO-8859-", 9)) + return ENC_QUOTED_PRINTABLE; else return ENC_8BIT; - /* return ENC_BASE64; */ - /* return ENC_QUOTED_PRINTABLE; */ } -const gchar *procmime_get_encoding_str(EncodingType encoding) +EncodingType procmime_get_encoding_for_file(const gchar *file) { - static const gchar *encoding_str[] = { - "7bit", "8bit", "quoted-printable", "base64", "x-uuencode", - NULL - }; + FILE *fp; + guchar buf[BUFSIZ]; + size_t len; - if (encoding >= ENC_7BIT && encoding <= ENC_UNKNOWN) - return encoding_str[encoding]; - else - return NULL; + if ((fp = fopen(file, "rb")) == NULL) { + FILE_OP_ERROR(file, "fopen"); + return ENC_UNKNOWN; + } + + while ((len = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) { + guchar *p; + gint i; + + for (p = buf, i = 0; i < len; p++, i++) { + if (*p & 0x80) { + fclose(fp); + return ENC_BASE64; + } + } + } + + fclose(fp); + return ENC_7BIT; +} + +struct EncodingTable +{ + gchar *str; + EncodingType enc_type; +}; + +struct EncodingTable encoding_table[] = { + {"7bit", ENC_7BIT}, + {"8bit", ENC_8BIT}, + {"binary", ENC_BINARY}, + {"quoted-printable", ENC_QUOTED_PRINTABLE}, + {"base64", ENC_BASE64}, + {"x-uuencode", ENC_UNKNOWN}, + {NULL, ENC_UNKNOWN}, +}; + +const gchar *procmime_get_encoding_str(EncodingType encoding) +{ + struct EncodingTable *enc_table; + + for (enc_table = encoding_table; enc_table->str != NULL; enc_table++) { + if (enc_table->enc_type == encoding) + return enc_table->str; + } + return NULL; }