/* EMACS_MODES: !lnumb !fill */
#define NAME "extpost"
#define VERSION "2.0"

#include <stdio.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <dos.h>
#include <stdlib.h>
#include <time.h>


#define OK 0
#define ERROR -1
#define FATAL -2

#define PREPOST         0x0005      /* Main Types */
#define EMAIL           0x0002
#define EXTERNAL        0x0006
#define EMAIL_VERBOSE   0x0007

#define ATCHAR  '@'         /* WWIVnet @ char, user@system */
#define EOT     '\3'        /* End Of Text */
#define CR	'\015'      /* Carriage Return */
#define LF	'\012'      /* Line Feed */
#define FF	'\014'        /* Form Feed (New Page) */

#define MAXP 10                /* Maximum pN.net ie. p1.net ... pN.net */
#define ERRLOG  "extpost.err"  /* File to log errors to */

#define MAXSYS  (unsigned short)65535  /* highest node number for WWIVnet */

#define MAXLINE 128         /* Maximum length of a line in a message */
#define MAXPATH 81          /* Maximum length of a DOS filesytem pathname */
#define MAXELM  30          /* Maximum number of elements for temp. array */
#define MSGLEN  31000       /* Max number of bytes for a single message */

                            /* These two items allow an overall syntax check */
#define HEADITEMS 8      /* Number of items in the header file specified */
                            /* in the config file */
#define CONFITEMS 20        /* Number of items in the config file */


/* For Pattern Matching Routines */
#define TRUE		1
#define FALSE		0
#define ABORT		-1
#define NEGATE_CLASS	'^'

char array[MAXELM][MAXLINE];   /* temp array */
int error; /* error flag/counter */
int append; /* append to p1.net flag 1=yes, 0=create p1.net-pN.net */

FILE *fe;

/* From WWIVnet Doc */
typedef struct {
        unsigned short  tosys,         /* destination system */
                        touser,        /* destination user */
                        fromsys,       /* originating system */
                        fromuser;      /* originating user */
        unsigned short  main_type,     /* main message type */
                        minor_type;    /* minor message type */
        unsigned short  list_len;      /* # of entries in system list */
        unsigned long   daten;         /* date/time sent */
        unsigned long   length;        /* # of bytes of msg after header */
        unsigned short  method;        /* method of compression */
} net_header_rec;

/* myheader structure */
typedef struct {
        unsigned short  tosys,         /* destination system */
                        touser,        /* destination user */
                        fromsys,       /* originating system */
                        fromuser;      /* originating user */
        unsigned short  main_type,     /* main message type */
                        minor_type;    /* minor message type */
        unsigned long   length;        /* # of bytes of msg after header */
	char title[MAXLINE];           /* Title of message */
	char poster[MAXLINE];          /* Verbose description of user */

} myheader;

typedef struct {
	char bbs[MAXPATH];     /* path for WWIV bbs directory */
	char data[MAXPATH];    /* path for WWIV data directory */
	char infile[MAXPATH];  /* path for input file */
	char lenfile[MAXPATH]; /* path for a file to store message lengths */
	char titfile[MAXPATH]; /* path for a file to store message titles */
	char tofile[MAXPATH];  /* path for a file to store message to lines */
	char frmfile[MAXPATH]; /* path for a file to store mesg from lines */
	char tmpfile[MAXPATH]; /* path for a temporary file */
	char msg_sep[MAXLINE]; /* reg. exp. denotes begin of message */
	char subject[MAXLINE]; /* reg. exp. that denotes Subject: line */
	char to[MAXLINE];      /* reg. exp. that denotes To: line */
	char from[MAXLINE];    /* reg. exp. that denotes From: line */
} config;

