home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / metamail / tahoe / head.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-18  |  4.7 KB  |  244 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifdef notdef
  14. static char sccsid[] = "@(#)head.c    5.4 (Berkeley) 2/18/88";
  15. #endif /* notdef */
  16.  
  17. #include "rcv.h"
  18.  
  19. /*
  20.  * Mail -- a mail program
  21.  *
  22.  * Routines for processing and detecting headlines.
  23.  */
  24.  
  25. /*
  26.  * See if the passed line buffer is a mail header.
  27.  * Return true if yes.  Note the extreme pains to
  28.  * accomodate all funny formats.
  29.  */
  30. ishead(linebuf)
  31.     char linebuf[];
  32. {
  33.     register char *cp;
  34.     struct headline hl;
  35.     char parbuf[BUFSIZ];
  36.  
  37.     cp = linebuf;
  38.     if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||
  39.         *cp++ != ' ')
  40.         return (0);
  41.     parse(linebuf, &hl, parbuf);
  42.     if (hl.l_from == NOSTR || hl.l_date == NOSTR) {
  43.         fail(linebuf, "No from or date field");
  44.         return (0);
  45.     }
  46.     if (!isdate(hl.l_date)) {
  47.         fail(linebuf, "Date field not legal date");
  48.         return (0);
  49.     }
  50.     /*
  51.      * I guess we got it!
  52.      */
  53.     return (1);
  54. }
  55.  
  56. /*ARGSUSED*/
  57. fail(linebuf, reason)
  58.     char linebuf[], reason[];
  59. {
  60.  
  61.     /*
  62.     if (value("debug") == NOSTR)
  63.         return;
  64.     fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason);
  65.     */
  66. }
  67.  
  68. /*
  69.  * Split a headline into its useful components.
  70.  * Copy the line into dynamic string space, then set
  71.  * pointers into the copied line in the passed headline
  72.  * structure.  Actually, it scans.
  73.  */
  74. parse(line, hl, pbuf)
  75.     char line[], pbuf[];
  76.     register struct headline *hl;
  77. {
  78.     register char *cp;
  79.     char *sp;
  80.     char word[LINESIZE];
  81.  
  82.     hl->l_from = NOSTR;
  83.     hl->l_tty = NOSTR;
  84.     hl->l_date = NOSTR;
  85.     cp = line;
  86.     sp = pbuf;
  87.     /*
  88.      * Skip over "From" first.
  89.      */
  90.     cp = nextword(cp, word);
  91.     cp = nextword(cp, word);
  92.     if (*word)
  93.         hl->l_from = copyin(word, &sp);
  94.     if (cp != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {
  95.         cp = nextword(cp, word);
  96.         hl->l_tty = copyin(word, &sp);
  97.     }
  98.     if (cp != NOSTR)
  99.         hl->l_date = copyin(cp, &sp);
  100. }
  101.  
  102. /*
  103.  * Copy the string on the left into the string on the right
  104.  * and bump the right (reference) string pointer by the length.
  105.  * Thus, dynamically allocate space in the right string, copying
  106.  * the left string into it.
  107.  */
  108. char *
  109. copyin(src, space)
  110.     register char *src;
  111.     char **space;
  112. {
  113.     register char *cp;
  114.     char *top;
  115.  
  116.     top = cp = *space;
  117.     while (*cp++ = *src++)
  118.         ;
  119.     *space = cp;
  120.     return (top);
  121. }
  122.  
  123. /*
  124.  * Test to see if the passed string is a ctime(3) generated
  125.  * date string as documented in the manual.  The template
  126.  * below is used as the criterion of correctness.
  127.  * Also, we check for a possible trailing time zone using
  128.  * the auxtype template.
  129.  */
  130.  
  131. #define    L    1        /* A lower case char */
  132. #define    S    2        /* A space */
  133. #define    D    3        /* A digit */
  134. #define    O    4        /* An optional digit or space */
  135. #define    C    5        /* A colon */
  136. #define    N    6        /* A new line */
  137. #define U    7        /* An upper case char */
  138.  
  139. char ctypes[] = { U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0 };
  140. char tmztypes[] = { U,L,L,S,U,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,U,U,U,S,D,D,D,D,0 };
  141.  
  142. isdate(date)
  143.     char date[];
  144. {
  145.  
  146.     if (cmatch(date, ctypes))
  147.         return (1);
  148.     return (cmatch(date, tmztypes));
  149. }
  150.  
  151. /*
  152.  * Match the given string (cp) against the given template (tp).
  153.  * Return 1 if they match, 0 if they don't
  154.  */
  155.  
  156. cmatch(cp, tp)
  157.     register char *cp, *tp;
  158. {
  159.  
  160.     while (*cp && *tp)
  161.         switch (*tp++) {
  162.         case L:
  163.             if (!islower(*cp++))
  164.                 return 0;
  165.             break;
  166.         case U:
  167.             if (!isupper(*cp++))
  168.                 return 0;
  169.             break;
  170.         case S:
  171.             if (*cp++ != ' ')
  172.                 return 0;
  173.             break;
  174.         case D:
  175.             if (!isdigit(*cp++))
  176.                 return 0;
  177.             break;
  178.         case O:
  179.             if (*cp != ' ' && !isdigit(*cp))
  180.                 return 0;
  181.             cp++;
  182.             break;
  183.         case C:
  184.             if (*cp++ != ':')
  185.                 return 0;
  186.             break;
  187.         case N:
  188.             if (*cp++ != '\n')
  189.                 return 0;
  190.             break;
  191.         }
  192.     if (*cp || *tp)
  193.         return 0;
  194.     return (1);
  195. }
  196.  
  197. /*
  198.  * Collect a liberal (space, tab delimited) word into the word buffer
  199.  * passed.  Also, return a pointer to the next word following that,
  200.  * or NOSTR if none follow.
  201.  */
  202. char *
  203. nextword(wp, wbuf)
  204.     register char *wp, *wbuf;
  205. {
  206.     register c;
  207.  
  208.     if (wp == NOSTR) {
  209.         *wbuf = 0;
  210.         return (NOSTR);
  211.     }
  212.     while ((c = *wp++) && c != ' ' && c != '\t') {
  213.         *wbuf++ = c;
  214.         if (c == '"') {
  215.              while ((c = *wp++) && c != '"')
  216.                  *wbuf++ = c;
  217.              if (c == '"')
  218.                  *wbuf++ = c;
  219.             else
  220.                 wp--;
  221.          }
  222.     }
  223.     *wbuf = '\0';
  224.     for (; c == ' ' || c == '\t'; c = *wp++)
  225.         ;
  226.     if (c == 0)
  227.         return (NOSTR);
  228.     return (wp - 1);
  229. }
  230.  
  231. /*
  232.  * Is c contained in s?
  233.  */
  234. any(c, s)
  235.     register c;
  236.     register char *s;
  237. {
  238.  
  239.     while (*s)
  240.         if (*s++ == c)
  241.             return 1;
  242.     return 0;
  243. }
  244.