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 int duplicate_file(const char *oldpath, const char *newpath)
{
	int ret=-1;
	size_t s=0;
	size_t t=0;
	struct fzp *op=NULL;
	struct fzp *np=NULL;
	char buf[DUP_CHUNK]="";
	if(!(op=fzp_open(oldpath, "rb"))
	  || !(np=fzp_open(newpath, "wb")))
		goto end;

	while((s=fzp_read(op, buf, DUP_CHUNK))>0)
	{
		t=fzp_write(np, buf, s);
		if(t!=s)
		{
			logp("could not write all bytes: %lu!=%lu\n",
				(unsigned long)s, (unsigned long)t);
			goto end;
		}
	}

	ret=0;
end:
	fzp_close(&np);
	fzp_close(&op);
	if(ret) logp("could not duplicate %s to %s\n", oldpath, newpath);
	return ret;
}
Exemple #3
0
static int full_match(struct file *o, struct file *n,
	struct fzp **ofp, struct fzp **nfp)
{
	size_t ogot;
	size_t ngot;
	unsigned int i=0;
	static char obuf[FULL_CHUNK];
	static char nbuf[FULL_CHUNK];

	if(*ofp) fzp_seek(*ofp, 0, SEEK_SET);
	else if(!(*ofp=fzp_open(o->path, "rb")))
	{
		// Blank this entry so that it can be ignored from
		// now on.
		free_w(&o->path);
		return 0;
	}

	if(*nfp) fzp_seek(*nfp, 0, SEEK_SET);
	else if(!(*nfp=fzp_open(n->path, "rb"))) return 0;

	while(1)
	{
		ogot=fzp_read(*ofp, obuf, FULL_CHUNK);
		ngot=fzp_read(*nfp, nbuf, FULL_CHUNK);
		if(ogot!=ngot) return 0;
		for(i=0; i<ogot; i++)
			if(obuf[i]!=nbuf[i]) return 0;
		if(ogot<FULL_CHUNK) break;
	}

	return 1;
}
Exemple #4
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 #5
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 #6
0
static int start_to_receive_new_file(struct asfd *asfd,
	struct sdirs *sdirs, struct conf **cconfs,
	struct sbuf *sb, struct dpth *dpth)
{
	int ret=-1;
	char *rpath=NULL;
	int istreedata=0;

//logp("start to receive: %s\n", sb->path.buf);

	if(!(rpath=set_new_datapth(asfd,
		sdirs, cconfs, sb, dpth, &istreedata)))
			goto end;
	