unsigned short user_at_system();
myheader mh;
config cf;
net_header_rec nh;
void main(int argc, char *argv[])
{

	int i,j;
	unsigned long length;
	long T;
	char s[MAXLINE];

	error=0;
printf("+----------------------------------------------------------------\n");
printf("| [%s:%s] Copyright (c) 1991, 1992 Andrew Gaunt.\n",NAME,VERSION);
printf("| All Rights Reserved\n");
printf("| Do not use without express permission from the author.\n");
printf("+----------------------------------------------------------------\n");

	if (argc==1){
		printf("usage: %s [-a] config_file ...\n",argv[0]);
		myexit(FATAL);
	}

	/* Open the error log file */
	if ( (fe=fopen(ERRLOG,"w")) == NULL ){
		printf("FATAL: can't open error log %s for writing.\n",ERRLOG);
		myexit(FATAL);
	}

	j=1;
	if (strcmp(argv[1],"-a")==NULL){
		j=2;
		append=1;
	}
	for (;j<argc;j++){

/* 		putchar(FF); */
		/* Read in the configuration file, current directory */
		if ( (i=readin_config(argv[j]))!= CONFITEMS){
			sprintf(s,"config file, %s corrupted.\n\t%d items read; %d needed\n",argv[j],i,CONFITEMS);
			errlog(s);
			myexit(FATAL);
		}
		print_config();
/*  		print_mh_header(); /* DEBUG */

		if (filter(cf.infile,cf.tmpfile) != OK){
			errlog("filter failed.\n");
			myexit(FATAL);
		}

		if(reformat(cf.tmpfile,cf.infile) != OK){
			errlog("reformat failed.\n");
			errlog(s);
			myexit(FATAL);
		}

		if(create_netfile() != EOF){
			errlog("create_netfile failed.\n");
			myexit(FATAL);
		}
		printf("\n-------------------------------\n");
		printf("[%s:%s] run complete.\n",NAME,VERSION);
	}
}


int fgetline(s,max,fg)
char s[];
int max;
FILE *fg;
{
  int i,c;
  i=0;
  while ( (c=fgetc(fg)) != EOF){
/*     printf("[%c]",c); /* DEBUG */
    if (c=='\n' || i>=max || c=='\t' ){
      break;
    }
    /* Comments begin with # and end with newline */
    if (c=='#'){
      while( (c=fgetc(fg))!=EOF ){
	if(c=='\n'){
          break;
        }
      }
      continue;
    }
    s[i]=c;
    i++;
  }
  s[i]='\0';
  return(i);
}

/* Read from fi up to max number of items into array */
/* and return number of items read */
int readin_array(fi,max)
FILE *fi;
int max;
{
	int i;
	char s[MAXLINE];

	init_array();
	i=0;
	while ( i<max ){
		if ( fgetline(array[i],MAXLINE,fi) == NULL){
			break;
		}

/*    		printf("\t%d:[%s]\n",i,array[i]); /* FOR DEBUG */

 		if ( (strcmp(array[i],"")) == NULL){
			break;
		}

		i++;
		if ( i >= MAXELM ){
			sprintf(s,"array full: %d lines\n",MAXELM);
			errlog(s);
			return(FATAL);
		}
	}
	return(i);
}

