+#ifdef CHARSET_EBCDIC
+static int ebcdic_new(BIO *bi);
+static int ebcdic_free(BIO *a);
+static int ebcdic_read(BIO *b, char *out, int outl);
+static int ebcdic_write(BIO *b, char *in, int inl);
+static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr);
+static int ebcdic_gets(BIO *bp, char *buf, int size);
+static int ebcdic_puts(BIO *bp, char *str);
+
+#define BIO_TYPE_EBCDIC_FILTER (18|0x0200)
+static BIO_METHOD methods_ebcdic=
+ {
+ BIO_TYPE_EBCDIC_FILTER,
+ "EBCDIC/ASCII filter",
+ ebcdic_write,
+ ebcdic_read,
+ ebcdic_puts,
+ ebcdic_gets,
+ ebcdic_ctrl,
+ ebcdic_new,
+ ebcdic_free,
+ };
+
+typedef struct
+{
+ size_t alloced;
+ char buff[1];
+} EBCDIC_OUTBUFF;
+
+BIO_METHOD *BIO_f_ebcdic_filter()
+{
+ return(&methods_ebcdic);
+}
+
+static int ebcdic_new(BIO *bi)
+{
+ EBCDIC_OUTBUFF *wbuf;
+
+ wbuf = (EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + 1024);
+ wbuf->alloced = 1024;
+ wbuf->buff[0] = '\0';
+
+ bi->ptr=(char *)wbuf;
+ bi->init=1;
+ bi->flags=0;
+ return(1);
+}
+
+static int ebcdic_free(BIO *a)
+{
+ if (a == NULL) return(0);
+ if (a->ptr != NULL)
+ OPENSSL_free(a->ptr);
+ a->ptr=NULL;
+ a->init=0;
+ a->flags=0;
+ return(1);
+}
+
+static int ebcdic_read(BIO *b, char *out, int outl)
+{
+ int ret=0;
+
+ if (out == NULL || outl == 0) return(0);
+ if (b->next_bio == NULL) return(0);
+
+ ret=BIO_read(b->next_bio,out,outl);
+ if (ret > 0)
+ ascii2ebcdic(out,out,ret);
+ return(ret);
+}
+
+static int ebcdic_write(BIO *b, char *in, int inl)
+{
+ EBCDIC_OUTBUFF *wbuf;
+ int ret=0;
+ int num;
+ unsigned char n;
+
+ if ((in == NULL) || (inl <= 0)) return(0);
+ if (b->next_bio == NULL) return(0);
+
+ wbuf=(EBCDIC_OUTBUFF *)b->ptr;
+
+ if (inl > (num = wbuf->alloced))
+ {
+ num = num + num; /* double the size */
+ if (num < inl)
+ num = inl;
+ OPENSSL_free(wbuf);
+ wbuf=(EBCDIC_OUTBUFF *)OPENSSL_malloc(sizeof(EBCDIC_OUTBUFF) + num);
+
+ wbuf->alloced = num;
+ wbuf->buff[0] = '\0';
+
+ b->ptr=(char *)wbuf;
+ }
+
+ ebcdic2ascii(wbuf->buff, in, inl);
+
+ ret=BIO_write(b->next_bio, wbuf->buff, inl);
+
+ return(ret);
+}
+
+static long ebcdic_ctrl(BIO *b, int cmd, long num, char *ptr)
+{
+ long ret;
+
+ if (b->next_bio == NULL) return(0);
+ switch (cmd)
+ {
+ case BIO_CTRL_DUP:
+ ret=0L;
+ break;
+ default:
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ break;
+ }
+ return(ret);
+}
+
+static int ebcdic_gets(BIO *bp, char *buf, int size)
+{
+ int i, ret;
+ if (bp->next_bio == NULL) return(0);
+/* return(BIO_gets(bp->next_bio,buf,size));*/
+ for (i=0; i<size-1; ++i)
+ {
+ ret = ebcdic_read(bp,&buf[i],1);
+ if (ret <= 0)
+ break;
+ else if (buf[i] == '\n')
+ {
+ ++i;
+ break;
+ }
+ }
+ if (i < size)
+ buf[i] = '\0';
+ return (ret < 0 && i == 0) ? ret : i;
+}
+
+static int ebcdic_puts(BIO *bp, char *str)
+{
+ if (bp->next_bio == NULL) return(0);
+ return ebcdic_write(bp, str, strlen(str));
+}
+#endif
+
+int MAIN(int, char **);
+
+int MAIN(int argc, char *argv[])