Added new command ccl_parse which parses a ccl find command
[yaz-moved-to-github.git] / client / client.c
index 1da6fe9..8a7424f 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1995-2002, Index Data
  * See the file LICENSE for details.
  *
- * $Id: client.c,v 1.157 2002-06-04 11:36:10 adam Exp $
+ * $Id: client.c,v 1.161 2002-07-12 12:20:34 ja7 Exp $
  */
 
 #include <stdio.h>
 
 #include <yaz/yaz-util.h>
 
-#include <yaz/tcpip.h>
-#ifdef USE_XTIMOSI
-#include <yaz/xmosi.h>
-#endif
+#include <yaz/comstack.h>
 
 #include <yaz/proto.h>
 #include <yaz/marcdisp.h>
@@ -31,6 +28,7 @@
 
 #if HAVE_READLINE_READLINE_H
 #include <readline/readline.h>
+#include <unistd.h>
 #endif
 #if HAVE_READLINE_HISTORY_H
 #include <readline/history.h>
@@ -72,6 +70,7 @@ static int kilobytes = 1024;
 static char* yazCharset = 0;
 static char* yazLang = 0;
 
+
 static char last_cmd[32] = "?";
 static FILE *marcdump = 0;
 static char *refid = NULL;
@@ -106,7 +105,8 @@ int rl_attempted_completion_over = 0;
 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;
+int cmd_register_tab(char* arg);
 
 ODR getODROutputStream()
 {
@@ -207,7 +207,7 @@ static void send_initRequest(const char* type_and_host)
        
        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;
@@ -350,7 +350,6 @@ int cmd_open(char *arg)
 {
     void *add;
     char type_and_host[101], base[101];
-    CS_TYPE t;
     
     if (conn)
     {
@@ -364,23 +363,20 @@ int cmd_open(char *arg)
             session_mem = NULL;
         }
     }
-       if (strncmp (arg, "unix:", 5) == 0)
-       {
+    if (strncmp (arg, "unix:", 5) == 0)
+    {
         base[0] = '\0';
         conn = cs_create_host(arg, 1, &add);
-       }
-       else
-       {
-               t = tcpip_type;
-               base[0] = '\0';
-               if (sscanf (arg, "%100[^/]/%100s", type_and_host, base) < 1)
-                       return 0;
-               
-               if(yazProxy) 
-                       conn = cs_create_host(yazProxy, 1, &add);
-               else 
-                       conn = cs_create_host(type_and_host, 1, &add);
-               
+    }
+    else
+    {
+        base[0] = '\0';
+        if (sscanf (arg, "%100[^/]/%100s", type_and_host, base) < 1)
+            return 0;
+        if (yazProxy) 
+            conn = cs_create_host(yazProxy, 1, &add);
+        else 
+            conn = cs_create_host(type_and_host, 1, &add);
     }
     if (!conn)
     {
@@ -431,6 +427,15 @@ int cmd_authentication(char *arg)
         au.which = Z_IdAuthentication_open;
         au.u.open = user;
     }
+    if (r == 2)
+    {
+        auth = &au;
+        au.which = Z_IdAuthentication_idPass;
+        au.u.idPass = &idPass;
+        idPass.groupId = NULL;
+        idPass.userId = user;
+        idPass.password = group;
+    }
     if (r == 3)
     {
         auth = &au;
@@ -591,17 +596,18 @@ static void display_record(Z_External *r)
                 odr_perror(in, "Decoding constructed record.");
                 fprintf(stderr, "[Near %d]\n", odr_offset(in));
                 fprintf(stderr, "Packet dump:\n---------\n");
-                odr_dumpBER(stderr, (char*)r->u.octet_aligned->buf,
-                    r->u.octet_aligned->len);
+                odr_dumpBER(stderr, (char*)r->u.octet_aligned->buf,r->u.octet_aligned->len);
                 fprintf(stderr, "---------\n");
-                exit(1);
-            }
-            /*
-             * Note: we throw away the original, BER-encoded record here.
-             * Do something else with it if you want to keep it.
-             */
-            r->u.sutrs = (Z_SUTRS *) rr; /* we don't actually check the type here. */
-            r->which = type->what;
+
+                               /* note just ignores the error ant print the bytes form the octet_aligned laiter */
+            } else {
+                               /*
+                                * Note: we throw away the original, BER-encoded record here.
+                                * Do something else with it if you want to keep it.
+                                */
+                               r->u.sutrs = (Z_SUTRS *) rr; /* we don't actually check the type here. */
+                               r->which = type->what;
+                       };
         }
     }
     if (ent && ent->oclass != CLASS_RECSYN)
