New define: IR_TCL_VERSION.
[ir-tcl-moved-to-github.git] / ir-tcl.c
index bb22467..f49c97b 100644 (file)
--- a/ir-tcl.c
+++ b/ir-tcl.c
@@ -5,7 +5,42 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: ir-tcl.c,v $
- * Revision 1.34  1995-05-29 10:33:42  adam
+ * Revision 1.43  1995-06-19 13:06:08  adam
+ * New define: IR_TCL_VERSION.
+ *
+ * Revision 1.42  1995/06/19  08:08:52  adam
+ * client.tcl: hotTargets now contain both database and target name.
+ * ir-tcl.c: setting protocol edited. Errors in callbacks are logged
+ * by logf(LOG_WARN, ...) calls.
+ *
+ * Revision 1.41  1995/06/16  12:28:16  adam
+ * Implemented preferredRecordSyntax.
+ * Minor changes in diagnostic handling.
+ * Record list deleted when connection closes.
+ *
+ * Revision 1.40  1995/06/14  13:37:18  adam
+ * Setting recordType implemented.
+ * Setting implementationVersion implemented.
+ * Settings implementationId / implementationName edited.
+ *
+ * Revision 1.39  1995/06/08  10:26:32  adam
+ * Bug fix in ir_strdup.
+ *
+ * Revision 1.38  1995/06/01  16:36:47  adam
+ * About buttons. Minor bug fixes.
+ *
+ * Revision 1.37  1995/06/01  07:31:20  adam
+ * Rename of many typedefs -> IrTcl_...
+ *
+ * Revision 1.36  1995/05/31  13:09:59  adam
+ * Client searches/presents may be interrupted.
+ * New moving book-logo.
+ *
+ * Revision 1.35  1995/05/31  08:36:33  adam
+ * Bug fix in client.tcl: didn't save options on clientrc.tcl.
+ * New method: referenceId. More work on scan.
+ *
+ * Revision 1.34  1995/05/29  10:33:42  adam
  * README and rename of startup script.
  *
  * Revision 1.33  1995/05/29  09:15:11  quinn
  *
  * Revision 1.8  1995/03/15  08:25:16  adam
  * New method presentStatus to check for error on present. Misc. cleanup
- * of IRRecordList manipulations. Full MARC record presentation in
+ * of IrTcl_RecordList manipulations. Full MARC record presentation in
  * search.tcl.
  *
  * Revision 1.7  1995/03/14  17:32:29  adam
@@ -124,18 +159,23 @@ typedef struct {
     int type;
     char *name;
     int (*method) (void *obj, Tcl_Interp *interp, int argc, char **argv);
-} IRMethod;
+} IrTcl_Method;
 
 typedef struct {
     void *obj;
-    IRMethod *tab;
-} IRMethods;
+    IrTcl_Method *tab;
+} IrTcl_Methods;
 
-static int do_disconnect (void *obj,Tcl_Interp *interp, int argc, char **argv);
+static Tcl_Interp *irTcl_interp;
 
-static IRRecordList *new_IR_record (IRSetObj *setobj, int no, int which)
+static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num);
+static int do_disconnect (void *obj, Tcl_Interp *interp, 
+                          int argc, char **argv);
+
+static IrTcl_RecordList *new_IR_record (IrTcl_SetObj *setobj, 
+                                        int no, int which)
 {
-    IRRecordList *rl;
+    IrTcl_RecordList *rl;
 
     for (rl = setobj->record_list; rl; rl = rl->next)
     {
@@ -148,8 +188,8 @@ static IRRecordList *new_IR_record (IRSetObj *setobj, int no, int which)
                rl->u.dbrec.buf = NULL;
                 break;
             case Z_NamePlusRecord_surrogateDiagnostic:
-                free (rl->u.diag.addinfo);
-                rl->u.diag.addinfo = NULL;
+                ir_deleteDiags (&rl->u.surrogateDiagnostics.list,
+                                &rl->u.surrogateDiagnostics.num);
                 break;
             }
             break;
@@ -167,9 +207,77 @@ static IRRecordList *new_IR_record (IRSetObj *setobj, int no, int which)
     return rl;
 }
 
-static IRRecordList *find_IR_record (IRSetObj *setobj, int no)
+static struct {
+    enum oid_value value;
+    const char *name;
+} IrTcl_recordSyntaxTab[] = { 
+{ VAL_UNIMARC,    "UNIMARC" },
+{ VAL_INTERMARC,  "INTERMARC" },
+{ VAL_CCF,        "CCF" },
+{ VAL_USMARC,     "USMARC" },
+{ VAL_UKMARC,     "UKMARC" },
+{ VAL_NORMARC,    "NORMARC" },
+{ VAL_LIBRISMARC, "LIBRISMARC" },
+{ VAL_DANMARC,    "DANMARC" },
+{ VAL_FINMARC,    "FINMARC" },
+{ VAL_MAB,        "MAB" },
+{ VAL_CANMARC,    "CANMARC" },
+{ VAL_SBN,        "SBN" },
+{ VAL_PICAMARC,   "PICAMARC" },
+{ VAL_AUSMARC,    "AUSMARC" },
+{ VAL_IBERMARC,   "IBERMARC" },
+{ VAL_SUTRS,      "SUTRS" },
+{ 0, NULL }
+};
+
+/* 
+ * IrTcl_eval
+ */
+int IrTcl_eval (Tcl_Interp *interp, const char *command)
 {
-    IRRecordList *rl;
+    char *tmp = malloc (strlen(command)+1);
+    int r;
+
+    if (!tmp)
+    {
+        logf (LOG_FATAL, "Out of memory in IrTcl_eval");
+        exit (1);
+    }
+    strcpy (tmp, command);
+    r = Tcl_Eval (interp, tmp);
+    if (r == TCL_ERROR)
+        logf (LOG_WARN, "Tcl error in line %d: %s", interp->errorLine, interp->result);
+    free (tmp);
+    return r;
+}
+
+/*
+ * IrTcl_getRecordSyntaxStr: Return record syntax name of object id
+ */
+static const char *IrTcl_getRecordSyntaxStr (enum oid_value value)
+{
+    int i;
+    for (i = 0; IrTcl_recordSyntaxTab[i].name; i++) 
+        if (IrTcl_recordSyntaxTab[i].value == value)
+            return IrTcl_recordSyntaxTab[i].name;
+    return "USMARC";
+}
+
+/*
+ * IrTcl_getRecordSyntaxVal: Return record syntax value of string
+ */
+static enum oid_value IrTcl_getRecordSyntaxVal (const char *name)
+{
+    int i;
+    for (i = 0; IrTcl_recordSyntaxTab[i].name; i++) 
+        if (!strcmp (IrTcl_recordSyntaxTab[i].name, name))
+            return IrTcl_recordSyntaxTab[i].value;
+    return 0;
+}
+
+static IrTcl_RecordList *find_IR_record (IrTcl_SetObj *setobj, int no)
+{
+    IrTcl_RecordList *rl;
 
     for (rl = setobj->record_list; rl; rl = rl->next)
         if (no == rl->no)
@@ -177,9 +285,9 @@ static IRRecordList *find_IR_record (IRSetObj *setobj, int no)
     return NULL;
 }
 
-static void delete_IR_records (IRSetObj *setobj)
+static void delete_IR_records (IrTcl_SetObj *setobj)
 {
-    IRRecordList *rl, *rl1;
+    IrTcl_RecordList *rl, *rl1;
 
     for (rl = setobj->record_list; rl; rl = rl1)
     {
@@ -189,7 +297,8 @@ static void delete_IR_records (IRSetObj *setobj)
            free (rl->u.dbrec.buf);
             break;
         case Z_NamePlusRecord_surrogateDiagnostic:
-            free (rl->u.diag.addinfo);
+            ir_deleteDiags (&rl->u.surrogateDiagnostics.list,
+                            &rl->u.surrogateDiagnostics.num);
             break;
        }
        rl1 = rl->next;
@@ -199,7 +308,7 @@ static void delete_IR_records (IRSetObj *setobj)
 }
 
 /*
- * getsetint: Set/get integer value
+ * get_set_int: Set/get integer value
  */
 static int get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv)
 {
@@ -216,68 +325,12 @@ static int get_set_int (int *val, Tcl_Interp *interp, int argc, char **argv)
 }
 
 /*
- * mk_nonSurrogateDiagnostics: Make Tcl result with diagnostic info
- */
-static int mk_nonSurrogateDiagnostics (Tcl_Interp *interp, 
-                                       int condition,
-                                      const char *addinfo)
-{
-    char buf[20];
-    const char *cp;
-
-    Tcl_AppendElement (interp, "NSD");
-    sprintf (buf, "%d", condition);
-    Tcl_AppendElement (interp, buf);
-    cp = diagbib1_str (condition);
-    if (cp)
-        Tcl_AppendElement (interp, (char*) cp);
-    else
-        Tcl_AppendElement (interp, "");
-    if (addinfo)
-        Tcl_AppendElement (interp, (char*) addinfo);
-    else
-        Tcl_AppendElement (interp, "");
-    return TCL_OK;
-}
-
-/*
- * get_parent_info: Returns information about parent object.
- */
-static int get_parent_info (Tcl_Interp *interp, const char *name,
-                           Tcl_CmdInfo *parent_info,
-                           const char **suffix)
-{
-    char parent_name[128];
-    const char *csep = strrchr (name, '.');
-    int pos;
-
-    if (!csep)
-    {
-        interp->result = "missing .";
-        return TCL_ERROR;
-    }
-    if (suffix)
-        *suffix = csep+1;
-    pos = csep-name;
-    if (pos > 127)
-        pos = 127;
-    memcpy (parent_name, name, pos);
-    parent_name[pos] = '\0';
-    if (!Tcl_GetCommandInfo (interp, parent_name, parent_info))
-    {
-        interp->result = "No parent";
-        return TCL_ERROR;
-    }
-    return TCL_OK;
-}
-
-/*
  * ir_method: Search for method in table and invoke method handler
  */
