Improve support for running everything as a monolithic application.

Submitted by: Lennart Bång, Bodo Möller
diff --git a/Configure b/Configure
index 4107d8a..f4fe84c 100755
--- a/Configure
+++ b/Configure
@@ -101,7 +101,7 @@
 "debug-ben-debug",	"gcc:-DBN_DEBUG -DREF_CHECK -DCRYPTO_MDEBUG -g3 -O2 -pedantic -Wall -Wshadow -Werror -pipe::(unknown):::::",
 "debug-ben-strict",	"gcc:-DBN_DEBUG -DREF_CHECK -DCRYPTO_MDEBUG -DCONST_STRICT -O2 -Wall -Wshadow -Werror -Wpointer-arith -Wcast-qual -Wwrite-strings -pipe::(unknown):::::",
 "debug-rse","cc:-DTERMIOS -DL_ENDIAN -pipe -O -g -ggdb3 -Wall::(unknown)::BN_LLONG $x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
-"debug-bodo",	"gcc:-DBIO_PAIR_DEBUG -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -g -m486 -Wall::-D_REENTRANT::BN_LLONG $x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
+"debug-bodo",	"gcc:-DBIO_PAIR_DEBUG -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -g -m486 -pedantic -Wshadow -Wall::-D_REENTRANT::BN_LLONG $x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
 "debug-ulf",	"gcc:-DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -DPEDANTIC -g -O2 -m486 -Wall  -pedantic -Wall -Wshadow -pipe::-D_REENTRANT::$x86_gcc_des $x86_gcc_opts:$x86_elf_asm",
 "dist",		"cc:-O::(unknown):::::",
 
diff --git a/TABLE b/TABLE
index 4a53987..2d86def 100644
--- a/TABLE
+++ b/TABLE
@@ -648,7 +648,7 @@
 
 *** debug-bodo
 $cc           = gcc
-$cflags       = -DBIO_PAIR_DEBUG -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -g -m486 -Wall
+$cflags       = -DBIO_PAIR_DEBUG -DL_ENDIAN -DREF_CHECK -DCRYPTO_MDEBUG_ALL -g -m486 -pedantic -Wshadow -Wall
 $unistd       = 
 $thread_cflag = -D_REENTRANT
 $lflags       = 
diff --git a/apps/ca.c b/apps/ca.c
index d12530a..8d33bc9 100644
--- a/apps/ca.c
+++ b/apps/ca.c
@@ -603,12 +603,14 @@
 			perror(outdir);
 			goto err;
 			}
+#ifdef S_IFDIR
 		if (!(sb.st_mode & S_IFDIR))
 			{
 			BIO_printf(bio_err,"%s need to be a directory\n",outdir);
 			perror(outdir);
 			goto err;
 			}
+#endif
 		}
 
 	/*****************************************************************/
@@ -1902,6 +1904,8 @@
 		X509_NAME_free(CAname);
 	if (subject != NULL)
 		X509_NAME_free(subject);
+	if (tmptm != NULL)
+		ASN1_UTCTIME_free(tmptm);
 	if (ok <= 0)
 		{
 		if (ret != NULL) X509_free(ret);
diff --git a/apps/x509.c b/apps/x509.c
index 70bd139..9d2a0c8 100644
--- a/apps/x509.c
+++ b/apps/x509.c
@@ -754,6 +754,7 @@
 	EVP_PKEY_free(CApkey);
 	X509_REQ_free(rq);
 	X509V3_EXT_cleanup();
+	X509_PURPOSE_cleanup();
 	EXIT(ret);
 	}
 
diff --git a/crypto/bf/bftest.c b/crypto/bf/bftest.c
index 6ecd260..5695250 100644
--- a/crypto/bf/bftest.c
+++ b/crypto/bf/bftest.c
@@ -76,18 +76,18 @@
 #include <openssl/ebcdic.h>
 #endif
 