int readin_config(f)
char f[];
{
	FILE *fi;
	char s[MAXLINE];
	int i;
	if ( (fi=fopen(f,"r")) == NULL ){
		sprintf(s,"can't read config file %s.\n",f);
		errlog(s);
		return(FATAL);
	}
	if ( (i=readin_array(fi,CONFITEMS)) != CONFITEMS){
		return(i);
	}
	sprintf(cf.bbs,"%s",array[0]);
	strcpy(cf.data,array[1]);
	strcpy(cf.infile,array[2]);
	strcpy(cf.lenfile,array[3]);
	strcpy(cf.titfile,array[4]);
	strcpy(cf.tofile,array[5]);
	strcpy(cf.frmfile,array[6]);
	strcpy(cf.tmpfile,array[7]);
	strcpy(cf.msg_sep,array[8]);
	strcpy(cf.subject,array[9]);
	strcpy(cf.to,array[10]);
	strcpy(cf.from,array[11]);

	mh.tosys=(unsigned short)atoi(array[12]);    /* dest. system */
	mh.fromsys=(unsigned short)atoi(array[13]);  /* originating system */
        mh.touser=(unsigned short)atoi(array[14]);   /* destination user */
        mh.fromuser=(unsigned short)atoi(array[15]); /* originating user */
	switch atoi(array[16]){
		case EMAIL: /* Email */
			mh.main_type=EMAIL;
			break;

		case EMAIL_VERBOSE: /* Email, sent to a users name */
			mh.main_type=EMAIL_VERBOSE;
			break;

		case EXTERNAL: /* for external programs */
			mh.main_type=EXTERNAL;
			break;

		case PREPOST: /* Prepost */
		default:
			mh.main_type=PREPOST;
			break;
	}
	mh.minor_type=(unsigned short)atoi(array[17]); /* minor message type */
	strcpy(mh.title,array[18]);         /* title and poster not included */
	strcpy(mh.poster,array[19]);

	fclose(fi);
	return(i);
}


int readin_header(f)
char f[];
{
	FILE *fi;
	int i;
	char s[MAXLINE];

	if ( (fi=fopen(f,"r")) == NULL ){
		sprintf(s,"can't read header file %s.\n",f);
		errlog(s);
		return(FATAL);
	}

	if ( (i=readin_array(fi,HEADITEMS)) != HEADITEMS){
		return(i);
	}
	mh.tosys=(unsigned short)atoi(array[0]);    /* dest. system */
	mh.fromsys=(unsigned short)atoi(array[1]);  /* originating system */
        mh.touser=(unsigned short)atoi(array[2]);   /* destination user */
        mh.fromuser=(unsigned short)atoi(array[3]); /* originating user */
	switch atoi(array[4]){
		case EMAIL: /* Email */
			mh.main_type=EMAIL;
			break;

		case EMAIL_VERBOSE: /* Email, sent to a users name */
			mh.main_type=EMAIL_VERBOSE;
			break;

		case EXTERNAL: /* for external programs */
			mh.main_type=EXTERNAL;
			break;

		case PREPOST: /* Prepost */
		default:
			mh.main_type=PREPOST;
			break;
	}
	mh.minor_type=(unsigned short)atoi(array[5]); /* minor message type */
	strcpy(mh.title,array[6]);         /* title and poster not included */
	strcpy(mh.poster,array[7]);
	fclose(fi);
	return(i);
}

