/******************************************************************************
 * 	This is the main METAL message system module (A Heavy BBS!!)
 *
 *	Name: METAL.C	VERSION 1.20a
 *
 *			Copyright (c) 1984  Tim Gary
 *			     Delphi Data Systems
 *			     All rights reserved.
 *
 *	This is a commercial product, and is for use by a single system
 *	and user.  Copies may be made for backup purposes ONLY.
 *
 *	Send any comments, bugs, updates, fixes, etc.. to:
 *		Delphi Data Systems
 *		PO Box 39-1567
 *		Mountain View, Ca. 94039
 *
 *	Voice phone (415) 941-7388 (Tim-home)	  (10am-9:30pm only, PLEASE!)
 *	Computer phone (415) 949-1476     (Up sometimes..)
 *	Piconet computer phone (415) 965-4097
 *
 *
 ******************************************************************************
 *
 * 1.20a 11/04/84  Alias to apply command is COMMENT.
 * 1.10e 11/03/84  Added APPLY command.
 * 1.10e 10/31/84  Functions moved out of this routine, overlays functions
 *		  added, new UNKILL command (also RESTORE=same thing).
 * 1.10c 10/12/84  Some routines moved to MEMISC overlay to conserve space.
 *
 * 1.10b 10/04/84  Chat fixed for xx columns, auto return..
 * 1.10b 10/01/84  Spelling error fixed.  Other cosmetics.
 *
 * 1.10a  9/27/84  More cosmetic changes.
 * 1.10a  9/08/84  Chat routines expanded to include user name, and if
 *		  sysop is not around, ask if they would like to leave
 *		  private comments to the sysop.
 * 1.10a  9/01/84  Continued work on overlays.
 * 1.10a  8/24/84  JUST STARTING OVERLAY VERSION.
 *
 * 1.01a  7/02/84  Multi-user lastcalr implemented.
 * 1.01a  6/27/84  Multi user OS support cont..  
 * 1.01a  6/10/84  Fixes for Aztec C 1.06.  Added Link to mutil command,
 *		  also started provisions for Multi-user OS's..
 *
 * 1.0b   4/22/84  Problem with mult commands fixed (introduced 9 days ago)
 * 1.0b   4/20/84  Fixed 'U' bug (command changed user.lastread..)
 * 1.0b   4/13/84  Added upper/lower case name ability.  3 User defined
 *		   files may be displayed.  '!' command now restores original
 *		   user status when turning off sysop status.  'Articles'
 *		   command added to allow printing of various text files.
 *
 * 1.0a	  2/15/84  Lastcalr file changed, benefit: pretty xmodem log, and
 *		   user parameters 'stick' when the user changes them and exits
 *		   to CP/M, and then returns.  NOCPM fix.
 *
 *****************************************************************************/

#define MAIN		/* this is for the .h files */

#include "xpm.h"	/* CPMIO header file for i/o operations.*/
#include "hmh.h"	/* METAL header, variable types, etc	*/
#include "hmconfg.h"	/* options/config declarations		*/
#include "ctype.h"

/**************************************************************************
 * This line commented out, and is contained in MEINFREQ.C now.
 * #define TITLE "\nMetal Message System..(A Heavy BBS)\nVersion 1.20a\n\n"
 **************************************************************************/

/* these need to be declared so the structure will work */

int type(),readmsgs(),expert(),whoisthis();

/* now for the main command structure with abbreviations, and routines */

struct cmdtype maincomtab[] = {
/*	Command Name		Function	Parameter	Overlay	    */
/*	-------------------	-------------	------------	----------  */
	"AD","D",		ADDUSER,	0,		OVUSER,
	"AP","PLY",		1,		0,		OVSEND,
	"A","RTICLES",		FEATURE,	'A',		OVMISC,
	"B","ULLETINS",		type,		BULLETIN,	0,
	"BYE","\0",		GOODBYE,	NO,		OVMISC,
	"CH","AT",		CHAT,		YES,		OVMISC,
	"CO","MMENT",		1,		0,		OVSEND,
	"C","PM",		GOCPM,		YES,		OVMISC,
	"D","ELETE",		DELETEUSER,	0,		OVUSER,
	"ED","IT",		EDITUSER,	0,		OVUSER,
	"E","NTER",		0,		0,		OVSEND,
	"EX","PERT",		expert,		0,		0,
	"F","EATURES",		FEATURE,	'A',		OVMISC,
	"G","OODBYE",		GOODBYE,	YES,		OVMISC,
	"H","ELP",		type,		HELP,		0,
	"J","UMP",		GOCPM,		NO,		OVMISC,
	"K","ILL",		KILL,		0,		OVKILL,
	"L","IST",		READUSERS,	NOPRINT,	OVINFREQ,
	"M","ESSAGES?",		MSGALERT,	0,		OVINFREQ,
	"N","OTES",		FEATURE,	'N',		OVMISC,
	"O","THERSYS",		type,		OTHERSYS,	0,
	"PR","INT",		READUSERS,	PRINT,		OVINFREQ,
	"PU","RGE",		PURGE,		0,		OVSYSOP,
	"Q","UICKSUMMARY",	0,		NO,		OVSUMM,
	"R","EAD",		readmsgs,	'\0',		0,
	"REP","LY",		0,		-1,		OVSEND,
	"RES","TORE",		UNKILL,		0,		OVKILL,
	"RN","S",		readmsgs,	'P',		0,
	"RP","\0",		readmsgs,	'P',		0,
	"RS","\0",		readmsgs,	'S',		0,
	"RR","S",		readmsgs,	'R',		0,
	"ST","ATS",		STATS,		0,		OVINFREQ,
	"S","UMMARY",		0,		YES,		OVSUMM,
	"UN","KILL",		UNKILL,		0,		OVKILL,
	"U","SERPARMS",		SAVEUSER,	0,		OVINFREQ,
	"W","ELCOME",		type,		WELCOME,	0,
	"WH","O",		whoisthis,	0,		0,
	"Y","ELL",		CHAT,		YES,		OVMISC,
	"X","PERT",		expert,		0,		0,
	"Z","\0",		CALLS,		0,		OVINFREQ,
	"CA","LLERS",		CALLS,		0,		OVINFREQ,
	"#","\0",		STATS,		0,		OVINFREQ,
	"?","\0",		type,		HELP,		0,
	"-","\0",		whoisthis,	0,		0,
	"!","\0",		SOSTAT,		0,		OVSYSOP,
	"+","\0",		READCOMM,	0,		OVSYSOP,
	"//","\0",		CHAT,		NO,		OVMISC,
	0,0,0,0,0
	};

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

