Esempio n. 1
0
int restore_sbuf_protocol1(struct asfd *asfd, struct sbuf *sb, struct bu *bu,
	enum action act, struct sdirs *sdirs,
	enum cntr_status cntr_status, struct conf **cconfs)
{
	if((sb->protocol1->datapth.buf
		&& asfd->write(asfd, &(sb->protocol1->datapth)))
	  || asfd->write(asfd, &sb->attr))
		return -1;
	else if(sbuf_is_filedata(sb)
	  || sbuf_is_vssdata(sb))
	{
		if(!sb->protocol1->datapth.buf)
		{
			logw(asfd, get_cntr(cconfs),
				"Got filedata entry with no datapth: %c:%s\n",
					sb->path.cmd, sb->path.buf);
			return 0;
		}
		return restore_file(asfd, bu, sb, act, sdirs, cconfs);
	}
	else
	{
		if(asfd->write(asfd, &sb->path))
			return -1;
		// If it is a link, send what
		// it points to.
		else if(sbuf_is_link(sb)
		  && asfd->write(asfd, &sb->link)) return -1;
		cntr_add(get_cntr(cconfs), sb->path.cmd, 0);
	}
	return 0;
}
Esempio n. 2
0
static int restore_sbuf(struct sbuf *sb, struct bu *arr, int a, int i, const char *tmppath1, const char *tmppath2, enum action act, const char *client, char status, struct cntr *p1cntr, struct cntr *cntr, struct config *cconf)
{
	//logp("%s: %s\n", act==ACTION_RESTORE?"restore":"verify", sb->path);
	write_status(client, status, sb->path, p1cntr, cntr);

	if((sb->datapth && async_write(CMD_DATAPTH,
		sb->datapth, strlen(sb->datapth)))
	  || async_write(CMD_STAT, sb->statbuf, sb->slen))
		return -1;
	else if(sb->cmd==CMD_FILE
	  || sb->cmd==CMD_ENC_FILE
	  || sb->cmd==CMD_METADATA
	  || sb->cmd==CMD_ENC_METADATA
	  || sb->cmd==CMD_EFS_FILE)
	{
		return restore_file(arr, a, i, sb->datapth,
		  sb->path, tmppath1, tmppath2, act,
		  sb->endfile, sb->cmd, sb->winattr, cntr, cconf);
	}
	else
	{
		if(async_write(sb->cmd, sb->path, sb->plen))
			return -1;
		// If it is a link, send what
		// it points to.
		else if(sbuf_is_link(sb))
		{
			if(async_write(sb->cmd, sb->linkto, sb->llen))
				return -1;
		}
		do_filecounter(cntr, sb->cmd, 0);
	}
	return 0;
}
Esempio n. 3
0
static int do_sbufl_fill_from_file(struct sbuf *sb, FILE *fp, gzFile zp,
	int phase1, struct cntr *cntr)
{
	int ars;
	struct iobuf rbuf;
	//free_sbufl(sb);
	iobuf_init(&rbuf);
	if((ars=read_stat(NULL /* no async */,
		&rbuf, fp, zp, sb, cntr))) return ars;
	if((ars=read_fp(fp, zp, &rbuf))) return ars;
	iobuf_copy(&sb->path, &rbuf);
	if(sbuf_is_link(sb))
	{
		if((ars=read_fp(fp, zp, &rbuf))) return ars;
		iobuf_copy(&sb->link, &rbuf);
		if(!cmd_is_link(rbuf.cmd))
			return unexpected(&rbuf, __func__);
	}
	else if(!phase1 && sbuf_is_filedata(sb))
	{
		if((ars=read_fp(fp, zp, &rbuf))) return ars;
		iobuf_copy(&(sb->burp1->endfile), &rbuf);
		if(!cmd_is_endfile(rbuf.cmd))
			return unexpected(&rbuf, __func__);
	}
	return 0;
}
Esempio n. 4
0
END_TEST

