Beispiel #1
0
static void setup_reads_from_slist_blks(struct asfd *asfd,
	int *ar, struct slist *slist, int number_of_blks, uint64_t interrupt)
{
	struct sbuf *s;
	struct blk blk;
	struct iobuf iobuf;
	uint64_t file_no=1;
	if(!slist) return;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_filedata(s)
		  && !sbuf_is_encrypted(s)) // Not working for proto2 yet.
		{
			int b;
			if(interrupt==file_no++)
				continue;
			blk_to_iobuf_sig(&blk, &iobuf);
			for(b=0; b<number_of_blks; b++)
			{
				iobuf_from_str(&iobuf, CMD_DATA,
					(char *)"some data");
				asfd_mock_read_iobuf(asfd, ar, 0, &iobuf);
			}
		}
	}
}
Beispiel #2
0
static void setup_chfd_reads_from_slist_blks_not_got(struct asfd *chfd,
	int *cr, struct slist *slist, int number_of_blks, uint64_t interrupt)
{
	int blk_index=1;
	uint64_t file_no=1;
	struct blk blk;
	struct iobuf iobuf;
	struct sbuf *s;
	if(!slist) return;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_filedata(s)
		  && !sbuf_is_encrypted(s)) // Not working for proto2 yet.
		{
			int b;
			if(interrupt==file_no++)
				continue;
			for(b=0; b<number_of_blks; b++)
			{
				blk.index=blk_index++;
				blk_to_iobuf_wrap_up(&blk, &iobuf);
				asfd_mock_read_iobuf(chfd, cr, 0, &iobuf);
			}
		}
	}
}
Beispiel #3
0
static void setup_writes_from_slist_blk_requests(struct asfd *asfd,
	int *aw, struct slist *slist, int number_of_blks, uint64_t interrupt)
{
	struct sbuf *s;
	struct iobuf iobuf;
	char req[32]="";
	int blk_index=1;
	uint64_t file_no=1;
	if(!slist) return;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_filedata(s)
		  && !sbuf_is_encrypted(s)) // Not working for proto2 yet.
		{
			int b;
			if(interrupt==file_no++)
				continue;
			for(b=0; b<number_of_blks; b++)
			{
				base64_from_uint64(blk_index++, req);
				iobuf_from_str(&iobuf, CMD_DATA_REQ, req);
				asfd_assert_write_iobuf(asfd, aw, 0, &iobuf);
			}
		}
	}
}
Beispiel #4
0
static void setup_asfds_proto1_stuff(struct asfd *asfd, struct slist *slist)
{
	int r=0; int w=0;
	struct sbuf *s;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_link(s))
		{
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->link);
		}
		else if(sbuf_is_filedata(s))
		{
			struct iobuf wbuf;
			// The string "data" gzipped.
			unsigned char gzipped_data1[10] = {
				0x1f, 0x8b, 0x08, 0, 0,
				0, 0, 0, 0x02, 0x03
			};
			unsigned char gzipped_data2[14] = {
				0x4b, 0x49, 0x2c, 0x49, 0x04, 0x00, 0x63,
				0xf3, 0xf3, 0xad, 0x04, 0x00, 0x00, 0x00
			};
			asfd_assert_write_iobuf(asfd, &w,
				0, &s->protocol1->datapth);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
			if(sbuf_is_encrypted(s))
			{
				// Encrypted files get sent as is.
				asfd_assert_write(asfd, &w, 0, CMD_APPEND,
					"data");
				asfd_assert_write(asfd, &w, 0, CMD_END_FILE,
					"4:8d777f385d3dfec8815d20f7496026dc");
				continue;
			}
			// Protocol1 always sends it gzipped.
			iobuf_set(&wbuf, CMD_APPEND,
				(char *)gzipped_data1, sizeof(gzipped_data1));
			asfd_assert_write_iobuf(asfd, &w, 0, &wbuf);
			iobuf_set(&wbuf, CMD_APPEND,
				(char *)gzipped_data2, sizeof(gzipped_data2));
			asfd_assert_write_iobuf(asfd, &w, 0, &wbuf);
			asfd_assert_write(asfd, &w, 0, CMD_END_FILE,
				"4:8d777f385d3dfec8815d20f7496026dc");
		}
		else
		{
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
		}
	}
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend");
	asfd_mock_read_no_op(asfd, &r, 100);
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend_ok");
}
Beispiel #5
0
static int send_file(struct asfd *asfd, struct sbuf *sb,
	int patches, const char *best,
	uint64_t *bytes, struct cntr *cntr)
{
	int ret=0;
	static BFILE *bfd=NULL;

	if(!bfd && !(bfd=bfile_alloc())) return -1;

	bfile_init(bfd, 0, cntr);
	if(bfd->open_for_send(bfd, asfd, best, sb->winattr,
		1 /* no O_NOATIME */, cntr, PROTO_1)) return -1;
	//logp("sending: %s\n", best);
	if(asfd->write(asfd, &sb->path))
		ret=-1;
	else if(patches)
	{
		// If we did some patches, the resulting file
		// is not gzipped. Gzip it during the send. 
		ret=send_whole_file_gzl(asfd, best, sb->protocol1->datapth.buf,
			1, bytes, NULL, cntr, 9, bfd, NULL, 0);
	}
	else
	{
		// If it was encrypted, it may or may not have been compressed
		// before encryption. Send it as it as, and let the client
		// sort it out.
		if(sbuf_is_encrypted(sb))
		{
			ret=send_whole_filel(asfd, sb->path.cmd, best,
				sb->protocol1->datapth.buf, 1, bytes,
				cntr, bfd, NULL, 0);
		}
		// It might have been stored uncompressed. Gzip it during
		// the send. If the client knew what kind of file it would be
		// receiving, this step could disappear.
		else if(!dpth_protocol1_is_compressed(sb->compression,
			sb->protocol1->datapth.buf))
		{
			ret=send_whole_file_gzl(asfd,
				best, sb->protocol1->datapth.buf, 1, bytes,
				NULL, cntr, 9, bfd, NULL, 0);
		}
		else
		{
			// If we did not do some patches, the resulting
			// file might already be gzipped. Send it as it is.
			ret=send_whole_filel(asfd, sb->path.cmd, best,
				sb->protocol1->datapth.buf, 1, bytes,
				cntr, bfd, NULL, 0);
		}
	}
	bfd->close(bfd, asfd);
	return ret;
}
Beispiel #6
0
static void setup_writes_from_slist(struct asfd *asfd,
	int *aw, struct slist *slist)
{
	struct sbuf *s;
	if(!slist) return;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_filedata(s)
		  && !sbuf_is_encrypted(s)) // Not working for proto2 yet.
		{
			asfd_assert_write(asfd,
				aw, 0, s->path.cmd, s->path.buf);
		}
	}
}
Beispiel #7
0
static void setup_reads_from_slist(struct asfd *asfd,
	int *ar, struct slist *slist, int number_of_blks, uint64_t interrupt)
{
	int file_no=1;
	struct sbuf *s;
	struct blk blk;
	struct iobuf iobuf;
	if(!slist) return;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_filedata(s)
		  && !sbuf_is_encrypted(s)) // Not working for proto2 yet.
		{
			int b;
			s->protocol2->index=file_no++;
			if(interrupt==s->protocol2->index)
			{
				char buf[32]="";
				asfd_mock_read(asfd,
					ar, 0, CMD_WARNING, "path vanished\n");
				base64_from_uint64(interrupt, buf);
				asfd_mock_read(asfd, ar, 0, CMD_INTERRUPT,
					buf);
				continue;
			}
			iobuf_free_content(&s->attr);
			attribs_encode(s);
			asfd_mock_read(asfd,
				ar, 0, CMD_ATTRIBS_SIGS, s->attr.buf);
			blk.fingerprint=file_no;
			memset(&blk.md5sum, file_no, MD5_DIGEST_LENGTH);
			blk_to_iobuf_sig(&blk, &iobuf);
			for(b=0; b<number_of_blks; b++)
				asfd_mock_read_iobuf(asfd, ar, 0, &iobuf);
		}
	}
}
Beispiel #8
0
static void setup_chfd_writes_from_slist(struct asfd *chfd,
	int *cw, struct slist *slist, int number_of_blks, uint64_t interrupt)
{
	struct sbuf *s;
	struct blk blk;
	struct iobuf iobuf;
	uint64_t file_no=1;
	if(!slist) return;
	for(s=slist->head; s; s=s->next)
	{
		if(sbuf_is_filedata(s)
		  && !sbuf_is_encrypted(s)) // Not working for proto2 yet.
		{
			int b;
			if(interrupt==file_no++)
				continue;
			blk.fingerprint=file_no;
			memset(&blk.md5sum, file_no, MD5_DIGEST_LENGTH);
			blk_to_iobuf_sig(&blk, &iobuf);
			for(b=0; b<number_of_blks; b++)
				asfd_assert_write_iobuf(chfd, cw, 0, &iobuf);
		}
	}
}
Beispiel #9
0
static int do_restore_file_or_get_meta(struct asfd *asfd, BFILE *bfd,
	struct sbuf *sb, const char *fname,
	char **metadata, size_t *metalen,
	struct cntr *cntr, const char *rpath,
	const char *encryption_password)
{
	int ret=-1;
	int enccompressed=0;
	uint64_t rcvdbytes=0;
	uint64_t sentbytes=0;
	const char *encpassword=NULL;

	if(sbuf_is_encrypted(sb))
		encpassword=encryption_password;
	enccompressed=dpth_protocol1_is_compressed(sb->compression,
		sb->protocol1->datapth.buf);
/*
	printf("%s \n", fname);
	if(encpassword && !enccompressed)
		printf("encrypted and not compressed\n");
	else if(!encpassword && enccompressed)
		printf("not encrypted and compressed\n");
	else if(!encpassword && !enccompressed)
		printf("not encrypted and not compressed\n");
	else if(encpassword && enccompressed)
		printf("encrypted and compressed\n");
*/

	if(metadata)
	{
		ret=transfer_gzfile_inl(asfd, sb, fname, NULL,
			&rcvdbytes, &sentbytes, encpassword, enccompressed,
			cntr, metadata);
		*metalen=sentbytes;
		// skip setting cntr, as we do not actually
		// restore until a bit later
		goto end;
	}
	else
	{
		ret=transfer_gzfile_inl(asfd, sb, fname, bfd,
			&rcvdbytes, &sentbytes,
			encpassword, enccompressed, cntr, NULL);
#ifndef HAVE_WIN32
		if(bfd && bfd->close(bfd, asfd))
		{
			logp("error closing %s in %s\n",
				fname, __func__);
			goto end;
		}
#endif
		if(!ret) attribs_set(asfd, rpath,
			&sb->statp, sb->winattr, cntr);
	}

	ret=0;
end:
	if(ret)
	{
		char msg[256]="";
		snprintf(msg, sizeof(msg),
			"Could not transfer file in: %s", rpath);
		if(restore_interrupt(asfd, sb, msg, cntr, PROTO_1))
			ret=-1;
	}
	return ret;
}
Beispiel #10
0
static int maybe_do_delta_stuff(struct asfd *asfd,
	struct sdirs *sdirs, struct sbuf *cb, struct sbuf *p1b,
	struct manio *ucmanio, struct conf **cconfs)
{
	int oldcompressed=0;
	int compression=p1b->compression;

