1 /* $NetBSD: dict_test.c,v 1.1.1.1 2013/01/02 18:59:12 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 79 usage(argv[0]); 80 } 81 dict_name = argv[optind]; 82 dict_allow_surrogate = 1; 83 dict = dict_open(dict_name, open_flags, dict_flags); 84 dict_register(dict_name, dict); 85 while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) { 86 bufp = vstring_str(inbuf); 87 if (!isatty(0)) { 88 vstream_printf("> %s\n", bufp); 89 vstream_fflush(VSTREAM_OUT); 90 } 91 if (*bufp == '#') 92 continue; 93 if ((cmd = mystrtok(&bufp, " ")) == 0) { 94 vstream_printf("usage: verbose|del key|get key|put key=value|first|next|masks|flags\n"); 95 vstream_fflush(VSTREAM_OUT); 96 continue; 97 } 98 if (dict_changed_name()) 99 msg_warn("dictionary has changed"); 100 key = *bufp ? vstring_str(unescape(keybuf, mystrtok(&bufp, " ="))) : 0; 101 value = mystrtok(&bufp, " ="); 102 if (strcmp(cmd, "verbose") == 0 && !key) { 103 msg_verbose++; 104 } else if (strcmp(cmd, "del") == 0 && key && !value) { 105 if ((rc = dict_del(dict, key)) > 0) 106 vstream_printf("%s: not found\n", key); 107 else if (rc < 0) 108 vstream_printf("%s: error\n", key); 109 else 110 vstream_printf("%s: deleted\n", key); 111 } else if (strcmp(cmd, "get") == 0 && key && !value) { 112 if ((value = dict_get(dict, key)) == 0) { 113 vstream_printf("%s: %s\n", key, dict->error ? 114 "error" : "not found"); 115 } else { 116 vstream_printf("%s=%s\n", key, value); 117 } 118 } else if (strcmp(cmd, "put") == 0 && key && value) { 119 if (dict_put(dict, key, value) != 0) 120 vstream_printf("%s: %s\n", key, dict->error ? 121 "error" : "not updated"); 122 else 123 vstream_printf("%s=%s\n", key, value); 124 } else if (strcmp(cmd, "first") == 0 && !key && !value) { 125 if (dict_seq(dict, DICT_SEQ_FUN_FIRST, &key, &value) == 0) 126 vstream_printf("%s=%s\n", key, value); 127 else 128 vstream_printf("%s\n", dict->error ? 129 "error" : "not found"); 130 } else if (strcmp(cmd, "next") == 0 && !key && !value) { 131 if (dict_seq(dict, DICT_SEQ_FUN_NEXT, &key, &value) == 0) 132 vstream_printf("%s=%s\n", key, value); 133 else 134 vstream_printf("%s\n", dict->error ? 135 "error" : "not found"); 136 } else if (strcmp(cmd, "flags") == 0 && !key && !value) { 137 vstream_printf("dict flags %s\n", 138 dict_flags_str(dict->flags)); 139 } else if (strcmp(cmd, "masks") == 0 && !key && !value) { 140 vstream_printf("DICT_FLAG_IMPL_MASK %s\n", 141 dict_flags_str(DICT_FLAG_IMPL_MASK)); 142 vstream_printf("DICT_FLAG_PARANOID %s\n", 143 dict_flags_str(DICT_FLAG_PARANOID)); 144 vstream_printf("DICT_FLAG_RQST_MASK %s\n", 145 dict_flags_str(DICT_FLAG_RQST_MASK)); 146 vstream_printf("DICT_FLAG_INST_MASK %s\n", 147 dict_flags_str(DICT_FLAG_INST_MASK)); 148 } else { 149 vstream_printf("usage: del key|get key|put key=value|first|next|masks|flags\n"); 150 } 151 vstream_fflush(VSTREAM_OUT); 152 } 153 vstring_free(keybuf); 154 vstring_free(inbuf); 155 dict_close(dict); 156 } 157