$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
Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
* Initial CVS import
+
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) {
*/
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 */
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']);
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);
+}
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);
* 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;
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) {
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);
}
}
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)
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);
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;
/* 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 "