static int do_sasl_auth(int sock, const char *user, const char *pass) { /* * For now just shortcut the SASL phase by requesting a "PLAIN" * sasl authentication. */ size_t ulen = strlen(user) + 1; size_t plen = pass ? strlen(pass) + 1 : 1; size_t tlen = ulen + plen + 1; protocol_binary_request_stats request = { .message.header.request = { .magic = PROTOCOL_BINARY_REQ, .opcode = PROTOCOL_BINARY_CMD_SASL_AUTH, .keylen = htons(5), .bodylen = htonl(5 + tlen) } }; retry_send(sock, &request, sizeof(request)); retry_send(sock, "PLAIN", 5); retry_send(sock, "", 1); retry_send(sock, user, ulen); if (pass) { retry_send(sock, pass, plen); } else { retry_send(sock, "", 1); } protocol_binary_response_no_extras response; retry_recv(sock, &response, sizeof(response.bytes)); uint32_t vallen = ntohl(response.message.header.response.bodylen); char *buffer = NULL; if (vallen != 0) { buffer = malloc(vallen); retry_recv(sock, buffer, vallen); } protocol_binary_response_status status; status = ntohs(response.message.header.response.status); if (status != PROTOCOL_BINARY_RESPONSE_SUCCESS) { fprintf(stderr, "Failed to authenticate to the server: %s\n", e2t(status)); close(sock); sock = -1; return -1; } free(buffer); return sock; }
static void dump_extra_info(int sock, uint32_t nb) { if (nb > 0) { char *payload = calloc(1, nb + 1); char *curr = payload; bool done = false; retry_recv(sock, payload, nb); fprintf(stderr, "\t%s\n", payload); free(payload); } }
/** * Request a stat from the server * @param sock socket connected to the server * @param key the name of the stat to receive (NULL == ALL) */ static void request_stat(int sock, const char *key) { uint32_t buffsize = 0; char *buffer = NULL; uint16_t keylen = 0; if (key != NULL) { keylen = (uint16_t)strlen(key); } protocol_binary_request_stats request = { .message.header.request = { .magic = PROTOCOL_BINARY_REQ, .opcode = PROTOCOL_BINARY_CMD_STAT, .keylen = htons(keylen), .bodylen = htonl(keylen) } }; retry_send(sock, &request, sizeof(request)); if (keylen > 0) { retry_send(sock, key, keylen); } protocol_binary_response_no_extras response; do { retry_recv(sock, &response, sizeof(response.bytes)); if (response.message.header.response.keylen != 0) { uint16_t keylen = ntohs(response.message.header.response.keylen); uint32_t vallen = ntohl(response.message.header.response.bodylen); if (vallen > buffsize) { if ((buffer = realloc(buffer, vallen)) == NULL) { fprintf(stderr, "Failed to allocate memory\n"); exit(1); } buffsize = vallen; } retry_recv(sock, buffer, vallen); print(buffer, keylen, buffer + keylen, vallen - keylen); } } while (response.message.header.response.keylen != 0); }
static int create(int sock, char **argv, int offset, int argc) { char *name; uint16_t namelen; char *engine; uint16_t nengine; char *config = NULL; uint32_t nconfig = 0; if (offset == argc) { fprintf(stderr, "You have to specify the bucket to create\n"); return EXIT_FAILURE; } name = argv[offset++]; namelen = (uint16_t)strlen(name); if (offset == argc) { fprintf(stderr, "You have to specify the engine for the bucket\n"); return EXIT_FAILURE; } engine = argv[offset++]; nengine = (uint16_t)strlen(engine) + 1; // Include '\0' if (offset < argc) { config = argv[offset++]; nconfig = (uint32_t)strlen(config); } if (offset != argc) { fprintf(stderr, "Too many arguments to create\n"); return EXIT_FAILURE; } protocol_binary_request_create_bucket request = { .message.header.request = { .magic = PROTOCOL_BINARY_REQ, .opcode = CREATE_BUCKET, .keylen = htons(namelen), .bodylen = htonl(nconfig + namelen + nengine) } }; retry_send(sock, &request, sizeof(request)); retry_send(sock, name, namelen); retry_send(sock, engine, nengine); if (config) { retry_send(sock, config, nconfig); } protocol_binary_response_no_extras response; retry_recv(sock, &response, sizeof(response.bytes)); uint32_t nb = ntohl(response.message.header.response.bodylen); if (response.message.header.response.status != 0) { uint16_t err = ntohs(response.message.header.response.status); fprintf(stderr, "Failed to create bucket \"%s\": %s\n", name, e2t(err)); dump_extra_info(sock, nb); return EXIT_FAILURE; } else { fprintf(stdout, "Bucket \"%s\" successfully created\n", name); } return EXIT_SUCCESS; }