static int restore_link(struct asfd *asfd, struct sbuf *sb, const char *fname, enum action act, struct conf **confs) { int ret=0; if(act==ACTION_RESTORE) { char *rpath=NULL; if(build_path(fname, "", &rpath, NULL)) { ret=warn_and_interrupt(asfd, sb, confs, "build path failed: %s", fname); goto end; } else if(make_link(asfd, fname, sb->link.buf, sb->link.cmd, confs)) { ret=warn_and_interrupt(asfd, sb, confs, "could not create link", ""); goto end; } else if(!ret) { attribs_set(asfd, fname, &(sb->statp), sb->winattr, confs); cntr_add(get_cntr(confs[OPT_CNTR]), sb->path.cmd, 1); } if(rpath) free(rpath); } else cntr_add(get_cntr(confs[OPT_CNTR]), sb->path.cmd, 1); end: return ret; }
static int restore_link(struct asfd *asfd, struct sbuf *sb, const char *fname, enum action act, struct cntr *cntr, enum protocol protocol, const char *restore_prefix) { int ret=0; if(act==ACTION_RESTORE) { char *rpath=NULL; if(build_path(fname, "", &rpath, NULL)) { ret=warn_and_interrupt(asfd, sb, cntr, protocol, "build path failed: %s", fname); goto end; } else if(make_link(asfd, fname, sb->link.buf, sb->link.cmd, cntr, restore_prefix)) { ret=warn_and_interrupt(asfd, sb, cntr, protocol, "could not create link", ""); goto end; } else if(!ret) { attribs_set(asfd, fname, &(sb->statp), sb->winattr, cntr); cntr_add(cntr, sb->path.cmd, 1); } free_w(&rpath); } else cntr_add(cntr, sb->path.cmd, 1); end: return ret; }
int restore_dir(struct asfd *asfd, struct sbuf *sb, const char *dname, enum action act, struct conf **confs) { int ret=0; char *rpath=NULL; if(act==ACTION_RESTORE) { if(build_path(dname, "", &rpath, NULL)) { ret=warn_and_interrupt(asfd, sb, confs, "build path failed: %s", dname); goto end; } else if(!is_dir_lstat(rpath)) { if(mkdir(rpath, 0777)) { ret=warn_and_interrupt(asfd, sb, confs, "mkdir error: %s", strerror(errno)); goto end; } } attribs_set(asfd, rpath, &(sb->statp), sb->winattr, confs); if(!ret) cntr_add(get_cntr(confs[OPT_CNTR]), sb->path.cmd, 1); } else cntr_add(get_cntr(confs[OPT_CNTR]), sb->path.cmd, 1); end: if(rpath) free(rpath); return ret; }
int restore_dir(struct asfd *asfd, struct sbuf *sb, const char *dname, enum action act, struct cntr *cntr, enum protocol protocol) { int ret=0; char *rpath=NULL; if(act==ACTION_RESTORE) { if(build_path(dname, "", &rpath, NULL)) { ret=warn_and_interrupt(asfd, sb, cntr, protocol, "build path failed: %s", dname); goto end; } else if(is_dir_lstat(rpath)<=0) { if(mkdir(rpath, 0777)) { ret=warn_and_interrupt(asfd, sb, cntr, protocol, "mkdir error: %s", strerror(errno)); goto end; } } attribs_set(asfd, rpath, &(sb->statp), sb->winattr, cntr); if(!ret) cntr_add(cntr, sb->path.cmd, 1); } else cntr_add(cntr, sb->path.cmd, 1); end: free_w(&rpath); return ret; }
static int restore_metadata(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, enum action act, int vss_restore, struct cntr *cntr, const char *encryption_password) { int ret=-1; size_t metalen=0; char *metadata=NULL; // If it is directory metadata, try to make sure the directory // exists. Pass in NULL as the cntr, so no counting is done. // The actual directory entry will be coming after the metadata, // annoyingly. This is because of the way that the server is queuing // up directories to send after file data, so that the stat info on // them gets set correctly. if(act==ACTION_VERIFY) { cntr_add(cntr, sb->path.cmd, 1); ret=0; goto end; } if(S_ISDIR(sb->statp.st_mode) && restore_dir(asfd, sb, fname, act, cntr, PROTO_1)) goto end; // Read in the metadata... if(restore_file_or_get_meta(asfd, bfd, sb, fname, act, &metadata, &metalen, vss_restore, cntr, encryption_password)) goto end; if(metadata) { if(!set_extrameta(asfd, bfd, fname, sb, metadata, metalen, cntr)) { #ifndef HAVE_WIN32 // Set attributes again, since we just diddled with the // file. attribs_set(asfd, fname, &(sb->statp), sb->winattr, cntr); cntr_add(cntr, sb->path.cmd, 1); #endif } // Carry on if we could not set_extrameta. } ret=0; end: free_w(&metadata); return ret; }
static int restore_metadata(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, enum action act, const char *encpassword, int vss_restore, struct conf *conf) { // If it is directory metadata, try to make sure the directory // exists. Pass in NULL as the cntr, so no counting is done. // The actual directory entry will be coming after the metadata, // annoyingly. This is because of the way that the server is queuing // up directories to send after file data, so that the stat info on // them gets set correctly. if(act==ACTION_RESTORE) { size_t metalen=0; char *metadata=NULL; if(S_ISDIR(sb->statp.st_mode) && restore_dir(asfd, sb, fname, act, NULL)) return -1; // Read in the metadata... if(restore_file_or_get_meta(asfd, bfd, sb, fname, act, encpassword, &metadata, &metalen, vss_restore, conf)) return -1; if(metadata) { if(set_extrameta(asfd, #ifdef HAVE_WIN32 bfd, #endif fname, sb->path.cmd, &(sb->statp), metadata, metalen, conf)) { free(metadata); // carry on if we could not do it return 0; } free(metadata); #ifndef HAVE_WIN32 // set attributes again, since we just diddled with // the file attribs_set(asfd, fname, &(sb->statp), sb->winattr, conf); #endif cntr_add(conf->cntr, sb->path.cmd, 1); } } else cntr_add(conf->cntr, sb->path.cmd, 1); return 0; }
static int restore_file_or_get_meta(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, enum action act, char **metadata, size_t *metalen, int vss_restore, struct cntr *cntr, const char *encyption_password) { int ret=0; char *rpath=NULL; if(act==ACTION_VERIFY) { cntr_add(cntr, sb->path.cmd, 1); goto end; } if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, cntr, PROTO_1)) ret=-1; goto end; } #ifndef HAVE_WIN32 // We always want to open the file if it is on Windows. Otherwise, // only open it if we are not doing metadata. if(!metadata) { #endif switch(open_for_restore(asfd, bfd, rpath, sb, vss_restore, cntr, PROTO_1)) { case OFR_OK: break; case OFR_CONTINUE: goto end; default: ret=-1; goto end; } #ifndef HAVE_WIN32 } #endif if(!(ret=do_restore_file_or_get_meta(asfd, bfd, sb, fname, metadata, metalen, cntr, rpath, encyption_password))) cntr_add(cntr, sb->path.cmd, 1); end: free_w(&rpath); if(ret) logp("restore_file error\n"); return ret; }
int restore_sbuf_protocol1(struct asfd *asfd, struct sbuf *sb, struct bu *bu, enum action act, struct sdirs *sdirs, enum cntr_status cntr_status, struct conf **cconfs) { if((sb->protocol1->datapth.buf && asfd->write(asfd, &(sb->protocol1->datapth))) || asfd->write(asfd, &sb->attr)) return -1; else if(sbuf_is_filedata(sb) || sbuf_is_vssdata(sb)) { if(!sb->protocol1->datapth.buf) { logw(asfd, get_cntr(cconfs), "Got filedata entry with no datapth: %c:%s\n", sb->path.cmd, sb->path.buf); return 0; } return restore_file(asfd, bu, sb, act, sdirs, cconfs); } else { if(asfd->write(asfd, &sb->path)) return -1; // If it is a link, send what // it points to. else if(sbuf_is_link(sb) && asfd->write(asfd, &sb->link)) return -1; cntr_add(get_cntr(cconfs), sb->path.cmd, 0); } return 0; }
static void get_wbuf_from_data(struct conf **confs, struct iobuf *wbuf, struct slist *slist, uint8_t end_flags) { struct blk *blk; struct blist *blist=slist->blist; for(blk=blist->last_sent; blk; blk=blk->next) { if(blk->requested) { iobuf_set(wbuf, CMD_DATA, blk->data, blk->length); blk->requested=0; blist->last_sent=blk; cntr_add(get_cntr(confs), CMD_DATA, 1); break; } else { cntr_add_same(get_cntr(confs), CMD_DATA); if(end_flags&END_BLK_REQUESTS) { // Force onwards when the server has said that // there are no more blocks to request. blist->last_sent=blk; continue; } } if(blk==blist->last_requested) break; } // Need to free stuff that is no longer needed. free_stuff(slist); }
static void get_wbuf_from_data(struct conf *conf, struct iobuf *wbuf, struct slist *slist, struct blist *blist, int blk_requests_end) { struct blk *blk; for(blk=blist->last_sent; blk; blk=blk->next) { if(blk->requested) { wbuf->cmd=CMD_DATA; wbuf->buf=blk->data; wbuf->len=blk->length; blk->requested=0; blist->last_sent=blk; cntr_add(conf->cntr, CMD_DATA, 1); cntr_add_sentbytes(conf->cntr, blk->length); break; } else { cntr_add_same(conf->cntr, CMD_DATA); if(blk_requests_end) { // Force onwards when the server has said that // there are no more blocks to request. blist->last_sent=blk; continue; } } if(blk==blist->last_requested) break; } // Need to free stuff that is no longer needed. free_stuff(slist, blist); }
static int add_data_to_store(struct cntr *cntr, struct slist *slist, struct iobuf *rbuf, struct dpth *dpth) { static struct blk *blk=NULL; // Find the first one in the list that was requested. // FIX THIS: Going up the list here, and then later // when writing to the manifest is not efficient. for(blk=slist->blist->head; blk && (!blk->requested || blk->got==BLK_GOT); blk=blk->next) { // logp("try: %d %d\n", blk->index, blk->got); } if(!blk) { logp("Received data but could not find next requested block.\n"); if(!slist->blist->head) logp("and slist->blist->head is null\n"); else logp("head index: %" PRIu64 "\n", slist->blist->head->index); return -1; } // Add it to the data store straight away. if(dpth_protocol2_fwrite(dpth, rbuf, blk)) return -1; cntr_add(cntr, CMD_DATA, 0); cntr_add_recvbytes(cntr, blk->length); blk->got=BLK_GOT; blk=blk->next; return 0; }
static int start_restore_file(struct asfd *asfd, BFILE *bfd, struct sbuf *sb, const char *fname, enum action act, const char *encpassword, char **metadata, size_t *metalen, int vss_restore, struct cntr *cntr) { int ret=-1; char *rpath=NULL; if(act==ACTION_VERIFY) { cntr_add(cntr, sb->path.cmd, 1); goto end; } if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // Failed - do a warning. snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, cntr, PROTO_2)) goto error; goto end; // Try to carry on with other files. } switch(open_for_restore(asfd, bfd, rpath, sb, vss_restore, cntr, PROTO_2)) { case OFR_OK: break; case OFR_CONTINUE: goto end; default: goto error; } cntr_add(cntr, sb->path.cmd, 1); end: ret=0; error: free_w(&rpath); return ret; }
static int read_stat(struct asfd *asfd, struct iobuf *rbuf, FILE *fp, gzFile zp, struct sbuf *sb, struct cntr *cntr) { while(1) { iobuf_free_content(rbuf); if(fp || zp) { int asr; if((asr=read_fp(fp, zp, rbuf))) { //logp("read_fp returned: %d\n", asr); return asr; } if(rbuf->buf[rbuf->len]=='\n') rbuf->buf[rbuf->len]='\0'; } else { if(asfd->read(asfd)) { break; } if(rbuf->cmd==CMD_WARNING) { logp("WARNING: %s\n", rbuf->buf); cntr_add(cntr, rbuf->cmd, 0); continue; } } if(rbuf->cmd==CMD_DATAPTH) { iobuf_copy(&(sb->burp1->datapth), rbuf); rbuf->buf=NULL; } else if(rbuf->cmd==CMD_ATTRIBS) { iobuf_copy(&sb->attr, rbuf); rbuf->buf=NULL; attribs_decode(sb); return 0; } else if((rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "backupend")) || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "restoreend")) || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "phase1end")) || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "backupphase2")) || (rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "estimateend"))) { iobuf_free_content(rbuf); return 1; } else return unexpected(rbuf, __func__); } iobuf_free_content(rbuf); return -1; }
// FIX THIS: it only works with protocol1. int restore_interrupt(struct asfd *asfd, struct sbuf *sb, const char *msg, struct cntr *cntr, enum protocol protocol) { int ret=0; struct iobuf *rbuf=asfd->rbuf; if(protocol!=PROTO_1) return 0; if(!cntr) return 0; cntr_add(cntr, CMD_WARNING, 1); logp("WARNING: %s\n", msg); if(asfd->write_str(asfd, CMD_WARNING, msg)) goto end; // If it is file data, get the server // to interrupt the flow and move on. if(sb->path.cmd!=CMD_FILE && sb->path.cmd!=CMD_ENC_FILE && sb->path.cmd!=CMD_EFS_FILE && sb->path.cmd!=CMD_VSS && sb->path.cmd!=CMD_ENC_VSS && sb->path.cmd!=CMD_VSS_T && sb->path.cmd!=CMD_ENC_VSS_T) return 0; if(sb->protocol1 && !(sb->protocol1->datapth.buf)) return 0; if(sb->protocol2 && !(sb->path.buf)) return 0; if(asfd->write_str(asfd, CMD_INTERRUPT, sb->protocol1->datapth.buf)) goto end; // Read to the end file marker. while(1) { iobuf_free_content(rbuf); if(asfd->read(asfd)) goto end; if(!ret && rbuf->len) { if(rbuf->cmd==CMD_APPEND) continue; else if(rbuf->cmd==CMD_END_FILE) break; else { iobuf_log_unexpected(rbuf, __func__); goto end; } } } ret=0; end: iobuf_free_content(rbuf); return ret; }
int restore_interrupt(struct asfd *asfd, struct sbuf *sb, const char *msg, struct cntr *cntr, enum protocol protocol) { int ret=0; char *path=NULL; struct iobuf *rbuf=asfd->rbuf; if(cntr) { cntr_add(cntr, CMD_WARNING, 1); logp("WARNING: %s\n", msg); if(asfd->write_str(asfd, CMD_WARNING, msg)) goto end; } // If it is file data, get the server // to interrupt the flow and move on. if(!iobuf_is_filedata(&sb->path) && !iobuf_is_vssdata(&sb->path)) return 0; if(protocol==PROTO_1) path=sb->protocol1->datapth.buf; else if(protocol==PROTO_2) path=sb->path.buf; if(!path) return 0; if(asfd->write_str(asfd, CMD_INTERRUPT, path)) goto end; // Read to the end file marker. while(1) { iobuf_free_content(rbuf); if(asfd->read(asfd)) goto end; if(!rbuf->len) continue; switch(rbuf->cmd) { case CMD_APPEND: case CMD_DATA: continue; case CMD_END_FILE: ret=0; goto end; default: iobuf_log_unexpected(rbuf, __func__); goto end; } } end: iobuf_free_content(rbuf); return ret; }
static DWORD WINAPI read_efs(PBYTE pbData, PVOID pvCallbackContext, PULONG ulLength) { struct iobuf *rbuf; struct winbuf *mybuf=(struct winbuf *)pvCallbackContext; rbuf=mybuf->asfd->rbuf; while(1) { if(mybuf->asfd->read(mybuf->asfd)) return ERROR_FUNCTION_FAILED; (*(mybuf->rcvd))+=rbuf->len; switch(rbuf->cmd) { case CMD_APPEND: memcpy(pbData, rbuf->buf, rbuf->len); *ulLength=(ULONG)rbuf->len; (*(mybuf->sent))+=rbuf->len; iobuf_free_content(rbuf); return ERROR_SUCCESS; case CMD_END_FILE: *ulLength=0; iobuf_free_content(rbuf); return ERROR_SUCCESS; case CMD_MESSAGE: logp("MESSAGE: %s\n", rbuf->buf); cntr_add(mybuf->cntr, rbuf->cmd, 0); iobuf_free_content(rbuf); continue; case CMD_WARNING: logp("WARNING: %s\n", rbuf->buf); cntr_add(mybuf->cntr, rbuf->cmd, 0); iobuf_free_content(rbuf); continue; default: iobuf_log_unexpected(rbuf, __func__); iobuf_free_content(rbuf); break; } } return ERROR_FUNCTION_FAILED; }
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs, struct sbuf *rb, FILE *p2fp, struct conf *cconf, char **last_requested) { static char *cp=NULL; static struct iobuf *rbuf; rbuf=asfd->rbuf; // Finished the file. // Write it to the phase2 file, and free the buffers. if(close_fp(&(rb->burp1->fp))) { logp("error closing delta for %s in receive\n", rb->path); goto error; } if(gzclose_fp(&(rb->burp1->zp))) { logp("error gzclosing delta for %s in receive\n", rb->path); goto error; } iobuf_copy(&rb->burp1->endfile, rbuf); rbuf->buf=NULL; if(rb->flags & SBUFL_RECV_DELTA && finish_delta(sdirs, rb)) goto error; if(sbufl_to_manifest(rb, p2fp, NULL)) goto error; if(rb->flags & SBUFL_RECV_DELTA) cntr_add_changed(cconf->cntr, rb->path.cmd); else cntr_add(cconf->cntr, rb->path.cmd, 0); if(*last_requested && !strcmp(rb->path.buf, *last_requested)) { free(*last_requested); *last_requested=NULL; } cp=strchr(rb->burp1->endfile.buf, ':'); if(rb->burp1->endfile.buf) cntr_add_bytes(cconf->cntr, strtoull(rb->burp1->endfile.buf, NULL, 10)); if(cp) { // checksum stuff goes here } sbuf_free_content(rb); return 0; error: sbuf_free_content(rb); return -1; }
void log_recvd(struct iobuf *iobuf, struct cntr *cntr, int print) { const char *prefix="unset"; switch(iobuf->cmd) { case CMD_MESSAGE: prefix="MESSAGE"; break; case CMD_WARNING: prefix="WARNING"; break; default: break; } logp("%s: %s", prefix, iobuf->buf); cntr_add(cntr, iobuf->cmd, print); }
static int restore_link(struct asfd *asfd, struct sbuf *sb, const char *fname, const char *restoreprefix, enum action act, struct conf *conf) { int ret=0; if(act==ACTION_RESTORE) { char *rpath=NULL; if(build_path(fname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", fname); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } else if(make_link(asfd, fname, sb->link.buf, sb->link.cmd, restoreprefix, conf)) { // failed - do a warning if(restore_interrupt(asfd, sb, "could not create link", conf)) ret=-1; goto end; } else if(!ret) { attribs_set(asfd, fname, &(sb->statp), sb->winattr, conf); cntr_add(conf->cntr, sb->path.cmd, 1); } if(rpath) free(rpath); } else cntr_add(conf->cntr, sb->path.cmd, 1); end: return ret; }
static int restore_dir(struct asfd *asfd, struct sbuf *sb, const char *dname, enum action act, struct conf *conf) { int ret=0; char *rpath=NULL; if(act==ACTION_RESTORE) { if(build_path(dname, "", &rpath, NULL)) { char msg[256]=""; // failed - do a warning snprintf(msg, sizeof(msg), "build path failed: %s", dname); if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } else if(!is_dir_lstat(rpath)) { if(mkdir(rpath, 0777)) { char msg[256]=""; snprintf(msg, sizeof(msg), "mkdir error: %s", strerror(errno)); // failed - do a warning if(restore_interrupt(asfd, sb, msg, conf)) ret=-1; goto end; } } attribs_set(asfd, rpath, &(sb->statp), sb->winattr, conf); if(!ret) cntr_add(conf->cntr, sb->path.cmd, 1); } else cntr_add(conf->cntr, sb->path.cmd, 1); end: if(rpath) free(rpath); return ret; }
static int new_non_file(struct sbuf *p1b, struct manio *ucmanio, struct conf **cconfs) { // Is something that does not need more data backed up. // Like a directory or a link or something like that. // Goes into the unchanged file, so that it does not end up out of // order with normal files, which has to wait around for their data // to turn up. if(manio_write_sbuf(ucmanio, p1b)) return -1; cntr_add(get_cntr(cconfs), p1b->path.cmd, 0); sbuf_free_content(p1b); return 0; }
static int new_non_file(struct sbuf *p1b, FILE *ucfp, struct conf *cconf) { // Is something that does not need more data backed up. // Like a directory or a link or something like that. // Goes into the unchanged file, so that it does not end up out of // order with normal files, which has to wait around for their data // to turn up. if(sbufl_to_manifest(p1b, ucfp, NULL)) return -1; else cntr_add(cconf->cntr, p1b->path.cmd, 0); sbuf_free_content(p1b); return 0; }
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs, struct sbuf *rb, struct manio *chmanio, struct conf **cconfs, char **last_requested) { int ret=-1; static char *cp=NULL; static struct iobuf *rbuf; struct cntr *cntr=get_cntr(cconfs); rbuf=asfd->rbuf; // Finished the file. // Write it to the phase2 file, and free the buffers. if(fzp_close(&(rb->protocol1->fzp))) { logp("error closing delta for %s in receive\n", rb->path.buf); goto end; } iobuf_move(&rb->endfile, rbuf); if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb)) goto end; if(manio_write_sbuf(chmanio, rb)) goto end; if(rb->flags & SBUF_RECV_DELTA) cntr_add_changed(cntr, rb->path.cmd); else cntr_add(cntr, rb->path.cmd, 0); if(*last_requested && !strcmp(rb->path.buf, *last_requested)) free_w(last_requested); cp=strchr(rb->endfile.buf, ':'); if(rb->endfile.buf) cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10)); if(cp) { // checksum stuff goes here } ret=0; end: sbuf_free_content(rb); return ret; }
static int restore_sbuf(struct asfd *asfd, struct sbuf *sb, enum action act, enum cstat_status status, struct conf *conf, int *need_data) { //logp("%s: %s\n", act==ACTION_RESTORE?"restore":"verify", sb->path.buf); if(write_status(status, sb->path.buf, conf)) return -1; if(asfd->write(asfd, &sb->attr) || asfd->write(asfd, &sb->path)) return -1; if(sbuf_is_link(sb) && asfd->write(asfd, &sb->link)) return -1; if(sb->burp2->bstart) { // This will restore directory data on Windows. struct blk *b=NULL; struct blk *n=NULL; b=sb->burp2->bstart; while(b) { struct iobuf wbuf; iobuf_set(&wbuf, CMD_DATA, b->data, b->length); if(asfd->write(asfd, &wbuf)) return -1; n=b->next; blk_free(&b); b=n; } sb->burp2->bstart=sb->burp2->bend=NULL; } switch(sb->path.cmd) { case CMD_FILE: case CMD_ENC_FILE: case CMD_METADATA: case CMD_ENC_METADATA: case CMD_EFS_FILE: *need_data=1; return 0; default: cntr_add(conf->cntr, sb->path.cmd, 0); return 0; } }
int logw(struct asfd *asfd, struct cntr *cntr, const char *fmt, ...) { int r=0; char buf[512]=""; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); if(asfd && asfd->as && asfd->as->doing_estimate) printf("\nWARNING: %s", buf); else { if(asfd) r=asfd->write_str(asfd, CMD_WARNING, buf); logp("WARNING: %s", buf); } va_end(ap); cntr_add(cntr, CMD_WARNING, 1); return r; }
int logm(struct asfd *asfd, struct conf **confs, const char *fmt, ...) { int r=0; char buf[512]=""; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); if(asfd && asfd->as->doing_estimate) printf("\nMESSAGE: %s", buf); else { if(asfd && get_int(confs[OPT_MESSAGE])) // Backwards compatibility r=asfd->write_str(asfd, CMD_MESSAGE, buf); logp("MESSAGE: %s", buf); } va_end(ap); if(confs) cntr_add(get_cntr(confs), CMD_MESSAGE, 1); return r; }
static int parse_rbuf(struct asfd *asfd, struct sbuf *sb, BFILE *bfd, size_t *datalen, struct conf *conf) { static struct iobuf *rbuf; rbuf=asfd->rbuf; //logp("now: %c:%s\n", rbuf->cmd, rbuf->buf); if(rbuf->cmd==CMD_DATAPTH) { iobuf_copy(&(sb->burp1->datapth), rbuf); rbuf->buf=NULL; } else if(rbuf->cmd==CMD_ATTRIBS) { // Ignore the stat data - we will fill it // in again. Some time may have passed by now, // and it is best to make it as fresh as // possible. } else if(rbuf->cmd==CMD_FILE || rbuf->cmd==CMD_ENC_FILE || rbuf->cmd==CMD_METADATA || rbuf->cmd==CMD_ENC_METADATA || rbuf->cmd==CMD_VSS || rbuf->cmd==CMD_ENC_VSS || rbuf->cmd==CMD_VSS_T || rbuf->cmd==CMD_ENC_VSS_T || rbuf->cmd==CMD_EFS_FILE) { if(deal_with_data(asfd, sb, bfd, datalen, conf)) return -1; } else if(rbuf->cmd==CMD_WARNING) { cntr_add(conf->cntr, rbuf->cmd, 0); } else { iobuf_log_unexpected(rbuf, __func__); return -1; } return 0; }
static int send_data(struct asfd *asfd, struct blk *blk, enum action act, struct sbuf *need_data, struct cntr *cntr) { struct iobuf wbuf; switch(act) { case ACTION_RESTORE: iobuf_set(&wbuf, CMD_DATA, blk->data, blk->length); if(asfd->write(asfd, &wbuf)) return -1; return 0; case ACTION_VERIFY: // Need to check that the block has the correct // checksums. switch(blk_verify(blk)) { case 1: iobuf_set(&wbuf, CMD_DATA, (char *)"0", 1); if(asfd->write(asfd, &wbuf)) return -1; cntr_add(cntr, CMD_DATA, 0); break; // All OK. case 0: { char msg[256]; snprintf(msg, sizeof(msg), "Checksum mismatch in block for %c:%s:%s\n", need_data->path.cmd, need_data->path.buf, uint64_to_savepathstr_with_sig(blk->savepath)); logw(asfd, cntr, msg); break; } default: { char msg[256]; snprintf(msg, sizeof(msg), "Error when attempting to verify block for %c:%s:%s\n", need_data->path.cmd, need_data->path.buf, uint64_to_savepathstr_with_sig(blk->savepath)); return -1; } } return 0; default: logp("unknown action in %s: %d\n", __func__, act); return -1; } }
int restore_sbuf_protocol2(struct asfd *asfd, struct sbuf *sb, enum action act, struct cntr *cntr, struct sbuf *need_data) { if(asfd->write(asfd, &sb->attr) || asfd->write(asfd, &sb->path)) return -1; if(sbuf_is_link(sb) && asfd->write(asfd, &sb->link)) return -1; if(sb->protocol2->bstart) { // This will restore directory data on Windows. struct blk *b=NULL; struct blk *n=NULL; b=sb->protocol2->bstart; while(b) { if(send_data(asfd, b, act, need_data, cntr)) return -1; n=b->next; blk_free(&b); b=n; } sb->protocol2->bstart=sb->protocol2->bend=NULL; } if(sbuf_is_filedata(sb)) { if(need_data) { iobuf_copy(&need_data->path, &sb->path); sb->path.buf=NULL; } } else cntr_add(cntr, sb->path.cmd, 0); return 0; }
int authorise_client(struct asfd *asfd, char **server_version, const char *cname, const char *password, struct cntr *cntr) { int ret=-1; char hello[256]=""; struct iobuf *rbuf=asfd->rbuf; snprintf(hello, sizeof(hello), "hello:%s", VERSION); if(asfd->write_str(asfd, CMD_GEN, hello)) { logp("problem with auth\n"); goto end; } if(asfd->read(asfd) || rbuf->cmd!=CMD_GEN || strncmp_w(rbuf->buf, "whoareyou")) { logp("problem with auth\n"); goto end; } if(rbuf->buf) { char *cp=NULL; if((cp=strchr(rbuf->buf, ':'))) { cp++; if(cp && !(*server_version=strdup_w(cp, __func__))) goto end; } iobuf_free_content(rbuf); } if(asfd->write_str(asfd, CMD_GEN, cname) || asfd_read_expect(asfd, CMD_GEN, "okpassword") || asfd->write_str(asfd, CMD_GEN, password) || asfd->read(asfd)) { logp("problem with auth\n"); goto end; } if(rbuf->cmd==CMD_WARNING) // special case for the version warning { //logw(conf->p1cntr, rbuf->buf); logp("WARNING: %s\n", rbuf->buf); cntr_add(cntr, rbuf->cmd, 0); iobuf_free_content(rbuf); if(asfd->read(asfd)) { logp("problem with auth\n"); goto end; } } if(rbuf->cmd==CMD_GEN && !strcmp(rbuf->buf, "ok")) { // It is OK. logp("auth ok\n"); } else { iobuf_log_unexpected(rbuf, __func__); goto end; } ret=0; end: iobuf_free_content(rbuf); return ret; }