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