- va_list args;
- const query_t* query = pcy->data;
-
- buffer_addstr(&pcy->obuf, "action=");
- va_start(args, fmt);
- buffer_addvf(&pcy->obuf, fmt, args);
- va_end(args);
- buffer_addstr(&pcy->obuf, "\n\n");
- buffer_consume(&pcy->ibuf, query->eoq - pcy->ibuf.data);
- epoll_modify(pcy->fd, EPOLLIN | EPOLLOUT, pcy);
+ query_context_t *context = client_data(pcy);
+ const query_t* query = &context->query;
+ buffer_t *buf = client_output_buffer(pcy);
+
+ /* Write reply "action=ACTION [text]" */
+ buffer_addstr(buf, "action=");
+ if (!query_format_buffer(buf, message, query)) {
+ buffer_addstr(buf, message);
+ }
+ buffer_addstr(buf, "\n\n");
+
+ /* Finalize query. */
+ buf = client_input_buffer(pcy);
+ buffer_consume(buf, query->eoq - buf->data);
+ client_io_rw(pcy);
+}
+
+static const filter_t *next_filter(client_t *pcy, const filter_t *filter,
+ const query_t *query, const filter_hook_t *hook, bool *ok) {
+ char log_prefix[BUFSIZ];
+ log_prefix[0] = '\0';
+
+#define log_reply(Level, Msg, ...) \
+ if (log_level >= LOG_ ## Level) { \
+ if (log_prefix[0] == '\0') { \
+ query_format(log_prefix, BUFSIZ, \
+ config->log_format && config->log_format[0] ? \
+ config->log_format : DEFAULT_LOG_FORMAT, query); \
+ } \
+ __log(LOG_ ## Level, "%s: " Msg, log_prefix, ##__VA_ARGS__); \
+ }
+
+ if (hook != NULL) {
+ query_context_t *context = client_data(pcy);
+ if (hook->counter >= 0 && hook->counter < MAX_COUNTERS && hook->cost > 0) {
+ context->context.counters[hook->counter] += hook->cost;
+ log_reply(DEBUG, "added %d to counter %d (now %u)",
+ hook->cost, hook->counter,
+ context->context.counters[hook->counter]);
+ }
+ }
+ if (hook == NULL) {
+ log_reply(WARNING, "aborted");
+ *ok = false;
+ return NULL;
+ } else if (hook->async) {
+ log_reply(WARNING, "asynchronous filter from filter %s", filter->name);
+ *ok = true;
+ return NULL;
+ } else if (hook->postfix) {
+ log_reply(INFO, "answer %s from filter %s: \"%s\"",
+ htokens[hook->type], filter->name, hook->value);
+ policy_answer(pcy, hook->value);
+ *ok = true;
+ return NULL;
+ } else {
+ log_reply(DEBUG, "answer %s from filter %s: next filter %s",
+ htokens[hook->type], filter->name,
+ (array_ptr(config->filters, hook->filter_id))->name);
+ return array_ptr(config->filters, hook->filter_id);
+ }
+#undef log_reply