8c5690d5d3f27af36b8294c7ba26e1ff445d4d0d
[awesomized/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 <fstream>
17 #include "mem_config.h"
18
19 #define PROGRAM_NAME "memdump"
20 #define PROGRAM_DESCRIPTION "Dump all values from one or many servers."
21 #define PROGRAM_VERSION "1.1"
22
23 #include "common/options.hpp"
24
25 static memcached_return_t print(const memcached_st *, const char *k, size_t l, void *ctx) {
26 auto out = static_cast<std::ostream *>(ctx);
27 out->write(k, l);
28 out->put('\n');
29 return MEMCACHED_SUCCESS;
30 }
31
32 int main(int argc, char *argv[]) {
33 client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION};
34
35 for (const auto &def : opt.defaults) {
36 switch (def.opt.val) {
37 case 'H': // no need for --hash
38 case 'b': // binary proto not available
39 break;
40 default:
41 opt.add(def);
42 }
43 }
44
45 opt.add("file", 'f', required_argument, "Output to file instead of standard output.");
46
47 if (!opt.parse(argc, argv)) {
48 exit(EXIT_FAILURE);
49 }
50
51 if (opt.isset("quiet") && !opt.isset("file")) {
52 std::cerr << "--quiet operation was requested, but --file was not set.\n";
53 exit(EXIT_FAILURE);
54 }
55
56 memcached_st memc;
57 if (!memcached_create(&memc)) {
58 if (!opt.isset("quiet")) {
59 std::cerr << "Failed to initialize memcached client.\n";
60 }
61 exit(EXIT_FAILURE);
62 }
63
64 if (!opt.apply(&memc)) {
65 exit(EXIT_FAILURE);
66 }
67
68 memcached_dump_fn cb[1] = {&print};
69 std::ostream *outstream = &std::cout;
70 std::ofstream outfile{};
71
72 if (auto filename = opt.argof("file")) {
73 if (opt.isset("debug")) {
74 std::cerr << "Opening " << filename << " for output.\n";
75 }
76 outfile.open(filename, std::ios::binary | std::ios::out);
77 if (!outfile.is_open()) {
78 if (!opt.isset("quiet")) {
79 std::cerr << "Failed to open " << filename << " for writing.\n";
80 }
81 memcached_free(&memc);
82 exit(EXIT_FAILURE);
83 }
84 outstream = &outfile;
85 }
86
87 auto rc = memcached_dump(&memc, cb, outstream, 1);
88
89 if (outfile) {
90 if (opt.isset("debug")) {
91 std::cerr << "Flushing " << opt.argof("file") << ".\n";
92 }
93 outfile.flush();
94 }
95
96 if (MEMCACHED_SUCCESS != rc) {
97 if (!opt.isset("quiet")) {
98 std::cerr << "Failed to dump keys:" << memcached_last_error_message(&memc) << "\n";
99 }
100 memcached_free(&memc);
101 exit(EXIT_FAILURE);
102 }
103
104 memcached_free(&memc);
105 exit(EXIT_SUCCESS);
106 }