	// If the file type changed, I think it is time to back it up again
	// (for example, EFS changing to normal file, or back again).
	if(cb->path.cmd!=p1b->path.cmd)
		return process_new_file(sdirs, cconfs, cb, p1b, ucmanio);

	// mtime is the actual file data.
	// ctime is the attributes or meta data.
	if(cb->statp.st_mtime==p1b->statp.st_mtime
	  && cb->statp.st_ctime==p1b->statp.st_ctime)
	{
		// got an unchanged file
		//logp("got unchanged file: %s %c %c\n",
		//	cb->path.buf, cb->path.cmd, p1b->path.cmd);
		return process_unchanged_file(p1b, cb, ucmanio, cconfs);
	}

	if(cb->statp.st_mtime==p1b->statp.st_mtime
	  && cb->statp.st_ctime!=p1b->statp.st_ctime)
	{
		// File data stayed the same, but attributes or meta data
		// changed. We already have the attributes, but may need to get
		// extra meta data.
		// FIX THIS horrible mess.
		if(cb->path.cmd==CMD_ENC_METADATA
		  || p1b->path.cmd==CMD_ENC_METADATA
		  || cb->path.cmd==CMD_EFS_FILE
		  || p1b->path.cmd==CMD_EFS_FILE
		// FIX THIS: make unencrypted metadata use the librsync
		  || cb->path.cmd==CMD_METADATA
		  || p1b->path.cmd==CMD_METADATA
		  || sbuf_is_vssdata(cb)
		  || sbuf_is_vssdata(p1b))
			return process_new_file(sdirs,
				cconfs, cb, p1b, ucmanio);
		// On Windows, we have to back up the whole file if ctime
		// changed, otherwise things like permission changes do not get
		// noticed. So, in that case, fall through to the changed stuff
		// below.
		// Non-Windows clients finish here.
		else if(!get_int(cconfs[OPT_CLIENT_IS_WINDOWS]))
			return process_unchanged_file(p1b,
				cb, ucmanio, cconfs);
	}

