Exemple #1
0
// Also used by restore.c.
// FIX THIS: This stuff is very similar to make_rev_delta, can maybe share
// some code.
int do_patch(struct asfd *asfd, const char *dst, const char *del,
	const char *upd, bool gzupd, int compression)
{
	struct fzp *dstp=NULL;
	struct fzp *delfzp=NULL;
	struct fzp *upfzp=NULL;
	rs_result result=RS_IO_ERROR;

	if(!(dstp=fzp_open(dst, "rb"))) goto end;

	if(!(delfzp=fzp_gzopen(del, "rb")))
		goto end;

	if(gzupd)
		upfzp=fzp_gzopen(upd, comp_level(compression));
	else
		upfzp=fzp_open(upd, "wb");

	if(!upfzp) goto end;

	result=rs_patch_gzfile(dstp, delfzp, upfzp);
end:
	fzp_close(&dstp);
	fzp_close(&delfzp);
	if(fzp_close(&upfzp))
	{
		logp("error closing %s in %s\n", upd, __func__);
		result=RS_IO_ERROR;
	}
	return result;
}
Exemple #2
0
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;

}
Exemple #3
0
static int make_rev_delta(const char *src, const char *sig, const char *del,
	int compression, struct conf **cconfs)
{
	int ret=-1;
	rs_result result;
	struct fzp *srcfzp=NULL;
	struct fzp *delfzp=NULL;
	struct fzp *sigp=NULL;
	rs_signature_t *sumset=NULL;

//logp("make rev delta: %s %s %s\n", src, sig, del);
	if(!(sigp=fzp_open(sig, "rb"))) goto end;

	if((result=rs_loadsig_fzp(sigp, &sumset))!=RS_DONE)
	{
		logp("rs_loadsig_fzp returned %d %s\n",
			result, rs_strerror(result));
		goto end;
	}
	if((result=rs_build_hash_table(sumset))!=RS_DONE)
	{
		logp("rs_build_hash_table returned %d %s\n",
			result, rs_strerror(result));
		goto end;
	}

//logp("make rev deltb: %s %s %s\n", src, sig, del);

	if(dpth_protocol1_is_compressed(compression, src))
		srcfzp=fzp_gzopen(src, "rb");
	else
		srcfzp=fzp_open(src, "rb");

	if(!srcfzp) goto end;

	if(get_int(cconfs[OPT_COMPRESSION]))
		delfzp=fzp_gzopen(del,
			comp_level(get_int(cconfs[OPT_COMPRESSION])));
	else
		delfzp=fzp_open(del, "wb");
	if(!delfzp) goto end;

	if((result=rs_delta_gzfile(sumset, srcfzp, delfzp))!=RS_DONE)
	{
		logp("rs_delta_gzfile returned %d %s\n",
			result, rs_strerror(result));
		goto end;
	}
	ret=0;
end:
	if(sumset) rs_free_sumset(sumset);
	fzp_close(&srcfzp);
	fzp_close(&sigp);
	if(fzp_close(&delfzp))
	{
		logp("error closing delfzp %s in %s\n", del, __func__);
		ret=-1;
	}
	return ret;
}
Exemple #4
0
static int bcompress(const char *src, const char *dst, int compression)
{
	int res;
	int got;
	struct fzp *sfzp=NULL;
	struct fzp *dfzp=NULL;
	char buf[ZCHUNK];

	if(!(sfzp=fzp_open(src, "rb"))
	  || !(dfzp=fzp_gzopen(dst, comp_level(compression))))
		goto error;
	while((got=fzp_read(sfzp, buf, sizeof(buf)))>0)
	{
		res=fzp_write(dfzp, buf, got);
		if(res!=got)
		{
			logp("compressing %s - read %d but wrote %d\n",
				src, got, res);
			goto error;
		}
	}
	fzp_close(&sfzp);
	return fzp_close(&dfzp);
error:
	fzp_close(&sfzp);
	fzp_close(&dfzp);
	return -1;
}
Exemple #5
0
int run_bsigs(int argc, char *argv[])
{
	int ret=1;
	fzp *fzp=NULL;
	struct iobuf rbuf;
	struct blk blk;
	memset(&rbuf, 0, sizeof(struct iobuf));

	if(argc!=2)
		return usage();
	path=argv[1];

	if(!(fzp=fzp_gzopen(path, "rb")))
		goto end;
	while(1)
	{
		iobuf_free_content(&rbuf);
		switch(iobuf_fill_from_fzp(&rbuf, fzp))
		{
			case 1: ret=0; // Finished OK.
			case -1: goto end; // Error.
		}

		if(parse_cmd(&rbuf, &blk)) goto end;
	}

end:
	iobuf_free_content(&rbuf);
	fzp_close(&fzp);
	return ret;
}
Exemple #6
0
static int manio_open_next_fpath(struct manio *manio)
{
	static struct stat statp;

	free_w(&manio->offset->fpath);
	if(!(manio->offset->fpath=get_next_fpath(manio, manio->offset)))
		return -1;

	if(!strcmp(manio->mode, MANIO_MODE_READ)
	  && lstat(manio->offset->fpath, &statp))
		return 0;

	if(build_path_w(manio->offset->fpath))
		return -1;
	switch(manio->phase)
	{
		case 2:
			if(!(manio->fzp=fzp_open(manio->offset->fpath,
				manio->mode))) return -1;
			return 0;
		case 1:
		case 3:
		default:
			if(!(manio->fzp=fzp_gzopen(manio->offset->fpath,
				manio->mode))) return -1;
			return 0;
	}
}
Exemple #7
0
static void check_dindex(int i)
{
	int ret;
	struct fzp *fzp;
	const char *p;
	struct iobuf rbuf;
	int lines=0;
	struct blk blk;
	uint64_t last_savepath=0;

	p=get_extra_path(i, "dindex");
	memset(&rbuf, 0, sizeof(rbuf));

	fail_unless((fzp=fzp_gzopen(p, "rb"))!=NULL);
	while(!(ret=iobuf_fill_from_fzp(&rbuf, fzp)))
	{
		lines++;
		switch(rbuf.cmd)
		{
			case CMD_SAVE_PATH:
				blk_set_from_iobuf_savepath(&blk, &rbuf);
				fail_unless(blk.savepath>last_savepath);
				last_savepath=blk.savepath;
				break;
			default:
				fail_unless(0==1);
				break;
		}
		iobuf_free_content(&rbuf);
	}
	fail_unless(ret==1);
	fail_unless(lines>500);
	fail_unless(!fzp_close(&fzp));
}
Exemple #8
0
static int make_rev_sig(const char *dst, const char *sig, const char *endfile,
	int compression, struct conf **confs)
{
	int ret=-1;
	struct fzp *dstfzp=NULL;
	struct fzp *sigp=NULL;
//logp("make rev sig: %s %s\n", dst, sig);

	if(dpth_protocol1_is_compressed(compression, dst))
		dstfzp=fzp_gzopen(dst, "rb");
	else
		dstfzp=fzp_open(dst, "rb");

	if(!dstfzp
	  || !(sigp=fzp_open(sig, "wb"))
	  || rs_sig_gzfile(dstfzp, sigp,
		get_librsync_block_len(endfile),
		RS_DEFAULT_STRONG_LEN, confs)!=RS_DONE)
			goto end;
	ret=0;
end:
//logp("end of make rev sig\n");
	fzp_close(&dstfzp);
	if(fzp_close(&sigp))
	{
		logp("error closing %s in %s\n", sig, __func__);
		return -1;
	}
	return ret;
}
Exemple #9
0
int manio_seek(struct manio *manio, man_off_t *offset)
{
	fzp_close(&manio->fzp);
	man_off_t_memcpy(&manio->offset, offset);
	if(!(manio->fzp=fzp_gzopen(manio->offset.fpath, manio->mode)))
		return -1;
	return fzp_seek(manio->fzp, manio->offset.offset, SEEK_SET);
}
Exemple #10
0
static void assert_file_content(const char *path, const char *content)
{
	size_t got;
	struct fzp *fp;
	size_t len=strlen(content);
	char buf[256]="";
	fail_unless((fp=fzp_gzopen(path, "rb"))!=NULL);
	got=fzp_read(fp, buf, len);
	fail_unless(len==got);
	fail_unless(!strcmp(buf, content));
	fzp_close(&fp);
}
Exemple #11
0
// Open the previous (current) manifest.
// If the split_vss setting changed between the previous backup and the new
// backup, do not open the previous manifest. This will have the effect of
// making the client back up everything fresh. Need to do this, otherwise
// toggling split_vss on and off will result in backups that do not work.
static int open_previous_manifest(struct fzp **cmanfp,
	struct sdirs *sdirs, const char *incexc, struct conf **cconfs)
{
	struct stat statp;
	if(!lstat(sdirs->cmanifest, &statp)
	  && !vss_opts_changed(sdirs, cconfs, incexc)
	  && !(*cmanfp=fzp_gzopen(sdirs->cmanifest, "rb")))
	{
		logp("could not open old manifest %s\n", sdirs->cmanifest);
		return -1;
	}
	return 0;
}
Exemple #12
0
int manio_seek(struct manio *manio, man_off_t *offset)
{
	fzp_close(&manio->fzp);
	if(!(manio->fzp=fzp_gzopen(offset->fpath, manio->mode))
	  || fzp_seek(manio->fzp, offset->offset, SEEK_SET))
		return -1;
	man_off_t_free_content(manio->offset);
	if(!(manio->offset->fpath=strdup_w(offset->fpath, __func__)))
		return -1;
	manio->offset->offset=offset->offset;
	manio->offset->fcount=offset->fcount;
	return 0;
}
Exemple #13
0
int zlib_inflate(struct asfd *asfd, const char *source_path,
	const char *dest_path, struct conf **confs)
{
	int ret=-1;
	size_t b=0;
	uint8_t in[ZCHUNK];
	struct fzp *src=NULL;
	struct fzp *dst=NULL;

	if(!(src=fzp_gzopen(source_path, "rb")))
	{
		logw(asfd, confs, "could not gzopen %s in %s: %s\n",
			source_path, __func__, strerror(errno));
		goto end;
	}
	if(!(dst=fzp_open(dest_path, "wb")))
	{
		logw(asfd, confs, "could not open %s in %s: %s\n",
			dest_path, __func__, strerror(errno));
		goto end;
	}

	while((b=fzp_read(src, in, ZCHUNK))>0)
	{
		if(fzp_write(dst, in, b)!=b)
		{
			logw(asfd, confs,
				"error when writing to %s\n", dest_path);
			goto end;
		}
	}
	if(!fzp_eof(src))
	{
		logw(asfd, confs,
			"error while reading %s in %s\n",
				source_path, __func__);
		goto end;
	}
	if(fzp_close(&dst))
	{
		logw(asfd, confs,
			"error when closing %s in %s: %s\n",
				dest_path, __func__, strerror(errno));
		goto end;
	}
	ret=0;
end:
	fzp_close(&src);
	fzp_close(&dst);
	return ret;
}
Exemple #14
0
END_TEST

