aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2000-09-20 13:55:50 +0000
committerRichard Levitte <levitte@openssl.org>2000-09-20 13:55:50 +0000
commit645749ef98612340b11c4bf2ba856e1fa469912b (patch)
tree3a93d71b7f63b5b01f085c38211ce82af0778125
parent9a0c0d3f7441515452caff3380b235bb15d33a5e (diff)
downloadopenssl-645749ef98612340b11c4bf2ba856e1fa469912b.tar.gz
On VMS, stdout may very well lead to a file that is written to in a
record-oriented fashion. That means that every write() will write a separate record, which will be read separately by the programs trying to read from it. This can be very confusing. The solution is to put a BIO filter in the way that will buffer text until a linefeed is reached, and then write everything a line at a time, so every record written will be an actual line, not chunks of lines and not (usually doesn't happen, but I've seen it once) several lines in one record. Voila, BIO_f_linebuffer() is born. Since we're so close to release time, I'm making this VMS-only for now, just to make sure no code is needlessly broken by this. After the release, this BIO method will be enabled on all other platforms as well.
-rw-r--r--CHANGES16
-rw-r--r--apps/asn1pars.c8
-rw-r--r--apps/ca.c24
-rw-r--r--apps/ciphers.c8
-rw-r--r--apps/crl.c20
-rw-r--r--apps/crl2p7.c10
-rw-r--r--apps/dgst.c12
-rw-r--r--apps/dh.c10
-rw-r--r--apps/dhparam.c10
-rw-r--r--apps/dsa.c10
-rw-r--r--apps/dsaparam.c10
-rw-r--r--apps/enc.c10
-rw-r--r--apps/errstr.c8
-rw-r--r--apps/gendh.c10
-rw-r--r--apps/gendsa.c10
-rw-r--r--apps/genrsa.c10
-rw-r--r--apps/nseq.c13
-rw-r--r--apps/openssl.c16
-rw-r--r--apps/passwd.c8
-rw-r--r--apps/pkcs12.c13
-rw-r--r--apps/pkcs7.c10
-rw-r--r--apps/pkcs8.c15
-rw-r--r--apps/rand.c8
-rw-r--r--apps/req.c16
-rw-r--r--apps/rsa.c10
-rw-r--r--apps/rsautl.c12
-rw-r--r--apps/sess_id.c10
-rw-r--r--apps/smime.c12
-rw-r--r--apps/spkac.c22
-rw-r--r--apps/x509.c18
-rw-r--r--crypto/bio/Makefile.ssl2
-rw-r--r--crypto/bio/bf_lbuf.c397
-rw-r--r--crypto/bio/bio.h5
-rw-r--r--crypto/bio/bio_err.c1
-rw-r--r--crypto/crypto-lib.com3
-rwxr-xr-xutil/libeay.num1
36 files changed, 730 insertions, 48 deletions
diff --git a/CHANGES b/CHANGES
index af491c8f71..786ab5064c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,22 @@
Changes between 0.9.5a and 0.9.6 [xx XXX 2000]
+ *) On VMS, stdout may very well lead to a file that is written to
+ in a record-oriented fashion. That means that every write() will
+ write a separate record, which will be read separately by the
+ programs trying to read from it. This can be very confusing.
+
+ The solution is to put a BIO filter in the way that will buffer
+ text until a linefeed is reached, and then write everything a
+ line at a time, so every record written will be an actual line,
+ not chunks of lines and not (usually doesn't happen, but I've
+ seen it once) several lines in one record. BIO_f_linebuffer() is
+ the answer.
+
+ Currently, it's a VMS-only method, because that's where it has
+ been tested well enough.
+ [Richard Levitte]
+
*) Remove 'optimized' squaring variant in BN_mod_mul_montgomery,
it can return incorrect results.
(Note: The buggy variant was not enabled in OpenSSL 0.9.5a,
diff --git a/apps/asn1pars.c b/apps/asn1pars.c
index 30e1da443a..f25c9f84e8 100644
--- a/apps/asn1pars.c
+++ b/apps/asn1pars.c
@@ -206,6 +206,12 @@ bad:
goto end;
}
BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
if (oidfile != NULL)
{
@@ -315,7 +321,7 @@ bad:
end:
BIO_free(derout);
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (b64 != NULL) BIO_free(b64);
if (ret != 0)
ERR_print_errors(bio_err);
diff --git a/apps/ca.c b/apps/ca.c
index 0931401992..2d71104745 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -690,6 +690,12 @@ bad:
if (verbose)
{
BIO_set_fp(out,stdout,BIO_NOCLOSE|BIO_FP_TEXT); /* cannot fail */
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
TXT_DB_write(out,db);
BIO_printf(bio_err,"%d entries loaded from the database\n",
db->data->num);
@@ -724,7 +730,15 @@ bad:
}
}
else
+ {
BIO_set_fp(Sout,stdout,BIO_NOCLOSE|BIO_FP_TEXT);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ Sout = BIO_push(tmpbio, Sout);
+ }
+#endif
+ }
}
if (req)
@@ -1020,7 +1034,7 @@ bad:
#endif
BIO_free(in);
- BIO_free(out);
+ BIO_free_all(out);
in=NULL;
out=NULL;
if (rename(serialfile,buf[2]) < 0)
@@ -1237,9 +1251,9 @@ bad:
ret=0;
err:
BIO_free(hex);
- BIO_free(Cout);
- BIO_free(Sout);
- BIO_free(out);
+ BIO_free_all(Cout);
+ BIO_free_all(Sout);
+ BIO_free_all(out);
BIO_free(in);
sk_X509_pop_free(cert_sk,X509_free);
@@ -1354,7 +1368,7 @@ static int save_serial(char *serialfile, BIGNUM *serial)
BIO_puts(out,"\n");
ret=1;
err:
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (ai != NULL) ASN1_INTEGER_free(ai);
return(ret);
}
diff --git a/apps/ciphers.c b/apps/ciphers.c
index 72b2009e18..b6e2f966d8 100644
--- a/apps/ciphers.c
+++ b/apps/ciphers.c
@@ -108,6 +108,12 @@ int MAIN(int argc, char **argv)
if (bio_err == NULL)
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ STDout = BIO_push(tmpbio, STDout);
+ }
+#endif
argc--;
argv++;
@@ -195,7 +201,7 @@ err:
end:
if (ctx != NULL) SSL_CTX_free(ctx);
if (ssl != NULL) SSL_free(ssl);
- if (STDout != NULL) BIO_free(STDout);
+ if (STDout != NULL) BIO_free_all(STDout);
EXIT(ret);
}
diff --git a/apps/crl.c b/apps/crl.c
index b1c3325f21..3b5725f23f 100644
--- a/apps/crl.c
+++ b/apps/crl.c
@@ -122,7 +122,15 @@ int MAIN(int argc, char **argv)
if (bio_out == NULL)
if ((bio_out=BIO_new(BIO_s_file())) != NULL)
+ {
BIO_set_fp(bio_out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_out = BIO_push(tmpbio, bio_out);
+ }
+#endif
+ }
informat=FORMAT_PEM;
outformat=FORMAT_PEM;
@@ -314,7 +322,15 @@ bad:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -340,8 +356,8 @@ bad:
if (!i) { BIO_printf(bio_err,"unable to write CRL\n"); goto end; }
ret=0;
end:
- BIO_free(out);
- BIO_free(bio_out);
+ BIO_free_all(out);
+ BIO_free_all(bio_out);
bio_out=NULL;
X509_CRL_free(x);
if(store) {
diff --git a/apps/crl2p7.c b/apps/crl2p7.c
index d02862710d..7f853b65ab 100644
--- a/apps/crl2p7.c
+++ b/apps/crl2p7.c
@@ -239,7 +239,15 @@ bad:
sk_free(certflst);
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -266,7 +274,7 @@ bad:
ret=0;
end:
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (p7 != NULL) PKCS7_free(p7);
if (crl != NULL) X509_CRL_free(crl);
diff --git a/apps/dgst.c b/apps/dgst.c
index d7e524a883..0e93c97ca5 100644
--- a/apps/dgst.c
+++ b/apps/dgst.c
@@ -236,7 +236,15 @@ int MAIN(int argc, char **argv)
if(out_bin)
out = BIO_new_file(outfile, "wb");
else out = BIO_new_file(outfile, "w");
- } else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ } else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
if(!out) {
BIO_printf(bio_err, "Error opening output file %s\n",
@@ -323,7 +331,7 @@ end:
OPENSSL_free(buf);
}
if (in != NULL) BIO_free(in);
- BIO_free(out);
+ BIO_free_all(out);
EVP_PKEY_free(sigkey);
if(sigbuf) OPENSSL_free(sigbuf);
if (bmd != NULL) BIO_free(bmd);
diff --git a/apps/dh.c b/apps/dh.c
index ee71d95f0c..7465442e49 100644
--- a/apps/dh.c
+++ b/apps/dh.c
@@ -184,7 +184,15 @@ bad:
}
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -309,7 +317,7 @@ bad:
ret=0;
end:
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (dh != NULL) DH_free(dh);
EXIT(ret);
}
diff --git a/apps/dhparam.c b/apps/dhparam.c
index a738c5af67..5f9b60148d 100644
--- a/apps/dhparam.c
+++ b/apps/dhparam.c
@@ -391,7 +391,15 @@ bad:
goto end;
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -496,7 +504,7 @@ bad:
ret=0;
end:
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (dh != NULL) DH_free(dh);
EXIT(ret);
}
diff --git a/apps/dsa.c b/apps/dsa.c
index 842e0c0d15..7c4a46f78e 100644
--- a/apps/dsa.c
+++ b/apps/dsa.c
@@ -233,7 +233,15 @@ bad:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -281,7 +289,7 @@ bad:
ret=0;
end:
if(in != NULL) BIO_free(in);
- if(out != NULL) BIO_free(out);
+ if(out != NULL) BIO_free_all(out);
if(dsa != NULL) DSA_free(dsa);
if(passin) OPENSSL_free(passin);
if(passout) OPENSSL_free(passout);
diff --git a/apps/dsaparam.c b/apps/dsaparam.c
index a15d6ea309..f861ec7b1a 100644
--- a/apps/dsaparam.c
+++ b/apps/dsaparam.c
@@ -205,7 +205,15 @@ bad:
}
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -347,7 +355,7 @@ bad:
ret=0;
end:
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (dsa != NULL) DSA_free(dsa);
EXIT(ret);
}
diff --git a/apps/enc.c b/apps/enc.c
index 49338aca0f..2101b4cc64 100644
--- a/apps/enc.c
+++ b/apps/enc.c
@@ -416,7 +416,15 @@ bad:
if (outf == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outf) <= 0)
@@ -584,7 +592,7 @@ end:
if (strbuf != NULL) OPENSSL_free(strbuf);
if (buff != NULL) OPENSSL_free(buff);
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (benc != NULL) BIO_free(benc);
if (b64 != NULL) BIO_free(b64);
if(pass) OPENSSL_free(pass);
diff --git a/apps/errstr.c b/apps/errstr.c
index 2c62046476..e392328f93 100644
--- a/apps/errstr.c
+++ b/apps/errstr.c
@@ -91,12 +91,18 @@ int MAIN(int argc, char **argv)
out=BIO_new(BIO_s_file());
if ((out != NULL) && BIO_set_fp(out,stdout,BIO_NOCLOSE))
{
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
lh_node_stats_bio((LHASH *)ERR_get_string_table(),out);
lh_stats_bio((LHASH *)ERR_get_string_table(),out);
lh_node_usage_stats_bio((LHASH *)
ERR_get_string_table(),out);
}
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
argc--;
argv++;
}
diff --git a/apps/gendh.c b/apps/gendh.c
index caf5e8d736..e0c7889a31 100644
--- a/apps/gendh.c
+++ b/apps/gendh.c
@@ -142,7 +142,15 @@ bad:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -174,7 +182,7 @@ bad:
end:
if (ret != 0)
ERR_print_errors(bio_err);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (dh != NULL) DH_free(dh);
EXIT(ret);
}
diff --git a/apps/gendsa.c b/apps/gendsa.c
index 1937613849..6022d8f142 100644
--- a/apps/gendsa.c
+++ b/apps/gendsa.c
@@ -178,7 +178,15 @@ bad:
if (out == NULL) goto end;
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -209,7 +217,7 @@ end:
if (ret != 0)
ERR_print_errors(bio_err);
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (dsa != NULL) DSA_free(dsa);
if(passout) OPENSSL_free(passout);
EXIT(ret);
diff --git a/apps/genrsa.c b/apps/genrsa.c
index 5cf47e6921..ac0b709e7a 100644
--- a/apps/genrsa.c
+++ b/apps/genrsa.c
@@ -168,7 +168,15 @@ bad:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -212,7 +220,7 @@ bad:
ret=0;
err:
if (rsa != NULL) RSA_free(rsa);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if(passout) OPENSSL_free(passout);
if (ret != 0)
ERR_print_errors(bio_err);
diff --git a/apps/nseq.c b/apps/nseq.c
index 7210fbdb5e..1d73d1ad52 100644
--- a/apps/nseq.c
+++ b/apps/nseq.c
@@ -119,8 +119,15 @@ int MAIN(int argc, char **argv)
"Can't open output file %s\n", outfile);
goto end;
}
- } else out = BIO_new_fp(stdout, BIO_NOCLOSE);
-
+ } else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
if (toseq) {
seq = NETSCAPE_CERT_SEQUENCE_new();
seq->certs = sk_X509_new_null();
@@ -152,7 +159,7 @@ int MAIN(int argc, char **argv)
ret = 0;
end:
BIO_free(in);
- BIO_free(out);
+ BIO_free_all(out);
NETSCAPE_CERT_SEQUENCE_free(seq);
EXIT(ret);
diff --git a/apps/openssl.c b/apps/openssl.c
index c3680c5e71..4f61006b73 100644
--- a/apps/openssl.c
+++ b/apps/openssl.c
@@ -238,13 +238,19 @@ static int do_cmd(LHASH *prog, int argc, char *argv[])
else if ((strncmp(argv[0],"no-",3)) == 0)
{
BIO *bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_stdout = BIO_push(tmpbio, bio_stdout);
+ }
+#endif
f.name=argv[0]+3;
ret = (lh_retrieve(prog,&f) != NULL);
if (!ret)
BIO_printf(bio_stdout, "%s\n", argv[0]);
else
BIO_printf(bio_stdout, "%s\n", argv[0]+3);
- BIO_free(bio_stdout);
+ BIO_free_all(bio_stdout);
goto end;
}
else if ((strcmp(argv[0],"quit") == 0) ||
@@ -269,11 +275,17 @@ static int do_cmd(LHASH *prog, int argc, char *argv[])
else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */
list_type = FUNC_TYPE_CIPHER;
bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ bio_stdout = BIO_push(tmpbio, bio_stdout);
+ }
+#endif
for (fp=functions; fp->name != NULL; fp++)
if (fp->type == list_type)
BIO_printf(bio_stdout, "%s\n", fp->name);
- BIO_free(bio_stdout);
+ BIO_free_all(bio_stdout);
ret=0;
goto end;
}
diff --git a/apps/passwd.c b/apps/passwd.c
index 6c1aed0f0b..6851a9927d 100644
--- a/apps/passwd.c
+++ b/apps/passwd.c
@@ -81,6 +81,12 @@ int MAIN(int argc, char **argv)
if (out == NULL)
goto err;
BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
badopt = 0, opt_done = 0;
i = 0;
@@ -276,7 +282,7 @@ err:
if (in)
BIO_free(in);
if (out)
- BIO_free(out);
+ BIO_free_all(out);
EXIT(ret);
}
diff --git a/apps/pkcs12.c b/apps/pkcs12.c
index 070993de30..6789169bdb 100644
--- a/apps/pkcs12.c
+++ b/apps/pkcs12.c
@@ -350,8 +350,15 @@ int MAIN(int argc, char **argv)
CRYPTO_push_info("write files");
#endif
- if (!outfile) out = BIO_new_fp(stdout, BIO_NOCLOSE);
- else out = BIO_new_file(outfile, "wb");
+ if (!outfile) {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ } else out = BIO_new_file(outfile, "wb");
if (!out) {
BIO_printf(bio_err, "Error opening output file %s\n",
outfile ? outfile : "<stdout>");
@@ -657,7 +664,7 @@ int MAIN(int argc, char **argv)
CRYPTO_remove_all_info();
#endif
BIO_free(in);
- BIO_free(out);
+ BIO_free_all(out);
if (canames) sk_free(canames);
if(passin) OPENSSL_free(passin);
if(passout) OPENSSL_free(passout);
diff --git a/apps/pkcs7.c b/apps/pkcs7.c
index f471cc77fd..0af269007a 100644
--- a/apps/pkcs7.c
+++ b/apps/pkcs7.c
@@ -196,7 +196,15 @@ bad:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -280,6 +288,6 @@ bad:
end:
if (p7 != NULL) PKCS7_free(p7);
if (in != NULL) BIO_free(in);
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
EXIT(ret);
}
diff --git a/apps/pkcs8.c b/apps/pkcs8.c
index b0914cd453..7b588e4337 100644
--- a/apps/pkcs8.c
+++ b/apps/pkcs8.c
@@ -194,8 +194,15 @@ int MAIN(int argc, char **argv)
"Can't open output file %s\n", outfile);
return (1);
}
- } else out = BIO_new_fp (stdout, BIO_NOCLOSE);
-
+ } else {
+ out = BIO_new_fp (stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
if (topk8) {
if(informat == FORMAT_PEM)
pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, passin);
@@ -253,7 +260,7 @@ int MAIN(int argc, char **argv)
}
PKCS8_PRIV_KEY_INFO_free (p8inf);
EVP_PKEY_free(pkey);
- BIO_free(out);
+ BIO_free_all(out);
if(passin) OPENSSL_free(passin);
if(passout) OPENSSL_free(passout);
return (0);
@@ -336,7 +343,7 @@ int MAIN(int argc, char **argv)
}
EVP_PKEY_free(pkey);
- BIO_free(out);
+ BIO_free_all(out);
BIO_free(in);
if(passin) OPENSSL_free(passin);
if(passout) OPENSSL_free(passout);
diff --git a/apps/rand.c b/apps/rand.c
index fa9bc023f4..04764d7ffb 100644
--- a/apps/rand.c
+++ b/apps/rand.c
@@ -101,7 +101,15 @@ int MAIN(int argc, char **argv)
if (outfile != NULL)
r = BIO_write_filename(out, outfile);
else
+ {
r = BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
if (r <= 0)
goto err;
diff --git a/apps/req.c b/apps/req.c
index 2c1b9ee876..1aab38d9d7 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -609,6 +609,12 @@ bad:
{
BIO_printf(bio_err,"writing new private key to stdout\n");
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
}
else
{
@@ -804,7 +810,15 @@ loop:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if ((keyout != NULL) && (strcmp(outfile,keyout) == 0))
@@ -890,7 +904,7 @@ end:
}
if ((req_conf != NULL) && (req_conf != config)) CONF_free(req_conf);
BIO_free(in);
- BIO_free(out);
+ BIO_free_all(out);
EVP_PKEY_free(pkey);
X509_REQ_free(req);
X509_free(x509ss);
diff --git a/apps/rsa.c b/apps/rsa.c
index fc8fa54941..b4b0651a94 100644
--- a/apps/rsa.c
+++ b/apps/rsa.c
@@ -278,7 +278,15 @@ bad:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -377,7 +385,7 @@ bad:
ret=0;
end:
if(in != NULL) BIO_free(in);
- if(out != NULL) BIO_free(out);
+ if(out != NULL) BIO_free_all(out);
if(rsa != NULL) RSA_free(rsa);
if(passin) OPENSSL_free(passin);
if(passout) OPENSSL_free(passout);
diff --git a/apps/rsautl.c b/apps/rsautl.c
index ba95229e1a..bcb94c3d81 100644
--- a/apps/rsautl.c
+++ b/apps/rsautl.c
@@ -198,7 +198,15 @@ int MAIN(int argc, char **argv)
ERR_print_errors(bio_err);
goto end;
}
- } else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ } else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
keysize = RSA_size(rsa);
@@ -255,7 +263,7 @@ int MAIN(int argc, char **argv)
end:
RSA_free(rsa);
BIO_free(in);
- BIO_free(out);
+ BIO_free_all(out);
if(rsa_in) OPENSSL_free(rsa_in);
if(rsa_out) OPENSSL_free(rsa_out);
return ret;
diff --git a/apps/sess_id.c b/apps/sess_id.c
index 71d5aa0b7c..60cc3f1e49 100644
--- a/apps/sess_id.c
+++ b/apps/sess_id.c
@@ -206,7 +206,15 @@ bad:
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -262,7 +270,7 @@ bad:
}
ret=0;
end:
- if (out != NULL) BIO_free(out);
+ if (out != NULL) BIO_free_all(out);
if (x != NULL) SSL_SESSION_free(x);
EXIT(ret);
}
diff --git a/apps/smime.c b/apps/smime.c
index 25997feb6d..9467b59bef 100644
--- a/apps/smime.c
+++ b/apps/smime.c
@@ -393,7 +393,15 @@ int MAIN(int argc, char **argv)
"Can't open output file %s\n", outfile);
goto end;
}
- } else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ } else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
if(operation == SMIME_VERIFY) {
if(!(store = setup_verify(CAfile, CApath))) goto end;
@@ -490,7 +498,7 @@ end:
PKCS7_free(p7);
BIO_free(in);
BIO_free(indata);
- BIO_free(out);
+ BIO_free_all(out);
if(passin) OPENSSL_free(passin);
return (ret);
}
diff --git a/apps/spkac.c b/apps/spkac.c
index ad45c2ddb7..459d730a70 100644
--- a/apps/spkac.c
+++ b/apps/spkac.c
@@ -192,7 +192,15 @@ bad:
spkstr = NETSCAPE_SPKI_b64_encode(spki);
if (outfile) out = BIO_new_file(outfile, "w");
- else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
if(!out) {
BIO_printf(bio_err, "Error opening output file\n");
@@ -241,7 +249,15 @@ bad:
}
if (outfile) out = BIO_new_file(outfile, "w");
- else out = BIO_new_fp(stdout, BIO_NOCLOSE);
+ else {
+ out = BIO_new_fp(stdout, BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
if(!out) {
BIO_printf(bio_err, "Error opening output file\n");
@@ -268,7 +284,7 @@ end:
CONF_free(conf);
NETSCAPE_SPKI_free(spki);
BIO_free(in);
- BIO_free(out);
+ BIO_free_all(out);
BIO_free(key);
EVP_PKEY_free(pkey);
if(passin) OPENSSL_free(passin);
diff --git a/apps/x509.c b/apps/x509.c
index b86352e2fb..76dd66db86 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -183,6 +183,12 @@ int MAIN(int argc, char **argv)
if (bio_err == NULL)
bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
STDout=BIO_new_fp(stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ STDout = BIO_push(tmpbio, STDout);
+ }
+#endif
informat=FORMAT_PEM;
outformat=FORMAT_PEM;
@@ -576,7 +582,15 @@ bad:
goto end;
}
if (outfile == NULL)
+ {
BIO_set_fp(out,stdout,BIO_NOCLOSE);
+#ifdef VMS
+ {
+ BIO *tmpbio = BIO_new(BIO_f_linebuffer());
+ out = BIO_push(tmpbio, out);
+ }
+#endif
+ }
else
{
if (BIO_write_filename(out,outfile) <= 0)
@@ -933,8 +947,8 @@ end:
app_RAND_write_file(NULL, bio_err);
OBJ_cleanup();
CONF_free(extconf);
- BIO_free(out);
- BIO_free(STDout);
+ BIO_free_all(out);
+ BIO_free_all(STDout);
X509_STORE_free(ctx);
X509_REQ_free(req);
X509_free(x);
diff --git a/crypto/bio/Makefile.ssl b/crypto/bio/Makefile.ssl
index 17d2314398..af5998b102 100644
--- a/crypto/bio/Makefile.ssl
+++ b/crypto/bio/Makefile.ssl
@@ -27,11 +27,13 @@ LIBSRC= bio_lib.c bio_cb.c bio_err.c \
bss_file.c bss_sock.c bss_conn.c \
bf_null.c bf_buff.c b_print.c b_dump.c \
b_sock.c bss_acpt.c bf_nbio.c bss_log.c bss_bio.c
+# bf_lbuf.c
LIBOBJ= bio_lib.o bio_cb.o bio_err.o \
bss_mem.o bss_null.o bss_fd.o \
bss_file.o bss_sock.o bss_conn.o \
bf_null.o bf_buff.o b_print.o b_dump.o \
b_sock.o bss_acpt.o bf_nbio.o bss_log.o bss_bio.o
+# bf_lbuf.o
SRC= $(LIBSRC)
diff --git a/crypto/bio/bf_lbuf.c b/crypto/bio/bf_lbuf.c
new file mode 100644
index 0000000000..7bcf8ed941
--- /dev/null
+++ b/crypto/bio/bf_lbuf.c
@@ -0,0 +1,397 @@
+/* crypto/bio/bf_buff.c */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include "cryptlib.h"
+#include <openssl/bio.h>
+#include <openssl/evp.h>
+
+static int linebuffer_write(BIO *h, const char *buf,int num);
+static int linebuffer_read(BIO *h, char *buf, int size);
+static int linebuffer_puts(BIO *h, const char *str);
+static int linebuffer_gets(BIO *h, char *str, int size);
+static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2);
+static int linebuffer_new(BIO *h);
+static int linebuffer_free(BIO *data);
+static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
+
+/* A 10k maximum should be enough for most purposes */
+#define DEFAULT_LINEBUFFER_SIZE 1024*10
+
+/* #define DEBUG */
+
+static BIO_METHOD methods_linebuffer=
+ {
+ BIO_TYPE_LINEBUFFER,
+ "linebuffer",
+ linebuffer_write,
+ linebuffer_read,
+ linebuffer_puts,
+ linebuffer_gets,
+ linebuffer_ctrl,
+ linebuffer_new,
+ linebuffer_free,
+ linebuffer_callback_ctrl,
+ };
+
+BIO_METHOD *BIO_f_linebuffer(void)
+ {
+ return(&methods_linebuffer);
+ }
+
+typedef struct bio_linebuffer_ctx_struct
+ {
+ char *obuf; /* the output char array */
+ int obuf_size; /* how big is the output buffer */
+ int obuf_len; /* how many bytes are in it */
+ } BIO_LINEBUFFER_CTX;
+
+static int linebuffer_new(BIO *bi)
+ {
+ BIO_LINEBUFFER_CTX *ctx;
+
+ ctx=(BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX));
+ if (ctx == NULL) return(0);
+ ctx->obuf=(char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE);
+ if (ctx->obuf == NULL) { OPENSSL_free(ctx); return(0); }
+ ctx->obuf_size=DEFAULT_LINEBUFFER_SIZE;
+ ctx->obuf_len=0;
+
+ bi->init=1;
+ bi->ptr=(char *)ctx;
+ bi->flags=0;
+ return(1);
+ }
+
+static int linebuffer_free(BIO *a)
+ {
+ BIO_LINEBUFFER_CTX *b;
+
+ if (a == NULL) return(0);
+ b=(BIO_LINEBUFFER_CTX *)a->ptr;
+ if (b->obuf != NULL) OPENSSL_free(b->obuf);
+ OPENSSL_free(a->ptr);
+ a->ptr=NULL;
+ a->init=0;
+ a->flags=0;
+ return(1);
+ }
+
+static int linebuffer_read(BIO *b, char *out, int outl)
+ {
+ int ret=0;
+
+ if (out == NULL) return(0);
+ if (b->next_bio == NULL) return(0);
+ ret=BIO_read(b->next_bio,out,outl);
+ BIO_clear_retry_flags(b);
+ BIO_copy_next_retry(b);
+ return(ret);
+ }
+
+static int linebuffer_write(BIO *b, const char *in, int inl)
+ {
+ int i,num=0,foundnl;
+ BIO_LINEBUFFER_CTX *ctx;
+
+ if ((in == NULL) || (inl <= 0)) return(0);
+ ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
+ if ((ctx == NULL) || (b->next_bio == NULL)) return(0);
+
+ BIO_clear_retry_flags(b);
+
+ do
+ {
+ const char *p;
+
+ for(p = in; p < in + inl && *p != '\n'; p++)
+ ;
+ if (*p == '\n')
+ {
+ p++;
+ foundnl = 1;
+ }
+ else
+ foundnl = 0;
+
+ /* If a NL was found and we already have text in the save
+ buffer, concatenate them and write */
+ while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len)
+ && ctx->obuf_len > 0)
+ {
+ int orig_olen = ctx->obuf_len;
+
+ i = ctx->obuf_size - ctx->obuf_len;
+ if (p - in > 0)
+ {
+ if (i >= p - in)
+ {
+ memcpy(&(ctx->obuf[ctx->obuf_len]),
+ in,p - in);
+ ctx->obuf_len += p - in;
+ inl -= p - in;
+ num += p - in;
+ in = p;
+ }
+ else
+ {
+ memcpy(&(ctx->obuf[ctx->obuf_len]),
+ in,i);
+ ctx->obuf_len += i;
+ inl -= i;
+ in += i;
+ num += i;
+ }
+ }
+
+#ifdef DEBUG
+BIO_write(b->next_bio, "<*<", 3);
+#endif
+ i=BIO_write(b->next_bio,
+ ctx->obuf, ctx->obuf_len);
+ if (i <= 0)
+ {
+ ctx->obuf_len = orig_olen;
+ BIO_copy_next_retry(b);
+
+#ifdef DEBUG
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+ if (i < 0) return((num > 0)?num:i);
+ if (i == 0) return(num);
+ }
+#ifdef DEBUG
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+ if (i < ctx->obuf_len)
+ memmove(ctx->obuf, ctx->obuf + i,
+ ctx->obuf_len - i);
+ ctx->obuf_len-=i;
+ }
+
+ /* Now that the save buffer is emptied, let's write the input
+ buffer if a NL was found and there is anything to write. */
+ if ((foundnl || p - in > ctx->obuf_size) && p - in > 0)
+ {
+#ifdef DEBUG
+BIO_write(b->next_bio, "<*<", 3);
+#endif
+ i=BIO_write(b->next_bio,in,p - in);
+ if (i <= 0)
+ {
+ BIO_copy_next_retry(b);
+#ifdef DEBUG
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+ if (i < 0) return((num > 0)?num:i);
+ if (i == 0) return(num);
+ }
+#ifdef DEBUG
+BIO_write(b->next_bio, ">*>", 3);
+#endif
+ num+=i;
+ in+=i;
+ inl-=i;
+ }
+ }
+ while(foundnl && inl > 0);
+ /* We've written as much as we can. The rest of the input buffer, if
+ any, is text that doesn't and with a NL and therefore needs to be
+ saved for the next trip. */
+ if (inl > 0)
+ {
+ memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl);
+ ctx->obuf_len += inl;
+ num += inl;
+ }
+ return num;
+ }
+
+static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+ BIO *dbio;
+ BIO_LINEBUFFER_CTX *ctx;
+ long ret=1;
+ char *p;
+ int r;
+ int obs;
+
+ ctx=(BIO_LINEBUFFER_CTX *)b->ptr;
+
+ switch (cmd)
+ {
+ case BIO_CTRL_RESET:
+ ctx->obuf_len=0;
+ if (b->next_bio == NULL) return(0);
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ break;
+ case BIO_CTRL_INFO:
+ ret=(long)ctx->obuf_len;
+ break;
+ case BIO_CTRL_WPENDING:
+ ret=(long)ctx->obuf_len;
+ if (ret == 0)
+ {
+ if (b->next_bio == NULL) return(0);
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ }
+ break;
+ case BIO_C_SET_BUFF_SIZE:
+ obs=(int)num;
+ p=ctx->obuf;
+ if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size))
+ {
+ p=(char *)OPENSSL_malloc((int)num);
+ if (p == NULL)
+ goto malloc_error;
+ }
+ if (ctx->obuf != p)
+ {
+ if (ctx->obuf_len > obs)
+ {
+ ctx->obuf_len = obs;
+ }
+ memcpy(p, ctx->obuf, ctx->obuf_len);
+ OPENSSL_free(ctx->obuf);
+ ctx->obuf=p;
+ ctx->obuf_size=obs;
+ }
+ break;
+ case BIO_C_DO_STATE_MACHINE:
+ if (b->next_bio == NULL) return(0);
+ BIO_clear_retry_flags(b);
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_FLUSH:
+ if (b->next_bio == NULL) return(0);
+ if (ctx->obuf_len <= 0)
+ {
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ break;
+ }
+
+ for (;;)
+ {
+ BIO_clear_retry_flags(b);
+ if (ctx->obuf_len > 0)
+ {
+ r=BIO_write(b->next_bio,
+ ctx->obuf, ctx->obuf_len);
+#if 0
+fprintf(stderr,"FLUSH %3d -> %3d\n",ctx->obuf_len,r);
+#endif
+ BIO_copy_next_retry(b);
+ if (r <= 0) return((long)r);
+ if (r < ctx->obuf_len)
+ memmove(ctx->obuf, ctx->obuf + r,
+ ctx->obuf_len - r);
+ ctx->obuf_len-=r;
+ }
+ else
+ {
+ ctx->obuf_len=0;
+ ret=1;
+ break;
+ }
+ }
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ break;
+ case BIO_CTRL_DUP:
+ dbio=(BIO *)ptr;
+ if ( !BIO_set_write_buffer_size(dbio,ctx->obuf_size))
+ ret=0;
+ break;
+ default:
+ if (b->next_bio == NULL) return(0);
+ ret=BIO_ctrl(b->next_bio,cmd,num,ptr);
+ break;
+ }
+ return(ret);
+malloc_error:
+ BIOerr(BIO_F_LINEBUFFER_CTRL,ERR_R_MALLOC_FAILURE);
+ return(0);
+ }
+
+static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
+ {
+ long ret=1;
+
+ if (b->next_bio == NULL) return(0);
+ switch (cmd)
+ {
+ default:
+ ret=BIO_callback_ctrl(b->next_bio,cmd,fp);
+ break;
+ }
+ return(ret);
+ }
+
+static int linebuffer_gets(BIO *b, char *buf, int size)
+ {
+ if (b->next_bio == NULL) return(0);
+ return(BIO_gets(b->next_bio,buf,size));
+ }
+
+static int linebuffer_puts(BIO *b, const char *str)
+ {
+ return(linebuffer_write(b,str,strlen(str)));
+ }
+
diff --git a/crypto/bio/bio.h b/crypto/bio/bio.h
index b7ab206777..97003b503c 100644
--- a/crypto/bio/bio.h
+++ b/crypto/bio/bio.h
@@ -91,6 +91,7 @@ extern "C" {
#define BIO_TYPE_NULL_FILTER (17|0x0200)
#define BIO_TYPE_BER (18|0x0200) /* BER -> bin filter */
#define BIO_TYPE_BIO (19|0x0400) /* (half a) BIO pair */
+#define BIO_TYPE_LINEBUFFER (20|0x0200) /* filter */
#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */
#define BIO_TYPE_FILTER 0x0200
@@ -554,6 +555,9 @@ BIO_METHOD *BIO_s_bio(void);
BIO_METHOD *BIO_s_null(void);
BIO_METHOD *BIO_f_null(void);
BIO_METHOD *BIO_f_buffer(void);
+#ifdef VMS
+BIO_METHOD *BIO_f_linebuffer(void);
+#endif
BIO_METHOD *BIO_f_nbio_test(void);
/* BIO_METHOD *BIO_f_ber(void); */
@@ -640,6 +644,7 @@ int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args);
#define BIO_F_CONN_CTRL 127
#define BIO_F_CONN_STATE 115
#define BIO_F_FILE_CTRL 116
+#define BIO_F_LINEBUFFER_CTRL 129
#define BIO_F_MEM_READ 128
#define BIO_F_MEM_WRITE 117
#define BIO_F_SSL_NEW 118
diff --git a/crypto/bio/bio_err.c b/crypto/bio/bio_err.c
index fb99195471..bb815fb1e6 100644
--- a/crypto/bio/bio_err.c
+++ b/crypto/bio/bio_err.c
@@ -91,6 +91,7 @@ static ERR_STRING_DATA BIO_str_functs[]=
{ERR_PACK(0,BIO_F_CONN_CTRL,0), "CONN_CTRL"},
{ERR_PACK(0,BIO_F_CONN_STATE,0), "CONN_STATE"},
{ERR_PACK(0,BIO_F_FILE_CTRL,0), "FILE_CTRL"},
+{ERR_PACK(0,BIO_F_LINEBUFFER_CTRL,0), "LINEBUFFER_CTRL"},
{ERR_PACK(0,BIO_F_MEM_READ,0), "MEM_READ"},
{ERR_PACK(0,BIO_F_MEM_WRITE,0), "MEM_WRITE"},
{ERR_PACK(0,BIO_F_SSL_NEW,0), "SSL_new"},
diff --git a/crypto/crypto-lib.com b/crypto/crypto-lib.com
index 73337b3d9a..edffeffde1 100644
--- a/crypto/crypto-lib.com
+++ b/crypto/crypto-lib.com
@@ -211,7 +211,8 @@ $ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
"bss_mem,bss_null,bss_fd,"+ -
"bss_file,bss_sock,bss_conn,"+ -
"bf_null,bf_buff,b_print,b_dump,"+ -
- "b_sock,bss_acpt,bf_nbio,bss_rtcp,bss_bio,bss_log"
+ "b_sock,bss_acpt,bf_nbio,bss_rtcp,bss_bio,bss_log,"+ -
+ "bf_lbuf"
$ LIB_STACK = "stack"
$ LIB_LHASH = "lhash,lh_stats"
$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,rand_win"
diff --git a/util/libeay.num b/util/libeay.num
index 842039bf76..3a72228d6a 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -1869,3 +1869,4 @@ RSA_PKCS1_RSAref 2459 EXIST:RSAREF:FUNCTION:RSA
X509_keyid_set1 2460 EXIST::FUNCTION:
BIO_next 2461 EXIST::FUNCTION:
DSO_METHOD_vms 2462 EXIST::FUNCTION:
+BIO_f_linebuffer 2463 EXIST:VMS:FUNCTION: