X-Git-Url: http://git.indexdata.com/?p=simpleserver-moved-to-github.git;a=blobdiff_plain;f=SimpleServer.xs;h=566e817eff537b310ed7b6ab18555a5709c1065d;hp=44f182c8df92cd2b50ad4360f91e2f28fdc8d766;hb=e86efa12765b33efbc5dd7ae4f21e22bc2d9c56a;hpb=bf76c3f6ff0e224efce7e47f9f778f6379a3e504 diff --git a/SimpleServer.xs b/SimpleServer.xs index 44f182c..566e817 100644 --- a/SimpleServer.xs +++ b/SimpleServer.xs @@ -1,5 +1,5 @@ /* - * $Id: SimpleServer.xs,v 1.28 2004-06-05 07:55:05 adam Exp $ + * $Id: SimpleServer.xs,v 1.39 2006-04-09 23:01:00 adam Exp $ * ---------------------------------------------------------------------- * * Copyright (c) 2000-2004, Index Data. @@ -102,18 +102,21 @@ CV * simpleserver_sv2cv(SV *handler) { } } -/* debuggin routine to check for destruction of Perl interpreters */ -#if 0 -int tst_clones(void) +/* debugging routine to check for destruction of Perl interpreters */ +#ifdef USE_ITHREADS +void tst_clones(void) { int i; PerlInterpreter *parent = PERL_GET_CONTEXT; - for (i = 0; i<500; i++) + for (i = 0; i<5000; i++) { - PerlInterpreter *perl_interp = perl_clone(parent, 0); - PERL_SET_CONTEXT( perl_interp ); + PerlInterpreter *perl_interp; + + PERL_SET_CONTEXT(parent); + PL_perl_destruct_level = 2; + perl_interp = perl_clone(parent, CLONEf_CLONE_HOST); PL_perl_destruct_level = 2; - PERL_SET_CONTEXT( parent ); + PERL_SET_CONTEXT(perl_interp); perl_destruct(perl_interp); perl_free(perl_interp); } @@ -135,7 +138,7 @@ int simpleserver_clone(void) { if (!current) { PerlInterpreter *perl_interp; PERL_SET_CONTEXT( root_perl_context ); - perl_interp = perl_clone(root_perl_context, 0); + perl_interp = perl_clone(root_perl_context, CLONEf_CLONE_HOST); PERL_SET_CONTEXT( perl_interp ); } } @@ -156,7 +159,7 @@ void simpleserver_free(void) { */ if (current_interp != root_perl_context) { PL_perl_destruct_level = 2; - PERL_SET_CONTEXT(root_perl_context); + PERL_SET_CONTEXT(current_interp); perl_destruct(current_interp); perl_free(current_interp); } @@ -355,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); @@ -438,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"); @@ -563,9 +580,6 @@ int bend_sort(void *handle, bend_sort_rr *rr) temp = hv_fetch(href, "STATUS", 6, 1); status = newSVsv(*temp); - - - PUTBACK; FREETMPS; LEAVE; @@ -592,20 +606,16 @@ int bend_search(void *handle, bend_search_rr *rr) HV *href; AV *aref; SV **temp; - SV *hits; - SV *err_code; - SV *err_str; char *ODR_errstr; STRLEN len; int i; char **basenames; - int n; WRBUF query; char *ptr; SV *point; - SV *ODR_point; Zfront_handle *zhandle = (Zfront_handle *)handle; CV* handler_cv = 0; + SV *rpnSV; dSP; ENTER; @@ -632,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); @@ -654,39 +672,31 @@ int bend_search(void *handle, bend_search_rr *rr) SPAGAIN; temp = hv_fetch(href, "HITS", 4, 1); - hits = newSVsv(*temp); + rr->hits = SvIV(*temp); temp = hv_fetch(href, "ERR_CODE", 8, 1); - err_code = newSVsv(*temp); + rr->errcode = SvIV(*temp); temp = hv_fetch(href, "ERR_STR", 7, 1); - err_str = newSVsv(*temp); + ptr = SvPV(*temp, len); + ODR_errstr = (char *)odr_malloc(rr->stream, len + 1); + strcpy(ODR_errstr, ptr); + rr->errstring = ODR_errstr; temp = hv_fetch(href, "HANDLE", 6, 1); point = newSVsv(*temp); - PUTBACK; - FREETMPS; - LEAVE; - hv_undef(href); av_undef(aref); - rr->hits = SvIV(hits); - rr->errcode = SvIV(err_code); - ptr = SvPV(err_str, len); - ODR_errstr = (char *)odr_malloc(rr->stream, len + 1); - strcpy(ODR_errstr, ptr); - rr->errstring = ODR_errstr; zhandle->handle = point; - handle = zhandle; - sv_free(hits); - sv_free(err_code); - sv_free(err_str); sv_free( (SV*) aref); sv_free( (SV*) href); - /*sv_free(point);*/ - wrbuf_free(query, 1); + if (query) + wrbuf_free(query, 1); + PUTBACK; + FREETMPS; + LEAVE; return 0; } @@ -790,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); @@ -818,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. + */ } } @@ -857,9 +877,6 @@ int bend_fetch(void *handle, bend_fetch_rr *rr) temp = hv_fetch(href, "HANDLE", 6, 1); point = newSVsv(*temp); - PUTBACK; - FREETMPS; - LEAVE; hv_undef(href); @@ -913,6 +930,10 @@ int bend_fetch(void *handle, bend_fetch_rr *rr) sv_free(err_code), sv_free(sur_flag); sv_free(rep_form); + + PUTBACK; + FREETMPS; + LEAVE; return 0; } @@ -920,7 +941,6 @@ int bend_fetch(void *handle, bend_fetch_rr *rr) int bend_present(void *handle, bend_present_rr *rr) { - HV *href; SV **temp; SV *err_code; @@ -1058,7 +1078,6 @@ int bend_scan(void *handle, bend_scan_rr *rr) char *ODR_errstr; STRLEN len; int term_len; - SV *term_tmp; SV *entries_ref; Zfront_handle *zhandle = (Zfront_handle *)handle; CV* handler_cv = 0; @@ -1167,32 +1186,22 @@ int bend_scan(void *handle, bend_scan_rr *rr) return 0; } - bend_initresult *bend_init(bend_initrequest *q) { - int dummy = simpleserver_clone(); - bend_initresult *r = (bend_initresult *) odr_malloc (q->stream, sizeof(*r)); - HV *href; - SV **temp; - SV *id; - SV *name; - SV *ver; - SV *err_str; - SV *status; + int dummy = simpleserver_clone(); + bend_initresult *r = (bend_initresult *) + odr_malloc (q->stream, sizeof(*r)); + char *ptr; + CV* handler_cv = 0; + dSP; + STRLEN len; NMEM nmem = nmem_create(); Zfront_handle *zhandle = (Zfront_handle *) nmem_malloc (nmem, sizeof(*zhandle)); - STRLEN len; - int n; SV *handle; - /*char *name_ptr; - char *ver_ptr;*/ - char *ptr; - char *user = NULL; - char *passwd = NULL; - CV* handler_cv = 0; + HV *href; + SV **temp; - dSP; ENTER; SAVETMPS; @@ -1217,6 +1226,7 @@ bend_initresult *bend_init(bend_initrequest *q) { q->bend_scan = bend_scan; } + href = newHV(); hv_store(href, "IMP_ID", 6, newSVpv("", 0), 0); hv_store(href, "IMP_NAME", 8, newSVpv("", 0), 0); @@ -1227,27 +1237,30 @@ 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, '/'); + user = nmem_strdup (odr_getmem (q->stream), q->auth->u.open); + char *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); - XPUSHs(sv_2mortal(newRV( (SV*) href))); + XPUSHs(sv_2mortal(newRV((SV*) href))); PUTBACK; @@ -1260,58 +1273,53 @@ bend_initresult *bend_init(bend_initrequest *q) SPAGAIN; temp = hv_fetch(href, "IMP_ID", 6, 1); - id = newSVsv(*temp); + ptr = SvPV(*temp, len); + q->implementation_id = nmem_strdup(nmem, ptr); temp = hv_fetch(href, "IMP_NAME", 8, 1); - name = newSVsv(*temp); + ptr = SvPV(*temp, len); + q->implementation_name = nmem_strdup(nmem, ptr); temp = hv_fetch(href, "IMP_VER", 7, 1); - ver = newSVsv(*temp); + ptr = SvPV(*temp, len); + q->implementation_version = nmem_strdup(nmem, ptr); temp = hv_fetch(href, "ERR_CODE", 8, 1); - status = newSVsv(*temp); + r->errcode = SvIV(*temp); temp = hv_fetch(href, "ERR_STR", 7, 1); - err_str = newSVsv(*temp); + ptr = SvPV(*temp, len); + r->errstring = (char *)odr_malloc(q->stream, len + 1); + strcpy(r->errstring, ptr); temp = hv_fetch(href, "HANDLE", 6, 1); handle= newSVsv(*temp); + zhandle->handle = handle; + + r->handle = zhandle; hv_undef(href); + sv_free((SV*) href); + PUTBACK; FREETMPS; LEAVE; - zhandle->handle = handle; - r->errcode = SvIV(status); - ptr = SvPV(err_str, len); - r->errstring = (char *)odr_malloc(q->stream, len + 1); - strcpy(r->errstring, ptr); - sv_free(err_str); - r->handle = zhandle; - ptr = SvPV(id, len); - q->implementation_id = nmem_strdup(nmem, ptr); - ptr = SvPV(name, len); - q->implementation_name = nmem_strdup(nmem, ptr); - ptr = SvPV(ver, len); - q->implementation_version = nmem_strdup(nmem, ptr); - return r; + return r; } - void bend_close(void *handle) { HV *href; Zfront_handle *zhandle = (Zfront_handle *)handle; - SV **temp; CV* handler_cv = 0; int stop_flag = 0; + dSP; + ENTER; + SAVETMPS; if (close_ref) { - dSP; - ENTER; - SAVETMPS; href = newHV(); hv_store(href, "HANDLE", 6, zhandle->handle, 0); @@ -1326,10 +1334,13 @@ void bend_close(void *handle) SPAGAIN; - PUTBACK; - FREETMPS; - LEAVE; + sv_free((SV*) href); } + else + sv_free(zhandle->handle); + PUTBACK; + FREETMPS; + LEAVE; stop_flag = zhandle->stop_flag; nmem_destroy(zhandle->nmem); simpleserver_free(); @@ -1342,6 +1353,9 @@ void bend_close(void *handle) MODULE = Net::Z3950::SimpleServer PACKAGE = Net::Z3950::SimpleServer +PROTOTYPES: DISABLE + + void set_init_handler(arg) SV *arg @@ -1425,6 +1439,7 @@ start_server(...) root_perl_context = PERL_GET_CONTEXT; nmem_mutex_create(&simpleserver_mutex); #if 0 + /* only for debugging perl_clone .. */ tst_clones(); #endif @@ -1448,3 +1463,11 @@ ScanPartial() RETVAL +void +yazlog(arg) + SV *arg + CODE: + STRLEN len; + char *ptr; + ptr = SvPV(arg, len); + yaz_log(YLOG_LOG, "%.*s", len, ptr);