Update of /cvsroot/monetdb/pathfinder/runtime
In directory sc8-pr-cvs16.sourceforge.net:/tmp/cvs-serv11826/runtime

Modified Files:
      Tag: xrpcdemo
        Makefile.ag pathfinder.mx pf_support.mx serialize_dflt.mx 
        xrpc_client.mx xrpc_server.mx 
Removed Files:
      Tag: xrpcdemo
        xrpc_common.mx 
Log Message:
still premature, it starts without errors 
but xrpc does not work yet (actually I did not test yet)

BEWARE: ./de-bootstrap and full rebuild required

xrpc_common was put into xrpc_server because more and more
of xrpc_server was ending up in xrpc_common.



U pathfinder.mx
Index: pathfinder.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/pathfinder.mx,v
retrieving revision 1.416.2.1.2.7
retrieving revision 1.416.2.1.2.8
diff -u -d -r1.416.2.1.2.7 -r1.416.2.1.2.8
--- pathfinder.mx       5 Jun 2008 14:17:39 -0000       1.416.2.1.2.7
+++ pathfinder.mx       5 Jun 2008 21:17:50 -0000       1.416.2.1.2.8
@@ -94,7 +94,6 @@
 module(pf_support);
 module(logger);
 module(mkey);
-module(xrpc_common);
 module(xrpc_server);
 module(xrpc_client);
 module(pf_standoff);
@@ -733,8 +732,8 @@
 
         # remove working sets of non-busy XRPC requests that timed out or 
aborted
         lock_set(xrpc_lock);
