move repository from m6w6 to awesomized
[m6w6/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-2021 Michael Wallner https://awesome.co/ |
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 "common/options.hpp"
23 #include "common/checks.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 auto verbose = opt.isset("verbose");
34
35 if (MEMCACHED_SUCCESS == rc) {
36 if (verbose) {
37 *ref << "key: " << key << "\n";
38 }
39 if (opt.isset("flags")) {
40 if (verbose) {
41 *ref << "flags: ";
42 }
43 *ref << flags << "\n";
44 }
45 if (verbose) {
46 *ref << "value: ";
47 }
48
49 ref->write(val, len);
50
51 if (verbose || !opt.isset("file")) {
52 *ref << std::endl;
53 }
54
55 ref->flush();
56 }
57
58 if (val) {
59 free(val);
60 }
61 return rc;
62 }
63
64 int main(int argc, char *argv[]) {
65 client_options opt{PROGRAM_NAME, PROGRAM_VERSION, PROGRAM_DESCRIPTION, "key [key ...]"};
66
67 for (const auto &def : opt.defaults) {
68 opt.add(def);
69 }
70 opt.add("flags", 'F', no_argument, "Display key flags, too.");
71 opt.add("file", 'f', optional_argument, "Output to file instead of standard output."
72 "\n\t\t# NOTE: defaults to <key> if no argument was provided.");
73
74 char **argp = nullptr;
75 if (!opt.parse(argc, argv, &argp)) {
76 exit(EXIT_FAILURE);
77 }
78
79 if (opt.isset("quiet") && !opt.isset("file")) {
80 std::cerr << "--quiet operation was requested, but --file was not set.\n";
81 exit(EXIT_FAILURE);
82 }
83
84 memcached_st memc;
85 if (!check_memcached(opt, memc)) {
86 exit(EXIT_FAILURE);
87 }
88
89 if (!opt.apply(&memc)) {
90 memcached_free(&memc);
91 exit(EXIT_FAILURE);
92 }
93
94 if (!check_argp(opt, argp, "No key(s) provided.")) {
95 memcached_free(&memc);
96 exit(EXIT_FAILURE);
97 }
98
99 auto file_flag = opt.isset("file");
100 auto file = opt.argof("file");
101 auto exit_code = EXIT_SUCCESS;
102 for (auto arg = argp; *arg; ++arg) {
103 auto key = *arg;
104 if (*key) {
105 if (!file && file_flag) {
106 file = key;
107 }
108
109 std::ofstream fstream{};
110 std::ostream *ostream = check_ostream(opt, file, fstream);
111
112 if (!check_return(opt, memc, key, memcat(opt, &memc, key, ostream))) {
113 exit_code = EXIT_FAILURE;
114 }
115 }
116 }
117
118 memcached_free(&memc);
119 exit(exit_code);
120 }