- exp_bones merge
authorJiří Škrábal <nykolas@ics.muni.cz>
Thu, 14 Oct 2004 14:27:30 +0000 (14:27 +0000)
committerJiří Škrábal <nykolas@ics.muni.cz>
Thu, 14 Oct 2004 14:27:30 +0000 (14:27 +0000)
org.glite.lb.server/src/bkserverd.c
org.glite.lb.server/src/il_notification.c
org.glite.lb.server/src/il_notification.h
org.glite.lb.server/src/ws_fault.c [new file with mode: 0644]
org.glite.lb.server/src/ws_fault.h [new file with mode: 0644]
org.glite.lb.server/src/ws_plugin.c [new file with mode: 0644]
org.glite.lb.server/src/ws_plugin.h [new file with mode: 0644]
org.glite.lb.server/src/ws_query.c [new file with mode: 0644]
org.glite.lb.server/src/ws_typemap.dat [new file with mode: 0644]
org.glite.lb.server/src/ws_typeref.c.T [new file with mode: 0644]
org.glite.lb.server/src/ws_typeref.h [new file with mode: 0644]

index 811935a..68e25cc 100644 (file)
@@ -1,6 +1,3 @@
-#ident "$Header$"
-
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -30,6 +27,9 @@
 
 #include <globus_common.h>
 
+#include <stdsoap2.h>
+
+#include "glite/lb/srvbones.h"
 #include "glite/lb/consumer.h"
 #include "glite/lb/purge.h"
 #include "glite/lb/context.h"
 #include "lbs_db.h"
 #include "lb_authz.h"
 #include "il_notification.h"
+#include "ws_plugin.h"
 
 extern int edg_wll_StoreProto(edg_wll_Context ctx);
 extern edg_wll_ErrorCode edg_wll_Open(edg_wll_Context ctx, char *cs);
-edg_wll_ErrorCode edg_wll_Close(edg_wll_Context);
+extern edg_wll_ErrorCode edg_wll_Close(edg_wll_Context);
+
+
 
-#define max(x,y) ((x)>(y)?(x):(y))
 
 #define CON_QUEUE              20      /* accept() */
 #define SLAVE_OVERLOAD         10      /* queue items per slave */
@@ -60,8 +62,6 @@ edg_wll_ErrorCode edg_wll_Close(edg_wll_Context);
 #define SLAVE_CONNS_MAX                500     /* commit suicide after that many connections */
 #define MASTER_TIMEOUT         30      /* maximal time of one-round of master network communication */
 #define SLAVE_TIMEOUT          30      /* maximal time of one-round of slave network communication */
-#define SLAVE_CHECK_SIGNALS    2       /* how often to check signals while waiting for recv_mesg */
-#define WATCH_TIMEOUT          1800    /* wake up to check updated credentials */
 
 #ifndef EDG_PURGE_STORAGE
 #define EDG_PURGE_STORAGE      "/tmp/purge"
@@ -77,53 +77,38 @@ edg_wll_ErrorCode edg_wll_Close(edg_wll_Context);
 #endif
 
 #ifndef dprintf
-#define dprintf(x) { if (debug) printf x; }
+#define dprintf(x)             { if (debug) printf x; }
 #endif
 
-       static const int one = 1;
-
-int debug  = 0;
-int rgma_export = 0;
-static int noAuth = 0;
-static int noIndex = 0;
-static int strict_locking = 0;
-static int hardJobsLimit = 0;
-static int hardEventsLimit = 0;
-static int hardRespSizeLimit = 0;
-static char    *dbstring = NULL,*fake_host = NULL;
-static int fake_port = 0;
-
-static char    ** super_users = NULL;
-char   *cadir = NULL, *vomsdir = NULL;
-
+#define sizofa(a)              (sizeof(a)/sizeof((a)[0]))
 
-static int     slaves = 10, semaphores = -1, semset;
-static char    *purgeStorage = EDG_PURGE_STORAGE;
-static char    *dumpStorage = EDG_DUMP_STORAGE;
-static time_t  purge_timeout[EDG_WLL_NUMBER_OF_STATCODES];
-static time_t  notif_duration = 60*60*24*7;
-static edg_wll_QueryRec        **job_index;
-static edg_wll_IColumnRec *job_index_cols;
 
-static volatile int die = 0, child_died = 0;
+int                                            debug  = 0;
+int                                            rgma_export = 0;
+static const int               one = 1;
+static int                             noAuth = 0;
+static int                             noIndex = 0;
+static int                             strict_locking = 0;
+static int                             hardJobsLimit = 0;
+static int                             hardEventsLimit = 0;
+static int                             hardRespSizeLimit = 0;
+static char                       *dbstring = NULL,*fake_host = NULL;
+static int                             fake_port = 0;
+static char                      **super_users = NULL;
+static int                             slaves = 10,
+                                               semaphores = -1,
+                                               semset;
+static char                       *purgeStorage = EDG_PURGE_STORAGE;
+static char                       *dumpStorage = EDG_DUMP_STORAGE;
 
-static int dispatchit(int,int,int);
-static int do_sendmsg(int,int,unsigned long,int);
-static int do_recvmsg(int,int *,unsigned long *,int *);
 
-static void wait_for_open(edg_wll_Context,const char *);
-
-static void catchsig(int sig)
-{
-       die = sig;
-}
+static time_t                  purge_timeout[EDG_WLL_NUMBER_OF_STATCODES];
+static time_t                  notif_duration = 60*60*24*7;
 
-static void catch_chld(int sig)
-{
-       child_died = 1;
-}
+static gss_cred_id_t   mycred = GSS_C_NO_CREDENTIAL;
+char                              *cadir = NULL,
+                                          *vomsdir = NULL;
 
-static int slave(void *,int);
 
 static struct option opts[] = {
        {"cert",        1, NULL,        'c'},
@@ -131,6 +116,7 @@ static struct option opts[] = {
        {"CAdir",       1, NULL,        'C'},
        {"VOMSdir",     1, NULL,        'V'},
        {"port",        1, NULL,        'p'},
+       {"wsport",  1, NULL,    'w'},
        {"address",     1, NULL,        'a'},
        {"debug",       0, NULL,        'd'},
        {"rgmaexport",  0, NULL,        'r'},
@@ -161,6 +147,7 @@ static void usage(char *me)
                "\t-C, --CAdir\t trusted certificates directory\n"
                "\t-V, --VOMSdir\t trusted VOMS servers certificates directory\n"
                "\t-p, --port\t port to listen\n"
+               "\t-w, --wsport\t port to serve the web services requests\n"
                "\t-m, --mysql\t database connect string\n"
                "\t-d, --debug\t don't run as daemon, additional diagnostics\n"
                "\t-r, --rgmaexport write state info to RGMA interface\n"
@@ -182,307 +169,81 @@ static void usage(char *me)
        ,me);
 }
 
