/* ....[@@@..[@@@..............[@.................. 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