Fix for bug 633247
[m6w6/libmemcached] / libmemcached / flush.c
1 #include "common.h"
2
3 static memcached_return_t memcached_flush_binary(memcached_st *ptr,
4 time_t expiration);
5 static memcached_return_t memcached_flush_textual(memcached_st *ptr,
6 time_t expiration);
7
8 memcached_return_t memcached_flush(memcached_st *ptr, time_t expiration)
9 {
10 memcached_return_t rc;
11
12 LIBMEMCACHED_MEMCACHED_FLUSH_START();
13 if (ptr->flags.binary_protocol)
14 rc= memcached_flush_binary(ptr, expiration);
15 else
16 rc= memcached_flush_textual(ptr, expiration);
17 LIBMEMCACHED_MEMCACHED_FLUSH_END();
18 return rc;
19 }
20
21 static memcached_return_t memcached_flush_textual(memcached_st *ptr,
22 time_t expiration)
23 {
24 unlikely (memcached_server_count(ptr) == 0)
25 return MEMCACHED_NO_SERVERS;
26
27 for (unsigned int x= 0; x < memcached_server_count(ptr); x++)
28 {
29 memcached_return_t rc;
30 char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE];
31
32 bool no_reply= ptr->flags.no_reply;
33 memcached_server_write_instance_st instance=
34 memcached_server_instance_fetch(ptr, x);
35
36 int send_length;
37 if (expiration)
38 {
39 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
40 "flush_all %llu%s\r\n",
41 (unsigned long long)expiration, no_reply ? " noreply" : "");
42 }
43 else
44 {
45 send_length= snprintf(buffer, MEMCACHED_DEFAULT_COMMAND_SIZE,
46 "flush_all%s\r\n", no_reply ? " noreply" : "");
47 }
48
49 if (send_length >= MEMCACHED_DEFAULT_COMMAND_SIZE || send_length < 0)
50 {
51 return MEMCACHED_FAILURE;
52 }
53
54 rc= memcached_do(instance, buffer, (size_t)send_length, true);
55
56 if (rc == MEMCACHED_SUCCESS && !no_reply)
57 (void)memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, NULL);
58 }
59
60 return MEMCACHED_SUCCESS;
61 }
62
63 static memcached_return_t memcached_flush_binary(memcached_st *ptr,
64 time_t expiration)
65 {
66 protocol_binary_request_flush request= {.bytes= {0}};
67
68 unlikely (memcached_server_count(ptr) == 0)
69 return MEMCACHED_NO_SERVERS;
70
71 request.message.header.request.magic= (uint8_t)PROTOCOL_BINARY_REQ;
72 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_FLUSH;
73 request.message.header.request.extlen= 4;
74 request.message.header.request.datatype= PROTOCOL_BINARY_RAW_BYTES;
75 request.message.header.request.bodylen= htonl(request.message.header.request.extlen);
76 request.message.body.expiration= htonl((uint32_t) expiration);
77
78 for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
79 {
80 memcached_server_write_instance_st instance=
81 memcached_server_instance_fetch(ptr, x);
82
83 if (ptr->flags.no_reply)
84 {
85 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_FLUSHQ;
86 }
87 else
88 {
89 request.message.header.request.opcode= PROTOCOL_BINARY_CMD_FLUSH;
90 }
91
92 if (memcached_do(instance, request.bytes, sizeof(request.bytes), true) != MEMCACHED_SUCCESS)
93 {
94 memcached_io_reset(instance);
95 return MEMCACHED_WRITE_FAILURE;
96 }
97 }
98
99 for (uint32_t x= 0; x < memcached_server_count(ptr); x++)
100 {
101 memcached_server_write_instance_st instance=
102 memcached_server_instance_fetch(ptr, x);
103
104 if (memcached_server_response_count(instance) > 0)
105 (void)memcached_response(instance, NULL, 0, NULL);
106 }
107
108 return MEMCACHED_SUCCESS;
109 }