Add the possibility to get hexdumps of unprintable data when using
[openssl.git] / crypto / bio / b_dump.c
index 5e05af5b0c2008307d4051316e6ae6005edaa8ae..7cbe4f22b51e55ec51748455c41d2d50095ae3ab 100644 (file)
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include "bio.h"
+#include <openssl/bio.h>
 
 #define TRUNCATE
 #define DUMP_WIDTH     16
+#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4))
 
-int BIO_dump(bio,s,len)
-BIO *bio;
-const char *s;
-int len;
+int BIO_dump(BIO *bio, const char *s, int len)
+       {
+       return BIO_dump_indent(bio, s, len, 0);
+       }
+
+int BIO_dump_indent(BIO *bio, const char *s, int len, int indent)
 {
   int ret=0;
-  char buf[160+1],tmp[20];
+  char buf[288+1],tmp[20],str[128+1];
   int i,j,rows,trunc;
   unsigned char ch;
+  int dump_width;
 
   trunc=0;
 
@@ -84,28 +88,44 @@ int len;
     trunc++;
 #endif
 
-  rows=(len/DUMP_WIDTH);
-  if ((rows*DUMP_WIDTH)<len)
+  if (indent < 0)
+    indent = 0;
+  if (indent) {
+    if (indent > 128) indent=128;
+    memset(str,' ',indent);
+  }
+  str[indent]='\0';
+
+  dump_width=DUMP_WIDTH_LESS_INDENT(indent);
+  rows=(len/dump_width);
+  if ((rows*dump_width)<len)
     rows++;
   for(i=0;i<rows;i++) {
     buf[0]='\0';       /* start with empty string */
-    sprintf(tmp,"%04x - ",i*DUMP_WIDTH);
-    strcpy(buf,tmp);
-    for(j=0;j<DUMP_WIDTH;j++) {
-      if (((i*DUMP_WIDTH)+j)>=len) {
+    strcpy(buf,str);
+    sprintf(tmp,"%04x - ",i*dump_width);
+    strcat(buf,tmp);
+    for(j=0;j<dump_width;j++) {
+      if (((i*dump_width)+j)>=len) {
        strcat(buf,"   ");
       } else {
-        ch=((unsigned char)*((char *)(s)+i*DUMP_WIDTH+j)) & 0xff;
+        ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
        sprintf(tmp,"%02x%c",ch,j==7?'-':' ');
         strcat(buf,tmp);
       }
     }
     strcat(buf,"  ");
-    for(j=0;j<DUMP_WIDTH;j++) {
-      if (((i*DUMP_WIDTH)+j)>=len)
+    for(j=0;j<dump_width;j++) {
+      if (((i*dump_width)+j)>=len)
        break;
-      ch=((unsigned char)*((char *)(s)+i*DUMP_WIDTH+j)) & 0xff;
+      ch=((unsigned char)*(s+i*dump_width+j)) & 0xff;
+#ifndef CHARSET_EBCDIC
       sprintf(tmp,"%c",((ch>=' ')&&(ch<='~'))?ch:'.');
+#else
+      sprintf(tmp,"%c",((ch>=os_toascii[' '])&&(ch<=os_toascii['~']))
+             ? os_toebcdic[ch]
+             : '.');
+#endif
       strcat(buf,tmp);
     }
     strcat(buf,"\n");
@@ -116,7 +136,7 @@ int len;
   }
 #ifdef TRUNCATE
   if (trunc > 0) {
-    sprintf(buf,"%04x - <SPACES/NULS>\n",len+trunc);
+    sprintf(buf,"%s%04x - <SPACES/NULS>\n",str,len+trunc);
     ret+=BIO_write(bio,(char *)buf,strlen(buf));
   }
 #endif