/*
- * Copyright (C) 1995-2006, Index Data ApS
+ * Copyright (C) 1995-2007, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: client.c,v 1.314 2006-09-07 11:31:39 adam Exp $
+ * $Id: client.c,v 1.356 2007-12-27 13:27:40 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 <yaz/otherinfo.h>
#include <yaz/charneg.h>
+#include <yaz/query-charset.h>
#include <yaz/pquery.h>
#include <yaz/sortspec.h>
#include "admin.h"
#include "tabcomplete.h"
+#include "fhistory.h"
#define C_PROMPT "Z> "
-static char *sru_method = "soap";
+static file_history_t file_history = 0;
+
+static char sru_method[10] = "soap";
+static char sru_version[10] = "1.2";
static char *codeset = 0; /* character set for output */
static int hex_dump = 0;
static char *dump_file_prefix = 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 int negotiationCharsetVersion = 3;
static char *outputCharset = 0;
static char *marcCharset = 0;
+static char *queryCharset = 0;
static char* yazLang = 0;
static char last_cmd[32] = "?";
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
int rl_attempted_completion_over = 0;
#endif
-/* set this one to 1, to avoid decode of unknown MARCs */
-#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
#endif
static char *command_generator(const char *text, int state);
int cmd_register_tab(const char* arg);
+int cmd_querycharset(const char *arg);
static void close_session (void);
-ODR getODROutputStream()
+ODR getODROutputStream(void)
{
return out;
}
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);
}
}
-
+ else if (ODR_MASK_GET(req->options, Z_Options_negotiationModel))
+ {
+ Z_OtherInformation **p;
+ Z_OtherInformationUnit *p0;
+
+ yaz_oi_APDU(apdu, &p);
+
+ if ((p0=yaz_oi_update(p, out, NULL, 0, 0)))
+ {
+ p0->which = Z_OtherInfo_externallyDefinedInfo;
+ p0->information.externallyDefinedInfo =
+ yaz_set_proposal_charneg(out, 0, 0, 0, 0, 0);
+ }
+
+ }
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) {
-
+
+ if (p)
+ {
char *charset=NULL, *lang=NULL;
int selected;
yaz_get_response_charneg(session_mem, p, &charset, &lang,
&selected);
- if (outputCharset && negotiationCharset) {
- odr_set_charset (out, charset, outputCharset);
- odr_set_charset (in, outputCharset, charset);
+ printf("Accepted character set : %s\n", charset ? charset:"none");
+ printf("Accepted code language : %s\n", lang ? lang:"none");
+ printf("Accepted records in ...: %d\n", selected );
+
+ if (outputCharset && charset)
+ {
+ printf("Converting between %s and %s\n",
+ outputCharset, charset);
+ odr_set_charset(out, charset, outputCharset);
+ odr_set_charset(in, outputCharset, charset);
+ cmd_querycharset(charset);
}
- else {
- odr_set_charset (out, 0, 0);
- odr_set_charset (in, 0, 0);
+ else
+ {
+ 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 1;
}
-static int parse_cmd_doc(const char **arg, ODR out, char **buf,
- int *len, int opt)
+static int parse_cmd_doc(const char **arg, ODR out, char **buf, int *len)
{
const char *sep;
while (**arg && strchr(" \t\n\r\f", **arg))
(*arg)++;
- if ((*arg)[0] == '\"' && (sep=strchr(*arg+1, '"')))
+ if (**arg == '\0')
{
- (*arg)++;
- *len = sep - *arg;
- *buf = odr_strdupn(out, *arg, *len);
- (*arg) = sep+1;
- return 1;
+ return 0;
}
- else if ((*arg)[0] && (*arg)[0] != '\"')
+ else if ((*arg)[0] == '<')
{
long fsize;
FILE *inf;
- const char *fname = *arg;
-
+ const char *fname;
+ const char *arg_start = ++(*arg);
+
while (**arg != '\0' && **arg != ' ')
(*arg)++;
+ fname = odr_strdupn(out, arg_start, *arg - arg_start);
+
inf = fopen(fname, "rb");
if (!inf)
{
return 0;
}
*len = fsize;
- *buf = odr_malloc(out, fsize);
+ *buf = (char *) odr_malloc(out, fsize+1);
+ (*buf)[fsize] = '\0';
if (fread(*buf, 1, fsize, inf) != fsize)
{
printf("Unable to read %s\n", fname);
return 0;
}
fclose(inf);
- return 1;
}
- else if (**arg == '\0')
+ else if ((*arg)[0] == '\"' && (sep=strchr(*arg+1, '"')))
{
- if (opt)
- {
- *len = 0;
- *buf = 0;
- return 1;
- }
- printf("Missing doc argument\n");
+ (*arg)++;
+ *len = sep - *arg;
+ *buf = odr_strdupn(out, *arg, *len);
+ (*arg) = sep+1;
}
else
- printf("Bad doc argument %s\n", *arg);
- return 0;
+ {
+ const char *arg_start = *arg;
+
+ while (**arg != '\0' && **arg != ' ')
+ (*arg)++;
+
+ *len = *arg - arg_start;
+ *buf = odr_strdupn(out, arg_start, *len);
+ }
+ return 1;
}
static int cmd_base(const char *arg)
conn = cs_create_host(arg, 1, &add);
if (!conn)
{
- printf ("Couldn't create comstack\n");
+ printf ("Could not resolve address %s\n", arg);
return 0;
}
#if YAZ_HAVE_XML2
- if (conn->protocol == PROTO_HTTP)
- queryType = QueryType_CQL;
#else
if (conn->protocol == PROTO_HTTP)
{
if (cs_connect(conn, add) < 0)
{
printf ("error = %s\n", cs_strerror(conn));
- if (conn->cerrno == CSYSERR)
- {
- char msg[256];
- yaz_strerror(msg, sizeof(msg));
- printf ("%s\n", msg);
- }
cs_close(conn);
conn = 0;
return 0;
int cmd_open(const char *arg)
{
+ int r;
if (arg)
{
strncpy (cur_host, arg, sizeof(cur_host)-1);
cur_host[sizeof(cur_host)-1] = 0;
}
- return session_connect(cur_host);
+ r = session_connect(cur_host);
+ if (conn && conn->protocol == PROTO_HTTP)
+ queryType = QueryType_CQL;
+ return r;
}
-void try_reconnect()
+void try_reconnect(void)
{
char* open_command;
au.which = Z_IdAuthentication_idPass;
au.u.idPass = &idPass;
idPass.groupId = NULL;
- idPass.userId = user;
- idPass.password = group;
+ idPass.userId = !strcmp(user, "-") ? 0 : user;
+ idPass.password = !strcmp(group, "-") ? 0 : group;
printf("Authentication set to User (%s), Pass (%s)\n", user, group);
}
if (r == 3)
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";
- }
+ if (octet_buf[9] == 'a')
+ from = "UTF-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");
- 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]);
gdu = z_get_HTTP_Request_host_path(out, host_port, path);
- if (!strcmp(sru_method, "get"))
+ if (!yaz_matchstr(sru_method, "get"))
{
yaz_sru_get_encode(gdu->u.HTTP_Request, sr, out, charset);
}
- else if (!strcmp(sru_method, "post"))
+ else if (!yaz_matchstr(sru_method, "post"))
{
yaz_sru_post_encode(gdu->u.HTTP_Request, sr, out, charset);
}
- else if (!strcmp(sru_method, "soap"))
+ else if (!yaz_matchstr(sru_method, "soap"))
{
yaz_sru_soap_encode(gdu->u.HTTP_Request, sr, out, charset);
}
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;
}
Z_SRW_PDU *sr = 0;
/* regular requestse .. */
- sr = yaz_srw_get(out, Z_SRW_scan_request);
+ sr = yaz_srw_get_pdu(out, Z_SRW_scan_request, sru_version);
switch(queryType)
{
setno = 1;
/* save this for later .. when fetching individual records */
- srw_sr = yaz_srw_get(srw_sr_odr_out, Z_SRW_searchRetrieve_request);
+ srw_sr = yaz_srw_get_pdu(srw_sr_odr_out, Z_SRW_searchRetrieve_request,
+ sru_version);
/* regular request .. */
- sr = yaz_srw_get(out, Z_SRW_searchRetrieve_request);
+ sr = yaz_srw_get_pdu(out, Z_SRW_searchRetrieve_request, sru_version);
switch(queryType)
{
if (record_schema)
sr->u.request->recordSchema = record_schema;
- if (recordsyntax_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML)
- sr->u.explain_request->recordPacking = "xml";
+ if (recordsyntax_size == 1 && !yaz_matchstr(recordsyntax_list[0], "xml"))
+ sr->u.request->recordPacking = "xml";
return send_srw(sr);
}
#endif
+static void query_charset_convert(Z_RPNQuery *q)
+{
+ if (queryCharset && outputCharset)
+ {
+ yaz_iconv_t cd = yaz_iconv_open(queryCharset, outputCharset);
+ if (!cd)
+ {
+ printf("Conversion from %s to %s unsupported\n",
+ outputCharset, queryCharset);
+ return;
+ }
+ yaz_query_charset_convert_rpnquery(q, out, cd);
+ yaz_iconv_close(cd);
+ }
+}
+
static int send_searchRequest(const char *arg)
{
Z_APDU *apdu = zget_APDU(out, Z_APDU_searchRequest);
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;
}
return 0;
}
yaz_pqf_destroy (pqf_parser);
+ query_charset_convert(RPNquery);
query.u.type_1 = RPNquery;
break;
case QueryType_CCL:
printf ("Couldn't convert from CCL to RPN\n");
return 0;
}
+ query_charset_convert(RPNquery);
query.u.type_1 = RPNquery;
ccl_rpn_delete (rpn);
break;
last_hit_count = *res->resultCount;
if (setnumber >= 0)
printf (", setno %d", setnumber);
- printf ("\n");
+ putchar('\n');
+ if (res->resultSetStatus)
+ {
+ printf("Result Set Status: ");
+ switch(*res->resultSetStatus)
+ {
+ case Z_SearchResponse_subset:
+ printf("subset"); break;
+ case Z_SearchResponse_interim:
+ printf("interim"); break;
+ case Z_SearchResponse_none:
+ printf("none"); break;
+ case Z_SearchResponse_estimate:
+ printf("estimate"); break;
+ default:
+ printf("%d", *res->resultSetStatus);
+ }
+ putchar('\n');
+ }
display_searchResult (res->additionalSearchInfo);
printf("records returned: %d\n",
*res->numberOfRecordsReturned);
{
if (pOid != NULL)
{
- int *pInt = pOid;
+ Odr_oid *pInt = pOid;
print_level(iLevel);
printf("%s:", pTag);
}
}
}
+ if (ext->which == Z_External_itemOrder)
+ {
+ Z_IOTaskPackage *otp = ext->u.itemOrder->u.taskPackage;
+ if (otp && otp->targetPart && otp->targetPart->itemRequest)
+ {
+ Z_External *ext = otp->targetPart->itemRequest;
+ if (ext->which == Z_External_octet)
+ {
+ Odr_oct *doc = ext->u.octet_aligned;
+ printf("Got itemRequest doc %.*s\n",
+ doc->len, doc->buf);
+ }
+ }
+ }
}
if (res->taskPackage && res->taskPackage->which == Z_External_octet)
{
return 0;
}
-static Z_External *create_external_itemRequest()
+static Z_External *create_external_itemRequest(void)
{
struct ill_get_ctl ctl;
ILL_ItemRequest *req;
}
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);
return 0;
}
-static int only_z3950()
+static int only_z3950(void)
{
if (!conn)
{
return cmd_update_common(arg, 0);
}
+static int cmd_update_Z3950(int version, int action_no, const char *recid,
+ char *rec_buf, int rec_len);
+
+static int cmd_update_SRW(int action_no, const char *recid,
+ char *rec_buf, int rec_len);
+
static int cmd_update_common(const char *arg, int version)
{
- Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest );
- Z_ExtendedServicesRequest *req = apdu->u.extendedServicesRequest;
- Z_External *r;
- char action[20], recid[20];
+ char *action_buf;
+ int action_len;
+ char *recid_buf;
+ int recid_len;
+ const char *recid = 0;
char *rec_buf;
int rec_len;
int action_no;
int noread = 0;
- Z_External *record_this = 0;
- if (only_z3950())
- return 1;
- *action = 0;
- *recid = 0;
- sscanf (arg, "%19s %19s%n", action, recid, &noread);
- if (noread == 0)
+ if (parse_cmd_doc(&arg, out, &action_buf, &action_len) == 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;
}
- if (!strcmp (action, "insert"))
+ if (parse_cmd_doc(&arg, out, &recid_buf, &recid_len) == 0)
+ {
+ printf("Missing recid\n");
+ return 0;
+ }
+
+ if (!strcmp(action_buf, "insert"))
action_no = Z_IUOriginPartToKeep_recordInsert;
- else if (!strcmp (action, "replace"))
+ else if (!strcmp(action_buf, "replace"))
action_no = Z_IUOriginPartToKeep_recordReplace;
- else if (!strcmp (action, "delete"))
+ else if (!strcmp(action_buf, "delete"))
action_no = Z_IUOriginPartToKeep_recordDelete;
- else if (!strcmp (action, "update"))
+ else if (!strcmp(action_buf, "update"))
action_no = Z_IUOriginPartToKeep_specialUpdate;
else
{
- printf ("Bad action: %s\n", action);
+ printf ("Bad action: %s\n", action_buf);
printf ("Possible values: insert, replace, delete, update\n");
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)
+ if (parse_cmd_doc(&arg, out, &rec_buf, &rec_len) == 0)
+ return 0;
+
+#if YAZ_HAVE_XML2
+ if (protocol == PROTO_HTTP)
+ return cmd_update_SRW(action_no, recid_buf, rec_buf, rec_len);
+#endif
+ return cmd_update_Z3950(version, action_no, recid_buf, rec_buf, rec_len);
+}
+
+#if YAZ_HAVE_XML2
+static int cmd_update_SRW(int action_no, const char *recid,
+ char *rec_buf, int rec_len)
+{
+ if (!conn)
+ session_connect(cur_host);
+ if (!conn)
return 0;
+ else
+ {
+ Z_SRW_PDU *srw = yaz_srw_get(out, Z_SRW_update_request);
+ Z_SRW_updateRequest *sr = srw->u.update_request;
+ switch(action_no)
+ {
+ case Z_IUOriginPartToKeep_recordInsert:
+ sr->operation = "info:srw/action/1/create";
+ break;
+ case Z_IUOriginPartToKeep_recordReplace:
+ sr->operation = "info:srw/action/1/replace";
+ break;
+ case Z_IUOriginPartToKeep_recordDelete:
+ sr->operation = "info:srw/action/1/delete";
+ break;
+ }
+ if (rec_buf)
+ {
+ sr->record = yaz_srw_get_record(out);
+ sr->record->recordData_buf = rec_buf;
+ sr->record->recordData_len = rec_len;
+ sr->record->recordSchema = record_schema;
+ }
+ if (recid)
+ sr->recordId = odr_strdup(out, recid);
+ return send_srw(srw);
+ }
+}
+#endif
+
+static int cmd_update_Z3950(int version, int action_no, const char *recid,
+ char *rec_buf, int rec_len)
+{
+ Z_APDU *apdu = zget_APDU(out, Z_APDU_extendedServicesRequest );
+ 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;
toKeep->databaseName = databaseNames[0];
toKeep->schema = 0;
+ if (record_schema)
+ {
+ toKeep->schema = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_SCHEMA,
+ record_schema, out);
+ }
toKeep->elementSetName = 0;
toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
notToKeep->elements[0] = (Z_IU0SuppliedRecords_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));
toKeep->databaseName = databaseNames[0];
toKeep->schema = 0;
+ if (record_schema)
+ {
+ toKeep->schema = yaz_string_to_oid_odr(yaz_oid_std(),
+ CLASS_SCHEMA,
+ record_schema, out);
+ }
toKeep->elementSetName = 0;
toKeep->actionQualifier = 0;
toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
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));
return 1;
else
{
+ 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)
+ if (parse_cmd_doc(&arg, out, &asn_buf,
+ &ext->u.single_ASN1_type->len) == 0)
+ return 0;
+
+ ext->u.single_ASN1_type->buf = (unsigned char *) asn_buf;
+
+ 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;
- if (parse_cmd_doc(&arg, out, (char **) &ext->u.single_ASN1_type->buf,
- &ext->u.single_ASN1_type->len, 0) == 0)
- return 0;
- req->packageType = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV,
- oid_value_xmles);
-
- ext->direct_reference = yaz_oidval_to_z3950oid(out, CLASS_EXTSERV,
- oid_value_xmles);
+ ext->direct_reference = oid;
+
send_apdu(apdu);
return 2;
return 0;
#if YAZ_HAVE_XML2
if (!conn)
- cmd_open(0);
+ session_connect(cur_host);
if (conn)
{
Z_SRW_PDU *sr = 0;
/* 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;
if (!*arg)
{
printf("SRU method is: %s\n", sru_method);
+ printf("SRU version is: %s\n", sru_version);
}
else
{
- if (!yaz_matchstr(arg, "post"))
- sru_method = "post";
- else if (!yaz_matchstr(arg, "get"))
- sru_method = "get";
- else if (!yaz_matchstr(arg, "soap"))
- sru_method = "soap";
- else
+ int r;
+ r = sscanf(arg, "%9s %9s", sru_method, sru_version);
+ if (r >= 1)
{
- printf("Unknown SRU method: %s\n", arg);
- printf("Specify one of POST, GET, SOAP\n");
+ if (!yaz_matchstr(sru_method, "post"))
+ ;
+ else if (!yaz_matchstr(sru_method, "get"))
+ ;
+ else if (!yaz_matchstr(sru_method, "soap"))
+ ;
+ else
+ {
+ strcpy(sru_method, "soap");
+ printf("Unknown SRU method: %s\n", arg);
+ printf("Specify one of POST, GET, SOAP\n");
+ }
}
}
return 0;
{
#if YAZ_HAVE_XML2
if (!conn)
- cmd_open(0);
+ session_connect(cur_host);
if (!conn)
return 0;
if (!send_SRW_searchRequest(arg))
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);
}
{
#if YAZ_HAVE_XML2
if (!conn)
- cmd_open(0);
+ session_connect(cur_host);
if (!conn)
return 0;
if (!send_SRW_presentRequest(arg))
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");
}
yaz_pqf_destroy (pqf_parser);
}
+ if (queryCharset && outputCharset)
+ {
+ yaz_iconv_t cd = yaz_iconv_open(queryCharset, outputCharset);
+ if (!cd)
+ {
+ printf("Conversion from %s to %s unsupported\n",
+ outputCharset, queryCharset);
+ return -1;
+ }
+ yaz_query_charset_convert_apt(req->termListAndStartPoint, out, cd);
+ yaz_iconv_close(cd);
+ }
if (term && *term)
{
if (req->termListAndStartPoint->term &&
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;
}
if (t->displayTerm)
printf("%s", t->displayTerm);
else if (t->term->which == Z_Term_general)
- {
printf("%.*s", t->term->u.general->len, t->term->u.general->buf);
- sprintf(last_scan_line, "%.*s", t->term->u.general->len,
- t->term->u.general->buf);
- }
else
printf("Term (not general)");
+ if (t->term->which == Z_Term_general)
+ sprintf(last_scan_line, "%.*s", t->term->u.general->len,
+ t->term->u.general->buf);
+
if (t->globalOccurrences)
printf (" (%d)\n", *t->globalOccurrences);
else
return 0;
}
-int cmd_scan(const char *arg)
+static int cmd_scan_common(const char *set, const char *arg)
{
if (protocol == PROTO_HTTP)
{
#if YAZ_HAVE_XML2
if (!conn)
- cmd_open(0);
+ session_connect(cur_host);
if (!conn)
return 0;
if (*arg)
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"))
}
xfree (marcCharset);
marcCharset = 0;
- if (strcmp(l1, "-"))
+ if (strcmp(l1, "-") && strcmp(l1, "none"))
marcCharset = xstrdup(l1);
return 1;
}
+int cmd_querycharset(const char *arg)
+{
+ char l1[30];
+
+ *l1 = 0;
+ if (sscanf(arg, "%29s", l1) < 1)
+ {
+ printf("Query character set is `%s'\n",
+ queryCharset ? queryCharset: "none");
+ return 1;
+ }
+ xfree (queryCharset);
+ queryCharset = 0;
+ if (strcmp(l1, "-") && strcmp(l1, "none"))
+ queryCharset = xstrdup(l1);
+ return 1;
+}
+
int cmd_displaycharset(const char *arg)
{
char l1[30];
if (sscanf(arg, "%29s %d %d", l1, &negotiationCharsetRecords,
&negotiationCharsetVersion) < 1)
{
- printf("Current negotiation character set is `%s'\n",
+ printf("Negotiation character set `%s'\n",
negotiationCharset ? negotiationCharset: "none");
- printf("Records in charset %s\n", negotiationCharsetRecords ?
- "yes" : "no");
- printf("Charneg version %d\n", negotiationCharsetVersion);
+ if (negotiationCharset)
+ {
+ printf("Records in charset %s\n", negotiationCharsetRecords ?
+ "yes" : "no");
+ printf("Charneg version %d\n", negotiationCharsetVersion);
+ }
}
else
{
int cmd_charset(const char* arg)
{
- char l1[30], l2[30], l3[30];
+ char l1[30], l2[30], l3[30], l4[30];
- *l1 = *l2 = *l3 = 0;
- if (sscanf(arg, "%29s %29s %29s", l1, l2, l3) < 1)
+ *l1 = *l2 = *l3 = *l4 = '\0';
+ if (sscanf(arg, "%29s %29s %29s %29s", l1, l2, l3, l4) < 1)
{
cmd_negcharset("");
cmd_displaycharset("");
cmd_marccharset("");
+ cmd_querycharset("");
}
else
{
cmd_displaycharset(l2);
if (*l3)
cmd_marccharset(l3);
+ if (*l4)
+ cmd_querycharset(l4);
}
return 1;
}
int cmd_lang(const char* arg)
{
if (*arg == '\0') {
- printf("Current language is `%s'\n", (yazLang)?yazLang:NULL);
+ printf("Current language is `%s'\n", yazLang ? yazLang : "none");
return 1;
}
xfree (yazLang);
{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;
}
return 1;
}
-void source_rcfile()
+void source_rc_file(const char *rc_file)
{
- /* Look for a $HOME/.yazclientrc and source it if it exists */
+ /* If rc_file != NULL, source that. Else
+ Look for .yazclientrc and read it if it exists.
+ If it does not exist, read $HOME/.yazclientrc instead */
struct stat statbuf;
- char buffer[1000];
- char* homedir=getenv("HOME");
-
- if( homedir ) {
-
- sprintf(buffer,"%s/.yazclientrc",homedir);
- if(stat(buffer,&statbuf)==0) {
- cmd_source(buffer, 0 );
+ if (rc_file)
+ {
+ if (stat(rc_file, &statbuf) == 0)
+ cmd_source(rc_file, 0);
+ else
+ {
+ fprintf(stderr, "yaz_client: cannot source '%s'\n", rc_file);
+ exit(1);
+ }
+ }
+ else
+ {
+ char fname[1000];
+ strcpy(fname, ".yazclientrc");
+ if (stat(fname, &statbuf)==0)
+ {
+ cmd_source(fname, 0);
+ }
+ else
+ {
+ const char* homedir = getenv("HOME");
+ if (homedir)
+ {
+ sprintf(fname, "%.800s/%s", homedir, ".yazclientrc");
+ if (stat(fname, &statbuf)==0)
+ cmd_source(fname, 0);
+ }
}
-
- };
-
- if(stat(".yazclientrc",&statbuf)==0) {
- cmd_source(".yazclientrc", 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)
+static void initialize(const char *rc_file)
{
FILE *inf;
int i;
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();
+ source_rc_file(rc_file);
+
+ 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\n");
+ else
{
Z_SOAP *soap_package = 0;
ODR o = odr_createmem(ODR_DECODE);
- Z_SOAP_Handler soap_handlers[2] = {
- {"http://www.loc.gov/zing/srw/", 0,
- (Z_SOAP_fun) yaz_srw_codec},
+ Z_SOAP_Handler soap_handlers[3] = {
+ {YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec},
+ {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
{0, 0, 0}
};
ret = z_soap_codec(o, &soap_package,
&hres->content_buf, &hres->content_len,
soap_handlers);
- if (!ret && soap_package->which == Z_SOAP_generic &&
- soap_package->u.generic->no == 0)
+ 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)
handle_srw_explain_response(sr->u.explain_response);
else if (sr->which == Z_SRW_scan_response)
handle_srw_scan_response(sr->u.scan_response);
+ else if (sr->which == Z_SRW_update_response)
+ printf("Got update response. Status: %s\n",
+ sr->u.update_response->operationStatus);
else
ret = -1;
}
else if (soap_package && (soap_package->which == Z_SOAP_fault
- || soap_package->which == Z_SOAP_error))
+ || soap_package->which == Z_SOAP_error))
{
printf ("HTTP Error Status=%d\n", hres->code);
printf ("SOAP Fault code %s\n",
soap_package->u.fault->details);
}
else
+ {
+ printf("z_soap_codec failed. (no SOAP error)\n");
ret = -1;
+ }
odr_destroy(o);
}
if (ret)
{
cs_close(conn);
conn = 0;
- cmd_open(0);
+ session_connect(cur_host);
reconnect_ok = 0;
if (conn)
{
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},
{"negcharset", cmd_negcharset, "<nego_charset>",NULL,0,NULL},
{"displaycharset", cmd_displaycharset, "<output_charset>",NULL,0,NULL},
{"marccharset", cmd_marccharset, "<charset_name>",NULL,0,NULL},
+ {"querycharset", cmd_querycharset, "<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},
{"zversion", cmd_zversion, "", NULL, 0, NULL},
{"help", cmd_help, "", NULL,0,NULL},
{"init", cmd_init, "", NULL,0,NULL},
- {"sru", cmd_sru, "", NULL,0,NULL},
+ {"sru", cmd_sru, "<method> <version>", NULL,0,NULL},
{"exit", cmd_quit, "",NULL,0,NULL},
{0,0,0,0,0,0}
};
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);
}
}
char *open_command = 0;
char *auth_command = 0;
char *arg;
+ const char *rc_file = 0;
int ret;
#if HAVE_LOCALE_H
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)
+ while ((ret = options("k:c:q:a:b:m:v:p:u:t:Vxd:f:", argv, argc, &arg)) != -2)
{
switch (ret)
{
exit(1);
}
break;
+ case 'a':
+ if (!strcmp(arg, "-"))
+ apdu_file=stderr;
+ else
+ apdu_file=fopen(arg, "a");
+ break;
+ case 'b':
+ if (!strcmp(arg, "-"))
+ ber_file=stderr;
+ else
+ ber_file=fopen(arg, "a");
+ break;
+ case 'c':
+ strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
+ ccl_fields[sizeof(ccl_fields)-1] = '\0';
+ break;
case 'd':
dump_file_prefix = arg;
break;
+ case 'f':
+ rc_file = arg;
+ break;
case 'k':
kilobytes = atoi(arg);
break;
exit (1);
}
break;
- case 't':
- outputCharset = xstrdup(arg);
- break;
- case 'c':
- strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
- ccl_fields[sizeof(ccl_fields)-1] = '\0';
+ case 'p':
+ yazProxy = xstrdup(arg);
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
- ber_file=fopen(arg, "a");
- break;
- case 'a':
- if (!strcmp(arg, "-"))
- apdu_file=stderr;
- else
- apdu_file=fopen(arg, "a");
- break;
- case 'x':
- hex_dump = 1;
- break;
- case 'p':
- yazProxy = xstrdup(arg);
+ case 't':
+ outputCharset = xstrdup(arg);
break;
case 'u':
if (!auth_command)
case 'V':
show_version();
break;
+ case 'x':
+ hex_dump = 1;
+ break;
default:
fprintf (stderr, "Usage: %s "
- " [-a <apdulog>]"
+ " [-a apdulog]"
" [-b berdump]"
- " [-d dump]\n"
- " [-c cclfields]"
+ " [-c cclfile]"
+ " [-d dump]"
+ " [-f cmdfile]"
" [-k size]"
- " [-m <marclog>]\n"
- " [-p <proxy-addr>]"
- " [-q cqlfields]"
- " [-u <auth>]"
+ " [-m marclog]"
+ " [-p proxy-addr]"
+ " [-q cqlfile]"
+ " [-t dispcharset]"
+ " [-u auth]"
+ " [-v loglevel]"
" [-V]"
- " [<server-addr>]\n",
+ " [-x]"
+ " [server-addr]\n",
prog);
exit (1);
}
}
- initialize();
+ initialize(rc_file);
if (auth_command)
{
#ifdef HAVE_GETTIMEOFDAY
#endif
xfree(open_command);
}
- client ();
- exit (0);
+ client();
+ exit_client(0);
+ return 0;
}
/*
* Local variables: