PRINTF("%s: PR_Poll returned 0x%02x for socket out_flags.\n",
FPRINTF(stderr, "%s: PR_Poll returned 0x%02x for socket out_flags.\n",
int main(int argc, char **argv){    PRFileDesc *       s;    PRFileDesc *       std_out;    CERTCertDBHandle * handle;    char *             host	=  NULL;    char *             port	=  "443";    char *             certDir  =  NULL;    char *             nickname =  NULL;    char *             cipherString = NULL;    int                multiplier = 0;    SECStatus          rv;    PRStatus           status;    PRInt32            filesReady;    PRInt32            ip;    int                npds;    int                override = 0;    int                disableSSL2 = 0;    int                disableSSL3 = 0;    int                disableTLS  = 0;    int                useExportPolicy = 0;    PRSocketOptionData opt;    PRNetAddr          addr;    PRHostEnt          hp;    PRPollDesc         pollset[2];    char               buf[PR_NETDB_BUF_SIZE];    PRBool             useCommandLinePassword = PR_FALSE;    PRBool             pingServerFirst = PR_FALSE;    int                error = 0;    PLOptState *optstate;    PLOptStatus optstatus;    PRStatus prStatus;    progName = strrchr(argv[0], '/');    if (!progName)	progName = strrchr(argv[0], '\\');    progName = progName ? progName+1 : argv[0];    optstate = PL_CreateOptState(argc, argv, "23Tfc:h:p:d:m:n:oqvw:x");    while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {	switch (optstate->option) {	  case '?':	  default : Usage(progName); 			break;          case '2': disableSSL2 = 1; 			break;          case '3': disableSSL3 = 1; 			break;          case 'T': disableTLS  = 1; 			break;          case 'c': cipherString = strdup(optstate->value); break;          case 'h': host = strdup(optstate->value);	break;          case 'f':  /* no longer meaningful. */        break;	  case 'd':	    certDir = strdup(optstate->value);	    certDir = SECU_ConfigDirectory(certDir);	    break;	  case 'm':	    multiplier = atoi(optstate->value);	    if (multiplier < 0)	    	multiplier = 0;	    break;	  case 'n': nickname = strdup(optstate->value);	break;	  case 'o': override = 1; 			break;	  case 'p': port = strdup(optstate->value);	break;	  case 'q': pingServerFirst = PR_TRUE;          break;	  case 'v': verbose++;	 			break;	  case 'w':		password = PORT_Strdup(optstate->value);		useCommandLinePassword = PR_TRUE;		break;	  case 'x': useExportPolicy = 1; 		break;	}    }    if (optstatus == PL_OPT_BAD)	Usage(progName);    if (!host || !port) Usage(progName);    if (!certDir) {	certDir = SECU_DefaultSSLDir();	/* Look in $SSL_DIR */	certDir = SECU_ConfigDirectory(certDir); /* call even if it's NULL */    }    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);    /* set our password function */    if ( useCommandLinePassword ) {	PK11_SetPasswordFunc(ownPasswd);    } else {    	PK11_SetPasswordFunc(SECU_GetModulePassword);    }    /* open the cert DB, the key DB, and the secmod DB. */    rv = NSS_Init(certDir);    if (rv != SECSuccess) {	SECU_PrintError(progName, "unable to open cert database");#if 0    rv = CERT_OpenVolatileCertDB(handle);	CERT_SetDefaultCertDB(handle);#else	return 1;#endif    }    handle = CERT_GetDefaultCertDB();    /* set the policy bits true for all the cipher suites. */    if (useExportPolicy)	NSS_SetExportPolicy();    else	NSS_SetDomesticPolicy();    /* all the SSL2 and SSL3 cipher suites are enabled by default. */    if (cipherString) {	/* disable all the ciphers, then enable the ones we want. */	disableAllSSLCiphers();    }    /* Lookup host */    status = PR_GetHostByName(host, buf, sizeof(buf), &hp);    if (status != PR_SUCCESS) {	SECU_PrintError(progName, "error looking up host");	return 1;    }    if (PR_EnumerateHostEnt(0, &hp, atoi(port), &addr) == -1) {	SECU_PrintError(progName, "error looking up host address");	return 1;    }    ip = PR_ntohl(addr.inet.ip);    PRINTF("%s: connecting to %s:%d (address=%d.%d.%d.%d)\n",	   progName, host, PR_ntohs(addr.inet.port),	   (ip >> 24) & 0xff,	   (ip >> 16) & 0xff,	   (ip >>  8) & 0xff,	   (ip >>  0) & 0xff);    if (pingServerFirst) {	int iter = 0;	PRErrorCode err;	do {	    s = PR_NewTCPSocket();	    if (s == NULL) {		SECU_PrintError(progName, "Failed to create a TCP socket");	    }	    opt.option             = PR_SockOpt_Nonblocking;	    opt.value.non_blocking = PR_FALSE;	    prStatus = PR_SetSocketOption(s, &opt);	    if (prStatus != PR_SUCCESS) {		PR_Close(s);		SECU_PrintError(progName, 		                "Failed to set blocking socket option");		return 1;	    }	    prStatus = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);	    if (prStatus == PR_SUCCESS) {    		PR_Shutdown(s, PR_SHUTDOWN_BOTH);    		PR_Close(s);               if (NSS_Shutdown() != SECSuccess) {                   exit(1);               }    		PR_Cleanup();		return 0;	    }	    err = PR_GetError();	    if ((err != PR_CONNECT_REFUSED_ERROR) && 	        (err != PR_CONNECT_RESET_ERROR)) {		SECU_PrintError(progName, "TCP Connection failed");		return 1;	    }	    PR_Close(s);	    PR_Sleep(PR_MillisecondsToInterval(WAIT_INTERVAL));	} while (++iter < MAX_WAIT_FOR_SERVER);	SECU_PrintError(progName,                      "Client timed out while waiting for connection to server");	return 1;    }    /* Create socket */    s = PR_NewTCPSocket();    if (s == NULL) {	SECU_PrintError(progName, "error creating socket");	return 1;    }    opt.option = PR_SockOpt_Nonblocking;    opt.value.non_blocking = PR_TRUE;    PR_SetSocketOption(s, &opt);    /*PR_SetSocketOption(PR_GetSpecialFD(PR_StandardInput), &opt);*/    s = SSL_ImportFD(NULL, s);    if (s == NULL) {	SECU_PrintError(progName, "error importing socket");	return 1;    }    rv = SSL_OptionSet(s, SSL_SECURITY, 1);    if (rv != SECSuccess) {        SECU_PrintError(progName, "error enabling socket");	return 1;    }    rv = SSL_OptionSet(s, SSL_HANDSHAKE_AS_CLIENT, 1);    if (rv != SECSuccess) {	SECU_PrintError(progName, "error enabling client handshake");	return 1;    }    /* all the SSL2 and SSL3 cipher suites are enabled by default. */    if (cipherString) {    	int ndx;	while (0 != (ndx = *cipherString++)) {	    int *cptr;	    int  cipher;	    if (! isalpha(ndx))	     	Usage(progName);	    cptr = islower(ndx) ? ssl3CipherSuites : ssl2CipherSuites;	    for (ndx &= 0x1f; (cipher = *cptr++) != 0 && --ndx > 0; ) 	    	/* do nothing */;	    if (cipher) {		SECStatus status;		status = SSL_CipherPrefSet(s, cipher, SSL_ALLOWED);		if (status != SECSuccess) 		    SECU_PrintError(progName, "SSL_CipherPrefSet()");	    }	}    }    rv = SSL_OptionSet(s, SSL_ENABLE_SSL2, !disableSSL2);    if (rv != SECSuccess) {	SECU_PrintError(progName, "error enabling SSLv2 ");	return 1;    }    rv = SSL_OptionSet(s, SSL_ENABLE_SSL3, !disableSSL3);    if (rv != SECSuccess) {	SECU_PrintError(progName, "error enabling SSLv3 ");	return 1;    }    rv = SSL_OptionSet(s, SSL_ENABLE_TLS, !disableTLS);    if (rv != SECSuccess) {	SECU_PrintError(progName, "error enabling TLS ");	return 1;    }    /* disable ssl2 and ssl2-compatible client hellos. */    rv = SSL_OptionSet(s, SSL_V2_COMPATIBLE_HELLO, !disableSSL2);    if (rv != SECSuccess) {	SECU_PrintError(progName, "error disabling v2 compatibility");	return 1;    }    if (useCommandLinePassword) {	SSL_SetPKCS11PinArg(s, password);    }    SSL_AuthCertificateHook(s, SSL_AuthCertificate, (void *)handle);    if (override) {	SSL_BadCertHook(s, ownBadCertHandler, NULL);    }    SSL_GetClientAuthDataHook(s, own_GetClientAuthData, (void *)nickname);    SSL_HandshakeCallback(s, handshakeCallback, NULL);    SSL_SetURL(s, host);    /* Try to connect to the server */    status = PR_Connect(s, &addr, PR_INTERVAL_NO_TIMEOUT);    if (status != PR_SUCCESS) {	if (PR_GetError() == PR_IN_PROGRESS_ERROR) {	    if (verbose)		SECU_PrintError(progName, "connect");	    milliPause(50 * multiplier);	    pollset[0].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;	    pollset[0].out_flags = 0;	    pollset[0].fd = s;	    while(1) {		PRINTF("%s: about to call PR_Poll for connect completion!\n", progName);		filesReady = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);		if (filesReady < 0) {		    SECU_PrintError(progName, "unable to connect (poll)");		    return 1;		}		PRINTF("%s: PR_Poll returned 0x%02x for socket out_flags.\n",			progName, pollset[0].out_flags);		if (filesReady == 0) {	/* shouldn't happen! */		    PRINTF("%s: PR_Poll returned zero!\n", progName);		    return 1;		}		/* Must milliPause between PR_Poll and PR_GetConnectStatus,		 * Or else winsock gets mighty confused.		 * Sleep(0);		 */		milliPause(1);		status = PR_GetConnectStatus(pollset);		if (status == PR_SUCCESS) {		    break;		}		if (PR_GetError() != PR_IN_PROGRESS_ERROR) {		    SECU_PrintError(progName, "unable to connect (poll)");		    return 1;		}		SECU_PrintError(progName, "poll");		milliPause(50 * multiplier);	    }	} else {	    SECU_PrintError(progName, "unable to connect");	    return 1;	}    }    pollset[0].fd        = s;    pollset[0].in_flags  = PR_POLL_READ;    pollset[1].fd        = PR_GetSpecialFD(PR_StandardInput);    pollset[1].in_flags  = PR_POLL_READ;    npds                 = 2;    std_out              = PR_GetSpecialFD(PR_StandardOutput);#if defined(WIN32)    /* PR_Poll cannot be used with stdin on Windows.  (sigh).     ** But use of PR_Poll and non-blocking sockets is a major feature    ** of this program.  So, we simulate a pollable stdin with a     ** TCP socket pair and a  thread that reads stdin and writes to     ** that socket pair.    */  {    PRFileDesc * fds[2];    PRThread *   thread;    int nspr_rv = PR_NewTCPSocketPair(fds);    if (nspr_rv != PR_SUCCESS) {        SECU_PrintError(progName, "PR_NewTCPSocketPair failed");	error = 1;	goto done;    }    pollset[1].fd = fds[1];    thread = PR_CreateThread(PR_USER_THREAD, thread_main, fds[0],                              PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,                              PR_UNJOINABLE_THREAD, 0);    if (!thread) {        SECU_PrintError(progName, "PR_CreateThread failed");	error = 1;	goto done;    }    /* Wait until the pseudo stdin is readable (for debugging).  --wtc */    PR_Poll(&pollset[1], 1, PR_INTERVAL_NO_TIMEOUT);  }#endif    /*    ** Select on stdin and on the socket. Write data from stdin to    ** socket, read data from socket and write to stdout.    */    PRINTF("%s: ready...\n", progName);    while (pollset[0].in_flags || pollset[1].in_flags) {	char buf[4000];	/* buffer for stdin */	int nb;		/* num bytes read from stdin. */	pollset[0].out_flags = 0;	pollset[1].out_flags = 0;	PRINTF("%s: about to call PR_Poll !\n", progName);	filesReady = PR_Poll(pollset, npds, PR_INTERVAL_NO_TIMEOUT);	if (filesReady < 0) {	    SECU_PrintError(progName, "select failed");	    error = 1;	    goto done;	}	if (filesReady == 0) {	/* shouldn't happen! */	    PRINTF("%s: PR_Poll returned zero!\n", progName);	    return 1;	}	PRINTF("%s: PR_Poll returned!\n", progName);	if (pollset[1].in_flags) {	        PRINTF("%s: PR_Poll returned 0x%02x for stdin out_flags.\n",		    progName, pollset[1].out_flags);	}	if (pollset[1].out_flags & PR_POLL_READ) {	    /* Read from stdin and write to socket */	    nb = PR_Read(pollset[1].fd, buf, sizeof(buf));	    PRINTF("%s: stdin read %d bytes\n", progName, nb);	    if (nb < 0) {		if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {		    SECU_PrintError(progName, "read from stdin failed");	            error = 1;		    break;		}	    } else if (nb == 0) {		pollset[1].in_flags = 0;	    } else {		char * bufp = buf;		PRINTF("%s: Writing %d bytes to server\n", progName, nb);		do {		    PRInt32 cc = PR_Write(s, bufp, nb);		    if (cc < 0) {		    	PRErrorCode err = PR_GetError();			if (err != PR_WOULD_BLOCK_ERROR) {			    SECU_PrintError(progName, 			                    "write to SSL socket failed");			    error = 254;			    goto done;			}			cc = 0;		    }		    bufp += cc;		    nb   -= cc;		    if (nb <= 0) 		    	break;		    pollset[0].in_flags = PR_POLL_WRITE | PR_POLL_EXCEPT;		    pollset[0].out_flags = 0;		    PRINTF("%s: about to call PR_Poll on writable socket !\n", progName);		    cc = PR_Poll(pollset, 1, PR_INTERVAL_NO_TIMEOUT);		    PRINTF("%s: PR_Poll returned with writable socket !\n", progName);		} while (1);		pollset[0].in_flags  = PR_POLL_READ;	    }	}	if (pollset[0].in_flags) {	    PRINTF("%s: PR_Poll returned 0x%02x for socket out_flags.\n",		   progName, pollset[0].out_flags);	}	if (   (pollset[0].out_flags & PR_POLL_READ) 	    || (pollset[0].out_flags & PR_POLL_ERR)  #ifdef PR_POLL_HUP	    || (pollset[0].out_flags & PR_POLL_HUP)#endif	    ) {	    /* Read from socket and write to stdout */	    nb = PR_Read(pollset[0].fd, buf, sizeof(buf));	    PRINTF("%s: Read from server %d bytes\n", progName, nb);	    if (nb < 0) {		if (PR_GetError() != PR_WOULD_BLOCK_ERROR) {		    SECU_PrintError(progName, "read from socket failed");		    error = 1;		    goto done;	    	}	    } else if (nb == 0) {		/* EOF from socket... bye bye */		pollset[0].in_flags = 0;	    } else {		PR_Write(std_out, buf, nb);		puts("\n\n");	    }	}	milliPause(50 * multiplier);    }  done:    PR_Close(s);    SSL_ClearSessionCache();    if (NSS_Shutdown() != SECSuccess) {        exit(1);    }    PR_Cleanup();    return error;}