bin: consolidate clients
authorMichael Wallner <mike@php.net>
Tue, 17 Nov 2020 15:55:34 +0000 (16:55 +0100)
committerMichael Wallner <mike@php.net>
Tue, 17 Nov 2020 15:55:34 +0000 (16:55 +0100)
13 files changed:
src/bin/CMakeLists.txt
src/bin/common/CMakeLists.txt
src/bin/common/checks.hpp [new file with mode: 0644]
src/bin/common/options.hpp
src/bin/memcat.cc
src/bin/memcp.cc
src/bin/memdump.cc
src/bin/memerror.cc
src/bin/memexist.cc
src/bin/memflush.cc
src/bin/memping.cc
src/bin/memrm.cc
src/bin/memtouch.cc

index 54b1fa76f8814f211e922be7855771df89b7e170..b4868b4b66e89b0ff036a1da1af905aa5be3821f 100644 (file)
@@ -2,7 +2,7 @@ add_subdirectory(common)
 
 foreach(CLIENT IN LISTS CLIENTS)
     add_executable(${CLIENT} ${CLIENT}.cc)
-    set_target_properties(${CLIENT} PROPERTIES CXX_STANDARD ${CXX_STANDARD})
+    set_property(TARGET ${CLIENT} PROPERTY CXX_STANDARD ${CXX_STANDARD})
     target_include_directories(${CLIENT} PRIVATE ..)
     target_link_libraries(${CLIENT} PRIVATE libclient_common)
     if(CMAKE_INSTALL_RPATH)
index 7a65bedd0dd70e38bb46bfa75e2577d230381c0f..973152d184ef2db968b325c7da5c4655bb5c32a9 100644 (file)
@@ -1,5 +1,6 @@
-add_library(libclient_common STATIC utilities.cc generator.cc options.cpp)
+add_library(libclient_common STATIC utilities.cc generator.cc options.cpp checks.hpp)
 add_library(client_common ALIAS libclient_common)
