summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--attach.h2
-rw-r--r--commands.c2
-rw-r--r--compose.c24
-rw-r--r--keymap.h2
-rw-r--r--lib.c7
-rw-r--r--lib.h1
-rw-r--r--menu.c52
-rw-r--r--mutt.h2
-rw-r--r--mutt_menu.h1
-rw-r--r--muttlib.c59
-rw-r--r--pager.c2
-rw-r--r--protos.h2
-rw-r--r--recvattach.c141
13 files changed, 195 insertions, 102 deletions
diff --git a/attach.h b/attach.h
index 2147b744..2e17a449 100644
--- a/attach.h
+++ b/attach.h
@@ -24,7 +24,7 @@ int mutt_attach_display_loop (MUTTMENU *menu, int op, FILE *fp, HEADER *hdr,
int recv);
-void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr);
+void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu);
void mutt_pipe_attachment_list (FILE *fp, int tag, BODY *top, int filter);
void mutt_print_attachment_list (FILE *fp, int tag, BODY *top);
diff --git a/commands.c b/commands.c
index fe623fd4..3761926d 100644
--- a/commands.c
+++ b/commands.c
@@ -761,7 +761,7 @@ int mutt_save_message (HEADER *h, int delete,
mutt_expand_path (buf, sizeof (buf));
/* check to make sure that this file is really the one the user wants */
- if (!mutt_save_confirm (buf, &st))
+ if (mutt_save_confirm (buf, &st) != 0)
return -1;
if (WithCrypto && need_passphrase && (decode || decrypt)
diff --git a/compose.c b/compose.c
index 22ebc23c..a77667c8 100644
--- a/compose.c
+++ b/compose.c
@@ -483,6 +483,7 @@ static void update_idx (MUTTMENU *menu, ATTACHPTR **idx, short idxlen)
idx[idxlen]->level = (idxlen > 0) ? idx[idxlen-1]->level : 0;
if (idxlen)
idx[idxlen - 1]->content->next = idx[idxlen]->content;
+ idx[idxlen]->content->aptr = idx[idxlen];
menu->current = idxlen++;
mutt_update_tree (idx, idxlen);
menu->max = idxlen;
@@ -760,14 +761,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
idx[idxlen] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR));
if ((idx[idxlen]->content = crypt_pgp_make_key_attachment(NULL)) != NULL)
{
- idx[idxlen]->level = (idxlen > 0) ? idx[idxlen-1]->level : 0;
-
- if(idxlen)
- idx[idxlen - 1]->content->next = idx[idxlen]->content;
-
- menu->current = idxlen++;
- mutt_update_tree (idx, idxlen);
- menu->max = idxlen;
+ update_idx (menu, idx, idxlen++);
menu->redraw |= REDRAW_INDEX;
}
else
@@ -1187,14 +1181,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
mutt_error _("What we have here is a failure to make an attachment");
continue;
}
-
- idx[idxlen]->level = (idxlen > 0) ? idx[idxlen-1]->level : 0;
- if (idxlen)
- idx[idxlen - 1]->content->next = idx[idxlen]->content;
-
- menu->current = idxlen++;
- mutt_update_tree (idx, idxlen);
- menu->max = idxlen;
+ update_idx (menu, idx, idxlen++);
idx[menu->current]->content->type = itype;
mutt_str_replace (&idx[menu->current]->content->subtype, p);
@@ -1227,7 +1214,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
case OP_SAVE:
CHECK_COUNT;
- mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : idx[menu->current]->content, NULL);
+ mutt_save_attachment_list (NULL, menu->tagprefix, menu->tagprefix ? msg->content : idx[menu->current]->content, NULL, menu);
MAYBE_REDRAW (menu->redraw);
break;
@@ -1392,7 +1379,10 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */
{
msg->content = idx[0]->content;
for (i = 0; i < idxlen; i++)
+ {
+ idx[i]->content->aptr = NULL;
FREE (&idx[i]);
+ }
}
else
msg->content = NULL;
diff --git a/keymap.h b/keymap.h
index bdbafae6..a88bbf46 100644
--- a/keymap.h
+++ b/keymap.h
@@ -19,6 +19,8 @@
#ifndef KEYMAP_H
#define KEYMAP_H
+#include "mapping.h"
+
/* maximal length of a key binding sequence used for buffer in km_bindkey */
#define MAX_SEQ 8
diff --git a/lib.c b/lib.c
index 97879c98..4c6a4b5b 100644
--- a/lib.c
+++ b/lib.c
@@ -646,3 +646,10 @@ char *mutt_concat_path (char *d, const char *dir, const char *fname, size_t l)
snprintf (d, l, fmt, dir, fname);
return d;
}
+
+const char *mutt_basename (const char *f)
+{
+ const char *p = strrchr (f, '/');
+ if (p) ++p;
+ return p;
+}
diff --git a/lib.h b/lib.h
index 6e006836..2bda25d2 100644
--- a/lib.h
+++ b/lib.h
@@ -118,6 +118,7 @@ char *mutt_substrdup (const char *, const char *);
char *safe_strdup (const char *);
const char *mutt_stristr (const char *, const char *);
+const char *mutt_basename (const char *);
int mutt_copy_stream (FILE *, FILE *);
int mutt_copy_bytes (FILE *, FILE *, size_t);
diff --git a/menu.c b/menu.c
index f64d918c..11d8faa1 100644
--- a/menu.c
+++ b/menu.c
@@ -800,6 +800,34 @@ static int menu_dialog_dokey (MUTTMENU *menu, int *ip)
}
}
+int menu_redraw (MUTTMENU *menu)
+{
+ /* See if all or part of the screen needs to be updated. */
+ if (menu->redraw & REDRAW_FULL)
+ {
+ menu_redraw_full (menu);
+ /* allow the caller to do any local configuration */
+ return (OP_REDRAW);
+ }
+
+ if (!menu->dialog)
+ menu_check_recenter (menu);
+
+ if (menu->redraw & REDRAW_STATUS)
+ menu_redraw_status (menu);
+ if (menu->redraw & REDRAW_INDEX)
+ menu_redraw_index (menu);
+ else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNCH))
+ menu_redraw_motion (menu);
+ else if (menu->redraw == REDRAW_CURRENT)
+ menu_redraw_current (menu);
+
+ if (menu->dialog)
+ menu_redraw_prompt (menu);
+
+ return OP_NULL;
+}
+
int mutt_menuLoop (MUTTMENU *menu)
{
int i = OP_NULL;
@@ -819,28 +847,8 @@ int mutt_menuLoop (MUTTMENU *menu)
imap_keepalive ();
#endif
- /* See if all or part of the screen needs to be updated. */
- if (menu->redraw & REDRAW_FULL)
- {
- menu_redraw_full (menu);
- /* allow the caller to do any local configuration */
- return (OP_REDRAW);
- }
-
- if (!menu->dialog)
- menu_check_recenter (menu);
-
- if (menu->redraw & REDRAW_STATUS)
- menu_redraw_status (menu);
- if (menu->redraw & REDRAW_INDEX)
- menu_redraw_index (menu);
- else if (menu->redraw & (REDRAW_MOTION | REDRAW_MOTION_RESYNCH))
- menu_redraw_motion (menu);
- else if (menu->redraw == REDRAW_CURRENT)
- menu_redraw_current (menu);
-
- if (menu->dialog)
- menu_redraw_prompt (menu);
+ if (menu_redraw (menu) == OP_REDRAW)
+ return OP_REDRAW;
menu->oldcurrent = menu->current;
diff --git a/mutt.h b/mutt.h
index f708d091..cc0d1b19 100644
--- a/mutt.h
+++ b/mutt.h
@@ -598,6 +598,8 @@ typedef struct body
struct body *parts; /* parts of a multipart or message/rfc822 */
struct header *hdr; /* header information for message/rfc822 */
+ struct attachptr *aptr; /* Menu information, used in recvattach.c */
+
time_t stamp; /* time stamp of last
* encoding update.
*/
diff --git a/mutt_menu.h b/mutt_menu.h
index 83b83cdb..9ed85bba 100644
--- a/mutt_menu.h
+++ b/mutt_menu.h
@@ -83,6 +83,7 @@ void menu_redraw_index (MUTTMENU *);
void menu_redraw_status (MUTTMENU *);
void menu_redraw_motion (MUTTMENU *);
void menu_redraw_current (MUTTMENU *);
+int menu_redraw (MUTTMENU *);
void menu_first_entry (MUTTMENU *);
void menu_last_entry (MUTTMENU *);
void menu_top_page (MUTTMENU *);
diff --git a/muttlib.c b/muttlib.c
index 9b75b834..7d412089 100644
--- a/muttlib.c
+++ b/muttlib.c
@@ -814,10 +814,11 @@ void mutt_expand_fmt (char *dest, size_t destlen, const char *fmt, const char *s
}
-/* return 0 on success, -1 on error */
+/* return 0 on success, -1 on abort, 1 on error */
int mutt_check_overwrite (const char *attname, const char *path,
- char *fname, size_t flen, int *append)
+ char *fname, size_t flen, int *append, char **directory)
{
+ int rc = 0;
char tmp[_POSIX_PATH_MAX];
struct stat st;
@@ -828,18 +829,38 @@ int mutt_check_overwrite (const char *attname, const char *path,
return -1;
if (S_ISDIR (st.st_mode))
{
- if (mutt_yesorno (_("File is a directory, save under it?"), M_YES) != M_YES)
- return (-1);
+ if (directory)
+ {
+ switch (mutt_multi_choice
+ (_("File is a directory, save under it? [(y)es, (n)o, (a)ll]"), _("yna")))
+ {
+ case 3: /* all */
+ mutt_str_replace (directory, fname);
+ break;
+ case 1: /* yes */
+ FREE (directory);
+ break;
+ case -1: /* abort */
+ FREE (directory);
+ return -1;
+ case 2: /* no */
+ FREE (directory);
+ return 1;
+ }
+ }
+ else if ((rc = mutt_yesorno (_("File is a directory, save under it?"), M_YES)) != M_YES)
+ return (rc == M_NO) ? 1 : -1;
+
if (!attname || !attname[0])
{
tmp[0] = 0;
if (mutt_get_field (_("File under directory: "), tmp, sizeof (tmp),
M_FILE | M_CLEAR) != 0 || !tmp[0])
return (-1);
- snprintf (fname, flen, "%s/%s", path, tmp);
+ mutt_concat_path (fname, path, tmp, flen);
}
else
- snprintf (fname, flen, "%s/%s", path, attname);
+ mutt_concat_path (fname, path, mutt_basename (attname), flen);
}
if (*append == 0 && access (fname, F_OK) == 0)
@@ -848,8 +869,9 @@ int mutt_check_overwrite (const char *attname, const char *path,
(_("File exists, (o)verwrite, (a)ppend, or (c)ancel?"), _("oac")))
{
case -1: /* abort */
+ return -1;
case 3: /* cancel */
- return -1;
+ return 1;
case 2: /* append */
*append = M_SAVE_APPEND;
@@ -1133,11 +1155,12 @@ FILE *mutt_open_read (const char *path, pid_t *thepid)
return (f);
}
-/* returns 1 if OK to proceed, 0 to abort */
+/* returns 0 if OK to proceed, -1 to abort, 1 to retry */
int mutt_save_confirm (const char *s, struct stat *st)
{
char tmp[_POSIX_PATH_MAX];
- int ret = 1;
+ int ret = 0;
+ int rc;
int magic = 0;
magic = mx_get_magic (s);
@@ -1146,7 +1169,7 @@ int mutt_save_confirm (const char *s, struct stat *st)
if (magic == M_POP)
{
mutt_error _("Can't save message to POP mailbox.");
- return 0;
+ return 1;
}
#endif
@@ -1155,14 +1178,16 @@ int mutt_save_confirm (const char *s, struct stat *st)
if (magic == -1)
{
mutt_error (_("%s is not a mailbox!"), s);
- return 0;
+ return 1;
}
if (option (OPTCONFIRMAPPEND))
{
snprintf (tmp, sizeof (tmp), _("Append messages to %s?"), s);
- if (mutt_yesorno (tmp, M_YES) != M_YES)
- ret = 0;
+ if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
+ ret = 1;
+ else if (rc == -1)
+ ret = -1;
}
}
else
@@ -1179,14 +1204,16 @@ int mutt_save_confirm (const char *s, struct stat *st)
if (option (OPTCONFIRMCREATE))
{
snprintf (tmp, sizeof (tmp), _("Create %s?"), s);
- if (mutt_yesorno (tmp, M_YES) != M_YES)
- ret = 0;
+ if ((rc = mutt_yesorno (tmp, M_YES)) == M_NO)
+ ret = 1;
+ else if (rc == -1)
+ ret = -1;
}
}
else
{
mutt_perror (s);
- return 0;
+ return 1;
}
}
}
diff --git a/pager.c b/pager.c
index 26fcf07e..dd84c4f8 100644
--- a/pager.c
+++ b/pager.c
@@ -2438,7 +2438,7 @@ CHECK_IMAP_ACL(IMAP_ACL_WRITE);
case OP_SAVE:
if (IsAttach (extra))
{
- mutt_save_attachment_list (extra->fp, 0, extra->bdy, extra->hdr);
+ mutt_save_attachment_list (extra->fp, 0, extra->bdy, extra->hdr, NULL);
break;
}
/* fall through */
diff --git a/protos.h b/protos.h
index 5a0d97f3..8a4722cd 100644
--- a/protos.h
+++ b/protos.h
@@ -248,7 +248,7 @@ int mutt_check_key (const char *);
int mutt_check_menu (const char *);
int mutt_check_mime_type (const char *);
int mutt_check_month (const char *);
-int mutt_check_overwrite (const char *, const char *, char *, size_t, int *);
+int mutt_check_overwrite (const char *, const char *, char *, size_t, int *, char **);
int mutt_check_traditional_pgp (HEADER *, int *);
int mutt_command_complete (char *, size_t, int, int);
int mutt_var_value_complete (char *, size_t, int);
diff --git a/recvattach.c b/recvattach.c
index 09abea2d..aa1ce274 100644
--- a/recvattach.c
+++ b/recvattach.c
@@ -129,6 +129,7 @@ ATTACHPTR **mutt_gen_attach_list (BODY *m,
new = idx[(*idxlen)++];
new->content = m;
+ m->aptr = new;
new->parent_type = parent_type;
new->level = level;
@@ -363,14 +364,21 @@ int mutt_is_message_type (int type, const char *subtype)
return (ascii_strcasecmp (subtype, "rfc822") == 0 || ascii_strcasecmp (subtype, "news") == 0);
}
-static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr)
+static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr, char **directory)
{
+ char *prompt;
char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];
int is_message;
int append = 0;
-
- if (body->filename)
- strfcpy (buf, body->filename, sizeof (buf));
+ int rc;
+
+ if (body->filename)
+ {
+ if (directory && *directory)
+ mutt_concat_path (buf, *directory, mutt_basename (body->filename), sizeof (buf));
+ else
+ strfcpy (buf, body->filename, sizeof (buf));
+ }
else if(body->hdr &&
body->encoding != ENCBASE64 &&
body->encoding != ENCQUOTEDPRINTABLE &&
@@ -379,45 +387,68 @@ static int mutt_query_save_attachment (FILE *fp, BODY *body, HEADER *hdr)
else
buf[0] = 0;
- if (mutt_get_field (_("Save to file: "), buf, sizeof (buf), M_FILE | M_CLEAR) != 0
- || !buf[0])
- return -1;
-
- mutt_expand_path (buf, sizeof (buf));
-
- is_message = (fp &&
- body->hdr &&
- body->encoding != ENCBASE64 &&
- body->encoding != ENCQUOTEDPRINTABLE &&
- mutt_is_message_type (body->type, body->subtype));
-
- if (is_message)
+ prompt = _("Save to file: ");
+ while (prompt)
{
- struct stat st;
-
- /* check to make sure that this file is really the one the user wants */
- if (!mutt_save_confirm (buf, &st))
- return -1;
- strfcpy(tfile, buf, sizeof(tfile));
- }
- else
- if (mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), &append))
+ if (mutt_get_field (prompt, buf, sizeof (buf), M_FILE | M_CLEAR) != 0
+ || !buf[0])
return -1;
-
- mutt_message _("Saving...");
- if (mutt_save_attachment (fp, body, tfile, append, (hdr || !is_message) ? hdr : body->hdr) == 0)
- {
- mutt_message _("Attachment saved.");
- return 0;
+
+ prompt = NULL;
+ mutt_expand_path (buf, sizeof (buf));
+
+ is_message = (fp &&
+ body->hdr &&
+ body->encoding != ENCBASE64 &&
+ body->encoding != ENCQUOTEDPRINTABLE &&
+ mutt_is_message_type (body->type, body->subtype));
+
+ if (is_message)
+ {
+ struct stat st;
+
+ /* check to make sure that this file is really the one the user wants */
+ if ((rc = mutt_save_confirm (buf, &st)) == 1)
+ {
+ prompt = _("Save to file: ");
+ continue;
+ }
+ else if (rc == -1)
+ return -1;
+ strfcpy(tfile, buf, sizeof(tfile));
+ }
+ else
+ {
+ if ((rc = mutt_check_overwrite (body->filename, buf, tfile, sizeof (tfile), &append, directory)) == -1)
+ return -1;
+ else if (rc == 1)
+ {
+ prompt = _("Save to file: ");
+ continue;
+ }
+ }
+
+ mutt_message _("Saving...");
+ if (mutt_save_attachment (fp, body, tfile, append, (hdr || !is_message) ? hdr : body->hdr) == 0)
+ {
+ mutt_message _("Attachment saved.");
+ return 0;
+ }
+ else
+ {
+ prompt = _("Save to file: ");
+ continue;
+ }
}
- else
- return -1;
+ return 0;
}
-
-void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr)
+
+void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr, MUTTMENU *menu)
{
char buf[_POSIX_PATH_MAX], tfile[_POSIX_PATH_MAX];
+ char *directory = NULL;
int rc = 1;
+ int last = menu ? menu->current : -1;
FILE *fpout;
buf[0] = 0;
@@ -438,7 +469,7 @@ void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr)
return;
mutt_expand_path (buf, sizeof (buf));
if (mutt_check_overwrite (top->filename, buf, tfile,
- sizeof (tfile), &append))
+ sizeof (tfile), &append, NULL))
return;
rc = mutt_save_attachment (fp, top, tfile, append, hdr);
if (rc == 0 && AttachSep && (fpout = fopen (tfile,"a")) != NULL)
@@ -457,15 +488,37 @@ void mutt_save_attachment_list (FILE *fp, int tag, BODY *top, HEADER *hdr)
}
}
}
- else
- mutt_query_save_attachment (fp, top, hdr);
+ else
+ {
+ if (tag && menu && top->aptr)
+ {
+ menu->oldcurrent = menu->current;
+ menu->current = top->aptr->num;
+ menu_check_recenter (menu);
+ menu->redraw |= REDRAW_MOTION;
+
+ menu_redraw (menu);
+ }
+ if (mutt_query_save_attachment (fp, top, hdr, &directory) == -1)
+ break;
+ }
}
else if (top->parts)
- mutt_save_attachment_list (fp, 1, top->parts, hdr);
+ mutt_save_attachment_list (fp, 1, top->parts, hdr, menu);
if (!tag)
- return;
+ break;
}
+ FREE (&directory);
+
+ if (tag && menu)
+ {
+ menu->oldcurrent = menu->current;
+ menu->current = last;
+ menu_check_recenter (menu);
+ menu->redraw |= REDRAW_MOTION;
+ }
+
if (!option (OPTATTACHSPLIT) && (rc == 0))
mutt_message _("Attachment saved.");
}
@@ -977,9 +1030,9 @@ void mutt_view_attachments (HEADER *hdr)
case OP_SAVE:
mutt_save_attachment_list (fp, menu->tagprefix,
- menu->tagprefix ? cur : idx[menu->current]->content, hdr);
+ menu->tagprefix ? cur : idx[menu->current]->content, hdr, menu);
- if (option (OPTRESOLVE) && menu->current < menu->max - 1)
+ if (!menu->tagprefix && option (OPTRESOLVE) && menu->current < menu->max - 1)
menu->current++;
menu->redraw = REDRAW_MOTION_RESYNCH | REDRAW_FULL;
@@ -1120,6 +1173,8 @@ void mutt_view_attachments (HEADER *hdr)
continue;
if (idx[idxmax]->content && idx[idxmax]->content->deleted)
hdr->attach_del = 1;
+ if (idx[idxmax]->content)
+ idx[idxmax]->content->aptr = NULL;
FREE (&idx[idxmax]->tree);
FREE (&idx[idxmax]);
}