2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from many
7 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 Bacula® is a registered trademark of Kern Sibbald.
17 * Generic base 64 input and output routines
19 * Written by Kern E. Sibbald, March MM.
33 static uint8_t const base64_digits[64] =
35 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
36 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
37 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
38 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
39 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
42 static int base64_inited = 0;
43 static uint8_t base64_map[256];
46 /* Initialize the Base 64 conversion routines */
51 memset(base64_map, 0, sizeof(base64_map));
53 base64_map[(uint8_t)base64_digits[i]] = i;
57 /* Convert a value to base64 characters.
58 * The result is stored in where, which
59 * must be at least 8 characters long.
61 * Returns the number of characters
62 * stored (not including the EOS).
65 to_base64(int64_t value, char *where)
71 /* Handle negative values */
77 /* Determine output size */
85 /* Output characters */
89 where[--i] = base64_digits[val & (uint64_t)0x3F];
96 * Convert the Base 64 characters in where to
97 * a value. No checking is done on the validity
103 from_base64(int64_t *value, char *where)
110 /* Check if it is negative */
112 if (where[i] == '-') {
116 /* Construct value */
117 while (where[i] != 0 && where[i] != ' ') {
119 val += base64_map[(uint8_t)where[i++]];
122 *value = neg ? -(int64_t)val : (int64_t)val;
128 * Encode binary data in bin of len bytes into
129 * buf as base64 characters.
131 * If compatible is true, the bin_to_base64 routine will be compatible
132 * with what the rest of the world uses.
134 * Returns: the number of characters stored not
138 bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
140 uint32_t reg, save, mask;
146 buflen--; /* allow for storing EOS */
147 for (i=0; i < binlen; ) {
151 reg |= (uint8_t)bin[i++];
153 reg |= (int8_t)bin[i++];
160 buf[j++] = base64_digits[reg & 0x3F];
165 if (rem && j < buflen) {
166 mask = (1 << rem) - 1;
168 buf[j++] = base64_digits[(reg & mask) << (6 - rem)];
170 buf[j++] = base64_digits[reg & mask];
178 * Decode base64 data in bin of len bytes into
179 * buf as binary characters.
181 * the base64_to_bin routine is compatible with what the rest of the world
184 * Returns: the number of characters stored not
187 int base64_to_bin(char *dest, int dest_size, char *src, int srclen)
191 uint8_t *bufplain = (uint8_t*) dest;
192 const uint8_t *bufin;
197 if (dest_size < (((srclen + 3) / 4) * 3)) {
198 /* dest buffer too small */
203 bufin = (const uint8_t *) src;
204 while ((*bufin != ' ') && (srclen != 0)) {
209 nprbytes = bufin - (const uint8_t *) src;
210 bufin = (const uint8_t *) src;
211 bufout = (uint8_t *) bufplain;
215 *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4);
216 *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2);
217 *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]);
222 /* Bacula base64 strings are not always padded with = */
224 *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4);
227 *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2);
230 *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]);
234 return (bufout - (uint8_t *) dest);
238 int main(int argc, char *argv[])
247 for (i=0; i < 1000; i++) {
248 bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
249 printf("xx=%s\n", buf);
254 for (i=1; i<100; i++) {
255 junk[i] = junk[i-1]-1;
257 len = bin_to_base64(buf, sizeof(buf), junk, 16, true);
258 printf("len=%d junk=%s\n", len, buf);
260 strcpy(junk, "This is a sample stringa");
261 len = bin_to_base64(buf, sizeof(buf), junk, strlen(junk), true);
263 base64_to_bin(junk, sizeof(junk), buf, len);
264 printf("buf=<%s>\n", junk);
270 static int errfunc(const char *epath, int eernoo)
272 printf("in errfunc\n");
278 * Test the base64 routines by encoding and decoding
281 int main(int argc, char *argv[])
292 time_t t = 1028712799;
294 if (argc > 1 && strcmp(argv[1], "-v") == 0)
300 glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
302 for (i=0; my_glob.gl_pathv[i]; i++) {
303 fname = my_glob.gl_pathv[i];
304 if (lstat(fname, &statp) < 0) {
306 printf("Cannot stat %s: %s\n", fname, be.bstrerror(errno));
309 encode_stat(where, &statp, sizeof(statp), 0, 0);
311 printf("Encoded stat=%s\n", where);
315 p += to_base64((int64_t)(statp.st_atime), p);
317 p += to_base64((int64_t)t, p);
318 printf("%s %s\n", fname, where);
320 printf("%s %lld\n", "st_dev", (int64_t)statp.st_dev);
321 printf("%s %lld\n", "st_ino", (int64_t)statp.st_ino);
322 printf("%s %lld\n", "st_mode", (int64_t)statp.st_mode);
323 printf("%s %lld\n", "st_nlink", (int64_t)statp.st_nlink);
324 printf("%s %lld\n", "st_uid", (int64_t)statp.st_uid);
325 printf("%s %lld\n", "st_gid", (int64_t)statp.st_gid);
326 printf("%s %lld\n", "st_rdev", (int64_t)statp.st_rdev);
327 printf("%s %lld\n", "st_size", (int64_t)statp.st_size);
328 printf("%s %lld\n", "st_blksize", (int64_t)statp.st_blksize);
329 printf("%s %lld\n", "st_blocks", (int64_t)statp.st_blocks);
330 printf("%s %lld\n", "st_atime", (int64_t)statp.st_atime);
331 printf("%s %lld\n", "st_mtime", (int64_t)statp.st_mtime);
332 printf("%s %lld\n", "st_ctime", (int64_t)statp.st_ctime);
336 printf("%s: len=%d val=%s\n", fname, strlen(where), where);
338 decode_stat(where, &statn, sizeof(statn), &j);
340 if (statp.st_dev != statn.st_dev ||
341 statp.st_ino != statn.st_ino ||
342 statp.st_mode != statn.st_mode ||
343 statp.st_nlink != statn.st_nlink ||
344 statp.st_uid != statn.st_uid ||
345 statp.st_gid != statn.st_gid ||
346 statp.st_rdev != statn.st_rdev ||
347 statp.st_size != statn.st_size ||
348 statp.st_blksize != statn.st_blksize ||
349 statp.st_blocks != statn.st_blocks ||
350 statp.st_atime != statn.st_atime ||
351 statp.st_mtime != statn.st_mtime ||
352 statp.st_ctime != statn.st_ctime) {
354 printf("%s: %s\n", fname, where);
355 encode_stat(where, &statn, sizeof(statn), 0, 0);
356 printf("%s: %s\n", fname, where);
357 printf("NOT EQAL\n");
363 printf("%d files examined\n", i);
365 to_base64(UINT32_MAX, where);
366 printf("UINT32_MAX=%s\n", where);