/*
....[@@@..[@@@..............[@.................. 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
------------------------------------------------------------------------------
socket.h
*/
#ifndef _SOCKET_H
#define _SOCKET_H
#include "config.h"
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/telnet.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
// This is the beginning of redesigning the Server and all IO classes
// The Socket class should be in the Stream class hierarchy but as
// I have the hierarchy now, it is not easy to insert Socket since
// Sockets can't be memory mapped so the IStream class wont work with it.
// The Read(), Write() functions are the same as Server:: functions and
// will replace them when Socket class is done. The Server will then
// have a slightly different role.
/*
Structures describing an Internet socket address
from sys/in.h
INADDR_ANY is 0.0.0.0 which means accept all incoming
#define INADDR_ANY ((unsigned long int) 0x00000000)
struct in_addr
{
__u32 s_addr;
};
struct sockaddr_in
{
short int sin_family; Address family
unsigned short int sin_port; Port number ( network byte order )
struct in_addr sin_addr; IP address
unsigned char __pad[ XXX ]; Pads to size of sockaddr
};
*/
#if defined( ultrix )
extern "C"
{
int socket( int, int, int );
int setsockopt( int, int, int, void *, int );
int connect( int, struct sockaddr *, int );
int accept( int, struct sockaddr *, int * );
int bind( int, struct sockaddr *, int );
int listen( int, int );
int select( int, fd_set *, fd_set *, fd_set *, struct timeval * );
int getsockname( int, struct sockaddr *, int * );
int getpeername( int, struct sockaddr *, int * );
void bzero( char *, int );
}
#endif
#ifndef FNDELAY
#define FNDELAY O_NDELAY
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK EGAIN
#endif
#define MAX_READ 256
#define MAX_WRITE 4096
// Telnet codes.
const char REQ_ECHO_OFF [] =
{
(char) IAC,
(char) WILL,
(char) TELOPT_ECHO,
(char) 0
};
const char REQ_ECHO_ON [] =
{
(char) IAC,
(char) WONT,
(char) TELOPT_ECHO,
(char) 0
};
const char TELNET_GA [] =
{
(char) IAC,
(char) GA,
(char) 0
};
// These codes aren't really accurate but it is enough for the class to work
#define SOCK_NOT_CREATED 1
#define SOCK_FCNTL_ERR 2
#define SOCK_UNKNOWN_HOST 3
#define SOCK_BAD_ADDRESS 4
#define SOCK_NOT_CONNECTED 5
#define SOCK_SOCKOPT_ERR 6
#define SOCK_EOF 7
class Socket : public sockaddr_in
{
protected:
int err;
int sock;
char ip[ 128 ]; // char string version of ip address.
public:
Socket()
: err(0), sock(-1)
{
strcpy( ip, "0.0.0.0" ); // 0.0.0.0 = INADDR_ANY
sin_port = 0;
sin_family = AF_INET;
sin_addr.s_addr = htonl( INADDR_ANY );
}
Socket( int port );
Socket( char * address, int port );
Socket( char * address, int port, int desc );
~Socket()
{
if( sock >= 0 )
::close( sock );
}
void close()
{
if( sock >= 0 )
::close( sock );
sock = -1;
}
int error() { return err; }
int eof() { return ( err == SOCK_EOF ); }
char *getHostName() { return ip; }
int getFamily() { return sin_family; }
void setDesc( int x ) { sock = x; }
int getDesc() { return sock; }
int reuseAddr();
int noDelay();
int nonBlock();
int getPort() { return ntohs( sin_port ); }
int listen();
Socket * accept();
int resolveIP();
int connect();
int getPeerName();
int write( const char * );
int write( const char *, int );
int read( char *, int );
int read( char * );
int echoOff();
int echoOn();
};
inline int Socket::read( char *buf )
{
return read( buf, 1024 );
}
#endif