Exemple #1
0
static char * fetch(BIO *bio,
                  const void *key,
                  uint16_t nkey)
{
    protocol_binary_request_get request;
    protocol_binary_response_no_extras response;
    char *payload;

    memset(&request, 0, sizeof(request));
    request.message.header.request.magic = PROTOCOL_BINARY_REQ;
    request.message.header.request.opcode = PROTOCOL_BINARY_CMD_GET;
    request.message.header.request.keylen = htons((uint16_t)nkey);
    request.message.header.request.bodylen = htonl(nkey);

    ensure_send(bio, &request, sizeof(request.bytes));
    ensure_send(bio, key, nkey);
    if (BIO_flush(bio) != 1) {
        fprintf(stderr, "Failed to flush bio instance\n");
        exit(EXIT_FAILURE);
    }

    payload = get_response(bio, &response);
    cb_assert(ntohs(response.message.header.response.status) == PROTOCOL_BINARY_RESPONSE_SUCCESS);
    cb_assert(payload != NULL);
    return payload;

}
Exemple #2
0
/**
 * Sets a property (to the specified value).
 * @param bio connection to the server.
 * @param property the name of the property to set.
 * @param value value to set the property to (NULL == no value).
 */
static int ioctl_set(BIO *bio, const char *property, const char* value)
{
    char *buffer = NULL;
    uint16_t keylen = 0;
    uint32_t valuelen = 0;
    int result;
    protocol_binary_request_ioctl_set request;
    protocol_binary_response_no_extras response;
    protocol_binary_response_status status;

    if (property != NULL) {
        keylen = (uint16_t)strlen(property);
    }
    if (value != NULL) {
        valuelen = (uint32_t)strlen(value);
    }

    memset(&request, 0, sizeof(request));
    request.message.header.request.magic = PROTOCOL_BINARY_REQ;
    request.message.header.request.opcode = PROTOCOL_BINARY_CMD_IOCTL_SET;
    request.message.header.request.keylen = htons(keylen);
    request.message.header.request.bodylen = htonl(valuelen);

    ensure_send(bio, &request, sizeof(request));
    if (keylen > 0) {
        ensure_send(bio, property, keylen);
    }
    if (valuelen > 0) {
        ensure_send(bio, value, valuelen);
    }

    ensure_recv(bio, &response, sizeof(response.bytes));
    if (response.message.header.response.bodylen != 0) {
        valuelen = ntohl(response.message.header.response.bodylen);
        buffer = malloc(valuelen);
        if (buffer == NULL) {
            fprintf(stderr, "Failed to allocate memory for set response\n");
            exit(EXIT_FAILURE);
        }
        ensure_recv(bio, buffer, valuelen);
    }
    status = htons(response.message.header.response.status);
    if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
        result = 0;
    } else {
        fprintf(stderr, "Error from server: %s\n",
                memcached_protocol_errcode_2_text(status));
        result = 1;
    }

    if (buffer != NULL) {
        fwrite(buffer, valuelen, 1, stdout);
        fputs("\n", stdout);
        fflush(stdout);
        free(buffer);
    }
    return result;
}
Exemple #3
0
/**
 * Request all features from the server and dump the available ones
 * @param sock socket connected to the server
 * @param key the name of the stat to receive (NULL == ALL)
 */
static void request_hello(BIO *bio, const char *key)
{
    protocol_binary_request_hello req;
    protocol_binary_response_hello res;
    char buffer[1024];
    const char useragent[] = "mchello v1.0";
    uint16_t nkey = (uint16_t)strlen(useragent);
    uint16_t features[MEMCACHED_TOTAL_HELLO_FEATURES];
    uint32_t total = nkey + MEMCACHED_TOTAL_HELLO_FEATURES * 2;
    int ii;

    memset(&req, 0, sizeof(req));
    req.message.header.request.magic = PROTOCOL_BINARY_REQ;
    req.message.header.request.opcode = PROTOCOL_BINARY_CMD_HELLO;
    req.message.header.request.bodylen = htonl(total);
    req.message.header.request.keylen = htons(nkey);
    req.message.header.request.datatype = PROTOCOL_BINARY_RAW_BYTES;

    ensure_send(bio, &req, sizeof(req));
    ensure_send(bio, useragent, nkey);

    for (ii = 0; ii < MEMCACHED_TOTAL_HELLO_FEATURES; ++ii) {
        features[ii] = htons(MEMCACHED_FIRST_HELLO_FEATURE + ii);
    }
    ensure_send(bio, &features, MEMCACHED_TOTAL_HELLO_FEATURES * 2);
    ensure_recv(bio, &res, sizeof(res.bytes));
    total = ntohl(res.message.header.response.bodylen);
    ensure_recv(bio, buffer, total);

    if (res.message.header.response.status != 0) {
        fprintf(stderr, "Got return value: %d\n",
                ntohs(res.message.header.response.status));
        return;
    }

    memcpy(features, buffer, total);
    total /= 2;

    fprintf(stdout, "Features:\n");
    for (ii = 0; ii < total; ++ii) {
        fprintf(stderr, "\t- %s\n",
                protocol_feature_2_text(ntohs(features[ii])));
    }
}
Exemple #4
0
/**
 * Get the verbosity level on the server.
 *
 * There isn't a single command to retrieve the current verbosity level,
 * but it is available through the settings stats...
 *
 * @param bio connection to the server.
 */
