Пример #1
0
/**
 * pkt_recv - receive packet
 * @fd:	file descriptor to read
 *
 * Reads the next packet from @fd. A new lo_packet is created and returned.
 * On error, %NULL is returned, in which case the stream (@fd) will be in
 * an undefined state.
 */
struct lo_packet *pkt_recv(int fd)
{
	struct ccgfs_pkt_header *hdr;
	struct lo_packet *pkt;
	ssize_t ret;
	int err;

	pkt = pkt_init(0, 0);
	hdr = pkt->data;
	ret = reliable_read(fd, hdr, sizeof(*hdr));
	if (ret != sizeof(*hdr)) {
		err = errno;
		pkt_destroy(pkt);
		errno = err;
		return NULL;
	}

	hdr->opcode = le32_to_cpu(hdr->opcode);
	hdr->length = le32_to_cpu(hdr->length);
	hdr         = pkt_resize(pkt, hdr->length);
	pkt->length = hdr->length;

	ret = reliable_read(fd, pkt->data + sizeof(*hdr),
	      pkt->length - sizeof(*hdr));
	if (ret != pkt->length - sizeof(*hdr)) {
		err = errno;
		pkt_destroy(pkt);
		errno = err;
		return NULL;
	}
	return pkt;
}
Пример #2
0
static int ccgfs_statfs(const char *path, struct statvfs *buf)
{
	struct lo_packet *rq, *rp;
	int ret;

	rq = mpkt_init(CCGFS_STATFS_REQUEST, PV_STRING);
	mpkt_send(out_fd, rq);

	ret = mpkt_recv(CCGFS_STATFS_RESPONSE, &rp);
	if (ret == -ENOTCONN) {
		memset(buf, 0, sizeof(*buf));
		return 0;
	}
	if (ret < 0)
		return ret;

	buf->f_bsize   = pkt_shift_64(rp);
	buf->f_frsize  = pkt_shift_64(rp);
	buf->f_blocks  = pkt_shift_64(rp);
	buf->f_bfree   = pkt_shift_64(rp);
	buf->f_bavail  = pkt_shift_64(rp);
	buf->f_files   = pkt_shift_64(rp);
	buf->f_ffree   = pkt_shift_64(rp);
	buf->f_favail  = pkt_shift_64(rp);
	buf->f_fsid    = pkt_shift_64(rp);
	buf->f_flag    = pkt_shift_64(rp);
	buf->f_namemax = pkt_shift_64(rp);
	pkt_destroy(rp);
	return 0;
}
Пример #3
0
void
test_packet_create_destroy(void** state)
{
  uint8_t data[5] = {1,2,3,4,5};
  KAD_PACKET* kp = NULL;

  assert_true(pkt_create(data, 5, PACKET_EMIT_TYPE_TCP, KADEMLIA2_PING, &kp));

  assert_true(pkt_destroy(kp));

}
Пример #4
0
static int __mpkt_recv(unsigned int type, struct lo_packet **putback,
    bool list_retrieval)
{
	const struct ccgfs_pkt_header *hdr;
	struct lo_packet *pkt;

	pkt = pkt_recv(in_fd);
	if (!list_retrieval)
		pthread_mutex_unlock(&net_lock);

	if (pkt == NULL) {
		fprintf(stderr, "%s: %s\n",
		        __func__, strerror(errno));
		pthread_kill(main_thread_id, SIGTERM);
		return -ENOTCONN;
	}

	hdr = pkt->data;
	if (hdr->opcode == CCGFS_ERRNO_RESPONSE) {
		int32_t ret = pkt_shift_32(pkt);
		pkt_destroy(pkt);

		/* May happen as a result of a write() */
		if (ret >= 0)
			return ret;

		return arch_errno(ret);
	}

	if (hdr->opcode != type) {
		pkt_destroy(pkt);
		*putback = NULL;
		return -EIO;
	}

	*putback = pkt;
	return list_retrieval;
}
Пример #5
0
static int ccgfs_readdir(const char *path, void *what, fuse_fill_dir_t filldir,
    off_t offset, struct fuse_file_info *f)
{
	struct lo_packet *rq, *rp;
	struct stat sb;
	int ret;

	rq = mpkt_init(CCGFS_READDIR_REQUEST, PV_STRING);
	pkt_push_s(rq, path);
	mpkt_send(out_fd, rq);

	memset(&sb, 0, sizeof(sb));
	while ((ret = mpkt_recv_list(CCGFS_READDIR_RESPONSE, &rp)) > 0) {
		sb.st_ino  = pkt_shift_64(rp);
		sb.st_mode = pkt_shift_32(rp) << 12;
		ret = (*filldir)(what, pkt_shift_s(rp), &sb, 0);
		pkt_destroy(rp);
		if (ret > 0)
			break;
	}

	if (ret > 0)
		/*
		 * Means, we exited above loop through the break;
		 * Need to slurp all the remaining packets, though.
		 */
		while ((ret = mpkt_recv_list(CCGFS_READDIR_RESPONSE, &rp)) > 0)
			pkt_destroy(rp);

	pthread_mutex_unlock(&net_lock);

	if (ret < 0)
		return ret;
	
	return 0;
}
Пример #6
0
static int ccgfs_getattr(const char *path, struct stat *sb)
{
	struct lo_packet *rq, *rp;
	int ret;

	rq = mpkt_init(CCGFS_GETATTR_REQUEST, PV_STRING);
	pkt_push_s(rq, path);
	mpkt_send(out_fd, rq);

	ret = mpkt_recv(CCGFS_GETATTR_RESPONSE, &rp);
	if (ret < 0)
		return ret;

	getattr_copy_mount(sb, rp);
	pkt_destroy(rp);
	return 0;
}
Пример #7
0
static int ccgfs_open(const char *path, struct fuse_file_info *filp)
{
	struct lo_packet *rq, *rp;
	int ret;

	rq = mpkt_init(CCGFS_OPEN_REQUEST, PV_STRING + PV_32);
	pkt_push_s(rq, path);
	pkt_push_32(rq, generic_openflags(filp->flags));
	mpkt_send(out_fd, rq);

	ret = mpkt_recv(CCGFS_OPEN_RESPONSE, &rp);
	if (ret < 0)
		return ret;

	filp->fh = pkt_shift_32(rp);
	pkt_destroy(rp);
	return 0;
}
Пример #8
0
static int ccgfs_fgetattr(const char *path, struct stat *sb,
    struct fuse_file_info *filp)
{
	struct lo_packet *rq, *rp;
	int ret;

