/*
 *  hap -- a mail notification program
 * 
 *  copyright 1995 by Eric Fischer, etaoin@uchicago.edu
 * 
 *  copies of hap may be redistributed under the terms of the
 *  GNU public license, copies of which are available from
 *  the Free Software Foundation, 59 Temple Place, Boston, MA
 *  02111 USA.
 *
 */

#include "hap.h"

/**************************************************************************

   POSTMARK RECOGNITION

**************************************************************************/

/* vague definition of an mtxt postmark.  Looks something like

    11-Jul-92 12:42:03-GMT,748;000000000001

   where a one digit number might have a space instead of a digit at the start.
   returns true if it matches, false if it doesn't.
*/

int
ismtxt (what)
	char *what;
{
	if (strlen (what) > 34) {
		if ((isspace (what[0]) || isdigit (what[0]))
		&&   isdigit (what[1])
		&&            what[2] == '-'
		&&   isalpha (what[3])
		&&   isalpha (what[4])
		&&   isalpha (what[5])
		&&            what[6] == '-'
		&&   isdigit (what[7])
		&&   isdigit (what[8])
		&&   isspace (what[9])
		&&  (isspace (what[10]) || isdigit (what[10]))
		&&   isdigit (what[11])
		&&            what[12] == ':'
		&&   isdigit (what[13])
		&&   isdigit (what[14])
		&&            what[15] == ':'
		&&   isdigit (what[16])
		&&   isdigit (what[17])
		&&            what[18] == '-'
		&&   isalpha (what[19])
		&&   isalpha (what[20])
		&&   isalpha (what[21])
		&&            what[22] == ',') {
			char *here = what + 23;

			if   (!isdigit (*here)) return 0;
			while (isdigit (*here)) here++;

			if (*here == ';') here++;
			else return 0;

			if   (!isdigit (*here)) return 0;
			while (isdigit (*here)) here++;

			if (*here == '\n') return 1;
			else return 0;
		}
	}
	return 0;
}

/* is it a digit or a space?  then say so. */

int
isdigsp (it)
	int it;
{
	return (isdigit (it) || isspace (it));
}

/* returns true if end points to the *end* of a date in ctime
   format:  Fri Jun  2 15:50:48 1995
                                   ^-- end points here
*/

int
isnormalmbox (end)
	char *end;
{
	if (isdigit (end[ 0])   /* year */
	&&  isdigit (end[-1])
	&&  isdigit (end[-2])
	&&  isdigit (end[-3])

	&&  isspace (end[-4])

	&&  isdigit (end[-5])   /* seconds */
	&&  isdigit (end[-6])

	&&  ':' ==   end[-7]

	&&  isdigit (end[-8])   /* minutes */
	&&  isdigit (end[-9])

	&&  ':' ==   end[-10]

	&&  isdigit (end[-11])  /* hour */
	&&  isdigsp (end[-12])

	&&  isspace (end[-13])

	&&  isdigit (end[-14])  /* day */
	&&  isdigsp (end[-15])

	&&  isspace (end[-16])

	&&  isalpha (end[-17])  /* month */
	&&  isalpha (end[-18])
	&&  isalpha (end[-19])

	&&  isspace (end[-20])

	&&  isalpha (end[-21])
	&&  isalpha (end[-22])
	&&  isalpha (end[-23])) {
		return 1;
	} else  return 0;
}

/* like isnormalmbox, but date format is Fri Jun  2 15:50:48 1995 CDT */

int
istrailingmbox (end)
	char *end;
{
	/* alternate form 1: time zone at the end.
	   this is the one the Mail manual approves of.
	*/

	if (isalpha (end[ 0])   /* time zone */
	&&  isalpha (end[-1])
	&&  isalpha (end[-2])

	&&  isspace (end[-3])

	&&  isdigit (end[-4])   /* year */
	&&  isdigit (end[-5])
	&&  isdigit (end[-6])
	&&  isdigit (end[-7])

	&&  isspace (end[-8])

	&&  isdigit (end[-9])   /* seconds */
	&&  isdigit (end[-10])

	&&  ':' ==   end[-11]

	&&  isdigit (end[-12])   /* minutes */
	&&  isdigit (end[-13])

	&&  ':' ==   end[-14]

	&&  isdigit (end[-15])  /* hour */
	&&  isdigsp (end[-16])

	&&  isspace (end[-17])

	&&  isdigit (end[-18])  /* day */
	&&  isdigsp (end[-19])

	&&  isspace (end[-20])

	&&  isalpha (end[-21])  /* month */
	&&  isalpha (end[-22])
	&&  isalpha (end[-23])

	&&  isspace (end[-24])

	&&  isalpha (end[-25])
	&&  isalpha (end[-26])
	&&  isalpha (end[-27])) {
		return 1;
	} else  return 0;
}

/* like isnormalmbox, but date format is Fri Jun  2 15:50:48 CDT 1995 */

int
isincludedmbox (end)
	char *end;
{
	/* alternate form 2: time zone before the year
	   this is the one trn uses.
	*/

	if (isdigit (end[ 0])   /* year */
	&&  isdigit (end[-1])
	&&  isdigit (end[-2])
	&&  isdigit (end[-3])

	&&  isspace (end[-4])

	&&  isalpha (end[-5])   /* time zone */
	&&  isalpha (end[-6])
	&&  isalpha (end[-7])

	&&  isspace (end[-8])

	&&  isdigit (end[-9])   /* seconds */
	&&  isdigit (end[-10])

	&&  ':' ==   end[-11]

	&&  isdigit (end[-12])   /* minutes */
	&&  isdigit (end[-13])

	&&  ':' ==   end[-14]

	&&  isdigit (end[-15])  /* hour */
	&&  isdigsp (end[-16])

	&&  isspace (end[-17])

	&&  isdigit (end[-18])  /* day */
	&&  isdigsp (end[-19])

	&&  isspace (end[-20])

	&&  isalpha (end[-21])  /* month */
	&&  isalpha (end[-22])
	&&  isalpha (end[-23])

	&&  isspace (end[-24])

	&&  isalpha (end[-25])
	&&  isalpha (end[-26])
	&&  isalpha (end[-27])) {
		return 1;
	} else  return 0;
}

/* return true if the line is an mbox From header.
   somewhat less conservative than 4.3 Mail (it accepts a 
   null username, since bounce messages sometimes are missing this)
   but much more conservative than simply flagging every line that
   begins with "From "
*/

int
ismbox (what)
	char *what;
{
	if (starts (what, "From ")) {
		int len = strlen (what);

		if (len > 29) {
			int kind;
			char *end = what + len - 2;

			if ((kind = isnormalmbox (end))) return 26;
			if ((kind = istrailingmbox (end))) return 30;
			if ((kind = isincludedmbox (end))) return 30;
			return 0;
		}
	}

	return 0;
}

/* return true if the line is the start of a message in whatever that
   format is that starts messages with four control-As
*/

int
isctrla (what)
	char *what;
{
	if (starts (what, "\001\001\001\001")) return 1;
	else return 0;
}

/* return true if the line matches the start of a babyl message */

int
isbabyl (what)
	char *what;
{
	if (starts (what, "\037\014")) return 1;
	else return 0;
}

/* return true if the line is the string that starts a BABYL message's
   second set of headers
*/

int
isbabyl2 (what)
	char *what;
{
	if (same (what, "*** EOOH ***\n")) return 1;
	else return 0;
}

int
ispostmark (what)
	char *what;
{
	return ismbox (what) || ismtxt (what) || isctrla (what) ||
		isbabyl (what);
}
