Sending mails progressively
This commit is contained in:
parent
746adb7af5
commit
3a8716453e
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
#include "compose.h"
|
#include "compose.h"
|
||||||
#include "mailer.h"
|
#include "mailer.h"
|
||||||
#include "callbacks.h"
|
#include "callbacks.h"
|
||||||
@ -153,3 +156,51 @@ void on_compose_help_about(GtkWidget * widget, gpointer data)
|
|||||||
|
|
||||||
on_help_about(widget, c->mailer);
|
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 */
|
/* help menu */
|
||||||
void on_compose_help_about(GtkWidget * widget, gpointer data);
|
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 */
|
#endif /* !MAILER_CALLBACKS_H */
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -221,40 +222,54 @@ void compose_send(Compose * compose)
|
|||||||
_send_mail(compose, msg, msg_len);
|
_send_mail(compose, msg, msg_len);
|
||||||
}
|
}
|
||||||
g_free(body);
|
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)
|
static int _send_mail(Compose * compose, char * msg, size_t msg_len)
|
||||||
{
|
{
|
||||||
int fdin[2];
|
int fd[2];
|
||||||
pid_t pid;
|
GtkWidget * hbox;
|
||||||
int status;
|
GtkWidget * widget;
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if(pipe(fdin) != 0 || (pid = fork()) == -1)
|
if(pipe(fd) != 0 || (compose->pid = fork()) == -1)
|
||||||
return mailer_error(compose->mailer, strerror(errno), 1);
|
return mailer_error(compose->mailer, strerror(errno), 1);
|
||||||
if(pid == 0)
|
if(compose->pid == 0)
|
||||||
return _mail_child(fdin);
|
return _mail_child(fd);
|
||||||
if(close(fdin[0]) != 0)
|
if(close(fd[0]) != 0 || fcntl(fd[1], F_SETFL, O_NONBLOCK) == -1)
|
||||||
mailer_error(compose->mailer, strerror(errno), 0);
|
mailer_error(compose->mailer, strerror(errno), 0);
|
||||||
/* FIXME send mail progressively */
|
compose->snd_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||||
write(1, msg, msg_len);
|
gtk_window_set_transient_for(GTK_WINDOW(compose->snd_window),
|
||||||
if(write(fdin[1], msg, msg_len) != msg_len)
|
GTK_WINDOW(compose->window));
|
||||||
ret = mailer_error(compose->mailer, strerror(errno), 1);
|
gtk_window_set_title(GTK_WINDOW(compose->snd_window),
|
||||||
if(close(fdin[1]) != 0)
|
"Sending mail...");
|
||||||
mailer_error(compose->mailer, strerror(errno), 0);
|
g_signal_connect(G_OBJECT(compose->snd_window), "delete_event",
|
||||||
if(waitpid(pid, &status, 0) != pid)
|
G_CALLBACK(on_send_closex), compose);
|
||||||
ret = mailer_error(compose->mailer, strerror(errno), 1);
|
hbox = gtk_hbox_new(FALSE, 0);
|
||||||
else if(WIFEXITED(status))
|
gtk_box_pack_start(GTK_BOX(hbox), gtk_label_new("Progression: "),
|
||||||
fprintf(stderr, "%s%s%d\n", "mailer: sendmail: ",
|
FALSE, FALSE, 0);
|
||||||
"Exited with error ", WEXITSTATUS(status));
|
compose->snd_progress = gtk_progress_bar_new();
|
||||||
return ret;
|
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");
|
perror("mailer");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,16 @@ typedef struct _Compose
|
|||||||
{
|
{
|
||||||
Mailer * mailer;
|
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 */
|
/* widgets */
|
||||||
GtkWidget * window;
|
GtkWidget * window;
|
||||||
GtkWidget * from;
|
GtkWidget * from;
|
||||||
|
Loading…
Reference in New Issue
Block a user