int main(int argc, char *argv[]) { uint64_t bytes; if (argc == 3) { set_units(true); bytes = strtoll(argv[2], NULL, 10); } else if (argc == 2) { set_units(false); bytes = strtoll(argv[1], NULL, 10); } else { printf("Usage: ppb [--si] <bytes>\n"); exit(EXIT_FAILURE); } pretty_print_bytes(bytes); exit(EXIT_SUCCESS); }
bool __check_request(struct bufferevent* bev, struct evbuffer* in, struct evbuffer* out, struct nbd_client* client) { struct nbd_req_header* peek = NULL; struct nbd_req_header req; uint32_t err = 0; uint64_t handle = 0; void* test = NULL; char bytestr[32]; peek = (struct nbd_req_header*) evbuffer_pullup(in, sizeof(struct nbd_req_header)); if (peek) { memcpy(&req, peek, sizeof(struct nbd_req_header)); if (be32toh(req.magic) == GAMMARAY_NBD_REQ_MAGIC) { handle = be64toh(req.handle); switch(be32toh(req.type)) { case NBD_CMD_READ: err = __handle_read(peek, client); if (err == -1) return true; evbuffer_drain(in, sizeof(struct nbd_req_header)); __send_response(bev, err, handle, client->buf, be32toh(req.length)); return false; case NBD_CMD_WRITE: fprintf(stderr, "+"); err = __handle_write(peek, client, in); if (err == -1) return true; pretty_print_bytes(client->write_bytes, bytestr, 32); fprintf(stderr, "\twrite[%"PRIu64"]: %"PRIu64" cumulative " "bytes (%s)\n", client->write_count, client->write_bytes, bytestr); evbuffer_drain(in, be32toh(req.length)); __send_response(bev, err, handle, NULL, 0); return false; case NBD_CMD_DISC: fprintf(stderr, "got disconnect.\n"); client->state = NBD_DISCONNECTED; evbuffer_drain(in, sizeof(struct nbd_req_header)); nbd_ev_handler(bev, BEV_EVENT_EOF, client); return false; case NBD_CMD_FLUSH: fprintf(stderr, "got flush.\n"); evbuffer_drain(in, sizeof(struct nbd_req_header)); if (fsync(client->handle->fd)) __send_response(bev, errno, handle, NULL, 0); else __send_response(bev, 0, handle, NULL, 0); return false; case NBD_CMD_TRIM: fprintf(stderr, "got trim.\n"); evbuffer_drain(in, sizeof(struct nbd_req_header)); if (fallocate(client->handle->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, be64toh(req.offset), be32toh(req.length))) __send_response(bev, errno, handle, NULL, 0); else __send_response(bev, 0, handle, NULL, 0); return false; default: test = evbuffer_pullup(in, sizeof(struct nbd_req_header) + be32toh(req.length)); if (test) evbuffer_drain(in, sizeof(struct nbd_req_header) + be32toh(req.length)); fprintf(stderr, "unknown command!\n"); fprintf(stderr, "-- Hexdumping --\n"); if (test) hexdump(test, be32toh(req.length)); fprintf(stderr, "disconnecting, protocol error!\n"); client->state = NBD_DISCONNECTED; nbd_ev_handler(bev, BEV_EVENT_EOF, client); }; } } return true; }