示例#1
0
文件: msg.c 项目: pkdevbox/burp
int send_msg_fzp(struct fzp *fzp, enum cmd cmd, const char *buf, size_t s)
{
	if(fzp_printf(fzp, "%c%04X", cmd, (unsigned int)s)!=5
	  || fzp_write(fzp, buf, s)!=s
	  || fzp_printf(fzp, "\n")!=1)
	{
		logp("Unable to write message to file: %s\n", strerror(errno));
		return -1;
	}
	return 0;
}
示例#2
0
void logp(const char *fmt, ...)
{
#ifndef UTEST
	int pid;
	char buf[512]="";
	va_list ap;
	va_start(ap, fmt);
	vsnprintf(buf, sizeof(buf), fmt, ap);
	pid=(int)getpid();
	if(logfzp)
		fzp_printf(logfzp, "%s: %s[%d] %s", gettm(), prog, pid, buf);
	else
	{
		if(do_syslog)
			syslog(LOG_INFO, "%s", buf);
		if(do_stdout)
		{
			if(json)
			{
				char *cp=NULL;
				if((cp=strrchr(buf, '\n'))) *cp='\0';
				// To help programs parsing the monitor output,
				// log things with simple JSON.
				fprintf(stdout, "{ \"logline\": \"%s\" }\n", buf);
			}
			else
				fprintf(stdout, "%s: %s[%d] %s",
					gettm(), prog, pid, buf);
		}
	}
	va_end(ap);
#endif
}
示例#3
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;
}
示例#4
0
static int gzprintf_hooks(struct fzp *fzp, struct hooks *hooks)
{
	size_t i;
	fzp_printf(fzp, "%c%04lX%s\n", CMD_MANIFEST,
		strlen(hooks->path), hooks->path);
	for(i=0; i<hooks->len; i++)
		if(to_fzp_fingerprint(fzp, hooks->fingerprints[i]))
			return -1;
	return 0;
}
示例#5
0
static int gzprintf_hooks(struct fzp *fzp, struct hooks *hooks)
{
	static char *f;
	static char ftmp[WEAK_STR_LEN];
	size_t len=strlen(hooks->fingerprints);

//	printf("NW: %c%04lX%s\n", CMD_MANIFEST,
//		strlen(hooks->path), hooks->path);
	// FIX THIS: The path could be long, and fzp_printf will truncate at
	// 512 characters.
	fzp_printf(fzp, "%c%04lX%s\n", CMD_MANIFEST,
		strlen(hooks->path), hooks->path);
	for(f=hooks->fingerprints; f<hooks->fingerprints+len; f+=WEAK_LEN)
	{
		snprintf(ftmp, sizeof(ftmp), "%s", f);
		fzp_printf(fzp, "%c%04lX%s\n", CMD_FINGERPRINT,
			strlen(ftmp), ftmp);
	}
	return 0;
}
示例#6
0
static int write_hook_header(struct manio *manio,
	struct fzp *fzp, const char *comp)
{
	const char *cp;
	char *tmp=NULL;
	cp=manio->rdirectory+strlen(manio->base_dir);
	while(cp && *cp=='/') cp++;
	if(!(tmp=prepend_s(cp, comp))) return -1;
	// FIX THIS: fzp_printf will truncate at 512 characters.
	fzp_printf(fzp, "%c%04X%s\n", CMD_MANIFEST, strlen(tmp), tmp);
	free_w(&tmp);
	return 0;
}
示例#7
0
// For the counters.
void logc(const char *fmt, ...)
{
	char buf[512]="";
	va_list ap;
	va_start(ap, fmt);
	vsnprintf(buf, sizeof(buf), fmt, ap);
	if(logfzp)
		fzp_printf(logfzp, "%s", buf); // for the server side
	else
	{
		if(do_progress_counter
		  && do_stdout)
			fprintf(stdout, "%s", buf);
	}
	va_end(ap);
}
示例#8
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));
}
示例#9
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;
}
示例#10
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;
}
示例#11
0
文件: manio.c 项目: pkdevbox/burp
// 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;
}
示例#12
0
int backup_phase4_server_protocol1(struct sdirs *sdirs, struct conf **cconfs)
{
	int ret=-1;
	struct stat statp;
	char realcurrent[256]="";
	uint64_t bno=0;
	int hardlinked_current=0;
	char tstmp[64]="";
	int previous_backup=0;
	struct fdirs *fdirs=NULL;

	readlink_w(sdirs->current, realcurrent, sizeof(realcurrent));

	if(!(fdirs=fdirs_alloc())
	  || fdirs_init(fdirs, sdirs, realcurrent))
		goto end;

	if(log_fzp_set(fdirs->logpath, cconfs))
		goto end;

	logp("Begin phase4 (shuffle files)\n");

	if(write_status(CNTR_STATUS_SHUFFLING, NULL, get_cntr(cconfs)))
		goto end;

	if(!lstat(sdirs->current, &statp)) // Had a previous backup.
	{
		previous_backup++;

		if(lstat(fdirs->hlinkedcurrent, &statp))
		{
			hardlinked_current=0;
			logp("Previous backup is not a hardlinked_archive\n");
			logp(" will generate reverse deltas\n");
		}
		else
		{
			hardlinked_current=1;
			logp("Previous backup is a hardlinked_archive\n");
			logp(" will not generate reverse deltas\n");
		}

		// If current was not a hardlinked_archive, need to duplicate
		// it.
		if(!hardlinked_current && lstat(fdirs->currentdup, &statp))
		{
			// Have not duplicated the current backup yet.
			if(!lstat(fdirs->currentduptmp, &statp))
			{
				logp("Removing previous directory: %s\n",
					fdirs->currentduptmp);
				if(recursive_delete(fdirs->currentduptmp))
				{
					logp("Could not delete %s\n",
						fdirs->currentduptmp);
					goto end;
				}
			}
			logp("Duplicating current backup.\n");
			if(recursive_hardlink(sdirs->current,
				fdirs->currentduptmp, cconfs)
			// The rename race condition is of no consequence here
			// because currentdup does not exist.
			  || do_rename(fdirs->currentduptmp, fdirs->currentdup))
				goto end;
		}
	}

	if(timestamp_read(fdirs->timestamp, tstmp, sizeof(tstmp)))
	{
		logp("could not read timestamp file: %s\n",
			fdirs->timestamp);
		goto end;
	}
	// Get the backup number.
	bno=strtoull(tstmp, NULL, 10);

	// Determine whether the new backup should be a hardlinked
	// archive or not, from the confs and the backup number...
	if(need_hardlinked_archive(cconfs, bno))
	{
		// Create a file to indicate that the previous backup
		// does not have others depending on it.
		struct fzp *hfp=NULL;
		if(!(hfp=fzp_open(fdirs->hlinked, "wb"))) goto end;

		// Stick the next backup timestamp in it. It might
		// be useful one day when wondering when the next
		// backup, now deleted, was made.
		fzp_printf(hfp, "%s\n", tstmp);
		if(fzp_close(&hfp))
		{
			logp("error closing hardlinked indication\n");
			goto end;
		}
	}
	else
		unlink(fdirs->hlinked);

	if(atomic_data_jiggle(sdirs, fdirs, hardlinked_current, cconfs))
	{
		logp("could not finish up backup.\n");
		goto end;
	}

	if(write_status(CNTR_STATUS_SHUFFLING,
		"deleting temporary files", get_cntr(cconfs)))
			goto end;

	// Remove the temporary data directory, we have now removed
	// everything useful from it.
	recursive_delete(fdirs->datadirtmp);

	// Clean up the currentdata directory - this is now the 'old'
	// currentdata directory. Any files that were deleted from
	// the client will be left in there, so call recursive_delete
	// with the option that makes it not delete files.
	// This will have the effect of getting rid of unnecessary
	// directories.
	recursive_delete_dirs_only(fdirs->currentdupdata);

	// Rename the old current to something that we know to delete.
	if(previous_backup && !hardlinked_current)
	{
		if(deleteme_move(sdirs,
			fdirs->fullrealcurrent, realcurrent, cconfs)
		// I have tested that potential race conditions on the
		// rename() are automatically recoverable here.
		  || do_rename(fdirs->currentdup, fdirs->fullrealcurrent))
			goto end;
	}

	if(deleteme_maybe_delete(cconfs, sdirs))
		goto end;

	logp("End phase4 (shuffle files)\n");

	ret=0;
end:
	fdirs_free(&fdirs);
	return ret;
}