// $Id: Rlogin.h,v 1.5 2002/10/11 02:20:15 leres Exp $
//
// Copyright (c) 1999, 2001, 2002
//      The Regents of the University of California.  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that: (1) source code distributions
// retain the above copyright notice and this paragraph in its entirety, (2)
// distributions including binary code include the above copyright notice and
// this paragraph in its entirety in the documentation or other materials
// provided with the distribution, and (3) all advertising materials mentioning
// features or use of this software display the following acknowledgement:
// ``This product includes software developed by the University of California,
// Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
// the University nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

#ifndef rlogin_h
#define rlogin_h

#include "Login.h"

typedef enum {
	RLOGIN_FIRST_NULL,	// waiting to see first NUL
	RLOGIN_CLIENT_USER_NAME,	// scanning client user name up to NUL
	RLOGIN_SERVER_USER_NAME,	// scanning server user name up to NUL
	RLOGIN_TERMINAL_TYPE,	// scanning terminal type & speed

	RLOGIN_SERVER_ACK,	// waiting to see NUL from server to ack client

	RLOGIN_IN_BAND_CONTROL_FF2,	// waiting to see the second FF

	RLOGIN_WINDOW_CHANGE_S1,	// waiting to see the first 's'
	RLOGIN_WINDOW_CHANGE_S2,	// waiting to see the second 's'
	RLOGIN_WINDOW_CHANGE_REMAINDER,	// remaining "bytes_to_scan" bytes

	RLOGIN_LINE_MODE,	// switch to line-oriented processing

	RLOGIN_PRESUMED_REJECTED,	// apparently server said No Way

	RLOGIN_UNKNOWN,	// we don't know what state we're in
} rlogin_state;

class RloginConn;

class RloginEndpoint : public TCP_EndpointLine {
public:
	RloginEndpoint(RloginConn* conn, int is_orig);
	~RloginEndpoint();

	rlogin_state RloginState() const	{ return state; }

protected:
	void DoDeliver(double t, int seq, int len, u_char* data);
	void BadProlog();

	RloginConn* AsRloginConn()	{ return (RloginConn*) conn; }

	rlogin_state state, save_state;
	int num_bytes_to_scan;
};

class RloginConn : public LoginConn {
public:
	RloginConn(NetSessions* s, HashKey* k, double t, const ConnID* id,
			const struct tcphdr* tp);

	void ClientUserName(const char* s);
	void ServerUserName(const char* s);
	void TerminalType(const char* s);

	void PrologFinished(RloginEndpoint* endp);

protected:
	void BuildEndpoints();
};

#endif
