/*
* Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2016 Hiroyuki Yamamoto & The Claws Mail Team
+ * Copyright (C) 1999-2020 the Claws Mail Team and 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
#include "timing.h"
#include "privacy.h"
#include "account.h"
-#include "claws_io.h"
+#include "file-utils.h"
static GHashTable *procmime_get_mime_type_table (void);
static MimeInfo *procmime_scan_file_short(const gchar *filename);
gint llen = 0; \
strretchomp(lastline); \
llen = strlen(lastline); \
- if (lastline[llen-1] == ' ' && !account_signatures_matchlist_str_found(lastline, "%s") && \
+ if (lastline[llen-1] == ' ' && !account_sigsep_matchlist_str_found(lastline, "%s") && \
!(llen == 2 && lastline[1] == ' ' && strchr(prefs_common.quote_chars, lastline[0]))) { \
/* this is flowed */ \
if (delsp) \
tmp_file = TRUE;
readend = mimeinfo->offset + mimeinfo->length;
- account_signatures_matchlist_create(); /* FLUSH_LASTLINE will use it */
+ account_sigsep_matchlist_create(); /* FLUSH_LASTLINE will use it */
*buf = '\0';
if (encoding == ENC_QUOTED_PRINTABLE) {
if (flowed)
FLUSH_LASTLINE();
} else if (encoding == ENC_BASE64) {
- gchar outbuf[BUFFSIZE];
+ gchar outbuf[BUFFSIZE + 1];
gint len, inlen, inread;
gboolean got_error = FALSE;
gboolean uncanonicalize = FALSE;
while ((inlen = MIN(readend - ftell(infp), sizeof(buf))) > 0 && !err) {
inread = claws_fread(buf, 1, inlen, infp);
+ memset(outbuf, 0, sizeof(buf));
len = g_base64_decode_step(buf, inlen, outbuf, &state, &save);
if (uncanonicalize == TRUE && strlen(outbuf) < len && starting) {
uncanonicalize = FALSE;
err = TRUE;
}
}
- if (tmpfp != outfp)
+ if (tmpfp != outfp) {
claws_fclose(tmpfp);
+ }
} else if (encoding == ENC_X_UUENCODE) {
gchar outbuf[BUFFSIZE];
gint len;
claws_fclose(outfp);
claws_fclose(infp);
- account_signatures_matchlist_delete();
+ account_sigsep_matchlist_delete();
if (err == TRUE) {
return FALSE;
gchar buf[BUFFSIZE];
gchar *str;
gboolean scan_ret = FALSE;
- gchar *tmpfile = NULL;
int r;
cm_return_val_if_fail(mimeinfo != NULL, TRUE);
if (!procmime_decode_content(mimeinfo))
return TRUE;
-#if HAVE_FMEMOPEN
- tmpfp = fmemopen(NULL, mimeinfo->length * 2, "w+");
-#else
- tmpfile = procmime_get_tmp_file_name(mimeinfo);
- if (tmpfile == NULL) {
- g_warning("no filename\n");
- return TRUE;
- }
-
- tmpfp = claws_fopen(tmpfile, "w+");
-#endif
+ tmpfp = my_tmpfile();
if (tmpfp == NULL) {
- g_free(tmpfile);
- FILE_OP_ERROR(tmpfile, "open");
+ FILE_OP_ERROR("tmpfile", "open");
return TRUE;
}
if ((r = procmime_get_part_to_stream(tmpfp, mimeinfo)) < 0) {
g_warning("procmime_get_part_to_stream error %d\n", r);
- g_free(tmpfile);
return TRUE;
}
claws_fclose(tmpfp);
-#if !HAVE_FMEMOPEN
- claws_unlink(tmpfile);
- g_free(tmpfile);
-#endif
-
return scan_ret;
}
FILE *procmime_get_binary_content(MimeInfo *mimeinfo)
{
FILE *outfp;
-#if !HAVE_FMEMOPEN
- gchar *tmpfile = NULL;
-#endif
cm_return_val_if_fail(mimeinfo != NULL, NULL);
if (!procmime_decode_content(mimeinfo))
return NULL;
-#if HAVE_FMEMOPEN
- outfp = fmemopen(NULL, mimeinfo->length * 2, "w+");
-#else
- tmpfile = procmime_get_tmp_file_name(mimeinfo);
- if (tmpfile == NULL) {
- g_warning("no filename\n");
- return TRUE;
- }
-
- outfp = procmime_fopen(tmpfile, "w+");
-
- g_unlink(tmpfile);
- g_free(tmpfile);
-#endif
+ outfp = my_tmpfile();
if (procmime_get_part_to_stream(outfp, mimeinfo) < 0) {
return NULL;
octet_percentage = 0.0;
debug_print("procmime_get_encoding_for_text_file(): "
- "8bit chars: %zd / %zd (%f%%)\n", octet_chars, total_len,
+ "8bit chars: %"G_GSIZE_FORMAT" / %"G_GSIZE_FORMAT" (%f%%)\n", octet_chars, total_len,
100.0 * octet_percentage);
if (octet_percentage > 0.20 || force_b64) {
{"image", MIMETYPE_IMAGE},
{"audio", MIMETYPE_AUDIO},
{"video", MIMETYPE_VIDEO},
+ {"model", MIMETYPE_MODEL},
{"application", MIMETYPE_APPLICATION},
{"message", MIMETYPE_MESSAGE},
{"multipart", MIMETYPE_MULTIPART},
GSList *cur;
for (cur = registered_parsers; cur; cur = cur->next) {
MimeParser *parser = (MimeParser *)cur->data;
- if (parser->type == type && !strcmp2(parser->sub_type, sub_type))
+ if (parser->type == type && !g_strcmp0(parser->sub_type, sub_type))
return parser;
}
return NULL;
depth = g_node_depth(node);
for (i = 0; i < depth; i++)
g_print(" ");
- g_print("%s/%s (offset:%d length:%d encoding: %d)\n", typenames[mimeinfo->type], mimeinfo->subtype, mimeinfo->offset, mimeinfo->length, mimeinfo->encoding_type);
+ g_print("%s/%s (offset:%d length:%d encoding: %d)\n",
+ (mimeinfo->type < 8)? typenames[mimeinfo->type] : "unknown",
+ mimeinfo->subtype, mimeinfo->offset, mimeinfo->length, mimeinfo->encoding_type);
return FALSE;
}
}
len = strlen(buf);
if (claws_fwrite(buf, sizeof(gchar), len, fp) < len) {
- g_warning("failed to dump %zd bytes from file", len);
+ g_warning("failed to dump %"G_GSIZE_FORMAT" bytes from file", len);
claws_fclose(infp);
return -1;
}
case MIMECONTENT_MEM:
len = strlen(mimeinfo->data.mem);
if (claws_fwrite(mimeinfo->data.mem, sizeof(gchar), len, fp) < len) {
- g_warning("failed to dump %zd bytes from mem", len);
+ g_warning("failed to dump %"G_GSIZE_FORMAT" bytes from mem", len);
return -1;
}
break;
break;
len = strlen(buf);
if (claws_fwrite(buf, sizeof(gchar), len, fp) < len) {
- g_warning("failed to write %zd", len);
+ g_warning("failed to write %"G_GSIZE_FORMAT, len);
claws_fclose(infp);
return -1;
}
*(str2 - 2) = '\0';
len = strlen(str);
if (claws_fwrite(str, sizeof(gchar), len, fp) < len) {
- g_warning("failed to write %zd from mem", len);
+ g_warning("failed to write %"G_GSIZE_FORMAT" from mem", len);
g_free(str);
return -1;
}
return base;
}
+void *procmime_get_part_as_string(MimeInfo *mimeinfo,
+ gboolean null_terminate)
+{
+ FILE *infp;
+ gchar *data;
+ gint length, readlength;
+
+ cm_return_val_if_fail(mimeinfo != NULL, NULL);
+
+ if (mimeinfo->encoding_type != ENC_BINARY &&
+ !procmime_decode_content(mimeinfo))
+ return NULL;
+
+ if (mimeinfo->content == MIMECONTENT_MEM)
+ return g_strdup(mimeinfo->data.mem);
+
+ if ((infp = claws_fopen(mimeinfo->data.filename, "rb")) == NULL) {
+ FILE_OP_ERROR(mimeinfo->data.filename, "claws_fopen");
+ return NULL;
+ }
+
+ if (fseek(infp, mimeinfo->offset, SEEK_SET) < 0) {
+ FILE_OP_ERROR(mimeinfo->data.filename, "fseek");
+ claws_fclose(infp);
+ return NULL;
+ }
+
+ length = mimeinfo->length;
+
+ data = g_malloc(null_terminate ? length + 1 : length);
+ if (data == NULL) {
+ g_warning("Could not allocate %d bytes for procmime_get_part_as_string.\n",
+ (null_terminate ? length + 1 : length));
+ claws_fclose(infp);
+ return NULL;
+ }
+
+ readlength = claws_fread(data, length, 1, infp);
+ if (readlength <= 0) {
+ FILE_OP_ERROR(mimeinfo->data.filename, "fread");
+ g_free(data);
+ claws_fclose(infp);
+ return NULL;
+ }
+
+ claws_fclose(infp);
+
+ if (null_terminate)
+ data[length] = '\0';
+
+ return data;
+}
+
+/* Returns an open GInputStream. The caller should just
+ * read mimeinfo->length bytes from it and then release it. */
+GInputStream *procmime_get_part_as_inputstream(MimeInfo *mimeinfo)
+{
+ cm_return_val_if_fail(mimeinfo != NULL, NULL);
+
+ if (mimeinfo->encoding_type != ENC_BINARY &&
+ !procmime_decode_content(mimeinfo)) {
+ g_warning("could not decode part");
+ return NULL;
+ }
+ if (mimeinfo->content == MIMECONTENT_MEM) {
+ /* NULL for destroy func, since we're not copying
+ * the data for the stream. */
+ return g_memory_input_stream_new_from_data(
+ mimeinfo->data.mem,
+ mimeinfo->length, NULL);
+ } else {
+ return g_memory_input_stream_new_from_data(
+ procmime_get_part_as_string(mimeinfo, FALSE),
+ mimeinfo->length, g_free);
+ }
+}
+
+GdkPixbuf *procmime_get_part_as_pixbuf(MimeInfo *mimeinfo, GError **error)
+{
+ GdkPixbuf *pixbuf;
+ GInputStream *stream;
+
+ if (error)
+ *error = NULL;
+
+ stream = procmime_get_part_as_inputstream(mimeinfo);
+ if (stream == NULL) {
+ if (error)
+ *error = g_error_new_literal(G_FILE_ERROR, -1, _("Could not decode part"));
+ return NULL;
+ }
+
+ pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, error);
+ g_object_unref(stream);
+
+ if (error && *error != NULL)
+ return NULL;
+
+ return pixbuf;
+}
+