summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>1998-11-15 09:34:15 +0000
committerThomas Roessler <roessler@does-not-exist.org>1998-11-15 09:34:15 +0000
commit8fa824fc79c18c4621c6fbb8c88ce45716ac3a6e (patch)
tree969aa07d998dd2783f419bf44431a7083e316a73
parentb7dffe977f2f92adb01e29caa8b2b24b27d439fe (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.c4
-rw-r--r--copy.c84
-rw-r--r--mutt.h1
-rw-r--r--protos.h2
-rw-r--r--recvattach.c93
5 files changed, 93 insertions, 91 deletions
diff --git a/compose.c b/compose.c
index 235f1cbf..d35c9be8 100644
--- a/compose.c
+++ b/compose.c
@@ -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;
}
diff --git a/copy.c b/copy.c
index bc2a80e9..e38b08e0 100644
--- a/copy.c
+++ b/copy.c
@@ -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;
}
}
diff --git a/mutt.h b/mutt.h
index 13b8346e..cf96ad00 100644
--- a/mutt.h
+++ b/mutt.h
@@ -640,6 +640,7 @@ typedef struct
typedef struct attachptr
{
BODY *content;
+ int parent_type;
char *tree;
int level;
int num;
diff --git a/protos.h b/protos.h
index e033b58d..dc8cf314 100644
--- a/protos.h
+++ b/protos.h
@@ -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)