* src/folder.c [1.213.2.6]
* src/folder.h [1.87.2.6] * src/inc.c [1.149.2.7] * src/messageview.c [1.94.2.8] * src/procheader.c [1.47.2.6] * src/procmsg.c [1.150.2.4] * src/procmsg.h [1.60.2.5] * src/pop.c [1.56.2.4] * src/pop.h [1.17.2.3] Let too big messages get downloaded, but truncated Add a button to download them completely
This commit is contained in:
parent
633a635211
commit
1a778f92f1
11 changed files with 480 additions and 26 deletions
|
@ -1,3 +1,17 @@
|
|||
2004-07-08 [colin] 0.9.11cvs17.10
|
||||
|
||||
* src/folder.c [1.213.2.6]
|
||||
* src/folder.h [1.87.2.6]
|
||||
* src/inc.c [1.149.2.7]
|
||||
* src/messageview.c [1.94.2.8]
|
||||
* src/procheader.c [1.47.2.6]
|
||||
* src/procmsg.c [1.150.2.4]
|
||||
* src/procmsg.h [1.60.2.5]
|
||||
* src/pop.c [1.56.2.4]
|
||||
* src/pop.h [1.17.2.3]
|
||||
Let too big messages get downloaded, but truncated
|
||||
Add a button to download them completely
|
||||
|
||||
2004-07-06 [colin] 0.9.11cvs17.9
|
||||
|
||||
* src/gtk/quicksearch.c [1.1.2.3]
|
||||
|
|
|
@ -11,7 +11,7 @@ MINOR_VERSION=9
|
|||
MICRO_VERSION=11
|
||||
INTERFACE_AGE=0
|
||||
BINARY_AGE=0
|
||||
EXTRA_VERSION=17.9
|
||||
EXTRA_VERSION=17.10
|
||||
EXTRA_RELEASE=
|
||||
|
||||
if test \( $EXTRA_VERSION -eq 0 \) -o \( "x$EXTRA_RELEASE" != "x" \); then
|
||||
|
|
35
src/folder.c
35
src/folder.c
|
@ -1055,6 +1055,41 @@ FolderItem *folder_find_item_from_path(const gchar *path)
|
|||
return d[1];
|
||||
}
|
||||
|
||||
static gboolean folder_item_find_phys_func(GNode *node, gpointer data)
|
||||
{
|
||||
FolderItem *item = node->data;
|
||||
gpointer *d = data;
|
||||
const gchar *path = d[0];
|
||||
const gchar *physpath = g_strdup_printf("%s%s%s%s%s",
|
||||
get_home_dir(), G_DIR_SEPARATOR_S,
|
||||
LOCAL_FOLDER(item->folder)->rootpath,
|
||||
G_DIR_SEPARATOR_S, item->path);
|
||||
|
||||
if (path_cmp(path, physpath) != 0) {
|
||||
g_free(physpath);
|
||||
return FALSE;
|
||||
}
|
||||
g_free(physpath);
|
||||
d[1] = item;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
FolderItem *folder_find_item_from_phys_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_phys_func, d);
|
||||
return d[1];
|
||||
}
|
||||
|
||||
FolderItem *folder_find_child_item_by_name(FolderItem *item, const gchar *name)
|
||||
{
|
||||
GNode *node;
|
||||
|
|
|
@ -698,6 +698,7 @@ Folder *folder_find_from_path (const gchar *path);
|
|||
Folder *folder_find_from_name (const gchar *name,
|
||||
FolderClass *klass);
|
||||
FolderItem *folder_find_item_from_path (const gchar *path);
|
||||
FolderItem *folder_find_item_from_phys_path (const gchar *path);
|
||||
FolderClass *folder_get_class_from_string (const gchar *str);
|
||||
FolderItem *folder_find_child_item_by_name (FolderItem *item,
|
||||
const gchar *name);
|
||||
|
|
22
src/inc.c
22
src/inc.c
|
@ -120,7 +120,8 @@ static gint inc_recv_message (Session *session,
|
|||
const gchar *msg,
|
||||
gpointer data);
|
||||
static gint inc_drop_message (Pop3Session *session,
|
||||
const gchar *file);
|
||||
const gchar *file,
|
||||
gboolean update_file);
|
||||
|
||||
static void inc_put_error (IncState istate,
|
||||
const gchar *msg);
|
||||
|
@ -1039,7 +1040,7 @@ static gint inc_recv_message(Session *session, const gchar *msg, gpointer data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static gint inc_drop_message(Pop3Session *session, const gchar *file)
|
||||
static gint inc_drop_message(Pop3Session *session, const gchar *file, gboolean update_file)
|
||||
{
|
||||
FolderItem *inbox;
|
||||
FolderItem *dropfolder;
|
||||
|
@ -1064,11 +1065,24 @@ static gint inc_drop_message(Pop3Session *session, const gchar *file)
|
|||
dropfolder = folder_get_default_processing();
|
||||
|
||||
/* add msg file to drop folder */
|
||||
if ((msgnum = folder_item_add_msg(dropfolder, file, NULL, TRUE)) < 0) {
|
||||
if ((msgnum = folder_item_add_msg(dropfolder, file, NULL, !update_file)) < 0) {
|
||||
unlink(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (update_file) {
|
||||
gchar *path = strdup(file);
|
||||
gchar *snum = strrchr(file, G_DIR_SEPARATOR)+1;
|
||||
int num = atoi(snum);
|
||||
FolderItem *item = NULL;
|
||||
|
||||
*(strrchr(path, G_DIR_SEPARATOR))='\0';
|
||||
item = folder_find_item_from_phys_path(path);
|
||||
|
||||
if (item) {
|
||||
folder_item_remove_msg(item, num);
|
||||
}
|
||||
g_free(path);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
#include "stock_pixmap.h"
|
||||
#include "hooks.h"
|
||||
#include "filtering.h"
|
||||
#include "pop.h"
|
||||
|
||||
static GList *messageview_list = NULL;
|
||||
|
||||
|
@ -77,6 +78,10 @@ static void return_receipt_show (NoticeView *noticeview,
|
|||
MsgInfo *msginfo);
|
||||
static void return_receipt_send_clicked (NoticeView *noticeview,
|
||||
MsgInfo *msginfo);
|
||||
static void partial_recv_show (NoticeView *noticeview,
|
||||
MsgInfo *msginfo);
|
||||
static void partial_recv_dload_clicked (NoticeView *noticeview,
|
||||
MsgInfo *msginfo);
|
||||
static void save_as_cb (gpointer data,
|
||||
guint action,
|
||||
GtkWidget *widget);
|
||||
|
@ -717,7 +722,9 @@ gint messageview_show(MessageView *messageview, MsgInfo *msginfo,
|
|||
|
||||
mimeview_show_message(messageview->mimeview, mimeinfo, file);
|
||||
|
||||
if ((messageview->msginfo->dispositionnotificationto ||
|
||||
if (messageview->msginfo->partial_recv)
|
||||
partial_recv_show(messageview->noticeview, messageview->msginfo);
|
||||
else if ((messageview->msginfo->dispositionnotificationto ||
|
||||
messageview->msginfo->returnreceiptto) &&
|
||||
!MSG_IS_RETRCPT_SENT(messageview->msginfo->flags))
|
||||
return_receipt_show(messageview->noticeview, messageview->msginfo);
|
||||
|
@ -1050,6 +1057,54 @@ static void return_receipt_send_clicked(NoticeView *noticeview, MsgInfo *msginfo
|
|||
g_free(file);
|
||||
}
|
||||
|
||||
static void partial_recv_show(NoticeView *noticeview, MsgInfo *msginfo)
|
||||
{
|
||||
gchar *text = NULL;
|
||||
if (!msginfo->planned_download) {
|
||||
text = g_strdup_printf(_("This message has been partially retrieved; it is %dKB large."),
|
||||
msginfo->total_size/1024);
|
||||
noticeview_set_text(noticeview, text);
|
||||
g_free(text);
|
||||
noticeview_set_button_text(noticeview, _("Mark for download"));
|
||||
noticeview_set_button_press_callback(noticeview,
|
||||
GTK_SIGNAL_FUNC(partial_recv_dload_clicked),
|
||||
(gpointer) msginfo);
|
||||
noticeview_show(noticeview);
|
||||
} else {
|
||||
text = g_strdup_printf(_("This message has been partially retrieved and is planned for download; it is %dKB large."),
|
||||
msginfo->total_size/1024);
|
||||
noticeview_set_text(noticeview, text);
|
||||
noticeview_set_button_text(noticeview, NULL);
|
||||
g_free(text);
|
||||
noticeview_show(noticeview);
|
||||
}
|
||||
}
|
||||
|
||||
static void partial_recv_dload_clicked(NoticeView *noticeview, MsgInfo *msginfo)
|
||||
{
|
||||
MsgInfo *tmpmsginfo;
|
||||
gchar *file;
|
||||
|
||||
file = procmsg_get_message_file_path(msginfo);
|
||||
if (!file) {
|
||||
g_warning("can't get message file path.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
tmpmsginfo = procheader_parse_file(file, msginfo->flags, TRUE, TRUE);
|
||||
tmpmsginfo->folder = msginfo->folder;
|
||||
tmpmsginfo->msgnum = msginfo->msgnum;
|
||||
|
||||
if (pop3_mark_for_download(tmpmsginfo->account_server, tmpmsginfo->account_login,
|
||||
tmpmsginfo->partial_recv, file) == 0) {
|
||||
msginfo->planned_download = 1;
|
||||
partial_recv_show(noticeview, msginfo);
|
||||
}
|
||||
|
||||
procmsg_msginfo_free(tmpmsginfo);
|
||||
g_free(file);
|
||||
}
|
||||
|
||||
static void select_account_cb(GtkWidget *w, gpointer data)
|
||||
{
|
||||
*(gint*)data = GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(w)));
|
||||
|
|
309
src/pop.c
309
src/pop.c
|
@ -78,7 +78,8 @@ static void pop3_session_destroy (Session *session);
|
|||
|
||||
static gint pop3_write_msg_to_file (const gchar *file,
|
||||
const gchar *data,
|
||||
guint len);
|
||||
guint len,
|
||||
const gchar *prefix);
|
||||
|
||||
static Pop3State pop3_lookup_next (Pop3Session *session);
|
||||
static Pop3ErrorValue pop3_ok (Pop3Session *session,
|
||||
|
@ -90,6 +91,7 @@ static gint pop3_session_recv_data_finished (Session *session,
|
|||
guchar *data,
|
||||
guint len);
|
||||
|
||||
static gchar *pop3_get_filename_for_partial_mail(Pop3Session *session, gchar *muidl);
|
||||
|
||||
static gint pop3_greeting_recv(Pop3Session *session, const gchar *msg)
|
||||
{
|
||||
|
@ -236,6 +238,7 @@ static gint pop3_getrange_uidl_recv(Pop3Session *session, const gchar *data,
|
|||
gint buf_len;
|
||||
gint num;
|
||||
time_t recv_time;
|
||||
gint partial_recv;
|
||||
const gchar *p = data;
|
||||
const gchar *lastp = data + len;
|
||||
const gchar *newline;
|
||||
|
@ -260,9 +263,13 @@ static gint pop3_getrange_uidl_recv(Pop3Session *session, const gchar *data,
|
|||
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;
|
||||
partial_recv = (gint)g_hash_table_lookup(session->partial_recv_table, id);
|
||||
|
||||
if (!session->ac_prefs->getall && recv_time != RECV_TIME_NONE) {
|
||||
session->msg[num].received = (partial_recv != 2);
|
||||
session->msg[num].partial_recv = partial_recv;
|
||||
|
||||
}
|
||||
if (!session->new_msg_exist &&
|
||||
(session->ac_prefs->getall || recv_time == RECV_TIME_NONE ||
|
||||
session->ac_prefs->rmmail)) {
|
||||
|
@ -335,7 +342,7 @@ static gint pop3_retr_recv(Pop3Session *session, const gchar *data, guint len)
|
|||
|
||||
file = get_tmp_file();
|
||||
if (pop3_write_msg_to_file(file, mail_receive_data.data,
|
||||
strlen(mail_receive_data.data)) < 0) {
|
||||
strlen(mail_receive_data.data), NULL) < 0) {
|
||||
g_free(file);
|
||||
g_free(mail_receive_data.data);
|
||||
session->error_val = PS_IOERR;
|
||||
|
@ -343,8 +350,78 @@ static gint pop3_retr_recv(Pop3Session *session, const gchar *data, guint len)
|
|||
}
|
||||
g_free(mail_receive_data.data);
|
||||
|
||||
if (session->msg[session->cur_msg].partial_recv == 2) {
|
||||
gchar *old_file = pop3_get_filename_for_partial_mail(session, session->msg[session->cur_msg].uidl);
|
||||
unlink(old_file);
|
||||
rename(file, old_file);
|
||||
g_free(file);
|
||||
file = old_file;
|
||||
/* drop_ok: 0: success 1: don't receive -1: error */
|
||||
drop_ok = session->drop_message(session, file, TRUE);
|
||||
} else {
|
||||
/* drop_ok: 0: success 1: don't receive -1: error */
|
||||
drop_ok = session->drop_message(session, file, FALSE);
|
||||
}
|
||||
g_free(file);
|
||||
if (drop_ok < 0) {
|
||||
session->error_val = PS_IOERR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
stats:
|
||||
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].partial_recv = FALSE;
|
||||
|
||||
session->msg[session->cur_msg].recv_time =
|
||||
drop_ok == 1 ? RECV_TIME_KEEP : session->current_time;
|
||||
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
static gint pop3_top_send(Pop3Session *session)
|
||||
{
|
||||
session->state = POP3_TOP;
|
||||
pop3_gen_send(session, "TOP %d 10", session->cur_msg);
|
||||
return PS_SUCCESS;
|
||||
}
|
||||
|
||||
static gint pop3_top_recv(Pop3Session *session, const gchar *data, guint len)
|
||||
{
|
||||
gchar *file;
|
||||
gint drop_ok;
|
||||
MailReceiveData mail_receive_data;
|
||||
gchar *partial_notice = NULL;
|
||||
|
||||
mail_receive_data.session = session;
|
||||
mail_receive_data.data = g_strndup(data, len);
|
||||
hooks_invoke(MAIL_RECEIVE_HOOKLIST, &mail_receive_data);
|
||||
|
||||
partial_notice = g_strdup_printf("SC-Partially-Retrieved: %s\n"
|
||||
"SC-Account-Server: %s\n"
|
||||
"SC-Account-Login: %s\n"
|
||||
"SC-Message-Size: %d",
|
||||
session->msg[session->cur_msg].uidl,
|
||||
session->ac_prefs->recv_server,
|
||||
session->ac_prefs->userid,
|
||||
session->msg[session->cur_msg].size);
|
||||
file = get_tmp_file();
|
||||
if (pop3_write_msg_to_file(file, mail_receive_data.data,
|
||||
strlen(mail_receive_data.data), partial_notice) < 0) {
|
||||
g_free(file);
|
||||
g_free(mail_receive_data.data);
|
||||
session->error_val = PS_IOERR;
|
||||
g_free(partial_notice);
|
||||
return -1;
|
||||
}
|
||||
g_free(mail_receive_data.data);
|
||||
g_free(partial_notice);
|
||||
|
||||
/* drop_ok: 0: success 1: don't receive -1: error */
|
||||
drop_ok = session->drop_message(session, file);
|
||||
drop_ok = session->drop_message(session, file, FALSE);
|
||||
g_free(file);
|
||||
if (drop_ok < 0) {
|
||||
session->error_val = PS_IOERR;
|
||||
|
@ -356,6 +433,7 @@ static gint pop3_retr_recv(Pop3Session *session, const gchar *data, guint len)
|
|||
session->cur_total_num++;
|
||||
|
||||
session->msg[session->cur_msg].received = TRUE;
|
||||
session->msg[session->cur_msg].partial_recv = TRUE;
|
||||
session->msg[session->cur_msg].recv_time =
|
||||
drop_ok == 1 ? RECV_TIME_KEEP : session->current_time;
|
||||
|
||||
|
@ -420,7 +498,7 @@ Session *pop3_session_new(PrefsAccount *account)
|
|||
session->state = POP3_READY;
|
||||
session->ac_prefs = account;
|
||||
session->pop_before_smtp = FALSE;
|
||||
session->uidl_table = pop3_get_uidl_table(account);
|
||||
pop3_get_uidl_table(account, session);
|
||||
session->current_time = time(NULL);
|
||||
session->error_val = PS_SUCCESS;
|
||||
session->error_msg = NULL;
|
||||
|
@ -444,23 +522,31 @@ static void pop3_session_destroy(Session *session)
|
|||
g_hash_table_destroy(pop3_session->uidl_table);
|
||||
}
|
||||
|
||||
if (pop3_session->partial_recv_table) {
|
||||
hash_free_strings(pop3_session->partial_recv_table);
|
||||
g_hash_table_destroy(pop3_session->partial_recv_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 *pop3_get_uidl_table(PrefsAccount *ac_prefs, Pop3Session *session)
|
||||
{
|
||||
GHashTable *table;
|
||||
GHashTable *partial_recv_table;
|
||||
gchar *path;
|
||||
FILE *fp;
|
||||
gchar buf[POPBUFSIZE];
|
||||
gchar uidl[POPBUFSIZE];
|
||||
time_t recv_time;
|
||||
time_t now;
|
||||
|
||||
gint partial_recv;
|
||||
|
||||
table = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
partial_recv_table = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
|
||||
path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
|
||||
"uidl", G_DIR_SEPARATOR_S, ac_prefs->recv_server,
|
||||
|
@ -474,6 +560,8 @@ GHashTable *pop3_get_uidl_table(PrefsAccount *ac_prefs)
|
|||
if ((fp = fopen(path, "rb")) == NULL) {
|
||||
if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
|
||||
g_free(path);
|
||||
session->uidl_table = table;
|
||||
session->partial_recv_table = partial_recv_table;
|
||||
return table;
|
||||
}
|
||||
}
|
||||
|
@ -482,24 +570,187 @@ GHashTable *pop3_get_uidl_table(PrefsAccount *ac_prefs)
|
|||
now = time(NULL);
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
gchar tmp[POPBUFSIZE];
|
||||
strretchomp(buf);
|
||||
recv_time = RECV_TIME_NONE;
|
||||
if (sscanf(buf, "%s\t%ld", uidl, &recv_time) != 2) {
|
||||
partial_recv = 0;
|
||||
|
||||
if (sscanf(buf, "%s\t%ld\t%s", uidl, &recv_time, &tmp) < 2) {
|
||||
if (sscanf(buf, "%s", uidl) != 1)
|
||||
continue;
|
||||
else
|
||||
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));
|
||||
if (strlen(tmp) == 1)
|
||||
partial_recv = atoi(tmp);
|
||||
else
|
||||
partial_recv = 2;
|
||||
|
||||
g_hash_table_insert(partial_recv_table, g_strdup(uidl),
|
||||
GINT_TO_POINTER(partial_recv));
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
session->uidl_table = table;
|
||||
session->partial_recv_table = partial_recv_table;
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
static gchar *pop3_get_filename_for_partial_mail(Pop3Session *session, gchar *muidl)
|
||||
{
|
||||
gchar *path;
|
||||
gchar *result = NULL;
|
||||
FILE *fp;
|
||||
gchar buf[POPBUFSIZE];
|
||||
gchar uidl[POPBUFSIZE];
|
||||
time_t recv_time;
|
||||
time_t now;
|
||||
gint partial_recv;
|
||||
|
||||
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 = fopen(path, "rb")) == NULL) {
|
||||
if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
|
||||
g_free(path);
|
||||
path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
|
||||
"uidl-", session->ac_prefs->recv_server,
|
||||
"-", session->ac_prefs->userid, NULL);
|
||||
if ((fp = fopen(path, "rb")) == NULL) {
|
||||
if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
|
||||
g_free(path);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
g_free(path);
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
gchar tmp[POPBUFSIZE];
|
||||
strretchomp(buf);
|
||||
recv_time = RECV_TIME_NONE;
|
||||
partial_recv = 0;
|
||||
|
||||
if (sscanf(buf, "%s\t%ld\t%s", uidl, &recv_time, &tmp) < 2) {
|
||||
if (sscanf(buf, "%s", uidl) != 1)
|
||||
continue;
|
||||
else {
|
||||
recv_time = now;
|
||||
}
|
||||
}
|
||||
if (!strcmp(muidl, uidl)) {
|
||||
result = strdup(tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int pop3_mark_for_download(const gchar *server, const gchar *login, const gchar *muidl, const gchar *filename)
|
||||
{
|
||||
gchar *path;
|
||||
gchar *pathnew;
|
||||
FILE *fp;
|
||||
FILE *fpnew;
|
||||
gchar buf[POPBUFSIZE];
|
||||
gchar uidl[POPBUFSIZE];
|
||||
time_t recv_time;
|
||||
time_t now;
|
||||
int len;
|
||||
gchar partial_recv[POPBUFSIZE];
|
||||
|
||||
|
||||
path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
|
||||
"uidl", G_DIR_SEPARATOR_S, server,
|
||||
"-", login, NULL);
|
||||
if ((fp = fopen(path, "rb")) == NULL) {
|
||||
perror("fopen1");
|
||||
if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
|
||||
g_free(path);
|
||||
path = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
|
||||
"uidl-", server,
|
||||
"-", login, NULL);
|
||||
if ((fp = fopen(path, "rb")) == NULL) {
|
||||
if (ENOENT != errno) FILE_OP_ERROR(path, "fopen");
|
||||
g_free(path);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
pathnew = g_strconcat(get_rc_dir(), G_DIR_SEPARATOR_S,
|
||||
"uidl", G_DIR_SEPARATOR_S, server,
|
||||
"-", login, ".new", NULL);
|
||||
if ((fpnew = fopen(pathnew, "wb")) == NULL) {
|
||||
perror("fopen2");
|
||||
fclose(fp);
|
||||
g_free(pathnew);
|
||||
return -1;
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
strretchomp(buf);
|
||||
recv_time = RECV_TIME_NONE;
|
||||
sprintf(partial_recv,"0");
|
||||
|
||||
if (sscanf(buf, "%s\t%ld\t%s", uidl, &recv_time, &partial_recv) < 2) {
|
||||
if (sscanf(buf, "%s", uidl) != 1)
|
||||
continue;
|
||||
else {
|
||||
recv_time = now;
|
||||
}
|
||||
}
|
||||
if (strcmp(muidl, uidl)) {
|
||||
fprintf(fpnew, "%s\t%ld\t%s\n", uidl, recv_time, partial_recv);
|
||||
} else {
|
||||
fprintf(fpnew, "%s\t%ld\t%s\n", uidl, recv_time, filename);
|
||||
}
|
||||
}
|
||||
fclose(fpnew);
|
||||
fclose(fp);
|
||||
|
||||
unlink(path);
|
||||
rename(pathnew, path);
|
||||
|
||||
g_free(path);
|
||||
g_free(pathnew);
|
||||
|
||||
if ((fp = fopen(filename,"rb")) == NULL) {
|
||||
perror("fopen3");
|
||||
return -1;
|
||||
}
|
||||
pathnew = g_strdup_printf("%s.new", filename);
|
||||
if ((fpnew = fopen(pathnew, "wb")) == NULL) {
|
||||
perror("fopen4");
|
||||
fclose(fp);
|
||||
g_free(pathnew);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(fpnew, "SC-Marked-For-Download: 1\n");
|
||||
while ((len = fread(buf, sizeof(gchar), sizeof(buf), fp)) > 0) {
|
||||
fprintf(fpnew, "%s", buf);
|
||||
}
|
||||
fclose(fpnew);
|
||||
fclose(fp);
|
||||
unlink(filename);
|
||||
rename(pathnew, filename);
|
||||
|
||||
g_free(pathnew);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint pop3_write_uidl_list(Pop3Session *session)
|
||||
{
|
||||
gchar *path;
|
||||
|
@ -521,8 +772,9 @@ gint pop3_write_uidl_list(Pop3Session *session)
|
|||
|
||||
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 (msg->uidl && msg->received && !msg->deleted) {
|
||||
fprintf(fp, "%s\t%ld\t%d\n", msg->uidl, msg->recv_time, msg->partial_recv);
|
||||
}
|
||||
}
|
||||
|
||||
if (fclose(fp) == EOF) FILE_OP_ERROR(path, "fclose");
|
||||
|
@ -532,7 +784,7 @@ gint pop3_write_uidl_list(Pop3Session *session)
|
|||
}
|
||||
|
||||
static gint pop3_write_msg_to_file(const gchar *file, const gchar *data,
|
||||
guint len)
|
||||
guint len, const gchar *prefix)
|
||||
{
|
||||
FILE *fp;
|
||||
const gchar *prev, *cur;
|
||||
|
@ -547,6 +799,11 @@ static gint pop3_write_msg_to_file(const gchar *file, const gchar *data,
|
|||
if (change_file_mode_rw(fp, file) < 0)
|
||||
FILE_OP_ERROR(file, "chmod");
|
||||
|
||||
if (prefix != NULL) {
|
||||
fprintf(fp, prefix);
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
/* +------------------+----------------+--------------------------+ *
|
||||
* ^data ^prev ^cur data+len-1^ */
|
||||
|
||||
|
@ -632,11 +889,19 @@ static Pop3State pop3_lookup_next(Pop3Session *session)
|
|||
return POP3_DELETE;
|
||||
}
|
||||
|
||||
if (size_limit_over)
|
||||
if (size_limit_over) {
|
||||
log_message
|
||||
(_("POP3: Skipping message %d (%d bytes)\n"),
|
||||
session->cur_msg, size);
|
||||
|
||||
if (!msg->received && msg->partial_recv != 2) {
|
||||
pop3_top_send(session);
|
||||
return POP3_TOP;
|
||||
} else if (msg->partial_recv == 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (size == 0 || msg->received || size_limit_over) {
|
||||
session->cur_total_bytes += size;
|
||||
if (session->cur_msg == session->count) {
|
||||
|
@ -799,6 +1064,10 @@ static gint pop3_session_recv_msg(Session *session, const gchar *msg)
|
|||
pop3_session->state = POP3_RETR_RECV;
|
||||
session_recv_data(session, 0, ".\r\n");
|
||||
break;
|
||||
case POP3_TOP:
|
||||
pop3_session->state = POP3_TOP_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)
|
||||
|
@ -862,6 +1131,18 @@ static gint pop3_session_recv_data_finished(Session *session, guchar *data,
|
|||
return -1;
|
||||
}
|
||||
break;
|
||||
case POP3_TOP_RECV:
|
||||
if (pop3_top_recv(pop3_session, data, len) < 0)
|
||||
return -1;
|
||||
|
||||
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;
|
||||
|
|
16
src/pop.h
16
src/pop.h
|
@ -60,6 +60,8 @@ typedef enum {
|
|||
POP3_GETSIZE_LIST_RECV,
|
||||
POP3_RETR,
|
||||
POP3_RETR_RECV,
|
||||
POP3_TOP,
|
||||
POP3_TOP_RECV,
|
||||
POP3_DELETE,
|
||||
POP3_LOGOUT,
|
||||
POP3_ERROR,
|
||||
|
@ -101,8 +103,9 @@ struct _Pop3MsgInfo
|
|||
gint size;
|
||||
gchar *uidl;
|
||||
time_t recv_time;
|
||||
guint received : 1;
|
||||
guint deleted : 1;
|
||||
guint received : 1;
|
||||
guint deleted : 1;
|
||||
guint partial_recv : 2;
|
||||
};
|
||||
|
||||
struct _Pop3Session
|
||||
|
@ -128,7 +131,8 @@ struct _Pop3Session
|
|||
Pop3MsgInfo *msg;
|
||||
|
||||
GHashTable *uidl_table;
|
||||
|
||||
GHashTable *partial_recv_table;
|
||||
|
||||
gboolean new_msg_exist;
|
||||
gboolean uidl_is_valid;
|
||||
|
||||
|
@ -141,7 +145,8 @@ struct _Pop3Session
|
|||
|
||||
/* virtual method to drop message */
|
||||
gint (*drop_message) (Pop3Session *session,
|
||||
const gchar *file);
|
||||
const gchar *file,
|
||||
gboolean update_file);
|
||||
};
|
||||
|
||||
#define POPBUFSIZE 512
|
||||
|
@ -149,7 +154,8 @@ struct _Pop3Session
|
|||
|
||||
|
||||
Session *pop3_session_new (PrefsAccount *account);
|
||||
GHashTable *pop3_get_uidl_table (PrefsAccount *account);
|
||||
GHashTable *pop3_get_uidl_table (PrefsAccount *account, Pop3Session *session);
|
||||
gint pop3_write_uidl_list (Pop3Session *session);
|
||||
int pop3_mark_for_download(const gchar *server, const gchar *login, const gchar *uidl, const gchar *filename);
|
||||
|
||||
#endif /* __POP_H__ */
|
||||
|
|
|
@ -502,7 +502,12 @@ enum
|
|||
H_FROM_SPACE = 13,
|
||||
H_X_FACE = 14,
|
||||
H_DISPOSITION_NOTIFICATION_TO = 15,
|
||||
H_RETURN_RECEIPT_TO = 16
|
||||
H_RETURN_RECEIPT_TO = 16,
|
||||
H_SC_PARTIALLY_RETRIEVED = 17,
|
||||
H_SC_ACCOUNT_SERVER = 18,
|
||||
H_SC_ACCOUNT_LOGIN = 19,
|
||||
H_SC_MESSAGE_SIZE = 20,
|
||||
H_SC_PLANNED_DOWNLOAD = 21
|
||||
};
|
||||
|
||||
static HeaderEntry hentry_full[] = {{"Date:", NULL, FALSE},
|
||||
|
@ -522,6 +527,11 @@ static HeaderEntry hentry_full[] = {{"Date:", NULL, FALSE},
|
|||
{"X-Face:", NULL, FALSE},
|
||||
{"Disposition-Notification-To:", NULL, FALSE},
|
||||
{"Return-Receipt-To:", NULL, FALSE},
|
||||
{"SC-Partially-Retrieved:", NULL, FALSE},
|
||||
{"SC-Account-Server:", NULL, FALSE},
|
||||
{"SC-Account-Login:",NULL, FALSE},
|
||||
{"SC-Message-Size:", NULL, FALSE},
|
||||
{"SC-Marked-For-Download:", NULL, FALSE},
|
||||
{NULL, NULL, FALSE}};
|
||||
|
||||
static HeaderEntry hentry_short[] = {{"Date:", NULL, FALSE},
|
||||
|
@ -676,6 +686,26 @@ static MsgInfo *parse_stream(void *data, gboolean isstring, MsgFlags flags,
|
|||
if (msginfo->returnreceiptto) break;
|
||||
msginfo->returnreceiptto = g_strdup(hp);
|
||||
break;
|
||||
case H_SC_PARTIALLY_RETRIEVED:
|
||||
if (msginfo->partial_recv) break;
|
||||
msginfo->partial_recv = g_strdup(hp);
|
||||
break;
|
||||
case H_SC_ACCOUNT_SERVER:
|
||||
if (msginfo->account_server) break;
|
||||
msginfo->account_server = g_strdup(hp);
|
||||
break;
|
||||
case H_SC_ACCOUNT_LOGIN:
|
||||
if (msginfo->account_login) break;
|
||||
msginfo->account_login = g_strdup(hp);
|
||||
break;
|
||||
case H_SC_MESSAGE_SIZE:
|
||||
if (msginfo->total_size) break;
|
||||
msginfo->total_size = atoi(hp);
|
||||
break;
|
||||
case H_SC_PLANNED_DOWNLOAD:
|
||||
if (msginfo->planned_download) break;
|
||||
msginfo->planned_download = atoi(hp);
|
||||
break;
|
||||
#ifdef ALLOW_HEADER_HINT
|
||||
case H_STATUS:
|
||||
if (strchr(hp, 'R') != NULL)
|
||||
|
|
|
@ -895,6 +895,17 @@ MsgInfo *procmsg_msginfo_get_full_info(MsgInfo *msginfo)
|
|||
if (!msginfo->returnreceiptto)
|
||||
msginfo->returnreceiptto = g_strdup
|
||||
(full_msginfo->returnreceiptto);
|
||||
if (!msginfo->partial_recv && full_msginfo->partial_recv)
|
||||
msginfo->partial_recv = g_strdup
|
||||
(full_msginfo->partial_recv);
|
||||
msginfo->total_size = full_msginfo->total_size;
|
||||
if (!msginfo->account_server && full_msginfo->account_server)
|
||||
msginfo->account_server = g_strdup
|
||||
(full_msginfo->account_server);
|
||||
if (!msginfo->account_login && full_msginfo->account_login)
|
||||
msginfo->account_login = g_strdup
|
||||
(full_msginfo->account_login);
|
||||
msginfo->planned_download = full_msginfo->planned_download;
|
||||
procmsg_msginfo_free(full_msginfo);
|
||||
|
||||
return procmsg_msginfo_new_ref(msginfo);
|
||||
|
|
|
@ -206,6 +206,13 @@ struct _MsgInfo
|
|||
guint decryption_failed : 1;
|
||||
|
||||
gint hidden;
|
||||
|
||||
/* used only for partially received messages */
|
||||
gchar *partial_recv;
|
||||
gint total_size;
|
||||
gchar *account_server;
|
||||
gchar *account_login;
|
||||
gint planned_download;
|
||||
};
|
||||
|
||||
struct _MsgFileInfo
|
||||
|
|
Loading…
Reference in a new issue