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 <unistd.h>
19 
20 #include <libmemcached-1.0/memcached.h>
21 #include <libmemcachedutil-1.0/util.h>
22 #include "client_options.h"
23 #include "utilities.h"
24 
25 #include <iostream>
26 
27 static bool opt_binary= false;
28 static int opt_verbose= 0;
29 static time_t opt_expire= 0;
30 static char *opt_servers= NULL;
31 static char *opt_username;
32 static char *opt_passwd;
33 
34 #define PROGRAM_NAME "memping"
35 #define PROGRAM_DESCRIPTION "Ping a server to see if it is alive"
36 
37 /* Prototypes */
38 void options_parse(int argc, char *argv[]);
39 
main(int argc,char * argv[])40 int main(int argc, char *argv[])
41 {
42   options_parse(argc, argv);
43 
44   if (opt_servers == NULL)
45   {
46     char *temp;
47 
48     if ((temp= getenv("MEMCACHED_SERVERS")))
49     {
50       opt_servers= strdup(temp);
51     }
52 
53     if (opt_servers == NULL)
54     {
55       std::cerr << "No Servers provided" << std::endl;
56       exit(EXIT_FAILURE);
57     }
58   }
59 
60   int exit_code= EXIT_SUCCESS;
61   memcached_server_st *servers= memcached_servers_parse(opt_servers);
62   if (servers == NULL or memcached_server_list_count(servers) == 0)
63   {
64     std::cerr << "Invalid server list provided:" << opt_servers << std::endl;
65     exit_code= EXIT_FAILURE;
66   }
67   else
68   {
69     for (uint32_t x= 0; x < memcached_server_list_count(servers); x++)
70     {
71       memcached_return_t instance_rc;
72       const char *hostname= servers[x].hostname;
73       in_port_t port= servers[x].port;
74 
75       if (opt_verbose)
76       {
77         std::cout << "Trying to ping " << hostname << ":" << port << std::endl;
78       }
79 
80       if (libmemcached_util_ping2(hostname, port, opt_username, opt_passwd, &instance_rc) == false)
81       {
82         std::cerr << "Failed to ping " << hostname << ":" << port << " " << memcached_strerror(NULL, instance_rc) <<  std::endl;
83         exit_code= EXIT_FAILURE;
84       }
85     }
86   }
87   memcached_server_list_free(servers);
88 
89   free(opt_servers);
90 
91   return exit_code;
92 }
93 
94 
options_parse(int argc,char * argv[])95 void options_parse(int argc, char *argv[])
96 {
97   memcached_programs_help_st help_options[]=
98   {
99     {0},
100   };
101 
102   static struct option long_options[]=
103   {
104     {(OPTIONSTRING)"version", no_argument, NULL, OPT_VERSION},
105     {(OPTIONSTRING)"help", no_argument, NULL, OPT_HELP},
106     {(OPTIONSTRING)"quiet", no_argument, NULL, OPT_QUIET},
107     {(OPTIONSTRING)"verbose", no_argument, &opt_verbose, OPT_VERBOSE},
108     {(OPTIONSTRING)"debug", no_argument, &opt_verbose, OPT_DEBUG},
109     {(OPTIONSTRING)"servers", required_argument, NULL, OPT_SERVERS},
110     {(OPTIONSTRING)"expire", required_argument, NULL, OPT_EXPIRE},
111     {(OPTIONSTRING)"binary", no_argument, NULL, OPT_BINARY},
112     {(OPTIONSTRING)"username", required_argument, NULL, OPT_USERNAME},
113     {(OPTIONSTRING)"password", required_argument, NULL, OPT_PASSWD},
114     {0, 0, 0, 0},
115   };
116 
117   bool opt_version= false;
118   bool opt_help= false;
119   int option_index= 0;
120   while (1)
121   {
122     int option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
123 
124     if (option_rv == -1) break;
125 
126     switch (option_rv)
127     {
128     case 0:
129       break;
130 
131     case OPT_BINARY:
132       opt_binary= true;
133       break;
134 
135     case OPT_VERBOSE: /* --verbose or -v */
136       opt_verbose = OPT_VERBOSE;
137       break;
138 
139     case OPT_DEBUG: /* --debug or -d */
140       opt_verbose = OPT_DEBUG;
141       break;
142 
143     case OPT_VERSION: /* --version or -V */
144       version_command(PROGRAM_NAME);
145       break;
146 
147     case OPT_HELP: /* --help or -h */
148       help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
149       break;
150 
151     case OPT_SERVERS: /* --servers or -s */
152       opt_servers= strdup(optarg);
153       break;
154 
155     case OPT_EXPIRE: /* --expire */
156       errno= 0;
157       opt_expire= time_t(strtoll(optarg, (char **)NULL, 10));
158       if (errno != 0)
159       {
160         std::cerr << "Incorrect value passed to --expire: `" << optarg << "`" << std::endl;
161         exit(EXIT_FAILURE);
162       }
163       break;
164 
165     case OPT_USERNAME:
166       opt_username= optarg;
167       opt_binary= true;
168       break;
169 
170     case OPT_PASSWD:
171       opt_passwd= optarg;
172       break;
173 
174     case OPT_QUIET:
175       close_stdio();
176       break;
177 
178     case '?':
179       /* getopt_long already printed an error message. */
180       exit(1);
181     default:
182       abort();
183     }
184   }
185 
186   if (opt_version)
187   {
188     version_command(PROGRAM_NAME);
189     exit(EXIT_SUCCESS);
190   }
191 
192   if (opt_help)
193   {
194     help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
195     exit(EXIT_SUCCESS);
196   }
197 }
198