Avoid mixed stmt/var declare
[simpleserver-moved-to-github.git] / SimpleServer.xs
index e324009..4c047e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: SimpleServer.xs,v 1.31 2004-06-06 09:07:18 adam Exp $ 
+ * $Id: SimpleServer.xs,v 1.40 2006-04-10 20:49:24 adam Exp $ 
  * ----------------------------------------------------------------------
  * 
  * Copyright (c) 2000-2004, Index Data.
@@ -103,7 +103,7 @@ CV * simpleserver_sv2cv(SV *handler) {
 }
 
 /* debugging routine to check for destruction of Perl interpreters */
-#if 1
+#ifdef USE_ITHREADS
 void tst_clones(void)
 {
     int i; 
@@ -358,7 +358,7 @@ void fatal(char *fmt, ...)
 {
     va_list ap;
 
-    fprintf(stderr, "FATAL (yazwrap): ");
+    fprintf(stderr, "FATAL (SimpleServer): ");
     va_start(ap, fmt);
     vfprintf(stderr, fmt, ap);
     va_end(ap);
@@ -441,8 +441,22 @@ static SV *rpn2perl(Z_RPNStructure *s)
     case Z_RPNStructure_simple: {
        Z_Operand *o = s->u.simple;
        Z_AttributesPlusTerm *at;
+       if (o->which == Z_Operand_resultSetId) {
+           SV *sv2;
+           /* This code causes a SIGBUS on my machine, and I have no
+              idea why.  It seems as clear as day to me */
+           char *rsid = (char*) o->u.resultSetId;
+           printf("Encoding resultSetId '%s'\n", rsid);
+           sv = newObject("Net::Z3950::RPN::RSID", (SV*) (hv = newHV()));
+           printf("Made sv=0x%lx, hv=0x%lx\n",
+                  (unsigned long) sv ,(unsigned long) hv);
+           sv2 = newSVpv(rsid, strlen(rsid));
+           setMember(hv, "id", sv2);
+           printf("Set hv{id} to 0x%lx\n", (unsigned long) sv2);
+           return sv;
+       }
        if (o->which != Z_Operand_APT)
-           fatal("can't handle RPN simples other than APT");
+           fatal("can't handle RPN simples other than APT and RSID");
        at = o->u.attributesPlusTerm;
        if (at->term->which != Z_Term_general)
            fatal("can't handle RPN terms other than general");
@@ -601,6 +615,7 @@ int bend_search(void *handle, bend_search_rr *rr)
        SV *point;
        Zfront_handle *zhandle = (Zfront_handle *)handle;
        CV* handler_cv = 0;
+       SV *rpnSV;
 
        dSP;
        ENTER;
@@ -627,15 +642,23 @@ int bend_search(void *handle, bend_search_rr *rr)
        hv_store(href, "DATABASES", 9, newRV( (SV*) aref), 0);
        hv_store(href, "HANDLE", 6, zhandle->handle, 0);
        hv_store(href, "PID", 3, newSViv(getpid()), 0);
-       hv_store(href, "RPN", 3, zquery2perl(rr->query), 0);
+       if ((rpnSV = zquery2perl(rr->query)) != 0) {
+           hv_store(href, "RPN", 3, rpnSV, 0);
+       }
        query = zquery2pquery(rr->query);
        if (query)
        {
                hv_store(href, "QUERY", 5, newSVpv((char *)query->buf, query->pos), 0);
        }
+       else if (rr->query->which == Z_Query_type_104 &&
+                rr->query->u.type_104->which == Z_External_CQL) {
+           hv_store(href, "CQL", 3,
+                    newSVpv(rr->query->u.type_104->u.cql, 0), 0);
+       }
        else
        {       
                rr->errcode = 108;
+               return 0;
        }
        PUSHMARK(sp);
        
@@ -669,7 +692,8 @@ int bend_search(void *handle, bend_search_rr *rr)
        zhandle->handle = point;
        sv_free( (SV*) aref);
        sv_free( (SV*) href);
-       wrbuf_free(query, 1);
+       if (query)
+           wrbuf_free(query, 1);
        PUTBACK;
        FREETMPS;
        LEAVE;
@@ -776,7 +800,13 @@ int bend_fetch(void *handle, bend_fetch_rr *rr)
        href = newHV();
        hv_store(href, "SETNAME", 7, newSVpv(rr->setname, 0), 0);
        temp = hv_store(href, "OFFSET", 6, newSViv(rr->number), 0);
-       oid_dotted = oid2dotted(rr->request_format_raw);
+       if (rr->request_format_raw != 0) {
+           oid_dotted = oid2dotted(rr->request_format_raw);
+       } else {
+           /* Probably an SRU request: assume XML is required */
+           oid_dotted = wrbuf_alloc();
+           wrbuf_puts(oid_dotted, "1.2.840.10003.5.109.10");
+       }
        hv_store(href, "REQ_FORM", 8, newSVpv((char *)oid_dotted->buf, oid_dotted->pos), 0);
        hv_store(href, "REP_FORM", 8, newSVpv((char *)oid_dotted->buf, oid_dotted->pos), 0);
        hv_store(href, "BASENAME", 8, newSVpv("", 0), 0);
@@ -804,7 +834,11 @@ int bend_fetch(void *handle, bend_fetch_rr *rr)
                }
                else
                {
-                       rr->errcode = 26;
+                       /* This is where we end up in the case of
+                        * SRU.  Since record composition ("element
+                        * sets") are meaningless in SRU anyway, we
+                        * just skip this.
+                        */
                }
        }
 
@@ -1158,8 +1192,6 @@ bend_initresult *bend_init(bend_initrequest *q)
        bend_initresult *r = (bend_initresult *)
                odr_malloc (q->stream, sizeof(*r));
        char *ptr;
-       char *user = NULL;
-       char *passwd = NULL;
        CV* handler_cv = 0;
        dSP;
        STRLEN len;
@@ -1205,22 +1237,26 @@ bend_initresult *bend_init(bend_initrequest *q)
        hv_store(href, "HANDLE", 6, newSVsv(&sv_undef), 0);
        hv_store(href, "PID", 3, newSViv(getpid()), 0);
        if (q->auth) {
+           char *user = NULL;
+           char *passwd = NULL;
            if (q->auth->which == Z_IdAuthentication_open) {
-               char *openpass = xstrdup (q->auth->u.open);
-               char *cp = strchr (openpass, '/');
+                char *cp;
+               user = nmem_strdup (odr_getmem (q->stream), q->auth->u.open);
+               cp = strchr (user, '/');
                if (cp) {
+                    /* password after / given */
                    *cp = '\0';
-                   user = nmem_strdup (odr_getmem (q->stream), openpass);
-                   passwd = nmem_strdup (odr_getmem (q->stream), cp + 1);
+                   passwd = cp+1;
                }
-               xfree(openpass);
            } else if (q->auth->which == Z_IdAuthentication_idPass) {
                user = q->auth->u.idPass->userId;
                passwd = q->auth->u.idPass->password;
            }
            /* ### some code paths have user/password unassigned here */
-           hv_store(href, "USER", 4, newSVpv(user, 0), 0);
-           hv_store(href, "PASS", 4, newSVpv(passwd, 0), 0);
+            if (user)
+               hv_store(href, "USER", 4, newSVpv(user, 0), 0);
+            if (passwd)
+               hv_store(href, "PASS", 4, newSVpv(passwd, 0), 0);
        }
 
        PUSHMARK(sp);   
@@ -1301,7 +1337,8 @@ void bend_close(void *handle)
 
                sv_free((SV*) href);
        }
-       sv_free(zhandle->handle);
+       else
+               sv_free(zhandle->handle);
        PUTBACK;
        FREETMPS;
        LEAVE;
@@ -1317,6 +1354,9 @@ void bend_close(void *handle)
 
 MODULE = Net::Z3950::SimpleServer      PACKAGE = Net::Z3950::SimpleServer
 
+PROTOTYPES: DISABLE
+
+
 void
 set_init_handler(arg)
                SV *arg
@@ -1424,3 +1464,11 @@ ScanPartial()
                RETVAL
 
  
+void
+yazlog(arg)
+               SV *arg
+       CODE:
+               STRLEN len;
+               char *ptr;
+               ptr = SvPV(arg, len);
+               yaz_log(YLOG_LOG, "%.*s", len, ptr);