really fix race conditions

Submitted by: "Patrick McCormick" <patrick@tellme.com>

PR: 262
PR: 291
diff --git a/CHANGES b/CHANGES
index 1a312d9..2443971 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1931,7 +1931,9 @@
         SSLv23_client_method(),   SSLv23_server_method(),
         SSLv2_client_method(),    SSLv2_server_method(),
         SSLv3_client_method(),    SSLv3_server_method(),
-        TLSv1_client_method(),    TLSv1_server_method().
+        TLSv1_client_method(),    TLSv1_server_method(),
+        ssl2_get_cipher_by_char(),
+        ssl3_get_cipher_by_char().
      [Patrick McCormick <patrick@tellme.com>, Bodo Moeller]
 
   *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after
diff --git a/ssl/s23_clnt.c b/ssl/s23_clnt.c
index 9c02cb4..9923089 100644
--- a/ssl/s23_clnt.c
+++ b/ssl/s23_clnt.c
@@ -89,11 +89,14 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&SSLv23_client_data,
-			(char *)sslv23_base_method(),sizeof(SSL_METHOD));
-		SSLv23_client_data.ssl_connect=ssl23_connect;
-		SSLv23_client_data.get_ssl_method=ssl23_get_client_method;
-		init=0;
+		if (init)
+			{
+			memcpy((char *)&SSLv23_client_data,
+				(char *)sslv23_base_method(),sizeof(SSL_METHOD));
+			SSLv23_client_data.ssl_connect=ssl23_connect;
+			SSLv23_client_data.get_ssl_method=ssl23_get_client_method;
+			init=0;
+			}
 
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
index 5c7e9fa..442c95a 100644
--- a/ssl/s23_srvr.c
+++ b/ssl/s23_srvr.c
@@ -141,11 +141,14 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&SSLv23_server_data,
-			(char *)sslv23_base_method(),sizeof(SSL_METHOD));
-		SSLv23_server_data.ssl_accept=ssl23_accept;
-		SSLv23_server_data.get_ssl_method=ssl23_get_server_method;
-		init=0;
+		if (init)
+			{
+			memcpy((char *)&SSLv23_server_data,
+				(char *)sslv23_base_method(),sizeof(SSL_METHOD));
+			SSLv23_server_data.ssl_accept=ssl23_accept;
+			SSLv23_server_data.get_ssl_method=ssl23_get_server_method;
+			init=0;
+			}
 
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
diff --git a/ssl/s2_clnt.c b/ssl/s2_clnt.c
index 0d29039..be03e9c 100644
--- a/ssl/s2_clnt.c
+++ b/ssl/s2_clnt.c
@@ -147,11 +147,14 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&SSLv2_client_data,(char *)sslv2_base_method(),
-			sizeof(SSL_METHOD));
-		SSLv2_client_data.ssl_connect=ssl2_connect;
-		SSLv2_client_data.get_ssl_method=ssl2_get_client_method;
-		init=0;
+		if (init)
+			{
+			memcpy((char *)&SSLv2_client_data,(char *)sslv2_base_method(),
+				sizeof(SSL_METHOD));
+			SSLv2_client_data.ssl_connect=ssl2_connect;
+			SSLv2_client_data.get_ssl_method=ssl2_get_client_method;
+			init=0;
+			}
 
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
diff --git a/ssl/s2_lib.c b/ssl/s2_lib.c
index cc0dcfa..0cbbb06 100644
--- a/ssl/s2_lib.c
+++ b/ssl/s2_lib.c
@@ -377,15 +377,19 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL);
 
-		for (i=0; i<SSL2_NUM_CIPHERS; i++)
-			sorted[i]= &(ssl2_ciphers[i]);
+		if (init)
+			{
+			for (i=0; i<SSL2_NUM_CIPHERS; i++)
+				sorted[i]= &(ssl2_ciphers[i]);
 
-		qsort(  (char *)sorted,
-			SSL2_NUM_CIPHERS,sizeof(SSL_CIPHER *),
-			FP_ICC ssl_cipher_ptr_id_cmp);
+			qsort((char *)sorted,
+				SSL2_NUM_CIPHERS,sizeof(SSL_CIPHER *),
+				FP_ICC ssl_cipher_ptr_id_cmp);
 
+			init=0;
+			}
+			
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
-		init=0;
 		}
 
 	id=0x02000000L|((unsigned long)p[0]<<16L)|
