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