/* cat > ./ax_mbx.c << '\Rogue\Monster\' */
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include "global.h"
#include "mbuf.h"
#include "ax25.h"
#include "timer.h"
#include "iface.h"
#include "lapb.h"
#include "ax_mbx.h"
#include "cmdparse.h"

static char mbbanner[] = "Welcome to the %s TCP/IP Mailbox\r" ;
static char mbmenu[] = "(C)hat, (S)end, (B)ye > " ;

void
mbx_incom(axp,cnt)
register struct ax25_cb *axp ;
int16 cnt ;
{
	struct mbx *m ;
	struct mbuf *bp, *recv_ax25() ;
	char *cp ;
	extern char hostname[] ;
	void mbx_rx(), mbx_state() ;
	extern char *index() ;
	
	if ((m = (struct mbx *)calloc(1,sizeof(struct mbx))) == NULLMBX) {
		disc_ax25(axp) ;	/* no memory! */
		return ;
	}

	m->state = MBX_CMD ;	/* start in command state */
	m->ax25_cb = axp ;

	pax25(m->name,&axp->addr.dest) ;
	cp = index(m->name,'-') ;
	if (cp != NULLCHAR)			/* get rid of SSID */
		*cp = '\0' ;

	m->lp = m->line ;		/* point line pointer at buffer */
	axp->r_upcall = mbx_rx ;
	axp->s_upcall = mbx_state ;
	axp->user = (char *)m ;

	/* The following is necessary because we didn't know we had a */
	/* "real" ax25 connection until a data packet came in.  We    */
	/* can't be spitting banners out at every station who connects, */
	/* since they might be a net/rom or IP station.  Sorry.  */
	
	bp = recv_ax25(axp,cnt) ;		/* get the initial input */
	free_p(bp) ;				/* and throw it away to avoid confusion */

	/* Now say hi */
	
	if ((bp = alloc_mbuf(strlen(hostname) + strlen(mbbanner) + 2)) == NULLBUF) {
		disc_ax25(axp) ; /* mbx_state will fix stuff up */
		return ;
	}

	*bp->data = PID_FIRST | PID_LAST | PID_NO_L3 ;	/* pid */
	bp->cnt = sprintf(bp->data+1,mbbanner,hostname) + 1 ;

	send_ax25(axp,bp) ;			/* send greeting message */
	(void)mbx_msg(axp, mbmenu) ;		/* send initial menu prompt */	
}

/* mbx_rx collects lines, and calls mbx_line when they are complete. */
/* If the lines get too long, it arbitrarily breaks them. */

void mbx_rx(axp,cnt)
struct ax25_cb *axp ;
int16 cnt ;
{
	struct mbuf *bp, *recv_ax25() ;
	struct mbx *m ;
	char c ;
	int mbx_line() ;
	
	m = (struct mbx *)axp->user ;
	
	if ((bp = recv_ax25(axp,cnt)) == NULLBUF)
		return ;

	while (pullup(&bp,&c,1) == 1) {
		if (c == '\r') {
			*m->lp = '\0' ;			/* null terminate */
			if (mbx_line(m) == -1) {	/* call the line processor */
				free_p(bp) ;		/* toss the rest */
				break ;				/* get out - we're obsolete */
			}
			m->lp = m->line ;		/* reset the pointer */
		}
		else if ((m->lp - m->line) == (MBXLINE - 1)) {
			*m->lp++ = c ;
			*m->lp = '\0' ;
			if (mbx_line(m) == -1) {
				free_p(bp) ;
				break ;
			}
			m->lp = m->line ;
		}
		else
			*m->lp++ = c ;
	}
}

void mbx_state(axp,old,new)
struct ax25_cb *axp ;
int old, new ;
{
	struct mbx *m ;
	void free_mbx() ;
	
	m = (struct mbx *)axp->user ;

	/* dummy for now ... */
	if (new == DISCONNECTED) {
		axp->user = NULLCHAR ;
		free_mbx(m) ;
	}
}

static void
free_mbx(m)
struct mbx *m ;
{
	if (m->to != NULLCHAR)
		free(m->to) ;

	if (m->tfile != NULLFILE)
		fclose(m->tfile) ;
		
	free(m) ;
}


static 
mbx_line(m)
struct mbx *m ;
{
	void ax_session() ;
	char *host ;
	extern char hostname[] ;
	char fullfrom[80] ;
	
