aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-09-05 10:00:53 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-09-05 10:00:53 +0000
commit3bf24b9336184fe9e28f7e09b9c5200a5f82b7d2 (patch)
tree51ccac6f26dcdf9fcfac1a7879477bfde2759b80 /src
parent11776e5a524745b01ac145439ac2892a29bd0826 (diff)
moved more modules to libsylph.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@548 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am18
-rw-r--r--src/account.c416
-rw-r--r--src/account.h61
-rw-r--r--src/customheader.c233
-rw-r--r--src/customheader.h45
-rw-r--r--src/defs.h122
-rw-r--r--src/enums.h55
-rw-r--r--src/filter.c1421
-rw-r--r--src/filter.h214
-rw-r--r--src/folder.c1583
-rw-r--r--src/folder.h395
-rw-r--r--src/imap.c4105
-rw-r--r--src/imap.h114
-rw-r--r--src/main.c3
-rw-r--r--src/md5.c433
-rw-r--r--src/md5.h49
-rw-r--r--src/mh.c1431
-rw-r--r--src/mh.h38
-rw-r--r--src/news.c1062
-rw-r--r--src/news.h59
-rw-r--r--src/nntp.c431
-rw-r--r--src/nntp.h109
-rw-r--r--src/pop.c857
-rw-r--r--src/pop.h153
-rw-r--r--src/prefs_account.c254
-rw-r--r--src/prefs_account.h182
-rw-r--r--src/prefs_common.c429
-rw-r--r--src/prefs_common.h257
-rw-r--r--src/procheader.c799
-rw-r--r--src/procheader.h93
-rw-r--r--src/procmime.c1170
-rw-r--r--src/procmime.h188
-rw-r--r--src/procmsg.c1446
-rw-r--r--src/procmsg.h282
-rw-r--r--src/rfc2015.c50
-rw-r--r--src/rfc2015.h5
-rw-r--r--src/smtp.c613
-rw-r--r--src/smtp.h117
38 files changed, 58 insertions, 19234 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index c567b8b9..ae8991a2 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,8 +3,6 @@ SUBDIRS = icons
bin_PROGRAMS = sylpheed
sylpheed_SOURCES = \
- defs.h \
- enums.h \
version.h \
main.c main.h \
mainwindow.c mainwindow.h \
@@ -18,21 +16,15 @@ sylpheed_SOURCES = \
summary_search.c summary_search.h \
message_search.c message_search.h \
colorlabel.c colorlabel.h \
- folder.c folder.h \
- procmsg.c procmsg.h \
- procheader.c procheader.h \
- filter.c filter.h \
action.c action.h \
compose.c compose.h \
gtkshruler.c gtkshruler.h \
menu.c menu.h \
stock_pixmap.c stock_pixmap.h \
prefs_ui.c prefs_ui.h \
- prefs_common.c prefs_common.h \
prefs_common_dialog.c prefs_common_dialog.h \
prefs_filter.c prefs_filter.h \
prefs_filter_edit.c prefs_filter_edit.h \
- prefs_account.c prefs_account.h \
prefs_account_dialog.c prefs_account_dialog.h \
prefs_folder_item.c prefs_folder_item.h \
prefs_display_header.c prefs_display_header.h \
@@ -40,10 +32,8 @@ sylpheed_SOURCES = \
prefs_summary_column.c prefs_summary_column.h \
prefs_template.c prefs_template.h \
prefs_actions.c prefs_actions.h \
- account.c account.h \
account_dialog.c account_dialog.h \
displayheader.c displayheader.h \
- customheader.c customheader.h \
template.c template.h \
addressbook.c addressbook.h \
addr_compl.c addr_compl.h \
@@ -80,19 +70,11 @@ sylpheed_SOURCES = \
about.c about.h \
setup.c setup.h \
gtkutils.c gtkutils.h \
- md5.c md5.h \
- smtp.c smtp.h \
- pop.c pop.h \
- mh.c mh.h \
mbox.c mbox.h \
send_message.c send_message.h \
inc.c inc.h \
import.c import.h \
export.c export.h \
- nntp.c nntp.h \
- news.c news.h \
- imap.c imap.h \
- procmime.c procmime.h \
rfc2015.c rfc2015.h \
passphrase.c passphrase.h \
select-keys.c select-keys.h \
diff --git a/src/account.c b/src/account.c
deleted file mode 100644
index 2ae0ca43..00000000
--- a/src/account.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "folder.h"
-#include "account.h"
-#include "prefs.h"
-#include "prefs_account.h"
-#include "procmsg.h"
-#include "procheader.h"
-#include "utils.h"
-
-#define PREFSBUFSIZE 1024
-
-PrefsAccount *cur_account;
-
-static GList *account_list = NULL;
-
-
-void account_read_config_all(void)
-{
- GSList *ac_label_list = NULL, *cur;
- gchar *rcpath;
- FILE *fp;
- gchar buf[PREFSBUFSIZE];
- PrefsAccount *ac_prefs;
-
- debug_print(_("Reading all config for each account...\n"));
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
- if ((fp = g_fopen(rcpath, "rb")) == NULL) {
- if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
- g_free(rcpath);
- return;
- }
- g_free(rcpath);
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- if (!strncmp(buf, "[Account: ", 10)) {
- strretchomp(buf);
- memmove(buf, buf + 1, strlen(buf));
- buf[strlen(buf) - 1] = '\0';
- debug_print("Found label: %s\n", buf);
- ac_label_list = g_slist_append(ac_label_list,
- g_strdup(buf));
- }
- }
- fclose(fp);
-
- /* read config data from file */
- cur_account = NULL;
- for (cur = ac_label_list; cur != NULL; cur = cur->next) {
- ac_prefs = prefs_account_new();
- prefs_account_read_config(ac_prefs, (gchar *)cur->data);
- account_list = g_list_append(account_list, ac_prefs);
- if (ac_prefs->is_default)
- cur_account = ac_prefs;
- }
- /* if default is not set, assume first account as default */
- if (!cur_account && account_list) {
- ac_prefs = (PrefsAccount *)account_list->data;
- account_set_as_default(ac_prefs);
- cur_account = ac_prefs;
- }
-
- while (ac_label_list) {
- g_free(ac_label_list->data);
- ac_label_list = g_slist_remove(ac_label_list,
- ac_label_list->data);
- }
-}
-
-void account_write_config_all(void)
-{
- prefs_account_write_config_all(account_list);
-}
-
-PrefsAccount *account_find_from_smtp_server(const gchar *address,
- const gchar *smtp_server)
-{
- GList *cur;
- PrefsAccount *ac;
-
- g_return_val_if_fail(address != NULL, NULL);
- g_return_val_if_fail(smtp_server != NULL, NULL);
-
- for (cur = account_list; cur != NULL; cur = cur->next) {
- ac = (PrefsAccount *)cur->data;
- if (!strcmp2(address, ac->address) &&
- !strcmp2(smtp_server, ac->smtp_server))
- return ac;
- }
-
- return NULL;
-}
-
-/*
- * account_find_from_address:
- * @address: Email address string.
- *
- * Find a mail (not news) account with the specified email address.
- *
- * Return value: The found account, or NULL if not found.
- */
-PrefsAccount *account_find_from_address(const gchar *address)
-{
- GList *cur;
- PrefsAccount *ac;
-
- g_return_val_if_fail(address != NULL, NULL);
-
- for (cur = account_list; cur != NULL; cur = cur->next) {
- ac = (PrefsAccount *)cur->data;
- if (ac->protocol != A_NNTP && ac->address &&
- strcasestr(address, ac->address) != NULL)
- return ac;
- }
-
- return NULL;
-}
-
-PrefsAccount *account_find_from_id(gint id)
-{
- GList *cur;
- PrefsAccount *ac;
-
- for (cur = account_list; cur != NULL; cur = cur->next) {
- ac = (PrefsAccount *)cur->data;
- if (id == ac->account_id)
- return ac;
- }
-
- return NULL;
-}
-
-PrefsAccount *account_find_from_item(FolderItem *item)
-{
- PrefsAccount *ac;
-
- g_return_val_if_fail(item != NULL, NULL);
-
- ac = item->account;
- if (!ac) {
- FolderItem *cur_item = item->parent;
- while (cur_item != NULL) {
- if (cur_item->account && cur_item->ac_apply_sub) {
- ac = cur_item->account;
- break;
- }
- cur_item = cur_item->parent;
- }
- }
- if (!ac)
- ac = item->folder->account;
-
- return ac;
-}
-
-PrefsAccount *account_find_from_message_file(const gchar *file)
-{
- static HeaderEntry hentry[] = {{"From:", NULL, FALSE},
- {"X-Sylpheed-Account-Id:", NULL, FALSE},
- {"AID:", NULL, FALSE},
- {NULL, NULL, FALSE}};
-
- enum
- {
- H_FROM = 0,
- H_X_SYLPHEED_ACCOUNT_ID = 1,
- H_AID = 2
- };
-
- PrefsAccount *ac = NULL;
- FILE *fp;
- gchar *str;
- gchar buf[BUFFSIZE];
- gint hnum;
-
- g_return_val_if_fail(file != NULL, NULL);
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return NULL;
- }
-
- while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
- != -1) {
- str = buf + strlen(hentry[hnum].name);
- if (hnum == H_FROM)
- ac = account_find_from_address(str);
- else if (hnum == H_X_SYLPHEED_ACCOUNT_ID || hnum == H_AID) {
- PrefsAccount *tmp_ac;
-
- tmp_ac = account_find_from_id(atoi(str));
- if (tmp_ac) {
- ac = tmp_ac;
- break;
- }
- }
- }
-
- fclose(fp);
- return ac;
-}
-
-PrefsAccount *account_find_from_msginfo(MsgInfo *msginfo)
-{
- gchar *file;
- PrefsAccount *ac;
-
- file = procmsg_get_message_file(msginfo);
- ac = account_find_from_message_file(file);
- g_free(file);
-
- if (!ac && msginfo->folder)
- ac = account_find_from_item(msginfo->folder);
-
- return ac;
-}
-
-void account_foreach(AccountFunc func, gpointer user_data)
-{
- GList *cur;
-
- for (cur = account_list; cur != NULL; cur = cur->next)
- if (func((PrefsAccount *)cur->data, user_data) != 0)
- return;
-}
-
-GList *account_get_list(void)
-{
- return account_list;
-}
-
-void account_list_free(void)
-{
- g_list_free(account_list);
- account_list = NULL;
-}
-
-void account_append(PrefsAccount *ac_prefs)
-{
- account_list = g_list_append(account_list, ac_prefs);
-}
-
-void account_set_as_default(PrefsAccount *ac_prefs)
-{
- PrefsAccount *ap;
- GList *cur;
-
- for (cur = account_list; cur != NULL; cur = cur->next) {
- ap = (PrefsAccount *)cur->data;
- if (ap->is_default)
- ap->is_default = FALSE;
- }
-
- ac_prefs->is_default = TRUE;
-}
-
-PrefsAccount *account_get_default(void)
-{
- PrefsAccount *ap;
- GList *cur;
-
- for (cur = account_list; cur != NULL; cur = cur->next) {
- ap = (PrefsAccount *)cur->data;
- if (ap->is_default)
- return ap;
- }
-
- return NULL;
-}
-
-#if 0
-void account_set_missing_folder(void)
-{
- PrefsAccount *ap;
- GList *cur;
-
- for (cur = account_list; cur != NULL; cur = cur->next) {
- ap = (PrefsAccount *)cur->data;
- if ((ap->protocol == A_IMAP4 || ap->protocol == A_NNTP) &&
- !ap->folder) {
- Folder *folder;
-
- if (ap->protocol == A_IMAP4) {
- folder = folder_new(F_IMAP, ap->account_name,
- ap->recv_server);
- } else {
- folder = folder_new(F_NEWS, ap->account_name,
- ap->nntp_server);
- }
-
- folder->account = ap;
- ap->folder = REMOTE_FOLDER(folder);
- folder_add(folder);
- if (ap->protocol == A_IMAP4) {
- if (main_window_toggle_online_if_offline
- (main_window_get())) {
- folder->klass->create_tree(folder);
- statusbar_pop_all();
- }
- }
- }
- }
-}
-#endif
-
-FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
- SpecialFolderItemType type)
-{
- FolderItem *item = NULL;
-
- g_return_val_if_fail(ac_prefs != NULL, NULL);
-
- switch (type) {
- case F_INBOX:
- if (ac_prefs->folder)
- item = FOLDER(ac_prefs->folder)->inbox;
- if (!item)
- item = folder_get_default_inbox();
- break;
- case F_OUTBOX:
- if (ac_prefs->set_sent_folder && ac_prefs->sent_folder) {
- item = folder_find_item_from_identifier
- (ac_prefs->sent_folder);
- }
- if (!item) {
- if (ac_prefs->folder)
- item = FOLDER(ac_prefs->folder)->outbox;
- if (!item)
- item = folder_get_default_outbox();
- }
- break;
- case F_DRAFT:
- if (ac_prefs->set_draft_folder && ac_prefs->draft_folder) {
- item = folder_find_item_from_identifier
- (ac_prefs->draft_folder);
- }
- if (!item) {
- if (ac_prefs->folder)
- item = FOLDER(ac_prefs->folder)->draft;
- if (!item)
- item = folder_get_default_draft();
- }
- break;
- case F_QUEUE:
- if (ac_prefs->folder)
- item = FOLDER(ac_prefs->folder)->queue;
- if (!item)
- item = folder_get_default_queue();
- break;
- case F_TRASH:
- if (ac_prefs->set_trash_folder && ac_prefs->trash_folder) {
- item = folder_find_item_from_identifier
- (ac_prefs->trash_folder);
- }
- if (!item) {
- if (ac_prefs->folder)
- item = FOLDER(ac_prefs->folder)->trash;
- if (!item)
- item = folder_get_default_trash();
- }
- break;
- default:
- break;
- }
-
- return item;
-}
-
-void account_destroy(PrefsAccount *ac_prefs)
-{
- g_return_if_fail(ac_prefs != NULL);
-
- folder_unref_account_all(ac_prefs);
-
- prefs_account_free(ac_prefs);
- account_list = g_list_remove(account_list, ac_prefs);
-
- if (cur_account == ac_prefs) cur_account = NULL;
- if (!cur_account && account_list) {
- cur_account = account_get_default();
- if (!cur_account) {
- ac_prefs = (PrefsAccount *)account_list->data;
- account_set_as_default(ac_prefs);
- cur_account = ac_prefs;
- }
- }
-}
diff --git a/src/account.h b/src/account.h
deleted file mode 100644
index 0cef7c50..00000000
--- a/src/account.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ACCOUNT_H__
-#define __ACCOUNT_H__
-
-#include <glib.h>
-
-#include "prefs.h"
-#include "prefs_account.h"
-#include "folder.h"
-#include "procmsg.h"
-
-typedef gint (*AccountFunc) (PrefsAccount *ac_prefs,
- gpointer user_data);
-
-extern PrefsAccount *cur_account;
-
-void account_read_config_all (void);
-void account_write_config_all (void);
-
-PrefsAccount *account_find_from_smtp_server (const gchar *address,
- const gchar *smtp_server);
-PrefsAccount *account_find_from_address (const gchar *address);
-PrefsAccount *account_find_from_id (gint id);
-PrefsAccount *account_find_from_item (FolderItem *item);
-PrefsAccount *account_find_from_message_file (const gchar *file);
-PrefsAccount *account_find_from_msginfo (MsgInfo *msginfo);
-
-void account_foreach (AccountFunc func,
- gpointer user_data);
-GList *account_get_list (void);
-void account_list_free (void);
-void account_append (PrefsAccount *ac_prefs);
-
-void account_set_as_default (PrefsAccount *ac_prefs);
-PrefsAccount *account_get_default (void);
-
-//void account_set_missing_folder(void);
-FolderItem *account_get_special_folder(PrefsAccount *ac_prefs,
- SpecialFolderItemType type);
-
-void account_destroy (PrefsAccount *ac_prefs);
-
-#endif /* __ACCOUNT_H__ */
diff --git a/src/customheader.c b/src/customheader.c
deleted file mode 100644
index c145484d..00000000
--- a/src/customheader.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-
-#include "customheader.h"
-#include "prefs.h"
-#include "prefs_account.h"
-#include "utils.h"
-
-
-void custom_header_read_config(PrefsAccount *ac)
-{
- gchar *rcpath;
- FILE *fp;
- gchar buf[PREFSBUFSIZE];
- CustomHeader *ch;
-
- debug_print("Reading custom header configuration...\n");
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- CUSTOM_HEADER_RC, NULL);
- if ((fp = g_fopen(rcpath, "rb")) == NULL) {
- if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
- g_free(rcpath);
- ac->customhdr_list = NULL;
- return;
- }
- g_free(rcpath);
-
- /* remove all previous headers list */
- while (ac->customhdr_list != NULL) {
- ch = (CustomHeader *)ac->customhdr_list->data;
- custom_header_free(ch);
- ac->customhdr_list = g_slist_remove(ac->customhdr_list, ch);
- }
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- ch = custom_header_read_str(buf);
- if (ch) {
- if (ch->account_id == ac->account_id) {
- ac->customhdr_list =
- g_slist_append(ac->customhdr_list, ch);
- } else
- custom_header_free(ch);
- }
- }
-
- fclose(fp);
-}
-
-void custom_header_write_config(PrefsAccount *ac)
-{
- gchar *rcpath;
- PrefFile *pfile;
- GSList *cur;
- gchar buf[PREFSBUFSIZE];
- FILE * fp;
- CustomHeader *ch;
-
- GSList *all_hdrs = NULL;
-
- debug_print("Writing custom header configuration...\n");
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- CUSTOM_HEADER_RC, NULL);
-
- if ((fp = g_fopen(rcpath, "rb")) == NULL) {
- if (ENOENT != errno) FILE_OP_ERROR(rcpath, "fopen");
- } else {
- all_hdrs = NULL;
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- ch = custom_header_read_str(buf);
- if (ch) {
- if (ch->account_id != ac->account_id)
- all_hdrs =
- g_slist_append(all_hdrs, ch);
- else
- custom_header_free(ch);
- }
- }
-
- fclose(fp);
- }
-
- if ((pfile = prefs_file_open(rcpath)) == NULL) {
- g_warning("failed to write configuration to file\n");
- g_free(rcpath);
- return;
- }
-
- for (cur = all_hdrs; cur != NULL; cur = cur->next) {
- CustomHeader *hdr = (CustomHeader *)cur->data;
- gchar *chstr;
-
- chstr = custom_header_get_str(hdr);
- if (fputs(chstr, pfile->fp) == EOF ||
- fputc('\n', pfile->fp) == EOF) {
- FILE_OP_ERROR(rcpath, "fputs || fputc");
- prefs_file_close_revert(pfile);
- g_free(rcpath);
- g_free(chstr);
- return;
- }
- g_free(chstr);
- }
-
- for (cur = ac->customhdr_list; cur != NULL; cur = cur->next) {
- CustomHeader *hdr = (CustomHeader *)cur->data;
- gchar *chstr;
-
- chstr = custom_header_get_str(hdr);
- if (fputs(chstr, pfile->fp) == EOF ||
- fputc('\n', pfile->fp) == EOF) {
- FILE_OP_ERROR(rcpath, "fputs || fputc");
- prefs_file_close_revert(pfile);
- g_free(rcpath);
- g_free(chstr);
- return;
- }
- g_free(chstr);
- }
-
- g_free(rcpath);
-
- while (all_hdrs != NULL) {
- ch = (CustomHeader *)all_hdrs->data;
- custom_header_free(ch);
- all_hdrs = g_slist_remove(all_hdrs, ch);
- }
-
- if (prefs_file_close(pfile) < 0) {
- g_warning("failed to write configuration to file\n");
- return;
- }
-}
-
-gchar *custom_header_get_str(CustomHeader *ch)
-{
- return g_strdup_printf("%i:%s: %s",
- ch->account_id, ch->name,
- ch->value ? ch->value : "");
-}
-
-CustomHeader *custom_header_read_str(const gchar *buf)
-{
- CustomHeader *ch;
- gchar *account_id_str;
- gint id;
- gchar *name;
- gchar *value;
- gchar *tmp;
-
- Xstrdup_a(tmp, buf, return NULL);
-
- account_id_str = tmp;
-
- name = strchr(account_id_str, ':');
- if (!name)
- return NULL;
- else {
- gchar *endp;
-
- *name++ = '\0';
- id = strtol(account_id_str, &endp, 10);
- if (*endp != '\0') return NULL;
- }
-
- value = strchr(name, ':');
- if (!value) return NULL;
-
- *value++ = '\0';
-
- g_strstrip(name);
- g_strstrip(value);
-
- ch = g_new0(CustomHeader, 1);
- ch->account_id = id;
- ch->name = *name ? g_strdup(name) : NULL;
- ch->value = *value ? g_strdup(value) : NULL;
-
- return ch;
-}
-
-CustomHeader *custom_header_find(GSList *header_list, const gchar *header)
-{
- GSList *cur;
- CustomHeader *chdr;
-
- for (cur = header_list; cur != NULL; cur = cur->next) {
- chdr = (CustomHeader *)cur->data;
- if (!g_ascii_strcasecmp(chdr->name, header))
- return chdr;
- }
-
- return NULL;
-}
-
-void custom_header_free(CustomHeader *ch)
-{
- if (!ch) return;
-
- g_free(ch->name);
- g_free(ch->value);
- g_free(ch);
-}
diff --git a/src/customheader.h b/src/customheader.h
deleted file mode 100644
index 27ae9373..00000000
--- a/src/customheader.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __CUSTOMHEADER_H__
-#define __CUSTOMHEADER_H__
-
-#include <glib.h>
-
-typedef struct _CustomHeader CustomHeader;
-
-#include "prefs_account.h"
-
-struct _CustomHeader
-{
- gint account_id;
- gchar *name;
- gchar *value;
-};
-
-void custom_header_read_config (PrefsAccount *ac);
-void custom_header_write_config (PrefsAccount *ac);
-
-gchar *custom_header_get_str (CustomHeader *ch);
-CustomHeader *custom_header_read_str (const gchar *buf);
-CustomHeader *custom_header_find (GSList *header_list,
- const gchar *header);
-void custom_header_free (CustomHeader *ch);
-
-#endif /* __CUSTOMHEADER_H__ */
diff --git a/src/defs.h b/src/defs.h
deleted file mode 100644
index 9683c28d..00000000
--- a/src/defs.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __DEFS_H__
-#define __DEFS_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glibconfig.h>
-
-#ifdef G_OS_WIN32
-# include <glib/gwin32.h>
-#endif
-
-#if HAVE_PATHS_H
-# include <paths.h>
-#endif
-
-#if HAVE_SYS_PARAM_H
-# include <sys/param.h>
-#endif
-
-#define INBOX_DIR "inbox"
-#define OUTBOX_DIR "sent"
-#define QUEUE_DIR "queue"
-#define DRAFT_DIR "draft"
-#define TRASH_DIR "trash"
-#ifdef G_OS_WIN32
-# define RC_DIR "Sylpheed"
-#else
-# define RC_DIR ".sylpheed-2.0"
-#endif
-#define OLD_RC_DIR ".sylpheed"
-#define NEWS_CACHE_DIR "newscache"
-#define IMAP_CACHE_DIR "imapcache"
-#define MIME_TMP_DIR "mimetmp"
-#define COMMON_RC "sylpheedrc"
-#define ACCOUNT_RC "accountrc"
-#define FILTER_RC "filterrc"
-#define FILTER_LIST "filter.xml"
-#define FILTER_HEADER_RC "filterheaderrc"
-#define CUSTOM_HEADER_RC "customheaderrc"
-#define DISPLAY_HEADER_RC "dispheaderrc"
-#define MENU_RC "menurc"
-#define ACTIONS_RC "actionsrc"
-#define COMMAND_HISTORY "command_history"
-#define TEMPLATE_DIR "templates"
-#define TMP_DIR "tmp"
-#define UIDL_DIR "uidl"
-#define NEWSGROUP_LIST ".newsgroup_list"
-#define ADDRESS_BOOK "addressbook.xml"
-#define MANUAL_HTML_INDEX "sylpheed.html"
-#define FAQ_HTML_INDEX "sylpheed-faq.html"
-#define HOMEPAGE_URI "http://sylpheed.good-day.net/"
-#define FOLDER_LIST "folderlist.xml"
-#define CACHE_FILE ".sylpheed_cache"
-#define MARK_FILE ".sylpheed_mark"
-#define CACHE_VERSION 0x21
-#define MARK_VERSION 2
-
-#ifdef G_OS_WIN32
-# define DEFAULT_SIGNATURE "signature.txt"
-#else
-# define DEFAULT_SIGNATURE ".signature"
-#endif
-#define DEFAULT_INC_PATH "/usr/bin/mh/inc"
-#define DEFAULT_INC_PROGRAM "inc"
-/* #define DEFAULT_INC_PATH "/usr/bin/imget" */
-/* #define DEFAULT_INC_PROGRAM "imget" */
-#define DEFAULT_SENDMAIL_CMD "/usr/sbin/sendmail -t -i"
-#define DEFAULT_BROWSER_CMD "mozilla-firefox -remote 'openURL(%s,new-window)'"
-
-#ifdef _PATH_MAILDIR
-# define DEFAULT_SPOOL_PATH _PATH_MAILDIR
-#else
-# define DEFAULT_SPOOL_PATH "/var/spool/mail"
-#endif
-
-#define BUFFSIZE 8192
-
-#ifndef MAXPATHLEN
-# define MAXPATHLEN 4095
-#endif
-
-#define DEFAULT_HEIGHT 460
-#define DEFAULT_FOLDERVIEW_WIDTH 179
-#define DEFAULT_MAINVIEW_WIDTH 600
-#define DEFAULT_SUMMARY_HEIGHT 140
-#define DEFAULT_HEADERVIEW_HEIGHT 40
-#define DEFAULT_COMPOSE_HEIGHT 560
-#define BORDER_WIDTH 2
-#define CTREE_INDENT 18
-#define FOLDER_SPACING 4
-#define MAX_ENTRY_LENGTH 8191
-#define COLOR_DIM 35000
-#define UI_REFRESH_INTERVAL 50000 /* usec */
-#define FOLDER_UPDATE_INTERVAL 1500 /* msec */
-#define PROGRESS_UPDATE_INTERVAL 200 /* msec */
-#define SESSION_TIMEOUT_INTERVAL 60 /* sec */
-#define MAX_HISTORY_SIZE 16
-
-#define DEFAULT_MESSAGE_FONT "Monospace 12"
-
-#endif /* __DEFS_H__ */
diff --git a/src/enums.h b/src/enums.h
deleted file mode 100644
index 13ac2a18..00000000
--- a/src/enums.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __ENUMS_H__
-#define __ENUMS_H__
-
-typedef enum
-{
- TOOLBAR_NONE,
- TOOLBAR_ICON,
- TOOLBAR_TEXT,
- TOOLBAR_BOTH
-} ToolbarStyle;
-
-typedef enum
-{
- S_COL_MARK,
- S_COL_UNREAD,
- S_COL_MIME,
- S_COL_SUBJECT,
- S_COL_FROM,
- S_COL_DATE,
- S_COL_SIZE,
- S_COL_NUMBER,
-
- S_COL_MSG_INFO,
-
- S_COL_LABEL,
- S_COL_TO,
-
- S_COL_FOREGROUND,
- S_COL_BOLD,
-
- N_SUMMARY_COLS
-} SummaryColumnType;
-
-#define N_SUMMARY_VISIBLE_COLS S_COL_MSG_INFO
-
-#endif /* __ENUMS_H__ */
diff --git a/src/filter.c b/src/filter.c
deleted file mode 100644
index efc2fa02..00000000
--- a/src/filter.c
+++ /dev/null
@@ -1,1421 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <string.h>
-#include <strings.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#if HAVE_REGEX_H
-# include <regex.h>
-#endif
-#include <time.h>
-
-#include "filter.h"
-#include "procmsg.h"
-#include "procheader.h"
-#include "folder.h"
-#include "utils.h"
-#include "xml.h"
-#include "prefs.h"
-#include "prefs_common.h"
-#include "prefs_account.h"
-#include "account.h"
-
-typedef enum
-{
- FLT_O_CONTAIN = 1 << 0,
- FLT_O_CASE_SENS = 1 << 1,
- FLT_O_REGEX = 1 << 2
-} FilterOldFlag;
-
-static gboolean filter_match_cond (FilterCond *cond,
- MsgInfo *msginfo,
- GSList *hlist,
- FilterInfo *fltinfo);
-static gboolean filter_match_header_cond(FilterCond *cond,
- GSList *hlist);
-
-static void filter_cond_free (FilterCond *cond);
-static void filter_action_free (FilterAction *action);
-
-
-gint filter_apply(GSList *fltlist, const gchar *file, FilterInfo *fltinfo)
-{
- MsgInfo *msginfo;
- gint ret = 0;
-
- g_return_val_if_fail(file != NULL, -1);
- g_return_val_if_fail(fltinfo != NULL, -1);
-
- if (!fltlist) return 0;
-
- msginfo = procheader_parse_file(file, fltinfo->flags, FALSE);
- if (!msginfo) return 0;
- msginfo->file_path = g_strdup(file);
-
- ret = filter_apply_msginfo(fltlist, msginfo, fltinfo);
-
- procmsg_msginfo_free(msginfo);
-
- return ret;
-}
-
-gint filter_apply_msginfo(GSList *fltlist, MsgInfo *msginfo,
- FilterInfo *fltinfo)
-{
- gchar *file;
- GSList *hlist, *cur;
- FilterRule *rule;
- gint ret = 0;
-
- g_return_val_if_fail(msginfo != NULL, -1);
- g_return_val_if_fail(fltinfo != NULL, -1);
-
- if (!fltlist) return 0;
-
- file = procmsg_get_message_file(msginfo);
- hlist = procheader_get_header_list_from_file(file);
- if (!hlist) {
- g_free(file);
- return 0;
- }
-
- for (cur = fltlist; cur != NULL; cur = cur->next) {
- rule = (FilterRule *)cur->data;
- if (!rule->enabled) continue;
- if (filter_match_rule(rule, msginfo, hlist, fltinfo)) {
- ret = filter_action_exec(rule, msginfo, file, fltinfo);
- if (ret < 0) {
- g_warning("filter_action_exec() returned error\n");
- break;
- }
- if (fltinfo->drop_done == TRUE ||
- fltinfo->actions[FLT_ACTION_STOP_EVAL] == TRUE)
- break;
- }
- }
-
- procheader_header_list_destroy(hlist);
- g_free(file);
-
- return ret;
-}
-
-gint filter_action_exec(FilterRule *rule, MsgInfo *msginfo, const gchar *file,
- FilterInfo *fltinfo)
-{
- FolderItem *dest_folder = NULL;
- FilterAction *action;
- GSList *cur;
- gchar *cmdline;
- gboolean copy_to_self = FALSE;
-
- g_return_val_if_fail(rule != NULL, -1);
- g_return_val_if_fail(msginfo != NULL, -1);
- g_return_val_if_fail(file != NULL, -1);
- g_return_val_if_fail(fltinfo != NULL, -1);
-
- for (cur = rule->action_list; cur != NULL; cur = cur->next) {
- action = (FilterAction *)cur->data;
-
- switch (action->type) {
- case FLT_ACTION_MARK:
- debug_print("filter_action_exec(): mark\n");
- MSG_SET_PERM_FLAGS(fltinfo->flags, MSG_MARKED);
- fltinfo->actions[action->type] = TRUE;
- break;
- case FLT_ACTION_COLOR_LABEL:
- debug_print("filter_action_exec(): color label: %d\n",
- action->int_value);
- MSG_UNSET_PERM_FLAGS(fltinfo->flags,
- MSG_CLABEL_FLAG_MASK);
- MSG_SET_COLORLABEL_VALUE(fltinfo->flags,
- action->int_value);
- fltinfo->actions[action->type] = TRUE;
- break;
- case FLT_ACTION_MARK_READ:
- debug_print("filter_action_exec(): mark as read\n");
- if (msginfo->folder) {
- if (MSG_IS_NEW(fltinfo->flags))
- msginfo->folder->new--;
- if (MSG_IS_UNREAD(fltinfo->flags))
- msginfo->folder->unread--;
- }
- MSG_UNSET_PERM_FLAGS(fltinfo->flags, MSG_NEW|MSG_UNREAD);
- fltinfo->actions[action->type] = TRUE;
- break;
- case FLT_ACTION_EXEC:
- cmdline = g_strconcat(action->str_value, " ", file,
- NULL);
- execute_command_line(cmdline, FALSE);
- g_free(cmdline);
- fltinfo->actions[action->type] = TRUE;
- break;
- case FLT_ACTION_EXEC_ASYNC:
- cmdline = g_strconcat(action->str_value, " ", file,
- NULL);
- execute_command_line(cmdline, TRUE);
- g_free(cmdline);
- fltinfo->actions[action->type] = TRUE;
- break;
- default:
- break;
- }
- }
-
- for (cur = rule->action_list; cur != NULL; cur = cur->next) {
- action = (FilterAction *)cur->data;
-
- switch (action->type) {
- case FLT_ACTION_MOVE:
- case FLT_ACTION_COPY:
- dest_folder = folder_find_item_from_identifier
- (action->str_value);
- if (!dest_folder) {
- g_warning("dest folder '%s' not found\n",
- action->str_value);
- return -1;
- }
- debug_print("filter_action_exec(): %s: dest_folder = %s\n",
- action->type == FLT_ACTION_COPY ?
- "copy" : "move", action->str_value);
-
- if (msginfo->folder) {
- gint val;
-
- /* local filtering */
- if (msginfo->folder == dest_folder)
- copy_to_self = TRUE;
- else {
- if (action->type == FLT_ACTION_COPY) {
- val = folder_item_copy_msg
- (dest_folder, msginfo);
- if (val == -1)
- return -1;
- }
- fltinfo->actions[action->type] = TRUE;
- }
- } else {
- if (folder_item_add_msg(dest_folder, file,
- &fltinfo->flags,
- FALSE) < 0)
- return -1;
- fltinfo->actions[action->type] = TRUE;
- }
-
- fltinfo->dest_list = g_slist_append(fltinfo->dest_list,
- dest_folder);
- if (action->type == FLT_ACTION_MOVE) {
- fltinfo->move_dest = dest_folder;
- fltinfo->drop_done = TRUE;
- }
- break;
- default:
- break;
- }
- }
-
- if (fltinfo->drop_done == TRUE)
- return 0;
-
- for (cur = rule->action_list; cur != NULL; cur = cur->next) {
- action = (FilterAction *)cur->data;
-
- switch (action->type) {
- case FLT_ACTION_NOT_RECEIVE:
- debug_print("filter_action_exec(): don't receive\n");
- fltinfo->drop_done = TRUE;
- fltinfo->actions[action->type] = TRUE;
- return 0;
- case FLT_ACTION_DELETE:
- debug_print("filter_action_exec(): delete\n");
- if (msginfo->folder) {
- /* local filtering */
- if (copy_to_self == FALSE)
- fltinfo->actions[action->type] = TRUE;
- } else
- fltinfo->actions[action->type] = TRUE;
-
- fltinfo->drop_done = TRUE;
- return 0;
- case FLT_ACTION_STOP_EVAL:
- debug_print("filter_action_exec(): stop evaluation\n");
- fltinfo->actions[action->type] = TRUE;
- return 0;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-static gboolean strmatch_regex(const gchar *haystack, const gchar *needle)
-{
-#if HAVE_REGEX_H && HAVE_REGCOMP
- gint ret = 0;
- regex_t preg;
- regmatch_t pmatch[1];
-
- ret = regcomp(&preg, needle, REG_EXTENDED|REG_ICASE);
- if (ret != 0) return FALSE;
-
- ret = regexec(&preg, haystack, 1, pmatch, 0);
- regfree(&preg);
-
- if (ret == REG_NOMATCH) return FALSE;
-
- if (pmatch[0].rm_so != -1)
- return TRUE;
- else
-#endif
- return FALSE;
-}
-
-gboolean filter_match_rule(FilterRule *rule, MsgInfo *msginfo, GSList *hlist,
- FilterInfo *fltinfo)
-{
- FilterCond *cond;
- GSList *cur;
- gboolean matched;
-
- g_return_val_if_fail(rule->cond_list != NULL, FALSE);
- g_return_val_if_fail(rule->action_list != NULL, FALSE);
-
- switch (rule->timing) {
- case FLT_TIMING_ANY:
- break;
- case FLT_TIMING_ON_RECEIVE:
- if (msginfo->folder != NULL)
- return FALSE;
- break;
- case FLT_TIMING_MANUAL:
- if (msginfo->folder == NULL)
- return FALSE;
- break;
- default:
- break;
- }
-
- if (rule->bool_op == FLT_AND) {
- for (cur = rule->cond_list; cur != NULL; cur = cur->next) {
- cond = (FilterCond *)cur->data;
- matched = filter_match_cond(cond, msginfo, hlist,
- fltinfo);
- if (matched == FALSE)
- return FALSE;
- }
-
- return TRUE;
- } else if (rule->bool_op == FLT_OR) {
- for (cur = rule->cond_list; cur != NULL; cur = cur->next) {
- cond = (FilterCond *)cur->data;
- matched = filter_match_cond(cond, msginfo, hlist,
- fltinfo);
- if (matched == TRUE)
- return TRUE;
- }
-
- return FALSE;
- }
-
- return FALSE;
-}
-
-static gboolean filter_match_cond(FilterCond *cond, MsgInfo *msginfo,
- GSList *hlist, FilterInfo *fltinfo)
-{
- gboolean matched = FALSE;
- gchar *file;
- gchar *cmdline;
- PrefsAccount *cond_ac;
-
- switch (cond->type) {
- case FLT_COND_HEADER:
- case FLT_COND_ANY_HEADER:
- case FLT_COND_TO_OR_CC:
- return filter_match_header_cond(cond, hlist);
- case FLT_COND_BODY:
- matched = procmime_find_string(msginfo, cond->str_value,
- cond->match_func);
- break;
- case FLT_COND_CMD_TEST:
- file = procmsg_get_message_file(msginfo);
- cmdline = g_strconcat(cond->str_value, " ", file, NULL);
- matched = (execute_command_line(cmdline, FALSE) == 0);
- g_free(cmdline);
- g_free(file);
- break;
- case FLT_COND_SIZE_GREATER:
- matched = (msginfo->size > cond->int_value * 1024);
- break;
- case FLT_COND_AGE_GREATER:
- matched = (time(NULL) - msginfo->date_t >
- cond->int_value * 24 * 60 * 60);
- break;
- case FLT_COND_ACCOUNT:
- cond_ac = account_find_from_id(cond->int_value);
- matched = (cond_ac != NULL && cond_ac == fltinfo->account);
- break;
- default:
- g_warning("filter_match_cond(): unknown condition: %d\n",
- cond->type);
- return FALSE;
- }
-
- if (FLT_IS_NOT_MATCH(cond->match_flag))
- matched = !matched;
-
- return matched;
-}
-
-static gboolean filter_match_header_cond(FilterCond *cond, GSList *hlist)
-{
- gboolean matched = FALSE;
- GSList *cur;
- Header *header;
-
- for (cur = hlist; cur != NULL; cur = cur->next) {
- header = (Header *)cur->data;
-
- switch (cond->type) {
- case FLT_COND_HEADER:
- if (!g_ascii_strcasecmp
- (header->name, cond->header_name)) {
- if (!cond->str_value ||
- cond->match_func(header->body,
- cond->str_value))
- matched = TRUE;
- }
- break;
- case FLT_COND_ANY_HEADER:
- if (!cond->str_value ||
- cond->match_func(header->body, cond->str_value))
- matched = TRUE;
- break;
- case FLT_COND_TO_OR_CC:
- if (!g_ascii_strcasecmp(header->name, "To") ||
- !g_ascii_strcasecmp(header->name, "Cc")) {
- if (!cond->str_value ||
- cond->match_func(header->body,
- cond->str_value))
- matched = TRUE;
- }
- break;
- default:
- break;
- }
-
- if (matched == TRUE)
- break;
- }
-
- if (FLT_IS_NOT_MATCH(cond->match_flag))
- matched = !matched;
-
- return matched;
-}
-
-#define RETURN_IF_TAG_NOT_MATCH(tag_name) \
- if (strcmp2(xmlnode->tag->tag, tag_name) != 0) { \
- g_warning("tag name != \"" tag_name "\"\n"); \
- filter_cond_list_free(cond_list); \
- filter_action_list_free(cond_list); \
- return FALSE; \
- } \
-
-#define STR_SWITCH(sw) { const gchar *sw_str = sw;
-#define STR_CASE_BEGIN(str) if (!strcmp(sw_str, str)) {
-#define STR_CASE(str) } else if (!strcmp(sw_str, str)) {
-#define STR_CASE_END } }
-
-static gboolean filter_xml_node_func(GNode *node, gpointer data)
-{
- XMLNode *xmlnode;
- GList *list;
- const gchar *name = NULL;
- FilterTiming timing = FLT_TIMING_ANY;
- gboolean enabled = TRUE;
- FilterRule *rule;
- FilterBoolOp bool_op = FLT_OR;
- GSList *cond_list = NULL;
- GSList *action_list = NULL;
- GNode *child, *cond_child, *action_child;
- GSList **fltlist = (GSList **)data;
-
- if (g_node_depth(node) != 2) return FALSE;
- g_return_val_if_fail(node->data != NULL, FALSE);
-
- xmlnode = node->data;
- RETURN_IF_TAG_NOT_MATCH("rule");
-
- for (list = xmlnode->tag->attr; list != NULL; list = list->next) {
- XMLAttr *attr = (XMLAttr *)list->data;
-
- if (!attr || !attr->name || !attr->value) continue;
- if (!strcmp(attr->name, "name"))
- name = attr->value;
- else if (!strcmp(attr->name, "timing")) {
- if (!strcmp(attr->value, "any"))
- timing = FLT_TIMING_ANY;
- else if (!strcmp(attr->value, "receive"))
- timing = FLT_TIMING_ON_RECEIVE;
- else if (!strcmp(attr->value, "manual"))
- timing = FLT_TIMING_MANUAL;
- } else if (!strcmp(attr->name, "enabled")) {
- if (!strcmp(attr->value, "true"))
- enabled = TRUE;
- else
- enabled = FALSE;
- }
- }
-
- /* condition list */
- child = node->children;
- if (!child) {
- g_warning("<rule> must have children\n");
- return FALSE;
- }
- xmlnode = child->data;
- RETURN_IF_TAG_NOT_MATCH("condition-list");
- for (list = xmlnode->tag->attr; list != NULL; list = list->next) {
- XMLAttr *attr = (XMLAttr *)list->data;
-
- if (attr && attr->name && attr->value &&
- !strcmp(attr->name, "bool")) {
- if (!strcmp(attr->value, "or"))
- bool_op = FLT_OR;
- else
- bool_op = FLT_AND;
- }
- }
-
- for (cond_child = child->children; cond_child != NULL;
- cond_child = cond_child->next) {
- const gchar *type = NULL;
- const gchar *name = NULL;
- const gchar *value = NULL;
- FilterCond *cond;
- FilterCondType cond_type = FLT_COND_HEADER;
- FilterMatchType match_type = FLT_CONTAIN;
- FilterMatchFlag match_flag = 0;
-
- xmlnode = cond_child->data;
- if (!xmlnode || !xmlnode->tag || !xmlnode->tag->tag) continue;
-
- for (list = xmlnode->tag->attr; list != NULL; list = list->next) {
- XMLAttr *attr = (XMLAttr *)list->data;
-
- if (!attr || !attr->name || !attr->value) continue;
- if (!strcmp(attr->name, "type"))
- type = attr->value;
- else if (!strcmp(attr->name, "name"))
- name = attr->value;
- }
-
- if (type) {
- filter_rule_match_type_str_to_enum
- (type, &match_type, &match_flag);
- }
- value = xmlnode->element;
-
- STR_SWITCH(xmlnode->tag->tag)
- STR_CASE_BEGIN("match-header")
- cond_type = FLT_COND_HEADER;
- STR_CASE("match-any-header")
- cond_type = FLT_COND_ANY_HEADER;
- STR_CASE("match-to-or-cc")
- cond_type = FLT_COND_TO_OR_CC;
- STR_CASE("match-body-text")
- cond_type = FLT_COND_BODY;
- STR_CASE("command-test")
- cond_type = FLT_COND_CMD_TEST;
- STR_CASE("size")
- cond_type = FLT_COND_SIZE_GREATER;
- STR_CASE("age")
- cond_type = FLT_COND_AGE_GREATER;
- STR_CASE("account-id")
- cond_type = FLT_COND_ACCOUNT;
- STR_CASE_END
-
- cond = filter_cond_new(cond_type, match_type, match_flag,
- name, value);
- cond_list = g_slist_append(cond_list, cond);
- }
-
- /* action list */
- child = child->next;
- if (!child) {
- g_warning("<rule> must have multiple children\n");
- filter_cond_list_free(cond_list);
- return FALSE;
- }
- xmlnode = child->data;
- RETURN_IF_TAG_NOT_MATCH("action-list");
-
- for (action_child = child->children; action_child != NULL;
- action_child = action_child->next) {
- FilterAction *action;
- FilterActionType action_type = FLT_ACTION_NONE;
-
- xmlnode = action_child->data;
- if (!xmlnode || !xmlnode->tag || !xmlnode->tag->tag) continue;
-
- STR_SWITCH(xmlnode->tag->tag)
- STR_CASE_BEGIN("move")
- action_type = FLT_ACTION_MOVE;
- STR_CASE("copy")
- action_type = FLT_ACTION_COPY;
- STR_CASE("not-receive")
- action_type = FLT_ACTION_NOT_RECEIVE;
- STR_CASE("delete")
- action_type = FLT_ACTION_DELETE;
- STR_CASE("exec")
- action_type = FLT_ACTION_EXEC;
- STR_CASE("exec-async")
- action_type = FLT_ACTION_EXEC_ASYNC;
- STR_CASE("mark")
- action_type = FLT_ACTION_MARK;
- STR_CASE("color-label")
- action_type = FLT_ACTION_COLOR_LABEL;
- STR_CASE("mark-as-read")
- action_type = FLT_ACTION_MARK_READ;
- STR_CASE("forward")
- action_type = FLT_ACTION_FORWARD;
- STR_CASE("forward-as-attachment")
- action_type = FLT_ACTION_FORWARD_AS_ATTACHMENT;
- STR_CASE("redirect")
- action_type = FLT_ACTION_REDIRECT;
- STR_CASE("stop-eval")
- action_type = FLT_ACTION_STOP_EVAL;
- STR_CASE_END
-
- action = filter_action_new(action_type, xmlnode->element);
- action_list = g_slist_append(action_list, action);
- }
-
- if (name && cond_list && action_list) {
- rule = filter_rule_new(name, bool_op, cond_list, action_list);
- rule->timing = timing;
- rule->enabled = enabled;
- *fltlist = g_slist_prepend(*fltlist, rule);
- }
-
- return FALSE;
-}
-
-#undef RETURN_IF_TAG_NOT_MATCH
-#undef STR_SWITCH
-#undef STR_CASE_BEGIN
-#undef STR_CASE
-#undef STR_CASE_END
-
-GSList *filter_xml_node_to_filter_list(GNode *node)
-{
- GSList *fltlist = NULL;
-
- g_return_val_if_fail(node != NULL, NULL);
-
- g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, 2,
- filter_xml_node_func, &fltlist);
- fltlist = g_slist_reverse(fltlist);
-
- return fltlist;
-}
-
-void filter_read_config(void)
-{
- gchar *rcpath;
- GNode *node;
- FilterRule *rule;
-
- debug_print("Reading filter configuration...\n");
-
- /* remove all previous filter list */
- while (prefs_common.fltlist != NULL) {
- rule = (FilterRule *)prefs_common.fltlist->data;
- filter_rule_free(rule);
- prefs_common.fltlist = g_slist_remove(prefs_common.fltlist,
- rule);
- }
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_LIST,
- NULL);
- if (!is_file_exist(rcpath)) {
- g_free(rcpath);
- return;
- }
-
- node = xml_parse_file(rcpath);
- if (!node) {
- g_warning("Can't parse %s\n", rcpath);
- g_free(rcpath);
- return;
- }
- g_free(rcpath);
-
- prefs_common.fltlist = filter_xml_node_to_filter_list(node);
-
- xml_free_tree(node);
-}
-
-#define NODE_NEW(tag, text) \
- node = xml_node_new(xml_tag_new(tag), text)
-#define ADD_ATTR(name, value) \
- xml_tag_add_attr(node->tag, xml_attr_new(name, value))
-
-void filter_write_config(void)
-{
- gchar *rcpath;
- PrefFile *pfile;
- GSList *cur;
-
- debug_print("Writing filter configuration...\n");
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, FILTER_LIST,
- NULL);
- if ((pfile = prefs_file_open(rcpath)) == NULL) {
- g_warning("failed to write filter configuration to file\n");
- g_free(rcpath);
- return;
- }
-
- xml_file_put_xml_decl(pfile->fp);
- fputs("\n<filter>\n", pfile->fp);
-
- for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
- FilterRule *rule = (FilterRule *)cur->data;
- GSList *cur_cond;
- GSList *cur_action;
- gchar match_type[16];
-
- fputs(" <rule name=\"", pfile->fp);
- xml_file_put_escape_str(pfile->fp, rule->name);
- fprintf(pfile->fp, "\" timing=\"%s\"",
- rule->timing == FLT_TIMING_ON_RECEIVE ? "receive" :
- rule->timing == FLT_TIMING_MANUAL ? "manual" : "any");
- fprintf(pfile->fp, " enabled=\"%s\">\n",
- rule->enabled ? "true" : "false");
-
- fprintf(pfile->fp, " <condition-list bool=\"%s\">\n",
- rule->bool_op == FLT_OR ? "or" : "and");
-
- for (cur_cond = rule->cond_list; cur_cond != NULL;
- cur_cond = cur_cond->next) {
- FilterCond *cond = (FilterCond *)cur_cond->data;
- XMLNode *node = NULL;
-
- switch (cond->match_type) {
- case FLT_CONTAIN:
- strcpy(match_type,
- FLT_IS_NOT_MATCH(cond->match_flag)
- ? "not-contain" : "contains");
- break;
- case FLT_EQUAL:
- strcpy(match_type,
- FLT_IS_NOT_MATCH(cond->match_flag)
- ? "is-not" : "is");
- break;
- case FLT_REGEX:
- strcpy(match_type,
- FLT_IS_NOT_MATCH(cond->match_flag)
- ? "not-regex" : "regex");
- break;
- default:
- match_type[0] = '\0';
- break;
- }
-
- switch (cond->type) {
- case FLT_COND_HEADER:
- NODE_NEW("match-header", cond->str_value);
- ADD_ATTR("type", match_type);
- ADD_ATTR("name", cond->header_name);
- break;
- case FLT_COND_ANY_HEADER:
- NODE_NEW("match-any-header", cond->str_value);
- ADD_ATTR("type", match_type);
- break;
- case FLT_COND_TO_OR_CC:
- NODE_NEW("match-to-or-cc", cond->str_value);
- ADD_ATTR("type", match_type);
- break;
- case FLT_COND_BODY:
- NODE_NEW("match-body-text", cond->str_value);
- ADD_ATTR("type", match_type);
- break;
- case FLT_COND_CMD_TEST:
- NODE_NEW("command-test", cond->str_value);
- break;
- case FLT_COND_SIZE_GREATER:
- NODE_NEW("size", itos(cond->int_value));
- ADD_ATTR("type",
- FLT_IS_NOT_MATCH(cond->match_flag)
- ? "lt" : "gt");
- break;
- case FLT_COND_AGE_GREATER:
- NODE_NEW("age", itos(cond->int_value));
- ADD_ATTR("type",
- FLT_IS_NOT_MATCH(cond->match_flag)
- ? "lt" : "gt");
- break;
- case FLT_COND_ACCOUNT:
- NODE_NEW("account-id", itos(cond->int_value));
- break;
- default:
- break;
- }
-
- if (node) {
- fputs(" ", pfile->fp);
- xml_file_put_node(pfile->fp, node);
- xml_free_node(node);
- }
- }
-
- fputs(" </condition-list>\n", pfile->fp);
-
- fputs(" <action-list>\n", pfile->fp);
-
- for (cur_action = rule->action_list; cur_action != NULL;
- cur_action = cur_action->next) {
- FilterAction *action = (FilterAction *)cur_action->data;
- XMLNode *node = NULL;
-
- switch (action->type) {
- case FLT_ACTION_MOVE:
- NODE_NEW("move", action->str_value);
- break;
- case FLT_ACTION_COPY:
- NODE_NEW("copy", action->str_value);
- break;
- case FLT_ACTION_NOT_RECEIVE:
- NODE_NEW("not-receive", NULL);
- break;
- case FLT_ACTION_DELETE:
- NODE_NEW("delete", NULL);
- break;
- case FLT_ACTION_EXEC:
- NODE_NEW("exec", action->str_value);
- break;
- case FLT_ACTION_EXEC_ASYNC:
- NODE_NEW("exec-async", action->str_value);
- break;
- case FLT_ACTION_MARK:
- NODE_NEW("mark", NULL);
- break;
- case FLT_ACTION_COLOR_LABEL:
- NODE_NEW("color-label", action->str_value);
- break;
- case FLT_ACTION_MARK_READ:
- NODE_NEW("mark-as-read", NULL);
- break;
- case FLT_ACTION_FORWARD:
- NODE_NEW("forward", action->str_value);
- break;
- case FLT_ACTION_FORWARD_AS_ATTACHMENT:
- NODE_NEW("forward-as-attachment",
- action->str_value);
- break;
- case FLT_ACTION_REDIRECT:
- NODE_NEW("redirect", action->str_value);
- break;
- case FLT_ACTION_STOP_EVAL:
- NODE_NEW("stop-eval", NULL);
- break;
- default:
- break;
- }
-
- if (node) {
- fputs(" ", pfile->fp);
- xml_file_put_node(pfile->fp, node);
- xml_free_node(node);
- }
- }
-
- fputs(" </action-list>\n", pfile->fp);
-
- fputs(" </rule>\n", pfile->fp);
- }
-
- fputs("</filter>\n", pfile->fp);
-
- g_free(rcpath);
-
- if (prefs_file_close(pfile) < 0) {
- g_warning(_("failed to write configuration to file\n"));
- return;
- }
-}
-
-#undef NODE_NEW
-#undef ADD_ATTR
-
-gchar *filter_get_str(FilterRule *rule)
-{
- gchar *str;
- FilterCond *cond1, *cond2;
- FilterAction *action = NULL;
- GSList *cur;
- gint flag1 = 0, flag2 = 0;
-
- cond1 = (FilterCond *)rule->cond_list->data;
- if (rule->cond_list->next)
- cond2 = (FilterCond *)rule->cond_list->next->data;
- else
- cond2 = NULL;
-
- /* new -> old flag conversion */
- switch (cond1->match_type) {
- case FLT_CONTAIN:
- case FLT_EQUAL:
- flag1 = FLT_IS_NOT_MATCH(cond1->match_flag) ? 0 : FLT_O_CONTAIN;
- if (FLT_IS_CASE_SENS(cond1->match_flag))
- flag1 |= FLT_O_CASE_SENS;
- break;
- case FLT_REGEX:
- flag1 = FLT_O_REGEX; break;
- default:
- break;
- }
- if (cond2) {
- switch (cond2->match_type) {
- case FLT_CONTAIN:
- case FLT_EQUAL:
- flag2 = FLT_IS_NOT_MATCH(cond2->match_flag) ? 0 : FLT_O_CONTAIN;
- if (FLT_IS_CASE_SENS(cond2->match_flag))
- flag2 |= FLT_O_CASE_SENS;
- break;
- case FLT_REGEX:
- flag2 = FLT_O_REGEX; break;
- default:
- break;
- }
- } else
- flag2 = FLT_O_CONTAIN;
-
- for (cur = rule->action_list; cur != NULL; cur = cur->next) {
- action = (FilterAction *)cur->data;
- if (action->type == FLT_ACTION_MOVE ||
- action->type == FLT_ACTION_NOT_RECEIVE ||
- action->type == FLT_ACTION_DELETE)
- break;
- }
-
- str = g_strdup_printf
- ("%s:%s:%c:%s:%s:%s:%d:%d:%c",
- cond1->header_name, cond1->str_value ? cond1->str_value : "",
- (cond2 && cond2->header_name) ?
- (rule->bool_op == FLT_AND ? '&' : '|') : ' ',
- (cond2 && cond2->header_name) ? cond2->header_name : "",
- (cond2 && cond2->str_value) ? cond2->str_value : "",
- (action && action->str_value) ? action->str_value : "",
- flag1, flag2,
- (action && action->type == FLT_ACTION_MOVE) ? 'm' :
- (action && action->type == FLT_ACTION_NOT_RECEIVE) ? 'n' :
- (action && action->type == FLT_ACTION_DELETE) ? 'd' : ' ');
-
- return str;
-}
-
-#define PARSE_ONE_PARAM(p, srcp) \
-{ \
- p = strchr(srcp, '\t'); \
- if (!p) return NULL; \
- else \
- *p++ = '\0'; \
-}
-
-FilterRule *filter_read_str(const gchar *str)
-{
- FilterRule *rule;
- FilterBoolOp bool_op;
- gint flag;
- FilterCond *cond;
- FilterMatchType match_type;
- FilterMatchFlag match_flag;
- FilterAction *action;
- GSList *cond_list = NULL;
- GSList *action_list = NULL;
- gchar *tmp;
- gchar *rule_name;
- gchar *name1, *body1, *op, *name2, *body2, *dest;
- gchar *flag1 = NULL, *flag2 = NULL, *action1 = NULL;
-
- Xstrdup_a(tmp, str, return NULL);
-
- name1 = tmp;
- PARSE_ONE_PARAM(body1, name1);
- PARSE_ONE_PARAM(op, body1);
- PARSE_ONE_PARAM(name2, op);
- PARSE_ONE_PARAM(body2, name2);
- PARSE_ONE_PARAM(dest, body2);
- if (strchr(dest, '\t')) {
- gchar *p;
-
- PARSE_ONE_PARAM(flag1, dest);
- PARSE_ONE_PARAM(flag2, flag1);
- PARSE_ONE_PARAM(action1, flag2);
- if ((p = strchr(action1, '\t'))) *p = '\0';
- }
-
- bool_op = (*op == '&') ? FLT_AND : FLT_OR;
-
- if (*name1) {
- if (flag1)
- flag = (FilterOldFlag)strtoul(flag1, NULL, 10);
- else
- flag = FLT_O_CONTAIN;
- match_type = FLT_CONTAIN;
- match_flag = 0;
- if (flag & FLT_O_REGEX)
- match_type = FLT_REGEX;
- else if (!(flag & FLT_O_CONTAIN))
- match_flag = FLT_NOT_MATCH;
- if (flag & FLT_O_CASE_SENS)
- match_flag |= FLT_CASE_SENS;
- cond = filter_cond_new(FLT_COND_HEADER, match_type, match_flag,
- name1, body1);
- cond_list = g_slist_append(cond_list, cond);
- }
- if (*name2) {
- if (flag2)
- flag = (FilterOldFlag)strtoul(flag2, NULL, 10);
- else
- flag = FLT_O_CONTAIN;
- match_type = FLT_CONTAIN;
- match_flag = 0;
- if (flag & FLT_O_REGEX)
- match_type = FLT_REGEX;
- else if (!(flag & FLT_O_CONTAIN))
- match_flag = FLT_NOT_MATCH;
- if (flag & FLT_O_CASE_SENS)
- match_flag |= FLT_CASE_SENS;
- cond = filter_cond_new(FLT_COND_HEADER, match_type, match_flag,
- name2, body2);
- cond_list = g_slist_append(cond_list, cond);
- }
-
- action = filter_action_new(FLT_ACTION_MOVE,
- *dest ? g_strdup(dest) : NULL);
- if (action1) {
- switch (*action1) {
- case 'm': action->type = FLT_ACTION_MOVE; break;
- case 'n': action->type = FLT_ACTION_NOT_RECEIVE; break;
- case 'd': action->type = FLT_ACTION_DELETE; break;
- default: g_warning("Invalid action: `%c'\n", *action1);
- }
- }
- action_list = g_slist_append(action_list, action);
-
- Xstrdup_a(rule_name, str, return NULL);
- subst_char(rule_name, '\t', ':');
-
- rule = filter_rule_new(rule_name, bool_op, cond_list, action_list);
-
- return rule;
-}
-
-FilterRule *filter_rule_new(const gchar *name, FilterBoolOp bool_op,
- GSList *cond_list, GSList *action_list)
-{
- FilterRule *rule;
-
- rule = g_new0(FilterRule, 1);
- rule->name = g_strdup(name);
- rule->bool_op = bool_op;
- rule->cond_list = cond_list;
- rule->action_list = action_list;
- rule->timing = FLT_TIMING_ANY;
- rule->enabled = TRUE;
-
- return rule;
-}
-
-FilterCond *filter_cond_new(FilterCondType type,
- FilterMatchType match_type,
- FilterMatchFlag match_flag,
- const gchar *header, const gchar *value)
-{
- FilterCond *cond;
-
- cond = g_new0(FilterCond, 1);
- cond->type = type;
- cond->match_type = match_type;
- cond->match_flag = match_flag;
-
- if (type == FLT_COND_HEADER)
- cond->header_name =
- (header && *header) ? g_strdup(header) : NULL;
- else
- cond->header_name = NULL;
-
- cond->str_value = (value && *value) ? g_strdup(value) : NULL;
- if (type == FLT_COND_SIZE_GREATER || type == FLT_COND_AGE_GREATER)
- cond->int_value = atoi(value);
- else
- cond->int_value = 0;
-
- if (match_type == FLT_REGEX)
- cond->match_func = strmatch_regex;
- else if (match_type == FLT_EQUAL) {
- if (FLT_IS_CASE_SENS(match_flag))
- cond->match_func = str_find_equal;
- else
- cond->match_func = str_case_find_equal;
- } else {
- if (FLT_IS_CASE_SENS(match_flag))
- cond->match_func = str_find;
- else
- cond->match_func = str_case_find;
- }
-
- return cond;
-}
-
-FilterAction *filter_action_new(FilterActionType type, const gchar *str)
-{
- FilterAction *action;
-
- action = g_new0(FilterAction, 1);
- action->type = type;
-
- action->str_value = (str && *str) ? g_strdup(str) : NULL;
- if (type == FLT_ACTION_COLOR_LABEL && str)
- action->int_value = atoi(str);
- else
- action->int_value = 0;
-
- return action;
-}
-
-FilterInfo *filter_info_new(void)
-{
- FilterInfo *fltinfo;
-
- fltinfo = g_new0(FilterInfo, 1);
- fltinfo->dest_list = NULL;
- fltinfo->move_dest = NULL;
- fltinfo->drop_done = FALSE;
-
- return fltinfo;
-}
-
-void filter_rule_rename_dest_path(FilterRule *rule, const gchar *old_path,
- const gchar *new_path)
-{
- FilterAction *action;
- GSList *cur;
- gchar *base;
- gchar *dest_path;
- gint oldpathlen;
-
- oldpathlen = strlen(old_path);
-
- for (cur = rule->action_list; cur != NULL; cur = cur->next) {
- action = (FilterAction *)cur->data;
-
- if (action->type != FLT_ACTION_MOVE &&
- action->type != FLT_ACTION_COPY)
- continue;
-
- if (action->str_value &&
- !strncmp(old_path, action->str_value, oldpathlen)) {
- base = action->str_value + oldpathlen;
- if (*base != G_DIR_SEPARATOR && *base != '\0')
- continue;
- while (*base == G_DIR_SEPARATOR) base++;
- if (*base == '\0')
- dest_path = g_strdup(new_path);
- else
- dest_path = g_strconcat(new_path,
- G_DIR_SEPARATOR_S,
- base, NULL);
- debug_print("filter_rule_rename_dest_path(): "
- "renaming %s -> %s\n",
- action->str_value, dest_path);
- g_free(action->str_value);
- action->str_value = dest_path;
- }
- }
-}
-
-void filter_rule_delete_action_by_dest_path(FilterRule *rule, const gchar *path)
-{
- FilterAction *action;
- GSList *cur;
- GSList *next;
- gint pathlen;
-
- pathlen = strlen(path);
-
- for (cur = rule->action_list; cur != NULL; cur = next) {
- action = (FilterAction *)cur->data;
- next = cur->next;
-
- if (action->type != FLT_ACTION_MOVE &&
- action->type != FLT_ACTION_COPY)
- continue;
-
- if (action->str_value &&
- !strncmp(path, action->str_value, pathlen) &&
- (action->str_value[pathlen] == G_DIR_SEPARATOR ||
- action->str_value[pathlen] == '\0')) {
- debug_print("filter_rule_delete_action_by_dest_path(): "
- "deleting %s\n", action->str_value);
- rule->action_list = g_slist_remove
- (rule->action_list, action);
- filter_action_free(action);
- }
- }
-}
-
-void filter_list_rename_path(const gchar *old_path, const gchar *new_path)
-{
- GSList *cur;
-
- g_return_if_fail(old_path != NULL);
- g_return_if_fail(new_path != NULL);
-
- for (cur = prefs_common.fltlist; cur != NULL; cur = cur->next) {
- FilterRule *rule = (FilterRule *)cur->data;
- filter_rule_rename_dest_path(rule, old_path, new_path);
- }
-
- filter_write_config();
-}
-
-void filter_list_delete_path(const gchar *path)
-{
- GSList *cur;
- GSList *next;
-
- g_return_if_fail(path != NULL);
-
- for (cur = prefs_common.fltlist; cur != NULL; cur = next) {
- FilterRule *rule = (FilterRule *)cur->data;
- next = cur->next;
-
- filter_rule_delete_action_by_dest_path(rule, path);
- if (!rule->action_list) {
- prefs_common.fltlist =
- g_slist_remove(prefs_common.fltlist, rule);
- filter_rule_free(rule);
- }
- }
-
- filter_write_config();
-}
-
-void filter_rule_match_type_str_to_enum(const gchar *match_type,
- FilterMatchType *type,
- FilterMatchFlag *flag)
-{
- g_return_if_fail(match_type != NULL);
-
- *type = FLT_CONTAIN;
- *flag = 0;
-
- if (!strcmp(match_type, "contains")) {
- *type = FLT_CONTAIN;
- } else if (!strcmp(match_type, "not-contain")) {
- *type = FLT_CONTAIN;
- *flag = FLT_NOT_MATCH;
- } else if (!strcmp(match_type, "is")) {
- *type = FLT_EQUAL;
- } else if (!strcmp(match_type, "is-not")) {
- *type = FLT_EQUAL;
- *flag = FLT_NOT_MATCH;
- } else if (!strcmp(match_type, "regex")) {
- *type = FLT_REGEX;
- } else if (!strcmp(match_type, "not-regex")) {
- *type = FLT_REGEX;
- *flag = FLT_NOT_MATCH;
- } else if (!strcmp(match_type, "gt")) {
- } else if (!strcmp(match_type, "lt")) {
- *flag = FLT_NOT_MATCH;
- }
-}
-
-void filter_get_keyword_from_msg(MsgInfo *msginfo, gchar **header, gchar **key,
- FilterCreateType type)
-{
- static HeaderEntry hentry[] = {{"List-Id:", NULL, TRUE},
- {"X-ML-Name:", NULL, TRUE},
- {"X-List:", NULL, TRUE},
- {"X-Mailing-list:", NULL, TRUE},
- {"X-Sequence:", NULL, TRUE},
- {NULL, NULL, FALSE}};
- enum
- {
- H_LIST_ID = 0,
- H_X_ML_NAME = 1,
- H_X_LIST = 2,
- H_X_MAILING_LIST = 3,
- H_X_SEQUENCE = 4
- };
-
- FILE *fp;
-
- g_return_if_fail(msginfo != NULL);
- g_return_if_fail(header != NULL);
- g_return_if_fail(key != NULL);
-
- *header = NULL;
- *key = NULL;
-
- switch (type) {
- case FLT_BY_NONE:
- return;
- case FLT_BY_AUTO:
- if ((fp = procmsg_open_message(msginfo)) == NULL)
- return;
- procheader_get_header_fields(fp, hentry);
- fclose(fp);
-
-#define SET_FILTER_KEY(hstr, idx) \
-{ \
- *header = g_strdup(hstr); \
- *key = hentry[idx].body; \
- hentry[idx].body = NULL; \
-}
-
- if (hentry[H_LIST_ID].body != NULL) {
- SET_FILTER_KEY("List-Id", H_LIST_ID);
- extract_list_id_str(*key);
- } else if (hentry[H_X_ML_NAME].body != NULL) {
- SET_FILTER_KEY("X-ML-Name", H_X_ML_NAME);
- } else if (hentry[H_X_LIST].body != NULL) {
- SET_FILTER_KEY("X-List", H_X_LIST);
- } else if (hentry[H_X_MAILING_LIST].body != NULL) {
- SET_FILTER_KEY("X-Mailing-list", H_X_MAILING_LIST);
- } else if (hentry[H_X_SEQUENCE].body != NULL) {
- gchar *p;
-
- SET_FILTER_KEY("X-Sequence", H_X_SEQUENCE);
- p = *key;
- while (*p != '\0') {
- while (*p != '\0' && !g_ascii_isspace(*p)) p++;
- while (g_ascii_isspace(*p)) p++;
- if (g_ascii_isdigit(*p)) {
- *p = '\0';
- break;
- }
- }
- g_strstrip(*key);
- } else if (msginfo->subject) {
- *header = g_strdup("Subject");
- *key = g_strdup(msginfo->subject);
- }
-
-#undef SET_FILTER_KEY
-
- g_free(hentry[H_LIST_ID].body);
- hentry[H_LIST_ID].body = NULL;
- g_free(hentry[H_X_ML_NAME].body);
- hentry[H_X_ML_NAME].body = NULL;
- g_free(hentry[H_X_LIST].body);
- hentry[H_X_LIST].body = NULL;
- g_free(hentry[H_X_MAILING_LIST].body);
- hentry[H_X_MAILING_LIST].body = NULL;
-
- break;
- case FLT_BY_FROM:
- *header = g_strdup("From");
- *key = g_strdup(msginfo->from);
- break;
- case FLT_BY_TO:
- *header = g_strdup("To");
- *key = g_strdup(msginfo->to);
- break;
- case FLT_BY_SUBJECT:
- *header = g_strdup("Subject");
- *key = g_strdup(msginfo->subject);
- break;
- default:
- break;
- }
-}
-
-void filter_rule_list_free(GSList *fltlist)
-{
- GSList *cur;
-
- for (cur = fltlist; cur != NULL; cur = cur->next)
- filter_rule_free((FilterRule *)cur->data);
- g_slist_free(fltlist);
-}
-
-void filter_rule_free(FilterRule *rule)
-{
- if (!rule) return;
-
- g_free(rule->name);
-
- filter_cond_list_free(rule->cond_list);
- filter_action_list_free(rule->action_list);
-
- g_free(rule);
-}
-
-void filter_cond_list_free(GSList *cond_list)
-{
- GSList *cur;
-
- for (cur = cond_list; cur != NULL; cur = cur->next)
- filter_cond_free((FilterCond *)cur->data);
- g_slist_free(cond_list);
-}
-
-void filter_action_list_free(GSList *action_list)
-{
- GSList *cur;
-
- for (cur = action_list; cur != NULL; cur = cur->next)
- filter_action_free((FilterAction *)cur->data);
- g_slist_free(action_list);
-}
-
-static void filter_cond_free(FilterCond *cond)
-{
- g_free(cond->header_name);
- g_free(cond->str_value);
- g_free(cond);
-}
-
-static void filter_action_free(FilterAction *action)
-{
- g_free(action->str_value);
- g_free(action);
-}
-
-void filter_info_free(FilterInfo *fltinfo)
-{
- g_slist_free(fltinfo->dest_list);
- g_free(fltinfo);
-}
diff --git a/src/filter.h b/src/filter.h
deleted file mode 100644
index dc38047e..00000000
--- a/src/filter.h
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __FILTER_H__
-#define __FILTER_H__
-
-#include <glib.h>
-
-#include "folder.h"
-#include "procmsg.h"
-#include "utils.h"
-
-typedef struct _FilterCond FilterCond;
-typedef struct _FilterAction FilterAction;
-typedef struct _FilterRule FilterRule;
-typedef struct _FilterInfo FilterInfo;
-
-typedef enum
-{
- FLT_TIMING_ANY,
- FLT_TIMING_ON_RECEIVE,
- FLT_TIMING_MANUAL
-} FilterTiming;
-
-typedef enum
-{
- FLT_COND_HEADER,
- FLT_COND_ANY_HEADER,
- FLT_COND_TO_OR_CC,
- FLT_COND_BODY,
- FLT_COND_CMD_TEST,
- FLT_COND_SIZE_GREATER,
- FLT_COND_AGE_GREATER,
- FLT_COND_ACCOUNT
-} FilterCondType;
-
-typedef enum
-{
- FLT_CONTAIN,
- FLT_EQUAL,
- FLT_REGEX
-} FilterMatchType;
-
-typedef enum
-{
- FLT_NOT_MATCH = 1 << 0,
- FLT_CASE_SENS = 1 << 1
-} FilterMatchFlag;
-
-typedef enum
-{
- FLT_OR,
- FLT_AND
-} FilterBoolOp;
-
-typedef enum
-{
- FLT_ACTION_MOVE,
- FLT_ACTION_COPY,
- FLT_ACTION_NOT_RECEIVE,
- FLT_ACTION_DELETE,
- FLT_ACTION_EXEC,
- FLT_ACTION_EXEC_ASYNC,
- FLT_ACTION_MARK,
- FLT_ACTION_COLOR_LABEL,
- FLT_ACTION_MARK_READ,
- FLT_ACTION_FORWARD,
- FLT_ACTION_FORWARD_AS_ATTACHMENT,
- FLT_ACTION_REDIRECT,
- FLT_ACTION_STOP_EVAL,
- FLT_ACTION_NONE
-} FilterActionType;
-
-typedef enum
-{
- FLT_BY_NONE,
- FLT_BY_AUTO,
- FLT_BY_FROM,
- FLT_BY_TO,
- FLT_BY_SUBJECT
-} FilterCreateType;
-
-#define FLT_IS_NOT_MATCH(flag) ((flag & FLT_NOT_MATCH) != 0)
-#define FLT_IS_CASE_SENS(flag) ((flag & FLT_CASE_SENS) != 0)
-
-struct _FilterCond
-{
- FilterCondType type;
-
- gchar *header_name;
-
- gchar *str_value;
- gint int_value;
-
- FilterMatchType match_type;
- FilterMatchFlag match_flag;
-
- StrFindFunc match_func;
-};
-
-struct _FilterAction
-{
- FilterActionType type;
-
- gchar *str_value;
- gint int_value;
-};
-
-struct _FilterRule
-{
- gchar *name;
-
- FilterBoolOp bool_op;
-
- GSList *cond_list;
- GSList *action_list;
-
- FilterTiming timing;
- gboolean enabled;
-};
-
-struct _FilterInfo
-{
- PrefsAccount *account;
- MsgFlags flags;
-
- gboolean actions[FLT_ACTION_NONE];
- GSList *dest_list;
- FolderItem *move_dest;
- gboolean drop_done;
-};
-
-gint filter_apply (GSList *fltlist,
- const gchar *file,
- FilterInfo *fltinfo);
-gint filter_apply_msginfo (GSList *fltlist,
- MsgInfo *msginfo,
- FilterInfo *fltinfo);
-
-gint filter_action_exec (FilterRule *rule,
- MsgInfo *msginfo,
- const gchar *file,
- FilterInfo *fltinfo);
-
-gboolean filter_match_rule (FilterRule *rule,
- MsgInfo *msginfo,
- GSList *hlist,
- FilterInfo *fltinfo);
-
-/* read / write config */
-GSList *filter_xml_node_to_filter_list (GNode *node);
-void filter_read_config (void);
-void filter_write_config (void);
-
-/* for old filterrc */
-gchar *filter_get_str (FilterRule *rule);
-FilterRule *filter_read_str (const gchar *str);
-
-FilterRule *filter_rule_new (const gchar *name,
- FilterBoolOp bool_op,
- GSList *cond_list,
- GSList *action_list);
-FilterCond *filter_cond_new (FilterCondType type,
- FilterMatchType match_type,
- FilterMatchFlag match_flag,
- const gchar *header,
- const gchar *body);
-FilterAction *filter_action_new (FilterActionType type,
- const gchar *str);
-FilterInfo *filter_info_new (void);
-
-void filter_rule_rename_dest_path (FilterRule *rule,
- const gchar *old_path,
- const gchar *new_path);
-void filter_rule_delete_action_by_dest_path
- (FilterRule *rule,
- const gchar *path);
-
-void filter_list_rename_path (const gchar *old_path,
- const gchar *new_path);
-void filter_list_delete_path (const gchar *path);
-
-void filter_rule_match_type_str_to_enum (const gchar *type_str,
- FilterMatchType *type,
- FilterMatchFlag *flag);
-
-void filter_get_keyword_from_msg (MsgInfo *msginfo,
- gchar **header,
- gchar **key,
- FilterCreateType type);
-
-void filter_rule_list_free (GSList *fltlist);
-void filter_rule_free (FilterRule *rule);
-void filter_cond_list_free (GSList *cond_list);
-void filter_action_list_free (GSList *action_list);
-void filter_info_free (FilterInfo *info);
-
-#endif /* __FILTER_H__ */
diff --git a/src/folder.c b/src/folder.c
deleted file mode 100644
index 25db6b24..00000000
--- a/src/folder.c
+++ /dev/null
@@ -1,1583 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "folder.h"
-#include "session.h"
-#include "imap.h"
-#include "news.h"
-#include "mh.h"
-#include "utils.h"
-#include "xml.h"
-#include "codeconv.h"
-#include "prefs.h"
-#include "account.h"
-#include "prefs_account.h"
-
-static GList *folder_list = NULL;
-
-static void folder_init (Folder *folder,
- const gchar *name);
-
-static gboolean folder_read_folder_func (GNode *node,
- gpointer data);
-static gchar *folder_get_list_path (void);
-static void folder_write_list_recursive (GNode *node,
- gpointer data);
-
-
-Folder *folder_new(FolderType type, const gchar *name, const gchar *path)
-{
- Folder *folder = NULL;
-
- name = name ? name : path;
- switch (type) {
- case F_MH:
- folder = mh_get_class()->folder_new(name, path);
- break;
- case F_IMAP:
- folder = imap_get_class()->folder_new(name, path);
- break;
- case F_NEWS:
- folder = news_get_class()->folder_new(name, path);
- break;
- default:
- return NULL;
- }
-
- return folder;
-}
-
-static void folder_init(Folder *folder, const gchar *name)
-{
- FolderItem *item;
-
- g_return_if_fail(folder != NULL);
-
- folder_set_name(folder, name);
- folder->account = NULL;
- folder->inbox = NULL;
- folder->outbox = NULL;
- folder->draft = NULL;
- folder->queue = NULL;
- folder->trash = NULL;
- folder->ui_func = NULL;
- folder->ui_func_data = NULL;
- item = folder_item_new(name, NULL);
- item->folder = folder;
- folder->node = item->node = g_node_new(item);
- folder->data = NULL;
-}
-
-void folder_local_folder_init(Folder *folder, const gchar *name,
- const gchar *path)
-{
- folder_init(folder, name);
- LOCAL_FOLDER(folder)->rootpath = g_strdup(path);
-}
-
-void folder_remote_folder_init(Folder *folder, const gchar *name,
- const gchar *path)
-{
- folder_init(folder, name);
- REMOTE_FOLDER(folder)->session = NULL;
-}
-
-void folder_destroy(Folder *folder)
-{
- g_return_if_fail(folder != NULL);
- g_return_if_fail(folder->klass->destroy != NULL);
-
- folder->klass->destroy(folder);
-
- folder_list = g_list_remove(folder_list, folder);
-
- folder_tree_destroy(folder);
- g_free(folder->name);
- g_free(folder);
-}
-
-void folder_local_folder_destroy(LocalFolder *lfolder)
-{
- g_return_if_fail(lfolder != NULL);
-
- g_free(lfolder->rootpath);
-}
-
-void folder_remote_folder_destroy(RemoteFolder *rfolder)
-{
- g_return_if_fail(rfolder != NULL);
-
- if (rfolder->session)
- session_destroy(rfolder->session);
-}
-
-#if 0
-Folder *mbox_folder_new(const gchar *name, const gchar *path)
-{
- /* not yet implemented */
- return NULL;
-}
-
-Folder *maildir_folder_new(const gchar *name, const gchar *path)
-{
- /* not yet implemented */
- return NULL;
-}
-#endif
-
-FolderItem *folder_item_new(const gchar *name, const gchar *path)
-{
- FolderItem *item;
-
- item = g_new0(FolderItem, 1);
-
- item->stype = F_NORMAL;
- item->name = g_strdup(name);
- item->path = g_strdup(path);
- item->mtime = 0;
- item->new = 0;
- item->unread = 0;
- item->total = 0;
- item->unmarked_num = 0;
- item->last_num = -1;
- item->no_sub = FALSE;
- item->no_select = FALSE;
- item->collapsed = FALSE;
- item->threaded = TRUE;
- item->opened = FALSE;
- item->updated = FALSE;
- item->cache_dirty = FALSE;
- item->mark_dirty = FALSE;
- item->node = NULL;
- item->parent = NULL;
- item->folder = NULL;
- item->account = NULL;
- item->ac_apply_sub = FALSE;
- item->auto_to = NULL;
- item->use_auto_to_on_reply = FALSE;
- item->auto_cc = NULL;
- item->auto_bcc = NULL;
- item->auto_replyto = NULL;
- item->mark_queue = NULL;
- item->data = NULL;
-
- return item;
-}
-
-void folder_item_append(FolderItem *parent, FolderItem *item)
-{
- g_return_if_fail(parent != NULL);
- g_return_if_fail(parent->folder != NULL);
- g_return_if_fail(parent->node != NULL);
- g_return_if_fail(item != NULL);
-
- item->parent = parent;
- item->folder = parent->folder;
- item->node = g_node_append_data(parent->node, item);
-}
-
-static gboolean folder_item_remove_func(GNode *node, gpointer data)
-{
- FolderItem *item = FOLDER_ITEM(node->data);
-
- folder_item_destroy(item);
- return FALSE;
-}
-
-void folder_item_remove(FolderItem *item)
-{
- GNode *node;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
- g_return_if_fail(item->node != NULL);
-
- node = item->node;
-
- if (item->folder->node == node)
- item->folder->node = NULL;
-
- g_node_traverse(node, G_POST_ORDER, G_TRAVERSE_ALL, -1,
- folder_item_remove_func, NULL);
- g_node_destroy(node);
-}
-
-void folder_item_remove_children(FolderItem *item)
-{
- GNode *node, *next;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
- g_return_if_fail(item->node != NULL);
-
- node = item->node->children;
- while (node != NULL) {
- next = node->next;
- folder_item_remove(FOLDER_ITEM(node->data));
- node = next;
- }
-}
-
-void folder_item_destroy(FolderItem *item)
-{
- Folder *folder;
-
- g_return_if_fail(item != NULL);
-
- folder = item->folder;
- if (folder) {
- if (folder->inbox == item)
- folder->inbox = NULL;
- else if (folder->outbox == item)
- folder->outbox = NULL;
- else if (folder->draft == item)
- folder->draft = NULL;
- else if (folder->queue == item)
- folder->queue = NULL;
- else if (folder->trash == item)
- folder->trash = NULL;
- }
-
- g_free(item->name);
- g_free(item->path);
- g_free(item->auto_to);
- g_free(item->auto_cc);
- g_free(item->auto_bcc);
- g_free(item->auto_replyto);
- g_free(item);
-}
-
-gint folder_item_compare(FolderItem *item_a, FolderItem *item_b)
-{
- gint ret;
- gchar *str_a, *str_b;
-
- if (!item_a || !item_b)
- return 0;
- if (!item_a->parent || !item_b->parent)
- return 0;
- if (!item_a->name || !item_b->name)
- return 0;
-
- /* if both a and b are special folders, sort them according to
- * their types (which is in-order). Note that this assumes that
- * there are no multiple folders of a special type. */
- if (item_a->stype != F_NORMAL && item_b->stype != F_NORMAL)
- return item_a->stype - item_b->stype;
-
- /* if b is normal folder, and a is not, b is smaller (ends up
- * lower in the list) */
- if (item_a->stype != F_NORMAL && item_b->stype == F_NORMAL)
- return item_b->stype - item_a->stype;
-
- /* if b is special folder, and a is not, b is larger (ends up
- * higher in the list) */
- if (item_a->stype == F_NORMAL && item_b->stype != F_NORMAL)
- return item_b->stype - item_a->stype;
-
- /* otherwise just compare the folder names */
- str_a = g_utf8_casefold(item_a->name, -1);
- str_b = g_utf8_casefold(item_b->name, -1);
- ret = g_utf8_collate(str_a, str_b);
- g_free(str_b);
- g_free(str_a);
-
- return ret;
-}
-
-void folder_set_ui_func(Folder *folder, FolderUIFunc func, gpointer data)
-{
- g_return_if_fail(folder != NULL);
-
- folder->ui_func = func;
- folder->ui_func_data = data;
-}
-
-void folder_set_name(Folder *folder, const gchar *name)
-{
- g_return_if_fail(folder != NULL);
-
- g_free(folder->name);
- folder->name = name ? g_strdup(name) : NULL;
- if (folder->node && folder->node->data) {
- FolderItem *item = (FolderItem *)folder->node->data;
-
- g_free(item->name);
- item->name = name ? g_strdup(name) : NULL;
- }
-}
-
-void folder_tree_destroy(Folder *folder)
-{
- g_return_if_fail(folder != NULL);
-
- if (folder->node)
- folder_item_remove(FOLDER_ITEM(folder->node->data));
-}
-
-void folder_add(Folder *folder)
-{
- Folder *cur_folder;
- GList *cur;
- gint i;
-
- g_return_if_fail(folder != NULL);
-
- for (i = 0, cur = folder_list; cur != NULL; cur = cur->next, i++) {
- cur_folder = FOLDER(cur->data);
- if (FOLDER_TYPE(folder) == F_MH) {
- if (FOLDER_TYPE(cur_folder) != F_MH) break;
- } else if (FOLDER_TYPE(folder) == F_IMAP) {
- if (FOLDER_TYPE(cur_folder) != F_MH &&
- FOLDER_TYPE(cur_folder) != F_IMAP) break;
- } else if (FOLDER_TYPE(folder) == F_NEWS) {
- if (FOLDER_TYPE(cur_folder) != F_MH &&
- FOLDER_TYPE(cur_folder) != F_IMAP &&
- FOLDER_TYPE(cur_folder) != F_NEWS) break;
- }
- }
-
- folder_list = g_list_insert(folder_list, folder, i);
-}
-
-GList *folder_get_list(void)
-{
- return folder_list;
-}
-
-gint folder_read_list(void)
-{
- GNode *node;
- XMLNode *xmlnode;
- gchar *path;
-
- path = folder_get_list_path();
- if (!is_file_exist(path)) return -1;
- node = xml_parse_file(path);
- if (!node) return -1;
-
- xmlnode = node->data;
- if (strcmp2(xmlnode->tag->tag, "folderlist") != 0) {
- g_warning("wrong folder list\n");
- xml_free_tree(node);
- return -1;
- }
-
- g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, 2,
- folder_read_folder_func, NULL);
-
- xml_free_tree(node);
- if (folder_list)
- return 0;
- else
- return -1;
-}
-
-void folder_write_list(void)
-{
- GList *list;
- Folder *folder;
- gchar *path;
- PrefFile *pfile;
-
- path = folder_get_list_path();
- if ((pfile = prefs_file_open(path)) == NULL) return;
-
- fprintf(pfile->fp, "<?xml version=\"1.0\" encoding=\"%s\"?>\n",
- CS_INTERNAL);
- fputs("\n<folderlist>\n", pfile->fp);
-
- for (list = folder_list; list != NULL; list = list->next) {
- folder = list->data;
- folder_write_list_recursive(folder->node, pfile->fp);
- }
-
- fputs("</folderlist>\n", pfile->fp);
-
- if (prefs_file_close(pfile) < 0)
- g_warning("failed to write folder list.\n");
-}
-
-struct TotalMsgStatus
-{
- guint new;
- guint unread;
- guint total;
- GString *str;
-};
-
-static gboolean folder_get_status_full_all_func(GNode *node, gpointer data)
-{
- FolderItem *item;
- struct TotalMsgStatus *status = (struct TotalMsgStatus *)data;
- gchar *id;
-
- g_return_val_if_fail(node->data != NULL, FALSE);
-
- item = FOLDER_ITEM(node->data);
-
- if (!item->path) return FALSE;
-
- status->new += item->new;
- status->unread += item->unread;
- status->total += item->total;
-
- if (status->str) {
- id = folder_item_get_identifier(item);
- g_string_sprintfa(status->str, "%5d %5d %5d %s\n",
- item->new, item->unread,
- item->total, id);
- g_free(id);
- }
-
- return FALSE;
-}
-
-static void folder_get_status_full_all(GString *str, guint *new, guint *unread,
- guint *total)
-{
- GList *list;
- Folder *folder;
- struct TotalMsgStatus status;
-
- status.new = status.unread = status.total = 0;
- status.str = str;
-
- debug_print("Counting total number of messages...\n");
-
- for (list = folder_list; list != NULL; list = list->next) {
- folder = FOLDER(list->data);
- if (folder->node)
- g_node_traverse(folder->node, G_PRE_ORDER,
- G_TRAVERSE_ALL, -1,
- folder_get_status_full_all_func,
- &status);
- }
-
- *new = status.new;
- *unread = status.unread;
- *total = status.total;
-}
-
-gchar *folder_get_status(GPtrArray *folders, gboolean full)
-{
- guint new, unread, total;
- GString *str;
- gint i;
- gchar *ret;
-
- new = unread = total = 0;
-
- str = g_string_new(NULL);
-
- if (folders) {
- for (i = 0; i < folders->len; i++) {
- FolderItem *item;
-
- item = g_ptr_array_index(folders, i);
- new += item->new;
- unread += item->unread;
- total += item->total;
-
- if (full) {
- gchar *id;
-
- id = folder_item_get_identifier(item);
- g_string_sprintfa(str, "%5d %5d %5d %s\n",
- item->new, item->unread,
- item->total, id);
- g_free(id);
- }
- }
- } else {
- folder_get_status_full_all(full ? str : NULL,
- &new, &unread, &total);
- }
-
- if (full)
- g_string_sprintfa(str, "%5d %5d %5d\n", new, unread, total);
- else
- g_string_sprintfa(str, "%d %d %d\n", new, unread, total);
-
- ret = str->str;
- g_string_free(str, FALSE);
-
- return ret;
-}
-
-Folder *folder_find_from_path(const gchar *path)
-{
- GList *list;
- Folder *folder;
-
- for (list = folder_list; list != NULL; list = list->next) {
- folder = list->data;
- if (FOLDER_TYPE(folder) == F_MH &&
- !path_cmp(LOCAL_FOLDER(folder)->rootpath, path))
- return folder;
- }
-
- return NULL;
-}
-
-Folder *folder_find_from_name(const gchar *name, FolderType type)
-{
- GList *list;
- Folder *folder;
-
- for (list = folder_list; list != NULL; list = list->next) {
- folder = list->data;
- if (FOLDER_TYPE(folder) == type &&
- strcmp2(name, folder->name) == 0)
- return folder;
- }
-
- return NULL;
-}
-
-static gboolean folder_item_find_func(GNode *node, gpointer data)
-{
- FolderItem *item = node->data;
- gpointer *d = data;
- const gchar *path = d[0];
-
- if (path_cmp(path, item->path) != 0)
- return FALSE;
-
- d[1] = item;
-
- return TRUE;
-}
-
-FolderItem *folder_find_item_from_path(const gchar *path)
-{
- Folder *folder;
- gpointer d[2];
-
- folder = folder_get_default_folder();
- g_return_val_if_fail(folder != NULL, NULL);
-
- d[0] = (gpointer)path;
- d[1] = NULL;
- g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
- folder_item_find_func, d);
- return d[1];
-}
-
-FolderItem *folder_find_child_item_by_name(FolderItem *item, const gchar *name)
-{
- GNode *node;
- FolderItem *child;
-
- for (node = item->node->children; node != NULL; node = node->next) {
- child = FOLDER_ITEM(node->data);
- if (strcmp2(g_basename(child->path), name) == 0)
- return child;
- }
-
- return NULL;
-}
-
-static const struct {
- gchar *str;
- FolderType type;
-} type_str_table[] = {
- {"#mh" , F_MH},
- {"#mbox" , F_MBOX},
- {"#maildir", F_MAILDIR},
- {"#imap" , F_IMAP},
- {"#news" , F_NEWS}
-};
-
-static gchar *folder_get_type_string(FolderType type)
-{
- gint i;
-
- for (i = 0; i < sizeof(type_str_table) / sizeof(type_str_table[0]);
- i++) {
- if (type_str_table[i].type == type)
- return type_str_table[i].str;
- }
-
- return NULL;
-}
-
-static FolderType folder_get_type_from_string(const gchar *str)
-{
- gint i;
-
- for (i = 0; i < sizeof(type_str_table) / sizeof(type_str_table[0]);
- i++) {
- if (g_ascii_strcasecmp(type_str_table[i].str, str) == 0)
- return type_str_table[i].type;
- }
-
- return F_UNKNOWN;
-}
-
-gchar *folder_get_identifier(Folder *folder)
-{
- gchar *type_str;
-
- g_return_val_if_fail(folder != NULL, NULL);
-
- type_str = folder_get_type_string(FOLDER_TYPE(folder));
- return g_strconcat(type_str, "/", folder->name, NULL);
-}
-
-gchar *folder_item_get_identifier(FolderItem *item)
-{
- gchar *id;
- gchar *folder_id;
-
- g_return_val_if_fail(item != NULL, NULL);
-
- if (!item->path) {
- if (!item->parent)
- return folder_get_identifier(item->folder);
- else
- return NULL;
- }
-
- folder_id = folder_get_identifier(item->folder);
- id = g_strconcat(folder_id, "/", item->path, NULL);
-#ifdef G_OS_WIN32
- subst_char(id, G_DIR_SEPARATOR, '/');
-#endif
- g_free(folder_id);
-
- return id;
-}
-
-FolderItem *folder_find_item_from_identifier(const gchar *identifier)
-{
- Folder *folder;
- gpointer d[2];
- gchar *str;
- gchar *p;
- gchar *name;
- gchar *path;
- FolderType type;
-
- g_return_val_if_fail(identifier != NULL, NULL);
-
- if (*identifier != '#')
- return folder_find_item_from_path(identifier);
-
- Xstrdup_a(str, identifier, return NULL);
-
- p = strchr(str, '/');
- if (!p)
- return folder_find_item_from_path(identifier);
- *p = '\0';
- p++;
- type = folder_get_type_from_string(str);
- if (type == F_UNKNOWN)
- return folder_find_item_from_path(identifier);
-
- name = p;
- p = strchr(p, '/');
- if (!p)
- return folder_find_item_from_path(identifier);
- *p = '\0';
- p++;
-
- folder = folder_find_from_name(name, type);
- if (!folder)
- return folder_find_item_from_path(identifier);
-
- path = p;
-
- d[0] = (gpointer)path;
- d[1] = NULL;
- g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
- folder_item_find_func, d);
- return d[1];
-}
-
-Folder *folder_get_default_folder(void)
-{
- return folder_list ? FOLDER(folder_list->data) : NULL;
-}
-
-FolderItem *folder_get_default_inbox(void)
-{
- Folder *folder;
-
- if (!folder_list) return NULL;
- folder = FOLDER(folder_list->data);
- g_return_val_if_fail(folder != NULL, NULL);
- return folder->inbox;
-}
-
-FolderItem *folder_get_default_outbox(void)
-{
- Folder *folder;
-
- if (!folder_list) return NULL;
- folder = FOLDER(folder_list->data);
- g_return_val_if_fail(folder != NULL, NULL);
- return folder->outbox;
-}
-
-FolderItem *folder_get_default_draft(void)
-{
- Folder *folder;
-
- if (!folder_list) return NULL;
- folder = FOLDER(folder_list->data);
- g_return_val_if_fail(folder != NULL, NULL);
- return folder->draft;
-}
-
-FolderItem *folder_get_default_queue(void)
-{
- Folder *folder;
-
- if (!folder_list) return NULL;
- folder = FOLDER(folder_list->data);
- g_return_val_if_fail(folder != NULL, NULL);
- return folder->queue;
-}
-
-FolderItem *folder_get_default_trash(void)
-{
- Folder *folder;
-
- if (!folder_list) return NULL;
- folder = FOLDER(folder_list->data);
- g_return_val_if_fail(folder != NULL, NULL);
- return folder->trash;
-}
-
-#define CREATE_FOLDER_IF_NOT_EXIST(member, dir, type) \
-{ \
- if (!folder->member) { \
- item = folder_item_new(dir, dir); \
- item->stype = type; \
- folder_item_append(rootitem, item); \
- folder->member = item; \
- } \
-}
-
-void folder_set_missing_folders(void)
-{
- Folder *folder;
- FolderItem *rootitem;
- FolderItem *item;
- GList *list;
-
- for (list = folder_list; list != NULL; list = list->next) {
- folder = list->data;
- if (FOLDER_TYPE(folder) != F_MH) continue;
- rootitem = FOLDER_ITEM(folder->node->data);
- g_return_if_fail(rootitem != NULL);
-
- if (folder->inbox && folder->outbox && folder->draft &&
- folder->queue && folder->trash)
- continue;
-
- if (folder->klass->create_tree(folder) < 0) {
- g_warning("%s: can't create the folder tree.\n",
- LOCAL_FOLDER(folder)->rootpath);
- continue;
- }
-
- CREATE_FOLDER_IF_NOT_EXIST(inbox, INBOX_DIR, F_INBOX);
- CREATE_FOLDER_IF_NOT_EXIST(outbox, OUTBOX_DIR, F_OUTBOX);
- CREATE_FOLDER_IF_NOT_EXIST(draft, DRAFT_DIR, F_DRAFT);
- CREATE_FOLDER_IF_NOT_EXIST(queue, QUEUE_DIR, F_QUEUE);
- CREATE_FOLDER_IF_NOT_EXIST(trash, TRASH_DIR, F_TRASH);
- }
-}
-
-static gboolean folder_unref_account_func(GNode *node, gpointer data)
-{
- FolderItem *item = node->data;
- PrefsAccount *account = data;
-
- if (item->account == account)
- item->account = NULL;
-
- return FALSE;
-}
-
-void folder_unref_account_all(PrefsAccount *account)
-{
- Folder *folder;
- GList *list;
-
- if (!account) return;
-
- for (list = folder_list; list != NULL; list = list->next) {
- folder = list->data;
- if (folder->account == account)
- folder->account = NULL;
- g_node_traverse(folder->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
- folder_unref_account_func, account);
- }
-}
-
-#undef CREATE_FOLDER_IF_NOT_EXIST
-
-gchar *folder_get_path(Folder *folder)
-{
- gchar *path;
-
- g_return_val_if_fail(folder != NULL, NULL);
-
- if (FOLDER_TYPE(folder) == F_MH) {
- path = g_filename_from_utf8(LOCAL_FOLDER(folder)->rootpath,
- -1, NULL, NULL, NULL);
- if (!path) {
- g_warning("folder_get_path: faild to convert character set\n");
- path = g_strdup(LOCAL_FOLDER(folder)->rootpath);
- }
- } else if (FOLDER_TYPE(folder) == F_IMAP) {
- g_return_val_if_fail(folder->account != NULL, NULL);
- path = g_strconcat(get_imap_cache_dir(),
- G_DIR_SEPARATOR_S,
- folder->account->recv_server,
- G_DIR_SEPARATOR_S,
- folder->account->userid,
- NULL);
- } else if (FOLDER_TYPE(folder) == F_NEWS) {
- g_return_val_if_fail(folder->account != NULL, NULL);
- path = g_strconcat(get_news_cache_dir(),
- G_DIR_SEPARATOR_S,
- folder->account->nntp_server,
- NULL);
- } else
- path = NULL;
-
- return path;
-}
-
-gchar *folder_item_get_path(FolderItem *item)
-{
- gchar *folder_path;
- gchar *item_path = NULL, *path;
-
- g_return_val_if_fail(item != NULL, NULL);
-
- folder_path = folder_get_path(item->folder);
- g_return_val_if_fail(folder_path != NULL, NULL);
-
- if (item->path) {
- item_path = g_filename_from_utf8(item->path, -1,
- NULL, NULL, NULL);
- if (!item_path) {
- g_warning("folder_item_get_path: faild to convert character set\n");
- item_path = g_strdup(item->path);
- }
-#ifdef G_OS_WIN32
- subst_char(item_path, '/', G_DIR_SEPARATOR);
-#endif
- }
-
- if (g_path_is_absolute(folder_path)) {
- if (item_path)
- path = g_strconcat(folder_path, G_DIR_SEPARATOR_S,
- item_path, NULL);
- else
- path = g_strdup(folder_path);
- } else {
- if (item_path)
- path = g_strconcat(get_mail_base_dir(),
- G_DIR_SEPARATOR_S, folder_path,
- G_DIR_SEPARATOR_S, item_path, NULL);
- else
- path = g_strconcat(get_mail_base_dir(),
- G_DIR_SEPARATOR_S, folder_path,
- NULL);
- }
-
- g_free(item_path);
- g_free(folder_path);
- return path;
-}
-
-gint folder_item_scan(FolderItem *item)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, -1);
-
- folder = item->folder;
- return folder->klass->scan(folder, item);
-}
-
-static void folder_item_scan_foreach_func(gpointer key, gpointer val,
- gpointer data)
-{
- folder_item_scan(FOLDER_ITEM(key));
-}
-
-void folder_item_scan_foreach(GHashTable *table)
-{
- g_hash_table_foreach(table, folder_item_scan_foreach_func, NULL);
-}
-
-GSList *folder_item_get_msg_list(FolderItem *item, gboolean use_cache)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, NULL);
-
- folder = item->folder;
- return folder->klass->get_msg_list(folder, item, use_cache);
-}
-
-gchar *folder_item_fetch_msg(FolderItem *item, gint num)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, NULL);
-
- folder = item->folder;
-
- return folder->klass->fetch_msg(folder, item, num);
-}
-
-gint folder_item_fetch_all_msg(FolderItem *item)
-{
- Folder *folder;
- GSList *mlist;
- GSList *cur;
- gint num = 0;
- gint ret = 0;
-
- g_return_val_if_fail(item != NULL, -1);
-
- debug_print("fetching all messages in %s ...\n", item->path);
-
- folder = item->folder;
-
- if (folder->ui_func)
- folder->ui_func(folder, item, folder->ui_func_data ?
- folder->ui_func_data : GINT_TO_POINTER(num));
-
- mlist = folder_item_get_msg_list(item, TRUE);
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- MsgInfo *msginfo = (MsgInfo *)cur->data;
- gchar *msg;
-
- num++;
- if (folder->ui_func)
- folder->ui_func(folder, item,
- folder->ui_func_data ?
- folder->ui_func_data :
- GINT_TO_POINTER(num));
-
- msg = folder_item_fetch_msg(item, msginfo->msgnum);
- if (!msg) {
- g_warning("Can't fetch message %d. Aborting.\n",
- msginfo->msgnum);
- ret = -1;
- break;
- }
- g_free(msg);
- }
-
- procmsg_msg_list_free(mlist);
-
- return ret;
-}
-
-MsgInfo *folder_item_get_msginfo(FolderItem *item, gint num)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, NULL);
-
- folder = item->folder;
-
- return folder->klass->get_msginfo(folder, item, num);
-}
-
-gint folder_item_add_msg(FolderItem *dest, const gchar *file, MsgFlags *flags,
- gboolean remove_source)
-{
- Folder *folder;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(file != NULL, -1);
- g_return_val_if_fail(dest->folder->klass->add_msg != NULL, -1);
-
- folder = dest->folder;
-
- return folder->klass->add_msg(folder, dest, file, flags, remove_source);
-}
-
-gint folder_item_add_msgs(FolderItem *dest, GSList *file_list,
- gboolean remove_source, gint *first)
-{
- Folder *folder;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(file_list != NULL, -1);
- g_return_val_if_fail(dest->folder->klass->add_msgs != NULL, -1);
-
- folder = dest->folder;
-
- return folder->klass->add_msgs(folder, dest, file_list, remove_source,
- first);
-}
-
-gint folder_item_move_msg(FolderItem *dest, MsgInfo *msginfo)
-{
- Folder *folder;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msginfo != NULL, -1);
- g_return_val_if_fail(dest->folder->klass->move_msg != NULL, -1);
-
- folder = dest->folder;
-
- return folder->klass->move_msg(folder, dest, msginfo);
-}
-
-gint folder_item_move_msgs(FolderItem *dest, GSList *msglist)
-{
- Folder *folder;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
- g_return_val_if_fail(dest->folder->klass->move_msgs != NULL, -1);
-
- folder = dest->folder;
-
- return folder->klass->move_msgs(folder, dest, msglist);
-}
-
-gint folder_item_copy_msg(FolderItem *dest, MsgInfo *msginfo)
-{
- Folder *folder;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msginfo != NULL, -1);
- g_return_val_if_fail(dest->folder->klass->copy_msg != NULL, -1);
-
- folder = dest->folder;
-
- return folder->klass->copy_msg(folder, dest, msginfo);
-}
-
-gint folder_item_copy_msgs(FolderItem *dest, GSList *msglist)
-{
- Folder *folder;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
- g_return_val_if_fail(dest->folder->klass->copy_msgs != NULL, -1);
-
- folder = dest->folder;
-
- return folder->klass->copy_msgs(folder, dest, msglist);
-}
-
-gint folder_item_remove_msg(FolderItem *item, MsgInfo *msginfo)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(item->folder->klass->remove_msg != NULL, -1);
-
- folder = item->folder;
-
- return folder->klass->remove_msg(folder, item, msginfo);
-}
-
-gint folder_item_remove_msgs(FolderItem *item, GSList *msglist)
-{
- Folder *folder;
- gint ret = 0;
-
- g_return_val_if_fail(item != NULL, -1);
-
- folder = item->folder;
- if (folder->klass->remove_msgs) {
- return folder->klass->remove_msgs(folder, item, msglist);
- }
-
- while (msglist != NULL) {
- MsgInfo *msginfo = (MsgInfo *)msglist->data;
-
- ret = folder_item_remove_msg(item, msginfo);
- if (ret != 0) break;
- msglist = msglist->next;
- }
-
- return ret;
-}
-
-gint folder_item_remove_all_msg(FolderItem *item)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(item->folder->klass->remove_all_msg != NULL, -1);
-
- folder = item->folder;
-
- return folder->klass->remove_all_msg(folder, item);
-}
-
-gboolean folder_item_is_msg_changed(FolderItem *item, MsgInfo *msginfo)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, FALSE);
- g_return_val_if_fail(item->folder->klass->is_msg_changed != NULL,
- FALSE);
-
- folder = item->folder;
- return folder->klass->is_msg_changed(folder, item, msginfo);
-}
-
-gint folder_item_close(FolderItem *item)
-{
- Folder *folder;
-
- g_return_val_if_fail(item != NULL, -1);
-
- item->opened = FALSE;
- folder = item->folder;
- return folder->klass->close(folder, item);
-}
-
-gchar *folder_item_get_cache_file(FolderItem *item)
-{
- gchar *path;
- gchar *file;
-
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(item->path != NULL, NULL);
-
- path = folder_item_get_path(item);
- g_return_val_if_fail(path != NULL, NULL);
- if (!is_dir_exist(path))
- make_dir_hier(path);
- file = g_strconcat(path, G_DIR_SEPARATOR_S, CACHE_FILE, NULL);
- g_free(path);
-
- return file;
-}
-
-gchar *folder_item_get_mark_file(FolderItem *item)
-{
- gchar *path;
- gchar *file;
-
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(item->path != NULL, NULL);
-
- path = folder_item_get_path(item);
- g_return_val_if_fail(path != NULL, NULL);
- if (!is_dir_exist(path))
- make_dir_hier(path);
- file = g_strconcat(path, G_DIR_SEPARATOR_S, MARK_FILE, NULL);
- g_free(path);
-
- return file;
-}
-
-static gboolean folder_build_tree(GNode *node, gpointer data)
-{
- Folder *folder = FOLDER(data);
- FolderItem *item;
- XMLNode *xmlnode;
- GList *list;
- SpecialFolderItemType stype = F_NORMAL;
- const gchar *name = NULL;
- const gchar *path = NULL;
- PrefsAccount *account = NULL;
- gboolean no_sub = FALSE, no_select = FALSE, collapsed = FALSE,
- threaded = TRUE, ac_apply_sub = FALSE;
- FolderSortKey sort_key = SORT_BY_NONE;
- FolderSortType sort_type = SORT_ASCENDING;
- gint new = 0, unread = 0, total = 0;
- time_t mtime = 0;
- gboolean use_auto_to_on_reply = FALSE;
- gchar *auto_to = NULL, *auto_cc = NULL, *auto_bcc = NULL,
- *auto_replyto = NULL;
- gboolean trim_summary_subject = FALSE, trim_compose_subject = FALSE;
-
- g_return_val_if_fail(node->data != NULL, FALSE);
- if (!node->parent) return FALSE;
-
- xmlnode = node->data;
- if (strcmp2(xmlnode->tag->tag, "folderitem") != 0) {
- g_warning("tag name != \"folderitem\"\n");
- return FALSE;
- }
-
- list = xmlnode->tag->attr;
- for (; list != NULL; list = list->next) {
- XMLAttr *attr = list->data;
-
- if (!attr || !attr->name || !attr->value) continue;
- if (!strcmp(attr->name, "type")) {
- if (!g_ascii_strcasecmp(attr->value, "normal"))
- stype = F_NORMAL;
- else if (!g_ascii_strcasecmp(attr->value, "inbox"))
- stype = F_INBOX;
- else if (!g_ascii_strcasecmp(attr->value, "outbox"))
- stype = F_OUTBOX;
- else if (!g_ascii_strcasecmp(attr->value, "draft"))
- stype = F_DRAFT;
- else if (!g_ascii_strcasecmp(attr->value, "queue"))
- stype = F_QUEUE;
- else if (!g_ascii_strcasecmp(attr->value, "trash"))
- stype = F_TRASH;
- } else if (!strcmp(attr->name, "name"))
- name = attr->value;
- else if (!strcmp(attr->name, "path"))
- path = attr->value;
- else if (!strcmp(attr->name, "mtime"))
- mtime = strtoul(attr->value, NULL, 10);
- else if (!strcmp(attr->name, "new"))
- new = atoi(attr->value);
- else if (!strcmp(attr->name, "unread"))
- unread = atoi(attr->value);
- else if (!strcmp(attr->name, "total"))
- total = atoi(attr->value);
- else if (!strcmp(attr->name, "no_sub"))
- no_sub = *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "no_select"))
- no_select = *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "collapsed"))
- collapsed = *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "threaded"))
- threaded = *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "sort_key")) {
- if (!strcmp(attr->value, "none"))
- sort_key = SORT_BY_NONE;
- else if (!strcmp(attr->value, "number"))
- sort_key = SORT_BY_NUMBER;
- else if (!strcmp(attr->value, "size"))
- sort_key = SORT_BY_SIZE;
- else if (!strcmp(attr->value, "date"))
- sort_key = SORT_BY_DATE;
- else if (!strcmp(attr->value, "from"))
- sort_key = SORT_BY_FROM;
- else if (!strcmp(attr->value, "subject"))
- sort_key = SORT_BY_SUBJECT;
- else if (!strcmp(attr->value, "score"))
- sort_key = SORT_BY_SCORE;
- else if (!strcmp(attr->value, "label"))
- sort_key = SORT_BY_LABEL;
- else if (!strcmp(attr->value, "mark"))
- sort_key = SORT_BY_MARK;
- else if (!strcmp(attr->value, "unread"))
- sort_key = SORT_BY_UNREAD;
- else if (!strcmp(attr->value, "mime"))
- sort_key = SORT_BY_MIME;
- else if (!strcmp(attr->value, "to"))
- sort_key = SORT_BY_TO;
- } else if (!strcmp(attr->name, "sort_type")) {
- if (!strcmp(attr->value, "ascending"))
- sort_type = SORT_ASCENDING;
- else
- sort_type = SORT_DESCENDING;
- } else if (!strcmp(attr->name, "account_id")) {
- account = account_find_from_id(atoi(attr->value));
- if (!account) g_warning("account_id: %s not found\n",
- attr->value);
- } else if (!strcmp(attr->name, "account_apply_sub"))
- ac_apply_sub = *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "to"))
- auto_to = g_strdup(attr->value);
- else if (!strcmp(attr->name, "use_auto_to_on_reply"))
- use_auto_to_on_reply =
- *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "cc"))
- auto_cc = g_strdup(attr->value);
- else if (!strcmp(attr->name, "bcc"))
- auto_bcc = g_strdup(attr->value);
- else if (!strcmp(attr->name, "replyto"))
- auto_replyto = g_strdup(attr->value);
- else if (!strcmp(attr->name, "trim_summary_subject")) {
- trim_summary_subject =
- *attr->value == '1' ? TRUE : FALSE;
- } else if (!strcmp(attr->name, "trim_compose_subject")) {
- trim_compose_subject =
- *attr->value = '1' ? TRUE : FALSE;
- }
- }
-
- item = folder_item_new(name, path);
- item->stype = stype;
- item->mtime = mtime;
- item->new = new;
- item->unread = unread;
- item->total = total;
- item->no_sub = no_sub;
- item->no_select = no_select;
- item->collapsed = collapsed;
- item->threaded = threaded;
- item->sort_key = sort_key;
- item->sort_type = sort_type;
- item->node = node;
- item->parent = FOLDER_ITEM(node->parent->data);
- item->folder = folder;
- switch (stype) {
- case F_INBOX: folder->inbox = item; break;
- case F_OUTBOX: folder->outbox = item; break;
- case F_DRAFT: folder->draft = item; break;
- case F_QUEUE: folder->queue = item; break;
- case F_TRASH: folder->trash = item; break;
- default: break;
- }
- item->account = account;
- item->ac_apply_sub = ac_apply_sub;
- item->auto_to = auto_to;
- item->use_auto_to_on_reply = use_auto_to_on_reply;
- item->auto_cc = auto_cc;
- item->auto_bcc = auto_bcc;
- item->auto_replyto = auto_replyto;
- item->trim_summary_subject = trim_summary_subject;
- item->trim_compose_subject = trim_compose_subject;
- node->data = item;
- xml_free_node(xmlnode);
-
- return FALSE;
-}
-
-static gboolean folder_read_folder_func(GNode *node, gpointer data)
-{
- Folder *folder;
- FolderItem *item;
- XMLNode *xmlnode;
- GList *list;
- FolderType type = F_UNKNOWN;
- const gchar *name = NULL;
- const gchar *path = NULL;
- PrefsAccount *account = NULL;
- gboolean collapsed = FALSE, threaded = TRUE, ac_apply_sub = FALSE;
-
- if (g_node_depth(node) != 2) return FALSE;
- g_return_val_if_fail(node->data != NULL, FALSE);
-
- xmlnode = node->data;
- if (strcmp2(xmlnode->tag->tag, "folder") != 0) {
- g_warning("tag name != \"folder\"\n");
- return TRUE;
- }
- g_node_unlink(node);
- list = xmlnode->tag->attr;
- for (; list != NULL; list = list->next) {
- XMLAttr *attr = list->data;
-
- if (!attr || !attr->name || !attr->value) continue;
- if (!strcmp(attr->name, "type")) {
- if (!g_ascii_strcasecmp(attr->value, "mh"))
- type = F_MH;
- else if (!g_ascii_strcasecmp(attr->value, "mbox"))
- type = F_MBOX;
- else if (!g_ascii_strcasecmp(attr->value, "maildir"))
- type = F_MAILDIR;
- else if (!g_ascii_strcasecmp(attr->value, "imap"))
- type = F_IMAP;
- else if (!g_ascii_strcasecmp(attr->value, "news"))
- type = F_NEWS;
- } else if (!strcmp(attr->name, "name"))
- name = attr->value;
- else if (!strcmp(attr->name, "path"))
- path = attr->value;
- else if (!strcmp(attr->name, "collapsed"))
- collapsed = *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "threaded"))
- threaded = *attr->value == '1' ? TRUE : FALSE;
- else if (!strcmp(attr->name, "account_id")) {
- account = account_find_from_id(atoi(attr->value));
- if (!account) g_warning("account_id: %s not found\n",
- attr->value);
- } else if (!strcmp(attr->name, "account_apply_sub"))
- ac_apply_sub = *attr->value == '1' ? TRUE : FALSE;
- }
-
- folder = folder_new(type, name, path);
- g_return_val_if_fail(folder != NULL, FALSE);
- folder->account = account;
- if (account && (type == F_IMAP || type == F_NEWS))
- account->folder = REMOTE_FOLDER(folder);
- item = FOLDER_ITEM(folder->node->data);
- node->data = item;
- item->node = node;
- g_node_destroy(folder->node);
- folder->node = node;
- folder_add(folder);
- item->collapsed = collapsed;
- item->threaded = threaded;
- item->account = account;
- item->ac_apply_sub = ac_apply_sub;
-
- g_node_traverse(node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
- folder_build_tree, folder);
-
- return FALSE;
-}
-
-static gchar *folder_get_list_path(void)
-{
- static gchar *filename = NULL;
-
- if (!filename)
- filename = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- FOLDER_LIST, NULL);
-
- return filename;
-}
-
-#define PUT_ESCAPE_STR(fp, attr, str) \
-{ \
- fputs(" " attr "=\"", fp); \
- xml_file_put_escape_str(fp, str); \
- fputs("\"", fp); \
-}
-
-static void folder_write_list_recursive(GNode *node, gpointer data)
-{
- FILE *fp = (FILE *)data;
- FolderItem *item;
- gint i, depth;
- static gchar *folder_type_str[] = {"mh", "mbox", "maildir", "imap",
- "news", "unknown"};
- static gchar *folder_item_stype_str[] = {"normal", "inbox", "outbox",
- "draft", "queue", "trash"};
- static gchar *sort_key_str[] = {"none", "number", "size", "date",
- "from", "subject", "score", "label",
- "mark", "unread", "mime", "to"};
-
- g_return_if_fail(node != NULL);
- g_return_if_fail(fp != NULL);
-
- item = FOLDER_ITEM(node->data);
- g_return_if_fail(item != NULL);
-
- depth = g_node_depth(node);
- for (i = 0; i < depth; i++)
- fputs(" ", fp);
- if (depth == 1) {
- Folder *folder = item->folder;
-
- fprintf(fp, "<folder type=\"%s\"",
- folder_type_str[FOLDER_TYPE(folder)]);
- if (folder->name)
- PUT_ESCAPE_STR(fp, "name", folder->name);
- if (FOLDER_TYPE(folder) == F_MH)
- PUT_ESCAPE_STR(fp, "path",
- LOCAL_FOLDER(folder)->rootpath);
- if (item->collapsed && node->children)
- fputs(" collapsed=\"1\"", fp);
- if (folder->account)
- fprintf(fp, " account_id=\"%d\"",
- folder->account->account_id);
- if (item->ac_apply_sub)
- fputs(" account_apply_sub=\"1\"", fp);
- } else {
- fprintf(fp, "<folderitem type=\"%s\"",
- folder_item_stype_str[item->stype]);
- if (item->name)
- PUT_ESCAPE_STR(fp, "name", item->name);
- if (item->path)
- PUT_ESCAPE_STR(fp, "path", item->path);
-
- if (item->no_sub)
- fputs(" no_sub=\"1\"", fp);
- if (item->no_select)
- fputs(" no_select=\"1\"", fp);
- if (item->collapsed && node->children)
- fputs(" collapsed=\"1\"", fp);
- if (item->threaded)
- fputs(" threaded=\"1\"", fp);
- else
- fputs(" threaded=\"0\"", fp);
-
- if (item->sort_key != SORT_BY_NONE) {
- fprintf(fp, " sort_key=\"%s\"",
- sort_key_str[item->sort_key]);
- if (item->sort_type == SORT_ASCENDING)
- fprintf(fp, " sort_type=\"ascending\"");
- else
- fprintf(fp, " sort_type=\"descending\"");
- }
-
- fprintf(fp,
- " mtime=\"%lu\" new=\"%d\" unread=\"%d\" total=\"%d\"",
- item->mtime, item->new, item->unread, item->total);
-
- if (item->account)
- fprintf(fp, " account_id=\"%d\"",
- item->account->account_id);
- if (item->ac_apply_sub)
- fputs(" account_apply_sub=\"1\"", fp);
-
- if (item->auto_to)
- PUT_ESCAPE_STR(fp, "to", item->auto_to);
- if (item->use_auto_to_on_reply)
- fputs(" use_auto_to_on_reply=\"1\"", fp);
- if (item->auto_cc)
- PUT_ESCAPE_STR(fp, "cc", item->auto_cc);
- if (item->auto_bcc)
- PUT_ESCAPE_STR(fp, "bcc", item->auto_bcc);
- if (item->auto_replyto)
- PUT_ESCAPE_STR(fp, "replyto", item->auto_replyto);
-
- if (item->trim_summary_subject)
- fputs(" trim_summary_subject=\"1\"", fp);
- if (item->trim_compose_subject)
- fputs(" trim_compose_subject=\"1\"", fp);
- }
-
- if (node->children) {
- GNode *child;
- fputs(">\n", fp);
-
- child = node->children;
- while (child) {
- GNode *cur;
-
- cur = child;
- child = cur->next;
- folder_write_list_recursive(cur, data);
- }
-
- for (i = 0; i < depth; i++)
- fputs(" ", fp);
- fprintf(fp, "</%s>\n", depth == 1 ? "folder" : "folderitem");
- } else
- fputs(" />\n", fp);
-}
-
-#undef PUT_ESCAPE_STR
diff --git a/src/folder.h b/src/folder.h
deleted file mode 100644
index 0908e241..00000000
--- a/src/folder.h
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __FOLDER_H__
-#define __FOLDER_H__
-
-#include <glib.h>
-#include <time.h>
-
-typedef struct _Folder Folder;
-typedef struct _FolderClass FolderClass;
-
-typedef struct _LocalFolder LocalFolder;
-typedef struct _RemoteFolder RemoteFolder;
-#if 0
-typedef struct _MboxFolder MboxFolder;
-typedef struct _MaildirFolder MaildirFolder;
-#endif
-
-typedef struct _FolderItem FolderItem;
-
-#define FOLDER(obj) ((Folder *)obj)
-#define FOLDER_CLASS(obj) (FOLDER(obj)->klass)
-#define FOLDER_TYPE(obj) (FOLDER(obj)->klass->type)
-
-#define LOCAL_FOLDER(obj) ((LocalFolder *)obj)
-#define REMOTE_FOLDER(obj) ((RemoteFolder *)obj)
-
-#define FOLDER_IS_LOCAL(obj) (FOLDER_TYPE(obj) == F_MH || \
- FOLDER_TYPE(obj) == F_MBOX || \
- FOLDER_TYPE(obj) == F_MAILDIR)
-
-#if 0
-#define MBOX_FOLDER(obj) ((MboxFolder *)obj)
-#define MAILDIR_FOLDER(obj) ((MaildirFolder *)obj)
-#endif
-
-#define FOLDER_ITEM(obj) ((FolderItem *)obj)
-
-#define FOLDER_ITEM_CAN_ADD(obj) \
- ((obj) && FOLDER_ITEM(obj)->folder && \
- FOLDER_ITEM(obj)->path && \
- (FOLDER_IS_LOCAL(FOLDER_ITEM(obj)->folder) || \
- FOLDER_TYPE(FOLDER_ITEM(obj)->folder) == F_IMAP) && \
- !FOLDER_ITEM(obj)->no_select)
-
-typedef enum
-{
- F_MH,
- F_MBOX,
- F_MAILDIR,
- F_IMAP,
- F_NEWS,
- F_UNKNOWN
-} FolderType;
-
-typedef enum
-{
- F_NORMAL,
- F_INBOX,
- F_OUTBOX,
- F_DRAFT,
- F_QUEUE,
- F_TRASH
-} SpecialFolderItemType;
-
-typedef enum
-{
- SORT_BY_NONE,
- SORT_BY_NUMBER,
- SORT_BY_SIZE,
- SORT_BY_DATE,
- SORT_BY_FROM,
- SORT_BY_SUBJECT,
- SORT_BY_SCORE,
- SORT_BY_LABEL,
- SORT_BY_MARK,
- SORT_BY_UNREAD,
- SORT_BY_MIME,
- SORT_BY_TO
-} FolderSortKey;
-
-typedef enum
-{
- SORT_ASCENDING,
- SORT_DESCENDING
-} FolderSortType;
-
-typedef void (*FolderUIFunc) (Folder *folder,
- FolderItem *item,
- gpointer data);
-typedef void (*FolderDestroyNotify) (Folder *folder,
- FolderItem *item,
- gpointer data);
-
-#include "prefs_account.h"
-#include "session.h"
-#include "procmsg.h"
-
-struct _Folder
-{
- FolderClass *klass;
-
- gchar *name;
- PrefsAccount *account;
-
- FolderItem *inbox;
- FolderItem *outbox;
- FolderItem *draft;
- FolderItem *queue;
- FolderItem *trash;
-
- FolderUIFunc ui_func;
- gpointer ui_func_data;
-
- GNode *node;
-
- gpointer data;
-};
-
-struct _FolderClass
-{
- FolderType type;
-
- /* virtual functions */
- Folder * (*folder_new) (const gchar *name,
- const gchar *path);
- void (*destroy) (Folder *folder);
-
- gint (*scan_tree) (Folder *folder);
- gint (*create_tree) (Folder *folder);
-
- GSList * (*get_msg_list) (Folder *folder,
- FolderItem *item,
- gboolean use_cache);
- /* return value is locale charset */
- gchar * (*fetch_msg) (Folder *folder,
- FolderItem *item,
- gint num);
- MsgInfo * (*get_msginfo) (Folder *folder,
- FolderItem *item,
- gint num);
- gint (*add_msg) (Folder *folder,
- FolderItem *dest,
- const gchar *file,
- MsgFlags *flags,
- gboolean remove_source);
- gint (*add_msgs) (Folder *folder,
- FolderItem *dest,
- GSList *file_list,
- gboolean remove_source,
- gint *first);
- gint (*move_msg) (Folder *folder,
- FolderItem *dest,
- MsgInfo *msginfo);
- gint (*move_msgs) (Folder *folder,
- FolderItem *dest,
- GSList *msglist);
- gint (*copy_msg) (Folder *folder,
- FolderItem *dest,
- MsgInfo *msginfo);
- gint (*copy_msgs) (Folder *folder,
- FolderItem *dest,
- GSList *msglist);
- gint (*remove_msg) (Folder *folder,
- FolderItem *item,
- MsgInfo *msginfo);
- gint (*remove_msgs) (Folder *folder,
- FolderItem *item,
- GSList *msglist);
- gint (*remove_all_msg) (Folder *folder,
- FolderItem *item);
- gboolean (*is_msg_changed) (Folder *folder,
- FolderItem *item,
- MsgInfo *msginfo);
- gint (*close) (Folder *folder,
- FolderItem *item);
- gint (*scan) (Folder *folder,
- FolderItem *item);
-
- FolderItem * (*create_folder) (Folder *folder,
- FolderItem *parent,
- const gchar *name);
- gint (*rename_folder) (Folder *folder,
- FolderItem *item,
- const gchar *name);
- gint (*move_folder) (Folder *folder,
- FolderItem *item,
- FolderItem *new_parent);
- gint (*remove_folder) (Folder *folder,
- FolderItem *item);
-};
-
-struct _LocalFolder
-{
- Folder folder;
-
- gchar *rootpath;
-};
-
-struct _RemoteFolder
-{
- Folder folder;
-
- Session *session;
-};
-
-#if 0
-struct _MboxFolder
-{
- LocalFolder lfolder;
-};
-
-struct _MaildirFolder
-{
- LocalFolder lfolder;
-};
-#endif
-
-struct _FolderItem
-{
- SpecialFolderItemType stype;
-
- gchar *name; /* UTF-8 */
- gchar *path; /* UTF-8 */
-
- time_t mtime;
-
- gint new;
- gint unread;
- gint total;
- gint unmarked_num;
-
- gint last_num;
-
- /* special flags */
- guint no_sub : 1; /* no child allowed? */
- guint no_select : 1; /* not selectable? */
- guint collapsed : 1; /* collapsed item */
- guint threaded : 1; /* threaded folder view */
-
- guint opened : 1; /* opened by summary view */
- guint updated : 1; /* folderview should be updated */
-
- guint cache_dirty : 1; /* cache file needs to be updated */
- guint mark_dirty : 1; /* mark file needs to be updated */
-
- FolderSortKey sort_key;
- FolderSortType sort_type;
-
- GNode *node;
-
- FolderItem *parent;
-
- Folder *folder;
-
- PrefsAccount *account;
-
- gboolean ac_apply_sub;
-
- gchar *auto_to;
- gboolean use_auto_to_on_reply;
- gchar *auto_cc;
- gchar *auto_bcc;
- gchar *auto_replyto;
-
- gboolean trim_summary_subject;
- gboolean trim_compose_subject;
-
- GSList *mark_queue;
-
- gpointer data;
-};
-
-Folder *folder_new (FolderType type,
- const gchar *name,
- const gchar *path);
-void folder_local_folder_init (Folder *folder,
- const gchar *name,
- const gchar *path);
-void folder_remote_folder_init (Folder *folder,
- const gchar *name,
- const gchar *path);
-
-void folder_destroy (Folder *folder);
-void folder_local_folder_destroy (LocalFolder *lfolder);
-void folder_remote_folder_destroy(RemoteFolder *rfolder);
-
-FolderItem *folder_item_new (const gchar *name,
- const gchar *path);
-void folder_item_append (FolderItem *parent,
- FolderItem *item);
-void folder_item_remove (FolderItem *item);
-void folder_item_remove_children (FolderItem *item);
-void folder_item_destroy (FolderItem *item);
-
-gint folder_item_compare (FolderItem *item_a,
- FolderItem *item_b);
-
-void folder_set_ui_func (Folder *folder,
- FolderUIFunc func,
- gpointer data);
-void folder_set_name (Folder *folder,
- const gchar *name);
-void folder_tree_destroy (Folder *folder);
-
-void folder_add (Folder *folder);
-
-GList *folder_get_list (void);
-gint folder_read_list (void);
-void folder_write_list (void);
-
-gchar *folder_get_status (GPtrArray *folders,
- gboolean full);
-
-Folder *folder_find_from_path (const gchar *path);
-Folder *folder_find_from_name (const gchar *name,
- FolderType type);
-FolderItem *folder_find_item_from_path (const gchar *path);
-FolderItem *folder_find_child_item_by_name (FolderItem *item,
- const gchar *name);
-gchar *folder_get_identifier (Folder *folder);
-gchar *folder_item_get_identifier (FolderItem *item);
-FolderItem *folder_find_item_from_identifier (const gchar *identifier);
-
-Folder *folder_get_default_folder (void);
-FolderItem *folder_get_default_inbox (void);
-FolderItem *folder_get_default_outbox (void);
-FolderItem *folder_get_default_draft (void);
-FolderItem *folder_get_default_queue (void);
-FolderItem *folder_get_default_trash (void);
-
-void folder_set_missing_folders (void);
-void folder_unref_account_all (PrefsAccount *account);
-
-/* return value is locale encoded file name */
-gchar *folder_get_path (Folder *folder);
-gchar *folder_item_get_path (FolderItem *item);
-
-gint folder_item_scan (FolderItem *item);
-void folder_item_scan_foreach (GHashTable *table);
-GSList *folder_item_get_msg_list (FolderItem *item,
- gboolean use_cache);
-/* return value is locale charset */
-gchar *folder_item_fetch_msg (FolderItem *item,
- gint num);
-gint folder_item_fetch_all_msg (FolderItem *item);
-MsgInfo *folder_item_get_msginfo (FolderItem *item,
- gint num);
-gint folder_item_add_msg (FolderItem *dest,
- const gchar *file,
- MsgFlags *flags,
- gboolean remove_source);
-gint folder_item_add_msgs (FolderItem *dest,
- GSList *file_list,
- gboolean remove_source,
- gint *first);
-gint folder_item_move_msg (FolderItem *dest,
- MsgInfo *msginfo);
-gint folder_item_move_msgs (FolderItem *dest,
- GSList *msglist);
-gint folder_item_copy_msg (FolderItem *dest,
- MsgInfo *msginfo);
-gint folder_item_copy_msgs (FolderItem *dest,
- GSList *msglist);
-gint folder_item_remove_msg (FolderItem *item,
- MsgInfo *msginfo);
-gint folder_item_remove_msgs (FolderItem *item,
- GSList *msglist);
-gint folder_item_remove_all_msg (FolderItem *item);
-gboolean folder_item_is_msg_changed (FolderItem *item,
- MsgInfo *msginfo);
-/* return value is locale chaset */
-gchar *folder_item_get_cache_file (FolderItem *item);
-gchar *folder_item_get_mark_file (FolderItem *item);
-
-gint folder_item_close (FolderItem *item);
-
-#endif /* __FOLDER_H__ */
diff --git a/src/imap.c b/src/imap.c
deleted file mode 100644
index a179c23c..00000000
--- a/src/imap.c
+++ /dev/null
@@ -1,4105 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <time.h>
-#if HAVE_ICONV
-# include <iconv.h>
-#endif
-
-#include "imap.h"
-#include "socket.h"
-#include "ssl.h"
-#include "recv.h"
-#include "procmsg.h"
-#include "procheader.h"
-#include "folder.h"
-#include "prefs_account.h"
-#include "codeconv.h"
-#include "md5.h"
-#include "base64.h"
-#include "utils.h"
-#include "prefs_common.h"
-
-#define IMAP4_PORT 143
-#if USE_SSL
-#define IMAPS_PORT 993
-#endif
-
-#define IMAP_CMD_LIMIT 1000
-
-#define QUOTE_IF_REQUIRED(out, str) \
-{ \
- if (*str != '"' && strpbrk(str, " \t(){}%*") != NULL) { \
- gchar *__tmp; \
- gint len; \
- \
- len = strlen(str) + 3; \
- Xalloca(__tmp, len, return IMAP_ERROR); \
- g_snprintf(__tmp, len, "\"%s\"", str); \
- out = __tmp; \
- } else { \
- Xstrdup_a(out, str, return IMAP_ERROR); \
- } \
-}
-
-static GList *session_list = NULL;
-
-static void imap_folder_init (Folder *folder,
- const gchar *name,
- const gchar *path);
-
-static Folder *imap_folder_new (const gchar *name,
- const gchar *path);
-static void imap_folder_destroy (Folder *folder);
-
-static Session *imap_session_new (PrefsAccount *account);
-static gint imap_session_connect (IMAPSession *session);
-static gint imap_session_reconnect (IMAPSession *session);
-static void imap_session_destroy (Session *session);
-/* static void imap_session_destroy_all (void); */
-
-static gint imap_search_flags (IMAPSession *session,
- GArray **uids,
- GHashTable **flags_table);
-static gint imap_fetch_flags (IMAPSession *session,
- GArray **uids,
- GHashTable **flags_table);
-
-static GSList *imap_get_msg_list (Folder *folder,
- FolderItem *item,
- gboolean use_cache);
-static gchar *imap_fetch_msg (Folder *folder,
- FolderItem *item,
- gint uid);
-static MsgInfo *imap_get_msginfo (Folder *folder,
- FolderItem *item,
- gint uid);
-static gint imap_add_msg (Folder *folder,
- FolderItem *dest,
- const gchar *file,
- MsgFlags *flags,
- gboolean remove_source);
-static gint imap_add_msgs (Folder *folder,
- FolderItem *dest,
- GSList *file_list,
- gboolean remove_source,
- gint *first);
-
-static gint imap_move_msg (Folder *folder,
- FolderItem *dest,
- MsgInfo *msginfo);
-static gint imap_move_msgs (Folder *folder,
- FolderItem *dest,
- GSList *msglist);
-static gint imap_copy_msg (Folder *folder,
- FolderItem *dest,
- MsgInfo *msginfo);
-static gint imap_copy_msgs (Folder *folder,
- FolderItem *dest,
- GSList *msglist);
-
-static gint imap_remove_msg (Folder *folder,
- FolderItem *item,
- MsgInfo *msginfo);
-static gint imap_remove_msgs (Folder *folder,
- FolderItem *item,
- GSList *msglist);
-static gint imap_remove_all_msg (Folder *folder,
- FolderItem *item);
-
-static gboolean imap_is_msg_changed (Folder *folder,
- FolderItem *item,
- MsgInfo *msginfo);
-
-static gint imap_close (Folder *folder,
- FolderItem *item);
-
-static gint imap_scan_folder (Folder *folder,
- FolderItem *item);
-static gint imap_scan_tree (Folder *folder);
-
-static gint imap_create_tree (Folder *folder);
-
-static FolderItem *imap_create_folder (Folder *folder,
- FolderItem *parent,
- const gchar *name);
-static gint imap_rename_folder (Folder *folder,
- FolderItem *item,
- const gchar *name);
-static gint imap_move_folder (Folder *folder,
- FolderItem *item,
- FolderItem *new_parent);
-static gint imap_remove_folder (Folder *folder,
- FolderItem *item);
-
-static IMAPSession *imap_session_get (Folder *folder);
-
-static gint imap_greeting (IMAPSession *session);
-static gint imap_auth (IMAPSession *session,
- const gchar *user,
- const gchar *pass,
- IMAPAuthType type);
-
-static gint imap_scan_tree_recursive (IMAPSession *session,
- FolderItem *item);
-static GSList *imap_parse_list (IMAPSession *session,
- const gchar *real_path,
- gchar *separator);
-
-static void imap_create_missing_folders (Folder *folder);
-static FolderItem *imap_create_special_folder
- (Folder *folder,
- SpecialFolderItemType stype,
- const gchar *name);
-
-static gint imap_do_copy_msgs (Folder *folder,
- FolderItem *dest,
- GSList *msglist,
- gboolean remove_source);
-static gint imap_remove_msgs_by_seq_set (Folder *folder,
- FolderItem *item,
- GSList *seq_list);
-
-static GSList *imap_get_uncached_messages (IMAPSession *session,
- FolderItem *item,
- guint32 first_uid,
- guint32 last_uid,
- gboolean update_count);
-static void imap_delete_cached_message (FolderItem *item,
- guint32 uid);
-static GSList *imap_delete_cached_messages (GSList *mlist,
- FolderItem *item,
- guint32 first_uid,
- guint32 last_uid);
-static void imap_delete_all_cached_messages (FolderItem *item);
-
-#if USE_SSL
-static SockInfo *imap_open (const gchar *server,
- gushort port,
- SSLType ssl_type);
-#else
-static SockInfo *imap_open (const gchar *server,
- gushort port);
-#endif
-
-static gint imap_msg_list_change_perm_flags (GSList *msglist,
- MsgPermFlags flags,
- gboolean is_set);
-static gchar *imap_get_flag_str (IMAPFlags flags);
-static gint imap_set_message_flags (IMAPSession *session,
- const gchar *seq_set,
- IMAPFlags flags,
- gboolean is_set);
-static gint imap_select (IMAPSession *session,
- IMAPFolder *folder,
- const gchar *path,
- gint *exists,
- gint *recent,
- gint *unseen,
- guint32 *uid_validity);
-static gint imap_status (IMAPSession *session,
- IMAPFolder *folder,
- const gchar *path,
- gint *messages,
- gint *recent,
- guint32 *uid_next,
- guint32 *uid_validity,
- gint *unseen);
-
-static void imap_parse_namespace (IMAPSession *session,
- IMAPFolder *folder);
-static void imap_get_namespace_by_list (IMAPSession *session,
- IMAPFolder *folder);
-static IMAPNameSpace *imap_find_namespace (IMAPFolder *folder,
- const gchar *path);
-static gchar imap_get_path_separator (IMAPFolder *folder,
- const gchar *path);
-static gchar *imap_get_real_path (IMAPFolder *folder,
- const gchar *path);
-
-static gchar *imap_parse_atom (IMAPSession *session,
- gchar *src,
- gchar *dest,
- gint dest_len,
- GString *str);
-static MsgFlags imap_parse_flags (const gchar *flag_str);
-static IMAPFlags imap_parse_imap_flags (const gchar *flag_str);
-static MsgInfo *imap_parse_envelope (IMAPSession *session,
- FolderItem *item,
- GString *line_str);
-
-static gboolean imap_has_capability (IMAPSession *session,
- const gchar *capability);
-static void imap_capability_free (IMAPSession *session);
-
-/* low-level IMAP4rev1 commands */
-static gint imap_cmd_capability (IMAPSession *session);
-static gint imap_cmd_authenticate
- (IMAPSession *session,
- const gchar *user,
- const gchar *pass,
- IMAPAuthType type);
-static gint imap_cmd_login (IMAPSession *session,
- const gchar *user,
- const gchar *pass);
-static gint imap_cmd_logout (IMAPSession *session);
-static gint imap_cmd_noop (IMAPSession *session);
-#if USE_SSL
-static gint imap_cmd_starttls (IMAPSession *session);
-#endif
-static gint imap_cmd_namespace (IMAPSession *session,
- gchar **ns_str);
-static gint imap_cmd_list (IMAPSession *session,
- const gchar *ref,
- const gchar *mailbox,
- GPtrArray *argbuf);
-static gint imap_cmd_do_select (IMAPSession *session,
- const gchar *folder,
- gboolean examine,
- gint *exists,
- gint *recent,
- gint *unseen,
- guint32 *uid_validity);
-static gint imap_cmd_select (IMAPSession *session,
- const gchar *folder,
- gint *exists,
- gint *recent,
- gint *unseen,
- guint32 *uid_validity);
-static gint imap_cmd_examine (IMAPSession *session,
- const gchar *folder,
- gint *exists,
- gint *recent,
- gint *unseen,
- guint32 *uid_validity);
-static gint imap_cmd_create (IMAPSession *session,
- const gchar *folder);
-static gint imap_cmd_rename (IMAPSession *session,
- const gchar *oldfolder,
- const gchar *newfolder);
-static gint imap_cmd_delete (IMAPSession *session,
- const gchar *folder);
-static gint imap_cmd_envelope (IMAPSession *session,
- const gchar *seq_set);
-static gint imap_cmd_search (IMAPSession *session,
- const gchar *criteria,
- GArray **result);
-static gint imap_cmd_fetch (IMAPSession *session,
- guint32 uid,
- const gchar *filename);
-static gint imap_cmd_append (IMAPSession *session,
- const gchar *destfolder,
- const gchar *file,
- IMAPFlags flags,
- guint32 *new_uid);
-static gint imap_cmd_copy (IMAPSession *session,
- const gchar *seq_set,
- const gchar *destfolder);
-static gint imap_cmd_store (IMAPSession *session,
- const gchar *seq_set,
- const gchar *sub_cmd);
-static gint imap_cmd_expunge (IMAPSession *session);
-static gint imap_cmd_close (IMAPSession *session);
-
-static gint imap_cmd_ok (IMAPSession *session,
- GPtrArray *argbuf);
-static void imap_cmd_gen_send (IMAPSession *session,
- const gchar *format, ...);
-static gint imap_cmd_gen_recv (IMAPSession *session,
- gchar **ret);
-
-/* misc utility functions */
-static gchar *strchr_cpy (const gchar *src,
- gchar ch,
- gchar *dest,
- gint len);
-static gchar *get_quoted (const gchar *src,
- gchar ch,
- gchar *dest,
- gint len);
-static gchar *search_array_contain_str (GPtrArray *array,
- gchar *str);
-static gchar *search_array_str (GPtrArray *array,
- gchar *str);
-static void imap_path_separator_subst (gchar *str,
- gchar separator);
-
-static gchar *imap_modified_utf7_to_utf8 (const gchar *mutf7_str);
-static gchar *imap_utf8_to_modified_utf7 (const gchar *from);
-
-static GSList *imap_get_seq_set_from_msglist (GSList *msglist);
-static void imap_seq_set_free (GSList *seq_list);
-
-static GHashTable *imap_get_uid_table (GArray *array);
-
-static gboolean imap_rename_folder_func (GNode *node,
- gpointer data);
-
-static FolderClass imap_class =
-{
- F_IMAP,
-
- imap_folder_new,
- imap_folder_destroy,
-
- imap_scan_tree,
- imap_create_tree,
-
- imap_get_msg_list,
- imap_fetch_msg,
- imap_get_msginfo,
- imap_add_msg,
- imap_add_msgs,
- imap_move_msg,
- imap_move_msgs,
- imap_copy_msg,
- imap_copy_msgs,
- imap_remove_msg,
- imap_remove_msgs,
- imap_remove_all_msg,
- imap_is_msg_changed,
- imap_close,
- imap_scan_folder,
-
- imap_create_folder,
- imap_rename_folder,
- imap_move_folder,
- imap_remove_folder
-};
-
-
-FolderClass *imap_get_class(void)
-{
- return &imap_class;
-}
-
-static Folder *imap_folder_new(const gchar *name, const gchar *path)
-{
- Folder *folder;
-
- folder = (Folder *)g_new0(IMAPFolder, 1);
- imap_folder_init(folder, name, path);
-
- return folder;
-}
-
-static void imap_folder_destroy(Folder *folder)
-{
- gchar *dir;
-
- dir = folder_get_path(folder);
- if (is_dir_exist(dir))
- remove_dir_recursive(dir);
- g_free(dir);
-
- folder_remote_folder_destroy(REMOTE_FOLDER(folder));
-}
-
-static void imap_folder_init(Folder *folder, const gchar *name,
- const gchar *path)
-{
- folder->klass = imap_get_class();
- folder_remote_folder_init(folder, name, path);
-}
-
-static IMAPSession *imap_session_get(Folder *folder)
-{
- RemoteFolder *rfolder = REMOTE_FOLDER(folder);
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, NULL);
- g_return_val_if_fail(folder->account != NULL, NULL);
-
- if (!prefs_common.online_mode)
- return NULL;
-
- if (!rfolder->session) {
- rfolder->session = imap_session_new(folder->account);
- if (rfolder->session)
- imap_parse_namespace(IMAP_SESSION(rfolder->session),
- IMAP_FOLDER(folder));
- return IMAP_SESSION(rfolder->session);
- }
-
- if (time(NULL) - rfolder->session->last_access_time <
- SESSION_TIMEOUT_INTERVAL) {
- return IMAP_SESSION(rfolder->session);
- }
-
- if (imap_cmd_noop(IMAP_SESSION(rfolder->session)) != IMAP_SUCCESS) {
- log_warning(_("IMAP4 connection to %s has been"
- " disconnected. Reconnecting...\n"),
- folder->account->recv_server);
- if (imap_session_reconnect(IMAP_SESSION(rfolder->session))
- == IMAP_SUCCESS)
- imap_parse_namespace(IMAP_SESSION(rfolder->session),
- IMAP_FOLDER(folder));
- else {
- session_destroy(rfolder->session);
- rfolder->session = NULL;
- }
- }
-
- return IMAP_SESSION(rfolder->session);
-}
-
-static gint imap_greeting(IMAPSession *session)
-{
- gchar *greeting;
- gint ok;
-
- if ((ok = imap_cmd_gen_recv(session, &greeting)) != IMAP_SUCCESS)
- return ok;
-
- if (greeting[0] != '*' || greeting[1] != ' ')
- ok = IMAP_ERROR;
- else if (!strncmp(greeting + 2, "OK", 2))
- ok = IMAP_SUCCESS;
- else if (!strncmp(greeting + 2, "PREAUTH", 7)) {
- session->authenticated = TRUE;
- ok = IMAP_SUCCESS;
- } else
- ok = IMAP_ERROR;
-
- g_free(greeting);
- return ok;
-}
-
-static gint imap_auth(IMAPSession *session, const gchar *user,
- const gchar *pass, IMAPAuthType type)
-{
- gboolean nologin;
- gint ok = IMAP_AUTHFAIL;
-
- nologin = imap_has_capability(session, "LOGINDISABLED");
-
- switch (type) {
- case 0:
- if (imap_has_capability(session, "AUTH=CRAM-MD5"))
- ok = imap_cmd_authenticate(session, user, pass, type);
- else if (nologin)
- log_print(_("IMAP4 server disables LOGIN.\n"));
- else
- ok = imap_cmd_login(session, user, pass);
- break;
- case IMAP_AUTH_LOGIN:
- if (nologin)
- log_warning(_("IMAP4 server disables LOGIN.\n"));
- else
- ok = imap_cmd_login(session, user, pass);
- break;
- case IMAP_AUTH_CRAM_MD5:
- ok = imap_cmd_authenticate(session, user, pass, type);
- break;
- default:
- break;
- }
-
- if (ok == IMAP_SUCCESS)
- session->authenticated = TRUE;
-
- return ok;
-}
-
-static Session *imap_session_new(PrefsAccount *account)
-{
- IMAPSession *session;
- gushort port;
-
- g_return_val_if_fail(account != NULL, NULL);
- g_return_val_if_fail(account->recv_server != NULL, NULL);
- g_return_val_if_fail(account->userid != NULL, NULL);
-
-#if USE_SSL
- port = account->set_imapport ? account->imapport
- : account->ssl_imap == SSL_TUNNEL ? IMAPS_PORT : IMAP4_PORT;
-#else
- port = account->set_imapport ? account->imapport : IMAP4_PORT;
-#endif
-
- session = g_new0(IMAPSession, 1);
-
- session_init(SESSION(session));
-
- SESSION(session)->type = SESSION_IMAP;
- SESSION(session)->sock = NULL;
- SESSION(session)->server = g_strdup(account->recv_server);
- SESSION(session)->port = port;
-#if USE_SSL
- SESSION(session)->ssl_type = account->ssl_imap;
-#endif
- SESSION(session)->last_access_time = time(NULL);
- SESSION(session)->data = account;
-
- SESSION(session)->destroy = imap_session_destroy;
-
- session->authenticated = FALSE;
- session->capability = NULL;
- session->uidplus = FALSE;
- session->mbox = NULL;
- session->cmd_count = 0;
-
- session_list = g_list_append(session_list, session);
-
- if (imap_session_connect(session) != IMAP_SUCCESS) {
- session_destroy(SESSION(session));
- return NULL;
- }
-
- return SESSION(session);
-}
-
-static gint imap_session_connect(IMAPSession *session)
-{
- SockInfo *sock;
- PrefsAccount *account;
- gchar *pass;
-
- g_return_val_if_fail(session != NULL, IMAP_ERROR);
-
- account = (PrefsAccount *)(SESSION(session)->data);
-
- log_message(_("creating IMAP4 connection to %s:%d ...\n"),
- SESSION(session)->server, SESSION(session)->port);
-
- pass = account->passwd;
- if (!pass) {
- gchar *tmp_pass;
- tmp_pass = input_query_password(account->recv_server,
- account->userid);
- if (!tmp_pass)
- return IMAP_ERROR;
- Xstrdup_a(pass, tmp_pass,
- {g_free(tmp_pass); return IMAP_ERROR;});
- g_free(tmp_pass);
- }
-
-#if USE_SSL
- if ((sock = imap_open(SESSION(session)->server, SESSION(session)->port,
- SESSION(session)->ssl_type)) == NULL)
-#else
- if ((sock = imap_open(SESSION(session)->server, SESSION(session)->port))
- == NULL)
-#endif
- return IMAP_ERROR;
-
- SESSION(session)->sock = sock;
-
- if (imap_greeting(session) != IMAP_SUCCESS)
- return IMAP_ERROR;
- if (imap_cmd_capability(session) != IMAP_SUCCESS)
- return IMAP_ERROR;
-
- if (imap_has_capability(session, "UIDPLUS"))
- session->uidplus = TRUE;
-
-#if USE_SSL
- if (account->ssl_imap == SSL_STARTTLS &&
- imap_has_capability(session, "STARTTLS")) {
- gint ok;
-
- ok = imap_cmd_starttls(session);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("Can't start TLS session.\n"));
- return IMAP_ERROR;
- }
- if (!ssl_init_socket_with_method(sock, SSL_METHOD_TLSv1))
- return IMAP_SOCKET;
-
- /* capability can be changed after STARTTLS */
- if (imap_cmd_capability(session) != IMAP_SUCCESS)
- return IMAP_ERROR;
- }
-#endif
-
- if (!session->authenticated &&
- imap_auth(session, account->userid, pass, account->imap_auth_type)
- != IMAP_SUCCESS) {
- imap_cmd_logout(session);
- return IMAP_AUTHFAIL;
- }
-
- return IMAP_SUCCESS;
-}
-
-static gint imap_session_reconnect(IMAPSession *session)
-{
- g_return_val_if_fail(session != NULL, IMAP_ERROR);
-
- session_disconnect(SESSION(session));
-
- imap_capability_free(session);
- session->uidplus = FALSE;
- g_free(session->mbox);
- session->mbox = NULL;
- session->authenticated = FALSE;
- SESSION(session)->state = SESSION_READY;
-
- return imap_session_connect(session);
-}
-
-static void imap_session_destroy(Session *session)
-{
- imap_capability_free(IMAP_SESSION(session));
- g_free(IMAP_SESSION(session)->mbox);
- session_list = g_list_remove(session_list, session);
-}
-
-#if 0
-static void imap_session_destroy_all(void)
-{
- while (session_list != NULL) {
- IMAPSession *session = (IMAPSession *)session_list->data;
-
- imap_cmd_logout(session);
- session_destroy(SESSION(session));
- }
-}
-#endif
-
-#define THROW goto catch
-
-static gint imap_search_flags(IMAPSession *session, GArray **uids,
- GHashTable **flags_table)
-{
- gint ok;
- gint i;
- GArray *flag_uids;
- GHashTable *unseen_table;
- GHashTable *flagged_table;
- GHashTable *answered_table;
- guint32 uid;
- IMAPFlags flags;
-
- ok = imap_cmd_search(session, "ALL", uids);
- if (ok != IMAP_SUCCESS) return ok;
-
- ok = imap_cmd_search(session, "UNSEEN", &flag_uids);
- if (ok != IMAP_SUCCESS) {
- g_array_free(*uids, TRUE);
- return ok;
- }
- unseen_table = imap_get_uid_table(flag_uids);
- g_array_free(flag_uids, TRUE);
- ok = imap_cmd_search(session, "FLAGGED", &flag_uids);
- if (ok != IMAP_SUCCESS) {
- g_hash_table_destroy(unseen_table);
- g_array_free(*uids, TRUE);
- return ok;
- }
- flagged_table = imap_get_uid_table(flag_uids);
- g_array_free(flag_uids, TRUE);
- ok = imap_cmd_search(session, "ANSWERED", &flag_uids);
- if (ok != IMAP_SUCCESS) {
- g_hash_table_destroy(flagged_table);
- g_hash_table_destroy(unseen_table);
- g_array_free(*uids, TRUE);
- return ok;
- }
- answered_table = imap_get_uid_table(flag_uids);
- g_array_free(flag_uids, TRUE);
-
- *flags_table = g_hash_table_new(NULL, g_direct_equal);
-
- for (i = 0; i < (*uids)->len; i++) {
- uid = g_array_index(*uids, guint32, i);
- flags = IMAP_FLAG_DRAFT;
- if (!g_hash_table_lookup(unseen_table, GUINT_TO_POINTER(uid)))
- flags |= IMAP_FLAG_SEEN;
- if (g_hash_table_lookup(flagged_table, GUINT_TO_POINTER(uid)))
- flags |= IMAP_FLAG_FLAGGED;
- if (g_hash_table_lookup(answered_table, GUINT_TO_POINTER(uid)))
- flags |= IMAP_FLAG_ANSWERED;
- g_hash_table_insert(*flags_table, GUINT_TO_POINTER(uid),
- GINT_TO_POINTER(flags));
- }
-
- g_hash_table_destroy(answered_table);
- g_hash_table_destroy(flagged_table);
- g_hash_table_destroy(unseen_table);
-
- return IMAP_SUCCESS;
-}
-
-static gint imap_fetch_flags(IMAPSession *session, GArray **uids,
- GHashTable **flags_table)
-{
- gint ok;
- gchar *tmp;
- gchar *cur_pos;
- gchar buf[IMAPBUFSIZE];
- guint32 uid;
- IMAPFlags flags;
-
- imap_cmd_gen_send(session, "UID FETCH 1:* (UID FLAGS)");
-
- *uids = g_array_new(FALSE, FALSE, sizeof(guint32));
- *flags_table = g_hash_table_new(NULL, g_direct_equal);
-
- while ((ok = imap_cmd_gen_recv(session, &tmp)) == IMAP_SUCCESS) {
- if (tmp[0] != '*' || tmp[1] != ' ') {
- g_free(tmp);
- break;
- }
- cur_pos = tmp + 2;
-
-#define PARSE_ONE_ELEMENT(ch) \
-{ \
- cur_pos = strchr_cpy(cur_pos, ch, buf, sizeof(buf)); \
- if (cur_pos == NULL) { \
- g_warning("cur_pos == NULL\n"); \
- g_free(tmp); \
- g_hash_table_destroy(*flags_table); \
- g_array_free(*uids, TRUE); \
- return IMAP_ERROR; \
- } \
-}
-
- PARSE_ONE_ELEMENT(' ');
- PARSE_ONE_ELEMENT(' ');
- if (strcmp(buf, "FETCH") != 0) {
- g_free(tmp);
- continue;
- }
- if (*cur_pos != '(') {
- g_free(tmp);
- continue;
- }
- cur_pos++;
- uid = 0;
- flags = 0;
-
- while (*cur_pos != '\0' && *cur_pos != ')') {
- while (*cur_pos == ' ') cur_pos++;
-
- if (!strncmp(cur_pos, "UID ", 4)) {
- cur_pos += 4;
- uid = strtoul(cur_pos, &cur_pos, 10);
- } else if (!strncmp(cur_pos, "FLAGS ", 6)) {
- cur_pos += 6;
- if (*cur_pos != '(') {
- g_warning("*cur_pos != '('\n");
- break;
- }
- cur_pos++;
- PARSE_ONE_ELEMENT(')');
- flags = imap_parse_imap_flags(buf);
- flags |= IMAP_FLAG_DRAFT;
- } else {
- g_warning("invalid FETCH response: %s\n", cur_pos);
- break;
- }
- }
-
-#undef PARSE_ONE_ELEMENT
-
- if (uid > 0) {
- g_array_append_val(*uids, uid);
- g_hash_table_insert(*flags_table, GUINT_TO_POINTER(uid),
- GINT_TO_POINTER(flags));
- }
-
- g_free(tmp);
- }
-
- if (ok != IMAP_SUCCESS) {
- g_hash_table_destroy(*flags_table);
- g_array_free(*uids, TRUE);
- }
-
- return ok;
-}
-
-static GSList *imap_get_msg_list(Folder *folder, FolderItem *item,
- gboolean use_cache)
-{
- GSList *mlist = NULL;
- IMAPSession *session;
- gint ok, exists = 0, recent = 0, unseen = 0;
- guint32 uid_validity = 0;
- guint32 first_uid = 0, last_uid = 0;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, NULL);
- g_return_val_if_fail(folder->account != NULL, NULL);
-
- item->new = item->unread = item->total = 0;
-
- session = imap_session_get(folder);
-
- if (!session) {
- mlist = procmsg_read_cache(item, FALSE);
- item->last_num = procmsg_get_last_num_in_msg_list(mlist);
- procmsg_set_flags(mlist, item);
- return mlist;
- }
-
- ok = imap_select(session, IMAP_FOLDER(folder), item->path,
- &exists, &recent, &unseen, &uid_validity);
- if (ok != IMAP_SUCCESS) THROW;
-
- if (exists == 0) {
- imap_delete_all_cached_messages(item);
- return NULL;
- }
-
- /* invalidate current cache if UIDVALIDITY has been changed */
- if (item->mtime != uid_validity) {
- debug_print("imap_get_msg_list: "
- "UIDVALIDITY has been changed.\n");
- use_cache = FALSE;
- }
-
- if (use_cache) {
- GArray *uids;
- GHashTable *msg_table;
- GHashTable *flags_table;
- guint32 cache_last;
- guint32 begin = 0;
- GSList *cur, *next = NULL;
- MsgInfo *msginfo;
- IMAPFlags imap_flags;
-
- /* get cache data */
- mlist = procmsg_read_cache(item, FALSE);
- procmsg_set_flags(mlist, item);
- cache_last = procmsg_get_last_num_in_msg_list(mlist);
-
- /* get all UID list and flags */
- ok = imap_search_flags(session, &uids, &flags_table);
- if (ok != IMAP_SUCCESS) {
- if (ok == IMAP_SOCKET || ok == IMAP_IOERR) THROW;
- ok = imap_fetch_flags(session, &uids, &flags_table);
- if (ok != IMAP_SUCCESS) THROW;
- }
-
- if (uids->len > 0) {
- first_uid = g_array_index(uids, guint32, 0);
- last_uid = g_array_index(uids, guint32, uids->len - 1);
- } else {
- g_array_free(uids, TRUE);
- g_hash_table_destroy(flags_table);
- THROW;
- }
-
- /* sync message flags with server */
- for (cur = mlist; cur != NULL; cur = next) {
- msginfo = (MsgInfo *)cur->data;
- next = cur->next;
- imap_flags = GPOINTER_TO_INT(g_hash_table_lookup
- (flags_table,
- GUINT_TO_POINTER(msginfo->msgnum)));
-
- if (imap_flags == 0) {
- debug_print("imap_get_msg_list: "
- "message %u has been deleted.\n",
- msginfo->msgnum);
- imap_delete_cached_message
- (item, msginfo->msgnum);
- if (MSG_IS_NEW(msginfo->flags))
- item->new--;
- if (MSG_IS_UNREAD(msginfo->flags))
- item->unread--;
- item->total--;
- mlist = g_slist_remove(mlist, msginfo);
- procmsg_msginfo_free(msginfo);
- item->cache_dirty = TRUE;
- item->mark_dirty = TRUE;
- continue;
- }
-
- if (!IMAP_IS_SEEN(imap_flags)) {
- if (!MSG_IS_UNREAD(msginfo->flags)) {
- item->unread++;
- MSG_SET_PERM_FLAGS(msginfo->flags,
- MSG_UNREAD);
- item->mark_dirty = TRUE;
- }
- } else {
- if (MSG_IS_NEW(msginfo->flags)) {
- item->new--;
- item->mark_dirty = TRUE;
- }
- if (MSG_IS_UNREAD(msginfo->flags)) {
- item->unread--;
- item->mark_dirty = TRUE;
- }
- MSG_UNSET_PERM_FLAGS(msginfo->flags,
- MSG_NEW|MSG_UNREAD);
- }
-
- if (IMAP_IS_FLAGGED(imap_flags)) {
- if (!MSG_IS_MARKED(msginfo->flags)) {
- MSG_SET_PERM_FLAGS(msginfo->flags,
- MSG_MARKED);
- item->mark_dirty = TRUE;
- }
- } else {
- if (MSG_IS_MARKED(msginfo->flags)) {
- MSG_UNSET_PERM_FLAGS(msginfo->flags,
- MSG_MARKED);
- item->mark_dirty = TRUE;
- }
- }
- if (IMAP_IS_ANSWERED(imap_flags)) {
- if (!MSG_IS_REPLIED(msginfo->flags)) {
- MSG_SET_PERM_FLAGS(msginfo->flags,
- MSG_REPLIED);
- item->mark_dirty = TRUE;
- }
- } else {
- if (MSG_IS_REPLIED(msginfo->flags)) {
- MSG_UNSET_PERM_FLAGS(msginfo->flags,
- MSG_REPLIED);
- item->mark_dirty = TRUE;
- }
- }
- }
-
- /* check for the first new message */
- msg_table = procmsg_msg_hash_table_create(mlist);
- if (msg_table == NULL)
- begin = first_uid;
- else {
- gint i;
-
- for (i = 0; i < uids->len; i++) {
- guint32 uid;
-
- uid = g_array_index(uids, guint32, i);
- if (g_hash_table_lookup
- (msg_table, GUINT_TO_POINTER(uid))
- == NULL) {
- debug_print("imap_get_msg_list: "
- "first new UID: %u\n", uid);
- begin = uid;
- break;
- }
- }
- g_hash_table_destroy(msg_table);
- }
-
- g_array_free(uids, TRUE);
- g_hash_table_destroy(flags_table);
-
- /* remove ununsed caches */
- if (first_uid > 0 && last_uid > 0) {
- mlist = imap_delete_cached_messages
- (mlist, item, 0, first_uid - 1);
- mlist = imap_delete_cached_messages
- (mlist, item, begin > 0 ? begin : last_uid + 1,
- UINT_MAX);
- }
-
- if (begin > 0 && begin <= last_uid) {
- GSList *newlist;
- newlist = imap_get_uncached_messages(session, item,
- begin, last_uid,
- TRUE);
- if (newlist)
- item->cache_dirty = TRUE;
- mlist = g_slist_concat(mlist, newlist);
- }
- } else {
- imap_delete_all_cached_messages(item);
- mlist = imap_get_uncached_messages(session, item, 0, 0, TRUE);
- last_uid = procmsg_get_last_num_in_msg_list(mlist);
- item->cache_dirty = TRUE;
- }
-
- item->mtime = uid_validity;
-
- mlist = procmsg_sort_msg_list(mlist, item->sort_key, item->sort_type);
-
- item->last_num = last_uid;
-
- debug_print("cache_dirty: %d, mark_dirty: %d\n",
- item->cache_dirty, item->mark_dirty);
-
-catch:
- return mlist;
-}
-
-#undef THROW
-
-static gchar *imap_fetch_msg(Folder *folder, FolderItem *item, gint uid)
-{
- gchar *path, *filename;
- IMAPSession *session;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
-
- path = folder_item_get_path(item);
- if (!is_dir_exist(path))
- make_dir_hier(path);
- filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(uid), NULL);
- g_free(path);
-
- if (is_file_exist(filename)) {
- debug_print("message %d has been already cached.\n", uid);
- return filename;
- }
-
- session = imap_session_get(folder);
- if (!session) {
- g_free(filename);
- return NULL;
- }
-
- ok = imap_select(session, IMAP_FOLDER(folder), item->path,
- NULL, NULL, NULL, NULL);
- if (ok != IMAP_SUCCESS) {
- g_warning("can't select mailbox %s\n", item->path);
- g_free(filename);
- return NULL;
- }
-
- debug_print("getting message %d...\n", uid);
- ok = imap_cmd_fetch(session, (guint32)uid, filename);
-
- if (ok != IMAP_SUCCESS) {
- g_warning("can't fetch message %d\n", uid);
- g_free(filename);
- return NULL;
- }
-
- return filename;
-}
-
-static MsgInfo *imap_get_msginfo(Folder *folder, FolderItem *item, gint uid)
-{
- IMAPSession *session;
- GSList *list;
- MsgInfo *msginfo = NULL;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
-
- session = imap_session_get(folder);
- g_return_val_if_fail(session != NULL, NULL);
-
- list = imap_get_uncached_messages(session, item, uid, uid, FALSE);
- if (list) {
- msginfo = (MsgInfo *)list->data;
- list->data = NULL;
- }
- procmsg_msg_list_free(list);
-
- return msginfo;
-}
-
-static gint imap_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
- MsgFlags *flags, gboolean remove_source)
-{
- GSList file_list;
- MsgFileInfo fileinfo;
-
- g_return_val_if_fail(file != NULL, -1);
-
- fileinfo.file = (gchar *)file;
- fileinfo.flags = flags;
- file_list.data = &fileinfo;
- file_list.next = NULL;
-
- return imap_add_msgs(folder, dest, &file_list, remove_source, NULL);
-}
-
-static gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
- gboolean remove_source, gint *first)
-{
- gchar *destdir;
- IMAPSession *session;
- gint messages, recent, unseen;
- guint32 uid_next, uid_validity;
- guint32 last_uid = 0;
- GSList *cur;
- MsgFileInfo *fileinfo;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(file_list != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- ok = imap_status(session, IMAP_FOLDER(folder), dest->path,
- &messages, &recent, &uid_next, &uid_validity, &unseen);
- if (ok != IMAP_SUCCESS) {
- g_warning("can't append messages\n");
- return -1;
- }
-
- destdir = imap_get_real_path(IMAP_FOLDER(folder), dest->path);
-
- if (!session->uidplus)
- last_uid = uid_next - 1;
- if (first)
- *first = uid_next;
-
- for (cur = file_list; cur != NULL; cur = cur->next) {
- IMAPFlags iflags = 0;
- guint32 new_uid = 0;
-
- fileinfo = (MsgFileInfo *)cur->data;
-
- if (fileinfo->flags) {
- if (MSG_IS_MARKED(*fileinfo->flags))
- iflags |= IMAP_FLAG_FLAGGED;
- if (MSG_IS_REPLIED(*fileinfo->flags))
- iflags |= IMAP_FLAG_ANSWERED;
- if (!MSG_IS_UNREAD(*fileinfo->flags))
- iflags |= IMAP_FLAG_SEEN;
- }
-
- if (dest->stype == F_OUTBOX ||
- dest->stype == F_QUEUE ||
- dest->stype == F_DRAFT ||
- dest->stype == F_TRASH)
- iflags |= IMAP_FLAG_SEEN;
-
- ok = imap_cmd_append(session, destdir, fileinfo->file, iflags,
- &new_uid);
-
- if (ok != IMAP_SUCCESS) {
- g_warning("can't append message %s\n", fileinfo->file);
- g_free(destdir);
- return -1;
- }
-
- if (!session->uidplus)
- last_uid++;
- else if (last_uid < new_uid)
- last_uid = new_uid;
-
- dest->last_num = last_uid;
- dest->total++;
- dest->updated = TRUE;
-
- if (fileinfo->flags) {
- if (MSG_IS_UNREAD(*fileinfo->flags))
- dest->unread++;
- } else
- dest->unread++;
- }
-
- g_free(destdir);
-
- if (remove_source) {
- for (cur = file_list; cur != NULL; cur = cur->next) {
- fileinfo = (MsgFileInfo *)cur->data;
- if (g_unlink(fileinfo->file) < 0)
- FILE_OP_ERROR(fileinfo->file, "unlink");
- }
- }
-
- return last_uid;
-}
-
-static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest, GSList *msglist,
- gboolean remove_source)
-{
- FolderItem *src;
- gchar *destdir;
- GSList *seq_list, *cur;
- MsgInfo *msginfo;
- IMAPSession *session;
- gint ok = IMAP_SUCCESS;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- msginfo = (MsgInfo *)msglist->data;
-
- src = msginfo->folder;
- if (src == dest) {
- g_warning("the src folder is identical to the dest.\n");
- return -1;
- }
-
- ok = imap_select(session, IMAP_FOLDER(folder), src->path,
- NULL, NULL, NULL, NULL);
- if (ok != IMAP_SUCCESS)
- return ok;
-
- destdir = imap_get_real_path(IMAP_FOLDER(folder), dest->path);
-
- seq_list = imap_get_seq_set_from_msglist(msglist);
-
- for (cur = seq_list; cur != NULL; cur = cur->next) {
- gchar *seq_set = (gchar *)cur->data;
-
- if (remove_source)
- debug_print("Moving message %s%c[%s] to %s ...\n",
- src->path, G_DIR_SEPARATOR,
- seq_set, destdir);
- else
- debug_print("Copying message %s%c[%s] to %s ...\n",
- src->path, G_DIR_SEPARATOR,
- seq_set, destdir);
-
- ok = imap_cmd_copy(session, seq_set, destdir);
- if (ok != IMAP_SUCCESS) {
- imap_seq_set_free(seq_list);
- return -1;
- }
- }
-
- dest->updated = TRUE;
-
- if (remove_source) {
- imap_remove_msgs_by_seq_set(folder, src, seq_list);
- if (ok != IMAP_SUCCESS) {
- imap_seq_set_free(seq_list);
- return ok;
- }
- }
-
- imap_seq_set_free(seq_list);
-
- for (cur = msglist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- dest->total++;
- if (MSG_IS_NEW(msginfo->flags))
- dest->new++;
- if (MSG_IS_UNREAD(msginfo->flags))
- dest->unread++;
-
- if (remove_source) {
- src->total--;
- if (MSG_IS_NEW(msginfo->flags))
- src->new--;
- if (MSG_IS_UNREAD(msginfo->flags))
- src->unread--;
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_INVALID);
- }
- }
-
- g_free(destdir);
-
- if (ok == IMAP_SUCCESS)
- return 0;
- else
- return -1;
-}
-
-static gint imap_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
-{
- GSList msglist;
-
- g_return_val_if_fail(msginfo != NULL, -1);
-
- msglist.data = msginfo;
- msglist.next = NULL;
-
- return imap_move_msgs(folder, dest, &msglist);
-}
-
-static gint imap_move_msgs(Folder *folder, FolderItem *dest, GSList *msglist)
-{
- MsgInfo *msginfo;
- GSList *file_list;
- gint ret = 0;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
-
- msginfo = (MsgInfo *)msglist->data;
- g_return_val_if_fail(msginfo->folder != NULL, -1);
-
- if (folder == msginfo->folder->folder)
- return imap_do_copy_msgs(folder, dest, msglist, TRUE);
-
- file_list = procmsg_get_message_file_list(msglist);
- g_return_val_if_fail(file_list != NULL, -1);
-
- ret = imap_add_msgs(folder, dest, file_list, FALSE, NULL);
-
- procmsg_message_file_list_free(file_list);
-
- if (ret != -1)
- ret = folder_item_remove_msgs(msginfo->folder, msglist);
-
- return ret;
-}
-
-static gint imap_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
-{
- GSList msglist;
-
- g_return_val_if_fail(msginfo != NULL, -1);
-
- msglist.data = msginfo;
- msglist.next = NULL;
-
- return imap_copy_msgs(folder, dest, &msglist);
-}
-
-static gint imap_copy_msgs(Folder *folder, FolderItem *dest, GSList *msglist)
-{
- MsgInfo *msginfo;
- GSList *file_list;
- gint ret;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
-
- msginfo = (MsgInfo *)msglist->data;
- g_return_val_if_fail(msginfo->folder != NULL, -1);
-
- if (folder == msginfo->folder->folder)
- return imap_do_copy_msgs(folder, dest, msglist, FALSE);
-
- file_list = procmsg_get_message_file_list(msglist);
- g_return_val_if_fail(file_list != NULL, -1);
-
- ret = imap_add_msgs(folder, dest, file_list, FALSE, NULL);
-
- procmsg_message_file_list_free(file_list);
-
- return ret;
-}
-
-static gint imap_remove_msgs_by_seq_set(Folder *folder, FolderItem *item,
- GSList *seq_list)
-{
- gint ok;
- IMAPSession *session;
- GSList *cur;
-
- g_return_val_if_fail(seq_list != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- for (cur = seq_list; cur != NULL; cur = cur->next) {
- gchar *seq_set = (gchar *)cur->data;
-
- ok = imap_set_message_flags(session, seq_set, IMAP_FLAG_DELETED,
- TRUE);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't set deleted flags: %s\n"),
- seq_set);
- return ok;
- }
- }
-
- ok = imap_cmd_expunge(session);
- if (ok != IMAP_SUCCESS)
- log_warning(_("can't expunge\n"));
-
- item->updated = TRUE;
-
- return ok;
-}
-
-static gint imap_remove_msg(Folder *folder, FolderItem *item, MsgInfo *msginfo)
-{
- GSList msglist;
-
- g_return_val_if_fail(msginfo != NULL, -1);
-
- msglist.data = msginfo;
- msglist.next = NULL;
-
- return imap_remove_msgs(folder, item, &msglist);
-}
-
-static gint imap_remove_msgs(Folder *folder, FolderItem *item, GSList *msglist)
-{
- gint ok;
- IMAPSession *session;
- GSList *seq_list, *cur;
- gchar *dir;
- gboolean dir_exist;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- ok = imap_select(session, IMAP_FOLDER(folder), item->path,
- NULL, NULL, NULL, NULL);
- if (ok != IMAP_SUCCESS)
- return ok;
-
- seq_list = imap_get_seq_set_from_msglist(msglist);
- ok = imap_remove_msgs_by_seq_set(folder, item, seq_list);
- imap_seq_set_free(seq_list);
- if (ok != IMAP_SUCCESS)
- return ok;
-
- dir = folder_item_get_path(item);
- dir_exist = is_dir_exist(dir);
- for (cur = msglist; cur != NULL; cur = cur->next) {
- MsgInfo *msginfo = (MsgInfo *)cur->data;
- guint32 uid = msginfo->msgnum;
-
- if (dir_exist)
- remove_numbered_files(dir, uid, uid);
- item->total--;
- if (MSG_IS_NEW(msginfo->flags))
- item->new--;
- if (MSG_IS_UNREAD(msginfo->flags))
- item->unread--;
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_INVALID);
- }
- g_free(dir);
-
- return IMAP_SUCCESS;
-}
-
-static gint imap_remove_all_msg(Folder *folder, FolderItem *item)
-{
- gint ok;
- IMAPSession *session;
- gchar *dir;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(item != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- ok = imap_select(session, IMAP_FOLDER(folder), item->path,
- NULL, NULL, NULL, NULL);
- if (ok != IMAP_SUCCESS)
- return ok;
-
- imap_cmd_gen_send(session, "STORE 1:* +FLAGS.SILENT (\\Deleted)");
- ok = imap_cmd_ok(session, NULL);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't set deleted flags: 1:*\n"));
- return ok;
- }
-
- ok = imap_cmd_expunge(session);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't expunge\n"));
- return ok;
- }
-
- item->new = item->unread = item->total = 0;
- item->updated = TRUE;
-
- dir = folder_item_get_path(item);
- if (is_dir_exist(dir))
- remove_all_numbered_files(dir);
- g_free(dir);
-
- return IMAP_SUCCESS;
-}
-
-static gboolean imap_is_msg_changed(Folder *folder, FolderItem *item,
- MsgInfo *msginfo)
-{
- /* TODO: properly implement this method */
- return FALSE;
-}
-
-static gint imap_close(Folder *folder, FolderItem *item)
-{
- gint ok;
- IMAPSession *session;
-
- g_return_val_if_fail(folder != NULL, -1);
-
- if (!item->path) return 0;
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- if (session->mbox) {
- if (strcmp2(session->mbox, item->path) != 0) return -1;
-
- ok = imap_cmd_close(session);
- if (ok != IMAP_SUCCESS)
- log_warning(_("can't close folder\n"));
-
- g_free(session->mbox);
- session->mbox = NULL;
-
- return ok;
- } else
- return 0;
-}
-
-static gint imap_scan_folder(Folder *folder, FolderItem *item)
-{
- IMAPSession *session;
- gint messages, recent, unseen;
- guint32 uid_next, uid_validity;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(item != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- ok = imap_status(session, IMAP_FOLDER(folder), item->path,
- &messages, &recent, &uid_next, &uid_validity, &unseen);
- if (ok != IMAP_SUCCESS) return -1;
-
- item->new = unseen > 0 ? recent : 0;
- item->unread = unseen;
- item->total = messages;
- item->last_num = (messages > 0 && uid_next > 0) ? uid_next - 1 : 0;
- /* item->mtime = uid_validity; */
- item->updated = TRUE;
-
- return 0;
-}
-
-static gint imap_scan_tree(Folder *folder)
-{
- FolderItem *item = NULL;
- IMAPSession *session;
- gchar *root_folder = NULL;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(folder->account != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) {
- if (!folder->node) {
- folder_tree_destroy(folder);
- item = folder_item_new(folder->name, NULL);
- item->folder = folder;
- folder->node = item->node = g_node_new(item);
- }
- return -1;
- }
-
- if (folder->account->imap_dir && *folder->account->imap_dir) {
- gchar *real_path;
- GPtrArray *argbuf;
- gint ok;
-
- Xstrdup_a(root_folder, folder->account->imap_dir, return -1);
- extract_quote(root_folder, '"');
- subst_char(root_folder,
- imap_get_path_separator(IMAP_FOLDER(folder),
- root_folder),
- '/');
- strtailchomp(root_folder, '/');
- real_path = imap_get_real_path
- (IMAP_FOLDER(folder), root_folder);
- debug_print("IMAP root directory: %s\n", real_path);
-
- /* check if root directory exist */
- argbuf = g_ptr_array_new();
- ok = imap_cmd_list(session, NULL, real_path, argbuf);
- if (ok != IMAP_SUCCESS ||
- search_array_str(argbuf, "LIST ") == NULL) {
- log_warning(_("root folder %s not exist\n"), real_path);
- g_ptr_array_free(argbuf, TRUE);
- g_free(real_path);
- return -1;
- }
- g_ptr_array_free(argbuf, TRUE);
- g_free(real_path);
- }
-
- if (folder->node)
- item = FOLDER_ITEM(folder->node->data);
- if (!item || ((item->path || root_folder) &&
- strcmp2(item->path, root_folder) != 0)) {
- folder_tree_destroy(folder);
- item = folder_item_new(folder->name, root_folder);
- item->folder = folder;
- folder->node = item->node = g_node_new(item);
- }
-
- imap_scan_tree_recursive(session, FOLDER_ITEM(folder->node->data));
- imap_create_missing_folders(folder);
-
- return 0;
-}
-
-static gint imap_scan_tree_recursive(IMAPSession *session, FolderItem *item)
-{
- Folder *folder;
- IMAPFolder *imapfolder;
- FolderItem *new_item;
- GSList *item_list, *cur;
- GNode *node;
- gchar *real_path;
- gchar *wildcard_path;
- gchar separator;
- gchar wildcard[3];
-
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(item->folder != NULL, -1);
- g_return_val_if_fail(item->no_sub == FALSE, -1);
-
- folder = item->folder;
- imapfolder = IMAP_FOLDER(folder);
-
- separator = imap_get_path_separator(imapfolder, item->path);
-
- if (folder->ui_func)
- folder->ui_func(folder, item, folder->ui_func_data);
-
- if (item->path) {
- wildcard[0] = separator;
- wildcard[1] = '%';
- wildcard[2] = '\0';
- real_path = imap_get_real_path(imapfolder, item->path);
- } else {
- wildcard[0] = '%';
- wildcard[1] = '\0';
- real_path = g_strdup("");
- }
-
- Xstrcat_a(wildcard_path, real_path, wildcard,
- {g_free(real_path); return IMAP_ERROR;});
- QUOTE_IF_REQUIRED(wildcard_path, wildcard_path);
-
- imap_cmd_gen_send(session, "LIST \"\" %s", wildcard_path);
-
- strtailchomp(real_path, separator);
- item_list = imap_parse_list(session, real_path, NULL);
- g_free(real_path);
-
- node = item->node->children;
- while (node != NULL) {
- FolderItem *old_item = FOLDER_ITEM(node->data);
- GNode *next = node->next;
-
- new_item = NULL;
-
- for (cur = item_list; cur != NULL; cur = cur->next) {
- FolderItem *cur_item = FOLDER_ITEM(cur->data);
- if (!strcmp2(old_item->path, cur_item->path)) {
- new_item = cur_item;
- break;
- }
- }
- if (!new_item) {
- debug_print("folder '%s' not found. removing...\n",
- old_item->path);
- folder_item_remove(old_item);
- } else {
- old_item->no_sub = new_item->no_sub;
- old_item->no_select = new_item->no_select;
- if (old_item->no_select == TRUE)
- old_item->new = old_item->unread =
- old_item->total = 0;
- if (old_item->no_sub == TRUE && node->children) {
- debug_print("folder '%s' doesn't have "
- "subfolders. removing...\n",
- old_item->path);
- folder_item_remove_children(old_item);
- }
- }
-
- node = next;
- }
-
- for (cur = item_list; cur != NULL; cur = cur->next) {
- FolderItem *cur_item = FOLDER_ITEM(cur->data);
- new_item = NULL;
- for (node = item->node->children; node != NULL;
- node = node->next) {
- if (!strcmp2(FOLDER_ITEM(node->data)->path,
- cur_item->path)) {
- new_item = FOLDER_ITEM(node->data);
- folder_item_destroy(cur_item);
- cur_item = NULL;
- break;
- }
- }
- if (!new_item) {
- new_item = cur_item;
- debug_print("new folder '%s' found.\n", new_item->path);
- folder_item_append(item, new_item);
- }
-
- if (!strcmp(new_item->path, "INBOX")) {
- new_item->stype = F_INBOX;
- folder->inbox = new_item;
- } else if (!item->parent || item->stype == F_INBOX) {
- const gchar *base;
-
- base = g_basename(new_item->path);
-
- if (!folder->outbox &&
- !g_ascii_strcasecmp(base, "Sent")) {
- new_item->stype = F_OUTBOX;
- folder->outbox = new_item;
- } else if (!folder->draft &&
- !g_ascii_strcasecmp(base, "Drafts")) {
- new_item->stype = F_DRAFT;
- folder->draft = new_item;
- } else if (!folder->queue &&
- !g_ascii_strcasecmp(base, "Queue")) {
- new_item->stype = F_QUEUE;
- folder->queue = new_item;
- } else if (!folder->trash &&
- !g_ascii_strcasecmp(base, "Trash")) {
- new_item->stype = F_TRASH;
- folder->trash = new_item;
- }
- }
-
-#if 0
- if (new_item->no_select == FALSE)
- imap_scan_folder(folder, new_item);
-#endif
- if (new_item->no_sub == FALSE)
- imap_scan_tree_recursive(session, new_item);
- }
-
- g_slist_free(item_list);
-
- return IMAP_SUCCESS;
-}
-
-static GSList *imap_parse_list(IMAPSession *session, const gchar *real_path,
- gchar *separator)
-{
- gchar buf[IMAPBUFSIZE];
- gchar flags[256];
- gchar separator_str[16];
- gchar *p;
- const gchar *name;
- gchar *loc_name, *loc_path;
- GSList *item_list = NULL;
- GString *str;
- FolderItem *new_item;
-
- debug_print("getting list of %s ...\n",
- *real_path ? real_path : "\"\"");
-
- str = g_string_new(NULL);
-
- for (;;) {
- if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) <= 0) {
- log_warning(_("error occurred while getting LIST.\n"));
- break;
- }
- strretchomp(buf);
- if (buf[0] != '*' || buf[1] != ' ') {
- log_print("IMAP4< %s\n", buf);
- if (sscanf(buf, "%*d %16s", buf) < 1 ||
- strcmp(buf, "OK") != 0)
- log_warning(_("error occurred while getting LIST.\n"));
-
- break;
- }
- debug_print("IMAP4< %s\n", buf);
-
- g_string_assign(str, buf);
- p = str->str + 2;
- if (strncmp(p, "LIST ", 5) != 0) continue;
- p += 5;
-
- if (*p != '(') continue;
- p++;
- p = strchr_cpy(p, ')', flags, sizeof(flags));
- if (!p) continue;
- while (*p == ' ') p++;
-
- p = strchr_cpy(p, ' ', separator_str, sizeof(separator_str));
- if (!p) continue;
- extract_quote(separator_str, '"');
- if (!strcmp(separator_str, "NIL"))
- separator_str[0] = '\0';
- if (separator)
- *separator = separator_str[0];
-
- buf[0] = '\0';
- while (*p == ' ') p++;
- if (*p == '{' || *p == '"')
- p = imap_parse_atom(session, p, buf, sizeof(buf), str);
- else
- strncpy2(buf, p, sizeof(buf));
- strtailchomp(buf, separator_str[0]);
- if (buf[0] == '\0') continue;
- if (!strcmp(buf, real_path)) continue;
-
- if (separator_str[0] != '\0')
- subst_char(buf, separator_str[0], '/');
- name = g_basename(buf);
- if (name[0] == '.') continue;
-
- loc_name = imap_modified_utf7_to_utf8(name);
- loc_path = imap_modified_utf7_to_utf8(buf);
- new_item = folder_item_new(loc_name, loc_path);
- if (strcasestr(flags, "\\Noinferiors") != NULL)
- new_item->no_sub = TRUE;
- if (strcmp(buf, "INBOX") != 0 &&
- strcasestr(flags, "\\Noselect") != NULL)
- new_item->no_select = TRUE;
-
- item_list = g_slist_append(item_list, new_item);
-
- debug_print("folder '%s' found.\n", loc_path);
- g_free(loc_path);
- g_free(loc_name);
- }
-
- g_string_free(str, TRUE);
-
- return item_list;
-}
-
-static gint imap_create_tree(Folder *folder)
-{
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(folder->node != NULL, -1);
- g_return_val_if_fail(folder->node->data != NULL, -1);
- g_return_val_if_fail(folder->account != NULL, -1);
-
- imap_scan_tree(folder);
- imap_create_missing_folders(folder);
-
- return 0;
-}
-
-static void imap_create_missing_folders(Folder *folder)
-{
- g_return_if_fail(folder != NULL);
-
- if (!folder->inbox)
- folder->inbox = imap_create_special_folder
- (folder, F_INBOX, "INBOX");
-#if 0
- if (!folder->outbox)
- folder->outbox = imap_create_special_folder
- (folder, F_OUTBOX, "Sent");
- if (!folder->draft)
- folder->draft = imap_create_special_folder
- (folder, F_DRAFT, "Drafts");
- if (!folder->queue)
- folder->queue = imap_create_special_folder
- (folder, F_QUEUE, "Queue");
-#endif
- if (!folder->trash)
- folder->trash = imap_create_special_folder
- (folder, F_TRASH, "Trash");
-}
-
-static FolderItem *imap_create_special_folder(Folder *folder,
- SpecialFolderItemType stype,
- const gchar *name)
-{
- FolderItem *item;
- FolderItem *new_item;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(folder->node != NULL, NULL);
- g_return_val_if_fail(folder->node->data != NULL, NULL);
- g_return_val_if_fail(folder->account != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- item = FOLDER_ITEM(folder->node->data);
- new_item = imap_create_folder(folder, item, name);
-
- if (!new_item) {
- g_warning(_("Can't create '%s'\n"), name);
- if (!folder->inbox) return NULL;
-
- new_item = imap_create_folder(folder, folder->inbox, name);
- if (!new_item)
- g_warning(_("Can't create '%s' under INBOX\n"), name);
- else
- new_item->stype = stype;
- } else
- new_item->stype = stype;
-
- return new_item;
-}
-
-static FolderItem *imap_create_folder(Folder *folder, FolderItem *parent,
- const gchar *name)
-{
- gchar *dirpath, *imap_path;
- IMAPSession *session;
- FolderItem *new_item;
- gchar separator;
- gchar *new_name;
- const gchar *p;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(folder->account != NULL, NULL);
- g_return_val_if_fail(parent != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- session = imap_session_get(folder);
- if (!session) return NULL;
-
- if (!parent->parent && strcmp(name, "INBOX") == 0)
- dirpath = g_strdup(name);
- else if (parent->path)
- dirpath = g_strconcat(parent->path, "/", name, NULL);
- else if ((p = strchr(name, '/')) != NULL && *(p + 1) != '\0')
- dirpath = g_strdup(name);
- else if (folder->account->imap_dir && *folder->account->imap_dir) {
- gchar *imap_dir;
-
- Xstrdup_a(imap_dir, folder->account->imap_dir, return NULL);
- strtailchomp(imap_dir, '/');
- dirpath = g_strconcat(imap_dir, "/", name, NULL);
- } else
- dirpath = g_strdup(name);
-
- /* keep trailing directory separator to create a folder that contains
- sub folder */
- imap_path = imap_utf8_to_modified_utf7(dirpath);
- strtailchomp(dirpath, '/');
- Xstrdup_a(new_name, name, {g_free(dirpath); return NULL;});
- strtailchomp(new_name, '/');
- separator = imap_get_path_separator(IMAP_FOLDER(folder), imap_path);
- imap_path_separator_subst(imap_path, separator);
- subst_char(new_name, '/', separator);
-
- if (strcmp(name, "INBOX") != 0) {
- GPtrArray *argbuf;
- gint i;
- gboolean exist = FALSE;
-
- argbuf = g_ptr_array_new();
- ok = imap_cmd_list(session, NULL, imap_path, argbuf);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't create mailbox: LIST failed\n"));
- g_free(imap_path);
- g_free(dirpath);
- g_ptr_array_free(argbuf, TRUE);
- return NULL;
- }
-
- for (i = 0; i < argbuf->len; i++) {
- gchar *str;
- str = g_ptr_array_index(argbuf, i);
- if (!strncmp(str, "LIST ", 5)) {
- exist = TRUE;
- break;
- }
- }
- g_ptr_array_free(argbuf, TRUE);
-
- if (!exist) {
- ok = imap_cmd_create(session, imap_path);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't create mailbox\n"));
- g_free(imap_path);
- g_free(dirpath);
- return NULL;
- }
- }
- }
-
- new_item = folder_item_new(new_name, dirpath);
- folder_item_append(parent, new_item);
- g_free(imap_path);
- g_free(dirpath);
-
- dirpath = folder_item_get_path(new_item);
- if (!is_dir_exist(dirpath))
- make_dir_hier(dirpath);
- g_free(dirpath);
-
- return new_item;
-}
-
-static gint imap_rename_folder_real(Folder *folder, FolderItem *item,
- FolderItem *new_parent, const gchar *name)
-{
- gchar *newpath;
- gchar *real_oldpath;
- gchar *real_newpath;
- gchar *paths[2];
- gchar *old_cache_dir;
- gchar *new_cache_dir;
- IMAPSession *session;
- gchar separator;
- gint ok;
- gint exists, recent, unseen;
- guint32 uid_validity;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(folder == item->folder, -1);
- g_return_val_if_fail(item->path != NULL, -1);
- g_return_val_if_fail(new_parent != NULL || name != NULL, -1);
- if (new_parent) {
- g_return_val_if_fail(item != new_parent, -1);
- g_return_val_if_fail(item->parent != new_parent, -1);
- g_return_val_if_fail(item->folder == new_parent->folder, -1);
- if (g_node_is_ancestor(item->node, new_parent->node)) {
- g_warning("folder to be moved is ancestor of new parent\n");
- return -1;
- }
- }
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- real_oldpath = imap_get_real_path(IMAP_FOLDER(folder), item->path);
-
- g_free(session->mbox);
- session->mbox = NULL;
- ok = imap_cmd_examine(session, "INBOX",
- &exists, &recent, &unseen, &uid_validity);
- if (ok != IMAP_SUCCESS) {
- g_free(real_oldpath);
- return -1;
- }
-
- separator = imap_get_path_separator(IMAP_FOLDER(folder), item->path);
- if (new_parent) {
- if (name) {
- newpath = g_strconcat(new_parent->path,
- G_DIR_SEPARATOR_S, name, NULL);
- } else {
- gchar *name_;
-
- name_ = g_path_get_basename(item->path);
- newpath = g_strconcat(new_parent->path,
- G_DIR_SEPARATOR_S, name_, NULL);
- AUTORELEASE_STR(name_, );
- name = name_;
- }
- } else {
- if (strchr(item->path, G_DIR_SEPARATOR)) {
- gchar *dirpath;
-
- dirpath = g_dirname(item->path);
- newpath = g_strconcat(dirpath, G_DIR_SEPARATOR_S, name,
- NULL);
- g_free(dirpath);
- } else
- newpath = g_strdup(name);
- }
-
- real_newpath = imap_utf8_to_modified_utf7(newpath);
- imap_path_separator_subst(real_newpath, separator);
-
- ok = imap_cmd_rename(session, real_oldpath, real_newpath);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't rename mailbox: %s to %s\n"),
- real_oldpath, real_newpath);
- g_free(real_oldpath);
- g_free(newpath);
- g_free(real_newpath);
- return -1;
- }
-
- if (new_parent) {
- g_node_unlink(item->node);
- g_node_append(new_parent->node, item->node);
- item->parent = new_parent;
- }
-
- g_free(item->name);
- item->name = g_strdup(name);
-
- old_cache_dir = folder_item_get_path(item);
-
- paths[0] = g_strdup(item->path);
- paths[1] = newpath;
- g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
- imap_rename_folder_func, paths);
-
- if (is_dir_exist(old_cache_dir)) {
- new_cache_dir = folder_item_get_path(item);
- if (g_rename(old_cache_dir, new_cache_dir) < 0) {
- FILE_OP_ERROR(old_cache_dir, "rename");
- }
- g_free(new_cache_dir);
- }
-
- g_free(old_cache_dir);
- g_free(paths[0]);
- g_free(newpath);
- g_free(real_oldpath);
- g_free(real_newpath);
-
- return 0;
-}
-
-static gint imap_rename_folder(Folder *folder, FolderItem *item,
- const gchar *name)
-{
- return imap_rename_folder_real(folder, item, NULL, name);
-}
-
-static gint imap_move_folder(Folder *folder, FolderItem *item,
- FolderItem *new_parent)
-{
- return imap_rename_folder_real(folder, item, new_parent, NULL);
-}
-
-static gint imap_remove_folder(Folder *folder, FolderItem *item)
-{
- gint ok;
- IMAPSession *session;
- gchar *path;
- gchar *cache_dir;
- gint exists, recent, unseen;
- guint32 uid_validity;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(item->path != NULL, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- path = imap_get_real_path(IMAP_FOLDER(folder), item->path);
-
- ok = imap_cmd_examine(session, "INBOX",
- &exists, &recent, &unseen, &uid_validity);
- if (ok != IMAP_SUCCESS) {
- g_free(path);
- return -1;
- }
-
- ok = imap_cmd_delete(session, path);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't delete mailbox\n"));
- g_free(path);
- return -1;
- }
-
- g_free(path);
- cache_dir = folder_item_get_path(item);
- if (is_dir_exist(cache_dir) && remove_dir_recursive(cache_dir) < 0)
- g_warning("can't remove directory '%s'\n", cache_dir);
- g_free(cache_dir);
- folder_item_remove(item);
-
- return 0;
-}
-
-static GSList *imap_get_uncached_messages(IMAPSession *session,
- FolderItem *item,
- guint32 first_uid, guint32 last_uid,
- gboolean update_count)
-{
- gchar *tmp;
- GSList *newlist = NULL;
- GSList *llast = NULL;
- GString *str;
- MsgInfo *msginfo;
- gchar seq_set[22];
-
- g_return_val_if_fail(session != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(item->folder != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(item->folder) == F_IMAP, NULL);
- g_return_val_if_fail(first_uid <= last_uid, NULL);
-
- if (first_uid == 0 && last_uid == 0)
- strcpy(seq_set, "1:*");
- else
- g_snprintf(seq_set, sizeof(seq_set), "%u:%u",
- first_uid, last_uid);
- if (imap_cmd_envelope(session, seq_set) != IMAP_SUCCESS) {
- log_warning(_("can't get envelope\n"));
- return NULL;
- }
-
- str = g_string_new(NULL);
-
- for (;;) {
- if (sock_getline(SESSION(session)->sock, &tmp) < 0) {
- log_warning(_("error occurred while getting envelope.\n"));
- g_string_free(str, TRUE);
- return newlist;
- }
- strretchomp(tmp);
- if (tmp[0] != '*' || tmp[1] != ' ') {
- log_print("IMAP4< %s\n", tmp);
- g_free(tmp);
- break;
- }
- if (strstr(tmp, "FETCH") == NULL) {
- log_print("IMAP4< %s\n", tmp);
- g_free(tmp);
- continue;
- }
- log_print("IMAP4< %s\n", tmp);
- g_string_assign(str, tmp);
- g_free(tmp);
-
- msginfo = imap_parse_envelope(session, item, str);
- if (!msginfo) {
- log_warning(_("can't parse envelope: %s\n"), str->str);
- continue;
- }
- if (update_count) {
- if (MSG_IS_NEW(msginfo->flags))
- item->new++;
- if (MSG_IS_UNREAD(msginfo->flags))
- item->unread++;
- }
- if (item->stype == F_QUEUE) {
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_QUEUED);
- } else if (item->stype == F_DRAFT) {
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_DRAFT);
- }
-
- msginfo->folder = item;
-
- if (!newlist)
- llast = newlist = g_slist_append(newlist, msginfo);
- else {
- llast = g_slist_append(llast, msginfo);
- llast = llast->next;
- }
-
- if (update_count)
- item->total++;
- }
-
- g_string_free(str, TRUE);
-
- session_set_access_time(SESSION(session));
-
- return newlist;
-}
-
-static void imap_delete_cached_message(FolderItem *item, guint32 uid)
-{
- gchar *dir;
- gchar *file;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
- g_return_if_fail(FOLDER_TYPE(item->folder) == F_IMAP);
-
- dir = folder_item_get_path(item);
- file = g_strdup_printf("%s%c%u", dir, G_DIR_SEPARATOR, uid);
-
- debug_print("Deleting cached message: %s\n", file);
-
- g_unlink(file);
-
- g_free(file);
- g_free(dir);
-}
-
-static GSList *imap_delete_cached_messages(GSList *mlist, FolderItem *item,
- guint32 first_uid, guint32 last_uid)
-{
- GSList *cur, *next;
- MsgInfo *msginfo;
- gchar *dir;
-
- g_return_val_if_fail(item != NULL, mlist);
- g_return_val_if_fail(item->folder != NULL, mlist);
- g_return_val_if_fail(FOLDER_TYPE(item->folder) == F_IMAP, mlist);
-
- if (first_uid == 0 && last_uid == 0)
- return mlist;
-
- debug_print("Deleting cached messages %u - %u ... ",
- first_uid, last_uid);
-
- dir = folder_item_get_path(item);
- if (is_dir_exist(dir))
- remove_numbered_files(dir, first_uid, last_uid);
- g_free(dir);
-
- for (cur = mlist; cur != NULL; ) {
- next = cur->next;
-
- msginfo = (MsgInfo *)cur->data;
- if (msginfo != NULL && first_uid <= msginfo->msgnum &&
- msginfo->msgnum <= last_uid) {
- procmsg_msginfo_free(msginfo);
- mlist = g_slist_remove(mlist, msginfo);
- }
-
- cur = next;
- }
-
- debug_print("done.\n");
-
- return mlist;
-}
-
-static void imap_delete_all_cached_messages(FolderItem *item)
-{
- gchar *dir;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
- g_return_if_fail(FOLDER_TYPE(item->folder) == F_IMAP);
-
- debug_print("Deleting all cached messages... ");
-
- dir = folder_item_get_path(item);
- if (is_dir_exist(dir))
- remove_all_numbered_files(dir);
- g_free(dir);
-
- debug_print("done.\n");
-}
-
-#if USE_SSL
-static SockInfo *imap_open(const gchar *server, gushort port,
- SSLType ssl_type)
-#else
-static SockInfo *imap_open(const gchar *server, gushort port)
-#endif
-{
- SockInfo *sock;
-
- if ((sock = sock_connect(server, port)) == NULL) {
- log_warning(_("Can't connect to IMAP4 server: %s:%d\n"),
- server, port);
- return NULL;
- }
-
-#if USE_SSL
- if (ssl_type == SSL_TUNNEL && !ssl_init_socket(sock)) {
- log_warning(_("Can't establish IMAP4 session with: %s:%d\n"),
- server, port);
- sock_close(sock);
- return NULL;
- }
-#endif
-
- return sock;
-}
-
-static GList *imap_parse_namespace_str(gchar *str)
-{
- guchar *p = str;
- gchar *name;
- gchar *separator;
- IMAPNameSpace *namespace;
- GList *ns_list = NULL;
-
- while (*p != '\0') {
- /* parse ("#foo" "/") */
-
- while (*p && *p != '(') p++;
- if (*p == '\0') break;
- p++;
-
- while (*p && *p != '"') p++;
- if (*p == '\0') break;
- p++;
- name = p;
-
- while (*p && *p != '"') p++;
- if (*p == '\0') break;
- *p = '\0';
- p++;
-
- while (*p && g_ascii_isspace(*p)) p++;
- if (*p == '\0') break;
- if (strncmp(p, "NIL", 3) == 0)
- separator = NULL;
- else if (*p == '"') {
- p++;
- separator = p;
- while (*p && *p != '"') p++;
- if (*p == '\0') break;
- *p = '\0';
- p++;
- } else break;
-
- while (*p && *p != ')') p++;
- if (*p == '\0') break;
- p++;
-
- namespace = g_new(IMAPNameSpace, 1);
- namespace->name = g_strdup(name);
- namespace->separator = separator ? separator[0] : '\0';
- ns_list = g_list_append(ns_list, namespace);
- }
-
- return ns_list;
-}
-
-static void imap_parse_namespace(IMAPSession *session, IMAPFolder *folder)
-{
- gchar *ns_str = NULL;
- gchar **str_array;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(folder != NULL);
-
- if (folder->ns_personal != NULL ||
- folder->ns_others != NULL ||
- folder->ns_shared != NULL)
- return;
-
- if (imap_cmd_namespace(session, &ns_str) != IMAP_SUCCESS) {
- log_warning(_("can't get namespace\n"));
- imap_get_namespace_by_list(session, folder);
- return;
- }
-
- str_array = strsplit_parenthesis(ns_str, '(', ')', 3);
- if (str_array[0])
- folder->ns_personal = imap_parse_namespace_str(str_array[0]);
- if (str_array[0] && str_array[1])
- folder->ns_others = imap_parse_namespace_str(str_array[1]);
- if (str_array[0] && str_array[1] && str_array[2])
- folder->ns_shared = imap_parse_namespace_str(str_array[2]);
- g_strfreev(str_array);
- g_free(ns_str);
-}
-
-static void imap_get_namespace_by_list(IMAPSession *session, IMAPFolder *folder)
-{
- GSList *item_list, *cur;
- gchar separator = '\0';
- IMAPNameSpace *namespace;
-
- g_return_if_fail(session != NULL);
- g_return_if_fail(folder != NULL);
-
- if (folder->ns_personal != NULL ||
- folder->ns_others != NULL ||
- folder->ns_shared != NULL)
- return;
-
- imap_cmd_gen_send(session, "LIST \"\" \"\"");
- item_list = imap_parse_list(session, "", &separator);
- for (cur = item_list; cur != NULL; cur = cur->next)
- folder_item_destroy(FOLDER_ITEM(cur->data));
- g_slist_free(item_list);
-
- namespace = g_new(IMAPNameSpace, 1);
- namespace->name = g_strdup("");
- namespace->separator = separator;
- folder->ns_personal = g_list_append(NULL, namespace);
-}
-
-static IMAPNameSpace *imap_find_namespace_from_list(GList *ns_list,
- const gchar *path)
-{
- IMAPNameSpace *namespace = NULL;
- gchar *tmp_path, *name;
-
- if (!path) path = "";
-
- for (; ns_list != NULL; ns_list = ns_list->next) {
- IMAPNameSpace *tmp_ns = ns_list->data;
-
- Xstrcat_a(tmp_path, path, "/", return namespace);
- Xstrdup_a(name, tmp_ns->name, return namespace);
- if (tmp_ns->separator && tmp_ns->separator != '/') {
- subst_char(tmp_path, tmp_ns->separator, '/');
- subst_char(name, tmp_ns->separator, '/');
- }
- if (strncmp(tmp_path, name, strlen(name)) == 0)
- namespace = tmp_ns;
- }
-
- return namespace;
-}
-
-static IMAPNameSpace *imap_find_namespace(IMAPFolder *folder,
- const gchar *path)
-{
- IMAPNameSpace *namespace;
-
- g_return_val_if_fail(folder != NULL, NULL);
-
- namespace = imap_find_namespace_from_list(folder->ns_personal, path);
- if (namespace) return namespace;
- namespace = imap_find_namespace_from_list(folder->ns_others, path);
- if (namespace) return namespace;
- namespace = imap_find_namespace_from_list(folder->ns_shared, path);
- if (namespace) return namespace;
-
- return NULL;
-}
-
-static gchar imap_get_path_separator(IMAPFolder *folder, const gchar *path)
-{
- IMAPNameSpace *namespace;
- gchar separator = '/';
-
- namespace = imap_find_namespace(folder, path);
- if (namespace && namespace->separator)
- separator = namespace->separator;
-
- return separator;
-}
-
-static gchar *imap_get_real_path(IMAPFolder *folder, const gchar *path)
-{
- gchar *real_path;
- gchar separator;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(path != NULL, NULL);
-
- real_path = imap_utf8_to_modified_utf7(path);
- separator = imap_get_path_separator(folder, path);
- imap_path_separator_subst(real_path, separator);
-
- return real_path;
-}
-
-static gchar *imap_parse_atom(IMAPSession *session, gchar *src,
- gchar *dest, gint dest_len, GString *str)
-{
- gchar *cur_pos = src;
- gchar *nextline;
-
- g_return_val_if_fail(str != NULL, cur_pos);
-
- /* read the next line if the current response buffer is empty */
- while (g_ascii_isspace(*cur_pos)) cur_pos++;
- while (*cur_pos == '\0') {
- if (sock_getline(SESSION(session)->sock, &nextline) < 0)
- return cur_pos;
- g_string_assign(str, nextline);
- cur_pos = str->str;
- strretchomp(nextline);
- /* log_print("IMAP4< %s\n", nextline); */
- debug_print("IMAP4< %s\n", nextline);
- g_free(nextline);
-
- while (g_ascii_isspace(*cur_pos)) cur_pos++;
- }
-
- if (!strncmp(cur_pos, "NIL", 3)) {
- *dest = '\0';
- cur_pos += 3;
- } else if (*cur_pos == '\"') {
- gchar *p;
-
- p = get_quoted(cur_pos, '\"', dest, dest_len);
- cur_pos = p ? p : cur_pos + 2;
- } else if (*cur_pos == '{') {
- gchar buf[32];
- gint len;
- gint block_len = 0;
-
- cur_pos = strchr_cpy(cur_pos + 1, '}', buf, sizeof(buf));
- len = atoi(buf);
- g_return_val_if_fail(len >= 0, cur_pos);
-
- g_string_truncate(str, 0);
- cur_pos = str->str;
-
- do {
- gint cur_len;
-
- cur_len = sock_getline(SESSION(session)->sock,
- &nextline);
- if (cur_len < 0)
- return cur_pos;
- block_len += cur_len;
- subst_null(nextline, cur_len, ' ');
- g_string_append(str, nextline);
- cur_pos = str->str;
- strretchomp(nextline);
- /* log_print("IMAP4< %s\n", nextline); */
- debug_print("IMAP4< %s\n", nextline);
- g_free(nextline);
- } while (block_len < len);
-
- memcpy(dest, cur_pos, MIN(len, dest_len - 1));
- dest[MIN(len, dest_len - 1)] = '\0';
- cur_pos += len;
- }
-
- return cur_pos;
-}
-
-static gchar *imap_get_header(IMAPSession *session, gchar *cur_pos,
- gchar **headers, GString *str)
-{
- gchar *nextline;
- gchar buf[32];
- gint len;
- gint block_len = 0;
-
- *headers = NULL;
-
- g_return_val_if_fail(str != NULL, cur_pos);
-
- while (g_ascii_isspace(*cur_pos)) cur_pos++;
-
- g_return_val_if_fail(*cur_pos == '{', cur_pos);
-
- cur_pos = strchr_cpy(cur_pos + 1, '}', buf, sizeof(buf));
- len = atoi(buf);
- g_return_val_if_fail(len >= 0, cur_pos);
-
- g_string_truncate(str, 0);
- cur_pos = str->str;
-
- do {
- gint cur_len;
-
- cur_len = sock_getline(SESSION(session)->sock, &nextline);
- if (cur_len < 0)
- return cur_pos;
- block_len += cur_len;
- subst_null(nextline, cur_len, ' ');
- g_string_append(str, nextline);
- cur_pos = str->str;
- /* strretchomp(nextline); */
- /* debug_print("IMAP4< %s\n", nextline); */
- g_free(nextline);
- } while (block_len < len);
-
- debug_print("IMAP4< [contents of RFC822.HEADER]\n");
-
- *headers = g_strndup(cur_pos, len);
- cur_pos += len;
-
- while (g_ascii_isspace(*cur_pos)) cur_pos++;
- while (*cur_pos == '\0') {
- if (sock_getline(SESSION(session)->sock, &nextline) < 0)
- return cur_pos;
- g_string_assign(str, nextline);
- cur_pos = str->str;
- strretchomp(nextline);
- debug_print("IMAP4< %s\n", nextline);
- g_free(nextline);
-
- while (g_ascii_isspace(*cur_pos)) cur_pos++;
- }
-
- return cur_pos;
-}
-
-static MsgFlags imap_parse_flags(const gchar *flag_str)
-{
- const gchar *p = flag_str;
- MsgFlags flags = {0, 0};
-
- flags.perm_flags = MSG_UNREAD;
-
- while ((p = strchr(p, '\\')) != NULL) {
- p++;
-
- if (g_ascii_strncasecmp(p, "Recent", 6) == 0 &&
- MSG_IS_UNREAD(flags)) {
- MSG_SET_PERM_FLAGS(flags, MSG_NEW);
- } else if (g_ascii_strncasecmp(p, "Seen", 4) == 0) {
- MSG_UNSET_PERM_FLAGS(flags, MSG_NEW|MSG_UNREAD);
- } else if (g_ascii_strncasecmp(p, "Deleted", 7) == 0) {
- MSG_SET_PERM_FLAGS(flags, MSG_DELETED);
- } else if (g_ascii_strncasecmp(p, "Flagged", 7) == 0) {
- MSG_SET_PERM_FLAGS(flags, MSG_MARKED);
- } else if (g_ascii_strncasecmp(p, "Answered", 8) == 0) {
- MSG_SET_PERM_FLAGS(flags, MSG_REPLIED);
- }
- }
-
- return flags;
-}
-
-static IMAPFlags imap_parse_imap_flags(const gchar *flag_str)
-{
- const gchar *p = flag_str;
- IMAPFlags flags = 0;
-
- while ((p = strchr(p, '\\')) != NULL) {
- p++;
-
- if (g_ascii_strncasecmp(p, "Seen", 4) == 0) {
- flags |= IMAP_FLAG_SEEN;
- } else if (g_ascii_strncasecmp(p, "Deleted", 7) == 0) {
- flags |= IMAP_FLAG_DELETED;
- } else if (g_ascii_strncasecmp(p, "Flagged", 7) == 0) {
- flags |= IMAP_FLAG_FLAGGED;
- } else if (g_ascii_strncasecmp(p, "Answered", 8) == 0) {
- flags |= IMAP_FLAG_ANSWERED;
- }
- }
-
- return flags;
-}
-
-static MsgInfo *imap_parse_envelope(IMAPSession *session, FolderItem *item,
- GString *line_str)
-{
- gchar buf[IMAPBUFSIZE];
- MsgInfo *msginfo = NULL;
- gchar *cur_pos;
- gint msgnum;
- guint32 uid = 0;
- size_t size = 0;
- MsgFlags flags = {0, 0}, imap_flags = {0, 0};
-
- g_return_val_if_fail(line_str != NULL, NULL);
- g_return_val_if_fail(line_str->str[0] == '*' &&
- line_str->str[1] == ' ', NULL);
-
- MSG_SET_TMP_FLAGS(flags, MSG_IMAP);
- if (item->stype == F_QUEUE) {
- MSG_SET_TMP_FLAGS(flags, MSG_QUEUED);
- } else if (item->stype == F_DRAFT) {
- MSG_SET_TMP_FLAGS(flags, MSG_DRAFT);
- }
-
- cur_pos = line_str->str + 2;
-
-#define PARSE_ONE_ELEMENT(ch) \
-{ \
- cur_pos = strchr_cpy(cur_pos, ch, buf, sizeof(buf)); \
- if (cur_pos == NULL) { \
- g_warning("cur_pos == NULL\n"); \
- procmsg_msginfo_free(msginfo); \
- return NULL; \
- } \
-}
-
- PARSE_ONE_ELEMENT(' ');
- msgnum = atoi(buf);
-
- PARSE_ONE_ELEMENT(' ');
- g_return_val_if_fail(!strcmp(buf, "FETCH"), NULL);
-
- g_return_val_if_fail(*cur_pos == '(', NULL);
- cur_pos++;
-
- while (*cur_pos != '\0' && *cur_pos != ')') {
- while (*cur_pos == ' ') cur_pos++;
-
- if (!strncmp(cur_pos, "UID ", 4)) {
- cur_pos += 4;
- uid = strtoul(cur_pos, &cur_pos, 10);
- } else if (!strncmp(cur_pos, "FLAGS ", 6)) {
- cur_pos += 6;
- if (*cur_pos != '(') {
- g_warning("*cur_pos != '('\n");
- procmsg_msginfo_free(msginfo);
- return NULL;
- }
- cur_pos++;
- PARSE_ONE_ELEMENT(')');
- imap_flags = imap_parse_flags(buf);
- } else if (!strncmp(cur_pos, "RFC822.SIZE ", 12)) {
- cur_pos += 12;
- size = strtol(cur_pos, &cur_pos, 10);
- } else if (!strncmp(cur_pos, "RFC822.HEADER ", 14)) {
- gchar *headers;
-
- cur_pos += 14;
- cur_pos = imap_get_header(session, cur_pos, &headers,
- line_str);
- msginfo = procheader_parse_str(headers, flags, FALSE);
- g_free(headers);
- } else {
- g_warning("invalid FETCH response: %s\n", cur_pos);
- break;
- }
- }
-
-#undef PARSE_ONE_ELEMENT
-
- if (msginfo) {
- msginfo->msgnum = uid;
- msginfo->size = size;
- msginfo->flags.tmp_flags |= imap_flags.tmp_flags;
- msginfo->flags.perm_flags = imap_flags.perm_flags;
- }
-
- return msginfo;
-}
-
-static gint imap_msg_list_change_perm_flags(GSList *msglist, MsgPermFlags flags,
- gboolean is_set)
-{
- Folder *folder;
- IMAPSession *session;
- IMAPFlags iflags = 0;
- MsgInfo *msginfo;
- GSList *seq_list, *cur;
- gint ok = IMAP_SUCCESS;
-
- if (msglist == NULL) return IMAP_SUCCESS;
-
- msginfo = (MsgInfo *)msglist->data;
- g_return_val_if_fail(msginfo != NULL, -1);
-
- g_return_val_if_fail(MSG_IS_IMAP(msginfo->flags), -1);
- g_return_val_if_fail(msginfo->folder != NULL, -1);
- g_return_val_if_fail(msginfo->folder->folder != NULL, -1);
-
- folder = msginfo->folder->folder;
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_IMAP, -1);
-
- session = imap_session_get(folder);
- if (!session) return -1;
-
- ok = imap_select(session, IMAP_FOLDER(folder), msginfo->folder->path,
- NULL, NULL, NULL, NULL);
- if (ok != IMAP_SUCCESS)
- return ok;
-
- seq_list = imap_get_seq_set_from_msglist(msglist);
-
- if (flags & MSG_MARKED) iflags |= IMAP_FLAG_FLAGGED;
- if (flags & MSG_REPLIED) iflags |= IMAP_FLAG_ANSWERED;
-
- for (cur = seq_list; cur != NULL; cur = cur->next) {
- gchar *seq_set = (gchar *)cur->data;
-
- if (iflags) {
- ok = imap_set_message_flags(session, seq_set, iflags,
- is_set);
- if (ok != IMAP_SUCCESS) break;
- }
-
- if (flags & MSG_UNREAD) {
- ok = imap_set_message_flags(session, seq_set,
- IMAP_FLAG_SEEN, !is_set);
- if (ok != IMAP_SUCCESS) break;
- }
- }
-
- imap_seq_set_free(seq_list);
-
- return ok;
-}
-
-gint imap_msg_set_perm_flags(MsgInfo *msginfo, MsgPermFlags flags)
-{
- GSList msglist;
-
- msglist.data = msginfo;
- msglist.next = NULL;
-
- return imap_msg_list_change_perm_flags(&msglist, flags, TRUE);
-}
-
-gint imap_msg_unset_perm_flags(MsgInfo *msginfo, MsgPermFlags flags)
-{
- GSList msglist;
-
- msglist.data = msginfo;
- msglist.next = NULL;
-
- return imap_msg_list_change_perm_flags(&msglist, flags, FALSE);
-}
-
-gint imap_msg_list_set_perm_flags(GSList *msglist, MsgPermFlags flags)
-{
- return imap_msg_list_change_perm_flags(msglist, flags, TRUE);
-}
-
-gint imap_msg_list_unset_perm_flags(GSList *msglist, MsgPermFlags flags)
-{
- return imap_msg_list_change_perm_flags(msglist, flags, FALSE);
-}
-
-static gchar *imap_get_flag_str(IMAPFlags flags)
-{
- GString *str;
- gchar *ret;
-
- str = g_string_new(NULL);
-
- if (IMAP_IS_SEEN(flags)) g_string_append(str, "\\Seen ");
- if (IMAP_IS_ANSWERED(flags)) g_string_append(str, "\\Answered ");
- if (IMAP_IS_FLAGGED(flags)) g_string_append(str, "\\Flagged ");
- if (IMAP_IS_DELETED(flags)) g_string_append(str, "\\Deleted ");
- if (IMAP_IS_DRAFT(flags)) g_string_append(str, "\\Draft");
-
- if (str->len > 0 && str->str[str->len - 1] == ' ')
- g_string_truncate(str, str->len - 1);
-
- ret = str->str;
- g_string_free(str, FALSE);
-
- return ret;
-}
-
-static gint imap_set_message_flags(IMAPSession *session,
- const gchar *seq_set,
- IMAPFlags flags,
- gboolean is_set)
-{
- gchar *cmd;
- gchar *flag_str;
- gint ok;
-
- flag_str = imap_get_flag_str(flags);
- cmd = g_strconcat(is_set ? "+FLAGS.SILENT (" : "-FLAGS.SILENT (",
- flag_str, ")", NULL);
- g_free(flag_str);
-
- ok = imap_cmd_store(session, seq_set, cmd);
- g_free(cmd);
-
- return ok;
-}
-
-static gint imap_select(IMAPSession *session, IMAPFolder *folder,
- const gchar *path,
- gint *exists, gint *recent, gint *unseen,
- guint32 *uid_validity)
-{
- gchar *real_path;
- gint ok;
- gint exists_, recent_, unseen_, uid_validity_;
-
- if (!exists || !recent || !unseen || !uid_validity) {
- if (session->mbox && strcmp(session->mbox, path) == 0)
- return IMAP_SUCCESS;
- exists = &exists_;
- recent = &recent_;
- unseen = &unseen_;
- uid_validity = &uid_validity_;
- }
-
- g_free(session->mbox);
- session->mbox = NULL;
-
- real_path = imap_get_real_path(folder, path);
- ok = imap_cmd_select(session, real_path,
- exists, recent, unseen, uid_validity);
- if (ok != IMAP_SUCCESS)
- log_warning(_("can't select folder: %s\n"), real_path);
- else
- session->mbox = g_strdup(path);
- g_free(real_path);
-
- return ok;
-}
-
-#define THROW(err) { ok = err; goto catch; }
-
-static gint imap_status(IMAPSession *session, IMAPFolder *folder,
- const gchar *path,
- gint *messages, gint *recent,
- guint32 *uid_next, guint32 *uid_validity,
- gint *unseen)
-{
- gchar *real_path;
- gchar *real_path_;
- gint ok;
- GPtrArray *argbuf = NULL;
- gchar *str;
-
- if (messages && recent && uid_next && uid_validity && unseen) {
- *messages = *recent = *uid_next = *uid_validity = *unseen = 0;
- argbuf = g_ptr_array_new();
- }
-
- real_path = imap_get_real_path(folder, path);
- QUOTE_IF_REQUIRED(real_path_, real_path);
- imap_cmd_gen_send(session, "STATUS %s "
- "(MESSAGES RECENT UIDNEXT UIDVALIDITY UNSEEN)",
- real_path_);
-
- ok = imap_cmd_ok(session, argbuf);
- if (ok != IMAP_SUCCESS || !argbuf) THROW(ok);
-
- str = search_array_str(argbuf, "STATUS");
- if (!str) THROW(IMAP_ERROR);
-
- str = strchr(str, '(');
- if (!str) THROW(IMAP_ERROR);
- str++;
- while (*str != '\0' && *str != ')') {
- while (*str == ' ') str++;
-
- if (!strncmp(str, "MESSAGES ", 9)) {
- str += 9;
- *messages = strtol(str, &str, 10);
- } else if (!strncmp(str, "RECENT ", 7)) {
- str += 7;
- *recent = strtol(str, &str, 10);
- } else if (!strncmp(str, "UIDNEXT ", 8)) {
- str += 8;
- *uid_next = strtoul(str, &str, 10);
- } else if (!strncmp(str, "UIDVALIDITY ", 12)) {
- str += 12;
- *uid_validity = strtoul(str, &str, 10);
- } else if (!strncmp(str, "UNSEEN ", 7)) {
- str += 7;
- *unseen = strtol(str, &str, 10);
- } else {
- g_warning("invalid STATUS response: %s\n", str);
- break;
- }
- }
-
-catch:
- g_free(real_path);
- if (argbuf) {
- ptr_array_free_strings(argbuf);
- g_ptr_array_free(argbuf, TRUE);
- }
-
- return ok;
-}
-
-#undef THROW
-
-static gboolean imap_has_capability(IMAPSession *session,
- const gchar *capability)
-{
- gchar **p;
-
- for (p = session->capability; *p != NULL; ++p) {
- if (!g_ascii_strcasecmp(*p, capability))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void imap_capability_free(IMAPSession *session)
-{
- if (session->capability) {
- g_strfreev(session->capability);
- session->capability = NULL;
- }
-}
-
-
-/* low-level IMAP4rev1 commands */
-
-#define THROW(err) { ok = err; goto catch; }
-
-static gint imap_cmd_capability(IMAPSession *session)
-{
- gint ok;
- GPtrArray *argbuf;
- gchar *capability;
-
- argbuf = g_ptr_array_new();
-
- imap_cmd_gen_send(session, "CAPABILITY");
- if ((ok = imap_cmd_ok(session, argbuf)) != IMAP_SUCCESS) THROW(ok);
-
- capability = search_array_str(argbuf, "CAPABILITY ");
- if (!capability) THROW(IMAP_ERROR);
-
- capability += strlen("CAPABILITY ");
-
- imap_capability_free(session);
- session->capability = g_strsplit(capability, " ", -1);
-
-catch:
- ptr_array_free_strings(argbuf);
- g_ptr_array_free(argbuf, TRUE);
-
- return ok;
-}
-
-#undef THROW
-
-static gint imap_cmd_authenticate(IMAPSession *session, const gchar *user,
- const gchar *pass, IMAPAuthType type)
-{
- gchar *auth_type;
- gint ok;
- gchar *buf = NULL;
- gchar *challenge;
- gint challenge_len;
- gchar hexdigest[33];
- gchar *response;
- gchar *response64;
-
- g_return_val_if_fail((type == 0 || type == IMAP_AUTH_CRAM_MD5),
- IMAP_ERROR);
-
- auth_type = "CRAM-MD5";
-
- imap_cmd_gen_send(session, "AUTHENTICATE %s", auth_type);
- ok = imap_cmd_gen_recv(session, &buf);
- if (ok != IMAP_SUCCESS || buf[0] != '+' || buf[1] != ' ') {
- g_free(buf);
- return IMAP_ERROR;
- }
-
- challenge = g_malloc(strlen(buf + 2) + 1);
- challenge_len = base64_decode(challenge, buf + 2, -1);
- challenge[challenge_len] = '\0';
- g_free(buf);
- log_print("IMAP< [Decoded: %s]\n", challenge);
-
- md5_hex_hmac(hexdigest, challenge, challenge_len, pass, strlen(pass));
- g_free(challenge);
-
- response = g_strdup_printf("%s %s", user, hexdigest);
- log_print("IMAP> [Encoded: %s]\n", response);
- response64 = g_malloc((strlen(response) + 3) * 2 + 1);
- base64_encode(response64, response, strlen(response));
- g_free(response);
-
- log_print("IMAP> %s\n", response64);
- sock_puts(SESSION(session)->sock, response64);
- ok = imap_cmd_ok(session, NULL);
- if (ok != IMAP_SUCCESS)
- log_warning(_("IMAP4 authentication failed.\n"));
-
- return ok;
-}
-
-static gint imap_cmd_login(IMAPSession *session,
- const gchar *user, const gchar *pass)
-{
- gchar *user_, *pass_;
- gint ok;
-
- QUOTE_IF_REQUIRED(user_, user);
- QUOTE_IF_REQUIRED(pass_, pass);
- imap_cmd_gen_send(session, "LOGIN %s %s", user_, pass_);
-
- ok = imap_cmd_ok(session, NULL);
- if (ok != IMAP_SUCCESS)
- log_warning(_("IMAP4 login failed.\n"));
-
- return ok;
-}
-
-static gint imap_cmd_logout(IMAPSession *session)
-{
- imap_cmd_gen_send(session, "LOGOUT");
- return imap_cmd_ok(session, NULL);
-}
-
-static gint imap_cmd_noop(IMAPSession *session)
-{
- imap_cmd_gen_send(session, "NOOP");
- return imap_cmd_ok(session, NULL);
-}
-
-#if USE_SSL
-static gint imap_cmd_starttls(IMAPSession *session)
-{
- imap_cmd_gen_send(session, "STARTTLS");
- return imap_cmd_ok(session, NULL);
-}
-#endif
-
-#define THROW(err) { ok = err; goto catch; }
-
-static gint imap_cmd_namespace(IMAPSession *session, gchar **ns_str)
-{
- gint ok;
- GPtrArray *argbuf;
- gchar *str;
-
- argbuf = g_ptr_array_new();
-
- imap_cmd_gen_send(session, "NAMESPACE");
- if ((ok = imap_cmd_ok(session, argbuf)) != IMAP_SUCCESS) THROW(ok);
-
- str = search_array_str(argbuf, "NAMESPACE");
- if (!str) THROW(IMAP_ERROR);
-
- *ns_str = g_strdup(str);
-
-catch:
- ptr_array_free_strings(argbuf);
- g_ptr_array_free(argbuf, TRUE);
-
- return ok;
-}
-
-#undef THROW
-
-static gint imap_cmd_list(IMAPSession *session, const gchar *ref,
- const gchar *mailbox, GPtrArray *argbuf)
-{
- gchar *ref_, *mailbox_;
-
- if (!ref) ref = "\"\"";
- if (!mailbox) mailbox = "\"\"";
-
- QUOTE_IF_REQUIRED(ref_, ref);
- QUOTE_IF_REQUIRED(mailbox_, mailbox);
- imap_cmd_gen_send(session, "LIST %s %s", ref_, mailbox_);
-
- return imap_cmd_ok(session, argbuf);
-}
-
-#define THROW goto catch
-
-static gint imap_cmd_do_select(IMAPSession *session, const gchar *folder,
- gboolean examine,
- gint *exists, gint *recent, gint *unseen,
- guint32 *uid_validity)
-{
- gint ok;
- gchar *resp_str;
- GPtrArray *argbuf;
- gchar *select_cmd;
- gchar *folder_;
- guint uid_validity_;
-
- *exists = *recent = *unseen = *uid_validity = 0;
- argbuf = g_ptr_array_new();
-
- if (examine)
- select_cmd = "EXAMINE";
- else
- select_cmd = "SELECT";
-
- QUOTE_IF_REQUIRED(folder_, folder);
- imap_cmd_gen_send(session, "%s %s", select_cmd, folder_);
-
- if ((ok = imap_cmd_ok(session, argbuf)) != IMAP_SUCCESS) THROW;
-
- resp_str = search_array_contain_str(argbuf, "EXISTS");
- if (resp_str) {
- if (sscanf(resp_str,"%d EXISTS", exists) != 1) {
- g_warning("imap_cmd_select(): invalid EXISTS line.\n");
- THROW;
- }
- }
-
- resp_str = search_array_contain_str(argbuf, "RECENT");
- if (resp_str) {
- if (sscanf(resp_str, "%d RECENT", recent) != 1) {
- g_warning("imap_cmd_select(): invalid RECENT line.\n");
- THROW;
- }
- }
-
- resp_str = search_array_contain_str(argbuf, "UIDVALIDITY");
- if (resp_str) {
- if (sscanf(resp_str, "OK [UIDVALIDITY %u] ", &uid_validity_)
- != 1) {
- g_warning("imap_cmd_select(): invalid UIDVALIDITY line.\n");
- THROW;
- }
- *uid_validity = uid_validity_;
- }
-
- resp_str = search_array_contain_str(argbuf, "UNSEEN");
- if (resp_str) {
- if (sscanf(resp_str, "OK [UNSEEN %d] ", unseen) != 1) {
- g_warning("imap_cmd_select(): invalid UNSEEN line.\n");
- THROW;
- }
- }
-
-catch:
- ptr_array_free_strings(argbuf);
- g_ptr_array_free(argbuf, TRUE);
-
- return ok;
-}
-
-static gint imap_cmd_select(IMAPSession *session, const gchar *folder,
- gint *exists, gint *recent, gint *unseen,
- guint32 *uid_validity)
-{
- return imap_cmd_do_select(session, folder, FALSE,
- exists, recent, unseen, uid_validity);
-}
-
-static gint imap_cmd_examine(IMAPSession *session, const gchar *folder,
- gint *exists, gint *recent, gint *unseen,
- guint32 *uid_validity)
-{
- return imap_cmd_do_select(session, folder, TRUE,
- exists, recent, unseen, uid_validity);
-}
-
-#undef THROW
-
-static gint imap_cmd_create(IMAPSession *session, const gchar *folder)
-{
- gchar *folder_;
-
- QUOTE_IF_REQUIRED(folder_, folder);
- imap_cmd_gen_send(session, "CREATE %s", folder_);
-
- return imap_cmd_ok(session, NULL);
-}
-
-static gint imap_cmd_rename(IMAPSession *session, const gchar *old_folder,
- const gchar *new_folder)
-{
- gchar *old_folder_, *new_folder_;
-
- QUOTE_IF_REQUIRED(old_folder_, old_folder);
- QUOTE_IF_REQUIRED(new_folder_, new_folder);
- imap_cmd_gen_send(session, "RENAME %s %s", old_folder_, new_folder_);
-
- return imap_cmd_ok(session, NULL);
-}
-
-static gint imap_cmd_delete(IMAPSession *session, const gchar *folder)
-{
- gchar *folder_;
-
- QUOTE_IF_REQUIRED(folder_, folder);
- imap_cmd_gen_send(session, "DELETE %s", folder_);
-
- return imap_cmd_ok(session, NULL);
-}
-
-#define THROW(err) { ok = err; goto catch; }
-
-static gint imap_cmd_search(IMAPSession *session, const gchar *criteria,
- GArray **result)
-{
- gint ok;
- GPtrArray *argbuf;
- GArray *array;
- gchar *str;
- gchar *p, *ep;
- gint i;
- guint32 uid;
-
- g_return_val_if_fail(criteria != NULL, IMAP_ERROR);
- g_return_val_if_fail(result != NULL, IMAP_ERROR);
-
- argbuf = g_ptr_array_new();
-
- imap_cmd_gen_send(session, "UID SEARCH %s", criteria);
- if ((ok = imap_cmd_ok(session, argbuf)) != IMAP_SUCCESS) THROW(ok);
-
- array = g_array_new(FALSE, FALSE, sizeof(guint32));
-
- for (i = 0; i < argbuf->len; i++) {
- str = g_ptr_array_index(argbuf, i);
- if (strncmp(str, "SEARCH", 6) != 0)
- continue;
-
- p = str + 6;
- while (*p != '\0') {
- uid = strtoul(p, &ep, 10);
- if (p < ep && uid > 0) {
- g_array_append_val(array, uid);
- p = ep;
- } else
- break;
- }
- }
-
- *result = array;
-
-catch:
- ptr_array_free_strings(argbuf);
- g_ptr_array_free(argbuf, TRUE);
-
- return ok;
-}
-
-static gint imap_cmd_fetch(IMAPSession *session, guint32 uid,
- const gchar *filename)
-{
- gint ok;
- gchar *buf;
- gchar *cur_pos;
- gchar size_str[32];
- glong size_num;
- gint ret;
-
- g_return_val_if_fail(filename != NULL, IMAP_ERROR);
-
- imap_cmd_gen_send(session, "UID FETCH %d BODY.PEEK[]", uid);
-
- while ((ok = imap_cmd_gen_recv(session, &buf)) == IMAP_SUCCESS) {
- if (buf[0] != '*' || buf[1] != ' ') {
- g_free(buf);
- return IMAP_ERROR;
- }
- if (strstr(buf, "FETCH") != NULL) break;
- g_free(buf);
- }
- if (ok != IMAP_SUCCESS)
- return ok;
-
-#define RETURN_ERROR_IF_FAIL(cond) \
- if (!(cond)) { \
- g_free(buf); \
- return IMAP_ERROR; \
- }
-
- cur_pos = strchr(buf, '{');
- RETURN_ERROR_IF_FAIL(cur_pos != NULL);
- cur_pos = strchr_cpy(cur_pos + 1, '}', size_str, sizeof(size_str));
- RETURN_ERROR_IF_FAIL(cur_pos != NULL);
- size_num = atol(size_str);
- RETURN_ERROR_IF_FAIL(size_num >= 0);
-
- RETURN_ERROR_IF_FAIL(*cur_pos == '\0');
-
-#undef RETURN_ERROR_IF_FAIL
-
- g_free(buf);
-
- if ((ret = recv_bytes_write_to_file(SESSION(session)->sock,
- size_num, filename)) != 0) {
- if (ret == -2)
- return IMAP_SOCKET;
- }
-
- if (imap_cmd_gen_recv(session, &buf) != IMAP_SUCCESS)
- return IMAP_ERROR;
-
- if (buf[0] == '\0' || buf[strlen(buf) - 1] != ')') {
- g_free(buf);
- return IMAP_ERROR;
- }
- g_free(buf);
-
- ok = imap_cmd_ok(session, NULL);
-
- if (ret != 0)
- return IMAP_ERROR;
-
- return ok;
-}
-
-static gint imap_cmd_append(IMAPSession *session, const gchar *destfolder,
- const gchar *file, IMAPFlags flags,
- guint32 *new_uid)
-{
- gint ok;
- gint size;
- gchar *destfolder_;
- gchar *flag_str;
- guint new_uid_;
- gchar *ret = NULL;
- gchar buf[BUFFSIZE];
- FILE *fp;
- GPtrArray *argbuf;
- gchar *resp_str;
-
- g_return_val_if_fail(file != NULL, IMAP_ERROR);
-
- size = get_file_size_as_crlf(file);
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return -1;
- }
- QUOTE_IF_REQUIRED(destfolder_, destfolder);
- flag_str = imap_get_flag_str(flags);
- imap_cmd_gen_send(session, "APPEND %s (%s) {%d}",
- destfolder_, flag_str, size);
- g_free(flag_str);
-
- ok = imap_cmd_gen_recv(session, &ret);
- if (ok != IMAP_SUCCESS || ret[0] != '+' || ret[1] != ' ') {
- log_warning(_("can't append %s to %s\n"), file, destfolder_);
- g_free(ret);
- fclose(fp);
- return IMAP_ERROR;
- }
- g_free(ret);
-
- log_print("IMAP4> %s\n", _("(sending file...)"));
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- strretchomp(buf);
- if (sock_puts(SESSION(session)->sock, buf) < 0) {
- fclose(fp);
- return -1;
- }
- }
-
- if (ferror(fp)) {
- FILE_OP_ERROR(file, "fgets");
- fclose(fp);
- return -1;
- }
-
- sock_puts(SESSION(session)->sock, "");
-
- fclose(fp);
-
- if (new_uid != NULL)
- *new_uid = 0;
-
- if (new_uid != NULL && session->uidplus) {
- argbuf = g_ptr_array_new();
-
- ok = imap_cmd_ok(session, argbuf);
- if (ok != IMAP_SUCCESS)
- log_warning(_("can't append message to %s\n"),
- destfolder_);
- else if (argbuf->len > 0) {
- resp_str = g_ptr_array_index(argbuf, argbuf->len - 1);
- if (resp_str &&
- sscanf(resp_str, "%*u OK [APPENDUID %*u %u]",
- &new_uid_) == 1) {
- *new_uid = new_uid_;
- }
- }
-
- ptr_array_free_strings(argbuf);
- g_ptr_array_free(argbuf, TRUE);
- } else
- ok = imap_cmd_ok(session, NULL);
-
- return ok;
-}
-
-static gint imap_cmd_copy(IMAPSession *session, const gchar *seq_set,
- const gchar *destfolder)
-{
- gint ok;
- gchar *destfolder_;
-
- g_return_val_if_fail(destfolder != NULL, IMAP_ERROR);
-
- QUOTE_IF_REQUIRED(destfolder_, destfolder);
- imap_cmd_gen_send(session, "UID COPY %s %s", seq_set, destfolder_);
-
- ok = imap_cmd_ok(session, NULL);
- if (ok != IMAP_SUCCESS) {
- log_warning(_("can't copy %s to %s\n"), seq_set, destfolder_);
- return -1;
- }
-
- return ok;
-}
-
-gint imap_cmd_envelope(IMAPSession *session, const gchar *seq_set)
-{
- imap_cmd_gen_send
- (session, "UID FETCH %s (UID FLAGS RFC822.SIZE RFC822.HEADER)",
- seq_set);
-
- return IMAP_SUCCESS;
-}
-
-static gint imap_cmd_store(IMAPSession *session, const gchar *seq_set,
- const gchar *sub_cmd)
-{
- gint ok;
-
- imap_cmd_gen_send(session, "UID STORE %s %s", seq_set, sub_cmd);
-
- if ((ok = imap_cmd_ok(session, NULL)) != IMAP_SUCCESS) {
- log_warning(_("error while imap command: STORE %s %s\n"),
- seq_set, sub_cmd);
- return ok;
- }
-
- return IMAP_SUCCESS;
-}
-
-static gint imap_cmd_expunge(IMAPSession *session)
-{
- gint ok;
-
- imap_cmd_gen_send(session, "EXPUNGE");
- if ((ok = imap_cmd_ok(session, NULL)) != IMAP_SUCCESS) {
- log_warning(_("error while imap command: EXPUNGE\n"));
- return ok;
- }
-
- return IMAP_SUCCESS;
-}
-
-static gint imap_cmd_close(IMAPSession *session)
-{
- gint ok;
-
- imap_cmd_gen_send(session, "CLOSE");
- if ((ok = imap_cmd_ok(session, NULL)) != IMAP_SUCCESS)
- log_warning(_("error while imap command: CLOSE\n"));
-
- return ok;
-}
-
-static gint imap_cmd_ok(IMAPSession *session, GPtrArray *argbuf)
-{
- gint ok;
- gchar *buf;
- gint cmd_num;
- gchar cmd_status[IMAPBUFSIZE + 1];
-
- while ((ok = imap_cmd_gen_recv(session, &buf)) == IMAP_SUCCESS) {
- if (buf[0] == '*' && buf[1] == ' ') {
- if (argbuf) {
- g_memmove(buf, buf + 2, strlen(buf + 2) + 1);
- g_ptr_array_add(argbuf, buf);
- } else
- g_free(buf);
- continue;
- }
-
- if (sscanf(buf, "%d %" Xstr(IMAPBUFSIZE) "s",
- &cmd_num, cmd_status) < 2) {
- g_free(buf);
- return IMAP_ERROR;
- } else if (cmd_num == session->cmd_count &&
- !strcmp(cmd_status, "OK")) {
- if (argbuf)
- g_ptr_array_add(argbuf, buf);
- else
- g_free(buf);
- return IMAP_SUCCESS;
- } else {
- g_free(buf);
- return IMAP_ERROR;
- }
- }
-
- return ok;
-}
-
-static void imap_cmd_gen_send(IMAPSession *session, const gchar *format, ...)
-{
- gchar buf[IMAPBUFSIZE];
- gchar tmp[IMAPBUFSIZE];
- gchar *p;
- va_list args;
-
- va_start(args, format);
- g_vsnprintf(tmp, sizeof(tmp), format, args);
- va_end(args);
-
- session->cmd_count++;
-
- g_snprintf(buf, sizeof(buf), "%d %s\r\n", session->cmd_count, tmp);
- if (!g_ascii_strncasecmp(tmp, "LOGIN ", 6) &&
- (p = strchr(tmp + 6, ' '))) {
- *p = '\0';
- log_print("IMAP4> %d %s ********\n", session->cmd_count, tmp);
- } else
- log_print("IMAP4> %d %s\n", session->cmd_count, tmp);
-
- sock_write_all(SESSION(session)->sock, buf, strlen(buf));
-}
-
-static gint imap_cmd_gen_recv(IMAPSession *session, gchar **ret)
-{
- if (sock_getline(SESSION(session)->sock, ret) < 0)
- return IMAP_SOCKET;
-
- strretchomp(*ret);
-
- log_print("IMAP4< %s\n", *ret);
-
- session_set_access_time(SESSION(session));
-
- return IMAP_SUCCESS;
-}
-
-
-/* misc utility functions */
-
-static gchar *strchr_cpy(const gchar *src, gchar ch, gchar *dest, gint len)
-{
- gchar *tmp;
-
- dest[0] = '\0';
- tmp = strchr(src, ch);
- if (!tmp)
- return NULL;
-
- memcpy(dest, src, MIN(tmp - src, len - 1));
- dest[MIN(tmp - src, len - 1)] = '\0';
-
- return tmp + 1;
-}
-
-static gchar *get_quoted(const gchar *src, gchar ch, gchar *dest, gint len)
-{
- const gchar *p = src;
- gint n = 0;
-
- g_return_val_if_fail(*p == ch, NULL);
-
- *dest = '\0';
- p++;
-
- while (*p != '\0' && *p != ch) {
- if (n < len - 1) {
- if (*p == '\\' && *(p + 1) != '\0')
- p++;
- *dest++ = *p++;
- } else
- p++;
- n++;
- }
-
- *dest = '\0';
- return (gchar *)(*p == ch ? p + 1 : p);
-}
-
-static gchar *search_array_contain_str(GPtrArray *array, gchar *str)
-{
- gint i;
-
- for (i = 0; i < array->len; i++) {
- gchar *tmp;
-
- tmp = g_ptr_array_index(array, i);
- if (strstr(tmp, str) != NULL)
- return tmp;
- }
-
- return NULL;
-}
-
-static gchar *search_array_str(GPtrArray *array, gchar *str)
-{
- gint i;
- gint len;
-
- len = strlen(str);
-
- for (i = 0; i < array->len; i++) {
- gchar *tmp;
-
- tmp = g_ptr_array_index(array, i);
- if (!strncmp(tmp, str, len))
- return tmp;
- }
-
- return NULL;
-}
-
-static void imap_path_separator_subst(gchar *str, gchar separator)
-{
- gchar *p;
- gboolean in_escape = FALSE;
-
- if (!separator || separator == '/') return;
-
- for (p = str; *p != '\0'; p++) {
- if (*p == '/' && !in_escape)
- *p = separator;
- else if (*p == '&' && *(p + 1) != '-' && !in_escape)
- in_escape = TRUE;
- else if (*p == '-' && in_escape)
- in_escape = FALSE;
- }
-}
-
-static gchar *imap_modified_utf7_to_utf8(const gchar *mutf7_str)
-{
- static iconv_t cd = (iconv_t)-1;
- static gboolean iconv_ok = TRUE;
- GString *norm_utf7;
- gchar *norm_utf7_p;
- size_t norm_utf7_len;
- const gchar *p;
- gchar *to_str, *to_p;
- size_t to_len;
- gboolean in_escape = FALSE;
-
- if (!iconv_ok) return g_strdup(mutf7_str);
-
- if (cd == (iconv_t)-1) {
- cd = iconv_open(CS_INTERNAL, CS_UTF_7);
- if (cd == (iconv_t)-1) {
- g_warning("iconv cannot convert UTF-7 to %s\n",
- CS_INTERNAL);
- iconv_ok = FALSE;
- return g_strdup(mutf7_str);
- }
- }
-
- /* modified UTF-7 to normal UTF-7 conversion */
- norm_utf7 = g_string_new(NULL);
-
- for (p = mutf7_str; *p != '\0'; p++) {
- /* replace: '&' -> '+',
- "&-" -> '&',
- "+" -> "+-",
- escaped ',' -> '/' */
- if (!in_escape && *p == '&') {
- if (*(p + 1) != '-') {
- g_string_append_c(norm_utf7, '+');
- in_escape = TRUE;
- } else {
- g_string_append_c(norm_utf7, '&');
- p++;
- }
- } else if (!in_escape && *p == '+') {
- g_string_append(norm_utf7, "+-");
- } else if (in_escape && *p == ',') {
- g_string_append_c(norm_utf7, '/');
- } else if (in_escape && *p == '-') {
- g_string_append_c(norm_utf7, '-');
- in_escape = FALSE;
- } else {
- g_string_append_c(norm_utf7, *p);
- }
- }
-
- /* somehow iconv() returns error when the last of the string is "+-" */
- g_string_append_c(norm_utf7, '\n');
- norm_utf7_p = norm_utf7->str;
- norm_utf7_len = norm_utf7->len;
- to_len = strlen(mutf7_str) * 5;
- to_p = to_str = g_malloc(to_len + 1);
-
- if (iconv(cd, (ICONV_CONST gchar **)&norm_utf7_p, &norm_utf7_len,
- &to_p, &to_len) == -1) {
- g_warning(_("iconv cannot convert UTF-7 to %s\n"), CS_INTERNAL);
- g_string_free(norm_utf7, TRUE);
- g_free(to_str);
- return g_strdup(mutf7_str);
- }
-
- /* second iconv() call for flushing */
- iconv(cd, NULL, NULL, &to_p, &to_len);
- g_string_free(norm_utf7, TRUE);
- *to_p = '\0';
- strretchomp(to_str);
-
- return to_str;
-}
-
-static gchar *imap_utf8_to_modified_utf7(const gchar *from)
-{
- static iconv_t cd = (iconv_t)-1;
- static gboolean iconv_ok = TRUE;
- gchar *norm_utf7, *norm_utf7_p;
- size_t from_len, norm_utf7_len;
- GString *to_str;
- gchar *from_tmp, *to, *p;
- gboolean in_escape = FALSE;
-
- if (!iconv_ok) return g_strdup(from);
-
- if (cd == (iconv_t)-1) {
- cd = iconv_open(CS_UTF_7, CS_INTERNAL);
- if (cd == (iconv_t)-1) {
- g_warning(_("iconv cannot convert %s to UTF-7\n"),
- CS_INTERNAL);
- iconv_ok = FALSE;
- return g_strdup(from);
- }
- }
-
- /* UTF-8 to normal UTF-7 conversion */
- Xstrdup_a(from_tmp, from, return g_strdup(from));
- from_len = strlen(from);
- norm_utf7_len = from_len * 5;
- Xalloca(norm_utf7, norm_utf7_len + 1, return g_strdup(from));
- norm_utf7_p = norm_utf7;
-
- while (from_len > 0) {
- if (*from_tmp == '+') {
- *norm_utf7_p++ = '+';
- *norm_utf7_p++ = '-';
- norm_utf7_len -= 2;
- from_tmp++;
- from_len--;
- } else if (g_ascii_isprint(*from_tmp)) {
- /* printable ascii char */
- *norm_utf7_p = *from_tmp;
- norm_utf7_p++;
- norm_utf7_len--;
- from_tmp++;
- from_len--;
- } else {
- size_t conv_len = 0;
-
- /* unprintable char: convert to UTF-7 */
- p = from_tmp;
- while (!g_ascii_isprint(*p) && conv_len < from_len) {
- conv_len += g_utf8_skip[*(guchar *)p];
- p += g_utf8_skip[*(guchar *)p];
- }
-
- from_len -= conv_len;
- if (iconv(cd, (ICONV_CONST gchar **)&from_tmp,
- &conv_len,
- &norm_utf7_p, &norm_utf7_len) == -1) {
- g_warning("iconv cannot convert %s to UTF-7\n",
- CS_INTERNAL);
- return g_strdup(from);
- }
-
- /* second iconv() call for flushing */
- iconv(cd, NULL, NULL, &norm_utf7_p, &norm_utf7_len);
- }
- }
-
- *norm_utf7_p = '\0';
- to_str = g_string_new(NULL);
- for (p = norm_utf7; p < norm_utf7_p; p++) {
- /* replace: '&' -> "&-",
- '+' -> '&',
- "+-" -> '+',
- BASE64 '/' -> ',' */
- if (!in_escape && *p == '&') {
- g_string_append(to_str, "&-");
- } else if (!in_escape && *p == '+') {
- if (*(p + 1) == '-') {
- g_string_append_c(to_str, '+');
- p++;
- } else {
- g_string_append_c(to_str, '&');
- in_escape = TRUE;
- }
- } else if (in_escape && *p == '/') {
- g_string_append_c(to_str, ',');
- } else if (in_escape && *p == '-') {
- g_string_append_c(to_str, '-');
- in_escape = FALSE;
- } else {
- g_string_append_c(to_str, *p);
- }
- }
-
- if (in_escape) {
- in_escape = FALSE;
- g_string_append_c(to_str, '-');
- }
-
- to = to_str->str;
- g_string_free(to_str, FALSE);
-
- return to;
-}
-
-static GSList *imap_get_seq_set_from_msglist(GSList *msglist)
-{
- GString *str;
- GSList *sorted_list, *cur;
- guint first, last, next;
- gchar *ret_str;
- GSList *ret_list = NULL;
-
- if (msglist == NULL)
- return NULL;
-
- str = g_string_sized_new(256);
-
- sorted_list = g_slist_copy(msglist);
- sorted_list = procmsg_sort_msg_list(sorted_list, SORT_BY_NUMBER,
- SORT_ASCENDING);
-
- first = ((MsgInfo *)sorted_list->data)->msgnum;
-
- for (cur = sorted_list; cur != NULL; cur = cur->next) {
- last = ((MsgInfo *)cur->data)->msgnum;
- if (cur->next)
- next = ((MsgInfo *)cur->next->data)->msgnum;
- else
- next = 0;
-
- if (last + 1 != next || next == 0) {
- if (str->len > 0)
- g_string_append_c(str, ',');
- if (first == last)
- g_string_sprintfa(str, "%u", first);
- else
- g_string_sprintfa(str, "%u:%u", first, last);
-
- first = next;
-
- if (str->len > IMAP_CMD_LIMIT) {
- ret_str = g_strdup(str->str);
- ret_list = g_slist_append(ret_list, ret_str);
- g_string_truncate(str, 0);
- }
- }
- }
-
- if (str->len > 0) {
- ret_str = g_strdup(str->str);
- ret_list = g_slist_append(ret_list, ret_str);
- }
-
- g_slist_free(sorted_list);
- g_string_free(str, TRUE);
-
- return ret_list;
-}
-
-static void imap_seq_set_free(GSList *seq_list)
-{
- slist_free_strings(seq_list);
- g_slist_free(seq_list);
-}
-
-static GHashTable *imap_get_uid_table(GArray *array)
-{
- GHashTable *table;
- gint i;
- guint32 uid;
-
- g_return_val_if_fail(array != NULL, NULL);
-
- table = g_hash_table_new(NULL, g_direct_equal);
-
- for (i = 0; i < array->len; i++) {
- uid = g_array_index(array, guint32, i);
- g_hash_table_insert(table, GUINT_TO_POINTER(uid),
- GINT_TO_POINTER(i + 1));
- }
-
- return table;
-}
-
-static gboolean imap_rename_folder_func(GNode *node, gpointer data)
-{
- FolderItem *item = node->data;
- gchar **paths = data;
- const gchar *oldpath = paths[0];
- const gchar *newpath = paths[1];
- gchar *base;
- gchar *new_itempath;
- gint oldpathlen;
-
- oldpathlen = strlen(oldpath);
- if (strncmp(oldpath, item->path, oldpathlen) != 0) {
- g_warning("path doesn't match: %s, %s\n", oldpath, item->path);
- return TRUE;
- }
-
- base = item->path + oldpathlen;
- while (*base == G_DIR_SEPARATOR) base++;
- if (*base == '\0')
- new_itempath = g_strdup(newpath);
- else
- new_itempath = g_strconcat(newpath, G_DIR_SEPARATOR_S, base,
- NULL);
- g_free(item->path);
- item->path = new_itempath;
-
- return FALSE;
-}
diff --git a/src/imap.h b/src/imap.h
deleted file mode 100644
index c726c875..00000000
--- a/src/imap.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __IMAP_H__
-#define __IMAP_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <time.h>
-
-#include "folder.h"
-#include "session.h"
-#include "procmsg.h"
-
-typedef struct _IMAPFolder IMAPFolder;
-typedef struct _IMAPSession IMAPSession;
-typedef struct _IMAPNameSpace IMAPNameSpace;
-
-#define IMAP_FOLDER(obj) ((IMAPFolder *)obj)
-#define IMAP_SESSION(obj) ((IMAPSession *)obj)
-
-#include "prefs_account.h"
-
-typedef enum
-{
- IMAP_AUTH_LOGIN = 1 << 0,
- IMAP_AUTH_CRAM_MD5 = 1 << 1
-} IMAPAuthType;
-
-struct _IMAPFolder
-{
- RemoteFolder rfolder;
-
- /* list of IMAPNameSpace */
- GList *ns_personal;
- GList *ns_others;
- GList *ns_shared;
-};
-
-struct _IMAPSession
-{
- Session session;
-
- gboolean authenticated;
-
- gchar **capability;
- gboolean uidplus;
-
- gchar *mbox;
- guint cmd_count;
-};
-
-struct _IMAPNameSpace
-{
- gchar *name;
- gchar separator;
-};
-
-#define IMAP_SUCCESS 0
-#define IMAP_SOCKET 2
-#define IMAP_AUTHFAIL 3
-#define IMAP_PROTOCOL 4
-#define IMAP_SYNTAX 5
-#define IMAP_IOERR 6
-#define IMAP_ERROR 7
-
-#define IMAPBUFSIZE 8192
-
-typedef enum
-{
- IMAP_FLAG_SEEN = 1 << 0,
- IMAP_FLAG_ANSWERED = 1 << 1,
- IMAP_FLAG_FLAGGED = 1 << 2,
- IMAP_FLAG_DELETED = 1 << 3,
- IMAP_FLAG_DRAFT = 1 << 4
-} IMAPFlags;
-
-#define IMAP_IS_SEEN(flags) ((flags & IMAP_FLAG_SEEN) != 0)
-#define IMAP_IS_ANSWERED(flags) ((flags & IMAP_FLAG_ANSWERED) != 0)
-#define IMAP_IS_FLAGGED(flags) ((flags & IMAP_FLAG_FLAGGED) != 0)
-#define IMAP_IS_DELETED(flags) ((flags & IMAP_FLAG_DELETED) != 0)
-#define IMAP_IS_DRAFT(flags) ((flags & IMAP_FLAG_DRAFT) != 0)
-
-FolderClass *imap_get_class (void);
-
-gint imap_msg_set_perm_flags (MsgInfo *msginfo,
- MsgPermFlags flags);
-gint imap_msg_unset_perm_flags (MsgInfo *msginfo,
- MsgPermFlags flags);
-gint imap_msg_list_set_perm_flags (GSList *msglist,
- MsgPermFlags flags);
-gint imap_msg_list_unset_perm_flags (GSList *msglist,
- MsgPermFlags flags);
-
-#endif /* __IMAP_H__ */
diff --git a/src/main.c b/src/main.c
index 5656fa8f..55fe685d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -561,6 +561,9 @@ static void check_gpg(void)
engineInfo = engineInfo->next;
}
}
+
+ procmsg_set_decrypt_message_func
+ (rfc2015_open_message_decrypted);
} else {
if (prefs_common.gpg_warning) {
AlertValue val;
diff --git a/src/md5.c b/src/md5.c
deleted file mode 100644
index 54585971..00000000
--- a/src/md5.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/* md5.c - MD5 Message-Digest Algorithm
- * Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
- *
- * according to the definition of MD5 in RFC 1321 from April 1992.
- * NOTE: This is *not* the same file as the one from glibc.
- *
- * 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 2, 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, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */
-/* heavily modified for GnuPG by <werner.koch@guug.de> */
-/* modified again for Sylpheed by <wk@gnupg.org> 2001-02-11 */
-
-
-/* Test values:
- * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E
- * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61
- * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72
- * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0
- */
-
-#include <config.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "utils.h"
-#include "md5.h"
-
-
-/****************
- * Rotate a 32 bit integer by n bytes
- */
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-rol( u32 x, int n)
-{
- __asm__("roll %%cl,%0"
- :"=r" (x)
- :"0" (x),"c" (n));
- return x;
-}
-#else
-#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
-#endif
-
-
-void
-md5_init(MD5_CONTEXT *ctx)
-{
- ctx->A = 0x67452301;
- ctx->B = 0xefcdab89;
- ctx->C = 0x98badcfe;
- ctx->D = 0x10325476;
-
- ctx->nblocks = 0;
- ctx->count = 0;
- ctx->finalized = 0;
-}
-
-/* These are the four functions used in the four steps of the MD5 algorithm
- and defined in the RFC 1321. The first function is a little bit optimized
- (as found in Colin Plumbs public domain implementation). */
-/* #define FF(b, c, d) ((b & c) | (~b & d)) */
-#define FF(b, c, d) (d ^ (b & (c ^ d)))
-#define FG(b, c, d) FF (d, b, c)
-#define FH(b, c, d) (b ^ c ^ d)
-#define FI(b, c, d) (c ^ (b | ~d))
-
-
-/****************
- * transform n*64 bytes
- */
-static void
-transform(MD5_CONTEXT *ctx, const unsigned char *data)
-{
- u32 correct_words[16];
- u32 A = ctx->A;
- u32 B = ctx->B;
- u32 C = ctx->C;
- u32 D = ctx->D;
- u32 *cwp = correct_words;
-
-#ifdef BIG_ENDIAN_HOST
- {
- int i;
- unsigned char *p2, *p1;
-
- for (i = 0, p1 = data, p2 = (unsigned char*)correct_words;
- i < 16; i++, p2 += 4) {
- p2[3] = *p1++;
- p2[2] = *p1++;
- p2[1] = *p1++;
- p2[0] = *p1++;
- }
- }
-#else
- memcpy(correct_words, data, 64);
-#endif
-
-
-#define OP(a, b, c, d, s, T) \
- do { \
- a += FF (b, c, d) + (*cwp++) + T; \
- a = rol(a, s); \
- a += b; \
- } while (0)
-
- /* Before we start, one word about the strange constants.
- They are defined in RFC 1321 as
-
- T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
- */
-
- /* Round 1. */
- OP (A, B, C, D, 7, 0xd76aa478);
- OP (D, A, B, C, 12, 0xe8c7b756);
- OP (C, D, A, B, 17, 0x242070db);
- OP (B, C, D, A, 22, 0xc1bdceee);
- OP (A, B, C, D, 7, 0xf57c0faf);
- OP (D, A, B, C, 12, 0x4787c62a);
- OP (C, D, A, B, 17, 0xa8304613);
- OP (B, C, D, A, 22, 0xfd469501);
- OP (A, B, C, D, 7, 0x698098d8);
- OP (D, A, B, C, 12, 0x8b44f7af);
- OP (C, D, A, B, 17, 0xffff5bb1);
- OP (B, C, D, A, 22, 0x895cd7be);
- OP (A, B, C, D, 7, 0x6b901122);
- OP (D, A, B, C, 12, 0xfd987193);
- OP (C, D, A, B, 17, 0xa679438e);
- OP (B, C, D, A, 22, 0x49b40821);
-
-#undef OP
-#define OP(f, a, b, c, d, k, s, T) \
- do { \
- a += f (b, c, d) + correct_words[k] + T; \
- a = rol(a, s); \
- a += b; \
- } while (0)
-
- /* Round 2. */
- OP (FG, A, B, C, D, 1, 5, 0xf61e2562);
- OP (FG, D, A, B, C, 6, 9, 0xc040b340);
- OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
- OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa);
- OP (FG, A, B, C, D, 5, 5, 0xd62f105d);
- OP (FG, D, A, B, C, 10, 9, 0x02441453);
- OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
- OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8);
- OP (FG, A, B, C, D, 9, 5, 0x21e1cde6);
- OP (FG, D, A, B, C, 14, 9, 0xc33707d6);
- OP (FG, C, D, A, B, 3, 14, 0xf4d50d87);
- OP (FG, B, C, D, A, 8, 20, 0x455a14ed);
- OP (FG, A, B, C, D, 13, 5, 0xa9e3e905);
- OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8);
- OP (FG, C, D, A, B, 7, 14, 0x676f02d9);
- OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
-
- /* Round 3. */
- OP (FH, A, B, C, D, 5, 4, 0xfffa3942);
- OP (FH, D, A, B, C, 8, 11, 0x8771f681);
- OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
- OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
- OP (FH, A, B, C, D, 1, 4, 0xa4beea44);
- OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9);
- OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60);
- OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
- OP (FH, A, B, C, D, 13, 4, 0x289b7ec6);
- OP (FH, D, A, B, C, 0, 11, 0xeaa127fa);
- OP (FH, C, D, A, B, 3, 16, 0xd4ef3085);
- OP (FH, B, C, D, A, 6, 23, 0x04881d05);
- OP (FH, A, B, C, D, 9, 4, 0xd9d4d039);
- OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
- OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
- OP (FH, B, C, D, A, 2, 23, 0xc4ac5665);
-
- /* Round 4. */
- OP (FI, A, B, C, D, 0, 6, 0xf4292244);
- OP (FI, D, A, B, C, 7, 10, 0x432aff97);
- OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
- OP (FI, B, C, D, A, 5, 21, 0xfc93a039);
- OP (FI, A, B, C, D, 12, 6, 0x655b59c3);
- OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92);
- OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
- OP (FI, B, C, D, A, 1, 21, 0x85845dd1);
- OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f);
- OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
- OP (FI, C, D, A, B, 6, 15, 0xa3014314);
- OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
- OP (FI, A, B, C, D, 4, 6, 0xf7537e82);
- OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
- OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb);
- OP (FI, B, C, D, A, 9, 21, 0xeb86d391);
-
- /* Put checksum in context given as argument. */
- ctx->A += A;
- ctx->B += B;
- ctx->C += C;
- ctx->D += D;
-}
-
-
-
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-void
-md5_update(MD5_CONTEXT *hd, const unsigned char *inbuf, size_t inlen)
-{
- if (hd->count == 64) { /* flush the buffer */
- transform( hd, hd->buf );
- hd->count = 0;
- hd->nblocks++;
- }
- if (!inbuf)
- return;
- if (hd->count) {
- for (; inlen && hd->count < 64; inlen--)
- hd->buf[hd->count++] = *inbuf++;
- md5_update(hd, NULL, 0);
- if (!inlen)
- return;
- }
-
- while (inlen >= 64) {
- transform(hd, inbuf);
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
-
- for (; inlen && hd->count < 64; inlen--)
- hd->buf[hd->count++] = *inbuf++;
-}
-
-
-
-/* The routine final terminates the message-digest computation and
- * ends with the desired message digest in mdContext->digest[0...15].
- * The handle is prepared for a new MD5 cycle.
- * Returns 16 bytes representing the digest.
- */
-
-static void
-do_final(MD5_CONTEXT *hd)
-{
- u32 t, msb, lsb;
- unsigned char *p;
-
- md5_update(hd, NULL, 0); /* flush */
-
- msb = 0;
- t = hd->nblocks;
- if ((lsb = t << 6) < t) /* multiply by 64 to make a byte count */
- msb++;
- msb += t >> 26;
- t = lsb;
- if ((lsb = t + hd->count) < t) /* add the count */
- msb++;
- t = lsb;
- if ((lsb = t << 3) < t) /* multiply by 8 to make a bit count */
- msb++;
- msb += t >> 29;
-
- if (hd->count < 56) { /* enough room */
- hd->buf[hd->count++] = 0x80; /* pad */
- while(hd->count < 56)
- hd->buf[hd->count++] = 0; /* pad */
- } else { /* need one extra block */
- hd->buf[hd->count++] = 0x80; /* pad character */
- while (hd->count < 64)
- hd->buf[hd->count++] = 0;
- md5_update(hd, NULL, 0); /* flush */
- memset(hd->buf, 0, 56); /* fill next block with zeroes */
- }
-
- /* append the 64 bit count */
- hd->buf[56] = lsb ;
- hd->buf[57] = lsb >> 8;
- hd->buf[58] = lsb >> 16;
- hd->buf[59] = lsb >> 24;
- hd->buf[60] = msb ;
- hd->buf[61] = msb >> 8;
- hd->buf[62] = msb >> 16;
- hd->buf[63] = msb >> 24;
- transform(hd, hd->buf);
-
- p = hd->buf;
-#ifdef BIG_ENDIAN_HOST
-#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
- *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
-#else /* little endian */
- /*#define X(a) do { *(u32*)p = hd->##a ; p += 4; } while(0)*/
- /* Unixware's cpp doesn't like the above construct so we do it his way:
- * (reported by Allan Clark) */
-#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
-#endif
- X(A);
- X(B);
- X(C);
- X(D);
-#undef X
- hd->finalized = 1;
-}
-
-void
-md5_final(unsigned char *digest, MD5_CONTEXT *ctx)
-{
- if (!ctx->finalized)
- do_final(ctx);
- memcpy(digest, ctx->buf, 16);
-}
-
-/*
- * Creates a MD5 digest in hex fomrat (lowercase letters) from the
- * string S. hextdigest but be buffer of at lease 33 bytes!
- */
-void
-md5_hex_digest(char *hexdigest, const unsigned char *s)
-{
- int i;
- MD5_CONTEXT context;
- unsigned char digest[16];
-
- md5_init(&context);
- md5_update(&context, s, strlen(s));
- md5_final(digest, &context);
-
- for (i = 0; i < 16; i++)
- sprintf(hexdigest + 2 * i, "%02x", digest[i]);
-}
-
-
-/*
-** Function: md5_hmac
-** taken from the file rfc2104.txt
-** written by Martin Schaaf <mascha@ma-scha.de>
-*/
-void
-md5_hmac(unsigned char *digest,
- const unsigned char* text, int text_len,
- const unsigned char* key, int key_len)
-{
- MD5_CONTEXT context;
- unsigned char k_ipad[64]; /* inner padding -
- * key XORd with ipad
- */
- unsigned char k_opad[64]; /* outer padding -
- * key XORd with opad
- */
- /* unsigned char tk[16]; */
- int i;
-
- /* start out by storing key in pads */
- memset(k_ipad, 0, sizeof k_ipad);
- memset(k_opad, 0, sizeof k_opad);
- if (key_len > 64) {
- /* if key is longer than 64 bytes reset it to key=MD5(key) */
- MD5_CONTEXT tctx;
-
- md5_init(&tctx);
- md5_update(&tctx, key, key_len);
- md5_final(k_ipad, &tctx);
- md5_final(k_opad, &tctx);
- } else {
- memcpy(k_ipad, key, key_len);
- memcpy(k_opad, key, key_len);
- }
-
- /*
- * the HMAC_MD5 transform looks like:
- *
- * MD5(K XOR opad, MD5(K XOR ipad, text))
- *
- * where K is an n byte key
- * ipad is the byte 0x36 repeated 64 times
- * opad is the byte 0x5c repeated 64 times
- * and text is the data being protected
- */
-
-
- /* XOR key with ipad and opad values */
- for (i = 0; i < 64; i++) {
- k_ipad[i] ^= 0x36;
- k_opad[i] ^= 0x5c;
- }
-
- /*
- * perform inner MD5
- */
- md5_init(&context); /* init context for 1st
- * pass */
- md5_update(&context, k_ipad, 64); /* start with inner pad */
- md5_update(&context, text, text_len); /* then text of datagram */
- md5_final(digest, &context); /* finish up 1st pass */
- /*
- * perform outer MD5
- */
- md5_init(&context); /* init context for 2nd
- * pass */
- md5_update(&context, k_opad, 64); /* start with outer pad */
- md5_update(&context, digest, 16); /* then results of 1st
- * hash */
- md5_final(digest, &context); /* finish up 2nd pass */
-}
-
-
-void
-md5_hex_hmac(char *hexdigest,
- const unsigned char* text, int text_len,
- const unsigned char* key, int key_len)
-{
- unsigned char digest[16];
- int i;
-
- md5_hmac(digest, text, text_len, key, key_len);
- for (i = 0; i < 16; i++)
- sprintf(hexdigest + 2 * i, "%02x", digest[i]);
-}
diff --git a/src/md5.h b/src/md5.h
deleted file mode 100644
index 84894b2c..00000000
--- a/src/md5.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* md5.h - MD5 Message-Digest Algorithm
- * Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
- *
- * according to the definition of MD5 in RFC 1321 from April 1992.
- * NOTE: This is *not* the same file as the one from glibc
- *
- * 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 2, 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, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef _MD5_HDR_
-#define _MD5_HDR_
-
-#include "utils.h"
-
-typedef struct { /* Hmm, should be private */
- u32 A,B,C,D;
- u32 nblocks;
- unsigned char buf[64];
- int count;
- int finalized;
-} MD5_CONTEXT;
-
-void md5_init(MD5_CONTEXT *ctx);
-void md5_update(MD5_CONTEXT *hd, const unsigned char *inbuf, size_t inlen);
-void md5_final(unsigned char *digest, MD5_CONTEXT *ctx);
-
-void md5_hex_digest(char *hexdigest, const unsigned char *s);
-
-void md5_hmac(unsigned char *digest,
- const unsigned char* text, int text_len,
- const unsigned char* key, int key_len);
-void md5_hex_hmac(char *hexdigest,
- const unsigned char* text, int text_len,
- const unsigned char* key, int key_len);
-
-#endif /* _MD5_HDR_ */
-
diff --git a/src/mh.c b/src/mh.c
deleted file mode 100644
index 40554867..00000000
--- a/src/mh.c
+++ /dev/null
@@ -1,1431 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#undef MEASURE_TIME
-
-#include "folder.h"
-#include "mh.h"
-#include "procmsg.h"
-#include "procheader.h"
-#include "utils.h"
-#include "prefs_common.h"
-
-static void mh_folder_init (Folder *folder,
- const gchar *name,
- const gchar *path);
-
-static Folder *mh_folder_new (const gchar *name,
- const gchar *path);
-static void mh_folder_destroy (Folder *folder);
-
-static GSList *mh_get_msg_list (Folder *folder,
- FolderItem *item,
- gboolean use_cache);
-static gchar *mh_fetch_msg (Folder *folder,
- FolderItem *item,
- gint num);
-static MsgInfo *mh_get_msginfo (Folder *folder,
- FolderItem *item,
- gint num);
-static gint mh_add_msg (Folder *folder,
- FolderItem *dest,
- const gchar *file,
- MsgFlags *flags,
- gboolean remove_source);
-static gint mh_add_msgs (Folder *folder,
- FolderItem *dest,
- GSList *file_list,
- gboolean remove_source,
- gint *first);
-static gint mh_move_msg (Folder *folder,
- FolderItem *dest,
- MsgInfo *msginfo);
-static gint mh_move_msgs (Folder *folder,
- FolderItem *dest,
- GSList *msglist);
-static gint mh_copy_msg (Folder *folder,
- FolderItem *dest,
- MsgInfo *msginfo);
-static gint mh_copy_msgs (Folder *folder,
- FolderItem *dest,
- GSList *msglist);
-static gint mh_remove_msg (Folder *folder,
- FolderItem *item,
- MsgInfo *msginfo);
-static gint mh_remove_all_msg (Folder *folder,
- FolderItem *item);
-static gboolean mh_is_msg_changed (Folder *folder,
- FolderItem *item,
- MsgInfo *msginfo);
-static gint mh_close (Folder *folder,
- FolderItem *item);
-
-static gint mh_scan_folder_full (Folder *folder,
- FolderItem *item,
- gboolean count_sum);
-static gint mh_scan_folder (Folder *folder,
- FolderItem *item);
-static gint mh_scan_tree (Folder *folder);
-
-static gint mh_create_tree (Folder *folder);
-static FolderItem *mh_create_folder (Folder *folder,
- FolderItem *parent,
- const gchar *name);
-static gint mh_rename_folder (Folder *folder,
- FolderItem *item,
- const gchar *name);
-static gint mh_move_folder (Folder *folder,
- FolderItem *item,
- FolderItem *new_parent);
-static gint mh_remove_folder (Folder *folder,
- FolderItem *item);
-
-static gchar *mh_get_new_msg_filename (FolderItem *dest);
-
-static gint mh_do_move_msgs (Folder *folder,
- FolderItem *dest,
- GSList *msglist);
-
-static time_t mh_get_mtime (FolderItem *item);
-static GSList *mh_get_uncached_msgs (GHashTable *msg_table,
- FolderItem *item);
-static MsgInfo *mh_parse_msg (const gchar *file,
- FolderItem *item);
-static void mh_remove_missing_folder_items (Folder *folder);
-static void mh_scan_tree_recursive (FolderItem *item);
-
-static gboolean mh_rename_folder_func (GNode *node,
- gpointer data);
-
-static FolderClass mh_class =
-{
- F_MH,
-
- mh_folder_new,
- mh_folder_destroy,
-
- mh_scan_tree,
- mh_create_tree,
-
- mh_get_msg_list,
- mh_fetch_msg,
- mh_get_msginfo,
- mh_add_msg,
- mh_add_msgs,
- mh_move_msg,
- mh_move_msgs,
- mh_copy_msg,
- mh_copy_msgs,
- mh_remove_msg,
- NULL,
- mh_remove_all_msg,
- mh_is_msg_changed,
- mh_close,
- mh_scan_folder,
-
- mh_create_folder,
- mh_rename_folder,
- mh_move_folder,
- mh_remove_folder,
-};
-
-
-FolderClass *mh_get_class(void)
-{
- return &mh_class;
-}
-
-static Folder *mh_folder_new(const gchar *name, const gchar *path)
-{
- Folder *folder;
-
- folder = (Folder *)g_new0(MHFolder, 1);
- mh_folder_init(folder, name, path);
-
- return folder;
-}
-
-static void mh_folder_destroy(Folder *folder)
-{
- folder_local_folder_destroy(LOCAL_FOLDER(folder));
-}
-
-static void mh_folder_init(Folder *folder, const gchar *name, const gchar *path)
-{
- folder->klass = mh_get_class();
- folder_local_folder_init(folder, name, path);
-}
-
-static GSList *mh_get_msg_list(Folder *folder, FolderItem *item,
- gboolean use_cache)
-{
- GSList *mlist;
- GHashTable *msg_table;
- time_t cur_mtime;
-#ifdef MEASURE_TIME
- GTimer *timer;
-#endif
-
- g_return_val_if_fail(item != NULL, NULL);
-
-#ifdef MEASURE_TIME
- timer = g_timer_new();
-#endif
-
- cur_mtime = mh_get_mtime(item);
-
- if (use_cache && item->mtime == cur_mtime) {
- debug_print("Folder is not modified.\n");
- mlist = procmsg_read_cache(item, FALSE);
- if (!mlist) {
- mlist = mh_get_uncached_msgs(NULL, item);
- if (mlist)
- item->cache_dirty = TRUE;
- }
- } else if (use_cache) {
- GSList *newlist, *cur, *next;
- gboolean strict_cache_check = prefs_common.strict_cache_check;
-
- if (item->stype == F_QUEUE || item->stype == F_DRAFT)
- strict_cache_check = TRUE;
-
- mlist = procmsg_read_cache(item, strict_cache_check);
- msg_table = procmsg_msg_hash_table_create(mlist);
- newlist = mh_get_uncached_msgs(msg_table, item);
- if (newlist)
- item->cache_dirty = TRUE;
- if (msg_table)
- g_hash_table_destroy(msg_table);
-
- if (!strict_cache_check) {
- /* remove nonexistent messages */
- for (cur = mlist; cur != NULL; cur = next) {
- MsgInfo *msginfo = (MsgInfo *)cur->data;
- next = cur->next;
- if (!MSG_IS_CACHED(msginfo->flags)) {
- debug_print("removing nonexistent message %d from cache\n", msginfo->msgnum);
- mlist = g_slist_remove(mlist, msginfo);
- procmsg_msginfo_free(msginfo);
- item->cache_dirty = TRUE;
- item->mark_dirty = TRUE;
- }
- }
- }
-
- mlist = g_slist_concat(mlist, newlist);
- } else {
- mlist = mh_get_uncached_msgs(NULL, item);
- item->cache_dirty = TRUE;
- }
-
- item->mtime = cur_mtime;
-
- procmsg_set_flags(mlist, item);
-
- mlist = procmsg_sort_msg_list(mlist, item->sort_key, item->sort_type);
-
-#ifdef MEASURE_TIME
- g_timer_stop(timer);
- g_print("%s: %s: elapsed time: %f sec\n",
- G_STRFUNC, item->path, g_timer_elapsed(timer, NULL));
- g_timer_destroy(timer);
-#endif
- debug_print("cache_dirty: %d, mark_dirty: %d\n",
- item->cache_dirty, item->mark_dirty);
-
- return mlist;
-}
-
-static gchar *mh_fetch_msg(Folder *folder, FolderItem *item, gint num)
-{
- gchar *path;
- gchar *file;
-
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(num > 0, NULL);
-
- if (item->last_num < 0 || num > item->last_num) {
- mh_scan_folder(folder, item);
- if (item->last_num < 0) return NULL;
- }
-
- g_return_val_if_fail(num <= item->last_num, NULL);
-
- path = folder_item_get_path(item);
- file = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL);
- g_free(path);
- if (!is_file_exist(file)) {
- g_free(file);
- return NULL;
- }
-
- return file;
-}
-
-static MsgInfo *mh_get_msginfo(Folder *folder, FolderItem *item, gint num)
-{
- MsgInfo *msginfo;
- gchar *file;
-
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(num > 0, NULL);
-
- file = mh_fetch_msg(folder, item, num);
- if (!file) return NULL;
-
- msginfo = mh_parse_msg(file, item);
- if (msginfo)
- msginfo->msgnum = num;
-
- g_free(file);
-
- return msginfo;
-}
-
-static gchar *mh_get_new_msg_filename(FolderItem *dest)
-{
- gchar *destfile;
- gchar *destpath;
-
- destpath = folder_item_get_path(dest);
- g_return_val_if_fail(destpath != NULL, NULL);
-
- if (!is_dir_exist(destpath))
- make_dir_hier(destpath);
-
- for (;;) {
- destfile = g_strdup_printf("%s%c%d", destpath, G_DIR_SEPARATOR,
- dest->last_num + 1);
- if (is_file_entry_exist(destfile)) {
- dest->last_num++;
- g_free(destfile);
- } else
- break;
- }
-
- g_free(destpath);
-
- return destfile;
-}
-
-#define SET_DEST_MSG_FLAGS(fp, dest, n, fl) \
-{ \
- MsgInfo newmsginfo; \
- \
- newmsginfo.msgnum = n; \
- newmsginfo.flags = fl; \
- if (dest->stype == F_OUTBOX || \
- dest->stype == F_QUEUE || \
- dest->stype == F_DRAFT || \
- dest->stype == F_TRASH) \
- MSG_UNSET_PERM_FLAGS(newmsginfo.flags, \
- MSG_NEW|MSG_UNREAD|MSG_DELETED); \
- \
- if (fp) \
- procmsg_write_flags(&newmsginfo, fp); \
- else if (dest->opened) \
- procmsg_add_flags(dest, n, newmsginfo.flags); \
-}
-
-static gint mh_add_msg(Folder *folder, FolderItem *dest, const gchar *file,
- MsgFlags *flags, gboolean remove_source)
-{
- GSList file_list;
- MsgFileInfo fileinfo;
-
- g_return_val_if_fail(file != NULL, -1);
-
- fileinfo.file = (gchar *)file;
- fileinfo.flags = flags;
- file_list.data = &fileinfo;
- file_list.next = NULL;
-
- return mh_add_msgs(folder, dest, &file_list, remove_source, NULL);
-}
-
-static gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
- gboolean remove_source, gint *first)
-{
- gchar *destfile;
- GSList *cur;
- MsgFileInfo *fileinfo;
- gint first_ = 0;
- FILE *fp;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(file_list != NULL, -1);
-
- if (dest->last_num < 0) {
- mh_scan_folder(folder, dest);
- if (dest->last_num < 0) return -1;
- }
-
- if ((((MsgFileInfo *)file_list->data)->flags == NULL &&
- file_list->next == NULL) || dest->opened)
- fp = NULL;
- else if ((fp = procmsg_open_mark_file(dest, DATA_APPEND)) == NULL)
- g_warning("Can't open mark file.\n");
-
- for (cur = file_list; cur != NULL; cur = cur->next) {
- fileinfo = (MsgFileInfo *)cur->data;
-
- destfile = mh_get_new_msg_filename(dest);
- if (destfile == NULL) return -1;
- if (first_ == 0 || first_ > dest->last_num + 1)
- first_ = dest->last_num + 1;
-
-#ifdef G_OS_UNIX
- if (link(fileinfo->file, destfile) < 0) {
-#endif
- if (copy_file(fileinfo->file, destfile, TRUE) < 0) {
- g_warning(_("can't copy message %s to %s\n"),
- fileinfo->file, destfile);
- g_free(destfile);
- return -1;
- }
-#ifdef G_OS_UNIX
- }
-#endif
-
- g_free(destfile);
- dest->last_num++;
- dest->total++;
- dest->updated = TRUE;
-
- if (fileinfo->flags) {
- if (MSG_IS_RECEIVED(*fileinfo->flags)) {
- if (dest->unmarked_num == 0)
- dest->new = 0;
- dest->unmarked_num++;
- procmsg_add_mark_queue(dest, dest->last_num,
- *fileinfo->flags);
- } else {
- SET_DEST_MSG_FLAGS(fp, dest, dest->last_num,
- *fileinfo->flags);
- }
- if (MSG_IS_NEW(*fileinfo->flags))
- dest->new++;
- if (MSG_IS_UNREAD(*fileinfo->flags))
- dest->unread++;
- } else {
- if (dest->unmarked_num == 0)
- dest->new = 0;
- dest->unmarked_num++;
- dest->new++;
- dest->unread++;
- }
- }
-
- if (fp) fclose(fp);
-
- if (first)
- *first = first_;
-
- if (remove_source) {
- for (cur = file_list; cur != NULL; cur = cur->next) {
- fileinfo = (MsgFileInfo *)cur->data;
- if (g_unlink(fileinfo->file) < 0)
- FILE_OP_ERROR(fileinfo->file, "unlink");
- }
- }
-
- return dest->last_num;
-}
-
-static gint mh_do_move_msgs(Folder *folder, FolderItem *dest, GSList *msglist)
-{
- FolderItem *src;
- gchar *srcfile;
- gchar *destfile;
- FILE *fp;
- GSList *cur;
- MsgInfo *msginfo;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
-
- if (dest->last_num < 0) {
- mh_scan_folder(folder, dest);
- if (dest->last_num < 0) return -1;
- }
-
- if (dest->opened)
- fp = NULL;
- else if ((fp = procmsg_open_mark_file(dest, DATA_APPEND)) == NULL)
- g_warning(_("Can't open mark file.\n"));
-
- for (cur = msglist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- src = msginfo->folder;
-
- if (src == dest) {
- g_warning(_("the src folder is identical to the dest.\n"));
- continue;
- }
- debug_print("Moving message %s%c%d to %s ...\n",
- src->path, G_DIR_SEPARATOR, msginfo->msgnum,
- dest->path);
-
- destfile = mh_get_new_msg_filename(dest);
- if (!destfile) break;
- srcfile = procmsg_get_message_file(msginfo);
-
- if (move_file(srcfile, destfile, FALSE) < 0) {
- g_free(srcfile);
- g_free(destfile);
- break;
- }
-
- g_free(srcfile);
- g_free(destfile);
- src->total--;
- src->updated = TRUE;
- dest->last_num++;
- dest->total++;
- dest->updated = TRUE;
-
- if (fp) {
- SET_DEST_MSG_FLAGS(fp, dest, dest->last_num,
- msginfo->flags);
- }
-
- if (MSG_IS_NEW(msginfo->flags)) {
- src->new--;
- dest->new++;
- }
- if (MSG_IS_UNREAD(msginfo->flags)) {
- src->unread--;
- dest->unread++;
- }
-
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_INVALID);
- }
-
- if (fp) fclose(fp);
-
- return dest->last_num;
-}
-
-static gint mh_move_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
-{
- GSList msglist;
-
- g_return_val_if_fail(msginfo != NULL, -1);
-
- msglist.data = msginfo;
- msglist.next = NULL;
-
- return mh_move_msgs(folder, dest, &msglist);
-}
-
-static gint mh_move_msgs(Folder *folder, FolderItem *dest, GSList *msglist)
-{
- MsgInfo *msginfo;
- GSList *file_list;
- gint ret = 0;
- gint first;
-
- msginfo = (MsgInfo *)msglist->data;
- if (folder == msginfo->folder->folder)
- return mh_do_move_msgs(folder, dest, msglist);
-
- file_list = procmsg_get_message_file_list(msglist);
- g_return_val_if_fail(file_list != NULL, -1);
-
- ret = mh_add_msgs(folder, dest, file_list, FALSE, &first);
-
- procmsg_message_file_list_free(file_list);
-
- if (ret != -1)
- ret = folder_item_remove_msgs(msginfo->folder, msglist);
-
- return ret;
-}
-
-static gint mh_copy_msg(Folder *folder, FolderItem *dest, MsgInfo *msginfo)
-{
- GSList msglist;
-
- g_return_val_if_fail(msginfo != NULL, -1);
-
- msglist.data = msginfo;
- msglist.next = NULL;
-
- return mh_copy_msgs(folder, dest, &msglist);
-}
-
-static gint mh_copy_msgs(Folder *folder, FolderItem *dest, GSList *msglist)
-{
- gchar *srcfile;
- gchar *destfile;
- FILE *fp;
- GSList *cur;
- MsgInfo *msginfo;
-
- g_return_val_if_fail(dest != NULL, -1);
- g_return_val_if_fail(msglist != NULL, -1);
-
- if (dest->last_num < 0) {
- mh_scan_folder(folder, dest);
- if (dest->last_num < 0) return -1;
- }
-
- if (dest->opened)
- fp = NULL;
- else if ((fp = procmsg_open_mark_file(dest, DATA_APPEND)) == NULL)
- g_warning(_("Can't open mark file.\n"));
-
- for (cur = msglist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
-
- if (msginfo->folder == dest) {
- g_warning(_("the src folder is identical to the dest.\n"));
- continue;
- }
- debug_print(_("Copying message %s%c%d to %s ...\n"),
- msginfo->folder->path, G_DIR_SEPARATOR,
- msginfo->msgnum, dest->path);
-
- destfile = mh_get_new_msg_filename(dest);
- if (!destfile) break;
- srcfile = procmsg_get_message_file(msginfo);
-
- if (copy_file(srcfile, destfile, TRUE) < 0) {
- FILE_OP_ERROR(srcfile, "copy");
- g_free(srcfile);
- g_free(destfile);
- break;
- }
-
- g_free(srcfile);
- g_free(destfile);
- dest->last_num++;
- dest->total++;
- dest->updated = TRUE;
-
- if (fp) {
- SET_DEST_MSG_FLAGS(fp, dest, dest->last_num,
- msginfo->flags);
- }
-
- if (MSG_IS_NEW(msginfo->flags))
- dest->new++;
- if (MSG_IS_UNREAD(msginfo->flags))
- dest->unread++;
- }
-
- if (fp) fclose(fp);
-
- return dest->last_num;
-}
-
-static gint mh_remove_msg(Folder *folder, FolderItem *item, MsgInfo *msginfo)
-{
- gchar *file;
-
- g_return_val_if_fail(item != NULL, -1);
-
- file = mh_fetch_msg(folder, item, msginfo->msgnum);
- g_return_val_if_fail(file != NULL, -1);
-
- if (g_unlink(file) < 0) {
- FILE_OP_ERROR(file, "unlink");
- g_free(file);
- return -1;
- }
- g_free(file);
-
- item->total--;
- item->updated = TRUE;
- if (MSG_IS_NEW(msginfo->flags))
- item->new--;
- if (MSG_IS_UNREAD(msginfo->flags))
- item->unread--;
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_INVALID);
-
- if (msginfo->msgnum == item->last_num)
- mh_scan_folder_full(folder, item, FALSE);
-
- return 0;
-}
-
-static gint mh_remove_all_msg(Folder *folder, FolderItem *item)
-{
- gchar *path;
- gint val;
-
- g_return_val_if_fail(item != NULL, -1);
-
- path = folder_item_get_path(item);
- g_return_val_if_fail(path != NULL, -1);
- val = remove_all_numbered_files(path);
- g_free(path);
- if (val == 0) {
- item->new = item->unread = item->total = 0;
- item->last_num = 0;
- item->updated = TRUE;
- }
-
- return val;
-}
-
-static gboolean mh_is_msg_changed(Folder *folder, FolderItem *item,
- MsgInfo *msginfo)
-{
- struct stat s;
-
- if (g_stat(itos(msginfo->msgnum), &s) < 0 ||
- msginfo->size != s.st_size ||
- msginfo->mtime != s.st_mtime)
- return TRUE;
-
- return FALSE;
-}
-
-static gint mh_close(Folder *folder, FolderItem *item)
-{
- return 0;
-}
-
-static gint mh_scan_folder_full(Folder *folder, FolderItem *item,
- gboolean count_sum)
-{
- gchar *path;
- DIR *dp;
- struct dirent *d;
- gint max = 0;
- gint num;
- gint n_msg = 0;
-
- g_return_val_if_fail(item != NULL, -1);
-
- debug_print("mh_scan_folder(): Scanning %s ...\n", item->path);
-
- path = folder_item_get_path(item);
- g_return_val_if_fail(path != NULL, -1);
- if (change_dir(path) < 0) {
- g_free(path);
- return -1;
- }
- g_free(path);
-
- if ((dp = opendir(".")) == NULL) {
- FILE_OP_ERROR(item->path, "opendir");
- return -1;
- }
-
- if (folder->ui_func)
- folder->ui_func(folder, item, folder->ui_func_data);
-
- while ((d = readdir(dp)) != NULL) {
- if ((num = to_number(d->d_name)) > 0 &&
- dirent_is_regular_file(d)) {
- n_msg++;
- if (max < num)
- max = num;
- }
- }
-
- closedir(dp);
-
- if (n_msg == 0)
- item->new = item->unread = item->total = 0;
- else if (count_sum) {
- gint new, unread, total, min, max_;
-
- procmsg_get_mark_sum
- (item, &new, &unread, &total, &min, &max_, 0);
-
- if (n_msg > total) {
- item->unmarked_num = new = n_msg - total;
- unread += n_msg - total;
- } else
- item->unmarked_num = 0;
-
- item->new = new;
- item->unread = unread;
- item->total = n_msg;
- }
-
- item->updated = TRUE;
-
- debug_print(_("Last number in dir %s = %d\n"), item->path, max);
- item->last_num = max;
-
- return 0;
-}
-
-static gint mh_scan_folder(Folder *folder, FolderItem *item)
-{
- return mh_scan_folder_full(folder, item, TRUE);
-}
-
-static gint mh_scan_tree(Folder *folder)
-{
- FolderItem *item;
- gchar *rootpath;
-
- g_return_val_if_fail(folder != NULL, -1);
-
- if (!folder->node) {
- item = folder_item_new(folder->name, NULL);
- item->folder = folder;
- folder->node = item->node = g_node_new(item);
- } else
- item = FOLDER_ITEM(folder->node->data);
-
- rootpath = folder_item_get_path(item);
- if (change_dir(rootpath) < 0) {
- g_free(rootpath);
- return -1;
- }
- g_free(rootpath);
-
- mh_create_tree(folder);
- mh_remove_missing_folder_items(folder);
- mh_scan_tree_recursive(item);
-
- return 0;
-}
-
-#define MAKE_DIR_IF_NOT_EXIST(dir) \
-{ \
- if (!is_dir_exist(dir)) { \
- if (is_file_exist(dir)) { \
- g_warning(_("File `%s' already exists.\n" \
- "Can't create folder."), dir); \
- return -1; \
- } \
- if (make_dir(dir) < 0) \
- return -1; \
- } \
-}
-
-static gint mh_create_tree(Folder *folder)
-{
- gchar *rootpath;
-
- g_return_val_if_fail(folder != NULL, -1);
-
- CHDIR_RETURN_VAL_IF_FAIL(get_mail_base_dir(), -1);
- rootpath = LOCAL_FOLDER(folder)->rootpath;
- MAKE_DIR_IF_NOT_EXIST(rootpath);
- CHDIR_RETURN_VAL_IF_FAIL(rootpath, -1);
- MAKE_DIR_IF_NOT_EXIST(INBOX_DIR);
- MAKE_DIR_IF_NOT_EXIST(OUTBOX_DIR);
- MAKE_DIR_IF_NOT_EXIST(QUEUE_DIR);
- MAKE_DIR_IF_NOT_EXIST(DRAFT_DIR);
- MAKE_DIR_IF_NOT_EXIST(TRASH_DIR);
-
- return 0;
-}
-
-#undef MAKE_DIR_IF_NOT_EXIST
-
-static FolderItem *mh_create_folder(Folder *folder, FolderItem *parent,
- const gchar *name)
-{
- gchar *path;
- gchar *fs_name;
- gchar *fullpath;
- FolderItem *new_item;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(parent != NULL, NULL);
- g_return_val_if_fail(name != NULL, NULL);
-
- path = folder_item_get_path(parent);
- fs_name = g_filename_from_utf8(name, -1, NULL, NULL, NULL);
- fullpath = g_strconcat(path, G_DIR_SEPARATOR_S,
- fs_name ? fs_name : name, NULL);
- g_free(fs_name);
- g_free(path);
-
- if (make_dir(fullpath) < 0) {
- g_free(fullpath);
- return NULL;
- }
-
- g_free(fullpath);
-
- if (parent->path)
- path = g_strconcat(parent->path, G_DIR_SEPARATOR_S, name,
- NULL);
- else
- path = g_strdup(name);
- new_item = folder_item_new(name, path);
- folder_item_append(parent, new_item);
- g_free(path);
-
- return new_item;
-}
-
-static gint mh_move_folder_real(Folder *folder, FolderItem *item,
- FolderItem *new_parent, const gchar *name)
-{
- gchar *oldpath;
- gchar *newpath;
- gchar *dirname;
- gchar *new_dir;
- gchar *name_;
- gchar *utf8_name;
- gchar *paths[2];
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(folder == item->folder, -1);
- g_return_val_if_fail(item->path != NULL, -1);
- g_return_val_if_fail(new_parent != NULL || name != NULL, -1);
- if (new_parent) {
- g_return_val_if_fail(item != new_parent, -1);
- g_return_val_if_fail(item->parent != new_parent, -1);
- g_return_val_if_fail(item->folder == new_parent->folder, -1);
- if (g_node_is_ancestor(item->node, new_parent->node)) {
- g_warning("folder to be moved is ancestor of new parent\n");
- return -1;
- }
- }
-
- oldpath = folder_item_get_path(item);
- if (new_parent) {
- if (name) {
- name_ = g_filename_from_utf8(name, -1, NULL, NULL,
- NULL);
- if (!name_)
- name_ = g_strdup(name);
- utf8_name = g_strdup(name);
- } else {
- name_ = g_path_get_basename(oldpath);
- utf8_name = g_filename_to_utf8(name_, -1, NULL, NULL,
- NULL);
- if (!utf8_name)
- utf8_name = g_strdup(name_);
- }
- new_dir = folder_item_get_path(new_parent);
- newpath = g_strconcat(new_dir, G_DIR_SEPARATOR_S, name_, NULL);
- g_free(new_dir);
- } else {
- name_ = g_filename_from_utf8(name, -1, NULL, NULL, NULL);
- utf8_name = g_strdup(name);
- dirname = g_dirname(oldpath);
- newpath = g_strconcat(dirname, G_DIR_SEPARATOR_S,
- name_ ? name_ : name, NULL);
- g_free(dirname);
- }
- g_free(name_);
-
- if (is_file_entry_exist(newpath)) {
- g_warning("%s already exists\n", newpath);
- g_free(oldpath);
- g_free(newpath);
- g_free(utf8_name);
- return -1;
- }
-
- debug_print("mh_move_folder: rename(%s, %s)\n", oldpath, newpath);
-
- if (g_rename(oldpath, newpath) < 0) {
- FILE_OP_ERROR(oldpath, "rename");
- g_free(oldpath);
- g_free(newpath);
- g_free(utf8_name);
- return -1;
- }
-
- g_free(oldpath);
- g_free(newpath);
-
- if (new_parent) {
- g_node_unlink(item->node);
- g_node_append(new_parent->node, item->node);
- item->parent = new_parent;
- if (new_parent->path != NULL) {
- newpath = g_strconcat(new_parent->path,
- G_DIR_SEPARATOR_S, utf8_name,
- NULL);
- g_free(utf8_name);
- } else
- newpath = utf8_name;
- } else {
- if (strchr(item->path, G_DIR_SEPARATOR) != NULL) {
- dirname = g_dirname(item->path);
- newpath = g_strconcat(dirname, G_DIR_SEPARATOR_S,
- utf8_name, NULL);
- g_free(dirname);
- g_free(utf8_name);
- } else
- newpath = utf8_name;
- }
-
- if (name) {
- g_free(item->name);
- item->name = g_strdup(name);
- }
-
- paths[0] = g_strdup(item->path);
- paths[1] = newpath;
- g_node_traverse(item->node, G_PRE_ORDER, G_TRAVERSE_ALL, -1,
- mh_rename_folder_func, paths);
-
- g_free(paths[0]);
- g_free(paths[1]);
-
- return 0;
-}
-
-static gint mh_move_folder(Folder *folder, FolderItem *item,
- FolderItem *new_parent)
-{
- return mh_move_folder_real(folder, item, new_parent, NULL);
-}
-
-static gint mh_rename_folder(Folder *folder, FolderItem *item,
- const gchar *name)
-{
- return mh_move_folder_real(folder, item, NULL, name);
-}
-
-static gint mh_remove_folder(Folder *folder, FolderItem *item)
-{
- gchar *path;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(item != NULL, -1);
- g_return_val_if_fail(item->path != NULL, -1);
-
- path = folder_item_get_path(item);
- if (remove_dir_recursive(path) < 0) {
- g_warning("can't remove directory `%s'\n", path);
- g_free(path);
- return -1;
- }
-
- g_free(path);
- folder_item_remove(item);
- return 0;
-}
-
-
-static time_t mh_get_mtime(FolderItem *item)
-{
- gchar *path;
- struct stat s;
-
- path = folder_item_get_path(item);
- if (g_stat(path, &s) < 0) {
- FILE_OP_ERROR(path, "stat");
- return -1;
- } else {
- return MAX(s.st_mtime, s.st_ctime);
- }
-}
-
-static GSList *mh_get_uncached_msgs(GHashTable *msg_table, FolderItem *item)
-{
- gchar *path;
- DIR *dp;
- struct dirent *d;
- GSList *newlist = NULL;
- GSList *last = NULL;
- MsgInfo *msginfo;
- gint n_newmsg = 0;
- gint num;
-
- g_return_val_if_fail(item != NULL, NULL);
-
- path = folder_item_get_path(item);
- g_return_val_if_fail(path != NULL, NULL);
- if (change_dir(path) < 0) {
- g_free(path);
- return NULL;
- }
- g_free(path);
-
- if ((dp = opendir(".")) == NULL) {
- FILE_OP_ERROR(item->path, "opendir");
- return NULL;
- }
-
- debug_print("Searching uncached messages...\n");
-
- if (msg_table) {
- while ((d = readdir(dp)) != NULL) {
- if ((num = to_number(d->d_name)) <= 0) continue;
-
- msginfo = g_hash_table_lookup
- (msg_table, GUINT_TO_POINTER(num));
-
- if (msginfo) {
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_CACHED);
- } else {
- /* not found in the cache (uncached message) */
- msginfo = mh_parse_msg(d->d_name, item);
- if (!msginfo) continue;
-
- if (!newlist)
- last = newlist =
- g_slist_append(NULL, msginfo);
- else {
- last = g_slist_append(last, msginfo);
- last = last->next;
- }
- n_newmsg++;
- }
- }
- } else {
- /* discard all previous cache */
- while ((d = readdir(dp)) != NULL) {
- if (to_number(d->d_name) <= 0) continue;
-
- msginfo = mh_parse_msg(d->d_name, item);
- if (!msginfo) continue;
-
- if (!newlist)
- last = newlist = g_slist_append(NULL, msginfo);
- else {
- last = g_slist_append(last, msginfo);
- last = last->next;
- }
- n_newmsg++;
- }
- }
-
- closedir(dp);
-
- if (n_newmsg)
- debug_print("%d uncached message(s) found.\n", n_newmsg);
- else
- debug_print("done.\n");
-
- /* sort new messages in numerical order */
- if (newlist && item->sort_key == SORT_BY_NONE) {
- debug_print("Sorting uncached messages in numerical order...\n");
- newlist = g_slist_sort
- (newlist, (GCompareFunc)procmsg_cmp_msgnum_for_sort);
- debug_print("done.\n");
- }
-
- return newlist;
-}
-
-static MsgInfo *mh_parse_msg(const gchar *file, FolderItem *item)
-{
- MsgInfo *msginfo;
- MsgFlags flags;
-
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(file != NULL, NULL);
-
- flags.perm_flags = MSG_NEW|MSG_UNREAD;
- flags.tmp_flags = 0;
-
- if (item->stype == F_QUEUE) {
- MSG_SET_TMP_FLAGS(flags, MSG_QUEUED);
- } else if (item->stype == F_DRAFT) {
- MSG_SET_TMP_FLAGS(flags, MSG_DRAFT);
- }
-
- msginfo = procheader_parse_file(file, flags, FALSE);
- if (!msginfo) return NULL;
-
- msginfo->msgnum = atoi(file);
- msginfo->folder = item;
-
- return msginfo;
-}
-
-#if 0
-static gboolean mh_is_maildir_one(const gchar *path, const gchar *dir)
-{
- gchar *entry;
- gboolean result;
-
- entry = g_strconcat(path, G_DIR_SEPARATOR_S, dir, NULL);
- result = is_dir_exist(entry);
- g_free(entry);
-
- return result;
-}
-
-/*
- * check whether PATH is a Maildir style mailbox.
- * This is the case if the 3 subdir: new, cur, tmp are existing.
- * This functon assumes that entry is an directory
- */
-static gboolean mh_is_maildir(const gchar *path)
-{
- return mh_is_maildir_one(path, "new") &&
- mh_is_maildir_one(path, "cur") &&
- mh_is_maildir_one(path, "tmp");
-}
-#endif
-
-static gboolean mh_remove_missing_folder_items_func(GNode *node, gpointer data)
-{
- FolderItem *item;
- gchar *path;
-
- g_return_val_if_fail(node->data != NULL, FALSE);
-
- if (G_NODE_IS_ROOT(node))
- return FALSE;
-
- item = FOLDER_ITEM(node->data);
-
- path = folder_item_get_path(item);
- if (!is_dir_exist(path)) {
- debug_print("folder '%s' not found. removing...\n", path);
- folder_item_remove(item);
- }
- g_free(path);
-
- return FALSE;
-}
-
-static void mh_remove_missing_folder_items(Folder *folder)
-{
- g_return_if_fail(folder != NULL);
-
- debug_print("searching missing folders...\n");
-
- g_node_traverse(folder->node, G_POST_ORDER, G_TRAVERSE_ALL, -1,
- mh_remove_missing_folder_items_func, folder);
-}
-
-static void mh_scan_tree_recursive(FolderItem *item)
-{
- Folder *folder;
-#ifdef G_OS_WIN32
- GDir *dir;
-#else
- DIR *dp;
- struct dirent *d;
-#endif
- const gchar *dir_name;
- struct stat s;
- gchar *fs_path;
- gchar *entry;
- gchar *utf8entry;
- gchar *utf8name;
- gint n_msg = 0;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
-
- folder = item->folder;
-
- fs_path = item->path ?
- g_filename_from_utf8(item->path, -1, NULL, NULL, NULL)
- : g_strdup(".");
- if (!fs_path)
- fs_path = g_strdup(item->path);
-#ifdef G_OS_WIN32
- dir = g_dir_open(fs_path, 0, NULL);
- if (!dir) {
- g_warning("failed to open directory: %s\n", fs_path);
- g_free(fs_path);
- return;
- }
-#else
- dp = opendir(fs_path);
- if (!dp) {
- FILE_OP_ERROR(fs_path, "opendir");
- g_free(fs_path);
- return;
- }
-#endif
- g_free(fs_path);
-
- debug_print("scanning %s ...\n",
- item->path ? item->path
- : LOCAL_FOLDER(item->folder)->rootpath);
- if (folder->ui_func)
- folder->ui_func(folder, item, folder->ui_func_data);
-
-#ifdef G_OS_WIN32
- while ((dir_name = g_dir_read_name(dir)) != NULL) {
-#else
- while ((d = readdir(dp)) != NULL) {
- dir_name = d->d_name;
-#endif
- if (dir_name[0] == '.') continue;
-
- utf8name = g_filename_to_utf8(dir_name, -1, NULL, NULL, NULL);
- if (!utf8name)
- utf8name = g_strdup(dir_name);
-
- if (item->path)
- utf8entry = g_strconcat(item->path, G_DIR_SEPARATOR_S,
- utf8name, NULL);
- else
- utf8entry = g_strdup(utf8name);
- entry = g_filename_from_utf8(utf8entry, -1, NULL, NULL, NULL);
- if (!entry)
- entry = g_strdup(utf8entry);
-
- if (
-#if !defined(G_OS_WIN32) && defined(HAVE_DIRENT_D_TYPE)
- d->d_type == DT_DIR ||
- (d->d_type == DT_UNKNOWN &&
-#endif
- g_stat(entry, &s) == 0 && S_ISDIR(s.st_mode)
-#if !defined(G_OS_WIN32) && defined(HAVE_DIRENT_D_TYPE)
- )
-#endif
- ) {
- FolderItem *new_item = NULL;
- GNode *node;
-
-#if 0
- if (mh_is_maildir(entry)) {
- g_free(entry);
- g_free(utf8entry);
- g_free(utf8name);
- continue;
- }
-#endif
-
-#ifndef G_OS_WIN32
- if (g_utf8_validate(utf8name, -1, NULL) == FALSE) {
- g_warning(_("Directory name\n"
- "'%s' is not a valid UTF-8 string.\n"
- "Maybe the locale encoding is used for filename.\n"
- "If that is the case, you must set the following environmental variable\n"
- "(see README for detail):\n"
- "\n"
- "\tG_FILENAME_ENCODING=@locale\n"),
- utf8name);
- g_free(entry);
- g_free(utf8entry);
- g_free(utf8name);
- continue;
- }
-#endif /* G_OS_WIN32 */
-
- node = item->node;
- for (node = node->children; node != NULL; node = node->next) {
- FolderItem *cur_item = FOLDER_ITEM(node->data);
- if (!strcmp2(cur_item->path, utf8entry)) {
- new_item = cur_item;
- break;
- }
- }
- if (!new_item) {
- debug_print("new folder '%s' found.\n", entry);
- new_item = folder_item_new(utf8name, utf8entry);
- folder_item_append(item, new_item);
- }
-
- if (!item->path) {
- if (!folder->inbox &&
- !strcmp(dir_name, INBOX_DIR)) {
- new_item->stype = F_INBOX;
- folder->inbox = new_item;
- } else if (!folder->outbox &&
- !strcmp(dir_name, OUTBOX_DIR)) {
- new_item->stype = F_OUTBOX;
- folder->outbox = new_item;
- } else if (!folder->draft &&
- !strcmp(dir_name, DRAFT_DIR)) {
- new_item->stype = F_DRAFT;
- folder->draft = new_item;
- } else if (!folder->queue &&
- !strcmp(dir_name, QUEUE_DIR)) {
- new_item->stype = F_QUEUE;
- folder->queue = new_item;
- } else if (!folder->trash &&
- !strcmp(dir_name, TRASH_DIR)) {
- new_item->stype = F_TRASH;
- folder->trash = new_item;
- }
- }
-
- mh_scan_tree_recursive(new_item);
- } else if (to_number(dir_name) > 0) n_msg++;
-
- g_free(entry);
- g_free(utf8entry);
- g_free(utf8name);
- }
-
-#ifdef G_OS_WIN32
- g_dir_close(dir);
-#else
- closedir(dp);
-#endif
-
- if (item->path) {
- gint new, unread, total, min, max;
-
- procmsg_get_mark_sum
- (item, &new, &unread, &total, &min, &max, 0);
- if (n_msg > total) {
- new += n_msg - total;
- unread += n_msg - total;
- }
- item->new = new;
- item->unread = unread;
- item->total = n_msg;
- item->updated = TRUE;
- }
-}
-
-static gboolean mh_rename_folder_func(GNode *node, gpointer data)
-{
- FolderItem *item = node->data;
- gchar **paths = data;
- const gchar *oldpath = paths[0];
- const gchar *newpath = paths[1];
- gchar *base;
- gchar *new_itempath;
- gint oldpathlen;
-
- oldpathlen = strlen(oldpath);
- if (strncmp(oldpath, item->path, oldpathlen) != 0) {
- g_warning("path doesn't match: %s, %s\n", oldpath, item->path);
- return TRUE;
- }
-
- base = item->path + oldpathlen;
- while (*base == G_DIR_SEPARATOR) base++;
- if (*base == '\0')
- new_itempath = g_strdup(newpath);
- else
- new_itempath = g_strconcat(newpath, G_DIR_SEPARATOR_S, base,
- NULL);
- g_free(item->path);
- item->path = new_itempath;
-
- return FALSE;
-}
diff --git a/src/mh.h b/src/mh.h
deleted file mode 100644
index 160259c1..00000000
--- a/src/mh.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __MH_H__
-#define __MH_H__
-
-#include <glib.h>
-
-#include "folder.h"
-
-typedef struct _MHFolder MHFolder;
-
-#define MH_FOLDER(obj) ((MHFolder *)obj)
-
-struct _MHFolder
-{
- LocalFolder lfolder;
-};
-
-FolderClass *mh_get_class (void);
-
-#endif /* __MH_H__ */
diff --git a/src/news.c b/src/news.c
deleted file mode 100644
index 28181b32..00000000
--- a/src/news.c
+++ /dev/null
@@ -1,1062 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <time.h>
-
-#include "news.h"
-#include "nntp.h"
-#include "socket.h"
-#include "recv.h"
-#include "procmsg.h"
-#include "procheader.h"
-#include "folder.h"
-#include "session.h"
-#include "codeconv.h"
-#include "utils.h"
-#include "prefs_common.h"
-#include "prefs_account.h"
-#if USE_SSL
-# include "ssl.h"
-#endif
-
-#define NNTP_PORT 119
-#if USE_SSL
-#define NNTPS_PORT 563
-#endif
-
-static void news_folder_init (Folder *folder,
- const gchar *name,
- const gchar *path);
-
-static Folder *news_folder_new (const gchar *name,
- const gchar *folder);
-static void news_folder_destroy (Folder *folder);
-
-static GSList *news_get_article_list (Folder *folder,
- FolderItem *item,
- gboolean use_cache);
-static gchar *news_fetch_msg (Folder *folder,
- FolderItem *item,
- gint num);
-static MsgInfo *news_get_msginfo (Folder *folder,
- FolderItem *item,
- gint num);
-
-static gint news_close (Folder *folder,
- FolderItem *item);
-
-static gint news_scan_group (Folder *folder,
- FolderItem *item);
-
-#if USE_SSL
-static Session *news_session_new (const gchar *server,
- gushort port,
- const gchar *userid,
- const gchar *passwd,
- SSLType ssl_type);
-#else
-static Session *news_session_new (const gchar *server,
- gushort port,
- const gchar *userid,
- const gchar *passwd);
-#endif
-
-static gint news_get_article_cmd (NNTPSession *session,
- const gchar *cmd,
- gint num,
- gchar *filename);
-static gint news_get_article (NNTPSession *session,
- gint num,
- gchar *filename);
-#if 0
-static gint news_get_header (NNTPSession *session,
- gint num,
- gchar *filename);
-#endif
-
-static gint news_select_group (NNTPSession *session,
- const gchar *group,
- gint *num,
- gint *first,
- gint *last);
-static GSList *news_get_uncached_articles(NNTPSession *session,
- FolderItem *item,
- gint cache_last,
- gint *rfirst,
- gint *rlast);
-static MsgInfo *news_parse_xover (const gchar *xover_str);
-static gchar *news_parse_xhdr (const gchar *xhdr_str,
- MsgInfo *msginfo);
-static GSList *news_delete_old_articles (GSList *alist,
- FolderItem *item,
- gint first);
-static void news_delete_all_articles (FolderItem *item);
-static void news_delete_expired_caches (GSList *alist,
- FolderItem *item);
-
-static FolderClass news_class =
-{
- F_NEWS,
-
- news_folder_new,
- news_folder_destroy,
-
- NULL,
- NULL,
-
- news_get_article_list,
- news_fetch_msg,
- news_get_msginfo,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- news_close,
- news_scan_group,
-
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-
-FolderClass *news_get_class(void)
-{
- return &news_class;
-}
-
-static Folder *news_folder_new(const gchar *name, const gchar *path)
-{
- Folder *folder;
-
- folder = (Folder *)g_new0(NewsFolder, 1);
- news_folder_init(folder, name, path);
-
- return folder;
-}
-
-static void news_folder_destroy(Folder *folder)
-{
- gchar *dir;
-
- dir = folder_get_path(folder);
- if (is_dir_exist(dir))
- remove_dir_recursive(dir);
- g_free(dir);
-
- folder_remote_folder_destroy(REMOTE_FOLDER(folder));
-}
-
-static void news_folder_init(Folder *folder, const gchar *name,
- const gchar *path)
-{
- folder->klass = news_get_class();
- folder_remote_folder_init(folder, name, path);
-}
-
-#if USE_SSL
-static Session *news_session_new(const gchar *server, gushort port,
- const gchar *userid, const gchar *passwd,
- SSLType ssl_type)
-#else
-static Session *news_session_new(const gchar *server, gushort port,
- const gchar *userid, const gchar *passwd)
-#endif
-{
- gchar buf[NNTPBUFSIZE];
- Session *session;
-
- g_return_val_if_fail(server != NULL, NULL);
-
- log_message(_("creating NNTP connection to %s:%d ...\n"), server, port);
-
-#if USE_SSL
- session = nntp_session_new(server, port, buf, userid, passwd, ssl_type);
-#else
- session = nntp_session_new(server, port, buf, userid, passwd);
-#endif
-
- return session;
-}
-
-static Session *news_session_new_for_folder(Folder *folder)
-{
- Session *session;
- PrefsAccount *ac;
- const gchar *userid = NULL;
- gchar *passwd = NULL;
- gushort port;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(folder->account != NULL, NULL);
-
- ac = folder->account;
- if (ac->use_nntp_auth && ac->userid && ac->userid[0]) {
- userid = ac->userid;
- if (ac->passwd && ac->passwd[0])
- passwd = g_strdup(ac->passwd);
- else
- passwd = input_query_password(ac->nntp_server, userid);
- }
-
-#if USE_SSL
- port = ac->set_nntpport ? ac->nntpport
- : ac->ssl_nntp ? NNTPS_PORT : NNTP_PORT;
- session = news_session_new(ac->nntp_server, port, userid, passwd,
- ac->ssl_nntp);
-#else
- port = ac->set_nntpport ? ac->nntpport : NNTP_PORT;
- session = news_session_new(ac->nntp_server, port, userid, passwd);
-#endif
-
- g_free(passwd);
-
- return session;
-}
-
-static NNTPSession *news_session_get(Folder *folder)
-{
- RemoteFolder *rfolder = REMOTE_FOLDER(folder);
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, NULL);
- g_return_val_if_fail(folder->account != NULL, NULL);
-
- if (!prefs_common.online_mode)
- return NULL;
-
- if (!rfolder->session) {
- rfolder->session = news_session_new_for_folder(folder);
- return NNTP_SESSION(rfolder->session);
- }
-
- if (time(NULL) - rfolder->session->last_access_time <
- SESSION_TIMEOUT_INTERVAL) {
- return NNTP_SESSION(rfolder->session);
- }
-
- if (nntp_mode(NNTP_SESSION(rfolder->session), FALSE)
- != NN_SUCCESS) {
- log_warning(_("NNTP connection to %s:%d has been"
- " disconnected. Reconnecting...\n"),
- folder->account->nntp_server,
- folder->account->set_nntpport ?
- folder->account->nntpport : NNTP_PORT);
- session_destroy(rfolder->session);
- rfolder->session = news_session_new_for_folder(folder);
- }
-
- if (rfolder->session)
- session_set_access_time(rfolder->session);
-
- return NNTP_SESSION(rfolder->session);
-}
-
-static GSList *news_get_article_list(Folder *folder, FolderItem *item,
- gboolean use_cache)
-{
- GSList *alist;
- NNTPSession *session;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, NULL);
-
- session = news_session_get(folder);
-
- if (!session) {
- alist = procmsg_read_cache(item, FALSE);
- item->last_num = procmsg_get_last_num_in_msg_list(alist);
- } else if (use_cache) {
- GSList *newlist;
- gint cache_last;
- gint first, last;
-
- alist = procmsg_read_cache(item, FALSE);
-
- cache_last = procmsg_get_last_num_in_msg_list(alist);
- newlist = news_get_uncached_articles
- (session, item, cache_last, &first, &last);
- if (newlist)
- item->cache_dirty = TRUE;
- if (first == 0 && last == 0) {
- news_delete_all_articles(item);
- procmsg_msg_list_free(alist);
- alist = NULL;
- item->cache_dirty = TRUE;
- } else {
- alist = news_delete_old_articles(alist, item, first);
- news_delete_expired_caches(alist, item);
- }
-
- alist = g_slist_concat(alist, newlist);
-
- item->last_num = last;
- } else {
- gint last;
-
- alist = news_get_uncached_articles
- (session, item, 0, NULL, &last);
- news_delete_all_articles(item);
- item->last_num = last;
- item->cache_dirty = TRUE;
- }
-
- procmsg_set_flags(alist, item);
-
- alist = procmsg_sort_msg_list(alist, item->sort_key, item->sort_type);
-
- debug_print("cache_dirty: %d, mark_dirty: %d\n",
- item->cache_dirty, item->mark_dirty);
-
- return alist;
-}
-
-static gchar *news_fetch_msg(Folder *folder, FolderItem *item, gint num)
-{
- gchar *path, *filename;
- NNTPSession *session;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
-
- path = folder_item_get_path(item);
- if (!is_dir_exist(path))
- make_dir_hier(path);
- filename = g_strconcat(path, G_DIR_SEPARATOR_S, itos(num), NULL);
- g_free(path);
-
- if (is_file_exist(filename)) {
- debug_print(_("article %d has been already cached.\n"), num);
- return filename;
- }
-
- session = news_session_get(folder);
- if (!session) {
- g_free(filename);
- return NULL;
- }
-
- ok = news_select_group(session, item->path, NULL, NULL, NULL);
- if (ok != NN_SUCCESS) {
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(folder)->session = NULL;
- }
- g_free(filename);
- return NULL;
- }
-
- debug_print(_("getting article %d...\n"), num);
- ok = news_get_article(NNTP_SESSION(REMOTE_FOLDER(folder)->session),
- num, filename);
- if (ok != NN_SUCCESS) {
- g_warning(_("can't read article %d\n"), num);
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(folder)->session = NULL;
- }
- g_free(filename);
- return NULL;
- }
-
- return filename;
-}
-
-static MsgInfo *news_get_msginfo(Folder *folder, FolderItem *item, gint num)
-{
- MsgInfo *msginfo;
- MsgFlags flags = {0, 0};
- gchar *file;
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
-
- file = news_fetch_msg(folder, item, num);
- if (!file) return NULL;
-
- msginfo = procheader_parse_file(file, flags, FALSE);
-
- g_free(file);
-
- return msginfo;
-}
-
-static gint news_close(Folder *folder, FolderItem *item)
-{
- return 0;
-}
-
-static gint news_scan_group(Folder *folder, FolderItem *item)
-{
- NNTPSession *session;
- gint num = 0, first = 0, last = 0;
- gint new = 0, unread = 0, total = 0;
- gint min = 0, max = 0;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(item != NULL, -1);
-
- session = news_session_get(folder);
- if (!session) return -1;
-
- ok = news_select_group(session, item->path, &num, &first, &last);
- if (ok != NN_SUCCESS) {
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(folder)->session = NULL;
- }
- return -1;
- }
-
- if (num == 0) {
- item->new = item->unread = item->total = item->last_num = 0;
- return 0;
- }
-
- procmsg_get_mark_sum(item, &new, &unread, &total, &min, &max, first);
-
- if (max < first || last < min)
- new = unread = total = num;
- else {
- if (min < first)
- min = first;
-
- if (last < max)
- max = last;
- else if (max < last) {
- new += last - max;
- unread += last - max;
- }
-
- if (new > num) new = num;
- if (unread > num) unread = num;
- }
-
- item->new = new;
- item->unread = unread;
- item->total = num;
- item->last_num = last;
-
- return 0;
-}
-
-static NewsGroupInfo *news_group_info_new(const gchar *name,
- gint first, gint last, gchar type)
-{
- NewsGroupInfo *ginfo;
-
- ginfo = g_new(NewsGroupInfo, 1);
- ginfo->name = g_strdup(name);
- ginfo->first = first;
- ginfo->last = last;
- ginfo->type = type;
-
- return ginfo;
-}
-
-static void news_group_info_free(NewsGroupInfo *ginfo)
-{
- g_free(ginfo->name);
- g_free(ginfo);
-}
-
-static gint news_group_info_compare(NewsGroupInfo *ginfo1,
- NewsGroupInfo *ginfo2)
-{
- return g_ascii_strcasecmp(ginfo1->name, ginfo2->name);
-}
-
-GSList *news_get_group_list(Folder *folder)
-{
- gchar *path, *filename;
- FILE *fp;
- GSList *list = NULL;
- GSList *last = NULL;
- gchar buf[NNTPBUFSIZE];
-
- g_return_val_if_fail(folder != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, NULL);
-
- path = folder_item_get_path(FOLDER_ITEM(folder->node->data));
- if (!is_dir_exist(path))
- make_dir_hier(path);
- filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL);
- g_free(path);
-
- if ((fp = g_fopen(filename, "rb")) == NULL) {
- NNTPSession *session;
- gint ok;
-
- session = news_session_get(folder);
- if (!session) {
- g_free(filename);
- return NULL;
- }
-
- ok = nntp_list(session);
- if (ok != NN_SUCCESS) {
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(folder)->session = NULL;
- }
- g_free(filename);
- return NULL;
- }
- if (recv_write_to_file(SESSION(session)->sock, filename) < 0) {
- log_warning(_("can't retrieve newsgroup list\n"));
- session_destroy(SESSION(session));
- REMOTE_FOLDER(folder)->session = NULL;
- g_free(filename);
- return NULL;
- }
-
- if ((fp = g_fopen(filename, "rb")) == NULL) {
- FILE_OP_ERROR(filename, "fopen");
- g_free(filename);
- return NULL;
- }
- }
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- gchar *p = buf;
- gchar *name;
- gint last_num;
- gint first_num;
- gchar type;
- NewsGroupInfo *ginfo;
-
- p = strchr(p, ' ');
- if (!p) continue;
- *p = '\0';
- p++;
- name = buf;
-
- if (sscanf(p, "%d %d %c", &last_num, &first_num, &type) < 3)
- continue;
-
- ginfo = news_group_info_new(name, first_num, last_num, type);
-
- if (!last)
- last = list = g_slist_append(NULL, ginfo);
- else {
- last = g_slist_append(last, ginfo);
- last = last->next;
- }
- }
-
- fclose(fp);
- g_free(filename);
-
- list = g_slist_sort(list, (GCompareFunc)news_group_info_compare);
-
- return list;
-}
-
-void news_group_list_free(GSList *group_list)
-{
- GSList *cur;
-
- if (!group_list) return;
-
- for (cur = group_list; cur != NULL; cur = cur->next)
- news_group_info_free((NewsGroupInfo *)cur->data);
- g_slist_free(group_list);
-}
-
-void news_remove_group_list_cache(Folder *folder)
-{
- gchar *path, *filename;
-
- g_return_if_fail(folder != NULL);
- g_return_if_fail(FOLDER_TYPE(folder) == F_NEWS);
-
- path = folder_item_get_path(FOLDER_ITEM(folder->node->data));
- filename = g_strconcat(path, G_DIR_SEPARATOR_S, NEWSGROUP_LIST, NULL);
- g_free(path);
-
- if (is_file_exist(filename)) {
- if (remove(filename) < 0)
- FILE_OP_ERROR(filename, "remove");
- }
- g_free(filename);
-}
-
-gint news_post(Folder *folder, const gchar *file)
-{
- FILE *fp;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, -1);
- g_return_val_if_fail(file != NULL, -1);
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return -1;
- }
-
- ok = news_post_stream(folder, fp);
-
- fclose(fp);
-
- return ok;
-}
-
-gint news_post_stream(Folder *folder, FILE *fp)
-{
- NNTPSession *session;
- gint ok;
-
- g_return_val_if_fail(folder != NULL, -1);
- g_return_val_if_fail(FOLDER_TYPE(folder) == F_NEWS, -1);
- g_return_val_if_fail(fp != NULL, -1);
-
- session = news_session_get(folder);
- if (!session) return -1;
-
- ok = nntp_post(session, fp);
- if (ok != NN_SUCCESS) {
- log_warning(_("can't post article.\n"));
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(folder)->session = NULL;
- }
- return -1;
- }
-
- return 0;
-}
-
-static gint news_get_article_cmd(NNTPSession *session, const gchar *cmd,
- gint num, gchar *filename)
-{
- gchar *msgid;
- gint ok;
-
- ok = nntp_get_article(session, cmd, num, &msgid);
- if (ok != NN_SUCCESS)
- return ok;
-
- debug_print("Message-Id = %s, num = %d\n", msgid, num);
- g_free(msgid);
-
- ok = recv_write_to_file(SESSION(session)->sock, filename);
- if (ok < 0) {
- log_warning(_("can't retrieve article %d\n"), num);
- if (ok == -2)
- return NN_SOCKET;
- else
- return NN_IOERR;
- }
-
- return NN_SUCCESS;
-}
-
-static gint news_get_article(NNTPSession *session, gint num, gchar *filename)
-{
- return news_get_article_cmd(session, "ARTICLE", num, filename);
-}
-
-#if 0
-static gint news_get_header(NNTPSession *session, gint num, gchar *filename)
-{
- return news_get_article_cmd(session, "HEAD", num, filename);
-}
-#endif
-
-/**
- * news_select_group:
- * @session: Active NNTP session.
- * @group: Newsgroup name.
- * @num: Estimated number of articles.
- * @first: First article number.
- * @last: Last article number.
- *
- * Select newsgroup @group with the GROUP command if it is not already
- * selected in @session, or article numbers need to be returned.
- *
- * Return value: NNTP result code.
- **/
-static gint news_select_group(NNTPSession *session, const gchar *group,
- gint *num, gint *first, gint *last)
-{
- gint ok;
- gint num_, first_, last_;
-
- if (!num || !first || !last) {
- if (session->group &&
- g_ascii_strcasecmp(session->group, group) == 0)
- return NN_SUCCESS;
- num = &num_;
- first = &first_;
- last = &last_;
- }
-
- g_free(session->group);
- session->group = NULL;
-
- ok = nntp_group(session, group, num, first, last);
- if (ok == NN_SUCCESS)
- session->group = g_strdup(group);
- else
- log_warning(_("can't select group: %s\n"), group);
-
- return ok;
-}
-
-static GSList *news_get_uncached_articles(NNTPSession *session,
- FolderItem *item, gint cache_last,
- gint *rfirst, gint *rlast)
-{
- gint ok;
- gint num = 0, first = 0, last = 0, begin = 0, end = 0;
- gchar buf[NNTPBUFSIZE];
- GSList *newlist = NULL;
- GSList *llast = NULL;
- MsgInfo *msginfo;
- gint max_articles;
-
- if (rfirst) *rfirst = -1;
- if (rlast) *rlast = -1;
-
- g_return_val_if_fail(session != NULL, NULL);
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(item->folder != NULL, NULL);
- g_return_val_if_fail(item->folder->account != NULL, NULL);
- g_return_val_if_fail(FOLDER_TYPE(item->folder) == F_NEWS, NULL);
-
- ok = news_select_group(session, item->path, &num, &first, &last);
- if (ok != NN_SUCCESS) {
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(item->folder)->session = NULL;
- }
- return NULL;
- }
-
- /* calculate getting overview range */
- if (first > last) {
- log_warning(_("invalid article range: %d - %d\n"),
- first, last);
- return NULL;
- }
-
- if (rfirst) *rfirst = first;
- if (rlast) *rlast = last;
-
- if (cache_last < first)
- begin = first;
- else if (last < cache_last)
- begin = first;
- else if (last == cache_last) {
- debug_print(_("no new articles.\n"));
- return NULL;
- } else
- begin = cache_last + 1;
- end = last;
-
- max_articles = item->folder->account->max_nntp_articles;
- if (max_articles > 0 && end - begin + 1 > max_articles)
- begin = end - max_articles + 1;
-
- log_message(_("getting xover %d - %d in %s...\n"),
- begin, end, item->path);
- ok = nntp_xover(session, begin, end);
- if (ok != NN_SUCCESS) {
- log_warning(_("can't get xover\n"));
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(item->folder)->session = NULL;
- }
- return NULL;
- }
-
- for (;;) {
- if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
- log_warning(_("error occurred while getting xover.\n"));
- session_destroy(SESSION(session));
- REMOTE_FOLDER(item->folder)->session = NULL;
- return newlist;
- }
-
- if (buf[0] == '.' && buf[1] == '\r') break;
-
- msginfo = news_parse_xover(buf);
- if (!msginfo) {
- log_warning(_("invalid xover line: %s\n"), buf);
- continue;
- }
-
- msginfo->folder = item;
- msginfo->flags.perm_flags = MSG_NEW|MSG_UNREAD;
- msginfo->flags.tmp_flags = MSG_NEWS;
- msginfo->newsgroups = g_strdup(item->path);
-
- if (!newlist)
- llast = newlist = g_slist_append(newlist, msginfo);
- else {
- llast = g_slist_append(llast, msginfo);
- llast = llast->next;
- }
- }
-
- ok = nntp_xhdr(session, "to", begin, end);
- if (ok != NN_SUCCESS) {
- log_warning(_("can't get xhdr\n"));
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(item->folder)->session = NULL;
- }
- return newlist;
- }
-
- llast = newlist;
-
- for (;;) {
- if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
- log_warning(_("error occurred while getting xhdr.\n"));
- session_destroy(SESSION(session));
- REMOTE_FOLDER(item->folder)->session = NULL;
- return newlist;
- }
-
- if (buf[0] == '.' && buf[1] == '\r') break;
- if (!llast) {
- g_warning("llast == NULL\n");
- continue;
- }
-
- msginfo = (MsgInfo *)llast->data;
- msginfo->to = news_parse_xhdr(buf, msginfo);
-
- llast = llast->next;
- }
-
- ok = nntp_xhdr(session, "cc", begin, end);
- if (ok != NN_SUCCESS) {
- log_warning(_("can't get xhdr\n"));
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- REMOTE_FOLDER(item->folder)->session = NULL;
- }
- return newlist;
- }
-
- llast = newlist;
-
- for (;;) {
- if (sock_gets(SESSION(session)->sock, buf, sizeof(buf)) < 0) {
- log_warning(_("error occurred while getting xhdr.\n"));
- session_destroy(SESSION(session));
- REMOTE_FOLDER(item->folder)->session = NULL;
- return newlist;
- }
-
- if (buf[0] == '.' && buf[1] == '\r') break;
- if (!llast) {
- g_warning("llast == NULL\n");
- continue;
- }
-
- msginfo = (MsgInfo *)llast->data;
- msginfo->cc = news_parse_xhdr(buf, msginfo);
-
- llast = llast->next;
- }
-
- session_set_access_time(SESSION(session));
-
- return newlist;
-}
-
-#define PARSE_ONE_PARAM(p, srcp) \
-{ \
- p = strchr(srcp, '\t'); \
- if (!p) return NULL; \
- else \
- *p++ = '\0'; \
-}
-
-static MsgInfo *news_parse_xover(const gchar *xover_str)
-{
- MsgInfo *msginfo;
- gchar *subject, *sender, *size, *line, *date, *msgid, *ref, *tmp;
- gchar *p;
- gint num, size_int, line_int;
- gchar *xover_buf;
-
- Xstrdup_a(xover_buf, xover_str, return NULL);
-
- PARSE_ONE_PARAM(subject, xover_buf);
- PARSE_ONE_PARAM(sender, subject);
- PARSE_ONE_PARAM(date, sender);
- PARSE_ONE_PARAM(msgid, date);
- PARSE_ONE_PARAM(ref, msgid);
- PARSE_ONE_PARAM(size, ref);
- PARSE_ONE_PARAM(line, size);
-
- tmp = strchr(line, '\t');
- if (!tmp) tmp = strchr(line, '\r');
- if (!tmp) tmp = strchr(line, '\n');
- if (tmp) *tmp = '\0';
-
- num = atoi(xover_str);
- size_int = atoi(size);
- line_int = atoi(line);
-
- /* set MsgInfo */
- msginfo = g_new0(MsgInfo, 1);
- msginfo->msgnum = num;
- msginfo->size = size_int;
-
- msginfo->date = g_strdup(date);
- msginfo->date_t = procheader_date_parse(NULL, date, 0);
-
- msginfo->from = conv_unmime_header(sender, NULL);
- msginfo->fromname = procheader_get_fromname(msginfo->from);
-
- msginfo->subject = conv_unmime_header(subject, NULL);
-
- extract_parenthesis(msgid, '<', '>');
- remove_space(msgid);
- if (*msgid != '\0')
- msginfo->msgid = g_strdup(msgid);
-
- eliminate_parenthesis(ref, '(', ')');
- if ((p = strrchr(ref, '<')) != NULL) {
- extract_parenthesis(p, '<', '>');
- remove_space(p);
- if (*p != '\0')
- msginfo->inreplyto = g_strdup(p);
- }
-
- return msginfo;
-}
-
-static gchar *news_parse_xhdr(const gchar *xhdr_str, MsgInfo *msginfo)
-{
- gchar *p;
- gchar *tmp;
- gint num;
-
- p = strchr(xhdr_str, ' ');
- if (!p)
- return NULL;
- else
- p++;
-
- num = atoi(xhdr_str);
- if (msginfo->msgnum != num) return NULL;
-
- tmp = strchr(p, '\r');
- if (!tmp) tmp = strchr(p, '\n');
-
- if (tmp)
- return g_strndup(p, tmp - p);
- else
- return g_strdup(p);
-}
-
-static GSList *news_delete_old_articles(GSList *alist, FolderItem *item,
- gint first)
-{
- GSList *cur, *next;
- MsgInfo *msginfo;
- gchar *dir;
-
- g_return_val_if_fail(item != NULL, alist);
- g_return_val_if_fail(item->folder != NULL, alist);
- g_return_val_if_fail(FOLDER_TYPE(item->folder) == F_NEWS, alist);
-
- if (first < 2) return alist;
-
- debug_print("Deleting cached articles 1 - %d ...\n", first - 1);
-
- dir = folder_item_get_path(item);
- remove_numbered_files(dir, 1, first - 1);
- g_free(dir);
-
- for (cur = alist; cur != NULL; ) {
- next = cur->next;
-
- msginfo = (MsgInfo *)cur->data;
- if (msginfo && msginfo->msgnum < first) {
- procmsg_msginfo_free(msginfo);
- alist = g_slist_remove(alist, msginfo);
- item->cache_dirty = TRUE;
- }
-
- cur = next;
- }
-
- return alist;
-}
-
-static void news_delete_all_articles(FolderItem *item)
-{
- gchar *dir;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
- g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
-
- debug_print("Deleting all cached articles...\n");
-
- dir = folder_item_get_path(item);
- remove_all_numbered_files(dir);
- g_free(dir);
-}
-
-static void news_delete_expired_caches(GSList *alist, FolderItem *item)
-{
- gchar *dir;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
- g_return_if_fail(FOLDER_TYPE(item->folder) == F_NEWS);
-
- debug_print("Deleting expired cached articles...\n");
-
- dir = folder_item_get_path(item);
- remove_expired_files(dir, 24 * 7);
- g_free(dir);
-}
diff --git a/src/news.h b/src/news.h
deleted file mode 100644
index 31628113..00000000
--- a/src/news.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __NEWS_H__
-#define __NEWS_H__
-
-#include <glib.h>
-#include <stdio.h>
-
-#include "folder.h"
-
-typedef struct _NewsFolder NewsFolder;
-typedef struct _NewsGroupInfo NewsGroupInfo;
-
-#define NEWS_FOLDER(obj) ((NewsFolder *)obj)
-
-struct _NewsFolder
-{
- RemoteFolder rfolder;
-
- gboolean use_auth;
-};
-
-struct _NewsGroupInfo
-{
- gchar *name;
- guint first;
- guint last;
- gchar type;
-};
-
-FolderClass *news_get_class (void);
-
-GSList *news_get_group_list (Folder *folder);
-void news_group_list_free (GSList *group_list);
-void news_remove_group_list_cache (Folder *folder);
-
-gint news_post (Folder *folder,
- const gchar *file);
-gint news_post_stream (Folder *folder,
- FILE *fp);
-
-#endif /* __NEWS_H__ */
diff --git a/src/nntp.c b/src/nntp.c
deleted file mode 100644
index 7e36baaa..00000000
--- a/src/nntp.c
+++ /dev/null
@@ -1,431 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "nntp.h"
-#include "socket.h"
-#include "utils.h"
-#if USE_SSL
-# include "ssl.h"
-#endif
-
-static gint verbose = 1;
-
-static void nntp_session_destroy(Session *session);
-
-static gint nntp_ok (SockInfo *sock,
- gchar *argbuf);
-
-static gint nntp_gen_send (SockInfo *sock,
- const gchar *format,
- ...);
-static gint nntp_gen_recv (SockInfo *sock,
- gchar *buf,
- gint size);
-static gint nntp_gen_command (NNTPSession *session,
- gchar *argbuf,
- const gchar *format,
- ...);
-
-
-#if USE_SSL
-Session *nntp_session_new(const gchar *server, gushort port, gchar *buf,
- const gchar *userid, const gchar *passwd,
- SSLType ssl_type)
-#else
-Session *nntp_session_new(const gchar *server, gushort port, gchar *buf,
- const gchar *userid, const gchar *passwd)
-#endif
-{
- NNTPSession *session;
- SockInfo *sock;
-
- if ((sock = sock_connect(server, port)) == NULL) {
- log_warning(_("Can't connect to NNTP server: %s:%d\n"),
- server, port);
- return NULL;
- }
-
-#if USE_SSL
- if (ssl_type == SSL_TUNNEL && !ssl_init_socket(sock)) {
- sock_close(sock);
- return NULL;
- }
-#endif
-
- if (nntp_ok(sock, buf) != NN_SUCCESS) {
- sock_close(sock);
- return NULL;
- }
-
- session = g_new0(NNTPSession, 1);
-
- session_init(SESSION(session));
-
- SESSION(session)->type = SESSION_NEWS;
- SESSION(session)->server = g_strdup(server);
- SESSION(session)->sock = sock;
- SESSION(session)->last_access_time = time(NULL);
- SESSION(session)->data = NULL;
-
- SESSION(session)->destroy = nntp_session_destroy;
-
- session->group = NULL;
-
- if (userid && passwd) {
- gint ok;
-
- session->userid = g_strdup(userid);
- session->passwd = g_strdup(passwd);
-
- ok = nntp_gen_send(sock, "AUTHINFO USER %s", session->userid);
- if (ok != NN_SUCCESS) {
- session_destroy(SESSION(session));
- return NULL;
- }
- ok = nntp_ok(sock, NULL);
- if (ok == NN_AUTHCONT) {
- ok = nntp_gen_send(sock, "AUTHINFO PASS %s",
- session->passwd);
- if (ok != NN_SUCCESS) {
- session_destroy(SESSION(session));
- return NULL;
- }
- ok = nntp_ok(sock, NULL);
- if (ok != NN_SUCCESS)
- session->auth_failed = TRUE;
- }
- if (ok == NN_SOCKET) {
- session_destroy(SESSION(session));
- return NULL;
- }
- }
-
- session_set_access_time(SESSION(session));
-
- return SESSION(session);
-}
-
-static void nntp_session_destroy(Session *session)
-{
- NNTPSession *nntp_session = NNTP_SESSION(session);
-
- g_return_if_fail(session != NULL);
-
- g_free(nntp_session->group);
- g_free(nntp_session->userid);
- g_free(nntp_session->passwd);
-}
-
-gint nntp_group(NNTPSession *session, const gchar *group,
- gint *num, gint *first, gint *last)
-{
- gint ok;
- gint resp;
- gchar buf[NNTPBUFSIZE];
-
- ok = nntp_gen_command(session, buf, "GROUP %s", group);
-
- if (ok != NN_SUCCESS && ok != NN_SOCKET && ok != NN_AUTHREQ) {
- ok = nntp_mode(session, FALSE);
- if (ok == NN_SUCCESS)
- ok = nntp_gen_command(session, buf, "GROUP %s", group);
- }
-
- if (ok != NN_SUCCESS)
- return ok;
-
- if (sscanf(buf, "%d %d %d %d", &resp, num, first, last)
- != 4) {
- log_warning(_("protocol error: %s\n"), buf);
- return NN_PROTOCOL;
- }
-
- return NN_SUCCESS;
-}
-
-gint nntp_get_article(NNTPSession *session, const gchar *cmd, gint num,
- gchar **msgid)
-{
- gint ok;
- gchar buf[NNTPBUFSIZE];
-
- if (num > 0)
- ok = nntp_gen_command(session, buf, "%s %d", cmd, num);
- else
- ok = nntp_gen_command(session, buf, cmd);
-
- if (ok != NN_SUCCESS)
- return ok;
-
- extract_parenthesis(buf, '<', '>');
- if (buf[0] == '\0') {
- log_warning(_("protocol error\n"));
- *msgid = g_strdup("0");
- } else
- *msgid = g_strdup(buf);
-
- return NN_SUCCESS;
-}
-
-gint nntp_article(NNTPSession *session, gint num, gchar **msgid)
-{
- return nntp_get_article(session, "ARTICLE", num, msgid);
-}
-
-gint nntp_body(NNTPSession *session, gint num, gchar **msgid)
-{
- return nntp_get_article(session, "BODY", num, msgid);
-}
-
-gint nntp_head(NNTPSession *session, gint num, gchar **msgid)
-{
- return nntp_get_article(session, "HEAD", num, msgid);
-}
-
-gint nntp_stat(NNTPSession *session, gint num, gchar **msgid)
-{
- return nntp_get_article(session, "STAT", num, msgid);
-}
-
-gint nntp_next(NNTPSession *session, gint *num, gchar **msgid)
-{
- gint ok;
- gint resp;
- gchar buf[NNTPBUFSIZE];
-
- ok = nntp_gen_command(session, buf, "NEXT");
-
- if (ok != NN_SUCCESS)
- return ok;
-
- if (sscanf(buf, "%d %d", &resp, num) != 2) {
- log_warning(_("protocol error: %s\n"), buf);
- return NN_PROTOCOL;
- }
-
- extract_parenthesis(buf, '<', '>');
- if (buf[0] == '\0') {
- log_warning(_("protocol error\n"));
- return NN_PROTOCOL;
- }
- *msgid = g_strdup(buf);
-
- return NN_SUCCESS;
-}
-
-gint nntp_xover(NNTPSession *session, gint first, gint last)
-{
- gint ok;
- gchar buf[NNTPBUFSIZE];
-
- ok = nntp_gen_command(session, buf, "XOVER %d-%d", first, last);
- if (ok != NN_SUCCESS)
- return ok;
-
- return NN_SUCCESS;
-}
-
-gint nntp_xhdr(NNTPSession *session, const gchar *header, gint first, gint last)
-{
- gint ok;
- gchar buf[NNTPBUFSIZE];
-
- ok = nntp_gen_command(session, buf, "XHDR %s %d-%d",
- header, first, last);
- if (ok != NN_SUCCESS)
- return ok;
-
- return NN_SUCCESS;
-}
-
-gint nntp_list(NNTPSession *session)
-{
- return nntp_gen_command(session, NULL, "LIST");
-}
-
-gint nntp_post(NNTPSession *session, FILE *fp)
-{
- gint ok;
- gchar buf[NNTPBUFSIZE];
- gchar *msg;
-
- ok = nntp_gen_command(session, buf, "POST");
- if (ok != NN_SUCCESS)
- return ok;
-
- msg = get_outgoing_rfc2822_str(fp);
- if (sock_write_all(SESSION(session)->sock, msg, strlen(msg)) < 0) {
- log_warning(_("Error occurred while posting\n"));
- g_free(msg);
- return NN_SOCKET;
- }
- g_free(msg);
-
- sock_write_all(SESSION(session)->sock, ".\r\n", 3);
- if ((ok = nntp_ok(SESSION(session)->sock, buf)) != NN_SUCCESS)
- return ok;
-
- session_set_access_time(SESSION(session));
-
- return NN_SUCCESS;
-}
-
-gint nntp_newgroups(NNTPSession *session)
-{
- return NN_SUCCESS;
-}
-
-gint nntp_newnews(NNTPSession *session)
-{
- return NN_SUCCESS;
-}
-
-gint nntp_mode(NNTPSession *session, gboolean stream)
-{
- gint ok;
-
- ok = nntp_gen_command(session, NULL, "MODE %s",
- stream ? "STREAM" : "READER");
-
- return ok;
-}
-
-static gint nntp_ok(SockInfo *sock, gchar *argbuf)
-{
- gint ok;
- gchar buf[NNTPBUFSIZE];
-
- if ((ok = nntp_gen_recv(sock, buf, sizeof(buf))) == NN_SUCCESS) {
- if (strlen(buf) < 3)
- return NN_ERROR;
-
- if ((buf[0] == '1' || buf[0] == '2' || buf[0] == '3') &&
- (buf[3] == ' ' || buf[3] == '\0')) {
- if (argbuf)
- strcpy(argbuf, buf);
-
- if (!strncmp(buf, "381", 3))
- return NN_AUTHCONT;
-
- return NN_SUCCESS;
- } else if (!strncmp(buf, "480", 3))
- return NN_AUTHREQ;
- else
- return NN_ERROR;
- }
-
- return ok;
-}
-
-static gint nntp_gen_send(SockInfo *sock, const gchar *format, ...)
-{
- gchar buf[NNTPBUFSIZE];
- va_list args;
-
- va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
-
- if (verbose) {
- if (!g_ascii_strncasecmp(buf, "AUTHINFO PASS", 13))
- log_print("NNTP> AUTHINFO PASS ********\n");
- else
- log_print("NNTP> %s\n", buf);
- }
-
- strcat(buf, "\r\n");
- if (sock_write_all(sock, buf, strlen(buf)) < 0) {
- log_warning(_("Error occurred while sending command\n"));
- return NN_SOCKET;
- }
-
- return NN_SUCCESS;
-}
-
-static gint nntp_gen_recv(SockInfo *sock, gchar *buf, gint size)
-{
- if (sock_gets(sock, buf, size) == -1)
- return NN_SOCKET;
-
- strretchomp(buf);
-
- if (verbose)
- log_print("NNTP< %s\n", buf);
-
- return NN_SUCCESS;
-}
-
-static gint nntp_gen_command(NNTPSession *session, gchar *argbuf,
- const gchar *format, ...)
-{
- gchar buf[NNTPBUFSIZE];
- va_list args;
- gint ok;
- SockInfo *sock;
-
- va_start(args, format);
- g_vsnprintf(buf, sizeof(buf), format, args);
- va_end(args);
-
- sock = SESSION(session)->sock;
- ok = nntp_gen_send(sock, "%s", buf);
- if (ok != NN_SUCCESS)
- return ok;
- ok = nntp_ok(sock, argbuf);
- if (ok == NN_AUTHREQ) {
- if (!session->userid || !session->passwd) {
- session->auth_failed = TRUE;
- return ok;
- }
-
- ok = nntp_gen_send(sock, "AUTHINFO USER %s", session->userid);
- if (ok != NN_SUCCESS)
- return ok;
- ok = nntp_ok(sock, NULL);
- if (ok == NN_AUTHCONT) {
- ok = nntp_gen_send(sock, "AUTHINFO PASS %s",
- session->passwd);
- if (ok != NN_SUCCESS)
- return ok;
- ok = nntp_ok(sock, NULL);
- }
- if (ok != NN_SUCCESS) {
- session->auth_failed = TRUE;
- return ok;
- }
-
- ok = nntp_gen_send(sock, "%s", buf);
- if (ok != NN_SUCCESS)
- return ok;
- ok = nntp_ok(sock, argbuf);
- }
-
- session_set_access_time(SESSION(session));
-
- return ok;
-}
diff --git a/src/nntp.h b/src/nntp.h
deleted file mode 100644
index 46992e42..00000000
--- a/src/nntp.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __NNTP_H__
-#define __NNTP_H__
-
-#include "session.h"
-#if USE_SSL
-# include "ssl.h"
-#endif
-
-typedef struct _NNTPSession NNTPSession;
-
-#define NNTP_SESSION(obj) ((NNTPSession *)obj)
-
-struct _NNTPSession
-{
- Session session;
-
- gchar *group;
-
- gchar *userid;
- gchar *passwd;
- gboolean auth_failed;
-};
-
-#define NN_SUCCESS 0
-#define NN_SOCKET 2
-#define NN_AUTHFAIL 3
-#define NN_PROTOCOL 4
-#define NN_SYNTAX 5
-#define NN_IOERR 6
-#define NN_ERROR 7
-#define NN_AUTHREQ 8
-#define NN_AUTHCONT 9
-
-#define NNTPBUFSIZE 8192
-
-#if USE_SSL
-Session *nntp_session_new (const gchar *server,
- gushort port,
- gchar *buf,
- const gchar *userid,
- const gchar *passwd,
- SSLType ssl_type);
-#else
-Session *nntp_session_new (const gchar *server,
- gushort port,
- gchar *buf,
- const gchar *userid,
- const gchar *passwd);
-#endif
-
-gint nntp_group (NNTPSession *session,
- const gchar *group,
- gint *num,
- gint *first,
- gint *last);
-gint nntp_get_article (NNTPSession *session,
- const gchar *cmd,
- gint num,
- gchar **msgid);
-gint nntp_article (NNTPSession *session,
- gint num,
- gchar **msgid);
-gint nntp_body (NNTPSession *session,
- gint num,
- gchar **msgid);
-gint nntp_head (NNTPSession *session,
- gint num,
- gchar **msgid);
-gint nntp_stat (NNTPSession *session,
- gint num,
- gchar **msgid);
-gint nntp_next (NNTPSession *session,
- gint *num,
- gchar **msgid);
-gint nntp_xover (NNTPSession *session,
- gint first,
- gint last);
-gint nntp_xhdr (NNTPSession *session,
- const gchar *header,
- gint first,
- gint last);
-gint nntp_list (NNTPSession *session);
-gint nntp_post (NNTPSession *session,
- FILE *fp);
-gint nntp_newgroups (NNTPSession *session);
-gint nntp_newnews (NNTPSession *session);
-gint nntp_mode (NNTPSession *sessio,
- gboolean stream);
-
-#endif /* __NNTP_H__ */
diff --git a/src/pop.c b/src/pop.c
deleted file mode 100644
index 3a562054..00000000
--- a/src/pop.c
+++ /dev/null
@@ -1,857 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <time.h>
-#include <errno.h>
-
-#include "pop.h"
-#include "md5.h"
-#include "prefs_account.h"
-#include "utils.h"
-#include "recv.h"
-
-static gint pop3_greeting_recv (Pop3Session *session,
- const gchar *msg);
-static gint pop3_getauth_user_send (Pop3Session *session);
-static gint pop3_getauth_pass_send (Pop3Session *session);
-static gint pop3_getauth_apop_send (Pop3Session *session);
-#if USE_SSL
-static gint pop3_stls_send (Pop3Session *session);
-static gint pop3_stls_recv (Pop3Session *session);
-#endif
-static gint pop3_getrange_stat_send (Pop3Session *session);
-static gint pop3_getrange_stat_recv (Pop3Session *session,
- const gchar *msg);
-static gint pop3_getrange_last_send (Pop3Session *session);
-static gint pop3_getrange_last_recv (Pop3Session *session,
- const gchar *msg);
-static gint pop3_getrange_uidl_send (Pop3Session *session);
-static gint pop3_getrange_uidl_recv (Pop3Session *session,
- const gchar *data,
- guint len);
-static gint pop3_getsize_list_send (Pop3Session *session);
-static gint pop3_getsize_list_recv (Pop3Session *session,
- const gchar *data,
- guint len);
-static gint pop3_retr_send (Pop3Session *session);
-static gint pop3_retr_recv (Pop3Session *session,
- const gchar *data,
- guint len);
-static gint pop3_delete_send (Pop3Session *session);
-static gint pop3_delete_recv (Pop3Session *session);
-static gint pop3_logout_send (Pop3Session *session);
-
-static void pop3_gen_send (Pop3Session *session,
- const gchar *format, ...);
-
-static void pop3_session_destroy (Session *session);
-
-static gint pop3_write_msg_to_file (const gchar *file,
- const gchar *data,
- guint len);
-
-static Pop3State pop3_lookup_next (Pop3Session *session);
-static Pop3ErrorValue pop3_ok (Pop3Session *session,
- const gchar *msg);
-
-static gint pop3_session_recv_msg (Session *session,
- const gchar *msg);
-static gint pop3_session_recv_data_finished (Session *session,
- guchar *data,
- guint len);
-
-
-static gint pop3_greeting_recv(Pop3Session *session, const gchar *msg)
-{
- session->state = POP3_GREETING;
-
- session->greeting = g_strdup(msg);
- return PS_SUCCESS;
-}
-
-#if USE_SSL
-static gint pop3_stls_send(Pop3Session *session)
-{
- session->state = POP3_STLS;
- pop3_gen_send(session, "STLS");
- return PS_SUCCESS;
-}
-
-static gint pop3_stls_recv(Pop3Session *session)
-{
- if (session_start_tls(SESSION(session)) < 0) {
- session->error_val = PS_SOCKET;
- return -1;
- }
- return PS_SUCCESS;
-}
-#endif /* USE_SSL */
-
-static gint pop3_getauth_user_send(Pop3Session *session)
-{
- g_return_val_if_fail(session->user != NULL, -1);
-
- session->state = POP3_GETAUTH_USER;
- pop3_gen_send(session, "USER %s", session->user);
- return PS_SUCCESS;
-}
-
-static gint pop3_getauth_pass_send(Pop3Session *session)
-{
- g_return_val_if_fail(session->pass != NULL, -1);
-
- session->state = POP3_GETAUTH_PASS;
- pop3_gen_send(session, "PASS %s", session->pass);
- return PS_SUCCESS;
-}
-
-static gint pop3_getauth_apop_send(Pop3Session *session)
-{
- gchar *start, *end;
- gchar *apop_str;
- gchar md5sum[33];
-
- g_return_val_if_fail(session->user != NULL, -1);
- g_return_val_if_fail(session->pass != NULL, -1);
-
- session->state = POP3_GETAUTH_APOP;
-
- if ((start = strchr(session->greeting, '<')) == NULL) {
- log_warning(_("Required APOP timestamp not found "
- "in greeting\n"));
- session->error_val = PS_PROTOCOL;
- return -1;
- }
-
- if ((end = strchr(start, '>')) == NULL || end == start + 1) {
- log_warning(_("Timestamp syntax error in greeting\n"));
- session->error_val = PS_PROTOCOL;
- return -1;
- }
-
- *(end + 1) = '\0';
-
- apop_str = g_strconcat(start, session->pass, NULL);
- md5_hex_digest(md5sum, apop_str);
- g_free(apop_str);
-
- pop3_gen_send(session, "APOP %s %s", session->user, md5sum);
-
- return PS_SUCCESS;
-}
-
-static gint pop3_getrange_stat_send(Pop3Session *session)
-{
- session->state = POP3_GETRANGE_STAT;
- pop3_gen_send(session, "STAT");
- return PS_SUCCESS;
-}
-
-static gint pop3_getrange_stat_recv(Pop3Session *session, const gchar *msg)
-{
- if (sscanf(msg, "%d %d", &session->count, &session->total_bytes) != 2) {
- log_warning(_("POP3 protocol error\n"));
- session->error_val = PS_PROTOCOL;
- return -1;
- } else {
- if (session->count == 0) {
- session->uidl_is_valid = TRUE;
- } else {
- session->msg = g_new0(Pop3MsgInfo, session->count + 1);
- session->cur_msg = 1;
- }
- }
-
- return PS_SUCCESS;
-}
-
-static gint pop3_getrange_last_send(Pop3Session *session)
-{
- session->state = POP3_GETRANGE_LAST;
- pop3_gen_send(session, "LAST");
- return PS_SUCCESS;
-}
-
-static gint pop3_getrange_last_recv(Pop3Session *session, const gchar *msg)
-{
- gint last;
-
- if (sscanf(msg, "%d", &last) == 0) {
- log_warning(_("POP3 protocol error\n"));
- session->error_val = PS_PROTOCOL;
- return -1;
- } else {
- if (session->count > last) {
- session->new_msg_exist = TRUE;
- session->cur_msg = last + 1;
- } else
- session->cur_msg = 0;
- }
-
- return PS_SUCCESS;
-}
-
-static gint pop3_getrange_uidl_send(Pop3Session *session)
-{
- session->state = POP3_GETRANGE_UIDL;
- pop3_gen_send(session, "UIDL");
- return PS_SUCCESS;
-}
-
-static gint pop3_getrange_uidl_recv(Pop3Session *session, const gchar *data,
- guint len)
-{
- gchar id[IDLEN + 1];
- gchar buf[POPBUFSIZE];
- gint buf_len;
- gint num;
- time_t recv_time;
- const gchar *p = data;
- const gchar *lastp = data + len;
- const gchar *newline;
-
- while (p < lastp) {
- if ((newline = memchr(p, '\r', lastp - p)) == NULL)
- return -1;
- buf_len = MIN(newline - p, sizeof(buf) - 1);
- memcpy(buf, p, buf_len);
- buf[buf_len] = '\0';
-
- p = newline + 1;
- if (p < lastp && *p == '\n') p++;
-
- if (sscanf(buf, "%d %" Xstr(IDLEN) "s", &num, id) != 2 ||
- num <= 0 || num > session->count) {
- log_warning(_("invalid UIDL response: %s\n"), buf);
- continue;
- }
-
- session->msg[num].uidl = g_strdup(id);
-
- recv_time = (time_t)g_hash_table_lookup(session->uidl_table, id);
- session->msg[num].recv_time = recv_time;
-
- if (!session->ac_prefs->getall && recv_time != RECV_TIME_NONE)
- session->msg[num].received = TRUE;
-
- if (!session->new_msg_exist &&
- (session->ac_prefs->getall || recv_time == RECV_TIME_NONE ||
- session->ac_prefs->rmmail)) {
- session->cur_msg = num;
- session->new_msg_exist = TRUE;
- }
- }
-
- session->uidl_is_valid = TRUE;
- return PS_SUCCESS;
-}
-
-static gint pop3_getsize_list_send(Pop3Session *session)
-{
- session->state = POP3_GETSIZE_LIST;
- pop3_gen_send(session, "LIST");
- return PS_SUCCESS;
-}
-
-static gint pop3_getsize_list_recv(Pop3Session *session, const gchar *data,
- guint len)
-{
- gchar buf[POPBUFSIZE];
- gint buf_len;
- guint num, size;
- const gchar *p = data;
- const gchar *lastp = data + len;
- const gchar *newline;
-
- while (p < lastp) {
- if ((newline = memchr(p, '\r', lastp - p)) == NULL)
- return -1;
- buf_len = MIN(newline - p, sizeof(buf) - 1);
- memcpy(buf, p, buf_len);
- buf[buf_len] = '\0';
-
- p = newline + 1;
- if (p < lastp && *p == '\n') p++;
-
- if (sscanf(buf, "%u %u", &num, &size) != 2) {
- session->error_val = PS_PROTOCOL;
- return -1;
- }
-
- if (num > 0 && num <= session->count)
- session->msg[num].size = size;
- if (num > 0 && num < session->cur_msg)
- session->cur_total_bytes += size;
- }
-
- return PS_SUCCESS;
-}
-
-static gint pop3_retr_send(Pop3Session *session)
-{
- session->state = POP3_RETR;
- pop3_gen_send(session, "RETR %d", session->cur_msg);
- return PS_SUCCESS;
-}
-
-static gint pop3_retr_recv(Pop3Session *session, const gchar *data, guint len)
-{
- gchar *file;
- gint drop_ok;
-
- file = get_tmp_file();
- if (pop3_write_msg_to_file(file, data, len) < 0) {
- g_free(file);
- session->error_val = PS_IOERR;
- return -1;
- }
-
- drop_ok = session->drop_message(session, file);
- g_unlink(file);
- g_free(file);
- if (drop_ok < 0) {
- session->error_val = PS_IOERR;
- return -1;
- }
-
- session->cur_total_bytes += session->msg[session->cur_msg].size;
- session->cur_total_recv_bytes += session->msg[session->cur_msg].size;
- session->cur_total_num++;
-
- session->msg[session->cur_msg].received = TRUE;
- session->msg[session->cur_msg].recv_time =
- drop_ok == DROP_DONT_RECEIVE ? RECV_TIME_KEEP
- : drop_ok == DROP_DELETE ? RECV_TIME_DELETE
- : session->current_time;
-
- return PS_SUCCESS;
-}
-
-static gint pop3_delete_send(Pop3Session *session)
-{
- session->state = POP3_DELETE;
- pop3_gen_send(session, "DELE %d", session->cur_msg);
- return PS_SUCCESS;
-}
-
-static gint pop3_delete_recv(Pop3Session *session)
-{
- session->msg[session->cur_msg].deleted = TRUE;
- return PS_SUCCESS;
-}
-
-static gint pop3_logout_send(Pop3Session *session)
-{
- session->state = POP3_LOGOUT;
- pop3_gen_send(session, "QUIT");
- return PS_SUCCESS;
-}
-
-static void pop3_gen_send(Pop3Session *session, const gchar *format, ...)
-{
- gchar buf[POPBUFSIZE + 1];
- va_list args;
-
- va_start(args, format);
- g_vsnprintf(buf, sizeof(buf) - 2, format, args);
- va_end(args);
-
- if (!g_ascii_strncasecmp(buf, "PASS ", 5))
- log_print("POP3> PASS ********\n");
- else
- log_print("POP3> %s\n", buf);
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
-}
-
-Session *pop3_session_new(PrefsAccount *account)
-{
- Pop3Session *session;
-
- g_return_val_if_fail(account != NULL, NULL);
-
- session = g_new0(Pop3Session, 1);
-
- session_init(SESSION(session));
-
- SESSION(session)->type = SESSION_POP3;
-
- SESSION(session)->recv_msg = pop3_session_recv_msg;
- SESSION(session)->recv_data_finished = pop3_session_recv_data_finished;
- SESSION(session)->send_data_finished = NULL;
-
- SESSION(session)->destroy = pop3_session_destroy;
-
- session->state = POP3_READY;
- session->ac_prefs = account;
- session->uidl_table = pop3_get_uidl_table(account);
- session->current_time = time(NULL);
- session->error_val = PS_SUCCESS;
- session->error_msg = NULL;
-
- return SESSION(session);
-}
-
-static void pop3_session_destroy(Session *session)
-{
- Pop3Session *pop3_session = POP3_SESSION(session);
- gint n;
-
- g_return_if_fail(session != NULL);
-
- for (n = 1; n <= pop3_session->count; n++)
- g_free(pop3_session->msg[n].uidl);
- g_free(pop3_session->msg);
-
- if (pop3_session->uidl_table) {
- hash_free_strings(pop3_session->uidl_table);
- g_hash_table_destroy(pop3_session->uidl_table);
- }
-
- g_free(pop3_session->greeting);
- g_free(pop3_session->user);
- g_free(pop3_session->pass);
- g_free(pop3_session->error_msg);
-}
-
-GHashTable *pop3_get_uidl_table(PrefsAccount *ac_prefs)
-{
- GHashTable *table;
- gchar *path;
- FILE *fp;
- gchar buf[POPBUFSIZE];
- gchar uidl[POPBUFSIZE];
- time_t recv_time;
- time_t now;
-
- table = g_hash_table_new(g_str_hash, g_str_equal);
-
- path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- UIDL_DIR, G_DIR_SEPARATOR_S, ac_prefs->recv_server,
- "-", ac_prefs->userid, NULL);
- if ((fp = g_fopen(path, "rb")) == NULL) {
- if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
- g_free(path);
- return table;
- }
- g_free(path);
-
- now = time(NULL);
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- strretchomp(buf);
- recv_time = RECV_TIME_NONE;
- if (sscanf(buf, "%s\t%ld", uidl, &recv_time) != 2) {
- if (sscanf(buf, "%s", uidl) != 1)
- continue;
- else
- recv_time = now;
- }
- if (recv_time == RECV_TIME_NONE)
- recv_time = RECV_TIME_RECEIVED;
- g_hash_table_insert(table, g_strdup(uidl),
- GINT_TO_POINTER(recv_time));
- }
-
- fclose(fp);
- return table;
-}
-
-gint pop3_write_uidl_list(Pop3Session *session)
-{
- gchar *path;
- FILE *fp;
- Pop3MsgInfo *msg;
- gint n;
-
- if (!session->uidl_is_valid) return 0;
-
- path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- "uidl", G_DIR_SEPARATOR_S,
- session->ac_prefs->recv_server,
- "-", session->ac_prefs->userid, NULL);
- if ((fp = g_fopen(path, "wb")) == NULL) {
- FILE_OP_ERROR(path, "fopen");
- g_free(path);
- return -1;
- }
-
- for (n = 1; n <= session->count; n++) {
- msg = &session->msg[n];
- if (msg->uidl && msg->received && !msg->deleted)
- fprintf(fp, "%s\t%ld\n", msg->uidl, msg->recv_time);
- }
-
- if (fclose(fp) == EOF) FILE_OP_ERROR(path, "fclose");
- g_free(path);
-
- return 0;
-}
-
-static gint pop3_write_msg_to_file(const gchar *file, const gchar *data,
- guint len)
-{
- FILE *fp;
- const gchar *prev, *cur;
-
- g_return_val_if_fail(file != NULL, -1);
-
- if ((fp = g_fopen(file, "wb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return -1;
- }
-
- if (change_file_mode_rw(fp, file) < 0)
- FILE_OP_ERROR(file, "chmod");
-
- /* +------------------+----------------+--------------------------+ *
- * ^data ^prev ^cur data+len-1^ */
-
- prev = data;
- while ((cur = (gchar *)my_memmem(prev, len - (prev - data), "\r\n", 2))
- != NULL) {
- if ((cur > prev && fwrite(prev, cur - prev, 1, fp) < 1) ||
- fputc('\n', fp) == EOF) {
- FILE_OP_ERROR(file, "fwrite");
- g_warning("can't write to file: %s\n", file);
- fclose(fp);
- g_unlink(file);
- return -1;
- }
-
- if (cur == data + len - 1) {
- prev = cur + 1;
- break;
- }
-
- if (*(cur + 1) == '\n')
- prev = cur + 2;
- else
- prev = cur + 1;
-
- if (prev - data < len - 1 && *prev == '.' && *(prev + 1) == '.')
- prev++;
-
- if (prev - data >= len)
- break;
- }
-
- if (prev - data < len &&
- fwrite(prev, len - (prev - data), 1, fp) < 1) {
- FILE_OP_ERROR(file, "fwrite");
- g_warning("can't write to file: %s\n", file);
- fclose(fp);
- g_unlink(file);
- return -1;
- }
- if (data[len - 1] != '\r' && data[len - 1] != '\n') {
- if (fputc('\n', fp) == EOF) {
- FILE_OP_ERROR(file, "fputc");
- g_warning("can't write to file: %s\n", file);
- fclose(fp);
- g_unlink(file);
- return -1;
- }
- }
-
- if (fclose(fp) == EOF) {
- FILE_OP_ERROR(file, "fclose");
- g_unlink(file);
- return -1;
- }
-
- return 0;
-}
-
-static Pop3State pop3_lookup_next(Pop3Session *session)
-{
- Pop3MsgInfo *msg;
- PrefsAccount *ac = session->ac_prefs;
- gint size;
- gboolean size_limit_over;
-
- for (;;) {
- msg = &session->msg[session->cur_msg];
- size = msg->size;
- size_limit_over =
- (ac->enable_size_limit &&
- ac->size_limit > 0 &&
- size > ac->size_limit * 1024);
-
- if (msg->recv_time == RECV_TIME_DELETE ||
- (ac->rmmail &&
- msg->recv_time != RECV_TIME_NONE &&
- msg->recv_time != RECV_TIME_KEEP &&
- session->current_time - msg->recv_time >=
- ac->msg_leave_time * 24 * 60 * 60)) {
- log_print(_("POP3: Deleting expired message %d\n"),
- session->cur_msg);
- pop3_delete_send(session);
- return POP3_DELETE;
- }
-
- if (size_limit_over)
- log_print
- (_("POP3: Skipping message %d (%d bytes)\n"),
- session->cur_msg, size);
-
- if (size == 0 || msg->received || size_limit_over) {
- session->cur_total_bytes += size;
- if (session->cur_msg == session->count) {
- pop3_logout_send(session);
- return POP3_LOGOUT;
- } else
- session->cur_msg++;
- } else
- break;
- }
-
- pop3_retr_send(session);
- return POP3_RETR;
-}
-
-static Pop3ErrorValue pop3_ok(Pop3Session *session, const gchar *msg)
-{
- Pop3ErrorValue ok;
-
- log_print("POP3< %s\n", msg);
-
- if (!strncmp(msg, "+OK", 3))
- ok = PS_SUCCESS;
- else if (!strncmp(msg, "-ERR", 4)) {
- if (strstr(msg + 4, "lock") ||
- strstr(msg + 4, "Lock") ||
- strstr(msg + 4, "LOCK") ||
- strstr(msg + 4, "wait")) {
- log_warning(_("mailbox is locked\n"));
- ok = PS_LOCKBUSY;
- } else if (strcasestr(msg + 4, "timeout")) {
- log_warning(_("session timeout\n"));
- ok = PS_ERROR;
- } else {
- switch (session->state) {
-#if USE_SSL
- case POP3_STLS:
- log_warning(_("can't start TLS session\n"));
- ok = PS_ERROR;
- break;
-#endif
- case POP3_GETAUTH_USER:
- case POP3_GETAUTH_PASS:
- case POP3_GETAUTH_APOP:
- log_warning(_("error occurred on authentication\n"));
- ok = PS_AUTHFAIL;
- break;
- case POP3_GETRANGE_LAST:
- case POP3_GETRANGE_UIDL:
- log_warning(_("command not supported\n"));
- ok = PS_NOTSUPPORTED;
- break;
- default:
- log_warning(_("error occurred on POP3 session\n"));
- ok = PS_ERROR;
- }
- }
-
- g_free(session->error_msg);
- session->error_msg = g_strdup(msg);
- fprintf(stderr, "POP3: %s\n", msg);
- } else
- ok = PS_PROTOCOL;
-
- session->error_val = ok;
- return ok;
-}
-
-static gint pop3_session_recv_msg(Session *session, const gchar *msg)
-{
- Pop3Session *pop3_session = POP3_SESSION(session);
- Pop3ErrorValue val = PS_SUCCESS;
- const gchar *body;
-
- body = msg;
- if (pop3_session->state != POP3_GETRANGE_UIDL_RECV &&
- pop3_session->state != POP3_GETSIZE_LIST_RECV) {
- val = pop3_ok(pop3_session, msg);
- if (val != PS_SUCCESS) {
- if (val != PS_NOTSUPPORTED) {
- pop3_session->state = POP3_ERROR;
- return -1;
- }
- }
-
- if (*body == '+' || *body == '-')
- body++;
- while (g_ascii_isalpha(*body))
- body++;
- while (g_ascii_isspace(*body))
- body++;
- }
-
- switch (pop3_session->state) {
- case POP3_READY:
- case POP3_GREETING:
- pop3_greeting_recv(pop3_session, body);
-#if USE_SSL
- if (pop3_session->ac_prefs->ssl_pop == SSL_STARTTLS)
- pop3_stls_send(pop3_session);
- else
-#endif
- if (pop3_session->ac_prefs->use_apop_auth)
- pop3_getauth_apop_send(pop3_session);
- else
- pop3_getauth_user_send(pop3_session);
- break;
-#if USE_SSL
- case POP3_STLS:
- if (pop3_stls_recv(pop3_session) != PS_SUCCESS)
- return -1;
- if (pop3_session->ac_prefs->use_apop_auth)
- pop3_getauth_apop_send(pop3_session);
- else
- pop3_getauth_user_send(pop3_session);
- break;
-#endif
- case POP3_GETAUTH_USER:
- pop3_getauth_pass_send(pop3_session);
- break;
- case POP3_GETAUTH_PASS:
- case POP3_GETAUTH_APOP:
- pop3_getrange_stat_send(pop3_session);
- break;
- case POP3_GETRANGE_STAT:
- if (pop3_getrange_stat_recv(pop3_session, body) < 0)
- return -1;
- if (pop3_session->count > 0)
- pop3_getrange_uidl_send(pop3_session);
- else
- pop3_logout_send(pop3_session);
- break;
- case POP3_GETRANGE_LAST:
- if (val == PS_NOTSUPPORTED)
- pop3_session->error_val = PS_SUCCESS;
- else if (pop3_getrange_last_recv(pop3_session, body) < 0)
- return -1;
- if (pop3_session->cur_msg > 0)
- pop3_getsize_list_send(pop3_session);
- else
- pop3_logout_send(pop3_session);
- break;
- case POP3_GETRANGE_UIDL:
- if (val == PS_NOTSUPPORTED) {
- pop3_session->error_val = PS_SUCCESS;
- pop3_getrange_last_send(pop3_session);
- } else {
- pop3_session->state = POP3_GETRANGE_UIDL_RECV;
- session_recv_data(session, 0, ".\r\n");
- }
- break;
- case POP3_GETSIZE_LIST:
- pop3_session->state = POP3_GETSIZE_LIST_RECV;
- session_recv_data(session, 0, ".\r\n");
- break;
- case POP3_RETR:
- pop3_session->state = POP3_RETR_RECV;
- session_recv_data(session, 0, ".\r\n");
- break;
- case POP3_DELETE:
- pop3_delete_recv(pop3_session);
- if (pop3_session->cur_msg == pop3_session->count)
- pop3_logout_send(pop3_session);
- else {
- pop3_session->cur_msg++;
- if (pop3_lookup_next(pop3_session) == POP3_ERROR)
- return -1;
- }
- break;
- case POP3_LOGOUT:
- session_disconnect(session);
- break;
- case POP3_ERROR:
- default:
- return -1;
- }
-
- return 0;
-}
-
-static gint pop3_session_recv_data_finished(Session *session, guchar *data,
- guint len)
-{
- Pop3Session *pop3_session = POP3_SESSION(session);
- Pop3ErrorValue val = PS_SUCCESS;
-
- switch (pop3_session->state) {
- case POP3_GETRANGE_UIDL_RECV:
- val = pop3_getrange_uidl_recv(pop3_session, data, len);
- if (val == PS_SUCCESS) {
- if (pop3_session->new_msg_exist)
- pop3_getsize_list_send(pop3_session);
- else
- pop3_logout_send(pop3_session);
- } else
- return -1;
- break;
- case POP3_GETSIZE_LIST_RECV:
- val = pop3_getsize_list_recv(pop3_session, data, len);
- if (val == PS_SUCCESS) {
- if (pop3_lookup_next(pop3_session) == POP3_ERROR)
- return -1;
- } else
- return -1;
- break;
- case POP3_RETR_RECV:
- if (pop3_retr_recv(pop3_session, data, len) < 0)
- return -1;
-
- if (pop3_session->msg[pop3_session->cur_msg].recv_time
- == RECV_TIME_DELETE ||
- (pop3_session->ac_prefs->rmmail &&
- pop3_session->ac_prefs->msg_leave_time == 0 &&
- pop3_session->msg[pop3_session->cur_msg].recv_time
- != RECV_TIME_KEEP))
- pop3_delete_send(pop3_session);
- else if (pop3_session->cur_msg == pop3_session->count)
- pop3_logout_send(pop3_session);
- else {
- pop3_session->cur_msg++;
- if (pop3_lookup_next(pop3_session) == POP3_ERROR)
- return -1;
- }
- break;
- case POP3_ERROR:
- default:
- return -1;
- }
-
- return 0;
-}
diff --git a/src/pop.h b/src/pop.h
deleted file mode 100644
index 515bc61b..00000000
--- a/src/pop.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2004 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __POP_H__
-#define __POP_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <time.h>
-
-#include "session.h"
-#include "prefs_account.h"
-
-typedef struct _Pop3MsgInfo Pop3MsgInfo;
-typedef struct _Pop3Session Pop3Session;
-
-#define POP3_SESSION(obj) ((Pop3Session *)obj)
-
-typedef enum {
- POP3_READY,
- POP3_GREETING,
-#if USE_SSL
- POP3_STLS,
-#endif
- POP3_GETAUTH_USER,
- POP3_GETAUTH_PASS,
- POP3_GETAUTH_APOP,
- POP3_GETRANGE_STAT,
- POP3_GETRANGE_LAST,
- POP3_GETRANGE_UIDL,
- POP3_GETRANGE_UIDL_RECV,
- POP3_GETSIZE_LIST,
- POP3_GETSIZE_LIST_RECV,
- POP3_RETR,
- POP3_RETR_RECV,
- POP3_DELETE,
- POP3_LOGOUT,
- POP3_ERROR,
-
- N_POP3_STATE
-} Pop3State;
-
-typedef enum {
- PS_SUCCESS = 0, /* command successful */
- PS_NOMAIL = 1, /* no mail available */
- PS_SOCKET = 2, /* socket I/O woes */
- PS_AUTHFAIL = 3, /* user authorization failed */
- PS_PROTOCOL = 4, /* protocol violation */
- PS_SYNTAX = 5, /* command-line syntax error */
- PS_IOERR = 6, /* file I/O error */
- PS_ERROR = 7, /* protocol error */
- PS_EXCLUDE = 8, /* client-side exclusion error */
- PS_LOCKBUSY = 9, /* server responded lock busy */
- PS_SMTP = 10, /* SMTP error */
- PS_DNS = 11, /* fatal DNS error */
- PS_BSMTP = 12, /* output batch could not be opened */
- PS_MAXFETCH = 13, /* poll ended by fetch limit */
-
- PS_NOTSUPPORTED = 14, /* command not supported */
-
- /* leave space for more codes */
-
- PS_CONTINUE = 128 /* more responses may follow */
-} Pop3ErrorValue;
-
-typedef enum {
- RECV_TIME_NONE = 0,
- RECV_TIME_RECEIVED = 1,
- RECV_TIME_KEEP = 2,
- RECV_TIME_DELETE = 3
-} RecvTime;
-
-typedef enum {
- DROP_OK = 0,
- DROP_DONT_RECEIVE = 1,
- DROP_DELETE = 2,
- DROP_ERROR = -1
-} Pop3DropValue;
-
-struct _Pop3MsgInfo
-{
- gint size;
- gchar *uidl;
- time_t recv_time;
- guint received : 1;
- guint deleted : 1;
-};
-
-struct _Pop3Session
-{
- Session session;
-
- Pop3State state;
-
- PrefsAccount *ac_prefs;
-
- gchar *greeting;
- gchar *user;
- gchar *pass;
- gint count;
- gint total_bytes;
- gint cur_msg;
- gint cur_total_num;
- gint cur_total_bytes;
- gint cur_total_recv_bytes;
-
- Pop3MsgInfo *msg;
-
- GHashTable *uidl_table;
-
- gboolean new_msg_exist;
- gboolean uidl_is_valid;
-
- time_t current_time;
-
- Pop3ErrorValue error_val;
- gchar *error_msg;
-
- gpointer data;
-
- /* virtual method to drop message */
- gint (*drop_message) (Pop3Session *session,
- const gchar *file);
-};
-
-#define POPBUFSIZE 512
-/* #define IDLEN 128 */
-#define IDLEN POPBUFSIZE
-
-Session *pop3_session_new (PrefsAccount *account);
-GHashTable *pop3_get_uidl_table (PrefsAccount *account);
-gint pop3_write_uidl_list (Pop3Session *session);
-
-#endif /* __POP_H__ */
diff --git a/src/prefs_account.c b/src/prefs_account.c
deleted file mode 100644
index b6d15fba..00000000
--- a/src/prefs_account.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include "prefs.h"
-#include "prefs_account.h"
-#include "customheader.h"
-#include "account.h"
-#include "utils.h"
-
-static PrefsAccount tmp_ac_prefs;
-
-static PrefParam param[] = {
- /* Basic */
- {"account_name", NULL, &tmp_ac_prefs.account_name, P_STRING},
- {"is_default", "FALSE", &tmp_ac_prefs.is_default, P_BOOL},
- {"name", NULL, &tmp_ac_prefs.name, P_STRING},
- {"address", NULL, &tmp_ac_prefs.address, P_STRING},
- {"organization", NULL, &tmp_ac_prefs.organization, P_STRING},
- {"protocol", NULL, &tmp_ac_prefs.protocol, P_ENUM},
- {"receive_server", NULL, &tmp_ac_prefs.recv_server, P_STRING},
- {"smtp_server", NULL, &tmp_ac_prefs.smtp_server, P_STRING},
- {"nntp_server", NULL, &tmp_ac_prefs.nntp_server, P_STRING},
- {"use_nntp_auth", "FALSE", &tmp_ac_prefs.use_nntp_auth, P_BOOL},
- {"user_id", "ENV_USER", &tmp_ac_prefs.userid, P_STRING},
- {"password", NULL, &tmp_ac_prefs.passwd, P_STRING},
- {"inbox", "inbox", &tmp_ac_prefs.inbox, P_STRING},
-
- /* Receive */
- {"use_apop_auth", "FALSE", &tmp_ac_prefs.use_apop_auth, P_BOOL},
- {"remove_mail", "TRUE", &tmp_ac_prefs.rmmail, P_BOOL},
- {"message_leave_time", "0", &tmp_ac_prefs.msg_leave_time, P_INT},
- {"get_all_mail", "FALSE", &tmp_ac_prefs.getall, P_BOOL},
- {"enable_size_limit", "FALSE", &tmp_ac_prefs.enable_size_limit, P_BOOL},
- {"size_limit", "1024", &tmp_ac_prefs.size_limit, P_INT},
- {"filter_on_receive", "TRUE", &tmp_ac_prefs.filter_on_recv, P_BOOL},
- {"imap_auth_method", "0", &tmp_ac_prefs.imap_auth_type, P_ENUM},
- {"max_nntp_articles", "300", &tmp_ac_prefs.max_nntp_articles, P_INT},
- {"receive_at_get_all", "TRUE", &tmp_ac_prefs.recv_at_getall, P_BOOL},
-
- /* Send */
- {"add_date", "TRUE", &tmp_ac_prefs.add_date, P_BOOL},
- {"generate_msgid", "TRUE", &tmp_ac_prefs.gen_msgid, P_BOOL},
- {"add_custom_header", "FALSE", &tmp_ac_prefs.add_customhdr, P_BOOL},
- {"use_smtp_auth", "FALSE", &tmp_ac_prefs.use_smtp_auth, P_BOOL},
- {"smtp_auth_method", "0", &tmp_ac_prefs.smtp_auth_type, P_ENUM},
- {"smtp_user_id", NULL, &tmp_ac_prefs.smtp_userid, P_STRING},
- {"smtp_password", NULL, &tmp_ac_prefs.smtp_passwd, P_STRING},
- {"pop_before_smtp", "FALSE", &tmp_ac_prefs.pop_before_smtp, P_BOOL},
-
- /* Compose */
- {"signature_type", "0", &tmp_ac_prefs.sig_type, P_ENUM},
- {"signature_path", "~" G_DIR_SEPARATOR_S DEFAULT_SIGNATURE,
- &tmp_ac_prefs.sig_path, P_STRING},
- {"set_autocc", "FALSE", &tmp_ac_prefs.set_autocc, P_BOOL},
- {"auto_cc", NULL, &tmp_ac_prefs.auto_cc, P_STRING},
- {"set_autobcc", "FALSE", &tmp_ac_prefs.set_autobcc, P_BOOL},
- {"auto_bcc", NULL, &tmp_ac_prefs.auto_bcc, P_STRING},
- {"set_autoreplyto", "FALSE", &tmp_ac_prefs.set_autoreplyto, P_BOOL},
- {"auto_replyto", NULL, &tmp_ac_prefs.auto_replyto, P_STRING},
-
-#if USE_GPGME
- /* Privacy */
- {"default_sign", "FALSE", &tmp_ac_prefs.default_sign, P_BOOL},
- {"default_encrypt", "FALSE", &tmp_ac_prefs.default_encrypt, P_BOOL},
- {"encrypt_reply", "TRUE", &tmp_ac_prefs.encrypt_reply, P_BOOL},
- {"ascii_armored", "FALSE", &tmp_ac_prefs.ascii_armored, P_BOOL},
- {"clearsign", "FALSE", &tmp_ac_prefs.clearsign, P_BOOL},
- {"sign_key", NULL, &tmp_ac_prefs.sign_key, P_ENUM},
- {"sign_key_id", NULL, &tmp_ac_prefs.sign_key_id, P_STRING},
-#endif /* USE_GPGME */
-
-#if USE_SSL
- /* SSL */
- {"ssl_pop", "0", &tmp_ac_prefs.ssl_pop, P_ENUM},
- {"ssl_imap", "0", &tmp_ac_prefs.ssl_imap, P_ENUM},
- {"ssl_nntp", "0", &tmp_ac_prefs.ssl_nntp, P_ENUM},
- {"ssl_smtp", "0", &tmp_ac_prefs.ssl_smtp, P_ENUM},
- {"use_nonblocking_ssl", "1", &tmp_ac_prefs.use_nonblocking_ssl, P_BOOL},
-#endif /* USE_SSL */
-
- /* Advanced */
- {"set_smtpport", "FALSE", &tmp_ac_prefs.set_smtpport, P_BOOL},
- {"smtp_port", "25", &tmp_ac_prefs.smtpport, P_USHORT},
- {"set_popport", "FALSE", &tmp_ac_prefs.set_popport, P_BOOL},
- {"pop_port", "110", &tmp_ac_prefs.popport, P_USHORT},
- {"set_imapport", "FALSE", &tmp_ac_prefs.set_imapport, P_BOOL},
- {"imap_port", "143", &tmp_ac_prefs.imapport, P_USHORT},
- {"set_nntpport", "FALSE", &tmp_ac_prefs.set_nntpport, P_BOOL},
- {"nntp_port", "119", &tmp_ac_prefs.nntpport, P_USHORT},
- {"set_domain", "FALSE", &tmp_ac_prefs.set_domain, P_BOOL},
- {"domain", NULL, &tmp_ac_prefs.domain, P_STRING},
- {"imap_directory", NULL, &tmp_ac_prefs.imap_dir, P_STRING},
- {"set_sent_folder", "FALSE", &tmp_ac_prefs.set_sent_folder, P_BOOL},
- {"sent_folder", NULL, &tmp_ac_prefs.sent_folder, P_STRING},
- {"set_draft_folder", "FALSE", &tmp_ac_prefs.set_draft_folder, P_BOOL},
- {"draft_folder", NULL, &tmp_ac_prefs.draft_folder, P_STRING},
- {"set_trash_folder", "FALSE", &tmp_ac_prefs.set_trash_folder, P_BOOL},
- {"trash_folder", NULL, &tmp_ac_prefs.trash_folder, P_STRING},
-
- {NULL, NULL, NULL, P_OTHER}
-};
-
-static gint prefs_account_get_new_id(void);
-
-
-PrefsAccount *prefs_account_get_tmp_prefs(void)
-{
- return &tmp_ac_prefs;
-}
-
-void prefs_account_set_tmp_prefs(PrefsAccount *ac_prefs)
-{
- tmp_ac_prefs = *ac_prefs;
-}
-
-void prefs_account_apply_tmp_prefs(PrefsAccount *ac_prefs)
-{
- *ac_prefs = tmp_ac_prefs;
-}
-
-PrefParam *prefs_account_get_params(void)
-{
- return param;
-}
-
-PrefsAccount *prefs_account_new(void)
-{
- PrefsAccount *ac_prefs;
-
- ac_prefs = g_new0(PrefsAccount, 1);
- memset(&tmp_ac_prefs, 0, sizeof(PrefsAccount));
- prefs_set_default(param);
- *ac_prefs = tmp_ac_prefs;
- ac_prefs->account_id = prefs_account_get_new_id();
-
- return ac_prefs;
-}
-
-void prefs_account_read_config(PrefsAccount *ac_prefs, const gchar *label)
-{
- const gchar *p = label;
- gchar *rcpath;
- gint id;
-
- g_return_if_fail(ac_prefs != NULL);
- g_return_if_fail(label != NULL);
-
- memset(&tmp_ac_prefs, 0, sizeof(PrefsAccount));
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
- prefs_read_config(param, label, rcpath, NULL);
- g_free(rcpath);
-
- *ac_prefs = tmp_ac_prefs;
- while (*p && !g_ascii_isdigit(*p)) p++;
- id = atoi(p);
- if (id < 0) g_warning("wrong account id: %d\n", id);
- ac_prefs->account_id = id;
-
- if (ac_prefs->protocol == A_APOP) {
- debug_print("converting protocol A_APOP to new prefs.\n");
- ac_prefs->protocol = A_POP3;
- ac_prefs->use_apop_auth = TRUE;
- }
-
- custom_header_read_config(ac_prefs);
-}
-
-void prefs_account_write_config_all(GList *account_list)
-{
- GList *cur;
- gchar *rcpath;
- PrefFile *pfile;
-
- rcpath = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, ACCOUNT_RC, NULL);
- if ((pfile = prefs_file_open(rcpath)) == NULL) {
- g_free(rcpath);
- return;
- }
- g_free(rcpath);
-
- for (cur = account_list; cur != NULL; cur = cur->next) {
- tmp_ac_prefs = *(PrefsAccount *)cur->data;
- if (fprintf(pfile->fp, "[Account: %d]\n",
- tmp_ac_prefs.account_id) <= 0 ||
- prefs_file_write_param(pfile, param) < 0) {
- g_warning(_("failed to write configuration to file\n"));
- prefs_file_close_revert(pfile);
- return;
- }
- if (cur->next) {
- if (fputc('\n', pfile->fp) == EOF) {
- FILE_OP_ERROR(rcpath, "fputc");
- prefs_file_close_revert(pfile);
- return;
- }
- }
- }
-
- if (prefs_file_close(pfile) < 0)
- g_warning(_("failed to write configuration to file\n"));
-}
-
-void prefs_account_free(PrefsAccount *ac_prefs)
-{
- if (!ac_prefs) return;
-
- tmp_ac_prefs = *ac_prefs;
- prefs_free(param);
-}
-
-static gint prefs_account_get_new_id(void)
-{
- GList *ac_list;
- PrefsAccount *ac;
- static gint last_id = 0;
-
- for (ac_list = account_get_list(); ac_list != NULL;
- ac_list = ac_list->next) {
- ac = (PrefsAccount *)ac_list->data;
- if (last_id < ac->account_id)
- last_id = ac->account_id;
- }
-
- return last_id + 1;
-}
diff --git a/src/prefs_account.h b/src/prefs_account.h
deleted file mode 100644
index 13ef8d94..00000000
--- a/src/prefs_account.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PREFS_ACCOUNT_H__
-#define __PREFS_ACCOUNT_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-
-typedef struct _PrefsAccount PrefsAccount;
-
-#include "folder.h"
-#include "smtp.h"
-#include "prefs.h"
-
-typedef enum {
- A_POP3,
- A_APOP, /* deprecated */
- A_RPOP, /* deprecated */
- A_IMAP4,
- A_NNTP,
- A_LOCAL
-} RecvProtocol;
-
-typedef enum {
- SIG_FILE,
- SIG_COMMAND,
- SIG_DIRECT
-} SigType;
-
-#if USE_GPGME
-typedef enum {
- SIGN_KEY_DEFAULT,
- SIGN_KEY_BY_FROM,
- SIGN_KEY_CUSTOM
-} SignKeyType;
-#endif /* USE_GPGME */
-
-struct _PrefsAccount
-{
- gchar *account_name;
-
- /* Personal info */
- gchar *name;
- gchar *address;
- gchar *organization;
-
- /* Server info */
- RecvProtocol protocol;
- gchar *recv_server;
- gchar *smtp_server;
- gchar *nntp_server;
- gboolean use_nntp_auth;
- gchar *userid;
- gchar *passwd;
-
-#if USE_SSL
- /* SSL */
- SSLType ssl_pop;
- SSLType ssl_imap;
- SSLType ssl_nntp;
- SSLType ssl_smtp;
- gboolean use_nonblocking_ssl;
-#endif /* USE_SSL */
-
- /* Temporarily preserved password */
- gchar *tmp_pass;
-
- /* Receive */
- gboolean use_apop_auth;
- gboolean rmmail;
- gint msg_leave_time;
- gboolean getall;
- gboolean recv_at_getall;
- gboolean enable_size_limit;
- gint size_limit;
- gboolean filter_on_recv;
- gchar *inbox;
-
- gint imap_auth_type;
- gint max_nntp_articles;
-
- /* Send */
- gboolean add_date;
- gboolean gen_msgid;
- gboolean add_customhdr;
- gboolean use_smtp_auth;
- SMTPAuthType smtp_auth_type;
- gchar *smtp_userid;
- gchar *smtp_passwd;
-
- /* Temporarily preserved password */
- gchar *tmp_smtp_pass;
-
- gboolean pop_before_smtp;
-
- GSList *customhdr_list;
-
- /* Compose */
- SigType sig_type;
- gchar *sig_path;
- gboolean set_autocc;
- gchar *auto_cc;
- gboolean set_autobcc;
- gchar *auto_bcc;
- gboolean set_autoreplyto;
- gchar *auto_replyto;
-
-#if USE_GPGME
- /* Privacy */
- gboolean default_sign;
- gboolean default_encrypt;
- gboolean ascii_armored;
- gboolean clearsign;
- gboolean encrypt_reply;
-
- SignKeyType sign_key;
- gchar *sign_key_id;
-#endif /* USE_GPGME */
-
- /* Advanced */
- gboolean set_smtpport;
- gushort smtpport;
- gboolean set_popport;
- gushort popport;
- gboolean set_imapport;
- gushort imapport;
- gboolean set_nntpport;
- gushort nntpport;
- gboolean set_domain;
- gchar *domain;
-
- gchar *imap_dir;
-
- gboolean set_sent_folder;
- gchar *sent_folder;
- gboolean set_draft_folder;
- gchar *draft_folder;
- gboolean set_trash_folder;
- gchar *trash_folder;
-
- /* Default or not */
- gboolean is_default;
- /* Unique account ID */
- gint account_id;
-
- RemoteFolder *folder;
-};
-
-PrefsAccount *prefs_account_new (void);
-
-PrefsAccount *prefs_account_get_tmp_prefs (void);
-void prefs_account_set_tmp_prefs (PrefsAccount *ac_prefs);
-void prefs_account_apply_tmp_prefs (PrefsAccount *ac_prefs);
-PrefParam *prefs_account_get_params (void);
-
-void prefs_account_read_config (PrefsAccount *ac_prefs,
- const gchar *label);
-void prefs_account_write_config_all (GList *account_list);
-
-void prefs_account_free (PrefsAccount *ac_prefs);
-
-#endif /* __PREFS_ACCOUNT_H__ */
diff --git a/src/prefs_common.c b/src/prefs_common.c
deleted file mode 100644
index eb1a1864..00000000
--- a/src/prefs_common.c
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <errno.h>
-
-#include "prefs.h"
-#include "prefs_common.h"
-#include "filter.h"
-#include "codeconv.h"
-#include "utils.h"
-
-PrefsCommon prefs_common;
-
-static PrefParam param[] = {
- /* Receive */
- {"use_ext_inc", "FALSE", &prefs_common.use_extinc, P_BOOL},
- {"ext_inc_path", DEFAULT_INC_PATH, &prefs_common.extinc_cmd, P_STRING},
-
- {"inc_local", "FALSE", &prefs_common.inc_local, P_BOOL},
- {"filter_on_inc_local", "TRUE", &prefs_common.filter_on_inc, P_BOOL},
- {"spool_path", DEFAULT_SPOOL_PATH, &prefs_common.spool_path, P_STRING},
-
- {"autochk_newmail", "FALSE", &prefs_common.autochk_newmail, P_BOOL},
- {"autochk_interval", "10", &prefs_common.autochk_itv, P_INT},
- {"check_on_startup", "FALSE", &prefs_common.chk_on_startup, P_BOOL},
- {"scan_all_after_inc", "FALSE", &prefs_common.scan_all_after_inc,
- P_BOOL},
- {"enable_newmsg_notify", "FALSE", &prefs_common.enable_newmsg_notify,
- P_BOOL},
- {"newmsg_notify_command", NULL, &prefs_common.newmsg_notify_cmd,
- P_STRING},
-
- /* Send */
- {"use_ext_sendmail", "FALSE", &prefs_common.use_extsend, P_BOOL},
- {"ext_sendmail_cmd", DEFAULT_SENDMAIL_CMD, &prefs_common.extsend_cmd,
- P_STRING},
- {"save_message", "TRUE", &prefs_common.savemsg, P_BOOL},
- {"filter_sent_message", "FALSE", &prefs_common.filter_sent, P_BOOL},
-
- {"outgoing_charset", CS_AUTO, &prefs_common.outgoing_charset, P_STRING},
- {"encoding_method", "0", &prefs_common.encoding_method, P_ENUM},
-
- {"allow_jisx0201_kana", "FALSE", &prefs_common.allow_jisx0201_kana,
- P_BOOL},
-
- /* Compose */
- {"auto_signature", "TRUE", &prefs_common.auto_sig, P_BOOL},
- {"signature_separator", "-- ", &prefs_common.sig_sep, P_STRING},
-
- {"auto_ext_editor", "FALSE", &prefs_common.auto_exteditor, P_BOOL},
-
- {"undo_level", "50", &prefs_common.undolevels, P_INT},
-
- {"linewrap_length", "72", &prefs_common.linewrap_len, P_INT},
- {"linewrap_quotation", "FALSE", &prefs_common.linewrap_quote, P_BOOL},
- {"linewrap_auto", "FALSE", &prefs_common.autowrap, P_BOOL},
- {"linewrap_before_sending", "FALSE", &prefs_common.linewrap_at_send,
- P_BOOL},
-
- {"reply_with_quote", "TRUE", &prefs_common.reply_with_quote, P_BOOL},
- {"reply_account_autoselect", "TRUE",
- &prefs_common.reply_account_autosel, P_BOOL},
- {"default_reply_list", "TRUE", &prefs_common.default_reply_list,
- P_BOOL},
-
- {"show_ruler", "TRUE", &prefs_common.show_ruler, P_BOOL},
-
- /* Quote */
- {"reply_quote_mark", "> ", &prefs_common.quotemark, P_STRING},
- {"reply_quote_format", "On %d\\n%f wrote:\\n\\n%Q",
- &prefs_common.quotefmt, P_STRING},
-
- {"forward_quote_mark", "> ", &prefs_common.fw_quotemark, P_STRING},
- {"forward_quote_format",
- "\\n\\nBegin forwarded message:\\n\\n"
- "?d{Date: %d\\n}?f{From: %f\\n}?t{To: %t\\n}?c{Cc: %c\\n}"
- "?n{Newsgroups: %n\\n}?s{Subject: %s\\n}\\n\\n%M",
- &prefs_common.fw_quotefmt, P_STRING},
-
- /* Display */
- {"message_font_name", DEFAULT_MESSAGE_FONT, &prefs_common.textfont,
- P_STRING},
-
- {"display_folder_unread_num", "TRUE",
- &prefs_common.display_folder_unread, P_BOOL},
- {"newsgroup_abbrev_len", "16", &prefs_common.ng_abbrev_len, P_INT},
-
- {"translate_header", "TRUE", &prefs_common.trans_hdr, P_BOOL},
-
- /* Display: Summary View */
- {"enable_swap_from", "FALSE", &prefs_common.swap_from, P_BOOL},
- {"date_format", "%y/%m/%d(%a) %H:%M", &prefs_common.date_format,
- P_STRING},
- {"expand_thread", "TRUE", &prefs_common.expand_thread, P_BOOL},
-
- {"enable_rules_hint", "TRUE", &prefs_common.enable_rules_hint, P_BOOL},
- {"bold_unread", "TRUE", &prefs_common.bold_unread, P_BOOL},
-
- {"toolbar_style", "3", &prefs_common.toolbar_style, P_ENUM},
- {"show_statusbar", "TRUE", &prefs_common.show_statusbar, P_BOOL},
-
- {"folderview_vscrollbar_policy", "0",
- &prefs_common.folderview_vscrollbar_policy, P_ENUM},
-
- {"summary_col_show_mark", "TRUE",
- &prefs_common.summary_col_visible[S_COL_MARK], P_BOOL},
- {"summary_col_show_unread", "TRUE",
- &prefs_common.summary_col_visible[S_COL_UNREAD], P_BOOL},
- {"summary_col_show_mime", "TRUE",
- &prefs_common.summary_col_visible[S_COL_MIME], P_BOOL},
- {"summary_col_show_subject", "TRUE",
- &prefs_common.summary_col_visible[S_COL_SUBJECT], P_BOOL},
- {"summary_col_show_from", "TRUE",
- &prefs_common.summary_col_visible[S_COL_FROM], P_BOOL},
- {"summary_col_show_date", "TRUE",
- &prefs_common.summary_col_visible[S_COL_DATE], P_BOOL},
- {"summary_col_show_size", "TRUE",
- &prefs_common.summary_col_visible[S_COL_SIZE], P_BOOL},
- {"summary_col_show_number", "FALSE",
- &prefs_common.summary_col_visible[S_COL_NUMBER], P_BOOL},
-
- {"summary_col_pos_mark", "0",
- &prefs_common.summary_col_pos[S_COL_MARK], P_INT},
- {"summary_col_pos_unread", "1",
- &prefs_common.summary_col_pos[S_COL_UNREAD], P_INT},
- {"summary_col_pos_mime", "2",
- &prefs_common.summary_col_pos[S_COL_MIME], P_INT},
- {"summary_col_pos_subject", "3",
- &prefs_common.summary_col_pos[S_COL_SUBJECT], P_INT},
- {"summary_col_pos_from", "4",
- &prefs_common.summary_col_pos[S_COL_FROM], P_INT},
- {"summary_col_pos_date", "5",
- &prefs_common.summary_col_pos[S_COL_DATE], P_INT},
- {"summary_col_pos_size", "6",
- &prefs_common.summary_col_pos[S_COL_SIZE], P_INT},
- {"summary_col_pos_number", "7",
- &prefs_common.summary_col_pos[S_COL_NUMBER], P_INT},
-
- {"summary_col_size_mark", "10",
- &prefs_common.summary_col_size[S_COL_MARK], P_INT},
- {"summary_col_size_unread", "13",
- &prefs_common.summary_col_size[S_COL_UNREAD], P_INT},
- {"summary_col_size_mime", "10",
- &prefs_common.summary_col_size[S_COL_MIME], P_INT},
- {"summary_col_size_subject", "200",
- &prefs_common.summary_col_size[S_COL_SUBJECT], P_INT},
- {"summary_col_size_from", "120",
- &prefs_common.summary_col_size[S_COL_FROM], P_INT},
- {"summary_col_size_date", "118",
- &prefs_common.summary_col_size[S_COL_DATE], P_INT},
- {"summary_col_size_size", "45",
- &prefs_common.summary_col_size[S_COL_SIZE], P_INT},
- {"summary_col_size_number", "40",
- &prefs_common.summary_col_size[S_COL_NUMBER], P_INT},
-
- /* Widget size */
- {"folderwin_x", "16", &prefs_common.folderwin_x, P_INT},
- {"folderwin_y", "16", &prefs_common.folderwin_y, P_INT},
- {"folderview_width", "179", &prefs_common.folderview_width, P_INT},
- {"folderview_height", "450", &prefs_common.folderview_height, P_INT},
- {"folderview_visible", "TRUE", &prefs_common.folderview_visible,
- P_BOOL},
-
- {"folder_col_folder", "150", &prefs_common.folder_col_folder, P_INT},
- {"folder_col_new", "32", &prefs_common.folder_col_new, P_INT},
- {"folder_col_unread", "32", &prefs_common.folder_col_unread, P_INT},
- {"folder_col_total", "32", &prefs_common.folder_col_total, P_INT},
-
- {"summaryview_width", "600", &prefs_common.summaryview_width, P_INT},
- {"summaryview_height", "157", &prefs_common.summaryview_height, P_INT},
-
- {"main_messagewin_x", "256", &prefs_common.main_msgwin_x, P_INT},
- {"main_messagewin_y", "210", &prefs_common.main_msgwin_y, P_INT},
- {"messageview_width", "600", &prefs_common.msgview_width, P_INT},
- {"messageview_height", "300", &prefs_common.msgview_height, P_INT},
- {"messageview_visible", "TRUE", &prefs_common.msgview_visible, P_BOOL},
-
- {"mainview_x", "64", &prefs_common.mainview_x, P_INT},
- {"mainview_y", "64", &prefs_common.mainview_y, P_INT},
- {"mainview_width", "600", &prefs_common.mainview_width, P_INT},
- {"mainview_height", "600", &prefs_common.mainview_height, P_INT},
- {"mainwin_x", "64", &prefs_common.mainwin_x, P_INT},
- {"mainwin_y", "64", &prefs_common.mainwin_y, P_INT},
- {"mainwin_width", "800", &prefs_common.mainwin_width, P_INT},
- {"mainwin_height", "600", &prefs_common.mainwin_height, P_INT},
- {"messagewin_width", "600", &prefs_common.msgwin_width, P_INT},
- {"messagewin_height", "540", &prefs_common.msgwin_height, P_INT},
- {"sourcewin_width", "600", &prefs_common.sourcewin_width, P_INT},
- {"sourcewin_height", "500", &prefs_common.sourcewin_height, P_INT},
- {"compose_width", "600", &prefs_common.compose_width, P_INT},
- {"compose_height", "560", &prefs_common.compose_height, P_INT},
-
- /* Message */
- {"enable_color", "TRUE", &prefs_common.enable_color, P_BOOL},
-
- {"quote_level1_color", "179", &prefs_common.quote_level1_col, P_INT},
- {"quote_level2_color", "179", &prefs_common.quote_level2_col, P_INT},
- {"quote_level3_color", "179", &prefs_common.quote_level3_col, P_INT},
- {"uri_color", "32512", &prefs_common.uri_col, P_INT},
- {"signature_color", "0", &prefs_common.sig_col, P_USHORT},
- {"recycle_quote_colors", "FALSE", &prefs_common.recycle_quote_colors,
- P_BOOL},
-
- {"convert_mb_alnum", "FALSE", &prefs_common.conv_mb_alnum, P_BOOL},
- {"display_header_pane", "TRUE", &prefs_common.display_header_pane,
- P_BOOL},
- {"display_header", "TRUE", &prefs_common.display_header, P_BOOL},
- {"render_html", "TRUE", &prefs_common.render_html, P_BOOL},
- {"line_space", "2", &prefs_common.line_space, P_INT},
-
- {"textview_cursor_visible", "FALSE",
- &prefs_common.textview_cursor_visible, P_BOOL},
-
- {"enable_smooth_scroll", "FALSE", &prefs_common.enable_smooth_scroll,
- P_BOOL},
- {"scroll_step", "1", &prefs_common.scroll_step, P_INT},
- {"scroll_half_page", "FALSE", &prefs_common.scroll_halfpage, P_BOOL},
-
- {"resize_image", "TRUE", &prefs_common.resize_image, P_BOOL},
- {"inline_image", "TRUE", &prefs_common.inline_image, P_BOOL},
-
- {"show_other_header", "FALSE", &prefs_common.show_other_header, P_BOOL},
-
- /* MIME viewer */
- {"mime_image_viewer", "display '%s'", &prefs_common.mime_image_viewer,
- P_STRING},
- {"mime_audio_player", "play '%s'", &prefs_common.mime_audio_player,
- P_STRING},
- {"mime_open_command", "gedit '%s'", &prefs_common.mime_open_cmd,
- P_STRING},
-
- /* Junk mail */
- {"enable_junk", "FALSE", &prefs_common.enable_junk, P_BOOL},
- {"junk_learn_command", "bogofilter -s -I", &prefs_common.junk_learncmd,
- P_STRING},
- {"nojunk_learn_command", "bogofilter -n -I",
- &prefs_common.nojunk_learncmd, P_STRING},
- {"junk_classify_command", "bogofilter -I",
- &prefs_common.junk_classify_cmd, P_STRING},
- {"junk_folder", NULL, &prefs_common.junk_folder, P_STRING},
- {"filter_junk_on_receive", "FALSE", &prefs_common.filter_junk_on_recv,
- P_BOOL},
-
-#if USE_GPGME
- /* Privacy */
- {"auto_check_signatures", "TRUE", &prefs_common.auto_check_signatures,
- P_BOOL},
- {"gpg_signature_popup", "FALSE", &prefs_common.gpg_signature_popup,
- P_BOOL},
- {"store_passphrase", "FALSE", &prefs_common.store_passphrase, P_BOOL},
- {"store_passphrase_timeout", "0",
- &prefs_common.store_passphrase_timeout, P_INT},
-#ifndef G_OS_WIN32
- {"passphrase_grab", "FALSE", &prefs_common.passphrase_grab, P_BOOL},
-#endif /* G_OS_WIN32 */
- {"gpg_warning", "TRUE", &prefs_common.gpg_warning, P_BOOL},
-#endif /* USE_GPGME */
-
- /* Interface */
- {"separate_folder", "FALSE", &prefs_common.sep_folder, P_BOOL},
- {"separate_message", "FALSE", &prefs_common.sep_msg, P_BOOL},
-
- {"always_show_message_when_selected", "FALSE",
- &prefs_common.always_show_msg, P_BOOL},
- {"open_unread_on_enter", "FALSE", &prefs_common.open_unread_on_enter,
- P_BOOL},
- {"mark_as_read_on_new_window", "FALSE",
- &prefs_common.mark_as_read_on_new_window, P_BOOL},
- {"open_inbox_on_inc", "FALSE", &prefs_common.open_inbox_on_inc, P_BOOL},
- {"immediate_execution", "TRUE", &prefs_common.immediate_exec, P_BOOL},
- {"receive_dialog_mode", "1", &prefs_common.recv_dialog_mode, P_ENUM},
- {"no_receive_error_panel", "FALSE", &prefs_common.no_recv_err_panel,
- P_BOOL},
- {"close_receive_dialog", "TRUE", &prefs_common.close_recv_dialog,
- P_BOOL},
-
-#ifdef G_OS_WIN32
- {"comply_gnome_hig", "FALSE", &prefs_common.comply_gnome_hig, P_BOOL},
-#else
- {"comply_gnome_hig", "TRUE", &prefs_common.comply_gnome_hig, P_BOOL},
-#endif
-
- /* Other */
- {"uri_open_command", DEFAULT_BROWSER_CMD, &prefs_common.uri_cmd,
- P_STRING},
- {"print_command", "lpr %s", &prefs_common.print_cmd, P_STRING},
- {"ext_editor_command", "gedit %s", &prefs_common.ext_editor_cmd,
- P_STRING},
-
- {"add_address_by_click", "FALSE", &prefs_common.add_address_by_click,
- P_BOOL},
-
- {"confirm_on_exit", "FALSE", &prefs_common.confirm_on_exit, P_BOOL},
- {"clean_trash_on_exit", "FALSE", &prefs_common.clean_on_exit, P_BOOL},
- {"ask_on_cleaning", "TRUE", &prefs_common.ask_on_clean, P_BOOL},
- {"warn_queued_on_exit", "TRUE", &prefs_common.warn_queued_on_exit,
- P_BOOL},
-
- {"logwindow_line_limit", "1000", &prefs_common.logwin_line_limit,
- P_INT},
-
- /* Advanced */
- {"strict_cache_check", "FALSE", &prefs_common.strict_cache_check,
- P_BOOL},
- {"io_timeout_secs", "60", &prefs_common.io_timeout_secs, P_INT},
-
- {NULL, NULL, NULL, P_OTHER}
-};
-
-
-PrefParam *prefs_common_get_params(void)
-{
- return param;
-}
-
-void prefs_common_read_config(void)
-{
- FILE *fp;
- gchar *path;
- gchar buf[PREFSBUFSIZE];
-
- path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMON_RC, NULL);
-
- prefs_read_config(param, "Common", path, NULL);
- g_free(path);
-
- prefs_common.online_mode = TRUE;
-
- prefs_common_junk_filter_list_set();
-
- path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMAND_HISTORY,
- NULL);
- if ((fp = g_fopen(path, "rb")) == NULL) {
- if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
- g_free(path);
- return;
- }
- g_free(path);
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- g_strstrip(buf);
- if (buf[0] == '\0') continue;
- prefs_common.mime_open_cmd_history =
- add_history(prefs_common.mime_open_cmd_history, buf);
- }
- fclose(fp);
-
- prefs_common.mime_open_cmd_history =
- g_list_reverse(prefs_common.mime_open_cmd_history);
-}
-
-void prefs_common_write_config(void)
-{
- GList *cur;
- FILE *fp;
- gchar *path;
-
- prefs_write_config(param, "Common", COMMON_RC);
-
- path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S, COMMAND_HISTORY,
- NULL);
- if ((fp = g_fopen(path, "wb")) == NULL) {
- FILE_OP_ERROR(path, "fopen");
- g_free(path);
- return;
- }
-
- for (cur = prefs_common.mime_open_cmd_history;
- cur != NULL; cur = cur->next) {
- fputs((gchar *)cur->data, fp);
- fputc('\n', fp);
- }
-
- fclose(fp);
- g_free(path);
-}
-
-void prefs_common_junk_filter_list_set(void)
-{
- FilterRule *rule;
- FilterCond *cond;
- FilterAction *action;
- GSList *cond_list = NULL, *action_list = NULL;
-
- if (prefs_common.junk_fltlist) {
- filter_rule_list_free(prefs_common.junk_fltlist);
- prefs_common.junk_fltlist = NULL;
- }
-
- if (!prefs_common.junk_classify_cmd || !prefs_common.junk_folder)
- return;
-
- cond = filter_cond_new(FLT_COND_CMD_TEST, 0, 0, NULL,
- prefs_common.junk_classify_cmd);
- cond_list = g_slist_append(NULL, cond);
- action = filter_action_new(FLT_ACTION_COPY, prefs_common.junk_folder);
- action_list = g_slist_append(NULL, action);
- action = filter_action_new(FLT_ACTION_DELETE, NULL);
- action_list = g_slist_append(action_list, action);
-
- rule = filter_rule_new(_("Junk mail filter"), FLT_OR,
- cond_list, action_list);
-
- prefs_common.junk_fltlist = g_slist_append(NULL, rule);
-}
diff --git a/src/prefs_common.h b/src/prefs_common.h
deleted file mode 100644
index afc5f1d0..00000000
--- a/src/prefs_common.h
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PREFS_COMMON_H__
-#define __PREFS_COMMON_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-
-typedef struct _PrefsCommon PrefsCommon;
-
-#include "enums.h"
-#include "prefs.h"
-
-typedef enum {
- RECV_DIALOG_ALWAYS,
- RECV_DIALOG_MANUAL,
- RECV_DIALOG_NEVER
-} RecvDialogMode;
-
-typedef enum {
- CTE_AUTO,
- CTE_BASE64,
- CTE_QUOTED_PRINTABLE,
- CTE_8BIT
-} TransferEncodingMethod;
-
-struct _PrefsCommon
-{
- /* Receive */
- gboolean use_extinc;
- gchar *extinc_cmd;
- gboolean inc_local;
- gboolean filter_on_inc;
- gchar *spool_path;
- gboolean scan_all_after_inc;
- gboolean autochk_newmail;
- gint autochk_itv;
- gboolean chk_on_startup;
- gboolean enable_newmsg_notify;
- gchar *newmsg_notify_cmd;
-
- /* Send */
- gboolean use_extsend;
- gchar *extsend_cmd;
- gboolean savemsg;
- gboolean filter_sent;
- gchar *outgoing_charset;
- TransferEncodingMethod encoding_method;
-
- gboolean allow_jisx0201_kana;
-
- /* Compose */
- gboolean auto_sig;
- gchar *sig_sep;
- gint undolevels;
- gint linewrap_len;
- gboolean linewrap_quote;
- gboolean autowrap;
- gboolean linewrap_at_send;
- gboolean auto_exteditor;
- gboolean reply_account_autosel;
- gboolean default_reply_list;
- gboolean show_ruler;
-
- /* Quote */
- gboolean reply_with_quote;
- gchar *quotemark;
- gchar *quotefmt;
- gchar *fw_quotemark;
- gchar *fw_quotefmt;
-
- /* Display */
- gchar *textfont;
-
- gboolean trans_hdr;
- gboolean display_folder_unread;
- gint ng_abbrev_len;
-
- gboolean swap_from;
- gboolean expand_thread;
- gchar *date_format;
-
- gboolean enable_rules_hint;
- gboolean bold_unread;
-
- ToolbarStyle toolbar_style;
- gboolean show_statusbar;
-
- gint folderview_vscrollbar_policy;
-
- /* Summary columns visibility, position and size */
- gboolean summary_col_visible[N_SUMMARY_COLS];
- gint summary_col_pos[N_SUMMARY_COLS];
- gint summary_col_size[N_SUMMARY_COLS];
-
- /* Widget visibility, position and size */
- gint folderwin_x;
- gint folderwin_y;
- gint folderview_width;
- gint folderview_height;
- gboolean folderview_visible;
-
- gint folder_col_folder;
- gint folder_col_new;
- gint folder_col_unread;
- gint folder_col_total;
-
- gint summaryview_width;
- gint summaryview_height;
-
- gint main_msgwin_x;
- gint main_msgwin_y;
- gint msgview_width;
- gint msgview_height;
- gboolean msgview_visible;
-
- gint mainview_x;
- gint mainview_y;
- gint mainview_width;
- gint mainview_height;
- gint mainwin_x;
- gint mainwin_y;
- gint mainwin_width;
- gint mainwin_height;
-
- gint msgwin_width;
- gint msgwin_height;
-
- gint sourcewin_width;
- gint sourcewin_height;
-
- gint compose_width;
- gint compose_height;
-
- /* Message */
- gboolean enable_color;
- gint quote_level1_col;
- gint quote_level2_col;
- gint quote_level3_col;
- gint uri_col;
- gushort sig_col;
- gboolean recycle_quote_colors;
- gboolean conv_mb_alnum;
- gboolean display_header_pane;
- gboolean display_header;
- gint line_space;
- gboolean render_html;
- gboolean textview_cursor_visible;
- gboolean enable_smooth_scroll;
- gint scroll_step;
- gboolean scroll_halfpage;
-
- gboolean resize_image;
- gboolean inline_image;
-
- gchar *force_charset;
-
- gboolean show_other_header;
- GSList *disphdr_list;
-
- /* MIME viewer */
- gchar *mime_image_viewer;
- gchar *mime_audio_player;
- gchar *mime_open_cmd;
-
- GList *mime_open_cmd_history;
-
- /* Junk Mail */
- gboolean enable_junk;
- gchar *junk_learncmd;
- gchar *nojunk_learncmd;
- gchar *junk_classify_cmd;
- gchar *junk_folder;
- gboolean filter_junk_on_recv;
-
-#if USE_GPGME
- /* Privacy */
- gboolean auto_check_signatures;
- gboolean gpg_signature_popup;
- gboolean store_passphrase;
- gint store_passphrase_timeout;
- gboolean passphrase_grab;
- gboolean gpg_warning;
-#endif /* USE_GPGME */
-
- /* Interface */
- gboolean sep_folder;
- gboolean sep_msg;
- gboolean always_show_msg;
- gboolean open_unread_on_enter;
- gboolean mark_as_read_on_new_window;
- gboolean open_inbox_on_inc;
- gboolean immediate_exec;
- RecvDialogMode recv_dialog_mode;
- gboolean no_recv_err_panel;
- gboolean close_recv_dialog;
- gboolean comply_gnome_hig;
-
- /* Other */
- gchar *uri_cmd;
- gchar *print_cmd;
- gchar *ext_editor_cmd;
-
- gboolean add_address_by_click;
-
- gboolean confirm_on_exit;
- gboolean clean_on_exit;
- gboolean ask_on_clean;
- gboolean warn_queued_on_exit;
-
- gint logwin_line_limit;
-
- /* Advanced */
- gboolean strict_cache_check;
- gint io_timeout_secs;
-
- /* Filtering */
- GSList *fltlist;
- GSList *junk_fltlist;
-
- /* Actions */
- GSList *actions_list;
-
- /* Online / Offline */
- gboolean online_mode;
-};
-
-extern PrefsCommon prefs_common;
-
-PrefParam *prefs_common_get_params (void);
-
-void prefs_common_read_config (void);
-void prefs_common_write_config (void);
-
-void prefs_common_junk_filter_list_set (void);
-
-#endif /* __PREFS_COMMON_H__ */
diff --git a/src/procheader.c b/src/procheader.c
deleted file mode 100644
index 4ca1490c..00000000
--- a/src/procheader.c
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <time.h>
-#include <sys/stat.h>
-
-#include "procheader.h"
-#include "procmsg.h"
-#include "codeconv.h"
-#include "prefs_common.h"
-#include "utils.h"
-
-#define BUFFSIZE 8192
-
-gint procheader_get_one_field(gchar *buf, size_t len, FILE *fp,
- HeaderEntry hentry[])
-{
- gint nexthead;
- gint hnum = 0;
- HeaderEntry *hp = NULL;
-
- if (hentry != NULL) {
- /* skip non-required headers */
- do {
- do {
- if (fgets(buf, len, fp) == NULL)
- return -1;
- if (buf[0] == '\r' || buf[0] == '\n')
- return -1;
- } while (buf[0] == ' ' || buf[0] == '\t');
-
- for (hp = hentry, hnum = 0; hp->name != NULL;
- hp++, hnum++) {
- if (!g_ascii_strncasecmp(hp->name, buf,
- strlen(hp->name)))
- break;
- }
- } while (hp->name == NULL);
- } else {
- if (fgets(buf, len, fp) == NULL) return -1;
- if (buf[0] == '\r' || buf[0] == '\n') return -1;
- }
-
- /* unfold the specified folded line */
- if (hp && hp->unfold) {
- gboolean folded = FALSE;
- gchar *bufp = buf + strlen(buf);
-
- for (; bufp > buf &&
- (*(bufp - 1) == '\n' || *(bufp - 1) == '\r');
- bufp--)
- *(bufp - 1) = '\0';
-
- while (1) {
- nexthead = fgetc(fp);
-
- /* folded */
- if (nexthead == ' ' || nexthead == '\t')
- folded = TRUE;
- else if (nexthead == EOF)
- break;
- else if (folded == TRUE) {
- if ((len - (bufp - buf)) <= 2) break;
-
- if (nexthead == '\n') {
- folded = FALSE;
- continue;
- }
-
- /* replace return code on the tail end
- with space */
- *bufp++ = ' ';
- *bufp++ = nexthead;
- *bufp = '\0';
-
- /* concatenate next line */
- if (fgets(bufp, len - (bufp - buf), fp)
- == NULL) break;
- bufp += strlen(bufp);
-
- for (; bufp > buf &&
- (*(bufp - 1) == '\n' || *(bufp - 1) == '\r');
- bufp--)
- *(bufp - 1) = '\0';
-
- folded = FALSE;
- } else {
- ungetc(nexthead, fp);
- break;
- }
- }
-
- return hnum;
- }
-
- while (1) {
- nexthead = fgetc(fp);
- if (nexthead == ' ' || nexthead == '\t') {
- size_t buflen = strlen(buf);
-
- /* concatenate next line */
- if ((len - buflen) > 2) {
- gchar *p = buf + buflen;
-
- *p++ = nexthead;
- *p = '\0';
- buflen++;
- if (fgets(p, len - buflen, fp) == NULL)
- break;
- } else
- break;
- } else {
- if (nexthead != EOF)
- ungetc(nexthead, fp);
- break;
- }
- }
-
- /* remove trailing return code */
- strretchomp(buf);
-
- return hnum;
-}
-
-gchar *procheader_get_unfolded_line(gchar *buf, size_t len, FILE *fp)
-{
- gboolean folded = FALSE;
- gint nexthead;
- gchar *bufp;
-
- if (fgets(buf, len, fp) == NULL) return NULL;
- if (buf[0] == '\r' || buf[0] == '\n') return NULL;
- bufp = buf + strlen(buf);
-
- for (; bufp > buf &&
- (*(bufp - 1) == '\n' || *(bufp - 1) == '\r');
- bufp--)
- *(bufp - 1) = '\0';
-
- while (1) {
- nexthead = fgetc(fp);
-
- /* folded */
- if (nexthead == ' ' || nexthead == '\t')
- folded = TRUE;
- else if (nexthead == EOF)
- break;
- else if (folded == TRUE) {
- if ((len - (bufp - buf)) <= 2) break;
-
- if (nexthead == '\n') {
- folded = FALSE;
- continue;
- }
-
- /* replace return code on the tail end
- with space */
- *bufp++ = ' ';
- *bufp++ = nexthead;
- *bufp = '\0';
-
- /* concatenate next line */
- if (fgets(bufp, len - (bufp - buf), fp)
- == NULL) break;
- bufp += strlen(bufp);
-
- for (; bufp > buf &&
- (*(bufp - 1) == '\n' || *(bufp - 1) == '\r');
- bufp--)
- *(bufp - 1) = '\0';
-
- folded = FALSE;
- } else {
- ungetc(nexthead, fp);
- break;
- }
- }
-
- /* remove trailing return code */
- strretchomp(buf);
-
- return buf;
-}
-
-GSList *procheader_get_header_list_from_file(const gchar *file)
-{
- FILE *fp;
- GSList *hlist;
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return NULL;
- }
-
- hlist = procheader_get_header_list(fp);
-
- fclose(fp);
- return hlist;
-}
-
-GSList *procheader_get_header_list(FILE *fp)
-{
- gchar buf[BUFFSIZE];
- gchar *p;
- GSList *hlist = NULL;
- Header *header;
-
- g_return_val_if_fail(fp != NULL, NULL);
-
- while (procheader_get_unfolded_line(buf, sizeof(buf), fp) != NULL) {
- if (*buf == ':') continue;
- for (p = buf; *p && *p != ' '; p++) {
- if (*p == ':') {
- header = g_new(Header, 1);
- header->name = g_strndup(buf, p - buf);
- p++;
- while (*p == ' ' || *p == '\t') p++;
- header->body = conv_unmime_header(p, NULL);
-
- hlist = g_slist_append(hlist, header);
- break;
- }
- }
- }
-
- return hlist;
-}
-
-GSList *procheader_add_header_list(GSList *hlist, const gchar *header_name,
- const gchar *body)
-{
- Header *header;
-
- g_return_val_if_fail(header_name != NULL, hlist);
-
- header = g_new(Header, 1);
- header->name = g_strdup(header_name);
- header->body = g_strdup(body);
-
- return g_slist_append(hlist, header);
-}
-
-GSList *procheader_merge_header_list(GSList *hlist1, GSList *hlist2)
-{
- GSList *cur;
-
- for (cur = hlist2; cur != NULL; cur = cur->next) {
- Header *header = (Header *)cur->data;
- if (procheader_find_header_list(hlist1, header->name) < 0)
- hlist1 = g_slist_append(hlist1, header);
- }
-
- return hlist1;
-}
-
-gint procheader_find_header_list(GSList *hlist, const gchar *header_name)
-{
- GSList *cur;
- gint index = 0;
- Header *header;
-
- g_return_val_if_fail(header_name != NULL, -1);
-
- for (cur = hlist; cur != NULL; cur = cur->next, index++) {
- header = (Header *)cur->data;
- if (g_ascii_strcasecmp(header->name, header_name) == 0)
- return index;
- }
-
- return -1;
-}
-
-GPtrArray *procheader_get_header_array(FILE *fp, const gchar *encoding)
-{
- gchar buf[BUFFSIZE];
- gchar *p;
- GPtrArray *headers;
- Header *header;
-
- g_return_val_if_fail(fp != NULL, NULL);
-
- headers = g_ptr_array_new();
-
- while (procheader_get_unfolded_line(buf, sizeof(buf), fp) != NULL) {
- if (*buf == ':') continue;
- for (p = buf; *p && *p != ' '; p++) {
- if (*p == ':') {
- header = g_new(Header, 1);
- header->name = g_strndup(buf, p - buf);
- p++;
- while (*p == ' ' || *p == '\t') p++;
- header->body = conv_unmime_header(p, encoding);
-
- g_ptr_array_add(headers, header);
- break;
- }
- }
- }
-
- return headers;
-}
-
-GPtrArray *procheader_get_header_array_asis(FILE *fp, const gchar *encoding)
-{
- gchar buf[BUFFSIZE];
- gchar *p;
- GPtrArray *headers;
- Header *header;
-
- g_return_val_if_fail(fp != NULL, NULL);
-
- headers = g_ptr_array_new();
-
- while (procheader_get_one_field(buf, sizeof(buf), fp, NULL) != -1) {
- if (*buf == ':') continue;
- for (p = buf; *p && *p != ' '; p++) {
- if (*p == ':') {
- header = g_new(Header, 1);
- header->name = g_strndup(buf, p - buf);
- p++;
- header->body = conv_unmime_header(p, encoding);
-
- g_ptr_array_add(headers, header);
- break;
- }
- }
- }
-
- return headers;
-}
-
-void procheader_header_list_destroy(GSList *hlist)
-{
- Header *header;
-
- while (hlist != NULL) {
- header = hlist->data;
- procheader_header_free(header);
- hlist = g_slist_remove(hlist, header);
- }
-}
-
-void procheader_header_array_destroy(GPtrArray *harray)
-{
- gint i;
- Header *header;
-
- for (i = 0; i < harray->len; i++) {
- header = g_ptr_array_index(harray, i);
- procheader_header_free(header);
- }
-
- g_ptr_array_free(harray, TRUE);
-}
-
-void procheader_header_free(Header *header)
-{
- if (!header) return;
-
- g_free(header->name);
- g_free(header->body);
- g_free(header);
-}
-
-void procheader_get_header_fields(FILE *fp, HeaderEntry hentry[])
-{
- gchar buf[BUFFSIZE];
- HeaderEntry *hp;
- gint hnum;
- gchar *p;
-
- if (hentry == NULL) return;
-
- while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
- != -1) {
- hp = hentry + hnum;
-
- p = buf + strlen(hp->name);
- while (*p == ' ' || *p == '\t') p++;
-
- if (hp->body == NULL)
- hp->body = g_strdup(p);
- else if (!g_ascii_strcasecmp(hp->name, "To:") ||
- !g_ascii_strcasecmp(hp->name, "Cc:")) {
- gchar *tp = hp->body;
- hp->body = g_strconcat(tp, ", ", p, NULL);
- g_free(tp);
- }
- }
-}
-
-MsgInfo *procheader_parse_file(const gchar *file, MsgFlags flags,
- gboolean full)
-{
- struct stat s;
- FILE *fp;
- MsgInfo *msginfo;
-
- if (g_stat(file, &s) < 0) {
- FILE_OP_ERROR(file, "stat");
- return NULL;
- }
- if (!S_ISREG(s.st_mode))
- return NULL;
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return NULL;
- }
-
- msginfo = procheader_parse_stream(fp, flags, full);
- fclose(fp);
-
- if (msginfo) {
- msginfo->size = s.st_size;
- msginfo->mtime = s.st_mtime;
- }
-
- return msginfo;
-}
-
-MsgInfo *procheader_parse_str(const gchar *str, MsgFlags flags, gboolean full)
-{
- FILE *fp;
- MsgInfo *msginfo;
-
- if ((fp = str_open_as_stream(str)) == NULL)
- return NULL;
-
- msginfo = procheader_parse_stream(fp, flags, full);
- fclose(fp);
- return msginfo;
-}
-
-enum
-{
- H_DATE = 0,
- H_FROM = 1,
- H_TO = 2,
- H_NEWSGROUPS = 3,
- H_SUBJECT = 4,
- H_MSG_ID = 5,
- H_REFERENCES = 6,
- H_IN_REPLY_TO = 7,
- H_CONTENT_TYPE = 8,
- H_SEEN = 9,
- H_CC = 10,
- H_X_FACE = 11
-};
-
-MsgInfo *procheader_parse_stream(FILE *fp, MsgFlags flags, gboolean full)
-{
- static HeaderEntry hentry_full[] = {{"Date:", NULL, FALSE},
- {"From:", NULL, TRUE},
- {"To:", NULL, TRUE},
- {"Newsgroups:", NULL, TRUE},
- {"Subject:", NULL, TRUE},
- {"Message-Id:", NULL, FALSE},
- {"References:", NULL, FALSE},
- {"In-Reply-To:", NULL, FALSE},
- {"Content-Type:", NULL, FALSE},
- {"Seen:", NULL, FALSE},
- {"Cc:", NULL, TRUE},
- {"X-Face:", NULL, FALSE},
- {NULL, NULL, FALSE}};
-
- static HeaderEntry hentry_short[] = {{"Date:", NULL, FALSE},
- {"From:", NULL, TRUE},
- {"To:", NULL, TRUE},
- {"Newsgroups:", NULL, TRUE},
- {"Subject:", NULL, TRUE},
- {"Message-Id:", NULL, FALSE},
- {"References:", NULL, FALSE},
- {"In-Reply-To:", NULL, FALSE},
- {"Content-Type:", NULL, FALSE},
- {"Seen:", NULL, FALSE},
- {NULL, NULL, FALSE}};
-
- MsgInfo *msginfo;
- gchar buf[BUFFSIZE];
- gchar *p;
- gchar *hp;
- HeaderEntry *hentry;
- gint hnum;
- gchar *from = NULL, *to = NULL, *subject = NULL, *cc = NULL;
- gchar *charset = NULL;
-
- hentry = full ? hentry_full : hentry_short;
-
- if (MSG_IS_QUEUED(flags)) {
- while (fgets(buf, sizeof(buf), fp) != NULL)
- if (buf[0] == '\r' || buf[0] == '\n') break;
- }
-
- msginfo = g_new0(MsgInfo, 1);
- msginfo->flags = flags;
- msginfo->references = NULL;
- msginfo->inreplyto = NULL;
-
- while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
- != -1) {
- hp = buf + strlen(hentry[hnum].name);
- while (*hp == ' ' || *hp == '\t') hp++;
-
- switch (hnum) {
- case H_DATE:
- if (msginfo->date) break;
- msginfo->date_t =
- procheader_date_parse(NULL, hp, 0);
- msginfo->date = g_strdup(hp);
- break;
- case H_FROM:
- if (from) break;
- from = g_strdup(hp);
- break;
- case H_TO:
- if (to) {
- p = to;
- to = g_strconcat(p, ", ", hp, NULL);
- g_free(p);
- } else
- to = g_strdup(hp);
- break;
- case H_NEWSGROUPS:
- if (msginfo->newsgroups) {
- p = msginfo->newsgroups;
- msginfo->newsgroups =
- g_strconcat(p, ",", hp, NULL);
- g_free(p);
- } else
- msginfo->newsgroups = g_strdup(buf + 12);
- break;
- case H_SUBJECT:
- if (msginfo->subject) break;
- subject = g_strdup(hp);
- break;
- case H_MSG_ID:
- if (msginfo->msgid) break;
-
- extract_parenthesis(hp, '<', '>');
- remove_space(hp);
- msginfo->msgid = g_strdup(hp);
- break;
- case H_REFERENCES:
- msginfo->references =
- references_list_prepend(msginfo->references,
- hp);
- break;
- case H_IN_REPLY_TO:
- if (msginfo->inreplyto) break;
-
- eliminate_parenthesis(hp, '(', ')');
- if ((p = strrchr(hp, '<')) != NULL &&
- strchr(p + 1, '>') != NULL) {
- extract_parenthesis(p, '<', '>');
- remove_space(p);
- if (*p != '\0')
- msginfo->inreplyto = g_strdup(p);
- }
- break;
- case H_CONTENT_TYPE:
- if (!g_ascii_strncasecmp(hp, "multipart", 9)) {
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_MIME);
- } else if (!charset) {
- procmime_scan_content_type_str
- (hp, NULL, &charset, NULL, NULL);
- }
- break;
- case H_SEEN:
- /* mnews Seen header */
- MSG_UNSET_PERM_FLAGS(msginfo->flags, MSG_NEW|MSG_UNREAD);
- break;
- case H_CC:
- if (cc) {
- p = cc;
- cc = g_strconcat(p, ", ", hp, NULL);
- g_free(p);
- } else
- cc = g_strdup(hp);
- break;
- case H_X_FACE:
- if (msginfo->xface) break;
- msginfo->xface = g_strdup(hp);
- break;
- default:
- break;
- }
- }
-
- if (from) {
- msginfo->from = conv_unmime_header(from, charset);
- msginfo->fromname = procheader_get_fromname(msginfo->from);
- g_free(from);
- }
- if (to) {
- msginfo->to = conv_unmime_header(to, charset);
- g_free(to);
- }
- if (subject) {
- msginfo->subject = conv_unmime_header(subject, charset);
- g_free(subject);
- }
- if (cc) {
- msginfo->cc = conv_unmime_header(cc, charset);
- g_free(cc);
- }
-
- if (!msginfo->inreplyto && msginfo->references)
- msginfo->inreplyto =
- g_strdup((gchar *)msginfo->references->data);
-
- g_free(charset);
-
- return msginfo;
-}
-
-gchar *procheader_get_fromname(const gchar *str)
-{
- gchar *tmp, *name;
-
- Xstrdup_a(tmp, str, return NULL);
-
- if (*tmp == '\"') {
- extract_quote(tmp, '\"');
- g_strstrip(tmp);
- } else if (strchr(tmp, '<')) {
- eliminate_parenthesis(tmp, '<', '>');
- g_strstrip(tmp);
- if (*tmp == '\0') {
- strcpy(tmp, str);
- extract_parenthesis(tmp, '<', '>');
- g_strstrip(tmp);
- }
- } else if (strchr(tmp, '(')) {
- extract_parenthesis(tmp, '(', ')');
- g_strstrip(tmp);
- }
-
- if (*tmp == '\0')
- name = g_strdup(str);
- else
- name = g_strdup(tmp);
-
- return name;
-}
-
-static gint procheader_scan_date_string(const gchar *str,
- gchar *weekday, gint *day,
- gchar *month, gint *year,
- gint *hh, gint *mm, gint *ss,
- gchar *zone)
-{
- gint result;
-
- result = sscanf(str, "%10s %d %9s %d %2d:%2d:%2d %5s",
- weekday, day, month, year, hh, mm, ss, zone);
- if (result == 8) return 0;
-
- result = sscanf(str, "%3s,%d %9s %d %2d:%2d:%2d %5s",
- weekday, day, month, year, hh, mm, ss, zone);
- if (result == 8) return 0;
-
- result = sscanf(str, "%d %9s %d %2d:%2d:%2d %5s",
- day, month, year, hh, mm, ss, zone);
- if (result == 7) return 0;
-
- *zone = '\0';
- result = sscanf(str, "%10s %d %9s %d %2d:%2d:%2d",
- weekday, day, month, year, hh, mm, ss);
- if (result == 7) return 0;
-
- result = sscanf(str, "%d %9s %d %2d:%2d:%2d",
- day, month, year, hh, mm, ss);
- if (result == 6) return 0;
-
- *ss = 0;
- result = sscanf(str, "%10s %d %9s %d %2d:%2d %5s",
- weekday, day, month, year, hh, mm, zone);
- if (result == 7) return 0;
-
- result = sscanf(str, "%d %9s %d %2d:%2d %5s",
- day, month, year, hh, mm, zone);
- if (result == 6) return 0;
-
- *zone = '\0';
- result = sscanf(str, "%10s %d %9s %d %2d:%2d",
- weekday, day, month, year, hh, mm);
- if (result == 6) return 0;
-
- result = sscanf(str, "%d %9s %d %2d:%2d",
- day, month, year, hh, mm);
- if (result == 5) return 0;
-
- return -1;
-}
-
-time_t procheader_date_parse(gchar *dest, const gchar *src, gint len)
-{
- static gchar monthstr[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
- gchar weekday[11];
- gint day;
- gchar month[10];
- gint year;
- gint hh, mm, ss;
- gchar zone[6];
- GDateMonth dmonth = G_DATE_BAD_MONTH;
- struct tm t;
- gchar *p;
- time_t timer;
- time_t tz_offset;
-
- if (procheader_scan_date_string(src, weekday, &day, month, &year,
- &hh, &mm, &ss, zone) < 0) {
- if (dest && len > 0)
- strncpy2(dest, src, len);
- return 0;
- }
-
- /* Y2K compliant :) */
- if (year < 1000) {
- if (year < 50)
- year += 2000;
- else
- year += 1900;
- }
-
- month[3] = '\0';
- for (p = monthstr; *p != '\0'; p += 3) {
- if (!g_ascii_strncasecmp(p, month, 3)) {
- dmonth = (gint)(p - monthstr) / 3 + 1;
- break;
- }
- }
-
- t.tm_sec = ss;
- t.tm_min = mm;
- t.tm_hour = hh;
- t.tm_mday = day;
- t.tm_mon = dmonth - 1;
- t.tm_year = year - 1900;
- t.tm_wday = 0;
- t.tm_yday = 0;
- t.tm_isdst = -1;
-
- timer = mktime(&t);
- tz_offset = remote_tzoffset_sec(zone);
- if (tz_offset != -1)
- timer += tzoffset_sec(&timer) - tz_offset;
-
- if (dest)
- procheader_date_get_localtime(dest, len, timer);
-
- return timer;
-}
-
-void procheader_date_get_localtime(gchar *dest, gint len, const time_t timer)
-{
- struct tm *lt;
- gchar *default_format = "%y/%m/%d(%a) %H:%M";
- gchar *tmp, *buf;
-
- Xalloca(tmp, len + 1, dest[0] = '\0'; return;);
-
- lt = localtime(&timer);
-
- if (prefs_common.date_format)
- strftime(tmp, len, prefs_common.date_format, lt);
- else
- strftime(tmp, len, default_format, lt);
-
- buf = conv_localetodisp(tmp, NULL);
- strncpy2(dest, buf, len);
- g_free(buf);
-}
diff --git a/src/procheader.h b/src/procheader.h
deleted file mode 100644
index 1667b4ed..00000000
--- a/src/procheader.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PROCHEADER_H__
-#define __PROCHEADER_H__
-
-#include <glib.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "procmsg.h"
-
-typedef struct _HeaderEntry HeaderEntry;
-typedef struct _Header Header;
-
-struct _HeaderEntry
-{
- gchar *name;
- gchar *body;
- gboolean unfold;
-};
-
-struct _Header
-{
- gchar *name;
- gchar *body;
-};
-
-gint procheader_get_one_field (gchar *buf,
- size_t len,
- FILE *fp,
- HeaderEntry hentry[]);
-gchar *procheader_get_unfolded_line (gchar *buf,
- size_t len,
- FILE *fp);
-
-GSList *procheader_get_header_list_from_file (const gchar *file);
-GSList *procheader_get_header_list (FILE *fp);
-GSList *procheader_add_header_list (GSList *hlist,
- const gchar *header_name,
- const gchar *body);
-GSList *procheader_merge_header_list (GSList *hlist1,
- GSList *hlist2);
-gint procheader_find_header_list (GSList *hlist,
- const gchar *header_name);
-void procheader_header_list_destroy (GSList *hlist);
-
-GPtrArray *procheader_get_header_array (FILE *fp,
- const gchar *encoding);
-GPtrArray *procheader_get_header_array_asis (FILE *fp,
- const gchar *encoding);
-void procheader_header_array_destroy (GPtrArray *harray);
-
-void procheader_header_free (Header *header);
-
-void procheader_get_header_fields (FILE *fp,
- HeaderEntry hentry[]);
-MsgInfo *procheader_parse_file (const gchar *file,
- MsgFlags flags,
- gboolean full);
-MsgInfo *procheader_parse_str (const gchar *str,
- MsgFlags flags,
- gboolean full);
-MsgInfo *procheader_parse_stream (FILE *fp,
- MsgFlags flags,
- gboolean full);
-
-gchar *procheader_get_fromname (const gchar *str);
-
-time_t procheader_date_parse (gchar *dest,
- const gchar *src,
- gint len);
-void procheader_date_get_localtime (gchar *dest,
- gint len,
- const time_t timer);
-
-#endif /* __PROCHEADER_H__ */
diff --git a/src/procmime.c b/src/procmime.c
deleted file mode 100644
index 1787aa2c..00000000
--- a/src/procmime.c
+++ /dev/null
@@ -1,1170 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-#include <locale.h>
-#include <ctype.h>
-
-#include "procmime.h"
-#include "procheader.h"
-#include "base64.h"
-#include "quoted-printable.h"
-#include "uuencode.h"
-#include "html.h"
-#include "codeconv.h"
-#include "utils.h"
-#include "prefs_common.h"
-
-#if USE_GPGME
-# include "rfc2015.h"
-#endif
-
-static GHashTable *procmime_get_mime_type_table (void);
-static GList *procmime_get_mime_type_list (const gchar *file);
-
-
-MimeInfo *procmime_mimeinfo_new(void)
-{
- MimeInfo *mimeinfo;
-
- mimeinfo = g_new0(MimeInfo, 1);
- mimeinfo->mime_type = MIME_UNKNOWN;
- mimeinfo->encoding_type = ENC_UNKNOWN;
-
- return mimeinfo;
-}
-
-void procmime_mimeinfo_free_all(MimeInfo *mimeinfo)
-{
- while (mimeinfo != NULL) {
- MimeInfo *next;
-
- 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_all(mimeinfo->sub);
- procmime_mimeinfo_free_all(mimeinfo->children);
-#if USE_GPGME
- procmime_mimeinfo_free_all(mimeinfo->plaintext);
-#endif
-
- next = mimeinfo->next;
- g_free(mimeinfo);
- mimeinfo = next;
- }
-}
-
-MimeInfo *procmime_mimeinfo_insert(MimeInfo *parent, MimeInfo *mimeinfo)
-{
- MimeInfo *child = parent->children;
-
- if (!child)
- parent->children = mimeinfo;
- else {
- while (child->next != NULL)
- child = child->next;
-
- child->next = mimeinfo;
- }
-
- mimeinfo->parent = parent;
- mimeinfo->level = parent->level + 1;
-
- return mimeinfo;
-}
-
-void procmime_mimeinfo_replace(MimeInfo *old, MimeInfo *new)
-{
- MimeInfo *parent = old->parent;
- MimeInfo *child;
-
- g_return_if_fail(parent != NULL);
- g_return_if_fail(new->next == NULL);
-
- for (child = parent->children; child && child != old;
- child = child->next)
- ;
- if (!child) {
- g_warning("oops: parent can't find it's own child");
- return;
- }
- procmime_mimeinfo_free_all(old);
-
- if (child == parent->children) {
- new->next = parent->children->next;
- parent->children = new;
- } else {
- new->next = child->next;
- child = new;
- }
-}
-
-MimeInfo *procmime_mimeinfo_next(MimeInfo *mimeinfo)
-{
- if (!mimeinfo) return NULL;
-
- if (mimeinfo->children)
- return mimeinfo->children;
- if (mimeinfo->sub)
- return mimeinfo->sub;
- 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)
- return mimeinfo->next;
- if (mimeinfo->main) {
- mimeinfo = mimeinfo->main;
- if (mimeinfo->next)
- return mimeinfo->next;
- }
- }
-
- return NULL;
-}
-
-#if 0
-void procmime_dump_mimeinfo(MimeInfo *mimeinfo)
-{
- gint i;
-
- g_print("\n");
-
- for (; mimeinfo != NULL; mimeinfo = procmime_mimeinfo_next(mimeinfo)) {
- for (i = 0; i < mimeinfo->level; i++)
- g_print(" ");
- g_print("%s%s\n", mimeinfo->main ? "sub: " : "",
- mimeinfo->content_type);
- }
-}
-#endif
-
-MimeInfo *procmime_scan_message(MsgInfo *msginfo)
-{
- FILE *fp;
- MimeInfo *mimeinfo;
-
- g_return_val_if_fail(msginfo != NULL, NULL);
-
-#if USE_GPGME
- if ((fp = procmsg_open_message_decrypted(msginfo, &mimeinfo)) == NULL)
- return NULL;
-#else
- if ((fp = procmsg_open_message(msginfo)) == NULL) return NULL;
- mimeinfo = procmime_scan_mime_header(fp);
-#endif
-
- if (mimeinfo) {
- mimeinfo->size = msginfo->size;
- mimeinfo->content_size = get_left_file_size(fp);
- if (mimeinfo->encoding_type == ENC_BASE64)
- mimeinfo->content_size = mimeinfo->content_size / 4 * 3;
- if (mimeinfo->mime_type == MIME_MULTIPART ||
- mimeinfo->mime_type == MIME_MESSAGE_RFC822)
- procmime_scan_multipart_message(mimeinfo, fp);
- }
-
- fclose(fp);
-
- return mimeinfo;
-}
-
-void procmime_scan_multipart_message(MimeInfo *mimeinfo, FILE *fp)
-{
- gchar *p;
- gchar *boundary;
- gint boundary_len = 0;
- gchar buf[BUFFSIZE];
- glong fpos, prev_fpos;
-
- g_return_if_fail(mimeinfo != NULL);
- g_return_if_fail(mimeinfo->mime_type == MIME_MULTIPART ||
- mimeinfo->mime_type == MIME_MESSAGE_RFC822);
-
- if (mimeinfo->mime_type == MIME_MULTIPART) {
- g_return_if_fail(mimeinfo->boundary != NULL);
- g_return_if_fail(mimeinfo->sub == NULL);
- }
- g_return_if_fail(fp != NULL);
-
- boundary = mimeinfo->boundary;
-
- if (boundary) {
- boundary_len = strlen(boundary);
-
- /* look for first boundary */
- while ((p = fgets(buf, sizeof(buf), fp)) != NULL)
- if (IS_BOUNDARY(buf, boundary, boundary_len)) break;
- if (!p) return;
- } else if (mimeinfo->parent && mimeinfo->parent->boundary) {
- boundary = mimeinfo->parent->boundary;
- boundary_len = strlen(boundary);
- }
-
- if ((fpos = ftell(fp)) < 0) {
- perror("ftell");
- return;
- }
-
- for (;;) {
- MimeInfo *partinfo;
- gboolean eom = FALSE;
- glong content_pos;
- gboolean is_base64;
- gint len;
- guint b64_content_len = 0;
- gint b64_pad_len = 0;
-
- prev_fpos = fpos;
- debug_print("prev_fpos: %ld\n", fpos);
-
- /* scan part header */
- if (mimeinfo->mime_type == MIME_MESSAGE_RFC822) {
- MimeInfo *sub;
-
- mimeinfo->sub = sub = procmime_scan_mime_header(fp);
- if (!sub) break;
-
- debug_print("message/rfc822 part found\n");
- sub->level = mimeinfo->level + 1;
- sub->parent = mimeinfo->parent;
- sub->main = mimeinfo;
-
- partinfo = sub;
- } else {
- partinfo = procmime_scan_mime_header(fp);
- if (!partinfo) break;
- procmime_mimeinfo_insert(mimeinfo, partinfo);
- debug_print("content-type: %s\n",
- partinfo->content_type);
- }
-
- /* begin content */
- content_pos = ftell(fp);
- debug_print("content_pos: %ld\n", content_pos);
-
- if (partinfo->mime_type == MIME_MULTIPART ||
- partinfo->mime_type == MIME_MESSAGE_RFC822) {
- if (partinfo->level < 8)
- procmime_scan_multipart_message(partinfo, fp);
- }
-
- /* look for next boundary */
- buf[0] = '\0';
- is_base64 = partinfo->encoding_type == ENC_BASE64;
- while ((p = fgets(buf, sizeof(buf), fp)) != NULL) {
- if (IS_BOUNDARY(buf, boundary, boundary_len)) {
- if (buf[2 + boundary_len] == '-' &&
- buf[2 + boundary_len + 1] == '-')
- eom = TRUE;
- break;
- } else if (is_base64) {
- const gchar *s;
- for (s = buf; *s && *s != '\r' && *s != '\n';
- ++s)
- if (*s == '=')
- ++b64_pad_len;
- b64_content_len += s - buf;
- }
- }
- if (p == NULL) {
- /* broken MIME, or single part MIME message */
- buf[0] = '\0';
- eom = TRUE;
- }
- debug_print("boundary: %s\n", buf);
-
- fpos = ftell(fp);
- debug_print("fpos: %ld\n", fpos);
-
- len = strlen(buf);
- partinfo->size = fpos - prev_fpos - len;
- if (is_base64)
- partinfo->content_size =
- b64_content_len / 4 * 3 - b64_pad_len;
- else
- partinfo->content_size = fpos - content_pos - len;
- debug_print("partinfo->size: %d\n", partinfo->size);
- debug_print("partinfo->content_size: %d\n",
- partinfo->content_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);
- }
-
- if (mimeinfo->mime_type == MIME_MESSAGE_RFC822) {
- if (len > 0 && fseek(fp, fpos - len, SEEK_SET) < 0)
- perror("fseek");
- break;
- }
-
- if (eom) break;
- }
-}
-
-void procmime_scan_encoding(MimeInfo *mimeinfo, const gchar *encoding)
-{
- gchar *buf;
-
- Xstrdup_a(buf, encoding, return);
-
- g_free(mimeinfo->encoding);
-
- mimeinfo->encoding = g_strdup(g_strstrip(buf));
- if (!g_ascii_strcasecmp(buf, "7bit"))
- mimeinfo->encoding_type = ENC_7BIT;
- else if (!g_ascii_strcasecmp(buf, "8bit"))
- mimeinfo->encoding_type = ENC_8BIT;
- else if (!g_ascii_strcasecmp(buf, "quoted-printable"))
- mimeinfo->encoding_type = ENC_QUOTED_PRINTABLE;
- else if (!g_ascii_strcasecmp(buf, "base64"))
- mimeinfo->encoding_type = ENC_BASE64;
- else if (!g_ascii_strcasecmp(buf, "x-uuencode"))
- mimeinfo->encoding_type = ENC_X_UUENCODE;
- else
- mimeinfo->encoding_type = ENC_UNKNOWN;
-
-}
-
-void procmime_scan_content_type(MimeInfo *mimeinfo, const gchar *content_type)
-{
- g_free(mimeinfo->content_type);
- g_free(mimeinfo->charset);
- g_free(mimeinfo->name);
- g_free(mimeinfo->boundary);
- mimeinfo->content_type = NULL;
- mimeinfo->charset = NULL;
- mimeinfo->name = NULL;
- mimeinfo->boundary = NULL;
-
- procmime_scan_content_type_str(content_type, &mimeinfo->content_type,
- &mimeinfo->charset, &mimeinfo->name,
- &mimeinfo->boundary);
-
- mimeinfo->mime_type = procmime_scan_mime_type(mimeinfo->content_type);
- if (mimeinfo->mime_type == MIME_MULTIPART && !mimeinfo->boundary)
- mimeinfo->mime_type = MIME_TEXT;
-}
-
-void procmime_scan_content_type_str(const gchar *content_type,
- gchar **mime_type, gchar **charset,
- gchar **name, gchar **boundary)
-{
- gchar *delim, *p;
- gchar *buf;
-
- Xstrdup_a(buf, content_type, return);
-
- if ((delim = strchr(buf, ';'))) *delim = '\0';
- if (mime_type)
- *mime_type = g_strdup(g_strstrip(buf));
-
- if (!delim) return;
- p = delim + 1;
-
- for (;;) {
- gchar *eq;
- gchar *attr, *value;
-
- if ((delim = strchr(p, ';'))) *delim = '\0';
-
- if (!(eq = strchr(p, '='))) break;
-
- *eq = '\0';
- attr = p;
- g_strstrip(attr);
- value = eq + 1;
- g_strstrip(value);
-
- if (*value == '"')
- extract_quote(value, '"');
- else {
- eliminate_parenthesis(value, '(', ')');
- g_strstrip(value);
- }
-
- if (*value) {
- if (charset && !g_ascii_strcasecmp(attr, "charset"))
- *charset = g_strdup(value);
- else if (name && !g_ascii_strcasecmp(attr, "name"))
- *name = conv_unmime_header(value, NULL);
- else if (boundary &&
- !g_ascii_strcasecmp(attr, "boundary"))
- *boundary = g_strdup(value);
- }
-
- if (!delim) break;
- p = delim + 1;
- }
-}
-
-void procmime_scan_content_disposition(MimeInfo *mimeinfo,
- const gchar *content_disposition)
-{
- gchar *delim, *p, *dispos;
- gchar *buf;
-
- Xstrdup_a(buf, content_disposition, return);
-
- if ((delim = strchr(buf, ';'))) *delim = '\0';
- mimeinfo->content_disposition = dispos = g_strdup(g_strstrip(buf));
-
- if (!delim) return;
- p = delim + 1;
-
- for (;;) {
- gchar *eq;
- gchar *attr, *value;
-
- if ((delim = strchr(p, ';'))) *delim = '\0';
-
- if (!(eq = strchr(p, '='))) break;
-
- *eq = '\0';
- attr = p;
- g_strstrip(attr);
- value = eq + 1;
- g_strstrip(value);
-
- if (*value == '"')
- extract_quote(value, '"');
- else {
- eliminate_parenthesis(value, '(', ')');
- g_strstrip(value);
- }
-
- if (*value) {
- if (!g_ascii_strcasecmp(attr, "filename")) {
- g_free(mimeinfo->filename);
- mimeinfo->filename =
- conv_unmime_header(value, NULL);
- break;
- }
- }
-
- if (!delim) break;
- p = delim + 1;
- }
-}
-
-enum
-{
- H_CONTENT_TRANSFER_ENCODING = 0,
- H_CONTENT_TYPE = 1,
- H_CONTENT_DISPOSITION = 2
-};
-
-MimeInfo *procmime_scan_mime_header(FILE *fp)
-{
- static HeaderEntry hentry[] = {{"Content-Transfer-Encoding:",
- NULL, FALSE},
- {"Content-Type:", NULL, TRUE},
- {"Content-Disposition:",
- NULL, TRUE},
- {NULL, NULL, FALSE}};
- gchar buf[BUFFSIZE];
- gint hnum;
- HeaderEntry *hp;
- MimeInfo *mimeinfo;
-
- g_return_val_if_fail(fp != NULL, NULL);
-
- mimeinfo = procmime_mimeinfo_new();
- mimeinfo->mime_type = MIME_TEXT;
- mimeinfo->encoding_type = ENC_7BIT;
- mimeinfo->fpos = ftell(fp);
-
- while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, hentry))
- != -1) {
- hp = hentry + hnum;
-
- if (H_CONTENT_TRANSFER_ENCODING == hnum) {
- procmime_scan_encoding
- (mimeinfo, buf + strlen(hp->name));
- } else if (H_CONTENT_TYPE == hnum) {
- procmime_scan_content_type
- (mimeinfo, buf + strlen(hp->name));
- } else if (H_CONTENT_DISPOSITION == hnum) {
- procmime_scan_content_disposition
- (mimeinfo, buf + strlen(hp->name));
- }
- }
-
- if (mimeinfo->mime_type == MIME_APPLICATION_OCTET_STREAM &&
- mimeinfo->name) {
- const gchar *type;
- type = procmime_get_mime_type(mimeinfo->name);
- if (type)
- mimeinfo->mime_type = procmime_scan_mime_type(type);
- }
-
- if (!mimeinfo->content_type)
- mimeinfo->content_type = g_strdup("text/plain");
-
- return mimeinfo;
-}
-
-FILE *procmime_decode_content(FILE *outfp, FILE *infp, MimeInfo *mimeinfo)
-{
- gchar buf[BUFFSIZE];
- gchar *boundary = NULL;
- gint boundary_len = 0;
- gboolean tmp_file = FALSE;
-
- g_return_val_if_fail(infp != NULL, NULL);
- g_return_val_if_fail(mimeinfo != NULL, NULL);
-
- if (!outfp) {
- outfp = my_tmpfile();
- if (!outfp) {
- perror("tmpfile");
- return NULL;
- }
- tmp_file = TRUE;
- }
-
- if (mimeinfo->parent && mimeinfo->parent->boundary) {
- boundary = mimeinfo->parent->boundary;
- boundary_len = strlen(boundary);
- }
-
- if (mimeinfo->encoding_type == ENC_QUOTED_PRINTABLE) {
- while (fgets(buf, sizeof(buf), infp) != NULL &&
- (!boundary ||
- !IS_BOUNDARY(buf, boundary, boundary_len))) {
- gint len;
- len = qp_decode_line(buf);
- fwrite(buf, len, 1, outfp);
- }
- } else if (mimeinfo->encoding_type == ENC_BASE64) {
- gchar outbuf[BUFFSIZE];
- gint len;
- Base64Decoder *decoder;
- gboolean uncanonicalize = FALSE;
- FILE *tmpfp = outfp;
- ContentType content_type;
-
- content_type = procmime_scan_mime_type(mimeinfo->content_type);
- if (content_type == MIME_TEXT ||
- content_type == MIME_TEXT_HTML ||
- content_type == MIME_MESSAGE_RFC822) {
- uncanonicalize = TRUE;
- tmpfp = my_tmpfile();
- if (!tmpfp) {
- perror("tmpfile");
- if (tmp_file) fclose(outfp);
- return NULL;
- }
- }
-
- decoder = base64_decoder_new();
- while (fgets(buf, sizeof(buf), infp) != NULL &&
- (!boundary ||
- !IS_BOUNDARY(buf, boundary, boundary_len))) {
- len = base64_decoder_decode(decoder, buf, outbuf);
- if (len < 0) {
- g_warning("Bad BASE64 content\n");
- break;
- }
- fwrite(outbuf, sizeof(gchar), len, tmpfp);
- }
- base64_decoder_free(decoder);
-
- if (uncanonicalize) {
- rewind(tmpfp);
- while (fgets(buf, sizeof(buf), tmpfp) != NULL) {
- strcrchomp(buf);
- fputs(buf, outfp);
- }
- fclose(tmpfp);
- }
- } else if (mimeinfo->encoding_type == ENC_X_UUENCODE) {
- gchar outbuf[BUFFSIZE];
- gint len;
- gboolean flag = FALSE;
-
- while (fgets(buf, sizeof(buf), infp) != NULL &&
- (!boundary ||
- !IS_BOUNDARY(buf, boundary, boundary_len))) {
- if(!flag && strncmp(buf,"begin ", 6)) continue;
-
- if (flag) {
- len = fromuutobits(outbuf, buf);
- if (len <= 0) {
- if (len < 0)
- g_warning("Bad UUENCODE content(%d)\n", len);
- break;
- }
- fwrite(outbuf, sizeof(gchar), len, outfp);
- } else
- flag = TRUE;
- }
- } else {
- while (fgets(buf, sizeof(buf), infp) != NULL &&
- (!boundary ||
- !IS_BOUNDARY(buf, boundary, boundary_len))) {
- fputs(buf, outfp);
- }
- }
-
- if (tmp_file) rewind(outfp);
- return outfp;
-}
-
-gint procmime_get_part(const gchar *outfile, const gchar *infile,
- MimeInfo *mimeinfo)
-{
- FILE *infp;
- gint ret;
-
- g_return_val_if_fail(outfile != NULL, -1);
- g_return_val_if_fail(infile != NULL, -1);
- g_return_val_if_fail(mimeinfo != NULL, -1);
-
- if ((infp = g_fopen(infile, "rb")) == NULL) {
- FILE_OP_ERROR(infile, "fopen");
- return -1;
- }
- ret = procmime_get_part_fp(outfile, infp, mimeinfo);
- fclose(infp);
-
- return ret;
-}
-
-gint procmime_get_part_fp(const gchar *outfile, FILE *infp, MimeInfo *mimeinfo)
-{
- FILE *outfp;
- gchar buf[BUFFSIZE];
-
- g_return_val_if_fail(outfile != NULL, -1);
- g_return_val_if_fail(infp != NULL, -1);
- g_return_val_if_fail(mimeinfo != NULL, -1);
-
- if (fseek(infp, mimeinfo->fpos, SEEK_SET) < 0) {
- FILE_OP_ERROR("procmime_get_part_fp()", "fseek");
- return -1;
- }
- if ((outfp = g_fopen(outfile, "wb")) == NULL) {
- FILE_OP_ERROR(outfile, "fopen");
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), infp) != NULL)
- if (buf[0] == '\r' || buf[0] == '\n') break;
-
- procmime_decode_content(outfp, infp, mimeinfo);
-
- if (fclose(outfp) == EOF) {
- FILE_OP_ERROR(outfile, "fclose");
- g_unlink(outfile);
- return -1;
- }
-
- return 0;
-}
-
-FILE *procmime_get_text_content(MimeInfo *mimeinfo, FILE *infp,
- const gchar *encoding)
-{
- FILE *tmpfp, *outfp;
- const gchar *src_encoding;
- gboolean conv_fail = FALSE;
- gchar buf[BUFFSIZE];
-
- g_return_val_if_fail(mimeinfo != NULL, NULL);
- g_return_val_if_fail(infp != NULL, NULL);
- g_return_val_if_fail(mimeinfo->mime_type == MIME_TEXT ||
- mimeinfo->mime_type == MIME_TEXT_HTML, NULL);
-
- if (fseek(infp, mimeinfo->fpos, SEEK_SET) < 0) {
- perror("fseek");
- return NULL;
- }
-
- while (fgets(buf, sizeof(buf), infp) != NULL)
- if (buf[0] == '\r' || buf[0] == '\n') break;
-
- tmpfp = procmime_decode_content(NULL, infp, mimeinfo);
- if (!tmpfp)
- return NULL;
-
- if ((outfp = my_tmpfile()) == NULL) {
- perror("tmpfile");
- fclose(tmpfp);
- return NULL;
- }
-
- src_encoding = prefs_common.force_charset
- ? prefs_common.force_charset : mimeinfo->charset;
-
- if (mimeinfo->mime_type == MIME_TEXT) {
- while (fgets(buf, sizeof(buf), tmpfp) != NULL) {
- gchar *str;
-
- str = conv_codeset_strdup(buf, src_encoding, encoding);
- if (str) {
- fputs(str, outfp);
- g_free(str);
- } else {
- conv_fail = TRUE;
- fputs(buf, outfp);
- }
- }
- } else if (mimeinfo->mime_type == MIME_TEXT_HTML) {
- HTMLParser *parser;
- CodeConverter *conv;
- const gchar *str;
-
- conv = conv_code_converter_new(src_encoding, encoding);
- parser = html_parser_new(tmpfp, conv);
- while ((str = html_parse(parser)) != NULL) {
- fputs(str, outfp);
- }
- html_parser_destroy(parser);
- conv_code_converter_destroy(conv);
- }
-
- if (conv_fail)
- g_warning(_("procmime_get_text_content(): Code conversion failed.\n"));
-
- fclose(tmpfp);
- rewind(outfp);
-
- return outfp;
-}
-
-/* search the first text part of (multipart) MIME message,
- decode, convert it and output to outfp. */
-FILE *procmime_get_first_text_content(MsgInfo *msginfo, const gchar *encoding)
-{
- FILE *infp, *outfp = NULL;
- MimeInfo *mimeinfo, *partinfo;
-
- g_return_val_if_fail(msginfo != NULL, NULL);
-
- mimeinfo = procmime_scan_message(msginfo);
- if (!mimeinfo) return NULL;
-
- if ((infp = procmsg_open_message(msginfo)) == NULL) {
- procmime_mimeinfo_free_all(mimeinfo);
- return NULL;
- }
-
- partinfo = mimeinfo;
- while (partinfo && partinfo->mime_type != MIME_TEXT)
- partinfo = procmime_mimeinfo_next(partinfo);
- if (!partinfo) {
- partinfo = mimeinfo;
- while (partinfo && partinfo->mime_type != MIME_TEXT_HTML)
- partinfo = procmime_mimeinfo_next(partinfo);
- }
-
- if (partinfo)
- outfp = procmime_get_text_content(partinfo, infp, encoding);
-
- fclose(infp);
- procmime_mimeinfo_free_all(mimeinfo);
-
- return outfp;
-}
-
-gboolean procmime_find_string_part(MimeInfo *mimeinfo, const gchar *filename,
- const gchar *str, StrFindFunc find_func)
-{
-
- FILE *infp, *outfp;
- gchar buf[BUFFSIZE];
-
- g_return_val_if_fail(mimeinfo != NULL, FALSE);
- g_return_val_if_fail(mimeinfo->mime_type == MIME_TEXT ||
- mimeinfo->mime_type == MIME_TEXT_HTML, FALSE);
- g_return_val_if_fail(str != NULL, FALSE);
- g_return_val_if_fail(find_func != NULL, FALSE);
-
- if ((infp = g_fopen(filename, "rb")) == NULL) {
- FILE_OP_ERROR(filename, "fopen");
- return FALSE;
- }
-
- outfp = procmime_get_text_content(mimeinfo, infp, NULL);
- fclose(infp);
-
- if (!outfp)
- return FALSE;
-
- while (fgets(buf, sizeof(buf), outfp) != NULL) {
- strretchomp(buf);
- if (find_func(buf, str)) {
- fclose(outfp);
- return TRUE;
- }
- }
-
- fclose(outfp);
-
- return FALSE;
-}
-
-gboolean procmime_find_string(MsgInfo *msginfo, const gchar *str,
- StrFindFunc find_func)
-{
- MimeInfo *mimeinfo;
- MimeInfo *partinfo;
- gchar *filename;
- gboolean found = FALSE;
-
- g_return_val_if_fail(msginfo != NULL, FALSE);
- g_return_val_if_fail(str != NULL, FALSE);
- g_return_val_if_fail(find_func != NULL, FALSE);
-
- filename = procmsg_get_message_file(msginfo);
- if (!filename) return FALSE;
- mimeinfo = procmime_scan_message(msginfo);
-
- for (partinfo = mimeinfo; partinfo != NULL;
- partinfo = procmime_mimeinfo_next(partinfo)) {
- if (partinfo->mime_type == MIME_TEXT ||
- partinfo->mime_type == MIME_TEXT_HTML) {
- if (procmime_find_string_part
- (partinfo, filename, str, find_func) == TRUE) {
- found = TRUE;
- break;
- }
- }
- }
-
- procmime_mimeinfo_free_all(mimeinfo);
- g_free(filename);
-
- return found;
-}
-
-gchar *procmime_get_part_file_name(MimeInfo *mimeinfo)
-{
- gchar *base;
- const gchar *base_;
-
- base_ = mimeinfo->filename ? mimeinfo->filename
- : mimeinfo->name ? mimeinfo->name : "mimetmp";
- base_ = g_basename(base_);
- if (*base_ == '\0') base_ = "mimetmp";
- base = conv_filename_from_utf8(base_);
- subst_for_filename(base);
-
- return base;
-}
-
-gchar *procmime_get_tmp_file_name(MimeInfo *mimeinfo)
-{
- static guint32 id = 0;
- gchar *base;
- gchar *filename;
- gchar f_prefix[10];
-
- g_return_val_if_fail(mimeinfo != NULL, NULL);
-
- g_snprintf(f_prefix, sizeof(f_prefix), "%08x.", id++);
-
- if (MIME_TEXT_HTML == mimeinfo->mime_type)
- base = g_strdup("mimetmp.html");
- else
- base = procmime_get_part_file_name(mimeinfo);
-
- filename = g_strconcat(get_mime_tmp_dir(), G_DIR_SEPARATOR_S,
- f_prefix, base, NULL);
-
- g_free(base);
-
- return filename;
-}
-
-ContentType procmime_scan_mime_type(const gchar *mime_type)
-{
- ContentType type;
-
- if (!g_ascii_strncasecmp(mime_type, "text/html", 9))
- type = MIME_TEXT_HTML;
- else if (!g_ascii_strncasecmp(mime_type, "text/", 5))
- type = MIME_TEXT;
- else if (!g_ascii_strncasecmp(mime_type, "message/rfc822", 14))
- type = MIME_MESSAGE_RFC822;
- else if (!g_ascii_strncasecmp(mime_type, "message/", 8))
- type = MIME_TEXT;
- else if (!g_ascii_strncasecmp(mime_type, "application/octet-stream",
- 24))
- type = MIME_APPLICATION_OCTET_STREAM;
- else if (!g_ascii_strncasecmp(mime_type, "application/", 12))
- type = MIME_APPLICATION;
- else if (!g_ascii_strncasecmp(mime_type, "multipart/", 10))
- type = MIME_MULTIPART;
- else if (!g_ascii_strncasecmp(mime_type, "image/", 6))
- type = MIME_IMAGE;
- else if (!g_ascii_strncasecmp(mime_type, "audio/", 6))
- type = MIME_AUDIO;
- else if (!g_ascii_strcasecmp(mime_type, "text"))
- type = MIME_TEXT;
- else
- type = MIME_UNKNOWN;
-
- return type;
-}
-
-static GList *mime_type_list = NULL;
-
-gchar *procmime_get_mime_type(const gchar *filename)
-{
- static GHashTable *mime_type_table = NULL;
- MimeType *mime_type;
- const gchar *p;
- gchar *ext;
-
- if (!mime_type_table) {
- mime_type_table = procmime_get_mime_type_table();
- if (!mime_type_table) return NULL;
- }
-
- filename = g_basename(filename);
- p = strrchr(filename, '.');
- if (!p) return NULL;
-
- Xstrdup_a(ext, p + 1, return NULL);
- g_strdown(ext);
- mime_type = g_hash_table_lookup(mime_type_table, ext);
- if (mime_type) {
- gchar *str;
-
- str = g_strconcat(mime_type->type, "/", mime_type->sub_type,
- NULL);
- return str;
- }
-
- return NULL;
-}
-
-static GHashTable *procmime_get_mime_type_table(void)
-{
- GHashTable *table = NULL;
- GList *cur;
- MimeType *mime_type;
- gchar **exts;
-
- if (!mime_type_list) {
- GList *list;
- gchar *dir;
-
- mime_type_list =
- procmime_get_mime_type_list(SYSCONFDIR "/mime.types");
- if (!mime_type_list) {
- list = procmime_get_mime_type_list("/etc/mime.types");
- mime_type_list = g_list_concat(mime_type_list, list);
- }
- dir = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
- "mime.types", NULL);
- list = procmime_get_mime_type_list(dir);
- g_free(dir);
- mime_type_list = g_list_concat(mime_type_list, list);
-
- if (!mime_type_list) {
- g_warning("mime.types not found\n");
- return NULL;
- }
- }
-
- table = g_hash_table_new(g_str_hash, g_str_equal);
-
- for (cur = mime_type_list; cur != NULL; cur = cur->next) {
- gint i;
- gchar *key;
-
- mime_type = (MimeType *)cur->data;
-
- if (!mime_type->extension) continue;
-
- exts = g_strsplit(mime_type->extension, " ", 16);
- for (i = 0; exts[i] != NULL; i++) {
- /* make the key case insensitive */
- g_strdown(exts[i]);
- /* use previously dup'd key on overwriting */
- if (g_hash_table_lookup(table, exts[i]))
- key = exts[i];
- else
- key = g_strdup(exts[i]);
- g_hash_table_insert(table, key, mime_type);
- }
- g_strfreev(exts);
- }
-
- return table;
-}
-
-static GList *procmime_get_mime_type_list(const gchar *file)
-{
- GList *list = NULL;
- FILE *fp;
- gchar buf[BUFFSIZE];
- gchar *p;
- gchar *delim;
- MimeType *mime_type;
-
- if ((fp = g_fopen(file, "rb")) == NULL) return NULL;
-
- debug_print("Reading %s ...\n", file);
-
- while (fgets(buf, sizeof(buf), fp) != NULL) {
- p = strchr(buf, '#');
- if (p) *p = '\0';
- g_strstrip(buf);
-
- p = buf;
- while (*p && !g_ascii_isspace(*p)) p++;
- if (*p) {
- *p = '\0';
- p++;
- }
- delim = strchr(buf, '/');
- if (delim == NULL) continue;
- *delim = '\0';
-
- mime_type = g_new(MimeType, 1);
- mime_type->type = g_strdup(buf);
- mime_type->sub_type = g_strdup(delim + 1);
-
- while (*p && g_ascii_isspace(*p)) p++;
- if (*p)
- mime_type->extension = g_strdup(p);
- else
- mime_type->extension = NULL;
-
- list = g_list_append(list, mime_type);
- }
-
- fclose(fp);
-
- if (!list)
- g_warning("Can't read mime.types\n");
-
- return list;
-}
-
-EncodingType procmime_get_encoding_for_charset(const gchar *charset)
-{
- if (!charset)
- return ENC_8BIT;
- else if (!g_ascii_strncasecmp(charset, "ISO-2022-", 9) ||
- !g_ascii_strcasecmp(charset, "US-ASCII"))
- return ENC_7BIT;
- else if (!g_ascii_strcasecmp(charset, "ISO-8859-5") ||
- !g_ascii_strncasecmp(charset, "KOI8-", 5) ||
- !g_ascii_strcasecmp(charset, "Windows-1251"))
- return ENC_8BIT;
- else if (!g_ascii_strncasecmp(charset, "ISO-8859-", 9))
- return ENC_QUOTED_PRINTABLE;
- else
- return ENC_8BIT;
-}
-
-EncodingType procmime_get_encoding_for_text_file(const gchar *file)
-{
- FILE *fp;
- guchar buf[BUFFSIZE];
- size_t len;
- size_t octet_chars = 0;
- size_t total_len = 0;
- gfloat octet_percentage;
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return ENC_UNKNOWN;
- }
-
- while ((len = fread(buf, sizeof(guchar), sizeof(buf), fp)) > 0) {
- guchar *p;
- gint i;
-
- for (p = buf, i = 0; i < len; ++p, ++i) {
- if (*p & 0x80)
- ++octet_chars;
- }
- total_len += len;
- }
-
- fclose(fp);
-
- if (total_len > 0)
- octet_percentage = (gfloat)octet_chars / (gfloat)total_len;
- else
- octet_percentage = 0.0;
-
- debug_print("procmime_get_encoding_for_text_file(): "
- "8bit chars: %d / %d (%f%%)\n", octet_chars, total_len,
- 100.0 * octet_percentage);
-
- if (octet_percentage > 0.20) {
- debug_print("using BASE64\n");
- return ENC_BASE64;
- } else if (octet_chars > 0) {
- debug_print("using quoted-printable\n");
- return ENC_QUOTED_PRINTABLE;
- } else {
- debug_print("using 7bit\n");
- return ENC_7BIT;
- }
-}
-
-const gchar *procmime_get_encoding_str(EncodingType encoding)
-{
- static const gchar *encoding_str[] = {
- "7bit", "8bit", "quoted-printable", "base64", "x-uuencode",
- NULL
- };
-
- if (encoding >= ENC_7BIT && encoding <= ENC_UNKNOWN)
- return encoding_str[encoding];
- else
- return NULL;
-}
diff --git a/src/procmime.h b/src/procmime.h
deleted file mode 100644
index fc2085a9..00000000
--- a/src/procmime.h
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PROCMIME_H__
-#define __PROCMIME_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <stdio.h>
-
-typedef struct _MimeType MimeType;
-typedef struct _MimeInfo MimeInfo;
-
-#include "procmsg.h"
-#include "utils.h"
-
-typedef enum
-{
- ENC_7BIT,
- ENC_8BIT,
- ENC_QUOTED_PRINTABLE,
- ENC_BASE64,
- ENC_X_UUENCODE,
- ENC_UNKNOWN
-} EncodingType;
-
-typedef enum
-{
- MIME_TEXT,
- MIME_TEXT_HTML,
- MIME_MESSAGE_RFC822,
- MIME_APPLICATION,
- MIME_APPLICATION_OCTET_STREAM,
- MIME_MULTIPART,
- MIME_IMAGE,
- MIME_AUDIO,
- MIME_UNKNOWN
-} ContentType;
-
-struct _MimeType
-{
- gchar *type;
- gchar *sub_type;
-
- gchar *extension;
-};
-
-/*
- * An example of MimeInfo structure:
- *
- * multipart/mixed root <-+ parent
- * |
- * multipart/alternative children <-+ parent
- * |
- * text/plain children --+
- * |
- * text/html next <-+
- *
- * message/rfc822 next <-+ main
- * |
- * sub (capsulated message)
- *
- * image/jpeg next
- */
-
-struct _MimeInfo
-{
- gchar *encoding;
-
- EncodingType encoding_type;
- ContentType mime_type;
-
- gchar *content_type;
- gchar *charset;
- gchar *name;
- gchar *boundary;
-
- gchar *content_disposition;
- gchar *filename;
-
- glong fpos;
- guint size;
- guint content_size;
-
- MimeInfo *main;
- MimeInfo *sub;
-
- MimeInfo *next;
- MimeInfo *parent;
- MimeInfo *children;
-
-#if USE_GPGME
- MimeInfo *plaintext;
- gchar *plaintextfile;
- gchar *sigstatus;
- gchar *sigstatus_full;
-#endif
-
- gint level;
-};
-
-#define IS_BOUNDARY(s, bnd, len) \
- (bnd && s[0] == '-' && s[1] == '-' && !strncmp(s + 2, bnd, len))
-
-/* MimeInfo handling */
-
-MimeInfo *procmime_mimeinfo_new (void);
-void procmime_mimeinfo_free_all (MimeInfo *mimeinfo);
-
-MimeInfo *procmime_mimeinfo_insert (MimeInfo *parent,
- MimeInfo *mimeinfo);
-void procmime_mimeinfo_replace (MimeInfo *old,
- MimeInfo *new);
-
-MimeInfo *procmime_mimeinfo_next (MimeInfo *mimeinfo);
-
-MimeInfo *procmime_scan_message (MsgInfo *msginfo);
-void procmime_scan_multipart_message (MimeInfo *mimeinfo,
- FILE *fp);
-
-/* scan headers */
-
-void procmime_scan_encoding (MimeInfo *mimeinfo,
- const gchar *encoding);
-void procmime_scan_content_type (MimeInfo *mimeinfo,
- const gchar *content_type);
-void procmime_scan_content_type_str (const gchar *content_type,
- gchar **mime_type,
- gchar **charset,
- gchar **name,
- gchar **boundary);
-void procmime_scan_content_disposition (MimeInfo *mimeinfo,
- const gchar *content_disposition);
-MimeInfo *procmime_scan_mime_header (FILE *fp);
-
-FILE *procmime_decode_content (FILE *outfp,
- FILE *infp,
- MimeInfo *mimeinfo);
-gint procmime_get_part (const gchar *outfile,
- const gchar *infile,
- MimeInfo *mimeinfo);
-gint procmime_get_part_fp (const gchar *outfile,
- FILE *infp,
- MimeInfo *mimeinfo);
-FILE *procmime_get_text_content (MimeInfo *mimeinfo,
- FILE *infp,
- const gchar *encoding);
-FILE *procmime_get_first_text_content (MsgInfo *msginfo,
- const gchar *encoding);
-
-gboolean procmime_find_string_part (MimeInfo *mimeinfo,
- const gchar *filename,
- const gchar *str,
- StrFindFunc find_func);
-gboolean procmime_find_string (MsgInfo *msginfo,
- const gchar *str,
- StrFindFunc find_func);
-
-gchar *procmime_get_part_file_name (MimeInfo *mimeinfo);
-gchar *procmime_get_tmp_file_name (MimeInfo *mimeinfo);
-
-ContentType procmime_scan_mime_type (const gchar *mime_type);
-gchar *procmime_get_mime_type (const gchar *filename);
-
-EncodingType procmime_get_encoding_for_charset (const gchar *charset);
-EncodingType procmime_get_encoding_for_text_file(const gchar *file);
-const gchar *procmime_get_encoding_str (EncodingType encoding);
-
-#endif /* __PROCMIME_H__ */
diff --git a/src/procmsg.c b/src/procmsg.c
deleted file mode 100644
index 0ecae5b4..00000000
--- a/src/procmsg.c
+++ /dev/null
@@ -1,1446 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#include "defs.h"
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "utils.h"
-#include "procmsg.h"
-#include "procheader.h"
-#include "account.h"
-#include "procmime.h"
-#include "prefs_common.h"
-#include "folder.h"
-#include "codeconv.h"
-#if USE_GPGME
-# include "rfc2015.h"
-#endif
-
-static void mark_sum_func (gpointer key,
- gpointer value,
- gpointer data);
-
-static GHashTable *procmsg_read_mark_file (FolderItem *item);
-static void procmsg_write_mark_file (FolderItem *item,
- GHashTable *mark_table);
-
-static FILE *procmsg_open_data_file (const gchar *file,
- guint version,
- DataOpenMode mode,
- gchar *buf,
- size_t buf_size);
-static FILE *procmsg_open_cache_file_with_buffer(FolderItem *item,
- DataOpenMode mode,
- gchar *buf,
- size_t buf_size);
-
-static gint procmsg_cmp_by_mark (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_unread (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_mime (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_label (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_number (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_size (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_date (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_from (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_to (gconstpointer a,
- gconstpointer b);
-static gint procmsg_cmp_by_subject (gconstpointer a,
- gconstpointer b);
-
-
-GHashTable *procmsg_msg_hash_table_create(GSList *mlist)
-{
- GHashTable *msg_table;
-
- if (mlist == NULL) return NULL;
-
- msg_table = g_hash_table_new(NULL, g_direct_equal);
- procmsg_msg_hash_table_append(msg_table, mlist);
-
- return msg_table;
-}
-
-void procmsg_msg_hash_table_append(GHashTable *msg_table, GSList *mlist)
-{
- GSList *cur;
- MsgInfo *msginfo;
-
- if (msg_table == NULL || mlist == NULL) return;
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
-
- g_hash_table_insert(msg_table,
- GUINT_TO_POINTER(msginfo->msgnum),
- msginfo);
- }
-}
-
-GHashTable *procmsg_to_folder_hash_table_create(GSList *mlist)
-{
- GHashTable *msg_table;
- GSList *cur;
- MsgInfo *msginfo;
-
- if (mlist == NULL) return NULL;
-
- msg_table = g_hash_table_new(NULL, g_direct_equal);
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- g_hash_table_insert(msg_table, msginfo->to_folder, msginfo);
- }
-
- return msg_table;
-}
-
-static gint procmsg_read_cache_data_str(FILE *fp, gchar **str)
-{
- gchar buf[BUFFSIZE];
- gint ret = 0;
- guint32 len;
-
- if (fread(&len, sizeof(len), 1, fp) == 1) {
- if (len > G_MAXINT)
- ret = -1;
- else {
- gchar *tmp = NULL;
-
- while (len > 0) {
- size_t size = MIN(len, BUFFSIZE - 1);
-
- if (fread(buf, size, 1, fp) != 1) {
- ret = -1;
- if (tmp) g_free(tmp);
- *str = NULL;
- break;
- }
-
- buf[size] = '\0';
- if (tmp) {
- *str = g_strconcat(tmp, buf, NULL);
- g_free(tmp);
- tmp = *str;
- } else
- tmp = *str = g_strdup(buf);
-
- len -= size;
- }
- }
- } else
- ret = -1;
-
- if (ret < 0)
- g_warning("Cache data is corrupted\n");
-
- return ret;
-}
-
-#define READ_CACHE_DATA(data, fp) \
-{ \
- if (procmsg_read_cache_data_str(fp, &data) < 0) { \
- procmsg_msginfo_free(msginfo); \
- procmsg_msg_list_free(mlist); \
- mlist = NULL; \
- break; \
- } \
-}
-
-#define READ_CACHE_DATA_INT(n, fp) \
-{ \
- guint32 idata; \
- \
- if (fread(&idata, sizeof(idata), 1, fp) != 1) { \
- g_warning("Cache data is corrupted\n"); \
- procmsg_msginfo_free(msginfo); \
- procmsg_msg_list_free(mlist); \
- mlist = NULL; \
- break; \
- } else \
- n = idata; \
-}
-
-GSList *procmsg_read_cache(FolderItem *item, gboolean scan_file)
-{
- GSList *mlist = NULL;
- GSList *last = NULL;
- FILE *fp;
- MsgInfo *msginfo;
- MsgFlags default_flags;
- gchar file_buf[BUFFSIZE];
- guint32 num;
- guint refnum;
- FolderType type;
-
- g_return_val_if_fail(item != NULL, NULL);
- g_return_val_if_fail(item->folder != NULL, NULL);
- type = FOLDER_TYPE(item->folder);
-
- default_flags.perm_flags = MSG_NEW|MSG_UNREAD;
- default_flags.tmp_flags = 0;
- if (type == F_MH || type == F_IMAP) {
- if (item->stype == F_QUEUE) {
- MSG_SET_TMP_FLAGS(default_flags, MSG_QUEUED);
- } else if (item->stype == F_DRAFT) {
- MSG_SET_TMP_FLAGS(default_flags, MSG_DRAFT);
- }
- }
- if (type == F_IMAP) {
- MSG_SET_TMP_FLAGS(default_flags, MSG_IMAP);
- } else if (type == F_NEWS) {
- MSG_SET_TMP_FLAGS(default_flags, MSG_NEWS);
- }
-
- if (type == F_MH) {
- gchar *path;
-
- path = folder_item_get_path(item);
- if (change_dir(path) < 0) {
- g_free(path);
- return NULL;
- }
- g_free(path);
- }
-
- if ((fp = procmsg_open_cache_file_with_buffer
- (item, DATA_READ, file_buf, sizeof(file_buf))) == NULL) {
- item->cache_dirty = TRUE;
- return NULL;
- }
-
- debug_print("Reading summary cache...");
-
- while (fread(&num, sizeof(num), 1, fp) == 1) {
- msginfo = g_new0(MsgInfo, 1);
- msginfo->msgnum = num;
- READ_CACHE_DATA_INT(msginfo->size, fp);
- READ_CACHE_DATA_INT(msginfo->mtime, fp);
- READ_CACHE_DATA_INT(msginfo->date_t, fp);
- READ_CACHE_DATA_INT(msginfo->flags.tmp_flags, fp);
-
- READ_CACHE_DATA(msginfo->fromname, fp);
-
- READ_CACHE_DATA(msginfo->date, fp);
- READ_CACHE_DATA(msginfo->from, fp);
- READ_CACHE_DATA(msginfo->to, fp);
- READ_CACHE_DATA(msginfo->newsgroups, fp);
- READ_CACHE_DATA(msginfo->subject, fp);
- READ_CACHE_DATA(msginfo->msgid, fp);
- READ_CACHE_DATA(msginfo->inreplyto, fp);
-
- READ_CACHE_DATA_INT(refnum, fp);
- for (; refnum != 0; refnum--) {
- gchar *ref;
-
- READ_CACHE_DATA(ref, fp);
- msginfo->references =
- g_slist_prepend(msginfo->references, ref);
- }
- if (msginfo->references)
- msginfo->references =
- g_slist_reverse(msginfo->references);
-
- MSG_SET_PERM_FLAGS(msginfo->flags, default_flags.perm_flags);
- MSG_SET_TMP_FLAGS(msginfo->flags, default_flags.tmp_flags);
-
- /* if the message file doesn't exist or is changed,
- don't add the data */
- if ((type == F_MH && scan_file &&
- folder_item_is_msg_changed(item, msginfo)) || num == 0) {
- procmsg_msginfo_free(msginfo);
- item->cache_dirty = TRUE;
- } else {
- msginfo->folder = item;
-
- if (!mlist)
- last = mlist = g_slist_append(NULL, msginfo);
- else {
- last = g_slist_append(last, msginfo);
- last = last->next;
- }
- }
- }
-
- fclose(fp);
-
- debug_print("done.\n");
-
- return mlist;
-}
-
-#undef READ_CACHE_DATA
-#undef READ_CACHE_DATA_INT
-
-static void mark_unset_new_func(gpointer key, gpointer value, gpointer data)
-{
- MSG_UNSET_PERM_FLAGS(*((MsgFlags *)value), MSG_NEW);
-}
-
-void procmsg_set_flags(GSList *mlist, FolderItem *item)
-{
- GSList *cur;
- gint new = 0, unread = 0, total = 0;
- gint lastnum = 0;
- gint unflagged = 0;
- gboolean mark_queue_exist;
- MsgInfo *msginfo;
- GHashTable *mark_table;
- MsgFlags *flags;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(item->folder != NULL);
-
- debug_print("Marking the messages...\n");
-
- mark_queue_exist = (item->mark_queue != NULL);
- mark_table = procmsg_read_mark_file(item);
- if (!mark_table) {
- item->new = item->unread = item->total = g_slist_length(mlist);
- item->updated = TRUE;
- item->mark_dirty = TRUE;
- return;
- }
-
- /* unset new flags if new (unflagged) messages exist */
- if (!mark_queue_exist) {
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- flags = g_hash_table_lookup
- (mark_table, GUINT_TO_POINTER(msginfo->msgnum));
- if (!flags) {
- g_hash_table_foreach(mark_table,
- mark_unset_new_func, NULL);
- item->mark_dirty = TRUE;
- break;
- }
- }
- }
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
-
- if (lastnum < msginfo->msgnum)
- lastnum = msginfo->msgnum;
-
- flags = g_hash_table_lookup
- (mark_table, GUINT_TO_POINTER(msginfo->msgnum));
-
- if (flags != NULL) {
- /* add the permanent flags only */
- msginfo->flags.perm_flags = flags->perm_flags;
- if (MSG_IS_NEW(*flags))
- ++new;
- if (MSG_IS_UNREAD(*flags))
- ++unread;
- if (FOLDER_TYPE(item->folder) == F_IMAP) {
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_IMAP);
- } else if (FOLDER_TYPE(item->folder) == F_NEWS) {
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_NEWS);
- }
- } else {
- ++unflagged;
- ++new;
- ++unread;
- }
-
- ++total;
- }
-
- item->new = new;
- item->unread = unread;
- item->total = total;
- item->unmarked_num = unflagged;
- item->last_num = lastnum;
- item->updated = TRUE;
-
- if (unflagged > 0)
- item->mark_dirty = TRUE;
-
- debug_print("new: %d unread: %d unflagged: %d total: %d\n",
- new, unread, unflagged, total);
-
- hash_free_value_mem(mark_table);
- g_hash_table_destroy(mark_table);
-}
-
-static FolderSortType cmp_func_sort_type;
-
-GSList *procmsg_sort_msg_list(GSList *mlist, FolderSortKey sort_key,
- FolderSortType sort_type)
-{
- GCompareFunc cmp_func;
-
- switch (sort_key) {
- case SORT_BY_MARK:
- cmp_func = procmsg_cmp_by_mark; break;
- case SORT_BY_UNREAD:
- cmp_func = procmsg_cmp_by_unread; break;
- case SORT_BY_MIME:
- cmp_func = procmsg_cmp_by_mime; break;
- case SORT_BY_LABEL:
- cmp_func = procmsg_cmp_by_label; break;
- case SORT_BY_NUMBER:
- cmp_func = procmsg_cmp_by_number; break;
- case SORT_BY_SIZE:
- cmp_func = procmsg_cmp_by_size; break;
- case SORT_BY_DATE:
- cmp_func = procmsg_cmp_by_date; break;
- case SORT_BY_FROM:
- cmp_func = procmsg_cmp_by_from; break;
- case SORT_BY_SUBJECT:
- cmp_func = procmsg_cmp_by_subject; break;
- case SORT_BY_TO:
- cmp_func = procmsg_cmp_by_to; break;
- default:
- return mlist;
- }
-
- cmp_func_sort_type = sort_type;
-
- mlist = g_slist_sort(mlist, cmp_func);
-
- return mlist;
-}
-
-gint procmsg_get_last_num_in_msg_list(GSList *mlist)
-{
- GSList *cur;
- MsgInfo *msginfo;
- gint last = 0;
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- if (msginfo && msginfo->msgnum > last)
- last = msginfo->msgnum;
- }
-
- return last;
-}
-
-void procmsg_msg_list_free(GSList *mlist)
-{
- GSList *cur;
- MsgInfo *msginfo;
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- procmsg_msginfo_free(msginfo);
- }
- g_slist_free(mlist);
-}
-
-void procmsg_write_cache(MsgInfo *msginfo, FILE *fp)
-{
- MsgTmpFlags flags = msginfo->flags.tmp_flags & MSG_CACHED_FLAG_MASK;
- GSList *cur;
-
- WRITE_CACHE_DATA_INT(msginfo->msgnum, fp);
- WRITE_CACHE_DATA_INT(msginfo->size, fp);
- WRITE_CACHE_DATA_INT(msginfo->mtime, fp);
- WRITE_CACHE_DATA_INT(msginfo->date_t, fp);
- WRITE_CACHE_DATA_INT(flags, fp);
-
- WRITE_CACHE_DATA(msginfo->fromname, fp);
-
- WRITE_CACHE_DATA(msginfo->date, fp);
- WRITE_CACHE_DATA(msginfo->from, fp);
- WRITE_CACHE_DATA(msginfo->to, fp);
- WRITE_CACHE_DATA(msginfo->newsgroups, fp);
- WRITE_CACHE_DATA(msginfo->subject, fp);
- WRITE_CACHE_DATA(msginfo->msgid, fp);
- WRITE_CACHE_DATA(msginfo->inreplyto, fp);
-
- WRITE_CACHE_DATA_INT(g_slist_length(msginfo->references), fp);
- for (cur = msginfo->references; cur != NULL; cur = cur->next) {
- WRITE_CACHE_DATA((gchar *)cur->data, fp);
- }
-}
-
-void procmsg_write_flags(MsgInfo *msginfo, FILE *fp)
-{
- MsgPermFlags flags = msginfo->flags.perm_flags;
-
- WRITE_CACHE_DATA_INT(msginfo->msgnum, fp);
- WRITE_CACHE_DATA_INT(flags, fp);
-}
-
-void procmsg_flush_mark_queue(FolderItem *item, FILE *fp)
-{
- MsgInfo *flaginfo;
-
- g_return_if_fail(item != NULL);
- g_return_if_fail(fp != NULL);
-
- if (item->mark_queue)
- debug_print("flushing mark_queue...\n");
-
- while (item->mark_queue != NULL) {
- flaginfo = (MsgInfo *)item->mark_queue->data;
- procmsg_write_flags(flaginfo, fp);
- procmsg_msginfo_free(flaginfo);
- item->mark_queue = g_slist_remove(item->mark_queue, flaginfo);
- }
-}
-
-void procmsg_add_mark_queue(FolderItem *item, gint num, MsgFlags flags)
-{
- MsgInfo *queue_msginfo;
-
- queue_msginfo = g_new0(MsgInfo, 1);
- queue_msginfo->msgnum = num;
- queue_msginfo->flags = flags;
- item->mark_queue = g_slist_append
- (item->mark_queue, queue_msginfo);
- return;
-}
-
-void procmsg_add_flags(FolderItem *item, gint num, MsgFlags flags)
-{
- FILE *fp;
- MsgInfo msginfo;
-
- g_return_if_fail(item != NULL);
-
- if (item->opened) {
- procmsg_add_mark_queue(item, num, flags);
- return;
- }
-
- if ((fp = procmsg_open_mark_file(item, DATA_APPEND)) == NULL) {
- g_warning(_("can't open mark file\n"));
- return;
- }
-
- msginfo.msgnum = num;
- msginfo.flags = flags;
-
- procmsg_write_flags(&msginfo, fp);
- fclose(fp);
-}
-
-struct MarkSum {
- gint *new;
- gint *unread;
- gint *total;
- gint *min;
- gint *max;
- gint first;
-};
-
-static void mark_sum_func(gpointer key, gpointer value, gpointer data)
-{
- MsgFlags *flags = value;
- gint num = GPOINTER_TO_INT(key);
- struct MarkSum *marksum = data;
-
- if (marksum->first <= num) {
- if (MSG_IS_NEW(*flags)) (*marksum->new)++;
- if (MSG_IS_UNREAD(*flags)) (*marksum->unread)++;
- if (num > *marksum->max) *marksum->max = num;
- if (num < *marksum->min || *marksum->min == 0) *marksum->min = num;
- (*marksum->total)++;
- }
-
- g_free(flags);
-}
-
-void procmsg_get_mark_sum(FolderItem *item,
- gint *new, gint *unread, gint *total,
- gint *min, gint *max,
- gint first)
-{
- GHashTable *mark_table;
- struct MarkSum marksum;
-
- *new = *unread = *total = *min = *max = 0;
- marksum.new = new;
- marksum.unread = unread;
- marksum.total = total;
- marksum.min = min;
- marksum.max = max;
- marksum.first = first;
-
- mark_table = procmsg_read_mark_file(item);
-
- if (mark_table) {
- g_hash_table_foreach(mark_table, mark_sum_func, &marksum);
- g_hash_table_destroy(mark_table);
- }
-}
-
-static GHashTable *procmsg_read_mark_file(FolderItem *item)
-{
- FILE *fp;
- GHashTable *mark_table = NULL;
- guint32 idata;
- guint num;
- MsgFlags *flags;
- MsgPermFlags perm_flags;
- GSList *cur;
-
- if ((fp = procmsg_open_mark_file(item, DATA_READ)) == NULL)
- return NULL;
-
- mark_table = g_hash_table_new(NULL, g_direct_equal);
-
- while (fread(&idata, sizeof(idata), 1, fp) == 1) {
- num = idata;
- if (fread(&idata, sizeof(idata), 1, fp) != 1) break;
- perm_flags = idata;
-
- flags = g_hash_table_lookup(mark_table, GUINT_TO_POINTER(num));
- if (flags != NULL)
- g_free(flags);
-
- flags = g_new0(MsgFlags, 1);
- flags->perm_flags = perm_flags;
-
- g_hash_table_insert(mark_table, GUINT_TO_POINTER(num), flags);
- }
-
- fclose(fp);
-
- if (item->mark_queue) {
- g_hash_table_foreach(mark_table, mark_unset_new_func, NULL);
- item->mark_dirty = TRUE;
- }
-
- for (cur = item->mark_queue; cur != NULL; cur = cur->next) {
- MsgInfo *msginfo = (MsgInfo *)cur->data;
-
- flags = g_hash_table_lookup(mark_table,
- GUINT_TO_POINTER(msginfo->msgnum));
- if (flags != NULL)
- g_free(flags);
-
- flags = g_new0(MsgFlags, 1);
- flags->perm_flags = msginfo->flags.perm_flags;
-
- g_hash_table_insert(mark_table,
- GUINT_TO_POINTER(msginfo->msgnum), flags);
-
- }
-
- if (item->mark_queue && !item->opened) {
- procmsg_write_mark_file(item, mark_table);
- procmsg_msg_list_free(item->mark_queue);
- item->mark_queue = NULL;
- item->mark_dirty = FALSE;
- }
-
- return mark_table;
-}
-
-static void write_mark_func(gpointer key, gpointer value, gpointer data)
-{
- MsgInfo msginfo;
-
- msginfo.msgnum = GPOINTER_TO_UINT(key);
- msginfo.flags.perm_flags = ((MsgFlags *)value)->perm_flags;
- procmsg_write_flags(&msginfo, (FILE *)data);
-}
-
-static void procmsg_write_mark_file(FolderItem *item, GHashTable *mark_table)
-{
- FILE *fp;
-
- fp = procmsg_open_mark_file(item, DATA_WRITE);
- g_hash_table_foreach(mark_table, write_mark_func, fp);
- fclose(fp);
-}
-
-static FILE *procmsg_open_data_file(const gchar *file, guint version,
- DataOpenMode mode,
- gchar *buf, size_t buf_size)
-{
- FILE *fp;
- guint32 data_ver;
-
- g_return_val_if_fail(file != NULL, NULL);
-
- if (mode == DATA_WRITE) {
- if ((fp = g_fopen(file, "wb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- return NULL;
- }
- if (change_file_mode_rw(fp, file) < 0)
- FILE_OP_ERROR(file, "chmod");
-
- WRITE_CACHE_DATA_INT(version, fp);
- return fp;
- }
-
- /* check version */
- if ((fp = g_fopen(file, "rb")) == NULL)
- debug_print("Mark/Cache file '%s' not found\n", file);
- else {
- if (buf && buf_size > 0)
- setvbuf(fp, buf, _IOFBF, buf_size);
- if (fread(&data_ver, sizeof(data_ver), 1, fp) != 1 ||
- version != data_ver) {
- g_message("%s: Mark/Cache version is different (%u != %u). Discarding it.\n",
- file, data_ver, version);
- fclose(fp);
- fp = NULL;
- }
- }
-
- if (mode == DATA_READ)
- return fp;
-
- if (fp) {
- /* reopen with append mode */
- fclose(fp);
- if ((fp = g_fopen(file, "ab")) == NULL)
- FILE_OP_ERROR(file, "fopen");
- } else {
- /* open with overwrite mode if mark file doesn't exist or
- version is different */
- fp = procmsg_open_data_file(file, version, DATA_WRITE, buf,
- buf_size);
- }
-
- return fp;
-}
-
-static FILE *procmsg_open_cache_file_with_buffer(FolderItem *item,
- DataOpenMode mode,
- gchar *buf, size_t buf_size)
-{
- gchar *cachefile;
- FILE *fp;
-
- cachefile = folder_item_get_cache_file(item);
- fp = procmsg_open_data_file(cachefile, CACHE_VERSION, mode, buf,
- buf_size);
- g_free(cachefile);
-
- return fp;
-}
-
-FILE *procmsg_open_cache_file(FolderItem *item, DataOpenMode mode)
-{
- gchar *cachefile;
- FILE *fp;
-
- cachefile = folder_item_get_cache_file(item);
- fp = procmsg_open_data_file(cachefile, CACHE_VERSION, mode, NULL, 0);
- g_free(cachefile);
-
- return fp;
-}
-
-FILE *procmsg_open_mark_file(FolderItem *item, DataOpenMode mode)
-{
- gchar *markfile;
- FILE *fp;
-
- markfile = folder_item_get_mark_file(item);
- fp = procmsg_open_data_file(markfile, MARK_VERSION, mode, NULL, 0);
- g_free(markfile);
-
- return fp;
-}
-
-void procmsg_clear_cache(FolderItem *item)
-{
- FILE *fp;
-
- fp = procmsg_open_cache_file(item, DATA_WRITE);
- if (fp)
- fclose(fp);
-}
-
-void procmsg_clear_mark(FolderItem *item)
-{
- FILE *fp;
-
- fp = procmsg_open_mark_file(item, DATA_WRITE);
- if (fp)
- fclose(fp);
-}
-
-/* return the reversed thread tree */
-GNode *procmsg_get_thread_tree(GSList *mlist)
-{
- GNode *root, *parent, *node, *next;
- GHashTable *table;
- MsgInfo *msginfo;
- const gchar *msgid;
- GSList *reflist;
-
- root = g_node_new(NULL);
- table = g_hash_table_new(g_str_hash, g_str_equal);
-
- for (; mlist != NULL; mlist = mlist->next) {
- msginfo = (MsgInfo *)mlist->data;
- parent = root;
-
- /* only look for the real parent first */
- if (msginfo->inreplyto) {
- parent = g_hash_table_lookup(table, msginfo->inreplyto);
- if (parent == NULL)
- parent = root;
- }
-
- node = g_node_insert_data_before
- (parent, parent == root ? parent->children : NULL,
- msginfo);
- if ((msgid = msginfo->msgid) &&
- g_hash_table_lookup(table, msgid) == NULL)
- g_hash_table_insert(table, (gchar *)msgid, node);
- }
-
- /* complete the unfinished threads */
- for (node = root->children; node != NULL; ) {
- next = node->next;
- msginfo = (MsgInfo *)node->data;
- parent = NULL;
-
- if (msginfo->inreplyto)
- parent = g_hash_table_lookup(table, msginfo->inreplyto);
-
- /* try looking for the indirect parent */
- if (!parent && msginfo->references) {
- for (reflist = msginfo->references;
- reflist != NULL; reflist = reflist->next)
- if ((parent = g_hash_table_lookup
- (table, reflist->data)) != NULL)
- break;
- }
-
- /* node should not be the parent, and node should not
- be an ancestor of parent (circular reference) */
- if (parent && parent != node &&
- !g_node_is_ancestor(node, parent)) {
- g_node_unlink(node);
- g_node_insert_before
- (parent, parent->children, node);
- }
- node = next;
- }
-
- g_hash_table_destroy(table);
-
- return root;
-}
-
-gint procmsg_move_messages(GSList *mlist)
-{
- GSList *cur, *movelist = NULL;
- MsgInfo *msginfo;
- FolderItem *dest = NULL;
- GHashTable *hash;
- gint val = 0;
-
- if (!mlist) return 0;
-
- hash = procmsg_to_folder_hash_table_create(mlist);
- folder_item_scan_foreach(hash);
- g_hash_table_destroy(hash);
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- if (!dest) {
- dest = msginfo->to_folder;
- movelist = g_slist_append(movelist, msginfo);
- } else if (dest == msginfo->to_folder) {
- movelist = g_slist_append(movelist, msginfo);
- } else {
- val = folder_item_move_msgs(dest, movelist);
- g_slist_free(movelist);
- movelist = NULL;
- if (val == -1)
- return val;
- dest = msginfo->to_folder;
- movelist = g_slist_append(movelist, msginfo);
- }
- }
-
- if (movelist) {
- val = folder_item_move_msgs(dest, movelist);
- g_slist_free(movelist);
- }
-
- return val == -1 ? -1 : 0;
-}
-
-gint procmsg_copy_messages(GSList *mlist)
-{
- GSList *cur, *copylist = NULL;
- MsgInfo *msginfo;
- FolderItem *dest = NULL;
- GHashTable *hash;
- gint val = 0;
-
- if (!mlist) return 0;
-
- hash = procmsg_to_folder_hash_table_create(mlist);
- folder_item_scan_foreach(hash);
- g_hash_table_destroy(hash);
-
- for (cur = mlist; cur != NULL; cur = cur->next) {
- msginfo = (MsgInfo *)cur->data;
- if (!dest) {
- dest = msginfo->to_folder;
- copylist = g_slist_append(copylist, msginfo);
- } else if (dest == msginfo->to_folder) {
- copylist = g_slist_append(copylist, msginfo);
- } else {
- val = folder_item_copy_msgs(dest, copylist);
- g_slist_free(copylist);
- copylist = NULL;
- if (val == -1)
- return val;
- dest = msginfo->to_folder;
- copylist = g_slist_append(copylist, msginfo);
- }
- }
-
- if (copylist) {
- val = folder_item_copy_msgs(dest, copylist);
- g_slist_free(copylist);
- }
-
- return val == -1 ? -1 : 0;
-}
-
-gchar *procmsg_get_message_file_path(MsgInfo *msginfo)
-{
- gchar *path, *file;
-
- g_return_val_if_fail(msginfo != NULL, NULL);
-
- if (msginfo->plaintext_file)
- file = g_strdup(msginfo->plaintext_file);
- else if (msginfo->file_path)
- return g_strdup(msginfo->file_path);
- else {
- path = folder_item_get_path(msginfo->folder);
- file = g_strconcat(path, G_DIR_SEPARATOR_S,
- itos(msginfo->msgnum), NULL);
- g_free(path);
- }
-
- return file;
-}
-
-gchar *procmsg_get_message_file(MsgInfo *msginfo)
-{
- gchar *filename = NULL;
-
- g_return_val_if_fail(msginfo != NULL, NULL);
-
- if (msginfo->file_path)
- return g_strdup(msginfo->file_path);
-
- filename = folder_item_fetch_msg(msginfo->folder, msginfo->msgnum);
- if (!filename)
- debug_print(_("can't fetch message %d\n"), msginfo->msgnum);
-
- return filename;
-}
-
-GSList *procmsg_get_message_file_list(GSList *mlist)
-{
- GSList *file_list = NULL;
- MsgInfo *msginfo;
- MsgFileInfo *fileinfo;
- gchar *file;
-
- while (mlist != NULL) {
- msginfo = (MsgInfo *)mlist->data;
- file = procmsg_get_message_file(msginfo);
- if (!file) {
- procmsg_message_file_list_free(file_list);
- return NULL;
- }
- fileinfo = g_new(MsgFileInfo, 1);
- fileinfo->file = file;
- fileinfo->flags = g_new(MsgFlags, 1);
- *fileinfo->flags = msginfo->flags;
- file_list = g_slist_prepend(file_list, fileinfo);
- mlist = mlist->next;
- }
-
- file_list = g_slist_reverse(file_list);
-
- return file_list;
-}
-
-void procmsg_message_file_list_free(GSList *file_list)
-{
- GSList *cur;
- MsgFileInfo *fileinfo;
-
- for (cur = file_list; cur != NULL; cur = cur->next) {
- fileinfo = (MsgFileInfo *)cur->data;
- g_free(fileinfo->file);
- g_free(fileinfo->flags);
- g_free(fileinfo);
- }
-
- g_slist_free(file_list);
-}
-
-FILE *procmsg_open_message(MsgInfo *msginfo)
-{
- FILE *fp;
- gchar *file;
-
- g_return_val_if_fail(msginfo != NULL, NULL);
-
- file = procmsg_get_message_file_path(msginfo);
- g_return_val_if_fail(file != NULL, NULL);
-
- if (!is_file_exist(file)) {
- g_free(file);
- file = procmsg_get_message_file(msginfo);
- if (!file)
- return NULL;
- }
-
- if ((fp = g_fopen(file, "rb")) == NULL) {
- FILE_OP_ERROR(file, "fopen");
- g_free(file);
- return NULL;
- }
-
- g_free(file);
-
- if (MSG_IS_QUEUED(msginfo->flags)) {
- gchar buf[BUFFSIZE];
-
- while (fgets(buf, sizeof(buf), fp) != NULL)
- if (buf[0] == '\r' || buf[0] == '\n') break;
- }
-
- return fp;
-}
-
-#if USE_GPGME
-FILE *procmsg_open_message_decrypted(MsgInfo *msginfo, MimeInfo **mimeinfo)
-{
- FILE *fp;
- MimeInfo *mimeinfo_;
- glong fpos;
-
- g_return_val_if_fail(msginfo != NULL, NULL);
-
- if (mimeinfo) *mimeinfo = NULL;
-
- if ((fp = procmsg_open_message(msginfo)) == NULL) return NULL;
-
- mimeinfo_ = procmime_scan_mime_header(fp);
- if (!mimeinfo_) {
- fclose(fp);
- return NULL;
- }
-
- if (!MSG_IS_ENCRYPTED(msginfo->flags) &&
- rfc2015_is_encrypted(mimeinfo_)) {
- MSG_SET_TMP_FLAGS(msginfo->flags, MSG_ENCRYPTED);
- }
-
- if (MSG_IS_ENCRYPTED(msginfo->flags) &&
- !msginfo->plaintext_file &&
- !msginfo->decryption_failed) {
- fpos = ftell(fp);
- rfc2015_decrypt_message(msginfo, mimeinfo_, fp);
- if (msginfo->plaintext_file &&
- !msginfo->decryption_failed) {
- fclose(fp);
- procmime_mimeinfo_free_all(mimeinfo_);
- if ((fp = procmsg_open_message(msginfo)) == NULL)
- return NULL;
- mimeinfo_ = procmime_scan_mime_header(fp);
- if (!mimeinfo_) {
- fclose(fp);
- return NULL;
- }
- } else {
- if (fseek(fp, fpos, SEEK_SET) < 0)
- perror("fseek");
- }
- }
-
- if (mimeinfo) *mimeinfo = mimeinfo_;
- return fp;
-}
-#endif
-
-gboolean procmsg_msg_exist(MsgInfo *msginfo)
-{
- gchar *path;
- gboolean ret;
-
- if (!msginfo) return FALSE;
-
- path = folder_item_get_path(msginfo->folder);
- change_dir(path);
- ret = !folder_item_is_msg_changed(msginfo->folder, msginfo);
- g_free(path);
-
- return ret;
-}
-
-void procmsg_empty_trash(FolderItem *trash)
-{
- if (trash && trash->total > 0) {
- debug_print("Emptying messages in %s ...\n", trash->path);
-
- folder_item_remove_all_msg(trash);
- procmsg_clear_cache(trash);
- procmsg_clear_mark(trash);
- trash->cache_dirty = FALSE;
- trash->mark_dirty = FALSE;
- }
-}
-
-void procmsg_empty_all_trash(void)
-{
- FolderItem *trash;
- GList *cur;
-
- for (cur = folder_get_list(); cur != NULL; cur = cur->next) {
- trash = FOLDER(cur->data)->trash;
- procmsg_empty_trash(trash);
- }
-}
-
-gint procmsg_save_to_outbox(FolderItem *outbox, const gchar *file)
-{
- gint num;
- MsgFlags flag = {0, 0};
-
- debug_print("saving sent message...\n");
-
- if (!outbox)
- outbox = folder_get_default_outbox();
- g_return_val_if_fail(outbox != NULL, -1);
-
- folder_item_scan(outbox);
- if ((num = folder_item_add_msg(outbox, file, &flag, FALSE)) < 0) {
- g_warning("can't save message\n");
- return -1;
- }
-
- return 0;
-}
-
-void procmsg_print_message(MsgInfo *msginfo, const gchar *cmdline)
-{
- static const gchar *def_cmd = "lpr %s";
- static guint id = 0;
- gchar *prtmp;
- FILE *tmpfp, *prfp;
- gchar buf[1024];
- gchar *p;
-
- g_return_if_fail(msginfo);
-
- if ((tmpfp = procmime_get_first_text_content
- (msginfo, conv_get_locale_charset_str())) == NULL) {
- g_warning(_("Can't get text part\n"));
- return;
- }
-
- prtmp = g_strdup_printf("%s%cprinttmp.%08x",
- get_mime_tmp_dir(), G_DIR_SEPARATOR, id++);
-
- if ((prfp = g_fopen(prtmp, "wb")) == NULL) {
- FILE_OP_ERROR(prtmp, "fopen");
- g_free(prtmp);
- fclose(tmpfp);
- return;
- }
-
-#define OUTPUT_HEADER(s, fmt) \
- if (s) { \
- gchar *locale_str; \
- locale_str = conv_codeset_strdup \
- (s, CS_INTERNAL, conv_get_locale_charset_str()); \
- fprintf(prfp, fmt, locale_str ? locale_str : s); \
- g_free(locale_str); \
- }
-
- OUTPUT_HEADER(msginfo->date, "Date: %s\n");
- OUTPUT_HEADER(msginfo->from, "From: %s\n");
- OUTPUT_HEADER(msginfo->to, "To: %s\n");
- OUTPUT_HEADER(msginfo->newsgroups, "Newsgroups: %s\n");
- OUTPUT_HEADER(msginfo->subject, "Subject: %s\n");
- fputc('\n', prfp);
-
-#undef OUTPUT_HEADER
-
- while (fgets(buf, sizeof(buf), tmpfp) != NULL)
- fputs(buf, prfp);
-
- fclose(prfp);
- fclose(tmpfp);
-
- if (cmdline && (p = strchr(cmdline, '%')) && *(p + 1) == 's' &&
- !strchr(p + 2, '%'))
- g_snprintf(buf, sizeof(buf) - 1, cmdline, prtmp);
- else {
- if (cmdline)
- g_warning(_("Print command line is invalid: `%s'\n"),
- cmdline);
- g_snprintf(buf, sizeof(buf) - 1, def_cmd, prtmp);
- }
-
- g_free(prtmp);
-
- g_strchomp(buf);
- if (buf[strlen(buf) - 1] != '&') strcat(buf, "&");
- system(buf);
-}
-
-MsgInfo *procmsg_msginfo_copy(MsgInfo *msginfo)
-{
- MsgInfo *newmsginfo;
-
- if (msginfo == NULL) return NULL;
-
- newmsginfo = g_new0(MsgInfo, 1);
-
-#define MEMBCOPY(mmb) newmsginfo->mmb = msginfo->mmb
-#define MEMBDUP(mmb) newmsginfo->mmb = msginfo->mmb ? \
- g_strdup(msginfo->mmb) : NULL
-
- MEMBCOPY(msgnum);
- MEMBCOPY(size);
- MEMBCOPY(mtime);
- MEMBCOPY(date_t);
-
- MEMBCOPY(flags);
-
- MEMBDUP(fromname);
-
- MEMBDUP(date);
- MEMBDUP(from);
- MEMBDUP(to);
- MEMBDUP(cc);
- MEMBDUP(newsgroups);
- MEMBDUP(subject);
- MEMBDUP(msgid);
- MEMBDUP(inreplyto);
-
- MEMBCOPY(folder);
- MEMBCOPY(to_folder);
-
- MEMBDUP(xface);
-
- MEMBDUP(file_path);
-
- MEMBDUP(plaintext_file);
- MEMBCOPY(decryption_failed);
-
- return newmsginfo;
-}
-
-MsgInfo *procmsg_msginfo_get_full_info(MsgInfo *msginfo)
-{
- MsgInfo *full_msginfo;
- gchar *file;
-
- if (msginfo == NULL) return NULL;
-
- file = procmsg_get_message_file(msginfo);
- if (!file) {
- g_warning("procmsg_msginfo_get_full_info(): can't get message file.\n");
- return NULL;
- }
-
- full_msginfo = procheader_parse_file(file, msginfo->flags, TRUE);
- g_free(file);
- if (!full_msginfo) return NULL;
-
- full_msginfo->msgnum = msginfo->msgnum;
- full_msginfo->size = msginfo->size;
- full_msginfo->mtime = msginfo->mtime;
- full_msginfo->folder = msginfo->folder;
- full_msginfo->to_folder = msginfo->to_folder;
-
- full_msginfo->file_path = g_strdup(msginfo->file_path);
-
-#if USE_GPGME
- full_msginfo->plaintext_file = g_strdup(msginfo->plaintext_file);
- full_msginfo->decryption_failed = msginfo->decryption_failed;
-#endif
-
- return full_msginfo;
-}
-
-gboolean procmsg_msginfo_equal(MsgInfo *msginfo_a, MsgInfo *msginfo_b)
-{
- if (!msginfo_a || !msginfo_b)
- return FALSE;
-
- if (msginfo_a == msginfo_b)
- return TRUE;
-
- if (msginfo_a->folder == msginfo_b->folder &&
- msginfo_a->msgnum == msginfo_b->msgnum &&
- msginfo_a->size == msginfo_b->size &&
- msginfo_a->mtime == msginfo_b->mtime)
- return TRUE;
-
- return FALSE;
-}
-
-void procmsg_msginfo_free(MsgInfo *msginfo)
-{
- if (msginfo == NULL) return;
-
- g_free(msginfo->xface);
-
- g_free(msginfo->fromname);
-
- g_free(msginfo->date);
- g_free(msginfo->from);
- g_free(msginfo->to);
- g_free(msginfo->cc);
- g_free(msginfo->newsgroups);
- g_free(msginfo->subject);
- g_free(msginfo->msgid);
- g_free(msginfo->inreplyto);
-
- slist_free_strings(msginfo->references);
- g_slist_free(msginfo->references);
-
- g_free(msginfo->file_path);
-
- g_free(msginfo->plaintext_file);
-
- g_free(msginfo);
-}
-
-gint procmsg_cmp_msgnum_for_sort(gconstpointer a, gconstpointer b)
-{
- const MsgInfo *msginfo1 = a;
- const MsgInfo *msginfo2 = b;
-
- if (!msginfo1 || !msginfo2)
- return 0;
-
- return msginfo1->msgnum - msginfo2->msgnum;
-}
-
-#define CMP_FUNC_DEF(func_name, val) \
-static gint func_name(gconstpointer a, gconstpointer b) \
-{ \
- const MsgInfo *msginfo1 = a; \
- const MsgInfo *msginfo2 = b; \
- gint ret; \
- \
- if (!msginfo1 || !msginfo2) \
- return 0; \
- \
- ret = (val); \
- if (ret == 0) \
- ret = msginfo1->date_t - msginfo2->date_t; \
- \
- return ret * (cmp_func_sort_type == SORT_ASCENDING ? 1 : -1); \
-}
-
-CMP_FUNC_DEF(procmsg_cmp_by_mark,
- MSG_IS_MARKED(msginfo1->flags) - MSG_IS_MARKED(msginfo2->flags))
-CMP_FUNC_DEF(procmsg_cmp_by_unread,
- MSG_IS_UNREAD(msginfo1->flags) - MSG_IS_UNREAD(msginfo2->flags))
-CMP_FUNC_DEF(procmsg_cmp_by_mime,
- MSG_IS_MIME(msginfo1->flags) - MSG_IS_MIME(msginfo2->flags))
-CMP_FUNC_DEF(procmsg_cmp_by_label,
- MSG_GET_COLORLABEL(msginfo1->flags) -
- MSG_GET_COLORLABEL(msginfo2->flags))
-CMP_FUNC_DEF(procmsg_cmp_by_size, msginfo1->size - msginfo2->size)
-
-#undef CMP_FUNC_DEF
-#define CMP_FUNC_DEF(func_name, val) \
-static gint func_name(gconstpointer a, gconstpointer b) \
-{ \
- const MsgInfo *msginfo1 = a; \
- const MsgInfo *msginfo2 = b; \
- \
- if (!msginfo1 || !msginfo2) \
- return 0; \
- \
- return (val) * (cmp_func_sort_type == SORT_ASCENDING ? 1 : -1); \
-}
-
-CMP_FUNC_DEF(procmsg_cmp_by_number, msginfo1->msgnum - msginfo2->msgnum)
-CMP_FUNC_DEF(procmsg_cmp_by_date, msginfo1->date_t - msginfo2->date_t)
-
-#undef CMP_FUNC_DEF
-#define CMP_FUNC_DEF(func_name, var_name) \
-static gint func_name(gconstpointer a, gconstpointer b) \
-{ \
- const MsgInfo *msginfo1 = a; \
- const MsgInfo *msginfo2 = b; \
- gint ret; \
- \
- if (!msginfo1->var_name) \
- return (msginfo2->var_name != NULL) * \
- (cmp_func_sort_type == SORT_ASCENDING ? -1 : 1);\
- if (!msginfo2->var_name) \
- return (cmp_func_sort_type == SORT_ASCENDING ? 1 : -1); \
- \
- ret = g_ascii_strcasecmp \
- (msginfo1->var_name, msginfo2->var_name); \
- if (ret == 0) \
- ret = msginfo1->date_t - msginfo2->date_t; \
- \
- return ret * (cmp_func_sort_type == SORT_ASCENDING ? 1 : -1); \
-}
-
-CMP_FUNC_DEF(procmsg_cmp_by_from, fromname)
-CMP_FUNC_DEF(procmsg_cmp_by_to, to)
-
-#undef CMP_FUNC_DEF
-
-static gint procmsg_cmp_by_subject(gconstpointer a, gconstpointer b)
-{
- const MsgInfo *msginfo1 = a;
- const MsgInfo *msginfo2 = b;
- gint ret;
-
- if (!msginfo1->subject)
- return (msginfo2->subject != NULL) *
- (cmp_func_sort_type == SORT_ASCENDING ? -1 : 1);
- if (!msginfo2->subject)
- return (cmp_func_sort_type == SORT_ASCENDING ? 1 : -1);
-
- ret = subject_compare_for_sort(msginfo1->subject, msginfo2->subject);
- if (ret == 0)
- ret = msginfo1->date_t - msginfo2->date_t;
-
- return ret * (cmp_func_sort_type == SORT_ASCENDING ? 1 : -1);
-}
diff --git a/src/procmsg.h b/src/procmsg.h
deleted file mode 100644
index 9e6d45b8..00000000
--- a/src/procmsg.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __PROCMSG_H__
-#define __PROCMSG_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <stdio.h>
-#include <time.h>
-#include <sys/types.h>
-#include <string.h>
-
-typedef struct _MsgInfo MsgInfo;
-typedef struct _MsgFlags MsgFlags;
-typedef struct _MsgFileInfo MsgFileInfo;
-
-#include "folder.h"
-#include "procmime.h"
-#include "prefs_filter.h"
-
-typedef enum
-{
- DATA_READ,
- DATA_WRITE,
- DATA_APPEND
-} DataOpenMode;
-
-#define MSG_NEW (1U << 0)
-#define MSG_UNREAD (1U << 1)
-#define MSG_MARKED (1U << 2)
-#define MSG_DELETED (1U << 3)
-#define MSG_REPLIED (1U << 4)
-#define MSG_FORWARDED (1U << 5)
-
-#define MSG_CLABEL_SBIT (7) /* start bit of color label */
-#define MAKE_MSG_CLABEL(h, m, l) (((h) << (MSG_CLABEL_SBIT + 2)) | \
- ((m) << (MSG_CLABEL_SBIT + 1)) | \
- ((l) << (MSG_CLABEL_SBIT + 0)))
-
-#define MSG_CLABEL_NONE MAKE_MSG_CLABEL(0U, 0U, 0U)
-#define MSG_CLABEL_1 MAKE_MSG_CLABEL(0U, 0U, 1U)
-#define MSG_CLABEL_2 MAKE_MSG_CLABEL(0U, 1U, 0U)
-#define MSG_CLABEL_3 MAKE_MSG_CLABEL(0U, 1U, 1U)
-#define MSG_CLABEL_4 MAKE_MSG_CLABEL(1U, 0U, 0U)
-#define MSG_CLABEL_5 MAKE_MSG_CLABEL(1U, 0U, 1U)
-#define MSG_CLABEL_6 MAKE_MSG_CLABEL(1U, 1U, 0U)
-#define MSG_CLABEL_7 MAKE_MSG_CLABEL(1U, 1U, 1U)
-
-#define MSG_CLABEL_ORANGE MSG_CLABEL_1
-#define MSG_CLABEL_RED MSG_CLABEL_2
-#define MSG_CLABEL_PINK MSG_CLABEL_3
-#define MSG_CLABEL_SKYBLUE MSG_CLABEL_4
-#define MSG_CLABEL_BLUE MSG_CLABEL_5
-#define MSG_CLABEL_GREEN MSG_CLABEL_6
-#define MSG_CLABEL_BROWN MSG_CLABEL_7
-
-/* RESERVED */
-#define MSG_RESERVED (1U << 31)
-
-#define MSG_CLABEL_FLAG_MASK (MSG_CLABEL_7)
-
-typedef guint32 MsgPermFlags;
-
-#define MSG_MOVE (1U << 0)
-#define MSG_COPY (1U << 1)
-#define MSG_QUEUED (1U << 16)
-#define MSG_DRAFT (1U << 17)
-#define MSG_ENCRYPTED (1U << 18)
-#define MSG_IMAP (1U << 19)
-#define MSG_NEWS (1U << 20)
-#define MSG_SIGNED (1U << 21)
-#define MSG_CACHED (1U << 28)
-#define MSG_MIME (1U << 29)
-#define MSG_INVALID (1U << 30)
-#define MSG_RECEIVED (1U << 31)
-
-#define MSG_CACHED_FLAG_MASK (MSG_MIME)
-
-typedef guint32 MsgTmpFlags;
-
-#define MSG_SET_FLAGS(msg, flags) { (msg) |= (flags); }
-#define MSG_UNSET_FLAGS(msg, flags) { (msg) &= ~(flags); }
-#define MSG_SET_PERM_FLAGS(msg, flags) \
- MSG_SET_FLAGS((msg).perm_flags, flags)
-#define MSG_SET_TMP_FLAGS(msg, flags) \
- MSG_SET_FLAGS((msg).tmp_flags, flags)
-#define MSG_UNSET_PERM_FLAGS(msg, flags) \
- MSG_UNSET_FLAGS((msg).perm_flags, flags)
-#define MSG_UNSET_TMP_FLAGS(msg, flags) \
- MSG_UNSET_FLAGS((msg).tmp_flags, flags)
-
-#define MSG_IS_NEW(msg) (((msg).perm_flags & MSG_NEW) != 0)
-#define MSG_IS_UNREAD(msg) (((msg).perm_flags & MSG_UNREAD) != 0)
-#define MSG_IS_MARKED(msg) (((msg).perm_flags & MSG_MARKED) != 0)
-#define MSG_IS_DELETED(msg) (((msg).perm_flags & MSG_DELETED) != 0)
-#define MSG_IS_REPLIED(msg) (((msg).perm_flags & MSG_REPLIED) != 0)
-#define MSG_IS_FORWARDED(msg) (((msg).perm_flags & MSG_FORWARDED) != 0)
-
-#define MSG_GET_COLORLABEL(msg) (((msg).perm_flags & MSG_CLABEL_FLAG_MASK))
-#define MSG_GET_COLORLABEL_VALUE(msg) (MSG_GET_COLORLABEL(msg) >> MSG_CLABEL_SBIT)
-#define MSG_SET_COLORLABEL_VALUE(msg, val) \
- MSG_SET_PERM_FLAGS(msg, ((((guint)(val)) & 7) << MSG_CLABEL_SBIT))
-
-#define MSG_IS_MOVE(msg) (((msg).tmp_flags & MSG_MOVE) != 0)
-#define MSG_IS_COPY(msg) (((msg).tmp_flags & MSG_COPY) != 0)
-
-#define MSG_IS_QUEUED(msg) (((msg).tmp_flags & MSG_QUEUED) != 0)
-#define MSG_IS_DRAFT(msg) (((msg).tmp_flags & MSG_DRAFT) != 0)
-#define MSG_IS_ENCRYPTED(msg) (((msg).tmp_flags & MSG_ENCRYPTED) != 0)
-#define MSG_IS_IMAP(msg) (((msg).tmp_flags & MSG_IMAP) != 0)
-#define MSG_IS_NEWS(msg) (((msg).tmp_flags & MSG_NEWS) != 0)
-#define MSG_IS_SIGNED(msg) (((msg).tmp_flags & MSG_SIGNED) != 0)
-#define MSG_IS_CACHED(msg) (((msg).tmp_flags & MSG_CACHED) != 0)
-#define MSG_IS_MIME(msg) (((msg).tmp_flags & MSG_MIME) != 0)
-#define MSG_IS_INVALID(msg) (((msg).tmp_flags & MSG_INVALID) != 0)
-#define MSG_IS_RECEIVED(msg) (((msg).tmp_flags & MSG_RECEIVED) != 0)
-
-#define WRITE_CACHE_DATA_INT(n, fp) \
-{ \
- guint32 idata; \
- \
- idata = (guint32)n; \
- fwrite(&idata, sizeof(idata), 1, fp); \
-}
-
-#define WRITE_CACHE_DATA(data, fp) \
-{ \
- size_t len; \
- \
- if (data == NULL) { \
- len = 0; \
- WRITE_CACHE_DATA_INT(len, fp); \
- } else { \
- len = strlen(data); \
- WRITE_CACHE_DATA_INT(len, fp); \
- if (len > 0) \
- fwrite(data, len, 1, fp); \
- } \
-}
-
-struct _MsgFlags
-{
- MsgPermFlags perm_flags;
- MsgTmpFlags tmp_flags;
-};
-
-struct _MsgInfo
-{
- guint msgnum;
- off_t size;
- time_t mtime;
- time_t date_t;
-
- MsgFlags flags;
-
- gchar *fromname;
-
- gchar *date;
- gchar *from;
- gchar *to;
- gchar *cc;
- gchar *newsgroups;
- gchar *subject;
- gchar *msgid;
- gchar *inreplyto;
-
- GSList *references;
-
- FolderItem *folder;
- FolderItem *to_folder;
-
- gchar *xface;
-
- /* used only for temporary messages */
- gchar *file_path;
-
- /* used only for encrypted messages */
- gchar *plaintext_file;
- guint decryption_failed : 1;
-};
-
-struct _MsgFileInfo
-{
- gchar *file;
- MsgFlags *flags;
-};
-
-GHashTable *procmsg_msg_hash_table_create (GSList *mlist);
-void procmsg_msg_hash_table_append (GHashTable *msg_table,
- GSList *mlist);
-GHashTable *procmsg_to_folder_hash_table_create (GSList *mlist);
-
-GSList *procmsg_read_cache (FolderItem *item,
- gboolean scan_file);
-void procmsg_set_flags (GSList *mlist,
- FolderItem *item);
-GSList *procmsg_sort_msg_list (GSList *mlist,
- FolderSortKey sort_key,
- FolderSortType sort_type);
-gint procmsg_get_last_num_in_msg_list(GSList *mlist);
-void procmsg_msg_list_free (GSList *mlist);
-void procmsg_write_cache (MsgInfo *msginfo,
- FILE *fp);
-void procmsg_write_flags (MsgInfo *msginfo,
- FILE *fp);
-void procmsg_flush_mark_queue (FolderItem *item,
- FILE *fp);
-void procmsg_add_mark_queue (FolderItem *item,
- gint num,
- MsgFlags flags);
-void procmsg_add_flags (FolderItem *item,
- gint num,
- MsgFlags flags);
-void procmsg_get_mark_sum (FolderItem *item,
- gint *new,
- gint *unread,
- gint *total,
- gint *min,
- gint *max,
- gint first);
-FILE *procmsg_open_cache_file (FolderItem *item,
- DataOpenMode mode);
-FILE *procmsg_open_mark_file (FolderItem *item,
- DataOpenMode mode);
-
-void procmsg_clear_cache (FolderItem *item);
-void procmsg_clear_mark (FolderItem *item);
-
-GNode *procmsg_get_thread_tree (GSList *mlist);
-
-gint procmsg_move_messages (GSList *mlist);
-gint procmsg_copy_messages (GSList *mlist);
-
-gchar *procmsg_get_message_file_path (MsgInfo *msginfo);
-gchar *procmsg_get_message_file (MsgInfo *msginfo);
-GSList *procmsg_get_message_file_list (GSList *mlist);
-void procmsg_message_file_list_free (GSList *file_list);
-FILE *procmsg_open_message (MsgInfo *msginfo);
-#if USE_GPGME
-FILE *procmsg_open_message_decrypted (MsgInfo *msginfo,
- MimeInfo **mimeinfo);
-#endif
-gboolean procmsg_msg_exist (MsgInfo *msginfo);
-
-void procmsg_empty_trash (FolderItem *trash);
-void procmsg_empty_all_trash (void);
-
-gint procmsg_save_to_outbox (FolderItem *outbox,
- const gchar *file);
-void procmsg_print_message (MsgInfo *msginfo,
- const gchar *cmdline);
-
-MsgInfo *procmsg_msginfo_copy (MsgInfo *msginfo);
-MsgInfo *procmsg_msginfo_get_full_info (MsgInfo *msginfo);
-gboolean procmsg_msginfo_equal (MsgInfo *msginfo_a,
- MsgInfo *msginfo_b);
-void procmsg_msginfo_free (MsgInfo *msginfo);
-
-gint procmsg_cmp_msgnum_for_sort (gconstpointer a,
- gconstpointer b);
-
-#endif /* __PROCMSG_H__ */
diff --git a/src/rfc2015.c b/src/rfc2015.c
index ef6a9230..8708dc81 100644
--- a/src/rfc2015.c
+++ b/src/rfc2015.c
@@ -35,6 +35,7 @@
#include <gpgme.h>
+#include "procmsg.h"
#include "procmime.h"
#include "procheader.h"
#include "base64.h"
@@ -637,6 +638,55 @@ void rfc2015_decrypt_message(MsgInfo *msginfo, MimeInfo *mimeinfo, FILE *fp)
#undef DECRYPTION_ABORT
+FILE *rfc2015_open_message_decrypted(MsgInfo *msginfo, MimeInfo **mimeinfo)
+{
+ FILE *fp;
+ MimeInfo *mimeinfo_;
+ glong fpos;
+
+ g_return_val_if_fail(msginfo != NULL, NULL);
+
+ if (mimeinfo) *mimeinfo = NULL;
+
+ if ((fp = procmsg_open_message(msginfo)) == NULL) return NULL;
+
+ mimeinfo_ = procmime_scan_mime_header(fp);
+ if (!mimeinfo_) {
+ fclose(fp);
+ return NULL;
+ }
+
+ if (!MSG_IS_ENCRYPTED(msginfo->flags) &&
+ rfc2015_is_encrypted(mimeinfo_)) {
+ MSG_SET_TMP_FLAGS(msginfo->flags, MSG_ENCRYPTED);
+ }
+
+ if (MSG_IS_ENCRYPTED(msginfo->flags) &&
+ !msginfo->plaintext_file &&
+ !msginfo->decryption_failed) {
+ fpos = ftell(fp);
+ rfc2015_decrypt_message(msginfo, mimeinfo_, fp);
+ if (msginfo->plaintext_file &&
+ !msginfo->decryption_failed) {
+ fclose(fp);
+ procmime_mimeinfo_free_all(mimeinfo_);
+ if ((fp = procmsg_open_message(msginfo)) == NULL)
+ return NULL;
+ mimeinfo_ = procmime_scan_mime_header(fp);
+ if (!mimeinfo_) {
+ fclose(fp);
+ return NULL;
+ }
+ } else {
+ if (fseek(fp, fpos, SEEK_SET) < 0)
+ perror("fseek");
+ }
+ }
+
+ if (mimeinfo) *mimeinfo = mimeinfo_;
+ return fp;
+}
+
/*
* plain contains an entire mime object.
diff --git a/src/rfc2015.h b/src/rfc2015.h
index 464b0154..e70605e1 100644
--- a/src/rfc2015.h
+++ b/src/rfc2015.h
@@ -23,6 +23,7 @@
#include <glib.h>
#include <stdio.h>
+#include "procmsg.h"
#include "procmime.h"
void rfc2015_disable_all (void);
@@ -31,11 +32,15 @@ MimeInfo **rfc2015_find_signature (MimeInfo *mimeinfo);
gboolean rfc2015_has_signature (MimeInfo *mimeinfo);
void rfc2015_check_signature (MimeInfo *mimeinfo,
FILE *fp);
+
gint rfc2015_is_encrypted (MimeInfo *mimeinfo);
gboolean rfc2015_msg_is_encrypted (const gchar *file);
void rfc2015_decrypt_message (MsgInfo *msginfo,
MimeInfo *mimeinfo,
FILE *fp);
+FILE *rfc2015_open_message_decrypted (MsgInfo *msginfo,
+ MimeInfo **mimeinfo);
+
GSList *rfc2015_create_signers_list (const gchar *keyid);
gint rfc2015_encrypt (const gchar *file,
GSList *recp_list,
diff --git a/src/smtp.c b/src/smtp.c
deleted file mode 100644
index 25a0f71a..00000000
--- a/src/smtp.c
+++ /dev/null
@@ -1,613 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-#include <glib/gi18n.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "smtp.h"
-#include "md5.h"
-#include "base64.h"
-#include "utils.h"
-
-static void smtp_session_destroy(Session *session);
-
-static gint smtp_from(SMTPSession *session);
-
-static gint smtp_auth(SMTPSession *session);
-static gint smtp_starttls(SMTPSession *session);
-static gint smtp_auth_cram_md5(SMTPSession *session);
-static gint smtp_auth_plain(SMTPSession *session);
-static gint smtp_auth_login(SMTPSession *session);
-
-static gint smtp_ehlo(SMTPSession *session);
-static gint smtp_ehlo_recv(SMTPSession *session, const gchar *msg);
-
-static gint smtp_helo(SMTPSession *session);
-static gint smtp_rcpt(SMTPSession *session);
-static gint smtp_data(SMTPSession *session);
-static gint smtp_send_data(SMTPSession *session);
-/* static gint smtp_rset(SMTPSession *session); */
-static gint smtp_quit(SMTPSession *session);
-static gint smtp_eom(SMTPSession *session);
-
-static gint smtp_session_recv_msg(Session *session, const gchar *msg);
-static gint smtp_session_send_data_finished(Session *session, guint len);
-
-
-Session *smtp_session_new(void)
-{
- SMTPSession *session;
-
- session = g_new0(SMTPSession, 1);
-
- session_init(SESSION(session));
-
- SESSION(session)->type = SESSION_SMTP;
-
- SESSION(session)->recv_msg = smtp_session_recv_msg;
-
- SESSION(session)->recv_data_finished = NULL;
- SESSION(session)->send_data_finished = smtp_session_send_data_finished;
-
- SESSION(session)->destroy = smtp_session_destroy;
-
- session->state = SMTP_READY;
-
-#if USE_SSL
- session->tls_init_done = FALSE;
-#endif
-
- session->hostname = NULL;
- session->user = NULL;
- session->pass = NULL;
-
- session->from = NULL;
- session->to_list = NULL;
- session->cur_to = NULL;
-
- session->send_data = NULL;
- session->send_data_len = 0;
-
- session->avail_auth_type = 0;
- session->forced_auth_type = 0;
- session->auth_type = 0;
-
- session->error_val = SM_OK;
- session->error_msg = NULL;
-
- return SESSION(session);
-}
-
-static void smtp_session_destroy(Session *session)
-{
- SMTPSession *smtp_session = SMTP_SESSION(session);
-
- g_free(smtp_session->hostname);
- g_free(smtp_session->user);
- g_free(smtp_session->pass);
- g_free(smtp_session->from);
-
- g_free(smtp_session->send_data);
-
- g_free(smtp_session->error_msg);
-}
-
-static gint smtp_from(SMTPSession *session)
-{
- gchar buf[MSGBUFSIZE];
-
- g_return_val_if_fail(session->from != NULL, SM_ERROR);
-
- session->state = SMTP_FROM;
-
- if (strchr(session->from, '<'))
- g_snprintf(buf, sizeof(buf), "MAIL FROM:%s", session->from);
- else
- g_snprintf(buf, sizeof(buf), "MAIL FROM:<%s>", session->from);
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
- log_print("SMTP> %s\n", buf);
-
- return SM_OK;
-}
-
-static gint smtp_auth(SMTPSession *session)
-{
-
- g_return_val_if_fail(session->user != NULL, SM_ERROR);
-
- session->state = SMTP_AUTH;
-
- if (session->forced_auth_type == SMTPAUTH_CRAM_MD5 ||
- (session->forced_auth_type == 0 &&
- (session->avail_auth_type & SMTPAUTH_CRAM_MD5) != 0))
- smtp_auth_cram_md5(session);
- else if (session->forced_auth_type == SMTPAUTH_PLAIN ||
- (session->forced_auth_type == 0 &&
- (session->avail_auth_type & SMTPAUTH_PLAIN) != 0))
- smtp_auth_plain(session);
- else if (session->forced_auth_type == SMTPAUTH_LOGIN ||
- (session->forced_auth_type == 0 &&
- (session->avail_auth_type & SMTPAUTH_LOGIN) != 0))
- smtp_auth_login(session);
- else {
- log_warning(_("SMTP AUTH not available\n"));
- return SM_AUTHFAIL;
- }
-
- return SM_OK;
-}
-
-static gint smtp_auth_recv(SMTPSession *session, const gchar *msg)
-{
- gchar buf[MSGBUFSIZE];
-
- switch (session->auth_type) {
- case SMTPAUTH_LOGIN:
- session->state = SMTP_AUTH_LOGIN_USER;
-
- if (!strncmp(msg, "334 ", 4)) {
- base64_encode(buf, session->user, strlen(session->user));
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
- buf);
- log_print("ESMTP> [USERID]\n");
- } else {
- /* Server rejects AUTH */
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
- "*");
- log_print("ESMTP> *\n");
- }
- break;
- case SMTPAUTH_CRAM_MD5:
- session->state = SMTP_AUTH_CRAM_MD5;
-
- if (!strncmp(msg, "334 ", 4)) {
- gchar *response;
- gchar *response64;
- gchar *challenge;
- gint challengelen;
- guchar hexdigest[33];
-
- challenge = g_malloc(strlen(msg + 4) + 1);
- challengelen = base64_decode(challenge, msg + 4, -1);
- challenge[challengelen] = '\0';
- log_print("ESMTP< [Decoded: %s]\n", challenge);
-
- g_snprintf(buf, sizeof(buf), "%s", session->pass);
- md5_hex_hmac(hexdigest, challenge, challengelen,
- buf, strlen(session->pass));
- g_free(challenge);
-
- response = g_strdup_printf
- ("%s %s", session->user, hexdigest);
- log_print("ESMTP> [Encoded: %s]\n", response);
-
- response64 = g_malloc((strlen(response) + 3) * 2 + 1);
- base64_encode(response64, response, strlen(response));
- g_free(response);
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
- response64);
- log_print("ESMTP> %s\n", response64);
- g_free(response64);
- } else {
- /* Server rejects AUTH */
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL,
- "*");
- log_print("ESMTP> *\n");
- }
- break;
- case SMTPAUTH_DIGEST_MD5:
- default:
- /* stop smtp_auth when no correct authtype */
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "*");
- log_print("ESMTP> *\n");
- break;
- }
-
- return SM_OK;
-}
-
-static gint smtp_auth_login_user_recv(SMTPSession *session, const gchar *msg)
-{
- gchar buf[MSGBUFSIZE];
-
- session->state = SMTP_AUTH_LOGIN_PASS;
-
- if (!strncmp(msg, "334 ", 4))
- base64_encode(buf, session->pass, strlen(session->pass));
- else
- /* Server rejects AUTH */
- g_snprintf(buf, sizeof(buf), "*");
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
- log_print("ESMTP> [PASSWORD]\n");
-
- return SM_OK;
-}
-
-static gint smtp_ehlo(SMTPSession *session)
-{
- gchar buf[MSGBUFSIZE];
-
- session->state = SMTP_EHLO;
-
- session->avail_auth_type = 0;
-
- g_snprintf(buf, sizeof(buf), "EHLO %s",
- session->hostname ? session->hostname : get_domain_name());
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
- log_print("ESMTP> %s\n", buf);
-
- return SM_OK;
-}
-
-static gint smtp_ehlo_recv(SMTPSession *session, const gchar *msg)
-{
- if (strncmp(msg, "250", 3) == 0) {
- const gchar *p = msg;
- p += 3;
- if (*p == '-' || *p == ' ') p++;
- if (g_ascii_strncasecmp(p, "AUTH", 4) == 0 && p[4] != '\0') {
- p += 5;
- if (strcasestr(p, "PLAIN"))
- session->avail_auth_type |= SMTPAUTH_PLAIN;
- if (strcasestr(p, "LOGIN"))
- session->avail_auth_type |= SMTPAUTH_LOGIN;
- if (strcasestr(p, "CRAM-MD5"))
- session->avail_auth_type |= SMTPAUTH_CRAM_MD5;
- if (strcasestr(p, "DIGEST-MD5"))
- session->avail_auth_type |= SMTPAUTH_DIGEST_MD5;
- }
- return SM_OK;
- } else if ((msg[0] == '1' || msg[0] == '2' || msg[0] == '3') &&
- (msg[3] == ' ' || msg[3] == '\0'))
- return SM_OK;
- else if (msg[0] == '5' && msg[1] == '0' &&
- (msg[2] == '4' || msg[2] == '3' || msg[2] == '1'))
- return SM_ERROR;
-
- return SM_ERROR;
-}
-
-static gint smtp_starttls(SMTPSession *session)
-{
- session->state = SMTP_STARTTLS;
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "STARTTLS");
- log_print("ESMTP> STARTTLS\n");
-
- return SM_OK;
-}
-
-static gint smtp_auth_cram_md5(SMTPSession *session)
-{
- session->state = SMTP_AUTH;
- session->auth_type = SMTPAUTH_CRAM_MD5;
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "AUTH CRAM-MD5");
- log_print("ESMTP> AUTH CRAM-MD5\n");
-
- return SM_OK;
-}
-
-static gint smtp_auth_plain(SMTPSession *session)
-{
- gchar *authstr;
- gint authlen;
- gchar *outbuf;
- gchar *p;
-
- session->state = SMTP_AUTH_PLAIN;
- session->auth_type = SMTPAUTH_PLAIN;
-
- /*
- * construct the string: \0<user>\0<pass>
- */
-
- authlen = 1 + strlen(session->user) + 1 + strlen(session->pass);
- authstr = g_malloc(authlen + 1);
-
- p = authstr;
-
- *p++ = '\0';
- strcpy(p, session->user);
- p += strlen(p) + 1;
- strcpy(p, session->pass);
-
- outbuf = g_malloc(sizeof("AUTH PLAIN ") + authlen * 2 + 1);
-
- strcpy(outbuf, "AUTH PLAIN ");
- p = outbuf + strlen(outbuf);
- base64_encode(p, authstr, authlen);
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, outbuf);
- log_print("ESMTP> AUTH PLAIN ********\n");
-
- g_free(outbuf);
- g_free(authstr);
-
- return SM_OK;
-}
-
-static gint smtp_auth_login(SMTPSession *session)
-{
- session->state = SMTP_AUTH;
- session->auth_type = SMTPAUTH_LOGIN;
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "AUTH LOGIN");
- log_print("ESMTP> AUTH LOGIN\n");
-
- return SM_OK;
-}
-
-static gint smtp_helo(SMTPSession *session)
-{
- gchar buf[MSGBUFSIZE];
-
- session->state = SMTP_HELO;
-
- g_snprintf(buf, sizeof(buf), "HELO %s",
- session->hostname ? session->hostname : get_domain_name());
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
- log_print("SMTP> %s\n", buf);
-
- return SM_OK;
-}
-
-static gint smtp_rcpt(SMTPSession *session)
-{
- gchar buf[MSGBUFSIZE];
- gchar *to;
-
- g_return_val_if_fail(session->cur_to != NULL, SM_ERROR);
-
- session->state = SMTP_RCPT;
-
- to = (gchar *)session->cur_to->data;
-
- if (strchr(to, '<'))
- g_snprintf(buf, sizeof(buf), "RCPT TO:%s", to);
- else
- g_snprintf(buf, sizeof(buf), "RCPT TO:<%s>", to);
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, buf);
- log_print("SMTP> %s\n", buf);
-
- session->cur_to = session->cur_to->next;
-
- return SM_OK;
-}
-
-static gint smtp_data(SMTPSession *session)
-{
- session->state = SMTP_DATA;
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "DATA");
- log_print("SMTP> DATA\n");
-
- return SM_OK;
-}
-
-static gint smtp_send_data(SMTPSession *session)
-{
- session->state = SMTP_SEND_DATA;
-
- session_send_data(SESSION(session), session->send_data,
- session->send_data_len);
-
- return SM_OK;
-}
-
-#if 0
-static gint smtp_rset(SMTPSession *session)
-{
- session->state = SMTP_RSET;
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "RSET");
- log_print("SMTP> RSET\n");
-
- return SM_OK;
-}
-#endif
-
-static gint smtp_quit(SMTPSession *session)
-{
- session->state = SMTP_QUIT;
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, "QUIT");
- log_print("SMTP> QUIT\n");
-
- return SM_OK;
-}
-
-static gint smtp_eom(SMTPSession *session)
-{
- session->state = SMTP_EOM;
-
- session_send_msg(SESSION(session), SESSION_MSG_NORMAL, ".");
- log_print("SMTP> . (EOM)\n");
-
- return SM_OK;
-}
-
-static gint smtp_session_recv_msg(Session *session, const gchar *msg)
-{
- SMTPSession *smtp_session = SMTP_SESSION(session);
- gboolean cont = FALSE;
-
- if (strlen(msg) < 4) {
- log_warning(_("bad SMTP response\n"));
- return -1;
- }
-
- switch (smtp_session->state) {
- case SMTP_EHLO:
- case SMTP_STARTTLS:
- case SMTP_AUTH:
- case SMTP_AUTH_PLAIN:
- case SMTP_AUTH_LOGIN_USER:
- case SMTP_AUTH_LOGIN_PASS:
- case SMTP_AUTH_CRAM_MD5:
- log_print("ESMTP< %s\n", msg);
- break;
- default:
- log_print("SMTP< %s\n", msg);
- break;
- }
-
- if (msg[0] == '5' && msg[1] == '0' &&
- (msg[2] == '4' || msg[2] == '3' || msg[2] == '1')) {
- log_warning(_("error occurred on SMTP session\n"));
- smtp_session->state = SMTP_ERROR;
- smtp_session->error_val = SM_ERROR;
- g_free(smtp_session->error_msg);
- smtp_session->error_msg = g_strdup(msg);
- return -1;
- }
-
- if (!strncmp(msg, "535", 3)) {
- log_warning(_("error occurred on authentication\n"));
- smtp_session->state = SMTP_ERROR;
- smtp_session->error_val = SM_AUTHFAIL;
- g_free(smtp_session->error_msg);
- smtp_session->error_msg = g_strdup(msg);
- return -1;
- }
-
- if (msg[0] != '1' && msg[0] != '2' && msg[0] != '3') {
- log_warning(_("error occurred on SMTP session\n"));
- smtp_session->state = SMTP_ERROR;
- smtp_session->error_val = SM_ERROR;
- g_free(smtp_session->error_msg);
- smtp_session->error_msg = g_strdup(msg);
- return -1;
- }
-
- if (msg[3] == '-')
- cont = TRUE;
- else if (msg[3] != ' ' && msg[3] != '\0') {
- log_warning(_("bad SMTP response\n"));
- smtp_session->state = SMTP_ERROR;
- smtp_session->error_val = SM_UNRECOVERABLE;
- return -1;
- }
-
- /* ignore all multiline responses except for EHLO */
- if (cont && smtp_session->state != SMTP_EHLO)
- return session_recv_msg(session);
-
- switch (smtp_session->state) {
- case SMTP_READY:
- case SMTP_CONNECTED:
-#if USE_SSL
- if (smtp_session->user || session->ssl_type != SSL_NONE)
-#else
- if (smtp_session->user)
-#endif
- smtp_ehlo(smtp_session);
- else
- smtp_helo(smtp_session);
- break;
- case SMTP_HELO:
- smtp_from(smtp_session);
- break;
- case SMTP_EHLO:
- smtp_ehlo_recv(smtp_session, msg);
- if (cont == TRUE)
- break;
-#if USE_SSL
- if (session->ssl_type == SSL_STARTTLS &&
- smtp_session->tls_init_done == FALSE) {
- smtp_starttls(smtp_session);
- break;
- }
-#endif
- if (smtp_session->user) {
- if (smtp_auth(smtp_session) != SM_OK)
- smtp_from(smtp_session);
- } else
- smtp_from(smtp_session);
- break;
- case SMTP_STARTTLS:
-#if USE_SSL
- if (session_start_tls(session) < 0) {
- log_warning(_("can't start TLS session\n"));
- smtp_session->state = SMTP_ERROR;
- smtp_session->error_val = SM_ERROR;
- return -1;
- }
- smtp_session->tls_init_done = TRUE;
- smtp_ehlo(smtp_session);
-#endif
- break;
- case SMTP_AUTH:
- smtp_auth_recv(smtp_session, msg);
- break;
- case SMTP_AUTH_LOGIN_USER:
- smtp_auth_login_user_recv(smtp_session, msg);
- break;
- case SMTP_AUTH_PLAIN:
- case SMTP_AUTH_LOGIN_PASS:
- case SMTP_AUTH_CRAM_MD5:
- smtp_from(smtp_session);
- break;
- case SMTP_FROM:
- if (smtp_session->cur_to)
- smtp_rcpt(smtp_session);
- break;
- case SMTP_RCPT:
- if (smtp_session->cur_to)
- smtp_rcpt(smtp_session);
- else
- smtp_data(smtp_session);
- break;
- case SMTP_DATA:
- smtp_send_data(smtp_session);
- break;
- case SMTP_EOM:
- smtp_quit(smtp_session);
- break;
- case SMTP_QUIT:
- session_disconnect(session);
- break;
- case SMTP_ERROR:
- default:
- log_warning(_("error occurred on SMTP session\n"));
- smtp_session->error_val = SM_ERROR;
- return -1;
- }
-
- if (cont)
- return session_recv_msg(session);
-
- return 0;
-}
-
-static gint smtp_session_send_data_finished(Session *session, guint len)
-{
- smtp_eom(SMTP_SESSION(session));
- return 0;
-}
diff --git a/src/smtp.h b/src/smtp.h
deleted file mode 100644
index 445bba69..00000000
--- a/src/smtp.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2005 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
- * the Free Software Foundation; either version 2 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef __SMTP_H__
-#define __SMTP_H__
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include <glib.h>
-
-#include "session.h"
-
-typedef struct _SMTPSession SMTPSession;
-
-#define SMTP_SESSION(obj) ((SMTPSession *)obj)
-
-#define MSGBUFSIZE 8192
-
-typedef enum
-{
- SM_OK = 0,
- SM_ERROR = 128,
- SM_UNRECOVERABLE = 129,
- SM_AUTHFAIL = 130
-} SMTPErrorValue;
-
-typedef enum
-{
- ESMTP_8BITMIME = 1 << 0,
- ESMTP_SIZE = 1 << 1,
- ESMTP_ETRN = 1 << 2
-} ESMTPFlag;
-
-typedef enum
-{
- SMTPAUTH_LOGIN = 1 << 0,
- SMTPAUTH_CRAM_MD5 = 1 << 1,
- SMTPAUTH_DIGEST_MD5 = 1 << 2,
- SMTPAUTH_PLAIN = 1 << 3
-} SMTPAuthType;
-
-typedef enum
-{
- SMTP_READY,
- SMTP_CONNECTED,
- SMTP_HELO,
- SMTP_EHLO,
- SMTP_STARTTLS,
- SMTP_FROM,
- SMTP_AUTH,
- SMTP_AUTH_PLAIN,
- SMTP_AUTH_LOGIN_USER,
- SMTP_AUTH_LOGIN_PASS,
- SMTP_AUTH_CRAM_MD5,
- SMTP_RCPT,
- SMTP_DATA,
- SMTP_SEND_DATA,
- SMTP_EOM,
- SMTP_RSET,
- SMTP_QUIT,
- SMTP_ERROR,
- SMTP_DISCONNECTED,
-
- N_SMTP_PHASE
-} SMTPState;
-
-struct _SMTPSession
-{
- Session session;
-
- SMTPState state;
-
-#if USE_SSL
- gboolean tls_init_done;
-#endif
-
- gchar *hostname;
-
- gchar *user;
- gchar *pass;
-
- gchar *from;
- GSList *to_list;
- GSList *cur_to;
-
- guchar *send_data;
- guint send_data_len;
-
- SMTPAuthType avail_auth_type;
- SMTPAuthType forced_auth_type;
- SMTPAuthType auth_type;
-
- SMTPErrorValue error_val;
- gchar *error_msg;
-};
-
-Session *smtp_session_new (void);
-
-#endif /* __SMTP_H__ */