security/nss/cmd/btoa/btoa.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "plgetopt.h"
     6 #include "secutil.h"
     7 #include "nssb64.h"
     8 #include <errno.h>
    10 #if defined(XP_WIN) || (defined(__sun) && !defined(SVR4))
    11 #if !defined(WIN32)
    12 extern int fread(char *, size_t, size_t, FILE*);
    13 extern int fwrite(char *, size_t, size_t, FILE*);
    14 extern int fprintf(FILE *, char *, ...);
    15 #endif
    16 #endif
    18 #if defined(WIN32)
    19 #include "fcntl.h"
    20 #include "io.h"
    21 #endif
    23 static PRInt32 
    24 output_ascii (void *arg, const char *obuf, PRInt32 size)
    25 {
    26     FILE *outFile = arg;
    27     int nb;
    29     nb = fwrite(obuf, 1, size, outFile);
    30     if (nb != size) {
    31 	PORT_SetError(SEC_ERROR_IO);
    32 	return -1;
    33     }
    35     return nb;
    36 }
    38 static SECStatus
    39 encode_file(FILE *outFile, FILE *inFile)
    40 {
    41     NSSBase64Encoder *cx;
    42     int nb;
    43     SECStatus status = SECFailure;
    44     unsigned char ibuf[4096];
    46     cx = NSSBase64Encoder_Create(output_ascii, outFile);
    47     if (!cx) {
    48 	return -1;
    49     }
    51     for (;;) {
    52 	if (feof(inFile)) break;
    53 	nb = fread(ibuf, 1, sizeof(ibuf), inFile);
    54 	if (nb != sizeof(ibuf)) {
    55 	    if (nb == 0) {
    56 		if (ferror(inFile)) {
    57 		    PORT_SetError(SEC_ERROR_IO);
    58 		    goto loser;
    59 		}
    60 		/* eof */
    61 		break;
    62 	    }
    63 	}
    65 	status = NSSBase64Encoder_Update(cx, ibuf, nb);
    66 	if (status != SECSuccess) goto loser;
    67     }
    69     status = NSSBase64Encoder_Destroy(cx, PR_FALSE);
    70     if (status != SECSuccess)
    71 	return status;
    73     /*
    74      * Add a trailing CRLF.  Note this must be done *after* the call
    75      * to Destroy above (because only then are we sure all data has
    76      * been written out).
    77      */
    78     fwrite("\r\n", 1, 2, outFile);
    79     return SECSuccess;
    81   loser:
    82     (void) NSSBase64Encoder_Destroy(cx, PR_TRUE);
    83     return status;
    84 }
    86 static void Usage(char *progName)
    87 {
    88     fprintf(stderr,
    89 	    "Usage: %s [-i input] [-o output]\n",
    90 	    progName);
    91     fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
    92 	    "-i input");
    93     fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
    94 	    "-o output");
    95     fprintf(stderr, "%-20s Wrap output in BEGIN/END lines and the given suffix\n",
    96 	    "-w suffix");
    97     fprintf(stderr, "%-20s (use \"c\" as a shortcut for suffix CERTIFICATE)\n",
    98 	    "");
    99     exit(-1);
   100 }
   102 int main(int argc, char **argv)
   103 {
   104     char *progName;
   105     SECStatus rv;
   106     FILE *inFile, *outFile;
   107     PLOptState *optstate;
   108     PLOptStatus status;
   109     char *suffix = NULL;
   111     inFile = 0;
   112     outFile = 0;
   113     progName = strrchr(argv[0], '/');
   114     if (!progName)
   115 	progName = strrchr(argv[0], '\\');
   116     progName = progName ? progName+1 : argv[0];
   118     /* Parse command line arguments */
   119     optstate = PL_CreateOptState(argc, argv, "i:o:w:");
   120     while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
   121 	switch (optstate->option) {
   122 	  default:
   123 	    Usage(progName);
   124 	    break;
   126 	  case 'i':
   127 	    inFile = fopen(optstate->value, "rb");
   128 	    if (!inFile) {
   129 		fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
   130 			progName, optstate->value);
   131 		return -1;
   132 	    }
   133 	    break;
   135 	  case 'o':
   136 	    outFile = fopen(optstate->value, "wb");
   137 	    if (!outFile) {
   138 		fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
   139 			progName, optstate->value);
   140 		return -1;
   141 	    }
   142 	    break;
   144 	  case 'w':
   145 	    if (!strcmp(optstate->value, "c"))
   146 		suffix = strdup("CERTIFICATE");
   147 	    else
   148 		suffix = strdup(optstate->value);
   149 	    break;
   150 	}
   151     }
   152     if (status == PL_OPT_BAD)
   153 	Usage(progName);
   154     if (!inFile) {
   155 #if defined(WIN32)
   156 	/* If we're going to read binary data from stdin, we must put stdin
   157 	** into O_BINARY mode or else incoming \r\n's will become \n's.
   158 	*/
   160 	int smrv = _setmode(_fileno(stdin), _O_BINARY);
   161 	if (smrv == -1) {
   162 	    fprintf(stderr,
   163 	    "%s: Cannot change stdin to binary mode. Use -i option instead.\n",
   164 	            progName);
   165 	    return smrv;
   166 	}
   167 #endif
   168     	inFile = stdin;
   169     }
   170     if (!outFile) {
   171 #if defined(WIN32)
   172 	/* We're going to write binary data to stdout. We must put stdout
   173 	** into O_BINARY mode or else outgoing \r\n's will become \r\r\n's.
   174 	*/
   176 	int smrv = _setmode(_fileno(stdout), _O_BINARY);
   177 	if (smrv == -1) {
   178 	    fprintf(stderr,
   179 	    "%s: Cannot change stdout to binary mode. Use -o option instead.\n",
   180 	            progName);
   181 	    return smrv;
   182 	}
   183 #endif
   184     	outFile = stdout;
   185     }
   186     if (suffix) {
   187 	fprintf(outFile, "-----BEGIN %s-----\n", suffix);
   188     }
   189     rv = encode_file(outFile, inFile);
   190     if (rv != SECSuccess) {
   191 	fprintf(stderr, "%s: lossage: error=%d errno=%d\n",
   192 		progName, PORT_GetError(), errno);
   193 	return -1;
   194     }
   195     if (suffix) {
   196 	fprintf(outFile, "-----END %s-----\n", suffix);
   197     }
   198     return 0;
   199 }

mercurial