See changes in changelog, but...
[awesomized/libmemcached] / src / memcp.c
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <getopt.h>
4 #include <sys/types.h>
5 #include <sys/stat.h>
6 #include <sys/types.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <strings.h>
10
11 #include <memcached.h>
12 #include "client_options.h"
13 #include "utilities.h"
14
15 #define PROGRAM_NAME "memcp"
16 #define PROGRAM_DESCRIPTION "Copy a set of files to a memcached cluster."
17
18 /* Prototypes */
19 void options_parse(int argc, char *argv[]);
20
21 static int opt_verbose= 0;
22 static char *opt_servers= NULL;
23 static int opt_method= OPT_SET;
24 static uint16_t opt_flags= 0;
25 static time_t opt_expires= 0;
26
27 int main(int argc, char *argv[])
28 {
29 memcached_st *memc;
30 memcached_return rc;
31 memcached_server_st *servers;
32
33 options_parse(argc, argv);
34
35 memc= memcached_create(NULL);
36
37 if (!opt_servers)
38 return 0;
39
40 if (opt_servers)
41 servers= parse_opt_servers(opt_servers);
42 else
43 servers= parse_opt_servers(argv[--argc]);
44
45 memcached_server_push(memc, servers);
46 memcached_server_list_free(servers);
47
48 while (optind < argc)
49 {
50 struct stat sbuf;
51 int fd;
52 char *ptr;
53 ssize_t read_length;
54 char *file_buffer_ptr;
55
56 fd= open(argv[optind], O_RDONLY);
57 if (fd < 0)
58 {
59 fprintf(stderr, "memcp: %s: %s\n", argv[optind], strerror(errno));
60 optind++;
61 continue;
62 }
63
64 (void)fstat(fd, &sbuf);
65
66 ptr= rindex(argv[optind], '/');
67 if (ptr)
68 ptr++;
69 else
70 ptr= argv[optind];
71
72 if (opt_verbose)
73 {
74 static char *opstr[] = { "set", "add", "replace" };
75 printf("op: %s\nsource file: %s\nlength: %zu\n"
76 "key: %s\nflags: %x\nexpires: %llu\n",
77 opstr[opt_method - OPT_SET], argv[optind], (size_t)sbuf.st_size,
78 ptr, opt_flags, (unsigned long long)opt_expires);
79 }
80
81 if ((file_buffer_ptr= (char *)malloc(sizeof(char) * sbuf.st_size)) == NULL)
82 {
83 fprintf(stderr, "malloc: %s\n", strerror(errno));
84 exit(1);
85 }
86
87 if ((read_length= read(fd, file_buffer_ptr, sbuf.st_size)) == -1)
88 {
89 fprintf(stderr, "read: %s\n", strerror(errno));
90 exit(1);
91 }
92 assert(read_length == sbuf.st_size);
93
94 if (opt_method == OPT_ADD)
95 rc= memcached_add(memc, ptr, strlen(ptr),
96 file_buffer_ptr, sbuf.st_size,
97 opt_expires, opt_flags);
98 else if (opt_method == OPT_REPLACE)
99 rc= memcached_replace(memc, ptr, strlen(ptr),
100 file_buffer_ptr, sbuf.st_size,
101 opt_expires, opt_flags);
102 else
103 rc= memcached_set(memc, ptr, strlen(ptr),
104 file_buffer_ptr, sbuf.st_size,
105 opt_expires, opt_flags);
106
107 if (rc != MEMCACHED_SUCCESS)
108 fprintf(stderr, "memcp: %s: memcache error %s\n",
109 ptr, memcached_strerror(memc, rc));
110
111 free(file_buffer_ptr);
112 close(fd);
113 optind++;
114 }
115
116 memcached_free(memc);
117
118 free(opt_servers);
119
120 return 0;
121 }
122
123 void options_parse(int argc, char *argv[])
124 {
125 int option_index= 0;
126 int option_rv;
127
128 memcached_programs_help_st help_options[]=
129 {
130 {0},
131 };
132
133 static struct option long_options[]=
134 {
135 {"version", no_argument, NULL, OPT_VERSION},
136 {"help", no_argument, NULL, OPT_HELP},
137 {"verbose", no_argument, &opt_verbose, OPT_VERBOSE},
138 {"debug", no_argument, &opt_verbose, OPT_DEBUG},
139 {"servers", required_argument, NULL, OPT_SERVERS},
140 {"flag", required_argument, NULL, OPT_FLAG},
141 {"expire", required_argument, NULL, OPT_EXPIRE},
142 {"set", no_argument, NULL, OPT_SET},
143 {"add", no_argument, NULL, OPT_ADD},
144 {"replace", no_argument, NULL, OPT_REPLACE},
145 {0, 0, 0, 0},
146 };
147
148 while (1)
149 {
150 option_rv= getopt_long(argc, argv, "Vhvds:", long_options, &option_index);
151
152 if (option_rv == -1) break;
153
154 switch (option_rv)
155 {
156 case 0:
157 break;
158 case OPT_VERBOSE: /* --verbose or -v */
159 opt_verbose = OPT_VERBOSE;
160 break;
161 case OPT_DEBUG: /* --debug or -d */
162 opt_verbose = OPT_DEBUG;
163 break;
164 case OPT_VERSION: /* --version or -V */
165 version_command(PROGRAM_NAME);
166 break;
167 case OPT_HELP: /* --help or -h */
168 help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options);
169 break;
170 case OPT_SERVERS: /* --servers or -s */
171 opt_servers= strdup(optarg);
172 break;
173 case OPT_FLAG: /* --flag */
174 opt_flags= (uint16_t)strtol(optarg, (char **)NULL, 16);
175 break;
176 case OPT_EXPIRE: /* --expire */
177 opt_expires= (time_t)strtoll(optarg, (char **)NULL, 10);
178 break;
179 case OPT_SET:
180 opt_method= OPT_SET;
181 break;
182 case OPT_REPLACE:
183 opt_method= OPT_REPLACE;
184 break;
185 case OPT_ADD:
186 opt_method= OPT_ADD;
187 break;
188 case '?':
189 /* getopt_long already printed an error message. */
190 exit(1);
191 default:
192 abort();
193 }
194 }
195 }