Statistics
| Revision:

root / src / send_message.c @ 424

History | View | Annotate | Download (16.8 kB)

1 1 hiro
/*
2 1 hiro
 * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3 321 hiro
 * Copyright (C) 1999-2005 Hiroyuki Yamamoto
4 1 hiro
 *
5 1 hiro
 * This program is free software; you can redistribute it and/or modify
6 1 hiro
 * it under the terms of the GNU General Public License as published by
7 1 hiro
 * the Free Software Foundation; either version 2 of the License, or
8 1 hiro
 * (at your option) any later version.
9 1 hiro
 *
10 1 hiro
 * This program is distributed in the hope that it will be useful,
11 1 hiro
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 1 hiro
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 1 hiro
 * GNU General Public License for more details.
14 1 hiro
 *
15 1 hiro
 * You should have received a copy of the GNU General Public License
16 1 hiro
 * along with this program; if not, write to the Free Software
17 1 hiro
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 1 hiro
 */
19 1 hiro
20 1 hiro
#ifdef HAVE_CONFIG_H
21 1 hiro
#  include "config.h"
22 1 hiro
#endif
23 1 hiro
24 1 hiro
#include "defs.h"
25 1 hiro
26 1 hiro
#include <glib.h>
27 92 hiro
#include <glib/gi18n.h>
28 1 hiro
#include <gtk/gtkmain.h>
29 1 hiro
#include <gtk/gtksignal.h>
30 1 hiro
#include <gtk/gtkwindow.h>
31 1 hiro
#include <stdio.h>
32 1 hiro
#include <string.h>
33 347 hiro
#include <sys/types.h>
34 347 hiro
#include <sys/wait.h>
35 1 hiro
36 1 hiro
#include "send_message.h"
37 1 hiro
#include "session.h"
38 1 hiro
#include "ssl.h"
39 1 hiro
#include "smtp.h"
40 1 hiro
#include "news.h"
41 1 hiro
#include "prefs_common.h"
42 1 hiro
#include "prefs_account.h"
43 1 hiro
#include "procheader.h"
44 1 hiro
#include "account.h"
45 1 hiro
#include "progressdialog.h"
46 1 hiro
#include "statusbar.h"
47 1 hiro
#include "inputdialog.h"
48 1 hiro
#include "alertpanel.h"
49 1 hiro
#include "manage_window.h"
50 288 hiro
#include "socket.h"
51 1 hiro
#include "utils.h"
52 1 hiro
53 1 hiro
#define SMTP_PORT        25
54 1 hiro
#if USE_SSL
55 1 hiro
#define SSMTP_PORT        465
56 1 hiro
#endif
57 1 hiro
58 1 hiro
typedef struct _SendProgressDialog        SendProgressDialog;
59 1 hiro
60 1 hiro
struct _SendProgressDialog
61 1 hiro
{
62 1 hiro
        ProgressDialog *dialog;
63 1 hiro
        Session *session;
64 1 hiro
        gboolean cancelled;
65 1 hiro
};
66 1 hiro
67 1 hiro
static gint send_message_local                (const gchar                *command,
68 1 hiro
                                         FILE                        *fp);
69 1 hiro
static gint send_message_smtp                (PrefsAccount                *ac_prefs,
70 1 hiro
                                         GSList                        *to_list,
71 1 hiro
                                         FILE                        *fp);
72 1 hiro
73 1 hiro
static gint send_recv_message                (Session                *session,
74 1 hiro
                                         const gchar                *msg,
75 1 hiro
                                         gpointer                 data);
76 1 hiro
static gint send_send_data_progressive        (Session                *session,
77 1 hiro
                                         guint                         cur_len,
78 1 hiro
                                         guint                         total_len,
79 1 hiro
                                         gpointer                 data);
80 1 hiro
static gint send_send_data_finished        (Session                *session,
81 1 hiro
                                         guint                         len,
82 1 hiro
                                         gpointer                 data);
83 1 hiro
84 1 hiro
static SendProgressDialog *send_progress_dialog_create(void);
85 1 hiro
static void send_progress_dialog_destroy(SendProgressDialog *dialog);
86 1 hiro
87 1 hiro
static void send_cancel_button_cb        (GtkWidget        *widget,
88 1 hiro
                                         gpointer         data);