#define FULL_CHUNK	4096

static void do_assert_files_equal(const char *opath, const char *npath,
                                  int compressed)
{
    size_t ogot;
    size_t ngot;
    unsigned int i=0;
    struct fzp *ofp;
    struct fzp *nfp;
    static char obuf[FULL_CHUNK];
    static char nbuf[FULL_CHUNK];

    if(compressed)
    {
        fail_unless((ofp=fzp_gzopen(opath, "rb"))!=NULL);
        fail_unless((nfp=fzp_gzopen(npath, "rb"))!=NULL);
    }
    else
    {
        fail_unless((ofp=fzp_open(opath, "rb"))!=NULL);
        fail_unless((nfp=fzp_open(npath, "rb"))!=NULL);
    }

    while(1)
    {
        ogot=fzp_read(ofp, obuf, FULL_CHUNK);
        ngot=fzp_read(nfp, nbuf, FULL_CHUNK);
        fail_unless(ogot==ngot);
        for(i=0; i<ogot; i++)
            fail_unless(obuf[i]==nbuf[i]);
        if(ogot<FULL_CHUNK) break;
    }
    fzp_close(&ofp);
    fzp_close(&nfp);
}
Exemple #15
0
int manio_open_next_fpath(struct manio *manio)
{
	static struct stat statp;

	if(!(manio->offset.fpath=get_next_fpath(manio))) return -1;

	if(!strcmp(manio->mode, MANIO_MODE_READ)
	  && lstat(manio->offset.fpath, &statp))
		return 0;

	if(build_path_w(manio->offset.fpath)
	  || !(manio->fzp=fzp_gzopen(manio->offset.fpath, manio->mode)))
		return -1;
	return 0;
}
Exemple #16
0
static int setup_cntr(struct asfd *asfd, const char *manifest,
        regex_t *regex, int srestore,
        enum action act, char status, struct conf **cconfs)
{
	int ars=0;
	int ret=-1;
	struct fzp *fzp=NULL;
	struct sbuf *sb=NULL;
	struct cntr *cntr=get_cntr(cconfs);

// FIX THIS: this is only trying to work for protocol1.
	if(get_protocol(cconfs)!=PROTO_1) return 0;

