*
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2000-2004 Kern Sibbald and John Walker
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#include "bacula.h"
#include "find.h"
-#ifdef HAVE_CYGWIN
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
/* Forward referenced subroutines */
-static
-int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd);
+static int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd);
void unix_name_to_win32(POOLMEM **win32_name, char *name);
void win_error(JCR *jcr, char *prefix, POOLMEM *ofile);
HANDLE bget_handle(BFILE *bfd);
/* */
/*=============================================================*/
+/*
+ * Return the data stream that will be used
+ */
+int select_data_stream(FF_PKT *ff_pkt)
+{
+ int stream;
+
+ /* 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;
+ }
+#ifdef HAVE_LIBZ
+ if (ff_pkt->flags & FO_GZIP) {
+ if (stream == STREAM_WIN32_DATA) {
+ stream = STREAM_WIN32_GZIP_DATA;
+ } else if (stream == STREAM_FILE_DATA) {
+ stream = STREAM_GZIP_DATA;
+ } else {
+ stream = STREAM_SPARSE_GZIP_DATA;
+ }
+ }
+#endif
+ return stream;
+}
+
/*
* Encode a stat structure into a base64 character string
* them in the encode_attribsEx() subroutine, but this is
* not recommended.
*/
-void encode_stat(char *buf, struct stat *statp, uint32_t LinkFI)
+void encode_stat(char *buf, FF_PKT *ff_pkt, int data_stream)
{
char *p = buf;
+ struct stat *statp = &ff_pkt->statp;
/*
- * NOTE: we should use rdev as major and minor device if
- * it is a block or char device (S_ISCHR(statp->st_mode)
- * or S_ISBLK(statp->st_mode)). In all other cases,
- * it is not used.
- *
+ * Encode a stat packet. I should have done this more intelligently
+ * with a length so that it could be easily expanded.
*/
p += to_base64((int64_t)statp->st_dev, p);
*p++ = ' '; /* separate fields with a space */
*p++ = ' ';
p += to_base64((int64_t)statp->st_size, p);
*p++ = ' ';
+#ifndef HAVE_MINGW
p += to_base64((int64_t)statp->st_blksize, p);
*p++ = ' ';
p += to_base64((int64_t)statp->st_blocks, p);
*p++ = ' ';
+#else
+ p += to_base64((int64_t)0, p); /* output place holder */
+ *p++ = ' ';
+ p += to_base64((int64_t)0, p); /* output place holder */
+ *p++ = ' ';
+#endif
p += to_base64((int64_t)statp->st_atime, p);
*p++ = ' ';
p += to_base64((int64_t)statp->st_mtime, p);
*p++ = ' ';
p += to_base64((int64_t)statp->st_ctime, p);
*p++ = ' ';
- p += to_base64((int64_t)LinkFI, p);
+ p += to_base64((int64_t)ff_pkt->LinkFI, p);
+ *p++ = ' ';
-/* FreeBSD function */
#ifdef HAVE_CHFLAGS
- *p++ = ' ';
- p += to_base64((int64_t)statp->st_flags, p);
+ /* FreeBSD function */
+ p += to_base64((int64_t)statp->st_flags, p); /* output st_flags */
+#else
+ p += to_base64((int64_t)0, p); /* output place holder */
#endif
+ *p++ = ' ';
+ p += to_base64((int64_t)data_stream, p);
*p = 0;
return;
}
/* Decode a stat packet from base64 characters */
-void
-decode_stat(char *buf, struct stat *statp, uint32_t *LinkFI)
+int decode_stat(char *buf, struct stat *statp, int32_t *LinkFI)
{
char *p = buf;
int64_t val;
p += from_base64(&val, p);
statp->st_size = val;
p++;
+#ifndef HAVE_MINGW
p += from_base64(&val, p);
statp->st_blksize = val;
p++;
p += from_base64(&val, p);
statp->st_blocks = val;
p++;
+#else
+ p += from_base64(&val, p);
+// statp->st_blksize = val;
+ p++;
+ p += from_base64(&val, p);
+// statp->st_blocks = val;
+ p++;
+#endif
p += from_base64(&val, p);
statp->st_atime = val;
p++;
p++;
p += from_base64(&val, p);
statp->st_ctime = val;
+
/* Optional FileIndex of hard linked file data */
if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
p++;
p += from_base64(&val, p);
*LinkFI = (uint32_t)val;
- } else {
+ } else {
*LinkFI = 0;
- }
+ return 0;
+ }
-/* FreeBSD user flags */
-#ifdef HAVE_CHFLAGS
+ /* FreeBSD user flags */
if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
p++;
p += from_base64(&val, p);
+#ifdef HAVE_CHFLAGS
statp->st_flags = (uint32_t)val;
- } else {
+ } else {
statp->st_flags = 0;
- }
#endif
+ }
+
+ /* Look for data stream id */
+ if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
+ p++;
+ p += from_base64(&val, p);
+ } else {
+ val = 0;
+ }
+ return (int)val;
+}
+
+/* Decode a LinkFI field of encoded stat packet */
+int32_t decode_LinkFI(char *buf, struct stat *statp)
+{
+ char *p = buf;
+ int64_t val;
+
+ skip_nonspaces(&p); /* st_dev */
+ p++; /* skip space */
+ skip_nonspaces(&p); /* st_ino */
+ p++;
+ p += from_base64(&val, p);
+ statp->st_mode = val; /* st_mode */
+ p++;
+ skip_nonspaces(&p); /* st_nlink */
+ p++;
+ skip_nonspaces(&p); /* st_uid */
+ p++;
+ skip_nonspaces(&p); /* st_gid */
+ p++;
+ skip_nonspaces(&p); /* st_rdev */
+ p++;
+ skip_nonspaces(&p); /* st_size */
+ p++;
+ skip_nonspaces(&p); /* st_blksize */
+ p++;
+ skip_nonspaces(&p); /* st_blocks */
+ p++;
+ skip_nonspaces(&p); /* st_atime */
+ p++;
+ skip_nonspaces(&p); /* st_mtime */
+ p++;
+ skip_nonspaces(&p); /* st_ctime */
+
+ /* Optional FileIndex of hard linked file data */
+ if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) {
+ p++;
+ p += from_base64(&val, p);
+ return (int32_t)val;
+ }
+ return 0;
}
/*
mode_t old_mask;
int stat = 1;
-#ifdef HAVE_CYGWIN
- if (stream == STREAM_UNIX_ATTRIBUTES_EX &&
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
+ if (attr->stream == STREAM_UNIX_ATTRIBUTES_EX &&
set_win32_attributes(jcr, attr, ofd)) {
+ if (is_bopen(ofd)) {
+ bclose(ofd);
+ }
+ pm_strcpy(&attr->ofname, "*none*");
+ return 1;
+ }
+ if (attr->data_stream == STREAM_WIN32_DATA ||
+ attr->data_stream == STREAM_WIN32_GZIP_DATA) {
+ if (is_bopen(ofd)) {
+ bclose(ofd);
+ }
+ pm_strcpy(&attr->ofname, "*none*");
return 1;
}
+
+
/*
* If Windows stuff failed, e.g. attempt to restore Unix file
* to Windows, simply fall through and we will do it the
if (attr->type == FT_LNK) {
/* Change owner of link, not of real file */
if (lchown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
- Jmsg2(jcr, M_WARNING, 0, _("Unable to set file owner %s: ERR=%s\n"),
+ Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
attr->ofname, strerror(errno));
stat = 0;
}
} else {
if (chown(attr->ofname, attr->statp.st_uid, attr->statp.st_gid) < 0) {
- Jmsg2(jcr, M_WARNING, 0, _("Unable to set file owner %s: ERR=%s\n"),
+ Jmsg2(jcr, M_ERROR, 0, _("Unable to set file owner %s: ERR=%s\n"),
attr->ofname, strerror(errno));
stat = 0;
}
if (chmod(attr->ofname, attr->statp.st_mode) < 0) {
- Jmsg2(jcr, M_WARNING, 0, _("Unable to set file modes %s: ERR=%s\n"),
+ Jmsg2(jcr, M_ERROR, 0, _("Unable to set file modes %s: ERR=%s\n"),
attr->ofname, strerror(errno));
stat = 0;
}
/* FreeBSD user flags */
#ifdef HAVE_CHFLAGS
if (chflags(attr->ofname, attr->statp.st_flags) < 0) {
- Jmsg2(jcr, M_WARNING, 0, _("Unable to set file flags %s: ERR=%s\n"),
+ Jmsg2(jcr, M_ERROR, 0, _("Unable to set file flags %s: ERR=%s\n"),
attr->ofname, strerror(errno));
stat = 0;
}
stat = 0;
}
}
+ pm_strcpy(&attr->ofname, "*none*");
umask(old_mask);
return stat;
}
/* */
/*=============================================================*/
-#ifndef HAVE_CYGWIN
+#if !defined(HAVE_CYGWIN) && !defined(HAVE_WIN32)
/*
* It is possible to piggyback additional data e.g. ACLs on
/* */
/*=============================================================*/
-#ifdef HAVE_CYGWIN
+#if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
int encode_attribsEx(JCR *jcr, char *attribsEx, FF_PKT *ff_pkt)
{
attribsEx[0] = 0; /* no extended attributes */
- if (!p_GetFileAttributesEx) {
+ if (!p_GetFileAttributesEx) {
return STREAM_UNIX_ATTRIBUTES;
}
if (!p_GetFileAttributesEx(ff_pkt->sys_fname, GetFileExInfoStandard,
(LPVOID)&atts)) {
win_error(jcr, "GetFileAttributesEx:", ff_pkt->sys_fname);
- return STREAM_UNIX_ATTRIBUTES_EX;
+ return STREAM_UNIX_ATTRIBUTES;
}
p += to_base64((uint64_t)atts.dwFileAttributes, p);
* Returns: 1 on success
* 0 on failure
*/
-static
-int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
+static int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
{
char *p = attr->attrEx;
int64_t val;
ULARGE_INTEGER li;
POOLMEM *win32_ofile;
+ if (!p_GetFileAttributesEx) {
+ return 0;
+ }
+
if (!p || !*p) { /* we should have attributes */
Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid);
if (is_bopen(ofd)) {
/* 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);
bopen(ofd, attr->ofname, O_WRONLY|O_BINARY, 0); /* attempt to open the file */
NULL);
Dmsg3(100, "Error in %s on file %s: ERR=%s\n", prefix, win32_ofile, msg);
strip_trailing_junk(msg);
- Jmsg(jcr, M_INFO, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg);
+ Jmsg(jcr, M_ERROR, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg);
LocalFree(msg);
}
NULL);
strip_trailing_junk(msg);
if (jcr) {
- Jmsg2(jcr, M_INFO, 0, _("Error in %s: ERR=%s\n"), prefix, msg);
+ Jmsg2(jcr, M_ERROR, 0, _("Error in %s: ERR=%s\n"), prefix, msg);
} else {
MessageBox(NULL, msg, prefix, MB_OK);
}