fbmuck-6.05/auto/
fbmuck-6.05/contrib/jresolver/
fbmuck-6.05/contrib/jresolver/org/
fbmuck-6.05/contrib/jresolver/org/fuzzball/
fbmuck-6.05/docs/devel/
fbmuck-6.05/game/
fbmuck-6.05/game/logs/
fbmuck-6.05/game/muf/
fbmuck-6.05/scripts/
fbmuck-6.05/src_docs/
#ifndef MCP_H
#define MCP_H

/* the type used to specify the connection */
typedef void *connection_t;

#define MCP_MESG_PREFIX     "#$#"
#define MCP_QUOTE_PREFIX    "#$\""

#define EMCP_SUCCESS		 0	/* successful result */
#define EMCP_NOMCP			-1	/* MCP isn't supported on this connection. */
#define EMCP_NOPACKAGE		-2	/* Package isn't supported for this connection. */
#define EMCP_ARGCOUNT		-3	/* Too many arguments in mesg. */
#define EMCP_ARGNAMELEN		-5	/* Arg name is too long. */
#define EMCP_MESGSIZE		-6	/* Message is too large. */

#define MAX_MCP_ARGNAME_LEN    30 /* max length of argument name. */
#define MAX_MCP_MESG_ARGS      30 /* max number of args per mesg. */
#define MAX_MCP_MESG_SIZE  262144 /* max mesg size in bytes. */

/* This is a convenient struct for dealing with MCP versions. */
typedef struct McpVersion_T {
	unsigned short vermajor;	/* major version number */
	unsigned short verminor;	/* minor version number */
} McpVer;



/* This is one line of a multi-line argument value. */
typedef struct McpArgPart_T {
	struct McpArgPart_T *next;
	char *value;
} McpArgPart;


/* This is one argument of a message. */
typedef struct McpArg_T {
	struct McpArg_T *next;
	char *name;
	McpArgPart *value;
	McpArgPart *last;
	int was_shown;
} McpArg;


/* This is an MCP message. */
typedef struct McpMesg_T {
	struct McpMesg_T *next;
	char *package;
	char *mesgname;
	char *datatag;
	McpArg *args;
	int incomplete;
	int bytes;
} McpMesg;


struct McpFrame_T;
typedef void (*McpPkg_CB) (struct McpFrame_T * mfr,

						   McpMesg * mesg, McpVer version, void *context);

typedef void (*ContextCleanup_CB) (void *context);



/* This is used to keep track of registered packages. */
typedef struct McpPkg_T {
	char *pkgname;				/* Name of the package */
	McpVer minver;				/* min supported version number */
	McpVer maxver;				/* max supported version number */
	McpPkg_CB callback;			/* function to call with mesgs */
	void *context;				/* user defined callback context */
	ContextCleanup_CB cleanup;  /* callback to use to free context */
	struct McpPkg_T *next;
} McpPkg;



/* This keeps connection specific data for MCP. */
typedef struct McpFrame_T {
	void *descriptor;			/* The descriptor to send output to */
	unsigned int enabled;		/* Flag denoting if MCP is enabled. */
	char *authkey;				/* Authorization key. */
	McpVer version;				/* Supported MCP version number. */
	McpPkg *packages;			/* Pkgs supported on this connection. */
	McpMesg *messages;			/* Partial messages, under construction. */
} McpFrame;