	if(!(sb=sbuf_alloc(PROTO_1))) goto end;
	if(!(fzp=fzp_gzopen(manifest, "rb")))
	{
		log_and_send(asfd, "could not open manifest");
		goto end;
	}
	while(1)
	{
		if((ars=sbuf_fill_from_file(sb, fzp, NULL, NULL)))
		{
			if(ars<0) goto end;
			// ars==1 means end ok
			break;
		}
		else
		{
			if(want_to_restore(srestore, sb, regex, cconfs))
			{
				cntr_add_phase1(cntr, sb->path.cmd, 0);
				if(sb->endfile.buf)
				  cntr_add_val(cntr,
					CMD_BYTES_ESTIMATED,
					strtoull(sb->endfile.buf,
						NULL, 10), 0);
			}
		}
		sbuf_free_content(sb);
	}
	ret=0;
end:
	sbuf_free(&sb);
	fzp_close(&fzp);
	return ret;
}
Exemple #17
0
static int start_to_receive_delta(struct sdirs *sdirs, struct conf **cconfs,
	struct sbuf *rb)
{
	if(rb->compression)
	{
		if(!(rb->protocol1->fzp=fzp_gzopen(sdirs->deltmppath,
			comp_level(rb->compression))))
				return -1;
	}
	else
	{
		if(!(rb->protocol1->fzp=fzp_open(sdirs->deltmppath, "wb")))
			return -1;
	}
	rb->flags |= SBUF_RECV_DELTA;

