Make ocspclnt read and write binary files on stdin and stdout.
authornelson%bolyard.com
Wed, 11 Jul 2007 23:40:02 +0000
changeset 7927 213313be21f4b2791ea778eedc12b8822c3d2104
parent 7926 2225c26e40300b97d9f5d0d52ecbeae8192a771a
child 7928 49e3ff06ac66cf3af48cf511c9c3992493dfac7c
push idunknown
push userunknown
push dateunknown
bugs381375
Make ocspclnt read and write binary files on stdin and stdout. bug 381375. r=neil.williams,julien.pierre
security/nss/cmd/ocspclnt/ocspclnt.c
--- a/security/nss/cmd/ocspclnt/ocspclnt.c
+++ b/security/nss/cmd/ocspclnt/ocspclnt.c
@@ -56,18 +56,30 @@
 #ifndef NO_PP		/*
 			 * Compile with this every once in a while to be
 			 * sure that no dependencies on it get added
 			 * outside of the pretty-printing routines.
 			 */
 #include "ocspti.h"	/* internals for pretty-printing routines *only* */
 #endif	/* NO_PP */
 
+#if defined(XP_UNIX)
+#include <unistd.h>
+#endif
+
+#if defined(_WIN32)
+#include "fcntl.h"
+#include "io.h"
+#endif
+
 #define DEFAULT_DB_DIR	"~/.netscape"
 
+/* global */
+char	*program_name;
+
 
 static void
 synopsis (char *program_name)
 {
     PRFileDesc *pr_stderr;
 
     pr_stderr = PR_STDERR;
     PR_fprintf (pr_stderr, "Usage:");
@@ -175,16 +187,35 @@ long_usage (char *program_name)
     PR_fprintf (pr_stderr,
 		"%-17s %-25s (GMT)\n", "", "YYMMDDhhmm[ss]Z");
     PR_fprintf (pr_stderr,
 		"%-17s %-25s (later than GMT)\n", "", "YYMMDDhhmm[ss]+hhmm");
     PR_fprintf (pr_stderr,
 		"%-17s %-25s (earlier than GMT)\n", "", "YYMMDDhhmm[ss]-hhmm");
 }
 
+#if defined(WIN32)
+/* We're going to write binary data to stdout, or read binary from stdin. 
+ * We must put stdout or stdin into O_BINARY mode or else 
+   outgoing \n's will become \r\n's, and incoming \r\n's will become \n's.
+*/
+static SECStatus
+make_file_binary(FILE * binfile)
+{
+    int smrv = _setmode(_fileno(binfile), _O_BINARY);
+    if (smrv == -1) {
+        fprintf(stderr, "%s: Cannot change stdout to binary mode.\n",
+                  program_name);
+    }
+    return smrv;
+}
+#define MAKE_FILE_BINARY make_file_binary
+#else
+#define MAKE_FILE_BINARY(file) 
+#endif
 
 /*
  * XXX This is a generic function that would probably make a good
  * replacement for SECU_DER_Read (which is not at all specific to DER,
  * despite its name), but that requires fixing all of the tools...
  * Still, it should be done, whenenver I/somebody has the time.
  * (Also, consider whether this actually belongs in the security
  * library itself, not just in the command library.)
@@ -298,16 +329,17 @@ create_request (FILE *out_file, CERTCert
 	if (rv != SECSuccess)
 	    goto loser;
     }
 
     encoding = CERT_EncodeOCSPRequest (NULL, request, NULL);
     if (encoding == NULL)
 	goto loser;
 
+    MAKE_FILE_BINARY(out_file);
     if (fwrite (encoding->data, encoding->len, 1, out_file) != 1)
 	goto loser;
 
     rv = SECSuccess;
 
 loser:
     if (encoding != NULL)
 	SECITEM_FreeItem(encoding, PR_TRUE);
@@ -374,16 +406,17 @@ dump_response (FILE *out_file, CERTCertD
     myCert = NULL;
 
     response = CERT_GetEncodedOCSPResponse (NULL, certs, loc, now,
 					    includeServiceLocator,
 					    NULL, NULL, NULL);
     if (response == NULL)
 	goto loser;
 
+    MAKE_FILE_BINARY(out_file);
     if (fwrite (response->data, response->len, 1, out_file) != 1)
 	goto loser;
 
     rv = SECSuccess;
 
 loser:
     if (response != NULL)
 	SECITEM_FreeItem (response, PR_TRUE);
@@ -947,17 +980,16 @@ cert_usage_from_char (const char *cert_u
     return SECSuccess;
 }
 
 
 int
 main (int argc, char **argv)
 {
     int		 retval;
-    char	*program_name;
     PRFileDesc	*in_file;
     FILE	*out_file;	/* not PRFileDesc until SECU accepts it */
     int		 crequest, dresponse;
     int		 prequest, presponse;
     int		 ccert, vcert;
     const char	*db_dir, *date_str, *cert_usage_str, *name;
     const char	*responder_name, *responder_url, *signer_name;
     PRBool	 add_acceptable_responses, add_service_locator;
@@ -1145,16 +1177,17 @@ main (int argc, char **argv)
     rv = NSS_Init (db_dir);
     if (rv != SECSuccess) {
 	SECU_PrintError (program_name, "NSS_Init failed");
 	goto prdone;
     }
     SECU_RegisterDynamicOids();
 
     if (prequest + presponse) {
+	MAKE_FILE_BINARY(stdin);
 	data = read_file_into_item (in_file, siBuffer);
 	if (data == NULL) {
 	    SECU_PrintError (program_name, "problem reading input");
 	    goto nssdone;
 	}
     }
 
     if (crequest + dresponse + presponse + ccert + vcert) {