@@ -1349,7 +1355,6 @@ static Z_External *create_ItemOrderExternal(const char *type, int itemno)
         (int *) odr_malloc(out, sizeof(int));
     *r->u.itemOrder->u.esRequest->notToKeep->resultSetItem->item = itemno;
 
-#if YAZ_MODULE_ill
     if (!strcmp (type, "item") || !strcmp(type, "2"))
     {
         printf ("using item-request\n");
@@ -1376,9 +1381,6 @@ static Z_External *create_ItemOrderExternal(const char *type, int itemno)
     else
         r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 0;
 
-#else
-    r->u.itemOrder->u.esRequest->notToKeep->itemRequest = 0;
-#endif
     return r;
 }
 
@@ -1736,7 +1738,6 @@ int send_scanrequest(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;
     int use_rpn = 1;
-#if YAZ_MODULE_ccl
     int oid[OID_SIZE];
     
     if (queryType == QueryType_CCL2RPN)
@@ -1763,7 +1764,6 @@ int send_scanrequest(const char *query, int pp, int num, const char *term)
         }
         ccl_rpn_delete (rpn);
     }
-#endif
     if (use_rpn && !(req->termListAndStartPoint =
                      p_query_scan(out, protocol, &req->attributeSet, query)))
     {
@@ -2043,18 +2043,14 @@ int cmd_querytype (char *arg)
         queryType = QueryType_CCL;
     else if (!strcmp (arg, "prefix") || !strcmp(arg, "rpn"))
         queryType = QueryType_Prefix;
-#if YAZ_MODULE_ccl
     else if (!strcmp (arg, "ccl2rpn") || !strcmp (arg, "cclrpn"))
         queryType = QueryType_CCL2RPN;
-#endif
     else
     {
         printf ("Querytype must be one of:\n");
         printf (" prefix         - Prefix query\n");
         printf (" ccl            - CCL query\n");
-#if YAZ_MODULE_ccl
         printf (" ccl2rpn        - CCL query converted to RPN\n");
-#endif
         return 0;
     }
     return 1;
@@ -2235,7 +2231,6 @@ int cmd_set_apdufile(char* arg)
 
 int cmd_set_cclfields(char* arg)
 {  
-#if YAZ_MODULE_ccl
     FILE *inf;
 
     REMOVE_TAILING_BLANKS(arg);
@@ -2247,9 +2242,6 @@ int cmd_set_cclfields(char* arg)
         ccl_qual_file (bibset, inf);
         fclose (inf);
     }
-#else 
-    fprintf(stderr,"Not compiled with the yaz ccl module\n");
-#endif
     
     return 1;
 }
@@ -2365,7 +2357,8 @@ int cmd_register_oid(char* args) {
     return 1;  
 }
 
