コード例 #1
0
ファイル: vfspath.c プロジェクト: argsno/ucore_os_plus
/*
 * Get current directory, as a pathname.
 * Use vop_namefile to get the pathname.
 */
int vfs_getcwd(struct iobuf *iob)
{
    int ret;
    struct inode *node;
    if ((ret = vfs_get_curdir(&node)) != 0) {
        return ret;
    }
    /* The current dir must be a directory, and thus it is not a device. */
    assert(node->in_fs != NULL);

    const char *devname = vfs_get_devname(node->in_fs);
    if ((ret =
                iobuf_move(iob, (char *)devname, strlen(devname), 1, NULL)) != 0) {
        goto out;
    }
    char colon = ':';
    if ((ret = iobuf_move(iob, &colon, sizeof(colon), 1, NULL)) != 0) {
        goto out;
    }
    ret = vop_namefile(node, iob);

out:
    vop_ref_dec(node);
    return ret;
}
コード例 #2
0
ファイル: sfs_inode.c プロジェクト: Aureate-Sunshine/ucore
/*
 * sfs_getdirentry - according to the iob->io_offset, calculate the dir entry's slot in disk block,
                     get dir entry content from the disk
 */
static int
sfs_getdirentry(struct inode *node, struct iobuf *iob) {
    struct sfs_disk_entry *entry;
    if ((entry = kmalloc(sizeof(struct sfs_disk_entry))) == NULL) {
        return -E_NO_MEM;
    }

    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);

    int ret, slot;
    off_t offset = iob->io_offset;
    if (offset < 0 || offset % sfs_dentry_size != 0) {
        kfree(entry);
        return -E_INVAL;
    }
    if ((slot = offset / sfs_dentry_size) > sin->din->blocks) {
        kfree(entry);
        return -E_NOENT;
    }
    lock_sin(sin);
    if ((ret = sfs_getdirentry_sub_nolock(sfs, sin, slot, entry)) != 0) {
        unlock_sin(sin);
        goto out;
    }
    unlock_sin(sin);
    ret = iobuf_move(iob, entry->name, sfs_dentry_size, 1, NULL);
out:
    kfree(entry);
    return ret;
}
コード例 #3
0
ファイル: backup_phase2.c プロジェクト: EmisFR/burp
static int set_up_for_sig_info(struct slist *slist, struct iobuf *attr,
	uint64_t index)
{
	struct sbuf *sb;

	for(sb=slist->add_sigs_here; sb; sb=sb->next)
	{
		if(!sb->protocol2->index)
			continue;
		if(index==sb->protocol2->index)
			break;
	}
	if(!sb)
	{
		logp("Could not find %" PRIu64 " in request list\n", index);
		return -1;
	}
	// Replace the attribs with the more recent values.
	iobuf_free_content(&sb->attr);
	iobuf_move(&sb->attr, attr);

	// Mark the end of the previous file.
	slist->add_sigs_here->protocol2->bend=slist->blist->tail;

	slist->add_sigs_here=sb;

	// Incoming sigs now need to get added to 'add_sigs_here'
	return 0;
}
コード例 #4
0
ファイル: backup_phase2.c プロジェクト: adrianimboden/burp
static int deal_with_filedata(struct asfd *asfd,
	struct sdirs *sdirs, struct sbuf *rb,
	struct iobuf *rbuf, struct dpth *dpth, struct conf **cconfs)
{
	iobuf_move(&rb->path, rbuf);

	if(rb->protocol1->datapth.buf)
	{
		// Receiving a delta.
		if(start_to_receive_delta(sdirs, cconfs, rb))
		{
			logp("error in start_to_receive_delta\n");
			return -1;
		}
		return 0;
	}

