summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEduardo Chappa <chappa@washington.edu>2020-06-28 19:59:24 -0600
committerEduardo Chappa <chappa@washington.edu>2020-06-28 19:59:24 -0600
commit33d28e5ec670e974d555bcee34a631d878fda84c (patch)
treeaa7ae348de2b154d6b8340e50eea121026a137d5
parent8140a5ad34cd4545d87314a94a00a2b660fc441a (diff)
downloadalpine-33d28e5ec670e974d555bcee34a631d878fda84c.tar.xz
* When an attachment is deleted and the original message is saved, Alpine
might write only a part of the name of the file deleted. Reported by Holger Trapp.
-rw-r--r--pith/pine.hlp6
-rw-r--r--pith/save.c154
2 files changed, 110 insertions, 50 deletions
diff --git a/pith/pine.hlp b/pith/pine.hlp
index cdd0cae6..84cfe722 100644
--- a/pith/pine.hlp
+++ b/pith/pine.hlp
@@ -140,7 +140,7 @@ with help text for the config screen and the composer that didn't have any
reasonable place to be called from.
Dummy change to get revision in pine.hlp
============= h_revision =================
-Alpine Commit 466 2020-06-28 14:06:09
+Alpine Commit 467 2020-06-28 19:55:50
============= h_news =================
<HTML>
<HEAD>
@@ -216,6 +216,10 @@ Bugs addressed:
Alpine would return to the first folder in the parent directory or to
the dual-folder. The fix is to return to the original dual-folder as
intended. Reported by Holger Trapp.
+
+<LI> When an attachment is deleted and the original message is saved, Alpine
+ might write only a part of the name of the file deleted. Reported by Holger
+ Trapp.
</UL>
<P>
diff --git a/pith/save.c b/pith/save.c
index 61ac3f53..4592a949 100644
--- a/pith/save.c
+++ b/pith/save.c
@@ -48,6 +48,7 @@ int save_ex_mask_types(char *, unsigned long *, gf_io_t);
int save_ex_explain_body(BODY *, unsigned long *, gf_io_t);
int save_ex_explain_parts(BODY *, int, unsigned long *, gf_io_t);
int save_ex_output_line(char *, unsigned long *, gf_io_t);
+int save_ex_output_text(char *, int, unsigned long *, gf_io_t);
/*
@@ -1612,8 +1613,8 @@ save_ex_explain_body(struct mail_bodystruct *body, long unsigned int *len, gf_io
int
save_ex_explain_parts(struct mail_bodystruct *body, int depth, long unsigned int *len, gf_io_t pc)
{
- char tmp[MAILTMPLEN], buftmp[MAILTMPLEN];
- unsigned long ilen;
+ char *tmp, namebuf[MAILTMPLEN], descbuf[MAILTMPLEN];
+ unsigned long ilen, tmplen;
char *name = parameter_val(body->parameter, "name");
if(!name){
@@ -1621,39 +1622,46 @@ save_ex_explain_parts(struct mail_bodystruct *body, int depth, long unsigned int
!strucmp(body->disposition.type, "ATTACHMENT"))
name = parameter_val(body->disposition.parameter, "filename");
}
+ if(name)
+ rfc1522_decode_to_utf8((unsigned char *)namebuf, sizeof(namebuf), name);
+ if(body->description && *body->description)
+ rfc1522_decode_to_utf8((unsigned char *)descbuf, sizeof(descbuf), body->description);
+
+ ilen = 0;
if(body->type == TYPEMULTIPART) { /* multipart gets special handling */
PART *part = body->nested.part; /* first body part */
*len = 0;
- if(body->description && *body->description){ /* MAILTMPLEN = sizeof(tmp) */
- snprintf(tmp, sizeof(tmp), "%*.*sA %s/%.*s%.10s%.100s%.10s segment described",
- depth, depth, " ", body_type_names(body->type),
- MAILTMPLEN-300, body->subtype ? body->subtype : "Unknown",
- name ? " (Name=\"" : "",
- name ? (char *) rfc1522_decode_to_utf8((unsigned char *)tmp_20k_buf,
- SIZEOF_20KBUF, name) : "",
- name ? "\")" : "");
- if(!save_ex_output_line(tmp, len, pc))
+ if(body->description && *body->description){
+ tmplen = strlen(_("A ")) + strlen(body_type_names(body->type)) + 1
+ + strlen(body->subtype ? body->subtype : "Unknown")
+ + strlen(name ? " (Name=\"" : "")
+ + strlen(name ? namebuf : "")
+ + strlen(name ? "\"" : "") + strlen(_(" segment described as "))
+ + strlen(descbuf) + strlen(_(" containing:")) + 1;
+ tmp = fs_get((tmplen + 1)*sizeof(char));
+ sprintf(tmp, "%s%s/%s%s%s%s%s%s%s", _("A "),
+ body_type_names(body->type), body->subtype ? body->subtype : "Unknown",
+ name ? " (Name=\"" : "", name ? namebuf : "", name ? "\")" : "",
+ _(" segment described as "), descbuf, _(" containing:"));
+ if(!save_ex_output_text(tmp, depth, len, pc))
return(0);
-
- snprintf(buftmp, sizeof(buftmp), "%.75s", body->description);
- snprintf(tmp, sizeof(tmp), "%*.*s as \"%.50s\" containing:", depth, depth, " ",
- (char *) rfc1522_decode_to_utf8((unsigned char *)tmp_20k_buf,
- SIZEOF_20KBUF, buftmp));
}
- else{ /* MAILTMPLEN = sizeof(tmp) */
- snprintf(tmp, sizeof(tmp), "%*.*sA %s/%.*s%.10s%.100s%.10s segment containing:",
- depth, depth, " ",
- body_type_names(body->type),
- MAILTMPLEN-300, body->subtype ? body->subtype : "Unknown",
- name ? " (Name=\"" : "",
- name ? (char *) rfc1522_decode_to_utf8((unsigned char *)tmp_20k_buf,
- SIZEOF_20KBUF, name) : "",
- name ? "\")" : "");
+ else{
+ tmplen = strlen(_("A ")) + strlen(body_type_names(body->type)) + 1
+ + strlen(body->subtype ? body->subtype : "Unknown")
+ + strlen(name ? " (Name=\"" : "")
+ + strlen(name ? namebuf : "")
+ + strlen(name ? "\"" : "") + strlen(_(" segment containing:")) + 1;
+ tmp = fs_get((tmplen + 1)*sizeof(char));
+ sprintf(tmp, "%s%s/%s%s%s%s%s", _("A "),
+ body_type_names(body->type), body->subtype ? body->subtype : "Unknown",
+ name ? " (Name=\"" : "", name ? namebuf : "", name ? "\")" : "",
+ _(" segment containing:"));
}
- if(save_ex_output_line(tmp, &ilen, pc))
+ if(save_ex_output_text(tmp, depth, &ilen, pc))
*len += ilen;
else
return(0);
@@ -1666,38 +1674,86 @@ save_ex_explain_parts(struct mail_bodystruct *body, int depth, long unsigned int
return(0);
while ((part = part->next) != NULL); /* until done */
}
- else{ /* MAILTMPLEN = sizeof(tmp) */
- snprintf(tmp, sizeof(tmp), "%*.*sA %s/%.*s%.10s%.100s%.10s segment of about %s bytes%s",
- depth, depth, " ",
- body_type_names(body->type),
- MAILTMPLEN-300, body->subtype ? body->subtype : "Unknown",
- name ? " (Name=\"" : "",
- name ? (char *) rfc1522_decode_to_utf8((unsigned char *)tmp_20k_buf,
- SIZEOF_20KBUF, name) : "",
- name ? "\")" : "",
- comatose((body->encoding == ENCBASE64)
+ else{
+ char *comatosep = comatose((body->encoding == ENCBASE64)
? ((body->size.bytes * 3)/4)
- : body->size.bytes),
- body->description ? "," : ".");
- if(!save_ex_output_line(tmp, len, pc))
- return(0);
-
- if(body->description && *body->description){ /* MAILTMPLEN = sizeof(tmp) */
- snprintf(buftmp, sizeof(buftmp), "%.75s", body->description);
- snprintf(tmp, sizeof(tmp), "%*.*s described as \"%.*s\"", depth, depth, " ",
- MAILTMPLEN-100,
- (char *) rfc1522_decode_to_utf8((unsigned char *)tmp_20k_buf,
- SIZEOF_20KBUF, buftmp));
- if(save_ex_output_line(tmp, &ilen, pc))
+ : body->size.bytes);
+ tmplen = strlen(_("A ")) + strlen(body_type_names(body->type)) + 1
+ + strlen(body->subtype && *body->subtype ? body->subtype : "Unknown")
+ + strlen(name ? " (Name=\"" : "")
+ + strlen(name ? namebuf : "")
+ + strlen(name ? "\"" : "") + strlen(_(" segment of about "))
+ + strlen(comatosep) + strlen(_(" bytes")) + 1
+ + strlen(body->description && *body->description ? _(" described as \"") : "")
+ + strlen(body->description && *body->description ? descbuf : "")
+ + strlen(body->description && *body->description ? "\"": "")
+ + 1;
+ tmp = fs_get((tmplen + 1)*sizeof(char));
+ sprintf(tmp, "%s%s/%s%s%s%s%s%s%s%s%s%s%s",
+ _("A "),
+ body_type_names(body->type),
+ body->subtype && *body->subtype ? body->subtype : "Unknown",
+ name ? " (Name=\"" : "", name ? namebuf : "", name ? "\")" : "",
+ _(" segment of about "),
+ comatosep,
+ _(" bytes"),
+ body->description && *body->description ? "," : ".",
+ body->description && *body->description ? " described as \"" : "",
+ body->description && *body->description ? descbuf : "",
+ body->description && *body->description ? "\"" : "");
+
+ if(save_ex_output_text(tmp, depth, &ilen, pc))
*len += ilen;
else
return(0);
- }
}
return(1);
}
+/* save output one line at the time. This uses save_ex_output_line, which
+ * only allows 68 characters of text per line, so what we do is to get justify
+ * the input text to 68 characters long. If it is not possible to do this,
+ * we chop the line at 68 characters and move the remaining text to the next
+ * line.
+ */
+int
+save_ex_output_text(char *text, int depth, unsigned long *len, gf_io_t pc)
+{
+ int starti, i, j, startpos, pos, rv;
+ int line_len = 68 - depth;
+ char tmp[100]; /* a number bigger than 68, we justify text here. */
+ char *s;
+ unsigned long ilen;
+
+ rv = 0;
+ pos = 0;
+ do {
+ ilen = 0;
+ sprintf(tmp, "%*.*s", depth, depth, " ");
+ startpos = pos;
+ for(starti = i = depth; i < 68 && text[pos] != '\0'; i++, pos++){
+ tmp[i] = text[pos];
+ if(tmp[i] == ' '){ /* save when we reach a space */
+ starti = i;
+ startpos = pos;
+ }
+ }
+ tmp[i] = '\0';
+ if(i == 68){
+ if(text[pos] != '\0' && text[pos] != ' '){ /* if we are not at the end of a word */
+ if(startpos < pos && starti != depth){ /* rewind */
+ tmp[starti] = '\0';
+ pos = startpos;
+ }
+ }
+ }
+ rv += save_ex_output_line(tmp, &ilen, pc);
+ *len += ilen;
+ }
+ while (text[pos] != '\0');
+ return rv;
+}
int
save_ex_output_line(char *line, long unsigned int *len, gf_io_t pc)