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