/*
Bacula® - The Network Backup Solution
- Copyright (C) 2002-2009 Free Software Foundation Europe e.V.
+ Copyright (C) 2002-2011 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
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
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
+ You should have received a copy of the GNU Affero 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.
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
*/
-/*
+/**
* Encode and decode standard Unix attributes and
* Extended attributes for Win32 and
* other non-Unix systems, or Unix systems with ACLs, ...
*
* Kern Sibbald, October MMII
*
- * Version $Id$
- *
*/
#include "bacula.h"
#include "find.h"
+#include "ch.h"
static uid_t my_uid = 1;
static gid_t my_gid = 1;
/* */
/*=============================================================*/
-/*
+/**
* Return the data stream that will be used
*/
int select_data_stream(FF_PKT *ff_pkt)
{
int stream;
- /*
+ /* This is a plugin special restore object */
+ if (ff_pkt->type == FT_RESTORE_FIRST) {
+ ff_pkt->flags = 0;
+ return STREAM_FILE_DATA;
+ }
+
+ /**
* Fix all incompatible options
*/
-
- /* No sparse option for encrypted data */
+ /** No sparse option for encrypted data */
if (ff_pkt->flags & FO_ENCRYPT) {
ff_pkt->flags &= ~FO_SPARSE;
}
- /* Note, no sparse option for win32_data */
+ /** Note, no sparse option for win32_data */
if (!is_portable_backup(&ff_pkt->bfd)) {
stream = STREAM_WIN32_DATA;
ff_pkt->flags &= ~FO_SPARSE;
} else {
stream = STREAM_FILE_DATA;
}
+ if (ff_pkt->flags & FO_OFFSETS) {
+ stream = STREAM_SPARSE_DATA;
+ }
- /* Encryption is only supported for file 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 */
+ /** Compression is not supported for Mac fork data */
if (stream == STREAM_MACOS_FORK_DATA) {
- ff_pkt->flags &= ~FO_GZIP;
+ ff_pkt->flags &= ~FO_COMPRESS;
}
- /*
+ /**
* Handle compression and encryption options
*/
-#ifdef HAVE_LIBZ
- if (ff_pkt->flags & FO_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 gzip should clear out
- * FO_GZIP above, and this code block should be unreachable. */
- ASSERT(!(ff_pkt->flags & FO_GZIP));
- return STREAM_NONE;
- }
+#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
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. */
}
-/*
+/**
* 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
* them in the encode_attribsEx() subroutine, but this is
* not recommended.
*/
-void encode_stat(char *buf, struct stat *statp, int32_t LinkFI, int data_stream)
+void encode_stat(char *buf, struct stat *statp, int stat_size, int32_t LinkFI, int data_stream)
{
char *p = buf;
/*
+ * We read the stat packet so make sure the caller's conception
+ * is the same as ours. They can be different if LARGEFILE is not
+ * the same when compiling this library and the calling program.
+ */
+ ASSERT(stat_size == (int)sizeof(struct stat));
+
+ /**
* Encode a stat packet. I should have done this more intelligently
* with a length so that it could be easily expanded.
*/
#endif
-/* Decode a stat packet from base64 characters */
-int decode_stat(char *buf, struct stat *statp, int32_t *LinkFI)
+/** Decode a stat packet from base64 characters */
+int decode_stat(char *buf, struct stat *statp, int stat_size, int32_t *LinkFI)
{
char *p = buf;
int64_t val;
+ /*
+ * We store into the stat packet so make sure the caller's conception
+ * is the same as ours. They can be different if LARGEFILE is not
+ * the same when compiling this library and the calling program.
+ */
+ ASSERT(stat_size == (int)sizeof(struct stat));
+
p += from_base64(&val, p);
plug(statp->st_dev, val);
p++;
return (int)val;
}
-/* Decode a LinkFI field of encoded stat packet */
-int32_t decode_LinkFI(char *buf, struct stat *statp)
+/** Decode a LinkFI field of encoded stat packet */
+int32_t decode_LinkFI(char *buf, struct stat *statp, int stat_size)
{
char *p = buf;
int64_t val;
+ /*
+ * We store into the stat packet so make sure the caller's conception
+ * is the same as ours. They can be different if LARGEFILE is not
+ * the same when compiling this library and the calling program.
+ */
+ ASSERT(stat_size == (int)sizeof(struct stat));
skip_nonspaces(&p); /* st_dev */
p++; /* skip space */
return 0;
}
-/*
+/**
* Set file modes, permissions and times
*
* fname is the original filename
return true;
}
if (attr->data_stream == STREAM_WIN32_DATA ||
- attr->data_stream == STREAM_WIN32_GZIP_DATA) {
+ attr->data_stream == STREAM_WIN32_GZIP_DATA ||
+ attr->data_stream == STREAM_WIN32_COMPRESSED_DATA) {
if (is_bopen(ofd)) {
bclose(ofd);
}
}
- /*
+ /**
* If Windows stuff failed, e.g. attempt to restore Unix file
* to Windows, simply fall through and we will do it the
* universal way.
}
}
- /*
+ /**
* We do not restore sockets, so skip trying to restore their
* attributes.
*/
ut.modtime = attr->statp.st_mtime;
/* ***FIXME**** optimize -- don't do if already correct */
- /*
+ /**
* For link, change owner of link using lchown, but don't
* try to do a chmod as that will update the file behind it.
*/
if (attr->type == FT_LNK) {
- /* Change owner of link, not of real file */
+ /** Change owner of link, not of real file */
if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0 && my_uid == 0) {
berrno be;
Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
ok = false;
}
- /*
+ /**
* Reset file times.
*/
if (utime(attr->ofname, &ut) < 0 && my_uid == 0) {
ok = false;
}
#ifdef HAVE_CHFLAGS
- /*
+ /**
* FreeBSD user flags
*
* Note, this should really be done before the utime() above,
#if !defined(HAVE_WIN32)
-/*
+/**
* It is possible to piggyback additional data e.g. ACLs on
* the encode_stat() data by returning the extended attributes
* here. They must be "self-contained" (i.e. you keep track
int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
{
#ifdef HAVE_DARWIN_OS
- /*
+ /**
* We save the Mac resource fork length so that on a
* restore, we can be sure we put back the whole resource.
*/
unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname);
- // try unicode version
+ /** try unicode version */
if (p_GetFileAttributesExW) {
POOLMEM* pwszBuf = get_pool_memory(PM_FNAME);
make_win32_path_UTF8_2_wchar(&pwszBuf, ff_pkt->fname);
return STREAM_UNIX_ATTRIBUTES_EX;
}
-/* Define attributes that are legal to set with SetFileAttributes() */
+/** Define attributes that are legal to set with SetFileAttributes() */
#define SET_ATTRS ( \
FILE_ATTRIBUTE_ARCHIVE| \
FILE_ATTRIBUTE_HIDDEN| \
FILE_ATTRIBUTE_TEMPORARY)
-/*
+/**
* Set Extended File Attributes for Win32
*
* fname is the original filename
ULARGE_INTEGER li;
POOLMEM *win32_ofile;
- // if we have neither ansi nor wchar version, we leave
+ /** if we have neither Win ansi nor wchar API, get out */
if (!(p_SetFileAttributesW || p_SetFileAttributesA)) {
return false;
}
p += from_base64(&val, p);
plug(atts.nFileSizeLow, val);
- /* Convert to Windows path format */
+ /** Convert to Windows path format */
win32_ofile = get_pool_memory(PM_FNAME);
unix_name_to_win32(&win32_ofile, attr->ofname);
- /* At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */
+ /** At this point, we have reconstructed the WIN32_FILE_ATTRIBUTE_DATA pkt */
if (!is_bopen(ofd)) {
Dmsg1(100, "File not open: %s\n", attr->ofname);