diff options
author | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-11-22 07:21:07 +0000 |
---|---|---|
committer | hiro <hiro@ee746299-78ed-0310-b773-934348b2243d> | 2005-11-22 07:21:07 +0000 |
commit | f83afc56908b487f1d0d87d563eabf68c01b411c (patch) | |
tree | a7614bea8301779382a5c52eb15ad988191c1356 | |
parent | 6e181791b71430f018d8a78fd943b825349f1128 (diff) |
reduced memory usage on SMTP session.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@771 ee746299-78ed-0310-b773-934348b2243d
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | ChangeLog.ja | 8 | ||||
-rw-r--r-- | libsylph/session.c | 54 | ||||
-rw-r--r-- | libsylph/session.h | 6 | ||||
-rw-r--r-- | libsylph/smtp.c | 7 | ||||
-rw-r--r-- | libsylph/smtp.h | 4 | ||||
-rw-r--r-- | libsylph/utils.c | 60 | ||||
-rw-r--r-- | libsylph/utils.h | 1 | ||||
-rw-r--r-- | src/send_message.c | 16 |
9 files changed, 129 insertions, 34 deletions
@@ -1,5 +1,12 @@ 2005-11-22 + * libsylph/utils.[ch] + libsylph/session.[ch] + libsylph/smtp.[ch] + src/send_message.c: reduced memory usage on SMTP session. + +2005-11-22 + * libsylph/imap.c: QUOTE_IF_REQUIRED(): add "[]&" to characters to be quoted (for courier-imap). diff --git a/ChangeLog.ja b/ChangeLog.ja index 6ecdfc37..ac4e09ea 100644 --- a/ChangeLog.ja +++ b/ChangeLog.ja @@ -1,5 +1,13 @@ 2005-11-22 + * libsylph/utils.[ch] + libsylph/session.[ch] + libsylph/smtp.[ch] + src/send_message.c: SMTP セッションでのメモリ消費量を削減。 + + +2005-11-22 + * libsylph/imap.c: QUOTE_IF_REQUIRED(): "[]&" をクオートする文字に 追加(courier-imap 対策)。 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); diff --git a/src/send_message.c b/src/send_message.c index 8072622a..ab67e90a 100644 --- a/src/send_message.c +++ b/src/send_message.c @@ -451,7 +451,7 @@ static gint send_message_smtp(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp) { Session *session; SMTPSession *smtp_session; - gchar *out_str; + FILE *out_fp; gushort port; SendProgressDialog *dialog; gchar buf[BUFFSIZE]; @@ -517,9 +517,17 @@ static gint send_message_smtp(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp) smtp_session->to_list = to_list; smtp_session->cur_to = to_list; - out_str = get_outgoing_rfc2822_str(fp); - smtp_session->send_data = (guchar *)out_str; - smtp_session->send_data_len = strlen(out_str); + out_fp = get_outgoing_rfc2822_file(fp); + if (!out_fp) { + session_destroy(session); + return -1; + } + smtp_session->send_data_fp = out_fp; + smtp_session->send_data_len = get_left_file_size(out_fp); + if (smtp_session->send_data_len < 0) { + session_destroy(session); + return -1; + } #if USE_SSL port = ac_prefs->set_smtpport ? ac_prefs->smtpport : |