create_netfile()
{
	int c,i,j,msgnum,busy;
	unsigned long ml;
	char s[MAXPATH];
	char s1[MAXLINE];
	FILE *fi,*fo,*fp,*fti,*fto,*ffr;

	busy=0;
	/* Create next for output p?.net */
	if (append!=1){
		i = 0;
		do {
			i++;
			sprintf( s, "%sP%d.NET", cf.data, i);
			fo = fopen(s, "rb");
			if (fo == NULL) {
				fclose(fo);
				printf("Creating %s.\n",s);
				fo = fopen(s, "wb");
				if (fo == NULL){
					sprintf(s1,"can't create %s.\n",s);
					errlog(s1);
					return(FATAL);
				}
				break;
			} else {
				fclose(fo);
			}
		} while (i < MAXP);
	}
	else{
		printf("Appending to p1.net.\n");
		fo = fopen("p1.net", "ab");
		if (fo == NULL){
			sprintf(s1,"can't create %s.\n",s);
			errlog(s1);
			return(FATAL);
		}
	}
	/* Open the input file, specified in the configuration file */
	if ( (fi=fopen(cf.infile,"rb")) == NULL ){
		sprintf(s,"can't read input file %s.\n",cf.infile);
		errlog(s1);
		return(FATAL);
	}

	/* Open file that contains message length data */
	if ( (fp=fopen(cf.lenfile,"r")) == NULL ){
		sprintf(s1,"can't read input file %s.\n",cf.lenfile);
		errlog(s1);
		return(FATAL);
	}
/* 	fgets(s,MAXLINE,fp); /* Toss the first length in the bit bucket */
	                  /* It's either zero or the length of any garbage */
	                  /* at the beginning of the file */

	/* Open file that contains message titles */
	if ( (fti=fopen(cf.titfile,"r")) == NULL ){
		sprintf(s1,"can't read input file %s.\n",cf.titfile);
		errlog(s1);
		return(FATAL);
	}
/*	fgets(s,MAXLINE,fti); /* Toss the title in the bit bucket */

	/* Open file that contains to lines */
	if ( (fto=fopen(cf.tofile,"r")) == NULL ){
		sprintf(s1,"can't read input file %s.\n",cf.tofile);
		errlog(s1);
		return(FATAL);
	}
/*	fgets(s,MAXLINE,fto); /* Toss first one in the bit bucket */

	/* Open file that contains from lines */
	if ( (ffr=fopen(cf.frmfile,"r")) == NULL ){
		sprintf(s1,"can't read input file %s.\n",cf.frmfile);
		errlog(s1);
		return(FATAL);
	}
/*	fgets(s,MAXLINE,ffr); /* Toss first one in bit bucket */

 	msgnum=0;
	while (1){
		switch(	c=fgetc(fi)){

			case EOF:
				flushall();
				fclose(fi);
				fclose(fo);
				fclose(fp);
				fclose(fti);
				fclose(fto);
				fclose(ffr);
				return(EOF);

			case EOT:
				msgnum++;
				printf("\n-------------------------------\n");
				printf("Message number %03d.\n",msgnum);
				do{
					if(fgetline(s,MAXLINE,fti)==NULL){
						errlog("titles out of sync.\n");
						break;
					}
				}while(strlen(s)<strlen(cf.subject));
				sprintf(mh.title,"%-40s",s);
  				printf("Title \"%s\"\n",mh.title);

				if (mh.main_type==EMAIL){
 					do{
						if(fgetline(s,MAXLINE,fto)==NULL){
							errlog("To's out of sync.\n");
							break;
						}
					}while(strlen(s)<strlen(cf.to));
					if(user_at_system(s,cf.to,0)!=0){
						mh.touser=user_at_system(s,cf.to,0);
					}
					if(user_at_system(s,cf.to,1)!=0){
						mh.tosys=user_at_system(s,cf.to,1);
					}
/* 					printf("TO USER: %u\n",mh.touser); /* DEBUG */

					do{
						if(fgetline(s,MAXLINE,ffr)==NULL){
							errlog("From's out of sync.\n");
			     				break;
						}
					}while(strlen(s)<strlen(cf.from));

					if(user_at_system(s,cf.from,0)!=0){
						mh.fromuser=user_at_system(s,cf.from,0);
					}
					if(user_at_system(s,cf.from,1)!=0){
						mh.fromsys=user_at_system(s,cf.from,1);
					}
/* 					printf("FROM USER: %u\n",mh.fromuser); /* DEBUG */
				}

/* 				fgets(s,MAXLINE,fp);  OLD WAY */
				if(fgetline(s,MAXLINE,fp)==NULL){
					errlog("msg lengths out of sync.\n");
					break;
				}


				ml=atol(s);
				mh.length=ml;
/* 				printf("Text length: %ld\n",mh.length); /* DEBUG */

				write_header(fo);
				printf("Writing message ");
				break;

			default:
/*				putchar(c); /* FOR DEBUG (print mesg text) */
				switch(busy){
					case 20: printf("-\b");break;;
					case 40: printf("\\\b");break;;
					case 60: printf("|\b");break;;
					case 80: printf("/\b");break;;
					default: if(busy>80){
							busy=0;
						 }
				}
				busy++;
				if (msgnum>0){
					fputc(c,fo);
				}
		}
	}
}


