* Older FDs don't have a delta sequence, so check if it is there 
           */
          if (p - jcr->attr < msglen) {
-            ar->DeltaSeq = str_to_int32(p);
+            ar->DeltaSeq = str_to_int32(p); /* delta_seq */
          }
       }
 
 
                goto good_rtn;
             }
             flags = ff_pkt->flags;
-            ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE);
+            ff_pkt->flags &= ~(FO_GZIP|FO_SPARSE|FO_OFFSETS);
             if (flags & FO_ENCRYPT) {
                rsrc_stream = STREAM_ENCRYPTED_MACOS_FORK_DATA;
             } else {
    int zstat;
 
    if (ff_pkt->flags & FO_GZIP) {
-      if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
-         cbuf = (Bytef *)jcr->compress_buf + SPARSE_FADDR_SIZE;
-         max_compress_len = jcr->compress_buf_size - SPARSE_FADDR_SIZE;
+      if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+         cbuf = (Bytef *)jcr->compress_buf + OFFSET_FADDR_SIZE;
+         max_compress_len = jcr->compress_buf_size - OFFSET_FADDR_SIZE;
       } else {
          cbuf = (Bytef *)jcr->compress_buf;
          max_compress_len = jcr->compress_buf_size; /* set max length */
 #endif
 
    if (ff_pkt->flags & FO_ENCRYPT) {
-      if (ff_pkt->flags & FO_SPARSE) {
-         Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse data not supported.\n"));
+      if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+         Jmsg0(jcr, M_FATAL, 0, _("Encrypting sparse or offset data not supported.\n"));
          goto err;
       }
       /** Allocate the cipher context */
     * Make space at beginning of buffer for fileAddr because this
     *   same buffer will be used for writing if compression is off.
     */
-   if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
-      rbuf += SPARSE_FADDR_SIZE;
-      rsize -= SPARSE_FADDR_SIZE;
+   if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+      rbuf += OFFSET_FADDR_SIZE;
+      rsize -= OFFSET_FADDR_SIZE;
 #ifdef HAVE_FREEBSD_OS
       /**
        * To read FreeBSD partitions, the read size must be
          }
          if (!allZeros) {
             /** Put file address as first data in buffer */
-            ser_begin(wbuf, SPARSE_FADDR_SIZE);
+            ser_begin(wbuf, OFFSET_FADDR_SIZE);
             ser_uint64(fileAddr);     /* store fileAddr in begin of buffer */
          }
          fileAddr += sd->msglen;      /* update file address */
          if (allZeros) {
             continue;                 /* skip block of zeros */
          }
-      } else if (ff_pkt->flags & FO_DELTA) {
+      } else if (ff_pkt->flags & FO_OFFSETS) {
          ser_declare;
-         ser_begin(wbuf, SPARSE_FADDR_SIZE);
+         ser_begin(wbuf, OFFSET_FADDR_SIZE);
          ser_uint64(ff_pkt->bfd.offset);     /* store offset in begin of buffer */
       }
 
          uint32_t initial_len = 0;
          ser_declare;
 
-         if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
-            cipher_input_len += SPARSE_FADDR_SIZE;
+         if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+            cipher_input_len += OFFSET_FADDR_SIZE;
          }
 
          /** Encrypt the length of the input block */
       }
 
       /* Send the buffer to the Storage daemon */
-      if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_DELTA)) {
-         sd->msglen += SPARSE_FADDR_SIZE; /* include fileAddr in size */
+      if ((ff_pkt->flags & FO_SPARSE) || (ff_pkt->flags & FO_OFFSETS)) {
+         sd->msglen += OFFSET_FADDR_SIZE; /* include fileAddr in size */
       }
       sd->msg = wbuf;              /* set correct write buffer */
       if (!sd->send()) {
 
                ff_pkt->flags &= ~FO_DELTA;   /* clean delta sequence number */
                ff_pkt->delta_seq = 0;
             }
+            if (sp.flags & FO_OFFSETS) {
+               ff_pkt->flags |= FO_OFFSETS;
+            }
+            if (sp.flags & FO_PORTABLE_DATA) {
+               ff_pkt->flags |= FO_PORTABLE_DATA;
+            }
+            ff_pkt->flags |= FO_PLUGIN;       /* data from plugin */
          }
 
          memcpy(&ff_pkt->statp, &sp.statp, sizeof(ff_pkt->statp));
 
        * First we expect a Stream Record Header
        */
       if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index,
-          &rctx.stream, &rctx.size) != 5) {
+          &rctx.full_stream, &rctx.size) != 5) {
          Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg);
          goto bail_out;
       }
+      /* Strip off new stream high bits */
+      rctx.stream = rctx.full_stream & STREAMMASK_TYPE;
       Dmsg5(150, "Got hdr: Files=%d FilInx=%d size=%d Stream=%d, %s.\n", 
             jcr->JobFiles, file_index, rctx.size, rctx.stream, stream_to_ascii(rctx.stream));
 
       unser_declare;
       uint64_t faddr;
       char ec1[50];
-      unser_begin(*data, SPARSE_FADDR_SIZE);
+      unser_begin(*data, OFFSET_FADDR_SIZE);
       unser_uint64(faddr);
       if (*addr != faddr) {
          *addr = faddr;
             return false;
          }
       }
-      *data += SPARSE_FADDR_SIZE;
-      *length -= SPARSE_FADDR_SIZE;
+      *data += OFFSET_FADDR_SIZE;
+      *length -= OFFSET_FADDR_SIZE;
       return true;
 }
 
       Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
    }
 
