}
static void
-auth_penalty_anvil_callback(const char *reply,
+auth_penalty_anvil_callback(const struct anvil_reply *reply,
struct auth_penalty_request *request)
{
unsigned int penalty = 0;
unsigned long last_penalty = 0;
unsigned int secs, drop_penalty;
- if (reply == NULL) {
+ if (reply->error != NULL) {
/* internal failure. */
if (!anvil_client_is_connected(request->client)) {
/* we probably didn't have permissions to reconnect
back to anvil. need to restart ourself. */
master_service_stop(master_service);
}
- } else if (sscanf(reply, "%u %lu", &penalty, &last_penalty) != 2) {
+ } else if (sscanf(reply->reply, "%u %lu", &penalty, &last_penalty) != 2) {
e_error(request->auth_request->event,
- "Invalid PENALTY-GET reply: %s", reply);
+ "Invalid PENALTY-GET reply: %s", reply->reply);
} else {
if ((time_t)last_penalty > ioloop_time) {
/* time moved backwards? */
};
static void
-kick_user_anvil_callback(const char *reply, struct kick_context *ctx)
+kick_user_anvil_callback(const struct anvil_reply *reply,
+ struct kick_context *ctx)
{
unsigned int count;
- if (reply != NULL) {
- if (str_to_uint(reply, &count) < 0)
+ if (reply->error == NULL) {
+ if (str_to_uint(reply->reply, &count) < 0)
e_error(ctx->event,
- "Unexpected reply from anvil: %s", reply);
+ "Unexpected reply from anvil: %s", reply->reply);
else
ctx->kicked_count += count;
}
queries = array_get(&client->queries_arr, &count);
query = queries[aqueue_idx(client->queries, 0)];
if (query->callback != NULL) T_BEGIN {
- query->callback(line, query->context);
+ struct anvil_reply reply = { .reply = line };
+ query->callback(&reply, query->context);
} T_END;
anvil_query_free(&query);
aqueue_delete_tail(client->queries);
return 0;
}
-static void anvil_client_cancel_queries(struct anvil_client *client)
+static void
+anvil_client_cancel_queries(struct anvil_client *client)
{
struct anvil_query *const *queries, *query;
unsigned int count;
queries = array_get(&client->queries_arr, &count);
while (aqueue_count(client->queries) > 0) {
query = queries[aqueue_idx(client->queries, 0)];
- if (query->callback != NULL)
- query->callback(NULL, query->context);
+ if (query->callback != NULL) {
+ struct anvil_reply reply = { .error = "Failed" };
+ query->callback(&reply, query->context);
+ }
anvil_query_free(&query);
aqueue_delete_tail(client->queries);
}
bool (*command)(const char *cmd, const char *const *args);
};
-/* reply=NULL if query failed */
-typedef void anvil_callback_t(const char *reply, void *context);
+struct anvil_reply {
+ /* non-NULL if query failed */
+ const char *error;
+ /* non-NULL if query succeeded */
+ const char *reply;
+};
+
+typedef void anvil_callback_t(const struct anvil_reply *reply, void *context);
/* If reconnect_callback is specified, it's called when connection is lost.
If the callback returns FALSE, reconnection isn't attempted. */
anvil_client_query(client, query, timeout_msecs, \
(anvil_callback_t *)(callback), 1 ? (context) : \
CALLBACK_TYPECHECK(callback, \
- void (*)(const char *, typeof(context))))
+ void (*)(const struct anvil_reply *, typeof(context))))
void anvil_client_query_abort(struct anvil_client *client,
struct anvil_query **query);
/* Send a command to anvil, don't expect any replies. */
}
static void
-lmtp_local_rcpt_anvil_cb(const char *reply, struct lmtp_local_recipient *llrcpt)
+lmtp_local_rcpt_anvil_cb(const struct anvil_reply *reply,
+ struct lmtp_local_recipient *llrcpt)
{
struct client *client = llrcpt->rcpt->client;
struct smtp_server_recipient *rcpt = llrcpt->rcpt->rcpt;
unsigned int parallel_count = 0;
llrcpt->anvil_query = NULL;
- if (reply == NULL) {
+ if (reply->error != NULL) {
/* lookup failed */
- } else if (str_to_uint(reply, ¶llel_count) < 0) {
- e_error(rcpt->event, "Invalid reply from anvil: %s", reply);
+ } else if (str_to_uint(reply->reply, ¶llel_count) < 0) {
+ e_error(rcpt->event, "Invalid reply from anvil: %s",
+ reply->reply);
}
if (parallel_count >= client->lmtp_set->lmtp_user_concurrency_limit) {
}
static void ATTR_NULL(1)
-anvil_lookup_callback(const char *reply, struct anvil_request *req)
+anvil_lookup_callback(const struct anvil_reply *reply,
+ struct anvil_request *req)
{
struct client *client = req->client;
const struct login_settings *set = client->set;
client->anvil_request = NULL;
conn_count = 0;
- if (reply != NULL && str_to_uint(reply, &conn_count) < 0)
- i_fatal("Received invalid reply from anvil: %s", reply);
+ if (reply != NULL && reply->error == NULL &&
+ str_to_uint(reply->reply, &conn_count) < 0)
+ i_fatal("Received invalid reply from anvil: %s", reply->reply);
/* reply=NULL if we didn't need to do anvil lookup,
- or if the anvil lookup failed. allow failed anvil lookups in. */
- if (reply == NULL || conn_count < set->mail_max_userip_connections) {
+ reply->error != NULL if the anvil lookup failed.
+ Allow failed anvil lookups in. */
+ if (reply == NULL || reply->error != NULL ||
+ conn_count < set->mail_max_userip_connections) {
if (master_send_request(req) < 0)
sasl_reply = SASL_SERVER_REPLY_MASTER_FAILED;
errmsg = NULL; /* client will see internal error */