1 /* -*- Mode: C; tab-width: 2; c-basic-offset: 2; indent-tabs-mode: nil -*- */
3 * This file contains an implementation of the callback interface for level 0
4 * in the protocol library. You might want to have your copy of the protocol
5 * specification next to your coffee ;-)
17 #include <libmemcached/protocol_handler.h>
18 #include <libmemcached/byteorder.h>
20 #include "memcached_light.h"
22 static protocol_binary_response_status
noop_command_handler(const void *cookie
,
23 protocol_binary_request_header
*header
,
24 memcached_binary_protocol_raw_response_handler response_handler
)
26 protocol_binary_response_no_extras response
= {
27 .message
.header
.response
= {
28 .magic
= PROTOCOL_BINARY_RES
,
29 .opcode
= PROTOCOL_BINARY_CMD_NOOP
,
30 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
31 .opaque
= header
->request
.opaque
35 return response_handler(cookie
, header
, (void*)&response
);
38 static protocol_binary_response_status
quit_command_handler(const void *cookie
,
39 protocol_binary_request_header
*header
,
40 memcached_binary_protocol_raw_response_handler response_handler
)
42 protocol_binary_response_no_extras response
= {
43 .message
.header
.response
= {
44 .magic
= PROTOCOL_BINARY_RES
,
45 .opcode
= PROTOCOL_BINARY_CMD_QUIT
,
46 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
47 .opaque
= header
->request
.opaque
51 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_QUIT
)
52 response_handler(cookie
, header
, (void*)&response
);
54 /* I need a better way to signal to close the connection */
55 return PROTOCOL_BINARY_RESPONSE_EIO
;
58 static protocol_binary_response_status
get_command_handler(const void *cookie
,
59 protocol_binary_request_header
*header
,
60 memcached_binary_protocol_raw_response_handler response_handler
)
62 uint8_t opcode
= header
->request
.opcode
;
64 protocol_binary_response_get response
;
67 .response
.message
.header
.response
= {
68 .magic
= PROTOCOL_BINARY_RES
,
70 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
71 .opaque
= header
->request
.opaque
75 struct item
*item
= get_item(header
+ 1, ntohs(header
->request
.keylen
));
78 msg
.response
.message
.body
.flags
= htonl(item
->flags
);
79 char *ptr
= (char*)(msg
.response
.bytes
+ sizeof(*header
) + 4);
81 msg
.response
.message
.header
.response
.cas
= htonll(item
->cas
);
82 if (opcode
== PROTOCOL_BINARY_CMD_GETK
|| opcode
== PROTOCOL_BINARY_CMD_GETKQ
)
84 memcpy(ptr
, item
->key
, item
->nkey
);
85 msg
.response
.message
.header
.response
.keylen
= htons((uint16_t)item
->nkey
);
87 bodysize
+= (uint32_t)item
->nkey
;
89 memcpy(ptr
, item
->data
, item
->size
);
90 bodysize
+= (uint32_t)item
->size
;
91 msg
.response
.message
.header
.response
.bodylen
= htonl(bodysize
);
92 msg
.response
.message
.header
.response
.extlen
= 4;
95 return response_handler(cookie
, header
, (void*)&msg
);
97 else if (opcode
== PROTOCOL_BINARY_CMD_GET
|| opcode
== PROTOCOL_BINARY_CMD_GETK
)
99 msg
.response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT
);
100 return response_handler(cookie
, header
, (void*)&msg
);
103 /* Q shouldn't report a miss ;-) */
104 return PROTOCOL_BINARY_RESPONSE_SUCCESS
;
107 static protocol_binary_response_status
delete_command_handler(const void *cookie
,
108 protocol_binary_request_header
*header
,
109 memcached_binary_protocol_raw_response_handler response_handler
)
111 size_t keylen
= ntohs(header
->request
.keylen
);
112 char *key
= ((char*)header
) + sizeof(*header
);
113 protocol_binary_response_no_extras response
= {
114 .message
.header
.response
= {
115 .magic
= PROTOCOL_BINARY_RES
,
116 .opcode
= header
->request
.opcode
,
117 .opaque
= header
->request
.opaque
121 if (!delete_item(key
, keylen
))
123 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT
);
124 return response_handler(cookie
, header
, (void*)&response
);
126 else if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_DELETE
)
128 /* DELETEQ doesn't want success response */
129 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
);
130 return response_handler(cookie
, header
, (void*)&response
);
133 return PROTOCOL_BINARY_RESPONSE_SUCCESS
;
136 static protocol_binary_response_status
flush_command_handler(const void *cookie
,
137 protocol_binary_request_header
*header
,
138 memcached_binary_protocol_raw_response_handler response_handler
)
140 uint8_t opcode
= header
->request
.opcode
;
142 /* @fixme sett inn when! */
145 if (opcode
== PROTOCOL_BINARY_CMD_FLUSH
)
147 protocol_binary_response_no_extras response
= {
148 .message
.header
.response
= {
149 .magic
= PROTOCOL_BINARY_RES
,
151 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
152 .opaque
= header
->request
.opaque
155 return response_handler(cookie
, header
, (void*)&response
);
158 return PROTOCOL_BINARY_RESPONSE_SUCCESS
;
161 static protocol_binary_response_status
arithmetic_command_handler(const void *cookie
,
162 protocol_binary_request_header
*header
,
163 memcached_binary_protocol_raw_response_handler response_handler
)
165 protocol_binary_request_incr
*req
= (void*)header
;
166 protocol_binary_response_incr response
= {
167 .message
.header
.response
= {
168 .magic
= PROTOCOL_BINARY_RES
,
169 .opcode
= header
->request
.opcode
,
170 .opaque
= header
->request
.opaque
,
174 uint16_t keylen
= ntohs(header
->request
.keylen
);
175 uint64_t initial
= ntohll(req
->message
.body
.initial
);
176 uint64_t delta
= ntohll(req
->message
.body
.delta
);
177 uint32_t expiration
= ntohl(req
->message
.body
.expiration
);
179 void *key
= req
->bytes
+ sizeof(req
->bytes
);
180 protocol_binary_response_status rval
= PROTOCOL_BINARY_RESPONSE_SUCCESS
;
182 uint64_t value
= initial
;
184 struct item
*item
= get_item(key
, keylen
);
187 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_INCREMENT
||
188 header
->request
.opcode
== PROTOCOL_BINARY_CMD_INCREMENTQ
)
190 value
= (*(uint64_t*)item
->data
) + delta
;
194 if (delta
> *(uint64_t*)item
->data
)
200 value
= *(uint64_t*)item
->data
- delta
;
203 expiration
= (uint32_t)item
->exp
;
207 delete_item(key
, keylen
);
210 item
= create_item(key
, keylen
, NULL
, sizeof(value
), flags
, (time_t)expiration
);
213 rval
= PROTOCOL_BINARY_RESPONSE_ENOMEM
;
217 memcpy(item
->data
, &value
, sizeof(value
));
221 response
.message
.header
.response
.status
= htons(rval
);
222 if (rval
== PROTOCOL_BINARY_RESPONSE_SUCCESS
)
224 response
.message
.header
.response
.bodylen
= ntohl(8);
225 response
.message
.body
.value
= ntohll((*(uint64_t*)item
->data
));
226 response
.message
.header
.response
.cas
= ntohll(item
->cas
);
229 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_INCREMENTQ
||
230 header
->request
.opcode
== PROTOCOL_BINARY_CMD_DECREMENTQ
)
232 return PROTOCOL_BINARY_RESPONSE_SUCCESS
;
236 return response_handler(cookie
, header
, (void*)&response
);
239 static protocol_binary_response_status
version_command_handler(const void *cookie
,
240 protocol_binary_request_header
*header
,
241 memcached_binary_protocol_raw_response_handler response_handler
)
243 const char *versionstring
= "1.0.0";
245 protocol_binary_response_header packet
;
249 .magic
= PROTOCOL_BINARY_RES
,
250 .opcode
= PROTOCOL_BINARY_CMD_VERSION
,
251 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
252 .opaque
= header
->request
.opaque
,
253 .bodylen
= htonl((uint32_t)strlen(versionstring
))
257 memcpy(response
.buffer
+ sizeof(response
.packet
), versionstring
, strlen(versionstring
));
259 return response_handler(cookie
, header
, (void*)&response
);
262 static protocol_binary_response_status
concat_command_handler(const void *cookie
,
263 protocol_binary_request_header
*header
,
264 memcached_binary_protocol_raw_response_handler response_handler
)
266 protocol_binary_response_status rval
= PROTOCOL_BINARY_RESPONSE_SUCCESS
;
267 uint16_t keylen
= ntohs(header
->request
.keylen
);
268 uint64_t cas
= ntohll(header
->request
.cas
);
269 void *key
= header
+ 1;
270 uint32_t vallen
= ntohl(header
->request
.bodylen
) - keylen
;
271 void *val
= (char*)key
+ keylen
;
273 struct item
*item
= get_item(key
, keylen
);
274 struct item
*nitem
= NULL
;
278 rval
= PROTOCOL_BINARY_RESPONSE_KEY_ENOENT
;
280 else if (cas
!= 0 && cas
!= item
->cas
)
282 rval
= PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS
;
284 else if ((nitem
= create_item(key
, keylen
, NULL
, item
->size
+ vallen
,
285 item
->flags
, item
->exp
)) == NULL
)
288 rval
= PROTOCOL_BINARY_RESPONSE_ENOMEM
;
292 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_APPEND
||
293 header
->request
.opcode
== PROTOCOL_BINARY_CMD_APPENDQ
)
295 memcpy(nitem
->data
, item
->data
, item
->size
);
296 memcpy(((char*)(nitem
->data
)) + item
->size
, val
, vallen
);
300 memcpy(nitem
->data
, val
, vallen
);
301 memcpy(((char*)(nitem
->data
)) + vallen
, item
->data
, item
->size
);
304 delete_item(key
, keylen
);
309 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_APPEND
||
310 header
->request
.opcode
== PROTOCOL_BINARY_CMD_PREPEND
)
312 protocol_binary_response_no_extras response
= {
315 .magic
= PROTOCOL_BINARY_RES
,
316 .opcode
= header
->request
.opcode
,
317 .status
= htons(rval
),
318 .opaque
= header
->request
.opaque
,
323 return response_handler(cookie
, header
, (void*)&response
);
330 static protocol_binary_response_status
set_command_handler(const void *cookie
,
331 protocol_binary_request_header
*header
,
332 memcached_binary_protocol_raw_response_handler response_handler
)
334 size_t keylen
= ntohs(header
->request
.keylen
);
335 size_t datalen
= ntohl(header
->request
.bodylen
) - keylen
- 8;
336 protocol_binary_request_replace
*request
= (void*)header
;
337 uint32_t flags
= ntohl(request
->message
.body
.flags
);
338 time_t timeout
= (time_t)ntohl(request
->message
.body
.expiration
);
339 char *key
= ((char*)header
) + sizeof(*header
) + 8;
340 char *data
= key
+ keylen
;
342 protocol_binary_response_no_extras response
= {
345 .magic
= PROTOCOL_BINARY_RES
,
346 .opcode
= header
->request
.opcode
,
347 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
348 .opaque
= header
->request
.opaque
353 if (header
->request
.cas
!= 0)
356 struct item
* item
= get_item(key
, keylen
);
359 if (item
->cas
!= ntohll(header
->request
.cas
))
362 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS
);
363 return response_handler(cookie
, header
, (void*)&response
);
369 delete_item(key
, keylen
);
370 struct item
* item
= create_item(key
, keylen
, data
, datalen
, flags
, timeout
);
373 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM
);
378 /* SETQ shouldn't return a message */
379 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_SET
)
381 response
.message
.header
.response
.cas
= htonll(item
->cas
);
383 return response_handler(cookie
, header
, (void*)&response
);
387 return PROTOCOL_BINARY_RESPONSE_SUCCESS
;
390 return response_handler(cookie
, header
, (void*)&response
);
393 static protocol_binary_response_status
add_command_handler(const void *cookie
,
394 protocol_binary_request_header
*header
,
395 memcached_binary_protocol_raw_response_handler response_handler
)
397 size_t keylen
= ntohs(header
->request
.keylen
);
398 size_t datalen
= ntohl(header
->request
.bodylen
) - keylen
- 8;
399 protocol_binary_request_add
*request
= (void*)header
;
400 uint32_t flags
= ntohl(request
->message
.body
.flags
);
401 time_t timeout
= (time_t)ntohl(request
->message
.body
.expiration
);
402 char *key
= ((char*)header
) + sizeof(*header
) + 8;
403 char *data
= key
+ keylen
;
405 protocol_binary_response_no_extras response
= {
408 .magic
= PROTOCOL_BINARY_RES
,
409 .opcode
= header
->request
.opcode
,
410 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
411 .opaque
= header
->request
.opaque
416 struct item
* item
= get_item(key
, keylen
);
419 item
= create_item(key
, keylen
, data
, datalen
, flags
, timeout
);
421 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM
);
425 /* ADDQ shouldn't return a message */
426 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_ADD
)
428 response
.message
.header
.response
.cas
= htonll(item
->cas
);
430 return response_handler(cookie
, header
, (void*)&response
);
433 return PROTOCOL_BINARY_RESPONSE_SUCCESS
;
439 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS
);
442 return response_handler(cookie
, header
, (void*)&response
);
445 static protocol_binary_response_status
replace_command_handler(const void *cookie
,
446 protocol_binary_request_header
*header
,
447 memcached_binary_protocol_raw_response_handler response_handler
)
449 size_t keylen
= ntohs(header
->request
.keylen
);
450 size_t datalen
= ntohl(header
->request
.bodylen
) - keylen
- 8;
451 protocol_binary_request_replace
*request
= (void*)header
;
452 uint32_t flags
= ntohl(request
->message
.body
.flags
);
453 time_t timeout
= (time_t)ntohl(request
->message
.body
.expiration
);
454 char *key
= ((char*)header
) + sizeof(*header
) + 8;
455 char *data
= key
+ keylen
;
457 protocol_binary_response_no_extras response
= {
460 .magic
= PROTOCOL_BINARY_RES
,
461 .opcode
= header
->request
.opcode
,
462 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
463 .opaque
= header
->request
.opaque
468 struct item
* item
= get_item(key
, keylen
);
470 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_KEY_ENOENT
);
471 else if (header
->request
.cas
== 0 || ntohll(header
->request
.cas
) == item
->cas
)
474 delete_item(key
, keylen
);
475 item
= create_item(key
, keylen
, data
, datalen
, flags
, timeout
);
477 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_ENOMEM
);
481 /* REPLACEQ shouldn't return a message */
482 if (header
->request
.opcode
== PROTOCOL_BINARY_CMD_REPLACE
)
484 response
.message
.header
.response
.cas
= htonll(item
->cas
);
486 return response_handler(cookie
, header
, (void*)&response
);
489 return PROTOCOL_BINARY_RESPONSE_SUCCESS
;
494 response
.message
.header
.response
.status
= htons(PROTOCOL_BINARY_RESPONSE_KEY_EEXISTS
);
498 return response_handler(cookie
, header
, (void*)&response
);
501 static protocol_binary_response_status
stat_command_handler(const void *cookie
,
502 protocol_binary_request_header
*header
,
503 memcached_binary_protocol_raw_response_handler response_handler
)
505 /* Just send the terminating packet*/
506 protocol_binary_response_no_extras response
= {
509 .magic
= PROTOCOL_BINARY_RES
,
510 .opcode
= PROTOCOL_BINARY_CMD_STAT
,
511 .status
= htons(PROTOCOL_BINARY_RESPONSE_SUCCESS
),
512 .opaque
= header
->request
.opaque
517 return response_handler(cookie
, header
, (void*)&response
);
520 memcached_binary_protocol_callback_st interface_v0_impl
= {
521 .interface_version
= MEMCACHED_PROTOCOL_HANDLER_V0
,
524 ** There is a number of bugs in the extra options for gcc causing
525 ** warning on these struct initializers. It hurts my heart to remove
526 ** it so I'll just leave it in here so that we can enable it when
527 ** we can drop support for the broken compilers
529 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GET
]= get_command_handler
,
530 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_SET
]= set_command_handler
,
531 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_ADD
]= add_command_handler
,
532 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_REPLACE
]= replace_command_handler
,
533 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DELETE
]= delete_command_handler
,
534 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_INCREMENT
]= arithmetic_command_handler
,
535 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DECREMENT
]= arithmetic_command_handler
,
536 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_QUIT
]= quit_command_handler
,
537 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_FLUSH
]= flush_command_handler
,
538 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GETQ
]= get_command_handler
,
539 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_NOOP
]= noop_command_handler
,
540 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_VERSION
]= version_command_handler
,
541 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GETK
]= get_command_handler
,
542 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GETKQ
]= get_command_handler
,
543 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_APPEND
]= concat_command_handler
,
544 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_PREPEND
]= concat_command_handler
,
545 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_STAT
]= stat_command_handler
,
546 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_SETQ
]= set_command_handler
,
547 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_ADDQ
]= add_command_handler
,
548 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_REPLACEQ
]= replace_command_handler
,
549 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DELETEQ
]= delete_command_handler
,
550 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_INCREMENTQ
]= arithmetic_command_handler
,
551 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DECREMENTQ
]= arithmetic_command_handler
,
552 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_QUITQ
]= quit_command_handler
,
553 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_FLUSHQ
]= flush_command_handler
,
554 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_APPENDQ
]= concat_command_handler
,
555 .interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_PREPENDQ
]= concat_command_handler
,
559 void initialize_interface_v0_handler(void)
561 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GET
]= get_command_handler
;
562 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_SET
]= set_command_handler
;
563 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_ADD
]= add_command_handler
;
564 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_REPLACE
]= replace_command_handler
;
565 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DELETE
]= delete_command_handler
;
566 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_INCREMENT
]= arithmetic_command_handler
;
567 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DECREMENT
]= arithmetic_command_handler
;
568 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_QUIT
]= quit_command_handler
;
569 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_FLUSH
]= flush_command_handler
;
570 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GETQ
]= get_command_handler
;
571 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_NOOP
]= noop_command_handler
;
572 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_VERSION
]= version_command_handler
;
573 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GETK
]= get_command_handler
;
574 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_GETKQ
]= get_command_handler
;
575 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_APPEND
]= concat_command_handler
;
576 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_PREPEND
]= concat_command_handler
;
577 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_STAT
]= stat_command_handler
;
578 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_SETQ
]= set_command_handler
;
579 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_ADDQ
]= add_command_handler
;
580 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_REPLACEQ
]= replace_command_handler
;
581 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DELETEQ
]= delete_command_handler
;
582 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_INCREMENTQ
]= arithmetic_command_handler
;
583 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_DECREMENTQ
]= arithmetic_command_handler
;
584 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_QUITQ
]= quit_command_handler
;
585 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_FLUSHQ
]= flush_command_handler
;
586 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_APPENDQ
]= concat_command_handler
;
587 interface_v0_impl
.interface
.v0
.comcode
[PROTOCOL_BINARY_CMD_PREPENDQ
]= concat_command_handler
;