* Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: client.c,v 1.323 2007-01-16 14:12:37 adam Exp $
+ * $Id: client.c,v 1.340 2007-05-30 08:12:16 adam Exp $
*/
/** \file client.c
* \brief yaz-client program
#include <assert.h>
#include <time.h>
#include <ctype.h>
+#ifndef WIN32
+#include <signal.h>
+#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <yaz/comstack.h>
+#include <yaz/oid_db.h>
+#define NO_OID 1
#include <yaz/proto.h>
#include <yaz/marcdisp.h>
#include <yaz/diagbib1.h>
#include "admin.h"
#include "tabcomplete.h"
+#include "fhistory.h"
#define C_PROMPT "Z> "
+static file_history_t file_history = 0;
+
static char *sru_method = "soap";
static char *codeset = 0; /* character set for output */
static int hex_dump = 0;
static int setno = 1; /* current set offset */
static enum oid_proto protocol = PROTO_Z3950; /* current app protocol */
#define RECORDSYNTAX_MAX 20
-static enum oid_value recordsyntax_list[RECORDSYNTAX_MAX] = { VAL_USMARC };
-static int recordsyntax_size = 1;
+static char *recordsyntax_list[RECORDSYNTAX_MAX];
+static int recordsyntax_size = 0;
static char *record_schema = 0;
static int sent_close = 0;
static QueryType queryType = QueryType_Prefix;
static CCL_bibset bibset; /* CCL bibset handle */
-static cql_transform_t cqltrans; /* CQL context-set handle */
+static cql_transform_t cqltrans = 0; /* CQL context-set handle */
#if HAVE_READLINE_COMPLETION_OVER
#define AVOID_MARC_DECODE 1
#define maxOtherInfosSupported 10
-struct {
- int oidval;
+struct eoi {
+ Odr_oid oid[OID_SIZE];
char* value;
} extraOtherInfos[maxOtherInfosSupported];
-
void process_cmd_line(char* line);
#if HAVE_READLINE_READLINE_H
yaz_oi_APDU(a, &oi);
for(i=0; i<maxOtherInfosSupported; ++i)
{
- if(extraOtherInfos[i].oidval != -1)
- yaz_oi_set_string_oidval(oi, out, extraOtherInfos[i].oidval,
+ if (oid_oidlen(extraOtherInfos[i].oid) > 0)
+ yaz_oi_set_string_oid(oi, out, extraOtherInfos[i].oid,
1, extraOtherInfos[i].value);
}
}
req->referenceId = set_refid (out);
- if (yazProxy && type_and_host)
- yaz_oi_set_string_oidval(&req->otherInfo, out, VAL_PROXY,
- 1, type_and_host);
+ if (yazProxy && type_and_host)
+ {
+ yaz_oi_set_string_oid(&req->otherInfo, out, yaz_oid_userinfo_proxy,
+ 1, type_and_host);
+ }
if (negotiationCharset || yazLang) {
Z_OtherInformation **p;
yaz_oi_APDU(apdu, &p);
- if ((p0=yaz_oi_update(p, out, NULL, 0, 0))) {
+ if ((p0=yaz_oi_update(p, out, NULL, 0, 0)))
+ {
ODR_MASK_SET(req->options, Z_Options_negotiationModel);
p0->which = Z_OtherInfo_externallyDefinedInfo;
negotiationCharsetRecords);
}
}
-
if (send_apdu(apdu))
printf("Sent initrequest.\n");
}
else if (uif->which == Z_External_single)
{
Odr_any *sat = uif->u.single_ASN1_type;
- oident *oid = oid_getentbyoid(uif->direct_reference);
- if (oid->value == VAL_OCLCUI) {
+ if (!oid_oidcmp(uif->direct_reference,
+ yaz_oid_userinfo_oclc_userinfo))
+ {
Z_OCLC_UserInformation *oclc_ui;
ODR decode = odr_createmem(ODR_DECODE);
odr_setbuf(decode, (char *) sat->buf, sat->len, 0);
Z_CharSetandLanguageNegotiation *p =
yaz_get_charneg_record(res->otherInfo);
-
+
if (p) {
char *charset=NULL, *lang=NULL;
yaz_get_response_charneg(session_mem, p, &charset, &lang,
&selected);
+ printf("Accepted character set : %s\n", charset);
+ printf("Accepted code language : %s\n", lang ? lang : "none");
+ printf("Accepted records in ...: %d\n", selected );
+
if (outputCharset && negotiationCharset) {
- odr_set_charset (out, charset, outputCharset);
- odr_set_charset (in, outputCharset, charset);
+ printf("Converting between %s and %s\n",
+ outputCharset, negotiationCharset);
+ odr_set_charset (out, charset, outputCharset);
+ odr_set_charset (in, outputCharset, charset);
}
else {
- odr_set_charset (out, 0, 0);
- odr_set_charset (in, 0, 0);
+ odr_set_charset (out, 0, 0);
+ odr_set_charset (in, 0, 0);
}
-
- printf("Accepted character set : %s\n", charset);
- printf("Accepted code language : %s\n", lang ? lang : "none");
- printf("Accepted records in ...: %d\n", selected );
}
}
fflush (stdout);
return 0;
}
*len = fsize;
- *buf = odr_malloc(out, fsize);
+ *buf = (char *) odr_malloc(out, fsize);
if (fread(*buf, 1, fsize, inf) != fsize)
{
printf("Unable to read %s\n", fname);
static void display_record(Z_External *r)
{
- oident *ent = oid_getentbyoid(r->direct_reference);
-
+ const Odr_oid *oid = r->direct_reference;
+
record_last = r;
/*
* Tell the user what we got.
*/
- if (r->direct_reference)
+ if (oid)
{
+ oid_class oclass;
+ char oid_name_buf[OID_STR_MAX];
+ const char *oid_name
+ = yaz_oid_to_string_buf(oid, &oclass, oid_name_buf);
printf("Record type: ");
- if (ent)
- printf("%s\n", ent->desc);
- else if (!odr_oid(print, &r->direct_reference, 0, 0))
- {
- odr_perror(print, "print oid");
- odr_reset(print);
- }
+ if (oid_name)
+ printf("%s\n", oid_name);
}
/* Check if this is a known, ASN.1 type tucked away in an octet string */
- if (ent && r->which == Z_External_octet)
+ if (r->which == Z_External_octet)
{
- Z_ext_typeent *type = z_ext_getentbyref(ent->value);
+ Z_ext_typeent *type = z_ext_getentbyref(r->direct_reference);
char *rr;
if (type)
}
}
}
- if (ent && ent->value == VAL_SOIF)
+ if (oid && !oid_oidcmp(oid, yaz_oid_recsyn_soif))
{
print_record((const unsigned char *) r->u.octet_aligned->buf,
r->u.octet_aligned->len);
if (marc_file)
fwrite (r->u.octet_aligned->buf, 1, r->u.octet_aligned->len, marc_file);
}
- else if (r->which == Z_External_octet)
+ else if (oid && r->which == Z_External_octet)
{
const char *octet_buf = (char*)r->u.octet_aligned->buf;
- if (ent->oclass == CLASS_RECSYN &&
- (ent->value == VAL_TEXT_XML ||
- ent->value == VAL_APPLICATION_XML ||
- ent->value == VAL_HTML))
+ if (oid && (!oid_oidcmp(oid, yaz_oid_recsyn_xml)
+ || !oid_oidcmp(oid, yaz_oid_recsyn_xml)
+ || !oid_oidcmp(oid, yaz_oid_recsyn_html)))
{
print_record((const unsigned char *) octet_buf,
r->u.octet_aligned->len);
}
- else if (ent->value == VAL_POSTSCRIPT)
+ else if (oid && !oid_oidcmp(oid, yaz_oid_recsyn_postscript))
{
int size = r->u.octet_aligned->len;
if (size > 100)
}
else
{
- if (
-#if AVOID_MARC_DECODE
- /* primitive check for a marc OID 5.1-29 except 16 */
- ent->oidsuffix[0] == 5 && ent->oidsuffix[1] < 30 &&
- ent->oidsuffix[1] != 16
-#else
- 1
-#endif
- )
+ if (oid && yaz_oid_is_iso2709(oid))
{
- char *result;
- int rlen;
+ const char *result;
+ size_t rlen;
yaz_iconv_t cd = 0;
yaz_marc_t mt = yaz_marc_create();
-
- if (yaz_marc_decode_buf(mt, octet_buf,r->u.octet_aligned->len,
- &result, &rlen)> 0)
+ const char *from = 0;
+
+ if (marcCharset && !strcmp(marcCharset, "auto"))
{
- char *from = 0;
- if (marcCharset && !strcmp(marcCharset, "auto"))
+ if (!oid_oidcmp(oid, yaz_oid_recsyn_usmarc))
{
- if (ent->value == VAL_USMARC)
- {
- if (octet_buf[9] == 'a')
- from = "UTF-8";
- else
- from = "MARC-8";
- }
- else
- from = "ISO-8859-1";
- }
- else if (marcCharset)
- from = marcCharset;
- if (outputCharset && from)
- {
- cd = yaz_iconv_open(outputCharset, from);
- printf ("convert from %s to %s", from,
- outputCharset);
- if (!cd)
- printf (" unsupported\n");
+ if (octet_buf[9] == 'a')
+ from = "UTF-8";
else
- printf ("\n");
+ from = "MARC-8";
}
+ else
+ from = "ISO-8859-1";
+ }
+ else if (marcCharset)
+ from = marcCharset;
+ if (outputCharset && from)
+ {
+ cd = yaz_iconv_open(outputCharset, from);
+ printf ("convert from %s to %s", from,
+ outputCharset);
if (!cd)
- fwrite (result, 1, rlen, stdout);
+ printf (" unsupported\n");
else
{
- char outbuf[6];
- size_t inbytesleft = rlen;
- const char *inp = result;
-
- while (inbytesleft)
- {
- size_t outbytesleft = sizeof(outbuf);
- char *outp = outbuf;
- size_t r;
-
- r = yaz_iconv (cd, (char**) &inp,
- &inbytesleft,
- &outp, &outbytesleft);
- if (r == (size_t) (-1))
- {
- int e = yaz_iconv_error(cd);
- if (e != YAZ_ICONV_E2BIG)
- break;
- }
- fwrite (outbuf, outp - outbuf, 1, stdout);
- }
+ yaz_marc_iconv(mt, cd);
+ printf ("\n");
}
}
+
+ if (yaz_marc_decode_buf(mt, octet_buf, r->u.octet_aligned->len,
+ &result, &rlen)> 0)
+ {
+ fwrite (result, rlen, 1, stdout);
+ }
else
{
printf ("bad MARC. Dumping as it is:\n");
if (marc_file)
fwrite (octet_buf, 1, r->u.octet_aligned->len, marc_file);
}
- else if (ent && ent->value == VAL_SUTRS)
+ else if (oid && !oid_oidcmp(oid, yaz_oid_recsyn_sutrs))
{
if (r->which != Z_External_sutrs)
{
if (marc_file)
fwrite (r->u.sutrs->buf, 1, r->u.sutrs->len, marc_file);
}
- else if (ent && ent->value == VAL_GRS1)
+ else if (oid && !oid_oidcmp(oid, yaz_oid_recsyn_grs_1))
{
WRBUF w;
if (r->which != Z_External_grs1)
}
w = wrbuf_alloc();
yaz_display_grs1(w, r->u.grs1, 0);
- puts (wrbuf_buf(w));
- wrbuf_free(w, 1);
+ puts (wrbuf_cstr(w));
+ wrbuf_destroy(w);
}
- else if (ent && ent->value == VAL_OPAC)
+ else if (oid && !oid_oidcmp(oid, yaz_oid_recsyn_opac))
{
int i;
if (r->u.opac->bibliographicRecord)
static void display_diagrecs(Z_DiagRec **pp, int num)
{
int i;
- oident *ent;
Z_DefaultDiagFormat *r;
printf("Diagnostic message(s) from database:\n");
}
else
r = p->u.defaultFormat;
- if (!(ent = oid_getentbyoid(r->diagnosticSetId)) ||
- ent->oclass != CLASS_DIAGSET || ent->value != VAL_BIB1)
- printf("Missing or unknown diagset\n");
+
+ if (!r->diagnosticSetId)
+ printf("Missing diagset\n");
+ else
+ {
+ oid_class oclass;
+ char diag_name_buf[OID_STR_MAX];
+ const char *diag_name = 0;
+ diag_name = yaz_oid_to_string_buf
+ (r->diagnosticSetId, &oclass, diag_name_buf);
+ if (oid_oidcmp(r->diagnosticSetId, yaz_oid_diagset_bib_1))
+ printf("Unknown diagset: %s\n", diag_name);
+ }
printf(" [%d] %s", *r->condition, diagbib1_str(*r->condition));
switch (r->which)
{
Z_GDU *gdu;
char *path = 0;
- path = odr_malloc(out, 2+strlen(databaseNames[0]));
+ path = (char *) odr_malloc(out, 2+strlen(databaseNames[0]));
*path = '/';
strcpy(path+1, databaseNames[0]);
cd = yaz_iconv_open("UTF-8", in_charset);
if (!cd)
{
- wrbuf_free(w, 1);
+ wrbuf_destroy(w);
return odr_strdup(o, q);
}
wrbuf_iconv_write(w, cd, q, strlen(q));
if (wrbuf_len(w))
- {
- int len = wrbuf_len(w);
- res = odr_strdupn(o, wrbuf_buf(w), len);
- }
+ res = odr_strdup(o, wrbuf_cstr(w));
else
res = odr_strdup(o, q);
yaz_iconv_close(cd);
- wrbuf_free(w, 1);
+ wrbuf_destroy(w);
return res;
}
if (record_schema)
sr->u.request->recordSchema = record_schema;
- if (recordsyntax_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML)
+ if (recordsyntax_size == 1 && !yaz_matchstr(recordsyntax_list[0], "xml"))
sr->u.request->recordPacking = "xml";
return send_srw(sr);
}
if (smallSetUpperBound > 0 || (largeSetLowerBound > 1 &&
mediumSetPresentNumber > 0))
{
- if (recordsyntax_size > 0)
+ if (recordsyntax_size)
req->preferredRecordSyntax =
- yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax_list[0]);
+ yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_RECSYN, recordsyntax_list[0], out);
+
req->smallSetElementSetNames =
req->mediumSetElementSetNames = elementSetNames;
}
{
if (pOid != NULL)
{
- int *pInt = pOid;
+ Odr_oid *pInt = pOid;
print_level(iLevel);
printf("%s:", pTag);
}
else
{
- oident oid;
-
- item_request_buf = odr_getbuf (out, &item_request_size, 0);
- oid.proto = PROTO_GENERAL;
- oid.oclass = CLASS_GENERAL;
- oid.value = VAL_ISO_ILL_1;
-
r = (Z_External *) odr_malloc (out, sizeof(*r));
- r->direct_reference = odr_oiddup(out,oid_getoidbyent(&oid));
+ r->direct_reference = odr_oiddup(out, yaz_oid_general_isoill_1);
r->indirect_reference = 0;
r->descriptor = 0;
r->which = Z_External_single;
}
else
{
- oident oid;
ill_request_buf = odr_getbuf (out, &ill_request_size, 0);
- oid.proto = PROTO_GENERAL;
- oid.oclass = CLASS_GENERAL;
- oid.value = VAL_ISO_ILL_1;
-
r = (Z_External *) odr_malloc (out, sizeof(*r));
- r->direct_reference = odr_oiddup(out,oid_getoidbyent(&oid));
+ r->direct_reference = odr_oiddup(out, yaz_oid_general_isoill_1);
r->indirect_reference = 0;
r->descriptor = 0;
r->which = Z_External_single;
static Z_External *create_ItemOrderExternal(const char *type, int itemno)
{
Z_External *r = (Z_External *) odr_malloc(out, sizeof(Z_External));
- oident ItemOrderRequest;
-
- ItemOrderRequest.proto = PROTO_Z3950;
- ItemOrderRequest.oclass = CLASS_EXTSERV;
- ItemOrderRequest.value = VAL_ITEMORDER;
-
- r->direct_reference = odr_oiddup(out,oid_getoidbyent(&ItemOrderRequest));
+ r->direct_reference = odr_oiddup(out, yaz_oid_extserv_item_order);
r->indirect_reference = 0;
r->descriptor = 0;
}
else if (!strcmp(type, "xml") || !strcmp(type, "3"))
{
- const char *xml_buf =
- "<itemorder>\n"
- " <type>request</type>\n"
- " <libraryNo>000200</libraryNo>\n"
- " <borrowerTicketNo> 1212 </borrowerTicketNo>\n"
- "</itemorder>";
+ const char *xml_buf =
+ "<itemorder>\n"
+ " <type>request</type>\n"
+ " <libraryNo>000200</libraryNo>\n"
+ " <borrowerTicketNo> 1212 </borrowerTicketNo>\n"
+ "</itemorder>";
r->u.itemOrder->u.esRequest->notToKeep->itemRequest =
- z_ext_record (out, VAL_TEXT_XML, xml_buf, strlen(xml_buf));
+ z_ext_record_oid(out, yaz_oid_recsyn_xml, xml_buf, strlen(xml_buf));
}
else
r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 0;
{
Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest);
Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
- oident ItemOrderRequest;
-
req->referenceId = set_refid (out);
- ItemOrderRequest.proto = PROTO_Z3950;
- ItemOrderRequest.oclass = CLASS_EXTSERV;
- ItemOrderRequest.value = VAL_ITEMORDER;
- req->packageType = odr_oiddup(out,oid_getoidbyent(&ItemOrderRequest));
+ req->packageType = odr_oiddup(out, yaz_oid_extserv_item_order);
req->packageName = esPackageName;
req->taskSpecificParameters = create_ItemOrderExternal(type, itemno);
static int cmd_update_common(const char *arg, int version)
{
- char action[20], recid[20];
+ char action[20], recid_buf[20];
+ const char *recid = 0;
char *rec_buf;
int rec_len;
int action_no;
int noread = 0;
*action = 0;
- *recid = 0;
- sscanf (arg, "%19s %19s%n", action, recid, &noread);
+ *recid_buf = 0;
+ sscanf (arg, "%19s %19s%n", action, recid_buf, &noread);
if (noread == 0)
{
- printf("Update must be followed by action and recid\n");
+ printf("Use: update action recid [fname]\n");
printf(" where action is one of insert,replace,delete.update\n");
- printf(" recid is some record ID (any string)\n");
+ printf(" recid is some record ID. Use none for no ID\n");
+ printf(" fname is file of record to be updated\n");
return 0;
}
return 0;
}
+ if (strcmp(recid_buf, "none")) /* none means no record ID */
+ recid = recid_buf;
+
arg += noread;
if (parse_cmd_doc(&arg, out, &rec_buf, &rec_len, 1) == 0)
return 0;
Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
Z_External *r;
Z_External *record_this = 0;
-
if (rec_buf)
- record_this = z_ext_record (out, VAL_TEXT_XML, rec_buf, rec_len);
+ record_this = z_ext_record_oid(out, yaz_oid_recsyn_xml,
+ rec_buf, rec_len);
else
{
if (!record_last)
record_this = record_last;
}
- req->packageType =
- yaz_oidval_to_z3950oid(out, CLASS_EXTSERV,
- version == 0 ? VAL_DBUPDATE0 : VAL_DBUPDATE);
+ req->packageType = odr_oiddup(out, (version == 0 ?
+ yaz_oid_extserv_database_update_first_version :
+ yaz_oid_extserv_database_update));
req->packageName = esPackageName;
notToKeep->elements[0] = (Z_IU0SuppliedRecords_elem *)
odr_malloc(out, sizeof(**notToKeep->elements));
notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
- if (*recid && strcmp(recid, "none"))
+ if (recid)
{
notToKeep->elements[0]->u.opaque = (Odr_oct *)
odr_malloc (out, sizeof(Odr_oct));
notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *)
odr_malloc(out, sizeof(**notToKeep->elements));
notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
- if (*recid)
+ if (recid)
{
notToKeep->elements[0]->u.opaque = (Odr_oct *)
odr_malloc (out, sizeof(Odr_oct));
{
char *asn_buf = 0;
int noread = 0;
+ Odr_oid *oid;
char oid_str[51];
- int oid_value_xmles = VAL_XMLES;
Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest);
Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
return 0;
}
arg += noread;
- oid_value_xmles = oid_getvalbyname(oid_str);
- if (oid_value_xmles == VAL_NONE)
- {
- printf("Bad OID: %s\n", oid_str);
- return 0;
- }
-
if (parse_cmd_doc(&arg, out, &asn_buf,
&ext->u.single_ASN1_type->len, 0) == 0)
return 0;
ext->u.single_ASN1_type->buf = (unsigned char *) asn_buf;
- req->packageType = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV,
- oid_value_xmles);
+ oid = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_EXTSERV, oid_str, out);
+ if (!oid)
+ {
+ printf("Bad OID: %s\n", oid_str);
+ return 0;
+ }
+
+ req->packageType = oid;
- ext->direct_reference = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV,
- oid_value_xmles);
+ ext->direct_reference = oid;
+
send_apdu(apdu);
return 2;
/* save this for later .. when fetching individual records */
sr = yaz_srw_get(out, Z_SRW_explain_request);
- if (recordsyntax_size > 0 && recordsyntax_list[0] == VAL_TEXT_XML)
+ if (recordsyntax_size == 1
+ && !yaz_matchstr(recordsyntax_list[0], "xml"))
sr->u.explain_request->recordPacking = "xml";
send_srw(sr);
return 2;
req->resultSetStartPoint = &setno;
req->numberOfRecordsRequested = &nos;
- if (recordsyntax_size == 1)
+ if (recordsyntax_size)
req->preferredRecordSyntax =
- yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax_list[0]);
+ yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_RECSYN, recordsyntax_list[0], out);
if (record_schema || recordsyntax_size >= 2)
{
else
{
compo.u.complex->generic->schema.oid =
- yaz_str_to_z3950oid(out, CLASS_SCHEMA, record_schema);
+ yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_SCHEMA, record_schema, out);
if (!compo.u.complex->generic->schema.oid)
{
/* OID wasn't a schema! Try record syntax instead. */
compo.u.complex->generic->schema.oid = (Odr_oid *)
- yaz_str_to_z3950oid(out, CLASS_RECSYN, record_schema);
+ yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_RECSYN, record_schema, out);
}
}
if (!elementSetNames)
}
compo.u.complex->num_dbSpecific = 0;
compo.u.complex->dbSpecific = 0;
+
+ compo.u.complex->num_recordSyntax = 0;
+ compo.u.complex->recordSyntax = 0;
if (recordsyntax_size >= 2)
{
int i;
odr_malloc(out, recordsyntax_size * sizeof(Odr_oid*));
for (i = 0; i < recordsyntax_size; i++)
compo.u.complex->recordSyntax[i] =
- yaz_oidval_to_z3950oid(out, CLASS_RECSYN,
- recordsyntax_list[i]);
- }
- else
- {
- compo.u.complex->num_recordSyntax = 0;
- compo.u.complex->recordSyntax = 0;
+ yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_RECSYN, recordsyntax_list[i], out);
}
}
else if (elementSetNames)
sr->u.request->maximumRecords = odr_intdup(out, nos);
if (record_schema)
sr->u.request->recordSchema = record_schema;
- if (recordsyntax_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML)
+ if (recordsyntax_size == 1 && !yaz_matchstr(recordsyntax_list[0], "xml"))
sr->u.request->recordPacking = "xml";
return send_srw(sr);
}
return 2;
}
+void exit_client(int code)
+{
+ file_history_save(file_history);
+ file_history_destroy(&file_history);
+ exit(code);
+}
+
int cmd_quit(const char *arg)
{
printf("See you later, alligator.\n");
xmalloc_trav ("");
- exit(0);
+ exit_client(0);
return 0;
}
return fres;
}
-int send_scanrequest(const char *query, int pp, int num, const char *term)
+int send_scanrequest(const char *set, const char *query,
+ int pp, int num, const char *term)
{
Z_APDU *apdu = zget_APDU(out, Z_APDU_scanRequest);
Z_ScanRequest *req = apdu->u.scanRequest;
return -1;
}
req->attributeSet =
- yaz_oidval_to_z3950oid(out, CLASS_ATTSET, VAL_BIB1);
+ yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_ATTSET, "Bib-1", out);
if (!(req->termListAndStartPoint = ccl_scan_query (out, rpn)))
{
printf("Couldn't convert CCL to Scan term\n");
req->numberOfTermsRequested = #
req->preferredPositionInResponse = &pp;
req->stepSize = odr_intdup(out, scan_stepSize);
+
+ if (set)
+ yaz_oi_set_string_oid(&req->otherInfo, out,
+ yaz_oid_userinfo_scan_set, 1, set);
+
send_apdu(apdu);
return 2;
}
return 0;
}
-int cmd_scan(const char *arg)
+static int cmd_scan_common(const char *set, const char *arg)
{
if (protocol == PROTO_HTTP)
{
if (*arg)
{
strcpy (last_scan_query, arg);
- if (send_scanrequest(arg, scan_position, scan_size, 0) < 0)
+ if (send_scanrequest(set, arg,
+ scan_position, scan_size, 0) < 0)
return 0;
}
else
{
- if (send_scanrequest(last_scan_query, 1, scan_size, last_scan_line) < 0)
+ if (send_scanrequest(set, last_scan_query,
+ 1, scan_size, last_scan_line) < 0)
return 0;
}
return 2;
}
}
+int cmd_scan(const char *arg)
+{
+ return cmd_scan_common(0, arg);
+}
+
+int cmd_setscan(const char *arg)
+{
+ char setstring[100];
+ int nor;
+ if (sscanf(arg, "%99s%n", setstring, &nor) < 1)
+ {
+ printf("missing set for setscan\n");
+ return 0;
+ }
+ return cmd_scan_common(setstring, arg + nor);
+}
+
int cmd_schema(const char *arg)
{
xfree(record_schema);
const char *cp = arg;
int nor;
int idx = 0;
- oid_value nsyntax[RECORDSYNTAX_MAX];
+ int i;
char form_str[41];
if (!arg || !*arg)
{
printf("Usage: format <recordsyntax>\n");
return 0;
}
+ for (i = 0; i < recordsyntax_size; i++)
+ {
+ xfree(recordsyntax_list[i]);
+ recordsyntax_list[i] = 0;
+ }
+
while (sscanf(cp, "%40s%n", form_str, &nor) >= 1 && nor > 0
&& idx < RECORDSYNTAX_MAX)
{
- nsyntax[idx] = oid_getvalbyname(form_str);
if (!strcmp(form_str, "none"))
break;
- if (nsyntax[idx] == VAL_NONE)
- {
- printf ("unknown record syntax: %s\n", form_str);
- return 0;
- }
+ recordsyntax_list[idx] = xstrdup(form_str);
cp += nor;
idx++;
}
recordsyntax_size = idx;
- memcpy(recordsyntax_list, nsyntax, idx * sizeof(*nsyntax));
return 1;
}
return 1;
}
-int cmd_attributeset(const char *arg)
-{
- char what[100];
-
- if (!arg || !*arg)
- {
- printf("Usage: attributeset <setname>\n");
- return 0;
- }
- sscanf(arg, "%s", what);
- if (p_query_attset (what))
- {
- printf("Unknown attribute set name\n");
- return 0;
- }
- return 1;
-}
-
int cmd_querytype (const char *arg)
{
if (!strcmp (arg, "ccl"))
{0,(enum oid_class) 0}
};
char oname_str[101], oclass_str[101], oid_str[101];
- char* name;
int i;
oid_class oidclass = CLASS_GENERAL;
- int val = 0, oid[OID_SIZE];
- struct oident * new_oident=NULL;
-
+ Odr_oid oid[OID_SIZE];
+
if (sscanf (args, "%100[^ ] %100[^ ] %100s",
oname_str,oclass_str, oid_str) < 1) {
printf("Error in register command \n");
return 0;
}
- i = 0;
- name = oid_str;
- val = 0;
-
- while (isdigit (*(unsigned char *) name))
- {
- val = val*10 + (*name - '0');
- name++;
- if (*name == '.')
- {
- if (i < OID_SIZE-1)
- oid[i++] = val;
- val = 0;
- name++;
- }
- }
- oid[i] = val;
- oid[i+1] = -1;
-
- new_oident = oid_addent (oid, PROTO_GENERAL, oidclass, oname_str,
- VAL_DYNAMIC);
- if(strcmp(new_oident->desc,oname_str))
+ oid_dotstring_to_oid(oid_str, oid);
+
+ if (yaz_oid_add(yaz_oid_std(), oidclass, oname_str, oid))
{
- fprintf(stderr,"oid is already named as %s, registration failed\n",
- new_oident->desc);
+ printf("oid %s already exists, registration failed\n",
+ oname_str);
}
return 1;
}
{
/* Look for a $HOME/.yazclientrc and source it if it exists */
struct stat statbuf;
- char buffer[1000];
- char* homedir=getenv("HOME");
+ char fname[1000];
+ char* homedir = getenv("HOME");
- if( homedir ) {
-
- sprintf(buffer,"%s/.yazclientrc",homedir);
+ sprintf(fname, "%.500s%s%s", homedir ? homedir : "",
+ homedir ? "/" : "",
+ ".yazclientrc");
- if(stat(buffer,&statbuf)==0) {
- cmd_source(buffer, 0 );
- }
-
- };
-
- if(stat(".yazclientrc",&statbuf)==0) {
- cmd_source(".yazclientrc", 0 );
- }
+ if (stat(fname,&statbuf)==0)
+ cmd_source(fname, 0 );
}
+void add_to_readline_history(void *client_data, const char *line)
+{
+#if HAVE_READLINE_HISTORY_H
+ if (strlen(line))
+ add_history(line);
+#endif
+}
static void initialize(void)
{
fprintf(stderr, "failed to allocate ODR streams\n");
exit(1);
}
- oid_init();
setvbuf(stdout, 0, _IONBF, 0);
if (apdu_file)
/* If this fails, no problem: we detect cqltrans == 0 later */
#if HAVE_READLINE_READLINE_H
- rl_attempted_completion_function = (CPPFunction*)readline_completer;
+ rl_attempted_completion_function =
+ (char **(*)(const char *, int, int)) readline_completer;
#endif
for(i = 0; i < maxOtherInfosSupported; ++i) {
- extraOtherInfos[i].oidval = -1;
+ extraOtherInfos[i].oid[0] = -1;
+ extraOtherInfos[i].value = 0;
}
+
+ cmd_format("usmarc");
source_rcfile();
+
+ file_history = file_history_new();
+ file_history_load(file_history);
+ file_history_trav(file_history, 0, add_to_readline_history);
}
static void http_response(Z_HTTP_Response *hres)
{
int ret = -1;
- const char *content_type = z_HTTP_header_lookup(hres->headers,
- "Content-Type");
const char *connection_head = z_HTTP_header_lookup(hres->headers,
"Connection");
- if (content_type && !yaz_strcmp_del("text/xml", content_type, "; "))
+ if (!yaz_srw_check_content_type(hres))
+ printf("Content type does not appear to be XML");
+ else
{
Z_SOAP *soap_package = 0;
ODR o = odr_createmem(ODR_DECODE);
soap_handlers);
if (!ret && soap_package->which == Z_SOAP_generic)
{
- Z_SRW_PDU *sr = soap_package->u.generic->p;
+ Z_SRW_PDU *sr = (Z_SRW_PDU *) soap_package->u.generic->p;
if (sr->which == Z_SRW_searchRetrieve_response)
handle_srw_response(sr->u.response);
else if (sr->which == Z_SRW_explain_response)
char oidstr[101], otherinfoString[101];
int otherinfoNo;
int sscan_res;
- int oidval;
sscan_res = sscanf (args, "%d %100[^ ] %100s",
&otherinfoNo, oidstr, otherinfoString);
- if (sscan_res==1) {
+
+ if (sscan_res > 0 && otherinfoNo >= maxOtherInfosSupported) {
+ printf("Error otherinfo index too large (%d>=%d)\n",
+ otherinfoNo,maxOtherInfosSupported);
+ return 0;
+ }
+
+
+ if (sscan_res==1)
+ {
/* reset this otherinfo */
- if(otherinfoNo>=maxOtherInfosSupported) {
- printf("Error otherinfo index to large (%d>%d)\n",
- otherinfoNo,maxOtherInfosSupported);
- }
- extraOtherInfos[otherinfoNo].oidval = -1;
- if (extraOtherInfos[otherinfoNo].value)
- xfree(extraOtherInfos[otherinfoNo].value);
+ extraOtherInfos[otherinfoNo].oid[0] = -1;
+ xfree(extraOtherInfos[otherinfoNo].value);
extraOtherInfos[otherinfoNo].value = 0;
return 0;
}
- if (sscan_res<3) {
+ if (sscan_res != 3) {
printf("Error in set_otherinfo command \n");
return 0;
}
-
- if (otherinfoNo>=maxOtherInfosSupported) {
- printf("Error otherinfo index too large (%d>=%d)\n",
- otherinfoNo,maxOtherInfosSupported);
- }
-
- oidval = oid_getvalbyname (oidstr);
- if (oidval == VAL_NONE)
+ else
{
- printf("Error in set_otherinfo command unknown oid %s \n",oidstr);
- return 0;
- }
- extraOtherInfos[otherinfoNo].oidval = oidval;
- if (extraOtherInfos[otherinfoNo].value)
+ NMEM oid_tmp = nmem_create();
+ const Odr_oid *oid =
+ yaz_string_to_oid_nmem(yaz_oid_std(),
+ CLASS_GENERAL, oidstr, oid_tmp);
+ oid_oidcpy(extraOtherInfos[otherinfoNo].oid, oid);
+
xfree(extraOtherInfos[otherinfoNo].value);
- extraOtherInfos[otherinfoNo].value = xstrdup(otherinfoString);
+ extraOtherInfos[otherinfoNo].value = xstrdup(otherinfoString);
+
+ nmem_destroy(oid_tmp);
+ }
return 0;
}
{
int i;
- if(strlen(args)>0) {
+ if (strlen(args)>0)
+ {
i = atoi(args);
- if( i >= maxOtherInfosSupported ) {
+ if (i >= maxOtherInfosSupported)
+ {
printf("Error otherinfo index to large (%d>%d)\n",i,maxOtherInfosSupported);
return 0;
}
-
- if(extraOtherInfos[i].oidval != -1)
+ if (extraOtherInfos[i].value)
+ {
+ char name_oid[OID_STR_MAX];
+ oid_class oclass;
+ const char *name =
+ yaz_oid_to_string_buf(extraOtherInfos[i].oid, &oclass,
+ name_oid);
printf(" otherinfo %d %s %s\n",
- i,
- yaz_z3950_oid_value_to_str(
- (enum oid_value) extraOtherInfos[i].oidval,
- CLASS_RECSYN),
+ i, name ? name : "null",
extraOtherInfos[i].value);
+ }
- } else {
- for(i=0; i<maxOtherInfosSupported; ++i) {
- if(extraOtherInfos[i].oidval != -1)
+ }
+ else
+ {
+ for(i = 0; i < maxOtherInfosSupported; ++i)
+ {
+ if (extraOtherInfos[i].value)
+ {
+ char name_oid[OID_STR_MAX];
+ oid_class oclass;
+ const char *name =
+ yaz_oid_to_string_buf(extraOtherInfos[i].oid, &oclass,
+ name_oid);
printf(" otherinfo %d %s %s\n",
- i,
- yaz_z3950_oid_value_to_str(
- (enum oid_value) extraOtherInfos[i].oidval,
- CLASS_RECSYN),
+ i, name ? name : "null",
extraOtherInfos[i].value);
+ }
}
-
}
return 0;
}
printf("ssub/lslb/mspn : %d/%d/%d\n",smallSetUpperBound,largeSetLowerBound,mediumSetPresentNumber);
/* print present related options */
- printf("Format : %s\n",
- (recordsyntax_size > 0) ?
- yaz_z3950_oid_value_to_str(recordsyntax_list[0], CLASS_RECSYN) :
- "none");
+ if (recordsyntax_size > 0)
+ {
+ printf("Format : %s\n", recordsyntax_list[0]);
+ }
printf("Schema : %s\n",record_schema ? record_schema : "not set");
printf("Elements : %s\n",elementSetNames?elementSetNames->u.generic:"");
otherinfoNo, maxOtherInfosSupported);
return 0;
}
- if (extraOtherInfos[otherinfoNo].oidval != -1)
+ if (extraOtherInfos[otherinfoNo].value)
{
/* only clear if set. */
- extraOtherInfos[otherinfoNo].oidval = -1;
+ extraOtherInfos[otherinfoNo].oid[0] = -1;
xfree(extraOtherInfos[otherinfoNo].value);
+ extraOtherInfos[otherinfoNo].value = 0;
}
} else {
int i;
for(i = 0; i < maxOtherInfosSupported; ++i)
{
- if (extraOtherInfos[i].oidval != -1)
+ if (extraOtherInfos[i].value)
{
- extraOtherInfos[i].oidval = -1;
+ extraOtherInfos[i].oid[0] = -1;
xfree(extraOtherInfos[i].value);
+ extraOtherInfos[i].value = 0;
}
}
}
char *ad;
completerFunctionType rl_completerfunction;
int complete_filenames;
- char **local_tabcompletes;
+ const char **local_tabcompletes;
} cmd_array[] = {
{"open", cmd_open, "('tcp'|'ssl')':<host>[':'<port>][/<db>]",NULL,0,NULL},
{"quit", cmd_quit, "",NULL,0,NULL},
{"delete", cmd_delete, "<setname>",NULL,0,NULL},
{"base", cmd_base, "<base-name>",NULL,0,NULL},
{"show", cmd_show, "<rec#>['+'<#recs>['+'<setname>]]",NULL,0,NULL},
+ {"setscan", cmd_setscan, "<term>",NULL,0,NULL},
{"scan", cmd_scan, "<term>",NULL,0,NULL},
{"scanstep", cmd_scanstep, "<size>",NULL,0,NULL},
{"scanpos", cmd_scanpos, "<size>",NULL,0,NULL},
{"schema", cmd_schema, "<schema>",complete_schema,0,NULL},
{"elements", cmd_elements, "<elementSetName>",NULL,0,NULL},
{"close", cmd_close, "",NULL,0,NULL},
- {"attributeset", cmd_attributeset, "<attrset>",complete_attributeset,0,NULL},
{"querytype", cmd_querytype, "<type>",complete_querytype,0,NULL},
{"refid", cmd_refid, "<id>",NULL,0,NULL},
{"itemorder", cmd_itemorder, "ill|item|xml <itemno>",NULL,0,NULL},
{"displaycharset", cmd_displaycharset, "<output_charset>",NULL,0,NULL},
{"marccharset", cmd_marccharset, "<charset_name>",NULL,0,NULL},
{"lang", cmd_lang, "<language_code>",NULL,0,NULL},
+ {"source", cmd_source_echo, "<filename>",NULL,1,NULL},
{".", cmd_source_echo, "<filename>",NULL,1,NULL},
{"!", cmd_subshell, "Subshell command",NULL,1,NULL},
{"set_apdufile", cmd_set_apdufile, "<filename>",NULL,1,NULL},
char command[101], tabargument[101];
int i;
int num_of_tabs;
- char** tabslist;
+ const char** tabslist;
if (sscanf (arg, "%100s %100s", command, tabargument) < 1) {
return 0;
if (!cmd_array[i].local_tabcompletes)
- cmd_array[i].local_tabcompletes = (char **) calloc(1,sizeof(char**));
+ cmd_array[i].local_tabcompletes = (const char **) calloc(1,sizeof(char**));
num_of_tabs=0;
num_of_tabs++;
}
- cmd_array[i].local_tabcompletes = (char **)
+ cmd_array[i].local_tabcompletes = (const char **)
realloc(cmd_array[i].local_tabcompletes,
(num_of_tabs+2)*sizeof(char**));
tabslist = cmd_array[i].local_tabcompletes;
}
#if HAVE_READLINE_READLINE_H
-static char** default_completer_list = NULL;
+static const char** default_completer_list = NULL;
static char* default_completer(const char* text, int state)
{
}
#endif
+#ifndef WIN32
+void ctrl_c_handler(int x)
+{
+ exit_client(0);
+}
+#endif
+
static void client(void)
{
char line[10240];
line[10239] = '\0';
+#ifndef WIN32
+ signal(SIGINT, ctrl_c_handler);
+#endif
+
#if HAVE_GETTIMEOFDAY
gettimeofday (&tv_start, 0);
#endif
if (*line_in)
add_history(line_in);
#endif
- strncpy(line, line_in, 10239);
+ strncpy(line, line_in, sizeof(line)-1);
free(line_in);
}
#endif
char *end_p;
printf (C_PROMPT);
fflush(stdout);
- if (!fgets(line, 10239, stdin))
+ if (!fgets(line, sizeof(line)-1, stdin))
break;
if ((end_p = strchr (line, '\n')))
*end_p = '\0';
}
+ if (isatty(0))
+ file_history_add_line(file_history, line);
process_cmd_line(line);
}
}
ODR_MASK_SET(&z3950_options, Z_Options_sort);
ODR_MASK_SET(&z3950_options, Z_Options_extendedServices);
ODR_MASK_SET(&z3950_options, Z_Options_delSet);
+ ODR_MASK_SET(&z3950_options, Z_Options_negotiationModel);
while ((ret = options("k:c:q:a:b:m:v:p:u:t:Vxd:", argv, argc, &arg)) != -2)
{
#endif
xfree(open_command);
}
- client ();
- exit (0);
+ client();
+ exit_client(0);
+ return 0;
}
/*
* Local variables: