int MAIN(int argc, char **argv)
	{
	int build_chain = 0;
	SSL *con=NULL;
#ifndef OPENSSL_NO_KRB5
	KSSL_CTX *kctx;
#endif
	int s,k,width,state=0;
	char *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;
	int cbuf_len,cbuf_off;
	int sbuf_len,sbuf_off;
	fd_set readfds,writefds;
	short port=PORT;
	int full_log=1;
	char *host=SSL_HOST_NAME;
	const char *unix_path = NULL;
	char *xmpphost = NULL;
	char *cert_file=NULL,*key_file=NULL,*chain_file=NULL;
	int cert_format = FORMAT_PEM, key_format = FORMAT_PEM;
	char *passarg = NULL, *pass = NULL;
	X509 *cert = NULL;
	EVP_PKEY *key = NULL;
	STACK_OF(X509) *chain = NULL;
	char *CApath=NULL,*CAfile=NULL;
	char *chCApath=NULL,*chCAfile=NULL;
	char *vfyCApath=NULL,*vfyCAfile=NULL;
	int reconnect=0,badop=0,verify=SSL_VERIFY_NONE;
	int crlf=0;
	int write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;
	SSL_CTX *ctx=NULL;
	int ret=1,in_init=1,i,nbio_test=0;
	int starttls_proto = PROTO_OFF;
	int prexit = 0;
	X509_VERIFY_PARAM *vpm = NULL;
	int badarg = 0;
	const SSL_METHOD *meth=NULL;
	int socket_type=SOCK_STREAM;
	BIO *sbio;
	char *inrand=NULL;
	int mbuf_len=0;
	struct timeval timeout, *timeoutp;
#ifndef OPENSSL_NO_ENGINE
	char *engine_id=NULL;
	char *ssl_client_engine_id=NULL;
	ENGINE *ssl_client_engine=NULL;
#endif
	ENGINE *e=NULL;
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
	struct timeval tv;
#if defined(OPENSSL_SYS_BEOS_R5)
	int stdin_set = 0;
#endif
#endif
#ifndef OPENSSL_NO_TLSEXT
	char *servername = NULL;
        tlsextctx tlsextcbp =
        {NULL,0};
# ifndef OPENSSL_NO_NEXTPROTONEG
	const char *next_proto_neg_in = NULL;
# endif
	const char *alpn_in = NULL;
# define MAX_SI_TYPES 100
	unsigned short serverinfo_types[MAX_SI_TYPES];
	int serverinfo_types_count = 0;
#endif
	char *sess_in = NULL;
	char *sess_out = NULL;
	struct sockaddr peer;
	int peerlen = sizeof(peer);
	int enable_timeouts = 0 ;
	long socket_mtu = 0;
#ifndef OPENSSL_NO_JPAKE
static char *jpake_secret = NULL;
#define no_jpake !jpake_secret
#else
#define no_jpake 1
#endif
#ifndef OPENSSL_NO_SRP
	char * srppass = NULL;
	int srp_lateuser = 0;
	SRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};
#endif
	SSL_EXCERT *exc = NULL;
	SSL_CONF_CTX *cctx = NULL;
	STACK_OF(OPENSSL_STRING) *ssl_args = NULL;
	char *crl_file = NULL;
	int crl_format = FORMAT_PEM;
	int crl_download = 0;
	STACK_OF(X509_CRL) *crls = NULL;
	int sdebug = 0;
	meth=SSLv23_client_method();
	apps_startup();
	c_Pause=0;
	c_quiet=0;
	c_ign_eof=0;
	c_debug=0;
	c_msg=0;
	c_showcerts=0;
	if (bio_err == NULL)
		bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);
	if (!load_config(bio_err, NULL))
		goto end;
	cctx = SSL_CONF_CTX_new();
	if (!cctx)
		goto end;
	SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);
	SSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE);
	if (	((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
		((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||
		((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))
		{
		BIO_printf(bio_err,"out of memory\n");
		goto end;
		}
	verify_depth=0;
	verify_error=X509_V_OK;
#ifdef FIONBIO
	c_nbio=0;
#endif
	argc--;
	argv++;
	while (argc >= 1)
		{
		if	(strcmp(*argv,"-host") == 0)
			{
			if (--argc < 1) goto bad;
			host= *(++argv);
			}
		else if	(strcmp(*argv,"-port") == 0)
			{
			if (--argc < 1) goto bad;
			port=atoi(*(++argv));
			if (port == 0) goto bad;
			}
		else if (strcmp(*argv,"-connect") == 0)
			{
			if (--argc < 1) goto bad;
			if (!extract_host_port(*(++argv),&host,NULL,&port))
				goto bad;
			}
		else if (strcmp(*argv,"-unix") == 0)
			{
			if (--argc < 1) goto bad;
			unix_path = *(++argv);
			}
		else if	(strcmp(*argv,"-xmpphost") == 0)
			{
			if (--argc < 1) goto bad;
			xmpphost= *(++argv);
			}
		else if	(strcmp(*argv,"-verify") == 0)
			{
			verify=SSL_VERIFY_PEER;
			if (--argc < 1) goto bad;
			verify_depth=atoi(*(++argv));
			if (!c_quiet)
				BIO_printf(bio_err,"verify depth is %d\n",verify_depth);
			}
		else if	(strcmp(*argv,"-cert") == 0)
			{
			if (--argc < 1) goto bad;
			cert_file= *(++argv);
			}
		else if	(strcmp(*argv,"-CRL") == 0)
			{
			if (--argc < 1) goto bad;
			crl_file= *(++argv);
			}
		else if	(strcmp(*argv,"-crl_download") == 0)
			crl_download = 1;
		else if	(strcmp(*argv,"-sess_out") == 0)
			{
			if (--argc < 1) goto bad;
			sess_out = *(++argv);
			}
		else if	(strcmp(*argv,"-sess_in") == 0)
			{
			if (--argc < 1) goto bad;
			sess_in = *(++argv);
			}
		else if	(strcmp(*argv,"-certform") == 0)
			{
			if (--argc < 1) goto bad;
			cert_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-CRLform") == 0)
			{
			if (--argc < 1) goto bad;
			crl_format = str2fmt(*(++argv));
			}
		else if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))
			{
			if (badarg)
				goto bad;
			continue;
			}
		else if (strcmp(*argv,"-verify_return_error") == 0)
			verify_return_error = 1;
		else if (strcmp(*argv,"-verify_quiet") == 0)
			verify_quiet = 1;
		else if (strcmp(*argv,"-brief") == 0)
			{
			c_brief = 1;
			verify_quiet = 1;
			c_quiet = 1;
			}
		else if (args_excert(&argv, &argc, &badarg, bio_err, &exc))
			{
			if (badarg)
				goto bad;
			continue;
			}
		else if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args))
			{
			if (badarg)
				goto bad;
			continue;
			}
		else if	(strcmp(*argv,"-prexit") == 0)
			prexit=1;
		else if	(strcmp(*argv,"-crlf") == 0)
			crlf=1;
		else if	(strcmp(*argv,"-quiet") == 0)
			{
			c_quiet=1;
			c_ign_eof=1;
			}
		else if	(strcmp(*argv,"-ign_eof") == 0)
			c_ign_eof=1;
		else if	(strcmp(*argv,"-no_ign_eof") == 0)
			c_ign_eof=0;
		else if	(strcmp(*argv,"-pause") == 0)
			c_Pause=1;
		else if	(strcmp(*argv,"-debug") == 0)
			c_debug=1;
#ifndef OPENSSL_NO_TLSEXT
		else if	(strcmp(*argv,"-tlsextdebug") == 0)
			c_tlsextdebug=1;
		else if	(strcmp(*argv,"-status") == 0)
			c_status_req=1;
#endif
#ifdef WATT32
		else if (strcmp(*argv,"-wdebug") == 0)
			dbug_init();
#endif
		else if	(strcmp(*argv,"-msg") == 0)
			c_msg=1;
		else if	(strcmp(*argv,"-msgfile") == 0)
			{
			if (--argc < 1) goto bad;
			bio_c_msg = BIO_new_file(*(++argv), "w");
			}
#ifndef OPENSSL_NO_SSL_TRACE
		else if	(strcmp(*argv,"-trace") == 0)
			c_msg=2;
#endif
		else if	(strcmp(*argv,"-security_debug") == 0)
			{ sdebug=1; }
		else if	(strcmp(*argv,"-security_debug_verbose") == 0)
			{ sdebug=2; }
		else if	(strcmp(*argv,"-showcerts") == 0)
			c_showcerts=1;
		else if	(strcmp(*argv,"-nbio_test") == 0)
			nbio_test=1;
		else if	(strcmp(*argv,"-state") == 0)
			state=1;
#ifndef OPENSSL_NO_PSK
                else if (strcmp(*argv,"-psk_identity") == 0)
			{
			if (--argc < 1) goto bad;
			psk_identity=*(++argv);
			}
                else if (strcmp(*argv,"-psk") == 0)
			{
                        size_t j;
			if (--argc < 1) goto bad;
			psk_key=*(++argv);
			for (j = 0; j < strlen(psk_key); j++)
                                {
                                if (isxdigit((unsigned char)psk_key[j]))
                                        continue;
                                BIO_printf(bio_err,"Not a hex number '%s'\n",*argv);
                                goto bad;
                                }
			}
#endif
#ifndef OPENSSL_NO_SRP
		else if (strcmp(*argv,"-srpuser") == 0)
			{
			if (--argc < 1) goto bad;
			srp_arg.srplogin= *(++argv);
			meth=TLSv1_client_method();
			}
		else if (strcmp(*argv,"-srppass") == 0)
			{
			if (--argc < 1) goto bad;
			srppass= *(++argv);
			meth=TLSv1_client_method();
			}
		else if (strcmp(*argv,"-srp_strength") == 0)
			{
			if (--argc < 1) goto bad;
			srp_arg.strength=atoi(*(++argv));
			BIO_printf(bio_err,"SRP minimal length for N is %d\n",srp_arg.strength);
			meth=TLSv1_client_method();
			}
		else if (strcmp(*argv,"-srp_lateuser") == 0)
			{
			srp_lateuser= 1;
			meth=TLSv1_client_method();
			}
		else if	(strcmp(*argv,"-srp_moregroups") == 0)
			{
			srp_arg.amp=1;
			meth=TLSv1_client_method();
			}
#endif
#ifndef OPENSSL_NO_SSL2
		else if	(strcmp(*argv,"-ssl2") == 0)
			meth=SSLv2_client_method();
#endif
#ifndef OPENSSL_NO_SSL3
		else if	(strcmp(*argv,"-ssl3") == 0)
			meth=SSLv3_client_method();
#endif
#ifndef OPENSSL_NO_TLS1
		else if	(strcmp(*argv,"-tls1_2") == 0)
			meth=TLSv1_2_client_method();
		else if	(strcmp(*argv,"-tls1_1") == 0)
			meth=TLSv1_1_client_method();
		else if	(strcmp(*argv,"-tls1") == 0)
			meth=TLSv1_client_method();
#endif
#ifndef OPENSSL_NO_DTLS1
		else if	(strcmp(*argv,"-dtls") == 0)
			{
			meth=DTLS_client_method();
			socket_type=SOCK_DGRAM;
			}
		else if	(strcmp(*argv,"-dtls1") == 0)
			{
			meth=DTLSv1_client_method();
			socket_type=SOCK_DGRAM;
			}
		else if	(strcmp(*argv,"-dtls1_2") == 0)
			{
			meth=DTLSv1_2_client_method();
			socket_type=SOCK_DGRAM;
			}
		else if (strcmp(*argv,"-timeout") == 0)
			enable_timeouts=1;
		else if (strcmp(*argv,"-mtu") == 0)
			{
			if (--argc < 1) goto bad;
			socket_mtu = atol(*(++argv));
			}
#endif
		else if	(strcmp(*argv,"-keyform") == 0)
			{
			if (--argc < 1) goto bad;
			key_format = str2fmt(*(++argv));
			}
		else if	(strcmp(*argv,"-pass") == 0)
			{
			if (--argc < 1) goto bad;
			passarg = *(++argv);
			}
		else if	(strcmp(*argv,"-cert_chain") == 0)
			{
			if (--argc < 1) goto bad;
			chain_file= *(++argv);
			}
		else if	(strcmp(*argv,"-key") == 0)
			{
			if (--argc < 1) goto bad;
			key_file= *(++argv);
			}
		else if	(strcmp(*argv,"-reconnect") == 0)
			{
			reconnect=5;
			}
		else if	(strcmp(*argv,"-CApath") == 0)
			{
			if (--argc < 1) goto bad;
			CApath= *(++argv);
			}
		else if	(strcmp(*argv,"-chainCApath") == 0)
			{
			if (--argc < 1) goto bad;
			chCApath= *(++argv);
			}
		else if	(strcmp(*argv,"-verifyCApath") == 0)
			{
			if (--argc < 1) goto bad;
			vfyCApath= *(++argv);
			}
		else if	(strcmp(*argv,"-build_chain") == 0)
			build_chain = 1;
		else if	(strcmp(*argv,"-CAfile") == 0)
			{
			if (--argc < 1) goto bad;
			CAfile= *(++argv);
			}
		else if	(strcmp(*argv,"-chainCAfile") == 0)
			{
			if (--argc < 1) goto bad;
			chCAfile= *(++argv);
			}
		else if	(strcmp(*argv,"-verifyCAfile") == 0)
			{
			if (--argc < 1) goto bad;
			vfyCAfile= *(++argv);
			}
#ifndef OPENSSL_NO_TLSEXT
# ifndef OPENSSL_NO_NEXTPROTONEG
		else if (strcmp(*argv,"-nextprotoneg") == 0)
			{
			if (--argc < 1) goto bad;
			next_proto_neg_in = *(++argv);
			}
# endif
		else if (strcmp(*argv,"-alpn") == 0)
			{
			if (--argc < 1) goto bad;
			alpn_in = *(++argv);
			}
		else if (strcmp(*argv,"-serverinfo") == 0)
			{
			char *c;
			int start = 0;
			int len;
			if (--argc < 1) goto bad;
			c = *(++argv);
			serverinfo_types_count = 0;
			len = strlen(c);
			for (i = 0; i <= len; ++i)
				{
				if (i == len || c[i] == ',')
					{
					serverinfo_types[serverinfo_types_count]
					    = atoi(c+start);
					serverinfo_types_count++;
					start = i+1;
					}
				if (serverinfo_types_count == MAX_SI_TYPES)
					break;
				}
			}
#endif
#ifdef FIONBIO
		else if (strcmp(*argv,"-nbio") == 0)
			{ c_nbio=1; }
#endif
		else if	(strcmp(*argv,"-starttls") == 0)
			{
			if (--argc < 1) goto bad;
			++argv;
			if (strcmp(*argv,"smtp") == 0)
				starttls_proto = PROTO_SMTP;
			else if (strcmp(*argv,"pop3") == 0)
				starttls_proto = PROTO_POP3;
			else if (strcmp(*argv,"imap") == 0)
				starttls_proto = PROTO_IMAP;
			else if (strcmp(*argv,"ftp") == 0)
				starttls_proto = PROTO_FTP;
			else if (strcmp(*argv, "xmpp") == 0)
				starttls_proto = PROTO_XMPP;
			else
				goto bad;
			}
#ifndef OPENSSL_NO_ENGINE
		else if	(strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine_id = *(++argv);
			}
		else if	(strcmp(*argv,"-ssl_client_engine") == 0)
			{
			if (--argc < 1) goto bad;
			ssl_client_engine_id = *(++argv);
			}
#endif
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) goto bad;
			inrand= *(++argv);
			}
#ifndef OPENSSL_NO_TLSEXT
		else if (strcmp(*argv,"-servername") == 0)
			{
			if (--argc < 1) goto bad;
			servername= *(++argv);
			}
#endif
#ifndef OPENSSL_NO_JPAKE
		else if (strcmp(*argv,"-jpake") == 0)
			{
			if (--argc < 1) goto bad;
			jpake_secret = *++argv;
			}
#endif
		else if (strcmp(*argv,"-use_srtp") == 0)
			{
			if (--argc < 1) goto bad;
			srtp_profiles = *(++argv);
			}
		else if (strcmp(*argv,"-keymatexport") == 0)
			{
			if (--argc < 1) goto bad;
			keymatexportlabel= *(++argv);
			}
		else if (strcmp(*argv,"-keymatexportlen") == 0)
			{
			if (--argc < 1) goto bad;
			keymatexportlen=atoi(*(++argv));
			if (keymatexportlen == 0) goto bad;
			}
                else
			{
			BIO_printf(bio_err,"unknown option %s\n",*argv);
			badop=1;
			break;
			}
		argc--;
		argv++;
		}
	if (badop)
		{
bad:
		sc_usage();
		goto end;
		}
	if (unix_path && (socket_type != SOCK_STREAM))
		{
		BIO_printf(bio_err, "Can't use unix sockets and datagrams together\n");
			goto end;
		}
#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)
	if (jpake_secret)
		{
		if (psk_key)
			{
			BIO_printf(bio_err,
				   "Can't use JPAKE and PSK together\n");
			goto end;
			}
		psk_identity = "JPAKE";
		}
#endif
	OpenSSL_add_ssl_algorithms();
	SSL_load_error_strings();
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
	next_proto.status = -1;
	if (next_proto_neg_in)
		{
		next_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);
		if (next_proto.data == NULL)
			{
			BIO_printf(bio_err, "Error parsing -nextprotoneg argument\n");
			goto end;
			}
		}
	else
		next_proto.data = NULL;
#endif
#ifndef OPENSSL_NO_ENGINE
        e = setup_engine(bio_err, engine_id, 1);
	if (ssl_client_engine_id)
		{
		ssl_client_engine = ENGINE_by_id(ssl_client_engine_id);
		if (!ssl_client_engine)
			{
			BIO_printf(bio_err,
					"Error getting client auth engine\n");
			goto end;
			}
		}
#endif
	if (!app_passwd(bio_err, passarg, NULL, &pass, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}
	if (key_file == NULL)
		key_file = cert_file;
	if (key_file)
		{
		key = load_key(bio_err, key_file, key_format, 0, pass, e,
			       "client certificate private key file");
		if (!key)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	if (cert_file)
		{
		cert = load_cert(bio_err,cert_file,cert_format,
				NULL, e, "client certificate file");
		if (!cert)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}
	if (chain_file)
		{
		chain = load_certs(bio_err, chain_file,FORMAT_PEM,
					NULL, e, "client certificate chain");
		if (!chain)
			goto end;
		}
	if (crl_file)
		{
		X509_CRL *crl;
		crl = load_crl(crl_file, crl_format);
		if (!crl)
			{
			BIO_puts(bio_err, "Error loading CRL\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		crls = sk_X509_CRL_new_null();
		if (!crls || !sk_X509_CRL_push(crls, crl))
			{
			BIO_puts(bio_err, "Error adding CRL\n");
			ERR_print_errors(bio_err);
			X509_CRL_free(crl);
			goto end;
			}
		}
	if (!load_excert(&exc, bio_err))
		goto end;
	if (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL
		&& !RAND_status())
		{
		BIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\n");
		}
	if (inrand != NULL)
		BIO_printf(bio_err,"%ld semi-random bytes loaded\n",
			app_RAND_load_files(inrand));
	if (bio_c_out == NULL)
		{
		if (c_quiet && !c_debug)
			{
			bio_c_out=BIO_new(BIO_s_null());
			if (c_msg && !bio_c_msg)
				bio_c_msg=BIO_new_fp(stdout,BIO_NOCLOSE);
			}
		else
			{
			if (bio_c_out == NULL)
				bio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);
			}
		}
#ifndef OPENSSL_NO_SRP
	if(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))
		{
		BIO_printf(bio_err, "Error getting password\n");
		goto end;
		}
#endif
	ctx=SSL_CTX_new(meth);
	if (ctx == NULL)
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	if (sdebug)
		ssl_ctx_security_debug(ctx, bio_err, sdebug);
	if (vpm)
		SSL_CTX_set1_param(ctx, vpm);
	if (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1, no_jpake))
		{
		ERR_print_errors(bio_err);
		goto end;
		}
	if (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,
						crls, crl_download))
		{
		BIO_printf(bio_err, "Error loading store locations\n");
		ERR_print_errors(bio_err);
		goto end;
		}
#ifndef OPENSSL_NO_ENGINE
	if (ssl_client_engine)
		{
		if (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))
			{
			BIO_puts(bio_err, "Error setting client auth engine\n");
			ERR_print_errors(bio_err);
			ENGINE_free(ssl_client_engine);
			goto end;
			}
		ENGINE_free(ssl_client_engine);
		}
#endif
#ifndef OPENSSL_NO_PSK
#ifdef OPENSSL_NO_JPAKE
	if (psk_key != NULL)
#else
	if (psk_key != NULL || jpake_secret)
#endif
		{
		if (c_debug)
			BIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\n");
		SSL_CTX_set_psk_client_callback(ctx, psk_client_cb);
		}
	if (srtp_profiles != NULL)
		SSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);
#endif
	if (exc) ssl_ctx_set_excert(ctx, exc);
	if (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);
#if !defined(OPENSSL_NO_TLSEXT)
# if !defined(OPENSSL_NO_NEXTPROTONEG)
	if (next_proto.data)
		SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);
# endif
	if (alpn_in)
		{
		unsigned short alpn_len;
		unsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);
		if (alpn == NULL)
			{
			BIO_printf(bio_err, "Error parsing -alpn argument\n");
			goto end;
			}
		SSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);
		OPENSSL_free(alpn);
		}
#endif
#ifndef OPENSSL_NO_TLSEXT
		for (i = 0; i < serverinfo_types_count; i++)
			{
			SSL_CTX_add_client_custom_ext(ctx,
						      serverinfo_types[i],
						      NULL, NULL, NULL,
						      serverinfo_cli_parse_cb,
						      NULL);
			}
#endif
	if (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);
#if 0
	else
		SSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));
#endif
	SSL_CTX_set_verify(ctx,verify,verify_callback);
	if ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||
		(!SSL_CTX_set_default_verify_paths(ctx)))
		{
		ERR_print_errors(bio_err);
		}
	ssl_ctx_add_crls(ctx, crls, crl_download);
	if (!set_cert_key_stuff(ctx,cert,key,chain,build_chain))
		goto end;
#ifndef OPENSSL_NO_TLSEXT
	if (servername != NULL)
		{
		tlsextcbp.biodebug = bio_err;
		SSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);
		SSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);
		}
#ifndef OPENSSL_NO_SRP
        if (srp_arg.srplogin)
		{
		if (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))
			{
			BIO_printf(bio_err,"Unable to set SRP username\n");
			goto end;
			}
		srp_arg.msg = c_msg;
		srp_arg.debug = c_debug ;
		SSL_CTX_set_srp_cb_arg(ctx,&srp_arg);
		SSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);
		SSL_CTX_set_srp_strength(ctx, srp_arg.strength);
		if (c_msg || c_debug || srp_arg.amp == 0)
			SSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);
		}
#endif
#endif
	con=SSL_new(ctx);
	if (sess_in)
		{
		SSL_SESSION *sess;
		BIO *stmp = BIO_new_file(sess_in, "r");
		if (!stmp)
			{
			BIO_printf(bio_err, "Can't open session file %s\n",
						sess_in);
			ERR_print_errors(bio_err);
			goto end;
			}
		sess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);
		BIO_free(stmp);
		if (!sess)
			{
			BIO_printf(bio_err, "Can't open session file %s\n",
						sess_in);
			ERR_print_errors(bio_err);
			goto end;
			}
		SSL_set_session(con, sess);
		SSL_SESSION_free(sess);
		}
#ifndef OPENSSL_NO_TLSEXT
	if (servername != NULL)
		{
		if (!SSL_set_tlsext_host_name(con,servername))
			{
			BIO_printf(bio_err,"Unable to set TLS servername extension.\n");
			ERR_print_errors(bio_err);
			goto end;
			}
		}
#endif
#ifndef OPENSSL_NO_KRB5
	if (con  &&  (kctx = kssl_ctx_new()) != NULL)
                {
		SSL_set0_kssl_ctx(con, kctx);
                kssl_ctx_setstring(kctx, KSSL_SERVER, host);
		}
#endif
#if 0
#ifdef TLSEXT_TYPE_opaque_prf_input
	SSL_set_tlsext_opaque_prf_input(con, "Test client", 11);
#endif
#endif
re_start:
#ifdef NO_SYS_UN_H
	if (init_client(&s,host,port,socket_type) == 0)
#else
	if ((!unix_path && (init_client(&s,host,port,socket_type) == 0)) ||
			(unix_path && (init_client_unix(&s,unix_path) == 0)))
#endif
		{
		BIO_printf(bio_err,"connect:errno=%d\n",get_last_socket_error());
		SHUTDOWN(s);
		goto end;
		}
	BIO_printf(bio_c_out,"CONNECTED(%08X)\n",s);
