/* $OpenBSD: head.c,v 1.5 1996/06/08 19:48:26 christos Exp $ */1/* $NetBSD: head.c,v 1.5 1996/06/08 19:48:26 christos Exp $ */23/*4* Copyright (c) 1980, 19935* The Regents of the University of California. All rights reserved.6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15* 3. All advertising materials mentioning features or use of this software16* must display the following acknowledgement:17* This product includes software developed by the University of18* California, Berkeley and its contributors.19* 4. Neither the name of the University nor the names of its contributors20* may be used to endorse or promote products derived from this software21* without specific prior written permission.22*23* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND24* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE25* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE26* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE27* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL28* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS29* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)30* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT31* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY32* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF33* SUCH DAMAGE.34*/3536/*#include "def.h"*/37#include "head.h"3839/*40* Mail -- a mail program41*42* Routines for processing and detecting headlines.43*/4445/*46* See if the passed line buffer is a mail header.47* Return true if yes. Note the extreme pains to48* accomodate all funny formats.49*/50int ishead(char *linebuf)51{52register char *cp;53struct headline hl;54char parbuf[BUFSIZ];5556cp = linebuf;57if (*cp++ != 'F' || *cp++ != 'r' || *cp++ != 'o' || *cp++ != 'm' ||58*cp++ != ' ')59return (0);60parse(linebuf, &hl, parbuf);61if (hl.l_from == NOSTR || hl.l_date == NOSTR) {62fail(linebuf, "No from or date field");63return (0);64}65if (!isdate(hl.l_date)) {66fail(linebuf, "Date field not legal date");67return (0);68}69/*70* I guess we got it!71*/72return (1);73}7475/*ARGSUSED*/76void fail(char *linebuf, char *reason)77{7879/*80if (value("debug") == NOSTR)81return;82fprintf(stderr, "\"%s\"\nnot a header because %s\n", linebuf, reason);83*/84}8586/*87* Split a headline into its useful components.88* Copy the line into dynamic string space, then set89* pointers into the copied line in the passed headline90* structure. Actually, it scans.91*/92void parse(char *line, register struct headline *hl, char *pbuf)93{94register char *cp;95char *sp;96char word[LINESIZE];9798hl->l_from = NOSTR;99hl->l_tty = NOSTR;100hl->l_date = NOSTR;101cp = line;102sp = pbuf;103/*104* Skip over "From" first.105*/106cp = nextword(cp, word);107cp = nextword(cp, word);108if (*word)109hl->l_from = copyin(word, &sp);110if (cp != NOSTR && cp[0] == 't' && cp[1] == 't' && cp[2] == 'y') {111cp = nextword(cp, word);112hl->l_tty = copyin(word, &sp);113}114if (cp != NOSTR)115hl->l_date = copyin(cp, &sp);116}117118/*119* Copy the string on the left into the string on the right120* and bump the right (reference) string pointer by the length.121* Thus, dynamically allocate space in the right string, copying122* the left string into it.123*/124char * copyin(register char *src, char **space)125{126register char *cp;127char *top;128129top = cp = *space;130while ((*cp++ = *src++) != '\0')131;132*space = cp;133return (top);134}135136/*137* Test to see if the passed string is a ctime(3) generated138* date string as documented in the manual. The template139* below is used as the criterion of correctness.140* Also, we check for a possible trailing time zone using141* the tmztype template.142*/143144/*145* 'A' An upper case char146* 'a' A lower case char147* ' ' A space148* '0' A digit149* 'O' An optional digit or space150* ':' A colon151* 'N' A new line152*/153char ctype[] = "Aaa Aaa O0 00:00:00 0000";154char ctype_without_secs[] = "Aaa Aaa O0 00:00 0000";155char tmztype[] = "Aaa Aaa O0 00:00:00 AAA 0000";156char tmztype_without_secs[] = "Aaa Aaa O0 00:00 AAA 0000";157158int isdate(char *date)159{160return cmatch(date, ctype_without_secs) ||161cmatch(date, tmztype_without_secs) ||162cmatch(date, ctype) || cmatch(date, tmztype);163}164165/*166* Match the given string (cp) against the given template (tp).167* Return 1 if they match, 0 if they don't168*/169int cmatch(register char *cp, register char *tp)170{171172while (*cp && *tp)173switch (*tp++) {174case 'a':175if (!islower(*cp++))176return 0;177break;178case 'A':179if (!isupper(*cp++))180return 0;181break;182case ' ':183if (*cp++ != ' ')184return 0;185break;186case '0':187if (!isdigit(*cp++))188return 0;189break;190case 'O':191if (*cp != ' ' && !isdigit(*cp))192return 0;193cp++;194break;195case ':':196if (*cp++ != ':')197return 0;198break;199case 'N':200if (*cp++ != '\n')201return 0;202break;203}204if (*cp || *tp)205return 0;206return (1);207}208209/*210* Collect a liberal (space, tab delimited) word into the word buffer211* passed. Also, return a pointer to the next word following that,212* or NOSTR if none follow.213*/214char *nextword(register char *wp, register char *wbuf)215{216register char c;217218if (wp == NOSTR) {219*wbuf = 0;220return (NOSTR);221}222while ((c = *wp++) && c != ' ' && c != '\t') {223*wbuf++ = c;224if (c == '"') {225while ((c = *wp++) && c != '"')226*wbuf++ = c;227if (c == '"')228*wbuf++ = c;229else230wp--;231}232}233*wbuf = '\0';234for (; c == ' ' || c == '\t'; c = *wp++)235;236if (c == 0)237return (NOSTR);238return (wp - 1);239}240241242