* Copyright (c) 1995-2003, Index Data
* See the file LICENSE for details.
*
- * $Id: client.c,v 1.194 2003-05-20 19:55:29 adam Exp $
+ * $Id: client.c,v 1.202 2003-07-14 12:59:23 adam Exp $
*/
#include <stdio.h>
#include <yaz/ill.h>
#include <yaz/srw.h>
#include <yaz/yaz-ccl.h>
+#include <yaz/cql.h>
#if HAVE_READLINE_READLINE_H
#include <readline/readline.h>
#define C_PROMPT "Z> "
static char *codeset = 0; /* character set for output */
-
+static int hex_dump = 0;
static ODR out, in, print; /* encoding and decoding streams */
+#if HAVE_XML2
static ODR srw_sr_odr_out = 0;
static Z_SRW_PDU *srw_sr = 0;
+#endif
static FILE *apdu_file = 0;
static FILE *ber_file = 0;
static COMSTACK conn = 0; /* our z-association */
static int setno = 1; /* current set offset */
static enum oid_proto protocol = PROTO_Z3950; /* current app protocol */
static enum oid_value recordsyntax = VAL_USMARC;
-//static enum oid_value schema = VAL_NONE;
static char *schema = 0;
static int sent_close = 0;
static NMEM session_mem = NULL; /* memory handle for init-response */
static char last_scan_line[512] = "0";
static char last_scan_query[512] = "0";
static char ccl_fields[512] = "default.bib";
+/* ### How can I set this path to use wherever YAZ is installed? */
+static char cql_fields[512] = "/usr/local/share/yaz/etc/pqf.properties";
static char *esPackageName = 0;
static char *yazProxy = 0;
static int kilobytes = 1024;
QueryType_Prefix,
QueryType_CCL,
QueryType_CCL2RPN,
- QueryType_CQL
+ QueryType_CQL,
+ QueryType_CQL2RPN
} QueryType;
static QueryType queryType = QueryType_Prefix;
static CCL_bibset bibset; /* CCL bibset handle */
+static cql_transform_t cqltrans; /* CQL qualifier-set handle */
#if HAVE_READLINE_COMPLETION_OVER
case QueryType_CCL: return "CCL (CCL sent to server) ";
case QueryType_CCL2RPN: return "CCL -> RPN (RPN sent to server)";
case QueryType_CQL: return "CQL (CQL sent to server)";
+ case QueryType_CQL2RPN: return "CQL -> RPN (RPN sent to server)";
default:
return "unknown Query type internal yaz-client error";
}
}
-
-void do_hex_dump(char* buf,int len)
+static void do_hex_dump(const char* buf, int len)
{
-#if 0
- int i,x;
- for( i=0; i<len ; i=i+16 )
- {
- printf(" %4.4d ",i);
- for(x=0 ; i+x<len && x<16; ++x)
- {
- printf("%2.2X ",(unsigned int)((unsigned char)buf[i+x]));
- }
- printf("\n");
+ if (hex_dump)
+ {
+ int i,x;
+ for( i=0; i<len ; i=i+16 )
+ {
+ printf(" %4.4d ",i);
+ for(x=0 ; i+x<len && x<16; ++x)
+ {
+ printf("%2.2X ",(unsigned int)((unsigned char)buf[i+x]));
+ }
+ printf("\n");
+ }
}
-#endif
}
void add_otherInfos(Z_APDU *a)
&result, &rlen)> 0)
{
char *from = 0;
- if (marcCharset && strcmp(marcCharset, "auto"))
- from = marcCharset;
- else
+ if (marcCharset && !strcmp(marcCharset, "auto"))
{
if (ent->value == VAL_USMARC)
{
if (octet_buf[9] == 'a')
from = "UTF-8";
else
- from = "MARC8";
+ from = "MARC-8";
}
else
from = "ISO-8859-1";
}
+ else if (marcCharset)
+ from = marcCharset;
if (outputCharset && from)
{
- printf ("convert from %s to %s\n", from,
- outputCharset);
cd = yaz_iconv_open(outputCharset, from);
+ printf ("convert from %s to %s", from,
+ outputCharset);
+ if (!cd)
+ printf (" unsupported\n");
+ else
+ printf ("\n");
}
if (!cd)
fwrite (result, 1, rlen, stdout);
else
{
- char outbuf[12];
+ char outbuf[6];
size_t inbytesleft = rlen;
const char *inp = result;
{
size_t outbytesleft = sizeof(outbuf);
char *outp = outbuf;
- size_t r = yaz_iconv (cd, (char**) &inp,
- &inbytesleft,
- &outp, &outbytesleft);
+ size_t r;
+
+ r = yaz_iconv (cd, (char**) &inp,
+ &inbytesleft,
+ &outp, &outbytesleft);
if (r == (size_t) (-1))
{
int e = yaz_iconv_error(cd);
puts (wrbuf_buf(w));
wrbuf_free(w, 1);
}
+ else if ( /* OPAC display not complete yet .. */
+ ent && ent->value == VAL_OPAC)
+ {
+ int i;
+ if (r->u.opac->bibliographicRecord)
+ display_record(r->u.opac->bibliographicRecord);
+ for (i = 0; i<r->u.opac->num_holdingsData; i++)
+ {
+ Z_HoldingsRecord *h = r->u.opac->holdingsData[i];
+ if (h->which == Z_HoldingsRecord_marcHoldingsRecord)
+ {
+ printf ("MARC holdings %d\n", i);
+ display_record(h->u.marcHoldingsRecord);
+ }
+ else if (h->which == Z_HoldingsRecord_holdingsAndCirc)
+ {
+ int j;
+
+ Z_HoldingsAndCircData *data = h->u.holdingsAndCirc;
+
+ printf ("Data holdings %d\n", i);
+ if (data->typeOfRecord)
+ printf ("typeOfRecord: %s\n", data->typeOfRecord);
+ if (data->encodingLevel)
+ printf ("encodingLevel: %s\n", data->encodingLevel);
+ if (data->receiptAcqStatus)
+ printf ("receiptAcqStatus: %s\n", data->receiptAcqStatus);
+ if (data->generalRetention)
+ printf ("generalRetention: %s\n", data->generalRetention);
+ if (data->completeness)
+ printf ("completeness: %s\n", data->completeness);
+ if (data->dateOfReport)
+ printf ("dateOfReport: %s\n", data->dateOfReport);
+ if (data->nucCode)
+ printf ("nucCode: %s\n", data->nucCode);
+ if (data->localLocation)
+ printf ("localLocation: %s\n", data->localLocation);
+ if (data->shelvingLocation)
+ printf ("shelvingLocation: %s\n", data->shelvingLocation);
+ if (data->callNumber)
+ printf ("callNumber: %s\n", data->callNumber);
+ if (data->copyNumber)
+ printf ("copyNumber: %s\n", data->copyNumber);
+ if (data->publicNote)
+ printf ("publicNote: %s\n", data->publicNote);
+ if (data->reproductionNote)
+ printf ("reproductionNote: %s\n", data->reproductionNote);
+ if (data->termsUseRepro)
+ printf ("termsUseRepro: %s\n", data->termsUseRepro);
+ if (data->enumAndChron)
+ printf ("enumAndChron: %s\n", data->enumAndChron);
+ for (j = 0; j<data->num_volumes; j++)
+ {
+ printf ("volume %d\n", j);
+ if (data->volumes[j]->enumeration)
+ printf (" enumeration: %s\n",
+ data->volumes[j]->enumeration);
+ if (data->volumes[j]->chronology)
+ printf (" chronology: %s\n",
+ data->volumes[j]->chronology);
+ if (data->volumes[j]->enumAndChron)
+ printf (" enumAndChron: %s\n",
+ data->volumes[j]->enumAndChron);
+ }
+ for (j = 0; j<data->num_circulationData; j++)
+ {
+ printf ("circulation %d\n", j);
+ if (data->circulationData[j]->availableNow)
+ printf (" availableNow: %d\n",
+ *data->circulationData[j]->availableNow);
+ if (data->circulationData[j]->availablityDate)
+ printf (" availabiltyDate: %s\n",
+ data->circulationData[j]->availablityDate);
+ if (data->circulationData[j]->availableThru)
+ printf (" availableThru: %s\n",
+ data->circulationData[j]->availableThru);
+ if (data->circulationData[j]->restrictions)
+ printf (" restrictions: %s\n",
+ data->circulationData[j]->restrictions);
+ if (data->circulationData[j]->itemId)
+ printf (" itemId: %s\n",
+ data->circulationData[j]->itemId);
+ if (data->circulationData[j]->renewable)
+ printf (" renewable: %d\n",
+ *data->circulationData[j]->renewable);
+ if (data->circulationData[j]->onHold)
+ printf (" onHold: %d\n",
+ *data->circulationData[j]->onHold);
+ if (data->circulationData[j]->enumAndChron)
+ printf (" enumAndChron: %s\n",
+ data->circulationData[j]->enumAndChron);
+ if (data->circulationData[j]->midspine)
+ printf (" midspine: %s\n",
+ data->circulationData[j]->midspine);
+ if (data->circulationData[j]->temporaryLocation)
+ printf (" temporaryLocation: %s\n",
+ data->circulationData[j]->temporaryLocation);
+ }
+ }
+ }
+ }
else
{
printf("Unknown record representation.\n");
Odr_oct ccl_query;
YAZ_PQF_Parser pqf_parser;
Z_External *ext;
+ QueryType myQueryType = queryType;
+ char pqfbuf[512];
- if (queryType == QueryType_CCL2RPN)
+ if (myQueryType == QueryType_CCL2RPN)
{
rpn = ccl_find_str(bibset, arg, &error, &pos);
if (error)
printf("CCL ERROR: %s\n", ccl_err_msg(error));
return 0;
}
+ } else if (myQueryType == QueryType_CQL2RPN) {
+ /* ### All this code should be wrapped in a utility function */
+ CQL_parser parser;
+ struct cql_node *node;
+ const char *addinfo;
+ if (cqltrans == 0) {
+ printf("Can't use CQL: no translation file. Try set_cqlfile\n");
+ return 0;
+ }
+ parser = cql_parser_create();
+ if ((error = cql_parser_string(parser, arg)) != 0) {
+ printf("Can't parse CQL: must be a syntax error\n");
+ return 0;
+ }
+ node = cql_parser_result(parser);
+ if ((error = cql_transform_buf(cqltrans, node, pqfbuf,
+ sizeof pqfbuf)) != 0) {
+ error = cql_transform_error(cqltrans, &addinfo);
+ printf ("Can't convert CQL to PQF: %s (addinfo=%s)\n",
+ cql_strerror(error), addinfo);
+ return 0;
+ }
+ arg = pqfbuf;
+ myQueryType = QueryType_Prefix;
}
+
req->referenceId = set_refid (out);
if (!strcmp(arg, "@big")) /* strictly for troublemaking */
{
req->query = &query;
- switch (queryType)
+ switch (myQueryType)
{
case QueryType_Prefix:
query.which = Z_Query_type_1;
queryType = QueryType_CCL2RPN;
else if (!strcmp(arg, "cql"))
queryType = QueryType_CQL;
+ else if (!strcmp (arg, "cql2rpn") || !strcmp (arg, "cqlrpn"))
+ queryType = QueryType_CQL2RPN;
else
{
printf ("Querytype must be one of:\n");
printf (" ccl - CCL query\n");
printf (" ccl2rpn - CCL query converted to RPN\n");
printf (" cql - CQL\n");
+ printf (" cql2rpn - CQL query converted to RPN\n");
return 0;
}
return 1;
return 0;
}
+int cmd_set_cqlfile(const char* arg)
+{
+ cql_transform_t newcqltrans;
+
+ if ((newcqltrans = cql_transform_open_fname(arg)) == 0) {
+ perror("unable to open CQL file");
+ return 0;
+ }
+ if (cqltrans != 0)
+ cql_transform_close(cqltrans);
+
+ cqltrans = newcqltrans;
+ strcpy(cql_fields, arg);
+ return 0;
+}
+
int cmd_set_auto_reconnect(const char* arg)
{
if(strlen(arg)==0) {
return 1;
}
-int cmd_set_proxy(const char* arg)
-{
- if(yazProxy) free(yazProxy);
- yazProxy=NULL;
-
- if(strlen(arg) > 1) {
- yazProxy=strdup(arg);
- }
- return 1;
-}
-
/*
this command takes 3 arge {name class oid}
*/
ccl_qual_file (bibset, inf);
fclose (inf);
}
+
+ cqltrans = cql_transform_open_fname(cql_fields);
+ /* If this fails, no problem: we detect cqltrans == 0 later */
+
#if HAVE_READLINE_READLINE_H
rl_attempted_completion_function = (CPPFunction*)readline_completer;
#endif
odr_reset(out);
odr_reset(in); /* release APDU from last round */
record_last = 0;
+ do_hex_dump(netbuffer, res);
odr_setbuf(in, netbuffer, res, 0);
if (!z_GDU(in, &gdu, 0, 0))
fprintf(f, "---------\n");
if (apdu_file)
z_GDU(print, &gdu, 0, 0);
- close_session ();
- break;
+ if (conn && cs_more(conn))
+ continue;
+ break;
}
if (ber_file)
odr_dumpBER(ber_file, netbuffer, res);
/* Query options */
printf("CCL file : %s\n",ccl_fields);
+ printf("CQL file : %s\n",cql_fields);
printf("Query type : %s\n",query_type_as_string(queryType));
printf("Named Result Sets : %s\n",setnumber==-1?"off":"on");
{"set_berfile", cmd_set_berfile, "<filename>",NULL,1,NULL},
{"set_marcdump", cmd_set_marcdump," <filename>",NULL,1,NULL},
{"set_cclfile", cmd_set_cclfile," <filename>",NULL,1,NULL},
+ {"set_cqlfile", cmd_set_cqlfile," <filename>",NULL,1,NULL},
{"set_auto_reconnect", cmd_set_auto_reconnect," on|off",complete_auto_reconnect,1,NULL},
{"set_otherinfo", cmd_set_otherinfo,"<otherinfoinddex> <oid> <string>",NULL,0,NULL},
{"register_oid", cmd_register_oid,"<name> <class> <oid>",NULL,0,NULL},
codeset = nl_langinfo(CODESET);
#endif
#endif
+ if (codeset)
+ outputCharset = xstrdup(codeset);
- while ((ret = options("k:c:a:b:m:v:p:u:t:V", argv, argc, &arg)) != -2)
+ while ((ret = options("k:c:q:a:b:m:v:p:u:t:Vx", argv, argc, &arg)) != -2)
{
switch (ret)
{
strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
ccl_fields[sizeof(ccl_fields)-1] = '\0';
break;
+ case 'q':
+ strncpy (cql_fields, arg, sizeof(cql_fields)-1);
+ cql_fields[sizeof(cql_fields)-1] = '\0';
+ break;
case 'b':
if (!strcmp(arg, "-"))
ber_file=stderr;
else
apdu_file=fopen(arg, "a");
break;
+ case 'x':
+ hex_dump = 1;
+ break;
case 'p':
yazProxy=strdup(arg);
break;
break;
default:
fprintf (stderr, "Usage: %s [-m <marclog>] [ -a <apdulog>] "
- "[-b berdump] [-c cclfields]\n [-p <proxy-addr>] [-u <auth>] "
+ "[-b berdump] [-c cclfields] \n"
+ "[-q cqlfields] [-p <proxy-addr>] [-u <auth>] "
"[-k size] [-V] [<server-addr>]\n",
prog);
exit (1);