static void setup_proto2_some_things(struct asfd *asfd, struct slist *slist)
{
	struct sbuf *s;
	struct stat statp_dir;
	struct stat statp_file;
	int r=0; int w=0;
	fail_unless(!lstat(BASE, &statp_dir));
	fail_unless(!lstat(BASE "/burp.conf", &statp_file));
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore :");
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "ok");
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restore_stream");
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore_stream_ok");
	for(s=slist->head; s; s=s->next)
	{
		s->winattr=0;
		s->compression=0;
		if(s->path.cmd==CMD_DIRECTORY)
		{
			memcpy(&s->statp, &statp_dir, sizeof(statp_dir));
			attribs_encode(s);
		}
		if(sbuf_is_link(s))
		{
			char path[256];
			if(s->path.cmd==CMD_HARD_LINK)
				snprintf(path, sizeof(path), "%s", s->link.buf);
			else
			{
				char *cp;
				snprintf(path, sizeof(path), "%s", s->path.buf);
				fail_unless((cp=strrchr(path, '/'))!=NULL);
				cp++;
				snprintf(cp, strlen(s->link.buf)+1, "%s",
					s->link.buf);
			}
			build_file(path, NULL);
			
			memcpy(&s->statp, &statp_file, sizeof(statp_file));
			attribs_encode(s);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->attr);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->path);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->link);
		}
		else if(sbuf_is_filedata(s))
		{
			memcpy(&s->statp, &statp_file, sizeof(statp_file));
			attribs_encode(s);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->attr);
			asfd_mock_read_iobuf(asfd, &r,
				0, &s->path);
			asfd_mock_read(asfd, &r, 0, CMD_DATA, "data");
		}
	}
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend");
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend ok");
}
Esempio n. 5
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");
}
Esempio n. 6
0
static void setup_asfds_proto2_interrupt(struct asfd *asfd, struct slist *slist)
{
	int r=0; int w=0;
	struct sbuf *s;
	int count=0;
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore_stream");
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restore_stream_ok");
	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);
			asfd_mock_read_no_op(asfd, &r, 1);
		}
		else if(sbuf_is_filedata(s))
		{
			struct blk *b;
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
			asfd_mock_read_no_op(asfd, &r, 1);
			if(count++==1)
			{
				asfd_assert_write(asfd,
					&w, 0, CMD_DATA, "data");
				asfd_assert_write(asfd,
					&w, 0, CMD_DATA, "data");
				asfd_mock_read_no_op(asfd, &r, 2);
				asfd_mock_read(asfd, &r, 0, CMD_INTERRUPT,
					s->path.buf);
				asfd_assert_write(asfd, &w, 0,
					CMD_END_FILE, "0:0");
				continue;
			}
			for(b=s->protocol2->bstart;
				b && b!=s->protocol2->bend; b=b->next)
			{
				asfd_assert_write(asfd,
					&w, 0, CMD_DATA, "data");
				asfd_mock_read_no_op(asfd, &r, 1);
			}
			asfd_assert_write(asfd, &w, 0, CMD_END_FILE, "0:0");
			asfd_mock_read_no_op(asfd, &r, 1);
		}
		else
		{
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
			asfd_mock_read_no_op(asfd, &r, 1);
		}
	}
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend");
	asfd_mock_read_no_op(asfd, &r, 200);
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend_ok");
}
Esempio n. 7
0
static int restore_sbuf(struct asfd *asfd, struct sbuf *sb, enum action act,
	enum cstat_status status, struct conf *conf, int *need_data)
{
	//logp("%s: %s\n", act==ACTION_RESTORE?"restore":"verify", sb->path.buf);
	if(write_status(status, sb->path.buf, conf)) return -1;

	if(asfd->write(asfd, &sb->attr)
	  || asfd->write(asfd, &sb->path))
		return -1;
	if(sbuf_is_link(sb)
	  && asfd->write(asfd, &sb->link))
		return -1;

	if(sb->burp2->bstart)
	{
		// This will restore directory data on Windows.
		struct blk *b=NULL;
		struct blk *n=NULL;
		b=sb->burp2->bstart;
		while(b)
		{
			struct iobuf wbuf;
			iobuf_set(&wbuf, CMD_DATA, b->data, b->length);
			if(asfd->write(asfd, &wbuf)) return -1;
			n=b->next;
			blk_free(&b);
			b=n;
		}
		sb->burp2->bstart=sb->burp2->bend=NULL;
	}

