+ /*
+ * Fix all incompatible options
+ */
+ /* No sparse option for encrypted data */
+ if (ff_pkt->flags & FO_ENCRYPT) {
+ ff_pkt->flags &= ~FO_SPARSE;
+ }
+
+ /* Note, no sparse option for win32_data */
+ if (!is_portable_backup(&ff_pkt->bfd)) {
+ stream = STREAM_WIN32_DATA;
+ ff_pkt->flags &= ~FO_SPARSE;
+ } else if (ff_pkt->flags & FO_SPARSE) {
+ stream = STREAM_SPARSE_DATA;
+ } else {
+ stream = STREAM_FILE_DATA;
+ }
+ if (ff_pkt->flags & FO_OFFSETS) {
+ stream = STREAM_SPARSE_DATA;
+ }
+
+ /* Encryption is only supported for file data */
+ if (stream != STREAM_FILE_DATA && stream != STREAM_WIN32_DATA &&
+ stream != STREAM_MACOS_FORK_DATA) {
+ ff_pkt->flags &= ~FO_ENCRYPT;
+ }
+
+ /* Compression is not supported for Mac fork data */
+ if (stream == STREAM_MACOS_FORK_DATA) {
+ ff_pkt->flags &= ~FO_COMPRESS;
+ }
+
+ /*
+ * Handle compression and encryption options
+ */
+#if defined(HAVE_LIBZ) || defined(HAVE_LZO)
+ if (ff_pkt->flags & FO_COMPRESS) {
+ #ifdef HAVE_LIBZ
+ if(ff_pkt->Compress_algo == COMPRESS_GZIP) {
+ switch (stream) {
+ case STREAM_WIN32_DATA:
+ stream = STREAM_WIN32_GZIP_DATA;
+ break;
+ case STREAM_SPARSE_DATA:
+ stream = STREAM_SPARSE_GZIP_DATA;
+ break;
+ case STREAM_FILE_DATA:
+ stream = STREAM_GZIP_DATA;
+ break;
+ default:
+ /*
+ * All stream types that do not support compression should clear out
+ * FO_COMPRESS above, and this code block should be unreachable.
+ */
+ ASSERT(!(ff_pkt->flags & FO_COMPRESS));
+ return STREAM_NONE;
+ }
+ }
+ #endif
+ #ifdef HAVE_LZO
+ if(ff_pkt->Compress_algo == COMPRESS_LZO1X) {
+ switch (stream) {
+ case STREAM_WIN32_DATA:
+ stream = STREAM_WIN32_COMPRESSED_DATA;
+ break;
+ case STREAM_SPARSE_DATA:
+ stream = STREAM_SPARSE_COMPRESSED_DATA;
+ break;
+ case STREAM_FILE_DATA:
+ stream = STREAM_COMPRESSED_DATA;
+ break;
+ default:
+ /*
+ * All stream types that do not support compression should clear out
+ * FO_COMPRESS above, and this code block should be unreachable.
+ */
+ ASSERT(!(ff_pkt->flags & FO_COMPRESS));
+ return STREAM_NONE;
+ }
+ }
+ #endif
+ }
+#endif
+#ifdef HAVE_CRYPTO
+ if (ff_pkt->flags & FO_ENCRYPT) {
+ switch (stream) {
+ case STREAM_WIN32_DATA:
+ stream = STREAM_ENCRYPTED_WIN32_DATA;
+ break;
+ case STREAM_WIN32_GZIP_DATA:
+ stream = STREAM_ENCRYPTED_WIN32_GZIP_DATA;
+ break;
+ case STREAM_WIN32_COMPRESSED_DATA:
+ stream = STREAM_ENCRYPTED_WIN32_COMPRESSED_DATA;
+ break;
+ case STREAM_FILE_DATA:
+ stream = STREAM_ENCRYPTED_FILE_DATA;
+ break;
+ case STREAM_GZIP_DATA:
+ stream = STREAM_ENCRYPTED_FILE_GZIP_DATA;
+ break;
+ case STREAM_COMPRESSED_DATA:
+ stream = STREAM_ENCRYPTED_FILE_COMPRESSED_DATA;
+ break;
+ default:
+ /* All stream types that do not support encryption should clear out
+ * FO_ENCRYPT above, and this code block should be unreachable. */
+ ASSERT(!(ff_pkt->flags & FO_ENCRYPT));
+ return STREAM_NONE;
+ }
+ }
+#endif
+
+ return stream;
+}
+
+
+/*
+ * Encode a stat structure into a base64 character string
+ * All systems must create such a structure.
+ * In addition, we tack on the LinkFI, which is non-zero in
+ * the case of a hard linked file that has no data. This
+ * is a File Index pointing to the link that does have the
+ * data (always the first one encountered in a save).
+ * You may piggyback attributes on this packet by encoding
+ * them in the encode_attribsEx() subroutine, but this is
+ * not recommended.
+ */
+void encode_stat(char *buf, struct stat *statp, int stat_size, int32_t LinkFI, int data_stream)