	// Receiving a whole new file.
	if(start_to_receive_new_file(asfd, sdirs, cconfs, rb, dpth))
	{
		logp("error in start_to_receive_new_file\n");
		return -1;
	}
	return 0;
}
コード例 #5
0
ファイル: dev_disk0.c プロジェクト: spinlock/ucore
static int
disk0_io(struct device *dev, struct iobuf *iob, bool write) {
    off_t offset = iob->io_offset;
    size_t resid = iob->io_resid;
    uint32_t blkno = offset / DISK0_BLKSIZE;
    uint32_t nblks = resid / DISK0_BLKSIZE;

    /* don't allow I/O that isn't block-aligned */
    if ((offset % DISK0_BLKSIZE) != 0 || (resid % DISK0_BLKSIZE) != 0) {
        return -E_INVAL;
    }

    /* don't allow I/O past the end of disk0 */
    if (blkno + nblks > dev->d_blocks) {
        return -E_INVAL;
    }

    /* read/write nothing ? */
    if (nblks == 0) {
        return 0;
    }

    lock_disk0();
    while (resid != 0) {
        size_t copied, alen = DISK0_BUFSIZE;
        if (write) {
            iobuf_move(iob, disk0_buffer, alen, 0, &copied);
            assert(copied != 0 && copied <= resid && copied % DISK0_BLKSIZE == 0);
            nblks = copied / DISK0_BLKSIZE;
            disk0_write_blks_nolock(blkno, nblks);
        }
        else {
            if (alen > resid) {
                alen = resid;
            }
            nblks = alen / DISK0_BLKSIZE;
            disk0_read_blks_nolock(blkno, nblks);
            iobuf_move(iob, disk0_buffer, alen, 1, &copied);
            assert(copied == alen && copied % DISK0_BLKSIZE == 0);
        }
        resid -= copied, blkno += nblks;
    }
    unlock_disk0();
    return 0;
}
コード例 #6
0
ファイル: backup_phase2.c プロジェクト: adrianimboden/burp
static int process_unchanged_file(struct sbuf *p1b, struct sbuf *cb,
	struct fzp *ucfp, struct conf **cconfs)
{
	// Need to re-encode the p1b attribs to include compression and
	// other bits and pieces that are recorded on cb.
	iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);
	iobuf_move(&p1b->protocol1->endfile, &cb->protocol1->endfile);
	p1b->compression=cb->compression;
	if(attribs_encode(p1b))
		return -1;
	if(sbufl_to_manifest(p1b, ucfp))
		return -1;
	cntr_add_same(get_cntr(cconfs[OPT_CNTR]), p1b->path.cmd);
	if(p1b->protocol1->endfile.buf) cntr_add_bytes(
		get_cntr(cconfs[OPT_CNTR]),
		 strtoull(p1b->protocol1->endfile.buf, NULL, 10));
	sbuf_free_content(cb);
	return 1;
}
コード例 #7
0
ファイル: backup_phase2.c プロジェクト: pablodav/burp
static int add_to_file_requests(struct slist *slist, struct iobuf *rbuf)
{
	static uint64_t file_no=1;
	struct sbuf *sb;

	if(!(sb=sbuf_alloc(PROTO_2))) return -1;

	iobuf_move(&sb->path, rbuf);
	// Give it a number to simplify tracking.
	sb->protocol2->index=file_no++;
	slist_add_sbuf(slist, sb);

	return 0;
}
コード例 #8
0
ファイル: build_manifest.c プロジェクト: grke/burp
void build_manifest_phase1_from_slist(const char *path,
	struct slist *slist, enum protocol protocol)
{
	struct sbuf *sb;
	struct manio *manio=NULL;
	struct iobuf datapth;
	struct iobuf endfile;
	iobuf_init(&datapth);
	iobuf_init(&endfile);

	for(sb=slist->head; sb; sb=sb->next)
		set_sbuf(slist, sb, 0 /* with_data_files */);

	fail_unless((manio=manio_open_phase1(path, "wb", protocol))!=NULL);

	for(sb=slist->head; sb; sb=sb->next)
	{
		// Might be given an slist that has datapth or endfile set,
		// which should not go into a phase1 scan. Deal with it.
		if(sb->protocol1
		  && sb->protocol1->datapth.buf)
			iobuf_move(&datapth, &sb->protocol1->datapth);
		if(sb->endfile.buf)
			iobuf_move(&endfile, &sb->endfile);
		fail_unless(!manio_write_sbuf(manio, sb));
		if(datapth.buf)
			iobuf_move(&sb->protocol1->datapth, &datapth);
		if(endfile.buf)
			iobuf_move(&sb->endfile, &endfile);
	}

	fail_unless(!send_msg_fzp(manio->fzp,
		CMD_GEN, "phase1end", strlen("phase1end")));

