/*
elmo - ELectronic Mail Operator
Copyright (C) 2003, 2004 rzyjontko
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
----------------------------------------------------------------------
mail fetching window
*/
/****************************************************************************
* IMPLEMENTATION HEADERS
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include "ecurses.h"
#include "pop.h"
#include "error.h"
#include "select.h"
#include "xmalloc.h"
#include "wrapbox.h"
#include "misc.h"
#include "cmd.h"
#include "file.h"
#include "ask.h"
#include "fetch.h"
#include "gettext.h"
#include "mybox.h"
#include "eprintf.h"
#include "interface.h"
#include "color.h"
#include "label.h"
#include "mlex.h"
#include "procmail.h"
/****************************************************************************
* IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
****************************************************************************/
#define WINDOW_WIDTH COLS - 6
#define PREAMBLE do { if (fetch_select == NULL) return; } while (0)
/****************************************************************************
* IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
****************************************************************************/
struct list {
struct list *next;
int index;
};
/****************************************************************************
* IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE DATA
****************************************************************************/
static struct {
char *fname; /* destination file name */
FILE *fp; /* destination file pointer */
int fetched; /* total messages fetched */
int total_count; /* total messages at the server */
int index; /* index of the message to be fetched / deleted */
struct list *to_fetch; /* list of messages to be fetched */
} conn;
/* Fetch window consists of select_t object, and an optional label. */
static elabel_t *label = NULL;
static select_t *fetch_select = NULL;
/* This is used to get account configuration. */
static ask_t *fetch_ask = NULL;
/* Format used when displaing messages in fetch window. */
static char *fetch_fmt = "%?%$ %D %016f (%-06S) %s";
/* Color used in fetch window. */
static chtype text_color;
/* Used in draw_line. */
static str_t *line_str = NULL;
/****************************************************************************
* INTERFACE DATA
****************************************************************************/
int fetch_got_mail = 0;
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTIONS
****************************************************************************/
static void
cleanup (void)
{
if (conn.fp)
fclose (conn.fp);
if (conn.fname){
unlink (conn.fname);
xfree (conn.fname);
}
if (fetch_ask)
ask_destroy (fetch_ask);
fetch_got_mail = 0;
fetch_ask = NULL;
conn.fname = NULL;
conn.fp = NULL;
conn.fetched = -1;
conn.total_count = -1;
if (fetch_select)
window_hide (fetch_select->win);
}
static void
deliver_mail (void)
{
char *box;
if (conn.fname && conn.fp){
rewind (conn.fp);
yyin = conn.fp;
mlex_scan_file (0);
fclose (conn.fp);
box = procmail_box (newmail);
wrapbox_deliver_to (conn.fname, box);
mail_destroy (newmail, BOX_INVALID);
xfree (box);
xfree (conn.fname);
}
conn.fname = NULL;
conn.fp = NULL;
}
static void
get_next (void)
{
conn.fetched++;
if (conn.fetched >= conn.total_count){
deliver_mail ();
pop_save_list ();
pop_close (cleanup, cleanup);
return;
}
deliver_mail ();
while (1){
conn.fname = wrapbox_fetch_where (1);
conn.fp = file_open (conn.fname, "w+",
O_RDWR | O_CREAT | O_EXCL, 0600);
if (conn.fp == NULL && errno == EEXIST)
xfree (conn.fname);
else
break;
}
if (conn.fp == NULL){
xfree (conn.fname);
error_ (0, _("couldn't open file %s"), conn.fname);
pop_close (cleanup, cleanup);
return;
}
pop_retr (conn.fetched + 1, conn.fp, get_next, cleanup);
}
static void
merge_lists (void)
{
pop_load_list ();
pop_merge_lists ();
get_next ();
}
static void
uidl_then_next (void)
{
pop_uidl (merge_lists, cleanup);
}
static void
action_all (void)
{
conn.fetched = -1;
conn.total_count = pop_maildrop_count ();
pop_list (uidl_then_next, cleanup);
}
static void
open_window (void)
{
if (pop_header_count () < 1){
error_ (0, "%s", _("no new messages"));
pop_close (cleanup, cleanup);
return;
}
window_show (fetch_select->win);
fetch_redraw ();
}
static void
get_infos (void)
{
pop_load_list ();
pop_merge_lists ();
pop_get_infos (open_window, cleanup);
}
static void
uidl_then_infos (void)
{
pop_uidl (get_infos, cleanup);
}
static void
action_win (void)
{
pop_list (uidl_then_infos, cleanup);
}
static int
open_connection (void (*action)(void))
{
int port = 0;
char *host;
char *user;
char *pass;
int method;
int secure;
char *s_port;
enum auth_method m;
cleanup ();
fetch_ask = ask_select ("pop_acc");
if (fetch_ask == NULL)
return 1;
host = ask_get_field (fetch_ask, "server");
user = ask_get_field (fetch_ask, "username");
pass = ask_get_field (fetch_ask, "password");
s_port = ask_get_field (fetch_ask, "port");
method = ask_get_field_int_default (fetch_ask, "use_apop", 0);
secure = ask_get_field_int_default (fetch_ask, "ssl", 0);
if (s_port)
port = atoi (s_port);
if (host == NULL){
error_ (0, _("server field in pop_acc not defined"));
ask_destroy (fetch_ask);
fetch_ask = NULL;
return 1;
}
if (user == NULL){
error_ (0, _("username field in pop_acc not defined"));
ask_destroy (fetch_ask);
fetch_ask = NULL;
return 1;
}
if (pass == NULL){
error_ (0, _("password field in pop_acc not defined"));
ask_destroy (fetch_ask);
fetch_ask = NULL;
return 1;
}
if (method)
m = AUTH_APOP;
else
m = AUTH_PLAIN;
return pop_open (host, port, user, pass, m, secure, action, cleanup);
}
static void
retr_succ (void)
{
mail_t *mail = pop_header_info (conn.index);
deliver_mail ();
if (mail == NULL)
return;
mail->flags |= FLAG_FETCHED;
fetch_redraw ();
}
static void
retr_fail (void)
{
if (conn.fp)
fclose (conn.fp);
conn.fp = NULL;
if (conn.fname){
unlink (conn.fname);
xfree (conn.fname);
}
conn.fname = NULL;
}
static void
dele_succ (void)
{
mail_t *mail = pop_header_info (conn.index);
mail->flags |= FLAG_TRASHED;
fetch_redraw ();
}
static void
rset_succ (void)
{
int i;
int count = pop_header_count ();
mail_t *mail;
for (i = 0; i < count; i++){
mail = pop_header_info (i);
mail->flags &= ~ FLAG_TRASHED;
}
fetch_redraw ();
}
static void
draw_line (WINDOW *win, int maxlen, int index, search_t *search)
{
mail_t *mail = pop_header_info (index);
if (line_str == NULL)
line_str = str_create ();
if (mail == NULL)
str_clear (line_str);
else
eprintf_mail_str (fetch_fmt, mail, line_str);
maxlen -= window_addnstr (win, line_str->str, maxlen);
while (maxlen-- > 0)
window_addch (win, ' ');
}
static int
count (select_t *nothing)
{
return pop_header_count ();
}
/* This file is generated by interface.pl script from interface.desc,
and inc.in. */
static WINDOW *interface_init (void);
#include "fetch.inc"
/****************************************************************************
* INTERFACE FUNCTIONS
****************************************************************************/
void
fetch_init (void)
{
WINDOW *window;
window = interface_init ();
fetch_select = select_open (window, 0, draw_line, count);
window_set_functions (window, fetch_show, fetch_redraw,
fetch_set_focus, fetch_unset_focus);
}
void
fetch_free_resources (void)
{
if (fetch_select)
select_close (fetch_select);
fetch_select = NULL;
if (label)
label_destroy (label);
label = NULL;
if (line_str)
str_destroy (line_str);
line_str = NULL;
}
void
fetch_all (void)
{
open_connection (action_all);
}
void
fetch_get_rest (void)
{
}
void
fetch_show (void)
{
select_show (fetch_select);
label_show (label);
}
void
fetch_redraw (void)
{
select_redraw (fetch_select);
label_redraw (label);
}
void
fetch_set_focus (void)
{
label_set_focus (label);
cmd_state_push (CMD_FETCH);
fetch_redraw ();
}
void
fetch_unset_focus (void)
{
label_unset_focus (label);
label_redraw (label);
cmd_state_pop ();
}
void
fetch_open (void)
{
open_connection (action_win);
}
void
fetch_open_all (void)
{
}
void
fetch_close (void)
{
pop_save_list ();
pop_close (cleanup, cleanup);
}
void
fetch_next (void)
{
select_next (fetch_select);
}
void
fetch_prev (void)
{
select_prev (fetch_select);
}
void
fetch_next_page (void)
{
select_next_page (fetch_select);
}
void
fetch_prev_page (void)
{
select_prev_page (fetch_select);
}
void
fetch_first (void)
{
select_first (fetch_select);
}
void
fetch_last (void)
{
select_last (fetch_select);
}
void
fetch_rset (void)
{
pop_rset (rset_succ, NULL);
}
void
fetch_del_all (void)
{
}
void
fetch_del_mail (void)
{
int num;
conn.index = fetch_select->bar_pos;
num = pop_num (conn.index);
pop_dele (num, dele_succ, NULL);
}
void
fetch_get_mail (void)
{
int num;
conn.index = fetch_select->bar_pos;
num = pop_num (conn.index);
while (1){
conn.fname = wrapbox_fetch_where (1);
conn.fp = file_open (conn.fname, "w+",
O_RDWR | O_CREAT | O_EXCL, 0600);
if (conn.fp == NULL && errno == EEXIST)
xfree (conn.fname);
else
break;
}
if (conn.fp == NULL){
error_ (0, _("couldn't open file %s"), conn.fname);
xfree (conn.fname);
conn.fname = NULL;
pop_close (cleanup, cleanup);
return;
}
pop_retr (num, conn.fp, retr_succ, retr_fail);
}
void
fetch_mark_mail (void)
{
pop_mark_mail (fetch_select->bar_pos);
}
void
fetch_unmark_mail (void)
{
}
void
fetch_mark_all (void)
{
}
void
fetch_unmark_all (void)
{
}
void
fetch_remove_till_limit (void)
{
}
void
fetch_remove_till_count (void)
{
}
/****************************************************************************
* INTERFACE CLASS BODIES
****************************************************************************/
/****************************************************************************
*
* END MODULE fetch.c
*
****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1