00519b520bd9f1193d86a49c7c4b6bdfe1a6c78c
[awesomized/libmemcached] / src / bin / memcat.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 "mem_config.h"
17
18 #define PROGRAM_NAME "memcat"
19 #define PROGRAM_DESCRIPTION "Cat a set of key values to stdout."
20 #define PROGRAM_VERSION "1.1"
21
22 #include "libmemcached/common.h"
23 #include "common/options.hpp"
24
25 #include <iostream>
26 #include <fstream>
27
28 memcached_return_t memcat(const client_options &opt, memcached_st *memc, const char *key, std::ostream &ref) {
29 memcached_return_t rc;
30 uint32_t flags;
31 size_t len;
32 auto val = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
33
34 if (MEMCACHED_SUCCESS == rc) {
35 if (opt.flags.verbose) {
36 ref << "key: " << key << "\n";
37 }
38 if (opt.flags.flags) {
39 ref << "flags: " << flags << "\n";
40 }
41 if (opt.flags.verbose) {
42 ref << "value: ";
43 }
44 ref.write(val, len);
45 ref << std::endl;
46 }
47
48 if (val) {
49 free(val);
50 }
51 return rc;
52 }
53
54 int main(int argc, char *argv[]) {
55 memcached_st memc;
56 client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, {
57 client_options::flag::help,
58 client_options::flag::version,
59 client_options::flag::verbose,
60 client_options::flag::debug,
61 client_options::flag::quiet,
62 client_options::flag::servers,
63 client_options::flag::binary,
64 client_options::flag::username,
65 client_options::flag::password,
66 client_options::flag::hash,
67 client_options::flag::flags,
68 client_options::flag::file,
69 }};
70
71 if (!opt.parse(argc, argv)) {
72 exit(EXIT_FAILURE);
73 }
74 if (opt.flags.help) {
75 opt.printHelp("key [ key ... ]");
76 exit(EXIT_SUCCESS);
77 }
78 if (opt.flags.version) {
79 opt.printVersion();
80 exit(EXIT_SUCCESS);
81 }
82
83 if (opt.flags.quiet && !opt.args.file) {
84 std::cerr << "--quiet operation was requested, but --file was not set.\n";
85 exit(EXIT_FAILURE);
86 }
87
88 if (!memcached_create(&memc)) {
89 if (!opt.flags.quiet) {
90 std::cerr << "Failed to initialize memcached client.\n";
91 }
92 exit(EXIT_FAILURE);
93 }
94
95 if (!opt.apply(&memc)) {
96 memcached_free(&memc);
97 exit(EXIT_FAILURE);
98 }
99
100 if (!*opt.args.positional) {
101 if (!opt.flags.quiet) {
102 std::cerr << "No key(s) provided.\n";
103 memcached_free(&memc);
104 exit(EXIT_FAILURE);
105 }
106 }
107
108 auto exit_code = EXIT_SUCCESS;
109 for (auto arg = opt.args.positional; *arg; ++arg) {
110 auto key = *arg;
111 if (*key) {
112 memcached_return_t rc;
113 if (opt.args.file && *opt.args.file) {
114 std::ofstream file{opt.args.file, std::ios::binary};
115 rc = memcat(opt, &memc, key, file);
116 } else {
117 rc = memcat(opt, &memc, key, std::cout);
118 }
119 if (MEMCACHED_SUCCESS != rc) {
120 exit_code = EXIT_FAILURE;
121
122 if (MEMCACHED_NOTFOUND == rc) {
123 if (opt.flags.verbose) {
124 std::cerr << "not found: " << key << "\n";
125 }
126 // continue;
127 } else {
128 if (!opt.flags.quiet) {
129 std::cerr << memcached_last_error_message(&memc) << "\n";
130 }
131 break;
132 }
133 }
134 }
135 }
136
137 memcached_free(&memc);
138 exit(exit_code);
139 }