/**************************
 * start the main program *
 **************************/

main(argc,argv)
 int argc;
 char *argv[];
{
char temp[40];

if (argc>1) ovloader(OVMENTER,argc,argv);

if (ovloader(OVINFREQ,INIT,argc)==ERROR)	/* initialize the works.. */
	{
	register char *zero=0;
	if (user.status==SYSOP)
		send("\n** USE MECONFIG TO INCREASE AVAILABLE MESSAGE SPACE **\n");
	  else	{
		send("\n** Sorry, but the BBS is in need of repair.  Please try it later! **");
		*zero=0xcd;	/* make sure bye hangs up on this one.. */
		}
	exit(0);
	}

/* if auto read option ON, then do this.. */
if (user.parm.rp==POFF)	/* backwards.. should be PON, but to keep compatible */
	{		/* with the previous version, I did it this way..    */
	send("[Auto Read]\n");
	readmsgs('P');	/* do a RP */
	}

/***************************
 * main command input loop *
 ***************************/

while(1)				/* one giant endless loop.. */
	{
	sprintf(temp,"\n%s%s: ",
		user.parm.expert!=PON ? "(Enter '?' for help)  "
		 : "",user.status==SYSOP ? "Sysop" : "Command");

	if (get_cmd(temp,maincomtab)==ERROR)	/* ERROR=bad command */
		{
		switch (message.number&3)	/* random(ish) error msg */
			{
			case 0:	send("Oh really!\n");
				break;
			case 1: send("I beg your pardon!\n");
				break;
			case 2: send("Say what?\n");
				break;
			default: send("Your typing's a little rusty!\n");
				break;
			}
		strloc=0;	/* sorry, but one error aborts rest.. */
		}	/* error in command */
	}	/* main while loop */

}	/* MAIN loop */ 	 	


/************************************************************************
 *
 * FUNCTIONS: init(), msg_alert(), getlastcalr(), readusers(), showuser(),
 *  saveuser(), disuser(), findbye()   now in MEINFREQ.C
 *
 * FUNCTIONS: askcomments(),feature(),cpm(),goodbye(),chat()   now in MEMISC.C
 *
 * FUNCTIONS: readcomm(),sostat()  now in MESYSOP.C
 *
 ************************************************************************/

/********************************************
 * Get a line of input, and do command if a *
 * match is found....			    *
 ********************************************/

get_cmd(str,cmdlist)
 char *str;
 struct cmdtype *cmdlist;
{
register struct cmdtype *ind;		/* index to go through list */
register char *chind;			/* character index	    */

sepstr=' ';	/* allow space seperator */
do {
   ask(str,buffer,MAXLINE,UP);	/* print prompt, and get line */
   if (*buffer=='/' && buffer[1]!='/')
	{
	strloc=0;	/* nullify rest of line */
	*buffer='\0';
	continue;
	}
   } while (*buffer=='\0');

sepstr='\0';	/* turn this off */

for (ind=cmdlist; ind->abbr; ind++)
	{
	if (!strncmp(buffer,ind->abbr,strlen(ind->abbr)))
		{	/* matched abbreviation */
		chind=buffer+strlen(ind->abbr);
		if (!strncmp(chind,ind->full,strlen(chind)))
			{
			if (ind->ovname==0) (*ind->func)(ind->value);
			  else ovloader(ind->ovname,ind->func,ind->value);
			break;	/* get out of all these nested tests */
			}
		} 	/* abbr. match test */
	}  /* search loop */

if (ind->abbr) return NULL;	/* NULL=all's well */

return ERROR;	/* command not found */

}  /* get_cmd */


/**********************
 * toggle expert mode *
 **********************/

expert(n)
 register int n;
{
user.parm.expert==PON ?		/* so what if it could be an IF.. */
  (send("\n[Novice mode]"),user.parm.expert=POFF) :
  (send("\n[Expert mode]"),user.parm.expert=PON);
}


/*************
 * Show user *
 *************/

whoisthis(n)
 register int n;
{
printf("User - %s %s",user.first,user.last);
}


char ostat=0;	/* these need to be externs here, since overlays */
char otype=0;	/* don't like statics (they don't stick)	 */


/*****************************
 * Check if user matches the passed string
 *****************************/

thisis(s)
 register char *s;
{
char bs[FNAMELEN+LNAMELEN+2];

sprintf(buffer,"%s %s",user.first,user.last);
strcpy(bs,s);  upcase(bs);	/* make passed string upper case only */

if (!ustrcmp(buffer,s) || (user.status==SYSOP && usindex("SYSOP",bs)))
	return TRUE;

return FALSE;
}


/****************************************
 * da..du..du..da..dat's all folks....	*
 ****************************************/

