Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #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;
}
Beispiel #5
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);
}
Beispiel #6
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;
}
Beispiel #7
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);
}
Beispiel #8
0
int fzp_read_ensure(struct fzp *fzp, void *ptr, size_t nmemb, const char *func)
{
	static int f;
	static int r;
	static size_t got;
	static int pass;
	for(r=0, got=0, pass=0; got!=nmemb; pass++)
	{
		r=fzp_read(fzp, ((char *)ptr)+got, nmemb-got);
		if(r>0)
		{
			got+=r;
			continue;
		}
		if(r<0)
		{
			pass_msg(nmemb, got, pass);
			logp("Error in %s, called from %s: %s\n",
				__func__, func, strerror(errno));
			return -1;
		}
		f=fzp_eof(fzp);
		if(!f) continue; // Not yet end of file, keep trying.
		if(f>0)
		{
			// End of file.
			if(!got) return 1;
			pass_msg(nmemb, got, pass);
			logp("Error in %s, called from %s: %u bytes, eof\n",
				__func__, func, got);
			return -1;
		}
		else
		{
			pass_msg(nmemb, got, pass);
			logp("Error in %s by fzp_feof, called from %s: %s\n",
				__func__, func, strerror(errno));
			return -1;
		}
	}
	return 0;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
0
/*
 * If the stream has no more data available, read some from F into
 * BUF, and let the stream use that.  On return, SEEN_EOF is true if
 * the end of file has passed into the stream.
 */
rs_result rs_infilebuf_fill(rs_job_t *job, rs_buffers_t *buf, void *opaque)
{
	int len=0;
	rs_filebuf_t *fb=(rs_filebuf_t *) opaque;
	struct cntr *cntr;
	int fd=fb->fd;
	cntr=fb->cntr;

	//logp("rs_infilebuf_fill\n");

	/* This is only allowed if either the buf has no input buffer
	 * yet, or that buffer could possibly be BUF. */
	if(buf->next_in)
	{
		//logp("infilebuf avail_in %d buf_len %d\n",
		//	buf->avail_in, fb->buf_len);
		if(buf->avail_in > fb->buf_len)
		{
			logp("buf->avail_in > fb->buf_len (%d > %d) in %s\n",
				buf->avail_in, fb->buf_len, __func__);
			return RS_IO_ERROR;
		}
		if(buf->next_in < fb->buf)
		{
			logp("buf->next_in < fb->buf in %s\n", __func__);
			return RS_IO_ERROR;
		}
		if(buf->next_in > fb->buf + fb->buf_len)
		{
			logp("buf->next_in > fb->buf + fb->buf_len in %s\n",
				__func__);
			return RS_IO_ERROR;
		}
	}
	else
	{
		if(buf->avail_in)
		{
			logp("buf->avail_in is %d in %s\n",
				buf->avail_in, __func__);
			return RS_IO_ERROR;
		}
	}

	if(buf->eof_in) return RS_DONE;

	if(buf->avail_in)
		/* Still some data remaining.  Perhaps we should read
		   anyhow? */
		return RS_DONE;

	if(fd>=0)
	{
		static struct iobuf *rbuf=NULL;
		rbuf=fb->asfd->rbuf;

		if(fb->asfd->read(fb->asfd)) return RS_IO_ERROR;
		if(rbuf->cmd==CMD_APPEND)
		{
			//logp("got '%c' in fd infilebuf: %d\n",
			//	CMD_APPEND, rbuf->len);
			memcpy(fb->buf, rbuf->buf, rbuf->len);
			len=rbuf->len;
			iobuf_free_content(rbuf);
		}
		else if(rbuf->cmd==CMD_END_FILE)
		{
			iobuf_free_content(rbuf);
			//logp("got %c in fd infilebuf\n", CMD_END_FILE);
			buf->eof_in=1;
			return RS_DONE;
		}
		else if(rbuf->cmd==CMD_WARNING)
		{
			logp("WARNING: %s\n", rbuf->buf);
			cntr_add(cntr, rbuf->cmd, 0);
			iobuf_free_content(rbuf);
			return RS_DONE;
		}
		else
		{
			iobuf_log_unexpected(rbuf, __func__);
			iobuf_free_content(rbuf);
			return RS_IO_ERROR;
		}
	}
	else if(fb->bfd)
	{
		if(fb->do_known_byte_count)
		{
			if(fb->data_len>0)
			{
				len=fb->bfd->read(fb->bfd, fb->buf,
					min(fb->buf_len, fb->data_len));
				fb->data_len-=len;
			}
			else
			{
				// We have already read as much data as the VSS
				// header told us to, so set len=0 in order to
				// finish up.
				len=0;
			}
		}
		else
			len=fb->bfd->read(fb->bfd, fb->buf, fb->buf_len);
		if(len==0)
		{
			//logp("bread: eof\n");
			buf->eof_in=1;
			return RS_DONE;
		}
		else if(len<0)
		{
			logp("rs_infilebuf_fill: error in bread\n");
			return RS_IO_ERROR;
		}
		//logp("bread: ok: %d\n", len);
		fb->bytes+=len;
		if(!MD5_Update(&(fb->md5), fb->buf, len))
		{
			logp("rs_infilebuf_fill: MD5_Update() failed\n");
			return RS_IO_ERROR;
		}
	}
	else if(fb->fzp)
	{
		if((len=fzp_read(fb->fzp, fb->buf, fb->buf_len))<=0)
		{
			// This will happen if file size is a multiple of
			// input block len.
			if(fzp_eof(fb->fzp))
			{
				buf->eof_in=1;
				return RS_DONE;
			}
			else
			{
				logp("rs_infilebuf_fill: got return %d when trying to read\n", len);
				return RS_IO_ERROR;
			}
		}
		fb->bytes+=len;
		if(!MD5_Update(&(fb->md5), fb->buf, len))
		{
			logp("rs_infilebuf_fill: MD5_Update() failed\n");
			return RS_IO_ERROR;
		}
	}

	buf->avail_in = len;
	buf->next_in = fb->buf;

	return RS_DONE;
}