	fail_unless(!manio_close(&manio));
}
コード例 #9
0
ファイル: backup_phase2.c プロジェクト: adrianimboden/burp
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
	struct sbuf *rb, struct fzp *chfp, struct conf **cconfs,
	char **last_requested)
{
	static char *cp=NULL;
	static struct iobuf *rbuf;
	rbuf=asfd->rbuf;
	// Finished the file.
	// Write it to the phase2 file, and free the buffers.

	if(fzp_close(&(rb->protocol1->fzp)))
	{
		logp("error closing delta for %s in receive\n", rb->path);
		goto error;
	}
	iobuf_move(&rb->protocol1->endfile, rbuf);
	if(rb->flags & SBUFL_RECV_DELTA && finish_delta(sdirs, rb))
		goto error;

	if(sbufl_to_manifest(rb, chfp))
		goto error;

	if(rb->flags & SBUFL_RECV_DELTA)
		cntr_add_changed(get_cntr(cconfs[OPT_CNTR]), rb->path.cmd);
	else
		cntr_add(get_cntr(cconfs[OPT_CNTR]), rb->path.cmd, 0);

	if(*last_requested && !strcmp(rb->path.buf, *last_requested))
	{
		free(*last_requested);
		*last_requested=NULL;
	}

	cp=strchr(rb->protocol1->endfile.buf, ':');
	if(rb->protocol1->endfile.buf)
		cntr_add_bytes(get_cntr(cconfs[OPT_CNTR]),
			strtoull(rb->protocol1->endfile.buf, NULL, 10));
	if(cp)
	{
		// checksum stuff goes here
	}

	sbuf_free_content(rb);
	return 0;
error:
	sbuf_free_content(rb);
	return -1;
}
コード例 #10
0
ファイル: backup_phase2.c プロジェクト: EmisFR/burp
static int deal_with_receive_end_file(struct asfd *asfd, struct sdirs *sdirs,
	struct sbuf *rb, struct manio *chmanio, struct conf **cconfs,
	char **last_requested)
{
	int ret=-1;
	static char *cp=NULL;
	static struct iobuf *rbuf;
	struct cntr *cntr=get_cntr(cconfs);
	rbuf=asfd->rbuf;
	// Finished the file.
	// Write it to the phase2 file, and free the buffers.

	if(fzp_close(&(rb->protocol1->fzp)))
	{
		logp("error closing delta for %s in receive\n", rb->path.buf);
		goto end;
	}
	iobuf_move(&rb->endfile, rbuf);
	if(rb->flags & SBUF_RECV_DELTA && finish_delta(sdirs, rb))
		goto end;

	if(manio_write_sbuf(chmanio, rb))
		goto end;

	if(rb->flags & SBUF_RECV_DELTA)
		cntr_add_changed(cntr, rb->path.cmd);
	else
		cntr_add(cntr, rb->path.cmd, 0);

	if(*last_requested && !strcmp(rb->path.buf, *last_requested))
		free_w(last_requested);

	cp=strchr(rb->endfile.buf, ':');
	if(rb->endfile.buf)
		cntr_add_bytes(cntr, strtoull(rb->endfile.buf, NULL, 10));
	if(cp)
	{
		// checksum stuff goes here
	}

	ret=0;
end:
	sbuf_free_content(rb);
	return ret;
}
コード例 #11
0
ファイル: rblk.c プロジェクト: EmisFR/burp
static int load_rblk(struct rblk *rblks, int ind, const char *datpath)
{
	int r;
	int ret=-1;
	int done=0;
	struct fzp *fzp=NULL;
	struct iobuf rbuf;

	iobuf_init(&rbuf);

	free_w(&rblks[ind].datpath);
	if(!(rblks[ind].datpath=strdup_w(datpath, __func__)))
		goto end;

	logp("swap %d to: %s\n", ind, datpath);

	if(!(fzp=fzp_open(datpath, "rb")))
		goto end;
	for(r=0; r<DATA_FILE_SIG_MAX; r++)
	{
		switch(iobuf_fill_from_fzp_data(&rbuf, fzp))
		{
			case 0: if(rbuf.cmd!=CMD_DATA)
				{
					logp("unknown cmd in %s: %c\n",
						__func__, rbuf.cmd);
					goto end;
				}
				iobuf_free_content(&rblks[ind].readbuf[r]);
				iobuf_move(&rblks[ind].readbuf[r], &rbuf);
				continue;
			case 1: done++;
				break;
			default: goto end;
		}
		if(done) break;
	}
	rblks[ind].readbuflen=r;
	ret=0;
end:
	fzp_close(&fzp);
	return ret;
}
コード例 #12
0
ファイル: sfs_inode.c プロジェクト: geraint0923/ucore_plus
static int
sfs_getdirentry(struct inode *node, struct iobuf *iob) {
    struct sfs_disk_entry *entry;
    if ((entry = kmalloc(sizeof(struct sfs_disk_entry))) == NULL) {
        return -E_NO_MEM;
    }

    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);

    off_t offset = iob->io_offset;
    if (offset < 0 || offset % sfs_dentry_size != 0) {
        kfree(entry);
        return -E_INVAL;
    }

    int ret, slot = offset / sfs_dentry_size;
    if (slot >= sin->din->dirinfo.slots + 2) {
        kfree(entry);
        return -E_NOENT;
    }
    switch (slot) {
    case 0:
        strcpy(entry->name, ".");
        break;
    case 1:
        strcpy(entry->name, "..");
        break;
    default:
        if ((ret = trylock_sin(sin)) != 0) {
            goto out;
        }
        ret = sfs_getdirentry_sub_nolock(sfs, sin, slot - 2, entry);
        unlock_sin(sin);
        if (ret != 0) {
            goto out;
        }
    }
    ret = iobuf_move(iob, entry->name, sfs_dentry_size, 1, NULL);
