aboutsummaryrefslogtreecommitdiff
path: root/libsylph
diff options
context:
space:
mode:
authorhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-11-22 07:21:07 +0000
committerhiro <hiro@ee746299-78ed-0310-b773-934348b2243d>2005-11-22 07:21:07 +0000
commitf83afc56908b487f1d0d87d563eabf68c01b411c (patch)
treea7614bea8301779382a5c52eb15ad988191c1356 /libsylph
parent6e181791b71430f018d8a78fd943b825349f1128 (diff)
reduced memory usage on SMTP session.
git-svn-id: svn://sylpheed.sraoss.jp/sylpheed/trunk@771 ee746299-78ed-0310-b773-934348b2243d
Diffstat (limited to 'libsylph')
-rw-r--r--libsylph/session.c54
-rw-r--r--libsylph/session.h6
-rw-r--r--libsylph/smtp.c7
-rw-r--r--libsylph/smtp.h4
-rw-r--r--libsylph/utils.c60
-rw-r--r--libsylph/utils.h1
6 files changed, 102 insertions, 30 deletions
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);