Added BER dumper.
authorSebastian Hammer <quinn@indexdata.com>
Mon, 19 Jun 1995 12:37:41 +0000 (12:37 +0000)
committerSebastian Hammer <quinn@indexdata.com>
Mon, 19 Jun 1995 12:37:41 +0000 (12:37 +0000)
client/client.c
odr/Makefile
odr/dumpber.c [new file with mode: 0644]
odr/odr.c
odr/odr_cons.c

index 70455bb..3189faf 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: client.c,v $
- * Revision 1.13  1995-06-16 10:29:11  quinn
+ * Revision 1.14  1995-06-19 12:37:41  quinn
+ * Added BER dumper.
+ *
+ * Revision 1.13  1995/06/16  10:29:11  quinn
  * *** empty log message ***
  *
  * Revision 1.12  1995/06/15  07:44:57  quinn
@@ -67,6 +70,7 @@
 
 #include <proto.h>
 #include <marcdisp.h>
+#include <diagbib1.h>
 
 #ifdef RPN_QUERY
 #ifdef PREFIX_QUERY
@@ -88,6 +92,7 @@ static int largeSetLowerBound = 1;
 static int mediumSetPresentNumber = 0;
 static int setno = 1;                   /* current set offset */
 static int protocol = PROTO_Z3950;      /* current app protocol */
+static int recordsyntax = VAL_USMARC;
 static ODR_MEM session_mem;                /* memory handle for init-response */
 static Z_InitResponse *session = 0;        /* session parameters */
 static char last_scan[512] = "0";
@@ -259,11 +264,10 @@ int cmd_authentication(char *arg)
 void display_record(Z_DatabaseRecord *p)
 {
     Odr_external *r = (Odr_external*) p;
+    oident *ent = oid_getentbyoid(r->direct_reference);
 
     if (r->direct_reference)
     {
-       oident *ent = oid_getentbyoid(r->direct_reference);
-
        printf("Record type: ");
        if (ent)
            printf("%s\n", ent->desc);
@@ -274,10 +278,20 @@ void display_record(Z_DatabaseRecord *p)
        }
     }
     if (r->which == ODR_EXTERNAL_octet && p->u.octet_aligned->len)
