/******************************************************
Desolation of the Dragon MUD II
(C) 2001-2002 Jesse DeFer
http://www.dotd.com dotd@dotd.com
******************************************************/
#include <errno.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netdb.h>
#include <netinet/in.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <limits.h>
#ifdef __cplusplus
#include <iostream>
#endif
#ifndef UMAX
#define UMAX(a,b) ((a)>(b)?(a):(b))
#endif
#ifndef UMIN
#define UMIN(a,b) ((a)<(b)?(a):(b))
#endif
#ifndef MAX_INBUF_SIZE
#define MAX_INBUF_SIZE 1024
#endif
#ifndef LINK
#define LINK(link, first, last, next, prev) \
{ \
if ( !(first) ) \
(first) = (link); \
else \
(last)->next = (link); \
(link)->next = NULL; \
(link)->prev = (last); \
(last) = (link); \
}
#endif
#ifndef UNLINK
#define UNLINK(link, first, last, next, prev) \
{ \
if ( !(link)->prev ) \
(first) = (link)->next; \
else \
(link)->prev->next = (link)->next; \
if ( !(link)->next ) \
(last) = (link)->prev; \
else \
(link)->next->prev = (link)->prev; \
}
#endif
#define DEBUG 19
typedef struct ldesc LDESC;
struct ldesc {
int descriptor;
char *messages_in;
int len_in;
int alloc_in;
char *messages_out;
int len_out;
int alloc_out;
#ifndef LISTENER
LDESC *next;
LDESC *prev;
#endif
};
void debug_printf(int level, const char *format, ...) __attribute__((format(printf,2,3)));
void read_message_from_ldesc(LDESC *ld);
int send_message_to_ldesc(LDESC *ld, char *data, int datalen);
void disconnect_ldesc(LDESC *ld);
int process_ldesc(LDESC *ld);
void init_ldesc(LDESC *ld);
void process_message(LDESC *ld, char *data, int datalen);
#ifdef LISTENER
extern int shutdown_process;
void send_to_all(char *str);
extern int conn_number;
#else
extern LDESC *first_ld;
extern LDESC *last_ld;
#endif
/*
* Low level message format:
*
* Byte: 1 2345 6-len
* [tag] [len] [data]
*
* Minimum message length: 6 bytes
* Minimum data length: 1 byte
* Maximum message/data length: none
*
*/
#define MESSAGE_TAG '\xA1'
/*
* All messages MUST start with:
* Format: "%d %d ", type, uid
* type the message type, see MESSAGE_XXX defines
* uid the unique id of the user, used to keep track of the connection,
* the mud must remember this to send in reply messages
*/
#define MESSAGE_USERCMD 0
/*
* The listener sends what the user types to the mud, via this message type.
* If the mud doesn't recognize the uid, start the login process
*
* Format: "%s", input
* input what the user typed
*/
#define MESSAGE_SENDTOUSER 1
/*
* The mud sends data to the user via this message type. If the listener
* doesn't recognize the uid, reply with MESSAGE_NOSUCHUSER
*
* Format: "%s", data
* data the actual data to send to the user
*/
#define MESSAGE_NOSUCHUSER 2
/*
* Use the message when the user doesn't exist. If the mud gets this, it
* should 'disconnect' the user and stop sending data. If the listener gets
* this, it should send a MESSAGE_NEWUSER message.
*
* No additional data needed
*/
#define MESSAGE_USERDISCON 3
/*
* When the listener sends this to the mud, the mud should 'disconnect' the
* user. When the mud sends this to the listener, the listener handles the
* user according to action. The mud can ignore the value of action.
*
* Format: "%s", action
* action what to do with the user, see MESSAGE_USERDISCON_xxx
*/
#define MESSAGE_USERDISCON_DONTCLOSE 0
#define MESSAGE_USERDISCON_CLOSESOCKET 1
#define MESSAGE_NEWUSER 4
/*
* The listener sends this to the mud to initiate a new connection.
*
* No additional data needed
*/
#define MESSAGE_FIRST MESSAGE_USERCMD
#define MESSAGE_LAST MESSAGE_NEWUSER
#define TOTAL_MESSAGE_TYPES MESSAGE_LAST+1
struct ldesc_msg_handler {
void (*process)(LDESC *ld, unsigned int uid, char *data);
};
typedef struct ldesc_msg_handler LDESC_MSG_HANDLER;
/*
* You must define the function pointers in this structure to handle
* the incoming messages. Message types you wish to ignore should be
* assigned NULL.
*/
extern LDESC_MSG_HANDLER recv_message_handlers[TOTAL_MESSAGE_TYPES];
#define DEFINE_PROCESS_CMD(func) void (func)(LDESC *ld, unsigned int uid, char *data)