Merge branch 'normal_cql'
authorAdam Dickmeiss <adam@indexdata.dk>
Wed, 3 Apr 2013 11:21:58 +0000 (13:21 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Wed, 3 Apr 2013 11:21:58 +0000 (13:21 +0200)
13 files changed:
configure.ac
doc/.gitignore
doc/Makefile.am
doc/comstack.xml
doc/local.ent.in [deleted file]
doc/local0.ent.in [new file with mode: 0644]
doc/server.xml
doc/yaz-config-man.xml
doc/yaz-man.xml
src/tcpip.c
util/marcdump.c
ztest/read-marc.c
ztest/ztest.c

index b73bfd9..bb5bca5 100644 (file)
@@ -406,7 +406,7 @@ client/Makefile
 ztest/Makefile
 zoom/Makefile
 doc/Makefile
-doc/local.ent
+doc/local0.ent
 doc/common/Makefile
 doc/common/print.dsl
 etc/Makefile
@@ -417,6 +417,8 @@ win/version.nsi
 include/yaz/yaz-version.h
 ],[
        sed s%echo_source=yes%echo_source=no%g < yaz-config > util/yaz-config && chmod +x yaz-config util/yaz-config
+       diff doc/local.ent doc/local0.ent >/dev/null 2>/dev/null \
+               || cp doc/local0.ent doc/local.ent
     ]
 )
 
index f80be9c..0c36393 100644 (file)
@@ -13,6 +13,7 @@ manpage.links
 manpage.refs
 *.[178]
 local.ent
+local0.ent
 htmlhelp.hhp
 toc.hhc
 std-oid-table.xml
index b2e3266..172ae24 100644 (file)
@@ -8,7 +8,7 @@ XMLFILES=bookinfo.xml introduction.xml installation.xml \
  asn.xml tools.xml odr.xml comstack.xml server.xml license.xml \
  future.xml zoom.xml credits.xml gfs-options.xml \
  yaz.xml soap.xml gfs-virtual.xml gfs-synopsis.xml \
- std-oid-table.xml manref.xml
+ std-oid-table.xml manref.xml local.ent
 
 HTMLFILES = index.html
 
@@ -23,7 +23,7 @@ REFFILES=yaz-client-man.xml yaz-ztest-man.xml yaz-config-man.xml \
        yaz-illclient-man.xml yaz-icu-man.xml yaz-url-man.xml \
        bib1-attr-man.xml yaz-json-parse-man.xml
 
-SUPPORTFILES=entities.ent apilayer.obj local.ent.in
+SUPPORTFILES=entities.ent apilayer.obj
 
 doc_DATA = $(HTMLFILES) apilayer.png 
 man_MANS = $(MANFILES)
@@ -80,6 +80,8 @@ $(HTMLFILES): $(XMLFILES)
        rm -f *.html
        $(HTML_COMPILE) $(srcdir)/yaz.xml
 
+$(MANFILES): local.ent
+
 yaz.pdf: $(XMLFILES)
        $(PDF_COMPILE) $(srcdir)/yaz.xml
 
index fe2d937..632cb9c 100644 (file)
    </para>
 
    <para>
-    For TCP/IP and SSL transport modes, the special hostname &quot;@&quot;
-    is mapped to any local address
-    (the manifest constant <literal>INADDR_ANY</literal>).
-    It is used to establish local listening endpoints in the server role.
+    For TCP/IP and SSL, the special hostnames <literal>@</literal>,
+    maps to <literal>IN6ADDR_ANY_INIT</literal> with
+    IPV4 binding as well (bindv6only=0),
+    The special hostname <literal>@4</literal> binds to
+    <literal>INADDR_ANY</literal> (IPV4 only listener).
+    The special hostname <literal>@6</literal> binds to
+    <literal>IN6ADDR_ANY_INIT</literal> with bindv6only=1 (IPV6 only listener).
    </para>
 
    <para>
