// Return 0 for OK, -1 for error, 1 for timer conditions not met. static int do_backup_client(struct config *conf, int resume, int estimate, struct cntr *p1cntr, struct cntr *cntr) { int ret=0; if(estimate) logp("do estimate client\n"); else logp("do backup client\n"); #if defined(HAVE_WIN32) win32_enable_backup_privileges(); #endif #if defined(WIN32_VSS) if((ret=win32_start_vss(conf))) return ret; #endif // Scan the file system and send the results to the server. // Skip phase1 if the server wanted to resume. if(!ret && !resume) ret=backup_phase1_client(conf, estimate, p1cntr, cntr); // Now, the server will be telling us what data we need to send. if(!estimate && !ret) ret=backup_phase2_client(conf, p1cntr, resume, cntr); if(estimate) print_filecounters(p1cntr, cntr, ACTION_ESTIMATE); #if defined(WIN32_VSS) win32_stop_vss(); #endif return ret; }
static int generate_key_and_csr(struct config *conf, const char *csr_path) { logp("Generating SSL key and certificate signing request\n"); logp("Running '%s --key --keypath %s --request --requestpath %s --name %s'\n", conf->ca_burp_ca, conf->ssl_key, csr_path, conf->cname); #ifdef HAVE_WIN32 win32_enable_backup_privileges(1 /* ignore_errors */); #endif if(run_script(conf->ca_burp_ca, NULL, 0, "--key", "--keypath", conf->ssl_key, "--request", "--requestpath", csr_path, "--name", conf->cname, NULL, NULL, NULL /* cntr */, 1 /* wait */, 0 /* do not use logp - stupid openssl prints lots of dots one at a time with no way to turn it off */)) { logp("error when running '%s --key --keypath %s --request --requestpath %s --name %s'\n", conf->ca_burp_ca, conf->ssl_key, csr_path, conf->cname); return -1; } return 0; }
// Return 0 for OK, -1 for error, 1 for timer conditions not met. int do_backup_client(struct asfd *asfd, struct conf *conf, enum action action, long name_max, int resume) { int ret=0; if(action==ACTION_ESTIMATE) logp("do estimate client\n"); else logp("do backup client\n"); #if defined(HAVE_WIN32) win32_enable_backup_privileges(); #if defined(WIN32_VSS) if((ret=win32_start_vss(conf))) return ret; #endif if(action==ACTION_BACKUP_TIMED) { // Run timed backups with lower priority. // I found that this has to be done after the snapshot, or the // snapshot never finishes. At least, I waited 30 minutes with // nothing happening. #if defined(B_VSS_XP) || defined(B_VSS_W2K3) if(SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_LOWEST)) logp("Set thread_priority_lowest\n"); else logp("Failed to set thread_priority_lowest\n"); #else if(SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_BEGIN)) logp("Set thread_mode_background_begin\n"); else logp("Failed to set thread_mode_background_begin\n"); #endif } #endif // Scan the file system and send the results to the server. // Skip phase1 if the server wanted to resume. if(!ret && !resume) ret=backup_phase1_client(asfd, conf, name_max, action==ACTION_ESTIMATE); if(action!=ACTION_ESTIMATE && !ret) { // Now, the server will be telling us what data we need to // send. if(conf->protocol==PROTO_BURP1) ret=backup_phase2_client_burp1(asfd, conf, resume); else ret=backup_phase2_client(asfd, conf, resume); } if(action==ACTION_ESTIMATE) cntr_print(conf->cntr, ACTION_ESTIMATE); #if defined(HAVE_WIN32) if(action==ACTION_BACKUP_TIMED) { if(SetThreadPriority(GetCurrentThread(), THREAD_MODE_BACKGROUND_END)) logp("Set thread_mode_background_end\n"); else logp("Failed to set thread_mode_background_end\n"); } #if defined(WIN32_VSS) win32_stop_vss(); #endif #endif return ret; }
// Return 0 for OK, -1 for error. int do_backup_client(struct asfd *asfd, struct conf **confs, enum action action, int resume) { int ret=-1; int breaking=get_int(confs[OPT_BREAKPOINT]); if(action==ACTION_ESTIMATE) logp("do estimate client\n"); else { logp("do backup client\n"); if(get_protocol(confs)==PROTO_1) logp("Using librsync hash %s\n", rshash_to_str(get_e_rshash(confs[OPT_RSHASH]))); } #ifdef HAVE_WIN32 win32_enable_backup_privileges(); #ifdef WIN32_VSS if(win32_start_vss(confs)) return ret; #endif if(action==ACTION_BACKUP_TIMED) set_low_priority(); #endif // Scan the file system and send the results to the server. // Skip phase1 if the server wanted to resume. if(!resume) { if(breaking==1) { breakpoint(breaking, __func__); goto end; } if(backup_phase1_client(asfd, confs, action==ACTION_ESTIMATE)) goto end; } switch(action) { case ACTION_DIFF: case ACTION_DIFF_LONG: ret=1; goto end; case ACTION_ESTIMATE: cntr_print(get_cntr(confs), ACTION_ESTIMATE); break; default: // Now, the server will be telling us what data we need // to send. if(breaking==2) { breakpoint(breaking, __func__); goto end; } if(get_protocol(confs)==PROTO_1) ret=backup_phase2_client_protocol1(asfd, confs, resume); else ret=backup_phase2_client_protocol2(asfd, confs, resume); if(ret) goto end; break; } ret=0; end: #if defined(HAVE_WIN32) if(action==ACTION_BACKUP_TIMED) unset_low_priority(); #if defined(WIN32_VSS) win32_stop_vss(); #endif #endif return ret; }
int do_restore_client_burp1(struct asfd *asfd, struct conf *conf, enum action act, int vss_restore) { int ars=0; int ret=-1; char msg[512]=""; struct sbuf *sb=NULL; // Windows needs to have the VSS data written first, and the actual data // written immediately afterwards. The server is transferring them in two // chunks. So, leave bfd open after a Windows metadata transfer. BFILE bfd; #ifdef HAVE_WIN32 binit(&bfd, 0, conf); #endif logp("doing %s\n", act_str(act)); snprintf(msg, sizeof(msg), "%s %s:%s", act_str(act), conf->backup?conf->backup:"", conf->regex?conf->regex:""); if(asfd->write_str(asfd, CMD_GEN, msg) || asfd->read_expect(asfd, CMD_GEN, "ok")) return -1; logp("doing %s confirmed\n", act_str(act)); if(conf->send_client_cntr) { // FIX THIS // if(cntr_recv(conf)) goto end; } #if defined(HAVE_WIN32) if(act==ACTION_RESTORE) win32_enable_backup_privileges(); #endif if(!(sb=sbuf_alloc(conf))) goto end; while(1) { char *fullpath=NULL; sbuf_free_content(sb); if((ars=sbufl_fill(sb, asfd, NULL, NULL, conf->cntr))) { if(ars<0) goto end; else { // ars==1 means it ended ok. //logp("got %s end\n", act_str(act)); if(asfd->write_str(asfd, CMD_GEN, "restoreend ok")) goto end; } break; } switch(sb->path.cmd) { case CMD_DIRECTORY: case CMD_FILE: case CMD_ENC_FILE: case CMD_SOFT_LINK: case CMD_HARD_LINK: case CMD_SPECIAL: case CMD_METADATA: case CMD_ENC_METADATA: case CMD_VSS: case CMD_ENC_VSS: case CMD_VSS_T: case CMD_ENC_VSS_T: case CMD_EFS_FILE: if(conf->strip) { int s; s=strip_path_components(asfd, sb, &(sb->path.buf), conf); if(s<0) goto end; // error else if(s==0) { // Too many components stripped // - carry on. continue; } // It is OK, sb->path is now stripped. } if(!(fullpath=prepend_s(conf->restoreprefix, sb->path.buf))) { log_and_send_oom(asfd, __func__); goto end; } if(act==ACTION_RESTORE) { strip_invalid_characters(&fullpath); if(!overwrite_ok(sb, conf, &bfd, fullpath)) { char msg[512]=""; // Something exists at that path. snprintf(msg, sizeof(msg), "Path exists: %s", fullpath); if(restore_interrupt(asfd, sb, msg, conf)) goto end; else { if(fullpath) free(fullpath); continue; } } } break; default: break; } switch(sb->path.cmd) { case CMD_WARNING: cntr_add(conf->cntr, sb->path.cmd, 1); printf("\n"); logp("%s", sb->path); break; case CMD_DIRECTORY: if(restore_dir(asfd, sb, fullpath, act, conf)) goto end; break; case CMD_FILE: case CMD_VSS_T: // Have it a separate statement to the // encrypted version so that encrypted and not // encrypted files can be restored at the // same time. if(restore_file_or_get_meta(asfd, &bfd, sb, fullpath, act, NULL, NULL, NULL, vss_restore, conf)) { logp("restore_file error\n"); goto end; } break; case CMD_ENC_FILE: case CMD_ENC_VSS_T: if(restore_file_or_get_meta(asfd, &bfd, sb, fullpath, act, conf->encryption_password, NULL, NULL, vss_restore, conf)) { logp("restore_file error\n"); goto end; } break; case CMD_SOFT_LINK: case CMD_HARD_LINK: if(restore_link(asfd, sb, fullpath, conf->restoreprefix, act, conf)) goto end; break; case CMD_SPECIAL: if(restore_special(asfd, sb, fullpath, act, conf)) goto end; break; case CMD_METADATA: case CMD_VSS: if(restore_metadata(asfd, &bfd, sb, fullpath, act, NULL, vss_restore, conf)) goto end; break; case CMD_ENC_METADATA: case CMD_ENC_VSS: if(restore_metadata(asfd, &bfd, sb, fullpath, act, conf->encryption_password, vss_restore, conf)) goto end; break; case CMD_EFS_FILE: if(restore_file_or_get_meta(asfd, &bfd, sb, fullpath, act, NULL, NULL, NULL, vss_restore, conf)) { logp("restore_file error\n"); goto end; } break; default: logp("unknown cmd: %c\n", sb->path.cmd); goto end; break; } if(fullpath) free(fullpath); } ret=0; end: sbuf_free(sb); #ifdef HAVE_WIN32 // It is possible for a bfd to still be open. bclose(&bfd, asfd); #endif cntr_print_end(conf->cntr); cntr_print(conf->cntr, act); if(!ret) logp("%s finished\n", act_str(act)); else logp("ret: %d\n", ret); return ret; }
int do_restore_client(struct asfd *asfd, struct conf **confs, enum action act, int vss_restore) { int ret=-1; char msg[512]=""; struct sbuf *sb=NULL; struct blk *blk=NULL; BFILE *bfd=NULL; char *fullpath=NULL; char *style=NULL; char *datpath=NULL; struct cntr *cntr=get_cntr(confs); enum protocol protocol=get_protocol(confs); int strip=get_int(confs[OPT_STRIP]); int overwrite=get_int(confs[OPT_OVERWRITE]); const char *backup=get_string(confs[OPT_BACKUP]); const char *regex=get_string(confs[OPT_REGEX]); const char *restore_prefix=get_string(confs[OPT_RESTOREPREFIX]); const char *encryption_password=get_string(confs[OPT_ENCRYPTION_PASSWORD]); if(!(bfd=bfile_alloc())) goto end; bfile_init(bfd, 0, cntr); snprintf(msg, sizeof(msg), "%s %s:%s", act_str(act), backup?backup:"", regex?regex:""); logp("doing %s\n", msg); if(asfd->write_str(asfd, CMD_GEN, msg) || asfd_read_expect(asfd, CMD_GEN, "ok")) goto error; logp("doing %s confirmed\n", act_str(act)); #if defined(HAVE_WIN32) if(act==ACTION_RESTORE) win32_enable_backup_privileges(); #endif if(!(style=get_restore_style(asfd, confs))) goto error; if(!strcmp(style, RESTORE_SPOOL)) { if(restore_spool(asfd, confs, &datpath)) goto error; } else logp("Streaming restore direct\n"); logf("\n"); if(get_int(confs[OPT_SEND_CLIENT_CNTR]) && cntr_recv(asfd, confs)) goto error; if(!(sb=sbuf_alloc(protocol)) || (protocol==PROTO_2 && !(blk=blk_alloc()))) { log_and_send_oom(asfd, __func__); goto error; } while(1) { sbuf_free_content(sb); if(protocol==PROTO_1) sb->flags |= SBUF_CLIENT_RESTORE_HACK; switch(sbuf_fill_from_net(sb, asfd, blk, datpath, cntr)) { case 0: break; case 1: if(asfd->write_str(asfd, CMD_GEN, "restoreend ok")) goto error; goto end; // It was OK. default: case -1: goto error; } if(protocol==PROTO_2) { if(blk->data) { int wret=0; if(act==ACTION_VERIFY) cntr_add(cntr, CMD_DATA, 1); else wret=write_data(asfd, bfd, blk); if(!datpath) blk_free_content(blk); blk->data=NULL; if(wret) goto error; continue; } else if(sb->endfile.buf) { continue; } } switch(sb->path.cmd) { case CMD_DIRECTORY: case CMD_FILE: case CMD_ENC_FILE: case CMD_SOFT_LINK: case CMD_HARD_LINK: case CMD_SPECIAL: case CMD_METADATA: case CMD_ENC_METADATA: case CMD_VSS: case CMD_ENC_VSS: case CMD_VSS_T: case CMD_ENC_VSS_T: case CMD_EFS_FILE: if(strip) { int s; s=strip_path_components(asfd, sb, strip, cntr, protocol); if(s<0) goto error; if(s==0) { // Too many components stripped // - carry on. continue; } // It is OK, sb.path is now stripped. } free_w(&fullpath); if(!(fullpath=prepend_s(restore_prefix, sb->path.buf))) { log_and_send_oom(asfd, __func__); goto error; } if(act==ACTION_RESTORE) { strip_invalid_characters(&fullpath); if(!overwrite_ok(sb, overwrite, #ifdef HAVE_WIN32 bfd, #endif fullpath)) { char msg[512]=""; // Something exists at that path. snprintf(msg, sizeof(msg), "Path exists: %s\n", fullpath); if(restore_interrupt(asfd, sb, msg, cntr, protocol)) goto error; continue; } } break; case CMD_MESSAGE: case CMD_WARNING: log_recvd(&sb->path, cntr, 1); logf("\n"); continue; default: break; } switch(sb->path.cmd) { // These are the same in both protocol1 and protocol2. case CMD_DIRECTORY: if(restore_dir(asfd, sb, fullpath, act, cntr, protocol)) goto error; continue; case CMD_SOFT_LINK: case CMD_HARD_LINK: if(restore_link(asfd, sb, fullpath, act, cntr, protocol, restore_prefix)) goto error; continue; case CMD_SPECIAL: if(restore_special(asfd, sb, fullpath, act, cntr, protocol)) goto error; continue; default: break; } if(protocol==PROTO_2) { if(restore_switch_protocol2(asfd, sb, fullpath, act, bfd, vss_restore, cntr)) goto error; } else { if(restore_switch_protocol1(asfd, sb, fullpath, act, bfd, vss_restore, cntr, encryption_password)) goto error; } } end: ret=0; error: // It is possible for a fd to still be open. bfd->close(bfd, asfd); bfile_free(&bfd); cntr_print_end(cntr); cntr_print(cntr, act); if(!ret) logp("%s finished\n", act_str(act)); else logp("ret: %d\n", ret); sbuf_free(&sb); free_w(&style); if(datpath) { recursive_delete(datpath); free_w(&datpath); } free_w(&fullpath); blk_free(&blk); return ret; }
int autoupgrade_client(struct async *as, struct conf *conf) { int a=0; int ret=-1; char *cp=NULL; char *copy=NULL; char *script_path=NULL; char script_name[32]=""; char package_name[32]=""; char write_str[256]=""; const char *args[2]; struct iobuf *rbuf=NULL; struct asfd *asfd; asfd=as->asfd; if(!conf->autoupgrade_dir) { logp("autoupgrade_dir not set!\n"); goto end; } if(!conf->autoupgrade_os) { logp("autoupgrade_os not set!\n"); goto end; } if(!(copy=strdup(conf->autoupgrade_dir))) { log_out_of_memory(__func__); goto end; } strip_trailing_slashes(©); if((cp=strchr(copy, '/'))) *cp='\0'; if(mkpath(&(conf->autoupgrade_dir), copy)) goto end; // Let the server know we are ready. snprintf(write_str, sizeof(write_str), "autoupgrade:%s", conf->autoupgrade_os); if(asfd->write_str(asfd, CMD_GEN, write_str)) goto end; if(!(a=asfd->simple_loop(asfd, conf, NULL, __func__, autoupgrade_func))) { ret=0; // No autoupgrade. goto end; } else if(a<0) // Error. #ifdef HAVE_WIN32 win32_enable_backup_privileges(); snprintf(script_name, sizeof(script_name), "script.bat"); snprintf(package_name, sizeof(package_name), "package.exe"); #else snprintf(script_name, sizeof(script_name), "script"); snprintf(package_name, sizeof(package_name), "package"); #endif if(receive_file(asfd, conf->autoupgrade_dir, script_name, conf)) { logp("Problem receiving %s/%s\n", conf->autoupgrade_dir, script_name); goto end; } if(receive_file(asfd, conf->autoupgrade_dir, package_name, conf)) { logp("Problem receiving %s/%s\n", conf->autoupgrade_dir, package_name); goto end; } if(!(script_path=prepend_s(conf->autoupgrade_dir, script_name))) goto end; chmod(script_path, 0755); /* Run the script here. */ a=0; args[a++]=script_path; args[a++]=NULL; ret=run_script(asfd, args, NULL, conf, 0 /* do not wait */, 1 /* use logp */, 1 /* use logw */); /* To get round Windows problems to do with installing over files that the current process is running from, I am forking the child, then immediately exiting the parent process. */ printf("\n"); logp("The server tried to upgrade your client.\n"); logp("You will need to try your command again.\n"); asfd_free(&as->asfd); exit(0); end: if(copy) free(copy); if(script_path) free(script_path); iobuf_free(rbuf); return ret; }