xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_test.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
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