	rq = mpkt_init(CCGFS_FGETATTR_REQUEST, PV_32);
	pkt_push_32(rq, filp->fh);
	mpkt_send(out_fd, rq);

	ret = mpkt_recv(CCGFS_GETATTR_RESPONSE, &rp);
	if (ret < 0)
		return ret;

	getattr_copy_mount(sb, rp);
	pkt_destroy(rp);
	return 0;
}
Пример #9
0
static int ccgfs_readlink(const char *path, char *linkbuf, size_t size)
{
	struct lo_packet *rq, *rp;
	const char *d_linkbuf;
	int ret;

	rq = mpkt_init(CCGFS_READLINK_REQUEST, PV_STRING);
	pkt_push_s(rq, path);
	mpkt_send(out_fd, rq);

	ret = mpkt_recv(CCGFS_READLINK_RESPONSE, &rp);
	if (ret < 0)
		return ret;

	d_linkbuf = pkt_shift_s(rp);
	memset(linkbuf, 0, size);
	strncpy(linkbuf, d_linkbuf, size);
	pkt_destroy(rp);
	return 0;
}
Пример #10
0
int main(int argc, char **argv)
{
	int new_argc = 0, i, ret;
	struct lo_packet *rp;
	char **new_argv;
	char buf[NAME_MAX];

	/*
	 * The mutex is unlocked. Hence we may not unlock it again.
	 * Hence __mpkt_recv(,,true).
	 */
	if ((ret = __mpkt_recv(CCGFS_FSINFO, &rp, true)) <= 0) {
		perror("mpkt_recv");
		exit(EXIT_FAILURE);
	}

	new_argv = malloc(sizeof(char *) * (argc + 5));
	new_argv[new_argc++] = argv[0];
	new_argv[new_argc++] = "-f";
	new_argv[new_argc++] = "-ouse_ino";

	if (user_allow_other())
		new_argv[new_argc++] = "-oallow_other";

#ifdef HAVE_JUST_FUSE_2_6_5
	snprintf(buf, sizeof(buf), "-ofsname=ccgfs#%s",
	         static_cast(const char *, pkt_shift_s(rp)));
#else
	snprintf(buf, sizeof(buf), "-osubtype=ccgfs,fsname=%s",
	         static_cast(const char *, pkt_shift_s(rp)));
#endif
	new_argv[new_argc++] = buf;
	pkt_destroy(rp);

	for (i = 1; i < argc; ++i)
		new_argv[new_argc++] = argv[i];
	new_argv[new_argc] = NULL;

	main_thread_id = pthread_self();
	return fuse_main(new_argc, new_argv, &ccgfs_ops, NULL);
}
Пример #11
0
void
test_packet_emit(void** state)
{
  uint8_t data[5] = {1,2,3,4,5};
  KAD_PACKET* kp = NULL;
  uint8_t* emit_buf;
  uint32_t io_bytes = 0;

  emit_buf = mem_alloc(20);

  assert_true(pkt_create(data, 5, PACKET_EMIT_TYPE_TCP, KADEMLIA2_PING, &kp));

  assert_true(pkt_emit(kp, emit_buf, 20, &io_bytes));

  assert_int_equal(7, io_bytes);

  assert_true(pkt_destroy(kp));

  mem_free(emit_buf);

}
Пример #12
0
static int ccgfs_listxattr(const char *path, char *buffer, size_t size)
{
	struct lo_packet *rq, *rp;
	int ret;

	rq = mpkt_init(CCGFS_LISTXATTR_REQUEST, PV_STRING);
	pkt_push_s(rq, path);
	pkt_push_64(rq, size);
	mpkt_send(out_fd, rq);

	ret = mpkt_recv(CCGFS_LISTXATTR_RESPONSE, &rp);
	if (ret < 0)
		return ret;

	ret = pkt_shift_64(rp);
	if (size > 0)
		memcpy(buffer, pkt_shift_s(rp), ret);
	else
		pkt_shift_s(rp); /* DBG */
	pkt_destroy(rp);
	return ret;
}
Пример #13
0
static int ccgfs_read(const char *path, char *buffer, size_t size,
    off_t offset, struct fuse_file_info *filp)
{
	struct lo_packet *rq, *rp;
	const char *data;
	int ret;

	rq = mpkt_init(CCGFS_READ_REQUEST, 2 * PV_32 + PV_64);
	pkt_push_32(rq, filp->fh);
	pkt_push_64(rq, size);
	pkt_push_64(rq, offset);
	mpkt_send(out_fd, rq);

	ret = mpkt_recv(CCGFS_READ_RESPONSE, &rp);
	if (ret < 0)
		return ret;

	ret  = pkt_shift_64(rp); /* return value/size */
	data = pkt_shift_s(rp);
	memcpy(buffer, data, ret);
	pkt_destroy(rp);
	return ret;
}
Пример #14
0
void
pkt_ref_dec(th_pkt_t *pkt)
{
  if((atomic_add(&pkt->pkt_refcount, -1)) == 1)
    pkt_destroy(pkt);
}