-int ir_method (Tcl_Interp *interp, int argc, char **argv, IRMethods *tab)
+int ir_method (Tcl_Interp *interp, int argc, char **argv, IrTcl_Methods *tab)
 {
-    IRMethods *tab_i = tab;
-    IRMethod *t;
+    IrTcl_Methods *tab_i = tab;
+    IrTcl_Method *t;
 
     for (tab_i = tab; tab_i->tab; tab_i++)
         for (t = tab_i->tab; t->name; t++)
@@ -303,7 +356,7 @@ int ir_method (Tcl_Interp *interp, int argc, char **argv, IRMethods *tab)
  * ir_method_r: Get status for all readable elements
  */
 int ir_method_r (void *obj, Tcl_Interp *interp, int argc, char **argv,
-                 IRMethod *tab)
+                 IrTcl_Method *tab)
 {
     char *argv_n[3];
     int argc_n;
@@ -359,6 +412,11 @@ int ir_named_bits (struct ir_named_entry *tab, Odr_bitmask *ob,
  */
 int ir_strdup (Tcl_Interp *interp, char** p, const char *s)
 {
+    if (!s)
+    {
+        *p = NULL;
+        return TCL_OK;
+    }
     *p = malloc (strlen(s)+1);
     if (!*p)
     {
@@ -396,17 +454,43 @@ void *ir_malloc (Tcl_Interp *interp, size_t size)
     return p;
 }
 
+static void set_referenceId (ODR o, Z_ReferenceId **dst, const char *src)
+{
+    if (!src || !*src)
+        *dst = NULL;
+    else
+    {
+        *dst = odr_malloc (o, sizeof(**dst));
+       (*dst)->size = (*dst)->len = strlen(src);
+       (*dst)->buf = odr_malloc (o, (*dst)->len);
+       memcpy ((*dst)->buf, src, (*dst)->len);
+    }
+}
+
+static void get_referenceId (char **dst, Z_ReferenceId *src)
+{
+    free (*dst);
+    if (!src)
+    {
+        *dst = NULL;
+       return;
+    }
+    *dst = malloc (src->len+1);
+    memcpy (*dst, src->buf, src->len);
+    (*dst)[src->len] = '\0';
+}
+
 /* ------------------------------------------------------- */
 
 /*
  * do_init_request: init method on IR object
  */
 static int do_init_request (void *obj, Tcl_Interp *interp,
-                      int argc, char **argv)
+                            int argc, char **argv)
 {
-    Z_APDU apdu, *apdup = &apdu;
-    IRObj *p = obj;
-    Z_InitRequest req;
+    Z_APDU *apdu;
+    IrTcl_Obj *p = obj;
+    Z_InitRequest *req;
     int r;
 
     if (argc <= 0)
@@ -417,12 +501,14 @@ static int do_init_request (void *obj, Tcl_Interp *interp,
         return TCL_ERROR;
     }
     odr_reset (p->odr_out);
+    apdu = zget_APDU (p->odr_out, Z_APDU_initRequest);
+    req = apdu->u.initRequest;
 
-    req.referenceId = 0;
-    req.options = &p->options;
-    req.protocolVersion = &p->protocolVersion;
-    req.preferredMessageSize = &p->preferredMessageSize;
-    req.maximumRecordSize = &p->maximumRecordSize;
+    set_referenceId (p->odr_out, &req->referenceId, p->set_inher.referenceId);
+    req->options = &p->options;
+    req->protocolVersion = &p->protocolVersion;
+    req->preferredMessageSize = &p->preferredMessageSize;
+    req->maximumRecordSize = &p->maximumRecordSize;
 
     if (p->idAuthenticationGroupId)
     {
@@ -443,27 +529,24 @@ static int do_init_request (void *obj, Tcl_Interp *interp,
             pass->password = p->idAuthenticationPassword;
         else
             pass->password = NULL;
-        req.idAuthentication = auth;
+        req->idAuthentication = auth;
     }
     else if (!p->idAuthenticationOpen || !*p->idAuthenticationOpen)
-        req.idAuthentication = NULL;
+        req->idAuthentication = NULL;
     else
     {
         Z_IdAuthentication *auth = odr_malloc (p->odr_out, sizeof(*auth));
 
         auth->which = Z_IdAuthentication_open;
         auth->u.open = p->idAuthenticationOpen;
-        req.idAuthentication = auth;
+        req->idAuthentication = auth;
     }
-    req.implementationId = p->implementationId;
-    req.implementationName = p->implementationName;
-    req.implementationVersion = "0.1";
-    req.userInformationField = 0;
+    req->implementationId = p->implementationId;
+    req->implementationName = p->implementationName;
+    req->implementationVersion = p->implementationVersion;
+    req->userInformationField = 0;
 
-    apdu.u.initRequest = &req;
-    apdu.which = Z_APDU_initRequest;
-
-    if (!z_APDU (p->odr_out, &apdup, 0))
+    if (!z_APDU (p->odr_out, &apdu, 0))
     {
         Tcl_AppendResult (interp, odr_errlist [odr_geterror (p->odr_out)],
                           NULL);
@@ -493,14 +576,9 @@ static int do_init_request (void *obj, Tcl_Interp *interp,
 static int do_protocolVersion (void *obj, Tcl_Interp *interp,
                                int argc, char **argv)
 {
-    static struct ir_named_entry version_tab[] = {
-    { "1", 0 },
-    { "2", 1 },
-    { "3", 2 },
-    { "4", 3 },
-    { NULL,0}
-    };
-    IRObj *p = obj;
+    int version, i;
+    char buf[10];
+    IrTcl_Obj *p = obj;
 
     if (argc <= 0)
     {
@@ -509,8 +587,20 @@ static int do_protocolVersion (void *obj, Tcl_Interp *interp,
        ODR_MASK_SET (&p->protocolVersion, 1);
         return TCL_OK;
     }
-    return ir_named_bits (version_tab, &p->protocolVersion,
-                          interp, argc-2, argv+2);
+    if (argc == 3)
+    {
+        if (Tcl_GetInt (interp, argv[2], &version)==TCL_ERROR)
+            return TCL_ERROR;
+        ODR_MASK_ZERO (&p->protocolVersion);
+        for (i = 0; i<version; i++)
+            ODR_MASK_SET (&p->protocolVersion, i);
+    }
+    for (i = 4; --i >= 0; )
+        if (ODR_MASK_GET (&p->protocolVersion, i))
+            break;
+    sprintf (buf, "%d", i+1);
+    interp->result = buf;
+    return TCL_OK;
 }
 
 /*
@@ -529,14 +619,14 @@ static int do_options (void *obj, Tcl_Interp *interp,
     { "accessCtrl", 6},
     { "scan", 7},
     { "sort", 8},
-    { "extentedServices", 10},
+    { "extendedServices", 10},
     { "level-1Segmentation", 11},
     { "level-2Segmentation", 12},
     { "concurrentOperations", 13},
     { "namedResultSets", 14},
     { NULL, 0}
     };
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc <= 0)
     {
@@ -556,11 +646,11 @@ static int do_options (void *obj, Tcl_Interp *interp,
 static int do_preferredMessageSize (void *obj, Tcl_Interp *interp,
                                     int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc <= 0)
     {
-        p->preferredMessageSize = 4096;
+        p->preferredMessageSize = 30000;
        return TCL_OK;
     }
     return get_set_int (&p->preferredMessageSize, interp, argc, argv);
@@ -570,13 +660,13 @@ static int do_preferredMessageSize (void *obj, Tcl_Interp *interp,
  * do_maximumRecordSize: Set/get maximum record size
  */
 static int do_maximumRecordSize (void *obj, Tcl_Interp *interp,
-                                    int argc, char **argv)
+                                 int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc <= 0)
     {
-        p->maximumRecordSize = 32768;
+        p->maximumRecordSize = 30000;
        return TCL_OK;
     }
     return get_set_int (&p->maximumRecordSize, interp, argc, argv);
@@ -588,7 +678,7 @@ static int do_maximumRecordSize (void *obj, Tcl_Interp *interp,
 static int do_initResult (void *obj, Tcl_Interp *interp,
                           int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
    
     if (argc <= 0)
         return TCL_OK;
@@ -602,10 +692,11 @@ static int do_initResult (void *obj, Tcl_Interp *interp,
 static int do_implementationName (void *obj, Tcl_Interp *interp,
                                     int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
-        return ir_strdup (interp, &p->implementationName, "TCL/TK on YAZ");
+        return ir_strdup (interp, &p->implementationName,
+                          "Index Data/IrTcl on YAZ");
     else if (argc == -1)
         return ir_strdel (interp, &p->implementationName);
     if (argc == 3)
@@ -615,40 +706,50 @@ static int do_implementationName (void *obj, Tcl_Interp *interp,
             == TCL_ERROR)
             return TCL_ERROR;
     }
-    Tcl_AppendResult (interp, p->implementationName,
-                      (char*) NULL);
+    Tcl_AppendResult (interp, p->implementationName, (char*) NULL);
     return TCL_OK;
 }
 
 /*
- * do_implementationId: Set/get Implementation Id.
+ * do_implementationId: Get Implementation Id.
  */
 static int do_implementationId (void *obj, Tcl_Interp *interp,
                                 int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
-        return ir_strdup (interp, &p->implementationId, "81");
+        return ir_strdup (interp, &p->implementationId, "YAZ (id=81)");
     else if (argc == -1)
         return ir_strdel (interp, &p->implementationId);
-    if (argc == 3)
-    {
-        free (p->implementationId);
-        if (ir_strdup (interp, &p->implementationId, argv[2]) == TCL_ERROR)
-            return TCL_ERROR;
-    }
     Tcl_AppendResult (interp, p->implementationId, (char*) NULL);
     return TCL_OK;
 }
 
 /*
+ * do_implementationVersion: get Implementation Version.
+ */
+static int do_implementationVersion (void *obj, Tcl_Interp *interp,
+                                     int argc, char **argv)
+{
+    IrTcl_Obj *p = obj;
+
+    if (argc == 0)
+        return ir_strdup (interp, &p->implementationVersion, 
+                          "YAZ: " YAZ_VERSION " / IrTcl: " IR_TCL_VERSION);
+    else if (argc == -1)
+        return ir_strdel (interp, &p->implementationVersion);
+    Tcl_AppendResult (interp, p->implementationVersion, (char*) NULL);
+    return TCL_OK;
+}
+
+/*
  * do_targetImplementationName: Get Implementation Name of target.
  */
 static int do_targetImplementationName (void *obj, Tcl_Interp *interp,
-                                    int argc, char **argv)
+                                        int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
     {
@@ -657,8 +758,7 @@ static int do_targetImplementationName (void *obj, Tcl_Interp *interp,
     }
     else if (argc == -1)
         return ir_strdel (interp, &p->targetImplementationName);
-    Tcl_AppendResult (interp, p->targetImplementationName,
-                      (char*) NULL);
+    Tcl_AppendResult (interp, p->targetImplementationName, (char*) NULL);
     return TCL_OK;
 }
 
@@ -668,7 +768,7 @@ static int do_targetImplementationName (void *obj, Tcl_Interp *interp,
 static int do_targetImplementationId (void *obj, Tcl_Interp *interp,
                                       int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
     {
@@ -687,7 +787,7 @@ static int do_targetImplementationId (void *obj, Tcl_Interp *interp,
 static int do_targetImplementationVersion (void *obj, Tcl_Interp *interp,
                                            int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
     {
@@ -706,7 +806,7 @@ static int do_targetImplementationVersion (void *obj, Tcl_Interp *interp,
 static int do_idAuthentication (void *obj, Tcl_Interp *interp,
                                 int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc >= 3 || argc == -1)
     {
@@ -763,9 +863,8 @@ static int do_connect (void *obj, Tcl_Interp *interp,
                       int argc, char **argv)
 {
     void *addr;
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
     int r;
-    int protocol_type = PROTO_Z3950;
 
     if (argc <= 0)
         return TCL_OK;
@@ -776,18 +875,9 @@ static int do_connect (void *obj, Tcl_Interp *interp,
             interp->result = "already connected";
             return TCL_ERROR;
         }
-        if (!strcmp (p->protocol_type, "Z3950"))
-            protocol_type = PROTO_Z3950;
-        else if (!strcmp (p->protocol_type, "SR"))
-            protocol_type = PROTO_SR;
-        else
-        {
-            interp->result = "bad protocol type";
-            return TCL_ERROR;
-        }
         if (!strcmp (p->cs_type, "tcpip"))
         {
-            p->cs_link = cs_create (tcpip_type, CS_BLOCK, protocol_type);
+            p->cs_link = cs_create (tcpip_type, CS_BLOCK, p->protocol_type);
             addr = tcpip_strtoaddr (argv[2]);
             if (!addr)
             {
@@ -796,10 +886,10 @@ static int do_connect (void *obj, Tcl_Interp *interp,
             }
             logf (LOG_DEBUG, "tcp/ip connect %s", argv[2]);
         }
-#if MOSI
         else if (!strcmp (p->cs_type, "mosi"))
         {
-            p->cs_link = cs_create (mosi_type, CS_BLOCK, protocol_type);
+#if MOSI
+            p->cs_link = cs_create (mosi_type, CS_BLOCK, p->protocol_type);
             addr = mosi_strtoaddr (argv[2]);
             if (!addr)
             {
@@ -807,18 +897,22 @@ static int do_connect (void *obj, Tcl_Interp *interp,
                 return TCL_ERROR;
             }
             logf (LOG_DEBUG, "mosi connect %s", argv[2]);
-        }
+#else
+            interp->result = "MOSI support not there";
+            return TCL_ERROR;
 #endif
+        }
         else 
         {
-            interp->result = "unknown comstack type";
+            Tcl_AppendResult (interp, "Bad comstack type: ", 
+                              p->cs_type, NULL);
             return TCL_ERROR;
         }
         if (ir_strdup (interp, &p->hostname, argv[2]) == TCL_ERROR)
             return TCL_ERROR;
         if ((r=cs_connect (p->cs_link, addr)) < 0)
         {
-            interp->result = "cs_connect fail";
+            interp->result = "connect fail";
             do_disconnect (p, NULL, 2, NULL);
             return TCL_ERROR;
         }
@@ -832,7 +926,7 @@ static int do_connect (void *obj, Tcl_Interp *interp,
         {
             p->connectFlag = 0;
             if (p->callback)
-                Tcl_Eval (p->interp, p->callback);
+                IrTcl_eval (p->interp, p->callback);
         }
     }
     if (p->hostname)
@@ -846,7 +940,7 @@ static int do_connect (void *obj, Tcl_Interp *interp,
 static int do_disconnect (void *obj, Tcl_Interp *interp,
                           int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
     {
@@ -865,6 +959,16 @@ static int do_disconnect (void *obj, Tcl_Interp *interp,
         assert (p->cs_link);
         cs_close (p->cs_link);
         p->cs_link = NULL;
+
+        ODR_MASK_ZERO (&p->options);
+       ODR_MASK_SET (&p->options, 0);
+       ODR_MASK_SET (&p->options, 1);
+       ODR_MASK_SET (&p->options, 7);
+       ODR_MASK_SET (&p->options, 14);
+
+        ODR_MASK_ZERO (&p->protocolVersion);
+       ODR_MASK_SET (&p->protocolVersion, 0);
+       ODR_MASK_SET (&p->protocolVersion, 1);
     }
     assert (!p->cs_link);
     return TCL_OK;
@@ -876,7 +980,7 @@ static int do_disconnect (void *obj, Tcl_Interp *interp,
 static int do_comstack (void *o, Tcl_Interp *interp,
                        int argc, char **argv)
 {
-    IRObj *obj = o;
+    IrTcl_Obj *obj = o;
 
     if (argc == 0)
         return ir_strdup (interp, &obj->cs_type, "tcpip");
@@ -892,27 +996,6 @@ static int do_comstack (void *o, Tcl_Interp *interp,
     return TCL_OK;
 }
 
-/*
- * do_protocol: Set/get protocol method on IR object
- */
-static int do_protocol (void *o, Tcl_Interp *interp,
-                       int argc, char **argv)
-{
-    IRObj *obj = o;
-
-    if (argc == 0)
-        return ir_strdup (interp, &obj->protocol_type, "Z3950");
-    else if (argc == -1)
-        return ir_strdel (interp, &obj->protocol_type);
-    else if (argc == 3)
-    {
-        free (obj->protocol_type);
-        if (ir_strdup (interp, &obj->protocol_type, argv[2]) == TCL_ERROR)
-            return TCL_ERROR;
-    }
-    Tcl_AppendElement (interp, obj->protocol_type);
-    return TCL_OK;
-}
 
 /*
  * do_callback: add callback
@@ -920,7 +1003,7 @@ static int do_protocol (void *o, Tcl_Interp *interp,
 static int do_callback (void *obj, Tcl_Interp *interp,
                           int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
     {
@@ -939,7 +1022,7 @@ static int do_callback (void *obj, Tcl_Interp *interp,
        }
        else
            p->callback = NULL;
-        p->interp = interp;
+        p->interp = irTcl_interp;
     }
     return TCL_OK;
 }
@@ -950,7 +1033,7 @@ static int do_callback (void *obj, Tcl_Interp *interp,
 static int do_failback (void *obj, Tcl_Interp *interp,
                           int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     if (argc == 0)
     {
@@ -969,7 +1052,44 @@ static int do_failback (void *obj, Tcl_Interp *interp,
        }
        else
            p->failback = NULL;
-        p->interp = interp;
+        p->interp = irTcl_interp;
+    }
+    return TCL_OK;
+}
+
+/*
+ * do_protocol: Set/get protocol method on IR object
+ */
+static int do_protocol (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+    IrTcl_Obj *p = o;
+
+    if (argc <= 0)
+    {
+        p->protocol_type = PROTO_Z3950;
+        return TCL_OK;
+    }
+    else if (argc == 3)
+    {
+        if (!strcmp (argv[2], "Z39"))
+            p->protocol_type = PROTO_Z3950;
+        else if (!strcmp (argv[2], "SR"))
+            p->protocol_type = PROTO_SR;
+        else
+        {
+            Tcl_AppendResult (interp, "Bad protocol: ", argv[2], NULL);
+            return TCL_ERROR;
+        }
+        return TCL_OK;
+    }
+    switch (p->protocol_type)
+    {
+    case PROTO_Z3950:
+        Tcl_AppendElement (interp, "Z39");
+        break;
+    case PROTO_SR:
+        Tcl_AppendElement (interp, "SR");
+        break;
     }
     return TCL_OK;
 }
@@ -978,10 +1098,10 @@ static int do_failback (void *obj, Tcl_Interp *interp,
  * do_databaseNames: specify database names
  */
 static int do_databaseNames (void *obj, Tcl_Interp *interp,
-                          int argc, char **argv)
+                             int argc, char **argv)
 {
     int i;
-    IRSetCObj *p = obj;
+    IrTcl_SetCObj *p = obj;
 
     if (argc == -1)
     {
@@ -1026,7 +1146,7 @@ static int do_databaseNames (void *obj, Tcl_Interp *interp,
 static int do_replaceIndicator (void *obj, Tcl_Interp *interp,
                                 int argc, char **argv)
 {
-    IRSetCObj *p = obj;
+    IrTcl_SetCObj *p = obj;
 
     if (argc <= 0)
     {
@@ -1042,7 +1162,7 @@ static int do_replaceIndicator (void *obj, Tcl_Interp *interp,
 static int do_queryType (void *obj, Tcl_Interp *interp,
                       int argc, char **argv)
 {
-    IRSetCObj *p = obj;
+    IrTcl_SetCObj *p = obj;
 
     if (argc == 0)
         return ir_strdup (interp, &p->queryType, "rpn");
@@ -1064,7 +1184,7 @@ static int do_queryType (void *obj, Tcl_Interp *interp,
 static int do_userInformationField (void *obj, Tcl_Interp *interp,
                                     int argc, char **argv)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
     
     if (argc == 0)
     {
@@ -1083,7 +1203,7 @@ static int do_userInformationField (void *obj, Tcl_Interp *interp,
 static int do_smallSetUpperBound (void *o, Tcl_Interp *interp,
                       int argc, char **argv)
 {
-    IRSetCObj *p = o;
+    IrTcl_SetCObj *p = o;
 
     if (argc <= 0)
     {
@@ -1099,7 +1219,7 @@ static int do_smallSetUpperBound (void *o, Tcl_Interp *interp,
 static int do_largeSetLowerBound (void *o, Tcl_Interp *interp,
                                   int argc, char **argv)
 {
-    IRSetCObj *p = o;
+    IrTcl_SetCObj *p = o;
 
     if (argc <= 0)
     {
@@ -1115,7 +1235,7 @@ static int do_largeSetLowerBound (void *o, Tcl_Interp *interp,
 static int do_mediumSetPresentNumber (void *o, Tcl_Interp *interp,
                                       int argc, char **argv)
 {
-    IRSetCObj *p = o;
+    IrTcl_SetCObj *p = o;
    
     if (argc <= 0)
     {
@@ -1125,8 +1245,62 @@ static int do_mediumSetPresentNumber (void *o, Tcl_Interp *interp,
     return get_set_int (&p->mediumSetPresentNumber, interp, argc, argv);
 }
 
+/*
+ * do_referenceId: Set/Get referenceId
+ */
+static int do_referenceId (void *obj, Tcl_Interp *interp,
+                          int argc, char **argv)
+{
+    IrTcl_SetCObj *p = obj;
 
-static IRMethod ir_method_tab[] = {
+    if (argc == 0)
+    {
+        p->referenceId = NULL;
+        return TCL_OK;
+    }
+    else if (argc == -1)
+        return ir_strdel (interp, &p->referenceId);
+    if (argc == 3)
+    {
+        free (p->referenceId);
+        if (ir_strdup (interp, &p->referenceId, argv[2]) == TCL_ERROR)
+            return TCL_ERROR;
+    }
+    Tcl_AppendResult (interp, p->referenceId, NULL);
+    return TCL_OK;
+}
+
+/*
+ * do_preferredRecordSyntax: Set/get preferred record syntax
+ */
+static int do_preferredRecordSyntax (void *obj, Tcl_Interp *interp,
+                                     int argc, char **argv)
+{
+    IrTcl_SetCObj *p = obj;
+
+    if (argc == 0)
+    {
+        p->preferredRecordSyntax = NULL;
+        return TCL_OK;
+    }
+    else if (argc == -1)
+    {
+        free (p->preferredRecordSyntax);
+        p->preferredRecordSyntax = NULL;
+        return TCL_OK;
+    }
+    if (argc == 3)
+    {
+        free (p->preferredRecordSyntax);
+        p->preferredRecordSyntax = NULL;
+        if (argv[2][0] && (p->preferredRecordSyntax = 
+                           malloc (sizeof(*p->preferredRecordSyntax))))
+            *p->preferredRecordSyntax = IrTcl_getRecordSyntaxVal (argv[2]);
+    }
+    return TCL_OK;
+            
+}
+static IrTcl_Method ir_method_tab[] = {
 { 1, "comstack",                    do_comstack },
 { 1, "protocol",                    do_protocol },
 { 0, "failback",                    do_failback },
@@ -1137,6 +1311,7 @@ static IRMethod ir_method_tab[] = {
 { 1, "maximumRecordSize",           do_maximumRecordSize },
 { 1, "implementationName",          do_implementationName },
 { 1, "implementationId",            do_implementationId },
+{ 1, "implementationVersion",       do_implementationVersion },
 { 0, "targetImplementationName",    do_targetImplementationName },
 { 0, "targetImplementationId",      do_targetImplementationId },
 { 0, "targetImplementationVersion", do_targetImplementationVersion },
@@ -1150,13 +1325,15 @@ static IRMethod ir_method_tab[] = {
 { 0, NULL, NULL}
 };
 
-static IRMethod ir_set_c_method_tab[] = {
+static IrTcl_Method ir_set_c_method_tab[] = {
 { 0, "databaseNames",               do_databaseNames},
 { 0, "replaceIndicator",            do_replaceIndicator},
 { 0, "queryType",                   do_queryType },
+{ 0, "preferredRecordSyntax",       do_preferredRecordSyntax },
 { 0, "smallSetUpperBound",          do_smallSetUpperBound},
 { 0, "largeSetLowerBound",          do_largeSetLowerBound},
 { 0, "mediumSetPresentNumber",      do_mediumSetPresentNumber},
+{ 0, "referenceId",                 do_referenceId },
 { 0, NULL, NULL}
 };
 
@@ -1164,10 +1341,10 @@ static IRMethod ir_set_c_method_tab[] = {
  * ir_obj_method: IR Object methods
  */
 static int ir_obj_method (ClientData clientData, Tcl_Interp *interp,
-int argc, char **argv)
+                          int argc, char **argv)
 {
-    IRMethods tab[3];
-    IRObj *p = clientData;
+    IrTcl_Methods tab[3];
+    IrTcl_Obj *p = clientData;
 
     if (argc < 2)
         return ir_method_r (clientData, interp, argc, argv, ir_method_tab);
@@ -1186,8 +1363,8 @@ int argc, char **argv)
  */
 static void ir_obj_delete (ClientData clientData)
 {
-    IRObj *obj = clientData;
-    IRMethods tab[3];
+    IrTcl_Obj *obj = clientData;
+    IrTcl_Methods tab[3];
 
     --(obj->ref_count);
     if (obj->ref_count > 0)
@@ -1213,10 +1390,10 @@ static void ir_obj_delete (ClientData clientData)
  * ir_obj_mk: IR Object creation
  */
 static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp,
-              int argc, char **argv)
+                      int argc, char **argv)
 {
-    IRMethods tab[3];
-    IRObj *obj;
+    IrTcl_Methods tab[3];
+    IrTcl_Obj *obj;
 #if CCL2RPN
     FILE *inf;
 #endif
@@ -1268,15 +1445,14 @@ static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp,
 /*
  * do_search: Do search request
  */
-static int do_search (void *o, Tcl_Interp *interp,
-                      int argc, char **argv)
+static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv)
 {
-    Z_SearchRequest req;
+    Z_SearchRequest *req;
     Z_Query query;
-    Z_APDU apdu, *apdup = &apdu;
+    Z_APDU *apdu;
     Odr_oct ccl_query;
-    IRSetObj *obj = o;
-    IRObj *p = obj->parent;
+    IrTcl_SetObj *obj = o;
+    IrTcl_Obj *p = obj->parent;
     int r;
     oident bib1;
 
@@ -1289,7 +1465,7 @@ static int do_search (void *o, Tcl_Interp *interp,
         interp->result = "wrong # args";
         return TCL_ERROR;
     }
-    if (!p->set_inher.num_databaseNames)
+    if (!obj->set_inher.num_databaseNames)
     {
         interp->result = "no databaseNames";
         return TCL_ERROR;
@@ -1300,30 +1476,43 @@ static int do_search (void *o, Tcl_Interp *interp,
         return TCL_ERROR;
     }
     odr_reset (p->odr_out);
-    apdu.which = Z_APDU_searchRequest;
-    apdu.u.searchRequest = &req;
-    
-    bib1.proto = PROTO_Z3950;
+    apdu = zget_APDU (p->odr_out, Z_APDU_searchRequest);
+    req = apdu->u.searchRequest;
+
+    bib1.proto = p->protocol_type;
     bib1.class = CLASS_ATTSET;
     bib1.value = VAL_BIB1;
 
-    req.referenceId = 0;
-    req.smallSetUpperBound = &p->set_inher.smallSetUpperBound;
-    req.largeSetLowerBound = &p->set_inher.largeSetLowerBound;
-    req.mediumSetPresentNumber = &p->set_inher.mediumSetPresentNumber;
-    req.replaceIndicator = &p->set_inher.replaceIndicator;
-    req.resultSetName = obj->setName ? obj->setName : "Default";
-    logf (LOG_DEBUG, "Search, resultSetName %s", req.resultSetName);
-    req.num_databaseNames = p->set_inher.num_databaseNames;
-    req.databaseNames = p->set_inher.databaseNames;
-    for (r=0; r < p->set_inher.num_databaseNames; r++)
-        logf (LOG_DEBUG, " Database %s", p->set_inher.databaseNames[r]);
-    req.smallSetElementSetNames = 0;
-    req.mediumSetElementSetNames = 0;
-    req.preferredRecordSyntax = 0;
-    req.query = &query;
-
-    if (!strcmp (p->set_inher.queryType, "rpn"))
+    set_referenceId (p->odr_out, &req->referenceId,
+                     obj->set_inher.referenceId);
+
+    req->smallSetUpperBound = &obj->set_inher.smallSetUpperBound;
+    req->largeSetLowerBound = &obj->set_inher.largeSetLowerBound;
+    req->mediumSetPresentNumber = &obj->set_inher.mediumSetPresentNumber;
+    req->replaceIndicator = &obj->set_inher.replaceIndicator;
+    req->resultSetName = obj->setName ? obj->setName : "Default";
+    logf (LOG_DEBUG, "Search, resultSetName %s", req->resultSetName);
+    req->num_databaseNames = obj->set_inher.num_databaseNames;
+    req->databaseNames = obj->set_inher.databaseNames;
+    for (r=0; r < obj->set_inher.num_databaseNames; r++)
+        logf (LOG_DEBUG, " Database %s", obj->set_inher.databaseNames[r]);
+    req->smallSetElementSetNames = 0;
+    req->mediumSetElementSetNames = 0;
+    if (obj->set_inher.preferredRecordSyntax)
+    {
+        struct oident ident;
+
+        ident.proto = p->protocol_type;
+        ident.class = CLASS_RECSYN;
+        ident.value = *obj->set_inher.preferredRecordSyntax;
+        req->preferredRecordSyntax = odr_oiddup (p->odr_out, 
+                                                 oid_getoidbyent (&ident));
+    }
+    else
+        req->preferredRecordSyntax = 0;
+    req->query = &query;
+
+    if (!strcmp (obj->set_inher.queryType, "rpn"))
     {
         Z_RPNQuery *RPNquery;
 
@@ -1339,7 +1528,7 @@ static int do_search (void *o, Tcl_Interp *interp,
         logf (LOG_DEBUG, "RPN");
     }
 #if CCL2RPN
-    else if (!strcmp (p->set_inher.queryType, "cclrpn"))
+    else if (!strcmp (obj->set_inher.queryType, "cclrpn"))
     {
         int error;
         int pos;
@@ -1349,7 +1538,8 @@ static int do_search (void *o, Tcl_Interp *interp,
         rpn = ccl_find_str(p->bibset, argv[2], &error, &pos);
         if (error)
         {
-            Tcl_AppendResult (interp, "CCL error: ", ccl_err_msg(error),NULL);
+            Tcl_AppendResult (interp, "CCL error: ", 
+                             ccl_err_msg(error), NULL);
             return TCL_ERROR;
         }
         ccl_pr_tree (rpn, stderr);
@@ -1361,7 +1551,7 @@ static int do_search (void *o, Tcl_Interp *interp,
         logf (LOG_DEBUG, "CCLRPN");
     }
 #endif
-    else if (!strcmp (p->set_inher.queryType, "ccl"))
+    else if (!strcmp (obj->set_inher.queryType, "ccl"))
     {
         query.which = Z_Query_type_2;
         query.u.type_2 = &ccl_query;
@@ -1374,7 +1564,7 @@ static int do_search (void *o, Tcl_Interp *interp,
         interp->result = "unknown query method";
         return TCL_ERROR;
     }
-    if (!z_APDU (p->odr_out, &apdup, 0))
+    if (!z_APDU (p->odr_out, &apdu, 0))
     {
         interp->result = odr_errlist [odr_geterror (p->odr_out)];
         odr_reset (p->odr_out);
@@ -1404,7 +1594,7 @@ static int do_search (void *o, Tcl_Interp *interp,
 static int do_resultCount (void *o, Tcl_Interp *interp,
                       int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
 
     if (argc <= 0)
         return TCL_OK;
@@ -1417,7 +1607,7 @@ static int do_resultCount (void *o, Tcl_Interp *interp,
 static int do_searchStatus (void *o, Tcl_Interp *interp,
                            int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
 
     if (argc <= 0)
         return TCL_OK;
@@ -1430,7 +1620,7 @@ static int do_searchStatus (void *o, Tcl_Interp *interp,
 static int do_presentStatus (void *o, Tcl_Interp *interp,
                            int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
 
     if (argc <= 0)
         return TCL_OK;
@@ -1444,7 +1634,7 @@ static int do_presentStatus (void *o, Tcl_Interp *interp,
 static int do_nextResultSetPosition (void *o, Tcl_Interp *interp,
                                      int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
 
     if (argc <= 0)
         return TCL_OK;
@@ -1457,7 +1647,7 @@ static int do_nextResultSetPosition (void *o, Tcl_Interp *interp,
 static int do_setName (void *o, Tcl_Interp *interp,
                       int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
 
     if (argc == 0)
         return ir_strdup (interp, &obj->setName, "Default");
@@ -1478,23 +1668,26 @@ static int do_setName (void *o, Tcl_Interp *interp,
  * do_numberOfRecordsReturned: Get number of records returned
  */
 static int do_numberOfRecordsReturned (void *o, Tcl_Interp *interp,
-                      int argc, char **argv)
+                                       int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
 
-    if (argc < 0)
+    if (argc <= 0)
+    {
+        obj->numberOfRecordsReturned = 0;
         return TCL_OK;
+    }
     return get_set_int (&obj->numberOfRecordsReturned, interp, argc, argv);
 }
 
 /*
- * do_recordType: Return record type (if any) at position.
+ * do_type: Return type (if any) at position.
  */
-static int do_recordType (void *o, Tcl_Interp *interp, int argc, char **argv)
+static int do_type (void *o, Tcl_Interp *interp, int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
     int offset;
-    IRRecordList *rl;
+    IrTcl_RecordList *rl;
 
     if (argc == 0)
     {
@@ -1519,24 +1712,88 @@ static int do_recordType (void *o, Tcl_Interp *interp, int argc, char **argv)
     switch (rl->which)
     {
     case Z_NamePlusRecord_databaseRecord:
-        interp->result = "databaseRecord";
+        interp->result = "DB";
         break;
     case Z_NamePlusRecord_surrogateDiagnostic:
-        interp->result = "surrogateDiagnostic";
+        interp->result = "SD";
         break;
     }
     return TCL_OK;
 }
 
+
 /*
- * do_recordDiag: Return diagnostic record info
+ * do_recordType: Return record type (if any) at position.
  */
-static int do_recordDiag (void *o, Tcl_Interp *interp, int argc, char **argv)
+static int do_recordType (void *o, Tcl_Interp *interp, int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
     int offset;
-    IRRecordList *rl;
+    IrTcl_RecordList *rl;
+
+    if (argc == 0)
+    {
+       return TCL_OK;
+    }
+    else if (argc == -1)
+    {
+       return TCL_OK;
+    }
+    if (argc < 3)
+    {
+        sprintf (interp->result, "wrong # args");
+        return TCL_ERROR;
+    }
+    if (Tcl_GetInt (interp, argv[2], &offset)==TCL_ERROR)
+        return TCL_ERROR;
+    rl = find_IR_record (obj, offset);
+    if (!rl)
+        return TCL_OK;
+    if (rl->which != Z_NamePlusRecord_databaseRecord)
+    {
+        Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL);
+        return TCL_ERROR;
+    }
+    Tcl_AppendElement (interp, (char*)
+                       IrTcl_getRecordSyntaxStr (rl->u.dbrec.type));
+    return TCL_OK;
+}
+
+/*
+ * ir_diagResult 
+ */
+static int ir_diagResult (Tcl_Interp *interp, IrTcl_Diagnostic *list, int num)
+{
     char buf[20];
+    int i;
+    const char *cp;
+
+    for (i = 0; i<num; i++)
+    {
+        logf (LOG_DEBUG, "Diagnostic, code %d", list[i].condition);
+        sprintf (buf, "%d", list[i].condition);
+        Tcl_AppendElement (interp, buf);
+        cp = diagbib1_str (list[i].condition);
+        if (cp)
+            Tcl_AppendElement (interp, (char*) cp);
+        else
+            Tcl_AppendElement (interp, "");
+        if (list[i].addinfo)
+            Tcl_AppendElement (interp, (char*) list[i].addinfo);
+        else
+            Tcl_AppendElement (interp, "");
+    }
+    return TCL_OK;
+}
+
+/*
+ * do_diag: Return diagnostic record info
+ */
+static int do_diag (void *o, Tcl_Interp *interp, int argc, char **argv)
+{
+    IrTcl_SetObj *obj = o;
+    int offset;
+    IrTcl_RecordList *rl;
 
     if (argc <= 0)
         return TCL_OK;
@@ -1558,11 +1815,8 @@ static int do_recordDiag (void *o, Tcl_Interp *interp, int argc, char **argv)
         Tcl_AppendResult (interp, "No Diagnostic record at #", argv[2], NULL);
         return TCL_ERROR;
     }
-    sprintf (buf, "%d", rl->u.diag.condition);
-    Tcl_AppendResult (interp, buf, " {", 
-                      (rl->u.diag.addinfo ? rl->u.diag.addinfo : ""),
-                      "}", NULL);
-    return TCL_OK;
+    return ir_diagResult (interp, rl->u.surrogateDiagnostics.list,
+                          rl->u.surrogateDiagnostics.num);
 }
 
 /*
@@ -1570,9 +1824,9 @@ static int do_recordDiag (void *o, Tcl_Interp *interp, int argc, char **argv)
  */
 static int do_getMarc (void *o, Tcl_Interp *interp, int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
     int offset;
-    IRRecordList *rl;
+    IrTcl_RecordList *rl;
 
     if (argc <= 0)
         return TCL_OK;
@@ -1591,7 +1845,7 @@ static int do_getMarc (void *o, Tcl_Interp *interp, int argc, char **argv)
     }
     if (rl->which != Z_NamePlusRecord_databaseRecord)
     {
-        Tcl_AppendResult (interp, "No MARC record at #", argv[2], NULL);
+        Tcl_AppendResult (interp, "No DB record at #", argv[2], NULL);
         return TCL_ERROR;
     }
     return ir_tcl_get_marc (interp, rl->u.dbrec.buf, argc, argv);
@@ -1604,16 +1858,21 @@ static int do_getMarc (void *o, Tcl_Interp *interp, int argc, char **argv)
 static int do_responseStatus (void *o, Tcl_Interp *interp, 
                              int argc, char **argv)
 {
-    IRSetObj *obj = o;
+    IrTcl_SetObj *obj = o;
 
     if (argc == 0)
     {
         obj->recordFlag = 0;
-       obj->addinfo = NULL;
+        obj->nonSurrogateDiagnosticNum = 0;
+        obj->nonSurrogateDiagnosticList = NULL;
        return TCL_OK;
     }
     else if (argc == -1)
-        return ir_strdel (interp, &obj->addinfo);
+    {
+        ir_deleteDiags (&obj->nonSurrogateDiagnosticList,
+                        &obj->nonSurrogateDiagnosticNum);
+        return TCL_OK;
+    }
     if (!obj->recordFlag)
     {
         Tcl_AppendElement (interp, "OK");
@@ -1625,8 +1884,9 @@ static int do_responseStatus (void *o, Tcl_Interp *interp,
        Tcl_AppendElement (interp, "DBOSD");
         break;
     case Z_Records_NSD:
-        return mk_nonSurrogateDiagnostics (interp, obj->condition, 
-                                          obj->addinfo);
+        Tcl_AppendElement (interp, "NSD");
+        return ir_diagResult (interp, obj->nonSurrogateDiagnosticList,
+                              obj->nonSurrogateDiagnosticNum);
     }
     return TCL_OK;
 }
@@ -1638,10 +1898,10 @@ static int do_responseStatus (void *o, Tcl_Interp *interp,
 static int do_present (void *o, Tcl_Interp *interp,
                        int argc, char **argv)
 {
-    IRSetObj *obj = o;
-    IRObj *p = obj->parent;
-    Z_APDU apdu, *apdup = &apdu;
-    Z_PresentRequest req;
+    IrTcl_SetObj *obj = o;
+    IrTcl_Obj *p = obj->parent;
+    Z_APDU *apdu;
+    Z_PresentRequest *req;
     int start;
     int number;
     int r;
@@ -1671,19 +1931,19 @@ static int do_present (void *o, Tcl_Interp *interp,
     obj->start = start;
     obj->number = number;
 
-    apdu.which = Z_APDU_presentRequest;
-    apdu.u.presentRequest = &req;
-    req.referenceId = 0;
-    /* sprintf(setstring, "%d", setnumber); */
+    apdu = zget_APDU (p->odr_out, Z_APDU_presentRequest);
+    req = apdu->u.presentRequest;
+
+    set_referenceId (p->odr_out, &req->referenceId,
+                     obj->set_inher.referenceId);
 
-    req.resultSetId = obj->setName ? obj->setName : "Default";
+    req->resultSetId = obj->setName ? obj->setName : "Default";
     
-    req.resultSetStartPoint = &start;
-    req.numberOfRecordsRequested = &number;
-    req.elementSetNames = 0;
-    req.preferredRecordSyntax = 0;
+    req->resultSetStartPoint = &start;
+    req->numberOfRecordsRequested = &number;
+    req->preferredRecordSyntax = 0;
 
-    if (!z_APDU (p->odr_out, &apdup, 0))
+    if (!z_APDU (p->odr_out, &apdu, 0))
     {
         interp->result = odr_errlist [odr_geterror (p->odr_out)];
         odr_reset (p->odr_out);
@@ -1716,7 +1976,7 @@ static int do_present (void *o, Tcl_Interp *interp,
 static int do_loadFile (void *o, Tcl_Interp *interp,
                         int argc, char **argv)
 {
-    IRSetObj *setobj = o;
+    IrTcl_SetObj *setobj = o;
     FILE *inf;
     size_t size;
     int  no = 1;
@@ -1737,7 +1997,7 @@ static int do_loadFile (void *o, Tcl_Interp *interp,
     }
     while ((buf = ir_tcl_fread_marc (inf, &size)))
     {
-        IRRecordList *rl;
+        IrTcl_RecordList *rl;
 
         rl = new_IR_record (setobj, no, Z_NamePlusRecord_databaseRecord);
         rl->u.dbrec.buf = buf;
@@ -1749,7 +2009,7 @@ static int do_loadFile (void *o, Tcl_Interp *interp,
     return TCL_OK;
 }
 
-static IRMethod ir_set_method_tab[] = {
+static IrTcl_Method ir_set_method_tab[] = {
     { 0, "search",                  do_search },
     { 0, "searchStatus",            do_searchStatus },
     { 0, "presentStatus",           do_presentStatus },
@@ -1758,9 +2018,10 @@ static IRMethod ir_set_method_tab[] = {
     { 0, "resultCount",             do_resultCount },
     { 0, "numberOfRecordsReturned", do_numberOfRecordsReturned },
     { 0, "present",                 do_present },
-    { 0, "recordType",              do_recordType },
+    { 0, "type",                    do_type },
     { 0, "getMarc",                 do_getMarc },
-    { 0, "Diag",                    do_recordDiag },
+    { 0, "recordType",              do_recordType },
+    { 0, "diag",                    do_diag },
     { 0, "responseStatus",          do_responseStatus },
     { 0, "loadFile",                do_loadFile },
     { 0, NULL, NULL}
@@ -1772,8 +2033,8 @@ static IRMethod ir_set_method_tab[] = {
 static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp,
                           int argc, char **argv)
 {
-    IRMethods tabs[3];
-    IRSetObj *p = clientData;
+    IrTcl_Methods tabs[3];
+    IrTcl_SetObj *p = clientData;
 
     if (argc < 2)
     {
@@ -1794,8 +2055,8 @@ static int ir_set_obj_method (ClientData clientData, Tcl_Interp *interp,
  */
 static void ir_set_obj_delete (ClientData clientData)
 {
-    IRMethods tabs[3];
-    IRSetObj *p = clientData;
+    IrTcl_Methods tabs[3];
+    IrTcl_SetObj *p = clientData;
 
     tabs[0].tab = ir_set_method_tab;
     tabs[0].obj = p;
@@ -1814,8 +2075,8 @@ static void ir_set_obj_delete (ClientData clientData)
 static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp,
                           int argc, char **argv)
 {
-    IRMethods tabs[3];
-    IRSetObj *obj;
+    IrTcl_Methods tabs[3];
+    IrTcl_SetObj *obj;
 
     if (argc < 2 || argc > 3)
     {
@@ -1828,15 +2089,15 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp,
     {
         Tcl_CmdInfo parent_info;
         int i;
-        IRSetCObj *dst;
-        IRSetCObj *src;
+        IrTcl_SetCObj *dst;
+        IrTcl_SetCObj *src;
 
         if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info))
         {
             interp->result = "No parent";
             return TCL_ERROR;
         }
-        obj->parent = (IRObj *) parent_info.clientData;
+        obj->parent = (IrTcl_Obj *) parent_info.clientData;
 
         dst = &obj->set_inher;
         src = &obj->parent->set_inher;
@@ -1855,7 +2116,18 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp,
         if (ir_strdup (interp, &dst->queryType, src->queryType)
             == TCL_ERROR)
             return TCL_ERROR;
-        
+
+        if (ir_strdup (interp, &dst->referenceId, src->referenceId)
+            == TCL_ERROR)
+            return TCL_ERROR;
+
+        if (src->preferredRecordSyntax && 
+            (dst->preferredRecordSyntax 
+             = malloc (sizeof(*dst->preferredRecordSyntax))))
+            *dst->preferredRecordSyntax = *src->preferredRecordSyntax;
+        else
+            dst->preferredRecordSyntax = NULL;
+        dst->replaceIndicator = src->replaceIndicator;
         dst->smallSetUpperBound = src->smallSetUpperBound;
         dst->largeSetLowerBound = src->largeSetLowerBound;
         dst->mediumSetPresentNumber = src->mediumSetPresentNumber;
@@ -1882,10 +2154,10 @@ static int ir_set_obj_mk (ClientData clientData, Tcl_Interp *interp,
  */
 static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv)
 {
-    Z_ScanRequest req;
-    Z_APDU apdu, *apdup = &apdu;
-    IRScanObj *obj = o;
-    IRObj *p = obj->parent;
+    Z_ScanRequest *req;
+    Z_APDU *apdu;
+    IrTcl_ScanObj *obj = o;
+    IrTcl_Obj *p = obj->parent;
     int r;
     oident bib1;
 #if CCL2RPN
@@ -1913,19 +2185,20 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv)
     }
     odr_reset (p->odr_out);
 
-    bib1.proto = PROTO_Z3950;
+    bib1.proto = p->protocol_type;
     bib1.class = CLASS_ATTSET;
     bib1.value = VAL_BIB1;
 
-    apdu.which = Z_APDU_scanRequest;
-    apdu.u.scanRequest = &req;
-    req.referenceId = NULL;
-    req.num_databaseNames = p->set_inher.num_databaseNames;
-    req.databaseNames = p->set_inher.databaseNames;
-    req.attributeSet = oid_getoidbyent (&bib1);
+    apdu = zget_APDU (p->odr_out, Z_APDU_scanRequest);
+    req = apdu->u.scanRequest;
+
+    set_referenceId (p->odr_out, &req->referenceId, p->set_inher.referenceId);
+    req->num_databaseNames = p->set_inher.num_databaseNames;
+    req->databaseNames = p->set_inher.databaseNames;
+    req->attributeSet = oid_getoidbyent (&bib1);
 
 #if !CCL2RPN
-    if (!(req.termListAndStartPoint = p_query_scan (p->odr_out, argv[2])))
+    if (!(req->termListAndStartPoint = p_query_scan (p->odr_out, argv[2])))
     {
         Tcl_AppendResult (interp, "Syntax error in query", NULL);
        return TCL_ERROR;
@@ -1939,19 +2212,19 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv)
     }
     ccl_pr_tree (rpn, stderr);
     fprintf (stderr, "\n");
-    if (!(req.termListAndStartPoint = ccl_scan_query (rpn)))
+    if (!(req->termListAndStartPoint = ccl_scan_query (rpn)))
         return TCL_ERROR;
 #endif
-    req.stepSize = &obj->stepSize;
-    req.numberOfTermsRequested = &obj->numberOfTermsRequested;
-    req.preferredPositionInResponse = &obj->preferredPositionInResponse;
-    logf (LOG_DEBUG, "stepSize=%d", *req.stepSize);
+    req->stepSize = &obj->stepSize;
+    req->numberOfTermsRequested = &obj->numberOfTermsRequested;
+    req->preferredPositionInResponse = &obj->preferredPositionInResponse;
+    logf (LOG_DEBUG, "stepSize=%d", *req->stepSize);
     logf (LOG_DEBUG, "numberOfTermsRequested=%d",
-          *req.numberOfTermsRequested);
+          *req->numberOfTermsRequested);
     logf (LOG_DEBUG, "preferredPositionInResponse=%d",
-          *req.preferredPositionInResponse);
+          *req->preferredPositionInResponse);
 
-    if (!z_APDU (p->odr_out, &apdup, 0))
+    if (!z_APDU (p->odr_out, &apdu, 0))
     {
         interp->result = odr_errlist [odr_geterror (p->odr_out)];
         odr_reset (p->odr_out);
@@ -1981,7 +2254,7 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv)
 static int do_stepSize (void *obj, Tcl_Interp *interp,
                         int argc, char **argv)
 {
-    IRScanObj *p = obj;
+    IrTcl_ScanObj *p = obj;
     if (argc <= 0)
     {
         p->stepSize = 0;
@@ -1996,7 +2269,7 @@ static int do_stepSize (void *obj, Tcl_Interp *interp,
 static int do_numberOfTermsRequested (void *obj, Tcl_Interp *interp,
                                       int argc, char **argv)
 {
-    IRScanObj *p = obj;
+    IrTcl_ScanObj *p = obj;
 
     if (argc <= 0)
     {
@@ -2013,7 +2286,7 @@ static int do_numberOfTermsRequested (void *obj, Tcl_Interp *interp,
 static int do_preferredPositionInResponse (void *obj, Tcl_Interp *interp,
                                            int argc, char **argv)
 {
-    IRScanObj *p = obj;
+    IrTcl_ScanObj *p = obj;
 
     if (argc <= 0)
     {
@@ -2029,7 +2302,7 @@ static int do_preferredPositionInResponse (void *obj, Tcl_Interp *interp,
 static int do_scanStatus (void *obj, Tcl_Interp *interp,
                           int argc, char **argv)
 {
-    IRScanObj *p = obj;
+    IrTcl_ScanObj *p = obj;
 
     if (argc <= 0)
         return TCL_OK;
@@ -2042,7 +2315,7 @@ static int do_scanStatus (void *obj, Tcl_Interp *interp,
 static int do_numberOfEntriesReturned (void *obj, Tcl_Interp *interp,
                                        int argc, char **argv)
 {
-    IRScanObj *p = obj;
+    IrTcl_ScanObj *p = obj;
 
     if (argc <= 0)
         return TCL_OK;
@@ -2055,7 +2328,7 @@ static int do_numberOfEntriesReturned (void *obj, Tcl_Interp *interp,
 static int do_positionOfTerm (void *obj, Tcl_Interp *interp,
                               int argc, char **argv)
 {
-    IRScanObj *p = obj;
+    IrTcl_ScanObj *p = obj;
 
     if (argc <= 0)
         return TCL_OK;
@@ -2067,7 +2340,7 @@ static int do_positionOfTerm (void *obj, Tcl_Interp *interp,
  */
 static int do_scanLine (void *obj, Tcl_Interp *interp, int argc, char **argv)
 {
-    IRScanObj *p = obj;
+    IrTcl_ScanObj *p = obj;
     int i;
     char numstr[20];
 
@@ -2075,16 +2348,18 @@ static int do_scanLine (void *obj, Tcl_Interp *interp, int argc, char **argv)
     {
         p->entries_flag = 0;
        p->entries = NULL;
-       p->nonSurrogateDiagnostics = NULL;
+       p->nonSurrogateDiagnosticNum = 0;
+        p->nonSurrogateDiagnosticList = 0;
        return TCL_OK;
     }
     else if (argc == -1)
     {
         p->entries_flag = 0;
        /* release entries */
-       p->entries = NULL;
-       /* release non diagnostics */
-       p->nonSurrogateDiagnostics = NULL;
+        p->entries = NULL;
+
+        ir_deleteDiags (&p->nonSurrogateDiagnosticList, 
+                        &p->nonSurrogateDiagnosticNum);
        return TCL_OK;
     }
     if (argc != 3)
@@ -2109,15 +2384,15 @@ static int do_scanLine (void *obj, Tcl_Interp *interp, int argc, char **argv)
        Tcl_AppendElement (interp, numstr);
        break;
     case Z_Entry_surrogateDiagnostic:
-        return 
-           mk_nonSurrogateDiagnostics (interp, p->entries[i].u.diag.condition,
-                                       p->entries[i].u.diag.addinfo);
+        Tcl_AppendElement (interp, "SD");
+        return ir_diagResult (interp, p->entries[i].u.diag.list,
+                              p->entries[i].u.diag.num);
        break;
     }
     return TCL_OK;
 }
 
-static IRMethod ir_scan_method_tab[] = {
+static IrTcl_Method ir_scan_method_tab[] = {
     { 0, "scan",                    do_scan },
     { 0, "stepSize",                do_stepSize },
     { 0, "numberOfTermsRequested",  do_numberOfTermsRequested },
@@ -2135,7 +2410,7 @@ static IRMethod ir_scan_method_tab[] = {
 static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp,
                                int argc, char **argv)
 {
-    IRMethods tabs[3];
+    IrTcl_Methods tabs[2];
 
     if (argc < 2)
     {
@@ -2154,7 +2429,15 @@ static int ir_scan_obj_method (ClientData clientData, Tcl_Interp *interp,
  */
 static void ir_scan_obj_delete (ClientData clientData)
 {
-    free ( (void*) clientData);
+    IrTcl_Methods tabs[2];
+    IrTcl_ScanObj *obj = clientData;
+
+    tabs[0].tab = ir_scan_method_tab;
+    tabs[0].obj = obj;
+    tabs[1].tab = NULL;
+
+    ir_method (NULL, -1, NULL, tabs);
+    free (obj);
 }
 
 /* 
@@ -2164,35 +2447,30 @@ static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp,
                            int argc, char **argv)
 {
     Tcl_CmdInfo parent_info;
-    IRScanObj *obj;
-    IRMethods tabs[3];
+    IrTcl_ScanObj *obj;
+    IrTcl_Methods tabs[2];
 
-    if (argc != 2)
+    if (argc != 3)
     {
         interp->result = "wrong # args";
         return TCL_ERROR;
     }
-    if (get_parent_info (interp, argv[1], &parent_info, NULL) == TCL_ERROR)
-        return TCL_ERROR;
+    if (!Tcl_GetCommandInfo (interp, argv[2], &parent_info))
+    {
+        interp->result = "No parent";
+       return TCL_ERROR;
+    }
     if (!(obj = ir_malloc (interp, sizeof(*obj))))
         return TCL_ERROR;
 
+    obj->parent = (IrTcl_Obj *) parent_info.clientData;
+
     tabs[0].tab = ir_scan_method_tab;
     tabs[0].obj = obj;
     tabs[1].tab = NULL;
 
     if (ir_method (interp, 0, NULL, tabs) == TCL_ERROR)
         return TCL_ERROR;
-#if 0
-    obj->stepSize = 0;
-    obj->numberOfTermsRequested = 20;
-    obj->preferredPositionInResponse = 1;
-
-    obj->entries = NULL;
-    obj->nonSurrogateDiagnostics = NULL;
-#endif
-
-    obj->parent = (IRObj *) parent_info.clientData;
     Tcl_CreateCommand (interp, argv[1], ir_scan_obj_method,
                        (ClientData) obj, ir_scan_obj_delete);
     return TCL_OK;
@@ -2202,7 +2480,7 @@ static int ir_scan_obj_mk (ClientData clientData, Tcl_Interp *interp,
 
 static void ir_initResponse (void *obj, Z_InitResponse *initrs)
 {
-    IRObj *p = obj;
+    IrTcl_Obj *p = obj;
 
     p->initResult = *initrs->result ? 1 : 0;
     if (!*initrs->result)
@@ -2210,6 +2488,8 @@ static void ir_initResponse (void *obj, Z_InitResponse *initrs)
     else
         logf (LOG_DEBUG, "Connection accepted by target");
 
+    get_referenceId (&p->set_inher.referenceId, initrs->referenceId);
+
     free (p->targetImplementationId);
     ir_strdup (p->interp, &p->targetImplementationId,
                initrs->implementationId);
@@ -2246,34 +2526,62 @@ static void ir_initResponse (void *obj, Z_InitResponse *initrs)
     }
 }
 
+static void ir_deleteDiags (IrTcl_Diagnostic **dst_list, int *dst_num)
+{
+    int i;
+    for (i = 0; i<*dst_num; i++)
+        free (dst_list[i]->addinfo);
+    free (*dst_list);
+    *dst_list = NULL;
+    *dst_num = 0;
+}
+
+static void ir_handleDiags (IrTcl_Diagnostic **dst_list, int *dst_num,
+                    Z_DiagRec **list, int num)
+{
+    int i;
+    char *addinfo;
+
+    *dst_num = num;
+    *dst_list = malloc (sizeof(**dst_list) * num);
+    if (!*dst_list) 
+    {
+        *dst_num = 0;
+        return;
+    }
+    for (i = 0; i<num; i++)
+    {
+        switch (list[i]->which)
+        {
+        case Z_DiagRec_defaultFormat:
+            (*dst_list)[i].condition = *list[i]->u.defaultFormat->condition;
+            addinfo = list[i]->u.defaultFormat->addinfo;
+            if (addinfo && 
+                ((*dst_list)[i].addinfo = malloc (strlen(addinfo)+1)))
+                strcpy ((*dst_list)[i].addinfo, addinfo);
+            break;
+        default:
+            (*dst_list)[i].addinfo = NULL;
+            (*dst_list)[i].condition = 0;
+        }
+    }
+}
+
 static void ir_handleRecords (void *o, Z_Records *zrs)
 {
-    IRObj *p = o;
-    IRSetObj *setobj = p->set_child;
+    IrTcl_Obj *p = o;
+    IrTcl_SetObj *setobj = p->set_child;
+
+    int offset;
+    IrTcl_RecordList *rl;
 
     setobj->which = zrs->which;
     setobj->recordFlag = 1;
-    if (zrs->which == Z_Records_NSD)
-    {
-        const char *addinfo;
-        
-        setobj->numberOfRecordsReturned = 0;
-        setobj->condition = *zrs->u.nonSurrogateDiagnostic->condition;
-        free (setobj->addinfo);
-        setobj->addinfo = NULL;
-        addinfo = zrs->u.nonSurrogateDiagnostic->addinfo;
-        if (addinfo && (setobj->addinfo = malloc (strlen(addinfo) + 1)))
-            strcpy (setobj->addinfo, addinfo);
-        logf (LOG_DEBUG, "Diagnostic response. %s (%d): %s",
-              diagbib1_str (setobj->condition),
-              setobj->condition,
-              setobj->addinfo ? setobj->addinfo : "");
-    }
-    else
+    
+    ir_deleteDiags (&setobj->nonSurrogateDiagnosticList,
+                    &setobj->nonSurrogateDiagnosticNum);
+    if (zrs->which == Z_Records_DBOSD)
     {
-        int offset;
-        IRRecordList *rl;
-        
         setobj->numberOfRecordsReturned = 
             zrs->u.databaseOrSurDiagnostics->num_records;
         logf (LOG_DEBUG, "Got %d records", setobj->numberOfRecordsReturned);
@@ -2284,16 +2592,12 @@ static void ir_handleRecords (void *o, Z_Records *zrs)
                                 records[offset]->which);
             if (rl->which == Z_NamePlusRecord_surrogateDiagnostic)
             {
-                Z_DiagRec *diagrec;
-                
-                diagrec = zrs->u.databaseOrSurDiagnostics->
-                    records[offset]->u.surrogateDiagnostic;
-                
-                rl->u.diag.condition = *diagrec->condition;
-                if (diagrec->addinfo && (rl->u.diag.addinfo =
-                                         malloc (strlen (diagrec->addinfo)+1)))
-                    strcpy (rl->u.diag.addinfo, diagrec->addinfo);
-            }
+                ir_handleDiags (&rl->u.surrogateDiagnostics.list,
+                                &rl->u.surrogateDiagnostics.num,
+                                &zrs->u.databaseOrSurDiagnostics->
+                                records[offset]->u.surrogateDiagnostic,
+                                1);
+            } 
             else
             {
                 Z_DatabaseRecord *zr; 
@@ -2303,54 +2607,88 @@ static void ir_handleRecords (void *o, Z_Records *zrs)
                     ->u.databaseRecord;
                 oe = (Odr_external*) zr;
                rl->u.dbrec.size = zr->u.octet_aligned->len;
+                rl->u.dbrec.type = VAL_USMARC;
                 if (oe->which == ODR_EXTERNAL_octet && rl->u.dbrec.size > 0)
                 {
                     const char *buf = (char*) zr->u.octet_aligned->buf;
                     if ((rl->u.dbrec.buf = malloc (rl->u.dbrec.size)))
                        memcpy (rl->u.dbrec.buf, buf, rl->u.dbrec.size);
+                    if (oe->direct_reference)
+                    {
+                        struct oident *ident = 
+                            oid_getentbyoid (oe->direct_reference);
+                        rl->u.dbrec.type = ident->value;
+                    }
                 }
                 else
                     rl->u.dbrec.buf = NULL;
             }
         }
     }
+    else if (zrs->which == Z_Records_multipleNSD)
+    {
+        logf (LOG_DEBUG, "multipleNonSurrogateDiagnostic %d",
+              zrs->u.multipleNonSurDiagnostics->num_diagRecs);
+        setobj->numberOfRecordsReturned = 0;
+        ir_handleDiags (&setobj->nonSurrogateDiagnosticList,
+                        &setobj->nonSurrogateDiagnosticNum,
+                        zrs->u.multipleNonSurDiagnostics->diagRecs,
+                        zrs->u.multipleNonSurDiagnostics->num_diagRecs);
+    }
+    else
+    {
+        logf (LOG_DEBUG, "NonSurrogateDiagnostic");
+        setobj->numberOfRecordsReturned = 0;
+        ir_handleDiags (&setobj->nonSurrogateDiagnosticList,
+                        &setobj->nonSurrogateDiagnosticNum,
+                        &zrs->u.nonSurrogateDiagnostic,
+                        1);
+    }
 }
 
 static void ir_searchResponse (void *o, Z_SearchResponse *searchrs)
 {    
-    IRObj *p = o;
-    IRSetObj *setobj = p->set_child;
+    IrTcl_Obj *p = o;
+    IrTcl_SetObj *setobj = p->set_child;
     Z_Records *zrs = searchrs->records;
 
-    if (setobj)
+    logf (LOG_DEBUG, "Received search response");
+    if (!setobj)
     {
-        setobj->searchStatus = searchrs->searchStatus ? 1 : 0;
-        setobj->resultCount = *searchrs->resultCount;
-        if (searchrs->presentStatus)
-            setobj->presentStatus = *searchrs->presentStatus;
-        if (searchrs->nextResultSetPosition)
-            setobj->nextResultSetPosition = *searchrs->nextResultSetPosition;
-
-        logf (LOG_DEBUG, "Search response %d, %d hits", 
-              setobj->searchStatus, setobj->resultCount);
-        if (zrs)
-            ir_handleRecords (o, zrs);
-        else
-            setobj->recordFlag = 0;
-    }
-    else
         logf (LOG_DEBUG, "Search response, no object!");
+       return;
+    }
+    setobj->searchStatus = searchrs->searchStatus ? 1 : 0;
+    get_referenceId (&setobj->set_inher.referenceId, searchrs->referenceId);
+    setobj->resultCount = *searchrs->resultCount;
+    if (searchrs->presentStatus)
+        setobj->presentStatus = *searchrs->presentStatus;
+    if (searchrs->nextResultSetPosition)
+        setobj->nextResultSetPosition = *searchrs->nextResultSetPosition;
+
+    logf (LOG_DEBUG, "Search response %d, %d hits", 
+          setobj->searchStatus, setobj->resultCount);
+    if (zrs)
+        ir_handleRecords (o, zrs);
+    else
+        setobj->recordFlag = 0;
 }
 
 
 static void ir_presentResponse (void *o, Z_PresentResponse *presrs)
 {
-    IRObj *p = o;
-    IRSetObj *setobj = p->set_child;
+    IrTcl_Obj *p = o;
+    IrTcl_SetObj *setobj = p->set_child;
     Z_Records *zrs = presrs->records;
     
-    logf (LOG_DEBUG, "Received presentResponse");
+    logf (LOG_DEBUG, "Received present response");
+    if (!setobj)
+    {
+        logf (LOG_DEBUG, "Present response, no object!");
+       return;
+    }
     setobj->presentStatus = *presrs->presentStatus;
+    get_referenceId (&setobj->set_inher.referenceId, presrs->referenceId);
     setobj->nextResultSetPosition = *presrs->nextResultSetPosition;
     if (zrs)
         ir_handleRecords (o, zrs);
@@ -2363,11 +2701,12 @@ static void ir_presentResponse (void *o, Z_PresentResponse *presrs)
 
 static void ir_scanResponse (void *o, Z_ScanResponse *scanrs)
 {
-    IRObj *p = o;
-    IRScanObj *scanobj = p->scan_child;
+    IrTcl_Obj *p = o;
+    IrTcl_ScanObj *scanobj = p->scan_child;
     
     logf (LOG_DEBUG, "Received scanResponse");
 
+    get_referenceId (&p->set_inher.referenceId, scanrs->referenceId);
     scanobj->scanStatus = *scanrs->scanStatus;
     logf (LOG_DEBUG, "scanStatus=%d", scanobj->scanStatus);
 
@@ -2387,9 +2726,9 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs)
 
     free (scanobj->entries);
     scanobj->entries = NULL;
-    free (scanobj->nonSurrogateDiagnostics);
-    scanobj->nonSurrogateDiagnostics = NULL;
 
+    ir_deleteDiags (&scanobj->nonSurrogateDiagnosticList,
+                    &scanobj->nonSurrogateDiagnosticNum);
     if (scanrs->entries)
     {
         int i;
@@ -2428,22 +2767,21 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs)
                        scanobj->entries[i].u.term.globalOccurrences = 0;
                     break;
                case Z_Entry_surrogateDiagnostic:
-                   scanobj->entries[i].u.diag.addinfo = 
-                           malloc (1+strlen(ze->u.surrogateDiagnostic->
-                                            addinfo));
-                    strcpy (scanobj->entries[i].u.diag.addinfo,
-                           ze->u.surrogateDiagnostic->addinfo);
-                   scanobj->entries[i].u.diag.condition = 
-                       *ze->u.surrogateDiagnostic->condition;
+                    ir_handleDiags (&scanobj->entries[i].u.diag.list,
+                                    &scanobj->entries[i].u.diag.num,
+                                    &ze->u.surrogateDiagnostic,
+                                    1);
                    break;
                }
            }
             break;
        case Z_ListEntries_nonSurrogateDiagnostics:
-           scanobj->num_diagRecs = scanrs->entries->
-                                 u.nonSurrogateDiagnostics->num_diagRecs;
-           scanobj->nonSurrogateDiagnostics = malloc (scanobj->num_diagRecs *
-                                 sizeof(*scanobj->nonSurrogateDiagnostics));
+            ir_handleDiags (&scanobj->nonSurrogateDiagnosticList,
+                            &scanobj->nonSurrogateDiagnosticNum,
+                            scanrs->entries->u.nonSurrogateDiagnostics->
+                            diagRecs,
+                            scanrs->entries->u.nonSurrogateDiagnostics->
+                            num_diagRecs);
             break;
        }
     }
@@ -2456,7 +2794,7 @@ static void ir_scanResponse (void *o, Z_ScanResponse *scanrs)
  */
 void ir_select_read (ClientData clientData)
 {
-    IRObj *p = clientData;
+    IrTcl_Obj *p = clientData;
     Z_APDU *apdu;
     int r;
 
@@ -2464,19 +2802,22 @@ void ir_select_read (ClientData clientData)
     {
         r = cs_rcvconnect (p->cs_link);
         if (r == 1)
+        {
+            logf (LOG_WARN, "cs_rcvconnect returned 1");
             return;
+        }
         p->connectFlag = 0;
         ir_select_remove_write (cs_fileno (p->cs_link), p);
         if (r < 0)
         {
             logf (LOG_DEBUG, "cs_rcvconnect error");
             if (p->failback)
-                Tcl_Eval (p->interp, p->failback);
+                IrTcl_eval (p->interp, p->failback);
             do_disconnect (p, NULL, 2, NULL);
             return;
         }
         if (p->callback)
-           Tcl_Eval (p->interp, p->callback);
+           IrTcl_eval (p->interp, p->callback);
         return;
     }
     do
@@ -2489,7 +2830,7 @@ void ir_select_read (ClientData clientData)
             logf (LOG_DEBUG, "cs_get failed, code %d", r);
             ir_select_remove (cs_fileno (p->cs_link), p);
             if (p->failback)
-                Tcl_Eval (p->interp, p->failback);
+                IrTcl_eval (p->interp, p->failback);
             do_disconnect (p, NULL, 2, NULL);
 
            /* relase ir object now if callback deleted it */
@@ -2504,10 +2845,10 @@ void ir_select_read (ClientData clientData)
         {
             logf (LOG_DEBUG, "%s", odr_errlist [odr_geterror (p->odr_in)]);
             if (p->failback)
-                Tcl_Eval (p->interp, p->failback);
+                IrTcl_eval (p->interp, p->failback);
             do_disconnect (p, NULL, 2, NULL);
 
-           /* relase ir object now if callback deleted it */
+           /* release ir object now if failback deleted it */
            ir_obj_delete (p);
             return;
         }
@@ -2528,12 +2869,12 @@ void ir_select_read (ClientData clientData)
         default:
             logf (LOG_WARN, "Received unknown APDU type (%d)", apdu->which);
             if (p->failback)
-                Tcl_Eval (p->interp, p->failback);
+                IrTcl_eval (p->interp, p->failback);
             do_disconnect (p, NULL, 2, NULL);
         }
         odr_reset (p->odr_in);
         if (p->callback)
-           Tcl_Eval (p->interp, p->callback);
+           IrTcl_eval (p->interp, p->callback);
        if (p->ref_count == 1)
        {
            ir_obj_delete (p);
@@ -2548,7 +2889,7 @@ void ir_select_read (ClientData clientData)
  */
 void ir_select_write (ClientData clientData)
 {
-    IRObj *p = clientData;
+    IrTcl_Obj *p = clientData;
     int r;
 
     logf (LOG_DEBUG, "In write handler");
@@ -2563,20 +2904,20 @@ void ir_select_write (ClientData clientData)
             logf (LOG_DEBUG, "cs_rcvconnect error");
             ir_select_remove_write (cs_fileno (p->cs_link), p);
             if (p->failback)
-                Tcl_Eval (p->interp, p->failback);
+                IrTcl_eval (p->interp, p->failback);
             do_disconnect (p, NULL, 2, NULL);
             return;
         }
         ir_select_remove_write (cs_fileno (p->cs_link), p);
         if (p->callback)
-           Tcl_Eval (p->interp, p->callback);
+           IrTcl_eval (p->interp, p->callback);
         return;
     }
     if ((r=cs_put (p->cs_link, p->sbuf, p->slen)) < 0)
     {   
         logf (LOG_DEBUG, "select write fail");
         if (p->failback)
-            Tcl_Eval (p->interp, p->failback);
+            IrTcl_eval (p->interp, p->failback);
         do_disconnect (p, NULL, 2, NULL);
     }
     else if (r == 0)            /* remove select bit */
@@ -2598,6 +2939,7 @@ int ir_tcl_init (Tcl_Interp *interp)
                       (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
     Tcl_CreateCommand (interp, "ir-scan", ir_scan_obj_mk,
                       (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+    irTcl_interp = interp;
     return TCL_OK;
 }