Esempio n. 1
0
static char *gen_endfile_str(void)
{
	uint64_t bytes;
	uint8_t checksum[MD5_DIGEST_LENGTH];
	bytes=prng_next64();
	prng_md5sum(checksum);
	return get_endfile_str(bytes, checksum);
}
Esempio n. 2
0
int write_endfile(struct asfd *asfd, uint64_t bytes, uint8_t *checksum)
{
	return asfd->write_str(asfd,
		CMD_END_FILE, get_endfile_str(bytes, checksum));
}
Esempio n. 3
0
static int write_endfile(struct asfd *asfd, unsigned long long bytes)
{
	return asfd->write_str(asfd, CMD_END_FILE, get_endfile_str(bytes));
}
Esempio n. 4
0
static int resume_partial_new_file(struct sbuf *p1b, struct cntr *cntr, const char *currentdata, const char *datadirtmp, const char *deltmppath, struct dpth *dpth, struct config *cconf)
{
	int ret=0;
	int junk=0;
	struct sbuf cb;
	char *rpath=NULL;
	int istreedata=0;
	struct stat statp;
	char *partial=NULL;
	char *partialdir=NULL;
	char *zdeltmp=NULL;
	// It does not matter what this checksum is set to.
	// This is just to get an endfile string in the format that
	// process_changed_file expects.
	unsigned char checksum[18]="0123456789ABCDEF";

	// Need to set up a fake current sbuf.
	init_sbuf(&cb);
	cb.cmd=p1b->cmd;
	cb.compression=p1b->compression;
	cb.path=strdup(p1b->path);
	cb.statbuf=strdup(p1b->statbuf);
	if(!(rpath=set_new_datapth(&cb, datadirtmp, dpth, &istreedata, cconf)))
	{
		ret=-1;
		goto end;
	}

	if(!(partialdir=prepend_s(datadirtmp, "p", strlen("p")))
	  || !(partial=prepend_s(partialdir,
		cb.datapth, strlen(cb.datapth)))
	  || build_path(partialdir, cb.datapth, strlen(cb.datapth),
		&partial, partialdir))
	{
		ret=-1;
		goto end;
	}

	if(!lstat(partial, &statp) && S_ISREG(statp.st_mode))
	{
		// A previous resume was going on.
		// Need to concatenate the possible delta onto the partial
		// file.
		FILE *dfp=NULL;
		gzFile dzp=NULL;
		logp("Resume previously resumed partial new file: %s %s\n",
			cb.path, rpath);

		if(!(cb.endfile=strdup(
			get_endfile_str(statp.st_size, checksum))))
		{
			ret=-1;
			goto end;
		}
		if(cb.compression)
		{
			// Recreate partial, in case it was only partially
			// written and consequently has gz errors.
			if(!(zdeltmp=prepend(deltmppath, ".z", strlen(".z"),
				0 /* no slash */))
			  || !(dzp=gzopen_file(zdeltmp, "wb"))
			  || copy_gzpath_to_gzFile(partial, dzp)
			  || do_rename(zdeltmp, partial))
			{
				ret=-1;
				goto end;
			}
		}
		else
		{
			// Just append to the existing one.
			if(!(dfp=open_file(partial, "ab")))
			{
				ret=-1;
				goto end;
			}
		}
		if(!lstat(deltmppath, &statp) && S_ISREG(statp.st_mode))
		{
			if(cb.compression)
			{
				if(copy_gzpath_to_gzFile(deltmppath, dzp))
				{
					ret=-1;
					goto end;
				}
			}
			else
			{
				if(copy_path_to_File(deltmppath, dfp))
				{
					ret=-1;
					goto end;
				}
			}
		}
		if(dfp && close_fp(&dfp))
		{
			ret=-1;
			goto end;
		}
		if(dzp && gzclose_fp(&dzp))
		{
			ret=-1;
			goto end;
		}
		if(process_changed_file(&cb, p1b, partialdir, NULL, NULL,
			&junk /* resume_partial=0 */,
			cntr, cconf))
		{
			ret=-1;
			goto end;
		}
		if(!istreedata) incr_dpth(dpth, cconf);

		goto end;
	}

	logp("Resume partial new file: %s %s\n", cb.path, rpath);
	if(!lstat(rpath, &statp) && S_ISREG(statp.st_mode))
	{
		if(!(cb.endfile=strdup(
			get_endfile_str(statp.st_size, checksum))))
		{
			ret=-1;
			goto end;
		}
		// If compression is on, be careful with gzip unexpected
		// end of file errors.
		// Otherwise, just rename the whole file.
		unlink(partial);
		if(cb.compression)
		{
			if(copy_gzpath_to_gzpath(rpath, partial))
			{
				logp("Error in copy_gzpath_to_gzpath\n");
				ret=-1;
				goto end;
			}
			// delete the original.
			if(unlink(rpath))
			{
				logp("Failed to unlink %s: %s\n",
					rpath, strerror(errno));
				return -1;
			}
		}
		else
		{
			if(do_rename(rpath, partial))
			{
				ret=-1;
				goto end;
			}
		}
		// So, we have created a new directory beginning with 'p',
		// and moved the partial download to it.
		// We can now use the partial file as the basis of a librsync
		// transfer.
		if(process_changed_file(&cb, p1b, partialdir, NULL, NULL,
			&junk /* resume_partial=0 */,
			cntr, cconf))
		{
			ret=-1;
			goto end;
		}
		if(!istreedata) incr_dpth(dpth, cconf);
		goto end;
	}

	logp("Actually, no - just treat it as completely new\n");
end:
	if(rpath) free(rpath);
	if(partialdir) free(partialdir);
	if(partial) free(partial);
	if(zdeltmp) free(zdeltmp);
	free_sbuf(&cb);
	return ret;
}