diff --git a/doc/local.ent.in b/doc/local.ent.in
deleted file mode 100644 (file)
index 22cfcf2..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ENTITY version "@VERSION@">
-<!ENTITY prefix "@prefix@">
diff --git a/doc/local0.ent.in b/doc/local0.ent.in
new file mode 100644 (file)
index 0000000..7b2eb41
--- /dev/null
@@ -0,0 +1 @@
+<!ENTITY version "@VERSION@">
index b4b0fbe..f5b28f4 100644 (file)
@@ -818,11 +818,13 @@ typedef struct bend_scan_rr {
    </para>
 
    <para>
-    For TCP/IP and SSL, the special hostnames <literal>@</literal> and
-    <literal>@6</literal> are mapped to the addresses
-    <literal>INADDR_ANY</literal> (IPV4) and
-    <literal>IN6ADDR_ANY_INIT</literal> (IPV6)
-    respectively.
+    For TCP/IP and SSL, the special hostnames <literal>@</literal>,
+    maps to <literal>IN6ADDR_ANY_INIT</literal> with
+    IPV4 binding as well (bindv6only=0),
+    The special hostname <literal>@4</literal> binds to
+    <literal>INADDR_ANY</literal> (IPV4 only listener).
+    The special hostname <literal>@6</literal> binds to
+    <literal>IN6ADDR_ANY_INIT</literal> with bindv6only=1 (IPV6 only listener).
    </para>
 
    <example id="server.example.running.unix"><title>Running the GFS on Unix</title>
index 4e8468a..277b740 100644 (file)
 
  <refsect1><title>FILES</title>
   <para>
-   <filename>&prefix;/bin/yaz-config</filename>
+   <filename>/usr/bin/yaz-config</filename>
   </para>
   <para>
-   <filename>&prefix;/lib/libyaz*.a</filename>
+   <filename>/usr/lib/libyaz*.a</filename>
   </para>
   <para>
-   <filename>&prefix;/include/yaz/*.h</filename>
+   <filename>/usr/include/yaz/*.h</filename>
   </para>
   </refsect1>
  <refsect1><title>SEE ALSO</title>
index b706541..82172f6 100644 (file)
     </citerefentry>
   </para>
   <para>YAZ manual (
-   <filename>&prefix;/share/doc/yaz</filename>)
+   <filename>/usr/share/doc/yaz</filename>)
   </para>
   <para>
    <ulink url="&url.yaz;">YAZ home page</ulink>.
index c70ff4c..32b1ec1 100644 (file)
@@ -338,7 +338,8 @@ static int ssl_check_error(COMSTACK h, tcpip_state *sp, int res)
 
 #if HAVE_GETADDRINFO
 /* resolve using getaddrinfo */
-struct addrinfo *tcpip_getaddrinfo(const char *str, const char *port)
+struct addrinfo *tcpip_getaddrinfo(const char *str, const char *port,
+                                   int *ipv6_only)
 {
     struct addrinfo hints, *res;
     int error;
@@ -366,18 +367,28 @@ struct addrinfo *tcpip_getaddrinfo(const char *str, const char *port)
     if (!strcmp("@", host))
     {
         hints.ai_flags = AI_PASSIVE;
+        hints.ai_family = AF_INET6;
+        error = getaddrinfo(0, port, &hints, &res);
+        *ipv6_only = 0;
+    }
+    else if (!strcmp("@4", host))
+    {
+        hints.ai_flags = AI_PASSIVE;
         hints.ai_family = AF_INET;
         error = getaddrinfo(0, port, &hints, &res);
+        *ipv6_only = -1;
     }
     else if (!strcmp("@6", host))
     {
         hints.ai_flags = AI_PASSIVE;
         hints.ai_family = AF_INET6;
         error = getaddrinfo(0, port, &hints, &res);
+        *ipv6_only = 1;
     }
     else
     {
         error = getaddrinfo(host, port, &hints, &res);
+        *ipv6_only = -1;
     }
     if (error)
         return 0;
@@ -433,6 +444,7 @@ void *tcpip_straddr(COMSTACK h, const char *str)
     tcpip_state *sp = (tcpip_state *)h->cprivate;
     const char *port = "210";
     struct addrinfo *ai = 0;
+    int ipv6_only = 0;
     if (h->protocol == PROTO_HTTP)
     {
         if (h->type == ssl_type)
@@ -445,7 +457,7 @@ void *tcpip_straddr(COMSTACK h, const char *str)
 
     if (sp->ai)
         freeaddrinfo(sp->ai);
-    sp->ai = tcpip_getaddrinfo(str, port);
+    sp->ai = tcpip_getaddrinfo(str, port, &ipv6_only);
     if (sp->ai && h->state == CS_ST_UNBND)
     {
         int s = -1;
@@ -459,7 +471,11 @@ void *tcpip_straddr(COMSTACK h, const char *str)
             return 0;
         assert(ai);
         h->iofile = s;
-
+        if (ipv6_only >= 0 &&
+            setsockopt(h->iofile,
+                       IPPROTO_IPV6,
+                       IPV6_V6ONLY, &ipv6_only, sizeof(ipv6_only)))
+                return 0;
         if (!tcpip_set_blocking(h, h->flags))
             return 0;
     }
index e0491c4..f92204e 100644 (file)
@@ -398,7 +398,10 @@ static void dump(const char *fname, const char *from, const char *to,
                 {
                     if ((i & 15) == 0)
                         fprintf(cfile, "  \"");
-                    fprintf(cfile, "\\x%02X", p[i] & 255);
+                    if (p[i] < 32 || p[i] > 126)
+                        fprintf(cfile, "\" \"\\x%02X\" \"", p[i] & 255);
+                    else
+                        fputc(p[i], cfile);
 
                     if (i < r - 1 && (i & 15) == 15)
                         fprintf(cfile, "\"\n");
index bf60296..c31eab3 100644 (file)
@@ -1536,12 +1536,48 @@ char *marc_records[NO_MARC_RECORDS] = {
   "\x44\x42\x46\x38\x38\x34\x32\x1E\x1D"
 };
 
+static char *marc_record0 =
+  "00366nam  220016"
+  "98a 450000100130"
+  "0000003000400013"
+  "0050017000170080"
+  "0410003401000170"
+  "0179040001300075"
+  "0500012000881000"
+  "0170010024500300"
+  "0117260001200147"
+  "2630009001593000"
+  "01100168" "\x1E" "   1122"
+  "4466 " "\x1E" "DLC" "\x1E" "000000"
+  "00000000.0" "\x1E" "91071"
+  "0c19910701nju   "
+  "        00010 en"
+  "g  " "\x1E" "  " "\x1F" "aDLC" "\x1F" "cDLC"
+  "" "\x1E" "00" "\x1F" "a123-xyz" "\x1E" "10" "\x1F" ""
+  "aJack Collins" "\x1E" "10"
+  "" "\x1F" "aHow to program"
+  " a computer" "\x1E" "1 " "\x1F" "a"
+  "Penguin" "\x1E" "  " "\x1F" "a8710"
+  "" "\x1E" "  " "\x1F" "ap. cm." "\x1E" "  " "\x1F" "a"
+  "   11224466 " "\x1E" "" "\x1D" ""
+;
+
 /* read MARC record from offset 'num' */
 char *dummy_marc_record(int num, ODR odr)
 {
     if (num < 1)
         return 0;
-    return marc_records[(num-1) % NO_MARC_RECORDS];
+    if (num >= NO_MARC_RECORDS)
+    {
+        char *p = odr_strdup(odr, marc_record0);
+        sprintf(p + 279, "%-5d", num);
+        p[284] = ' ';
+        return p;
+    }
+    else
+    {
+        return marc_records[(num-1) % NO_MARC_RECORDS];
+    }
 }
 
 /* read MARC record and convert to XML */
index 896f56e..0fde809 100644 (file)
@@ -95,7 +95,7 @@ static void remove_sets(struct session_handle *sh)
     Only terms  that looks a numeric is used.. Returns -1 if
     no sub tree has a hit count term
 */
-static Odr_int get_term_hit(Z_RPNStructure *s)
+static Odr_int get_term_hit(Z_RPNStructure *s, unsigned *hash)
 {
     Odr_int h = -1;
     switch(s->which)
@@ -114,13 +114,19 @@ static Odr_int get_term_hit(Z_RPNStructure *s)
                     h = odr_atoi(wrbuf_cstr(hits_str));
                     wrbuf_destroy(hits_str);
                 }
+                else
+                {
+                    int i;
+                    for (i = 0; i < oct->len; i++)
+                        *hash = *hash * 65509 + oct->buf[i];
+                }
             }
         }
         break;
     case Z_RPNStructure_complex:
-        h = get_term_hit(s->u.complex->s1);
+        h = get_term_hit(s->u.complex->s1, hash);
         if (h == -1)
-            h = get_term_hit(s->u.complex->s2);
+            h = get_term_hit(s->u.complex->s2, hash);
         break;
     }
     return h;
@@ -128,7 +134,7 @@ static Odr_int get_term_hit(Z_RPNStructure *s)
 
 /** \brief gets hit count for numeric terms in RPN queries
     \param q RPN Query
-    \return number of hits (random or number for term)
+    \return number of hits
 
     This is just for testing.. A real database of course uses
     the content of a database to establish a value.. In our case, we
@@ -139,12 +145,23 @@ static Odr_int get_hit_count(Z_Query *q)
 {
     if (q->which == Z_Query_type_1 || q->which == Z_Query_type_101)
     {
+        unsigned hash = 0;
         Odr_int h = -1;
-        h = get_term_hit(q->u.type_1->RPNStructure);
+        h = get_term_hit(q->u.type_1->RPNStructure, &hash);
         if (h == -1)
-            h = rand() % 24;
+            h = hash % 24;
         return h;
     }
+    else if (q->which == Z_Query_type_104 &&
+             q->u.type_104->which == Z_External_CQL)
+    {
+        unsigned hash = 0;
+        const char *cql = q->u.type_104->u.cql;
+        int i;
+        for (i = 0; cql[i]; i++)
+            hash = hash * 65509 + cql[i];
+        return hash % 24;
+    }
     else
         return 24;
 }