#ifdef FIONBIO
	if (c_nbio)
		{
		unsigned long l=1;
		BIO_printf(bio_c_out,"turning on non blocking io\n");
		if (BIO_socket_ioctl(s,FIONBIO,&l) < 0)
			{
			ERR_print_errors(bio_err);
			goto end;
			}
		}
#endif
	if (c_Pause & 0x01) SSL_set_debug(con, 1);
	if (socket_type == SOCK_DGRAM)
		{
		sbio=BIO_new_dgram(s,BIO_NOCLOSE);
		if (getsockname(s, &peer, (void *)&peerlen) < 0)
			{
			BIO_printf(bio_err, "getsockname:errno=%d\n",
				get_last_socket_error());
			SHUTDOWN(s);
			goto end;
			}
		(void)BIO_ctrl_set_connected(sbio, 1, &peer);
		if (enable_timeouts)
			{
			timeout.tv_sec = 0;
			timeout.tv_usec = DGRAM_RCV_TIMEOUT;
			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);
			timeout.tv_sec = 0;
			timeout.tv_usec = DGRAM_SND_TIMEOUT;
			BIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);
			}
		if (socket_mtu > 28)
			{
			SSL_set_options(con, SSL_OP_NO_QUERY_MTU);
			SSL_set_mtu(con, socket_mtu - 28);
			}
		else
			BIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);
		}
	else
		sbio=BIO_new_socket(s,BIO_NOCLOSE);
	if (nbio_test)
		{
		BIO *test;
		test=BIO_new(BIO_f_nbio_test());
		sbio=BIO_push(test,sbio);
		}
	if (c_debug)
		{
		SSL_set_debug(con, 1);
		BIO_set_callback(sbio,bio_dump_callback);
		BIO_set_callback_arg(sbio,(char *)bio_c_out);
		}
	if (c_msg)
		{
#ifndef OPENSSL_NO_SSL_TRACE
		if (c_msg == 2)
			SSL_set_msg_callback(con, SSL_trace);
		else
#endif
			SSL_set_msg_callback(con, msg_cb);
		SSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out);
		}
#ifndef OPENSSL_NO_TLSEXT
	if (c_tlsextdebug)
		{
		SSL_set_tlsext_debug_callback(con, tlsext_cb);
		SSL_set_tlsext_debug_arg(con, bio_c_out);
		}
	if (c_status_req)
		{
		SSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);
		SSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);
		SSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);
#if 0
{
STACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();
OCSP_RESPID *id = OCSP_RESPID_new();
id->value.byKey = ASN1_OCTET_STRING_new();
id->type = V_OCSP_RESPID_KEY;
ASN1_STRING_set(id->value.byKey, "Hello World", -1);
sk_OCSP_RESPID_push(ids, id);
SSL_set_tlsext_status_ids(con, ids);
}
#endif
		}
#endif
#ifndef OPENSSL_NO_JPAKE
	if (jpake_secret)
		jpake_client_auth(bio_c_out, sbio, jpake_secret);
#endif
	SSL_set_bio(con,sbio,sbio);
	SSL_set_connect_state(con);
	width=SSL_get_fd(con)+1;
	read_tty=1;
	write_tty=0;
	tty_on=0;
	read_ssl=1;
	write_ssl=1;
	cbuf_len=0;
	cbuf_off=0;
	sbuf_len=0;
	sbuf_off=0;
	if (starttls_proto == PROTO_SMTP)
		{
		int foundit=0;
		BIO *fbio = BIO_new(BIO_f_buffer());
		BIO_push(fbio, sbio);
		do
			{
			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
			}
		while (mbuf_len>3 && mbuf[3]=='-');
		BIO_printf(fbio,"EHLO openssl.client.net\r\n");
		(void)BIO_flush(fbio);
		do
			{
			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
			if (strstr(mbuf,"STARTTLS"))
				foundit=1;
			}
		while (mbuf_len>3 && mbuf[3]=='-');
		(void)BIO_flush(fbio);
		BIO_pop(fbio);
		BIO_free(fbio);
		if (!foundit)
			BIO_printf(bio_err,
				   "didn't found starttls in server response,"
				   " try anyway...\n");
		BIO_printf(sbio,"STARTTLS\r\n");
		BIO_read(sbio,sbuf,BUFSIZZ);
		}
	else if (starttls_proto == PROTO_POP3)
		{
		BIO_read(sbio,mbuf,BUFSIZZ);
		BIO_printf(sbio,"STLS\r\n");
		BIO_read(sbio,sbuf,BUFSIZZ);
		}
	else if (starttls_proto == PROTO_IMAP)
		{
		int foundit=0;
		BIO *fbio = BIO_new(BIO_f_buffer());
		BIO_push(fbio, sbio);
		BIO_gets(fbio,mbuf,BUFSIZZ);
		BIO_printf(fbio,". CAPABILITY\r\n");
		(void)BIO_flush(fbio);
		do
			{
			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
			if (strstr(mbuf,"STARTTLS"))
				foundit=1;
			}
		while (mbuf_len>3 && mbuf[0]!='.');
		(void)BIO_flush(fbio);
		BIO_pop(fbio);
		BIO_free(fbio);
		if (!foundit)
			BIO_printf(bio_err,
				   "didn't found STARTTLS in server response,"
				   " try anyway...\n");
		BIO_printf(sbio,". STARTTLS\r\n");
		BIO_read(sbio,sbuf,BUFSIZZ);
		}
	else if (starttls_proto == PROTO_FTP)
		{
		BIO *fbio = BIO_new(BIO_f_buffer());
		BIO_push(fbio, sbio);
		do
			{
			mbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);
			}
		while (mbuf_len>3 && mbuf[3]=='-');
		(void)BIO_flush(fbio);
		BIO_pop(fbio);
		BIO_free(fbio);
		BIO_printf(sbio,"AUTH TLS\r\n");
		BIO_read(sbio,sbuf,BUFSIZZ);
		}
	if (starttls_proto == PROTO_XMPP)
		{
		int seen = 0;
		BIO_printf(sbio,"<stream:stream "
		    "xmlns:stream='http://etherx.jabber.org/streams' "
		    "xmlns='jabber:client' to='%s' version='1.0'>", xmpphost ?
			   xmpphost : host);
		seen = BIO_read(sbio,mbuf,BUFSIZZ);
		mbuf[seen] = 0;
		while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") &&
				!strstr(mbuf, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\""))
			{
			seen = BIO_read(sbio,mbuf,BUFSIZZ);
			if (seen <= 0)
				goto shut;
			mbuf[seen] = 0;
			}
		BIO_printf(sbio, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
		seen = BIO_read(sbio,sbuf,BUFSIZZ);
		sbuf[seen] = 0;
		if (!strstr(sbuf, "<proceed"))
			goto shut;
		mbuf[0] = 0;
		}
	for (;;)
		{
		FD_ZERO(&readfds);
		FD_ZERO(&writefds);
		if ((SSL_version(con) == DTLS1_VERSION) &&
			DTLSv1_get_timeout(con, &timeout))
			timeoutp = &timeout;
		else
			timeoutp = NULL;
		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
			{
			in_init=1;
			tty_on=0;
			}
		else
			{
			tty_on=1;
			if (in_init)
				{
				in_init=0;
#if 0
#ifndef OPENSSL_NO_TLSEXT
				if (servername != NULL && !SSL_session_reused(con))
					{
					BIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\n",tlsextcbp.ack?"":"not ");
					}
#endif
#endif
				if (sess_out)
					{
					BIO *stmp = BIO_new_file(sess_out, "w");
					if (stmp)
						{
						PEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));
						BIO_free(stmp);
						}
					else
						BIO_printf(bio_err, "Error writing session file %s\n", sess_out);
					}
				if (c_brief)
					{
					BIO_puts(bio_err,
						"CONNECTION ESTABLISHED\n");
					print_ssl_summary(bio_err, con);
					}
				print_stuff(bio_c_out,con,full_log);
				if (full_log > 0) full_log--;
				if (starttls_proto)
					{
					BIO_printf(bio_err,"%s",mbuf);
					starttls_proto = PROTO_OFF;
					}
				if (reconnect)
					{
					reconnect--;
					BIO_printf(bio_c_out,"drop connection and then reconnect\n");
					SSL_shutdown(con);
					SSL_set_connect_state(con);
					SHUTDOWN(SSL_get_fd(con));
					goto re_start;
					}
				}
			}
		ssl_pending = read_ssl && SSL_pending(con);
		if (!ssl_pending)
			{
#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)
			if (tty_on)
				{
				if (read_tty)  openssl_fdset(fileno(stdin),&readfds);
				if (write_tty) openssl_fdset(fileno(stdout),&writefds);
				}
			if (read_ssl)
				openssl_fdset(SSL_get_fd(con),&readfds);
			if (write_ssl)
				openssl_fdset(SSL_get_fd(con),&writefds);
#else
			if(!tty_on || !write_tty) {
				if (read_ssl)
					openssl_fdset(SSL_get_fd(con),&readfds);
				if (write_ssl)
					openssl_fdset(SSL_get_fd(con),&writefds);
			}
#endif
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
			i=0;
			if(!write_tty) {
				if(read_tty) {
					tv.tv_sec = 1;
					tv.tv_usec = 0;
					i=select(width,(void *)&readfds,(void *)&writefds,
						 NULL,&tv);
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
					if(!i && (!_kbhit() || !read_tty) ) continue;
#else
					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
#endif
				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
					 NULL,timeoutp);
			}
#elif defined(OPENSSL_SYS_NETWARE)
			if(!write_tty) {
				if(read_tty) {
					tv.tv_sec = 1;
					tv.tv_usec = 0;
					i=select(width,(void *)&readfds,(void *)&writefds,
						NULL,&tv);
				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
					NULL,timeoutp);
			}
#elif defined(OPENSSL_SYS_BEOS_R5)
			i=0;
			stdin_set = 0;
			(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);
			if(!write_tty) {
				if(read_tty) {
					tv.tv_sec = 1;
					tv.tv_usec = 0;
					i=select(width,(void *)&readfds,(void *)&writefds,
						 NULL,&tv);
					if (read(fileno(stdin), sbuf, 0) >= 0)
						stdin_set = 1;
					if (!i && (stdin_set != 1 || !read_tty))
						continue;
				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
					 NULL,timeoutp);
			}
			(void)fcntl(fileno(stdin), F_SETFL, 0);
#else
			i=select(width,(void *)&readfds,(void *)&writefds,
				 NULL,timeoutp);
#endif
			if ( i < 0)
				{
				BIO_printf(bio_err,"bad select %d\n",
				get_last_socket_error());
				goto shut;
				}
			}
		if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
			{
			BIO_printf(bio_err,"TIMEOUT occurred\n");
			}
		if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
			{
			k=SSL_write(con,&(cbuf[cbuf_off]),
				(unsigned int)cbuf_len);
			switch (SSL_get_error(con,k))
				{
			case SSL_ERROR_NONE:
				cbuf_off+=k;
				cbuf_len-=k;
				if (k <= 0) goto end;
				if (cbuf_len <= 0)
					{
					read_tty=1;
					write_ssl=0;
					}
				else
					{
					read_tty=0;
					write_ssl=1;
					}
				break;
			case SSL_ERROR_WANT_WRITE:
				BIO_printf(bio_c_out,"write W BLOCK\n");
				write_ssl=1;
				read_tty=0;
				break;
			case SSL_ERROR_WANT_READ:
				BIO_printf(bio_c_out,"write R BLOCK\n");
				write_tty=0;
				read_ssl=1;
				write_ssl=0;
				break;
			case SSL_ERROR_WANT_X509_LOOKUP:
				BIO_printf(bio_c_out,"write X BLOCK\n");
				break;
			case SSL_ERROR_ZERO_RETURN:
				if (cbuf_len != 0)
					{
					BIO_printf(bio_c_out,"shutdown\n");
					ret = 0;
					goto shut;
					}
				else
					{
					read_tty=1;
					write_ssl=0;
					break;
					}
			case SSL_ERROR_SYSCALL:
				if ((k != 0) || (cbuf_len != 0))
					{
					BIO_printf(bio_err,"write:errno=%d\n",
						get_last_socket_error());
					goto shut;
					}
				else
					{
					read_tty=1;
					write_ssl=0;
					}
				break;
			case SSL_ERROR_SSL:
				ERR_print_errors(bio_err);
				goto shut;
				}
			}
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
		else if (!ssl_pending && write_tty)
#else
		else if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))
#endif
			{
#ifdef CHARSET_EBCDIC
			ascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);