-int cmd_push_command(char* arg) {
+int cmd_push_command(char* arg) 
+{
 #if HAVE_READLINE_HISTORY_H
     if(strlen(arg)>1) 
         add_history(arg);
@@ -2375,11 +2368,13 @@ int cmd_push_command(char* arg) {
     return 1;
 }
 
-void source_rcfile() {
+void source_rcfile() 
+{
     /*  Look for a $HOME/.yazclientrc and source it if it exists */
     struct stat statbuf;
     char buffer[1000];
     char* homedir=getenv("HOME");
+
     if(!homedir) return;
     
     sprintf(buffer,"%s/.yazclientrc",homedir);
@@ -2396,9 +2391,7 @@ void source_rcfile() {
 
 static void initialize(void)
 {
-#if YAZ_MODULE_ccl
     FILE *inf;
-#endif
     if (!(out = odr_createmem(ODR_ENCODE)) ||
         !(in = odr_createmem(ODR_DECODE)) ||
         !(print = odr_createmem(ODR_PRINT)))
@@ -2412,7 +2405,6 @@ static void initialize(void)
     if (apdu_file)
         odr_setprint(print, apdu_file);
 
-#if YAZ_MODULE_ccl
     bibset = ccl_qual_mk (); 
     inf = fopen (ccl_fields, "r");
     if (inf)
@@ -2420,7 +2412,6 @@ static void initialize(void)
         ccl_qual_file (bibset, inf);
         fclose (inf);
     }
-#endif
     cmd_base("Default");
 
 #if HAVE_READLINE_READLINE_H
@@ -2547,63 +2538,95 @@ void wait_and_handle_responce()
 }
 
 
+int cmd_cclparse(char* arg) {
+    int error, pos;
+       struct ccl_rpn_node *rpn=NULL;
+       
+       
+       rpn = ccl_find_str (bibset, arg, &error, &pos);
+       
+       if (error) {
+               printf ("%*s^ - ", 3+strlen(last_cmd)+1+pos, " ");
+               printf ("%s\n", ccl_err_msg (error));
+       }
+       else
+       {
+               if (rpn)
+               {       
+                       ccl_pr_tree(rpn, stdout); 
+               }
+       }
+       if (rpn)
+               ccl_rpn_delete(rpn);
+
+    printf ("\n");
+       
+       return 0;
+};
+
+
 static int cmd_help (char *line);
 
+typedef char *(*completerFunctionType)(const char *text, int state);
+
 static struct {
     char *cmd;
     int (*fun)(char *arg);
     char *ad;
-    char *(*rl_completerfunction)(const char *text, int state);
+       completerFunctionType rl_completerfunction;
     int complete_filenames;
+       char **local_tabcompletes;
 } cmd[] = {
-    {"open", cmd_open, "('tcp'|'ssl')':<host>[':'<port>][/<db>]",NULL,0},
-    {"quit", cmd_quit, "",NULL,0},
-    {"find", cmd_find, "<query>",NULL,0},
-    {"delete", cmd_delete, "<setname>",NULL,0},
-    {"base", cmd_base, "<base-name>",NULL,0},
-    {"show", cmd_show, "<rec#>['+'<#recs>['+'<setname>]]",NULL,0},
-    {"scan", cmd_scan, "<term>",NULL,0},
-    {"sort", cmd_sort, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0},
-    {"sort+", cmd_sort_newset, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0},
-    {"authentication", cmd_authentication, "<acctstring>",NULL,0},
-    {"lslb", cmd_lslb, "<largeSetLowerBound>",NULL,0},
-    {"ssub", cmd_ssub, "<smallSetUpperBound>",NULL,0},
-    {"mspn", cmd_mspn, "<mediumSetPresentNumber>",NULL,0},
-    {"status", cmd_status, "",NULL,0},
-    {"setnames", cmd_setnames, "",NULL,0},
-    {"cancel", cmd_cancel, "",NULL,0},
-    {"format", cmd_format, "<recordsyntax>",complete_format,0},
-    {"schema", cmd_schema, "<schema>",complete_schema,0},
-    {"elements", cmd_elements, "<elementSetName>",NULL,0},
-    {"close", cmd_close, "",NULL,0},
-    {"attributeset", cmd_attributeset, "<attrset>",complete_attributeset,0},
-    {"querytype", cmd_querytype, "<type>",complete_querytype,0},
-    {"refid", cmd_refid, "<id>",NULL,0},
-    {"itemorder", cmd_itemorder, "ill|item <itemno>",NULL,0},
-    {"update", cmd_update, "<item>",NULL,0},
-    {"packagename", cmd_packagename, "<packagename>",NULL,0},
-    {"proxy", cmd_proxy, "[('tcp'|'ssl')]<host>[':'<port>]",NULL,0},
-    {"charset", cmd_charset, "<charset_name>",NULL,0},
-    {"lang", cmd_lang, "<language_code>",NULL,0},
-    {".", cmd_source, "<filename>",NULL,1},
-    {"!", cmd_subshell, "Subshell command",NULL,0},
-    {"set_apdufile", cmd_set_apdufile, "<filename>",NULL,0},
-    {"set_marcdump", cmd_set_marcdump," <filename>",NULL,0},
-    {"set_cclfields", cmd_set_cclfields,"<filename>",NULL,1}, 
-    {"register_oid",cmd_register_oid,"<name> <class> <oid>",NULL,0},
-    {"push_command",cmd_push_command,"<command>",command_generator,0},
+    {"open", cmd_open, "('tcp'|'ssl')':<host>[':'<port>][/<db>]",NULL,0,NULL},
+    {"quit", cmd_quit, "",NULL,0,NULL},
+    {"find", cmd_find, "<query>",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},
+    {"scan", cmd_scan, "<term>",NULL,0,NULL},
+    {"sort", cmd_sort, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0,NULL},
+    {"sort+", cmd_sort_newset, "<sortkey> <flag> <sortkey> <flag> ...",NULL,0,NULL},
+    {"authentication", cmd_authentication, "<acctstring>",NULL,0,NULL},
+    {"lslb", cmd_lslb, "<largeSetLowerBound>",NULL,0,NULL},
+    {"ssub", cmd_ssub, "<smallSetUpperBound>",NULL,0,NULL},
+    {"mspn", cmd_mspn, "<mediumSetPresentNumber>",NULL,0,NULL},
+    {"status", cmd_status, "",NULL,0,NULL},
+    {"setnames", cmd_setnames, "",NULL,0,NULL},
+    {"cancel", cmd_cancel, "",NULL,0,NULL},
+    {"format", cmd_format, "<recordsyntax>",complete_format,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 <itemno>",NULL,0,NULL},
+    {"update", cmd_update, "<item>",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},
+    {"lang", cmd_lang, "<language_code>",NULL,0,NULL},
+    {".", cmd_source, "<filename>",NULL,1,NULL},
+    {"!", cmd_subshell, "Subshell command",NULL,1,NULL},
+    {"set_apdufile", cmd_set_apdufile, "<filename>",NULL,1,NULL},
+    {"set_marcdump", cmd_set_marcdump," <filename>",NULL,1,NULL},
+    {"set_cclfile", cmd_set_cclfields," <filename>",NULL,1,NULL},
+    {"register_oid", cmd_register_oid,"<name> <class> <oid>",NULL,0,NULL},
+    {"push_command", cmd_push_command,"<command>",command_generator,0,NULL},
+       {"register_tab", cmd_register_tab,"<commandname> <tab>",command_generator,0,NULL},
+       {"cclparse", cmd_cclparse,"<ccl find command>",NULL,0,NULL},
     /* Server Admin Functions */
-    {"adm-reindex", cmd_adm_reindex, "<database-name>",NULL,0},
-    {"adm-truncate", cmd_adm_truncate, "('database'|'index')<object-name>",NULL,0},
-    {"adm-create", cmd_adm_create, "",NULL,0},
-    {"adm-drop", cmd_adm_drop, "('database'|'index')<object-name>",NULL,0},
-    {"adm-import", cmd_adm_import, "<record-type> <dir> <pattern>",NULL,0},
-    {"adm-refresh", cmd_adm_refresh, "",NULL,0},
-    {"adm-commit", cmd_adm_commit, "",NULL,0},
-    {"adm-shutdown", cmd_adm_shutdown, "",NULL,0},
-    {"adm-startup", cmd_adm_startup, "",NULL,0},
-    {"help", cmd_help, "", NULL},
-    {0,0,0,0,0}
+    {"adm-reindex", cmd_adm_reindex, "<database-name>",NULL,0,NULL},
+    {"adm-truncate", cmd_adm_truncate, "('database'|'index')<object-name>",NULL,0,NULL},
+    {"adm-create", cmd_adm_create, "",NULL,0,NULL},
+    {"adm-drop", cmd_adm_drop, "('database'|'index')<object-name>",NULL,0,NULL},
+    {"adm-import", cmd_adm_import, "<record-type> <dir> <pattern>",NULL,0,NULL},
+    {"adm-refresh", cmd_adm_refresh, "",NULL,0,NULL},
+    {"adm-commit", cmd_adm_commit, "",NULL,0,NULL},
+    {"adm-shutdown", cmd_adm_shutdown, "",NULL,0,NULL},
+    {"adm-startup", cmd_adm_startup, "",NULL,0,NULL},
+    {"help", cmd_help, "", NULL,0,NULL},
+    {0,0,0,0,0,0}
 };
 
 static int cmd_help (char *line)
@@ -2646,6 +2669,50 @@ static int cmd_help (char *line)
     return 1;
 }
 
+int cmd_register_tab(char* arg) {
+       
+       char command[101], tabargument[101];
+       int i;
+       int num_of_tabs;
+       char** tabslist;
+
+       if (sscanf (arg, "%100s %100s", command, tabargument) < 1) {
+               return 0;
+       };
+
+       /* locate the amdn in the list */
+       for (i = 0; cmd[i].cmd; i++) {
+               if (!strncmp(cmd[i].cmd, command, strlen(command))) {
+                       break;
+               }
+       }
+       
+       if(!cmd[i].cmd) { 
+               fprintf(stderr,"Unknown command %s\n",command);
+               return 1;
+       };
+       
+
+
+       if(!cmd[i].local_tabcompletes) {
+               cmd[i].local_tabcompletes = calloc(1,sizeof(char**));
+       };
+       
+       num_of_tabs=0;          
+       
+       tabslist = cmd[i].local_tabcompletes;
+       for(;tabslist && *tabslist;tabslist++) {
+               num_of_tabs++;
+       };  
+
+       cmd[i].local_tabcompletes=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;
+    return 1;
+}
+
+
 void process_cmd_line(char* line)
 {  
     int i,res;
@@ -2728,6 +2795,8 @@ char *command_generator(const char *text, int state)
 char ** readline_completer(char *text, int start, int end) {
 #if HAVE_READLINE_READLINE_H
 
+       completerFunctionType completerToUse;
+       
     if(start == 0) {
 #if HAVE_READLINE_RL_COMPLETION_MATCHES
         char** res=rl_completion_matches(text,
@@ -2756,23 +2825,31 @@ char ** readline_completer(char *text, int start, int end) {
             }
         }
     
+               if(!cmd[i].cmd) return NULL;
 
-        if(!cmd[i].complete_filenames) 
-            rl_attempted_completion_over = 1;    
-        if(cmd[i].rl_completerfunction) {
+
+               curret_global_list = cmd[i].local_tabcompletes;
+               
+               completerToUse = cmd[i].rl_completerfunction;
+               if(completerToUse==NULL)  /* if no pr. command completer is defined use the default completer */
+                       completerToUse = default_completer;
+               
+        if(completerToUse) {
 #ifdef HAVE_READLINE_RL_COMPLETION_MATCHES
             char** res=
                 rl_completion_matches(text,
-                                   cmd[i].rl_completerfunction);
+                                   completerToUse);
 #else
             char** res=
                 completion_matches(text,
-                                   (CPFunction*)cmd[i].rl_completerfunction);
+                                   (CPFunction*)completerToUse);
 #endif
-            rl_attempted_completion_over = 1;    
-            return res;
+                       if(!cmd[i].complete_filenames) 
+                               rl_attempted_completion_over = 1;
+                       return res;
         } else {
-            rl_attempted_completion_over = 1;
+                       if(!cmd[i].complete_filenames) 
+                               rl_attempted_completion_over = 1;
             return 0;
         }
     }
@@ -2853,19 +2930,19 @@ int main(int argc, char **argv)
                 exit (1);
             }
             break;
-    case 'c':
-        strncpy (ccl_fields, arg, sizeof(ccl_fields)-1);
-        ccl_fields[sizeof(ccl_fields)-1] = '\0';
-        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)
             {