From f83afc56908b487f1d0d87d563eabf68c01b411c Mon Sep 17 00:00:00 2001 From: hiro Date: Tue, 22 Nov 2005 07:21:07 +0000 Subject: reduced memory usage on SMTP session. git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@771 ee746299-78ed-0310-b773-934348b2243d --- libsylph/session.c | 54 ++++++++++++++++++++++++++++-------------------- libsylph/session.h | 6 +++--- libsylph/smtp.c | 7 ++++--- libsylph/smtp.h | 4 ++-- libsylph/utils.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ libsylph/utils.h | 1 + 6 files changed, 102 insertions(+), 30 deletions(-) (limited to 'libsylph') diff --git a/libsylph/session.c b/libsylph/session.c index 2560c014..7fcc744c 100644 --- a/libsylph/session.c +++ b/libsylph/session.c @@ -87,8 +87,8 @@ void session_init(Session *session) session->write_buf_p = NULL; session->write_buf_len = 0; - session->write_data = NULL; - session->write_data_p = NULL; + session->write_data_fp = NULL; + session->write_data_pos = 0; session->write_data_len = 0; session->timeout_tag = 0; @@ -377,18 +377,18 @@ static gboolean session_recv_msg_idle_cb(gpointer data) return FALSE; } -gint session_send_data(Session *session, const guchar *data, guint size) +gint session_send_data(Session *session, FILE *data_fp, guint size) { gboolean ret; - g_return_val_if_fail(session->write_data == NULL, -1); - g_return_val_if_fail(data != NULL, -1); + g_return_val_if_fail(session->write_data_fp == NULL, -1); + g_return_val_if_fail(data_fp != NULL, -1); g_return_val_if_fail(size != 0, -1); session->state = SESSION_SEND; - session->write_data = data; - session->write_data_p = session->write_data; + session->write_data_fp = data_fp; + session->write_data_pos = 0; session->write_data_len = size; g_get_current_time(&session->tv_prev); @@ -673,19 +673,23 @@ static gint session_write_buf(Session *session) static gint session_write_data(Session *session) { + gchar buf[SESSION_BUFFSIZE]; gint write_len; gint to_write_len; - g_return_val_if_fail(session->write_data != NULL, -1); - g_return_val_if_fail(session->write_data_p != NULL, -1); + g_return_val_if_fail(session->write_data_fp != NULL, -1); + g_return_val_if_fail(session->write_data_pos >= 0, -1); g_return_val_if_fail(session->write_data_len > 0, -1); - to_write_len = session->write_data_len - - (session->write_data_p - session->write_data); + to_write_len = session->write_data_len - session->write_data_pos; to_write_len = MIN(to_write_len, SESSION_BUFFSIZE); + if (fread(buf, to_write_len, 1, session->write_data_fp) < 1) { + g_warning("session_write_data: reading data from file failed\n"); + session->state = SESSION_ERROR; + return -1; + } - write_len = sock_write(session->sock, (gchar *)session->write_data_p, - to_write_len); + write_len = sock_write(session->sock, buf, to_write_len); if (write_len < 0) { switch (errno) { @@ -700,14 +704,21 @@ static gint session_write_data(Session *session) } /* incomplete write */ - if (session->write_data_p - session->write_data + write_len < - session->write_data_len) { - session->write_data_p += write_len; + if (session->write_data_pos + write_len < session->write_data_len) { + session->write_data_pos += write_len; + if (write_len < to_write_len) { + if (fseek(session->write_data_fp, + session->write_data_pos, SEEK_SET) < 0) { + g_warning("session_write_data: file seek failed\n"); + session->state = SESSION_ERROR; + return -1; + } + } return 1; } - session->write_data = NULL; - session->write_data_p = NULL; + session->write_data_fp = NULL; + session->write_data_pos = 0; session->write_data_len = 0; return 0; @@ -750,8 +761,8 @@ static gboolean session_write_data_cb(SockInfo *source, gint ret; g_return_val_if_fail(condition == G_IO_OUT, FALSE); - g_return_val_if_fail(session->write_data != NULL, FALSE); - g_return_val_if_fail(session->write_data_p != NULL, FALSE); + g_return_val_if_fail(session->write_data_fp != NULL, FALSE); + g_return_val_if_fail(session->write_data_pos >= 0, FALSE); g_return_val_if_fail(session->write_data_len > 0, FALSE); write_data_len = session->write_data_len; @@ -771,8 +782,7 @@ static gboolean session_write_data_cb(SockInfo *source, session_set_timeout(session, session->timeout_interval); session->send_data_progressive_notify (session, - session->write_data_p - session->write_data, - write_data_len, + session->write_data_pos, write_data_len, session->send_data_progressive_notify_data); g_get_current_time(&session->tv_prev); } diff --git a/libsylph/session.h b/libsylph/session.h index b1239624..988349d7 100644 --- a/libsylph/session.h +++ b/libsylph/session.h @@ -121,8 +121,8 @@ struct _Session gint write_buf_len; /* buffer for large data */ - const guchar *write_data; - const guchar *write_data_p; + FILE *write_data_fp; + gint write_data_pos; gint write_data_len; guint timeout_tag; @@ -196,7 +196,7 @@ gint session_send_msg (Session *session, const gchar *msg); gint session_recv_msg (Session *session); gint session_send_data (Session *session, - const guchar *data, + FILE *data_fp, guint size); gint session_recv_data (Session *session, guint size, diff --git a/libsylph/smtp.c b/libsylph/smtp.c index 896547b5..2ee725ee 100644 --- a/libsylph/smtp.c +++ b/libsylph/smtp.c @@ -87,7 +87,7 @@ Session *smtp_session_new(void) session->to_list = NULL; session->cur_to = NULL; - session->send_data = NULL; + session->send_data_fp = NULL; session->send_data_len = 0; session->avail_auth_type = 0; @@ -109,7 +109,8 @@ static void smtp_session_destroy(Session *session) g_free(smtp_session->pass); g_free(smtp_session->from); - g_free(smtp_session->send_data); + if (smtp_session->send_data_fp) + fclose(smtp_session->send_data_fp); g_free(smtp_session->error_msg); } @@ -418,7 +419,7 @@ static gint smtp_send_data(SMTPSession *session) { session->state = SMTP_SEND_DATA; - session_send_data(SESSION(session), session->send_data, + session_send_data(SESSION(session), session->send_data_fp, session->send_data_len); return SM_OK; diff --git a/libsylph/smtp.h b/libsylph/smtp.h index 554d4f04..4bb10b6e 100644 --- a/libsylph/smtp.h +++ b/libsylph/smtp.h @@ -101,8 +101,8 @@ struct _SMTPSession GSList *to_list; GSList *cur_to; - guchar *send_data; - guint send_data_len; + FILE *send_data_fp; + gint send_data_len; SMTPAuthType avail_auth_type; SMTPAuthType forced_auth_type; diff --git a/libsylph/utils.c b/libsylph/utils.c index 2d441163..8f531967 100644 --- a/libsylph/utils.c +++ b/libsylph/utils.c @@ -2757,6 +2757,66 @@ gchar *normalize_newlines(const gchar *str) return out; } +FILE *get_outgoing_rfc2822_file(FILE *fp) +{ + gchar buf[BUFFSIZE]; + FILE *outfp; + + outfp = my_tmpfile(); + if (!outfp) { + FILE_OP_ERROR("get_outgoing_rfc2822_file", "my_tmpfile"); + return NULL; + } + + /* output header part */ + while (fgets(buf, sizeof(buf), fp) != NULL) { + strretchomp(buf); + if (!g_ascii_strncasecmp(buf, "Bcc:", 4)) { + gint next; + + for (;;) { + next = fgetc(fp); + if (next == EOF) + break; + else if (next != ' ' && next != '\t') { + ungetc(next, fp); + break; + } + if (fgets(buf, sizeof(buf), fp) == NULL) + break; + } + } else { + if (fputs(buf, outfp) == EOF) + goto file_error; + if (fputs("\r\n", outfp) == EOF) + goto file_error; + if (buf[0] == '\0') + break; + } + } + + /* output body part */ + while (fgets(buf, sizeof(buf), fp) != NULL) { + strretchomp(buf); + if (buf[0] == '.') { + if (fputc('.', outfp) == EOF) + goto file_error; + } + if (fputs(buf, outfp) == EOF) + goto file_error; + if (fputs("\r\n", outfp) == EOF) + goto file_error; + } + + rewind(outfp); + return outfp; + +file_error: + g_warning("get_outgoing_rfc2822_file(): writing to temporary file failed.\n"); + fclose(outfp); + return NULL; +} + gchar *get_outgoing_rfc2822_str(FILE *fp) { gchar buf[BUFFSIZE]; diff --git a/libsylph/utils.h b/libsylph/utils.h index b5cb3a76..48d9e507 100644 --- a/libsylph/utils.h +++ b/libsylph/utils.h @@ -421,6 +421,7 @@ gint uncanonicalize_file_replace(const gchar *file); gchar *normalize_newlines (const gchar *str); +FILE *get_outgoing_rfc2822_file (FILE *fp); gchar *get_outgoing_rfc2822_str (FILE *fp); gchar *generate_mime_boundary (const gchar *prefix); -- cgit v1.2.3