int init_array()
{
	int i;
	i=0;
	for (i=1;i<MAXELM;i++){
		strcpy(array[i],"");
		i++;
	}
	return(OK);
}


/*
 *   Give it the name of the input file and a temporary file it can use 
 * The reformated data will end up in the temporary file, to be used
 * later on. This routine also counts the number of characters for the
 * text (only) of each message and stores this info to a file named by
 * cf.lenfile
 *
 *   An EOT marker is placed just before the beginning of the
 * text of each message, thus marking the End Of Text of the
 * previous message
 *
 */
reformat(i,o)
char i[],o[];
{
	FILE *fi,*fo,*fp,*fti,*fto,*ffr;
	char s[MAXLINE];
	char s1[MAXLINE];
	unsigned long l;
	int msgnum;
	int j;
	int ti; /* Title found flag */
	int to; /* To found flag */
	int fr; /* From found flag */

	printf("Reformatting %s -> %s\n",i,o);

	if ( (fi=fopen(i,"rb")) == NULL ){
		sprintf(s1,"can't read input file %s.\n",i);
		errlog(s1);
		return(FATAL);
	}

	if ( (fo=fopen(o,"wb")) == NULL ){
		sprintf(s1,"can't write to file %s.\n",o);
		errlog(s1);
		return(FATAL);
	}

 	if ( (fp=fopen(cf.lenfile,"w")) == NULL ){
		sprintf(s1,"can't write length file %s.\n",cf.lenfile);
		errlog(s1);
		return(FATAL);
	}
 	if ( (fti=fopen(cf.titfile,"wb")) == NULL ){
		sprintf(s1,"can't write title file %s.\n",cf.titfile);
		errlog(s1);
		return(FATAL);
	}
 	if ( (fto=fopen(cf.tofile,"wb")) == NULL ){
		sprintf(s1,"can't write title file %s.\n",cf.tofile);
		errlog(s1);
		return(FATAL);
	}
 	if ( (ffr=fopen(cf.frmfile,"wb")) == NULL ){
		sprintf(s1,"can't write title file %s.\n",cf.frmfile);
		errlog(s1);
		return(FATAL);
	}
	l=0;
	ti=0;
	to=0;
	fr=0;
	msgnum=0;
	printf("Message number 000\b\b\b");
	while ( fgets(s,MAXLINE-1,fi)  ){
		if (wildmat(s,cf.msg_sep)!=0){
			fprintf(fo,"%c",EOT);
			printf("%03d\b\b\b",msgnum+1);
			if (msgnum>0){
				fprintf(fp,"%ld\n",l);
				if (ti==0){
					fprintf(fti,"%s\r\n",mh.title);
				}
				if (to==0){
					fprintf(fto,"%s\r\n","<TO UNKNOWN>");
				}
				if (fr==0){
					fprintf(ffr,"%s\r\n","<FROM UNKNOWN>");
				}
				l=0;
				ti=0;
				to=0;
				fr=0;
			}
			msgnum++;
		}
		if (msgnum>0){
			if (wildmat(s,cf.subject)!=0){
				if (ti==0){
					fprintf(fti,"%s",s);
					ti=1;
				}
			}
			if (wildmat(s,cf.to)!=0){
				if (to==0){
					fprintf(fto,"%s",s);
					to=1;
				}
			}
			if (wildmat(s,cf.from)!=0){
				if (fr==0){
					fprintf(ffr,"%s",s);
					fr=1;
				}
			}
		}
		for(j=0;j<strlen(s);j++){
/*  			printf("%02x:%c\n",s[j],s[j]); /* FOR DEBUG */
			if(msgnum>0){
				fputc(s[j],fo);
				l++;
			}
			if (l>MSGLEN){
				sprintf(s1,"message %d is too long.\n",msgnum);
				errlog(s1);
				return(FATAL);
			}
		}
	}
	/* write out stuff for last message */
	fprintf(fp,"%ld\n",l);
	if (ti==0){
		fprintf(fti,"%s\r\n",mh.title);
	}
	if (to==0){
		fprintf(fto,"%s\r\n","<TO UNKNOWN>");
	}
	if (fr==0){
		fprintf(ffr,"%s\r\n","<FROM UNKNOWN>");
	}

	printf("DONE! %d messages.\n",msgnum);
	flushall();
	fclose(fi);
	fclose(fo);
	fclose(fp);
	fclose(fti);
	fclose(fto);
	fclose(ffr);
	return(OK);
}

