diff options
author | Thomas Roessler <roessler@does-not-exist.org> | 1998-11-15 09:34:15 +0000 |
---|---|---|
committer | Thomas Roessler <roessler@does-not-exist.org> | 1998-11-15 09:34:15 +0000 |
commit | 8fa824fc79c18c4621c6fbb8c88ce45716ac3a6e (patch) | |
tree | 969aa07d998dd2783f419bf44431a7083e316a73 | |
parent | b7dffe977f2f92adb01e29caa8b2b24b27d439fe (diff) |
I can elaborate a little more on the last paragraph. It is deletion
of the top level part direct under a message/rfc822 part which
gives problems because the headers of the message/rfc822 part have
to be changed in this case. It is hard to tell exactly how many
bytes and lines will be removed and added in this case.
If we can refrain from deletion of such parts and thus only allow
deletion of parts direct under a multipart part, then it is
relative easy always to make correct Content-Length: and Lines:
headers in the copy. (The correctness of the Lines count is
dependent of the correctness of the initial value, though).
(From: Byrial Jensen)
-rw-r--r-- | compose.c | 4 | ||||
-rw-r--r-- | copy.c | 84 | ||||
-rw-r--r-- | mutt.h | 1 | ||||
-rw-r--r-- | protos.h | 2 | ||||
-rw-r--r-- | recvattach.c | 93 |
5 files changed, 93 insertions, 91 deletions
@@ -383,7 +383,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */ int oldSort = Sort, oldSortAux = SortAux; struct stat st; - idx = mutt_gen_attach_list (msg->content, idx, &idxlen, &idxmax, 0, 1); + idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1); menu = mutt_new_menu (); menu->menu = MENU_COMPOSE; @@ -477,7 +477,7 @@ int mutt_compose_menu (HEADER *msg, /* structure for new message */ for (i = 0; i < idxlen; i++) safe_free ((void **) &idx[i]); idxlen = 0; - idx = mutt_gen_attach_list (msg->content, idx, &idxlen, &idxmax, 0, 1); + idx = mutt_gen_attach_list (msg->content, -1, idx, &idxlen, &idxmax, 0, 1); menu->data = idx; menu->max = idxlen; } @@ -36,7 +36,7 @@ static const char rcsid[]="$Id$"; extern char MimeSpecials[]; -static int copy_delete_attach (BODY *b, FILE *fpin, FILE *fpout); +static int copy_delete_attach (BODY *b, FILE *fpin, FILE *fpout, char *date); /* Ok, the only reason for not merging this with mutt_copy_header() * below is to avoid creating a HEADER structure in message_handler(). @@ -360,8 +360,8 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix) return (0); } -/* Count the number of lines to be deleted in this body*/ -static int count_delete_lines (FILE *fp, BODY *b) +/* Count the number of lines and bytes to be deleted in this body*/ +static int count_delete_lines (FILE *fp, BODY *b, long *length, size_t datelen) { int dellines = 0; long l; @@ -378,13 +378,16 @@ static int count_delete_lines (FILE *fp, BODY *b) if (ch == '\n') dellines ++; } - /* Add lines to a new message/external-body part */ dellines -= 3; + *length -= b->length - (84 + datelen); + /* Count the number of digits exceeding the first one to write the size */ + for (l = 10 ; b->length >= l ; l *= 10) + (*length) ++; } else { for (b = b->parts ; b ; b = b->next) - dellines += count_delete_lines (fp, b); + dellines += count_delete_lines (fp, b, length, datelen); } return dellines; } @@ -424,37 +427,55 @@ _mutt_copy_message (FILE *fpout, FILE *fpin, HEADER *hdr, BODY *body, { int new_lines; long new_offset; + long new_length = body->length; + char date[SHORT_STRING]; - /* Count the number of lines to be deleted */ + mutt_make_date (date, sizeof (date)); + date[5] = date[mutt_strlen (date) - 1] = '\"'; + + /* Count the number of lines and bytes to be deleted */ fseek (fpin, body->offset, SEEK_SET); - new_lines = hdr->lines - count_delete_lines (fpin, body); - if (new_lines < 0) - new_lines = 0; + new_lines = hdr->lines - + count_delete_lines (fpin, body, &new_length, mutt_strlen (date)); /* Copy the headers */ if (mutt_copy_header (fpin, hdr, fpout, chflags | CH_NOLEN | CH_NONEWLINE, NULL)) return -1; - if (new_lines) - { + fprintf (fpout, "Content-Length: %ld\n", new_length); + if (new_lines <= 0) + new_lines = 0; + else fprintf (fpout, "Lines: %d\n\n", new_lines); - if (ferror (fpout)) - return -1; - } + if (ferror (fpout)) + return -1; new_offset = ftell (fpout); /* Copy the body */ fseek (fpin, body->offset, SEEK_SET); - if (copy_delete_attach (body, fpin, fpout)) + if (copy_delete_attach (body, fpin, fpout, date)) return -1; +#ifdef DEBUG + { + long fail = ((ftell (fpout) - new_offset) - new_length); + + if (fail) + { + mutt_error ("The length calculation was wrong by %ld bytes", fail); + new_length += fail; + sleep (5); + } + } +#endif + /* Update original message if we are sync'ing a mailfolder */ if (flags & M_CM_UPDATE) { hdr->attach_del = 0; hdr->lines = new_lines; body->offset = new_offset; - body->length = ftell (fpout) - new_offset; + body->length = new_length; mutt_free_body (&body->parts); } @@ -596,13 +617,9 @@ mutt_append_message (CONTEXT *dest, CONTEXT *src, HEADER *hdr, int cmflags, * * The function will return 0 on success and -1 on failure. */ -static int copy_delete_attach (BODY *b, FILE *fpin, FILE *fpout) +static int copy_delete_attach (BODY *b, FILE *fpin, FILE *fpout, char *date) { BODY *part; - char date[SHORT_STRING]; - - mutt_make_date (date, sizeof (date)); - date[5] = date[mutt_strlen (date) - 1] = '\"'; for (part = b->parts ; part ; part = part->next) { @@ -628,32 +645,9 @@ static int copy_delete_attach (BODY *b, FILE *fpin, FILE *fpout) /* Skip the deleted body */ fseek (fpin, part->offset + part->length, SEEK_SET); } - else if (part->hdr && part->parts->deleted) - { - /* Here we have a message which only part is deleted. */ - /* First copy it's mime headers */ - if (mutt_copy_bytes (fpin, fpout, part->offset - ftell (fpin))) - return -1; - - /* Then change the only parts Content-Type. */ - if (mutt_copy_header (fpin, part->hdr, fpout, - CH_MIME | CH_NOLEN | CH_NONEWLINE, NULL)) - return -1; - fprintf (fpout, - "Mime-Version: 1.0\n" - "Content-Type: message/external-body; access-type=x-mutt-deleted;\n" - "\texpiration=%s; length=%ld\n" - "\n", date + 5, part->parts->length); - - /* And output the mime headers of the deleted part */ - mutt_write_mime_header (part->parts, fpout); - - /* Skip the deleted body */ - fseek (fpin, part->offset + part->length, SEEK_SET); - } else { - if (copy_delete_attach (part, fpin, fpout)) + if (copy_delete_attach (part, fpin, fpout, date)) return -1; } } @@ -640,6 +640,7 @@ typedef struct typedef struct attachptr { BODY *content; + int parent_type; char *tree; int level; int num; @@ -90,7 +90,7 @@ BODY *mutt_read_mime_header (FILE *, int); ENVELOPE *mutt_read_rfc822_header (FILE *, HEADER *, short); HEADER *mutt_dup_header (HEADER *); -ATTACHPTR **mutt_gen_attach_list (BODY *, ATTACHPTR **, short *, short *, int, int); +ATTACHPTR **mutt_gen_attach_list (BODY *, int, ATTACHPTR **, short *, short *, int, int); time_t mutt_local_tz (void); time_t mutt_mktime (struct tm *, int); diff --git a/recvattach.c b/recvattach.c index f3899c4c..ac6b16de 100644 --- a/recvattach.c +++ b/recvattach.c @@ -97,6 +97,7 @@ void mutt_update_tree (ATTACHPTR **idx, short idxlen) } ATTACHPTR **mutt_gen_attach_list (BODY *m, + int parent_type, ATTACHPTR **idx, short *idxlen, short *idxmax, @@ -116,18 +117,19 @@ ATTACHPTR **mutt_gen_attach_list (BODY *m, #endif ) { - idx = mutt_gen_attach_list (m->parts, idx, idxlen, idxmax, level, compose); + idx = mutt_gen_attach_list (m->parts, m->type, idx, idxlen, idxmax, level, compose); } else { new = idx[(*idxlen)++] = (ATTACHPTR *) safe_calloc (1, sizeof (ATTACHPTR)); new->content = m; + new->parent_type = parent_type; new->level = level; /* We don't support multipart messages in the compose menu yet */ if (!compose && mutt_is_message_type(m->type, m->subtype)) { - idx = mutt_gen_attach_list (m->parts, idx, idxlen, idxmax, level + 1, compose); + idx = mutt_gen_attach_list (m->parts, m->type, idx, idxlen, idxmax, level + 1, compose); } } } @@ -845,7 +847,7 @@ void mutt_view_attachments (HEADER *hdr) cur = hdr->content; } - idx = mutt_gen_attach_list (cur, idx, &idxlen, &idxmax, 0, 0); + idx = mutt_gen_attach_list (cur, -1, idx, &idxlen, &idxmax, 0, 0); menu = mutt_new_menu (); menu->max = idxlen; @@ -905,48 +907,53 @@ void mutt_view_attachments (HEADER *hdr) case OP_DELETE: - if (menu->max == 1) - { - mutt_message _("Only deletion of multipart attachments is supported."); - } - else - { #ifdef _PGPPATH - if (hdr->pgp) - { - mutt_message _( - "Deletion of attachments from PGP messages is unsupported."); - } - else + if (hdr->pgp) + { + mutt_message _( + "Deletion of attachments from PGP messages is unsupported."); + } + else #endif - { - if (!menu->tagprefix) - { - idx[menu->current]->content->deleted = 1; - if (option (OPTRESOLVE) && menu->current < menu->max - 1) - { - menu->current++; - menu->redraw = REDRAW_MOTION_RESYNCH; - } - else - menu->redraw = REDRAW_CURRENT; - } - else - { - int x; - - for (x = 0; x < menu->max; x++) - { - if (idx[x]->content->tagged) - { - idx[x]->content->deleted = 1; - menu->redraw = REDRAW_INDEX; - } - } - } - } - } - break; + { + if (!menu->tagprefix) + { + if (idx[menu->current]->parent_type == TYPEMULTIPART) + { + idx[menu->current]->content->deleted = 1; + if (option (OPTRESOLVE) && menu->current < menu->max - 1) + { + menu->current++; + menu->redraw = REDRAW_MOTION_RESYNCH; + } + else + menu->redraw = REDRAW_CURRENT; + } + else + mutt_message _( + "Only deletion of multipart attachments is supported."); + } + else + { + int x; + + for (x = 0; x < menu->max; x++) + { + if (idx[x]->content->tagged) + { + if (idx[x]->parent_type == TYPEMULTIPART) + { + idx[x]->content->deleted = 1; + menu->redraw = REDRAW_INDEX; + } + else + mutt_message _( + "Only deletion of multipart attachments is supported."); + } + } + } + } + break; case OP_UNDELETE: if (!menu->tagprefix) |