-   if ((flags & FO_SPARSE) || (flags & FO_DELTA)) {
+   if ((flags & FO_SPARSE) || (flags & FO_OFFSETS)) {
       if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
          goto bail_out;
       }
    cipher_ctx->buf_len -= cipher_ctx->packet_len;
    Dmsg2(130, "Encryption writing full block, %u bytes, remaining %u bytes in buffer\n", wsize, cipher_ctx->buf_len);
 
-   if ((flags & FO_SPARSE) || (flags & FO_DELTA)) {
+   if ((flags & FO_SPARSE) || (flags & FO_OFFSETS)) {
       if (!sparse_data(jcr, bfd, addr, &wbuf, &wsize)) {
          return false;
       }
 
 
 struct r_ctx {
    JCR *jcr;
-   int32_t stream;
-   int32_t prev_stream;
+   int32_t stream;                     /* stream less new bits */
+   int32_t prev_stream;                /* previous stream */
+   int32_t full_stream;                /* full stream including new bits */
    BFILE bfd;                          /* File content */
    uint64_t fileAddr;                  /* file write address */
    uint32_t size;                      /* Size of file */
 
    } else {
       stream = STREAM_FILE_DATA;
    }
-   if (ff_pkt->flags & FO_DELTA) {
+   if (ff_pkt->flags & FO_OFFSETS) {
       stream = STREAM_SPARSE_DATA;
    }
 
 
       return 0;
    }
    Dmsg2(dbglvl, "Got Attr: FilInx=%d type=%d\n", attr->file_index, attr->type);
+   /*
+    * Note AR_DATA_STREAM should never be set since it is encoded
+    *  at the end of the attributes.
+    */
    if (attr->type & AR_DATA_STREAM) {
       attr->data_stream = 1;
    } else {
    attr->lname = p;                   /* set link position */
    while (*p++ != 0)                  /* skip link */
       { }
+   attr->delta_seq = 0;
    if (attr->type == FT_RESTORE_FIRST) {
       /* We have an object, so do a binary copy */
       object_len = reclen + rec - p;
       pm_strcpy(attr->attrEx, p);     /* copy extended attributes, if any */
       if (attr->data_stream) {
          int64_t val;
-         while (*p++ != 0)               /* skip extended attributes */
+         while (*p++ != 0)            /* skip extended attributes */
             { }
          from_base64(&val, p);
          attr->data_stream = (int32_t)val;
-      }
+      } else {
+         while (*p++ != 0)            /* skip extended attributes */
+            { }
+         if (p - rec < reclen) {
+            attr->delta_seq = str_to_int32(p); /* delta_seq */
+         }
+      }       
    }
-   Dmsg7(dbglvl, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s ds=%d\n",
+   Dmsg8(dbglvl, "unpack_attr FI=%d Type=%d fname=%s attr=%s lname=%s attrEx=%s datastr=%d delta_seq=%d\n",
       attr->file_index, attr->type, attr->fname, attr->attr, attr->lname,
-      attr->attrEx, attr->data_stream);
+      attr->attrEx, attr->data_stream, attr->delta_seq);
    *attr->ofname = 0;
    *attr->olname = 0;
    return 1;
 
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2003-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2003-2010 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.
  *
  *    Kern Sibbald, June MMIII
  *
- *   Version $Id$
  */
 
 #ifndef __ATTR_H_
    int32_t type;                      /* file type FT */
    int32_t file_index;                /* file index */
    int32_t LinkFI;                    /* file index to data if hard link */
+   int32_t delta_seq;                 /* delta sequence numbr */
    uid_t uid;                         /* userid */
    struct stat statp;                 /* decoded stat packet */
    POOLMEM *attrEx;                   /* extended attributes if any */
 
 
 #define get_self(x) ((delta_test*)((x)->pContext))
 #define FO_DELTA        (1<<28)       /* Do delta on file */
+#define FO_OFFSETS      (1<<30)       /* Keep block offsets */
 
 class delta_test
 {
       bRC state = bfuncs->checkChanges(ctx, sp);
       /* Should always be bRC_OK */
       sp->type = (state == bRC_Seen)? FT_NOCHG : FT_REG;
-      sp->flags |= FO_DELTA;
+      sp->flags |= (FO_DELTA|FO_OFFSETS);
       self->delta = sp->delta_seq + 1;
    }
    pm_strcpy(self->fname, files[self->delta % nb_files]);
 
          if (rec->Stream == STREAM_SPARSE_DATA) {
             ser_declare;
             uint64_t faddr;
-            wbuf = rec->data + SPARSE_FADDR_SIZE;
-            wsize = rec->data_len - SPARSE_FADDR_SIZE;
-            ser_begin(rec->data, SPARSE_FADDR_SIZE);
+            wbuf = rec->data + OFFSET_FADDR_SIZE;
+            wsize = rec->data_len - OFFSET_FADDR_SIZE;
+            ser_begin(rec->data, OFFSET_FADDR_SIZE);
             unser_uint64(faddr);
             if (fileAddr != faddr) {
                fileAddr = faddr;
             ser_declare;
             uint64_t faddr;
             char ec1[50];
-            wbuf = rec->data + SPARSE_FADDR_SIZE;
-            wsize = rec->data_len - SPARSE_FADDR_SIZE;
-            ser_begin(rec->data, SPARSE_FADDR_SIZE);
+            wbuf = rec->data + OFFSET_FADDR_SIZE;
+            wsize = rec->data_len - OFFSET_FADDR_SIZE;
+            ser_begin(rec->data, OFFSET_FADDR_SIZE);
             unser_uint64(faddr);
             if (fileAddr != faddr) {
                fileAddr = faddr;