]> git.sur5r.net Git - bacula/bacula/commitdiff
Add missing files for xattr and eliminate a few compiler complaints
authorKern Sibbald <kern@sibbald.com>
Wed, 26 Nov 2008 14:11:19 +0000 (14:11 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 26 Nov 2008 14:11:19 +0000 (14:11 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@8087 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/filed/protos.h
bacula/src/filed/xattr.c [new file with mode: 0644]
bacula/src/filed/xattr.h [new file with mode: 0644]
bacula/src/lib/serial.h

index 8c3dcb77fe6de662519b980bf09b4cac72c8c3ef..428a9ddf7c1bcc22edd73dadb7c5f883fb1ae83b 100644 (file)
@@ -1,10 +1,7 @@
-/*
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -28,6 +25,9 @@
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *   Version $Id$
+ */
 
 extern bool blast_data_to_storage_daemon(JCR *jcr, char *addr);
 extern void do_verify_volume(JCR *jcr);
@@ -62,4 +62,3 @@ void unstrip_path(FF_PKT *ff_pkt);
 /* from xattr.c */
 bool build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt);
 bool parse_xattr_stream(JCR *jcr, int stream);
-
diff --git a/bacula/src/filed/xattr.c b/bacula/src/filed/xattr.c
new file mode 100644 (file)
index 0000000..acbf968
--- /dev/null
@@ -0,0 +1,583 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2008-2008 Free Software Foundation Europe e.V.
+
+   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
+   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., 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.
+*/
+/*
+ * Functions to handle Extended Attributes for bacula.
+ *
+ * Extended Attributes are so OS specific we only restore Extended Attributes if
+ * they were saved using a filed on the same platform.
+ *
+ * Currently we support the following OSes:
+ *   - FreeBSD
+ *   - Darwin
+ *   - Linux
+ *   - NetBSD
+ *
+ *   Written by Marco van Wieringen, November MMVIII
+ *
+ *   Version $Id: xattr.c 7879 2008-10-23 10:12:36Z kerns $
+ */
+
+#include "bacula.h"
+#include "filed.h"
+#include "xattr.h"
+
+/*
+ * List of supported OSs.
+ */
+#if !defined(HAVE_XATTR)            /* Extended Attributes support is required, of course */ \
+   || !( defined(HAVE_DARWIN_OS) \
+      || defined(HAVE_FREEBSD_OS) \
+      || defined(HAVE_LINUX_OS) \
+      || defined(HAVE_NETBSD_OS) \
+        )
+
+bool build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+   Jmsg(jcr, M_FATAL, 0, _("XATTR support not configured for your machine.\n"));
+   return false;
+}
+
+bool parse_xattr_stream(JCR *jcr, int stream)
+{
+   Jmsg(jcr, M_FATAL, 0, _("XATTR support not configured for your machine.\n"));
+   return false;
+}
+
+#else
+
+#ifdef HAVE_SYS_XATTR_H
+#include <sys/xattr.h>
+#endif
+
+#if defined(HAVE_GETXATTR) && !defined(HAVE_LGETXATTR)
+#define lgetxattr getxattr
+#endif
+#if defined(HAVE_SETXATTR) && !defined(HAVE_LSETXATTR)
+#define lsetxattr setxattr
+#endif
+#if defined(HAVE_LISTXATTR) && !defined(HAVE_LLISTXATTR)
+#define llistxattr listxattr
+#endif
+
+/*
+ * Send a XATTR stream to the SD.
+ */
+static bool send_xattr_stream(JCR *jcr, int stream, int len)
+{
+   BSOCK *sd = jcr->store_bsock;
+   POOLMEM *msgsave;
+#ifdef FD_NO_SEND_TEST
+   return true;
+#endif
+
+   /*
+    * Send header
+    */
+   if (!sd->fsend("%ld %d 0", jcr->JobFiles, stream)) {
+      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+            sd->bstrerror());
+
+      return false;
+   }
+
+   /*
+    * Send the buffer to the storage deamon
+    */
+   Dmsg1(400, "Backing up XATTR <%s>\n", jcr->xattr_data);
+   msgsave = sd->msg;
+   sd->msg = jcr->xattr_data;
+   sd->msglen = len;
+   if (!sd->send()) {
+      sd->msg = msgsave;
+      sd->msglen = 0;
+      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+            sd->bstrerror());
+
+      return false;
+   }
+
+   jcr->JobBytes += sd->msglen;
+   sd->msg = msgsave;
+   if (!sd->signal(BNET_EOD)) {
+      Jmsg1(jcr, M_FATAL, 0, _("Network send error to SD. ERR=%s\n"),
+            sd->bstrerror());
+
+      return false;
+   }
+
+   Dmsg1(200, "XATTR of file: %s successfully backed up!\n", jcr->last_fname);
+
+   return true;
+}
+
+static void xattr_drop_internal_table(xattr_t *xattr_value_list)
+{
+   xattr_t *current_xattr;
+
+   /*
+    * Walk the list of xattrs and free allocated memory on traversing.
+    */
+   for (current_xattr = xattr_value_list;
+        current_xattr != (xattr_t *)NULL;
+        current_xattr++) {
+      /*
+       * See if we can shortcut.
+       */
+      if (current_xattr->magic != XATTR_MAGIC)
+         break;
+
+      free(current_xattr->name);
+
+      if (current_xattr->value_length > 0)
+         free(current_xattr->value);
+   }
+
+   /*
+    * Free the array of control structs.
+    */
+   free(xattr_value_list);
+}
+
+
+static uint32_t serialize_xattr_stream(JCR *jcr, uint32_t expected_serialize_len, xattr_t *xattr_value_list)
+{
+   xattr_t *current_xattr;
+   ser_declare;
+
+   /*
+    * Make sure the serialized stream fits in the poolmem buffer.
+    * We allocate some more to be sure the stream is gonna fit.
+    */
+   jcr->xattr_data = check_pool_memory_size(jcr->xattr_data, expected_serialize_len + 10);
+   ser_begin(jcr->xattr_data, expected_serialize_len + 10);
+
+   /*
+    * Walk the list of xattrs and serialize the data.
+    */
+   for (current_xattr = xattr_value_list; current_xattr != (xattr_t *)NULL; current_xattr++) {
+      /*
+       * See if we can shortcut.
+       */
+      if (current_xattr->magic != XATTR_MAGIC)
+         break;
+
+      ser_uint32(current_xattr->magic);
+      ser_uint32(current_xattr->name_length);
+      ser_bytes(current_xattr->name, current_xattr->name_length);
+
+      ser_uint32(current_xattr->value_length);
+      ser_bytes(current_xattr->value, current_xattr->value_length);
+   }
+
+   ser_end(jcr->xattr_data, expected_serialize_len + 10);
+
+   return ser_length(jcr->xattr_data);
+}
+
+static bool generic_xattr_build_streams(JCR *jcr, FF_PKT *ff_pkt, int stream)
+{
+   int count = 0;
+   ssize_t xattr_list_len,
+           xattr_value_len,
+           expected_serialize_len = 0,
+           serialize_len = 0;
+   char *xattr_list, *bp;
+   xattr_t *xattr_value_list, *current_xattr;
+
+   /*
+    * First get the length of the available list with extended attributes.
+    */
+   xattr_list_len = llistxattr(jcr->last_fname, NULL, 0);
+   if (xattr_list_len < 0) {
+      berrno be;
+      Jmsg2(jcr, M_ERROR, 0, _("llistxattr error on file \"%s\": ERR=%s\n"),
+         jcr->last_fname, be.bstrerror());
+      Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
+         jcr->last_fname, be.bstrerror());
+      return false;
+   } else if (xattr_list_len == 0) {
+      return true;
+   }
+
+   /*
+    * Allocate room for the extented attribute list.
+    */
+   if ((xattr_list = (char *)malloc(xattr_list_len + 1)) == (char *)NULL) {
+      Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_list_len + 1);
+
+      return false;
+   }
+   memset((caddr_t)xattr_list, 0, xattr_list_len + 1);
+
+   /*
+    * Get the actual list of extended attributes names for a file.
+    */
+   xattr_list_len = llistxattr(jcr->last_fname, xattr_list, xattr_list_len);
+   if (xattr_list_len < 0) {
+      berrno be;
+      Jmsg2(jcr, M_ERROR, 0, _("llistxattr error on file \"%s\": ERR=%s\n"),
+         jcr->last_fname, be.bstrerror());
+      Dmsg2(100, "llistxattr error file=%s ERR=%s\n",
+         jcr->last_fname, be.bstrerror());
+
+      free(xattr_list);
+      return false;
+   }
+   xattr_list[xattr_list_len] = '\0';
+
+   /*
+    * Count the number of extended attributes on a file.
+    */
+   bp = xattr_list;
+   while ((bp - xattr_list) + 1 < xattr_list_len) {
+      count++;
+
+      bp = strchr(bp, '\0') + 1;
+   }
+
+   /*
+    * Allocate enough room to hold all extended attributes.
+    * After allocating the storage make sure its empty by zeroing it.
+    */
+   if ((xattr_value_list = (xattr_t *)malloc(count * sizeof(xattr_t))) == (xattr_t *)NULL) {
+      Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), count * sizeof(xattr_t));
+
+      return false;
+   }
+   memset((caddr_t)xattr_value_list, 0, count * sizeof(xattr_t));
+
+   /*
+    * Walk the list of extended attributes names and retrieve the data.
+    * We already count the bytes needed for serializing the stream later on.
+    */
+   current_xattr = xattr_value_list;
+   bp = xattr_list;
+   while ((bp - xattr_list) + 1 < xattr_list_len) {
+#if defined(HAVE_LINUX_OS)
+      /*
+       * On Linux you also get the acls in the extented attribute list.
+       * So we check if we are already backing up acls and if we do we
+       * don't store the extended attribute with the same info.
+       */
+      if (ff_pkt->flags & FO_ACL && !strcmp(bp, "system.posix_acl_access")) {
+         bp = strchr(bp, '\0') + 1;
+
+         continue;
+      }
+#endif
+
+      /*
+       * Each xattr valuepair starts with a magic so we can parse it easier.
+       */
+      current_xattr->magic = XATTR_MAGIC;
+      expected_serialize_len += sizeof(current_xattr->magic);
+
+      /*
+       * Allocate space for storing the name.
+       */
+      current_xattr->name_length = strlen(bp);
+      if ((current_xattr->name = (char *)malloc(current_xattr->name_length)) == (char *)NULL) {
+         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr->name_length);
+
+         goto bail_out;
+      }
+      memcpy((caddr_t)current_xattr->name, (caddr_t)bp, current_xattr->name_length);
+
+      expected_serialize_len += sizeof(current_xattr->name_length) + current_xattr->name_length;
+
+      /*
+       * First see how long the value is for the extended attribute.
+       */
+      xattr_value_len = lgetxattr(jcr->last_fname, bp, NULL, 0);
+      if (xattr_value_len < 0) {
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("lgetxattr error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
+            jcr->last_fname, be.bstrerror());
+
+         goto bail_out;
+      }
+
+      /*
+       * Allocate space for storing the value.
+       */
+      if ((current_xattr->value = (char *)malloc(xattr_value_len)) == (char *)NULL) {
+         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), xattr_value_len);
+
+         goto bail_out;
+      }
+      memset((caddr_t)current_xattr->value, 0, xattr_value_len);
+
+      xattr_value_len = lgetxattr(jcr->last_fname, bp, current_xattr->value, xattr_value_len);
+      if (xattr_value_len < 0) {
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("lgetxattr error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg2(100, "lgetxattr error file=%s ERR=%s\n",
+            jcr->last_fname, be.bstrerror());
+
+         goto bail_out;
+      }
+
+      /*
+       * Store the actual length of the value.
+       */
+      current_xattr->value_length = xattr_value_len;
+
+      expected_serialize_len += sizeof(current_xattr->value_length) + current_xattr->value_length;
+      
+      /*
+       * Next attribute.
+       */
+      current_xattr++;
+      bp = strchr(bp, '\0') + 1;
+   }
+
+   /*
+    * Serialize the datastream.
+    */
+   if ((serialize_len = serialize_xattr_stream(jcr, expected_serialize_len,
+         xattr_value_list)) < expected_serialize_len) {
+      Jmsg1(jcr, M_ERROR, 0, _("failed to serialize extended attributes on file \"%s\"\n"),
+         jcr->last_fname);
+
+      goto bail_out;
+   }
+
+   xattr_drop_internal_table(xattr_value_list);
+   free(xattr_list);
+
+   /*
+    * Send the datastream to the SD.
+    */
+   return send_xattr_stream(jcr, stream, serialize_len);
+
+bail_out:
+   xattr_drop_internal_table(xattr_value_list);
+   free(xattr_list);
+
+   return false;
+}
+
+static bool generic_xattr_parse_streams(JCR *jcr)
+{
+   unser_declare;
+   xattr_t current_xattr;
+   bool retval = true;
+
+   /*
+    * Parse the stream and perform the setxattr calls on the file.
+    *
+    * Start unserializing the data. We keep on looping while we have not
+    * unserialized all bytes in the stream.
+    */
+   unser_begin(jcr->xattr_data, jcr->xattr_data_len);
+   while (unser_length(jcr->xattr_data) < jcr->xattr_data_len) {
+      /*
+       * First make sure the magic is present. This way we can easily catch corruption.
+       * Any missing MAGIC is fatal we do NOT try to continue.
+       */
+      unser_uint32(current_xattr.magic);
+      if (current_xattr.magic != XATTR_MAGIC) {
+         Jmsg1(jcr, M_ERROR, 0, _("Illegal xattr stream, no XATTR_MAGIC on file \"%s\"\n"),
+            jcr->last_fname);
+
+         return false;
+      }
+
+      /*
+       * Decode the valuepair. First decode the length of the name.
+       */
+      unser_uint32(current_xattr.name_length);
+      
+      /*
+       * Allocate room for the name and decode its content.
+       */
+      if ((current_xattr.name = (char *)malloc(current_xattr.name_length + 1)) == (char *)NULL) {
+         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.name_length + 1);
+
+         return false;
+      }
+      unser_bytes(current_xattr.name, current_xattr.name_length);
+
+      /*
+       * The xattr_name needs to be null terminated for lsetxattr.
+       */
+      current_xattr.name[current_xattr.name_length] = '\0';
+
+      /*
+       * Decode the value length.
+       */
+      unser_uint32(current_xattr.value_length);
+
+      /*
+       * Allocate room for the value and decode its content.
+       */
+      if ((current_xattr.value = (char *)malloc(current_xattr.value_length)) == (char *)NULL) {
+         Emsg1(M_ABORT, 0, _("Out of memory requesting %d bytes\n"), current_xattr.value_length);
+
+         return false;
+      }
+      unser_bytes(current_xattr.value, current_xattr.value_length);
+
+      /*
+       * Try to set the extended attribute on the file.
+       * If we fail to set this attribute we flag the error but its not fatal,
+       * we try to restore the other extended attributes too.
+       */
+      if (lsetxattr(jcr->last_fname, current_xattr.name, current_xattr.value,
+         current_xattr.value_length, 0) != 0) {
+         berrno be;
+         Jmsg2(jcr, M_ERROR, 0, _("lsetxattr error on file \"%s\": ERR=%s\n"),
+            jcr->last_fname, be.bstrerror());
+         Dmsg2(100, "lsetxattr error file=%s ERR=%s\n",
+            jcr->last_fname, be.bstrerror());
+
+         /*
+          * Reset the return flag to false to indicate one or more extended attributes
+          * could not be restored.
+          */
+         retval = false;
+      }
+
+      /*
+       * Free the temporary buffers.
+       */
+      free(current_xattr.name);
+      free(current_xattr.value);
+   }
+
+   unser_end(jcr->xattr_data, jcr->xattr_data_len);
+   return retval;
+}
+
+#if defined(HAVE_DARWIN_OS)
+static bool darwin_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_DARWIN);
+}
+
+static bool darwin_parse_xattr_stream(JCR *jcr, int stream)
+{
+   switch (stream) {
+   case STREAM_XATTR_DARWIN:
+      return generic_xattr_parse_streams(jcr);
+   }
+}
+#elif defined(HAVE_FREEBSD_OS)
+static bool freebsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_FREEBSD);
+}
+
+static bool freebsd_parse_xattr_stream(JCR *jcr, int stream)
+{
+   switch (stream) {
+   case STREAM_XATTR_FREEBSD:
+      return generic_xattr_parse_streams(jcr);
+   }
+}
+#elif defined(HAVE_LINUX_OS)
+static bool linux_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_LINUX);
+}
+
+static bool linux_parse_xattr_stream(JCR *jcr, int stream)
+{
+   switch (stream) {
+   case STREAM_XATTR_LINUX:
+      return generic_xattr_parse_streams(jcr);
+   }
+   return false;
+}
+#elif defined(HAVE_NETBSD_OS)
+static bool netbsd_build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+   return generic_xattr_build_streams(jcr, ff_pkt, STREAM_XATTR_NETBSD);
+}
+
+static bool netbsd_parse_xattr_stream(JCR *jcr, int stream)
+{
+   switch (stream) {
+   case STREAM_XATTR_NETBSD:
+      return generic_xattr_parse_streams(jcr);
+   }
+   return false;
+}
+#endif
+
+bool build_xattr_streams(JCR *jcr, FF_PKT *ff_pkt)
+{
+#if defined(HAVE_DARWIN_OS)
+   return darwin_build_xattr_streams(jcr, ff_pkt);
+#elif defined(HAVE_FREEBSD_OS)
+   return freebsd_build_xattr_streams(jcr, ff_pkt);
+#elif defined(HAVE_LINUX_OS)
+   return linux_build_xattr_streams(jcr, ff_pkt);
+#elif defined(HAVE_NETBSD_OS)
+   return netbsd_build_xattr_streams(jcr, ff_pkt);
+#endif
+}
+
+bool parse_xattr_stream(JCR *jcr, int stream)
+{
+   /*
+    * Based on the stream being passed in dispatch to the right function
+    * for parsing and restoring a specific xattr. The platform determines
+    * which streams are recognized and parsed and which are handled by
+    * the default case and ignored. As only one of the platform defines
+    * is true per compile we never end up with duplicate switch values.
+    */
+   switch (stream) {
+#if defined(HAVE_DARWIN_OS)
+   case STREAM_XATTR_DARWIN:
+      return darwin_parse_xattr_stream(jcr, stream);
+#elif defined(HAVE_FREEBSD_OS)
+   case STREAM_XATTR_FREEBSD:
+      return freebsd_parse_xattr_stream(jcr, stream);
+#elif defined(HAVE_LINUX_OS)
+   case STREAM_XATTR_LINUX:
+      return linux_parse_xattr_stream(jcr, stream);
+#elif defined(HAVE_NETBSD_OS)
+   case STREAM_XATTR_NETBSD:
+      return netbsd_parse_xattr_stream(jcr, stream);
+#endif
+   default:
+      /*
+       * Issue a warning and discard the message. But pretend the restore was ok.
+       */
+      Qmsg2(jcr, M_WARNING, 0,
+         _("Can't restore Extended Attributes of %s - incompatible xattr stream encountered - %d\n"),
+         jcr->last_fname, stream);
+      return true;
+   } /* end switch (stream) */
+}
+
+#endif
diff --git a/bacula/src/filed/xattr.h b/bacula/src/filed/xattr.h
new file mode 100644 (file)
index 0000000..8044c42
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2004-2008 Free Software Foundation Europe e.V.
+
+   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
+   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., 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.
+*/
+
+#ifndef _BACULA_XATTR_
+#define _BACULA_XATTR_
+
+/*
+ * Magic used in the magic field of the xattr struct.
+ * This way we can see we encounter a valid xattr struct.
+ */
+#define XATTR_MAGIC 0x5C5884
+
+/*
+ * Internal representation of an extended attribute.
+ */
+typedef struct xattr {
+   uint32_t magic;
+   uint32_t name_length;
+   char *name;
+   uint32_t value_length;
+   char *value;
+} xattr_t;
+
+#endif
index 4f235a211966ff11fb769bd1b26776486890f707..615128754348c292184c461c586822cbb0e77798 100644 (file)
@@ -1,13 +1,7 @@
-/*
- *
- * Written by John Walker, MM
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Bacula® is a registered trademark ofJohn Walker.
+   Bacula® is a registered trademark ofKern Sibbald.
    The licensor of Bacula is the Free Software Foundation Europe
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ * Written by John Walker, MM
+ *
+ *   Version $Id$
+ */
 
 /*  Serialisation support functions from serial.c.  */
 
@@ -76,8 +76,8 @@ extern void unserial_string(uint8_t * * const ptr, char * const str);
 
 /*  ser_length  --  Determine length in bytes of serialised into a
                     buffer x.  */
-#define ser_length(x)  (ser_ptr - (uint8_t *)(x))
-#define unser_length(x)  (ser_ptr - (uint8_t *)(x))
+#define ser_length(x)  ((uint32_t)(ser_ptr - (uint8_t *)(x)))
+#define unser_length(x) ((uint32_t)(ser_ptr - (uint8_t *)(x)))
 
 /*  ser_end(x, s)  --  End serialisation into a buffer x of size s.  */
 #define ser_end(x, s)   ASSERT(ser_length(x) <= (s))