-    {
        marc_display ((char*)p->u.octet_aligned->buf, stdout);
+    else if (ent->value == VAL_SUTRS)
+    {
+       Odr_oct *rc;
+
+       if (!z_SUTRS(in, &rc, 0))
+       {
+           odr_perror(in, "decoding SUTRS");
+           odr_reset(in);
+       }
+       else
+           printf("%.*s", rc->len, rc->buf);
     }
-    else
+    else 
     {
        printf("Unknown record representation.\n");
        if (!odr_external(print, &r, 0))
@@ -297,7 +311,7 @@ static void display_diagrec(Z_DiagRec *p)
     Z_DiagRec *r = p;
 #endif
 
-    printf("Diagnostic message from database.\n");
+    printf("Diagnostic message from database:\n");
 #ifdef Z_95
     if (p->which != Z_DiagRec_defaultFormat)
     {
@@ -310,8 +324,11 @@ static void display_diagrec(Z_DiagRec *p)
     if (!(ent = oid_getentbyoid(r->diagnosticSetId)) ||
        ent->class != CLASS_DIAGSET || ent->value != VAL_BIB1)
        printf("Missing or unknown diagset\n");
-    printf("Error condition: %d", *r->condition);
-    printf(" -- %s\n", r->addinfo ? r->addinfo : "");
+    printf("    [%d] %s", *r->condition, diagbib1_str(*r->condition));
+    if (r->addinfo && *r->addinfo)
+       printf(" -- %s\n", r->addinfo);
+    else
+       printf("\n");
 }
 
 static void display_nameplusrecord(Z_NamePlusRecord *p)
@@ -389,6 +406,16 @@ static int send_searchRequest(char *arg)
     *req->smallSetUpperBound = smallSetUpperBound;
     *req->largeSetLowerBound = largeSetLowerBound;
     *req->mediumSetPresentNumber = mediumSetPresentNumber;
+    if (smallSetUpperBound > 0 || (largeSetLowerBound > 1 &&
+       mediumSetPresentNumber > 0))
+    {
+       oident prefsyn;
+
+       prefsyn.proto = protocol;
+       prefsyn.class = CLASS_RECSYN;
+       prefsyn.value = recordsyntax;
+       req->preferredRecordSyntax = odr_oiddup(out, oid_getoidbyent(&prefsyn));
+    }
     req->num_databaseNames = 1;
     req->databaseNames = &databaseNames;
 
@@ -519,6 +546,7 @@ static int send_presentRequest(char *arg)
 {
     Z_APDU *apdu = zget_APDU(out, Z_APDU_presentRequest);
     Z_PresentRequest *req = apdu->u.presentRequest;
+    oident prefsyn;
     int nos = 1;
     char *p;
     char setstring[100];
@@ -538,6 +566,10 @@ static int send_presentRequest(char *arg)
     }
     req->resultSetStartPoint = &setno;
     req->numberOfRecordsRequested = &nos;
+    prefsyn.proto = protocol;
+    prefsyn.class = CLASS_RECSYN;
+    prefsyn.value = recordsyntax;
+    req->preferredRecordSyntax = oid_getoidbyent(&prefsyn);
     send_apdu(apdu);
     printf("Sent presentRequest (%d+%d).\n", setno, nos);
     return 2;
@@ -664,6 +696,38 @@ int cmd_scan(char *arg)
     return 2;
 }
 
+int cmd_format(char *arg)
+{
+    if (!arg || !*arg)
+    {
+       printf("Usage: format <recordsyntax>\n");
+       return 0;
+    }
+    if (!strcmp(arg, "sutrs"))
+    {
+       printf("Preferred format is SUTRS.\n");
+       recordsyntax = VAL_SUTRS;
+       return 1;
+    }
+    else if (!strcmp(arg, "usmarc"))
+    {
+       printf("Preferred format is USMARC\n");
+       recordsyntax = VAL_USMARC;
+       return 1;
+    }
+    else if (!strcmp(arg, "danmarc"))
+    {
+       printf("Preferred format is DANMARC\n");
+       recordsyntax = VAL_DANMARC;
+       return 1;
+    }
+    else
+    {
+       printf("Specify one of {sutrs,usmarc,danmarc}.\n");
+       return 0;
+    }
+}
+
 static void initialize(void)
 {
 #ifdef RPN_QUERY
@@ -714,6 +778,7 @@ static int client(void)
        {"status", cmd_status, ""},
        {"setnames", cmd_setnames, ""},
        {"cancel", cmd_cancel, ""},
+       {"format", cmd_format, "<recordsyntax>"},
        {0,0}
     };
     char *netbuffer= 0;
@@ -787,6 +852,9 @@ static int client(void)
                if (!z_APDU(in, &apdu, 0))
                {
                    odr_perror(in, "Decoding incoming APDU");
+                   fprintf(stderr, "Packet dump:\n---------\n");
+                   odr_dumpBER(stderr, netbuffer, res);
+                   fprintf(stderr, "---------\n");
                    exit(1);
                }
 #if 0
index 1af7ed4..ef329cf 100644 (file)
@@ -1,7 +1,7 @@
 # Copyright (C) 1994, Index Data I/S 
 # All rights reserved.
 # Sebastian Hammer, Adam Dickmeiss
-# $Id: Makefile,v 1.20 1995-05-30 10:25:46 quinn Exp $
+# $Id: Makefile,v 1.21 1995-06-19 12:38:45 quinn Exp $
 
 SHELL=/bin/sh
 INCLUDE=-I../include -I.
@@ -14,7 +14,7 @@ LIBS=-lodr
 PO = odr_bool.o ber_bool.o ber_len.o ber_tag.o odr_util.o odr_null.o \
        ber_null.o odr_int.o ber_int.o odr_tag.o odr_cons.o odr_seq.o\
        odr_oct.o ber_oct.o odr_bit.o ber_bit.o odr_oid.o ber_oid.o odr_use.o \
-       odr_choice.o odr_any.o ber_any.o odr.o odr_mem.o
+       odr_choice.o odr_any.o ber_any.o odr.o odr_mem.o dumpber.o
 CPP=$(CC) -E
 
 all: $(LIBDIR) $(INCDIR) $(LIB)
diff --git a/odr/dumpber.c b/odr/dumpber.c
new file mode 100644 (file)
index 0000000..253e160
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1995, Index Data.
+ * See the file LICENSE for details.
+ * Sebastian Hammer, Adam Dickmeiss
+ *
+ * $Log: dumpber.c,v $
+ * Revision 1.1  1995-06-19 12:38:45  quinn
+ * Added BER dumper.
+ *
+ *
+ */
+
+#include <odr.h>
+#include <stdio.h>
+
+static int do_dumpBER(FILE *f, char *buf, int len, int level)
+{
+    int res, ll, class, tag, cons;
+    char *b = buf;
+    
+    if (!len)
+       return 0;
+    if (!buf[0] && !buf[1])
+       return 0;
+    if ((res = ber_dectag(b, &class, &tag, &cons)) <= 0)
+       return 0;
+    if (res > len)
+    {
+       fprintf(stderr, "Unexpected end of buffer\n");
+       return 0;
+    }
+    fprintf(stderr, "%*s", level * 4, "");
+    if (class == ODR_UNIVERSAL)
+    {
+       static char *nl[] =
+       {
+           "Ugh", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
+           "NULL", "OID", "OBJECT DESCIPTOR", "EXTERNAL", "REAL",
+           "ENUM", "[UNIV 11]", "[UNIV 12]", "[UNIV 13]", "[UNIV 14]",
+           "[UNIV 15]", "SEQUENCE", "SET", "NUMERICSTRING", "PRINTABLESTRING",
+           "[UNIV 20]", "[UNIV 21]", "[UNIV 22]", "[UNIV 23]", "[UNIV 24]",
+           "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", "[UNIV 28]"
+       };
+
+       if (tag < 28)
+           fprintf(stderr, "%s", nl[tag]);
+       else
+           fprintf(stderr, "[UNIV %d]", tag);
+    }
+    else if (class == ODR_CONTEXT)
+       fprintf(stderr, "[%d]", tag);
+    else
+       fprintf(stderr, "[%d:%d]", class, tag);
+    b += res;
+    len -= res;
+    if ((res = ber_declen(b, &ll)) <= 0)
+    {
+       fprintf(stderr, "bad length\n");
+       return 0;
+    }
+    if (res > len)
+    {
+       fprintf(stderr, "Unexpected end of buffer\n");
+       return 0;
+    }
+    b += res;
+    len -= res;
+    if (ll >= 0)
+       fprintf(stderr, " len=%d\n", ll);
+    else
+       fprintf(stderr, " len=?\n");
+    if (!cons)
+    {
+       if (ll < 0)
+       {
+           fprintf(stderr, "Bad length on primitive type.\n");
+           return 0;
+       }
+       return ll + (b - buf);
+    }
+    if (ll >= 0)
+       len = ll;
+    /* constructed - cycle through children */
+    while ((ll == -1 && len >= 2) || (ll >= 0 && len))
+    {
+       if (ll == -1 && *b == 0 && *(b + 1) == 0)
+           break;
+       if (!(res = do_dumpBER(f, b, len, level + 1)))
+       {
+           fprintf(stderr, "Dump of content element failed.\n");
+           return 0;
+       }
+       b += res;
+       len -= res;
+    }
+    if (ll == -1)
+    {
+       if (len < 2)
+       {
+           fprintf(stderr, "Buffer too short in indefinite lenght.\n");
+           return 0;
+       }
+       return (b - buf) + 2;
+    }
+    return b - buf;
+}
+
+int odr_dumpBER(FILE *f, char *buf, int len)
+{
+    return do_dumpBER(f, buf, len, 0);
+}
index d4424c0..0366db9 100644 (file)
--- a/odr/odr.c
+++ b/odr/odr.c
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: odr.c,v $
- * Revision 1.13  1995-05-22 11:32:02  quinn
+ * Revision 1.14  1995-06-19 12:38:46  quinn
+ * Added BER dumper.
+ *
+ * Revision 1.13  1995/05/22  11:32:02  quinn
  * Fixing Interface to odr_null.
  *
  * Revision 1.12  1995/05/16  08:50:49  quinn
@@ -66,7 +69,8 @@ char *odr_errlist[] =
     "Other error",
     "Protocol error",
     "Malformed data",
-    "Stack overflow"
+    "Stack overflow",
+    "Length of constructed type different from sum of members"
 };
 
 void odr_perror(ODR o, char *message)
index a2435b4..83231a3 100644 (file)
@@ -4,7 +4,10 @@
  * Sebastian Hammer, Adam Dickmeiss
  *
  * $Log: odr_cons.c,v $
- * Revision 1.11  1995-05-16 08:50:53  quinn
+ * Revision 1.12  1995-06-19 12:38:47  quinn
+ * Added BER dumper.
+ *
+ * Revision 1.11  1995/05/16  08:50:53  quinn
  * License, documentation, and memory fixes
  *
  * Revision 1.10  1995/04/18  08:15:21  quinn
@@ -134,7 +137,7 @@ int odr_constructed_end(ODR o)
            else if (o->bp - o->stack[o->stackp].base !=
                o->stack[o->stackp].len)
            {
-               o->error = OOTHER;
+               o->error = OCONLEN;
                return 0;
            }
            o->stackp--;