2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
29 * Generic base 64 input and output routines
31 * Written by Kern E. Sibbald, March MM.
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[256];
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(int64_t value, char *where)
83 /* Handle negative values */
89 /* Determine output size */
97 /* Output characters */
101 where[--i] = base64_digits[val & (uint64_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(int64_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 ? -(int64_t)val : (int64_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 * Decode base64 data in bin of len bytes into
191 * buf as binary characters.
193 * the base64_to_bin routine is compatible with what the rest of the world
196 * Returns: the number of characters stored not
199 int base64_to_bin(char *dest, int dest_size, char *src, int srclen)
203 uint8_t *bufplain = (uint8_t*) dest;
204 const uint8_t *bufin;
209 if (dest_size < (((srclen + 3) / 4) * 3)) {
210 /* dest buffer too small */
215 bufin = (const uint8_t *) src;
216 while ((*bufin != ' ') && (srclen != 0)) {
221 nprbytes = bufin - (const uint8_t *) src;
222 bufin = (const uint8_t *) src;
223 bufout = (uint8_t *) bufplain;
227 *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4);
228 *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2);
229 *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]);
234 /* Bacula base64 strings are not always padded with = */
236 *(bufout++) = (base64_map[bufin[0]] << 2 | base64_map[bufin[1]] >> 4);
239 *(bufout++) = (base64_map[bufin[1]] << 4 | base64_map[bufin[2]] >> 2);
242 *(bufout++) = (base64_map[bufin[2]] << 6 | base64_map[bufin[3]]);
246 return (bufout - (uint8_t *) dest);
250 int main(int argc, char *argv[])
259 for (i=0; i < 1000; i++) {
260 bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
261 printf("xx=%s\n", buf);
266 for (i=1; i<100; i++) {
267 junk[i] = junk[i-1]-1;
269 len = bin_to_base64(buf, sizeof(buf), junk, 16, true);
270 printf("len=%d junk=%s\n", len, buf);
272 strcpy(junk, "This is a sample stringa");
273 len = bin_to_base64(buf, sizeof(buf), junk, strlen(junk), true);
275 base64_to_bin(junk, sizeof(junk), buf, len);
276 printf("buf=<%s>\n", junk);
282 static int errfunc(const char *epath, int eernoo)
284 printf("in errfunc\n");
290 * Test the base64 routines by encoding and decoding
293 int main(int argc, char *argv[])
304 time_t t = 1028712799;
306 if (argc > 1 && strcmp(argv[1], "-v") == 0)
312 glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
314 for (i=0; my_glob.gl_pathv[i]; i++) {
315 fname = my_glob.gl_pathv[i];
316 if (lstat(fname, &statp) < 0) {
318 printf("Cannot stat %s: %s\n", fname, be.bstrerror(errno));
321 encode_stat(where, &statp, sizeof(statp), 0, 0);
323 printf("Encoded stat=%s\n", where);
327 p += to_base64((int64_t)(statp.st_atime), p);
329 p += to_base64((int64_t)t, p);
330 printf("%s %s\n", fname, where);
332 printf("%s %lld\n", "st_dev", (int64_t)statp.st_dev);
333 printf("%s %lld\n", "st_ino", (int64_t)statp.st_ino);
334 printf("%s %lld\n", "st_mode", (int64_t)statp.st_mode);
335 printf("%s %lld\n", "st_nlink", (int64_t)statp.st_nlink);
336 printf("%s %lld\n", "st_uid", (int64_t)statp.st_uid);
337 printf("%s %lld\n", "st_gid", (int64_t)statp.st_gid);
338 printf("%s %lld\n", "st_rdev", (int64_t)statp.st_rdev);
339 printf("%s %lld\n", "st_size", (int64_t)statp.st_size);
340 printf("%s %lld\n", "st_blksize", (int64_t)statp.st_blksize);
341 printf("%s %lld\n", "st_blocks", (int64_t)statp.st_blocks);
342 printf("%s %lld\n", "st_atime", (int64_t)statp.st_atime);
343 printf("%s %lld\n", "st_mtime", (int64_t)statp.st_mtime);
344 printf("%s %lld\n", "st_ctime", (int64_t)statp.st_ctime);
348 printf("%s: len=%d val=%s\n", fname, strlen(where), where);
350 decode_stat(where, &statn, sizeof(statn), &j);
352 if (statp.st_dev != statn.st_dev ||
353 statp.st_ino != statn.st_ino ||
354 statp.st_mode != statn.st_mode ||
355 statp.st_nlink != statn.st_nlink ||
356 statp.st_uid != statn.st_uid ||
357 statp.st_gid != statn.st_gid ||
358 statp.st_rdev != statn.st_rdev ||
359 statp.st_size != statn.st_size ||
360 statp.st_blksize != statn.st_blksize ||
361 statp.st_blocks != statn.st_blocks ||
362 statp.st_atime != statn.st_atime ||
363 statp.st_mtime != statn.st_mtime ||
364 statp.st_ctime != statn.st_ctime) {
366 printf("%s: %s\n", fname, where);
367 encode_stat(where, &statn, sizeof(statn), 0, 0);
368 printf("%s: %s\n", fname, where);
369 printf("NOT EQAL\n");
375 printf("%d files examined\n", i);
377 to_base64(UINT32_MAX, where);
378 printf("UINT32_MAX=%s\n", where);