89 1 hiro
90 1 hiro
static void send_put_error                (Session        *session);
91 1 hiro
92 1 hiro
93 1 hiro
gint send_message(const gchar *file, PrefsAccount *ac_prefs, GSList *to_list)
94 1 hiro
{
95 1 hiro
        FILE *fp;
96 1 hiro
        gint val;
97 1 hiro
98 1 hiro
        g_return_val_if_fail(file != NULL, -1);
99 1 hiro
        g_return_val_if_fail(ac_prefs != NULL, -1);
100 1 hiro
        g_return_val_if_fail(to_list != NULL, -1);
101 1 hiro
102 1 hiro
        if ((fp = fopen(file, "rb")) == NULL) {
103 1 hiro
                FILE_OP_ERROR(file, "fopen");
104 1 hiro
                return -1;
105 1 hiro
        }
106 1 hiro
107 1 hiro
        if (prefs_common.use_extsend && prefs_common.extsend_cmd) {
108 1 hiro
                val = send_message_local(prefs_common.extsend_cmd, fp);
109 1 hiro
                fclose(fp);
110 1 hiro
                return val;
111 1 hiro
        }
112 1 hiro
113 1 hiro
        val = send_message_smtp(ac_prefs, to_list, fp);
114 1 hiro
115 1 hiro
        fclose(fp);
116 1 hiro
        return val;
117 1 hiro
}
118 1 hiro
119 1 hiro
enum
120 1 hiro
{
121 1 hiro
        Q_SENDER     = 0,
122 1 hiro
        Q_SMTPSERVER = 1,
123 1 hiro
        Q_RECIPIENTS = 2,
124 1 hiro
        Q_ACCOUNT_ID = 3
125 1 hiro
};
126 1 hiro
127 1 hiro
QueueInfo *send_get_queue_info(const gchar *file)
128 1 hiro
{
129 1 hiro
        static HeaderEntry qentry[] = {{"S:",   NULL, FALSE},
130 1 hiro
                                       {"SSV:", NULL, FALSE},
131 1 hiro
                                       {"R:",   NULL, FALSE},
132 1 hiro
                                       {"AID:", NULL, FALSE},
133 1 hiro
                                       {NULL,   NULL, FALSE}};
134 1 hiro
        FILE *fp;
135 1 hiro
        gchar buf[BUFFSIZE];
136 1 hiro
        gint hnum;
137 1 hiro
        QueueInfo *qinfo;
138 1 hiro
139 1 hiro
        g_return_val_if_fail(file != NULL, NULL);
140 1 hiro
141 1 hiro
        if ((fp = fopen(file, "rb")) == NULL) {
142 1 hiro
                FILE_OP_ERROR(file, "fopen");
143 1 hiro
                return NULL;
144 1 hiro
        }
145 1 hiro
146 1 hiro
        qinfo = g_new0(QueueInfo, 1);
147 1 hiro
148 1 hiro
        while ((hnum = procheader_get_one_field(buf, sizeof(buf), fp, qentry))
149 1 hiro
               != -1) {
150 1 hiro
                gchar *p;
151 1 hiro
152 1 hiro
                p = buf + strlen(qentry[hnum].name);
153 1 hiro
154 1 hiro
                switch (hnum) {
155 1 hiro
                case Q_SENDER:
156 1 hiro
                        if (!qinfo->from)
157 1 hiro
                                qinfo->from = g_strdup(p);
158 1 hiro
                        break;
159 1 hiro
                case Q_SMTPSERVER:
160 1 hiro
                        if (!qinfo->server)
161 1 hiro
                                qinfo->server = g_strdup(p);
162 1 hiro
                        break;
163 1 hiro
                case Q_RECIPIENTS:
164 1 hiro
                        qinfo->to_list =
165 1 hiro
                                address_list_append(qinfo->to_list, p);
166 1 hiro
                        break;
167 1 hiro
                case Q_ACCOUNT_ID:
168 1 hiro
                        qinfo->ac = account_find_from_id(atoi(p));
169 1 hiro
                        break;
170 1 hiro
                default:
171 1 hiro
                        break;
172 1 hiro
                }
173 1 hiro
        }
174 1 hiro
175 1 hiro
        qinfo->fp = fp;
176 1 hiro
177 1 hiro
        if (((!qinfo->ac || (qinfo->ac && qinfo->ac->protocol != A_NNTP)) &&
178 1 hiro
             !qinfo->to_list) || !qinfo->from) {
179 1 hiro
                g_warning(_("Queued message header is broken.\n"));
180 1 hiro
                send_queue_info_free(qinfo);
181 1 hiro
                return NULL;
182 1 hiro
        }
183 1 hiro
184 1 hiro
        if (!qinfo->ac) {
185 1 hiro
                qinfo->ac = account_find_from_smtp_server(qinfo->from,
186 1 hiro
                                                          qinfo->server);
187 1 hiro
                if (!qinfo->ac) {
188 1 hiro
                        g_warning("Account not found. "
189 1 hiro
                                  "Using current account...\n");
190 1 hiro
                        qinfo->ac = cur_account;
191 1 hiro
                }
192 1 hiro
        }
193 1 hiro
194 1 hiro
        return qinfo;
195 1 hiro
}
196 1 hiro
197 317 hiro
gint send_get_queue_contents(QueueInfo *qinfo, const gchar *dest)
198 317 hiro
{
199 317 hiro
        FILE *fp;
200 317 hiro
        glong pos;
201 317 hiro
        gchar buf[BUFFSIZE];
202 317 hiro
203 317 hiro
        g_return_val_if_fail(qinfo != NULL, -1);
204 317 hiro
        g_return_val_if_fail(qinfo->fp != NULL, -1);
205 317 hiro
        g_return_val_if_fail(dest != NULL, -1);
206 317 hiro
207 317 hiro
        if ((fp = fopen(dest, "wb")) == NULL) {
208 317 hiro
                FILE_OP_ERROR(dest, "fopen");
209 317 hiro
                return -1;
210 317 hiro
        }
211 317 hiro
212 317 hiro
        pos = ftell(qinfo->fp);
213 317 hiro
214 317 hiro
        while (fgets(buf, sizeof(buf), qinfo->fp) != NULL)
215 317 hiro
                fputs(buf, fp);
216 317 hiro
217 317 hiro
        if (fclose(fp) < 0) {
218 317 hiro
                FILE_OP_ERROR(dest, "fclose");
219 317 hiro
                unlink(dest);
220 317 hiro
                return -1;
221 317 hiro
        }
222 317 hiro
223 317 hiro
        fseek(qinfo->fp, pos, SEEK_SET);
224 317 hiro
225 317 hiro
        return 0;
226 317 hiro
}
227 317 hiro
228 1 hiro
void send_queue_info_free(QueueInfo *qinfo)
229 1 hiro
{
230 1 hiro
        if (qinfo == NULL) return;
231 1 hiro
232 1 hiro
        slist_free_strings(qinfo->to_list);
233 1 hiro
        g_slist_free(qinfo->to_list);
234 1 hiro
        g_free(qinfo->from);
235 1 hiro
        g_free(qinfo->server);
236 1 hiro
        if (qinfo->fp)
237 1 hiro
                fclose(qinfo->fp);
238 1 hiro
        g_free(qinfo);
239 1 hiro
}
240 1 hiro
241 1 hiro
gint send_message_queue(QueueInfo *qinfo)
242 1 hiro
{
243 1 hiro
        gint val = 0;
244 1 hiro
        glong fpos;
245 1 hiro
        PrefsAccount *mailac = NULL, *newsac = NULL;
246 1 hiro
247 1 hiro
        g_return_val_if_fail(qinfo != NULL, -1);
248 1 hiro
249 317 hiro
        fpos = ftell(qinfo->fp);
250 317 hiro
251 1 hiro
        if (prefs_common.use_extsend && prefs_common.extsend_cmd) {
252 1 hiro
                val = send_message_local(prefs_common.extsend_cmd, qinfo->fp);
253 1 hiro
        } else {
254 1 hiro
                if (qinfo->ac && qinfo->ac->protocol == A_NNTP) {
255 1 hiro
                        newsac = qinfo->ac;
256 1 hiro
257 1 hiro
                        /* search mail account */
258 1 hiro
                        mailac = account_find_from_address(qinfo->from);
259 1 hiro
                        if (!mailac) {
260 1 hiro
                                if (cur_account &&
261 1 hiro
                                    cur_account->protocol != A_NNTP)
262 1 hiro
                                        mailac = cur_account;
263 1 hiro
                                else {
264 1 hiro
                                        mailac = account_get_default();
265 1 hiro
                                        if (mailac->protocol == A_NNTP)
266 1 hiro
                                                mailac = NULL;
267 1 hiro
                                }
268 1 hiro
                        }
269 1 hiro
                } else
270 1 hiro
                        mailac = qinfo->ac;
271 1 hiro
272 1 hiro
                if (qinfo->to_list) {
273 1 hiro
                        if (mailac)
274 1 hiro
                                val = send_message_smtp(mailac, qinfo->to_list,
275 1 hiro
                                                        qinfo->fp);
276 1 hiro
                        else {
277 1 hiro
                                PrefsAccount tmp_ac;
278 1 hiro
279 1 hiro
                                g_warning("Account not found.\n");
280 1 hiro
281 1 hiro
                                memset(&tmp_ac, 0, sizeof(PrefsAccount));
282 1 hiro
                                tmp_ac.address = qinfo->from;
283 1 hiro
                                tmp_ac.smtp_server = qinfo->server;
284 1 hiro
                                tmp_ac.smtpport = SMTP_PORT;
285 1 hiro
                                val = send_message_smtp(&tmp_ac, qinfo->to_list,
286 1 hiro
                                                        qinfo->fp);
287 1 hiro
                        }
288 1 hiro
                }
289 1 hiro
290 1 hiro
                if (val == 0 && newsac) {
291 1 hiro
                        fseek(qinfo->fp, fpos, SEEK_SET);
292 1 hiro
                        val = news_post_stream(FOLDER(newsac->folder),
293 1 hiro
                                               qinfo->fp);
294 1 hiro
                        if (val < 0)
295 1 hiro
                                alertpanel_error(_("Error occurred while posting the message to %s ."),
296 1 hiro
                                                 newsac->nntp_server);
297 1 hiro
                }
298 1 hiro
        }
299 1 hiro
300 317 hiro
        fseek(qinfo->fp, fpos, SEEK_SET);
301 317 hiro
302 1 hiro
        return val;
303 1 hiro
}
304 1 hiro
305 1 hiro
static gint send_message_local(const gchar *command, FILE *fp)
306 1 hiro
{
307 288 hiro
        gchar **argv;
308 288 hiro
        GPid pid;
309 288 hiro
        gint child_stdin;
310 1 hiro
        gchar buf[BUFFSIZE];
311 288 hiro
        gboolean err = FALSE;
312 347 hiro
        gint status;
313 1 hiro
314 1 hiro
        g_return_val_if_fail(command != NULL, -1);
315 1 hiro
        g_return_val_if_fail(fp != NULL, -1);
316 1 hiro
317 288 hiro
        log_message(_("Sending message using command: %s\n"), command);
318 288 hiro
319 288 hiro
        argv = strsplit_with_quote(command, " ", 0);
320 288 hiro
321 347 hiro
        if (g_spawn_async_with_pipes(NULL, argv, NULL,
322 347 hiro
                                     G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
323 347 hiro
                                     &pid, &child_stdin, NULL, NULL,
324 347 hiro
                                     NULL) == FALSE) {
325 288 hiro
                g_snprintf(buf, sizeof(buf),
326 288 hiro
                           _("Can't execute command: %s"), command);
327 288 hiro
                log_warning("%s\n", buf);
328 288 hiro
                alertpanel_error("%s", buf);
329 288 hiro
                g_strfreev(argv);
330 1 hiro
                return -1;
331 1 hiro
        }
332 288 hiro
        g_strfreev(argv);
333 1 hiro
334 1 hiro
        while (fgets(buf, sizeof(buf), fp) != NULL) {
335 1 hiro
                strretchomp(buf);
336 288 hiro
                if (buf[0] == '.' && buf[1] == '\0') {
337 288 hiro
                        if (fd_write_all(child_stdin, ".", 1) < 0) {
338 288 hiro
                                err = TRUE;
339 288 hiro
                                break;
340 288 hiro
                        }
341 288 hiro
                }
342 288 hiro
                if (fd_write_all(child_stdin, buf, strlen(buf)) < 0 ||
343 288 hiro
                    fd_write_all(child_stdin, "\n", 1) < 0) {
344 288 hiro
                        err = TRUE;
345 288 hiro
                        break;
346 288 hiro
                }
347 1 hiro
        }
348 1 hiro
349 288 hiro
        fd_close(child_stdin);
350 347 hiro
351 347 hiro
        waitpid(pid, &status, 0);
352 347 hiro
        if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
353 347 hiro
                err = TRUE;
354 347 hiro
355 288 hiro
        g_spawn_close_pid(pid);
356 1 hiro
357 288 hiro
        if (err) {
358 288 hiro
                g_snprintf(buf, sizeof(buf),
359 288 hiro
                           _("Error occurred while executing command: %s"),
360 288 hiro
                           command);
361 288 hiro
                log_warning("%s\n", buf);
362 288 hiro
                alertpanel_error("%s", buf);
363 288 hiro
                return -1;
364 288 hiro
        }
365 288 hiro
366 1 hiro
        return 0;
367 1 hiro
}
368 1 hiro
369 1 hiro
static gint send_message_smtp(PrefsAccount *ac_prefs, GSList *to_list, FILE *fp)
370 1 hiro
{
371 1 hiro
        Session *session;
372 1 hiro
        SMTPSession *smtp_session;
373 1 hiro
        gushort port;
374 1 hiro
        SendProgressDialog *dialog;
375 1 hiro
        gchar buf[BUFFSIZE];
376 1 hiro
        gint ret = 0;
377 1 hiro
378 1 hiro
        g_return_val_if_fail(ac_prefs != NULL, -1);
379 1 hiro
        g_return_val_if_fail(ac_prefs->address != NULL, -1);
380 1 hiro
        g_return_val_if_fail(ac_prefs->smtp_server != NULL, -1);
381 1 hiro
        g_return_val_if_fail(to_list != NULL, -1);
382 1 hiro
        g_return_val_if_fail(fp != NULL, -1);
383 1 hiro
384 1 hiro
        session = smtp_session_new();
385 1 hiro
        smtp_session = SMTP_SESSION(session);
386 1 hiro
387 1 hiro
        smtp_session->hostname =
388 1 hiro
                ac_prefs->set_domain ? g_strdup(ac_prefs->domain) : NULL;
389 1 hiro
390 1 hiro
        if (ac_prefs->use_smtp_auth) {
391 1 hiro
                smtp_session->forced_auth_type = ac_prefs->smtp_auth_type;
392 1 hiro
393 1 hiro
                if (ac_prefs->smtp_userid) {
394 1 hiro
                        smtp_session->user = g_strdup(ac_prefs->smtp_userid);
395 1 hiro
                        if (ac_prefs->smtp_passwd)
396 1 hiro
                                smtp_session->pass =
397 1 hiro
                                        g_strdup(ac_prefs->smtp_passwd);
398 1 hiro
                        else if (ac_prefs->tmp_smtp_pass)
399 1 hiro
                                smtp_session->pass =
400 1 hiro
                                        g_strdup(ac_prefs->tmp_smtp_pass);
401 1 hiro
                        else {
402 1 hiro
                                smtp_session->pass =
403 1 hiro
                                        input_dialog_query_password
404 1 hiro
                                                (ac_prefs->smtp_server,
405 1 hiro
                                                 smtp_session->user);
406 1 hiro
                                if (!smtp_session->pass)
407 1 hiro
                                        smtp_session->pass = g_strdup("");
408 1 hiro
                                ac_prefs->tmp_smtp_pass =
409 1 hiro
                                        g_strdup(smtp_session->pass);
410 1 hiro
                        }
411 1 hiro
                } else {
412 1 hiro
                        smtp_session->user = g_strdup(ac_prefs->userid);
413 1 hiro
                        if (ac_prefs->passwd)
414 1 hiro
                                smtp_session->pass = g_strdup(ac_prefs->passwd);
415 1 hiro
                        else if (ac_prefs->tmp_pass)
416 1 hiro
                                smtp_session->pass =
417 1 hiro
                                        g_strdup(ac_prefs->tmp_pass);
418 1 hiro
                        else {
419 1 hiro
                                smtp_session->pass =
420 1 hiro
                                        input_dialog_query_password
421 1 hiro
                                                (ac_prefs->smtp_server,
422 1 hiro
                                                 smtp_session->user);
423 1 hiro
                                if (!smtp_session->pass)
424 1 hiro
                                        smtp_session->pass = g_strdup("");
425 1 hiro
                                ac_prefs->tmp_pass =
426 1 hiro
                                        g_strdup(smtp_session->pass);
427 1 hiro
                        }
428 1 hiro
                }
429 1 hiro
        } else {
430 1 hiro
                smtp_session->user = NULL;
431 1 hiro
                smtp_session->pass = NULL;
432 1 hiro
        }
433 1 hiro
434 1 hiro
        smtp_session->from = g_strdup(ac_prefs->address);
435 1 hiro
        smtp_session->to_list = to_list;
436 1 hiro
        smtp_session->cur_to = to_list;
437 1 hiro
        smtp_session->send_data = get_outgoing_rfc2822_str(fp);
438 1 hiro
        smtp_session->send_data_len = strlen(smtp_session->send_data);
439 1 hiro
440 1 hiro
#if USE_SSL
441 1 hiro
        port = ac_prefs->set_smtpport ? ac_prefs->smtpport :
442 1 hiro
                ac_prefs->ssl_smtp == SSL_TUNNEL ? SSMTP_PORT : SMTP_PORT;
443 1 hiro
        session->ssl_type = ac_prefs->ssl_smtp;
444 1 hiro
        if (ac_prefs->ssl_smtp != SSL_NONE)
445 1 hiro
                session->nonblocking = ac_prefs->use_nonblocking_ssl;
446 1 hiro
#else
447 1 hiro
        port = ac_prefs->set_smtpport ? ac_prefs->smtpport : SMTP_PORT;
448 1 hiro
#endif
449 1 hiro
450 1 hiro
        dialog = send_progress_dialog_create();
451 1 hiro
        dialog->session = session;
452 1 hiro
453 321 hiro
        progress_dialog_append(dialog->dialog, NULL, ac_prefs->smtp_server,
454 321 hiro
                               _("Connecting"), NULL);
455 1 hiro
456 1 hiro
        g_snprintf(buf, sizeof(buf), _("Connecting to SMTP server: %s ..."),
457 1 hiro
                   ac_prefs->smtp_server);
458 1 hiro
        progress_dialog_set_label(dialog->dialog, buf);
459 1 hiro
        log_message("%s\n", buf);
460 1 hiro
461 1 hiro
        session_set_recv_message_notify(session, send_recv_message, dialog);
462 1 hiro
        session_set_send_data_progressive_notify
463 1 hiro
                (session, send_send_data_progressive, dialog);
464 1 hiro
        session_set_send_data_notify(session, send_send_data_finished, dialog);
465 1 hiro
466 1 hiro
        if (session_connect(session, ac_prefs->smtp_server, port) < 0) {
467 1 hiro
                session_destroy(session);
468 1 hiro
                send_progress_dialog_destroy(dialog);
469 1 hiro
                return -1;
470 1 hiro
        }
471 1 hiro
472 1 hiro
        debug_print("send_message_smtp(): begin event loop\n");
473 1 hiro
474 1 hiro
        while (session_is_connected(session) && dialog->cancelled == FALSE)
475 1 hiro
                gtk_main_iteration();
476 1 hiro
477 1 hiro
        if (SMTP_SESSION(session)->error_val == SM_AUTHFAIL) {
478 1 hiro
                if (ac_prefs->smtp_userid && ac_prefs->tmp_smtp_pass) {
479 1 hiro
                        g_free(ac_prefs->tmp_smtp_pass);
480 1 hiro
                        ac_prefs->tmp_smtp_pass = NULL;
481 1 hiro
                }
482 1 hiro
                ret = -1;
483 201 hiro
        } else if (session->state == SESSION_EOF &&
484 201 hiro
                   SMTP_SESSION(session)->state == SMTP_QUIT) {
485 201 hiro
                /* consider EOF right after QUIT successful */
486 201 hiro
                log_warning("%s\n", _("Connection closed by the remote host."));
487 201 hiro
                ret = 0;
488 1 hiro
        } else if (session->state == SESSION_ERROR ||
489 1 hiro
                   session->state == SESSION_EOF ||
490 1 hiro
                   session->state == SESSION_TIMEOUT ||
491 1 hiro
                   SMTP_SESSION(session)->state == SMTP_ERROR ||
492 1 hiro
                   SMTP_SESSION(session)->error_val != SM_OK)
493 1 hiro
                ret = -1;
494 1 hiro
        else if (dialog->cancelled == TRUE)
495 1 hiro
                ret = -1;
496 1 hiro
497 1 hiro
        if (ret == -1) {
498 1 hiro
                manage_window_focus_in(dialog->dialog->window, NULL, NULL);
499 1 hiro
                send_put_error(session);
500 1 hiro
                manage_window_focus_out(dialog->dialog->window, NULL, NULL);
501 1 hiro
        }
502 1 hiro
503 1 hiro
        session_destroy(session);
504 1 hiro
        send_progress_dialog_destroy(dialog);
505 1 hiro
506 1 hiro
        return ret;
507 1 hiro
}
508 1 hiro
509 1 hiro
static gint send_recv_message(Session *session, const gchar *msg, gpointer data)
510 1 hiro
{
511 1 hiro
        gchar buf[BUFFSIZE];
512 1 hiro
        SMTPSession *smtp_session = SMTP_SESSION(session);
513 1 hiro
        SendProgressDialog *dialog = (SendProgressDialog *)data;
514 1 hiro
        gchar *state_str = NULL;
515 1 hiro
516 1 hiro
        g_return_val_if_fail(dialog != NULL, -1);
517 1 hiro
518 1 hiro
        switch (smtp_session->state) {
519 1 hiro
        case SMTP_READY:
520 1 hiro
        case SMTP_CONNECTED:
521 1 hiro
                return 0;
522 1 hiro
        case SMTP_HELO:
523 1 hiro
                g_snprintf(buf, sizeof(buf), _("Sending HELO..."));
524 1 hiro
                state_str = _("Authenticating");
525 1 hiro
                statusbar_print_all(_("Sending message..."));
526 1 hiro
                break;
527 1 hiro
        case SMTP_EHLO:
528 1 hiro
                g_snprintf(buf, sizeof(buf), _("Sending EHLO..."));
529 1 hiro
                state_str = _("Authenticating");
530 1 hiro
                statusbar_print_all(_("Sending message..."));
531 1 hiro
                break;
532 1 hiro
        case SMTP_AUTH:
533 1 hiro
                g_snprintf(buf, sizeof(buf), _("Authenticating..."));
534 1 hiro
                state_str = _("Authenticating");
535 1 hiro
                break;
536 1 hiro
        case SMTP_FROM:
537 1 hiro
                g_snprintf(buf, sizeof(buf), _("Sending MAIL FROM..."));
538 1 hiro
                state_str = _("Sending");
539 1 hiro
                break;
540 1 hiro
        case SMTP_RCPT:
541 1 hiro
                g_snprintf(buf, sizeof(buf), _("Sending RCPT TO..."));
542 1 hiro
                state_str = _("Sending");
543 1 hiro
                break;
544 1 hiro
        case SMTP_DATA:
545 1 hiro
        case SMTP_EOM:
546 1 hiro
                g_snprintf(buf, sizeof(buf), _("Sending DATA..."));
547 1 hiro
                state_str = _("Sending");
548 1 hiro
                break;
549 1 hiro
        case SMTP_QUIT:
550 1 hiro
                g_snprintf(buf, sizeof(buf), _("Quitting..."));
551 1 hiro
                state_str = _("Quitting");
552 1 hiro
                break;
553 1 hiro
        case SMTP_ERROR:
554 1 hiro
                g_warning("send: error: %s\n", msg);
555 1 hiro
                return 0;
556 1 hiro
        default:
557 1 hiro
                return 0;
558 1 hiro
        }
559 1 hiro
560 1 hiro
        progress_dialog_set_label(dialog->dialog, buf);
561 321 hiro
        progress_dialog_set_row_status(dialog->dialog, 0, state_str);
562 1 hiro
563 1 hiro
        return 0;
564 1 hiro
}
565 1 hiro
566 1 hiro
static gint send_send_data_progressive(Session *session, guint cur_len,
567 1 hiro
                                       guint total_len, gpointer data)