	if(!(sb->protocol1->fzp=fzp_open(rpath, "wb")))
	{
		log_and_send(asfd, "make file failed");
		goto end;
	}
	if(!istreedata) dpth_incr(dpth);
	ret=0;
end:
	free_w(&rpath);
	return ret;
}
Exemple #7
0
int log_fzp_set(const char *path, struct conf **confs)
{
	fzp_close(&logfzp);
	if(path)
	{
		logp("Logging to %s\n", path);
		if(!(logfzp=fzp_open(path, "ab"))) return -1;
	}
	if(logfzp) fzp_setlinebuf(logfzp);
	do_syslog=get_int(confs[OPT_SYSLOG]);
	if(force_quiet)
	{
		do_stdout=0;
		do_progress_counter=0;
	}
	else
	{
		do_stdout=get_int(confs[OPT_STDOUT]);
		do_progress_counter=get_int(confs[OPT_PROGRESS_COUNTER]);
	}

	if(syslog_opened)
	{
		closelog();
		syslog_opened=0;
	}
	if(do_syslog)
	{
		openlog(prog, LOG_PID, LOG_USER);
		syslog_opened++;
	}
	return 0;
}
Exemple #8
0
struct slist *build_manifest_with_data_files(const char *path,
	const char *datapath, int entries, int data_files)
{
	struct blk *b=NULL;
	struct slist *slist=NULL;
	struct manio *manio=NULL;
	struct fzp *fzp=NULL;
	char spath[256]="";
	char cpath[256]="";

	fail_unless((manio=manio_open_phase3(path, "wb", PROTO_2,
		RMANIFEST_RELATIVE))!=NULL);
	slist=do_build_manifest(manio, PROTO_2, entries, data_files);
	fail_unless(!manio_close(&manio));

	for(b=slist->blist->head; b; b=b->next)
	{
		snprintf(spath, sizeof(spath), "%s/%s", datapath,
			uint64_to_savepathstr(b->savepath));
		if(strcmp(spath, cpath))
		{
			snprintf(cpath, sizeof(cpath), "%s", spath);
			fzp_close(&fzp);
		}
		if(!fzp)
		{
			fail_unless(!build_path_w(cpath));
			fail_unless((fzp=fzp_open(cpath, "wb"))!=NULL);
		}
		fzp_printf(fzp, "%c%04X%s", CMD_DATA, strlen("data"), "data");
	}
	fzp_close(&fzp);

	return slist;
}
Exemple #9
0
int manio_read_fcount(struct manio *manio)
{
	int ret=-1;
	size_t s;
	struct fzp *fzp=NULL;
	char *path=NULL;
	char buf[16]="";
	if(!(path=get_fcount_path(manio))
	  || !(fzp=fzp_open(path, "rb")))
		goto end;
	if(!fzp_gets(fzp, buf, sizeof(buf)))
	{
		logp("fzp_gets on %s failed\n", path);
		goto end;
	}
	s=strlen(buf);
	if(s!=9)
	{
		logp("data in %s is not the right length (%s!=9)\n", s);
		goto end;
	}
	manio->offset->fcount=strtoul(buf, NULL, 16);
	ret=0;
end:
	fzp_close(&fzp);
	free_w(&path);
	return ret;
}
Exemple #10
0
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;
}
Exemple #11
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 #12
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;
}
int status_client_ncurses(struct conf **confs)
{
        int ret=-1;
	int csin=-1;
	int csout=-1;
	pid_t childpid=-1;
	struct async *as=NULL;
	const char *monitor_logfile=get_string(confs[OPT_MONITOR_LOGFILE]);
	struct asfd *so_asfd=NULL;
	struct sel *sel=NULL;

	if(!(sel=sel_alloc()))
		goto end;

	setup_signals();

	// Fork a burp child process that will contact the server over SSL.
	// We will read and write from and to its stdout and stdin.
	if((childpid=fork_monitor(&csin, &csout, confs))<0)
		goto end;
//printf("childpid: %d\n", childpid);

	if(!(as=async_alloc())
	  || as->init(as, 0)
	  || !setup_asfd_linebuf_write(as, "monitor stdin", &csin)
	  || !setup_asfd_linebuf_read(as, "monitor stdout", &csout))
		goto end;
//printf("ml: %s\n", monitor_logfile);
#ifdef HAVE_NCURSES
	if(actg==ACTION_STATUS)
	{
		if(!setup_asfd_ncurses_stdin(as))
			goto end;
		ncurses_init();
	}
#endif
	if(!(so_asfd=setup_asfd_stdout(as)))
		goto end;

	if(monitor_logfile
	  && !(lfzp=fzp_open(monitor_logfile, "wb")))
		goto end;
	log_fzp_set_direct(lfzp);

	ret=status_client_ncurses_main_loop(as, so_asfd, sel,
		get_string(confs[OPT_ORIG_CLIENT]));
end:
#ifdef HAVE_NCURSES
	if(actg==ACTION_STATUS)
		ncurses_free();
#endif
	if(ret) logp("%s exiting with error: %d\n", __func__, ret);
	fzp_close(&lfzp);
	async_asfd_free_all(&as);
	close_fd(&csin);
	close_fd(&csout);
	sel_free(&sel);
	return ret;
}
Exemple #14
0
static int create_zero_length_file(const char *path)
{
	int ret=0;
	struct fzp *dest;
	if(!(dest=fzp_open(path, "wb")))
		ret=-1;
	ret|=fzp_close(&dest);
	return ret;
}
Exemple #15
0
static struct asfd *asfd_setup(const char *outputpath)
{
    struct asfd *asfd;
    fail_unless((asfd=asfd_alloc())!=NULL);
    fail_unless((asfd->rbuf=iobuf_alloc())!=NULL);
    asfd->write=my_asfd_write;
    fail_unless(!build_path_w(outputpath));
    fail_unless((output=fzp_open(outputpath, "wb"))!=NULL);
    json_set_pretty_print(1);
    return asfd;
}
Exemple #16
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 #17
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 #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 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 #20
0
static int load_rblk(struct rblk *rblks, int ind, const char *datpath)
{
	int r;
	int ret=-1;
	int done=0;
	struct fzp *fzp=NULL;
	struct iobuf rbuf;

	iobuf_init(&rbuf);

	free_w(&rblks[ind].datpath);
	if(!(rblks[ind].datpath=strdup_w(datpath, __func__)))
		goto end;

	logp("swap %d to: %s\n", ind, datpath);

	if(!(fzp=fzp_open(datpath, "rb")))
		goto end;
	for(r=0; r<DATA_FILE_SIG_MAX; r++)
	{
		switch(iobuf_fill_from_fzp_data(&rbuf, fzp))
		{
			case 0: if(rbuf.cmd!=CMD_DATA)
				{
					logp("unknown cmd in %s: %c\n",
						__func__, rbuf.cmd);
					goto end;
				}
				iobuf_free_content(&rblks[ind].readbuf[r]);
				iobuf_move(&rblks[ind].readbuf[r], &rbuf);
				continue;
			case 1: done++;
				break;
			default: goto end;
		}
		if(done) break;
	}
	rblks[ind].readbuflen=r;
	ret=0;
end:
	fzp_close(&fzp);
	return ret;
}
Exemple #21
0
static int get_part_cksum(struct file *f, struct fzp **fzp)
{
	MD5_CTX md5;
	int got=0;
	static char buf[PART_CHUNK];
	unsigned char checksum[MD5_DIGEST_LENGTH+1];

	if(*fzp) fzp_seek(*fzp, 0, SEEK_SET);
	else if(!(*fzp=fzp_open(f->path, "rb")))
	{
		f->part_cksum=0;
		return 0;
	}

	if(!MD5_Init(&md5))
	{
		logp("MD5_Init() failed\n");
		return -1;
	}

	got=fzp_read(*fzp, buf, PART_CHUNK);

	if(!MD5_Update(&md5, buf, got))
	{
		logp("MD5_Update() failed\n");
		return -1;
	}

	if(!MD5_Final(checksum, &md5))
	{
		logp("MD5_Final() failed\n");
		return -1;
	}

	memcpy(&(f->part_cksum), checksum, sizeof(unsigned));

	// Try for a bit of efficiency - no need to calculate the full checksum
	// again if we already read the whole file.
	if(got<PART_CHUNK) f->full_cksum=f->part_cksum;

	return 0;
}
Exemple #22
0
static int write_incexc(const char *realworking, const char *incexc)
{
	int ret=-1;
	struct fzp *fzp=NULL;
	char *path=NULL;
	if(!incexc || !*incexc) return 0;
	if(!(path=prepend_s(realworking, "incexc"))
	  || !(fzp=fzp_open(path, "wb")))
		goto end;
	fzp_printf(fzp, "%s", incexc);
	ret=0;
end:
	if(fzp_close(&fzp))
	{
		logp("error writing to %s in write_incexc\n", path);
		ret=-1;
	}
	free_w(&path);
	return ret;
}
Exemple #23
0
static int get_full_cksum(struct file *f, struct fzp **fzp)
{
	size_t s=0;
	MD5_CTX md5;
	static char buf[FULL_CHUNK];
	unsigned char checksum[MD5_DIGEST_LENGTH+1];

	if(*fzp) fzp_seek(*fzp, 0, SEEK_SET);
	else if(!(*fzp=fzp_open(f->path, "rb")))
	{
		f->full_cksum=0;
		return 0;
	}

	if(!MD5_Init(&md5))
	{
		logp("MD5_Init() failed\n");
		return -1;
	}

	while((s=fzp_read(*fzp, buf, FULL_CHUNK))>0)
	{
		if(!MD5_Update(&md5, buf, s))
		{
			logp("MD5_Update() failed\n");
			return -1;
		}
		if(s<FULL_CHUNK) break;
	}

	if(!MD5_Final(checksum, &md5))
	{
		logp("MD5_Final() failed\n");
		return -1;
	}

	memcpy(&(f->full_cksum), checksum, sizeof(unsigned));

	return 0;
}
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 get_cname_from_ssl_cert(struct conf **c)
{
	int ret=-1;
	struct fzp *fzp=NULL;
	X509 *cert=NULL;
	X509_NAME *subj=NULL;
	char *path=get_string(c[OPT_SSL_CERT]);
	const char *cn=NULL;

	if(!path || !(fzp=fzp_open(path, "rb"))) return 0;

	if(!(cert=fzp_PEM_read_X509(fzp)))
	{
		logp("unable to parse %s in: %s\n", path, __func__);
		goto end;
	}
	if(!(subj=X509_get_subject_name(cert)))
	{
		logp("unable to get subject from %s in: %s\n", path, __func__);
		goto end;
	}

	if(!(cn=extract_cn(subj)))
	{
		logp("could not get CN from %s\n", path);
		goto end;
	}
	if(set_string(c[OPT_CNAME], cn))
		goto end;
	logp("cname from cert: %s\n", cn);

	ret=0;
end:
	if(cert) X509_free(cert);
	fzp_close(&fzp);
	return ret;
}
Exemple #26
0
static int inflate_oldfile(const char *opath, const char *infpath,
	struct stat *statp, struct cntr *cntr)
{
	int ret=0;

