* $Id$
*
* Citadel message support routines
- * see copyright.txt for copyright information
+ * see COPYING for copyright information
*/
#include "sysdep.h"
#endif
#include <stdarg.h>
+#include <libcitadel.h>
#include "citadel.h"
#include "citadel_ipc.h"
#include "citadel_decls.h"
#include "messages.h"
#include "commands.h"
#include "rooms.h"
-#include "tools.h"
-#include "html.h"
#ifndef HAVE_SNPRINTF
#include "snprintf.h"
#endif
char reply_to[SIZ];
char reply_subject[SIZ];
+char reply_references[SIZ];
+char reply_inreplyto[SIZ];
struct cittext {
struct cittext *next;
int num_msgs;
char rc_alt_semantics;
extern char room_name[];
+extern char tempdir[];
extern unsigned room_flags;
extern unsigned room_flags2;
extern long highest_msg_read;
struct cittext *textlist = NULL;
struct cittext *ptr;
char wordbuf[MAXWORDBUF];
+ int rv = 0;
/* first, load the text into the buffer */
fseek(fp, 0L, 0);
}
putc(10, fp);
fflush(fp);
- ftruncate(fileno(fp), ftell(fp));
+ rv = ftruncate(fileno(fp), ftell(fp));
/* and deallocate the memory we used */
while (textlist != NULL) {
strcpy(reply_to, NO_REPLY_TO);
strcpy(reply_subject, "");
+ strcpy(reply_references, "");
+ strcpy(reply_inreplyto, "");
- r = CtdlIPCGetSingleMessage(ipc, num, (pagin == READ_HEADER ? 1 : 0),
- (can_do_msg4 ? 4 : 0),
- &message, buf);
+ r = CtdlIPCGetSingleMessage(ipc, num, (pagin == READ_HEADER ? 1 : 0), 4, &message, buf);
if (r / 100 != 1) {
err_printf("*** msg #%ld: %d %s\n", num, r, buf);
++lines_printed;
/* Set the reply-to address to an Internet e-mail address if possible
*/
- if (message->email != NULL) if (!IsEmptyStr(message->email)) {
+ if ((message->email != NULL) && (!IsEmptyStr(message->email))) {
if (!IsEmptyStr(message->author)) {
snprintf(reply_to, sizeof reply_to, "%s <%s>", message->author, message->email);
}
lines_printed = checkpagin(lines_printed, pagin, screenheight);
}
+
+ if (message->msgid != NULL) {
+ safestrncpy(reply_inreplyto, message->msgid, sizeof reply_inreplyto);
+ }
+
+ if (message->references != NULL) if (!IsEmptyStr(message->references)) {
+ safestrncpy(reply_references, message->references, sizeof reply_references);
+ }
+
if (message->subject != NULL) {
- safestrncpy(reply_subject, message->subject,
- sizeof reply_subject);
+ safestrncpy(reply_subject, message->subject, sizeof reply_subject);
if (!IsEmptyStr(message->subject)) {
if (dest) {
fprintf(dest, "Subject: %s\n",
}
/* Enumerate any attachments */
- if ( (pagin == 1) && (can_do_msg4) && (message->attachments) ) {
+ if ( (pagin == 1) && (message->attachments) ) {
struct parts *ptr;
for (ptr = message->attachments; ptr; ptr = ptr->next) {
char *ptr;
int substitutions = 0;
long msglen = 0L;
+ int rv;
scr_printf("Enter text to be replaced:\n: ");
ctdl_getline(srch_str, (sizeof(srch_str)-1) );
- if (IsEmptyStr(srch_str))
+ if (IsEmptyStr(srch_str)) {
return;
+ }
scr_printf("Enter text to replace it with:\n: ");
ctdl_getline(rplc_str, (sizeof(rplc_str)-1) );
fp = fopen(filename, "r+");
- if (fp == NULL)
+ if (fp == NULL) {
return;
+ }
wpos = startpos;
fseek(fp, startpos, 0);
if (strlen(buf) > 384) {
rpos = ftell(fp);
fseek(fp, wpos, 0);
- fwrite((char *) buf, 128, 1, fp);
+ rv = fwrite((char *) buf, 128, 1, fp);
strcpy(buf, &buf[128]);
wpos = ftell(fp);
fseek(fp, rpos, 0);
}
}
fseek(fp, wpos, 0);
- if (!IsEmptyStr(buf))
- fwrite((char *) buf, strlen(buf), 1, fp);
+ if (!IsEmptyStr(buf)) {
+ rv = fwrite((char *) buf, strlen(buf), 1, fp);
+ }
wpos = ftell(fp);
fclose(fp);
- truncate(filename, wpos);
+ rv = truncate(filename, wpos);
scr_printf("<R>eplace made %d substitution(s).\n\n", substitutions);
}
strcpy(message.recipient, "");
strcpy(message.author, "");
strcpy(message.subject, "");
+ strcpy(message.references, "");
message.text = ""; /* point to "", changes later */
message.anonymous = 0;
message.type = mode;
strcpy(message.recipient, buf);
if (is_reply) {
+
if (!IsEmptyStr(reply_subject)) {
if (!strncasecmp(reply_subject,
"Re: ", 3)) {
reply_subject);
}
}
+
+ /* Trim down excessively long lists of thread references. We eliminate the
+ * second one in the list so that the thread root remains intact.
+ */
+ int rrtok = num_tokens(reply_references, '|');
+ int rrlen = strlen(reply_references);
+ if ( ((rrtok >= 3) && (rrlen > 900)) || (rrtok > 10) ) {
+ remove_token(reply_references, 1, '|');
+ }
+
+ snprintf(message.references, sizeof message.references, "%s%s%s",
+ reply_references,
+ (IsEmptyStr(reply_references) ? "" : "|"),
+ reply_inreplyto
+ );
}
if (room_flags & QR_ANONOPT) {
/* Display the quotable text with line numbers added */
line = 0;
- fgets(buf, 128, qfile);
+ if (fgets(buf, 128, qfile) == NULL) {
+ /* we're skipping a line here */
+ }
while (fgets(buf, 128, qfile) != NULL) {
- scr_printf("%2d %s", ++line, buf);
+ scr_printf("%3d %s", ++line, buf);
}
- scr_printf("Begin quoting at [ 1] : ");
- ctdl_getline(buf, 3);
+ scr_printf("Begin quoting at [1] : ");
+ ctdl_getline(buf, 4);
qstart = (buf[0] == 0) ? (1) : atoi(buf);
scr_printf(" End quoting at [%d] : ", line);
- ctdl_getline(buf, 3);
+ ctdl_getline(buf, 4);
qend = (buf[0] == 0) ? (line) : atoi(buf);
rewind(qfile);
line = 0;
- fgets(buf, 128, qfile);
+ if (fgets(buf, 128, qfile) == NULL) {
+ /* we're skipping a line here */
+ }
tfile = fopen(temp, "w");
while (fgets(buf, 128, qfile) != NULL) {
if ((++line >= qstart) && (line <= qend))
{
int i;
char cmd[SIZ];
+ int rv;
if (num_urls == 0) {
scr_printf("There were no URL's in the previous message.\n\n");
i = intprompt("Display which one", 1, 1, num_urls);
snprintf(cmd, sizeof cmd, rc_url_cmd, urls[i - 1]);
- system(cmd);
+ rv = system(cmd);
scr_printf("\n");
}
char filename[PATH_MAX];
char save_to[PATH_MAX];
void *attachment = NULL; /* Downloaded attachment */
- FILE *dest = NULL; /* Alternate destination other than screen */
+ FILE *dest = NULL; /* Alternate destination other than screen */
int r; /* IPC response code */
+ static int att_seq = 0; /* Attachment download sequence number */
+ int rv = 0; /* silence the stupid warn_unused_result warnings */
if (c < 0)
b = (num_msgs - 1);
quotflag = 0;
enable_color = hold_color;
process_quote();
+ e = 'r';
+ goto DONE_QUOTING;
}
if (arcflag) {
fclose(dest);
enable_color = hold_color;
f = fork();
if (f == 0) {
- freopen(prtfile, "r", stdin);
+ if (freopen(prtfile, "r", stdin) == NULL) {
+ /* we probably should handle the error condition here */
+ }
screen_reset();
stty_ctdl(SB_RESTORE);
ka_system(printcmd);
color(DIM_WHITE);
scr_printf(") ");
- keyopt("<B>ack <A>gain <Q>uote <R>eply <N>ext <S>top ");
+ keyopt("<B>ack <A>gain <R>eply reply<Q>uoted <N>ext <S>top ");
if (rc_url_cmd[0] && num_urls)
keyopt("<U>RLview ");
if (has_images > 0 && !IsEmptyStr(imagecmd))
&& (e != 'q') && (e != 'b') && (e != 'h')
&& (e != 'r') && (e != 'f') && (e != '?')
&& (e != 'u') && (e != 'c') && (e != 'y')
- && (e != 'i'));
+ && (e != 'i') && (e != 'o') );
switch (e) {
case 's':
scr_printf("Stop");
scr_printf("Print");
break;
case 'q':
- scr_printf("Quote");
+ scr_printf("reply Quoted");
break;
case 'b':
scr_printf("Back");
case 'r':
scr_printf("Reply");
break;
+ case 'o':
+ scr_printf("Open attachments");
+ break;
case 'f':
scr_printf("File");
break;
scr_printf("\n");
scr_flush();
}
- switch (e) {
+DONE_QUOTING: switch (e) {
case '?':
scr_printf("Options available here:\n"
" ? Help (prints this message)\n"
if (!IsEmptyStr(printcmd))
scr_printf(" P Print this message\n");
scr_printf(
- " Q Quote portions of this message for your next post\n"
+ " Q Reply to this message, quoting portions of it\n"
" H Headers (display message headers only)\n");
if (is_mail)
scr_printf(" R Reply to this message\n");
- if (rc_allow_attachments)
- scr_printf
- (" F (save attachments to a file)\n");
+ if (rc_allow_attachments) {
+ scr_printf(" O (Open attachments)\n");
+ scr_printf(" F (save attachments to a File)\n");
+ }
if (!IsEmptyStr(rc_url_cmd))
scr_printf(" U (list URL's for display)\n");
if (!IsEmptyStr(imagecmd) && has_images > 0)
if (r / 100 != 2) /* r will be init'ed, FIXME */
goto RMSGREAD; /* the logic here sucks */
break;
+ case 'o':
case 'f':
- newprompt("Which section? ", filename,
- ((sizeof filename) - 1));
+ newprompt("Which section? ", filename, ((sizeof filename) - 1));
r = CtdlIPCAttachmentDownload(ipc, msg_arr[a],
filename, &attachment, progress, cmd);
if (r / 100 != 2) {
* Part 1 won't have a filename; use the
* subject of the message instead. IO
*/
- if (IsEmptyStr(filename))
+ if (IsEmptyStr(filename)) {
strcpy(filename, reply_subject);
- destination_directory(save_to, filename);
- save_buffer(attachment,
- extract_unsigned_long(cmd, 0),
- save_to);
+ }
+ if (e == 'o') { /* open attachment */
+ mkdir(tempdir, 0700);
+ snprintf(save_to, sizeof save_to, "%s/%04x.%s",
+ tempdir,
+ ++att_seq,
+ filename);
+ save_buffer(attachment, extract_unsigned_long(cmd, 0), save_to);
+ snprintf(cmd, sizeof cmd, rc_open_cmd, save_to);
+ rv = system(cmd);
+ }
+ else { /* save attachment to disk */
+ destination_directory(save_to, filename);
+ save_buffer(attachment, extract_unsigned_long(cmd, 0), save_to);
+ }
}
if (attachment) {
free(attachment);