talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

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:
Msrc/Makefile.am | 2++
Msrc/common/utils.c | 24+++++++++++++++++++++++-
Msrc/compose.c | 90++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
Asrc/entity.c | 403+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/entity.h | 33+++++++++++++++++++++++++++++++++
Msrc/html.c | 319+++----------------------------------------------------------------------------
Msrc/html.h | 8++------
Msrc/mh.c | 37++++++++++++++++++++++++++++++++++---
Msrc/plugins/fancy/claws.def | 1+
Msrc/plugins/pgpcore/pgp_viewer.c | 6++++++
Msrc/plugins/pgpcore/sgpgme.c | 8++------
Msrc/plugins/rssyl/strutils.c | 79++++++++++++-------------------------------------------------------------------
Msrc/prefs_account.c | 30++++++++++++++++++++----------
Msrc/prefs_themes.c | 60+++++++++++++++++++++++++++++++++++++++++++++++-------------
Msrc/procheader.c | 38++++++++++++++++++++++++++++++++++++++
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[] = { - {"&#34;", "\42"}, - {"&#38;", "\46"}, - {"&#39;", "\47"}, - {"&#60;", "\74"}, - {"&#62;", "\76"}, - {"&#034;", "\42"}, - {"&#038;", "\46"}, - {"&#039;", "\47"}, - {"&#060;", "\74"}, - {"&#062;", "\76"}, - {"&#146;", "\47"}, - {"&#153;", "\342\204\242"}, - {"&#160;", "\40"}, - {"&#161;", "\302\241"}, - {"&#162;", "\302\242"}, - {"&#163;", "\302\243"}, - {"&#164;", "\302\244"}, - {"&#165;", "\302\245"}, - {"&#166;", "\302\246"}, - {"&#167;", "\302\247"}, - {"&#168;", "\302\250"}, - {"&#169;", "\302\251"}, - {"&#170;", "\302\252"}, - {"&#171;", "\302\253"}, - {"&#172;", "\302\254"}, - {"&#173;", "\302\255"}, - {"&#174;", "\302\256"}, - {"&#175;", "\302\257"}, - {"&#176;", "\302\260"}, - {"&#177;", "\302\261"}, - {"&#178;", "\302\262"}, - {"&#179;", "\302\263"}, - {"&#180;", "\302\264"}, - {"&#181;", "\302\265"}, - {"&#182;", "\302\266"}, - {"&#183;", "\302\267"}, - {"&#184;", "\302\270"}, - {"&#185;", "\302\271"}, - {"&#186;", "\302\272"}, - {"&#187;", "\302\273"}, - {"&#188;", "\302\274"}, - {"&#189;", "\302\275"}, - {"&#190;", "\302\276"}, - {"&#191;", "\302\277"}, - {"&#192;", "\303\200"}, - {"&#193;", "\303\201"}, - {"&#194;", "\303\202"}, - {"&#195;", "\303\203"}, - {"&#196;", "\303\204"}, - {"&#197;", "\303\205"}, - {"&#198;", "\303\206"}, - {"&#199;", "\303\207"}, - {"&#200;", "\303\210"}, - {"&#201;", "\303\211"}, - {"&#202;", "\303\212"}, - {"&#203;", "\303\213"}, - {"&#204;", "\303\214"}, - {"&#205;", "\303\215"}, - {"&#206;", "\303\216"}, - {"&#207;", "\303\217"}, - {"&#208;", "\303\220"}, - {"&#209;", "\303\221"}, - {"&#210;", "\303\222"}, - {"&#211;", "\303\223"}, - {"&#212;", "\303\224"}, - {"&#213;", "\303\225"}, - {"&#214;", "\303\226"}, - {"&#215;", "\303\227"}, - {"&#216;", "\303\230"}, - {"&#217;", "\303\231"}, - {"&#218;", "\303\232"}, - {"&#219;", "\303\233"}, - {"&#220;", "\303\234"}, - {"&#221;", "\303\235"}, - {"&#222;", "\303\236"}, - {"&#223;", "\303\237"}, - {"&#224;", "\303\240"}, - {"&#225;", "\303\241"}, - {"&#226;", "\303\242"}, - {"&#227;", "\303\243"}, - {"&#228;", "\303\244"}, - {"&#229;", "\303\245"}, - {"&#230;", "\303\246"}, - {"&#231;", "\303\247"}, - {"&#232;", "\303\250"}, - {"&#233;", "\303\251"}, - {"&#234;", "\303\252"}, - {"&#235;", "\303\253"}, - {"&#236;", "\303\254"}, - {"&#237;", "\303\255"}, - {"&#238;", "\303\256"}, - {"&#239;", "\303\257"}, - {"&#240;", "\303\260"}, - {"&#241;", "\303\261"}, - {"&#242;", "\303\262"}, - {"&#243;", "\303\263"}, - {"&#244;", "\303\264"}, - {"&#245;", "\303\265"}, - {"&#246;", "\303\266"}, - {"&#247;", "\303\267"}, - {"&#248;", "\303\270"}, - {"&#249;", "\303\271"}, - {"&#250;", "\303\272"}, - {"&#251;", "\303\273"}, - {"&#252;", "\303\274"}, - {"&#253;", "\303\275"}, - {"&#254;", "\303\276"}, - {"&#255;", "\303\277"}, - {"&#338;", "\305\222"}, - {"&#339;", "\305\223"}, - {"&#352;", "\305\240"}, - {"&#353;", "\305\241"}, - {"&#376;", "\305\270"}, - {"&#710;", "\313\206"}, - {"&#732;", "\313\234"}, - {"&#8194;", "\342\200\202"}, - {"&#8195;", "\342\200\203"}, - {"&#8201;", "\342\200\211"}, - {"&#8211;", "\342\200\223"}, - {"&#8212;", "\342\200\224"}, - {"&#8216;", "\342\200\230"}, - {"&#8217;", "\342\200\231"}, - {"&#8218;", "\342\200\232"}, - {"&#8220;", "\342\200\234"}, - {"&#8221;", "\342\200\235"}, - {"&#8222;", "\342\200\236"}, - {"&#8224;", "\342\200\240"}, - {"&#8225;", "\342\200\241"}, - {"&#8226;", "\342\200\242"}, - {"&#8230;", "\342\200\246"}, - {"&#8240;", "\342\200\260"}, - {"&#8249;", "\342\200\271"}, - {"&#8250;", "\342\200\272"}, - {"&#8364;", "\342\202\254"}, - {"&#8482;", "\342\204\242"}, - {"&quot;", "\42"}, - {"&amp;", "\46"}, - {"&apos;", "\47"}, - {"&lt;", "\74"}, - {"&gt;", "\76"}, - {"&squot;", "\47"}, - {"&nbsp;", "\40"}, - {"&iexcl;", "\302\241"}, - {"&cent;", "\302\242"}, - {"&pound;", "\302\243"}, - {"&curren;", "\302\244"}, - {"&yen;", "\302\245"}, - {"&brvbar;", "\302\246"}, - {"&sect;", "\302\247"}, - {"&uml;", "\302\250"}, - {"&copy;", "\302\251"}, - {"&ordf;", "\302\252"}, - {"&laquo;", "\302\253"}, - {"&not;", "\302\254"}, - {"&shy;", "\302\255"}, - {"&reg;", "\302\256"}, - {"&macr;", "\302\257"}, - {"&deg;", "\302\260"}, - {"&plusmn;", "\302\261"}, - {"&sup2;", "\302\262"}, - {"&sup3;", "\302\263"}, - {"&acute;", "\302\264"}, - {"&micro;", "\302\265"}, - {"&para;", "\302\266"}, - {"&middot;", "\302\267"}, - {"&cedil;", "\302\270"}, - {"&sup1;", "\302\271"}, - {"&ordm;", "\302\272"}, - {"&raquo;", "\302\273"}, - {"&frac14;", "\302\274"}, - {"&frac12;", "\302\275"}, - {"&frac34;", "\302\276"}, - {"&iquest;", "\302\277"}, - {"&Agrave;", "\303\200"}, - {"&Aacute;", "\303\201"}, - {"&Acirc;", "\303\202"}, - {"&Atilde;", "\303\203"}, - {"&Auml;", "\303\204"}, - {"&Aring;", "\303\205"}, - {"&AElig;", "\303\206"}, - {"&Ccedil;", "\303\207"}, - {"&Egrave;", "\303\210"}, - {"&Eacute;", "\303\211"}, - {"&Ecirc;", "\303\212"}, - {"&Euml;", "\303\213"}, - {"&Igrave;", "\303\214"}, - {"&Iacute;", "\303\215"}, - {"&Icirc;", "\303\216"}, - {"&Iuml;", "\303\217"}, - {"&ETH;", "\303\220"}, - {"&Ntilde;", "\303\221"}, - {"&Ograve;", "\303\222"}, - {"&Oacute;", "\303\223"}, - {"&Ocirc;", "\303\224"}, - {"&Otilde;", "\303\225"}, - {"&Ouml;", "\303\226"}, - {"&times;", "\303\227"}, - {"&Oslash;", "\303\230"}, - {"&Ugrave;", "\303\231"}, - {"&Uacute;", "\303\232"}, - {"&Ucirc;", "\303\233"}, - {"&Uuml;", "\303\234"}, - {"&Yacute;", "\303\235"}, - {"&THORN;", "\303\236"}, - {"&szlig;", "\303\237"}, - {"&agrave;", "\303\240"}, - {"&aacute;", "\303\241"}, - {"&acirc;", "\303\242"}, - {"&atilde;", "\303\243"}, - {"&auml;", "\303\244"}, - {"&aring;", "\303\245"}, - {"&aelig;", "\303\246"}, - {"&ccedil;", "\303\247"}, - {"&egrave;", "\303\250"}, - {"&eacute;", "\303\251"}, - {"&ecirc;", "\303\252"}, - {"&euml;", "\303\253"}, - {"&igrave;", "\303\254"}, - {"&iacute;", "\303\255"}, - {"&icirc;", "\303\256"}, - {"&iuml;", "\303\257"}, - {"&eth;", "\303\260"}, - {"&ntilde;", "\303\261"}, - {"&ograve;", "\303\262"}, - {"&oacute;", "\303\263"}, - {"&ocirc;", "\303\264"}, - {"&otilde;", "\303\265"}, - {"&ouml;", "\303\266"}, - {"&divide;", "\303\267"}, - {"&oslash;", "\303\270"}, - {"&ugrave;", "\303\271"}, - {"&uacute;", "\303\272"}, - {"&ucirc;", "\303\273"}, - {"&uuml;", "\303\274"}, - {"&yacute;", "\303\275"}, - {"&thorn;", "\303\276"}, - {"&yuml;", "\303\277"}, - {"&OElig;", "\305\222"}, - {"&oelig;", "\305\223"}, - {"&Scaron;", "\305\240"}, - {"&scaron;", "\305\241"}, - {"&Yuml;", "\305\270"}, - {"&circ;", "\313\206"}, - {"&tilde;", "\313\234"}, - {"&ensp;", "\342\200\202"}, - {"&emsp;", "\342\200\203"}, - {"&thinsp;", "\342\200\211"}, - {"&ndash;", "\342\200\223"}, - {"&mdash;", "\342\200\224"}, - {"&lsquo;", "\342\200\230"}, - {"&rsquo;", "\342\200\231"}, - {"&sbquo;", "\342\200\232"}, - {"&ldquo;", "\342\200\234"}, - {"&rdquo;", "\342\200\235"}, - {"&bdquo;", "\342\200\236"}, - {"&dagger;", "\342\200\240"}, - {"&Dagger;", "\342\200\241"}, - {"&bull;", "\342\200\242"}, - {"&hellip;", "\342\200\246"}, - {"&permil;", "\342\200\260"}, - {"&lsaquo;", "\342\200\271"}, - {"&rsaquo;", "\342\200\272"}, - {"&euro;", "\342\202\254"}, - {"&trade;", "\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; }