From 3b29294c143f8413659bb27a4f2d241bc26eba3d Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 25 Dec 2000 22:50:43 +0000 Subject: [PATCH] * Added an API function to extract and unfold specific RFC822 fields. * imap-->fetch-->envelope-->in-reply-to now works * More robust checking and reporting of temp file errors in the client --- citadel/ChangeLog | 6 +++ citadel/imap_fetch.c | 32 ++++++++++----- citadel/internet_addressing.c | 67 ++++++++++++++++++++++++++++++++ citadel/internet_addressing.h | 1 + citadel/messages.c | 73 ++++++++++++++++++++++++++--------- 5 files changed, 152 insertions(+), 27 deletions(-) diff --git a/citadel/ChangeLog b/citadel/ChangeLog index d9d2d4faf..48fd23bb0 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,9 @@ $Log$ + Revision 573.56 2000/12/25 22:50:43 ajc + * Added an API function to extract and unfold specific RFC822 fields. + * imap-->fetch-->envelope-->in-reply-to now works + * More robust checking and reporting of temp file errors in the client + Revision 573.55 2000/12/25 20:43:24 ajc * imap_fetch.c: added support for fetch-->envelope-->from @@ -2237,3 +2242,4 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import + diff --git a/citadel/imap_fetch.c b/citadel/imap_fetch.c index 895a03fee..563984112 100644 --- a/citadel/imap_fetch.c +++ b/citadel/imap_fetch.c @@ -255,7 +255,7 @@ void imap_output_envelope_from(struct CtdlMessage *msg) { void imap_fetch_envelope(long msgnum, struct CtdlMessage *msg) { char datestringbuf[256]; time_t msgdate; - + char *fieldptr = NULL; /* Parse the message date into an IMAP-format date string */ if (msg->cm_fields['T'] != NULL) { @@ -273,21 +273,32 @@ void imap_fetch_envelope(long msgnum, struct CtdlMessage *msg) { */ cprintf("ENVELOPE ("); - /* date */ + /* Date */ imap_strout(datestringbuf); cprintf(" "); - /* subject */ + /* Subject */ imap_strout(msg->cm_fields['U']); cprintf(" "); - /* from */ + /* From */ imap_output_envelope_from(msg); - /* Sender (always in the RFC822 header) */ - cprintf("NIL "); + /* Sender */ + if (0) { + /* FIXME ... check for a *real* Sender: field */ + } + else { + imap_output_envelope_from(msg); + } - cprintf("NIL "); /* reply-to */ + /* Reply-to */ + if (0) { + /* FIXME ... check for a *real* Reply-to: field */ + } + else { + imap_output_envelope_from(msg); + } cprintf("NIL "); /* to */ @@ -295,8 +306,11 @@ void imap_fetch_envelope(long msgnum, struct CtdlMessage *msg) { cprintf("NIL "); /* bcc */ - cprintf("NIL "); /* in-reply-to */ - + /* In-reply-to */ + fieldptr = rfc822_fetch_field(msg->cm_fields['M'], "In-reply-to"); + imap_strout(fieldptr); + cprintf(" "); + if (fieldptr != NULL) phree(fieldptr); /* message ID */ imap_strout(msg->cm_fields['I']); diff --git a/citadel/internet_addressing.c b/citadel/internet_addressing.c index 3ec2d6a6c..00fde5ca6 100644 --- a/citadel/internet_addressing.c +++ b/citadel/internet_addressing.c @@ -558,3 +558,70 @@ struct CtdlMessage *convert_internet_message(char *rfc822) { return msg; } + + +/* + * Look for a particular header field in an RFC822 message text. If the + * requested field is found, it is unfolded (if necessary) and returned to + * the caller. The field name is stripped out, leaving only its contents. + * The caller is responsible for freeing the returned buffer. If the requested + * field is not present, or anything else goes wrong, it returns NULL. + */ +char *rfc822_fetch_field(char *rfc822, char *fieldname) { + int pos = 0; + int beg, end; + int done = 0; + int colonpos, i; + char *fieldbuf = NULL; + + /* Should never happen, but sometimes we get stupid */ + if (rfc822 == NULL) return(NULL); + if (fieldname == NULL) return(NULL); + + while (!done) { + + /* Locate beginning and end of field, keeping in mind that + * some fields might be multiline + */ + beg = pos; + end = (-1); + for (pos=beg; ((pos<=strlen(rfc822))&&(end<0)); ++pos) { + if ((rfc822[pos]=='\n') + && (!isspace(rfc822[pos+1]))) { + end = pos; + } + if ( (rfc822[pos]=='\n') /* done w. headers? */ + && ( (rfc822[pos+1]=='\n') + ||(rfc822[pos+1]=='\r'))) { + end = pos; + done = 1; + } + + } + + /* At this point we have a field. Is it The One? */ + if (end > beg) { + fieldbuf = mallok((end-beg)+3); + if (fieldbuf == NULL) return(NULL); + safestrncpy(fieldbuf, &rfc822[beg], (end-beg)+1); + unfold_rfc822_field(fieldbuf); + colonpos = (-1); + for (i = strlen(fieldbuf); i >= 0; --i) { + if (fieldbuf[i] == ':') colonpos = i; + } + if (colonpos > 0) { + fieldbuf[colonpos] = 0; + if (!strcasecmp(fieldbuf, fieldname)) { + strcpy(fieldbuf, &fieldbuf[colonpos+1]); + striplt(fieldbuf); + return(fieldbuf); + } + } + phree(fieldbuf); + } + + /* If we've hit the end of the message, bail out */ + if (pos > strlen(rfc822)) done = 1; + } + return(NULL); +} diff --git a/citadel/internet_addressing.h b/citadel/internet_addressing.h index 7c54f70d4..432aed8d2 100644 --- a/citadel/internet_addressing.h +++ b/citadel/internet_addressing.h @@ -5,6 +5,7 @@ int fuzzy_match(struct usersupp *us, char *matchstring); void process_rfc822_addr(char *rfc822, char *user, char *node, char *name); +char *rfc822_fetch_field(char *rfc822, char *fieldname); int convert_internet_address(char *destuser, char *desthost, char *source); diff --git a/citadel/messages.c b/citadel/messages.c index fd9fda489..778f25ae1 100644 --- a/citadel/messages.c +++ b/citadel/messages.c @@ -589,9 +589,10 @@ void replace_string(char *filename, long int startpos) * Function to begin composing a new message */ int make_message(char *filename, /* temporary file name */ - char *recipient, /* NULL if it's not mail */ - int anon_type, /* see MES_ types in header file */ - int format_type, int mode) + char *recipient, /* NULL if it's not mail */ + int anon_type, /* see MES_ types in header file */ + int format_type, + int mode) { FILE *fp; int a, b, e_ex_code; @@ -610,17 +611,20 @@ int make_message(char *filename, /* temporary file name */ if (room_flags & QR_ANONONLY) { printf(" ****"); - } else { + } + else { printf(" %s from %s", datestr, fullname); - if (strlen(recipient) > 0) + if (strlen(recipient) > 0) { printf(" to %s", recipient); + } } printf("\n"); beg = 0L; - if (mode == 1) + if (mode == 1) { printf("(Press ctrl-d when finished)\n"); + } if (mode == 0) { fp = fopen(filename, "r"); if (fp != NULL) { @@ -629,6 +633,12 @@ int make_message(char *filename, /* temporary file name */ fclose(fp); } else { fp = fopen(filename, "w"); + if (fp == NULL) { + printf("*** Error opening temp file!\n" + " %s: %s\n", + filename, strerror(errno)); + return(1); + } fclose(fp); } } @@ -637,12 +647,24 @@ ME1: switch (mode) { case 0: fp = fopen(filename, "r+"); + if (fp == NULL) { + printf("*** Error opening temp file!\n" + " %s: %s\n", + filename, strerror(errno)); + return(1); + } citedit(fp); fclose(fp); goto MECR; case 1: fp = fopen(filename, "w"); + if (fp == NULL) { + printf("*** Error opening temp file!\n" + " %s: %s\n", + filename, strerror(errno)); + return(1); + } do { a = inkey(); if (a == 255) @@ -887,7 +909,20 @@ int entmsg(int is_reply, /* nonzero if this was a eply command */ return (2); } - /* ...and transmit it to the server. */ + /* Reopen the temp file that was created, so we can send it */ + fp = fopen(temp, "r"); + + /* Yes, unlink it now, so it doesn't stick around if we crash */ + unlink(temp); + + if (fp == NULL) { + printf("*** Internal error while trying to save message!\n" + " %s: %s\n", + temp, strerror(errno)); + return(errno); + } + + /* Transmit message to the server */ sprintf(cmd, "ENT0 1|%s|%d|%d||", buf, b, mode); serv_puts(cmd); serv_gets(cmd); @@ -895,13 +930,11 @@ int entmsg(int is_reply, /* nonzero if this was a eply command */ printf("%s\n", &cmd[4]); return (1); } - fp = fopen(temp, "r"); - if (fp != NULL) { - transmit_message(fp); - fclose(fp); - } + + transmit_message(fp); serv_puts("000"); - unlink(temp); + + fclose(fp); highmsg = msg_arr[num_msgs - 1]; num_msgs = 0; @@ -920,14 +953,18 @@ int entmsg(int is_reply, /* nonzero if this was a eply command */ /* now see if anyone else has posted in here */ b = (-1); - for (a = 0; a < num_msgs; ++a) - if (msg_arr[a] > highmsg) + for (a = 0; a < num_msgs; ++a) { + if (msg_arr[a] > highmsg) { ++b; + } + } - /* in the Mail> room, this algorithm always counts one message - * higher than in public rooms, so we decrement it by one */ - if (need_recp) + /* In the Mail> room, this algorithm always counts one message + * higher than in public rooms, so we decrement it by one. + */ + if (need_recp) { --b; + } if (b == 1) { printf("*** 1 additional message has been entered " -- 2.30.2