2 * Generic base 64 input and output routines
4 * Written by Kern E. Sibbald, March MM.
9 Bacula® - The Network Backup Solution
11 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
13 The main author of Bacula is Kern Sibbald, with contributions from
14 many others, a complete list can be found in the file AUTHORS.
15 This program is Free Software; you can redistribute it and/or
16 modify it under the terms of version two of the GNU General Public
17 License as published by the Free Software Foundation plus additions
18 that are listed in the file LICENSE.
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
30 Bacula® is a registered trademark of John Walker.
31 The licensor of Bacula is the Free Software Foundation Europe
32 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
33 Switzerland, email:ftf@fsfeurope.org.
45 static uint8_t const base64_digits[64] =
47 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
48 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
49 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
50 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
51 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
54 static int base64_inited = 0;
55 static uint8_t base64_map[128];
58 /* Initialize the Base 64 conversion routines */
63 memset(base64_map, 0, sizeof(base64_map));
65 base64_map[(uint8_t)base64_digits[i]] = i;
69 /* Convert a value to base64 characters.
70 * The result is stored in where, which
71 * must be at least 8 characters long.
73 * Returns the number of characters
74 * stored (not including the EOS).
77 to_base64(intmax_t value, char *where)
83 /* Handle negative values */
89 /* Determine output size */
97 /* Output characters */
101 where[--i] = base64_digits[val & (uintmax_t)0x3F];
108 * Convert the Base 64 characters in where to
109 * a value. No checking is done on the validity
110 * of the characters!!
115 from_base64(intmax_t *value, char *where)
122 /* Check if it is negative */
124 if (where[i] == '-') {
128 /* Construct value */
129 while (where[i] != 0 && where[i] != ' ') {
131 val += base64_map[(uint8_t)where[i++]];
134 *value = neg ? -(intmax_t)val : (intmax_t)val;
140 * Encode binary data in bin of len bytes into
141 * buf as base64 characters.
143 * If compatible is true, the bin_to_base64 routine will be compatible
144 * with what the rest of the world uses.
146 * Returns: the number of characters stored not
150 bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
152 uint32_t reg, save, mask;
158 buflen--; /* allow for storing EOS */
159 for (i=0; i < binlen; ) {
163 reg |= (uint8_t)bin[i++];
165 reg |= (int8_t)bin[i++];
172 buf[j++] = base64_digits[reg & 0x3F];
177 if (rem && j < buflen) {
178 mask = (1 << rem) - 1;
180 buf[j++] = base64_digits[(reg & mask) << 6 - rem];
182 buf[j++] = base64_digits[reg & mask];
190 int main(int argc, char *argv[])
199 for (i=0; i < 1000; i++) {
200 bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
201 printf("xx=%s\n", buf);
206 for (i=1; i<100; i++) {
207 junk[i] = junk[i-1]-1;
209 len = bin_to_base64(buf, sizeof(buf) junk, 16, true);
210 printf("len=%d junk=%s\n", len, buf);
216 static int errfunc(const char *epath, int eernoo)
218 printf("in errfunc\n");
224 * Test the base64 routines by encoding and decoding
227 int main(int argc, char *argv[])
237 time_t t = 1028712799;
239 if (argc > 1 && strcmp(argv[1], "-v") == 0)
245 glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
247 for (i=0; my_glob.gl_pathv[i]; i++) {
248 fname = my_glob.gl_pathv[i];
249 if (lstat(fname, &statp) < 0) {
250 printf("Cannot stat %s: %s\n", fname, strerror(errno));
253 encode_stat(where, &statp);
255 printf("Encoded stat=%s\n", where);
259 p += to_base64((intmax_t)(statp.st_atime), p);
261 p += to_base64((intmax_t)t, p);
262 printf("%s %s\n", fname, where);
264 printf("%s %lld\n", "st_dev", (intmax_t)statp.st_dev);
265 printf("%s %lld\n", "st_ino", (intmax_t)statp.st_ino);
266 printf("%s %lld\n", "st_mode", (intmax_t)statp.st_mode);
267 printf("%s %lld\n", "st_nlink", (intmax_t)statp.st_nlink);
268 printf("%s %lld\n", "st_uid", (intmax_t)statp.st_uid);
269 printf("%s %lld\n", "st_gid", (intmax_t)statp.st_gid);
270 printf("%s %lld\n", "st_rdev", (intmax_t)statp.st_rdev);
271 printf("%s %lld\n", "st_size", (intmax_t)statp.st_size);
272 printf("%s %lld\n", "st_blksize", (intmax_t)statp.st_blksize);
273 printf("%s %lld\n", "st_blocks", (intmax_t)statp.st_blocks);
274 printf("%s %lld\n", "st_atime", (intmax_t)statp.st_atime);
275 printf("%s %lld\n", "st_mtime", (intmax_t)statp.st_mtime);
276 printf("%s %lld\n", "st_ctime", (intmax_t)statp.st_ctime);
280 printf("%s: len=%d val=%s\n", fname, strlen(where), where);
282 decode_stat(where, &statn);
284 if (statp.st_dev != statn.st_dev ||
285 statp.st_ino != statn.st_ino ||
286 statp.st_mode != statn.st_mode ||
287 statp.st_nlink != statn.st_nlink ||
288 statp.st_uid != statn.st_uid ||
289 statp.st_gid != statn.st_gid ||
290 statp.st_rdev != statn.st_rdev ||
291 statp.st_size != statn.st_size ||
292 statp.st_blksize != statn.st_blksize ||
293 statp.st_blocks != statn.st_blocks ||
294 statp.st_atime != statn.st_atime ||
295 statp.st_mtime != statn.st_mtime ||
296 statp.st_ctime != statn.st_ctime) {
298 printf("%s: %s\n", fname, where);
299 encode_stat(where, &statn);
300 printf("%s: %s\n", fname, where);
301 printf("NOT EQAL\n");
307 printf("%d files examined\n", i);
309 to_base64(UINT32_MAX, where);
310 printf("UINT32_MAX=%s\n", where);