コード例 #1
0
static void qmqpd_reply(QMQPD_STATE *state, int log_message,
			        int status_code, const char *fmt,...)
{
    va_list ap;

    /*
     * Optionally change hard errors into retryable ones. Send the reply and
     * optionally log it. Always insert a delay before reporting a problem.
     * This slows down software run-away conditions.
     */
    if (status_code == QMQPD_STAT_HARD && var_soft_bounce)
	status_code = QMQPD_STAT_RETRY;
    VSTRING_RESET(state->buf);
    VSTRING_ADDCH(state->buf, status_code);
    va_start(ap, fmt);
    vstring_vsprintf_append(state->buf, fmt, ap);
    va_end(ap);
    NETSTRING_PUT_BUF(state->client, state->buf);
    if (log_message)
	(status_code == QMQPD_STAT_OK ? msg_info : msg_warn) ("%s: %s: %s",
		      state->queue_id, state->namaddr, STR(state->buf) + 1);
    if (status_code != QMQPD_STAT_OK)
	sleep(var_qmqpd_err_sleep);
    netstring_fflush(state->client);
}
コード例 #2
0
ファイル: qmqp-sink.c プロジェクト: DabeDotCom/postfix
static void send_reply(SINK_STATE *state)
{
    vstring_sprintf(buffer, "%c*k", QMQP_STAT_OK);
    NETSTRING_PUT_BUF(state->stream, buffer);
    netstring_fflush(state->stream);
    if (count_deliveries) {
	counter++;
	vstream_printf("%d\r", counter);
	vstream_fflush(VSTREAM_OUT);
    }
    disconnect(state);
}
コード例 #3
0
ファイル: dict_sockmap.c プロジェクト: aosm/postfix
static const char *dict_sockmap_lookup(DICT *dict, const char *key)
{
    const char *myname = "dict_sockmap_lookup";
    DICT_SOCKMAP *dp = (DICT_SOCKMAP *) dict;
    AUTO_CLNT *sockmap_clnt = DICT_SOCKMAP_RH_HANDLE(dp->client_info);
    VSTREAM *fp;
    int     netstring_err;
    char   *reply_payload;
    int     except_count;
    const char *error_class;

    if (msg_verbose)
	msg_info("%s: key %s", myname, key);

    /*
     * Optionally fold the key.
     */
    if (dict->flags & DICT_FLAG_FOLD_MUL) {
	if (dict->fold_buf == 0)
	    dict->fold_buf = vstring_alloc(100);
	vstring_strcpy(dict->fold_buf, key);
	key = lowercase(STR(dict->fold_buf));
    }

    /*
     * We retry connection-level errors once, to make server restarts
     * transparent.
     */
    for (except_count = 0; /* see below */ ; except_count++) {

	/*
	 * Look up the stream.
	 */
	if ((fp = auto_clnt_access(sockmap_clnt)) == 0) {
	    msg_warn("table %s:%s lookup error: %m", dict->type, dict->name);
	    dict->error = DICT_ERR_RETRY;
	    return (0);
	}

	/*
	 * Set up an exception handler.
	 */
	netstring_setup(fp, dict_sockmap_timeout);
	if ((netstring_err = vstream_setjmp(fp)) == 0) {

	    /*
	     * Send the query. This may raise an exception.
	     */
	    vstring_sprintf(dp->rdwr_buf, "%s %s", dp->sockmap_name, key);
	    NETSTRING_PUT_BUF(fp, dp->rdwr_buf);

	    /*
	     * Receive the response. This may raise an exception.
	     */
	    netstring_get(fp, dp->rdwr_buf, dict_sockmap_max_reply);

	    /*
	     * If we got here, then no exception was raised.
	     */
	    break;
	}

	/*
	 * Handle exceptions.
	 */
	else {

	    /*
	     * We retry a broken connection only once.
	     */
	    if (except_count == 0 && netstring_err == NETSTRING_ERR_EOF
		&& errno != ETIMEDOUT) {
		auto_clnt_recover(sockmap_clnt);
		continue;
	    }

	    /*
	     * We do not retry other errors.
	     */
	    else {
		msg_warn("table %s:%s lookup error: %s",
			 dict->type, dict->name,
			 netstring_strerror(netstring_err));
		dict->error = DICT_ERR_RETRY;
		return (0);
	    }
	}
    }

    /*
     * Parse the reply.
     */
    VSTRING_TERMINATE(dp->rdwr_buf);
    reply_payload = split_at(STR(dp->rdwr_buf), ' ');
    if (strcmp(STR(dp->rdwr_buf), DICT_SOCKMAP_PROT_OK) == 0) {
	dict->error = 0;
	return (reply_payload);
    } else if (strcmp(STR(dp->rdwr_buf), DICT_SOCKMAP_PROT_NOTFOUND) == 0) {
	dict->error = 0;
	return (0);
    }
    /* We got no definitive reply. */
    if (strcmp(STR(dp->rdwr_buf), DICT_SOCKMAP_PROT_TEMP) == 0) {
	error_class = "temporary";
	dict->error = DICT_ERR_RETRY;
    } else if (strcmp(STR(dp->rdwr_buf), DICT_SOCKMAP_PROT_TIMEOUT) == 0) {
	error_class = "timeout";
	dict->error = DICT_ERR_RETRY;
    } else if (strcmp(STR(dp->rdwr_buf), DICT_SOCKMAP_PROT_PERM) == 0) {
	error_class = "permanent";
	dict->error = DICT_ERR_CONFIG;
    } else {
	error_class = "unknown";
	dict->error = DICT_ERR_RETRY;
    }
    while (reply_payload && ISSPACE(*reply_payload))
	reply_payload++;
    msg_warn("%s:%s socketmap server %s error%s%.200s",
	     dict->type, dict->name, error_class,
	     reply_payload && *reply_payload ? ": " : "",
	     reply_payload && *reply_payload ?
	     printable(reply_payload, '?') : "");
    return (0);
}