summaryrefslogtreecommitdiffstats
path: root/attach.c
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>1998-08-25 22:33:07 +0000
committerThomas Roessler <roessler@does-not-exist.org>1998-08-25 22:33:07 +0000
commit986ab5e943db7aaed2aed98f8b74e4c26666fdd8 (patch)
tree58cfec1114686823dbdbf22cf2ca52f77eb1075d /attach.c
parent9044dd4d58af4b4d64a6e68b7b76c42d317e7ce5 (diff)
CVS branch clean-up.
Diffstat (limited to 'attach.c')
-rw-r--r--attach.c272
1 files changed, 179 insertions, 93 deletions
diff --git a/attach.c b/attach.c
index 4345d093..d0a887e1 100644
--- a/attach.c
+++ b/attach.c
@@ -23,12 +23,20 @@
#include "rfc1524.h"
#include "mime.h"
#include "pager.h"
+#include "mailbox.h"
+#include "copy.h"
+#include "mx.h"
+
+#ifdef _PGPPATH
+#include "pgp.h"
+#endif
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include <string.h>
#include <errno.h>
@@ -37,14 +45,16 @@ int mutt_compose_attachment (BODY *a)
{
char type[STRING];
char command[STRING];
+ char newfile[_POSIX_PATH_MAX] = "";
rfc1524_entry *entry = rfc1524_new_entry ();
-
- snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+ short unlink_newfile = 0;
+ int rc = 0;
+
+ snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
if (rfc1524_mailcap_lookup (a, type, entry, M_COMPOSE))
{
if (entry->composecommand || entry->composetypecommand)
{
- char newfile[_POSIX_PATH_MAX] = "";
if (entry->composetypecommand)
strfcpy (command, entry->composetypecommand, sizeof (command));
@@ -55,19 +65,17 @@ int mutt_compose_attachment (BODY *a)
{
dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",
a->filename, newfile));
- if (!mutt_rename_file (a->filename, newfile))
+ if (symlink (a->filename, newfile) == -1)
{
if (!mutt_yesorno ("Can't match nametemplate, continue?", 1))
- return 0;
- }
- else
- {
- safe_free ((void **) &a->filename);
- a->filename = safe_strdup (newfile);
+ goto bailout;
}
+ unlink_newfile = 1;
}
-
- if (rfc1524_expand_command (a, a->filename, type,
+ else
+ strfcpy(newfile, a->filename, sizeof(newfile));
+
+ if (rfc1524_expand_command (a, newfile, type,
command, sizeof (command)))
{
/* For now, editing requires a file, no piping */
@@ -86,7 +94,7 @@ int mutt_compose_attachment (BODY *a)
if ((fp = safe_fopen (a->filename, "r")) == NULL)
{
mutt_perror ("Failure to open file to parse headers.");
- return 0;
+ goto bailout;
}
b = mutt_read_mime_header (fp, 0);
@@ -117,7 +125,7 @@ int mutt_compose_attachment (BODY *a)
if ((tfp = safe_fopen (tempfile, "w")) == NULL)
{
mutt_perror ("Failure to open file to strip headers.");
- return 0;
+ goto bailout;
}
mutt_copy_stream (fp, tfp);
fclose (fp);
@@ -138,8 +146,15 @@ int mutt_compose_attachment (BODY *a)
return 1;
}
+ rc = 1;
+
+ bailout:
+
+ if(unlink_newfile)
+ unlink(newfile);
+
rfc1524_free_entry (&entry);
- return 1;
+ return rc;
}
/*
@@ -151,18 +166,20 @@ int mutt_compose_attachment (BODY *a)
* Returns 1 if editor found, 0 if not (useful to tell calling menu to
* redraw)
*/
-int mutt_edit_attachment (BODY *a, int opt)
+int mutt_edit_attachment (BODY *a)
{
char type[STRING];
char command[STRING];
+ char newfile[_POSIX_PATH_MAX] = "";
rfc1524_entry *entry = rfc1524_new_entry ();
-
- snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+ short unlink_newfile = 0;
+ int rc = 0;
+
+ snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
if (rfc1524_mailcap_lookup (a, type, entry, M_EDIT))
{
if (entry->editcommand)
{
- char newfile[_POSIX_PATH_MAX] = "";
strfcpy (command, entry->editcommand, sizeof (command));
if (rfc1524_expand_filename (entry->nametemplate,
@@ -170,19 +187,17 @@ int mutt_edit_attachment (BODY *a, int opt)
{
dprint(1, (debugfile, "oldfile: %s\t newfile: %s\n",
a->filename, newfile));
- if (mutt_rename_file (a->filename, newfile))
+ if (symlink (a->filename, newfile) == -1)
{
if (!mutt_yesorno ("Can't match nametemplate, continue?", 1))
- return 0;
- }
- else
- {
- safe_free ((void **) &a->filename);
- a->filename = safe_strdup (newfile);
+ goto bailout;
}
+ unlink_newfile = 1;
}
+ else
+ strfcpy(newfile, a->filename, sizeof(newfile));
- if (rfc1524_expand_command (a, a->filename, type,
+ if (rfc1524_expand_command (a, newfile, type,
command, sizeof (command)))
{
/* For now, editing requires a file, no piping */
@@ -198,8 +213,8 @@ int mutt_edit_attachment (BODY *a, int opt)
else if (a->type == TYPETEXT)
{
/* On text, default to editor */
- mutt_edit_file (strcmp ("builtin", Editor) == 0 ? Visual : Editor,
- a->filename);
+ mutt_edit_file ((!Editor || strcmp ("builtin", Editor) == 0) ?
+ NONULL(Visual) : NONULL(Editor), newfile);
}
else
{
@@ -208,8 +223,15 @@ int mutt_edit_attachment (BODY *a, int opt)
return 0;
}
+ rc = 1;
+
+ bailout:
+
+ if(unlink_newfile)
+ unlink(newfile);
+
rfc1524_free_entry (&entry);
- return 1;
+ return rc;
}
int mutt_is_autoview (char *type)
@@ -242,15 +264,19 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
char type[STRING];
char command[STRING];
char descrip[STRING];
+ char *fname;
rfc1524_entry *entry = NULL;
int rc = -1;
-
- is_message = (a->type == TYPEMESSAGE && a->subtype &&
- (!strcasecmp (a->subtype,"rfc822") ||
- !strcasecmp (a->subtype, "news")));
+ int unlink_tempfile = 0;
+
+ is_message = mutt_is_message_type(a->type, a->subtype);
+#ifdef _PGPPATH
+ if (is_message && (a->hdr->pgp & PGPENCRYPT) && !pgp_valid_passphrase())
+ return (rc);
+#endif /* _PGPPATH */
use_mailcap = (flag == M_MAILCAP ||
(flag == M_REGULAR && mutt_needs_mailcap (a)));
- snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+ snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
if (use_mailcap)
{
@@ -279,13 +305,21 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
}
strfcpy (command, entry->command, sizeof (command));
- if (rfc1524_expand_filename (entry->nametemplate, a->filename,
+ if (fp)
+ {
+ fname = safe_strdup (a->filename);
+ mutt_sanitize_filename (fname);
+ }
+ else
+ fname = a->filename;
+
+ if (rfc1524_expand_filename (entry->nametemplate, fname,
tempfile, sizeof (tempfile)))
{
if (fp == NULL)
{
/* send case: the file is already there */
- if (mutt_rename_file (a->filename, tempfile))
+ if (symlink (a->filename, tempfile) == -1)
{
if (mutt_yesorno ("Can't match nametemplate, continue?", 1) == M_YES)
strfcpy (tempfile, a->filename, sizeof (tempfile));
@@ -293,19 +327,17 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
goto return_error;
}
else
- {
- safe_free ((void **) &a->filename);
- a->filename = safe_strdup (tempfile);
- }
+ unlink_tempfile = 1;
}
}
else if (fp == NULL) /* send case */
strfcpy (tempfile, a->filename, sizeof (tempfile));
-
+
if (fp)
{
/* recv case: we need to save the attachment to a file */
- if (mutt_save_attachment (fp, a, tempfile, 0) == -1)
+ FREE (&fname);
+ if (mutt_save_attachment (fp, a, tempfile, 0, NULL) == -1)
goto return_error;
}
@@ -320,7 +352,7 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
{
/* recv case */
strfcpy (pagerfile, a->filename, sizeof (pagerfile));
- mutt_adv_mktemp (pagerfile);
+ mutt_adv_mktemp (pagerfile, sizeof(pagerfile));
}
else
mutt_mktemp (pagerfile);
@@ -402,7 +434,7 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
if (flag == M_AS_TEXT)
{
/* just let me see the raw data */
- if (mutt_save_attachment (fp, a, pagerfile, 0))
+ if (mutt_save_attachment (fp, a, pagerfile, 0, NULL))
goto return_error;
}
else
@@ -448,6 +480,9 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
rfc1524_free_entry (&entry);
if (fp && tempfile[0])
mutt_unlink (tempfile);
+ else if (unlink_tempfile)
+ unlink(tempfile);
+
if (pagerfile[0])
mutt_unlink (pagerfile);
@@ -457,15 +492,13 @@ int mutt_view_attachment (FILE *fp, BODY *a, int flag)
/* returns 1 on success, 0 on error */
int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
{
- STATE o;
pid_t thepid;
-
- memset (&o, 0, sizeof (STATE));
+ int out = -1;
if (outfile && *outfile)
- if ((o.fpout = safe_fopen (outfile, "w")) == NULL)
+ if ((out = safe_open (outfile, O_CREAT | O_EXCL | O_WRONLY)) < 0)
{
- mutt_perror ("fopen");
+ mutt_perror ("open");
return 0;
}
@@ -480,7 +513,7 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
memset (&s, 0, sizeof (STATE));
if (outfile && *outfile)
- thepid = mutt_create_filter (path, &s.fpout, &o.fpin, NULL);
+ thepid = mutt_create_filter_fd (path, &s.fpout, NULL, NULL, -1, out, -1);
else
thepid = mutt_create_filter (path, &s.fpout, NULL, NULL);
@@ -497,12 +530,16 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
if ((ifp = fopen (b->filename, "r")) == NULL)
{
mutt_perror ("fopen");
- fclose (o.fpout);
+ if (outfile && *outfile)
+ {
+ close (out);
+ unlink (outfile);
+ }
return 0;
}
if (outfile && *outfile)
- thepid = mutt_create_filter (path, &ofp, &o.fpin, NULL);
+ thepid = mutt_create_filter_fd (path, &ofp, NULL, NULL, -1, out, -1);
else
thepid = mutt_create_filter (path, &ofp, NULL, NULL);
@@ -512,11 +549,7 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
}
if (outfile && *outfile)
- {
- mutt_copy_stream (o.fpin, o.fpout);
- fclose (o.fpin);
- fclose (o.fpout);
- }
+ close (out);
if (mutt_wait_filter (thepid) != 0 || option (OPTWAITKEY))
mutt_any_key_to_continue (NULL);
@@ -524,31 +557,76 @@ int mutt_pipe_attachment (FILE *fp, BODY *b, const char *path, char *outfile)
}
/* returns 0 on success, -1 on error */
-int mutt_save_attachment (FILE *fp, BODY *m, char *path, int flags)
+int mutt_save_attachment (FILE *fp, BODY *m, char *path, int flags, HEADER *hdr)
{
if (fp)
{
- /* In recv mode, extract from folder and decode */
+
+ /* recv mode */
- STATE s;
-
- memset (&s, 0, sizeof (s));
- if (flags == M_SAVE_APPEND)
- s.fpout = safe_fopen (path, "a");
- else
- s.fpout = fopen (path, "w");
- if (s.fpout == NULL)
+ if(hdr &&
+ m->hdr &&
+ m->encoding != ENCBASE64 &&
+ m->encoding != ENCQUOTEDPRINTABLE &&
+ mutt_is_message_type(m->type, m->subtype))
{
- mutt_perror ("fopen");
- return (-1);
+ /* message type attachments are written to mail folders. */
+
+ char buf[HUGE_STRING];
+ HEADER *hn;
+ CONTEXT ctx;
+ MESSAGE *msg;
+ int chflags = 0;
+ int r = -1;
+
+ hn = m->hdr;
+ hn->msgno = hdr->msgno; /* required for MH/maildir */
+ hn->read = 1;
+
+ fseek (fp, m->offset, 0);
+ if (fgets (buf, sizeof (buf), fp) == NULL)
+ return -1;
+ if (mx_open_mailbox(path, M_APPEND | M_QUIET, &ctx) == NULL)
+ return -1;
+ if ((msg = mx_open_new_message (&ctx, hn, is_from (buf, NULL, 0) ? 0 : M_ADD_FROM)) == NULL)
+ {
+ mx_close_mailbox(&ctx);
+ return -1;
+ }
+ if (ctx.magic == M_MBOX || ctx.magic == M_MMDF)
+ chflags = CH_FROM;
+ chflags |= (ctx.magic == M_MAILDIR ? CH_NOSTATUS : CH_UPDATE);
+ if ((r = _mutt_copy_message (msg->fp, fp, hn, hn->content, 0, chflags)) == 0)
+ mutt_message("Attachment saved.");
+
+ mx_close_message (&msg);
+ mx_close_mailbox(&ctx);
+ return r;
}
- fseek ((s.fpin = fp), m->offset, 0);
- mutt_decode_attachment (m, &s);
-
- if (fclose (s.fpout) != 0)
+ else
{
- mutt_perror ("fclose");
- return (-1);
+ /* In recv mode, extract from folder and decode */
+
+ STATE s;
+
+ memset (&s, 0, sizeof (s));
+ if (flags == M_SAVE_APPEND)
+ s.fpout = safe_fopen (path, "a");
+ else
+ s.fpout = fopen (path, "w");
+ if (s.fpout == NULL)
+ {
+ mutt_perror ("fopen");
+ return (-1);
+ }
+ fseek ((s.fpin = fp), m->offset, 0);
+ mutt_decode_attachment (m, &s);
+
+ if (fclose (s.fpout) != 0)
+ {
+ mutt_perror ("fclose");
+ return (-1);
+ }
}
}
else
@@ -590,6 +668,8 @@ int mutt_decode_save_attachment (FILE *fp, BODY *m, char *path,
{
STATE s;
unsigned int saved_encoding = 0;
+ BODY *saved_parts = NULL;
+ HEADER *saved_hdr = NULL;
memset (&s, 0, sizeof (s));
s.flags = displaying ? M_DISPLAY : 0;
@@ -627,10 +707,12 @@ int mutt_decode_save_attachment (FILE *fp, BODY *m, char *path,
m->length = st.st_size;
m->encoding = ENC8BIT;
m->offset = 0;
- if (m->type == TYPEMESSAGE && m->subtype &&
- (!strcasecmp (m->subtype,"rfc822") ||
- !strcasecmp (m->subtype, "news")))
+ if (mutt_is_message_type(m->type, m->subtype))
+ {
+ saved_parts = m->parts;
+ saved_hdr = m->hdr;
m->parts = mutt_parse_messageRFC822 (s.fpin, m);
+ }
}
else
s.fpin = fp;
@@ -642,8 +724,12 @@ int mutt_decode_save_attachment (FILE *fp, BODY *m, char *path,
{
m->length = 0;
m->encoding = saved_encoding;
- if (m->parts)
- mutt_free_body (&m->parts);
+ if (saved_parts)
+ {
+ mutt_free_header (&m->hdr);
+ m->parts = saved_parts;
+ m->hdr = saved_hdr;
+ }
fclose (s.fpin);
}
@@ -663,8 +749,9 @@ int mutt_print_attachment (FILE *fp, BODY *a)
char type[STRING];
pid_t thepid;
FILE *ifp, *fpout;
-
- snprintf (type, sizeof (type), "%s/%s", TYPE (a->type), a->subtype);
+ short unlink_newfile = 0;
+
+ snprintf (type, sizeof (type), "%s/%s", TYPE (a), a->subtype);
if (rfc1524_mailcap_lookup (a, type, NULL, M_PRINT))
{
@@ -679,9 +766,7 @@ int mutt_print_attachment (FILE *fp, BODY *a)
{
if (!fp)
{
- /* only attempt file move in send mode */
-
- if (mutt_rename_file (a->filename, newfile))
+ if (symlink(a->filename, newfile) == -1)
{
if (mutt_yesorno ("Can't match nametemplate, continue?", 1) != M_YES)
{
@@ -691,16 +776,13 @@ int mutt_print_attachment (FILE *fp, BODY *a)
strfcpy (newfile, a->filename, sizeof (newfile));
}
else
- {
- safe_free ((void **)&a->filename);
- a->filename = safe_strdup (newfile);
- }
+ unlink_newfile = 1;
}
}
/* in recv mode, save file to newfile first */
if (fp)
- mutt_save_attachment (fp, a, newfile, 0);
+ mutt_save_attachment (fp, a, newfile, 0, NULL);
strfcpy (command, entry->printcommand, sizeof (command));
piped = rfc1524_expand_command (a, newfile, type, command, sizeof (command));
@@ -732,6 +814,8 @@ int mutt_print_attachment (FILE *fp, BODY *a)
if (fp)
mutt_unlink (newfile);
+ else if (unlink_newfile)
+ unlink(newfile);
rfc1524_free_entry (&entry);
return (1);
@@ -739,7 +823,9 @@ int mutt_print_attachment (FILE *fp, BODY *a)
if (!strcasecmp ("text/plain", a->subtype) ||
!strcasecmp ("application/postscript", a->subtype))
- return (mutt_pipe_attachment (fp, a, PrintCmd, NULL));
+ {
+ return (mutt_pipe_attachment (fp, a, NONULL(PrintCmd), NULL));
+ }
else if (mutt_can_decode (a))
{
/* decode and print */
@@ -752,7 +838,7 @@ int mutt_print_attachment (FILE *fp, BODY *a)
if ((ifp = fopen (newfile, "r")) != NULL)
{
endwin ();
- thepid = mutt_create_filter (PrintCmd, &fpout, NULL, NULL);
+ thepid = mutt_create_filter (NONULL(PrintCmd), &fpout, NULL, NULL);
mutt_copy_stream (ifp, fpout);
fclose (ifp);
fclose (fpout);