/*
	Schrodinger's Box Haven  code version -0.1 alpha
        Copyright (C) 1994, Gordon Chan

	You can do whatever ya want with this code as long as you leave this
        copyright & disclaimer intact.  You can hack it up all you want, etc...
        No guarantees.

	Send comments, flames, bug reports, etc ... to
		au233@freenet.carleton.ca  <---- (preferred address for now)
		gjc@achilles.net
		gchan@ccs.carleton.ca
*/


/* Here's the copyrights & disclaimers from the Opium Den and unixCB codes */

/* Opium Den */
/*
  val's haven code v -0.85

        Copyright (C) 1994 Joel Ward

        Warranty:
                Don't blame me for anything.

        You can do whatever the fuck you want with this code as long as you
don't remove this copyright/disclaimer notice.
*/

/* unixCB */
/*
  
  cbd.c
  
  "cbd.c" is the main code for the CB simulator.
  
  Copyright (c) 1992, Gary Grossman.  All rights reserved.
  Send comments and questions to: garyg@soda.berkeley.edu
  
  */

#include<stdio.h>
#include<arpa/telnet.h>

#include "linked_lists.h"
#include "control_sequences.h"
#include "main.h"


char *process_telnet_sequence (user, buffer)
	struct user *user;
	char *buffer;
{

	while (*buffer /* && is_telnet_char (buffer)*/ )  {

#ifdef DEBUG
		sprintf (err, "buffer content before= %c (%d)\r\n", *buffer, (unsigned char) *buffer);		
		write_err (err);
#endif
		switch ( (unsigned char) *buffer) {
			case IAC:
				user->ts_mode = TS_IAC;
		write_err ("ts_mode changed to TS_IAC\r\n");
				buffer++;
				break;
			case WILL:
				user->ts_mode = TS_WILL;
		write_err ("ts_mode changed to TS_WILL\r\n");	
				buffer++;
				break;
			case WONT:
				user->ts_mode = TS_WONT;
		write_err ("ts_mode changed to TS_WONT\r\n");	
				buffer++;
				break;
			case DO:
				user->ts_mode = TS_DO;
		write_err ("ts_mode changed to TS_DO\r\n");	
				buffer++;
				break;
			case DONT:
				user->ts_mode = TS_DONT;
		write_err ("ts_mode changed to TS_DONT\r\n");	
				buffer++;
				break;
			default:
				if (*buffer != TELOPT_SGA &&
				    *buffer != TELOPT_ECHO &&
				    *buffer != TELOPT_LINEMODE)
					buffer++; 
		write_err ("ts_mode NOT changed\r\n");	

				break;
		}
#ifdef DEBUG
		sprintf (err, "buffer content after= %c (%d)\r\n", *buffer, (unsigned char) *buffer);		
		write_err (err);
#endif
		if (user->ts_mode && *buffer)  
			buffer = (char *) process_ts (user, buffer); 
	}

	return buffer;
}


char *process_ts (user, buffer)
	struct user *user;
	char *buffer;
{
	switch (user->ts_mode)	{

	case TS_IAC:
		switch ( (unsigned char) *buffer) {
		case WILL:
			user->ts_mode = TS_WILL;
		write_err ("* ts_mode changed to TS_WILL\r\n");	
			buffer++;
			break;
		case WONT:
			user->ts_mode = TS_WONT;
		write_err ("* ts_mode changed to TS_WONT\r\n");	
			buffer++;
			break;
		case DO:
			user->ts_mode = TS_DO;
		write_err ("* ts_mode changed to TS_DO\r\n");	
			buffer++;
			break;
		case DONT:
			user->ts_mode = TS_DONT;
		write_err ("* ts_mode changed to TS_DONT\r\n");	
			buffer++;
			break;
/*		case AYT:
			write_user (user->desc, "\n[Yes]\r\n");
			user->ts_mode = TS_NONE;
		write_err ("* got AYT\r\n");	
			buffer++;
			break;
		case EC:
		case EL:

			erase_char (user);
			user->ts_mode = TS_NONE;
		write_err ("* got EL or EC\r\n");	
			buffer++;
			break;

		case AO:
			clear_queue (user->input);
			user->ts_mode = TS_NONE;
		write_err ("* got AO\r\n");	
			buffer++;
			break;  
*/
		default:
			user->ts_mode = TS_NONE;
			buffer++;
			break;
		}
		break;

	case TS_WILL:
		switch ( (unsigned char) *buffer) {
		case TELOPT_LINEMODE:
			user->ts_mode = TS_NONE;
			send_ts (user->desc, DONT, TELOPT_LINEMODE);
		write_err ("* TS_WILL, TELOPT_LINEMODE\r\n");	
			buffer++;
			break;		
		default:
			user->ts_mode = TS_NONE;
			buffer++;
			break;
		}			
		break;

	case TS_WONT:
		user->ts_mode = TS_NONE;
		buffer++;
		break;

	case TS_DO:
		switch ( (unsigned char) *buffer) {
		case TELOPT_ECHO:
			if (is_user_not (user, Fecho_text) )
				toggle_user (user, Fecho_text);
			user->ts_mode = TS_NONE;
		write_err ("* TS_DO, TELOPT_ECHO\r\n");	
			buffer++;
			break;
		case TELOPT_SGA:
			if (is_user (user, Flinemode) )
				toggle_user (user, Flinemode);
			user->ts_mode = TS_NONE;
		write_err ("* TS_DO, TELOPT_SGA\r\n");	
			buffer++;
			break;
		default:
			user->ts_mode = TS_NONE;
			buffer++;
			break;
		}
		break;
	
	case TS_DONT:
		switch ( (unsigned char) *buffer) {
		case TELOPT_ECHO:
			if (is_user (user, Fecho_text) )
				toggle_user (user, Fecho_text);
			user->ts_mode = TS_NONE;
		write_err ("* TS_DONT, TELOPT_ECHO\r\n");	
			buffer++;
			break;

		case TELOPT_SGA:
			if (is_user_not (user, Flinemode) )
				toggle_user (user, Flinemode);
			user->ts_mode = TS_NONE;
		write_err ("* TS_DONT, TELOPT_SGA\r\n");	
			buffer++;
			break;			

		default:
			user->ts_mode = TS_NONE;
			buffer++;
			break;
		}
		break;
	}
	return buffer;
}




int is_telnet_char (buf)
	char *buf;
{
	if ( 	(unsigned char) *buf == IAC ||
		(unsigned char) *buf == DONT ||
		(unsigned char) *buf == DO ||
		(unsigned char) *buf == WONT ||
		(unsigned char) *buf == WILL ||
/*
		(unsigned char) *buf == AYT ||
		(unsigned char) *buf == EL ||
		(unsigned char) *buf == EC ||
		(unsigned char) *buf == AO ||
*/		
		(unsigned char) *buf == TELOPT_ECHO ||
		(unsigned char) *buf == TELOPT_LINEMODE ||
		(unsigned char) *buf == TELOPT_SGA )
			return 1;

	return 0;
}		 



void send_ts (desc, arg1, arg2)
	int desc, arg1, arg2;
{
	char string[3];
	
	string[0] = IAC;
	string[1] = arg1;
	string[2] = arg2;
	string[3] = '\0';
	
	write_user (desc, string);
}
	

