// FIX THIS: Maybe should be in bfile.c. enum ofr_e open_for_restore(struct asfd *asfd, BFILE *bfd, const char *path, struct sbuf *sb, int vss_restore, struct cntr *cntr, enum protocol protocol) { static int flags; if(bfd->mode!=BF_CLOSED) { #ifdef HAVE_WIN32 if(bfd->path && !strcmp(bfd->path, path)) { // Already open after restoring the VSS data. // Time now for the actual file data. return OFR_OK; } else { #endif if(bfd->close(bfd, asfd)) { logp("error closing %s in %s()\n", path, __func__); return OFR_ERROR; } #ifdef HAVE_WIN32 } #endif } bfile_init(bfd, sb->winattr, cntr); #ifdef HAVE_WIN32 bfd->set_win32_api(bfd, vss_restore); #endif if(S_ISDIR(sb->statp.st_mode)) { // Windows directories are treated as having file data. flags=O_WRONLY|O_BINARY; mkdir(path, 0777); } else flags=O_WRONLY|O_BINARY|O_CREAT|O_TRUNC; if(bfd->open(bfd, asfd, path, flags, S_IRUSR | S_IWUSR)) { berrno be; berrno_init(&be); char msg[256]=""; snprintf(msg, sizeof(msg), "Could not open for writing %s: %s", path, berrno_bstrerror(&be, errno)); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) return OFR_ERROR; return OFR_CONTINUE; } // Add attributes to bfd so that they can be set when it is closed. bfd->winattr=sb->winattr; memcpy(&bfd->statp, &sb->statp, sizeof(struct stat)); return OFR_OK; }
static int set_file_times(struct asfd *asfd, const char *path, struct utimbuf *ut, struct stat *statp, struct conf *conf) { int e; // The mingw64 utime() appears not to work on read-only files. // Use the utime() from bacula instead. #ifdef HAVE_WIN32 //e=utime(path, ut); e=win32_utime(path, ut); #else e=utime(path, ut); #endif if(e<0) { berrno be; berrno_init(&be); logw(asfd, conf, "Unable to set file times %s: ERR=%s", path, berrno_bstrerror(&be, errno)); return -1; } return 0; }
/* These receive_a_file() and send_file() functions are for use by extra_comms and the CA stuff, rather than backups/restores. */ int receive_a_file(struct asfd *asfd, const char *path, struct conf **confs) { int ret=-1; BFILE *bfd=NULL; unsigned long long rcvdbytes=0; unsigned long long sentbytes=0; if(!(bfd=bfile_alloc())) goto end; bfile_init(bfd, 0, confs); #ifdef HAVE_WIN32 bfd->set_win32_api(bfd, 0); #endif if(bfd->open(bfd, asfd, path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR)) { berrno be; berrno_init(&be); logp("Could not open for writing %s: %s\n", path, berrno_bstrerror(&be, errno)); goto end; } ret=transfer_gzfile_in(asfd, path, bfd, &rcvdbytes, &sentbytes, confs); if(bfd->close(bfd, asfd)) { logp("error closing %s in receive_a_file\n", path); goto end; } logp("Received: %s\n", path); ret=0; end: bfd->close(bfd, asfd); bfile_free(&bfd); return ret; }
int attribs_set(struct asfd *asfd, const char *path, struct stat *statp, uint64_t winattr, struct conf *conf) { struct utimbuf ut; ut.actime=statp->st_atime; ut.modtime=statp->st_mtime; #ifdef HAVE_WIN32 win32_chmod(path, statp->st_mode, winattr); set_file_times(asfd, path, &ut, statp, conf); return 0; #endif /* ***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. */ /* Watch out, a metadata restore will have cmd set to CMD_METADATA or CMD_ENC_META, but that is OK at the moment because we are not doing meta stuff on links. */ if(S_ISLNK(statp->st_mode)) { // Change owner of link, not of real file. if(lchown(path, statp->st_uid, statp->st_gid)<0) { berrno be; berrno_init(&be); logw(asfd, conf, "Unable to set file owner %s: ERR=%s", path, berrno_bstrerror(&be, errno)); return -1; } } else { if(chown(path, statp->st_uid, statp->st_gid)<0) { berrno be; berrno_init(&be); logw(asfd, conf, "Unable to set file owner %s: ERR=%s", path, berrno_bstrerror(&be, errno)); return -1; } if(chmod(path, statp->st_mode) < 0) { berrno be; berrno_init(&be); logw(asfd, conf, "Unable to set file modes %s: ERR=%s", path, berrno_bstrerror(&be, errno)); return -1; } if(set_file_times(asfd, path, &ut, statp, conf)) return -1; #ifdef HAVE_CHFLAGS /* * FreeBSD user flags * * Note, this should really be done before the utime() above, * but if the immutable bit is set, it will make the utimes() * fail. */ if(chflags(path, statp->st_flags)<0) { berrno be; berrno_init(&be); logw(conf, "Unable to set file flags %s: ERR=%s", path, berrno_bstrerror(&be, errno)); return -1; } #endif } return 0; }
// FIX THIS: Maybe should be in bfile.c. enum ofr_e open_for_restore(struct asfd *asfd, BFILE *bfd, const char *path, struct sbuf *sb, int vss_restore, struct cntr *cntr, enum protocol protocol) { static int flags; if(bfd->mode!=BF_CLOSED) { #ifdef HAVE_WIN32 if(bfd->path && !strcmp(bfd->path, path)) { // Already open after restoring the VSS data. // Time now for the actual file data. return OFR_OK; } else { #endif if(bfd->close(bfd, asfd)) { logp("error closing %s in %s()\n", path, __func__); return OFR_ERROR; } #ifdef HAVE_WIN32 } #endif } #ifdef HAVE_WIN32 // Some massive hacks to work around times that winattr was not // getting set correctly inside server side backups. // The EFS one will stop burp segfaulting when restoring affected // EFS files. if(sb->path.cmd==CMD_EFS_FILE) sb->winattr |= FILE_ATTRIBUTE_ENCRYPTED; if(S_ISDIR(sb->statp.st_mode)) sb->winattr |= FILE_ATTRIBUTE_DIRECTORY; #endif bfile_init(bfd, sb->winattr, cntr); #ifdef HAVE_WIN32 bfd->set_win32_api(bfd, vss_restore); #endif if(S_ISDIR(sb->statp.st_mode)) { // Windows directories are treated as having file data. flags=O_WRONLY|O_BINARY; mkdir(path, 0777); } else flags=O_WRONLY|O_BINARY|O_CREAT|O_TRUNC; if(bfd->open(bfd, asfd, path, flags, S_IRUSR | S_IWUSR)) { berrno be; berrno_init(&be); char msg[256]=""; snprintf(msg, sizeof(msg), "Could not open for writing %s: %s", path, berrno_bstrerror(&be, errno)); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) return OFR_ERROR; return OFR_CONTINUE; } // Add attributes to bfd so that they can be set when it is closed. bfd->winattr=sb->winattr; memcpy(&bfd->statp, &sb->statp, sizeof(struct stat)); return OFR_OK; }
int win32_start_vss(struct conf **confs) { int errors=0; if(SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlHandler, TRUE)) logp("Control handler registered.\n"); else logp("Could not register control handler.\n"); if(g_pVSSClient->InitializeForBackup()) { const char *vss_drives=get_string(confs[OPT_VSS_DRIVES]); char szWinDriveLetters[27]; // Tell vss which drives to snapshot. if(vss_drives) { unsigned int i=0; for(i=0; i<strlen(vss_drives) && i<26; i++) szWinDriveLetters[i]=toupper(vss_drives[i]); szWinDriveLetters[i]='\0'; } else { // Not given anything specific. Figure out what to do // from the given starting directories. int j=0; struct strlist *s; for(s=get_strlist(confs[OPT_STARTDIR]), j=0; s && j<26; s=s->next) { const char *path=NULL; if(!s->flag) continue; path=s->path; if(strlen(path)>2 && isalpha(path[0]) && path[1]==':') { int x=0; // Try not to add the same letter twice. for(x=0; x<j; x++) if(toupper(path[0])==szWinDriveLetters[x]) break; if(x<j) continue; szWinDriveLetters[j++]=toupper(path[0]); } } szWinDriveLetters[j]='\0'; } printf("Generate VSS snapshots.\n"); printf("Driver=\"%s\", Drive(s)=\"%s\"\n", g_pVSSClient->GetDriverName(), szWinDriveLetters); if(!g_pVSSClient->CreateSnapshots(szWinDriveLetters)) { logp("Generate VSS snapshots failed.\n"); errors++; } else { int i; for(i=0; i<(int)strlen(szWinDriveLetters); i++) { logp("VSS drive letters: %d\n", i); if(islower(szWinDriveLetters[i])) { logp(_("Generate VSS snapshot of drive \"%c:\\\" failed.\n"), szWinDriveLetters[i]); errors++; } } for(i=0; i<(int)g_pVSSClient->GetWriterCount(); i++) { logp("VSS writer count: %d\n", i); if(g_pVSSClient->GetWriterState(i)<1) { logp("VSS Writer (PrepareForBackup): %s\n", g_pVSSClient->GetWriterInfo(i)); errors++; } } } } else { berrno be; berrno_init(&be); logp("VSS was not initialized properly.\n"); logp("VSS support is disabled. ERR=%s\n", berrno_bstrerror(&be, b_errno_win32)); errors++; } return errors; }
int attribs_set(struct asfd *asfd, const char *path, struct stat *statp, uint64_t winattr, struct cntr *cntr) { struct utimbuf ut; ut.actime=statp->st_atime; ut.modtime=statp->st_mtime; #ifdef HAVE_WIN32 win32_chmod(path, statp->st_mode, winattr); set_file_times(asfd, path, &ut, statp, cntr); return 0; #endif if(lchown(path, statp->st_uid, statp->st_gid)<0) { berrno be; berrno_init(&be); logw(asfd, cntr, "Unable to set file owner %s: ERR=%s\n", path, berrno_bstrerror(&be, errno)); return -1; } /* Watch out, a metadata restore will have cmd set to CMD_METADATA or CMD_ENC_META, but that is OK at the moment because we are not doing meta stuff on links. */ if(S_ISLNK(statp->st_mode)) { #ifdef HAVE_LUTIMES if(do_lutimes(path, statp)) { berrno be; berrno_init(&be); logw(asfd, cntr, "Unable to set lutimes %s: ERR=%s\n", path, berrno_bstrerror(&be, errno)); return -1; } #endif } else { if(chmod(path, statp->st_mode) < 0) { berrno be; berrno_init(&be); logw(asfd, cntr, "Unable to set file modes %s: ERR=%s\n", path, berrno_bstrerror(&be, errno)); return -1; } if(set_file_times(asfd, path, &ut, statp, cntr)) return -1; #ifdef HAVE_CHFLAGS /* * FreeBSD user flags * * Note, this should really be done before the utime() above, * but if the immutable bit is set, it will make the utimes() * fail. */ if(chflags(path, statp->st_flags)<0) { berrno be; berrno_init(&be); logw(asfd, cntr, "Unable to set file flags %s: ERR=%s\n", path, berrno_bstrerror(&be, errno)); return -1; } #endif } return 0; }