security/nss/cmd/atob/atob.c

branch
TOR_BUG_9701
changeset 3
141e0f1194b1
equal deleted inserted replaced
-1:000000000000 0:a7fcb8a7cab2
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/. */
4
5 #include "plgetopt.h"
6 #include "secutil.h"
7 #include "nssb64.h"
8 #include <errno.h>
9
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
17
18 #if defined(WIN32)
19 #include "fcntl.h"
20 #include "io.h"
21 #endif
22
23 static PRInt32
24 output_binary (void *arg, const unsigned char *obuf, PRInt32 size)
25 {
26 FILE *outFile = arg;
27 int nb;
28
29 nb = fwrite(obuf, 1, size, outFile);
30 if (nb != size) {
31 PORT_SetError(SEC_ERROR_IO);
32 return -1;
33 }
34
35 return nb;
36 }
37
38 static PRBool
39 isBase64Char(char c)
40 {
41 return ((c >= 'A' && c <= 'Z')
42 || (c >= 'a' && c <= 'z')
43 || (c >= '0' && c <= '9')
44 || c == '+'
45 || c == '/'
46 || c == '=');
47 }
48
49 static SECStatus
50 decode_file(FILE *outFile, FILE *inFile)
51 {
52 NSSBase64Decoder *cx;
53 SECStatus status = SECFailure;
54 char ibuf[4096];
55 const char *ptr;
56
57 cx = NSSBase64Decoder_Create(output_binary, outFile);
58 if (!cx) {
59 return -1;
60 }
61
62 for (;;) {
63 if (feof(inFile)) break;
64 if (!fgets(ibuf, sizeof(ibuf), inFile)) {
65 if (ferror(inFile)) {
66 PORT_SetError(SEC_ERROR_IO);
67 goto loser;
68 }
69 /* eof */
70 break;
71 }
72 for (ptr = ibuf; *ptr; ++ptr) {
73 char c = *ptr;
74 if (c == '\n' || c == '\r') {
75 break; /* found end of line */
76 }
77 if (!isBase64Char(c)) {
78 ptr = ibuf; /* ignore line */
79 break;
80 }
81 }
82 if (ibuf == ptr) {
83 continue; /* skip empty or non-base64 line */
84 }
85
86 status = NSSBase64Decoder_Update(cx, ibuf, ptr-ibuf);
87 if (status != SECSuccess) goto loser;
88 }
89
90 return NSSBase64Decoder_Destroy(cx, PR_FALSE);
91
92 loser:
93 (void) NSSBase64Decoder_Destroy(cx, PR_TRUE);
94 return status;
95 }
96
97 static void Usage(char *progName)
98 {
99 fprintf(stderr,
100 "Usage: %s [-i input] [-o output]\n",
101 progName);
102 fprintf(stderr, "%-20s Define an input file to use (default is stdin)\n",
103 "-i input");
104 fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",
105 "-o output");
106 exit(-1);
107 }
108
109 int main(int argc, char **argv)
110 {
111 char *progName;
112 SECStatus rv;
113 FILE *inFile, *outFile;
114 PLOptState *optstate;
115 PLOptStatus status;
116
117 inFile = 0;
118 outFile = 0;
119 progName = strrchr(argv[0], '/');
120 progName = progName ? progName+1 : argv[0];
121
122 /* Parse command line arguments */
123 optstate = PL_CreateOptState(argc, argv, "?hi:o:");
124 while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
125 switch (optstate->option) {
126 case '?':
127 case 'h':
128 Usage(progName);
129 break;
130
131 case 'i':
132 inFile = fopen(optstate->value, "r");
133 if (!inFile) {
134 fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
135 progName, optstate->value);
136 return -1;
137 }
138 break;
139
140 case 'o':
141 outFile = fopen(optstate->value, "wb");
142 if (!outFile) {
143 fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
144 progName, optstate->value);
145 return -1;
146 }
147 break;
148 }
149 }
150 if (!inFile) inFile = stdin;
151 if (!outFile) {
152 #if defined(WIN32)
153 int smrv = _setmode(_fileno(stdout), _O_BINARY);
154 if (smrv == -1) {
155 fprintf(stderr,
156 "%s: Cannot change stdout to binary mode. Use -o option instead.\n",
157 progName);
158 return smrv;
159 }
160 #endif
161 outFile = stdout;
162 }
163 rv = decode_file(outFile, inFile);
164 if (rv != SECSuccess) {
165 fprintf(stderr, "%s: lossage: error=%d errno=%d\n",
166 progName, PORT_GetError(), errno);
167 return -1;
168 }
169 return 0;
170 }

mercurial