diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 1998-08-25 22:33:07 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 1998-08-25 22:33:07 +0000 |
commit | 986ab5e943db7aaed2aed98f8b74e4c26666fdd8 (patch) | |
tree | 58cfec1114686823dbdbf22cf2ca52f77eb1075d /attach.c | |
parent | 9044dd4d58af4b4d64a6e68b7b76c42d317e7ce5 (diff) |
CVS branch clean-up.
Diffstat (limited to 'attach.c')
-rw-r--r-- | attach.c | 272 |
1 files changed, 179 insertions, 93 deletions
@@ -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); |