/* Internet TTY "link" (keyboard chat) server
 * Copyright 1991 Phil Karn, KA9Q
 */
#include <stdio.h>
#include <time.h>
#include "global.h"
#include "mbuf.h"
#include "socket.h"
#include "telnet.h"
#include "session.h"
#include "proc.h"
#include "tty.h"
#include "mailbox.h"
#include "commands.h"

static int Sttylink = -1;	/* Protoype socket for service */
extern int Attended;
static char Tnbanner[] = "Welcome to TTY-Link at %s - The system is %s.\n";

int
ttylstart(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	struct sockaddr_in lsocket;
	int s,type;

	if(Sttylink != -1){
		return 0;
	}
	psignal(Curproc,0);	/* Don't keep the parser waiting */
	chname(Curproc,"TTYlink listener");

	lsocket.sin_family = AF_INET;
	lsocket.sin_addr.s_addr = INADDR_ANY;
	if(argc < 2)
		lsocket.sin_port = IPPORT_TTYLINK;
	else
		lsocket.sin_port = atoi(argv[1]);

	Sttylink = socket(AF_INET,SOCK_STREAM,0);
	bind(Sttylink,(char *)&lsocket,sizeof(lsocket));
	listen(Sttylink,1);
	for(;;){
		if((s = accept(Sttylink,NULLCHAR,(int *)NULL)) == -1)
			break;	/* Service is shutting down */
		
		if(availmem() < Memthresh){
			usprintf(s,"System is overloaded; try again later\r\n");
			shutdown(s,1);
		} else {
			type = TELNET;
			newproc("chat",2048,ttylhandle,s,(void *)&type,NULL,0);
		}
	}
	return 0;
}
/* This function handles all incoming "chat" sessions, be they TCP,
 * NET/ROM or AX.25
 */
void
ttylhandle(s,t,p)
int s;
void *t;
void *p;
{
	int type,index;
	struct session *sp;
	char addr[MAXSOCKSIZE];
	int len = MAXSOCKSIZE;
	struct telnet tn;
	extern char *Motd;
	time_t nowtime;

	type = * (int *)t;
	sockmode(s,SOCK_ASCII);
	sockowner(s,Curproc);	/* We own it now */
	log(s,"open %s",Sestypes[type]);

	/* Allocate a session descriptor */
	if((sp = newsession(NULLCHAR,type,1)) == NULLSESSION){
		usprintf(s,"Too many sessions\n");
		close_s(s);
		return;
	}
	index = sp - Sessions;

	/* Initialize a Telnet protocol descriptor */
	memset((char *)&tn,0,sizeof(tn));
	tn.session = sp;	/* Upward pointer */
	sp->cb.telnet = &tn;	/* Downward pointer */
	sp->s = s;
	sp->proc = Curproc;

	time(&nowtime);		/* current time */

	getpeername(s,addr,&len);
	tprintf("\007Incoming %s session %u from %s on %s",
	 Sestypes[type],index,psocket(addr),ctime(&nowtime));

	usprintf(s, Tnbanner, Hostname, Attended ? "attended" : "unattended");
	if(Motd != NULLCHAR)
		usprintf(s, "%s", Motd);

	tnrecv(&tn);
}

/* Shut down Ttylink server */
int
ttyl0(argc,argv,p)
int argc;
char *argv[];
void *p;
{
	close_s(Sttylink);
	Sttylink = -1;
	return 0;
}
