Sending mails progressively
This commit is contained in:
parent
746adb7af5
commit
3a8716453e
@ -2,7 +2,10 @@
|
||||
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "compose.h"
|
||||
#include "mailer.h"
|
||||
#include "callbacks.h"
|
||||
@ -153,3 +156,51 @@ void on_compose_help_about(GtkWidget * widget, gpointer data)
|
||||
|
||||
on_help_about(widget, c->mailer);
|
||||
}
|
||||
|
||||
|
||||
/* send mail */
|
||||
gboolean on_send_closex(GtkWidget * widget, GdkEvent * event, gpointer data)
|
||||
{
|
||||
Compose * c = data;
|
||||
|
||||
on_send_cancel(widget, c);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void on_send_cancel(GtkWidget * widget, gpointer data)
|
||||
{
|
||||
Compose * c = data;
|
||||
|
||||
g_io_channel_shutdown(c->channel, TRUE, NULL);
|
||||
gtk_widget_destroy(c->snd_window);
|
||||
free(c->buf);
|
||||
}
|
||||
|
||||
|
||||
gboolean on_send_write(GIOChannel * source, GIOCondition condition,
|
||||
gpointer data)
|
||||
{
|
||||
Compose * c = data;
|
||||
gsize i;
|
||||
|
||||
if((i = (c->buf_len - c->buf_pos) % 512) == 0)
|
||||
i = 512;
|
||||
if(g_io_channel_write_chars(source, &c->buf[c->buf_pos], i, &i, NULL)
|
||||
!= G_IO_STATUS_NORMAL)
|
||||
{
|
||||
mailer_error(c->mailer, strerror(errno), FALSE);
|
||||
on_send_cancel(c->snd_window, c);
|
||||
return FALSE;
|
||||
}
|
||||
c->buf_pos+=i;
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(c->snd_progress),
|
||||
c->buf_pos / c->buf_len);
|
||||
if(c->buf_pos >= c->buf_len)
|
||||
{
|
||||
on_send_cancel(c->snd_window, c);
|
||||
compose_delete(c);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -37,4 +37,10 @@ void on_compose_view_bcc(GtkWidget * widget, gpointer data);
|
||||
/* help menu */
|
||||
void on_compose_help_about(GtkWidget * widget, gpointer data);
|
||||
|
||||
/* send mail */
|
||||
gboolean on_send_closex(GtkWidget * widget, GdkEvent * event, gpointer data);
|
||||
void on_send_cancel(GtkWidget * widget, gpointer data);
|
||||
gboolean on_send_write(GIOChannel * source, GIOCondition condition,
|
||||
gpointer data);
|
||||
|
||||
#endif /* !MAILER_CALLBACKS_H */
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
@ -221,40 +222,54 @@ void compose_send(Compose * compose)
|
||||
_send_mail(compose, msg, msg_len);
|
||||
}
|
||||
g_free(body);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
static int _mail_child(int fdin[2]);
|
||||
static int _mail_child(int fd[2]);
|
||||
static int _send_mail(Compose * compose, char * msg, size_t msg_len)
|
||||
{
|
||||
int fdin[2];
|
||||
pid_t pid;
|
||||
int status;
|
||||
int ret = 0;
|
||||
int fd[2];
|
||||
GtkWidget * hbox;
|
||||
GtkWidget * widget;
|
||||
|
||||
if(pipe(fdin) != 0 || (pid = fork()) == -1)
|
||||
if(pipe(fd) != 0 || (compose->pid = fork()) == -1)
|
||||
return mailer_error(compose->mailer, strerror(errno), 1);
|
||||
if(pid == 0)
|
||||
return _mail_child(fdin);
|
||||
if(close(fdin[0]) != 0)
|
||||
if(compose->pid == 0)
|
||||
return _mail_child(fd);
|
||||
if(close(fd[0]) != 0 || fcntl(fd[1], F_SETFL, O_NONBLOCK) == -1)
|
||||
mailer_error(compose->mailer, strerror(errno), 0);
|
||||
/* FIXME send mail progressively */
|
||||
write(1, msg, msg_len);
|
||||
if(write(fdin[1], msg, msg_len) != msg_len)
|
||||
ret = mailer_error(compose->mailer, strerror(errno), 1);
|
||||
if(close(fdin[1]) != 0)
|
||||
mailer_error(compose->mailer, strerror(errno), 0);
|
||||
if(waitpid(pid, &status, 0) != pid)
|
||||
ret = mailer_error(compose->mailer, strerror(errno), 1);
|
||||
else if(WIFEXITED(status))
|
||||
fprintf(stderr, "%s%s%d\n", "mailer: sendmail: ",
|
||||
"Exited with error ", WEXITSTATUS(status));
|
||||
return ret;
|
||||
compose->snd_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for(GTK_WINDOW(compose->snd_window),
|
||||
GTK_WINDOW(compose->window));
|
||||
gtk_window_set_title(GTK_WINDOW(compose->snd_window),
|
||||
"Sending mail...");
|
||||
g_signal_connect(G_OBJECT(compose->snd_window), "delete_event",
|
||||
G_CALLBACK(on_send_closex), compose);
|
||||
hbox = gtk_hbox_new(FALSE, 0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Progression: "),
|
||||
FALSE, FALSE, 0);
|
||||
compose->snd_progress = gtk_progress_bar_new();
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(compose->snd_progress),
|
||||
0.0);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), compose->snd_progress, TRUE, TRUE, 0);
|
||||
widget = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
|
||||
g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(
|
||||
on_send_cancel), compose);
|
||||
gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(compose->snd_window), 4);
|
||||
gtk_container_add(GTK_CONTAINER(compose->snd_window), hbox);
|
||||
gtk_widget_show_all(compose->snd_window);
|
||||
compose->fd = fd[1];
|
||||
compose->buf = msg;
|
||||
compose->buf_len = msg_len;
|
||||
compose->buf_pos = 0;
|
||||
compose->channel = g_io_channel_unix_new(fd[1]);
|
||||
g_io_add_watch(compose->channel, G_IO_OUT, on_send_write, compose);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _mail_child(int fdin[2])
|
||||
static int _mail_child(int fd[2])
|
||||
{
|
||||
if(close(fdin[1]) != 0 || close(0) != 0 || dup2(fdin[0], 0) == -1)
|
||||
if(close(fd[1]) != 0 || close(0) != 0 || dup2(fd[0], 0) == -1)
|
||||
perror("mailer");
|
||||
else
|
||||
{
|
||||
|
@ -13,6 +13,16 @@ typedef struct _Compose
|
||||
{
|
||||
Mailer * mailer;
|
||||
|
||||
/* sending mail */
|
||||
pid_t pid;
|
||||
int fd;
|
||||
char * buf;
|
||||
size_t buf_len;
|
||||
size_t buf_pos;
|
||||
GIOChannel * channel;
|
||||
GtkWidget * snd_window;
|
||||
GtkWidget * snd_progress;
|
||||
|
||||
/* widgets */
|
||||
GtkWidget * window;
|
||||
GtkWidget * from;
|
||||
|
Loading…
Reference in New Issue
Block a user