-char *bf_key[2]={
+static char *bf_key[2]={
 	"abcdefghijklmnopqrstuvwxyz",
 	"Who is John Galt?"
 	};
 
 /* big endian */
-BF_LONG bf_plain[2][2]={
+static BF_LONG bf_plain[2][2]={
 	{0x424c4f57L,0x46495348L},
 	{0xfedcba98L,0x76543210L}
 	};
 
-BF_LONG bf_cipher[2][2]={
+static BF_LONG bf_cipher[2][2]={
 	{0x324ed0feL,0xf413a203L},
 	{0xcc91732bL,0x8022f684L}
 	};
@@ -228,16 +228,16 @@
 	0x63,0xC2,0xCF,0x80,0xDA};
 
 #define KEY_TEST_NUM	25
-unsigned char key_test[KEY_TEST_NUM]={
+static unsigned char key_test[KEY_TEST_NUM]={
 	0xf0,0xe1,0xd2,0xc3,0xb4,0xa5,0x96,0x87,
 	0x78,0x69,0x5a,0x4b,0x3c,0x2d,0x1e,0x0f,
 	0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
 	0x88};
 
-unsigned char key_data[8]=
+static unsigned char key_data[8]=
 	{0xFE,0xDC,0xBA,0x98,0x76,0x54,0x32,0x10};
 
-unsigned char key_out[KEY_TEST_NUM][8]={
+static unsigned char key_out[KEY_TEST_NUM][8]={
 	{0xF9,0xAD,0x59,0x7C,0x49,0xDB,0x00,0x5E},
 	{0xE9,0x1D,0x21,0xC1,0xD9,0x61,0xA6,0xD6},
 	{0xE9,0xC2,0xB7,0x0A,0x1B,0xC6,0x5C,0xF3},
diff --git a/crypto/bn/bntest.c b/crypto/bn/bntest.c
index df4b81f..652f679 100644
--- a/crypto/bn/bntest.c
+++ b/crypto/bn/bntest.c
@@ -104,6 +104,8 @@
 	BIO *out;
 	char *outfile=NULL;
 
+	results = 0;
+
 	argc--;
 	argv++;
 	while (argc >= 1)
@@ -207,6 +209,9 @@
 	if (!test_exp(out,ctx)) goto err;
 	fflush(stdout);
 
+	BN_CTX_free(ctx);
+	BIO_free(out);
+
 /**/
 	exit(0);
 err:
diff --git a/crypto/bn/exptest.c b/crypto/bn/exptest.c
index 9e4ae91..d64905d 100644
--- a/crypto/bn/exptest.c
+++ b/crypto/bn/exptest.c
@@ -160,7 +160,15 @@
 			exit(1);
 			}
 		}
+	BN_free(r_mont);
+	BN_free(r_recp);
+	BN_free(r_simple);
+	BN_free(a);
+	BN_free(b);
+	BN_free(m);
+	BN_CTX_free(ctx);
 	CRYPTO_mem_leaks(out);
+	BIO_free(out);
 	printf(" done\n");
 	exit(0);
 err:
diff --git a/crypto/cast/casttest.c b/crypto/cast/casttest.c
index 3244b11..ab2aeac 100644
--- a/crypto/cast/casttest.c
+++ b/crypto/cast/casttest.c
@@ -71,32 +71,32 @@
 
 #define FULL_TEST
 
-unsigned char k[16]={
+static unsigned char k[16]={
 	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
 	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A
 	};
 
-unsigned char in[8]={ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
+static unsigned char in[8]={ 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};
 
-int k_len[3]={16,10,5};
-unsigned char c[3][8]={
+static int k_len[3]={16,10,5};
+static unsigned char c[3][8]={
 	{0x23,0x8B,0x4F,0xE5,0x84,0x7E,0x44,0xB2},
 	{0xEB,0x6A,0x71,0x1A,0x2C,0x02,0x27,0x1B},
 	{0x7A,0xC8,0x16,0xD1,0x6E,0x9B,0x30,0x2E},
 	};
-unsigned char out[80];
+static unsigned char out[80];
 
-unsigned char in_a[16]={
+static unsigned char in_a[16]={
 	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
 	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
-unsigned char in_b[16]={
+static unsigned char in_b[16]={
 	0x01,0x23,0x45,0x67,0x12,0x34,0x56,0x78,
 	0x23,0x45,0x67,0x89,0x34,0x56,0x78,0x9A};
 
-unsigned char c_a[16]={
+static unsigned char c_a[16]={
 	0xEE,0xA9,0xD0,0xA2,0x49,0xFD,0x3B,0xA6,
 	0xB3,0x43,0x6F,0xB8,0x9D,0x6D,0xCA,0x92};
-unsigned char c_b[16]={
+static unsigned char c_b[16]={
 	0xB2,0xC9,0x5E,0xB0,0x0C,0x31,0xAD,0x71,
 	0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E};
 
diff --git a/crypto/des/destest.c b/crypto/des/destest.c
index 5a04fc9..69155ed 100644
--- a/crypto/des/destest.c
+++ b/crypto/des/destest.c
@@ -309,8 +309,8 @@
 	0x3d,0x6d,0x5b,0xe3,0x25,0x5a,0xf8,0xc3
 	};
 
-DES_LONG cbc_cksum_ret=0xB462FEF7L;
-unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
+static DES_LONG cbc_cksum_ret=0xB462FEF7L;
+static unsigned char cbc_cksum_data[8]={0x1D,0x26,0x93,0x97,0xf7,0xfe,0x62,0xb4};
 
 static char *pt(unsigned char *p);
 static int cfb_test(int bits, unsigned char *cfb_cipher);
diff --git a/crypto/dh/dhtest.c b/crypto/dh/dhtest.c
index 7703319..687ce71 100644
--- a/crypto/dh/dhtest.c
+++ b/crypto/dh/dhtest.c
@@ -87,14 +87,13 @@
 #include "bss_file.c"
 #endif
 
-BIO *out=NULL;
-
 int main(int argc, char *argv[])
 	{
 	DH *a,*b;
 	char buf[12];
 	unsigned char *abuf=NULL,*bbuf=NULL;
 	int i,alen,blen,aout,bout,ret=1;
+	BIO *out;
 
 #ifdef WIN32
 	CRYPTO_malloc_init();
@@ -167,6 +166,9 @@
 err:
 	if (abuf != NULL) Free(abuf);
 	if (bbuf != NULL) Free(bbuf);
+	if(b != NULL) DH_free(b);
+	if(a != NULL) DH_free(a);
+	BIO_free(out);
 	exit(ret);
 	return(ret);
 	}
diff --git a/crypto/dsa/dsatest.c b/crypto/dsa/dsatest.c
index fc25c9a..0137fcf 100644
--- a/crypto/dsa/dsatest.c
+++ b/crypto/dsa/dsatest.c
@@ -194,7 +194,11 @@
 		ERR_print_errors(bio_err);
 	if (dsa != NULL) DSA_free(dsa);
 	CRYPTO_mem_leaks(bio_err);
-	if (bio_err != NULL) BIO_free(bio_err);
+	if (bio_err != NULL)
+		{
+		BIO_free(bio_err);
+		bio_err = NULL;
+		}
 	exit(!ret);
 	return(0);
 	}
diff --git a/crypto/pkcs7/example.c b/crypto/pkcs7/example.c
index 7354890..244abf9 100644
--- a/crypto/pkcs7/example.c
+++ b/crypto/pkcs7/example.c
@@ -36,7 +36,7 @@
 		signed_string_nid=
 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
 	os=ASN1_OCTET_STRING_new();
-	ASN1_OCTET_STRING_set(os,str,strlen(str));
+	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
 	/* When we add, we do not free */
 	PKCS7_add_signed_attribute(si,signed_string_nid,
 		V_ASN1_OCTET_STRING,(char *)os);
@@ -86,8 +86,8 @@
 
 	os1=ASN1_OCTET_STRING_new();
 	os2=ASN1_OCTET_STRING_new();
-	ASN1_OCTET_STRING_set(os1,str1,strlen(str1));
-	ASN1_OCTET_STRING_set(os2,str1,strlen(str1));
+	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
+	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
 	i =i2d_ASN1_OCTET_STRING(os1,NULL);
 	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
 	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
@@ -197,7 +197,7 @@
 		signed_string_nid=
 			OBJ_create("1.2.3.4.5","OID_example","Our example OID");
 	os=ASN1_OCTET_STRING_new();
-	ASN1_OCTET_STRING_set(os,str,strlen(str));
+	ASN1_OCTET_STRING_set(os,(unsigned char*)str,strlen(str));
 	/* When we add, we do not free */
 	ret=X509_ATTRIBUTE_create(signed_string_nid,
 		V_ASN1_OCTET_STRING,(char *)os);
@@ -250,8 +250,8 @@
 
 	os1=ASN1_OCTET_STRING_new();
 	os2=ASN1_OCTET_STRING_new();
-	ASN1_OCTET_STRING_set(os1,str1,strlen(str1));
-	ASN1_OCTET_STRING_set(os2,str1,strlen(str1));
+	ASN1_OCTET_STRING_set(os1,(unsigned char*)str1,strlen(str1));
+	ASN1_OCTET_STRING_set(os2,(unsigned char*)str1,strlen(str1));
 	i =i2d_ASN1_OCTET_STRING(os1,NULL);
 	i+=i2d_ASN1_OCTET_STRING(os2,NULL);
 	total=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
diff --git a/crypto/rc2/rc2test.c b/crypto/rc2/rc2test.c
index 6a5defa..521269d 100644
--- a/crypto/rc2/rc2test.c
+++ b/crypto/rc2/rc2test.c
@@ -72,7 +72,7 @@
 #else
 #include <openssl/rc2.h>
 
-unsigned char RC2key[4][16]={
+static unsigned char RC2key[4][16]={
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
@@ -83,14 +83,14 @@
 	 0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F},
 	};
 
-unsigned char RC2plain[4][8]={
+static unsigned char RC2plain[4][8]={
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	};
 
-unsigned char RC2cipher[4][8]={
+static unsigned char RC2cipher[4][8]={
 	{0x1C,0x19,0x8A,0x83,0x8D,0xF0,0x28,0xB7},
 	{0x21,0x82,0x9C,0x78,0xA9,0xF9,0xC0,0x74},
 	{0x13,0xDB,0x35,0x17,0xD3,0x21,0x86,0x9E},
diff --git a/crypto/rc4/rc4test.c b/crypto/rc4/rc4test.c
index 5abf8cf..3914eb6 100644
--- a/crypto/rc4/rc4test.c
+++ b/crypto/rc4/rc4test.c
@@ -69,7 +69,7 @@
 #else
 #include <openssl/rc4.h>
 
-unsigned char keys[7][30]={
+static unsigned char keys[7][30]={
 	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
 	{8,0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef},
 	{8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
@@ -78,8 +78,8 @@
 	{4,0xef,0x01,0x23,0x45},
 	};
 
-unsigned char data_len[7]={8,8,8,20,28,10};
-unsigned char data[7][30]={
+static unsigned char data_len[7]={8,8,8,20,28,10};
+static unsigned char data[7][30]={
 	{0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xff},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff},
@@ -94,7 +94,7 @@
 	{0},
 	};
 
-unsigned char output[7][30]={
+static unsigned char output[7][30]={
 	{0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96,0x00},
 	{0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79,0x00},
 	{0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a,0x00},
diff --git a/crypto/rc5/rc5test.c b/crypto/rc5/rc5test.c
index d819284..634ceac 100644
--- a/crypto/rc5/rc5test.c
+++ b/crypto/rc5/rc5test.c
@@ -72,7 +72,7 @@
 #else
 #include <openssl/rc5.h>
 
-unsigned char RC5key[5][16]={
+static unsigned char RC5key[5][16]={
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0x91,0x5f,0x46,0x19,0xbe,0x41,0xb2,0x51,
@@ -85,7 +85,7 @@
 	 0x24,0x97,0x57,0x4d,0x7f,0x15,0x31,0x25},
 	};
 
-unsigned char RC5plain[5][8]={
+static unsigned char RC5plain[5][8]={
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0x21,0xA5,0xDB,0xEE,0x15,0x4B,0x8F,0x6D},
 	{0xF7,0xC0,0x13,0xAC,0x5B,0x2B,0x89,0x52},
@@ -93,7 +93,7 @@
 	{0x65,0xC1,0x78,0xB2,0x84,0xD1,0x97,0xCC},
 	};
 
-unsigned char RC5cipher[5][8]={
+static unsigned char RC5cipher[5][8]={
 	{0x21,0xA5,0xDB,0xEE,0x15,0x4B,0x8F,0x6D},
 	{0xF7,0xC0,0x13,0xAC,0x5B,0x2B,0x89,0x52},
 	{0x2F,0x42,0xB3,0xB7,0x03,0x69,0xFC,0x92},
@@ -102,7 +102,7 @@
 	};
 
 #define RC5_CBC_NUM 27
-unsigned char rc5_cbc_cipher[RC5_CBC_NUM][8]={
+static unsigned char rc5_cbc_cipher[RC5_CBC_NUM][8]={
 	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1e},
 	{0x79,0x7b,0xba,0x4d,0x78,0x11,0x1d,0x1e},
 	{0x7a,0x7b,0xba,0x4d,0x79,0x11,0x1d,0x1f},
@@ -132,7 +132,7 @@
 	{0x7f,0xd1,0xa0,0x23,0xa5,0xbb,0xa2,0x17},
 	};
 
-unsigned char rc5_cbc_key[RC5_CBC_NUM][17]={
+static unsigned char rc5_cbc_key[RC5_CBC_NUM][17]={
 	{ 1,0x00},
 	{ 1,0x00},
 	{ 1,0x00},
@@ -165,7 +165,7 @@
 	{ 5,0x01,0x02,0x03,0x04,0x05},
 	};
 
-unsigned char rc5_cbc_plain[RC5_CBC_NUM][8]={
+static unsigned char rc5_cbc_plain[RC5_CBC_NUM][8]={
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
@@ -195,14 +195,14 @@
 	{0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x01},
 	};
 
-int rc5_cbc_rounds[RC5_CBC_NUM]={
+static int rc5_cbc_rounds[RC5_CBC_NUM]={
 	 0, 0, 0, 0, 0, 1, 2, 2,
 	 8, 8,12,16, 8,12,16,12,
 	 8,12,16, 8,12,16,12, 8,
 	 8, 8, 8,
 	};
 
-unsigned char rc5_cbc_iv[RC5_CBC_NUM][8]={
+static unsigned char rc5_cbc_iv[RC5_CBC_NUM][8]={
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
 	{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01},
diff --git a/crypto/rsa/rsa_oaep_test.c b/crypto/rsa/rsa_oaep_test.c
index 0d4e39d..9405e88 100644
--- a/crypto/rsa/rsa_oaep_test.c
+++ b/crypto/rsa/rsa_oaep_test.c
@@ -203,7 +203,7 @@
     return(0);
 }
 
-int main() 
+int main(int argc, char *argv[])
     {
     int err=0;
     int v;
diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c
index 9c4706e..f2565e7 100644
--- a/crypto/x509v3/v3_purp.c
+++ b/crypto/x509v3/v3_purp.c
@@ -76,18 +76,18 @@
 static int xp_cmp(X509_PURPOSE **a, X509_PURPOSE **b);
 
 static X509_PURPOSE xstandard[] = {
-{1, check_purpose_ssl_client, "SSL client", NULL},
-{2, check_purpose_ssl_server, "SSL server", NULL},
-{3, check_purpose_ns_ssl_server, "Netscape SSL server", NULL},
-{4, check_purpose_smime_sign, "S/MIME signing", NULL},
-{5, check_purpose_smime_encrypt, "S/MIME encryption", NULL},
-{6, check_purpose_crl_sign, "CRL signing", NULL},
-{-1, NULL, NULL, NULL}
+	{1, 0, check_purpose_ssl_client, "SSL client", /* NULL */},
+	{2, 0, check_purpose_ssl_server, "SSL server", /* NULL */},
+	{3, 0, check_purpose_ns_ssl_server, "Netscape SSL server", /* NULL */},
+	{4, 0, check_purpose_smime_sign, "S/MIME signing", /* NULL */},
+	{5, 0, check_purpose_smime_encrypt, "S/MIME encryption", /* NULL */},
+	{6, 0, check_purpose_crl_sign, "CRL signing", /* NULL */},
+	{-1, 0, NULL, NULL, /* NULL */}
 };
 
 IMPLEMENT_STACK_OF(X509_PURPOSE)
 
-static STACK_OF(X509_PURPOSE) *xptable;
+static STACK_OF(X509_PURPOSE) *xptable = NULL;
 
 static int xp_cmp(X509_PURPOSE **a, X509_PURPOSE **b)
 {
@@ -123,13 +123,44 @@
 int X509_PURPOSE_add(X509_PURPOSE *xp)
 {
 	int idx;
-	if(!xptable) xptable = sk_X509_PURPOSE_new(xp_cmp);
+	if(!xptable)
+		{
+		xptable = sk_X509_PURPOSE_new(xp_cmp);
+		if (!xptable) 
+			{
+			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
+		}
+			
 	idx = x509_purpose_get_idx(xp->purpose_id);
-	if(idx != -1) sk_X509_PURPOSE_set(xptable, idx, xp);
-	else sk_X509_PURPOSE_push(xptable, xp);
+	if(idx != -1)
+		sk_X509_PURPOSE_set(xptable, idx, xp);
+	else
+		if (!sk_X509_PURPOSE_push(xptable, xp))
+			{
+			X509V3err(X509V3_F_X509_PURPOSE_ADD,ERR_R_MALLOC_FAILURE);
+			return 0;
+			}
 	return 1;
 }
 
+static void xptable_free(X509_PURPOSE *p)
+	{
+	if (p->purpose_flags & X509_PURPOSE_DYNAMIC) 
+		{
+		if (p->purpose_flags & X509_PURPOSE_DYNAMIC_NAME)
+			Free(p->purpose_name);
+		Free(p);
+		}
+	}
+
+void X509_PURPOSE_cleanup(void)
+{
+	sk_X509_PURPOSE_pop_free(xptable, xptable_free);
+	xptable = NULL;
+}
+
 void X509_PURPOSE_add_standard(void)
 {
 	X509_PURPOSE *xp;
diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c
index 50efa8d..6c233d2 100644
--- a/crypto/x509v3/v3err.c
+++ b/crypto/x509v3/v3err.c
@@ -102,6 +102,7 @@
 {ERR_PACK(0,X509V3_F_X509V3_EXT_I2D,0),	"X509V3_EXT_i2d"},
 {ERR_PACK(0,X509V3_F_X509V3_GET_VALUE_BOOL,0),	"X509V3_get_value_bool"},
 {ERR_PACK(0,X509V3_F_X509V3_PARSE_LIST,0),	"X509V3_parse_list"},
+{ERR_PACK(0,X509V3_F_X509_PURPOSE_ADD,0),	"X509_PURPOSE_add"},
 {0,NULL}
 	};
 
diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h
index 7915307..2e2756f 100644
--- a/crypto/x509v3/x509v3.h
+++ b/crypto/x509v3/x509v3.h
@@ -317,11 +317,15 @@
 #define XKU_CODE_SIGN		0x8
 #define XKU_SGC			0x10
 
+#define X509_PURPOSE_DYNAMIC	0x1
+#define X509_PURPOSE_DYNAMIC_NAME	0x2
+
 typedef struct x509_purpose_st {
-int purpose_id;
-int (*check_purpose)(struct x509_purpose_st *, X509 *, int);
-char *purpose_name;
-void *usr_data;
+	int purpose_id;
+	int purpose_flags;
+	int (*check_purpose)(struct x509_purpose_st *, X509 *, int);
+	char *purpose_name;
+	/* void *usr_data; */ /* if we enable this it needs a free function */
 } X509_PURPOSE;
 
 DECLARE_STACK_OF(X509_PURPOSE)
@@ -492,6 +496,7 @@
 
 int X509_check_purpose(X509 *x, int id, int ca);
 int X509_PURPOSE_add(X509_PURPOSE *xp);
+void X509_PURPOSE_cleanup(void);
 void X509_PURPOSE_add_standard(void);
 int X509_PURPOSE_enum(int (*efunc)(X509_PURPOSE *, void *), void *usr);
 int X509_PURPOSE_get_id(X509_PURPOSE *);
@@ -542,6 +547,7 @@
 #define X509V3_F_X509V3_EXT_I2D				 136
 #define X509V3_F_X509V3_GET_VALUE_BOOL			 110
 #define X509V3_F_X509V3_PARSE_LIST			 109
+#define X509V3_F_X509_PURPOSE_ADD			 137
 
 /* Reason codes. */
 #define X509V3_R_BAD_IP_ADDRESS				 118
diff --git a/ssl/ssltest.c b/ssl/ssltest.c
index 5c6508e..7d3c31d 100644
--- a/ssl/ssltest.c
+++ b/ssl/ssltest.c
@@ -97,8 +97,8 @@
 static BIO *bio_stdout=NULL;
 
 static char *cipher=NULL;
-int verbose=0;
-int debug=0;
+static int verbose=0;
+static int debug=0;
 #if 0
 /* Not used yet. */
 #ifdef FIONBIO
@@ -167,12 +167,15 @@
 #ifndef NO_DH
 	DH *dh;
 #endif
+	verbose = 0;
+	debug = 0;
+	cipher = 0;
+	
+	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
 
 	bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
 	bio_stdout=BIO_new_fp(stdout,BIO_NOCLOSE);
 
-	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
-
 	argc--;
 	argv++;
 
@@ -432,6 +435,7 @@
 	ERR_remove_state(0);
 	EVP_cleanup();
 	CRYPTO_mem_leaks(bio_err);
+	if (bio_err != NULL) BIO_free(bio_err);
 	EXIT(ret);
 	}
 
diff --git a/util/libeay.num b/util/libeay.num
index 6bdee9c..04d14ea 100755
--- a/util/libeay.num
+++ b/util/libeay.num
@@ -1992,3 +1992,4 @@
 EVP_PKEY_get_RSA                        2017
 EVP_PKEY_get_DH                         2018
 EVP_PKEY_get_DSA                        2019
+X509_PURPOSE_cleanup                    2020