END_TEST static void setup_proto2_some_things(struct asfd *asfd, struct slist *slist) { struct sbuf *s; struct stat statp_dir; struct stat statp_file; int r=0; int w=0; fail_unless(!lstat(BASE, &statp_dir)); fail_unless(!lstat(BASE "/burp.conf", &statp_file)); asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore :"); asfd_mock_read(asfd, &r, 0, CMD_GEN, "ok"); asfd_mock_read(asfd, &r, 0, CMD_GEN, "restore_stream"); asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore_stream_ok"); for(s=slist->head; s; s=s->next) { s->winattr=0; s->compression=0; if(s->path.cmd==CMD_DIRECTORY) { memcpy(&s->statp, &statp_dir, sizeof(statp_dir)); attribs_encode(s); } if(sbuf_is_link(s)) { char path[256]; if(s->path.cmd==CMD_HARD_LINK) snprintf(path, sizeof(path), "%s", s->link.buf); else { char *cp; snprintf(path, sizeof(path), "%s", s->path.buf); fail_unless((cp=strrchr(path, '/'))!=NULL); cp++; snprintf(cp, strlen(s->link.buf)+1, "%s", s->link.buf); } build_file(path, NULL); memcpy(&s->statp, &statp_file, sizeof(statp_file)); attribs_encode(s); asfd_mock_read_iobuf(asfd, &r, 0, &s->attr); asfd_mock_read_iobuf(asfd, &r, 0, &s->path); asfd_mock_read_iobuf(asfd, &r, 0, &s->link); } else if(sbuf_is_filedata(s)) { memcpy(&s->statp, &statp_file, sizeof(statp_file)); attribs_encode(s); asfd_mock_read_iobuf(asfd, &r, 0, &s->attr); asfd_mock_read_iobuf(asfd, &r, 0, &s->path); asfd_mock_read(asfd, &r, 0, CMD_DATA, "data"); } } asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend"); asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend ok"); }
static int do_to_server(struct asfd *asfd, struct conf *conf, FF_PKT *ff, struct sbuf *sb, char cmd, int compression) { sb->compression=compression; sb->statp=ff->statp; attribs_encode(sb); #ifdef HAVE_WIN32 if(conf->split_vss && !conf->strip_vss && maybe_send_extrameta(asfd, ff->fname, cmd, sb, conf, metasymbol)) return -1; #endif if(usual_stuff(asfd, conf, ff->fname, ff->link, sb, cmd)) return -1; if(ff->type==FT_REG) cntr_add_val(conf->cntr, CMD_BYTES_ESTIMATED, (unsigned long long)ff->statp.st_size, 0); #ifdef HAVE_WIN32 if(conf->split_vss && !conf->strip_vss // FIX THIS: May have to check that it is not a directory here. && !S_ISDIR(sb->statp.st_mode) // does this work? && maybe_send_extrameta(asfd, ff->fname, cmd, sb, conf, vss_trail_symbol)) return -1; return 0; #else return maybe_send_extrameta(asfd, ff->fname, cmd, sb, conf, metasymbol); #endif }
// Return -1 for error, 0 for could not open file, 1 for success. int rabin_open_file(struct sbuf *sb, struct asfd *asfd, struct cntr *cntr, struct conf **confs) { struct BFILE *bfd=&sb->protocol2->bfd; #ifdef HAVE_WIN32 if(win32_lstat(sb->path.buf, &sb->statp, &sb->winattr)) #else if(lstat(sb->path.buf, &sb->statp)) #endif { // This file is no longer available. logw(asfd, cntr, "%s has vanished\n", sb->path.buf); return 0; } sb->compression=get_int(confs[OPT_COMPRESSION]); // Encryption not yet implemented in protocol2. //sb->protocol2->encryption=conf->protocol2->encryption_password?1:0; if(attribs_encode(sb)) return -1; if(sbuf_is_metadata(sb)) return rabin_open_file_extrameta(sb, asfd, cntr); if(bfd->open_for_send(bfd, asfd, sb->path.buf, sb->winattr, get_int(confs[OPT_ATIME]), cntr, PROTO_2)) { logw(asfd, get_cntr(confs), "Could not open %s\n", sb->path.buf); return 0; } return 1; }
static void maybe_fake_directory(struct sbuf *mb) { if(S_ISDIR(mb->statp.st_mode)) return; // We are faking a directory entry. // Make sure the directory bit is set. mb->statp.st_mode &= ~(S_IFMT); mb->statp.st_mode |= S_IFDIR; attribs_encode(mb); }
static int do_to_server(struct asfd *asfd, struct conf **confs, struct FF_PKT *ff, struct sbuf *sb, enum cmd cmd, int compression) { #ifdef HAVE_WIN32 int split_vss=0; int strip_vss=0; if(get_protocol(confs)==PROTO_1) { split_vss=get_int(confs[OPT_SPLIT_VSS]); strip_vss=get_int(confs[OPT_STRIP_VSS]); } #endif struct cntr *cntr=get_cntr(confs); sb->compression=compression; sb->encryption=encryption; sb->statp=ff->statp; attribs_encode(sb); #ifdef HAVE_WIN32 if(split_vss && !strip_vss && cmd!=CMD_EFS_FILE && maybe_send_extrameta(asfd, ff->fname, cmd, sb, cntr, metasymbol)) return -1; #endif if(usual_stuff(asfd, cntr, ff->fname, ff->link, sb, cmd)) return -1; if(ff->type==FT_REG) cntr_add_val(cntr, CMD_BYTES_ESTIMATED, (uint64_t)ff->statp.st_size); #ifdef HAVE_WIN32 if(split_vss && !strip_vss && cmd!=CMD_EFS_FILE // FIX THIS: May have to check that it is not a directory here. && !S_ISDIR(sb->statp.st_mode) // does this work? && maybe_send_extrameta(asfd, ff->fname, cmd, sb, cntr, vss_trail_symbol)) return -1; return 0; #else return maybe_send_extrameta(asfd, ff->fname, cmd, sb, cntr, metasymbol); #endif }
static int process_unchanged_file(struct sbuf *p1b, struct sbuf *cb, struct fzp *ucfp, struct conf **cconfs) { // Need to re-encode the p1b attribs to include compression and // other bits and pieces that are recorded on cb. iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth); iobuf_move(&p1b->protocol1->endfile, &cb->protocol1->endfile); p1b->compression=cb->compression; if(attribs_encode(p1b)) return -1; if(sbufl_to_manifest(p1b, ucfp)) return -1; cntr_add_same(get_cntr(cconfs[OPT_CNTR]), p1b->path.cmd); if(p1b->protocol1->endfile.buf) cntr_add_bytes( get_cntr(cconfs[OPT_CNTR]), strtoull(p1b->protocol1->endfile.buf, NULL, 10)); sbuf_free_content(cb); return 1; }
static void setup_reads_from_slist(struct asfd *asfd, int *ar, struct slist *slist, int number_of_blks, uint64_t interrupt) { int file_no=1; struct sbuf *s; struct blk blk; struct iobuf iobuf; if(!slist) return; for(s=slist->head; s; s=s->next) { if(sbuf_is_filedata(s) && !sbuf_is_encrypted(s)) // Not working for proto2 yet. { int b; s->protocol2->index=file_no++; if(interrupt==s->protocol2->index) { char buf[32]=""; asfd_mock_read(asfd, ar, 0, CMD_WARNING, "path vanished\n"); base64_from_uint64(interrupt, buf); asfd_mock_read(asfd, ar, 0, CMD_INTERRUPT, buf); continue; } iobuf_free_content(&s->attr); attribs_encode(s); asfd_mock_read(asfd, ar, 0, CMD_ATTRIBS_SIGS, s->attr.buf); blk.fingerprint=file_no; memset(&blk.md5sum, file_no, MD5_DIGEST_LENGTH); blk_to_iobuf_sig(&blk, &iobuf); for(b=0; b<number_of_blks; b++) asfd_mock_read_iobuf(asfd, ar, 0, &iobuf); } } }
static void setup_proto1_some_things(struct asfd *asfd, struct slist *slist) { struct sbuf *s; struct stat statp_dir; struct stat statp_file; int r=0; int w=0; fail_unless(!lstat(BASE, &statp_dir)); fail_unless(!lstat(BASE "/burp.conf", &statp_file)); asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore :"); asfd_mock_read(asfd, &r, 0, CMD_GEN, "ok"); for(s=slist->head; s; s=s->next) { s->winattr=0; s->compression=0; if(s->path.cmd==CMD_DIRECTORY) { memcpy(&s->statp, &statp_dir, sizeof(statp_dir)); attribs_encode(s); } if(sbuf_is_link(s)) { char path[256]; if(s->path.cmd==CMD_HARD_LINK) snprintf(path, sizeof(path), "%s", s->link.buf); else { char *cp; snprintf(path, sizeof(path), "%s", s->path.buf); fail_unless((cp=strrchr(path, '/'))!=NULL); cp++; snprintf(cp, strlen(s->link.buf)+1, "%s", s->link.buf); } build_file(path, NULL); memcpy(&s->statp, &statp_file, sizeof(statp_file)); attribs_encode(s); asfd_mock_read_iobuf(asfd, &r, 0, &s->attr); asfd_mock_read_iobuf(asfd, &r, 0, &s->path); asfd_mock_read_iobuf(asfd, &r, 0, &s->link); } else if(sbuf_is_filedata(s)) { struct iobuf rbuf; // The string "data" gzipped. unsigned char gzipped_data[27] = { 0x1f, 0x8b, 0x08, 0x08, 0xb4, 0x1e, 0x7f, 0x56, 0x00, 0x03, 0x79, 0x00, 0x4b, 0x49, 0x2c, 0x49, 0xe4, 0x02, 0x00, 0x82, 0xc5, 0xc1, 0xe6, 0x05, 0x00, 0x00, 0x00 }; memcpy(&s->statp, &statp_file, sizeof(statp_file)); attribs_encode(s); asfd_mock_read(asfd, &r, 0, CMD_DATAPTH, s->path.buf); asfd_mock_read_iobuf(asfd, &r, 0, &s->attr); asfd_mock_read_iobuf(asfd, &r, 0, &s->path); // Protocol1 always sends it gzipped. iobuf_set(&rbuf, CMD_APPEND, (char *)gzipped_data, sizeof(gzipped_data)); asfd_mock_read_iobuf(asfd, &r, 0, &rbuf); asfd_mock_read(asfd, &r, 0, CMD_END_FILE, "0:19201273128"); } } asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend"); asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend ok"); }
static int deal_with_data(struct asfd *asfd, struct sbuf *sb, BFILE *bfd, size_t *datalen, struct conf *conf) { int ret=-1; int forget=0; FILE *fp=NULL; size_t elen=0; char *extrameta=NULL; unsigned long long bytes=0; sb->compression=conf->compression; iobuf_copy(&sb->path, asfd->rbuf); iobuf_init(asfd->rbuf); #ifdef HAVE_WIN32 if(win32_lstat(sb->path.buf, &sb->statp, &sb->winattr)) #else if(lstat(sb->path.buf, &sb->statp)) #endif { logw(asfd, conf, "Path has vanished: %s", sb->path.buf); if(forget_file(asfd, sb, conf)) goto error; goto end; } if(size_checks(asfd, sb, conf)) forget++; if(!forget) { sb->compression=in_exclude_comp(conf->excom, sb->path.buf, conf->compression); if(attribs_encode(sb)) goto error; else if(open_file_for_sendl(asfd, #ifdef HAVE_WIN32 bfd, NULL, #else NULL, &fp, #endif sb->path.buf, sb->winattr, datalen, conf->atime, conf)) forget++; } if(forget) { if(forget_file(asfd, sb, conf)) goto error; goto end; } if(sb->path.cmd==CMD_METADATA || sb->path.cmd==CMD_ENC_METADATA || sb->path.cmd==CMD_VSS || sb->path.cmd==CMD_ENC_VSS #ifdef HAVE_WIN32 || conf->strip_vss #endif ) { if(get_extrameta(asfd, #ifdef HAVE_WIN32 bfd, #endif sb->path.buf, &sb->statp, &extrameta, &elen, sb->winattr, conf, datalen)) { logw(asfd, conf, "Meta data error for %s", sb->path.buf); goto end; } if(extrameta) { #ifdef HAVE_WIN32 if(conf->strip_vss) { free(extrameta); extrameta=NULL; elen=0; } #endif } else { logw(asfd, conf, "No meta data after all: %s", sb->path.buf); goto end; } } if(sb->path.cmd==CMD_FILE && sb->burp1->datapth.buf) { unsigned long long sentbytes=0; // Need to do sig/delta stuff. if(asfd->write(asfd, &(sb->burp1->datapth)) || asfd->write(asfd, &sb->attr) || asfd->write(asfd, &sb->path) || load_signature_and_send_delta(asfd, bfd, fp, &bytes, &sentbytes, conf, *datalen)) { logp("error in sig/delta for %s (%s)\n", sb->path.buf, sb->burp1->datapth.buf); goto end; } else { cntr_add(conf->cntr, CMD_FILE_CHANGED, 1); cntr_add_bytes(conf->cntr, bytes); cntr_add_sentbytes(conf->cntr, sentbytes); } } else { //logp("need to send whole file: %s\n", sb.path); // send the whole file. if((asfd->write(asfd, &sb->attr) || asfd->write(asfd, &sb->path)) || send_whole_file_w(asfd, sb, NULL, 0, &bytes, conf->encryption_password, conf, sb->compression, bfd, fp, extrameta, elen, *datalen)) goto end; else { cntr_add(conf->cntr, sb->path.cmd, 1); cntr_add_bytes(conf->cntr, bytes); cntr_add_sentbytes(conf->cntr, bytes); } } end: ret=0; error: #ifdef HAVE_WIN32 // If using Windows do not close bfd - it needs // to stay open to read VSS/file data/VSS. // It will get closed either when given a // different file path, or when this function // exits. #else close_file_for_sendl(NULL, &fp, asfd); #endif sbuf_free_content(sb); if(extrameta) free(extrameta); return ret; }