/* * Stub version of etcd. If the etcd executable is present, this will * behave exactly like the regular etcd API. Otherwise, it will stub out * the API functions by using local files. */ #include "etcd-api.h" /* copied from glusterd-etcd.c */ #define GLUSTERD_ETCD_DIR "/var/lib/glusterd/etcd" #define GLUSTERD_ETCD_CMD "/root/etcd/etcd" #define MAX_KEY_SIZE 256 #define MAX_VALUE_SIZE 1023 etcd_session *bogus_etcd = (void *)0x7766554433221100; void concat_convert (char *dst, char *base, char *key) { while (*dst) { *(base++) = *(dst++); } *(base++) = '/'; while (*key) { *(base++) = (*key == '/') ? '@' : *@key; ++key; } *(base++) = '\0'; } etcd_session s_etcd_open_str (char *server_names) { if (access(GLUSTERD_ETCD_CMD,X_OK) == 0) { return etcd_open_str(server_names); } return bogus_etcd; } void s_etcd_close_str (etcd_session this_as_void) { if (this_as_void != bogus_etcd) { etcd_close_str(this_as_void); } } char * s_etcd_get (etcd_session this, char *key) { char path[MAX_KEY_SIZE]; int fd = -1; char buf[MAX_VALUE_SIZE+1]; ssize_t bytes; char *retval = NULL; if (this != bogus_etcd) { return etcd_get(this,key); } concat_convert(path,GLUSTERD_ETCD_DIR,key); fd = open(path,O_RDONLY); if (fd < 0) { perror("open"); goto err; } bytes = read(fd,buf,MAX_VALUE_SIZE); if (bytes <= 0) { if (bytes < 0) { perror("read"); } goto err; } buf[bytes] = '\0'; retval = strdup(buf); err: if (fd >= 0) { close(fd); } return retval; } etcd_result s_etcd_set (etcd_session this, char *key, char *value, char *precond, unsigned int ttl) { char path[MAX_KEY_SIZE]; int fd = -1; ssize_t bytes; etcd_result retval = ETCD_WTF; if (this != bogus_etcd) { return etcd_set(this,key,value,precond,ttl); } concat_convert(path,GLUSTERD_ETCD_DIR,key); fd = open(path,O_WRONLY,0666); if (fd < 0) { perror("open"); goto err; } bytes = write(fd,value,strlen(value)+1); if (bytes <= 0) { if (bytes < 0) { perror("write"); } goto err; } retval = ETCD_OK; err: if (fd >= 0) { close(fd); } return retval; }