out:
    kfree(entry);
    return ret;
}
コード例 #13
0
ファイル: build_asfd_mock.c プロジェクト: Lacoste/burp
static int mock_asfd_read(struct asfd *asfd)
{
	struct ioevent *r;
	struct ioevent_list *reads=(struct ioevent_list *)asfd->data1;

//printf("r %s %d %d\n", asfd->desc, reads->cursor, reads->size);
	fail_unless(reads->cursor<reads->size);

	r=&reads->ioevent[reads->cursor];
	if(r->no_op)
	{
		r->no_op--;
		if(!r->no_op)
			reads->cursor++;
		return r->ret;
	}
//printf("r %s - %c:%s\n", asfd->desc, r->iobuf.cmd, r->iobuf.buf);
	iobuf_move(asfd->rbuf, &r->iobuf);
	reads->cursor++;
	return r->ret;
}
コード例 #14
0
static int
sfs_getdirentry(struct inode *node, struct iobuf *iob) {
    struct sfs_disk_entry *entry;
    if ((entry = kmalloc(sizeof(struct sfs_disk_entry))) == NULL) {
        // kprintf("%s %s %d -E_NO_MEM\n", __FILE__, __func__, __LINE__);
        return -E_NO_MEM;
    }

    struct sfs_fs *sfs = fsop_info(vop_fs(node), sfs);
    struct sfs_inode *sin = vop_info(node, sfs_inode);

    int ret, slot;
    off_t offset = iob->io_offset;
    if (offset < 0 || offset % sfs_dentry_size != 0) {
        // kprintf("%s %s %d -E_INVAL\n", __FILE__, __func__, __LINE__);
        kfree(entry);
        return -E_INVAL;
    }
    if ((slot = offset / sfs_dentry_size) > sin->din->blocks) {
        // kprintf("%s %s %d -E_NOENT\n", __FILE__, __func__, __LINE__);
        kfree(entry);
        return -E_NOENT;
    }
    lock_sin(sin);
    if ((ret = sfs_getdirentry_sub_nolock(sfs, sin, slot, entry)) != 0) {
        unlock_sin(sin);
        // kprintf("%s %s %d can not find!!! slot is %d\n", __FILE__, __func__, __LINE__, slot);
        goto out;
    }
    unlock_sin(sin);
    // kprintf("sfs_getdirentry\n");
    ret = iobuf_move(iob, entry->name, sfs_dentry_size, 1, NULL);
out:
    kfree(entry);
    return ret;
}
コード例 #15
0
ファイル: backup_phase2.c プロジェクト: EmisFR/burp
static int deal_with_read(struct iobuf *rbuf, struct slist *slist,
	struct cntr *cntr, uint8_t *end_flags, struct dpth *dpth)
{
	int ret=0;

