]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/base64.c
kes If doing a mount, look for a slot, and if specified pass it to
[bacula/bacula] / bacula / src / lib / base64.c
1 /*
2  *   Generic base 64 input and output routines
3  *
4  *    Written by Kern E. Sibbald, March MM.
5  *
6  *   Version $Id$
7  */
8 /*
9    Copyright (C) 2000-2006 Kern Sibbald
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License
13    version 2 as amended with additional clauses defined in the
14    file LICENSE in the main source directory.
15
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
19    the file LICENSE for additional details.
20
21  */
22
23
24 #include "bacula.h"
25
26
27 #ifdef TEST_MODE
28 #include <glob.h>
29 #endif
30
31
32 static uint8_t const base64_digits[64] =
33 {
34   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
35   'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
36   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
37   'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
38   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
39 };
40
41 static int base64_inited = 0;
42 static uint8_t base64_map[128];
43
44
45 /* Initialize the Base 64 conversion routines */
46 void
47 base64_init(void)
48 {
49    int i;
50    memset(base64_map, 0, sizeof(base64_map));
51    for (i=0; i<64; i++)
52       base64_map[(uint8_t)base64_digits[i]] = i;
53    base64_inited = 1;
54 }
55
56 /* Convert a value to base64 characters.
57  * The result is stored in where, which
58  * must be at least 8 characters long.
59  *
60  * Returns the number of characters
61  * stored (not including the EOS).
62  */
63 int
64 to_base64(intmax_t value, char *where)
65 {
66    uintmax_t val;
67    int i = 0;
68    int n;
69
70    /* Handle negative values */
71    if (value < 0) {
72       where[i++] = '-';
73       value = -value;
74    }
75
76    /* Determine output size */
77    val = value;
78    do {
79       val >>= 6;
80       i++;
81    } while (val);
82    n = i;
83
84    /* Output characters */
85    val = value;
86    where[i] = 0;
87    do {
88       where[--i] = base64_digits[val & (uintmax_t)0x3F];
89       val >>= 6;
90    } while (val);
91    return n;
92 }
93
94 /*
95  * Convert the Base 64 characters in where to
96  * a value. No checking is done on the validity
97  * of the characters!!
98  *
99  * Returns the value.
100  */
101 int
102 from_base64(intmax_t *value, char *where)
103 {
104    uintmax_t val = 0;
105    int i, neg;
106
107    if (!base64_inited)
108       base64_init();
109    /* Check if it is negative */
110    i = neg = 0;
111    if (where[i] == '-') {
112       i++;
113       neg = 1;
114    }
115    /* Construct value */
116    while (where[i] != 0 && where[i] != ' ') {
117       val <<= 6;
118       val += base64_map[(uint8_t)where[i++]];
119    }
120
121    *value = neg ? -(intmax_t)val : (intmax_t)val;
122    return i;
123 }
124
125
126 /*
127  * Encode binary data in bin of len bytes into
128  * buf as base64 characters.
129  *
130  * If compatible is true, the bin_to_base64 routine will be compatible
131  * with what the rest of the world uses.
132  *
133  *  Returns: the number of characters stored not
134  *           including the EOS
135  */
136 int
137 bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
138 {
139    uint32_t reg, save, mask;
140    int rem, i;
141    int j = 0;
142
143    reg = 0;
144    rem = 0;
145    buflen--;                       /* allow for storing EOS */
146    for (i=0; i < binlen; ) {
147       if (rem < 6) {
148          reg <<= 8;
149          if (compatible) {
150             reg |= (uint8_t)bin[i++];
151          } else {
152             reg |= (int8_t)bin[i++];
153          }
154          rem += 8;
155       }
156       save = reg;
157       reg >>= (rem - 6);
158       if (j < buflen) {
159          buf[j++] = base64_digits[reg & 0x3F];
160       }
161       reg = save;
162       rem -= 6;
163    }
164    if (rem && j < buflen) {
165       mask = (1 << rem) - 1;
166       if (compatible) {
167          buf[j++] = base64_digits[(reg & mask) << 6 - rem];
168       } else {
169          buf[j++] = base64_digits[reg & mask];
170       }
171    }
172    buf[j] = 0;
173    return j;
174 }
175
176 #ifdef BIN_TEST
177 int main(int argc, char *argv[])
178 {
179    int xx = 0;
180    int len;
181    char buf[100];
182    char junk[100];
183    int i;
184
185 #ifdef xxxx
186    for (i=0; i < 1000; i++) {
187       bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
188       printf("xx=%s\n", buf);
189       xx++;
190    }
191 #endif
192    junk[0] = 0xFF;
193    for (i=1; i<100; i++) {
194       junk[i] = junk[i-1]-1;
195    }
196    len = bin_to_base64(buf, sizeof(buf) junk, 16, true);
197    printf("len=%d junk=%s\n", len, buf);
198    return 0;
199 }
200 #endif
201
202 #ifdef TEST_MODE
203 static int errfunc(const char *epath, int eernoo)
204 {
205   printf("in errfunc\n");
206   return 1;
207 }
208
209
210 /*
211  * Test the base64 routines by encoding and decoding
212  * lstat() packets.
213  */
214 int main(int argc, char *argv[])
215 {
216    char where[500];
217    int i;
218    glob_t my_glob;
219    char *fname;
220    struct stat statp;
221    struct stat statn;
222    int debug_level = 0;
223    char *p;
224    time_t t = 1028712799;
225
226    if (argc > 1 && strcmp(argv[1], "-v") == 0)
227       debug_level++;
228
229    base64_init();
230
231    my_glob.gl_offs = 0;
232    glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
233
234    for (i=0; my_glob.gl_pathv[i]; i++) {
235       fname = my_glob.gl_pathv[i];
236       if (lstat(fname, &statp) < 0) {
237          printf("Cannot stat %s: %s\n", fname, strerror(errno));
238          continue;
239       }
240       encode_stat(where, &statp);
241
242       printf("Encoded stat=%s\n", where);
243
244 #ifdef xxx
245       p = where;
246       p += to_base64((intmax_t)(statp.st_atime), p);
247       *p++ = ' ';
248       p += to_base64((intmax_t)t, p);
249       printf("%s %s\n", fname, where);
250
251       printf("%s %lld\n", "st_dev", (intmax_t)statp.st_dev);
252       printf("%s %lld\n", "st_ino", (intmax_t)statp.st_ino);
253       printf("%s %lld\n", "st_mode", (intmax_t)statp.st_mode);
254       printf("%s %lld\n", "st_nlink", (intmax_t)statp.st_nlink);
255       printf("%s %lld\n", "st_uid", (intmax_t)statp.st_uid);
256       printf("%s %lld\n", "st_gid", (intmax_t)statp.st_gid);
257       printf("%s %lld\n", "st_rdev", (intmax_t)statp.st_rdev);
258       printf("%s %lld\n", "st_size", (intmax_t)statp.st_size);
259       printf("%s %lld\n", "st_blksize", (intmax_t)statp.st_blksize);
260       printf("%s %lld\n", "st_blocks", (intmax_t)statp.st_blocks);
261       printf("%s %lld\n", "st_atime", (intmax_t)statp.st_atime);
262       printf("%s %lld\n", "st_mtime", (intmax_t)statp.st_mtime);
263       printf("%s %lld\n", "st_ctime", (intmax_t)statp.st_ctime);
264 #endif
265
266       if (debug_level)
267          printf("%s: len=%d val=%s\n", fname, strlen(where), where);
268
269       decode_stat(where, &statn);
270
271       if (statp.st_dev != statn.st_dev ||
272           statp.st_ino != statn.st_ino ||
273           statp.st_mode != statn.st_mode ||
274           statp.st_nlink != statn.st_nlink ||
275           statp.st_uid != statn.st_uid ||
276           statp.st_gid != statn.st_gid ||
277           statp.st_rdev != statn.st_rdev ||
278           statp.st_size != statn.st_size ||
279           statp.st_blksize != statn.st_blksize ||
280           statp.st_blocks != statn.st_blocks ||
281           statp.st_atime != statn.st_atime ||
282           statp.st_mtime != statn.st_mtime ||
283           statp.st_ctime != statn.st_ctime) {
284
285          printf("%s: %s\n", fname, where);
286          encode_stat(where, &statn);
287          printf("%s: %s\n", fname, where);
288          printf("NOT EQAL\n");
289       }
290
291    }
292    globfree(&my_glob);
293
294    printf("%d files examined\n", i);
295
296    to_base64(UINT32_MAX, where);
297    printf("UINT32_MAX=%s\n", where);
298
299    return 0;
300 }
301 #endif