Example #1
0
static gboolean
emqfe_headers_format (EMailFormatterExtension *extension,
                      EMailFormatter *formatter,
                      EMailFormatterContext *context,
                      EMailPart *part,
                      GOutputStream *stream,
                      GCancellable *cancellable)
{
	CamelContentType *ct;
	CamelMimePart *mime_part;
	const gchar *charset;
	GString *buffer;
	gchar **default_headers;
	guint ii, length = 0;

	g_return_val_if_fail (E_IS_MAIL_PART_HEADERS (part), FALSE);

	mime_part = e_mail_part_ref_mime_part (part);

	ct = camel_mime_part_get_content_type (mime_part);
	charset = camel_content_type_param (ct, "charset");
	charset = camel_iconv_charset_name (charset);

	buffer = g_string_new ("");

	/* dump selected headers */

	default_headers = e_mail_part_headers_dup_default_headers (
		E_MAIL_PART_HEADERS (part));
	if (default_headers != NULL)
		length = g_strv_length (default_headers);

	for (ii = 0; ii < length; ii++)
		emfqe_format_header (
			formatter, context, buffer, part,
			default_headers[ii], charset);

	g_strfreev (default_headers);

	g_string_append (buffer, HEADER_PREFIX);
	g_string_append (buffer, "<br>");
	g_string_append (buffer, HEADER_SUFFIX);

	g_output_stream_write_all (
		stream, buffer->str, buffer->len, NULL, cancellable, NULL);

	g_string_free (buffer, TRUE);

	g_object_unref (mime_part);

	return TRUE;
}
Example #2
0
const gchar *
camel_iconv_charset_language (const gchar *charset)
{
	gint i;

	if (!charset)
		return NULL;

	charset = camel_iconv_charset_name (charset);
	for (i = 0; i < G_N_ELEMENTS (cjkr_lang_map); i++) {
		if (!g_ascii_strcasecmp (cjkr_lang_map[i].charset, charset))
			return cjkr_lang_map[i].lang;
	}

	return NULL;
}
Example #3
0
static CamelSExpResult *
check_header (struct _CamelSExp *f,
              gint argc,
              struct _CamelSExpResult **argv,
              FilterMessageSearch *fms,
              camel_search_match_t how)
{
	gboolean matched = FALSE;
	CamelSExpResult *r;
	gint i;

	if (argc > 1 && argv[0]->type == CAMEL_SEXP_RES_STRING) {
		gchar *name = argv[0]->value.string;

		/* shortcut: a match for "" against any header always matches */
		for (i = 1; i < argc && !matched; i++)
			matched = argv[i]->type == CAMEL_SEXP_RES_STRING && argv[i]->value.string[0] == 0;

		if (g_ascii_strcasecmp (name, "x-camel-mlist") == 0) {
			const gchar *list = camel_message_info_mlist (fms->info);

			if (list) {
				for (i = 1; i < argc && !matched; i++) {
					if (argv[i]->type == CAMEL_SEXP_RES_STRING)
						matched = camel_search_header_match (list, argv[i]->value.string, how, CAMEL_SEARCH_TYPE_MLIST, NULL);
				}
			}
		} else if (fms->message || !check_header_in_message_info (fms->info, argc, argv, how, &matched)) {
			CamelMimeMessage *message;
			CamelMimePart *mime_part;
			struct _camel_header_raw *header;
			const gchar *charset = NULL;
			camel_search_t type = CAMEL_SEARCH_TYPE_ENCODED;
			CamelContentType *ct;

			message = camel_filter_search_get_message (fms, f);
			mime_part = CAMEL_MIME_PART (message);

			/* FIXME: what about Resent-To, Resent-Cc and Resent-From? */
			if (g_ascii_strcasecmp ("to", name) == 0 || g_ascii_strcasecmp ("cc", name) == 0 || g_ascii_strcasecmp ("from", name) == 0)
				type = CAMEL_SEARCH_TYPE_ADDRESS_ENCODED;
			else if (message) {
				ct = camel_mime_part_get_content_type (mime_part);
				if (ct) {
					charset = camel_content_type_param (ct, "charset");
					charset = camel_iconv_charset_name (charset);
				}
			}

			for (header = mime_part->headers; header && !matched; header = header->next) {
				/* empty name means any header */
				if (!name || !*name || !g_ascii_strcasecmp (header->name, name)) {
					for (i = 1; i < argc && !matched; i++) {
						if (argv[i]->type == CAMEL_SEXP_RES_STRING)
							matched = camel_search_header_match (header->value, argv[i]->value.string, how, type, charset);
					}
				}
			}
		}
	}

	r = camel_sexp_result_new (f, CAMEL_SEXP_RES_BOOL);
	r->value.boolean = matched;

	return r;
}
/* FIXME: check format of fields. */
static gboolean
process_header (CamelMedium *medium,
                const gchar *name,
                const gchar *value)
{
	CamelHeaderType header_type;
	CamelMimeMessage *message = CAMEL_MIME_MESSAGE (medium);
	CamelInternetAddress *addr;
	const gchar *charset;
	gchar *unfolded;

	header_type = (CamelHeaderType) g_hash_table_lookup (header_name_table, name);
	switch (header_type) {
	case HEADER_FROM:
		addr = camel_internet_address_new ();
		unfolded = camel_header_unfold (value);
		if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
			g_object_unref (addr);
		} else {
			if (message->from)
				g_object_unref (message->from);
			message->from = addr;
		}
		g_free (unfolded);
		break;
	case HEADER_REPLY_TO:
		addr = camel_internet_address_new ();
		unfolded = camel_header_unfold (value);
		if (camel_address_decode ((CamelAddress *) addr, unfolded) <= 0) {
			g_object_unref (addr);
		} else {
			if (message->reply_to)
				g_object_unref (message->reply_to);
			message->reply_to = addr;
		}
		g_free (unfolded);
		break;
	case HEADER_SUBJECT:
		g_free (message->subject);
		if (((CamelDataWrapper *) message)->mime_type) {
			charset = camel_content_type_param (((CamelDataWrapper *) message)->mime_type, "charset");
			charset = camel_iconv_charset_name (charset);
		} else
			charset = NULL;

		unfolded = camel_header_unfold (value);
		message->subject = g_strstrip (camel_header_decode_string (unfolded, charset));
		g_free (unfolded);
		break;
	case HEADER_TO:
	case HEADER_CC:
	case HEADER_BCC:
	case HEADER_RESENT_TO:
	case HEADER_RESENT_CC:
	case HEADER_RESENT_BCC:
		addr = g_hash_table_lookup (message->recipients, name);
		if (value) {
			unfolded = camel_header_unfold (value);
			camel_address_decode (CAMEL_ADDRESS (addr), unfolded);
			g_free (unfolded);
		} else {
			camel_address_remove (CAMEL_ADDRESS (addr), -1);
		}
		return FALSE;
	case HEADER_DATE:
		if (value) {
			message->date = camel_header_decode_date (value, &message->date_offset);
		} else {
			message->date = CAMEL_MESSAGE_DATE_CURRENT;
			message->date_offset = 0;
		}
		break;
	case HEADER_MESSAGE_ID:
		g_free (message->message_id);
		if (value)
			message->message_id = camel_header_msgid_decode (value);
		else
			message->message_id = NULL;
		break;
	default:
		return FALSE;
	}

	return TRUE;
}
Example #5
0
/* This should run pretty quick, its called a lot */
iconv_t
camel_iconv_open (const gchar *oto,
                  const gchar *ofrom)
{
	const gchar *to, *from;
	gchar *tofrom;
	struct _iconv_cache *ic;
	struct _iconv_cache_node *in;
	gint errnosav;
	iconv_t ip;

	if (oto == NULL || ofrom == NULL) {
		errno = EINVAL;
		return (iconv_t) -1;
	}

	to = camel_iconv_charset_name (oto);
	from = camel_iconv_charset_name (ofrom);
	tofrom = g_alloca (strlen (to) + strlen (from) + 2);
	sprintf (tofrom, "%s%%%s", to, from);

	G_LOCK (iconv);

	ic = g_hash_table_lookup (iconv_cache, tofrom);
	if (ic) {
		g_queue_remove (&iconv_cache_list, ic);
	} else {
		GList *link;

		link = g_queue_peek_tail_link (&iconv_cache_list);

		while (link != NULL && iconv_cache_list.length > E_ICONV_CACHE_SIZE) {
			GList *prev = g_list_previous (link);

			ic = (struct _iconv_cache *) link->data;
			in = g_queue_peek_head (&ic->open);

			if (in != NULL && !in->busy) {
				cd (printf ("Flushing iconv converter '%s'\n", ic->conv));
				g_queue_delete_link (&iconv_cache_list, link);
				g_hash_table_remove (iconv_cache, ic->conv);
				flush_entry (ic);
			}

			link = prev;
		}

		ic = g_malloc (sizeof (*ic));
		g_queue_init (&ic->open);
		ic->conv = g_strdup (tofrom);
		g_hash_table_insert (iconv_cache, ic->conv, ic);

		cd (printf ("Creating iconv converter '%s'\n", ic->conv));
	}

	g_queue_push_head (&iconv_cache_list, ic);

	/* If we have a free iconv, use it */
	in = g_queue_peek_tail (&ic->open);
	if (in != NULL && !in->busy) {
		cd (printf ("using existing iconv converter '%s'\n", ic->conv));
		ip = in->ip;
		if (ip != (iconv_t) - 1) {
			/* work around some broken iconv implementations
			 * that die if the length arguments are NULL
			 */
			gsize buggy_iconv_len = 0;
			gchar *buggy_iconv_buf = NULL;

			/* resets the converter */
			iconv (ip, &buggy_iconv_buf, &buggy_iconv_len, &buggy_iconv_buf, &buggy_iconv_len);
			in->busy = TRUE;
			g_queue_remove (&ic->open, in);
			g_queue_push_head (&ic->open, in);
		}
	} else {
		cd (printf ("creating new iconv converter '%s'\n", ic->conv));
		ip = iconv_open (to, from);
		in = g_malloc (sizeof (*in));
		in->ip = ip;
		in->parent = ic;
		g_queue_push_head (&ic->open, in);
		if (ip != (iconv_t) - 1) {
			g_hash_table_insert (iconv_cache_open, ip, in);
			in->busy = TRUE;
		} else {
			errnosav = errno;
			g_warning ("Could not open converter for '%s' to '%s' charset", from, to);
			in->busy = FALSE;
			errno = errnosav;
		}
	}

	G_UNLOCK (iconv);

	return ip;
}