1/*++
2/* NAME
3/*	flush_clnt 3
4/* SUMMARY
5/*	fast flush cache manager client interface
6/* SYNOPSIS
7/*	#include <flush_clnt.h>
8/*
9/*	void	flush_init()
10/*
11/*	int	flush_add(site, queue_id)
12/*	const char *site;
13/*	const char *queue_id;
14/*
15/*	int	flush_send_site(site)
16/*	const char *site;
17/*
18/*	int	flush_send_file(queue_id)
19/*	const char *queue_id;
20/*
21/*	int	flush_refresh()
22/*
23/*	int	flush_purge()
24/* DESCRIPTION
25/*	The following routines operate through the "fast flush" service.
26/*	This service maintains a cache of what mail is queued. The cache
27/*	is maintained for eligible destinations. A destination is the
28/*	right-hand side of a user@domain email address.
29/*
30/*	flush_init() initializes. It must be called before dropping
31/*	privileges in a daemon process.
32/*
33/*	flush_add() informs the "fast flush" cache manager that mail is
34/*	queued for the specified site with the specified queue ID.
35/*
36/*	flush_send_site() requests delivery of all mail that is queued for
37/*	the specified destination.
38/*
39/*	flush_send_file() requests delivery of mail with the specified
40/*	queue ID.
41/*
42/*	flush_refresh() requests the "fast flush" cache manager to refresh
43/*	cached information that was not used for some configurable amount
44/*	time.
45/*
46/*	flush_purge() requests the "fast flush" cache manager to refresh
47/*	all cached information. This is incredibly expensive, and is not
48/*	recommended.
49/* DIAGNOSTICS
50/*	The result codes and their meanings are (see flush_clnt(5h)):
51/* .IP MAIL_FLUSH_OK
52/*	The request completed successfully (in case of requests that
53/*	complete in the background: the request was accepted by the server).
54/* .IP MAIL_FLUSH_FAIL
55/*	The request failed (the request could not be sent to the server,
56/*	or the server reported failure).
57/* .IP MAIL_FLUSH_BAD
58/*	The "fast flush" server rejected the request (invalid request
59/*	parameter).
60/* .IP MAIL_FLUSH_DENY
61/*	The specified domain is not eligible for "fast flush" service,
62/*	or the "fast flush" service is disabled.
63/* SEE ALSO
64/*	flush(8) Postfix fast flush cache manager
65/* LICENSE
66/* .ad
67/* .fi
68/*	The Secure Mailer license must be distributed with this software.
69/* AUTHOR(S)
70/*	Wietse Venema
71/*	IBM T.J. Watson Research
72/*	P.O. Box 704
73/*	Yorktown Heights, NY 10598, USA
74/*--*/
75
76/* System library. */
77
78#include "sys_defs.h"
79#include <unistd.h>
80#include <stdarg.h>
81
82/* Utility library. */
83
84#include <msg.h>
85#include <vstream.h>
86
87/* Global library. */
88
89#include <mail_proto.h>
90#include <mail_flush.h>
91#include <mail_params.h>
92#include <domain_list.h>
93#include <match_parent_style.h>
94#include <flush_clnt.h>
95
96/* Application-specific. */
97
98#define STR(x)	vstring_str(x)
99
100static DOMAIN_LIST *flush_domains;
101
102/* flush_init - initialize */
103
104void    flush_init(void)
105{
106    flush_domains = domain_list_init(MATCH_FLAG_RETURN
107				   | match_parent_style(VAR_FFLUSH_DOMAINS),
108				     var_fflush_domains);
109}
110
111/* flush_purge - house keeping */
112
113int     flush_purge(void)
114{
115    const char *myname = "flush_purge";
116    int     status;
117
118    if (msg_verbose)
119	msg_info("%s", myname);
120
121    /*
122     * Don't bother the server if the service is turned off.
123     */
124    if (*var_fflush_domains == 0)
125	status = FLUSH_STAT_DENY;
126    else
127	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
128			      ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_PURGE,
129				     ATTR_TYPE_END);
130
131    if (msg_verbose)
132	msg_info("%s: status %d", myname, status);
133
134    return (status);
135}
136
137/* flush_refresh - house keeping */
138
139int     flush_refresh(void)
140{
141    const char *myname = "flush_refresh";
142    int     status;
143
144    if (msg_verbose)
145	msg_info("%s", myname);
146
147    /*
148     * Don't bother the server if the service is turned off.
149     */
150    if (*var_fflush_domains == 0)
151	status = FLUSH_STAT_DENY;
152    else
153	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
154			    ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_REFRESH,
155				     ATTR_TYPE_END);
156
157    if (msg_verbose)
158	msg_info("%s: status %d", myname, status);
159
160    return (status);
161}
162
163/* flush_send_site - deliver mail queued for site */
164
165int     flush_send_site(const char *site)
166{
167    const char *myname = "flush_send_site";
168    int     status;
169
170    if (msg_verbose)
171	msg_info("%s: site %s", myname, site);
172
173    /*
174     * Don't bother the server if the service is turned off, or if the site
175     * is not eligible.
176     */
177    if (flush_domains == 0)
178	msg_panic("missing flush client initialization");
179    if (domain_list_match(flush_domains, site) != 0)
180	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
181			  ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_SEND_SITE,
182				     ATTR_TYPE_STR, MAIL_ATTR_SITE, site,
183				     ATTR_TYPE_END);
184    else if (flush_domains->error == 0)
185	status = FLUSH_STAT_DENY;
186    else
187	status = FLUSH_STAT_FAIL;
188
189    if (msg_verbose)
190	msg_info("%s: site %s status %d", myname, site, status);
191
192    return (status);
193}
194
195/* flush_send_file - deliver specific message */
196
197int     flush_send_file(const char *queue_id)
198{
199    const char *myname = "flush_send_file";
200    int     status;
201
202    if (msg_verbose)
203	msg_info("%s: queue_id %s", myname, queue_id);
204
205    /*
206     * Require that the service is turned on.
207     */
208    status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
209			  ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_SEND_FILE,
210				 ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
211				 ATTR_TYPE_END);
212
213    if (msg_verbose)
214	msg_info("%s: queue_id %s status %d", myname, queue_id, status);
215
216    return (status);
217}
218
219/* flush_add - inform "fast flush" cache manager */
220
221int     flush_add(const char *site, const char *queue_id)
222{
223    const char *myname = "flush_add";
224    int     status;
225
226    if (msg_verbose)
227	msg_info("%s: site %s id %s", myname, site, queue_id);
228
229    /*
230     * Don't bother the server if the service is turned off, or if the site
231     * is not eligible.
232     */
233    if (flush_domains == 0)
234	msg_panic("missing flush client initialization");
235    if (domain_list_match(flush_domains, site) != 0)
236	status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
237				ATTR_TYPE_STR, MAIL_ATTR_REQ, FLUSH_REQ_ADD,
238				     ATTR_TYPE_STR, MAIL_ATTR_SITE, site,
239				 ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
240				     ATTR_TYPE_END);
241    else if (flush_domains->error == 0)
242	status = FLUSH_STAT_DENY;
243    else
244	status = FLUSH_STAT_FAIL;
245
246    if (msg_verbose)
247	msg_info("%s: site %s id %s status %d", myname, site, queue_id,
248		 status);
249
250    return (status);
251}
252