home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / Mail / head.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  4KB  |  260 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #
  3.  
  4. #include "def.h"
  5.  
  6. /*
  7.  * Mail -- a mail program
  8.  *
  9.  * Routines for processing and detecting headlines.
  10.  */
  11.  
  12. /*
  13.  * See if the passed line buffer is a mail header.
  14.  * Return true if yes.  Note the extreme pains to
  15.  * accomodate all funny formats.
  16.  */
  17.  
  18. ishead(linebuf)
  19.     char linebuf[];
  20. {
  21.     register char *cp;
  22.     struct headline hl;
  23.  
  24.     cp = linebuf;
  25.     if (!isname("From ", cp, 5))
  26.         return(0);
  27.     parse(cp, &hl);
  28.     if (hl.l_from == NOSTR || hl.l_date == NOSTR)
  29.         return(0);
  30.     if (strlen(hl.l_from) >= 17)
  31.         return(0);
  32.     if (!isdate(hl.l_date))
  33.         return(0);
  34.     
  35.     /*
  36.      * I guess we got it!
  37.      */
  38.  
  39.     return(1);
  40. }
  41.  
  42. /*
  43.  * Split a headline into its useful components.
  44.  * Copy the line into dynamic string space, then set
  45.  * pointers into the copied line in the passed headline
  46.  * structure.  Actually, it scans.
  47.  */
  48.  
  49. parse(line, hl)
  50.     char line[];
  51.     struct headline *hl;
  52. {
  53.     register char *cp, *dp;
  54.     char word[LINESIZE];
  55.  
  56.     hl->l_from = NOSTR;
  57.     hl->l_tty = NOSTR;
  58.     hl->l_date = NOSTR;
  59.     cp = line;
  60.  
  61.     /*
  62.      * Skip the first "word" of the line, which should be "From"
  63.      * anyway.
  64.      */
  65.  
  66.     cp = nextword(cp, word);
  67.     dp = nextword(cp, word);
  68.     if (!equal(word, ""))
  69.         hl->l_from = savestr(word);
  70.     if (isname(dp, "tty", 3)) {
  71.         cp = nextword(dp, word);
  72.         hl->l_tty = savestr(word);
  73.         if (cp != NOSTR)
  74.             hl->l_date = savestr(cp);
  75.     }
  76.     else
  77.         if (dp != NOSTR)
  78.             hl->l_date = savestr(dp);
  79. }
  80.  
  81. /*
  82.  * See if the two passed strings agree in the first n characters.
  83.  * Return true if they do, gnu.
  84.  */
  85.  
  86. isname(as1, as2, acount)
  87.     char *as1, *as2;
  88. {
  89.     register char *s1, *s2;
  90.     register count;
  91.  
  92.     s1 = as1;
  93.     s2 = as2;
  94.     count = acount;
  95.     if (count > 0)
  96.         do
  97.             if (*s1++ != *s2++)
  98.                 return(0);
  99.         while (--count);
  100.     return(1);
  101. }
  102.  
  103. /*
  104.  * Test to see if the passed string is a ctime(3) generated
  105.  * date string as documented in the manual.  The template
  106.  * below is used as the criterion of correctness.
  107.  */
  108.  
  109. #define    L    1        /* An alpha char */
  110. #define    S    2        /* A space */
  111. #define    D    3        /* A digit */
  112. #define    O    4        /* An optional digit or space */
  113. #define    C    5        /* A colon */
  114. #define    N    6        /* A new line */
  115.  
  116. char ctypes[] = {L,L,L,S,L,L,L,S,O,D,S,D,D,C,D,D,C,D,D,S,D,D,D,D,0};
  117.  
  118. isdate(date)
  119.     char date[];
  120. {
  121.     register char *cp, *tp;
  122.     register int c;
  123.  
  124.     cp = date;
  125.     tp = ctypes;
  126.     while (*cp != '\0' && *tp != 0) {
  127.         c = *cp++;
  128.         switch (*tp++) {
  129.         case L:
  130.             if (!isalpha(c))
  131.                 return(0);
  132.             break;
  133.  
  134.         case S:
  135.             if (c != ' ')
  136.                 return(0);
  137.             break;
  138.  
  139.         case D:
  140.             if (!isdigit(c))
  141.                 return(0);
  142.             break;
  143.  
  144.         case O:
  145.             if (c != ' ' && !isdigit(c))
  146.                 return(0);
  147.             break;
  148.  
  149.         case C:
  150.             if (c != ':')
  151.                 return(0);
  152.             break;
  153.  
  154.         case N:
  155.             if (c != '\n')
  156.                 return(0);
  157.             break;
  158.         }
  159.     }
  160.     if (*cp != '\0' || *tp != 0)
  161.         return(0);
  162.     return(1);
  163. }
  164.  
  165. /*
  166.  * Collect a liberal (space, tab delimited) word into the word buffer
  167.  * passed.  Also, return a pointer to the next word following that,
  168.  * or NOSTR if none follow.
  169.  */
  170.  
  171. char *
  172. nextword(wp, wbuf)
  173.     char wp[], wbuf[];
  174. {
  175.     register char *cp, *cp2;
  176.  
  177.     if ((cp = wp) == NOSTR) {
  178.         copy("", wbuf);
  179.         return(NOSTR);
  180.     }
  181.     cp2 = wbuf;
  182.     while (!any(*cp, " \t") && *cp != '\0')
  183.         *cp2++ = *cp++;
  184.     *cp2 = '\0';
  185.     while (any(*cp, " \t"))
  186.         cp++;
  187.     if (*cp == '\0')
  188.         return(NOSTR);
  189.     return(cp);
  190. }
  191.  
  192. /*
  193.  * Test to see if the character is an ascii alphabetic.
  194.  */
  195.  
  196. isalpha(c)
  197. {
  198.     register int ch;
  199.  
  200.     ch = raise(c);
  201.     return(ch >= 'A' && ch <= 'Z');
  202. }
  203.  
  204. /*
  205.  * Test to see if the character is an ascii digit.
  206.  */
  207.  
  208. isdigit(c)
  209. {
  210.     return(c >= '0' && c <= '9');
  211. }
  212.  
  213. /*
  214.  * Copy str1 to str2, return pointer to null in str2.
  215.  */
  216.  
  217. char *
  218. copy(str1, str2)
  219.     char *str1, *str2;
  220. {
  221.     register char *s1, *s2;
  222.  
  223.     s1 = str1;
  224.     s2 = str2;
  225.     while (*s1)
  226.         *s2++ = *s1++;
  227.     *s2 = 0;
  228.     return(s2);
  229. }
  230.  
  231. /*
  232.  * Is ch any of the characters in str?
  233.  */
  234.  
  235. any(ch, str)
  236.     char *str;
  237. {
  238.     register char *f;
  239.     register c;
  240.  
  241.     f = str;
  242.     c = ch;
  243.     while (*f)
  244.         if (c == *f++)
  245.             return(1);
  246.     return(0);
  247. }
  248.  
  249. /*
  250.  * Convert lower case letters to upper case.
  251.  */
  252.  
  253. raise(c)
  254.     register int c;
  255. {
  256.     if (c >= 'a' && c <= 'z')
  257.         c += 'A' - 'a';
  258.     return(c);
  259. }
  260.