int backup_phase1_client(struct config *conf, int estimate, struct cntr *p1cntr, struct cntr *cntr) { int sd=0; int ret=0; FF_PKT *ff=NULL; // First, tell the server about everything that needs to be backed up. logp("Phase 1 begin (file system scan)\n"); if(conf->encryption_password) { filesymbol=CMD_ENC_FILE; metasymbol=CMD_ENC_METADATA; } ff=init_find_files(); for(; sd < conf->sdcount; sd++) { if(conf->startdir[sd]->flag) { if((ret=find_files_begin(ff, conf, conf->startdir[sd]->path, p1cntr))) break; } } term_find_files(ff); print_endcounter(p1cntr); //print_filecounters(p1cntr, cntr, ACTION_BACKUP); if(ret) logp("Error in phase 1\n"); logp("Phase 1 end (file system scan)\n"); return ret; }
int backup_phase2_client(struct config *conf, struct cntr *p1cntr, int resume, struct cntr *cntr) { int ret=0; logp("Phase 2 begin (send file data)\n"); ret=do_backup_phase2_client(conf, resume, p1cntr, cntr); print_endcounter(cntr); print_filecounters(p1cntr, cntr, ACTION_BACKUP); if(ret) logp("Error in phase 2\n"); logp("Phase 2 end (send file data)\n"); return ret; }
// a = length of struct bu array // i = position to restore from static int restore_manifest(struct bu *arr, int a, int i, const char *tmppath1, const char *tmppath2, regex_t *regex, enum action act, const char *client, struct cntr *p1cntr, struct cntr *cntr, struct config *cconf, bool all) { int ret=0; gzFile zp=NULL; char *manifest=NULL; char *datadir=NULL; FILE *logfp=NULL; char *logpath=NULL; char *logpathz=NULL; // For sending status information up to the server. char status=STATUS_RESTORING; if(act==ACTION_RESTORE) status=STATUS_RESTORING; else if(act==ACTION_VERIFY) status=STATUS_VERIFYING; if( (act==ACTION_RESTORE && !(logpath=prepend_s(arr[i].path, "restorelog", strlen("restorelog")))) || (act==ACTION_RESTORE && !(logpathz=prepend_s(arr[i].path, "restorelog.gz", strlen("restorelog.gz")))) || (act==ACTION_VERIFY && !(logpath=prepend_s(arr[i].path, "verifylog", strlen("verifylog")))) || (act==ACTION_VERIFY && !(logpathz=prepend_s(arr[i].path, "verifylog.gz", strlen("verifylog.gz")))) || !(manifest=prepend_s(arr[i].path, "manifest.gz", strlen("manifest.gz")))) { log_and_send("out of memory"); ret=-1; } else if(!(logfp=open_file(logpath, "ab")) || set_logfp(logfp)) { char msg[256]=""; snprintf(msg, sizeof(msg), "could not open log file: %s", logpath); log_and_send(msg); ret=-1; } else if(!(zp=gzopen_file(manifest, "rb"))) { log_and_send("could not open manifest"); ret=-1; } else { char cmd; int quit=0; size_t len=0; struct sbuf sb; // For out-of-sequence directory restoring so that the // timestamps come out right: int s=0; int scount=0; struct sbuf **sblist=NULL; init_sbuf(&sb); while(!quit) { int ars=0; char *buf=NULL; if(async_read_quick(&cmd, &buf, &len)) { logp("read quick error\n"); ret=-1; quit++; break; } if(buf) { //logp("got read quick\n"); if(cmd==CMD_WARNING) { logp("WARNING: %s\n", buf); do_filecounter(cntr, cmd, 0); free(buf); buf=NULL; continue; } else if(cmd==CMD_INTERRUPT) { // Client wanted to interrupt the // sending of a file. But if we are // here, we have already moved on. // Ignore. free(buf); buf=NULL; continue; } else { logp("unexpected cmd from client: %c:%s\n", cmd, buf); free(buf); buf=NULL; ret=-1; quit++; break; } } if((ars=sbuf_fill(NULL, zp, &sb, cntr))) { if(ars<0) ret=-1; // ars==1 means end ok quit++; } else { if(check_regex(regex, sb.path)) { // Check if we have any directories waiting // to be restored. for(s=scount-1; s>=0; s--) { if(is_subdir(sblist[s]->path, sb.path)) { // We are still in a subdir. //printf(" subdir (%s %s)\n", sblist[s]->path, sb.path); break; } else { // Can now restore sblist[s] // because nothing else is // fiddling in a subdirectory. if(restore_sbuf(sblist[s], arr, a, i, tmppath1, tmppath2, act, client, status, p1cntr, cntr, cconf)) { ret=-1; quit++; break; } else if(del_from_sbuf_arr( &sblist, &scount)) { ret=-1; quit++; break; } } } /* If it is a directory, need to remember it and restore it later, so that the permissions come out right. */ /* Meta data of directories will also have the stat stuff set to be a directory, so will also come out at the end. */ if(!ret && S_ISDIR(sb.statp.st_mode)) { if(add_to_sbuf_arr(&sblist, &sb, &scount)) { ret=-1; quit++; } // Wipe out sb, without freeing up // all the strings inside it, which // have been added to sblist. init_sbuf(&sb); } else if(!ret && restore_sbuf(&sb, arr, a, i, tmppath1, tmppath2, act, client, status, p1cntr, cntr, cconf)) { ret=-1; quit++; } } } free_sbuf(&sb); } gzclose_fp(&zp); // Restore any directories that are left in the list. if(!ret) for(s=scount-1; s>=0; s--) { if(restore_sbuf(sblist[s], arr, a, i, tmppath1, tmppath2, act, client, status, p1cntr, cntr, cconf)) { ret=-1; break; } } free_sbufs(sblist, scount); if(!ret && !all) ret=do_restore_end(act, cntr); print_endcounter(cntr); print_filecounters(p1cntr, cntr, act, 0); reset_filecounter(p1cntr); reset_filecounter(cntr); } set_logfp(NULL); compress_file(logpath, logpathz, cconf); if(manifest) free(manifest); if(datadir) free(datadir); if(logpath) free(logpath); if(logpathz) free(logpathz); return ret; }