568 1 hiro
{
569 1 hiro
        gchar buf[BUFFSIZE];
570 1 hiro
        SendProgressDialog *dialog = (SendProgressDialog *)data;
571 1 hiro
572 1 hiro
        g_return_val_if_fail(dialog != NULL, -1);
573 1 hiro
574 1 hiro
        if (SMTP_SESSION(session)->state != SMTP_SEND_DATA &&
575 1 hiro
            SMTP_SESSION(session)->state != SMTP_EOM)
576 1 hiro
                return 0;
577 1 hiro
578 1 hiro
        g_snprintf(buf, sizeof(buf), _("Sending message (%d / %d bytes)"),
579 1 hiro
                   cur_len, total_len);
580 1 hiro
        progress_dialog_set_label(dialog->dialog, buf);
581 1 hiro
        progress_dialog_set_percentage
582 1 hiro
                (dialog->dialog, (gfloat)cur_len / (gfloat)total_len);
583 1 hiro
584 1 hiro
        return 0;
585 1 hiro
}
586 1 hiro
587 1 hiro
static gint send_send_data_finished(Session *session, guint len, gpointer data)
588 1 hiro
{
589 1 hiro
        SendProgressDialog *dialog = (SendProgressDialog *)data;
590 1 hiro
591 1 hiro
        g_return_val_if_fail(dialog != NULL, -1);
592 1 hiro
593 1 hiro
        send_send_data_progressive(session, len, len, dialog);
594 1 hiro
        return 0;
595 1 hiro
}
596 1 hiro
597 1 hiro
static SendProgressDialog *send_progress_dialog_create(void)
598 1 hiro
{
599 1 hiro
        SendProgressDialog *dialog;
600 1 hiro
        ProgressDialog *progress;
601 1 hiro
602 1 hiro
        dialog = g_new0(SendProgressDialog, 1);
603 1 hiro
604 1 hiro
        progress = progress_dialog_create();
605 1 hiro
        gtk_window_set_title(GTK_WINDOW(progress->window),
606 1 hiro
                             _("Sending message"));
607 1 hiro
        g_signal_connect(G_OBJECT(progress->cancel_btn), "clicked",
608 1 hiro
                         G_CALLBACK(send_cancel_button_cb), dialog);
609 1 hiro
        g_signal_connect(G_OBJECT(progress->window), "delete_event",
610 1 hiro
                         G_CALLBACK(gtk_true), NULL);
611 1 hiro
        gtk_window_set_modal(GTK_WINDOW(progress->window), TRUE);
612 1 hiro
        manage_window_set_transient(GTK_WINDOW(progress->window));
613 1 hiro
614 1 hiro
        progress_dialog_set_value(progress, 0.0);
615 1 hiro
616 1 hiro
        gtk_widget_show_now(progress->window);
617 1 hiro
618 1 hiro
        dialog->dialog = progress;
619 1 hiro
620 1 hiro
        return dialog;
621 1 hiro
}
622 1 hiro
623 1 hiro
static void send_progress_dialog_destroy(SendProgressDialog *dialog)
624 1 hiro
{
625 1 hiro
        g_return_if_fail(dialog != NULL);
626 1 hiro
627 300 hiro
        manage_window_destroy(dialog->dialog->window, NULL);
628 1 hiro
        progress_dialog_destroy(dialog->dialog);
629 1 hiro
        g_free(dialog);
630 1 hiro
}
631 1 hiro
632 1 hiro
static void send_cancel_button_cb(GtkWidget *widget, gpointer data)
633 1 hiro
{
634 1 hiro
        SendProgressDialog *dialog = (SendProgressDialog *)data;
635 1 hiro
636 1 hiro
        dialog->cancelled = TRUE;
637 1 hiro
}
638 1 hiro
639 1 hiro
static void send_put_error(Session *session)
640 1 hiro
{
641 1 hiro
        gchar *msg;
642 1 hiro
        gchar *log_msg = NULL;
643 1 hiro
        gchar *err_msg = NULL;
644 1 hiro
645 1 hiro
        msg = SMTP_SESSION(session)->error_msg;
646 1 hiro
647 1 hiro
        switch (SMTP_SESSION(session)->error_val) {
648 1 hiro
        case SM_ERROR:
649 1 hiro
        case SM_UNRECOVERABLE:
650 1 hiro
                log_msg = _("Error occurred while sending the message.");
651 1 hiro
                if (msg)
652 1 hiro
                        err_msg = g_strdup_printf
653 1 hiro
                                (_("Error occurred while sending the message:\n%s"),
654 1 hiro
                                 msg);
655 1 hiro
                else
656 1 hiro
                        err_msg = g_strdup(log_msg);
657 1 hiro
                break;
658 1 hiro
        case SM_AUTHFAIL:
659 1 hiro
                log_msg = _("Authentication failed.");
660 1 hiro
                if (msg)
661 1 hiro
                        err_msg = g_strdup_printf
662 1 hiro
                                (_("Authentication failed:\n%s"), msg);
663 1 hiro
                else
664 1 hiro
                        err_msg = g_strdup(log_msg);
665 1 hiro
                break;
666 1 hiro
        default:
667 1 hiro
                switch (session->state) {
668 1 hiro
                case SESSION_ERROR:
669 1 hiro
                        log_msg =
670 1 hiro
                                _("Error occurred while sending the message.");
671 1 hiro
                        err_msg = g_strdup(log_msg);
672 1 hiro
                        break;
673 1 hiro
                case SESSION_EOF:
674 1 hiro
                        log_msg = _("Connection closed by the remote host.");
675 1 hiro
                        err_msg = g_strdup(log_msg);
676 1 hiro
                        break;
677 1 hiro
                case SESSION_TIMEOUT:
678 1 hiro
                        log_msg = _("Session timed out.");
679 1 hiro
                        err_msg = g_strdup(log_msg);
680 1 hiro
                        break;
681 1 hiro
                default:
682 1 hiro
                        break;
683 1 hiro
                }
684 1 hiro
                break;
685 1 hiro
        }
686 1 hiro
687 1 hiro
        if (log_msg)
688 1 hiro
                log_warning("%s\n", log_msg);
689 1 hiro
        if (err_msg) {
690 1 hiro
                alertpanel_error("%s", err_msg);
691 1 hiro
                g_free(err_msg);
692 1 hiro
        }
693 1 hiro
}