static int get_verbosity(BIO *bio)
{
    const char *settings = "settings";
    const uint16_t settingslen = (uint16_t)strlen(settings);

    protocol_binary_request_stats request = {
        .message.header.request.magic = PROTOCOL_BINARY_REQ,
        .message.header.request.opcode = PROTOCOL_BINARY_CMD_STAT,
        .message.header.request.keylen = htons(settingslen),
        .message.header.request.bodylen = htonl(settingslen)
    };

    ensure_send(bio, &request, sizeof(request));
    ensure_send(bio, settings, settingslen);

    // loop and receive the result and print the verbosity when we get it
    struct statistic st;
    do {
        receive_stat_response(bio, &st);
        if (st.key != NULL && strcasecmp(st.key, "verbosity") == 0) {
            uint32_t level;
            if (safe_strtoul(st.value, &level)) {
                const char *levels[] = { "warning",
                                         "info",
                                         "debug",
                                         "detail",
                                         "unknown" };
                const char *ptr = levels[4];

                if (level < 4) {
                    ptr = levels[level];
                }
                fprintf(stderr, "%s\n", ptr);
            } else {
                fprintf(stderr, "%s\n", st.value);
            }
        }
        free(st.key);
        free(st.value);
    } while (st.key != NULL);

    return EXIT_SUCCESS;
}
Exemple #5
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(BIO *bio, const char *key)
{
    uint32_t buffsize = 0;
    char *buffer = NULL;
    uint16_t keylen = 0;
    protocol_binary_request_stats request;
    protocol_binary_response_no_extras response;

    if (key != NULL) {
        keylen = (uint16_t)strlen(key);
    }

    memset(&request, 0, sizeof(request));
    request.message.header.request.magic = PROTOCOL_BINARY_REQ;
    request.message.header.request.opcode = PROTOCOL_BINARY_CMD_STAT;
    request.message.header.request.keylen = htons(keylen);
    request.message.header.request.bodylen = htonl(keylen);

    ensure_send(bio, &request, sizeof(request));
    if (keylen > 0) {
        ensure_send(bio, key, keylen);
    }

    do {
        ensure_recv(bio, &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;
            }
            ensure_recv(bio, buffer, vallen);
            print(buffer, keylen, buffer + keylen, vallen - keylen);
        }
    } while (response.message.header.response.keylen != 0);
}
Exemple #6
0
static int set_ascii(BIO *bio, const char *key, size_t size) {
    char line[1024];
    int len = snprintf(line, sizeof(line), "set %s 0 0 %lu\r\n",
                       key, (unsigned long)size);
    ensure_send(bio, &line, len);
    if (size > 0) {
        char* value = malloc(size);
        if (value) {
            ensure_send(bio, value, (int)size);
            free(value);
        } else {
            for (size_t ii = 0; ii < size; ++ii) {
                ensure_send(bio, key, 1);
            }
        }
    }
    ensure_send(bio, "\r\n", 2);
    memset(line, 0, sizeof(line));
    int ii = -1;
    do {
        ++ii;
        ensure_recv(bio, line + ii, 1);
    } while (line[ii] != '\n');

    while (ii >= 0 && isspace(line[ii])) {
        line[ii] = '\0';
        --ii;
    }

    if (strcasecmp(line, "stored") == 0) {
        fprintf(stdout, "Stored %s with %lu bytes\n", key, (unsigned long)size);
        return EXIT_SUCCESS;
    }

    fprintf(stderr, "FAILURE: Received %s", line);

    return EXIT_FAILURE;
}
Exemple #7
0
/**
 * Refresh the cbsasl password database
 * @param sock socket connected to the server
 */
static void refresh(BIO *bio)
{
    protocol_binary_response_no_extras response;
    protocol_binary_request_no_extras request;

    memset(&request, 0, sizeof(request));
    request.message.header.request.magic = PROTOCOL_BINARY_REQ;
    request.message.header.request.opcode = PROTOCOL_BINARY_CMD_ISASL_REFRESH;

    ensure_send(bio, &request, sizeof(request));

    ensure_recv(bio, &response, sizeof(response.bytes));
    if (response.message.header.response.status != 0) {
        uint16_t err = ntohs(response.message.header.response.status);
        fprintf(stderr, "Failed to refresh cbsasl passwd db: %d\n",
                err);
    }
}