2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
20 * Generic base 64 input and output routines
22 * Written by Kern E. Sibbald, March MM.
36 static uint8_t const base64_digits[64] =
38 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
39 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
40 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
41 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
42 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
45 static int base64_inited = 0;
46 static uint8_t base64_map[256];
49 /* Initialize the Base 64 conversion routines */
54 memset(base64_map, 0, sizeof(base64_map));
56 base64_map[(uint8_t)base64_digits[i]] = i;
60 /* Convert a value to base64 characters.
61 * The result is stored in where, which
62 * must be at least 8 characters long.
64 * Returns the number of characters
65 * stored (not including the EOS).
68 to_base64(int64_t value, char *where)
74 /* Handle negative values */
80 /* Determine output size */
88 /* Output characters */
92 where[--i] = base64_digits[val & (uint64_t)0x3F];
99 * Convert the Base 64 characters in where to
100 * a value. No checking is done on the validity
101 * of the characters!!
106 from_base64(int64_t *value, char *where)
113 /* Check if it is negative */
115 if (where[i] == '-') {
119 /* Construct value */
120 while (where[i] != 0 && where[i] != ' ') {
122 val += base64_map[(uint8_t)where[i++]];
125 *value = neg ? -(int64_t)val : (int64_t)val;
131 * Encode binary data in bin of len bytes into
132 * buf as base64 characters.
134 * If compatible is true, the bin_to_base64 routine will be compatible
135 * with what the rest of the world uses.
137 * Returns: the number of characters stored not
141 bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
143 uint32_t reg, save, mask;
149 buflen--; /* allow for storing EOS */
150 for (i=0; i < binlen; ) {
154 reg |= (uint8_t)bin[i++];
156 reg |= (int8_t)bin[i++];
163 buf[j++] = base64_digits[reg & 0x3F];
168 if (rem && j < buflen) {
169 mask = (1 << rem) - 1;
171 buf[j++] = base64_digits[(reg & mask) << (6 - rem)];
173 buf[j++] = base64_digits[reg & mask];
181 * Decode base64 data in bin of len bytes into
182 * buf as binary characters.
184 * the base64_to_bin routine is compatible with what the rest of the world
187 * Returns: the number of characters stored not
190 int base64_to_bin(char *dest, int dest_size, char *src, int srclen)
194 uint8_t *bufplain = (uint8_t*) dest;
195 const uint8_t *bufin;
200 if (dest_size < (((srclen + 3) / 4) * 3)) {
201 /* dest buffer too small */
206 bufin = (const uint8_t *) src;
207 while ((*bufin != ' ') && (srclen != 0)) {
212 nprbytes = bufin - (const uint8_t *) src;
213 bufin = (const uint8_t *) src;
214 bufout = (uint8_t *) bufplain;
218 *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4);
219 *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2);
220 *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]);
225 /* Bacula base64 strings are not always padded with = */
227 *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4);
230 *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2);
233 *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]);
237 return (bufout - (uint8_t *) dest);
241 int main(int argc, char *argv[])
250 for (i=0; i < 1000; i++) {
251 bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
252 printf("xx=%s\n", buf);
257 for (i=1; i<100; i++) {
258 junk[i] = junk[i-1]-1;
260 len = bin_to_base64(buf, sizeof(buf), junk, 16, true);
261 printf("len=%d junk=%s\n", len, buf);
263 strcpy(junk, "This is a sample stringa");
264 len = bin_to_base64(buf, sizeof(buf), junk, strlen(junk), true);
266 base64_to_bin(junk, sizeof(junk), buf, len);
267 printf("buf=<%s>\n", junk);
273 static int errfunc(const char *epath, int eernoo)
275 printf("in errfunc\n");
281 * Test the base64 routines by encoding and decoding
284 int main(int argc, char *argv[])
295 time_t t = 1028712799;
297 if (argc > 1 && strcmp(argv[1], "-v") == 0)
303 glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
305 for (i=0; my_glob.gl_pathv[i]; i++) {
306 fname = my_glob.gl_pathv[i];
307 if (lstat(fname, &statp) < 0) {
309 printf("Cannot stat %s: %s\n", fname, be.bstrerror(errno));
312 encode_stat(where, &statp, sizeof(statp), 0, 0);
314 printf("Encoded stat=%s\n", where);
318 p += to_base64((int64_t)(statp.st_atime), p);
320 p += to_base64((int64_t)t, p);
321 printf("%s %s\n", fname, where);
323 printf("%s %lld\n", "st_dev", (int64_t)statp.st_dev);
324 printf("%s %lld\n", "st_ino", (int64_t)statp.st_ino);
325 printf("%s %lld\n", "st_mode", (int64_t)statp.st_mode);
326 printf("%s %lld\n", "st_nlink", (int64_t)statp.st_nlink);
327 printf("%s %lld\n", "st_uid", (int64_t)statp.st_uid);
328 printf("%s %lld\n", "st_gid", (int64_t)statp.st_gid);
329 printf("%s %lld\n", "st_rdev", (int64_t)statp.st_rdev);
330 printf("%s %lld\n", "st_size", (int64_t)statp.st_size);
331 printf("%s %lld\n", "st_blksize", (int64_t)statp.st_blksize);
332 printf("%s %lld\n", "st_blocks", (int64_t)statp.st_blocks);
333 printf("%s %lld\n", "st_atime", (int64_t)statp.st_atime);
334 printf("%s %lld\n", "st_mtime", (int64_t)statp.st_mtime);
335 printf("%s %lld\n", "st_ctime", (int64_t)statp.st_ctime);
339 printf("%s: len=%d val=%s\n", fname, strlen(where), where);
341 decode_stat(where, &statn, sizeof(statn), &j);
343 if (statp.st_dev != statn.st_dev ||
344 statp.st_ino != statn.st_ino ||
345 statp.st_mode != statn.st_mode ||
346 statp.st_nlink != statn.st_nlink ||
347 statp.st_uid != statn.st_uid ||
348 statp.st_gid != statn.st_gid ||
349 statp.st_rdev != statn.st_rdev ||
350 statp.st_size != statn.st_size ||
351 statp.st_blksize != statn.st_blksize ||
352 statp.st_blocks != statn.st_blocks ||
353 statp.st_atime != statn.st_atime ||
354 statp.st_mtime != statn.st_mtime ||
355 statp.st_ctime != statn.st_ctime) {
357 printf("%s: %s\n", fname, where);
358 encode_stat(where, &statn, sizeof(statn), 0, 0);
359 printf("%s: %s\n", fname, where);
360 printf("NOT EQAL\n");
366 printf("%d files examined\n", i);
368 to_base64(UINT32_MAX, where);
369 printf("UINT32_MAX=%s\n", where);