	return 0;
}
Exemple #18
0
static int start_to_receive_delta(struct sdirs *sdirs, struct conf **cconfs,
	struct sbuf *rb)
{
	if(get_int(cconfs[OPT_COMPRESSION]))
	{
		if(!(rb->protocol1->fzp=fzp_gzopen(sdirs->deltmppath,
			comp_level(cconfs))))
				return -1;
	}
	else
	{
		if(!(rb->protocol1->fzp=fzp_open(sdirs->deltmppath, "wb")))
			return -1;
	}
	rb->flags |= SBUFL_RECV_DELTA;

	return 0;
}
Exemple #19
0
static void check_hooks(int i, int fcount)
{
	int ret;
	struct fzp *fzp;
	const char *p;
	struct iobuf rbuf;
	struct blk blk;
	int lines=0;
	uint64_t last_fingerprint=0;
	char manifest_line[64]="";

	p=get_extra_path(i, "hooks");
	memset(&rbuf, 0, sizeof(rbuf));
	snprintf(manifest_line, sizeof(manifest_line),
		"%s/%08X", RMANIFEST_RELATIVE, i);

	fail_unless((fzp=fzp_gzopen(p, "rb"))!=NULL);
	while(!(ret=iobuf_fill_from_fzp(&rbuf, fzp)))
	{
		lines++;
		switch(rbuf.cmd)
		{
			case CMD_MANIFEST:
				fail_unless(lines==1);
				ck_assert_str_eq(manifest_line, rbuf.buf);
				break;
			case CMD_FINGERPRINT:
				blk_set_from_iobuf_fingerprint(&blk, &rbuf);
				fail_unless(blk.fingerprint>last_fingerprint);
				last_fingerprint=blk.fingerprint;
				break;
			default:
				fail_unless(0==1);
				break;
		}
		iobuf_free_content(&rbuf);
	}
	fail_unless(ret==1);
	if(i<fcount-1)
		fail_unless(lines>200);
	else
		fail_unless(lines>10); // Last file will have fewer entries.
	fail_unless(!fzp_close(&fzp));
}
Exemple #20
0
static int sort_and_write_dindex(struct manio *manio)
{
	int i;
	int ret=-1;
	struct fzp *fzp=NULL;
	char msg[32]="";
	char *path=NULL;
	struct iobuf wbuf;
	struct blk blk;
	int dindex_count=manio->dindex_count;
	uint64_t *dindex_sort=manio->dindex_sort;
	if(!dindex_sort) return 0;

	snprintf(msg, sizeof(msg), "%08"PRIX64, manio->offset->fcount-1);
	if(!(path=prepend_s(manio->dindex_dir, msg))
	  || build_path_w(path)
	  || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE)))
		goto end;

	qsort(dindex_sort, dindex_count, sizeof(uint64_t), uint64_t_sort);

	for(i=0; i<dindex_count; i++)
	{
		// Do not bother with duplicates.
		if(i && dindex_sort[i]==dindex_sort[i-1])
			continue;

		blk.savepath=dindex_sort[i];
		blk_to_iobuf_savepath(&blk, &wbuf);
		if(iobuf_send_msg_fzp(&wbuf, fzp)) return -1;
	}
	if(fzp_close(&fzp))
	{
		logp("Error closing %s in %s: %s\n",
			path, __func__, strerror(errno));
		goto end;
	}
	manio->dindex_count=0;
	ret=0;
end:
	fzp_close(&fzp);
	free_w(&path);
	return ret;
}
Exemple #21
0
void build_sparse_index(const char *path, int manifests, int fingerprints)
{
	struct fzp *fzp;

	fail_unless(!build_path_w(path));

	fail_unless((fzp=fzp_gzopen(path, "wb"))!=NULL);
	for(int m=0; m<manifests; m++)
	{
		char mpath[256];
		snprintf(mpath, sizeof(mpath), "some/manifest/%d", m);
		fzp_printf(fzp, "%c%04lX%s\n",
			CMD_MANIFEST, strlen(mpath), mpath);

		for(int f=0; f<fingerprints; f++)
			fail_unless(!to_fzp_fingerprint(fzp, prng_next64()));
	}
	fail_unless(!fzp_close(&fzp));
}
Exemple #22
0
static int sort_and_write_hooks(struct manio *manio)
{
	int i;
	int ret=-1;
	struct fzp *fzp=NULL;
	char msg[32]="";
	char *path=NULL;
	int hook_count=manio->hook_count;
	uint64_t *hook_sort=manio->hook_sort;
	if(!hook_sort) return 0;

	snprintf(msg, sizeof(msg), "%08"PRIX64, manio->offset->fcount-1);
	if(!(path=prepend_s(manio->hook_dir, msg))
	  || build_path_w(path)
	  || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE)))
		goto end;

	qsort(hook_sort, hook_count, sizeof(uint64_t), uint64_t_sort);

	if(write_hook_header(fzp, manio->rmanifest, msg)) goto end;
	for(i=0; i<hook_count; i++)
	{
		// Do not bother with duplicates.
		if(i && hook_sort[i]==hook_sort[i-1])
			continue;

		if(to_fzp_fingerprint(fzp, hook_sort[i]))
			goto end;
	}
	if(fzp_close(&fzp))
	{
		logp("Error closing %s in %s: %s\n",
			path, __func__, strerror(errno));
		goto end;
	}
	if(manio_write_fcount(manio)) goto end;
	manio->hook_count=0;
	ret=0;
