Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/codex/codex.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2003-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
static const char usage[] =
25
"[-?\n@(#)$Id: codex (AT&T Research) 2009-04-15 $\n]"
26
USAGE_LICENSE
27
"[+NAME?codex - encode/decode filter]"
28
"[+DESCRIPTION?\bcodex\b decodes the standard input and/or encodes the"
29
" standard output according to the \amethod\a operand.]"
30
"[+?Codex method names consist of a leading identifier and 0 or more options"
31
" separated by \b-\b or \b+\b. Method names with identical \b-\b options"
32
" are equivalent. For example, \buu-base64-text\b specifies the"
33
" \buu\b method with the \bbase64\b and \btext\b options, and"
34
" \bpzip-crc+partition=test\b specifies the \bpzip\b method with"
35
" \bcrc\b enabled using the \btest\b partition.]"
36
"[+?Methods may be composed using the \b<\b and \b>\b operators"
37
" (with no intervening space.) \b<\b\amethod\a applies the \amethod\a"
38
" decoder and \b>\b\amethod\a applies the \amethod\a encoder.]"
39
"[+?Supported methods are listed below. Each method may have one or more"
40
" of these attributes:]{"
41
" [+decode?Only decoding is supported -- most likely because the"
42
" encoder has not been published. If omitted then both"
43
" encoding and are supported.]"
44
" [+ident?The decoder self-identifies from the input data and does"
45
" not require an explicit \amethod\a operand.]"
46
" [+vcodex?A self-identifying \bvcodex\b(3) method. The encoder and"
47
" decoder may be applied to either the input or output."
48
" Otherwise decode is restricted to the input and encode is"
49
" restricted to the output.]"
50
"}"
51
"[+?By default decoders are applied to the standard input from left to"
52
" right, and encoders are applied to the standard output from right"
53
" to left. \bvcodex\b methods may be applied to either the input"
54
" or output depending on the composition context.]"
55
"[+?All methods accept these options:]{"
56
" [+PASSPHRASE=\apassphrase\a?The method specific passphrase. If"
57
" not specified then \b--passphrase\b=\apassphrase\a is used."
58
" If \b--passphrase\b is not specified then the passphrase"
59
" for each method requiring one is prompted on and read from"
60
" \b/dev/tty\b. Default to the interactive prompt to avoid"
61
" exposing passphrases to other processes.]"
62
" [+RETAIN?Decode/encode state is retained across discipline"
63
" \binitf\b/\bdonef\b calls.]"
64
" [+SIZE=\asize\a?The decoded size is \asize\a. Some decode methods"
65
" that lack end of data markers require this because they"
66
" may read/write garbage data at the end of the encoded data.]"
67
" [+SOURCE=\afile\a?The delta method source \afile\a.]"
68
" [+TRACE?Enable method trace.]"
69
" [+VERBOSE?Enable verbose method trace.]"
70
"}"
71
"[+?The \bCODEX_OPTIONS\b environment variable may contain space separated"
72
" options that control all \bcodex\b(3) methods. The environment options"
73
" are:]{"
74
" [+trace=\apattern\a?Enable method trace for all methods matching the"
75
" \bksh\b(1) \apattern\a.]"
76
" [+verbose=\apattern\a?Enable verbose method trace for all methods"
77
" matching the \bksh\b(1) \apattern\a. A verbose trace includes"
78
" \bcodex\b(3) discipline exception calls.]"
79
"}"
80
"[+?The supported methods are:]{\fmethods\f}"
81
82
"[d:decode?Apply the \amethod\a operand to the standard input only.]"
83
"[e:encode?Apply the \amethod\a operand to the standard output only.]"
84
"[f:passfile?Like \b--passphrase\b, except the passphrase is the first"
85
" line (sans newline) from \afile\a.]:[file]"
86
"[i:identify?Identify and write the standard input encoding name on the"
87
" standard output and exit.]"
88
"[n:null?Write to the \bcodenull\b(3) stream instead of the standard output.]"
89
"[p:passphrase?The default passphrase for all methods requiring passphrases."
90
" The method specific \bPASSPHRASE\b=\apassphrase\a overrides the"
91
" default. If \b--passphrase\b and \bPASSPHRASE\b=\apassphrase\a are"
92
" not specified then the passphrase for each method requiring one"
93
" is prompted on and read from \b/dev/tty\b. Default to the interactive"
94
" prompt to avoid exposing passphrases to other processes.]:[passphrase]"
95
"[r:invert|reverse?Invert the method composition.]"
96
"[t:trace?Enable method trace. Equivalent to"
97
" \bexport CODEX_OPTIONS='trace=*'\b.]"
98
"[v:verbose?Enable verbose method trace. A verbose trace includes \bcodex\b(3)"
99
" discipline exception calls. Equivalent to"
100
" \bexport CODEX_OPTIONS='verbose=*'\b.]"
101
102
"\n"
103
"\n[ [ <,> ] method [ <,>,| method ... ] ]\n"
104
"\n"
105
106
"[+SEE ALSO?\bcodex\b(3), \bvcodex\b(3)]"
107
;
108
109
#include <ast.h>
110
#include <codex.h>
111
#include <option.h>
112
113
/*
114
* optget() info discipline function
115
*/
116
117
static int
118
optinfo(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
119
{
120
register Codexmeth_t* meth;
121
register const char* p;
122
register int c;
123
124
switch (*s)
125
{
126
case 'm':
127
for (meth = codexlist(NiL); meth; meth = codexlist(meth))
128
{
129
sfprintf(sp, "[+%s\b", meth->name);
130
p = " (";
131
if (meth->identf || meth->vcmeth)
132
{
133
sfprintf(sp, "%sident", p);
134
p = ",";
135
}
136
if (meth->vcmeth)
137
{
138
sfprintf(sp, "%svcodex", p);
139
p = ",";
140
}
141
else if (!(meth->flags & CODEX_ENCODE))
142
{
143
sfprintf(sp, "%sdecode", p);
144
p = ",";
145
}
146
if (*p == ',')
147
sfputc(sp, ')');
148
sfputc(sp, '?');
149
p = meth->description;
150
while (c = *p++)
151
{
152
if (c == ']')
153
sfputc(sp, c);
154
sfputc(sp, c);
155
}
156
sfputc(sp, ']');
157
if ((p = meth->options) || meth->optionsf)
158
{
159
sfprintf(sp, "{\n");
160
if (meth->optionsf)
161
(*meth->optionsf)(meth, sp);
162
if (p)
163
sfprintf(sp, "%s", p);
164
sfprintf(sp, "\n}");
165
}
166
}
167
break;
168
}
169
return 0;
170
}
171
172
static void
173
checkdata(Sfio_t* sp)
174
{
175
register unsigned char* u;
176
register unsigned char* e;
177
Codexdata_t data;
178
179
if (codexdata(sp, &data) > 0)
180
{
181
if (data.buf)
182
{
183
for (e = (u = (unsigned char*)data.buf) + data.size; u < e; u++)
184
sfprintf(sfstderr, "%02x", *u);
185
sfprintf(sfstderr, "\n");
186
}
187
else
188
sfprintf(sfstderr, "%0*I*x\n", data.size * 2, sizeof(data.num), data.num);
189
}
190
}
191
192
#if defined(main)
193
#if defined(__EXPORT__)
194
#define extern __EXPORT__
195
#endif
196
extern
197
#endif
198
199
int
200
main(int argc, register char** argv)
201
{
202
void* buf;
203
Sfio_t* ip;
204
Sfio_t* op;
205
Sfio_t* pp;
206
char* s;
207
Codexnum_t flags;
208
Optdisc_t optdisc;
209
char ident[CODEX_IDENT];
210
211
static Codexdisc_t codexdisc;
212
213
error_info.id = "codex";
214
codexinit(&codexdisc, errorf);
215
optinit(&optdisc, optinfo);
216
ip = sfstdin;
217
op = sfstdout;
218
flags = 0;
219
for (;;)
220
{
221
switch (optget(argv, usage))
222
{
223
case 'd':
224
op = 0;
225
continue;
226
case 'e':
227
ip = 0;
228
continue;
229
case 'f':
230
if (!(pp = sfopen(NiL, opt_info.arg, "r")))
231
error(ERROR_SYSTEM|3, "%s: cannot read", opt_info.arg);
232
else if (!(s = sfgetr(pp, '\n', 1)))
233
{
234
sfclose(pp);
235
error(ERROR_SYSTEM|3, "%s: read error", opt_info.arg);
236
}
237
codexdisc.passphrase = strcpy(fmtbuf(sfvalue(pp)), s);
238
sfclose(pp);
239
continue;
240
case 'i':
241
if (!(buf = sfreserve(ip, CODEX_IDENT, SF_LOCKR)) && !(buf = sfreserve(ip, sfvalue(ip), SF_LOCKR)))
242
error(ERROR_SYSTEM|3, "read error");
243
if (codexid(buf, sfvalue(ip), ident, sizeof(ident)))
244
sfprintf(op, "%s\n", ident);
245
else
246
error(2, "unknown input encoding");
247
sfread(ip, buf, 0);
248
return 0;
249
case 'n':
250
op = codexnull();
251
continue;
252
case 'p':
253
codexdisc.passphrase = opt_info.arg;
254
continue;
255
case 'r':
256
flags |= CODEX_INVERT;
257
continue;
258
case 't':
259
flags |= CODEX_TRACE;
260
continue;
261
case 'v':
262
flags |= CODEX_VERBOSE;
263
continue;
264
case ':':
265
error(2, "%s", opt_info.arg);
266
continue;
267
case '?':
268
error(ERROR_usage(2), "%s", opt_info.arg);
269
continue;
270
}
271
break;
272
}
273
argv += opt_info.index;
274
if (error_info.errors || *argv && *(argv + 1))
275
error(ERROR_usage(2), "%s", optusage(NiL));
276
if (!ip && !op)
277
ip = sfstdin;
278
if (codex(ip, op, *argv, flags, &codexdisc, NiL) < 0)
279
return 1;
280
if (!ip)
281
ip = sfstdin;
282
if (!op)
283
op = sfstdout;
284
if (sfmove(ip, op, SF_UNBOUND, -1) < 0 || !sfeof(ip) || sferror(ip))
285
error(ERROR_SYSTEM|2, "read error");
286
checkdata(ip);
287
checkdata(op);
288
if (sfsync(op) || sferror(op))
289
error(ERROR_SYSTEM|2, "write error");
290
#ifdef main
291
codexpop(ip, op, 0);
292
#endif
293
return error_info.errors != 0;
294
}
295
296