1 /* $NetBSD: dict_test.c,v 1.1.1.2 2013/09/25 19:06:37 tron Exp $ */ 2 3 /* 4 * Proof-of-concept test program. Create, update or read a database. When 5 * the input is a name=value pair, the database is updated, otherwise the 6 * program assumes that the input specifies a lookup key and prints the 7 * corresponding value. 8 */ 9 10 /* System library. */ 11 12 #include <sys_defs.h> 13 #include <stdlib.h> 14 #include <fcntl.h> 15 #include <unistd.h> 16 #include <signal.h> 17 #include <string.h> 18 19 /* Utility library. */ 20 21 #include <msg.h> 22 #include <stringops.h> 23 #include <vstring.h> 24 #include <vstream.h> 25 #include <msg_vstream.h> 26 #include <vstring_vstream.h> 27 #include <dict.h> 28 29 static NORETURN usage(char *myname) 30 { 31 msg_fatal("usage: %s type:file read|write|create [fold] [sync]", myname); 32 } 33 34 void dict_test(int argc, char **argv) 35 { 36 VSTRING *keybuf = vstring_alloc(1); 37 VSTRING *inbuf = vstring_alloc(1); 38 DICT *dict; 39 char *dict_name; 40 int open_flags; 41 char *bufp; 42 char *cmd; 43 const char *key; 44 const char *value; 45 int ch; 46 int dict_flags = DICT_FLAG_LOCK | DICT_FLAG_DUP_REPLACE; 47 int n; 48 int rc; 49 50 signal(SIGPIPE, SIG_IGN); 51 52 msg_vstream_init(argv[0], VSTREAM_ERR); 53 while ((ch = GETOPT(argc, argv, "v")) > 0) { 54 switch (ch) { 55 default: 56 usage(argv[0]); 57 case 'v': 58 msg_verbose++; 59 break; 60 } 61 } 62 optind = OPTIND; 63 if (argc - optind < 2) 64 usage(argv[0]); 65 if (strcasecmp(argv[optind + 1], "create") == 0) 66 open_flags = O_CREAT | O_RDWR | O_TRUNC; 67 else if (strcasecmp(argv[optind + 1], "write") == 0) 68 open_flags = O_RDWR; 69 else if (strcasecmp(argv[optind + 1], "read") == 0) 70 open_flags = O_RDONLY; 71 else 72 msg_fatal("unknown access mode: %s", argv[2]); 73 for (n = 2; argv[optind + n]; n++) { 74 if (strcasecmp(argv[optind + 2], "fold") == 0) 75 dict_flags |= DICT_FLAG_FOLD_ANY; 76 else if (strcasecmp(argv[optind + 2], "sync") == 0) 77 dict_flags |= DICT_FLAG_SYNC_UPDATE; 78 else if (strcasecmp(argv[optind + 2], "open_lock") == 0) { 79 dict_flags |= DICT_FLAG_OPEN_LOCK; 80 dict_flags &= ~DICT_FLAG_LOCK; 81 } else 82 usage(argv[0]); 83 } 84 vstream_fflush(VSTREAM_OUT); 85 dict_name = argv[optind]; 86 dict_allow_surrogate = 1; 87 dict = dict_open(dict_name, open_flags, dict_flags); 88 dict_register(dict_name, dict); 89 while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) { 90 bufp = vstring_str(inbuf); 91 if (!isatty(0)) { 92 vstream_printf("> %s\n", bufp); 93 vstream_fflush(VSTREAM_OUT); 94 } 95 if (*bufp == '#') 96 continue; 97 if ((cmd = mystrtok(&bufp, " ")) == 0) { 98 vstream_printf("usage: verbose|del key|get key|put key=value|first|next|masks|flags\n"); 99 vstream_fflush(VSTREAM_OUT); 100 continue; 101 } 102 if (dict_changed_name()) 103 msg_warn("dictionary has changed"); 104 key = *bufp ? vstring_str(unescape(keybuf, mystrtok(&bufp, " ="))) : 0; 105 value = mystrtok(&bufp, " ="); 106 if (strcmp(cmd, "verbose") == 0 && !key) { 107 msg_verbose++; 108 } else if (strcmp(cmd, "del") == 0 && key && !value) { 109 if ((rc = dict_del(dict, key)) > 0) 110 vstream_printf("%s: not found\n", key); 111 else if (rc < 0) 112 vstream_printf("%s: error\n", key); 113 else 114 vstream_printf("%s: deleted\n", key); 115 } else if (strcmp(cmd, "get") == 0 && key && !value) { 116 if ((value = dict_get(dict, key)) == 0) { 117 vstream_printf("%s: %s\n", key, dict->error ? 118 "error" : "not found"); 119 } else { 120 vstream_printf("%s=%s\n", key, value); 121 } 122 } else if (strcmp(cmd, "put") == 0 && key && value) { 123 if (dict_put(dict, key, value) != 0) 124 vstream_printf("%s: %s\n", key, dict->error ? 125 "error" : "not updated"); 126 else 127 vstream_printf("%s=%s\n", key, value); 128 } else if (strcmp(cmd, "first") == 0 && !key && !value) { 129 if (dict_seq(dict, DICT_SEQ_FUN_FIRST, &key, &value) == 0) 130 vstream_printf("%s=%s\n", key, value); 131 else 132 vstream_printf("%s\n", dict->error ? 133 "error" : "not found"); 134 } else if (strcmp(cmd, "next") == 0 && !key && !value) { 135 if (dict_seq(dict, DICT_SEQ_FUN_NEXT, &key, &value) == 0) 136 vstream_printf("%s=%s\n", key, value); 137 else 138 vstream_printf("%s\n", dict->error ? 139 "error" : "not found"); 140 } else if (strcmp(cmd, "flags") == 0 && !key && !value) { 141 vstream_printf("dict flags %s\n", 142 dict_flags_str(dict->flags)); 143 } else if (strcmp(cmd, "masks") == 0 && !key && !value) { 144 vstream_printf("DICT_FLAG_IMPL_MASK %s\n", 145 dict_flags_str(DICT_FLAG_IMPL_MASK)); 146 vstream_printf("DICT_FLAG_PARANOID %s\n", 147 dict_flags_str(DICT_FLAG_PARANOID)); 148 vstream_printf("DICT_FLAG_RQST_MASK %s\n", 149 dict_flags_str(DICT_FLAG_RQST_MASK)); 150 vstream_printf("DICT_FLAG_INST_MASK %s\n", 151 dict_flags_str(DICT_FLAG_INST_MASK)); 152 } else { 153 vstream_printf("usage: del key|get key|put key=value|first|next|masks|flags\n"); 154 } 155 vstream_fflush(VSTREAM_OUT); 156 } 157 vstring_free(keybuf); 158 vstring_free(inbuf); 159 dict_close(dict); 160 } 161