The single stats server function now returns valid data.
#ifndef __MEMCACHED_H__
#define __MEMCACHED_H__
+#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <limits.h>
+#include <assert.h>
#include <time.h>
#ifdef __cplusplus
#define MEMCACHED_DEFAULT_PORT 11211
#define MEMCACHED_DEFAULT_COMMAND_SIZE 350
+#define HUGE_STRING_LEN 8196
typedef enum {
MEMCACHED_SUCCESS,
struct memcached_stat_st {
unsigned int pid;
unsigned int uptime;
+ unsigned int threads;
time_t time;
- char *version;
- unsigned rusage_user_seconds;
+ char version[8];
+ unsigned int pointer_size;
+ unsigned int rusage_user;
+ unsigned int rusage_system;
+ unsigned int rusage_user_seconds;
unsigned int rusage_user_microseconds;
- unsigned rusage_system_seconds;
+ unsigned int rusage_system_seconds;
unsigned int rusage_system_microseconds;
unsigned int curr_items;
unsigned int total_items;
unsigned int count);
memcached_return memcached_decrement(memcached_st *ptr, char *key, size_t key_length,
unsigned int count);
-memcached_return memcached_stat(memcached_st *ptr, memcached_stat_st *stat);
+memcached_stat_st **memcached_stat(memcached_st *ptr, memcached_return *error);
+memcached_return memcached_stat_hostname(memcached_stat_st *stat, char *args,
+ char *hostname, unsigned int port);
memcached_return memcached_flush(memcached_st *ptr, time_t expiration);
char *memcached_version(memcached_st *ptr, memcached_return *error);
memcached_return memcached_verbosity(memcached_st *ptr, unsigned int verbosity);
uint16_t *flags,
memcached_return *error);
void memcached_server_add(memcached_st *ptr, char *server_name, unsigned int port);
-static memcached_return memcached_response(memcached_st *ptr,
- char *buffer, size_t buffer_length);
char *memcached_strerror(memcached_st *ptr, memcached_return rc);
+/* These are all private, do not use. */
+memcached_return memcached_connect(memcached_st *ptr);
+memcached_return memcached_response(memcached_st *ptr,
+ char *buffer,
+ size_t buffer_length);
+
#ifdef __cplusplus
}
#endif
LIBS =\r
\r
lib_LTLIBRARIES = libmemcached.la\r
-libmemcached_la_SOURCES = memcached.c\r
+libmemcached_la_SOURCES = memcached.c \\r
+ memcached_connect.c \\r
+ memcached_response.c \\r
+ memcached_get.c \\r
+ memcached_storage.c \\r
+ memcached_stats.c\r
Memcached library
*/
#include <memcached.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <limits.h>
-#include <assert.h>
-
memcached_st *memcached_init(memcached_st *ptr)
{
{
}
-static memcached_return memcached_connect(memcached_st *ptr)
-{
- int rc;
- struct sockaddr_in localAddr, servAddr;
- struct hostent *h;
- char *server_name= "localhost";
-
- if (ptr->connected)
- return MEMCACHED_SUCCESS;
-
-
- if ((h= gethostbyname(server_name)) == NULL)
- {
- fprintf(stderr, "unknown host '%s'\n", server_name);
- return MEMCACHED_HOST_LOCKUP_FAILURE;
- }
-
- servAddr.sin_family= h->h_addrtype;
- memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
- servAddr.sin_port = htons(MEMCACHED_DEFAULT_PORT);
-
- /* Create the socket */
- if ((ptr->fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
- {
- fprintf(stderr, "cannot open socket");
- return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
- }
-
-
- /* bind any port number */
- localAddr.sin_family = AF_INET;
- localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
- localAddr.sin_port = htons(0);
-
- if (bind(ptr->fd, (struct sockaddr *) &localAddr, sizeof(localAddr)) < 0)
- {
- fprintf(stderr, "cannot bind port TCP %u\n", MEMCACHED_DEFAULT_PORT);
- return(MEMCACHED_CONNECTION_BIND_FAILURE);
- }
-
- /* connect to server */
- if (connect(ptr->fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
- {
- fprintf(stderr, "cannot connect to host '%s'\n", server_name);
- return MEMCACHED_HOST_LOCKUP_FAILURE;
- }
-
- ptr->connected= 1;
-
- return MEMCACHED_SUCCESS;
-}
-
-static memcached_return memcached_response(memcached_st *ptr,
- char *buffer, size_t buffer_length)
-{
- size_t send_length;
- send_length= read(ptr->fd, buffer, buffer_length);
-
- /* This should never happen, if it does it means that key must now be quite large. */
- assert(send_length != buffer_length);
-
- if (send_length)
- switch(buffer[0])
- {
- case 'V': /* VALUE */
- return MEMCACHED_SUCCESS;
- case 'O': /* OK */
- return MEMCACHED_SUCCESS;
- case 'S': /* STORED */
- {
- if (buffer[1] == 'T')
- return MEMCACHED_SUCCESS;
- else if (buffer[1] == 'E')
- return MEMCACHED_SERVER_ERROR;
- else
- return MEMCACHED_UNKNOWN_READ_FAILURE;
- }
- case 'D': /* DELETED */
- return MEMCACHED_SUCCESS;
- case 'N': /* NOT_FOUND */
- {
- if (buffer[4] == 'F')
- return MEMCACHED_NOTFOUND;
- else if (buffer[4] == 'S')
- return MEMCACHED_NOTSTORED;
- else
- return MEMCACHED_UNKNOWN_READ_FAILURE;
- }
- case 'E': /* PROTOCOL ERROR */
- return MEMCACHED_PROTOCOL_ERROR;
- case 'C': /* CLIENT ERROR */
- return MEMCACHED_CLIENT_ERROR;
- default:
- return MEMCACHED_UNKNOWN_READ_FAILURE;
- }
-
- return MEMCACHED_READ_FAILURE;
-}
-
-static memcached_return memcached_send(memcached_st *ptr,
- char *key, size_t key_length,
- char *value, size_t value_length,
- time_t expiration,
- uint16_t flags,
- char *verb)
-{
- size_t send_length;
- memcached_return rc;
- char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-
- rc= memcached_connect(ptr);
-
- send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "%s %.*s %u %u %u\r\n", verb,
- key_length, key, flags, expiration, value_length);
- if ((send(ptr->fd, buffer, send_length, 0) == -1))
- {
- fprintf(stderr, "failed set on %.*s TCP\n", key_length+1, key);
-
- return MEMCACHED_WRITE_FAILURE;
- }
-
- send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "%.*s\r\n",
- value_length, value);
- if ((send(ptr->fd, buffer, send_length, 0) == -1))
- {
- fprintf(stderr, "failed set on %.*s TCP\n", key_length+1, key);
-
- return MEMCACHED_WRITE_FAILURE;
- }
-
- send_length= read(ptr->fd, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE);
-
- if (send_length && buffer[0] == 'S') /* STORED */
- return MEMCACHED_SUCCESS;
- else if (send_length && buffer[0] == 'N') /* NOT_STORED */
- return MEMCACHED_NOTSTORED;
- else
- return MEMCACHED_READ_FAILURE;
-}
-
-memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length,
- char *value, size_t value_length,
- time_t expiration,
- uint16_t flags)
-{
- return memcached_send(ptr, key, key_length, value, value_length,
- expiration, flags, "set");
-}
-
-memcached_return memcached_add(memcached_st *ptr, char *key, size_t key_length,
- char *value, size_t value_length,
- time_t expiration,
- uint16_t flags)
-{
- return memcached_send(ptr, key, key_length, value, value_length,
- expiration, flags, "add");
-}
-
-memcached_return memcached_replace(memcached_st *ptr, char *key, size_t key_length,
- char *value, size_t value_length,
- time_t expiration,
- uint16_t flags)
-{
- return memcached_send(ptr, key, key_length, value, value_length,
- expiration, flags, "replace");
-}
memcached_return memcached_delete(memcached_st *ptr, char *key, size_t key_length,
time_t expiration)
return MEMCACHED_SUCCESS;
}
-memcached_return memcached_stat(memcached_st *ptr, memcached_stat_st *stat)
-{
- size_t send_length;
- memcached_return rc;
- char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
-
- rc= memcached_connect(ptr);
-
- send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
- "stats \r\n");
- if ((send(ptr->fd, buffer, send_length, 0) == -1))
- {
- fprintf(stderr, "failed on stats\n");
-
- return MEMCACHED_WRITE_FAILURE;
- }
-
- while((send_length= read(ptr->fd, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE)) > 0)
- {
- if (send_length && buffer[0] == 'D') /* DELETED */
- return MEMCACHED_SUCCESS;
- else if (send_length && buffer[0] == 'N') /* NOT FOUND */
- return MEMCACHED_NOTFOUND;
- else if (send_length && buffer[0] == 'E') /* PROTOCOL ERROR */
- return MEMCACHED_PROTOCOL_ERROR;
- else if (send_length && buffer[0] == 'C') /* CLIENT ERROR */
- return MEMCACHED_CLIENT_ERROR;
- else if (send_length && buffer[0] == 'S') /* SERVER ERROR */
- return MEMCACHED_SERVER_ERROR;
- else if (send_length) /* UNKNOWN READ FAILURE */
- {
- fprintf(stderr, "UNKNOWN %.*s\n", send_length, buffer);
- return MEMCACHED_UNKNOWN_READ_FAILURE;
- }
- else
- return MEMCACHED_READ_FAILURE;
- }
-}
-
memcached_return memcached_flush(memcached_st *ptr, time_t expiration)
{
size_t send_length;
return MEMCACHED_SUCCESS;
}
-
-char *memcached_get(memcached_st *ptr, char *key, size_t key_length,
- size_t *value_length,
- uint16_t *flags,
- memcached_return *error)
-{
- size_t send_length;
- char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
- char *string_ptr;
-
- *error= memcached_connect(ptr);
-
- send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "get %.*s\r\n",
- key_length, key);
- if (*error != MEMCACHED_SUCCESS)
- return NULL;
-
- if ((send(ptr->fd, buffer, send_length, 0) == -1))
- {
- fprintf(stderr, "failed fetch on %.*s TCP\n", key_length+1, key);
- *error= MEMCACHED_WRITE_FAILURE;
- return NULL;
- }
-
- memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE);
- *error= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE);
-
- if (*error == MEMCACHED_SUCCESS)
- {
- char *end_ptr;
-
- string_ptr= buffer;
- string_ptr+= 6; /* "VALUE " */
-
- /* We do nothing with the key, since we only asked for one key */
- for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
-
- /* Flags fetch */
- string_ptr= end_ptr + 1;
- for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
- *flags= (uint16_t)strtol(string_ptr, &end_ptr, 10);
-
- /* Length fetch */
- string_ptr= end_ptr + 1;
- for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
- *value_length= strtoll(string_ptr, &end_ptr, 10);
-
- /* Skip past the \r\n */
- string_ptr= end_ptr +2;
-
- if (*value_length)
- {
- size_t need_to_copy;
- char *pos_ptr;
- char *value;
-
- value= (char *)malloc(*value_length * sizeof(char));
-
- if (!value)
- {
- *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
- return NULL;
- }
-
- need_to_copy= (*value_length < (size_t)(buffer-string_ptr))
- ? *value_length
- : (size_t)(buffer-string_ptr) ;
-
- pos_ptr= memcpy(value, string_ptr, need_to_copy);
-
- if ( need_to_copy > *value_length)
- {
- size_t read_length;
- size_t need_to_read;
-
- need_to_read= *value_length - need_to_copy;
-
- read_length= read(ptr->fd, pos_ptr, need_to_read);
- if (read_length != need_to_read)
- {
- free(value);
- *error= MEMCACHED_PARTIAL_READ;
-
- return NULL;
- }
- }
-
- return value;
- }
- }
-
- return NULL;
-}
-
void memcached_deinit(memcached_st *ptr)
{
if (ptr->fd == -1)
--- /dev/null
+#include <memcached.h>
+
+memcached_return memcached_connect(memcached_st *ptr)
+{
+ int rc;
+ struct sockaddr_in localAddr, servAddr;
+ struct hostent *h;
+ char *server_name= "localhost";
+
+ if (ptr->connected)
+ return MEMCACHED_SUCCESS;
+
+
+ if ((h= gethostbyname(server_name)) == NULL)
+ {
+ fprintf(stderr, "unknown host '%s'\n", server_name);
+ return MEMCACHED_HOST_LOCKUP_FAILURE;
+ }
+
+ servAddr.sin_family= h->h_addrtype;
+ memcpy((char *) &servAddr.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
+ servAddr.sin_port = htons(MEMCACHED_DEFAULT_PORT);
+
+ /* Create the socket */
+ if ((ptr->fd= socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ fprintf(stderr, "cannot open socket");
+ return MEMCACHED_CONNECTION_SOCKET_CREATE_FAILURE;
+ }
+
+
+ /* bind any port number */
+ localAddr.sin_family = AF_INET;
+ localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ localAddr.sin_port = htons(0);
+
+ if (bind(ptr->fd, (struct sockaddr *) &localAddr, sizeof(localAddr)) < 0)
+ {
+ fprintf(stderr, "cannot bind port TCP %u\n", MEMCACHED_DEFAULT_PORT);
+ return(MEMCACHED_CONNECTION_BIND_FAILURE);
+ }
+
+ /* connect to server */
+ if (connect(ptr->fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
+ {
+ fprintf(stderr, "cannot connect to host '%s'\n", server_name);
+ return MEMCACHED_HOST_LOCKUP_FAILURE;
+ }
+
+ ptr->connected= 1;
+
+ return MEMCACHED_SUCCESS;
+}
--- /dev/null
+#include <memcached.h>
+
+char *memcached_get(memcached_st *ptr, char *key, size_t key_length,
+ size_t *value_length,
+ uint16_t *flags,
+ memcached_return *error)
+{
+ size_t send_length;
+ char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+ char *string_ptr;
+
+ *error= memcached_connect(ptr);
+
+ send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, "get %.*s\r\n",
+ key_length, key);
+ if (*error != MEMCACHED_SUCCESS)
+ return NULL;
+
+ if ((send(ptr->fd, buffer, send_length, 0) == -1))
+ {
+ fprintf(stderr, "failed fetch on %.*s TCP\n", key_length+1, key);
+ *error= MEMCACHED_WRITE_FAILURE;
+ return NULL;
+ }
+
+ memset(buffer, 0, MEMCACHED_DEFAULT_COMMAND_SIZE);
+ *error= memcached_response(ptr, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE);
+
+ if (*error == MEMCACHED_SUCCESS)
+ {
+ char *end_ptr;
+
+ string_ptr= buffer;
+ string_ptr+= 6; /* "VALUE " */
+
+ /* We do nothing with the key, since we only asked for one key */
+ for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
+
+ /* Flags fetch */
+ string_ptr= end_ptr + 1;
+ for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
+ *flags= (uint16_t)strtol(string_ptr, &end_ptr, 10);
+
+ /* Length fetch */
+ string_ptr= end_ptr + 1;
+ for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
+ *value_length= strtoll(string_ptr, &end_ptr, 10);
+
+ /* Skip past the \r\n */
+ string_ptr= end_ptr +2;
+
+ if (*value_length)
+ {
+ size_t need_to_copy;
+ char *pos_ptr;
+ char *value;
+
+ value= (char *)malloc(*value_length * sizeof(char));
+
+ if (!value)
+ {
+ *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
+ return NULL;
+ }
+
+ need_to_copy= (*value_length < (size_t)(buffer-string_ptr))
+ ? *value_length
+ : (size_t)(buffer-string_ptr) ;
+
+ pos_ptr= memcpy(value, string_ptr, need_to_copy);
+
+ if ( need_to_copy > *value_length)
+ {
+ size_t read_length;
+ size_t need_to_read;
+
+ need_to_read= *value_length - need_to_copy;
+
+ read_length= read(ptr->fd, pos_ptr, need_to_read);
+ if (read_length != need_to_read)
+ {
+ free(value);
+ *error= MEMCACHED_PARTIAL_READ;
+
+ return NULL;
+ }
+ }
+
+ return value;
+ }
+ }
+
+ return NULL;
+}
--- /dev/null
+/*
+ Memcached library
+
+ memcached_response() is used to determine the return result
+ from an issued command.
+*/
+
+#include <memcached.h>
+
+memcached_return memcached_response(memcached_st *ptr,
+ char *buffer, size_t buffer_length)
+{
+ size_t send_length;
+
+ memset(buffer, 0, buffer_length);
+ send_length= read(ptr->fd, buffer, buffer_length);
+
+ if (send_length)
+ switch(buffer[0])
+ {
+ case 'V': /* VALUE */
+ return MEMCACHED_SUCCESS;
+ case 'O': /* OK */
+ return MEMCACHED_SUCCESS;
+ case 'S': /* STORED STATS SERVER_ERROR */
+ {
+ if (buffer[1] == 'T') /* STORED STATS */
+ return MEMCACHED_SUCCESS;
+ else if (buffer[1] == 'E')
+ return MEMCACHED_SERVER_ERROR;
+ else
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
+ }
+ case 'D': /* DELETED */
+ return MEMCACHED_SUCCESS;
+ case 'N': /* NOT_FOUND */
+ {
+ if (buffer[4] == 'F')
+ return MEMCACHED_NOTFOUND;
+ else if (buffer[4] == 'S')
+ return MEMCACHED_NOTSTORED;
+ else
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
+ }
+ case 'E': /* PROTOCOL ERROR */
+ return MEMCACHED_PROTOCOL_ERROR;
+ case 'C': /* CLIENT ERROR */
+ return MEMCACHED_CLIENT_ERROR;
+ default:
+ return MEMCACHED_UNKNOWN_READ_FAILURE;
+ }
+
+ return MEMCACHED_READ_FAILURE;
+}
--- /dev/null
+/*
+*/
+
+#include <memcached.h>
+
+static void set_data(memcached_stat_st *stat, char *key, char *value)
+{
+ if (!memcmp("pid", key, strlen("pid")))
+ {
+ stat->pid= strtol(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("uptime", key, strlen("uptime")))
+ {
+ stat->uptime= strtol(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("time", key, strlen("time")))
+ {
+ stat->time= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("version", key, strlen("version")))
+ {
+ memcpy(stat->version, value, 8);
+ }
+ else if (!memcmp("pointer_size", key, strlen("pointer_size")))
+ {
+ stat->pointer_size= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("rusage_user", key, strlen("rusage_user")))
+ {
+ stat->rusage_user= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("rusage_system", key, strlen("rusage_system")))
+ {
+ stat->rusage_system= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("rusage_user_seconds", key, strlen("rusage_user_seconds")))
+ {
+ stat->rusage_user_seconds= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("rusage_user_microseconds", key, strlen("rusage_user_microseconds")))
+ {
+ stat->rusage_user_microseconds= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("rusage_system_seconds", key, strlen("rusage_system_seconds")))
+ {
+ stat->rusage_system_seconds= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("rusage_system_microseconds", key, strlen("rusage_system_microseconds")))
+ {
+ stat->rusage_system_microseconds= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("curr_items", key, strlen("curr_items")))
+ {
+ stat->curr_items= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("total_items", key, strlen("total_items")))
+ {
+ stat->total_items= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("bytes", key, strlen("bytes")))
+ {
+ stat->bytes= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("curr_connections", key, strlen("curr_connections")))
+ {
+ stat->curr_connections= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("total_connections", key, strlen("total_connections")))
+ {
+ stat->total_connections= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("connection_structures", key, strlen("connection_structures")))
+ {
+ stat->connection_structures= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("cmd_get", key, strlen("cmd_get")))
+ {
+ stat->cmd_get= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("cmd_set", key, strlen("cmd_set")))
+ {
+ stat->cmd_set= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("get_hits", key, strlen("get_hits")))
+ {
+ stat->get_hits= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("get_misses", key, strlen("get_misses")))
+ {
+ stat->get_misses= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("evictions", key, strlen("evictions")))
+ {
+ stat->evictions= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("bytes_read", key, strlen("bytes_read")))
+ {
+ stat->bytes_read= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("bytes_written", key, strlen("bytes_written")))
+ {
+ stat->bytes_written= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("limit_maxbytes", key, strlen("limit_maxbytes")))
+ {
+ stat->limit_maxbytes= strtoll(value, (char **)NULL, 10);
+ }
+ else if (!memcmp("threads", key, strlen("threads")))
+ {
+ stat->threads= strtol(key, (char **)NULL, 10);
+ }
+ else
+ {
+ fprintf(stderr, "Unknown key %s\n", key);
+ }
+}
+
+memcached_stat_st **memcached_stat(memcached_st *ptr, memcached_return *error)
+{
+ return NULL;
+}
+
+memcached_return memcached_stat_hostname(memcached_stat_st *stat, char *args,
+ char *hostname, unsigned int port)
+{
+ size_t send_length;
+ memcached_return rc;
+ char buffer[HUGE_STRING_LEN];
+ memcached_st memc;
+
+ memcached_init(&memc);
+
+ rc= memcached_connect(&memc);
+
+ if (args)
+ send_length= snprintf(buffer, HUGE_STRING_LEN,
+ "stats %s\r\n", args);
+ else
+ send_length= snprintf(buffer, HUGE_STRING_LEN,
+ "stats\r\n");
+
+ if ((send(memc.fd, buffer, send_length, 0) == -1))
+ {
+ fprintf(stderr, "failed on stats\n");
+
+ rc= MEMCACHED_WRITE_FAILURE;
+ goto error;
+ }
+
+ rc= memcached_response(&memc, buffer, HUGE_STRING_LEN);
+
+ if (rc == MEMCACHED_SUCCESS)
+ {
+ char *string_ptr, *end_ptr;
+ char *key, *value;
+
+ string_ptr= buffer;
+ while (1)
+ {
+ if (memcmp(string_ptr, "STAT ", 5))
+ break;
+ string_ptr+= 5;
+ for (end_ptr= string_ptr; *end_ptr != ' '; end_ptr++);
+ key= string_ptr;
+ key[(size_t)(end_ptr-string_ptr)]= 0;
+ printf("Key %s\n", key);
+
+ string_ptr= end_ptr + 1;
+ for (end_ptr= string_ptr; *end_ptr != '\r'; end_ptr++);
+ value= string_ptr;
+ value[(size_t)(end_ptr-string_ptr)]= 0;
+ printf("Value %s\n", value);
+ string_ptr= end_ptr + 2;
+ set_data(stat, key, value);
+ }
+ }
+
+error:
+ memcached_deinit(&memc);
+
+ return rc;
+}
--- /dev/null
+/*
+ Memcached library
+
+ memcached_set()
+ memcached_replace()
+ memcached_add()
+
+*/
+
+#include <memcached.h>
+
+static memcached_return memcached_send(memcached_st *ptr,
+ char *key, size_t key_length,
+ char *value, size_t value_length,
+ time_t expiration,
+ uint16_t flags,
+ char *verb)
+{
+ size_t send_length;
+ memcached_return rc;
+ char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
+
+ rc= memcached_connect(ptr);
+
+ send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+ "%s %.*s %u %u %u\r\n", verb,
+ key_length, key, flags, expiration, value_length);
+ if ((send(ptr->fd, buffer, send_length, 0) == -1))
+ {
+ fprintf(stderr, "failed set on %.*s TCP\n", key_length+1, key);
+
+ return MEMCACHED_WRITE_FAILURE;
+ }
+
+ send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
+ "%.*s\r\n",
+ value_length, value);
+ if ((send(ptr->fd, buffer, send_length, 0) == -1))
+ {
+ fprintf(stderr, "failed set on %.*s TCP\n", key_length+1, key);
+
+ return MEMCACHED_WRITE_FAILURE;
+ }
+
+ send_length= read(ptr->fd, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE);
+
+ if (send_length && buffer[0] == 'S') /* STORED */
+ return MEMCACHED_SUCCESS;
+ else if (send_length && buffer[0] == 'N') /* NOT_STORED */
+ return MEMCACHED_NOTSTORED;
+ else
+ return MEMCACHED_READ_FAILURE;
+}
+
+memcached_return memcached_set(memcached_st *ptr, char *key, size_t key_length,
+ char *value, size_t value_length,
+ time_t expiration,
+ uint16_t flags)
+{
+ return memcached_send(ptr, key, key_length, value, value_length,
+ expiration, flags, "set");
+}
+
+memcached_return memcached_add(memcached_st *ptr, char *key, size_t key_length,
+ char *value, size_t value_length,
+ time_t expiration,
+ uint16_t flags)
+{
+ return memcached_send(ptr, key, key_length, value, value_length,
+ expiration, flags, "add");
+}
+
+memcached_return memcached_replace(memcached_st *ptr, char *key, size_t key_length,
+ char *value, size_t value_length,
+ time_t expiration,
+ uint16_t flags)
+{
+ return memcached_send(ptr, key, key_length, value, value_length,
+ expiration, flags, "replace");
+}
memcached_deinit(memc);
}
+void stats_hostname_test(void)
+{
+ memcached_return rc;
+ memcached_stat_st stat;
+ rc= memcached_stat_hostname(&stat, NULL,
+ "localhost",
+ MEMCACHED_DEFAULT_PORT);
+}
+
int main(void)
{
/* Clean the server before beginning testing */
flush_test();
get_test();
get_test2();
+ stats_hostname_test();
/* Clean up whatever we might have left */
flush_test();