/*
- * Copyright (C) 1995-2005, Index Data ApS
+ * Copyright (C) 1995-2006, Index Data ApS
* See the file LICENSE for details.
*
- * $Id: client.c,v 1.294 2005-07-22 06:23:14 adam Exp $
+ * $Id: client.c,v 1.309 2006-05-07 20:57:26 adam Exp $
+ */
+/** \file client.c
+ * \brief yaz-client program
*/
#include <stdio.h>
static Z_ElementSetNames *elementSetNames = 0;
static int setno = 1; /* current set offset */
static enum oid_proto protocol = PROTO_Z3950; /* current app protocol */
-static enum oid_value recordsyntax = VAL_USMARC;
+#define RECORDSYNTAX_MAX 20
+static enum oid_value recordsyntax_list[RECORDSYNTAX_MAX] = { VAL_USMARC };
+static int recordsyntax_size = 1;
+
static char *record_schema = 0;
static int sent_close = 0;
static NMEM session_mem = NULL; /* memory handle for init-response */
void process_cmd_line(char* line);
-char ** readline_completer(char *text, int start, int end);
-char *command_generator(const char *text, int state);
-char** curret_global_list=NULL;
+#if HAVE_READLINE_READLINE_H
+char **readline_completer(char *text, int start, int end);
+#endif
+static char *command_generator(const char *text, int state);
int cmd_register_tab(const char* arg);
static void close_session (void);
p0->which = Z_OtherInfo_externallyDefinedInfo;
p0->information.externallyDefinedInfo =
- yaz_set_proposal_charneg(
- out,
- (const char**)&negotiationCharset,
- negotiationCharset ? 1 : 0,
- (const char**)&yazLang, yazLang ? 1 : 0,
- negotiationCharsetRecords);
+ yaz_set_proposal_charneg_list(out, ",",
+ negotiationCharset,
+ yazLang,
+ negotiationCharsetRecords);
}
}
if (oid->value == VAL_OCLCUI) {
Z_OCLC_UserInformation *oclc_ui;
ODR decode = odr_createmem(ODR_DECODE);
- odr_setbuf(decode, sat->buf, sat->len, 0);
+ odr_setbuf(decode, (char *) sat->buf, sat->len, 0);
if (!z_OCLC_UserInformation(decode, &oclc_ui, 0, 0))
printf ("Bad OCLC UserInformation:\n");
else
if (!(*type->fun)(in, &rr, 0, 0))
{
odr_perror(in, "Decoding constructed record.");
- fprintf(stdout, "[Near %d]\n", odr_offset(in));
+ fprintf(stdout, "[Near %ld]\n", (long) odr_offset(in));
fprintf(stdout, "Packet dump:\n---------\n");
odr_dumpBER(stdout, (char*)r->u.octet_aligned->buf,
r->u.octet_aligned->len);
if (record_schema)
sr->u.request->recordSchema = record_schema;
- if (recordsyntax == VAL_TEXT_XML)
+ if (recordsyntax_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML)
sr->u.explain_request->recordPacking = "xml";
return send_srw(sr);
}
if (smallSetUpperBound > 0 || (largeSetLowerBound > 1 &&
mediumSetPresentNumber > 0))
{
- req->preferredRecordSyntax =
- yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax);
-
+ if (recordsyntax_size > 0)
+ req->preferredRecordSyntax =
+ yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax_list[0]);
req->smallSetElementSetNames =
req->mediumSetElementSetNames = elementSetNames;
}
const char *pqf_msg;
size_t off;
int code = yaz_pqf_error (pqf_parser, &pqf_msg, &off);
- printf("%*s^\n", off+4, "");
+ int ioff = off;
+ printf("%*s^\n", ioff+4, "");
printf("Prefix query error: %s (code %d)\n", pqf_msg, code);
yaz_pqf_destroy (pqf_parser);
}
/* display Query Expression as part of searchResult-1 */
-static void display_queryExpression (Z_QueryExpression *qe)
+static void display_queryExpression (const char *lead, Z_QueryExpression *qe)
{
if (!qe)
return;
+ printf(" %s=", lead);
if (qe->which == Z_QueryExpression_term)
{
if (qe->u.term->queryTerm)
switch (term->which)
{
case Z_Term_general:
- printf (" %.*s", term->u.general->len, term->u.general->buf);
+ printf ("%.*s", term->u.general->len, term->u.general->buf);
break;
case Z_Term_characterString:
- printf (" %s", term->u.characterString);
+ printf ("%s", term->u.characterString);
break;
case Z_Term_numeric:
- printf (" %d", *term->u.numeric);
+ printf ("%d", *term->u.numeric);
break;
case Z_Term_null:
- printf (" null");
+ printf ("null");
break;
}
}
printf ("SearchResult-1:");
for (j = 0; j < sr->num; j++)
{
+ if (j)
+ printf(",");
if (!sr->elements[j]->subqueryExpression)
- printf (" %d", j);
- display_queryExpression (
+ printf("%d", j);
+ display_queryExpression("term",
sr->elements[j]->subqueryExpression);
- display_queryExpression (
+ display_queryExpression("interpretation",
sr->elements[j]->subqueryInterpretation);
- display_queryExpression (
+ display_queryExpression("recommendation",
sr->elements[j]->subqueryRecommendation);
if (sr->elements[j]->subqueryCount)
- printf ("(%d)", *sr->elements[j]->subqueryCount);
+ printf(" cnt=%d", *sr->elements[j]->subqueryCount);
+ if (sr->elements[j]->subqueryId)
+ printf(" id=%s ", sr->elements[j]->subqueryId);
}
printf ("\n");
}
/* save this for later .. when fetching individual records */
sr = yaz_srw_get(out, Z_SRW_explain_request);
- if (recordsyntax == VAL_TEXT_XML)
+ if (recordsyntax_size > 0 && recordsyntax_list[0] == VAL_TEXT_XML)
sr->u.explain_request->recordPacking = "xml";
send_srw(sr);
return 2;
req->resultSetStartPoint = &setno;
req->numberOfRecordsRequested = &nos;
- req->preferredRecordSyntax =
- yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax);
+ if (recordsyntax_size == 1)
+ req->preferredRecordSyntax =
+ yaz_oidval_to_z3950oid(out, CLASS_RECSYN, recordsyntax_list[0]);
- if (record_schema)
+ if (record_schema || recordsyntax_size >= 2)
{
req->recordComposition = &compo;
compo.which = Z_RecordComp_complex;
compo.u.complex->generic = (Z_Specification *)
odr_malloc(out, sizeof(*compo.u.complex->generic));
+
compo.u.complex->generic->which = Z_Schema_oid;
-
- compo.u.complex->generic->schema.oid =
- yaz_str_to_z3950oid(out, CLASS_SCHEMA, record_schema);
-
- if (!compo.u.complex->generic->schema.oid)
+ if (!record_schema)
+ compo.u.complex->generic->schema.oid = 0;
+ else
{
- /* 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);
+ compo.u.complex->generic->schema.oid =
+ yaz_str_to_z3950oid(out, CLASS_SCHEMA, record_schema);
+
+ 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);
+ }
}
if (!elementSetNames)
compo.u.complex->generic->elementSpec = 0;
}
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;
+ compo.u.complex->num_recordSyntax = recordsyntax_size;
+ compo.u.complex->recordSyntax = (Odr_oid **)
+ 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;
+ }
}
else if (elementSetNames)
{
sr->u.request->maximumRecords = odr_intdup(out, nos);
if (record_schema)
sr->u.request->recordSchema = record_schema;
- if (recordsyntax == VAL_TEXT_XML)
+ if (recordsyntax_size == 1 && recordsyntax_list[0] == VAL_TEXT_XML)
sr->u.request->recordPacking = "xml";
return send_srw(sr);
}
Z_TriggerResourceControlRequest *req =
apdu->u.triggerResourceControlRequest;
bool_t rfalse = 0;
-
+ char command[16];
+
+ *command = '\0';
+ sscanf(arg, "%15s", command);
+
if (only_z3950())
return 0;
if (session_initResponse &&
send_apdu(apdu);
printf("Sent cancel request\n");
- return 2;
+ if (!strcmp(command, "wait"))
+ return 2;
+ return 1;
}
const char *pqf_msg;
size_t off;
int code = yaz_pqf_error (pqf_parser, &pqf_msg, &off);
- printf("%*s^\n", off+7, "");
+ int ioff = off;
+ printf("%*s^\n", ioff+7, "");
printf("Prefix query error: %s (code %d)\n", pqf_msg, code);
yaz_pqf_destroy (pqf_parser);
return -1;
int cmd_format(const char *arg)
{
- oid_value nsyntax;
+ const char *cp = arg;
+ int nor;
+ int idx = 0;
+ oid_value nsyntax[RECORDSYNTAX_MAX];
+ char form_str[41];
if (!arg || !*arg)
{
printf("Usage: format <recordsyntax>\n");
return 0;
}
- nsyntax = oid_getvalbyname (arg);
- if (strcmp(arg, "none") && nsyntax == VAL_NONE)
+ while (sscanf(cp, "%40s%n", form_str, &nor) >= 1 && nor > 0
+ && idx < RECORDSYNTAX_MAX)
{
- printf ("unknown record syntax\n");
- return 0;
+ 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;
+ }
+ cp += nor;
+ idx++;
}
- recordsyntax = nsyntax;
+ recordsyntax_size = idx;
+ memcpy(recordsyntax_list, nsyntax, idx * sizeof(*nsyntax));
return 1;
}
int cmd_proxy(const char* arg)
{
- xfree (yazProxy);
- yazProxy = NULL;
+ xfree(yazProxy);
+ yazProxy = 0;
if (*arg)
yazProxy = xstrdup (arg);
return 1;
#if HAVE_READLINE_READLINE_H
rl_attempted_completion_function = (CPPFunction*)readline_completer;
#endif
-
-
- for(i=0; i<maxOtherInfosSupported; ++i) {
+ for(i = 0; i < maxOtherInfosSupported; ++i) {
extraOtherInfos[i].oidval = -1;
}
{
FILE *f = ber_file ? ber_file : stdout;
odr_perror(in, "Decoding incoming APDU");
- fprintf(f, "[Near %d]\n", odr_offset(in));
+ fprintf(f, "[Near %ld]\n", (long) odr_offset(in));
fprintf(f, "Packet dump:\n---------\n");
odr_dumpBER(f, netbuffer, res);
fprintf(f, "---------\n");
rpn = ccl_find_str (bibset, arg, &error, &pos);
if (error) {
- printf ("%*s^ - ", 3+strlen(last_cmd)+1+pos, " ");
+ int ioff = 3+strlen(last_cmd)+1+pos;
+ printf ("%*s^ - ", ioff, " ");
printf ("%s\n", ccl_err_msg (error));
}
else
int sscan_res;
int oidval;
- sscan_res = sscanf (args, "%d %100[^ ] %100s", &otherinfoNo, oidstr, otherinfoString);
+ sscan_res = sscanf (args, "%d %100[^ ] %100s",
+ &otherinfoNo, oidstr, otherinfoString);
if (sscan_res==1) {
/* reset this otherinfo */
if(otherinfoNo>=maxOtherInfosSupported) {
}
extraOtherInfos[otherinfoNo].oidval = -1;
if (extraOtherInfos[otherinfoNo].value)
- free(extraOtherInfos[otherinfoNo].value);
+ xfree(extraOtherInfos[otherinfoNo].value);
+ extraOtherInfos[otherinfoNo].value = 0;
return 0;
}
if (sscan_res<3) {
}
if (otherinfoNo>=maxOtherInfosSupported) {
- printf("Error otherinfo index to large (%d>%d)\n",
+ printf("Error otherinfo index too large (%d>=%d)\n",
otherinfoNo,maxOtherInfosSupported);
}
oidval = oid_getvalbyname (oidstr);
- if (oidval == -1 ) {
+ if (oidval == VAL_NONE)
+ {
printf("Error in set_otherinfo command unknown oid %s \n",oidstr);
return 0;
}
extraOtherInfos[otherinfoNo].oidval = oidval;
- if(extraOtherInfos[otherinfoNo].value) free(extraOtherInfos[otherinfoNo].value);
- extraOtherInfos[otherinfoNo].value = strdup(otherinfoString);
+ if (extraOtherInfos[otherinfoNo].value)
+ xfree(extraOtherInfos[otherinfoNo].value);
+ extraOtherInfos[otherinfoNo].value = xstrdup(otherinfoString);
return 0;
}
printf("ssub/lslb/mspn : %d/%d/%d\n",smallSetUpperBound,largeSetLowerBound,mediumSetPresentNumber);
/* print present related options */
- printf("Format : %s\n",yaz_z3950_oid_value_to_str(recordsyntax,CLASS_RECSYN));
+ printf("Format : %s\n",
+ (recordsyntax_size > 0) ?
+ yaz_z3950_oid_value_to_str(recordsyntax_list[0], CLASS_RECSYN) :
+ "none");
printf("Schema : %s\n",record_schema ? record_schema : "not set");
printf("Elements : %s\n",elementSetNames?elementSetNames->u.generic:"");
int cmd_clear_otherinfo(const char* args)
{
if(strlen(args)>0) {
- int otherinfoNo;
- otherinfoNo = atoi(args);
- if( otherinfoNo >= maxOtherInfosSupported ) {
- printf("Error otherinfo index to large (%d>%d)\n",otherinfoNo,maxOtherInfosSupported);
+ int otherinfoNo = atoi(args);
+ if (otherinfoNo >= maxOtherInfosSupported) {
+ printf("Error otherinfo index too large (%d>=%d)\n",
+ otherinfoNo, maxOtherInfosSupported);
return 0;
}
-
- if(extraOtherInfos[otherinfoNo].oidval != -1) {
+ if (extraOtherInfos[otherinfoNo].oidval != -1)
+ {
/* only clear if set. */
- extraOtherInfos[otherinfoNo].oidval=-1;
- free(extraOtherInfos[otherinfoNo].value);
+ extraOtherInfos[otherinfoNo].oidval = -1;
+ xfree(extraOtherInfos[otherinfoNo].value);
}
} else {
int i;
-
- for(i=0; i<maxOtherInfosSupported; ++i) {
- if (extraOtherInfos[i].oidval!=-1 ) {
- extraOtherInfos[i].oidval=-1;
- free(extraOtherInfos[i].value);
+ for(i = 0; i < maxOtherInfosSupported; ++i)
+ {
+ if (extraOtherInfos[i].oidval != -1)
+ {
+ extraOtherInfos[i].oidval = -1;
+ xfree(extraOtherInfos[i].value);
}
}
}
{"zversion", cmd_zversion, "", NULL, 0, NULL},
{"help", cmd_help, "", NULL,0,NULL},
{"init", cmd_init, "", NULL,0,NULL},
+ {"exit", cmd_quit, "",NULL,0,NULL},
{0,0,0,0,0,0}
};
return 1;
}
-int cmd_register_tab(const char* arg) {
-
+int cmd_register_tab(const char* arg)
+{
+#if HAVE_READLINE_READLINE_H
char command[101], tabargument[101];
int i;
int num_of_tabs;
}
}
- if(!cmd_array[i].cmd) {
+ if (!cmd_array[i].cmd) {
fprintf(stderr,"Unknown command %s\n",command);
return 1;
}
- if(!cmd_array[i].local_tabcompletes)
+ if (!cmd_array[i].local_tabcompletes)
cmd_array[i].local_tabcompletes = (char **) calloc(1,sizeof(char**));
num_of_tabs=0;
tabslist = cmd_array[i].local_tabcompletes;
- for(;tabslist && *tabslist;tabslist++) {
+ for(; tabslist && *tabslist; tabslist++) {
num_of_tabs++;
}
- cmd_array[i].local_tabcompletes = (char **)
- realloc(cmd_array[i].local_tabcompletes,(num_of_tabs+2)*sizeof(char**));
- tabslist=cmd_array[i].local_tabcompletes;
- tabslist[num_of_tabs]=strdup(tabargument);
- tabslist[num_of_tabs+1]=NULL;
+ cmd_array[i].local_tabcompletes = (char **)
+ realloc(cmd_array[i].local_tabcompletes,
+ (num_of_tabs+2)*sizeof(char**));
+ tabslist = cmd_array[i].local_tabcompletes;
+ tabslist[num_of_tabs] = strdup(tabargument);
+ tabslist[num_of_tabs+1] = NULL;
+#endif
return 1;
}
fflush(marc_file);
}
-
-char *command_generator(const char *text, int state)
+static char *command_generator(const char *text, int state)
{
+#if HAVE_READLINE_READLINE_H
static int idx;
if (state==0) {
idx = 0;
}
for( ; cmd_array[idx].cmd; ++idx) {
- if (!strncmp(cmd_array[idx].cmd,text,strlen(text))) {
+ if (!strncmp(cmd_array[idx].cmd, text, strlen(text))) {
++idx; /* skip this entry on the next run */
return strdup(cmd_array[idx-1].cmd);
}
}
+#endif
return NULL;
}
+#if HAVE_READLINE_READLINE_H
+static char** default_completer_list = NULL;
+
+static char* default_completer(const char* text, int state)
+{
+ return complete_from_list(default_completer_list, text, state);
+}
+#endif
+
+#if HAVE_READLINE_READLINE_H
/*
This function only known how to complete on the first word
*/
-char ** readline_completer(char *text, int start, int end) {
-#if HAVE_READLINE_READLINE_H
-
- completerFunctionType completerToUse;
-
+char **readline_completer(char *text, int start, int end)
+{
+ completerFunctionType completerToUse;
+
if(start == 0) {
#if HAVE_READLINE_RL_COMPLETION_MATCHES
- char** res=rl_completion_matches(text,
- command_generator);
+ char** res = rl_completion_matches(text, command_generator);
#else
- char** res=completion_matches(text,
- (CPFunction*)command_generator);
+ char** res = completion_matches(text,
+ (CPFunction*)command_generator);
#endif
rl_attempted_completion_over = 1;
return res;
return NULL;
}
- for (i = 0; cmd_array[i].cmd; i++) {
- if (!strncmp(cmd_array[i].cmd, word, strlen(word))) {
+ for (i = 0; cmd_array[i].cmd; i++)
+ if (!strncmp(cmd_array[i].cmd, word, strlen(word)))
break;
- }
- }
- if(!cmd_array[i].cmd) return NULL;
+ if(!cmd_array[i].cmd)
+ return NULL;
- curret_global_list = cmd_array[i].local_tabcompletes;
+ default_completer_list = cmd_array[i].local_tabcompletes;
completerToUse = cmd_array[i].rl_completerfunction;
- if(completerToUse==NULL) /* if no pr. command completer is defined use the default completer */
+ if (!completerToUse)
+ { /* if command completer is not defined use the default completer */
completerToUse = default_completer;
-
- if(completerToUse) {
+ }
+ if (completerToUse) {
#ifdef HAVE_READLINE_RL_COMPLETION_MATCHES
char** res=
- rl_completion_matches(text,
- completerToUse);
+ rl_completion_matches(text, completerToUse);
#else
char** res=
- completion_matches(text,
- (CPFunction*)completerToUse);
+ completion_matches(text, (CPFunction*)completerToUse);
#endif
- if(!cmd_array[i].complete_filenames)
+ if (!cmd_array[i].complete_filenames)
rl_attempted_completion_over = 1;
return res;
} else {
- if(!cmd_array[i].complete_filenames)
+ if (!cmd_array[i].complete_filenames)
rl_attempted_completion_over = 1;
return 0;
}
}
-#else
- return 0;
-#endif
}
-
+#endif
static void client(void)
{
add_history(line_in);
#endif
strncpy(line, line_in, 10239);
- free (line_in);
+ free(line_in);
}
#endif
if (!line_in)
hex_dump = 1;
break;
case 'p':
- yazProxy=strdup(arg);
+ yazProxy = xstrdup(arg);
break;
case 'u':
if (!auth_command)