1*ebfedea0SLionel Sambuc /*********************************************************************\
2*ebfedea0SLionel Sambuc
3*ebfedea0SLionel Sambuc MODULE NAME: b64.c
4*ebfedea0SLionel Sambuc
5*ebfedea0SLionel Sambuc AUTHOR: Bob Trower 08/04/01
6*ebfedea0SLionel Sambuc
7*ebfedea0SLionel Sambuc PROJECT: Crypt Data Packaging
8*ebfedea0SLionel Sambuc
9*ebfedea0SLionel Sambuc COPYRIGHT: Copyright (c) Trantor Standard Systems Inc., 2001
10*ebfedea0SLionel Sambuc
11*ebfedea0SLionel Sambuc NOTE: This source code may be used as you wish, subject to
12*ebfedea0SLionel Sambuc the MIT license. See the LICENCE section below.
13*ebfedea0SLionel Sambuc
14*ebfedea0SLionel Sambuc DESCRIPTION:
15*ebfedea0SLionel Sambuc This little utility implements the Base64
16*ebfedea0SLionel Sambuc Content-Transfer-Encoding standard described in
17*ebfedea0SLionel Sambuc RFC1113 (http://www.faqs.org/rfcs/rfc1113.html).
18*ebfedea0SLionel Sambuc
19*ebfedea0SLionel Sambuc This is the coding scheme used by MIME to allow
20*ebfedea0SLionel Sambuc binary data to be transferred by SMTP mail.
21*ebfedea0SLionel Sambuc
22*ebfedea0SLionel Sambuc Groups of 3 bytes from a binary stream are coded as
23*ebfedea0SLionel Sambuc groups of 4 bytes in a text stream.
24*ebfedea0SLionel Sambuc
25*ebfedea0SLionel Sambuc The input stream is 'padded' with zeros to create
26*ebfedea0SLionel Sambuc an input that is an even multiple of 3.
27*ebfedea0SLionel Sambuc
28*ebfedea0SLionel Sambuc A special character ('=') is used to denote padding so
29*ebfedea0SLionel Sambuc that the stream can be decoded back to its exact size.
30*ebfedea0SLionel Sambuc
31*ebfedea0SLionel Sambuc Encoded output is formatted in lines which should
32*ebfedea0SLionel Sambuc be a maximum of 72 characters to conform to the
33*ebfedea0SLionel Sambuc specification. This program defaults to 72 characters,
34*ebfedea0SLionel Sambuc but will allow more or less through the use of a
35*ebfedea0SLionel Sambuc switch. The program enforces a minimum line size
36*ebfedea0SLionel Sambuc of 4 characters.
37*ebfedea0SLionel Sambuc
38*ebfedea0SLionel Sambuc Example encoding:
39*ebfedea0SLionel Sambuc
40*ebfedea0SLionel Sambuc The stream 'ABCD' is 32 bits long. It is mapped as
41*ebfedea0SLionel Sambuc follows:
42*ebfedea0SLionel Sambuc
43*ebfedea0SLionel Sambuc ABCD
44*ebfedea0SLionel Sambuc
45*ebfedea0SLionel Sambuc A (65) B (66) C (67) D (68) (None) (None)
46*ebfedea0SLionel Sambuc 01000001 01000010 01000011 01000100
47*ebfedea0SLionel Sambuc
48*ebfedea0SLionel Sambuc 16 (Q) 20 (U) 9 (J) 3 (D) 17 (R) 0 (A) NA (=) NA (=)
49*ebfedea0SLionel Sambuc 010000 010100 001001 000011 010001 000000 000000 000000
50*ebfedea0SLionel Sambuc
51*ebfedea0SLionel Sambuc
52*ebfedea0SLionel Sambuc QUJDRA==
53*ebfedea0SLionel Sambuc
54*ebfedea0SLionel Sambuc Decoding is the process in reverse. A 'decode' lookup
55*ebfedea0SLionel Sambuc table has been created to avoid string scans.
56*ebfedea0SLionel Sambuc
57*ebfedea0SLionel Sambuc DESIGN GOALS: Specifically:
58*ebfedea0SLionel Sambuc Code is a stand-alone utility to perform base64
59*ebfedea0SLionel Sambuc encoding/decoding. It should be genuinely useful
60*ebfedea0SLionel Sambuc when the need arises and it meets a need that is
61*ebfedea0SLionel Sambuc likely to occur for some users.
62*ebfedea0SLionel Sambuc Code acts as sample code to show the author's
63*ebfedea0SLionel Sambuc design and coding style.
64*ebfedea0SLionel Sambuc
65*ebfedea0SLionel Sambuc Generally:
66*ebfedea0SLionel Sambuc This program is designed to survive:
67*ebfedea0SLionel Sambuc Everything you need is in a single source file.
68*ebfedea0SLionel Sambuc It compiles cleanly using a vanilla ANSI C compiler.
69*ebfedea0SLionel Sambuc It does its job correctly with a minimum of fuss.
70*ebfedea0SLionel Sambuc The code is not overly clever, not overly simplistic
71*ebfedea0SLionel Sambuc and not overly verbose.
72*ebfedea0SLionel Sambuc Access is 'cut and paste' from a web page.
73*ebfedea0SLionel Sambuc Terms of use are reasonable.
74*ebfedea0SLionel Sambuc
75*ebfedea0SLionel Sambuc VALIDATION: Non-trivial code is never without errors. This
76*ebfedea0SLionel Sambuc file likely has some problems, since it has only
77*ebfedea0SLionel Sambuc been tested by the author. It is expected with most
78*ebfedea0SLionel Sambuc source code that there is a period of 'burn-in' when
79*ebfedea0SLionel Sambuc problems are identified and corrected. That being
80*ebfedea0SLionel Sambuc said, it is possible to have 'reasonably correct'
81*ebfedea0SLionel Sambuc code by following a regime of unit test that covers
82*ebfedea0SLionel Sambuc the most likely cases and regression testing prior
83*ebfedea0SLionel Sambuc to release. This has been done with this code and
84*ebfedea0SLionel Sambuc it has a good probability of performing as expected.
85*ebfedea0SLionel Sambuc
86*ebfedea0SLionel Sambuc Unit Test Cases:
87*ebfedea0SLionel Sambuc
88*ebfedea0SLionel Sambuc case 0:empty file:
89*ebfedea0SLionel Sambuc CASE0.DAT -> ->
90*ebfedea0SLionel Sambuc (Zero length target file created
91*ebfedea0SLionel Sambuc on both encode and decode.)
92*ebfedea0SLionel Sambuc
93*ebfedea0SLionel Sambuc case 1:One input character:
94*ebfedea0SLionel Sambuc CASE1.DAT A -> QQ== -> A
95*ebfedea0SLionel Sambuc
96*ebfedea0SLionel Sambuc case 2:Two input characters:
97*ebfedea0SLionel Sambuc CASE2.DAT AB -> QUJD -> AB
98*ebfedea0SLionel Sambuc
99*ebfedea0SLionel Sambuc case 3:Three input characters:
100*ebfedea0SLionel Sambuc CASE3.DAT ABC -> QUJD -> ABC
101*ebfedea0SLionel Sambuc
102*ebfedea0SLionel Sambuc case 4:Four input characters:
103*ebfedea0SLionel Sambuc case4.dat ABCD -> QUJDRA== -> ABCD
104*ebfedea0SLionel Sambuc
105*ebfedea0SLionel Sambuc case 5:All chars from 0 to ff, linesize set to 50:
106*ebfedea0SLionel Sambuc
107*ebfedea0SLionel Sambuc AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIj
108*ebfedea0SLionel Sambuc JCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZH
109*ebfedea0SLionel Sambuc SElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr
110*ebfedea0SLionel Sambuc bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6P
111*ebfedea0SLionel Sambuc kJGSk5SVlpeYmZqbnJ2en6ChoqOkpaanqKmqq6ytrq+wsbKz
112*ebfedea0SLionel Sambuc tLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX
113*ebfedea0SLionel Sambuc 2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7
114*ebfedea0SLionel Sambuc /P3+/w==
115*ebfedea0SLionel Sambuc
116*ebfedea0SLionel Sambuc case 6:Mime Block from e-mail:
117*ebfedea0SLionel Sambuc (Data same as test case 5)
118*ebfedea0SLionel Sambuc
119*ebfedea0SLionel Sambuc case 7: Large files:
120*ebfedea0SLionel Sambuc Tested 28 MB file in/out.
121*ebfedea0SLionel Sambuc
122*ebfedea0SLionel Sambuc case 8: Random Binary Integrity:
123*ebfedea0SLionel Sambuc This binary program (b64.exe) was encoded to base64,
124*ebfedea0SLionel Sambuc back to binary and then executed.
125*ebfedea0SLionel Sambuc
126*ebfedea0SLionel Sambuc case 9 Stress:
127*ebfedea0SLionel Sambuc All files in a working directory encoded/decoded
128*ebfedea0SLionel Sambuc and compared with file comparison utility to
129*ebfedea0SLionel Sambuc ensure that multiple runs do not cause problems
130*ebfedea0SLionel Sambuc such as exhausting file handles, tmp storage, etc.
131*ebfedea0SLionel Sambuc
132*ebfedea0SLionel Sambuc -------------
133*ebfedea0SLionel Sambuc
134*ebfedea0SLionel Sambuc Syntax, operation and failure:
135*ebfedea0SLionel Sambuc All options/switches tested. Performs as
136*ebfedea0SLionel Sambuc expected.
137*ebfedea0SLionel Sambuc
138*ebfedea0SLionel Sambuc case 10:
139*ebfedea0SLionel Sambuc No Args -- Shows Usage Screen
140*ebfedea0SLionel Sambuc Return Code 1 (Invalid Syntax)
141*ebfedea0SLionel Sambuc case 11:
142*ebfedea0SLionel Sambuc One Arg (invalid) -- Shows Usage Screen
143*ebfedea0SLionel Sambuc Return Code 1 (Invalid Syntax)
144*ebfedea0SLionel Sambuc case 12:
145*ebfedea0SLionel Sambuc One Arg Help (-?) -- Shows detailed Usage Screen.
146*ebfedea0SLionel Sambuc Return Code 0 (Success -- help request is valid).
147*ebfedea0SLionel Sambuc case 13:
148*ebfedea0SLionel Sambuc One Arg Help (-h) -- Shows detailed Usage Screen.
149*ebfedea0SLionel Sambuc Return Code 0 (Success -- help request is valid).
150*ebfedea0SLionel Sambuc case 14:
151*ebfedea0SLionel Sambuc One Arg (valid) -- Uses stdin/stdout (filter)
152*ebfedea0SLionel Sambuc Return Code 0 (Sucess)
153*ebfedea0SLionel Sambuc case 15:
154*ebfedea0SLionel Sambuc Two Args (invalid file) -- shows system error.
155*ebfedea0SLionel Sambuc Return Code 2 (File Error)
156*ebfedea0SLionel Sambuc case 16:
157*ebfedea0SLionel Sambuc Encode non-existent file -- shows system error.
158*ebfedea0SLionel Sambuc Return Code 2 (File Error)
159*ebfedea0SLionel Sambuc case 17:
160*ebfedea0SLionel Sambuc Out of disk space -- shows system error.
161*ebfedea0SLionel Sambuc Return Code 3 (File I/O Error)
162*ebfedea0SLionel Sambuc
163*ebfedea0SLionel Sambuc -------------
164*ebfedea0SLionel Sambuc
165*ebfedea0SLionel Sambuc Compile/Regression test:
166*ebfedea0SLionel Sambuc gcc compiled binary under Cygwin
167*ebfedea0SLionel Sambuc Microsoft Visual Studio under Windows 2000
168*ebfedea0SLionel Sambuc Microsoft Version 6.0 C under Windows 2000
169*ebfedea0SLionel Sambuc
170*ebfedea0SLionel Sambuc DEPENDENCIES: None
171*ebfedea0SLionel Sambuc
172*ebfedea0SLionel Sambuc LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc.
173*ebfedea0SLionel Sambuc
174*ebfedea0SLionel Sambuc Permission is hereby granted, free of charge, to any person
175*ebfedea0SLionel Sambuc obtaining a copy of this software and associated
176*ebfedea0SLionel Sambuc documentation files (the "Software"), to deal in the
177*ebfedea0SLionel Sambuc Software without restriction, including without limitation
178*ebfedea0SLionel Sambuc the rights to use, copy, modify, merge, publish, distribute,
179*ebfedea0SLionel Sambuc sublicense, and/or sell copies of the Software, and to
180*ebfedea0SLionel Sambuc permit persons to whom the Software is furnished to do so,
181*ebfedea0SLionel Sambuc subject to the following conditions:
182*ebfedea0SLionel Sambuc
183*ebfedea0SLionel Sambuc The above copyright notice and this permission notice shall
184*ebfedea0SLionel Sambuc be included in all copies or substantial portions of the
185*ebfedea0SLionel Sambuc Software.
186*ebfedea0SLionel Sambuc
187*ebfedea0SLionel Sambuc THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
188*ebfedea0SLionel Sambuc KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
189*ebfedea0SLionel Sambuc WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
190*ebfedea0SLionel Sambuc PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
191*ebfedea0SLionel Sambuc OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
192*ebfedea0SLionel Sambuc OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
193*ebfedea0SLionel Sambuc OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
194*ebfedea0SLionel Sambuc SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
195*ebfedea0SLionel Sambuc
196*ebfedea0SLionel Sambuc VERSION HISTORY:
197*ebfedea0SLionel Sambuc Bob Trower 08/04/01 -- Create Version 0.00.00B
198*ebfedea0SLionel Sambuc
199*ebfedea0SLionel Sambuc \******************************************************************* */
200*ebfedea0SLionel Sambuc
201*ebfedea0SLionel Sambuc #include <inttypes.h>
202*ebfedea0SLionel Sambuc #include <stdio.h>
203*ebfedea0SLionel Sambuc #include <stdlib.h>
204*ebfedea0SLionel Sambuc
205*ebfedea0SLionel Sambuc #include "b64.h"
206*ebfedea0SLionel Sambuc
207*ebfedea0SLionel Sambuc /*
208*ebfedea0SLionel Sambuc ** Translation Table as described in RFC1113
209*ebfedea0SLionel Sambuc */
210*ebfedea0SLionel Sambuc static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
211*ebfedea0SLionel Sambuc
212*ebfedea0SLionel Sambuc /*
213*ebfedea0SLionel Sambuc ** Translation Table to decode (created by author)
214*ebfedea0SLionel Sambuc */
215*ebfedea0SLionel Sambuc static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
216*ebfedea0SLionel Sambuc
217*ebfedea0SLionel Sambuc /*
218*ebfedea0SLionel Sambuc ** encodeblock
219*ebfedea0SLionel Sambuc **
220*ebfedea0SLionel Sambuc ** encode 3 8-bit binary bytes as 4 '6-bit' characters
221*ebfedea0SLionel Sambuc */
222*ebfedea0SLionel Sambuc static void
encodeblock(uint8_t * wordin,uint8_t * wordout,int wordlen)223*ebfedea0SLionel Sambuc encodeblock(uint8_t *wordin, uint8_t *wordout, int wordlen)
224*ebfedea0SLionel Sambuc {
225*ebfedea0SLionel Sambuc wordout[0] = cb64[(unsigned)wordin[0] >> 2];
226*ebfedea0SLionel Sambuc wordout[1] = cb64[((unsigned)(wordin[0] & 0x03) << 4) | ((unsigned)(wordin[1] & 0xf0) >> 4)];
227*ebfedea0SLionel Sambuc wordout[2] = (uint8_t)(wordlen > 1) ?
228*ebfedea0SLionel Sambuc cb64[((unsigned)(wordin[1] & 0x0f) << 2) | ((unsigned)(wordin[2] & 0xc0) >> 6)] : '=';
229*ebfedea0SLionel Sambuc wordout[3] = (uint8_t)(wordlen > 2) ? cb64[wordin[2] & 0x3f] : '=';
230*ebfedea0SLionel Sambuc }
231*ebfedea0SLionel Sambuc
232*ebfedea0SLionel Sambuc /*
233*ebfedea0SLionel Sambuc ** encode
234*ebfedea0SLionel Sambuc **
235*ebfedea0SLionel Sambuc ** base64 encode a stream adding padding and line breaks as per spec.
236*ebfedea0SLionel Sambuc */
237*ebfedea0SLionel Sambuc int
b64encode(const char * in,const size_t insize,void * vp,size_t outsize,int linesize)238*ebfedea0SLionel Sambuc b64encode(const char *in, const size_t insize, void *vp, size_t outsize, int linesize)
239*ebfedea0SLionel Sambuc {
240*ebfedea0SLionel Sambuc const char *inp;
241*ebfedea0SLionel Sambuc unsigned i;
242*ebfedea0SLionel Sambuc uint8_t wordout[4];
243*ebfedea0SLionel Sambuc uint8_t wordin[3];
244*ebfedea0SLionel Sambuc char *out = vp;
245*ebfedea0SLionel Sambuc char *outp;
246*ebfedea0SLionel Sambuc int blocksout;
247*ebfedea0SLionel Sambuc int wordlen;
248*ebfedea0SLionel Sambuc
249*ebfedea0SLionel Sambuc wordlen = 0;
250*ebfedea0SLionel Sambuc for (blocksout = 0, inp = in, outp = out; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize;) {
251*ebfedea0SLionel Sambuc for (wordlen = 0, i = 0; i < sizeof(wordin); i++) {
252*ebfedea0SLionel Sambuc wordin[i] = (uint8_t) *inp++;
253*ebfedea0SLionel Sambuc if ((size_t)(inp - in) <= insize) {
254*ebfedea0SLionel Sambuc wordlen++;
255*ebfedea0SLionel Sambuc } else {
256*ebfedea0SLionel Sambuc wordin[i] = 0x0;
257*ebfedea0SLionel Sambuc }
258*ebfedea0SLionel Sambuc }
259*ebfedea0SLionel Sambuc if (wordlen > 0) {
260*ebfedea0SLionel Sambuc encodeblock(wordin, wordout, wordlen);
261*ebfedea0SLionel Sambuc for (i = 0; i < sizeof(wordout) ; i++) {
262*ebfedea0SLionel Sambuc *outp++ = wordout[i];
263*ebfedea0SLionel Sambuc }
264*ebfedea0SLionel Sambuc blocksout++;
265*ebfedea0SLionel Sambuc }
266*ebfedea0SLionel Sambuc if (linesize > 0) {
267*ebfedea0SLionel Sambuc if (blocksout >= (int)(linesize / sizeof(wordout)) ||
268*ebfedea0SLionel Sambuc (size_t)(inp - in) >= insize) {
269*ebfedea0SLionel Sambuc if (blocksout) {
270*ebfedea0SLionel Sambuc *outp++ = '\r';
271*ebfedea0SLionel Sambuc *outp++ = '\n';
272*ebfedea0SLionel Sambuc }
273*ebfedea0SLionel Sambuc blocksout = 0;
274*ebfedea0SLionel Sambuc }
275*ebfedea0SLionel Sambuc }
276*ebfedea0SLionel Sambuc }
277*ebfedea0SLionel Sambuc return (int)(outp - out);
278*ebfedea0SLionel Sambuc }
279*ebfedea0SLionel Sambuc
280*ebfedea0SLionel Sambuc /*
281*ebfedea0SLionel Sambuc ** decodeblock
282*ebfedea0SLionel Sambuc **
283*ebfedea0SLionel Sambuc ** decode 4 '6-bit' characters into 3 8-bit binary bytes
284*ebfedea0SLionel Sambuc */
285*ebfedea0SLionel Sambuc static void
decodeblock(uint8_t wordin[4],uint8_t wordout[3])286*ebfedea0SLionel Sambuc decodeblock(uint8_t wordin[4], uint8_t wordout[3])
287*ebfedea0SLionel Sambuc {
288*ebfedea0SLionel Sambuc wordout[0] = (uint8_t) ((unsigned)wordin[0] << 2 | (unsigned)wordin[1] >> 4);
289*ebfedea0SLionel Sambuc wordout[1] = (uint8_t) ((unsigned)wordin[1] << 4 | (unsigned)wordin[2] >> 2);
290*ebfedea0SLionel Sambuc wordout[2] = (uint8_t) (((wordin[2] << 6) & 0xc0) | wordin[3]);
291*ebfedea0SLionel Sambuc }
292*ebfedea0SLionel Sambuc
293*ebfedea0SLionel Sambuc /*
294*ebfedea0SLionel Sambuc ** decode
295*ebfedea0SLionel Sambuc **
296*ebfedea0SLionel Sambuc ** decode a base64 encoded stream discarding padding, line breaks and noise
297*ebfedea0SLionel Sambuc */
298*ebfedea0SLionel Sambuc int
b64decode(const char * in,const size_t insize,void * vp,size_t outsize)299*ebfedea0SLionel Sambuc b64decode(const char *in, const size_t insize, void *vp, size_t outsize)
300*ebfedea0SLionel Sambuc {
301*ebfedea0SLionel Sambuc const char *inp;
302*ebfedea0SLionel Sambuc unsigned wordlen;
303*ebfedea0SLionel Sambuc unsigned i;
304*ebfedea0SLionel Sambuc uint8_t wordout[3];
305*ebfedea0SLionel Sambuc uint8_t wordin[4];
306*ebfedea0SLionel Sambuc uint8_t v;
307*ebfedea0SLionel Sambuc char *out = vp;
308*ebfedea0SLionel Sambuc char *outp;
309*ebfedea0SLionel Sambuc
310*ebfedea0SLionel Sambuc for (inp = in, outp = out ; (size_t)(inp - in) < insize && (size_t)(outp - out) < outsize ; ) {
311*ebfedea0SLionel Sambuc for (wordlen = 0, i = 0 ; i < sizeof(wordin) && (size_t)(inp - in) < insize ; i++) {
312*ebfedea0SLionel Sambuc /* get a single character */
313*ebfedea0SLionel Sambuc for (v = 0; (size_t)(inp - in) <= insize && v == 0 ; ) {
314*ebfedea0SLionel Sambuc if (*inp == '\r' && *(inp + 1) == '\n') {
315*ebfedea0SLionel Sambuc inp += 2;
316*ebfedea0SLionel Sambuc } else {
317*ebfedea0SLionel Sambuc v = (uint8_t) *inp++;
318*ebfedea0SLionel Sambuc v = (uint8_t) ((v < 43 || v > 122) ? 0 : cd64[v - 43]);
319*ebfedea0SLionel Sambuc if (v) {
320*ebfedea0SLionel Sambuc v = (uint8_t) ((v == '$') ? 0 : v - 61);
321*ebfedea0SLionel Sambuc }
322*ebfedea0SLionel Sambuc }
323*ebfedea0SLionel Sambuc }
324*ebfedea0SLionel Sambuc /* perhaps 0x0 pad */
325*ebfedea0SLionel Sambuc if ((size_t)(inp - in) <= insize) {
326*ebfedea0SLionel Sambuc wordlen += 1;
327*ebfedea0SLionel Sambuc if (v) {
328*ebfedea0SLionel Sambuc wordin[i] = (uint8_t) (v - 1);
329*ebfedea0SLionel Sambuc }
330*ebfedea0SLionel Sambuc } else {
331*ebfedea0SLionel Sambuc wordin[i] = 0x0;
332*ebfedea0SLionel Sambuc }
333*ebfedea0SLionel Sambuc }
334*ebfedea0SLionel Sambuc if (wordlen > 0) {
335*ebfedea0SLionel Sambuc decodeblock(wordin, wordout);
336*ebfedea0SLionel Sambuc for (i = 0; i < wordlen - 1 ; i++) {
337*ebfedea0SLionel Sambuc *outp++ = wordout[i];
338*ebfedea0SLionel Sambuc }
339*ebfedea0SLionel Sambuc }
340*ebfedea0SLionel Sambuc }
341*ebfedea0SLionel Sambuc return (int)(outp - out);
342*ebfedea0SLionel Sambuc }
343