	switch(sb->path.cmd)
	{
		case CMD_FILE:
		case CMD_ENC_FILE:
		case CMD_METADATA:
		case CMD_ENC_METADATA:
		case CMD_EFS_FILE:
			*need_data=1;
			return 0;
		default:
			cntr_add(conf->cntr, sb->path.cmd, 0);
			return 0;
	}
}
Esempio n. 8
0
static int do_sbufl_fill_from_net(struct sbuf *sb, struct asfd *asfd,
	struct cntr *cntr)
{
	int ars;
	static struct iobuf *rbuf=NULL;
	rbuf=asfd->rbuf;
	iobuf_free_content(rbuf);
	if((ars=read_stat(asfd, rbuf, NULL, NULL, sb, cntr))
	  || (ars=asfd->read(asfd))) return ars;
	iobuf_copy(&sb->path, rbuf);
	rbuf->buf=NULL;
	if(sbuf_is_link(sb))
	{
		if((ars=asfd->read(asfd))) return ars;
		iobuf_copy(&sb->link, rbuf);
		rbuf->buf=NULL;
		if(!cmd_is_link(rbuf->cmd))
			return unexpected(rbuf, __func__);
	}
	return 0;
}
Esempio n. 9
0
int restore_sbuf_protocol2(struct asfd *asfd, struct sbuf *sb, enum action act,
	struct cntr *cntr, struct sbuf *need_data)
{
	if(asfd->write(asfd, &sb->attr)
	  || asfd->write(asfd, &sb->path))
		return -1;
	if(sbuf_is_link(sb)
	  && asfd->write(asfd, &sb->link))
		return -1;

	if(sb->protocol2->bstart)
	{
		// This will restore directory data on Windows.
		struct blk *b=NULL;
		struct blk *n=NULL;
		b=sb->protocol2->bstart;
		while(b)
		{
			if(send_data(asfd, b, act, need_data, cntr))
				return -1;
			n=b->next;
			blk_free(&b);
			b=n;
		}
		sb->protocol2->bstart=sb->protocol2->bend=NULL;
	}

	if(sbuf_is_filedata(sb))
	{
		if(need_data)
		{
			iobuf_copy(&need_data->path, &sb->path);
			sb->path.buf=NULL;
		}
	}
	else
		cntr_add(cntr, sb->path.cmd, 0);
	return 0;
}
Esempio n. 10
0
END_TEST

