Postfix3.3.1
dict_inline.c
[詳解]
1 /*++
2 /* NAME
3 /* dict_inline 3
4 /* SUMMARY
5 /* dictionary manager interface for inline table
6 /* SYNOPSIS
7 /* #include <dict_inline.h>
8 /*
9 /* DICT *dict_inline_open(name, open_flags, dict_flags)
10 /* const char *name;
11 /* int open_flags;
12 /* int dict_flags;
13 /* DESCRIPTION
14 /* dict_inline_open() opens a read-only, in-memory table.
15 /* Example: "\fBinline:{\fIkey_1=value_1, ..., key_n=value_n\fR}".
16 /* The longer form with { key = value } allows values that
17 /* contain whitespace or comma.
18 /* SEE ALSO
19 /* dict(3) generic dictionary manager
20 /* LICENSE
21 /* .ad
22 /* .fi
23 /* The Secure Mailer license must be distributed with this software.
24 /* AUTHOR(S)
25 /* Wietse Venema
26 /* IBM T.J. Watson Research
27 /* P.O. Box 704
28 /* Yorktown Heights, NY 10598, USA
29 /*
30 /* Wietse Venema
31 /* Google, Inc.
32 /* 111 8th Avenue
33 /* New York, NY 10011, USA
34 /*--*/
35 
36 /* System library. */
37 
38 #include <sys_defs.h>
39 #include <string.h>
40 
41 /* Utility library. */
42 
43 #include <msg.h>
44 #include <mymalloc.h>
45 #include <stringops.h>
46 #include <dict.h>
47 #include <dict_ht.h>
48 #include <dict_inline.h>
49 
50 /* Application-specific. */
51 
52 /* dict_inline_open - open inline table */
53 
54 DICT *dict_inline_open(const char *name, int open_flags, int dict_flags)
55 {
56  DICT *dict;
57  char *cp, *saved_name = 0;
58  size_t len;
59  char *nameval, *vname, *value;
60  const char *err = 0;
61  char *xperr = 0;
62  int count = 0;
63 
64  /*
65  * Clarity first. Let the optimizer worry about redundant code.
66  */
67 #define DICT_INLINE_RETURN(x) do { \
68  DICT *__d = (x); \
69  if (saved_name != 0) \
70  myfree(saved_name); \
71  if (xperr != 0) \
72  myfree(xperr); \
73  return (__d); \
74  } while (0)
75 
76  /*
77  * Sanity checks.
78  */
79  if (open_flags != O_RDONLY)
81  open_flags, dict_flags,
82  "%s:%s map requires O_RDONLY access mode",
83  DICT_TYPE_INLINE, name));
84 
85  /*
86  * UTF-8 syntax check.
87  */
89  && allascii(name) == 0
90  && valid_utf8_string(name, strlen(name)) == 0)
92  open_flags, dict_flags,
93  "bad UTF-8 syntax: \"%s:%s\"; "
94  "need \"%s:{name=value...}\"",
95  DICT_TYPE_INLINE, name,
97 
98  /*
99  * Parse the table into its constituent name=value pairs.
100  */
101  if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0
102  || *(cp = saved_name = mystrndup(name + 1, len - 2)) == 0)
104  open_flags, dict_flags,
105  "bad syntax: \"%s:%s\"; "
106  "need \"%s:{name=value...}\"",
107  DICT_TYPE_INLINE, name,
109 
110  /*
111  * Reuse the "internal" dictionary type.
112  */
113  dict = dict_open3(DICT_TYPE_HT, name, open_flags, dict_flags);
115  while ((nameval = mystrtokq(&cp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
116  if ((nameval[0] != CHARS_BRACE[0]
117  || (err = xperr = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP)) == 0)
118  && (err = split_qnameval(nameval, &vname, &value)) != 0)
119  break;
120 
121  /* No duplicate checks. See comments in dict_thash.c. */
122  dict->update(dict, vname, value);
123  count += 1;
124  }
125  if (err != 0 || count == 0) {
126  dict->close(dict);
128  open_flags, dict_flags,
129  "%s: \"%s:%s\"; "
130  "need \"%s:{name=value...}\"",
131  err != 0 ? err : "empty table",
132  DICT_TYPE_INLINE, name,
134  }
136 
138 }
#define CHARS_BRACE
Definition: sys_defs.h:1763
#define DICT_NEED_UTF8_ACTIVATION(enable, flags)
Definition: dict.h:171
#define DICT_TYPE_HT
Definition: dict_ht.h:23
char * extpar(char **bp, const char *parens, int flags)
Definition: extpar.c:77
void(* close)(struct DICT *)
Definition: dict.h:87
int valid_utf8_string(const char *, ssize_t)
#define EXTPAR_FLAG_STRIP
Definition: stringops.h:57
char * mystrtokq(char **src, const char *sep, const char *parens)
Definition: mystrtok.c:80
DICT * dict_inline_open(const char *name, int open_flags, int dict_flags)
Definition: dict_inline.c:54
DICT * dict_open3(const char *, const char *, int, int)
Definition: dict_open.c:439
Definition: dict.h:78
int(* update)(struct DICT *, const char *, const char *)
Definition: dict.h:83
const char * split_qnameval(char *buf, char **pkey, char **pvalue)
#define DICT_OWNER_TRUSTED
Definition: dict.h:46
void dict_type_override(DICT *, const char *)
Definition: dict_open.c:563
#define allascii(s)
Definition: stringops.h:66
int status
Definition: dict.h:38
#define CHARS_COMMA_SP
Definition: sys_defs.h:1761
char * mystrndup(const char *str, ssize_t len)
Definition: mymalloc.c:242
size_t balpar(const char *string, const char *parens)
Definition: balpar.c:39
#define DICT_INLINE_RETURN(x)
int util_utf8_enable
Definition: printable.c:47
DICT_OWNER owner
Definition: dict.h:93
#define DICT_TYPE_INLINE
Definition: dict_inline.h:22
DICT * dict_surrogate(const char *dict_type, const char *dict_name, int open_flags, int dict_flags, const char *fmt,...)