/*
- * Copyright (c) 1995-2002, Index Data
+ * Copyright (c) 1995-2003, Index Data
* See the file LICENSE for details.
*
- * $Id: client.c,v 1.169 2002-09-17 11:07:30 adam Exp $
+ * $Id: client.c,v 1.181 2003-02-14 18:49:23 adam Exp $
*/
#include <stdio.h>
#include <stdlib.h>
+#if HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+#if HAVE_LANGINFO_H
+#include <langinfo.h>
+#endif
+
#include <time.h>
+#include <ctype.h>
+
+#ifdef WIN32
+#include <io.h>
+#define S_ISREG(x) (x & _S_IFREG)
+#define S_ISDIR(x) (x & _S_IFDIR)
+#endif
#include <yaz/yaz-util.h>
#define C_PROMPT "Z> "
+static char *codeset = 0; /* character set for output */
+
static ODR out, in, print; /* encoding and decoding streams */
static FILE *apdu_file = 0;
static COMSTACK conn = 0; /* our z-association */
char *databaseNames[128];
int num_databaseNames = 0;
static Z_External *record_last = 0;
-static int setnumber = -1; /* current result set number */
+static int setnumber = -1; /* current result set number */
static int smallSetUpperBound = 0;
static int largeSetLowerBound = 1;
static int mediumSetPresentNumber = 0;
static enum oid_value recordsyntax = VAL_USMARC;
static enum oid_value schema = VAL_NONE;
static int sent_close = 0;
-static NMEM session_mem = NULL; /* memory handle for init-response */
+static NMEM session_mem = NULL; /* memory handle for init-response */
static Z_InitResponse *session = 0; /* session parameters */
static char last_scan_line[512] = "0";
static char last_scan_query[512] = "0";
typedef enum {
QueryType_Prefix,
QueryType_CCL,
- QueryType_CCL2RPN
+ QueryType_CCL2RPN,
+ QueryType_CQL
} QueryType;
static QueryType queryType = QueryType_Prefix;
#define maxOtherInfosSupported 10
struct {
int oidval;
- char* value;
+ char* value;
} extraOtherInfos[maxOtherInfosSupported];
case QueryType_Prefix: return "prefix (RPN sent to server)";
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)";
default:
return "unknown Query type internal yaz-client error";
}
#endif
}
-
-
void add_otherInfos(Z_APDU *a)
{
Z_OtherInformation **oi;
yaz_get_charneg_record(res->otherInfo);
if (p) {
-
- char *charset=NULL, *lang=NULL;
- int selected;
-
- yaz_get_response_charneg(session_mem, p, &charset, &lang,
+
+ char *charset=NULL, *lang=NULL;
+ int selected;
+
+ yaz_get_response_charneg(session_mem, p, &charset, &lang,
&selected);
-
- printf("Accepted character set : %s\n", charset);
- printf("Accepted code language : %s\n", lang ? lang : "none");
- printf("Accepted records in ...: %d\n", selected );
+
+ 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);
{
printf ("error = %s\n", cs_strerror(conn));
if (conn->cerrno == CSYSERR)
- perror("system");
+ {
+ char msg[256];
+ yaz_strerror(msg, sizeof(msg));
+ printf ("%s\n", msg);
+ }
cs_close(conn);
conn = 0;
return 0;
/* SEARCH SERVICE ------------------------------ */
static void display_record(Z_External *r);
-static void display_variant(Z_Variant *v, int level)
-{
- int i;
-
- for (i = 0; i < v->num_triples; i++)
- {
- printf("%*sclass=%d,type=%d", level * 4, "", *v->triples[i]->zclass,
- *v->triples[i]->type);
- if (v->triples[i]->which == Z_Triple_internationalString)
- printf(",value=%s\n", v->triples[i]->value.internationalString);
- else
- printf("\n");
- }
-}
-
-static void display_grs1(Z_GenericRecord *r, int level)
-{
- int i;
-
- if (!r)
- {
- return;
- }
- for (i = 0; i < r->num_elements; i++)
- {
- Z_TaggedElement *t;
-
- printf("%*s", level * 4, "");
- t = r->elements[i];
- printf("(");
- if (t->tagType)
- printf("%d,", *t->tagType);
- else
- printf("?,");
- if (t->tagValue->which == Z_StringOrNumeric_numeric)
- printf("%d) ", *t->tagValue->u.numeric);
- else
- printf("%s) ", t->tagValue->u.string);
- if (t->content->which == Z_ElementData_subtree)
- {
- if (!t->content->u.subtree)
- printf (" (no subtree)\n");
- else
- {
- printf("\n");
- display_grs1(t->content->u.subtree, level+1);
- }
- }
- else if (t->content->which == Z_ElementData_string)
- printf("%s\n", t->content->u.string);
- else if (t->content->which == Z_ElementData_numeric)
- printf("%d\n", *t->content->u.numeric);
- else if (t->content->which == Z_ElementData_oid)
- {
- int *ip = t->content->u.oid;
- oident *oent;
-
- if ((oent = oid_getentbyoid(t->content->u.oid)))
- printf("OID: %s\n", oent->desc);
- else
- {
- printf("{");
- while (ip && *ip >= 0)
- printf(" %d", *(ip++));
- printf(" }\n");
- }
- }
- else if (t->content->which == Z_ElementData_noDataRequested)
- printf("[No data requested]\n");
- else if (t->content->which == Z_ElementData_elementEmpty)
- printf("[Element empty]\n");
- else if (t->content->which == Z_ElementData_elementNotThere)
- printf("[Element not there]\n");
- else if (t->content->which == Z_ElementData_date)
- printf("Date: %s\n", t->content->u.date);
- else if (t->content->which == Z_ElementData_ext)
- {
- printf ("External\n");
- display_record (t->content->u.ext);
- }
- else
- printf("? type = %d\n",t->content->which);
- if (t->appliedVariant)
- display_variant(t->appliedVariant, level+1);
- if (t->metaData && t->metaData->supportedVariants)
- {
- int c;
-
- printf("%*s---- variant list\n", (level+1)*4, "");
- for (c = 0; c < t->metaData->num_supportedVariants; c++)
- {
- printf("%*svariant #%d\n", (level+1)*4, "", c);
- display_variant(t->metaData->supportedVariants[c], level + 2);
- }
- }
- }
-}
-
-
static void print_record(const unsigned char *buf, size_t len)
{
size_t i = len;
r->u.octet_aligned->len);
fprintf(stderr, "---------\n");
- /* note just ignores the error ant print the bytes form the octet_aligned laiter */
+ /* note just ignores the error ant print the bytes form the octet_aligned later */
} else {
/*
* Note: we throw away the original, BER-encoded record here.
if (ent && ent->value == VAL_SOIF)
print_record((const unsigned char *) r->u.octet_aligned->buf,
r->u.octet_aligned->len);
- else if (r->which == Z_External_octet && r->u.octet_aligned->len)
+ else if (r->which == Z_External_octet)
{
const char *octet_buf = (char*)r->u.octet_aligned->buf;
if (ent->value == VAL_TEXT_XML || ent->value == VAL_APPLICATION_XML ||
#endif
)
{
- if (marc_display_exl (octet_buf, NULL, 0 /* debug */,
- r->u.octet_aligned->len) <= 0)
+ char *result;
+ int 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)
+ {
+ char *from = 0;
+ if (ent->value == VAL_USMARC)
+ {
+ if (octet_buf[9] == 'a')
+ from = "UTF-8";
+ else
+ from = "MARC8";
+ }
+ else
+ from = "ISO-8859-1";
+
+ if (codeset && from)
+ {
+ printf ("convert from %s to %s\n", from, codeset);
+ cd = yaz_iconv_open(codeset, from);
+ }
+ if (!cd)
+ fwrite (result, 1, rlen, stdout);
+ else
+ {
+ char outbuf[12];
+ size_t inbytesleft = rlen;
+ const char *inp = result;
+
+ while (inbytesleft)
+ {
+ size_t outbytesleft = sizeof(outbuf);
+ char *outp = outbuf;
+ size_t 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);
+ }
+ }
+ }
+ else
{
printf ("bad MARC. Dumping as it is:\n");
print_record((const unsigned char*) octet_buf,
- r->u.octet_aligned->len);
- }
+ r->u.octet_aligned->len);
+ }
+ yaz_marc_destroy(mt);
+ if (cd)
+ yaz_iconv_close(cd);
}
else
{
}
else if (ent && ent->value == VAL_GRS1)
{
+ WRBUF w;
if (r->which != Z_External_grs1)
{
printf("Expecting single GRS type for GRS.\n");
return;
}
- display_grs1(r->u.grs1, 0);
+ w = wrbuf_alloc();
+ yaz_display_grs1(w, r->u.grs1, 0);
+ puts (wrbuf_buf(w));
+ wrbuf_free(w, 1);
}
else
{
Z_RPNQuery *RPNquery;
Odr_oct ccl_query;
YAZ_PQF_Parser pqf_parser;
+ Z_External *ext;
if (queryType == QueryType_CCL2RPN)
{
query.u.type_1 = RPNquery;
ccl_rpn_delete (rpn);
break;
+ case QueryType_CQL:
+ query.which = Z_Query_type_104;
+ ext = (Z_External *) odr_malloc(out, sizeof(*ext));
+ ext->direct_reference = odr_getoidbystr(out, "1.2.840.10003.16.2");
+ ext->indirect_reference = 0;
+ ext->descriptor = 0;
+ ext->which = Z_External_CQL;
+ ext->u.cql = odr_strdup(out, arg);
+ query.u.type_104 = ext;
+ break;
default:
printf ("Unsupported query type\n");
return 0;
Z_IUOriginPartToKeep *toKeep;
Z_IUSuppliedRecords *notToKeep;
oident update_oid;
- printf ("Update request\n");
- fflush(stdout);
-
- if (!record_last)
+ char action[20], recid[20], fname[80];
+ int action_no;
+ Z_External *record_this = 0;
+
+ *action = 0;
+ *recid = 0;
+ *fname = 0;
+ sscanf (arg, "%19s %19s %79s", action, recid, fname);
+
+ if (!strcmp (action, "insert"))
+ action_no = Z_IUOriginPartToKeep_recordInsert;
+ else if (!strcmp (action, "replace"))
+ action_no = Z_IUOriginPartToKeep_recordReplace;
+ else if (!strcmp (action, "delete"))
+ action_no = Z_IUOriginPartToKeep_recordDelete;
+ else if (!strcmp (action, "update"))
+ action_no = Z_IUOriginPartToKeep_specialUpdate;
+ else
+ {
+ printf ("Bad action: %s\n", action);
+ printf ("Possible values: insert, replace, delete, update\n");
return 0;
+ }
+
+ if (*fname)
+ {
+ FILE *inf;
+ struct stat status;
+ stat (fname, &status);
+ if (S_ISREG(status.st_mode) && (inf = fopen(fname, "r")))
+ {
+ size_t len = status.st_size;
+ char *buf = (char *) xmalloc (len);
+
+ fread (buf, 1, len, inf);
+
+ fclose (inf);
+
+ record_this = z_ext_record (out, VAL_TEXT_XML, buf, len);
+
+ xfree (buf);
+ }
+ else
+ {
+ printf ("File %s doesn't exist\n", fname);
+ return 0;
+ }
+ }
+ else
+ {
+ if (!record_last)
+ {
+ printf ("No last record (update ignored)\n");
+ return 0;
+ }
+ record_this = record_last;
+ }
+
update_oid.proto = PROTO_Z3950;
update_oid.oclass = CLASS_EXTSERV;
update_oid.value = VAL_DBUPDATE;
toKeep->elementSetName = 0;
toKeep->actionQualifier = 0;
toKeep->action = (int *) odr_malloc(out, sizeof(*toKeep->action));
- *toKeep->action = Z_IUOriginPartToKeep_recordInsert;
+ *toKeep->action = action_no;
notToKeep = r->u.update->u.esRequest->notToKeep = (Z_IUSuppliedRecords *)
odr_malloc(out, sizeof(*r->u.update->u.esRequest->notToKeep));
odr_malloc(out, sizeof(*notToKeep->elements));
notToKeep->elements[0] = (Z_IUSuppliedRecords_elem *)
odr_malloc(out, sizeof(**notToKeep->elements));
- notToKeep->elements[0]->u.number = 0;
+ notToKeep->elements[0]->which = Z_IUSuppliedRecords_elem_opaque;
+ if (*recid)
+ {
+ notToKeep->elements[0]->u.opaque = (Odr_oct *)
+ odr_malloc (out, sizeof(Odr_oct));
+ notToKeep->elements[0]->u.opaque->buf = (unsigned char *) recid;
+ notToKeep->elements[0]->u.opaque->size = strlen(recid);
+ notToKeep->elements[0]->u.opaque->len = strlen(recid);
+ }
+ else
+ notToKeep->elements[0]->u.opaque = 0;
notToKeep->elements[0]->supplementalId = 0;
notToKeep->elements[0]->correlationInfo = 0;
- notToKeep->elements[0]->record = record_last;
+ notToKeep->elements[0]->record = record_this;
send_apdu(apdu);
compo.u.complex->generic = (Z_Specification *)
odr_malloc(out, sizeof(*compo.u.complex->generic));
- compo.u.complex->generic->schema = (Odr_oid *)
+ compo.u.complex->generic->which = Z_Specification_oid;
+ compo.u.complex->generic->u.oid = (Odr_oid *)
odr_oiddup(out, oid_ent_to_oid(&prefschema, oid));
- if (!compo.u.complex->generic->schema)
+ if (!compo.u.complex->generic->u.oid)
{
/* OID wasn't a schema! Try record syntax instead. */
prefschema.oclass = CLASS_RECSYN;
- compo.u.complex->generic->schema = (Odr_oid *)
+ compo.u.complex->generic->u.oid = (Odr_oid *)
odr_oiddup(out, oid_ent_to_oid(&prefschema, oid));
}
if (!elementSetNames)
int cmd_format(char *arg)
{
+ oid_value nsyntax;
if (!arg || !*arg)
{
printf("Usage: format <recordsyntax>\n");
return 0;
}
- recordsyntax = oid_getvalbyname (arg);
- if (recordsyntax == VAL_NONE)
+ nsyntax = oid_getvalbyname (arg);
+ if (strcmp(arg, "none") && nsyntax == VAL_NONE)
{
printf ("unknown record syntax\n");
return 0;
}
+ recordsyntax = nsyntax;
return 1;
}
queryType = QueryType_Prefix;
else if (!strcmp (arg, "ccl2rpn") || !strcmp (arg, "cclrpn"))
queryType = QueryType_CCL2RPN;
+ else if (!strcmp(arg, "cql"))
+ queryType = QueryType_CQL;
else
{
printf ("Querytype must be one of:\n");
printf (" prefix - Prefix query\n");
printf (" ccl - CCL query\n");
printf (" ccl2rpn - CCL query converted to RPN\n");
+ printf (" cql - CQL\n");
return 0;
}
return 1;
{"schema",CLASS_SCHEMA},
{"tagset",CLASS_TAGSET},
{"general",CLASS_GENERAL},
- {0,0}
+ {0,(enum oid_class) 0}
};
char oname_str[101], oclass_str[101], oid_str[101];
char* name;
}
if(extraOtherInfos[i].oidval != -1)
- printf(" otherinfo %d %s %s\n",i,yaz_z3950_oid_value_to_str(extraOtherInfos[i].oidval,CLASS_RECSYN), extraOtherInfos[i].value);
+ printf(" otherinfo %d %s %s\n",
+ i,
+ yaz_z3950_oid_value_to_str(
+ (enum oid_value) extraOtherInfos[i].oidval,
+ CLASS_RECSYN),
+ extraOtherInfos[i].value);
} else {
for(i=0; i<maxOtherInfosSupported; ++i) {
if(extraOtherInfos[i].oidval != -1)
- printf(" otherinfo %d %s %s\n",i,yaz_z3950_oid_value_to_str(extraOtherInfos[i].oidval,CLASS_RECSYN), extraOtherInfos[i].value);
+ printf(" otherinfo %d %s %s\n",
+ i,
+ yaz_z3950_oid_value_to_str(
+ (enum oid_value) extraOtherInfos[i].oidval,
+ CLASS_RECSYN),
+ extraOtherInfos[i].value);
}
}
{"querytype", cmd_querytype, "<type>",complete_querytype,0,NULL},
{"refid", cmd_refid, "<id>",NULL,0,NULL},
{"itemorder", cmd_itemorder, "ill|item <itemno>",NULL,0,NULL},
- {"update", cmd_update, "<item>",NULL,0,NULL},
+ {"update", cmd_update, "<action> <recid> [<file>]",NULL,0,NULL},
{"packagename", cmd_packagename, "<packagename>",NULL,0,NULL},
{"proxy", cmd_proxy, "[('tcp'|'ssl')]<host>[':'<port>]",NULL,0,NULL},
{"charset", cmd_charset, "<charset_name>",NULL,0,NULL},
return 1;
}
-
-
- if(!cmd[i].local_tabcompletes) {
- cmd[i].local_tabcompletes = calloc(1,sizeof(char**));
- }
+
+ if(!cmd[i].local_tabcompletes)
+ cmd[i].local_tabcompletes = (char **) calloc(1,sizeof(char**));
num_of_tabs=0;
num_of_tabs++;
}
- cmd[i].local_tabcompletes=realloc(cmd[i].local_tabcompletes,(num_of_tabs+2)*sizeof(char**));
+ cmd[i].local_tabcompletes = (char **)
+ realloc(cmd[i].local_tabcompletes,(num_of_tabs+2)*sizeof(char**));
tabslist=cmd[i].local_tabcompletes;
tabslist[num_of_tabs]=strdup(tabargument);
tabslist[num_of_tabs+1]=NULL;
char *arg;
int ret;
- while ((ret = options("k:c:a:m:v:p:u:", argv, argc, &arg)) != -2)
+#if HAVE_LOCALE_H
+ if (!setlocale(LC_CTYPE, ""))
+ fprintf (stderr, "setlocale failed\n");
+#endif
+#if HAVE_LANGINFO_H
+ codeset = nl_langinfo(CODESET);
+#endif
+
+ while ((ret = options("k:c:a:m:v:p:u:t:", argv, argc, &arg)) != -2)
{
switch (ret)
{
exit (1);
}
break;
- case 'c':
- strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
- ccl_fields[sizeof(ccl_fields)-1] = '\0';
- break;
+ case 't':
+ codeset = arg;
+ break;
+ case 'c':
+ strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
+ ccl_fields[sizeof(ccl_fields)-1] = '\0';
+ break;
case 'a':
if (!strcmp(arg, "-"))
apdu_file=stderr;
else
apdu_file=fopen(arg, "a");
break;
- case 'p':
- yazProxy=strdup(arg);
- break;
+ case 'p':
+ yazProxy=strdup(arg);
+ break;
case 'u':
if (!auth_command)
{