6d31780c0c3b06dadb5401513b5dacb2b9c28cd3
[m6w6/libmemcached] / src / bin / memdump.cc
1 /*
2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
14 */
15
16 #include "mem_config.h"
17
18 #include <cerrno>
19 #include <cstdio>
20 #include <cstdlib>
21 #include <cstring>
22 #include <fcntl.h>
23 #include <getopt.h>
24 #include <inttypes.h>
25 #include <iostream>
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30
31 #include "libmemcached-1.0/memcached.h"
32
33 #include "client_options.h"
34 #include "utilities.h"
35
36 #define PROGRAM_NAME "memdump"
37 #define PROGRAM_DESCRIPTION "Dump all values from one or many servers."
38
39 /* Prototypes */
40 static void options_parse(int argc, char *argv[]);
41
42 static bool opt_binary = 0;
43 static int opt_verbose = 0;
44 static char *opt_servers = NULL;
45 static char *opt_hash = NULL;
46 static char *opt_username;
47 static char *opt_passwd;
48
49 /* Print the keys and counter how many were found */
50 static memcached_return_t key_printer(const memcached_st *, const char *key, size_t key_length,
51 void *) {
52 std::cout.write(key, key_length);
53 std::cout << std::endl;
54
55 return MEMCACHED_SUCCESS;
56 }
57
58 int main(int argc, char *argv[]) {
59 memcached_dump_fn callbacks[1];
60
61 callbacks[0] = &key_printer;
62
63 options_parse(argc, argv);
64
65 if (opt_servers == NULL) {
66 char *temp;
67
68 if ((temp = getenv("MEMCACHED_SERVERS"))) {
69 opt_servers = strdup(temp);
70 } else if (argc > 1 and argv[--argc]) {
71 opt_servers = strdup(argv[argc]);
72 }
73
74 if (opt_servers == NULL) {
75 std::cerr << "No Servers provided" << std::endl;
76 exit(EXIT_FAILURE);
77 }
78 }
79
80 memcached_server_st *servers = memcached_servers_parse(opt_servers);
81 if (servers == NULL or memcached_server_list_count(servers) == 0) {
82 std::cerr << "Invalid server list provided:" << opt_servers << std::endl;
83 return EXIT_FAILURE;
84 }
85
86 memcached_st *memc = memcached_create(NULL);
87 if (memc == NULL) {
88 std::cerr << "Could not allocate a memcached_st structure.\n" << std::endl;
89 return EXIT_FAILURE;
90 }
91 process_hash_option(memc, opt_hash);
92
93 memcached_server_push(memc, servers);
94 memcached_server_list_free(servers);
95 memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, (uint64_t) opt_binary);
96
97 if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0) {
98 memcached_free(memc);
99 std::cerr << "--username was supplied, but binary was not built with SASL support."
100 << std::endl;
101 return EXIT_FAILURE;
102 }
103
104 if (opt_username) {
105 memcached_return_t ret;
106 if (memcached_failed(ret = memcached_set_sasl_auth_data(memc, opt_username, opt_passwd))) {
107 std::cerr << memcached_last_error_message(memc) << std::endl;
108 memcached_free(memc);
109 return EXIT_FAILURE;
110 }
111 }
112
113 memcached_return_t rc = memcached_dump(memc, callbacks, NULL, 1);
114
115 int exit_code = EXIT_SUCCESS;
116 if (memcached_failed(rc)) {
117 if (opt_verbose) {
118 std::cerr << "Failed to dump keys: " << memcached_last_error_message(memc) << std::endl;
119 }
120 exit_code = EXIT_FAILURE;
121 }
122
123 memcached_free(memc);
124
125 if (opt_servers) {
126 free(opt_servers);
127 }
128 if (opt_hash) {
129 free(opt_hash);
130 }
131
132 return exit_code;
133 }
134
135 static void options_parse(int argc, char *argv[]) {
136 static struct option long_options[] = {
137 {(OPTIONSTRING) "version", no_argument, NULL, OPT_VERSION},
138 {(OPTIONSTRING) "help", no_argument, NULL, OPT_HELP},
139 {(OPTIONSTRING) "quiet", no_argument, NULL, OPT_QUIET},
140 {(OPTIONSTRING) "verbose", no_argument, &opt_verbose, OPT_VERBOSE},
141 {(OPTIONSTRING) "debug", no_argument, &opt_verbose, OPT_DEBUG},
142 {(OPTIONSTRING) "servers", required_argument, NULL, OPT_SERVERS},
143 {(OPTIONSTRING) "hash", required_argument, NULL, OPT_HASH},
144 {(OPTIONSTRING) "binary", no_argument, NULL, OPT_BINARY},
145 {(OPTIONSTRING) "username", required_argument, NULL, OPT_USERNAME},
146 {(OPTIONSTRING) "password", required_argument, NULL, OPT_PASSWD},
147 {0, 0, 0, 0}};
148
149 int option_index = 0;
150 bool opt_version = false;
151 bool opt_help = false;
152 while (1) {
153 int option_rv = getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
154
155 if (option_rv == -1)
156 break;
157
158 switch (option_rv) {
159 case 0:
160 break;
161
162 case OPT_BINARY:
163 opt_binary = true;
164 break;
165
166 case OPT_VERBOSE: /* --verbose or -v */
167 opt_verbose = OPT_VERBOSE;
168 break;
169
170 case OPT_DEBUG: /* --debug or -d */
171 opt_verbose = OPT_DEBUG;
172 break;
173
174 case OPT_VERSION: /* --version or -V */
175 opt_verbose = true;
176 break;
177
178 case OPT_HELP: /* --help or -h */
179 opt_help = true;
180 break;
181
182 case OPT_SERVERS: /* --servers or -s */
183 opt_servers = strdup(optarg);
184 break;
185
186 case OPT_HASH:
187 opt_hash = strdup(optarg);
188 break;
189
190 case OPT_USERNAME:
191 opt_username = optarg;
192 break;
193
194 case OPT_PASSWD:
195 opt_passwd = optarg;
196 break;
197
198 case OPT_QUIET:
199 close_stdio();
200 break;
201
202 case '?':
203 /* getopt_long already printed an error message. */
204 exit(1);
205 default:
206 abort();
207 }
208 }
209
210 if (opt_version) {
211 version_command(PROGRAM_NAME);
212 exit(EXIT_SUCCESS);
213 }
214
215 if (opt_help) {
216 help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, NULL);
217 exit(EXIT_SUCCESS);
218 }
219 }