end:
	fzp_close(&fzp);
	free_w(&path);
	return ret;
}
Exemple #23
0
static int sort_and_write_hooks(struct manio *manio)
{
	int i;
	int ret=-1;
	struct fzp *fzp=NULL;
	char comp[32]="";
	char *path=NULL;
	int hook_count=manio->hook_count;
	char **hook_sort=manio->hook_sort;
	if(!hook_sort) return 0;

	snprintf(comp, sizeof(comp), "%08"PRIX64, manio->offset.fcount-1);
	if(!(path=prepend_s(manio->hook_dir, comp))
	  || build_path_w(path)
	  || !(fzp=fzp_gzopen(path, manio->mode)))
		goto end;

	qsort(hook_sort, hook_count, sizeof(char *), strsort);

	if(write_hook_header(manio, fzp, comp)) goto end;
	for(i=0; i<hook_count; i++)
	{
		// Do not bother with duplicates.
		if(i && !strcmp(hook_sort[i],
			hook_sort[i-1])) continue;
		fzp_printf(fzp, "%c%04X%s\n", CMD_FINGERPRINT,
			(unsigned int)strlen(hook_sort[i]), hook_sort[i]);
	}
	if(fzp_close(&fzp))
	{
		logp("Error closing %s in %s: %s\n",
			path, __func__, strerror(errno));
		goto end;
	}
	if(manio_write_fcount(manio)) goto end;
	manio->hook_count=0;
	ret=0;
end:
	fzp_close(&fzp);
	free_w(&path);
	return ret;
}
Exemple #24
0
END_TEST

