#include "global.h"
#ifdef RLOGINCLI
#include "mbuf.h"
#include "socket.h"

#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: rlogin.c,v 1.14 1996/12/23 20:37:36 root Exp $";
#endif

static char *username = "guest";
static char terminal[] = "ansi";
static char *termspeed = "/38400";

extern FILE *Rawterm;
int rlo_connect (struct session * sp, char *fsocket, int len);
void rlo_output (int unused, void *p1, void *p2);
void rlrecv (struct session * sp);


/* Execute user rlogin command */
int
dorlogin (argc, argv, p)
int argc;
char *argv[];
void *p;
{
struct session *sp;
struct sockaddr_in fsocket;
struct sockaddr_in lsocket;

	/*Make sure this comes from console - WG7J*/
	if (Curproc->input != Command->input)
		return 0;

	/* Allocate a session descriptor */
	if ((sp = newsession (argv[1], RLOGIN, 0)) == NULLSESSION) {
		tputs (TooManySessions);
		return 1;
	}
	fsocket.sin_family = AF_INET;
	if (argc < 3)
		fsocket.sin_port = IPPORT_RLOGIN;
	else
		fsocket.sin_port = atoi (argv[2]);

	tprintf ("Resolving %s... ", sp->name);
	if ((fsocket.sin_addr.s_addr = resolve (sp->name)) == 0L) {
		tprintf (Badhost, sp->name);
		keywait (NULLCHAR, 1);
		freesession (sp);
		return 1;
	}
	if ((sp->s = socket (AF_INET, SOCK_STREAM, 0)) == -1) {
		tputs (Nosock);
		keywait (NULLCHAR, 1);
		freesession (sp);
		return 1;
	}
	lsocket.sin_family = AF_INET;
	lsocket.sin_addr.s_addr = INADDR_ANY;
	lsocket.sin_port = IPPORT_RLOGIN;
	bind (sp->s, (char *) &lsocket, sizeof (lsocket));
	return rlo_connect (sp, (char *) &fsocket, SOCKSIZE);
}


/* Generic interactive connect routine */
int
rlo_connect (sp, fsocket, len)
struct session *sp;
char *fsocket;
int len;
{
unsigned int index;

	index = sp - Sessions;

	sockmode (sp->s, SOCK_ASCII);
	tprintf ("Trying %s...\n", psocket ((struct sockaddr *) fsocket));
	if (connect (sp->s, fsocket, len) == -1) {
		tprintf ("%s session %u failed: %s errno %d\n",
			 Sestypes[sp->type], index, sockerr (sp->s), errno);

		keywait (NULLCHAR, 1);
		freesession (sp);
		return 1;
	}
	tprintf ("%s session ", Sestypes[sp->type]);
	tprintf ("%u connected to %s\n", index, sp->name);
	rlrecv (sp);
	return 0;
}


/* Rlogin input routine, common to both rlogin and ttylink */
void
rlrecv (sp)
struct session *sp;
{
int c, s, index;
char *cp;

	s = sp->s;

	/* We run both the network and local sockets in transparent mode
	 * because we have to do our own eol mapping
	 */
	seteol (s, "");
	seteol (Curproc->input, "");
	seteol (Curproc->output, "");

	/* Read real keystrokes from the keyboard */
	sp->ttystate.crnl = 0;
	/* Put tty into raw mode */
	sp->ttystate.echo = 0;
	sp->ttystate.edit = 0;

	setflush (s, '\n');

	index = sp - Sessions;

	/* Fork off the transmit process */
	sp->proc1 = newproc ("rlo_out", 1024, rlo_output, 0, sp, NULL, 0);

	/* Process input on the connection */
	while ((c = recvchar (s)) != EOF) {
#ifdef UNIX
		putch ((char) c);
#else
		putc ((char) c, Rawterm);
#endif
	}
	/* A close was received from the remote host.
	 * Notify the user, kill the output task and wait for a response
	 * from the user before freeing the session.
	 */
	cp = sockerr (s);
#ifndef TNOS_68K
	seteol (s, "\r\n");
	seteol (Curproc->input, "\r\n");
	seteol (Curproc->output, "\r\n");
#else
	seteol (s, "\r\l");
	seteol (Curproc->input, "\r\l");
	seteol (Curproc->output, "\r\l");
#endif

	tprintf ("%s session %u", Sestypes[sp->type], index);
	tprintf (" closed: %s\n", cp != NULLCHAR ? cp : "EOF");
	killproc (sp->proc1);
	sp->proc1 = NULLPROC;
	close_s (sp->s);
	sp->s = -1;
	keywait (NULLCHAR, 1);
	freesession (sp);
}


/* User rlogin output task, started by user rlogin command */
void
rlo_output (unused, sp1, p)
int unused;
void *sp1;
void *p;
{
struct session *sp;
struct mbuf *bp;
char *cp;
char *logname, *termname;

	sp = (struct session *) sp1;

	logname = getenv ("USER");
	if (logname == NULLCHAR)
		logname = username;
	termname = getenv ("TERM");
	if (termname == NULLCHAR)
		termname = terminal;
	bp = ambufw ((int16) (1 + strlen (logname) + 1 + strlen (logname) + 1 +
			      strlen (termname) + strlen (termspeed) + 1));

	cp = bp->data;
	*cp++ = '\0';
	strcpy (cp, logname);
	cp += strlen (logname) + 1;
	strcpy (cp, logname);
	cp += strlen (logname) + 1;
	strcpy (cp, termname);
	cp += strlen (termname);
	strcpy (cp, termspeed);
	cp += strlen (termspeed) + 1;
	bp->cnt = ((unsigned char *) cp - bp->data);
	if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) != -1) {
		/* Send whatever's typed on the terminal */
		while (recv_mbuf (sp->input, &bp, 0, NULLCHAR, 0) > 0) {
			if (send_mbuf (sp->s, bp, 0, NULLCHAR, 0) == -1)
				break;
		}
	}
	/* Make sure our parent doesn't try to kill us after we exit */
	sp->proc1 = NULLPROC;
}

#endif