	switch(rbuf->cmd)
	{
		/* Incoming block data. */
		case CMD_DATA:
			if(add_data_to_store(cntr, slist, rbuf, dpth))
				goto error;
			goto end;

		/* Incoming block signatures. */
		case CMD_ATTRIBS_SIGS:
			static struct iobuf attr;
			static uint64_t index;

			iobuf_init(&attr);
			iobuf_move(&attr, rbuf);
			index=decode_file_no(&attr);

			// Need to go through slist to find the matching
			// entry.
			if(set_up_for_sig_info(slist, &attr, index))
				goto error;
			return 0;
		case CMD_SIG:
			if(add_to_sig_list(slist, rbuf))
				goto error;
			goto end;

		/* Incoming control/message stuff. */
		case CMD_MESSAGE:
		case CMD_WARNING:
		{
			struct cntr *cntr=NULL;
			log_recvd(rbuf, cntr, 0);
			goto end;
		}
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "sigs_end"))
			{
				(*end_flags)|=END_SIGS;
				goto end;
			}
			else if(!strcmp(rbuf->buf, "backup_end"))
			{
				(*end_flags)|=END_BACKUP;
				goto end;
			}
			break;
		case CMD_INTERRUPT:
		{
			uint64_t file_no;
			file_no=base64_to_uint64(rbuf->buf);
			if(slist_del_sbuf_by_index(slist, file_no))
				goto error;
			goto end;
		}
		default:
			break;
	}

	iobuf_log_unexpected(rbuf, __func__);
error:
	ret=-1;
end:
	iobuf_free_content(rbuf);
	return ret;
}
コード例 #16
0
ファイル: sbuf.c プロジェクト: pablodav/burp
static enum parse_ret parse_cmd(struct sbuf *sb, struct asfd *asfd,
	struct iobuf *rbuf, struct blk *blk, struct cntr *cntr)
{
	switch(rbuf->cmd)
	{
		case CMD_ATTRIBS:
			if(sb->protocol2)
				sbuf_free_content(sb);
			else
			{
				if(sb->protocol1->datapth.buf)
					// protocol 1 phase 2+ file data
					// starts with datapth.
					iobuf_free_content(&sb->attr);
				else
					// protocol 1 phase 1 or non file data
					// starts with attribs
					sbuf_free_content(sb);
			}
			iobuf_move(&sb->attr, rbuf);
			attribs_decode(sb);
			return PARSE_RET_NEED_MORE;

		case CMD_FILE:
		case CMD_DIRECTORY:
		case CMD_SOFT_LINK:
		case CMD_HARD_LINK:
		case CMD_SPECIAL:
		// Stuff not currently supported in burp-2, but OK
		// to find in burp-1.
		case CMD_ENC_FILE:
		case CMD_METADATA:
		case CMD_ENC_METADATA:
		case CMD_EFS_FILE:
		case CMD_VSS:
		case CMD_ENC_VSS:
		case CMD_VSS_T:
		case CMD_ENC_VSS_T:
			if(!sb->attr.buf)
			{
				log_and_send(asfd, "read cmd with no attribs");
				return PARSE_RET_ERROR;
			}
			if(sb->flags & SBUF_NEED_LINK)
			{
				if(cmd_is_link(rbuf->cmd))
				{
					iobuf_free_content(&sb->link);
					iobuf_move(&sb->link, rbuf);
					sb->flags &= ~SBUF_NEED_LINK;
					return PARSE_RET_COMPLETE;
				}
				else
				{
					log_and_send(asfd, "got non-link after link in manifest");
					return PARSE_RET_NEED_MORE;
				}
			}
			else
			{
				iobuf_free_content(&sb->path);
				iobuf_move(&sb->path, rbuf);
				if(cmd_is_link(rbuf->cmd))
				{
					sb->flags |= SBUF_NEED_LINK;
					return PARSE_RET_NEED_MORE;
				}
				else if(sb->protocol1
				  && sb->protocol1->datapth.buf)
				{
					// Protocol1 client restore reads
					// CMD_APPEND and CMD_END_FILE in the
					// calling function, so pretend it is
					// complete if we have the hack flag.
					if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
						return PARSE_RET_COMPLETE;
					return PARSE_RET_NEED_MORE;
				}
				return PARSE_RET_COMPLETE;
			}
#ifndef HAVE_WIN32
		case CMD_SIG:
			// Fill in the sig/block, if the caller provided
			// a pointer for one. Server only.
			if(!blk) return PARSE_RET_NEED_MORE;

			// Just fill in the sig details.
			if(blk_set_from_iobuf_sig_and_savepath(blk, rbuf))
				return PARSE_RET_ERROR;
			blk->got_save_path=1;
			iobuf_free_content(rbuf);
			return PARSE_RET_COMPLETE;
#endif
		case CMD_DATA:
			// Need to write the block to disk.
			// Client only.
			if(!blk) return PARSE_RET_NEED_MORE;
			blk->data=rbuf->buf;
			blk->length=rbuf->len;
			rbuf->buf=NULL;
			return PARSE_RET_COMPLETE;
		case CMD_MESSAGE:
		case CMD_WARNING:
			log_recvd(rbuf, cntr, 1);
			return PARSE_RET_NEED_MORE;
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "restoreend")
			  || !strcmp(rbuf->buf, "phase1end")
			  || !strcmp(rbuf->buf, "backupphase2")
			// Think these are protocol1 things.
                	  || !strcmp(rbuf->buf, "backupend")
			  || !strcmp(rbuf->buf, "estimateend"))
				return PARSE_RET_FINISHED;
			iobuf_log_unexpected(rbuf, __func__);
			return PARSE_RET_ERROR;
		case CMD_FINGERPRINT:
			if(blk && blk_set_from_iobuf_fingerprint(blk, rbuf))
				return PARSE_RET_ERROR;
			// Fall through.
		case CMD_MANIFEST:
			iobuf_free_content(&sb->path);
			iobuf_move(&sb->path, rbuf);
			return PARSE_RET_COMPLETE;
		case CMD_ERROR:
			logp("got error: %s\n", rbuf->buf);
			return PARSE_RET_ERROR;
		case CMD_DATAPTH:
			if(!sb->protocol1)
			{
				iobuf_log_unexpected(rbuf, __func__);
				return PARSE_RET_ERROR;
			}
			if(sb->flags & SBUF_CLIENT_RESTORE_HACK)
			{
				sbuf_free_content(sb);
				sb->flags |= SBUF_CLIENT_RESTORE_HACK;
			}
			else
				sbuf_free_content(sb);
			
			iobuf_move(&sb->protocol1->datapth, rbuf);
			return PARSE_RET_NEED_MORE;
		case CMD_END_FILE:
			iobuf_free_content(&sb->endfile);
			iobuf_move(&sb->endfile, rbuf);
			if(sb->protocol1)
			{
				if(!sb->attr.buf
				  || !sb->protocol1->datapth.buf
				  || (!sbuf_is_filedata(sb)
					&& !sbuf_is_vssdata(sb)))
				{
					logp("got unexpected cmd_endfile");
					return PARSE_RET_ERROR;
				}
			}
			return PARSE_RET_COMPLETE;
		default:
			iobuf_log_unexpected(rbuf, __func__);
			return PARSE_RET_ERROR;
	}
	logp("Fell out of switch unexpectedly in %s()\n", __func__);
	return PARSE_RET_ERROR;
}
コード例 #17
0
ファイル: backup_phase2.c プロジェクト: pkdevbox/burp
static int deal_with_read(struct iobuf *rbuf, struct slist *slist,
	struct cntr *cntr, uint8_t *end_flags, struct dpth *dpth)
{
	int ret=0;
	static struct sbuf *inew=NULL;

