home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / mm-0.90 / parsemsg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  5.7 KB  |  216 lines

  1. /*
  2.  * Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  * the City of New York.  Permission is granted to any individual or
  4.  * institution to use, copy, or redistribute this software so long as it
  5.  * is not sold for profit, provided this copyright notice is retained.
  6.  */
  7.  
  8. #ifndef lint
  9. static char *rcsid = "$Header: /f/src2/encore.bin/cucca/mm/tarring-it-up/RCS/parsemsg.c,v 2.4 90/10/04 18:25:27 melissa Exp $";
  10. #endif
  11.  
  12. #include "mm.h"
  13. #include "parse.h"
  14. #include "cmds.h"
  15. #include "message.h"
  16.  
  17. extern msgvec *cf;
  18.  
  19. keywrd header_keys[] = {
  20.     { "to", 0, TO },
  21.     { "cc", 0, CC },
  22.     { "bcc", 0, BCC },
  23.     { "fcc", 0, FCC },
  24.     { "from", 0, FROM },
  25.     { "date", 0, DATE },
  26.     { "subject", 0, SUBJECT },
  27.     { "reply-to", 0, REPLY_TO },
  28.     { "in-reply-to", 0, IN_REPLY_TO },
  29.     { "resent-to", 0, RESENT_TO },
  30.     { "resent-date", 0, RESENT_DATE },
  31.     { "resent-from", 0, RESENT_FROM },
  32.     { "sender", 0, SENDER },
  33.     { "references", 0, REFERENCES },
  34.     { "comments", 0, COMMENTS },
  35.     { "message-id", 0, MESSAGE_ID },
  36.     { "keywords", 0, KEYWORDS },
  37.     { "encrypted", 0, ENCRYPTED },
  38.     { "received", 0, RECEIVED },
  39. };
  40.  
  41. static keytab header_tab = { (sizeof(header_keys)/ sizeof(keywrd)),
  42.                  header_keys };
  43.  
  44. static brktab hdrbrk = {        /* break table for field name */
  45.     {                    /* letters only in first position */
  46.       0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x20, 
  47.       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
  48.     },
  49.     {                    /* letters, digits and hyphens here */
  50.       0xff, 0xff, 0xff, 0xff, 0xb2, 0xe8, 0x00, 0x3f,
  51.       0x80, 0x00, 0x00, 0x16, 0x80, 0x00, 0x00, 0x1f
  52.     }                    /* (also +%_.!) */
  53. };
  54.  
  55. static fdb header_fdb = { _CMKEY, 0, nil, (pdat) &header_tab,"header field, ",
  56.               NULL, &hdrbrk};
  57. static fdb other = { _CMFLD, FLD_EMPTY, NULL, NULL, NULL, NULL, &hdrbrk };
  58. static fdb colon = { _CMTOK, 0, nil, (pdat) ":" };
  59. static fdb text = { _CMTXT };
  60.  
  61. /*
  62.  * take a 'text' mail message, and convert it to internal format.
  63.  * parse out all of the headers, etc.
  64.  */
  65. static mail_msg mesg;
  66.  
  67. mail_msg *
  68. parse_msg(msg)
  69. message *msg;
  70. {
  71.     char *s = msg->text, *next_header();
  72.     char *s1, *realloc(), *malloc();
  73.     int next;
  74.     int retval;
  75.     pval pv;
  76.     fdb *used;
  77.     int parselen;
  78.     headers *h, *new_header();
  79.     int len;
  80.     keylist match_keylist(), kl, k, add_keyword();
  81.     
  82.     bzero (&mesg, sizeof (mail_msg));
  83.     while(s1 = next_header(&s,&next)) {
  84.     int l;
  85.     stripspaces(s1);
  86.     l = strlen(s1);
  87.     s1 = realloc(s1, strlen(s1) + 2);
  88.     s1[l] = '\0';
  89.     strcat(s1, "\n");
  90.     retval = match(s1, strlen(s1), fdbchn(&header_fdb, &other,
  91.                           NULL), &pv, &used, &parselen);
  92.     if (retval == CMxOK) {
  93.         char *name = malloc(parselen+1);
  94.         strncpy(name,s1,parselen);
  95.         name[parselen] = '\0';
  96.         s1 += parselen;
  97.         if (used == &header_fdb) {
  98.         int which = pv._pvkey;
  99.         if (match(s1, strlen(s1), fdbchn(&colon, nil),
  100.               &pv, &used, &parselen) == CMxOK) {
  101.             h = new_header(which, name, HEAD_KNOWN, &mesg);
  102.             free(name);
  103.             s1 += parselen;
  104.         }
  105.         else {
  106.             free(name);
  107.             break;
  108.         }
  109.         switch (which) {
  110.           case TO:
  111.           case CC:
  112.           case BCC:
  113.           case RESENT_TO:
  114.             h->address = (addresslist *) malloc(sizeof(addresslist));
  115.             h->address->first = h->address->last = NULL;
  116.             match_addresses(h->address, &s1, strlen(s1));
  117.             break;
  118.           case KEYWORDS:
  119.             h->keys = match_keylist(s1);
  120.             if (!(mode& MM_SEND)) {
  121.             k = h->keys;
  122.             while(k && *k) {
  123.                 cf->keywords = add_keyword(*k, cf->keywords);
  124.                 k++;
  125.             }
  126.             }
  127.             break;
  128.           case FCC:
  129.             k = kl = match_keylist(s1);
  130.             h->address = (addresslist *) malloc(sizeof(addresslist));
  131.             h->address->first = h->address->last = NULL;
  132.             while (k && *k) {
  133.               add_addresslist(h->address, *k, ADR_FILE);
  134.               k++;
  135.             }
  136.             free_keylist(kl);
  137.             break;
  138.           case FROM:
  139.           case DATE:
  140.           case SUBJECT:
  141.           case REPLY_TO:
  142.           case IN_REPLY_TO:
  143.           case RESENT_DATE:
  144.           case RESENT_FROM:
  145.           case SENDER:
  146.           case REFERENCES:
  147.           case COMMENTS:
  148.           case MESSAGE_ID:
  149.           case ENCRYPTED:
  150.           case RECEIVED:
  151.             skip_spaces(&s1);
  152.             retval = match(s1, strlen(s1), fdbchn(&text,nil), &pv,
  153.                    &used, &parselen);
  154.             h->string = malloc(parselen+1);
  155.             strncpy(h->string,s1,parselen);
  156.             s1 += parselen;
  157.             /* zero-terminate and trim trailing whitespace */
  158.             do { h->string[parselen] = 0; }
  159.             while (--parselen >= 0 && isspace (h->string[parselen]));
  160.             break;
  161.         }
  162.         }
  163.         else {
  164.         if (match(s1, strlen(s1), fdbchn(&colon, nil),
  165.               &pv, &used, &parselen) == CMxOK) {
  166.             h = new_header(USER_HEADERS, name, HEAD_UNKNOWN,
  167.                    &mesg);
  168.             free(name);
  169.             s1 += parselen;
  170.             skip_spaces(&s1);
  171.             retval = match(s1, strlen(s1), fdbchn(&text,nil), &pv,
  172.                    &used, &parselen);
  173.             h->string = malloc(parselen+1);
  174.             strncpy(h->string,s1,parselen);
  175.             s1 += parselen;
  176.             /* zero-terminate and trim trailing whitespace */
  177.             do { h->string[parselen] = 0; }
  178.             while (--parselen >= 0 && isspace (h->string[parselen]));
  179.         }
  180.         else {
  181.             /*
  182.              * this line is not a valid header, so back up to previous
  183.              * newline and treat that as the start of the message body.
  184.              */
  185.             char *cp = s - 2;    /* skip over \n */
  186.           
  187.             while (cp > msg->text && *cp != '\n')
  188.             --cp;
  189.             if (*cp == '\n')
  190.             s = cp;
  191.             free(name);
  192.             break;
  193.         }
  194.         }
  195.     }
  196.     else {
  197.         /* see code above */
  198.         char *cp = s - 2;
  199.  
  200.         while (cp > msg->text && *cp != '\n')
  201.         --cp;
  202.         if (*cp == '\n')
  203.         s = cp;
  204.         break;
  205.     }
  206.     if (!next) break;
  207.     }
  208.     if (*s == '\n')            /* if leading newline... */
  209.     s++;                /* ...separator, not body */
  210.     len = msg->size - (s - msg->text);
  211.     mesg.body = malloc(len+1);
  212.     strncpy(mesg.body,s,len);
  213.     mesg.body[len] = '\0';
  214.     return(&mesg);
  215. }
  216.