/** * 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; }
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; }
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)); }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
void pkt_ref_dec(th_pkt_t *pkt) { if((atomic_add(&pkt->pkt_refcount, -1)) == 1) pkt_destroy(pkt); }