]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/base64.c
Merge branch 'master' into mvw/1361
[bacula/bacula] / bacula / src / lib / base64.c
index 6a9f8a8382106bb2f3af5e918b5d56f6dbb6a488..02e42639c711681d250ec6b1bf0f17e0c6705838 100644 (file)
@@ -1,40 +1,48 @@
-/*   
- *   Generic base 64 input and output routines
- *
- *    Written by Kern E. Sibbald, March MM.
- *
- *   Version $Id$
- */
-
 /*
-   Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
 
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.
 
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ *   Generic base 64 input and output routines
+ *
+ *    Written by Kern E. Sibbald, March MM.
+ *
+ *   Version $Id$
  */
 
 
 #include "bacula.h"
 
+
 #ifdef TEST_MODE
 #include <glob.h>
 #endif
 
 
-static char const base64_digits[64] =
+static uint8_t const base64_digits[64] =
 {
   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
   'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
@@ -44,17 +52,17 @@ static char const base64_digits[64] =
 };
 
 static int base64_inited = 0;
-static char base64_map[128];
-  
+static uint8_t base64_map[128];
+
 
 /* Initialize the Base 64 conversion routines */
 void
 base64_init(void)
-{     
-   int i; 
+{
+   int i;
    memset(base64_map, 0, sizeof(base64_map));
    for (i=0; i<64; i++)
-      base64_map[(int)base64_digits[i]] = i;
+      base64_map[(uint8_t)base64_digits[i]] = i;
    base64_inited = 1;
 }
 
@@ -90,7 +98,7 @@ to_base64(intmax_t value, char *where)
    val = value;
    where[i] = 0;
    do {
-      where[--i] = base64_digits[val & (unsigned)0x3F];
+      where[--i] = base64_digits[val & (uintmax_t)0x3F];
       val >>= 6;
    } while (val);
    return n;
@@ -105,11 +113,11 @@ to_base64(intmax_t value, char *where)
  */
 int
 from_base64(intmax_t *value, char *where)
-{ 
+{
    uintmax_t val = 0;
    int i, neg;
 
-   if (!base64_inited) 
+   if (!base64_inited)
       base64_init();
    /* Check if it is negative */
    i = neg = 0;
@@ -120,137 +128,59 @@ from_base64(intmax_t *value, char *where)
    /* Construct value */
    while (where[i] != 0 && where[i] != ' ') {
       val <<= 6;
-      val += base64_map[(int)where[i++]];
+      val += base64_map[(uint8_t)where[i++]];
    }
-        
+
    *value = neg ? -(intmax_t)val : (intmax_t)val;
    return i;
 }
 
-/* Encode a stat structure into a base64 character string */
-void
-encode_stat(char *buf, struct stat *statp)
-{
-   char *p = buf;
-   /*
-    * NOTE: we should use rdev as major and minor device if
-    * it is a block or char device (S_ISCHR(statp->st_mode)
-    * or S_ISBLK(statp->st_mode)).  In all other cases,
-    * it is not used.  
-    *
-    */
-   p += to_base64((intmax_t)statp->st_dev, p);
-   *p++ = ' ';                        /* separate fields with a space */
-   p += to_base64((intmax_t)statp->st_ino, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_mode, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_nlink, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_uid, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_gid, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_rdev, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_size, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_blksize, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_blocks, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_atime, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_mtime, p);
-   *p++ = ' ';
-   p += to_base64((intmax_t)statp->st_ctime, p);
-   *p++ = 0;
-   return;
-}
-
-
-/* Decode a stat packet from base64 characters */
-void
-decode_stat(char *buf, struct stat *statp)
-{
-   char *p = buf;
-   intmax_t val;
-
-   p += from_base64(&val, p);
-   statp->st_dev = val;
-   p++;                              /* skip space */
-   p += from_base64(&val, p);
-   statp->st_ino = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_mode = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_nlink = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_uid = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_gid = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_rdev = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_size = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_blksize = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_blocks = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_atime = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_mtime = val;
-   p++;
-   p += from_base64(&val, p);
-   statp->st_ctime = val;
-   p++;
-}
 
 /*
  * Encode binary data in bin of len bytes into
  * buf as base64 characters.
  *
+ * If compatible is true, the bin_to_base64 routine will be compatible
+ * with what the rest of the world uses.
+ *
  *  Returns: the number of characters stored not
- *          including the EOS
+ *           including the EOS
  */
 int
-bin_to_base64(char *buf, char *bin, int len)
+bin_to_base64(char *buf, int buflen, char *bin, int binlen, int compatible)
 {
-   unsigned int reg, save, mask;
+   uint32_t reg, save, mask;
    int rem, i;
    int j = 0;
 
    reg = 0;
    rem = 0;
-   for (i=0; i<len; ) {
+   buflen--;                       /* allow for storing EOS */
+   for (i=0; i < binlen; ) {
       if (rem < 6) {
-        reg <<= 8;
-        reg |= bin[i++];
-        rem += 8;
+         reg <<= 8;
+         if (compatible) {
+            reg |= (uint8_t)bin[i++];
+         } else {
+            reg |= (int8_t)bin[i++];
+         }
+         rem += 8;
       }
       save = reg;
       reg >>= (rem - 6);
-      buf[j++] = base64_digits[reg & (unsigned)0x3F];
+      if (j < buflen) {
+         buf[j++] = base64_digits[reg & 0x3F];
+      }
       reg = save;
       rem -= 6;
    }
-   if (rem) {
-      mask = 1;
-      for (i=1; i<rem; i++) {
-        mask = (mask << 1) | 1;
+   if (rem && j < buflen) {
+      mask = (1 << rem) - 1;
+      if (compatible) {
+         buf[j++] = base64_digits[(reg & mask) << (6 - rem)];
+      } else {
+         buf[j++] = base64_digits[reg & mask];
       }
-      buf[j++] = base64_digits[reg & mask];
    }
    buf[j] = 0;
    return j;
@@ -265,12 +195,18 @@ int main(int argc, char *argv[])
    char junk[100];
    int i;
 
-   for (i=0; i < 100; i++) {
-      bin_to_base64(buf, (char *)&xx, 4);
+#ifdef xxxx
+   for (i=0; i < 1000; i++) {
+      bin_to_base64(buf, sizeof(buf), (char *)&xx, 4, true);
       printf("xx=%s\n", buf);
       xx++;
    }
-   len = bin_to_base64(buf, junk, 16);
+#endif
+   junk[0] = 0xFF;
+   for (i=1; i<100; i++) {
+      junk[i] = junk[i-1]-1;
+   }
+   len = bin_to_base64(buf, sizeof(buf) junk, 16, true);
    printf("len=%d junk=%s\n", len, buf);
    return 0;
 }
@@ -279,7 +215,7 @@ int main(int argc, char *argv[])
 #ifdef TEST_MODE
 static int errfunc(const char *epath, int eernoo)
 {
-  Dmsg0(-1, "in errfunc\n");
+  printf("in errfunc\n");
   return 1;
 }
 
@@ -288,7 +224,7 @@ static int errfunc(const char *epath, int eernoo)
  * Test the base64 routines by encoding and decoding
  * lstat() packets.
  */
-int main(int argc, char *argv[]) 
+int main(int argc, char *argv[])
 {
    char where[500];
    int i;
@@ -297,44 +233,71 @@ int main(int argc, char *argv[])
    struct stat statp;
    struct stat statn;
    int debug_level = 0;
+   char *p;
+   time_t t = 1028712799;
 
    if (argc > 1 && strcmp(argv[1], "-v") == 0)
-      debug_level++;  
+      debug_level++;
 
    base64_init();
 
    my_glob.gl_offs = 0;
-   glob("/etc/*", GLOB_MARK, errfunc, &my_glob);
+   glob("/etc/grub.conf", GLOB_MARK, errfunc, &my_glob);
 
    for (i=0; my_glob.gl_pathv[i]; i++) {
       fname = my_glob.gl_pathv[i];
       if (lstat(fname, &statp) < 0) {
-         printf("Cannot stat %s: %s\n", fname, strerror(errno));
-        continue;
+         berrno be;
+         printf("Cannot stat %s: %s\n", fname, be.bstrerror(errno));
+         continue;
       }
-      encode_stat(where, &statp);
+      encode_stat(where, &statp, 0, 0);
+
+      printf("Encoded stat=%s\n", where);
+
+#ifdef xxx
+      p = where;
+      p += to_base64((intmax_t)(statp.st_atime), p);
+      *p++ = ' ';
+      p += to_base64((intmax_t)t, p);
+      printf("%s %s\n", fname, where);
+
+      printf("%s %lld\n", "st_dev", (intmax_t)statp.st_dev);
+      printf("%s %lld\n", "st_ino", (intmax_t)statp.st_ino);
+      printf("%s %lld\n", "st_mode", (intmax_t)statp.st_mode);
+      printf("%s %lld\n", "st_nlink", (intmax_t)statp.st_nlink);
+      printf("%s %lld\n", "st_uid", (intmax_t)statp.st_uid);
+      printf("%s %lld\n", "st_gid", (intmax_t)statp.st_gid);
+      printf("%s %lld\n", "st_rdev", (intmax_t)statp.st_rdev);
+      printf("%s %lld\n", "st_size", (intmax_t)statp.st_size);
+      printf("%s %lld\n", "st_blksize", (intmax_t)statp.st_blksize);
+      printf("%s %lld\n", "st_blocks", (intmax_t)statp.st_blocks);
+      printf("%s %lld\n", "st_atime", (intmax_t)statp.st_atime);
+      printf("%s %lld\n", "st_mtime", (intmax_t)statp.st_mtime);
+      printf("%s %lld\n", "st_ctime", (intmax_t)statp.st_ctime);
+#endif
 
       if (debug_level)
          printf("%s: len=%d val=%s\n", fname, strlen(where), where);
-      
+
       decode_stat(where, &statn);
 
-      if (statp.st_dev != statn.st_dev || 
-         statp.st_ino != statn.st_ino ||
-         statp.st_mode != statn.st_mode ||
-         statp.st_nlink != statn.st_nlink ||
-         statp.st_uid != statn.st_uid ||
-         statp.st_gid != statn.st_gid ||
-         statp.st_rdev != statn.st_rdev ||
-         statp.st_size != statn.st_size ||
-         statp.st_blksize != statn.st_blksize ||
-         statp.st_blocks != statn.st_blocks ||
-         statp.st_atime != statn.st_atime ||
-         statp.st_mtime != statn.st_mtime ||
-         statp.st_ctime != statn.st_ctime) {
+      if (statp.st_dev != statn.st_dev ||
+          statp.st_ino != statn.st_ino ||
+          statp.st_mode != statn.st_mode ||
+          statp.st_nlink != statn.st_nlink ||
+          statp.st_uid != statn.st_uid ||
+          statp.st_gid != statn.st_gid ||
+          statp.st_rdev != statn.st_rdev ||
+          statp.st_size != statn.st_size ||
+          statp.st_blksize != statn.st_blksize ||
+          statp.st_blocks != statn.st_blocks ||
+          statp.st_atime != statn.st_atime ||
+          statp.st_mtime != statn.st_mtime ||
+          statp.st_ctime != statn.st_ctime) {
 
          printf("%s: %s\n", fname, where);
-        encode_stat(where, &statn);
+         encode_stat(where, &statn, 0, 0);
          printf("%s: %s\n", fname, where);
          printf("NOT EQAL\n");
       }
@@ -344,6 +307,9 @@ int main(int argc, char *argv[])
 
    printf("%d files examined\n", i);
 
+   to_base64(UINT32_MAX, where);
+   printf("UINT32_MAX=%s\n", where);
+
    return 0;
-}   
+}
 #endif