diff --git a/ssl/s2_srvr.c b/ssl/s2_srvr.c
index d64d4e1..2efc14b 100644
--- a/ssl/s2_srvr.c
+++ b/ssl/s2_srvr.c
@@ -147,11 +147,14 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&SSLv2_server_data,(char *)sslv2_base_method(),
-			sizeof(SSL_METHOD));
-		SSLv2_server_data.ssl_accept=ssl2_accept;
-		SSLv2_server_data.get_ssl_method=ssl2_get_server_method;
-		init=0;
+		if (init)
+			{
+			memcpy((char *)&SSLv2_server_data,(char *)sslv2_base_method(),
+				sizeof(SSL_METHOD));
+			SSLv2_server_data.ssl_accept=ssl2_accept;
+			SSLv2_server_data.get_ssl_method=ssl2_get_server_method;
+			init=0;
+			}
 
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 6e29a6c..592e0b3 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -180,11 +180,14 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&SSLv3_client_data,(char *)sslv3_base_method(),
-			sizeof(SSL_METHOD));
-		SSLv3_client_data.ssl_connect=ssl3_connect;
-		SSLv3_client_data.get_ssl_method=ssl3_get_client_method;
-		init=0;
+		if (init)
+			{
+			memcpy((char *)&SSLv3_client_data,(char *)sslv3_base_method(),
+				sizeof(SSL_METHOD));
+			SSLv3_client_data.ssl_connect=ssl3_connect;
+			SSLv3_client_data.get_ssl_method=ssl3_get_client_method;
+			init=0;
+			}
 
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c
index 40730ca..afc81a2 100644
--- a/ssl/s3_lib.c
+++ b/ssl/s3_lib.c
@@ -1819,16 +1819,19 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL);
 
-		for (i=0; i<SSL3_NUM_CIPHERS; i++)
-			sorted[i]= &(ssl3_ciphers[i]);
+		if (init)
+			{
+			for (i=0; i<SSL3_NUM_CIPHERS; i++)
+				sorted[i]= &(ssl3_ciphers[i]);
 
-		qsort(	(char *)sorted,
-			SSL3_NUM_CIPHERS,sizeof(SSL_CIPHER *),
-			FP_ICC ssl_cipher_ptr_id_cmp);
+			qsort(sorted,
+				SSL3_NUM_CIPHERS,sizeof(SSL_CIPHER *),
+				FP_ICC ssl_cipher_ptr_id_cmp);
 
+			init=0;
+			}
+		
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL);
-
-		init=0;
 		}
 
 	id=0x03000000L|((unsigned long)p[0]<<8L)|(unsigned long)p[1];
diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c
index 7742f3b..98c950a 100644
--- a/ssl/s3_srvr.c
+++ b/ssl/s3_srvr.c
@@ -183,12 +183,15 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
-			sizeof(SSL_METHOD));
-		SSLv3_server_data.ssl_accept=ssl3_accept;
-		SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
-		init=0;
-
+		if (init)
+			{
+			memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
+				sizeof(SSL_METHOD));
+			SSLv3_server_data.ssl_accept=ssl3_accept;
+			SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
+			init=0;
+			}
+			
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&SSLv3_server_data);
diff --git a/ssl/t1_clnt.c b/ssl/t1_clnt.c
index 3eb3ae5..57205fb 100644
--- a/ssl/t1_clnt.c
+++ b/ssl/t1_clnt.c
@@ -81,12 +81,15 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&TLSv1_client_data,(char *)tlsv1_base_method(),
-			sizeof(SSL_METHOD));
-		TLSv1_client_data.ssl_connect=ssl3_connect;
-		TLSv1_client_data.get_ssl_method=tls1_get_client_method;
-		init=0;
-
+		if (init)
+			{
+			memcpy((char *)&TLSv1_client_data,(char *)tlsv1_base_method(),
+				sizeof(SSL_METHOD));
+			TLSv1_client_data.ssl_connect=ssl3_connect;
+			TLSv1_client_data.get_ssl_method=tls1_get_client_method;
+			init=0;
+			}
+		
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&TLSv1_client_data);
diff --git a/ssl/t1_srvr.c b/ssl/t1_srvr.c
index c72e552..1c1149e 100644
--- a/ssl/t1_srvr.c
+++ b/ssl/t1_srvr.c
@@ -82,12 +82,15 @@
 		{
 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
 
-		memcpy((char *)&TLSv1_server_data,(char *)tlsv1_base_method(),
-			sizeof(SSL_METHOD));
-		TLSv1_server_data.ssl_accept=ssl3_accept;
-		TLSv1_server_data.get_ssl_method=tls1_get_server_method;
-		init=0;
-
+		if (init)
+			{
+			memcpy((char *)&TLSv1_server_data,(char *)tlsv1_base_method(),
+				sizeof(SSL_METHOD));
+			TLSv1_server_data.ssl_accept=ssl3_accept;
+			TLSv1_server_data.get_ssl_method=tls1_get_server_method;
+			init=0;
+			}
+			
 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
 		}
 	return(&TLSv1_server_data);