	if(!inew && !(inew=sbuf_alloc(PROTO_2))) goto error;

	switch(rbuf->cmd)
	{
		/* Incoming block data. */
		case CMD_DATA:
			if(add_data_to_store(cntr, slist, rbuf, dpth))
				goto error;
			goto end;

		/* Incoming block signatures. */
		case CMD_ATTRIBS_SIGS:
			// New set of stuff incoming. Clean up.
			iobuf_free_content(&inew->attr);
			iobuf_move(&inew->attr, rbuf);
			inew->protocol2->index=decode_file_no(&inew->attr);

			// Need to go through slist to find the matching
			// entry.
			if(set_up_for_sig_info(slist, inew))
				goto error;
			return 0;
		case CMD_SIG:
			if(add_to_sig_list(slist, rbuf))
				goto error;
			goto end;

		/* Incoming control/message stuff. */
		case CMD_MESSAGE:
		case CMD_WARNING:
		{
			struct cntr *cntr=NULL;
			log_recvd(rbuf, cntr, 0);
			goto end;
		}
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "sigs_end"))
			{
				(*end_flags)|=END_SIGS;
				goto end;
			}
			else if(!strcmp(rbuf->buf, "backup_end"))
			{
				(*end_flags)|=END_BACKUP;
				goto end;
			}
			break;
		default:
			break;
	}

	iobuf_log_unexpected(rbuf, __func__);
error:
	ret=-1;
	sbuf_free(&inew);
