From 0edfdd01ae95aa2770f2e122bdea25208494acbd Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 25 Jul 2002 12:52:52 +0000 Subject: [PATCH] Character set negotiation updates --- CHANGELOG | 22 ++++++++ buildconf.sh | 4 +- client/client.c | 44 +++++++++++---- include/yaz/backend.h | 13 ++++- include/yaz/data1.h | 5 +- retrieval/d1_absyn.c | 16 +++++- retrieval/d1_expat.c | 4 +- retrieval/d1_grs.c | 38 +++++++++++-- retrieval/d1_marc.c | 36 +++++++----- retrieval/d1_read.c | 51 +++++++++++++---- retrieval/d1_write.c | 146 ++++++++++++++++++++++++++++--------------------- server/seshigh.c | 43 ++++++++++++++- win/yaz.nsi | 3 +- 13 files changed, 310 insertions(+), 115 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 7042b21..690c9f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,28 @@ Possible compatibility problems with earlier versions marked with '*'. --- 1.8.8 2002/MM/DD +Added three members in bend_initrequest structure to facilitate +character set negotiation. + +Fixed a bug in frontend server that could cause indefinite +loops under rare conditions. + +Revised character set utilities (charneg.h) so that encoding +UCS-4, UCSA-4, UTF-16 and UTF-8 are encoded non-privately. + +For PQF, directive @term sets term type for Scan/Search. +Here is general, string, numeric, null. The term type +is inherited - just like @attr. + +New call odr_set_charset that sets character set conversion for +international-strings on a ODR stream. Prototype is: + int odr_set_charset(ODR o, const char *to, const char *from); +The InternationalString is still represented as C string in YAZ +so native strings of type UTF-8, ASCII, etc. will work (UTF-16 +won't). On the protocol level, you can use any encoding. + +Support for UNIX sockets in ZOOM. + Solaris recv sometimes returns errno == ENOENT. It is treated as EINPROGRESS. COMSTACK patch by Ko van der Sloot. diff --git a/buildconf.sh b/buildconf.sh index bcf0d28..440077e 100755 --- a/buildconf.sh +++ b/buildconf.sh @@ -1,6 +1,6 @@ #!/bin/sh -# $Id: buildconf.sh,v 1.12 2002-05-13 18:34:53 adam Exp $ -aclocal +# $Id: buildconf.sh,v 1.13 2002-07-25 12:52:52 adam Exp $ +aclocal libtoolize --automake --force automake -a autoconf diff --git a/client/client.c b/client/client.c index 8a7424f..ed14f02 100644 --- a/client/client.c +++ b/client/client.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2002, Index Data * See the file LICENSE for details. * - * $Id: client.c,v 1.161 2002-07-12 12:20:34 ja7 Exp $ + * $Id: client.c,v 1.162 2002-07-25 12:52:53 adam Exp $ */ #include @@ -306,10 +306,11 @@ static int process_initResponse(Z_InitResponse *res) char *charset=NULL, *lang=NULL; int selected; - yaz_get_response_charneg(session_mem, p, &charset, &lang, &selected); + yaz_get_response_charneg(session_mem, p, &charset, &lang, + &selected); - printf("Accepted character set : `%s'\n", charset); - printf("Accepted code language : `%s'\n", lang); + printf("Accepted character set : %s\n", charset); + printf("Accepted code language : %s\n", lang ? lang : "none"); printf("Accepted records in ...: %d\n", selected ); } } @@ -901,11 +902,23 @@ static void display_queryExpression (Z_QueryExpression *qe) if (qe->u.term->queryTerm) { Z_Term *term = qe->u.term->queryTerm; - if (term->which == Z_Term_general) + switch (term->which) + { + case Z_Term_general: printf (" %.*s", term->u.general->len, term->u.general->buf); + break; + case Z_Term_characterString: + printf (" %s", term->u.characterString); + break; + case Z_Term_numeric: + printf (" %d", *term->u.numeric); + break; + case Z_Term_null: + printf (" null"); + break; + } } } - } /* see if we can find USR:SearchResult-1 */ @@ -2114,17 +2127,24 @@ int cmd_proxy(char* arg) int cmd_charset(char* arg) { - if (*arg == '\0') { - printf("Current character set is `%s'\n", (yazCharset)?yazCharset:NULL); + char l1[30], l2[30]; + + *l1 = *l2 = 0; + if (sscanf(arg, "%29s %29s", l1, l2) < 1) + { + printf("Current character set is `%s'\n", (yazCharset) ? + yazCharset:NULL); return 1; } xfree (yazCharset); yazCharset = NULL; - if (*arg) + if (*l1) + yazCharset = xstrdup(l1); + if (*l2) { - yazCharset = (char *) xmalloc (strlen(arg)+1); - strcpy (yazCharset, arg); - } + odr_set_charset (out, l1, l2); + odr_set_charset (in, l2, l1); + } return 1; } diff --git a/include/yaz/backend.h b/include/yaz/backend.h index e8d8bc2..a8e6c81 100644 --- a/include/yaz/backend.h +++ b/include/yaz/backend.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-2001, Index Data. + * Copyright (c) 1995-2002, Index Data. * * Permission to use, copy, modify, distribute, and sell this software and * its documentation, in whole or in part, for any purpose, is hereby granted, @@ -24,7 +24,10 @@ * OF THIS SOFTWARE. * * $Log: backend.h,v $ - * Revision 1.14 2002-03-20 14:36:00 adam + * Revision 1.15 2002-07-25 12:52:53 adam + * Character set negotiation updates + * + * Revision 1.14 2002/03/20 14:36:00 adam * Additional Search Info for GFS * * Revision 1.13 2002/03/05 12:45:49 mike @@ -285,6 +288,12 @@ typedef struct bend_initrequest int (*bend_delete)(void *handle, bend_delete_rr *rr); int (*bend_scan)(void *handle, bend_scan_rr *rr); int (*bend_segment)(void *handle, bend_segment_rr *rr); + + ODR decode; /* decoding stream */ + /* character set and language negotiation - see include/yaz/z-charneg.h */ + Z_CharSetandLanguageNegotiation *charneg_request; + Z_External *charneg_response; + } bend_initrequest; typedef struct bend_initresult diff --git a/include/yaz/data1.h b/include/yaz/data1.h index 3c6ada6..b8c78a5 100644 --- a/include/yaz/data1.h +++ b/include/yaz/data1.h @@ -23,7 +23,7 @@ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE * OF THIS SOFTWARE. * - * $Id: data1.h,v 1.13 2002-07-05 16:04:28 adam Exp $ + * $Id: data1.h,v 1.14 2002-07-25 12:52:53 adam Exp $ */ #ifndef DATA1_H @@ -211,6 +211,7 @@ typedef struct data1_absyn data1_marctab *marc; data1_sub_elements *sub_elements; data1_element *main_elements; + char *encoding; } data1_absyn; /* @@ -473,6 +474,8 @@ YAZ_EXPORT int data1_iconv (data1_handle dh, NMEM m, data1_node *n, const char *tocode, const char *fromcode); +YAZ_EXPORT const char *data1_get_encoding (data1_handle dh, data1_node *n); + YAZ_END_CDECL #endif diff --git a/retrieval/d1_absyn.c b/retrieval/d1_absyn.c index 6d9bb23..9e4d41b 100644 --- a/retrieval/d1_absyn.c +++ b/retrieval/d1_absyn.c @@ -4,7 +4,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: d1_absyn.c,v $ - * Revision 1.31 2002-04-04 20:49:46 adam + * Revision 1.32 2002-07-25 12:52:53 adam + * Character set negotiation updates + * + * Revision 1.31 2002/04/04 20:49:46 adam * New functions yaz_is_abspath, yaz_path_fopen_base * * Revision 1.30 2000/12/05 19:07:24 adam @@ -429,6 +432,7 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file) res->name = 0; res->reference = VAL_NONE; res->tagset = 0; + res->encoding = 0; tagset_childp = &res->tagset; res->attset = data1_empty_attset (dh); @@ -769,6 +773,16 @@ data1_absyn *data1_read_absyn (data1_handle dh, const char *file) } marcp = &(*marcp)->next; } + else if (!strcmp(cmd, "encoding")) + { + if (argc != 2) + { + yaz_log(LOG_WARN, "%s:%d: Bad # or args for encoding", + file, lineno); + continue; + } + res->encoding = nmem_strdup (data1_nmem_get(dh), argv[1]); + } else { yaz_log(LOG_WARN, "%s:%d: Unknown directive '%s'", file, lineno, cmd); diff --git a/retrieval/d1_expat.c b/retrieval/d1_expat.c index 556f006..4d09049 100644 --- a/retrieval/d1_expat.c +++ b/retrieval/d1_expat.c @@ -2,7 +2,7 @@ * Copyright (c) 2002, Index Data. * See the file LICENSE for details. * - * $Id: d1_expat.c,v 1.5 2002-07-11 10:39:49 adam Exp $ + * $Id: d1_expat.c,v 1.6 2002-07-25 12:52:53 adam Exp $ */ #if HAVE_EXPAT_H @@ -79,7 +79,7 @@ static void cb_decl (void *user, const char *version, const char*encoding, attr_list[1] = version; attr_list[2] = "encoding"; - attr_list[3] = encoding; + attr_list[3] = "UTF-8"; /* encoding */ attr_list[4] = "standalone"; attr_list[5] = standalone ? "yes" : "no"; diff --git a/retrieval/d1_grs.c b/retrieval/d1_grs.c index cea1dba..5432b0f 100644 --- a/retrieval/d1_grs.c +++ b/retrieval/d1_grs.c @@ -3,7 +3,7 @@ * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: d1_grs.c,v 1.23 2002-07-11 10:40:34 adam Exp $ + * $Id: d1_grs.c,v 1.24 2002-07-25 12:52:53 adam Exp $ * */ @@ -125,7 +125,7 @@ static Z_ElementData *nodetoelementdata(data1_handle dh, data1_node *n, res->which = Z_ElementData_elementNotThere; res->u.elementNotThere = odr_nullval(); } - else if (n->which == DATA1N_data && (leaf || n->next == NULL)) + else if (n->which == DATA1N_data && leaf) { char str[512]; int toget; @@ -144,8 +144,6 @@ static Z_ElementData *nodetoelementdata(data1_handle dh, data1_node *n, break; case DATA1I_text: toget = n->u.data.len; - if (p && p->u.tag.get_bytes > 0 && p->u.tag.get_bytes < toget) - toget = p->u.tag.get_bytes; res->which = Z_ElementData_string; res->u.string = (char *)odr_malloc(o, toget+1); memcpy(res->u.string, n->u.data.data, toget); @@ -173,6 +171,21 @@ static Z_ElementData *nodetoelementdata(data1_handle dh, data1_node *n, return res; } +static int is_empty_data (data1_node *n) +{ + if (n && n->which == DATA1N_data && n->u.data.what == DATA1I_text) + { + int i = n->u.data.len; + + while (i > 0 && n->u.data.data[i-1] == '\n') + i--; + if (i == 0) + return 1; + } + return 0; +} + + static Z_TaggedElement *nodetotaggedelement(data1_handle dh, data1_node *n, int select, ODR o, int *len) @@ -187,7 +200,20 @@ static Z_TaggedElement *nodetotaggedelement(data1_handle dh, data1_node *n, if (n->u.tag.element) tag = n->u.tag.element->tag; data = n->child; - leaf = 0; + + /* skip empty data children */ + while (is_empty_data(data)) + data = data->next; + if (!data) + data = n->child; + else + { /* got one. see if this is the only non-empty one */ + data1_node *sub = data->next; + while (sub && is_empty_data(sub)) + sub = sub->next; + if (!sub) + leaf = 1; /* all empty. 'data' is the only child */ + } } /* * If we're a data element at this point, we need to insert a @@ -204,6 +230,8 @@ static Z_TaggedElement *nodetotaggedelement(data1_handle dh, data1_node *n, } data = n; leaf = 1; + if (is_empty_data(data)) + return 0; } else { diff --git a/retrieval/d1_marc.c b/retrieval/d1_marc.c index fc0127a..bb054ac 100644 --- a/retrieval/d1_marc.c +++ b/retrieval/d1_marc.c @@ -3,7 +3,7 @@ * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: d1_marc.c,v 1.20 2002-07-03 14:09:34 adam Exp $ + * $Id: d1_marc.c,v 1.21 2002-07-25 12:52:53 adam Exp $ */ @@ -144,6 +144,7 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) return res; } + /* * Locate some data under this node. This routine should handle variants * prettily. @@ -151,21 +152,30 @@ data1_marctab *data1_read_marctab (data1_handle dh, const char *file) static char *get_data(data1_node *n, int *len) { char *r; + data1_node *np = 0; - while (n->which != DATA1N_data && n->child) - n = n->child; - if (n->which != DATA1N_data || - (n->u.data.what != DATA1I_text && n->u.data.what != DATA1I_num)) + while (n) { - r = "[Structured/included data]"; - *len = strlen(r); - return r; + if (n->which == DATA1N_data) + { + *len = n->u.data.len; + while (*len && d1_isspace(n->u.data.data[*len - 1])) + (*len)--; + if (*len != 0) + return n->u.data.data; + } + if (n->which == DATA1N_tag) + np = n->child; + n = n->next; + if (!n) + { + n = np; + np = 0; + } } - - *len = n->u.data.len; - while (*len && d1_isspace(n->u.data.data[*len - 1])) - (*len)--; - return n->u.data.data; + r = ""; + *len = strlen(r); + return r; } static void memint (char *p, int val, int len) diff --git a/retrieval/d1_read.c b/retrieval/d1_read.c index e79ad72..4926ec1 100644 --- a/retrieval/d1_read.c +++ b/retrieval/d1_read.c @@ -3,7 +3,7 @@ * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: d1_read.c,v 1.45 2002-07-05 16:04:28 adam Exp $ + * $Id: d1_read.c,v 1.46 2002-07-25 12:52:53 adam Exp $ */ #include @@ -834,7 +834,7 @@ static int conv_item (NMEM m, iconv_t t, } static void data1_iconv_s (data1_handle dh, NMEM m, data1_node *n, - iconv_t t, WRBUF wrbuf) + iconv_t t, WRBUF wrbuf, const char *tocode) { for (; n; n = n->next) { @@ -872,24 +872,55 @@ static void data1_iconv_s (data1_handle dh, NMEM m, data1_node *n, } } break; + case DATA1N_preprocess: + if (strcmp(n->u.preprocess.target, "xml") == 0) + { + data1_xattr *p = n->u.preprocess.attributes; + for (; p; p = p->next) + if (strcmp (p->name, "encoding") == 0) + p->value = nmem_strdup (m, tocode); + } + break; } - data1_iconv_s (dh, m, n->child, t, wrbuf); + data1_iconv_s (dh, m, n->child, t, wrbuf, tocode); } } #endif +const char *data1_get_encoding (data1_handle dh, data1_node *n) +{ + /* see if we have an xml header that specifies encoding */ + if (n && n->child && n->child->which == DATA1N_preprocess && + strcmp (n->child->u.preprocess.target, "xml") == 0) + { + data1_xattr *xp = n->child->u.preprocess.attributes; + for (; xp; xp = xp->next) + if (!strcmp (xp->name, "encoding") == 0) + return xp->value; + } + /* no encoding in header, so see if "encoding" was specified for abs */ + if (n && n->which == DATA1N_root && + n->u.root.absyn && n->u.root.absyn->encoding) + return n->u.root.absyn->encoding; + /* none of above, return a hard coded default */ + return "ISO-8859-1"; +} + int data1_iconv (data1_handle dh, NMEM m, data1_node *n, const char *tocode, const char *fromcode) { #if HAVE_ICONV_H - WRBUF wrbuf = wrbuf_alloc(); - iconv_t t = iconv_open (tocode, fromcode); - if (t == (iconv_t) (-1)) - return -1; - data1_iconv_s (dh, m, n, t, wrbuf); - iconv_close (t); - wrbuf_free (wrbuf, 1); + if (strcmp (tocode, fromcode)) + { + WRBUF wrbuf = wrbuf_alloc(); + iconv_t t = iconv_open (tocode, fromcode); + if (t == (iconv_t) (-1)) + return -1; + data1_iconv_s (dh, m, n, t, wrbuf, tocode); + iconv_close (t); + wrbuf_free (wrbuf, 1); + } return 0; #else return -2; diff --git a/retrieval/d1_write.c b/retrieval/d1_write.c index 1e80c6b..69d8db6 100644 --- a/retrieval/d1_write.c +++ b/retrieval/d1_write.c @@ -3,7 +3,7 @@ * See the file LICENSE for details. * Sebastian Hammer, Adam Dickmeiss * - * $Id: d1_write.c,v 1.14 2002-07-05 12:42:52 adam Exp $ + * $Id: d1_write.c,v 1.15 2002-07-25 12:52:53 adam Exp $ */ #include @@ -24,10 +24,50 @@ static int wordlen(char *b, int max) return l; } -static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col) +static void indent (WRBUF b, int col) +{ + int i; + for (i = 0; i': + wrbuf_puts (b, ">"); + break; + case '<': + wrbuf_puts (b, "<"); + break; +#if 0 + case '&': + wrbuf_puts (b, "&"); + break; +#endif + default: + wrbuf_putc(b, msg[i]); + } + } +} + +static void wrbuf_put_cdata(WRBUF b, const char *msg) +{ + wrbuf_write_cdata (b, msg, strlen(msg)); +} + +static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col, + int pretty_format) { data1_node *c; - char line[1024]; for (c = n->child; c; c = c->next) { @@ -36,25 +76,24 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col) if (c->which == DATA1N_preprocess) { data1_xattr *p; - -#if PRETTY_FORMAT - sprintf (line, "%*s", col, ""); - wrbuf_puts (b, line); -#endif + + if (pretty_format) + indent (b, col); wrbuf_puts (b, "u.preprocess.target); + wrbuf_put_cdata (b, c->u.preprocess.target); for (p = c->u.preprocess.attributes; p; p = p->next) { wrbuf_putc (b, ' '); - wrbuf_puts (b, p->name); + wrbuf_put_cdata (b, p->name); wrbuf_putc (b, '='); wrbuf_putc (b, '"'); - wrbuf_puts (b, p->value); + wrbuf_put_cdata (b, p->value); wrbuf_putc (b, '"'); } if (c->child) wrbuf_puts(b, " "); - if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0) + if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2, + pretty_format) < 0) return -1; wrbuf_puts (b, "?>\n"); } @@ -65,44 +104,39 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col) tag = c->u.tag.tag; if (!data1_matchstr(tag, "wellknown")) /* skip wellknown */ { - if (nodetoidsgml(c, select, b, col) < 0) + if (nodetoidsgml(c, select, b, col, pretty_format) < 0) return -1; } else { data1_xattr *p; -#if PRETTY_FORMAT - sprintf (line, "%*s", col, ""); - wrbuf_puts (b, line); -#endif + if (pretty_format) + indent (b, col); wrbuf_puts (b, "<"); - wrbuf_puts (b, tag); + wrbuf_put_cdata (b, tag); for (p = c->u.tag.attributes; p; p = p->next) { wrbuf_putc (b, ' '); - wrbuf_puts (b, p->name); + wrbuf_put_cdata (b, p->name); wrbuf_putc (b, '='); wrbuf_putc (b, '"'); - wrbuf_puts (b, p->value); + wrbuf_put_cdata (b, p->value); wrbuf_putc (b, '"'); } wrbuf_puts(b, ">"); -#if PRETTY_FORMAT - wrbuf_puts(b, "\n"); -#endif - if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2) < 0) + if (pretty_format) + wrbuf_puts(b, "\n"); + if (nodetoidsgml(c, select, b, (col > 40) ? 40 : col+2, + pretty_format) < 0) return -1; -#if PRETTY_FORMAT - sprintf (line, "%*s", col); - wrbuf_puts(b, line); -#endif + if (pretty_format) + indent (b, col); wrbuf_puts(b, ""); -#if PRETTY_FORMAT - wrbuf_puts (b, "\n"); -#endif + if (pretty_format) + wrbuf_puts (b, "\n"); } } else if (c->which == DATA1N_data || c->which == DATA1N_comment) @@ -112,24 +146,16 @@ static int nodetoidsgml(data1_node *n, int select, WRBUF b, int col) int first = 1; int lcol = col; -#if PRETTY_FORMAT - if (!c->u.data.formatted_text) - { - sprintf(line, "%*s", col, ""); - wrbuf_write(b, line, strlen(line)); - } -#endif + if (pretty_format && !c->u.data.formatted_text) + indent (b, col); if (c->which == DATA1N_comment) - { - wrbuf_write (b, ""); -#if PRETTY_FORMAT - wrbuf_puts(b, "\n"); -#endif + if (pretty_format) + wrbuf_puts(b, "\n"); } } } @@ -200,7 +220,7 @@ char *data1_nodetoidsgml (data1_handle dh, data1_node *n, int select, int *len) wrbuf_rewind(b); - if (nodetoidsgml(n, select, b, 0)) + if (nodetoidsgml(n, select, b, 0, 0 /* no pretty format */)) return 0; *len = wrbuf_len(b); return wrbuf_buf(b); diff --git a/server/seshigh.c b/server/seshigh.c index 2be36c1..a9e17fa 100644 --- a/server/seshigh.c +++ b/server/seshigh.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2002, Index Data * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.130 2002-06-18 21:30:39 adam Exp $ + * $Id: seshigh.c,v 1.131 2002-07-25 12:52:54 adam Exp $ */ /* @@ -46,6 +46,8 @@ #include #include #include +#include +#include #include @@ -358,6 +360,8 @@ void ir_session(IOCHAN h, int event) iochan_clearflag(h, EVENT_OUTPUT|EVENT_INPUT); iochan_setflag(h, assoc->cs_get_mask); } + else + assoc->cs_put_mask = EVENT_OUTPUT; break; default: if (conn->io_pending & CS_WANT_WRITE) @@ -574,7 +578,8 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) Z_APDU *apdu = zget_APDU(assoc->encode, Z_APDU_initResponse); Z_InitResponse *resp = apdu->u.initResponse; bend_initresult *binitres; - char options[100]; + + char options[140]; xfree (assoc->init); assoc->init = (bend_initrequest *) xmalloc (sizeof(*assoc->init)); @@ -602,6 +607,17 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) assoc->init->bend_scan = NULL; assoc->init->bend_segment = NULL; assoc->init->bend_fetch = NULL; + assoc->init->charneg_request = NULL; + assoc->init->charneg_response = NULL; + assoc->init->decode = assoc->decode; + + if (ODR_MASK_GET(req->options, Z_Options_negotiationModel)) + { + Z_CharSetandLanguageNegotiation *negotiation = + yaz_get_charneg_record (req->otherInfo); + if (negotiation->which == Z_CharSetandLanguageNegotiation_proposal) + assoc->init->charneg_request = negotiation; + } assoc->init->peer_name = odr_strdup (assoc->encode, cs_addrstr(assoc->client_link)); @@ -665,13 +681,33 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) if (ODR_MASK_GET(req->options, Z_Options_concurrentOperations)) { ODR_MASK_SET(resp->options, Z_Options_concurrentOperations); - strcat(options, " concurop"); + strcat(options, " concurrop"); } if (ODR_MASK_GET(req->options, Z_Options_sort) && assoc->init->bend_sort) { ODR_MASK_SET(resp->options, Z_Options_sort); strcat(options, " sort"); } + + if (ODR_MASK_GET(req->options, Z_Options_negotiationModel) + && assoc->init->charneg_response) + { + Z_OtherInformation **p; + Z_OtherInformationUnit *p0; + + yaz_oi_APDU(apdu, &p); + + if ((p0=yaz_oi_update(p, assoc->encode, NULL, 0, 0))) { + ODR_MASK_SET(resp->options, Z_Options_negotiationModel); + + p0->which = Z_OtherInfo_externallyDefinedInfo; + p0->information.externallyDefinedInfo = + assoc->init->charneg_response; + } + ODR_MASK_SET(resp->options, Z_Options_negotiationModel); + strcat(options, " negotiation"); + } + if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1)) { ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1); @@ -687,6 +723,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_3); assoc->version = 3; } + yaz_log(LOG_LOG, "Negotiated to v%d: %s", assoc->version, options); assoc->maximumRecordSize = *req->maximumRecordSize; if (assoc->maximumRecordSize > control_block->maxrecordsize) diff --git a/win/yaz.nsi b/win/yaz.nsi index 8eb4fa5..3e37755 100644 --- a/win/yaz.nsi +++ b/win/yaz.nsi @@ -1,4 +1,4 @@ -; $Id: yaz.nsi,v 1.8 2002-06-05 21:10:16 adam Exp $ +; $Id: yaz.nsi,v 1.9 2002-07-25 12:52:54 adam Exp $ !define VERSION "1.8.8" @@ -98,6 +98,7 @@ Section "YAZ Source" File ..\util\*.tcl SetOutPath $INSTDIR\odr File ..\odr\*.c + File ..\odr\*.h SetOutPath $INSTDIR\z39.50 File ..\z39.50\*.c File ..\z39.50\*.asn -- 1.7.10.4