blob: 0aedf3387a0975eff780e7baee5e2182c926a16a [file] [log] [blame]
Denis Vlasenko21afc7d2006-09-03 15:49:40 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Copyright 2006 Rob Landley <rob@landley.net>
4 *
5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
6 */
7
8#include "libbb.h"
9
10/* Conversion table. for base 64 */
Denis Vlasenko6ca409e2007-08-12 20:58:27 +000011const char bb_uuenc_tbl_base64[65 + 2] ALIGN1 = {
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000012 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
13 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
14 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
15 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
16 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
17 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
18 'w', 'x', 'y', 'z', '0', '1', '2', '3',
19 '4', '5', '6', '7', '8', '9', '+', '/',
Denis Vlasenkoaa198dd2007-06-12 07:24:11 +000020 '=' /* termination character */,
21 '\n', '\0' /* needed for uudecode.c */
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000022};
23
Denis Vlasenko6ca409e2007-08-12 20:58:27 +000024const char bb_uuenc_tbl_std[65] ALIGN1 = {
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000025 '`', '!', '"', '#', '$', '%', '&', '\'',
26 '(', ')', '*', '+', ',', '-', '.', '/',
27 '0', '1', '2', '3', '4', '5', '6', '7',
28 '8', '9', ':', ';', '<', '=', '>', '?',
29 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
30 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
31 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
32 'X', 'Y', 'Z', '[', '\\', ']', '^', '_',
33 '`' /* termination character */
34};
35
36/*
Denis Vlasenkoe8240f12007-06-26 15:59:37 +000037 * Encode bytes at S of length LENGTH to uuencode or base64 format and place it
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000038 * to STORE. STORE will be 0-terminated, and must point to a writable
39 * buffer of at least 1+BASE64_LENGTH(length) bytes.
40 * where BASE64_LENGTH(len) = (4 * ((LENGTH + 2) / 3))
41 */
Denis Vlasenko46611172007-08-06 15:43:17 +000042void bb_uuencode(char *p, const void *src, int length, const char *tbl)
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000043{
Denis Vlasenkoe8240f12007-06-26 15:59:37 +000044 const unsigned char *s = src;
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000045
Denis Vlasenko46611172007-08-06 15:43:17 +000046 /* Transform the 3x8 bits to 4x6 bits */
47 while (length > 0) {
48 unsigned s1, s2;
49
50 /* Are s[1], s[2] valid or should be assumed 0? */
51 s1 = s2 = 0;
52 length -= 3; /* can be >=0, -1, -2 */
Denis Vlasenkoe5dbba22007-08-06 15:49:12 +000053 if (length >= -1) {
Denis Vlasenko46611172007-08-06 15:43:17 +000054 s1 = s[1];
Denis Vlasenkoe5dbba22007-08-06 15:49:12 +000055 if (length >= 0)
Denis Vlasenko46611172007-08-06 15:43:17 +000056 s2 = s[2];
57 }
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000058 *p++ = tbl[s[0] >> 2];
Denis Vlasenko46611172007-08-06 15:43:17 +000059 *p++ = tbl[((s[0] & 3) << 4) + (s1 >> 4)];
60 *p++ = tbl[((s1 & 0xf) << 2) + (s2 >> 6)];
61 *p++ = tbl[s2 & 0x3f];
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000062 s += 3;
63 }
Denis Vlasenko46611172007-08-06 15:43:17 +000064 /* Zero-terminate */
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000065 *p = '\0';
Denis Vlasenko46611172007-08-06 15:43:17 +000066 /* If length is -2 or -1, pad last char or two */
67 while (length) {
68 *--p = tbl[64];
69 length++;
70 }
Denis Vlasenko21afc7d2006-09-03 15:49:40 +000071}