/*****************************************************************
 *
 * void mcp_package_register(
 *              const char* pkgname,
 *              McpVer minver,
 *              McpVer maxver,
 *              McpPkg_CB callback,
 *              void* context
 *          );
 *
 *****************************************************************
 *
 * void mcp_package_deregister(
 *              const char* pkgname,
 *          );
 *
 *
 *****************************************************************
 *
 * void mcp_initialize();
 *
 *   Initializes MCP globally at startup time.
 *
 *****************************************************************
 *
 * void mcp_negotiation_start(McpFrame* mfr);
 *
 *   Starts MCP negotiations, if any are to be had.
 *
 *****************************************************************
 *
 * void mcp_frame_init(McpFrame* mfr, connection_t con);
 *
 *   Initializes an McpFrame for a new connection.
 *   You MUST call this to initialize a new McpFrame.
 *   The caller is responsible for the allocation of the McpFrame.
 *
 *****************************************************************
 *
 * void mcp_frame_clear(McpFrame* mfr);
 *
 *   Cleans up an McpFrame for a closing connection.
 *   You MUST call this when you are done using an McpFrame.
 *
 *****************************************************************
 *
 * void mcp_frame_package_add(
 *              McpFrame* mfr,
 *              char* package,
 *              McpVer minver,
 *              McpVer maxver
 *          );
 *
 *   Attempt to register a package for this connection.
 *   Returns EMCP_SUCCESS if the package was deemed supported.
 *   Returns EMCP_NOMCP if MCP is not supported on this connection.
 *   Returns EMCP_NOPACKAGE if the package versions didn't overlap.
 *
 *****************************************************************
 *
 * void mcp_frame_package_remove(
 *              McpFrame* mfr,
 *              char* package,
 *              McpVer minver,
 *              McpVer maxver
 *          );
 *
 *   Deregisters a package for a given frame.
 *
 *****************************************************************
 *
 * void mcp_frame_package_supported(
 *              McpFrame* mfr,
 *              char* package
 *          );
 *
 *   Returns the supported version of the given package.
 *   Returns {0,0} if the package is not supported.
 *
 *****************************************************************
 *
 * void mcp_frame_package_docallback(
 *              McpFrame* mfr,
 *              McpMesg* msg
 *          );
 *
 *   Executes the callback function for the given message.
 *   Returns EMCP_SUCCESS if the call completed successfully.
 *   Returns EMCP_NOMCP if MCP is not supported for that connection.
 *   Returns EMCP_NOPACKAGE if the package is not supported.
 *
 *****************************************************************
 *
 * int mcp_frame_process_input(
 *           McpFrame* mfr,
 *           const char* linein,
 *           char *outbuf,
 *           int bufsize
 *      );
 *
 *   Check a line of input for MCP commands.
 *   Returns 0 if the line was an out-of-band MCP message.
 *   Returns 1 if the line was in-band data.
 *     outbuf will contain the in-band data on return, if any.
 *
 *****************************************************************
 *
 * void mcp_frame_output_inband(
 *             McpFrame* mfr,
 *             const char* lineout
 *         );
 *
 *   Sends a string to the given connection, using MCP escaping
 *     if needed and supported.
 *
 *****************************************************************
 *
 * int mcp_frame_output_mesg(
 *             McpFrame* mfr,
 *             McpMesg* msg
 *         );
 *
 *   Sends an MCP message to the given connection.
 *   Returns EMCP_SUCCESS if successful.
 *   Returns EMCP_NOMCP if MCP isn't supported on this connection.
 *   Returns EMCP_NOPACKAGE if this connection doesn't support the package.
 *
 *****************************************************************
 *
 * void mcp_mesg_init(
 *         McpMesg*    msg,
 *         const char* package,
 *         const char* mesgname
 *     );
 *
 *   Initializes an MCP message.
 *   You MUST initialize a message before using it.
 *   You MUST also mcp_mesg_clear() a mesg once you are done using it.
 *
 *****************************************************************
 *
 * void mcp_mesg_clear(
 *              McpMesg* msg
 *          );
 *
 *   Clear the given MCP message.
 *   You MUST clear every message after you are done using it, to
 *     free the memory used by the message.
 *
 *****************************************************************
 *
 * int mcp_mesg_arg_linecount(
 *         McpMesg* msg,
 *         const char* name
 *     );
 *
 *   Returns the count of the number of lines in the given arg of
 *   the given message.
 *
 *****************************************************************
 *
 * char* mcp_mesg_arg_getline(
 *         McpMesg* msg,
 *         const char* argname
 *         int linenum;
 *     );
 *
 *   Gets the value of a named argument in the given message.
 *
 *****************************************************************
 *
 * int mcp_mesg_arg_append(
 *         McpMesg* msg,
 *         const char* argname,
 *         const char* argval
 *     );
 *
 *   Appends to the list value of the named arg in the given mesg.
 *   If that named argument doesn't exist yet, it will be created.
 *   This is used to construct arguments that have lists as values.
 *   Returns the success state of the call.  EMCP_SUCCESS if the
 *   call was successful.  EMCP_ARGCOUNT if this would make too
 *   many arguments in the message.  EMCP_ARGLENGTH is this would
 *   cause an argument to exceed the max allowed number of lines.
 *
 *****************************************************************
 *
 * void mcp_mesg_arg_remove(
 *         McpMesg* msg,
 *         const char* argname
 *     );
 *
 *   Removes the named argument from the given message.
 *
 *****************************************************************
 *
 * int mcp_version_compare(McpVer v1, McpVer v2);
 *
 *   Compares two McpVer structs.
 *   Results are similar to strcmp():
 *     Returns negative if v1 <  v2
 *     Returns 0 (zero) if v1 == v2
 *     Returns positive if v1 >  v2
 *
 *****************************************************************
 *
 * McpVer mcp_version_select(
 *                McpVer min1,
 *                McpVer max1,
 *                McpVer min2,
 *                McpVer max2
 *            );
 *
 *   Given the min and max package versions supported by a client
 *     and server, this will return the highest version that is
 *     supported by both.
 *   Returns a McpVer of {0, 0} if there is no version overlap.
 *
 *****************************************************************/




void mcp_initialize(void);
void mcp_negotiation_start(McpFrame * mfr);

void mcp_package_register(const char *pkgname, McpVer minver, McpVer maxver,
						  McpPkg_CB callback, void *context, ContextCleanup_CB cleanup);
void mcp_package_deregister(const char *pkgname);

void mcp_frame_init(McpFrame * mfr, connection_t con);
void mcp_frame_clear(McpFrame * mfr);

int mcp_frame_package_add(McpFrame * mfr, const char *package, McpVer minver, McpVer maxver);
void mcp_frame_package_remove(McpFrame * mfr, const char *package);
void mcp_frame_package_renegotiate(const char *package);
McpVer mcp_frame_package_supported(McpFrame * mfr, const char *package);
int mcp_frame_package_docallback(McpFrame * mfr, McpMesg * msg);

int mcp_frame_process_input(McpFrame * mfr, const char *linein, char *outbuf, int bufsize);
void mcp_frame_output_inband(McpFrame * mfr, const char *lineout);
int mcp_frame_output_mesg(McpFrame * mfr, McpMesg * msg);

void mcp_mesg_init(McpMesg * msg, const char *package, const char *mesgname);
void mcp_mesg_clear(McpMesg * msg);

int mcp_mesg_arg_linecount(McpMesg * msg, const char *name);
char *mcp_mesg_arg_getline(McpMesg * msg, const char *argname, int linenum);
int mcp_mesg_arg_append(McpMesg * msg, const char *argname, const char *argval);
void mcp_mesg_arg_remove(McpMesg * msg, const char *argname);

int mcp_version_compare(McpVer v1, McpVer v2);
McpVer mcp_version_select(McpVer min1, McpVer max1, McpVer min2, McpVer max2);

#endif							/* MCP_H */