#include "bacula.h"
#include "find.h"
-#ifdef HAVE_CYGWIN
+/* ===============================================================
+ *
+ * U N I X AND W I N D O W S
+ *
+ * ===============================================================
+ */
+
+int is_win32_stream(int stream)
+{
+ switch (stream) {
+ case STREAM_WIN32_DATA:
+ case STREAM_WIN32_GZIP_DATA:
+ return 1;
+ }
+ return 0;
+}
+
+const char *stream_to_ascii(int stream)
+{
+ static char buf[20];
+
+ switch (stream) {
+ case STREAM_GZIP_DATA:
+ return "GZIP data";
+ case STREAM_SPARSE_GZIP_DATA:
+ return "GZIP sparse data";
+ case STREAM_WIN32_DATA:
+ return "Win32 data";
+ case STREAM_WIN32_GZIP_DATA:
+ return "Win32 GZIP data";
+ case STREAM_UNIX_ATTRIBUTES:
+ return "File attributes";
+ case STREAM_FILE_DATA:
+ return "File data";
+ case STREAM_MD5_SIGNATURE:
+ return "MD5 signature";
+ case STREAM_UNIX_ATTRIBUTES_EX:
+ return "Extended attributes";
+ case STREAM_SPARSE_DATA:
+ return "Sparse data";
+ case STREAM_PROGRAM_NAMES:
+ return "Program names";
+ case STREAM_PROGRAM_DATA:
+ return "Program data";
+ case STREAM_SHA1_SIGNATURE:
+ return "SHA1 signature";
+ default:
+ sprintf(buf, "%d", stream);
+ return (const char *)buf;
+ }
+}
+
+
+
+/* ===============================================================
+ *
+ * W I N D O W S
+ *
+ * ===============================================================
+ */
+
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
void unix_name_to_win32(POOLMEM **win32_name, char *name);
extern "C" HANDLE get_osfhandle(int fd);
-void binit(BFILE *bfd, int use_win_api)
+
+void binit(BFILE *bfd)
{
bfd->fid = -1;
bfd->mode = BF_CLOSED;
- bfd->use_win_api = use_win_api;
+ bfd->use_backup_api = have_win32_api();
bfd->errmsg = NULL;
bfd->lpContext = NULL;
bfd->lerror = 0;
}
-HANDLE bget_handle(BFILE *bfd)
+/*
+ * Enables using the Backup API (win32_data).
+ * Returns 1 if function worked
+ * Returns 0 if failed (i.e. do not have Backup API on this machine)
+ */
+int set_win32_backup(BFILE *bfd)
{
- if (!bfd->use_win_api) {
- return get_osfhandle(bfd->fid);
+ /* We enable if possible here */
+ bfd->use_backup_api = have_win32_api();
+ return bfd->use_backup_api;
+}
+
+
+int set_portable_backup(BFILE *bfd)
+{
+ bfd->use_backup_api = 0;
+ return 1;
+}
+
+/*
+ * Return 1 if we are NOT using Win32 BackupWrite()
+ * return 0 if are
+ */
+int is_portable_backup(BFILE *bfd)
+{
+ return !bfd->use_backup_api;
+}
+
+int have_win32_api()
+{
+ return p_BackupRead && p_BackupWrite;
+}
+
+
+
+/*
+ * Return 1 if we support the stream
+ * 0 if we do not support the stream
+ */
+int is_stream_supported(int stream)
+{
+ /* No Win32 backup on this machine */
+ switch (stream) {
+#ifndef HAVE_LIBZ
+ case STREAM_GZIP_DATA:
+ case STREAM_SPARSE_GZIP_DATA:
+ return 0;
+#endif
+ case STREAM_WIN32_DATA:
+ case STREAM_WIN32_GZIP_DATA:
+ return have_win32_api();
+
+ /* Known streams */
+#ifdef HAVE_LIBZ
+ case STREAM_GZIP_DATA:
+ case STREAM_SPARSE_GZIP_DATA:
+#endif
+ case STREAM_UNIX_ATTRIBUTES:
+ case STREAM_FILE_DATA:
+ case STREAM_MD5_SIGNATURE:
+ case STREAM_UNIX_ATTRIBUTES_EX:
+ case STREAM_SPARSE_DATA:
+ case STREAM_PROGRAM_NAMES:
+ case STREAM_PROGRAM_DATA:
+ case STREAM_SHA1_SIGNATURE:
+ case 0: /* compatibility with old tapes */
+ return 1;
}
+ return 0;
+}
+
+HANDLE bget_handle(BFILE *bfd)
+{
return bfd->fh;
}
int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
{
POOLMEM *win32_fname;
-
- if (!bfd->use_win_api) {
- bfd->fid = open(fname, flags, mode);
- if (bfd->fid >= 0) {
- bfd->mode = BF_READ; /* not important if BF_READ or BF_WRITE */
- }
- return bfd->fid;
- }
+ DWORD dwaccess, dwflags;
/* Convert to Windows path format */
win32_fname = get_pool_memory(PM_FNAME);
unix_name_to_win32(&win32_fname, (char *)fname);
- if (flags & O_WRONLY) { /* creating */
+ if (flags & O_CREAT) { /* Create */
+ if (bfd->use_backup_api) {
+ dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
+ dwflags = FILE_FLAG_BACKUP_SEMANTICS;
+ } else {
+ dwaccess = GENERIC_WRITE;
+ dwflags = 0;
+ }
bfd->fh = CreateFile(win32_fname,
- FILE_ALL_ACCESS|WRITE_DAC|ACCESS_SYSTEM_SECURITY, /* access */
- 0,
- NULL, /* SecurityAttributes */
- CREATE_ALWAYS, /* CreationDisposition */
- FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, /* Flags and attributes */
- NULL); /* TemplateFile */
-
- if (bfd->fh == INVALID_HANDLE_VALUE) {
- bfd->lerror = GetLastError();
- bfd->mode = BF_CLOSED;
+ dwaccess, /* Requested access */
+ 0, /* Shared mode */
+ NULL, /* SecurityAttributes */
+ CREATE_ALWAYS, /* CreationDisposition */
+ dwflags, /* Flags and attributes */
+ NULL); /* TemplateFile */
+ bfd->mode = BF_WRITE;
+
+ } else if (flags & O_WRONLY) { /* Open existing for write */
+ if (bfd->use_backup_api) {
+#ifdef HAVE_WIN32
+ dwaccess = GENERIC_WRITE|/*FILE_ALL_ACCESS|*/WRITE_OWNER|WRITE_DAC/*|ACCESS_SYSTEM_SECURITY*/;
+#else
+ dwaccess = GENERIC_WRITE|FILE_ALL_ACCESS|WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY;
+#endif
+ dwflags = FILE_FLAG_BACKUP_SEMANTICS;
} else {
- bfd->mode = BF_WRITE;
+ dwaccess = GENERIC_WRITE;
+ dwflags = 0;
}
- } else {
bfd->fh = CreateFile(win32_fname,
- GENERIC_READ|ACCESS_SYSTEM_SECURITY, /* access */
- FILE_SHARE_READ, /* shared mode */
- NULL, /* SecurityAttributes */
- OPEN_EXISTING, /* CreationDisposition */
- FILE_FLAG_BACKUP_SEMANTICS, /* Flags and attributes */
- NULL); /* TemplateFile */
-
- if (bfd->fh == INVALID_HANDLE_VALUE) {
- bfd->lerror = GetLastError();
- bfd->mode = BF_CLOSED;
+ dwaccess, /* Requested access */
+ 0, /* Shared mode */
+ NULL, /* SecurityAttributes */
+ OPEN_EXISTING, /* CreationDisposition */
+ dwflags, /* Flags and attributes */
+ NULL); /* TemplateFile */
+ bfd->mode = BF_WRITE;
+
+ } else { /* Read */
+ if (bfd->use_backup_api) {
+ dwaccess = GENERIC_READ|READ_CONTROL|ACCESS_SYSTEM_SECURITY;
+ dwflags = FILE_FLAG_BACKUP_SEMANTICS;
} else {
- bfd->mode = BF_READ;
+ dwaccess = GENERIC_READ;
+ dwflags = 0;
}
+ bfd->fh = CreateFile(win32_fname,
+ dwaccess, /* Requested access */
+ FILE_SHARE_READ, /* Shared mode */
+ NULL, /* SecurityAttributes */
+ OPEN_EXISTING, /* CreationDisposition */
+ dwflags, /* Flags and attributes */
+ NULL); /* TemplateFile */
+ bfd->mode = BF_READ;
+ }
+
+ if (bfd->fh == INVALID_HANDLE_VALUE) {
+ bfd->lerror = GetLastError();
+ bfd->mode = BF_CLOSED;
}
bfd->errmsg = NULL;
bfd->lpContext = NULL;
+ free_pool_memory(win32_fname);
return bfd->mode == BF_CLOSED ? -1 : 1;
}
int bclose(BFILE *bfd)
{
int stat = 0;
- if (!bfd->use_win_api) {
- int stat = close(bfd->fid);
- bfd->fid = -1;
- bfd->mode = BF_CLOSED;
- return stat;
- }
+
if (bfd->errmsg) {
free_pool_memory(bfd->errmsg);
bfd->errmsg = NULL;
if (bfd->mode == BF_CLOSED) {
return 0;
}
- if (bfd->mode == BF_READ) {
+ if (bfd->use_backup_api && bfd->mode == BF_READ) {
BYTE buf[10];
- if (!bfd->lpContext && !BackupRead(bfd->fh,
+ if (!bfd->lpContext && !p_BackupRead(bfd->fh,
buf, /* buffer */
(DWORD)0, /* bytes to read */
&bfd->rw_bytes, /* bytes read */
&bfd->lpContext)) { /* Read context */
stat = -1;
}
- } else {
+ } else if (bfd->use_backup_api && bfd->mode == BF_WRITE) {
BYTE buf[10];
- if (!bfd->lpContext && !BackupWrite(bfd->fh,
+ if (!bfd->lpContext && !p_BackupWrite(bfd->fh,
buf, /* buffer */
(DWORD)0, /* bytes to read */
&bfd->rw_bytes, /* bytes written */
{
LPTSTR msg;
- if (!bfd->use_win_api) {
- return strerror(errno);
- }
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
*/
ssize_t bread(BFILE *bfd, void *buf, size_t count)
{
- if (!bfd->use_win_api) {
- return read(bfd->fid, buf, count);
- }
-
bfd->rw_bytes = 0;
- if (!BackupRead(bfd->fh,
- (BYTE *)buf,
- count,
- &bfd->rw_bytes,
- 0, /* no Abort */
- 1, /* Process Security */
- &bfd->lpContext)) { /* Context */
- bfd->lerror = GetLastError();
- return -1;
+
+ if (bfd->use_backup_api) {
+ if (!p_BackupRead(bfd->fh,
+ (BYTE *)buf,
+ count,
+ &bfd->rw_bytes,
+ 0, /* no Abort */
+ 1, /* Process Security */
+ &bfd->lpContext)) { /* Context */
+ bfd->lerror = GetLastError();
+ return -1;
+ }
+ } else {
+ if (!ReadFile(bfd->fh,
+ buf,
+ count,
+ &bfd->rw_bytes,
+ NULL)) {
+ bfd->lerror = GetLastError();
+ return -1;
+ }
}
+
return (ssize_t)bfd->rw_bytes;
}
ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
{
- if (!bfd->use_win_api) {
- return write(bfd->fid, buf, count);
- }
-
bfd->rw_bytes = 0;
- if (!BackupWrite(bfd->fh,
- (BYTE *)buf,
- count,
- &bfd->rw_bytes,
- 0, /* No abort */
- 1, /* Process Security */
- &bfd->lpContext)) { /* Context */
- bfd->lerror = GetLastError();
- return -1;
+
+ if (bfd->use_backup_api) {
+ if (!p_BackupWrite(bfd->fh,
+ (BYTE *)buf,
+ count,
+ &bfd->rw_bytes,
+ 0, /* No abort */
+ 1, /* Process Security */
+ &bfd->lpContext)) { /* Context */
+ bfd->lerror = GetLastError();
+ return -1;
+ }
+ } else {
+ if (!WriteFile(bfd->fh,
+ buf,
+ count,
+ &bfd->rw_bytes,
+ NULL)) {
+ bfd->lerror = GetLastError();
+ return -1;
+ }
}
return (ssize_t)bfd->rw_bytes;
}
off_t blseek(BFILE *bfd, off_t offset, int whence)
{
- if (!bfd->use_win_api) {
- return lseek(bfd->fid, offset, whence);
- }
+ /* ****FIXME**** this is needed if we want to read Win32 Archives */
return -1;
}
*
* ===============================================================
*/
-void binit(BFILE *bfd, int use_win_api)
+void binit(BFILE *bfd)
{
bfd->fid = -1;
}
+int have_win32_api()
+{
+ return 0; /* no can do */
+}
+
+/*
+ * Enables using the Backup API (win32_data).
+ * Returns 1 if function worked
+ * Returns 0 if failed (i.e. do not have Backup API on this machine)
+ */
+int set_win32_backup(BFILE *bfd)
+{
+ return 0; /* no can do */
+}
+
+
+int set_portable_backup(BFILE *bfd)
+{
+ return 1; /* no problem */
+}
+
+/*
+ * Return 1 if we are writing in portable format
+ * return 0 if not
+ */
+int is_portable_backup(BFILE *bfd)
+{
+ return 1; /* portable by definition */
+}
+
+int is_stream_supported(int stream)
+{
+ /* No Win32 backup on this machine */
+ switch (stream) {
+#ifndef HAVE_LIBZ
+ case STREAM_GZIP_DATA:
+ case STREAM_SPARSE_GZIP_DATA:
+#endif
+ case STREAM_WIN32_DATA:
+ case STREAM_WIN32_GZIP_DATA:
+ return 0;
+
+ /* Known streams */
+#ifdef HAVE_LIBZ
+ case STREAM_GZIP_DATA:
+ case STREAM_SPARSE_GZIP_DATA:
+#endif
+ case STREAM_UNIX_ATTRIBUTES:
+ case STREAM_FILE_DATA:
+ case STREAM_MD5_SIGNATURE:
+ case STREAM_UNIX_ATTRIBUTES_EX:
+ case STREAM_SPARSE_DATA:
+ case STREAM_PROGRAM_NAMES:
+ case STREAM_PROGRAM_DATA:
+ case STREAM_SHA1_SIGNATURE:
+ case 0: /* compatibility with old tapes */
+ return 1;
+
+ }
+ return 0;
+}
+
int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode)
{
- return bfd->fid = open(fname, flags, mode);
+ bfd->fid = open(fname, flags, mode);
+ bfd->berrno = errno;
+ Dmsg1(50, "Open file %d\n", bfd->fid);
+ return bfd->fid;
}
int bclose(BFILE *bfd)
{
- int stat = close(bfd->fid);
+ int stat;
+ Dmsg1(50, "Close file %d\n", bfd->fid);
+ if (bfd->fid == -1) {
+ return 0;
+ }
+ stat = close(bfd->fid);
+ bfd->berrno = errno;
bfd->fid = -1;
+
return stat;
}
ssize_t bread(BFILE *bfd, void *buf, size_t count)
{
- return read(bfd->fid, buf, count);
+ ssize_t stat;
+ stat = read(bfd->fid, buf, count);
+ bfd->berrno = errno;
+ return stat;
}
ssize_t bwrite(BFILE *bfd, void *buf, size_t count)
{
- return write(bfd->fid, buf, count);
+ ssize_t stat;
+ stat = write(bfd->fid, buf, count);
+ bfd->berrno = errno;
+ return stat;
}
int is_bopen(BFILE *bfd)
off_t blseek(BFILE *bfd, off_t offset, int whence)
{
- return lseek(bfd->fid, offset, whence);
+ off_t pos;
+ pos = lseek(bfd->fid, offset, whence);
+ bfd->berrno = errno;
+ return pos;
}
char *berror(BFILE *bfd)
{
- return strerror(errno);
+ return strerror(bfd->berrno);
}
#endif