Postfix3.3.1
dict_test.c
[詳解]
1  /*
2  * Proof-of-concept test program. Create, update or read a database. Type
3  * '?' for a list of commands.
4  */
5 
6 /* System library. */
7 
8 #include <sys_defs.h>
9 #include <stdlib.h>
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <signal.h>
13 #include <string.h>
14 
15 #ifdef STRCASECMP_IN_STRINGS_H
16 #include <strings.h>
17 #endif
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 #include <dict_lmdb.h>
29 #include <dict_db.h>
30 
31 static NORETURN usage(char *myname)
32 {
33  msg_fatal("usage: %s type:file read|write|create [flags...]", myname);
34 }
35 
36 void dict_test(int argc, char **argv)
37 {
38  VSTRING *keybuf = vstring_alloc(1);
39  VSTRING *inbuf = vstring_alloc(1);
40  DICT *dict;
41  char *dict_name;
42  int open_flags;
43  char *bufp;
44  char *cmd;
45  const char *key;
46  const char *value;
47  int ch;
48  int dict_flags = 0;
49  int n;
50  int rc;
51 
52 #define USAGE "verbose|del key|get key|put key=value|first|next|masks|flags"
53 
54  signal(SIGPIPE, SIG_IGN);
55 
56  msg_vstream_init(argv[0], VSTREAM_ERR);
57  while ((ch = GETOPT(argc, argv, "v")) > 0) {
58  switch (ch) {
59  default:
60  usage(argv[0]);
61  case 'v':
62  msg_verbose++;
63  break;
64  }
65  }
66  optind = OPTIND;
67  if (argc - optind < 2)
68  usage(argv[0]);
69  if (strcasecmp(argv[optind + 1], "create") == 0)
70  open_flags = O_CREAT | O_RDWR | O_TRUNC;
71  else if (strcasecmp(argv[optind + 1], "write") == 0)
72  open_flags = O_RDWR;
73  else if (strcasecmp(argv[optind + 1], "read") == 0)
74  open_flags = O_RDONLY;
75  else
76  msg_fatal("unknown access mode: %s", argv[2]);
77  for (n = 2; argv[optind + n]; n++)
78  dict_flags |= dict_flags_mask(argv[optind + 2]);
79  if ((dict_flags & DICT_FLAG_OPEN_LOCK) == 0)
80  dict_flags |= DICT_FLAG_LOCK;
81  if ((dict_flags & (DICT_FLAG_DUP_WARN | DICT_FLAG_DUP_IGNORE)) == 0)
82  dict_flags |= DICT_FLAG_DUP_REPLACE;
83  dict_flags |= DICT_FLAG_UTF8_REQUEST;
85  dict_name = argv[optind];
87  util_utf8_enable = 1;
88  dict = dict_open(dict_name, open_flags, dict_flags);
89  dict_register(dict_name, dict);
90  vstream_printf("owner=%s (uid=%ld)\n",
91  dict->owner.status == DICT_OWNER_TRUSTED ? "trusted" :
92  dict->owner.status == DICT_OWNER_UNTRUSTED ? "untrusted" :
93  dict->owner.status == DICT_OWNER_UNKNOWN ? "unspecified" :
94  "error", (long) dict->owner.uid);
96 
97  while (vstring_fgets_nonl(inbuf, VSTREAM_IN)) {
98  bufp = vstring_str(inbuf);
99  if (!isatty(0)) {
100  vstream_printf("> %s\n", bufp);
102  }
103  if (*bufp == '#')
104  continue;
105  if ((cmd = mystrtok(&bufp, " ")) == 0) {
106  vstream_printf("usage: %s\n", USAGE);
108  continue;
109  }
110  if (dict_changed_name())
111  msg_warn("dictionary has changed");
112  key = *bufp ? vstring_str(unescape(keybuf, mystrtok(&bufp, " ="))) : 0;
113  value = mystrtok(&bufp, " =");
114  if (strcmp(cmd, "verbose") == 0 && !key) {
115  msg_verbose++;
116  } else if (strcmp(cmd, "del") == 0 && key && !value) {
117  if ((rc = dict_del(dict, key)) > 0)
118  vstream_printf("%s: not found\n", key);
119  else if (rc < 0)
120  vstream_printf("%s: error\n", key);
121  else
122  vstream_printf("%s: deleted\n", key);
123  } else if (strcmp(cmd, "get") == 0 && key && !value) {
124  if ((value = dict_get(dict, key)) == 0) {
125  vstream_printf("%s: %s\n", key, dict->error ?
126  "error" : "not found");
127  } else {
128  vstream_printf("%s=%s\n", key, value);
129  }
130  } else if (strcmp(cmd, "put") == 0 && key && value) {
131  if (dict_put(dict, key, value) != 0)
132  vstream_printf("%s: %s\n", key, dict->error ?
133  "error" : "not updated");
134  } else if (strcmp(cmd, "first") == 0 && !key && !value) {
135  if (dict_seq(dict, DICT_SEQ_FUN_FIRST, &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, "next") == 0 && !key && !value) {
141  if (dict_seq(dict, DICT_SEQ_FUN_NEXT, &key, &value) == 0)
142  vstream_printf("%s=%s\n", key, value);
143  else
144  vstream_printf("%s\n", dict->error ?
145  "error" : "not found");
146  } else if (strcmp(cmd, "flags") == 0 && !key && !value) {
147  vstream_printf("dict flags %s\n",
148  dict_flags_str(dict->flags));
149  } else if (strcmp(cmd, "masks") == 0 && !key && !value) {
150  vstream_printf("DICT_FLAG_IMPL_MASK %s\n",
152  vstream_printf("DICT_FLAG_PARANOID %s\n",
154  vstream_printf("DICT_FLAG_RQST_MASK %s\n",
156  vstream_printf("DICT_FLAG_INST_MASK %s\n",
158  } else {
159  vstream_printf("usage: %s\n", USAGE);
160  }
162  }
163  vstring_free(keybuf);
164  vstring_free(inbuf);
165  dict_close(dict);
166 }
int msg_verbose
Definition: msg.c:177
#define DICT_FLAG_DUP_IGNORE
Definition: dict.h:111
#define vstring_fgets_nonl(s, p)
#define DICT_OWNER_UNTRUSTED
Definition: dict.h:47
uid_t uid
Definition: dict.h:39
#define dict_put(dp, key, val)
Definition: dict.h:237
void dict_register(const char *dict_name, DICT *dict_info)
Definition: dict.c:312
#define DICT_FLAG_RQST_MASK
Definition: dict.h:162
#define DICT_SEQ_FUN_FIRST
Definition: dict.h:200
#define NORETURN
Definition: sys_defs.h:1583
#define vstring_str(vp)
Definition: vstring.h:71
#define VSTREAM_OUT
Definition: vstream.h:67
#define DICT_SEQ_FUN_NEXT
Definition: dict.h:201
int flags
Definition: dict.h:81
#define USAGE
DICT * dict_open(const char *, int, int)
Definition: dict_open.c:421
#define DICT_FLAG_UTF8_REQUEST
Definition: dict.h:130
#define VSTREAM_IN
Definition: vstream.h:66
char * mystrtok(char **src, const char *sep)
Definition: mystrtok.c:54
int dict_flags_mask(const char *names)
Definition: dict.c:660
Definition: dict.h:78
void dict_test(int argc, char **argv)
Definition: dict_test.c:36
#define DICT_OWNER_TRUSTED
Definition: dict.h:46
#define dict_get(dp, key)
Definition: dict.h:236
#define DICT_FLAG_DUP_REPLACE
Definition: dict.h:117
#define DICT_OWNER_UNKNOWN
Definition: dict.h:45
int dict_allow_surrogate
const char * dict_changed_name(void)
Definition: dict.c:583
#define dict_seq(dp, f, key, val)
Definition: dict.h:239
VSTREAM * vstream_printf(const char *fmt,...)
Definition: vstream.c:1335
#define DICT_FLAG_LOCK
Definition: dict.h:116
#define DICT_FLAG_PARANOID
Definition: dict.h:158
void msg_warn(const char *fmt,...)
Definition: msg.c:215
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
const char * dict_flags_str(int dict_flags)
Definition: dict.c:647
#define DICT_FLAG_INST_MASK
Definition: dict.h:166
int error
Definition: dict.h:94
#define DICT_FLAG_DUP_WARN
Definition: dict.h:110
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int status
Definition: dict.h:38
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
#define GETOPT(argc, argv, str)
Definition: sys_defs.h:1313
#define DICT_FLAG_IMPL_MASK
Definition: dict.h:160
#define OPTIND
int strcasecmp(const char *s1, const char *s2)
Definition: strcasecmp.c:41
VSTRING * vstring_free(VSTRING *vp)
Definition: vstring.c:380
void msg_vstream_init(const char *name, VSTREAM *vp)
Definition: msg_vstream.c:77
int util_utf8_enable
Definition: printable.c:47
#define dict_del(dp, key)
Definition: dict.h:238
DICT_OWNER owner
Definition: dict.h:93
#define VSTREAM_ERR
Definition: vstream.h:68
#define DICT_FLAG_OPEN_LOCK
Definition: dict.h:127
#define dict_close(dp)
Definition: dict.h:240
VSTRING * unescape(VSTRING *, const char *)
Definition: unescape.c:69