START_TEST(test_protocol1_verify_file_gzip_read_failure)
{
	struct asfd *asfd;
	struct cntr *cntr;
	struct sbuf *sb;
	const char *path="somepath";
	const char *datapth="/datapth";
	const char *endfile="0:0";
	const char *best=BASE "/existent";
	const char *plain_text="some plain text";
	size_t s;
	struct fzp *fzp;
	s=strlen(plain_text);

	clean();
	cntr=setup_cntr();
	sb=setup_sbuf(path, datapth, endfile, 1/*compression*/);

	// Make a corrupt gzipped file.
	build_path_w(best);
	fail_unless((fzp=fzp_gzopen(best, "wb"))!=NULL);
	fail_unless(fzp_write(fzp, plain_text, s)==s);
	fail_unless(!fzp_close(&fzp));
	fail_unless((fzp=fzp_open(best, "r+b"))!=NULL);
	fail_unless(!fzp_seek(fzp, 10, SEEK_SET));
	fail_unless(fzp_write(fzp, "aa", 2)==2);
	fail_unless(!fzp_close(&fzp));

	asfd=asfd_mock_setup(&areads, &awrites);
	setup_error_while_reading(asfd, best);

	// Returns 0 so that the parent process continues.
	fail_unless(!verify_file(asfd, sb, 0 /*patches*/, best, cntr));
	fail_unless(cntr->ent[CMD_WARNING]->count==1);
	tear_down(&sb, &cntr, NULL, &asfd);
}
Exemple #25
0
static int verify_file(struct asfd *asfd, struct sbuf *sb,
	int patches, const char *best,
	uint64_t *bytes, struct cntr *cntr)
{
	MD5_CTX md5;
	size_t b=0;
	const char *cp=NULL;
	const char *newsum=NULL;
	uint8_t in[ZCHUNK];
	uint8_t checksum[MD5_DIGEST_LENGTH];
	uint64_t cbytes=0;
	struct fzp *fzp=NULL;

	if(!(cp=strrchr(sb->endfile.buf, ':')))
	{
		logw(asfd, cntr,
			"%s has no md5sum!\n", sb->protocol1->datapth.buf);
		return 0;
	}
	cp++;
	if(!MD5_Init(&md5))
	{
		logp("MD5_Init() failed\n");
		return -1;
	}
	if(patches
	  || sb->path.cmd==CMD_ENC_FILE
	  || sb->path.cmd==CMD_ENC_METADATA
	  || sb->path.cmd==CMD_EFS_FILE
	  || sb->path.cmd==CMD_ENC_VSS
	  || (!patches && !dpth_protocol1_is_compressed(sb->compression, best)))
		fzp=fzp_open(best, "rb");
	else
		fzp=fzp_gzopen(best, "rb");

	if(!fzp)
	{
		logw(asfd, cntr, "could not open %s\n", best);
		return 0;
	}
	while((b=fzp_read(fzp, in, ZCHUNK))>0)
	{
		cbytes+=b;
		if(!MD5_Update(&md5, in, b))
		{
			logp("MD5_Update() failed\n");
			fzp_close(&fzp);
			return -1;
		}
	}
	if(!fzp_eof(fzp))
	{
		logw(asfd, cntr, "error while reading %s\n", best);
		fzp_close(&fzp);
		return 0;
	}
	fzp_close(&fzp);
	if(!MD5_Final(checksum, &md5))
	{
		logp("MD5_Final() failed\n");
		return -1;
	}
	newsum=bytes_to_md5str(checksum);

	if(strcmp(newsum, cp))
	{
		logp("%s %s\n", newsum, cp);
		logw(asfd, cntr, "md5sum for '%s (%s)' did not match!\n",
			sb->path.buf, sb->protocol1->datapth.buf);
		logp("md5sum for '%s (%s)' did not match!\n",
			sb->path.buf, sb->protocol1->datapth.buf);
		return 0;
	}
	*bytes+=cbytes;

	// Just send the file name to the client, so that it can show cntr.
	if(asfd->write(asfd, &sb->path)) return -1;
	return 0;
}
Exemple #26
0
/* Merge two files of sorted dindexes into each other. */
int merge_dindexes(const char *dst, const char *srca, const char *srcb)
{
	int ret=-1;
	struct sbuf *asb=NULL;
	struct sbuf *bsb=NULL;
	struct fzp *azp=NULL;
	struct fzp *bzp=NULL;
	struct fzp *dzp=NULL;
	uint64_t *anew=NULL;
	uint64_t *bnew=NULL;

	if(!(asb=sbuf_alloc(PROTO_2))
	  || (srcb && !(bsb=sbuf_alloc(PROTO_2))))
		goto end;
	if(build_path_w(dst))
		goto end;
	if((srca && !(azp=fzp_gzopen(srca, "rb")))
	  || (srcb && !(bzp=fzp_gzopen(srcb, "rb")))
	  || !(dzp=fzp_gzopen(dst, "wb")))
		goto end;

	while(azp || bzp || anew || bnew)
	{
		if(azp
		  && asb
		  && !anew)
		{
			switch(get_next_dindex(&anew, asb, azp))
			{
				case -1: goto end;
				case 1: fzp_close(&azp); // Finished OK.
			}
		}

		if(bzp
		  && bsb
		  && !bnew)
		{
			switch(get_next_dindex(&bnew, bsb, bzp))
			{
				case -1: goto end;
				case 1: fzp_close(&bzp); // Finished OK.
			}
		}

		if(anew && !bnew)
		{
			if(gzprintf_dindex(dzp, anew)) goto end;
			free_v((void **)&anew);
		}
		else if(!anew && bnew)
		{
			if(gzprintf_dindex(dzp, bnew)) goto end;
			free_v((void **)&bnew);
		}
		else if(!anew && !bnew)
		{
			continue;
		}
		else if(*anew==*bnew)
		{
			// They were the same - write the new one.
			if(gzprintf_dindex(dzp, bnew)) goto end;
			free_v((void **)&anew);
			free_v((void **)&bnew);
		}
		else if(*anew<*bnew)
		{
			if(gzprintf_dindex(dzp, anew)) goto end;
			free_v((void **)&anew);
		}
		else
		{
			if(gzprintf_dindex(dzp, bnew)) goto end;
			free_v((void **)&bnew);
		}
	}

	if(fzp_close(&dzp))
	{
		logp("Error closing %s in %s\n", tmpfile, __func__);
		goto end;
	}

	ret=0;
end:
	fzp_close(&azp);
	fzp_close(&bzp);
	fzp_close(&dzp);
	sbuf_free(&asb);
	sbuf_free(&bsb);
	free_v((void **)&anew);
	free_v((void **)&bnew);
	return ret;
}
Exemple #27
0
static
#endif
int merge_sparse_indexes(const char *dst, const char *srca, const char *srcb)
{
	int fcmp;
	int ret=-1;
	struct sbuf *asb=NULL;
	struct sbuf *bsb=NULL;
	uint64_t *afingerprints=NULL;
	uint64_t *bfingerprints=NULL;
	size_t aflen=0;
	size_t bflen=0;
	struct fzp *azp=NULL;
	struct fzp *bzp=NULL;
	struct fzp *dzp=NULL;
	struct hooks *anew=NULL;
	struct hooks *bnew=NULL;
	char *apath=NULL;
	char *bpath=NULL;

	if(!(asb=sbuf_alloc(PROTO_2))
	  || (srcb && !(bsb=sbuf_alloc(PROTO_2))))
		goto end;
	if(build_path_w(dst))
		goto end;
	if((srca && !(azp=fzp_gzopen(srca, "rb")))
	  || (srcb && !(bzp=fzp_gzopen(srcb, "rb")))
	  || !(dzp=fzp_gzopen(dst, "wb")))
		goto end;

	while(azp || bzp || anew || bnew)
	{
		if(azp
		  && asb
		  && !anew)
		{
			switch(get_next_set_of_hooks(&anew, asb, azp,
				&apath, &afingerprints, &aflen))
			{
				case -1: goto end;
				case 1: fzp_close(&azp); // Finished OK.
			}
		}

		if(bzp
		  && bsb
		  && !bnew)
		{
			switch(get_next_set_of_hooks(&bnew, bsb, bzp,
				&bpath, &bfingerprints, &bflen))
			{
				case -1: goto end;
				case 1: fzp_close(&bzp); // Finished OK.
			}
		}

		if(anew && !bnew)
		{
			if(gzprintf_hooks(dzp, anew)) goto end;
			hooks_free(&anew);
		}
		else if(!anew && bnew)
		{
			if(gzprintf_hooks(dzp, bnew)) goto end;
			hooks_free(&bnew);
		}
		else if(!anew && !bnew)
		{
			continue;
		}
		else if(!(fcmp=hookscmp(anew, bnew)))
		{
			// They were the same - write the new one.
			if(gzprintf_hooks(dzp, bnew)) goto end;
			hooks_free(&anew);
			hooks_free(&bnew);
		}
		else if(fcmp<0)
		{
			if(gzprintf_hooks(dzp, anew)) goto end;
			hooks_free(&anew);
		}
		else
		{
			if(gzprintf_hooks(dzp, bnew)) goto end;
			hooks_free(&bnew);
		}
	}

	if(fzp_close(&dzp))
	{
		logp("Error closing %s in %s\n", tmpfile, __func__);
		goto end;
	}

	ret=0;
end:
	fzp_close(&azp);
	fzp_close(&bzp);
	fzp_close(&dzp);
	sbuf_free(&asb);
	sbuf_free(&bsb);
	hooks_free(&anew);
	hooks_free(&bnew);
	free_v((void **)&afingerprints);
	free_v((void **)&bfingerprints);
	free_w(&apath);
	free_w(&bpath);
	return ret;
}
Exemple #28
0
/* Need to make all the stuff that this does atomic so that existing backups
   never get broken, even if somebody turns the power off on the server. */
