/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@falcon.mercer.peachnet.edu 
MUD++ development mailing list    mudpp-list@spice.com
------------------------------------------------------------------------------
server.h
*/

#include "socket.h"

#ifndef SERVER_H
#define SERVER_H

#define NULL_CHAR '\0'
#ifndef NULL
#define NULL 0
#endif

#ifndef FNDELAY
#define FNDELAY O_NONBLOCK
#endif

#ifndef EWOULDBLOCK
#define EWOULDBLOCK  EAGAIN 
#endif

// On my old DEC with 4.2 bsd I had to do this. SIG_DFL wont compile
#ifdef ultrix
#ifdef SIG_IGN
#undef SIG_IGN
#define SIG_IGN (void*)1
#endif
#endif


#define SOFT_MAX_DESC  256  // Fuzzy _POSIX_OPEN_MAX, only used for array size
#define MAX_READ       256
#define MAX_WRITE      4096 // Dont write more than this in a call



class Server
{
	private:
		Socket *master;
		int    masterport;
		int    masterdesc;
		int    type;
		int    nameserver;
		int    maxdesc;
		int    maxread;
		int    maxidle;
		int    descripts;
		int    topdesc;
		int    bitwidth;
		timeval null_time;
		fd_set MASTER_SET, R_SET, W_SET, E_SET;

	public:
		Server()
		:	masterport(4000), masterdesc(0)
		{
		}

		Server( int theport = 4000 )
		:	masterport( theport ), masterdesc(0),
			type( SOCK_STREAM ), nameserver(0), maxread( MAX_READ ),
			maxidle(0), descripts(0)
		{
			null_time.tv_sec  = 0;
			null_time.tv_usec = 0;
			maxdesc = sysconf( _SC_OPEN_MAX );
			printf( "SERVER: Ok. This OS supports %d open descriptors theoretically.\n",
					maxdesc );

			// Who cares if OS supports 2 mil, realistic is 256 for a MUD
			if( maxdesc > 256 )
				maxdesc = 256;

			bitwidth = maxdesc / 8;
		}

		~Server();

		Socket * getSock();   // return actual socket descriptor value
		int getPort() { return masterport; }
		int getDesc() { return masterdesc; }
		int boot( int tport = 4000 ); // boot on a specific port
		int boot( int, int ); // reboot ( port and TCP desc )
		int newConnection();
		void addSock( Socket * );  // Add a previously opened desc.
		Socket * accept();
		int poll();
		void sleep( long millisecs ); 
		void useNameServer();
		void remove( Socket * );
		int error( Socket * );
		int canWrite( Socket * );
		int canRead( Socket * );
};

#endif