static void setup_asfds_proto2_stuff(struct asfd *asfd, struct slist *slist)
{
	int r=0; int w=0;
	struct sbuf *s;
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore_stream");
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restore_stream_ok");
	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 blk *b;
			asfd_assert_write_iobuf(asfd, &w, 0, &s->attr);
			asfd_assert_write_iobuf(asfd, &w, 0, &s->path);
			for(b=s->protocol2->bstart;
			  b && b!=s->protocol2->bend; b=b->next)
				asfd_assert_write(asfd,
					&w, 0, CMD_DATA, "data");
			asfd_assert_write(asfd, &w, 0, CMD_END_FILE, "0:0");
		}
		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, 300);
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend_ok");
}
Esempio n. 11
0
static void setup_proto1_some_things(struct asfd *asfd, struct slist *slist)
{
	struct sbuf *s;
	struct stat statp_dir;
	struct stat statp_file;
	int r=0; int w=0;
	fail_unless(!lstat(BASE, &statp_dir));
	fail_unless(!lstat(BASE "/burp.conf", &statp_file));
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restore :");
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "ok");
	for(s=slist->head; s; s=s->next)
	{
		s->winattr=0;
		s->compression=0;
		if(s->path.cmd==CMD_DIRECTORY)
		{
			memcpy(&s->statp, &statp_dir, sizeof(statp_dir));
			attribs_encode(s);
		}
		if(sbuf_is_link(s))
		{
			char path[256];
			if(s->path.cmd==CMD_HARD_LINK)
				snprintf(path, sizeof(path), "%s", s->link.buf);
			else
			{
				char *cp;
				snprintf(path, sizeof(path), "%s", s->path.buf);
				fail_unless((cp=strrchr(path, '/'))!=NULL);
				cp++;
				snprintf(cp, strlen(s->link.buf)+1, "%s",
					s->link.buf);
			}
			build_file(path, NULL);
			
			memcpy(&s->statp, &statp_file, sizeof(statp_file));
			attribs_encode(s);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->attr);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->path);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->link);
		}
		else if(sbuf_is_filedata(s))
		{
			struct iobuf rbuf;
			// The string "data" gzipped.
			unsigned char gzipped_data[27] = {
				0x1f, 0x8b, 0x08, 0x08, 0xb4, 0x1e, 0x7f, 0x56,
				0x00, 0x03, 0x79, 0x00, 0x4b, 0x49, 0x2c, 0x49,
				0xe4, 0x02, 0x00, 0x82, 0xc5, 0xc1, 0xe6, 0x05,
				0x00, 0x00, 0x00
			};
			memcpy(&s->statp, &statp_file, sizeof(statp_file));
			attribs_encode(s);
			asfd_mock_read(asfd, &r,
				0, CMD_DATAPTH, s->path.buf);
			asfd_mock_read_iobuf(asfd, &r, 0, &s->attr);
			asfd_mock_read_iobuf(asfd, &r,
				0, &s->path);
			// Protocol1 always sends it gzipped.
			iobuf_set(&rbuf, CMD_APPEND,
				(char *)gzipped_data, sizeof(gzipped_data));
			asfd_mock_read_iobuf(asfd, &r, 0, &rbuf);
			asfd_mock_read(asfd, &r,
				0, CMD_END_FILE, "0:19201273128");
		}
	}
	asfd_mock_read(asfd, &r, 0, CMD_GEN, "restoreend");
	asfd_assert_write(asfd, &w, 0, CMD_GEN, "restoreend ok");
}
Esempio n. 12
0
static int list_manifest(struct asfd *asfd,
	const char *fullpath, regex_t *regex,
	const char *browsedir, struct conf *conf)
{
	int ars=0;
	int ret=0;
	struct sbuf *sb=NULL;
	struct manio *manio=NULL;
	char *manifest_dir=NULL;
	char *last_bd_match=NULL;
	size_t bdlen=0;

	if(!(manifest_dir=prepend_s(fullpath,
		conf->protocol==PROTO_BURP1?"manifest.gz":"manifest"))
	  || !(manio=manio_alloc())
	  || manio_init_read(manio, manifest_dir)
	  || !(sb=sbuf_alloc(conf)))
	{
		log_and_send_oom(asfd, __func__);
		goto error;
	}
	manio_set_protocol(manio, conf->protocol);

	if(browsedir) bdlen=strlen(browsedir);

	while(1)
	{
		int show=0;

		if((ars=manio_sbuf_fill(manio, asfd, sb, NULL, NULL, conf))<0)
			goto error;
		else if(ars>0)
			goto end; // Finished OK.

		if(write_status(STATUS_LISTING, sb->path.buf, conf))
			goto error;

		if(browsedir)
		{
			int r;
			if((r=check_browsedir(browsedir,
				&sb->path.buf, bdlen, &last_bd_match))<0)
					goto error;
			if(!r) continue;
			show++;
		}
		else
		{
			if(check_regex(regex, sb->path.buf))
				show++;
		}
		if(show)
		{
			if(write_wrapper(asfd, &sb->attr)
			  || write_wrapper(asfd, &sb->path))
				goto error;
			if(sbuf_is_link(sb)
			  && write_wrapper(asfd, &sb->link))
				goto error;
		}

		sbuf_free_content(sb);
	}

error:
	ret=-1;
end:
	sbuf_free(&sb);
	free_w(&manifest_dir);
	manio_free(&manio);
	free_w(&last_bd_match);
	return ret;
}
Esempio n. 13
0
static int list_manifest(const char *fullpath, regex_t *regex, const char *browsedir, const char *client, struct cntr *p1cntr, struct cntr *cntr)
{
	int ars=0;
	int ret=0;
	int quit=0;
	gzFile zp=NULL;
	struct sbuf mb;
	char *manifest=NULL;
	size_t bdlen=0;

	init_sbuf(&mb);

	if(!(manifest=prepend_s(fullpath,
		"manifest.gz", strlen("manifest.gz"))))
	{
		log_and_send_oom(__FUNCTION__);
		return -1;
	}
	if(!(zp=gzopen_file(manifest, "rb")))
	{
		log_and_send("could not open manifest");
		free(manifest);
		return -1;
	}
	free(manifest);

	if(browsedir) bdlen=strlen(browsedir);

	while(!quit)
	{
		int show=0;
		//logp("list manifest loop\n");
		// Need to parse while sending, to take note of the regex.

		free_sbuf(&mb);
		if((ars=sbuf_fill(NULL, zp, &mb, cntr)))
		{
			if(ars<0) ret=-1;
			// ars==1 means it ended ok.
			break;
		}

		if(mb.cmd!=CMD_DIRECTORY
		 && mb.cmd!=CMD_FILE
		 && mb.cmd!=CMD_ENC_FILE
		 && mb.cmd!=CMD_EFS_FILE
		 && mb.cmd!=CMD_SPECIAL
		 && !cmd_is_link(mb.cmd))
			continue;

		//if(mb.path[mb.plen]=='\n') mb.path[mb.plen]='\0';
		write_status(client, STATUS_LISTING, mb.path, p1cntr, cntr);

		if(browsedir)
		{
			int r;
			if((r=check_browsedir(browsedir, &(mb.path), bdlen))<0)
			{
				quit++;
				ret=-1;
			}
			if(!r) continue;
			show++;
		}
		else
		{
			if(check_regex(regex, mb.path))
				show++;
		}
		if(show)
		{
			if(async_write(CMD_STAT, mb.statbuf, mb.slen)
			  || async_write(mb.cmd, mb.path, mb.plen))
			{ quit++; ret=-1; }
			else if(sbuf_is_link(&mb)
			  && async_write(mb.cmd, mb.linkto, mb.llen))
			{ quit++; ret=-1; }
		}
	}
	gzclose_fp(&zp);
	free_sbuf(&mb);
	return ret;
}
Esempio n. 14
0
File: list.c Progetto: ZungBang/burp
static int list_manifest(const char *fullpath)
{
    int ret=0;
    struct sbuf *sb=NULL;
    struct manio *manio=NULL;
    char *manifest_dir=NULL;
    char *last_bd_match=NULL;
    size_t bdlen=0;

    if(!(manifest_dir=prepend_s(fullpath,
                                protocol==PROTO_1?"manifest.gz":"manifest"))
            || !(manio=manio_open(manifest_dir, "rb", protocol))
            || !(sb=sbuf_alloc(protocol)))
    {
        log_and_send_oom(asfd);
        goto error;
    }

    if(browsedir) bdlen=strlen(browsedir);

    while(1)
    {
        sbuf_free_content(sb);

        switch(manio_read(manio, sb))
        {
        case 0:
            break;
        case 1:
            if(browsedir && *browsedir && !last_bd_match)
                asfd_write_wrapper_str(asfd,
                                       CMD_ERROR,
                                       "directory not found");
            goto end; // Finished OK.
        default:
            goto error;
        }

        if(protocol==PROTO_2 && sb->endfile.buf)
            continue;
        if(sbuf_is_metadata(sb))
            continue;

        if(write_status(CNTR_STATUS_LISTING, sb->path.buf, cntr))
            goto error;

        if(browsedir)
        {
            int r;
            if((r=check_browsedir(browsedir,
                                  sb, bdlen, &last_bd_match))<0)
                goto error;
            if(!r) continue;
        }

        if(regex && !regex_check(regex, sb->path.buf))
            continue;

        if(asfd_write_wrapper(asfd, &sb->attr)
                || asfd_write_wrapper(asfd, &sb->path))
            goto error;
        if(sbuf_is_link(sb)
                && asfd_write_wrapper(asfd, &sb->link))
            goto error;
    }

error:
    ret=-1;
end:
    sbuf_free(&sb);
    free_w(&manifest_dir);
    manio_close(&manio);
    free_w(&last_bd_match);
    return ret;
}