Merged libopensrf source directories (libtransport, libstack, and utils) into a singl...
authorerickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Thu, 21 Jun 2007 16:19:20 +0000 (16:19 +0000)
committererickson <erickson@9efc2488-bf62-4759-914b-345cdb29e865>
Thu, 21 Jun 2007 16:19:20 +0000 (16:19 +0000)
Moved opensrf headers to trunk/include/opensrf
Moved objson headers to trunk/include/objson
Updated #include's throughout to be fully qualified.  e.g. <opensrf/utils.h>, <objson/object.h>
Removed old, unused trunk/src/xinclude code
Cleaned up Makefiles to support new directory layout

git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@957 9efc2488-bf62-4759-914b-345cdb29e865

127 files changed:
Makefile
include/objson/json2xml.h [new file with mode: 0644]
include/objson/json_parser.h [new file with mode: 0644]
include/objson/object.h [new file with mode: 0644]
include/objson/xml2json.h [new file with mode: 0644]
include/opensrf/log.h [new file with mode: 0644]
include/opensrf/md5.h [new file with mode: 0644]
include/opensrf/osrfConfig.h [new file with mode: 0644]
include/opensrf/osrf_app_session.h [new file with mode: 0644]
include/opensrf/osrf_application.h [new file with mode: 0644]
include/opensrf/osrf_big_hash.h [new file with mode: 0644]
include/opensrf/osrf_big_list.h [new file with mode: 0644]
include/opensrf/osrf_cache.h [new file with mode: 0644]
include/opensrf/osrf_hash.h [new file with mode: 0644]
include/opensrf/osrf_list.h [new file with mode: 0644]
include/opensrf/osrf_message.h [new file with mode: 0644]
include/opensrf/osrf_prefork.h [new file with mode: 0644]
include/opensrf/osrf_settings.h [new file with mode: 0644]
include/opensrf/osrf_stack.h [new file with mode: 0644]
include/opensrf/osrf_system.h [new file with mode: 0644]
include/opensrf/osrf_transgroup.h [new file with mode: 0644]
include/opensrf/sha.h [new file with mode: 0644]
include/opensrf/socket_bundle.h [new file with mode: 0644]
include/opensrf/string_array.h [new file with mode: 0644]
include/opensrf/transport_client.h [new file with mode: 0644]
include/opensrf/transport_message.h [new file with mode: 0644]
include/opensrf/transport_session.h [new file with mode: 0644]
include/opensrf/utils.h [new file with mode: 0644]
include/opensrf/xml_utils.h [new file with mode: 0644]
src/Makefile
src/libopensrf/basic_client.c [new file with mode: 0644]
src/libopensrf/component.c [new file with mode: 0644]
src/libopensrf/log.c [new file with mode: 0644]
src/libopensrf/md5.c [new file with mode: 0644]
src/libopensrf/opensrf.c [new file with mode: 0644]
src/libopensrf/osrfConfig.c [new file with mode: 0644]
src/libopensrf/osrf_app_session.c [new file with mode: 0644]
src/libopensrf/osrf_application.c [new file with mode: 0644]
src/libopensrf/osrf_big_hash.c [new file with mode: 0644]
src/libopensrf/osrf_big_list.c [new file with mode: 0644]
src/libopensrf/osrf_cache.c [new file with mode: 0644]
src/libopensrf/osrf_hash.c [new file with mode: 0644]
src/libopensrf/osrf_list.c [new file with mode: 0644]
src/libopensrf/osrf_message.c [new file with mode: 0644]
src/libopensrf/osrf_prefork.c [new file with mode: 0644]
src/libopensrf/osrf_settings.c [new file with mode: 0644]
src/libopensrf/osrf_stack.c [new file with mode: 0644]
src/libopensrf/osrf_system.c [new file with mode: 0644]
src/libopensrf/osrf_transgroup.c [new file with mode: 0644]
src/libopensrf/sha.c [new file with mode: 0644]
src/libopensrf/socket_bundle.c [new file with mode: 0644]
src/libopensrf/socket_test.c [new file with mode: 0644]
src/libopensrf/string_array.c [new file with mode: 0644]
src/libopensrf/transport_client.c [new file with mode: 0644]
src/libopensrf/transport_message.c [new file with mode: 0644]
src/libopensrf/transport_session.c [new file with mode: 0644]
src/libopensrf/utils.c [new file with mode: 0644]
src/libopensrf/xml_utils.c [new file with mode: 0644]
src/libstack/Makefile [deleted file]
src/libstack/opensrf.c [deleted file]
src/libstack/osrfConfig.c [deleted file]
src/libstack/osrfConfig.h [deleted file]
src/libstack/osrf_app_session.c [deleted file]
src/libstack/osrf_app_session.h [deleted file]
src/libstack/osrf_application.c [deleted file]
src/libstack/osrf_application.h [deleted file]
src/libstack/osrf_big_hash.c [deleted file]
src/libstack/osrf_big_hash.h [deleted file]
src/libstack/osrf_big_list.c [deleted file]
src/libstack/osrf_big_list.h [deleted file]
src/libstack/osrf_cache.c [deleted file]
src/libstack/osrf_cache.h [deleted file]
src/libstack/osrf_hash.c [deleted file]
src/libstack/osrf_hash.h [deleted file]
src/libstack/osrf_list.c [deleted file]
src/libstack/osrf_list.h [deleted file]
src/libstack/osrf_message.c [deleted file]
src/libstack/osrf_message.h [deleted file]
src/libstack/osrf_prefork.c [deleted file]
src/libstack/osrf_prefork.h [deleted file]
src/libstack/osrf_settings.c [deleted file]
src/libstack/osrf_settings.h [deleted file]
src/libstack/osrf_stack.c [deleted file]
src/libstack/osrf_stack.h [deleted file]
src/libstack/osrf_system.c [deleted file]
src/libstack/osrf_system.h [deleted file]
src/libstack/osrf_transgroup.c [deleted file]
src/libstack/osrf_transgroup.h [deleted file]
src/libtransport/Makefile [deleted file]
src/libtransport/basic_client.c [deleted file]
src/libtransport/component.c [deleted file]
src/libtransport/transport_client.c [deleted file]
src/libtransport/transport_client.h [deleted file]
src/libtransport/transport_message.c [deleted file]
src/libtransport/transport_message.h [deleted file]
src/libtransport/transport_session.c [deleted file]
src/libtransport/transport_session.h [deleted file]
src/objson/Makefile
src/objson/json2xml.c
src/objson/json2xml.h [deleted file]
src/objson/json_parser.c
src/objson/json_parser.h [deleted file]
src/objson/object.c
src/objson/object.h [deleted file]
src/objson/objson_test.c
src/objson/xml2json.c
src/objson/xml2json.h [deleted file]
src/srfsh/srfsh.h
src/utils/Makefile [deleted file]
src/utils/fieldmapper-c.pl [deleted file]
src/utils/log.c [deleted file]
src/utils/log.h [deleted file]
src/utils/md5.c [deleted file]
src/utils/md5.h [deleted file]
src/utils/sha.c [deleted file]
src/utils/sha.h [deleted file]
src/utils/socket_bundle.c [deleted file]
src/utils/socket_bundle.h [deleted file]
src/utils/socket_test.c [deleted file]
src/utils/string_array.c [deleted file]
src/utils/string_array.h [deleted file]
src/utils/utils.c [deleted file]
src/utils/utils.h [deleted file]
src/utils/xml_utils.c [deleted file]
src/utils/xml_utils.h [deleted file]
src/xinclude/Makefile [deleted file]
src/xinclude/mod_xinclude.c [deleted file]

index a23c57c..8441861 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,14 +1,18 @@
 all:
-       @source install.conf && make -s -C src all
+       @echo -e "\n * Run 'make verbose' to see full make output\n"
+       source install.conf && make -s -C src all
+
+verbose:
+       source install.conf && make -C src all
 
 jserver:
-       @source install.conf && make -s -C src jserver
+       source install.conf && make -s -C src jserver
 
 install:
-       @source install.conf && make -s -C src install
+       source install.conf && make -s -C src install
 
 jserver-install:
-       @source install.conf && make -s -C src jserver-install
+       source install.conf && make -s -C src jserver-install
 
 clean:
-       @make -s -C src clean
+       make -s -C src clean
diff --git a/include/objson/json2xml.h b/include/objson/json2xml.h
new file mode 100644 (file)
index 0000000..9eaa1c0
--- /dev/null
@@ -0,0 +1,11 @@
+
+#include <string.h>
+#include <stdio.h>
+
+/* the JSON parser, so we can read the response we're XMLizing */
+#include <objson/object.h>
+#include <objson/json_parser.h>
+#include <opensrf/utils.h>
+
+char* jsonObjectToXML(jsonObject*);
+
diff --git a/include/objson/json_parser.h b/include/objson/json_parser.h
new file mode 100644 (file)
index 0000000..ede5d91
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+
+
+
+/* ---------------------------------------------------------------------------------------
+       JSON parser.
+ * --------------------------------------------------------------------------------------- */
+#ifndef JSON_PARSER_H
+#define JSON_PARSER_H
+
+#include <stdio.h>
+#include <objson/object.h>
+#include <opensrf/utils.h>
+
+
+
+/* Parses the given JSON string and returns the built object. 
+ *     returns NULL (and prints parser error to stderr) on error.  
+ */
+
+jsonObject* json_parse_string(char* string);
+
+jsonObject* jsonParseString(char* string);
+jsonObject* jsonParseStringFmt( char* string, ... );
+
+jsonObject* json_parse_file( const char* filename );
+
+jsonObject* jsonParseFile( const char* string );
+
+
+
+/* does the actual parsing work.  returns 0 on success.  -1 on error and
+ * -2 if there was no object to build (string was all comments) 
+ */
+int _json_parse_string(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
+
+/* returns 0 on success and turns obj into a string object */
+int json_parse_json_string(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
+
+/* returns 0 on success and turns obj into a number or double object */
+int json_parse_json_number(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
+
+/* returns 0 on success and turns obj into an 'object' object */
+int json_parse_json_object(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
+
+/* returns 0 on success and turns object into an array object */
+int json_parse_json_array(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
+
+/* churns through whitespace and increments index as it goes.
+ * eat_all == true means we should eat newlines, tabs
+ */
+void json_eat_ws(char* string, unsigned long* index, int eat_all, int current_strlen);
+
+int json_parse_json_bool(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
+
+/* removes comments from a json string.  if the comment contains a class hint
+ * and class_hint isn't NULL, an allocated char* with the class name will be
+ * shoved into *class_hint.  returns 0 on success, -1 on parse error.
+ * 'index' is assumed to be at the second character (*) of the comment
+ */
+int json_eat_comment(char* string, unsigned long* index, char** class_hint, int parse_class, int current_strlen);
+
+/* prints a useful error message to stderr. always returns -1 */
+int json_handle_error(char* string, unsigned long* index, char* err_msg);
+
+/* returns true if c is 0-9 */
+int is_number(char c);
+
+int json_parse_json_null(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
+
+
+#endif
diff --git a/include/objson/object.h b/include/objson/object.h
new file mode 100644 (file)
index 0000000..8d62c1a
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+
+/* ---------------------------------------------------------------------------------------
+       libjson
+ * --------------------------------------------------------------------------------------- */
+
+#ifndef _JSON_OBJECT_H
+#define _JSON_OBJECT_H
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <opensrf/utils.h>
+
+/* json object types */
+#define JSON_HASH      0
+#define JSON_ARRAY     1
+#define JSON_STRING    2
+#define JSON_NUMBER    3
+#define JSON_NULL      4       
+#define JSON_BOOL      5
+
+
+/* top level generic object structure */
+struct _jsonObjectStruct {
+
+       /* how many sub-objects do we contain if we're an array or an object.  
+               Note that this includes null array elements in sparse arrays */
+       unsigned long size;
+
+       /* optional class hint */
+       char* classname;
+
+       /* see JSON types above */
+       int type;
+
+
+       /* our cargo */
+       union _jsonObjectValue {
+               struct _jsonObjectNodeStruct* c; /* our list of sub-objects if we're an array or a hash */
+               char*           s; /* string */
+               int                     b; /* bool */
+               double          n; /* number */
+       } value;
+       
+
+       /* client may provide a comment string which will be 
+        * added to the object when stringified */
+       char* comment;
+
+};
+typedef struct _jsonObjectStruct jsonObject;
+
+
+/** 
+       String parsing function.  This is assigned by the json_parser code.
+       to avoid circular dependency, declare the parse function here,
+       and have the json parse code set the variable to a real function 
+*/
+//jsonObject* (*jsonParseString) (char* str);
+
+
+/* this contains a single element of the object along with the elements 
+ * index (if this object is an array) and key (if this object is a hash)
+ */
+struct _jsonObjectNodeStruct {
+
+       unsigned long index; /* our array position */
+       char* key; /* our hash key */
+
+       jsonObject* item; /* our object */
+       struct _jsonObjectNodeStruct* next; /* pointer to the next object node */
+};
+typedef struct _jsonObjectNodeStruct jsonObjectNode;
+
+
+
+/* utility object for iterating over hash objects */
+struct _jsonObjectIteratorStruct {
+       const jsonObject* obj; /* the topic object */
+       jsonObjectNode* current; /* the current node within the object */
+};
+typedef struct _jsonObjectIteratorStruct jsonObjectIterator;
+
+
+/** Allocates a new iterator 
+       @param obj The object over which to iterate.
+*/
+jsonObjectIterator* jsonNewObjectIterator(const jsonObject* obj);
+
+/** 
+       De-allocates an iterator 
+       @param iter The iterator object to free
+*/
+void jsonObjectIteratorFree(jsonObjectIterator* iter);
+
+/** 
+       Returns the object_node currently pointed to by the iterator
+       and increments the pointer to the next node
+       @param iter The iterator in question.
+ */
+jsonObjectNode* jsonObjectIteratorNext(jsonObjectIterator* iter);
+
+/** 
+       @param iter The iterator.
+       @return True if there is another node after the current node.
+ */
+int jsonObjectIteratorHasNext(const jsonObjectIterator* iter);
+
+
+/** 
+       Allocates a new object. 
+       @param string The string data if this object is to be a string.  
+       if not, string should be NULL 
+       @return The newly allocated object or NULL on memory error.
+*/
+jsonObject* jsonNewObjectFmt(const char* string, ...);
+jsonObject* jsonNewObject(const char* string);
+
+/**
+       Allocates a new JSON number object.
+       @param num The number this object is to hold
+       @return The newly allocated object.
+*/
+jsonObject* jsonNewNumberObject( double num );
+
+
+/** 
+       Returns a pointer to the object at the given index.  This call is
+       only valid if the object has a type of JSON_ARRAY.
+       @param obj The object
+       @param index The position within the object
+       @return The object at the given index.
+*/
+jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index );
+
+
+/** 
+       Returns a pointer to the object with the given key 
+       @param obj The object
+       @param key The key
+       @return The object with the given key.
+*/
+jsonObject* jsonObjectGetKey( const jsonObject* obj, const char* key );
+
+/** 
+       De-allocates an object.  Note that this function should only be called 
+       on objects that are _not_ children of other objects or there will be
+       double-free's
+       @param obj The object to free.
+*/
+void jsonObjectFree(jsonObject* obj);
+
+
+/** 
+       Allocates a new object node.
+       @param obj The object to which the node will be appended.
+       @return The new object node.
+*/
+jsonObjectNode* jsonNewObjectNode(jsonObject* obj);
+
+/** 
+       De-allocates an object node 
+       @param obj The object node to de-allocate.
+*/
+void jsonObjectNodeFree(jsonObjectNode* obj);
+
+
+/** 
+       Pushes the given object onto the end of the list.  This coerces an object
+       into becoming an array.  _Only_ use this function on objects that you
+       want to become an array.
+       If obj is NULL, inserts a new NULL object into the list.
+       @return array size on success, -1 on error 
+ */
+unsigned long jsonObjectPush(jsonObject* dest, jsonObject* newObj);
+
+/* removes (and deallocates) the object at the given index (if one exists) and inserts 
+ * the new one.  returns the size on success, -1 on error 
+ * If obj is NULL, inserts a new object into the list with is_null set to true
+ */
+unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj);
+
+/* inserts the new object, overwriting (removing, deallocating) any 
+ * previous object with the given key.
+ * returns the size on success, -1 on error 
+ * if 'obj' is NULL, a new object is inserted at key 'key' with 'is_null' 
+ * set to true
+ */
+unsigned long jsonObjectSetKey(jsonObject* dest, const char* key, jsonObject* newObj);
+
+/* removes the object at the given index and, if more items exist,
+ * re-indexes (shifts down by 1) the rest of the objects in the array
+ */
+unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index);
+
+/* removes (and deallocates) the object with key 'key' if it exists */
+unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key);
+
+/* returns a pointer to the string data held by this object if this object
+       is a string.  Otherwise returns NULL*/
+char* jsonObjectGetString(const jsonObject*);
+
+double jsonObjectGetNumber( const jsonObject* obj );
+
+/* sets the string data */
+void jsonObjectSetString(jsonObject* dest, const char* string);
+
+/* sets the number value for the object */
+void jsonObjectSetNumber(jsonObject* dest, double num);
+
+/* sets the class hint for this object */
+void jsonObjectSetClass(jsonObject* dest, const char* classname );
+
+/* converts an object to a json string.  client is responsible for freeing the return string */
+char* jsonObjectToJSON( const jsonObject* obj );
+
+/* set this object's comment string */
+void jsonObjectSetComment(jsonObject* dest, const char* classname);
+
+/* utility method.  starting at index 'index', shifts all indices down by one and 
+ * decrements the objects size by 1 
+ */
+void _jsonObjectShiftIndex(jsonObject* dest, unsigned long index);
+
+/* formats a JSON string from printing.  User must free returned string */
+char* jsonFormatString( const char* jsonString );
+
+jsonObject* jsonObjectClone( const jsonObject* o );
+
+/* tries to extract the string data from an object.
+       if object -> NULL (the C NULL)
+       if array ->     NULL  (the C NULL)
+       if null  -> NULL (the C NULL)
+       if true/false -> true/false
+       if string/number/double the string version of either of those
+       The caller is responsible for freeing the returned string
+       */
+char* jsonObjectToSimpleString( const jsonObject* o );
+
+int jsonBoolIsTrue( const jsonObject* o );
+
+
+/* ------------------------------------------------------------------------ */
+/* XPATH */
+
+/* provides an XPATH style search interface (e.g. /some/node/here) and 
+       return the object at that location if one exists.  Naturally,  
+       every element in the path must be a proper object ("hash" / {}).
+       Returns NULL if the specified node is not found 
+       Note also that the object returned is a clone and
+       must be freed by the caller
+*/
+jsonObject* jsonObjectFindPath( const jsonObject* obj, char* path, ... );
+
+
+/* Utility method. finds any object in the tree that matches the path.  
+       Use this for finding paths that start with '//' */
+jsonObject* _jsonObjectFindPathRecurse( const jsonObject* o, char* root, char* path );
+
+/* returns a list of object whose key is 'root'.  These are used as
+       potential objects when doing a // search */
+jsonObject* __jsonObjectFindPathRecurse( const jsonObject* o, char* root );
+
+/* ------------------------------------------------------------------------ */
+
+
+#endif
+
+
diff --git a/include/objson/xml2json.h b/include/objson/xml2json.h
new file mode 100644 (file)
index 0000000..a9ded67
--- /dev/null
@@ -0,0 +1,19 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <libxml/globals.h>
+#include <libxml/xmlerror.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#include <libxml/xmlmemory.h>
+
+#include <objson/object.h>
+#include <objson/json_parser.h>
+#include <opensrf/utils.h>
+#include <opensrf/osrf_list.h>
+
+
+jsonObject* jsonXMLToJSONObject(const char* xml);
+
+
+
diff --git a/include/opensrf/log.h b/include/opensrf/log.h
new file mode 100644 (file)
index 0000000..4aafad3
--- /dev/null
@@ -0,0 +1,80 @@
+#include <opensrf/utils.h>
+
+#include <syslog.h>
+#include <stdio.h>
+#include <time.h>
+#include <errno.h>
+
+#ifndef OSRF_LOG_INCLUDED
+#define OSRF_LOG_INCLUDED
+
+/* log levels */
+#define OSRF_LOG_ERROR 1
+#define OSRF_LOG_WARNING 2
+#define OSRF_LOG_INFO 3
+#define OSRF_LOG_DEBUG 4
+#define OSRF_LOG_INTERNAL 5
+#define OSRF_LOG_ACTIVITY -1
+
+#define OSRF_LOG_TYPE_FILE 1
+#define OSRF_LOG_TYPE_SYSLOG 2
+
+#define OSRF_LOG_MARK __FILE__, __LINE__
+
+
+/* Initializes the logger. */
+void osrfLogInit( int type, const char* appname, int maxlevel );
+
+/** Sets the systlog facility for the regular logs */
+void osrfLogSetSyslogFacility( int facility );
+
+/** Sets the systlog facility for the activity logs */
+void osrfLogSetSyslogActFacility( int facility );
+
+/** Sets the log file to use if we're logging to a file */
+void osrfLogSetFile( const char* logfile );
+
+/* once we know which application we're running, call this method to
+ * set the appname so log lines can include the app name */
+void osrfLogSetAppname( const char* appname );
+
+/** Set or Get the global log level.  Any log statements with a higher level
+ * than "level" will not be logged */
+void osrfLogSetLevel( int loglevel );
+int osrfLogGetLevel( void );
+
+/* Log an error message */
+void osrfLogError( const char* file, int line, const char* msg, ... );
+
+/* Log a warning message */
+void osrfLogWarning( const char* file, int line, const char* msg, ... );
+
+/* log an info message */
+void osrfLogInfo( const char* file, int line, const char* msg, ... );
+
+/* Log a debug message */
+void osrfLogDebug( const char* file, int line, const char* msg, ... );
+
+/* Log an internal debug message */
+void osrfLogInternal( const char* file, int line, const char* msg, ... );
+
+/* Log an activity message */
+void osrfLogActivity( const char* file, int line, const char* msg, ... );
+
+void osrfLogCleanup();
+
+void osrfLogClearXid();
+void osrfLogSetXid(char* xid);
+void osrfLogMkXid();
+void osrfLogSetIsClient(int is);
+char* osrfLogGetXid();
+
+/* sets the activity flag */
+void osrfLogSetActivityEnabled( int enabled );
+
+/* returns the int representation of the log facility based on the facility name
+ * if the facility name is invalid, LOG_LOCAL0 is returned 
+ */
+int osrfLogFacilityToInt( char* facility );
+
+#endif
diff --git a/include/opensrf/md5.h b/include/opensrf/md5.h
new file mode 100644 (file)
index 0000000..53dd2b1
--- /dev/null
@@ -0,0 +1,35 @@
+/* --- The MD5 routines --- */
+
+/* MD5 routines, after Ron Rivest */
+/* Written by David Madore <david.madore@ens.fr>, with code taken in
+ * part from Colin Plumb. */
+/* Public domain (1999/11/24) */
+
+/* Note: these routines do not depend on endianness. */
+
+/* === The header === */
+
+/* Put this in md5.h if you don't like having everything in one big
+ * file. */
+
+#ifndef _DMADORE_MD5_H
+#define _DMADORE_MD5_H
+
+struct md5_ctx {
+  /* The four chaining variables */
+  unsigned long buf[4];
+  /* Count number of message bits */
+  unsigned long bits[2];
+  /* Data being fed in */
+  unsigned long in[16];
+  /* Our position within the 512 bits (always between 0 and 63) */
+  int b;
+};
+
+void MD5_transform (unsigned long buf[4], const unsigned long in[16]);
+void MD5_start (struct md5_ctx *context);
+void MD5_feed (struct md5_ctx *context, unsigned char inb);
+void MD5_stop (struct md5_ctx *context, unsigned char digest[16]);
+
+#endif /* not defined _DMADORE_MD5_H */
+
diff --git a/include/opensrf/osrfConfig.h b/include/opensrf/osrfConfig.h
new file mode 100644 (file)
index 0000000..75dbcfd
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+#ifndef _OSRF_CONFIG_H
+#define _OSRF_CONFIG_H
+
+#include <opensrf/xml_utils.h>
+#include <opensrf/utils.h>
+#include <opensrf/string_array.h>
+#include <objson/object.h>
+
+typedef struct {
+       jsonObject* config;
+       char* configContext;
+} osrfConfig;
+
+
+/**
+       Parses a new config file.  Caller is responsible for freeing the returned
+               config object when finished.  
+       @param configFile The XML config file to parse.
+       @param configContext Optional root of the subtree in the config file where 
+       we will look for values. If it's not provided,  searches will be 
+       performed from the root of the config file
+       @return The config object if the file parses successfully.  Otherwise
+               it returns NULL;
+*/
+osrfConfig* osrfConfigInit(char* configFile, char* configContext);
+
+/**
+       @return True if we have a default config defined
+*/
+int osrfConfigHasDefaultConfig();
+
+/**
+       Replaces the config object's objson object.  This is useful
+       if you have an ojbson object already and not an XML config
+       file to parse.
+       @param cfg The config object to alter
+       @param obj The objson objet to use when searching values
+*/
+void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj);
+
+/** Deallocates a config object 
+       @param cfg The config object to free
+*/
+void osrfConfigFree(osrfConfig* cfg);
+
+
+/* Assigns the default config file.  This file will be used whenever
+       NULL is passed to config retrieval functions 
+       @param cfg The config object to use as the default config
+*/
+void osrfConfigSetDefaultConfig(osrfConfig* cfg);
+
+/* frees the default config if one exists */
+void osrfConfigCleanup();
+
+
+/** 
+       Returns the value in the config found at 'path'.
+       If the value found at 'path' is a long or a double,
+       the value is stringified and then returned.
+       The caller must free the returned char* 
+
+       if there is a configContext, then it will be appended to 
+       the front of the path like so: //<configContext>/<path>
+       if no configContext was provided to osfConfigSetFile, then 
+       the path is interpreted literally.
+       @param cfg The config file to search or NULL if the default
+               config should be used
+       @param path The search path
+*/
+char* osrfConfigGetValue(osrfConfig* cfg, char* path, ...);
+
+/** 
+       Puts the list of values found at 'path' into the pre-allocated 
+       string array.  
+       Note that the config node found at 'path' must be an array.
+       @param cfg The config file to search or NULL if the default
+               config should be used
+       @param arr An allocated string_array where the values will
+               be stored
+       @param path The search path
+       @return the number of values added to the string array;
+*/
+
+int osrfConfigGetValueList(osrfConfig* cfg, osrfStringArray* arr, char* path, ...);
+
+
+#endif
diff --git a/include/opensrf/osrf_app_session.h b/include/opensrf/osrf_app_session.h
new file mode 100644 (file)
index 0000000..aae373c
--- /dev/null
@@ -0,0 +1,234 @@
+#ifndef _OSRF_APP_SESSION
+#define _OSRF_APP_SESSION
+
+#include <opensrf/transport_client.h>
+#include <opensrf/osrf_message.h>
+#include <opensrf/osrf_system.h>
+#include <opensrf/string_array.h>
+#include <opensrf/osrfConfig.h>
+#include <opensrf/osrf_hash.h>
+#include <opensrf/osrf_list.h>
+
+#include <objson/object.h>
+#include <objson/json_parser.h>
+
+
+
+#define        DEF_RECV_TIMEOUT 6 /* receive timeout */
+#define        DEF_QUEUE_SIZE  
+
+enum OSRF_SESSION_STATE { OSRF_SESSION_CONNECTING, OSRF_SESSION_CONNECTED, OSRF_SESSION_DISCONNECTED };
+enum OSRF_SESSION_TYPE { OSRF_SESSION_SERVER, OSRF_SESSION_CLIENT };
+
+/* entry point for data into the stack.  gets set in osrf_stack.c */
+int (*osrf_stack_entry_point) (transport_client* client, int timeout, int* recvd );
+
+struct osrf_app_request_struct {
+       /** Our controlling session */
+       struct osrf_app_session_struct* session;
+
+       /** our "id" */
+       int request_id;
+       /** True if we have received a 'request complete' message from our request */
+       int complete;
+       /** Our original request payload */
+       osrf_message* payload; 
+       /** List of responses to our request */
+       osrf_message* result;
+
+       /* if set to true, then a call that is waiting on a response, will reset the 
+               timeout and set this variable back to false */
+       int reset_timeout;
+};
+typedef struct osrf_app_request_struct osrf_app_request;
+typedef struct osrf_app_request_struct osrfAppRequest;
+
+struct osrf_app_session_struct {
+
+       /** Our messag passing object */
+       transport_client* transport_handle;
+       /** Cache of active app_request objects */
+
+       //osrf_app_request* request_queue;
+
+       osrfList* request_queue;
+
+       /** The original remote id of the remote service we're talking to */
+       char* orig_remote_id;
+       /** The current remote id of the remote service we're talking to */
+       char* remote_id;
+
+       /** Who we're talking to if we're a client.  
+               what app we're serving if we're a server */
+       char* remote_service;
+
+       /** The current request thread_trace */
+       int thread_trace;
+       /** Our ID */
+       char* session_id;
+
+       /* true if this session does not require connect messages */
+       int stateless;
+
+       /** The connect state */
+       enum OSRF_SESSION_STATE state;
+
+       /** SERVER or CLIENT */
+       enum OSRF_SESSION_TYPE type;
+
+       /* let the user use the session to store their own session data */
+       void* userData;
+
+       void (*userDataFree) (void*);
+};
+typedef struct osrf_app_session_struct osrf_app_session;
+typedef struct osrf_app_session_struct osrfAppSession;
+
+
+
+// -------------------------------------------------------------------------- 
+// PUBLIC API ***
+// -------------------------------------------------------------------------- 
+
+/** Allocates a initializes a new app_session */
+osrf_app_session* osrfAppSessionClientInit( char* remote_service );
+osrf_app_session* osrf_app_client_session_init( char* remote_service );
+
+/** Allocates and initializes a new server session.  The global session cache
+  * is checked to see if this session already exists, if so, it's returned 
+  */
+osrf_app_session* osrf_app_server_session_init( 
+               char* session_id, char* our_app, char* remote_id );
+
+/** returns a session from the global session hash */
+osrf_app_session* osrf_app_session_find_session( char* session_id );
+
+/** Builds a new app_request object with the given payload andn returns
+  * the id of the request.  This id is then used to perform work on the
+  * requeset.
+  */
+int osrfAppSessionMakeRequest(
+               osrf_app_session* session, jsonObject* params, 
+               char* method_name, int protocol, string_array* param_strings);
+
+int osrf_app_session_make_req( 
+               osrf_app_session* session, jsonObject* params, 
+               char* method_name, int protocol, string_array* param_strings);
+
+/** Sets the given request to complete state */
+void osrf_app_session_set_complete( osrf_app_session* session, int request_id );
+
+/** Returns true if the given request is complete */
+int osrf_app_session_request_complete( osrf_app_session* session, int request_id );
+
+/** Does a recv call on the given request */
+osrf_message* osrfAppSessionRequestRecv(
+               osrf_app_session* session, int request_id, int timeout );
+osrf_message* osrf_app_session_request_recv( 
+               osrf_app_session* session, int request_id, int timeout );
+
+/** Removes the request from the request set and frees the reqest */
+void osrf_app_session_request_finish( osrf_app_session* session, int request_id );
+
+/** Resends the orginal request with the given request id */
+int osrf_app_session_request_resend( osrf_app_session*, int request_id );
+
+/** Resets the remote connection target to that of the original*/
+void osrf_app_session_reset_remote( osrf_app_session* );
+
+/** Sets the remote target to 'remote_id' */
+void osrf_app_session_set_remote( osrf_app_session* session, char* remote_id );
+
+/** pushes the given message into the result list of the app_request
+  * whose request_id matches the messages thread_trace 
+  */
+int osrf_app_session_push_queue( osrf_app_session*, osrf_message* msg );
+
+/** Attempts to connect to the remote service. Returns 1 on successful 
+  * connection, 0 otherwise.
+  */
+int osrf_app_session_connect( osrf_app_session* );
+int osrfAppSessionConnect( osrf_app_session* );
+
+/** Sends a disconnect message to the remote service.  No response is expected */
+int osrf_app_session_disconnect( osrf_app_session* );
+
+/**  Waits up to 'timeout' seconds for some data to arrive.
+  * Any data that arrives will be processed according to its
+  * payload and message type.  This method will return after
+  * any data has arrived.
+  */
+int osrf_app_session_queue_wait( osrf_app_session*, int timeout, int* recvd );
+
+/** Disconnects (if client), frees any attached app_reuqests, removes the session from the 
+  * global session cache and frees the session.  Needless to say, only call this when the
+  * session is completey done.
+  */
+void osrf_app_session_destroy ( osrf_app_session* );
+void osrfAppSessionFree( osrfAppSession* );
+
+
+
+// --------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// Request functions
+// --------------------------------------------------------------------------
+
+/** Allocations and initializes a new app_request object */
+osrf_app_request* _osrf_app_request_init( osrf_app_session* session, osrf_message* msg );
+
+/** Frees memory used by an app_request object */
+void _osrf_app_request_free( void * req );
+
+/** Pushes the given message onto the list of 'responses' to this request */
+void _osrf_app_request_push_queue( osrf_app_request*, osrf_message* payload );
+
+/** Checks the receive queue for messages.  If any are found, the first
+  * is popped off and returned.  Otherwise, this method will wait at most timeout 
+  * seconds for a message to appear in the receive queue.  Once it arrives it is returned.
+  * If no messages arrive in the timeout provided, null is returned.
+  */
+osrf_message* _osrf_app_request_recv( osrf_app_request* req, int timeout );
+
+/** Resend this requests original request message */
+int _osrf_app_request_resend( osrf_app_request* req );
+
+
+/* tells the request to reset it's wait timeout */
+void osrf_app_session_request_reset_timeout( osrf_app_session* session, int req_id );
+
+// --------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// Session functions 
+// --------------------------------------------------------------------------
+
+/** Returns the app_request with the given thread_trace (request_id) */
+osrf_app_request* _osrf_app_session_get_request( osrf_app_session*, int thread_trace );
+
+/** frees memory held by a session. Note: We delete all requests in the request list */
+void _osrf_app_session_free( osrf_app_session* );
+
+/** adds a session to the global session cache */
+void _osrf_app_session_push_session( osrf_app_session* );
+
+/** Adds an app_request to the request set */
+void _osrf_app_session_push_request( osrf_app_session*, osrf_app_request* req );
+
+/** Removes an app_request from this session request set, freeing the request object */
+void _osrf_app_session_remove_request( osrf_app_session*, osrf_app_request* req );
+
+/** Send the given message */
+int _osrf_app_session_send( osrf_app_session*, osrf_message* msg );
+
+int osrfAppSessionSendBatch( osrf_app_session*, osrf_message* msgs[], int size );
+
+int osrfAppRequestRespond( osrfAppSession* ses, int requestId, jsonObject* data ); 
+int osrfAppRequestRespondComplete( osrfAppSession* ses, int requestId, jsonObject* data ); 
+
+int osrfAppSessionStatus( osrfAppSession* ses, int type, char* name, int reqId, char* message );
+
+void osrfAppSessionCleanup();
+
+
+
+#endif
diff --git a/include/opensrf/osrf_application.h b/include/opensrf/osrf_application.h
new file mode 100644 (file)
index 0000000..ac548a2
--- /dev/null
@@ -0,0 +1,234 @@
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
+#include <opensrf/osrf_app_session.h>
+#include <opensrf/osrf_hash.h>
+
+#include <objson/object.h>
+#include <stdio.h>
+#include <dlfcn.h>
+
+
+/**
+  All OpenSRF methods take the signature
+  int methodName( osrfMethodContext* );
+  If a negative number is returned, it means an unknown error occured and an exception
+  will be returned to the client automatically.
+  If a positive number is returned, it means that libopensrf should send a 'Request Complete'
+  message following any messages sent by the method.
+  If 0 is returned, it tells libopensrf that the method completed successfully and 
+  there is no need to send any further data to the client.
+  */
+
+
+
+/** 
+  This macro verifies methods receive the correct parameters */
+#define _OSRF_METHOD_VERIFY_CONTEXT(d) \
+       if(!d) return -1; \
+       if(!d->session) { osrfLogError( OSRF_LOG_MARK,  "Session is NULL in app reqeust" ); return -1; }\
+       if(!d->method) { osrfLogError( OSRF_LOG_MARK,  "Method is NULL in app reqeust" ); return -1; }\
+       if(d->method->argc) {\
+               if(!d->params) { osrfLogError( OSRF_LOG_MARK,  "Params is NULL in app reqeust %s", d->method->name ); return -1; }\
+               if( d->params->type != JSON_ARRAY ) { \
+                       osrfLogError( OSRF_LOG_MARK,  "'params' is not a JSON array for method %s", d->method->name);\
+                       return -1; }\
+       }\
+       if( !d->method->name ) { osrfLogError( OSRF_LOG_MARK,  "Method name is NULL"); return -1; } 
+
+#ifdef OSRF_LOG_PARAMS 
+#define OSRF_METHOD_VERIFY_CONTEXT(d) \
+       _OSRF_METHOD_VERIFY_CONTEXT(d); \
+       char* __j = jsonObjectToJSON(d->params);\
+       if(__j) { \
+               osrfLogInfo( OSRF_LOG_MARK,  "CALL:     %s %s - %s", d->session->remote_service, d->method->name, __j);\
+               free(__j); \
+       } 
+#else
+#define OSRF_METHOD_VERIFY_CONTEXT(d) _OSRF_METHOD_VERIFY_CONTEXT(d); 
+#endif
+
+
+
+/* used internally to make sure the method description provided is OK */
+#define OSRF_METHOD_VERIFY_DESCRIPTION(app, d) \
+       if(!app) return -1; \
+       if(!d) return -1;\
+       if(!d->name) { osrfLogError( OSRF_LOG_MARK,  "No method name provided in description" ), return -1; } \
+       if(!d->symbol) { osrfLogError( OSRF_LOG_MARK,  "No method symbol provided in description" ), return -1; } \
+       if(!d->notes) d->notes = ""; \
+       if(!d->paramNotes) d->paramNotes = "";\
+       if(!d->returnNotes) d->returnNotes = "";
+
+
+
+
+/* Some well known parameters */
+#define OSRF_SYSMETHOD_INTROSPECT                              "opensrf.system.method"
+#define OSRF_SYSMETHOD_INTROSPECT_ATOMIC               "opensrf.system.method.atomic"
+#define OSRF_SYSMETHOD_INTROSPECT_ALL                  "opensrf.system.method.all"
+#define OSRF_SYSMETHOD_INTROSPECT_ALL_ATOMIC   "opensrf.system.method.all.atomic"
+#define OSRF_SYSMETHOD_ECHO                                            "opensrf.system.echo"
+#define OSRF_SYSMETHOD_ECHO_ATOMIC                             "opensrf.system.echo.atomic"
+
+#define OSRF_METHOD_SYSTEM                     1
+#define OSRF_METHOD_STREAMING          2
+#define OSRF_METHOD_ATOMIC                     4
+#define OSRF_METHOD_CACHABLE           8
+
+       
+
+struct _osrfApplicationStruct {
+       void* handle;                                                                   /* the lib handle */
+       osrfHash* methods;
+   void (*onExit) (void);
+};
+typedef struct _osrfApplicationStruct osrfApplication;
+
+
+struct _osrfMethodStruct {
+       char* name;                                     /* the method name */
+       char* symbol;                           /* the symbol name (function) */
+       char* notes;                            /* public method documentation */
+       int argc;                                       /* how many args this method expects */
+       //char* paramNotes;                     /* Description of the params expected for this method */
+       int options;                            /* describes the various options for this method */
+       void* userData;                         /* You can put your weeeeeeed in it ... */
+
+       /*
+       int sysmethod;                          
+       int streaming;                          
+       int atomic;                                     
+       int cachable;                           
+       */
+}; 
+typedef struct _osrfMethodStruct osrfMethod;
+
+struct _osrfMethodContextStruct {
+       osrfAppSession* session;        /* the current session */
+       osrfMethod* method;                     /* the requested method */      
+       jsonObject* params;                     /* the params to the method */
+       int request;                                    /* request id */
+       jsonObject* responses;          /* array of cached responses. */
+};
+typedef struct _osrfMethodContextStruct osrfMethodContext;
+
+
+
+/** 
+  Register an application
+  @param appName The name of the application
+  @param soFile The library (.so) file that implements this application
+  @return 0 on success, -1 on error
+  */
+int osrfAppRegisterApplication( char* appName, char* soFile );
+
+/**
+  Register a method
+  Any method with  the OSRF_METHOD_STREAMING option set will have a ".atomic"
+  version of the method registered automatically
+  @param appName The name of the application that implements the method
+  @param methodName The fully qualified name of the method
+  @param symbolName The symbol name (function) that implements the method
+  @param notes Public documentation for this method.
+  @params argc The number of arguments this method expects 
+  @param streaming True if this is a streaming method that requires an atomic version
+  @return 0 on success, -1 on error
+  */
+int osrfAppRegisterMethod( char* appName, char* methodName, 
+               char* symbolName, char* notes, int argc, int options );
+
+
+int osrfAppRegisterExtendedMethod( char* appName, char* methodName, 
+               char* symbolName, char* notes, int argc, int options, void* );
+
+osrfMethod* _osrfAppBuildMethod( char* methodName, 
+               char* symbolName, char* notes, int argc, int options, void* );
+
+/**
+  Finds the given app in the list of apps
+  @param name The name of the application
+  @return The application pointer or NULL if there is no such application
+  */
+osrfApplication* _osrfAppFindApplication( char* name );
+
+/**
+  Finds the given method for the given app
+  @param appName The application
+  @param methodName The method to find
+  @return A method pointer or NULL if no such method 
+  exists for the given application
+  */
+osrfMethod* _osrfAppFindMethod( char* appName, char* methodName );
+
+/**
+  Finds the given method for the given app
+  @param app The application object
+  @param methodName The method to find
+  @return A method pointer or NULL if no such method 
+  exists for the given application
+  */
+osrfMethod* __osrfAppFindMethod( osrfApplication* app, char* methodName );
+
+
+/**
+  Runs the specified method for the specified application.
+  @param appName The name of the application who's method to run
+  @param methodName The name of the method to run
+  @param ses The app session attached to this request
+  @params reqId The request id for this request
+  @param params The method parameters
+  */
+int osrfAppRunMethod( char* appName, char* methodName, 
+               osrfAppSession* ses, int reqId, jsonObject* params );
+
+
+/**
+  Trys to run the requested method as a system method.
+  A system method is a well known method that all
+  servers implement.  
+  @param context The current method context
+  @return 0 if the method is run successfully, return < 0 means
+  the method was not run, return > 0 means the method was run
+  and the application code now needs to send a 'request complete' 
+  message
+  */
+int __osrfAppRunSystemMethod(osrfMethodContext* context);
+
+/**
+  Registers all of the system methods for this app so that they may be
+  treated the same as other methods */
+int __osrfAppRegisterSysMethods( char* app );
+
+
+
+/**
+  Responds to the client with a method exception
+  @param ses The current session
+  @param request The request id
+  @param msg The debug message to send to the client
+  @return 0 on successfully sending of the message, -1 otherwise
+  */
+int osrfAppRequestRespondException( osrfAppSession* ses, int request, char* msg, ... );
+
+int __osrfAppPostProcess( osrfMethodContext* context, int retcode );
+
+
+int osrfAppRespond( osrfMethodContext* context, jsonObject* data );
+int _osrfAppRespond( osrfMethodContext* context, jsonObject* data, int complete );
+int osrfAppRespondComplete( osrfMethodContext* context, jsonObject* data );
+
+/* OSRF_METHOD_ATOMIC and/or OSRF_METHOD_CACHABLE and/or 0 for no special options */
+//int osrfAppProcessMethodOptions( char* method );
+
+int osrfAppIntrospect( osrfMethodContext* ctx );
+int osrfAppIntrospectAll( osrfMethodContext* ctx );
+int osrfAppEcho( osrfMethodContext* ctx );
+
+
+/**
+ * Tells the backend process to run its child init function */
+int osrfAppRunChildInit(char* appname);
+void osrfAppSetOnExit(osrfApplication* app, char* appName);
+void osrfAppRunExitCode();
+
+
diff --git a/include/opensrf/osrf_big_hash.h b/include/opensrf/osrf_big_hash.h
new file mode 100644 (file)
index 0000000..a738755
--- /dev/null
@@ -0,0 +1,87 @@
+#ifndef OSRF_HASH_H
+#define OSRF_HASH_H
+
+#include <Judy.h>
+#include <opensrf/utils.h>
+#include <opensrf/string_array.h>
+
+#define OSRF_HASH_MAXKEY 256
+
+struct __osrfBigHashStruct {
+       Pvoid_t hash;                                                   /* the hash */
+       void (*freeItem) (char* key, void* item);       /* callback for freeing stored items */
+};
+typedef struct __osrfBigHashStruct osrfBigHash;
+
+
+struct __osrfBigHashIteratorStruct {
+       char* current;
+       osrfBigHash* hash;
+};
+typedef struct __osrfBigHashIteratorStruct osrfBigHashIterator;
+
+/**
+  Allocates a new hash object
+  */
+osrfBigHash* osrfNewBigHash();
+
+/**
+  Sets the given key with the given item
+  if "freeItem" is defined and an item already exists at the given location, 
+  then old item is freed and the new item is put into place.
+  if "freeItem" is not defined and an item already exists, the old item
+  is returned.
+  @return The old item if exists and there is no 'freeItem', returns NULL
+  otherwise
+  */
+void* osrfBigHashSet( osrfBigHash* hash, void* item, const char* key, ... );
+
+/**
+  Removes an item from the hash.
+  if 'freeItem' is defined it is used and NULL is returned,
+  else the freed item is returned
+  */
+void* osrfBigHashRemove( osrfBigHash* hash, const char* key, ... );
+
+void* osrfBigHashGet( osrfBigHash* hash, const char* key, ... );
+
+
+/**
+  @return A list of strings representing the keys of the hash. 
+  caller is responsible for freeing the returned string array 
+  with osrfStringArrayFree();
+  */
+osrfStringArray* osrfBigHashKeys( osrfBigHash* hash );
+
+/**
+  Frees a hash
+  */
+void osrfBigHashFree( osrfBigHash* hash );
+
+/**
+  @return The number of items in the hash
+  */
+unsigned long osrfBigHashGetCount( osrfBigHash* hash );
+
+
+
+
+/**
+  Creates a new list iterator with the given list
+  */
+osrfBigHashIterator* osrfNewBigHashIterator( osrfBigHash* hash );
+
+/**
+  Returns the next non-NULL item in the list, return NULL when
+  the end of the list has been reached
+  */
+void* osrfBigHashIteratorNext( osrfBigHashIterator* itr );
+
+/**
+  Deallocates the given list
+  */
+void osrfBigHashIteratorFree( osrfBigHashIterator* itr );
+
+void osrfBigHashIteratorReset( osrfBigHashIterator* itr );
+
+#endif
diff --git a/include/opensrf/osrf_big_list.h b/include/opensrf/osrf_big_list.h
new file mode 100644 (file)
index 0000000..ebe3da7
--- /dev/null
@@ -0,0 +1,142 @@
+#ifndef OSRF_BIG_LIST_H
+#define OSRF_BIG_LIST_H
+
+
+#include <stdio.h>
+#include <opensrf/utils.h>
+#include <Judy.h>
+
+/**
+  Items are stored as void*'s so it's up to the user to
+  manage the data wisely.  Also, if the 'freeItem' callback is defined for the list,
+  then, it will be used on any item that needs to be freed, so don't mix data
+  types in the list if you want magic freeing */
+
+struct __osrfBigListStruct {
+       Pvoid_t list;                                                   /* the list */
+       int size;                                                               /* how many items in the list including NULL items between non-NULL items */    
+       void (*freeItem) (void* item);  /* callback for freeing stored items */
+};
+typedef struct __osrfBigListStruct osrfBigList;
+
+
+struct __osrfBigBigListIteratorStruct {
+       osrfBigList* list;
+       unsigned long current;
+};
+typedef struct __osrfBigBigListIteratorStruct osrfBigBigListIterator;
+
+
+/**
+  Creates a new list iterator with the given list
+  */
+osrfBigBigListIterator* osrfNewBigListIterator( osrfBigList* list );
+
+/**
+  Returns the next non-NULL item in the list, return NULL when
+  the end of the list has been reached
+  */
+void* osrfBigBigListIteratorNext( osrfBigBigListIterator* itr );
+
+/**
+  Deallocates the given list
+  */
+void osrfBigBigListIteratorFree( osrfBigBigListIterator* itr );
+
+void osrfBigBigListIteratorReset( osrfBigBigListIterator* itr );
+
+
+/**
+  Allocates a new list
+  @param compress If true, the list will compress empty slots on delete.  If item positionality
+  is not important, then using this feature is reccomended to keep the list from growing indefinitely.
+  if item positionality is not important.
+  @return The allocated list
+  */
+osrfBigList* osrfNewBigList();
+
+/**
+  Pushes an item onto the end of the list.  This always finds the highest index
+  in the list and pushes the new item into the list after it.
+  @param list The list
+  @param item The item to push
+  @return 0 on success, -1 on failure
+  */
+int osrfBigListPush( osrfBigList* list, void* item );
+
+
+/**
+ * Removes the last item in the list
+ * See osrfBigListRemove for details on how the removed item is handled
+ * @return The item, unless 'freeItem' exists, then returns NULL
+ */
+void* osrfBigListPop( osrfBigList* list );
+
+/**
+  Puts the given item into the list at the specified position.  If there
+  is already an item at the given position and the list has it's 
+  "freeItem" function defined, then it will be used to free said item.
+  If no 'freeItem' callback is defined, then the displaced item will
+  be returned;
+  @param list The list
+  @param item The item to put into the list
+  @param position The position to place the item in
+  @return NULL in successfully inserting the new item and freeing
+  any displaced items.  Returns the displaced item if no "freeItem"
+  callback is defined.
+       */
+void* osrfBigListSet( osrfBigList* list, void* item, unsigned long position );
+
+/**
+  Returns the item at the given position
+  @param list The list
+  @param postiont the position
+  */
+void* osrfBigListGetIndex( osrfBigList* list, unsigned long  position );
+
+/**
+  Frees the list and all list items (if the list has a "freeItem" function defined )
+  @param list The list
+  */
+void osrfBigListFree( osrfBigList* list );
+
+/**
+  Removes the list item at the given index
+  @param list The list
+  @param position The position of the item to remove
+  @return A pointer to the item removed if "freeItem" is not defined
+  for this list, returns NULL if it is.
+  */
+void* osrfBigListRemove( osrfBigList* list, int position );
+
+/**
+  Finds the list item whose void* is the same as the one passed in
+  @param list The list
+  @param addr The pointer connected to the list item we're to find
+  @return the index of the item, or -1 if the item was not found
+  */
+int osrfBigListFind( osrfBigList* list, void* addr );
+
+
+void __osrfBigListSetSize( osrfBigList* list );
+
+
+/**
+  @return The number of non-null items in the list
+  */
+unsigned long osrfBigListGetCount( osrfBigList* list );
+
+/**
+ * May be used as a default memory freeing call
+ * Just calls free() on list items
+ */
+void osrfBigListVanillaFree( void* item );
+
+/**
+ * Tells the list to just call 'free()' on each item when
+ * an item or the whole list is destroyed
+ */
+void osrfBigListSetDefaultFree( osrfBigList* list );
+
+
+#endif
diff --git a/include/opensrf/osrf_cache.h b/include/opensrf/osrf_cache.h
new file mode 100644 (file)
index 0000000..5a755ff
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+
+#include <objson/object.h>
+#include <objson/json_parser.h>
+#include <memcache.h>
+#include <opensrf/log.h>
+
+/**
+  osrfCache is a globally shared cache API
+  */
+
+
+/**
+  Initialize the cache.
+  @param serverStrings An array of "ip:port" strings to use as cache servers
+  @param size The size of the serverStrings array
+  @param maxCacheSeconds The maximum amount of time an object / string may
+       be cached.  Negative number means there is no limit
+  */
+int osrfCacheInit( char* serverStrings[], int size, time_t maxCacheSeconds );
+
+
+/**
+  Puts an object into the cache
+  @param key The cache key
+  @param obj The object to cache
+  @param seconds The amount of time to cache the data, negative number means
+       to cache up to 'maxCacheSeconds' as set by osrfCacheInit()
+  @return 0 on success, -1 on error
+  */
+int osrfCachePutObject( char* key, const jsonObject* obj, time_t seconds );
+
+/**
+  Puts a string into the cache
+  @param key The cache key
+  @param value The string to cache
+  @param seconds The amount of time to cache the data, negative number means
+       to cache up to 'maxCacheSeconds' as set by osrfCacheInit()
+  @return 0 on success, -1 on error
+  */
+int osrfCachePutString( char* key, const char* value, time_t seconds);
+
+/**
+  Grabs an object from the cache.
+  @param key The cache key
+  @return The object (which must be freed) if it exists, otherwise returns NULL
+  */
+jsonObject* osrfCacheGetObject( char* key, ... );
+
+/**
+  Grabs a string from the cache.
+  @param key The cache key
+  @return The string (which must be freed) if it exists, otherwise returns NULL
+  */
+char* osrfCacheGetString( char* key, ... );
+
+/**
+  Removes the item with the given key from the cache.
+  @return 0 on success, -1 on error.
+  */
+int osrfCacheRemove( char* key, ... );
+
+/**
+ * Sets the expire time to 'seconds' for the given key
+ */
+int osrfCacheSetExpire( time_t seconds, char* key, ... );
+
+
+
diff --git a/include/opensrf/osrf_hash.h b/include/opensrf/osrf_hash.h
new file mode 100644 (file)
index 0000000..132e43e
--- /dev/null
@@ -0,0 +1,115 @@
+#ifndef OSRF_HASH_H
+#define OSRF_HASH_H
+
+#include <opensrf/utils.h>
+#include <opensrf/string_array.h>
+#include <opensrf/osrf_list.h>
+
+/* 0x100 is a good size for small hashes */
+//#define OSRF_HASH_LIST_SIZE 0x100  /* size of the main hash list */
+#define OSRF_HASH_LIST_SIZE 0x10  /* size of the main hash list */
+
+
+/* used internally */
+#define OSRF_HASH_NODE_FREE(h, n) \
+       if(h && n) { \
+               if(h->freeItem) h->freeItem(n->key, n->item);\
+               free(n->key); free(n); \
+       }
+
+
+struct __osrfHashStruct {
+       osrfList* hash; /* this hash */
+       void (*freeItem) (char* key, void* item);       /* callback for freeing stored items */
+       unsigned int size;
+       osrfStringArray* keys;
+};
+typedef struct __osrfHashStruct osrfHash;
+
+struct _osrfHashNodeStruct {
+       char* key;
+       void* item;
+};
+typedef struct _osrfHashNodeStruct osrfHashNode;
+
+
+struct __osrfHashIteratorStruct {
+       char* current;
+       int currentIdx;
+       osrfHash* hash;
+       osrfStringArray* keys;
+};
+typedef struct __osrfHashIteratorStruct osrfHashIterator;
+
+osrfHashNode* osrfNewHashNode(char* key, void* item);
+void* osrfHashNodeFree(osrfHash*, osrfHashNode*);
+
+/**
+  Allocates a new hash object
+  */
+osrfHash* osrfNewHash();
+
+/**
+  Sets the given key with the given item
+  if "freeItem" is defined and an item already exists at the given location, 
+  then old item is freed and the new item is put into place.
+  if "freeItem" is not defined and an item already exists, the old item
+  is returned.
+  @return The old item if exists and there is no 'freeItem', returns NULL
+  otherwise
+  */
+void* osrfHashSet( osrfHash* hash, void* item, const char* key, ... );
+
+/**
+  Removes an item from the hash.
+  if 'freeItem' is defined it is used and NULL is returned,
+  else the freed item is returned
+  */
+void* osrfHashRemove( osrfHash* hash, const char* key, ... );
+
+void* osrfHashGet( osrfHash* hash, const char* key, ... );
+
+
+/**
+  @return A list of strings representing the keys of the hash. 
+  caller is responsible for freeing the returned string array 
+  with osrfStringArrayFree();
+  */
+osrfStringArray* osrfHashKeys( osrfHash* hash );
+
+osrfStringArray* osrfHashKeysInc( osrfHash* hash );
+
+/**
+  Frees a hash
+  */
+void osrfHashFree( osrfHash* hash );
+
+/**
+  @return The number of items in the hash
+  */
+unsigned long osrfHashGetCount( osrfHash* hash );
+
+
+
+
+/**
+  Creates a new list iterator with the given list
+  */
+osrfHashIterator* osrfNewHashIterator( osrfHash* hash );
+
+int osrfHashIteratorHasNext( osrfHashIterator* itr );
+
+/**
+  Returns the next non-NULL item in the list, return NULL when
+  the end of the list has been reached
+  */
+void* osrfHashIteratorNext( osrfHashIterator* itr );
+
+/**
+  Deallocates the given list
+  */
+void osrfHashIteratorFree( osrfHashIterator* itr );
+
+void osrfHashIteratorReset( osrfHashIterator* itr );
+
+#endif
diff --git a/include/opensrf/osrf_list.h b/include/opensrf/osrf_list.h
new file mode 100644 (file)
index 0000000..f59669a
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef OSRF_LIST_H
+#define OSRF_LIST_H
+
+#include <opensrf/utils.h>
+
+#define OSRF_LIST_DEFAULT_SIZE 48 /* most opensrf lists are small... */
+#define OSRF_LIST_INC_SIZE 256
+#define OSRF_LIST_MAX_SIZE 10240
+
+
+#define OSRF_LIST_GET_INDEX(l, i) (!l || i >= l->size) ? NULL: l->arrlist[i]
+
+/**
+  Items are stored as void*'s so it's up to the user to
+  manage the data wisely.  Also, if the 'freeItem' callback is defined for the list,
+  then, it will be used on any item that needs to be freed, so don't mix data
+  types in the list if you want magic freeing */
+
+struct __osrfListStruct {
+       unsigned int size;                      /* how many items in the list including NULL items between non-NULL items */    
+       void (*freeItem) (void* item);  /* callback for freeing stored items */
+       void** arrlist;
+       int arrsize; /* how big is the currently allocated array */
+};
+typedef struct __osrfListStruct osrfList;
+
+
+struct __osrfListIteratorStruct {
+       const osrfList* list;
+       unsigned int current;
+};
+typedef struct __osrfListIteratorStruct osrfListIterator;
+
+osrfList* osrfNewListSize( unsigned int size );
+
+
+/**
+  Creates a new list iterator with the given list
+  */
+osrfListIterator* osrfNewListIterator( const osrfList* list );
+
+/**
+  Returns the next non-NULL item in the list, return NULL when
+  the end of the list has been reached
+  */
+void* osrfListIteratorNext( osrfListIterator* itr );
+
+/**
+  Deallocates the given list
+  */
+void osrfListIteratorFree( osrfListIterator* itr );
+
+void osrfListIteratorReset( osrfListIterator* itr );
+
+
+/**
+  Allocates a new list
+  @param compress If true, the list will compress empty slots on delete.  If item positionality
+  is not important, then using this feature is reccomended to keep the list from growing indefinitely.
+  if item positionality is not important.
+  @return The allocated list
+  */
+osrfList* osrfNewList();
+
+/**
+  Pushes an item onto the end of the list.  This always finds the highest index
+  in the list and pushes the new item into the list after it.
+  @param list The list
+  @param item The item to push
+  @return 0 on success, -1 on failure
+  */
+int osrfListPush( osrfList* list, void* item );
+
+
+/**
+ * Removes the last item in the list
+ * See osrfListRemove for details on how the removed item is handled
+ * @return The item, unless 'freeItem' exists, then returns NULL
+ */
+void* osrfListPop( osrfList* list );
+
+/**
+  Puts the given item into the list at the specified position.  If there
+  is already an item at the given position and the list has it's 
+  "freeItem" function defined, then it will be used to free said item.
+  If no 'freeItem' callback is defined, then the displaced item will
+  be returned;
+  @param list The list
+  @param item The item to put into the list
+  @param position The position to place the item in
+  @return NULL in successfully inserting the new item and freeing
+  any displaced items.  Returns the displaced item if no "freeItem"
+  callback is defined.
+       */
+void* osrfListSet( osrfList* list, void* item, unsigned int position );
+
+/**
+  Returns the item at the given position
+  @param list The list
+  @param postiont the position
+  */
+void* osrfListGetIndex( const osrfList* list, unsigned int  position );
+
+/**
+  Frees the list and all list items (if the list has a "freeItem" function defined )
+  @param list The list
+  */
+void osrfListFree( osrfList* list );
+
+/**
+  Removes the list item at the given index
+  @param list The list
+  @param position The position of the item to remove
+  @return A pointer to the item removed if "freeItem" is not defined
+  for this list, returns NULL if it is.
+  */
+void* osrfListRemove( osrfList* list, unsigned int position );
+
+/**
+  Finds the list item whose void* is the same as the one passed in
+  @param list The list
+  @param addr The pointer connected to the list item we're to find
+  @return the index of the item, or -1 if the item was not found
+  */
+int osrfListFind( const osrfList* list, void* addr );
+
+
+void __osrfListSetSize( osrfList* list );
+
+
+/**
+  @return The number of non-null items in the list
+  */
+unsigned int osrfListGetCount( const osrfList* list );
+
+/**
+ * May be used as a default memory freeing call
+ * Just calls free() on list items
+ */
+void osrfListVanillaFree( void* item );
+
+/**
+ * Tells the list to just call 'free()' on each item when
+ * an item or the whole list is destroyed
+ */
+void osrfListSetDefaultFree( osrfList* list );
+
+/**
+ * Inserts the new item at the first free (null) slot
+ * in the array.  Item is shoved onto the end of the
+ * list if there are no null slots */
+int osrfListPushFirst( osrfList* list, void* item );
+
+
+#endif
diff --git a/include/opensrf/osrf_message.h b/include/opensrf/osrf_message.h
new file mode 100644 (file)
index 0000000..12e14c6
--- /dev/null
@@ -0,0 +1,121 @@
+#include <opensrf/string_array.h>
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
+#include <objson/object.h>
+#include <objson/json_parser.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>
+
+
+
+#ifndef osrf_message_h
+#define osrf_message_h
+
+#define OSRF_XML_NAMESPACE "http://open-ils.org/xml/namespaces/oils_v1"
+
+#define OSRF_STATUS_CONTINUE                                           100
+
+#define OSRF_STATUS_OK                                                         200
+#define OSRF_STATUS_ACCEPTED                                           202
+#define OSRF_STATUS_COMPLETE                                           205
+
+#define OSRF_STATUS_REDIRECTED                                 307
+
+#define OSRF_STATUS_BADREQUEST                                 400
+#define OSRF_STATUS_UNAUTHORIZED                                       401
+#define OSRF_STATUS_FORBIDDEN                                          403
+#define OSRF_STATUS_NOTFOUND                                           404
+#define OSRF_STATUS_NOTALLOWED                                 405
+#define OSRF_STATUS_TIMEOUT                                            408
+#define OSRF_STATUS_EXPFAILED                                          417
+
+#define OSRF_STATUS_INTERNALSERVERERROR                500
+#define OSRF_STATUS_NOTIMPLEMENTED                             501
+#define OSRF_STATUS_VERSIONNOTSUPPORTED                505
+
+
+enum M_TYPE { CONNECT, REQUEST, RESULT, STATUS, DISCONNECT };
+
+#define OSRF_MAX_PARAMS                                                                128;
+
+struct osrf_message_struct {
+
+       enum M_TYPE m_type;
+       int thread_trace;
+       int protocol;
+
+       /* if we're a STATUS message */
+       char* status_name;
+
+       /* if we're a STATUS or RESULT */
+       char* status_text;
+       int status_code;
+
+       int is_exception;
+
+       /* if we're a RESULT */
+       jsonObject* _result_content;
+
+       /* unparsed json string */
+       char* result_string;
+
+       /* if we're a REQUEST */
+       char* method_name;
+
+       jsonObject* _params;
+
+       /* in case anyone wants to make a list of us.  
+               we won't touch this variable */
+       struct osrf_message_struct* next;
+
+       char* full_param_string;
+
+};
+typedef struct osrf_message_struct osrf_message;
+typedef struct osrf_message_struct osrfMessage;
+
+
+osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol );
+//void osrf_message_set_request_info( osrf_message*, char* param_name, json* params );
+void osrf_message_set_status_info( osrf_message*, char* status_name, char* status_text, int status_code );
+void osrf_message_set_result_content( osrf_message*, char* json_string );
+void osrfMessageFree( osrfMessage* );
+void osrf_message_free( osrf_message* );
+char* osrf_message_to_xml( osrf_message* );
+char* osrf_message_serialize(osrf_message*);
+
+/* count is the max number of messages we'll put into msgs[] */
+int osrf_message_deserialize(char* json, osrf_message* msgs[], int count);
+
+
+
+/** Pushes any message retreived from the xml into the 'msgs' array.
+  * it is assumed that 'msgs' has beenn pre-allocated.
+  * Returns the number of message that are in the buffer.
+  */
+int osrf_message_from_xml( char* xml, osrf_message* msgs[] );
+
+void osrf_message_set_params( osrf_message* msg, jsonObject* o );
+void osrf_message_set_method( osrf_message* msg, char* method_name );
+void osrf_message_add_object_param( osrf_message* msg, jsonObject* o );
+void osrf_message_add_param( osrf_message*, char* param_string );
+
+
+jsonObject* osrfMessageGetResult( osrfMessage* msg );
+
+/**
+  Returns the message as a jsonObject
+  @return The jsonObject which must be freed by the caller.
+  */
+jsonObject* osrfMessageToJSON( osrfMessage* msg );
+
+char* osrfMessageSerializeBatch( osrfMessage* msgs [], int count );
+
+
+#endif
diff --git a/include/opensrf/osrf_prefork.h b/include/opensrf/osrf_prefork.h
new file mode 100644 (file)
index 0000000..543343c
--- /dev/null
@@ -0,0 +1,96 @@
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/select.h>
+#include <sys/wait.h>
+
+#include <opensrf/utils.h>
+#include <opensrf/transport_message.h>
+#include <opensrf/transport_client.h>
+#include <opensrf/osrf_stack.h>
+#include <opensrf/osrf_settings.h>
+#include <opensrf/osrfConfig.h>
+
+//#define READ_BUFSIZE 4096
+#define READ_BUFSIZE 1024
+#define MAX_BUFSIZE 10485760 /* 10M enough? ;) */
+#define ABS_MAX_CHILDREN 256 
+
+/* we receive data.  we find the next child in
+       line that is available.  pass the data down that childs pipe and go
+       back to listening for more data.
+       when we receive SIGCHLD, we check for any dead children and clean up
+       their respective prefork_child objects, close pipes, etc.
+
+       we build a select fd_set with all the child pipes (going to the parent) 
+       when a child is done processing a request, it writes a small chunk of 
+       data to the parent to alert the parent that the child is again available 
+       */
+
+struct prefork_simple_struct {
+       int max_requests;
+       int min_children;
+       int max_children;
+       int fd;
+       int data_to_child;
+       int data_to_parent;
+       int current_num_children;
+       int keepalive; /* keepalive time for stateful sessions */
+       char* appname;
+       struct prefork_child_struct* first_child;
+       transport_client* connection;
+};
+typedef struct prefork_simple_struct prefork_simple;
+
+struct prefork_child_struct {
+       pid_t pid;
+       int read_data_fd;
+       int write_data_fd;
+       int read_status_fd;
+       int write_status_fd;
+       int min_children;
+       int available;
+       int max_requests;
+       char* appname;
+       int keepalive;
+       struct prefork_child_struct* next;
+};
+
+typedef struct prefork_child_struct prefork_child;
+
+int osrf_prefork_run(char* appname);
+
+prefork_simple*  prefork_simple_init( transport_client* client, 
+       int max_requests, int min_children, int max_children );
+
+prefork_child*  launch_child( prefork_simple* forker );
+void prefork_launch_children( prefork_simple* forker );
+
+void prefork_run(prefork_simple* forker);
+
+void add_prefork_child( prefork_simple* forker, prefork_child* child );
+prefork_child* find_prefork_child( prefork_simple* forker, pid_t pid );
+void del_prefork_child( prefork_simple* forker, pid_t pid );
+
+void check_children( prefork_simple* forker, int forever );
+
+void prefork_child_process_request(prefork_child*, char* data);
+int prefork_child_init_hook(prefork_child*);
+
+prefork_child* prefork_child_init( 
+               int max_requests, int read_data_fd, int write_data_fd, 
+               int read_status_fd, int write_status_fd );
+
+/* listens on the 'data_to_child' fd and wait for incoming data */
+void prefork_child_wait( prefork_child* child );
+
+int prefork_free( prefork_simple* );
+int prefork_child_free( prefork_child* );
+
+
+void osrf_prefork_register_routers( char* appname );
+
+void osrf_prefork_child_exit( prefork_child* );
diff --git a/include/opensrf/osrf_settings.h b/include/opensrf/osrf_settings.h
new file mode 100644 (file)
index 0000000..9aa0d47
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef OSRF_SETTINGS_H
+#define OSRF_SETTINGS_H
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdarg.h>
+
+#include <opensrf/log.h>
+#include <opensrf/utils.h>
+#include <opensrf/osrf_app_session.h>
+
+#include <objson/object.h>
+#include <objson/json_parser.h>
+
+typedef struct { 
+       char* hostname; 
+       jsonObject* config; 
+} osrf_host_config;
+
+
+osrf_host_config* osrf_settings_new_host_config(char* hostname);
+void osrf_settings_free_host_config(osrf_host_config*);
+char* osrf_settings_host_value(char* path, ...);
+jsonObject* osrf_settings_host_value_object(char* format, ...);
+int osrf_settings_retrieve(char* hostname);
+
+#endif
+
diff --git a/include/opensrf/osrf_stack.h b/include/opensrf/osrf_stack.h
new file mode 100644 (file)
index 0000000..da2db3d
--- /dev/null
@@ -0,0 +1,19 @@
+#include <opensrf/transport_client.h>
+#include <opensrf/osrf_message.h>
+#include <opensrf/osrf_app_session.h>
+
+#ifndef OSRF_STACK_H
+#define OSRF_STACK_H
+
+/* the max number of oilsMessage blobs present in any one root packet */
+#define OSRF_MAX_MSGS_PER_PACKET 256
+// -----------------------------------------------------------------------------
+
+int osrf_stack_process( transport_client* client, int timeout, int* msg_received );
+osrfAppSession*  osrf_stack_transport_handler( transport_message* msg, char* my_service );
+int osrf_stack_message_handler( osrf_app_session* session, osrf_message* msg );
+int osrf_stack_application_handler( osrf_app_session* session, osrf_message* msg );
+
+
+
+#endif
diff --git a/include/opensrf/osrf_system.h b/include/opensrf/osrf_system.h
new file mode 100644 (file)
index 0000000..540e8d1
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef OSRF_SYSTEM_H
+#define OSRF_SYSTEM_H
+
+#include <opensrf/transport_client.h>
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
+#include <opensrf/osrf_settings.h>
+#include <opensrf/osrfConfig.h>
+#include <opensrf/osrf_cache.h>
+
+
+
+/** Connects to jabber.  Returns 1 on success, 0 on failure 
+       contextnode is the location in the config file where we collect config info
+*/
+
+
+int osrf_system_bootstrap_client( char* config_file, char* contextnode );
+
+/* bootstraps a client adding the given resource string to the host/pid, etc. resource string */
+/**
+  Sets up the global connection.
+  @param configFile The OpenSRF bootstrap config file
+  @param contextNode The location in the config file where we'll find the necessary info
+  @param resource The login resource.  If NULL a default will be created
+  @return 1 on successs, 0 on failure.
+  */
+int osrfSystemBootstrapClientResc( char* configFile, char* contextNode, char* resource );
+int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, char* resource );
+
+/**
+  Bootstrap the server.
+  @param hostname The name of this host.  This is the name that will be used to 
+       load the settings.
+  @param configfile The OpenSRF bootstrap config file
+  @param contextnode The config context
+  @return 0 on success, -1 on error
+  */
+int osrfSystemBootstrap( char* hostName, char* configfile, char* contextNode );
+
+transport_client* osrfSystemGetTransportClient( void );
+transport_client* osrf_system_get_transport_client( void );
+
+/* disconnects and destroys the current client connection */
+int osrf_system_disconnect_client();
+int osrf_system_shutdown( void ); 
+
+
+/* this will clear the global transport client pointer without
+ * actually destroying the socket.  this is useful for allowing
+ * children to have their own socket, even though their parent
+ * already created a socket
+ */
+void osrfSystemIgnoreTransportClient();
+
+
+#endif
diff --git a/include/opensrf/osrf_transgroup.h b/include/opensrf/osrf_transgroup.h
new file mode 100644 (file)
index 0000000..9788d93
--- /dev/null
@@ -0,0 +1,122 @@
+#include <opensrf/transport_client.h>
+#include <opensrf/transport_message.h>
+#include <opensrf/osrf_list.h>
+#include <opensrf/osrf_hash.h>
+#include <opensrf/osrfConfig.h>
+#include <opensrf/utils.h>
+#include <time.h>
+
+/**
+  Maintains a set of transport clients 
+  */
+
+struct __osrfTransportGroupStruct {
+       osrfHash* nodes;                                                /* our hash of nodes keyed by domain */
+       osrfHashIterator* itr;                          /* points to the next node in the list */
+};
+typedef struct __osrfTransportGroupStruct osrfTransportGroup;
+
+
+struct __osrfTransportGroupNode {
+       transport_client* connection;           /* our connection to the network */
+       char* domain;                                                   /* the domain we're connected to */
+       char* username;                                         /* username used to connect to the group of servers */
+       char* password;                                         /* password used to connect to the group of servers */
+       char* resource;                                         /* the login resource */
+       int port;                                                               /* port used to connect to the group of servers */
+
+       int active;                                                             /* true if we're able to send data on this connection */
+       time_t lastsent;                                                /* the last time we sent a message */
+};
+typedef struct __osrfTransportGroupNode osrfTransportGroupNode;
+
+
+/**
+  Creates a new group node
+  @param domain The domain we're connecting to
+  @param port The port to connect on
+  @param username The login name
+  @param password The login password
+  @param resource The login resource
+  @return A new transport group node
+  */
+osrfTransportGroupNode* osrfNewTransportGroupNode( 
+               char* domain, int port, char* username, char* password, char* resource );
+
+
+/**
+  Allocates and initializes a new transport group.
+  The first node in the array is the default node for client connections.
+  @param nodes The nodes in the group.
+  */
+osrfTransportGroup* osrfNewTransportGroup( osrfTransportGroupNode* nodes[], int count );
+
+/**
+  Attempts to connect all of the nodes in this group.
+  @param grp The transport group
+  @return The number of nodes successfully connected
+  */
+int osrfTransportGroupConnectAll( osrfTransportGroup* grp );
+
+void osrfTransportGroupDisconnectAll( osrfTransportGroup* grp );
+
+
+/**
+  Sends a transport message by going to the next domain in the set.
+  if we have a connection for the recipient domain, then we consider it to be
+  a 'local' message.  Local messages have their recipient domains re-written to
+  match the domain of the next server in the set and they are sent directly to 
+  that server.  If we do not have a connection for the recipient domain, it is 
+  considered a 'remote' message and the message is sent directly (unchanged)
+  to the next connection in the set.
+
+  @param grp The transport group
+  @param msg The message to send 
+  @return 0 on normal successful send.  
+  Returns -1 if the message cannot be sent.  
+  */
+int osrfTransportGroupSend( osrfTransportGroup* grp, transport_message* msg );
+
+/**
+  Sends the message to the exact recipient.  No failover is attempted.
+  @return 0 on success, -1 on error.
+  */
+int osrfTransportGroupSendMatch( osrfTransportGroup* grp, transport_message* msg );
+
+
+int _osrfTGServerSend( osrfTransportGroup* grp, char* domain, transport_message* msg );
+int _osrfTGClientSend( osrfTransportGroup* grp, char* domain, transport_message* msg );
+
+/**
+  Waits on all connections for inbound data.
+  @param grp The transport group
+  @param timeout How long to wait for data.  0 means check for data
+  but don't wait, a negative number means to wait indefinitely
+  @return The received message or NULL if the timeout occurred before a 
+  message was received 
+ */
+transport_message* osrfTransportGroupRecvAll( osrfTransportGroup* grp, int timeout );
+
+/**
+  Waits for data from a single domain
+  @param grp The transport group
+  @param domain The domain to wait for data on
+  @param timeout see osrfTransportGroupRecvAll
+  */
+transport_message* osrfTransportGroupRecv( osrfTransportGroup* grp, char* domain, int timeout );
+
+/**
+  Tells the group that a message to the given domain failed
+  domain did not make it through;
+  @param grp The transport group
+  @param comain The failed domain
+  */
+void osrfTransportGroupSetInactive( osrfTransportGroup* grp, char* domain );
+
+
+/**
+  Finds a node in our list of nodes 
+  */
+osrfTransportGroupNode* __osrfTransportGroupFindNode( osrfTransportGroup* grp, char* domain );
+
+
diff --git a/include/opensrf/sha.h b/include/opensrf/sha.h
new file mode 100644 (file)
index 0000000..6c3d2d4
--- /dev/null
@@ -0,0 +1,41 @@
+// sha.h
+// Jabber client library
+//
+// Original Code Copyright (C) 1999-2001 Dave Smith (dave@jabber.org)
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// 
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+//
+// Contributor(s): Julian Missig
+//
+// This Original Code has been modified by IBM Corporation. Modifications 
+// made by IBM described herein are Copyright (c) International Business 
+// Machines Corporation, 2002.
+//
+// Date             Modified by     Description of modification
+// 01/20/2002       IBM Corp.       Updated to libjudo 1.1.1
+// 2002-03-05       IBM Corp.       Updated to libjudo 1.1.5
+// 2002-07-09       IBM Corp.       Added Roster::getSession()
+//
+// =====================================================================================
+
+
+//#ifdef WIN32
+     char* shahash(const char* str);
+//#else
+//extern "C" {
+//     char* shahash(const char* str);
+//}
+//#endif
+
diff --git a/include/opensrf/socket_bundle.h b/include/opensrf/socket_bundle.h
new file mode 100644 (file)
index 0000000..f290cdc
--- /dev/null
@@ -0,0 +1,111 @@
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <errno.h>
+
+
+//---------------------------------------------------------------
+// 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>
+#include <netinet/tcp.h>
+#include <sys/un.h>
+
+#include <signal.h>
+
+#ifndef SOCKET_BUNDLE_H
+#define SOCKET_BUNDLE_H
+
+
+#define SERVER_SOCKET                  1
+#define CLIENT_SOCKET                  2
+
+#define INET 10 
+#define UNIX 11 
+
+
+/* models a single socket connection */
+struct socket_node_struct {
+       int endpoint;           /* SERVER_SOCKET or CLIENT_SOCKET */
+       int addr_type;          /* INET or UNIX */
+       int sock_fd;
+       int parent_id;          /* if we're a new client for a server socket, 
+                                                               this points to the server socket we spawned from */
+       struct socket_node_struct* next;
+};
+typedef struct socket_node_struct socket_node;
+
+
+/* Maintains the socket set */
+struct socket_manager_struct {
+       /* callback for passing up any received data.  sock_fd is the socket
+               that read the data.  parent_id (if > 0) is the socket id of the 
+               server that this socket spawned from (i.e. it's a new client connection) */
+       void (*data_received) 
+               (void* blob, struct socket_manager_struct*, 
+                int sock_fd, char* data, int parent_id);
+
+       void (*on_socket_closed) (void* blob, int sock_fd);
+
+       socket_node* socket;
+       void* blob;
+};
+typedef struct socket_manager_struct socket_manager;
+
+void socket_manager_free(socket_manager* mgr);
+
+/* creates a new server socket node and adds it to the socket set.
+       returns socket id on success.  -1 on failure.
+       socket_type is one of INET or UNIX  */
+int socket_open_tcp_server(socket_manager*, int port, char* listen_ip );
+
+int socket_open_unix_server(socket_manager* mgr, char* path);
+
+int socket_open_udp_server( socket_manager* mgr, int port, char* listen_ip );
+
+/* creates a client TCP socket and adds it to the socket set.
+       returns 0 on success.  -1 on failure.  */
+int socket_open_tcp_client(socket_manager*, int port, char* dest_addr);
+
+/* creates a client UNIX socket and adds it to the socket set.
+       returns 0 on success.  -1 on failure.  */
+int socket_open_unix_client(socket_manager*, char* sock_path);
+
+int socket_open_udp_client( socket_manager* mgr, int port, char* dest_addr);
+
+/* sends the given data to the given socket. returns 0 on success, -1 otherwise */
+int socket_send(int sock_fd, const char* data);
+
+/* waits at most usecs microseconds for the socket buffer to
+ * be available */
+int socket_send_timeout( int sock_fd, const char* data, int usecs );
+
+/* disconnects the node with the given sock_fd and removes
+       it from the socket set */
+void socket_disconnect(socket_manager*, int sock_fd);
+
+/* XXX This only works if 'sock_fd' is a client socket... */
+int socket_wait(socket_manager* mgr, int timeout, int sock_fd);
+
+/* waits on all sockets for incoming data.  
+       timeout == -1   | block indefinitely
+       timeout == 0    | don't block, just read any available data off all sockets
+       timeout == x    | block for at most x seconds */
+int socket_wait_all(socket_manager* mgr, int timeout);
+
+/* utility function for displaying the currently attached sockets */
+void _socket_print_list(socket_manager* mgr);
+
+int socket_connected(int sock_fd);
+
+#endif
diff --git a/include/opensrf/string_array.h b/include/opensrf/string_array.h
new file mode 100644 (file)
index 0000000..77b3de0
--- /dev/null
@@ -0,0 +1,41 @@
+#include <stdio.h>
+
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
+
+#define STRING_ARRAY_MAX_SIZE 1024
+
+#ifndef STRING_ARRAY_H
+#define STRING_ARRAY_H
+
+struct string_array_struct {
+               char** array;   
+               int size;
+               int arr_size;
+               int total_string_size;
+};
+typedef struct string_array_struct string_array;
+typedef struct string_array_struct osrfStringArray;
+
+osrfStringArray* init_string_array(int size);
+osrfStringArray* osrfNewStringArray(int size);
+
+void string_array_add(osrfStringArray*, char* string);
+void osrfStringArrayAdd(osrfStringArray*, char* string);
+
+char* string_array_get_string(osrfStringArray* arr, int index);
+char* osrfStringArrayGetString(osrfStringArray* arr, int index);
+
+/* returns true if this array contains the given string */
+int osrfStringArrayContains( osrfStringArray* arr, char* string );
+
+
+void string_array_destroy(osrfStringArray*);
+void osrfStringArrayFree(osrfStringArray*);
+
+/* total size of all included strings */
+int string_array_get_total_size(osrfStringArray* arr);
+
+void osrfStringArrayRemove( osrfStringArray* arr, char* str);
+
+#endif
diff --git a/include/opensrf/transport_client.h b/include/opensrf/transport_client.h
new file mode 100644 (file)
index 0000000..e61f840
--- /dev/null
@@ -0,0 +1,92 @@
+#include <opensrf/transport_session.h>
+#include <opensrf/utils.h>
+#include <opensrf/log.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;
+       int error;
+};
+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.
+// if port > 0 => connect via TCP
+// else if unix_path != NULL => connect via UNIX socket
+// ---------------------------------------------------------------------------
+transport_client* client_init( const char* server, int port, const char* unix_path, 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
diff --git a/include/opensrf/transport_message.h b/include/opensrf/transport_message.h
new file mode 100644 (file)
index 0000000..ddd8f39
--- /dev/null
@@ -0,0 +1,99 @@
+#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>
+
+#include <opensrf/utils.h>
+#include <opensrf/xml_utils.h>
+#include <opensrf/log.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;
+   char* osrf_xid;
+       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 );
+
+void message_set_osrf_xid( transport_message* msg, char* osrf_xid );
+
+// ---------------------------------------------------------------------------------
+// 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[], int size );
+
+// ---------------------------------------------------------------------------------
+// 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[], int size );
+
+/** Puts the domain portion of the given jid into the pre-allocated buffer */
+void jid_get_domain( const char* jid, char buf[], int size );
+
+void set_msg_error( transport_message*, char* error_type, int error_code);
+
+
+#endif
diff --git a/include/opensrf/transport_session.h b/include/opensrf/transport_session.h
new file mode 100644 (file)
index 0000000..5aa8597
--- /dev/null
@@ -0,0 +1,234 @@
+// ---------------------------------------------------------------------------------
+// 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 <opensrf/transport_message.h>
+
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
+#include <opensrf/socket_bundle.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 );
+void grab_incoming(void* blob, socket_manager* mgr, int sockid, char* data, int parent);
+
+// ---------------------------------------------------------------------------------
+// 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;
+       socket_manager* sock_mgr;
+
+       /* 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;
+       growing_buffer* osrf_xid_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;
+
+       char* server;
+       char* unix_path;
+       int     port;
+       int sock_id;
+
+       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.
+// If port > 0, then this session uses  TCP connection.  Otherwise,
+// if unix_path != NULL, it uses a UNIX domain socket.
+// ------------------------------------------------------------------
+transport_session* init_transport( const char* server, int port, 
+       const char* unix_path, 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
diff --git a/include/opensrf/utils.h b/include/opensrf/utils.h
new file mode 100644 (file)
index 0000000..7bbade0
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+Mike Rylander <mrylander@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+//#include <sys/timeb.h>
+
+#include "md5.h"
+
+#define OSRF_MALLOC(ptr, size) \
+       do {\
+               ptr = (void*) malloc( size ); \
+               if( ptr == NULL ) { \
+                       perror("OSRF_MALLOC(): Out of Memory" );\
+                       exit(99); \
+               } \
+               memset( ptr, 0, size );\
+       } while(0)
+
+
+#define OSRF_BUFFER_ADD(gb, data) \
+       do {\
+               int __tl; \
+               if(gb && data) {\
+                       __tl = strlen(data) + gb->n_used;\
+                       if( __tl < gb->size ) {\
+                               strcat(gb->buf, data);\
+                               gb->n_used = __tl; \
+                       } else { buffer_add(gb, data); }\
+               }\
+       } while(0)
+
+#define OSRF_BUFFER_ADD_CHAR(gb, c)\
+       do {\
+               if(gb) {\
+                       if(gb->n_used < gb->size - 1)\
+                               gb->buf[gb->n_used++] = c;\
+                       else\
+                               buffer_add_char(gb, c);\
+               }\
+       }while(0)
+
+       
+
+
+/* turns a va_list into a string */
+#define VA_LIST_TO_STRING(x) \
+       unsigned long __len = 0;\
+       va_list args; \
+       va_list a_copy;\
+       va_copy(a_copy, args); \
+       va_start(args, x); \
+       __len = vsnprintf(NULL, 0, x, args); \
+       va_end(args); \
+       __len += 2; \
+       char _b[__len]; \
+       bzero(_b, __len); \
+       va_start(a_copy, x); \
+       vsnprintf(_b, __len - 1, x, a_copy); \
+       va_end(a_copy); \
+       char* VA_BUF = _b; \
+
+/* turns a long into a string */
+#define LONG_TO_STRING(l) \
+       unsigned int __len = snprintf(NULL, 0, "%ld", l) + 2;\
+       char __b[__len]; \
+       bzero(__b, __len); \
+       snprintf(__b, __len - 1, "%ld", l); \
+       char* LONGSTR = __b;
+
+#define DOUBLE_TO_STRING(l) \
+       unsigned int __len = snprintf(NULL, 0, "%f", l) + 2; \
+       char __b[__len]; \
+       bzero(__b, __len); \
+       snprintf(__b, __len - 1, "%f", l); \
+       char* DOUBLESTR = __b;
+
+#define LONG_DOUBLE_TO_STRING(l) \
+       unsigned int __len = snprintf(NULL, 0, "%Lf", l) + 2; \
+       char __b[__len]; \
+       bzero(__b, __len); \
+       snprintf(__b, __len - 1, "%Lf", l); \
+       char* LONGDOUBLESTR = __b;
+
+
+#define INT_TO_STRING(l) \
+       unsigned int __len = snprintf(NULL, 0, "%d", l) + 2; \
+       char __b[__len]; \
+       bzero(__b, __len); \
+       snprintf(__b, __len - 1, "%d", l); \
+       char* INTSTR = __b;
+
+
+/*
+#define MD5SUM(s) \
+       struct md5_ctx ctx; \
+       unsigned char digest[16];\
+       MD5_start (&ctx);\
+       int i;\
+       for ( i=0 ; i != strlen(text) ; i++ ) MD5_feed (&ctx, text[i]);\
+       MD5_stop (&ctx, digest);\
+       char buf[16];\
+       memset(buf,0,16);\
+       char final[256];\
+       memset(final,0,256);\
+       for ( i=0 ; i<16 ; i++ ) {\
+               sprintf(buf, "%02x", digest[i]);\
+               strcat( final, buf );\
+       }\
+       char* MD5STR = final;
+       */
+
+
+       
+
+
+#define BUFFER_MAX_SIZE 10485760 
+
+/* these are evil and should be condemned 
+       ! Only use these if you are done with argv[].
+       call init_proc_title() first, then call
+       set_proc_title. 
+       the title is only allowed to be as big as the
+       initial process name of the process (full size of argv[]).
+       truncation may occurr.
+ */
+int init_proc_title( int argc, char* argv[] );
+int set_proc_title( char* format, ... );
+
+
+int daemonize();
+
+void* safe_malloc(int size);
+
+// ---------------------------------------------------------------------------------
+// Generic growing buffer. Add data all you want
+// ---------------------------------------------------------------------------------
+struct growing_buffer_struct {
+       char *buf;
+       int n_used;
+       int size;
+};
+typedef struct growing_buffer_struct growing_buffer;
+
+growing_buffer* buffer_init( int initial_num_bytes);
+
+// XXX This isn't defined in utils.c!! removing for now...
+//int buffer_addchar(growing_buffer* gb, char c);
+
+int buffer_add(growing_buffer* gb, char* c);
+int buffer_fadd(growing_buffer* gb, const char* format, ... );
+int buffer_reset( growing_buffer* gb);
+char* buffer_data( growing_buffer* gb);
+char* buffer_release( growing_buffer* gb );
+int buffer_free( growing_buffer* gb );
+int buffer_add_char(growing_buffer* gb, char c);
+
+/* returns the size needed to fill in the vsnprintf buffer.  
+       * ! this calls va_end on the va_list argument*
+       */
+long va_list_size(const char* format, va_list);
+
+/* turns a va list into a string, caller must free the 
+       allocated char */
+char* va_list_to_string(const char* format, ...);
+
+
+/* string escape utility method.  escapes unicode embeded characters.
+       escapes the usual \n, \t, etc. 
+       for example, if you provide a string like so:
+
+       hello,
+               you
+
+       you would get back:
+       hello,\n\tyou
+ */
+char* uescape( const char* string, int size, int full_escape );
+
+/* utility methods */
+int set_fl( int fd, int flags );
+int clr_fl( int fd, int flags );
+
+
+
+// Utility method
+double get_timestamp_millis();
+
+
+/* returns true if the whole string is a number */
+int stringisnum(char* s);
+
+/* reads a file and returns the string version of the file
+       user is responsible for freeing the returned char*
+       */
+char* file_to_string(const char* filename);
+
+
+
+/** 
+  Calculates the md5 of the text provided.
+  The returned string must be freed by the caller.
+  */
+char* md5sum( char* text, ... );
+
+
+/**
+  Checks the validity of the file descriptor
+  returns -1 if the file descriptor is invalid
+  returns 0 if the descriptor is OK
+  */
+int osrfUtilsCheckFileDescriptor( int fd );
+
+#endif
diff --git a/include/opensrf/xml_utils.h b/include/opensrf/xml_utils.h
new file mode 100644 (file)
index 0000000..2b3a030
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef _XML_UTILS_H
+#define _XML_UTILS_H
+
+#include <objson/object.h>
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+jsonObject* xmlDocToJSON(xmlDocPtr doc);
+
+/* helper function */
+jsonObject* _xmlToJSON(xmlNodePtr node, jsonObject*);
+
+/* debug function, prints each node and content */
+void recurse_doc( xmlNodePtr node );
+
+
+/* turns an XML doc into a char*.  
+       User is responsible for freeing the returned char*
+       if(full), then we return the whole doc (xml declaration, etc.)
+       else we return the doc from the root node down
+       */
+char* xmlDocToString(xmlDocPtr doc, int full);
+
+
+/* Takes an xmlChar** from a SAX callback and returns the value
+       for the attribute with name 'name'
+       */
+char* xmlSaxAttr( const xmlChar** atts, char* name ); 
+
+/**
+  Sets the xml attributes from atts to the given dom node 
+ */
+int xmlAddAttrs( xmlNodePtr node, const xmlChar** atts );
+
+
+#endif
index 4ff75c2..0cf5657 100644 (file)
@@ -9,62 +9,12 @@ export PERLDIR                        = $(LIBDIR)/perl5
 export INCLUDEDIR              = $(PREFIX)/include
 
 export LDLIBS                  += 
-export LDFLAGS                 += -Wl,-rpath=$(LIBDIR) -L $(TMPDIR) -L . -L /opt/lib
-export CFLAGS                  += -pipe -g -Wall -O2 -fPIC -I$(LIBXML2_HEADERS) -I$(APACHE2_HEADERS) \
-                                                               -I$(LIBXML2_HEADERS)/libxml  -I$(TMP) \
-                                                               -I$(APR_HEADERS) -I$(TMPDIR)
-
-LIBOPENSRF                             = libopensrf.so
-
-OPENSRF_TARGETS =      libtransport/transport_session.o \
-                       libtransport/transport_client.o \
-                       libtransport/transport_message.o \
-                       libstack/osrf_app_session.o \
-                       libstack/osrf_stack.o \
-                       libstack/osrfConfig.o \
-                       libstack/osrf_settings.o \
-                       libstack/osrf_message.o \
-                       libstack/osrf_prefork.o \
-                       libstack/osrf_system.o \
-                       libstack/osrf_application.o \
-                       libstack/osrf_cache.o \
-                       libstack/xml_utils.o \
-                       libstack/osrf_transgroup.o \
-                       libstack/osrf_list.o \
-                       libstack/osrf_hash.o \
-                       utils/socket_bundle.o \
-                       utils/string_array.o \
-                       utils/utils.o \
-                       utils/log.o \
-                       utils/md5.o \
-                       utils/sha.o 
-
-OPENSRF_HEADERS =      libtransport/transport_session.h \
-                       libtransport/transport_client.h \
-                       libtransport/transport_message.h \
-                       libstack/osrf_app_session.h \
-                       libstack/osrf_stack.h \
-                       libstack/osrfConfig.h \
-                       libstack/osrf_settings.h \
-                       libstack/osrf_message.h \
-                       libstack/osrf_prefork.h \
-                       libstack/osrf_system.h \
-                       libstack/osrf_application.h \
-                       libstack/osrf_cache.h \
-                       libstack/xml_utils.h \
-                       libstack/osrf_transgroup.h \
-                       libstack/osrf_list.h \
-                       libstack/osrf_hash.h \
-                       utils/socket_bundle.h \
-                       utils/string_array.h \
-                       utils/utils.h \
-                       utils/log.h \
-                       utils/md5.h \
-                       utils/sha.h 
+export LDFLAGS                 += -Wl,-rpath=$(LIBDIR) -L $(TMPDIR) -L .
+export CFLAGS                  += -pipe -g -Wall -O2 -fPIC -I ../../include/ -I$(LIBXML2_HEADERS) -I$(APACHE2_HEADERS) \
+                                                               -I$(LIBXML2_HEADERS)/libxml -I$(APR_HEADERS) 
 
 all:   prep \
-       libopensrf.so \
-       libstack/opensrf \
+       opensrf \
        router \
        srfsh \
        jserver \
@@ -79,56 +29,35 @@ install:    install-prep \
                perl-install \
                objson-install
 
-prep:
-       mkdir -p $(TMPDIR)
-
-libopensrf.so: objson/libobjson.so
-       @echo utils
-       make -C utils
-       @echo transport
-       make -C libtransport
-       @echo stack
-       make -C libstack
-       @echo $@
-       $(CC) -shared -W1 $(LDFLAGS) -lxml2 -lmemcache -lobjson $(OPENSRF_TARGETS) -o $(TMPDIR)/$(LIBOPENSRF)
-       @echo apps
-       make -C  c-apps
 
+# --------------------------------------------------------------------------------
+# BINARIES and LIBS
+# --------------------------------------------------------------------------------
 
-opensrf-install:       objson-install
-       @echo $@
-       cp $(TMPDIR)/$(LIBOPENSRF) $(LIBDIR)/$(LIBOPENSRF)
-       cp $(OPENSRF_HEADERS) $(INCLUDEDIR)/opensrf/
-       cp libstack/opensrf $(BINDIR)/opensrf-c
-       make -C c-apps install
-
+prep:
+       mkdir -p $(TMPDIR)
 
 objson/libobjson.so:   prep
        @echo $@
        make -C objson
 
-# --------------------------------------------------------------------------------
-# BINARIES
-# --------------------------------------------------------------------------------
-libstack/opensrf.o:    libstack/opensrf.c libopensrf.so
-libstack/opensrf:      libstack/opensrf.o
-       @echo $@
-       $(CC) $(CFLAGS) $(LDFLAGS) -lxml2 -lopensrf -lobjson libstack/opensrf.o -o $@
-       
+opensrf:       objson/libobjson.so
+       make -C libopensrf
+       make -C c-apps
 
-router: libopensrf.so
+router: opensrf
        @echo $@
        make -C router 
 
-srfsh: libopensrf.so
+srfsh: opensrf
        @echo $@
        make -C srfsh
 
-gateway:       libopensrf.so
+gateway:       opensrf
        @echo $@
        make -C gateway
 
-jserver:       libopensrf.so
+jserver:       opensrf
        @echo $@
        make -C jserver
 
@@ -136,22 +65,32 @@ jserver:   libopensrf.so
 # --------------------------------------------------------------------------------
 # INSTALL
 # --------------------------------------------------------------------------------
+
+# make sure the install directories exist
 install-prep:  
        @echo $@
        mkdir -p $(LIBDIR)
        mkdir -p $(BINDIR)
        mkdir -p $(PERLDIR)
        mkdir -p $(INCLUDEDIR)
-       mkdir -p $(INCLUDEDIR)/$(OPENSRF)
        mkdir -p $(ETCDIR)
 
 objson-install:        install-prep 
        @echo $@
        make -C objson install
 
-libopensrf-install:    install-prep
+# installs libopensrf.so, opensrf-c, headers, example configs, and osrf_ctl.sh
+opensrf-install:       objson-install
        @echo $@
-       cp $(TMPDIR)/$(LIBOPENSRF) $(LIBDIR)
+       cp $(TMPDIR)/libopensrf.so $(LIBDIR)/libopensrf.so
+       cp -r ../include/opensrf $(INCLUDEDIR)
+       cp libopensrf/opensrf $(BINDIR)/opensrf-c
+       make -C c-apps install
+       cp ../examples/bootstrap.conf.example $(ETCDIR)
+       cp ../bin/osrf_ctl.sh $(BINDIR)
+       cp ../examples/opensrf.xml.example $(ETCDIR)
+       cp ../examples/opensrf_core.xml.example $(ETCDIR)
+       cp ../examples/srfsh.xml.example $(ETCDIR)
 
 gateway-install:       install-prep opensrf-install    
        @echo $@
@@ -172,28 +111,19 @@ jserver-install:  install-prep
 perl-install:  install-prep
        @echo $@
        cp -r perlmods/* $(PERLDIR)/
-       cp ../examples/bootstrap.conf.example $(ETCDIR)
-       cp ../bin/osrf_ctl.sh $(BINDIR)
-       cp ../examples/opensrf.xml.example $(ETCDIR)
-       cp ../examples/opensrf_core.xml.example $(ETCDIR)
-       cp ../examples/srfsh.xml.example $(ETCDIR)
 
 
 # --------------------------------------------------------------------------------
 # CLEAN        
 # --------------------------------------------------------------------------------
 clean:
-       @echo $@
-       make -C libtransport clean
-       make -C libstack clean
+       make -C libopensrf clean
        make -C router clean
        make -C gateway clean
        make -C jserver clean
-       make -C utils clean
        make -C objson clean
        make -C srfsh clean
        make -C c-apps clean
-       echo "Removing directory [$(TMPDIR)]"
        /bin/rm -rf $(TMPDIR) *.o
 
 
diff --git a/src/libopensrf/basic_client.c b/src/libopensrf/basic_client.c
new file mode 100644 (file)
index 0000000..5cf8f76
--- /dev/null
@@ -0,0 +1,81 @@
+#include <opensrf/transport_client.h>
+#include "signal.h"
+
+pid_t pid;
+void sig_int( int sig ) {
+       fprintf(stderr, "Killing child %d\n", pid );
+       kill( pid, SIGKILL );
+}
+
+/* connects and registers with the router */
+int main( int argc, char** argv ) {
+
+       if( argc < 5 ) {
+               osrfLogError( OSRF_LOG_MARK, "Usage: %s <username> <host> <resource> <recipient> \n", argv[0] );
+               return 99;
+       }
+
+       transport_message* send;
+       transport_client* client = client_init( argv[2], 5222, 0 );
+
+       // try to connect, allow 15 second connect timeout 
+       if( client_connect( client, argv[1], "jkjkasdf", argv[3], 15, AUTH_DIGEST ) ) 
+               osrfLogInfo(OSRF_LOG_MARK, "Connected...\n");
+        else { 
+               osrfLogError( OSRF_LOG_MARK, "NOT Connected...\n" ); 
+               return -1;
+        }
+       
+       if( (pid=fork()) ) { /* parent */
+
+               signal(SIGINT, sig_int);
+               fprintf(stderr, "Listener: %ld\n", (long) getpid() );   
+               char buf[300];
+               memset(buf, 0, 300);
+               printf("=> ");
+
+               while( fgets( buf, 299, stdin) ) {
+
+                       // remove newline
+                       buf[strlen(buf)-1] = '\0';
+
+                       if( strcmp(buf, "exit")==0) { 
+                               client_free( client );  
+                               break; 
+                       }
+
+                       send = message_init( buf, "", "123454321", argv[4], NULL );
+                       client_send_message( client, send );
+                       message_free( send );
+                       printf("\n=> ");
+                       memset(buf, 0, 300);
+               }
+               fprintf(stderr, "Killing child %d\n", pid );
+               kill( pid, SIGKILL );
+               return 0;
+
+       } else {
+
+               fprintf(stderr, "Sender: %ld\n", (long) getpid() );     
+
+               transport_message* recv;
+               while( (recv=client_recv( client, -1)) ) {
+                       if( recv->is_error )
+                               fprintf( stderr, "\nReceived Error\t: ------------------\nFrom:\t\t"
+                                       "%s\nRouterFrom:\t%s\nBody:\t\t%s\nType %s\nCode %d\n=> ", 
+                                       recv->sender, recv->router_from, recv->body, recv->error_type, recv->error_code );
+                       else
+                               fprintf( stderr, "\nReceived\t: ------------------\nFrom:\t\t"
+                                       "%s\nRouterFrom:\t%s\nBody:\t\t%s\n=> ", recv->sender, recv->router_from, recv->body );
+
+                       message_free( recv );
+               }
+
+       }
+       return 0;
+
+}
+
+
+
+
diff --git a/src/libopensrf/component.c b/src/libopensrf/component.c
new file mode 100644 (file)
index 0000000..c63dd44
--- /dev/null
@@ -0,0 +1,52 @@
+#include <opensrf/transport_client.h>
+#include "signal.h"
+
+
+/*
+void print_stuff(void* blah, char* data) {
+       fprintf(stderr, "Received from socket: %s\n", data);
+}
+*/
+
+/* connects and registers with the router */
+int main( int argc, char** argv ) {
+
+
+
+       if( argc < 5 ) {
+               osrfLogError(OSRF_LOG_MARK,  "Usage: %s <server> <port> <name> <secret>", argv[0] );
+               return -1;
+       }
+
+       int port = atoi(argv[2]);
+       transport_client* client = client_init( argv[1], port, 1 );
+
+       // try to connect, allow 15 second connect timeout 
+       if( client_connect( client, argv[3], argv[4], "", 15, 1 ) ) 
+               osrfLogInfo(OSRF_LOG_MARK, "Connected...\n");
+        else  {
+               osrfLogError(OSRF_LOG_MARK,  "NOT Connected...\n" ); 
+               return -1;
+        }
+       
+       transport_message* recv;
+       while( (recv=client_recv( client, -1)) ) {
+               if( recv->is_error )
+                       fprintf( stderr, "\nReceived Error\t: ------------------\nFrom:\t\t"
+                               "%s\nRouterFrom:\t%s\nBody:\t\t%s\nType %s\nCode %d\n=> ", 
+                               recv->sender, recv->router_from, recv->body, recv->error_type, recv->error_code );
+               else
+                       fprintf( stderr, "\nReceived\t: ------------------\nFrom:\t\t"
+                               "%s\nRouterFrom:\t%s\nBody:\t\t%s\n=> ", recv->sender, recv->router_from, recv->body );
+               transport_message* send = message_init( "Hello...", "", "123454321", recv->sender, argv[3] );
+               client_send_message( client, send );
+               message_free( recv );
+               message_free( send );
+       }
+       return 0;
+
+}
+
+
+
+
diff --git a/src/libopensrf/log.c b/src/libopensrf/log.c
new file mode 100644 (file)
index 0000000..35d2756
--- /dev/null
@@ -0,0 +1,252 @@
+#include <opensrf/log.h>
+
+static int _osrfLogType                                = -1;
+static int _osrfLogFacility                    = LOG_LOCAL0;
+static int _osrfLogActFacility         = LOG_LOCAL1;
+static char* _osrfLogFile                      = NULL;
+static char* _osrfLogAppname           = NULL;
+static int _osrfLogLevel                       = OSRF_LOG_INFO;
+static int _osrfLogActivityEnabled     = 1;
+static int _osrfLogIsClient         = 0;
+
+static char* _osrfLogXid            = NULL; /* current xid */
+static char* _osrfLogXidPfx         = NULL; /* xid prefix string */
+
+static void osrfLogSetType( int logtype );
+static void _osrfLogDetail( int level, const char* filename, int line, char* msg );
+static void _osrfLogToFile( char* msg, ... );
+static void _osrfLogSetXid(char* xid);
+
+#define OSRF_LOG_GO(f,li,m,l)  \
+        if(!m) return;         \
+        VA_LIST_TO_STRING(m);  \
+        _osrfLogDetail( l, f, li, VA_BUF );
+
+void osrfLogCleanup() {
+       free(_osrfLogAppname);
+       free(_osrfLogFile);
+}
+
+
+void osrfLogInit( int type, const char* appname, int maxlevel ) {
+       osrfLogSetType(type);
+       if(appname) osrfLogSetAppname(appname);
+       osrfLogSetLevel(maxlevel);
+       if( type == OSRF_LOG_TYPE_SYSLOG ) 
+               openlog(_osrfLogAppname, 0, _osrfLogFacility );
+}
+
+static void _osrfLogSetXid(char* xid) {
+   if(xid) {
+      if(_osrfLogXid) free(_osrfLogXid);
+      _osrfLogXid = strdup(xid);
+   }
+}
+
+void osrfLogClearXid() { _osrfLogSetXid(""); }
+void osrfLogSetXid(char* xid) {
+   if(!_osrfLogIsClient) _osrfLogSetXid(xid);
+}
+
+void osrfLogMkXid() {
+   if(_osrfLogIsClient) {
+      static int _osrfLogXidInc = 0; /* increments with each new xid for uniqueness */
+      char buf[32];
+      memset(buf, 0x0, 32);
+      snprintf(buf, 32, "%s%d", _osrfLogXidPfx, _osrfLogXidInc);
+      _osrfLogSetXid(buf);
+      _osrfLogXidInc++;
+   }
+}
+
+char* osrfLogGetXid() {
+   return _osrfLogXid;
+}
+
+void osrfLogSetIsClient(int is) {
+   _osrfLogIsClient = is;
+   if(!is) return;
+   /* go ahead and create the xid prefix so it will be consistent later */
+   static char buff[32];
+   memset(buff, 0x0, 32);
+   snprintf(buff, 32, "%d%ld", (int)time(NULL), (long) getpid());
+   _osrfLogXidPfx = buff;
+}
+
+/** Sets the type of logging to perform.  See log types */
+static void osrfLogSetType( int logtype ) { 
+       if( logtype != OSRF_LOG_TYPE_FILE &&
+                       logtype != OSRF_LOG_TYPE_SYSLOG ) {
+               fprintf(stderr, "Unrecognized log type.  Logging to stderr\n");
+               return;
+       }
+       _osrfLogType = logtype;
+}
+
+void osrfLogSetFile( const char* logfile ) {
+       if(!logfile) return;
+       if(_osrfLogFile) free(_osrfLogFile);
+       _osrfLogFile = strdup(logfile);
+}
+
+void osrfLogSetActivityEnabled( int enabled ) {
+       _osrfLogActivityEnabled = enabled;
+}
+
+void osrfLogSetAppname( const char* appname ) {
+       if(!appname) return;
+       if(_osrfLogAppname) free(_osrfLogAppname);
+       _osrfLogAppname = strdup(appname);
+
+       /* if syslogging, re-open the log with the appname */
+       if( _osrfLogType == OSRF_LOG_TYPE_SYSLOG) {
+               closelog();
+               openlog(_osrfLogAppname, 0, _osrfLogFacility);
+       }
+}
+
+void osrfLogSetSyslogFacility( int facility ) {
+       _osrfLogFacility = facility;
+}
+void osrfLogSetSyslogActFacility( int facility ) {
+       _osrfLogActFacility = facility;
+}
+
+/** Sets the global log level.  Any log statements with a higher level
+ * than "level" will not be logged */
+void osrfLogSetLevel( int loglevel ) {
+       _osrfLogLevel = loglevel;
+}
+
+/** Gets the current global log level. **/
+int osrfLogGetLevel( void ) {
+       return _osrfLogLevel;
+}
+
+void osrfLogError( const char* file, int line, const char* msg, ... ) 
+       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_ERROR); }
+void osrfLogWarning( const char* file, int line, const char* msg, ... ) 
+       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_WARNING); }
+void osrfLogInfo( const char* file, int line, const char* msg, ... ) 
+       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INFO); }
+void osrfLogDebug( const char* file, int line, const char* msg, ... ) 
+       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_DEBUG); }
+void osrfLogInternal( const char* file, int line, const char* msg, ... ) 
+       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INTERNAL); }
+void osrfLogActivity( const char* file, int line, const char* msg, ... ) { 
+       OSRF_LOG_GO(file, line, msg, OSRF_LOG_ACTIVITY); 
+       _osrfLogDetail( OSRF_LOG_INFO, file, line, VA_BUF ); /* also log at info level */
+}
+
+/** Actually does the logging */
+static void _osrfLogDetail( int level, const char* filename, int line, char* msg ) {
+
+       if( level == OSRF_LOG_ACTIVITY && ! _osrfLogActivityEnabled ) return;
+       if( level > _osrfLogLevel ) return;
+       if(!msg) return;
+       if(!filename) filename = "";
+
+       char* l = "INFO";               /* level name */
+       int lvl = LOG_INFO;     /* syslog level */
+       int fac = _osrfLogFacility;
+
+       switch( level ) {
+               case OSRF_LOG_ERROR:            
+                       l = "ERR "; 
+                       lvl = LOG_ERR;
+                       break;
+
+               case OSRF_LOG_WARNING:  
+                       l = "WARN"; 
+                       lvl = LOG_WARNING;
+                       break;
+
+               case OSRF_LOG_INFO:             
+                       l = "INFO"; 
+                       lvl = LOG_INFO;
+                       break;
+
+               case OSRF_LOG_DEBUG:    
+                       l = "DEBG"; 
+                       lvl = LOG_DEBUG;
+                       break;
+
+               case OSRF_LOG_INTERNAL: 
+                       l = "INT "; 
+                       lvl = LOG_DEBUG;
+                       break;
+
+               case OSRF_LOG_ACTIVITY: 
+                       l = "ACT"; 
+                       lvl = LOG_INFO;
+                       fac = _osrfLogActFacility;
+                       break;
+       }
+
+   char* xid = (_osrfLogXid) ? _osrfLogXid : "";
+
+       if(_osrfLogType == OSRF_LOG_TYPE_SYSLOG ) {
+               char buf[1536];  
+               memset(buf, 0x0, 1536);
+               /* give syslog some breathing room, and be cute about it */
+               strncat(buf, msg, 1535);
+               buf[1532] = '.';
+               buf[1533] = '.';
+               buf[1534] = '.';
+               buf[1535] = '\0';
+               syslog( fac | lvl, "[%s:%ld:%s:%d:%s] %s", l, (long) getpid(), filename, line, xid, buf );
+       }
+
+       else if( _osrfLogType == OSRF_LOG_TYPE_FILE )
+               _osrfLogToFile("[%s:%ld:%s:%d:%s] %s", l, (long) getpid(), filename, line, xid, msg );
+
+}
+
+
+static void _osrfLogToFile( char* msg, ... ) {
+
+       if(!msg) return;
+       if(!_osrfLogFile) return;
+       VA_LIST_TO_STRING(msg);
+
+       if(!_osrfLogAppname) _osrfLogAppname = strdup("osrf");
+       int l = strlen(VA_BUF) + strlen(_osrfLogAppname) + 36;
+       char buf[l];
+       bzero(buf,l);
+
+       char datebuf[36];
+       bzero(datebuf,36);
+       time_t t = time(NULL);
+       struct tm* tms = localtime(&t);
+       strftime(datebuf, 36, "%Y-%m-%d %H:%M:%S", tms);
+
+       FILE* file = fopen(_osrfLogFile, "a");
+       if(!file) {
+               fprintf(stderr, "Unable to fopen file %s for writing\n", _osrfLogFile);
+               return;
+       }
+
+       fprintf(file, "%s %s %s\n", _osrfLogAppname, datebuf, VA_BUF );
+       if( fclose(file) != 0 ) 
+               osrfLogWarning(OSRF_LOG_MARK, "Error closing log file: %s", strerror(errno));
+
+}
+
+
+int osrfLogFacilityToInt( char* facility ) {
+       if(!facility) return LOG_LOCAL0;
+       if(strlen(facility) < 6) return LOG_LOCAL0;
+       switch( facility[5] ) {
+               case '0': return LOG_LOCAL0;
+               case '1': return LOG_LOCAL1;
+               case '2': return LOG_LOCAL2;
+               case '3': return LOG_LOCAL3;
+               case '4': return LOG_LOCAL4;
+               case '5': return LOG_LOCAL5;
+               case '6': return LOG_LOCAL6;
+               case '7': return LOG_LOCAL7;
+       }
+       return LOG_LOCAL0;
+}
+
+
diff --git a/src/libopensrf/md5.c b/src/libopensrf/md5.c
new file mode 100644 (file)
index 0000000..c8d7688
--- /dev/null
@@ -0,0 +1,367 @@
+/* --- The data --- */
+
+const char data[] =
+"/* --- The MD5 routines --- */\n\n/* MD5 routines, after Ron R"
+"ivest */\n/* Written by David Madore <david.madore@ens.fr>, w"
+"ith code taken in\n * part from Colin Plumb. */\n/* Public dom"
+"ain (1999/11/24) */\n\n/* Note: these routines do not depend o"
+"n endianness. */\n\n/* === The header === */\n\n/* Put this in m"
+"d5.h if you don't like having everything in one big\n * file."
+" */\n\n#ifndef _DMADORE_MD5_H\n#define _DMADORE_MD5_H\n\nstruct m"
+"d5_ctx {\n  /* The four chaining variables */\n  unsigned long"
+" buf[4];\n  /* Count number of message bits */\n  unsigned lon"
+"g bits[2];\n  /* Data being fed in */\n  unsigned long in[16];"
+"\n  /* Our position within the 512 bits (always between 0 and"
+" 63) */\n  int b;\n};\n\nvoid MD5_transform (unsigned long buf[4"
+"], const unsigned long in[16]);\nvoid MD5_start (struct md5_c"
+"tx *context);\nvoid MD5_feed (struct md5_ctx *context, unsign"
+"ed char inb);\nvoid MD5_stop (struct md5_ctx *context, unsign"
+"ed char digest[16]);\n\n#endif /* not defined _DMADORE_MD5_H *"
+"/\n\n/* === The implementation === */\n\n#define F1(x, y, z) (z "
+"^ (x & (y ^ z)))\n#define F2(x, y, z) F1(z, x, y)\n#define F3("
+"x, y, z) (x ^ y ^ z)\n#define F4(x, y, z) (y ^ (x | ~z))\n\n#de"
+"fine MD5STEP(f, w, x, y, z, data, s) \\\n\t{ w += f (x, y, z) +"
+" data;  w = w<<s | (w&0xffffffffUL)>>(32-s); \\\n\t  w += x; }\n"
+"\nvoid\nMD5_transform (unsigned long buf[4], const unsigned lo"
+"ng in[16])\n{\n  register unsigned long a, b, c, d;\n\n  a = buf"
+"[0];  b = buf[1];  c = buf[2];  d = buf[3];\n  MD5STEP(F1, a,"
+" b, c, d, in[0] + 0xd76aa478UL, 7);\n  MD5STEP(F1, d, a, b, c"
+", in[1] + 0xe8c7b756UL, 12);\n  MD5STEP(F1, c, d, a, b, in[2]"
+" + 0x242070dbUL, 17);\n  MD5STEP(F1, b, c, d, a, in[3] + 0xc1"
+"bdceeeUL, 22);\n  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU"
+"L, 7);\n  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aUL, 12);\n"
+"  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613UL, 17);\n  MD5ST"
+"EP(F1, b, c, d, a, in[7] + 0xfd469501UL, 22);\n  MD5STEP(F1, "
+"a, b, c, d, in[8] + 0x698098d8UL, 7);\n  MD5STEP(F1, d, a, b,"
+" c, in[9] + 0x8b44f7afUL, 12);\n  MD5STEP(F1, c, d, a, b, in["
+"10] + 0xffff5bb1UL, 17);\n  MD5STEP(F1, b, c, d, a, in[11] + "
+"0x895cd7beUL, 22);\n  MD5STEP(F1, a, b, c, d, in[12] + 0x6b90"
+"1122UL, 7);\n  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193UL,"
+" 12);\n  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eUL, 17);\n"
+"  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821UL, 22);\n  MD5S"
+"TEP(F2, a, b, c, d, in[1] + 0xf61e2562UL, 5);\n  MD5STEP(F2, "
+"d, a, b, c, in[6] + 0xc040b340UL, 9);\n  MD5STEP(F2, c, d, a,"
+" b, in[11] + 0x265e5a51UL, 14);\n  MD5STEP(F2, b, c, d, a, in"
+"[0] + 0xe9b6c7aaUL, 20);\n  MD5STEP(F2, a, b, c, d, in[5] + 0"
+"xd62f105dUL, 5);\n  MD5STEP(F2, d, a, b, c, in[10] + 0x024414"
+"53UL, 9);\n  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681UL, 1"
+"4);\n  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8UL, 20);\n  M"
+"D5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6UL, 5);\n  MD5STEP(F"
+"2, d, a, b, c, in[14] + 0xc33707d6UL, 9);\n  MD5STEP(F2, c, d"
+", a, b, in[3] + 0xf4d50d87UL, 14);\n  MD5STEP(F2, b, c, d, a,"
+" in[8] + 0x455a14edUL, 20);\n  MD5STEP(F2, a, b, c, d, in[13]"
+" + 0xa9e3e905UL, 5);\n  MD5STEP(F2, d, a, b, c, in[2] + 0xfce"
+"fa3f8UL, 9);\n  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9UL,"
+" 14);\n  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aUL, 20);\n"
+"  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942UL, 4);\n  MD5STE"
+"P(F3, d, a, b, c, in[8] + 0x8771f681UL, 11);\n  MD5STEP(F3, c"
+", d, a, b, in[11] + 0x6d9d6122UL, 16);\n  MD5STEP(F3, b, c, d"
+", a, in[14] + 0xfde5380cUL, 23);\n  MD5STEP(F3, a, b, c, d, i"
+"n[1] + 0xa4beea44UL, 4);\n  MD5STEP(F3, d, a, b, c, in[4] + 0"
+"x4bdecfa9UL, 11);\n  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b"
+"60UL, 16);\n  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70UL, "
+"23);\n  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6UL, 4);\n  "
+"MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faUL, 11);\n  MD5STEP"
+"(F3, c, d, a, b, in[3] + 0xd4ef3085UL, 16);\n  MD5STEP(F3, b,"
+" c, d, a, in[6] + 0x04881d05UL, 23);\n  MD5STEP(F3, a, b, c, "
+"d, in[9] + 0xd9d4d039UL, 4);\n  MD5STEP(F3, d, a, b, c, in[12"
+"] + 0xe6db99e5UL, 11);\n  MD5STEP(F3, c, d, a, b, in[15] + 0x"
+"1fa27cf8UL, 16);\n  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac566"
+"5UL, 23);\n  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244UL, 6)"
+";\n  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97UL, 10);\n  MD5"
+"STEP(F4, c, d, a, b, in[14] + 0xab9423a7UL, 15);\n  MD5STEP(F"
+"4, b, c, d, a, in[5] + 0xfc93a039UL, 21);\n  MD5STEP(F4, a, b"
+", c, d, in[12] + 0x655b59c3UL, 6);\n  MD5STEP(F4, d, a, b, c,"
+" in[3] + 0x8f0ccc92UL, 10);\n  MD5STEP(F4, c, d, a, b, in[10]"
+" + 0xffeff47dUL, 15);\n  MD5STEP(F4, b, c, d, a, in[1] + 0x85"
+"845dd1UL, 21);\n  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU"
+"L, 6);\n  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0UL, 10);"
+"\n  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314UL, 15);\n  MD5S"
+"TEP(F4, b, c, d, a, in[13] + 0x4e0811a1UL, 21);\n  MD5STEP(F4"
+", a, b, c, d, in[4] + 0xf7537e82UL, 6);\n  MD5STEP(F4, d, a, "
+"b, c, in[11] + 0xbd3af235UL, 10);\n  MD5STEP(F4, c, d, a, b, "
+"in[2] + 0x2ad7d2bbUL, 15);\n  MD5STEP(F4, b, c, d, a, in[9] +"
+" 0xeb86d391UL, 21);\n  buf[0] += a;  buf[1] += b;  buf[2] += "
+"c;  buf[3] += d;\n}\n\n#undef F1\n#undef F2\n#undef F3\n#undef F4\n"
+"#undef MD5STEP\n\nvoid\nMD5_start (struct md5_ctx *ctx)\n{\n  int"
+" i;\n\n  ctx->buf[0] = 0x67452301UL;\n  ctx->buf[1] = 0xefcdab8"
+"9UL;\n  ctx->buf[2] = 0x98badcfeUL;\n  ctx->buf[3] = 0x1032547"
+"6UL;\n  ctx->bits[0] = 0;\n  ctx->bits[1] = 0;\n  for ( i=0 ; i"
+"<16 ; i++ )\n    ctx->in[i] = 0;\n  ctx->b = 0;\n}\n\nvoid\nMD5_fe"
+"ed (struct md5_ctx *ctx, unsigned char inb)\n{\n  int i;\n  uns"
+"igned long temp;\n\n  ctx->in[ctx->b/4] |= ((unsigned long)inb"
+") << ((ctx->b%4)*8);\n  if ( ++ctx->b >= 64 )\n    {\n      MD5"
+"_transform (ctx->buf, ctx->in);\n      ctx->b = 0;\n      for "
+"( i=0 ; i<16 ; i++ )\n\tctx->in[i] = 0;\n    }\n  temp = ctx->bi"
+"ts[0];\n  ctx->bits[0] += 8;\n  if ( (temp&0xffffffffUL) > (ct"
+"x->bits[0]&0xffffffffUL) )\n    ctx->bits[1]++;\n}\n\nvoid\nMD5_s"
+"top (struct md5_ctx *ctx, unsigned char digest[16])\n{\n  int "
+"i;\n  unsigned long bits[2];\n\n  for ( i=0 ; i<2 ; i++ )\n    b"
+"its[i] = ctx->bits[i];\n  MD5_feed (ctx, 0x80);\n  for ( ; ctx"
+"->b!=56 ; )\n    MD5_feed (ctx, 0);\n  for ( i=0 ; i<2 ; i++ )"
+"\n    {\n      MD5_feed (ctx, bits[i]&0xff);\n      MD5_feed (c"
+"tx, (bits[i]>>8)&0xff);\n      MD5_feed (ctx, (bits[i]>>16)&0"
+"xff);\n      MD5_feed (ctx, (bits[i]>>24)&0xff);\n    }\n  for "
+"( i=0 ; i<4 ; i++ )\n    {\n      digest[4*i] = ctx->buf[i]&0x"
+"ff;\n      digest[4*i+1] = (ctx->buf[i]>>8)&0xff;\n      diges"
+"t[4*i+2] = (ctx->buf[i]>>16)&0xff;\n      digest[4*i+3] = (ct"
+"x->buf[i]>>24)&0xff;\n    }\n}\n\f\n/* --- The core of the progra"
+"m --- */\n\n#include <stdio.h>\n#include <string.h>\n\n#define LA"
+"RGE_ENOUGH 16384\n\nchar buffer[LARGE_ENOUGH];\n\nint\nmain (int "
+"argc, char *argv[])\n{\n  unsigned int i;\n\n  buffer[0] = 0;\n  "
+"strcat (buffer, \"/* --- The data --- */\\n\\n\");\n  strcat (buf"
+"fer, \"const char data[] =\");\n  for ( i=0 ; data[i] ; i++ )\n "
+"   {\n      if ( i%60 == 0 )\n\tstrcat (buffer, \"\\n\\\"\");\n      "
+"switch ( data[i] )\n\t{\n\tcase '\\\\':\n\tcase '\"':\n\t  strcat (buff"
+"er, \"\\\\\");\n\t  buffer[strlen(buffer)+1] = 0;\n\t  buffer[strlen"
+"(buffer)] = data[i];\n\t  break;\n\tcase '\\n':\n\t  strcat (buffer"
+", \"\\\\n\");\n\t  break;\n\tcase '\\t':\n\t  strcat (buffer, \"\\\\t\");\n\t"
+"  break;\n\tcase '\\f':\n\t  strcat (buffer, \"\\\\f\");\n\t  break;\n\td"
+"efault:\n\t  buffer[strlen(buffer)+1] = 0;\n\t  buffer[strlen(bu"
+"ffer)] = data[i];\n\t}\n      if ( i%60 == 59 || !data[i+1] )\n\t"
+"strcat (buffer, \"\\\"\");\n    }\n  strcat (buffer, \";\\n\\f\\n\");\n "
+" strcat (buffer, data);\n  if ( argc >= 2 && strcmp (argv[1],"
+" \"xyzzy\") == 0 )\n    printf (\"%s\", buffer);\n  else\n    {\n   "
+"   struct md5_ctx ctx;\n      unsigned char digest[16];\n\n    "
+"  MD5_start (&ctx);\n      for ( i=0 ; buffer[i] ; i++ )\n\tMD5"
+"_feed (&ctx, buffer[i]);\n      MD5_stop (&ctx, digest);\n    "
+"  for ( i=0 ; i<16 ; i++ )\n\tprintf (\"%02x\", digest[i]);\n    "
+"  printf (\"\\n\");\n    }\n  return 0;\n}\n";
+
+
+//#include "md5.h"
+#include "opensrf/md5.h"
+
+
+/* --- The MD5 routines --- */
+
+/* MD5 routines, after Ron Rivest */
+/* Written by David Madore <david.madore@ens.fr>, with code taken in
+ * part from Colin Plumb. */
+/* Public domain (1999/11/24) */
+
+/* Note: these routines do not depend on endianness. */
+
+/* === The header === */
+
+/* Put this in md5.h if you don't like having everything in one big
+ * file. */
+
+
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+#define MD5STEP(f, w, x, y, z, data, s) \
+       { w += f (x, y, z) + data;  w = w<<s | (w&0xffffffffUL)>>(32-s); \
+         w += x; }
+
+void
+MD5_transform (unsigned long buf[4], const unsigned long in[16])
+{
+  register unsigned long a, b, c, d;
+
+  a = buf[0];  b = buf[1];  c = buf[2];  d = buf[3];
+  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478UL, 7);
+  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756UL, 12);
+  MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbUL, 17);
+  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeUL, 22);
+  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafUL, 7);
+  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aUL, 12);
+  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613UL, 17);
+  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501UL, 22);
+  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8UL, 7);
+  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afUL, 12);
+  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1UL, 17);
+  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beUL, 22);
+  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122UL, 7);
+  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193UL, 12);
+  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eUL, 17);
+  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821UL, 22);
+  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562UL, 5);
+  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340UL, 9);
+  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51UL, 14);
+  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaUL, 20);
+  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dUL, 5);
+  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453UL, 9);
+  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681UL, 14);
+  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8UL, 20);
+  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6UL, 5);
+  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6UL, 9);
+  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87UL, 14);
+  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edUL, 20);
+  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905UL, 5);
+  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8UL, 9);
+  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9UL, 14);
+  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aUL, 20);
+  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942UL, 4);
+  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681UL, 11);
+  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122UL, 16);
+  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cUL, 23);
+  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44UL, 4);
+  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9UL, 11);
+  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60UL, 16);
+  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70UL, 23);
+  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6UL, 4);
+  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faUL, 11);
+  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085UL, 16);
+  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05UL, 23);
+  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039UL, 4);
+  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5UL, 11);
+  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8UL, 16);
+  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665UL, 23);
+  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244UL, 6);
+  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97UL, 10);
+  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7UL, 15);
+  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039UL, 21);
+  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3UL, 6);
+  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92UL, 10);
+  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dUL, 15);
+  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1UL, 21);
+  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fUL, 6);
+  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0UL, 10);
+  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314UL, 15);
+  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1UL, 21);
+  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82UL, 6);
+  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235UL, 10);
+  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbUL, 15);
+  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391UL, 21);
+  buf[0] += a;  buf[1] += b;  buf[2] += c;  buf[3] += d;
+}
+
+#undef F1
+#undef F2
+#undef F3
+#undef F4
+#undef MD5STEP
+
+void
+MD5_start (struct md5_ctx *ctx)
+{
+  int i;
+
+  ctx->buf[0] = 0x67452301UL;
+  ctx->buf[1] = 0xefcdab89UL;
+  ctx->buf[2] = 0x98badcfeUL;
+  ctx->buf[3] = 0x10325476UL;
+  ctx->bits[0] = 0;
+  ctx->bits[1] = 0;
+  for ( i=0 ; i<16 ; i++ )
+    ctx->in[i] = 0;
+  ctx->b = 0;
+}
+
+void
+MD5_feed (struct md5_ctx *ctx, unsigned char inb)
+{
+  int i;
+  unsigned long temp;
+
+  ctx->in[ctx->b/4] |= ((unsigned long)inb) << ((ctx->b%4)*8);
+  if ( ++ctx->b >= 64 )
+    {
+      MD5_transform (ctx->buf, ctx->in);
+      ctx->b = 0;
+      for ( i=0 ; i<16 ; i++ )
+       ctx->in[i] = 0;
+    }
+  temp = ctx->bits[0];
+  ctx->bits[0] += 8;
+  if ( (temp&0xffffffffUL) > (ctx->bits[0]&0xffffffffUL) )
+    ctx->bits[1]++;
+}
+
+void
+MD5_stop (struct md5_ctx *ctx, unsigned char digest[16])
+{
+  int i;
+  unsigned long bits[2];
+
+  for ( i=0 ; i<2 ; i++ )
+    bits[i] = ctx->bits[i];
+  MD5_feed (ctx, 0x80);
+  for ( ; ctx->b!=56 ; )
+    MD5_feed (ctx, 0);
+  for ( i=0 ; i<2 ; i++ )
+    {
+      MD5_feed (ctx, bits[i]&0xff);
+      MD5_feed (ctx, (bits[i]>>8)&0xff);
+      MD5_feed (ctx, (bits[i]>>16)&0xff);
+      MD5_feed (ctx, (bits[i]>>24)&0xff);
+    }
+  for ( i=0 ; i<4 ; i++ )
+    {
+      digest[4*i] = ctx->buf[i]&0xff;
+      digest[4*i+1] = (ctx->buf[i]>>8)&0xff;
+      digest[4*i+2] = (ctx->buf[i]>>16)&0xff;
+      digest[4*i+3] = (ctx->buf[i]>>24)&0xff;
+    }
+}
+\f
+/* --- The core of the program --- */
+
+#include <stdio.h>
+#include <string.h>
+
+#define LARGE_ENOUGH 16384
+
+char buffer[LARGE_ENOUGH];
+
+/*
+int
+main (int argc, char *argv[])
+{
+  unsigned int i;
+
+  buffer[0] = 0;
+  strcat (buffer, \n\n");
+  strcat (buffer, "const char data[] =");
+  for ( i=0 ; data[i] ; i++ )
+    {
+      if ( i%60 == 0 )
+       strcat (buffer, "\n\"");
+      switch ( data[i] )
+       {
+       case '\\':
+       case '"':
+         strcat (buffer, "\\");
+         buffer[strlen(buffer)+1] = 0;
+         buffer[strlen(buffer)] = data[i];
+         break;
+       case '\n':
+         strcat (buffer, "\\n");
+         break;
+       case '\t':
+         strcat (buffer, "\\t");
+         break;
+       case '\f':
+         strcat (buffer, "\\f");
+         break;
+       default:
+         buffer[strlen(buffer)+1] = 0;
+         buffer[strlen(buffer)] = data[i];
+       }
+      if ( i%60 == 59 || !data[i+1] )
+       strcat (buffer, "\"");
+    }
+  strcat (buffer, ";\n\f\n");
+  strcat (buffer, data);
+  if ( argc >= 2 && strcmp (argv[1], "xyzzy") == 0 )
+    printf ("%s", buffer);
+  else
+    {
+      struct md5_ctx ctx;
+      unsigned char digest[16];
+
+      MD5_start (&ctx);
+      for ( i=0 ; buffer[i] ; i++ )
+       MD5_feed (&ctx, buffer[i]);
+      MD5_stop (&ctx, digest);
+      for ( i=0 ; i<16 ; i++ )
+       printf ("%02x", digest[i]);
+      printf ("\n");
+    }
+  return 0;
+}
+*/
diff --git a/src/libopensrf/opensrf.c b/src/libopensrf/opensrf.c
new file mode 100644 (file)
index 0000000..5532f73
--- /dev/null
@@ -0,0 +1,42 @@
+#include <opensrf/osrf_system.h>
+//#include <opensrf/osrf_hash.h>
+//#include <opensrf/osrf_list.h>
+
+int main( int argc, char* argv[] ) {
+
+       if( argc < 4 ) {
+               fprintf(stderr, "Usage: %s <host> <bootstrap_config> <config_context>\n", argv[0]);
+               return 1;
+       }
+
+       fprintf(stderr, "Loading OpenSRF host %s with bootstrap config %s "
+                       "and config context %s\n", argv[1], argv[2], argv[3] );
+
+       /* these must be strdup'ed because init_proc_title / set_proc_title 
+               are evil and overwrite the argv memory */
+       char* host              = strdup( argv[1] );
+       char* config    = strdup( argv[2] );
+       char* context   = strdup( argv[3] );
+
+       init_proc_title( argc, argv );
+       set_proc_title( "OpenSRF System-C" );
+
+       int ret = osrfSystemBootstrap( host, config, context );
+
+       if (ret != 0) {
+               osrfLogError(
+                       OSRF_LOG_MARK,
+                       "Server Loop returned an error condition, exiting with %d",
+                       ret
+               );
+       }
+
+
+       free(host);
+       free(config);
+       free(context);
+
+       return ret;
+}
+
+
diff --git a/src/libopensrf/osrfConfig.c b/src/libopensrf/osrfConfig.c
new file mode 100644 (file)
index 0000000..7fd9dbd
--- /dev/null
@@ -0,0 +1,135 @@
+/* defines the currently used bootstrap config file */
+#include <opensrf/osrfConfig.h>
+
+static osrfConfig* osrfConfigDefault = NULL;
+
+
+void osrfConfigSetDefaultConfig(osrfConfig* cfg) {
+       if(cfg) {
+               if( osrfConfigDefault )
+                       osrfConfigFree( osrfConfigDefault );
+               osrfConfigDefault = cfg;
+       }
+}
+
+void osrfConfigFree(osrfConfig* cfg) {
+       if(cfg) {
+               jsonObjectFree(cfg->config);
+               free(cfg->configContext);
+               free(cfg);
+       }       
+}
+
+
+int osrfConfigHasDefaultConfig() {
+       return ( osrfConfigDefault != NULL );
+}
+
+
+void osrfConfigCleanup() { 
+       osrfConfigFree(osrfConfigDefault);
+       osrfConfigDefault = NULL;
+}
+
+
+void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj) {
+       if(!cfg || !obj) return;
+       jsonObjectFree(cfg->config);
+       cfg->config = jsonObjectClone(obj);     
+}
+
+osrfConfig* osrfConfigInit(char* configFile, char* configContext) {
+       if(!configFile) return NULL;
+
+       // Load XML from the configuration file
+       
+       xmlDocPtr doc = xmlParseFile(configFile);
+       if(!doc) {
+               fprintf( stderr, "osrfConfigInit: Unable to parse XML config file %s\n", configFile);
+               osrfLogWarning( OSRF_LOG_MARK, "Unable to parse XML config file %s", configFile);
+               return NULL;
+       }
+
+       // Translate it into a jsonObject
+       
+       jsonObject* json_config = xmlDocToJSON(doc);
+       xmlFreeDoc(doc);
+
+       if(!json_config ) {
+               fprintf( stderr, "osrfConfigInit: xmlDocToJSON failed for config %s\n", configFile);
+               osrfLogWarning( OSRF_LOG_MARK, "xmlDocToJSON failed for config %s", configFile);
+               return NULL;
+       }       
+
+       // Build an osrfConfig and return it by pointer
+       
+       osrfConfig* cfg = safe_malloc(sizeof(osrfConfig));
+
+       if(configContext) cfg->configContext = strdup(configContext);
+       else cfg->configContext = NULL;
+
+       cfg->config = json_config;
+       
+       return cfg;
+}
+
+char* osrfConfigGetValue(osrfConfig* cfg, char* path, ...) {
+
+       if(!path) return NULL;
+       if(!cfg) cfg = osrfConfigDefault;
+       if(!cfg) { osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()"); return NULL; }
+
+       VA_LIST_TO_STRING(path);
+
+       jsonObject* obj;
+       char* val = NULL;
+
+       if(cfg->configContext) {
+               obj = jsonObjectFindPath( cfg->config, "//%s%s", cfg->configContext, VA_BUF);
+               if(obj) val = jsonObjectToSimpleString(jsonObjectGetIndex(obj, 0));
+
+       } else {
+               obj = jsonObjectFindPath( cfg->config, VA_BUF);
+               if(obj) val = jsonObjectToSimpleString(obj);
+       }
+
+       jsonObjectFree(obj);
+       return val;
+}
+
+
+int osrfConfigGetValueList(osrfConfig* cfg, osrfStringArray* arr, char* path, ...) {
+
+       if(!arr || !path) return 0;
+       if(!cfg) cfg = osrfConfigDefault;
+       if(!cfg) { osrfLogWarning( OSRF_LOG_MARK, "No Config object!"); return -1;}
+
+       VA_LIST_TO_STRING(path);
+
+       jsonObject* obj;
+       if(cfg->configContext) {
+               obj = jsonObjectFindPath( cfg->config, "//%s%s", cfg->configContext, VA_BUF);
+       } else {
+               obj = jsonObjectFindPath( cfg->config, VA_BUF);
+       }
+
+       int count = 0;
+
+       if(obj && obj->type == JSON_ARRAY ) {
+
+               int i;
+               for( i = 0; i < obj->size; i++ ) {
+
+                       char* val = jsonObjectToSimpleString(jsonObjectGetIndex(obj, i));
+                       if(val) {
+                               count++;
+                               osrfStringArrayAdd(arr, val);
+                               free(val);
+                       }
+               }
+       }
+
+       jsonObjectFree(obj);
+       return count;
+}
+
diff --git a/src/libopensrf/osrf_app_session.c b/src/libopensrf/osrf_app_session.c
new file mode 100644 (file)
index 0000000..d89c445
--- /dev/null
@@ -0,0 +1,660 @@
+#include <opensrf/osrf_app_session.h>
+#include <time.h>
+
+/* the global app_session cache */
+osrfHash* osrfAppSessionCache = NULL;
+
+
+// --------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// Request API
+// --------------------------------------------------------------------------
+
+/** Allocation and initializes a new app_request object */
+osrf_app_request* _osrf_app_request_init( 
+               osrf_app_session* session, osrf_message* msg ) {
+
+       osrf_app_request* req = 
+               (osrf_app_request*) safe_malloc(sizeof(osrf_app_request));
+
+       req->session            = session;
+       req->request_id = msg->thread_trace;
+       req->complete           = 0;
+       req->payload            = msg;
+       req->result                     = NULL;
+
+       return req;
+
+}
+
+
+void osrfAppSessionCleanup() {
+       osrfHashFree(osrfAppSessionCache);      
+}
+
+
+
+/** Frees memory used by an app_request object */
+void _osrf_app_request_free( void * req ){
+       if( req == NULL ) return;
+       osrfAppRequest* r = (osrfAppRequest*) req;
+       if( r->payload ) osrf_message_free( r->payload );
+       free( r );
+}
+
+/** Pushes the given message onto the list of 'responses' to this request */
+void _osrf_app_request_push_queue( osrf_app_request* req, osrf_message* result ){
+       if(req == NULL || result == NULL) return;
+       osrfLogDebug( OSRF_LOG_MARK,  "App Session pushing request [%d] onto request queue", result->thread_trace );
+       if(req->result == NULL) {
+               req->result = result;
+
+       } else {
+               
+               osrf_message* ptr = req->result;
+               osrf_message* ptr2 = req->result->next;
+               while( ptr2 ) {
+                       ptr = ptr2;
+                       ptr2 = ptr2->next;
+               }
+               ptr->next = result;
+       }
+}
+
+/** Removes this app_request from our session request set */
+void osrf_app_session_request_finish( 
+               osrf_app_session* session, int req_id ){
+
+       if(session == NULL) return;
+       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
+       if(req == NULL) return;
+       osrfListRemove( req->session->request_queue, req->request_id );
+}
+
+
+void osrf_app_session_request_reset_timeout( osrf_app_session* session, int req_id ) {
+       if(session == NULL) return;
+       osrfLogDebug( OSRF_LOG_MARK, "Resetting request timeout %d", req_id );
+       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
+       if(req == NULL) return;
+       req->reset_timeout = 1;
+}
+
+/** Checks the receive queue for messages.  If any are found, the first
+  * is popped off and returned.  Otherwise, this method will wait at most timeout 
+  * seconds for a message to appear in the receive queue.  Once it arrives it is returned.
+  * If no messages arrive in the timeout provided, null is returned.
+  */
+osrf_message* _osrf_app_request_recv( osrf_app_request* req, int timeout ) {
+
+       if(req == NULL) return NULL;
+
+       if( req->result != NULL ) {
+               /* pop off the first message in the list */
+               osrf_message* tmp_msg = req->result;
+               req->result = req->result->next;
+               return tmp_msg;
+       }
+
+       time_t start = time(NULL);      
+       time_t remaining = (time_t) timeout;
+
+       while( remaining >= 0 ) {
+               /* tell the session to wait for stuff */
+               osrfLogDebug( OSRF_LOG_MARK,  "In app_request receive with remaining time [%d]", (int) remaining );
+
+               osrf_app_session_queue_wait( req->session, 0, NULL );
+
+               if( req->result != NULL ) { /* if we received anything */
+                       /* pop off the first message in the list */
+                       osrfLogDebug( OSRF_LOG_MARK,  "app_request_recv received a message, returning it");
+                       osrf_message* ret_msg = req->result;
+                       osrf_message* tmp_msg = ret_msg->next;
+                       req->result = tmp_msg;
+                       return ret_msg;
+               }
+
+               if( req->complete )
+                       return NULL;
+
+               osrf_app_session_queue_wait( req->session, (int) remaining, NULL );
+
+               if( req->result != NULL ) { /* if we received anything */
+                       /* pop off the first message in the list */
+                       osrfLogDebug( OSRF_LOG_MARK,  "app_request_recv received a message, returning it");
+                       osrf_message* ret_msg = req->result;
+                       osrf_message* tmp_msg = ret_msg->next;
+                       req->result = tmp_msg;
+                       return ret_msg;
+               }
+               if( req->complete )
+                       return NULL;
+
+               if(req->reset_timeout) {
+                       remaining = (time_t) timeout;
+                       req->reset_timeout = 0;
+                       osrfLogDebug( OSRF_LOG_MARK, "Recevied a timeout reset");
+               } else {
+                       remaining -= (int) (time(NULL) - start);
+               }
+       }
+
+       osrfLogInfo( OSRF_LOG_MARK, "Returning NULL from app_request_recv after timeout");
+       return NULL;
+}
+
+/** Resend this requests original request message */
+int _osrf_app_request_resend( osrf_app_request* req ) {
+       if(req == NULL) return 0;
+       if(!req->complete) {
+               osrfLogDebug( OSRF_LOG_MARK,  "Resending request [%d]", req->request_id );
+               return _osrf_app_session_send( req->session, req->payload );
+       }
+       return 1;
+}
+
+
+
+// --------------------------------------------------------------------------
+// --------------------------------------------------------------------------
+// Session API
+// --------------------------------------------------------------------------
+
+/** returns a session from the global session hash */
+osrf_app_session* osrf_app_session_find_session( char* session_id ) {
+       if(session_id) return osrfHashGet(osrfAppSessionCache, session_id);
+       return NULL;
+}
+
+
+/** adds a session to the global session cache */
+void _osrf_app_session_push_session( osrf_app_session* session ) {
+       if(!session) return;
+       if( osrfAppSessionCache == NULL ) osrfAppSessionCache = osrfNewHash();
+       if( osrfHashGet( osrfAppSessionCache, session->session_id ) ) return;
+       osrfHashSet( osrfAppSessionCache, session, session->session_id );
+}
+
+/** Allocates a initializes a new app_session */
+
+osrf_app_session* osrfAppSessionClientInit( char* remote_service ) {
+       return osrf_app_client_session_init( remote_service );
+}
+
+osrf_app_session* osrf_app_client_session_init( char* remote_service ) {
+
+       osrf_app_session* session = safe_malloc(sizeof(osrf_app_session));      
+
+       session->transport_handle = osrf_system_get_transport_client();
+       if( session->transport_handle == NULL ) {
+               osrfLogWarning( OSRF_LOG_MARK, "No transport client for service 'client'");
+               free( session );
+               return NULL;
+       }
+
+       char target_buf[512];
+       target_buf[ 0 ] = '\0';
+
+       osrfStringArray* arr = osrfNewStringArray(8);
+       osrfConfigGetValueList(NULL, arr, "/domains/domain");
+       char* domain = osrfStringArrayGetString(arr, 0);
+       char* router_name = osrfConfigGetValue(NULL, "/router_name");
+       
+       int len = snprintf( target_buf, 512, "%s@%s/%s",  router_name, domain, remote_service );
+       osrfStringArrayFree(arr);
+       //free(domain);
+       free(router_name);
+
+       if( len >= sizeof( target_buf ) ) {
+               osrfLogWarning( OSRF_LOG_MARK, "Buffer overflow for remote_id");
+               free( session );
+               return NULL;
+       }
+
+       session->request_queue = osrfNewList();
+       session->request_queue->freeItem = &_osrf_app_request_free;
+       session->remote_id = strdup(target_buf);
+       session->orig_remote_id = strdup(session->remote_id);
+       session->remote_service = strdup(remote_service);
+
+       #ifdef ASSUME_STATELESS
+       session->stateless = 1;
+       osrfLogDebug( OSRF_LOG_MARK, "%s session is stateless", remote_service );
+       #else
+       session->stateless = 0;
+       osrfLogDebug( OSRF_LOG_MARK, "%s session is NOT stateless", remote_service );
+       #endif
+
+       /* build a chunky, random session id */
+       char id[256];
+       memset(id,0,256);
+
+       sprintf(id, "%f.%d%ld", get_timestamp_millis(), (int)time(NULL), (long) getpid());
+       session->session_id = strdup(id);
+       osrfLogDebug( OSRF_LOG_MARK,  "Building a new client session with id [%s] [%s]", 
+                       session->remote_service, session->session_id );
+
+       session->thread_trace = 0;
+       session->state = OSRF_SESSION_DISCONNECTED;
+       session->type = OSRF_SESSION_CLIENT;
+       //session->next = NULL;
+       _osrf_app_session_push_session( session );
+       return session;
+}
+
+osrf_app_session* osrf_app_server_session_init( 
+               char* session_id, char* our_app, char* remote_id ) {
+
+       osrfLogDebug( OSRF_LOG_MARK, "Initing server session with session id %s, service %s,"
+                       " and remote_id %s", session_id, our_app, remote_id );
+
+       osrf_app_session* session = osrf_app_session_find_session( session_id );
+       if(session) return session;
+
+       session = safe_malloc(sizeof(osrf_app_session));        
+
+       session->transport_handle = osrf_system_get_transport_client();
+       if( session->transport_handle == NULL ) {
+               osrfLogWarning( OSRF_LOG_MARK, "No transport client for service '%s'", our_app );
+               return NULL;
+       }
+
+       int stateless = 0;
+       char* statel = osrf_settings_host_value("/apps/%s/stateless", our_app );
+       if(statel) stateless = atoi(statel);
+       free(statel);
+
+
+       session->request_queue = osrfNewList();
+       session->request_queue->freeItem = &_osrf_app_request_free;
+       session->remote_id = strdup(remote_id);
+       session->orig_remote_id = strdup(remote_id);
+       session->session_id = strdup(session_id);
+       session->remote_service = strdup(our_app);
+       session->stateless = stateless;
+
+       #ifdef ASSUME_STATELESS
+       session->stateless = 1;
+       #endif
+
+       session->thread_trace = 0;
+       session->state = OSRF_SESSION_DISCONNECTED;
+       session->type = OSRF_SESSION_SERVER;
+
+       _osrf_app_session_push_session( session );
+       return session;
+
+}
+
+
+
+/** frees memory held by a session */
+void _osrf_app_session_free( osrf_app_session* session ){
+       if(session==NULL)
+               return;
+
+       if( session->userDataFree && session->userData ) 
+               session->userDataFree(session->userData);
+       
+       free(session->remote_id);
+       free(session->orig_remote_id);
+       free(session->session_id);
+       free(session->remote_service);
+       osrfListFree(session->request_queue);
+       free(session);
+}
+
+int osrfAppSessionMakeRequest(
+               osrf_app_session* session, jsonObject* params, 
+               char* method_name, int protocol, string_array* param_strings ) {
+
+       return osrf_app_session_make_req( session, params, 
+                       method_name, protocol, param_strings );
+}
+
+int osrf_app_session_make_req( 
+               osrf_app_session* session, jsonObject* params, 
+               char* method_name, int protocol, string_array* param_strings ) {
+       if(session == NULL) return -1;
+
+   osrfLogMkXid();
+
+       osrf_message* req_msg = osrf_message_init( REQUEST, ++(session->thread_trace), protocol );
+       osrf_message_set_method(req_msg, method_name);
+       if(params) {
+               osrf_message_set_params(req_msg, params);
+
+       } else {
+
+               if(param_strings) {
+                       int i;
+                       for(i = 0; i!= param_strings->size ; i++ ) {
+                               osrf_message_add_param(req_msg,
+                                       string_array_get_string(param_strings,i));
+                       }
+               }
+       }
+
+       osrf_app_request* req = _osrf_app_request_init( session, req_msg );
+       if(_osrf_app_session_send( session, req_msg ) ) {
+               osrfLogWarning( OSRF_LOG_MARK,  "Error sending request message [%d]", session->thread_trace );
+               return -1;
+       }
+
+       osrfLogDebug( OSRF_LOG_MARK,  "Pushing [%d] onto requeust queue for session [%s] [%s]",
+                       req->request_id, session->remote_service, session->session_id );
+       osrfListSet( session->request_queue, req, req->request_id ); 
+       return req->request_id;
+}
+
+void osrf_app_session_set_complete( osrf_app_session* session, int request_id ) {
+       if(session == NULL)
+               return;
+
+       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, request_id );
+       if(req) req->complete = 1;
+}
+
+int osrf_app_session_request_complete( osrf_app_session* session, int request_id ) {
+       if(session == NULL)
+               return 0;
+       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, request_id );
+       if(req)
+               return req->complete;
+       return 0;
+}
+
+
+/** Resets the remote connection id to that of the original*/
+void osrf_app_session_reset_remote( osrf_app_session* session ){
+       if( session==NULL )
+               return;
+
+       free(session->remote_id);
+       osrfLogDebug( OSRF_LOG_MARK,  "App Session [%s] [%s] resetting remote id to %s",
+                       session->remote_service, session->session_id, session->orig_remote_id );
+
+       session->remote_id = strdup(session->orig_remote_id);
+}
+
+void osrf_app_session_set_remote( osrf_app_session* session, char* remote_id ) {
+       if(session == NULL)
+               return;
+       if( session->remote_id )
+               free(session->remote_id );
+       session->remote_id = strdup( remote_id );
+}
+
+/** pushes the given message into the result list of the app_request
+  with the given request_id */
+int osrf_app_session_push_queue( 
+               osrf_app_session* session, osrf_message* msg ){
+       if(session == NULL || msg == NULL) return 0;
+
+       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, msg->thread_trace );
+       if(req == NULL) return 0;
+       _osrf_app_request_push_queue( req, msg );
+
+       return 0;
+}
+
+int osrfAppSessionConnect( osrf_app_session* session ) { 
+       return osrf_app_session_connect(session);
+}
+
+
+/** Attempts to connect to the remote service */
+int osrf_app_session_connect(osrf_app_session* session){
+       
+       if(session == NULL)
+               return 0;
+
+       if(session->state == OSRF_SESSION_CONNECTED) {
+               return 1;
+       }
+
+       int timeout = 5; /* XXX CONFIG VALUE */
+
+       osrfLogDebug( OSRF_LOG_MARK,  "AppSession connecting to %s", session->remote_id );
+
+       /* defaulting to protocol 1 for now */
+       osrf_message* con_msg = osrf_message_init( CONNECT, session->thread_trace, 1 );
+       osrf_app_session_reset_remote( session );
+       session->state = OSRF_SESSION_CONNECTING;
+       int ret = _osrf_app_session_send( session, con_msg );
+       osrf_message_free(con_msg);
+       if(ret) return 0;
+
+       time_t start = time(NULL);      
+       time_t remaining = (time_t) timeout;
+
+       while( session->state != OSRF_SESSION_CONNECTED && remaining >= 0 ) {
+               osrf_app_session_queue_wait( session, remaining, NULL );
+               remaining -= (int) (time(NULL) - start);
+       }
+
+       if(session->state == OSRF_SESSION_CONNECTED)
+               osrfLogDebug( OSRF_LOG_MARK, " * Connected Successfully to %s", session->remote_service );
+
+       if(session->state != OSRF_SESSION_CONNECTED)
+               return 0;
+
+       return 1;
+}
+
+
+
+/** Disconnects from the remote service */
+int osrf_app_session_disconnect( osrf_app_session* session){
+       if(session == NULL)
+               return 1;
+
+       if(session->state == OSRF_SESSION_DISCONNECTED)
+               return 1;
+
+       if(session->stateless && session->state != OSRF_SESSION_CONNECTED) {
+               osrfLogDebug( OSRF_LOG_MARK,  
+                               "Exiting disconnect on stateless session %s", 
+                               session->session_id);
+               return 1;
+       }
+
+       osrfLogDebug(OSRF_LOG_MARK,  "AppSession disconnecting from %s", session->remote_id );
+
+       osrf_message* dis_msg = osrf_message_init( DISCONNECT, session->thread_trace, 1 );
+       _osrf_app_session_send( session, dis_msg );
+       session->state = OSRF_SESSION_DISCONNECTED;
+
+       osrf_message_free( dis_msg );
+       osrf_app_session_reset_remote( session );
+       return 1;
+}
+
+int osrf_app_session_request_resend( osrf_app_session* session, int req_id ) {
+       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
+       return _osrf_app_request_resend( req );
+}
+
+
+int osrfAppSessionSendBatch( osrfAppSession* session, osrf_message* msgs[], int size ) {
+
+       if( !(session && msgs && size > 0) ) return 0;
+       int retval = 0;
+
+       osrfMessage* msg = msgs[0];
+
+       if(msg) {
+
+               osrf_app_session_queue_wait( session, 0, NULL );
+
+               if(session->state != OSRF_SESSION_CONNECTED)  {
+
+                       if(session->stateless) { /* stateless session always send to the root listener */
+                               osrf_app_session_reset_remote(session);
+
+                       } else { 
+
+                               /* do an auto-connect if necessary */
+                               if( ! session->stateless &&
+                                       (msg->m_type != CONNECT) && 
+                                       (msg->m_type != DISCONNECT) &&
+                                       (session->state != OSRF_SESSION_CONNECTED) ) {
+
+                                       if(!osrf_app_session_connect( session )) 
+                                               return 0;
+                               }
+                       }
+               }
+       }
+
+       char* string = osrfMessageSerializeBatch(msgs, size);
+
+       if( string ) {
+
+               transport_message* t_msg = message_init( 
+                               string, "", session->session_id, session->remote_id, NULL );
+      message_set_osrf_xid( t_msg, osrfLogGetXid() );
+
+               retval = client_send_message( session->transport_handle, t_msg );
+
+               if( retval ) osrfLogError(OSRF_LOG_MARK, "client_send_message failed");
+
+               osrfLogInfo(OSRF_LOG_MARK, "[%s] sent %d bytes of data to %s",
+                       session->remote_service, strlen(string), t_msg->recipient );
+
+               osrfLogDebug(OSRF_LOG_MARK, "Sent: %s", string );
+
+               free(string);
+               message_free( t_msg );
+       }
+
+       return retval; 
+}
+
+
+
+int _osrf_app_session_send( osrf_app_session* session, osrf_message* msg ){
+       if( !(session && msg) ) return 0;
+       osrfMessage* a[1];
+       a[0] = msg;
+       return osrfAppSessionSendBatch( session, a, 1 );
+}
+
+
+
+
+/**  Waits up to 'timeout' seconds for some data to arrive.
+  * Any data that arrives will be processed according to its
+  * payload and message type.  This method will return after
+  * any data has arrived.
+  */
+int osrf_app_session_queue_wait( osrf_app_session* session, int timeout, int* recvd ){
+       if(session == NULL) return 0;
+       int ret_val = 0;
+       osrfLogDebug(OSRF_LOG_MARK,  "AppSession in queue_wait with timeout %d", timeout );
+       ret_val = osrf_stack_entry_point(session->transport_handle, timeout, recvd);
+       return ret_val;
+}
+
+/** Disconnects (if client) and removes the given session from the global session cache 
+  * ! This free's all attached app_requests ! 
+  */
+void osrfAppSessionFree( osrfAppSession* ses ) {
+       osrf_app_session_destroy( ses );
+}
+
+
+void osrf_app_session_destroy( osrf_app_session* session ){
+       if(session == NULL) return;
+
+       osrfLogDebug(OSRF_LOG_MARK,  "AppSession [%s] [%s] destroying self and deleting requests", 
+                       session->remote_service, session->session_id );
+       if(session->type == OSRF_SESSION_CLIENT 
+                       && session->state != OSRF_SESSION_DISCONNECTED ) { /* disconnect if we're a client */
+               osrf_message* dis_msg = osrf_message_init( DISCONNECT, session->thread_trace, 1 );
+               _osrf_app_session_send( session, dis_msg ); 
+               osrf_message_free(dis_msg);
+       }
+
+       osrfHashRemove( osrfAppSessionCache, session->session_id );
+       _osrf_app_session_free( session );
+}
+
+osrf_message* osrfAppSessionRequestRecv(
+               osrf_app_session* session, int req_id, int timeout ) {
+       return osrf_app_session_request_recv( session, req_id, timeout );
+}
+osrf_message* osrf_app_session_request_recv( 
+               osrf_app_session* session, int req_id, int timeout ) {
+       if(req_id < 0 || session == NULL)
+               return NULL;
+       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
+       return _osrf_app_request_recv( req, timeout );
+}
+
+
+
+int osrfAppRequestRespond( osrfAppSession* ses, int requestId, jsonObject* data ) {
+       if(!ses || ! data ) return -1;
+
+       osrf_message* msg = osrf_message_init( RESULT, requestId, 1 );
+       osrf_message_set_status_info( msg, NULL, "OK", OSRF_STATUS_OK );
+       char* json = jsonObjectToJSON( data );
+
+       osrf_message_set_result_content( msg, json );
+       _osrf_app_session_send( ses, msg ); 
+
+       free(json);
+       osrf_message_free( msg );
+
+       return 0;
+}
+
+
+int osrfAppRequestRespondComplete( 
+               osrfAppSession* ses, int requestId, jsonObject* data ) {
+
+       osrf_message* payload = osrf_message_init( RESULT, requestId, 1 );
+       osrf_message_set_status_info( payload, NULL, "OK", OSRF_STATUS_OK );
+
+       osrf_message* status = osrf_message_init( STATUS, requestId, 1);
+       osrf_message_set_status_info( status, "osrfConnectStatus", "Request Complete", OSRF_STATUS_COMPLETE );
+       
+       if (data) {
+               char* json = jsonObjectToJSON( data );
+               osrf_message_set_result_content( payload, json );
+               free(json);
+
+               osrfMessage* ms[2];
+               ms[0] = payload;
+               ms[1] = status;
+
+               osrfAppSessionSendBatch( ses, ms, 2 );
+
+               osrf_message_free( payload );
+       } else {
+               osrfAppSessionSendBatch( ses, &status, 1 );
+       }
+
+       osrf_message_free( status );
+
+       return 0;
+}
+
+int osrfAppSessionStatus( osrfAppSession* ses, int type, char* name, int reqId, char* message ) {
+
+       if(ses) {
+               osrf_message* msg = osrf_message_init( STATUS, reqId, 1);
+               osrf_message_set_status_info( msg, name, message, type );
+               _osrf_app_session_send( ses, msg ); 
+               osrf_message_free( msg );
+               return 0;
+       }
+       return -1;
+}
+
+
+
+
+
+
diff --git a/src/libopensrf/osrf_application.c b/src/libopensrf/osrf_application.c
new file mode 100644 (file)
index 0000000..1f12b86
--- /dev/null
@@ -0,0 +1,477 @@
+#include <opensrf/osrf_application.h>
+#include <objson/object.h>
+
+//osrfApplication* __osrfAppList = NULL; 
+
+osrfHash* __osrfAppHash = NULL;
+
+
+int osrfAppRegisterApplication( char* appName, char* soFile ) {
+       if(!appName || ! soFile) return -1;
+       char* error;
+
+       if(!__osrfAppHash) __osrfAppHash = osrfNewHash();
+
+       osrfLogInfo( OSRF_LOG_MARK, "Registering application %s with file %s", appName, soFile );
+
+       osrfApplication* app = safe_malloc(sizeof(osrfApplication));
+       app->handle = dlopen (soFile, RTLD_NOW);
+   app->onExit = NULL;
+
+       if(!app->handle) {
+               osrfLogWarning( OSRF_LOG_MARK, "Failed to dlopen library file %s: %s", soFile, dlerror() );
+               dlerror(); /* clear the error */
+               free(app);
+               return -1;
+       }
+
+       app->methods = osrfNewHash();
+       osrfHashSet( __osrfAppHash, app, appName );
+
+       /* see if we can run the initialize method */
+       int (*init) (void);
+       *(void **) (&init) = dlsym(app->handle, "osrfAppInitialize");
+
+       if( (error = dlerror()) != NULL ) {
+               osrfLogWarning( OSRF_LOG_MARK, 
+                       "! Unable to locate method symbol [osrfAppInitialize] for app %s: %s", appName, error );
+
+       } else {
+
+               /* run the method */
+               int ret;
+               if( (ret = (*init)()) ) {
+                       osrfLogWarning( OSRF_LOG_MARK, "Application %s returned non-zero value from "
+                                       "'osrfAppInitialize', not registering...", appName );
+                       //free(app->name); /* need a method to remove an application from the list */
+                       //free(app);
+                       return ret;
+               }
+       }
+
+       __osrfAppRegisterSysMethods(appName);
+
+       osrfLogInfo( OSRF_LOG_MARK, "Application %s registered successfully", appName );
+
+       osrfLogSetAppname(appName);
+
+   osrfAppSetOnExit(app, appName);
+
+       return 0;
+}
+
+
+void osrfAppSetOnExit(osrfApplication* app, char* appName) {
+   if(!(app && appName)) return;
+
+       /* see if we can run the initialize method */
+   char* error;
+       void (*onExit) (void);
+       *(void **) (&onExit) = dlsym(app->handle, "osrfAppChildExit");
+
+       if( (error = dlerror()) != NULL ) {
+      osrfLogDebug(OSRF_LOG_MARK, "No exit handler defined for %s", appName);
+      return;
+   }
+
+   osrfLogInfo(OSRF_LOG_MARK, "registering exit handler for %s", appName);
+   app->onExit = (*onExit);
+   //if( (ret = (*onExit)()) ) {
+}
+
+
+int osrfAppRunChildInit(char* appname) {
+       osrfApplication* app = _osrfAppFindApplication(appname);
+       if(!app) return -1;
+
+       char* error;
+       int ret;
+       int (*childInit) (void);
+
+       *(void**) (&childInit) = dlsym(app->handle, "osrfAppChildInit");
+
+       if( (error = dlerror()) != NULL ) {
+               osrfLogInfo( OSRF_LOG_MARK, "No child init defined for app %s : %s", appname, error);
+               return 0;
+       }
+
+       if( (ret = (*childInit)()) ) {
+               osrfLogError(OSRF_LOG_MARK, "App %s child init failed", appname);
+               return -1;
+       }
+
+       osrfLogInfo(OSRF_LOG_MARK, "%s child init succeeded", appname);
+       return 0;
+}
+
+
+void osrfAppRunExitCode() { 
+   osrfHashIterator* itr = osrfNewHashIterator(__osrfAppHash);
+   osrfApplication* app;
+   while( (app = osrfHashIteratorNext(itr)) ) {
+      if( app->onExit ) {
+         osrfLogInfo(OSRF_LOG_MARK, "Running onExit handler for app %s", itr->current);
+         app->onExit();
+      }
+   }
+}
+
+
+int osrfAppRegisterMethod( char* appName, char* methodName, 
+               char* symbolName, char* notes, int argc, int options ) {
+
+       return osrfAppRegisterExtendedMethod(
+                       appName,
+                       methodName,
+                       symbolName,
+                       notes,
+                       argc,
+                       options,
+                       NULL
+       );
+
+}
+
+int osrfAppRegisterExtendedMethod( char* appName, char* methodName, 
+               char* symbolName, char* notes, int argc, int options, void * user_data ) {
+
+       if( !appName || ! methodName  ) return -1;
+
+       osrfApplication* app = _osrfAppFindApplication(appName);
+       if(!app) {
+               osrfLogWarning( OSRF_LOG_MARK, "Unable to locate application %s", appName );
+               return -1;
+       }
+
+       osrfLogDebug( OSRF_LOG_MARK, "Registering method %s for app %s", methodName, appName );
+
+       osrfMethod* method = _osrfAppBuildMethod(
+               methodName, symbolName, notes, argc, options, user_data );              
+       method->options = options;
+
+       /* plug the method into the list of methods */
+       osrfHashSet( app->methods, method, method->name );
+
+       if( options & OSRF_METHOD_STREAMING ) { /* build the atomic counterpart */
+               int newops = options | OSRF_METHOD_ATOMIC;
+               osrfMethod* atomicMethod = _osrfAppBuildMethod(
+                       methodName, symbolName, notes, argc, newops, NULL );            
+               osrfHashSet( app->methods, atomicMethod, atomicMethod->name );
+               atomicMethod->userData = method->userData;
+       }
+
+       return 0;
+}
+
+
+
+osrfMethod* _osrfAppBuildMethod( char* methodName, 
+       char* symbolName, char* notes, int argc, int options, void* user_data ) {
+
+       osrfMethod* method                                      = safe_malloc(sizeof(osrfMethod));
+
+       if(methodName) method->name             = strdup(methodName);
+       if(symbolName) method->symbol           = strdup(symbolName);
+       if(notes) method->notes                         = strdup(notes);
+       if(user_data) method->userData  = user_data;
+
+       method->argc                                                    = argc;
+       method->options                                         = options;
+
+       if(options & OSRF_METHOD_ATOMIC) { /* add ".atomic" to the end of the name */
+               char mb[strlen(method->name) + 8];
+               sprintf(mb, "%s.atomic", method->name);
+               free(method->name);
+               method->name = strdup(mb);
+               method->options |= OSRF_METHOD_STREAMING;
+       }
+
+       return method;
+}
+
+
+int __osrfAppRegisterSysMethods( char* app ) {
+
+       osrfAppRegisterMethod( 
+                       app, OSRF_SYSMETHOD_INTROSPECT, NULL, 
+                       "Return a list of methods whose names have the same initial "
+                       "substring as that of the provided method name PARAMS( methodNameSubstring )", 
+                       1, OSRF_METHOD_SYSTEM | OSRF_METHOD_STREAMING );
+
+       osrfAppRegisterMethod( 
+                       app, OSRF_SYSMETHOD_INTROSPECT_ALL, NULL, 
+                       "Returns a complete list of methods. PARAMS()", 0, 
+                       OSRF_METHOD_SYSTEM | OSRF_METHOD_STREAMING );
+
+       osrfAppRegisterMethod( 
+                       app, OSRF_SYSMETHOD_ECHO, NULL, 
+                       "Echos all data sent to the server back to the client. PARAMS([a, b, ...])", 0, 
+                       OSRF_METHOD_SYSTEM | OSRF_METHOD_STREAMING );
+
+       return 0;
+}
+
+osrfApplication* _osrfAppFindApplication( char* name ) {
+       if(!name) return NULL;
+       return (osrfApplication*) osrfHashGet(__osrfAppHash, name);
+}
+
+osrfMethod* __osrfAppFindMethod( osrfApplication* app, char* methodName ) {
+       if(!app || ! methodName) return NULL;
+       return (osrfMethod*) osrfHashGet( app->methods, methodName );
+}
+
+osrfMethod* _osrfAppFindMethod( char* appName, char* methodName ) {
+       if(!appName || ! methodName) return NULL;
+       return __osrfAppFindMethod( _osrfAppFindApplication(appName), methodName );
+}
+
+
+int osrfAppRunMethod( char* appName, char* methodName, 
+               osrfAppSession* ses, int reqId, jsonObject* params ) {
+
+       if( !(appName && methodName && ses) ) return -1;
+
+       char* error;
+       osrfApplication* app;
+       osrfMethod* method;
+       osrfMethodContext context;
+
+       context.session = ses;
+       context.params = params;
+       context.request = reqId;
+       context.responses = NULL;
+
+       /* this is the method we're gonna run */
+       int (*meth) (osrfMethodContext*);       
+
+       if( !(app = _osrfAppFindApplication(appName)) )
+               return osrfAppRequestRespondException( ses, 
+                               reqId, "Application not found: %s", appName );
+       
+       if( !(method = __osrfAppFindMethod( app, methodName )) ) 
+               return osrfAppRequestRespondException( ses, reqId, 
+                               "Method [%s] not found for service %s", methodName, appName );
+
+       context.method = method;
+
+       #ifdef OSRF_STRICT_PARAMS
+       if( method->argc > 0 ) {
+               if(!params || params->type != JSON_ARRAY || params->size < method->argc )
+                       return osrfAppRequestRespondException( ses, reqId, 
+                               "Not enough params for method %s / service %s", methodName, appName );
+       }
+       #endif
+
+       int retcode = 0;
+
+       if( method->options & OSRF_METHOD_SYSTEM ) {
+               retcode = __osrfAppRunSystemMethod(&context);
+
+       } else {
+
+               /* open and now run the method */
+               *(void **) (&meth) = dlsym(app->handle, method->symbol);
+
+               if( (error = dlerror()) != NULL ) {
+                       return osrfAppRequestRespondException( ses, reqId, 
+                               "Unable to execute method [%s]  for service %s", methodName, appName );
+               }
+
+               retcode = (*meth) (&context);
+       }
+
+       if(retcode < 0) 
+               return osrfAppRequestRespondException( 
+                               ses, reqId, "An unknown server error occurred" );
+
+       return __osrfAppPostProcess( &context, retcode );
+
+}
+
+
+int osrfAppRespond( osrfMethodContext* ctx, jsonObject* data ) {
+       return _osrfAppRespond( ctx, data, 0 );
+}
+
+int osrfAppRespondComplete( osrfMethodContext* context, jsonObject* data ) {
+       return _osrfAppRespond( context, data, 1 );
+}
+
+int _osrfAppRespond( osrfMethodContext* ctx, jsonObject* data, int complete ) {
+       if(!(ctx && ctx->method)) return -1;
+
+       if( ctx->method->options & OSRF_METHOD_ATOMIC ) {
+               osrfLogDebug( OSRF_LOG_MARK,   
+                       "Adding responses to stash for atomic method %s", ctx->method->name );
+
+               if( ctx->responses == NULL )                                                                                            
+                       ctx->responses = jsonParseString("[]");                                                 
+
+               if ( data != NULL )
+                       jsonObjectPush( ctx->responses, jsonObjectClone(data) );        
+       }
+
+
+       if(     !(ctx->method->options & OSRF_METHOD_ATOMIC) && 
+                       !(ctx->method->options & OSRF_METHOD_CACHABLE) ) {
+
+               if(complete) 
+                       osrfAppRequestRespondComplete( ctx->session, ctx->request, data );
+               else
+                       osrfAppRequestRespond( ctx->session, ctx->request, data );
+               return 0;
+       }
+
+       return 0;
+}
+
+
+
+
+int __osrfAppPostProcess( osrfMethodContext* ctx, int retcode ) {
+       if(!(ctx && ctx->method)) return -1;
+
+       osrfLogDebug( OSRF_LOG_MARK,  "Postprocessing method %s with retcode %d",
+                       ctx->method->name, retcode );
+
+       if(ctx->responses) { /* we have cached responses to return (no responses have been sent) */
+
+               osrfAppRequestRespondComplete( ctx->session, ctx->request, ctx->responses );
+               jsonObjectFree(ctx->responses);
+               ctx->responses = NULL;
+
+       } else {
+
+               if( retcode > 0 ) 
+                       osrfAppSessionStatus( ctx->session, OSRF_STATUS_COMPLETE,  
+                                       "osrfConnectStatus", ctx->request, "Request Complete" );
+       }
+
+       return 0;
+}
+
+int osrfAppRequestRespondException( osrfAppSession* ses, int request, char* msg, ... ) {
+       if(!ses) return -1;
+       if(!msg) msg = "";
+       VA_LIST_TO_STRING(msg);
+       osrfLogWarning( OSRF_LOG_MARK,  "Returning method exception with message: %s", VA_BUF );
+       osrfAppSessionStatus( ses, OSRF_STATUS_NOTFOUND, "osrfMethodException", request,  VA_BUF );
+       return 0;
+}
+
+
+static void __osrfAppSetIntrospectMethod( osrfMethodContext* ctx, osrfMethod* method, jsonObject* resp ) {
+       if(!(ctx && resp)) return;
+
+       jsonObjectSetKey(resp, "api_name",      jsonNewObject(method->name));
+       jsonObjectSetKey(resp, "method",                jsonNewObject(method->symbol));
+       jsonObjectSetKey(resp, "service",       jsonNewObject(ctx->session->remote_service));
+       jsonObjectSetKey(resp, "notes",         jsonNewObject(method->notes));
+       jsonObjectSetKey(resp, "argc",          jsonNewNumberObject(method->argc));
+
+       jsonObjectSetKey(resp, "sysmethod", 
+                       jsonNewNumberObject( (method->options & OSRF_METHOD_SYSTEM) ? 1 : 0 ));
+       jsonObjectSetKey(resp, "atomic",                
+                       jsonNewNumberObject( (method->options & OSRF_METHOD_ATOMIC) ? 1 : 0 ));
+       jsonObjectSetKey(resp, "cachable",      
+                       jsonNewNumberObject( (method->options & OSRF_METHOD_CACHABLE) ? 1 : 0 ));
+
+       jsonObjectSetClass(resp, "method");
+}
+
+
+
+int __osrfAppRunSystemMethod(osrfMethodContext* ctx) {
+       OSRF_METHOD_VERIFY_CONTEXT(ctx);
+
+       if(     !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ALL ) || 
+                       !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ALL_ATOMIC )) {
+
+               return osrfAppIntrospectAll(ctx);
+       }
+
+
+       if(     !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT ) ||
+                       !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ATOMIC )) {
+
+               return osrfAppIntrospect(ctx);
+       }
+
+       if(     !strcmp(ctx->method->name, OSRF_SYSMETHOD_ECHO ) ||
+                       !strcmp(ctx->method->name, OSRF_SYSMETHOD_ECHO_ATOMIC )) {
+
+               return osrfAppEcho(ctx);
+       }
+
+
+       osrfAppRequestRespondException( ctx->session, 
+                       ctx->request, "System method implementation not found");
+
+       return 0;
+}
+
+
+int osrfAppIntrospect( osrfMethodContext* ctx ) {
+
+       jsonObject* resp = NULL;
+       char* methodSubstring = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) );
+       osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service );
+       int len = 0;
+
+       if(!methodSubstring) return 1; /* respond with no methods */
+
+       if(app) {
+
+               osrfHashIterator* itr = osrfNewHashIterator(app->methods);
+               osrfMethod* method;
+
+               while( (method = osrfHashIteratorNext(itr)) ) {
+                       if( (len = strlen(methodSubstring)) <= strlen(method->name) ) {
+                               if( !strncmp( method->name, methodSubstring, len) ) {
+                                       resp = jsonNewObject(NULL);
+                                       __osrfAppSetIntrospectMethod( ctx, method, resp );
+                                       osrfAppRespond(ctx, resp);
+                                       jsonObjectFree(resp);
+                               }
+                       }
+               }
+               osrfHashIteratorFree(itr);
+               return 1;
+       }
+
+       return -1;
+
+}
+
+
+int osrfAppIntrospectAll( osrfMethodContext* ctx ) {
+       jsonObject* resp = NULL;
+       osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service );
+
+       if(app) {
+               osrfHashIterator* itr = osrfNewHashIterator(app->methods);
+               osrfMethod* method;
+               while( (method = osrfHashIteratorNext(itr)) ) {
+                       resp = jsonNewObject(NULL);
+                       __osrfAppSetIntrospectMethod( ctx, method, resp );
+                       osrfAppRespond(ctx, resp);
+                       jsonObjectFree(resp);
+               }
+               osrfHashIteratorFree(itr);
+               return 1;
+       }
+
+       return -1;
+}
+
+int osrfAppEcho( osrfMethodContext* ctx ) {
+       OSRF_METHOD_VERIFY_CONTEXT(ctx);
+       int i;
+       for( i = 0; i < ctx->params->size; i++ ) {
+               jsonObject* str = jsonObjectGetIndex(ctx->params,i);
+               osrfAppRespond(ctx, str);
+       }
+       return 1;
+}
+
diff --git a/src/libopensrf/osrf_big_hash.c b/src/libopensrf/osrf_big_hash.c
new file mode 100644 (file)
index 0000000..3e69f2f
--- /dev/null
@@ -0,0 +1,173 @@
+#include <opensrf/osrf_big_hash.h>
+
+osrfBigHash* osrfNewBigHash() {
+       osrfBigHash* hash = safe_malloc(sizeof(osrfBigHash));
+       hash->hash = (Pvoid_t) NULL;
+       hash->freeItem = NULL;
+       return hash;
+}
+
+void* osrfBigHashSet( osrfBigHash* hash, void* item, const char* key, ... ) {
+       if(!(hash && item && key )) return NULL;
+
+       Word_t* value;
+       VA_LIST_TO_STRING(key);
+       uint8_t idx[strlen(VA_BUF) + 1];
+       strcpy( idx, VA_BUF );
+
+       void* olditem = osrfBigHashRemove( hash, VA_BUF );
+
+       JSLI(value, hash->hash, idx);
+       if(value) *value = (Word_t) item;
+       return olditem;
+       
+}
+
+void* osrfBigHashRemove( osrfBigHash* hash, const char* key, ... ) {
+       if(!(hash && key )) return NULL;
+
+       VA_LIST_TO_STRING(key);
+
+       Word_t* value;
+       uint8_t idx[strlen(VA_BUF) + 1];
+       strcpy( idx, VA_BUF );
+       void* item = NULL;
+       int retcode;
+
+       JSLG( value, hash->hash,  idx);
+
+       if( value ) {
+               item = (void*) *value;
+               if(item) {
+                       if( hash->freeItem ) {
+                               hash->freeItem( (char*) idx, item ); 
+                               item = NULL;
+                       }
+               }
+       }
+
+
+       JSLD( retcode, hash->hash, idx );
+
+       return item;
+}
+
+
+void* osrfBigHashGet( osrfBigHash* hash, const char* key, ... ) {
+       if(!(hash && key )) return NULL;
+
+       VA_LIST_TO_STRING(key);
+
+       Word_t* value;
+       uint8_t idx[strlen(VA_BUF) + 1];
+       strcpy( idx, VA_BUF );
+
+       JSLG( value, hash->hash, idx );
+       if(value) return (void*) *value;
+       return NULL;
+}
+
+
+osrfStringArray* osrfBigHashKeys( osrfBigHash* hash ) {
+       if(!hash) return NULL;
+
+       Word_t* value;
+       uint8_t idx[OSRF_HASH_MAXKEY];
+       strcpy(idx, "");
+       char* key;
+       osrfStringArray* strings = osrfNewStringArray(8);
+
+       JSLF( value, hash->hash, idx );
+
+       while( value ) {
+               key = (char*) idx;
+               osrfStringArrayAdd( strings, key );
+               JSLN( value, hash->hash, idx );
+       }
+
+       return strings;
+}
+
+
+unsigned long osrfBigHashGetCount( osrfBigHash* hash ) {
+       if(!hash) return -1;
+
+       Word_t* value;
+       unsigned long count = 0;
+       uint8_t idx[OSRF_HASH_MAXKEY];
+
+       strcpy( (char*) idx, "");
+       JSLF(value, hash->hash, idx);
+
+       while(value) {
+               count++;
+               JSLN( value, hash->hash, idx );
+       }
+
+       return count;
+}
+
+void osrfBigHashFree( osrfBigHash* hash ) {
+       if(!hash) return;
+
+       int i;
+       osrfStringArray* keys = osrfBigHashKeys( hash );
+
+       for( i = 0; i != keys->size; i++ )  {
+               char* key = (char*) osrfStringArrayGetString( keys, i );
+               osrfBigHashRemove( hash, key );
+       }
+
+       osrfStringArrayFree(keys);
+       free(hash);
+}
+
+
+
+osrfBigHashIterator* osrfNewBigHashIterator( osrfBigHash* hash ) {
+       if(!hash) return NULL;
+       osrfBigHashIterator* itr = safe_malloc(sizeof(osrfBigHashIterator));
+       itr->hash = hash;
+       itr->current = NULL;
+       return itr;
+}
+
+void* osrfBigHashIteratorNext( osrfBigHashIterator* itr ) {
+       if(!(itr && itr->hash)) return NULL;
+
+       Word_t* value;
+       uint8_t idx[OSRF_HASH_MAXKEY];
+
+       if( itr->current == NULL ) { /* get the first item in the list */
+               strcpy(idx, "");
+               JSLF( value, itr->hash->hash, idx );
+
+       } else {
+               strcpy(idx, itr->current);
+               JSLN( value, itr->hash->hash, idx );
+       }
+
+       if(value) {
+               free(itr->current);
+               itr->current = strdup((char*) idx);
+               return (void*) *value;
+       }
+
+       return NULL;
+
+}
+
+void osrfBigHashIteratorFree( osrfBigHashIterator* itr ) {
+       if(!itr) return;
+       free(itr->current);
+       free(itr);
+}
+
+void osrfBigHashIteratorReset( osrfBigHashIterator* itr ) {
+       if(!itr) return;
+       free(itr->current);
+       itr->current = NULL;
+}
+
+
+
diff --git a/src/libopensrf/osrf_big_list.c b/src/libopensrf/osrf_big_list.c
new file mode 100644 (file)
index 0000000..26ff7b6
--- /dev/null
@@ -0,0 +1,174 @@
+#include <opensrf/osrf_big_list.h>
+
+
+osrfBigList* osrfNewBigList() {
+       osrfBigList* list = safe_malloc(sizeof(osrfBigList));
+       list->list = (Pvoid_t) NULL;
+       list->size = 0;
+       list->freeItem = NULL;
+       return list;
+}
+
+
+int osrfBigListPush( osrfBigList* list, void* item ) {
+       if(!(list && item)) return -1;
+       Word_t* value;
+       unsigned long index = -1;
+       JLL(value, list->list, index );
+       osrfBigListSet( list, item, index+1 );
+       return 0;
+}
+
+
+void* osrfBigListSet( osrfBigList* list, void* item, unsigned long position ) {
+       if(!list || position < 0) return NULL;
+
+       Word_t* value;
+       void* olditem = osrfBigListRemove( list, position );
+
+       JLI( value, list->list, position ); 
+       *value = (Word_t) item;
+       __osrfBigListSetSize( list );
+
+       return olditem;
+}
+
+
+void* osrfBigListGetIndex( osrfBigList* list, unsigned long position ) {
+       if(!list) return NULL;
+
+       Word_t* value;
+       JLG( value, list->list, position );
+       if(value) return (void*) *value;
+       return NULL;
+}
+
+void osrfBigListFree( osrfBigList* list ) {
+       if(!list) return;
+
+       Word_t* value;
+       unsigned long index = -1;
+       JLL(value, list->list, index );
+       int retcode;
+
+       while (value != NULL) {
+               if(list->freeItem) 
+                       list->freeItem( (void*) *value );
+               JLD(retcode, list->list, index);
+               JLP(value, list->list, index);
+       }               
+
+       free(list);
+}
+
+void* osrfBigListRemove( osrfBigList* list, int position ) {
+       if(!list) return NULL;
+
+       int retcode;
+       Word_t* value;
+       JLG( value, list->list, position );
+       void* olditem = NULL;
+
+       if( value ) {
+
+               olditem = (void*) *value;
+               if( olditem ) {
+                       JLD(retcode, list->list, position );
+                       if(retcode == 1) {
+                               if(list->freeItem) {
+                                       list->freeItem( olditem );
+                                       olditem = NULL;
+                               }
+                               __osrfBigListSetSize( list );
+                       }
+               }
+       }
+
+       return olditem;
+}
+
+
+int osrfBigListFind( osrfBigList* list, void* addr ) {
+       if(!(list && addr)) return -1;
+
+       Word_t* value;
+       unsigned long index = -1;
+       JLL(value, list->list, index );
+
+       while (value != NULL) {
+               if( (void*) *value == addr )
+                       return index;
+               JLP(value, list->list, index);
+       }
+
+       return -1;
+}
+
+
+
+void __osrfBigListSetSize( osrfBigList* list ) {
+       if(!list) return;
+
+       Word_t* value;
+       unsigned long index = -1;
+       JLL(value, list->list, index );
+       list->size = index + 1;
+}
+
+
+unsigned long osrfBigListGetCount( osrfBigList* list ) {
+       if(!list) return -1;
+       unsigned long retcode = -1;
+       JLC( retcode, list->list, 0, -1 );
+       return retcode;
+}
+
+
+void* osrfBigListPop( osrfBigList* list ) {
+       if(!list) return NULL;
+       return osrfBigListRemove( list, list->size - 1 );
+}
+
+
+osrfBigBigListIterator* osrfNewBigListIterator( osrfBigList* list ) {
+       if(!list) return NULL;
+       osrfBigBigListIterator* itr = safe_malloc(sizeof(osrfBigBigListIterator));
+       itr->list = list;
+       itr->current = 0;
+       return itr;
+}
+
+void* osrfBigBigListIteratorNext( osrfBigBigListIterator* itr ) {
+       if(!(itr && itr->list)) return NULL;
+
+       Word_t* value;
+       if(itr->current >= itr->list->size) return NULL;
+       JLF( value, itr->list->list, itr->current );
+       if(value) {
+               itr->current++;
+               return (void*) *value;
+       }
+       return NULL;
+}
+
+void osrfBigBigListIteratorFree( osrfBigBigListIterator* itr ) {
+       if(!itr) return;
+       free(itr);
+}
+
+
+
+void osrfBigBigListIteratorReset( osrfBigBigListIterator* itr ) {
+       if(!itr) return;
+       itr->current = 0;
+}
+
+
+void osrfBigListVanillaFree( void* item ) {
+       free(item);
+}
+
+void osrfBigListSetDefaultFree( osrfBigList* list ) {
+       if(!list) return;
+       list->freeItem = osrfBigListVanillaFree;
+}
diff --git a/src/libopensrf/osrf_cache.c b/src/libopensrf/osrf_cache.c
new file mode 100644 (file)
index 0000000..940af11
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+Bill Erickson <highfalutin@gmail.com>
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+#include <opensrf/osrf_cache.h>
+
+struct memcache* __osrfCache = NULL;
+time_t __osrfCacheMaxSeconds = -1;
+
+int osrfCacheInit( char* serverStrings[], int size, time_t maxCacheSeconds ) {
+       if( !(serverStrings && size > 0) ) return -1;
+
+       int i;
+       __osrfCache = mc_new();
+       __osrfCacheMaxSeconds = maxCacheSeconds;
+
+       for( i = 0; i < size && serverStrings[i]; i++ ) 
+               mc_server_add4( __osrfCache, serverStrings[i] );
+
+       return 0;
+}
+
+int osrfCachePutObject( char* key, const jsonObject* obj, time_t seconds ) {
+       if( !(key && obj) ) return -1;
+       char* s = jsonObjectToJSON( obj );
+       osrfLogInternal( OSRF_LOG_MARK, "osrfCachePut(): Putting object: %s", s);
+       if( seconds < 0 ) seconds = __osrfCacheMaxSeconds;
+
+       mc_set(__osrfCache, key, strlen(key), s, strlen(s), seconds, 0);
+       free(s);
+       return 0;
+}
+
+int osrfCachePutString( char* key, const char* value, time_t seconds ) {
+       if( !(key && value) ) return -1;
+       if( seconds < 0 ) seconds = __osrfCacheMaxSeconds;
+       osrfLogInternal( OSRF_LOG_MARK, "osrfCachePutString(): Putting string: %s", value);
+       mc_set(__osrfCache, key, strlen(key), value, strlen(value), seconds, 0);
+       return 0;
+}
+
+jsonObject* osrfCacheGetObject( char* key, ... ) {
+       jsonObject* obj = NULL;
+       if( key ) {
+               VA_LIST_TO_STRING(key);
+               char* data = (char*) mc_aget( __osrfCache, VA_BUF, strlen(VA_BUF) );
+               if( data ) {
+                       osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetObject(): Returning object: %s", data);
+                       obj = jsonParseString( data );
+                       return obj;
+               }
+               osrfLogWarning(OSRF_LOG_MARK, "No cache data exists with key %s", VA_BUF);
+       }
+       return NULL;
+}
+
+char* osrfCacheGetString( char* key, ... ) {
+       if( key ) {
+               VA_LIST_TO_STRING(key);
+               char* data = (char*) mc_aget(__osrfCache, VA_BUF, strlen(VA_BUF) );
+               osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetObject(): Returning object: %s", data);
+               if(!data) osrfLogWarning(OSRF_LOG_MARK, "No cache data exists with key %s", VA_BUF);
+               return data;
+       }
+       return NULL;
+}
+
+
+int osrfCacheRemove( char* key, ... ) {
+       if( key ) {
+               VA_LIST_TO_STRING(key);
+               return mc_delete(__osrfCache, VA_BUF, strlen(VA_BUF), 0 );
+       }
+       return -1;
+}
+
+
+int osrfCacheSetExpire( time_t seconds, char* key, ... ) {
+       if( key ) {
+               VA_LIST_TO_STRING(key);
+               jsonObject* o = osrfCacheGetObject( VA_BUF );
+               //osrfCacheRemove(VA_BUF);
+               return osrfCachePutObject( VA_BUF, o, seconds );
+       }
+       return -1;
+}
+
+
diff --git a/src/libopensrf/osrf_hash.c b/src/libopensrf/osrf_hash.c
new file mode 100644 (file)
index 0000000..e00f09c
--- /dev/null
@@ -0,0 +1,242 @@
+#include <opensrf/osrf_hash.h>
+
+osrfHash* osrfNewHash() {
+       osrfHash* hash;
+       OSRF_MALLOC(hash, sizeof(osrfHash));
+       hash->hash              = osrfNewList();
+       hash->keys              = osrfNewStringArray(64);
+       return hash;
+}
+
+
+/* algorithm proposed by Donald E. Knuth 
+ * in The Art Of Computer Programming Volume 3 (more or less..)*/
+/*
+static unsigned int osrfHashMakeKey(char* str) {
+       if(!str) return 0;
+       unsigned int len = strlen(str);
+       unsigned int h = len;
+       unsigned int i = 0;
+       for(i = 0; i < len; str++, i++)
+               h = ((h << 5) ^ (h >> 27)) ^ (*str);
+       return (h & (OSRF_HASH_LIST_SIZE-1));
+}
+*/
+
+
+/* macro version of the above function */
+#define OSRF_HASH_MAKE_KEY(str,num) \
+   do {\
+      char* __k = str;\
+      unsigned int __len = strlen(__k); \
+      unsigned int __h = __len;\
+      unsigned int __i = 0;\
+      for(__i = 0; __i < __len; __k++, __i++)\
+         __h = ((__h << 5) ^ (__h >> 27)) ^ (*__k);\
+      num = (__h & (OSRF_HASH_LIST_SIZE-1));\
+   } while(0)
+
+
+
+/* returns the index of the item and points l to the sublist the item
+ * lives in if the item and points n to the hashnode the item 
+ * lives in if the item is found.  Otherwise -1 is returned */
+static unsigned int osrfHashFindItem( osrfHash* hash, char* key, osrfList** l, osrfHashNode** n ) {
+       if(!(hash && key)) return -1;
+
+
+       unsigned int i = 0;
+       OSRF_HASH_MAKE_KEY(key,i);
+
+       osrfList* list = OSRF_LIST_GET_INDEX( hash->hash, i );
+       if( !list ) { return -1; }
+
+       int k;
+       osrfHashNode* node = NULL;
+       for( k = 0; k < list->size; k++ ) {
+               node = OSRF_LIST_GET_INDEX(list, k);
+               if( node && node->key && !strcmp(node->key, key) )
+                       break;
+               node = NULL;
+       }
+
+       if(!node) return -1;
+
+       if(l) *l = list;
+       if(n) *n = node;
+       return k;
+}
+
+osrfHashNode* osrfNewHashNode(char* key, void* item) {
+       if(!(key && item)) return NULL;
+       osrfHashNode* n;
+       OSRF_MALLOC(n, sizeof(osrfHashNode));
+       n->key = strdup(key);
+       n->item = item;
+       return n;
+}
+
+void* osrfHashNodeFree(osrfHash* hash, osrfHashNode* node) {
+       if(!(node && hash)) return NULL;
+       void* item = NULL;
+       if( hash->freeItem )
+               hash->freeItem( node->key, node->item );
+       else item = node->item;
+       free(node->key);
+       free(node);
+       return item;
+}
+
+void* osrfHashSet( osrfHash* hash, void* item, const char* key, ... ) {
+       if(!(hash && item && key )) return NULL;
+
+       VA_LIST_TO_STRING(key);
+       void* olditem = osrfHashRemove( hash, VA_BUF );
+
+       unsigned int bucketkey = 0;
+       OSRF_HASH_MAKE_KEY(VA_BUF,bucketkey);
+       
+       osrfList* bucket;
+       if( !(bucket = OSRF_LIST_GET_INDEX(hash->hash, bucketkey)) ) {
+               bucket = osrfNewList();
+               osrfListSet( hash->hash, bucket, bucketkey );
+       }
+
+       osrfHashNode* node = osrfNewHashNode(VA_BUF, item);
+       osrfListPushFirst( bucket, node );
+
+       if(!osrfStringArrayContains(hash->keys, VA_BUF))
+               osrfStringArrayAdd( hash->keys, VA_BUF );
+
+       hash->size++;
+       return olditem;
+}
+
+void* osrfHashRemove( osrfHash* hash, const char* key, ... ) {
+       if(!(hash && key )) return NULL;
+
+       VA_LIST_TO_STRING(key);
+
+       osrfList* list = NULL;
+       osrfHashNode* node;
+       int index = osrfHashFindItem( hash, (char*) VA_BUF, &list, &node );
+       if( index == -1 ) return NULL;
+
+       osrfListRemove( list, index );
+       hash->size--;
+
+       void* item = osrfHashNodeFree(hash, node);
+       osrfStringArrayRemove(hash->keys, VA_BUF);
+       return item;
+}
+
+
+void* osrfHashGet( osrfHash* hash, const char* key, ... ) {
+       if(!(hash && key )) return NULL;
+       VA_LIST_TO_STRING(key);
+
+       osrfHashNode* node = NULL;
+       int index = osrfHashFindItem( hash, (char*) VA_BUF, NULL, &node );
+       if( index == -1 ) return NULL;
+       return node->item;
+}
+
+
+osrfStringArray* osrfHashKeysInc( osrfHash* hash ) {
+       if(!hash) return NULL;
+       return hash->keys;
+}
+
+osrfStringArray* osrfHashKeys( osrfHash* hash ) {
+       if(!hash) return NULL;
+       
+       int i, k;
+       osrfList* list;
+       osrfHashNode* node;
+       osrfStringArray* strings = osrfNewStringArray(8);
+
+       for( i = 0; i != hash->hash->size; i++ ) {
+               list = OSRF_LIST_GET_INDEX( hash->hash, i );
+               if(list) {
+                       for( k = 0; k != list->size; k++ ) {
+                               node = OSRF_LIST_GET_INDEX( list, k );  
+                               if( node ) osrfStringArrayAdd( strings, node->key );
+                       }
+               }
+       }
+
+       return strings;
+}
+
+
+unsigned long osrfHashGetCount( osrfHash* hash ) {
+       if(!hash) return -1;
+       return hash->size;
+}
+
+void osrfHashFree( osrfHash* hash ) {
+       if(!hash) return;
+
+       int i, j;
+       osrfList* list;
+       osrfHashNode* node;
+
+       for( i = 0; i != hash->hash->size; i++ ) {
+               if( ( list = OSRF_LIST_GET_INDEX( hash->hash, i )) ) {
+                       for( j = 0; j != list->size; j++ ) {
+                               if( (node = OSRF_LIST_GET_INDEX( list, j )) ) {
+                                       OSRF_HASH_NODE_FREE(hash, node);
+                               }
+                       }
+                       osrfListFree(list);
+               }
+       }
+
+       osrfListFree(hash->hash);
+       osrfStringArrayFree(hash->keys);
+       free(hash);
+}
+
+
+
+osrfHashIterator* osrfNewHashIterator( osrfHash* hash ) {
+       if(!hash) return NULL;
+       //osrfHashIterator* itr = safe_malloc(sizeof(osrfHashIterator));
+       osrfHashIterator* itr;
+       OSRF_MALLOC(itr, sizeof(osrfHashIterator));
+       itr->hash = hash;
+       itr->current = NULL;
+       itr->keys = osrfHashKeysInc(hash);
+       return itr;
+}
+
+void* osrfHashIteratorNext( osrfHashIterator* itr ) {
+       if(!(itr && itr->hash)) return NULL;
+       if( itr->currentIdx >= itr->keys->size ) return NULL;
+       free(itr->current);
+       itr->current = strdup(
+                       osrfStringArrayGetString(itr->keys, itr->currentIdx++));
+       char* val = osrfHashGet( itr->hash, itr->current );
+       return val;
+}
+
+void osrfHashIteratorFree( osrfHashIterator* itr ) {
+       if(!itr) return;
+       free(itr->current);
+       //osrfStringArrayFree(itr->keys);
+       free(itr);
+}
+
+void osrfHashIteratorReset( osrfHashIterator* itr ) {
+       if(!itr) return;
+       free(itr->current);
+       //osrfStringArrayFree(itr->keys);
+       itr->keys = osrfHashKeysInc(itr->hash);
+       itr->currentIdx = 0;
+       itr->current = NULL;
+}
+
+
+int osrfHashIteratorHasNext( osrfHashIterator* itr ) {
+       return ( itr->currentIdx < itr->keys->size ) ? 1 : 0;
+}
diff --git a/src/libopensrf/osrf_list.c b/src/libopensrf/osrf_list.c
new file mode 100644 (file)
index 0000000..2d37b02
--- /dev/null
@@ -0,0 +1,154 @@
+#include <opensrf/osrf_list.h>
+
+osrfList* osrfNewList() {
+       osrfList* list;
+       OSRF_MALLOC(list, sizeof(osrfList));
+       list->arrsize   = OSRF_LIST_DEFAULT_SIZE;
+       OSRF_MALLOC(list->arrlist, list->arrsize * sizeof(void*));
+       return list;
+}
+
+osrfList* osrfNewListSize( unsigned int size ) {
+       osrfList* list;
+       OSRF_MALLOC(list, sizeof(osrfList));
+    if( size <= 0 ) size = 16;
+       list->arrsize   = size;
+       OSRF_MALLOC( list->arrlist, list->arrsize * sizeof(void*) );
+       return list;
+}
+
+
+int osrfListPush( osrfList* list, void* item ) {
+       if(!(list)) return -1;
+       osrfListSet( list, item, list->size );
+       return 0;
+}
+
+int osrfListPushFirst( osrfList* list, void* item ) {
+       if(!(list && item)) return -1;
+       int i;
+       for( i = 0; i < list->size; i++ ) 
+               if(!list->arrlist[i]) break;
+       osrfListSet( list, item, i );
+       return list->size;
+}
+
+void* osrfListSet( osrfList* list, void* item, unsigned int position ) {
+       if(!list || position < 0) return NULL;
+
+       int i;
+       int newsize = list->arrsize;
+       void** newarr;
+
+       while( position >= newsize ) 
+               newsize += OSRF_LIST_INC_SIZE;
+
+       if( newsize > list->arrsize ) { /* expand the list if necessary */
+               OSRF_MALLOC(newarr, newsize * sizeof(void*));
+               for( i = 0; i < list->arrsize; i++ ) 
+                       newarr[i] = list->arrlist[i];
+               free(list->arrlist);
+               list->arrlist = newarr;
+               list->arrsize = newsize;
+       }
+
+       void* olditem = osrfListRemove( list, position );
+       list->arrlist[position] = item;
+       if( list->size <= position ) list->size = position + 1;
+       return olditem;
+}
+
+
+void* osrfListGetIndex( const osrfList* list, unsigned int position ) {
+       if(!list || position >= list->size || position < 0) return NULL;
+       return list->arrlist[position];
+}
+
+void osrfListFree( osrfList* list ) {
+       if(!list) return;
+
+       if( list->freeItem ) {
+               int i; void* val;
+               for( i = 0; i < list->size; i++ ) {
+                       if( (val = list->arrlist[i]) ) 
+                               list->freeItem(val);
+               }
+       }
+
+       free(list->arrlist);
+       free(list);
+}
+
+void* osrfListRemove( osrfList* list, unsigned int position ) {
+       if(!list || position >= list->size || position < 0) return NULL;
+
+       void* olditem = list->arrlist[position];
+       list->arrlist[position] = NULL;
+       if( list->freeItem ) {
+               list->freeItem(olditem);
+               olditem = NULL;
+       }
+
+       if( position == list->size - 1 ) list->size--;
+       return olditem;
+}
+
+
+int osrfListFind( const osrfList* list, void* addr ) {
+       if(!(list && addr)) return -1;
+       int index;
+       for( index = 0; index < list->size; index++ ) {
+               if( list->arrlist[index] == addr ) 
+                       return index;
+       }
+       return -1;
+}
+
+
+unsigned int osrfListGetCount( const osrfList* list ) {
+       if(!list) return -1;
+       return list->size;
+}
+
+
+void* osrfListPop( osrfList* list ) {
+       if(!list) return NULL;
+       return osrfListRemove( list, list->size - 1 );
+}
+
+
+osrfListIterator* osrfNewListIterator( const osrfList* list ) {
+       if(!list) return NULL;
+       osrfListIterator* itr;
+       OSRF_MALLOC(itr, sizeof(osrfListIterator));
+       itr->list = list;
+       itr->current = 0;
+       return itr;
+}
+
+void* osrfListIteratorNext( osrfListIterator* itr ) {
+       if(!(itr && itr->list)) return NULL;
+       if(itr->current >= itr->list->size) return NULL;
+       return itr->list->arrlist[itr->current++];
+}
+
+void osrfListIteratorFree( osrfListIterator* itr ) {
+       if(!itr) return;
+       free(itr);
+}
+
+
+void osrfListIteratorReset( osrfListIterator* itr ) {
+       if(!itr) return;
+       itr->current = 0;
+}
+
+
+void osrfListVanillaFree( void* item ) {
+       free(item);
+}
+
+void osrfListSetDefaultFree( osrfList* list ) {
+       if(!list) return;
+       list->freeItem = osrfListVanillaFree;
+}
diff --git a/src/libopensrf/osrf_message.c b/src/libopensrf/osrf_message.c
new file mode 100644 (file)
index 0000000..313216a
--- /dev/null
@@ -0,0 +1,330 @@
+#include <opensrf/osrf_message.h>
+
+osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
+
+       osrf_message* msg                       = (osrf_message*) safe_malloc(sizeof(osrf_message));
+       msg->m_type                                     = type;
+       msg->thread_trace                       = thread_trace;
+       msg->protocol                           = protocol;
+       msg->next                                       = NULL;
+       msg->is_exception                       = 0;
+       msg->_params                            = NULL;
+       msg->_result_content            = NULL;
+
+       return msg;
+}
+
+
+void osrf_message_set_method( osrf_message* msg, char* method_name ) {
+       if( msg == NULL || method_name == NULL ) return;
+       msg->method_name = strdup( method_name );
+}
+
+
+void osrf_message_add_object_param( osrf_message* msg, jsonObject* o ) {
+       if(!msg|| !o) return;
+       if(!msg->_params)
+               msg->_params = jsonParseString("[]");
+       char* j = jsonObjectToJSON(o);
+       jsonObjectPush(msg->_params, jsonParseString(j));
+       free(j);
+}
+
+void osrf_message_set_params( osrf_message* msg, jsonObject* o ) {
+       if(!msg || !o) return;
+
+       if(o->type != JSON_ARRAY) {
+               osrfLogDebug( OSRF_LOG_MARK, "passing non-array to osrf_message_set_params(), fixing...");
+               jsonObject* clone = jsonObjectClone(o);
+               o = jsonNewObject(NULL);
+               jsonObjectPush(o, clone);
+               if(msg->_params) jsonObjectFree(msg->_params);
+               msg->_params = o;
+               return;
+       }
+
+       if(msg->_params) jsonObjectFree(msg->_params);
+       msg->_params = jsonObjectClone(o);
+}
+
+
+/* only works if parse_json_params is false */
+void osrf_message_add_param( osrf_message* msg, char* param_string ) {
+       if(msg == NULL || param_string == NULL) return;
+       if(!msg->_params) msg->_params = jsonParseString("[]");
+       jsonObjectPush(msg->_params, jsonParseString(param_string));
+}
+
+
+void osrf_message_set_status_info( 
+               osrf_message* msg, char* status_name, char* status_text, int status_code ) {
+       if(!msg) return;
+
+       if( status_name != NULL ) 
+               msg->status_name = strdup( status_name );
+
+       if( status_text != NULL )
+               msg->status_text = strdup( status_text );
+
+       msg->status_code = status_code;
+}
+
+
+void osrf_message_set_result_content( osrf_message* msg, char* json_string ) {
+       if( msg == NULL || json_string == NULL) return;
+       msg->result_string =    strdup(json_string);
+       if(json_string) msg->_result_content = jsonParseString(json_string);
+}
+
+
+
+void osrfMessageFree( osrfMessage* msg ) {
+       osrf_message_free( msg );
+}
+
+void osrf_message_free( osrf_message* msg ) {
+       if( msg == NULL )
+               return;
+
+       if( msg->status_name != NULL )
+               free(msg->status_name);
+
+       if( msg->status_text != NULL )
+               free(msg->status_text);
+
+       if( msg->_result_content != NULL )
+               jsonObjectFree( msg->_result_content );
+
+       if( msg->result_string != NULL )
+               free( msg->result_string);
+
+       if( msg->method_name != NULL )
+               free(msg->method_name);
+
+       if( msg->_params != NULL )
+               jsonObjectFree(msg->_params);
+
+       free(msg);
+}
+
+
+char* osrfMessageSerializeBatch( osrfMessage* msgs [], int count ) {
+       if( !msgs ) return NULL;
+
+       char* j;
+       int i = 0;
+       osrfMessage* msg = NULL;
+       jsonObject* wrapper = jsonNewObject(NULL);
+
+       while( ((msg = msgs[i]) && (i++ < count)) ) 
+               jsonObjectPush(wrapper, osrfMessageToJSON( msg ));
+
+       j = jsonObjectToJSON(wrapper);
+       jsonObjectFree(wrapper);
+
+       return j;       
+}
+
+
+char* osrf_message_serialize(osrf_message* msg) {
+
+       if( msg == NULL ) return NULL;
+       char* j = NULL;
+
+       jsonObject* json = osrfMessageToJSON( msg );
+
+       if(json) {
+               jsonObject* wrapper = jsonNewObject(NULL);
+               jsonObjectPush(wrapper, json);
+               j = jsonObjectToJSON(wrapper);
+               jsonObjectFree(wrapper);
+       }
+
+       return j;
+}
+
+
+jsonObject* osrfMessageToJSON( osrfMessage* msg ) {
+
+       jsonObject* json = jsonNewObject(NULL);
+       jsonObjectSetClass(json, "osrfMessage");
+       jsonObject* payload;
+       char sc[64]; memset(sc,0,64);
+
+       char* str;
+
+       INT_TO_STRING(msg->thread_trace);
+       jsonObjectSetKey(json, "threadTrace", jsonNewObject(INTSTR));
+
+       switch(msg->m_type) {
+               
+               case CONNECT: 
+                       jsonObjectSetKey(json, "type", jsonNewObject("CONNECT"));
+                       break;
+
+               case DISCONNECT: 
+                       jsonObjectSetKey(json, "type", jsonNewObject("DISCONNECT"));
+                       break;
+
+               case STATUS:
+                       jsonObjectSetKey(json, "type", jsonNewObject("STATUS"));
+                       payload = jsonNewObject(NULL);
+                       jsonObjectSetClass(payload, msg->status_name);
+                       jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
+         sprintf(sc,"%d",msg->status_code);
+                       jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
+                       jsonObjectSetKey(json, "payload", payload);
+                       break;
+
+               case REQUEST:
+                       jsonObjectSetKey(json, "type", jsonNewObject("REQUEST"));
+                       payload = jsonNewObject(NULL);
+                       jsonObjectSetClass(payload, "osrfMethod");
+                       jsonObjectSetKey(payload, "method", jsonNewObject(msg->method_name));
+                       str = jsonObjectToJSON(msg->_params);
+                       jsonObjectSetKey(payload, "params", jsonParseString(str));
+                       free(str);
+                       jsonObjectSetKey(json, "payload", payload);
+
+                       break;
+
+               case RESULT:
+                       jsonObjectSetKey(json, "type", jsonNewObject("RESULT"));
+                       payload = jsonNewObject(NULL);
+                       jsonObjectSetClass(payload,"osrfResult");
+                       jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
+         sprintf(sc,"%d",msg->status_code);
+                       jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
+                       str = jsonObjectToJSON(msg->_result_content);
+                       jsonObjectSetKey(payload, "content", jsonParseString(str));
+                       free(str);
+                       jsonObjectSetKey(json, "payload", payload);
+                       break;
+       }
+
+       return json;
+}
+
+
+int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) {
+
+       if(!string || !msgs || count <= 0) return 0;
+       int numparsed = 0;
+
+       jsonObject* json = jsonParseString(string);
+
+       if(!json) {
+               osrfLogWarning( OSRF_LOG_MARK, 
+                       "osrf_message_deserialize() unable to parse data: \n%s\n", string);
+               return 0;
+       }
+
+       int x;
+
+       for( x = 0; x < json->size && x < count; x++ ) {
+
+               jsonObject* message = jsonObjectGetIndex(json, x);
+
+               if(message && message->type != JSON_NULL && 
+                       message->classname && !strcmp(message->classname, "osrfMessage")) {
+
+                       osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
+
+                       jsonObject* tmp = jsonObjectGetKey(message, "type");
+
+                       char* t;
+                       if( ( t = jsonObjectGetString(tmp)) ) {
+
+                               if(!strcmp(t, "CONNECT"))               new_msg->m_type = CONNECT;
+                               if(!strcmp(t, "DISCONNECT"))    new_msg->m_type = DISCONNECT;
+                               if(!strcmp(t, "STATUS"))                new_msg->m_type = STATUS;
+                               if(!strcmp(t, "REQUEST"))               new_msg->m_type = REQUEST;
+                               if(!strcmp(t, "RESULT"))                new_msg->m_type = RESULT;
+                       }
+
+                       tmp = jsonObjectGetKey(message, "threadTrace");
+                       if(tmp) {
+                               char* tt = jsonObjectToSimpleString(tmp);
+                               if(tt) {
+                                       new_msg->thread_trace = atoi(tt);
+                                       free(tt);
+                               }
+                               /*
+                               if(tmp->type == JSON_NUMBER)
+                                       new_msg->thread_trace = (int) jsonObjectGetNumber(tmp);
+                               if(tmp->type == JSON_STRING)
+                                       new_msg->thread_trace = atoi(jsonObjectGetString(tmp));
+                                       */
+                       }
+
+
+                       tmp = jsonObjectGetKey(message, "protocol");
+
+                       if(tmp) {
+                               char* proto = jsonObjectToSimpleString(tmp);
+                               if(proto) {
+                                       new_msg->protocol = atoi(proto);
+                                       free(proto);
+                               }
+
+                               /*
+                               if(tmp->type == JSON_NUMBER)
+                                       new_msg->protocol = (int) jsonObjectGetNumber(tmp);
+                               if(tmp->type == JSON_STRING)
+                                       new_msg->protocol = atoi(jsonObjectGetString(tmp));
+                                       */
+                       }
+
+                       tmp = jsonObjectGetKey(message, "payload");
+                       if(tmp) {
+                               if(tmp->classname)
+                                       new_msg->status_name = strdup(tmp->classname);
+
+                               jsonObject* tmp0 = jsonObjectGetKey(tmp,"method");
+                               if(jsonObjectGetString(tmp0))
+                                       new_msg->method_name = strdup(jsonObjectGetString(tmp0));
+
+                               tmp0 = jsonObjectGetKey(tmp,"params");
+                               if(tmp0) {
+                                       char* s = jsonObjectToJSON(tmp0);
+                                       new_msg->_params = jsonParseString(s);
+                                       if(new_msg->_params && new_msg->_params->type == JSON_NULL) 
+                                               new_msg->_params->type = JSON_ARRAY;
+                                       free(s);
+                               }
+
+                               tmp0 = jsonObjectGetKey(tmp,"status");
+                               if(jsonObjectGetString(tmp0))
+                                       new_msg->status_text = strdup(jsonObjectGetString(tmp0));
+
+                               tmp0 = jsonObjectGetKey(tmp,"statusCode");
+                               if(tmp0) {
+                                       if(jsonObjectGetString(tmp0))
+                                               new_msg->status_code = atoi(jsonObjectGetString(tmp0));
+                                       if(tmp0->type == JSON_NUMBER)
+                                               new_msg->status_code = (int) jsonObjectGetNumber(tmp0);
+                               }
+
+                               tmp0 = jsonObjectGetKey(tmp,"content");
+                               if(tmp0) {
+                                       char* s = jsonObjectToJSON(tmp0);
+                                       new_msg->_result_content = jsonParseString(s);
+                                       free(s);
+                               }
+
+                       }
+                       msgs[numparsed++] = new_msg;
+               }
+       }
+
+       jsonObjectFree(json);
+       return numparsed;
+}
+
+
+
+jsonObject* osrfMessageGetResult( osrfMessage* msg ) {
+       if(msg) return msg->_result_content;
+       return NULL;
+}
+
diff --git a/src/libopensrf/osrf_prefork.c b/src/libopensrf/osrf_prefork.c
new file mode 100644 (file)
index 0000000..01a97cc
--- /dev/null
@@ -0,0 +1,765 @@
+#include <opensrf/osrf_prefork.h>
+#include <opensrf/osrf_app_session.h>
+#include <opensrf/osrf_application.h>
+#include <signal.h>
+
+/* true if we just deleted a child.  This will allow us to make sure we're
+       not trying to use freed memory */
+int child_dead;
+
+int main();
+void sigchld_handler( int sig );
+
+int osrf_prefork_run(char* appname) {
+
+       if(!appname) {
+               osrfLogError( OSRF_LOG_MARK, "osrf_prefork_run requires an appname to run!");
+               return -1;
+       }
+
+       set_proc_title( "OpenSRF Listener [%s]", appname );
+
+       int maxr = 1000; 
+       int maxc = 10;
+       int minc = 3;
+
+       osrfLogInfo( OSRF_LOG_MARK, "Loading config in osrf_forker for app %s", appname);
+
+       jsonObject* max_req = osrf_settings_host_value_object("/apps/%s/unix_config/max_requests", appname);
+       jsonObject* min_children = osrf_settings_host_value_object("/apps/%s/unix_config/min_children", appname);
+       jsonObject* max_children = osrf_settings_host_value_object("/apps/%s/unix_config/max_children", appname);
+
+       char* keepalive = osrf_settings_host_value("/apps/%s/keepalive", appname);
+       time_t kalive;
+       if( keepalive ) {
+               kalive = atoi(keepalive);
+               free(keepalive);
+       } else {
+               kalive = 5; /* give it a default */
+       }
+
+       osrfLogInfo(OSRF_LOG_MARK, "keepalive setting = %d seconds", kalive);
+
+
+       
+       if(!max_req) osrfLogWarning( OSRF_LOG_MARK, "Max requests not defined, assuming 1000");
+       else maxr = (int) jsonObjectGetNumber(max_req);
+
+       if(!min_children) osrfLogWarning( OSRF_LOG_MARK, "Min children not defined, assuming 3");
+       else minc = (int) jsonObjectGetNumber(min_children);
+
+       if(!max_children) osrfLogWarning( OSRF_LOG_MARK, "Max children not defined, assuming 10");
+       else maxc = (int) jsonObjectGetNumber(max_children);
+
+       jsonObjectFree(max_req);
+       jsonObjectFree(min_children);
+       jsonObjectFree(max_children);
+       /* --------------------------------------------------- */
+
+       char* resc = va_list_to_string("%s_listener", appname);
+
+       if(!osrf_system_bootstrap_client_resc( NULL, NULL, resc )) {
+               osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()");
+               free(resc);
+               return -1;
+       }
+
+       free(resc);
+
+       prefork_simple* forker = prefork_simple_init(
+               osrfSystemGetTransportClient(), maxr, minc, maxc);
+
+       forker->appname = strdup(appname);
+       forker->keepalive       = kalive;
+
+       if(forker == NULL) {
+               osrfLogError( OSRF_LOG_MARK, "osrf_prefork_run() failed to create prefork_simple object");
+               return -1;
+       }
+
+       prefork_launch_children(forker);
+
+       osrf_prefork_register_routers(appname);
+       
+       osrfLogInfo( OSRF_LOG_MARK, "Launching osrf_forker for app %s", appname);
+       prefork_run(forker);
+       
+       osrfLogWarning( OSRF_LOG_MARK, "prefork_run() retuned - how??");
+       prefork_free(forker);
+       return 0;
+
+}
+
+void osrf_prefork_register_routers( char* appname ) {
+
+       osrfStringArray* arr = osrfNewStringArray(4);
+
+       int c = osrfConfigGetValueList( NULL, arr, "/routers/router" );
+       char* routerName = osrfConfigGetValue( NULL, "/router_name" );
+       transport_client* client = osrfSystemGetTransportClient();
+
+       osrfLogInfo( OSRF_LOG_MARK, "router name is %s and we have %d routers to connect to", routerName, c );
+
+       while( c ) {
+               char* domain = osrfStringArrayGetString(arr, --c);
+               if(domain) {
+
+                       char* jid = va_list_to_string( "%s@%s/router", routerName, domain );
+                       osrfLogInfo( OSRF_LOG_MARK, "Registering with router %s", jid );
+
+                       transport_message* msg = message_init("registering", NULL, NULL, jid, NULL );
+                       message_set_router_info( msg, NULL, NULL, appname, "register", 0 );
+
+                       client_send_message( client, msg );
+                       message_free( msg );
+                       free(jid);
+               }
+       }
+
+       free(routerName);
+       osrfStringArrayFree(arr);
+}
+
+int prefork_child_init_hook(prefork_child* child) {
+
+       if(!child) return -1;
+       osrfLogDebug( OSRF_LOG_MARK, "Child init hook for child %d", child->pid);
+       char* resc = va_list_to_string("%s_drone",child->appname);
+
+   /* if we're a source-client, tell the logger now that we're a new process*/
+   char* isclient = osrfConfigGetValue(NULL, "/client");
+   if( isclient && !strcasecmp(isclient,"true") )
+      osrfLogSetIsClient(1);
+   free(isclient);
+
+
+       /* we want to remove traces of our parents socket connection 
+        * so we can have our own */
+       osrfSystemIgnoreTransportClient();
+
+       if(!osrf_system_bootstrap_client_resc( NULL, NULL, resc)) {
+               osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()");
+               free(resc);
+               return -1;
+       }
+
+       free(resc);
+
+       if( ! osrfAppRunChildInit(child->appname) ) {
+               osrfLogDebug(OSRF_LOG_MARK, "Prefork child_init succeeded\n");
+       } else {
+               osrfLogError(OSRF_LOG_MARK, "Prefork child_init failed\n");
+               return -1;
+       }
+
+       set_proc_title( "OpenSRF Drone [%s]", child->appname );
+       return 0;
+}
+
+void prefork_child_process_request(prefork_child* child, char* data) {
+       if( !child ) return;
+
+       transport_client* client = osrfSystemGetTransportClient();
+
+       if(!client_connected(client)) {
+               osrfSystemIgnoreTransportClient();
+               osrfLogWarning(OSRF_LOG_MARK, "Reconnecting child to opensrf after disconnect...");
+               if(!osrf_system_bootstrap_client(NULL, NULL)) {
+                       osrfLogError( OSRF_LOG_MARK, 
+                               "Unable to bootstrap client in prefork_child_process_request()");
+                       sleep(1);
+         osrf_prefork_child_exit(child);
+               }
+       }
+
+       /* construct the message from the xml */
+       transport_message* msg = new_message_from_xml( data );
+
+       osrfAppSession* session = osrf_stack_transport_handler(msg, child->appname);
+       if(!session) return;
+
+       if( session->stateless && session->state != OSRF_SESSION_CONNECTED ) {
+               osrfAppSessionFree( session );
+               return;
+       }
+
+       osrfLogDebug( OSRF_LOG_MARK, "Entering keepalive loop for session %s", session->session_id );
+       int keepalive = child->keepalive;
+       int retval;
+       int recvd;
+       time_t start;
+       time_t end;
+
+       while(1) {
+
+               osrfLogDebug(OSRF_LOG_MARK, 
+                               "osrf_prefork calling queue_wait [%d] in keepalive loop", keepalive);
+               start           = time(NULL);
+               retval  = osrf_app_session_queue_wait(session, keepalive, &recvd);
+               end             = time(NULL);
+
+               osrfLogDebug(OSRF_LOG_MARK, "Data received == %d", recvd);
+
+               if(retval) {
+                       osrfLogError(OSRF_LOG_MARK, "queue-wait returned non-success %d", retval);
+                       break;
+               }
+
+               /* see if the client disconnected from us */
+               if(session->state != OSRF_SESSION_CONNECTED) break;
+
+               /* if no data was reveived within the timeout interval */
+               if( !recvd && (end - start) >= keepalive ) {
+                       osrfLogInfo(OSRF_LOG_MARK, "No request was reveived in %d seconds, exiting stateful session", keepalive);
+                       osrfAppSessionStatus( 
+                                       session, 
+                                       OSRF_STATUS_TIMEOUT, 
+                                       "osrfConnectStatus", 
+                                       0, "Disconnected on timeout" );
+
+                       break;
+               }
+       }
+
+       osrfLogDebug( OSRF_LOG_MARK, "Exiting keepalive loop for session %s", session->session_id );
+       osrfAppSessionFree( session );
+       return;
+}
+
+
+prefork_simple*  prefork_simple_init( transport_client* client, 
+               int max_requests, int min_children, int max_children ) {
+
+       if( min_children > max_children ) {
+               osrfLogError( OSRF_LOG_MARK,  "min_children (%d) is greater "
+                               "than max_children (%d)", min_children, max_children );
+               return NULL;
+       }
+
+       if( max_children > ABS_MAX_CHILDREN ) {
+               osrfLogError( OSRF_LOG_MARK,  "max_children (%d) is greater than ABS_MAX_CHILDREN (%d)",
+                               max_children, ABS_MAX_CHILDREN );
+               return NULL;
+       }
+
+       osrfLogInfo(OSRF_LOG_MARK, "Prefork launching child with max_request=%d,"
+               "min_children=%d, max_children=%d", max_requests, min_children, max_children );
+
+       /* flesh out the struct */
+       prefork_simple* prefork = (prefork_simple*) safe_malloc(sizeof(prefork_simple));        
+       prefork->max_requests = max_requests;
+       prefork->min_children = min_children;
+       prefork->max_children = max_children;
+       prefork->first_child = NULL;
+       prefork->connection = client;
+
+       return prefork;
+}
+
+prefork_child*  launch_child( prefork_simple* forker ) {
+
+       pid_t pid;
+       int data_fd[2];
+       int status_fd[2];
+
+       /* Set up the data pipes and add the child struct to the parent */
+       if( pipe(data_fd) < 0 ) { /* build the data pipe*/
+               osrfLogError( OSRF_LOG_MARK,  "Pipe making error" );
+               return NULL;
+       }
+
+       if( pipe(status_fd) < 0 ) {/* build the status pipe */
+               osrfLogError( OSRF_LOG_MARK,  "Pipe making error" );
+               return NULL;
+       }
+
+       osrfLogInternal( OSRF_LOG_MARK,  "Pipes: %d %d %d %d", data_fd[0], data_fd[1], status_fd[0], status_fd[1] );
+       prefork_child* child = prefork_child_init( forker->max_requests, data_fd[0], 
+                       data_fd[1], status_fd[0], status_fd[1] );
+
+       child->appname = strdup(forker->appname);
+       child->keepalive = forker->keepalive;
+
+
+       add_prefork_child( forker, child );
+
+       if( (pid=fork()) < 0 ) {
+               osrfLogError( OSRF_LOG_MARK,  "Forking Error" );
+               return NULL;
+       }
+
+       if( pid > 0 ) {  /* parent */
+
+               signal(SIGCHLD, sigchld_handler);
+               (forker->current_num_children)++;
+               child->pid = pid;
+
+               osrfLogDebug( OSRF_LOG_MARK,  "Parent launched %d", pid );
+               /* *no* child pipe FD's can be closed or the parent will re-use fd's that
+                       the children are currently using */
+               return child;
+       }
+
+       else { /* child */
+
+               osrfLogInternal( OSRF_LOG_MARK, "I am  new child with read_data_fd = %d and write_status_fd = %d",
+                       child->read_data_fd, child->write_status_fd );
+
+               child->pid = getpid();
+               close( child->write_data_fd );
+               close( child->read_status_fd );
+
+               /* do the initing */
+               if( prefork_child_init_hook(child) == -1 ) {
+                       osrfLogError(OSRF_LOG_MARK, 
+                               "Forker child going away because we could not connect to OpenSRF...");
+         osrf_prefork_child_exit(child);
+               }
+
+               prefork_child_wait( child );
+      osrf_prefork_child_exit(child); /* just to be sure */
+        }
+       return NULL;
+}
+
+void osrf_prefork_child_exit(prefork_child* child) {
+   osrfAppRunExitCode();
+   exit(0);
+}
+
+void prefork_launch_children( prefork_simple* forker ) {
+       if(!forker) return;
+       int c = 0;
+       while( c++ < forker->min_children )
+               launch_child( forker );
+}
+
+
+void sigchld_handler( int sig ) {
+       signal(SIGCHLD, sigchld_handler);
+       child_dead = 1;
+}
+
+
+void reap_children( prefork_simple* forker ) {
+
+       pid_t child_pid;
+       int status;
+
+       while( (child_pid=waitpid(-1,&status,WNOHANG)) > 0) 
+               del_prefork_child( forker, child_pid ); 
+
+       /* replenish */
+       while( forker->current_num_children < forker->min_children ) 
+               launch_child( forker );
+
+       child_dead = 0;
+}
+
+void prefork_run(prefork_simple* forker) {
+
+       if( forker->first_child == NULL )
+               return;
+
+       transport_message* cur_msg = NULL;
+
+
+       while(1) {
+
+               if( forker->first_child == NULL ) {/* no more children */
+                       osrfLogWarning( OSRF_LOG_MARK, "No more children..." );
+                       return;
+               }
+
+               osrfLogDebug( OSRF_LOG_MARK, "Forker going into wait for data...");
+               cur_msg = client_recv( forker->connection, -1 );
+
+               //fprintf(stderr, "Got Data %f\n", get_timestamp_millis() );
+
+               if( cur_msg == NULL ) continue;
+
+               int honored = 0;        /* true if we've serviced the request */
+               int no_recheck = 0;
+
+               while( ! honored ) {
+
+                       if(!no_recheck) check_children( forker, 0 ); 
+                       no_recheck = 0;
+
+                       osrfLogDebug( OSRF_LOG_MARK,  "Server received inbound data" );
+                       int k;
+                       prefork_child* cur_child = forker->first_child;
+
+                       /* Look for an available child */
+                       for( k = 0; k < forker->current_num_children; k++ ) {
+
+                               osrfLogInternal( OSRF_LOG_MARK, "Searching for available child. cur_child->pid = %d", cur_child->pid );
+                               osrfLogInternal( OSRF_LOG_MARK, "Current num children %d and loop %d", forker->current_num_children, k);
+                       
+                               if( cur_child->available ) {
+                                       osrfLogDebug( OSRF_LOG_MARK,  "forker sending data to %d", cur_child->pid );
+
+                                       message_prepare_xml( cur_msg );
+                                       char* data = cur_msg->msg_xml;
+                                       if( ! data || strlen(data) < 1 ) break;
+
+                                       cur_child->available = 0;
+                                       osrfLogInternal( OSRF_LOG_MARK,  "Writing to child fd %d", cur_child->write_data_fd );
+
+                                       int written = 0;
+                                       //fprintf(stderr, "Writing Data %f\n", get_timestamp_millis() );
+                                       if( (written = write( cur_child->write_data_fd, data, strlen(data) + 1 )) < 0 ) {
+                                               osrfLogWarning( OSRF_LOG_MARK, "Write returned error %d", errno);
+                                               cur_child = cur_child->next;
+                                               continue;
+                                       }
+
+                                       //fprintf(stderr, "Wrote %d bytes to child\n", written);
+
+                                       forker->first_child = cur_child->next;
+                                       honored = 1;
+                                       break;
+                               } else 
+                                       cur_child = cur_child->next;
+                       } 
+
+                       /* if none available, add a new child if we can */
+                       if( ! honored ) {
+                               osrfLogDebug( OSRF_LOG_MARK, "Not enough children, attempting to add...");
+
+                               if( forker->current_num_children < forker->max_children ) {
+                                       osrfLogDebug( OSRF_LOG_MARK,  "Launching new child with current_num = %d",
+                                                       forker->current_num_children );
+
+                                       prefork_child* new_child = launch_child( forker );
+                    if( new_child ) {
+
+                                           message_prepare_xml( cur_msg );
+                                           char* data = cur_msg->msg_xml;
+
+                        if( data ) {
+                            int len = strlen(data);
+
+                            if( len > 0 ) {
+                                                   new_child->available = 0;
+                                                   osrfLogDebug( OSRF_LOG_MARK,  "Writing to new child fd %d : pid %d", 
+                                                               new_child->write_data_fd, new_child->pid );
+        
+                                                   if( write( new_child->write_data_fd, data, len + 1 ) >= 0 ) {
+                                                       forker->first_child = new_child->next;
+                                                       honored = 1;
+                                }
+                            }
+                        }
+                    }
+
+                               }
+                       }
+
+                       if( !honored ) {
+                               osrfLogWarning( OSRF_LOG_MARK,  "No children available, waiting...");
+
+                               check_children( forker, 1 );  /* non-poll version */
+                               /* tell the loop no to call check_children again, since we're calling it now */
+                               no_recheck = 1;
+                       }
+
+                       if( child_dead )
+                               reap_children(forker);
+
+
+                       //fprintf(stderr, "Parent done with request %f\n", get_timestamp_millis() );
+
+               } // honored?
+
+               message_free( cur_msg );
+
+       } /* top level listen loop */
+
+}
+
+
+/** XXX Add a flag which tells select() to wait forever on children
+ * in the best case, this will be faster than calling usleep(x), and
+ * in the worst case it won't be slower and will do less logging...
+ */
+
+void check_children( prefork_simple* forker, int forever ) {
+
+       //check_begin:
+
+       int select_ret;
+       fd_set read_set;
+       FD_ZERO(&read_set);
+       int max_fd = 0;
+       int n;
+
+
+       if( child_dead )
+               reap_children(forker);
+
+       prefork_child* cur_child = forker->first_child;
+
+       int i;
+       for( i = 0; i!= forker->current_num_children; i++ ) {
+
+               if( cur_child->read_status_fd > max_fd )
+                       max_fd = cur_child->read_status_fd;
+               FD_SET( cur_child->read_status_fd, &read_set );
+               cur_child = cur_child->next;
+       }
+
+       FD_CLR(0,&read_set);/* just to be sure */
+
+       if( forever ) {
+               osrfLogWarning(OSRF_LOG_MARK, "We have no children available - waiting for one to show up...");
+
+               if( (select_ret=select( max_fd + 1 , &read_set, NULL, NULL, NULL)) == -1 ) {
+                       osrfLogWarning( OSRF_LOG_MARK,  "Select returned error %d on check_children", errno );
+               }
+               osrfLogInfo(OSRF_LOG_MARK, "select() completed after waiting on children to become available");
+
+       } else {
+
+               struct timeval tv;
+               tv.tv_sec       = 0;
+               tv.tv_usec      = 0;
+       
+               if( (select_ret=select( max_fd + 1 , &read_set, NULL, NULL, &tv)) == -1 ) {
+                       osrfLogWarning( OSRF_LOG_MARK,  "Select returned error %d on check_children", errno );
+               }
+       }
+
+       if( select_ret == 0 )
+               return;
+
+       /* see if one of a child has told us it's done */
+       cur_child = forker->first_child;
+       int j;
+       int num_handled = 0;
+       for( j = 0; j!= forker->current_num_children && num_handled < select_ret ; j++ ) {
+
+               if( FD_ISSET( cur_child->read_status_fd, &read_set ) ) {
+                       //printf( "Server received status from a child %d\n", cur_child->pid );
+                       osrfLogDebug( OSRF_LOG_MARK,  "Server received status from a child %d", cur_child->pid );
+
+                       num_handled++;
+
+                       /* now suck off the data */
+                       char buf[64];
+                       memset( buf, 0, 64);
+                       if( (n=read(cur_child->read_status_fd, buf, 63))  < 0 ) {
+                               osrfLogWarning( OSRF_LOG_MARK, "Read error afer select in child status read with errno %d", errno);
+                       }
+
+                       osrfLogDebug( OSRF_LOG_MARK,  "Read %d bytes from status buffer: %s", n, buf );
+                       cur_child->available = 1;
+               }
+               cur_child = cur_child->next;
+       } 
+
+}
+
+
+void prefork_child_wait( prefork_child* child ) {
+
+       int i,n;
+       growing_buffer* gbuf = buffer_init( READ_BUFSIZE );
+       char buf[READ_BUFSIZE];
+       memset( buf, 0, READ_BUFSIZE );
+
+       for( i = 0; i < child->max_requests; i++ ) {
+
+               n = -1;
+               int gotdata = 0;
+               clr_fl(child->read_data_fd, O_NONBLOCK );
+
+               while( (n=read(child->read_data_fd, buf, READ_BUFSIZE-1)) > 0 ) {
+                       osrfLogDebug(OSRF_LOG_MARK, "Prefork child read %d bytes of data", n);
+                       if(!gotdata)
+                               set_fl(child->read_data_fd, O_NONBLOCK );
+                       buffer_add( gbuf, buf );
+                       memset( buf, 0, READ_BUFSIZE );
+                       gotdata = 1;
+               }
+
+               if( errno == EAGAIN ) n = 0;
+
+      if( errno == EPIPE ) {
+         osrfLogDebug(OSRF_LOG_MARK, "C child attempted read on broken pipe, exiting...");
+         break;
+      }
+
+               if( n < 0 ) {
+                       osrfLogWarning( OSRF_LOG_MARK,  "Prefork child read returned error with errno %d", errno );
+                       break;
+
+               } else if( gotdata ) {
+                       osrfLogDebug(OSRF_LOG_MARK, "Prefork child got a request.. processing..");
+                       prefork_child_process_request(child, gbuf->buf);
+                       buffer_reset( gbuf );
+               }
+
+               if( i < child->max_requests - 1 ) 
+                       write( child->write_status_fd, "available" /*less than 64 bytes*/, 9 );
+       }
+
+       buffer_free(gbuf);
+
+       osrfLogDebug( OSRF_LOG_MARK, "Child with max-requests=%d, num-served=%d exiting...[%ld]", 
+                       child->max_requests, i, (long) getpid() );
+
+   osrf_prefork_child_exit(child); /* just to be sure */
+}
+
+
+void add_prefork_child( prefork_simple* forker, prefork_child* child ) {
+       
+       if( forker->first_child == NULL ) {
+               forker->first_child = child;
+               child->next = child;
+               return;
+       }
+
+       /* we put the child in as the last because, regardless, 
+               we have to do the DLL splice dance, and this is the
+          simplest way */
+
+       prefork_child* start_child = forker->first_child;
+       while(1) {
+               if( forker->first_child->next == start_child ) 
+                       break;
+               forker->first_child = forker->first_child->next;
+       }
+
+       /* here we know that forker->first_child is the last element 
+               in the list and start_child is the first.  Insert the
+               new child between them*/
+
+       forker->first_child->next = child;
+       child->next = start_child;
+       return;
+}
+
+prefork_child* find_prefork_child( prefork_simple* forker, pid_t pid ) {
+
+       if( forker->first_child == NULL ) { return NULL; }
+       prefork_child* start_child = forker->first_child;
+       do {
+               if( forker->first_child->pid == pid ) 
+                       return forker->first_child;
+       } while( (forker->first_child = forker->first_child->next) != start_child );
+
+       return NULL;
+}
+
+
+void del_prefork_child( prefork_simple* forker, pid_t pid ) { 
+
+       if( forker->first_child == NULL ) { return; }
+
+       (forker->current_num_children)--;
+       osrfLogDebug( OSRF_LOG_MARK, "Deleting Child: %d", pid );
+
+       prefork_child* start_child = forker->first_child; /* starting point */
+       prefork_child* cur_child        = start_child; /* current pointer */
+       prefork_child* prev_child       = start_child; /* the trailing pointer */
+
+       /* special case where there is only one in the list */
+       if( start_child == start_child->next ) {
+               if( start_child->pid == pid ) {
+                       forker->first_child = NULL;
+
+                       close( start_child->read_data_fd );
+                       close( start_child->write_data_fd );
+                       close( start_child->read_status_fd );
+                       close( start_child->write_status_fd );
+
+                       prefork_child_free( start_child );
+               }
+               return;
+       }
+
+
+       /* special case where the first item in the list needs to be removed */
+       if( start_child->pid == pid ) { 
+
+               /* find the last one so we can remove the start_child */
+               do { 
+                       prev_child = cur_child;
+                       cur_child = cur_child->next;
+               }while( cur_child != start_child );
+
+               /* now cur_child == start_child */
+               prev_child->next = cur_child->next;
+               forker->first_child = prev_child;
+
+               close( cur_child->read_data_fd );
+               close( cur_child->write_data_fd );
+               close( cur_child->read_status_fd );
+               close( cur_child->write_status_fd );
+
+               prefork_child_free( cur_child );
+               return;
+       } 
+
+       do {
+               prev_child = cur_child;
+               cur_child = cur_child->next;
+
+               if( cur_child->pid == pid ) {
+                       prev_child->next = cur_child->next;
+
+                       close( cur_child->read_data_fd );
+                       close( cur_child->write_data_fd );
+                       close( cur_child->read_status_fd );
+                       close( cur_child->write_status_fd );
+
+                       prefork_child_free( cur_child );
+                       return;
+               }
+
+       } while(cur_child != start_child);
+}
+
+
+
+
+prefork_child* prefork_child_init( 
+       int max_requests, int read_data_fd, int write_data_fd, 
+       int read_status_fd, int write_status_fd ) {
+
+       prefork_child* child = (prefork_child*) safe_malloc(sizeof(prefork_child));
+       child->max_requests             = max_requests;
+       child->read_data_fd             = read_data_fd;
+       child->write_data_fd            = write_data_fd;
+       child->read_status_fd   = read_status_fd;
+       child->write_status_fd  = write_status_fd;
+       child->available                        = 1;
+
+       return child;
+}
+
+
+int prefork_free( prefork_simple* prefork ) {
+       
+       while( prefork->first_child != NULL ) {
+               osrfLogInfo( OSRF_LOG_MARK,  "Killing children and sleeping 1 to reap..." );
+               kill( 0,        SIGKILL );
+               sleep(1);
+       }
+
+       client_free(prefork->connection);
+       free(prefork->appname);
+       free( prefork );
+       return 1;
+}
+
+int prefork_child_free( prefork_child* child ) { 
+       free(child->appname);
+       close(child->read_data_fd);
+       close(child->write_status_fd);
+       free( child ); 
+       return 1;
+}
+
diff --git a/src/libopensrf/osrf_settings.c b/src/libopensrf/osrf_settings.c
new file mode 100644 (file)
index 0000000..a732b08
--- /dev/null
@@ -0,0 +1,88 @@
+#include <opensrf/osrf_settings.h> 
+
+osrf_host_config* config = NULL;
+
+char* osrf_settings_host_value(char* format, ...) {
+       VA_LIST_TO_STRING(format);
+
+       if( ! config ) {
+               const char * msg = "NULL config pointer";
+               fprintf( stderr, "osrf_settings_host_value: %s\n", msg );
+               osrfLogError( OSRF_LOG_MARK, msg );
+               exit( 99 );
+       }
+
+       jsonObject* o = jsonObjectFindPath(config->config, VA_BUF);
+       char* val = jsonObjectToSimpleString(o);
+       jsonObjectFree(o);
+       return val;
+}
+
+jsonObject* osrf_settings_host_value_object(char* format, ...) {
+       VA_LIST_TO_STRING(format);
+
+       if( ! config ) {
+               const char * msg = "config pointer is NULL";
+               fprintf( stderr, "osrf_settings_host_value_object: %s\n", msg );
+               osrfLogError( OSRF_LOG_MARK, msg );
+               exit( 99 );
+       }
+
+       return jsonObjectFindPath(config->config, VA_BUF);
+}
+
+
+int osrf_settings_retrieve(char* hostname) {
+
+       if(!config) {
+
+               osrf_app_session* session = osrf_app_client_session_init("opensrf.settings");
+               jsonObject* params = jsonNewObject(NULL);
+               jsonObjectPush(params, jsonNewObject(hostname));
+               int req_id = osrf_app_session_make_req( 
+                       session, params, "opensrf.settings.host_config.get", 1, NULL );
+               osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 60 );
+               jsonObjectFree(params);
+
+               if(!omsg) {
+                       osrfLogError( OSRF_LOG_MARK, "No osrf_message received from host %s (timeout?)", hostname);
+               } else if(!omsg->_result_content) {
+                       osrf_message_free(omsg);
+                       osrfLogError(
+                               OSRF_LOG_MARK,
+                               "NULL or non-existant osrf_message result content received from host %s, "
+                               "broken message or no settings for host",
+                               hostname
+                       );
+               } else {
+                       config = osrf_settings_new_host_config(hostname);
+                       config->config = jsonObjectClone(omsg->_result_content);
+                       osrf_message_free(omsg);
+               }
+
+               osrf_app_session_request_finish( session, req_id );
+               osrf_app_session_destroy( session );
+
+               if(!config) {
+                       osrfLogError( OSRF_LOG_MARK, "Unable to load config for host %s", hostname);
+                       return -1;
+               }
+       }
+
+       return 0;
+}
+
+osrf_host_config* osrf_settings_new_host_config(char* hostname) {
+       if(!hostname) return NULL;
+       osrf_host_config* c = safe_malloc(sizeof(osrf_host_config));
+       c->hostname = strdup(hostname);
+       return c;
+}
+
+void osrf_settings_free_host_config(osrf_host_config* c) {
+       if(!c) c = config;
+       if(!c) return;
+       free(c->hostname);
+       jsonObjectFree(c->config);      
+       free(c);
+}
diff --git a/src/libopensrf/osrf_stack.c b/src/libopensrf/osrf_stack.c
new file mode 100644 (file)
index 0000000..231ccbc
--- /dev/null
@@ -0,0 +1,263 @@
+#include <opensrf/osrf_stack.h>
+#include <opensrf/osrf_application.h>
+
+osrf_message* _do_client( osrf_app_session*, osrf_message* );
+osrf_message* _do_server( osrf_app_session*, osrf_message* );
+
+/* tell osrf_app_session where the stack entry is */
+int (*osrf_stack_entry_point) (transport_client*, int, int*)  = &osrf_stack_process;
+
+int osrf_stack_process( transport_client* client, int timeout, int* msg_received ) {
+       if( !client ) return -1;
+       transport_message* msg = NULL;
+       if(msg_received) *msg_received = 0;
+
+       while( (msg = client_recv( client, timeout )) ) {
+               if(msg_received) *msg_received = 1;
+               osrfLogDebug( OSRF_LOG_MARK,  "Received message from transport code from %s", msg->sender );
+               osrf_stack_transport_handler( msg, NULL );
+               timeout = 0;
+       }
+
+       if( client->error ) {
+               osrfLogWarning(OSRF_LOG_MARK, "transport_client had trouble reading from the socket..");
+               return -1;
+       }
+
+       if( ! client_connected( client ) ) return -1;
+
+       return 0;
+}
+
+
+
+// -----------------------------------------------------------------------------
+// Entry point into the stack
+// -----------------------------------------------------------------------------
+osrfAppSession* osrf_stack_transport_handler( transport_message* msg, char* my_service ) { 
+
+       if(!msg) return NULL;
+
+   osrfLogSetXid(msg->osrf_xid);
+
+       osrfLogDebug( OSRF_LOG_MARK,  "Transport handler received new message \nfrom %s "
+                       "to %s with body \n\n%s\n", msg->sender, msg->recipient, msg->body );
+
+       if( msg->is_error && ! msg->thread ) {
+               osrfLogWarning( OSRF_LOG_MARK, "!! Received jabber layer error for %s ... exiting\n", msg->sender );
+               message_free( msg );
+               return NULL;
+       }
+
+       if(! msg->thread  && ! msg->is_error ) {
+               osrfLogWarning( OSRF_LOG_MARK, "Received a non-error message with no thread trace... dropping");
+               message_free( msg );
+               return NULL;
+       }
+
+       osrf_app_session* session = osrf_app_session_find_session( msg->thread );
+
+       if( !session && my_service ) 
+               session = osrf_app_server_session_init( msg->thread, my_service, msg->sender);
+
+       if( !session ) return NULL;
+
+       if(!msg->is_error)
+               osrfLogDebug( OSRF_LOG_MARK, "Session [%s] found or built", session->session_id );
+
+       osrf_app_session_set_remote( session, msg->sender );
+       osrf_message* arr[OSRF_MAX_MSGS_PER_PACKET];
+       memset(arr, 0, OSRF_MAX_MSGS_PER_PACKET );
+       int num_msgs = osrf_message_deserialize(msg->body, arr, OSRF_MAX_MSGS_PER_PACKET);
+
+       osrfLogDebug( OSRF_LOG_MARK,  "We received %d messages from %s", num_msgs, msg->sender );
+
+       double starttime = get_timestamp_millis();
+
+       int i;
+       for( i = 0; i != num_msgs; i++ ) {
+
+               /* if we've received a jabber layer error message (probably talking to 
+                       someone who no longer exists) and we're not talking to the original
+                       remote id for this server, consider it a redirect and pass it up */
+               if(msg->is_error) {
+                       osrfLogWarning( OSRF_LOG_MARK,  " !!! Received Jabber layer error message" ); 
+
+                       if(strcmp(session->remote_id,session->orig_remote_id)) {
+                               osrfLogWarning( OSRF_LOG_MARK,  "Treating jabber error as redirect for tt [%d] "
+                                       "and session [%s]", arr[i]->thread_trace, session->session_id );
+
+                               arr[i]->m_type = STATUS;
+                               arr[i]->status_code = OSRF_STATUS_REDIRECTED;
+
+                       } else {
+                               osrfLogWarning( OSRF_LOG_MARK, " * Jabber Error is for top level remote id [%s], no one "
+                                               "to send my message too!!!", session->remote_id );
+                       }
+               }
+
+               osrf_stack_message_handler( session, arr[i] );
+       }
+
+       double duration = get_timestamp_millis() - starttime;
+       osrfLogInfo(OSRF_LOG_MARK, "Message processing duration %f", duration);
+
+       message_free( msg );
+       osrfLogDebug( OSRF_LOG_MARK, "after msg delete");
+
+       return session;
+}
+
+int osrf_stack_message_handler( osrf_app_session* session, osrf_message* msg ) {
+       if(session == NULL || msg == NULL)
+               return 0;
+
+       osrf_message* ret_msg = NULL;
+
+       if( session->type ==  OSRF_SESSION_CLIENT )
+                ret_msg = _do_client( session, msg );
+       else
+               ret_msg= _do_server( session, msg );
+
+       if(ret_msg) {
+               osrfLogDebug( OSRF_LOG_MARK, "passing message %d / session %s to app handler", 
+                               msg->thread_trace, session->session_id );
+               osrf_stack_application_handler( session, ret_msg );
+       } else
+               osrf_message_free(msg);
+
+       return 1;
+
+} 
+
+/** If we return a message, that message should be passed up the stack, 
+  * if we return NULL, we're finished for now...
+  */
+osrf_message* _do_client( osrf_app_session* session, osrf_message* msg ) {
+       if(session == NULL || msg == NULL)
+               return NULL;
+
+       osrf_message* new_msg;
+
+       if( msg->m_type == STATUS ) {
+               
+               switch( msg->status_code ) {
+
+                       case OSRF_STATUS_OK:
+                               osrfLogDebug( OSRF_LOG_MARK, "We connected successfully");
+                               session->state = OSRF_SESSION_CONNECTED;
+                               osrfLogDebug( OSRF_LOG_MARK,  "State: %x => %s => %d", session, session->session_id, session->state );
+                               return NULL;
+
+                       case OSRF_STATUS_COMPLETE:
+                               osrf_app_session_set_complete( session, msg->thread_trace );
+                               return NULL;
+
+                       case OSRF_STATUS_CONTINUE:
+                               osrf_app_session_request_reset_timeout( session, msg->thread_trace );
+                               return NULL;
+
+                       case OSRF_STATUS_REDIRECTED:
+                               osrf_app_session_reset_remote( session );
+                               session->state = OSRF_SESSION_DISCONNECTED;
+                               osrf_app_session_request_resend( session, msg->thread_trace );
+                               return NULL;
+
+                       case OSRF_STATUS_EXPFAILED: 
+                               osrf_app_session_reset_remote( session );
+                               session->state = OSRF_SESSION_DISCONNECTED;
+                               return NULL;
+
+                       case OSRF_STATUS_TIMEOUT:
+                               osrf_app_session_reset_remote( session );
+                               session->state = OSRF_SESSION_DISCONNECTED;
+                               osrf_app_session_request_resend( session, msg->thread_trace );
+                               return NULL;
+
+
+                       default:
+                               new_msg = osrf_message_init( RESULT, msg->thread_trace, msg->protocol );
+                               osrf_message_set_status_info( new_msg, 
+                                               msg->status_name, msg->status_text, msg->status_code );
+                               osrfLogWarning( OSRF_LOG_MARK, "The stack doesn't know what to do with " 
+                                               "the provided message code: %d, name %s. Passing UP.", 
+                                               msg->status_code, msg->status_name );
+                               new_msg->is_exception = 1;
+                               osrf_app_session_set_complete( session, msg->thread_trace );
+                               osrf_message_free(msg);
+                               return new_msg;
+               }
+
+               return NULL;
+
+       } else if( msg->m_type == RESULT ) 
+               return msg;
+
+       return NULL;
+
+}
+
+
+/** If we return a message, that message should be passed up the stack, 
+  * if we return NULL, we're finished for now...
+  */
+osrf_message* _do_server( osrf_app_session* session, osrf_message* msg ) {
+
+       if(session == NULL || msg == NULL) return NULL;
+
+       osrfLogDebug( OSRF_LOG_MARK, "Server received message of type %d", msg->m_type );
+
+       switch( msg->m_type ) {
+
+               case STATUS:
+                               return NULL;
+
+               case DISCONNECT:
+                               /* session will be freed by the forker */
+                               osrfLogDebug(OSRF_LOG_MARK, "Client sent explicit disconnect");
+                               session->state = OSRF_SESSION_DISCONNECTED;
+                               return NULL;
+
+               case CONNECT:
+                               osrfAppSessionStatus( session, OSRF_STATUS_OK, 
+                                               "osrfConnectStatus", msg->thread_trace, "Connection Successful" );
+                               session->state = OSRF_SESSION_CONNECTED;
+                               return NULL;
+
+               case REQUEST:
+
+                               osrfLogDebug( OSRF_LOG_MARK, "server passing message %d to application handler "
+                                               "for session %s", msg->thread_trace, session->session_id );
+                               return msg;
+
+               default:
+                       osrfLogWarning( OSRF_LOG_MARK, "Server cannot handle message of type %d", msg->m_type );
+                       session->state = OSRF_SESSION_DISCONNECTED;
+                       return NULL;
+
+       }
+}
+
+
+
+int osrf_stack_application_handler( osrf_app_session* session, osrf_message* msg ) {
+       if(session == NULL || msg == NULL) return 0;
+
+       if(msg->m_type == RESULT && session->type == OSRF_SESSION_CLIENT) {
+               osrf_app_session_push_queue( session, msg ); 
+               return 1;
+       }
+
+       if(msg->m_type != REQUEST) return 1;
+
+       char* method = msg->method_name;
+       char* app       = session->remote_service;
+       jsonObject* params = msg->_params;
+
+       osrfAppRunMethod( app, method,  session, msg->thread_trace, params );
+       osrfMessageFree(msg);
+               
+       return 1;
+}
+
+
diff --git a/src/libopensrf/osrf_system.c b/src/libopensrf/osrf_system.c
new file mode 100644 (file)
index 0000000..c378b7b
--- /dev/null
@@ -0,0 +1,326 @@
+#include <opensrf/osrf_system.h>
+#include <opensrf/osrf_application.h>
+#include <opensrf/osrf_prefork.h>
+#include <signal.h>
+
+static int _osrfSystemInitCache( void );
+
+static transport_client* osrfGlobalTransportClient = NULL;
+
+transport_client* osrfSystemGetTransportClient( void ) {
+       return osrfGlobalTransportClient;
+}
+
+void osrfSystemIgnoreTransportClient() {
+       osrfGlobalTransportClient = NULL;
+}
+
+transport_client* osrf_system_get_transport_client( void ) {
+       return osrfGlobalTransportClient;
+}
+
+int osrf_system_bootstrap_client( char* config_file, char* contextnode ) {
+       return osrf_system_bootstrap_client_resc(config_file, contextnode, NULL);
+}
+
+int osrfSystemBootstrapClientResc( char* config_file, char* contextnode, char* resource ) {
+       return osrf_system_bootstrap_client_resc( config_file, contextnode, resource );
+}
+
+
+static int _osrfSystemInitCache( void ) {
+
+       jsonObject* cacheServers = osrf_settings_host_value_object("/cache/global/servers/server");
+       char* maxCache = osrf_settings_host_value("/cache/global/max_cache_time");
+
+       if( cacheServers && maxCache) {
+
+               if( cacheServers->type == JSON_ARRAY ) {
+                       int i;
+                       char* servers[cacheServers->size];
+                       for( i = 0; i != cacheServers->size; i++ ) {
+                               servers[i] = jsonObjectGetString( jsonObjectGetIndex(cacheServers, i) );
+                               osrfLogInfo( OSRF_LOG_MARK, "Adding cache server %s", servers[i]);
+                       }
+                       osrfCacheInit( servers, cacheServers->size, atoi(maxCache) );
+
+               } else {
+                       char* servers[] = { jsonObjectGetString(cacheServers) };                
+                       osrfLogInfo( OSRF_LOG_MARK, "Adding cache server %s", servers[0]);
+                       osrfCacheInit( servers, 1, atoi(maxCache) );
+               }
+
+       } else {
+               osrfLogError( OSRF_LOG_MARK,  "Missing config value for /cache/global/servers/server _or_ "
+                       "/cache/global/max_cache_time");
+       }
+
+       return 0;
+}
+
+
+int osrfSystemBootstrap( char* hostname, char* configfile, char* contextNode ) {
+       if( !(hostname && configfile && contextNode) ) return -1;
+
+       /* first we grab the settings */
+       if(!osrfSystemBootstrapClientResc(configfile, contextNode, "settings_grabber" )) {
+               osrfLogError( OSRF_LOG_MARK,
+                       "Unable to bootstrap for host %s from configuration file %s",
+                       hostname, configfile );
+               return -1;
+       }
+
+       int retcode = osrf_settings_retrieve(hostname);
+       osrf_system_disconnect_client();
+
+       if( retcode ) {
+               osrfLogError( OSRF_LOG_MARK,
+                       "Unable to retrieve settings for host %s from configuration file %s",
+                       hostname, configfile );
+               return -1;
+       }
+       
+       jsonObject* apps = osrf_settings_host_value_object("/activeapps/appname");
+       osrfStringArray* arr = osrfNewStringArray(8);
+       
+       _osrfSystemInitCache();
+
+       if(apps) {
+               int i = 0;
+
+               if(apps->type == JSON_STRING) {
+                       osrfStringArrayAdd(arr, jsonObjectGetString(apps));
+
+               } else {
+                       jsonObject* app;
+                       while( (app = jsonObjectGetIndex(apps, i++)) ) 
+                               osrfStringArrayAdd(arr, jsonObjectGetString(app));
+               }
+
+               char* appname = NULL;
+               i = 0;
+               while( (appname = osrfStringArrayGetString(arr, i++)) ) {
+
+                       char* lang = osrf_settings_host_value("/apps/%s/language", appname);
+
+                       if(lang && !strcasecmp(lang,"c"))  {
+
+                               char* libfile = osrf_settings_host_value("/apps/%s/implementation", appname);
+               
+                               if(! (appname && libfile) ) {
+                                       osrfLogWarning( OSRF_LOG_MARK, "Missing appname / libfile in settings config");
+                                       continue;
+                               }
+
+                               osrfLogInfo( OSRF_LOG_MARK, "Launching application %s with implementation %s", appname, libfile);
+               
+                               pid_t pid;
+               
+                               if( (pid = fork()) ) { 
+                                       // storage pid in local table for re-launching dead children...
+                                       osrfLogInfo( OSRF_LOG_MARK, "Launched application child %ld", (long) pid);
+       
+                               } else {
+               
+                                       fprintf(stderr, " * Running application %s\n", appname);
+                                       if( osrfAppRegisterApplication( appname, libfile ) == 0 ) 
+                                               osrf_prefork_run(appname);
+       
+                                       osrfLogDebug( OSRF_LOG_MARK, "Server exiting for app %s and library %s\n", appname, libfile );
+                                       exit(0);
+                               }
+                       } // language == c
+               } 
+       }
+
+       /** daemonize me **/
+
+       /* background and let our children do their thing */
+       daemonize();
+    while(1) {
+        errno = 0;
+        pid_t pid = wait(NULL);
+        if(-1 == pid) {
+            if(errno == ECHILD)
+                osrfLogError(OSRF_LOG_MARK, "We have no more live services... exiting");
+            else
+                osrfLogError(OSRF_LOG_MARK, "Exiting top-level system loop with error: %s", strerror(errno));
+            break;
+        } else {
+            osrfLogError(OSRF_LOG_MARK, "We lost a top-level service process with PID %ld", pid);
+        }
+    }
+
+
+       return 0;
+}
+
+int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, char* resource ) {
+
+       int failure = 0;
+
+       if(osrfSystemGetTransportClient()) {
+               osrfLogInfo(OSRF_LOG_MARK, "Client is already bootstrapped");
+               return 1; /* we already have a client connection */
+       }
+
+       if( !( config_file && contextnode ) && ! osrfConfigHasDefaultConfig() ) {
+               osrfLogError( OSRF_LOG_MARK, "No Config File Specified\n" );
+               return -1;
+       }
+
+       if( config_file ) {
+               osrfConfig* cfg = osrfConfigInit( config_file, contextnode );
+               if(cfg)
+                       osrfConfigSetDefaultConfig(cfg);
+               else
+                       return 0;   /* Can't load configuration?  Bail out */
+       }
+
+
+       char* log_file          = osrfConfigGetValue( NULL, "/logfile");
+       char* log_level         = osrfConfigGetValue( NULL, "/loglevel" );
+       osrfStringArray* arr    = osrfNewStringArray(8);
+       osrfConfigGetValueList(NULL, arr, "/domains/domain");
+
+       char* username          = osrfConfigGetValue( NULL, "/username" );
+       char* password          = osrfConfigGetValue( NULL, "/passwd" );
+       char* port              = osrfConfigGetValue( NULL, "/port" );
+       char* unixpath          = osrfConfigGetValue( NULL, "/unixpath" );
+       char* facility          = osrfConfigGetValue( NULL, "/syslog" );
+       char* actlog            = osrfConfigGetValue( NULL, "/actlog" );
+
+       if(!log_file) {
+               fprintf(stderr, "No log file specified in configuration file %s\n",
+                          config_file);
+               free(log_level);
+               free(username);
+               free(password);
+               free(port);
+               free(unixpath);
+               free(facility);
+               free(actlog);
+               return -1;
+       }
+
+       /* if we're a source-client, tell the logger */
+       char* isclient = osrfConfigGetValue(NULL, "/client");
+       if( isclient && !strcasecmp(isclient,"true") )
+               osrfLogSetIsClient(1);
+       free(isclient);
+
+       int llevel = 0;
+       int iport = 0;
+       if(port) iport = atoi(port);
+       if(log_level) llevel = atoi(log_level);
+
+       if(!strcmp(log_file, "syslog")) {
+               osrfLogInit( OSRF_LOG_TYPE_SYSLOG, contextnode, llevel );
+               osrfLogSetSyslogFacility(osrfLogFacilityToInt(facility));
+               if(actlog) osrfLogSetSyslogActFacility(osrfLogFacilityToInt(actlog));
+
+       } else {
+               osrfLogInit( OSRF_LOG_TYPE_FILE, contextnode, llevel );
+               osrfLogSetFile( log_file );
+       }
+
+
+       /* Get a domain, if one is specified */
+       const char* domain = osrfStringArrayGetString( arr, 0 ); /* just the first for now */
+       if(!domain) {
+               fprintf(stderr, "No domain specified in configuration file %s\n", config_file);
+               osrfLogError( OSRF_LOG_MARK, "No domain specified in configuration file %s\n", config_file);
+               failure = 1;
+       }
+
+       if(!username) {
+               fprintf(stderr, "No username specified in configuration file %s\n", config_file);
+               osrfLogError( OSRF_LOG_MARK, "No username specified in configuration file %s\n", config_file);
+               failure = 1;
+       }
+
+       if(!password) {
+               fprintf(stderr, "No password specified in configuration file %s\n", config_file);
+               osrfLogError( OSRF_LOG_MARK, "No password specified in configuration file %s\n", config_file);
+               failure = 1;
+       }
+
+       if((iport <= 0) && !unixpath) {
+               fprintf(stderr, "No unixpath or valid port in configuration file %s\n", config_file);
+               osrfLogError( OSRF_LOG_MARK, "No unixpath or valid port in configuration file %s\n",
+                       config_file);
+               failure = 1;
+       }
+
+       if (failure) {
+               osrfStringArrayFree(arr);
+               free(log_level);
+               free(username);
+               free(password);
+               free(port);
+               free(unixpath);
+               free(facility);
+               free(actlog);
+               return 0;
+       }
+
+       osrfLogInfo( OSRF_LOG_MARK, "Bootstrapping system with domain %s, port %d, and unixpath %s",
+               domain, iport, unixpath ? unixpath : "(none)" );
+       transport_client* client = client_init( domain, iport, unixpath, 0 );
+
+       const char* host;
+       host = getenv("HOSTNAME");
+
+       char tbuf[32];
+       tbuf[0] = '\0';
+       snprintf(tbuf, 32, "%f", get_timestamp_millis());
+
+       if(!host) host = "";
+       if(!resource) resource = "";
+
+       int len = strlen(resource) + 256;
+       char buf[len];
+       buf[0] = '\0';
+       snprintf(buf, len - 1, "%s_%s_%s_%ld", resource, host, tbuf, (long) getpid() );
+
+       if(client_connect( client, username, password, buf, 10, AUTH_DIGEST )) {
+               /* child nodes will leak the parents client... but we can't free
+                       it without disconnecting the parents client :( */
+               osrfGlobalTransportClient = client;
+       }
+
+       osrfStringArrayFree(arr);
+       free(actlog);
+       free(facility);
+       free(log_level);
+       free(log_file);
+       free(username);
+       free(password);
+       free(port);     
+       free(unixpath);
+
+       if(osrfGlobalTransportClient)
+               return 1;
+
+       return 0;
+}
+
+int osrf_system_disconnect_client( void ) {
+       client_disconnect( osrfGlobalTransportClient );
+       client_free( osrfGlobalTransportClient );
+       osrfGlobalTransportClient = NULL;
+       return 0;
+}
+
+int osrf_system_shutdown( void ) {
+       osrfConfigCleanup();
+       osrf_system_disconnect_client();
+       osrf_settings_free_host_config(NULL);
+       osrfAppSessionCleanup();
+       osrfLogCleanup();
+       return 1;
+}
+
+
+
+
diff --git a/src/libopensrf/osrf_transgroup.c b/src/libopensrf/osrf_transgroup.c
new file mode 100644 (file)
index 0000000..72b203f
--- /dev/null
@@ -0,0 +1,244 @@
+#include <opensrf/osrf_transgroup.h>
+#include <sys/select.h>
+
+
+osrfTransportGroupNode* osrfNewTransportGroupNode( 
+               char* domain, int port, char* username, char* password, char* resource ) {
+
+       if(!(domain && port && username && password && resource)) return NULL;
+
+       osrfTransportGroupNode* node = safe_malloc(sizeof(osrfTransportGroupNode));
+       node->domain    = strdup(domain);
+       node->port              = port;
+       node->username = strdup(username);
+       node->password = strdup(password);
+       node->domain    = strdup(domain);
+       node->resource  = strdup(resource);
+       node->active    = 0;
+       node->lastsent  = 0;
+       node->connection = client_init( domain, port, NULL, 0 );
+
+       return node;
+}
+
+
+osrfTransportGroup* osrfNewTransportGroup( osrfTransportGroupNode* nodes[], int count ) {
+       if(!nodes || count < 1) return NULL;
+
+       osrfTransportGroup* grp = safe_malloc(sizeof(osrfTransportGroup));
+       grp->nodes                                      = osrfNewHash();
+       grp->itr                                                = osrfNewHashIterator(grp->nodes);
+
+       int i;
+       for( i = 0; i != count; i++ ) {
+               if(!(nodes[i] && nodes[i]->domain) ) return NULL;
+               osrfHashSet( grp->nodes, nodes[i], nodes[i]->domain );
+               osrfLogDebug( OSRF_LOG_MARK, "Adding domain %s to TransportGroup", nodes[i]->domain);
+       }
+
+       return grp;
+}
+
+
+/* connect all of the nodes to their servers */
+int osrfTransportGroupConnectAll( osrfTransportGroup* grp ) {
+       if(!grp) return -1;
+       int active = 0;
+
+       osrfTransportGroupNode* node;
+       osrfHashIteratorReset(grp->itr);
+
+       while( (node = osrfHashIteratorNext(grp->itr)) ) {
+               osrfLogInfo( OSRF_LOG_MARK, "TransportGroup attempting to connect to domain %s", 
+                                                        node->connection->session->server);
+
+               if(client_connect( node->connection, node->username, 
+                                       node->password, node->resource, 10, AUTH_DIGEST )) {
+                       node->active = 1;
+                       active++;
+                       osrfLogInfo( OSRF_LOG_MARK, "TransportGroup successfully connected to domain %s", 
+                                                        node->connection->session->server);
+               } else {
+                       osrfLogWarning( OSRF_LOG_MARK, "TransportGroup unable to connect to domain %s", 
+                                                        node->connection->session->server);
+               }
+       }
+
+       osrfHashIteratorReset(grp->itr);
+       return active;
+}
+
+void osrfTransportGroupDisconnectAll( osrfTransportGroup* grp ) {
+       if(!grp) return;
+
+       osrfTransportGroupNode* node;
+       osrfHashIteratorReset(grp->itr);
+
+       while( (node = osrfHashIteratorNext(grp->itr)) ) {
+               osrfLogInfo( OSRF_LOG_MARK, "TransportGroup disconnecting from domain %s", 
+                                                        node->connection->session->server);
+               client_disconnect(node->connection);
+               node->active = 0;
+       }
+
+       osrfHashIteratorReset(grp->itr);
+}
+
+
+int osrfTransportGroupSendMatch( osrfTransportGroup* grp, transport_message* msg ) {
+       if(!(grp && msg)) return -1;
+
+       char domain[256];
+       bzero(domain, 256);
+       jid_get_domain( msg->recipient, domain, 255 );
+
+       osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain);
+       if(node) {
+               if( (client_send_message( node->connection, msg )) == 0 )
+                       return 0;
+       }
+
+       osrfLogWarning( OSRF_LOG_MARK, "Error sending message to domain %s", domain );
+       return -1;
+}
+
+int osrfTransportGroupSend( osrfTransportGroup* grp, transport_message* msg ) {
+
+       if(!(grp && msg)) return -1;
+       int bufsize = 256;
+
+       char domain[bufsize];
+       bzero(domain, bufsize);
+       jid_get_domain( msg->recipient, domain, bufsize - 1 );
+
+       char msgrecip[bufsize];
+       bzero(msgrecip, bufsize);
+       jid_get_username(msg->recipient, msgrecip, bufsize - 1);
+
+       char msgres[bufsize];
+       bzero(msgres, bufsize);
+       jid_get_resource(msg->recipient, msgres, bufsize - 1);
+
+       char* firstdomain = NULL;
+       char newrcp[1024];
+
+       int updateRecip = 1;
+       /* if we don't host this domain, don't update the recipient but send it as is */
+       if(!osrfHashGet(grp->nodes, domain)) updateRecip = 0;
+
+       osrfTransportGroupNode* node;
+
+       do {
+
+               node = osrfHashIteratorNext(grp->itr);
+               if(!node) osrfHashIteratorReset(grp->itr);
+
+               node = osrfHashIteratorNext(grp->itr);
+               if(!node) return -1;
+
+               if(firstdomain == NULL) {
+                       firstdomain = node->domain;
+
+               } else {
+                       if(!strcmp(firstdomain, node->domain)) { /* we've made a full loop */
+                               osrfLogWarning( OSRF_LOG_MARK, "We've tried to send to all domains.. giving up");
+                               return -1;
+                       }
+               }
+
+               /* update the recipient domain if necessary */
+
+               if(updateRecip) {
+                       bzero(newrcp, 1024);
+                       sprintf(newrcp, "%s@%s/%s", msgrecip, node->domain, msgres);
+                       free(msg->recipient);
+                       msg->recipient = strdup(newrcp);
+               }
+
+               if( (client_send_message( node->connection, msg )) == 0 ) 
+                       return 0;
+
+       } while(1);
+
+       return -1;
+}
+
+static int __osrfTGWait( fd_set* fdset, int maxfd, int timeout ) {
+       if(!(fdset && maxfd)) return 0;
+
+       struct timeval tv;
+       tv.tv_sec = timeout;
+       tv.tv_usec = 0;
+       int retval = 0;
+
+       if( timeout < 0 ) {
+               if( (retval = select( maxfd + 1, fdset, NULL, NULL, NULL)) == -1 ) 
+                       return 0;
+
+       } else {
+               if( (retval = select( maxfd + 1, fdset, NULL, NULL, &tv)) == -1 ) 
+                       return 0;
+       }
+
+       return retval;
+}
+
+
+transport_message* osrfTransportGroupRecvAll( osrfTransportGroup* grp, int timeout ) {
+       if(!grp) return NULL;
+
+       int maxfd = 0;
+       fd_set fdset;
+       FD_ZERO( &fdset );
+
+       osrfTransportGroupNode* node;
+       osrfHashIterator* itr = osrfNewHashIterator(grp->nodes);
+
+       while( (node = osrfHashIteratorNext(itr)) ) {
+               if(node->active) {
+                       int fd = node->connection->session->sock_id;
+                       if( fd < maxfd ) maxfd = fd;
+                       FD_SET( fd, &fdset );
+               }
+       }
+       osrfHashIteratorReset(itr);
+
+       if( __osrfTGWait( &fdset, maxfd, timeout ) ) {
+               while( (node = osrfHashIteratorNext(itr)) ) {
+                       if(node->active) {
+                               int fd = node->connection->session->sock_id;
+                               if( FD_ISSET( fd, &fdset ) ) {
+                                       return client_recv( node->connection, 0 );
+                               }
+                       }
+               }
+       }
+
+       osrfHashIteratorFree(itr);
+       return NULL;
+}
+
+transport_message* osrfTransportGroupRecv( osrfTransportGroup* grp, char* domain, int timeout ) {
+       if(!(grp && domain)) return NULL;
+
+       osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain);
+       if(!node && node->connection && node->connection->session) return NULL;
+       int fd = node->connection->session->sock_id;
+
+       fd_set fdset;
+       FD_ZERO( &fdset );
+       FD_SET( fd, &fdset );
+
+       int active = __osrfTGWait( &fdset, fd, timeout );
+       if(active) return client_recv( node->connection, 0 );
+       
+       return NULL;
+}
+
+void osrfTransportGroupSetInactive( osrfTransportGroup* grp, char* domain ) {
+       if(!(grp && domain)) return;
+       osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain );
+       if(node) node->active = 0;
+}
+
+
diff --git a/src/libopensrf/sha.c b/src/libopensrf/sha.c
new file mode 100644 (file)
index 0000000..14791bd
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * 
+ *  Gabber
+ *  Copyright (C) 1999-2000 Dave Smith & Julian Missig
+ */
+
+
+/* 
+   Implements the Secure Hash Algorithm (SHA1)
+
+   Copyright (C) 1999 Scott G. Miller
+
+   Released under the terms of the GNU General Public License v2
+   see file COPYING for details
+
+   Credits: 
+      Robert Klep <robert@ilse.nl>  -- Expansion function fix 
+         Thomas "temas" Muldowney <temas@box5.net>:
+                       -- shahash() for string fun
+                       -- Will add the int32 stuff in a few
+                       
+   ---
+   FIXME: This source takes int to be a 32 bit integer.  This
+   may vary from system to system.  I'd use autoconf if I was familiar
+   with it.  Anyone want to help me out?
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#ifdef MACOS
+#  include <string.h>
+#else
+#  include <sys/stat.h>
+#  include <sys/types.h>
+#endif
+
+#include <string.h>
+
+#ifndef WIN32
+#  include <unistd.h>
+#  define INT64 long long
+#else
+#  include <string.h>
+#  define snprintf _snprintf
+#  define INT64 __int64
+#endif
+
+#define switch_endianness(x) (x<<24 & 0xff000000) | \
+                             (x<<8  & 0x00ff0000) | \
+                             (x>>8  & 0x0000ff00) | \
+                             (x>>24 & 0x000000ff)
+
+/* Initial hash values */
+#define Ai 0x67452301 
+#define Bi 0xefcdab89
+#define Ci 0x98badcfe
+#define Di 0x10325476
+#define Ei 0xc3d2e1f0
+
+/* SHA1 round constants */
+#define K1 0x5a827999
+#define K2 0x6ed9eba1
+#define K3 0x8f1bbcdc 
+#define K4 0xca62c1d6
+
+/* Round functions.  Note that f2() is used in both rounds 2 and 4 */
+#define f1(B,C,D) ((B & C) | ((~B) & D))
+#define f2(B,C,D) (B ^ C ^ D)
+#define f3(B,C,D) ((B & C) | (B & D) | (C & D))
+
+/* left circular shift functions (rotate left) */
+#define rol1(x) ((x<<1) | ((x>>31) & 1))
+#define rol5(A) ((A<<5) | ((A>>27) & 0x1f))
+#define rol30(B) ((B<<30) | ((B>>2) & 0x3fffffff))
+
+/*
+  Hashes 'data', which should be a pointer to 512 bits of data (sixteen
+  32 bit ints), into the ongoing 160 bit hash value (five 32 bit ints)
+  'hash'
+*/
+int 
+sha_hash(int *data, int *hash)  
+{
+  int W[80];
+  unsigned int A=hash[0], B=hash[1], C=hash[2], D=hash[3], E=hash[4];
+  unsigned int t, x, TEMP;
+
+  for (t=0; t<16; t++) 
+    {
+#ifndef WORDS_BIGENDIAN
+      W[t]=switch_endianness(data[t]);
+#else 
+      W[t]=data[t];
+#endif
+    }
+
+
+  /* SHA1 Data expansion */
+  for (t=16; t<80; t++) 
+    {
+      x=W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
+      W[t]=rol1(x);
+    }
+
+  /* SHA1 main loop (t=0 to 79) 
+   This is broken down into four subloops in order to use
+   the correct round function and constant */
+  for (t=0; t<20; t++) 
+    {
+      TEMP=rol5(A) + f1(B,C,D) + E + W[t] + K1;
+      E=D;
+      D=C;
+      C=rol30(B);
+      B=A;
+      A=TEMP;
+    }
+  for (; t<40; t++) 
+    {
+      TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K2;
+      E=D;
+      D=C;
+      C=rol30(B);
+      B=A;
+      A=TEMP;
+    }
+  for (; t<60; t++) 
+    {
+      TEMP=rol5(A) + f3(B,C,D) + E + W[t] + K3;
+      E=D;
+      D=C;
+      C=rol30(B);
+      B=A;
+      A=TEMP;
+    }
+  for (; t<80; t++) 
+    {
+      TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K4;
+      E=D;
+      D=C;
+      C=rol30(B);
+      B=A;
+      A=TEMP;
+    }
+  hash[0]+=A; 
+  hash[1]+=B;
+  hash[2]+=C;
+  hash[3]+=D;
+  hash[4]+=E;
+  return 0;
+}
+
+/*
+  Takes a pointer to a 160 bit block of data (five 32 bit ints) and
+  intializes it to the start constants of the SHA1 algorithm.  This
+  must be called before using hash in the call to sha_hash
+*/
+int 
+sha_init(int *hash) 
+{
+  hash[0]=Ai;
+  hash[1]=Bi;
+  hash[2]=Ci;
+  hash[3]=Di;
+  hash[4]=Ei;
+  return 0;
+}
+
+int strprintsha(char *dest, int *hashval) 
+{
+       int x;
+       char *hashstr = dest;
+       for (x=0; x<5; x++) 
+       {
+               snprintf(hashstr, 9, "%08x", hashval[x]);
+               hashstr+=8;
+       }
+       //snprintf(hashstr++, 1, "\0");
+       hashstr[0] = '\0';
+       hashstr++;
+
+       return 0;
+}
+
+char *shahash(const char *str) 
+{
+       char read_buffer[65];
+       //int read_buffer[64];
+       int c=1, i;
+       
+       INT64 length=0;
+
+       int strsz;
+       static char final[40];
+       int *hashval;
+
+       hashval = (int *)malloc(20);
+
+       sha_init(hashval);
+
+       strsz = strlen(str);
+
+       if(strsz == 0) 
+       {
+            memset(read_buffer, 0, 65);
+            read_buffer[0] = 0x80;
+            sha_hash((int *)read_buffer, hashval);
+       }
+
+       while (strsz>0) 
+       {
+               memset(read_buffer, 0, 65);
+               strncpy((char*)read_buffer, str, 64);
+               c = strlen((char *)read_buffer);
+               length+=c;
+               strsz-=c;
+               if (strsz<=0) 
+               {
+                       length<<=3;     
+                       read_buffer[c]=(char)0x80;
+                       for (i=c+1; i<64; i++) 
+                               read_buffer[i]=0;
+                       if (c>55) 
+                       {
+                               /* we need to do an entire new block */
+                               sha_hash((int *)read_buffer, hashval);
+                               for (i=0; i<14; i++) 
+                                       ((int*)read_buffer)[i]=0;
+                       }      
+#ifndef WORDS_BIGENDIAN
+                       for (i=0; i<8; i++) 
+                       {
+                               read_buffer[56+i]=(char)(length>>(56-(i*8))) & 0xff;
+                       }
+#else  
+                       memcpy(read_buffer+56, &length, 8);
+#endif
+               }
+               
+               sha_hash((int *)read_buffer, hashval);
+               str+=64;
+       }
+
+       strprintsha((char *)final, hashval);
+       free(hashval);
+       return (char *)final;
+}
diff --git a/src/libopensrf/socket_bundle.c b/src/libopensrf/socket_bundle.c
new file mode 100644 (file)
index 0000000..6196410
--- /dev/null
@@ -0,0 +1,743 @@
+#include <opensrf/socket_bundle.h>
+
+/* buffer used to read from the sockets */
+#define RBUFSIZE 1024
+
+static socket_node* _socket_add_node(socket_manager* mgr,
+               int endpoint, int addr_type, int sock_fd, int parent_id );
+static socket_node* socket_find_node(socket_manager* mgr, int sock_fd);
+static void socket_remove_node(socket_manager*, int sock_fd);
+static int _socket_send(int sock_fd, const char* data, int flags);
+static int _socket_route_data(socket_manager* mgr, int num_active, fd_set* read_set);
+static int _socket_route_data_id( socket_manager* mgr, int sock_id);
+static int _socket_handle_new_client(socket_manager* mgr, socket_node* node);
+static int _socket_handle_client_data(socket_manager* mgr, socket_node* node);
+
+
+/* -------------------------------------------------------------------- 
+       Test Code 
+       -------------------------------------------------------------------- */
+/*
+int count = 0;
+void printme(void* blob, socket_manager* mgr, 
+               int sock_fd, char* data, int parent_id) {
+
+       fprintf(stderr, "Got data from socket %d with parent %d => %s", 
+                       sock_fd, parent_id, data );
+
+       socket_send(sock_fd, data);
+
+       if(count++ > 2) {
+               socket_disconnect(mgr, sock_fd);
+               _socket_print_list(mgr);
+       }
+}
+
+int main(int argc, char* argv[]) {
+       socket_manager manager;
+       memset(&manager, 0, sizeof(socket_manager));
+       int port = 11000;
+       if(argv[1])
+               port = atoi(argv[1]);
+
+       manager.data_received = &printme;
+       socket_open_tcp_server(&manager, port);
+
+       while(1)
+               socket_wait_all(&manager, -1);
+
+       return 0;
+}
+*/
+/* -------------------------------------------------------------------- */
+
+
+/* allocates and inserts a new socket node into the nodeset.
+       if parent_id is positive and non-zero, it will be set */
+static socket_node* _socket_add_node(socket_manager* mgr, 
+               int endpoint, int addr_type, int sock_fd, int parent_id ) {
+
+       if(mgr == NULL) return NULL;
+       osrfLogInternal( OSRF_LOG_MARK, "Adding socket node with fd %d", sock_fd);
+       socket_node* new_node = safe_malloc(sizeof(socket_node));
+
+       new_node->endpoint      = endpoint;
+       new_node->addr_type     = addr_type;
+       new_node->sock_fd               = sock_fd;
+       new_node->next                  = NULL;
+       new_node->parent_id = 0;
+       if(parent_id > 0)
+               new_node->parent_id = parent_id;
+
+       new_node->next                  = mgr->socket;
+       mgr->socket                             = new_node;
+       return new_node;
+}
+
+/* creates a new server socket node and adds it to the socket set.
+       returns new socket fd on success.  -1 on failure.
+       socket_type is one of INET or UNIX  */
+int socket_open_tcp_server(socket_manager* mgr, int port, char* listen_ip) {
+
+       if( mgr == NULL ) {
+               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): NULL mgr"); 
+               return -1;
+       }
+
+       int sock_fd;
+       struct sockaddr_in server_addr;
+
+       errno = 0;
+       sock_fd = socket(AF_INET, SOCK_STREAM, 0);
+       if(sock_fd < 0) {
+               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): Unable to create TCP socket: %s",
+                       strerror( errno ) );
+               return -1;
+       }
+
+       server_addr.sin_family = AF_INET;
+
+       if(listen_ip != NULL) {
+               server_addr.sin_addr.s_addr = inet_addr(listen_ip);
+       } else {
+               server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+       }
+
+       server_addr.sin_port = htons(port);
+
+       errno = 0;
+       if(bind( sock_fd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) {
+               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): cannot bind to port %d: %s",
+                       port, strerror( errno ) );
+               return -1;
+       }
+
+       errno = 0;
+       if(listen(sock_fd, 20) == -1) {
+               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): listen() returned error: %s",
+                       strerror( errno ) );
+               return -1;
+       }
+
+       _socket_add_node(mgr, SERVER_SOCKET, INET, sock_fd, 0);
+       return sock_fd;
+}
+
+int socket_open_unix_server(socket_manager* mgr, char* path) {
+       if(mgr == NULL || path == NULL) return -1;
+
+       osrfLogDebug( OSRF_LOG_MARK, "opening unix socket at %s", path);
+       int sock_fd;
+       struct sockaddr_un server_addr;
+
+       errno = 0;
+       sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if(sock_fd < 0){
+               osrfLogWarning( OSRF_LOG_MARK, "socket_open_unix_server(): socket() failed: %s",
+                       strerror( errno ) );
+               return -1;
+       }
+
+       server_addr.sun_family = AF_UNIX;
+       strcpy(server_addr.sun_path, path);
+
+       errno = 0;
+       if( bind(sock_fd, (struct sockaddr*) &server_addr, 
+                               sizeof(struct sockaddr_un)) < 0) {
+               osrfLogWarning( OSRF_LOG_MARK, 
+                       "socket_open_unix_server(): cannot bind to unix port %s: %s",
+                       path, strerror( errno ) );
+               return -1;
+       }
+
+       errno = 0;
+       if(listen(sock_fd, 20) == -1) {
+               osrfLogWarning( OSRF_LOG_MARK, "socket_open_unix_server(): listen() returned error: %s",
+                       strerror( errno ) );
+               return -1;
+       }
+
+       osrfLogDebug( OSRF_LOG_MARK, "unix socket successfully opened");
+       
+       int i = 1;
+
+       /* causing problems with router for some reason ... */
+       //osrfLogDebug( OSRF_LOG_MARK, "Setting SO_REUSEADDR");
+       //setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
+       
+       //osrfLogDebug( OSRF_LOG_MARK, "Setting TCP_NODELAY");
+       setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
+
+       _socket_add_node(mgr, SERVER_SOCKET, UNIX, sock_fd, 0);
+       return sock_fd;
+}
+
+
+
+int socket_open_udp_server( 
+               socket_manager* mgr, int port, char* listen_ip ) {
+
+       int sockfd;
+       struct sockaddr_in server_addr;
+
+       errno = 0;
+       if( (sockfd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
+               osrfLogWarning( OSRF_LOG_MARK, "Unable to create UDP socket: %s", strerror( errno ) );
+               return -1;
+       }
+
+       server_addr.sin_family = AF_INET;
+       server_addr.sin_port = htons(port);
+       if(listen_ip) server_addr.sin_addr.s_addr = inet_addr(listen_ip);
+       else server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+       errno = 0;
+       if( (bind (sockfd, (struct sockaddr *) &server_addr,sizeof(server_addr))) ) {
+               osrfLogWarning( OSRF_LOG_MARK, "Unable to bind to UDP port %d: %s",
+                       port, strerror( errno ) );
+               return -1;
+       }
+
+       _socket_add_node(mgr, SERVER_SOCKET, INET, sockfd, 0);
+       return sockfd;
+}
+
+
+int socket_open_tcp_client(socket_manager* mgr, int port, char* dest_addr) {
+
+       struct sockaddr_in remoteAddr, localAddr;
+   struct hostent *hptr;
+   int sock_fd;
+
+   // ------------------------------------------------------------------
+   // Create the socket
+   // ------------------------------------------------------------------
+   errno = 0;
+   if( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
+          osrfLogWarning( OSRF_LOG_MARK,  "socket_open_tcp_client(): Cannot create TCP socket: %s",
+                       strerror( errno ) );
+      return -1;
+   }
+
+       int i = 1;
+       //osrfLogDebug( OSRF_LOG_MARK, "Setting TCP_NODELAY");
+       setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
+
+
+   // ------------------------------------------------------------------
+   // Get the hostname
+   // ------------------------------------------------------------------
+   errno = 0;
+   if( (hptr = gethostbyname( dest_addr ) ) == NULL ) {
+          osrfLogWarning(  OSRF_LOG_MARK, "socket_open_tcp_client(): Unknown Host => %s: %s",
+                                               dest_addr, strerror( errno ) );
+      return -1;
+   }
+
+   // ------------------------------------------------------------------
+   // Construct server info struct
+   // ------------------------------------------------------------------
+   memset( &remoteAddr, 0, sizeof(remoteAddr));
+   remoteAddr.sin_family = AF_INET;
+   remoteAddr.sin_port = htons( port );
+   memcpy( (char*) &remoteAddr.sin_addr.s_addr,
+         hptr->h_addr_list[0], hptr->h_length );
+
+   // ------------------------------------------------------------------
+   // Construct local info struct
+   // ------------------------------------------------------------------
+   memset( &localAddr, 0, sizeof( localAddr ) );
+   localAddr.sin_family = AF_INET;
+   localAddr.sin_addr.s_addr = htonl( INADDR_ANY );
+   localAddr.sin_port = htons(0);
+
+   // ------------------------------------------------------------------
+   // Bind to a local port
+   // ------------------------------------------------------------------
+   errno = 0;
+   if( bind( sock_fd, (struct sockaddr *) &localAddr, sizeof( localAddr ) ) < 0 ) {
+          osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot bind to local port: %s",
+               strerror( errno ) );
+      return -1;
+   }
+
+   // ------------------------------------------------------------------
+   // Connect to server
+   // ------------------------------------------------------------------
+   errno = 0;
+   if( connect( sock_fd, (struct sockaddr*) &remoteAddr, sizeof( struct sockaddr_in ) ) < 0 ) {
+          osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot connect to server %s: %s",
+                  dest_addr, strerror(errno) );
+          return -1;
+   }
+
+       _socket_add_node(mgr, CLIENT_SOCKET, INET, sock_fd, -1 );
+
+   return sock_fd;
+}
+
+
+int socket_open_udp_client( 
+               socket_manager* mgr, int port, char* dest_addr) {
+
+       int sockfd;
+       struct sockaddr_in client_addr, server_addr;
+       struct hostent* host;
+
+       errno = 0;
+       if( (host = gethostbyname(dest_addr)) == NULL) {
+               osrfLogWarning( OSRF_LOG_MARK, "Unable to resolve host: %s: %s",
+                       dest_addr, strerror( errno ) );
+               return -1;
+       }
+
+       server_addr.sin_family = host->h_addrtype;
+       memcpy((char *) &server_addr.sin_addr.s_addr,
+                            host->h_addr_list[0], host->h_length);
+       server_addr.sin_port = htons(port);
+
+       errno = 0;
+       if( (sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0 ) {
+               osrfLogWarning( OSRF_LOG_MARK, "socket_open_udp_client(): Unable to create UDP socket: %s", strerror( errno ) );
+               return -1;
+       }
+
+       client_addr.sin_family = AF_INET;
+       client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+       client_addr.sin_port = htons(0);
+
+       errno = 0;
+       if( (bind(sockfd, (struct sockaddr *) &client_addr, sizeof(client_addr))) < 0 ) {
+               osrfLogWarning( OSRF_LOG_MARK, "Unable to bind UDP socket: %s", strerror( errno ) );
+               return -1;
+       }
+
+       _socket_add_node(mgr, CLIENT_SOCKET, INET, sockfd, -1 );
+
+       return sockfd;
+}
+
+
+int socket_open_unix_client(socket_manager* mgr, char* sock_path) {
+
+       int sock_fd, len;
+   struct sockaddr_un usock;
+
+   errno = 0;
+   if( (sock_fd = socket( AF_UNIX, SOCK_STREAM, 0 )) < 0 ) {
+          osrfLogWarning(  OSRF_LOG_MARK, "socket_open_unix_client(): Cannot create UNIX socket: %s", strerror( errno ) );
+               return -1;
+       }
+
+   usock.sun_family = AF_UNIX;
+   strcpy( usock.sun_path, sock_path );
+
+   len = sizeof( usock.sun_family ) + strlen( usock.sun_path );
+
+   errno = 0;
+   if( connect( sock_fd, (struct sockaddr *) &usock, len ) < 0 ) {
+          osrfLogWarning(  OSRF_LOG_MARK, "Error connecting to unix socket: %s",
+                       strerror( errno ) );
+               return -1;
+       }
+
+       _socket_add_node(mgr, CLIENT_SOCKET, UNIX, sock_fd, -1 );
+
+   return sock_fd;
+}
+
+
+/* returns the socket_node with the given sock_fd */
+static socket_node* socket_find_node(socket_manager* mgr, int sock_fd) {
+       if(mgr == NULL) return NULL;
+       socket_node* node = mgr->socket;
+       while(node) {
+               if(node->sock_fd == sock_fd)
+                       return node;
+               node = node->next;
+       }
+       return NULL;
+}
+
+/* removes the node with the given sock_fd from the list and frees it */
+static void socket_remove_node(socket_manager* mgr, int sock_fd) {
+
+       if(mgr == NULL) return;
+
+       osrfLogDebug( OSRF_LOG_MARK, "removing socket %d", sock_fd);
+
+       socket_node* head = mgr->socket;
+       socket_node* tail = head;
+       if(head == NULL) return;
+
+       /* if removing the first node in the list */
+       if(head->sock_fd == sock_fd) {
+               mgr->socket = head->next;
+               free(head);
+               return;
+       }
+
+       head = head->next;
+
+       /* if removing any other node */
+       while(head) {
+               if(head->sock_fd == sock_fd) {
+                       tail->next = head->next;
+                       free(head);
+                       return;
+               }
+               tail = head;
+               head = head->next;
+       }
+}
+
+
+void _socket_print_list(socket_manager* mgr) {
+       if(mgr == NULL) return;
+       socket_node* node = mgr->socket;
+       osrfLogDebug( OSRF_LOG_MARK, "socket_node list: [");
+       while(node) {
+               osrfLogDebug( OSRF_LOG_MARK, "sock_fd: %d | parent_id: %d", 
+                               node->sock_fd, node->parent_id);
+               node = node->next;
+       }
+       osrfLogDebug( OSRF_LOG_MARK, "]");
+}
+
+/* sends the given data to the given socket */
+int socket_send(int sock_fd, const char* data) {
+       return _socket_send( sock_fd, data, 0);
+}
+
+/* utility method */
+static int _socket_send(int sock_fd, const char* data, int flags) {
+
+       signal(SIGPIPE, SIG_IGN); /* in case a unix socket was closed */
+
+       errno = 0;
+       size_t r = send( sock_fd, data, strlen(data), flags );
+       int local_errno = errno;
+       
+       if( r == -1 ) {
+               osrfLogWarning( OSRF_LOG_MARK, "_socket_send(): Error sending data with return %d", r );
+               osrfLogWarning( OSRF_LOG_MARK, "Last Sys Error: %s", strerror(local_errno));
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/* sends the given data to the given socket. 
+ * sets the send flag MSG_DONTWAIT which will allow the 
+ * process to continue even if the socket buffer is full
+ * returns 0 on success, -1 otherwise */
+//int socket_send_nowait( int sock_fd, const char* data) {
+//     return _socket_send( sock_fd, data, MSG_DONTWAIT);
+//}
+
+
+/*
+ * Waits at most usecs microseconds for the send buffer of the given
+ * socket to accept new data.  This does not guarantee that the 
+ * socket will accept all the data we want to give it.
+ */
+int socket_send_timeout( int sock_fd, const char* data, int usecs ) {
+
+       fd_set write_set;
+       FD_ZERO( &write_set );
+       FD_SET( sock_fd, &write_set );
+
+       int mil = 1000000;
+       int secs = (int) usecs / mil;
+       usecs = usecs - (secs * mil);
+
+       struct timeval tv;
+       tv.tv_sec = secs;
+       tv.tv_usec = usecs;
+
+       errno = 0;
+       int ret = select( sock_fd + 1, NULL, &write_set, NULL, &tv);
+       if( ret > 0 ) return _socket_send( sock_fd, data, 0);
+
+       osrfLogError(OSRF_LOG_MARK, "socket_send_timeout(): "
+               "timed out on send for socket %d after %d secs, %d usecs: %s",
+               sock_fd, secs, usecs, strerror( errno ) );
+
+       return -1;
+}
+
+
+/* disconnects the node with the given sock_fd and removes
+       it from the socket set */
+void socket_disconnect(socket_manager* mgr, int sock_fd) {
+       osrfLogInternal( OSRF_LOG_MARK, "Closing socket %d", sock_fd);
+       close( sock_fd );
+       socket_remove_node(mgr, sock_fd);
+}
+
+
+/* we assume that if select() fails, the socket is no longer valid */
+int socket_connected(int sock_fd) {
+       fd_set read_set;
+       FD_ZERO( &read_set );
+       FD_SET( sock_fd, &read_set );
+       if( select( sock_fd + 1, &read_set, NULL, NULL, NULL) == -1 ) 
+               return 0;
+       return 1;
+
+}
+
+/* this only waits on the server socket and does not handle the actual
+       data coming in from the client..... XXX */
+int socket_wait(socket_manager* mgr, int timeout, int sock_fd) {
+
+       int retval = 0;
+       fd_set read_set;
+       FD_ZERO( &read_set );
+       FD_SET( sock_fd, &read_set );
+
+       struct timeval tv;
+       tv.tv_sec = timeout;
+       tv.tv_usec = 0;
+       errno = 0;
+
+       if( timeout < 0 ) {  
+
+               // If timeout is -1, we block indefinitely
+               if( (retval = select( sock_fd + 1, &read_set, NULL, NULL, NULL)) == -1 ) {
+                       osrfLogDebug( OSRF_LOG_MARK, "Call to select() interrupted: Sys Error: %s", strerror(errno));
+                       return -1;
+               }
+
+       } else if( timeout > 0 ) { /* timeout of 0 means don't block */
+
+               if( (retval = select( sock_fd + 1, &read_set, NULL, NULL, &tv)) == -1 ) {
+                       osrfLogDebug( OSRF_LOG_MARK, "Call to select() interrupted: Sys Error: %s", strerror(errno));
+                       return -1;
+               }
+       }
+
+       osrfLogInternal( OSRF_LOG_MARK, "%d active sockets after select()", retval);
+       return _socket_route_data_id(mgr, sock_fd);
+}
+
+
+int socket_wait_all(socket_manager* mgr, int timeout) {
+
+       if(mgr == NULL) {
+               osrfLogWarning( OSRF_LOG_MARK,  "socket_wait_all(): null mgr" );
+               return -1;
+       }
+
+       int retval = 0;
+       fd_set read_set;
+       FD_ZERO( &read_set );
+
+       socket_node* node = mgr->socket;
+       int max_fd = 0;
+       while(node) {
+               osrfLogInternal( OSRF_LOG_MARK, "Adding socket fd %d to select set",node->sock_fd);
+               FD_SET( node->sock_fd, &read_set );
+               if(node->sock_fd > max_fd) max_fd = node->sock_fd;
+               node = node->next;
+       }
+       max_fd += 1;
+
+       struct timeval tv;
+       tv.tv_sec = timeout;
+       tv.tv_usec = 0;
+       errno = 0;
+
+       if( timeout < 0 ) {  
+
+               // If timeout is -1, there is no timeout passed to the call to select
+               if( (retval = select( max_fd, &read_set, NULL, NULL, NULL)) == -1 ) {
+                       osrfLogWarning( OSRF_LOG_MARK, "select() call aborted: %s", strerror(errno));
+                       return -1;
+               }
+
+       } else if( timeout != 0 ) { /* timeout of 0 means don't block */
+
+               if( (retval = select( max_fd, &read_set, NULL, NULL, &tv)) == -1 ) {
+                       osrfLogWarning( OSRF_LOG_MARK, "select() call aborted: %s", strerror(errno));
+                       return -1;
+               }
+       }
+
+       osrfLogDebug( OSRF_LOG_MARK, "%d active sockets after select()", retval);
+       return _socket_route_data(mgr, retval, &read_set);
+}
+
+/* iterates over the sockets in the set and handles active sockets.
+       new sockets connecting to server sockets cause the creation
+       of a new socket node.
+       Any new data read is is passed off to the data_received callback
+       as it arrives */
+/* determines if we're receiving a new client or data
+       on an existing client */
+static int _socket_route_data(
+       socket_manager* mgr, int num_active, fd_set* read_set) {
+
+       if(!(mgr && read_set)) return -1;
+
+       int last_failed_id = -1;
+
+
+       /* come back here if someone yanks a socket_node from beneath us */
+       while(1) {
+
+               socket_node* node = mgr->socket;
+               int handled = 0;
+               int status = 0;
+               
+               while(node && (handled < num_active)) {
+       
+                       int sock_fd = node->sock_fd;
+                       
+                       if(last_failed_id != -1) {
+                               /* in case it was not removed by our overlords */
+                               osrfLogInternal( OSRF_LOG_MARK, "Attempting to remove last_failed_id of %d", last_failed_id);
+                               socket_remove_node( mgr, last_failed_id );
+                               last_failed_id = -1;
+                               status = -1;
+                               break;
+                       }
+       
+                       /* does this socket have data? */
+                       if( FD_ISSET( sock_fd, read_set ) ) {
+       
+                               osrfLogInternal( OSRF_LOG_MARK, "Socket %d active", sock_fd);
+                               handled++;
+                               FD_CLR(sock_fd, read_set);
+       
+                               if(node->endpoint == SERVER_SOCKET) 
+                                       _socket_handle_new_client(mgr, node);
+       
+                               else
+                                       status = _socket_handle_client_data(mgr, node);
+       
+                               /* someone may have yanked a socket_node out from under 
+                                       us...start over with the first socket */
+                               if(status == -1)  {
+                                       last_failed_id = sock_fd;
+                                       osrfLogInternal( OSRF_LOG_MARK, "Backtracking back to start of loop because "
+                                                       "of -1 return code from _socket_handle_client_data()");
+                               }
+                       }
+
+                       if(status == -1) break;
+                       node = node->next;
+
+               } // is_set
+
+               if(status == 0) break;
+               if(status == -1) status = 0;
+       } 
+
+       return 0;
+}
+
+
+/* routes data from a single known socket */
+static int _socket_route_data_id( socket_manager* mgr, int sock_id) {
+       socket_node* node = socket_find_node(mgr, sock_id);     
+       int status = 0;
+
+       if(node) {
+               if(node->endpoint == SERVER_SOCKET) 
+                       _socket_handle_new_client(mgr, node);
+       
+               if(node->endpoint == CLIENT_SOCKET ) 
+                       status = _socket_handle_client_data(mgr, node);
+
+               if(status == -1) {
+                       socket_remove_node(mgr, sock_id);
+                       return -1;
+               }
+               return 0;
+       } 
+
+       return -1;
+}
+
+
+static int _socket_handle_new_client(socket_manager* mgr, socket_node* node) {
+       if(mgr == NULL || node == NULL) return -1;
+
+       errno = 0;
+       int new_sock_fd;
+       new_sock_fd = accept(node->sock_fd, NULL, NULL);
+       if(new_sock_fd < 0) {
+               osrfLogWarning( OSRF_LOG_MARK, "_socket_handle_new_client(): accept() failed: %s",
+                       strerror( errno ) );
+               return -1;
+       }
+
+       if(node->addr_type == INET) {
+               _socket_add_node(mgr, CLIENT_SOCKET, INET, new_sock_fd, node->sock_fd);
+               osrfLogDebug( OSRF_LOG_MARK, "Adding new INET client for %d", node->sock_fd);
+
+       } else if(node->addr_type == UNIX) {
+               _socket_add_node(mgr, CLIENT_SOCKET, UNIX, new_sock_fd, node->sock_fd);
+               osrfLogDebug( OSRF_LOG_MARK, "Adding new UNIX client for %d", node->sock_fd);
+       }
+
+       return 0;
+}
+
+
+static int _socket_handle_client_data(socket_manager* mgr, socket_node* node) {
+       if(mgr == NULL || node == NULL) return -1;
+
+       char buf[RBUFSIZE];
+       int read_bytes;
+       int sock_fd = node->sock_fd;
+
+       memset(buf, 0, RBUFSIZE);
+       set_fl(sock_fd, O_NONBLOCK);
+
+       osrfLogInternal( OSRF_LOG_MARK, "%ld : Received data at %f\n", (long) getpid(), get_timestamp_millis());
+
+       while( (read_bytes = recv(sock_fd, buf, RBUFSIZE-1, 0) ) > 0 ) {
+               osrfLogInternal( OSRF_LOG_MARK, "Socket %d Read %d bytes and data: %s", sock_fd, read_bytes, buf);
+               if(mgr->data_received)
+                       mgr->data_received(mgr->blob, mgr, sock_fd, buf, node->parent_id);
+
+               memset(buf, 0, RBUFSIZE);
+       }
+    int local_errno = errno; /* capture errno as set by recv() */
+
+       if(socket_find_node(mgr, sock_fd)) {  /* someone may have closed this socket */
+               clr_fl(sock_fd, O_NONBLOCK); 
+               if(read_bytes < 0) { 
+                       if(local_errno != EAGAIN) 
+                               osrfLogWarning(OSRF_LOG_MARK,  " * Error reading socket with error %s", strerror(local_errno));
+               }
+
+       } else { return -1; } /* inform the caller that this node has been tampered with */
+
+       if(read_bytes == 0) {  /* socket closed by client */
+               if(mgr->on_socket_closed) {
+                       mgr->on_socket_closed(mgr->blob, sock_fd);
+               }
+               return -1;
+       }
+
+       return 0;
+
+}
+
+
+void socket_manager_free(socket_manager* mgr) {
+       if(mgr == NULL) return;
+       socket_node* tmp;
+       while(mgr->socket) {
+               tmp = mgr->socket->next;
+               socket_disconnect(mgr, mgr->socket->sock_fd);
+               mgr->socket = tmp;
+       }
+       free(mgr);
+
+}
+
diff --git a/src/libopensrf/socket_test.c b/src/libopensrf/socket_test.c
new file mode 100644 (file)
index 0000000..c921ac6
--- /dev/null
@@ -0,0 +1,33 @@
+#include <opensrf/socket_bundle.h>
+
+int count = 0;
+void printme(void* blob, socket_manager* mgr, 
+               int sock_fd, char* data, int parent_id) {
+
+       fprintf(stderr, "Got data from socket %d with parent %d => %s", 
+                       sock_fd, parent_id, data );
+
+       socket_send(sock_fd, data);
+
+       if(count++ > 2) {
+//             socket_disconnect(mgr, sock_fd);
+               _socket_print_list(mgr);
+               socket_manager_free(mgr);
+               exit(0);
+       }
+}
+
+int main(int argc, char* argv[]) {
+       socket_manager* manager = safe_malloc(sizeof(socket_manager));
+       int port = 11000;
+       if(argv[1])
+               port = atoi(argv[1]);
+
+       manager->data_received = &printme;
+       socket_open_tcp_server(manager, port);
+
+       while(1)
+               socket_wait_all(manager, -1);
+
+       return 0;
+}
diff --git a/src/libopensrf/string_array.c b/src/libopensrf/string_array.c
new file mode 100644 (file)
index 0000000..3197718
--- /dev/null
@@ -0,0 +1,116 @@
+#include <opensrf/string_array.h>
+
+osrfStringArray* osrfNewStringArray(int size) {
+       return init_string_array(size);
+}
+
+string_array* init_string_array(int size) {
+       if(size > STRING_ARRAY_MAX_SIZE)
+               osrfLogError( OSRF_LOG_MARK, "init_string_array size is too large");
+
+       /*
+       string_array* arr = 
+               (string_array*) safe_malloc(sizeof(string_array));
+               */
+       string_array* arr;
+       OSRF_MALLOC( arr, sizeof(string_array));
+
+       //arr->array = (char**) safe_malloc(size * sizeof(char*));
+       OSRF_MALLOC(arr->array, size * sizeof(char*));
+
+       arr->size = 0;
+       arr->arr_size = size;
+       return arr;
+}
+
+
+void osrfStringArrayAdd(osrfStringArray* arr, char* string) {
+       string_array_add(arr, string);
+}
+
+void string_array_add(string_array* arr, char* str) {
+       if(arr == NULL || str == NULL ) return;
+       if( strlen(str) < 1 ) return;
+
+       arr->size++;
+
+       if( arr->size > STRING_ARRAY_MAX_SIZE ) 
+               osrfLogError( OSRF_LOG_MARK, "string_array_add size is too large");
+
+       /* if necessary, double capacity */
+       if(arr->size >= arr->arr_size) {
+               arr->arr_size *= 2;
+               //char** tmp = (char**) safe_malloc(arr->arr_size * sizeof(char*));
+               char** tmp;
+               OSRF_MALLOC( tmp, arr->arr_size * sizeof(char*));
+               int i;
+
+               /* copy the string pointers over */
+               for( i = 0; i!= arr->size; i++ ) 
+                       tmp[i] = arr->array[i];
+
+               free(arr->array);
+               arr->array = tmp;
+       }
+
+       arr->array[arr->size - 1] = strdup(str);
+}
+
+char* osrfStringArrayGetString(osrfStringArray* arr, int index) {
+       return string_array_get_string(arr, index);
+}
+
+char* string_array_get_string(string_array* arr, int index) {
+       if(!arr || index < 0 || index >= arr->size ) return NULL;
+       return arr->array[index]; 
+}
+
+
+void osrfStringArrayFree(osrfStringArray* arr) {
+       string_array_destroy(arr);
+}
+
+void string_array_destroy(string_array* arr) {
+       if(arr) {
+               int i = 0;
+               while( i < arr->size ) free(arr->array[i++]);
+               free(arr->array);
+               free(arr);
+       }
+}
+
+
+int osrfStringArrayContains( osrfStringArray* arr, char* string ) {
+       if(!(arr && string)) return 0;
+       
+       int i;
+       for( i = 0; i != arr->size; i++ ) {
+               char* str = osrfStringArrayGetString(arr, i);
+               if(str) {
+                       if(!strcmp(str, string)) return 1;
+               }
+       }
+
+       return 0;
+}
+
+void osrfStringArrayRemove( osrfStringArray* arr, char* tstr) {
+       if(!(arr && tstr)) return;
+       int i;
+       for( i = 0; i != arr->size; i++ ) {
+               char* str = osrfStringArrayGetString(arr, i);
+               if(str) {
+                       if(!strcmp(str, tstr)) {
+                               free(arr->array[i]);
+                               arr->array[i] = NULL;
+                               break;
+                       }
+               }
+       }
+       for( ; i != arr->size; i++ ) 
+               arr->array[i] = arr->array[i+1];
+
+       arr->size--;
+}
+
+
diff --git a/src/libopensrf/transport_client.c b/src/libopensrf/transport_client.c
new file mode 100644 (file)
index 0000000..9a14291
--- /dev/null
@@ -0,0 +1,225 @@
+#include <opensrf/transport_client.h>
+
+
+//int main( int argc, char** argv );
+
+/*
+int main( int argc, char** argv ) {
+
+       transport_message* recv;
+       transport_message* send;
+
+       transport_client* client = client_init( "spacely.georgialibraries.org", 5222 );
+
+       // try to connect, allow 15 second connect timeout 
+       if( client_connect( client, "admin", "asdfjkjk", "system", 15 ) ) {
+               printf("Connected...\n");
+       } else { 
+               printf( "NOT Connected...\n" ); exit(99); 
+       }
+
+       while( (recv = client_recv( client, -1 )) ) {
+
+               if( recv->body ) {
+                       int len = strlen(recv->body);
+                       char buf[len + 20];
+                       memset( buf, 0, len + 20); 
+                       sprintf( buf, "Echoing...%s", recv->body );
+                       send = message_init( buf, "Echoing Stuff", "12345", recv->sender, "" );
+               } else {
+                       send = message_init( " * ECHOING * ", "Echoing Stuff", "12345", recv->sender, "" );
+               }
+
+               if( send == NULL ) { printf("something's wrong"); }
+               client_send_message( client, send );
+                               
+               message_free( send );
+               message_free( recv );
+       }
+
+       printf( "ended recv loop\n" );
+
+       return 0;
+
+}
+*/
+
+
+transport_client* client_init( const char* server, int port, const char* unix_path, int component ) {
+
+       if(server == NULL) return NULL;
+
+       /* build and clear the client object */
+       size_t c_size = sizeof( transport_client);
+       transport_client* client = safe_malloc( c_size );
+
+       /* build and clear the message list */
+       size_t l_size = sizeof( transport_message_list );
+       client->m_list = safe_malloc( l_size );
+
+       client->m_list->next = NULL;
+       client->m_list->message = NULL;
+       client->m_list->type = MESSAGE_LIST_HEAD;
+
+       /* build the session */
+       
+       client->session = init_transport( server, port, unix_path, client, component );
+
+       client->session->message_callback = client_message_handler;
+       client->error = 0;
+
+       return client;
+}
+
+
+int client_connect( transport_client* client, 
+               char* username, char* password, char* resource, 
+               int connect_timeout, enum TRANSPORT_AUTH_TYPE  auth_type ) {
+       if(client == NULL) return 0; 
+       return session_connect( client->session, username, 
+                       password, resource, connect_timeout, auth_type );
+}
+
+
+int client_disconnect( transport_client* client ) {
+       if( client == NULL ) { return 0; }
+       return session_disconnect( client->session );
+}
+
+int client_connected( transport_client* client ) {
+       if(client == NULL) return 0;
+       return client->session->state_machine->connected;
+}
+
+int client_send_message( transport_client* client, transport_message* msg ) {
+       if(client == NULL) return 0;
+       if( client->error ) return -1;
+       return session_send_msg( client->session, msg );
+}
+
+
+transport_message* client_recv( transport_client* client, int timeout ) {
+       if( client == NULL ) { return NULL; }
+
+       transport_message_node* node;
+       transport_message* msg;
+
+
+       /* see if there are any message in the messages queue */
+       if( client->m_list->next != NULL ) {
+               /* pop off the first one... */
+               node = client->m_list->next;
+               client->m_list->next = node->next;
+               msg = node->message;
+               free( node );
+               return msg;
+       }
+
+       if( timeout == -1 ) {  /* wait potentially forever for data to arrive */
+
+               while( client->m_list->next == NULL ) {
+               //      if( ! session_wait( client->session, -1 ) ) {
+                       int x;
+                       if( (x = session_wait( client->session, -1 )) ) {
+                               osrfLogDebug(OSRF_LOG_MARK, "session_wait returned failure code %d\n", x);
+                               client->error = 1;
+                               return NULL;
+                       }
+               }
+
+       } else { /* wait at most timeout seconds */
+
+       
+               /* if not, loop up to 'timeout' seconds waiting for data to arrive */
+               time_t start = time(NULL);      
+               time_t remaining = (time_t) timeout;
+
+               int counter = 0;
+
+               int wait_ret;
+               while( client->m_list->next == NULL && remaining >= 0 ) {
+
+                       if( (wait_ret= session_wait( client->session, remaining)) ) {
+                               client->error = 1;
+                               osrfLogDebug(OSRF_LOG_MARK, "session_wait returned failure code %d: setting error=1\n", wait_ret);
+                               return NULL;
+                       }
+
+                       ++counter;
+
+#ifdef _ROUTER
+                       // session_wait returns -1 if there is no more data and we're a router
+                       if( remaining == 0 ) { // && wait_ret == -1 ) {
+                               break;
+                       }
+#else
+                       if( remaining == 0 ) // or infinite loop
+                               break;
+#endif
+
+                       remaining -= (int) (time(NULL) - start);
+               }
+
+       }
+
+       /* again, see if there are any messages in the message queue */
+       if( client->m_list->next != NULL ) {
+               /* pop off the first one... */
+               node = client->m_list->next;
+               client->m_list->next = node->next;
+               msg = node->message;
+               free( node );
+               return msg;
+
+       } else {
+               return NULL;
+       }
+}
+
+/* throw the message into the message queue */
+void client_message_handler( void* client, transport_message* msg ){
+
+       if(client == NULL) return;
+       if(msg == NULL) return; 
+
+       transport_client* cli = (transport_client*) client;
+
+       size_t len = sizeof(transport_message_node);
+       transport_message_node* node = 
+               (transport_message_node*) safe_malloc(len);
+       node->type = MESSAGE_LIST_ITEM;
+       node->message = msg;
+
+
+       /* find the last node and put this onto the end */
+       transport_message_node* tail = cli->m_list;
+       transport_message_node* current = tail->next;
+
+       while( current != NULL ) {
+               tail = current;
+               current = current->next;
+       }
+       tail->next = node;
+}
+
+
+int client_free( transport_client* client ){
+       if(client == NULL) return 0; 
+
+       session_free( client->session );
+       transport_message_node* current = client->m_list->next;
+       transport_message_node* next;
+
+       /* deallocate the list of messages */
+       while( current != NULL ) {
+               next = current->next;
+               message_free( current->message );
+               free(current);
+               current = next;
+       }
+
+       free( client->m_list );
+       free( client );
+       return 1;
+}
+
diff --git a/src/libopensrf/transport_message.c b/src/libopensrf/transport_message.c
new file mode 100644 (file)
index 0000000..5c6862b
--- /dev/null
@@ -0,0 +1,357 @@
+#include <opensrf/transport_message.h>
+
+
+// ---------------------------------------------------------------------------------
+// Allocates and initializes a new transport_message
+// ---------------------------------------------------------------------------------
+transport_message* message_init( char* body, 
+               char* subject, char* thread, char* recipient, char* sender ) {
+
+       transport_message* msg = 
+               (transport_message*) safe_malloc( sizeof(transport_message) );
+
+       if( body                                        == NULL ) { body                        = ""; }
+       if( thread                              == NULL ) { thread              = ""; }
+       if( subject                             == NULL ) { subject             = ""; }
+       if( sender                              == NULL ) { sender              = ""; }
+       if( recipient                   ==      NULL ) { recipient      = ""; }
+
+       msg->body                               = strdup(body);
+       msg->thread                             = strdup(thread);
+       msg->subject                    = strdup(subject);
+       msg->recipient                  = strdup(recipient);
+       msg->sender                             = strdup(sender);
+
+       if(     msg->body               == NULL || msg->thread                          == NULL ||
+                       msg->subject    == NULL || msg->recipient                       == NULL ||
+                       msg->sender             == NULL ) {
+
+               osrfLogError(OSRF_LOG_MARK,  "message_init(): Out of Memory" );
+               return NULL;
+       }
+
+       return msg;
+}
+
+
+transport_message* new_message_from_xml( const char* msg_xml ) {
+
+       if( msg_xml == NULL || strlen(msg_xml) < 1 )
+               return NULL;
+
+       transport_message* new_msg = 
+               (transport_message*) safe_malloc( sizeof(transport_message) );
+
+       xmlKeepBlanksDefault(0);
+       xmlDocPtr msg_doc = xmlReadDoc( BAD_CAST msg_xml, NULL, NULL, 0 );
+       xmlNodePtr root = xmlDocGetRootElement(msg_doc);
+
+       xmlChar* sender = xmlGetProp(root, BAD_CAST "from");
+       xmlChar* recipient      = xmlGetProp(root, BAD_CAST "to");
+       xmlChar* subject                = xmlGetProp(root, BAD_CAST "subject");
+       xmlChar* thread         = xmlGetProp( root, BAD_CAST "thread" );
+       xmlChar* router_from    = xmlGetProp( root, BAD_CAST "router_from" );
+       xmlChar* router_to      = xmlGetProp( root, BAD_CAST "router_to" );
+       xmlChar* router_class= xmlGetProp( root, BAD_CAST "router_class" );
+       xmlChar* broadcast      = xmlGetProp( root, BAD_CAST "broadcast" );
+   xmlChar* osrf_xid    = xmlGetProp( root, BAD_CAST "osrf_xid" );
+
+   if( osrf_xid ) {
+      message_set_osrf_xid( new_msg, (char*) osrf_xid);
+      xmlFree(osrf_xid);
+   }
+
+       if( router_from ) {
+               new_msg->sender         = strdup((char*)router_from);
+       } else {
+               if( sender ) {
+                       new_msg->sender         = strdup((char*)sender);
+                       xmlFree(sender);
+               }
+       }
+
+       if( recipient ) {
+               new_msg->recipient      = strdup((char*)recipient);
+               xmlFree(recipient);
+       }
+       if(subject){
+               new_msg->subject                = strdup((char*)subject);
+               xmlFree(subject);
+       }
+       if(thread) {
+               new_msg->thread         = strdup((char*)thread);
+               xmlFree(thread);
+       }
+       if(router_from) {
+               new_msg->router_from    = strdup((char*)router_from);
+               xmlFree(router_from);
+       }
+       if(router_to) {
+               new_msg->router_to      = strdup((char*)router_to);
+               xmlFree(router_to);
+       }
+       if(router_class) {
+               new_msg->router_class = strdup((char*)router_class);
+               xmlFree(router_class);
+       }
+       if(broadcast) {
+               if(strcmp(broadcast,"0") )
+                       new_msg->broadcast      = 1;
+               xmlFree(broadcast);
+       }
+
+       xmlNodePtr search_node = root->children;
+       while( search_node != NULL ) {
+
+               if( ! strcmp( (char*) search_node->name, "thread" ) ) {
+                       if( search_node->children && search_node->children->content ) 
+                               new_msg->thread = strdup( (char*) search_node->children->content );
+               }
+
+               if( ! strcmp( (char*) search_node->name, "subject" ) ) {
+                       if( search_node->children && search_node->children->content )
+                               new_msg->subject = strdup( (char*) search_node->children->content );
+               }
+
+               if( ! strcmp( (char*) search_node->name, "body" ) ) {
+                       if( search_node->children && search_node->children->content )
+                               new_msg->body = strdup((char*) search_node->children->content );
+               }
+
+               search_node = search_node->next;
+       }
+
+       if( new_msg->thread == NULL ) 
+               new_msg->thread = strdup("");
+       if( new_msg->subject == NULL )
+               new_msg->subject = strdup("");
+       if( new_msg->body == NULL )
+               new_msg->body = strdup("");
+
+       new_msg->msg_xml = xmlDocToString(msg_doc, 0);
+   xmlFreeDoc(msg_doc);
+   xmlCleanupParser();
+
+       return new_msg;
+}
+
+void message_set_osrf_xid( transport_message* msg, char* osrf_xid ) {
+   if(!msg) return;
+   if( osrf_xid )
+      msg->osrf_xid = strdup(osrf_xid);
+   else msg->osrf_xid = strdup("");
+}
+
+void message_set_router_info( transport_message* msg, char* router_from,
+               char* router_to, char* router_class, char* router_command, int broadcast_enabled ) {
+
+       if(router_from)
+               msg->router_from                = strdup(router_from);
+       else
+               msg->router_from                = strdup("");
+
+       if(router_to)
+               msg->router_to                  = strdup(router_to);
+       else
+               msg->router_to                  = strdup("");
+
+       if(router_class)
+               msg->router_class               = strdup(router_class);
+       else 
+               msg->router_class               = strdup("");
+       
+       if(router_command)
+               msg->router_command     = strdup(router_command);
+       else
+               msg->router_command     = strdup("");
+
+       msg->broadcast = broadcast_enabled;
+
+       if( msg->router_from == NULL || msg->router_to == NULL ||
+                       msg->router_class == NULL || msg->router_command == NULL ) 
+               osrfLogError(OSRF_LOG_MARK,  "message_set_router_info(): Out of Memory" );
+
+       return;
+}
+
+
+
+/* encodes the message for traversal */
+int message_prepare_xml( transport_message* msg ) {
+       if( msg->msg_xml != NULL ) { return 1; }
+       msg->msg_xml = message_to_xml( msg );
+       return 1;
+}
+
+
+// ---------------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------------
+int message_free( transport_message* msg ){
+       if( msg == NULL ) { return 0; }
+
+       free(msg->body); 
+       free(msg->thread);
+       free(msg->subject);
+       free(msg->recipient);
+       free(msg->sender);
+       free(msg->router_from);
+       free(msg->router_to);
+       free(msg->router_class);
+       free(msg->router_command);
+   free(msg->osrf_xid);
+       if( msg->error_type != NULL ) free(msg->error_type);
+       if( msg->msg_xml != NULL ) free(msg->msg_xml);
+       free(msg);
+       return 1;
+}
+       
+// ---------------------------------------------------------------------------------
+// Allocates a char* holding the XML representation of this jabber message
+// ---------------------------------------------------------------------------------
+char* message_to_xml( const transport_message* msg ) {
+
+       int                     bufsize;
+       //xmlChar*              xmlbuf;
+       char*                   encoded_body;
+
+       xmlNodePtr      message_node;
+       xmlNodePtr      body_node;
+       xmlNodePtr      thread_node;
+       xmlNodePtr      subject_node;
+       xmlNodePtr      error_node;
+       
+       xmlDocPtr       doc;
+
+       xmlKeepBlanksDefault(0);
+
+       if( ! msg ) { 
+               osrfLogWarning(OSRF_LOG_MARK,  "Passing NULL message to message_to_xml()"); 
+               return 0; 
+       }
+
+       doc = xmlReadDoc( BAD_CAST "<message/>", NULL, NULL, XML_PARSE_NSCLEAN );
+       message_node = xmlDocGetRootElement(doc);
+
+       if( msg->is_error ) {
+               error_node = xmlNewChild(message_node, NULL, BAD_CAST "error" , NULL );
+               xmlAddChild( message_node, error_node );
+               xmlNewProp( error_node, BAD_CAST "type", BAD_CAST msg->error_type );
+               char code_buf[16];
+               memset( code_buf, 0, 16);
+               sprintf(code_buf, "%d", msg->error_code );
+               xmlNewProp( error_node, BAD_CAST "code", BAD_CAST code_buf  );
+       }
+
+       /* set from and to */
+       xmlNewProp( message_node, BAD_CAST "to", BAD_CAST msg->recipient );
+       xmlNewProp( message_node, BAD_CAST "from", BAD_CAST msg->sender );
+       xmlNewProp( message_node, BAD_CAST "router_from", BAD_CAST msg->router_from );
+       xmlNewProp( message_node, BAD_CAST "router_to", BAD_CAST msg->router_to );
+       xmlNewProp( message_node, BAD_CAST "router_class", BAD_CAST msg->router_class );
+       xmlNewProp( message_node, BAD_CAST "router_command", BAD_CAST msg->router_command );
+       xmlNewProp( message_node, BAD_CAST "osrf_xid", BAD_CAST msg->osrf_xid );
+
+       if( msg->broadcast )
+               xmlNewProp( message_node, BAD_CAST "broadcast", BAD_CAST "1" );
+
+       /* Now add nodes where appropriate */
+       char* body                              = msg->body;
+       char* subject                   = msg->subject;
+       char* thread                    = msg->thread; 
+
+       if( thread && strlen(thread) > 0 ) {
+               thread_node = xmlNewChild(message_node, NULL, (xmlChar*) "thread", NULL );
+               xmlNodePtr txt = xmlNewText((xmlChar*) thread);
+               xmlAddChild(thread_node, txt);
+               xmlAddChild(message_node, thread_node); 
+       }
+
+       if( subject && strlen(subject) > 0 ) {
+               subject_node = xmlNewChild(message_node, NULL, (xmlChar*) "subject", NULL );
+               xmlNodePtr txt = xmlNewText((xmlChar*) subject);
+               xmlAddChild(subject_node, txt);
+               xmlAddChild( message_node, subject_node ); 
+       }
+
+       if( body && strlen(body) > 0 ) {
+               body_node = xmlNewChild(message_node, NULL, (xmlChar*) "body", NULL);
+               xmlNodePtr txt = xmlNewText((xmlChar*) body);
+               xmlAddChild(body_node, txt);
+               xmlAddChild( message_node, body_node ); 
+       }
+
+       xmlBufferPtr xmlbuf = xmlBufferCreate();
+       xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
+       char* xml = strdup((char*) (xmlBufferContent(xmlbuf)));
+       xmlBufferFree(xmlbuf);
+       xmlFreeDoc( doc );               
+       xmlCleanupParser();
+       return xml;
+}
+
+
+
+void jid_get_username( const char* jid, char buf[], int size ) {
+
+       if( jid == NULL ) { return; }
+
+       /* find the @ and return whatever is in front of it */
+       int len = strlen( jid );
+       int i;
+       for( i = 0; i != len; i++ ) {
+               if( jid[i] == 64 ) { /*ascii @*/
+                       if(i > size)  i = size;
+                       strncpy( buf, jid, i );
+                       return;
+               }
+       }
+}
+
+
+void jid_get_resource( const char* jid, char buf[], int size)  {
+       if( jid == NULL ) { return; }
+       int len = strlen( jid );
+       int i;
+       for( i = 0; i!= len; i++ ) {
+               if( jid[i] == 47 ) { /* ascii / */
+                       const char* start = jid + i + 1; /* right after the '/' */
+                       int rlen = len - (i+1);
+                       if(rlen > size) rlen = size;
+                       strncpy( buf, start, rlen );
+               }
+       }
+}
+
+void jid_get_domain( const char* jid, char buf[], int size ) {
+
+       if(jid == NULL) return;
+
+       int len = strlen(jid);
+       int i;
+       int index1 = 0; 
+       int index2 = 0;
+
+       for( i = 0; i!= len; i++ ) {
+               if(jid[i] == 64) /* ascii @ */
+                       index1 = i + 1;
+               else if(jid[i] == 47 && index1 != 0) /* ascii / */
+                       index2 = i;
+       }
+
+       if( index1 > 0 && index2 > 0 && index2 > index1 ) {
+               int dlen = index2 - index1;
+               if(dlen > size) dlen = size;
+               memcpy( buf, jid + index1, dlen );
+       }
+}
+
+void set_msg_error( transport_message* msg, char* type, int err_code ) {
+
+       if( type != NULL && strlen( type ) > 0 ) {
+               msg->error_type = safe_malloc( strlen(type)+1); 
+               strcpy( msg->error_type, type );
+               msg->error_code = err_code;
+       }
+       msg->is_error = 1;
+}
diff --git a/src/libopensrf/transport_session.c b/src/libopensrf/transport_session.c
new file mode 100644 (file)
index 0000000..43483f0
--- /dev/null
@@ -0,0 +1,635 @@
+#include <opensrf/transport_session.h>
+
+
+
+// ---------------------------------------------------------------------------------
+// returns a built and allocated transport_session object.
+// This codes does no network activity, only memory initilization
+// ---------------------------------------------------------------------------------
+transport_session* init_transport(  const char* server, 
+       int port, const char* unix_path, void* user_data, int component ) {
+
+       /* create the session struct */
+       transport_session* session = 
+               (transport_session*) safe_malloc( sizeof(transport_session) );
+
+       session->user_data = user_data;
+
+       session->component = component;
+
+       /* initialize the data buffers */
+       session->body_buffer                    = buffer_init( JABBER_BODY_BUFSIZE );
+       session->subject_buffer         = buffer_init( JABBER_SUBJECT_BUFSIZE );
+       session->thread_buffer          = buffer_init( JABBER_THREAD_BUFSIZE );
+       session->from_buffer                    = buffer_init( JABBER_JID_BUFSIZE );
+       session->status_buffer          = buffer_init( JABBER_STATUS_BUFSIZE );
+       session->recipient_buffer       = buffer_init( JABBER_JID_BUFSIZE );
+       session->message_error_type = buffer_init( JABBER_JID_BUFSIZE );
+       session->session_id                     = buffer_init( 64 ); 
+
+       /* for OpenSRF extensions */
+       session->router_to_buffer               = buffer_init( JABBER_JID_BUFSIZE );
+       session->router_from_buffer     = buffer_init( JABBER_JID_BUFSIZE );
+       session->osrf_xid_buffer        = buffer_init( JABBER_JID_BUFSIZE );
+       session->router_class_buffer    = buffer_init( JABBER_JID_BUFSIZE );
+       session->router_command_buffer  = buffer_init( JABBER_JID_BUFSIZE );
+
+
+       if(     session->body_buffer            == NULL || session->subject_buffer       == NULL        ||
+                       session->thread_buffer  == NULL || session->from_buffer          == NULL        ||
+                       session->status_buffer  == NULL || session->recipient_buffer == NULL ||
+                       session->router_to_buffer       == NULL || session->router_from_buffer   == NULL ||
+                       session->router_class_buffer == NULL || session->router_command_buffer == NULL ||
+                       session->session_id == NULL ) { 
+
+               osrfLogError(OSRF_LOG_MARK,  "init_transport(): buffer_init returned NULL" );
+               return 0;
+       }
+
+
+       /* initialize the jabber state machine */
+       session->state_machine = (jabber_machine*) safe_malloc( sizeof(jabber_machine) );
+
+       /* initialize the sax push parser */
+       session->parser_ctxt = xmlCreatePushParserCtxt(SAXHandler, session, "", 0, NULL);
+
+       /* initialize the transport_socket structure */
+       session->sock_mgr = (socket_manager*) safe_malloc( sizeof(socket_manager) );
+
+       session->sock_mgr->data_received = &grab_incoming;
+       session->sock_mgr->blob = session;
+       
+       session->port = port;
+       session->server = strdup(server);
+       if(unix_path)   
+               session->unix_path = strdup(unix_path);
+       else session->unix_path = NULL;
+
+       session->sock_id = 0;
+
+       return session;
+}
+
+
+
+/* XXX FREE THE BUFFERS */
+int session_free( transport_session* session ) {
+       if( ! session ) { return 0; }
+
+       if(session->sock_mgr)
+               socket_manager_free(session->sock_mgr);
+
+       if( session->state_machine ) free( session->state_machine );
+       if( session->parser_ctxt) {
+               xmlFreeDoc( session->parser_ctxt->myDoc );
+               xmlFreeParserCtxt(session->parser_ctxt);
+       }
+
+       xmlCleanupCharEncodingHandlers();
+       xmlDictCleanup();
+       xmlCleanupParser();
+
+       buffer_free(session->body_buffer);
+       buffer_free(session->subject_buffer);
+       buffer_free(session->thread_buffer);
+       buffer_free(session->from_buffer);
+       buffer_free(session->recipient_buffer);
+       buffer_free(session->status_buffer);
+       buffer_free(session->message_error_type);
+       buffer_free(session->router_to_buffer);
+       buffer_free(session->router_from_buffer);
+       buffer_free(session->osrf_xid_buffer);
+       buffer_free(session->router_class_buffer);
+       buffer_free(session->router_command_buffer);
+       buffer_free(session->session_id);
+
+       free(session->server);
+       free(session->unix_path);
+
+       free( session );
+       return 1;
+}
+
+
+int session_wait( transport_session* session, int timeout ) {
+       if( ! session || ! session->sock_mgr ) {
+               return 0;
+       }
+
+       int ret =  socket_wait( session->sock_mgr, timeout, session->sock_id );
+
+       if( ret ) {
+               osrfLogDebug(OSRF_LOG_MARK, "socket_wait returned error code %d", ret);
+               session->state_machine->connected = 0;
+       }
+       return ret;
+}
+
+int session_send_msg( 
+               transport_session* session, transport_message* msg ) {
+
+       if( ! session ) { return -1; }
+
+       if( ! session->state_machine->connected ) {
+               osrfLogWarning(OSRF_LOG_MARK, "State machine is not connected in send_msg()");
+               return -1;
+       }
+
+       message_prepare_xml( msg );
+       //tcp_send( session->sock_obj, msg->msg_xml );
+       return socket_send( session->sock_id, msg->msg_xml );
+
+}
+
+
+/* connects to server and connects to jabber */
+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 size1 = 0;
+       int size2 = 0;
+
+       if( ! session ) { 
+               osrfLogWarning(OSRF_LOG_MARK,  "session is null in connect" );
+               return 0; 
+       }
+
+
+       //char* server = session->sock_obj->server;
+       char* server = session->server;
+
+       if( ! session->sock_id ) {
+
+               if(session->port > 0) {
+                       if( (session->sock_id = socket_open_tcp_client(
+                               session->sock_mgr, session->port, session->server)) <= 0 ) 
+                       return 0;
+
+               } else if(session->unix_path != NULL) {
+                       if( (session->sock_id = socket_open_unix_client(
+                               session->sock_mgr, session->unix_path)) <= 0 ) 
+                       return 0;
+               }
+               else {
+                       osrfLogWarning( OSRF_LOG_MARK, "Can't open session: no port or unix path" );
+                       return 0;
+               }
+       }
+
+       if( session->component ) {
+
+               /* the first Jabber connect stanza */
+               char* our_hostname = getenv("HOSTNAME");
+               size1 = 150 + strlen( server );
+               char stanza1[ size1 ]; 
+               memset( stanza1, 0, size1 );
+               sprintf( stanza1, 
+                               "<stream:stream version='1.0' xmlns:stream='http://etherx.jabber.org/streams' "
+                               "xmlns='jabber:component:accept' to='%s' from='%s' xml:lang='en'>",
+                               username, our_hostname );
+
+               /* send the first stanze */
+               session->state_machine->connecting = CONNECTING_1;
+
+//             if( ! tcp_send( session->sock_obj, stanza1 ) ) {
+               if( socket_send( session->sock_id, stanza1 ) ) {
+                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
+                       return 0;
+               }
+       
+               /* wait for reply */
+               //tcp_wait( session->sock_obj, connect_timeout ); /* make the timeout smarter XXX */
+               socket_wait(session->sock_mgr, connect_timeout, session->sock_id);
+       
+               /* server acknowledges our existence, now see if we can login */
+               if( session->state_machine->connecting == CONNECTING_2 ) {
+       
+                       int ss = session->session_id->n_used + strlen(password) + 5;
+                       char hashstuff[ss];
+                       memset(hashstuff,0,ss);
+                       sprintf( hashstuff, "%s%s", session->session_id->buf, password );
+
+                       char* hash = shahash( hashstuff );
+                       size2 = 100 + strlen( hash );
+                       char stanza2[ size2 ];
+                       memset( stanza2, 0, size2 );
+                       sprintf( stanza2, "<handshake>%s</handshake>", hash );
+       
+                       //if( ! tcp_send( session->sock_obj, stanza2 )  ) {
+                       if( socket_send( session->sock_id, stanza2 )  ) {
+                               osrfLogWarning(OSRF_LOG_MARK, "error sending");
+                               return 0;
+                       }
+               }
+
+       } else { /* we're not a component */
+
+               /* the first Jabber connect stanza */
+               size1 = 100 + strlen( server );
+               char stanza1[ size1 ]; 
+               memset( stanza1, 0, size1 );
+               sprintf( stanza1, 
+                               "<stream:stream to='%s' xmlns='jabber:client' "
+                               "xmlns:stream='http://etherx.jabber.org/streams'>",
+                       server );
+       
+
+               /* send the first stanze */
+               session->state_machine->connecting = CONNECTING_1;
+               //if( ! tcp_send( session->sock_obj, stanza1 ) ) {
+               if( socket_send( session->sock_id, stanza1 ) ) {
+                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
+                       return 0;
+               }
+
+
+               /* wait for reply */
+               //tcp_wait( session->sock_obj, connect_timeout ); /* make the timeout smarter XXX */
+               socket_wait( session->sock_mgr, connect_timeout, session->sock_id ); /* make the timeout smarter XXX */
+
+               if( auth_type == AUTH_PLAIN ) {
+
+                       /* the second jabber connect stanza including login info*/
+                       size2 = 150 + strlen( username ) + strlen(password) + strlen(resource);
+                       char stanza2[ size2 ];
+                       memset( stanza2, 0, size2 );
+               
+                       sprintf( stanza2, 
+                                       "<iq id='123456789' type='set'><query xmlns='jabber:iq:auth'>"
+                                       "<username>%s</username><password>%s</password><resource>%s</resource></query></iq>",
+                                       username, password, resource );
+       
+                       /* server acknowledges our existence, now see if we can login */
+                       if( session->state_machine->connecting == CONNECTING_2 ) {
+                               //if( ! tcp_send( session->sock_obj, stanza2 )  ) {
+                               if( socket_send( session->sock_id, stanza2 )  ) {
+                                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
+                                       return 0;
+                               }
+                       }
+
+               } else if( auth_type == AUTH_DIGEST ) {
+
+                       int ss = session->session_id->n_used + strlen(password) + 5;
+                       char hashstuff[ss];
+                       memset(hashstuff,0,ss);
+                       sprintf( hashstuff, "%s%s", session->session_id->buf, password );
+
+                       char* hash = shahash( hashstuff );
+
+                       /* the second jabber connect stanza including login info*/
+                       size2 = 150 + strlen( hash ) + strlen(password) + strlen(resource);
+                       char stanza2[ size2 ];
+                       memset( stanza2, 0, size2 );
+               
+                       sprintf( stanza2, 
+                                       "<iq id='123456789' type='set'><query xmlns='jabber:iq:auth'>"
+                                       "<username>%s</username><digest>%s</digest><resource>%s</resource></query></iq>",
+                                       username, hash, resource );
+       
+                       /* server acknowledges our existence, now see if we can login */
+                       if( session->state_machine->connecting == CONNECTING_2 ) {
+                               //if( ! tcp_send( session->sock_obj, stanza2 )  ) {
+                               if( socket_send( session->sock_id, stanza2 )  ) {
+                                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
+                                       return 0;
+                               }
+                       }
+
+               }
+
+       } // not component
+
+
+       /* wait for reply */
+       //tcp_wait( session->sock_obj, connect_timeout );
+       socket_wait( session->sock_mgr, connect_timeout, session->sock_id );
+
+       if( session->state_machine->connected ) {
+               /* yar! */
+               return 1;
+       }
+
+       return 0;
+}
+
+// ---------------------------------------------------------------------------------
+// TCP data callback. Shove the data into the push parser.
+// ---------------------------------------------------------------------------------
+//void grab_incoming( void * session, char* data ) {
+void grab_incoming(void* blob, socket_manager* mgr, int sockid, char* data, int parent) {
+       transport_session* ses = (transport_session*) blob;
+       if( ! ses ) { return; }
+       xmlParseChunk(ses->parser_ctxt, data, strlen(data), 0);
+}
+
+
+void startElementHandler(
+       void *session, const xmlChar *name, const xmlChar **atts) {
+
+       transport_session* ses = (transport_session*) session;
+       if( ! ses ) { return; }
+
+       
+       if( strcmp( name, "message" ) == 0 ) {
+               ses->state_machine->in_message = 1;
+               buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) );
+               buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) );
+               buffer_add( ses->router_from_buffer, get_xml_attr( atts, "router_from" ) );
+               buffer_add( ses->osrf_xid_buffer, get_xml_attr( atts, "osrf_xid" ) );
+               buffer_add( ses->router_to_buffer, get_xml_attr( atts, "router_to" ) );
+               buffer_add( ses->router_class_buffer, get_xml_attr( atts, "router_class" ) );
+               buffer_add( ses->router_command_buffer, get_xml_attr( atts, "router_command" ) );
+               char* broadcast = get_xml_attr( atts, "broadcast" );
+               if( broadcast )
+                       ses->router_broadcast = atoi( broadcast );
+
+               return;
+       }
+
+       if( ses->state_machine->in_message ) {
+
+               if( strcmp( name, "body" ) == 0 ) {
+                       ses->state_machine->in_message_body = 1;
+                       return;
+               }
+       
+               if( strcmp( name, "subject" ) == 0 ) {
+                       ses->state_machine->in_subject = 1;
+                       return;
+               }
+       
+               if( strcmp( name, "thread" ) == 0 ) {
+                       ses->state_machine->in_thread = 1;
+                       return;
+               }
+
+       }
+
+       if( strcmp( name, "presence" ) == 0 ) {
+               ses->state_machine->in_presence = 1;
+               buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) );
+               buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) );
+               return;
+       }
+
+       if( strcmp( name, "status" ) == 0 ) {
+               ses->state_machine->in_status = 1;
+               return;
+       }
+
+
+       if( strcmp( name, "stream:error" ) == 0 ) {
+               ses->state_machine->in_error = 1;
+               ses->state_machine->connected = 0;
+               osrfLogWarning(  OSRF_LOG_MARK, "Received <stream:error> message from Jabber server" );
+               return;
+       }
+
+
+       /* first server response from a connect attempt */
+       if( strcmp( name, "stream:stream" ) == 0 ) {
+               if( ses->state_machine->connecting == CONNECTING_1 ) {
+                       ses->state_machine->connecting = CONNECTING_2;
+                       buffer_add( ses->session_id, get_xml_attr(atts, "id") );
+               }
+       }
+
+       if( strcmp( name, "handshake" ) == 0 ) {
+               ses->state_machine->connected = 1;
+               ses->state_machine->connecting = 0;
+               return;
+       }
+
+
+       if( strcmp( name, "error" ) == 0 ) {
+               ses->state_machine->in_message_error = 1;
+               buffer_add( ses->message_error_type, get_xml_attr( atts, "type" ) );
+               ses->message_error_code = atoi( get_xml_attr( atts, "code" ) );
+               osrfLogInfo( OSRF_LOG_MARK,  "Received <error> message with type %s and code %s", 
+                       get_xml_attr( atts, "type"), get_xml_attr( atts, "code") );
+               return;
+       }
+
+       if( strcmp( name, "iq" ) == 0 ) {
+               ses->state_machine->in_iq = 1;
+
+               if( strcmp( get_xml_attr(atts, "type"), "result") == 0 
+                               && ses->state_machine->connecting == CONNECTING_2 ) {
+                       ses->state_machine->connected = 1;
+                       ses->state_machine->connecting = 0;
+                       return;
+               }
+
+               if( strcmp( get_xml_attr(atts, "type"), "error") == 0 ) {
+                       osrfLogWarning( OSRF_LOG_MARK,  "Error connecting to jabber" );
+                       return;
+               }
+       }
+}
+
+char* get_xml_attr( const xmlChar** atts, char* attr_name ) {
+       int i;
+       if (atts != NULL) {
+               for(i = 0;(atts[i] != NULL);i++) {
+                       if( strcmp( atts[i++], attr_name ) == 0 ) {
+                               if( atts[i] != NULL ) {
+                                       return (char*) atts[i];
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+
+
+// ------------------------------------------------------------------
+// See which tags are ending
+// ------------------------------------------------------------------
+void endElementHandler( void *session, const xmlChar *name) {
+       transport_session* ses = (transport_session*) session;
+       if( ! ses ) { return; }
+
+       if( strcmp( name, "message" ) == 0 ) {
+
+
+               /* pass off the message info the callback */
+               if( ses->message_callback ) {
+
+                       /* here it's ok to pass in the raw buffers because
+                               message_init allocates new space for the chars 
+                               passed in */
+                       transport_message* msg =  message_init( 
+                               ses->body_buffer->buf, 
+                               ses->subject_buffer->buf,
+                               ses->thread_buffer->buf, 
+                               ses->recipient_buffer->buf, 
+                               ses->from_buffer->buf );
+
+                       message_set_router_info( msg, 
+                               ses->router_from_buffer->buf, 
+                               ses->router_to_buffer->buf, 
+                               ses->router_class_buffer->buf,
+                               ses->router_command_buffer->buf,
+                               ses->router_broadcast );
+
+         message_set_osrf_xid( msg, ses->osrf_xid_buffer->buf );
+
+                       if( ses->message_error_type->n_used > 0 ) {
+                               set_msg_error( msg, ses->message_error_type->buf, ses->message_error_code );
+                       }
+
+                       if( msg == NULL ) { return; }
+                       ses->message_callback( ses->user_data, msg );
+               }
+
+               ses->state_machine->in_message = 0;
+               reset_session_buffers( session );
+               return;
+       }
+       
+       if( strcmp( name, "body" ) == 0 ) {
+               ses->state_machine->in_message_body = 0;
+               return;
+       }
+
+       if( strcmp( name, "subject" ) == 0 ) {
+               ses->state_machine->in_subject = 0;
+               return;
+       }
+
+       if( strcmp( name, "thread" ) == 0 ) {
+               ses->state_machine->in_thread = 0;
+               return;
+       }
+       
+       if( strcmp( name, "iq" ) == 0 ) {
+               ses->state_machine->in_iq = 0;
+               if( ses->message_error_code > 0 ) {
+                       osrfLogWarning( OSRF_LOG_MARK,  "Error in IQ packet: code %d",  ses->message_error_code );
+                       osrfLogWarning( OSRF_LOG_MARK,  "Error 401 means not authorized" );
+               }
+               reset_session_buffers( session );
+               return;
+       }
+
+       if( strcmp( name, "presence" ) == 0 ) {
+               ses->state_machine->in_presence = 0;
+               /*
+               if( ses->presence_callback ) {
+                       // call the callback with the status, etc.
+               }
+               */
+               reset_session_buffers( session );
+               return;
+       }
+
+       if( strcmp( name, "status" ) == 0 ) {
+               ses->state_machine->in_status = 0;
+               return;
+       }
+
+       if( strcmp( name, "error" ) == 0 ) {
+               ses->state_machine->in_message_error = 0;
+               return;
+       }
+
+       if( strcmp( name, "error:error" ) == 0 ) {
+               ses->state_machine->in_error = 0;
+               return;
+       }
+}
+
+int reset_session_buffers( transport_session* ses ) {
+       buffer_reset( ses->body_buffer );
+       buffer_reset( ses->subject_buffer );
+       buffer_reset( ses->thread_buffer );
+       buffer_reset( ses->from_buffer );
+       buffer_reset( ses->recipient_buffer );
+       buffer_reset( ses->router_from_buffer );
+       buffer_reset( ses->osrf_xid_buffer );
+       buffer_reset( ses->router_to_buffer );
+       buffer_reset( ses->router_class_buffer );
+       buffer_reset( ses->router_command_buffer );
+       buffer_reset( ses->message_error_type );
+       buffer_reset( ses->session_id );
+
+       return 1;
+}
+
+// ------------------------------------------------------------------
+// takes data out of the body of the message and pushes it into
+// the appropriate buffer
+// ------------------------------------------------------------------
+void characterHandler(
+               void *session, const xmlChar *ch, int len) {
+
+       char data[len+1];
+       memset( data, 0, len+1 );
+       strncpy( data, (char*) ch, len );
+       data[len] = 0;
+
+       //printf( "Handling characters: %s\n", data );
+       transport_session* ses = (transport_session*) session;
+       if( ! ses ) { return; }
+
+       /* set the various message parts */
+       if( ses->state_machine->in_message ) {
+
+               if( ses->state_machine->in_message_body ) {
+                       buffer_add( ses->body_buffer, data );
+               }
+
+               if( ses->state_machine->in_subject ) {
+                       buffer_add( ses->subject_buffer, data );
+               }
+
+               if( ses->state_machine->in_thread ) {
+                       buffer_add( ses->thread_buffer, data );
+               }
+       }
+
+       /* set the presence status */
+       if( ses->state_machine->in_presence && ses->state_machine->in_status ) {
+               buffer_add( ses->status_buffer, data );
+       }
+
+       if( ses->state_machine->in_error ) {
+               /* for now... */
+               osrfLogWarning( OSRF_LOG_MARK,  "ERROR Xml fragment: %s\n", ch );
+       }
+
+}
+
+/* XXX change to warning handlers */
+void  parseWarningHandler( void *session, const char* msg, ... ) {
+
+       va_list args;
+       va_start(args, msg);
+       fprintf(stdout, "transport_session XML WARNING");
+       vfprintf(stdout, msg, args);
+       va_end(args);
+       fprintf(stderr, "XML WARNING: %s\n", msg ); 
+}
+
+void  parseErrorHandler( void *session, const char* msg, ... ){
+
+       va_list args;
+       va_start(args, msg);
+       fprintf(stdout, "transport_session XML ERROR");
+       vfprintf(stdout, msg, args);
+       va_end(args);
+       fprintf(stderr, "XML ERROR: %s\n", msg ); 
+
+}
+
+int session_disconnect( transport_session* session ) {
+       if( session == NULL ) { return 0; }
+       //tcp_send( session->sock_obj, "</stream:stream>");
+       socket_send(session->sock_id, "</stream:stream>");
+       socket_disconnect(session->sock_mgr, session->sock_id);
+       return 0;
+       //return tcp_disconnect( session->sock_obj );
+}
+
diff --git a/src/libopensrf/utils.c b/src/libopensrf/utils.c
new file mode 100644 (file)
index 0000000..07ed9a2
--- /dev/null
@@ -0,0 +1,475 @@
+/*
+Copyright (C) 2005  Georgia Public Library Service 
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+*/
+
+#include <opensrf/utils.h>
+#include <errno.h>
+
+inline void* safe_malloc( int size ) {
+       void* ptr = (void*) malloc( size );
+       if( ptr == NULL ) {
+               perror("safe_malloc(): Out of Memory" );
+               exit(99);
+       }
+       memset( ptr, 0, size );
+       return ptr;
+}
+
+/****************
+ The following static variables, and the following two functions,
+ overwrite the argv array passed to main().  The purpose is to
+ change the program name as reported by ps and similar utilities.
+
+ Warning: this code makes the non-portable assumption that the
+ strings to which argv[] points are contiguous in memory.  The
+ C Standard makes no such guarantee.
+ ****************/
+static char** global_argv = NULL;
+static int global_argv_size = 0;
+
+int init_proc_title( int argc, char* argv[] ) {
+
+       global_argv = argv;
+
+       int i = 0;
+       while( i < argc ) {
+               int len = strlen( global_argv[i]);
+               bzero( global_argv[i++], len );
+               global_argv_size += len;
+       }
+
+       global_argv_size -= 2;
+       return 0;
+}
+
+int set_proc_title( char* format, ... ) {
+       VA_LIST_TO_STRING(format);
+       bzero( *(global_argv), global_argv_size );
+       return snprintf( *(global_argv), global_argv_size, VA_BUF );
+}
+
+
+/* utility method for profiling */
+double get_timestamp_millis() {
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       double time     = (int)tv.tv_sec        + ( ((double)tv.tv_usec / 1000000) );
+       return time;
+}
+
+
+/* setting/clearing file flags */
+int set_fl( int fd, int flags ) {
+       
+       int val;
+
+       if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) 
+               return -1;
+
+       val |= flags;
+
+       if( fcntl( fd, F_SETFL, val ) < 0 ) 
+               return -1;
+
+       return 0;
+}
+       
+int clr_fl( int fd, int flags ) {
+       
+       int val;
+
+       if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) 
+               return -1;
+
+       val &= ~flags;
+
+       if( fcntl( fd, F_SETFL, val ) < 0 ) 
+               return -1;
+
+       return 0;
+}
+
+long va_list_size(const char* format, va_list args) {
+       int len = 0;
+       len = vsnprintf(NULL, 0, format, args);
+       va_end(args);
+       len += 2;
+       return len;
+}
+
+
+char* va_list_to_string(const char* format, ...) {
+
+       long len = 0;
+       va_list args;
+       va_list a_copy;
+
+       va_copy(a_copy, args);
+
+       va_start(args, format);
+       len = va_list_size(format, args);
+
+       char buf[len];
+       memset(buf, 0, len);
+
+       va_start(a_copy, format);
+       vsnprintf(buf, len - 1, format, a_copy);
+       va_end(a_copy);
+       return strdup(buf);
+}
+
+// ---------------------------------------------------------------------------------
+// Flesh out a ubiqitous growing string buffer
+// ---------------------------------------------------------------------------------
+
+growing_buffer* buffer_init(int num_initial_bytes) {
+
+       if( num_initial_bytes > BUFFER_MAX_SIZE ) return NULL;
+
+       size_t len = sizeof(growing_buffer);
+
+       growing_buffer* gb;
+       OSRF_MALLOC(gb, len);
+
+       gb->n_used = 0;/* nothing stored so far */
+       gb->size = num_initial_bytes;
+       OSRF_MALLOC(gb->buf, gb->size + 1);
+
+       return gb;
+}
+
+
+int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
+
+       if(!gb || !format) return 0; 
+
+       long len = 0;
+       va_list args;
+       va_list a_copy;
+
+       va_copy(a_copy, args);
+
+       va_start(args, format);
+       len = va_list_size(format, args);
+
+       char buf[len];
+       memset(buf, 0, len);
+
+       va_start(a_copy, format);
+       vsnprintf(buf, len - 1, format, a_copy);
+       va_end(a_copy);
+
+       return buffer_add(gb, buf);
+
+}
+
+
+int buffer_add(growing_buffer* gb, char* data) {
+       if(!(gb && data)) return 0;
+
+       int data_len = strlen( data );
+
+       if(data_len == 0) return 0;
+
+       int total_len = data_len + gb->n_used;
+
+       if( total_len >= gb->size ) {
+               while( total_len >= gb->size ) {
+                       gb->size *= 2;
+               }
+       
+               if( gb->size > BUFFER_MAX_SIZE ) {
+                       fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
+                       buffer_free( gb );
+                       return 0;
+               }
+       
+               char* new_data;
+               OSRF_MALLOC(new_data, gb->size );
+       
+               strcpy( new_data, gb->buf );
+               free( gb->buf );
+               gb->buf = new_data;
+       }
+
+       strcat( gb->buf, data );
+       gb->n_used = total_len;
+       return total_len;
+}
+
+
+int buffer_reset( growing_buffer *gb){
+       if( gb == NULL ) { return 0; }
+       if( gb->buf == NULL ) { return 0; }
+       memset( gb->buf, 0, gb->size );
+       gb->n_used = 0;
+       return 1;
+}
+
+/* Return a pointer to the text within a growing_buffer, */
+/* while destroying the growing_buffer itself.           */
+
+char* buffer_release( growing_buffer* gb) {
+       char* s = gb->buf;
+       s[gb->n_used] = '\0';
+       free( gb );
+       return s;
+}
+
+/* Destroy a growing_buffer and the text it contains */
+
+int buffer_free( growing_buffer* gb ) {
+       if( gb == NULL ) 
+               return 0;
+       free( gb->buf );
+       free( gb );
+       return 1;
+}
+
+char* buffer_data( growing_buffer *gb) {
+       return strdup( gb->buf );
+}
+
+
+/*
+#define OSRF_BUFFER_ADD_CHAR(gb, c)\
+       do {\
+               if(gb) {\
+                       if(gb->n_used < gb->size - 1)\
+                               gb->buf[gb->n_used++] = c;\
+                       else\
+                               buffer_add_char(gb, c);\
+               }\
+       }while(0)
+       */
+
+int buffer_add_char(growing_buffer* gb, char c) {
+       char buf[2];
+       buf[0] = c;
+       buf[1] = '\0';
+       buffer_add(gb, buf);
+       return 1;
+}
+
+
+
+char* uescape( const char* string, int size, int full_escape ) {
+
+       growing_buffer* buf = buffer_init(size + 64);
+       int clen = 0;
+       int idx = 0;
+       unsigned long int c = 0x0;
+
+       while (string[idx]) {
+
+               c = 0x0;
+
+               if ((unsigned char)string[idx] >= 0x80) { // not ASCII
+
+                       if ((unsigned char)string[idx] >= 0xC0 && (unsigned char)string[idx] <= 0xF4) { // starts a UTF8 string
+
+                               clen = 1;
+                               if (((unsigned char)string[idx] & 0xF0) == 0xF0) {
+                                       clen = 3;
+                                       c = (unsigned char)string[idx] ^ 0xF0;
+
+                               } else if (((unsigned char)string[idx] & 0xE0) == 0xE0) {
+                                       clen = 2;
+                                       c = (unsigned char)string[idx] ^ 0xE0;
+
+                               } else if (((unsigned char)string[idx] & 0xC0) == 0xC0) {
+                                       clen = 1;
+                                       c = (unsigned char)string[idx] ^ 0xC0;
+                               }
+
+                               for (;clen;clen--) {
+
+                                       idx++; // look at the next byte
+                                       c = (c << 6) | ((unsigned char)string[idx] & 0x3F); // add this byte worth
+
+                               }
+
+                               buffer_fadd(buf, "\\u%04x", c);
+
+                       } else {
+                               buffer_free(buf);
+                               return NULL;
+                       }
+
+               } else {
+                       c = string[idx];
+
+                       /* escape the usual suspects */
+                       if(full_escape) {
+                               switch(c) {
+                                       case '"':
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               OSRF_BUFFER_ADD_CHAR(buf, '"');
+                                               break;
+       
+                                       case '\b':
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               OSRF_BUFFER_ADD_CHAR(buf, 'b');
+                                               break;
+       
+                                       case '\f':
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               OSRF_BUFFER_ADD_CHAR(buf, 'f');
+                                               break;
+       
+                                       case '\t':
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               OSRF_BUFFER_ADD_CHAR(buf, 't');
+                                               break;
+       
+                                       case '\n':
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               OSRF_BUFFER_ADD_CHAR(buf, 'n');
+                                               break;
+       
+                                       case '\r':
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               OSRF_BUFFER_ADD_CHAR(buf, 'r');
+                                               break;
+
+                                       case '\\':
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
+                                               break;
+
+                                       default:
+                                               if( c < 32 ) buffer_fadd(buf, "\\u%04x", c);
+                                               else OSRF_BUFFER_ADD_CHAR(buf, c);
+                               }
+
+                       } else {
+                               OSRF_BUFFER_ADD_CHAR(buf, c);
+                       }
+               }
+
+               idx++;
+       }
+
+       char* d = buffer_data(buf);
+       buffer_free(buf);
+       return d;
+}
+
+
+// A function to turn a process into a daemon and set it's process name in ps/top
+int daemonize() {
+       int f = fork();
+
+       if (f == -1) {
+               perror("Failed to fork!");
+               return -1;
+
+       } else if (f == 0) { // We're in the child now...
+               setsid();
+               return 0;
+
+       } else { // We're in the parent...
+               exit(0);
+       }
+}
+
+
+/* Return 1 if the string represents an integer,  */
+/* as recognized by strtol(); Otherwise return 0. */
+
+int stringisnum(char* s) {
+       char* w;
+       strtol(s, &w, 10);
+       return *w ? 0 : 1;
+}
+       
+
+
+char* file_to_string(const char* filename) {
+
+       if(!filename) return NULL;
+
+       int len = 1024;
+       char buf[len];
+       bzero(buf, len);
+       growing_buffer* gb = buffer_init(len);
+
+       FILE* file = fopen(filename, "r");
+       if(!file) {
+               int l = strlen(filename) + 64;
+               char b[l];
+               snprintf(b,l,"Unable to open file [%s] in file_to_string()", filename);
+               perror(b);
+               return NULL;
+       }
+
+       while(fgets(buf, len - 1, file)) {
+               buffer_add(gb, buf);
+               bzero(buf, len);
+       }
+
+       fclose(file);
+
+       char* data = buffer_data(gb);
+       buffer_free(gb);
+       return data;
+}
+
+
+char* md5sum( char* text, ... ) {
+
+       struct md5_ctx ctx;
+       unsigned char digest[16];
+
+       MD5_start (&ctx);
+
+       VA_LIST_TO_STRING(text);
+
+       int i;
+       for ( i=0 ; i != strlen(VA_BUF) ; i++ )
+               MD5_feed (&ctx, VA_BUF[i]);
+
+       MD5_stop (&ctx, digest);
+
+       char buf[16];
+       memset(buf,0,16);
+
+       char final[256];
+       memset(final,0,256);
+
+       for ( i=0 ; i<16 ; i++ ) {
+               sprintf(buf, "%02x", digest[i]);
+               strcat( final, buf );
+       }
+
+       return strdup(final);
+
+}
+
+int osrfUtilsCheckFileDescriptor( int fd ) {
+
+       fd_set tmpset;
+       FD_ZERO(&tmpset);
+       FD_SET(fd, &tmpset);
+
+       struct timeval tv;
+       tv.tv_sec = 0;
+       tv.tv_usec = 0;
+
+       if( select(fd + 1, &tmpset, NULL, NULL, &tv) == -1 ) {
+               if( errno == EBADF ) return -1;
+       }
+
+       return 0;
+}
+
diff --git a/src/libopensrf/xml_utils.c b/src/libopensrf/xml_utils.c
new file mode 100644 (file)
index 0000000..e3ef206
--- /dev/null
@@ -0,0 +1,121 @@
+#include <opensrf/xml_utils.h>
+
+
+void recurse_doc( xmlNodePtr node ) {
+       if( node == NULL ) return;
+       printf("Recurse: %s =>  %s", node->name, node->content );
+       xmlNodePtr t = node->children;
+       while(t) {
+               recurse_doc(t);
+               t = t->next;
+       }
+}
+
+
+
+jsonObject* xmlDocToJSON(xmlDocPtr doc) {
+       if(!doc) return NULL;
+       return _xmlToJSON(xmlDocGetRootElement(doc), NULL);
+}
+
+jsonObject* _xmlToJSON(xmlNodePtr node, jsonObject* obj) {
+
+       if(!node) return NULL;
+       if(xmlIsBlankNode(node)) return NULL;
+       if(obj == NULL) obj = jsonNewObject(NULL);
+
+       if(node->type == XML_TEXT_NODE) {
+               jsonObjectSetString(obj, (char*) node->content);        
+
+       } else if(node->type == XML_ELEMENT_NODE || node->type == XML_ATTRIBUTE_NODE ) {
+
+               jsonObject* new_obj = jsonNewObject(NULL);
+
+               jsonObject* old;
+
+               /* do the duplicate node / array shuffle */
+               if( (old = jsonObjectGetKey(obj, (char*) node->name)) ) {
+                       if(old->type == JSON_ARRAY ) {
+                               jsonObjectPush(old, new_obj);
+                       } else {
+                               jsonObject* arr = jsonNewObject(NULL);
+                               jsonObjectPush(arr, jsonObjectClone(old));
+                               jsonObjectPush(arr, new_obj);
+                               jsonObjectSetKey(obj, (char*) node->name, arr);
+                       }
+               } else {
+                       jsonObjectSetKey(obj, (char*) node->name, new_obj);
+               }
+
+               xmlNodePtr child = node->children;
+                if (child) { // at least one...
+                       if (child != node->last) { // more than one -- ignore TEXT nodes
+                               while(child) {
+                                       if (child->type != XML_TEXT_NODE) _xmlToJSON(child, new_obj);
+                                       child = child->next;
+                               }
+                       } else {
+                               _xmlToJSON(child, new_obj);
+                       }
+                }
+       }       
+
+       return obj;
+}
+
+
+char* xmlDocToString(xmlDocPtr doc, int full) {
+
+       if(!doc) return NULL;
+
+       char* xml;
+
+       if(full) {
+
+               xmlChar* xmlbuf;
+               int size;
+               xmlDocDumpMemory(doc, &xmlbuf, &size);
+               xml = strdup((char*) (xmlbuf));
+               xmlFree(xmlbuf);
+               return xml;
+
+       } else {
+
+               xmlBufferPtr xmlbuf = xmlBufferCreate();
+               xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
+               xml = strdup((char*) (xmlBufferContent(xmlbuf)));
+               xmlBufferFree(xmlbuf);
+               return xml;
+
+       }
+}
+
+
+
+
+char* xmlSaxAttr( const xmlChar** atts, char* name ) {
+       if( atts && name ) {
+               int i;
+               for(i = 0; (atts[i] != NULL); i++) {
+                       if(!strcmp(atts[i], name)) {
+                               if(atts[++i]) return (char*) atts[i];
+                       }
+               }
+       }
+       return NULL;
+}
+
+
+int xmlAddAttrs( xmlNodePtr node, const xmlChar** atts ) {
+       if( node && atts ) {
+               int i;
+               for(i = 0; (atts[i] != NULL); i++) {
+                       if(atts[i+1]) {
+                               xmlSetProp(node, atts[i], atts[i+1]);
+                               i++;
+                       }
+               }
+       }
+       return 0;
+}
+
diff --git a/src/libstack/Makefile b/src/libstack/Makefile
deleted file mode 100644 (file)
index 82fae9a..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-# OSRF_LOG_PARAMS log all incoming method params at OSRF_INFO log level. 
-# OSRF_STRICT_PARAMS instructs the app handler to return an error if the number of method arguments
-#      provided to any method is not at least as large as the 'argc' setting for the method
-
-CFLAGS +=  -DASSUME_STATELESS  -DOSRF_LOG_PARAMS -DOSRF_STRICT_PARAMS -rdynamic -fno-strict-aliasing
-LDLIBS += -lxml2 -lobjson -ldl -lmemcache 
-
-TARGETS = osrf_message.o \
-                        osrf_app_session.o \
-                        osrf_stack.o \
-                        osrf_system.o \
-                        osrf_settings.o \
-                        osrf_prefork.o \
-                        osrfConfig.o \
-                        osrf_application.o \
-                        osrf_cache.o \
-                        osrf_transgroup.o \
-                        osrf_list.o \
-                        osrf_hash.o \
-                        xml_utils.o 
-
-HEADERS = osrf_message.h \
-                        osrf_app_session.h \
-                        osrf_stack.h \
-                        osrf_system.h \
-                        osrf_settings.h \
-                        osrf_prefork.h \
-                        osrfConfig.h \
-                        osrf_application.h \
-                        osrf_cache.h \
-                        osrf_transgroup.h \
-                        osrf_list.h \
-                        osrf_hash.h \
-                        xml_utils.h
-
-all: xml_utils.o $(TARGETS) copy 
-
-xml_utils.o:
-       cp ../utils/xml_utils.h .
-       cp ../utils/xml_utils.c .
-       $(CC) -c $(CFLAGS) xml_utils.c -o $@ 
-
-copy:
-       cp $(HEADERS) $(TMPDIR)/
-
-osrf_message.o:        osrf_message.c osrf_message.h
-osrf_app_session.o:    osrf_app_session.c osrf_app_session.h
-osrf_stack.o:  osrf_stack.c osrf_stack.h
-osrf_system.o: osrf_system.c osrf_system.h
-osrf_settings.o:       osrf_settings.c osrf_settings.h
-osrf_prefork.o:        osrf_prefork.c osrf_prefork.h
-osrfConfig.o:  osrfConfig.c osrfConfig.h xml_utils.o
-osrf_application.o: osrf_application.c osrf_application.h
-osrf_cache.o:  osrf_cache.c osrf_cache.h
-osrf_list.o:   osrf_list.c osrf_list.h
-#osrf_big_list.o:      osrf_big_list.c osrf_big_list.h
-osrf_hash.o:   osrf_hash.c osrf_hash.h
-#osrf_big_hash.o:      osrf_big_hash.c osrf_big_hash.h
-
-
-clean:
-       /bin/rm -f *.o libopensrf_stack.so xml_utils.h xml_utils.c opensrf
-
diff --git a/src/libstack/opensrf.c b/src/libstack/opensrf.c
deleted file mode 100644 (file)
index 9291930..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "osrf_system.h"
-#include "osrf_hash.h"
-#include "osrf_list.h"
-
-int main( int argc, char* argv[] ) {
-
-       if( argc < 4 ) {
-               fprintf(stderr, "Usage: %s <host> <bootstrap_config> <config_context>\n", argv[0]);
-               return 1;
-       }
-
-       fprintf(stderr, "Loading OpenSRF host %s with bootstrap config %s "
-                       "and config context %s\n", argv[1], argv[2], argv[3] );
-
-       /* these must be strdup'ed because init_proc_title / set_proc_title 
-               are evil and overwrite the argv memory */
-       char* host              = strdup( argv[1] );
-       char* config    = strdup( argv[2] );
-       char* context   = strdup( argv[3] );
-
-       init_proc_title( argc, argv );
-       set_proc_title( "OpenSRF System-C" );
-
-       int ret = osrfSystemBootstrap( host, config, context );
-
-       if (ret != 0) {
-               osrfLogError(
-                       OSRF_LOG_MARK,
-                       "Server Loop returned an error condition, exiting with %d",
-                       ret
-               );
-       }
-
-
-       free(host);
-       free(config);
-       free(context);
-
-       return ret;
-}
-
-
diff --git a/src/libstack/osrfConfig.c b/src/libstack/osrfConfig.c
deleted file mode 100644 (file)
index b02b6fd..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* defines the currently used bootstrap config file */
-#include "osrfConfig.h"
-
-static osrfConfig* osrfConfigDefault = NULL;
-
-
-void osrfConfigSetDefaultConfig(osrfConfig* cfg) {
-       if(cfg) {
-               if( osrfConfigDefault )
-                       osrfConfigFree( osrfConfigDefault );
-               osrfConfigDefault = cfg;
-       }
-}
-
-void osrfConfigFree(osrfConfig* cfg) {
-       if(cfg) {
-               jsonObjectFree(cfg->config);
-               free(cfg->configContext);
-               free(cfg);
-       }       
-}
-
-
-int osrfConfigHasDefaultConfig() {
-       return ( osrfConfigDefault != NULL );
-}
-
-
-void osrfConfigCleanup() { 
-       osrfConfigFree(osrfConfigDefault);
-       osrfConfigDefault = NULL;
-}
-
-
-void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj) {
-       if(!cfg || !obj) return;
-       jsonObjectFree(cfg->config);
-       cfg->config = jsonObjectClone(obj);     
-}
-
-osrfConfig* osrfConfigInit(char* configFile, char* configContext) {
-       if(!configFile) return NULL;
-
-       // Load XML from the configuration file
-       
-       xmlDocPtr doc = xmlParseFile(configFile);
-       if(!doc) {
-               fprintf( stderr, "osrfConfigInit: Unable to parse XML config file %s\n", configFile);
-               osrfLogWarning( OSRF_LOG_MARK, "Unable to parse XML config file %s", configFile);
-               return NULL;
-       }
-
-       // Translate it into a jsonObject
-       
-       jsonObject* json_config = xmlDocToJSON(doc);
-       xmlFreeDoc(doc);
-
-       if(!json_config ) {
-               fprintf( stderr, "osrfConfigInit: xmlDocToJSON failed for config %s\n", configFile);
-               osrfLogWarning( OSRF_LOG_MARK, "xmlDocToJSON failed for config %s", configFile);
-               return NULL;
-       }       
-
-       // Build an osrfConfig and return it by pointer
-       
-       osrfConfig* cfg = safe_malloc(sizeof(osrfConfig));
-
-       if(configContext) cfg->configContext = strdup(configContext);
-       else cfg->configContext = NULL;
-
-       cfg->config = json_config;
-       
-       return cfg;
-}
-
-char* osrfConfigGetValue(osrfConfig* cfg, char* path, ...) {
-
-       if(!path) return NULL;
-       if(!cfg) cfg = osrfConfigDefault;
-       if(!cfg) { osrfLogWarning( OSRF_LOG_MARK, "No Config object in osrfConfigGetValue()"); return NULL; }
-
-       VA_LIST_TO_STRING(path);
-
-       jsonObject* obj;
-       char* val = NULL;
-
-       if(cfg->configContext) {
-               obj = jsonObjectFindPath( cfg->config, "//%s%s", cfg->configContext, VA_BUF);
-               if(obj) val = jsonObjectToSimpleString(jsonObjectGetIndex(obj, 0));
-
-       } else {
-               obj = jsonObjectFindPath( cfg->config, VA_BUF);
-               if(obj) val = jsonObjectToSimpleString(obj);
-       }
-
-       jsonObjectFree(obj);
-       return val;
-}
-
-
-int osrfConfigGetValueList(osrfConfig* cfg, osrfStringArray* arr, char* path, ...) {
-
-       if(!arr || !path) return 0;
-       if(!cfg) cfg = osrfConfigDefault;
-       if(!cfg) { osrfLogWarning( OSRF_LOG_MARK, "No Config object!"); return -1;}
-
-       VA_LIST_TO_STRING(path);
-
-       jsonObject* obj;
-       if(cfg->configContext) {
-               obj = jsonObjectFindPath( cfg->config, "//%s%s", cfg->configContext, VA_BUF);
-       } else {
-               obj = jsonObjectFindPath( cfg->config, VA_BUF);
-       }
-
-       int count = 0;
-
-       if(obj && obj->type == JSON_ARRAY ) {
-
-               int i;
-               for( i = 0; i < obj->size; i++ ) {
-
-                       char* val = jsonObjectToSimpleString(jsonObjectGetIndex(obj, i));
-                       if(val) {
-                               count++;
-                               osrfStringArrayAdd(arr, val);
-                               free(val);
-                       }
-               }
-       }
-
-       jsonObjectFree(obj);
-       return count;
-}
-
diff --git a/src/libstack/osrfConfig.h b/src/libstack/osrfConfig.h
deleted file mode 100644 (file)
index c0a6459..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-Copyright (C) 2005  Georgia Public Library Service 
-Bill Erickson <highfalutin@gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-*/
-
-#ifndef _OSRF_CONFIG_H
-#define _OSRF_CONFIG_H
-
-#include "xml_utils.h"
-#include "opensrf/utils.h"
-#include "opensrf/string_array.h"
-#include "objson/object.h"
-
-typedef struct {
-       jsonObject* config;
-       char* configContext;
-} osrfConfig;
-
-
-/**
-       Parses a new config file.  Caller is responsible for freeing the returned
-               config object when finished.  
-       @param configFile The XML config file to parse.
-       @param configContext Optional root of the subtree in the config file where 
-       we will look for values. If it's not provided,  searches will be 
-       performed from the root of the config file
-       @return The config object if the file parses successfully.  Otherwise
-               it returns NULL;
-*/
-osrfConfig* osrfConfigInit(char* configFile, char* configContext);
-
-/**
-       @return True if we have a default config defined
-*/
-int osrfConfigHasDefaultConfig();
-
-/**
-       Replaces the config object's objson object.  This is useful
-       if you have an ojbson object already and not an XML config
-       file to parse.
-       @param cfg The config object to alter
-       @param obj The objson objet to use when searching values
-*/
-void osrfConfigReplaceConfig(osrfConfig* cfg, const jsonObject* obj);
-
-/** Deallocates a config object 
-       @param cfg The config object to free
-*/
-void osrfConfigFree(osrfConfig* cfg);
-
-
-/* Assigns the default config file.  This file will be used whenever
-       NULL is passed to config retrieval functions 
-       @param cfg The config object to use as the default config
-*/
-void osrfConfigSetDefaultConfig(osrfConfig* cfg);
-
-/* frees the default config if one exists */
-void osrfConfigCleanup();
-
-
-/** 
-       Returns the value in the config found at 'path'.
-       If the value found at 'path' is a long or a double,
-       the value is stringified and then returned.
-       The caller must free the returned char* 
-
-       if there is a configContext, then it will be appended to 
-       the front of the path like so: //<configContext>/<path>
-       if no configContext was provided to osfConfigSetFile, then 
-       the path is interpreted literally.
-       @param cfg The config file to search or NULL if the default
-               config should be used
-       @param path The search path
-*/
-char* osrfConfigGetValue(osrfConfig* cfg, char* path, ...);
-
-/** 
-       Puts the list of values found at 'path' into the pre-allocated 
-       string array.  
-       Note that the config node found at 'path' must be an array.
-       @param cfg The config file to search or NULL if the default
-               config should be used
-       @param arr An allocated string_array where the values will
-               be stored
-       @param path The search path
-       @return the number of values added to the string array;
-*/
-
-int osrfConfigGetValueList(osrfConfig* cfg, osrfStringArray* arr, char* path, ...);
-
-
-#endif
diff --git a/src/libstack/osrf_app_session.c b/src/libstack/osrf_app_session.c
deleted file mode 100644 (file)
index 095e50e..0000000
+++ /dev/null
@@ -1,660 +0,0 @@
-#include "osrf_app_session.h"
-#include <time.h>
-
-/* the global app_session cache */
-osrfHash* osrfAppSessionCache = NULL;
-
-
-// --------------------------------------------------------------------------
-// --------------------------------------------------------------------------
-// Request API
-// --------------------------------------------------------------------------
-
-/** Allocation and initializes a new app_request object */
-osrf_app_request* _osrf_app_request_init( 
-               osrf_app_session* session, osrf_message* msg ) {
-
-       osrf_app_request* req = 
-               (osrf_app_request*) safe_malloc(sizeof(osrf_app_request));
-
-       req->session            = session;
-       req->request_id = msg->thread_trace;
-       req->complete           = 0;
-       req->payload            = msg;
-       req->result                     = NULL;
-
-       return req;
-
-}
-
-
-void osrfAppSessionCleanup() {
-       osrfHashFree(osrfAppSessionCache);      
-}
-
-
-
-/** Frees memory used by an app_request object */
-void _osrf_app_request_free( void * req ){
-       if( req == NULL ) return;
-       osrfAppRequest* r = (osrfAppRequest*) req;
-       if( r->payload ) osrf_message_free( r->payload );
-       free( r );
-}
-
-/** Pushes the given message onto the list of 'responses' to this request */
-void _osrf_app_request_push_queue( osrf_app_request* req, osrf_message* result ){
-       if(req == NULL || result == NULL) return;
-       osrfLogDebug( OSRF_LOG_MARK,  "App Session pushing request [%d] onto request queue", result->thread_trace );
-       if(req->result == NULL) {
-               req->result = result;
-
-       } else {
-               
-               osrf_message* ptr = req->result;
-               osrf_message* ptr2 = req->result->next;
-               while( ptr2 ) {
-                       ptr = ptr2;
-                       ptr2 = ptr2->next;
-               }
-               ptr->next = result;
-       }
-}
-
-/** Removes this app_request from our session request set */
-void osrf_app_session_request_finish( 
-               osrf_app_session* session, int req_id ){
-
-       if(session == NULL) return;
-       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
-       if(req == NULL) return;
-       osrfListRemove( req->session->request_queue, req->request_id );
-}
-
-
-void osrf_app_session_request_reset_timeout( osrf_app_session* session, int req_id ) {
-       if(session == NULL) return;
-       osrfLogDebug( OSRF_LOG_MARK, "Resetting request timeout %d", req_id );
-       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
-       if(req == NULL) return;
-       req->reset_timeout = 1;
-}
-
-/** Checks the receive queue for messages.  If any are found, the first
-  * is popped off and returned.  Otherwise, this method will wait at most timeout 
-  * seconds for a message to appear in the receive queue.  Once it arrives it is returned.
-  * If no messages arrive in the timeout provided, null is returned.
-  */
-osrf_message* _osrf_app_request_recv( osrf_app_request* req, int timeout ) {
-
-       if(req == NULL) return NULL;
-
-       if( req->result != NULL ) {
-               /* pop off the first message in the list */
-               osrf_message* tmp_msg = req->result;
-               req->result = req->result->next;
-               return tmp_msg;
-       }
-
-       time_t start = time(NULL);      
-       time_t remaining = (time_t) timeout;
-
-       while( remaining >= 0 ) {
-               /* tell the session to wait for stuff */
-               osrfLogDebug( OSRF_LOG_MARK,  "In app_request receive with remaining time [%d]", (int) remaining );
-
-               osrf_app_session_queue_wait( req->session, 0, NULL );
-
-               if( req->result != NULL ) { /* if we received anything */
-                       /* pop off the first message in the list */
-                       osrfLogDebug( OSRF_LOG_MARK,  "app_request_recv received a message, returning it");
-                       osrf_message* ret_msg = req->result;
-                       osrf_message* tmp_msg = ret_msg->next;
-                       req->result = tmp_msg;
-                       return ret_msg;
-               }
-
-               if( req->complete )
-                       return NULL;
-
-               osrf_app_session_queue_wait( req->session, (int) remaining, NULL );
-
-               if( req->result != NULL ) { /* if we received anything */
-                       /* pop off the first message in the list */
-                       osrfLogDebug( OSRF_LOG_MARK,  "app_request_recv received a message, returning it");
-                       osrf_message* ret_msg = req->result;
-                       osrf_message* tmp_msg = ret_msg->next;
-                       req->result = tmp_msg;
-                       return ret_msg;
-               }
-               if( req->complete )
-                       return NULL;
-
-               if(req->reset_timeout) {
-                       remaining = (time_t) timeout;
-                       req->reset_timeout = 0;
-                       osrfLogDebug( OSRF_LOG_MARK, "Recevied a timeout reset");
-               } else {
-                       remaining -= (int) (time(NULL) - start);
-               }
-       }
-
-       osrfLogInfo( OSRF_LOG_MARK, "Returning NULL from app_request_recv after timeout");
-       return NULL;
-}
-
-/** Resend this requests original request message */
-int _osrf_app_request_resend( osrf_app_request* req ) {
-       if(req == NULL) return 0;
-       if(!req->complete) {
-               osrfLogDebug( OSRF_LOG_MARK,  "Resending request [%d]", req->request_id );
-               return _osrf_app_session_send( req->session, req->payload );
-       }
-       return 1;
-}
-
-
-
-// --------------------------------------------------------------------------
-// --------------------------------------------------------------------------
-// Session API
-// --------------------------------------------------------------------------
-
-/** returns a session from the global session hash */
-osrf_app_session* osrf_app_session_find_session( char* session_id ) {
-       if(session_id) return osrfHashGet(osrfAppSessionCache, session_id);
-       return NULL;
-}
-
-
-/** adds a session to the global session cache */
-void _osrf_app_session_push_session( osrf_app_session* session ) {
-       if(!session) return;
-       if( osrfAppSessionCache == NULL ) osrfAppSessionCache = osrfNewHash();
-       if( osrfHashGet( osrfAppSessionCache, session->session_id ) ) return;
-       osrfHashSet( osrfAppSessionCache, session, session->session_id );
-}
-
-/** Allocates a initializes a new app_session */
-
-osrf_app_session* osrfAppSessionClientInit( char* remote_service ) {
-       return osrf_app_client_session_init( remote_service );
-}
-
-osrf_app_session* osrf_app_client_session_init( char* remote_service ) {
-
-       osrf_app_session* session = safe_malloc(sizeof(osrf_app_session));      
-
-       session->transport_handle = osrf_system_get_transport_client();
-       if( session->transport_handle == NULL ) {
-               osrfLogWarning( OSRF_LOG_MARK, "No transport client for service 'client'");
-               free( session );
-               return NULL;
-       }
-
-       char target_buf[512];
-       target_buf[ 0 ] = '\0';
-
-       osrfStringArray* arr = osrfNewStringArray(8);
-       osrfConfigGetValueList(NULL, arr, "/domains/domain");
-       char* domain = osrfStringArrayGetString(arr, 0);
-       char* router_name = osrfConfigGetValue(NULL, "/router_name");
-       
-       int len = snprintf( target_buf, 512, "%s@%s/%s",  router_name, domain, remote_service );
-       osrfStringArrayFree(arr);
-       //free(domain);
-       free(router_name);
-
-       if( len >= sizeof( target_buf ) ) {
-               osrfLogWarning( OSRF_LOG_MARK, "Buffer overflow for remote_id");
-               free( session );
-               return NULL;
-       }
-
-       session->request_queue = osrfNewList();
-       session->request_queue->freeItem = &_osrf_app_request_free;
-       session->remote_id = strdup(target_buf);
-       session->orig_remote_id = strdup(session->remote_id);
-       session->remote_service = strdup(remote_service);
-
-       #ifdef ASSUME_STATELESS
-       session->stateless = 1;
-       osrfLogDebug( OSRF_LOG_MARK, "%s session is stateless", remote_service );
-       #else
-       session->stateless = 0;
-       osrfLogDebug( OSRF_LOG_MARK, "%s session is NOT stateless", remote_service );
-       #endif
-
-       /* build a chunky, random session id */
-       char id[256];
-       memset(id,0,256);
-
-       sprintf(id, "%f.%d%ld", get_timestamp_millis(), (int)time(NULL), (long) getpid());
-       session->session_id = strdup(id);
-       osrfLogDebug( OSRF_LOG_MARK,  "Building a new client session with id [%s] [%s]", 
-                       session->remote_service, session->session_id );
-
-       session->thread_trace = 0;
-       session->state = OSRF_SESSION_DISCONNECTED;
-       session->type = OSRF_SESSION_CLIENT;
-       //session->next = NULL;
-       _osrf_app_session_push_session( session );
-       return session;
-}
-
-osrf_app_session* osrf_app_server_session_init( 
-               char* session_id, char* our_app, char* remote_id ) {
-
-       osrfLogDebug( OSRF_LOG_MARK, "Initing server session with session id %s, service %s,"
-                       " and remote_id %s", session_id, our_app, remote_id );
-
-       osrf_app_session* session = osrf_app_session_find_session( session_id );
-       if(session) return session;
-
-       session = safe_malloc(sizeof(osrf_app_session));        
-
-       session->transport_handle = osrf_system_get_transport_client();
-       if( session->transport_handle == NULL ) {
-               osrfLogWarning( OSRF_LOG_MARK, "No transport client for service '%s'", our_app );
-               return NULL;
-       }
-
-       int stateless = 0;
-       char* statel = osrf_settings_host_value("/apps/%s/stateless", our_app );
-       if(statel) stateless = atoi(statel);
-       free(statel);
-
-
-       session->request_queue = osrfNewList();
-       session->request_queue->freeItem = &_osrf_app_request_free;
-       session->remote_id = strdup(remote_id);
-       session->orig_remote_id = strdup(remote_id);
-       session->session_id = strdup(session_id);
-       session->remote_service = strdup(our_app);
-       session->stateless = stateless;
-
-       #ifdef ASSUME_STATELESS
-       session->stateless = 1;
-       #endif
-
-       session->thread_trace = 0;
-       session->state = OSRF_SESSION_DISCONNECTED;
-       session->type = OSRF_SESSION_SERVER;
-
-       _osrf_app_session_push_session( session );
-       return session;
-
-}
-
-
-
-/** frees memory held by a session */
-void _osrf_app_session_free( osrf_app_session* session ){
-       if(session==NULL)
-               return;
-
-       if( session->userDataFree && session->userData ) 
-               session->userDataFree(session->userData);
-       
-       free(session->remote_id);
-       free(session->orig_remote_id);
-       free(session->session_id);
-       free(session->remote_service);
-       osrfListFree(session->request_queue);
-       free(session);
-}
-
-int osrfAppSessionMakeRequest(
-               osrf_app_session* session, jsonObject* params, 
-               char* method_name, int protocol, string_array* param_strings ) {
-
-       return osrf_app_session_make_req( session, params, 
-                       method_name, protocol, param_strings );
-}
-
-int osrf_app_session_make_req( 
-               osrf_app_session* session, jsonObject* params, 
-               char* method_name, int protocol, string_array* param_strings ) {
-       if(session == NULL) return -1;
-
-   osrfLogMkXid();
-
-       osrf_message* req_msg = osrf_message_init( REQUEST, ++(session->thread_trace), protocol );
-       osrf_message_set_method(req_msg, method_name);
-       if(params) {
-               osrf_message_set_params(req_msg, params);
-
-       } else {
-
-               if(param_strings) {
-                       int i;
-                       for(i = 0; i!= param_strings->size ; i++ ) {
-                               osrf_message_add_param(req_msg,
-                                       string_array_get_string(param_strings,i));
-                       }
-               }
-       }
-
-       osrf_app_request* req = _osrf_app_request_init( session, req_msg );
-       if(_osrf_app_session_send( session, req_msg ) ) {
-               osrfLogWarning( OSRF_LOG_MARK,  "Error sending request message [%d]", session->thread_trace );
-               return -1;
-       }
-
-       osrfLogDebug( OSRF_LOG_MARK,  "Pushing [%d] onto requeust queue for session [%s] [%s]",
-                       req->request_id, session->remote_service, session->session_id );
-       osrfListSet( session->request_queue, req, req->request_id ); 
-       return req->request_id;
-}
-
-void osrf_app_session_set_complete( osrf_app_session* session, int request_id ) {
-       if(session == NULL)
-               return;
-
-       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, request_id );
-       if(req) req->complete = 1;
-}
-
-int osrf_app_session_request_complete( osrf_app_session* session, int request_id ) {
-       if(session == NULL)
-               return 0;
-       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, request_id );
-       if(req)
-               return req->complete;
-       return 0;
-}
-
-
-/** Resets the remote connection id to that of the original*/
-void osrf_app_session_reset_remote( osrf_app_session* session ){
-       if( session==NULL )
-               return;
-
-       free(session->remote_id);
-       osrfLogDebug( OSRF_LOG_MARK,  "App Session [%s] [%s] resetting remote id to %s",
-                       session->remote_service, session->session_id, session->orig_remote_id );
-
-       session->remote_id = strdup(session->orig_remote_id);
-}
-
-void osrf_app_session_set_remote( osrf_app_session* session, char* remote_id ) {
-       if(session == NULL)
-               return;
-       if( session->remote_id )
-               free(session->remote_id );
-       session->remote_id = strdup( remote_id );
-}
-
-/** pushes the given message into the result list of the app_request
-  with the given request_id */
-int osrf_app_session_push_queue( 
-               osrf_app_session* session, osrf_message* msg ){
-       if(session == NULL || msg == NULL) return 0;
-
-       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, msg->thread_trace );
-       if(req == NULL) return 0;
-       _osrf_app_request_push_queue( req, msg );
-
-       return 0;
-}
-
-int osrfAppSessionConnect( osrf_app_session* session ) { 
-       return osrf_app_session_connect(session);
-}
-
-
-/** Attempts to connect to the remote service */
-int osrf_app_session_connect(osrf_app_session* session){
-       
-       if(session == NULL)
-               return 0;
-
-       if(session->state == OSRF_SESSION_CONNECTED) {
-               return 1;
-       }
-
-       int timeout = 5; /* XXX CONFIG VALUE */
-
-       osrfLogDebug( OSRF_LOG_MARK,  "AppSession connecting to %s", session->remote_id );
-
-       /* defaulting to protocol 1 for now */
-       osrf_message* con_msg = osrf_message_init( CONNECT, session->thread_trace, 1 );
-       osrf_app_session_reset_remote( session );
-       session->state = OSRF_SESSION_CONNECTING;
-       int ret = _osrf_app_session_send( session, con_msg );
-       osrf_message_free(con_msg);
-       if(ret) return 0;
-
-       time_t start = time(NULL);      
-       time_t remaining = (time_t) timeout;
-
-       while( session->state != OSRF_SESSION_CONNECTED && remaining >= 0 ) {
-               osrf_app_session_queue_wait( session, remaining, NULL );
-               remaining -= (int) (time(NULL) - start);
-       }
-
-       if(session->state == OSRF_SESSION_CONNECTED)
-               osrfLogDebug( OSRF_LOG_MARK, " * Connected Successfully to %s", session->remote_service );
-
-       if(session->state != OSRF_SESSION_CONNECTED)
-               return 0;
-
-       return 1;
-}
-
-
-
-/** Disconnects from the remote service */
-int osrf_app_session_disconnect( osrf_app_session* session){
-       if(session == NULL)
-               return 1;
-
-       if(session->state == OSRF_SESSION_DISCONNECTED)
-               return 1;
-
-       if(session->stateless && session->state != OSRF_SESSION_CONNECTED) {
-               osrfLogDebug( OSRF_LOG_MARK,  
-                               "Exiting disconnect on stateless session %s", 
-                               session->session_id);
-               return 1;
-       }
-
-       osrfLogDebug(OSRF_LOG_MARK,  "AppSession disconnecting from %s", session->remote_id );
-
-       osrf_message* dis_msg = osrf_message_init( DISCONNECT, session->thread_trace, 1 );
-       _osrf_app_session_send( session, dis_msg );
-       session->state = OSRF_SESSION_DISCONNECTED;
-
-       osrf_message_free( dis_msg );
-       osrf_app_session_reset_remote( session );
-       return 1;
-}
-
-int osrf_app_session_request_resend( osrf_app_session* session, int req_id ) {
-       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
-       return _osrf_app_request_resend( req );
-}
-
-
-int osrfAppSessionSendBatch( osrfAppSession* session, osrf_message* msgs[], int size ) {
-
-       if( !(session && msgs && size > 0) ) return 0;
-       int retval = 0;
-
-       osrfMessage* msg = msgs[0];
-
-       if(msg) {
-
-               osrf_app_session_queue_wait( session, 0, NULL );
-
-               if(session->state != OSRF_SESSION_CONNECTED)  {
-
-                       if(session->stateless) { /* stateless session always send to the root listener */
-                               osrf_app_session_reset_remote(session);
-
-                       } else { 
-
-                               /* do an auto-connect if necessary */
-                               if( ! session->stateless &&
-                                       (msg->m_type != CONNECT) && 
-                                       (msg->m_type != DISCONNECT) &&
-                                       (session->state != OSRF_SESSION_CONNECTED) ) {
-
-                                       if(!osrf_app_session_connect( session )) 
-                                               return 0;
-                               }
-                       }
-               }
-       }
-
-       char* string = osrfMessageSerializeBatch(msgs, size);
-
-       if( string ) {
-
-               transport_message* t_msg = message_init( 
-                               string, "", session->session_id, session->remote_id, NULL );
-      message_set_osrf_xid( t_msg, osrfLogGetXid() );
-
-               retval = client_send_message( session->transport_handle, t_msg );
-
-               if( retval ) osrfLogError(OSRF_LOG_MARK, "client_send_message failed");
-
-               osrfLogInfo(OSRF_LOG_MARK, "[%s] sent %d bytes of data to %s",
-                       session->remote_service, strlen(string), t_msg->recipient );
-
-               osrfLogDebug(OSRF_LOG_MARK, "Sent: %s", string );
-
-               free(string);
-               message_free( t_msg );
-       }
-
-       return retval; 
-}
-
-
-
-int _osrf_app_session_send( osrf_app_session* session, osrf_message* msg ){
-       if( !(session && msg) ) return 0;
-       osrfMessage* a[1];
-       a[0] = msg;
-       return osrfAppSessionSendBatch( session, a, 1 );
-}
-
-
-
-
-/**  Waits up to 'timeout' seconds for some data to arrive.
-  * Any data that arrives will be processed according to its
-  * payload and message type.  This method will return after
-  * any data has arrived.
-  */
-int osrf_app_session_queue_wait( osrf_app_session* session, int timeout, int* recvd ){
-       if(session == NULL) return 0;
-       int ret_val = 0;
-       osrfLogDebug(OSRF_LOG_MARK,  "AppSession in queue_wait with timeout %d", timeout );
-       ret_val = osrf_stack_entry_point(session->transport_handle, timeout, recvd);
-       return ret_val;
-}
-
-/** Disconnects (if client) and removes the given session from the global session cache 
-  * ! This free's all attached app_requests ! 
-  */
-void osrfAppSessionFree( osrfAppSession* ses ) {
-       osrf_app_session_destroy( ses );
-}
-
-
-void osrf_app_session_destroy( osrf_app_session* session ){
-       if(session == NULL) return;
-
-       osrfLogDebug(OSRF_LOG_MARK,  "AppSession [%s] [%s] destroying self and deleting requests", 
-                       session->remote_service, session->session_id );
-       if(session->type == OSRF_SESSION_CLIENT 
-                       && session->state != OSRF_SESSION_DISCONNECTED ) { /* disconnect if we're a client */
-               osrf_message* dis_msg = osrf_message_init( DISCONNECT, session->thread_trace, 1 );
-               _osrf_app_session_send( session, dis_msg ); 
-               osrf_message_free(dis_msg);
-       }
-
-       osrfHashRemove( osrfAppSessionCache, session->session_id );
-       _osrf_app_session_free( session );
-}
-
-osrf_message* osrfAppSessionRequestRecv(
-               osrf_app_session* session, int req_id, int timeout ) {
-       return osrf_app_session_request_recv( session, req_id, timeout );
-}
-osrf_message* osrf_app_session_request_recv( 
-               osrf_app_session* session, int req_id, int timeout ) {
-       if(req_id < 0 || session == NULL)
-               return NULL;
-       osrf_app_request* req = OSRF_LIST_GET_INDEX( session->request_queue, req_id );
-       return _osrf_app_request_recv( req, timeout );
-}
-
-
-
-int osrfAppRequestRespond( osrfAppSession* ses, int requestId, jsonObject* data ) {
-       if(!ses || ! data ) return -1;
-
-       osrf_message* msg = osrf_message_init( RESULT, requestId, 1 );
-       osrf_message_set_status_info( msg, NULL, "OK", OSRF_STATUS_OK );
-       char* json = jsonObjectToJSON( data );
-
-       osrf_message_set_result_content( msg, json );
-       _osrf_app_session_send( ses, msg ); 
-
-       free(json);
-       osrf_message_free( msg );
-
-       return 0;
-}
-
-
-int osrfAppRequestRespondComplete( 
-               osrfAppSession* ses, int requestId, jsonObject* data ) {
-
-       osrf_message* payload = osrf_message_init( RESULT, requestId, 1 );
-       osrf_message_set_status_info( payload, NULL, "OK", OSRF_STATUS_OK );
-
-       osrf_message* status = osrf_message_init( STATUS, requestId, 1);
-       osrf_message_set_status_info( status, "osrfConnectStatus", "Request Complete", OSRF_STATUS_COMPLETE );
-       
-       if (data) {
-               char* json = jsonObjectToJSON( data );
-               osrf_message_set_result_content( payload, json );
-               free(json);
-
-               osrfMessage* ms[2];
-               ms[0] = payload;
-               ms[1] = status;
-
-               osrfAppSessionSendBatch( ses, ms, 2 );
-
-               osrf_message_free( payload );
-       } else {
-               osrfAppSessionSendBatch( ses, &status, 1 );
-       }
-
-       osrf_message_free( status );
-
-       return 0;
-}
-
-int osrfAppSessionStatus( osrfAppSession* ses, int type, char* name, int reqId, char* message ) {
-
-       if(ses) {
-               osrf_message* msg = osrf_message_init( STATUS, reqId, 1);
-               osrf_message_set_status_info( msg, name, message, type );
-               _osrf_app_session_send( ses, msg ); 
-               osrf_message_free( msg );
-               return 0;
-       }
-       return -1;
-}
-
-
-
-
-
-
diff --git a/src/libstack/osrf_app_session.h b/src/libstack/osrf_app_session.h
deleted file mode 100644 (file)
index af35af5..0000000
+++ /dev/null
@@ -1,235 +0,0 @@
-#ifndef _OSRF_APP_SESSION
-#define _OSRF_APP_SESSION
-
-#include "opensrf/transport_client.h"
-#include "objson/object.h"
-#include "osrf_message.h"
-#include "osrf_system.h"
-#include "opensrf/string_array.h"
-#include "osrfConfig.h"
-#include "osrf_hash.h"
-#include "osrf_list.h"
-
-#include "objson/object.h"
-#include "objson/json_parser.h"
-
-
-
-#define        DEF_RECV_TIMEOUT 6 /* receive timeout */
-#define        DEF_QUEUE_SIZE  
-
-enum OSRF_SESSION_STATE { OSRF_SESSION_CONNECTING, OSRF_SESSION_CONNECTED, OSRF_SESSION_DISCONNECTED };
-enum OSRF_SESSION_TYPE { OSRF_SESSION_SERVER, OSRF_SESSION_CLIENT };
-
-/* entry point for data into the stack.  gets set in osrf_stack.c */
-int (*osrf_stack_entry_point) (transport_client* client, int timeout, int* recvd );
-
-struct osrf_app_request_struct {
-       /** Our controlling session */
-       struct osrf_app_session_struct* session;
-
-       /** our "id" */
-       int request_id;
-       /** True if we have received a 'request complete' message from our request */
-       int complete;
-       /** Our original request payload */
-       osrf_message* payload; 
-       /** List of responses to our request */
-       osrf_message* result;
-
-       /* if set to true, then a call that is waiting on a response, will reset the 
-               timeout and set this variable back to false */
-       int reset_timeout;
-};
-typedef struct osrf_app_request_struct osrf_app_request;
-typedef struct osrf_app_request_struct osrfAppRequest;
-
-struct osrf_app_session_struct {
-
-       /** Our messag passing object */
-       transport_client* transport_handle;
-       /** Cache of active app_request objects */
-
-       //osrf_app_request* request_queue;
-
-       osrfList* request_queue;
-
-       /** The original remote id of the remote service we're talking to */
-       char* orig_remote_id;
-       /** The current remote id of the remote service we're talking to */
-       char* remote_id;
-
-       /** Who we're talking to if we're a client.  
-               what app we're serving if we're a server */
-       char* remote_service;
-
-       /** The current request thread_trace */
-       int thread_trace;
-       /** Our ID */
-       char* session_id;
-
-       /* true if this session does not require connect messages */
-       int stateless;
-
-       /** The connect state */
-       enum OSRF_SESSION_STATE state;
-
-       /** SERVER or CLIENT */
-       enum OSRF_SESSION_TYPE type;
-
-       /* let the user use the session to store their own session data */
-       void* userData;
-
-       void (*userDataFree) (void*);
-};
-typedef struct osrf_app_session_struct osrf_app_session;
-typedef struct osrf_app_session_struct osrfAppSession;
-
-
-
-// -------------------------------------------------------------------------- 
-// PUBLIC API ***
-// -------------------------------------------------------------------------- 
-
-/** Allocates a initializes a new app_session */
-osrf_app_session* osrfAppSessionClientInit( char* remote_service );
-osrf_app_session* osrf_app_client_session_init( char* remote_service );
-
-/** Allocates and initializes a new server session.  The global session cache
-  * is checked to see if this session already exists, if so, it's returned 
-  */
-osrf_app_session* osrf_app_server_session_init( 
-               char* session_id, char* our_app, char* remote_id );
-
-/** returns a session from the global session hash */
-osrf_app_session* osrf_app_session_find_session( char* session_id );
-
-/** Builds a new app_request object with the given payload andn returns
-  * the id of the request.  This id is then used to perform work on the
-  * requeset.
-  */
-int osrfAppSessionMakeRequest(
-               osrf_app_session* session, jsonObject* params, 
-               char* method_name, int protocol, string_array* param_strings);
-
-int osrf_app_session_make_req( 
-               osrf_app_session* session, jsonObject* params, 
-               char* method_name, int protocol, string_array* param_strings);
-
-/** Sets the given request to complete state */
-void osrf_app_session_set_complete( osrf_app_session* session, int request_id );
-
-/** Returns true if the given request is complete */
-int osrf_app_session_request_complete( osrf_app_session* session, int request_id );
-
-/** Does a recv call on the given request */
-osrf_message* osrfAppSessionRequestRecv(
-               osrf_app_session* session, int request_id, int timeout );
-osrf_message* osrf_app_session_request_recv( 
-               osrf_app_session* session, int request_id, int timeout );
-
-/** Removes the request from the request set and frees the reqest */
-void osrf_app_session_request_finish( osrf_app_session* session, int request_id );
-
-/** Resends the orginal request with the given request id */
-int osrf_app_session_request_resend( osrf_app_session*, int request_id );
-
-/** Resets the remote connection target to that of the original*/
-void osrf_app_session_reset_remote( osrf_app_session* );
-
-/** Sets the remote target to 'remote_id' */
-void osrf_app_session_set_remote( osrf_app_session* session, char* remote_id );
-
-/** pushes the given message into the result list of the app_request
-  * whose request_id matches the messages thread_trace 
-  */
-int osrf_app_session_push_queue( osrf_app_session*, osrf_message* msg );
-
-/** Attempts to connect to the remote service. Returns 1 on successful 
-  * connection, 0 otherwise.
-  */
-int osrf_app_session_connect( osrf_app_session* );
-int osrfAppSessionConnect( osrf_app_session* );
-
-/** Sends a disconnect message to the remote service.  No response is expected */
-int osrf_app_session_disconnect( osrf_app_session* );
-
-/**  Waits up to 'timeout' seconds for some data to arrive.
-  * Any data that arrives will be processed according to its
-  * payload and message type.  This method will return after
-  * any data has arrived.
-  */
-int osrf_app_session_queue_wait( osrf_app_session*, int timeout, int* recvd );
-
-/** Disconnects (if client), frees any attached app_reuqests, removes the session from the 
-  * global session cache and frees the session.  Needless to say, only call this when the
-  * session is completey done.
-  */
-void osrf_app_session_destroy ( osrf_app_session* );
-void osrfAppSessionFree( osrfAppSession* );
-
-
-
-// --------------------------------------------------------------------------
-// --------------------------------------------------------------------------
-// Request functions
-// --------------------------------------------------------------------------
-
-/** Allocations and initializes a new app_request object */
-osrf_app_request* _osrf_app_request_init( osrf_app_session* session, osrf_message* msg );
-
-/** Frees memory used by an app_request object */
-void _osrf_app_request_free( void * req );
-
-/** Pushes the given message onto the list of 'responses' to this request */
-void _osrf_app_request_push_queue( osrf_app_request*, osrf_message* payload );
-
-/** Checks the receive queue for messages.  If any are found, the first
-  * is popped off and returned.  Otherwise, this method will wait at most timeout 
-  * seconds for a message to appear in the receive queue.  Once it arrives it is returned.
-  * If no messages arrive in the timeout provided, null is returned.
-  */
-osrf_message* _osrf_app_request_recv( osrf_app_request* req, int timeout );
-
-/** Resend this requests original request message */
-int _osrf_app_request_resend( osrf_app_request* req );
-
-
-/* tells the request to reset it's wait timeout */
-void osrf_app_session_request_reset_timeout( osrf_app_session* session, int req_id );
-
-// --------------------------------------------------------------------------
-// --------------------------------------------------------------------------
-// Session functions 
-// --------------------------------------------------------------------------
-
-/** Returns the app_request with the given thread_trace (request_id) */
-osrf_app_request* _osrf_app_session_get_request( osrf_app_session*, int thread_trace );
-
-/** frees memory held by a session. Note: We delete all requests in the request list */
-void _osrf_app_session_free( osrf_app_session* );
-
-/** adds a session to the global session cache */
-void _osrf_app_session_push_session( osrf_app_session* );
-
-/** Adds an app_request to the request set */
-void _osrf_app_session_push_request( osrf_app_session*, osrf_app_request* req );
-
-/** Removes an app_request from this session request set, freeing the request object */
-void _osrf_app_session_remove_request( osrf_app_session*, osrf_app_request* req );
-
-/** Send the given message */
-int _osrf_app_session_send( osrf_app_session*, osrf_message* msg );
-
-int osrfAppSessionSendBatch( osrf_app_session*, osrf_message* msgs[], int size );
-
-int osrfAppRequestRespond( osrfAppSession* ses, int requestId, jsonObject* data ); 
-int osrfAppRequestRespondComplete( osrfAppSession* ses, int requestId, jsonObject* data ); 
-
-int osrfAppSessionStatus( osrfAppSession* ses, int type, char* name, int reqId, char* message );
-
-void osrfAppSessionCleanup();
-
-
-
-#endif
diff --git a/src/libstack/osrf_application.c b/src/libstack/osrf_application.c
deleted file mode 100644 (file)
index 1d62642..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-#include "osrf_application.h"
-#include "objson/object.h"
-
-//osrfApplication* __osrfAppList = NULL; 
-
-osrfHash* __osrfAppHash = NULL;
-
-
-int osrfAppRegisterApplication( char* appName, char* soFile ) {
-       if(!appName || ! soFile) return -1;
-       char* error;
-
-       if(!__osrfAppHash) __osrfAppHash = osrfNewHash();
-
-       osrfLogInfo( OSRF_LOG_MARK, "Registering application %s with file %s", appName, soFile );
-
-       osrfApplication* app = safe_malloc(sizeof(osrfApplication));
-       app->handle = dlopen (soFile, RTLD_NOW);
-   app->onExit = NULL;
-
-       if(!app->handle) {
-               osrfLogWarning( OSRF_LOG_MARK, "Failed to dlopen library file %s: %s", soFile, dlerror() );
-               dlerror(); /* clear the error */
-               free(app);
-               return -1;
-       }
-
-       app->methods = osrfNewHash();
-       osrfHashSet( __osrfAppHash, app, appName );
-
-       /* see if we can run the initialize method */
-       int (*init) (void);
-       *(void **) (&init) = dlsym(app->handle, "osrfAppInitialize");
-
-       if( (error = dlerror()) != NULL ) {
-               osrfLogWarning( OSRF_LOG_MARK, 
-                       "! Unable to locate method symbol [osrfAppInitialize] for app %s: %s", appName, error );
-
-       } else {
-
-               /* run the method */
-               int ret;
-               if( (ret = (*init)()) ) {
-                       osrfLogWarning( OSRF_LOG_MARK, "Application %s returned non-zero value from "
-                                       "'osrfAppInitialize', not registering...", appName );
-                       //free(app->name); /* need a method to remove an application from the list */
-                       //free(app);
-                       return ret;
-               }
-       }
-
-       __osrfAppRegisterSysMethods(appName);
-
-       osrfLogInfo( OSRF_LOG_MARK, "Application %s registered successfully", appName );
-
-       osrfLogSetAppname(appName);
-
-   osrfAppSetOnExit(app, appName);
-
-       return 0;
-}
-
-
-void osrfAppSetOnExit(osrfApplication* app, char* appName) {
-   if(!(app && appName)) return;
-
-       /* see if we can run the initialize method */
-   char* error;
-       void (*onExit) (void);
-       *(void **) (&onExit) = dlsym(app->handle, "osrfAppChildExit");
-
-       if( (error = dlerror()) != NULL ) {
-      osrfLogDebug(OSRF_LOG_MARK, "No exit handler defined for %s", appName);
-      return;
-   }
-
-   osrfLogInfo(OSRF_LOG_MARK, "registering exit handler for %s", appName);
-   app->onExit = (*onExit);
-   //if( (ret = (*onExit)()) ) {
-}
-
-
-int osrfAppRunChildInit(char* appname) {
-       osrfApplication* app = _osrfAppFindApplication(appname);
-       if(!app) return -1;
-
-       char* error;
-       int ret;
-       int (*childInit) (void);
-
-       *(void**) (&childInit) = dlsym(app->handle, "osrfAppChildInit");
-
-       if( (error = dlerror()) != NULL ) {
-               osrfLogInfo( OSRF_LOG_MARK, "No child init defined for app %s : %s", appname, error);
-               return 0;
-       }
-
-       if( (ret = (*childInit)()) ) {
-               osrfLogError(OSRF_LOG_MARK, "App %s child init failed", appname);
-               return -1;
-       }
-
-       osrfLogInfo(OSRF_LOG_MARK, "%s child init succeeded", appname);
-       return 0;
-}
-
-
-void osrfAppRunExitCode() { 
-   osrfHashIterator* itr = osrfNewHashIterator(__osrfAppHash);
-   osrfApplication* app;
-   while( (app = osrfHashIteratorNext(itr)) ) {
-      if( app->onExit ) {
-         osrfLogInfo(OSRF_LOG_MARK, "Running onExit handler for app %s", itr->current);
-         app->onExit();
-      }
-   }
-}
-
-
-int osrfAppRegisterMethod( char* appName, char* methodName, 
-               char* symbolName, char* notes, int argc, int options ) {
-
-       return osrfAppRegisterExtendedMethod(
-                       appName,
-                       methodName,
-                       symbolName,
-                       notes,
-                       argc,
-                       options,
-                       NULL
-       );
-
-}
-
-int osrfAppRegisterExtendedMethod( char* appName, char* methodName, 
-               char* symbolName, char* notes, int argc, int options, void * user_data ) {
-
-       if( !appName || ! methodName  ) return -1;
-
-       osrfApplication* app = _osrfAppFindApplication(appName);
-       if(!app) {
-               osrfLogWarning( OSRF_LOG_MARK, "Unable to locate application %s", appName );
-               return -1;
-       }
-
-       osrfLogDebug( OSRF_LOG_MARK, "Registering method %s for app %s", methodName, appName );
-
-       osrfMethod* method = _osrfAppBuildMethod(
-               methodName, symbolName, notes, argc, options, user_data );              
-       method->options = options;
-
-       /* plug the method into the list of methods */
-       osrfHashSet( app->methods, method, method->name );
-
-       if( options & OSRF_METHOD_STREAMING ) { /* build the atomic counterpart */
-               int newops = options | OSRF_METHOD_ATOMIC;
-               osrfMethod* atomicMethod = _osrfAppBuildMethod(
-                       methodName, symbolName, notes, argc, newops, NULL );            
-               osrfHashSet( app->methods, atomicMethod, atomicMethod->name );
-               atomicMethod->userData = method->userData;
-       }
-
-       return 0;
-}
-
-
-
-osrfMethod* _osrfAppBuildMethod( char* methodName, 
-       char* symbolName, char* notes, int argc, int options, void* user_data ) {
-
-       osrfMethod* method                                      = safe_malloc(sizeof(osrfMethod));
-
-       if(methodName) method->name             = strdup(methodName);
-       if(symbolName) method->symbol           = strdup(symbolName);
-       if(notes) method->notes                         = strdup(notes);
-       if(user_data) method->userData  = user_data;
-
-       method->argc                                                    = argc;
-       method->options                                         = options;
-
-       if(options & OSRF_METHOD_ATOMIC) { /* add ".atomic" to the end of the name */
-               char mb[strlen(method->name) + 8];
-               sprintf(mb, "%s.atomic", method->name);
-               free(method->name);
-               method->name = strdup(mb);
-               method->options |= OSRF_METHOD_STREAMING;
-       }
-
-       return method;
-}
-
-
-int __osrfAppRegisterSysMethods( char* app ) {
-
-       osrfAppRegisterMethod( 
-                       app, OSRF_SYSMETHOD_INTROSPECT, NULL, 
-                       "Return a list of methods whose names have the same initial "
-                       "substring as that of the provided method name PARAMS( methodNameSubstring )", 
-                       1, OSRF_METHOD_SYSTEM | OSRF_METHOD_STREAMING );
-
-       osrfAppRegisterMethod( 
-                       app, OSRF_SYSMETHOD_INTROSPECT_ALL, NULL, 
-                       "Returns a complete list of methods. PARAMS()", 0, 
-                       OSRF_METHOD_SYSTEM | OSRF_METHOD_STREAMING );
-
-       osrfAppRegisterMethod( 
-                       app, OSRF_SYSMETHOD_ECHO, NULL, 
-                       "Echos all data sent to the server back to the client. PARAMS([a, b, ...])", 0, 
-                       OSRF_METHOD_SYSTEM | OSRF_METHOD_STREAMING );
-
-       return 0;
-}
-
-osrfApplication* _osrfAppFindApplication( char* name ) {
-       if(!name) return NULL;
-       return (osrfApplication*) osrfHashGet(__osrfAppHash, name);
-}
-
-osrfMethod* __osrfAppFindMethod( osrfApplication* app, char* methodName ) {
-       if(!app || ! methodName) return NULL;
-       return (osrfMethod*) osrfHashGet( app->methods, methodName );
-}
-
-osrfMethod* _osrfAppFindMethod( char* appName, char* methodName ) {
-       if(!appName || ! methodName) return NULL;
-       return __osrfAppFindMethod( _osrfAppFindApplication(appName), methodName );
-}
-
-
-int osrfAppRunMethod( char* appName, char* methodName, 
-               osrfAppSession* ses, int reqId, jsonObject* params ) {
-
-       if( !(appName && methodName && ses) ) return -1;
-
-       char* error;
-       osrfApplication* app;
-       osrfMethod* method;
-       osrfMethodContext context;
-
-       context.session = ses;
-       context.params = params;
-       context.request = reqId;
-       context.responses = NULL;
-
-       /* this is the method we're gonna run */
-       int (*meth) (osrfMethodContext*);       
-
-       if( !(app = _osrfAppFindApplication(appName)) )
-               return osrfAppRequestRespondException( ses, 
-                               reqId, "Application not found: %s", appName );
-       
-       if( !(method = __osrfAppFindMethod( app, methodName )) ) 
-               return osrfAppRequestRespondException( ses, reqId, 
-                               "Method [%s] not found for service %s", methodName, appName );
-
-       context.method = method;
-
-       #ifdef OSRF_STRICT_PARAMS
-       if( method->argc > 0 ) {
-               if(!params || params->type != JSON_ARRAY || params->size < method->argc )
-                       return osrfAppRequestRespondException( ses, reqId, 
-                               "Not enough params for method %s / service %s", methodName, appName );
-       }
-       #endif
-
-       int retcode = 0;
-
-       if( method->options & OSRF_METHOD_SYSTEM ) {
-               retcode = __osrfAppRunSystemMethod(&context);
-
-       } else {
-
-               /* open and now run the method */
-               *(void **) (&meth) = dlsym(app->handle, method->symbol);
-
-               if( (error = dlerror()) != NULL ) {
-                       return osrfAppRequestRespondException( ses, reqId, 
-                               "Unable to execute method [%s]  for service %s", methodName, appName );
-               }
-
-               retcode = (*meth) (&context);
-       }
-
-       if(retcode < 0) 
-               return osrfAppRequestRespondException( 
-                               ses, reqId, "An unknown server error occurred" );
-
-       return __osrfAppPostProcess( &context, retcode );
-
-}
-
-
-int osrfAppRespond( osrfMethodContext* ctx, jsonObject* data ) {
-       return _osrfAppRespond( ctx, data, 0 );
-}
-
-int osrfAppRespondComplete( osrfMethodContext* context, jsonObject* data ) {
-       return _osrfAppRespond( context, data, 1 );
-}
-
-int _osrfAppRespond( osrfMethodContext* ctx, jsonObject* data, int complete ) {
-       if(!(ctx && ctx->method)) return -1;
-
-       if( ctx->method->options & OSRF_METHOD_ATOMIC ) {
-               osrfLogDebug( OSRF_LOG_MARK,   
-                       "Adding responses to stash for atomic method %s", ctx->method->name );
-
-               if( ctx->responses == NULL )                                                                                            
-                       ctx->responses = jsonParseString("[]");                                                 
-
-               if ( data != NULL )
-                       jsonObjectPush( ctx->responses, jsonObjectClone(data) );        
-       }
-
-
-       if(     !(ctx->method->options & OSRF_METHOD_ATOMIC) && 
-                       !(ctx->method->options & OSRF_METHOD_CACHABLE) ) {
-
-               if(complete) 
-                       osrfAppRequestRespondComplete( ctx->session, ctx->request, data );
-               else
-                       osrfAppRequestRespond( ctx->session, ctx->request, data );
-               return 0;
-       }
-
-       return 0;
-}
-
-
-
-
-int __osrfAppPostProcess( osrfMethodContext* ctx, int retcode ) {
-       if(!(ctx && ctx->method)) return -1;
-
-       osrfLogDebug( OSRF_LOG_MARK,  "Postprocessing method %s with retcode %d",
-                       ctx->method->name, retcode );
-
-       if(ctx->responses) { /* we have cached responses to return (no responses have been sent) */
-
-               osrfAppRequestRespondComplete( ctx->session, ctx->request, ctx->responses );
-               jsonObjectFree(ctx->responses);
-               ctx->responses = NULL;
-
-       } else {
-
-               if( retcode > 0 ) 
-                       osrfAppSessionStatus( ctx->session, OSRF_STATUS_COMPLETE,  
-                                       "osrfConnectStatus", ctx->request, "Request Complete" );
-       }
-
-       return 0;
-}
-
-int osrfAppRequestRespondException( osrfAppSession* ses, int request, char* msg, ... ) {
-       if(!ses) return -1;
-       if(!msg) msg = "";
-       VA_LIST_TO_STRING(msg);
-       osrfLogWarning( OSRF_LOG_MARK,  "Returning method exception with message: %s", VA_BUF );
-       osrfAppSessionStatus( ses, OSRF_STATUS_NOTFOUND, "osrfMethodException", request,  VA_BUF );
-       return 0;
-}
-
-
-static void __osrfAppSetIntrospectMethod( osrfMethodContext* ctx, osrfMethod* method, jsonObject* resp ) {
-       if(!(ctx && resp)) return;
-
-       jsonObjectSetKey(resp, "api_name",      jsonNewObject(method->name));
-       jsonObjectSetKey(resp, "method",                jsonNewObject(method->symbol));
-       jsonObjectSetKey(resp, "service",       jsonNewObject(ctx->session->remote_service));
-       jsonObjectSetKey(resp, "notes",         jsonNewObject(method->notes));
-       jsonObjectSetKey(resp, "argc",          jsonNewNumberObject(method->argc));
-
-       jsonObjectSetKey(resp, "sysmethod", 
-                       jsonNewNumberObject( (method->options & OSRF_METHOD_SYSTEM) ? 1 : 0 ));
-       jsonObjectSetKey(resp, "atomic",                
-                       jsonNewNumberObject( (method->options & OSRF_METHOD_ATOMIC) ? 1 : 0 ));
-       jsonObjectSetKey(resp, "cachable",      
-                       jsonNewNumberObject( (method->options & OSRF_METHOD_CACHABLE) ? 1 : 0 ));
-
-       jsonObjectSetClass(resp, "method");
-}
-
-
-
-int __osrfAppRunSystemMethod(osrfMethodContext* ctx) {
-       OSRF_METHOD_VERIFY_CONTEXT(ctx);
-
-       if(     !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ALL ) || 
-                       !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ALL_ATOMIC )) {
-
-               return osrfAppIntrospectAll(ctx);
-       }
-
-
-       if(     !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT ) ||
-                       !strcmp(ctx->method->name, OSRF_SYSMETHOD_INTROSPECT_ATOMIC )) {
-
-               return osrfAppIntrospect(ctx);
-       }
-
-       if(     !strcmp(ctx->method->name, OSRF_SYSMETHOD_ECHO ) ||
-                       !strcmp(ctx->method->name, OSRF_SYSMETHOD_ECHO_ATOMIC )) {
-
-               return osrfAppEcho(ctx);
-       }
-
-
-       osrfAppRequestRespondException( ctx->session, 
-                       ctx->request, "System method implementation not found");
-
-       return 0;
-}
-
-
-int osrfAppIntrospect( osrfMethodContext* ctx ) {
-
-       jsonObject* resp = NULL;
-       char* methodSubstring = jsonObjectGetString( jsonObjectGetIndex(ctx->params, 0) );
-       osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service );
-       int len = 0;
-
-       if(!methodSubstring) return 1; /* respond with no methods */
-
-       if(app) {
-
-               osrfHashIterator* itr = osrfNewHashIterator(app->methods);
-               osrfMethod* method;
-
-               while( (method = osrfHashIteratorNext(itr)) ) {
-                       if( (len = strlen(methodSubstring)) <= strlen(method->name) ) {
-                               if( !strncmp( method->name, methodSubstring, len) ) {
-                                       resp = jsonNewObject(NULL);
-                                       __osrfAppSetIntrospectMethod( ctx, method, resp );
-                                       osrfAppRespond(ctx, resp);
-                                       jsonObjectFree(resp);
-                               }
-                       }
-               }
-               osrfHashIteratorFree(itr);
-               return 1;
-       }
-
-       return -1;
-
-}
-
-
-int osrfAppIntrospectAll( osrfMethodContext* ctx ) {
-       jsonObject* resp = NULL;
-       osrfApplication* app = _osrfAppFindApplication( ctx->session->remote_service );
-
-       if(app) {
-               osrfHashIterator* itr = osrfNewHashIterator(app->methods);
-               osrfMethod* method;
-               while( (method = osrfHashIteratorNext(itr)) ) {
-                       resp = jsonNewObject(NULL);
-                       __osrfAppSetIntrospectMethod( ctx, method, resp );
-                       osrfAppRespond(ctx, resp);
-                       jsonObjectFree(resp);
-               }
-               osrfHashIteratorFree(itr);
-               return 1;
-       }
-
-       return -1;
-}
-
-int osrfAppEcho( osrfMethodContext* ctx ) {
-       OSRF_METHOD_VERIFY_CONTEXT(ctx);
-       int i;
-       for( i = 0; i < ctx->params->size; i++ ) {
-               jsonObject* str = jsonObjectGetIndex(ctx->params,i);
-               osrfAppRespond(ctx, str);
-       }
-       return 1;
-}
-
diff --git a/src/libstack/osrf_application.h b/src/libstack/osrf_application.h
deleted file mode 100644 (file)
index 0980a81..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-#include <stdio.h>
-#include <dlfcn.h>
-#include "opensrf/utils.h"
-#include "opensrf/log.h"
-#include "objson/object.h"
-#include "osrf_app_session.h"
-#include "osrf_hash.h"
-
-
-/**
-  All OpenSRF methods take the signature
-  int methodName( osrfMethodContext* );
-  If a negative number is returned, it means an unknown error occured and an exception
-  will be returned to the client automatically.
-  If a positive number is returned, it means that libopensrf should send a 'Request Complete'
-  message following any messages sent by the method.
-  If 0 is returned, it tells libopensrf that the method completed successfully and 
-  there is no need to send any further data to the client.
-  */
-
-
-
-/** 
-  This macro verifies methods receive the correct parameters */
-#define _OSRF_METHOD_VERIFY_CONTEXT(d) \
-       if(!d) return -1; \
-       if(!d->session) { osrfLogError( OSRF_LOG_MARK,  "Session is NULL in app reqeust" ); return -1; }\
-       if(!d->method) { osrfLogError( OSRF_LOG_MARK,  "Method is NULL in app reqeust" ); return -1; }\
-       if(d->method->argc) {\
-               if(!d->params) { osrfLogError( OSRF_LOG_MARK,  "Params is NULL in app reqeust %s", d->method->name ); return -1; }\
-               if( d->params->type != JSON_ARRAY ) { \
-                       osrfLogError( OSRF_LOG_MARK,  "'params' is not a JSON array for method %s", d->method->name);\
-                       return -1; }\
-       }\
-       if( !d->method->name ) { osrfLogError( OSRF_LOG_MARK,  "Method name is NULL"); return -1; } 
-
-#ifdef OSRF_LOG_PARAMS 
-#define OSRF_METHOD_VERIFY_CONTEXT(d) \
-       _OSRF_METHOD_VERIFY_CONTEXT(d); \
-       char* __j = jsonObjectToJSON(d->params);\
-       if(__j) { \
-               osrfLogInfo( OSRF_LOG_MARK,  "CALL:     %s %s - %s", d->session->remote_service, d->method->name, __j);\
-               free(__j); \
-       } 
-#else
-#define OSRF_METHOD_VERIFY_CONTEXT(d) _OSRF_METHOD_VERIFY_CONTEXT(d); 
-#endif
-
-
-
-/* used internally to make sure the method description provided is OK */
-#define OSRF_METHOD_VERIFY_DESCRIPTION(app, d) \
-       if(!app) return -1; \
-       if(!d) return -1;\
-       if(!d->name) { osrfLogError( OSRF_LOG_MARK,  "No method name provided in description" ), return -1; } \
-       if(!d->symbol) { osrfLogError( OSRF_LOG_MARK,  "No method symbol provided in description" ), return -1; } \
-       if(!d->notes) d->notes = ""; \
-       if(!d->paramNotes) d->paramNotes = "";\
-       if(!d->returnNotes) d->returnNotes = "";
-
-
-
-
-/* Some well known parameters */
-#define OSRF_SYSMETHOD_INTROSPECT                              "opensrf.system.method"
-#define OSRF_SYSMETHOD_INTROSPECT_ATOMIC               "opensrf.system.method.atomic"
-#define OSRF_SYSMETHOD_INTROSPECT_ALL                  "opensrf.system.method.all"
-#define OSRF_SYSMETHOD_INTROSPECT_ALL_ATOMIC   "opensrf.system.method.all.atomic"
-#define OSRF_SYSMETHOD_ECHO                                            "opensrf.system.echo"
-#define OSRF_SYSMETHOD_ECHO_ATOMIC                             "opensrf.system.echo.atomic"
-
-#define OSRF_METHOD_SYSTEM                     1
-#define OSRF_METHOD_STREAMING          2
-#define OSRF_METHOD_ATOMIC                     4
-#define OSRF_METHOD_CACHABLE           8
-
-       
-
-struct _osrfApplicationStruct {
-       void* handle;                                                                   /* the lib handle */
-       osrfHash* methods;
-   void (*onExit) (void);
-};
-typedef struct _osrfApplicationStruct osrfApplication;
-
-
-struct _osrfMethodStruct {
-       char* name;                                     /* the method name */
-       char* symbol;                           /* the symbol name (function) */
-       char* notes;                            /* public method documentation */
-       int argc;                                       /* how many args this method expects */
-       //char* paramNotes;                     /* Description of the params expected for this method */
-       int options;                            /* describes the various options for this method */
-       void* userData;                         /* You can put your weeeeeeed in it ... */
-
-       /*
-       int sysmethod;                          
-       int streaming;                          
-       int atomic;                                     
-       int cachable;                           
-       */
-}; 
-typedef struct _osrfMethodStruct osrfMethod;
-
-struct _osrfMethodContextStruct {
-       osrfAppSession* session;        /* the current session */
-       osrfMethod* method;                     /* the requested method */      
-       jsonObject* params;                     /* the params to the method */
-       int request;                                    /* request id */
-       jsonObject* responses;          /* array of cached responses. */
-};
-typedef struct _osrfMethodContextStruct osrfMethodContext;
-
-
-
-/** 
-  Register an application
-  @param appName The name of the application
-  @param soFile The library (.so) file that implements this application
-  @return 0 on success, -1 on error
-  */
-int osrfAppRegisterApplication( char* appName, char* soFile );
-
-/**
-  Register a method
-  Any method with  the OSRF_METHOD_STREAMING option set will have a ".atomic"
-  version of the method registered automatically
-  @param appName The name of the application that implements the method
-  @param methodName The fully qualified name of the method
-  @param symbolName The symbol name (function) that implements the method
-  @param notes Public documentation for this method.
-  @params argc The number of arguments this method expects 
-  @param streaming True if this is a streaming method that requires an atomic version
-  @return 0 on success, -1 on error
-  */
-int osrfAppRegisterMethod( char* appName, char* methodName, 
-               char* symbolName, char* notes, int argc, int options );
-
-
-int osrfAppRegisterExtendedMethod( char* appName, char* methodName, 
-               char* symbolName, char* notes, int argc, int options, void* );
-
-osrfMethod* _osrfAppBuildMethod( char* methodName, 
-               char* symbolName, char* notes, int argc, int options, void* );
-
-/**
-  Finds the given app in the list of apps
-  @param name The name of the application
-  @return The application pointer or NULL if there is no such application
-  */
-osrfApplication* _osrfAppFindApplication( char* name );
-
-/**
-  Finds the given method for the given app
-  @param appName The application
-  @param methodName The method to find
-  @return A method pointer or NULL if no such method 
-  exists for the given application
-  */
-osrfMethod* _osrfAppFindMethod( char* appName, char* methodName );
-
-/**
-  Finds the given method for the given app
-  @param app The application object
-  @param methodName The method to find
-  @return A method pointer or NULL if no such method 
-  exists for the given application
-  */
-osrfMethod* __osrfAppFindMethod( osrfApplication* app, char* methodName );
-
-
-/**
-  Runs the specified method for the specified application.
-  @param appName The name of the application who's method to run
-  @param methodName The name of the method to run
-  @param ses The app session attached to this request
-  @params reqId The request id for this request
-  @param params The method parameters
-  */
-int osrfAppRunMethod( char* appName, char* methodName, 
-               osrfAppSession* ses, int reqId, jsonObject* params );
-
-
-/**
-  Trys to run the requested method as a system method.
-  A system method is a well known method that all
-  servers implement.  
-  @param context The current method context
-  @return 0 if the method is run successfully, return < 0 means
-  the method was not run, return > 0 means the method was run
-  and the application code now needs to send a 'request complete' 
-  message
-  */
-int __osrfAppRunSystemMethod(osrfMethodContext* context);
-
-/**
-  Registers all of the system methods for this app so that they may be
-  treated the same as other methods */
-int __osrfAppRegisterSysMethods( char* app );
-
-
-
-/**
-  Responds to the client with a method exception
-  @param ses The current session
-  @param request The request id
-  @param msg The debug message to send to the client
-  @return 0 on successfully sending of the message, -1 otherwise
-  */
-int osrfAppRequestRespondException( osrfAppSession* ses, int request, char* msg, ... );
-
-int __osrfAppPostProcess( osrfMethodContext* context, int retcode );
-
-
-int osrfAppRespond( osrfMethodContext* context, jsonObject* data );
-int _osrfAppRespond( osrfMethodContext* context, jsonObject* data, int complete );
-int osrfAppRespondComplete( osrfMethodContext* context, jsonObject* data );
-
-/* OSRF_METHOD_ATOMIC and/or OSRF_METHOD_CACHABLE and/or 0 for no special options */
-//int osrfAppProcessMethodOptions( char* method );
-
-int osrfAppIntrospect( osrfMethodContext* ctx );
-int osrfAppIntrospectAll( osrfMethodContext* ctx );
-int osrfAppEcho( osrfMethodContext* ctx );
-
-
-/**
- * Tells the backend process to run its child init function */
-int osrfAppRunChildInit(char* appname);
-void osrfAppSetOnExit(osrfApplication* app, char* appName);
-void osrfAppRunExitCode();
-
-
diff --git a/src/libstack/osrf_big_hash.c b/src/libstack/osrf_big_hash.c
deleted file mode 100644 (file)
index 41d5131..0000000
+++ /dev/null
@@ -1,173 +0,0 @@
-#include "osrf_big_hash.h"
-
-osrfBigHash* osrfNewBigHash() {
-       osrfBigHash* hash = safe_malloc(sizeof(osrfBigHash));
-       hash->hash = (Pvoid_t) NULL;
-       hash->freeItem = NULL;
-       return hash;
-}
-
-void* osrfBigHashSet( osrfBigHash* hash, void* item, const char* key, ... ) {
-       if(!(hash && item && key )) return NULL;
-
-       Word_t* value;
-       VA_LIST_TO_STRING(key);
-       uint8_t idx[strlen(VA_BUF) + 1];
-       strcpy( idx, VA_BUF );
-
-       void* olditem = osrfBigHashRemove( hash, VA_BUF );
-
-       JSLI(value, hash->hash, idx);
-       if(value) *value = (Word_t) item;
-       return olditem;
-       
-}
-
-void* osrfBigHashRemove( osrfBigHash* hash, const char* key, ... ) {
-       if(!(hash && key )) return NULL;
-
-       VA_LIST_TO_STRING(key);
-
-       Word_t* value;
-       uint8_t idx[strlen(VA_BUF) + 1];
-       strcpy( idx, VA_BUF );
-       void* item = NULL;
-       int retcode;
-
-       JSLG( value, hash->hash,  idx);
-
-       if( value ) {
-               item = (void*) *value;
-               if(item) {
-                       if( hash->freeItem ) {
-                               hash->freeItem( (char*) idx, item ); 
-                               item = NULL;
-                       }
-               }
-       }
-
-
-       JSLD( retcode, hash->hash, idx );
-
-       return item;
-}
-
-
-void* osrfBigHashGet( osrfBigHash* hash, const char* key, ... ) {
-       if(!(hash && key )) return NULL;
-
-       VA_LIST_TO_STRING(key);
-
-       Word_t* value;
-       uint8_t idx[strlen(VA_BUF) + 1];
-       strcpy( idx, VA_BUF );
-
-       JSLG( value, hash->hash, idx );
-       if(value) return (void*) *value;
-       return NULL;
-}
-
-
-osrfStringArray* osrfBigHashKeys( osrfBigHash* hash ) {
-       if(!hash) return NULL;
-
-       Word_t* value;
-       uint8_t idx[OSRF_HASH_MAXKEY];
-       strcpy(idx, "");
-       char* key;
-       osrfStringArray* strings = osrfNewStringArray(8);
-
-       JSLF( value, hash->hash, idx );
-
-       while( value ) {
-               key = (char*) idx;
-               osrfStringArrayAdd( strings, key );
-               JSLN( value, hash->hash, idx );
-       }
-
-       return strings;
-}
-
-
-unsigned long osrfBigHashGetCount( osrfBigHash* hash ) {
-       if(!hash) return -1;
-
-       Word_t* value;
-       unsigned long count = 0;
-       uint8_t idx[OSRF_HASH_MAXKEY];
-
-       strcpy( (char*) idx, "");
-       JSLF(value, hash->hash, idx);
-
-       while(value) {
-               count++;
-               JSLN( value, hash->hash, idx );
-       }
-
-       return count;
-}
-
-void osrfBigHashFree( osrfBigHash* hash ) {
-       if(!hash) return;
-
-       int i;
-       osrfStringArray* keys = osrfBigHashKeys( hash );
-
-       for( i = 0; i != keys->size; i++ )  {
-               char* key = (char*) osrfStringArrayGetString( keys, i );
-               osrfBigHashRemove( hash, key );
-       }
-
-       osrfStringArrayFree(keys);
-       free(hash);
-}
-
-
-
-osrfBigHashIterator* osrfNewBigHashIterator( osrfBigHash* hash ) {
-       if(!hash) return NULL;
-       osrfBigHashIterator* itr = safe_malloc(sizeof(osrfBigHashIterator));
-       itr->hash = hash;
-       itr->current = NULL;
-       return itr;
-}
-
-void* osrfBigHashIteratorNext( osrfBigHashIterator* itr ) {
-       if(!(itr && itr->hash)) return NULL;
-
-       Word_t* value;
-       uint8_t idx[OSRF_HASH_MAXKEY];
-
-       if( itr->current == NULL ) { /* get the first item in the list */
-               strcpy(idx, "");
-               JSLF( value, itr->hash->hash, idx );
-
-       } else {
-               strcpy(idx, itr->current);
-               JSLN( value, itr->hash->hash, idx );
-       }
-
-       if(value) {
-               free(itr->current);
-               itr->current = strdup((char*) idx);
-               return (void*) *value;
-       }
-
-       return NULL;
-
-}
-
-void osrfBigHashIteratorFree( osrfBigHashIterator* itr ) {
-       if(!itr) return;
-       free(itr->current);
-       free(itr);
-}
-
-void osrfBigHashIteratorReset( osrfBigHashIterator* itr ) {
-       if(!itr) return;
-       free(itr->current);
-       itr->current = NULL;
-}
-
-
-
diff --git a/src/libstack/osrf_big_hash.h b/src/libstack/osrf_big_hash.h
deleted file mode 100644 (file)
index 22e0a46..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-#ifndef OSRF_HASH_H
-#define OSRF_HASH_H
-
-#include <Judy.h>
-#include "opensrf/utils.h"
-#include "opensrf/string_array.h"
-
-#define OSRF_HASH_MAXKEY 256
-
-struct __osrfBigHashStruct {
-       Pvoid_t hash;                                                   /* the hash */
-       void (*freeItem) (char* key, void* item);       /* callback for freeing stored items */
-};
-typedef struct __osrfBigHashStruct osrfBigHash;
-
-
-struct __osrfBigHashIteratorStruct {
-       char* current;
-       osrfBigHash* hash;
-};
-typedef struct __osrfBigHashIteratorStruct osrfBigHashIterator;
-
-/**
-  Allocates a new hash object
-  */
-osrfBigHash* osrfNewBigHash();
-
-/**
-  Sets the given key with the given item
-  if "freeItem" is defined and an item already exists at the given location, 
-  then old item is freed and the new item is put into place.
-  if "freeItem" is not defined and an item already exists, the old item
-  is returned.
-  @return The old item if exists and there is no 'freeItem', returns NULL
-  otherwise
-  */
-void* osrfBigHashSet( osrfBigHash* hash, void* item, const char* key, ... );
-
-/**
-  Removes an item from the hash.
-  if 'freeItem' is defined it is used and NULL is returned,
-  else the freed item is returned
-  */
-void* osrfBigHashRemove( osrfBigHash* hash, const char* key, ... );
-
-void* osrfBigHashGet( osrfBigHash* hash, const char* key, ... );
-
-
-/**
-  @return A list of strings representing the keys of the hash. 
-  caller is responsible for freeing the returned string array 
-  with osrfStringArrayFree();
-  */
-osrfStringArray* osrfBigHashKeys( osrfBigHash* hash );
-
-/**
-  Frees a hash
-  */
-void osrfBigHashFree( osrfBigHash* hash );
-
-/**
-  @return The number of items in the hash
-  */
-unsigned long osrfBigHashGetCount( osrfBigHash* hash );
-
-
-
-
-/**
-  Creates a new list iterator with the given list
-  */
-osrfBigHashIterator* osrfNewBigHashIterator( osrfBigHash* hash );
-
-/**
-  Returns the next non-NULL item in the list, return NULL when
-  the end of the list has been reached
-  */
-void* osrfBigHashIteratorNext( osrfBigHashIterator* itr );
-
-/**
-  Deallocates the given list
-  */
-void osrfBigHashIteratorFree( osrfBigHashIterator* itr );
-
-void osrfBigHashIteratorReset( osrfBigHashIterator* itr );
-
-#endif
diff --git a/src/libstack/osrf_big_list.c b/src/libstack/osrf_big_list.c
deleted file mode 100644 (file)
index 5d7e3dc..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "osrf_big_list.h"
-
-
-osrfBigList* osrfNewBigList() {
-       osrfBigList* list = safe_malloc(sizeof(osrfBigList));
-       list->list = (Pvoid_t) NULL;
-       list->size = 0;
-       list->freeItem = NULL;
-       return list;
-}
-
-
-int osrfBigListPush( osrfBigList* list, void* item ) {
-       if(!(list && item)) return -1;
-       Word_t* value;
-       unsigned long index = -1;
-       JLL(value, list->list, index );
-       osrfBigListSet( list, item, index+1 );
-       return 0;
-}
-
-
-void* osrfBigListSet( osrfBigList* list, void* item, unsigned long position ) {
-       if(!list || position < 0) return NULL;
-
-       Word_t* value;
-       void* olditem = osrfBigListRemove( list, position );
-
-       JLI( value, list->list, position ); 
-       *value = (Word_t) item;
-       __osrfBigListSetSize( list );
-
-       return olditem;
-}
-
-
-void* osrfBigListGetIndex( osrfBigList* list, unsigned long position ) {
-       if(!list) return NULL;
-
-       Word_t* value;
-       JLG( value, list->list, position );
-       if(value) return (void*) *value;
-       return NULL;
-}
-
-void osrfBigListFree( osrfBigList* list ) {
-       if(!list) return;
-
-       Word_t* value;
-       unsigned long index = -1;
-       JLL(value, list->list, index );
-       int retcode;
-
-       while (value != NULL) {
-               if(list->freeItem) 
-                       list->freeItem( (void*) *value );
-               JLD(retcode, list->list, index);
-               JLP(value, list->list, index);
-       }               
-
-       free(list);
-}
-
-void* osrfBigListRemove( osrfBigList* list, int position ) {
-       if(!list) return NULL;
-
-       int retcode;
-       Word_t* value;
-       JLG( value, list->list, position );
-       void* olditem = NULL;
-
-       if( value ) {
-
-               olditem = (void*) *value;
-               if( olditem ) {
-                       JLD(retcode, list->list, position );
-                       if(retcode == 1) {
-                               if(list->freeItem) {
-                                       list->freeItem( olditem );
-                                       olditem = NULL;
-                               }
-                               __osrfBigListSetSize( list );
-                       }
-               }
-       }
-
-       return olditem;
-}
-
-
-int osrfBigListFind( osrfBigList* list, void* addr ) {
-       if(!(list && addr)) return -1;
-
-       Word_t* value;
-       unsigned long index = -1;
-       JLL(value, list->list, index );
-
-       while (value != NULL) {
-               if( (void*) *value == addr )
-                       return index;
-               JLP(value, list->list, index);
-       }
-
-       return -1;
-}
-
-
-
-void __osrfBigListSetSize( osrfBigList* list ) {
-       if(!list) return;
-
-       Word_t* value;
-       unsigned long index = -1;
-       JLL(value, list->list, index );
-       list->size = index + 1;
-}
-
-
-unsigned long osrfBigListGetCount( osrfBigList* list ) {
-       if(!list) return -1;
-       unsigned long retcode = -1;
-       JLC( retcode, list->list, 0, -1 );
-       return retcode;
-}
-
-
-void* osrfBigListPop( osrfBigList* list ) {
-       if(!list) return NULL;
-       return osrfBigListRemove( list, list->size - 1 );
-}
-
-
-osrfBigBigListIterator* osrfNewBigListIterator( osrfBigList* list ) {
-       if(!list) return NULL;
-       osrfBigBigListIterator* itr = safe_malloc(sizeof(osrfBigBigListIterator));
-       itr->list = list;
-       itr->current = 0;
-       return itr;
-}
-
-void* osrfBigBigListIteratorNext( osrfBigBigListIterator* itr ) {
-       if(!(itr && itr->list)) return NULL;
-
-       Word_t* value;
-       if(itr->current >= itr->list->size) return NULL;
-       JLF( value, itr->list->list, itr->current );
-       if(value) {
-               itr->current++;
-               return (void*) *value;
-       }
-       return NULL;
-}
-
-void osrfBigBigListIteratorFree( osrfBigBigListIterator* itr ) {
-       if(!itr) return;
-       free(itr);
-}
-
-
-
-void osrfBigBigListIteratorReset( osrfBigBigListIterator* itr ) {
-       if(!itr) return;
-       itr->current = 0;
-}
-
-
-void osrfBigListVanillaFree( void* item ) {
-       free(item);
-}
-
-void osrfBigListSetDefaultFree( osrfBigList* list ) {
-       if(!list) return;
-       list->freeItem = osrfBigListVanillaFree;
-}
diff --git a/src/libstack/osrf_big_list.h b/src/libstack/osrf_big_list.h
deleted file mode 100644 (file)
index 523f28d..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#ifndef OSRF_BIG_LIST_H
-#define OSRF_BIG_LIST_H
-
-
-#include <stdio.h>
-#include "opensrf/utils.h"
-#include <Judy.h>
-
-/**
-  Items are stored as void*'s so it's up to the user to
-  manage the data wisely.  Also, if the 'freeItem' callback is defined for the list,
-  then, it will be used on any item that needs to be freed, so don't mix data
-  types in the list if you want magic freeing */
-
-struct __osrfBigListStruct {
-       Pvoid_t list;                                                   /* the list */
-       int size;                                                               /* how many items in the list including NULL items between non-NULL items */    
-       void (*freeItem) (void* item);  /* callback for freeing stored items */
-};
-typedef struct __osrfBigListStruct osrfBigList;
-
-
-struct __osrfBigBigListIteratorStruct {
-       osrfBigList* list;
-       unsigned long current;
-};
-typedef struct __osrfBigBigListIteratorStruct osrfBigBigListIterator;
-
-
-/**
-  Creates a new list iterator with the given list
-  */
-osrfBigBigListIterator* osrfNewBigListIterator( osrfBigList* list );
-
-/**
-  Returns the next non-NULL item in the list, return NULL when
-  the end of the list has been reached
-  */
-void* osrfBigBigListIteratorNext( osrfBigBigListIterator* itr );
-
-/**
-  Deallocates the given list
-  */
-void osrfBigBigListIteratorFree( osrfBigBigListIterator* itr );
-
-void osrfBigBigListIteratorReset( osrfBigBigListIterator* itr );
-
-
-/**
-  Allocates a new list
-  @param compress If true, the list will compress empty slots on delete.  If item positionality
-  is not important, then using this feature is reccomended to keep the list from growing indefinitely.
-  if item positionality is not important.
-  @return The allocated list
-  */
-osrfBigList* osrfNewBigList();
-
-/**
-  Pushes an item onto the end of the list.  This always finds the highest index
-  in the list and pushes the new item into the list after it.
-  @param list The list
-  @param item The item to push
-  @return 0 on success, -1 on failure
-  */
-int osrfBigListPush( osrfBigList* list, void* item );
-
-
-/**
- * Removes the last item in the list
- * See osrfBigListRemove for details on how the removed item is handled
- * @return The item, unless 'freeItem' exists, then returns NULL
- */
-void* osrfBigListPop( osrfBigList* list );
-
-/**
-  Puts the given item into the list at the specified position.  If there
-  is already an item at the given position and the list has it's 
-  "freeItem" function defined, then it will be used to free said item.
-  If no 'freeItem' callback is defined, then the displaced item will
-  be returned;
-  @param list The list
-  @param item The item to put into the list
-  @param position The position to place the item in
-  @return NULL in successfully inserting the new item and freeing
-  any displaced items.  Returns the displaced item if no "freeItem"
-  callback is defined.
-       */
-void* osrfBigListSet( osrfBigList* list, void* item, unsigned long position );
-
-/**
-  Returns the item at the given position
-  @param list The list
-  @param postiont the position
-  */
-void* osrfBigListGetIndex( osrfBigList* list, unsigned long  position );
-
-/**
-  Frees the list and all list items (if the list has a "freeItem" function defined )
-  @param list The list
-  */
-void osrfBigListFree( osrfBigList* list );
-
-/**
-  Removes the list item at the given index
-  @param list The list
-  @param position The position of the item to remove
-  @return A pointer to the item removed if "freeItem" is not defined
-  for this list, returns NULL if it is.
-  */
-void* osrfBigListRemove( osrfBigList* list, int position );
-
-/**
-  Finds the list item whose void* is the same as the one passed in
-  @param list The list
-  @param addr The pointer connected to the list item we're to find
-  @return the index of the item, or -1 if the item was not found
-  */
-int osrfBigListFind( osrfBigList* list, void* addr );
-
-
-void __osrfBigListSetSize( osrfBigList* list );
-
-
-/**
-  @return The number of non-null items in the list
-  */
-unsigned long osrfBigListGetCount( osrfBigList* list );
-
-/**
- * May be used as a default memory freeing call
- * Just calls free() on list items
- */
-void osrfBigListVanillaFree( void* item );
-
-/**
- * Tells the list to just call 'free()' on each item when
- * an item or the whole list is destroyed
- */
-void osrfBigListSetDefaultFree( osrfBigList* list );
-
-
-#endif
diff --git a/src/libstack/osrf_cache.c b/src/libstack/osrf_cache.c
deleted file mode 100644 (file)
index 13cb272..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Copyright (C) 2005  Georgia Public Library Service 
-Bill Erickson <highfalutin@gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-*/
-
-#include "osrf_cache.h"
-
-struct memcache* __osrfCache = NULL;
-time_t __osrfCacheMaxSeconds = -1;
-
-int osrfCacheInit( char* serverStrings[], int size, time_t maxCacheSeconds ) {
-       if( !(serverStrings && size > 0) ) return -1;
-
-       int i;
-       __osrfCache = mc_new();
-       __osrfCacheMaxSeconds = maxCacheSeconds;
-
-       for( i = 0; i < size && serverStrings[i]; i++ ) 
-               mc_server_add4( __osrfCache, serverStrings[i] );
-
-       return 0;
-}
-
-int osrfCachePutObject( char* key, const jsonObject* obj, time_t seconds ) {
-       if( !(key && obj) ) return -1;
-       char* s = jsonObjectToJSON( obj );
-       osrfLogInternal( OSRF_LOG_MARK, "osrfCachePut(): Putting object: %s", s);
-       if( seconds < 0 ) seconds = __osrfCacheMaxSeconds;
-
-       mc_set(__osrfCache, key, strlen(key), s, strlen(s), seconds, 0);
-       free(s);
-       return 0;
-}
-
-int osrfCachePutString( char* key, const char* value, time_t seconds ) {
-       if( !(key && value) ) return -1;
-       if( seconds < 0 ) seconds = __osrfCacheMaxSeconds;
-       osrfLogInternal( OSRF_LOG_MARK, "osrfCachePutString(): Putting string: %s", value);
-       mc_set(__osrfCache, key, strlen(key), value, strlen(value), seconds, 0);
-       return 0;
-}
-
-jsonObject* osrfCacheGetObject( char* key, ... ) {
-       jsonObject* obj = NULL;
-       if( key ) {
-               VA_LIST_TO_STRING(key);
-               char* data = (char*) mc_aget( __osrfCache, VA_BUF, strlen(VA_BUF) );
-               if( data ) {
-                       osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetObject(): Returning object: %s", data);
-                       obj = jsonParseString( data );
-                       return obj;
-               }
-               osrfLogWarning(OSRF_LOG_MARK, "No cache data exists with key %s", VA_BUF);
-       }
-       return NULL;
-}
-
-char* osrfCacheGetString( char* key, ... ) {
-       if( key ) {
-               VA_LIST_TO_STRING(key);
-               char* data = (char*) mc_aget(__osrfCache, VA_BUF, strlen(VA_BUF) );
-               osrfLogInternal( OSRF_LOG_MARK, "osrfCacheGetObject(): Returning object: %s", data);
-               if(!data) osrfLogWarning(OSRF_LOG_MARK, "No cache data exists with key %s", VA_BUF);
-               return data;
-       }
-       return NULL;
-}
-
-
-int osrfCacheRemove( char* key, ... ) {
-       if( key ) {
-               VA_LIST_TO_STRING(key);
-               return mc_delete(__osrfCache, VA_BUF, strlen(VA_BUF), 0 );
-       }
-       return -1;
-}
-
-
-int osrfCacheSetExpire( time_t seconds, char* key, ... ) {
-       if( key ) {
-               VA_LIST_TO_STRING(key);
-               jsonObject* o = osrfCacheGetObject( VA_BUF );
-               //osrfCacheRemove(VA_BUF);
-               return osrfCachePutObject( VA_BUF, o, seconds );
-       }
-       return -1;
-}
-
-
diff --git a/src/libstack/osrf_cache.h b/src/libstack/osrf_cache.h
deleted file mode 100644 (file)
index 317cdd0..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
-Copyright (C) 2005  Georgia Public Library Service 
-Bill Erickson <highfalutin@gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-*/
-
-
-#include "objson/object.h"
-#include "objson/json_parser.h"
-#include "memcache.h"
-#include "log.h"
-
-/**
-  osrfCache is a globally shared cache API
-  */
-
-
-/**
-  Initialize the cache.
-  @param serverStrings An array of "ip:port" strings to use as cache servers
-  @param size The size of the serverStrings array
-  @param maxCacheSeconds The maximum amount of time an object / string may
-       be cached.  Negative number means there is no limit
-  */
-int osrfCacheInit( char* serverStrings[], int size, time_t maxCacheSeconds );
-
-
-/**
-  Puts an object into the cache
-  @param key The cache key
-  @param obj The object to cache
-  @param seconds The amount of time to cache the data, negative number means
-       to cache up to 'maxCacheSeconds' as set by osrfCacheInit()
-  @return 0 on success, -1 on error
-  */
-int osrfCachePutObject( char* key, const jsonObject* obj, time_t seconds );
-
-/**
-  Puts a string into the cache
-  @param key The cache key
-  @param value The string to cache
-  @param seconds The amount of time to cache the data, negative number means
-       to cache up to 'maxCacheSeconds' as set by osrfCacheInit()
-  @return 0 on success, -1 on error
-  */
-int osrfCachePutString( char* key, const char* value, time_t seconds);
-
-/**
-  Grabs an object from the cache.
-  @param key The cache key
-  @return The object (which must be freed) if it exists, otherwise returns NULL
-  */
-jsonObject* osrfCacheGetObject( char* key, ... );
-
-/**
-  Grabs a string from the cache.
-  @param key The cache key
-  @return The string (which must be freed) if it exists, otherwise returns NULL
-  */
-char* osrfCacheGetString( char* key, ... );
-
-/**
-  Removes the item with the given key from the cache.
-  @return 0 on success, -1 on error.
-  */
-int osrfCacheRemove( char* key, ... );
-
-/**
- * Sets the expire time to 'seconds' for the given key
- */
-int osrfCacheSetExpire( time_t seconds, char* key, ... );
-
-
-
diff --git a/src/libstack/osrf_hash.c b/src/libstack/osrf_hash.c
deleted file mode 100644 (file)
index 778c282..0000000
+++ /dev/null
@@ -1,242 +0,0 @@
-#include "osrf_hash.h"
-
-osrfHash* osrfNewHash() {
-       osrfHash* hash;
-       OSRF_MALLOC(hash, sizeof(osrfHash));
-       hash->hash              = osrfNewList();
-       hash->keys              = osrfNewStringArray(64);
-       return hash;
-}
-
-
-/* algorithm proposed by Donald E. Knuth 
- * in The Art Of Computer Programming Volume 3 (more or less..)*/
-/*
-static unsigned int osrfHashMakeKey(char* str) {
-       if(!str) return 0;
-       unsigned int len = strlen(str);
-       unsigned int h = len;
-       unsigned int i = 0;
-       for(i = 0; i < len; str++, i++)
-               h = ((h << 5) ^ (h >> 27)) ^ (*str);
-       return (h & (OSRF_HASH_LIST_SIZE-1));
-}
-*/
-
-
-/* macro version of the above function */
-#define OSRF_HASH_MAKE_KEY(str,num) \
-   do {\
-      char* __k = str;\
-      unsigned int __len = strlen(__k); \
-      unsigned int __h = __len;\
-      unsigned int __i = 0;\
-      for(__i = 0; __i < __len; __k++, __i++)\
-         __h = ((__h << 5) ^ (__h >> 27)) ^ (*__k);\
-      num = (__h & (OSRF_HASH_LIST_SIZE-1));\
-   } while(0)
-
-
-
-/* returns the index of the item and points l to the sublist the item
- * lives in if the item and points n to the hashnode the item 
- * lives in if the item is found.  Otherwise -1 is returned */
-static unsigned int osrfHashFindItem( osrfHash* hash, char* key, osrfList** l, osrfHashNode** n ) {
-       if(!(hash && key)) return -1;
-
-
-       unsigned int i = 0;
-       OSRF_HASH_MAKE_KEY(key,i);
-
-       osrfList* list = OSRF_LIST_GET_INDEX( hash->hash, i );
-       if( !list ) { return -1; }
-
-       int k;
-       osrfHashNode* node = NULL;
-       for( k = 0; k < list->size; k++ ) {
-               node = OSRF_LIST_GET_INDEX(list, k);
-               if( node && node->key && !strcmp(node->key, key) )
-                       break;
-               node = NULL;
-       }
-
-       if(!node) return -1;
-
-       if(l) *l = list;
-       if(n) *n = node;
-       return k;
-}
-
-osrfHashNode* osrfNewHashNode(char* key, void* item) {
-       if(!(key && item)) return NULL;
-       osrfHashNode* n;
-       OSRF_MALLOC(n, sizeof(osrfHashNode));
-       n->key = strdup(key);
-       n->item = item;
-       return n;
-}
-
-void* osrfHashNodeFree(osrfHash* hash, osrfHashNode* node) {
-       if(!(node && hash)) return NULL;
-       void* item = NULL;
-       if( hash->freeItem )
-               hash->freeItem( node->key, node->item );
-       else item = node->item;
-       free(node->key);
-       free(node);
-       return item;
-}
-
-void* osrfHashSet( osrfHash* hash, void* item, const char* key, ... ) {
-       if(!(hash && item && key )) return NULL;
-
-       VA_LIST_TO_STRING(key);
-       void* olditem = osrfHashRemove( hash, VA_BUF );
-
-       unsigned int bucketkey = 0;
-       OSRF_HASH_MAKE_KEY(VA_BUF,bucketkey);
-       
-       osrfList* bucket;
-       if( !(bucket = OSRF_LIST_GET_INDEX(hash->hash, bucketkey)) ) {
-               bucket = osrfNewList();
-               osrfListSet( hash->hash, bucket, bucketkey );
-       }
-
-       osrfHashNode* node = osrfNewHashNode(VA_BUF, item);
-       osrfListPushFirst( bucket, node );
-
-       if(!osrfStringArrayContains(hash->keys, VA_BUF))
-               osrfStringArrayAdd( hash->keys, VA_BUF );
-
-       hash->size++;
-       return olditem;
-}
-
-void* osrfHashRemove( osrfHash* hash, const char* key, ... ) {
-       if(!(hash && key )) return NULL;
-
-       VA_LIST_TO_STRING(key);
-
-       osrfList* list = NULL;
-       osrfHashNode* node;
-       int index = osrfHashFindItem( hash, (char*) VA_BUF, &list, &node );
-       if( index == -1 ) return NULL;
-
-       osrfListRemove( list, index );
-       hash->size--;
-
-       void* item = osrfHashNodeFree(hash, node);
-       osrfStringArrayRemove(hash->keys, VA_BUF);
-       return item;
-}
-
-
-void* osrfHashGet( osrfHash* hash, const char* key, ... ) {
-       if(!(hash && key )) return NULL;
-       VA_LIST_TO_STRING(key);
-
-       osrfHashNode* node = NULL;
-       int index = osrfHashFindItem( hash, (char*) VA_BUF, NULL, &node );
-       if( index == -1 ) return NULL;
-       return node->item;
-}
-
-
-osrfStringArray* osrfHashKeysInc( osrfHash* hash ) {
-       if(!hash) return NULL;
-       return hash->keys;
-}
-
-osrfStringArray* osrfHashKeys( osrfHash* hash ) {
-       if(!hash) return NULL;
-       
-       int i, k;
-       osrfList* list;
-       osrfHashNode* node;
-       osrfStringArray* strings = osrfNewStringArray(8);
-
-       for( i = 0; i != hash->hash->size; i++ ) {
-               list = OSRF_LIST_GET_INDEX( hash->hash, i );
-               if(list) {
-                       for( k = 0; k != list->size; k++ ) {
-                               node = OSRF_LIST_GET_INDEX( list, k );  
-                               if( node ) osrfStringArrayAdd( strings, node->key );
-                       }
-               }
-       }
-
-       return strings;
-}
-
-
-unsigned long osrfHashGetCount( osrfHash* hash ) {
-       if(!hash) return -1;
-       return hash->size;
-}
-
-void osrfHashFree( osrfHash* hash ) {
-       if(!hash) return;
-
-       int i, j;
-       osrfList* list;
-       osrfHashNode* node;
-
-       for( i = 0; i != hash->hash->size; i++ ) {
-               if( ( list = OSRF_LIST_GET_INDEX( hash->hash, i )) ) {
-                       for( j = 0; j != list->size; j++ ) {
-                               if( (node = OSRF_LIST_GET_INDEX( list, j )) ) {
-                                       OSRF_HASH_NODE_FREE(hash, node);
-                               }
-                       }
-                       osrfListFree(list);
-               }
-       }
-
-       osrfListFree(hash->hash);
-       osrfStringArrayFree(hash->keys);
-       free(hash);
-}
-
-
-
-osrfHashIterator* osrfNewHashIterator( osrfHash* hash ) {
-       if(!hash) return NULL;
-       //osrfHashIterator* itr = safe_malloc(sizeof(osrfHashIterator));
-       osrfHashIterator* itr;
-       OSRF_MALLOC(itr, sizeof(osrfHashIterator));
-       itr->hash = hash;
-       itr->current = NULL;
-       itr->keys = osrfHashKeysInc(hash);
-       return itr;
-}
-
-void* osrfHashIteratorNext( osrfHashIterator* itr ) {
-       if(!(itr && itr->hash)) return NULL;
-       if( itr->currentIdx >= itr->keys->size ) return NULL;
-       free(itr->current);
-       itr->current = strdup(
-                       osrfStringArrayGetString(itr->keys, itr->currentIdx++));
-       char* val = osrfHashGet( itr->hash, itr->current );
-       return val;
-}
-
-void osrfHashIteratorFree( osrfHashIterator* itr ) {
-       if(!itr) return;
-       free(itr->current);
-       //osrfStringArrayFree(itr->keys);
-       free(itr);
-}
-
-void osrfHashIteratorReset( osrfHashIterator* itr ) {
-       if(!itr) return;
-       free(itr->current);
-       //osrfStringArrayFree(itr->keys);
-       itr->keys = osrfHashKeysInc(itr->hash);
-       itr->currentIdx = 0;
-       itr->current = NULL;
-}
-
-
-int osrfHashIteratorHasNext( osrfHashIterator* itr ) {
-       return ( itr->currentIdx < itr->keys->size ) ? 1 : 0;
-}
diff --git a/src/libstack/osrf_hash.h b/src/libstack/osrf_hash.h
deleted file mode 100644 (file)
index 02e62c2..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#ifndef OSRF_HASH_H
-#define OSRF_HASH_H
-
-#include "opensrf/utils.h"
-#include "opensrf/string_array.h"
-#include "osrf_list.h"
-
-/* 0x100 is a good size for small hashes */
-//#define OSRF_HASH_LIST_SIZE 0x100  /* size of the main hash list */
-#define OSRF_HASH_LIST_SIZE 0x10  /* size of the main hash list */
-
-
-/* used internally */
-#define OSRF_HASH_NODE_FREE(h, n) \
-       if(h && n) { \
-               if(h->freeItem) h->freeItem(n->key, n->item);\
-               free(n->key); free(n); \
-       }
-
-
-struct __osrfHashStruct {
-       osrfList* hash; /* this hash */
-       void (*freeItem) (char* key, void* item);       /* callback for freeing stored items */
-       unsigned int size;
-       osrfStringArray* keys;
-};
-typedef struct __osrfHashStruct osrfHash;
-
-struct _osrfHashNodeStruct {
-       char* key;
-       void* item;
-};
-typedef struct _osrfHashNodeStruct osrfHashNode;
-
-
-struct __osrfHashIteratorStruct {
-       char* current;
-       int currentIdx;
-       osrfHash* hash;
-       osrfStringArray* keys;
-};
-typedef struct __osrfHashIteratorStruct osrfHashIterator;
-
-osrfHashNode* osrfNewHashNode(char* key, void* item);
-void* osrfHashNodeFree(osrfHash*, osrfHashNode*);
-
-/**
-  Allocates a new hash object
-  */
-osrfHash* osrfNewHash();
-
-/**
-  Sets the given key with the given item
-  if "freeItem" is defined and an item already exists at the given location, 
-  then old item is freed and the new item is put into place.
-  if "freeItem" is not defined and an item already exists, the old item
-  is returned.
-  @return The old item if exists and there is no 'freeItem', returns NULL
-  otherwise
-  */
-void* osrfHashSet( osrfHash* hash, void* item, const char* key, ... );
-
-/**
-  Removes an item from the hash.
-  if 'freeItem' is defined it is used and NULL is returned,
-  else the freed item is returned
-  */
-void* osrfHashRemove( osrfHash* hash, const char* key, ... );
-
-void* osrfHashGet( osrfHash* hash, const char* key, ... );
-
-
-/**
-  @return A list of strings representing the keys of the hash. 
-  caller is responsible for freeing the returned string array 
-  with osrfStringArrayFree();
-  */
-osrfStringArray* osrfHashKeys( osrfHash* hash );
-
-osrfStringArray* osrfHashKeysInc( osrfHash* hash );
-
-/**
-  Frees a hash
-  */
-void osrfHashFree( osrfHash* hash );
-
-/**
-  @return The number of items in the hash
-  */
-unsigned long osrfHashGetCount( osrfHash* hash );
-
-
-
-
-/**
-  Creates a new list iterator with the given list
-  */
-osrfHashIterator* osrfNewHashIterator( osrfHash* hash );
-
-int osrfHashIteratorHasNext( osrfHashIterator* itr );
-
-/**
-  Returns the next non-NULL item in the list, return NULL when
-  the end of the list has been reached
-  */
-void* osrfHashIteratorNext( osrfHashIterator* itr );
-
-/**
-  Deallocates the given list
-  */
-void osrfHashIteratorFree( osrfHashIterator* itr );
-
-void osrfHashIteratorReset( osrfHashIterator* itr );
-
-#endif
diff --git a/src/libstack/osrf_list.c b/src/libstack/osrf_list.c
deleted file mode 100644 (file)
index 0e58f0f..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-#include "osrf_list.h"
-
-osrfList* osrfNewList() {
-       osrfList* list;
-       OSRF_MALLOC(list, sizeof(osrfList));
-       list->arrsize   = OSRF_LIST_DEFAULT_SIZE;
-       OSRF_MALLOC(list->arrlist, list->arrsize * sizeof(void*));
-       return list;
-}
-
-osrfList* osrfNewListSize( unsigned int size ) {
-       osrfList* list;
-       OSRF_MALLOC(list, sizeof(osrfList));
-    if( size <= 0 ) size = 16;
-       list->arrsize   = size;
-       OSRF_MALLOC( list->arrlist, list->arrsize * sizeof(void*) );
-       return list;
-}
-
-
-int osrfListPush( osrfList* list, void* item ) {
-       if(!(list)) return -1;
-       osrfListSet( list, item, list->size );
-       return 0;
-}
-
-int osrfListPushFirst( osrfList* list, void* item ) {
-       if(!(list && item)) return -1;
-       int i;
-       for( i = 0; i < list->size; i++ ) 
-               if(!list->arrlist[i]) break;
-       osrfListSet( list, item, i );
-       return list->size;
-}
-
-void* osrfListSet( osrfList* list, void* item, unsigned int position ) {
-       if(!list || position < 0) return NULL;
-
-       int i;
-       int newsize = list->arrsize;
-       void** newarr;
-
-       while( position >= newsize ) 
-               newsize += OSRF_LIST_INC_SIZE;
-
-       if( newsize > list->arrsize ) { /* expand the list if necessary */
-               OSRF_MALLOC(newarr, newsize * sizeof(void*));
-               for( i = 0; i < list->arrsize; i++ ) 
-                       newarr[i] = list->arrlist[i];
-               free(list->arrlist);
-               list->arrlist = newarr;
-               list->arrsize = newsize;
-       }
-
-       void* olditem = osrfListRemove( list, position );
-       list->arrlist[position] = item;
-       if( list->size <= position ) list->size = position + 1;
-       return olditem;
-}
-
-
-void* osrfListGetIndex( const osrfList* list, unsigned int position ) {
-       if(!list || position >= list->size || position < 0) return NULL;
-       return list->arrlist[position];
-}
-
-void osrfListFree( osrfList* list ) {
-       if(!list) return;
-
-       if( list->freeItem ) {
-               int i; void* val;
-               for( i = 0; i < list->size; i++ ) {
-                       if( (val = list->arrlist[i]) ) 
-                               list->freeItem(val);
-               }
-       }
-
-       free(list->arrlist);
-       free(list);
-}
-
-void* osrfListRemove( osrfList* list, unsigned int position ) {
-       if(!list || position >= list->size || position < 0) return NULL;
-
-       void* olditem = list->arrlist[position];
-       list->arrlist[position] = NULL;
-       if( list->freeItem ) {
-               list->freeItem(olditem);
-               olditem = NULL;
-       }
-
-       if( position == list->size - 1 ) list->size--;
-       return olditem;
-}
-
-
-int osrfListFind( const osrfList* list, void* addr ) {
-       if(!(list && addr)) return -1;
-       int index;
-       for( index = 0; index < list->size; index++ ) {
-               if( list->arrlist[index] == addr ) 
-                       return index;
-       }
-       return -1;
-}
-
-
-unsigned int osrfListGetCount( const osrfList* list ) {
-       if(!list) return -1;
-       return list->size;
-}
-
-
-void* osrfListPop( osrfList* list ) {
-       if(!list) return NULL;
-       return osrfListRemove( list, list->size - 1 );
-}
-
-
-osrfListIterator* osrfNewListIterator( const osrfList* list ) {
-       if(!list) return NULL;
-       osrfListIterator* itr;
-       OSRF_MALLOC(itr, sizeof(osrfListIterator));
-       itr->list = list;
-       itr->current = 0;
-       return itr;
-}
-
-void* osrfListIteratorNext( osrfListIterator* itr ) {
-       if(!(itr && itr->list)) return NULL;
-       if(itr->current >= itr->list->size) return NULL;
-       return itr->list->arrlist[itr->current++];
-}
-
-void osrfListIteratorFree( osrfListIterator* itr ) {
-       if(!itr) return;
-       free(itr);
-}
-
-
-void osrfListIteratorReset( osrfListIterator* itr ) {
-       if(!itr) return;
-       itr->current = 0;
-}
-
-
-void osrfListVanillaFree( void* item ) {
-       free(item);
-}
-
-void osrfListSetDefaultFree( osrfList* list ) {
-       if(!list) return;
-       list->freeItem = osrfListVanillaFree;
-}
diff --git a/src/libstack/osrf_list.h b/src/libstack/osrf_list.h
deleted file mode 100644 (file)
index d829ab7..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-#ifndef OSRF_LIST_H
-#define OSRF_LIST_H
-
-#include "opensrf/utils.h"
-
-#define OSRF_LIST_DEFAULT_SIZE 48 /* most opensrf lists are small... */
-#define OSRF_LIST_INC_SIZE 256
-#define OSRF_LIST_MAX_SIZE 10240
-
-
-#define OSRF_LIST_GET_INDEX(l, i) (!l || i >= l->size) ? NULL: l->arrlist[i]
-
-/**
-  Items are stored as void*'s so it's up to the user to
-  manage the data wisely.  Also, if the 'freeItem' callback is defined for the list,
-  then, it will be used on any item that needs to be freed, so don't mix data
-  types in the list if you want magic freeing */
-
-struct __osrfListStruct {
-       unsigned int size;                      /* how many items in the list including NULL items between non-NULL items */    
-       void (*freeItem) (void* item);  /* callback for freeing stored items */
-       void** arrlist;
-       int arrsize; /* how big is the currently allocated array */
-};
-typedef struct __osrfListStruct osrfList;
-
-
-struct __osrfListIteratorStruct {
-       const osrfList* list;
-       unsigned int current;
-};
-typedef struct __osrfListIteratorStruct osrfListIterator;
-
-osrfList* osrfNewListSize( unsigned int size );
-
-
-/**
-  Creates a new list iterator with the given list
-  */
-osrfListIterator* osrfNewListIterator( const osrfList* list );
-
-/**
-  Returns the next non-NULL item in the list, return NULL when
-  the end of the list has been reached
-  */
-void* osrfListIteratorNext( osrfListIterator* itr );
-
-/**
-  Deallocates the given list
-  */
-void osrfListIteratorFree( osrfListIterator* itr );
-
-void osrfListIteratorReset( osrfListIterator* itr );
-
-
-/**
-  Allocates a new list
-  @param compress If true, the list will compress empty slots on delete.  If item positionality
-  is not important, then using this feature is reccomended to keep the list from growing indefinitely.
-  if item positionality is not important.
-  @return The allocated list
-  */
-osrfList* osrfNewList();
-
-/**
-  Pushes an item onto the end of the list.  This always finds the highest index
-  in the list and pushes the new item into the list after it.
-  @param list The list
-  @param item The item to push
-  @return 0 on success, -1 on failure
-  */
-int osrfListPush( osrfList* list, void* item );
-
-
-/**
- * Removes the last item in the list
- * See osrfListRemove for details on how the removed item is handled
- * @return The item, unless 'freeItem' exists, then returns NULL
- */
-void* osrfListPop( osrfList* list );
-
-/**
-  Puts the given item into the list at the specified position.  If there
-  is already an item at the given position and the list has it's 
-  "freeItem" function defined, then it will be used to free said item.
-  If no 'freeItem' callback is defined, then the displaced item will
-  be returned;
-  @param list The list
-  @param item The item to put into the list
-  @param position The position to place the item in
-  @return NULL in successfully inserting the new item and freeing
-  any displaced items.  Returns the displaced item if no "freeItem"
-  callback is defined.
-       */
-void* osrfListSet( osrfList* list, void* item, unsigned int position );
-
-/**
-  Returns the item at the given position
-  @param list The list
-  @param postiont the position
-  */
-void* osrfListGetIndex( const osrfList* list, unsigned int  position );
-
-/**
-  Frees the list and all list items (if the list has a "freeItem" function defined )
-  @param list The list
-  */
-void osrfListFree( osrfList* list );
-
-/**
-  Removes the list item at the given index
-  @param list The list
-  @param position The position of the item to remove
-  @return A pointer to the item removed if "freeItem" is not defined
-  for this list, returns NULL if it is.
-  */
-void* osrfListRemove( osrfList* list, unsigned int position );
-
-/**
-  Finds the list item whose void* is the same as the one passed in
-  @param list The list
-  @param addr The pointer connected to the list item we're to find
-  @return the index of the item, or -1 if the item was not found
-  */
-int osrfListFind( const osrfList* list, void* addr );
-
-
-void __osrfListSetSize( osrfList* list );
-
-
-/**
-  @return The number of non-null items in the list
-  */
-unsigned int osrfListGetCount( const osrfList* list );
-
-/**
- * May be used as a default memory freeing call
- * Just calls free() on list items
- */
-void osrfListVanillaFree( void* item );
-
-/**
- * Tells the list to just call 'free()' on each item when
- * an item or the whole list is destroyed
- */
-void osrfListSetDefaultFree( osrfList* list );
-
-/**
- * Inserts the new item at the first free (null) slot
- * in the array.  Item is shoved onto the end of the
- * list if there are no null slots */
-int osrfListPushFirst( osrfList* list, void* item );
-
-
-#endif
diff --git a/src/libstack/osrf_message.c b/src/libstack/osrf_message.c
deleted file mode 100644 (file)
index beb52d0..0000000
+++ /dev/null
@@ -1,330 +0,0 @@
-#include "osrf_message.h"
-
-osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol ) {
-
-       osrf_message* msg                       = (osrf_message*) safe_malloc(sizeof(osrf_message));
-       msg->m_type                                     = type;
-       msg->thread_trace                       = thread_trace;
-       msg->protocol                           = protocol;
-       msg->next                                       = NULL;
-       msg->is_exception                       = 0;
-       msg->_params                            = NULL;
-       msg->_result_content            = NULL;
-
-       return msg;
-}
-
-
-void osrf_message_set_method( osrf_message* msg, char* method_name ) {
-       if( msg == NULL || method_name == NULL ) return;
-       msg->method_name = strdup( method_name );
-}
-
-
-void osrf_message_add_object_param( osrf_message* msg, jsonObject* o ) {
-       if(!msg|| !o) return;
-       if(!msg->_params)
-               msg->_params = jsonParseString("[]");
-       char* j = jsonObjectToJSON(o);
-       jsonObjectPush(msg->_params, jsonParseString(j));
-       free(j);
-}
-
-void osrf_message_set_params( osrf_message* msg, jsonObject* o ) {
-       if(!msg || !o) return;
-
-       if(o->type != JSON_ARRAY) {
-               osrfLogDebug( OSRF_LOG_MARK, "passing non-array to osrf_message_set_params(), fixing...");
-               jsonObject* clone = jsonObjectClone(o);
-               o = jsonNewObject(NULL);
-               jsonObjectPush(o, clone);
-               if(msg->_params) jsonObjectFree(msg->_params);
-               msg->_params = o;
-               return;
-       }
-
-       if(msg->_params) jsonObjectFree(msg->_params);
-       msg->_params = jsonObjectClone(o);
-}
-
-
-/* only works if parse_json_params is false */
-void osrf_message_add_param( osrf_message* msg, char* param_string ) {
-       if(msg == NULL || param_string == NULL) return;
-       if(!msg->_params) msg->_params = jsonParseString("[]");
-       jsonObjectPush(msg->_params, jsonParseString(param_string));
-}
-
-
-void osrf_message_set_status_info( 
-               osrf_message* msg, char* status_name, char* status_text, int status_code ) {
-       if(!msg) return;
-
-       if( status_name != NULL ) 
-               msg->status_name = strdup( status_name );
-
-       if( status_text != NULL )
-               msg->status_text = strdup( status_text );
-
-       msg->status_code = status_code;
-}
-
-
-void osrf_message_set_result_content( osrf_message* msg, char* json_string ) {
-       if( msg == NULL || json_string == NULL) return;
-       msg->result_string =    strdup(json_string);
-       if(json_string) msg->_result_content = jsonParseString(json_string);
-}
-
-
-
-void osrfMessageFree( osrfMessage* msg ) {
-       osrf_message_free( msg );
-}
-
-void osrf_message_free( osrf_message* msg ) {
-       if( msg == NULL )
-               return;
-
-       if( msg->status_name != NULL )
-               free(msg->status_name);
-
-       if( msg->status_text != NULL )
-               free(msg->status_text);
-
-       if( msg->_result_content != NULL )
-               jsonObjectFree( msg->_result_content );
-
-       if( msg->result_string != NULL )
-               free( msg->result_string);
-
-       if( msg->method_name != NULL )
-               free(msg->method_name);
-
-       if( msg->_params != NULL )
-               jsonObjectFree(msg->_params);
-
-       free(msg);
-}
-
-
-char* osrfMessageSerializeBatch( osrfMessage* msgs [], int count ) {
-       if( !msgs ) return NULL;
-
-       char* j;
-       int i = 0;
-       osrfMessage* msg = NULL;
-       jsonObject* wrapper = jsonNewObject(NULL);
-
-       while( ((msg = msgs[i]) && (i++ < count)) ) 
-               jsonObjectPush(wrapper, osrfMessageToJSON( msg ));
-
-       j = jsonObjectToJSON(wrapper);
-       jsonObjectFree(wrapper);
-
-       return j;       
-}
-
-
-char* osrf_message_serialize(osrf_message* msg) {
-
-       if( msg == NULL ) return NULL;
-       char* j = NULL;
-
-       jsonObject* json = osrfMessageToJSON( msg );
-
-       if(json) {
-               jsonObject* wrapper = jsonNewObject(NULL);
-               jsonObjectPush(wrapper, json);
-               j = jsonObjectToJSON(wrapper);
-               jsonObjectFree(wrapper);
-       }
-
-       return j;
-}
-
-
-jsonObject* osrfMessageToJSON( osrfMessage* msg ) {
-
-       jsonObject* json = jsonNewObject(NULL);
-       jsonObjectSetClass(json, "osrfMessage");
-       jsonObject* payload;
-       char sc[64]; memset(sc,0,64);
-
-       char* str;
-
-       INT_TO_STRING(msg->thread_trace);
-       jsonObjectSetKey(json, "threadTrace", jsonNewObject(INTSTR));
-
-       switch(msg->m_type) {
-               
-               case CONNECT: 
-                       jsonObjectSetKey(json, "type", jsonNewObject("CONNECT"));
-                       break;
-
-               case DISCONNECT: 
-                       jsonObjectSetKey(json, "type", jsonNewObject("DISCONNECT"));
-                       break;
-
-               case STATUS:
-                       jsonObjectSetKey(json, "type", jsonNewObject("STATUS"));
-                       payload = jsonNewObject(NULL);
-                       jsonObjectSetClass(payload, msg->status_name);
-                       jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
-         sprintf(sc,"%d",msg->status_code);
-                       jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
-                       jsonObjectSetKey(json, "payload", payload);
-                       break;
-
-               case REQUEST:
-                       jsonObjectSetKey(json, "type", jsonNewObject("REQUEST"));
-                       payload = jsonNewObject(NULL);
-                       jsonObjectSetClass(payload, "osrfMethod");
-                       jsonObjectSetKey(payload, "method", jsonNewObject(msg->method_name));
-                       str = jsonObjectToJSON(msg->_params);
-                       jsonObjectSetKey(payload, "params", jsonParseString(str));
-                       free(str);
-                       jsonObjectSetKey(json, "payload", payload);
-
-                       break;
-
-               case RESULT:
-                       jsonObjectSetKey(json, "type", jsonNewObject("RESULT"));
-                       payload = jsonNewObject(NULL);
-                       jsonObjectSetClass(payload,"osrfResult");
-                       jsonObjectSetKey(payload, "status", jsonNewObject(msg->status_text));
-         sprintf(sc,"%d",msg->status_code);
-                       jsonObjectSetKey(payload, "statusCode", jsonNewObject(sc));
-                       str = jsonObjectToJSON(msg->_result_content);
-                       jsonObjectSetKey(payload, "content", jsonParseString(str));
-                       free(str);
-                       jsonObjectSetKey(json, "payload", payload);
-                       break;
-       }
-
-       return json;
-}
-
-
-int osrf_message_deserialize(char* string, osrf_message* msgs[], int count) {
-
-       if(!string || !msgs || count <= 0) return 0;
-       int numparsed = 0;
-
-       jsonObject* json = jsonParseString(string);
-
-       if(!json) {
-               osrfLogWarning( OSRF_LOG_MARK, 
-                       "osrf_message_deserialize() unable to parse data: \n%s\n", string);
-               return 0;
-       }
-
-       int x;
-
-       for( x = 0; x < json->size && x < count; x++ ) {
-
-               jsonObject* message = jsonObjectGetIndex(json, x);
-
-               if(message && message->type != JSON_NULL && 
-                       message->classname && !strcmp(message->classname, "osrfMessage")) {
-
-                       osrf_message* new_msg = safe_malloc(sizeof(osrf_message));
-
-                       jsonObject* tmp = jsonObjectGetKey(message, "type");
-
-                       char* t;
-                       if( ( t = jsonObjectGetString(tmp)) ) {
-
-                               if(!strcmp(t, "CONNECT"))               new_msg->m_type = CONNECT;
-                               if(!strcmp(t, "DISCONNECT"))    new_msg->m_type = DISCONNECT;
-                               if(!strcmp(t, "STATUS"))                new_msg->m_type = STATUS;
-                               if(!strcmp(t, "REQUEST"))               new_msg->m_type = REQUEST;
-                               if(!strcmp(t, "RESULT"))                new_msg->m_type = RESULT;
-                       }
-
-                       tmp = jsonObjectGetKey(message, "threadTrace");
-                       if(tmp) {
-                               char* tt = jsonObjectToSimpleString(tmp);
-                               if(tt) {
-                                       new_msg->thread_trace = atoi(tt);
-                                       free(tt);
-                               }
-                               /*
-                               if(tmp->type == JSON_NUMBER)
-                                       new_msg->thread_trace = (int) jsonObjectGetNumber(tmp);
-                               if(tmp->type == JSON_STRING)
-                                       new_msg->thread_trace = atoi(jsonObjectGetString(tmp));
-                                       */
-                       }
-
-
-                       tmp = jsonObjectGetKey(message, "protocol");
-
-                       if(tmp) {
-                               char* proto = jsonObjectToSimpleString(tmp);
-                               if(proto) {
-                                       new_msg->protocol = atoi(proto);
-                                       free(proto);
-                               }
-
-                               /*
-                               if(tmp->type == JSON_NUMBER)
-                                       new_msg->protocol = (int) jsonObjectGetNumber(tmp);
-                               if(tmp->type == JSON_STRING)
-                                       new_msg->protocol = atoi(jsonObjectGetString(tmp));
-                                       */
-                       }
-
-                       tmp = jsonObjectGetKey(message, "payload");
-                       if(tmp) {
-                               if(tmp->classname)
-                                       new_msg->status_name = strdup(tmp->classname);
-
-                               jsonObject* tmp0 = jsonObjectGetKey(tmp,"method");
-                               if(jsonObjectGetString(tmp0))
-                                       new_msg->method_name = strdup(jsonObjectGetString(tmp0));
-
-                               tmp0 = jsonObjectGetKey(tmp,"params");
-                               if(tmp0) {
-                                       char* s = jsonObjectToJSON(tmp0);
-                                       new_msg->_params = jsonParseString(s);
-                                       if(new_msg->_params && new_msg->_params->type == JSON_NULL) 
-                                               new_msg->_params->type = JSON_ARRAY;
-                                       free(s);
-                               }
-
-                               tmp0 = jsonObjectGetKey(tmp,"status");
-                               if(jsonObjectGetString(tmp0))
-                                       new_msg->status_text = strdup(jsonObjectGetString(tmp0));
-
-                               tmp0 = jsonObjectGetKey(tmp,"statusCode");
-                               if(tmp0) {
-                                       if(jsonObjectGetString(tmp0))
-                                               new_msg->status_code = atoi(jsonObjectGetString(tmp0));
-                                       if(tmp0->type == JSON_NUMBER)
-                                               new_msg->status_code = (int) jsonObjectGetNumber(tmp0);
-                               }
-
-                               tmp0 = jsonObjectGetKey(tmp,"content");
-                               if(tmp0) {
-                                       char* s = jsonObjectToJSON(tmp0);
-                                       new_msg->_result_content = jsonParseString(s);
-                                       free(s);
-                               }
-
-                       }
-                       msgs[numparsed++] = new_msg;
-               }
-       }
-
-       jsonObjectFree(json);
-       return numparsed;
-}
-
-
-
-jsonObject* osrfMessageGetResult( osrfMessage* msg ) {
-       if(msg) return msg->_result_content;
-       return NULL;
-}
-
diff --git a/src/libstack/osrf_message.h b/src/libstack/osrf_message.h
deleted file mode 100644 (file)
index b87a97e..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "opensrf/string_array.h"
-#include "opensrf/utils.h"
-#include "opensrf/log.h"
-#include "objson/object.h"
-#include "objson/json_parser.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>
-
-
-
-#ifndef osrf_message_h
-#define osrf_message_h
-
-#define OSRF_XML_NAMESPACE "http://open-ils.org/xml/namespaces/oils_v1"
-
-#define OSRF_STATUS_CONTINUE                                           100
-
-#define OSRF_STATUS_OK                                                         200
-#define OSRF_STATUS_ACCEPTED                                           202
-#define OSRF_STATUS_COMPLETE                                           205
-
-#define OSRF_STATUS_REDIRECTED                                 307
-
-#define OSRF_STATUS_BADREQUEST                                 400
-#define OSRF_STATUS_UNAUTHORIZED                                       401
-#define OSRF_STATUS_FORBIDDEN                                          403
-#define OSRF_STATUS_NOTFOUND                                           404
-#define OSRF_STATUS_NOTALLOWED                                 405
-#define OSRF_STATUS_TIMEOUT                                            408
-#define OSRF_STATUS_EXPFAILED                                          417
-
-#define OSRF_STATUS_INTERNALSERVERERROR                500
-#define OSRF_STATUS_NOTIMPLEMENTED                             501
-#define OSRF_STATUS_VERSIONNOTSUPPORTED                505
-
-
-enum M_TYPE { CONNECT, REQUEST, RESULT, STATUS, DISCONNECT };
-
-#define OSRF_MAX_PARAMS                                                                128;
-
-struct osrf_message_struct {
-
-       enum M_TYPE m_type;
-       int thread_trace;
-       int protocol;
-
-       /* if we're a STATUS message */
-       char* status_name;
-
-       /* if we're a STATUS or RESULT */
-       char* status_text;
-       int status_code;
-
-       int is_exception;
-
-       /* if we're a RESULT */
-       jsonObject* _result_content;
-
-       /* unparsed json string */
-       char* result_string;
-
-       /* if we're a REQUEST */
-       char* method_name;
-
-       jsonObject* _params;
-
-       /* in case anyone wants to make a list of us.  
-               we won't touch this variable */
-       struct osrf_message_struct* next;
-
-       char* full_param_string;
-
-};
-typedef struct osrf_message_struct osrf_message;
-typedef struct osrf_message_struct osrfMessage;
-
-
-osrf_message* osrf_message_init( enum M_TYPE type, int thread_trace, int protocol );
-//void osrf_message_set_request_info( osrf_message*, char* param_name, json* params );
-void osrf_message_set_status_info( osrf_message*, char* status_name, char* status_text, int status_code );
-void osrf_message_set_result_content( osrf_message*, char* json_string );
-void osrfMessageFree( osrfMessage* );
-void osrf_message_free( osrf_message* );
-char* osrf_message_to_xml( osrf_message* );
-char* osrf_message_serialize(osrf_message*);
-
-/* count is the max number of messages we'll put into msgs[] */
-int osrf_message_deserialize(char* json, osrf_message* msgs[], int count);
-
-
-
-/** Pushes any message retreived from the xml into the 'msgs' array.
-  * it is assumed that 'msgs' has beenn pre-allocated.
-  * Returns the number of message that are in the buffer.
-  */
-int osrf_message_from_xml( char* xml, osrf_message* msgs[] );
-
-void osrf_message_set_params( osrf_message* msg, jsonObject* o );
-void osrf_message_set_method( osrf_message* msg, char* method_name );
-void osrf_message_add_object_param( osrf_message* msg, jsonObject* o );
-void osrf_message_add_param( osrf_message*, char* param_string );
-
-
-jsonObject* osrfMessageGetResult( osrfMessage* msg );
-
-/**
-  Returns the message as a jsonObject
-  @return The jsonObject which must be freed by the caller.
-  */
-jsonObject* osrfMessageToJSON( osrfMessage* msg );
-
-char* osrfMessageSerializeBatch( osrfMessage* msgs [], int count );
-
-
-#endif
diff --git a/src/libstack/osrf_prefork.c b/src/libstack/osrf_prefork.c
deleted file mode 100644 (file)
index 1ea5959..0000000
+++ /dev/null
@@ -1,765 +0,0 @@
-#include "osrf_prefork.h"
-#include <signal.h>
-#include "osrf_app_session.h"
-#include "osrf_application.h"
-
-/* true if we just deleted a child.  This will allow us to make sure we're
-       not trying to use freed memory */
-int child_dead;
-
-int main();
-void sigchld_handler( int sig );
-
-int osrf_prefork_run(char* appname) {
-
-       if(!appname) {
-               osrfLogError( OSRF_LOG_MARK, "osrf_prefork_run requires an appname to run!");
-               return -1;
-       }
-
-       set_proc_title( "OpenSRF Listener [%s]", appname );
-
-       int maxr = 1000; 
-       int maxc = 10;
-       int minc = 3;
-
-       osrfLogInfo( OSRF_LOG_MARK, "Loading config in osrf_forker for app %s", appname);
-
-       jsonObject* max_req = osrf_settings_host_value_object("/apps/%s/unix_config/max_requests", appname);
-       jsonObject* min_children = osrf_settings_host_value_object("/apps/%s/unix_config/min_children", appname);
-       jsonObject* max_children = osrf_settings_host_value_object("/apps/%s/unix_config/max_children", appname);
-
-       char* keepalive = osrf_settings_host_value("/apps/%s/keepalive", appname);
-       time_t kalive;
-       if( keepalive ) {
-               kalive = atoi(keepalive);
-               free(keepalive);
-       } else {
-               kalive = 5; /* give it a default */
-       }
-
-       osrfLogInfo(OSRF_LOG_MARK, "keepalive setting = %d seconds", kalive);
-
-
-       
-       if(!max_req) osrfLogWarning( OSRF_LOG_MARK, "Max requests not defined, assuming 1000");
-       else maxr = (int) jsonObjectGetNumber(max_req);
-
-       if(!min_children) osrfLogWarning( OSRF_LOG_MARK, "Min children not defined, assuming 3");
-       else minc = (int) jsonObjectGetNumber(min_children);
-
-       if(!max_children) osrfLogWarning( OSRF_LOG_MARK, "Max children not defined, assuming 10");
-       else maxc = (int) jsonObjectGetNumber(max_children);
-
-       jsonObjectFree(max_req);
-       jsonObjectFree(min_children);
-       jsonObjectFree(max_children);
-       /* --------------------------------------------------- */
-
-       char* resc = va_list_to_string("%s_listener", appname);
-
-       if(!osrf_system_bootstrap_client_resc( NULL, NULL, resc )) {
-               osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()");
-               free(resc);
-               return -1;
-       }
-
-       free(resc);
-
-       prefork_simple* forker = prefork_simple_init(
-               osrfSystemGetTransportClient(), maxr, minc, maxc);
-
-       forker->appname = strdup(appname);
-       forker->keepalive       = kalive;
-
-       if(forker == NULL) {
-               osrfLogError( OSRF_LOG_MARK, "osrf_prefork_run() failed to create prefork_simple object");
-               return -1;
-       }
-
-       prefork_launch_children(forker);
-
-       osrf_prefork_register_routers(appname);
-       
-       osrfLogInfo( OSRF_LOG_MARK, "Launching osrf_forker for app %s", appname);
-       prefork_run(forker);
-       
-       osrfLogWarning( OSRF_LOG_MARK, "prefork_run() retuned - how??");
-       prefork_free(forker);
-       return 0;
-
-}
-
-void osrf_prefork_register_routers( char* appname ) {
-
-       osrfStringArray* arr = osrfNewStringArray(4);
-
-       int c = osrfConfigGetValueList( NULL, arr, "/routers/router" );
-       char* routerName = osrfConfigGetValue( NULL, "/router_name" );
-       transport_client* client = osrfSystemGetTransportClient();
-
-       osrfLogInfo( OSRF_LOG_MARK, "router name is %s and we have %d routers to connect to", routerName, c );
-
-       while( c ) {
-               char* domain = osrfStringArrayGetString(arr, --c);
-               if(domain) {
-
-                       char* jid = va_list_to_string( "%s@%s/router", routerName, domain );
-                       osrfLogInfo( OSRF_LOG_MARK, "Registering with router %s", jid );
-
-                       transport_message* msg = message_init("registering", NULL, NULL, jid, NULL );
-                       message_set_router_info( msg, NULL, NULL, appname, "register", 0 );
-
-                       client_send_message( client, msg );
-                       message_free( msg );
-                       free(jid);
-               }
-       }
-
-       free(routerName);
-       osrfStringArrayFree(arr);
-}
-
-int prefork_child_init_hook(prefork_child* child) {
-
-       if(!child) return -1;
-       osrfLogDebug( OSRF_LOG_MARK, "Child init hook for child %d", child->pid);
-       char* resc = va_list_to_string("%s_drone",child->appname);
-
-   /* if we're a source-client, tell the logger now that we're a new process*/
-   char* isclient = osrfConfigGetValue(NULL, "/client");
-   if( isclient && !strcasecmp(isclient,"true") )
-      osrfLogSetIsClient(1);
-   free(isclient);
-
-
-       /* we want to remove traces of our parents socket connection 
-        * so we can have our own */
-       osrfSystemIgnoreTransportClient();
-
-       if(!osrf_system_bootstrap_client_resc( NULL, NULL, resc)) {
-               osrfLogError( OSRF_LOG_MARK, "Unable to bootstrap client for osrf_prefork_run()");
-               free(resc);
-               return -1;
-       }
-
-       free(resc);
-
-       if( ! osrfAppRunChildInit(child->appname) ) {
-               osrfLogDebug(OSRF_LOG_MARK, "Prefork child_init succeeded\n");
-       } else {
-               osrfLogError(OSRF_LOG_MARK, "Prefork child_init failed\n");
-               return -1;
-       }
-
-       set_proc_title( "OpenSRF Drone [%s]", child->appname );
-       return 0;
-}
-
-void prefork_child_process_request(prefork_child* child, char* data) {
-       if( !child ) return;
-
-       transport_client* client = osrfSystemGetTransportClient();
-
-       if(!client_connected(client)) {
-               osrfSystemIgnoreTransportClient();
-               osrfLogWarning(OSRF_LOG_MARK, "Reconnecting child to opensrf after disconnect...");
-               if(!osrf_system_bootstrap_client(NULL, NULL)) {
-                       osrfLogError( OSRF_LOG_MARK, 
-                               "Unable to bootstrap client in prefork_child_process_request()");
-                       sleep(1);
-         osrf_prefork_child_exit(child);
-               }
-       }
-
-       /* construct the message from the xml */
-       transport_message* msg = new_message_from_xml( data );
-
-       osrfAppSession* session = osrf_stack_transport_handler(msg, child->appname);
-       if(!session) return;
-
-       if( session->stateless && session->state != OSRF_SESSION_CONNECTED ) {
-               osrfAppSessionFree( session );
-               return;
-       }
-
-       osrfLogDebug( OSRF_LOG_MARK, "Entering keepalive loop for session %s", session->session_id );
-       int keepalive = child->keepalive;
-       int retval;
-       int recvd;
-       time_t start;
-       time_t end;
-
-       while(1) {
-
-               osrfLogDebug(OSRF_LOG_MARK, 
-                               "osrf_prefork calling queue_wait [%d] in keepalive loop", keepalive);
-               start           = time(NULL);
-               retval  = osrf_app_session_queue_wait(session, keepalive, &recvd);
-               end             = time(NULL);
-
-               osrfLogDebug(OSRF_LOG_MARK, "Data received == %d", recvd);
-
-               if(retval) {
-                       osrfLogError(OSRF_LOG_MARK, "queue-wait returned non-success %d", retval);
-                       break;
-               }
-
-               /* see if the client disconnected from us */
-               if(session->state != OSRF_SESSION_CONNECTED) break;
-
-               /* if no data was reveived within the timeout interval */
-               if( !recvd && (end - start) >= keepalive ) {
-                       osrfLogInfo(OSRF_LOG_MARK, "No request was reveived in %d seconds, exiting stateful session", keepalive);
-                       osrfAppSessionStatus( 
-                                       session, 
-                                       OSRF_STATUS_TIMEOUT, 
-                                       "osrfConnectStatus", 
-                                       0, "Disconnected on timeout" );
-
-                       break;
-               }
-       }
-
-       osrfLogDebug( OSRF_LOG_MARK, "Exiting keepalive loop for session %s", session->session_id );
-       osrfAppSessionFree( session );
-       return;
-}
-
-
-prefork_simple*  prefork_simple_init( transport_client* client, 
-               int max_requests, int min_children, int max_children ) {
-
-       if( min_children > max_children ) {
-               osrfLogError( OSRF_LOG_MARK,  "min_children (%d) is greater "
-                               "than max_children (%d)", min_children, max_children );
-               return NULL;
-       }
-
-       if( max_children > ABS_MAX_CHILDREN ) {
-               osrfLogError( OSRF_LOG_MARK,  "max_children (%d) is greater than ABS_MAX_CHILDREN (%d)",
-                               max_children, ABS_MAX_CHILDREN );
-               return NULL;
-       }
-
-       osrfLogInfo(OSRF_LOG_MARK, "Prefork launching child with max_request=%d,"
-               "min_children=%d, max_children=%d", max_requests, min_children, max_children );
-
-       /* flesh out the struct */
-       prefork_simple* prefork = (prefork_simple*) safe_malloc(sizeof(prefork_simple));        
-       prefork->max_requests = max_requests;
-       prefork->min_children = min_children;
-       prefork->max_children = max_children;
-       prefork->first_child = NULL;
-       prefork->connection = client;
-
-       return prefork;
-}
-
-prefork_child*  launch_child( prefork_simple* forker ) {
-
-       pid_t pid;
-       int data_fd[2];
-       int status_fd[2];
-
-       /* Set up the data pipes and add the child struct to the parent */
-       if( pipe(data_fd) < 0 ) { /* build the data pipe*/
-               osrfLogError( OSRF_LOG_MARK,  "Pipe making error" );
-               return NULL;
-       }
-
-       if( pipe(status_fd) < 0 ) {/* build the status pipe */
-               osrfLogError( OSRF_LOG_MARK,  "Pipe making error" );
-               return NULL;
-       }
-
-       osrfLogInternal( OSRF_LOG_MARK,  "Pipes: %d %d %d %d", data_fd[0], data_fd[1], status_fd[0], status_fd[1] );
-       prefork_child* child = prefork_child_init( forker->max_requests, data_fd[0], 
-                       data_fd[1], status_fd[0], status_fd[1] );
-
-       child->appname = strdup(forker->appname);
-       child->keepalive = forker->keepalive;
-
-
-       add_prefork_child( forker, child );
-
-       if( (pid=fork()) < 0 ) {
-               osrfLogError( OSRF_LOG_MARK,  "Forking Error" );
-               return NULL;
-       }
-
-       if( pid > 0 ) {  /* parent */
-
-               signal(SIGCHLD, sigchld_handler);
-               (forker->current_num_children)++;
-               child->pid = pid;
-
-               osrfLogDebug( OSRF_LOG_MARK,  "Parent launched %d", pid );
-               /* *no* child pipe FD's can be closed or the parent will re-use fd's that
-                       the children are currently using */
-               return child;
-       }
-
-       else { /* child */
-
-               osrfLogInternal( OSRF_LOG_MARK, "I am  new child with read_data_fd = %d and write_status_fd = %d",
-                       child->read_data_fd, child->write_status_fd );
-
-               child->pid = getpid();
-               close( child->write_data_fd );
-               close( child->read_status_fd );
-
-               /* do the initing */
-               if( prefork_child_init_hook(child) == -1 ) {
-                       osrfLogError(OSRF_LOG_MARK, 
-                               "Forker child going away because we could not connect to OpenSRF...");
-         osrf_prefork_child_exit(child);
-               }
-
-               prefork_child_wait( child );
-      osrf_prefork_child_exit(child); /* just to be sure */
-        }
-       return NULL;
-}
-
-void osrf_prefork_child_exit(prefork_child* child) {
-   osrfAppRunExitCode();
-   exit(0);
-}
-
-void prefork_launch_children( prefork_simple* forker ) {
-       if(!forker) return;
-       int c = 0;
-       while( c++ < forker->min_children )
-               launch_child( forker );
-}
-
-
-void sigchld_handler( int sig ) {
-       signal(SIGCHLD, sigchld_handler);
-       child_dead = 1;
-}
-
-
-void reap_children( prefork_simple* forker ) {
-
-       pid_t child_pid;
-       int status;
-
-       while( (child_pid=waitpid(-1,&status,WNOHANG)) > 0) 
-               del_prefork_child( forker, child_pid ); 
-
-       /* replenish */
-       while( forker->current_num_children < forker->min_children ) 
-               launch_child( forker );
-
-       child_dead = 0;
-}
-
-void prefork_run(prefork_simple* forker) {
-
-       if( forker->first_child == NULL )
-               return;
-
-       transport_message* cur_msg = NULL;
-
-
-       while(1) {
-
-               if( forker->first_child == NULL ) {/* no more children */
-                       osrfLogWarning( OSRF_LOG_MARK, "No more children..." );
-                       return;
-               }
-
-               osrfLogDebug( OSRF_LOG_MARK, "Forker going into wait for data...");
-               cur_msg = client_recv( forker->connection, -1 );
-
-               //fprintf(stderr, "Got Data %f\n", get_timestamp_millis() );
-
-               if( cur_msg == NULL ) continue;
-
-               int honored = 0;        /* true if we've serviced the request */
-               int no_recheck = 0;
-
-               while( ! honored ) {
-
-                       if(!no_recheck) check_children( forker, 0 ); 
-                       no_recheck = 0;
-
-                       osrfLogDebug( OSRF_LOG_MARK,  "Server received inbound data" );
-                       int k;
-                       prefork_child* cur_child = forker->first_child;
-
-                       /* Look for an available child */
-                       for( k = 0; k < forker->current_num_children; k++ ) {
-
-                               osrfLogInternal( OSRF_LOG_MARK, "Searching for available child. cur_child->pid = %d", cur_child->pid );
-                               osrfLogInternal( OSRF_LOG_MARK, "Current num children %d and loop %d", forker->current_num_children, k);
-                       
-                               if( cur_child->available ) {
-                                       osrfLogDebug( OSRF_LOG_MARK,  "forker sending data to %d", cur_child->pid );
-
-                                       message_prepare_xml( cur_msg );
-                                       char* data = cur_msg->msg_xml;
-                                       if( ! data || strlen(data) < 1 ) break;
-
-                                       cur_child->available = 0;
-                                       osrfLogInternal( OSRF_LOG_MARK,  "Writing to child fd %d", cur_child->write_data_fd );
-
-                                       int written = 0;
-                                       //fprintf(stderr, "Writing Data %f\n", get_timestamp_millis() );
-                                       if( (written = write( cur_child->write_data_fd, data, strlen(data) + 1 )) < 0 ) {
-                                               osrfLogWarning( OSRF_LOG_MARK, "Write returned error %d", errno);
-                                               cur_child = cur_child->next;
-                                               continue;
-                                       }
-
-                                       //fprintf(stderr, "Wrote %d bytes to child\n", written);
-
-                                       forker->first_child = cur_child->next;
-                                       honored = 1;
-                                       break;
-                               } else 
-                                       cur_child = cur_child->next;
-                       } 
-
-                       /* if none available, add a new child if we can */
-                       if( ! honored ) {
-                               osrfLogDebug( OSRF_LOG_MARK, "Not enough children, attempting to add...");
-
-                               if( forker->current_num_children < forker->max_children ) {
-                                       osrfLogDebug( OSRF_LOG_MARK,  "Launching new child with current_num = %d",
-                                                       forker->current_num_children );
-
-                                       prefork_child* new_child = launch_child( forker );
-                    if( new_child ) {
-
-                                           message_prepare_xml( cur_msg );
-                                           char* data = cur_msg->msg_xml;
-
-                        if( data ) {
-                            int len = strlen(data);
-
-                            if( len > 0 ) {
-                                                   new_child->available = 0;
-                                                   osrfLogDebug( OSRF_LOG_MARK,  "Writing to new child fd %d : pid %d", 
-                                                               new_child->write_data_fd, new_child->pid );
-        
-                                                   if( write( new_child->write_data_fd, data, len + 1 ) >= 0 ) {
-                                                       forker->first_child = new_child->next;
-                                                       honored = 1;
-                                }
-                            }
-                        }
-                    }
-
-                               }
-                       }
-
-                       if( !honored ) {
-                               osrfLogWarning( OSRF_LOG_MARK,  "No children available, waiting...");
-
-                               check_children( forker, 1 );  /* non-poll version */
-                               /* tell the loop no to call check_children again, since we're calling it now */
-                               no_recheck = 1;
-                       }
-
-                       if( child_dead )
-                               reap_children(forker);
-
-
-                       //fprintf(stderr, "Parent done with request %f\n", get_timestamp_millis() );
-
-               } // honored?
-
-               message_free( cur_msg );
-
-       } /* top level listen loop */
-
-}
-
-
-/** XXX Add a flag which tells select() to wait forever on children
- * in the best case, this will be faster than calling usleep(x), and
- * in the worst case it won't be slower and will do less logging...
- */
-
-void check_children( prefork_simple* forker, int forever ) {
-
-       //check_begin:
-
-       int select_ret;
-       fd_set read_set;
-       FD_ZERO(&read_set);
-       int max_fd = 0;
-       int n;
-
-
-       if( child_dead )
-               reap_children(forker);
-
-       prefork_child* cur_child = forker->first_child;
-
-       int i;
-       for( i = 0; i!= forker->current_num_children; i++ ) {
-
-               if( cur_child->read_status_fd > max_fd )
-                       max_fd = cur_child->read_status_fd;
-               FD_SET( cur_child->read_status_fd, &read_set );
-               cur_child = cur_child->next;
-       }
-
-       FD_CLR(0,&read_set);/* just to be sure */
-
-       if( forever ) {
-               osrfLogWarning(OSRF_LOG_MARK, "We have no children available - waiting for one to show up...");
-
-               if( (select_ret=select( max_fd + 1 , &read_set, NULL, NULL, NULL)) == -1 ) {
-                       osrfLogWarning( OSRF_LOG_MARK,  "Select returned error %d on check_children", errno );
-               }
-               osrfLogInfo(OSRF_LOG_MARK, "select() completed after waiting on children to become available");
-
-       } else {
-
-               struct timeval tv;
-               tv.tv_sec       = 0;
-               tv.tv_usec      = 0;
-       
-               if( (select_ret=select( max_fd + 1 , &read_set, NULL, NULL, &tv)) == -1 ) {
-                       osrfLogWarning( OSRF_LOG_MARK,  "Select returned error %d on check_children", errno );
-               }
-       }
-
-       if( select_ret == 0 )
-               return;
-
-       /* see if one of a child has told us it's done */
-       cur_child = forker->first_child;
-       int j;
-       int num_handled = 0;
-       for( j = 0; j!= forker->current_num_children && num_handled < select_ret ; j++ ) {
-
-               if( FD_ISSET( cur_child->read_status_fd, &read_set ) ) {
-                       //printf( "Server received status from a child %d\n", cur_child->pid );
-                       osrfLogDebug( OSRF_LOG_MARK,  "Server received status from a child %d", cur_child->pid );
-
-                       num_handled++;
-
-                       /* now suck off the data */
-                       char buf[64];
-                       memset( buf, 0, 64);
-                       if( (n=read(cur_child->read_status_fd, buf, 63))  < 0 ) {
-                               osrfLogWarning( OSRF_LOG_MARK, "Read error afer select in child status read with errno %d", errno);
-                       }
-
-                       osrfLogDebug( OSRF_LOG_MARK,  "Read %d bytes from status buffer: %s", n, buf );
-                       cur_child->available = 1;
-               }
-               cur_child = cur_child->next;
-       } 
-
-}
-
-
-void prefork_child_wait( prefork_child* child ) {
-
-       int i,n;
-       growing_buffer* gbuf = buffer_init( READ_BUFSIZE );
-       char buf[READ_BUFSIZE];
-       memset( buf, 0, READ_BUFSIZE );
-
-       for( i = 0; i < child->max_requests; i++ ) {
-
-               n = -1;
-               int gotdata = 0;
-               clr_fl(child->read_data_fd, O_NONBLOCK );
-
-               while( (n=read(child->read_data_fd, buf, READ_BUFSIZE-1)) > 0 ) {
-                       osrfLogDebug(OSRF_LOG_MARK, "Prefork child read %d bytes of data", n);
-                       if(!gotdata)
-                               set_fl(child->read_data_fd, O_NONBLOCK );
-                       buffer_add( gbuf, buf );
-                       memset( buf, 0, READ_BUFSIZE );
-                       gotdata = 1;
-               }
-
-               if( errno == EAGAIN ) n = 0;
-
-      if( errno == EPIPE ) {
-         osrfLogDebug(OSRF_LOG_MARK, "C child attempted read on broken pipe, exiting...");
-         break;
-      }
-
-               if( n < 0 ) {
-                       osrfLogWarning( OSRF_LOG_MARK,  "Prefork child read returned error with errno %d", errno );
-                       break;
-
-               } else if( gotdata ) {
-                       osrfLogDebug(OSRF_LOG_MARK, "Prefork child got a request.. processing..");
-                       prefork_child_process_request(child, gbuf->buf);
-                       buffer_reset( gbuf );
-               }
-
-               if( i < child->max_requests - 1 ) 
-                       write( child->write_status_fd, "available" /*less than 64 bytes*/, 9 );
-       }
-
-       buffer_free(gbuf);
-
-       osrfLogDebug( OSRF_LOG_MARK, "Child with max-requests=%d, num-served=%d exiting...[%ld]", 
-                       child->max_requests, i, (long) getpid() );
-
-   osrf_prefork_child_exit(child); /* just to be sure */
-}
-
-
-void add_prefork_child( prefork_simple* forker, prefork_child* child ) {
-       
-       if( forker->first_child == NULL ) {
-               forker->first_child = child;
-               child->next = child;
-               return;
-       }
-
-       /* we put the child in as the last because, regardless, 
-               we have to do the DLL splice dance, and this is the
-          simplest way */
-
-       prefork_child* start_child = forker->first_child;
-       while(1) {
-               if( forker->first_child->next == start_child ) 
-                       break;
-               forker->first_child = forker->first_child->next;
-       }
-
-       /* here we know that forker->first_child is the last element 
-               in the list and start_child is the first.  Insert the
-               new child between them*/
-
-       forker->first_child->next = child;
-       child->next = start_child;
-       return;
-}
-
-prefork_child* find_prefork_child( prefork_simple* forker, pid_t pid ) {
-
-       if( forker->first_child == NULL ) { return NULL; }
-       prefork_child* start_child = forker->first_child;
-       do {
-               if( forker->first_child->pid == pid ) 
-                       return forker->first_child;
-       } while( (forker->first_child = forker->first_child->next) != start_child );
-
-       return NULL;
-}
-
-
-void del_prefork_child( prefork_simple* forker, pid_t pid ) { 
-
-       if( forker->first_child == NULL ) { return; }
-
-       (forker->current_num_children)--;
-       osrfLogDebug( OSRF_LOG_MARK, "Deleting Child: %d", pid );
-
-       prefork_child* start_child = forker->first_child; /* starting point */
-       prefork_child* cur_child        = start_child; /* current pointer */
-       prefork_child* prev_child       = start_child; /* the trailing pointer */
-
-       /* special case where there is only one in the list */
-       if( start_child == start_child->next ) {
-               if( start_child->pid == pid ) {
-                       forker->first_child = NULL;
-
-                       close( start_child->read_data_fd );
-                       close( start_child->write_data_fd );
-                       close( start_child->read_status_fd );
-                       close( start_child->write_status_fd );
-
-                       prefork_child_free( start_child );
-               }
-               return;
-       }
-
-
-       /* special case where the first item in the list needs to be removed */
-       if( start_child->pid == pid ) { 
-
-               /* find the last one so we can remove the start_child */
-               do { 
-                       prev_child = cur_child;
-                       cur_child = cur_child->next;
-               }while( cur_child != start_child );
-
-               /* now cur_child == start_child */
-               prev_child->next = cur_child->next;
-               forker->first_child = prev_child;
-
-               close( cur_child->read_data_fd );
-               close( cur_child->write_data_fd );
-               close( cur_child->read_status_fd );
-               close( cur_child->write_status_fd );
-
-               prefork_child_free( cur_child );
-               return;
-       } 
-
-       do {
-               prev_child = cur_child;
-               cur_child = cur_child->next;
-
-               if( cur_child->pid == pid ) {
-                       prev_child->next = cur_child->next;
-
-                       close( cur_child->read_data_fd );
-                       close( cur_child->write_data_fd );
-                       close( cur_child->read_status_fd );
-                       close( cur_child->write_status_fd );
-
-                       prefork_child_free( cur_child );
-                       return;
-               }
-
-       } while(cur_child != start_child);
-}
-
-
-
-
-prefork_child* prefork_child_init( 
-       int max_requests, int read_data_fd, int write_data_fd, 
-       int read_status_fd, int write_status_fd ) {
-
-       prefork_child* child = (prefork_child*) safe_malloc(sizeof(prefork_child));
-       child->max_requests             = max_requests;
-       child->read_data_fd             = read_data_fd;
-       child->write_data_fd            = write_data_fd;
-       child->read_status_fd   = read_status_fd;
-       child->write_status_fd  = write_status_fd;
-       child->available                        = 1;
-
-       return child;
-}
-
-
-int prefork_free( prefork_simple* prefork ) {
-       
-       while( prefork->first_child != NULL ) {
-               osrfLogInfo( OSRF_LOG_MARK,  "Killing children and sleeping 1 to reap..." );
-               kill( 0,        SIGKILL );
-               sleep(1);
-       }
-
-       client_free(prefork->connection);
-       free(prefork->appname);
-       free( prefork );
-       return 1;
-}
-
-int prefork_child_free( prefork_child* child ) { 
-       free(child->appname);
-       close(child->read_data_fd);
-       close(child->write_status_fd);
-       free( child ); 
-       return 1;
-}
-
diff --git a/src/libstack/osrf_prefork.h b/src/libstack/osrf_prefork.h
deleted file mode 100644 (file)
index 9515445..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-
-#include "opensrf/utils.h"
-#include "opensrf/transport_message.h"
-#include "opensrf/transport_client.h"
-#include "osrf_stack.h"
-#include "osrf_settings.h"
-#include "osrfConfig.h"
-
-//#define READ_BUFSIZE 4096
-#define READ_BUFSIZE 1024
-#define MAX_BUFSIZE 10485760 /* 10M enough? ;) */
-#define ABS_MAX_CHILDREN 256 
-
-/* we receive data.  we find the next child in
-       line that is available.  pass the data down that childs pipe and go
-       back to listening for more data.
-       when we receive SIGCHLD, we check for any dead children and clean up
-       their respective prefork_child objects, close pipes, etc.
-
-       we build a select fd_set with all the child pipes (going to the parent) 
-       when a child is done processing a request, it writes a small chunk of 
-       data to the parent to alert the parent that the child is again available 
-       */
-
-struct prefork_simple_struct {
-       int max_requests;
-       int min_children;
-       int max_children;
-       int fd;
-       int data_to_child;
-       int data_to_parent;
-       int current_num_children;
-       int keepalive; /* keepalive time for stateful sessions */
-       char* appname;
-       struct prefork_child_struct* first_child;
-       transport_client* connection;
-};
-typedef struct prefork_simple_struct prefork_simple;
-
-struct prefork_child_struct {
-       pid_t pid;
-       int read_data_fd;
-       int write_data_fd;
-       int read_status_fd;
-       int write_status_fd;
-       int min_children;
-       int available;
-       int max_requests;
-       char* appname;
-       int keepalive;
-       struct prefork_child_struct* next;
-};
-
-typedef struct prefork_child_struct prefork_child;
-
-int osrf_prefork_run(char* appname);
-
-prefork_simple*  prefork_simple_init( transport_client* client, 
-       int max_requests, int min_children, int max_children );
-
-prefork_child*  launch_child( prefork_simple* forker );
-void prefork_launch_children( prefork_simple* forker );
-
-void prefork_run(prefork_simple* forker);
-
-void add_prefork_child( prefork_simple* forker, prefork_child* child );
-prefork_child* find_prefork_child( prefork_simple* forker, pid_t pid );
-void del_prefork_child( prefork_simple* forker, pid_t pid );
-
-void check_children( prefork_simple* forker, int forever );
-
-void prefork_child_process_request(prefork_child*, char* data);
-int prefork_child_init_hook(prefork_child*);
-
-prefork_child* prefork_child_init( 
-               int max_requests, int read_data_fd, int write_data_fd, 
-               int read_status_fd, int write_status_fd );
-
-/* listens on the 'data_to_child' fd and wait for incoming data */
-void prefork_child_wait( prefork_child* child );
-
-int prefork_free( prefork_simple* );
-int prefork_child_free( prefork_child* );
-
-
-void osrf_prefork_register_routers( char* appname );
-
-void osrf_prefork_child_exit( prefork_child* );
diff --git a/src/libstack/osrf_settings.c b/src/libstack/osrf_settings.c
deleted file mode 100644 (file)
index 26e3b8f..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-#include "osrf_settings.h" 
-
-osrf_host_config* config = NULL;
-
-char* osrf_settings_host_value(char* format, ...) {
-       VA_LIST_TO_STRING(format);
-
-       if( ! config ) {
-               const char * msg = "NULL config pointer";
-               fprintf( stderr, "osrf_settings_host_value: %s\n", msg );
-               osrfLogError( OSRF_LOG_MARK, msg );
-               exit( 99 );
-       }
-
-       jsonObject* o = jsonObjectFindPath(config->config, VA_BUF);
-       char* val = jsonObjectToSimpleString(o);
-       jsonObjectFree(o);
-       return val;
-}
-
-jsonObject* osrf_settings_host_value_object(char* format, ...) {
-       VA_LIST_TO_STRING(format);
-
-       if( ! config ) {
-               const char * msg = "config pointer is NULL";
-               fprintf( stderr, "osrf_settings_host_value_object: %s\n", msg );
-               osrfLogError( OSRF_LOG_MARK, msg );
-               exit( 99 );
-       }
-
-       return jsonObjectFindPath(config->config, VA_BUF);
-}
-
-
-int osrf_settings_retrieve(char* hostname) {
-
-       if(!config) {
-
-               osrf_app_session* session = osrf_app_client_session_init("opensrf.settings");
-               jsonObject* params = jsonNewObject(NULL);
-               jsonObjectPush(params, jsonNewObject(hostname));
-               int req_id = osrf_app_session_make_req( 
-                       session, params, "opensrf.settings.host_config.get", 1, NULL );
-               osrf_message* omsg = osrf_app_session_request_recv( session, req_id, 60 );
-               jsonObjectFree(params);
-
-               if(!omsg) {
-                       osrfLogError( OSRF_LOG_MARK, "No osrf_message received from host %s (timeout?)", hostname);
-               } else if(!omsg->_result_content) {
-                       osrf_message_free(omsg);
-                       osrfLogError(
-                               OSRF_LOG_MARK,
-                               "NULL or non-existant osrf_message result content received from host %s, "
-                               "broken message or no settings for host",
-                               hostname
-                       );
-               } else {
-                       config = osrf_settings_new_host_config(hostname);
-                       config->config = jsonObjectClone(omsg->_result_content);
-                       osrf_message_free(omsg);
-               }
-
-               osrf_app_session_request_finish( session, req_id );
-               osrf_app_session_destroy( session );
-
-               if(!config) {
-                       osrfLogError( OSRF_LOG_MARK, "Unable to load config for host %s", hostname);
-                       return -1;
-               }
-       }
-
-       return 0;
-}
-
-osrf_host_config* osrf_settings_new_host_config(char* hostname) {
-       if(!hostname) return NULL;
-       osrf_host_config* c = safe_malloc(sizeof(osrf_host_config));
-       c->hostname = strdup(hostname);
-       return c;
-}
-
-void osrf_settings_free_host_config(osrf_host_config* c) {
-       if(!c) c = config;
-       if(!c) return;
-       free(c->hostname);
-       jsonObjectFree(c->config);      
-       free(c);
-}
diff --git a/src/libstack/osrf_settings.h b/src/libstack/osrf_settings.h
deleted file mode 100644 (file)
index fecfc32..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef OSRF_SETTINGS_H
-#define OSRF_SETTINGS_H
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <time.h>
-#include <stdarg.h>
-
-#include "opensrf/log.h"
-#include "opensrf/utils.h"
-#include "objson/object.h"
-#include "objson/json_parser.h"
-#include "osrf_app_session.h"
-
-
-typedef struct { 
-       char* hostname; 
-       jsonObject* config; 
-} osrf_host_config;
-
-
-osrf_host_config* osrf_settings_new_host_config(char* hostname);
-void osrf_settings_free_host_config(osrf_host_config*);
-char* osrf_settings_host_value(char* path, ...);
-jsonObject* osrf_settings_host_value_object(char* format, ...);
-int osrf_settings_retrieve(char* hostname);
-
-#endif
-
diff --git a/src/libstack/osrf_stack.c b/src/libstack/osrf_stack.c
deleted file mode 100644 (file)
index fe59c92..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-#include "osrf_stack.h"
-#include "osrf_application.h"
-
-osrf_message* _do_client( osrf_app_session*, osrf_message* );
-osrf_message* _do_server( osrf_app_session*, osrf_message* );
-
-/* tell osrf_app_session where the stack entry is */
-int (*osrf_stack_entry_point) (transport_client*, int, int*)  = &osrf_stack_process;
-
-int osrf_stack_process( transport_client* client, int timeout, int* msg_received ) {
-       if( !client ) return -1;
-       transport_message* msg = NULL;
-       if(msg_received) *msg_received = 0;
-
-       while( (msg = client_recv( client, timeout )) ) {
-               if(msg_received) *msg_received = 1;
-               osrfLogDebug( OSRF_LOG_MARK,  "Received message from transport code from %s", msg->sender );
-               osrf_stack_transport_handler( msg, NULL );
-               timeout = 0;
-       }
-
-       if( client->error ) {
-               osrfLogWarning(OSRF_LOG_MARK, "transport_client had trouble reading from the socket..");
-               return -1;
-       }
-
-       if( ! client_connected( client ) ) return -1;
-
-       return 0;
-}
-
-
-
-// -----------------------------------------------------------------------------
-// Entry point into the stack
-// -----------------------------------------------------------------------------
-osrfAppSession* osrf_stack_transport_handler( transport_message* msg, char* my_service ) { 
-
-       if(!msg) return NULL;
-
-   osrfLogSetXid(msg->osrf_xid);
-
-       osrfLogDebug( OSRF_LOG_MARK,  "Transport handler received new message \nfrom %s "
-                       "to %s with body \n\n%s\n", msg->sender, msg->recipient, msg->body );
-
-       if( msg->is_error && ! msg->thread ) {
-               osrfLogWarning( OSRF_LOG_MARK, "!! Received jabber layer error for %s ... exiting\n", msg->sender );
-               message_free( msg );
-               return NULL;
-       }
-
-       if(! msg->thread  && ! msg->is_error ) {
-               osrfLogWarning( OSRF_LOG_MARK, "Received a non-error message with no thread trace... dropping");
-               message_free( msg );
-               return NULL;
-       }
-
-       osrf_app_session* session = osrf_app_session_find_session( msg->thread );
-
-       if( !session && my_service ) 
-               session = osrf_app_server_session_init( msg->thread, my_service, msg->sender);
-
-       if( !session ) return NULL;
-
-       if(!msg->is_error)
-               osrfLogDebug( OSRF_LOG_MARK, "Session [%s] found or built", session->session_id );
-
-       osrf_app_session_set_remote( session, msg->sender );
-       osrf_message* arr[OSRF_MAX_MSGS_PER_PACKET];
-       memset(arr, 0, OSRF_MAX_MSGS_PER_PACKET );
-       int num_msgs = osrf_message_deserialize(msg->body, arr, OSRF_MAX_MSGS_PER_PACKET);
-
-       osrfLogDebug( OSRF_LOG_MARK,  "We received %d messages from %s", num_msgs, msg->sender );
-
-       double starttime = get_timestamp_millis();
-
-       int i;
-       for( i = 0; i != num_msgs; i++ ) {
-
-               /* if we've received a jabber layer error message (probably talking to 
-                       someone who no longer exists) and we're not talking to the original
-                       remote id for this server, consider it a redirect and pass it up */
-               if(msg->is_error) {
-                       osrfLogWarning( OSRF_LOG_MARK,  " !!! Received Jabber layer error message" ); 
-
-                       if(strcmp(session->remote_id,session->orig_remote_id)) {
-                               osrfLogWarning( OSRF_LOG_MARK,  "Treating jabber error as redirect for tt [%d] "
-                                       "and session [%s]", arr[i]->thread_trace, session->session_id );
-
-                               arr[i]->m_type = STATUS;
-                               arr[i]->status_code = OSRF_STATUS_REDIRECTED;
-
-                       } else {
-                               osrfLogWarning( OSRF_LOG_MARK, " * Jabber Error is for top level remote id [%s], no one "
-                                               "to send my message too!!!", session->remote_id );
-                       }
-               }
-
-               osrf_stack_message_handler( session, arr[i] );
-       }
-
-       double duration = get_timestamp_millis() - starttime;
-       osrfLogInfo(OSRF_LOG_MARK, "Message processing duration %f", duration);
-
-       message_free( msg );
-       osrfLogDebug( OSRF_LOG_MARK, "after msg delete");
-
-       return session;
-}
-
-int osrf_stack_message_handler( osrf_app_session* session, osrf_message* msg ) {
-       if(session == NULL || msg == NULL)
-               return 0;
-
-       osrf_message* ret_msg = NULL;
-
-       if( session->type ==  OSRF_SESSION_CLIENT )
-                ret_msg = _do_client( session, msg );
-       else
-               ret_msg= _do_server( session, msg );
-
-       if(ret_msg) {
-               osrfLogDebug( OSRF_LOG_MARK, "passing message %d / session %s to app handler", 
-                               msg->thread_trace, session->session_id );
-               osrf_stack_application_handler( session, ret_msg );
-       } else
-               osrf_message_free(msg);
-
-       return 1;
-
-} 
-
-/** If we return a message, that message should be passed up the stack, 
-  * if we return NULL, we're finished for now...
-  */
-osrf_message* _do_client( osrf_app_session* session, osrf_message* msg ) {
-       if(session == NULL || msg == NULL)
-               return NULL;
-
-       osrf_message* new_msg;
-
-       if( msg->m_type == STATUS ) {
-               
-               switch( msg->status_code ) {
-
-                       case OSRF_STATUS_OK:
-                               osrfLogDebug( OSRF_LOG_MARK, "We connected successfully");
-                               session->state = OSRF_SESSION_CONNECTED;
-                               osrfLogDebug( OSRF_LOG_MARK,  "State: %x => %s => %d", session, session->session_id, session->state );
-                               return NULL;
-
-                       case OSRF_STATUS_COMPLETE:
-                               osrf_app_session_set_complete( session, msg->thread_trace );
-                               return NULL;
-
-                       case OSRF_STATUS_CONTINUE:
-                               osrf_app_session_request_reset_timeout( session, msg->thread_trace );
-                               return NULL;
-
-                       case OSRF_STATUS_REDIRECTED:
-                               osrf_app_session_reset_remote( session );
-                               session->state = OSRF_SESSION_DISCONNECTED;
-                               osrf_app_session_request_resend( session, msg->thread_trace );
-                               return NULL;
-
-                       case OSRF_STATUS_EXPFAILED: 
-                               osrf_app_session_reset_remote( session );
-                               session->state = OSRF_SESSION_DISCONNECTED;
-                               return NULL;
-
-                       case OSRF_STATUS_TIMEOUT:
-                               osrf_app_session_reset_remote( session );
-                               session->state = OSRF_SESSION_DISCONNECTED;
-                               osrf_app_session_request_resend( session, msg->thread_trace );
-                               return NULL;
-
-
-                       default:
-                               new_msg = osrf_message_init( RESULT, msg->thread_trace, msg->protocol );
-                               osrf_message_set_status_info( new_msg, 
-                                               msg->status_name, msg->status_text, msg->status_code );
-                               osrfLogWarning( OSRF_LOG_MARK, "The stack doesn't know what to do with " 
-                                               "the provided message code: %d, name %s. Passing UP.", 
-                                               msg->status_code, msg->status_name );
-                               new_msg->is_exception = 1;
-                               osrf_app_session_set_complete( session, msg->thread_trace );
-                               osrf_message_free(msg);
-                               return new_msg;
-               }
-
-               return NULL;
-
-       } else if( msg->m_type == RESULT ) 
-               return msg;
-
-       return NULL;
-
-}
-
-
-/** If we return a message, that message should be passed up the stack, 
-  * if we return NULL, we're finished for now...
-  */
-osrf_message* _do_server( osrf_app_session* session, osrf_message* msg ) {
-
-       if(session == NULL || msg == NULL) return NULL;
-
-       osrfLogDebug( OSRF_LOG_MARK, "Server received message of type %d", msg->m_type );
-
-       switch( msg->m_type ) {
-
-               case STATUS:
-                               return NULL;
-
-               case DISCONNECT:
-                               /* session will be freed by the forker */
-                               osrfLogDebug(OSRF_LOG_MARK, "Client sent explicit disconnect");
-                               session->state = OSRF_SESSION_DISCONNECTED;
-                               return NULL;
-
-               case CONNECT:
-                               osrfAppSessionStatus( session, OSRF_STATUS_OK, 
-                                               "osrfConnectStatus", msg->thread_trace, "Connection Successful" );
-                               session->state = OSRF_SESSION_CONNECTED;
-                               return NULL;
-
-               case REQUEST:
-
-                               osrfLogDebug( OSRF_LOG_MARK, "server passing message %d to application handler "
-                                               "for session %s", msg->thread_trace, session->session_id );
-                               return msg;
-
-               default:
-                       osrfLogWarning( OSRF_LOG_MARK, "Server cannot handle message of type %d", msg->m_type );
-                       session->state = OSRF_SESSION_DISCONNECTED;
-                       return NULL;
-
-       }
-}
-
-
-
-int osrf_stack_application_handler( osrf_app_session* session, osrf_message* msg ) {
-       if(session == NULL || msg == NULL) return 0;
-
-       if(msg->m_type == RESULT && session->type == OSRF_SESSION_CLIENT) {
-               osrf_app_session_push_queue( session, msg ); 
-               return 1;
-       }
-
-       if(msg->m_type != REQUEST) return 1;
-
-       char* method = msg->method_name;
-       char* app       = session->remote_service;
-       jsonObject* params = msg->_params;
-
-       osrfAppRunMethod( app, method,  session, msg->thread_trace, params );
-       osrfMessageFree(msg);
-               
-       return 1;
-}
-
-
diff --git a/src/libstack/osrf_stack.h b/src/libstack/osrf_stack.h
deleted file mode 100644 (file)
index 0ef6d00..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#include "opensrf/transport_client.h"
-#include "osrf_message.h"
-#include "osrf_app_session.h"
-
-#ifndef OSRF_STACK_H
-#define OSRF_STACK_H
-
-/* the max number of oilsMessage blobs present in any one root packet */
-#define OSRF_MAX_MSGS_PER_PACKET 256
-// -----------------------------------------------------------------------------
-
-int osrf_stack_process( transport_client* client, int timeout, int* msg_received );
-osrfAppSession*  osrf_stack_transport_handler( transport_message* msg, char* my_service );
-int osrf_stack_message_handler( osrf_app_session* session, osrf_message* msg );
-int osrf_stack_application_handler( osrf_app_session* session, osrf_message* msg );
-
-
-
-#endif
diff --git a/src/libstack/osrf_system.c b/src/libstack/osrf_system.c
deleted file mode 100644 (file)
index dc6b2ba..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-#include "osrf_system.h"
-#include <signal.h>
-#include "osrf_application.h"
-#include "osrf_prefork.h"
-
-static int _osrfSystemInitCache( void );
-
-static transport_client* osrfGlobalTransportClient = NULL;
-
-transport_client* osrfSystemGetTransportClient( void ) {
-       return osrfGlobalTransportClient;
-}
-
-void osrfSystemIgnoreTransportClient() {
-       osrfGlobalTransportClient = NULL;
-}
-
-transport_client* osrf_system_get_transport_client( void ) {
-       return osrfGlobalTransportClient;
-}
-
-int osrf_system_bootstrap_client( char* config_file, char* contextnode ) {
-       return osrf_system_bootstrap_client_resc(config_file, contextnode, NULL);
-}
-
-int osrfSystemBootstrapClientResc( char* config_file, char* contextnode, char* resource ) {
-       return osrf_system_bootstrap_client_resc( config_file, contextnode, resource );
-}
-
-
-static int _osrfSystemInitCache( void ) {
-
-       jsonObject* cacheServers = osrf_settings_host_value_object("/cache/global/servers/server");
-       char* maxCache = osrf_settings_host_value("/cache/global/max_cache_time");
-
-       if( cacheServers && maxCache) {
-
-               if( cacheServers->type == JSON_ARRAY ) {
-                       int i;
-                       char* servers[cacheServers->size];
-                       for( i = 0; i != cacheServers->size; i++ ) {
-                               servers[i] = jsonObjectGetString( jsonObjectGetIndex(cacheServers, i) );
-                               osrfLogInfo( OSRF_LOG_MARK, "Adding cache server %s", servers[i]);
-                       }
-                       osrfCacheInit( servers, cacheServers->size, atoi(maxCache) );
-
-               } else {
-                       char* servers[] = { jsonObjectGetString(cacheServers) };                
-                       osrfLogInfo( OSRF_LOG_MARK, "Adding cache server %s", servers[0]);
-                       osrfCacheInit( servers, 1, atoi(maxCache) );
-               }
-
-       } else {
-               osrfLogError( OSRF_LOG_MARK,  "Missing config value for /cache/global/servers/server _or_ "
-                       "/cache/global/max_cache_time");
-       }
-
-       return 0;
-}
-
-
-int osrfSystemBootstrap( char* hostname, char* configfile, char* contextNode ) {
-       if( !(hostname && configfile && contextNode) ) return -1;
-
-       /* first we grab the settings */
-       if(!osrfSystemBootstrapClientResc(configfile, contextNode, "settings_grabber" )) {
-               osrfLogError( OSRF_LOG_MARK,
-                       "Unable to bootstrap for host %s from configuration file %s",
-                       hostname, configfile );
-               return -1;
-       }
-
-       int retcode = osrf_settings_retrieve(hostname);
-       osrf_system_disconnect_client();
-
-       if( retcode ) {
-               osrfLogError( OSRF_LOG_MARK,
-                       "Unable to retrieve settings for host %s from configuration file %s",
-                       hostname, configfile );
-               return -1;
-       }
-       
-       jsonObject* apps = osrf_settings_host_value_object("/activeapps/appname");
-       osrfStringArray* arr = osrfNewStringArray(8);
-       
-       _osrfSystemInitCache();
-
-       if(apps) {
-               int i = 0;
-
-               if(apps->type == JSON_STRING) {
-                       osrfStringArrayAdd(arr, jsonObjectGetString(apps));
-
-               } else {
-                       jsonObject* app;
-                       while( (app = jsonObjectGetIndex(apps, i++)) ) 
-                               osrfStringArrayAdd(arr, jsonObjectGetString(app));
-               }
-
-               char* appname = NULL;
-               i = 0;
-               while( (appname = osrfStringArrayGetString(arr, i++)) ) {
-
-                       char* lang = osrf_settings_host_value("/apps/%s/language", appname);
-
-                       if(lang && !strcasecmp(lang,"c"))  {
-
-                               char* libfile = osrf_settings_host_value("/apps/%s/implementation", appname);
-               
-                               if(! (appname && libfile) ) {
-                                       osrfLogWarning( OSRF_LOG_MARK, "Missing appname / libfile in settings config");
-                                       continue;
-                               }
-
-                               osrfLogInfo( OSRF_LOG_MARK, "Launching application %s with implementation %s", appname, libfile);
-               
-                               pid_t pid;
-               
-                               if( (pid = fork()) ) { 
-                                       // storage pid in local table for re-launching dead children...
-                                       osrfLogInfo( OSRF_LOG_MARK, "Launched application child %ld", (long) pid);
-       
-                               } else {
-               
-                                       fprintf(stderr, " * Running application %s\n", appname);
-                                       if( osrfAppRegisterApplication( appname, libfile ) == 0 ) 
-                                               osrf_prefork_run(appname);
-       
-                                       osrfLogDebug( OSRF_LOG_MARK, "Server exiting for app %s and library %s\n", appname, libfile );
-                                       exit(0);
-                               }
-                       } // language == c
-               } 
-       }
-
-       /** daemonize me **/
-
-       /* background and let our children do their thing */
-       daemonize();
-    while(1) {
-        errno = 0;
-        pid_t pid = wait(NULL);
-        if(-1 == pid) {
-            if(errno == ECHILD)
-                osrfLogError(OSRF_LOG_MARK, "We have no more live services... exiting");
-            else
-                osrfLogError(OSRF_LOG_MARK, "Exiting top-level system loop with error: %s", strerror(errno));
-            break;
-        } else {
-            osrfLogError(OSRF_LOG_MARK, "We lost a top-level service process with PID %ld", pid);
-        }
-    }
-
-
-       return 0;
-}
-
-int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, char* resource ) {
-
-       int failure = 0;
-
-       if(osrfSystemGetTransportClient()) {
-               osrfLogInfo(OSRF_LOG_MARK, "Client is already bootstrapped");
-               return 1; /* we already have a client connection */
-       }
-
-       if( !( config_file && contextnode ) && ! osrfConfigHasDefaultConfig() ) {
-               osrfLogError( OSRF_LOG_MARK, "No Config File Specified\n" );
-               return -1;
-       }
-
-       if( config_file ) {
-               osrfConfig* cfg = osrfConfigInit( config_file, contextnode );
-               if(cfg)
-                       osrfConfigSetDefaultConfig(cfg);
-               else
-                       return 0;   /* Can't load configuration?  Bail out */
-       }
-
-
-       char* log_file          = osrfConfigGetValue( NULL, "/logfile");
-       char* log_level         = osrfConfigGetValue( NULL, "/loglevel" );
-       osrfStringArray* arr    = osrfNewStringArray(8);
-       osrfConfigGetValueList(NULL, arr, "/domains/domain");
-
-       char* username          = osrfConfigGetValue( NULL, "/username" );
-       char* password          = osrfConfigGetValue( NULL, "/passwd" );
-       char* port              = osrfConfigGetValue( NULL, "/port" );
-       char* unixpath          = osrfConfigGetValue( NULL, "/unixpath" );
-       char* facility          = osrfConfigGetValue( NULL, "/syslog" );
-       char* actlog            = osrfConfigGetValue( NULL, "/actlog" );
-
-       if(!log_file) {
-               fprintf(stderr, "No log file specified in configuration file %s\n",
-                          config_file);
-               free(log_level);
-               free(username);
-               free(password);
-               free(port);
-               free(unixpath);
-               free(facility);
-               free(actlog);
-               return -1;
-       }
-
-       /* if we're a source-client, tell the logger */
-       char* isclient = osrfConfigGetValue(NULL, "/client");
-       if( isclient && !strcasecmp(isclient,"true") )
-               osrfLogSetIsClient(1);
-       free(isclient);
-
-       int llevel = 0;
-       int iport = 0;
-       if(port) iport = atoi(port);
-       if(log_level) llevel = atoi(log_level);
-
-       if(!strcmp(log_file, "syslog")) {
-               osrfLogInit( OSRF_LOG_TYPE_SYSLOG, contextnode, llevel );
-               osrfLogSetSyslogFacility(osrfLogFacilityToInt(facility));
-               if(actlog) osrfLogSetSyslogActFacility(osrfLogFacilityToInt(actlog));
-
-       } else {
-               osrfLogInit( OSRF_LOG_TYPE_FILE, contextnode, llevel );
-               osrfLogSetFile( log_file );
-       }
-
-
-       /* Get a domain, if one is specified */
-       const char* domain = osrfStringArrayGetString( arr, 0 ); /* just the first for now */
-       if(!domain) {
-               fprintf(stderr, "No domain specified in configuration file %s\n", config_file);
-               osrfLogError( OSRF_LOG_MARK, "No domain specified in configuration file %s\n", config_file);
-               failure = 1;
-       }
-
-       if(!username) {
-               fprintf(stderr, "No username specified in configuration file %s\n", config_file);
-               osrfLogError( OSRF_LOG_MARK, "No username specified in configuration file %s\n", config_file);
-               failure = 1;
-       }
-
-       if(!password) {
-               fprintf(stderr, "No password specified in configuration file %s\n", config_file);
-               osrfLogError( OSRF_LOG_MARK, "No password specified in configuration file %s\n", config_file);
-               failure = 1;
-       }
-
-       if((iport <= 0) && !unixpath) {
-               fprintf(stderr, "No unixpath or valid port in configuration file %s\n", config_file);
-               osrfLogError( OSRF_LOG_MARK, "No unixpath or valid port in configuration file %s\n",
-                       config_file);
-               failure = 1;
-       }
-
-       if (failure) {
-               osrfStringArrayFree(arr);
-               free(log_level);
-               free(username);
-               free(password);
-               free(port);
-               free(unixpath);
-               free(facility);
-               free(actlog);
-               return 0;
-       }
-
-       osrfLogInfo( OSRF_LOG_MARK, "Bootstrapping system with domain %s, port %d, and unixpath %s",
-               domain, iport, unixpath ? unixpath : "(none)" );
-       transport_client* client = client_init( domain, iport, unixpath, 0 );
-
-       const char* host;
-       host = getenv("HOSTNAME");
-
-       char tbuf[32];
-       tbuf[0] = '\0';
-       snprintf(tbuf, 32, "%f", get_timestamp_millis());
-
-       if(!host) host = "";
-       if(!resource) resource = "";
-
-       int len = strlen(resource) + 256;
-       char buf[len];
-       buf[0] = '\0';
-       snprintf(buf, len - 1, "%s_%s_%s_%ld", resource, host, tbuf, (long) getpid() );
-
-       if(client_connect( client, username, password, buf, 10, AUTH_DIGEST )) {
-               /* child nodes will leak the parents client... but we can't free
-                       it without disconnecting the parents client :( */
-               osrfGlobalTransportClient = client;
-       }
-
-       osrfStringArrayFree(arr);
-       free(actlog);
-       free(facility);
-       free(log_level);
-       free(log_file);
-       free(username);
-       free(password);
-       free(port);     
-       free(unixpath);
-
-       if(osrfGlobalTransportClient)
-               return 1;
-
-       return 0;
-}
-
-int osrf_system_disconnect_client( void ) {
-       client_disconnect( osrfGlobalTransportClient );
-       client_free( osrfGlobalTransportClient );
-       osrfGlobalTransportClient = NULL;
-       return 0;
-}
-
-int osrf_system_shutdown( void ) {
-       osrfConfigCleanup();
-       osrf_system_disconnect_client();
-       osrf_settings_free_host_config(NULL);
-       osrfAppSessionCleanup();
-       osrfLogCleanup();
-       return 1;
-}
-
-
-
-
diff --git a/src/libstack/osrf_system.h b/src/libstack/osrf_system.h
deleted file mode 100644 (file)
index 3a87008..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-#ifndef OSRF_SYSTEM_H
-#define OSRF_SYSTEM_H
-
-#include "opensrf/transport_client.h"
-#include "opensrf/utils.h"
-#include "opensrf/log.h"
-#include "osrf_settings.h"
-#include "osrfConfig.h"
-#include "osrf_cache.h"
-
-
-
-/** Connects to jabber.  Returns 1 on success, 0 on failure 
-       contextnode is the location in the config file where we collect config info
-*/
-
-
-int osrf_system_bootstrap_client( char* config_file, char* contextnode );
-
-/* bootstraps a client adding the given resource string to the host/pid, etc. resource string */
-/**
-  Sets up the global connection.
-  @param configFile The OpenSRF bootstrap config file
-  @param contextNode The location in the config file where we'll find the necessary info
-  @param resource The login resource.  If NULL a default will be created
-  @return 1 on successs, 0 on failure.
-  */
-int osrfSystemBootstrapClientResc( char* configFile, char* contextNode, char* resource );
-int osrf_system_bootstrap_client_resc( char* config_file, char* contextnode, char* resource );
-
-/**
-  Bootstrap the server.
-  @param hostname The name of this host.  This is the name that will be used to 
-       load the settings.
-  @param configfile The OpenSRF bootstrap config file
-  @param contextnode The config context
-  @return 0 on success, -1 on error
-  */
-int osrfSystemBootstrap( char* hostName, char* configfile, char* contextNode );
-
-transport_client* osrfSystemGetTransportClient( void );
-transport_client* osrf_system_get_transport_client( void );
-
-/* disconnects and destroys the current client connection */
-int osrf_system_disconnect_client();
-int osrf_system_shutdown( void ); 
-
-
-/* this will clear the global transport client pointer without
- * actually destroying the socket.  this is useful for allowing
- * children to have their own socket, even though their parent
- * already created a socket
- */
-void osrfSystemIgnoreTransportClient();
-
-
-#endif
diff --git a/src/libstack/osrf_transgroup.c b/src/libstack/osrf_transgroup.c
deleted file mode 100644 (file)
index 1d3d3f4..0000000
+++ /dev/null
@@ -1,244 +0,0 @@
-#include "osrf_transgroup.h"
-#include <sys/select.h>
-
-
-osrfTransportGroupNode* osrfNewTransportGroupNode( 
-               char* domain, int port, char* username, char* password, char* resource ) {
-
-       if(!(domain && port && username && password && resource)) return NULL;
-
-       osrfTransportGroupNode* node = safe_malloc(sizeof(osrfTransportGroupNode));
-       node->domain    = strdup(domain);
-       node->port              = port;
-       node->username = strdup(username);
-       node->password = strdup(password);
-       node->domain    = strdup(domain);
-       node->resource  = strdup(resource);
-       node->active    = 0;
-       node->lastsent  = 0;
-       node->connection = client_init( domain, port, NULL, 0 );
-
-       return node;
-}
-
-
-osrfTransportGroup* osrfNewTransportGroup( osrfTransportGroupNode* nodes[], int count ) {
-       if(!nodes || count < 1) return NULL;
-
-       osrfTransportGroup* grp = safe_malloc(sizeof(osrfTransportGroup));
-       grp->nodes                                      = osrfNewHash();
-       grp->itr                                                = osrfNewHashIterator(grp->nodes);
-
-       int i;
-       for( i = 0; i != count; i++ ) {
-               if(!(nodes[i] && nodes[i]->domain) ) return NULL;
-               osrfHashSet( grp->nodes, nodes[i], nodes[i]->domain );
-               osrfLogDebug( OSRF_LOG_MARK, "Adding domain %s to TransportGroup", nodes[i]->domain);
-       }
-
-       return grp;
-}
-
-
-/* connect all of the nodes to their servers */
-int osrfTransportGroupConnectAll( osrfTransportGroup* grp ) {
-       if(!grp) return -1;
-       int active = 0;
-
-       osrfTransportGroupNode* node;
-       osrfHashIteratorReset(grp->itr);
-
-       while( (node = osrfHashIteratorNext(grp->itr)) ) {
-               osrfLogInfo( OSRF_LOG_MARK, "TransportGroup attempting to connect to domain %s", 
-                                                        node->connection->session->server);
-
-               if(client_connect( node->connection, node->username, 
-                                       node->password, node->resource, 10, AUTH_DIGEST )) {
-                       node->active = 1;
-                       active++;
-                       osrfLogInfo( OSRF_LOG_MARK, "TransportGroup successfully connected to domain %s", 
-                                                        node->connection->session->server);
-               } else {
-                       osrfLogWarning( OSRF_LOG_MARK, "TransportGroup unable to connect to domain %s", 
-                                                        node->connection->session->server);
-               }
-       }
-
-       osrfHashIteratorReset(grp->itr);
-       return active;
-}
-
-void osrfTransportGroupDisconnectAll( osrfTransportGroup* grp ) {
-       if(!grp) return;
-
-       osrfTransportGroupNode* node;
-       osrfHashIteratorReset(grp->itr);
-
-       while( (node = osrfHashIteratorNext(grp->itr)) ) {
-               osrfLogInfo( OSRF_LOG_MARK, "TransportGroup disconnecting from domain %s", 
-                                                        node->connection->session->server);
-               client_disconnect(node->connection);
-               node->active = 0;
-       }
-
-       osrfHashIteratorReset(grp->itr);
-}
-
-
-int osrfTransportGroupSendMatch( osrfTransportGroup* grp, transport_message* msg ) {
-       if(!(grp && msg)) return -1;
-
-       char domain[256];
-       bzero(domain, 256);
-       jid_get_domain( msg->recipient, domain, 255 );
-
-       osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain);
-       if(node) {
-               if( (client_send_message( node->connection, msg )) == 0 )
-                       return 0;
-       }
-
-       osrfLogWarning( OSRF_LOG_MARK, "Error sending message to domain %s", domain );
-       return -1;
-}
-
-int osrfTransportGroupSend( osrfTransportGroup* grp, transport_message* msg ) {
-
-       if(!(grp && msg)) return -1;
-       int bufsize = 256;
-
-       char domain[bufsize];
-       bzero(domain, bufsize);
-       jid_get_domain( msg->recipient, domain, bufsize - 1 );
-
-       char msgrecip[bufsize];
-       bzero(msgrecip, bufsize);
-       jid_get_username(msg->recipient, msgrecip, bufsize - 1);
-
-       char msgres[bufsize];
-       bzero(msgres, bufsize);
-       jid_get_resource(msg->recipient, msgres, bufsize - 1);
-
-       char* firstdomain = NULL;
-       char newrcp[1024];
-
-       int updateRecip = 1;
-       /* if we don't host this domain, don't update the recipient but send it as is */
-       if(!osrfHashGet(grp->nodes, domain)) updateRecip = 0;
-
-       osrfTransportGroupNode* node;
-
-       do {
-
-               node = osrfHashIteratorNext(grp->itr);
-               if(!node) osrfHashIteratorReset(grp->itr);
-
-               node = osrfHashIteratorNext(grp->itr);
-               if(!node) return -1;
-
-               if(firstdomain == NULL) {
-                       firstdomain = node->domain;
-
-               } else {
-                       if(!strcmp(firstdomain, node->domain)) { /* we've made a full loop */
-                               osrfLogWarning( OSRF_LOG_MARK, "We've tried to send to all domains.. giving up");
-                               return -1;
-                       }
-               }
-
-               /* update the recipient domain if necessary */
-
-               if(updateRecip) {
-                       bzero(newrcp, 1024);
-                       sprintf(newrcp, "%s@%s/%s", msgrecip, node->domain, msgres);
-                       free(msg->recipient);
-                       msg->recipient = strdup(newrcp);
-               }
-
-               if( (client_send_message( node->connection, msg )) == 0 ) 
-                       return 0;
-
-       } while(1);
-
-       return -1;
-}
-
-static int __osrfTGWait( fd_set* fdset, int maxfd, int timeout ) {
-       if(!(fdset && maxfd)) return 0;
-
-       struct timeval tv;
-       tv.tv_sec = timeout;
-       tv.tv_usec = 0;
-       int retval = 0;
-
-       if( timeout < 0 ) {
-               if( (retval = select( maxfd + 1, fdset, NULL, NULL, NULL)) == -1 ) 
-                       return 0;
-
-       } else {
-               if( (retval = select( maxfd + 1, fdset, NULL, NULL, &tv)) == -1 ) 
-                       return 0;
-       }
-
-       return retval;
-}
-
-
-transport_message* osrfTransportGroupRecvAll( osrfTransportGroup* grp, int timeout ) {
-       if(!grp) return NULL;
-
-       int maxfd = 0;
-       fd_set fdset;
-       FD_ZERO( &fdset );
-
-       osrfTransportGroupNode* node;
-       osrfHashIterator* itr = osrfNewHashIterator(grp->nodes);
-
-       while( (node = osrfHashIteratorNext(itr)) ) {
-               if(node->active) {
-                       int fd = node->connection->session->sock_id;
-                       if( fd < maxfd ) maxfd = fd;
-                       FD_SET( fd, &fdset );
-               }
-       }
-       osrfHashIteratorReset(itr);
-
-       if( __osrfTGWait( &fdset, maxfd, timeout ) ) {
-               while( (node = osrfHashIteratorNext(itr)) ) {
-                       if(node->active) {
-                               int fd = node->connection->session->sock_id;
-                               if( FD_ISSET( fd, &fdset ) ) {
-                                       return client_recv( node->connection, 0 );
-                               }
-                       }
-               }
-       }
-
-       osrfHashIteratorFree(itr);
-       return NULL;
-}
-
-transport_message* osrfTransportGroupRecv( osrfTransportGroup* grp, char* domain, int timeout ) {
-       if(!(grp && domain)) return NULL;
-
-       osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain);
-       if(!node && node->connection && node->connection->session) return NULL;
-       int fd = node->connection->session->sock_id;
-
-       fd_set fdset;
-       FD_ZERO( &fdset );
-       FD_SET( fd, &fdset );
-
-       int active = __osrfTGWait( &fdset, fd, timeout );
-       if(active) return client_recv( node->connection, 0 );
-       
-       return NULL;
-}
-
-void osrfTransportGroupSetInactive( osrfTransportGroup* grp, char* domain ) {
-       if(!(grp && domain)) return;
-       osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain );
-       if(node) node->active = 0;
-}
-
-
diff --git a/src/libstack/osrf_transgroup.h b/src/libstack/osrf_transgroup.h
deleted file mode 100644 (file)
index 57ee1be..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-#include "opensrf/transport_client.h"
-#include "opensrf/transport_message.h"
-#include "osrf_list.h"
-#include "osrf_hash.h"
-#include "osrfConfig.h"
-#include "opensrf/utils.h"
-#include <time.h>
-
-/**
-  Maintains a set of transport clients 
-  */
-
-struct __osrfTransportGroupStruct {
-       osrfHash* nodes;                                                /* our hash of nodes keyed by domain */
-       osrfHashIterator* itr;                          /* points to the next node in the list */
-};
-typedef struct __osrfTransportGroupStruct osrfTransportGroup;
-
-
-struct __osrfTransportGroupNode {
-       transport_client* connection;           /* our connection to the network */
-       char* domain;                                                   /* the domain we're connected to */
-       char* username;                                         /* username used to connect to the group of servers */
-       char* password;                                         /* password used to connect to the group of servers */
-       char* resource;                                         /* the login resource */
-       int port;                                                               /* port used to connect to the group of servers */
-
-       int active;                                                             /* true if we're able to send data on this connection */
-       time_t lastsent;                                                /* the last time we sent a message */
-};
-typedef struct __osrfTransportGroupNode osrfTransportGroupNode;
-
-
-/**
-  Creates a new group node
-  @param domain The domain we're connecting to
-  @param port The port to connect on
-  @param username The login name
-  @param password The login password
-  @param resource The login resource
-  @return A new transport group node
-  */
-osrfTransportGroupNode* osrfNewTransportGroupNode( 
-               char* domain, int port, char* username, char* password, char* resource );
-
-
-/**
-  Allocates and initializes a new transport group.
-  The first node in the array is the default node for client connections.
-  @param nodes The nodes in the group.
-  */
-osrfTransportGroup* osrfNewTransportGroup( osrfTransportGroupNode* nodes[], int count );
-
-/**
-  Attempts to connect all of the nodes in this group.
-  @param grp The transport group
-  @return The number of nodes successfully connected
-  */
-int osrfTransportGroupConnectAll( osrfTransportGroup* grp );
-
-void osrfTransportGroupDisconnectAll( osrfTransportGroup* grp );
-
-
-/**
-  Sends a transport message by going to the next domain in the set.
-  if we have a connection for the recipient domain, then we consider it to be
-  a 'local' message.  Local messages have their recipient domains re-written to
-  match the domain of the next server in the set and they are sent directly to 
-  that server.  If we do not have a connection for the recipient domain, it is 
-  considered a 'remote' message and the message is sent directly (unchanged)
-  to the next connection in the set.
-
-  @param grp The transport group
-  @param msg The message to send 
-  @return 0 on normal successful send.  
-  Returns -1 if the message cannot be sent.  
-  */
-int osrfTransportGroupSend( osrfTransportGroup* grp, transport_message* msg );
-
-/**
-  Sends the message to the exact recipient.  No failover is attempted.
-  @return 0 on success, -1 on error.
-  */
-int osrfTransportGroupSendMatch( osrfTransportGroup* grp, transport_message* msg );
-
-
-int _osrfTGServerSend( osrfTransportGroup* grp, char* domain, transport_message* msg );
-int _osrfTGClientSend( osrfTransportGroup* grp, char* domain, transport_message* msg );
-
-/**
-  Waits on all connections for inbound data.
-  @param grp The transport group
-  @param timeout How long to wait for data.  0 means check for data
-  but don't wait, a negative number means to wait indefinitely
-  @return The received message or NULL if the timeout occurred before a 
-  message was received 
- */
-transport_message* osrfTransportGroupRecvAll( osrfTransportGroup* grp, int timeout );
-
-/**
-  Waits for data from a single domain
-  @param grp The transport group
-  @param domain The domain to wait for data on
-  @param timeout see osrfTransportGroupRecvAll
-  */
-transport_message* osrfTransportGroupRecv( osrfTransportGroup* grp, char* domain, int timeout );
-
-/**
-  Tells the group that a message to the given domain failed
-  domain did not make it through;
-  @param grp The transport group
-  @param comain The failed domain
-  */
-void osrfTransportGroupSetInactive( osrfTransportGroup* grp, char* domain );
-
-
-/**
-  Finds a node in our list of nodes 
-  */
-osrfTransportGroupNode* __osrfTransportGroupFindNode( osrfTransportGroup* grp, char* domain );
-
-
diff --git a/src/libtransport/Makefile b/src/libtransport/Makefile
deleted file mode 100644 (file)
index 643e81c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-
-TARGETS        = transport_message.o transport_session.o transport_client.o 
-HEADERS        = transport_message.h transport_session.h transport_client.h 
-
-TARGET = libopensrf_transport.so
-
-all:   $(TARGETS) copy
-
-copy:
-       cp $(HEADERS) $(TMPDIR)
-
-transport_session.o:   transport_session.c transport_session.h
-transport_message.o:   transport_message.c transport_message.h
-transport_client.o:    transport_client.c transport_client.h
-
-
-clean:
-       /bin/rm -f *.o 
diff --git a/src/libtransport/basic_client.c b/src/libtransport/basic_client.c
deleted file mode 100644 (file)
index d7fa9a1..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-#include "transport_client.h"
-#include "signal.h"
-
-pid_t pid;
-void sig_int( int sig ) {
-       fprintf(stderr, "Killing child %d\n", pid );
-       kill( pid, SIGKILL );
-}
-
-/* connects and registers with the router */
-int main( int argc, char** argv ) {
-
-       if( argc < 5 ) {
-               osrfLogError( OSRF_LOG_MARK, "Usage: %s <username> <host> <resource> <recipient> \n", argv[0] );
-               return 99;
-       }
-
-       transport_message* send;
-       transport_client* client = client_init( argv[2], 5222, 0 );
-
-       // try to connect, allow 15 second connect timeout 
-       if( client_connect( client, argv[1], "jkjkasdf", argv[3], 15, AUTH_DIGEST ) ) 
-               osrfLogInfo(OSRF_LOG_MARK, "Connected...\n");
-        else { 
-               osrfLogError( OSRF_LOG_MARK, "NOT Connected...\n" ); 
-               return -1;
-        }
-       
-       if( (pid=fork()) ) { /* parent */
-
-               signal(SIGINT, sig_int);
-               fprintf(stderr, "Listener: %ld\n", (long) getpid() );   
-               char buf[300];
-               memset(buf, 0, 300);
-               printf("=> ");
-
-               while( fgets( buf, 299, stdin) ) {
-
-                       // remove newline
-                       buf[strlen(buf)-1] = '\0';
-
-                       if( strcmp(buf, "exit")==0) { 
-                               client_free( client );  
-                               break; 
-                       }
-
-                       send = message_init( buf, "", "123454321", argv[4], NULL );
-                       client_send_message( client, send );
-                       message_free( send );
-                       printf("\n=> ");
-                       memset(buf, 0, 300);
-               }
-               fprintf(stderr, "Killing child %d\n", pid );
-               kill( pid, SIGKILL );
-               return 0;
-
-       } else {
-
-               fprintf(stderr, "Sender: %ld\n", (long) getpid() );     
-
-               transport_message* recv;
-               while( (recv=client_recv( client, -1)) ) {
-                       if( recv->is_error )
-                               fprintf( stderr, "\nReceived Error\t: ------------------\nFrom:\t\t"
-                                       "%s\nRouterFrom:\t%s\nBody:\t\t%s\nType %s\nCode %d\n=> ", 
-                                       recv->sender, recv->router_from, recv->body, recv->error_type, recv->error_code );
-                       else
-                               fprintf( stderr, "\nReceived\t: ------------------\nFrom:\t\t"
-                                       "%s\nRouterFrom:\t%s\nBody:\t\t%s\n=> ", recv->sender, recv->router_from, recv->body );
-
-                       message_free( recv );
-               }
-
-       }
-       return 0;
-
-}
-
-
-
-
diff --git a/src/libtransport/component.c b/src/libtransport/component.c
deleted file mode 100644 (file)
index 1f909d2..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "transport_client.h"
-#include "signal.h"
-
-
-/*
-void print_stuff(void* blah, char* data) {
-       fprintf(stderr, "Received from socket: %s\n", data);
-}
-*/
-
-/* connects and registers with the router */
-int main( int argc, char** argv ) {
-
-
-
-       if( argc < 5 ) {
-               osrfLogError(OSRF_LOG_MARK,  "Usage: %s <server> <port> <name> <secret>", argv[0] );
-               return -1;
-       }
-
-       int port = atoi(argv[2]);
-       transport_client* client = client_init( argv[1], port, 1 );
-
-       // try to connect, allow 15 second connect timeout 
-       if( client_connect( client, argv[3], argv[4], "", 15, 1 ) ) 
-               osrfLogInfo(OSRF_LOG_MARK, "Connected...\n");
-        else  {
-               osrfLogError(OSRF_LOG_MARK,  "NOT Connected...\n" ); 
-               return -1;
-        }
-       
-       transport_message* recv;
-       while( (recv=client_recv( client, -1)) ) {
-               if( recv->is_error )
-                       fprintf( stderr, "\nReceived Error\t: ------------------\nFrom:\t\t"
-                               "%s\nRouterFrom:\t%s\nBody:\t\t%s\nType %s\nCode %d\n=> ", 
-                               recv->sender, recv->router_from, recv->body, recv->error_type, recv->error_code );
-               else
-                       fprintf( stderr, "\nReceived\t: ------------------\nFrom:\t\t"
-                               "%s\nRouterFrom:\t%s\nBody:\t\t%s\n=> ", recv->sender, recv->router_from, recv->body );
-               transport_message* send = message_init( "Hello...", "", "123454321", recv->sender, argv[3] );
-               client_send_message( client, send );
-               message_free( recv );
-               message_free( send );
-       }
-       return 0;
-
-}
-
-
-
-
diff --git a/src/libtransport/transport_client.c b/src/libtransport/transport_client.c
deleted file mode 100644 (file)
index a318127..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-#include "transport_client.h"
-
-
-//int main( int argc, char** argv );
-
-/*
-int main( int argc, char** argv ) {
-
-       transport_message* recv;
-       transport_message* send;
-
-       transport_client* client = client_init( "spacely.georgialibraries.org", 5222 );
-
-       // try to connect, allow 15 second connect timeout 
-       if( client_connect( client, "admin", "asdfjkjk", "system", 15 ) ) {
-               printf("Connected...\n");
-       } else { 
-               printf( "NOT Connected...\n" ); exit(99); 
-       }
-
-       while( (recv = client_recv( client, -1 )) ) {
-
-               if( recv->body ) {
-                       int len = strlen(recv->body);
-                       char buf[len + 20];
-                       memset( buf, 0, len + 20); 
-                       sprintf( buf, "Echoing...%s", recv->body );
-                       send = message_init( buf, "Echoing Stuff", "12345", recv->sender, "" );
-               } else {
-                       send = message_init( " * ECHOING * ", "Echoing Stuff", "12345", recv->sender, "" );
-               }
-
-               if( send == NULL ) { printf("something's wrong"); }
-               client_send_message( client, send );
-                               
-               message_free( send );
-               message_free( recv );
-       }
-
-       printf( "ended recv loop\n" );
-
-       return 0;
-
-}
-*/
-
-
-transport_client* client_init( const char* server, int port, const char* unix_path, int component ) {
-
-       if(server == NULL) return NULL;
-
-       /* build and clear the client object */
-       size_t c_size = sizeof( transport_client);
-       transport_client* client = safe_malloc( c_size );
-
-       /* build and clear the message list */
-       size_t l_size = sizeof( transport_message_list );
-       client->m_list = safe_malloc( l_size );
-
-       client->m_list->next = NULL;
-       client->m_list->message = NULL;
-       client->m_list->type = MESSAGE_LIST_HEAD;
-
-       /* build the session */
-       
-       client->session = init_transport( server, port, unix_path, client, component );
-
-       client->session->message_callback = client_message_handler;
-       client->error = 0;
-
-       return client;
-}
-
-
-int client_connect( transport_client* client, 
-               char* username, char* password, char* resource, 
-               int connect_timeout, enum TRANSPORT_AUTH_TYPE  auth_type ) {
-       if(client == NULL) return 0; 
-       return session_connect( client->session, username, 
-                       password, resource, connect_timeout, auth_type );
-}
-
-
-int client_disconnect( transport_client* client ) {
-       if( client == NULL ) { return 0; }
-       return session_disconnect( client->session );
-}
-
-int client_connected( transport_client* client ) {
-       if(client == NULL) return 0;
-       return client->session->state_machine->connected;
-}
-
-int client_send_message( transport_client* client, transport_message* msg ) {
-       if(client == NULL) return 0;
-       if( client->error ) return -1;
-       return session_send_msg( client->session, msg );
-}
-
-
-transport_message* client_recv( transport_client* client, int timeout ) {
-       if( client == NULL ) { return NULL; }
-
-       transport_message_node* node;
-       transport_message* msg;
-
-
-       /* see if there are any message in the messages queue */
-       if( client->m_list->next != NULL ) {
-               /* pop off the first one... */
-               node = client->m_list->next;
-               client->m_list->next = node->next;
-               msg = node->message;
-               free( node );
-               return msg;
-       }
-
-       if( timeout == -1 ) {  /* wait potentially forever for data to arrive */
-
-               while( client->m_list->next == NULL ) {
-               //      if( ! session_wait( client->session, -1 ) ) {
-                       int x;
-                       if( (x = session_wait( client->session, -1 )) ) {
-                               osrfLogDebug(OSRF_LOG_MARK, "session_wait returned failure code %d\n", x);
-                               client->error = 1;
-                               return NULL;
-                       }
-               }
-
-       } else { /* wait at most timeout seconds */
-
-       
-               /* if not, loop up to 'timeout' seconds waiting for data to arrive */
-               time_t start = time(NULL);      
-               time_t remaining = (time_t) timeout;
-
-               int counter = 0;
-
-               int wait_ret;
-               while( client->m_list->next == NULL && remaining >= 0 ) {
-
-                       if( (wait_ret= session_wait( client->session, remaining)) ) {
-                               client->error = 1;
-                               osrfLogDebug(OSRF_LOG_MARK, "session_wait returned failure code %d: setting error=1\n", wait_ret);
-                               return NULL;
-                       }
-
-                       ++counter;
-
-#ifdef _ROUTER
-                       // session_wait returns -1 if there is no more data and we're a router
-                       if( remaining == 0 ) { // && wait_ret == -1 ) {
-                               break;
-                       }
-#else
-                       if( remaining == 0 ) // or infinite loop
-                               break;
-#endif
-
-                       remaining -= (int) (time(NULL) - start);
-               }
-
-       }
-
-       /* again, see if there are any messages in the message queue */
-       if( client->m_list->next != NULL ) {
-               /* pop off the first one... */
-               node = client->m_list->next;
-               client->m_list->next = node->next;
-               msg = node->message;
-               free( node );
-               return msg;
-
-       } else {
-               return NULL;
-       }
-}
-
-/* throw the message into the message queue */
-void client_message_handler( void* client, transport_message* msg ){
-
-       if(client == NULL) return;
-       if(msg == NULL) return; 
-
-       transport_client* cli = (transport_client*) client;
-
-       size_t len = sizeof(transport_message_node);
-       transport_message_node* node = 
-               (transport_message_node*) safe_malloc(len);
-       node->type = MESSAGE_LIST_ITEM;
-       node->message = msg;
-
-
-       /* find the last node and put this onto the end */
-       transport_message_node* tail = cli->m_list;
-       transport_message_node* current = tail->next;
-
-       while( current != NULL ) {
-               tail = current;
-               current = current->next;
-       }
-       tail->next = node;
-}
-
-
-int client_free( transport_client* client ){
-       if(client == NULL) return 0; 
-
-       session_free( client->session );
-       transport_message_node* current = client->m_list->next;
-       transport_message_node* next;
-
-       /* deallocate the list of messages */
-       while( current != NULL ) {
-               next = current->next;
-               message_free( current->message );
-               free(current);
-               current = next;
-       }
-
-       free( client->m_list );
-       free( client );
-       return 1;
-}
-
diff --git a/src/libtransport/transport_client.h b/src/libtransport/transport_client.h
deleted file mode 100644 (file)
index 50a2c66..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "transport_session.h"
-#include "opensrf/utils.h"
-#include "opensrf/log.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;
-       int error;
-};
-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.
-// if port > 0 => connect via TCP
-// else if unix_path != NULL => connect via UNIX socket
-// ---------------------------------------------------------------------------
-transport_client* client_init( const char* server, int port, const char* unix_path, 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
diff --git a/src/libtransport/transport_message.c b/src/libtransport/transport_message.c
deleted file mode 100644 (file)
index f0e63af..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-#include "transport_message.h"
-
-
-// ---------------------------------------------------------------------------------
-// Allocates and initializes a new transport_message
-// ---------------------------------------------------------------------------------
-transport_message* message_init( char* body, 
-               char* subject, char* thread, char* recipient, char* sender ) {
-
-       transport_message* msg = 
-               (transport_message*) safe_malloc( sizeof(transport_message) );
-
-       if( body                                        == NULL ) { body                        = ""; }
-       if( thread                              == NULL ) { thread              = ""; }
-       if( subject                             == NULL ) { subject             = ""; }
-       if( sender                              == NULL ) { sender              = ""; }
-       if( recipient                   ==      NULL ) { recipient      = ""; }
-
-       msg->body                               = strdup(body);
-       msg->thread                             = strdup(thread);
-       msg->subject                    = strdup(subject);
-       msg->recipient                  = strdup(recipient);
-       msg->sender                             = strdup(sender);
-
-       if(     msg->body               == NULL || msg->thread                          == NULL ||
-                       msg->subject    == NULL || msg->recipient                       == NULL ||
-                       msg->sender             == NULL ) {
-
-               osrfLogError(OSRF_LOG_MARK,  "message_init(): Out of Memory" );
-               return NULL;
-       }
-
-       return msg;
-}
-
-
-transport_message* new_message_from_xml( const char* msg_xml ) {
-
-       if( msg_xml == NULL || strlen(msg_xml) < 1 )
-               return NULL;
-
-       transport_message* new_msg = 
-               (transport_message*) safe_malloc( sizeof(transport_message) );
-
-       xmlKeepBlanksDefault(0);
-       xmlDocPtr msg_doc = xmlReadDoc( BAD_CAST msg_xml, NULL, NULL, 0 );
-       xmlNodePtr root = xmlDocGetRootElement(msg_doc);
-
-       xmlChar* sender = xmlGetProp(root, BAD_CAST "from");
-       xmlChar* recipient      = xmlGetProp(root, BAD_CAST "to");
-       xmlChar* subject                = xmlGetProp(root, BAD_CAST "subject");
-       xmlChar* thread         = xmlGetProp( root, BAD_CAST "thread" );
-       xmlChar* router_from    = xmlGetProp( root, BAD_CAST "router_from" );
-       xmlChar* router_to      = xmlGetProp( root, BAD_CAST "router_to" );
-       xmlChar* router_class= xmlGetProp( root, BAD_CAST "router_class" );
-       xmlChar* broadcast      = xmlGetProp( root, BAD_CAST "broadcast" );
-   xmlChar* osrf_xid    = xmlGetProp( root, BAD_CAST "osrf_xid" );
-
-   if( osrf_xid ) {
-      message_set_osrf_xid( new_msg, (char*) osrf_xid);
-      xmlFree(osrf_xid);
-   }
-
-       if( router_from ) {
-               new_msg->sender         = strdup((char*)router_from);
-       } else {
-               if( sender ) {
-                       new_msg->sender         = strdup((char*)sender);
-                       xmlFree(sender);
-               }
-       }
-
-       if( recipient ) {
-               new_msg->recipient      = strdup((char*)recipient);
-               xmlFree(recipient);
-       }
-       if(subject){
-               new_msg->subject                = strdup((char*)subject);
-               xmlFree(subject);
-       }
-       if(thread) {
-               new_msg->thread         = strdup((char*)thread);
-               xmlFree(thread);
-       }
-       if(router_from) {
-               new_msg->router_from    = strdup((char*)router_from);
-               xmlFree(router_from);
-       }
-       if(router_to) {
-               new_msg->router_to      = strdup((char*)router_to);
-               xmlFree(router_to);
-       }
-       if(router_class) {
-               new_msg->router_class = strdup((char*)router_class);
-               xmlFree(router_class);
-       }
-       if(broadcast) {
-               if(strcmp(broadcast,"0") )
-                       new_msg->broadcast      = 1;
-               xmlFree(broadcast);
-       }
-
-       xmlNodePtr search_node = root->children;
-       while( search_node != NULL ) {
-
-               if( ! strcmp( (char*) search_node->name, "thread" ) ) {
-                       if( search_node->children && search_node->children->content ) 
-                               new_msg->thread = strdup( (char*) search_node->children->content );
-               }
-
-               if( ! strcmp( (char*) search_node->name, "subject" ) ) {
-                       if( search_node->children && search_node->children->content )
-                               new_msg->subject = strdup( (char*) search_node->children->content );
-               }
-
-               if( ! strcmp( (char*) search_node->name, "body" ) ) {
-                       if( search_node->children && search_node->children->content )
-                               new_msg->body = strdup((char*) search_node->children->content );
-               }
-
-               search_node = search_node->next;
-       }
-
-       if( new_msg->thread == NULL ) 
-               new_msg->thread = strdup("");
-       if( new_msg->subject == NULL )
-               new_msg->subject = strdup("");
-       if( new_msg->body == NULL )
-               new_msg->body = strdup("");
-
-       new_msg->msg_xml = xmlDocToString(msg_doc, 0);
-   xmlFreeDoc(msg_doc);
-   xmlCleanupParser();
-
-       return new_msg;
-}
-
-void message_set_osrf_xid( transport_message* msg, char* osrf_xid ) {
-   if(!msg) return;
-   if( osrf_xid )
-      msg->osrf_xid = strdup(osrf_xid);
-   else msg->osrf_xid = strdup("");
-}
-
-void message_set_router_info( transport_message* msg, char* router_from,
-               char* router_to, char* router_class, char* router_command, int broadcast_enabled ) {
-
-       if(router_from)
-               msg->router_from                = strdup(router_from);
-       else
-               msg->router_from                = strdup("");
-
-       if(router_to)
-               msg->router_to                  = strdup(router_to);
-       else
-               msg->router_to                  = strdup("");
-
-       if(router_class)
-               msg->router_class               = strdup(router_class);
-       else 
-               msg->router_class               = strdup("");
-       
-       if(router_command)
-               msg->router_command     = strdup(router_command);
-       else
-               msg->router_command     = strdup("");
-
-       msg->broadcast = broadcast_enabled;
-
-       if( msg->router_from == NULL || msg->router_to == NULL ||
-                       msg->router_class == NULL || msg->router_command == NULL ) 
-               osrfLogError(OSRF_LOG_MARK,  "message_set_router_info(): Out of Memory" );
-
-       return;
-}
-
-
-
-/* encodes the message for traversal */
-int message_prepare_xml( transport_message* msg ) {
-       if( msg->msg_xml != NULL ) { return 1; }
-       msg->msg_xml = message_to_xml( msg );
-       return 1;
-}
-
-
-// ---------------------------------------------------------------------------------
-//
-// ---------------------------------------------------------------------------------
-int message_free( transport_message* msg ){
-       if( msg == NULL ) { return 0; }
-
-       free(msg->body); 
-       free(msg->thread);
-       free(msg->subject);
-       free(msg->recipient);
-       free(msg->sender);
-       free(msg->router_from);
-       free(msg->router_to);
-       free(msg->router_class);
-       free(msg->router_command);
-   free(msg->osrf_xid);
-       if( msg->error_type != NULL ) free(msg->error_type);
-       if( msg->msg_xml != NULL ) free(msg->msg_xml);
-       free(msg);
-       return 1;
-}
-       
-// ---------------------------------------------------------------------------------
-// Allocates a char* holding the XML representation of this jabber message
-// ---------------------------------------------------------------------------------
-char* message_to_xml( const transport_message* msg ) {
-
-       int                     bufsize;
-       //xmlChar*              xmlbuf;
-       char*                   encoded_body;
-
-       xmlNodePtr      message_node;
-       xmlNodePtr      body_node;
-       xmlNodePtr      thread_node;
-       xmlNodePtr      subject_node;
-       xmlNodePtr      error_node;
-       
-       xmlDocPtr       doc;
-
-       xmlKeepBlanksDefault(0);
-
-       if( ! msg ) { 
-               osrfLogWarning(OSRF_LOG_MARK,  "Passing NULL message to message_to_xml()"); 
-               return 0; 
-       }
-
-       doc = xmlReadDoc( BAD_CAST "<message/>", NULL, NULL, XML_PARSE_NSCLEAN );
-       message_node = xmlDocGetRootElement(doc);
-
-       if( msg->is_error ) {
-               error_node = xmlNewChild(message_node, NULL, BAD_CAST "error" , NULL );
-               xmlAddChild( message_node, error_node );
-               xmlNewProp( error_node, BAD_CAST "type", BAD_CAST msg->error_type );
-               char code_buf[16];
-               memset( code_buf, 0, 16);
-               sprintf(code_buf, "%d", msg->error_code );
-               xmlNewProp( error_node, BAD_CAST "code", BAD_CAST code_buf  );
-       }
-
-       /* set from and to */
-       xmlNewProp( message_node, BAD_CAST "to", BAD_CAST msg->recipient );
-       xmlNewProp( message_node, BAD_CAST "from", BAD_CAST msg->sender );
-       xmlNewProp( message_node, BAD_CAST "router_from", BAD_CAST msg->router_from );
-       xmlNewProp( message_node, BAD_CAST "router_to", BAD_CAST msg->router_to );
-       xmlNewProp( message_node, BAD_CAST "router_class", BAD_CAST msg->router_class );
-       xmlNewProp( message_node, BAD_CAST "router_command", BAD_CAST msg->router_command );
-       xmlNewProp( message_node, BAD_CAST "osrf_xid", BAD_CAST msg->osrf_xid );
-
-       if( msg->broadcast )
-               xmlNewProp( message_node, BAD_CAST "broadcast", BAD_CAST "1" );
-
-       /* Now add nodes where appropriate */
-       char* body                              = msg->body;
-       char* subject                   = msg->subject;
-       char* thread                    = msg->thread; 
-
-       if( thread && strlen(thread) > 0 ) {
-               thread_node = xmlNewChild(message_node, NULL, (xmlChar*) "thread", NULL );
-               xmlNodePtr txt = xmlNewText((xmlChar*) thread);
-               xmlAddChild(thread_node, txt);
-               xmlAddChild(message_node, thread_node); 
-       }
-
-       if( subject && strlen(subject) > 0 ) {
-               subject_node = xmlNewChild(message_node, NULL, (xmlChar*) "subject", NULL );
-               xmlNodePtr txt = xmlNewText((xmlChar*) subject);
-               xmlAddChild(subject_node, txt);
-               xmlAddChild( message_node, subject_node ); 
-       }
-
-       if( body && strlen(body) > 0 ) {
-               body_node = xmlNewChild(message_node, NULL, (xmlChar*) "body", NULL);
-               xmlNodePtr txt = xmlNewText((xmlChar*) body);
-               xmlAddChild(body_node, txt);
-               xmlAddChild( message_node, body_node ); 
-       }
-
-       xmlBufferPtr xmlbuf = xmlBufferCreate();
-       xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
-       char* xml = strdup((char*) (xmlBufferContent(xmlbuf)));
-       xmlBufferFree(xmlbuf);
-       xmlFreeDoc( doc );               
-       xmlCleanupParser();
-       return xml;
-}
-
-
-
-void jid_get_username( const char* jid, char buf[], int size ) {
-
-       if( jid == NULL ) { return; }
-
-       /* find the @ and return whatever is in front of it */
-       int len = strlen( jid );
-       int i;
-       for( i = 0; i != len; i++ ) {
-               if( jid[i] == 64 ) { /*ascii @*/
-                       if(i > size)  i = size;
-                       strncpy( buf, jid, i );
-                       return;
-               }
-       }
-}
-
-
-void jid_get_resource( const char* jid, char buf[], int size)  {
-       if( jid == NULL ) { return; }
-       int len = strlen( jid );
-       int i;
-       for( i = 0; i!= len; i++ ) {
-               if( jid[i] == 47 ) { /* ascii / */
-                       const char* start = jid + i + 1; /* right after the '/' */
-                       int rlen = len - (i+1);
-                       if(rlen > size) rlen = size;
-                       strncpy( buf, start, rlen );
-               }
-       }
-}
-
-void jid_get_domain( const char* jid, char buf[], int size ) {
-
-       if(jid == NULL) return;
-
-       int len = strlen(jid);
-       int i;
-       int index1 = 0; 
-       int index2 = 0;
-
-       for( i = 0; i!= len; i++ ) {
-               if(jid[i] == 64) /* ascii @ */
-                       index1 = i + 1;
-               else if(jid[i] == 47 && index1 != 0) /* ascii / */
-                       index2 = i;
-       }
-
-       if( index1 > 0 && index2 > 0 && index2 > index1 ) {
-               int dlen = index2 - index1;
-               if(dlen > size) dlen = size;
-               memcpy( buf, jid + index1, dlen );
-       }
-}
-
-void set_msg_error( transport_message* msg, char* type, int err_code ) {
-
-       if( type != NULL && strlen( type ) > 0 ) {
-               msg->error_type = safe_malloc( strlen(type)+1); 
-               strcpy( msg->error_type, type );
-               msg->error_code = err_code;
-       }
-       msg->is_error = 1;
-}
diff --git a/src/libtransport/transport_message.h b/src/libtransport/transport_message.h
deleted file mode 100644 (file)
index 4e94e24..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-#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>
-
-#include "opensrf/utils.h"
-#include "opensrf/xml_utils.h"
-#include "opensrf/log.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;
-   char* osrf_xid;
-       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 );
-
-void message_set_osrf_xid( transport_message* msg, char* osrf_xid );
-
-// ---------------------------------------------------------------------------------
-// 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[], int size );
-
-// ---------------------------------------------------------------------------------
-// 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[], int size );
-
-/** Puts the domain portion of the given jid into the pre-allocated buffer */
-void jid_get_domain( const char* jid, char buf[], int size );
-
-void set_msg_error( transport_message*, char* error_type, int error_code);
-
-
-#endif
diff --git a/src/libtransport/transport_session.c b/src/libtransport/transport_session.c
deleted file mode 100644 (file)
index c62306c..0000000
+++ /dev/null
@@ -1,635 +0,0 @@
-#include "transport_session.h"
-
-
-
-// ---------------------------------------------------------------------------------
-// returns a built and allocated transport_session object.
-// This codes does no network activity, only memory initilization
-// ---------------------------------------------------------------------------------
-transport_session* init_transport(  const char* server, 
-       int port, const char* unix_path, void* user_data, int component ) {
-
-       /* create the session struct */
-       transport_session* session = 
-               (transport_session*) safe_malloc( sizeof(transport_session) );
-
-       session->user_data = user_data;
-
-       session->component = component;
-
-       /* initialize the data buffers */
-       session->body_buffer                    = buffer_init( JABBER_BODY_BUFSIZE );
-       session->subject_buffer         = buffer_init( JABBER_SUBJECT_BUFSIZE );
-       session->thread_buffer          = buffer_init( JABBER_THREAD_BUFSIZE );
-       session->from_buffer                    = buffer_init( JABBER_JID_BUFSIZE );
-       session->status_buffer          = buffer_init( JABBER_STATUS_BUFSIZE );
-       session->recipient_buffer       = buffer_init( JABBER_JID_BUFSIZE );
-       session->message_error_type = buffer_init( JABBER_JID_BUFSIZE );
-       session->session_id                     = buffer_init( 64 ); 
-
-       /* for OpenSRF extensions */
-       session->router_to_buffer               = buffer_init( JABBER_JID_BUFSIZE );
-       session->router_from_buffer     = buffer_init( JABBER_JID_BUFSIZE );
-       session->osrf_xid_buffer        = buffer_init( JABBER_JID_BUFSIZE );
-       session->router_class_buffer    = buffer_init( JABBER_JID_BUFSIZE );
-       session->router_command_buffer  = buffer_init( JABBER_JID_BUFSIZE );
-
-
-       if(     session->body_buffer            == NULL || session->subject_buffer       == NULL        ||
-                       session->thread_buffer  == NULL || session->from_buffer          == NULL        ||
-                       session->status_buffer  == NULL || session->recipient_buffer == NULL ||
-                       session->router_to_buffer       == NULL || session->router_from_buffer   == NULL ||
-                       session->router_class_buffer == NULL || session->router_command_buffer == NULL ||
-                       session->session_id == NULL ) { 
-
-               osrfLogError(OSRF_LOG_MARK,  "init_transport(): buffer_init returned NULL" );
-               return 0;
-       }
-
-
-       /* initialize the jabber state machine */
-       session->state_machine = (jabber_machine*) safe_malloc( sizeof(jabber_machine) );
-
-       /* initialize the sax push parser */
-       session->parser_ctxt = xmlCreatePushParserCtxt(SAXHandler, session, "", 0, NULL);
-
-       /* initialize the transport_socket structure */
-       session->sock_mgr = (socket_manager*) safe_malloc( sizeof(socket_manager) );
-
-       session->sock_mgr->data_received = &grab_incoming;
-       session->sock_mgr->blob = session;
-       
-       session->port = port;
-       session->server = strdup(server);
-       if(unix_path)   
-               session->unix_path = strdup(unix_path);
-       else session->unix_path = NULL;
-
-       session->sock_id = 0;
-
-       return session;
-}
-
-
-
-/* XXX FREE THE BUFFERS */
-int session_free( transport_session* session ) {
-       if( ! session ) { return 0; }
-
-       if(session->sock_mgr)
-               socket_manager_free(session->sock_mgr);
-
-       if( session->state_machine ) free( session->state_machine );
-       if( session->parser_ctxt) {
-               xmlFreeDoc( session->parser_ctxt->myDoc );
-               xmlFreeParserCtxt(session->parser_ctxt);
-       }
-
-       xmlCleanupCharEncodingHandlers();
-       xmlDictCleanup();
-       xmlCleanupParser();
-
-       buffer_free(session->body_buffer);
-       buffer_free(session->subject_buffer);
-       buffer_free(session->thread_buffer);
-       buffer_free(session->from_buffer);
-       buffer_free(session->recipient_buffer);
-       buffer_free(session->status_buffer);
-       buffer_free(session->message_error_type);
-       buffer_free(session->router_to_buffer);
-       buffer_free(session->router_from_buffer);
-       buffer_free(session->osrf_xid_buffer);
-       buffer_free(session->router_class_buffer);
-       buffer_free(session->router_command_buffer);
-       buffer_free(session->session_id);
-
-       free(session->server);
-       free(session->unix_path);
-
-       free( session );
-       return 1;
-}
-
-
-int session_wait( transport_session* session, int timeout ) {
-       if( ! session || ! session->sock_mgr ) {
-               return 0;
-       }
-
-       int ret =  socket_wait( session->sock_mgr, timeout, session->sock_id );
-
-       if( ret ) {
-               osrfLogDebug(OSRF_LOG_MARK, "socket_wait returned error code %d", ret);
-               session->state_machine->connected = 0;
-       }
-       return ret;
-}
-
-int session_send_msg( 
-               transport_session* session, transport_message* msg ) {
-
-       if( ! session ) { return -1; }
-
-       if( ! session->state_machine->connected ) {
-               osrfLogWarning(OSRF_LOG_MARK, "State machine is not connected in send_msg()");
-               return -1;
-       }
-
-       message_prepare_xml( msg );
-       //tcp_send( session->sock_obj, msg->msg_xml );
-       return socket_send( session->sock_id, msg->msg_xml );
-
-}
-
-
-/* connects to server and connects to jabber */
-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 size1 = 0;
-       int size2 = 0;
-
-       if( ! session ) { 
-               osrfLogWarning(OSRF_LOG_MARK,  "session is null in connect" );
-               return 0; 
-       }
-
-
-       //char* server = session->sock_obj->server;
-       char* server = session->server;
-
-       if( ! session->sock_id ) {
-
-               if(session->port > 0) {
-                       if( (session->sock_id = socket_open_tcp_client(
-                               session->sock_mgr, session->port, session->server)) <= 0 ) 
-                       return 0;
-
-               } else if(session->unix_path != NULL) {
-                       if( (session->sock_id = socket_open_unix_client(
-                               session->sock_mgr, session->unix_path)) <= 0 ) 
-                       return 0;
-               }
-               else {
-                       osrfLogWarning( OSRF_LOG_MARK, "Can't open session: no port or unix path" );
-                       return 0;
-               }
-       }
-
-       if( session->component ) {
-
-               /* the first Jabber connect stanza */
-               char* our_hostname = getenv("HOSTNAME");
-               size1 = 150 + strlen( server );
-               char stanza1[ size1 ]; 
-               memset( stanza1, 0, size1 );
-               sprintf( stanza1, 
-                               "<stream:stream version='1.0' xmlns:stream='http://etherx.jabber.org/streams' "
-                               "xmlns='jabber:component:accept' to='%s' from='%s' xml:lang='en'>",
-                               username, our_hostname );
-
-               /* send the first stanze */
-               session->state_machine->connecting = CONNECTING_1;
-
-//             if( ! tcp_send( session->sock_obj, stanza1 ) ) {
-               if( socket_send( session->sock_id, stanza1 ) ) {
-                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
-                       return 0;
-               }
-       
-               /* wait for reply */
-               //tcp_wait( session->sock_obj, connect_timeout ); /* make the timeout smarter XXX */
-               socket_wait(session->sock_mgr, connect_timeout, session->sock_id);
-       
-               /* server acknowledges our existence, now see if we can login */
-               if( session->state_machine->connecting == CONNECTING_2 ) {
-       
-                       int ss = session->session_id->n_used + strlen(password) + 5;
-                       char hashstuff[ss];
-                       memset(hashstuff,0,ss);
-                       sprintf( hashstuff, "%s%s", session->session_id->buf, password );
-
-                       char* hash = shahash( hashstuff );
-                       size2 = 100 + strlen( hash );
-                       char stanza2[ size2 ];
-                       memset( stanza2, 0, size2 );
-                       sprintf( stanza2, "<handshake>%s</handshake>", hash );
-       
-                       //if( ! tcp_send( session->sock_obj, stanza2 )  ) {
-                       if( socket_send( session->sock_id, stanza2 )  ) {
-                               osrfLogWarning(OSRF_LOG_MARK, "error sending");
-                               return 0;
-                       }
-               }
-
-       } else { /* we're not a component */
-
-               /* the first Jabber connect stanza */
-               size1 = 100 + strlen( server );
-               char stanza1[ size1 ]; 
-               memset( stanza1, 0, size1 );
-               sprintf( stanza1, 
-                               "<stream:stream to='%s' xmlns='jabber:client' "
-                               "xmlns:stream='http://etherx.jabber.org/streams'>",
-                       server );
-       
-
-               /* send the first stanze */
-               session->state_machine->connecting = CONNECTING_1;
-               //if( ! tcp_send( session->sock_obj, stanza1 ) ) {
-               if( socket_send( session->sock_id, stanza1 ) ) {
-                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
-                       return 0;
-               }
-
-
-               /* wait for reply */
-               //tcp_wait( session->sock_obj, connect_timeout ); /* make the timeout smarter XXX */
-               socket_wait( session->sock_mgr, connect_timeout, session->sock_id ); /* make the timeout smarter XXX */
-
-               if( auth_type == AUTH_PLAIN ) {
-
-                       /* the second jabber connect stanza including login info*/
-                       size2 = 150 + strlen( username ) + strlen(password) + strlen(resource);
-                       char stanza2[ size2 ];
-                       memset( stanza2, 0, size2 );
-               
-                       sprintf( stanza2, 
-                                       "<iq id='123456789' type='set'><query xmlns='jabber:iq:auth'>"
-                                       "<username>%s</username><password>%s</password><resource>%s</resource></query></iq>",
-                                       username, password, resource );
-       
-                       /* server acknowledges our existence, now see if we can login */
-                       if( session->state_machine->connecting == CONNECTING_2 ) {
-                               //if( ! tcp_send( session->sock_obj, stanza2 )  ) {
-                               if( socket_send( session->sock_id, stanza2 )  ) {
-                                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
-                                       return 0;
-                               }
-                       }
-
-               } else if( auth_type == AUTH_DIGEST ) {
-
-                       int ss = session->session_id->n_used + strlen(password) + 5;
-                       char hashstuff[ss];
-                       memset(hashstuff,0,ss);
-                       sprintf( hashstuff, "%s%s", session->session_id->buf, password );
-
-                       char* hash = shahash( hashstuff );
-
-                       /* the second jabber connect stanza including login info*/
-                       size2 = 150 + strlen( hash ) + strlen(password) + strlen(resource);
-                       char stanza2[ size2 ];
-                       memset( stanza2, 0, size2 );
-               
-                       sprintf( stanza2, 
-                                       "<iq id='123456789' type='set'><query xmlns='jabber:iq:auth'>"
-                                       "<username>%s</username><digest>%s</digest><resource>%s</resource></query></iq>",
-                                       username, hash, resource );
-       
-                       /* server acknowledges our existence, now see if we can login */
-                       if( session->state_machine->connecting == CONNECTING_2 ) {
-                               //if( ! tcp_send( session->sock_obj, stanza2 )  ) {
-                               if( socket_send( session->sock_id, stanza2 )  ) {
-                                       osrfLogWarning(OSRF_LOG_MARK, "error sending");
-                                       return 0;
-                               }
-                       }
-
-               }
-
-       } // not component
-
-
-       /* wait for reply */
-       //tcp_wait( session->sock_obj, connect_timeout );
-       socket_wait( session->sock_mgr, connect_timeout, session->sock_id );
-
-       if( session->state_machine->connected ) {
-               /* yar! */
-               return 1;
-       }
-
-       return 0;
-}
-
-// ---------------------------------------------------------------------------------
-// TCP data callback. Shove the data into the push parser.
-// ---------------------------------------------------------------------------------
-//void grab_incoming( void * session, char* data ) {
-void grab_incoming(void* blob, socket_manager* mgr, int sockid, char* data, int parent) {
-       transport_session* ses = (transport_session*) blob;
-       if( ! ses ) { return; }
-       xmlParseChunk(ses->parser_ctxt, data, strlen(data), 0);
-}
-
-
-void startElementHandler(
-       void *session, const xmlChar *name, const xmlChar **atts) {
-
-       transport_session* ses = (transport_session*) session;
-       if( ! ses ) { return; }
-
-       
-       if( strcmp( name, "message" ) == 0 ) {
-               ses->state_machine->in_message = 1;
-               buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) );
-               buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) );
-               buffer_add( ses->router_from_buffer, get_xml_attr( atts, "router_from" ) );
-               buffer_add( ses->osrf_xid_buffer, get_xml_attr( atts, "osrf_xid" ) );
-               buffer_add( ses->router_to_buffer, get_xml_attr( atts, "router_to" ) );
-               buffer_add( ses->router_class_buffer, get_xml_attr( atts, "router_class" ) );
-               buffer_add( ses->router_command_buffer, get_xml_attr( atts, "router_command" ) );
-               char* broadcast = get_xml_attr( atts, "broadcast" );
-               if( broadcast )
-                       ses->router_broadcast = atoi( broadcast );
-
-               return;
-       }
-
-       if( ses->state_machine->in_message ) {
-
-               if( strcmp( name, "body" ) == 0 ) {
-                       ses->state_machine->in_message_body = 1;
-                       return;
-               }
-       
-               if( strcmp( name, "subject" ) == 0 ) {
-                       ses->state_machine->in_subject = 1;
-                       return;
-               }
-       
-               if( strcmp( name, "thread" ) == 0 ) {
-                       ses->state_machine->in_thread = 1;
-                       return;
-               }
-
-       }
-
-       if( strcmp( name, "presence" ) == 0 ) {
-               ses->state_machine->in_presence = 1;
-               buffer_add( ses->from_buffer, get_xml_attr( atts, "from" ) );
-               buffer_add( ses->recipient_buffer, get_xml_attr( atts, "to" ) );
-               return;
-       }
-
-       if( strcmp( name, "status" ) == 0 ) {
-               ses->state_machine->in_status = 1;
-               return;
-       }
-
-
-       if( strcmp( name, "stream:error" ) == 0 ) {
-               ses->state_machine->in_error = 1;
-               ses->state_machine->connected = 0;
-               osrfLogWarning(  OSRF_LOG_MARK, "Received <stream:error> message from Jabber server" );
-               return;
-       }
-
-
-       /* first server response from a connect attempt */
-       if( strcmp( name, "stream:stream" ) == 0 ) {
-               if( ses->state_machine->connecting == CONNECTING_1 ) {
-                       ses->state_machine->connecting = CONNECTING_2;
-                       buffer_add( ses->session_id, get_xml_attr(atts, "id") );
-               }
-       }
-
-       if( strcmp( name, "handshake" ) == 0 ) {
-               ses->state_machine->connected = 1;
-               ses->state_machine->connecting = 0;
-               return;
-       }
-
-
-       if( strcmp( name, "error" ) == 0 ) {
-               ses->state_machine->in_message_error = 1;
-               buffer_add( ses->message_error_type, get_xml_attr( atts, "type" ) );
-               ses->message_error_code = atoi( get_xml_attr( atts, "code" ) );
-               osrfLogInfo( OSRF_LOG_MARK,  "Received <error> message with type %s and code %s", 
-                       get_xml_attr( atts, "type"), get_xml_attr( atts, "code") );
-               return;
-       }
-
-       if( strcmp( name, "iq" ) == 0 ) {
-               ses->state_machine->in_iq = 1;
-
-               if( strcmp( get_xml_attr(atts, "type"), "result") == 0 
-                               && ses->state_machine->connecting == CONNECTING_2 ) {
-                       ses->state_machine->connected = 1;
-                       ses->state_machine->connecting = 0;
-                       return;
-               }
-
-               if( strcmp( get_xml_attr(atts, "type"), "error") == 0 ) {
-                       osrfLogWarning( OSRF_LOG_MARK,  "Error connecting to jabber" );
-                       return;
-               }
-       }
-}
-
-char* get_xml_attr( const xmlChar** atts, char* attr_name ) {
-       int i;
-       if (atts != NULL) {
-               for(i = 0;(atts[i] != NULL);i++) {
-                       if( strcmp( atts[i++], attr_name ) == 0 ) {
-                               if( atts[i] != NULL ) {
-                                       return (char*) atts[i];
-                               }
-                       }
-               }
-       }
-       return NULL;
-}
-
-
-// ------------------------------------------------------------------
-// See which tags are ending
-// ------------------------------------------------------------------
-void endElementHandler( void *session, const xmlChar *name) {
-       transport_session* ses = (transport_session*) session;
-       if( ! ses ) { return; }
-
-       if( strcmp( name, "message" ) == 0 ) {
-
-
-               /* pass off the message info the callback */
-               if( ses->message_callback ) {
-
-                       /* here it's ok to pass in the raw buffers because
-                               message_init allocates new space for the chars 
-                               passed in */
-                       transport_message* msg =  message_init( 
-                               ses->body_buffer->buf, 
-                               ses->subject_buffer->buf,
-                               ses->thread_buffer->buf, 
-                               ses->recipient_buffer->buf, 
-                               ses->from_buffer->buf );
-
-                       message_set_router_info( msg, 
-                               ses->router_from_buffer->buf, 
-                               ses->router_to_buffer->buf, 
-                               ses->router_class_buffer->buf,
-                               ses->router_command_buffer->buf,
-                               ses->router_broadcast );
-
-         message_set_osrf_xid( msg, ses->osrf_xid_buffer->buf );
-
-                       if( ses->message_error_type->n_used > 0 ) {
-                               set_msg_error( msg, ses->message_error_type->buf, ses->message_error_code );
-                       }
-
-                       if( msg == NULL ) { return; }
-                       ses->message_callback( ses->user_data, msg );
-               }
-
-               ses->state_machine->in_message = 0;
-               reset_session_buffers( session );
-               return;
-       }
-       
-       if( strcmp( name, "body" ) == 0 ) {
-               ses->state_machine->in_message_body = 0;
-               return;
-       }
-
-       if( strcmp( name, "subject" ) == 0 ) {
-               ses->state_machine->in_subject = 0;
-               return;
-       }
-
-       if( strcmp( name, "thread" ) == 0 ) {
-               ses->state_machine->in_thread = 0;
-               return;
-       }
-       
-       if( strcmp( name, "iq" ) == 0 ) {
-               ses->state_machine->in_iq = 0;
-               if( ses->message_error_code > 0 ) {
-                       osrfLogWarning( OSRF_LOG_MARK,  "Error in IQ packet: code %d",  ses->message_error_code );
-                       osrfLogWarning( OSRF_LOG_MARK,  "Error 401 means not authorized" );
-               }
-               reset_session_buffers( session );
-               return;
-       }
-
-       if( strcmp( name, "presence" ) == 0 ) {
-               ses->state_machine->in_presence = 0;
-               /*
-               if( ses->presence_callback ) {
-                       // call the callback with the status, etc.
-               }
-               */
-               reset_session_buffers( session );
-               return;
-       }
-
-       if( strcmp( name, "status" ) == 0 ) {
-               ses->state_machine->in_status = 0;
-               return;
-       }
-
-       if( strcmp( name, "error" ) == 0 ) {
-               ses->state_machine->in_message_error = 0;
-               return;
-       }
-
-       if( strcmp( name, "error:error" ) == 0 ) {
-               ses->state_machine->in_error = 0;
-               return;
-       }
-}
-
-int reset_session_buffers( transport_session* ses ) {
-       buffer_reset( ses->body_buffer );
-       buffer_reset( ses->subject_buffer );
-       buffer_reset( ses->thread_buffer );
-       buffer_reset( ses->from_buffer );
-       buffer_reset( ses->recipient_buffer );
-       buffer_reset( ses->router_from_buffer );
-       buffer_reset( ses->osrf_xid_buffer );
-       buffer_reset( ses->router_to_buffer );
-       buffer_reset( ses->router_class_buffer );
-       buffer_reset( ses->router_command_buffer );
-       buffer_reset( ses->message_error_type );
-       buffer_reset( ses->session_id );
-
-       return 1;
-}
-
-// ------------------------------------------------------------------
-// takes data out of the body of the message and pushes it into
-// the appropriate buffer
-// ------------------------------------------------------------------
-void characterHandler(
-               void *session, const xmlChar *ch, int len) {
-
-       char data[len+1];
-       memset( data, 0, len+1 );
-       strncpy( data, (char*) ch, len );
-       data[len] = 0;
-
-       //printf( "Handling characters: %s\n", data );
-       transport_session* ses = (transport_session*) session;
-       if( ! ses ) { return; }
-
-       /* set the various message parts */
-       if( ses->state_machine->in_message ) {
-
-               if( ses->state_machine->in_message_body ) {
-                       buffer_add( ses->body_buffer, data );
-               }
-
-               if( ses->state_machine->in_subject ) {
-                       buffer_add( ses->subject_buffer, data );
-               }
-
-               if( ses->state_machine->in_thread ) {
-                       buffer_add( ses->thread_buffer, data );
-               }
-       }
-
-       /* set the presence status */
-       if( ses->state_machine->in_presence && ses->state_machine->in_status ) {
-               buffer_add( ses->status_buffer, data );
-       }
-
-       if( ses->state_machine->in_error ) {
-               /* for now... */
-               osrfLogWarning( OSRF_LOG_MARK,  "ERROR Xml fragment: %s\n", ch );
-       }
-
-}
-
-/* XXX change to warning handlers */
-void  parseWarningHandler( void *session, const char* msg, ... ) {
-
-       va_list args;
-       va_start(args, msg);
-       fprintf(stdout, "transport_session XML WARNING");
-       vfprintf(stdout, msg, args);
-       va_end(args);
-       fprintf(stderr, "XML WARNING: %s\n", msg ); 
-}
-
-void  parseErrorHandler( void *session, const char* msg, ... ){
-
-       va_list args;
-       va_start(args, msg);
-       fprintf(stdout, "transport_session XML ERROR");
-       vfprintf(stdout, msg, args);
-       va_end(args);
-       fprintf(stderr, "XML ERROR: %s\n", msg ); 
-
-}
-
-int session_disconnect( transport_session* session ) {
-       if( session == NULL ) { return 0; }
-       //tcp_send( session->sock_obj, "</stream:stream>");
-       socket_send(session->sock_id, "</stream:stream>");
-       socket_disconnect(session->sock_mgr, session->sock_id);
-       return 0;
-       //return tcp_disconnect( session->sock_obj );
-}
-
diff --git a/src/libtransport/transport_session.h b/src/libtransport/transport_session.h
deleted file mode 100644 (file)
index 78d108b..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-// ---------------------------------------------------------------------------------
-// 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_message.h"
-
-#include "opensrf/utils.h"
-#include "opensrf/log.h"
-#include "opensrf/socket_bundle.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 );
-void grab_incoming(void* blob, socket_manager* mgr, int sockid, char* data, int parent);
-
-// ---------------------------------------------------------------------------------
-// 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;
-       socket_manager* sock_mgr;
-
-       /* 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;
-       growing_buffer* osrf_xid_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;
-
-       char* server;
-       char* unix_path;
-       int     port;
-       int sock_id;
-
-       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.
-// If port > 0, then this session uses  TCP connection.  Otherwise,
-// if unix_path != NULL, it uses a UNIX domain socket.
-// ------------------------------------------------------------------
-transport_session* init_transport( const char* server, int port, 
-       const char* unix_path, 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
index 5f26dae..a113a92 100644 (file)
 #
 # --------------------------------------------------------------------
 
-OBJS                           = md5.o utils.o json2xml.o object.o json_parser.o xml2json.o
-UTIL_DIR                       = ../utils
-DEST_INCLUDE   = objson
-CFLAGS                 += -DSTRICT_JSON_WRITE #-DSTRICT_JSON_READ
+OBJS = utils.o json2xml.o object.o json_parser.o xml2json.o
+CFLAGS += -DSTRICT_JSON_WRITE -DOSRF_DISABLE_MD5 
+TARGETS = object.o json_parser.o json2xml.o xml2json.o ../libopensrf/utils.o ../libopensrf/md5.o
+JSON_INC = ../../include/objson
 
-JSON_HEADERS = object.h json_parser.h json2xml.h xml2json.h
 
-all:   test
-
-test: libobjson.so objson_test.o
-
-objson_test.o: objson_test.c 
-object.o:      object.h object.c
-json_parser.o: json_parser.h json_parser.c
-json2xml.o:    json2xml.h json2xml.c
-xml2json.o:    xml2json.h xml2json.c
+all: libobjson.so
 
+object.o:      object.c $(JSON_INC)/object.h
+json_parser.o: json_parser.c $(JSON_INC)/json_parser.h
+json2xml.o:    json2xml.c $(JSON_INC)/json2xml.h
+xml2json.o:    xml2json.c $(JSON_INC)/xml2json.h
+../libopensrf/utils.o: ../libopensrf/utils.c ../../include/opensrf/utils.h
+../libopensrf/md5.o: ../libopensrf/md5.c ../../include/opensrf/md5.h
 
 install:
-       mkdir -p $(INCLUDEDIR)/$(DEST_INCLUDE)
-       cp $(TMPDIR)/$(DEST_INCLUDE)/*.h $(INCLUDEDIR)/objson/
+       cp -r ../../include/objson $(INCLUDEDIR)
        cp $(TMPDIR)/libobjson.so $(LIBDIR)/libobjson.so
 
-libobjson.so:  $(OBJS)
-       $(CC) -shared -W1 $(OBJS) -o $(TMPDIR)/libobjson.so
-       $(CC) -shared -W1 $(OBJS) -o libobjson.so
-       mkdir -p $(TMPDIR)/$(DEST_INCLUDE)/
-       cp $(JSON_HEADERS) $(TMPDIR)/$(DEST_INCLUDE)/
-
-utils.o:       $(UTIL_DIR)/utils.h $(UTIL_DIR)/utils.c
-       cp $(UTIL_DIR)/utils.h .
-       cp $(UTIL_DIR)/utils.c .
-       $(CC) -c $(CFLAGS) utils.c -o $@
-
-md5.o: $(UTIL_DIR)/md5.h $(UTIL_DIR)/md5.c
-       cp $(UTIL_DIR)/md5.h .
-       cp $(UTIL_DIR)/md5.c .
-       $(CC) -c $(CFLAGS) md5.c -o $@
+libobjson.so:  $(TARGETS)
+       $(CC) -shared -W1 $(TARGETS) -o $(TMPDIR)/libobjson.so
 
 clean:
-       /bin/rm -f *.o *.so utils.c utils.h libobjson.so
+       /bin/rm -f *.o *.so 
 
index ef4fa19..5abf2ed 100644 (file)
@@ -1,5 +1,5 @@
 
-#include "json2xml.h"
+#include <objson/json2xml.h>
 
 static char* _escape_xml (char*);
 static int _recurse_jsonObjectToXML(jsonObject*, growing_buffer*);
diff --git a/src/objson/json2xml.h b/src/objson/json2xml.h
deleted file mode 100644 (file)
index e4d2b44..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-
-#include <string.h>
-#include <stdio.h>
-
-/* the JSON parser, so we can read the response we're XMLizing */
-#include "object.h"
-#include "json_parser.h"
-//#include "opensrf/utils.h"
-#include "utils.h"
-
-char* jsonObjectToXML(jsonObject*);
-
index d75431f..8313872 100644 (file)
@@ -14,7 +14,7 @@ GNU General Public License for more details.
 */
 
 
-#include "json_parser.h"
+#include <objson/json_parser.h>
 
 /* keep a copy of the length of the current json string so we don't 
  * have to calculate it in each function
diff --git a/src/objson/json_parser.h b/src/objson/json_parser.h
deleted file mode 100644 (file)
index bba852f..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-Copyright (C) 2005  Georgia Public Library Service 
-Bill Erickson <highfalutin@gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-*/
-
-
-
-
-/* ---------------------------------------------------------------------------------------
-       JSON parser.
- * --------------------------------------------------------------------------------------- */
-#ifndef JSON_PARSER_H
-#define JSON_PARSER_H
-
-#include <stdio.h>
-#include "object.h"
-//#include "opensrf/utils.h"
-#include "utils.h"
-
-
-
-/* Parses the given JSON string and returns the built object. 
- *     returns NULL (and prints parser error to stderr) on error.  
- */
-
-jsonObject* json_parse_string(char* string);
-
-jsonObject* jsonParseString(char* string);
-jsonObject* jsonParseStringFmt( char* string, ... );
-
-jsonObject* json_parse_file( const char* filename );
-
-jsonObject* jsonParseFile( const char* string );
-
-
-
-/* does the actual parsing work.  returns 0 on success.  -1 on error and
- * -2 if there was no object to build (string was all comments) 
- */
-int _json_parse_string(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
-
-/* returns 0 on success and turns obj into a string object */
-int json_parse_json_string(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
-
-/* returns 0 on success and turns obj into a number or double object */
-int json_parse_json_number(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
-
-/* returns 0 on success and turns obj into an 'object' object */
-int json_parse_json_object(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
-
-/* returns 0 on success and turns object into an array object */
-int json_parse_json_array(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
-
-/* churns through whitespace and increments index as it goes.
- * eat_all == true means we should eat newlines, tabs
- */
-void json_eat_ws(char* string, unsigned long* index, int eat_all, int current_strlen);
-
-int json_parse_json_bool(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
-
-/* removes comments from a json string.  if the comment contains a class hint
- * and class_hint isn't NULL, an allocated char* with the class name will be
- * shoved into *class_hint.  returns 0 on success, -1 on parse error.
- * 'index' is assumed to be at the second character (*) of the comment
- */
-int json_eat_comment(char* string, unsigned long* index, char** class_hint, int parse_class, int current_strlen);
-
-/* prints a useful error message to stderr. always returns -1 */
-int json_handle_error(char* string, unsigned long* index, char* err_msg);
-
-/* returns true if c is 0-9 */
-int is_number(char c);
-
-int json_parse_json_null(char* string, unsigned long* index, jsonObject* obj, int current_strlen);
-
-
-#endif
index 782379b..3983576 100644 (file)
@@ -13,8 +13,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 */
 
-#include "object.h"
-#include "json_parser.h"
+#include <objson/object.h>
+#include <objson/json_parser.h>
 
 
 /* ---------------------------------------------------------------------- */
diff --git a/src/objson/object.h b/src/objson/object.h
deleted file mode 100644 (file)
index 8764e89..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
-Copyright (C) 2005  Georgia Public Library Service 
-Bill Erickson <highfalutin@gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-*/
-
-
-/* ---------------------------------------------------------------------------------------
-       libjson
- * --------------------------------------------------------------------------------------- */
-
-#ifndef _JSON_OBJECT_H
-#define _JSON_OBJECT_H
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-//#include "opensrf/utils.h"
-#include "utils.h"
-
-/* json object types */
-#define JSON_HASH      0
-#define JSON_ARRAY     1
-#define JSON_STRING    2
-#define JSON_NUMBER    3
-#define JSON_NULL      4       
-#define JSON_BOOL      5
-
-
-/* top level generic object structure */
-struct _jsonObjectStruct {
-
-       /* how many sub-objects do we contain if we're an array or an object.  
-               Note that this includes null array elements in sparse arrays */
-       unsigned long size;
-
-       /* optional class hint */
-       char* classname;
-
-       /* see JSON types above */
-       int type;
-
-
-       /* our cargo */
-       union _jsonObjectValue {
-               struct _jsonObjectNodeStruct* c; /* our list of sub-objects if we're an array or a hash */
-               char*           s; /* string */
-               int                     b; /* bool */
-               double          n; /* number */
-       } value;
-       
-
-       /* client may provide a comment string which will be 
-        * added to the object when stringified */
-       char* comment;
-
-};
-typedef struct _jsonObjectStruct jsonObject;
-
-
-/** 
-       String parsing function.  This is assigned by the json_parser code.
-       to avoid circular dependency, declare the parse function here,
-       and have the json parse code set the variable to a real function 
-*/
-//jsonObject* (*jsonParseString) (char* str);
-
-
-/* this contains a single element of the object along with the elements 
- * index (if this object is an array) and key (if this object is a hash)
- */
-struct _jsonObjectNodeStruct {
-
-       unsigned long index; /* our array position */
-       char* key; /* our hash key */
-
-       jsonObject* item; /* our object */
-       struct _jsonObjectNodeStruct* next; /* pointer to the next object node */
-};
-typedef struct _jsonObjectNodeStruct jsonObjectNode;
-
-
-
-/* utility object for iterating over hash objects */
-struct _jsonObjectIteratorStruct {
-       const jsonObject* obj; /* the topic object */
-       jsonObjectNode* current; /* the current node within the object */
-};
-typedef struct _jsonObjectIteratorStruct jsonObjectIterator;
-
-
-/** Allocates a new iterator 
-       @param obj The object over which to iterate.
-*/
-jsonObjectIterator* jsonNewObjectIterator(const jsonObject* obj);
-
-/** 
-       De-allocates an iterator 
-       @param iter The iterator object to free
-*/
-void jsonObjectIteratorFree(jsonObjectIterator* iter);
-
-/** 
-       Returns the object_node currently pointed to by the iterator
-       and increments the pointer to the next node
-       @param iter The iterator in question.
- */
-jsonObjectNode* jsonObjectIteratorNext(jsonObjectIterator* iter);
-
-/** 
-       @param iter The iterator.
-       @return True if there is another node after the current node.
- */
-int jsonObjectIteratorHasNext(const jsonObjectIterator* iter);
-
-
-/** 
-       Allocates a new object. 
-       @param string The string data if this object is to be a string.  
-       if not, string should be NULL 
-       @return The newly allocated object or NULL on memory error.
-*/
-jsonObject* jsonNewObjectFmt(const char* string, ...);
-jsonObject* jsonNewObject(const char* string);
-
-/**
-       Allocates a new JSON number object.
-       @param num The number this object is to hold
-       @return The newly allocated object.
-*/
-jsonObject* jsonNewNumberObject( double num );
-
-
-/** 
-       Returns a pointer to the object at the given index.  This call is
-       only valid if the object has a type of JSON_ARRAY.
-       @param obj The object
-       @param index The position within the object
-       @return The object at the given index.
-*/
-jsonObject* jsonObjectGetIndex( const jsonObject* obj, unsigned long index );
-
-
-/** 
-       Returns a pointer to the object with the given key 
-       @param obj The object
-       @param key The key
-       @return The object with the given key.
-*/
-jsonObject* jsonObjectGetKey( const jsonObject* obj, const char* key );
-
-/** 
-       De-allocates an object.  Note that this function should only be called 
-       on objects that are _not_ children of other objects or there will be
-       double-free's
-       @param obj The object to free.
-*/
-void jsonObjectFree(jsonObject* obj);
-
-
-/** 
-       Allocates a new object node.
-       @param obj The object to which the node will be appended.
-       @return The new object node.
-*/
-jsonObjectNode* jsonNewObjectNode(jsonObject* obj);
-
-/** 
-       De-allocates an object node 
-       @param obj The object node to de-allocate.
-*/
-void jsonObjectNodeFree(jsonObjectNode* obj);
-
-
-/** 
-       Pushes the given object onto the end of the list.  This coerces an object
-       into becoming an array.  _Only_ use this function on objects that you
-       want to become an array.
-       If obj is NULL, inserts a new NULL object into the list.
-       @return array size on success, -1 on error 
- */
-unsigned long jsonObjectPush(jsonObject* dest, jsonObject* newObj);
-
-/* removes (and deallocates) the object at the given index (if one exists) and inserts 
- * the new one.  returns the size on success, -1 on error 
- * If obj is NULL, inserts a new object into the list with is_null set to true
- */
-unsigned long jsonObjectSetIndex(jsonObject* dest, unsigned long index, jsonObject* newObj);
-
-/* inserts the new object, overwriting (removing, deallocating) any 
- * previous object with the given key.
- * returns the size on success, -1 on error 
- * if 'obj' is NULL, a new object is inserted at key 'key' with 'is_null' 
- * set to true
- */
-unsigned long jsonObjectSetKey(jsonObject* dest, const char* key, jsonObject* newObj);
-
-/* removes the object at the given index and, if more items exist,
- * re-indexes (shifts down by 1) the rest of the objects in the array
- */
-unsigned long jsonObjectRemoveIndex(jsonObject* dest, unsigned long index);
-
-/* removes (and deallocates) the object with key 'key' if it exists */
-unsigned long jsonObjectRemoveKey( jsonObject* dest, const char* key);
-
-/* returns a pointer to the string data held by this object if this object
-       is a string.  Otherwise returns NULL*/
-char* jsonObjectGetString(const jsonObject*);
-
-double jsonObjectGetNumber( const jsonObject* obj );
-
-/* sets the string data */
-void jsonObjectSetString(jsonObject* dest, const char* string);
-
-/* sets the number value for the object */
-void jsonObjectSetNumber(jsonObject* dest, double num);
-
-/* sets the class hint for this object */
-void jsonObjectSetClass(jsonObject* dest, const char* classname );
-
-/* converts an object to a json string.  client is responsible for freeing the return string */
-char* jsonObjectToJSON( const jsonObject* obj );
-
-/* set this object's comment string */
-void jsonObjectSetComment(jsonObject* dest, const char* classname);
-
-/* utility method.  starting at index 'index', shifts all indices down by one and 
- * decrements the objects size by 1 
- */
-void _jsonObjectShiftIndex(jsonObject* dest, unsigned long index);
-
-/* formats a JSON string from printing.  User must free returned string */
-char* jsonFormatString( const char* jsonString );
-
-jsonObject* jsonObjectClone( const jsonObject* o );
-
-/* tries to extract the string data from an object.
-       if object -> NULL (the C NULL)
-       if array ->     NULL  (the C NULL)
-       if null  -> NULL (the C NULL)
-       if true/false -> true/false
-       if string/number/double the string version of either of those
-       The caller is responsible for freeing the returned string
-       */
-char* jsonObjectToSimpleString( const jsonObject* o );
-
-int jsonBoolIsTrue( const jsonObject* o );
-
-
-/* ------------------------------------------------------------------------ */
-/* XPATH */
-
-/* provides an XPATH style search interface (e.g. /some/node/here) and 
-       return the object at that location if one exists.  Naturally,  
-       every element in the path must be a proper object ("hash" / {}).
-       Returns NULL if the specified node is not found 
-       Note also that the object returned is a clone and
-       must be freed by the caller
-*/
-jsonObject* jsonObjectFindPath( const jsonObject* obj, char* path, ... );
-
-
-/* Utility method. finds any object in the tree that matches the path.  
-       Use this for finding paths that start with '//' */
-jsonObject* _jsonObjectFindPathRecurse( const jsonObject* o, char* root, char* path );
-
-/* returns a list of object whose key is 'root'.  These are used as
-       potential objects when doing a // search */
-jsonObject* __jsonObjectFindPathRecurse( const jsonObject* o, char* root );
-
-/* ------------------------------------------------------------------------ */
-
-
-#endif
-
-
index 20cf2ff..5813780 100644 (file)
@@ -14,8 +14,8 @@ GNU General Public License for more details.
 */
 
 //#include "utils.h"
-#include "object.h"
-#include "json_parser.h"
+#include <objson/object.h>
+#include <objson/json_parser.h>
 
 #include <stdio.h>
 #include <fcntl.h>
index efdcfb0..d3dfaa0 100644 (file)
@@ -1,4 +1,4 @@
-#include "xml2json.h"
+#include <objson/xml2json.h>
 
 struct osrfXMLGatewayParserStruct {
     osrfList* objStack;
diff --git a/src/objson/xml2json.h b/src/objson/xml2json.h
deleted file mode 100644 (file)
index 35ed4ac..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-
-#include <stdio.h>
-#include <string.h>
-#include <libxml/globals.h>
-#include <libxml/xmlerror.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xmlmemory.h>
-
-#include "object.h"
-#include "json_parser.h"
-#include "utils.h"
-#include "osrf_list.h"
-
-
-
-jsonObject* jsonXMLToJSONObject(const char* xml);
-
-
-
index f6fc7ca..6497231 100644 (file)
@@ -1,13 +1,13 @@
-#include "opensrf/transport_client.h"
-#include "opensrf/osrf_message.h"
-#include "opensrf/osrf_app_session.h"
+#include <opensrf/transport_client.h>
+#include <opensrf/osrf_message.h>
+#include <opensrf/osrf_app_session.h>
 #include <time.h>
 #include <sys/timeb.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 
-#include "utils.h"
-#include "log.h"
+#include <opensrf/utils.h>
+#include <opensrf/log.h>
 
 #include <signal.h>
 
diff --git a/src/utils/Makefile b/src/utils/Makefile
deleted file mode 100644 (file)
index 77eae02..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-
-UTIL_HEADERS = md5.h log.h utils.h socket_bundle.h sha.h string_array.h xml_utils.h
-UTIL_OBJECTS = md5.o log.o utils.o socket_bundle.o sha.o string_array.o 
-
-all:   $(UTIL_OBJECTS) copy
-
-copy:
-       cp $(UTIL_HEADERS) $(TMPDIR)
-
-log.o: log.c log.h
-utils.o: utils.c utils.h
-socket_bundle.o: socket_bundle.c socket_bundle.h
-md5.o: md5.c md5.h
-sha.o: sha.c sha.h
-string_array.o: string_array.c string_array.h
-
-
-clean:
-       /bin/rm -f *.o 
-
-
diff --git a/src/utils/fieldmapper-c.pl b/src/utils/fieldmapper-c.pl
deleted file mode 100755 (executable)
index 80a59e5..0000000
+++ /dev/null
@@ -1,229 +0,0 @@
-#!/usr/bin/perl
-use strict; use warnings;
-use Data::Dumper; 
-use OpenILS::Utils::Fieldmapper;  
-
-
-if(!$ARGV[1]) {
-       print "usage: $0 <header_file> <source_file>\n";
-       exit;
-}
-
-warn "Generating fieldmapper-c code...\n";
-
-#open(HEADER, ">fieldmapper.h");
-#open(SOURCE, ">fieldmapper.c");
-
-print $ARGV[0] . "\n";
-print $ARGV[1] . "\n";
-
-open(HEADER, ">$ARGV[0]");
-open(SOURCE, ">$ARGV[1]");
-
-my $map = $Fieldmapper::fieldmap;
-
-print HEADER <<C;
-
-#include "objson/object.h"
-#include "objson/json_parser.h"
-#include "utils.h"
-
-/* Fieldmapper-C.  Autogenerated from fieldmapper-c.pl.\n\nNote that object*'s passed in as
-constructor parameters are copied in so the originals will need to be freed*/
-
-/* fm_obj is the generic placeholder object */
-struct fm_obj_struct { 
-       char* classname; 
-       object* array;
-};
-typedef struct fm_obj_struct fm_obj;
-
-/* takes a json object and builds a fieldmapper object.  the object
-       is then cast into an fm_obj and returned.  To verify an object is
-       what is expected, check fm_obj_thing->classname. */
-fm_obj* fm_factory(object*);
-
-/* builds a new fieldmapper object by class name */
-fm_obj* fm_factory_string(char*);
-
-void fm_free(fm_obj* fm);
-C
-
-print SOURCE <<C;
-#include "fieldmapper.h"
-
-void fm_free(fm_obj* fm) {
-       if(!fm) return;
-       free_object(fm->array);
-       free(fm);
-}
-C
-
-my $factory_string = <<C;
-fm_obj* fm_factory(object* obj) {
-
-       if(!obj) return NULL;
-       if(!obj->classname) return NULL;
-       fm_obj* fm = NULL;
-
-C
-
-my $fstring_string = <<C;
-fm_obj* fm_factory_string(char* string) {
-       if(!string) return NULL;
-       object* obj = new_object(NULL);
-       object* tmp = NULL;
-C
-
-for my $object (keys %$map) {
-
-       my $short_name                          = $map->{$object}->{hint};
-       my $func_header_string  = "";
-       my $func_code_string            = "";
-       my $constructor_string  = "";
-
-       $factory_string .= <<CODE;
-       if(!strcmp(obj->classname,"$short_name"))
-               fm = (fm_obj*) fm_new_$short_name(obj);
-CODE
-
-       $fstring_string .= <<CODE;
-       if(!strcmp(string, "$short_name")) {
-               obj->set_class(obj, "$short_name");
-CODE
-
-       my $header_string = <<CODE;
-struct fm_${short_name}_struct {
-       char* classname;
-       object* array;
-       char*\t\t(*to_string) (struct fm_${short_name}_struct*);
-CODE
-
-       $func_header_string .= <<CODE;
-char* fm_${short_name}_to_string(fm_$short_name*);
-CODE
-
-       my $to_string   = <<CODE;
-char* fm_${short_name}_to_string(fm_$short_name* fm) {
-       if(!fm || !fm->array) return NULL;
-       growing_buffer* buf = buffer_init(256);
-       buffer_fadd(buf, "%s => {\\n", fm->classname);
-       object* o;
-CODE
-
-       $constructor_string .= <<CODE; 
-fm_$short_name* fm_new_$short_name(object* obj_array) {
-
-       fm_$short_name* fm = (fm_$short_name*) safe_malloc(sizeof(fm_$short_name));
-
-       /* build an empty array object */
-       if(!obj_array) {
-               fm->array = new_object(NULL);
-               fm->array->is_array = 1;
-               fm->array->set_class(fm->array, "$short_name");
-
-       } else {
-
-               /* we don't want invalid objects */
-               if (!obj_array->classname) return NULL;
-               if(strcmp(obj_array->classname, "$short_name")) return NULL;
-       
-               char* s = obj_array->to_json(obj_array);
-               fm->array = json_parse_string(s);
-               free(s);
-       }
-
-       fm->classname = fm->array->classname;
-       fm->to_string = &fm_${short_name}_to_string;
-CODE
-
-       for my $field (keys %{$map->{$object}->{fields}}) {
-               my $position = $map->{$object}->{fields}->{$field}->{position};
-
-               $to_string .= <<CODE;
-       o = fm->array->get_index(fm->array, $position);
-       if(o) {
-               char* str = o->to_json(o);
-               buffer_fadd(buf, "  $field\\t: %s\\n", str);
-               free(str);
-       };
-CODE
-               
-               $fstring_string .= <<CODE;
-               tmp = new_object(NULL);
-               tmp->is_null = 1;
-               obj->set_index(obj, $position, tmp);
-CODE
-
-               $header_string .= <<CODE;
-       object*\t(*get_$field) (struct fm_${short_name}_struct*);
-       void\t\t(*set_$field) (struct fm_${short_name}_struct*, object*);
-CODE
-
-               $constructor_string .= <<CODE;
-       fm->set_$field = &fm_${short_name}_set_$field;
-       fm->get_$field = &fm_${short_name}_get_$field;
-CODE
-
-               $func_header_string .= <<CODE;
-object* fm_${short_name}_get_$field(fm_$short_name*);
-void fm_${short_name}_set_$field(fm_$short_name*, object*);
-CODE
-
-               $func_code_string .= <<CODE
-       object* fm_${short_name}_get_$field(fm_$short_name* fm) {
-               if(!fm || !fm->array) return NULL;
-               return fm->array->get_index(fm->array, $position);
-       }
-
-       void fm_${short_name}_set_$field(fm_$short_name* fm, object* obj) {
-               if(!fm || !fm->array || !obj) return;
-               fm->array->set_index(fm->array, $position, obj);
-       }
-CODE
-
-       }
-
-       $fstring_string .= <<CODE;
-               return (fm_obj*) fm_new_$short_name(obj);
-       }
-CODE
-
-       $to_string .= <<CODE;
-       buffer_add(buf,"}\\n");
-       char* b = buffer_data(buf);
-       buffer_free(buf);
-       return b;
-}
-CODE
-
-       $constructor_string .= "\treturn fm;\n}\n";
-       $header_string .= "};\n";
-       $func_code_string = $constructor_string . $to_string . $func_code_string;
-
-       $header_string .= "typedef struct fm_$short_name"."_struct fm_$short_name;\n\n";
-       $header_string .= "fm_$short_name* fm_new_$short_name(object*);\n";
-       $header_string .= "$func_header_string\n";
-
-       print HEADER "\n$header_string\n";
-       print SOURCE "\n$func_code_string\n";
-
-
-}
-
-$factory_string .= "\treturn fm;\n}\n";
-#$fstring_string .= "\treturn NULL;\n}\n";
-$fstring_string .= <<CODE;
-       free_object(obj);
-       return NULL;
-}
-CODE
-
-print SOURCE "\n$factory_string\n";
-print SOURCE "\n$fstring_string\n";
-
-close HEADER;
-close SOURCE;
-
-warn  "done\n";
-
diff --git a/src/utils/log.c b/src/utils/log.c
deleted file mode 100644 (file)
index 624cd10..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-#include "log.h"
-
-static int _osrfLogType                                = -1;
-static int _osrfLogFacility                    = LOG_LOCAL0;
-static int _osrfLogActFacility         = LOG_LOCAL1;
-static char* _osrfLogFile                      = NULL;
-static char* _osrfLogAppname           = NULL;
-static int _osrfLogLevel                       = OSRF_LOG_INFO;
-static int _osrfLogActivityEnabled     = 1;
-static int _osrfLogIsClient         = 0;
-
-static char* _osrfLogXid            = NULL; /* current xid */
-static char* _osrfLogXidPfx         = NULL; /* xid prefix string */
-
-static void osrfLogSetType( int logtype );
-static void _osrfLogDetail( int level, const char* filename, int line, char* msg );
-static void _osrfLogToFile( char* msg, ... );
-static void _osrfLogSetXid(char* xid);
-
-#define OSRF_LOG_GO(f,li,m,l)  \
-        if(!m) return;         \
-        VA_LIST_TO_STRING(m);  \
-        _osrfLogDetail( l, f, li, VA_BUF );
-
-void osrfLogCleanup() {
-       free(_osrfLogAppname);
-       free(_osrfLogFile);
-}
-
-
-void osrfLogInit( int type, const char* appname, int maxlevel ) {
-       osrfLogSetType(type);
-       if(appname) osrfLogSetAppname(appname);
-       osrfLogSetLevel(maxlevel);
-       if( type == OSRF_LOG_TYPE_SYSLOG ) 
-               openlog(_osrfLogAppname, 0, _osrfLogFacility );
-}
-
-static void _osrfLogSetXid(char* xid) {
-   if(xid) {
-      if(_osrfLogXid) free(_osrfLogXid);
-      _osrfLogXid = strdup(xid);
-   }
-}
-
-void osrfLogClearXid() { _osrfLogSetXid(""); }
-void osrfLogSetXid(char* xid) {
-   if(!_osrfLogIsClient) _osrfLogSetXid(xid);
-}
-
-void osrfLogMkXid() {
-   if(_osrfLogIsClient) {
-      static int _osrfLogXidInc = 0; /* increments with each new xid for uniqueness */
-      char buf[32];
-      memset(buf, 0x0, 32);
-      snprintf(buf, 32, "%s%d", _osrfLogXidPfx, _osrfLogXidInc);
-      _osrfLogSetXid(buf);
-      _osrfLogXidInc++;
-   }
-}
-
-char* osrfLogGetXid() {
-   return _osrfLogXid;
-}
-
-void osrfLogSetIsClient(int is) {
-   _osrfLogIsClient = is;
-   if(!is) return;
-   /* go ahead and create the xid prefix so it will be consistent later */
-   static char buff[32];
-   memset(buff, 0x0, 32);
-   snprintf(buff, 32, "%d%ld", (int)time(NULL), (long) getpid());
-   _osrfLogXidPfx = buff;
-}
-
-/** Sets the type of logging to perform.  See log types */
-static void osrfLogSetType( int logtype ) { 
-       if( logtype != OSRF_LOG_TYPE_FILE &&
-                       logtype != OSRF_LOG_TYPE_SYSLOG ) {
-               fprintf(stderr, "Unrecognized log type.  Logging to stderr\n");
-               return;
-       }
-       _osrfLogType = logtype;
-}
-
-void osrfLogSetFile( const char* logfile ) {
-       if(!logfile) return;
-       if(_osrfLogFile) free(_osrfLogFile);
-       _osrfLogFile = strdup(logfile);
-}
-
-void osrfLogSetActivityEnabled( int enabled ) {
-       _osrfLogActivityEnabled = enabled;
-}
-
-void osrfLogSetAppname( const char* appname ) {
-       if(!appname) return;
-       if(_osrfLogAppname) free(_osrfLogAppname);
-       _osrfLogAppname = strdup(appname);
-
-       /* if syslogging, re-open the log with the appname */
-       if( _osrfLogType == OSRF_LOG_TYPE_SYSLOG) {
-               closelog();
-               openlog(_osrfLogAppname, 0, _osrfLogFacility);
-       }
-}
-
-void osrfLogSetSyslogFacility( int facility ) {
-       _osrfLogFacility = facility;
-}
-void osrfLogSetSyslogActFacility( int facility ) {
-       _osrfLogActFacility = facility;
-}
-
-/** Sets the global log level.  Any log statements with a higher level
- * than "level" will not be logged */
-void osrfLogSetLevel( int loglevel ) {
-       _osrfLogLevel = loglevel;
-}
-
-/** Gets the current global log level. **/
-int osrfLogGetLevel( void ) {
-       return _osrfLogLevel;
-}
-
-void osrfLogError( const char* file, int line, const char* msg, ... ) 
-       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_ERROR); }
-void osrfLogWarning( const char* file, int line, const char* msg, ... ) 
-       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_WARNING); }
-void osrfLogInfo( const char* file, int line, const char* msg, ... ) 
-       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INFO); }
-void osrfLogDebug( const char* file, int line, const char* msg, ... ) 
-       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_DEBUG); }
-void osrfLogInternal( const char* file, int line, const char* msg, ... ) 
-       { OSRF_LOG_GO(file, line, msg, OSRF_LOG_INTERNAL); }
-void osrfLogActivity( const char* file, int line, const char* msg, ... ) { 
-       OSRF_LOG_GO(file, line, msg, OSRF_LOG_ACTIVITY); 
-       _osrfLogDetail( OSRF_LOG_INFO, file, line, VA_BUF ); /* also log at info level */
-}
-
-/** Actually does the logging */
-static void _osrfLogDetail( int level, const char* filename, int line, char* msg ) {
-
-       if( level == OSRF_LOG_ACTIVITY && ! _osrfLogActivityEnabled ) return;
-       if( level > _osrfLogLevel ) return;
-       if(!msg) return;
-       if(!filename) filename = "";
-
-       char* l = "INFO";               /* level name */
-       int lvl = LOG_INFO;     /* syslog level */
-       int fac = _osrfLogFacility;
-
-       switch( level ) {
-               case OSRF_LOG_ERROR:            
-                       l = "ERR "; 
-                       lvl = LOG_ERR;
-                       break;
-
-               case OSRF_LOG_WARNING:  
-                       l = "WARN"; 
-                       lvl = LOG_WARNING;
-                       break;
-
-               case OSRF_LOG_INFO:             
-                       l = "INFO"; 
-                       lvl = LOG_INFO;
-                       break;
-
-               case OSRF_LOG_DEBUG:    
-                       l = "DEBG"; 
-                       lvl = LOG_DEBUG;
-                       break;
-
-               case OSRF_LOG_INTERNAL: 
-                       l = "INT "; 
-                       lvl = LOG_DEBUG;
-                       break;
-
-               case OSRF_LOG_ACTIVITY: 
-                       l = "ACT"; 
-                       lvl = LOG_INFO;
-                       fac = _osrfLogActFacility;
-                       break;
-       }
-
-   char* xid = (_osrfLogXid) ? _osrfLogXid : "";
-
-       if(_osrfLogType == OSRF_LOG_TYPE_SYSLOG ) {
-               char buf[1536];  
-               memset(buf, 0x0, 1536);
-               /* give syslog some breathing room, and be cute about it */
-               strncat(buf, msg, 1535);
-               buf[1532] = '.';
-               buf[1533] = '.';
-               buf[1534] = '.';
-               buf[1535] = '\0';
-               syslog( fac | lvl, "[%s:%ld:%s:%d:%s] %s", l, (long) getpid(), filename, line, xid, buf );
-       }
-
-       else if( _osrfLogType == OSRF_LOG_TYPE_FILE )
-               _osrfLogToFile("[%s:%ld:%s:%d:%s] %s", l, (long) getpid(), filename, line, xid, msg );
-
-}
-
-
-static void _osrfLogToFile( char* msg, ... ) {
-
-       if(!msg) return;
-       if(!_osrfLogFile) return;
-       VA_LIST_TO_STRING(msg);
-
-       if(!_osrfLogAppname) _osrfLogAppname = strdup("osrf");
-       int l = strlen(VA_BUF) + strlen(_osrfLogAppname) + 36;
-       char buf[l];
-       bzero(buf,l);
-
-       char datebuf[36];
-       bzero(datebuf,36);
-       time_t t = time(NULL);
-       struct tm* tms = localtime(&t);
-       strftime(datebuf, 36, "%Y-%m-%d %H:%M:%S", tms);
-
-       FILE* file = fopen(_osrfLogFile, "a");
-       if(!file) {
-               fprintf(stderr, "Unable to fopen file %s for writing\n", _osrfLogFile);
-               return;
-       }
-
-       fprintf(file, "%s %s %s\n", _osrfLogAppname, datebuf, VA_BUF );
-       if( fclose(file) != 0 ) 
-               osrfLogWarning(OSRF_LOG_MARK, "Error closing log file: %s", strerror(errno));
-
-}
-
-
-int osrfLogFacilityToInt( char* facility ) {
-       if(!facility) return LOG_LOCAL0;
-       if(strlen(facility) < 6) return LOG_LOCAL0;
-       switch( facility[5] ) {
-               case '0': return LOG_LOCAL0;
-               case '1': return LOG_LOCAL1;
-               case '2': return LOG_LOCAL2;
-               case '3': return LOG_LOCAL3;
-               case '4': return LOG_LOCAL4;
-               case '5': return LOG_LOCAL5;
-               case '6': return LOG_LOCAL6;
-               case '7': return LOG_LOCAL7;
-       }
-       return LOG_LOCAL0;
-}
-
-
diff --git a/src/utils/log.h b/src/utils/log.h
deleted file mode 100644 (file)
index 1928d41..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-#include <syslog.h>
-#include <stdio.h>
-#include "utils.h"
-#include <time.h>
-#include <errno.h>
-
-#ifndef OSRF_LOG_INCLUDED
-#define OSRF_LOG_INCLUDED
-
-/* log levels */
-#define OSRF_LOG_ERROR 1
-#define OSRF_LOG_WARNING 2
-#define OSRF_LOG_INFO 3
-#define OSRF_LOG_DEBUG 4
-#define OSRF_LOG_INTERNAL 5
-#define OSRF_LOG_ACTIVITY -1
-
-#define OSRF_LOG_TYPE_FILE 1
-#define OSRF_LOG_TYPE_SYSLOG 2
-
-#define OSRF_LOG_MARK __FILE__, __LINE__
-
-
-/* Initializes the logger. */
-void osrfLogInit( int type, const char* appname, int maxlevel );
-
-/** Sets the systlog facility for the regular logs */
-void osrfLogSetSyslogFacility( int facility );
-
-/** Sets the systlog facility for the activity logs */
-void osrfLogSetSyslogActFacility( int facility );
-
-/** Sets the log file to use if we're logging to a file */
-void osrfLogSetFile( const char* logfile );
-
-/* once we know which application we're running, call this method to
- * set the appname so log lines can include the app name */
-void osrfLogSetAppname( const char* appname );
-
-/** Set or Get the global log level.  Any log statements with a higher level
- * than "level" will not be logged */
-void osrfLogSetLevel( int loglevel );
-int osrfLogGetLevel( void );
-
-/* Log an error message */
-void osrfLogError( const char* file, int line, const char* msg, ... );
-
-/* Log a warning message */
-void osrfLogWarning( const char* file, int line, const char* msg, ... );
-
-/* log an info message */
-void osrfLogInfo( const char* file, int line, const char* msg, ... );
-
-/* Log a debug message */
-void osrfLogDebug( const char* file, int line, const char* msg, ... );
-
-/* Log an internal debug message */
-void osrfLogInternal( const char* file, int line, const char* msg, ... );
-
-/* Log an activity message */
-void osrfLogActivity( const char* file, int line, const char* msg, ... );
-
-void osrfLogCleanup();
-
-void osrfLogClearXid();
-void osrfLogSetXid(char* xid);
-void osrfLogMkXid();
-void osrfLogSetIsClient(int is);
-char* osrfLogGetXid();
-
-/* sets the activity flag */
-void osrfLogSetActivityEnabled( int enabled );
-
-/* returns the int representation of the log facility based on the facility name
- * if the facility name is invalid, LOG_LOCAL0 is returned 
- */
-int osrfLogFacilityToInt( char* facility );
-
-#endif
diff --git a/src/utils/md5.c b/src/utils/md5.c
deleted file mode 100644 (file)
index 7da3d60..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/* --- The data --- */
-
-const char data[] =
-"/* --- The MD5 routines --- */\n\n/* MD5 routines, after Ron R"
-"ivest */\n/* Written by David Madore <david.madore@ens.fr>, w"
-"ith code taken in\n * part from Colin Plumb. */\n/* Public dom"
-"ain (1999/11/24) */\n\n/* Note: these routines do not depend o"
-"n endianness. */\n\n/* === The header === */\n\n/* Put this in m"
-"d5.h if you don't like having everything in one big\n * file."
-" */\n\n#ifndef _DMADORE_MD5_H\n#define _DMADORE_MD5_H\n\nstruct m"
-"d5_ctx {\n  /* The four chaining variables */\n  unsigned long"
-" buf[4];\n  /* Count number of message bits */\n  unsigned lon"
-"g bits[2];\n  /* Data being fed in */\n  unsigned long in[16];"
-"\n  /* Our position within the 512 bits (always between 0 and"
-" 63) */\n  int b;\n};\n\nvoid MD5_transform (unsigned long buf[4"
-"], const unsigned long in[16]);\nvoid MD5_start (struct md5_c"
-"tx *context);\nvoid MD5_feed (struct md5_ctx *context, unsign"
-"ed char inb);\nvoid MD5_stop (struct md5_ctx *context, unsign"
-"ed char digest[16]);\n\n#endif /* not defined _DMADORE_MD5_H *"
-"/\n\n/* === The implementation === */\n\n#define F1(x, y, z) (z "
-"^ (x & (y ^ z)))\n#define F2(x, y, z) F1(z, x, y)\n#define F3("
-"x, y, z) (x ^ y ^ z)\n#define F4(x, y, z) (y ^ (x | ~z))\n\n#de"
-"fine MD5STEP(f, w, x, y, z, data, s) \\\n\t{ w += f (x, y, z) +"
-" data;  w = w<<s | (w&0xffffffffUL)>>(32-s); \\\n\t  w += x; }\n"
-"\nvoid\nMD5_transform (unsigned long buf[4], const unsigned lo"
-"ng in[16])\n{\n  register unsigned long a, b, c, d;\n\n  a = buf"
-"[0];  b = buf[1];  c = buf[2];  d = buf[3];\n  MD5STEP(F1, a,"
-" b, c, d, in[0] + 0xd76aa478UL, 7);\n  MD5STEP(F1, d, a, b, c"
-", in[1] + 0xe8c7b756UL, 12);\n  MD5STEP(F1, c, d, a, b, in[2]"
-" + 0x242070dbUL, 17);\n  MD5STEP(F1, b, c, d, a, in[3] + 0xc1"
-"bdceeeUL, 22);\n  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU"
-"L, 7);\n  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aUL, 12);\n"
-"  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613UL, 17);\n  MD5ST"
-"EP(F1, b, c, d, a, in[7] + 0xfd469501UL, 22);\n  MD5STEP(F1, "
-"a, b, c, d, in[8] + 0x698098d8UL, 7);\n  MD5STEP(F1, d, a, b,"
-" c, in[9] + 0x8b44f7afUL, 12);\n  MD5STEP(F1, c, d, a, b, in["
-"10] + 0xffff5bb1UL, 17);\n  MD5STEP(F1, b, c, d, a, in[11] + "
-"0x895cd7beUL, 22);\n  MD5STEP(F1, a, b, c, d, in[12] + 0x6b90"
-"1122UL, 7);\n  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193UL,"
-" 12);\n  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eUL, 17);\n"
-"  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821UL, 22);\n  MD5S"
-"TEP(F2, a, b, c, d, in[1] + 0xf61e2562UL, 5);\n  MD5STEP(F2, "
-"d, a, b, c, in[6] + 0xc040b340UL, 9);\n  MD5STEP(F2, c, d, a,"
-" b, in[11] + 0x265e5a51UL, 14);\n  MD5STEP(F2, b, c, d, a, in"
-"[0] + 0xe9b6c7aaUL, 20);\n  MD5STEP(F2, a, b, c, d, in[5] + 0"
-"xd62f105dUL, 5);\n  MD5STEP(F2, d, a, b, c, in[10] + 0x024414"
-"53UL, 9);\n  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681UL, 1"
-"4);\n  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8UL, 20);\n  M"
-"D5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6UL, 5);\n  MD5STEP(F"
-"2, d, a, b, c, in[14] + 0xc33707d6UL, 9);\n  MD5STEP(F2, c, d"
-", a, b, in[3] + 0xf4d50d87UL, 14);\n  MD5STEP(F2, b, c, d, a,"
-" in[8] + 0x455a14edUL, 20);\n  MD5STEP(F2, a, b, c, d, in[13]"
-" + 0xa9e3e905UL, 5);\n  MD5STEP(F2, d, a, b, c, in[2] + 0xfce"
-"fa3f8UL, 9);\n  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9UL,"
-" 14);\n  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aUL, 20);\n"
-"  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942UL, 4);\n  MD5STE"
-"P(F3, d, a, b, c, in[8] + 0x8771f681UL, 11);\n  MD5STEP(F3, c"
-", d, a, b, in[11] + 0x6d9d6122UL, 16);\n  MD5STEP(F3, b, c, d"
-", a, in[14] + 0xfde5380cUL, 23);\n  MD5STEP(F3, a, b, c, d, i"
-"n[1] + 0xa4beea44UL, 4);\n  MD5STEP(F3, d, a, b, c, in[4] + 0"
-"x4bdecfa9UL, 11);\n  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b"
-"60UL, 16);\n  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70UL, "
-"23);\n  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6UL, 4);\n  "
-"MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faUL, 11);\n  MD5STEP"
-"(F3, c, d, a, b, in[3] + 0xd4ef3085UL, 16);\n  MD5STEP(F3, b,"
-" c, d, a, in[6] + 0x04881d05UL, 23);\n  MD5STEP(F3, a, b, c, "
-"d, in[9] + 0xd9d4d039UL, 4);\n  MD5STEP(F3, d, a, b, c, in[12"
-"] + 0xe6db99e5UL, 11);\n  MD5STEP(F3, c, d, a, b, in[15] + 0x"
-"1fa27cf8UL, 16);\n  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac566"
-"5UL, 23);\n  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244UL, 6)"
-";\n  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97UL, 10);\n  MD5"
-"STEP(F4, c, d, a, b, in[14] + 0xab9423a7UL, 15);\n  MD5STEP(F"
-"4, b, c, d, a, in[5] + 0xfc93a039UL, 21);\n  MD5STEP(F4, a, b"
-", c, d, in[12] + 0x655b59c3UL, 6);\n  MD5STEP(F4, d, a, b, c,"
-" in[3] + 0x8f0ccc92UL, 10);\n  MD5STEP(F4, c, d, a, b, in[10]"
-" + 0xffeff47dUL, 15);\n  MD5STEP(F4, b, c, d, a, in[1] + 0x85"
-"845dd1UL, 21);\n  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU"
-"L, 6);\n  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0UL, 10);"
-"\n  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314UL, 15);\n  MD5S"
-"TEP(F4, b, c, d, a, in[13] + 0x4e0811a1UL, 21);\n  MD5STEP(F4"
-", a, b, c, d, in[4] + 0xf7537e82UL, 6);\n  MD5STEP(F4, d, a, "
-"b, c, in[11] + 0xbd3af235UL, 10);\n  MD5STEP(F4, c, d, a, b, "
-"in[2] + 0x2ad7d2bbUL, 15);\n  MD5STEP(F4, b, c, d, a, in[9] +"
-" 0xeb86d391UL, 21);\n  buf[0] += a;  buf[1] += b;  buf[2] += "
-"c;  buf[3] += d;\n}\n\n#undef F1\n#undef F2\n#undef F3\n#undef F4\n"
-"#undef MD5STEP\n\nvoid\nMD5_start (struct md5_ctx *ctx)\n{\n  int"
-" i;\n\n  ctx->buf[0] = 0x67452301UL;\n  ctx->buf[1] = 0xefcdab8"
-"9UL;\n  ctx->buf[2] = 0x98badcfeUL;\n  ctx->buf[3] = 0x1032547"
-"6UL;\n  ctx->bits[0] = 0;\n  ctx->bits[1] = 0;\n  for ( i=0 ; i"
-"<16 ; i++ )\n    ctx->in[i] = 0;\n  ctx->b = 0;\n}\n\nvoid\nMD5_fe"
-"ed (struct md5_ctx *ctx, unsigned char inb)\n{\n  int i;\n  uns"
-"igned long temp;\n\n  ctx->in[ctx->b/4] |= ((unsigned long)inb"
-") << ((ctx->b%4)*8);\n  if ( ++ctx->b >= 64 )\n    {\n      MD5"
-"_transform (ctx->buf, ctx->in);\n      ctx->b = 0;\n      for "
-"( i=0 ; i<16 ; i++ )\n\tctx->in[i] = 0;\n    }\n  temp = ctx->bi"
-"ts[0];\n  ctx->bits[0] += 8;\n  if ( (temp&0xffffffffUL) > (ct"
-"x->bits[0]&0xffffffffUL) )\n    ctx->bits[1]++;\n}\n\nvoid\nMD5_s"
-"top (struct md5_ctx *ctx, unsigned char digest[16])\n{\n  int "
-"i;\n  unsigned long bits[2];\n\n  for ( i=0 ; i<2 ; i++ )\n    b"
-"its[i] = ctx->bits[i];\n  MD5_feed (ctx, 0x80);\n  for ( ; ctx"
-"->b!=56 ; )\n    MD5_feed (ctx, 0);\n  for ( i=0 ; i<2 ; i++ )"
-"\n    {\n      MD5_feed (ctx, bits[i]&0xff);\n      MD5_feed (c"
-"tx, (bits[i]>>8)&0xff);\n      MD5_feed (ctx, (bits[i]>>16)&0"
-"xff);\n      MD5_feed (ctx, (bits[i]>>24)&0xff);\n    }\n  for "
-"( i=0 ; i<4 ; i++ )\n    {\n      digest[4*i] = ctx->buf[i]&0x"
-"ff;\n      digest[4*i+1] = (ctx->buf[i]>>8)&0xff;\n      diges"
-"t[4*i+2] = (ctx->buf[i]>>16)&0xff;\n      digest[4*i+3] = (ct"
-"x->buf[i]>>24)&0xff;\n    }\n}\n\f\n/* --- The core of the progra"
-"m --- */\n\n#include <stdio.h>\n#include <string.h>\n\n#define LA"
-"RGE_ENOUGH 16384\n\nchar buffer[LARGE_ENOUGH];\n\nint\nmain (int "
-"argc, char *argv[])\n{\n  unsigned int i;\n\n  buffer[0] = 0;\n  "
-"strcat (buffer, \"/* --- The data --- */\\n\\n\");\n  strcat (buf"
-"fer, \"const char data[] =\");\n  for ( i=0 ; data[i] ; i++ )\n "
-"   {\n      if ( i%60 == 0 )\n\tstrcat (buffer, \"\\n\\\"\");\n      "
-"switch ( data[i] )\n\t{\n\tcase '\\\\':\n\tcase '\"':\n\t  strcat (buff"
-"er, \"\\\\\");\n\t  buffer[strlen(buffer)+1] = 0;\n\t  buffer[strlen"
-"(buffer)] = data[i];\n\t  break;\n\tcase '\\n':\n\t  strcat (buffer"
-", \"\\\\n\");\n\t  break;\n\tcase '\\t':\n\t  strcat (buffer, \"\\\\t\");\n\t"
-"  break;\n\tcase '\\f':\n\t  strcat (buffer, \"\\\\f\");\n\t  break;\n\td"
-"efault:\n\t  buffer[strlen(buffer)+1] = 0;\n\t  buffer[strlen(bu"
-"ffer)] = data[i];\n\t}\n      if ( i%60 == 59 || !data[i+1] )\n\t"
-"strcat (buffer, \"\\\"\");\n    }\n  strcat (buffer, \";\\n\\f\\n\");\n "
-" strcat (buffer, data);\n  if ( argc >= 2 && strcmp (argv[1],"
-" \"xyzzy\") == 0 )\n    printf (\"%s\", buffer);\n  else\n    {\n   "
-"   struct md5_ctx ctx;\n      unsigned char digest[16];\n\n    "
-"  MD5_start (&ctx);\n      for ( i=0 ; buffer[i] ; i++ )\n\tMD5"
-"_feed (&ctx, buffer[i]);\n      MD5_stop (&ctx, digest);\n    "
-"  for ( i=0 ; i<16 ; i++ )\n\tprintf (\"%02x\", digest[i]);\n    "
-"  printf (\"\\n\");\n    }\n  return 0;\n}\n";
-
-
-#include "md5.h"
-
-
-/* --- The MD5 routines --- */
-
-/* MD5 routines, after Ron Rivest */
-/* Written by David Madore <david.madore@ens.fr>, with code taken in
- * part from Colin Plumb. */
-/* Public domain (1999/11/24) */
-
-/* Note: these routines do not depend on endianness. */
-
-/* === The header === */
-
-/* Put this in md5.h if you don't like having everything in one big
- * file. */
-
-
-#define F1(x, y, z) (z ^ (x & (y ^ z)))
-#define F2(x, y, z) F1(z, x, y)
-#define F3(x, y, z) (x ^ y ^ z)
-#define F4(x, y, z) (y ^ (x | ~z))
-
-#define MD5STEP(f, w, x, y, z, data, s) \
-       { w += f (x, y, z) + data;  w = w<<s | (w&0xffffffffUL)>>(32-s); \
-         w += x; }
-
-void
-MD5_transform (unsigned long buf[4], const unsigned long in[16])
-{
-  register unsigned long a, b, c, d;
-
-  a = buf[0];  b = buf[1];  c = buf[2];  d = buf[3];
-  MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478UL, 7);
-  MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756UL, 12);
-  MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbUL, 17);
-  MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeUL, 22);
-  MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafUL, 7);
-  MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aUL, 12);
-  MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613UL, 17);
-  MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501UL, 22);
-  MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8UL, 7);
-  MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afUL, 12);
-  MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1UL, 17);
-  MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beUL, 22);
-  MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122UL, 7);
-  MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193UL, 12);
-  MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eUL, 17);
-  MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821UL, 22);
-  MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562UL, 5);
-  MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340UL, 9);
-  MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51UL, 14);
-  MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaUL, 20);
-  MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dUL, 5);
-  MD5STEP(F2, d, a, b, c, in[10] + 0x02441453UL, 9);
-  MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681UL, 14);
-  MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8UL, 20);
-  MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6UL, 5);
-  MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6UL, 9);
-  MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87UL, 14);
-  MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edUL, 20);
-  MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905UL, 5);
-  MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8UL, 9);
-  MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9UL, 14);
-  MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aUL, 20);
-  MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942UL, 4);
-  MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681UL, 11);
-  MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122UL, 16);
-  MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cUL, 23);
-  MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44UL, 4);
-  MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9UL, 11);
-  MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60UL, 16);
-  MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70UL, 23);
-  MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6UL, 4);
-  MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faUL, 11);
-  MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085UL, 16);
-  MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05UL, 23);
-  MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039UL, 4);
-  MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5UL, 11);
-  MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8UL, 16);
-  MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665UL, 23);
-  MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244UL, 6);
-  MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97UL, 10);
-  MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7UL, 15);
-  MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039UL, 21);
-  MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3UL, 6);
-  MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92UL, 10);
-  MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dUL, 15);
-  MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1UL, 21);
-  MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fUL, 6);
-  MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0UL, 10);
-  MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314UL, 15);
-  MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1UL, 21);
-  MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82UL, 6);
-  MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235UL, 10);
-  MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbUL, 15);
-  MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391UL, 21);
-  buf[0] += a;  buf[1] += b;  buf[2] += c;  buf[3] += d;
-}
-
-#undef F1
-#undef F2
-#undef F3
-#undef F4
-#undef MD5STEP
-
-void
-MD5_start (struct md5_ctx *ctx)
-{
-  int i;
-
-  ctx->buf[0] = 0x67452301UL;
-  ctx->buf[1] = 0xefcdab89UL;
-  ctx->buf[2] = 0x98badcfeUL;
-  ctx->buf[3] = 0x10325476UL;
-  ctx->bits[0] = 0;
-  ctx->bits[1] = 0;
-  for ( i=0 ; i<16 ; i++ )
-    ctx->in[i] = 0;
-  ctx->b = 0;
-}
-
-void
-MD5_feed (struct md5_ctx *ctx, unsigned char inb)
-{
-  int i;
-  unsigned long temp;
-
-  ctx->in[ctx->b/4] |= ((unsigned long)inb) << ((ctx->b%4)*8);
-  if ( ++ctx->b >= 64 )
-    {
-      MD5_transform (ctx->buf, ctx->in);
-      ctx->b = 0;
-      for ( i=0 ; i<16 ; i++ )
-       ctx->in[i] = 0;
-    }
-  temp = ctx->bits[0];
-  ctx->bits[0] += 8;
-  if ( (temp&0xffffffffUL) > (ctx->bits[0]&0xffffffffUL) )
-    ctx->bits[1]++;
-}
-
-void
-MD5_stop (struct md5_ctx *ctx, unsigned char digest[16])
-{
-  int i;
-  unsigned long bits[2];
-
-  for ( i=0 ; i<2 ; i++ )
-    bits[i] = ctx->bits[i];
-  MD5_feed (ctx, 0x80);
-  for ( ; ctx->b!=56 ; )
-    MD5_feed (ctx, 0);
-  for ( i=0 ; i<2 ; i++ )
-    {
-      MD5_feed (ctx, bits[i]&0xff);
-      MD5_feed (ctx, (bits[i]>>8)&0xff);
-      MD5_feed (ctx, (bits[i]>>16)&0xff);
-      MD5_feed (ctx, (bits[i]>>24)&0xff);
-    }
-  for ( i=0 ; i<4 ; i++ )
-    {
-      digest[4*i] = ctx->buf[i]&0xff;
-      digest[4*i+1] = (ctx->buf[i]>>8)&0xff;
-      digest[4*i+2] = (ctx->buf[i]>>16)&0xff;
-      digest[4*i+3] = (ctx->buf[i]>>24)&0xff;
-    }
-}
-\f
-/* --- The core of the program --- */
-
-#include <stdio.h>
-#include <string.h>
-
-#define LARGE_ENOUGH 16384
-
-char buffer[LARGE_ENOUGH];
-
-/*
-int
-main (int argc, char *argv[])
-{
-  unsigned int i;
-
-  buffer[0] = 0;
-  strcat (buffer, \n\n");
-  strcat (buffer, "const char data[] =");
-  for ( i=0 ; data[i] ; i++ )
-    {
-      if ( i%60 == 0 )
-       strcat (buffer, "\n\"");
-      switch ( data[i] )
-       {
-       case '\\':
-       case '"':
-         strcat (buffer, "\\");
-         buffer[strlen(buffer)+1] = 0;
-         buffer[strlen(buffer)] = data[i];
-         break;
-       case '\n':
-         strcat (buffer, "\\n");
-         break;
-       case '\t':
-         strcat (buffer, "\\t");
-         break;
-       case '\f':
-         strcat (buffer, "\\f");
-         break;
-       default:
-         buffer[strlen(buffer)+1] = 0;
-         buffer[strlen(buffer)] = data[i];
-       }
-      if ( i%60 == 59 || !data[i+1] )
-       strcat (buffer, "\"");
-    }
-  strcat (buffer, ";\n\f\n");
-  strcat (buffer, data);
-  if ( argc >= 2 && strcmp (argv[1], "xyzzy") == 0 )
-    printf ("%s", buffer);
-  else
-    {
-      struct md5_ctx ctx;
-      unsigned char digest[16];
-
-      MD5_start (&ctx);
-      for ( i=0 ; buffer[i] ; i++ )
-       MD5_feed (&ctx, buffer[i]);
-      MD5_stop (&ctx, digest);
-      for ( i=0 ; i<16 ; i++ )
-       printf ("%02x", digest[i]);
-      printf ("\n");
-    }
-  return 0;
-}
-*/
diff --git a/src/utils/md5.h b/src/utils/md5.h
deleted file mode 100644 (file)
index 53dd2b1..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* --- The MD5 routines --- */
-
-/* MD5 routines, after Ron Rivest */
-/* Written by David Madore <david.madore@ens.fr>, with code taken in
- * part from Colin Plumb. */
-/* Public domain (1999/11/24) */
-
-/* Note: these routines do not depend on endianness. */
-
-/* === The header === */
-
-/* Put this in md5.h if you don't like having everything in one big
- * file. */
-
-#ifndef _DMADORE_MD5_H
-#define _DMADORE_MD5_H
-
-struct md5_ctx {
-  /* The four chaining variables */
-  unsigned long buf[4];
-  /* Count number of message bits */
-  unsigned long bits[2];
-  /* Data being fed in */
-  unsigned long in[16];
-  /* Our position within the 512 bits (always between 0 and 63) */
-  int b;
-};
-
-void MD5_transform (unsigned long buf[4], const unsigned long in[16]);
-void MD5_start (struct md5_ctx *context);
-void MD5_feed (struct md5_ctx *context, unsigned char inb);
-void MD5_stop (struct md5_ctx *context, unsigned char digest[16]);
-
-#endif /* not defined _DMADORE_MD5_H */
-
diff --git a/src/utils/sha.c b/src/utils/sha.c
deleted file mode 100644 (file)
index 14791bd..0000000
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- * 
- *  Gabber
- *  Copyright (C) 1999-2000 Dave Smith & Julian Missig
- */
-
-
-/* 
-   Implements the Secure Hash Algorithm (SHA1)
-
-   Copyright (C) 1999 Scott G. Miller
-
-   Released under the terms of the GNU General Public License v2
-   see file COPYING for details
-
-   Credits: 
-      Robert Klep <robert@ilse.nl>  -- Expansion function fix 
-         Thomas "temas" Muldowney <temas@box5.net>:
-                       -- shahash() for string fun
-                       -- Will add the int32 stuff in a few
-                       
-   ---
-   FIXME: This source takes int to be a 32 bit integer.  This
-   may vary from system to system.  I'd use autoconf if I was familiar
-   with it.  Anyone want to help me out?
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#ifdef MACOS
-#  include <string.h>
-#else
-#  include <sys/stat.h>
-#  include <sys/types.h>
-#endif
-
-#include <string.h>
-
-#ifndef WIN32
-#  include <unistd.h>
-#  define INT64 long long
-#else
-#  include <string.h>
-#  define snprintf _snprintf
-#  define INT64 __int64
-#endif
-
-#define switch_endianness(x) (x<<24 & 0xff000000) | \
-                             (x<<8  & 0x00ff0000) | \
-                             (x>>8  & 0x0000ff00) | \
-                             (x>>24 & 0x000000ff)
-
-/* Initial hash values */
-#define Ai 0x67452301 
-#define Bi 0xefcdab89
-#define Ci 0x98badcfe
-#define Di 0x10325476
-#define Ei 0xc3d2e1f0
-
-/* SHA1 round constants */
-#define K1 0x5a827999
-#define K2 0x6ed9eba1
-#define K3 0x8f1bbcdc 
-#define K4 0xca62c1d6
-
-/* Round functions.  Note that f2() is used in both rounds 2 and 4 */
-#define f1(B,C,D) ((B & C) | ((~B) & D))
-#define f2(B,C,D) (B ^ C ^ D)
-#define f3(B,C,D) ((B & C) | (B & D) | (C & D))
-
-/* left circular shift functions (rotate left) */
-#define rol1(x) ((x<<1) | ((x>>31) & 1))
-#define rol5(A) ((A<<5) | ((A>>27) & 0x1f))
-#define rol30(B) ((B<<30) | ((B>>2) & 0x3fffffff))
-
-/*
-  Hashes 'data', which should be a pointer to 512 bits of data (sixteen
-  32 bit ints), into the ongoing 160 bit hash value (five 32 bit ints)
-  'hash'
-*/
-int 
-sha_hash(int *data, int *hash)  
-{
-  int W[80];
-  unsigned int A=hash[0], B=hash[1], C=hash[2], D=hash[3], E=hash[4];
-  unsigned int t, x, TEMP;
-
-  for (t=0; t<16; t++) 
-    {
-#ifndef WORDS_BIGENDIAN
-      W[t]=switch_endianness(data[t]);
-#else 
-      W[t]=data[t];
-#endif
-    }
-
-
-  /* SHA1 Data expansion */
-  for (t=16; t<80; t++) 
-    {
-      x=W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
-      W[t]=rol1(x);
-    }
-
-  /* SHA1 main loop (t=0 to 79) 
-   This is broken down into four subloops in order to use
-   the correct round function and constant */
-  for (t=0; t<20; t++) 
-    {
-      TEMP=rol5(A) + f1(B,C,D) + E + W[t] + K1;
-      E=D;
-      D=C;
-      C=rol30(B);
-      B=A;
-      A=TEMP;
-    }
-  for (; t<40; t++) 
-    {
-      TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K2;
-      E=D;
-      D=C;
-      C=rol30(B);
-      B=A;
-      A=TEMP;
-    }
-  for (; t<60; t++) 
-    {
-      TEMP=rol5(A) + f3(B,C,D) + E + W[t] + K3;
-      E=D;
-      D=C;
-      C=rol30(B);
-      B=A;
-      A=TEMP;
-    }
-  for (; t<80; t++) 
-    {
-      TEMP=rol5(A) + f2(B,C,D) + E + W[t] + K4;
-      E=D;
-      D=C;
-      C=rol30(B);
-      B=A;
-      A=TEMP;
-    }
-  hash[0]+=A; 
-  hash[1]+=B;
-  hash[2]+=C;
-  hash[3]+=D;
-  hash[4]+=E;
-  return 0;
-}
-
-/*
-  Takes a pointer to a 160 bit block of data (five 32 bit ints) and
-  intializes it to the start constants of the SHA1 algorithm.  This
-  must be called before using hash in the call to sha_hash
-*/
-int 
-sha_init(int *hash) 
-{
-  hash[0]=Ai;
-  hash[1]=Bi;
-  hash[2]=Ci;
-  hash[3]=Di;
-  hash[4]=Ei;
-  return 0;
-}
-
-int strprintsha(char *dest, int *hashval) 
-{
-       int x;
-       char *hashstr = dest;
-       for (x=0; x<5; x++) 
-       {
-               snprintf(hashstr, 9, "%08x", hashval[x]);
-               hashstr+=8;
-       }
-       //snprintf(hashstr++, 1, "\0");
-       hashstr[0] = '\0';
-       hashstr++;
-
-       return 0;
-}
-
-char *shahash(const char *str) 
-{
-       char read_buffer[65];
-       //int read_buffer[64];
-       int c=1, i;
-       
-       INT64 length=0;
-
-       int strsz;
-       static char final[40];
-       int *hashval;
-
-       hashval = (int *)malloc(20);
-
-       sha_init(hashval);
-
-       strsz = strlen(str);
-
-       if(strsz == 0) 
-       {
-            memset(read_buffer, 0, 65);
-            read_buffer[0] = 0x80;
-            sha_hash((int *)read_buffer, hashval);
-       }
-
-       while (strsz>0) 
-       {
-               memset(read_buffer, 0, 65);
-               strncpy((char*)read_buffer, str, 64);
-               c = strlen((char *)read_buffer);
-               length+=c;
-               strsz-=c;
-               if (strsz<=0) 
-               {
-                       length<<=3;     
-                       read_buffer[c]=(char)0x80;
-                       for (i=c+1; i<64; i++) 
-                               read_buffer[i]=0;
-                       if (c>55) 
-                       {
-                               /* we need to do an entire new block */
-                               sha_hash((int *)read_buffer, hashval);
-                               for (i=0; i<14; i++) 
-                                       ((int*)read_buffer)[i]=0;
-                       }      
-#ifndef WORDS_BIGENDIAN
-                       for (i=0; i<8; i++) 
-                       {
-                               read_buffer[56+i]=(char)(length>>(56-(i*8))) & 0xff;
-                       }
-#else  
-                       memcpy(read_buffer+56, &length, 8);
-#endif
-               }
-               
-               sha_hash((int *)read_buffer, hashval);
-               str+=64;
-       }
-
-       strprintsha((char *)final, hashval);
-       free(hashval);
-       return (char *)final;
-}
diff --git a/src/utils/sha.h b/src/utils/sha.h
deleted file mode 100644 (file)
index 6c3d2d4..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-// sha.h
-// Jabber client library
-//
-// Original Code Copyright (C) 1999-2001 Dave Smith (dave@jabber.org)
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-// 
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Lesser General Public License for more details.
-// 
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-// Contributor(s): Julian Missig
-//
-// This Original Code has been modified by IBM Corporation. Modifications 
-// made by IBM described herein are Copyright (c) International Business 
-// Machines Corporation, 2002.
-//
-// Date             Modified by     Description of modification
-// 01/20/2002       IBM Corp.       Updated to libjudo 1.1.1
-// 2002-03-05       IBM Corp.       Updated to libjudo 1.1.5
-// 2002-07-09       IBM Corp.       Added Roster::getSession()
-//
-// =====================================================================================
-
-
-//#ifdef WIN32
-     char* shahash(const char* str);
-//#else
-//extern "C" {
-//     char* shahash(const char* str);
-//}
-//#endif
-
diff --git a/src/utils/socket_bundle.c b/src/utils/socket_bundle.c
deleted file mode 100644 (file)
index 4356ef6..0000000
+++ /dev/null
@@ -1,743 +0,0 @@
-#include "socket_bundle.h"
-
-/* buffer used to read from the sockets */
-#define RBUFSIZE 1024
-
-static socket_node* _socket_add_node(socket_manager* mgr,
-               int endpoint, int addr_type, int sock_fd, int parent_id );
-static socket_node* socket_find_node(socket_manager* mgr, int sock_fd);
-static void socket_remove_node(socket_manager*, int sock_fd);
-static int _socket_send(int sock_fd, const char* data, int flags);
-static int _socket_route_data(socket_manager* mgr, int num_active, fd_set* read_set);
-static int _socket_route_data_id( socket_manager* mgr, int sock_id);
-static int _socket_handle_new_client(socket_manager* mgr, socket_node* node);
-static int _socket_handle_client_data(socket_manager* mgr, socket_node* node);
-
-
-/* -------------------------------------------------------------------- 
-       Test Code 
-       -------------------------------------------------------------------- */
-/*
-int count = 0;
-void printme(void* blob, socket_manager* mgr, 
-               int sock_fd, char* data, int parent_id) {
-
-       fprintf(stderr, "Got data from socket %d with parent %d => %s", 
-                       sock_fd, parent_id, data );
-
-       socket_send(sock_fd, data);
-
-       if(count++ > 2) {
-               socket_disconnect(mgr, sock_fd);
-               _socket_print_list(mgr);
-       }
-}
-
-int main(int argc, char* argv[]) {
-       socket_manager manager;
-       memset(&manager, 0, sizeof(socket_manager));
-       int port = 11000;
-       if(argv[1])
-               port = atoi(argv[1]);
-
-       manager.data_received = &printme;
-       socket_open_tcp_server(&manager, port);
-
-       while(1)
-               socket_wait_all(&manager, -1);
-
-       return 0;
-}
-*/
-/* -------------------------------------------------------------------- */
-
-
-/* allocates and inserts a new socket node into the nodeset.
-       if parent_id is positive and non-zero, it will be set */
-static socket_node* _socket_add_node(socket_manager* mgr, 
-               int endpoint, int addr_type, int sock_fd, int parent_id ) {
-
-       if(mgr == NULL) return NULL;
-       osrfLogInternal( OSRF_LOG_MARK, "Adding socket node with fd %d", sock_fd);
-       socket_node* new_node = safe_malloc(sizeof(socket_node));
-
-       new_node->endpoint      = endpoint;
-       new_node->addr_type     = addr_type;
-       new_node->sock_fd               = sock_fd;
-       new_node->next                  = NULL;
-       new_node->parent_id = 0;
-       if(parent_id > 0)
-               new_node->parent_id = parent_id;
-
-       new_node->next                  = mgr->socket;
-       mgr->socket                             = new_node;
-       return new_node;
-}
-
-/* creates a new server socket node and adds it to the socket set.
-       returns new socket fd on success.  -1 on failure.
-       socket_type is one of INET or UNIX  */
-int socket_open_tcp_server(socket_manager* mgr, int port, char* listen_ip) {
-
-       if( mgr == NULL ) {
-               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): NULL mgr"); 
-               return -1;
-       }
-
-       int sock_fd;
-       struct sockaddr_in server_addr;
-
-       errno = 0;
-       sock_fd = socket(AF_INET, SOCK_STREAM, 0);
-       if(sock_fd < 0) {
-               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): Unable to create TCP socket: %s",
-                       strerror( errno ) );
-               return -1;
-       }
-
-       server_addr.sin_family = AF_INET;
-
-       if(listen_ip != NULL) {
-               server_addr.sin_addr.s_addr = inet_addr(listen_ip);
-       } else {
-               server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-       }
-
-       server_addr.sin_port = htons(port);
-
-       errno = 0;
-       if(bind( sock_fd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0) {
-               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): cannot bind to port %d: %s",
-                       port, strerror( errno ) );
-               return -1;
-       }
-
-       errno = 0;
-       if(listen(sock_fd, 20) == -1) {
-               osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_server(): listen() returned error: %s",
-                       strerror( errno ) );
-               return -1;
-       }
-
-       _socket_add_node(mgr, SERVER_SOCKET, INET, sock_fd, 0);
-       return sock_fd;
-}
-
-int socket_open_unix_server(socket_manager* mgr, char* path) {
-       if(mgr == NULL || path == NULL) return -1;
-
-       osrfLogDebug( OSRF_LOG_MARK, "opening unix socket at %s", path);
-       int sock_fd;
-       struct sockaddr_un server_addr;
-
-       errno = 0;
-       sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
-       if(sock_fd < 0){
-               osrfLogWarning( OSRF_LOG_MARK, "socket_open_unix_server(): socket() failed: %s",
-                       strerror( errno ) );
-               return -1;
-       }
-
-       server_addr.sun_family = AF_UNIX;
-       strcpy(server_addr.sun_path, path);
-
-       errno = 0;
-       if( bind(sock_fd, (struct sockaddr*) &server_addr, 
-                               sizeof(struct sockaddr_un)) < 0) {
-               osrfLogWarning( OSRF_LOG_MARK, 
-                       "socket_open_unix_server(): cannot bind to unix port %s: %s",
-                       path, strerror( errno ) );
-               return -1;
-       }
-
-       errno = 0;
-       if(listen(sock_fd, 20) == -1) {
-               osrfLogWarning( OSRF_LOG_MARK, "socket_open_unix_server(): listen() returned error: %s",
-                       strerror( errno ) );
-               return -1;
-       }
-
-       osrfLogDebug( OSRF_LOG_MARK, "unix socket successfully opened");
-       
-       int i = 1;
-
-       /* causing problems with router for some reason ... */
-       //osrfLogDebug( OSRF_LOG_MARK, "Setting SO_REUSEADDR");
-       //setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
-       
-       //osrfLogDebug( OSRF_LOG_MARK, "Setting TCP_NODELAY");
-       setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
-
-       _socket_add_node(mgr, SERVER_SOCKET, UNIX, sock_fd, 0);
-       return sock_fd;
-}
-
-
-
-int socket_open_udp_server( 
-               socket_manager* mgr, int port, char* listen_ip ) {
-
-       int sockfd;
-       struct sockaddr_in server_addr;
-
-       errno = 0;
-       if( (sockfd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
-               osrfLogWarning( OSRF_LOG_MARK, "Unable to create UDP socket: %s", strerror( errno ) );
-               return -1;
-       }
-
-       server_addr.sin_family = AF_INET;
-       server_addr.sin_port = htons(port);
-       if(listen_ip) server_addr.sin_addr.s_addr = inet_addr(listen_ip);
-       else server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-
-       errno = 0;
-       if( (bind (sockfd, (struct sockaddr *) &server_addr,sizeof(server_addr))) ) {
-               osrfLogWarning( OSRF_LOG_MARK, "Unable to bind to UDP port %d: %s",
-                       port, strerror( errno ) );
-               return -1;
-       }
-
-       _socket_add_node(mgr, SERVER_SOCKET, INET, sockfd, 0);
-       return sockfd;
-}
-
-
-int socket_open_tcp_client(socket_manager* mgr, int port, char* dest_addr) {
-
-       struct sockaddr_in remoteAddr, localAddr;
-   struct hostent *hptr;
-   int sock_fd;
-
-   // ------------------------------------------------------------------
-   // Create the socket
-   // ------------------------------------------------------------------
-   errno = 0;
-   if( (sock_fd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
-          osrfLogWarning( OSRF_LOG_MARK,  "socket_open_tcp_client(): Cannot create TCP socket: %s",
-                       strerror( errno ) );
-      return -1;
-   }
-
-       int i = 1;
-       //osrfLogDebug( OSRF_LOG_MARK, "Setting TCP_NODELAY");
-       setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, &i, sizeof(i));
-
-
-   // ------------------------------------------------------------------
-   // Get the hostname
-   // ------------------------------------------------------------------
-   errno = 0;
-   if( (hptr = gethostbyname( dest_addr ) ) == NULL ) {
-          osrfLogWarning(  OSRF_LOG_MARK, "socket_open_tcp_client(): Unknown Host => %s: %s",
-                                               dest_addr, strerror( errno ) );
-      return -1;
-   }
-
-   // ------------------------------------------------------------------
-   // Construct server info struct
-   // ------------------------------------------------------------------
-   memset( &remoteAddr, 0, sizeof(remoteAddr));
-   remoteAddr.sin_family = AF_INET;
-   remoteAddr.sin_port = htons( port );
-   memcpy( (char*) &remoteAddr.sin_addr.s_addr,
-         hptr->h_addr_list[0], hptr->h_length );
-
-   // ------------------------------------------------------------------
-   // Construct local info struct
-   // ------------------------------------------------------------------
-   memset( &localAddr, 0, sizeof( localAddr ) );
-   localAddr.sin_family = AF_INET;
-   localAddr.sin_addr.s_addr = htonl( INADDR_ANY );
-   localAddr.sin_port = htons(0);
-
-   // ------------------------------------------------------------------
-   // Bind to a local port
-   // ------------------------------------------------------------------
-   errno = 0;
-   if( bind( sock_fd, (struct sockaddr *) &localAddr, sizeof( localAddr ) ) < 0 ) {
-          osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot bind to local port: %s",
-               strerror( errno ) );
-      return -1;
-   }
-
-   // ------------------------------------------------------------------
-   // Connect to server
-   // ------------------------------------------------------------------
-   errno = 0;
-   if( connect( sock_fd, (struct sockaddr*) &remoteAddr, sizeof( struct sockaddr_in ) ) < 0 ) {
-          osrfLogWarning( OSRF_LOG_MARK, "socket_open_tcp_client(): Cannot connect to server %s: %s",
-                  dest_addr, strerror(errno) );
-          return -1;
-   }
-
-       _socket_add_node(mgr, CLIENT_SOCKET, INET, sock_fd, -1 );
-
-   return sock_fd;
-}
-
-
-int socket_open_udp_client( 
-               socket_manager* mgr, int port, char* dest_addr) {
-
-       int sockfd;
-       struct sockaddr_in client_addr, server_addr;
-       struct hostent* host;
-
-       errno = 0;
-       if( (host = gethostbyname(dest_addr)) == NULL) {
-               osrfLogWarning( OSRF_LOG_MARK, "Unable to resolve host: %s: %s",
-                       dest_addr, strerror( errno ) );
-               return -1;
-       }
-
-       server_addr.sin_family = host->h_addrtype;
-       memcpy((char *) &server_addr.sin_addr.s_addr,
-                            host->h_addr_list[0], host->h_length);
-       server_addr.sin_port = htons(port);
-
-       errno = 0;
-       if( (sockfd = socket(AF_INET,SOCK_DGRAM,0)) < 0 ) {
-               osrfLogWarning( OSRF_LOG_MARK, "socket_open_udp_client(): Unable to create UDP socket: %s", strerror( errno ) );
-               return -1;
-       }
-
-       client_addr.sin_family = AF_INET;
-       client_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-       client_addr.sin_port = htons(0);
-
-       errno = 0;
-       if( (bind(sockfd, (struct sockaddr *) &client_addr, sizeof(client_addr))) < 0 ) {
-               osrfLogWarning( OSRF_LOG_MARK, "Unable to bind UDP socket: %s", strerror( errno ) );
-               return -1;
-       }
-
-       _socket_add_node(mgr, CLIENT_SOCKET, INET, sockfd, -1 );
-
-       return sockfd;
-}
-
-
-int socket_open_unix_client(socket_manager* mgr, char* sock_path) {
-
-       int sock_fd, len;
-   struct sockaddr_un usock;
-
-   errno = 0;
-   if( (sock_fd = socket( AF_UNIX, SOCK_STREAM, 0 )) < 0 ) {
-          osrfLogWarning(  OSRF_LOG_MARK, "socket_open_unix_client(): Cannot create UNIX socket: %s", strerror( errno ) );
-               return -1;
-       }
-
-   usock.sun_family = AF_UNIX;
-   strcpy( usock.sun_path, sock_path );
-
-   len = sizeof( usock.sun_family ) + strlen( usock.sun_path );
-
-   errno = 0;
-   if( connect( sock_fd, (struct sockaddr *) &usock, len ) < 0 ) {
-          osrfLogWarning(  OSRF_LOG_MARK, "Error connecting to unix socket: %s",
-                       strerror( errno ) );
-               return -1;
-       }
-
-       _socket_add_node(mgr, CLIENT_SOCKET, UNIX, sock_fd, -1 );
-
-   return sock_fd;
-}
-
-
-/* returns the socket_node with the given sock_fd */
-static socket_node* socket_find_node(socket_manager* mgr, int sock_fd) {
-       if(mgr == NULL) return NULL;
-       socket_node* node = mgr->socket;
-       while(node) {
-               if(node->sock_fd == sock_fd)
-                       return node;
-               node = node->next;
-       }
-       return NULL;
-}
-
-/* removes the node with the given sock_fd from the list and frees it */
-static void socket_remove_node(socket_manager* mgr, int sock_fd) {
-
-       if(mgr == NULL) return;
-
-       osrfLogDebug( OSRF_LOG_MARK, "removing socket %d", sock_fd);
-
-       socket_node* head = mgr->socket;
-       socket_node* tail = head;
-       if(head == NULL) return;
-
-       /* if removing the first node in the list */
-       if(head->sock_fd == sock_fd) {
-               mgr->socket = head->next;
-               free(head);
-               return;
-       }
-
-       head = head->next;
-
-       /* if removing any other node */
-       while(head) {
-               if(head->sock_fd == sock_fd) {
-                       tail->next = head->next;
-                       free(head);
-                       return;
-               }
-               tail = head;
-               head = head->next;
-       }
-}
-
-
-void _socket_print_list(socket_manager* mgr) {
-       if(mgr == NULL) return;
-       socket_node* node = mgr->socket;
-       osrfLogDebug( OSRF_LOG_MARK, "socket_node list: [");
-       while(node) {
-               osrfLogDebug( OSRF_LOG_MARK, "sock_fd: %d | parent_id: %d", 
-                               node->sock_fd, node->parent_id);
-               node = node->next;
-       }
-       osrfLogDebug( OSRF_LOG_MARK, "]");
-}
-
-/* sends the given data to the given socket */
-int socket_send(int sock_fd, const char* data) {
-       return _socket_send( sock_fd, data, 0);
-}
-
-/* utility method */
-static int _socket_send(int sock_fd, const char* data, int flags) {
-
-       signal(SIGPIPE, SIG_IGN); /* in case a unix socket was closed */
-
-       errno = 0;
-       size_t r = send( sock_fd, data, strlen(data), flags );
-       int local_errno = errno;
-       
-       if( r == -1 ) {
-               osrfLogWarning( OSRF_LOG_MARK, "_socket_send(): Error sending data with return %d", r );
-               osrfLogWarning( OSRF_LOG_MARK, "Last Sys Error: %s", strerror(local_errno));
-               return -1;
-       }
-
-       return 0;
-}
-
-
-/* sends the given data to the given socket. 
- * sets the send flag MSG_DONTWAIT which will allow the 
- * process to continue even if the socket buffer is full
- * returns 0 on success, -1 otherwise */
-//int socket_send_nowait( int sock_fd, const char* data) {
-//     return _socket_send( sock_fd, data, MSG_DONTWAIT);
-//}
-
-
-/*
- * Waits at most usecs microseconds for the send buffer of the given
- * socket to accept new data.  This does not guarantee that the 
- * socket will accept all the data we want to give it.
- */
-int socket_send_timeout( int sock_fd, const char* data, int usecs ) {
-
-       fd_set write_set;
-       FD_ZERO( &write_set );
-       FD_SET( sock_fd, &write_set );
-
-       int mil = 1000000;
-       int secs = (int) usecs / mil;
-       usecs = usecs - (secs * mil);
-
-       struct timeval tv;
-       tv.tv_sec = secs;
-       tv.tv_usec = usecs;
-
-       errno = 0;
-       int ret = select( sock_fd + 1, NULL, &write_set, NULL, &tv);
-       if( ret > 0 ) return _socket_send( sock_fd, data, 0);
-
-       osrfLogError(OSRF_LOG_MARK, "socket_send_timeout(): "
-               "timed out on send for socket %d after %d secs, %d usecs: %s",
-               sock_fd, secs, usecs, strerror( errno ) );
-
-       return -1;
-}
-
-
-/* disconnects the node with the given sock_fd and removes
-       it from the socket set */
-void socket_disconnect(socket_manager* mgr, int sock_fd) {
-       osrfLogInternal( OSRF_LOG_MARK, "Closing socket %d", sock_fd);
-       close( sock_fd );
-       socket_remove_node(mgr, sock_fd);
-}
-
-
-/* we assume that if select() fails, the socket is no longer valid */
-int socket_connected(int sock_fd) {
-       fd_set read_set;
-       FD_ZERO( &read_set );
-       FD_SET( sock_fd, &read_set );
-       if( select( sock_fd + 1, &read_set, NULL, NULL, NULL) == -1 ) 
-               return 0;
-       return 1;
-
-}
-
-/* this only waits on the server socket and does not handle the actual
-       data coming in from the client..... XXX */
-int socket_wait(socket_manager* mgr, int timeout, int sock_fd) {
-
-       int retval = 0;
-       fd_set read_set;
-       FD_ZERO( &read_set );
-       FD_SET( sock_fd, &read_set );
-
-       struct timeval tv;
-       tv.tv_sec = timeout;
-       tv.tv_usec = 0;
-       errno = 0;
-
-       if( timeout < 0 ) {  
-
-               // If timeout is -1, we block indefinitely
-               if( (retval = select( sock_fd + 1, &read_set, NULL, NULL, NULL)) == -1 ) {
-                       osrfLogDebug( OSRF_LOG_MARK, "Call to select() interrupted: Sys Error: %s", strerror(errno));
-                       return -1;
-               }
-
-       } else if( timeout > 0 ) { /* timeout of 0 means don't block */
-
-               if( (retval = select( sock_fd + 1, &read_set, NULL, NULL, &tv)) == -1 ) {
-                       osrfLogDebug( OSRF_LOG_MARK, "Call to select() interrupted: Sys Error: %s", strerror(errno));
-                       return -1;
-               }
-       }
-
-       osrfLogInternal( OSRF_LOG_MARK, "%d active sockets after select()", retval);
-       return _socket_route_data_id(mgr, sock_fd);
-}
-
-
-int socket_wait_all(socket_manager* mgr, int timeout) {
-
-       if(mgr == NULL) {
-               osrfLogWarning( OSRF_LOG_MARK,  "socket_wait_all(): null mgr" );
-               return -1;
-       }
-
-       int retval = 0;
-       fd_set read_set;
-       FD_ZERO( &read_set );
-
-       socket_node* node = mgr->socket;
-       int max_fd = 0;
-       while(node) {
-               osrfLogInternal( OSRF_LOG_MARK, "Adding socket fd %d to select set",node->sock_fd);
-               FD_SET( node->sock_fd, &read_set );
-               if(node->sock_fd > max_fd) max_fd = node->sock_fd;
-               node = node->next;
-       }
-       max_fd += 1;
-
-       struct timeval tv;
-       tv.tv_sec = timeout;
-       tv.tv_usec = 0;
-       errno = 0;
-
-       if( timeout < 0 ) {  
-
-               // If timeout is -1, there is no timeout passed to the call to select
-               if( (retval = select( max_fd, &read_set, NULL, NULL, NULL)) == -1 ) {
-                       osrfLogWarning( OSRF_LOG_MARK, "select() call aborted: %s", strerror(errno));
-                       return -1;
-               }
-
-       } else if( timeout != 0 ) { /* timeout of 0 means don't block */
-
-               if( (retval = select( max_fd, &read_set, NULL, NULL, &tv)) == -1 ) {
-                       osrfLogWarning( OSRF_LOG_MARK, "select() call aborted: %s", strerror(errno));
-                       return -1;
-               }
-       }
-
-       osrfLogDebug( OSRF_LOG_MARK, "%d active sockets after select()", retval);
-       return _socket_route_data(mgr, retval, &read_set);
-}
-
-/* iterates over the sockets in the set and handles active sockets.
-       new sockets connecting to server sockets cause the creation
-       of a new socket node.
-       Any new data read is is passed off to the data_received callback
-       as it arrives */
-/* determines if we're receiving a new client or data
-       on an existing client */
-static int _socket_route_data(
-       socket_manager* mgr, int num_active, fd_set* read_set) {
-
-       if(!(mgr && read_set)) return -1;
-
-       int last_failed_id = -1;
-
-
-       /* come back here if someone yanks a socket_node from beneath us */
-       while(1) {
-
-               socket_node* node = mgr->socket;
-               int handled = 0;
-               int status = 0;
-               
-               while(node && (handled < num_active)) {
-       
-                       int sock_fd = node->sock_fd;
-                       
-                       if(last_failed_id != -1) {
-                               /* in case it was not removed by our overlords */
-                               osrfLogInternal( OSRF_LOG_MARK, "Attempting to remove last_failed_id of %d", last_failed_id);
-                               socket_remove_node( mgr, last_failed_id );
-                               last_failed_id = -1;
-                               status = -1;
-                               break;
-                       }
-       
-                       /* does this socket have data? */
-                       if( FD_ISSET( sock_fd, read_set ) ) {
-       
-                               osrfLogInternal( OSRF_LOG_MARK, "Socket %d active", sock_fd);
-                               handled++;
-                               FD_CLR(sock_fd, read_set);
-       
-                               if(node->endpoint == SERVER_SOCKET) 
-                                       _socket_handle_new_client(mgr, node);
-       
-                               else
-                                       status = _socket_handle_client_data(mgr, node);
-       
-                               /* someone may have yanked a socket_node out from under 
-                                       us...start over with the first socket */
-                               if(status == -1)  {
-                                       last_failed_id = sock_fd;
-                                       osrfLogInternal( OSRF_LOG_MARK, "Backtracking back to start of loop because "
-                                                       "of -1 return code from _socket_handle_client_data()");
-                               }
-                       }
-
-                       if(status == -1) break;
-                       node = node->next;
-
-               } // is_set
-
-               if(status == 0) break;
-               if(status == -1) status = 0;
-       } 
-
-       return 0;
-}
-
-
-/* routes data from a single known socket */
-static int _socket_route_data_id( socket_manager* mgr, int sock_id) {
-       socket_node* node = socket_find_node(mgr, sock_id);     
-       int status = 0;
-
-       if(node) {
-               if(node->endpoint == SERVER_SOCKET) 
-                       _socket_handle_new_client(mgr, node);
-       
-               if(node->endpoint == CLIENT_SOCKET ) 
-                       status = _socket_handle_client_data(mgr, node);
-
-               if(status == -1) {
-                       socket_remove_node(mgr, sock_id);
-                       return -1;
-               }
-               return 0;
-       } 
-
-       return -1;
-}
-
-
-static int _socket_handle_new_client(socket_manager* mgr, socket_node* node) {
-       if(mgr == NULL || node == NULL) return -1;
-
-       errno = 0;
-       int new_sock_fd;
-       new_sock_fd = accept(node->sock_fd, NULL, NULL);
-       if(new_sock_fd < 0) {
-               osrfLogWarning( OSRF_LOG_MARK, "_socket_handle_new_client(): accept() failed: %s",
-                       strerror( errno ) );
-               return -1;
-       }
-
-       if(node->addr_type == INET) {
-               _socket_add_node(mgr, CLIENT_SOCKET, INET, new_sock_fd, node->sock_fd);
-               osrfLogDebug( OSRF_LOG_MARK, "Adding new INET client for %d", node->sock_fd);
-
-       } else if(node->addr_type == UNIX) {
-               _socket_add_node(mgr, CLIENT_SOCKET, UNIX, new_sock_fd, node->sock_fd);
-               osrfLogDebug( OSRF_LOG_MARK, "Adding new UNIX client for %d", node->sock_fd);
-       }
-
-       return 0;
-}
-
-
-static int _socket_handle_client_data(socket_manager* mgr, socket_node* node) {
-       if(mgr == NULL || node == NULL) return -1;
-
-       char buf[RBUFSIZE];
-       int read_bytes;
-       int sock_fd = node->sock_fd;
-
-       memset(buf, 0, RBUFSIZE);
-       set_fl(sock_fd, O_NONBLOCK);
-
-       osrfLogInternal( OSRF_LOG_MARK, "%ld : Received data at %f\n", (long) getpid(), get_timestamp_millis());
-
-       while( (read_bytes = recv(sock_fd, buf, RBUFSIZE-1, 0) ) > 0 ) {
-               osrfLogInternal( OSRF_LOG_MARK, "Socket %d Read %d bytes and data: %s", sock_fd, read_bytes, buf);
-               if(mgr->data_received)
-                       mgr->data_received(mgr->blob, mgr, sock_fd, buf, node->parent_id);
-
-               memset(buf, 0, RBUFSIZE);
-       }
-    int local_errno = errno; /* capture errno as set by recv() */
-
-       if(socket_find_node(mgr, sock_fd)) {  /* someone may have closed this socket */
-               clr_fl(sock_fd, O_NONBLOCK); 
-               if(read_bytes < 0) { 
-                       if(local_errno != EAGAIN) 
-                               osrfLogWarning(OSRF_LOG_MARK,  " * Error reading socket with error %s", strerror(local_errno));
-               }
-
-       } else { return -1; } /* inform the caller that this node has been tampered with */
-
-       if(read_bytes == 0) {  /* socket closed by client */
-               if(mgr->on_socket_closed) {
-                       mgr->on_socket_closed(mgr->blob, sock_fd);
-               }
-               return -1;
-       }
-
-       return 0;
-
-}
-
-
-void socket_manager_free(socket_manager* mgr) {
-       if(mgr == NULL) return;
-       socket_node* tmp;
-       while(mgr->socket) {
-               tmp = mgr->socket->next;
-               socket_disconnect(mgr, mgr->socket->sock_fd);
-               mgr->socket = tmp;
-       }
-       free(mgr);
-
-}
-
diff --git a/src/utils/socket_bundle.h b/src/utils/socket_bundle.h
deleted file mode 100644 (file)
index 28a5405..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "utils.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-
-#include "utils.h"
-#include "log.h"
-
-//---------------------------------------------------------------
-// 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>
-#include <netinet/tcp.h>
-#include <sys/un.h>
-
-#include <signal.h>
-
-#ifndef SOCKET_BUNDLE_H
-#define SOCKET_BUNDLE_H
-
-
-#define SERVER_SOCKET                  1
-#define CLIENT_SOCKET                  2
-
-#define INET 10 
-#define UNIX 11 
-
-
-/* models a single socket connection */
-struct socket_node_struct {
-       int endpoint;           /* SERVER_SOCKET or CLIENT_SOCKET */
-       int addr_type;          /* INET or UNIX */
-       int sock_fd;
-       int parent_id;          /* if we're a new client for a server socket, 
-                                                               this points to the server socket we spawned from */
-       struct socket_node_struct* next;
-};
-typedef struct socket_node_struct socket_node;
-
-
-/* Maintains the socket set */
-struct socket_manager_struct {
-       /* callback for passing up any received data.  sock_fd is the socket
-               that read the data.  parent_id (if > 0) is the socket id of the 
-               server that this socket spawned from (i.e. it's a new client connection) */
-       void (*data_received) 
-               (void* blob, struct socket_manager_struct*, 
-                int sock_fd, char* data, int parent_id);
-
-       void (*on_socket_closed) (void* blob, int sock_fd);
-
-       socket_node* socket;
-       void* blob;
-};
-typedef struct socket_manager_struct socket_manager;
-
-void socket_manager_free(socket_manager* mgr);
-
-/* creates a new server socket node and adds it to the socket set.
-       returns socket id on success.  -1 on failure.
-       socket_type is one of INET or UNIX  */
-int socket_open_tcp_server(socket_manager*, int port, char* listen_ip );
-
-int socket_open_unix_server(socket_manager* mgr, char* path);
-
-int socket_open_udp_server( socket_manager* mgr, int port, char* listen_ip );
-
-/* creates a client TCP socket and adds it to the socket set.
-       returns 0 on success.  -1 on failure.  */
-int socket_open_tcp_client(socket_manager*, int port, char* dest_addr);
-
-/* creates a client UNIX socket and adds it to the socket set.
-       returns 0 on success.  -1 on failure.  */
-int socket_open_unix_client(socket_manager*, char* sock_path);
-
-int socket_open_udp_client( socket_manager* mgr, int port, char* dest_addr);
-
-/* sends the given data to the given socket. returns 0 on success, -1 otherwise */
-int socket_send(int sock_fd, const char* data);
-
-/* waits at most usecs microseconds for the socket buffer to
- * be available */
-int socket_send_timeout( int sock_fd, const char* data, int usecs );
-
-/* disconnects the node with the given sock_fd and removes
-       it from the socket set */
-void socket_disconnect(socket_manager*, int sock_fd);
-
-/* XXX This only works if 'sock_fd' is a client socket... */
-int socket_wait(socket_manager* mgr, int timeout, int sock_fd);
-
-/* waits on all sockets for incoming data.  
-       timeout == -1   | block indefinitely
-       timeout == 0    | don't block, just read any available data off all sockets
-       timeout == x    | block for at most x seconds */
-int socket_wait_all(socket_manager* mgr, int timeout);
-
-/* utility function for displaying the currently attached sockets */
-void _socket_print_list(socket_manager* mgr);
-
-int socket_connected(int sock_fd);
-
-#endif
diff --git a/src/utils/socket_test.c b/src/utils/socket_test.c
deleted file mode 100644 (file)
index 4bc7653..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "socket_bundle.h"
-
-int count = 0;
-void printme(void* blob, socket_manager* mgr, 
-               int sock_fd, char* data, int parent_id) {
-
-       fprintf(stderr, "Got data from socket %d with parent %d => %s", 
-                       sock_fd, parent_id, data );
-
-       socket_send(sock_fd, data);
-
-       if(count++ > 2) {
-//             socket_disconnect(mgr, sock_fd);
-               _socket_print_list(mgr);
-               socket_manager_free(mgr);
-               exit(0);
-       }
-}
-
-int main(int argc, char* argv[]) {
-       socket_manager* manager = safe_malloc(sizeof(socket_manager));
-       int port = 11000;
-       if(argv[1])
-               port = atoi(argv[1]);
-
-       manager->data_received = &printme;
-       socket_open_tcp_server(manager, port);
-
-       while(1)
-               socket_wait_all(manager, -1);
-
-       return 0;
-}
diff --git a/src/utils/string_array.c b/src/utils/string_array.c
deleted file mode 100644 (file)
index ee8c542..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-#include "string_array.h"
-
-osrfStringArray* osrfNewStringArray(int size) {
-       return init_string_array(size);
-}
-
-string_array* init_string_array(int size) {
-       if(size > STRING_ARRAY_MAX_SIZE)
-               osrfLogError( OSRF_LOG_MARK, "init_string_array size is too large");
-
-       /*
-       string_array* arr = 
-               (string_array*) safe_malloc(sizeof(string_array));
-               */
-       string_array* arr;
-       OSRF_MALLOC( arr, sizeof(string_array));
-
-       //arr->array = (char**) safe_malloc(size * sizeof(char*));
-       OSRF_MALLOC(arr->array, size * sizeof(char*));
-
-       arr->size = 0;
-       arr->arr_size = size;
-       return arr;
-}
-
-
-void osrfStringArrayAdd(osrfStringArray* arr, char* string) {
-       string_array_add(arr, string);
-}
-
-void string_array_add(string_array* arr, char* str) {
-       if(arr == NULL || str == NULL ) return;
-       if( strlen(str) < 1 ) return;
-
-       arr->size++;
-
-       if( arr->size > STRING_ARRAY_MAX_SIZE ) 
-               osrfLogError( OSRF_LOG_MARK, "string_array_add size is too large");
-
-       /* if necessary, double capacity */
-       if(arr->size >= arr->arr_size) {
-               arr->arr_size *= 2;
-               //char** tmp = (char**) safe_malloc(arr->arr_size * sizeof(char*));
-               char** tmp;
-               OSRF_MALLOC( tmp, arr->arr_size * sizeof(char*));
-               int i;
-
-               /* copy the string pointers over */
-               for( i = 0; i!= arr->size; i++ ) 
-                       tmp[i] = arr->array[i];
-
-               free(arr->array);
-               arr->array = tmp;
-       }
-
-       arr->array[arr->size - 1] = strdup(str);
-}
-
-char* osrfStringArrayGetString(osrfStringArray* arr, int index) {
-       return string_array_get_string(arr, index);
-}
-
-char* string_array_get_string(string_array* arr, int index) {
-       if(!arr || index < 0 || index >= arr->size ) return NULL;
-       return arr->array[index]; 
-}
-
-
-void osrfStringArrayFree(osrfStringArray* arr) {
-       string_array_destroy(arr);
-}
-
-void string_array_destroy(string_array* arr) {
-       if(arr) {
-               int i = 0;
-               while( i < arr->size ) free(arr->array[i++]);
-               free(arr->array);
-               free(arr);
-       }
-}
-
-
-int osrfStringArrayContains( osrfStringArray* arr, char* string ) {
-       if(!(arr && string)) return 0;
-       
-       int i;
-       for( i = 0; i != arr->size; i++ ) {
-               char* str = osrfStringArrayGetString(arr, i);
-               if(str) {
-                       if(!strcmp(str, string)) return 1;
-               }
-       }
-
-       return 0;
-}
-
-void osrfStringArrayRemove( osrfStringArray* arr, char* tstr) {
-       if(!(arr && tstr)) return;
-       int i;
-       for( i = 0; i != arr->size; i++ ) {
-               char* str = osrfStringArrayGetString(arr, i);
-               if(str) {
-                       if(!strcmp(str, tstr)) {
-                               free(arr->array[i]);
-                               arr->array[i] = NULL;
-                               break;
-                       }
-               }
-       }
-       for( ; i != arr->size; i++ ) 
-               arr->array[i] = arr->array[i+1];
-
-       arr->size--;
-}
-
-
diff --git a/src/utils/string_array.h b/src/utils/string_array.h
deleted file mode 100644 (file)
index c235b93..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-#include <stdio.h>
-
-#include "utils.h"
-#include "log.h"
-
-#define STRING_ARRAY_MAX_SIZE 1024
-
-#ifndef STRING_ARRAY_H
-#define STRING_ARRAY_H
-
-struct string_array_struct {
-               char** array;   
-               int size;
-               int arr_size;
-               int total_string_size;
-};
-typedef struct string_array_struct string_array;
-typedef struct string_array_struct osrfStringArray;
-
-osrfStringArray* init_string_array(int size);
-osrfStringArray* osrfNewStringArray(int size);
-
-void string_array_add(osrfStringArray*, char* string);
-void osrfStringArrayAdd(osrfStringArray*, char* string);
-
-char* string_array_get_string(osrfStringArray* arr, int index);
-char* osrfStringArrayGetString(osrfStringArray* arr, int index);
-
-/* returns true if this array contains the given string */
-int osrfStringArrayContains( osrfStringArray* arr, char* string );
-
-
-void string_array_destroy(osrfStringArray*);
-void osrfStringArrayFree(osrfStringArray*);
-
-/* total size of all included strings */
-int string_array_get_total_size(osrfStringArray* arr);
-
-void osrfStringArrayRemove( osrfStringArray* arr, char* str);
-
-#endif
diff --git a/src/utils/utils.c b/src/utils/utils.c
deleted file mode 100644 (file)
index 47b3d2f..0000000
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
-Copyright (C) 2005  Georgia Public Library Service 
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-*/
-
-#include "utils.h"
-#include <errno.h>
-
-inline void* safe_malloc( int size ) {
-       void* ptr = (void*) malloc( size );
-       if( ptr == NULL ) {
-               perror("safe_malloc(): Out of Memory" );
-               exit(99);
-       }
-       memset( ptr, 0, size );
-       return ptr;
-}
-
-/****************
- The following static variables, and the following two functions,
- overwrite the argv array passed to main().  The purpose is to
- change the program name as reported by ps and similar utilities.
-
- Warning: this code makes the non-portable assumption that the
- strings to which argv[] points are contiguous in memory.  The
- C Standard makes no such guarantee.
- ****************/
-static char** global_argv = NULL;
-static int global_argv_size = 0;
-
-int init_proc_title( int argc, char* argv[] ) {
-
-       global_argv = argv;
-
-       int i = 0;
-       while( i < argc ) {
-               int len = strlen( global_argv[i]);
-               bzero( global_argv[i++], len );
-               global_argv_size += len;
-       }
-
-       global_argv_size -= 2;
-       return 0;
-}
-
-int set_proc_title( char* format, ... ) {
-       VA_LIST_TO_STRING(format);
-       bzero( *(global_argv), global_argv_size );
-       return snprintf( *(global_argv), global_argv_size, VA_BUF );
-}
-
-
-/* utility method for profiling */
-double get_timestamp_millis() {
-       struct timeval tv;
-       gettimeofday(&tv, NULL);
-       double time     = (int)tv.tv_sec        + ( ((double)tv.tv_usec / 1000000) );
-       return time;
-}
-
-
-/* setting/clearing file flags */
-int set_fl( int fd, int flags ) {
-       
-       int val;
-
-       if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) 
-               return -1;
-
-       val |= flags;
-
-       if( fcntl( fd, F_SETFL, val ) < 0 ) 
-               return -1;
-
-       return 0;
-}
-       
-int clr_fl( int fd, int flags ) {
-       
-       int val;
-
-       if( (val = fcntl( fd, F_GETFL, 0) ) < 0 ) 
-               return -1;
-
-       val &= ~flags;
-
-       if( fcntl( fd, F_SETFL, val ) < 0 ) 
-               return -1;
-
-       return 0;
-}
-
-long va_list_size(const char* format, va_list args) {
-       int len = 0;
-       len = vsnprintf(NULL, 0, format, args);
-       va_end(args);
-       len += 2;
-       return len;
-}
-
-
-char* va_list_to_string(const char* format, ...) {
-
-       long len = 0;
-       va_list args;
-       va_list a_copy;
-
-       va_copy(a_copy, args);
-
-       va_start(args, format);
-       len = va_list_size(format, args);
-
-       char buf[len];
-       memset(buf, 0, len);
-
-       va_start(a_copy, format);
-       vsnprintf(buf, len - 1, format, a_copy);
-       va_end(a_copy);
-       return strdup(buf);
-}
-
-// ---------------------------------------------------------------------------------
-// Flesh out a ubiqitous growing string buffer
-// ---------------------------------------------------------------------------------
-
-growing_buffer* buffer_init(int num_initial_bytes) {
-
-       if( num_initial_bytes > BUFFER_MAX_SIZE ) return NULL;
-
-       size_t len = sizeof(growing_buffer);
-
-       growing_buffer* gb;
-       OSRF_MALLOC(gb, len);
-
-       gb->n_used = 0;/* nothing stored so far */
-       gb->size = num_initial_bytes;
-       OSRF_MALLOC(gb->buf, gb->size + 1);
-
-       return gb;
-}
-
-
-int buffer_fadd(growing_buffer* gb, const char* format, ... ) {
-
-       if(!gb || !format) return 0; 
-
-       long len = 0;
-       va_list args;
-       va_list a_copy;
-
-       va_copy(a_copy, args);
-
-       va_start(args, format);
-       len = va_list_size(format, args);
-
-       char buf[len];
-       memset(buf, 0, len);
-
-       va_start(a_copy, format);
-       vsnprintf(buf, len - 1, format, a_copy);
-       va_end(a_copy);
-
-       return buffer_add(gb, buf);
-
-}
-
-
-int buffer_add(growing_buffer* gb, char* data) {
-       if(!(gb && data)) return 0;
-
-       int data_len = strlen( data );
-
-       if(data_len == 0) return 0;
-
-       int total_len = data_len + gb->n_used;
-
-       if( total_len >= gb->size ) {
-               while( total_len >= gb->size ) {
-                       gb->size *= 2;
-               }
-       
-               if( gb->size > BUFFER_MAX_SIZE ) {
-                       fprintf(stderr, "Buffer reached MAX_SIZE of %d", BUFFER_MAX_SIZE );
-                       buffer_free( gb );
-                       return 0;
-               }
-       
-               char* new_data;
-               OSRF_MALLOC(new_data, gb->size );
-       
-               strcpy( new_data, gb->buf );
-               free( gb->buf );
-               gb->buf = new_data;
-       }
-
-       strcat( gb->buf, data );
-       gb->n_used = total_len;
-       return total_len;
-}
-
-
-int buffer_reset( growing_buffer *gb){
-       if( gb == NULL ) { return 0; }
-       if( gb->buf == NULL ) { return 0; }
-       memset( gb->buf, 0, gb->size );
-       gb->n_used = 0;
-       return 1;
-}
-
-/* Return a pointer to the text within a growing_buffer, */
-/* while destroying the growing_buffer itself.           */
-
-char* buffer_release( growing_buffer* gb) {
-       char* s = gb->buf;
-       s[gb->n_used] = '\0';
-       free( gb );
-       return s;
-}
-
-/* Destroy a growing_buffer and the text it contains */
-
-int buffer_free( growing_buffer* gb ) {
-       if( gb == NULL ) 
-               return 0;
-       free( gb->buf );
-       free( gb );
-       return 1;
-}
-
-char* buffer_data( growing_buffer *gb) {
-       return strdup( gb->buf );
-}
-
-
-/*
-#define OSRF_BUFFER_ADD_CHAR(gb, c)\
-       do {\
-               if(gb) {\
-                       if(gb->n_used < gb->size - 1)\
-                               gb->buf[gb->n_used++] = c;\
-                       else\
-                               buffer_add_char(gb, c);\
-               }\
-       }while(0)
-       */
-
-int buffer_add_char(growing_buffer* gb, char c) {
-       char buf[2];
-       buf[0] = c;
-       buf[1] = '\0';
-       buffer_add(gb, buf);
-       return 1;
-}
-
-
-
-char* uescape( const char* string, int size, int full_escape ) {
-
-       growing_buffer* buf = buffer_init(size + 64);
-       int clen = 0;
-       int idx = 0;
-       unsigned long int c = 0x0;
-
-       while (string[idx]) {
-
-               c = 0x0;
-
-               if ((unsigned char)string[idx] >= 0x80) { // not ASCII
-
-                       if ((unsigned char)string[idx] >= 0xC0 && (unsigned char)string[idx] <= 0xF4) { // starts a UTF8 string
-
-                               clen = 1;
-                               if (((unsigned char)string[idx] & 0xF0) == 0xF0) {
-                                       clen = 3;
-                                       c = (unsigned char)string[idx] ^ 0xF0;
-
-                               } else if (((unsigned char)string[idx] & 0xE0) == 0xE0) {
-                                       clen = 2;
-                                       c = (unsigned char)string[idx] ^ 0xE0;
-
-                               } else if (((unsigned char)string[idx] & 0xC0) == 0xC0) {
-                                       clen = 1;
-                                       c = (unsigned char)string[idx] ^ 0xC0;
-                               }
-
-                               for (;clen;clen--) {
-
-                                       idx++; // look at the next byte
-                                       c = (c << 6) | ((unsigned char)string[idx] & 0x3F); // add this byte worth
-
-                               }
-
-                               buffer_fadd(buf, "\\u%04x", c);
-
-                       } else {
-                               buffer_free(buf);
-                               return NULL;
-                       }
-
-               } else {
-                       c = string[idx];
-
-                       /* escape the usual suspects */
-                       if(full_escape) {
-                               switch(c) {
-                                       case '"':
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               OSRF_BUFFER_ADD_CHAR(buf, '"');
-                                               break;
-       
-                                       case '\b':
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               OSRF_BUFFER_ADD_CHAR(buf, 'b');
-                                               break;
-       
-                                       case '\f':
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               OSRF_BUFFER_ADD_CHAR(buf, 'f');
-                                               break;
-       
-                                       case '\t':
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               OSRF_BUFFER_ADD_CHAR(buf, 't');
-                                               break;
-       
-                                       case '\n':
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               OSRF_BUFFER_ADD_CHAR(buf, 'n');
-                                               break;
-       
-                                       case '\r':
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               OSRF_BUFFER_ADD_CHAR(buf, 'r');
-                                               break;
-
-                                       case '\\':
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               OSRF_BUFFER_ADD_CHAR(buf, '\\');
-                                               break;
-
-                                       default:
-                                               if( c < 32 ) buffer_fadd(buf, "\\u%04x", c);
-                                               else OSRF_BUFFER_ADD_CHAR(buf, c);
-                               }
-
-                       } else {
-                               OSRF_BUFFER_ADD_CHAR(buf, c);
-                       }
-               }
-
-               idx++;
-       }
-
-       char* d = buffer_data(buf);
-       buffer_free(buf);
-       return d;
-}
-
-
-// A function to turn a process into a daemon and set it's process name in ps/top
-int daemonize() {
-       int f = fork();
-
-       if (f == -1) {
-               perror("Failed to fork!");
-               return -1;
-
-       } else if (f == 0) { // We're in the child now...
-               setsid();
-               return 0;
-
-       } else { // We're in the parent...
-               exit(0);
-       }
-}
-
-
-/* Return 1 if the string represents an integer,  */
-/* as recognized by strtol(); Otherwise return 0. */
-
-int stringisnum(char* s) {
-       char* w;
-       strtol(s, &w, 10);
-       return *w ? 0 : 1;
-}
-       
-
-
-char* file_to_string(const char* filename) {
-
-       if(!filename) return NULL;
-
-       int len = 1024;
-       char buf[len];
-       bzero(buf, len);
-       growing_buffer* gb = buffer_init(len);
-
-       FILE* file = fopen(filename, "r");
-       if(!file) {
-               int l = strlen(filename) + 64;
-               char b[l];
-               snprintf(b,l,"Unable to open file [%s] in file_to_string()", filename);
-               perror(b);
-               return NULL;
-       }
-
-       while(fgets(buf, len - 1, file)) {
-               buffer_add(gb, buf);
-               bzero(buf, len);
-       }
-
-       fclose(file);
-
-       char* data = buffer_data(gb);
-       buffer_free(gb);
-       return data;
-}
-
-
-char* md5sum( char* text, ... ) {
-
-       struct md5_ctx ctx;
-       unsigned char digest[16];
-
-       MD5_start (&ctx);
-
-       VA_LIST_TO_STRING(text);
-
-       int i;
-       for ( i=0 ; i != strlen(VA_BUF) ; i++ )
-               MD5_feed (&ctx, VA_BUF[i]);
-
-       MD5_stop (&ctx, digest);
-
-       char buf[16];
-       memset(buf,0,16);
-
-       char final[256];
-       memset(final,0,256);
-
-       for ( i=0 ; i<16 ; i++ ) {
-               sprintf(buf, "%02x", digest[i]);
-               strcat( final, buf );
-       }
-
-       return strdup(final);
-
-}
-
-int osrfUtilsCheckFileDescriptor( int fd ) {
-
-       fd_set tmpset;
-       FD_ZERO(&tmpset);
-       FD_SET(fd, &tmpset);
-
-       struct timeval tv;
-       tv.tv_sec = 0;
-       tv.tv_usec = 0;
-
-       if( select(fd + 1, &tmpset, NULL, NULL, &tv) == -1 ) {
-               if( errno == EBADF ) return -1;
-       }
-
-       return 0;
-}
-
diff --git a/src/utils/utils.h b/src/utils/utils.h
deleted file mode 100644 (file)
index 7bbade0..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
-Copyright (C) 2005  Georgia Public Library Service 
-Bill Erickson <highfalutin@gmail.com>
-Mike Rylander <mrylander@gmail.com>
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-*/
-
-#ifndef UTILS_H
-#define UTILS_H
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
-//#include <sys/timeb.h>
-
-#include "md5.h"
-
-#define OSRF_MALLOC(ptr, size) \
-       do {\
-               ptr = (void*) malloc( size ); \
-               if( ptr == NULL ) { \
-                       perror("OSRF_MALLOC(): Out of Memory" );\
-                       exit(99); \
-               } \
-               memset( ptr, 0, size );\
-       } while(0)
-
-
-#define OSRF_BUFFER_ADD(gb, data) \
-       do {\
-               int __tl; \
-               if(gb && data) {\
-                       __tl = strlen(data) + gb->n_used;\
-                       if( __tl < gb->size ) {\
-                               strcat(gb->buf, data);\
-                               gb->n_used = __tl; \
-                       } else { buffer_add(gb, data); }\
-               }\
-       } while(0)
-
-#define OSRF_BUFFER_ADD_CHAR(gb, c)\
-       do {\
-               if(gb) {\
-                       if(gb->n_used < gb->size - 1)\
-                               gb->buf[gb->n_used++] = c;\
-                       else\
-                               buffer_add_char(gb, c);\
-               }\
-       }while(0)
-
-       
-
-
-/* turns a va_list into a string */
-#define VA_LIST_TO_STRING(x) \
-       unsigned long __len = 0;\
-       va_list args; \
-       va_list a_copy;\
-       va_copy(a_copy, args); \
-       va_start(args, x); \
-       __len = vsnprintf(NULL, 0, x, args); \
-       va_end(args); \
-       __len += 2; \
-       char _b[__len]; \
-       bzero(_b, __len); \
-       va_start(a_copy, x); \
-       vsnprintf(_b, __len - 1, x, a_copy); \
-       va_end(a_copy); \
-       char* VA_BUF = _b; \
-
-/* turns a long into a string */
-#define LONG_TO_STRING(l) \
-       unsigned int __len = snprintf(NULL, 0, "%ld", l) + 2;\
-       char __b[__len]; \
-       bzero(__b, __len); \
-       snprintf(__b, __len - 1, "%ld", l); \
-       char* LONGSTR = __b;
-
-#define DOUBLE_TO_STRING(l) \
-       unsigned int __len = snprintf(NULL, 0, "%f", l) + 2; \
-       char __b[__len]; \
-       bzero(__b, __len); \
-       snprintf(__b, __len - 1, "%f", l); \
-       char* DOUBLESTR = __b;
-
-#define LONG_DOUBLE_TO_STRING(l) \
-       unsigned int __len = snprintf(NULL, 0, "%Lf", l) + 2; \
-       char __b[__len]; \
-       bzero(__b, __len); \
-       snprintf(__b, __len - 1, "%Lf", l); \
-       char* LONGDOUBLESTR = __b;
-
-
-#define INT_TO_STRING(l) \
-       unsigned int __len = snprintf(NULL, 0, "%d", l) + 2; \
-       char __b[__len]; \
-       bzero(__b, __len); \
-       snprintf(__b, __len - 1, "%d", l); \
-       char* INTSTR = __b;
-
-
-/*
-#define MD5SUM(s) \
-       struct md5_ctx ctx; \
-       unsigned char digest[16];\
-       MD5_start (&ctx);\
-       int i;\
-       for ( i=0 ; i != strlen(text) ; i++ ) MD5_feed (&ctx, text[i]);\
-       MD5_stop (&ctx, digest);\
-       char buf[16];\
-       memset(buf,0,16);\
-       char final[256];\
-       memset(final,0,256);\
-       for ( i=0 ; i<16 ; i++ ) {\
-               sprintf(buf, "%02x", digest[i]);\
-               strcat( final, buf );\
-       }\
-       char* MD5STR = final;
-       */
-
-
-       
-
-
-#define BUFFER_MAX_SIZE 10485760 
-
-/* these are evil and should be condemned 
-       ! Only use these if you are done with argv[].
-       call init_proc_title() first, then call
-       set_proc_title. 
-       the title is only allowed to be as big as the
-       initial process name of the process (full size of argv[]).
-       truncation may occurr.
- */
-int init_proc_title( int argc, char* argv[] );
-int set_proc_title( char* format, ... );
-
-
-int daemonize();
-
-void* safe_malloc(int size);
-
-// ---------------------------------------------------------------------------------
-// Generic growing buffer. Add data all you want
-// ---------------------------------------------------------------------------------
-struct growing_buffer_struct {
-       char *buf;
-       int n_used;
-       int size;
-};
-typedef struct growing_buffer_struct growing_buffer;
-
-growing_buffer* buffer_init( int initial_num_bytes);
-
-// XXX This isn't defined in utils.c!! removing for now...
-//int buffer_addchar(growing_buffer* gb, char c);
-
-int buffer_add(growing_buffer* gb, char* c);
-int buffer_fadd(growing_buffer* gb, const char* format, ... );
-int buffer_reset( growing_buffer* gb);
-char* buffer_data( growing_buffer* gb);
-char* buffer_release( growing_buffer* gb );
-int buffer_free( growing_buffer* gb );
-int buffer_add_char(growing_buffer* gb, char c);
-
-/* returns the size needed to fill in the vsnprintf buffer.  
-       * ! this calls va_end on the va_list argument*
-       */
-long va_list_size(const char* format, va_list);
-
-/* turns a va list into a string, caller must free the 
-       allocated char */
-char* va_list_to_string(const char* format, ...);
-
-
-/* string escape utility method.  escapes unicode embeded characters.
-       escapes the usual \n, \t, etc. 
-       for example, if you provide a string like so:
-
-       hello,
-               you
-
-       you would get back:
-       hello,\n\tyou
- */
-char* uescape( const char* string, int size, int full_escape );
-
-/* utility methods */
-int set_fl( int fd, int flags );
-int clr_fl( int fd, int flags );
-
-
-
-// Utility method
-double get_timestamp_millis();
-
-
-/* returns true if the whole string is a number */
-int stringisnum(char* s);
-
-/* reads a file and returns the string version of the file
-       user is responsible for freeing the returned char*
-       */
-char* file_to_string(const char* filename);
-
-
-
-/** 
-  Calculates the md5 of the text provided.
-  The returned string must be freed by the caller.
-  */
-char* md5sum( char* text, ... );
-
-
-/**
-  Checks the validity of the file descriptor
-  returns -1 if the file descriptor is invalid
-  returns 0 if the descriptor is OK
-  */
-int osrfUtilsCheckFileDescriptor( int fd );
-
-#endif
diff --git a/src/utils/xml_utils.c b/src/utils/xml_utils.c
deleted file mode 100644 (file)
index cb2164f..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "xml_utils.h"
-
-
-void recurse_doc( xmlNodePtr node ) {
-       if( node == NULL ) return;
-       printf("Recurse: %s =>  %s", node->name, node->content );
-       xmlNodePtr t = node->children;
-       while(t) {
-               recurse_doc(t);
-               t = t->next;
-       }
-}
-
-
-
-jsonObject* xmlDocToJSON(xmlDocPtr doc) {
-       if(!doc) return NULL;
-       return _xmlToJSON(xmlDocGetRootElement(doc), NULL);
-}
-
-jsonObject* _xmlToJSON(xmlNodePtr node, jsonObject* obj) {
-
-       if(!node) return NULL;
-       if(xmlIsBlankNode(node)) return NULL;
-       if(obj == NULL) obj = jsonNewObject(NULL);
-
-       if(node->type == XML_TEXT_NODE) {
-               jsonObjectSetString(obj, (char*) node->content);        
-
-       } else if(node->type == XML_ELEMENT_NODE || node->type == XML_ATTRIBUTE_NODE ) {
-
-               jsonObject* new_obj = jsonNewObject(NULL);
-
-               jsonObject* old;
-
-               /* do the duplicate node / array shuffle */
-               if( (old = jsonObjectGetKey(obj, (char*) node->name)) ) {
-                       if(old->type == JSON_ARRAY ) {
-                               jsonObjectPush(old, new_obj);
-                       } else {
-                               jsonObject* arr = jsonNewObject(NULL);
-                               jsonObjectPush(arr, jsonObjectClone(old));
-                               jsonObjectPush(arr, new_obj);
-                               jsonObjectSetKey(obj, (char*) node->name, arr);
-                       }
-               } else {
-                       jsonObjectSetKey(obj, (char*) node->name, new_obj);
-               }
-
-               xmlNodePtr child = node->children;
-                if (child) { // at least one...
-                       if (child != node->last) { // more than one -- ignore TEXT nodes
-                               while(child) {
-                                       if (child->type != XML_TEXT_NODE) _xmlToJSON(child, new_obj);
-                                       child = child->next;
-                               }
-                       } else {
-                               _xmlToJSON(child, new_obj);
-                       }
-                }
-       }       
-
-       return obj;
-}
-
-
-char* xmlDocToString(xmlDocPtr doc, int full) {
-
-       if(!doc) return NULL;
-
-       char* xml;
-
-       if(full) {
-
-               xmlChar* xmlbuf;
-               int size;
-               xmlDocDumpMemory(doc, &xmlbuf, &size);
-               xml = strdup((char*) (xmlbuf));
-               xmlFree(xmlbuf);
-               return xml;
-
-       } else {
-
-               xmlBufferPtr xmlbuf = xmlBufferCreate();
-               xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
-               xml = strdup((char*) (xmlBufferContent(xmlbuf)));
-               xmlBufferFree(xmlbuf);
-               return xml;
-
-       }
-}
-
-
-
-
-char* xmlSaxAttr( const xmlChar** atts, char* name ) {
-       if( atts && name ) {
-               int i;
-               for(i = 0; (atts[i] != NULL); i++) {
-                       if(!strcmp(atts[i], name)) {
-                               if(atts[++i]) return (char*) atts[i];
-                       }
-               }
-       }
-       return NULL;
-}
-
-
-int xmlAddAttrs( xmlNodePtr node, const xmlChar** atts ) {
-       if( node && atts ) {
-               int i;
-               for(i = 0; (atts[i] != NULL); i++) {
-                       if(atts[i+1]) {
-                               xmlSetProp(node, atts[i], atts[i+1]);
-                               i++;
-                       }
-               }
-       }
-       return 0;
-}
-
diff --git a/src/utils/xml_utils.h b/src/utils/xml_utils.h
deleted file mode 100644 (file)
index a329061..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#ifndef _XML_UTILS_H
-#define _XML_UTILS_H
-
-#include "objson/object.h"
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-
-jsonObject* xmlDocToJSON(xmlDocPtr doc);
-
-/* helper function */
-jsonObject* _xmlToJSON(xmlNodePtr node, jsonObject*);
-
-/* debug function, prints each node and content */
-void recurse_doc( xmlNodePtr node );
-
-
-/* turns an XML doc into a char*.  
-       User is responsible for freeing the returned char*
-       if(full), then we return the whole doc (xml declaration, etc.)
-       else we return the doc from the root node down
-       */
-char* xmlDocToString(xmlDocPtr doc, int full);
-
-
-/* Takes an xmlChar** from a SAX callback and returns the value
-       for the attribute with name 'name'
-       */
-char* xmlSaxAttr( const xmlChar** atts, char* name ); 
-
-/**
-  Sets the xml attributes from atts to the given dom node 
- */
-int xmlAddAttrs( xmlNodePtr node, const xmlChar** atts );
-
-
-#endif
diff --git a/src/xinclude/Makefile b/src/xinclude/Makefile
deleted file mode 100644 (file)
index ba537e9..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-SO=mod_xinclude.so
-
-# --------------------------------------------------------
-TMPDIR = /tmp/ilstmp/opensrf
-LIBDIR = /openils/lib
-CC_OPTS = -Wall -O2 -fPIC -I /usr/include/libxml2 -I /opt/include
-LD_OPTS = -lxml2 
-APXS2 = /opt/bin/apxs
-# --------------------------------------------------------
-
-all: $(SO)
-
-install: 
-       cp $(TMPDIR)/$(SO) $(LIBDIR)/$(SO)
-       $(APXS2) -i -a -n xinclude $(LIBDIR)/$(SO)
-
-$(SO): mod_xinclude.c  
-       $(CC) -c $(CC_OPTS)  mod_xinclude.c
-       $(CC) $(LD_OPTS) -shared -W1 mod_xinclude.o -o $(TMPDIR)/$(SO)
-
-clean:
-       /bin/rm -f *.o *.so
diff --git a/src/xinclude/mod_xinclude.c b/src/xinclude/mod_xinclude.c
deleted file mode 100644 (file)
index 08fee22..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "httpd.h"
-#include "http_config.h"
-#include "http_core.h"
-#include "http_protocol.h"
-#include "apr_compat.h"
-#include "apr_strings.h"
-
-#include <libxml/parser.h>
-#include <libxml/xinclude.h>
-
-#define MODULE_NAME "xinclude_module"
-
-static int mod_xinclude_handler (request_rec *r) {
-
-       /* make sure we're needed first thing*/
-       if (strcmp(r->handler, MODULE_NAME )) 
-               return DECLINED;
-
-       /* set content type */
-       ap_set_content_type(r, "text/html");
-
-
-       /* which file are we parsing */
-       char* file = r->filename;
-
-       if(!file) { 
-               fprintf(stderr, "No XML file to parse");
-               fflush(stderr);
-               return HTTP_INTERNAL_SERVER_ERROR;
-       }
-
-       /* parse the doc */
-       xmlDocPtr doc = xmlParseFile(file);
-
-       if(!doc) {
-               fprintf(stderr, "Error parsing XML file %s\n", file);
-               fflush(stderr);
-               return HTTP_INTERNAL_SERVER_ERROR;
-       }
-
-       /* process the xincludes */
-       int status = xmlXIncludeProcess(doc);
-       
-       if(status < 0) {
-               fprintf(stderr, "Error processing XIncludes in  XML file %s\n", file);
-               fflush(stderr);
-               return HTTP_INTERNAL_SERVER_ERROR;
-       }
-
-       xmlBufferPtr xmlbuf = xmlBufferCreate();
-       xmlNodeDump( xmlbuf, doc, xmlDocGetRootElement(doc), 0, 0);
-       char* xml = (char*) (xmlBufferContent(xmlbuf));
-
-       ap_rputs(xml,r);
-
-       xmlBufferFree(xmlbuf);
-       xmlFreeDoc(doc);
-
-       return OK;
-}
-
-
-static void mod_xinclude_register_hooks (apr_pool_t *p) {
-       ap_hook_handler(mod_xinclude_handler, NULL, NULL, APR_HOOK_MIDDLE);
-}
-
-module AP_MODULE_DECLARE_DATA xinclude_module = {
-       STANDARD20_MODULE_STUFF,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       NULL,
-       mod_xinclude_register_hooks,
-};
-