static int atomic_data_jiggle(struct sdirs *sdirs, struct fdirs *fdirs,
	int hardlinked_current, struct conf **cconfs)
{
	int ret=-1;
	char *datapth=NULL;
	char *tmpman=NULL;
	struct stat statp;

	char *deltabdir=NULL;
	char *deltafdir=NULL;
	char *sigpath=NULL;
	struct fzp *zp=NULL;
	struct sbuf *sb=NULL;

	struct fzp *delfp=NULL;

	logp("Doing the atomic data jiggle...\n");

	if(!(tmpman=get_tmp_filename(fdirs->manifest)))
		goto error;
	if(lstat(fdirs->manifest, &statp))
	{
		// Manifest does not exist - maybe the server was killed before
		// it could be renamed.
		logp("%s did not exist - trying %s\n", fdirs->manifest, tmpman);
		// Rename race condition is of no consequence, because manifest
		// already does not exist.
		do_rename(tmpman, fdirs->manifest);
	}
	if(!(zp=fzp_gzopen(fdirs->manifest, "rb")))
		goto error;

	if(!(deltabdir=prepend_s(fdirs->currentdup, "deltas.reverse"))
	  || !(deltafdir=prepend_s(sdirs->finishing, "deltas.forward"))
	  || !(sigpath=prepend_s(fdirs->currentdup, "sig.tmp"))
	  || !(sb=sbuf_alloc(PROTO_1)))
	{
		log_out_of_memory(__func__);
		goto error;
	}

	mkdir(fdirs->datadir, 0777);

	while(1)
	{
		switch(sbuf_fill_from_file(sb, zp, NULL, NULL))
		{
			case 0: break;
			case 1: goto end;
			default: goto error;
		}
		if(sb->protocol1->datapth.buf)
		{
			if(write_status(CNTR_STATUS_SHUFFLING,
				sb->protocol1->datapth.buf, get_cntr(cconfs))
			  || jiggle(sdirs, fdirs, sb, hardlinked_current,
				deltabdir, deltafdir,
				sigpath, &delfp, cconfs))
					goto error;
		}
		sbuf_free_content(sb);
	}

end:
	if(fzp_close(&delfp))
	{
		logp("error closing %s in atomic_data_jiggle\n",
			fdirs->deletionsfile);
		goto error;
	}

	if(maybe_delete_files_from_manifest(tmpman, fdirs, cconfs))
		goto error;

	// Remove the temporary data directory, we have probably removed
	// useful files from it.
	recursive_delete_dirs_only(deltafdir);

	ret=0;
error:
	fzp_close(&zp);
	fzp_close(&delfp);
	sbuf_free(&sb);
	free_w(&deltabdir);
	free_w(&deltafdir);
	free_w(&sigpath);
	free_w(&datapth);
	free_w(&tmpman);
	return ret;
}
Exemple #29
0
static int process_changed_file(struct asfd *asfd,
	struct sdirs *sdirs, struct conf **cconfs,
	struct sbuf *cb, struct sbuf *p1b,
	const char *adir)
{
	size_t blocklen=0;
	char *curpath=NULL;
	//logp("need to process changed file: %s (%s)\n",
	//	cb->path, cb->datapth);

	// Move datapth onto p1b.
	iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);

	if(!(curpath=prepend_s(adir, p1b->protocol1->datapth.buf)))
	{
		log_out_of_memory(__func__);
		return -1;
	}
	if(dpth_protocol1_is_compressed(cb->compression, curpath))
		p1b->protocol1->sigfzp=fzp_gzopen(curpath, "rb");
	else
		p1b->protocol1->sigfzp=fzp_open(curpath, "rb");
	if(!p1b->protocol1->sigfzp)
	{
		logp("could not open %s: %s\n", curpath, strerror(errno));
		free(curpath);
		return -1;
	}
	free(curpath);

	blocklen=get_librsync_block_len(cb->protocol1->endfile.buf);
	if(!(p1b->protocol1->sigjob=
#ifdef RS_DEFAULT_STRONG_LEN
		rs_sig_begin(blocklen, RS_DEFAULT_STRONG_LEN)
#else
		// This is for librsync-1.0.0. RS_DEFAULT_STRONG_LEN was 8 in
		// librsync-0.9.7.
		rs_sig_begin(blocklen, 8,
		  rshash_to_magic_number(get_e_rshash(cconfs[OPT_RSHASH])))
#endif
	))
	{
		logp("could not start signature job.\n");
		return -1;
	}
	//logp("sig begin: %s\n", p1b->protocol1->datapth.buf);
	if(!(p1b->protocol1->infb=rs_filebuf_new(asfd, NULL,
		p1b->protocol1->sigfzp,
		-1, blocklen, -1, get_cntr(cconfs[OPT_CNTR]))))
	{
		logp("could not rs_filebuf_new for infb.\n");
		return -1;
	}
	if(!(p1b->protocol1->outfb=rs_filebuf_new(asfd, NULL, NULL,
		asfd->fd, ASYNC_BUF_LEN, -1, get_cntr(cconfs[OPT_CNTR]))))
	{
		logp("could not rs_filebuf_new for in_outfb.\n");
		return -1;
	}

	// Flag the things that need to be sent (to the client)
	p1b->flags |= SBUFL_SEND_DATAPTH;
	p1b->flags |= SBUFL_SEND_STAT;
	p1b->flags |= SBUFL_SEND_PATH;

	//logp("sending sig for %s\n", p1b->path);
	//logp("(%s)\n", p1b->datapth);

	return 0;
}
Exemple #30
0
// This deals with reading in the sparse index, as well as actual candidate
// manifests.
enum cand_ret candidate_load(struct candidate *candidate, const char *path,
	struct scores *scores)
{
	enum cand_ret ret=CAND_RET_PERM;
	struct fzp *fzp=NULL;
	struct sbuf *sb=NULL;
	struct blk *blk=NULL;

