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