]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/tokyocabinet/tcamgr.c
ebl Add tokyocabinet source to bacula
[bacula/bacula] / bacula / src / lib / tokyocabinet / tcamgr.c
1 /*************************************************************************************************
2  * The command line utility of the abstract database API
3  *                                                      Copyright (C) 2006-2008 Mikio Hirabayashi
4  * This file is part of Tokyo Cabinet.
5  * Tokyo Cabinet is free software; you can redistribute it and/or modify it under the terms of
6  * the GNU Lesser General Public License as published by the Free Software Foundation; either
7  * version 2.1 of the License or any later version.  Tokyo Cabinet is distributed in the hope
8  * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
10  * License for more details.
11  * You should have received a copy of the GNU Lesser General Public License along with Tokyo
12  * Cabinet; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13  * Boston, MA 02111-1307 USA.
14  *************************************************************************************************/
15
16
17 #include <tcutil.h>
18 #include <tcadb.h>
19 #include "myconf.h"
20
21
22 /* global variables */
23 const char *g_progname;                  // program name
24
25
26 /* function prototypes */
27 int main(int argc, char **argv);
28 static void usage(void);
29 static void printerr(TCADB *adb);
30 static int printdata(const char *ptr, int size, bool px);
31 static char *hextoobj(const char *str, int *sp);
32 static int runcreate(int argc, char **argv);
33 static int runinform(int argc, char **argv);
34 static int runput(int argc, char **argv);
35 static int runout(int argc, char **argv);
36 static int runget(int argc, char **argv);
37 static int runlist(int argc, char **argv);
38 static int runversion(int argc, char **argv);
39 static int proccreate(const char *name);
40 static int procinform(const char *name);
41 static int procput(const char *name, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
42                    int dmode);
43 static int procout(const char *name, const char *kbuf, int ksiz);
44 static int procget(const char *name, const char *kbuf, int ksiz, bool px, bool pz);
45 static int proclist(const char *name, int max, bool pv, bool px, const char *fmstr);
46 static int procversion(void);
47
48
49 /* main routine */
50 int main(int argc, char **argv){
51   g_progname = argv[0];
52   if(argc < 2) usage();
53   int rv = 0;
54   if(!strcmp(argv[1], "create")){
55     rv = runcreate(argc, argv);
56   } else if(!strcmp(argv[1], "inform")){
57     rv = runinform(argc, argv);
58   } else if(!strcmp(argv[1], "put")){
59     rv = runput(argc, argv);
60   } else if(!strcmp(argv[1], "out")){
61     rv = runout(argc, argv);
62   } else if(!strcmp(argv[1], "get")){
63     rv = runget(argc, argv);
64   } else if(!strcmp(argv[1], "list")){
65     rv = runlist(argc, argv);
66   } else if(!strcmp(argv[1], "version") || !strcmp(argv[1], "--version")){
67     rv = runversion(argc, argv);
68   } else {
69     usage();
70   }
71   return rv;
72 }
73
74
75 /* print the usage and exit */
76 static void usage(void){
77   fprintf(stderr, "%s: the command line utility of the abstract database API\n", g_progname);
78   fprintf(stderr, "\n");
79   fprintf(stderr, "usage:\n");
80   fprintf(stderr, "  %s create name\n", g_progname);
81   fprintf(stderr, "  %s inform name\n", g_progname);
82   fprintf(stderr, "  %s put [-sx] [-dk|-dc] name key value\n", g_progname);
83   fprintf(stderr, "  %s out [-sx] name key\n", g_progname);
84   fprintf(stderr, "  %s get [-sx] [-px] [-pz] name key\n", g_progname);
85   fprintf(stderr, "  %s list [-m num] [-pv] [-px] [-fm str] name\n", g_progname);
86   fprintf(stderr, "  %s version\n", g_progname);
87   fprintf(stderr, "\n");
88   exit(1);
89 }
90
91
92 /* print error information */
93 static void printerr(TCADB *adb){
94   fprintf(stderr, "%s: error\n", g_progname);
95 }
96
97
98 /* print record data */
99 static int printdata(const char *ptr, int size, bool px){
100   int len = 0;
101   while(size-- > 0){
102     if(px){
103       if(len > 0) putchar(' ');
104       len += printf("%02X", *(unsigned char *)ptr);
105     } else {
106       putchar(*ptr);
107       len++;
108     }
109     ptr++;
110   }
111   return len;
112 }
113
114
115 /* create a binary object from a hexadecimal string */
116 static char *hextoobj(const char *str, int *sp){
117   int len = strlen(str);
118   char *buf = tcmalloc(len + 1);
119   int j = 0;
120   for(int i = 0; i < len; i += 2){
121     while(strchr(" \n\r\t\f\v", str[i])){
122       i++;
123     }
124     char mbuf[3];
125     if((mbuf[0] = str[i]) == '\0') break;
126     if((mbuf[1] = str[i+1]) == '\0') break;
127     mbuf[2] = '\0';
128     buf[j++] = (char)strtol(mbuf, NULL, 16);
129   }
130   buf[j] = '\0';
131   *sp = j;
132   return buf;
133 }
134
135
136 /* parse arguments of create command */
137 static int runcreate(int argc, char **argv){
138   char *name = NULL;
139   for(int i = 2; i < argc; i++){
140     if(!name && argv[i][0] == '-'){
141       usage();
142     } else if(!name){
143       name = argv[i];
144     } else {
145       usage();
146     }
147   }
148   if(!name) usage();
149   int rv = proccreate(name);
150   return rv;
151 }
152
153
154 /* parse arguments of inform command */
155 static int runinform(int argc, char **argv){
156   char *name = NULL;
157   for(int i = 2; i < argc; i++){
158     if(!name && argv[i][0] == '-'){
159       usage();
160     } else if(!name){
161       name = argv[i];
162     } else {
163       usage();
164     }
165   }
166   if(!name) usage();
167   name = tcsprintf("%s#mode=r", name);
168   int rv = procinform(name);
169   free(name);
170   return rv;
171 }
172
173
174 /* parse arguments of put command */
175 static int runput(int argc, char **argv){
176   char *name = NULL;
177   char *key = NULL;
178   char *value = NULL;
179   int dmode = 0;
180   bool sx = false;
181   for(int i = 2; i < argc; i++){
182     if(!name && argv[i][0] == '-'){
183       if(!strcmp(argv[i], "-dk")){
184         dmode = -1;
185       } else if(!strcmp(argv[i], "-dc")){
186         dmode = 1;
187       } else if(!strcmp(argv[i], "-sx")){
188         sx = true;
189       } else {
190         usage();
191       }
192     } else if(!name){
193       name = argv[i];
194     } else if(!key){
195       key = argv[i];
196     } else if(!value){
197       value = argv[i];
198     } else {
199       usage();
200     }
201   }
202   if(!name || !key || !value) usage();
203   int ksiz, vsiz;
204   char *kbuf, *vbuf;
205   if(sx){
206     kbuf = hextoobj(key, &ksiz);
207     vbuf = hextoobj(value, &vsiz);
208   } else {
209     ksiz = strlen(key);
210     kbuf = tcmemdup(key, ksiz);
211     vsiz = strlen(value);
212     vbuf = tcmemdup(value, vsiz);
213   }
214   int rv = procput(name, kbuf, ksiz, vbuf, vsiz, dmode);
215   free(vbuf);
216   free(kbuf);
217   return rv;
218 }
219
220
221 /* parse arguments of out command */
222 static int runout(int argc, char **argv){
223   char *name = NULL;
224   char *key = NULL;
225   bool sx = false;
226   for(int i = 2; i < argc; i++){
227     if(!name && argv[i][0] == '-'){
228       if(!strcmp(argv[i], "-sx")){
229         sx = true;
230       } else {
231         usage();
232       }
233     } else if(!name){
234       name = argv[i];
235     } else if(!key){
236       key = argv[i];
237     } else {
238       usage();
239     }
240   }
241   if(!name || !key) usage();
242   int ksiz;
243   char *kbuf;
244   if(sx){
245     kbuf = hextoobj(key, &ksiz);
246   } else {
247     ksiz = strlen(key);
248     kbuf = tcmemdup(key, ksiz);
249   }
250   int rv = procout(name, kbuf, ksiz);
251   free(kbuf);
252   return rv;
253 }
254
255
256 /* parse arguments of get command */
257 static int runget(int argc, char **argv){
258   char *name = NULL;
259   char *key = NULL;
260   bool sx = false;
261   bool px = false;
262   bool pz = false;
263   for(int i = 2; i < argc; i++){
264     if(!name && argv[i][0] == '-'){
265       if(!strcmp(argv[i], "-sx")){
266         sx = true;
267       } else if(!strcmp(argv[i], "-px")){
268         px = true;
269       } else if(!strcmp(argv[i], "-pz")){
270         pz = true;
271       } else {
272         usage();
273       }
274     } else if(!name){
275       name = argv[i];
276     } else if(!key){
277       key = argv[i];
278     } else {
279       usage();
280     }
281   }
282   if(!name || !key) usage();
283   int ksiz;
284   char *kbuf;
285   if(sx){
286     kbuf = hextoobj(key, &ksiz);
287   } else {
288     ksiz = strlen(key);
289     kbuf = tcmemdup(key, ksiz);
290   }
291   name = tcsprintf("%s#mode=r", name);
292   int rv = procget(name, kbuf, ksiz, px, pz);
293   free(name);
294   free(kbuf);
295   return rv;
296 }
297
298
299 /* parse arguments of list command */
300 static int runlist(int argc, char **argv){
301   char *name = NULL;
302   int max = -1;
303   bool pv = false;
304   bool px = false;
305   char *fmstr = NULL;
306   for(int i = 2; i < argc; i++){
307     if(!name && argv[i][0] == '-'){
308       if(!strcmp(argv[i], "-m")){
309         if(++i >= argc) usage();
310         max = atoi(argv[i]);
311       } else if(!strcmp(argv[i], "-pv")){
312         pv = true;
313       } else if(!strcmp(argv[i], "-px")){
314         px = true;
315       } else if(!strcmp(argv[i], "-fm")){
316         if(++i >= argc) usage();
317         fmstr = argv[i];
318       } else {
319         usage();
320       }
321     } else if(!name){
322       name = argv[i];
323     } else {
324       usage();
325     }
326   }
327   if(!name) usage();
328   name = tcsprintf("%s#mode=r", name);
329   int rv = proclist(name, max, pv, px, fmstr);
330   free(name);
331   return rv;
332 }
333
334
335 /* parse arguments of version command */
336 static int runversion(int argc, char **argv){
337   int rv = procversion();
338   return rv;
339 }
340
341
342 /* perform create command */
343 static int proccreate(const char *name){
344   TCADB *adb = tcadbnew();
345   if(!tcadbopen(adb, name)){
346     printerr(adb);
347     tcadbdel(adb);
348     return 1;
349   }
350   bool err = false;
351   if(!tcadbclose(adb)){
352     printerr(adb);
353     err = true;
354   }
355   tcadbdel(adb);
356   return err ? 1 : 0;
357 }
358
359
360 /* perform inform command */
361 static int procinform(const char *name){
362   TCADB *adb = tcadbnew();
363   if(!tcadbopen(adb, name)){
364     printerr(adb);
365     tcadbdel(adb);
366     return 1;
367   }
368   bool err = false;
369   printf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
370   printf("size: %llu\n", (unsigned long long)tcadbsize(adb));
371   if(!tcadbclose(adb)){
372     printerr(adb);
373     err = true;
374   }
375   tcadbdel(adb);
376   return err ? 1 : 0;
377 }
378
379
380 /* perform put command */
381 static int procput(const char *name, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
382                    int dmode){
383   TCADB *adb = tcadbnew();
384   if(!tcadbopen(adb, name)){
385     printerr(adb);
386     tcadbdel(adb);
387     return 1;
388   }
389   bool err = false;
390   switch(dmode){
391   case -1:
392     if(!tcadbputkeep(adb, kbuf, ksiz, vbuf, vsiz)){
393       printerr(adb);
394       err = true;
395     }
396     break;
397   case 1:
398     if(!tcadbputcat(adb, kbuf, ksiz, vbuf, vsiz)){
399       printerr(adb);
400       err = true;
401     }
402     break;
403   default:
404     if(!tcadbput(adb, kbuf, ksiz, vbuf, vsiz)){
405       printerr(adb);
406       err = true;
407     }
408     break;
409   }
410   if(!tcadbclose(adb)){
411     if(!err) printerr(adb);
412     err = true;
413   }
414   tcadbdel(adb);
415   return err ? 1 : 0;
416 }
417
418
419 /* perform out command */
420 static int procout(const char *name, const char *kbuf, int ksiz){
421   TCADB *adb = tcadbnew();
422   if(!tcadbopen(adb, name)){
423     printerr(adb);
424     tcadbdel(adb);
425     return 1;
426   }
427   bool err = false;
428   if(!tcadbout(adb, kbuf, ksiz)){
429     printerr(adb);
430     err = true;
431   }
432   if(!tcadbclose(adb)){
433     if(!err) printerr(adb);
434     err = true;
435   }
436   tcadbdel(adb);
437   return err ? 1 : 0;
438 }
439
440
441 /* perform get command */
442 static int procget(const char *name, const char *kbuf, int ksiz, bool px, bool pz){
443   TCADB *adb = tcadbnew();
444   if(!tcadbopen(adb, name)){
445     printerr(adb);
446     tcadbdel(adb);
447     return 1;
448   }
449   bool err = false;
450   int vsiz;
451   char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
452   if(vbuf){
453     printdata(vbuf, vsiz, px);
454     if(!pz) putchar('\n');
455     free(vbuf);
456   } else {
457     printerr(adb);
458     err = true;
459   }
460   if(!tcadbclose(adb)){
461     if(!err) printerr(adb);
462     err = true;
463   }
464   tcadbdel(adb);
465   return err ? 1 : 0;
466 }
467
468
469 /* perform list command */
470 static int proclist(const char *name, int max, bool pv, bool px, const char *fmstr){
471   TCADB *adb = tcadbnew();
472   if(!tcadbopen(adb, name)){
473     printerr(adb);
474     tcadbdel(adb);
475     return 1;
476   }
477   bool err = false;
478   if(fmstr){
479     TCLIST *keys = tcadbfwmkeys2(adb, fmstr, max);
480     for(int i = 0; i < tclistnum(keys); i++){
481       int ksiz;
482       const char *kbuf = tclistval(keys, i, &ksiz);
483       printdata(kbuf, ksiz, px);
484       if(pv){
485         int vsiz;
486         char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
487         if(vbuf){
488           putchar('\t');
489           printdata(vbuf, vsiz, px);
490           free(vbuf);
491         }
492       }
493       putchar('\n');
494     }
495     tclistdel(keys);
496   } else {
497     if(!tcadbiterinit(adb)){
498       printerr(adb);
499       err = true;
500     }
501     int ksiz;
502     char *kbuf;
503     int cnt = 0;
504     while((kbuf = tcadbiternext(adb, &ksiz)) != NULL){
505       printdata(kbuf, ksiz, px);
506       if(pv){
507         int vsiz;
508         char *vbuf = tcadbget(adb, kbuf, ksiz, &vsiz);
509         if(vbuf){
510           putchar('\t');
511           printdata(vbuf, vsiz, px);
512           free(vbuf);
513         }
514       }
515       putchar('\n');
516       free(kbuf);
517       if(max >= 0 && ++cnt >= max) break;
518     }
519   }
520   if(!tcadbclose(adb)){
521     if(!err) printerr(adb);
522     err = true;
523   }
524   tcadbdel(adb);
525   return err ? 1 : 0;
526 }
527
528
529 /* perform version command */
530 static int procversion(void){
531   printf("Tokyo Cabinet version %s (%d:%s)\n", tcversion, _TC_LIBVER, _TC_FORMATVER);
532   printf("Copyright (C) 2006-2008 Mikio Hirabayashi\n");
533   return 0;
534 }
535
536
537
538 // END OF FILE