/*
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.
----------------------------------------------------------------------
attachments viewer
*/
/****************************************************************************
* IMPLEMENTATION HEADERS
****************************************************************************/
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "attach.h"
#include "ecurses.h"
#include "error.h"
#include "mail.h"
#include "rmime.h"
#include "select.h"
#include "xmalloc.h"
#include "read.h"
#include "cmd.h"
#include "gettext.h"
#include "wrapbox.h"
#include "file.h"
#include "ask.h"
#include "interface.h"
#include "color.h"
#include "label.h"
#include "folder.h"
#include "eprintf.h"
#include "run.h"
/****************************************************************************
* IMPLEMENTATION PRIVATE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE CLASS PROTOTYPES / EXTERNAL CLASS REFERENCES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE STRUCTURES / UTILITY CLASSES
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION REQUIRED EXTERNAL REFERENCES (AVOID)
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE DATA
****************************************************************************/
/* Attachment window consists of select_t object and an optional label. */
static select_t *attach_select = NULL;
static elabel_t *label = NULL;
static char *attach_fmt = "%020t %040f (%-06s)";
/* These are directories, where user saves his attachments. */
static char *save_dir = NULL;
static char *save_all_dir = NULL;
/* Color used in attachments window. */
static chtype text_color;
/* Used in draw_line. */
static str_t *str_line = NULL;
/****************************************************************************
* INTERFACE DATA
****************************************************************************/
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTION PROTOTYPES
****************************************************************************/
/* This file is generated by interface.pl script from interface.desc,
and inc.in. */
static WINDOW *interface_init (void);
#include "attach.inc"
/****************************************************************************
* IMPLEMENTATION PRIVATE FUNCTIONS
****************************************************************************/
static mime_t *
selected_mime (void)
{
mail_t *mail = folder_mail_selected ();
return mime_nth_leaf (mail->mime, attach_select->bar_pos);
}
static void
draw_line (WINDOW *win, int maxlen, int index, search_t *search)
{
mail_t *mail = folder_mail_selected ();
mime_t *mime = (mail) ? mime_nth_leaf (mail->mime, index) : NULL;
if (str_line == NULL)
str_line = str_create ();
if (mime) {
eprintf_mime_str (attach_fmt, mime, str_line);
maxlen -= window_addnstr (win, str_line->str, maxlen);
}
while (maxlen-- > 0)
window_addch (win, ' ');
}
static int
count (select_t *nothing)
{
mail_t *mail = folder_mail_selected ();
return (mail) ? mime_leaf_count (mail->mime) : 0;
}
static void
set_focus (void)
{
if (label){
label_set_focus (label);
}
cmd_state_push (CMD_ATTACH);
attach_refresh ();
}
static void
unset_focus (void)
{
if (label){
label_unset_focus (label);
label_redraw (label);
}
cmd_state_pop ();
}
static void
save_directory (char **dir, char *str)
{
char *seek = strrchr (str, '/');
if (seek == NULL)
return;
if (*dir)
xfree (*dir);
*seek = '\0';
*dir = xstrdup (str);
*seek = '/';
}
static int
save_file (FILE *fp, mail_t *mail, mime_t *mime)
{
int ret = 0;
str_t *str;
str = wrapbox_mail_body (mail, mime, 1);
if (str == NULL){
error_ (errno, _("couldn't read attachment, write aborted"));
return 1;
}
if (fwrite (str->str, 1, str->len, fp) != str->len){
error_ (errno, "fwrite");
ret = 1;
}
fclose (fp);
str_destroy (str);
return ret;
}
static FILE *
force_open (const char *dir, const char *fname, char *path)
{
FILE *fp;
fp = file_open (path, "w", O_WRONLY | O_CREAT, 0644);
if (fp == NULL)
error_ (errno, _("couldn't open %s in %s"), fname, dir);
xfree (path);
return fp;
}
static FILE *
try_open (const char *dir, const char *fname, char *path, int *overwrite)
{
char *response;
str_t *str;
FILE *fp;
if (*overwrite){
return force_open (dir, fname, path);
}
fp = file_open (path, "w", O_WRONLY | O_CREAT | O_EXCL, 0644);
if (fp == NULL){
if (errno != EEXIST){
error_ (errno, _("couldn't open %s in %s"),
fname, dir);
xfree (path);
return NULL;
}
str = str_create ();
str_sprintf (str, _("File %s already exists, overwrite "
"[a/y/N]? "), fname);
response = read_argument (str->str, NULL, COMPLETE_NONE,
HIDE_NO);
str_destroy (str);
if (*response == 'a' || *response == 'A')
*overwrite = 1;
else if (*response != 'y' && *response != 'Y'){
xfree (path);
return NULL;
}
}
return force_open (dir, fname, path);
}
static int
save_attach (const char *dir, mail_t *mail, mime_t *mime, int overwrite)
{
int i;
char *path;
FILE *fp;
if (mime == NULL)
return overwrite;
if (mime->file_name){
path = file_with_dir (dir, mime->file_name);
fp = try_open (dir, mime->file_name, path, & overwrite);
if (fp)
save_file (fp, mail, mime);
return overwrite;
}
if (mime->parts == NULL)
return overwrite;
for (i = 0; i < mime->parts->count; i++){
overwrite = save_attach (dir, mail, mime->parts->array[i],
overwrite);
}
return overwrite;
}
/****************************************************************************
* INTERFACE FUNCTIONS
****************************************************************************/
void
attach_init (void)
{
WINDOW *window;
window = interface_init ();
attach_select = select_open (window, 0, draw_line, count);
window_set_functions (window, attach_show, attach_refresh,
set_focus, unset_focus);
}
void
attach_free_resources (void)
{
if (attach_select)
select_close (attach_select);
attach_select = NULL;
if (label)
label_destroy (label);
label = NULL;
if (str_line)
str_destroy (str_line);
str_line = NULL;
if (save_dir)
xfree (save_dir);
save_dir = NULL;
if (save_all_dir)
xfree (save_all_dir);
save_all_dir = NULL;
}
void
attach_show (void)
{
window_show (attach_select->win);
select_first (attach_select);
attach_refresh ();
}
void
attach_hide (void)
{
window_hide (attach_select->win);
}
void
attach_refresh (void)
{
if (label)
label_redraw (label);
select_redraw (attach_select);
}
void
attach_hit (void)
{
mail_t *mail = folder_mail_selected ();
mime_t *mime = selected_mime ();
if (run_mime (mail, mime) == 2)
window_hide (attach_select->win);
}
void
attach_prev (void)
{
select_prev (attach_select);
}
void
attach_next (void)
{
select_next (attach_select);
}
void
attach_prev_page (void)
{
select_prev_page (attach_select);
}
void
attach_next_page (void)
{
select_next_page (attach_select);
}
void
attach_first (void)
{
select_first (attach_select);
}
void
attach_last (void)
{
select_last (attach_select);
}
void
attach_save (void)
{
FILE *fp;
char *def;
char *file;
int ret;
mail_t *mail = folder_mail_selected ();
mime_t *mime = (mail) ? selected_mime () : NULL;
if (mime == NULL)
return;
def = file_with_dir (save_dir, mime->file_name);
file = read_argument (_("File: "), def, COMPLETE_FILES, HIDE_NO);
if (file == NULL || *file == '\0' || *file == '\n')
return;
if (def)
xfree (def);
save_directory (& save_dir, file);
fp = file_open (file, "w", O_WRONLY | O_CREAT | O_EXCL, 0644);
if (fp == NULL){
if (errno != EEXIST){
error_ (errno, "%s", file);
return;
}
file = xstrdup (file);
ret = ask_if_sure (_("File already exists, overwrite [y/N]? "));
switch (ret){
case -1:
case 0:
xfree (file);
return;
case 1:
fp = file_open (file, "w", O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fp == NULL){
error_ (errno, "%s", file);
xfree (file);
return;
}
xfree (file);
}
}
save_file (fp, mail, selected_mime ());
}
void
attach_save_all (void)
{
char *dir;
mail_t *mail = folder_mail_selected ();
if (mail == NULL || mail->mime == NULL)
return;
dir = read_argument (_("Directory: "), save_all_dir, COMPLETE_FILES,
HIDE_NO);
if (dir == NULL || *dir == '\0' || *dir == '\n')
return;
if (save_all_dir)
xfree (save_all_dir);
save_all_dir = xstrdup (dir);
if (mail->mime->decrypted)
save_attach (save_all_dir, mail, mail->mime->decrypted, 0);
else
save_attach (save_all_dir, mail, mail->mime->mime, 0);
}
/****************************************************************************
* INTERFACE CLASS BODIES
****************************************************************************/
/****************************************************************************
*
* END MODULE attach.c
*
****************************************************************************/
syntax highlighted by Code2HTML, v. 0.9.1