end:
	iobuf_free_content(rbuf);
	return ret;
}
コード例 #18
0
ファイル: backup_phase2.c プロジェクト: adrianimboden/burp
static int process_changed_file(struct asfd *asfd,
	struct sdirs *sdirs, struct conf **cconfs,
	struct sbuf *cb, struct sbuf *p1b,
	const char *adir)
{
	size_t blocklen=0;
	char *curpath=NULL;
	//logp("need to process changed file: %s (%s)\n",
	//	cb->path, cb->datapth);

	// Move datapth onto p1b.
	iobuf_move(&p1b->protocol1->datapth, &cb->protocol1->datapth);

	if(!(curpath=prepend_s(adir, p1b->protocol1->datapth.buf)))
	{
		log_out_of_memory(__func__);
		return -1;
	}
	if(dpth_protocol1_is_compressed(cb->compression, curpath))
		p1b->protocol1->sigfzp=fzp_gzopen(curpath, "rb");
	else
		p1b->protocol1->sigfzp=fzp_open(curpath, "rb");
	if(!p1b->protocol1->sigfzp)
	{
		logp("could not open %s: %s\n", curpath, strerror(errno));
		free(curpath);
		return -1;
	}
	free(curpath);

	blocklen=get_librsync_block_len(cb->protocol1->endfile.buf);
	if(!(p1b->protocol1->sigjob=
#ifdef RS_DEFAULT_STRONG_LEN
		rs_sig_begin(blocklen, RS_DEFAULT_STRONG_LEN)
#else
		// This is for librsync-1.0.0. RS_DEFAULT_STRONG_LEN was 8 in
		// librsync-0.9.7.
		rs_sig_begin(blocklen, 8,
		  rshash_to_magic_number(get_e_rshash(cconfs[OPT_RSHASH])))
#endif
	))
	{
		logp("could not start signature job.\n");
		return -1;
	}
	//logp("sig begin: %s\n", p1b->protocol1->datapth.buf);
	if(!(p1b->protocol1->infb=rs_filebuf_new(asfd, NULL,
		p1b->protocol1->sigfzp,
		-1, blocklen, -1, get_cntr(cconfs[OPT_CNTR]))))
	{
		logp("could not rs_filebuf_new for infb.\n");
		return -1;
	}
	if(!(p1b->protocol1->outfb=rs_filebuf_new(asfd, NULL, NULL,
		asfd->fd, ASYNC_BUF_LEN, -1, get_cntr(cconfs[OPT_CNTR]))))
	{
		logp("could not rs_filebuf_new for in_outfb.\n");
		return -1;
	}

	// Flag the things that need to be sent (to the client)
	p1b->flags |= SBUFL_SEND_DATAPTH;
	p1b->flags |= SBUFL_SEND_STAT;
	p1b->flags |= SBUFL_SEND_PATH;

	//logp("sending sig for %s\n", p1b->path);
	//logp("(%s)\n", p1b->datapth);

	return 0;
}
コード例 #19
0
ファイル: resume.c プロジェクト: ZungBang/burp
static
#endif
int get_last_good_entry(struct manio *manio, struct iobuf *result,
                        struct cntr *cntr, struct dpth *dpth, enum protocol protocol,
                        man_off_t **pos)
{
    int ars=0;
    int got_vss_start=0;
    struct sbuf *sb=NULL;
    struct iobuf lastpath;

    if(!(sb=sbuf_alloc(protocol)))
        goto error;

    iobuf_init(&lastpath);

    man_off_t_free(pos);
    if(!(*pos=manio_tell(manio)))
    {
        logp("Could not manio_tell first pos in %s(): %s\n",
             __func__, strerror(errno));
        goto error;
    }

    while(1)
    {
        if(sb->path.buf && !got_vss_start)
        {
            iobuf_free_content(&lastpath);
            iobuf_move(&lastpath, &sb->path);
            if(!sbuf_is_filedata(sb)
                    && !sbuf_is_vssdata(sb))
            {
                iobuf_free_content(result);
                iobuf_move(result, &lastpath);

                man_off_t_free(pos);
                if(!(*pos=manio_tell(manio)))
                {
                    logp("Could not manio_tell pos in %s(): %s\n",
                         __func__, strerror(errno));
                    goto error;
                }
            }
        }
        if(sb->endfile.buf && !got_vss_start)
        {
            iobuf_free_content(result);
            iobuf_move(result, &lastpath);

            man_off_t_free(pos);
            if(!(*pos=manio_tell(manio)))
            {
                logp("Could not manio_tell pos in %s(): %s\n",
                     __func__, strerror(errno));
                goto error;
            }
        }

        sbuf_free_content(sb);
        ars=manio_read(manio, sb);
        if(dpth && set_higher_datapth(sb, dpth)) goto error;

        switch(ars)
        {
        case 0:
            break;
        case 1:
            iobuf_free_content(&lastpath);
            sbuf_free(&sb);
            return 0;
        default:
            if(result->buf)
                logp("Error after %s in %s()\n",
                     result->buf, __func__);
            // Treat error in changed manio as
            // OK - could have been a short write.
            iobuf_free_content(&lastpath);
            sbuf_free(&sb);
            return 0;
        }

        // Some hacks for split_vss.
        switch(sb->path.cmd)
        {
        case CMD_VSS:
        case CMD_ENC_VSS:
            got_vss_start=1;
            break;
        case CMD_VSS_T:
        case CMD_ENC_VSS_T:
            got_vss_start=0;
            break;
        case CMD_FILE:
        case CMD_ENC_FILE:
            if(S_ISDIR(sb->statp.st_mode))
                got_vss_start=0;
            break;
        default:
            break;
        }

        if(cntr)
        {
            // FIX THIS: cannot distinguish between new and
            // changed files.
            cntr_add_changed(cntr, sb->path.cmd);
            if(sb->endfile.buf)
            {
                uint64_t e=strtoull(sb->endfile.buf, NULL, 10);
                cntr_add_bytes(cntr, e);
            }
        }
    }

error:
    iobuf_free_content(&lastpath);
    sbuf_free(&sb);
    man_off_t_free(pos);
    return -1;
}
コード例 #20
0
ファイル: backup_phase2.c プロジェクト: adrianimboden/burp
// returns 1 for finished ok.
static int do_stuff_to_receive(struct asfd *asfd,
	struct sdirs *sdirs, struct conf **cconfs,
	struct sbuf *rb, struct fzp *chfp,
	struct dpth *dpth, char **last_requested)
{
	struct iobuf *rbuf=asfd->rbuf;

