home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / usr.bin / mail / head.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-18  |  5.7 KB  |  249 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, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)head.c    5.7 (Berkeley) 6/1/90";
  36. #endif /* not lint */
  37.  
  38. #include "rcv.h"
  39.  
  40. /*
  41.  * Mail -- a mail program
  42.  *
  43.  * Routines for processing and detecting headlines.
  44.  */
  45.  
  46. /*
  47.  * See if the passed line buffer is a mail header.
  48.  * Return true if yes.  Note the extreme pains to
  49.  * accomodate all funny formats.
  50.  */
  51. ishead(linebuf)
  52.     char linebuf[];
  53. {
  54.     register char *cp;
  55.     struct headline hl;
  56.     char parbuf[BUFSIZ];
  57.  
  58.     cp = linebuf;
  59.     if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||
  60.         *cp++ != ' ')
  61.         return (0);
  62.     parse(linebuf, &hl, parbuf);
  63.     if (hl.l_from == NOSTR || hl.l_date == NOSTR) {
  64.         fail(linebuf, "No from or date field");
  65.         return (0);
  66.     }
  67.     if (!isdate(hl.l_date)) {
  68.         fail(linebuf, "Date field not legal date");
  69.         return (0);
  70.     }
  71.     /*
  72.      * I guess we got it!
  73.      */
  74.     return (1);
  75. }
  76.  
  77. /*ARGSUSED*/
  78. fail(linebuf, reason)
  79.     char linebuf[], reason[];
  80. {
  81.  
  82.     /*
  83.     if (value("debug") == NOSTR)
  84.         return;
  85.     fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason);
  86.     */
  87. }
  88.  
  89. /*
  90.  * Split a headline into its useful components.
  91.  * Copy the line into dynamic string space, then set
  92.  * pointers into the copied line in the passed headline
  93.  * structure.  Actually, it scans.
  94.  */
  95. parse(line, hl, pbuf)
  96.     char line[], pbuf[];
  97.     register struct headline *hl;
  98. {
  99.     register char *cp;
  100.     char *sp;
  101.     char word[LINESIZE];
  102.  
  103.     hl->l_from = NOSTR;
  104.     hl->l_tty = NOSTR;
  105.     hl->l_date = NOSTR;
  106.     cp = line;
  107.     sp = pbuf;
  108.     /*
  109.      * Skip over "From" first.
  110.      */
  111.     cp = nextword(cp, word);
  112.     cp = nextword(cp, word);
  113.     if (*word)
  114.         hl->l_from = copyin(word, &sp);
  115.     if (cp != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {
  116.         cp = nextword(cp, word);
  117.         hl->l_tty = copyin(word, &sp);
  118.     }
  119.     if (cp != NOSTR)
  120.         hl->l_date = copyin(cp, &sp);
  121. }
  122.  
  123. /*
  124.  * Copy the string on the left into the string on the right
  125.  * and bump the right (reference) string pointer by the length.
  126.  * Thus, dynamically allocate space in the right string, copying
  127.  * the left string into it.
  128.  */
  129. char *
  130. copyin(src, space)
  131.     register char *src;
  132.     char **space;
  133. {
  134.     register char *cp;
  135.     char *top;
  136.  
  137.     top = cp = *space;
  138.     while (*cp++ = *src++)
  139.         ;
  140.     *space = cp;
  141.     return (top);
  142. }
  143.  
  144. /*
  145.  * Test to see if the passed string is a ctime(3) generated
  146.  * date string as documented in the manual.  The template
  147.  * below is used as the criterion of correctness.
  148.  * Also, we check for a possible trailing time zone using
  149.  * the tmztype template.
  150.  */
  151.  
  152. /*
  153.  * 'A'    An upper case char
  154.  * 'a'    A lower case char
  155.  * ' '    A space
  156.  * '0'    A digit
  157.  * 'O'    An optional digit or space
  158.  * ':'    A colon
  159.  * 'N'    A new line
  160.  */
  161. char ctype[] = "Aaa Aaa O0 00:00:00 0000";
  162. char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000";
  163.  
  164. isdate(date)
  165.     char date[];
  166. {
  167.  
  168.     return cmatch(date, ctype) || cmatch(date, tmztype);
  169. }
  170.  
  171. /*
  172.  * Match the given string (cp) against the given template (tp).
  173.  * Return 1 if they match, 0 if they don't
  174.  */
  175. cmatch(cp, tp)
  176.     register char *cp, *tp;
  177. {
  178.  
  179.     while (*cp && *tp)
  180.         switch (*tp++) {
  181.         case 'a':
  182.             if (!islower(*cp++))
  183.                 return 0;
  184.             break;
  185.         case 'A':
  186.             if (!isupper(*cp++))
  187.                 return 0;
  188.             break;
  189.         case ' ':
  190.             if (*cp++ != ' ')
  191.                 return 0;
  192.             break;
  193.         case '0':
  194.             if (!isdigit(*cp++))
  195.                 return 0;
  196.             break;
  197.         case 'O':
  198.             if (*cp != ' ' && !isdigit(*cp))
  199.                 return 0;
  200.             cp++;
  201.             break;
  202.         case ':':
  203.             if (*cp++ != ':')
  204.                 return 0;
  205.             break;
  206.         case 'N':
  207.             if (*cp++ != '\n')
  208.                 return 0;
  209.             break;
  210.         }
  211.     if (*cp || *tp)
  212.         return 0;
  213.     return (1);
  214. }
  215.  
  216. /*
  217.  * Collect a liberal (space, tab delimited) word into the word buffer
  218.  * passed.  Also, return a pointer to the next word following that,
  219.  * or NOSTR if none follow.
  220.  */
  221. char *
  222. nextword(wp, wbuf)
  223.     register char *wp, *wbuf;
  224. {
  225.     register c;
  226.  
  227.     if (wp == NOSTR) {
  228.         *wbuf = 0;
  229.         return (NOSTR);
  230.     }
  231.     while ((c = *wp++) && c != ' ' && c != '\t') {
  232.         *wbuf++ = c;
  233.         if (c == '"') {
  234.              while ((c = *wp++) && c != '"')
  235.                  *wbuf++ = c;
  236.              if (c == '"')
  237.                  *wbuf++ = c;
  238.             else
  239.                 wp--;
  240.          }
  241.     }
  242.     *wbuf = '\0';
  243.     for (; c == ' ' || c == '\t'; c = *wp++)
  244.         ;
  245.     if (c == 0)
  246.         return (NOSTR);
  247.     return (wp - 1);
  248. }
  249.