	if(!statp->st_size)
	{
		struct fzp *dest=NULL;
		// Empty file - cannot inflate.
		// just close the destination and we have duplicated a
		// zero length file.
		if(!(dest=fzp_open(infpath, "wb"))) goto end;
		logp("asked to inflate zero length file: %s\n", opath);
		if(fzp_close(&dest))
			logp("error closing %s in %s\n", infpath, __func__);
	}
	else if(zlib_inflate(NULL, opath, infpath, cntr))
	{
		logp("zlib_inflate returned error\n");
		ret=-1;
	}
end:
	return ret;
}
Exemple #27
0
// Backup phase4 needs to know the fcount, so leave a file behind that
// contains it (otherwise phase4 will have to read and sort the directory
// contents).
static int manio_write_fcount(struct manio *manio)
{
	int ret=-1;
	struct fzp *fzp=NULL;
	char *path=NULL;

	if(!(path=get_fcount_path(manio))
	  || !(fzp=fzp_open(path, "wb")))
		goto end;
	if(fzp_printf(fzp, "%08"PRIX64"\n", manio->offset->fcount)!=9)
	{
		logp("Short write when writing to %s\n", path);
		goto end;
	}
	ret=0;
end:
	if(fzp_close(&fzp))
	{
		logp("Could not close file pointer to %s\n", path);
		ret=-1;
	}
	free_w(&path);
	return ret;
}
Exemple #28
0
static char *get_ca_dir(struct conf **confs)
{
	struct fzp *fzp=NULL;
	char buf[4096]="";
	const char *ca_conf=get_string(confs[OPT_CA_CONF]);
	if(!(fzp=fzp_open(ca_conf, "r"))) goto end;
	while(fzp_gets(fzp, buf, sizeof(buf)))
	{
		char *field=NULL;
		char *value=NULL;
		if(conf_get_pair(buf, &field, &value)
		  || !field || !value) continue;

		if(!strcasecmp(field, "CA_DIR"))
		{
			if(!(gca_dir=strdup_w(value, __func__)))
				goto end;
			break;
		}
	}
end:
	fzp_close(&fzp);
	return gca_dir;
}
Exemple #29
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 #30
0
int backup_phase2_server_protocol1(struct async *as, struct sdirs *sdirs,
	const char *incexc, int resume, struct conf **cconfs)
{
	int ret=0;
	struct manio *p1manio=NULL;
	struct dpth *dpth=NULL;
	char *deltmppath=NULL;
	char *last_requested=NULL;
	// Where to write changed data.
	// Data is not getting written to a compressed file.
	// This is important for recovery if the power goes.
	struct fzp *chfp=NULL;
	struct fzp *ucfp=NULL; // unchanged data
	struct fzp *cmanfp=NULL; // previous (current) manifest.
	struct sbuf *cb=NULL; // file list in current manifest
	struct sbuf *p1b=NULL; // file list from client
	struct sbuf *rb=NULL; // receiving file from client
	struct asfd *asfd=as->asfd;
	int breaking=0;
	int breakcount=0;
	if(get_int(cconfs[OPT_BREAKPOINT])>=2000
	  && get_int(cconfs[OPT_BREAKPOINT])<3000)
	{
		breaking=get_int(cconfs[OPT_BREAKPOINT]);
		breakcount=breaking-2000;
	}

	logp("Begin phase2 (receive file data)\n");

	if(!(dpth=dpth_alloc())
	  || dpth_protocol1_init(dpth, sdirs->currentdata,
		get_int(cconfs[OPT_MAX_STORAGE_SUBDIRS])))
			goto error;

	if(open_previous_manifest(&cmanfp, sdirs, incexc, cconfs))
		goto error;

	if(get_int(cconfs[OPT_DIRECTORY_TREE]))
	{
		// Need to make sure we do not try to create a path that is
		// too long.
		if(build_path_w(sdirs->treepath)) goto error;
		treepathlen=strlen(sdirs->treepath);
		init_fs_max(sdirs->treepath);
	}

	if(!(p1manio=manio_alloc())
	  || manio_init_read(p1manio, sdirs->phase1data)
	  || !(cb=sbuf_alloc(cconfs))
	  || !(p1b=sbuf_alloc(cconfs))
	  || !(rb=sbuf_alloc(cconfs)))
		goto error;

	manio_set_protocol(p1manio, PROTO_1);

	if(resume && do_resume(p1manio, sdirs, dpth, cconfs))
		goto error;

	// Unchanged and changed should now be truncated correctly, we just
	// have to open them for appending.
	if(!(ucfp=fzp_open(sdirs->unchanged, "a+b"))
	  || !(chfp=fzp_open(sdirs->changed, "a+b")))
		goto error;

	if(manio_closed(p1manio)
	  && manio_open_next_fpath(p1manio))
		goto error;

	while(1)
	{
		if(breaking)
		{
			if(breakcount--==0) return breakpoint(cconfs, __func__);
		}

		//printf("in loop, %s %s %c\n",
		//	cmanfp?"got cmanfp":"no cmanfp",
		//	rb->path.buf?:"no rb->path",
	 	//	rb->path.buf?'X':rb->path.cmd);
		if(write_status(CNTR_STATUS_BACKUP,
			rb->path.buf?rb->path.buf:p1b->path.buf, cconfs))
				goto error;
		if(last_requested
		  || manio_closed(p1manio)
		  || asfd->writebuflen)
		{
			switch(do_stuff_to_receive(asfd, sdirs,
				cconfs, rb, chfp, dpth, &last_requested))
			{
				case 0: break;
				case 1: goto end; // Finished ok.
				case -1: goto error;
			}
		}

		switch(do_stuff_to_send(asfd, p1b, &last_requested))
		{
			case 0: break;
			case 1: continue;
			case -1: goto error;
		}

		if(manio_closed(p1manio)) continue;

		sbuf_free_content(p1b);

		switch(manio_sbuf_fill_phase1(p1manio, asfd,
			p1b, NULL, sdirs, cconfs))
		{
			case 0: break;
			case 1: manio_close(p1manio);
				if(asfd->write_str(asfd,
				  CMD_GEN, "backupphase2end")) goto error;
				break;
			case -1: goto error;
		}

		if(!cmanfp)
		{
			// No old manifest, need to ask for a new file.
			if(process_new(sdirs, cconfs, p1b, ucfp))
				goto error;
			continue;
		}

		// Have an old manifest, look for it there.

		// Might already have it, or be ahead in the old
		// manifest.
		if(cb->path.buf) switch(maybe_process_file(asfd,
			sdirs, cb, p1b, ucfp, cconfs))
		{
			case 0: break;
			case 1: continue;
			case -1: goto error;
		}

		while(cmanfp)
		{
			sbuf_free_content(cb);
			switch(sbufl_fill(cb, asfd, cmanfp, cconfs))
			{
				case 0: break;
				case 1: fzp_close(&cmanfp);
					if(process_new(sdirs, cconfs, p1b,
						ucfp)) goto error;
					continue;
				case -1: goto error;
			}
			switch(maybe_process_file(asfd, sdirs,
				cb, p1b, ucfp, cconfs))
			{
				case 0: continue;
				case 1: break;
				case -1: goto error;
			}
			break;
		}
	}

error:
	ret=-1;
end:
	if(fzp_close(&chfp))
	{
		logp("error closing %s in %s\n", sdirs->changed, __func__);
		ret=-1;
	}
	if(fzp_close(&ucfp))
	{
		logp("error closing %s in %s\n", sdirs->unchanged, __func__);
		ret=-1;
	}
	free_w(&deltmppath);
	sbuf_free(&cb);
	sbuf_free(&p1b);
	sbuf_free(&rb);
	manio_free(&p1manio);
	fzp_close(&cmanfp);
	dpth_free(&dpth);
	if(!ret) unlink(sdirs->phase1data);

	logp("End phase2 (receive file data)\n");

	return ret;
}