xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_test.c (revision a24efa7dea9f1f56c3bdb15a927d3516792ace1c)
1 /*	$NetBSD: dict_test.c,v 1.1.1.3 2014/07/06 19:27:58 tron 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 /* Utility library. */
18 
19 #include <msg.h>
20 #include <stringops.h>
21 #include <vstring.h>
22 #include <vstream.h>
23 #include <msg_vstream.h>
24 #include <vstring_vstream.h>
25 #include <dict.h>
26 
27 static NORETURN usage(char *myname)
28 {
29     msg_fatal("usage: %s type:file read|write|create [flags...]", myname);
30 }
31 
32 void    dict_test(int argc, char **argv)
33 {
34     VSTRING *keybuf = vstring_alloc(1);
35     VSTRING *inbuf = vstring_alloc(1);
36     DICT   *dict;
37     char   *dict_name;
38     int     open_flags;
39     char   *bufp;
40     char   *cmd;
41     const char *key;
42     const char *value;
43     int     ch;
44     int     dict_flags = 0;
45     int     n;
46     int     rc;
47 
48 #define USAGE	"verbose|del key|get key|put key=value|first|next|masks|flags"
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 	dict_flags |= dict_flags_mask(argv[optind + 2]);
75     if ((dict_flags & DICT_FLAG_OPEN_LOCK) == 0)
76 	dict_flags |= DICT_FLAG_LOCK;
77     if ((dict_flags & (DICT_FLAG_DUP_WARN | DICT_FLAG_DUP_IGNORE)) == 0)
78 	dict_flags |= DICT_FLAG_DUP_REPLACE;
79     vstream_fflush(VSTREAM_OUT);
80     dict_name = argv[optind];
81     dict_allow_surrogate = 1;
82     dict = dict_open(dict_name, open_flags, dict_flags);
83     dict_register(dict_name, dict);
84     while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
85 	bufp = vstring_str(inbuf);
86 	if (!isatty(0)) {
87 	    vstream_printf("> %s\n", bufp);
88 	    vstream_fflush(VSTREAM_OUT);
89 	}
90 	if (*bufp == '#')
91 	    continue;
92 	if ((cmd = mystrtok(&bufp, " ")) == 0) {
93 	    vstream_printf("usage: %s\n", USAGE);
94 	    vstream_fflush(VSTREAM_OUT);
95 	    continue;
96 	}
97 	if (dict_changed_name())
98 	    msg_warn("dictionary has changed");
99 	key = *bufp ? vstring_str(unescape(keybuf, mystrtok(&bufp, " ="))) : 0;
100 	value = mystrtok(&bufp, " =");
101 	if (strcmp(cmd, "verbose") == 0 && !key) {
102 	    msg_verbose++;
103 	} else if (strcmp(cmd, "del") == 0 && key && !value) {
104 	    if ((rc = dict_del(dict, key)) > 0)
105 		vstream_printf("%s: not found\n", key);
106 	    else if (rc < 0)
107 		vstream_printf("%s: error\n", key);
108 	    else
109 		vstream_printf("%s: deleted\n", key);
110 	} else if (strcmp(cmd, "get") == 0 && key && !value) {
111 	    if ((value = dict_get(dict, key)) == 0) {
112 		vstream_printf("%s: %s\n", key, dict->error ?
113 			       "error" : "not found");
114 	    } else {
115 		vstream_printf("%s=%s\n", key, value);
116 	    }
117 	} else if (strcmp(cmd, "put") == 0 && key && value) {
118 	    if (dict_put(dict, key, value) != 0)
119 		vstream_printf("%s: %s\n", key, dict->error ?
120 			       "error" : "not updated");
121 	    else
122 		vstream_printf("%s=%s\n", key, value);
123 	} else if (strcmp(cmd, "first") == 0 && !key && !value) {
124 	    if (dict_seq(dict, DICT_SEQ_FUN_FIRST, &key, &value) == 0)
125 		vstream_printf("%s=%s\n", key, value);
126 	    else
127 		vstream_printf("%s\n", dict->error ?
128 			       "error" : "not found");
129 	} else if (strcmp(cmd, "next") == 0 && !key && !value) {
130 	    if (dict_seq(dict, DICT_SEQ_FUN_NEXT, &key, &value) == 0)
131 		vstream_printf("%s=%s\n", key, value);
132 	    else
133 		vstream_printf("%s\n", dict->error ?
134 			       "error" : "not found");
135 	} else if (strcmp(cmd, "flags") == 0 && !key && !value) {
136 	    vstream_printf("dict flags %s\n",
137 			   dict_flags_str(dict->flags));
138 	} else if (strcmp(cmd, "masks") == 0 && !key && !value) {
139 	    vstream_printf("DICT_FLAG_IMPL_MASK %s\n",
140 			   dict_flags_str(DICT_FLAG_IMPL_MASK));
141 	    vstream_printf("DICT_FLAG_PARANOID %s\n",
142 			   dict_flags_str(DICT_FLAG_PARANOID));
143 	    vstream_printf("DICT_FLAG_RQST_MASK %s\n",
144 			   dict_flags_str(DICT_FLAG_RQST_MASK));
145 	    vstream_printf("DICT_FLAG_INST_MASK %s\n",
146 			   dict_flags_str(DICT_FLAG_INST_MASK));
147 	} else {
148 	    vstream_printf("usage: %s\n", USAGE);
149 	}
150 	vstream_fflush(VSTREAM_OUT);
151     }
152     vstring_free(keybuf);
153     vstring_free(inbuf);
154     dict_close(dict);
155 }
156