/* 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 #include #include #include #include #include #include #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 * ****************************************************************************/