static int do_lock_dirs(struct sdirs *sdirs, struct conf *conf) { int ret=-1; char *lockbase=NULL; char *lockfile=NULL; if(conf->client_lockdir) { if(!(sdirs->lockdir=strdup_w(conf->client_lockdir, __func__)) || !(lockbase=prepend_s(sdirs->lockdir, conf->cname))) goto end; } else { if(!(sdirs->lockdir=strdup_w(sdirs->client, __func__)) || !(lockbase=strdup_w(sdirs->client, __func__))) goto end; } if(!(lockfile=prepend_s(lockbase, "lockfile")) || !(sdirs->lock=lock_alloc_and_init(lockfile))) goto end; ret=0; end: free_w(&lockbase); free_w(&lockfile); return ret; }
static char *get_restorepath(struct conf **cconfs) { char *tmp=NULL; char *restorepath=NULL; if((tmp=prepend_s(get_string(cconfs[OPT_DIRECTORY]), get_string(cconfs[OPT_CNAME])))) restorepath=prepend_s(tmp, "restore"); free_w(&tmp); return restorepath; }
int init_dpthl(struct dpthl *dpthl, struct asfd *asfd, struct sdirs *sdirs, struct conf *cconf) { char *tmp=NULL; //logp("in init_dpthl\n"); dpthl->looped=0; dpthl->prim=0; dpthl->seco=0; dpthl->tert=0; if((dpthl->prim=get_highest_entry(sdirs->currentdata))<0) { // Could not open directory. Set all zeros. dpthl->prim=0; // mk_dpthl(dpthl, cconf); return 0; } mk_dpthl_prim(dpthl); if(!(tmp=prepend_s(sdirs->currentdata, dpthl->path))) { log_and_send_oom(asfd, __func__); return -1; } if((dpthl->seco=get_highest_entry(tmp))<0) { // Could not open directory. Set zero. dpthl->seco=0; // mk_dpthl(dpthl, cconf); free(tmp); return 0; } free(tmp); mk_dpthl_seco(dpthl); if(!(tmp=prepend_s(sdirs->currentdata, dpthl->path))) { log_and_send_oom(asfd, __func__); return -1; } if((dpthl->tert=get_highest_entry(tmp))<0) { // Could not open directory. Set zero. dpthl->tert=0; // mk_dpthl(dpthl, cconf); free(tmp); return 0; } // At this point, we have the latest data file. Increment to get the // next free one. if(incr_dpthl(dpthl, cconf)) return -1; //logp("init_dpthl: %d/%d/%d\n", dpthl->prim, dpthl->seco, dpthl->tert); //logp("init_dpthl: %s\n", dpthl->path); return 0; }
int deleteme_move(struct sdirs *sdirs, const char *fullpath, const char *path, struct conf **cconfs) { int ret=-1; char *tmp=NULL; char *dest=NULL; int attempts=0; struct stat statp; char suffix[16]=""; char *timestamp=NULL; if(lstat(fullpath, &statp) && errno==ENOENT) { // The path to move aside does not exist. // Treat this as OK. ret=0; goto end; } if(!(tmp=prepend_s(sdirs->deleteme, path)) || mkpath(&tmp, sdirs->deleteme) || !(dest=prepend("", tmp))) goto end; // Try to generate destination paths if the desired one is already // taken. while(1) { if(lstat(dest, &statp)) break; snprintf(suffix, sizeof(suffix), ".%d", ++attempts); free_w(&dest); if(!(dest=prepend(tmp, suffix))) goto end; if(attempts>=100) break; // Give up. } // Paranoia - really do not want the deleteme directory to be loaded // as if it were a normal storage directory, so remove the timestamp. if(!(timestamp=prepend_s(fullpath, "timestamp"))) goto end; unlink(timestamp); // Possible race condition is of no consequence, as the destination // will need to be deleted at some point anyway. ret=do_rename(fullpath, dest); end: free_w(&dest); free_w(&tmp); free_w(×tamp); return ret; }
int compress_filename(const char *d, const char *file, const char *zfile, struct config *cconf) { char *fullfile=NULL; char *fullzfile=NULL; if(!(fullfile=prepend_s(d, file, strlen(file))) || !(fullzfile=prepend_s(d, zfile, strlen(zfile))) || compress_file(fullfile, fullzfile, cconf)) { if(fullfile) free(fullfile); if(fullzfile) free(fullzfile); return -1; } return 0; }
static int finish_delta(struct sdirs *sdirs, struct sbuf *rb) { int ret=0; char *deltmp=NULL; char *delpath=NULL; if(!(deltmp=prepend_s("deltas.forward", rb->burp1->datapth.buf)) || !(delpath=prepend_s(sdirs->working, deltmp)) || mkpath(&delpath, sdirs->working) || do_rename(sdirs->deltmppath, delpath)) ret=-1; if(delpath) free(delpath); if(deltmp) free(deltmp); return ret; }
static void add_hlnk(int find, const char *path, const char *link) { char *src; char *dst; fail_unless((src=prepend_s(fullpath, path))!=NULL); fail_unless((dst=prepend_s(fullpath, link))!=NULL); fail_unless(!do_link(dst, src, NULL, NULL, 0)); if(find==FOUND) { fail_unless(!strlist_add(&expected, src, (long)FT_LNK_H)); fail_unless(!strlist_add(&expected, dst, 0)); } free_w(&src); free_w(&dst); }
static int finish_delta(struct sbuf *rb, const char *working, const char *deltmppath) { int ret=0; char *deltmp=NULL; char *delpath=NULL; if(!(deltmp=prepend_s("deltas.forward", rb->datapth, strlen(rb->datapth))) || !(delpath=prepend_s(working, deltmp, strlen(deltmp))) || mkpath(&delpath, working) || do_rename(deltmppath, delpath)) ret=-1; if(delpath) free(delpath); if(deltmp) free(deltmp); return ret; }
int compress_filename(const char *d, const char *file, const char *zfile, int compression) { char *fullfile=NULL; char *fullzfile=NULL; if(!(fullfile=prepend_s(d, file)) || !(fullzfile=prepend_s(d, zfile)) || compress_file(fullfile, fullzfile, compression)) { free_w(&fullfile); free_w(&fullzfile); return -1; } return 0; }
static int browse_manifest_start(struct asfd *srfd, struct cstat *cstat, struct bu *bu, const char *browse, struct conf **confs) { int ret=-1; char *manifest=NULL; struct sbuf *sb=NULL; struct manio *manio=NULL; if(!(manifest=prepend_s(bu->path, cstat->protocol==PROTO_1?"manifest.gz":"manifest")) || !(manio=manio_alloc()) || manio_init_read(manio, manifest) || !(sb=sbuf_alloc_protocol(cstat->protocol))) goto end; manio_set_protocol(manio, cstat->protocol); if(get_int(confs[OPT_MONITOR_BROWSE_CACHE])) ret=cache_load(srfd, manio, sb, cstat, bu); else ret=do_browse_manifest(srfd, manio, sb, browse); end: free_w(&manifest); manio_free(&manio); sbuf_free(&sb); return ret; }
static char *get_next_fpath(struct manio *manio) { static char tmp[32]; if(manio->protocol==PROTO_1) return get_next_fpath_protocol1(manio); snprintf(tmp, sizeof(tmp), "%08"PRIX64, manio->offset.fcount++); return prepend_s(manio->directory, tmp); }
static char *set_new_datapth(struct sbuf *sb, const char *datadirtmp, struct dpth *dpth, int *istreedata, struct config *cconf) { char *rpath=NULL; if(cconf->directory_tree) *istreedata=treedata(sb); if(*istreedata) { // We want to place this file in a directory structure like // the directory structure on the original client. if(!(sb->datapth=prepend_s("t", sb->path, strlen(sb->path)))) { log_and_send_oom(__FUNCTION__); return NULL; } } else { mk_dpth(dpth, cconf, sb->cmd); if(!(sb->datapth=strdup(dpth->path))) // file data path { log_and_send_oom(__FUNCTION__); return NULL; } } if(build_path(datadirtmp, sb->datapth, strlen(sb->datapth), &rpath, datadirtmp)) { log_and_send("build path failed"); return NULL; } return rpath; }
static char *get_next_fpath(struct manio *manio) { static char tmp[32]; if(manio->protocol==PROTO_BURP1) return get_next_fpath_burp1(manio); snprintf(tmp, sizeof(tmp), "%08lX", manio->fcount++); return prepend_s(manio->directory, tmp); }
static char *set_new_datapth(struct asfd *asfd, struct sdirs *sdirs, struct conf **cconfs, struct sbuf *sb, struct dpth *dpth, int *istreedata) { char *tmp=NULL; char *rpath=NULL; if(get_int(cconfs[OPT_DIRECTORY_TREE])) *istreedata=treedata(sb, cconfs); if(*istreedata) { // We want to place this file in a directory structure like // the directory structure on the original client. if(!(tmp=prepend_s(TREE_DIR, sb->path.buf))) { log_and_send_oom(asfd, __func__); return NULL; } } else { if(!(tmp=strdup_w(dpth_protocol1_mk(dpth, get_int(cconfs[OPT_COMPRESSION]), sb->path.cmd), __func__))) return NULL; } iobuf_from_str(&sb->protocol1->datapth, CMD_DATAPTH, tmp); if(build_path(sdirs->datadirtmp, sb->protocol1->datapth.buf, &rpath, sdirs->datadirtmp)) { log_and_send(asfd, "build path failed"); return NULL; } return rpath; }
static int open_log(struct asfd *asfd, struct sdirs *sdirs, struct conf **cconfs) { int ret=-1; char *logpath=NULL; const char *peer_version=get_string(cconfs[OPT_PEER_VERSION]); if(!(logpath=prepend_s(sdirs->rworking, "log"))) goto end; if(log_fzp_set(logpath, cconfs)) { logp("could not open log file: %s\n", logpath); goto end; } logp("Client version: %s\n", peer_version?:""); logp("Protocol: %d\n", (int)get_protocol(cconfs)); if(get_int(cconfs[OPT_CLIENT_IS_WINDOWS])) logp("Client is Windows\n"); // Make sure a warning appears in the backup log. // The client will already have been sent a message with logw. // This time, prevent it sending a logw to the client by specifying // NULL for cntr. if(get_int(cconfs[OPT_VERSION_WARN])) version_warn(asfd, NULL, cconfs); ret=0; end: free_w(&logpath); return ret; }
static int incexc_matches(const char *fullrealwork, const char *incexc) { int ret=0; int got=0; struct fzp *fzp=NULL; char buf[4096]=""; const char *inc=NULL; char *old_incexc_path=NULL; if(!(old_incexc_path=prepend_s(fullrealwork, "incexc"))) return -1; if(!(fzp=fzp_open(old_incexc_path, "rb"))) { // Assume that no incexc file could be found because the client // was on an old version. Assume resume is OK and return 1. ret=1; goto end; } inc=incexc; while((got=fzp_read(fzp, buf, sizeof(buf)))>0) { if(strlen(inc)<(size_t)got) break; if(strncmp(buf, inc, got)) break; inc+=got; } if(inc && strlen(inc)) ret=0; else ret=1; end: fzp_close(&fzp); free_w(&old_incexc_path); return ret; }
static int finish_delta(struct sdirs *sdirs, struct sbuf *rb) { int ret=0; char *deltmp=NULL; char *delpath=NULL; if(!(deltmp=prepend_s("deltas.forward", rb->protocol1->datapth.buf)) || !(delpath=prepend_s(sdirs->working, deltmp)) || mkpath(&delpath, sdirs->working) // Rename race condition is of no consequence here, as delpath will // just get recreated. || do_rename(sdirs->deltmppath, delpath)) ret=-1; if(delpath) free(delpath); if(deltmp) free(deltmp); return ret; }
static struct fzp *open_backup_log(struct bu *bu, const char *logfile) { char *path=NULL; struct fzp *fzp=NULL; char logfilereal[32]=""; if(!strcmp(logfile, "backup")) snprintf(logfilereal, sizeof(logfilereal), "log"); else if(!strcmp(logfile, "restore")) snprintf(logfilereal, sizeof(logfilereal), "restorelog"); else if(!strcmp(logfile, "verify")) snprintf(logfilereal, sizeof(logfilereal), "verifylog"); else if(!strcmp(logfile, "backup_stats")) snprintf(logfilereal, sizeof(logfilereal), "backup_stats"); else if(!strcmp(logfile, "restore_stats")) snprintf(logfilereal, sizeof(logfilereal), "restore_stats"); else if(!strcmp(logfile, "verify_stats")) snprintf(logfilereal, sizeof(logfilereal), "verify_stats"); if(!(path=prepend_s(bu->path, logfilereal))) goto end; if(!(fzp=fzp_gzopen(path, "rb"))) { if(astrcat(&path, ".gz", __func__) || !(fzp=fzp_gzopen(path, "rb"))) goto end; } end: free_w(&path); return fzp; }
int check_for_rubble_burp2(struct asfd *asfd, struct sdirs *sdirs, const char *incexc, int *resume, struct conf *cconf) { // FIX THIS - currently just deletes the interrupted backup. ssize_t len=0; char *real=NULL; char lnk[32]=""; if((len=readlink(sdirs->working, lnk, sizeof(lnk)-1))<0) return 0; else if(!len) { unlink(sdirs->working); return 0; } lnk[len]='\0'; if(!(real=prepend_s(sdirs->client, lnk))) { log_and_send_oom(asfd, __func__); return -1; } if(recursive_delete(real, "", 1)) { char msg[256]=""; snprintf(msg, sizeof(msg), "Could not remove interrupted directory: %s", real); log_and_send(asfd, msg); return -1; } unlink(sdirs->working); return 0; }
int bu_init(struct bu *bu, char *fullpath, char *basename, char *timestampstr, uint16_t flags) { if(!(bu->data=prepend_s(fullpath, "data")) || !(bu->delta=prepend_s(fullpath, "deltas.reverse"))) goto error; bu->path=fullpath; bu->basename=basename; bu->timestamp=timestampstr; bu->flags=flags; bu->bno=strtoul(timestampstr, NULL, 10); return 0; error: free_w(&bu->data); free_w(&bu->delta); return -1; }
int cstat_init(struct cstat *cstat, const char *name, const char *clientconfdir) { if((clientconfdir && !(cstat->conffile=prepend_s(clientconfdir, name))) || !(cstat->name=strdup_w(name, __func__))) return -1; return 0; }
static void add_nostat(int find, const char *path) { char *tmp; fail_unless((tmp=prepend_s(fullpath, path))!=NULL); if(find==FOUND) fail_unless(!strlist_add(&expected, tmp, (long)FT_NOSTAT)); free_w(&tmp); }
static int get_logpaths(struct bu *bu, const char *file, char **logpath, char **logpathz) { if(!(*logpath=prepend_s(bu->path, file)) || !(*logpathz=prepend(*logpath, ".gz"))) return -1; return 0; }
static char *deleteme_get_path(const char *basedir, struct conf **cconfs) { static char *deleteme=NULL; char *manual_delete=get_string(cconfs[OPT_MANUAL_DELETE]); free_w(&deleteme); if(manual_delete) return manual_delete; return prepend_s(basedir, "deleteme"); }
static char *get_next_fpath(struct manio *manio, man_off_t *offset) { static char tmp[32]; if(is_single_file(manio)) return strdup_w(manio->manifest, __func__); snprintf(tmp, sizeof(tmp), "%08"PRIX64, offset->fcount++); return prepend_s(manio->manifest, tmp); }
static void add_node(int find, const char *path, mode_t mode, long ftype) { char *tmp; fail_unless((tmp=prepend_s(fullpath, path))!=NULL); fail_unless(!mknod(tmp, mode, 100)); if(find==FOUND) fail_unless(!strlist_add(&expected, tmp, ftype)); free_w(&tmp); }
static void add_file(int find, const char *path, size_t s) { char *tmp; fail_unless((tmp=prepend_s(fullpath, path))!=NULL); create_file(tmp, s); if(find==FOUND) fail_unless(!strlist_add(&expected, tmp, (long)FT_REG)); free_w(&tmp); }
static int receive_file(struct asfd *asfd, const char *autoupgrade_dir, const char *file, struct conf *conf) { int ret=0; char *incoming=NULL; if(!(incoming=prepend_s(autoupgrade_dir, file))) return -1; ret=receive_a_file(asfd, incoming, conf); if(incoming) free(incoming); return ret; }
int readlink_w_in_dir(const char *dir, const char *lnk, char buf[], size_t buflen) { char *tmp=NULL; if(!(tmp=prepend_s(dir, lnk))) return -1; readlink_w(tmp, buf, buflen); free_w(&tmp); return 0; }
int build_path(const char *datadir, const char *fname, char **rpath, const char *limit) { //logp("build path: '%s/%s'\n", datadir, fname); if(!(*rpath=prepend_s(datadir, fname))) return -1; if(mkpath(rpath, limit)) { free_w(rpath); return -1; } return 0; }