Ejemplo n.º 1
0
static int
doflush(struct puffs_usermount *pu, puffs_cookie_t cookie, int op,
        off_t start, off_t end)
{
    struct puffs_framebuf *pb;
    struct puffs_flush *pf;
    size_t winlen;
    int rv;

    pb = puffs_framebuf_make();
    if (pb == NULL)
        return ENOMEM;

    winlen = sizeof(struct puffs_flush);
    if ((rv = puffs_framebuf_getwindow(pb, 0, (void *)&pf, &winlen)) == -1)
        goto out;
    assert(winlen == sizeof(struct puffs_flush));

    pf->pf_req.preq_buflen = sizeof(struct puffs_flush);
    pf->pf_req.preq_opclass = PUFFSOP_FLUSH;
    pf->pf_req.preq_id = puffs__nextreq(pu);

    pf->pf_op = op;
    pf->pf_cookie = cookie;
    pf->pf_start = start;
    pf->pf_end = end;

    rv = puffs_framev_enqueue_cc(puffs_cc_getcc(pu),
                                 puffs_getselectable(pu), pb, 0);

out:
    puffs_framebuf_destroy(pb);
    return rv;
}
Ejemplo n.º 2
0
/* no memory allocation, direct copy */
int
psbuf_do_data(struct puffs_framebuf *pb, uint8_t *data, uint32_t *dlen)
{
	void *win;
	size_t bufoff, winlen;
	uint32_t len, dataoff;

	if (psbuf_get_type(pb) != SSH_FXP_DATA) {
		uint32_t val;

		if (psbuf_get_type(pb) != SSH_FXP_STATUS)
			return INVALRESPONSE;

		if (psbuf_get_4(pb, &val) != 0)
			return INVALRESPONSE;

		if (val != SSH_FX_EOF)
			return sftperr_to_errno(val);

		*dlen = 0;
		return 0;
	}
	if (psbuf_get_4(pb, &len) != 0)
		return INVALRESPONSE;

	if (*dlen < len)
		return EINVAL;

	*dlen = 0;

	dataoff = 0;
	while (dataoff < len) {
		winlen = len-dataoff;
		bufoff = puffs_framebuf_telloff(pb);
		if (puffs_framebuf_getwindow(pb, bufoff,
		    &win, &winlen) == -1)
			return EINVAL;
		if (winlen == 0)
			break;
			
		memcpy(data + dataoff, win, winlen);
		dataoff += winlen;
	}

	*dlen = dataoff;

	return 0;
}
Ejemplo n.º 3
0
int
psbuf_read(struct puffs_usermount *pu, struct puffs_framebuf *pb,
	int fd, int *done)
{
	void *win;
	ssize_t n;
	size_t howmuch, winlen;
	int lenstate;

 the_next_level:
	if ((lenstate = READSTATE_LENGTH(CUROFF(pb))))
		howmuch = 4 - CUROFF(pb);
	else
		howmuch = psbuf_get_len(pb) - (CUROFF(pb) - 4);

	if (puffs_framebuf_reserve_space(pb, howmuch) == -1)
		return errno;

	while (howmuch) {
		winlen = howmuch;
		if (puffs_framebuf_getwindow(pb, CUROFF(pb), &win, &winlen)==-1)
			return errno;
		n = recv(fd, win, winlen, MSG_NOSIGNAL);
		switch (n) {
		case 0:
			return ECONNRESET;
		case -1:
			if (errno == EAGAIN)
				return 0;
			return errno;
		default:
			howmuch -= n;
			puffs_framebuf_seekset(pb, CUROFF(pb) + n);
			break;
		}
	}

	if (!lenstate) {
		/* XXX: initial exchange shorter.. but don't worry, be happy */
		puffs_framebuf_seekset(pb, 9);
		*done = 1;
		return 0;
	} else
		goto the_next_level;
}
Ejemplo n.º 4
0
int
psbuf_write(struct puffs_usermount *pu, struct puffs_framebuf *pb,
	int fd, int *done)
{
	void *win;
	ssize_t n;
	size_t winlen, howmuch;
	
	/* finalize buffer.. could be elsewhere ... */
	if (CUROFF(pb) == 0) {
		uint32_t len;

		len = htobe32(puffs_framebuf_tellsize(pb) - 4);
		puffs_framebuf_putdata_atoff(pb, 0, &len, 4);
	}

	howmuch = puffs_framebuf_tellsize(pb) - CUROFF(pb);
	while (howmuch) {
		winlen = howmuch;
		if (puffs_framebuf_getwindow(pb, CUROFF(pb), &win, &winlen)==-1)
			return errno;
		n = send(fd, win, winlen, MSG_NOSIGNAL);
		switch (n) {
		case 0:
			return ECONNRESET;
		case -1:
			if (errno == EAGAIN)
				return 0;
			return errno;
		default:
			howmuch -= n;
			puffs_framebuf_seekset(pb, CUROFF(pb) + n);
			break;
		}
	}

	*done = 1;
	return 0;
}