	// Got a changed file.
	//logp("got changed file: %s\n", p1b->path.buf);

	// If either old or new is encrypted, or librsync is off, we need to
	// get a new file.
	// FIX THIS horrible mess.
	if(!get_int(cconfs[OPT_LIBRSYNC])
	// FIX THIS: make unencrypted metadata use the librsync
	  || cb->path.cmd==CMD_METADATA
	  || p1b->path.cmd==CMD_METADATA
	  || sbuf_is_encrypted(cb)
	  || sbuf_is_encrypted(p1b)
	  || sbuf_is_vssdata(cb)
	  || sbuf_is_vssdata(p1b))
		return process_new_file(sdirs, cconfs, cb, p1b, ucmanio);

	// Get new files if they have switched between compression on or off.
	if(cb->protocol1->datapth.buf
	  && dpth_protocol1_is_compressed(cb->compression,
	    cb->protocol1->datapth.buf))
		oldcompressed=1;
	if( ( oldcompressed && !compression)
	 || (!oldcompressed &&  compression))
		return process_new_file(sdirs, cconfs, cb, p1b, ucmanio);

	// Otherwise, do the delta stuff (if possible).
	if(sbuf_is_filedata(p1b)
	  || sbuf_is_vssdata(p1b))
	{
		if(process_changed_file(asfd, sdirs, cconfs, cb, p1b,
			sdirs->currentdata)) return -1;
	}
	else
	{
		if(changed_non_file(p1b, ucmanio, p1b->path.cmd, cconfs))
			return -1;
	}
	sbuf_free_content(cb);
	return 1;
}
Beispiel #11
0
static int do_send_file(struct asfd *asfd, struct sbuf *sb,
	int patches, const char *best, struct cntr *cntr)
{
	enum send_e ret=SEND_FATAL;
	struct BFILE bfd;
	uint64_t bytes=0; // Unused.

	bfile_init(&bfd, 0, cntr);
	if(bfd.open_for_send(&bfd, asfd, best, sb->winattr,
		1 /* no O_NOATIME */, cntr, PROTO_1))
			return SEND_FATAL;
	if(asfd->write(asfd, &sb->path))
		ret=SEND_FATAL;
	else if(patches)
	{
		// If we did some patches, the resulting file
		// is not gzipped. Gzip it during the send.
		ret=send_whole_file_gzl(
			asfd,
			sb->protocol1->datapth.buf,
			/*quick_read*/1,
			&bytes,
			/*encpassword*/NULL,
			cntr,
			/*compression*/9,
			&bfd,
			/*extrameta*/NULL,
			/*elen*/0,
			/*key_deriv*/ENCRYPTION_UNSET,
			/*salt*/0
		);
	}
	else
	{
		// If it was encrypted, it may or may not have been compressed
		// before encryption. Send it as it as, and let the client
		// sort it out.
		if(sbuf_is_encrypted(sb))
		{
			ret=send_whole_filel(asfd,
#ifdef HAVE_WIN32
				sb->path.cmd
#endif
				sb->protocol1->datapth.buf,
				1, &bytes, cntr, &bfd, NULL, 0);
		}
		// It might have been stored uncompressed. Gzip it during
		// the send. If the client knew what kind of file it would be
		// receiving, this step could disappear.
		else if(!dpth_protocol1_is_compressed(sb->compression,
			sb->protocol1->datapth.buf))
		{
			ret=send_whole_file_gzl(
				asfd,
				sb->protocol1->datapth.buf,
				/*quick_read*/1,
				&bytes,
				/*encpassword*/NULL,
				cntr,
				/*compression*/9,
				&bfd,
				/*extrameta*/NULL,
				/*elen*/0,
				/*key_deriv*/ENCRYPTION_UNSET,
				/*salt*/0
			);
		}
		else
		{
			// If we did not do some patches, the resulting
			// file might already be gzipped. Send it as it is.
			ret=send_whole_filel(asfd,
#ifdef HAVE_WIN32
				sb->path.cmd
#endif
				sb->protocol1->datapth.buf,
				1, &bytes, cntr, &bfd, NULL, 0);
		}
	}
	bfd.close(&bfd, asfd);

	switch(ret)
	{
		case SEND_OK:
		case SEND_ERROR: // Carry on.
			return 0;
		case SEND_FATAL:
		default:
			return -1;
	}
}