#endif
			i=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);
			if (i <= 0)
				{
				BIO_printf(bio_c_out,"DONE\n");
				ret = 0;
				goto shut;
				}
			sbuf_len-=i;;
			sbuf_off+=i;
			if (sbuf_len <= 0)
				{
				read_ssl=1;
				write_tty=0;
				}
			}
		else if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))
			{
#ifdef RENEG
{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }
#endif
#if 1
			k=SSL_read(con,sbuf,1024   );
#else
			k=SSL_read(con,sbuf,16);
{ char zbuf[10240];
printf("read=%d pending=%d peek=%d\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));
}
#endif
			switch (SSL_get_error(con,k))
				{
			case SSL_ERROR_NONE:
				if (k <= 0)
					goto end;
				sbuf_off=0;
				sbuf_len=k;
				read_ssl=0;
				write_tty=1;
				break;
			case SSL_ERROR_WANT_WRITE:
				BIO_printf(bio_c_out,"read W BLOCK\n");
				write_ssl=1;
				read_tty=0;
				break;
			case SSL_ERROR_WANT_READ:
				BIO_printf(bio_c_out,"read R BLOCK\n");
				write_tty=0;
				read_ssl=1;
				if ((read_tty == 0) && (write_ssl == 0))
					write_ssl=1;
				break;
			case SSL_ERROR_WANT_X509_LOOKUP:
				BIO_printf(bio_c_out,"read X BLOCK\n");
				break;
			case SSL_ERROR_SYSCALL:
				ret=get_last_socket_error();
				if (c_brief)
					BIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\n");
				else
					BIO_printf(bio_err,"read:errno=%d\n",ret);
				goto shut;
			case SSL_ERROR_ZERO_RETURN:
				BIO_printf(bio_c_out,"closed\n");
				ret=0;
				goto shut;
			case SSL_ERROR_SSL:
				ERR_print_errors(bio_err);
				goto shut;
				}
			}
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)
#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)
		else if (_kbhit())
#else
		else if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))
#endif
#elif defined (OPENSSL_SYS_NETWARE)
		else if (_kbhit())
#elif defined(OPENSSL_SYS_BEOS_R5)
		else if (stdin_set)
#else
		else if (FD_ISSET(fileno(stdin),&readfds))
#endif
			{
			if (crlf)
				{
				int j, lf_num;
				i=raw_read_stdin(cbuf,BUFSIZZ/2);
				lf_num = 0;
				for (j = 0; j < i; j++)
					if (cbuf[j] == '\n')
						lf_num++;
				for (j = i-1; j >= 0; j--)
					{
					cbuf[j+lf_num] = cbuf[j];
					if (cbuf[j] == '\n')
						{
						lf_num--;
						i++;
						cbuf[j+lf_num] = '\r';
						}
					}
				assert(lf_num == 0);
				}
			else
				i=raw_read_stdin(cbuf,BUFSIZZ);
			if ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == 'Q')))
				{
				BIO_printf(bio_err,"DONE\n");
				ret=0;
				goto shut;
				}
			if ((!c_ign_eof) && (cbuf[0] == 'R'))
				{
				BIO_printf(bio_err,"RENEGOTIATING\n");
				SSL_renegotiate(con);
				cbuf_len=0;
				}
#ifndef OPENSSL_NO_HEARTBEATS
			else if ((!c_ign_eof) && (cbuf[0] == 'B'))
 				{
				BIO_printf(bio_err,"HEARTBEATING\n");
				SSL_heartbeat(con);
				cbuf_len=0;
				}
#endif
			else
				{
				cbuf_len=i;
				cbuf_off=0;
#ifdef CHARSET_EBCDIC
				ebcdic2ascii(cbuf, cbuf, i);
#endif
				}
			write_ssl=1;
			read_tty=0;
			}
		}
	ret=0;
shut:
	if (in_init)
		print_stuff(bio_c_out,con,full_log);
	SSL_shutdown(con);
	SHUTDOWN(SSL_get_fd(con));
end:
	if (con != NULL)
		{
		if (prexit != 0)
			print_stuff(bio_c_out,con,1);
		SSL_free(con);
		}
#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
	if (next_proto.data)
		OPENSSL_free(next_proto.data);
#endif
	if (ctx != NULL) SSL_CTX_free(ctx);
	if (cert)
		X509_free(cert);
	if (crls)
		sk_X509_CRL_pop_free(crls, X509_CRL_free);
	if (key)
		EVP_PKEY_free(key);
	if (chain)
		sk_X509_pop_free(chain, X509_free);
	if (pass)
		OPENSSL_free(pass);
	if (vpm)
		X509_VERIFY_PARAM_free(vpm);
	ssl_excert_free(exc);
	if (ssl_args)
		sk_OPENSSL_STRING_free(ssl_args);
	if (cctx)
		SSL_CONF_CTX_free(cctx);
#ifndef OPENSSL_NO_JPAKE
	if (jpake_secret && psk_key)
		OPENSSL_free(psk_key);