+set_target_properties(libclient_common PROPERTIES CXX_STANDARD ${CXX_STANDARD})
 target_link_libraries(libclient_common PUBLIC libmemcached)
 target_include_directories(libclient_common PUBLIC
         .
diff --git a/src/bin/common/checks.hpp b/src/bin/common/checks.hpp
new file mode 100644 (file)
index 0000000..e46fffb
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+    +--------------------------------------------------------------------+
+    | libmemcached - C/C++ Client Library for memcached                  |
+    +--------------------------------------------------------------------+
+    | Redistribution and use in source and binary forms, with or without |
+    | modification, are permitted under the terms of the BSD license.    |
+    | You should have received a copy of the license in a bundled file   |
+    | named LICENSE; in case you did not receive a copy you can review   |
+    | the terms online at: https://opensource.org/licenses/BSD-3-Clause  |
+    +--------------------------------------------------------------------+
+    | Copyright (c) 2006-2014 Brian Aker   https://datadifferential.com/ |
+    | Copyright (c) 2020 Michael Wallner   <mike@php.net>                |
+    +--------------------------------------------------------------------+
+*/
+
+#pragma once
+
+#include "options.hpp"
+#include "libmemcached/common.h"
+
+#include <fstream>
+
+bool check_buffering(const client_options &opt, memcached_st &memc) {
+  if (opt.isset("buffer")) {
+    if (MEMCACHED_SUCCESS != memcached_flush_buffers(&memc)) {
+      if (!opt.isset("quiet")) {
+        std::cerr << memcached_last_error_message(&memc) << "\n";
+      }
+      return false;
+    }
+  }
+  return true;
+}
+
+bool check_argp(const client_options &opt, char **argp, const char *error_msg) {
+  if (argp && *argp) {
+    return true;
+  }
+  if (!opt.isset("quiet")) {
+    std::cerr << error_msg << "\n";
+  }
+  return false;
+}
+
+bool check_memcached(const client_options &opt, memcached_st &memc) {
+  if (!memcached_create(&memc)) {
+    if (!opt.isset("quiet")) {
+      std::cerr << "Failed to initialize memcached client.\n";
+    }
+    return false;
+  }
+  return true;
+}
+
+bool check_return(const client_options &opt, memcached_st &memc, const char *key,
+                  memcached_return_t rc) {
+  if (!memcached_success(rc)) {
+    if (!opt.isset("quiet")) {
+      if (MEMCACHED_NOTFOUND == rc) {
+        if (opt.isset("verbose")) {
+          std::cerr << "Could not find key '" << key << "'.\n";
+        }
+      } else {
+        std::cerr << "Fatal error for key '" << key
+                  << "': " << memcached_last_error_message(&memc) << "\n";
+      }
+    }
+    return false;
+  }
+  return true;
+}
+
+std::ostream *check_ostream(const client_options &opt, const char *file, std::ofstream &stream) {
+  if (file && *file) {
+    if (opt.isset("debug")) {
+      std::cerr << "Opening '" << file << "' for writing.\n";
+    }
+    stream.open(file);
+    if (stream.is_open()) {
+      return &stream;
+    } else if (!opt.isset("quiet")) {
+      std::cerr << "Failed to open '" << file << "' for writing.\n";
+    }
+  }
+  return &std::cout;
+}
index 27ba5433d6ac5b1d7a36a7643c09dd7e1debac2e..28ade9733c8d1b233561b22969157b5202420754 100644 (file)
@@ -96,15 +96,19 @@ public:
       if (auto username = ext.arg) {
         if (!LIBMEMCACHED_WITH_SASL_SUPPORT) {
           if (!opt.isset("quiet")) {
-            std::cerr << "SASL username was supplied, but binary was not built with SASL support.\n";
+            std::cerr
+                << "SASL username was supplied, but binary was not built with SASL support.\n";
             return false;
           }
         }
-        if (MEMCACHED_SUCCESS != memcached_set_sasl_auth_data(memc, username, opt.argof("password"))) {
-          if (!opt.isset("quiet")) {
-            std::cerr << memcached_last_error_message(memc);
+        if (memc) {
+          if (MEMCACHED_SUCCESS
+              != memcached_set_sasl_auth_data(memc, username, opt.argof("password"))) {
+            if (!opt.isset("quiet")) {
+              std::cerr << memcached_last_error_message(memc);
+            }
+            return false;
           }
-          return false;
         }
       }
       return true;
index 56b5a46c9e9ee76bdc889beeb4a3a559d7b14cb4..9e2704af5b0aef0fbe11e6abf943745218c4c18a 100644 (file)
 #define PROGRAM_VERSION     "1.1"
 
 #include "common/options.hpp"
+#include "common/checks.hpp"
 
 #include <iostream>
 #include <fstream>
 
-memcached_return_t memcat(const client_options &opt, memcached_st *memc, const char *key, std::ostream &ref) {
+memcached_return_t memcat(const client_options &opt, memcached_st *memc, const char *key, std::ostream *ref) {
   memcached_return_t rc;
   uint32_t flags;
   size_t len;
   auto val = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
+  auto verbose = opt.isset("verbose");
 
   if (MEMCACHED_SUCCESS == rc) {
-    if (opt.isset("verbose")) {
-      ref << "key: " << key << "\n";
+    if (verbose) {
+      *ref << "key: " << key << "\n";
     }
     if (opt.isset("flags")) {
-      ref << "flags: " << flags << "\n";
+      *ref << "flags: " << flags << "\n";
     }
-    if (opt.isset("verbose")) {
-      ref << "value: ";
+    if (verbose) {
+      *ref << "value: ";
     }
-    ref.write(val, len);
-    ref << std::endl;
+    ref->write(val, len) << std::endl;
   }
 
   if (val) {
@@ -51,8 +52,6 @@ memcached_return_t memcat(const client_options &opt, memcached_st *memc, const c
 }
 
 int main(int argc, char *argv[]) {
-  char **argp = nullptr;
-  memcached_st memc;
   client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "key [ key ... ]"};
 
   for (const auto &def : opt.defaults) {
@@ -61,6 +60,7 @@ int main(int argc, char *argv[]) {
   opt.add("flags", 'F', no_argument, "Display key flags, too.");
   opt.add("file", 'f', required_argument, "Output to file instead of standard output.");
 
+  char **argp = nullptr;
   if (!opt.parse(argc, argv, &argp)) {
     exit(EXIT_FAILURE);
   }
@@ -70,10 +70,8 @@ int main(int argc, char *argv[]) {
     exit(EXIT_FAILURE);
   }
 
-  if (!memcached_create(&memc)) {
-    if (!opt.isset("quiet")) {
-      std::cerr << "Failed to initialize memcached client.\n";
-    }
+  memcached_st memc;
+  if (!check_memcached(opt, memc)) {
     exit(EXIT_FAILURE);
   }
 
@@ -82,10 +80,7 @@ int main(int argc, char *argv[]) {
     exit(EXIT_FAILURE);
   }
 
-  if (!*argp) {
-    if (!opt.isset("quiet")) {
-      std::cerr << "No key(s) provided.\n";
-    }
+  if (!check_argp(opt, argp, "No key(s) provided.")) {
     memcached_free(&memc);
     exit(EXIT_FAILURE);
   }
@@ -94,28 +89,25 @@ int main(int argc, char *argv[]) {
   for (auto arg = argp; *arg; ++arg) {
     auto key = *arg;
     if (*key) {
-      memcached_return_t rc;
+
+      std::ofstream fstream{};
+      std::ostream *ostream = check_ostream(opt, opt.argof("file"), fstream);
+
       auto file = opt.argof("file");
       if (file && *file) {
-        std::ofstream stream{file, std::ios::binary};
-        rc = memcat(opt, &memc, key, stream);
-      } else {
-        rc = memcat(opt, &memc, key, std::cout);
-      }
-      if (MEMCACHED_SUCCESS != rc) {
-        exit_code = EXIT_FAILURE;
-
-        if (MEMCACHED_NOTFOUND == rc) {
-          if (opt.isset("verbose")) {
-            std::cerr << "not found: " << key << "\n";
-          }
-          // continue;
-        } else {
+        fstream.open(file, std::ios::binary | std::ios::out);
+        if (!fstream.is_open()) {
+          exit_code = EXIT_FAILURE;
           if (!opt.isset("quiet")) {
-            std::cerr << memcached_last_error_message(&memc) << "\n";
+            std::cerr << "Failed to open " << file << " for writing.\n";
           }
-          break;
+          continue;
         }
+        ostream = &fstream;
+      }
+
+      if (!check_return(opt, memc, key, memcat(opt, &memc, key, ostream))) {
+        exit_code = EXIT_FAILURE;
       }
     }
   }
index e149ef316df876d531b4019596f6a53abd04cedd..713eb570e1eb75bc99b55f77cc1a620b6249a27d 100644 (file)
 #define PROGRAM_VERSION     "1.1"
 
 #include "common/options.hpp"
+#include "common/checks.hpp"
 
 #include <climits>
 #include <cstdlib>
+#include <libgen.h>
 #include <fstream>
 #include <sstream>
 
 struct memcp_file {
-  enum key {
+  enum class type {
     basename,
     relative,
     absolute
-  } type;
-  enum op {
+  } key;
+  enum class mode {
     SET,
     ADD,
     REPLACE
-  } mode;
+  } op;
   const char *path;
   uint32_t flags;
   time_t expire;
 };
 
 static void add_file(std::vector<memcp_file> &files, const client_options &opt, const char *file) {
-  memcp_file::key type = memcp_file::basename;
-  memcp_file::op mode = memcp_file::SET;
+  memcp_file::type type = memcp_file::type::basename;
+  memcp_file::mode mode = memcp_file::mode::SET;
   uint32_t flags = 0;
   time_t expire = 0;
 
   if (opt.isset("absolute")) {
-    type = memcp_file::absolute;
+    type = memcp_file::type::absolute;
   } else if (opt.isset("relative")) {
-    type = memcp_file::relative;
+    type = memcp_file::type::relative;
   }
 
   if (opt.isset("replace")) {
-    mode = memcp_file::REPLACE;
+    mode = memcp_file::mode::REPLACE;
   } else if (opt.isset("add")) {
-    mode = memcp_file::ADD;
+    mode = memcp_file::mode::ADD;
   }
 
   if (auto flags_str = opt.argof("flags")) {
@@ -68,7 +70,7 @@ static void add_file(std::vector<memcp_file> &files, const client_options &opt,
   }
 
   if (opt.isset("debug")) {
-    auto mode_str = mode == memcp_file::REPLACE ? "REPLACE" : mode == memcp_file::ADD ? "ADD" : "SET";
+    auto mode_str = mode == memcp_file::mode::REPLACE ? "REPLACE" : mode == memcp_file::mode::ADD ? "ADD" : "SET";
     std::cerr << "Scheduling " << mode_str << " '" << file << "' (expire=" << expire << ", flags=" << flags << ").\n";
   }
 
@@ -76,7 +78,6 @@ static void add_file(std::vector<memcp_file> &files, const client_options &opt,
 }
 
 int main(int argc, char *argv[]) {
-  memcached_st memc;
   std::vector<memcp_file> files{};
   client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "file [file ...]"};
 
@@ -135,10 +136,8 @@ int main(int argc, char *argv[]) {
     exit(EXIT_FAILURE);
   }
 
-  if (!memcached_create(&memc)) {
-    if (!opt.isset("quiet")) {
-      std::cerr << "Failed to initialize memcached client.\n";
-    }
+  memcached_st memc;
+  if (!check_memcached(opt, memc)) {
     exit(EXIT_FAILURE);
   }
 
@@ -147,10 +146,7 @@ int main(int argc, char *argv[]) {
   }
 
   if (files.empty()) {
-    if (!*argp) {
-      if (!opt.isset("quiet")) {
-        std::cerr << "No file(s) provided.\n";
-      }
+    if (!check_argp(opt, argp, "No file(s) provided.")) {
       memcached_free(&memc);
       exit(EXIT_FAILURE);
     }
@@ -174,9 +170,9 @@ int main(int argc, char *argv[]) {
       const char *path;
       char rpath[PATH_MAX+1];
 
-      if (file.type == memcp_file::relative) {
+      if (file.key == memcp_file::type::relative) {
         path = filename;
-      } else if (file.type == memcp_file::absolute) {
+      } else if (file.key == memcp_file::type::absolute) {
         path = realpath(filename, rpath);
         if (!path) {
           if (!opt.isset("quiet")) {
@@ -186,7 +182,7 @@ int main(int argc, char *argv[]) {
           continue;
         }
       } else {
-        path = basename(filename);
+        path = basename(const_cast<char *>(filename));
       }
 
       std::ostringstream data{};
@@ -194,11 +190,11 @@ int main(int argc, char *argv[]) {
 
       memcached_return_t rc;
       const char *mode;
-      if (file.mode == memcp_file::REPLACE) {
+      if (file.op == memcp_file::mode::REPLACE) {
         mode = "replace";
         rc = memcached_replace(&memc, path, strlen(path), data.str().c_str(), data.str().length(),
                                file.expire, file.flags);
-      } else if (file.mode == memcp_file::ADD) {
+      } else if (file.op == memcp_file::mode::ADD) {
         mode = "add";
         rc = memcached_add(&memc, path, strlen(path), data.str().c_str(), data.str().length(),
                            file.expire, file.flags);
@@ -208,7 +204,7 @@ int main(int argc, char *argv[]) {
                            file.expire, file.flags);
       }
 
-      if (MEMCACHED_SUCCESS != rc) {
+      if (!memcached_success(rc)) {
         exit_code = EXIT_FAILURE;
 
         auto error = memcached_last_error(&memc)
@@ -219,11 +215,15 @@ int main(int argc, char *argv[]) {
       }
 
       if (opt.isset("verbose")) {
-        std::cerr << path << "\n";
+        std::cout << path << "\n";
       }
     }
   }
 
+  if (!check_buffering(opt, memc)) {
+    exit_code = EXIT_FAILURE;
+  }
+
   memcached_free(&memc);
   exit(exit_code);
 }
index 8c5690d5d3f27af36b8294c7ba26e1ff445d4d0d..7bed49232b8e983101fad4cf031678d5db8c524a 100644 (file)
@@ -21,6 +21,7 @@
 #define PROGRAM_VERSION     "1.1"
 
 #include "common/options.hpp"
+#include "common/checks.hpp"
 
 static memcached_return_t print(const memcached_st *, const char *k, size_t l, void *ctx) {
   auto out = static_cast<std::ostream *>(ctx);
@@ -54,10 +55,7 @@ int main(int argc, char *argv[]) {
   }
 
   memcached_st memc;
-  if (!memcached_create(&memc)) {
-    if (!opt.isset("quiet")) {
-      std::cerr << "Failed to initialize memcached client.\n";
-    }
+  if (!check_memcached(opt, memc)) {
     exit(EXIT_FAILURE);
   }
 
@@ -66,23 +64,8 @@ int main(int argc, char *argv[]) {
   }
 
   memcached_dump_fn cb[1] = {&print};
-  std::ostream *outstream = &std::cout;
   std::ofstream outfile{};
-
-  if (auto filename = opt.argof("file")) {
-    if (opt.isset("debug")) {
-      std::cerr << "Opening " << filename << " for output.\n";
-    }
-    outfile.open(filename, std::ios::binary | std::ios::out);
-    if (!outfile.is_open()) {
-      if (!opt.isset("quiet")) {
-        std::cerr << "Failed to open " << filename << " for writing.\n";
-      }
-      memcached_free(&memc);
-      exit(EXIT_FAILURE);
-    }
-    outstream = &outfile;
-  }
+  std::ostream *outstream = check_ostream(opt, opt.argof("file"), outfile);
 
   auto rc = memcached_dump(&memc, cb, outstream, 1);
 
index 208e013dd6a0d3b915865fcbea8af7abc25b1f04..f78afed7328fa4b5f9a496f3f619430d6f339a7a 100644 (file)
@@ -20,6 +20,7 @@
 #define PROGRAM_VERSION     "1.1"
 
 #include "common/options.hpp"
+#include "common/checks.hpp"
 
 int main(int argc, char *argv[]) {
   client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "code [code ...]"};
@@ -30,6 +31,7 @@ int main(int argc, char *argv[]) {
     case 'V': // --version
     case 'v': // --verbose
     case 'd': // --debug
+    case 'q': // --quiet
       opt.add(def);
       break;
     default:
@@ -42,10 +44,11 @@ int main(int argc, char *argv[]) {
     exit(EXIT_FAILURE);
   }
 
-  opt.apply(nullptr);
+  if (!opt.apply(nullptr)) {
+    exit(EXIT_FAILURE);
+  }
 
-  if (!*argp) {
-    std::cerr << "No error codes provided.\n";
+  if (!check_argp(opt, argp, "No error code(s) provided.")) {
     exit(EXIT_FAILURE);
   }
 
@@ -55,10 +58,9 @@ int main(int argc, char *argv[]) {
 
     if (opt.isset("verbose")) {
       std::cout << "code: " << code << "\n";
-      std::cout << "name: " << memcached_strerror(nullptr, rc) << "\n";
-    } else {
-      std::cout << memcached_strerror(nullptr, rc) << "\n";
+      std::cout << "name: ";
     }
+    std::cout << memcached_strerror(nullptr, rc) << std::endl;
   }
 
   exit(EXIT_SUCCESS);
index b3b7a1ec9a1fcbbb77d482f842480cbca06ad421..f4ede92a82f2bef67c7d16c3cc33704a55fdab37 100644 (file)
@@ -20,6 +20,7 @@
 #define PROGRAM_VERSION     "1.1"
 
 #include "common/options.hpp"
+#include "common/checks.hpp"
 
 int main(int argc, char *argv[]) {
   client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "key [key ...]"};
@@ -34,10 +35,7 @@ int main(int argc, char *argv[]) {
   }
 
   memcached_st memc;
-  if (!memcached_create(&memc)) {
-    if (!opt.isset("quiet")) {
-      std::cerr << "Failed to initialize memcached client.\n";
-    }
+  if (!check_memcached(opt, memc)) {
     exit(EXIT_FAILURE);
   }
 
@@ -46,31 +44,21 @@ int main(int argc, char *argv[]) {
     exit(EXIT_FAILURE);
   }
 
-  if (!*argp) {
-    if (!opt.isset("quiet")) {
-      std::cerr << "No key(s) provided.\n";
-    }
+  if (!check_argp(opt, argp, "No key(s) provided.")) {
     memcached_free(&memc);
     exit(EXIT_FAILURE);
   }
 
   auto exit_code = EXIT_SUCCESS;
   for (auto arg = argp; *arg; ++arg) {
-    auto rc = memcached_exist(&memc, *arg, strlen(*arg));
-
-    if (MEMCACHED_SUCCESS == rc) {
-      if (opt.isset("verbose")) {
-        std::cerr << "Found key '" << *arg << "'.\n";
-      }
-    } else {
-      exit_code = EXIT_FAILURE;
-      if (opt.isset("verbose")) {
-        if (rc == MEMCACHED_NOTFOUND) {
-          std::cerr << "Could not find key '" << *arg << "'.\n";
-        } else {
-          std::cerr << "Fatal error for key '" << *arg << "': "
-                    << memcached_last_error_message(&memc) << "\n";
+    auto key = *arg;
+    if (*key) {
+      if (check_return(opt, memc, key, memcached_exist(&memc, *arg, strlen(*arg)))) {
+        if (opt.isset("verbose")) {
+          std::cerr << "Found key '" << *arg << "'.\n";
         }
+      } else {
+        exit_code = EXIT_FAILURE;
       }
     }
   }
index d577a166c8e0a4d4a2b7a37dbec54c741dbd398c..7d39867f54422042db5f4dae2d495bf194040b01 100644 (file)
 
 #include "mem_config.h"
 
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
-#include <getopt.h>
-#include <iostream>
-#include <unistd.h>
-
-#include "libmemcached-1.0/memcached.h"
-#include "client_options.h"
-#include "utilities.h"
-
-static int opt_binary = 0;
-static int opt_verbose = 0;
-static time_t opt_expire = 0;
-static char *opt_servers = NULL;
-static char *opt_username;
-static char *opt_passwd;
-
 #define PROGRAM_NAME        "memflush"
-#define PROGRAM_DESCRIPTION "Erase all data in a server of memcached servers."
+#define PROGRAM_DESCRIPTION "Erase all data in a cluster of memcached servers."
+#define PROGRAM_VERSION     "1.1"
 
-/* Prototypes */
-void options_parse(int argc, char *argv[]);
+#include "common/options.hpp"
+#include "common/checks.hpp"
 
 int main(int argc, char *argv[]) {
-  options_parse(argc, argv);
-
-  if (opt_servers == NULL) {
-    char *temp;
-
-    if ((temp = getenv("MEMCACHED_SERVERS"))) {
-      opt_servers = strdup(temp);
-    }
+  client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION};
 
-    if (opt_servers == NULL) {
-      std::cerr << "No Servers provided" << std::endl;
-      exit(EXIT_FAILURE);
+  for (const auto &def : opt.defaults) {
+    switch (def.opt.val) {
+    case 'H': // no need for --hash
+      break;
+    default:
+      opt.add(def);
+      break;
     }
   }
 
-  memcached_server_st *servers = memcached_servers_parse(opt_servers);
-  if (servers == NULL or memcached_server_list_count(servers) == 0) {
-    std::cerr << "Invalid server list provided:" << opt_servers << std::endl;
-    free(opt_servers);
-    return EXIT_FAILURE;
-  }
-
-  free(opt_servers);
+  opt.add("expire", 'e', required_argument, "Flush based on expire time.");
 
-  memcached_st *memc = memcached_create(NULL);
-  memcached_server_push(memc, servers);
-  memcached_server_list_free(servers);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, (uint64_t) opt_binary);
-
-  if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0) {
-    memcached_free(memc);
-    std::cerr << "--username was supplied, but binary was not built with SASL support."
-              << std::endl;
-    return EXIT_FAILURE;
+  if (!opt.parse(argc, argv, nullptr)) {
+    exit(EXIT_FAILURE);
   }
 
-  if (opt_username) {
-    memcached_return_t ret;
-    if (memcached_failed(ret = memcached_set_sasl_auth_data(memc, opt_username, opt_passwd))) {
-      std::cerr << memcached_last_error_message(memc) << std::endl;
-      memcached_free(memc);
-      return EXIT_FAILURE;
-    }
+  memcached_st memc;
+  if (!check_memcached(opt, memc)) {
+    exit(EXIT_FAILURE);
   }
 
-  memcached_return_t rc = memcached_flush(memc, opt_expire);
-  if (rc != MEMCACHED_SUCCESS) {
-    std::cerr << memcached_last_error_message(memc) << std::endl;
-    memcached_free(memc);
-    return EXIT_FAILURE;
+  if (!opt.apply(&memc)) {
+    memcached_free(&memc);
+    exit(EXIT_FAILURE);
   }
 
-  memcached_free(memc);
-  return EXIT_SUCCESS;
-}
-
-void options_parse(int argc, char *argv[]) {
-  static struct option long_options[] = {
-      {(OPTIONSTRING) "version", no_argument, NULL, OPT_VERSION},
-      {(OPTIONSTRING) "help", no_argument, NULL, OPT_HELP},
-      {(OPTIONSTRING) "quiet", no_argument, NULL, OPT_QUIET},
-      {(OPTIONSTRING) "verbose", no_argument, &opt_verbose, OPT_VERBOSE},
-      {(OPTIONSTRING) "debug", no_argument, &opt_verbose, OPT_DEBUG},
-      {(OPTIONSTRING) "servers", required_argument, NULL, OPT_SERVERS},
-      {(OPTIONSTRING) "expire", required_argument, NULL, OPT_EXPIRE},
-      {(OPTIONSTRING) "binary", no_argument, NULL, OPT_BINARY},
-      {(OPTIONSTRING) "username", required_argument, NULL, OPT_USERNAME},
-      {(OPTIONSTRING) "password", required_argument, NULL, OPT_PASSWD},
-      {0, 0, 0, 0},
-  };
-
-  bool opt_version = false;
-  bool opt_help = false;
-  int option_index = 0;
-  while (1) {
-    int option_rv = getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
-    if (option_rv == -1)
-      break;
-    switch (option_rv) {
-    case 0:
-      break;
-
-    case OPT_BINARY:
-      opt_binary = true;
-      break;
-
-    case OPT_VERBOSE: /* --verbose or -v */
-      opt_verbose = OPT_VERBOSE;
-      break;
-
-    case OPT_DEBUG: /* --debug or -d */
-      opt_verbose = OPT_DEBUG;
-      break;
-
-    case OPT_VERSION: /* --version or -V */
-      opt_version = true;
-      break;
-
-    case OPT_HELP: /* --help or -h */
-      opt_help = true;
-      break;
-
-    case OPT_SERVERS: /* --servers or -s */
-      opt_servers = strdup(optarg);
-      break;
-
-    case OPT_EXPIRE: /* --expire */
-      errno = 0;
-      opt_expire = (time_t) strtoll(optarg, (char **) NULL, 10);
-      if (errno) {
-        std::cerr << "Incorrect value passed to --expire: `" << optarg << "`" << std::endl;
-        exit(EXIT_FAILURE);
-      }
-      break;
-
-    case OPT_USERNAME:
-      opt_username = optarg;
-      break;
-
-    case OPT_PASSWD:
-      opt_passwd = optarg;
-      break;
-
-    case OPT_QUIET:
-      close_stdio();
-      break;
-
-    case '?':
-      /* getopt_long already printed an error message. */
-      exit(EXIT_FAILURE);
+  time_t expire = 0;
+  if (auto exp_str = opt.argof("expire")) {
+    expire = std::stoul(exp_str);
+  }
 
-    default:
-      abort();
+  auto exit_code = EXIT_SUCCESS;
+  memcached_return_t rc = memcached_flush(&memc, expire);
+  if (!memcached_success(rc)) {
+    exit_code = EXIT_FAILURE;
+    if (!opt.isset("quiet")) {
+      std::cerr << "Failed to flush server: " << memcached_last_error_message(&memc) << "\n";
     }
   }
 
-  if (opt_version) {
-    version_command(PROGRAM_NAME);
-    exit(EXIT_SUCCESS);
+  if (!check_buffering(opt, memc)) {
+    exit_code = EXIT_FAILURE;
   }
 
-  if (opt_help) {
-    help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, NULL);
-    exit(EXIT_SUCCESS);
-  }
+  memcached_free(&memc);
+  exit(exit_code);
 }
index 902954c7882f988d6daa3e64727dcdc9903b5416..d875280ead6af5f4135fcbe80a93675fcca1879c 100644 (file)
 
 #include "mem_config.h"
 
+#define PROGRAM_NAME        "memping"
+#define PROGRAM_DESCRIPTION "Ping a server or a set of servers."
+#define PROGRAM_VERSION     "1.1"
+
+#include "common/options.hpp"
+#include "common/checks.hpp"
+
+#include "libmemcached/util.h"
+
+static memcached_return_t ping(const memcached_st *memc, const memcached_instance_st *s, void *ctx) {
+  auto opt = static_cast<client_options *>(ctx);
+  memcached_return_t rc;
+  bool ok;
+
+  if (opt->isset("debug")) {
+    std::cerr << "Trying to ping" << s->_hostname << ":" << s->port() << ".\n";
+  }
+
+  if (auto username = opt->argof("username")) {
+    auto password = opt->argof("password");
+    ok = libmemcached_util_ping2(s->_hostname, s->port(), username, password, &rc);
+  } else {
+    ok = libmemcached_util_ping(s->_hostname, s->port(), &rc);
+  }
+  if (!ok && !opt->isset("quiet")) {
+    std::cerr << "Failed to ping '" << s->_hostname << ":" << s->port()
+              << ":" << memcached_strerror(memc, rc) << ".\n";
+  }
+
+  return rc;
+}
+
+int main(int argc, char *argv[]) {
+  client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION};
+
+  for (const auto &def : opt.defaults) {
+    switch (def.opt.val) {
+    case 'h': // --help
+    case 'V': // --version
+    case 'v': // --verbose
+    case 'd': // --debug
+    case 'q': // --quiet
+    case 's': // --servers
+    case 'u': // --username
+    case 'p': // --password
+      opt.add(def);
+      break;
+    default:
+      break;
+    }
+  }
+
+  if (!opt.parse(argc, argv, nullptr)) {
+    exit(EXIT_FAILURE);
+  }
+
+  memcached_st memc;
+  if (!check_memcached(opt, memc)) {
+    exit(EXIT_FAILURE);
+  }
+
+  if (!opt.apply(&memc)) {
+    memcached_free(&memc);
+    exit(EXIT_FAILURE);
+  }
+
+  auto exit_code = EXIT_SUCCESS;
+  memcached_server_fn cb[1] = {&ping};
+  if (!memcached_success(memcached_server_cursor(&memc, cb, &opt, 1))) {
+    exit_code = EXIT_FAILURE;
+  }
+
+  memcached_free(&memc);
+  exit(exit_code);
+}
+
 #include <cerrno>
 #include <cstdio>
 #include <cstring>
index d2e84e2309620afecd5e080dbc06c979e2c3143b..b489c0f1229b4367c5282c0ebf860890ae59c58c 100644 (file)
 
 #include "mem_config.h"
 
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
-#include <getopt.h>
-#include <iostream>
-#include <unistd.h>
-
-#include "libmemcached-1.0/memcached.h"
-#include "client_options.h"
-#include "utilities.h"
-
-static int opt_binary = 0;
-static int opt_verbose = 0;
-static time_t opt_expire = 0;
-static char *opt_servers = NULL;
-static char *opt_hash = NULL;
-static char *opt_username;
-static char *opt_passwd;
-
 #define PROGRAM_NAME        "memrm"
 #define PROGRAM_DESCRIPTION "Erase a key or set of keys from a memcached cluster."
+#define PROGRAM_VERSION     "1.1"
 
-/* Prototypes */
-static void options_parse(int argc, char *argv[]);
+#include "common/options.hpp"
+#include "common/checks.hpp"
 
 int main(int argc, char *argv[]) {
-  options_parse(argc, argv);
-  initialize_sockets();
-
-  if (opt_servers == NULL) {
-    char *temp;
-
-    if ((temp = getenv("MEMCACHED_SERVERS"))) {
-      opt_servers = strdup(temp);
-    }
+  client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "key [key ...]"};
 
-    if (opt_servers == NULL) {
-      std::cerr << "No Servers provided" << std::endl;
-      exit(EXIT_FAILURE);
-    }
-  }
-
-  memcached_server_st *servers = memcached_servers_parse(opt_servers);
-  if (servers == NULL or memcached_server_list_count(servers) == 0) {
-    std::cerr << "Invalid server list provided:" << opt_servers << std::endl;
-    return EXIT_FAILURE;
+  for (const auto &def : opt.defaults) {
+    opt.add(def);
   }
 
-  memcached_st *memc = memcached_create(NULL);
-  process_hash_option(memc, opt_hash);
+  opt.add("expire", 'e', required_argument, "Remove based on expire time. DEPRECATED: has no effect.");
 
-  memcached_server_push(memc, servers);
-  memcached_server_list_free(servers);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, (uint64_t) opt_binary);
-
-  if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0) {
-    memcached_free(memc);
-    std::cerr << "--username was supplied, but binary was not built with SASL support."
-              << std::endl;
-    return EXIT_FAILURE;
+  char **argp = nullptr;
+  if (!opt.parse(argc, argv, &argp)) {
+    exit(EXIT_FAILURE);
   }
 
-  if (opt_username) {
-    memcached_return_t ret;
-    if (memcached_failed(ret = memcached_set_sasl_auth_data(memc, opt_username, opt_passwd))) {
-      std::cerr << memcached_last_error_message(memc) << std::endl;
-      memcached_free(memc);
-      return EXIT_FAILURE;
-    }
+  memcached_st memc;
+  if (!check_memcached(opt, memc)) {
+    exit(EXIT_FAILURE);
   }
 
-  int return_code = EXIT_SUCCESS;
-
-  while (optind < argc) {
-    memcached_return_t rc = memcached_delete(memc, argv[optind], strlen(argv[optind]), opt_expire);
-
-    if (rc == MEMCACHED_NOTFOUND) {
-      if (opt_verbose) {
-        std::cerr << "Could not find key \"" << argv[optind] << "\"" << std::endl;
-      }
-    } else if (memcached_fatal(rc)) {
-      if (opt_verbose) {
-        std::cerr << "Failed to delete key \"" << argv[optind]
-                  << "\" :" << memcached_last_error_message(memc) << std::endl;
-      }
-
-      return_code = EXIT_FAILURE;
-    } else // success
-    {
-      if (opt_verbose) {
-        std::cout << "Deleted key " << argv[optind];
-        if (opt_expire) {
-          std::cout << " expires: " << opt_expire << std::endl;
-        }
-        std::cout << std::endl;
-      }
-    }
-
-    optind++;
+  if (!opt.apply(&memc)) {
+    memcached_free(&memc);
+    exit(EXIT_FAILURE);
   }
 
-  memcached_free(memc);
-
-  if (opt_servers) {
-    free(opt_servers);
+  if (!check_argp(opt, argp, "No key(s) provided.")){
+    memcached_free(&memc);
+    exit(EXIT_FAILURE);
   }
 
-  if (opt_hash) {
-    free(opt_hash);
+  time_t expire = 0;
+  if (auto exp_str = opt.argof("expire")) {
+    expire = std::stoul(exp_str);
   }
 
-  return return_code;
-}
-
-static void options_parse(int argc, char *argv[]) {
-  memcached_programs_help_st help_options[] = {
-      {0},
-  };
-
-  static struct option long_options[] = {
-      {(OPTIONSTRING) "version", no_argument, NULL, OPT_VERSION},
-      {(OPTIONSTRING) "help", no_argument, NULL, OPT_HELP},
-      {(OPTIONSTRING) "quiet", no_argument, NULL, OPT_QUIET},
-      {(OPTIONSTRING) "verbose", no_argument, &opt_verbose, OPT_VERBOSE},
-      {(OPTIONSTRING) "debug", no_argument, &opt_verbose, OPT_DEBUG},
-      {(OPTIONSTRING) "servers", required_argument, NULL, OPT_SERVERS},
-      {(OPTIONSTRING) "expire", required_argument, NULL, OPT_EXPIRE},
-      {(OPTIONSTRING) "hash", required_argument, NULL, OPT_HASH},
-      {(OPTIONSTRING) "binary", no_argument, NULL, OPT_BINARY},
-      {(OPTIONSTRING) "username", required_argument, NULL, OPT_USERNAME},
-      {(OPTIONSTRING) "password", required_argument, NULL, OPT_PASSWD},
-      {0, 0, 0, 0},
-  };
-
-  bool opt_version = false;
-  bool opt_help = false;
-  int option_index = 0;
-
-  while (1) {
-    int option_rv = getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
-    if (option_rv == -1) {
-      break;
-    }
-
-    switch (option_rv) {
-    case 0:
-      break;
-
-    case OPT_BINARY:
-      opt_binary = 1;
-      break;
-
-    case OPT_VERBOSE: /* --verbose or -v */
-      opt_verbose = OPT_VERBOSE;
-      break;
-
-    case OPT_DEBUG: /* --debug or -d */
-      opt_verbose = OPT_DEBUG;
-      break;
-
-    case OPT_VERSION: /* --version or -V */
-      opt_version = true;
-      break;
-
-    case OPT_HELP: /* --help or -h */
-      opt_help = true;
-      break;
-
-    case OPT_SERVERS: /* --servers or -s */
-      opt_servers = strdup(optarg);
-      break;
-
-    case OPT_EXPIRE: /* --expire */
-      errno = 0;
-      opt_expire = (time_t) strtoll(optarg, (char **) NULL, 10);
-      if (errno) {
-        std::cerr << "Incorrect value passed to --expire: `" << optarg << "`" << std::endl;
-        exit(EXIT_FAILURE);
+  auto exit_code = EXIT_SUCCESS;
+  for (auto arg = argp; *arg; ++arg) {
+    auto key = *arg;
+    if (*key) {
+      if (!check_return(opt, memc, key, memcached_delete(&memc, key, strlen(key), expire))) {
+        exit_code = EXIT_FAILURE;
       }
-      break;
-
-    case OPT_HASH:
-      opt_hash = strdup(optarg);
-      break;
-
-    case OPT_USERNAME:
-      opt_username = optarg;
-      break;
-
-    case OPT_PASSWD:
-      opt_passwd = optarg;
-      break;
-
-    case OPT_QUIET:
-      close_stdio();
-      break;
-
-    case '?':
-      /* getopt_long already printed an error message. */
-      exit(EXIT_SUCCESS);
-
-    default:
-      abort();
     }
   }
 
-  if (opt_version) {
-    version_command(PROGRAM_NAME);
-    exit(EXIT_SUCCESS);
+  if (!check_buffering(opt, memc)) {
+    exit_code = EXIT_FAILURE;
   }
 
-  if (opt_help) {
-    help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
-    exit(EXIT_SUCCESS);
-  }
+  memcached_free(&memc);
+  exit(exit_code);
 }
index dbb9ad5ceeb0e79c30a1fe0b320c40979a10c960..400c47efcbed5b38d3af20803f0dba74018c7949 100644 (file)
 
 #include "mem_config.h"
 
-#include <cerrno>
-#include <cstdio>
-#include <cstring>
-#include <getopt.h>
-#include <iostream>
-#include <unistd.h>
-
-#include "libmemcached-1.0/memcached.h"
-
-#include "utilities.h"
-
 #define PROGRAM_NAME        "memtouch"
-#define PROGRAM_DESCRIPTION "Update the expiration value of an already existing value in the server"
+#define PROGRAM_DESCRIPTION "Update the expiration time of an already existing key."
+#define PROGRAM_VERSION     "1.1"
 
-/* Prototypes */
-void options_parse(int argc, char *argv[]);
-
-static int opt_binary = 0;
-static int opt_verbose = 0;
-static char *opt_servers = NULL;
-static char *opt_hash = NULL;
-static char *opt_username;
-static char *opt_passwd;
-
-time_t expiration = 0;
+#include "common/options.hpp"
+#include "common/checks.hpp"
 
 int main(int argc, char *argv[]) {
-  int return_code = EXIT_SUCCESS;
-
-  options_parse(argc, argv);
-  initialize_sockets();
-
-  if (opt_servers == NULL) {
-    char *temp;
-
-    if ((temp = getenv("MEMCACHED_SERVERS"))) {
-      opt_servers = strdup(temp);
-    }
-
-    if (opt_servers == NULL) {
-      std::cerr << "No Servers provided" << std::endl;
-      exit(EXIT_FAILURE);
-    }
-  }
+  client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "key [key ...]"};
 
-  memcached_server_st *servers = memcached_servers_parse(opt_servers);
-  if (servers == NULL or memcached_server_list_count(servers) == 0) {
-    std::cerr << "Invalid server list provided:" << opt_servers << std::endl;
-    return EXIT_FAILURE;
+  for (const auto &def : opt.defaults) {
+    opt.add(def);
   }
 
-  memcached_st *memc = memcached_create(NULL);
-  process_hash_option(memc, opt_hash);
-
-  memcached_server_push(memc, servers);
-  memcached_server_list_free(servers);
-  memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_BINARY_PROTOCOL, (uint64_t) opt_binary);
+  opt.add("expiration", 'e', no_argument, "Expiration time in seconds or unix timestamp.");
 
-  if (opt_username and LIBMEMCACHED_WITH_SASL_SUPPORT == 0) {
-    memcached_free(memc);
-    std::cerr << "--username was supplied, but binary was not built with SASL support."
-              << std::endl;
-    return EXIT_FAILURE;
+  char **argp = nullptr;
+  if (!opt.parse(argc, argv, &argp)) {
+    exit(EXIT_FAILURE);
   }
 
-  if (opt_username) {
-    memcached_return_t ret;
-    if (memcached_failed(ret = memcached_set_sasl_auth_data(memc, opt_username, opt_passwd))) {
-      std::cerr << memcached_last_error_message(memc) << std::endl;
-      memcached_free(memc);
-      return EXIT_FAILURE;
-    }
+  memcached_st memc;
+  if (!check_memcached(opt, memc)) {
+    exit(EXIT_FAILURE);
   }
 
-  while (optind < argc) {
-    memcached_return_t rc = memcached_touch(memc, argv[optind], strlen(argv[optind]), expiration);
-    if (rc == MEMCACHED_NOTFOUND) {
-      if (opt_verbose) {
-        std::cout << "Could not find key \"" << argv[optind] << "\"" << std::endl;
-      }
-
-      return_code = EXIT_FAILURE;
-    } else if (memcached_failed(rc)) {
-      if (opt_verbose) {
-        std::cerr << "Fatal error for key \"" << argv[optind]
-                  << "\" :" << memcached_last_error_message(memc) << std::endl;
-      }
-
-      return_code = EXIT_FAILURE;
-    } else // success
-    {
-      if (opt_verbose) {
-        std::cout << "Found key " << argv[optind] << std::endl;
-      }
-    }
-
-    optind++;
+  if (!opt.apply(&memc)) {
+    memcached_free(&memc);
+    exit(EXIT_FAILURE);
   }
 
-  memcached_free(memc);
-
-  if (opt_servers) {
-    free(opt_servers);
+  if (!check_argp(opt, argp, "No key(s) provided.")) {
+    memcached_free(&memc);
+    exit(EXIT_FAILURE);
   }
 
-  if (opt_hash) {
-    free(opt_hash);
+  time_t expire = 0;
+  if (auto exp_str = opt.argof("expire")) {
+    expire = std::stoul(exp_str);
   }
 
-  return return_code;
-}
-
-void options_parse(int argc, char *argv[]) {
-  memcached_programs_help_st help_options[] = {
-      {0},
-  };
-
-  static struct option long_options[] = {
-      {(OPTIONSTRING) "version", no_argument, NULL, OPT_VERSION},
-      {(OPTIONSTRING) "help", no_argument, NULL, OPT_HELP},
-      {(OPTIONSTRING) "quiet", no_argument, NULL, OPT_QUIET},
-      {(OPTIONSTRING) "verbose", no_argument, &opt_verbose, OPT_VERBOSE},
-      {(OPTIONSTRING) "debug", no_argument, &opt_verbose, OPT_DEBUG},
-      {(OPTIONSTRING) "servers", required_argument, NULL, OPT_SERVERS},
-      {(OPTIONSTRING) "hash", required_argument, NULL, OPT_HASH},
-      {(OPTIONSTRING) "binary", no_argument, NULL, OPT_BINARY},
-      {(OPTIONSTRING) "username", required_argument, NULL, OPT_USERNAME},
-      {(OPTIONSTRING) "password", required_argument, NULL, OPT_PASSWD},
-      {(OPTIONSTRING) "expire", required_argument, NULL, OPT_EXPIRE},
-      {0, 0, 0, 0},
-  };
-
-  bool opt_version = false;
-  bool opt_help = false;
-  int option_index = 0;
-
-  while (1) {
-    int option_rv = getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
-    if (option_rv == -1) {
-      break;
-    }
-
-    switch (option_rv) {
-    case 0:
-      break;
-
-    case OPT_BINARY:
-      opt_binary = true;
-      break;
-
-    case OPT_VERBOSE: /* --verbose or -v */
-      opt_verbose = OPT_VERBOSE;
-      break;
-
-    case OPT_DEBUG: /* --debug or -d */
-      opt_verbose = OPT_DEBUG;
-      break;
-
-    case OPT_VERSION: /* --version or -V */
-      opt_version = true;
-      break;
-
-    case OPT_HELP: /* --help or -h */
-      opt_help = true;
-      break;
-
-    case OPT_SERVERS: /* --servers or -s */
-      opt_servers = strdup(optarg);
-      break;
-
-    case OPT_HASH:
-      opt_hash = strdup(optarg);
-      break;
-
-    case OPT_USERNAME:
-      opt_username = optarg;
-      break;
-
-    case OPT_PASSWD:
-      opt_passwd = optarg;
-      break;
-
-    case OPT_EXPIRE:
-      errno = 0;
-      expiration = time_t(strtoul(optarg, (char **) NULL, 10));
-      if (errno) {
-        fprintf(stderr, "Invalid value for --expire: %s\n", optarg);
-        exit(EXIT_FAILURE);
+  auto exit_code = EXIT_SUCCESS;
+  for (auto arg = argp; *arg; ++arg) {
+    auto key = *arg;
+    if (*key) {
+      if (!check_return(opt, memc, key, memcached_touch(&memc, key, strlen(key), expire))) {
+        exit_code = EXIT_FAILURE;
       }
-      break;
-
-    case OPT_QUIET:
-      close_stdio();
-      break;
-
-    case '?':
-      /* getopt_long already printed an error message. */
-      exit(EXIT_FAILURE);
-
-    default:
-      abort();
     }
   }
 
-  if (opt_version) {
-    version_command(PROGRAM_NAME);
-    exit(EXIT_SUCCESS);
+  if (!check_buffering(opt, memc)) {
+    exit_code = EXIT_FAILURE;
   }
 
-  if (opt_help) {
-    help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
-    exit(EXIT_SUCCESS);
-  }
+  memcached_free(&memc);
+  exit(exit_code);
 }