	iobuf_free_content(rbuf);
	// This also attempts to write anything in the write buffer.
	if(asfd->as->read_write(asfd->as))
	{
		logp("error in %s\n", __func__);
		return -1;
	}

	if(!rbuf->buf) return 0;

	if(rbuf->cmd==CMD_MESSAGE
	  || rbuf->cmd==CMD_WARNING)
	{
		log_recvd(rbuf, cconfs, 0);
		return 0;
	}

	if(rb->protocol1->fzp)
	{
		// Currently writing a file (or meta data)
		switch(rbuf->cmd)
		{
			case CMD_APPEND:
				if(deal_with_receive_append(asfd, rb, cconfs))
					goto error;
				return 0;
			case CMD_END_FILE:
				if(deal_with_receive_end_file(asfd, sdirs, rb,
					chfp, cconfs, last_requested))
						goto error;
				return 0;
			default:
				iobuf_log_unexpected(rbuf, __func__);
				goto error;
		}
	}

	// Otherwise, expecting to be told of a file to save.
	switch(rbuf->cmd)
	{
		case CMD_DATAPTH:
			iobuf_move(&rb->protocol1->datapth, rbuf);
			return 0;
		case CMD_ATTRIBS:
			iobuf_move(&rb->attr, rbuf);
			return 0;
		case CMD_GEN:
			if(!strcmp(rbuf->buf, "okbackupphase2end"))
				goto end_phase2;
			iobuf_log_unexpected(rbuf, __func__);
			goto error;
		case CMD_INTERRUPT:
			// Interrupt - forget about the last requested
			// file if it matches. Otherwise, we can get
			// stuck on the select in the async stuff,
			// waiting for something that will never arrive.
			if(*last_requested
			  && !strcmp(rbuf->buf, *last_requested))
				free_w(last_requested);
			return 0;
		default:
			break;
	}
	if(cmd_is_filedata(rbuf->cmd))
	{
		if(deal_with_filedata(asfd, sdirs, rb, rbuf, dpth, cconfs))
			goto error;
		return 0;
	}
	iobuf_log_unexpected(rbuf, __func__);

error:
	return -1;
end_phase2:
	return 1;
}