/* $NetBSD: flush_clnt.c,v 1.3 2022/10/08 16:12:45 christos Exp $ */
/*++
/* NAME
/* flush_clnt 3
/* SUMMARY
/* fast flush cache manager client interface
/* SYNOPSIS
/* #include <flush_clnt.h>
/*
/* void flush_init()
/*
/* int flush_add(site, queue_id)
/* const char *site;
/* const char *queue_id;
/*
/* int flush_send_site(site)
/* const char *site;
/*
/* int flush_send_file(queue_id)
/* const char *queue_id;
/*
/* int flush_refresh()
/*
/* int flush_purge()
/* DESCRIPTION
/* The following routines operate through the "fast flush" service.
/* This service maintains a cache of what mail is queued. The cache
/* is maintained for eligible destinations. A destination is the
/* right-hand side of a user@domain email address.
/*
/* flush_init() initializes. It must be called before dropping
/* privileges in a daemon process.
/*
/* flush_add() informs the "fast flush" cache manager that mail is
/* queued for the specified site with the specified queue ID.
/*
/* flush_send_site() requests delivery of all mail that is queued for
/* the specified destination.
/*
/* flush_send_file() requests delivery of mail with the specified
/* queue ID.
/*
/* flush_refresh() requests the "fast flush" cache manager to refresh
/* cached information that was not used for some configurable amount
/* time.
/*
/* flush_purge() requests the "fast flush" cache manager to refresh
/* all cached information. This is incredibly expensive, and is not
/* recommended.
/* DIAGNOSTICS
/* The result codes and their meanings are (see flush_clnt(5h)):
/* .IP MAIL_FLUSH_OK
/* The request completed successfully (in case of requests that
/* complete in the background: the request was accepted by the server).
/* .IP MAIL_FLUSH_FAIL
/* The request failed (the request could not be sent to the server,
/* or the server reported failure).
/* .IP MAIL_FLUSH_BAD
/* The "fast flush" server rejected the request (invalid request
/* parameter).
/* .IP MAIL_FLUSH_DENY
/* The specified domain is not eligible for "fast flush" service,
/* or the "fast flush" service is disabled.
/* SEE ALSO
/* flush(8) Postfix fast flush cache manager
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
/* Wietse Venema
/* Google, Inc.
/* 111 8th Avenue
/* New York, NY 10011, USA
/*--*/
/* System library. */
#include "sys_defs.h"
#include <unistd.h>
#include <stdarg.h>
/* Utility library. */
#include <msg.h>
#include <vstream.h>
/* Global library. */
#include <mail_proto.h>
#include <mail_flush.h>
#include <mail_params.h>
#include <domain_list.h>
#include <match_parent_style.h>
#include <flush_clnt.h>
/* Application-specific. */
#define STR(x) vstring_str(x)
static DOMAIN_LIST *flush_domains;
/* flush_init - initialize */
void flush_init(void)
{
flush_domains = domain_list_init(VAR_FFLUSH_DOMAINS, MATCH_FLAG_RETURN
| match_parent_style(VAR_FFLUSH_DOMAINS),
var_fflush_domains);
}
/* flush_purge - house keeping */
int flush_purge(void)
{
const char *myname = "flush_purge";
int status;
if (msg_verbose)
msg_info("%s", myname);
/*
* Don't bother the server if the service is turned off.
*/
if (*var_fflush_domains == 0)
status = FLUSH_STAT_DENY;
else
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
MAIL_ATTR_PROTO_FLUSH,
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_PURGE),
ATTR_TYPE_END);
if (msg_verbose)
msg_info("%s: status %d", myname, status);
return (status);
}
/* flush_refresh - house keeping */
int flush_refresh(void)
{
const char *myname = "flush_refresh";
int status;
if (msg_verbose)
msg_info("%s", myname);
/*
* Don't bother the server if the service is turned off.
*/
if (*var_fflush_domains == 0)
status = FLUSH_STAT_DENY;
else
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
MAIL_ATTR_PROTO_FLUSH,
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_REFRESH),
ATTR_TYPE_END);
if (msg_verbose)
msg_info("%s: status %d", myname, status);
return (status);
}
/* flush_send_site - deliver mail queued for site */
int flush_send_site(const char *site)
{
const char *myname = "flush_send_site";
int status;
if (msg_verbose)
msg_info("%s: site %s", myname, site);
/*
* Don't bother the server if the service is turned off, or if the site
* is not eligible.
*/
if (flush_domains == 0)
msg_panic("missing flush client initialization");
if (domain_list_match(flush_domains, site) != 0) {
if (warn_compat_break_flush_domains)
msg_info("using backwards-compatible default setting "
VAR_RELAY_DOMAINS "=$mydestination to flush "
"mail for domain \"%s\"", site);
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
MAIL_ATTR_PROTO_FLUSH,
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_SEND_SITE),
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
ATTR_TYPE_END);
} else if (flush_domains->error == 0)
status = FLUSH_STAT_DENY;
else
status = FLUSH_STAT_FAIL;
if (msg_verbose)
msg_info("%s: site %s status %d", myname, site, status);
return (status);
}
/* flush_send_file - deliver specific message */
int flush_send_file(const char *queue_id)
{
const char *myname = "flush_send_file";
int status;
if (msg_verbose)
msg_info("%s: queue_id %s", myname, queue_id);
/*
* Require that the service is turned on.
*/
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
MAIL_ATTR_PROTO_FLUSH,
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_SEND_FILE),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
ATTR_TYPE_END);
if (msg_verbose)
msg_info("%s: queue_id %s status %d", myname, queue_id, status);
return (status);
}
/* flush_add - inform "fast flush" cache manager */
int flush_add(const char *site, const char *queue_id)
{
const char *myname = "flush_add";
int status;
if (msg_verbose)
msg_info("%s: site %s id %s", myname, site, queue_id);
/*
* Don't bother the server if the service is turned off, or if the site
* is not eligible.
*/
if (flush_domains == 0)
msg_panic("missing flush client initialization");
if (domain_list_match(flush_domains, site) != 0) {
if (warn_compat_break_flush_domains)
msg_info("using backwards-compatible default setting "
VAR_RELAY_DOMAINS "=$mydestination to update "
"fast-flush logfile for domain \"%s\"", site);
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
MAIL_ATTR_PROTO_FLUSH,
SEND_ATTR_STR(MAIL_ATTR_REQ, FLUSH_REQ_ADD),
SEND_ATTR_STR(MAIL_ATTR_SITE, site),
SEND_ATTR_STR(MAIL_ATTR_QUEUEID, queue_id),
ATTR_TYPE_END);
} else if (flush_domains->error == 0)
status = FLUSH_STAT_DENY;
else
status = FLUSH_STAT_FAIL;
if (msg_verbose)
msg_info("%s: site %s id %s status %d", myname, site, queue_id,
status);
return (status);
}