-
-static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after)
-{
-        (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec);
-        (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec);
-        while ( (*timeout).tv_usec < 0) {
-                (*timeout).tv_sec--;
-                (*timeout).tv_usec += 1000000;
-        }
-        if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1);
-        else return(0);
-}
-
-static int check_timeout(struct timeval *timeout, struct timeval before, struct timeval after)
-{
-       return (timeout->tv_usec <= after.tv_usec - before.tv_usec) ? 
-                       (timeout->tv_sec <= after.tv_sec - before.tv_sec) :
-                       (timeout->tv_sec < after.tv_sec - before.tv_sec);
-}
-
-static void clnt_reject(void *mycred, int conn)
-{
-       int     flags = fcntl(conn, F_GETFL, 0);
-
-       if (fcntl(conn, F_SETFL, flags | O_NONBLOCK) < 0) 
-               return;
-
-       edg_wll_gss_reject(conn);
-       return;
-}
-
-
-#define MSG_BUFSIZ     15
-
-/* send socket sock through socket to_sock */
-static int do_sendmsg(int to_sock, int sock, unsigned long clnt_dispatched,int store) {
-
-        struct msghdr msg = {0};
-        struct cmsghdr *cmsg;
-        int myfds;     /* Contains the file descriptors to pass. */
-        char buf[CMSG_SPACE(sizeof myfds)];  /* ancillary data buffer */
-        int *fdptr;
-        struct iovec sendiov;
-        char sendbuf[MSG_BUFSIZ];              /* to store unsigned int + \0 */
-
-
-        snprintf(sendbuf,sizeof(sendbuf),"%c %lu",store?'S':'Q',clnt_dispatched);
-
-        msg.msg_name = NULL;
-        msg.msg_namelen = 0;
-        msg.msg_iov = &sendiov;
-        msg.msg_iovlen = 1;
-        sendiov.iov_base = sendbuf;
-        sendiov.iov_len = sizeof(sendbuf);
-
-        msg.msg_control = buf;
-        msg.msg_controllen = sizeof buf;
-
-        cmsg = CMSG_FIRSTHDR(&msg);
-        cmsg->cmsg_level = SOL_SOCKET;
-        cmsg->cmsg_type = SCM_RIGHTS;
-        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-        fdptr = (int *)CMSG_DATA(cmsg);
-        *fdptr = sock;
-
-        msg.msg_controllen = cmsg->cmsg_len;
-        /* send fd to server-slave to do rest of communication */
-       if (sendmsg(to_sock, &msg, 0) < 0)  
-               return 1;
-        
-        return 0;
-}
-
-
-/* receive socket sock through socket from_sock */
-static int do_recvmsg(int from_sock, int *sock, unsigned long *clnt_accepted,int *store) {
-
-        struct msghdr msg = {0};
-        struct cmsghdr *cmsg;
-        int myfds; /* Contains the file descriptors to pass. */
-        char buf[CMSG_SPACE(sizeof(myfds))];  /* ancillary data buffer */
-        struct iovec recviov;
-        char recvbuf[MSG_BUFSIZ],op;
-
-
-        msg.msg_name = NULL;
-        msg.msg_namelen = 0;
-        msg.msg_iov = &recviov;
-        msg.msg_iovlen = 1;
-        recviov.iov_base = recvbuf;
-        recviov.iov_len = sizeof(recvbuf);
-
-        msg.msg_control = buf;
-        msg.msg_controllen = sizeof buf;
-
-        cmsg = CMSG_FIRSTHDR(&msg);
-        cmsg->cmsg_level = SOL_SOCKET;
-        cmsg->cmsg_type = SCM_RIGHTS;
-        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
-        msg.msg_controllen = cmsg->cmsg_len;
-
-        if (recvmsg(from_sock, &msg, 0) < 0) 
-               return 1;
-        
-        *sock = *((int *)CMSG_DATA(cmsg));
-       sscanf(recvbuf,"%c %lu",&op,clnt_accepted);
-       *store = op == 'S';
-
-        return 0;
-}
+static void wait_for_open(edg_wll_Context,const char *);
+static int decrement_timeout(struct timeval *, struct timeval, struct timeval);
+static int read_roots(const char *);
+static int asyn_gethostbyaddr(char **, const char *, int, int, struct timeval *);
+static int amIroot(const char *);
+static int parse_limits(char *, int *, int *, int *);
+static int check_mkdir(const char *);
 
 
-struct asyn_result {
-       struct hostent *ent;
-       int             err;
+/*
+ *     SERVER BONES structures and handlers
+ */
+int bk_clnt_data_init(void **);
+
+       /*
+        *      Serve & Store handlers
+        */
+int bk_clnt_reject(int);
+int bk_handle_connection(int, struct timeval, void *);
+int bk_accept_serve(int, void *);
+int bk_accept_store(int, void *);
+int bk_clnt_disconnect(int, void *);
+
+       /*
+        *      WS handlers
+        */
+int bk_handle_ws_connection(int, struct timeval, void *);
+int bk_accept_ws(int, void *);
+int bk_ws_clnt_reject(int);
+int bk_ws_clnt_disconnect(int, void *);
+
+
+#define SRV_SERVE              0
+#define SRV_STORE              1
+#define SRV_WS                 2
+static struct glite_srvbones_service service_table[] = {
+       { "serve",      -1, bk_handle_connection, bk_accept_serve, bk_clnt_reject, bk_clnt_disconnect },
+       { "store",      -1, bk_handle_connection, bk_accept_store, bk_clnt_reject, bk_clnt_disconnect },
+       { "WS",         -1, bk_handle_ws_connection, bk_accept_ws, bk_ws_clnt_reject, bk_ws_clnt_disconnect }
 };
 
-/* ares callback handler for ares_gethostbyaddr()       */
-static void callback_handler(void *arg, int status, struct hostent *h) {
-       struct asyn_result *arp = (struct asyn_result *) arg;
-
-       switch (status) {
-          case ARES_SUCCESS:
-               if (h && h->h_name) {
-                       arp->ent->h_name = strdup(h->h_name);           
-                       if (arp->ent->h_name == NULL) {
-                               arp->err = NETDB_INTERNAL;
-                       } else {
-                               arp->err = NETDB_SUCCESS;
-                       }
-               } else {
-                       arp->err = NO_DATA;
-               }
-               break;
-           case ARES_EBADNAME:
-           case ARES_ENOTFOUND:
-               arp->err = HOST_NOT_FOUND;
-               break;
-           case ARES_ENOTIMP:
-               arp->err = NO_RECOVERY;
-               break;
-           case ARES_ENOMEM:
-           case ARES_EDESTRUCTION:
-           default:
-               arp->err = NETDB_INTERNAL;
-               break;
-       }
-}
-
-static void free_hostent(struct hostent *h){
-       int i;
-
-       if (h) {
-               if (h->h_name) free(h->h_name);
-               if (h->h_aliases) {
-                       for (i=0; h->h_aliases[i]; i++) free(h->h_aliases[i]);
-                       free(h->h_aliases);
-               }
-               if (h->h_addr_list) {
-                       for (i=0; h->h_addr_list[i]; i++) free(h->h_addr_list[i]);
-                       free(h->h_addr_list);
-               }
-               free(h);
-       }
-}
-
-static int asyn_gethostbyaddr(char **name, const char *addr,int len, int type, struct timeval *timeout) {
-       struct asyn_result ar;
-       ares_channel channel;
-       int nfds;
-       fd_set readers, writers;
-       struct timeval tv, *tvp;
-       struct timeval start_time,check_time;
-
-
-/* start timer */
-        gettimeofday(&start_time,0);
-
-/* ares init */
-        if ( ares_init(&channel) != ARES_SUCCESS ) return(NETDB_INTERNAL);
-       ar.ent = (struct hostent *) malloc (sizeof(*ar.ent));
-       memset((void *) ar.ent, 0, sizeof(*ar.ent));
-
-/* query DNS server asynchronously */
-       ares_gethostbyaddr(channel, addr, len, type, callback_handler, (void *) &ar);
-
-/* wait for result */
-        while (1) {
-                FD_ZERO(&readers);
-                FD_ZERO(&writers);
-                nfds = ares_fds(channel, &readers, &writers);
-                if (nfds == 0)
-                        break;
-
-                gettimeofday(&check_time,0);
-               if (decrement_timeout(timeout, start_time, check_time)) {
-                       ares_destroy(channel);
-                       free_hostent(ar.ent);
-                       return(TRY_AGAIN);
-               }
-               start_time = check_time;
-
-                tvp = ares_timeout(channel, timeout, &tv);
-
-                switch ( select(nfds, &readers, &writers, NULL, tvp) ) {
-                       case -1: if (errno != EINTR) {
-                                       ares_destroy(channel);
-                                       free_hostent(ar.ent);
-                                       return NETDB_INTERNAL;
-                                } else
-                                       continue;
-                       case 0: 
-                               FD_ZERO(&readers);
-                               FD_ZERO(&writers);
-                               /* fallthrough */
-                        default : ares_process(channel, &readers, &writers);
-                }
-
-        }
-
-       
-       ares_destroy(channel);
-               
-       if (ar.err == NETDB_SUCCESS) {
-               *name = strdup(ar.ent->h_name); 
-               free_hostent(ar.ent); 
-       }
-       return (ar.err);
-}
-
-static int read_roots(const char *file)
-{
-       FILE    *roots = fopen(file,"r");
-       char    buf[BUFSIZ];
-       int     cnt = 0;
-
-       if (!roots) {
-               perror(file);
-               return 1;
-       }
-
-       while (!feof(roots)) {
-               char    *nl;
-               fgets(buf,sizeof buf,roots);
-               nl = strchr(buf,'\n');
-               if (nl) *nl = 0;
-
-               super_users = realloc(super_users, (cnt+1) * sizeof super_users[0]);
-               super_users[cnt] = strdup(buf);
-               super_users[++cnt] = NULL;
-       }
-
-       fclose(roots);
-
-       return 0;
-}
-
-static int amIroot(const char *subj)
-{
-       int     i;
+struct clnt_data_t {
+       edg_wll_Context                 ctx;
+       struct soap                        *soap;
+       void                               *mysql;
+       edg_wll_QueryRec          **job_index;
+       edg_wll_IColumnRec         *job_index_cols;
+};
 
-       if (!subj) return 0;
-       for (i=0; super_users && super_users[i]; i++) 
-               if (strcmp(subj,super_users[i]) == 0) return 1;
 
-       return 0;
-}
 
-static int parse_limits(char *opt, int *j_limit, int *e_limit, int *size_limit)
+int main(int argc, char *argv[])
 {
-       return (sscanf(opt, "%d:%d:%d", j_limit, e_limit, size_limit) == 3);
-}
-
-static unsigned long   clnt_dispatched=0, clnt_accepted=0;
-static gss_cred_id_t   mycred = GSS_C_NO_CREDENTIAL;
-static int     server_sock,store_sock;
+       int                                     fd, i;
+       struct sockaddr_in      a;
+       char                       *mysubj = NULL;
+       int                                     opt;
+       char                            pidfile[PATH_MAX] = EDG_BKSERVERD_PIDFILE,
+                                          *port, *ws_port,
+                                          *name,
+                                          *cert, *key;
+       FILE                       *fpid;
+       key_t                           semkey;
+       edg_wll_Context         ctx;
+       OM_uint32                       min_stat;
+       edg_wll_GssStatus       gss_code;
+       struct timeval          to;
 
-static int check_mkdir(const char *);
 
-int main(int argc,char *argv[])
-{
-       int     fd,i;
-       struct sockaddr_in      a;
-       struct sigaction        sa;
-       sigset_t        sset;
-       char    *mysubj = NULL;
-       int     opt;
-       char    *cert,*key,*port;
-       char    *name,pidfile[PATH_MAX] = EDG_BKSERVERD_PIDFILE;
-       int     sock_slave[2];
-       FILE    *fpid;
-       key_t   semkey;
-       time_t  cert_mtime = 0,key_mtime = 0;
-       edg_wll_Context ctx;
-       OM_uint32       min_stat;
-       edg_wll_GssStatus gss_code;
 
        name = strrchr(argv[0],'/');
        if (name) name++; else name = argv[0];
 
-       asprintf(&port,"%d",GLITE_WMSC_JOBID_DEFAULT_PORT);
+       asprintf(&port, "%d", GLITE_WMSC_JOBID_DEFAULT_PORT);
+       asprintf(&ws_port, "%d", GLITE_WMSC_JOBID_DEFAULT_PORT+2);
        cert = key = cadir = vomsdir = NULL;
 
 /* no magic here: 1 month, 3 and 7 days */
@@ -506,13 +267,14 @@ int main(int argc,char *argv[])
        if (geteuid()) snprintf(pidfile,sizeof pidfile,"%s/edg-bkserverd.pid",
                        getenv("HOME"));
 
-       while ((opt = getopt_long(argc,argv,"a:c:k:C:V:p:drm:ns:l:L:N:i:S:D:X:Y:",opts,NULL)) != EOF) switch (opt) {
+       while ((opt = getopt_long(argc,argv,"a:c:k:C:V:p:w:drm:ns:l:L:N:i:S:D:X:Y:",opts,NULL)) != EOF) switch (opt) {
                case 'a': fake_host = strdup(optarg); break;
                case 'c': cert = optarg; break;
                case 'k': key = optarg; break;
                case 'C': cadir = optarg; break;
                case 'V': vomsdir = optarg; break;
                case 'p': free(port); port = strdup(optarg); break;
+               case 'w': free(ws_port); ws_port = strdup(optarg); break;
                case 'd': debug = 1; break;
                case 'r': rgma_export = 1; break;
                case 'm': dbstring = optarg; break;
@@ -556,29 +318,31 @@ int main(int argc,char *argv[])
                case '?': usage(name); return 1;
        }
 
-       if (optind < argc) { usage(name); return 1; }
+       if ( optind < argc ) { usage(name); return 1; }
 
        setlinebuf(stdout);
        setlinebuf(stderr);
 
-       dprintf(("Master pid %d\n",getpid()));
        fpid = fopen(pidfile,"r");
-       if (fpid) {
+       if ( fpid )
+       {
                int     opid = -1;
-               if (fscanf(fpid,"%d",&opid) == 1) {
-                       if (!kill(opid,0)) {
+
+               if ( fscanf(fpid,"%d",&opid) == 1 )
+               {
+                       if ( !kill(opid,0) )
+                       {
                                fprintf(stderr,"%s: another instance running, pid = %d\n",argv[0],opid);
                                return 1;
-                       } else if (errno != ESRCH) {
-                               perror("kill()"); return 1;
                        }
+                       else if (errno != ESRCH) { perror("kill()"); return 1; }
                }
                fclose(fpid);
        } else if (errno != ENOENT) { perror(pidfile); return 1; }
 
-       fpid = fopen(pidfile,"w");
+       fpid = fopen(pidfile, "w");
        if (!fpid) { perror(pidfile); return 1; }
-       fprintf(fpid,"%d",getpid());
+       fprintf(fpid, "%d", getpid());
        fclose(fpid);
 
        semkey = ftok(pidfile,0);
@@ -589,29 +353,36 @@ int main(int argc,char *argv[])
        if (check_mkdir(purgeStorage)) exit(1);
 
        if (semaphores == -1) semaphores = slaves;
-       semset = semget(semkey,0,0);
-       if (semset >= 0) semctl(semset,0,IPC_RMID);
-       semset = semget(semkey,semaphores,IPC_CREAT | 0600);
+       semset = semget(semkey, 0, 0);
+       if (semset >= 0) semctl(semset, 0, IPC_RMID);
+       semset = semget(semkey, semaphores, IPC_CREAT | 0600);
        if (semset < 0) { perror("semget()"); return 1; }
        dprintf(("Using %d semaphores, set id %d\n",semaphores,semset));
-       for (i=0; i<semaphores; i++) {
+       for (i=0; i<semaphores; i++)
+       {
                struct sembuf   s;
 
                s.sem_num = i; s.sem_op = 1; s.sem_flg = 0;
                if (semop(semset,&s,1) == -1) { perror("semop()"); return 1; }
        }
 
-       if (fake_host) {
+       if ( fake_host )
+       {
                char    *p = strchr(fake_host,':');
-               if (p) {
+
+               if (p)
+               {
                        *p = 0;
                        fake_port = atoi(p+1);
-               } else fake_port = atoi(port);
+               }
+               else fake_port = atoi(port);
        }
-       else {
+       else
+       {
                char    buf[300];
 
-               if (globus_module_activate(GLOBUS_COMMON_MODULE) != GLOBUS_SUCCESS)   {
+               if ( globus_module_activate(GLOBUS_COMMON_MODULE) != GLOBUS_SUCCESS )
+               {
                        dprintf(("[%d]: Unable to initialize Globus common module\n",getpid()));
                        if (!debug) syslog(LOG_CRIT,"Unable to initialize Globus common module\n");
                }
@@ -622,72 +393,85 @@ int main(int argc,char *argv[])
                fake_port = atoi(port); 
        }
 
-       dprintf(("server address: %s:%d\n",fake_host,fake_port));
-
-       server_sock = socket(PF_INET,SOCK_STREAM,0);
-       if (server_sock<0) { perror("socket()"); return 1; }
+       dprintf(("server address: %s:%d\n", fake_host, fake_port));
 
+       service_table[SRV_SERVE].conn = socket(PF_INET, SOCK_STREAM, 0);
+       if ( service_table[SRV_SERVE].conn < 0 ) { perror("socket()"); return 1; }
        a.sin_family = AF_INET;
        a.sin_port = htons(atoi(port));
        a.sin_addr.s_addr = INADDR_ANY;
-
-       setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-       if (bind(server_sock,(struct sockaddr *) &a,sizeof(a))) 
+       setsockopt(service_table[SRV_SERVE].conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+       if ( bind(service_table[SRV_SERVE].conn, (struct sockaddr *) &a, sizeof(a)) )
+       { 
                char    buf[100];
+
                snprintf(buf,sizeof(buf),"bind(%d)",atoi(port));
                perror(buf);
                return 1;
        }
+       if ( listen(service_table[SRV_SERVE].conn, CON_QUEUE) ) { perror("listen()"); return 1; }
 
-       if (listen(server_sock,CON_QUEUE)) { perror("listen()"); return 1; }
-
-       store_sock = socket(PF_INET,SOCK_STREAM,0);
-       if (store_sock<0) { perror("socket()"); return 1; }
-
+       service_table[SRV_STORE].conn = socket(PF_INET, SOCK_STREAM, 0);
+       if ( service_table[SRV_STORE].conn < 0) { perror("socket()"); return 1; }
        a.sin_family = AF_INET;
-       a.sin_port = htons(atoi(port)+1);
-       a.sin_addr.s_addr = INADDR_ANY;
-
-       setsockopt(store_sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-       if (bind(store_sock,(struct sockaddr *) &a,sizeof(a))) {
+a.sin_port = htons(atoi(port)+1);
+a.sin_addr.s_addr = INADDR_ANY;
+       setsockopt(service_table[SRV_STORE].conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+       if ( bind(service_table[SRV_STORE].conn, (struct sockaddr *) &a, sizeof(a)))
+       {
                char    buf[100];
-               snprintf(buf,sizeof(buf),"bind(%d)",atoi(port)+1);
+
+               snprintf(buf,sizeof(buf), "bind(%d)", atoi(port)+1);
                perror(buf);
                return 1;
        }
-       if (listen(store_sock,CON_QUEUE)) { perror("listen()"); return 1; }
+       if ( listen(service_table[SRV_STORE].conn, CON_QUEUE) ) { perror("listen()"); return 1; }
+
+       service_table[SRV_WS].conn = socket(PF_INET, SOCK_STREAM, 0);
+       if ( service_table[SRV_WS].conn < 0) { perror("socket()"); return 1; }
+       a.sin_family = AF_INET;
+       a.sin_port = htons(atoi(ws_port));
+       a.sin_addr.s_addr = INADDR_ANY;
+       setsockopt(service_table[SRV_WS].conn, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
+       if ( bind(service_table[SRV_WS].conn, (struct sockaddr *) &a, sizeof(a)))
+       {
+               char    buf[100];
 
-       if (socketpair(AF_UNIX, SOCK_STREAM, 0, sock_slave)) {
-               perror("socketpair()");
+               snprintf(buf, sizeof(buf), "bind(%d)", atoi(ws_port));
+               perror(buf);
                return 1;
        }
+       if ( listen(service_table[SRV_WS].conn, CON_QUEUE) ) { perror("listen()"); return 1; }
 
-       if (!cert || !key) fprintf(stderr,"%s: key or certificate file not specified - unable to watch them for changes!\n",argv[0]);
+       if (!cert || !key)
+               fprintf(stderr, "%s: key or certificate file not specified"
+                                               " - unable to watch them for changes!\n", argv[0]);
 
-       if (cadir) setenv("X509_CERT_DIR",cadir,1);
-       edg_wll_gss_watch_creds(cert,&cert_mtime);
-       if (edg_wll_gss_acquire_cred_gsi(cert, key, &mycred, &mysubj, &gss_code)) {
-          dprintf(("Running unauthenticated\n"));
-       } else {
+       if ( cadir ) setenv("X509_CERT_DIR", cadir, 1);
+       if ( !edg_wll_gss_acquire_cred_gsi(cert, key, &mycred, &mysubj, &gss_code) )
+       {
                int     i;
-               dprintf(("Server identity: %s\n",mysubj));
 
-               for (i=0; super_users && super_users[i]; i++);
-               super_users = realloc(super_users,(i+2) * sizeof *super_users);
+               dprintf(("Server identity: %s\n",mysubj));
+               for ( i = 0; super_users && super_users[i]; i++ ) ;
+               super_users = realloc(super_users, (i+2)*sizeof(*super_users));
                super_users[i] = mysubj;
                super_users[i+1] = NULL;
        }
+       else dprintf(("Running unauthenticated\n"));
 
-       if (noAuth) dprintf(("Promiscuous mode\n"));
+       if ( noAuth ) dprintf(("Promiscuous mode\n"));
        dprintf(("Listening at %d,%d (accepting protocols: " COMP_PROTO " and compatible) ...\n",atoi(port),atoi(port)+1));
+       dprintf(("Listening at %d (accepting web service protocol) ...\n", atoi(ws_port)));
 
        if (!dbstring) dbstring = getenv("LBDB");
 
        /* Just check the database and let it be. The slaves do the job. */
        edg_wll_InitContext(&ctx);
-       wait_for_open(ctx,dbstring);
+       wait_for_open(ctx, dbstring);
 
-       if (edg_wll_DBCheckVersion(ctx)) {
+       if (edg_wll_DBCheckVersion(ctx))
+       {
                char    *et,*ed;
                edg_wll_Error(ctx,&et,&ed);
 
@@ -697,7 +481,7 @@ int main(int argc,char *argv[])
        edg_wll_Close(ctx);
        edg_wll_FreeContext(ctx);
 
-       if (!debug) {
+       if ( !debug ) {
                if (daemon(1,0) == -1) {
                        perror("deamon()");
                        exit(1);
@@ -713,561 +497,576 @@ int main(int argc,char *argv[])
                setpgid(0, getpid());
        }
 
-       memset(&sa,0,sizeof(sa)); assert(sa.sa_handler == NULL);
-       sa.sa_handler = catchsig;
-       sigaction(SIGINT,&sa,NULL);
-       sigaction(SIGTERM,&sa,NULL);
-
-       sa.sa_handler = catch_chld;
-       sigaction(SIGCHLD,&sa,NULL);
 
-       sa.sa_handler = SIG_IGN;
-       sigaction(SIGUSR1,&sa,NULL);
+       glite_srvbones_set_param(GLITE_SBPARAM_SLAVES_CT, slaves);
+       glite_srvbones_set_param(GLITE_SBPARAM_SLAVE_OVERLOAD, SLAVE_OVERLOAD);
+       glite_srvbones_set_param(GLITE_SBPARAM_SLAVE_CONNS_MAX, SLAVE_CONNS_MAX);
+       to = (struct timeval){CLNT_TIMEOUT, 0};
+       glite_srvbones_set_param(GLITE_SBPARAM_CLNT_TIMEOUT, &to);
+       to = (struct timeval){TOTAL_CLNT_TIMEOUT, 0};
+       glite_srvbones_set_param(GLITE_SBPARAM_TOTAL_CLNT_TIMEOUT, &to);
 
-       sigemptyset(&sset);
-       sigaddset(&sset,SIGCHLD);
-       sigaddset(&sset,SIGTERM);
-       sigaddset(&sset,SIGINT);
-       sigprocmask(SIG_BLOCK,&sset,NULL);
+       glite_srvbones_run(bk_clnt_data_init, service_table, sizofa(service_table), debug);
 
-       for (i=0; i<slaves; i++) slave(mycred,sock_slave[1]);
 
-       while (!die) {
-               fd_set  fds;
-               int     ret,mx;
-               struct timeval  watch_to = { WATCH_TIMEOUT, 0 };
-               gss_cred_id_t   newcred = GSS_C_NO_CREDENTIAL;
-               edg_wll_GssStatus       gss_code;
-               
+       semctl(semset, 0, IPC_RMID, 0);
+       unlink(pidfile);
+       free(port);
+       gss_release_cred(&min_stat, &mycred);
 
-               FD_ZERO(&fds);
-               FD_SET(server_sock,&fds);
-               FD_SET(store_sock,&fds);
-               FD_SET(sock_slave[0],&fds);
-
-               switch (edg_wll_gss_watch_creds(cert,&cert_mtime)) {
-                       case 0: break;
-                       case 1: 
-                               ret = edg_wll_gss_acquire_cred_gsi(cert, key, &newcred, NULL, &gss_code);
-                               if (ret == 0) {
-                                       dprintf(("reloading credentials"));
-                                       gss_release_cred(&min_stat, &mycred);
-                                       mycred = newcred;
-                                       kill(0,SIGUSR1);
-                               }
-                               else {
-                                       dprintf(("reloading credentials failed"));
-                               }
 
-                               break;
-                       case -1: dprintf(("edg_wll_ssl_watch_creds failed\n"));
-                                break;
-               }
-                       
-               mx = server_sock;
-               if (mx < store_sock) mx = store_sock;
-               if (mx < sock_slave[0]) mx = sock_slave[0];
-               sigprocmask(SIG_UNBLOCK,&sset,NULL);
-               ret = select(mx+1,&fds,NULL,NULL,&watch_to);
-               sigprocmask(SIG_BLOCK,&sset,NULL);
-
-// XXX is needed?              ctx->p_tmp_timeout.tv_sec = MASTER_TIMEOUT;
-
-               if (ret == -1 && errno != EINTR) {
-                       if (debug) perror("select()");
-                       else syslog(LOG_CRIT,"select(): %m");
-                       return 1;
-               }
-
-               if (child_died) {
-                       int     pid;
-                       while ((pid=waitpid(-1,NULL,WNOHANG))>0) {
-                               if (!die) {
-                                       int newpid = slave(mycred,sock_slave[1]);
-                                       dprintf(("[master] Servus mortuus [%d] miraculo resurrexit [%d]\n",pid,newpid));
-                               }
-                       }
-                       child_died = 0;
-                       continue;
-               }
-
-               if (die) continue;
-
-               if (FD_ISSET(server_sock,&fds) && dispatchit(sock_slave[0],server_sock,0)) continue;
-               if (FD_ISSET(store_sock,&fds) && dispatchit(sock_slave[0],store_sock,1)) continue;
-               
-               if (FD_ISSET(sock_slave[0],&fds)) {
-/* slave accepted a request */
-                       unsigned long   a;
-
-                       if ((recv(sock_slave[0],&a,sizeof(a),MSG_WAITALL) == sizeof(a))
-                               && a<=clnt_dispatched
-                               && (a>clnt_accepted || clnt_accepted>clnt_dispatched)
-                       ) clnt_accepted = a;
-               }
-
-       }
-
-       dprintf(("[master] Terminating on signal %d\n",die));
-       if (!debug) syslog(LOG_INFO,"Terminating on signal %d\n",die);
-       kill(0,die);
-       semctl(semset,0,IPC_RMID,0);
-       unlink(pidfile);
-       free(port);
-       gss_release_cred(&min_stat, &mycred);
        return 0;
 }
 
-static int dispatchit(int sock_slave,int sock,int store)
-{
-       struct sockaddr_in a;
-       int     conn;
-       unsigned char *pom;
-       int     alen,ret;
-
-       alen=sizeof(a);
-       conn = accept(sock,(struct sockaddr *) &a,&alen);
-
-       if (conn<0) { 
-               if (debug) {
-                       perror("accept()"); return 1; 
-               } else {
-                       syslog(LOG_ERR,"accept(): %m");
-                       sleep(5);
-                       return -1;
-               }
-       }
-
-       alen=sizeof(a);
-       getpeername(conn,(struct sockaddr *)&a,&alen);
-       pom = (char *) &a.sin_addr.s_addr;
 
-       dprintf(("[master] %s connection from %d.%d.%d.%d:%d\n",store?"store":"query",
-               (int) pom[0],(int) pom[1],(int) pom[2],(int) pom[3], ntohs(a.sin_port)));
+int bk_clnt_data_init(void **data)
+{
+       edg_wll_Context                 ctx;
+       struct clnt_data_t         *cdata;
+       edg_wll_QueryRec          **job_index;
+       edg_wll_IColumnRec         *job_index_cols;
 
-       ret = 0;
-       if ((clnt_dispatched<clnt_accepted      /* wraparound */
-               || clnt_dispatched-clnt_accepted < slaves*SLAVE_OVERLOAD)
-               && !(ret=do_sendmsg(sock_slave,conn,clnt_dispatched++,store))) {
-                       /* all done */; 
-                       dprintf(("[master] Dispatched %lu, last known served %lu\n",clnt_dispatched-1,clnt_accepted));
-               }
-       else {
-               clnt_reject(mycred,conn);
-               dprintf(("[master] Reject due to overload\n"));
-       }
-       close(conn);
-       if (ret) {
-               perror("sendmsg()");
-               if (!debug) syslog(LOG_ERR,"sendmsg(): %m");
-       }
-       return 0;
-}
 
+       if ( !(cdata = calloc(1, sizeof(*cdata))) )
+               return -1;
 
-static int slave(void *mycred,int sock)
-{
-       edg_wll_Context ctx;
-       int     conn = -1,pid;
-       sigset_t        sset;
-       void    *mysql;
-       char    *server_name = NULL;
-       int     conn_cnt = 0;
-       int     h_errno;
-       struct sigaction        sa;
-       int     sockflags;
-       struct timeval  client_done,client_start;
-
-       if ((pid = fork())) return pid;
-
-       srandom(getpid()+time(NULL));
-
-       close(server_sock);
-       close(store_sock);
-
-       sigemptyset(&sset);
-       sigaddset(&sset,SIGTERM);
-       sigaddset(&sset,SIGINT);
-       sigaddset(&sset,SIGUSR1);
-
-       memset(&sa,0,sizeof sa);
-       sa.sa_handler = catchsig;
-       sigaction(SIGUSR1,&sa,NULL);
-
-               if ((sockflags = fcntl(sock, F_GETFL, 0)) < 0 ||
-                       fcntl(sock, F_SETFL, sockflags | O_NONBLOCK) < 0)
+       if ( edg_wll_InitContext(&ctx) ) 
        {
-               dprintf(("[%d] fcntl(master_sock): %s\n",getpid(),strerror(errno)));
-               if (!debug) syslog(LOG_CRIT,"fcntl(master_sock): %m");
-               exit(1);
+               free(cdata);
+               return -1;
        }
 
-       edg_wll_InitContext(&ctx);
-
-       dprintf(("[%d] Spawned, opening database ...\n",getpid()));
-       if (!dbstring) dbstring = getenv("LBDB");
+       dprintf(("[%d] opening database ...\n", getpid()));
+       if ( !dbstring ) dbstring = getenv("LBDB");
+       wait_for_open(ctx, dbstring);
+       cdata->mysql = ctx->mysql;
 
-       wait_for_open(ctx,dbstring);
+       if ( edg_wll_QueryJobIndices(ctx, &job_index, NULL) )
+       {
+               char       *et, *ed;
 
-       mysql = ctx->mysql;
-       if (edg_wll_QueryJobIndices(ctx,&job_index,NULL)) {
-               char    *et,*ed;
                edg_wll_Error(ctx,&et,&ed);
-
                dprintf(("[%d]: query_job_indices(): %s: %s, no custom indices available\n",getpid(),et,ed));
                if (!debug) syslog(LOG_ERR,"[%d]: query_job_indices(): %s: %s, no custom indices available\n",getpid(),et,ed);
                free(et);
                free(ed);
-               job_index = NULL;
        }
        edg_wll_FreeContext(ctx);
+       cdata->job_index = job_index;
 
-       if (job_index) {
+       if ( job_index )
+       {
                int i,j, k, maxncol, ncol;
+
                ncol = maxncol = 0;
-               for (i=0; job_index[i]; i++) {
-                       for (j=0; job_index[i][j].attr; j++) maxncol++;
-               }
+               for ( i = 0; job_index[i]; i++ )
+                       for ( j = 0; job_index[i][j].attr; j++ )
+                               maxncol++;
+
                job_index_cols = calloc(maxncol+1, sizeof(edg_wll_IColumnRec));
-               for (i=0; job_index[i]; i++) {
-                       for (j=0; job_index[i][j].attr; j++) {
-                               for (k=0; k<ncol && edg_wll_CmpColumn(&job_index_cols[k].qrec, &job_index[i][j]); k++);
-                               if (k==ncol) {
+               for ( i = 0; job_index[i]; i++ )
+               {
+                       for ( j = 0; job_index[i][j].attr; j++)
+                       {
+                               for ( k = 0;
+                                         k < ncol && edg_wll_CmpColumn(&job_index_cols[k].qrec, &job_index[i][j]);
+                                         k++);
+
+                               if ( k == ncol)
+                               {
                                        job_index_cols[ncol].qrec = job_index[i][j];
-                                       if (job_index[i][j].attr == EDG_WLL_QUERY_ATTR_USERTAG) {
+                                       if ( job_index[i][j].attr == EDG_WLL_QUERY_ATTR_USERTAG )
+                                       {
                                                job_index_cols[ncol].qrec.attr_id.tag =
-                                                       strdup(job_index[i][j].attr_id.tag);
+                                                               strdup(job_index[i][j].attr_id.tag);
                                        }
                                        job_index_cols[ncol].colname =
-                                               edg_wll_QueryRecToColumn(&job_index_cols[ncol].qrec);
+                                                       edg_wll_QueryRecToColumn(&job_index_cols[ncol].qrec);
                                        ncol++;
                                }
                        }
                }
                job_index_cols[ncol].qrec.attr = EDG_WLL_QUERY_ATTR_UNDEF;
                job_index_cols[ncol].colname = NULL;
+               cdata->job_index_cols = job_index_cols;
        }
 
-       
-       while (!die && (conn_cnt < SLAVE_CONNS_MAX || conn >= 0)) {
-               fd_set  fds;
-               int     alen,store,max = sock,newconn = -1;
-               int     connflags,kick_client = 0;
-               unsigned long   seq;
-               struct  timeval dns_to = {DNS_TIMEOUT, 0},
-                               check_to = {SLAVE_CHECK_SIGNALS, 0},
-                               total_to = { TOTAL_CLNT_TIMEOUT,0 },
-                               client_to = { CLNT_TIMEOUT,0 }, now;
-               char    *name = NULL;
-               struct  sockaddr_in     a;
-               edg_wll_GssStatus       gss_code;
-
-
-               FD_ZERO(&fds);
-               FD_SET(sock,&fds);
-               if (conn >= 0) FD_SET(conn,&fds);
-               if (conn > sock) max = conn;
-       
-               sigprocmask(SIG_UNBLOCK,&sset,NULL);
-               switch (select(max+1,&fds,NULL,NULL,&check_to)) {
-                       case -1:
-                               if (errno != EINTR) {
-                                       dprintf(("[%d] select(): %s\n",getpid(),strerror(errno)));
-                                       if (!debug) syslog(LOG_CRIT,"select(): %m");
-                                       exit(1);
-                               }
-                               continue;
-                       case 0: if (conn < 0) continue;
-                       default: break;
-               }
-               sigprocmask(SIG_BLOCK,&sset,NULL);
-
-               gettimeofday(&now,NULL);
-               if (conn >= 0 && (check_timeout(&client_to,client_done,now) ||
-                               check_timeout(&total_to,client_start,now)))
-                                       kick_client = 1;
-
-               if (conn >= 0 && !kick_client && FD_ISSET(conn,&fds)) {
-       /* serve the request */
-
-                       dprintf(("[%d] incoming request\n",getpid()));
-
-                       ctx->p_tmp_timeout.tv_sec = SLAVE_TIMEOUT;
-                       ctx->p_tmp_timeout.tv_usec = 0;
-
-                       if (total_to.tv_sec < ctx->p_tmp_timeout.tv_sec)
-                               /* XXX: sec = && usec < never happens */
-                       {
-                               ctx->p_tmp_timeout.tv_sec = total_to.tv_sec;
-                               ctx->p_tmp_timeout.tv_usec = total_to.tv_usec;
-                       }
-
-                       if (store ? edg_wll_StoreProto(ctx) : edg_wll_ServerHTTP(ctx)) { 
-                               char    *errt,*errd;
-                               errt = errd = NULL;
-
-                               switch (edg_wll_Error(ctx,&errt,&errd)) {
-                                       case ETIMEDOUT:
-                                               /* fallthrough */
-                                       case EDG_WLL_ERROR_GSS:
-                                       case EPIPE:
-                                               dprintf(("[%d] %s (%s)\n",getpid(),errt,errd));
-                                               if (!debug) syslog(LOG_ERR,"%s (%s)",errt,errd);
-                                               /* fallthrough */
-                                       case ENOTCONN:
-                                               edg_wll_gss_close(&ctx->connPool[ctx->connToUse].gss, NULL);
-                                               edg_wll_FreeContext(ctx);
-                                               ctx = NULL;
-                                               close(conn);
-                                               conn = -1;
-                                               free(errt); free(errd);
-                                               dprintf(("[%d] Connection closed\n",getpid()));
-                                               continue;
-                                               break;
-                                       case ENOENT:
-                                               /* fallthrough */
-                                       case EINVAL:
-                                               /* fallthrough */
-                                       case EPERM:
-                                       case EEXIST:
-                                       case EDG_WLL_ERROR_NOINDEX:
-                                       case E2BIG:
-                                               dprintf(("[%d] %s (%s)\n",getpid(),errt,errd));
-                                               if (!debug) syslog(LOG_ERR,"%s (%s)",errt,errd);
-                                               break; /* no action for non-fatal errors */
-                                       default:
-                                               dprintf(("[%d] %s (%s)\n",getpid(),errt,errd));
-                                               if (!debug) syslog(LOG_CRIT,"%s (%s)",errt,errd);
-                                               exit(1);
-                               } 
-                               free(errt); free(errd);
-                       }
-                       
-                       dprintf(("[%d] request done\n",getpid()));
-                       gettimeofday(&client_done,NULL);
-                       continue;
+       *data = cdata;
+       return 0;
+}
 
-               } 
+       
+/*
+ *     Creates context (initializes it from global vatiables and data given
+ *     from server_bones)
+ *     gets the connection info
+ *     and accepts the gss connection
+ */
+int bk_handle_connection(int conn, struct timeval client_start, void *data)
+{
+       struct clnt_data_t *cdata = (struct clnt_data_t *)data;
+       edg_wll_Context         ctx;
+       gss_name_t                      client_name = GSS_C_NO_NAME;
+       gss_buffer_desc         token = GSS_C_EMPTY_BUFFER;
+       edg_wll_GssStatus       gss_code;
+       OM_uint32                       min_stat,
+                                               maj_stat;
+       struct timeval          dns_to = {DNS_TIMEOUT, 0},
+                                               total_to = { TOTAL_CLNT_TIMEOUT,0 },
+                                               now;
+       struct sockaddr_in      a;
+       int                                     alen;
+       char                       *server_name = NULL,
+                                          *name = NULL;
+       int                                     h_errno;
 
 
-               if (FD_ISSET(sock,&fds) && conn_cnt < SLAVE_CONNS_MAX) {
-                       if (conn >= 0) usleep(100000 + 1000 * (random() % 200));
-                       if (do_recvmsg(sock,&newconn,&seq,&store)) switch (errno) {
-                               case EINTR: /* XXX: signals are blocked */
-                               case EAGAIN: continue;
-                               default: dprintf(("[%d] recvmsg(): %s\n",getpid(),strerror(errno)));
-                                       if (!debug) syslog(LOG_CRIT,"recvmsg(): %m\n");
-                                       exit(1);
-                       }
-                       kick_client = 1;
-               }
 
-               if (kick_client && conn >= 0) {
-                       if (ctx->connPool[ctx->connToUse].gss.context != GSS_C_NO_CONTEXT) {
-                               struct timeval  to = { 0, CLNT_REJECT_TIMEOUT };
-                               edg_wll_gss_close(&ctx->connPool[ctx->connToUse].gss,&to);
-                       }
-                       edg_wll_FreeContext(ctx);
-                       close(conn); /* XXX: should not harm */
-                       conn = -1;
-                       dprintf(("[%d] Idle connection closed\n",getpid()));
-               }
+       if ( edg_wll_InitContext(&ctx) )
+       {
+               fprintf(stderr, "Couldn't create context");
+               return -1;
+       }
+       cdata->ctx = ctx;
 
-               if (newconn >= 0) {
-                       OM_uint32       min_stat, maj_stat;
-                       gss_name_t      client_name = GSS_C_NO_NAME;
-                       gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
-
-                       conn = newconn;
-                       gettimeofday(&client_start,NULL);
-                       client_done.tv_sec = client_start.tv_sec;
-                       client_done.tv_usec = client_start.tv_usec;
-
-                       switch (send(sock,&seq,sizeof(seq),0)) {
-                               case -1:
-                                       if (debug) perror("send()");
-                                       else syslog(LOG_CRIT,"send(): %m\n");
-                                       exit(1);
-                               case sizeof(seq): break;
-                               default: dprintf(("[%d] send(): incomplete message\n",getpid()));
-                                       exit(1);
-                       }
+       /* Shared structures (pointers)
+        */
+       ctx->mysql = cdata->mysql;
+       ctx->job_index_cols = cdata->job_index_cols;
+       ctx->job_index = cdata->job_index; 
        
-                       dprintf(("[%d] serving %s %lu\n",getpid(),store?"store":"query",seq));
-                       conn_cnt++;
-       
-                       connflags = fcntl(conn, F_GETFL, 0);
-                       if (fcntl(conn, F_SETFL, connflags | O_NONBLOCK) < 0) {
-                               dprintf(("[%d] can't set O_NONBLOCK mode (%s), closing.\n",
-                                                       getpid(), strerror(errno)));
-                               if (!debug) syslog(LOG_ERR,"can't set O_NONBLOCK mode (%s), closing.\n",
-                                               strerror(errno));
-       
-                               close(conn);
-                               conn = -1;
-                               continue;
-                       }
-       
-                       edg_wll_InitContext(&ctx);
-       
-                       /* Shared structures (pointers) */
-                       ctx->mysql = mysql;
-                       ctx->job_index_cols = (void*) job_index_cols;
-                       ctx->job_index = job_index; 
-       
-                       ctx->notifDuration = notif_duration;
-                       ctx->purgeStorage = strdup(purgeStorage);
-                       ctx->dumpStorage = strdup(dumpStorage);
-                       ctx->hardJobsLimit = hardJobsLimit;
-                       ctx->hardEventsLimit = hardEventsLimit;
-                       ctx->semset = semset;
-                       ctx->semaphores = semaphores;
-                       if (noAuth) ctx->noAuth = 1;
-                       ctx->rgma_export = rgma_export;
-                       memcpy(ctx->purge_timeout,purge_timeout,sizeof ctx->purge_timeout);
-       
-                       ctx->p_tmp_timeout.tv_sec = SLAVE_TIMEOUT;
-       
-                       ctx->poolSize = 1;
-                       free(ctx->connPool);
-                       ctx->connPool = calloc(1,sizeof(edg_wll_ConnPool));
-                       ctx->connToUse = 0;
+       /*      set globals
+        */
+       ctx->notifDuration = notif_duration;
+       ctx->purgeStorage = strdup(purgeStorage);
+       ctx->dumpStorage = strdup(dumpStorage);
+       ctx->hardJobsLimit = hardJobsLimit;
+       ctx->hardEventsLimit = hardEventsLimit;
+       ctx->semset = semset;
+       ctx->semaphores = semaphores;
+       if ( noAuth ) ctx->noAuth = 1;
+       ctx->rgma_export = rgma_export;
+       memcpy(ctx->purge_timeout, purge_timeout, sizeof(ctx->purge_timeout));
+
+       ctx->p_tmp_timeout.tv_sec = SLAVE_TIMEOUT;
+       ctx->p_tmp_timeout.tv_usec = 0;
+       if ( total_to.tv_sec < ctx->p_tmp_timeout.tv_sec )
+       {
+               ctx->p_tmp_timeout.tv_sec = total_to.tv_sec;
+               ctx->p_tmp_timeout.tv_usec = total_to.tv_usec;
+       }
        
-                       alen = sizeof(a);
-                       getpeername(conn,(struct sockaddr *)&a,&alen);
-                       ctx->connPool[ctx->connToUse].peerName = strdup(inet_ntoa(a.sin_addr));
-                       ctx->connPool[ctx->connToUse].peerPort = ntohs(a.sin_port);
-
-                       /* not a critical operation, do not waste all SLAVE_TIMEOUT */
-                       switch (h_errno = asyn_gethostbyaddr(&name,(char *) &a.sin_addr.s_addr,sizeof(a.sin_addr.s_addr),
-                                               AF_INET,&dns_to)) {
-                               case NETDB_SUCCESS:
-                                       if (name) dprintf(("[%d] connection from %s:%d (%s)\n", getpid(),
-                                                               inet_ntoa(a.sin_addr), ntohs(a.sin_port), name));
-                                       free(ctx->connPool[ctx->connToUse].peerName);
-                                       ctx->connPool[ctx->connToUse].peerName = name;
-                                       name = NULL;
-                                       break;
-                               default:
-                                       if (debug) fprintf(stderr,"gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
-                                       /* else syslog(LOG_ERR,"gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno)); */
-                                       dprintf(("[%d] connection from %s:%d\n", getpid(), inet_ntoa(a.sin_addr), ntohs(a.sin_port)));
-                                       break;
-                       }
+       ctx->poolSize = 1;
+       ctx->connPool = calloc(1, sizeof(edg_wll_ConnPool));
+       ctx->connToUse = 0;
+
+       alen = sizeof(a);
+       getpeername(conn, (struct sockaddr *)&a, &alen);
+       ctx->connPool[ctx->connToUse].peerName = strdup(inet_ntoa(a.sin_addr));
+       ctx->connPool[ctx->connToUse].peerPort = ntohs(a.sin_port);
+
+       /* not a critical operation, do not waste all SLAVE_TIMEOUT */
+       h_errno = asyn_gethostbyaddr(&name, (char *)&a.sin_addr.s_addr,sizeof(a.sin_addr.s_addr), AF_INET, &dns_to);
+       switch ( h_errno )
+       {
+       case NETDB_SUCCESS:
+               if (name) dprintf(("[%d] connection from %s:%d (%s)\n",
+                                       getpid(), inet_ntoa(a.sin_addr), ntohs(a.sin_port), name));
+               free(ctx->connPool[ctx->connToUse].peerName);
+               ctx->connPool[ctx->connToUse].peerName = name;
+               name = NULL;
+               break;
+
+       default:
+               if (debug) fprintf(stderr, "gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
+               dprintf(("[%d] connection from %s:%d\n", getpid(), inet_ntoa(a.sin_addr), ntohs(a.sin_port)));
+               break;
+       }
        
-                       gettimeofday(&now,0);
-                       if ( decrement_timeout(&ctx->p_tmp_timeout, client_start, now) ) {
-                               if (debug) fprintf(stderr,"gethostbyaddr() timeout");
-                               else syslog(LOG_ERR,"gethostbyaddr(): timeout");
-                               free(name);
-                               continue;
-                       }
+       gettimeofday(&now,0);
+       if ( decrement_timeout(&ctx->p_tmp_timeout, client_start, now) )
+       {
+               if (debug) fprintf(stderr, "gethostbyaddr() timeout");
+               else syslog(LOG_ERR, "gethostbyaddr(): timeout");
+               free(name);
+
+               return -1;
+       }
                                
+       if (fake_host)
+       {
+               ctx->srvName = strdup(fake_host);
+               ctx->srvPort = fake_port;
+       }
+       else
+       {
+               alen = sizeof(a);
+               getsockname(conn,(struct sockaddr *) &a,&alen);
        
-                       if (fake_host) {
-                               ctx->srvName = strdup(fake_host);
-                               ctx->srvPort = fake_port;
-                       }
-                       else {
-                               alen = sizeof(a);
-                               getsockname(conn,(struct sockaddr *) &a,&alen);
-       
-                               dns_to.tv_sec = DNS_TIMEOUT;
-                               dns_to.tv_usec = 0;
-                               switch (h_errno = asyn_gethostbyaddr(&name,(char *) &a.sin_addr.s_addr,sizeof(a.sin_addr.s_addr),
-                                                       AF_INET,&dns_to)) {
-                                       case NETDB_SUCCESS:
-                                               ctx->srvName = name;
-                                               if (server_name != NULL) {
-                                                       if (strcmp(name, server_name)) {
-                                                               if (debug) fprintf(stderr, "different server endpoint names (%s,%s),"
+               dns_to.tv_sec = DNS_TIMEOUT;
+               dns_to.tv_usec = 0;
+               h_errno = asyn_gethostbyaddr(&name,
+                                               (char *) &a.sin_addr.s_addr,sizeof(a.sin_addr.s_addr),
+                                               AF_INET,&dns_to);
+
+               switch ( h_errno )
+               {
+               case NETDB_SUCCESS:
+                       ctx->srvName = name;
+                       if ( server_name != NULL )
+                       {
+                               if ( strcmp(name, server_name))
+                               {
+                                       if (debug) fprintf(stderr, "different server endpoint names (%s,%s),"
                                                                                        " check DNS PTR records\n", name, server_name);
-                                                               else syslog(LOG_ERR,"different server endpoint names (%s,%s),"
+                                       else syslog(LOG_ERR,"different server endpoint names (%s,%s),"
                                                                                        " check DNS PTR records\n", name, server_name);
-                                                       }
-                                               } else {
-                                                       server_name = strdup(name);
-                                               }
-                                               break;
-                                       default:
-                                               if (debug) fprintf(stderr, "gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
-                                               else syslog(LOG_ERR,"gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
-                                               if (server_name != NULL) {
-                                                        ctx->srvName = strdup(server_name);
-                                               } else {
-                                                       /* only "GET /jobid" requests refused */
-                                               }
-                                               break;
                                }
-                               ctx->srvPort = ntohs(a.sin_port);
                        }
-       
-                       if (edg_wll_gss_accept(mycred, conn, &ctx->p_tmp_timeout, &ctx->connPool[ctx->connToUse].gss, &gss_code)) {
-                               dprintf(("[%d] Client authentication failed, closing.\n",getpid()));
-                               if (!debug) syslog(LOG_ERR,"Client authentication failed");
-       
-                               close(conn);
-                               conn = -1;
-                               edg_wll_FreeContext(ctx);
-                               continue;
-                       } 
-                       maj_stat = gss_inquire_context(&min_stat, ctx->connPool[ctx->connToUse].gss.context, &client_name, NULL, NULL, NULL, NULL, NULL, NULL);
-                       if (!GSS_ERROR(maj_stat))
-                               maj_stat = gss_display_name(&min_stat, client_name, &token, NULL);
-
-                       if (!GSS_ERROR(maj_stat)) {
-                               if (ctx->peerName) free(ctx->peerName);
-                               ctx->peerName = (char *)token.value;
-                               memset(&token, 0, sizeof(token));
-/* XXX DK: pujde pouzit lifetime z inquire_context()?
-                               ctx->peerProxyValidity = ASN1_UTCTIME_mktime(X509_get_notAfter(peer));
-*/
+                       else server_name = strdup(name);
+                       break;
+
+               default:
+                       if ( debug )
+                               fprintf(stderr, "gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
+                       else
+                               syslog(LOG_ERR,"gethostbyaddr(%s): %s", inet_ntoa(a.sin_addr), hstrerror(h_errno));
+                       if ( server_name != NULL )
+                               ctx->srvName = strdup(server_name);
+                       break;
+               }
+               ctx->srvPort = ntohs(a.sin_port);
+       }
+
+       if ( edg_wll_gss_accept(mycred, conn, &ctx->p_tmp_timeout, &ctx->connPool[ctx->connToUse].gss, &gss_code) )
+       {
+               dprintf(("[%d] Client authentication failed, closing.\n", getpid()));
+               if (!debug) syslog(LOG_ERR, "Client authentication failed");
+               edg_wll_FreeContext(ctx);
+               return 1;
+       } 
+
+       maj_stat = gss_inquire_context(&min_stat, ctx->connPool[ctx->connToUse].gss.context,
+                                                       &client_name, NULL, NULL, NULL, NULL, NULL, NULL);
+       if ( !GSS_ERROR(maj_stat) )
+               maj_stat = gss_display_name(&min_stat, client_name, &token, NULL);
+
+       if ( !GSS_ERROR(maj_stat) )
+       {
+               if (ctx->peerName) free(ctx->peerName);
+               ctx->peerName = (char *)token.value;
+               memset(&token, 0, sizeof(token));
+               /* XXX DK: pujde pouzit lifetime z inquire_context()?
+                *
+               ctx->peerProxyValidity = ASN1_UTCTIME_mktime(X509_get_notAfter(peer));
+                */
   
-                               dprintf(("[%d] client DN: %s\n",getpid(),ctx->peerName));
-                       } else {
-                               /* XXX DK: Check if the ANONYMOUS flag is set ? */
-                               dprintf(("[%d] annonymous client\n",getpid()));
-                       }
+               dprintf(("[%d] client DN: %s\n",getpid(),ctx->peerName));
+       }
+       else
+               /* XXX DK: Check if the ANONYMOUS flag is set ?
+                */
+               dprintf(("[%d] annonymous client\n",getpid()));
                  
-                       if (client_name != GSS_C_NO_NAME)
-                            gss_release_name(&min_stat, &client_name);
-                       if (token.value)
-                            gss_release_buffer(&min_stat, &token);
-
-                       edg_wll_SetVomsGroups(ctx, &ctx->connPool[ctx->connToUse].gss, vomsdir, cadir);
-                       if (debug && ctx->vomsGroups.len > 0) {
-                           int i;
+       if ( client_name != GSS_C_NO_NAME )
+               gss_release_name(&min_stat, &client_name);
+       if ( token.value )
+               gss_release_buffer(&min_stat, &token);
+
+       edg_wll_SetVomsGroups(ctx, &ctx->connPool[ctx->connToUse].gss, vomsdir, cadir);
+       if (debug && ctx->vomsGroups.len > 0)
+       {
+               int i;
   
-                           dprintf(("[%d] client's VOMS groups:\n",getpid()));
-                           for (i = 0; i < ctx->vomsGroups.len; i++)
-                                dprintf(("\t%s:%s\n", 
-                                        ctx->vomsGroups.val[i].vo,
-                                        ctx->vomsGroups.val[i].name));
-                       }
-       
-                       /* used also to reset start_time after edg_wll_ssl_accept! */
-                       /* gettimeofday(&start_time,0); */
+               dprintf(("[%d] client's VOMS groups:\n",getpid()));
+               for ( i = 0; i < ctx->vomsGroups.len; i++ )
+                       dprintf(("\t%s:%s\n", ctx->vomsGroups.val[i].vo, ctx->vomsGroups.val[i].name));
+       }
        
+       /* used also to reset start_time after edg_wll_ssl_accept! */
+       /* gettimeofday(&start_time,0); */
        
-                       ctx->noAuth = noAuth || amIroot(ctx->peerName);
-                       switch (noIndex) {
-                               case 0: ctx->noIndex = 0; break;
-                               case 1: ctx->noIndex = amIroot(ctx->peerName); break;
-                               case 2: ctx->noIndex = 1; break;
-                       }
-                       ctx->strict_locking = strict_locking;
-               }
+       ctx->noAuth = noAuth || amIroot(ctx->peerName);
+       switch ( noIndex )
+       {
+       case 0: ctx->noIndex = 0; break;
+       case 1: ctx->noIndex = amIroot(ctx->peerName); break;
+       case 2: ctx->noIndex = 1; break;
        }
+       ctx->strict_locking = strict_locking;
+
+
+       return 0;
+}
 
-       if (die) {
-               dprintf(("[%d] Terminating on signal %d\n",getpid(),die));
-               if (!debug) syslog(LOG_INFO,"Terminating on signal %d",die);
+int bk_handle_ws_connection(int conn, struct timeval client_start, void *data)
+{
+    struct clnt_data_t    *cdata = (struct clnt_data_t *) data;
+       struct soap                        *soap;
+       int                                             rv;
+
+
+       if ( !(soap = soap_new()) )
+       {
+               fprintf(stderr, "Couldn't create soap environment");
+               return -1;
+       }
+
+       if ( (rv = bk_handle_connection(conn, client_start, data)) )
+       {
+               soap_destroy(soap);
+               return rv;
        }
-       dprintf(("[%d] Terminating after %d connections\n",getpid(),conn_cnt));
-       if (!debug) syslog(LOG_INFO,"Terminating after %d connections",conn_cnt);
-       exit(0);
+
+       cdata->soap = soap;
+
+       soap_init(soap);
+    soap_set_namespaces(soap, namespaces);
+    soap_register_plugin_arg(soap, edg_wll_ws_plugin, cdata->ctx);
+
+
+       return 0;
 }
 
+int bk_accept_store(int conn, void *cdata)
+{
+       edg_wll_Context         ctx = ((struct clnt_data_t *) cdata)->ctx;
+
+       /*
+        *      serve the request
+        */
+       if ( edg_wll_StoreProto(ctx) )
+       { 
+               char    *errt, *errd;
+
+               
+               errt = errd = NULL;
+               switch ( edg_wll_Error(ctx, &errt, &errd) )
+               {
+               case ETIMEDOUT:
+               case EDG_WLL_ERROR_GSS:
+               case EPIPE:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*      fallthrough
+                        */
+               case ENOTCONN:
+                       edg_wll_gss_close(&ctx->connPool[ctx->connToUse].gss, NULL);
+                       edg_wll_FreeContext(ctx);
+                       ctx = NULL;
+                       free(errt); free(errd);
+                       dprintf(("[%d] Connection closed\n", getpid()));
+                       /*
+                        *      "recoverable" error - return (>0)
+                        */
+                       return 1;
+                       break;
+
+               case ENOENT:
+               case EINVAL:
+               case EPERM:
+               case EEXIST:
+               case EDG_WLL_ERROR_NOINDEX:
+               case E2BIG:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if ( !debug ) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*
+                        *      no action for non-fatal errors
+                        */
+                       break;
+                       
+               default:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_CRIT,"%s (%s)",errt,errd);
+                       /*
+                        *      unknown error - do rather return (<0) (slave will be killed)
+                        */
+                       return -1;
+               } 
+               free(errt); free(errd);
+       }
+
+       return 0;
+}
+
+int bk_accept_serve(int conn, void *cdata)
+{
+       edg_wll_Context         ctx = ((struct clnt_data_t *) cdata)->ctx;
+
+       /*
+        *      serve the request
+        */
+       if ( edg_wll_ServerHTTP(ctx) )
+       { 
+               char    *errt, *errd;
+
+               
+               errt = errd = NULL;
+               switch ( edg_wll_Error(ctx, &errt, &errd) )
+               {
+               case ETIMEDOUT:
+               case EDG_WLL_ERROR_GSS:
+               case EPIPE:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*      fallthrough
+                        */
+               case ENOTCONN:
+                       edg_wll_gss_close(&ctx->connPool[ctx->connToUse].gss, NULL);
+                       edg_wll_FreeContext(ctx);
+                       ctx = NULL;
+                       free(errt); free(errd);
+                       dprintf(("[%d] Connection closed\n", getpid()));
+                       /*
+                        *      "recoverable" error - return (>0)
+                        */
+                       return 1;
+                       break;
+
+               case ENOENT:
+               case EINVAL:
+               case EPERM:
+               case EEXIST:
+               case EDG_WLL_ERROR_NOINDEX:
+               case E2BIG:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if ( !debug ) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*
+                        *      no action for non-fatal errors
+                        */
+                       break;
+                       
+               default:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_CRIT,"%s (%s)",errt,errd);
+                       /*
+                        *      unknown error - do rather return (<0) (slave will be killed)
+                        */
+                       return -1;
+               } 
+               free(errt); free(errd);
+       }
+
+       return 0;
+}
+
+
+int bk_accept_ws(int conn, void *cdata)
+{
+       struct soap                *soap = ((struct clnt_data_t *) cdata)->soap;
+       edg_wll_Context         ctx = ((struct clnt_data_t *) cdata)->ctx;
+
+
+       /*      XXX: Is it neccessary?
+        *
+        *      BEWARE: gSoap is trying to handle this connection -> closes the
+        *      socket after then query is served (or something like that :)
+        *
+       soap->socket = conn;
+        */
+       if ( soap_serve(soap) )
+       {
+               char    *errt, *errd;
+
+               
+               errt = errd = NULL;
+               switch ( edg_wll_Error(ctx, &errt, &errd) )
+               {
+               case ETIMEDOUT:
+               case EDG_WLL_ERROR_GSS:
+               case EPIPE:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*      fallthrough
+                        */
+               case ENOTCONN:
+                       edg_wll_gss_close(&ctx->connPool[ctx->connToUse].gss, NULL);
+                       edg_wll_FreeContext(ctx);
+                       ctx = NULL;
+                       free(errt); free(errd);
+                       dprintf(("[%d] Connection closed\n", getpid()));
+                       /*
+                        *      "recoverable" error - return (>0)
+                        */
+                       return 1;
+                       break;
+
+               case ENOENT:
+               case EINVAL:
+               case EPERM:
+               case EEXIST:
+               case EDG_WLL_ERROR_NOINDEX:
+               case E2BIG:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if ( !debug ) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*
+                        *      no action for non-fatal errors
+                        */
+                       break;
+                       
+               default:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_CRIT,"%s (%s)",errt,errd);
+                       /*
+                        *      unknown error - do rather return (<0) (slave will be killed)
+                        */
+                       return -1;
+               } 
+               free(errt); free(errd);
+               return 1;
+       }
+
+       return 0;
+}
+
+
+int bk_clnt_disconnect(int conn, void *cdata)
+{
+       edg_wll_Context         ctx = ((struct clnt_data_t *) cdata)->ctx;
+
+
+       if ( ctx->connPool[ctx->connToUse].gss.context != GSS_C_NO_CONTEXT)
+       {
+               struct timeval  to = { 0, CLNT_REJECT_TIMEOUT };
+
+               edg_wll_gss_close(&ctx->connPool[ctx->connToUse].gss, &to);
+       }
+       edg_wll_FreeContext(ctx);
+
+       return 0;
+}
+
+int bk_ws_clnt_disconnect(int conn, void *cdata)
+{
+       int             rv;
+
+
+       if ( (rv = bk_clnt_disconnect(conn, cdata)) )
+               return rv;
+
+       soap_destroy(((struct clnt_data_t *)cdata)->soap);
+
+       return 0;
+}
+
+int bk_clnt_reject(int conn)
+{
+       int             flags = fcntl(conn, F_GETFL, 0);
+
+       if ( fcntl(conn, F_SETFL, flags | O_NONBLOCK) < 0 ) 
+               return 1;
+
+       edg_wll_gss_reject(conn);
+
+       return 0;
+}
+
+int bk_ws_clnt_reject(int conn)
+{
+       return bk_clnt_reject(conn);
+}
+
+
 static void wait_for_open(edg_wll_Context ctx, const char *dbstring)
 {
        char    *dbfail_string1, *dbfail_string2;
@@ -1300,23 +1099,188 @@ static void wait_for_open(edg_wll_Context ctx, const char *dbstring)
        }
 }
 
+static void free_hostent(struct hostent *h){
+       int i;
+
+       if (h) {
+               if (h->h_name) free(h->h_name);
+               if (h->h_aliases) {
+                       for (i=0; h->h_aliases[i]; i++) free(h->h_aliases[i]);
+                       free(h->h_aliases);
+               }
+               if (h->h_addr_list) {
+                       for (i=0; h->h_addr_list[i]; i++) free(h->h_addr_list[i]);
+                       free(h->h_addr_list);
+               }
+               free(h);
+       }
+}
+
+struct asyn_result {
+       struct hostent *ent;
+       int             err;
+};
+
+/* ares callback handler for ares_gethostbyaddr()       */
+static void callback_handler(void *arg, int status, struct hostent *h)
+{
+       struct asyn_result *arp = (struct asyn_result *) arg;
+
+       switch (status) {
+          case ARES_SUCCESS:
+               if (h && h->h_name) {
+                       arp->ent->h_name = strdup(h->h_name);           
+                       if (arp->ent->h_name == NULL) {
+                               arp->err = NETDB_INTERNAL;
+                       } else {
+                               arp->err = NETDB_SUCCESS;
+                       }
+               } else {
+                       arp->err = NO_DATA;
+               }
+               break;
+           case ARES_EBADNAME:
+           case ARES_ENOTFOUND:
+               arp->err = HOST_NOT_FOUND;
+               break;
+           case ARES_ENOTIMP:
+               arp->err = NO_RECOVERY;
+               break;
+           case ARES_ENOMEM:
+           case ARES_EDESTRUCTION:
+           default:
+               arp->err = NETDB_INTERNAL;
+               break;
+       }
+}
+
+static int asyn_gethostbyaddr(char **name, const char *addr,int len, int type, struct timeval *timeout)
+{
+       struct asyn_result ar;
+       ares_channel channel;
+       int nfds;
+       fd_set readers, writers;
+       struct timeval tv, *tvp;
+       struct timeval start_time,check_time;
+
+
+/* start timer */
+        gettimeofday(&start_time,0);
+
+/* ares init */
+        if ( ares_init(&channel) != ARES_SUCCESS ) return(NETDB_INTERNAL);
+       ar.ent = (struct hostent *) malloc (sizeof(*ar.ent));
+       memset((void *) ar.ent, 0, sizeof(*ar.ent));
+
+/* query DNS server asynchronously */
+       ares_gethostbyaddr(channel, addr, len, type, callback_handler, (void *) &ar);
+
+/* wait for result */
+        while (1) {
+                FD_ZERO(&readers);
+                FD_ZERO(&writers);
+                nfds = ares_fds(channel, &readers, &writers);
+                if (nfds == 0)
+                        break;
+
+                gettimeofday(&check_time,0);
+               if (decrement_timeout(timeout, start_time, check_time)) {
+                       ares_destroy(channel);
+                       free_hostent(ar.ent);
+                       return(TRY_AGAIN);
+               }
+               start_time = check_time;
+
+                tvp = ares_timeout(channel, timeout, &tv);
+
+                switch ( select(nfds, &readers, &writers, NULL, tvp) ) {
+                       case -1: if (errno != EINTR) {
+                                       ares_destroy(channel);
+                                       free_hostent(ar.ent);
+                                       return NETDB_INTERNAL;
+                                } else
+                                       continue;
+                       case 0: 
+                               FD_ZERO(&readers);
+                               FD_ZERO(&writers);
+                               /* fallthrough */
+                        default : ares_process(channel, &readers, &writers);
+                }
+
+        }
+
+       
+       ares_destroy(channel);
+               
+       if (ar.err == NETDB_SUCCESS) {
+               *name = strdup(ar.ent->h_name); 
+               free_hostent(ar.ent); 
+       }
+       return (ar.err);
+}
+
+static int read_roots(const char *file)
+{
+       FILE    *roots = fopen(file,"r");
+       char    buf[BUFSIZ];
+       int     cnt = 0;
+
+       if (!roots) {
+               perror(file);
+               return 1;
+       }
+
+       while (!feof(roots)) {
+               char    *nl;
+               fgets(buf,sizeof buf,roots);
+               nl = strchr(buf,'\n');
+               if (nl) *nl = 0;
+
+               super_users = realloc(super_users, (cnt+1) * sizeof super_users[0]);
+               super_users[cnt] = strdup(buf);
+               super_users[++cnt] = NULL;
+       }
+
+       fclose(roots);
+
+       return 0;
+}
+
+static int amIroot(const char *subj)
+{
+       int     i;
+
+       if (!subj) return 0;
+       for (i=0; super_users && super_users[i]; i++) 
+               if (strcmp(subj,super_users[i]) == 0) return 1;
+
+       return 0;
+}
+
+static int parse_limits(char *opt, int *j_limit, int *e_limit, int *size_limit)
+{
+       return (sscanf(opt, "%d:%d:%d", j_limit, e_limit, size_limit) == 3);
+}
+
 static int check_mkdir(const char *dir)
 {
        struct stat     sbuf;
        
-       if (stat(dir,&sbuf)) {
-               if (errno == ENOENT) {
-                       if (mkdir(dir, S_IRWXU)) {
-                               dprintf(("[%d] %s: %s\n",
-                                       getpid(),dir,strerror(errno)));
-
-                               if (!debug) syslog(LOG_CRIT,"%s: %m",dir);
+       if ( stat(dir, &sbuf) )
+       {
+               if ( errno == ENOENT )
+               {
+                       if ( mkdir(dir, S_IRWXU) )
+                       {
+                               dprintf(("[%d] %s: %s\n", getpid(), dir, strerror(errno)));
+                               if (!debug) syslog(LOG_CRIT, "%s: %m", dir);
                                return 1;
                        }
                }
-               else {
-                       dprintf(("[%d] %s: %s\n",getpid(),strerror(errno)));
-                       if (!debug) syslog(LOG_CRIT,"%s: %m",dir);
+               else
+               {
+                       dprintf(("[%d] %s: %s\n", getpid(), dir, strerror(errno)));
+                       if (!debug) syslog(LOG_CRIT, "%s: %m", dir);
                        return 1;
                }
        }
@@ -1326,4 +1290,19 @@ static int check_mkdir(const char *dir)
                if (!debug) syslog(LOG_CRIT,"%s: not a directory",dir);
                return 1;
        }
+
+       return 0;
 }
+
+static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after)
+{
+        (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec);
+        (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec);
+        while ( (*timeout).tv_usec < 0) {
+                (*timeout).tv_sec--;
+                (*timeout).tv_usec += 1000000;
+        }
+        if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1);
+        else return(0);
+}
+
index 0744d13..88a699a 100644 (file)
@@ -3,8 +3,6 @@
  *   - implementation of IL API calls for notifications
  *
  */
-#ident "$Header$"
-
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/socket.h>
index f76a829..52487c4 100644 (file)
@@ -1,8 +1,6 @@
 #ifndef IL_NOTIFICATION_H
 #define IL_NOTIFICATION_H
 
-#ident "$Header$"
-
 /* needed for the edg_wll_NotifId */
 #include "glite/lb/notification.h"
 /* import the edg_wll_JobStat structure */
diff --git a/org.glite.lb.server/src/ws_fault.c b/org.glite.lb.server/src/ws_fault.c
new file mode 100644 (file)
index 0000000..6f7bbc0
--- /dev/null
@@ -0,0 +1,56 @@
+#include <string.h>
+
+#include "glite/lb/context-int.h"
+
+#include "bk_ws_H.h"
+#include "bk_ws_Stub.h"
+
+
+void edg_wll_ErrToFault(const edg_wll_Context ctx,struct soap *soap)
+{
+       char    *et,*ed;
+       struct SOAP_ENV__Detail *detail = soap_malloc(soap,sizeof *detail);
+       struct _GenericLBFault *f = soap_malloc(soap,sizeof *f);
+
+
+       f->edgwll__GenericLBFault = soap_malloc(soap,sizeof *f->edgwll__GenericLBFault);
+
+       f->edgwll__GenericLBFault->code = edg_wll_Error(ctx,&et,&ed);
+       f->edgwll__GenericLBFault->text = soap_malloc(soap,strlen(et)+1);
+       strcpy(f->edgwll__GenericLBFault->text,et); 
+       free(et);
+       f->edgwll__GenericLBFault->description = soap_malloc(soap,strlen(ed)+1);
+       strcpy(f->edgwll__GenericLBFault->description,ed); 
+       free(ed);
+
+       detail->__type = SOAP_TYPE__GenericLBFault;
+       detail->value = f;
+       detail->__any = NULL;
+
+       soap_receiver_fault(soap,"shit",NULL);
+       if (soap->version == 2) soap->fault->SOAP_ENV__Detail = detail;
+       else soap->fault->detail = detail;
+}
+
+
+void edg_wll_FaultToErr(const struct soap *soap,edg_wll_Context ctx)
+{
+       struct SOAP_ENV__Detail *detail = soap->version == 2 ?
+               soap->fault->SOAP_ENV__Detail : soap->fault->detail;
+
+       struct edgwll__GenericLBFaultType       *f;
+
+       if (detail->__type == SOAP_TYPE__GenericLBFault) {
+                       f = ((struct _GenericLBFault *) detail->value)
+                       ->edgwll__GenericLBFault;
+               edg_wll_SetError(ctx,f->code,f->description);
+       }
+       else {
+               char    *s;
+
+               asprintf(&s,"SOAP: %s", soap->version == 2 ?
+                       soap->fault->SOAP_ENV__Reason : soap->fault->faultstring);
+               edg_wll_SetError(ctx,EINVAL,s);
+               free(s);
+       }
+}
diff --git a/org.glite.lb.server/src/ws_fault.h b/org.glite.lb.server/src/ws_fault.h
new file mode 100644 (file)
index 0000000..70870cd
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef __EDG_WORKLOAD_LOGGING_LBSERVER_WS_FAULT_H__
+#define __EDG_WORKLOAD_LOGGING_LBSERVER_WS_FAULT_H__
+
+extern void edg_wll_ErrToFault(const edg_wll_Context, struct soap *);
+extern void edg_wll_FaultToErr(const struct soap *, edg_wll_Context);
+
+#endif /* __EDG_WORKLOAD_LOGGING_LBSERVER_WS_FAULT_H__ */
diff --git a/org.glite.lb.server/src/ws_plugin.c b/org.glite.lb.server/src/ws_plugin.c
new file mode 100644 (file)
index 0000000..6a3df26
--- /dev/null
@@ -0,0 +1,191 @@
+#include <stdio.h>
+#include <assert.h>
+#include <signal.h>
+#include <stdsoap2.h>
+
+#include "glite/lb/lb_gss.h"
+#include "glite/lb/context-int.h"
+
+#ifdef PLUGIN_TEST
+extern int edg_wll_open(edg_wll_Context);
+#endif
+
+#include "ws_plugin.h"
+
+#include "LoggingAndBookkeeping.nsmap"
+
+#ifdef WS_PLUGIN_DEBUG
+#  define pdprintf(s)  printf s
+#else
+#  define pdprintf(s)
+#endif
+
+static const char plugin_id[] = PLUGIN_ID;
+
+#ifdef PLUGIN_TEST
+static int edg_wll_ws_connect(struct soap *, const char *, const char *, int);
+#endif
+static void edg_wll_ws_delete(struct soap *, struct soap_plugin *);
+static size_t edg_wll_ws_recv(struct soap *, char *, size_t);
+static int edg_wll_ws_send(struct soap *, const char *, size_t);
+
+
+int edg_wll_ws_plugin(struct soap *soap, struct soap_plugin *p, void *arg)
+{
+       /*      The parametr (edg_wll_Context) must be given!  */
+       assert(arg != NULL);
+
+       p->id                   = plugin_id;
+       p->data                 = arg;
+       p->fdelete              = edg_wll_ws_delete;
+
+#ifdef PLUGIN_TEST
+       soap->fconnect  = edg_wll_ws_connect;
+#endif
+       soap->fsend             = edg_wll_ws_send;
+       soap->frecv             = edg_wll_ws_recv;
+
+       return SOAP_OK;
+}
+
+#ifdef PLUGIN_TEST
+int edg_wll_ws_connect(struct soap *soap, const char *endpoint,
+       const char *host, int port)
+{
+       edg_wll_Context         ctx = (edg_wll_Context)soap_lookup_plugin(soap, plugin_id);
+
+
+       ctx->srvName = strdup(host);
+       ctx->srvPort = port;
+       ctx->p_tmp_timeout = ctx->p_query_timeout;
+       if ( edg_wll_open(ctx) )
+               return edg_wll_Error(ctx, NULL, NULL);
+
+       soap->socket = 2;
+
+       return SOAP_OK;
+}
+#endif
+
+static void edg_wll_ws_delete(struct soap *soap, struct soap_plugin *p)
+{
+       /*
+        *      Keep silly gSOAP happy
+        */
+}
+
+
+size_t edg_wll_ws_recv(struct soap *soap, char *buf, size_t bufsz)
+{
+       edg_wll_Context         ctx = (edg_wll_Context)soap_lookup_plugin(soap, plugin_id);
+       edg_wll_GssStatus       gss_code;
+       int                                     len;
+
+
+       edg_wll_ResetError(ctx);
+       if ( ctx->connPool[ctx->connToUse].gss.context == GSS_C_NO_CONTEXT )
+       {
+               edg_wll_SetError(ctx, ENOTCONN, NULL);
+               soap->errnum = ENOTCONN;
+               return 0;
+       }
+       
+       len = edg_wll_gss_read(&ctx->connPool[ctx->connToUse].gss,
+                                       buf, bufsz, &ctx->p_tmp_timeout, &gss_code);
+
+       switch ( len )
+       {
+       case EDG_WLL_GSS_OK:
+               break;
+
+       case EDG_WLL_GSS_ERROR_GSS:
+               edg_wll_SetErrorGss(ctx, "receving WS request", &gss_code);
+               soap->errnum = ENOTCONN;
+               return 0;
+
+       case EDG_WLL_GSS_ERROR_ERRNO:
+               edg_wll_SetError(ctx, errno, "edg_wll_gss_read()");
+               soap->errnum = errno;
+               return 0;
+
+       case EDG_WLL_GSS_ERROR_TIMEOUT:
+               edg_wll_SetError(ctx, ETIMEDOUT, NULL);
+               soap->errnum = ETIMEDOUT;
+               return 0;
+
+       case EDG_WLL_GSS_ERROR_EOF:
+               edg_wll_SetError(ctx, ENOTCONN, NULL);
+               soap->errnum = ENOTCONN;
+               return 0;
+
+               /* default: fallthrough */
+       }
+
+       pdprintf(("\nWS received:\n%s\n\n", buf));
+       return len;
+}
+
+static int edg_wll_ws_send(struct soap *soap, const char *buf, size_t bufsz)
+{
+       edg_wll_Context         ctx = (edg_wll_Context) soap_lookup_plugin(soap, plugin_id);
+       edg_wll_GssStatus       gss_code;
+       struct sigaction        sa, osa;
+       int                                     total = 0,
+                                               ret;
+
+
+       edg_wll_ResetError(ctx);
+
+       if ( ctx->connPool[ctx->connToUse].gss.context == GSS_C_NO_CONTEXT )
+       {
+               edg_wll_SetError(ctx, ENOTCONN, NULL);
+               soap->errnum = ENOTCONN;
+               return SOAP_EOF;
+       }
+
+       memset(&sa, 0, sizeof(sa));
+       assert(sa.sa_handler == NULL);
+       sa.sa_handler = SIG_IGN;
+       sigaction(SIGPIPE, &sa, &osa);
+
+       ret = edg_wll_gss_write_full(&ctx->connPool[ctx->connToUse].gss,
+                               (void*)buf, bufsz,
+                               &ctx->p_tmp_timeout,
+                               &total, &gss_code);
+
+       sigaction(SIGPIPE, &osa, NULL);
+
+       switch ( ret )
+       {
+       case EDG_WLL_GSS_OK:
+               pdprintf(("\nWS sent:\n%s\n\n", buf));
+               break;
+
+       case EDG_WLL_GSS_ERROR_TIMEOUT:
+               edg_wll_SetError(ctx, ETIMEDOUT, "edg_wll_ws_send()");
+               soap->errnum = ETIMEDOUT;
+               return SOAP_EOF;
+
+       case EDG_WLL_GSS_ERROR_ERRNO:
+               if ( errno == EPIPE )
+               {
+                       edg_wll_SetError(ctx, ENOTCONN, "edg_wll_ws_send()");
+                       soap->errnum = ENOTCONN;
+               }
+               else
+               {
+                       edg_wll_SetError(ctx, errno, "edg_wll_ws_send()");
+                       soap->errnum = errno;
+               }
+               return SOAP_EOF;
+
+       case EDG_WLL_GSS_ERROR_GSS:
+       case EDG_WLL_GSS_ERROR_EOF:
+       default:
+               edg_wll_SetError(ctx, ENOTCONN, "edg_wll_ws_send()");
+               soap->errnum = ENOTCONN;
+               return SOAP_EOF;
+       }
+
+       return SOAP_OK;
+}
diff --git a/org.glite.lb.server/src/ws_plugin.h b/org.glite.lb.server/src/ws_plugin.h
new file mode 100644 (file)
index 0000000..9b691be
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __EDG_WORKLOAD_LOGGING_LBSERVER_WS_PLUGIN_H__
+#define __EDG_WORKLOAD_LOGGING_LBSERVER_WS_PLUGIN_H__
+
+#define PLUGIN_ID              "GLITE_WS_PLUGIN"
+
+int edg_wll_ws_plugin(struct soap *, struct soap_plugin *, void *);
+
+#endif /* __EDG_WORKLOAD_LOGGING_LBSERVER_WS_PLUGIN_H__ */
diff --git a/org.glite.lb.server/src/ws_query.c b/org.glite.lb.server/src/ws_query.c
new file mode 100644 (file)
index 0000000..60dd118
--- /dev/null
@@ -0,0 +1,107 @@
+#include <stdsoap2.h>
+
+#include "glite/lb/context-int.h"
+#include "glite/lb/consumer.h"
+
+#include "jobstat.h"
+#include "query.h"
+#include "ws_plugin.h"
+#include "bk_ws_H.h"
+#include "get_events.h"
+#include "ws_fault.h"
+#include "ws_typeref.h"
+
+
+int edgwll2__JobStatus(
+        struct soap                                               *soap,
+        char                                                      *jobid,
+        struct edgwll__JobStatFlags               *flags,
+        struct edgwll2__JobStatusResponse  *out)
+{
+       edg_wll_Context         ctx = (edg_wll_Context) soap_lookup_plugin(soap, PLUGIN_ID);
+       edg_wlc_JobId           j;
+       edg_wll_JobStat         s;
+
+
+       if ( edg_wlc_JobIdParse(jobid, &j) )
+       {
+               edg_wll_SetError(ctx, EINVAL, jobid);
+               edg_wll_ErrToFault(ctx, soap);
+               return SOAP_FAULT;
+       }
+
+       if ( edg_wll_JobStatus(ctx, j, 0, &s) )
+       {
+               edg_wll_ErrToFault(ctx, soap);
+               return SOAP_FAULT;
+       }
+
+       edg_wll_StatusToSoap(soap, &s, &(out->status));
+
+       return SOAP_OK;
+}
+
+int edgwll2__QueryJobs(
+       struct soap                                                *soap,
+       struct edgwll__QueryConditions     *conditions,
+       struct edgwll__JobStatFlags                *flags,
+       struct edgwll2__QueryJobsResponse  *out)
+{
+       edg_wll_Context         ctx = (edg_wll_Context) soap_lookup_plugin(soap, PLUGIN_ID);
+       edg_wlc_JobId      *jobsOut = NULL;
+       edg_wll_JobStat    *statesOut = NULL;
+       edg_wll_QueryRec  **qr = NULL;
+       int                                     fl,
+                                               i, j,
+                                               ret = SOAP_FAULT;
+
+
+       out->states = soap_malloc(soap, sizeof(*out->states));
+       out->jobs = soap_malloc(soap, sizeof(*out->jobs));
+       if ( !out->states || !out->jobs ) goto cleanup;
+       memset(out->states, 0, sizeof(*(out->states)));
+       memset(out->jobs, 0, sizeof(*(out->jobs)));
+
+       edg_wll_ResetError(ctx);
+       edg_wll_SoapToJobStatFlags(flags, &fl);
+       if ( edg_wll_SoapToQueryCondsExt(conditions, &qr) ) {
+               edg_wll_SetError(ctx, ENOMEM, "Couldn't create internal structures");
+               goto cleanup;
+       }
+       if ( edg_wll_QueryJobsServer(ctx, qr, fl, &jobsOut, &statesOut) ) goto cleanup;
+       if ( edg_wll_JobsQueryResToSoap(soap, jobsOut, statesOut, out) ) goto cleanup;
+       ret = SOAP_OK;
+
+cleanup:
+       if ( qr ) {
+               for ( i = 0; qr[i]; i++ ) {
+                       for ( j = 0; qr[i][j].attr; j++ )
+                               edg_wll_QueryRecFree(&qr[i][j]);
+                       free(qr[i]);
+               }
+               free(qr);
+       }
+       if ( jobsOut ) {
+               for ( i = 0; jobsOut[i]; i++ )
+                       edg_wlc_JobIdFree(jobsOut[i]);
+               free(jobsOut);
+       }
+       if ( statesOut ) {
+               for ( i = 0; statesOut[i].state; i++ )
+                       edg_wll_FreeStatus(&statesOut[i]);
+               free(statesOut);
+       }
+       if ( ret == SOAP_FAULT ) edg_wll_ErrToFault(ctx, soap);
+
+       return ret;
+}
+
+int edgwll2__UserJobs(
+       struct soap                                                *soap,
+       struct edgwll2__UserJobsResponse   *out)
+{
+       out->jobs = NULL;
+       out->states = NULL;
+
+       return SOAP_OK;
+}
diff --git a/org.glite.lb.server/src/ws_typemap.dat b/org.glite.lb.server/src/ws_typemap.dat
new file mode 100644 (file)
index 0000000..c79474a
--- /dev/null
@@ -0,0 +1,2 @@
+edgwll = http://glite.org/wsdl/types/lb
+edgwll = http://glite.org/wsdl/services/lb
diff --git a/org.glite.lb.server/src/ws_typeref.c.T b/org.glite.lb.server/src/ws_typeref.c.T
new file mode 100644 (file)
index 0000000..fd862f4
--- /dev/null
@@ -0,0 +1,521 @@
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdsoap2.h>
+
+#include "bk_ws_H.h"
+
+#include "glite/lb/consumer.h"
+/* XXX: references only, src and dest share pointers */
+
+void edg_wll_JobStatCodeToSoap(edg_wll_JobStatCode in, enum edgwll__JobStatCode *out)
+{
+       switch ( in )
+       {
+       case EDG_WLL_JOB_UNDEF: *out = UNDEF; break;
+@@@{
+       for my $stat ($status->getTypesOrdered) {
+               my $u = uc $stat;
+               my $c = getTypeComment $status $stat;
+               gen qq{
+!      case EDG_WLL_JOB_$u: *out = $u; break; /**< $c */
+};
+       }
+@@@}
+       }
+}
+
+void edg_wll_SoapToJobStatCode(enum edgwll__JobStatCode in, edg_wll_JobStatCode *out)
+{
+       switch ( in )
+       {
+       case UNDEF: *out = EDG_WLL_JOB_UNDEF; break;
+@@@{
+       for my $stat ($status->getTypesOrdered) {
+               my $u = uc $stat;
+               my $c = getTypeComment $status $stat;
+               gen qq{
+!      case $u: *out = EDG_WLL_JOB_$u; break; /**< $c */
+};
+       }
+@@@}
+       }
+}
+
+int edg_wll_StatusToSoap(struct soap *soap,edg_wll_JobStat const *src,struct edgwll__JobStat **dest)
+{
+       int     i;
+       struct edgwll__JobStat *js;
+
+       if ( !(js = soap_malloc(soap, sizeof(*js))) ) return SOAP_FAULT;
+       memset(js, 0, sizeof(*js));
+       edg_wll_JobStatCodeToSoap(src->state, &(js->state));
+@@@{
+       selectType $status '_common_';
+       for (getFieldsOrdered $status) {
+               my $f = selectField $status $_;
+               my $ft = $f->{type};
+               my $usuc = $_;
+               $usuc = $1.uc($2).$3 while ($usuc =~ /([^_]*)_([a-z])(.*)/);
+               if ($ft eq 'jobid') {
+                       gen "\tjs->$usuc = edg_wlc_JobIdUnparse(src->$_);\n";
+               }
+               elsif ($ft eq 'strlist') {
+                       gen "\tfor (i=0; src->$_ && src->$_\[i]; i++);\n";
+                       gen "\tjs->__size$usuc = i;\n";
+                       gen "\tjs->$usuc = src->$_;\n";
+               } elsif ($ft eq 'intlist') {
+                       gen "\tjs->__size$usuc = src->$_ ? src->$_\[0] : 0;\n";
+                       gen "\tjs->$usuc = src->$_ ? src->$_ + 1 : NULL;\n";
+               } elsif ($ft eq 'stslist' || $ft eq 'taglist') {
+# FIXME
+                       gen "\tjs->__size$usuc = 0;\n";
+                       gen "\tjs->$usuc = NULL;\n";
+               } elsif ($ft eq 'timeval') {
+                       gen "\tjs->$usuc = soap_malloc(soap,sizeof *js->$usuc);\n";
+                       gen "\tjs->$usuc->tvSec = src->$_.tv_sec;\n";
+                       gen "\tjs->$usuc->tvUsec = src->$_.tv_usec;\n";
+               }
+               else { gen "\tjs->$usuc = src->$_;\n"; }
+       }
+@@@}
+
+       *dest = js;
+       return SOAP_OK;
+}
+
+void edg_wll_SoapToStatus(struct soap *soap,struct edgwll__JobStat const *src,edg_wll_JobStat *dest)
+{
+       memset(dest,0,sizeof *dest);
+       edg_wll_SoapToJobStatCode(src->state, &(dest->state));
+
+@@@{
+       selectType $status '_common_';
+       for (getFieldsOrdered $status) {
+               my $f = selectField $status $_;
+               my $ft = $f->{type};
+               my $usuc = $_;
+               $usuc = $1.uc($2).$3 while ($usuc =~ /([^_]*)_([a-z])(.*)/);
+
+               if ($ft eq 'jobid') {
+                       gen "\tif (src->$usuc) edg_wlc_JobIdParse(src->$usuc,&dest->$_);\n";
+               } elsif ($ft eq 'strlist') {
+                       gen "\tsoap_unlink(soap,src->$usuc);\n";
+                       gen "\tdest->$_ = realloc(src->$usuc,sizeof(*dest->$_) * (src->__size$usuc + 1));\n";
+                       gen "\tdest->$_\[src->__size$usuc] = NULL;\n";
+               } elsif ($ft eq 'intlist') {
+                       gen "\tsoap_unlink(soap,src->$usuc);\n";
+                       gen "\tdest->$_ = realloc(src->$usuc,sizeof(*dest->$_) * (src->__size$usuc + 1));\n";
+                       gen "\tmemmove(dest->$_ + 1,dest->$_,sizeof(*dest->$_) * (src->__size$usuc));\n";
+                       gen "\tdest->$_\[0] = src->__size$usuc;\n";
+               } elsif ($ft eq 'stslist' || $ft eq 'taglist') {
+# FIXME
+                       gen "\tdest->$_ = NULL;\n";
+               } elsif ($ft eq 'timeval') {
+                       gen "\tdest->$_.tv_sec = src->$usuc->tvSec;\n";
+                       gen "\tdest->$_.tv_usec = src->$usuc->tvUsec;\n";
+               } elsif ($ft eq 'string') {
+                       gen "\tdest->$_ = src->$usuc;\n";
+                       gen "\tsoap_unlink(soap,src->$usuc);\n";
+               } else {
+                       gen "\tdest->$_ = src->$usuc;\n";
+}
+}
+@@@}
+}
+
+void edg_wll_SoapToJobStatFlags(const struct edgwll__JobStatFlags *in, int *out)
+{
+       int             i;
+
+       assert(in); assert(out);
+       *out = 0;
+       for ( i = 0; i < in->__sizeflag; i++ ) switch ( in->flag[i] )
+       {
+       case CLASSADS: *out |= EDG_WLL_STAT_CLASSADS; break;
+       case CHILDREN: *out |= EDG_WLL_STAT_CHILDREN; break;
+       case CHILDSTAT: *out |= EDG_WLL_STAT_CHILDSTAT; break;
+       }
+}
+
+int edg_wll_JobStatFlagsToSoap(struct soap *soap, const int in, struct edgwll__JobStatFlags *out)
+{
+       int             i = 0;
+
+       assert(out);
+       memset(out, 0, sizeof(*out));
+       if ( in & EDG_WLL_STAT_CLASSADS ) out->__sizeflag++;
+       if ( in & EDG_WLL_STAT_CHILDREN ) out->__sizeflag++;
+       if ( in & EDG_WLL_STAT_CHILDSTAT ) out->__sizeflag++;
+       if ( !out->__sizeflag ) return SOAP_OK;
+       out->flag = soap_malloc(soap, sizeof(*(out->flag))*out->__sizeflag);
+       if ( !out->flag ) return SOAP_FAULT;
+
+       if ( in & EDG_WLL_STAT_CLASSADS ) out->flag[i++] = CLASSADS;
+       if ( in & EDG_WLL_STAT_CHILDREN ) out->flag[i++] = CHILDREN;
+       if ( in & EDG_WLL_STAT_CHILDSTAT ) out->flag[i++] = CHILDSTAT;
+
+       return SOAP_OK;
+}
+
+void edg_wll_SoapToAttr(const enum edgwll__QueryAttr in, edg_wll_QueryAttr *out)
+{
+       switch ( in )
+       {
+       case UNDEF: *out = EDG_WLL_QUERY_ATTR_UNDEF; break;
+       case JOBID: *out = EDG_WLL_QUERY_ATTR_JOBID; break;
+       case OWNER: *out = EDG_WLL_QUERY_ATTR_OWNER; break;
+       case STATUS: *out = EDG_WLL_QUERY_ATTR_STATUS; break;
+       case LOCATION: *out = EDG_WLL_QUERY_ATTR_LOCATION; break;
+       case DESTINATION: *out = EDG_WLL_QUERY_ATTR_DESTINATION; break;
+       case DONECODE: *out = EDG_WLL_QUERY_ATTR_DONECODE; break;
+       case USERTAG: *out = EDG_WLL_QUERY_ATTR_USERTAG; break;
+       case TIME: *out = EDG_WLL_QUERY_ATTR_TIME; break;
+       case LEVEL: *out = EDG_WLL_QUERY_ATTR_LEVEL; break;
+       case HOST: *out = EDG_WLL_QUERY_ATTR_HOST; break;
+       case SOURCE: *out = EDG_WLL_QUERY_ATTR_SOURCE; break;
+       case INSTANCE: *out = EDG_WLL_QUERY_ATTR_INSTANCE; break;
+       case EVENT_TYPE: *out = EDG_WLL_QUERY_ATTR_EVENT_TYPE; break;
+       case CHKPT_TAG: *out = EDG_WLL_QUERY_ATTR_CHKPT_TAG; break;
+       case RESUBMITTED: *out = EDG_WLL_QUERY_ATTR_RESUBMITTED; break;
+       case PARENT: *out = EDG_WLL_QUERY_ATTR_PARENT; break;
+       case EXITCODE: *out = EDG_WLL_QUERY_ATTR_EXITCODE; break;
+       default: *out = in; break;
+       }
+}
+
+void edg_wll_AttrToSoap(const edg_wll_QueryAttr in, enum edgwll__QueryAttr *out)
+{
+       switch ( in )
+       {
+       case EDG_WLL_QUERY_ATTR_UNDEF: *out = UNDEF; break;
+       case EDG_WLL_QUERY_ATTR_JOBID: *out = JOBID; break;
+       case EDG_WLL_QUERY_ATTR_OWNER: *out = OWNER; break;
+       case EDG_WLL_QUERY_ATTR_STATUS: *out = STATUS; break;
+       case EDG_WLL_QUERY_ATTR_LOCATION: *out = LOCATION; break;
+       case EDG_WLL_QUERY_ATTR_DESTINATION: *out = DESTINATION; break;
+       case EDG_WLL_QUERY_ATTR_DONECODE: *out = DONECODE; break;
+       case EDG_WLL_QUERY_ATTR_USERTAG: *out = USERTAG; break;
+       case EDG_WLL_QUERY_ATTR_TIME: *out = TIME; break;
+       case EDG_WLL_QUERY_ATTR_LEVEL: *out = LEVEL; break;
+       case EDG_WLL_QUERY_ATTR_HOST: *out = HOST; break;
+       case EDG_WLL_QUERY_ATTR_SOURCE: *out = SOURCE; break;
+       case EDG_WLL_QUERY_ATTR_INSTANCE: *out = INSTANCE; break;
+       case EDG_WLL_QUERY_ATTR_EVENT_TYPE: *out = EVENT_TYPE; break;
+       case EDG_WLL_QUERY_ATTR_CHKPT_TAG: *out = CHKPT_TAG; break;
+       case EDG_WLL_QUERY_ATTR_RESUBMITTED: *out = RESUBMITTED; break;
+       case EDG_WLL_QUERY_ATTR_PARENT: *out = PARENT; break;
+       case EDG_WLL_QUERY_ATTR_EXITCODE: *out = EXITCODE; break;
+       default: *out = in; break;
+       }
+}
+
+void edg_wll_SoapToQueryOp(const enum edgwll__QueryOp in, edg_wll_QueryOp *out)
+{
+       switch ( in )
+       {
+       case EQUAL: *out = EDG_WLL_QUERY_OP_EQUAL; break;
+       case LESS: *out = EDG_WLL_QUERY_OP_LESS; break;
+       case GREATER: *out = EDG_WLL_QUERY_OP_GREATER; break;
+       case WITHIN: *out = EDG_WLL_QUERY_OP_WITHIN; break;
+       default: *out = in; break;
+       }
+}
+
+void edg_wll_QueryOpToSoap(const edg_wll_QueryOp in, enum edgwll__QueryOp *out)
+{
+       switch ( in )
+       {
+       case EDG_WLL_QUERY_OP_EQUAL: *out = EQUAL; break;
+       case EDG_WLL_QUERY_OP_LESS: *out = LESS; break;
+       case EDG_WLL_QUERY_OP_GREATER: *out = GREATER; break;
+       case EDG_WLL_QUERY_OP_WITHIN: *out = WITHIN; break;
+       default: *out = in; break;
+       }
+}
+
+int edg_wll_SoapToQueryVal(
+       const edg_wll_QueryAttr                         attr,
+       const struct edgwll__QueryRecValue *in,
+       union edg_wll_QueryVal                     *out)
+{
+       assert(in); assert(out);
+       if ( in->c ) {
+               if ( attr == EDG_WLL_QUERY_ATTR_JOBID || attr == EDG_WLL_QUERY_ATTR_PARENT ) {
+                       if ( edg_wlc_JobIdParse(in->c, &(out->j)) ) return -1;
+               } else {
+                       if ( !(out->c = strdup(in->c)) ) return -1;
+               }
+       }
+       else if ( in->t ) {
+               out->t.tv_sec = in->t->tvSec;
+               out->t.tv_usec = in->t->tvUsec;
+       }
+       else if ( in->i ) out->i = *(in->i);
+
+       return 0;
+}
+
+int edg_wll_QueryValToSoap(
+       struct soap                                        *soap,
+       const edg_wll_QueryAttr                 attr,
+       const union edg_wll_QueryVal   *in,
+       struct edgwll__QueryRecValue   *out)
+{
+       assert(in); assert(out);
+       memset(out, 0, sizeof(*out));
+       switch ( attr ) {
+       case EDG_WLL_QUERY_ATTR_USERTAG:
+       case EDG_WLL_QUERY_ATTR_OWNER: 
+       case EDG_WLL_QUERY_ATTR_LOCATION:
+       case EDG_WLL_QUERY_ATTR_DESTINATION:
+       case EDG_WLL_QUERY_ATTR_HOST:
+       case EDG_WLL_QUERY_ATTR_INSTANCE:
+               if ( in->c && !(out->c = soap_strdup(soap, in->c)) ) return SOAP_FAULT;
+               break;
+       case EDG_WLL_QUERY_ATTR_JOBID:
+       case EDG_WLL_QUERY_ATTR_PARENT: {
+                       char *s = edg_wlc_JobIdUnparse(in->j);
+                       out->c = soap_strdup(soap, s);
+                       free(s);
+                       if ( !out->c ) return SOAP_FAULT;
+               }
+               break;
+       case EDG_WLL_QUERY_ATTR_TIME:
+               out->t = soap_malloc(soap, sizeof(*(out->t)));
+               if ( !out->t ) return SOAP_FAULT;
+               out->t->tvSec = in->t.tv_sec;
+               out->t->tvUsec = in->t.tv_usec;
+               break;
+       case EDG_WLL_QUERY_ATTR_STATUS:
+       case EDG_WLL_QUERY_ATTR_DONECODE:
+       case EDG_WLL_QUERY_ATTR_LEVEL:
+       case EDG_WLL_QUERY_ATTR_SOURCE:
+       case EDG_WLL_QUERY_ATTR_EVENT_TYPE:
+       case EDG_WLL_QUERY_ATTR_RESUBMITTED:
+       default:
+               out->i = soap_malloc(soap, sizeof(*(out->i)));
+               if ( !out->i ) return SOAP_FAULT;
+               *(out->i) = in->i;
+               break;
+       }
+
+       return SOAP_OK;
+}
+
+int edg_wll_SoapToQueryRec(
+       const enum edgwll__QueryAttr    attr,
+       const struct edgwll__QueryRec  *in,
+       edg_wll_QueryRec                           *out)
+{
+       assert(attr); assert(in); assert(out);
+       memset(out, 0, sizeof(*out));
+       edg_wll_SoapToAttr(attr, &out->attr);
+       switch ( out->attr )
+       {
+       case EDG_WLL_QUERY_ATTR_TIME:
+               edg_wll_SoapToJobStatCode(*(in->attrid->state), &(out->attr_id.state));
+               break;
+       case EDG_WLL_QUERY_ATTR_USERTAG:
+               out->attr_id.tag = strdup(in->attrid->tag);
+               break;
+       default:
+               break;
+       }
+       edg_wll_SoapToQueryOp(in->op, &(out->op));
+       switch ( out->op )
+       {
+       case EDG_WLL_QUERY_OP_WITHIN:
+               if ( edg_wll_SoapToQueryVal(out->attr, in->value2, &(out->value2)) ) goto err;
+       default:
+               if ( edg_wll_SoapToQueryVal(out->attr, in->value1, &(out->value)) ) goto err;
+               break;
+       }
+
+       return 0;
+err:
+       edg_wll_QueryRecFree(out);
+       return -1;
+}
+
+int edg_wll_QueryRecToSoap(
+       struct soap                                *soap,
+       const edg_wll_QueryRec     *in,
+       struct edgwll__QueryRec   **out)
+{
+       struct edgwll__QueryRec    *qr;
+
+
+       assert(in); assert(out);
+       if ( !(qr = soap_malloc(soap, sizeof(*qr))) ) return SOAP_FAULT;
+       memset(qr, 0, sizeof(*qr));
+       if ( !in ) goto ret;
+       edg_wll_QueryOpToSoap(in->op, &(qr->op));
+       if (   in->attr == EDG_WLL_QUERY_ATTR_TIME
+               || in->attr == EDG_WLL_QUERY_ATTR_USERTAG ) {
+               if ( !(qr->attrid = soap_malloc(soap, sizeof(*(qr->attrid)))) ) return SOAP_FAULT;
+               memset(qr->attrid, 0, sizeof(*(qr->attrid)));
+               if ( in->attr == EDG_WLL_QUERY_ATTR_TIME ) {
+                       qr->attrid->state = soap_malloc(soap, sizeof(*(qr->attrid->state)));
+                       if ( !qr->attrid->state ) return SOAP_FAULT;
+                       edg_wll_JobStatCodeToSoap(in->attr_id.state, qr->attrid->state);
+               }
+               else {
+                       qr->attrid->tag = soap_strdup(soap, in->attr_id.tag);
+                       if ( !qr->attrid->tag ) return SOAP_FAULT;
+               }
+       }
+       switch ( in->op ) {
+       case EDG_WLL_QUERY_OP_WITHIN:
+               if ( !(qr->value2 = soap_malloc(soap, sizeof(*(qr->value2)))) ) return SOAP_FAULT;
+               if ( edg_wll_QueryValToSoap(soap, in->attr, &(in->value2), qr->value2) ) return SOAP_FAULT;
+       default:
+               if ( !(qr->value1 = soap_malloc(soap, sizeof(*(qr->value1)))) ) return SOAP_FAULT;
+               if ( edg_wll_QueryValToSoap(soap, in->attr, &(in->value), qr->value1) ) return SOAP_FAULT;
+               break;
+       }
+
+ret:
+       *out = qr;
+       return SOAP_OK;
+}
+
+int edg_wll_SoapToQueryConds(const struct edgwll__QueryCondition *in, edg_wll_QueryRec **out)
+{
+       int                                     i;
+       edg_wll_QueryRec   *qr;
+
+
+       assert(in); assert(out);
+       if ( !(qr = calloc(in->__sizerecords+1, sizeof(*qr))) ) goto err;
+       for ( i = 0; i < in->__sizerecords; i++ )
+               if ( edg_wll_SoapToQueryRec(in->attr, in->records[i], qr+i) ) goto err;
+       *out = qr;
+       return 0;
+
+err:
+       if ( qr ) {
+               for ( i = 0; qr[i].attr; i++ ) edg_wll_QueryRecFree(qr+i);
+               free(qr);
+       }
+       return -1;
+}
+
+int edg_wll_QueryCondsToSoap(
+       struct soap                                        *soap,
+       const edg_wll_QueryRec             *in,
+       struct edgwll__QueryCondition **out)
+{
+       int                                                             i;
+       struct edgwll__QueryCondition  *qc;
+
+
+       assert(out);
+       if ( !(qc = soap_malloc(soap, sizeof(*qc))) ) return SOAP_FAULT;
+       memset(qc, 0, sizeof(*qc));
+       if ( !in ) goto ret;
+       while ( in[qc->__sizerecords].attr ) qc->__sizerecords++;
+       if ( !qc->__sizerecords ) goto ret;
+       qc->records = soap_malloc(soap, sizeof(*(qc->records))*qc->__sizerecords);
+       if ( !qc->records ) return SOAP_FAULT;
+       edg_wll_AttrToSoap(in[0].attr, &(qc->attr));
+       for ( i = 0; in[i].attr; i++ )
+               if ( edg_wll_QueryRecToSoap(soap, in+i, qc->records+i) )
+                       return SOAP_FAULT;
+
+ret:
+       *out = qc;
+       return SOAP_OK;
+}
+
+int edg_wll_SoapToQueryCondsExt(const struct edgwll__QueryConditions *in, edg_wll_QueryRec ***out)
+{
+       int                                     i;
+       edg_wll_QueryRec  **qr;
+
+
+       assert(in); assert(out);
+       if ( !(qr = calloc(in->__sizecondition+1, sizeof(*qr))) ) return -1;
+       for ( i = 0; i < in->__sizecondition; i++ )
+               if ( edg_wll_SoapToQueryConds(in->condition[i], qr+i) ) goto err;
+
+       *out = qr;
+       return 0;
+
+err:
+       if ( qr ) {
+               int             j;
+               for ( i = 0; qr[i]; i++ )
+               {
+                       for ( j = 0; qr[i][j].attr; j++ ) edg_wll_QueryRecFree(qr[i]);
+                       free(qr[i]);
+               }
+               free(qr);
+       }
+       return -1;
+}
+
+int edg_wll_QueryCondsExtToSoap(
+       struct soap                                                        *soap,
+       const edg_wll_QueryRec                            **in,
+       struct edgwll__QueryConditions            **out)
+{
+       int                                                             i;
+       struct edgwll__QueryConditions *qc;
+
+
+       assert(out);
+       if ( !(qc = soap_malloc(soap, sizeof(*qc))) ) return SOAP_FAULT;
+       memset(qc, 0, sizeof(*qc));
+       if ( !in ) goto ret;
+       while ( in[qc->__sizecondition] ) qc->__sizecondition++;
+       if ( !qc->__sizecondition ) goto ret;
+       qc->condition = soap_malloc(soap, sizeof(*(qc->condition))*qc->__sizecondition);
+       if ( !qc->condition ) return SOAP_FAULT;
+       for ( i = 0; in[i]; i++ )
+               if ( edg_wll_QueryCondsToSoap(soap, in[i], qc->condition+i) )
+                       return SOAP_FAULT;
+
+ret:
+       *out = qc;
+       return SOAP_OK;
+}
+
+int edg_wll_JobsQueryResToSoap(
+       struct soap                                                *soap,
+       const edg_wlc_JobId                                *jobs,
+       const edg_wll_JobStat                      *states,
+       struct edgwll2__QueryJobsResponse  *out)
+{
+       int                                                     i;
+
+
+       assert(out); assert(out->states); assert(out->jobs);
+       memset(out->jobs, 0, sizeof(*(out->jobs)));
+       memset(out->states, 0, sizeof(*(out->states)));
+
+       if ( jobs ) {
+               for ( i = 0; jobs[i]; i++ ) ;
+               out->jobs->jobs = soap_malloc(soap, sizeof(*(out->jobs->jobs))*i);
+               if ( !out->jobs->jobs ) return SOAP_FAULT;
+               out->jobs->__sizejobs = i;
+               for ( i = 0; jobs[i]; i++ ) {
+                       char       *s;
+                       if ( !(s = edg_wlc_JobIdUnparse(jobs[i])) ) return SOAP_FAULT;
+                       if ( !(out->jobs->jobs[i] = soap_strdup(soap, s)) ) return SOAP_FAULT;
+                       free(s);
+               }
+       }
+       if ( states ) {
+               for ( i = 0; states[i].state; i++ ) ;
+               out->states->states = soap_malloc(soap, sizeof(*(out->states->states))*i);
+               if ( !out->states->states ) return SOAP_FAULT;
+               out->states->__sizestates = i;
+
+               for ( i = 0; states[i].state; i++ )
+                       if ( edg_wll_StatusToSoap(soap, states+i, out->states->states+i) )
+                               return SOAP_FAULT;
+       }
+
+       return SOAP_OK;
+}
diff --git a/org.glite.lb.server/src/ws_typeref.h b/org.glite.lb.server/src/ws_typeref.h
new file mode 100644 (file)
index 0000000..44813c7
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef __EDG_WORKLOAD_LOGGING_LBSERVER_WS_TYPEREF_H__
+#define __EDG_WORKLOAD_LOGGING_LBSERVER_WS_TYPEREF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void edg_wll_JobStatCodeToSoap(edg_wll_JobStatCode, enum edgwll__JobStatCode *);
+extern void edg_wll_SoapToJobStatCode(enum edgwll__JobStatCode, edg_wll_JobStatCode *);
+
+extern void edg_wll_StatusToSoap(struct soap *, edg_wll_JobStat const *, struct edgwll__JobStat *);
+extern void edg_wll_SoapToStatus(struct soap *, struct edgwll__JobStat const *, edg_wll_JobStat **);
+
+extern void edg_wll_SoapToJobStatFlags(const struct edgwll__JobStatFlags *, int *);
+extern int edg_wll_JobStatFlagsToSoap(struct soap *, const int, struct edgwll__JobStatFlags *);
+
+extern void edg_wll_SoapToAttr(const enum edgwll__QueryAttr, edg_wll_QueryAttr *);
+extern void edg_wll_AttrToSoap(const edg_wll_QueryAttr, enum edgwll__QueryAttr *);
+
+extern void edg_wll_SoapToQueryOp(
+                       const enum edgwll__QueryOp,
+                       edg_wll_QueryOp *);
+extern void edg_wll_QueryOpToSoap(
+                       const edg_wll_QueryOp,
+                       enum edgwll__QueryOp *);
+
+extern int edg_wll_SoapToQueryVal(
+                       const edg_wll_QueryAttr,
+                       const struct edgwll__QueryRecValue *,
+                       union edg_wll_QueryVal *);
+extern int edg_wll_QueryValToSoap(struct soap *,
+                       const edg_wll_QueryAttr,
+                       const union edg_wll_QueryVal *,
+                       struct edgwll__QueryRecValue *);
+
+extern int edg_wll_SoapToQueryRec(
+                       const enum edgwll__QueryAttr,
+                       const struct edgwll__QueryRec *,
+                       edg_wll_QueryRec *);
+extern int edg_wll_QueryRecToSoap(struct soap *,
+                       const edg_wll_QueryRec *,
+                       struct edgwll__QueryRec *);
+
+
+extern int edg_wll_SoapToQueryConds(
+                       const struct edgwll__QueryCondition *,
+                       edg_wll_QueryRec **);
+extern int edg_wll_QueryCondsToSoap(struct soap *,
+                       const edg_wll_QueryRec *,
+                       struct edgwll__QueryCondition **);
+
+extern int edg_wll_SoapToQueryCondsExt(
+                       const struct edgwll__QueryConditions *,
+                       edg_wll_QueryRec ***);
+extern int edg_wll_QueryCondsExtToSoap(struct soap *,
+                       const edg_wll_QueryRec **,
+                       struct edgwll__QueryConditions **);
+
+extern int edg_wll_JobsQueryResToSoap(struct soap *,
+                       edg_wlc_JobId *,
+                       edg_wll_JobStat *,
+                       struct edgwll2__QueryJobsResponse *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __EDG_WORKLOAD_LOGGING_LBSERVER_WS_TYPEREF_H__ */