Added object Yaz_Z_Assoc. Much more functional client.
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 9 Apr 1999 11:46:57 +0000 (11:46 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 9 Apr 1999 11:46:57 +0000 (11:46 +0000)
15 files changed:
include/yaz-ir-assoc.h
include/yaz-pdu-observer.h
include/yaz-proxy.h
include/yaz-z-assoc.h [new file with mode: 0644]
include/yaz-z-query.h
src/Makefile.in
src/yaz-client.cpp
src/yaz-ir-assoc.cpp
src/yaz-pdu-assoc.cpp
src/yaz-proxy-main.cpp
src/yaz-proxy.cpp
src/yaz-server.cpp
src/yaz-socket-manager.cpp
src/yaz-z-assoc.cpp [new file with mode: 0644]
src/yaz-z-query.cpp

index a5f998d..ad7efbb 100644 (file)
@@ -4,65 +4,80 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-ir-assoc.h,v $
- * Revision 1.4  1999-03-23 14:17:57  adam
- * More work on timeout handling. Work on yaz-client.
- *
- * Revision 1.3  1999/02/02 14:01:12  adam
- * First WIN32 port of YAZ++.
- *
- * Revision 1.2  1999/01/28 13:08:39  adam
- * Yaz_PDU_Assoc better encapsulated. Memory leak fix in
- * yaz-socket-manager.cc.
- *
- * Revision 1.1.1.1  1999/01/28 09:41:07  adam
- * First implementation of YAZ++.
+ * Revision 1.5  1999-04-09 11:47:23  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
  *
  */
 
-
-#include <proto.h>
-#include <odr.h>
-#include <yaz-pdu-observer.h>
+#include <yaz-z-assoc.h>
+#include <yaz-z-query.h>
 
 /** Information Retrieval Assocation.
     This object implements the client - and server role of a generic
     Z39.50 Association.
 */
-class YAZ_EXPORT Yaz_IR_Assoc : public IYaz_PDU_Observer {
+class YAZ_EXPORT Yaz_IR_Assoc: public Yaz_Z_Assoc {
  public:
     /// Create object using the PDU Observer specified
     Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable);
     /// Destroy assocation and close PDU Observer
     virtual ~Yaz_IR_Assoc();
-    /// Receive PDU
-    void recv_PDU(const char *buf, int len);
-    /// Connect notification
-    void connectNotify();
-    /// Failure notification
-    void failNotify();
-    /// Timeout notification
-    void timeoutNotify();
-    /// Begin Z39.50 client role
-    void client(const char *addr);
-    /// Begin Z39.50 server role
-    void server(const char *addr);
-    /// Decode Z39.50 PDU.
-    Z_APDU *decode_Z_PDU(const char *buf, int len);
-    /// Encode Z39.50 PDU.
-    int encode_Z_PDU(Z_APDU *apdu, char **buf, int *len);
-    /// Send Z39.50 PDU
-    int send_Z_PDU(Z_APDU *apdu);
     /// Receive Z39.50 PDU
-    virtual void recv_Z_PDU(Z_APDU *apdu) = 0;
-    /// Create Z39.50 PDU with reasonable defaults
-    Z_APDU *create_Z_PDU(int type);
-    /// Request Alloc
-    ODR odr_encode ();
+    void recv_Z_PDU(Z_APDU *apdu);
+    /// Set Database Names
+    void set_databaseNames (int num, const char **list);
+    void set_databaseNames(const char *dblist, const char *sep);
+    /// Get Database Names
+    void get_databaseNames (int *num, char ***list);
+
+    void client(const char *addr);
+
+    /// Set Preferred Record Syntax
+    void set_preferredRecordSyntax (int value);
+    void set_preferredRecordSyntax (const char *syntax);
+    /// Get Preferred Record Syntax
+    void get_preferredRecordSyntax (int *val);
+    void get_preferredRecordSyntax (const char **syntax);
+
+    /// Set ElementSetName
+    void set_elementSetName (const char *elementSetName);
+    /// Get ElementSetName
+    void get_elementSetName (const char **elementSetName);
+    void get_elementSetName (Z_ElementSetNames **elementSetNames);
+
+    int get_lastReceived();
+    void set_lastReceived(int lastReceived);
+
+    /// OtherInformation
+    Z_OtherInformationUnit *set_otherInformation(
+       Z_OtherInformation **otherInformationP, int *oid,
+       int categoryValue);
+    void set_otherInformationString (Z_OtherInformation **otherInformationP,
+                                    int *oid, int categoryValue,
+                                    const char *str);
+
+    /// Settings
+    void set_proxy(const char *str);
+    const char *get_proxy();
+    const char *get_host();
+
+    /// Send Services
+    int send_initRequest();
+    int send_searchRequest(Yaz_Z_Query *query);
+    int send_presentRequest(int start, int number);
+    /// Recv Services
+    virtual void recv_initRequest(Z_InitRequest *initRequest);
+    virtual void recv_initResponse(Z_InitResponse *initResponse);
+    virtual void recv_searchRequest(Z_SearchRequest *searchRequest);
+    virtual void recv_presentRequest(Z_PresentRequest *presentRequest);
+    virtual void recv_searchResponse(Z_SearchResponse *searchResponse);
+    virtual void recv_presentResponse(Z_PresentResponse *presentResponse);
  private:
-    static int yaz_init_flag;
-    static int yaz_init_func();
-    IYaz_PDU_Observable *m_PDU_Observable;
-    ODR m_odr_in;
-    ODR m_odr_out;
-    ODR m_odr_print;
+    char *m_proxy;
+    char *m_host;
+    int m_num_databaseNames;
+    char **m_databaseNames;
+    int m_preferredRecordSyntax;
+    Z_ElementSetNames *m_elementSetNames;
+    int m_lastReceived;
 };
index 78618bf..f89436f 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-pdu-observer.h,v $
- * Revision 1.4  1999-03-23 14:17:57  adam
+ * Revision 1.5  1999-04-09 11:47:23  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.4  1999/03/23 14:17:57  adam
  * More work on timeout handling. Work on yaz-client.
  *
  * Revision 1.3  1999/02/02 14:01:14  adam
@@ -60,7 +63,7 @@ class YAZ_EXPORT IYaz_PDU_Observer {
     virtual void connectNotify() = 0;
     /// Called whenever the connection was closed
     virtual void failNotify() = 0;
-    /// Called whenever the connection was closed
+    /// Called whenever there is a timeout
     virtual void timeoutNotify() = 0;
     /// Make clone of observer using IYaz_PDU_Observable interface
     virtual IYaz_PDU_Observer *clone(IYaz_PDU_Observable *the_PDU_Observable) = 0;
index 8b09c91..9d8e213 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-proxy.h,v $
- * Revision 1.2  1999-02-02 14:01:15  adam
+ * Revision 1.3  1999-04-09 11:47:23  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.2  1999/02/02 14:01:15  adam
  * First WIN32 port of YAZ++.
  *
  * Revision 1.1.1.1  1999/01/28 09:41:07  adam
  *
  */
 
-#include <yaz-ir-assoc.h>
+#include <yaz-z-assoc.h>
 
 class Yaz_Proxy;
 
 /// Private class
-class YAZ_EXPORT Yaz_ProxyClient : public Yaz_IR_Assoc {
+class YAZ_EXPORT Yaz_ProxyClient : public Yaz_Z_Assoc {
     friend Yaz_Proxy;
     Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable);
     void recv_Z_PDU(Z_APDU *apdu);
@@ -36,7 +39,7 @@ class YAZ_EXPORT Yaz_ProxyMap {
 };
 
 /// Information Retrieval Proxy Server.
-class YAZ_EXPORT Yaz_Proxy : public Yaz_IR_Assoc {
+class YAZ_EXPORT Yaz_Proxy : public Yaz_Z_Assoc {
  public:
     Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable);
     ~Yaz_Proxy();
diff --git a/include/yaz-z-assoc.h b/include/yaz-z-assoc.h
new file mode 100644 (file)
index 0000000..caec440
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1998-1999, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ * 
+ * $Log: yaz-z-assoc.h,v $
+ * Revision 1.1  1999-04-09 11:47:23  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ */
+
+#include <proto.h>
+#include <odr.h>
+#include <yaz-pdu-observer.h>
+
+/** Z39.50 Assocation.
+    This object implements the client - and server role of a generic
+    Z39.50 Association.
+*/
+class YAZ_EXPORT Yaz_Z_Assoc : public IYaz_PDU_Observer {
+ public:
+    /// Create object using the PDU Observer specified
+    Yaz_Z_Assoc(IYaz_PDU_Observable *the_PDU_Observable);
+    /// Destroy assocation and close PDU Observer
+    virtual ~Yaz_Z_Assoc();
+    /// Receive PDU
+    void recv_PDU(const char *buf, int len);
+    /// Connect notification
+    void connectNotify();
+    /// Failure notification
+    void failNotify();
+    /// Timeout notification
+    void timeoutNotify();
+    /// Begin Z39.50 client role
+    void client(const char *addr);
+    /// Begin Z39.50 server role
+    void server(const char *addr);
+    /// Close connection
+    void close();
+    /// Decode Z39.50 PDU.
+    Z_APDU *decode_Z_PDU(const char *buf, int len);
+    /// Encode Z39.50 PDU.
+    int encode_Z_PDU(Z_APDU *apdu, char **buf, int *len);
+    /// Send Z39.50 PDU
+    int send_Z_PDU(Z_APDU *apdu);
+    /// Receive Z39.50 PDU
+    virtual void recv_Z_PDU(Z_APDU *apdu) = 0;
+    /// Create Z39.50 PDU with reasonable defaults
+    Z_APDU *create_Z_PDU(int type);
+    /// Request Alloc
+    ODR odr_encode ();
+ private:
+    static int yaz_init_flag;
+    static int yaz_init_func();
+    IYaz_PDU_Observable *m_PDU_Observable;
+    ODR m_odr_in;
+    ODR m_odr_out;
+    ODR m_odr_print;
+};
index b35bb8b..8febc1e 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-z-query.h,v $
- * Revision 1.1  1999-03-23 14:17:57  adam
+ * Revision 1.2  1999-04-09 11:47:23  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.1  1999/03/23 14:17:57  adam
  * More work on timeout handling. Work on yaz-client.
  *
  */
@@ -22,7 +25,7 @@ class YAZ_EXPORT Yaz_Z_Query : public Yaz_Query {
     /// Delete Query
     virtual ~Yaz_Z_Query();
     /// Set RPN
-    void set_rpn (const char *rpn);
+    int set_rpn (const char *rpn);
     /// Set Z Query
     void set_Z_Query (Z_Query *z_query);
     /// Get Z Query
index b14caa9..bef737b 100644 (file)
@@ -1,7 +1,7 @@
 # Copyright (C) 1999, Index Data ApS
 # All rights reserved.
 # Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile.in,v 1.3 1999-03-23 14:17:57 adam Exp $
+# $Id: Makefile.in,v 1.4 1999-04-09 11:46:57 adam Exp $
 
 SHELL=/bin/sh
 
@@ -18,8 +18,7 @@ LIBDIR=../../yaz/lib
 INCLUDE=-I../../yaz/z39.50 -I../../yaz/include -I../include
 DEFS=$(INCLUDE) $(CDEFS)
 YAZLIBS=$(LIBDIR)/libasn.a \
-  $(LIBDIR)/libcomstack.a $(LIBDIR)/ccl.a \
-  $(LIBDIR)/libodr.a $(LIBDIR)/libutil.a 
+  $(LIBDIR)/libcomstack.a $(LIBDIR)/libodr.a $(LIBDIR)/libutil.a 
 PROG1=yaz-client
 PROGO1=yaz-client.o
 PROG2=yaz-server
@@ -27,8 +26,8 @@ PROGO2=yaz-server.o
 PROG3=yaz-proxy
 PROGO3=yaz-proxy-main.o
 LIB=libyaz++.lib
-PO=yaz-socket-manager.o yaz-pdu-assoc.o yaz-ir-assoc.o yaz-proxy.o \
-       yaz-z-query.o
+PO=yaz-socket-manager.o yaz-pdu-assoc.o yaz-z-assoc.o yaz-proxy.o \
+       yaz-z-query.o yaz-ir-assoc.o
 
 .SUFFIXES: .cpp
 
index 7f67f35..8a88bc3 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-client.cpp,v $
- * Revision 1.4  1999-03-23 14:17:57  adam
+ * Revision 1.5  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.4  1999/03/23 14:17:57  adam
  * More work on timeout handling. Work on yaz-client.
  *
  * Revision 1.3  1999/02/02 14:01:18  adam
  */
 
 #include <log.h>
+#include <options.h>
 #include <yaz-ir-assoc.h>
 #include <yaz-pdu-assoc.h>
 #include <yaz-socket-manager.h>
-#include <yaz-z-query.h>
+
+extern "C" {
+#if HAVE_READLINE_READLINE_H
+#include <readline/readline.h>
+#endif
+#if HAVE_READLINE_HISTORY_H
+#include <readline/history.h>
+#endif
+}
 
 class YAZ_EXPORT MyClient : public Yaz_IR_Assoc {
+private:
+    int m_interactive_flag;
+    char m_thisCommand[1024];
+    char m_lastCommand[1024];
+    Yaz_SocketManager *m_socketManager;
 public:
-    MyClient(IYaz_PDU_Observable *the_PDU_Observable);
-    void recv_Z_PDU(Z_APDU *apdu);
+    MyClient(IYaz_PDU_Observable *the_PDU_Observable,
+            Yaz_SocketManager *the_SocketManager);
     IYaz_PDU_Observer *clone(IYaz_PDU_Observable *the_PDU_Observable);
-    void init();
-    void search(Yaz_Z_Query *query);
-    void present(int start, int number);
-    void set_databaseNames (int num, char **list);
-    void set_syntax (const char *syntax);
-    void set_elementSetName (const char *elementSetName);
-private:
-    int m_num_databaseNames;
-    char **m_databaseNames;
-    int m_recordSyntax;
-    Z_ElementSetNames *m_elementSetNames;
+    int args(Yaz_SocketManager *socketManager, int argc, char **argv);
+    int interactive(Yaz_SocketManager *socketManager);
+    int wait();
+    void recv_initResponse(Z_InitResponse *initResponse);
+    void recv_searchResponse(Z_SearchResponse *searchResponse);
+    int processCommand(const char *cmd);
+    const char *MyClient::getCommand();
+    int cmd_open(char *host);
+    int cmd_quit(char *args);
+    int cmd_close(char *args);
+    int cmd_find(char *args);
 };
 
-void MyClient::recv_Z_PDU(Z_APDU *apdu)
-{
-    logf (LOG_LOG, "recv_APDU");
-    switch (apdu->which)
-    {
-    case Z_APDU_initResponse:
-        logf (LOG_LOG, "got InitResponse");
-        break;
-    case Z_APDU_searchResponse:
-        logf (LOG_LOG, "got searchResponse");
-        break;
-    case Z_APDU_presentResponse:
-        logf (LOG_LOG, "got presentResponse");
-        break;
-    }
-}
-
 IYaz_PDU_Observer *MyClient::clone(IYaz_PDU_Observable *the_PDU_Observable)
 {
-    return new MyClient(the_PDU_Observable);
+    return new MyClient(the_PDU_Observable, m_socketManager);
 }
 
-MyClient::MyClient(IYaz_PDU_Observable *the_PDU_Observable) :
+MyClient::MyClient(IYaz_PDU_Observable *the_PDU_Observable,
+                  Yaz_SocketManager *the_socketManager) :
     Yaz_IR_Assoc (the_PDU_Observable)
 {
-    m_num_databaseNames = 0;
-    m_databaseNames = 0;
-    m_recordSyntax = VAL_NONE;
+    m_interactive_flag = 1;
+    m_thisCommand[0] = '\0';
+    m_lastCommand[0] = '\0';
+    m_socketManager = the_socketManager;
 }
 
-void MyClient::set_databaseNames (int num, char **list)
+void usage(char *prog)
 {
-    int i;
-    for (i = 0; i<m_num_databaseNames; i++)
-       delete m_databaseNames[i];
-    delete m_databaseNames;
-    m_databaseNames = 0;
-    m_num_databaseNames = num;
-    m_databaseNames = new (char*) [num];
-    for (i = 0; i<m_num_databaseNames; i++)
-    {
-       m_databaseNames[i] = new char[strlen(list[i])+1];
-       strcpy (m_databaseNames[i], list[i]);
-    }
+    fprintf (stderr, "%s: [-v log] [-p proxy] [zurl]\n", prog);
+    exit (1);
 }
 
-void MyClient::set_syntax (const char *syntax)
+void MyClient::recv_initResponse(Z_InitResponse *initResponse)
 {
-    m_recordSyntax = VAL_NONE;
-    if (syntax && *syntax)
-       m_recordSyntax = oid_getvalbyname (syntax);
+    printf ("Got InitResponse. Status ");
+    if (*initResponse->result)
+       printf ("Ok\n");
+    else
+       printf ("Fail\n");
 }
 
-void MyClient::set_elementSetName (const char *elementSetName)
+void MyClient::recv_searchResponse(Z_SearchResponse *searchResponse)
 {
-    if (m_elementSetNames)
-       delete [] m_elementSetNames->u.generic;
-    delete m_elementSetNames;
-    m_elementSetNames = 0;
-    if (elementSetName && *elementSetName)
+    printf ("Got SearchResponse. Status ");
+    if (!*searchResponse->searchStatus)
     {
-       m_elementSetNames = new Z_ElementSetNames;
-       m_elementSetNames->which = Z_ElementSetNames_generic;
-       m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
-       strcpy (m_elementSetNames->u.generic, elementSetName);
+       printf ("Fail\n");
+       return;
     }
+    printf ("Ok\n");
+    printf ("Hits: %d\n", *searchResponse->resultCount);
 }
 
-void MyClient::search(Yaz_Z_Query *query)
+int MyClient::wait()
 {
-    Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
-    Z_SearchRequest *req = apdu->u.searchRequest;
-
-    req->num_databaseNames = m_num_databaseNames;
-    req->databaseNames = m_databaseNames;
-    req->query = query->get_Z_Query();
-
-    int oid_syntax[OID_SIZE];
-    oident prefsyn;
-    if (m_recordSyntax != VAL_NONE)
+    set_lastReceived(0);
+    while (m_socketManager->processEvent() > 0)
     {
-       prefsyn.proto = PROTO_Z3950;
-       prefsyn.oclass = CLASS_RECSYN;
-       prefsyn.value = (enum oid_value) m_recordSyntax;
-       oid_ent_to_oid(&prefsyn, oid_syntax);
-       req->preferredRecordSyntax = oid_syntax;
+       if (get_lastReceived())
+           return 1;
     }
-    send_Z_PDU(apdu);
+    return 0;
+}
+
+#define C_PROMPT "Z>"
+
+int MyClient::cmd_open(char *host)
+{
+    client (host);
+    if (send_initRequest() >= 0)
+       wait();
+    else
+       close();
+    return 1;
 }
 
-void MyClient::present(int start, int number)
+int MyClient::cmd_quit(char *args)
 {
-    Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
-    Z_PresentRequest *req = apdu->u.presentRequest;
+    return 0;
+}
 
-    req->resultSetStartPoint = &start;
-    req->numberOfRecordsRequested = &number;
+int MyClient::cmd_close(char *args)
+{
+    close();
+    return 1;
+}
 
-    int oid_syntax[OID_SIZE];
-    oident prefsyn;
-    if (m_recordSyntax != VAL_NONE)
+int MyClient::cmd_find(char *args)
+{
+    Yaz_Z_Query query;
+
+    if (query.set_rpn(args) <= 0)
     {
-       prefsyn.proto = PROTO_Z3950;
-       prefsyn.oclass = CLASS_RECSYN;
-       prefsyn.value = (enum oid_value) m_recordSyntax;
-       oid_ent_to_oid(&prefsyn, oid_syntax);
-       req->preferredRecordSyntax = oid_syntax;
+       printf ("Bad RPN query\n");
+       return 1;
     }
-    Z_RecordComposition compo;
-    if (m_elementSetNames)
+    if (send_searchRequest(&query) >= 0)
+       wait();
+    return 1;
+}
+
+int MyClient::processCommand(const char *commandLine)
+{
+    char cmdStr[1024], cmdArgs[1024];
+    cmdArgs[0] = '\0';
+    cmdStr[0] = '\0';
+    static struct {
+        char *cmd;
+        int (MyClient::*fun)(char *arg);
+        char *ad;
+    } cmd[] = {
+       {"open", &cmd_open, "('tcp'|'osi')':'[<tsel>'/']<host>[':'<port>]"},
+        {"quit", &cmd_quit, ""},
+       {"close", &cmd_close, ""},
+       {"find", &cmd_find, ""},
+       {0,0,0}
+    };
+    
+    if (sscanf(commandLine, "%s %[^;]", cmdStr, cmdArgs) < 1)
+       return 1;
+    int i;
+    for (i = 0; cmd[i].cmd; i++)
+       if (!strncmp(cmd[i].cmd, cmdStr, strlen(cmdStr)))
+           break;
+    
+    int res = 1;
+    if (cmd[i].cmd) // Invoke command handler
+       res = (this->*cmd[i].fun)(cmdArgs);
+    else            // Dump help screen
     {
-       req->recordComposition = &compo;
-        compo.which = Z_RecordComp_simple;
-        compo.u.simple = m_elementSetNames;
+       printf("Unknown command: %s.\n", cmdStr);
+       printf("Currently recognized commands:\n");
+       for (i = 0; cmd[i].cmd; i++)
+           printf("   %s %s\n", cmd[i].cmd, cmd[i].ad);
     }
-    send_Z_PDU(apdu);
+    return res;
 }
 
-void MyClient::init()
+const char *MyClient::getCommand()
 {
-    Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
-    Z_InitRequest *req = apdu->u.initRequest;
-    
-    ODR_MASK_SET(req->options, Z_Options_search);
-    ODR_MASK_SET(req->options, Z_Options_present);
-    ODR_MASK_SET(req->options, Z_Options_namedResultSets);
-    ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
-    ODR_MASK_SET(req->options, Z_Options_scan);
-    ODR_MASK_SET(req->options, Z_Options_sort);
-    ODR_MASK_SET(req->options, Z_Options_extendedServices);
-    ODR_MASK_SET(req->options, Z_Options_delSet);
+#if HAVE_READLINE_READLINE_H
+    // Read using GNU readline
+    char *line_in;
+    line_in=readline(C_PROMPT);
+    if (!line_in)
+       return 0;
+#if HAVE_READLINE_HISTORY_H
+    if (*line_in)
+       add_history(line_in);
+#endif
+    strncpy(m_thisCommand,line_in, 1023);
+    m_thisCommand[1023] = '\0';
+    free (line_in);
+#else    
+    // Read using fgets(3)
+    printf (C_PROMPT);
+    fflush(stdout);
+    if (!fgets(m_thisCommand, 1023, stdin))
+       return 0;
+#endif
+    // Remove trailing whitespace
+    char *cp = m_thisCommand + strlen(m_thisCommand);
+    while (cp != m_thisCommand && strchr("\t \n", cp[-1]))
+       cp--;
+    *cp = '\0';
+    cp = m_thisCommand;
+    // Remove leading spaces...
+    while (strchr ("\t \n", *cp))
+       cp++;
+    // Save command if non-empty
+    if (*cp != '\0')
+       strcpy (m_lastCommand, cp);
+    return m_lastCommand;
+}
 
-    ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
-    ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
-    ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
+int MyClient::interactive(Yaz_SocketManager *socketManager)
+{
+    const char *cmd;
+    if (!m_interactive_flag)
+       return 0;
+    while ((cmd = getCommand()))
+    {
+       if (!processCommand(cmd))
+           break;
+    }
+    return 0;
+}
 
-    send_Z_PDU(apdu);
+int MyClient::args(Yaz_SocketManager *socketManager, int argc, char **argv)
+{
+    char *host = 0;
+    char *proxy = 0;
+    char *arg;
+    char *prog = argv[0];
+    int ret;
+
+    while ((ret = options("p:v:q", argv, argc, &arg)) != -2)
+    {
+        switch (ret)
+        {
+        case 0:
+            if (host)
+           {
+               usage(prog);
+               return 1;
+           }
+           host = arg;
+            break;
+        case 'p':
+           if (proxy)
+           {
+               usage(prog);
+               return 1;
+           }
+           set_proxy(arg);
+           break;
+       case 'v':
+           log_init_level (log_mask_str(arg));
+           break;
+       case 'q':
+           m_interactive_flag = 0;
+           break;
+        default:
+           usage(prog);
+           return 1;
+        }
+    }
+    if (host)
+    {
+       client (host);
+       send_initRequest();
+       wait ();
+    }
+    return 0;
 }
 
 int main(int argc, char **argv)
@@ -187,11 +290,10 @@ int main(int argc, char **argv)
     Yaz_SocketManager mySocketManager;
     Yaz_PDU_Assoc *some = new Yaz_PDU_Assoc(&mySocketManager, 0);
 
-    MyClient z(some);
+    MyClient z(some, &mySocketManager);
 
-    z.client(argc < 2 ? "localhost:9999" : argv[1]);
-    z.init();
-    while (mySocketManager.processEvent() > 0)
-       ;
-    return 0;
+    if (z.args(&mySocketManager, argc, argv))
+       exit (1);
+    if (z.interactive(&mySocketManager))
+       exit (1);
 }
index f941e6c..4217bcd 100644 (file)
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-ir-assoc.cpp,v $
- * Revision 1.4  1999-03-23 14:17:57  adam
- * More work on timeout handling. Work on yaz-client.
- *
- * Revision 1.3  1999/02/02 14:01:19  adam
- * First WIN32 port of YAZ++.
- *
- * Revision 1.2  1999/01/28 13:08:43  adam
- * Yaz_PDU_Assoc better encapsulated. Memory leak fix in
- * yaz-socket-manager.cc.
- *
- * Revision 1.1.1.1  1999/01/28 09:41:07  adam
- * First implementation of YAZ++.
+ * Revision 1.5  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
  *
  */
 
+#include <assert.h>
+
 #include <log.h>
 #include <yaz-ir-assoc.h>
 
-int Yaz_IR_Assoc::yaz_init_func()
+Yaz_IR_Assoc::Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
+    : Yaz_Z_Assoc(the_PDU_Observable)
 {
-    logf (LOG_LOG, "nmem_init");
-    nmem_init();
-    logf (LOG_LOG, "done");
-    return 1;
+    m_num_databaseNames = 0;
+    m_databaseNames = 0;
+    m_preferredRecordSyntax = VAL_NONE;
+    m_elementSetNames = 0;
+    m_lastReceived = 0;
+    m_host = 0;
+    m_proxy = 0;
+
+    const char *db = "Default";
+    set_databaseNames(1, &db);
 }
 
-int Yaz_IR_Assoc::yaz_init_flag = Yaz_IR_Assoc::yaz_init_func();
+Yaz_IR_Assoc::~Yaz_IR_Assoc()
+{
+    if (m_elementSetNames)
+       delete [] m_elementSetNames->u.generic;
+    delete m_elementSetNames;
+}
 
-Yaz_IR_Assoc::Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
+void Yaz_IR_Assoc::get_databaseNames (int *num, char ***list)
 {
-    m_PDU_Observable = the_PDU_Observable;
-    m_odr_in = odr_createmem (ODR_DECODE);
-    m_odr_out = odr_createmem (ODR_ENCODE);
-    m_odr_print = odr_createmem (ODR_PRINT);
+    *num = m_num_databaseNames;
+    *list = m_databaseNames;
 }
 
-Yaz_IR_Assoc::~Yaz_IR_Assoc()
+void Yaz_IR_Assoc::set_databaseNames (int num, const char **list)
 {
-    m_PDU_Observable->destroy();
-    delete m_PDU_Observable;
-    odr_destroy (m_odr_print);
-    odr_destroy (m_odr_out);
-    odr_destroy (m_odr_in);
+    int i;
+    logf (LOG_LOG, "Yaz_IR_Assoc::set_databaseNames num=%d", num);
+    for (i = 0; i<m_num_databaseNames; i++)
+       delete [] m_databaseNames[i];
+    delete [] m_databaseNames;
+    m_num_databaseNames = num;
+    m_databaseNames = new (char*) [num];
+    for (i = 0; i<m_num_databaseNames; i++)
+    {
+       m_databaseNames[i] = new char[strlen(list[i])+1];
+       strcpy(m_databaseNames[i], list[i]);
+    }
+}
+
+void Yaz_IR_Assoc::set_databaseNames(const char *dblist, const char *sep)
+{
+    const char **list = new (const char*) [strlen(dblist)];
+    char *dbtmp = new char[strlen(dblist)+1];
+    strcpy(dbtmp, dblist);
+    int num = 0;
+    int len = 0;
+    for (char *cp = dbtmp; ; cp++)
+       if (*cp && !strchr(sep, *cp))
+           len++;
+       else
+       {
+           if (len)
+           {
+               list[num] = cp - len;
+               num++;
+           }
+           if (!*cp)
+               break;
+           *cp = '\0';
+           len = 0;
+       }
+    set_databaseNames (num, list);
+    delete [] dbtmp;
+    delete [] list;
 }
 
-void Yaz_IR_Assoc::recv_PDU(const char *buf, int len)
+void Yaz_IR_Assoc::set_preferredRecordSyntax (int value)
 {
-    logf (LOG_LOG, "recv_PDU len=%d", len);
-    Z_APDU *apdu = decode_Z_PDU (buf, len);
-    if (apdu)
-         recv_Z_PDU (apdu);
+    m_preferredRecordSyntax = value;
 }
 
-Z_APDU *Yaz_IR_Assoc::create_Z_PDU(int type)
+void Yaz_IR_Assoc::set_preferredRecordSyntax (const char *syntax)
 {
-    return zget_APDU(m_odr_out, type);
+    m_preferredRecordSyntax = VAL_NONE;
+    if (syntax && *syntax)
+       m_preferredRecordSyntax = oid_getvalbyname (syntax);
 }
 
-int Yaz_IR_Assoc::send_Z_PDU(Z_APDU *apdu)
+void Yaz_IR_Assoc::get_preferredRecordSyntax (int *value)
 {
-    char *buf;
-    int len;
-    if (encode_Z_PDU(apdu, &buf, &len) > 0)
-       return m_PDU_Observable->send_PDU(buf, len);
-    return -1;
+    *value = m_preferredRecordSyntax;
 }
 
-Z_APDU *Yaz_IR_Assoc::decode_Z_PDU(const char *buf, int len)
+void Yaz_IR_Assoc::get_preferredRecordSyntax (const char **dst)
 {
-    Z_APDU *apdu;
+    struct oident ent;
+    ent.proto = PROTO_Z3950;
+    ent.oclass = CLASS_RECSYN;
+    ent.value = (enum oid_value) m_preferredRecordSyntax;
 
-    odr_reset (m_odr_in);
-    odr_setbuf (m_odr_in, (char*) buf, len, 0);
+    int oid[OID_SIZE];
+    oid_ent_to_oid (&ent, oid);
+    struct oident *entp = oid_getentbyoid (oid);
+    
+    *dst = entp ? entp->desc : "";
+}
 
-    if (!z_APDU(m_odr_in, &apdu, 0))
+void Yaz_IR_Assoc::set_elementSetName (const char *elementSetName)
+{
+    if (m_elementSetNames)
+       delete [] m_elementSetNames->u.generic;
+    delete m_elementSetNames;
+    m_elementSetNames = 0;
+    if (elementSetName && *elementSetName)
     {
-        logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ",
-             odr_errmsg(odr_geterror(m_odr_in)),
-             odr_offset(m_odr_in));
-        logf(LOG_LOG, "PDU dump:");
-        odr_dumpBER(log_file(), buf, len);
-        return 0;
+       m_elementSetNames = new Z_ElementSetNames;
+       m_elementSetNames->which = Z_ElementSetNames_generic;
+       m_elementSetNames->u.generic = new char[strlen(elementSetName)+1];
+       strcpy (m_elementSetNames->u.generic, elementSetName);
     }
-    else
+}
+
+void Yaz_IR_Assoc::get_elementSetName (Z_ElementSetNames **elementSetNames)
+{
+    *elementSetNames = m_elementSetNames;
+}
+
+void Yaz_IR_Assoc::get_elementSetName (const char **elementSetName)
+{
+    if (!m_elementSetNames ||
+       m_elementSetNames->which != Z_ElementSetNames_generic)
     {
-        logf (LOG_LOG, "decoded ok");
-        return apdu;
+       *elementSetName = 0;
+       return;
     }
+    *elementSetName = m_elementSetNames->u.generic;
 }
 
-int Yaz_IR_Assoc::encode_Z_PDU(Z_APDU *apdu, char **buf, int *len)
+void Yaz_IR_Assoc::set_otherInformationString (
+    Z_OtherInformation **otherInformation,
+    int *oid, int categoryValue,
+    const char *str)
 {
-    if (!z_APDU(m_odr_out, &apdu, 0))
-        return -1;
-    *buf = odr_getbuf (m_odr_out, len, 0);
-    odr_reset (m_odr_out);
-    return *len;
+    Z_OtherInformationUnit *oi =
+       set_otherInformation(otherInformation, oid, categoryValue);
+    if (!oi)
+       return;
+    oi->information.characterInfo = odr_strdup (odr_encode(), str);
 }
 
-void Yaz_IR_Assoc::connectNotify()
+Z_OtherInformationUnit *Yaz_IR_Assoc::set_otherInformation (
+    Z_OtherInformation **otherInformationP,
+    int *oid, int categoryValue)
 {
-    logf (LOG_LOG, "connectNotify");
+    int i;
+    Z_OtherInformation *otherInformation = *otherInformationP;
+    if (!otherInformation)
+    {
+       otherInformation = *otherInformationP = (Z_OtherInformation *)
+           odr_malloc (odr_encode(), sizeof(*otherInformation));
+       otherInformation->num_elements = 0;
+       otherInformation->list = (Z_OtherInformationUnit **)
+           odr_malloc (odr_encode(), 8*sizeof(*otherInformation));
+       for (i = 0; i<8; i++)
+           otherInformation->list[i] = 0;
+    }
+    for (i = 0; i<otherInformation->num_elements; i++)
+    {
+       assert (otherInformation->list[i]);
+       if (!oid)
+       {
+           if (!otherInformation->list[i]->category)
+               return otherInformation->list[i];
+       }
+       else
+       {
+           if (otherInformation->list[i]->category &&
+               categoryValue ==
+               *otherInformation->list[i]->category->categoryValue &&
+               !oid_oidcmp (oid, otherInformation->list[i]->category->
+                            categoryTypeId))
+               return otherInformation->list[i];
+       }
+    }
+    otherInformation->list[i] = (Z_OtherInformationUnit*)
+       odr_malloc (odr_encode(), sizeof(Z_OtherInformationUnit));
+    if (oid)
+    {
+       otherInformation->list[i]->category = (Z_InfoCategory*)
+           odr_malloc (odr_encode(), sizeof(Z_InfoCategory));
+       otherInformation->list[i]->category->categoryTypeId = (int*)
+           odr_oiddup (odr_encode(), oid);
+       otherInformation->list[i]->category->categoryValue = (int*)
+           odr_malloc (odr_encode(), sizeof(int));
+       *otherInformation->list[i]->category->categoryValue =
+           categoryValue;
+    }
+    else
+       otherInformation->list[i]->category = 0;
+    otherInformation->list[i]->which = Z_OtherInfo_characterInfo;
+    otherInformation->list[i]->information.characterInfo = 0;
+    
+    otherInformation->num_elements = i+1;
+    return otherInformation->list[i];
+}
+
+void Yaz_IR_Assoc::recv_Z_PDU(Z_APDU *apdu)
+{
+    logf (LOG_LOG, "recv_Z_PDU");
+    m_lastReceived = apdu->which;
+    switch (apdu->which)
+    {
+    case Z_APDU_initResponse:
+       logf (LOG_LOG, "recv InitResponse");
+       recv_initResponse(apdu->u.initResponse);
+       break;
+    case Z_APDU_initRequest:
+        logf (LOG_LOG, "recv InitRequest");
+       recv_initRequest(apdu->u.initRequest);
+        break;
+    case Z_APDU_searchRequest:
+        logf (LOG_LOG, "recv searchRequest");
+       recv_searchRequest(apdu->u.searchRequest);
+        break;
+    case Z_APDU_searchResponse:
+       logf (LOG_LOG, "recv searchResponse"); 
+       recv_searchResponse(apdu->u.searchResponse);
+       break;
+    case Z_APDU_presentRequest:
+        logf (LOG_LOG, "recv presentRequest");
+       recv_presentRequest(apdu->u.presentRequest);
+        break;
+    case Z_APDU_presentResponse:
+        logf (LOG_LOG, "recv presentResponse");
+       recv_presentResponse(apdu->u.presentResponse);
+        break;
+    }
+}
+
+int Yaz_IR_Assoc::send_searchRequest(Yaz_Z_Query *query)
+{
+    Z_APDU *apdu = create_Z_PDU(Z_APDU_searchRequest);
+    Z_SearchRequest *req = apdu->u.searchRequest;
+    int recordSyntax;
+
+    req->query = query->get_Z_Query();
+    if (!req->query)
+       return -1;
+    get_databaseNames (&req->num_databaseNames, &req->databaseNames);
+    for (int i = 0; i<req->num_databaseNames; i++)
+       logf (LOG_LOG, "Database %s", req->databaseNames[i]);
+    int oid_syntax[OID_SIZE];
+    oident prefsyn;
+    get_preferredRecordSyntax(&recordSyntax);
+    if (recordSyntax != VAL_NONE)
+    {
+       prefsyn.proto = PROTO_Z3950;
+       prefsyn.oclass = CLASS_RECSYN;
+       prefsyn.value = (enum oid_value) recordSyntax;
+       oid_ent_to_oid(&prefsyn, oid_syntax);
+       req->preferredRecordSyntax = oid_syntax;
+    }
+    logf (LOG_LOG, "send_searchRequest");
+    return send_Z_PDU(apdu);
 }
 
-void Yaz_IR_Assoc::failNotify()
+int Yaz_IR_Assoc::send_presentRequest(int start, int number)
 {
-    logf (LOG_LOG, "failNotify");
+    Z_APDU *apdu = create_Z_PDU(Z_APDU_presentRequest);
+    Z_PresentRequest *req = apdu->u.presentRequest;
+
+    req->resultSetStartPoint = &start;
+    req->numberOfRecordsRequested = &number;
+
+    int oid_syntax[OID_SIZE];
+    oident prefsyn;
+    int recordSyntax;
+    get_preferredRecordSyntax (&recordSyntax);
+    if (recordSyntax != VAL_NONE)
+    {
+       prefsyn.proto = PROTO_Z3950;
+       prefsyn.oclass = CLASS_RECSYN;
+       prefsyn.value = (enum oid_value) recordSyntax;
+       oid_ent_to_oid(&prefsyn, oid_syntax);
+       req->preferredRecordSyntax = oid_syntax;
+    }
+    Z_RecordComposition compo;
+    Z_ElementSetNames *elementSetNames;
+    get_elementSetName (&elementSetNames);
+    if (elementSetNames)
+    {
+       req->recordComposition = &compo;
+        compo.which = Z_RecordComp_simple;
+        compo.u.simple = elementSetNames;
+    }
+    return send_Z_PDU(apdu);
 }
 
-void Yaz_IR_Assoc::timeoutNotify()
+void Yaz_IR_Assoc::set_proxy(const char *str)
 {
-    logf (LOG_LOG, "timeoutNotify");
+    delete m_proxy;
+    m_proxy = new char[strlen(str)+1];
+    strcpy (m_proxy, str);
 }
 
 void Yaz_IR_Assoc::client(const char *addr)
 {
-    m_PDU_Observable->connect (this, addr);
+    delete [] m_host;
+    m_host = new char[strlen(addr)+1];
+    strcpy(m_host, addr);
+    const char *zurl_p = (m_proxy ? m_proxy : m_host);
+    char *zurl = new char[strlen(zurl_p)+1];
+    strcpy(zurl, zurl_p);
+    char *dbpart = strchr(zurl, '/');
+    if (dbpart)
+    {
+       set_databaseNames (dbpart+1, "+ ");
+       *dbpart = '\0';
+    }
+    Yaz_Z_Assoc::client(zurl);
+    delete [] zurl;
+}
+
+const char *Yaz_IR_Assoc::get_proxy()
+{
+    return m_proxy;
+}
+
+const char *Yaz_IR_Assoc::get_host()
+{
+    return m_host;
+}
+
+void Yaz_IR_Assoc::recv_searchRequest(Z_SearchRequest *searchRequest)
+{
+    Z_APDU *apdu = create_Z_PDU(Z_APDU_searchResponse);
+    send_Z_PDU(apdu);
+}
+
+void Yaz_IR_Assoc::recv_presentRequest(Z_PresentRequest *presentRequest)
+{
+    Z_APDU *apdu = create_Z_PDU(Z_APDU_presentResponse);
+    send_Z_PDU(apdu);
 }
 
-void Yaz_IR_Assoc::server(const char *addr)
+void Yaz_IR_Assoc::recv_initRequest(Z_InitRequest *initRequest)
 {
-    m_PDU_Observable->listen (this, addr);
+    Z_APDU *apdu = create_Z_PDU(Z_APDU_initResponse);
+    send_Z_PDU(apdu);
 }
 
-ODR Yaz_IR_Assoc::odr_encode()
+void Yaz_IR_Assoc::recv_searchResponse (Z_SearchResponse *searchResponse)
 {
-    return m_odr_out;
 }
+
+void Yaz_IR_Assoc::recv_presentResponse (Z_PresentResponse *presentResponse)
+{
+}
+
+void Yaz_IR_Assoc::recv_initResponse(Z_InitResponse *initResponse)
+{
+}
+
+int Yaz_IR_Assoc::get_lastReceived()
+{
+    return m_lastReceived;
+}
+
+void Yaz_IR_Assoc::set_lastReceived(int lastReceived)
+{
+    m_lastReceived = lastReceived;
+}
+
+int Yaz_IR_Assoc::send_initRequest()
+{
+
+    Z_APDU *apdu = create_Z_PDU(Z_APDU_initRequest);
+    Z_InitRequest *req = apdu->u.initRequest;
+    
+    ODR_MASK_SET(req->options, Z_Options_search);
+    ODR_MASK_SET(req->options, Z_Options_present);
+    ODR_MASK_SET(req->options, Z_Options_namedResultSets);
+    ODR_MASK_SET(req->options, Z_Options_triggerResourceCtrl);
+    ODR_MASK_SET(req->options, Z_Options_scan);
+    ODR_MASK_SET(req->options, Z_Options_sort);
+    ODR_MASK_SET(req->options, Z_Options_extendedServices);
+    ODR_MASK_SET(req->options, Z_Options_delSet);
+
+    ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_1);
+    ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_2);
+    ODR_MASK_SET(req->protocolVersion, Z_ProtocolVersion_3);
+
+    if (m_proxy && m_host)
+    {
+       int oid[OID_SIZE];
+       struct oident ent;
+       ent.proto = PROTO_Z3950;
+       ent.oclass = CLASS_USERINFO;
+       ent.value = VAL_PROXY;
+       oid_ent_to_oid (&ent, oid);
+       logf (LOG_LOG, "proxy host %s", m_host);
+       set_otherInformationString(&req->otherInfo, oid, 1, m_host);
+    }
+    return send_Z_PDU(apdu);
+}
+
index e0c0c9d..e20837b 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-pdu-assoc.cpp,v $
- * Revision 1.4  1999-03-23 14:17:57  adam
+ * Revision 1.5  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.4  1999/03/23 14:17:57  adam
  * More work on timeout handling. Work on yaz-client.
  *
  * Revision 1.3  1999/02/02 14:01:20  adam
@@ -55,7 +58,7 @@ Yaz_PDU_Assoc::~Yaz_PDU_Assoc()
 
 void Yaz_PDU_Assoc::socketNotify(int event)
 {
-    logf (LOG_LOG, "socketNotify p=%p event = %d", this, event);
+    logf (LOG_LOG, "Yaz_PDU_Assoc::socketNotify p=%p event = %d", this, event);
     if (m_state == Connected)
     {
        m_state = Ready;
@@ -215,9 +218,12 @@ Yaz_PDU_Assoc::PDU_Queue::~PDU_Queue()
 int Yaz_PDU_Assoc::flush_PDU()
 {
     int r;
-
+    
+    logf (LOG_LOG, "Yaz_PDU_Assoc::flush_PDU");
     if (m_state != Ready)
+    {
        return 1;
+    }
     PDU_Queue *q = m_queue_out;
     if (!q)
     {
@@ -237,13 +243,12 @@ int Yaz_PDU_Assoc::flush_PDU()
        m_socketObservable->maskObserver(this, YAZ_SOCKET_OBSERVE_READ|
                                         YAZ_SOCKET_OBSERVE_EXCEPT|
                                         YAZ_SOCKET_OBSERVE_WRITE);
-        logf (LOG_LOG, "put %d bytes (incomplete write)", q->m_len);
+        logf (LOG_LOG, "flush_PDU put %d bytes (incomplete write)", q->m_len);
         return r;
     }
-    logf (LOG_LOG, "put %d bytes fd=%d", q->m_len, cs_fileno(m_cs));
+    logf (LOG_LOG, "flush_PDU put %d bytes fd=%d", q->m_len, cs_fileno(m_cs));
     // whole packet sent... delete this and proceed to next ...
     m_queue_out = q->m_next;
-    logf (LOG_LOG, "m_queue_out = %p", m_queue_out);
     delete q;
     // don't select on write if queue is empty ...
     if (!m_queue_out)
@@ -254,7 +259,7 @@ int Yaz_PDU_Assoc::flush_PDU()
 
 int Yaz_PDU_Assoc::send_PDU(const char *buf, int len)
 {
-    logf (LOG_LOG, "send_PDU");
+    logf (LOG_LOG, "Yaz_PDU_Assoc::send_PDU");
     PDU_Queue **pq = &m_queue_out;
     int is_idle = (*pq ? 0 : 1);
     
@@ -267,13 +272,9 @@ int Yaz_PDU_Assoc::send_PDU(const char *buf, int len)
         pq = &(*pq)->m_next;
     *pq = new PDU_Queue(buf, len);
     if (is_idle)
-    {
         return flush_PDU ();
-    }
     else
-    {
        logf (LOG_LOG, "cannot send_PDU fd=%d", cs_fileno(m_cs));
-    }
     return 0;
 }
 
@@ -342,8 +343,14 @@ void Yaz_PDU_Assoc::connect(IYaz_PDU_Observer *observer,
                                         YAZ_SOCKET_OBSERVE_EXCEPT|
                                         YAZ_SOCKET_OBSERVE_WRITE);
        if (res == 1)
+       {
+           logf (LOG_LOG, "Connect pending");
            m_state = Connecting;
+       }
        else
+       {
+           logf (LOG_LOG, "Connect complete");
            m_state = Connected;
+       }
     }
 }
index 320a92a..b7292fd 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-proxy-main.cpp,v $
- * Revision 1.3  1999-02-02 14:01:21  adam
+ * Revision 1.4  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.3  1999/02/02 14:01:21  adam
  * First WIN32 port of YAZ++.
  *
  * Revision 1.2  1999/01/28 13:08:45  adam
@@ -26,8 +29,8 @@ int main(int argc, char **argv)
 {
     Yaz_SocketManager mySocketManager;
     Yaz_Proxy proxy(new Yaz_PDU_Assoc(&mySocketManager, 0));
-    
-    proxy.server("@:9999");
+
+    proxy.server(argc < 2 ? "@:9999" : argv[1]);
     while (mySocketManager.processEvent() > 0)
        ;
     return 0;
index a37500a..59ccc36 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-proxy.cpp,v $
- * Revision 1.2  1999-01-28 13:08:46  adam
+ * Revision 1.3  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.2  1999/01/28 13:08:46  adam
  * Yaz_PDU_Assoc better encapsulated. Memory leak fix in
  * yaz-socket-manager.cc.
  *
@@ -20,7 +23,7 @@
 #include <yaz-proxy.h>
 
 Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable) :
-    Yaz_IR_Assoc(the_PDU_Observable)
+    Yaz_Z_Assoc(the_PDU_Observable)
 {
     m_PDU_Observable = the_PDU_Observable;
     m_maps = 0;
@@ -73,7 +76,7 @@ IYaz_PDU_Observer *Yaz_ProxyClient::clone(IYaz_PDU_Observable
 }
 
 Yaz_ProxyClient::Yaz_ProxyClient(IYaz_PDU_Observable *the_PDU_Observable) :
-    Yaz_IR_Assoc (the_PDU_Observable)
+    Yaz_Z_Assoc (the_PDU_Observable)
 {
     
 }
index 932910c..2d2c244 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-server.cpp,v $
- * Revision 1.4  1999-03-23 14:17:57  adam
+ * Revision 1.5  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.4  1999/03/23 14:17:57  adam
  * More work on timeout handling. Work on yaz-client.
  *
  * Revision 1.3  1999/02/02 14:01:22  adam
  */
 
 #include <log.h>
-#include <yaz-ir-assoc.h>
+#include <yaz-z-assoc.h>
 #include <yaz-pdu-assoc.h>
 #include <yaz-socket-manager.h>
 
-class MyServer : public Yaz_IR_Assoc {
+class MyServer : public Yaz_Z_Assoc {
 public:
     MyServer(IYaz_PDU_Observable *the_PDU_Observable);
     void recv_Z_PDU(Z_APDU *apdu);
@@ -69,7 +72,7 @@ IYaz_PDU_Observer *MyServer::clone(IYaz_PDU_Observable *the_PDU_Observable)
 }
 
 MyServer::MyServer(IYaz_PDU_Observable *the_PDU_Observable) :
-    Yaz_IR_Assoc (the_PDU_Observable)
+    Yaz_Z_Assoc (the_PDU_Observable)
 {
     m_no = 0;
 }
index eeb06e2..43d90ca 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-socket-manager.cpp,v $
- * Revision 1.4  1999-03-23 14:17:57  adam
+ * Revision 1.5  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.4  1999/03/23 14:17:57  adam
  * More work on timeout handling. Work on yaz-client.
  *
  * Revision 1.3  1999/02/02 14:01:23  adam
@@ -110,6 +113,7 @@ int Yaz_SocketManager::processEvent()
     YazSocketEntry *p;
     YazSocketEvent *event = getEvent();
     unsigned timeout = 0;
+    logf (LOG_LOG, "processEvent");
     if (event)
     {
        event->observer->socketNotify(event->event);
@@ -153,7 +157,12 @@ int Yaz_SocketManager::processEvent()
        }
     }
     if (!no)
+    {
+       logf (LOG_LOG, "no pending events return 0");
+       if (!m_observers)
+           logf (LOG_LOG, "no observers");
        return 0;
+    }
 
     struct timeval to;
     to.tv_sec = timeout;
diff --git a/src/yaz-z-assoc.cpp b/src/yaz-z-assoc.cpp
new file mode 100644 (file)
index 0000000..360bcf6
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1998-1999, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ * 
+ * $Log: yaz-z-assoc.cpp,v $
+ * Revision 1.1  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ */
+
+#include <log.h>
+#include <yaz-z-assoc.h>
+
+int Yaz_Z_Assoc::yaz_init_func()
+{
+    logf (LOG_LOG, "nmem_init");
+    nmem_init();
+    logf (LOG_LOG, "done");
+    return 1;
+}
+
+int Yaz_Z_Assoc::yaz_init_flag = Yaz_Z_Assoc::yaz_init_func();
+
+Yaz_Z_Assoc::Yaz_Z_Assoc(IYaz_PDU_Observable *the_PDU_Observable)
+{
+    m_PDU_Observable = the_PDU_Observable;
+    m_odr_in = odr_createmem (ODR_DECODE);
+    m_odr_out = odr_createmem (ODR_ENCODE);
+    m_odr_print = odr_createmem (ODR_PRINT);
+}
+
+Yaz_Z_Assoc::~Yaz_Z_Assoc()
+{
+    m_PDU_Observable->destroy();
+    delete m_PDU_Observable;
+    odr_destroy (m_odr_print);
+    odr_destroy (m_odr_out);
+    odr_destroy (m_odr_in);
+}
+
+void Yaz_Z_Assoc::recv_PDU(const char *buf, int len)
+{
+    logf (LOG_LOG, "recv_PDU len=%d", len);
+    Z_APDU *apdu = decode_Z_PDU (buf, len);
+    if (apdu)
+       recv_Z_PDU (apdu);
+}
+
+Z_APDU *Yaz_Z_Assoc::create_Z_PDU(int type)
+{
+    return zget_APDU(m_odr_out, type);
+}
+
+int Yaz_Z_Assoc::send_Z_PDU(Z_APDU *apdu)
+{
+    char *buf;
+    int len;
+    logf (LOG_LOG, "Yaz_Z_Assoc:send_Z_PDU");
+    if (encode_Z_PDU(apdu, &buf, &len) > 0)
+       return m_PDU_Observable->send_PDU(buf, len);
+    return -1;
+}
+
+Z_APDU *Yaz_Z_Assoc::decode_Z_PDU(const char *buf, int len)
+{
+    Z_APDU *apdu;
+
+    odr_reset (m_odr_in);
+    odr_setbuf (m_odr_in, (char*) buf, len, 0);
+
+    if (!z_APDU(m_odr_in, &apdu, 0))
+    {
+        logf(LOG_LOG, "ODR error on incoming PDU: %s [near byte %d] ",
+             odr_errmsg(odr_geterror(m_odr_in)),
+             odr_offset(m_odr_in));
+        logf(LOG_LOG, "PDU dump:");
+        odr_dumpBER(log_file(), buf, len);
+        return 0;
+    }
+    else
+    {
+        logf (LOG_LOG, "decoded ok");
+        return apdu;
+    }
+}
+
+int Yaz_Z_Assoc::encode_Z_PDU(Z_APDU *apdu, char **buf, int *len)
+{
+    if (!z_APDU(m_odr_out, &apdu, 0))
+    {
+       logf (LOG_LOG, "yaz_Z_Assoc::encode_Z_PDU failed");
+        return -1;
+    }
+    *buf = odr_getbuf (m_odr_out, len, 0);
+    odr_reset (m_odr_out);
+    return *len;
+}
+
+void Yaz_Z_Assoc::connectNotify()
+{
+    logf (LOG_LOG, "connectNotify");
+}
+
+void Yaz_Z_Assoc::failNotify()
+{
+    logf (LOG_LOG, "failNotify");
+}
+
+void Yaz_Z_Assoc::timeoutNotify()
+{
+    logf (LOG_LOG, "timeoutNotify");
+}
+
+void Yaz_Z_Assoc::client(const char *addr)
+{
+    m_PDU_Observable->connect (this, addr);
+}
+
+void Yaz_Z_Assoc::close()
+{
+    m_PDU_Observable->close ();
+}
+
+void Yaz_Z_Assoc::server(const char *addr)
+{
+    m_PDU_Observable->listen (this, addr);
+}
+
+ODR Yaz_Z_Assoc::odr_encode()
+{
+    return m_odr_out;
+}
index e7d9b48..3fbd3e6 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  * 
  * $Log: yaz-z-query.cpp,v $
- * Revision 1.1  1999-03-23 14:17:57  adam
+ * Revision 1.2  1999-04-09 11:46:57  adam
+ * Added object Yaz_Z_Assoc. Much more functional client.
+ *
+ * Revision 1.1  1999/03/23 14:17:57  adam
  * More work on timeout handling. Work on yaz-client.
  *
  */
@@ -18,7 +21,7 @@ Yaz_Z_Query::Yaz_Z_Query()
     odr_decode = odr_createmem (ODR_DECODE);
 }
 
-void Yaz_Z_Query::set_rpn (const char *rpn)
+int Yaz_Z_Query::set_rpn (const char *rpn)
 {
     buf = 0;
     odr_reset (odr_encode);
@@ -26,10 +29,11 @@ void Yaz_Z_Query::set_rpn (const char *rpn)
     query->which = Z_Query_type_1;
     query->u.type_1 = p_query_rpn (odr_encode, PROTO_Z3950, rpn);
     if (!query->u.type_1)
-       return;
+       return -1;
     if (!z_Query (odr_encode, &query, 0))
-       return;
+       return -1;
     buf = odr_getbuf (odr_encode, &len, 0);
+    return len;
 }
 
 void Yaz_Z_Query::set_Z_Query(Z_Query *z_query)