Postfix3.3.1
dict_random.c
[詳解]
1 /*++
2 /* NAME
3 /* dict_random 3
4 /* SUMMARY
5 /* dictionary manager interface for randomized tables
6 /* SYNOPSIS
7 /* #include <dict_random.h>
8 /*
9 /* DICT *dict_random_open(name, open_flags, dict_flags)
10 /* const char *name;
11 /* int open_flags;
12 /* int dict_flags;
13 /* DESCRIPTION
14 /* dict_random_open() opens an in-memory, read-only, table.
15 /* Example: "\fBrandmap:{\fIresult_1, ... ,result_n}\fR".
16 /*
17 /* Each table query returns a random choice from the specified
18 /* results. Other table access methods are not supported.
19 /*
20 /* The first and last characters of the "randmap:" table name
21 /* must be '{' and '}'. Within these, individual maps are
22 /* separated with comma or whitespace.
23 /* SEE ALSO
24 /* dict(3) generic dictionary manager
25 /* LICENSE
26 /* .ad
27 /* .fi
28 /* The Secure Mailer license must be distributed with this software.
29 /* AUTHOR(S)
30 /* Wietse Venema
31 /* IBM T.J. Watson Research
32 /* P.O. Box 704
33 /* Yorktown Heights, NY 10598, 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 <myrand.h>
46 #include <stringops.h>
47 #include <dict_random.h>
48 
49 /* Application-specific. */
50 
51 typedef struct {
52  DICT dict; /* generic members */
53  ARGV *replies; /* reply values */
54 } DICT_RANDOM;
55 
56 #define STR(x) vstring_str(x)
57 
58 /* dict_random_lookup - find randomized-table entry */
59 
60 static const char *dict_random_lookup(DICT *dict, const char *unused_query)
61 {
62  DICT_RANDOM *dict_random = (DICT_RANDOM *) dict;
63 
65  dict_random->replies->argv[myrand() % dict_random->replies->argc]);
66 }
67 
68 /* dict_random_close - disassociate from randomized table */
69 
70 static void dict_random_close(DICT *dict)
71 {
72  DICT_RANDOM *dict_random = (DICT_RANDOM *) dict;
73 
74  argv_free(dict_random->replies);
75  dict_free(dict);
76 }
77 
78 /* dict_random_open - open a randomized table */
79 
80 DICT *dict_random_open(const char *name, int open_flags, int dict_flags)
81 {
82  DICT_RANDOM *dict_random;
83  char *saved_name = 0;
84  ARGV *argv;
85  size_t len;
86 
87  /*
88  * Clarity first. Let the optimizer worry about redundant code.
89  */
90 #define DICT_RANDOM_RETURN(x) do { \
91  if (saved_name != 0) \
92  myfree(saved_name); \
93  return (x); \
94  } while (0)
95 
96  /*
97  * Sanity checks.
98  */
99  if (open_flags != O_RDONLY)
101  open_flags, dict_flags,
102  "%s:%s map requires O_RDONLY access mode",
103  DICT_TYPE_RANDOM, name));
104 
105  /*
106  * Split the name name into its constituent parts.
107  */
108  if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0
109  || *(saved_name = mystrndup(name + 1, len - 2)) == 0
110  || ((argv = argv_splitq(saved_name, CHARS_COMMA_SP, CHARS_BRACE)),
111  (argv->argc == 0)))
113  open_flags, dict_flags,
114  "bad syntax: \"%s:%s\"; "
115  "need \"%s:{value...}\"",
116  DICT_TYPE_RANDOM, name,
118 
119  /*
120  * Bundle up the result.
121  */
122  dict_random =
123  (DICT_RANDOM *) dict_alloc(DICT_TYPE_RANDOM, name, sizeof(*dict_random));
124  dict_random->dict.lookup = dict_random_lookup;
125  dict_random->dict.close = dict_random_close;
126  dict_random->dict.flags = dict_flags | DICT_FLAG_PATTERN;
127  dict_random->replies = argv;
128  dict_random->dict.owner.status = DICT_OWNER_TRUSTED;
129  dict_random->dict.owner.uid = 0;
130 
131  DICT_RANDOM_RETURN(DICT_DEBUG (&dict_random->dict));
132 }
#define CHARS_BRACE
Definition: sys_defs.h:1763
uid_t uid
Definition: dict.h:39
ARGV * argv_free(ARGV *argvp)
Definition: argv.c:136
void(* close)(struct DICT *)
Definition: dict.h:87
Definition: argv.h:17
#define DICT_RANDOM_RETURN(x)
int flags
Definition: dict.h:81
ARGV * replies
Definition: dict_random.c:53
char ** argv
Definition: argv.h:20
#define DICT_ERR_NONE
Definition: dict.h:177
Definition: dict.h:78
#define DICT_OWNER_TRUSTED
Definition: dict.h:46
ARGV * argv_splitq(const char *, const char *, const char *)
Definition: argv_splitq.c:67
const char *(* lookup)(struct DICT *, const char *)
Definition: dict.h:82
#define DICT_TYPE_RANDOM
Definition: dict_random.h:22
#define DICT_ERR_VAL_RETURN(dict, err, val)
Definition: dict.h:192
int status
Definition: dict.h:38
#define CHARS_COMMA_SP
Definition: sys_defs.h:1761
#define DICT_FLAG_PATTERN
Definition: dict.h:115
void dict_free(DICT *)
Definition: dict_alloc.c:163
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
int myrand(void)
Definition: myrand.c:58
DICT * dict_random_open(const char *name, int open_flags, int dict_flags)
Definition: dict_random.c:80
ssize_t argc
Definition: argv.h:19
DICT * dict_alloc(const char *, const char *, ssize_t)
Definition: dict_alloc.c:135
DICT_OWNER owner
Definition: dict.h:93
DICT * dict_surrogate(const char *dict_type, const char *dict_name, int open_flags, int dict_flags, const char *fmt,...)