MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ascii_scrub.c
1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 
6 #include "protocol_extension.h"
7 
8 static const char *get_name(const void *cmd_cookie);
9 static bool accept_command(const void *cmd_cookie, void *cookie,
10  int argc, token_t *argv, size_t *ndata,
11  char **ptr);
12 static ENGINE_ERROR_CODE execute_command(const void *cmd_cookie, const void *cookie,
13  int argc, token_t *argv,
14  ENGINE_ERROR_CODE (*response_handler)(const void *cookie,
15  int nbytes,
16  const char *dta));
17 static void abort_command(const void *cmd_cookie, const void *cookie);
18 
19 static EXTENSION_ASCII_PROTOCOL_DESCRIPTOR scrub_descriptor = {
20  .get_name = get_name,
21  .accept = accept_command,
22  .execute = execute_command,
23  .abort = abort_command,
24  .cookie = &scrub_descriptor
25 };
26 
27 GET_SERVER_API server_api;
28 
29 static const char *get_name(const void *cmd_cookie) {
30  return "scrub";
31 }
32 
33 static bool accept_command(const void *cmd_cookie, void *cookie,
34  int argc, token_t *argv, size_t *ndata,
35  char **ptr) {
36  return strcmp(argv[0].value, "scrub") == 0;
37 }
38 
39 static bool my_response_handler(const void *key, uint16_t keylen,
40  const void *ext, uint8_t extlen,
41  const void *body, uint32_t bodylen,
42  uint8_t datatype, uint16_t status,
43  uint64_t cas, const void *cookie)
44 {
45  uint16_t *rval = (uint16_t*)cookie;
46  *rval = status;
47  return true;
48 }
49 
50 static ENGINE_ERROR_CODE execute_command(const void *cmd_cookie, const void *cookie,
51  int argc, token_t *argv,
52  ENGINE_ERROR_CODE (*response_handler)(const void *cookie,
53  int nbytes,
54  const char *dta))
55 {
57  .request.magic = (uint8_t)PROTOCOL_BINARY_REQ,
58  .request.opcode = PROTOCOL_BINARY_CMD_SCRUB
59  };
60 
61  uint16_t status = 0;
62  SERVER_HANDLE_V1 *server = server_api();
63  ENGINE_HANDLE_V1 *v1 = (ENGINE_HANDLE_V1*)server->engine;
64  if (v1 == NULL) {
65  return response_handler(cookie, 29, "SERVER_ERROR internal error\r\n");
66  }
67 
68  v1->unknown_command(server->engine, &status, &request, my_response_handler);
69 
70  if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
71  return response_handler(cookie, 4, "OK\r\n");
72  } else if (status == PROTOCOL_BINARY_RESPONSE_EBUSY) {
73  return response_handler(cookie, 6, "BUSY\r\n");
74  } else {
75  return response_handler(cookie, 7, "ERROR\r\n");
76  }
77 }
78 
79 static void abort_command(const void *cmd_cookie, const void *cookie)
80 {
81  /* EMPTY */
82 }
83 
84 MEMCACHED_PUBLIC_API
85 EXTENSION_ERROR_CODE memcached_extensions_initialize(const char *config,
86  GET_SERVER_API get_server_api) {
87  server_api = get_server_api;
88  SERVER_HANDLE_V1 *server = get_server_api();
89  if (server == NULL) {
90  return EXTENSION_FATAL;
91  }
92  if (!server->extension->register_extension(EXTENSION_ASCII_PROTOCOL,
93  &scrub_descriptor)) {
94  return EXTENSION_FATAL;
95  }
96 
97  return EXTENSION_SUCCESS;
98 }