-        var timedout := project(xrpc_timeouts.ord_uselect(0LL,GDKusec()), 
"timedout");
-        var aborted := 
xrpc_wsids.ord_uselect(lng_nil,lng_nil).mirror().leftfetchjoin(xrpc_statuses).ord_select("abort"));
+        var timedout := project(xrpc_timeouts.ord_uselect(0LL,usec()), 
"timedout");
+        var aborted := 
xrpc_wsids.ord_uselect(lng_nil,lng_nil).mirror().leftfetchjoin(xrpc_statuses).ord_select("abort");
         kunion(aborted,timedout)@batloop() {
             var wslock := xrpc_locks.find($h);
             if (lock_try(ws_lock) = 0) {
@@ -1418,7 +1417,7 @@
 #  0 = no xrpc ws caching needed, 
 # >0 = ws is already cached at idx
 # <0 = create new ws and cache it at idx
-PROC _ws_xrpcget() : int;
+PROC _ws_xrpcget() : int
 {
     var xrpc := 0;
     xrpc_seqnr := (xrpc_querynr :+= 1LL);
@@ -1435,7 +1434,7 @@
 }
 
 # create a new ws if necessary (res <= 0), returns wsid
-PROC _ws_new(int xrpc, oid idx, int update) : lng;
+PROC _ws_new(int xrpc, oid idx, int update) : lng
 {
     var wsid;
     if (xrpc > 0) {
@@ -1461,7 +1460,7 @@
 {
     # NOTE: use pre-query MIL variables xrpc_qid/xrpc_timeout to possibly 
re-use an existing ws
     lock_set(xrpc_lock);
-    var err := CATCH(var xrpc, wsid := _ws_new(xrpc := _ws_xrpcget(), idx := 
oid(abs(xrpc)), update), ws := bat(str(wsid)));
+    var ws, xrpc, idx, err := CATCH(wsid := _ws_new(xrpc := _ws_xrpcget(), idx 
:= oid(abs(xrpc)), update), ws := bat(str(wsid)));
     lock_unset(xrpc_lock);
     if (not(isnil(err))) ERROR(err);
 
@@ -4167,8 +4166,8 @@
 #define XQUERY_TYPES 20
 #define XQUERY_ABSTRACT 8
 
-extern xquery_type xquery_types[XQUERY_TYPES+1];
-extern int xquery_typenr(char* tpe);
+pathfinder_export xquery_type xquery_types[XQUERY_TYPES+1];
+pathfinder_export int xquery_typenr(char* tpe);
 #endif
 @c
 #include "pf_config.h"

--- xrpc_common.mx DELETED ---

U pf_support.mx
Index: pf_support.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/pf_support.mx,v
retrieving revision 1.299.4.5
retrieving revision 1.299.4.6
diff -u -d -r1.299.4.5 -r1.299.4.6
--- pf_support.mx       5 Jun 2008 12:55:19 -0000       1.299.4.5
+++ pf_support.mx       5 Jun 2008 21:17:52 -0000       1.299.4.6
@@ -3860,7 +3860,7 @@
 PROC do_2phase_commit() : void
 {
   # write PRECOMMIT record
-  log_trans_precommit(pf_logger, xrpc_qid, ???cid);
+  log_trans_precommit(pf_logger, xrpc_qid);
 
   # now wait until we get an ABORT or a COMMIT message
   xrpc_wait_for_commit(xrpc_qid);
@@ -5825,6 +5825,9 @@
 #define PF_MODE_UPDATE 2 /* updating query */
 #define PF_MODE_RETRY  3 /* updating query run for the second time (exclusive 
mode) */
 
+pf_support_export int xrpc_port;
+pf_support_export char *xrpc_hostname;
+
 #endif
 @c
 
@@ -5834,7 +5837,10 @@
 #include <plain/algebra.h> /* needed for result size estimation in 
CMDenumerate */
 #include <math.h> /* needed for round_up */
 
[EMAIL PROTECTED]
+
+char *xrpc_hostname = NULL;
+int xrpc_port = 0;
+
 /* delete a file from the local tmp/ directory in the dbfarm; protect against 
abuse */
 int CMDcleantmpdir(lng *lim) {
         DIR *dirp = opendir("tmp");
@@ -7890,7 +7896,6 @@
        return GDK_SUCCEED;
 }
 
-
 typedef struct stack_item si;
 
 struct stack_item {

U xrpc_client.mx
Index: xrpc_client.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_client.mx,v
retrieving revision 1.45.4.5
retrieving revision 1.45.4.6
diff -u -d -r1.45.4.5 -r1.45.4.6
--- xrpc_client.mx      5 Jun 2008 12:55:23 -0000       1.45.4.5
+++ xrpc_client.mx      5 Jun 2008 21:17:54 -0000       1.45.4.6
@@ -80,7 +80,7 @@
 @mil
 
 PROC doLoopLiftedRPC(
-        str module,
+        str modname,
         str location,
         str method,
         bit updCall,
@@ -146,7 +146,7 @@
 
         var local_name := "rpc_res_00" + str(int($h)+off);
         var rpc_res, timeout := max(0LL,xrpc_timeout - (usec() - timer_start));
-        var rpc_err := CATCH(rpc_res := http_post(genType, xrpc_mode, 
xrpc_qid, xrpc_seqnr, timeout, $t, module, location, method,
+        var rpc_err := CATCH(rpc_res := http_post(genType, xrpc_mode, 
xrpc_qid, xrpc_seqnr, timeout, $t, modname, location, method,
                     updCall, arity, itercnt, ws, fun_vid, fun_iter, fun_item,
                     fun_kind, int_values, dbl_values, dec_values, str_values));
 
@@ -244,7 +244,7 @@
 "xrpc_client");
 
 PROC doIterativeRPC(
-        str module,
+        str modname,
         str location,
         str method,
         bit updCall,
@@ -291,7 +291,7 @@
         var local_name := "rpc_res_00" + str(h+1);
         if (xrpc_qid != "") lock_unset(wslock);
         var rpc_res, timeout := max(0LL,xrpc_timeout - (usec() - timer_start));
-        var rpc_err := CATCH(rpc_res := http_post(genType, xrpc_mode, 
xrpc_qid, xrpc_seqnr, timeout, $t, module, location, method,
+        var rpc_err := CATCH(rpc_res := http_post(genType, xrpc_mode, 
xrpc_qid, xrpc_seqnr, timeout, $t, modname, location, method,
                     updCall, arity, lng(1), ws, cur_fun_vid, cur_fun_iter, 
cur_fun_item,
                     cur_fun_kind, int_values, dbl_values, dec_values, 
str_values));
         if (xrpc_qid != "") lock_set(wslock);
@@ -359,7 +359,7 @@
 "xrpc_client");
 
 PROC doRPC(
-        str module,
+        str modname,
         str location,
         str method,
         bit updCall,
@@ -377,10 +377,10 @@
         BAT[void, str] str_values) : BAT[void,bat]
 {
     if (search(xrpc_mode,"iterative") >= 0) 
-        doIterativeRPC(module, location, method, updCall, arity, niters,
+        doIterativeRPC(modname, location, method, updCall, arity, niters,
                         ws, dsts, fun_vid, fun_iter, fun_item, fun_kind, 
int_values, dbl_values, dec_values, str_values);
     else
-        doLoopliftedRPC(module, location, method, updCall, arity, niters,
+        doLoopliftedRPC(modname, location, method, updCall, arity, niters,
                         ws, dsts, fun_vid, fun_iter, fun_item, fun_kind, 
int_values, dbl_values, dec_values, str_values);
 }
 
@@ -401,7 +401,7 @@
 #include "pf_support.h"
 #include "shredder.h"
 #include "serialize.h"
-#include "xrpc_common.h"
+#include "xrpc_server.h"
 #include "xrpc_client.h"
 
 

U serialize_dflt.mx
Index: serialize_dflt.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/serialize_dflt.mx,v
retrieving revision 1.46.4.3
retrieving revision 1.46.4.4
diff -u -d -r1.46.4.3 -r1.46.4.4
--- serialize_dflt.mx   5 Jun 2008 12:55:21 -0000       1.46.4.3
+++ serialize_dflt.mx   5 Jun 2008 21:17:53 -0000       1.46.4.4
@@ -41,7 +41,7 @@
 #include "serialize_null.h"
 #include "pathfinder.h"
 #include "pf_support.h"
-#include "xrpc_common.h" /* *_NS defs */
+#include "xrpc_server.h" /* *_NS defs */
 
 /* a lot of characters, static strings, and their sizes 
    (the idea is to reuse constant character pointers during

U Makefile.ag
Index: Makefile.ag
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/Makefile.ag,v
retrieving revision 1.86.4.2
retrieving revision 1.86.4.3
diff -u -d -r1.86.4.2 -r1.86.4.3
--- Makefile.ag 29 May 2008 08:35:49 -0000      1.86.4.2
+++ Makefile.ag 5 Jun 2008 21:17:49 -0000       1.86.4.3
@@ -55,7 +55,7 @@
                 pf_support.mx \
                 shredder.mx 
         LIBS = \
-                lib_xrpc_common libserialize libpf $(PF_LIBS) \
+                libserialize libpf $(PF_LIBS) \
                 $(MONETDB_LIBS) -lbat -lstream $(MONETDB4_LIBS) -lmonet 
$(PTHREAD_LIBS) \
                 $(MONETDB4_MODS) -l_lock -l_monettime -l_streams -l_builtin 
-l_ascii_io -l_algebra -l_constant
 }
@@ -98,14 +98,6 @@
                 $(MONETDB4_MODS) -l_logger -l_streams -l_builtin -l_ascii_io 
-l_algebra -l_sys -l_constant -l_mapi 
 }
 
-lib__xrpc_common = {
-        DIR = libdir/MonetDB4
-        SOURCES = xrpc_common.mx
-        LIBS = \
-                          $(SOCKET_LIBS) \
-                          $(MONETDB_LIBS) -lbat -lstream $(MONETDB4_LIBS)
-}      
-
 lib__xrpc_client = {
         DIR = libdir/MonetDB4
         SOURCES = xrpc_client.mx
@@ -145,5 +137,5 @@
 headers_mil = {
        HEADERS = mil
         DIR = libdir/MonetDB4
-        SOURCES = pathfinder.mx pf_support.mx pf_standoff.mx xrpc_client.mx 
xrpc_server.mx xrpc_common.mx
+        SOURCES = pathfinder.mx pf_support.mx pf_standoff.mx xrpc_client.mx 
xrpc_server.mx 
 }

U xrpc_server.mx
Index: xrpc_server.mx
===================================================================
RCS file: /cvsroot/monetdb/pathfinder/runtime/xrpc_server.mx,v
retrieving revision 1.68.4.5
retrieving revision 1.68.4.6
diff -u -d -r1.68.4.5 -r1.68.4.6
--- xrpc_server.mx      5 Jun 2008 12:55:25 -0000       1.68.4.5
+++ xrpc_server.mx      5 Jun 2008 21:17:55 -0000       1.68.4.6
@@ -43,35 +43,36 @@
 .COMMAND rpcd_start(int port, bit open, str options) : void = CMDrpcd_start;
 "Start the HTTP server for RPC calls on the specified port."
 
+.COMMAND my_hostname() : str = CMDmy_hostname;
+"Returns the hostname of the localhost."
+
+.PRELUDE = xrpc_prelude;
 .EPILOGUE = xrpc_epilogue;
 .END xrpc_server;
 
 @mil
 # initialize xrpcd_admin: IPs that can execute modules from the special
 # xrpc/admin directory
-var xrpc_admin := bat(str,void);
-xrpc_admin.insert(reverse(split(monet_environment.find("xrpc_admin"),";"))).bbpname("xrpc_admin");
+var xrpc_admin := 
bat("xrpc_admin").append(split(monet_environment.find("xrpc_admin"),";"));
 
 # initialize xrpcd_user: IPs that can retrieve XML documents stored in
 # the database using a URL of the form:
 #               http://<host>[:port]/xrpc/<name>.xml
-var xrpc_user := bat(str,void);
-xrpc_user.insert(reverse(split(monet_environment.find("xrpc_user"),";"))).bbpname("xrpc_user");
+var xrpc_user := 
bat("xrpc_user").append(split(monet_environment.find("xrpc_user"),";"));
 
 # initialize xrpcd_trusted: URL prefixes for modules that anybody can execute
-var xrpc_trusted := bat(str,void);
-xrpc_trusted.insert(reverse(split(monet_environment.find("xrpc_trusted"),";"))).bbpname("xrpc_trusted");
+var xrpc_trusted := 
bat("xrpc_trusted").append(split(monet_environment.find("xrpc_trusted"),";"));
 
 proc add_xrpc_trusted(BAT[str,void] prefixes) : void {
-    xrpc_trusted.insert(prefixes);
+    xrpc_trusted.append(prefixes.reverse());
 }
 
 proc add_xrpc_trusted(BAT[void,str] prefixes) : void {
-    xrpc_trusted.insert(prefixes.reverse());
+    xrpc_trusted.append(prefixes);
 }
 
 proc add_xrpc_trusted(str prefix) : void {
-    xrpc_trusted.insert(prefix, nil);
+    xrpc_trusted.append(prefix);
 }
 
 proc get_xrpc_open() : bit {
@@ -122,7 +123,7 @@
 
 PROC rpcd_start() : void {
     var port := get_xrpc_port();
-    xrpc_trusted.insert("http://127.0.0.1:"+str(port),nil);
+    xrpc_trusted.append("http://127.0.0.1:"+str(port));
     if (monet_environment.find("monet_welcome") = "yes") 
         printf("%c XRPC administrative console at 
http://127.0.0.1:%d/admin\n";, int(35), port);
     fork( rpcd_start(port, get_xrpc_open(), get_xrpc_options()) );
@@ -133,6 +134,172 @@
 \"monet_environment\"",
 "xrpc_server");
 
+PROC print_xrpc() : void {
+    print(xrpc_qids,xrpc_statuses,xrpc_timeouts,xrpc_locks,xrpc_wsids);
+}
[EMAIL PROTECTED]
+#ifndef XRPC_SERVER_H
+#define XRPC_SERVER_H
+
+#include <mapi/mapi.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stream_socket.h>
+
+#ifdef _WIN32   /* Windows specific */
+    #include <winsock.h>
+    #define snprintf _snprintf
+    #ifndef __MINGW32__
+        #pragma comment(lib, "ws2_32")
+    #endif
+#else           /* UNIX specific */
+    #include <sys/select.h>
+    #include <sys/types.h>     /* used by socket */
+    #include <sys/socket.h>
+    #include <unistd.h> /* gethostname() */
+    #include <netinet/in.h> /* hton and ntoh */
+    #include <arpa/inet.h>  /* dotted IP addr to and from 32-bits int */
+    #include <netdb.h>      /* gethostbyname(), h_errno */
+    #include <errno.h>
+    #include <ctype.h>
+#endif
+#include "pf_support.h"
+#include "xrpc_server.proto.h"
+
+/* HTTP defines */
+#define XRPC_DOC_CALLBACK       "/xrpc/doc"
+#define XRPC_ADM_CALLBACK       "/xrpc/admin"
+#define XRPC_REQ_CALLBACK       "/xrpc"
+
+#define ERR403                  "403 Forbidden"
+#define ERR404                  "404 Bad Request"
+#define ERR408                  "408 Request Timeout"
+#define ERR500                  "500 Internal Server Error"
+#define ERR504                  "504 Gateway Timeout"
+
+#define OUT_OF_MEM              "Internal Receiver Error: out-of memory"
+#define NOT_WELL_FORMED         "Request XML message not well-formed"
+#define MAX_NR_PARAMS           1024
+
+#define HTTP_200_OK\
+            "HTTP/1.1 200 OK\r\n"\
+            "Content-type: text/xml; charset=\"utf-8\"\r\n\r\n"
+
+/* our namespaces */
+#define MXQ_ADMIN     "http://monetdb.cwi.nl/XQuery/admin/";
+#define SOAP_NS       "http://www.w3.org/2003/05/soap-envelope";
+#define XDT_NS        "http://www.w3.org/2005/xpath-datatypes";
+#define XS_NS         "http://www.w3.org/2001/XMLSchema";
+#define XSI_NS        "http://www.w3.org/2001/XMLSchema-instance";
+#define XRPC_NS       "http://monetdb.cwi.nl/XQuery";
+#define XRPC_LOC      "http://monetdb.cwi.nl/XQuery/XRPC.xsd";
+#define WSCOOR_NS     "http://docs.oasis-open.org/ws-tx/wscoor/2006/06";
+#define WSAT_NS       "http://docs.oasis-open.org/ws-tx/wsat/2006/06";
+
+#define XRPC_REQUEST  XRPC_NS"|request"
+#define XRPC_RESPONSE XRPC_NS"|response"
+
+/* XRPC SOAP snippets */
+#define SOAP_ENVELOPE\
+    "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"\
+    "<env:Envelope xmlns:env=\"" SOAP_NS "\""\
+                 " xmlns:xrpc=\"" XRPC_NS "\""\
+                 " xmlns:xdt=\"" XDT_NS "\" "\
+                 " xmlns:xs=\"" XS_NS "\""\
+                 " xmlns:xsi=\"" XSI_NS "\""\
+                 " xsi:schemaLocation=\"" XRPC_NS " " XRPC_LOC "\">"
+
+#define XRPC_WS_QID\
+      "<wscoor:CoordinationContext xmlns:wscoor=\""WSCOOR_NS"\""\
+                 "env:mustUnderstand=\"true\">"\
+        "<wscoor:Identifier>%s</wscoor:Identifier>"\
+        "<wscoor:Expires>%s</wscoor:Expires>"\
+        "<wscoor:CoordinationType>" WSAT_NS "</wscoor:CoordinationType>"\
+      "</wscoor:CoordinationContext>"
+
+#define XRPC_REQ_HEADER\
+    "<env:Body>"\
+      "<xrpc:request xrpc:module=\"%s\""\
+                   " xrpc:location=\"%s\""\
+                   " xrpc:method=\"%s\""\
+                   " xrpc:arity=\"%lld\""\
+                   " xrpc:iter-count=\"%lld\""\
+                   " xrpc:caller=\"%s\""\
+                   " xrpc:mode=\"%s\""\
+                   " xrpc:updCall=\"%s\">"
+
+#define XRPC_RES_HEADER\
+    "<env:Body>"\
+      "<xrpc:response xrpc:module=\"%s\""\
+                    " xrpc:method=\"%s\">"
+
+#define XRPC_HTTP_CALL "<xrpc:call>"                                    \
+                         "<xrpc:sequence>"                              \
+                           "<xrpc:atomic-value xsi:type=\"xs:string\">" \
+                             "%s"                                       \
+                           "</xrpc:atomic-value>"                       \
+                         "</xrpc:sequence>"                             \
+                       "</xrpc:call>"
+
+#define XRPC_PUT_CALL  "<xrpc:call>"                                    \
+                         "<xrpc:sequence>"                              \
+                           "<xrpc:atomic-value xsi:type=\"xs:string\">" \
+                             "%s"                                       \
+                           "</xrpc:atomic-value>"                       \
+                         "</xrpc:sequence>"                             \
+                         "<xrpc:sequence>"                              \
+                           "<xrpc:element>%s</xrpc:element>"            \
+                         "</xrpc:sequence>"                             \
+                       "</xrpc:call>"
+
+#define XRPC_FOOTER     "</xrpc:request>"   \
+                      "</env:Body>"         \
+                    "</env:Envelope>\n"
+
+typedef struct {
+    char *qid;
+    char *caller;
+    lng start;
+    lng timeout;
+    char *mode;
+    char *module;
+    char *method;
+    char *location;
+    int updCall;
+    int hasNodeParam;
+    size_t argc;
+    size_t iterc;
+    size_t nr_args;
+    size_t max_args;
+    lng **argcnt;
+    int *argtpe;
+    char **argval;
+    lng partcnt;
+    BAT *shredBAT;
+} XRPCreq_t;
+
+/* exports for xrpc_server.mx and serialize_dflt.mx */
+xrpc_server_export int        isAllowed(BAT *allowed, char* key);
+xrpc_server_export int        isTrusted(stream *out, char *location);
+
+xrpc_server_export XRPCreq_t *xrpc_parse_message(stream *out, BAT *shredBAT, 
BAT *participants, bit isAdmin);
+xrpc_server_export XRPCreq_t *XRPCreq_new(char *qid, char *caller, lng 
timeout, char *mode, char *module,
+                                         char *method, char *location, int 
updCall, size_t iterc, size_t argc);
+xrpc_server_export void       XRPCreq_free(XRPCreq_t *req);
+xrpc_server_export void       send_err(stream *out, char *http_err, char 
*soap_err, char *err_reason);
+xrpc_server_export lng        my_strtoll(stream *out, bte isSigned, char 
*val_ptr, char *attr_name);
+
+xrpc_server_export BAT *xrpc_qids;
+xrpc_server_export BAT *xrpc_timeouts;
+xrpc_server_export BAT *xrpc_statuses;
+xrpc_server_export BAT *xrpc_locks;
+xrpc_server_export BAT *xrpc_wsids;
+xrpc_server_export BAT *xrpc_trusted;
+xrpc_server_export BAT *xrpc_admin;
+
+#endif /* XRPC_SERVER */
+
 @c
 #include "pf_config.h"
 #include <gdk.h>
@@ -140,9 +307,8 @@
 #include "pf_support.h"
 #include "shredder.h"
 #include "serialize.h"
-#include "xrpc_common.h"
-#include "xrpc_server.h"
 #include "shttpd.h"
+#include "xrpc_server.h"
 
 static int rpcd_running = 0;
 static int timing = 0;
@@ -150,6 +316,636 @@
 static int listen_socket = -1;
 static char datadir[1024];
 
+
+int CMDmy_hostname(char **res)
+{
+    int ret = 0, len = HOST_NAME_MAX > 255 ? HOST_NAME_MAX : 255;
+    char err[1024];
+
+    char *hname = GDKmalloc(len);
+    if(!hname) {
+        GDKerror("CMDmy_hostname: failed to malloc 'hname'\n");
+        return GDK_FAIL;
+    }
+    
+    errno = 0;
+    ret = gethostname(hname, len);
+    if(ret < 0) {
+        snprintf(err, 1024, "CMDmy_hostname: gethostname() failed: %s.\n", 
strerror(errno));
+        return GDK_FAIL;
+    }
+
+    *res = hname;
+    return GDK_SUCCEED;
+}
+
+void
+send_err(stream *out,
+         char *http_err,
+         char *soap_err,
+         char *err_reason)
+{
+    if (out == NULL) {
+        GDKerror(err_reason);
+    } else {
+        stream_printf(out, "HTTP/1.1 %s\r\n"
+            "Content-type: text/xml; charset=\"utf-8\"\r\n\r\n"
+            "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+            "<env:Envelope xmlns:env=\"%s\">"
+            "<env:Body>"
+            "<env:Fault>"
+            "<env:Code><env:Value>%s</env:Value></env:Code>"
+            "<env:Reason>"
+            "<env:Text xml:lang=\"en\">%s</env:Text>"
+            "</env:Reason>"
+            "</env:Fault></env:Body></env:Envelope>\n",
+            http_err, SOAP_NS, soap_err, err_reason);
+        stream_flush(out);
+    }
+}
+
+
+XRPCreq_t *
+XRPCreq_new(
+        char *qid,
+        char *caller,
+        lng timeout,
+        char *mode,
+        char *module,
+        char *method,
+        char *location,
+        int updCall,
+        size_t iterc,
+        size_t argc)
+{
+    size_t i = 0, j = 0;
+
+    XRPCreq_t *req = (XRPCreq_t*) GDKmalloc(sizeof(XRPCreq_t));
+    if(!req) return NULL;
+
+    req->qid = qid;
+    req->caller = caller;
+    req->timeout = timeout;
+    req->mode = mode;
+    req->start = GDKusec();
+    req->module = module;
+    req->method = method;
+    req->location = location;
+    req->updCall = updCall;
+    req->hasNodeParam = FALSE;
+    req->argc = argc;
+    req->iterc = iterc;
+    req->nr_args = 0;
+    req->max_args = iterc * (argc>0?argc:1) * MAX_NR_PARAMS;
+
+    if (!(req->argcnt = (lng**) GDKmalloc(iterc * sizeof(lng*)))) {
+        GDKfree(req);
+        return NULL;
+    }
+    for (i = 0; i < iterc; i++) {
+        /* we allocate _at least one_ argcnt for each parameter, so that
+         * we have a place to note that a function has zero parameter */
+        if(!(req->argcnt[i] = GDKmalloc((argc>0?argc:1) * sizeof(lng)))){
+            for (j = 0; j < i; j++)
+                GDKfree(req->argcnt[j]);
+            GDKfree(req);
+            return NULL;
+        }
+        req->argcnt[i][0] = 0;
+        for (j = 1; j < argc; j++)
+            req->argcnt[i][j] = 0;
+    }
+
+    if(!(req->argtpe = (int*) GDKmalloc(req->max_args * sizeof(int)))){
+        for(i = 0; i < iterc; i++) GDKfree(req->argcnt[i]);
+        GDKfree(req->argcnt);
+        GDKfree(req);
+        return NULL;
+    }
+   
+    if(!(req->argval = (char**) GDKmalloc(req->max_args * sizeof(char *)))){
+        for(i = 0; i < iterc; i++) GDKfree(req->argcnt[i]);
+        GDKfree(req->argcnt);
+        GDKfree(req->argtpe);
+        GDKfree(req);
+        return NULL;
+    }
+
+    return req;
+}
+
+void
+XRPCreq_free(XRPCreq_t *req)
+{
+    size_t i = 0;
+
+    if(req->qid) GDKfree(req->qid);
+    for(i = 0; i < req->iterc; i++) GDKfree(req->argcnt[i]);
+    GDKfree(req->argcnt);
+    GDKfree(req->argtpe);
+    GDKfree(req->argval);
+    GDKfree(req);
+}
+
+/* Convert string to long int.  I promise never to use errno anymore!! */
+lng
+my_strtoll(stream *out,
+           bte isSigned,
+           char *val_ptr,
+           char *attr_name)
+{
+    char errstr[1024], *end_ptr = val_ptr;
+    long long int ret = strtoll(val_ptr, &end_ptr, 10);
+
+    if(end_ptr == val_ptr){
+        snprintf(errstr, 1024,
+                "Invalid value (\"%s\") of numeric attribute \"%s\"",
+                val_ptr, attr_name);
+        send_err(out, ERR404, "env:Sender", errstr);
+        return GDK_lng_min;
+    } else if(ret < 0 && !isSigned){
+        snprintf(errstr, 1024,
+                "Invalid value (\"%s\") of numeric attribute \"%s\": "
+                "should not be negative",
+                val_ptr, attr_name);
+        send_err(out, ERR404, "env:Sender", errstr);
+        return GDK_lng_min;
+    }
+    return ret;
+}
+
+/**
+ * @return PRE, or 0 if not found.
+ */
+static INLINE oid
+get_pre_by_qname(str qname,
+                 oid start_pre,
+                 oid end_pre,
+                 oid *pre_propT,
+                 char *pre_kindT,
+                 BAT *qn_uri_loc)
+{
+    oid i;
+    BUN bun = BUN_NONE;
+    BATiter qn_uli = bat_iterator(qn_uri_loc);
+
+    for (i = start_pre; i <= end_pre; i++) {
+        if (pre_kindT[i] == ELEMENT) {
+            BUNfndVOID(bun, qn_uli, &(pre_propT[i]));
+            if(bun != BUN_NONE && strcmp(BUNtail(qn_uli, bun), qname) == 0)
+                return i;
+        }
+    }
+    return 0;
+}
+
+/**
+ * Checks if a prefix of 'key' is present in a bat with a list of allowed 
prefixes
+ *
+ * Return 1 if yes, 0 otherwise.
+ */
+int 
+isAllowed(BAT *allowed, char* key)
+{
+    BATiter allowedi = bat_iterator(allowed);
+    BUN p,q;
+    BATloop(allowed, p, q) {
+        char* prefix = BUNtail(allowedi,p);
+        if (strncmp(key, prefix, strlen(prefix)) == 0)  
+            return 1;
+    }
+    return (BATcount(allowed) == 0);
+}
+
+/**
+ * Checks if the prefix of 'location' is listed in "xrpc_trusted".
+ *
+ * Return 1 if yes, 0 otherwise.
+ */
+int
+isTrusted(stream *out, char *location)
+{
+    if (!isAllowed(xrpc_trusted, location)) {
+        char * msg = "Called module not allowed:";
+        size_t len = strlen(msg) + strlen(location) + 11;
+        size_t len_x = 0, pos = 0;
+        char * err;
+        BUN p,q;
+        BATiter xrpc_trustedi = bat_iterator(xrpc_trusted);
+        BATloop(xrpc_trusted, p, q) {
+            char* prefix = BUNhead(xrpc_trustedi, p);
+            len_x += strlen(prefix) + 4;
+        }
+        err = alloca(len + len_x);
+        if (err) {
+            len += len_x;
+        } else {
+            len_x = 0;
+            err = alloca(len);
+        }
+        assert(err);
+        pos += snprintf(err+pos, len-pos, "%s", msg);
+        if (!len_x) {
+            pos += snprintf(err+pos, len-pos, " '%s'.", location);
+        } else {
+            pos += snprintf(err+pos, len-pos, "\n'%s' not in", location);
+            BATloop(xrpc_trusted, p, q) {
+                char* prefix = BUNhead(xrpc_trustedi, p);
+                pos += snprintf(err+pos, len-pos, "\n'%s',", prefix);
+            }
+            err[pos-1] = '.';
+        }
+        send_err(out, ERR403, "env:Sender", err);
+        return 0;
+    }
+    return 1;
+}
+
+static int 
+get_node_type(str typename) {
+    if (strcmp(typename, XRPC_NS"|element") == 0)
+        return XS_ELEMENT;
+    if (strcmp(typename, XRPC_NS"|text") == 0)
+        return XS_TEXT;
+    if (strcmp(typename, XRPC_NS"|comment") == 0)
+        return XS_COMMENT;
+    if (strcmp(typename, XRPC_NS"|processing-instruction") == 0) 
+        return XS_PI;
+    if (strcmp(typename, XRPC_NS"|document") == 0)
+        return XS_DOCUMENT;
+    return -1;
+} 
+
+static BAT* 
+get_elt_qn(BAT* pre_kind, BAT* pre_prop) {
+    int elt = ELEMENT;
+    BAT *elt_qn, *tmp = BATselect(pre_kind, &elt, &elt);
+    if (!tmp) return NULL;
+    elt_qn = BATsemijoin(pre_prop, tmp);
+    BBPreclaim(tmp);
+    return elt_qn;
+}
+
+XRPCreq_t *
+xrpc_parse_message(stream *out,
+                   BAT *shredBAT,
+                   BAT *participants,
+                   bit isAdmin)
+{
+    XRPCreq_t *req = NULL, *res = NULL;
+    char* msg = participants?XRPC_REQUEST:XRPC_RESPONSE;
+    char *module = NULL, *method = NULL, *location = NULL;
+    char *qid = NULL, *host = NULL, *caller = "query,0";
+    char *querynr_str = NULL, *timeout_str = NULL, *mode_str = NULL;
+    char *arity_str = NULL, *itercnt_str = NULL;
+    char *pul = NULL, *val = NULL;
+    int updCall = FALSE;
+    lng timeout = 300000, argc = GDK_lng_min, iterc = -1, i = 0, j = 0, k = 0;
+    char errstr[1024];
+
+    BATiter shredBATi, prop_vali, qn_uli;
+    BAT *pre_size = NULL, *pre_level = NULL, *pre_kind = NULL,  *pre_prop = 
NULL;
+    BAT *qn_loc   = NULL, *qn_uri_loc = NULL;
+    BAT *prop_val = NULL,  *prop_text = NULL;
+    BAT *attr_own = NULL,  *attr_qn = NULL, *attr_prop = NULL;
+    BAT *frag_root = NULL, *elt_qn = NULL;
+    int   *pre_sizeT = NULL; /* Arrays holding the Tail values of some of the 
BATs above. */
+    char  *pre_levelT = NULL, *pre_kindT = NULL;
+    char  *text_base = NULL; /* text base of prop_text tail values */
+    oid   *attr_ownT = NULL, *attr_qnT = NULL, *attr_propT = NULL;
+    oid   *pre_propT = NULL;
+    var_t *prop_textT = NULL;
+
+    oid msg_node_pre = 0, qid_node_pre = 0, val_node_pre = 0;
+    oid call_node_pre = 0,  seq_node_pre = 0,  tpe_node_pre = 0;
+    oid next_call_node_pre = 0, next_seq_node_pre = 0, next_tpe_node_pre = 0;
+    oid ao_ptr = 0; /* cursor in the attr_own bat */
+    size_t nattrs = 0;
+    
+    /* We need to clean up the pre_size, pre_level, pre_prop and
+     * pre_kind values between two node values, to prevent that
+     * a node value is treated as part of the message */
+    oid start_invalidate = 0; /* indicates from which node we should start 
with invalidation */
+    char level_diff = 0; /* indicates how many levels each pre_level value of 
a node should be reduced. */
+
+    i = BUNfirst(shredBAT);
+    shredBATi = bat_iterator(shredBAT);
+    /* FIXME: should used BATdescriptor */
[EMAIL PROTECTED] getbat
+    @1 = BATdescriptor(*(bat*)BUNtail(shredBATi,[EMAIL PROTECTED]));
+    if (pre_size == NULL) {
+        send_err(out, ERR404, "env:Sender", "Shredded BAT @1 unavailable");
+        goto cleanup;
+    }
[EMAIL PROTECTED]
+    @:getbat(pre_size,PRE_SIZE)@
+    @:getbat(pre_level,PRE_LEVEL)@
+    @:getbat(pre_prop,PRE_PROP)@
+    @:getbat(pre_kind,PRE_KIND)@
+    @:getbat(prop_text,PROP_TEXT)@
+    @:getbat(prop_val,PROP_VAL)@
+    @:getbat(qn_uri_loc,QN_URI_LOC)@
+    @:getbat(qn_loc,QN_LOC)@
+    @:getbat(frag_root,FRAG_ROOT)@
+    @:getbat(attr_own,ATTR_OWN)@
+    @:getbat(attr_qn,ATTR_QN)@
+    @:getbat(attr_prop,ATTR_PROP)@
+
+    prop_vali = bat_iterator(prop_val);
+    qn_uli = bat_iterator(qn_uri_loc);
+
+    pre_sizeT  = (int*)  Tloc(pre_size, BUNfirst(pre_size));
+    pre_levelT = (char*) Tloc(pre_level, BUNfirst(pre_level));
+    pre_propT  = (oid*)  Tloc(pre_prop, BUNfirst(pre_prop));
+    pre_kindT  = (char*) Tloc(pre_kind, BUNfirst(pre_kind));
+    prop_textT = (var_t*)Tloc(prop_text, BUNfirst(prop_text));
+    attr_ownT  = (oid*)  Tloc(attr_own, BUNfirst(attr_own));
+    attr_qnT   = (oid*)  Tloc(attr_qn, BUNfirst(attr_qn));
+    attr_propT = (oid*)  Tloc(attr_prop, BUNfirst(attr_prop));
+    text_base  = prop_text->theap->base;
+
+    pre_level  = BATsetaccess(pre_level, BAT_WRITE);
+    frag_root  = BATsetaccess(frag_root, BAT_APPEND);
+    nattrs     = BATcount(attr_prop);
+
+
+    if (!(msg_node_pre = get_pre_by_qname(msg, 2, BATcount(pre_size), 
pre_propT, pre_kindT, qn_uri_loc))) {
+        send_err(out, ERR404, "env:Sender", msg);
+        goto cleanup;
+    }
+    call_node_pre = msg_node_pre;
+
+    if (msg == XRPC_REQUEST) {
+        /* XRPC request message parsing */
+        while(ao_ptr < nattrs && attr_ownT[ao_ptr] < msg_node_pre) ao_ptr++;
+        while(ao_ptr < nattrs && attr_ownT[ao_ptr] == msg_node_pre) {
+            pul = (char*) BUNtail(qn_uli, BUNfirst(qn_uri_loc) + 
attr_qnT[ao_ptr]);
+            val = (char*) BUNtail(prop_vali, BUNfirst(prop_val) + 
attr_propT[ao_ptr]);
+            if(strcmp(pul, XRPC_NS"|module") == 0) {
+                module = val;
+            } else if(strcmp(pul, XRPC_NS"|location") == 0) {
+                location = val;
+            } else if(strcmp(pul, XRPC_NS"|method") == 0) {
+                method = val;
+            } else if(strcmp(pul, XRPC_NS"|arity") == 0) {
+                arity_str = val;
+            } else if(strcmp(pul, XRPC_NS"|iter-count") == 0) {
+                itercnt_str = val;
+            } else if(strcmp(pul, XRPC_NS"|mode") == 0) {
+                mode_str = val;
+            } else if(strcmp(pul, XRPC_NS"|caller") == 0) {
+                caller = val;
+            } else if(strcmp(pul,XRPC_NS"|updCall") == 0) {
+                if((val[0] == 't' && val[1] == 'r' && val[2] == 'u' && val[3] 
== 'e') ||
+                   (val[0] == 'T' && val[1] == 'r' && val[2] == 'u' && val[3] 
== 'e') ||
+                   (val[0] == 'T' && val[1] == 'R' && val[2] == 'U' && val[3] 
== 'E'))
+                updCall = TRUE;
+            }
+            ao_ptr++;
+        }
+        if(!(module && location && method && arity_str)) {
+            send_err(out, ERR404, "env:Sender", 
+                "The \""XRPC_NS":request\" node didn't contain the required 
attributes\n");
+            goto cleanup;
+        }
+        if(!isAdmin && !isTrusted(out, location))
+            goto cleanup;
+        if(itercnt_str){
+            iterc = my_strtoll(out, FALSE, itercnt_str, "iter-count");
+            if(iterc == GDK_lng_min) goto cleanup;
+        }
+
+        /* Does this request require any isolation support? */
+        if ((qid_node_pre = get_pre_by_qname(XRPC_NS"|queryID",
+                        msg_node_pre, msg_node_pre + pre_sizeT[msg_node_pre] + 
1,
+                        pre_propT, pre_kindT, qn_uri_loc))) {
+            while(ao_ptr < nattrs && attr_ownT[ao_ptr] < qid_node_pre) 
ao_ptr++;
+            while(ao_ptr < nattrs && attr_ownT[ao_ptr] == qid_node_pre) {
+                pul = (char*) BUNtail(qn_uli, BUNfirst(qn_uri_loc) + 
attr_qnT[ao_ptr]);
+                val = (char*) BUNtail(prop_vali, BUNfirst(prop_val) + 
attr_propT[ao_ptr]);
+                if(strcmp(pul, XRPC_NS"|host") == 0) {
+                    host = val;
+                } else if(strcmp(pul, XRPC_NS"|querynr") == 0) {
+                    querynr_str = val;
+                } else if(strcmp(pul, XRPC_NS"|timeout") == 0) {
+                    timeout_str = val;
+                    timeout = my_strtoll(out, FALSE, timeout_str, "timeout");
+                    if (timeout == GDK_lng_min) goto cleanup;
+                } else {
+                    snprintf(errstr, 1024, 
+                        "Invalid attribute for the \""XRPC_NS":queryID\" 
element: %s\n", pul);
+                    send_err(out, ERR404, "env:Sender", errstr);
+                    goto cleanup;
+                }
+                ao_ptr++;
+            }
+            if(!(host && querynr_str && timeout_str)) {
+                send_err(out, ERR404, "env:Sender", "A \""XRPC_NS":queryID\" 
element "
+                    "must contain all three attributes: host, querynr, 
timeout\n");
+                goto cleanup;
+            }
+
+            k = strlen(host) + strlen(querynr_str) + 2;
+            if(!(qid = GDKmalloc(k))) {
+                send_err(out, ERR500, "env:Receiver", OUT_OF_MEM);
+                goto cleanup;
+            }
+
+            val = qid;
+            pul = qid + k;
+            while(*host && val < pul) *val++ = *host++;
+            *val++ = '|';
+            while(*querynr_str && val < pul) *val++ = *querynr_str++;
+            *val = '\0';
+        }
+        call_node_pre = get_pre_by_qname(XRPC_NS"|call", 
MAX(call_node_pre,msg_node_pre),
+            msg_node_pre + pre_sizeT[msg_node_pre] + 1,
+            pre_propT, pre_kindT, qn_uri_loc);
+
+        argc = my_strtoll(out, FALSE, arity_str, "arity");
+    }
+    if (iterc == -1) {
+        /* if no iterc was found in the request (and always for XRPC 
responses), just count sequence elements */
+        BAT *qn_seq = BATselect(qn_uri_loc, XRPC_NS"|sequence", 
XRPC_NS"|sequence");
+        elt_qn = get_elt_qn(pre_prop, qn_seq);
+        if (elt_qn && qn_seq) {
+            BAT* elt_seq = BATmirror(BATsemijoin(BATmirror(elt_qn),  elt_seq));
+            if (elt_seq) {
+                iterc = BATcount(elt_seq);
+                BBPreclaim(elt_seq);
+            }
+        }
+        if (iterc == -1) goto cleanup;
+    }
+    if (msg == XRPC_RESPONSE) {
+        /* for XRPC response messages we add all participants to the 
participant bat */
+        BAT *qn_part = BATselect(qn_uri_loc, XRPC_NS"|participant", 
XRPC_NS"|participant");
+        if (qn_part) {
+            BAT *elt_part = BATmirror(BATsemijoin(BATmirror(elt_qn),  
qn_part));
+            if (elt_part) {
+                BATiter pi = bat_iterator(elt_part);
+                BUN p,q;
+                BATloop(elt_part,p,q) {
+                    oid pre = 1 + *(oid*) BUNhead(pi,p);
+                    if (pre_kindT[pre] == TEXT) {
+                        str part = text_base + pre_propT[pre];
+                        BUNappend(participants, part, FALSE);
+                    }
+                }
+                BBPreclaim(elt_part);
+                argc = 1;
+            }
+            BBPreclaim(qn_part);
+        }
+    } 
+    if (argc == GDK_lng_min) goto cleanup;
+
+    /* the req struct contains all parsed data (we use it also for response 
messages) */ 
+    if(!(req = XRPCreq_new(qid, caller, timeout, mode_str, module, method, 
location, updCall, iterc, argc))) {
+        send_err(out, ERR500, "env:Receiver", OUT_OF_MEM);
+        goto cleanup;
+    }
+
+    /* Fill the arrays 'req->argcnt', 'req->argval', 'req->argtpe' */
+    /* i: index in xrpc:call; j: index of xrpc:sequence per xrpc:call */
+    for(i = 0; next_call_node_pre < BATcount(pre_size); call_node_pre = 
next_call_node_pre, i++) {
+        /* skip possible empty text node, without further checking */
+        call_node_pre += (pre_kindT[call_node_pre] == ELEMENT ? 0 : 1);
+        next_call_node_pre = call_node_pre + pre_sizeT[call_node_pre] + 1;
+
+        for(seq_node_pre = call_node_pre + 1, j = 0; seq_node_pre < 
next_call_node_pre;
+                seq_node_pre = next_seq_node_pre, j++) {
+            /* skip possible empty text nodes, without further checking */
+            seq_node_pre += (pre_kindT[seq_node_pre] == ELEMENT ? 0 : 1);
+            next_seq_node_pre = seq_node_pre + pre_sizeT[seq_node_pre] + 1;
+       
+            for(tpe_node_pre = seq_node_pre+1, k=1; tpe_node_pre < 
next_seq_node_pre;
+                    tpe_node_pre = next_tpe_node_pre, k++) {
+                /* skip possible empty text nodes, without further checking */
+                tpe_node_pre += (pre_kindT[tpe_node_pre] == ELEMENT ? 0 : 1);
+                next_tpe_node_pre = tpe_node_pre + pre_sizeT[tpe_node_pre]+1;
+                /* advance our cursor in attr_own */
+                while(ao_ptr < nattrs && attr_ownT[ao_ptr] < tpe_node_pre) 
ao_ptr++;
+
+                if (req->nr_args == req->max_args) {
+                    req->max_args *= 2;
+                    char **bptr = GDKrealloc(req->argval, req->max_args * 
sizeof(char*));
+                    if (!bptr) {
+                        send_err(out, ERR500, "env:Receiver",OUT_OF_MEM);
+                        goto cleanup;
+                    }
+                    req->argval = bptr;
+
+                    if(!(bptr = GDKrealloc(req->argtpe, req->max_args * 
sizeof(int*)))) {
+                        send_err(out, ERR500, "env:Receiver",OUT_OF_MEM);
+                        goto cleanup;
+                    }
+                    req->argtpe = (int*) bptr;
+                }
+
+                pul = (char*) BUNtail(qn_uli, pre_propT[tpe_node_pre]);
+                if (strcmp(pul, XRPC_NS"|atomic-value") == 0) {
+                    int tpe = -1;
+                    while(ao_ptr < nattrs && attr_ownT[ao_ptr] == 
tpe_node_pre) {
+                        if(strcmp((char*)BUNtail(qn_uli, 
BUNfirst(qn_uri_loc)+attr_qnT[ao_ptr]),
+                                    XSI_NS"|type") == 0) {
+                            tpe = xquery_typenr((char*)BUNtail(prop_vali, 
BUNfirst(prop_val)+attr_propT[ao_ptr]));
+                        }
+                        ao_ptr++;
+                    }
+                    if(tpe < 0){
+                        snprintf(errstr, 1024, "XRPC request: 
iter["LLFMT"]/param["LLFMT"]/value["LLFMT"]"
+                                " does not have an \""XSI_NS":type\"", i+1, 
j+1, k);
+                        send_err(out, ERR404, "env:Sender", errstr);
+                        goto cleanup;
+                    }
+                    req->argtpe[req->nr_args] = tpe;
+                    val_node_pre = tpe_node_pre + 1;
+                    if(pre_sizeT[tpe_node_pre] != 1 || pre_kindT[val_node_pre] 
!= TEXT) {
+                        snprintf(errstr, 1024, "XRPC message: 
iter["LLFMT"]/param["LLFMT"]/value["LLFMT"]"
+                                "is expected to have a simple value", i+1, 
j+1, k);
+                        send_err(out, ERR404, "env:Sender", errstr);
+                        goto cleanup;
+                    }
+                    req->argval[req->nr_args] = text_base + 
prop_textT[pre_propT[val_node_pre]];
+                } else if (strcmp(pul, XRPC_NS"|attribute") == 0) {
+                    while(ao_ptr < nattrs && attr_ownT[ao_ptr] < tpe_node_pre) 
ao_ptr++;
+                    if (attr_ownT[ao_ptr] == tpe_node_pre) {
+                        val_node_pre = ao_ptr;
+                    } else {
+                        snprintf(errstr, 1024, "XRPC request: "
+                                "iter["LLFMT"]/param["LLFMT"]/value["LLFMT"] "
+                                "of type "XRPC_NS":attribute is expected to 
have a single attribute",
+                                i+1, j+1, k);
+                        send_err(out, ERR404, "env:Sender", errstr);
+                        goto cleanup;
+                    }
+                    req->hasNodeParam = TRUE;
+                    req->argtpe[req->nr_args] = XS_ATTRIBUTE;
+                    req->argval[req->nr_args] = (char*) (size_t) val_node_pre; 
+                } else {
+                    req->argtpe[req->nr_args] = get_node_type(pul);
+                    if (req->argtpe[req->nr_args] == XS_DOCUMENT) {
+                        val_node_pre = tpe_node_pre;
+                        pre_kindT[val_node_pre] = 4;
+                        pre_propT[val_node_pre] = oid_nil;
+                    } else if (req->argtpe[req->nr_args] < 0) {
+                        snprintf(errstr, 1024, "XRPC request: "
+                                "iter["LLFMT"]/param["LLFMT"]/value["LLFMT"] "
+                                "contains unsupported type: %s\n",
+                                i+1, j+1, k, pul);
+                        send_err(out, ERR404, "env:Sender", errstr);
+                        goto cleanup;
+                    } else {
+                        val_node_pre = tpe_node_pre + 1;
+                        val_node_pre += (pre_kindT[val_node_pre] == ELEMENT ? 
0 : 1);
+                    }
+                    req->argval[req->nr_args] = (char*) (size_t) val_node_pre;
+                    frag_root = BUNappend(frag_root, (ptr)&val_node_pre, TRUE);
+                    req->hasNodeParam = TRUE;
+
+                    /* reassign level values for the ELEM nodes */
+                    level_diff = pre_levelT[val_node_pre];
+                    if(req->argtpe[req->nr_args] == XS_DOCUMENT)
+                        level_diff++;
+                    unsigned long long l = val_node_pre;
+                    for( ; l <= (val_node_pre + pre_sizeT[val_node_pre]); l++){
+                        pre_levelT[l] -= level_diff;
+                    }
+                    for (l = start_invalidate; l < val_node_pre; l++) {
+                        pre_levelT[l] = -3;
+                        pre_sizeT[l] = 0;
+                    }
+                    start_invalidate = val_node_pre + pre_sizeT[val_node_pre] 
+ 1;
+                }
+                req->argcnt[i][j]++;
+                req->nr_args++;
+            } /* end loop 'xrpc:<type>' */
+        } /* end loop 'xrpc:sequence' */
+    } /* end loop 'xrpc:call' */
+    frag_root = BATsetaccess(frag_root, BAT_READ);
+    res = req; req = NULL;
[EMAIL PROTECTED] delbat
+    if (@1) BBPunfix(@1->batCacheid);
[EMAIL PROTECTED]
+cleanup:
+    if (req) XRPCreq_free(req);
+    if (elt_qn) BBPreclaim(elt_qn);
+    @:delbat(pre_level)@
+    @:delbat(pre_prop)@
+    @:delbat(pre_kind)@
+    @:delbat(prop_text)@
+    @:delbat(prop_val)@
+    @:delbat(qn_uri_loc)@
+    @:delbat(qn_loc)@
+    @:delbat(frag_root)@
+    @:delbat(attr_own)@
+    @:delbat(attr_qn)@
+    @:delbat(attr_prop)@
+    return res;
+}
+
+
 /**
  * Retrieves the request message from the connection and shred it to
  * BATs.
@@ -198,9 +994,6 @@
               BAT *shredBAT,
               bit isAdmin)
 {
-     /* request message parsing code  moved to xrpc_common as it is now also 
-      * used for response message parsing 
-      */
     return xrpc_parse_message(out, shredBAT, NULL, isAdmin);
 }
 
@@ -621,6 +1414,30 @@
     return GDK_SUCCEED;
 }
 
[EMAIL PROTECTED] xrpc_bat
+    [EMAIL PROTECTED] = BATnew(TYPE_void,ATOMindex("@2"),1024);
+    assert([EMAIL PROTECTED]);
+    BATseqbase([EMAIL PROTECTED], 1);
+    BBPrename([EMAIL PROTECTED]>batCacheid, "[EMAIL PROTECTED]");
[EMAIL PROTECTED]
+BAT *xrpc_qids = NULL, *xrpc_statuses = NULL, *xrpc_timeouts = NULL, 
*xrpc_locks = NULL, *xrpc_wsids = NULL;
+BAT *xrpc_trusted = NULL, *xrpc_admin = NULL, *xrpc_user = NULL;
+
+bat* xrpc_prelude(void) {
+    @:xrpc_bat(qids,str)@
+    @:xrpc_bat(statuses,str)@
+    @:xrpc_bat(timeouts,lng)@
+    @:xrpc_bat(locks,lock)@
+    @:xrpc_bat(wsids,lng)@
+    @:xrpc_bat(trusted,str)@
+    @:xrpc_bat(admin,str)@
+    @:xrpc_bat(user,str)@
+    CMDmy_hostname(&xrpc_hostname);
+    assert(xrpc_hostname);
+    return NULL;
+}
+
+
 void xrpc_epilogue(void)
 {
     shttpd_fini();      /* Shut down the HTTP server. */


-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Monetdb-pf-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-pf-checkins

Reply via email to