/* Get rid of unwanted characters, like the EOT which is used by this */
/* program to show the End Of Text */
filter(i,o)
char i[],o[];
{
	FILE *fi,*fo;
	char s[MAXLINE];
	char s1[MAXLINE];
	int c;

	printf("Filtering %s -> %s ",i,o);

	if ( (fi=fopen(i,"rb")) == NULL ){
		sprintf(s1,"can't read input file %s.\n",i);
		errlog(s1);
		return(FATAL);
	}

	if ( (fo=fopen(o,"wb")) == NULL ){
		sprintf(s1,"can't write input file %s.\n",o);
		errlog(s1);
		return(FATAL);
	}

	while ( (c=fgetc(fi)) != EOF){
		switch(c) {
			case EOT:
				printf("EOT\b\b\b   \b\b\b");
				break;

			default:
				fputc(c,fo);
		}
	}
	flushall();
	fclose(fi);
	fclose(fo);
	printf("DONE\n");
	return(OK);
}

/* Write a WWIVnet header, the system, major/minor types, and stuff */
/* come from the file named by cf.header */
write_header(fo)
FILE *fo;
{
	long T;
	char s[MAXLINE];
	char post_date[30];
	struct date datep;
	struct time timep;
	int i;

	time(&T);

	strcpy(s,ctime(&T));

	/* Don't let post_date contain a newline */
	for(i=0;i<strlen(s);i++){
		if (s[i]==LF){
			post_date[i]='\0';
		}
		else{
			post_date[i]=s[i];
		}
	}	
	

	gettime(&timep);
	getdate(&datep);

	nh.tosys=mh.tosys;
	nh.touser=mh.touser;
	nh.fromsys=mh.fromsys;
	nh.fromuser=mh.fromuser;
	nh.main_type=mh.main_type;
	nh.minor_type=mh.minor_type;
	nh.list_len=0;
	nh.daten=dostounix(&datep, &timep);
	nh.length=mh.length+strlen(mh.title)+1+strlen(mh.poster)+1+strlen(post_date)+2;
	nh.method=0;

	printf("Poster %s, Date %s\n",mh.poster,post_date);
	print_nh_header();

/*	return(0); /* FOR DEBUG */


	fflush(fo);
 	write(fileno(fo),(void *)&nh,sizeof(net_header_rec));
	/*write(fileno(fo),(void *)nh.list,2*nh.list_len);*/ /* Not using */
 	write(fileno(fo),(void *)mh.title,strlen(mh.title)); 
	write(fileno(fo),'\0',sizeof(char)); 
 	write(fileno(fo),(void *)mh.poster,strlen(mh.poster));
	fflush(fo);
	fprintf(fo,"\r");
	fflush(fo);
 	write(fileno(fo),(void *)post_date,strlen(post_date));
	fflush(fo);
	fprintf(fo,"\r\n");
	fflush(fo);
	return(OK);
}

/* The below code has been imported for the wildcard matching features */
/* I've added to allow flexibilty in the Message (From:) separator strings */
/* and other such things where regular expressions are handy */

