From 772c0adfb65f6d777eab2ba6c1e65a560f9e7af8 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Wed, 16 Apr 2003 17:26:35 +0000 Subject: [PATCH] Win32 backup API implementation git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@442 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ReleaseNotes | 6 +- bacula/kernstodo | 18 ++- bacula/src/baconfig.h | 2 + bacula/src/console/Makefile.in | 2 +- bacula/src/dird/ua_cmds.c | 2 +- bacula/src/dird/ua_status.c | 10 +- bacula/src/filed/backup.c | 24 ++-- bacula/src/filed/job.c | 4 + bacula/src/filed/restore.c | 13 +- bacula/src/filed/verify.c | 11 +- bacula/src/findlib/attribs.c | 187 +++++++++++++++++-------- bacula/src/findlib/bfile.c | 232 ++++++++++++++++++++++++++++++- bacula/src/findlib/create_file.c | 23 +-- bacula/src/findlib/find.h | 141 +++++++++++-------- bacula/src/findlib/protos.h | 8 +- bacula/src/jcr.h | 1 + bacula/src/version.h | 4 +- 17 files changed, 517 insertions(+), 171 deletions(-) diff --git a/bacula/ReleaseNotes b/bacula/ReleaseNotes index d79a6d93f7..b4bf68611a 100644 --- a/bacula/ReleaseNotes +++ b/bacula/ReleaseNotes @@ -34,14 +34,14 @@ Other Changes this Release: several other utility programs. - Full listing of most catalog records (llist command). - Relabel Purged tapes with the relabel command. -- Correct misentered path separators on Win32 systems to +- Correct backwards path separators on Win32 systems to prevent creating files names with mixed conventions. - Print IP address on failed connections to servers. - Cancel command works much better (cancels waiting jobs in Dir and in SD). - Now have reasonable (but still small) regression script. -- New Console commands for aiding scripting (input, output, tee, - time, wait). +- New Console commands for aiding scripting (@input, @output, @tee, + @time, @version and wait). Items to note: - Version 1.29 File daemons can be used with version 1.30. However, diff --git a/bacula/kernstodo b/bacula/kernstodo index 346cfa342e..f3702f03f8 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -25,6 +25,8 @@ For 1.30 release: - Fix "access not allowed" for backup of files on WinXP. - Document new transparent Console commands and wait command. - Document new immediate File save capability. +- Document OPTIMIZE TABLE in MySQL +- Fix watchdog pthread crash on Win32 - Figure out how to use ssh or stunnel to protect Bacula communications. @@ -32,6 +34,21 @@ After 1.30: - Make | and < work on FD side. - Pass prefix_links to FD. - Implement a M_SECURITY message class. +- Implement disk spooling. Two parts: 1. Spool to disk then + immediately to tape to speed up tape operations. 2. Spool to + disk only when the tape is full, then when a tape is hung move + it to tape. +- From Phil Stracchino: + It would probably be a per-client option, and would be called + something like, say, "Automatically purge obsoleted jobs". What it + would do is, when you successfully complete a Differential backup of a + client, it would automatically purge all Incremental backups for that + client that are rendered redundant by that Differential. Likewise, + when a Full backup on a client completed, it would automatically purge + all Differential and Incremental jobs obsoleted by that Full backup. + This would let people minimize the number of tapes they're keeping on + hand without having to master the art of retention times. + - Allow multiple Storage specifications (or multiple names on a single Storage specification) in the Job record. Thus a job can be backed up to a number of storage devices. @@ -88,7 +105,6 @@ After 1.30: - Why are save/restore of device different sizes (sparse?) Yup! Fix it. - Implement some way for the Console to dynamically create a job. - Restore to a particular time -- e.g. before date, after date. -- Implement disk spooling - Solaris -I on tar for include list - Prohibit backing up archive device (findlib/find_one.c:128) - Need a verbose mode in restore, perhaps to bsr. diff --git a/bacula/src/baconfig.h b/bacula/src/baconfig.h index a332332d08..5fb2ff5c99 100644 --- a/bacula/src/baconfig.h +++ b/bacula/src/baconfig.h @@ -106,6 +106,8 @@ #define STREAM_PROGRAM_NAMES 8 /* program names for program data */ #define STREAM_PROGRAM_DATA 9 /* Data needing program */ #define STREAM_SHA1_SIGNATURE 10 /* SHA1 signature for the file */ +#define STREAM_WIN32_DATA 11 /* Win32 BackupRead data */ +#define STREAM_WIN32_GZIP_DATA 12 /* Gzipped Win32 BackupRead data */ /* * Internal code for Signature types diff --git a/bacula/src/console/Makefile.in b/bacula/src/console/Makefile.in index f393800327..2d0977f457 100644 --- a/bacula/src/console/Makefile.in +++ b/bacula/src/console/Makefile.in @@ -48,7 +48,7 @@ console: $(CONSOBJS) ../lib/libbac.a ../cats/libsql.a $(LIBS) $(DLIB) $(CONS_LIBS) -lbac -lsql -lm static-console: $(CONSOBJS) ../lib/libbac.a ../cats/libsql.a - $(CXX) $(LDFLAGS) $(CONS_LDFLAGS) -L../lib -L../cats -o $@ $(CONSOBJS) \ + $(CXX) -static $(LDFLAGS) $(CONS_LDFLAGS) -L../lib -L../cats -o $@ $(CONSOBJS) \ $(LIBS) $(DLIB) $(CONS_LIBS) -lbac -lsql -lm strip $@ diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 0d69982c08..7daf368e50 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -1391,7 +1391,7 @@ int quitcmd(UAContext *ua, char *cmd) */ int waitcmd(UAContext *ua, char *cmd) { - usleep(300000); + usleep(500000); for (int running=1; running; ) { running = 0; lock_jcr_chain(); diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 4cb06736c9..f543fd0147 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -159,7 +159,7 @@ static void do_all_status(UAContext *ua, char *cmd) client = NULL; for (i=0; (client = (CLIENT *)GetNextRes(R_CLIENT, (RES *)client)); i++) { } - unique_client = (CLIENT **) malloc(i * sizeof(CLIENT)); + unique_client = (CLIENT **)malloc(i * sizeof(CLIENT)); /* Find Unique Client address/port */ client = (CLIENT *)GetNextRes(R_CLIENT, NULL); i = 0; @@ -322,6 +322,10 @@ static void do_storage_status(UAContext *ua, STORE *store) if (!connect_to_storage_daemon(ua->jcr, 1, 15, 0)) { bsendmsg(ua, _("\nFailed to connect to Storage daemon %s.\n====\n"), store->hdr.name); + if (ua->jcr->store_bsock) { + bnet_close(ua->jcr->store_bsock); + ua->jcr->store_bsock = NULL; + } return; } Dmsg0(20, _("Connected to storage daemon\n")); @@ -356,6 +360,10 @@ static void do_client_status(UAContext *ua, CLIENT *client) if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) { bsendmsg(ua, _("Failed to connect to Client %s.\n====\n"), client->hdr.name); + if (ua->jcr->file_bsock) { + bnet_close(ua->jcr->file_bsock); + ua->jcr->file_bsock = NULL; + } return; } Dmsg0(20, _("Connected to file daemon\n")); diff --git a/bacula/src/filed/backup.c b/bacula/src/filed/backup.c index 794e26c953..98b0988006 100644 --- a/bacula/src/filed/backup.c +++ b/bacula/src/filed/backup.c @@ -175,6 +175,8 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) return 1; } + binit(&ff_pkt->bfd, jcr->use_win_backup_api); + /* Open any file with data that we intend to save */ if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && ff_pkt->statp.st_size > 0) || @@ -187,13 +189,12 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) } if (bopen(&ff_pkt->bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0) < 0) { ff_pkt->ff_errno = errno; - Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); + Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, + berror(&ff_pkt->bfd)); stop_thread_timer(tid); return 1; } stop_thread_timer(tid); - } else { - binit(&ff_pkt->bfd); /* mark file not opened */ } Dmsg1(130, "bfiled: sending %s to stored\n", ff_pkt->fname); @@ -211,7 +212,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) * Send Attributes header to Storage daemon * */ -/* #ifndef FD_NO_SEND_TEST */ if (!bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, stream)) { if (is_bopen(&ff_pkt->bfd)) { bclose(&ff_pkt->bfd); @@ -256,7 +256,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) return 0; } bnet_sig(sd, BNET_EOD); /* indicate end of attributes data */ -/* #endif */ /* * If the file has data, read it and send to the Storage daemon @@ -301,7 +300,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) } #endif -/* #ifndef FD_NO_SEND_TEST */ /* * Send Data header to Storage daemon * @@ -312,7 +310,6 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) return 0; } Dmsg1(100, ">stored: datahdr %s\n", sd->msg); -/* #endif */ if (ff_pkt->flags & FO_MD5) { MD5Init(&md5c); @@ -384,7 +381,7 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) } #endif -/* #ifndef FD_NO_SEND_TEST */ + /* #ifndef FD_NO_SEND_TEST */ /* Send the buffer to the Storage daemon */ if (!sparseBlock) { if (ff_pkt->flags & FO_SPARSE) { @@ -400,50 +397,45 @@ static int save_file(FF_PKT *ff_pkt, void *vjcr) } } Dmsg1(130, "Send data to SD len=%d\n", sd->msglen); -/* #endif */ + /* #endif */ jcr->JobBytes += sd->msglen; /* count bytes saved possibly compressed */ sd->msg = msgsave; /* restore read buffer */ } /* end while read file data */ + if (sd->msglen < 0) { Jmsg(jcr, M_ERROR, 0, _("Read error on file %s. ERR=%s\n"), - ff_pkt->fname, strerror(errno)); + ff_pkt->fname, berror(&ff_pkt->bfd)); } bclose(&ff_pkt->bfd); /* close file */ -/* #ifndef FD_NO_SEND_TEST */ if (!bnet_sig(sd, BNET_EOD)) { /* indicate end of file data */ set_jcr_job_status(jcr, JS_ErrorTerminated); return 0; } -/* #endif */ } /* Terminate any MD5 signature and send it to Storage daemon and the Director */ if (gotMD5 && ff_pkt->flags & FO_MD5) { MD5Final(signature, &md5c); -/* #ifndef FD_NO_SEND_TEST */ bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_MD5_SIGNATURE); Dmsg1(100, "bfiled>stored:header %s\n", sd->msg); memcpy(sd->msg, signature, 16); sd->msglen = 16; bnet_send(sd); bnet_sig(sd, BNET_EOD); /* end of MD5 */ -/* #endif */ gotMD5 = 0; } else if (gotSHA1 && ff_pkt->flags & FO_SHA1) { /* Terminate any SHA1 signature and send it to Storage daemon and the Director */ SHA1Final(&sha1c, signature); -/* #ifndef FD_NO_SEND_TEST */ bnet_fsend(sd, "%ld %d 0", jcr->JobFiles, STREAM_SHA1_SIGNATURE); Dmsg1(100, "bfiled>stored:header %s\n", sd->msg); memcpy(sd->msg, signature, 20); sd->msglen = 20; bnet_send(sd); bnet_sig(sd, BNET_EOD); /* end of SHA1 */ -/* #endif */ gotMD5 = 0; } return 1; diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index e90e56dc13..31df986bf0 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -157,6 +157,7 @@ void *handle_client_request(void *dirp) jcr = new_jcr(sizeof(JCR), filed_free_jcr); /* create JCR */ jcr->dir_bsock = dir; jcr->ff = init_find_files(); + jcr->use_win_backup_api = 0; jcr->start_time = time(NULL); jcr->last_fname = get_pool_memory(PM_FNAME); jcr->last_fname[0] = 0; @@ -288,6 +289,9 @@ static int job_cmd(JCR *jcr) } jcr->sd_auth_key = bstrdup(sd_auth_key); free_pool_memory(sd_auth_key); + if (jcr->use_win_backup_api) { + SetServicePrivileges(jcr); + } Dmsg2(120, "JobId=%d Auth=%s\n", jcr->JobId, jcr->sd_auth_key); return bnet_fsend(dir, OKjob); } diff --git a/bacula/src/filed/restore.c b/bacula/src/filed/restore.c index da0f6c136f..72f3d680a8 100644 --- a/bacula/src/filed/restore.c +++ b/bacula/src/filed/restore.c @@ -64,7 +64,7 @@ void do_restore(JCR *jcr) wherelen = strlen(jcr->where); - binit(&bfd); + binit(&bfd, jcr->use_win_backup_api); sd = jcr->store_bsock; set_jcr_job_status(jcr, JS_Running); @@ -268,7 +268,8 @@ void do_restore(JCR *jcr) extract = FALSE; stat = create_file(jcr, fname, ofile, lname, type, - stream, &statp, attribsEx, &bfd, jcr->replace); + stream, &statp, attribsEx, &bfd, jcr->replace, + jcr->use_win_backup_api); switch (stat) { case CF_ERROR: case CF_SKIP: @@ -311,7 +312,7 @@ void do_restore(JCR *jcr) fileAddr = faddr; if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) { Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), - edit_uint64(fileAddr, ec1), ofile, strerror(errno)); + edit_uint64(fileAddr, ec1), ofile, berror(&bfd)); goto bail_out; } } @@ -322,7 +323,7 @@ void do_restore(JCR *jcr) Dmsg2(30, "Write %u bytes, total before write=%u\n", wsize, total); if ((uint32_t)bwrite(&bfd, wbuf, wsize) != wsize) { Dmsg0(0, "===Write error===\n"); - Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), ofile, strerror(errno)); + Jmsg2(jcr, M_ERROR, 0, _("Write error on %s: %s\n"), ofile, berror(&bfd)); goto bail_out; } total += wsize; @@ -349,7 +350,7 @@ void do_restore(JCR *jcr) fileAddr = faddr; if (blseek(&bfd, (off_t)fileAddr, SEEK_SET) < 0) { Jmsg3(jcr, M_ERROR, 0, _("Seek to %s error on %s: ERR=%s\n"), - edit_uint64(fileAddr, ec1), ofile, strerror(errno)); + edit_uint64(fileAddr, ec1), ofile, berror(&bfd)); goto bail_out; } } @@ -368,7 +369,7 @@ void do_restore(JCR *jcr) Dmsg2(100, "Write uncompressed %d bytes, total before write=%d\n", compress_len, total); if ((uLong)bwrite(&bfd, jcr->compress_buf, compress_len) != compress_len) { Dmsg0(0, "===Write error===\n"); - Jmsg2(jcr, M_ERROR, 0, "Write error on %s: %s\n", ofile, strerror(errno)); + Jmsg2(jcr, M_ERROR, 0, "Write error on %s: %s\n", ofile, berror(&bfd)); goto bail_out; } total += compress_len; diff --git a/bacula/src/filed/verify.c b/bacula/src/filed/verify.c index e996fc6fa5..a726ae3ad7 100644 --- a/bacula/src/filed/verify.c +++ b/bacula/src/filed/verify.c @@ -137,17 +137,17 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) return 1; } + binit(&bfd, jcr->use_win_backup_api); if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && ff_pkt->statp.st_size > 0) || ff_pkt->type == FT_RAW || ff_pkt->type == FT_FIFO) { if ((bopen(&bfd, ff_pkt->fname, O_RDONLY | O_BINARY, 0)) < 0) { ff_pkt->ff_errno = errno; - Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open %s: ERR=%s.\n"), ff_pkt->fname, strerror(ff_pkt->ff_errno)); + Jmsg(jcr, M_NOTSAVED, -1, _(" Cannot open %s: ERR=%s.\n"), + ff_pkt->fname, berror(&bfd)); return 1; } - } else { - binit(&bfd); } encode_stat(attribs, &ff_pkt->statp, ff_pkt->LinkFI); @@ -157,7 +157,6 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) pm_strcpy(&jcr->last_fname, ff_pkt->fname); V(jcr->mutex); - /* * Send file attributes to Director * File_index @@ -199,7 +198,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) } if (n < 0) { Jmsg(jcr, M_WARNING, -1, _("Error reading file %s: ERR=%s\n"), - ff_pkt->fname, strerror(errno)); + ff_pkt->fname, berror(&bfd)); } MD5Final(signature, &md5c); @@ -217,7 +216,7 @@ static int verify_file(FF_PKT *ff_pkt, void *pkt) } if (n < 0) { Jmsg(jcr, M_WARNING, -1, _("Error reading file %s: ERR=%s\n"), - ff_pkt->fname, strerror(errno)); + ff_pkt->fname, berror(&bfd)); } SHA1Final(&sha1c, signature); diff --git a/bacula/src/findlib/attribs.c b/bacula/src/findlib/attribs.c index db3e63a306..1e21ac8b5e 100755 --- a/bacula/src/findlib/attribs.c +++ b/bacula/src/findlib/attribs.c @@ -33,16 +33,15 @@ #include "jcr.h" #ifdef HAVE_CYGWIN -#include /* Forward referenced subroutines */ static int set_win32_attributes(void *jcr, char *fname, char *ofile, char *lname, - int type, int stream, struct stat *statp, - char *attribsEx, BFILE *ofd); + int type, int stream, struct stat *statp, + char *attribsEx, BFILE *ofd); void unix_name_to_win32(POOLMEM **win32_name, char *name); -extern "C" HANDLE get_osfhandle(int fd); void win_error(void *jcr, char *prefix, POOLMEM *ofile); +HANDLE bget_handle(BFILE *bfd); #endif /* For old systems that don't have lchown() use chown() */ @@ -51,9 +50,9 @@ void win_error(void *jcr, char *prefix, POOLMEM *ofile); #endif /*=============================================================*/ -/* */ -/* *** A l l S y s t e m s *** */ -/* */ +/* */ +/* *** A l l S y s t e m s *** */ +/* */ /*=============================================================*/ @@ -65,7 +64,7 @@ void encode_stat(char *buf, struct stat *statp, uint32_t LinkFI) * 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. + * it is not used. * */ p += to_base64((int64_t)statp->st_dev, p); @@ -95,6 +94,7 @@ void encode_stat(char *buf, struct stat *statp, uint32_t LinkFI) p += to_base64((int64_t)statp->st_ctime, p); *p++ = ' '; p += to_base64((int64_t)LinkFI, p); + /* FreeBSD function */ #ifdef HAVE_CHFLAGS *p++ = ' '; @@ -115,7 +115,7 @@ decode_stat(char *buf, struct stat *statp, uint32_t *LinkFI) p += from_base64(&val, p); statp->st_dev = val; - p++; /* skip space */ + p++; /* skip space */ p += from_base64(&val, p); statp->st_ino = val; p++; @@ -159,6 +159,7 @@ decode_stat(char *buf, struct stat *statp, uint32_t *LinkFI) } else { *LinkFI = 0; } + /* FreeBSD user flags */ #ifdef HAVE_CHFLAGS if (*p == ' ' || (*p != 0 && *(p+1) == ' ')) { @@ -178,31 +179,31 @@ decode_stat(char *buf, struct stat *statp, uint32_t *LinkFI) * ofile is the output filename (may be in a different directory) * * Returns: 1 on success - * 0 on failure + * 0 on failure */ int set_attributes(void *jcr, char *fname, char *ofile, char *lname, - int type, int stream, struct stat *statp, - char *attribsEx, BFILE *ofd) + int type, int stream, struct stat *statp, + char *attribsEx, BFILE *ofd) { - struct utimbuf ut; + struct utimbuf ut; mode_t old_mask; int stat = 1; #ifdef HAVE_CYGWIN if (set_win32_attributes(jcr, fname, ofile, lname, type, stream, - statp, attribsEx, ofd)) { + statp, attribsEx, ofd)) { return 1; } /* * If Windows stuff failed, e.g. attempt to restore Unix file - * to Windows, simply fall through and we will do it the + * to Windows, simply fall through and we will do it the * universal way. */ #endif old_mask = umask(0); if (is_bopen(ofd)) { - bclose(ofd); /* first close file */ + bclose(ofd); /* first close file */ } ut.actime = statp->st_atime; @@ -211,43 +212,42 @@ int set_attributes(void *jcr, char *fname, char *ofile, char *lname, /* ***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. + * try to do a chmod as that will update the file behind it. */ if (type == FT_LNK) { /* Change owner of link, not of real file */ if (lchown(ofile, statp->st_uid, statp->st_gid) < 0) { Jmsg2(jcr, M_WARNING, 0, "Unable to set file owner %s: ERR=%s\n", - ofile, strerror(errno)); - stat = 0; + ofile, strerror(errno)); + stat = 0; } } else { if (chown(ofile, statp->st_uid, statp->st_gid) < 0) { Jmsg2(jcr, M_WARNING, 0, "Unable to set file owner %s: ERR=%s\n", - ofile, strerror(errno)); - stat = 0; + ofile, strerror(errno)); + stat = 0; } if (chmod(ofile, statp->st_mode) < 0) { Jmsg2(jcr, M_WARNING, 0, "Unable to set file modes %s: ERR=%s\n", - ofile, strerror(errno)); - stat = 0; + ofile, strerror(errno)); + stat = 0; } /* FreeBSD user flags */ #ifdef HAVE_CHFLAGS if (chflags(ofile, statp->st_flags) < 0) { Jmsg2(jcr, M_WARNING, 0, "Unable to set file flags %s: ERR=%s\n", - ofile, strerror(errno)); - stat = 0; + ofile, strerror(errno)); + stat = 0; } - #endif /* * Reset file times. */ if (utime(ofile, &ut) < 0) { Jmsg2(jcr, M_ERROR, 0, "Unable to set file times %s: ERR=%s\n", - ofile, strerror(errno)); - stat = 0; + ofile, strerror(errno)); + stat = 0; } } umask(old_mask); @@ -256,9 +256,9 @@ int set_attributes(void *jcr, char *fname, char *ofile, char *lname, /*=============================================================*/ -/* */ -/* * * * U n i x * * * * */ -/* */ +/* */ +/* * * * U n i x * * * * */ +/* */ /*=============================================================*/ #ifndef HAVE_CYGWIN @@ -269,18 +269,22 @@ int set_attributes(void *jcr, char *fname, char *ofile, char *lname, */ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) { - *attribsEx = 0; /* no extended attributes */ + *attribsEx = 0; /* no extended attributes */ return STREAM_UNIX_ATTRIBUTES; } +void SetServicePrivileges(void *jcr) + { } + + #endif /*=============================================================*/ -/* */ -/* * * * W i n 3 2 * * * * */ -/* */ +/* */ +/* * * * W i n 3 2 * * * * */ +/* */ /*=============================================================*/ #ifdef HAVE_CYGWIN @@ -293,7 +297,7 @@ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) WIN32_FILE_ATTRIBUTE_DATA atts; ULARGE_INTEGER li; - attribsEx[0] = 0; /* no extended attributes */ + attribsEx[0] = 0; /* no extended attributes */ if (NoGetFileAttributesEx) { return STREAM_UNIX_ATTRIBUTES; @@ -301,7 +305,7 @@ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) unix_name_to_win32(&ff_pkt->sys_fname, ff_pkt->fname); if (!GetFileAttributesEx(ff_pkt->sys_fname, GetFileExInfoStandard, - (LPVOID)&atts)) { + (LPVOID)&atts)) { win_error(jcr, "GetFileAttributesEx:", ff_pkt->sys_fname); return STREAM_WIN32_ATTRIBUTES; } @@ -336,7 +340,7 @@ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) FILE_ATTRIBUTE_OFFLINE| \ FILE_ATTRIBUTE_READONLY| \ FILE_ATTRIBUTE_SYSTEM| \ - FILE_ATTRIBUTE_TEMPORARY) + FILE_ATTRIBUTE_TEMPORARY) /* @@ -346,12 +350,12 @@ int encode_attribsEx(void *jcr, char *attribsEx, FF_PKT *ff_pkt) * ofile is the output filename (may be in a different directory) * * Returns: 1 on success - * 0 on failure + * 0 on failure */ static int set_win32_attributes(void *jcr, char *fname, char *ofile, char *lname, - int type, int stream, struct stat *statp, - char *attribsEx, BFILE *ofd) + int type, int stream, struct stat *statp, + char *attribsEx, BFILE *ofd) { char *p = attribsEx; int64_t val; @@ -360,10 +364,10 @@ int set_win32_attributes(void *jcr, char *fname, char *ofile, char *lname, int stat; POOLMEM *win32_ofile; - if (!p || !*p) { /* we should have attributes */ + if (!p || !*p) { /* we should have attributes */ Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", ofile, ofd->fid); if (is_bopen(ofd)) { - bclose(ofd); + bclose(ofd); } return 0; } else { @@ -372,17 +376,17 @@ int set_win32_attributes(void *jcr, char *fname, char *ofile, char *lname, p += from_base64(&val, p); atts.dwFileAttributes = val; - p++; /* skip space */ + p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftCreationTime.dwLowDateTime = li.LowPart; atts.ftCreationTime.dwHighDateTime = li.HighPart; - p++; /* skip space */ + p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastAccessTime.dwLowDateTime = li.LowPart; atts.ftLastAccessTime.dwHighDateTime = li.HighPart; - p++; /* skip space */ + p++; /* skip space */ p += from_base64(&val, p); li.QuadPart = val; atts.ftLastWriteTime.dwLowDateTime = li.LowPart; @@ -402,15 +406,15 @@ int set_win32_attributes(void *jcr, char *fname, char *ofile, char *lname, if (!is_bopen(ofd)) { Dmsg1(100, "File not open: %s\n", ofile); - bopen(ofd, ofile, O_RDWR|O_BINARY, 0); /* attempt to open the file */ + bopen(ofd, ofile, O_WRONLY|O_BINARY, 0); /* attempt to open the file */ } if (is_bopen(ofd)) { Dmsg1(100, "SetFileTime %s\n", ofile); - stat = SetFileTime(get_osfhandle(ofd->fid), - &atts.ftCreationTime, - &atts.ftLastAccessTime, - &atts.ftLastWriteTime); + stat = SetFileTime(bget_handle(ofd), + &atts.ftCreationTime, + &atts.ftLastAccessTime, + &atts.ftLastWriteTime); if (stat != 1) { win_error(jcr, "SetFileTime:", win32_ofile); } @@ -432,14 +436,15 @@ void win_error(void *vjcr, char *prefix, POOLMEM *win32_ofile) DWORD lerror = GetLastError(); LPTSTR msg; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| - FORMAT_MESSAGE_FROM_SYSTEM, - NULL, - lerror, - 0, - (LPTSTR)&msg, - 0, - NULL); + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + lerror, + 0, + (LPTSTR)&msg, + 0, + NULL); Dmsg3(100, "Error in %s on file %s: ERR=%s\n", prefix, win32_ofile, msg); + strip_trailing_junk(msg); Jmsg3(jcr, M_INFO, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg); LocalFree(msg); } @@ -454,4 +459,68 @@ void unix_name_to_win32(POOLMEM **win32_name, char *name) cygwin_conv_to_win32_path(name, *win32_name); } -#endif /* HAVE_CYGWIN */ +/* + * Setup privileges we think we will need. We probably do not need + * the SE_SECURITY_NAME, but since nothing seems to be working, + * we get it hoping to fix the problems. + */ +void SetServicePrivileges(void *jcr) +{ + HANDLE hToken; + TOKEN_PRIVILEGES tkp; + POOLMEM *dummy = "*none*"; + // Get a token for this process. + if (!OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { + win_error(jcr, "OpenProcessToken", dummy); + /* Forge on anyway */ + } + + // Get the LUID for the security privilege. + if (!LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &tkp.Privileges[0].Luid)) { + win_error(jcr, "LookupPrivilegeValue", dummy); + } + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get the security privilege for this process. + if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES)NULL, (PDWORD)0)) { + win_error(jcr, "AdjustTokenPrivileges SE_PRIVILEGE_ENABLED", dummy); +// MessageBox(NULL, "Get security priv failed: AdjustTokePrivileges", "backup", MB_OK); + } + + // Get the LUID for the backup privilege. + if (!LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &tkp.Privileges[0].Luid)) { + win_error(jcr, "LookupPrivilegeValue", dummy); + } + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get the backup privilege for this process. + if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES)NULL, (PDWORD)0)) { + win_error(jcr, "AdjustTokenPrivileges SE_BACKUP_NAME", dummy); +// MessageBox(NULL, "Get backup priv failed: AdjustTokePrivileges", "backup", MB_OK); + } + + // Get the LUID for the restore privilege. + if (!LookupPrivilegeValue(NULL, SE_RESTORE_NAME, &tkp.Privileges[0].Luid)) { + win_error(jcr, "LookupPrivilegeValue", dummy); + } + + tkp.PrivilegeCount = 1; // one privilege to set + tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + // Get the restore privilege for this process. + if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof(TOKEN_PRIVILEGES), + (PTOKEN_PRIVILEGES)NULL, (PDWORD)0)) { + win_error(jcr, "AdjustTokenPrivileges SE_RESTORE_NAME", dummy); +// MessageBox(NULL, "Get restore priv failed: AdjustTokePrivileges", "restore", MB_OK); + } +} + + +#endif /* HAVE_CYGWIN */ diff --git a/bacula/src/findlib/bfile.c b/bacula/src/findlib/bfile.c index 74618d13fd..45a1edb320 100644 --- a/bacula/src/findlib/bfile.c +++ b/bacula/src/findlib/bfile.c @@ -31,15 +31,234 @@ #include "bacula.h" #include "find.h" +#ifdef HAVE_CYGWIN -void binit(BFILE *bfd) +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) +{ + bfd->fid = -1; + bfd->mode = BF_CLOSED; + bfd->use_win_api = use_win_api; + bfd->errmsg = NULL; + bfd->lpContext = NULL; + bfd->lerror = 0; +} + +HANDLE bget_handle(BFILE *bfd) +{ + if (!bfd->use_win_api) { + return get_osfhandle(bfd->fid); + } + 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; + } + + /* 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 */ + bfd->fh = CreateFile(win32_fname, + WRITE_OWNER|WRITE_DAC|ACCESS_SYSTEM_SECURITY, /* access */ + 0, /* shared mode */ + NULL, /* SecurityAttributes */ + CREATE_ALWAYS, /* CreationDisposition */ + FILE_FLAG_BACKUP_SEMANTICS, /* Flags and attributes */ + NULL); /* TemplateFile */ + + if (bfd->fh == INVALID_HANDLE_VALUE) { + bfd->lerror = GetLastError(); + bfd->mode = BF_CLOSED; + } else { + bfd->mode = BF_WRITE; + } + } else { + bfd->fh = CreateFile(win32_fname, + READ_CONTROL|ACCESS_SYSTEM_SECURITY, /* access */ + 0, /* 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; + } else { + bfd->mode = BF_READ; + } + } + bfd->errmsg = NULL; + bfd->lpContext = NULL; + return bfd->mode == BF_CLOSED ? -1 : 1; +} + +/* + * Returns 0 on success + * -1 on error + */ +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) { + BYTE buf[10]; + if (!bfd->lpContext && !BackupRead(bfd->fh, + buf, /* buffer */ + (DWORD)0, /* bytes to read */ + &bfd->rw_bytes, /* bytes read */ + 1, /* Abort */ + 1, /* ProcessSecurity */ + &bfd->lpContext)) { /* Read context */ + stat = -1; + } + } else { + BYTE buf[10]; + if (!bfd->lpContext && !BackupWrite(bfd->fh, + buf, /* buffer */ + (DWORD)0, /* bytes to read */ + &bfd->rw_bytes, /* bytes written */ + 1, /* Abort */ + 1, /* ProcessSecurity */ + &bfd->lpContext)) { /* Write context */ + stat = -1; + } + } + if (!CloseHandle(bfd->fh)) { + stat = -1; + } + bfd->mode = BF_CLOSED; + bfd->lpContext = NULL; + return stat; +} + +/* + * Generate error message + */ +char *berror(BFILE *bfd) +{ + LPTSTR msg; + + if (!bfd->use_win_api) { + return strerror(errno); + } + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER| + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + bfd->lerror, + 0, + (LPTSTR)&msg, + 0, + NULL); + strip_trailing_junk(msg); + if (!bfd->errmsg) { + bfd->errmsg = get_pool_memory(PM_FNAME); + } + pm_strcpy(&bfd->errmsg, msg); + LocalFree(msg); + return bfd->errmsg; +} + +/* Returns: bytes read on success + * 0 on EOF + * -1 on error + */ +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; + BackupRead(bfd->fh, + (BYTE *)buf, + count, + &bfd->rw_bytes, + 0, /* no Abort */ + 1, /* Process Security */ + &bfd->lpContext); /* Context */ + if (bfd->rw_bytes > 0) { + return (ssize_t)bfd->rw_bytes; + } + bfd->lerror = GetLastError(); + return bfd->lerror == 0 ? 0 : -1; +} + +ssize_t bwrite(BFILE *bfd, void *buf, size_t count) +{ + DWORD bytes_written = 0; + if (!bfd->use_win_api) { + return write(bfd->fid, buf, count); + } + BackupWrite(bfd->fh, + (BYTE *)buf, + count, + &bytes_written, + 0, /* No abort */ + 1, /* Process Security */ + &bfd->lpContext); /* Context */ + + if ((size_t)bfd->rw_bytes == count) { + return (ssize_t)bfd->rw_bytes; + } + bfd->lerror = GetLastError(); + return bfd->lerror == 0 ? (ssize_t)bfd->rw_bytes : -1; +} + +int is_bopen(BFILE *bfd) +{ + return bfd->mode != BF_CLOSED; +} + +off_t blseek(BFILE *bfd, off_t offset, int whence) +{ + if (!bfd->use_win_api) { + return lseek(bfd->fid, offset, whence); + } + return -1; +} + +#else /* Unix systems */ + +/* =============================================================== + * + * U N I X + * + * =============================================================== + */ +void binit(BFILE *bfd, int use_win_api) { bfd->fid = -1; } -int bopen(BFILE *bfd, const char *pathname, int flags, mode_t mode) +int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode) { - return bfd->fid = open(pathname, flags, mode); + return bfd->fid = open(fname, flags, mode); } int bclose(BFILE *bfd) @@ -68,3 +287,10 @@ off_t blseek(BFILE *bfd, off_t offset, int whence) { return lseek(bfd->fid, offset, whence); } + +char *berror(BFILE *bfd) +{ + return strerror(errno); +} + +#endif diff --git a/bacula/src/findlib/create_file.c b/bacula/src/findlib/create_file.c index bca0d9f29b..319cabac2d 100644 --- a/bacula/src/findlib/create_file.c +++ b/bacula/src/findlib/create_file.c @@ -63,7 +63,7 @@ static int path_already_seen(char *path, int pnl); */ int create_file(void *jcr, char *fname, char *ofile, char *lname, int type, int stream, struct stat *statp, - char *attribsEx, BFILE *ofd, int replace) + char *attribsEx, BFILE *ofd, int replace, int win_io) { int new_mode, parent_mode, mode; uid_t uid; @@ -71,7 +71,7 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, int stat = 0; int pnl; - binit(ofd); + binit(ofd, win_io); new_mode = statp->st_mode; Dmsg2(300, "newmode=%x file=%s\n", new_mode, ofile); parent_mode = S_IWUSR | S_IXUSR | new_mode; @@ -158,7 +158,7 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, } Dmsg1(50, "Create file: %s\n", ofile); if ((bopen(ofd, ofile, mode, S_IRUSR | S_IWUSR)) < 0) { - Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), ofile, strerror(errno)); + Jmsg2(jcr, M_ERROR, 0, _("Could not create %s: ERR=%s\n"), ofile, berror(ofd)); return CF_ERROR; } return CF_EXTRACT; @@ -169,13 +169,13 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, if (S_ISFIFO(statp->st_mode)) { Dmsg1(200, "Restore fifo: %s\n", ofile); if (mkfifo(ofile, statp->st_mode) != 0 && errno != EEXIST) { - Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), ofile, strerror(errno)); + Jmsg2(jcr, M_ERROR, 0, _("Cannot make fifo %s: ERR=%s\n"), ofile, berror(ofd)); return CF_ERROR; } } else { Dmsg1(200, "Restore node: %s\n", ofile); if (mknod(ofile, statp->st_mode, statp->st_rdev) != 0 && errno != EEXIST) { - Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), ofile, strerror(errno)); + Jmsg2(jcr, M_ERROR, 0, _("Cannot make node %s: ERR=%s\n"), ofile, berror(ofd)); return CF_ERROR; } } @@ -190,7 +190,7 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, tid = NULL; } if ((bopen(ofd, ofile, mode, 0)) < 0) { - Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), ofile, strerror(errno)); + Jmsg2(jcr, M_ERROR, 0, _("Could not open %s: ERR=%s\n"), ofile, berror(ofd)); stop_thread_timer(tid); return CF_ERROR; } @@ -203,8 +203,8 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, case FT_LNK: Dmsg2(130, "FT_LNK should restore: %s -> %s\n", ofile, lname); if (symlink(lname, ofile) != 0 && errno != EEXIST) { - Jmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), - ofile, lname, strerror(errno)); + Jmsg3(jcr, M_ERROR, 0, _("Could not symlink %s -> %s: ERR=%s\n"), + ofile, lname, berror(ofd)); return CF_ERROR; } return CF_CREATED; @@ -212,8 +212,8 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(130, "Hard link %s => %s\n", ofile, lname); if (link(lname, ofile) != 0) { - Jmsg3(jcr, M_ERROR, 0, _("Could not hard link %s ==> %s: ERR=%s\n"), - ofile, lname, strerror(errno)); + Jmsg3(jcr, M_ERROR, 0, _("Could not hard link %s ==> %s: ERR=%s\n"), + ofile, lname, berror(ofd)); return CF_ERROR; } return CF_CREATED; @@ -223,7 +223,8 @@ int create_file(void *jcr, char *fname, char *ofile, char *lname, case FT_DIR: Dmsg2(300, "Make dir mode=%o dir=%s\n", new_mode, ofile); if (make_path(jcr, ofile, new_mode, parent_mode, uid, gid, 0, NULL) != 0) { - Jmsg1(jcr, M_ERROR, 0, _("Could not make directory: %s\n"), ofile); + Jmsg2(jcr, M_ERROR, 0, _("Could not make directory %s: ERR=%s.\n"), + ofile, berror(ofd)); return CF_ERROR; } return CF_CREATED; diff --git a/bacula/src/findlib/find.h b/bacula/src/findlib/find.h index 4d1e4b2a1d..4bd86c0f53 100755 --- a/bacula/src/findlib/find.h +++ b/bacula/src/findlib/find.h @@ -61,43 +61,43 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); /* * Status codes returned by create_file() */ -#define CF_SKIP 1 /* skip file (not newer or something) */ -#define CF_ERROR 2 /* error creating file */ -#define CF_EXTRACT 3 /* file created, data to extract */ -#define CF_CREATED 4 /* file created, no data to extract */ +#define CF_SKIP 1 /* skip file (not newer or something) */ +#define CF_ERROR 2 /* error creating file */ +#define CF_EXTRACT 3 /* file created, data to extract */ +#define CF_CREATED 4 /* file created, no data to extract */ /* * NOTE!!! These go on the tape, so don't change them. If * need be, add to them. */ -#define FT_LNKSAVED 1 /* hard link to file already saved */ -#define FT_REGE 2 /* Regular file but empty */ -#define FT_REG 3 /* Regular file */ -#define FT_LNK 4 /* Soft Link */ -#define FT_DIR 5 /* Directory */ -#define FT_SPEC 6 /* Special file -- chr, blk, fifo, sock */ -#define FT_NOACCESS 7 /* Not able to access */ -#define FT_NOFOLLOW 8 /* Could not follow link */ -#define FT_NOSTAT 9 /* Could not stat file */ -#define FT_NOCHG 10 /* Incremental option, file not changed */ -#define FT_DIRNOCHG 11 /* Incremental option, directory not changed */ -#define FT_ISARCH 12 /* Trying to save archive file */ -#define FT_NORECURSE 13 /* No recursion into directory */ -#define FT_NOFSCHG 14 /* Different file system, prohibited */ -#define FT_NOOPEN 15 /* Could not open directory */ -#define FT_RAW 16 /* Raw block device */ -#define FT_FIFO 17 /* Raw fifo device */ +#define FT_LNKSAVED 1 /* hard link to file already saved */ +#define FT_REGE 2 /* Regular file but empty */ +#define FT_REG 3 /* Regular file */ +#define FT_LNK 4 /* Soft Link */ +#define FT_DIR 5 /* Directory */ +#define FT_SPEC 6 /* Special file -- chr, blk, fifo, sock */ +#define FT_NOACCESS 7 /* Not able to access */ +#define FT_NOFOLLOW 8 /* Could not follow link */ +#define FT_NOSTAT 9 /* Could not stat file */ +#define FT_NOCHG 10 /* Incremental option, file not changed */ +#define FT_DIRNOCHG 11 /* Incremental option, directory not changed */ +#define FT_ISARCH 12 /* Trying to save archive file */ +#define FT_NORECURSE 13 /* No recursion into directory */ +#define FT_NOFSCHG 14 /* Different file system, prohibited */ +#define FT_NOOPEN 15 /* Could not open directory */ +#define FT_RAW 16 /* Raw block device */ +#define FT_FIFO 17 /* Raw fifo device */ /* Options saved in "flag" of ff packet */ -#define FO_MD5 0x001 /* Do MD5 checksum */ -#define FO_GZIP 0x002 /* Do Zlib compression */ -#define FO_NO_RECURSION 0x004 /* no recursion in directories */ -#define FO_MULTIFS 0x008 /* multiple file systems */ -#define FO_SPARSE 0x010 /* do sparse file checking */ -#define FO_IF_NEWER 0x020 /* replace if newer */ -#define FO_NOREPLACE 0x040 /* never replace */ -#define FO_READFIFO 0x080 /* read data from fifo */ -#define FO_SHA1 0x100 /* Do SHA1 checksum */ +#define FO_MD5 0x001 /* Do MD5 checksum */ +#define FO_GZIP 0x002 /* Do Zlib compression */ +#define FO_NO_RECURSION 0x004 /* no recursion in directories */ +#define FO_MULTIFS 0x008 /* multiple file systems */ +#define FO_SPARSE 0x010 /* do sparse file checking */ +#define FO_IF_NEWER 0x020 /* replace if newer */ +#define FO_NOREPLACE 0x040 /* never replace */ +#define FO_READFIFO 0x080 /* read data from fifo */ +#define FO_SHA1 0x100 /* Do SHA1 checksum */ /* * Options saved in "options" of include list @@ -109,21 +109,21 @@ int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result); #define OPT_compute_MD5 0x01 /* compute MD5 of file's data */ #define OPT_GZIP_compression 0x02 /* use GZIP compression */ #define OPT_no_recursion 0x04 /* no recursion in directories */ -#define OPT_multifs 0x08 /* multiple file systems */ -#define OPT_sparse 0x10 /* do sparse file checking */ +#define OPT_multifs 0x08 /* multiple file systems */ +#define OPT_sparse 0x10 /* do sparse file checking */ #define OPT_replace_if_newer 0x20 /* replace file if newer */ #define OPT_never_replace 0x40 /* never replace */ -#define OPT_read_fifo 0x80 /* read data from fifo (named pipe) */ +#define OPT_read_fifo 0x80 /* read data from fifo (named pipe) */ #define OPT_compute_SHA1 0x100 /* compute SHA1 of file's data */ struct s_included_file { struct s_included_file *next; - int options; /* backup options */ - int level; /* compression level */ - int len; /* length of fname */ - int pattern; /* set if pattern */ - char VerifyOpts[20]; /* Options for verify */ + int options; /* backup options */ + int level; /* compression level */ + int len; /* length of fname */ + int pattern; /* set if pattern */ + char VerifyOpts[20]; /* Options for verify */ char fname[1]; }; @@ -133,40 +133,65 @@ struct s_excluded_file { char fname[1]; }; +#ifdef HAVE_CYGWIN + +#include + +#define BF_CLOSED 0 +#define BF_READ 1 /* BackupRead */ +#define BF_WRITE 2 /* BackupWrite */ + +/* Basic low level I/O file packet */ +typedef struct s_bfile { + int use_win_api; /* set if using WinAPI */ + int mode; /* set if file is open */ + HANDLE fh; /* Win32 file handle */ + int fid; /* fd if doing Unix style */ + LPVOID lpContext; /* BackupRead/Write context */ + POOLMEM *errmsg; /* error message buffer */ + DWORD rw_bytes; /* Bytes read or written */ + DWORD lerror; /* Last error code */ +} BFILE; + +#else + +/* Basic low level I/O file packet */ typedef struct s_bfile { - int fid; /* file id on Unix */ + int fid; /* file id on Unix */ } BFILE; +#endif + /* * Definition of the find_files packet passed as the * first argument to the find_files callback subroutine. */ typedef struct s_ff { - char *fname; /* filename */ - char *link; /* link if file linked */ - POOLMEM *sys_fname; /* system filename */ - struct stat statp; /* stat packet */ - uint32_t FileIndex; /* FileIndex of this file */ - uint32_t LinkFI; /* FileIndex of main hard linked file */ - struct f_link *linked; /* Set if we are hard linked */ - int type; /* FT_ type from above */ - int flags; /* control flags */ - int ff_errno; /* errno */ - int incremental; /* do incremental save */ - BFILE bfd; /* Bacula file descriptor */ - time_t save_time; /* start of incremental time */ - int mtime_only; /* incremental on mtime_only */ - int dereference; /* follow links */ - int GZIP_level; /* compression level */ - int atime_preserve; /* preserve access times */ - int null_output_device; /* using null output device */ + char *fname; /* filename */ + char *link; /* link if file linked */ + POOLMEM *sys_fname; /* system filename */ + struct stat statp; /* stat packet */ + uint32_t FileIndex; /* FileIndex of this file */ + uint32_t LinkFI; /* FileIndex of main hard linked file */ + struct f_link *linked; /* Set if we are hard linked */ + int type; /* FT_ type from above */ + int flags; /* control flags */ + int ff_errno; /* errno */ + int incremental; /* do incremental save */ + BFILE bfd; /* Bacula file descriptor */ + time_t save_time; /* start of incremental time */ + int mtime_only; /* incremental on mtime_only */ + int dereference; /* follow links */ + int GZIP_level; /* compression level */ + int atime_preserve; /* preserve access times */ + int null_output_device; /* using null output device */ char VerifyOpts[20]; struct s_included_file *included_files_list; struct s_excluded_file *excluded_files_list; struct s_excluded_file *excluded_paths_list; - struct f_link *linklist; /* hard linked files */ + struct f_link *linklist; /* hard linked files */ } FF_PKT; diff --git a/bacula/src/findlib/protos.h b/bacula/src/findlib/protos.h index da28b45323..49f7b889d0 100644 --- a/bacula/src/findlib/protos.h +++ b/bacula/src/findlib/protos.h @@ -30,11 +30,12 @@ int encode_attribsEx (void *jcr, char *attribsEx, FF_PKT *ff_pkt); int set_attributes(void *jcr, char *fname, char *ofile, char *lname, int type, int stream, struct stat *statp, char *attribsEx, BFILE *ofd); +void SetServicePrivileges(void *jcr); /* from create_file.c */ int create_file(void *jcr, char *fname, char *ofile, char *lname, int type, int stream, struct stat *statp, - char *attribsEx, BFILE *ofd, int replace); + char *attribsEx, BFILE *ofd, int replace, int win_io); /* From find.c */ FF_PKT *init_find_files(); @@ -65,10 +66,11 @@ int make_path(void *jcr, const char *argpath, int mode, /* from file_io.c */ ssize_t bread(BFILE *bfd, void *buf, size_t count); -int bopen(BFILE *bfd, const char *pathname, int flags, mode_t mode); +int bopen(BFILE *bfd, const char *fname, int flags, mode_t mode); int bclose(BFILE *bfd); ssize_t bread(BFILE *bfd, void *buf, size_t count); ssize_t bwrite(BFILE *bfd, void *buf, size_t count); off_t blseek(BFILE *bfd, off_t offset, int whence); int is_bopen(BFILE *bfd); -void binit(BFILE *bfd); +void binit(BFILE *bfd, int use_win_api); +char *berror(BFILE *bfd); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 2a672c461e..8bb95fdcf1 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -174,6 +174,7 @@ struct s_jcr { uint32_t EndFile; uint32_t StartBlock; uint32_t EndBlock; + int use_win_backup_api; /* set to use native Win API */ #endif /* FILE_DAEMON */ #ifdef STORAGE_DAEMON diff --git a/bacula/src/version.h b/bacula/src/version.h index 2500bbaf02..4d19a9ccce 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.30" #define VSTRING "1" -#define BDATE "14 April 2003" -#define LSMDATE "14Apr03" +#define BDATE "16 April 2003" +#define LSMDATE "16Apr03" /* Debug flags */ #define DEBUG 1 -- 2.39.2