示例#1
0
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;
}
示例#2
0
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);
    }
}
示例#3
0
/**
 * 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);
}
示例#4
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;
}