/*
 *  Do shell-style pattern matching for ?, \, [], and * characters.
 *  Might not be robust in face of malformed patterns; e.g., "foo[a-"
 *  could cause a segmentation violation.  It is 8bit clean.
 *
 *  Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986.
 *  Rich $alz is now <rsalz@bbn.com>.
 *  Special thanks to Lars Mathiesen <thorinn@diku.dk> for the ABORT code.
 *  This can greatly speed up failing wildcard patterns.  For example:
 *	pattern: -*-*-*-*-*-*-12-*-*-*-m-*-*-*
 *	text 1:	 -adobe-courier-bold-o-normal--12-120-75-75-m-70-iso8859-1
 *	text 2:	 -adobe-courier-bold-o-normal--12-120-75-75-X-70-iso8859-1
 *  Text 1 matches with 51 calls, while text 2 fails with 54 calls.  Without
 *  the ABORT, then it takes 22310 calls to fail.  Ugh.
 */

/* Forward declaration. */
static int	DoMatch();

/*
**  See if the text matches the p, which has an implied leading asterisk.
*/
static int
Star(text, p)
    register char	*text;
    register char	*p;
{
    register int	ret;

    do
	ret = DoMatch(text++, p);
    while (ret == FALSE);
    return ret;
}


/* Match text and p, return TRUE, FALSE, or ABORT. */
static int
DoMatch(text, p)
    register char	*text;
    register char	*p;
{
    register int 	 last;
    register int 	 matched;
    register int 	 reverse;

    for ( ; *p; text++, p++) {
	if (*text == '\0' && *p != '*')
	    return ABORT;
	switch (*p) {
	case '\\':
	    /* Literal match with following character. */
	    p++;
	    /* FALLTHROUGH */
	default:
	    if (*text != *p)
		return FALSE;
	    continue;
	case '?':
	    /* Match anything. */
	    continue;
	case '*':
	    /* Trailing star matches everything. */
	    return *++p ? Star(text, p) : TRUE;
	case '[':
	    if ( (reverse = p[1]) == NEGATE_CLASS)
		/* Inverted character class. */
		p++;
	    for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p)
		/* This next line requires a good C compiler. */
		if (*p == '-' ? *text <= *++p && *text >= last : *text == *p)
		    matched = TRUE;
	    if (matched == reverse)
		return FALSE;
	    continue;
	}
    }

    return *text == '\0';
}

/*  User-level routine.  Returns TRUE or FALSE. */
int wildmat(text, p)
    char	*text;
    char	*p;
{
    return DoMatch(text, p) == TRUE;
}


/* DEBUGING ROUTINES */

print_array()
{
	int i;
	printf("** array[*]\n");
	for (i=0;i<MAXELM;i++){
		printf("%-2d. [%s]\n",i,array[i]);
	}
	printf("** end\n");
	return(OK);
}

print_nh_header()
{
printf("To %u@%u, ",nh.touser,nh.tosys);
printf("from %u@%u, ",nh.fromuser,nh.fromsys);
printf("type %u-%u (",nh.main_type,nh.minor_type);
switch(nh.main_type){
	case EMAIL:
		printf("EMAIL), ");
		break;
	case EMAIL_VERBOSE:
		printf("EMAIL TO USERS NAME), ");
		break;
	case PREPOST:
		printf("PREPOST), ");
		break;
	case EXTERNAL:

		printf("EXTERNAL), ");
		break;
	default:
		printf("UNKNOWN), ");
		break;
}

/* printf("\tList length      nh.list_len: %u: UNUSED\n",nh.list_len); */
/* printf("\tTime stamp          nh.daten: %u\n",nh.daten); */
printf("length %u\n",nh.length);
return(OK);
}

print_mh_header()
{
printf("MH Header:\n");
printf("\tTo system   : %u\n",mh.tosys);
printf("\tFrom system : %u\n",mh.fromsys);
printf("\tTo user     : %u\n",mh.touser);
printf("\tFrom user   : %u\n",mh.fromuser);
printf("\tMain type   : %u\n",mh.main_type);
printf("\tMinor type  : %u\n",mh.minor_type);
printf("\tTitle       : %s\n",mh.title);
printf("\tPoster      : %s\n",mh.poster);
printf("\tText length : %u\n",mh.length);
return(OK);
}

