Added support for UNIX sockets.
[awesomized/libmemcached] / lib / memcached_hosts.c
1 #include <memcached.h>
2 #include "common.h"
3
4 /* Protoypes (static) */
5 static memcached_return server_add(memcached_st *ptr, char *hostname,
6 unsigned int port,
7 memcached_connection type);
8
9 static void host_reset(memcached_server_st *host, char *new_hostname, unsigned int port,
10 memcached_connection type)
11 {
12 host->stack_responses= 0;
13 host->cursor_active= 0;
14 host->hostname= new_hostname;
15 host->port= port;
16 host->fd= -1;
17 host->type= type;
18 }
19
20 memcached_return memcached_server_push(memcached_st *ptr, memcached_server_st *list)
21 {
22 unsigned int x;
23 unsigned int count;
24 memcached_server_st *new_host_list;
25
26 if (!list)
27 return MEMCACHED_SUCCESS;
28
29 for (count= 0; list[count].hostname; count++);
30
31 new_host_list=
32 (memcached_server_st *)realloc(ptr->hosts,
33 sizeof(memcached_server_st) * (count + ptr->number_of_hosts + 1));
34
35 if (!new_host_list)
36 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
37
38 ptr->hosts= new_host_list;
39
40 for (x= 0; list[x].hostname; x++)
41 {
42 ptr->hosts[ptr->number_of_hosts].hostname= strdup(list[x].hostname);
43 ptr->hosts[ptr->number_of_hosts].port= list[x].port;
44 ptr->hosts[ptr->number_of_hosts].fd= list[x].fd;
45 ptr->hosts[ptr->number_of_hosts].stack_responses= list[x].stack_responses;
46 ptr->hosts[ptr->number_of_hosts].cursor_active= list[x].cursor_active;
47 ptr->hosts[ptr->number_of_hosts].type= list[x].type;
48 ptr->number_of_hosts++;
49 }
50 host_reset(&ptr->hosts[ptr->number_of_hosts], NULL, 0,
51 MEMCACHED_CONNECTION_UNKNOWN);
52
53 return MEMCACHED_SUCCESS;
54 }
55
56 memcached_return memcached_server_add_unix_socket(memcached_st *ptr, char *filename)
57 {
58 if (!filename)
59 return MEMCACHED_FAILURE;
60
61 return server_add(ptr, filename, 0, MEMCACHED_CONNECTION_UNIX_SOCKET);
62 }
63
64 memcached_return memcached_server_add(memcached_st *ptr, char *hostname, unsigned int port)
65 {
66 if (!port)
67 port= MEMCACHED_DEFAULT_PORT;
68
69 if (!hostname)
70 hostname= "localhost";
71
72 return server_add(ptr, hostname, port, MEMCACHED_CONNECTION_TCP);
73 }
74
75 static memcached_return server_add(memcached_st *ptr, char *hostname,
76 unsigned int port,
77 memcached_connection type)
78 {
79 memcached_server_st *new_host_list;
80 char *new_hostname;
81 LIBMEMCACHED_MEMCACHED_SERVER_ADD_START();
82
83
84 if (ptr->number_of_hosts)
85 {
86 new_host_list= (memcached_server_st *)realloc(ptr->hosts,
87 sizeof(memcached_server_st) * (ptr->number_of_hosts+1));
88 if (!new_host_list)
89 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
90 host_reset(&new_host_list[ptr->number_of_hosts], NULL, 0,
91 MEMCACHED_CONNECTION_UNKNOWN);
92 }
93 else
94 {
95 new_host_list=
96 (memcached_server_st *)malloc(sizeof(memcached_server_st) * 2);
97 if (!new_host_list)
98 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
99 host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
100 host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
101 }
102
103 ptr->hosts= new_host_list;
104
105 new_hostname=
106 (char *)malloc(sizeof(char) * (strlen(hostname)+1));
107
108 if (!new_hostname)
109 return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
110
111 memset(new_hostname, 0, strlen(hostname)+1);
112 memcpy(new_hostname, hostname, strlen(hostname));
113 host_reset(&ptr->hosts[ptr->number_of_hosts], new_hostname, port, type);
114 ptr->number_of_hosts++;
115
116 LIBMEMCACHED_MEMCACHED_SERVER_ADD_END();
117
118 return MEMCACHED_SUCCESS;
119 }
120
121 memcached_server_st *memcached_server_list_append(memcached_server_st *ptr,
122 char *hostname, unsigned int port,
123 memcached_return *error)
124 {
125 unsigned int count;
126 memcached_server_st *new_host_list;
127 char *new_hostname;
128
129 if (!hostname)
130 return ptr;
131
132 if (!port)
133 port= MEMCACHED_DEFAULT_PORT;
134
135 /* Always count so that we keep a free host at the end */
136 if (ptr)
137 {
138 for (count= 0; ptr[count].hostname; count++);
139 count+= 2;
140 new_host_list= (memcached_server_st *)realloc(ptr, sizeof(memcached_server_st) * count);
141 if (!new_host_list)
142 goto error;
143 host_reset(&new_host_list[count-1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
144 }
145 else
146 {
147 count= 2;
148 new_host_list= (memcached_server_st *)malloc(sizeof(memcached_server_st) * count);
149 if (!new_host_list)
150 goto error;
151 host_reset(&new_host_list[0], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
152 host_reset(&new_host_list[1], NULL, 0, MEMCACHED_CONNECTION_UNKNOWN);
153 }
154
155 new_hostname= strdup(hostname);
156
157 if (!new_hostname)
158 goto error;
159
160 host_reset(&new_host_list[count-2], new_hostname, port, MEMCACHED_CONNECTION_TCP);
161
162 *error= MEMCACHED_SUCCESS;
163 return new_host_list;
164 error:
165 *error= MEMCACHED_MEMORY_ALLOCATION_FAILURE;
166
167 return NULL;
168 }
169
170 unsigned int memcached_server_list_count(memcached_server_st *ptr)
171 {
172 unsigned int x;
173
174 for (x= 0; ptr[x].hostname; x++);
175
176 return x;
177 }
178
179 void memcached_server_list_free(memcached_server_st *ptr)
180 {
181 unsigned int x;
182
183 for (x= 0; ptr[x].hostname; x++)
184 free(ptr[x].hostname);
185
186 free(ptr);
187 }