--- /dev/null
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "logging.h"
+#include "utils.h"
+
+/* libxml stuff for the config reader */
+#include <libxml/xmlmemory.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <libxml/tree.h>
+
+#include "utils.h"
+
+#ifndef GENERIC_UTILS_H
+#define GENERIC_UTILS_H
+
+#define equals(a,b) !strcmp(a,b)
+
+// ---------------------------------------------------------------------------------
+// Config file module
+// ---------------------------------------------------------------------------------
+struct config_reader_struct {
+ xmlDocPtr config_doc;
+ xmlXPathContextPtr xpathCx;
+ char* name;
+ struct config_reader_struct* next;
+};
+typedef struct config_reader_struct config_reader;
+config_reader* conf_reader;
+
+//void config_reader_init( char* config_file );
+void config_reader_init( char* name, char* config_file );
+
+void config_reader_free();
+
+// allocastes a char*. FREE me.
+char* config_value( const char* config_name, const char* xp_query, ... );
+
+#endif
--- /dev/null
+#include "transport_session.h"
+#include <time.h>
+
+#ifndef TRANSPORT_CLIENT_H
+#define TRANSPORT_CLIENT_H
+
+#define MESSAGE_LIST_HEAD 1
+#define MESSAGE_LIST_ITEM 2
+
+
+// ---------------------------------------------------------------------------
+// Represents a node in a linked list. The node holds a pointer to the next
+// node (which is null unless set), a pointer to a transport_message, and
+// and a type variable (which is not really curently necessary).
+// ---------------------------------------------------------------------------
+struct message_list_struct {
+ struct message_list_struct* next;
+ transport_message* message;
+ int type;
+};
+
+typedef struct message_list_struct transport_message_list;
+typedef struct message_list_struct transport_message_node;
+
+// ---------------------------------------------------------------------------
+// Our client struct. We manage a list of messages and a controlling session
+// ---------------------------------------------------------------------------
+struct transport_client_struct {
+ transport_message_list* m_list;
+ transport_session* session;
+};
+typedef struct transport_client_struct transport_client;
+
+// ---------------------------------------------------------------------------
+// Allocates and initializes and transport_client. This does no connecting
+// The user must call client_free(client) when finished with the allocated
+// object.
+// ---------------------------------------------------------------------------
+transport_client* client_init( char* server, int port, int component );
+
+// ---------------------------------------------------------------------------
+// Connects to the Jabber server with the provided information. Returns 1 on
+// success, 0 otherwise.
+// ---------------------------------------------------------------------------
+int client_connect( transport_client* client,
+ char* username, char* password, char* resource,
+ int connect_timeout, enum TRANSPORT_AUTH_TYPE auth_type );
+
+int client_disconnect( transport_client* client );
+
+// ---------------------------------------------------------------------------
+// De-allocates memory associated with a transport_client object. Users
+// must use this method when finished with a client object.
+// ---------------------------------------------------------------------------
+int client_free( transport_client* client );
+
+// ---------------------------------------------------------------------------
+// Sends the given message. The message must at least have the recipient
+// field set.
+// ---------------------------------------------------------------------------
+int client_send_message( transport_client* client, transport_message* msg );
+
+// ---------------------------------------------------------------------------
+// Returns 1 if this client is currently connected to the server, 0 otherwise
+// ---------------------------------------------------------------------------
+int client_connected( transport_client* client );
+
+// ---------------------------------------------------------------------------
+// This is the message handler required by transport_session. This handler
+// takes all incoming messages and puts them into the back of a linked list
+// of messages.
+// ---------------------------------------------------------------------------
+void client_message_handler( void* client, transport_message* msg );
+
+// ---------------------------------------------------------------------------
+// If there are any message in the message list, the 'oldest' message is
+// returned. If not, this function will wait at most 'timeout' seconds
+// for a message to arrive. Specifying -1 means that this function will not
+// return unless a message arrives.
+// ---------------------------------------------------------------------------
+transport_message* client_recv( transport_client* client, int timeout );
+
+
+#endif
--- /dev/null
+#include "generic_utils.h"
+
+#include <string.h>
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlmemory.h>
+
+#ifndef TRANSPORT_MESSAGE_H
+#define TRANSPORT_MESSAGE_H
+
+
+
+// ---------------------------------------------------------------------------------
+// Jabber message object.
+// ---------------------------------------------------------------------------------
+struct transport_message_struct {
+ char* body;
+ char* subject;
+ char* thread;
+ char* recipient;
+ char* sender;
+ char* router_from;
+ char* router_to;
+ char* router_class;
+ char* router_command;
+ int is_error;
+ char* error_type;
+ int error_code;
+ int broadcast;
+ char* msg_xml; /* the entire message as XML complete with entity encoding */
+};
+typedef struct transport_message_struct transport_message;
+
+// ---------------------------------------------------------------------------------
+// Allocates and returns a transport_message. All chars are safely re-allocated
+// within this method.
+// Returns NULL on error
+// ---------------------------------------------------------------------------------
+transport_message* message_init( char* body, char* subject,
+ char* thread, char* recipient, char* sender );
+
+transport_message* new_message_from_xml( const char* msg_xml );
+
+
+void message_set_router_info( transport_message* msg, char* router_from,
+ char* router_to, char* router_class, char* router_command, int broadcast_enabled );
+
+// ---------------------------------------------------------------------------------
+// Formats the Jabber message as XML for encoding.
+// Returns NULL on error
+// ---------------------------------------------------------------------------------
+char* message_to_xml( const transport_message* msg );
+
+
+// ---------------------------------------------------------------------------------
+// Call this to create the encoded XML for sending on the wire.
+// This is a seperate function so that encoding will not necessarily have
+// to happen on all messages (i.e. typically only occurs outbound messages).
+// ---------------------------------------------------------------------------------
+int message_prepare_xml( transport_message* msg );
+
+// ---------------------------------------------------------------------------------
+// Deallocates the memory used by the transport_message
+// Returns 0 on error
+// ---------------------------------------------------------------------------------
+int message_free( transport_message* msg );
+
+// ---------------------------------------------------------------------------------
+// Prepares the shared XML document
+// ---------------------------------------------------------------------------------
+//int message_init_xml();
+
+// ---------------------------------------------------------------------------------
+// Determines the username of a Jabber ID. This expects a pre-allocated char
+// array for the return value.
+// ---------------------------------------------------------------------------------
+void jid_get_username( const char* jid, char buf[] );
+
+// ---------------------------------------------------------------------------------
+// Determines the resource of a Jabber ID. This expects a pre-allocated char
+// array for the return value.
+// ---------------------------------------------------------------------------------
+void jid_get_resource( const char* jid, char buf[] );
+
+/** Puts the domain portion of the given jid into the pre-allocated buffer */
+void jid_get_domain( const char* jid, char buf[] );
+
+void set_msg_error( transport_message*, char* error_type, int error_code);
+
+
+#endif
--- /dev/null
+// ---------------------------------------------------------------------------------
+// Manages the Jabber session. Data is taken from the TCP object and pushed into
+// a SAX push parser as it arrives. When key Jabber documetn elements are met,
+// logic ensues.
+// ---------------------------------------------------------------------------------
+#include "transport_socket.h"
+#include "transport_message.h"
+#include "generic_utils.h"
+
+#include "sha.h"
+
+#include <string.h>
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h> /* only for xmlNewInputFromFile() */
+#include <libxml/tree.h>
+#include <libxml/debugXML.h>
+#include <libxml/xmlmemory.h>
+
+#ifndef TRANSPORT_SESSION_H
+#define TRANSPORT_SESSION_H
+
+#define CONNECTING_1 1 /* just starting the connection to Jabber */
+#define CONNECTING_2 2 /* First <stream> packet sent and <stream> packet received from server */
+
+/* Note. these are growing buffers, so all that's necessary is a sane starting point */
+#define JABBER_BODY_BUFSIZE 4096
+#define JABBER_SUBJECT_BUFSIZE 64
+#define JABBER_THREAD_BUFSIZE 64
+#define JABBER_JID_BUFSIZE 64
+#define JABBER_STATUS_BUFSIZE 16
+
+// ---------------------------------------------------------------------------------
+// Takes data from the socket handler and pushes it directly into the push parser
+// ---------------------------------------------------------------------------------
+void grab_incoming( void * session, char* data );
+
+// ---------------------------------------------------------------------------------
+// Callback for handling the startElement event. Much of the jabber logic occurs
+// in this and the characterHandler callbacks.
+// Here we check for the various top level jabber elements: body, iq, etc.
+// ---------------------------------------------------------------------------------
+void startElementHandler(
+ void *session, const xmlChar *name, const xmlChar **atts);
+
+// ---------------------------------------------------------------------------------
+// Callback for handling the endElement event. Updates the Jabber state machine
+// to let us know the element is over.
+// ---------------------------------------------------------------------------------
+void endElementHandler( void *session, const xmlChar *name);
+
+// ---------------------------------------------------------------------------------
+// This is where we extract XML text content. In particular, this is useful for
+// extracting Jabber message bodies.
+// ---------------------------------------------------------------------------------
+void characterHandler(
+ void *session, const xmlChar *ch, int len);
+
+void parseWarningHandler( void *session, const char* msg, ... );
+void parseErrorHandler( void *session, const char* msg, ... );
+
+// ---------------------------------------------------------------------------------
+// Tells the SAX parser which functions will be used as event callbacks
+// ---------------------------------------------------------------------------------
+static xmlSAXHandler SAXHandlerStruct = {
+ NULL, /* internalSubset */
+ NULL, /* isStandalone */
+ NULL, /* hasInternalSubset */
+ NULL, /* hasExternalSubset */
+ NULL, /* resolveEntity */
+ NULL, /* getEntity */
+ NULL, /* entityDecl */
+ NULL, /* notationDecl */
+ NULL, /* attributeDecl */
+ NULL, /* elementDecl */
+ NULL, /* unparsedEntityDecl */
+ NULL, /* setDocumentLocator */
+ NULL, /* startDocument */
+ NULL, /* endDocument */
+ startElementHandler, /* startElement */
+ endElementHandler, /* endElement */
+ NULL, /* reference */
+ characterHandler, /* characters */
+ NULL, /* ignorableWhitespace */
+ NULL, /* processingInstruction */
+ NULL, /* comment */
+ parseWarningHandler, /* xmlParserWarning */
+ parseErrorHandler, /* xmlParserError */
+ NULL, /* xmlParserFatalError : unused */
+ NULL, /* getParameterEntity */
+ NULL, /* cdataBlock; */
+ NULL, /* externalSubset; */
+ 1,
+ NULL,
+ NULL, /* startElementNs */
+ NULL, /* endElementNs */
+ NULL /* xmlStructuredErrorFunc */
+};
+
+// ---------------------------------------------------------------------------------
+// Our SAX handler pointer.
+// ---------------------------------------------------------------------------------
+static const xmlSAXHandlerPtr SAXHandler = &SAXHandlerStruct;
+
+// ---------------------------------------------------------------------------------
+// Jabber state machine. This is how we know where we are in the Jabber
+// conversation.
+// ---------------------------------------------------------------------------------
+struct jabber_state_machine_struct {
+ int connected;
+ int connecting;
+ int in_message;
+ int in_message_body;
+ int in_thread;
+ int in_subject;
+ int in_error;
+ int in_message_error;
+ int in_iq;
+ int in_presence;
+ int in_status;
+};
+typedef struct jabber_state_machine_struct jabber_machine;
+
+
+enum TRANSPORT_AUTH_TYPE { AUTH_PLAIN, AUTH_DIGEST };
+
+// ---------------------------------------------------------------------------------
+// Transport session. This maintains all the various parts of a session
+// ---------------------------------------------------------------------------------
+struct transport_session_struct {
+
+ /* our socket connection */
+ transport_socket* sock_obj;
+ /* our Jabber state machine */
+ jabber_machine* state_machine;
+ /* our SAX push parser context */
+ xmlParserCtxtPtr parser_ctxt;
+
+ /* our text buffers for holding text data */
+ growing_buffer* body_buffer;
+ growing_buffer* subject_buffer;
+ growing_buffer* thread_buffer;
+ growing_buffer* from_buffer;
+ growing_buffer* recipient_buffer;
+ growing_buffer* status_buffer;
+ growing_buffer* message_error_type;
+ growing_buffer* session_id;
+ int message_error_code;
+
+ /* for OILS extenstions */
+ growing_buffer* router_to_buffer;
+ growing_buffer* router_from_buffer;
+ growing_buffer* router_class_buffer;
+ growing_buffer* router_command_buffer;
+ int router_broadcast;
+
+ /* this can be anything. It will show up in the
+ callbacks for your convenience. Otherwise, it's
+ left untouched. */
+ void* user_data;
+
+ int component; /* true if we're a component */
+
+ /* the Jabber message callback */
+ void (*message_callback) ( void* user_data, transport_message* msg );
+ //void (iq_callback) ( void* user_data, transport_iq_message* iq );
+};
+typedef struct transport_session_struct transport_session;
+
+
+// ------------------------------------------------------------------
+// Allocates and initializes the necessary transport session
+// data structures.
+// ------------------------------------------------------------------
+transport_session* init_transport( char* server, int port, void* user_data, int component );
+
+// ------------------------------------------------------------------
+// Returns the value of the given XML attribute
+// The xmlChar** construct is commonly returned from SAX event
+// handlers. Pass that in with the name of the attribute you want
+// to retrieve.
+// ------------------------------------------------------------------
+char* get_xml_attr( const xmlChar** atts, char* attr_name );
+
+// ------------------------------------------------------------------
+// Waits at most 'timeout' seconds for data to arrive from the
+// TCP handler. A timeout of -1 means to wait indefinitely.
+// ------------------------------------------------------------------
+int session_wait( transport_session* session, int timeout );
+
+// ---------------------------------------------------------------------------------
+// Sends the given Jabber message
+// ---------------------------------------------------------------------------------
+int session_send_msg( transport_session* session, transport_message* msg );
+
+// ---------------------------------------------------------------------------------
+// Returns 1 if this session is connected to the jabber server. 0 otherwise
+// ---------------------------------------------------------------------------------
+int session_connected( transport_session* );
+
+// ------------------------------------------------------------------
+// Deallocates session memory
+// ------------------------------------------------------------------
+int session_free( transport_session* session );
+
+// ------------------------------------------------------------------
+// Connects to the Jabber server. Waits at most connect_timeout
+// seconds before failing
+// ------------------------------------------------------------------
+int session_connect( transport_session* session,
+ const char* username, const char* password,
+ const char* resource, int connect_timeout,
+ enum TRANSPORT_AUTH_TYPE auth_type );
+
+int session_disconnect( transport_session* session );
+
+int reset_session_buffers( transport_session* session );
+
+#endif
--- /dev/null
+#include "generic_utils.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+
+//---------------------------------------------------------------
+// WIN32
+//---------------------------------------------------------------
+#ifdef WIN32
+#include <Windows.h>
+#include <Winsock.h>
+#else
+
+//---------------------------------------------------------------
+// Unix headers
+//---------------------------------------------------------------
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#endif
+
+#ifndef TRANSPORT_SOCKET_H
+#define TRANSPORT_SOCKET_H
+
+/* how many characters we read from the socket at a time */
+#ifdef _ROUTER
+#define BUFSIZE 412
+#else
+#define BUFSIZE 4096
+#endif
+
+/* we maintain the socket information */
+struct transport_socket_struct {
+ /* for a client, sock_fd is THE socket connection. For a server,
+ it's the socket we listen on */
+ int sock_fd;
+ int connected;
+ char* server; /* remote server name or ip */
+ int port;
+ void* user_data;
+
+ /* user_data may be anything. it's whatever you wish
+ to see showing up in the callback in addition to
+ the acutal character data*/
+ void (*data_received_callback) (void * user_data, char*);
+};
+typedef struct transport_socket_struct transport_socket;
+
+/* connects. If is_server is true, we call tcp_server_connect */
+int tcp_connect( transport_socket* obj );
+
+int tcp_send( transport_socket* obj, const char* data );
+
+int tcp_disconnect( transport_socket* obj );
+
+/* does both client and server waiting.
+ returns the socket_fd on success, 0 on error */
+int tcp_wait( transport_socket* obj, int timeout );
+
+int tcp_connected(transport_socket* obj);
+
+
+
+#endif