	if (m->state == MBX_CMD) {
		switch (tolower(m->line[0])) {
			case 'b':	/* bye - bye */
				disc_ax25(m->ax25_cb) ;
				return -1 ;	/* tell line processor to quit */
				break ;
			case 'c':	/* chat */
				m->ax25_cb->user = NULLCHAR ;
				ax_session(m->ax25_cb,0) ;	/* make it a chat session */
				free_mbx(m) ;
				return -1 ;
				break ;
			case 's':
				if (mbx_to(m) == -1) {
					mbx_msg(m->ax25_cb,
							"Bad address - try 'S name' or 'S name@host'\r") ;
					mbx_msg(m->ax25_cb,mbmenu) ;
				}
				else {
					m->state = MBX_SUBJ ;
					mbx_msg(m->ax25_cb,"Subject: ") ;
				}
				break ;
			default:
				mbx_msg(m->ax25_cb,"Huh?\r") ;
				mbx_msg(m->ax25_cb,mbmenu) ;
		}
	return 0 ;
	}
	else if (m->state == MBX_SUBJ) {
		if (mbx_data(m) == -1) {
			mbx_msg(m->ax25_cb,"Can't create temp file for mail\r") ;
			mbx_msg(m->ax25_cb,mbmenu) ;
			free(m->to) ;
			m->to = NULLCHAR ;
			m->state = MBX_CMD ;
			return 0 ;
		}
		m->state = MBX_DATA ;
		mbx_msg(m->ax25_cb,
			"Enter message.  Terminate with '.' alone in first column:\r") ;
		return 0 ;
	}
	else if (m->state == MBX_DATA) {
		if (m->line[0] == '.' && m->line[1] == '\0') {
			if ((host = index(m->to,'@')) == NULLCHAR)
				host = hostname ;		/* use our hostname */
			else
				host++ ;				/* use the host part of address */

			/* make up full from name for work file */
			sprintf(fullfrom,"%s@%s",m->name,hostname) ;
			
			fseek(m->tfile,0L,0) ;		/* reset to beginning */
			if (queuejob((void *)0,m->tfile,host,m->to,fullfrom) != 0)
				mbx_msg(m->ax25_cb,
						"Couldn't queue message for delivery\r") ;

			free(m->to) ;
			m->to = NULLCHAR ;
			fclose(m->tfile) ;
			m->tfile = NULLFILE ;
			m->state = MBX_CMD ;
			mbx_msg(m->ax25_cb, mbmenu) ;
			return 0 ;
		}
		/* not done yet! */
		fprintf(m->tfile,"%s\n",m->line) ;
		return 0 ;
	}
}

/* send text msg to ax.25 session axp */
static
mbx_msg(axp,msg)
struct ax25_cb *axp ;
char msg[] ;
{
	int len ;
	struct mbuf *bp ;

	len = strlen(msg) ;

	if ((bp = alloc_mbuf(len+1)) == NULLBUF) {
		disc_ax25(axp) ;
		return -1 ;
	}

	bp->cnt = len + 1 ;
	
	*bp->data = PID_FIRST | PID_LAST | PID_NO_L3 ;
	
	memcpy(bp->data+1, msg, len) ;

	send_ax25(axp,bp) ;

	return 0 ;
}

/* Prepare the addressee.  If the address is bad, return -1, otherwise
 * return 0
 */
static
mbx_to(m)
struct mbx *m ;
{
	register char *cp, *cp1 ;

	cp = m->line ;
	while (!isspace(*cp))		/* skip the Send command */
		if (*cp == '\0')		/* also stop for NULLs */
			break ;
		else
			cp++ ;				/* try next character ... */

	if (*cp == '\0')			/* no address here */
		return -1 ;

	while (isspace(*cp))		/* now skip the white space */
		if (*cp == '\0')
			break ;
		else
			cp++ ;

	if (*cp == '\0')			/* no address here */
		return -1 ;

	cp1 = cp ;
	while (!isspace(*cp1))		/* now find end of arg */
		if (*cp1 == '\0')
			break ;
		else
			cp1++ ;

	*cp1 = '\0' ;				/* null terminate the arg */

/*	if (checkaddress(cp) == 0) */	/* see how this address looks */
/*		return -1 ;	*/			/* oops */

	if ((m->to = malloc(strlen(cp) + 1)) == NULLCHAR)
		return -1 ;				/* no room for address */

	strcpy(m->to,cp) ;			/* copy address */

	return 0 ;
}

/* This opens the data file and writes the mail header into it.
 * Returns 0 if OK, and -1 if not.
 */

static
mbx_data(m)
struct mbx *m ;
{
	long t, time();		/* DG2KK: was: time_t */
	char *ptime() ;
	extern char hostname[] ;
	extern FILE *tmpfile();
	extern long get_msgid() ;
	
	if ((m->tfile = tmpfile()) == NULLFILE)
		return -1 ;

	time(&t) ;
	fprintf(m->tfile,"Date: %s",ptime(&t)) ;
	fprintf(m->tfile,"Message-Id: <%ld@%s>\n",get_msgid(),hostname) ;
	fprintf(m->tfile,"From: %s@%s\n",m->name,hostname) ;
	fprintf(m->tfile,"To: %s\n",m->to) ;
	fprintf(m->tfile,"Subject: %s\n\n",m->line) ;

	return 0 ;
}

queuejob()
{
}
