commit bc4915bb92508d919130ad229d8483324b82f039
parent 39be80dde52ad1b5815fc14af5bec39068ee55d9
Author: Michael Rasmussen <mir@datanom.net>
Date: Thu, 16 Nov 2017 17:18:24 +0100
Merge branch 'master' of ssh+git://git.claws-mail.org/home/git/claws
Diffstat:
15 files changed, 718 insertions(+), 420 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
@@ -142,6 +142,7 @@ claws_mail_SOURCES = \
displayheader.c \
edittags.c \
enriched.c \
+ entity.c \
export.c \
file_checker.c \
filtering.c \
@@ -260,6 +261,7 @@ claws_mailinclude_HEADERS = \
displayheader.h \
edittags.h \
enriched.h \
+ entity.h \
export.h \
filtering.h \
folder.h \
diff --git a/src/common/utils.c b/src/common/utils.c
@@ -1054,7 +1054,7 @@ void subst_for_filename(gchar *str)
if (!str)
return;
#ifdef G_OS_WIN32
- subst_chars(str, "\t\r\n\\/*:", '_');
+ subst_chars(str, "\t\r\n\\/*?:", '_');
#else
subst_chars(str, "\t\r\n\\/*", '_');
#endif
@@ -2028,6 +2028,27 @@ const gchar *get_domain_name(void)
off_t get_file_size(const gchar *file)
{
+#ifdef G_OS_WIN32
+ GFile *f;
+ GFileInfo *fi;
+ GError *error = NULL;
+ goffset size;
+
+ f = g_file_new_for_path(file);
+ fi = g_file_query_info(f, "standard::size",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ if (error != NULL) {
+ debug_print("get_file_size error: %s\n", error->message);
+ g_error_free(error);
+ g_object_unref(f);
+ return -1;
+ }
+ size = g_file_info_get_size(fi);
+ g_object_unref(fi);
+ g_object_unref(f);
+ return size;
+
+#else
GStatBuf s;
if (g_stat(file, &s) < 0) {
@@ -2036,6 +2057,7 @@ off_t get_file_size(const gchar *file)
}
return s.st_size;
+#endif
}
time_t get_file_mtime(const gchar *file)
diff --git a/src/compose.c b/src/compose.c
@@ -3633,31 +3633,58 @@ static ComposeInsertResult compose_insert_file(Compose *compose, const gchar *fi
gint len;
FILE *fp;
gboolean prev_autowrap;
+#ifdef G_OS_WIN32
+ GFile *f;
+ GFileInfo *fi;
+ GError *error = NULL;
+#else
GStatBuf file_stat;
+#endif
int ret;
+ goffset size;
GString *file_contents = NULL;
ComposeInsertResult result = COMPOSE_INSERT_SUCCESS;
cm_return_val_if_fail(file != NULL, COMPOSE_INSERT_NO_FILE);
/* get the size of the file we are about to insert */
+#ifdef G_OS_WIN32
+ f = g_file_new_for_path(file);
+ fi = g_file_query_info(f, "standard::size",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ ret = 0;
+ if (error != NULL) {
+ g_warning(error->message);
+ ret = 1;
+ g_error_free(error);
+ g_object_unref(f);
+ }
+#else
ret = g_stat(file, &file_stat);
+#endif
if (ret != 0) {
gchar *shortfile = g_path_get_basename(file);
alertpanel_error(_("Could not get size of file '%s'."), shortfile);
g_free(shortfile);
return COMPOSE_INSERT_NO_FILE;
} else if (prefs_common.warn_large_insert == TRUE) {
+#ifdef G_OS_WIN32
+ size = g_file_info_get_size(fi);
+ g_object_unref(fi);
+ g_object_unref(f);
+#else
+ size = file_stat.st_size;
+#endif
/* ask user for confirmation if the file is large */
if (prefs_common.warn_large_insert_size < 0 ||
- file_stat.st_size > (prefs_common.warn_large_insert_size * 1024)) {
+ size > ((goffset) prefs_common.warn_large_insert_size * 1024)) {
AlertValue aval;
gchar *msg;
msg = g_strdup_printf(_("You are about to insert a file of %s "
"in the message body. Are you sure you want to do that?"),
- to_human_readable(file_stat.st_size));
+ to_human_readable(size));
aval = alertpanel_full(_("Are you sure?"), msg, GTK_STOCK_CANCEL,
g_strconcat("+", _("_Insert"), NULL), NULL, TRUE, NULL, ALERT_QUESTION, G_ALERTDEFAULT);
g_free(msg);
@@ -6325,7 +6352,14 @@ static int compose_add_attachments(Compose *compose, MimeInfo *parent)
AttachInfo *ainfo;
GtkTreeView *tree_view = GTK_TREE_VIEW(compose->attach_clist);
MimeInfo *mimepart;
+#ifdef G_OS_WIN32
+ GFile *f;
+ GFileInfo *fi;
+ GError *error = NULL;
+#else
GStatBuf statbuf;
+#endif
+ goffset size;
gchar *type, *subtype;
GtkTreeModel *model;
GtkTreeIter iter;
@@ -6347,15 +6381,31 @@ static int compose_add_attachments(Compose *compose, MimeInfo *parent)
}
continue;
}
+#ifdef G_OS_WIN32
+ f = g_file_new_for_path(ainfo->file);
+ fi = g_file_query_info(f, "standard::size",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ if (error != NULL) {
+ g_warning(error->message);
+ g_error_free(error);
+ g_object_unref(f);
+ return -1;
+ }
+ size = g_file_info_get_size(fi);
+ g_object_unref(fi);
+ g_object_unref(f);
+#else
if (g_stat(ainfo->file, &statbuf) < 0)
return -1;
+ size = statbuf.st_size;
+#endif
mimepart = procmime_mimeinfo_new();
mimepart->content = MIMECONTENT_FILE;
mimepart->data.filename = g_strdup(ainfo->file);
mimepart->tmp = FALSE; /* or we destroy our attachment */
mimepart->offset = 0;
- mimepart->length = statbuf.st_size;
+ mimepart->length = size;
type = g_strdup(ainfo->content_type);
@@ -10433,26 +10483,56 @@ warn_err:
compose_close(compose);
return TRUE;
} else {
+#ifdef G_OS_WIN32
+ GFile *f;
+ GFileInfo *fi;
+ GTimeVal tv;
+ GError *error;
+#else
GStatBuf s;
+#endif
gchar *path;
+ goffset size, mtime;
path = folder_item_fetch_msg(draft, msgnum);
if (path == NULL) {
debug_print("can't fetch %s:%d\n", draft->path, msgnum);
goto unlock;
}
+#ifdef G_OS_WIN32
+ f = g_file_new_for_path(path);
+ fi = g_file_query_info(f, "standard::size,time::modified",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ if (error != NULL) {
+ debug_print("couldn't query file info for '%s': %s\n",
+ path, error->message);
+ g_error_free(error);
+ g_free(path);
+ g_object_unref(f);
+ goto unlock;
+ }
+ size = g_file_info_get_size(fi);
+ g_file_info_get_modification_time(fi, &tv);
+ mtime = tv.tv_sec;
+ g_object_unref(fi);
+ g_object_unref(f);
+ g_free(path);
+#else
if (g_stat(path, &s) < 0) {
FILE_OP_ERROR(path, "stat");
g_free(path);
goto unlock;
}
+ size = s.st_size;
+ mtime = s.st_mtime;
+#endif
g_free(path);
procmsg_msginfo_free(&(compose->targetinfo));
compose->targetinfo = procmsg_msginfo_new();
compose->targetinfo->msgnum = msgnum;
- compose->targetinfo->size = (goffset)s.st_size;
- compose->targetinfo->mtime = s.st_mtime;
+ compose->targetinfo->size = size;
+ compose->targetinfo->mtime = mtime;
compose->targetinfo->folder = draft;
if (target_locked)
procmsg_msginfo_set_flags(compose->targetinfo, MSG_LOCKED, 0);
diff --git a/src/entity.c b/src/entity.c
@@ -0,0 +1,403 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2017 Ricardo Mones and the Claws Mail team
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#include "claws-features.h"
+#endif
+
+#include "defs.h"
+#include "utils.h"
+#include "entity.h"
+
+#define ENTITY_MAX_LEN 8
+#define DECODED_MAX_LEN 6
+
+static GHashTable *symbol_table = NULL;
+
+typedef struct _EntitySymbol EntitySymbol;
+
+struct _EntitySymbol
+{
+ gchar *const key;
+ gchar *const value;
+};
+
+/* in alphabetical order with upper-case version first */
+static EntitySymbol symbolic_entities[] = {
+ /* A */
+ {"Aacute", "Á"},
+ {"aacute", "á"},
+ {"Acirc", "Â"},
+ {"acirc", "â"},
+ {"acute", "´"},
+ {"AElig", "Æ"},
+ {"aelig", "æ"},
+ {"Agrave", "À"},
+ {"agrave", "à"},
+ {"alefsym", "ℵ"},
+ {"Alpha", "Α"},
+ {"alpha", "α"},
+ {"amp", "&"},
+ {"and", "∧"},
+ {"ang", "∠"},
+ {"apos", "'"},
+ {"Aring", "Å"},
+ {"aring", "å"},
+ {"asymp", "≈"},
+ {"Atilde", "Ã"},
+ {"atilde", "ã"},
+ {"Auml", "Ä"},
+ {"auml", "ä"},
+ /* B */
+ {"bdquo", "„"},
+ {"Beta", "Β"},
+ {"beta", "β"},
+ {"brvbar", "¦"},
+ {"bull", "•"},
+ /* C */
+ {"cap", "∩"},
+ {"Ccedil", "Ç"},
+ {"ccedil", "ç"},
+ {"cedil", "¸"},
+ {"cent", "¢"},
+ {"Chi", "Χ"},
+ {"chi", "χ"},
+ {"circ", "ˆ"},
+ {"clubs", "♣"},
+ {"cong", "≅"},
+ {"copy", "©"},
+ {"crarr", "↵"},
+ {"cup", "∪"},
+ {"curren", "¤"},
+ /* D */
+ {"dagger", "†"},
+ {"Dagger", "‡"},
+ {"dArr", "⇓"},
+ {"darr", "↓"},
+ {"deg", "°"},
+ {"Delta", "Δ"},
+ {"delta", "δ"},
+ {"diams", "♦"},
+ {"divide", "÷"},
+ /* E */
+ {"Eacute", "É"},
+ {"eacute", "é"},
+ {"Ecirc", "Ê"},
+ {"ecirc", "ê"},
+ {"Egrave", "È"},
+ {"egrave", "è"},
+ {"empty", "∅"},
+ {"emsp", "\xE2\x80\x83"},
+ {"ensp", "\xE2\x80\x82"},
+ {"Epsilon", "Ε"},
+ {"epsilon", "ε"},
+ {"equiv", "≡"},
+ {"Eta", "Η"},
+ {"eta", "η"},
+ {"ETH", "Ð"},
+ {"eth", "ð"},
+ {"Euml", "Ë"},
+ {"euml", "ë"},
+ {"euro", "€"},
+ {"exist", "∃"},
+ /* F */
+ {"fnof", "ƒ"},
+ {"forall", "∀"},
+ {"frac12", "½"},
+ {"frac14", "¼"},
+ {"frac34", "¾"},
+ {"frasl", "⁄"},
+ /* G */
+ {"Gamma", "Γ"},
+ {"gamma", "γ"},
+ {"ge", "≥"},
+ {"gt", ">"},
+ /* H */
+ {"hArr", "⇔"},
+ {"harr", "↔"},
+ {"hearts", "♥"},
+ {"hellip", "…"},
+ /* I */
+ {"Iacute", "Í"},
+ {"iacute", "í"},
+ {"IArr", "⇐"},
+ {"Icirc", "Î"},
+ {"icirc", "î"},
+ {"iexcl", "¡"},
+ {"Igrave", "Ì"},
+ {"igrave", "ì"},
+ {"image", "ℑ"},
+ {"infin", "∞"},
+ {"int", "∫"},
+ {"Iota", "Ι"},
+ {"iota", "ι"},
+ {"iquest", "¿"},
+ {"isin", "∈"},
+ {"Iuml", "Ï"},
+ {"iuml", "ï"},
+ /* K */
+ {"Kappa", "Κ"},
+ {"kappa", "κ"},
+ /* L */
+ {"Lambda", "Λ"},
+ {"lambda", "λ"},
+ {"lang", "〈"},
+ {"laquo", "«"},
+ {"larr", "←"},
+ {"lceil", "⌈"},
+ {"ldquo", "“"},
+ {"le", "≤"},
+ {"lfloor", "⌊"},
+ {"lowast", "∗"},
+ {"loz", "◊"},
+ {"lrm", "\xE2\x80\x8E"},
+ {"lsaquo", "‹"},
+ {"lsquo", "‘"},
+ {"lt", "<"},
+ /* M */
+ {"macr", "¯"},
+ {"mdash", "—"},
+ {"micro", "µ"},
+ {"middot", "·"},
+ {"minus", "−"},
+ {"Mu", "Μ"},
+ {"mu", "μ"},
+ /* N */
+ {"nabla", "∇"},
+ {"nbsp", "\xC2\xA0"},
+ {"ndash", "–"},
+ {"ne", "≠"},
+ {"ni", "∋"},
+ {"not", "¬"},
+ {"notin", "∉"},
+ {"nsub", "⊄"},
+ {"Ntilde", "Ñ"},
+ {"ntilde", "ñ"},
+ {"Nu", "Ν"},
+ {"nu", "ν"},
+ /* O */
+ {"Oacute", "Ó"},
+ {"oacute", "ó"},
+ {"Ocirc", "Ô"},
+ {"ocirc", "ô"},
+ {"OElig", "Œ"},
+ {"oelig", "œ"},
+ {"Ograve", "Ò"},
+ {"ograve", "ò"},
+ {"oline", "‾"},
+ {"Omega", "Ω"},
+ {"omega", "ω"},
+ {"Omicron", "Ο"},
+ {"omicron", "ο"},
+ {"oplus", "⊕"},
+ {"or", "∨"},
+ {"ordf", "ª"},
+ {"ordm", "º"},
+ {"Oslash", "Ø"},
+ {"oslash", "ø"},
+ {"Otilde", "Õ"},
+ {"otilde", "õ"},
+ {"otimes", "⊗"},
+ {"Ouml", "Ö"},
+ {"ouml", "ö"},
+ /* P */
+ {"para", "¶"},
+ {"part", "∂"},
+ {"permil", "‰"},
+ {"perp", "⊥"},
+ {"Phi", "Φ"},
+ {"phi", "φ"},
+ {"Pi", "Π"},
+ {"pi", "π"},
+ {"piv", "ϖ"},
+ {"plusmn", "±"},
+ {"pound", "£"},
+ {"Prime", "″"},
+ {"prime", "′"},
+ {"prod", "∏"},
+ {"prop", "∝"},
+ {"Psi", "Ψ"},
+ {"psi", "ψ"},
+ /* Q */
+ {"quot", "\""},
+ /* R */
+ {"radic", "√"},
+ {"rang", "〉"},
+ {"raquo", "»"},
+ {"rArr", "⇒"},
+ {"rarr", "→"},
+ {"rceil", "⌉"},
+ {"rdquo", "”"},
+ {"real", "ℜ"},
+ {"reg", "®"},
+ {"rfloor", "⌋"},
+ {"Rho", "Ρ"},
+ {"rho", "ρ"},
+ {"rlm", "\xE2\x80\x8F"},
+ {"rsaquo", "›"},
+ {"rsquo", "’"},
+ /* S */
+ {"sbquo", "‚"},
+ {"Scaron", "Š"},
+ {"scaron", "š"},
+ {"sdot", "⋅"},
+ {"sect", "§"},
+ {"shy", "\xC2\xAD"},
+ {"Sigma", "Σ"},
+ {"sigma", "σ"},
+ {"sigmaf", "ς"},
+ {"sim", "∼"},
+ {"spades", "♠"},
+ {"sub", "⊂"},
+ {"sube", "⊆"},
+ {"sum", "∑"},
+ {"sup", "⊃"},
+ {"sup1", "¹"},
+ {"sup2", "²"},
+ {"sup3", "³"},
+ {"supe", "⊇"},
+ {"szlig", "ß"},
+ /* T */
+ {"Tau", "Τ"},
+ {"tau", "τ"},
+ {"there4", "∴"},
+ {"Theta", "Θ"},
+ {"theta", "θ"},
+ {"thetasym", "ϑ"},
+ {"thinsp", "\xE2\x80\x89"},
+ {"THORN", "Þ"},
+ {"thorn", "þ"},
+ {"tilde", "˜"},
+ {"times", "×"},
+ {"trade", "™"},
+ /* U */
+ {"Uacute", "Ú"},
+ {"uacute", "ú"},
+ {"uArr", "⇑"},
+ {"uarr", "↑"},
+ {"Ucirc", "Û"},
+ {"ucirc", "û"},
+ {"Ugrave", "Ù"},
+ {"ugrave", "ù"},
+ {"uml", "¨"},
+ {"upsih", "ϒ"},
+ {"Upsilon", "Υ"},
+ {"upsilon", "υ"},
+ {"Uuml", "Ü"},
+ {"uuml", "ü"},
+ /* W */
+ {"weierp", "℘"},
+ /* X */
+ {"Xi", "Ξ"},
+ {"xi", "ξ"},
+ /* Y */
+ {"Yacute", "Ý"},
+ {"yacute", "ý"},
+ {"yen", "¥"},
+ {"Yuml", "Ÿ"},
+ {"yuml", "ÿ"},
+ /* Z */
+ {"Zeta", "Ζ"},
+ {"zeta", "ζ"},
+ {"zwj", "\xE2\x80\x8D"},
+ {"zwnj", "\xE2\x80\x8C"},
+ {NULL, NULL}
+};
+
+static gchar* entity_extract_to_buffer(gchar *p, gchar b[])
+{
+ gint i = 0;
+
+ while (*p != '\0' && *p != ';' && i < ENTITY_MAX_LEN) {
+ b[i] = *p;
+ ++i, ++p;
+ }
+ if (*p != ';' || i == ENTITY_MAX_LEN)
+ return NULL;
+ b[i] = '\0';
+
+ return b;
+}
+
+static gchar *entity_decode_numeric(gchar *str)
+{
+ gchar b[ENTITY_MAX_LEN];
+ gchar *p = str, *res;
+ gboolean hex = FALSE;
+ gunichar c;
+
+ ++p;
+ if (*p == '\0')
+ return NULL;
+
+ if (*p == 'x') {
+ hex = TRUE;
+ ++p;
+ if (*p == '\0')
+ return NULL;
+ }
+
+ if (entity_extract_to_buffer (p, b) == NULL)
+ return NULL;
+
+ c = g_ascii_strtoll (b, NULL, (hex? 16: 10));
+ res = g_malloc0 (DECODED_MAX_LEN + 1);
+ g_unichar_to_utf8 (c, res);
+
+ return res;
+}
+
+static gchar *entity_decode_symbol(gchar *str)
+{
+ gchar b[ENTITY_MAX_LEN];
+ gchar *decoded;
+
+ if (entity_extract_to_buffer (str, b) == NULL)
+ return NULL;
+
+ if (symbol_table == NULL) {
+ gint i;
+
+ symbol_table = g_hash_table_new (g_str_hash, g_str_equal);
+ for (i = 0; symbolic_entities[i].key != NULL; ++i) {
+ g_hash_table_insert (symbol_table,
+ symbolic_entities[i].key, symbolic_entities[i].value);
+ }
+ debug_print("initialized entities table with %d symbols\n", i);
+ }
+
+ decoded = g_hash_table_lookup (symbol_table, b);
+ if (decoded != NULL)
+ return g_strdup (decoded);
+
+ return NULL;
+}
+
+gchar *entity_decode(gchar *str)
+{
+ gchar *p = str;
+ if (p == NULL || *p != '&')
+ return NULL;
+ ++p;
+ if (*p == '\0')
+ return NULL;
+ if (*p == '#')
+ return entity_decode_numeric(p);
+ else
+ return entity_decode_symbol(p);
+}
diff --git a/src/entity.h b/src/entity.h
@@ -0,0 +1,33 @@
+/*
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 2017 Ricardo Mones and the Claws Mail team
+ *
+ * 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
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ENTITY_H__
+#define __ENTITY_H__
+
+#include <glib.h>
+
+/*
+ * Try to decode the HTML entity pointed by str, whose first element
+ * must be the '&' character.
+ *
+ * Returns a newly-allocated string with the decoded entity or NULL
+ * on failure to decode (like an unknown or invalid entity).
+ * Returned strings must be freed with g_free().
+ */
+gchar *entity_decode(gchar *str);
+
+#endif /* __ENTITY_H__ */
diff --git a/src/html.c b/src/html.c
@@ -24,288 +24,12 @@
#include "html.h"
#include "codeconv.h"
#include "utils.h"
+#include "entity.h"
#define SC_HTMLBUFSIZE 8192
#define HR_STR "────────────────────────────────────────────────"
#define LI_STR "• "
-typedef struct _SC_HTMLSymbol SC_HTMLSymbol;
-
-struct _SC_HTMLSymbol
-{
- gchar *const key;
- gchar *const val;
-};
-
-static SC_HTMLSymbol symbol_list[] = {
- {""", "\42"},
- {"&", "\46"},
- {"'", "\47"},
- {"<", "\74"},
- {">", "\76"},
- {""", "\42"},
- {"&", "\46"},
- {"'", "\47"},
- {"<", "\74"},
- {">", "\76"},
- {"’", "\47"},
- {"™", "\342\204\242"},
- {" ", "\40"},
- {"¡", "\302\241"},
- {"¢", "\302\242"},
- {"£", "\302\243"},
- {"¤", "\302\244"},
- {"¥", "\302\245"},
- {"¦", "\302\246"},
- {"§", "\302\247"},
- {"¨", "\302\250"},
- {"©", "\302\251"},
- {"ª", "\302\252"},
- {"«", "\302\253"},
- {"¬", "\302\254"},
- {"­", "\302\255"},
- {"®", "\302\256"},
- {"¯", "\302\257"},
- {"°", "\302\260"},
- {"±", "\302\261"},
- {"²", "\302\262"},
- {"³", "\302\263"},
- {"´", "\302\264"},
- {"µ", "\302\265"},
- {"¶", "\302\266"},
- {"·", "\302\267"},
- {"¸", "\302\270"},
- {"¹", "\302\271"},
- {"º", "\302\272"},
- {"»", "\302\273"},
- {"¼", "\302\274"},
- {"½", "\302\275"},
- {"¾", "\302\276"},
- {"¿", "\302\277"},
- {"À", "\303\200"},
- {"Á", "\303\201"},
- {"Â", "\303\202"},
- {"Ã", "\303\203"},
- {"Ä", "\303\204"},
- {"Å", "\303\205"},
- {"Æ", "\303\206"},
- {"Ç", "\303\207"},
- {"È", "\303\210"},
- {"É", "\303\211"},
- {"Ê", "\303\212"},
- {"Ë", "\303\213"},
- {"Ì", "\303\214"},
- {"Í", "\303\215"},
- {"Î", "\303\216"},
- {"Ï", "\303\217"},
- {"Ð", "\303\220"},
- {"Ñ", "\303\221"},
- {"Ò", "\303\222"},
- {"Ó", "\303\223"},
- {"Ô", "\303\224"},
- {"Õ", "\303\225"},
- {"Ö", "\303\226"},
- {"×", "\303\227"},
- {"Ø", "\303\230"},
- {"Ù", "\303\231"},
- {"Ú", "\303\232"},
- {"Û", "\303\233"},
- {"Ü", "\303\234"},
- {"Ý", "\303\235"},
- {"Þ", "\303\236"},
- {"ß", "\303\237"},
- {"à", "\303\240"},
- {"á", "\303\241"},
- {"â", "\303\242"},
- {"ã", "\303\243"},
- {"ä", "\303\244"},
- {"å", "\303\245"},
- {"æ", "\303\246"},
- {"ç", "\303\247"},
- {"è", "\303\250"},
- {"é", "\303\251"},
- {"ê", "\303\252"},
- {"ë", "\303\253"},
- {"ì", "\303\254"},
- {"í", "\303\255"},
- {"î", "\303\256"},
- {"ï", "\303\257"},
- {"ð", "\303\260"},
- {"ñ", "\303\261"},
- {"ò", "\303\262"},
- {"ó", "\303\263"},
- {"ô", "\303\264"},
- {"õ", "\303\265"},
- {"ö", "\303\266"},
- {"÷", "\303\267"},
- {"ø", "\303\270"},
- {"ù", "\303\271"},
- {"ú", "\303\272"},
- {"û", "\303\273"},
- {"ü", "\303\274"},
- {"ý", "\303\275"},
- {"þ", "\303\276"},
- {"ÿ", "\303\277"},
- {"Œ", "\305\222"},
- {"œ", "\305\223"},
- {"Š", "\305\240"},
- {"š", "\305\241"},
- {"Ÿ", "\305\270"},
- {"ˆ", "\313\206"},
- {"˜", "\313\234"},
- {" ", "\342\200\202"},
- {" ", "\342\200\203"},
- {" ", "\342\200\211"},
- {"–", "\342\200\223"},
- {"—", "\342\200\224"},
- {"‘", "\342\200\230"},
- {"’", "\342\200\231"},
- {"‚", "\342\200\232"},
- {"“", "\342\200\234"},
- {"”", "\342\200\235"},
- {"„", "\342\200\236"},
- {"†", "\342\200\240"},
- {"‡", "\342\200\241"},
- {"•", "\342\200\242"},
- {"…", "\342\200\246"},
- {"‰", "\342\200\260"},
- {"‹", "\342\200\271"},
- {"›", "\342\200\272"},
- {"€", "\342\202\254"},
- {"™", "\342\204\242"},
- {""", "\42"},
- {"&", "\46"},
- {"'", "\47"},
- {"<", "\74"},
- {">", "\76"},
- {"&squot;", "\47"},
- {" ", "\40"},
- {"¡", "\302\241"},
- {"¢", "\302\242"},
- {"£", "\302\243"},
- {"¤", "\302\244"},
- {"¥", "\302\245"},
- {"¦", "\302\246"},
- {"§", "\302\247"},
- {"¨", "\302\250"},
- {"©", "\302\251"},
- {"ª", "\302\252"},
- {"«", "\302\253"},
- {"¬", "\302\254"},
- {"­", "\302\255"},
- {"®", "\302\256"},
- {"¯", "\302\257"},
- {"°", "\302\260"},
- {"±", "\302\261"},
- {"²", "\302\262"},
- {"³", "\302\263"},
- {"´", "\302\264"},
- {"µ", "\302\265"},
- {"¶", "\302\266"},
- {"·", "\302\267"},
- {"¸", "\302\270"},
- {"¹", "\302\271"},
- {"º", "\302\272"},
- {"»", "\302\273"},
- {"¼", "\302\274"},
- {"½", "\302\275"},
- {"¾", "\302\276"},
- {"¿", "\302\277"},
- {"À", "\303\200"},
- {"Á", "\303\201"},
- {"Â", "\303\202"},
- {"Ã", "\303\203"},
- {"Ä", "\303\204"},
- {"Å", "\303\205"},
- {"Æ", "\303\206"},
- {"Ç", "\303\207"},
- {"È", "\303\210"},
- {"É", "\303\211"},
- {"Ê", "\303\212"},
- {"Ë", "\303\213"},
- {"Ì", "\303\214"},
- {"Í", "\303\215"},
- {"Î", "\303\216"},
- {"Ï", "\303\217"},
- {"Ð", "\303\220"},
- {"Ñ", "\303\221"},
- {"Ò", "\303\222"},
- {"Ó", "\303\223"},
- {"Ô", "\303\224"},
- {"Õ", "\303\225"},
- {"Ö", "\303\226"},
- {"×", "\303\227"},
- {"Ø", "\303\230"},
- {"Ù", "\303\231"},
- {"Ú", "\303\232"},
- {"Û", "\303\233"},
- {"Ü", "\303\234"},
- {"Ý", "\303\235"},
- {"Þ", "\303\236"},
- {"ß", "\303\237"},
- {"à", "\303\240"},
- {"á", "\303\241"},
- {"â", "\303\242"},
- {"ã", "\303\243"},
- {"ä", "\303\244"},
- {"å", "\303\245"},
- {"æ", "\303\246"},
- {"ç", "\303\247"},
- {"è", "\303\250"},
- {"é", "\303\251"},
- {"ê", "\303\252"},
- {"ë", "\303\253"},
- {"ì", "\303\254"},
- {"í", "\303\255"},
- {"î", "\303\256"},
- {"ï", "\303\257"},
- {"ð", "\303\260"},
- {"ñ", "\303\261"},
- {"ò", "\303\262"},
- {"ó", "\303\263"},
- {"ô", "\303\264"},
- {"õ", "\303\265"},
- {"ö", "\303\266"},
- {"÷", "\303\267"},
- {"ø", "\303\270"},
- {"ù", "\303\271"},
- {"ú", "\303\272"},
- {"û", "\303\273"},
- {"ü", "\303\274"},
- {"ý", "\303\275"},
- {"þ", "\303\276"},
- {"ÿ", "\303\277"},
- {"Œ", "\305\222"},
- {"œ", "\305\223"},
- {"Š", "\305\240"},
- {"š", "\305\241"},
- {"Ÿ", "\305\270"},
- {"ˆ", "\313\206"},
- {"˜", "\313\234"},
- {" ", "\342\200\202"},
- {" ", "\342\200\203"},
- {" ", "\342\200\211"},
- {"–", "\342\200\223"},
- {"—", "\342\200\224"},
- {"‘", "\342\200\230"},
- {"’", "\342\200\231"},
- {"‚", "\342\200\232"},
- {"“", "\342\200\234"},
- {"”", "\342\200\235"},
- {"„", "\342\200\236"},
- {"†", "\342\200\240"},
- {"‡", "\342\200\241"},
- {"•", "\342\200\242"},
- {"…", "\342\200\246"},
- {"‰", "\342\200\260"},
- {"‹", "\342\200\271"},
- {"›", "\342\200\272"},
- {"€", "\342\202\254"},
- {"™", "\342\204\242"}
-};
-
-static GHashTable *default_symbol_table;
-
static SC_HTMLState sc_html_read_line (SC_HTMLParser *parser);
static void sc_html_append_char (SC_HTMLParser *parser,
gchar ch);
@@ -340,16 +64,6 @@ SC_HTMLParser *sc_html_parser_new(FILE *fp, CodeConverter *conv)
parser->pre = FALSE;
parser->indent = 0;
- if (!default_symbol_table) {
- gint i;
- default_symbol_table = g_hash_table_new(g_str_hash, g_str_equal);
- for (i = 0; i < sizeof(symbol_list) / sizeof(symbol_list[0]); i++)
- g_hash_table_insert(default_symbol_table,
- symbol_list[i].key, symbol_list[i].val);
- }
-
- parser->symbol_table = default_symbol_table;
-
return parser;
}
@@ -612,8 +326,7 @@ static void decode_href(SC_HTMLParser *parser)
tparser->str = g_string_new(NULL);
tparser->buf = g_string_new(parser->href);
tparser->bufp = tparser->buf->str;
- tparser->symbol_table = default_symbol_table;
-
+
tmp = sc_html_parse(tparser);
g_free(parser->href);
@@ -725,33 +438,21 @@ static SC_HTMLState sc_html_parse_tag(SC_HTMLParser *parser)
static void sc_html_parse_special(SC_HTMLParser *parser)
{
- gchar symbol_name[9];
- gint n;
- const gchar *val;
+ gchar *entity;
parser->state = SC_HTML_UNKNOWN;
cm_return_if_fail(*parser->bufp == '&');
- /* &foo; */
- for (n = 0; parser->bufp[n] != '\0' && parser->bufp[n] != ';'; n++)
- ;
- if (n > 7 || parser->bufp[n] != ';') {
+ entity = entity_decode(parser->bufp);
+ if (entity != NULL) {
+ sc_html_append_str(parser, entity, -1);
+ g_free(entity);
+ while (*parser->bufp++ != ';');
+ } else {
/* output literal `&' */
sc_html_append_char(parser, *parser->bufp++);
- parser->state = SC_HTML_NORMAL;
- return;
}
- strncpy2(symbol_name, parser->bufp, n + 2);
- parser->bufp += n + 1;
-
- if ((val = g_hash_table_lookup(parser->symbol_table, symbol_name))
- != NULL) {
- sc_html_append_str(parser, val, -1);
- parser->state = SC_HTML_NORMAL;
- return;
- }
-
- sc_html_append_str(parser, symbol_name, -1);
+ parser->state = SC_HTML_NORMAL;
}
static gchar *sc_html_find_tag(SC_HTMLParser *parser, const gchar *tag)
diff --git a/src/html.h b/src/html.h
@@ -1,6 +1,6 @@
/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2012 Hiroyuki Yamamoto and the Claws Mail team
+ * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
+ * Copyright (C) 1999-2017 Hiroyuki Yamamoto and the Claws Mail team
*
* 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
@@ -14,7 +14,6 @@
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
*/
#ifndef __HTML_H__
@@ -51,9 +50,6 @@ struct _SC_HTMLParser
FILE *fp;
CodeConverter *conv;
- GHashTable *symbol_table;
- GHashTable *alt_symbol_table;
-
GString *str;
GString *buf;
diff --git a/src/mh.c b/src/mh.c
@@ -730,7 +730,15 @@ static gint mh_remove_all_msg(Folder *folder, FolderItem *item)
static gboolean mh_is_msg_changed(Folder *folder, FolderItem *item,
MsgInfo *msginfo)
{
+#ifdef G_OS_WIN32
+ GFile *f;
+ GFileInfo *fi;
+ GTimeVal tv;
+ GError *error = NULL;
+#else
GStatBuf s;
+ int r;
+#endif
gchar *path;
gchar *parent_path;
@@ -738,16 +746,39 @@ static gboolean mh_is_msg_changed(Folder *folder, FolderItem *item,
path = g_strdup_printf("%s%c%d", parent_path,
G_DIR_SEPARATOR, msginfo->msgnum);
g_free(parent_path);
- if (g_stat((path), &s) < 0 ||
+
+#ifdef G_OS_WIN32
+ f = g_file_new_for_path(path);
+ g_free(path);
+ fi = g_file_query_info(f, "standard::size,time::modified",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ if (error != NULL) {
+ g_warning(error->message);
+ g_error_free(error);
+ g_object_unref(f);
+ return TRUE;
+ }
+
+ g_file_info_get_modification_time(fi, &tv);
+ if (msginfo->size != g_file_info_get_size(fi) || (
+ (msginfo->mtime - tv.tv_sec != 0) &&
+ abs(msginfo->mtime - tv.tv_sec) != 3600)) {
+ g_error_free(error);
+ g_object_unref(f);
+ return TRUE;
+ }
+#else
+ r = g_stat(path, &s);
+ g_free(path);
+ if (r < 0 ||
msginfo->size != s.st_size || (
(msginfo->mtime - s.st_mtime != 0) &&
(msginfo->mtime - s.st_mtime != 3600) &&
(msginfo->mtime - s.st_mtime != -3600))) {
- g_free(path);
return TRUE;
}
+#endif
- g_free(path);
return FALSE;
}
diff --git a/src/plugins/fancy/claws.def b/src/plugins/fancy/claws.def
@@ -91,3 +91,4 @@ statusbar_pop_all
statusbar_print_all
statusbar_progress_all
str_write_to_file
+subst_char
diff --git a/src/plugins/pgpcore/pgp_viewer.c b/src/plugins/pgpcore/pgp_viewer.c
@@ -278,7 +278,13 @@ static void pgpview_show_mime_part(TextView *textview, MimeInfo *partinfo)
return;
} else {
TEXTVIEW_INSERT(_("\n Key ID "));
+
+#if defined GPGME_VERSION_NUMBER && GPGME_VERSION_NUMBER >= 0x010700
+ TEXTVIEW_INSERT(key->fpr);
+#else
TEXTVIEW_INSERT(sig->fpr);
+#endif
+
TEXTVIEW_INSERT(":\n\n");
TEXTVIEW_INSERT(_(" This key is in your keyring.\n"));
}
diff --git a/src/plugins/pgpcore/sgpgme.c b/src/plugins/pgpcore/sgpgme.c
@@ -281,9 +281,7 @@ gchar *sgpgme_sigstat_info_short(gpgme_ctx_t ctx, gpgme_verify_result_t status)
if (key) {
result = g_strdup_printf(_("Good signature from \"%s\""), uname);
} else {
- gchar *id = g_strdup(sig->fpr + strlen(sig->fpr)-8);
- result = g_strdup_printf(_("Key 0x%s not available to verify this signature"), id);
- g_free(id);
+ result = g_strdup_printf(_("Key 0x%s not available to verify this signature"), sig->fpr);
}
break;
}
@@ -301,9 +299,7 @@ gchar *sgpgme_sigstat_info_short(gpgme_ctx_t ctx, gpgme_verify_result_t status)
result = g_strdup_printf(_("Bad signature from \"%s\""), uname);
break;
case GPG_ERR_NO_PUBKEY: {
- gchar *id = g_strdup(sig->fpr + strlen(sig->fpr)-8);
- result = g_strdup_printf(_("Key 0x%s not available to verify this signature"), id);
- g_free(id);
+ result = g_strdup_printf(_("Key 0x%s not available to verify this signature"), sig->fpr);
break;
}
default:
diff --git a/src/plugins/rssyl/strutils.c b/src/plugins/rssyl/strutils.c
@@ -30,6 +30,7 @@
/* Claws Mail includes */
#include <common/utils.h>
+#include <entity.h>
/* Local includes */
/* (shouldn't be any) */
@@ -120,28 +121,6 @@ struct _RSSyl_HTMLSymbol
gchar *const val;
};
-/* TODO: find a way to offload this to a library which knows all the
- * defined named entities (over 200). */
-static RSSyl_HTMLSymbol symbol_list[] = {
- { "lt", "<" },
- { "gt", ">" },
- { "amp", "&" },
- { "apos", "'" },
- { "quot", "\"" },
- { "lsquo", "‘" },
- { "rsquo", "’" },
- { "ldquo", "“" },
- { "rdquo", "”" },
- { "nbsp", " " },
- { "trade", "™" },
- { "copy", "©" },
- { "reg", "®" },
- { "hellip", "…" },
- { "mdash", "—" },
- { "euro", "€" },
- { NULL, NULL }
-};
-
static RSSyl_HTMLSymbol tag_list[] = {
{ "<cite>", "\"" },
{ "</cite>", "\"" },
@@ -160,55 +139,21 @@ static RSSyl_HTMLSymbol tag_list[] = {
static gchar *rssyl_replace_chrefs(gchar *string)
{
char *new = g_malloc0(strlen(string) + 1), *ret;
- char buf[16], tmp[6];
- int i, ii, j, n, len;
- gunichar c;
- gboolean valid, replaced;
+ gchar *entity;
+ int i, ii;
/* &xx; */
ii = 0;
for (i = 0; i < strlen(string); ++i) {
if (string[i] == '&') {
- j = i+1;
- n = 0;
- valid = FALSE;
- while (string[j] != '\0' && n < 16) {
- if (string[j] != ';') {
- buf[n++] = string[j];
- } else {
- /* End of entity */
- valid = TRUE;
- buf[n] = '\0';
- break;
- }
- j++;
- }
- if (strlen(buf) > 0 && valid) {
- replaced = FALSE;
-
- if (buf[0] == '#' && (c = atoi(buf+1)) > 0) {
- len = g_unichar_to_utf8(c, tmp);
- tmp[len] = '\0';
- g_strlcat(new, tmp, strlen(string));
- ii += len;
- replaced = TRUE;
- } else {
- for (c = 0; symbol_list[c].key != NULL; c++) {
- if (!strcmp(buf, symbol_list[c].key)) {
- g_strlcat(new, symbol_list[c].val, strlen(string));
- ii += strlen(symbol_list[c].val);
- replaced = TRUE;
- break;
- }
- }
- }
- if (!replaced) {
- new[ii++] = '&'; /* & */
- g_strlcat(new, buf, strlen(string));
- ii += strlen(buf);
- new[ii++] = ';';
- }
- i = j;
+ entity = entity_decode(&(string[i]));
+ if (entity != NULL) {
+ g_strlcat(new, entity, strlen(string));
+ ii += strlen(entity);
+ g_free(entity);
+ entity = NULL;
+ while (string[++i] != ';');
+ --i; /* loop will inc it again */
} else {
new[ii++] = string[i];
}
@@ -239,7 +184,7 @@ gchar *rssyl_replace_html_stuff(gchar *text,
/* TODO: rewrite this part to work similarly to rssyl_replace_chrefs() */
if( tags ) {
for( i = 0; tag_list[i].key != NULL; i++ ) {
- if( g_strstr_len(text, strlen(text), symbol_list[i].key) ) {
+ if( g_strstr_len(text, strlen(text), tag_list[i].key) ) {
tmp = rssyl_strreplace(wtext, tag_list[i].key, tag_list[i].val);
g_free(wtext);
wtext = g_strdup(tmp);
diff --git a/src/prefs_account.c b/src/prefs_account.c
@@ -1837,6 +1837,9 @@ static void send_create_widget_func(PrefsPage * _page,
gtk_widget_show (smtp_uid_entry);
gtk_widget_set_size_request (smtp_uid_entry, DEFAULT_ENTRY_WIDTH, -1);
gtk_box_pack_start (GTK_BOX (hbox), smtp_uid_entry, TRUE, TRUE, 0);
+ g_signal_connect(G_OBJECT(smtp_uid_entry), "changed",
+ G_CALLBACK(prefs_account_entry_changed_newline_check_cb),
+ GINT_TO_POINTER(ac_prefs->protocol));
#ifdef GENERIC_UMPC
PACK_VSPACER(vbox4, vbox_spc, VSPACING_NARROW_2);
@@ -1858,6 +1861,9 @@ static void send_create_widget_func(PrefsPage * _page,
gtk_widget_set_size_request (smtp_pass_entry, DEFAULT_ENTRY_WIDTH, -1);
gtk_box_pack_start (GTK_BOX (hbox), smtp_pass_entry, TRUE, TRUE, 0);
gtk_entry_set_visibility (GTK_ENTRY (smtp_pass_entry), FALSE);
+ g_signal_connect(G_OBJECT(smtp_pass_entry), "changed",
+ G_CALLBACK(prefs_account_entry_changed_newline_check_cb),
+ GINT_TO_POINTER(ac_prefs->protocol));
showpwd_checkbtn = gtk_check_button_new_with_label (_("Show password"));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(showpwd_checkbtn), FALSE);
@@ -3026,15 +3032,13 @@ static gint prefs_basic_apply(void)
protocol == A_IMAP4 ? "imap":"news",
tmp_ac_prefs.account_name ? tmp_ac_prefs.account_name : "(null)");
- if (protocol == A_POP3 &&
- strchr(gtk_entry_get_text(GTK_ENTRY(basic_page.uid_entry)), '\n') != NULL) {
- alertpanel_error(_("User ID can not contain newline character."));
+ if (strchr(gtk_entry_get_text(GTK_ENTRY(basic_page.uid_entry)), '\n') != NULL) {
+ alertpanel_error(_("User ID cannot contain a newline character."));
return -1;
}
- if (protocol == A_POP3 &&
- strchr(gtk_entry_get_text(GTK_ENTRY(basic_page.pass_entry)), '\n') != NULL) {
- alertpanel_error(_("Password can not contain newline character."));
+ if (strchr(gtk_entry_get_text(GTK_ENTRY(basic_page.pass_entry)), '\n') != NULL) {
+ alertpanel_error(_("Password cannot contain a newline character."));
return -1;
}
@@ -3061,6 +3065,16 @@ static gint prefs_basic_apply(void)
static gint prefs_receive_apply(void)
{
+ if (strchr(gtk_entry_get_text(GTK_ENTRY(send_page.smtp_uid_entry)), '\n') != NULL) {
+ alertpanel_error(_("SMTP user ID cannot contain a newline character."));
+ return -1;
+ }
+
+ if (strchr(gtk_entry_get_text(GTK_ENTRY(send_page.smtp_pass_entry)), '\n') != NULL) {
+ alertpanel_error(_("SMTP password cannot contain a newline character."));
+ return -1;
+ }
+
prefs_set_data_from_dialog(receive_param);
return 0;
}
@@ -4958,7 +4972,6 @@ static void prefs_account_showpwd_checkbtn_toggled(GtkToggleButton *button,
static void prefs_account_entry_changed_newline_check_cb(GtkWidget *entry,
gpointer user_data)
{
- RecvProtocol protocol = GPOINTER_TO_INT(user_data);
#if !GTK_CHECK_VERSION(3, 0, 0)
static GdkColor red;
static gboolean colors_initialised = FALSE;
@@ -4967,9 +4980,6 @@ static void prefs_account_entry_changed_newline_check_cb(GtkWidget *entry,
#endif
#if !GTK_CHECK_VERSION(3, 0, 0)
- if (protocol != A_POP3)
- return;
-
if (strchr(gtk_entry_get_text(GTK_ENTRY(entry)), '\n') != NULL) {
/* Entry contains a newline, light it up. */
debug_print("found newline in string, painting entry red\n");
diff --git a/src/prefs_themes.c b/src/prefs_themes.c
@@ -174,24 +174,58 @@ static void prefs_themes_file_install (const gchar *filename, gpointer data);
static void prefs_themes_file_stats(const gchar *filename, gpointer data)
{
+#ifdef G_OS_WIN32
+ GFile *f;
+ GFileInfo *fi;
+ GError *error = NULL;
+#else
GStatBuf s;
+#endif
+ goffset size;
DirInfo *di = (DirInfo *)data;
gint len;
gint i;
- if (0 == g_stat(filename, &s) && 0 != S_ISREG(s.st_mode)) {
- di->bytes += s.st_size;
- di->files++;
- len = strlen(filename);
- for (i = 0; (di->supported)[i] != NULL; ++i) {
- gint curlen = (di->length)[i];
- if (len <= curlen)
- continue;
- const gchar *extension = filename + (len - curlen);
- if (!strcmp(extension, (di->supported)[i])) {
- di->pixms++;
- break;
- }
+#ifdef G_OS_WIN32
+ f = g_file_new_for_path(filename);
+ fi = g_file_query_info(f, "standard::size,standard::type",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ if (error != NULL) {
+ g_warning(error->message);
+ g_error_free(error);
+ g_object_unref(f);
+ return;
+ }
+ if (g_file_info_get_file_type(fi) != G_FILE_TYPE_REGULAR) {
+ g_object_unref(fi);
+ g_object_unref(f);
+ return;
+ }
+ size = g_file_info_get_size(fi);
+ g_object_unref(fi);
+ g_object_unref(f);
+#else
+ if ((i = g_stat(filename, &s)) != 0) {
+ debug_print("g_stat on '%s' failed: %d\n", filename, i);
+ return;
+ }
+ if (!S_ISREG(s.st_mode)) {
+ return;
+ }
+ size = s.st_size;
+#endif
+
+ di->bytes += size;
+ di->files++;
+ len = strlen(filename);
+ for (i = 0; (di->supported)[i] != NULL; ++i) {
+ gint curlen = (di->length)[i];
+ if (len <= curlen)
+ continue;
+ const gchar *extension = filename + (len - curlen);
+ if (!strcmp(extension, (di->supported)[i])) {
+ di->pixms++;
+ break;
}
}
}
diff --git a/src/procheader.c b/src/procheader.c
@@ -403,16 +403,43 @@ void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
MsgInfo *procheader_parse_file(const gchar *file, MsgFlags flags,
gboolean full, gboolean decrypted)
{
+#ifdef G_OS_WIN32
+ GFile *f;
+ GFileInfo *fi;
+ GTimeVal tv;
+ GError *error = NULL;
+#else
GStatBuf s;
+#endif
FILE *fp;
MsgInfo *msginfo;
+#ifdef G_OS_WIN32
+ f = g_file_new_for_path(file);
+ fi = g_file_query_info(f, "standard::size,standard::type,time::modified",
+ G_FILE_QUERY_INFO_NONE, NULL, &error);
+ if (error != NULL) {
+ g_warning(error->message);
+ g_error_free(error);
+ g_object_unref(f);
+ }
+#else
if (g_stat(file, &s) < 0) {
FILE_OP_ERROR(file, "stat");
return NULL;
}
+#endif
+
+#ifdef G_OS_WIN32
+ if (g_file_info_get_file_type(fi) != G_FILE_TYPE_REGULAR) {
+ g_object_unref(fi);
+ g_object_unref(f);
+ return NULL;
+ }
+#else
if (!S_ISREG(s.st_mode))
return NULL;
+#endif
if ((fp = g_fopen(file, "rb")) == NULL) {
FILE_OP_ERROR(file, "fopen");
@@ -423,10 +450,21 @@ MsgInfo *procheader_parse_file(const gchar *file, MsgFlags flags,
fclose(fp);
if (msginfo) {
+#ifdef G_OS_WIN32
+ msginfo->size = g_file_info_get_size(fi);
+ g_file_info_get_modification_time(fi, &tv);
+ msginfo->mtime = tv.tv_sec;
+#else
msginfo->size = s.st_size;
msginfo->mtime = s.st_mtime;
+#endif
}
+#ifdef G_OS_WIN32
+ g_object_unref(fi);
+ g_object_unref(f);
+#endif
+
return msginfo;
}