	if(!(sb=sbuf_alloc(PROTO_2))
	  || !(blk=blk_alloc()))
	{
		ret=CAND_RET_PERM;
		goto error;
	}
	
	if(!(fzp=fzp_gzopen(path, "rb")))
	{
		ret=CAND_RET_TEMP;
		goto error;
	}
	while(fzp)
	{
		sbuf_free_content(sb);
		switch(sbuf_fill_from_file(sb, fzp, blk, NULL))
		{
			case 1: goto end;
			case -1:
				logp("Error reading %s in %s, pos %d\n",
					path, __func__, fzp_tell(fzp));
				ret=CAND_RET_TEMP;
				goto error;
		}
		if(blk_fingerprint_is_hook(blk))
		{
			if(sparse_add_candidate(&blk->fingerprint, candidate))
			{
				ret=CAND_RET_PERM;
				goto error;
			}
		}
		else if(sb->path.cmd==CMD_MANIFEST)
		{
			if(!(candidate=candidates_add_new()))
			{
				ret=CAND_RET_PERM;
				goto error;
			}
			candidate->path=sb->path.buf;
			sb->path.buf=NULL;
		}
		blk->fingerprint=0;
	}

end:
	if(scores_grow(scores, candidates_len))
	{
		ret=CAND_RET_PERM;
		goto error;
	}
	candidates_set_score_pointers(candidates, candidates_len, scores);
	scores_reset(scores);
	//logp("Now have %d candidates\n", (int)candidates_len);
	ret=CAND_RET_OK;
error:
	fzp_close(&fzp);
	sbuf_free(&sb);
	blk_free(&blk);
	return ret;
}