print_config()
{
printf("+-----------------------------------------------------------\n");
printf("| Configuration:\n");
printf("+-----------------------------------------------------------\n");
printf("|\tBBS  Dir     : %s\n",cf.bbs);
printf("|\tDATA Dir     : %s\n",cf.data);
printf("|\tInput file   : %s\n",cf.infile);
printf("|\tTemp file    : %s\n",cf.tmpfile);
printf("|\tMessage Sep  : %s\n",cf.msg_sep);
printf("|\tTitle regexp : %s\n",cf.subject);
printf("|\tTo regexp    : %s\n",cf.to);
printf("|\tFrom regexp  : %s\n",cf.from);
printf("|\tMsglen file  : %s\n",cf.lenfile);
printf("+-----------------------------------------------------------\n");
return(OK);
}

errlog(s)
char s[];
{
	fprintf(fe,"ERROR: %s\n",s);
	error++;
	return(OK);
}

myexit(r)
int r;
{
	char s[MAXLINE];

	/* close the error log */
	fclose(fe);
	if ( (fe=fopen(ERRLOG,"r")) == NULL ){
		printf("FATAL: can't open error log %s for reading.\n",ERRLOG);
		exit(FATAL);
	}
	printf("%d ERROR(S) have occuured:\n",error);
	while ( fgets(s,MAXLINE-1,fe)  ){
		printf("\t%s",s);
	}			
	fclose(fe);
	exit(r);
	return(OK);
}

/* if mode is 0, return the usernumber found in s, else return system number */
unsigned short user_at_system(s,pattern,mode)
char s[];
char pattern[];
int mode;
{
	unsigned short unum;
	unsigned short sysnum;
	char user[30];
	char system[6];
	char pat[MAXLINE];
	int i;
	int j;
	int ok;

/* 	printf("\ns:\n%s\n",s); /* for DEBUG */
/* 	printf("pattern: [%s]\n",pattern); /* for DEBUG */

	/* Skip over pattern */
	for(i=0;i<strlen(s);i++){
		strncpy(pat,s,i);
		pat[i+1]='\0';
		if(wildmat(pat,pattern)){
/* 			printf("got pat: [%s]\n",pat); /* for DEBUG */
			ok=1;
			break;
		}
		ok=0;
	}
	if(!ok){
/*		printf("Pattern not found.\n"); /* for DEBUG */
		return((unsigned short)0);
	}


	/* get the user number */
	j=0;
	while (i<strlen(s)){
/* 		printf("\ns:\n%s\n",s); /* for DEBUG */
/* 		curs(i); /* for DEBUG */
/* 		printf("i=%d\n",i); /* for DEBUG */
		if(s[i]==ATCHAR){
/* 			printf("Got an @\n"); /* for DEBUG */
			j++;
			i++;
			break;
		}
		user[j]=s[i];
		i++;
		j++;
	}
	user[j]='\0';
/* 	printf("user: [%s]\n",user); /* for DEBUG */

/* 	printf("i=%d\n",i); /* for DEBUG */

	/* get the system number */
	j=0;
	for(;i<strlen(s);i++,j++){
		system[j]=s[i];
	}
	system[j+1]='\0';

/* 	printf("system: [%s]\n",system); /* for DEBUG */

        unum=(unsigned short)atoi(user);
        sysnum=(unsigned short)atoi(system);

/* 	printf("unum: [%u]\nsysnum [%u]\n",unum,sysnum); /* for DEBUG */

	if(mode==1 &&  (sysnum > 0) && (sysnum < MAXSYS) ){
		return(sysnum);
	}
	return(unum);
}

/*
curs(i)
int i;
{
	int j;
	for(j=0;j<i;j++){
		printf(" ");
	}
	printf("^\n");
}
*/