88
89
static CLNT_STREAM *proxymap_stream; /* read-only maps */
89
90
static CLNT_STREAM *proxywrite_stream; /* read-write maps */
92
/* dict_proxy_sequence - find first/next entry */
94
static int dict_proxy_sequence(DICT *dict, int function,
95
const char **key, const char **value)
97
const char *myname = "dict_proxy_sequence";
98
DICT_PROXY *dict_proxy = (DICT_PROXY *) dict;
105
* The client and server live in separate processes that may start and
106
* terminate independently. We cannot rely on a persistent connection,
107
* let alone on persistent state (such as a specific open table) that is
108
* associated with a specific connection. Each lookup needs to specify
109
* the table and the flags that were specified to dict_proxy_open().
111
VSTRING_RESET(dict_proxy->reskey);
112
VSTRING_TERMINATE(dict_proxy->reskey);
113
VSTRING_RESET(dict_proxy->result);
114
VSTRING_TERMINATE(dict_proxy->result);
115
request_flags = dict_proxy->inst_flags
116
| (dict->flags & DICT_FLAG_RQST_MASK);
118
stream = clnt_stream_access(dict_proxy->clnt);
121
if (attr_print(stream, ATTR_FLAG_NONE,
122
ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_SEQUENCE,
123
ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict->name,
124
ATTR_TYPE_INT, MAIL_ATTR_FLAGS, request_flags,
125
ATTR_TYPE_INT, MAIL_ATTR_FUNC, function,
127
|| vstream_fflush(stream)
128
|| attr_scan(stream, ATTR_FLAG_STRICT,
129
ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
130
ATTR_TYPE_STR, MAIL_ATTR_KEY, dict_proxy->reskey,
131
ATTR_TYPE_STR, MAIL_ATTR_VALUE, dict_proxy->result,
132
ATTR_TYPE_END) != 3) {
133
if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
134
msg_warn("%s: service %s: %m", myname, VSTREAM_PATH(stream));
137
msg_info("%s: table=%s flags=%s func=%d -> status=%d key=%s val=%s",
138
myname, dict->name, dict_flags_str(request_flags),
139
function, status, STR(dict_proxy->reskey),
140
STR(dict_proxy->result));
143
msg_fatal("%s sequence failed for table \"%s\" function %d: "
145
dict_proxy->service, dict->name, function);
146
case PROXY_STAT_DENY:
147
msg_fatal("%s service is not configured for table \"%s\"",
148
dict_proxy->service, dict->name);
150
*key = STR(dict_proxy->reskey);
151
*value = STR(dict_proxy->result);
152
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_SUCCESS);
153
case PROXY_STAT_NOKEY:
155
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, DICT_STAT_FAIL);
156
case PROXY_STAT_RETRY:
158
DICT_ERR_VAL_RETURN(dict, DICT_ERR_RETRY, DICT_STAT_ERROR);
160
msg_warn("%s sequence failed for table \"%s\" function %d: "
161
"unexpected reply status %d",
162
dict_proxy->service, dict->name, function, status);
165
clnt_stream_recover(dict_proxy->clnt);
166
sleep(1); /* XXX make configurable */
91
170
/* dict_proxy_lookup - find table entry */
93
172
static const char *dict_proxy_lookup(DICT *dict, const char *key)
142
221
msg_fatal("%s service is not configured for table \"%s\"",
143
222
dict_proxy->service, dict->name);
144
223
case PROXY_STAT_OK:
145
return (STR(dict_proxy->result));
224
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, STR(dict_proxy->result));
146
225
case PROXY_STAT_NOKEY:
226
DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE, (char *) 0);
149
227
case PROXY_STAT_RETRY:
150
dict_errno = DICT_ERR_RETRY;
228
DICT_ERR_VAL_RETURN(dict, DICT_ERR_RETRY, (char *) 0);
153
230
msg_warn("%s lookup failed for table \"%s\" key \"%s\": "
154
231
"unexpected reply status %d",
381
467
if (attr_print(stream, ATTR_FLAG_NONE,
382
468
ATTR_TYPE_STR, MAIL_ATTR_REQ, PROXY_REQ_OPEN,
383
469
ATTR_TYPE_STR, MAIL_ATTR_TABLE, dict_proxy->dict.name,
384
ATTR_TYPE_INT, MAIL_ATTR_FLAGS, dict_proxy->in_flags,
470
ATTR_TYPE_INT, MAIL_ATTR_FLAGS, dict_proxy->inst_flags,
385
471
ATTR_TYPE_END) != 0
386
472
|| vstream_fflush(stream)
387
473
|| attr_scan(stream, ATTR_FLAG_STRICT,