* Added an API function to extract and unfold specific RFC822 fields.
authorArt Cancro <ajc@citadel.org>
Mon, 25 Dec 2000 22:50:43 +0000 (22:50 +0000)
committerArt Cancro <ajc@citadel.org>
Mon, 25 Dec 2000 22:50:43 +0000 (22:50 +0000)
* imap-->fetch-->envelope-->in-reply-to now works
* More robust checking and reporting of temp file errors in the client

citadel/ChangeLog
citadel/imap_fetch.c
citadel/internet_addressing.c
citadel/internet_addressing.h
citadel/messages.c

index d9d2d4faf2f97a49cfe5c7828131ca8c17b699f9..48fd23bb081893afaece8242fd50b110beb8a7b9 100644 (file)
@@ -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 <bryant@cs.usm.maine.edu>
 
 Fri Jul 10 1998 Art Cancro <ajc@uncensored.citadel.org>
        * Initial CVS import 
+
index 895a03feed44b704c792fba51fd1be2b0b3c0c83..563984112e7ed99705bea4063651eea9d0286808 100644 (file)
@@ -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']);
index 3ec2d6a6c55c64fbe9926b6f2a402c6705055a8c..00fde5ca64b38fb5e3d86e7760a47e908ebf1da8 100644 (file)
@@ -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);
+}
index 7c54f70d47fdba63024078ed88a6ecde07bad04e..432aed8d2111a46e7f3153a9d688ed952c1d8b15 100644 (file)
@@ -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);
index fd9fda48906f510771e0d17b2e04906d9619eafb..778f25ae1a14920d8c4c2426fdd0c0120bba1843 100644 (file)
@@ -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 <R>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 <R>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 <R>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 "