#endif
	if (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }
	if (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }
	if (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }
	if (bio_c_out != NULL)
		{
		BIO_free(bio_c_out);
		bio_c_out=NULL;
		}
	if (bio_c_msg != NULL)
		{
		BIO_free(bio_c_msg);
		bio_c_msg=NULL;
		}
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
['int MAIN(int argc, char **argv)\n\t{\n\tint build_chain = 0;\n\tSSL *con=NULL;\n#ifndef OPENSSL_NO_KRB5\n\tKSSL_CTX *kctx;\n#endif\n\tint s,k,width,state=0;\n\tchar *cbuf=NULL,*sbuf=NULL,*mbuf=NULL;\n\tint cbuf_len,cbuf_off;\n\tint sbuf_len,sbuf_off;\n\tfd_set readfds,writefds;\n\tshort port=PORT;\n\tint full_log=1;\n\tchar *host=SSL_HOST_NAME;\n\tconst char *unix_path = NULL;\n\tchar *xmpphost = NULL;\n\tchar *cert_file=NULL,*key_file=NULL,*chain_file=NULL;\n\tint cert_format = FORMAT_PEM, key_format = FORMAT_PEM;\n\tchar *passarg = NULL, *pass = NULL;\n\tX509 *cert = NULL;\n\tEVP_PKEY *key = NULL;\n\tSTACK_OF(X509) *chain = NULL;\n\tchar *CApath=NULL,*CAfile=NULL;\n\tchar *chCApath=NULL,*chCAfile=NULL;\n\tchar *vfyCApath=NULL,*vfyCAfile=NULL;\n\tint reconnect=0,badop=0,verify=SSL_VERIFY_NONE;\n\tint crlf=0;\n\tint write_tty,read_tty,write_ssl,read_ssl,tty_on,ssl_pending;\n\tSSL_CTX *ctx=NULL;\n\tint ret=1,in_init=1,i,nbio_test=0;\n\tint starttls_proto = PROTO_OFF;\n\tint prexit = 0;\n\tX509_VERIFY_PARAM *vpm = NULL;\n\tint badarg = 0;\n\tconst SSL_METHOD *meth=NULL;\n\tint socket_type=SOCK_STREAM;\n\tBIO *sbio;\n\tchar *inrand=NULL;\n\tint mbuf_len=0;\n\tstruct timeval timeout, *timeoutp;\n#ifndef OPENSSL_NO_ENGINE\n\tchar *engine_id=NULL;\n\tchar *ssl_client_engine_id=NULL;\n\tENGINE *ssl_client_engine=NULL;\n#endif\n\tENGINE *e=NULL;\n#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)\n\tstruct timeval tv;\n#if defined(OPENSSL_SYS_BEOS_R5)\n\tint stdin_set = 0;\n#endif\n#endif\n#ifndef OPENSSL_NO_TLSEXT\n\tchar *servername = NULL;\n        tlsextctx tlsextcbp =\n        {NULL,0};\n# ifndef OPENSSL_NO_NEXTPROTONEG\n\tconst char *next_proto_neg_in = NULL;\n# endif\n\tconst char *alpn_in = NULL;\n# define MAX_SI_TYPES 100\n\tunsigned short serverinfo_types[MAX_SI_TYPES];\n\tint serverinfo_types_count = 0;\n#endif\n\tchar *sess_in = NULL;\n\tchar *sess_out = NULL;\n\tstruct sockaddr peer;\n\tint peerlen = sizeof(peer);\n\tint enable_timeouts = 0 ;\n\tlong socket_mtu = 0;\n#ifndef OPENSSL_NO_JPAKE\nstatic char *jpake_secret = NULL;\n#define no_jpake !jpake_secret\n#else\n#define no_jpake 1\n#endif\n#ifndef OPENSSL_NO_SRP\n\tchar * srppass = NULL;\n\tint srp_lateuser = 0;\n\tSRP_ARG srp_arg = {NULL,NULL,0,0,0,1024};\n#endif\n\tSSL_EXCERT *exc = NULL;\n\tSSL_CONF_CTX *cctx = NULL;\n\tSTACK_OF(OPENSSL_STRING) *ssl_args = NULL;\n\tchar *crl_file = NULL;\n\tint crl_format = FORMAT_PEM;\n\tint crl_download = 0;\n\tSTACK_OF(X509_CRL) *crls = NULL;\n\tint sdebug = 0;\n\tmeth=SSLv23_client_method();\n\tapps_startup();\n\tc_Pause=0;\n\tc_quiet=0;\n\tc_ign_eof=0;\n\tc_debug=0;\n\tc_msg=0;\n\tc_showcerts=0;\n\tif (bio_err == NULL)\n\t\tbio_err=BIO_new_fp(stderr,BIO_NOCLOSE);\n\tif (!load_config(bio_err, NULL))\n\t\tgoto end;\n\tcctx = SSL_CONF_CTX_new();\n\tif (!cctx)\n\t\tgoto end;\n\tSSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CLIENT);\n\tSSL_CONF_CTX_set_flags(cctx, SSL_CONF_FLAG_CMDLINE);\n\tif (\t((cbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||\n\t\t((sbuf=OPENSSL_malloc(BUFSIZZ)) == NULL) ||\n\t\t((mbuf=OPENSSL_malloc(BUFSIZZ)) == NULL))\n\t\t{\n\t\tBIO_printf(bio_err,"out of memory\\n");\n\t\tgoto end;\n\t\t}\n\tverify_depth=0;\n\tverify_error=X509_V_OK;\n#ifdef FIONBIO\n\tc_nbio=0;\n#endif\n\targc--;\n\targv++;\n\twhile (argc >= 1)\n\t\t{\n\t\tif\t(strcmp(*argv,"-host") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\thost= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-port") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tport=atoi(*(++argv));\n\t\t\tif (port == 0) goto bad;\n\t\t\t}\n\t\telse if (strcmp(*argv,"-connect") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tif (!extract_host_port(*(++argv),&host,NULL,&port))\n\t\t\t\tgoto bad;\n\t\t\t}\n\t\telse if (strcmp(*argv,"-unix") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tunix_path = *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-xmpphost") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\txmpphost= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-verify") == 0)\n\t\t\t{\n\t\t\tverify=SSL_VERIFY_PEER;\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tverify_depth=atoi(*(++argv));\n\t\t\tif (!c_quiet)\n\t\t\t\tBIO_printf(bio_err,"verify depth is %d\\n",verify_depth);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-cert") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tcert_file= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-CRL") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tcrl_file= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-crl_download") == 0)\n\t\t\tcrl_download = 1;\n\t\telse if\t(strcmp(*argv,"-sess_out") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsess_out = *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-sess_in") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsess_in = *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-certform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tcert_format = str2fmt(*(++argv));\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-CRLform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tcrl_format = str2fmt(*(++argv));\n\t\t\t}\n\t\telse if (args_verify(&argv, &argc, &badarg, bio_err, &vpm))\n\t\t\t{\n\t\t\tif (badarg)\n\t\t\t\tgoto bad;\n\t\t\tcontinue;\n\t\t\t}\n\t\telse if (strcmp(*argv,"-verify_return_error") == 0)\n\t\t\tverify_return_error = 1;\n\t\telse if (strcmp(*argv,"-verify_quiet") == 0)\n\t\t\tverify_quiet = 1;\n\t\telse if (strcmp(*argv,"-brief") == 0)\n\t\t\t{\n\t\t\tc_brief = 1;\n\t\t\tverify_quiet = 1;\n\t\t\tc_quiet = 1;\n\t\t\t}\n\t\telse if (args_excert(&argv, &argc, &badarg, bio_err, &exc))\n\t\t\t{\n\t\t\tif (badarg)\n\t\t\t\tgoto bad;\n\t\t\tcontinue;\n\t\t\t}\n\t\telse if (args_ssl(&argv, &argc, cctx, &badarg, bio_err, &ssl_args))\n\t\t\t{\n\t\t\tif (badarg)\n\t\t\t\tgoto bad;\n\t\t\tcontinue;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-prexit") == 0)\n\t\t\tprexit=1;\n\t\telse if\t(strcmp(*argv,"-crlf") == 0)\n\t\t\tcrlf=1;\n\t\telse if\t(strcmp(*argv,"-quiet") == 0)\n\t\t\t{\n\t\t\tc_quiet=1;\n\t\t\tc_ign_eof=1;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-ign_eof") == 0)\n\t\t\tc_ign_eof=1;\n\t\telse if\t(strcmp(*argv,"-no_ign_eof") == 0)\n\t\t\tc_ign_eof=0;\n\t\telse if\t(strcmp(*argv,"-pause") == 0)\n\t\t\tc_Pause=1;\n\t\telse if\t(strcmp(*argv,"-debug") == 0)\n\t\t\tc_debug=1;\n#ifndef OPENSSL_NO_TLSEXT\n\t\telse if\t(strcmp(*argv,"-tlsextdebug") == 0)\n\t\t\tc_tlsextdebug=1;\n\t\telse if\t(strcmp(*argv,"-status") == 0)\n\t\t\tc_status_req=1;\n#endif\n#ifdef WATT32\n\t\telse if (strcmp(*argv,"-wdebug") == 0)\n\t\t\tdbug_init();\n#endif\n\t\telse if\t(strcmp(*argv,"-msg") == 0)\n\t\t\tc_msg=1;\n\t\telse if\t(strcmp(*argv,"-msgfile") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tbio_c_msg = BIO_new_file(*(++argv), "w");\n\t\t\t}\n#ifndef OPENSSL_NO_SSL_TRACE\n\t\telse if\t(strcmp(*argv,"-trace") == 0)\n\t\t\tc_msg=2;\n#endif\n\t\telse if\t(strcmp(*argv,"-security_debug") == 0)\n\t\t\t{ sdebug=1; }\n\t\telse if\t(strcmp(*argv,"-security_debug_verbose") == 0)\n\t\t\t{ sdebug=2; }\n\t\telse if\t(strcmp(*argv,"-showcerts") == 0)\n\t\t\tc_showcerts=1;\n\t\telse if\t(strcmp(*argv,"-nbio_test") == 0)\n\t\t\tnbio_test=1;\n\t\telse if\t(strcmp(*argv,"-state") == 0)\n\t\t\tstate=1;\n#ifndef OPENSSL_NO_PSK\n                else if (strcmp(*argv,"-psk_identity") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tpsk_identity=*(++argv);\n\t\t\t}\n                else if (strcmp(*argv,"-psk") == 0)\n\t\t\t{\n                        size_t j;\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tpsk_key=*(++argv);\n\t\t\tfor (j = 0; j < strlen(psk_key); j++)\n                                {\n                                if (isxdigit((unsigned char)psk_key[j]))\n                                        continue;\n                                BIO_printf(bio_err,"Not a hex number \'%s\'\\n",*argv);\n                                goto bad;\n                                }\n\t\t\t}\n#endif\n#ifndef OPENSSL_NO_SRP\n\t\telse if (strcmp(*argv,"-srpuser") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsrp_arg.srplogin= *(++argv);\n\t\t\tmeth=TLSv1_client_method();\n\t\t\t}\n\t\telse if (strcmp(*argv,"-srppass") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsrppass= *(++argv);\n\t\t\tmeth=TLSv1_client_method();\n\t\t\t}\n\t\telse if (strcmp(*argv,"-srp_strength") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsrp_arg.strength=atoi(*(++argv));\n\t\t\tBIO_printf(bio_err,"SRP minimal length for N is %d\\n",srp_arg.strength);\n\t\t\tmeth=TLSv1_client_method();\n\t\t\t}\n\t\telse if (strcmp(*argv,"-srp_lateuser") == 0)\n\t\t\t{\n\t\t\tsrp_lateuser= 1;\n\t\t\tmeth=TLSv1_client_method();\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-srp_moregroups") == 0)\n\t\t\t{\n\t\t\tsrp_arg.amp=1;\n\t\t\tmeth=TLSv1_client_method();\n\t\t\t}\n#endif\n#ifndef OPENSSL_NO_SSL2\n\t\telse if\t(strcmp(*argv,"-ssl2") == 0)\n\t\t\tmeth=SSLv2_client_method();\n#endif\n#ifndef OPENSSL_NO_SSL3\n\t\telse if\t(strcmp(*argv,"-ssl3") == 0)\n\t\t\tmeth=SSLv3_client_method();\n#endif\n#ifndef OPENSSL_NO_TLS1\n\t\telse if\t(strcmp(*argv,"-tls1_2") == 0)\n\t\t\tmeth=TLSv1_2_client_method();\n\t\telse if\t(strcmp(*argv,"-tls1_1") == 0)\n\t\t\tmeth=TLSv1_1_client_method();\n\t\telse if\t(strcmp(*argv,"-tls1") == 0)\n\t\t\tmeth=TLSv1_client_method();\n#endif\n#ifndef OPENSSL_NO_DTLS1\n\t\telse if\t(strcmp(*argv,"-dtls") == 0)\n\t\t\t{\n\t\t\tmeth=DTLS_client_method();\n\t\t\tsocket_type=SOCK_DGRAM;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-dtls1") == 0)\n\t\t\t{\n\t\t\tmeth=DTLSv1_client_method();\n\t\t\tsocket_type=SOCK_DGRAM;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-dtls1_2") == 0)\n\t\t\t{\n\t\t\tmeth=DTLSv1_2_client_method();\n\t\t\tsocket_type=SOCK_DGRAM;\n\t\t\t}\n\t\telse if (strcmp(*argv,"-timeout") == 0)\n\t\t\tenable_timeouts=1;\n\t\telse if (strcmp(*argv,"-mtu") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsocket_mtu = atol(*(++argv));\n\t\t\t}\n#endif\n\t\telse if\t(strcmp(*argv,"-keyform") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tkey_format = str2fmt(*(++argv));\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-pass") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tpassarg = *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-cert_chain") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tchain_file= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-key") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tkey_file= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-reconnect") == 0)\n\t\t\t{\n\t\t\treconnect=5;\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-CApath") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tCApath= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-chainCApath") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tchCApath= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-verifyCApath") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tvfyCApath= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-build_chain") == 0)\n\t\t\tbuild_chain = 1;\n\t\telse if\t(strcmp(*argv,"-CAfile") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tCAfile= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-chainCAfile") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tchCAfile= *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-verifyCAfile") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tvfyCAfile= *(++argv);\n\t\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n# ifndef OPENSSL_NO_NEXTPROTONEG\n\t\telse if (strcmp(*argv,"-nextprotoneg") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tnext_proto_neg_in = *(++argv);\n\t\t\t}\n# endif\n\t\telse if (strcmp(*argv,"-alpn") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\talpn_in = *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-serverinfo") == 0)\n\t\t\t{\n\t\t\tchar *c;\n\t\t\tint start = 0;\n\t\t\tint len;\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tc = *(++argv);\n\t\t\tserverinfo_types_count = 0;\n\t\t\tlen = strlen(c);\n\t\t\tfor (i = 0; i <= len; ++i)\n\t\t\t\t{\n\t\t\t\tif (i == len || c[i] == \',\')\n\t\t\t\t\t{\n\t\t\t\t\tserverinfo_types[serverinfo_types_count]\n\t\t\t\t\t    = atoi(c+start);\n\t\t\t\t\tserverinfo_types_count++;\n\t\t\t\t\tstart = i+1;\n\t\t\t\t\t}\n\t\t\t\tif (serverinfo_types_count == MAX_SI_TYPES)\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n#endif\n#ifdef FIONBIO\n\t\telse if (strcmp(*argv,"-nbio") == 0)\n\t\t\t{ c_nbio=1; }\n#endif\n\t\telse if\t(strcmp(*argv,"-starttls") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\t++argv;\n\t\t\tif (strcmp(*argv,"smtp") == 0)\n\t\t\t\tstarttls_proto = PROTO_SMTP;\n\t\t\telse if (strcmp(*argv,"pop3") == 0)\n\t\t\t\tstarttls_proto = PROTO_POP3;\n\t\t\telse if (strcmp(*argv,"imap") == 0)\n\t\t\t\tstarttls_proto = PROTO_IMAP;\n\t\t\telse if (strcmp(*argv,"ftp") == 0)\n\t\t\t\tstarttls_proto = PROTO_FTP;\n\t\t\telse if (strcmp(*argv, "xmpp") == 0)\n\t\t\t\tstarttls_proto = PROTO_XMPP;\n\t\t\telse\n\t\t\t\tgoto bad;\n\t\t\t}\n#ifndef OPENSSL_NO_ENGINE\n\t\telse if\t(strcmp(*argv,"-engine") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tengine_id = *(++argv);\n\t\t\t}\n\t\telse if\t(strcmp(*argv,"-ssl_client_engine") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tssl_client_engine_id = *(++argv);\n\t\t\t}\n#endif\n\t\telse if (strcmp(*argv,"-rand") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tinrand= *(++argv);\n\t\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n\t\telse if (strcmp(*argv,"-servername") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tservername= *(++argv);\n\t\t\t}\n#endif\n#ifndef OPENSSL_NO_JPAKE\n\t\telse if (strcmp(*argv,"-jpake") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tjpake_secret = *++argv;\n\t\t\t}\n#endif\n\t\telse if (strcmp(*argv,"-use_srtp") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tsrtp_profiles = *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-keymatexport") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tkeymatexportlabel= *(++argv);\n\t\t\t}\n\t\telse if (strcmp(*argv,"-keymatexportlen") == 0)\n\t\t\t{\n\t\t\tif (--argc < 1) goto bad;\n\t\t\tkeymatexportlen=atoi(*(++argv));\n\t\t\tif (keymatexportlen == 0) goto bad;\n\t\t\t}\n                else\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"unknown option %s\\n",*argv);\n\t\t\tbadop=1;\n\t\t\tbreak;\n\t\t\t}\n\t\targc--;\n\t\targv++;\n\t\t}\n\tif (badop)\n\t\t{\nbad:\n\t\tsc_usage();\n\t\tgoto end;\n\t\t}\n\tif (unix_path && (socket_type != SOCK_STREAM))\n\t\t{\n\t\tBIO_printf(bio_err, "Can\'t use unix sockets and datagrams together\\n");\n\t\t\tgoto end;\n\t\t}\n#if !defined(OPENSSL_NO_JPAKE) && !defined(OPENSSL_NO_PSK)\n\tif (jpake_secret)\n\t\t{\n\t\tif (psk_key)\n\t\t\t{\n\t\t\tBIO_printf(bio_err,\n\t\t\t\t   "Can\'t use JPAKE and PSK together\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\tpsk_identity = "JPAKE";\n\t\t}\n#endif\n\tOpenSSL_add_ssl_algorithms();\n\tSSL_load_error_strings();\n#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)\n\tnext_proto.status = -1;\n\tif (next_proto_neg_in)\n\t\t{\n\t\tnext_proto.data = next_protos_parse(&next_proto.len, next_proto_neg_in);\n\t\tif (next_proto.data == NULL)\n\t\t\t{\n\t\t\tBIO_printf(bio_err, "Error parsing -nextprotoneg argument\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\telse\n\t\tnext_proto.data = NULL;\n#endif\n#ifndef OPENSSL_NO_ENGINE\n        e = setup_engine(bio_err, engine_id, 1);\n\tif (ssl_client_engine_id)\n\t\t{\n\t\tssl_client_engine = ENGINE_by_id(ssl_client_engine_id);\n\t\tif (!ssl_client_engine)\n\t\t\t{\n\t\t\tBIO_printf(bio_err,\n\t\t\t\t\t"Error getting client auth engine\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n#endif\n\tif (!app_passwd(bio_err, passarg, NULL, &pass, NULL))\n\t\t{\n\t\tBIO_printf(bio_err, "Error getting password\\n");\n\t\tgoto end;\n\t\t}\n\tif (key_file == NULL)\n\t\tkey_file = cert_file;\n\tif (key_file)\n\t\t{\n\t\tkey = load_key(bio_err, key_file, key_format, 0, pass, e,\n\t\t\t       "client certificate private key file");\n\t\tif (!key)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (cert_file)\n\t\t{\n\t\tcert = load_cert(bio_err,cert_file,cert_format,\n\t\t\t\tNULL, e, "client certificate file");\n\t\tif (!cert)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (chain_file)\n\t\t{\n\t\tchain = load_certs(bio_err, chain_file,FORMAT_PEM,\n\t\t\t\t\tNULL, e, "client certificate chain");\n\t\tif (!chain)\n\t\t\tgoto end;\n\t\t}\n\tif (crl_file)\n\t\t{\n\t\tX509_CRL *crl;\n\t\tcrl = load_crl(crl_file, crl_format);\n\t\tif (!crl)\n\t\t\t{\n\t\t\tBIO_puts(bio_err, "Error loading CRL\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\tcrls = sk_X509_CRL_new_null();\n\t\tif (!crls || !sk_X509_CRL_push(crls, crl))\n\t\t\t{\n\t\t\tBIO_puts(bio_err, "Error adding CRL\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tX509_CRL_free(crl);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n\tif (!load_excert(&exc, bio_err))\n\t\tgoto end;\n\tif (!app_RAND_load_file(NULL, bio_err, 1) && inrand == NULL\n\t\t&& !RAND_status())\n\t\t{\n\t\tBIO_printf(bio_err,"warning, not much extra random data, consider using the -rand option\\n");\n\t\t}\n\tif (inrand != NULL)\n\t\tBIO_printf(bio_err,"%ld semi-random bytes loaded\\n",\n\t\t\tapp_RAND_load_files(inrand));\n\tif (bio_c_out == NULL)\n\t\t{\n\t\tif (c_quiet && !c_debug)\n\t\t\t{\n\t\t\tbio_c_out=BIO_new(BIO_s_null());\n\t\t\tif (c_msg && !bio_c_msg)\n\t\t\t\tbio_c_msg=BIO_new_fp(stdout,BIO_NOCLOSE);\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tif (bio_c_out == NULL)\n\t\t\t\tbio_c_out=BIO_new_fp(stdout,BIO_NOCLOSE);\n\t\t\t}\n\t\t}\n#ifndef OPENSSL_NO_SRP\n\tif(!app_passwd(bio_err, srppass, NULL, &srp_arg.srppassin, NULL))\n\t\t{\n\t\tBIO_printf(bio_err, "Error getting password\\n");\n\t\tgoto end;\n\t\t}\n#endif\n\tctx=SSL_CTX_new(meth);\n\tif (ctx == NULL)\n\t\t{\n\t\tERR_print_errors(bio_err);\n\t\tgoto end;\n\t\t}\n\tif (sdebug)\n\t\tssl_ctx_security_debug(ctx, bio_err, sdebug);\n\tif (vpm)\n\t\tSSL_CTX_set1_param(ctx, vpm);\n\tif (!args_ssl_call(ctx, bio_err, cctx, ssl_args, 1, no_jpake))\n\t\t{\n\t\tERR_print_errors(bio_err);\n\t\tgoto end;\n\t\t}\n\tif (!ssl_load_stores(ctx, vfyCApath, vfyCAfile, chCApath, chCAfile,\n\t\t\t\t\t\tcrls, crl_download))\n\t\t{\n\t\tBIO_printf(bio_err, "Error loading store locations\\n");\n\t\tERR_print_errors(bio_err);\n\t\tgoto end;\n\t\t}\n#ifndef OPENSSL_NO_ENGINE\n\tif (ssl_client_engine)\n\t\t{\n\t\tif (!SSL_CTX_set_client_cert_engine(ctx, ssl_client_engine))\n\t\t\t{\n\t\t\tBIO_puts(bio_err, "Error setting client auth engine\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tENGINE_free(ssl_client_engine);\n\t\t\tgoto end;\n\t\t\t}\n\t\tENGINE_free(ssl_client_engine);\n\t\t}\n#endif\n#ifndef OPENSSL_NO_PSK\n#ifdef OPENSSL_NO_JPAKE\n\tif (psk_key != NULL)\n#else\n\tif (psk_key != NULL || jpake_secret)\n#endif\n\t\t{\n\t\tif (c_debug)\n\t\t\tBIO_printf(bio_c_out, "PSK key given or JPAKE in use, setting client callback\\n");\n\t\tSSL_CTX_set_psk_client_callback(ctx, psk_client_cb);\n\t\t}\n\tif (srtp_profiles != NULL)\n\t\tSSL_CTX_set_tlsext_use_srtp(ctx, srtp_profiles);\n#endif\n\tif (exc) ssl_ctx_set_excert(ctx, exc);\n\tif (socket_type == SOCK_DGRAM) SSL_CTX_set_read_ahead(ctx, 1);\n#if !defined(OPENSSL_NO_TLSEXT)\n# if !defined(OPENSSL_NO_NEXTPROTONEG)\n\tif (next_proto.data)\n\t\tSSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &next_proto);\n# endif\n\tif (alpn_in)\n\t\t{\n\t\tunsigned short alpn_len;\n\t\tunsigned char *alpn = next_protos_parse(&alpn_len, alpn_in);\n\t\tif (alpn == NULL)\n\t\t\t{\n\t\t\tBIO_printf(bio_err, "Error parsing -alpn argument\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\tSSL_CTX_set_alpn_protos(ctx, alpn, alpn_len);\n\t\tOPENSSL_free(alpn);\n\t\t}\n#endif\n#ifndef OPENSSL_NO_TLSEXT\n\t\tfor (i = 0; i < serverinfo_types_count; i++)\n\t\t\t{\n\t\t\tSSL_CTX_add_client_custom_ext(ctx,\n\t\t\t\t\t\t      serverinfo_types[i],\n\t\t\t\t\t\t      NULL, NULL, NULL,\n\t\t\t\t\t\t      serverinfo_cli_parse_cb,\n\t\t\t\t\t\t      NULL);\n\t\t\t}\n#endif\n\tif (state) SSL_CTX_set_info_callback(ctx,apps_ssl_info_callback);\n#if 0\n\telse\n\t\tSSL_CTX_set_cipher_list(ctx,getenv("SSL_CIPHER"));\n#endif\n\tSSL_CTX_set_verify(ctx,verify,verify_callback);\n\tif ((!SSL_CTX_load_verify_locations(ctx,CAfile,CApath)) ||\n\t\t(!SSL_CTX_set_default_verify_paths(ctx)))\n\t\t{\n\t\tERR_print_errors(bio_err);\n\t\t}\n\tssl_ctx_add_crls(ctx, crls, crl_download);\n\tif (!set_cert_key_stuff(ctx,cert,key,chain,build_chain))\n\t\tgoto end;\n#ifndef OPENSSL_NO_TLSEXT\n\tif (servername != NULL)\n\t\t{\n\t\ttlsextcbp.biodebug = bio_err;\n\t\tSSL_CTX_set_tlsext_servername_callback(ctx, ssl_servername_cb);\n\t\tSSL_CTX_set_tlsext_servername_arg(ctx, &tlsextcbp);\n\t\t}\n#ifndef OPENSSL_NO_SRP\n        if (srp_arg.srplogin)\n\t\t{\n\t\tif (!srp_lateuser && !SSL_CTX_set_srp_username(ctx, srp_arg.srplogin))\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"Unable to set SRP username\\n");\n\t\t\tgoto end;\n\t\t\t}\n\t\tsrp_arg.msg = c_msg;\n\t\tsrp_arg.debug = c_debug ;\n\t\tSSL_CTX_set_srp_cb_arg(ctx,&srp_arg);\n\t\tSSL_CTX_set_srp_client_pwd_callback(ctx, ssl_give_srp_client_pwd_cb);\n\t\tSSL_CTX_set_srp_strength(ctx, srp_arg.strength);\n\t\tif (c_msg || c_debug || srp_arg.amp == 0)\n\t\t\tSSL_CTX_set_srp_verify_param_callback(ctx, ssl_srp_verify_param_cb);\n\t\t}\n#endif\n#endif\n\tcon=SSL_new(ctx);\n\tif (sess_in)\n\t\t{\n\t\tSSL_SESSION *sess;\n\t\tBIO *stmp = BIO_new_file(sess_in, "r");\n\t\tif (!stmp)\n\t\t\t{\n\t\t\tBIO_printf(bio_err, "Can\'t open session file %s\\n",\n\t\t\t\t\t\tsess_in);\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\tsess = PEM_read_bio_SSL_SESSION(stmp, NULL, 0, NULL);\n\t\tBIO_free(stmp);\n\t\tif (!sess)\n\t\t\t{\n\t\t\tBIO_printf(bio_err, "Can\'t open session file %s\\n",\n\t\t\t\t\t\tsess_in);\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\tSSL_set_session(con, sess);\n\t\tSSL_SESSION_free(sess);\n\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n\tif (servername != NULL)\n\t\t{\n\t\tif (!SSL_set_tlsext_host_name(con,servername))\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"Unable to set TLS servername extension.\\n");\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n#endif\n#ifndef OPENSSL_NO_KRB5\n\tif (con  &&  (kctx = kssl_ctx_new()) != NULL)\n                {\n\t\tSSL_set0_kssl_ctx(con, kctx);\n                kssl_ctx_setstring(kctx, KSSL_SERVER, host);\n\t\t}\n#endif\n#if 0\n#ifdef TLSEXT_TYPE_opaque_prf_input\n\tSSL_set_tlsext_opaque_prf_input(con, "Test client", 11);\n#endif\n#endif\nre_start:\n#ifdef NO_SYS_UN_H\n\tif (init_client(&s,host,port,socket_type) == 0)\n#else\n\tif ((!unix_path && (init_client(&s,host,port,socket_type) == 0)) ||\n\t\t\t(unix_path && (init_client_unix(&s,unix_path) == 0)))\n#endif\n\t\t{\n\t\tBIO_printf(bio_err,"connect:errno=%d\\n",get_last_socket_error());\n\t\tSHUTDOWN(s);\n\t\tgoto end;\n\t\t}\n\tBIO_printf(bio_c_out,"CONNECTED(%08X)\\n",s);\n#ifdef FIONBIO\n\tif (c_nbio)\n\t\t{\n\t\tunsigned long l=1;\n\t\tBIO_printf(bio_c_out,"turning on non blocking io\\n");\n\t\tif (BIO_socket_ioctl(s,FIONBIO,&l) < 0)\n\t\t\t{\n\t\t\tERR_print_errors(bio_err);\n\t\t\tgoto end;\n\t\t\t}\n\t\t}\n#endif\n\tif (c_Pause & 0x01) SSL_set_debug(con, 1);\n\tif (socket_type == SOCK_DGRAM)\n\t\t{\n\t\tsbio=BIO_new_dgram(s,BIO_NOCLOSE);\n\t\tif (getsockname(s, &peer, (void *)&peerlen) < 0)\n\t\t\t{\n\t\t\tBIO_printf(bio_err, "getsockname:errno=%d\\n",\n\t\t\t\tget_last_socket_error());\n\t\t\tSHUTDOWN(s);\n\t\t\tgoto end;\n\t\t\t}\n\t\t(void)BIO_ctrl_set_connected(sbio, 1, &peer);\n\t\tif (enable_timeouts)\n\t\t\t{\n\t\t\ttimeout.tv_sec = 0;\n\t\t\ttimeout.tv_usec = DGRAM_RCV_TIMEOUT;\n\t\t\tBIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_RECV_TIMEOUT, 0, &timeout);\n\t\t\ttimeout.tv_sec = 0;\n\t\t\ttimeout.tv_usec = DGRAM_SND_TIMEOUT;\n\t\t\tBIO_ctrl(sbio, BIO_CTRL_DGRAM_SET_SEND_TIMEOUT, 0, &timeout);\n\t\t\t}\n\t\tif (socket_mtu > 28)\n\t\t\t{\n\t\t\tSSL_set_options(con, SSL_OP_NO_QUERY_MTU);\n\t\t\tSSL_set_mtu(con, socket_mtu - 28);\n\t\t\t}\n\t\telse\n\t\t\tBIO_ctrl(sbio, BIO_CTRL_DGRAM_MTU_DISCOVER, 0, NULL);\n\t\t}\n\telse\n\t\tsbio=BIO_new_socket(s,BIO_NOCLOSE);\n\tif (nbio_test)\n\t\t{\n\t\tBIO *test;\n\t\ttest=BIO_new(BIO_f_nbio_test());\n\t\tsbio=BIO_push(test,sbio);\n\t\t}\n\tif (c_debug)\n\t\t{\n\t\tSSL_set_debug(con, 1);\n\t\tBIO_set_callback(sbio,bio_dump_callback);\n\t\tBIO_set_callback_arg(sbio,(char *)bio_c_out);\n\t\t}\n\tif (c_msg)\n\t\t{\n#ifndef OPENSSL_NO_SSL_TRACE\n\t\tif (c_msg == 2)\n\t\t\tSSL_set_msg_callback(con, SSL_trace);\n\t\telse\n#endif\n\t\t\tSSL_set_msg_callback(con, msg_cb);\n\t\tSSL_set_msg_callback_arg(con, bio_c_msg ? bio_c_msg : bio_c_out);\n\t\t}\n#ifndef OPENSSL_NO_TLSEXT\n\tif (c_tlsextdebug)\n\t\t{\n\t\tSSL_set_tlsext_debug_callback(con, tlsext_cb);\n\t\tSSL_set_tlsext_debug_arg(con, bio_c_out);\n\t\t}\n\tif (c_status_req)\n\t\t{\n\t\tSSL_set_tlsext_status_type(con, TLSEXT_STATUSTYPE_ocsp);\n\t\tSSL_CTX_set_tlsext_status_cb(ctx, ocsp_resp_cb);\n\t\tSSL_CTX_set_tlsext_status_arg(ctx, bio_c_out);\n#if 0\n{\nSTACK_OF(OCSP_RESPID) *ids = sk_OCSP_RESPID_new_null();\nOCSP_RESPID *id = OCSP_RESPID_new();\nid->value.byKey = ASN1_OCTET_STRING_new();\nid->type = V_OCSP_RESPID_KEY;\nASN1_STRING_set(id->value.byKey, "Hello World", -1);\nsk_OCSP_RESPID_push(ids, id);\nSSL_set_tlsext_status_ids(con, ids);\n}\n#endif\n\t\t}\n#endif\n#ifndef OPENSSL_NO_JPAKE\n\tif (jpake_secret)\n\t\tjpake_client_auth(bio_c_out, sbio, jpake_secret);\n#endif\n\tSSL_set_bio(con,sbio,sbio);\n\tSSL_set_connect_state(con);\n\twidth=SSL_get_fd(con)+1;\n\tread_tty=1;\n\twrite_tty=0;\n\ttty_on=0;\n\tread_ssl=1;\n\twrite_ssl=1;\n\tcbuf_len=0;\n\tcbuf_off=0;\n\tsbuf_len=0;\n\tsbuf_off=0;\n\tif (starttls_proto == PROTO_SMTP)\n\t\t{\n\t\tint foundit=0;\n\t\tBIO *fbio = BIO_new(BIO_f_buffer());\n\t\tBIO_push(fbio, sbio);\n\t\tdo\n\t\t\t{\n\t\t\tmbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);\n\t\t\t}\n\t\twhile (mbuf_len>3 && mbuf[3]==\'-\');\n\t\tBIO_printf(fbio,"EHLO openssl.client.net\\r\\n");\n\t\t(void)BIO_flush(fbio);\n\t\tdo\n\t\t\t{\n\t\t\tmbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);\n\t\t\tif (strstr(mbuf,"STARTTLS"))\n\t\t\t\tfoundit=1;\n\t\t\t}\n\t\twhile (mbuf_len>3 && mbuf[3]==\'-\');\n\t\t(void)BIO_flush(fbio);\n\t\tBIO_pop(fbio);\n\t\tBIO_free(fbio);\n\t\tif (!foundit)\n\t\t\tBIO_printf(bio_err,\n\t\t\t\t   "didn\'t found starttls in server response,"\n\t\t\t\t   " try anyway...\\n");\n\t\tBIO_printf(sbio,"STARTTLS\\r\\n");\n\t\tBIO_read(sbio,sbuf,BUFSIZZ);\n\t\t}\n\telse if (starttls_proto == PROTO_POP3)\n\t\t{\n\t\tBIO_read(sbio,mbuf,BUFSIZZ);\n\t\tBIO_printf(sbio,"STLS\\r\\n");\n\t\tBIO_read(sbio,sbuf,BUFSIZZ);\n\t\t}\n\telse if (starttls_proto == PROTO_IMAP)\n\t\t{\n\t\tint foundit=0;\n\t\tBIO *fbio = BIO_new(BIO_f_buffer());\n\t\tBIO_push(fbio, sbio);\n\t\tBIO_gets(fbio,mbuf,BUFSIZZ);\n\t\tBIO_printf(fbio,". CAPABILITY\\r\\n");\n\t\t(void)BIO_flush(fbio);\n\t\tdo\n\t\t\t{\n\t\t\tmbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);\n\t\t\tif (strstr(mbuf,"STARTTLS"))\n\t\t\t\tfoundit=1;\n\t\t\t}\n\t\twhile (mbuf_len>3 && mbuf[0]!=\'.\');\n\t\t(void)BIO_flush(fbio);\n\t\tBIO_pop(fbio);\n\t\tBIO_free(fbio);\n\t\tif (!foundit)\n\t\t\tBIO_printf(bio_err,\n\t\t\t\t   "didn\'t found STARTTLS in server response,"\n\t\t\t\t   " try anyway...\\n");\n\t\tBIO_printf(sbio,". STARTTLS\\r\\n");\n\t\tBIO_read(sbio,sbuf,BUFSIZZ);\n\t\t}\n\telse if (starttls_proto == PROTO_FTP)\n\t\t{\n\t\tBIO *fbio = BIO_new(BIO_f_buffer());\n\t\tBIO_push(fbio, sbio);\n\t\tdo\n\t\t\t{\n\t\t\tmbuf_len = BIO_gets(fbio,mbuf,BUFSIZZ);\n\t\t\t}\n\t\twhile (mbuf_len>3 && mbuf[3]==\'-\');\n\t\t(void)BIO_flush(fbio);\n\t\tBIO_pop(fbio);\n\t\tBIO_free(fbio);\n\t\tBIO_printf(sbio,"AUTH TLS\\r\\n");\n\t\tBIO_read(sbio,sbuf,BUFSIZZ);\n\t\t}\n\tif (starttls_proto == PROTO_XMPP)\n\t\t{\n\t\tint seen = 0;\n\t\tBIO_printf(sbio,"<stream:stream "\n\t\t    "xmlns:stream=\'http://etherx.jabber.org/streams\' "\n\t\t    "xmlns=\'jabber:client\' to=\'%s\' version=\'1.0\'>", xmpphost ?\n\t\t\t   xmpphost : host);\n\t\tseen = BIO_read(sbio,mbuf,BUFSIZZ);\n\t\tmbuf[seen] = 0;\n\t\twhile (!strstr(mbuf, "<starttls xmlns=\'urn:ietf:params:xml:ns:xmpp-tls\'") &&\n\t\t\t\t!strstr(mbuf, "<starttls xmlns=\\"urn:ietf:params:xml:ns:xmpp-tls\\""))\n\t\t\t{\n\t\t\tseen = BIO_read(sbio,mbuf,BUFSIZZ);\n\t\t\tif (seen <= 0)\n\t\t\t\tgoto shut;\n\t\t\tmbuf[seen] = 0;\n\t\t\t}\n\t\tBIO_printf(sbio, "<starttls xmlns=\'urn:ietf:params:xml:ns:xmpp-tls\'/>");\n\t\tseen = BIO_read(sbio,sbuf,BUFSIZZ);\n\t\tsbuf[seen] = 0;\n\t\tif (!strstr(sbuf, "<proceed"))\n\t\t\tgoto shut;\n\t\tmbuf[0] = 0;\n\t\t}\n\tfor (;;)\n\t\t{\n\t\tFD_ZERO(&readfds);\n\t\tFD_ZERO(&writefds);\n\t\tif ((SSL_version(con) == DTLS1_VERSION) &&\n\t\t\tDTLSv1_get_timeout(con, &timeout))\n\t\t\ttimeoutp = &timeout;\n\t\telse\n\t\t\ttimeoutp = NULL;\n\t\tif (SSL_in_init(con) && !SSL_total_renegotiations(con))\n\t\t\t{\n\t\t\tin_init=1;\n\t\t\ttty_on=0;\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\ttty_on=1;\n\t\t\tif (in_init)\n\t\t\t\t{\n\t\t\t\tin_init=0;\n#if 0\n#ifndef OPENSSL_NO_TLSEXT\n\t\t\t\tif (servername != NULL && !SSL_session_reused(con))\n\t\t\t\t\t{\n\t\t\t\t\tBIO_printf(bio_c_out,"Server did %sacknowledge servername extension.\\n",tlsextcbp.ack?"":"not ");\n\t\t\t\t\t}\n#endif\n#endif\n\t\t\t\tif (sess_out)\n\t\t\t\t\t{\n\t\t\t\t\tBIO *stmp = BIO_new_file(sess_out, "w");\n\t\t\t\t\tif (stmp)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tPEM_write_bio_SSL_SESSION(stmp, SSL_get_session(con));\n\t\t\t\t\t\tBIO_free(stmp);\n\t\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tBIO_printf(bio_err, "Error writing session file %s\\n", sess_out);\n\t\t\t\t\t}\n\t\t\t\tif (c_brief)\n\t\t\t\t\t{\n\t\t\t\t\tBIO_puts(bio_err,\n\t\t\t\t\t\t"CONNECTION ESTABLISHED\\n");\n\t\t\t\t\tprint_ssl_summary(bio_err, con);\n\t\t\t\t\t}\n\t\t\t\tprint_stuff(bio_c_out,con,full_log);\n\t\t\t\tif (full_log > 0) full_log--;\n\t\t\t\tif (starttls_proto)\n\t\t\t\t\t{\n\t\t\t\t\tBIO_printf(bio_err,"%s",mbuf);\n\t\t\t\t\tstarttls_proto = PROTO_OFF;\n\t\t\t\t\t}\n\t\t\t\tif (reconnect)\n\t\t\t\t\t{\n\t\t\t\t\treconnect--;\n\t\t\t\t\tBIO_printf(bio_c_out,"drop connection and then reconnect\\n");\n\t\t\t\t\tSSL_shutdown(con);\n\t\t\t\t\tSSL_set_connect_state(con);\n\t\t\t\t\tSHUTDOWN(SSL_get_fd(con));\n\t\t\t\t\tgoto re_start;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\tssl_pending = read_ssl && SSL_pending(con);\n\t\tif (!ssl_pending)\n\t\t\t{\n#if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_NETWARE) && !defined (OPENSSL_SYS_BEOS_R5)\n\t\t\tif (tty_on)\n\t\t\t\t{\n\t\t\t\tif (read_tty)  openssl_fdset(fileno(stdin),&readfds);\n\t\t\t\tif (write_tty) openssl_fdset(fileno(stdout),&writefds);\n\t\t\t\t}\n\t\t\tif (read_ssl)\n\t\t\t\topenssl_fdset(SSL_get_fd(con),&readfds);\n\t\t\tif (write_ssl)\n\t\t\t\topenssl_fdset(SSL_get_fd(con),&writefds);\n#else\n\t\t\tif(!tty_on || !write_tty) {\n\t\t\t\tif (read_ssl)\n\t\t\t\t\topenssl_fdset(SSL_get_fd(con),&readfds);\n\t\t\t\tif (write_ssl)\n\t\t\t\t\topenssl_fdset(SSL_get_fd(con),&writefds);\n\t\t\t}\n#endif\n#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)\n\t\t\ti=0;\n\t\t\tif(!write_tty) {\n\t\t\t\tif(read_tty) {\n\t\t\t\t\ttv.tv_sec = 1;\n\t\t\t\t\ttv.tv_usec = 0;\n\t\t\t\t\ti=select(width,(void *)&readfds,(void *)&writefds,\n\t\t\t\t\t\t NULL,&tv);\n#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)\n\t\t\t\t\tif(!i && (!_kbhit() || !read_tty) ) continue;\n#else\n\t\t\t\t\tif(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;\n#endif\n\t\t\t\t} else \ti=select(width,(void *)&readfds,(void *)&writefds,\n\t\t\t\t\t NULL,timeoutp);\n\t\t\t}\n#elif defined(OPENSSL_SYS_NETWARE)\n\t\t\tif(!write_tty) {\n\t\t\t\tif(read_tty) {\n\t\t\t\t\ttv.tv_sec = 1;\n\t\t\t\t\ttv.tv_usec = 0;\n\t\t\t\t\ti=select(width,(void *)&readfds,(void *)&writefds,\n\t\t\t\t\t\tNULL,&tv);\n\t\t\t\t} else \ti=select(width,(void *)&readfds,(void *)&writefds,\n\t\t\t\t\tNULL,timeoutp);\n\t\t\t}\n#elif defined(OPENSSL_SYS_BEOS_R5)\n\t\t\ti=0;\n\t\t\tstdin_set = 0;\n\t\t\t(void)fcntl(fileno(stdin), F_SETFL, O_NONBLOCK);\n\t\t\tif(!write_tty) {\n\t\t\t\tif(read_tty) {\n\t\t\t\t\ttv.tv_sec = 1;\n\t\t\t\t\ttv.tv_usec = 0;\n\t\t\t\t\ti=select(width,(void *)&readfds,(void *)&writefds,\n\t\t\t\t\t\t NULL,&tv);\n\t\t\t\t\tif (read(fileno(stdin), sbuf, 0) >= 0)\n\t\t\t\t\t\tstdin_set = 1;\n\t\t\t\t\tif (!i && (stdin_set != 1 || !read_tty))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t} else \ti=select(width,(void *)&readfds,(void *)&writefds,\n\t\t\t\t\t NULL,timeoutp);\n\t\t\t}\n\t\t\t(void)fcntl(fileno(stdin), F_SETFL, 0);\n#else\n\t\t\ti=select(width,(void *)&readfds,(void *)&writefds,\n\t\t\t\t NULL,timeoutp);\n#endif\n\t\t\tif ( i < 0)\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err,"bad select %d\\n",\n\t\t\t\tget_last_socket_error());\n\t\t\t\tgoto shut;\n\t\t\t\t}\n\t\t\t}\n\t\tif ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)\n\t\t\t{\n\t\t\tBIO_printf(bio_err,"TIMEOUT occurred\\n");\n\t\t\t}\n\t\tif (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))\n\t\t\t{\n\t\t\tk=SSL_write(con,&(cbuf[cbuf_off]),\n\t\t\t\t(unsigned int)cbuf_len);\n\t\t\tswitch (SSL_get_error(con,k))\n\t\t\t\t{\n\t\t\tcase SSL_ERROR_NONE:\n\t\t\t\tcbuf_off+=k;\n\t\t\t\tcbuf_len-=k;\n\t\t\t\tif (k <= 0) goto end;\n\t\t\t\tif (cbuf_len <= 0)\n\t\t\t\t\t{\n\t\t\t\t\tread_tty=1;\n\t\t\t\t\twrite_ssl=0;\n\t\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\tread_tty=0;\n\t\t\t\t\twrite_ssl=1;\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_WANT_WRITE:\n\t\t\t\tBIO_printf(bio_c_out,"write W BLOCK\\n");\n\t\t\t\twrite_ssl=1;\n\t\t\t\tread_tty=0;\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_WANT_READ:\n\t\t\t\tBIO_printf(bio_c_out,"write R BLOCK\\n");\n\t\t\t\twrite_tty=0;\n\t\t\t\tread_ssl=1;\n\t\t\t\twrite_ssl=0;\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_WANT_X509_LOOKUP:\n\t\t\t\tBIO_printf(bio_c_out,"write X BLOCK\\n");\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_ZERO_RETURN:\n\t\t\t\tif (cbuf_len != 0)\n\t\t\t\t\t{\n\t\t\t\t\tBIO_printf(bio_c_out,"shutdown\\n");\n\t\t\t\t\tret = 0;\n\t\t\t\t\tgoto shut;\n\t\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\tread_tty=1;\n\t\t\t\t\twrite_ssl=0;\n\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\tcase SSL_ERROR_SYSCALL:\n\t\t\t\tif ((k != 0) || (cbuf_len != 0))\n\t\t\t\t\t{\n\t\t\t\t\tBIO_printf(bio_err,"write:errno=%d\\n",\n\t\t\t\t\t\tget_last_socket_error());\n\t\t\t\t\tgoto shut;\n\t\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\tread_tty=1;\n\t\t\t\t\twrite_ssl=0;\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_SSL:\n\t\t\t\tERR_print_errors(bio_err);\n\t\t\t\tgoto shut;\n\t\t\t\t}\n\t\t\t}\n#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)\n\t\telse if (!ssl_pending && write_tty)\n#else\n\t\telse if (!ssl_pending && FD_ISSET(fileno(stdout),&writefds))\n#endif\n\t\t\t{\n#ifdef CHARSET_EBCDIC\n\t\t\tascii2ebcdic(&(sbuf[sbuf_off]),&(sbuf[sbuf_off]),sbuf_len);\n#endif\n\t\t\ti=raw_write_stdout(&(sbuf[sbuf_off]),sbuf_len);\n\t\t\tif (i <= 0)\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_c_out,"DONE\\n");\n\t\t\t\tret = 0;\n\t\t\t\tgoto shut;\n\t\t\t\t}\n\t\t\tsbuf_len-=i;;\n\t\t\tsbuf_off+=i;\n\t\t\tif (sbuf_len <= 0)\n\t\t\t\t{\n\t\t\t\tread_ssl=1;\n\t\t\t\twrite_tty=0;\n\t\t\t\t}\n\t\t\t}\n\t\telse if (ssl_pending || FD_ISSET(SSL_get_fd(con),&readfds))\n\t\t\t{\n#ifdef RENEG\n{ static int iiii; if (++iiii == 52) { SSL_renegotiate(con); iiii=0; } }\n#endif\n#if 1\n\t\t\tk=SSL_read(con,sbuf,1024   );\n#else\n\t\t\tk=SSL_read(con,sbuf,16);\n{ char zbuf[10240];\nprintf("read=%d pending=%d peek=%d\\n",k,SSL_pending(con),SSL_peek(con,zbuf,10240));\n}\n#endif\n\t\t\tswitch (SSL_get_error(con,k))\n\t\t\t\t{\n\t\t\tcase SSL_ERROR_NONE:\n\t\t\t\tif (k <= 0)\n\t\t\t\t\tgoto end;\n\t\t\t\tsbuf_off=0;\n\t\t\t\tsbuf_len=k;\n\t\t\t\tread_ssl=0;\n\t\t\t\twrite_tty=1;\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_WANT_WRITE:\n\t\t\t\tBIO_printf(bio_c_out,"read W BLOCK\\n");\n\t\t\t\twrite_ssl=1;\n\t\t\t\tread_tty=0;\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_WANT_READ:\n\t\t\t\tBIO_printf(bio_c_out,"read R BLOCK\\n");\n\t\t\t\twrite_tty=0;\n\t\t\t\tread_ssl=1;\n\t\t\t\tif ((read_tty == 0) && (write_ssl == 0))\n\t\t\t\t\twrite_ssl=1;\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_WANT_X509_LOOKUP:\n\t\t\t\tBIO_printf(bio_c_out,"read X BLOCK\\n");\n\t\t\t\tbreak;\n\t\t\tcase SSL_ERROR_SYSCALL:\n\t\t\t\tret=get_last_socket_error();\n\t\t\t\tif (c_brief)\n\t\t\t\t\tBIO_puts(bio_err, "CONNECTION CLOSED BY SERVER\\n");\n\t\t\t\telse\n\t\t\t\t\tBIO_printf(bio_err,"read:errno=%d\\n",ret);\n\t\t\t\tgoto shut;\n\t\t\tcase SSL_ERROR_ZERO_RETURN:\n\t\t\t\tBIO_printf(bio_c_out,"closed\\n");\n\t\t\t\tret=0;\n\t\t\t\tgoto shut;\n\t\t\tcase SSL_ERROR_SSL:\n\t\t\t\tERR_print_errors(bio_err);\n\t\t\t\tgoto shut;\n\t\t\t\t}\n\t\t\t}\n#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS)\n#if defined(OPENSSL_SYS_WINCE) || defined(OPENSSL_SYS_MSDOS)\n\t\telse if (_kbhit())\n#else\n\t\telse if ((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0)))\n#endif\n#elif defined (OPENSSL_SYS_NETWARE)\n\t\telse if (_kbhit())\n#elif defined(OPENSSL_SYS_BEOS_R5)\n\t\telse if (stdin_set)\n#else\n\t\telse if (FD_ISSET(fileno(stdin),&readfds))\n#endif\n\t\t\t{\n\t\t\tif (crlf)\n\t\t\t\t{\n\t\t\t\tint j, lf_num;\n\t\t\t\ti=raw_read_stdin(cbuf,BUFSIZZ/2);\n\t\t\t\tlf_num = 0;\n\t\t\t\tfor (j = 0; j < i; j++)\n\t\t\t\t\tif (cbuf[j] == \'\\n\')\n\t\t\t\t\t\tlf_num++;\n\t\t\t\tfor (j = i-1; j >= 0; j--)\n\t\t\t\t\t{\n\t\t\t\t\tcbuf[j+lf_num] = cbuf[j];\n\t\t\t\t\tif (cbuf[j] == \'\\n\')\n\t\t\t\t\t\t{\n\t\t\t\t\t\tlf_num--;\n\t\t\t\t\t\ti++;\n\t\t\t\t\t\tcbuf[j+lf_num] = \'\\r\';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tassert(lf_num == 0);\n\t\t\t\t}\n\t\t\telse\n\t\t\t\ti=raw_read_stdin(cbuf,BUFSIZZ);\n\t\t\tif ((!c_ign_eof) && ((i <= 0) || (cbuf[0] == \'Q\')))\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err,"DONE\\n");\n\t\t\t\tret=0;\n\t\t\t\tgoto shut;\n\t\t\t\t}\n\t\t\tif ((!c_ign_eof) && (cbuf[0] == \'R\'))\n\t\t\t\t{\n\t\t\t\tBIO_printf(bio_err,"RENEGOTIATING\\n");\n\t\t\t\tSSL_renegotiate(con);\n\t\t\t\tcbuf_len=0;\n\t\t\t\t}\n#ifndef OPENSSL_NO_HEARTBEATS\n\t\t\telse if ((!c_ign_eof) && (cbuf[0] == \'B\'))\n \t\t\t\t{\n\t\t\t\tBIO_printf(bio_err,"HEARTBEATING\\n");\n\t\t\t\tSSL_heartbeat(con);\n\t\t\t\tcbuf_len=0;\n\t\t\t\t}\n#endif\n\t\t\telse\n\t\t\t\t{\n\t\t\t\tcbuf_len=i;\n\t\t\t\tcbuf_off=0;\n#ifdef CHARSET_EBCDIC\n\t\t\t\tebcdic2ascii(cbuf, cbuf, i);\n#endif\n\t\t\t\t}\n\t\t\twrite_ssl=1;\n\t\t\tread_tty=0;\n\t\t\t}\n\t\t}\n\tret=0;\nshut:\n\tif (in_init)\n\t\tprint_stuff(bio_c_out,con,full_log);\n\tSSL_shutdown(con);\n\tSHUTDOWN(SSL_get_fd(con));\nend:\n\tif (con != NULL)\n\t\t{\n\t\tif (prexit != 0)\n\t\t\tprint_stuff(bio_c_out,con,1);\n\t\tSSL_free(con);\n\t\t}\n#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)\n\tif (next_proto.data)\n\t\tOPENSSL_free(next_proto.data);\n#endif\n\tif (ctx != NULL) SSL_CTX_free(ctx);\n\tif (cert)\n\t\tX509_free(cert);\n\tif (crls)\n\t\tsk_X509_CRL_pop_free(crls, X509_CRL_free);\n\tif (key)\n\t\tEVP_PKEY_free(key);\n\tif (chain)\n\t\tsk_X509_pop_free(chain, X509_free);\n\tif (pass)\n\t\tOPENSSL_free(pass);\n\tif (vpm)\n\t\tX509_VERIFY_PARAM_free(vpm);\n\tssl_excert_free(exc);\n\tif (ssl_args)\n\t\tsk_OPENSSL_STRING_free(ssl_args);\n\tif (cctx)\n\t\tSSL_CONF_CTX_free(cctx);\n#ifndef OPENSSL_NO_JPAKE\n\tif (jpake_secret && psk_key)\n\t\tOPENSSL_free(psk_key);\n#endif\n\tif (cbuf != NULL) { OPENSSL_cleanse(cbuf,BUFSIZZ); OPENSSL_free(cbuf); }\n\tif (sbuf != NULL) { OPENSSL_cleanse(sbuf,BUFSIZZ); OPENSSL_free(sbuf); }\n\tif (mbuf != NULL) { OPENSSL_cleanse(mbuf,BUFSIZZ); OPENSSL_free(mbuf); }\n\tif (bio_c_out != NULL)\n\t\t{\n\t\tBIO_free(bio_c_out);\n\t\tbio_c_out=NULL;\n\t\t}\n\tif (bio_c_msg != NULL)\n\t\t{\n\t\tBIO_free(bio_c_msg);\n\t\tbio_c_msg=NULL;\n\t\t}\n\tapps_shutdown();\n\tOPENSSL_EXIT(ret);\n\t}']