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