Exemple #1
0
static void verify_clnt_init(void)
{
    if (vrfy_clnt != 0)
	msg_panic("verify_clnt_init: multiple initialization");
    vrfy_clnt = clnt_stream_create(MAIL_CLASS_PRIVATE, var_verify_service,
				   var_ipc_idle_limit, var_ipc_ttl_limit);
}
Exemple #2
0
VSTRING *rewrite_clnt(const char *rule, const char *addr, VSTRING *result)
{
    VSTREAM *stream;
    int     server_flags;
    int     count = 0;

    /*
     * One-entry cache.
     */
    if (last_addr == 0) {
	last_rule = vstring_alloc(10);
	last_addr = vstring_alloc(100);
	last_result = vstring_alloc(100);
    }

    /*
     * Sanity check. An address must be in externalized form. The result must
     * not clobber the input, because we may have to retransmit the query.
     */
#define STR vstring_str

    if (*addr == 0)
	addr = "";
    if (addr == STR(result))
	msg_panic("rewrite_clnt: result clobbers input");

    /*
     * Peek at the cache.
     */
    if (time((time_t *) 0) < last_expire
	&& strcmp(addr, STR(last_addr)) == 0
	&& strcmp(rule, STR(last_rule)) == 0) {
	vstring_strcpy(result, STR(last_result));
	if (msg_verbose)
	    msg_info("rewrite_clnt: cached: %s: %s -> %s",
		     rule, addr, vstring_str(result));
	return (result);
    }

    /*
     * Keep trying until we get a complete response. The rewrite service is
     * CPU bound and making the client asynchronous would just complicate the
     * code.
     */
    if (rewrite_clnt_stream == 0)
	rewrite_clnt_stream = clnt_stream_create(MAIL_CLASS_PRIVATE,
						 var_rewrite_service,
						 var_ipc_idle_limit,
						 var_ipc_ttl_limit);

    for (;;) {
	stream = clnt_stream_access(rewrite_clnt_stream);
	errno = 0;
	count += 1;
	if (attr_print(stream, ATTR_FLAG_NONE,
		       ATTR_TYPE_STR, MAIL_ATTR_REQ, REWRITE_ADDR,
		       ATTR_TYPE_STR, MAIL_ATTR_RULE, rule,
		       ATTR_TYPE_STR, MAIL_ATTR_ADDR, addr,
		       ATTR_TYPE_END) != 0
	    || vstream_fflush(stream)
	    || attr_scan(stream, ATTR_FLAG_STRICT,
			 ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &server_flags,
			 ATTR_TYPE_STR, MAIL_ATTR_ADDR, result,
			 ATTR_TYPE_END) != 2) {
	    if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
		msg_warn("problem talking to service %s: %m",
			 var_rewrite_service);
	} else {
	    if (msg_verbose)
		msg_info("rewrite_clnt: %s: %s -> %s",
			 rule, addr, vstring_str(result));
	    /* Server-requested disconnect. */
	    if (server_flags != 0)
		clnt_stream_recover(rewrite_clnt_stream);
	    break;
	}
	sleep(1);				/* XXX make configurable */
	clnt_stream_recover(rewrite_clnt_stream);
    }

    /*
     * Update the cache.
     */
    vstring_strcpy(last_rule, rule);
    vstring_strcpy(last_addr, addr);
    vstring_strcpy(last_result, STR(result));
    last_expire = time((time_t *) 0) + 30;	/* XXX make configurable */

    return (result);
}