used by the Postfix SMTP server. Liviu Daia. Files:
mail_params.h, smtpd.c, smtpd_sasl_glue.c.
- Cleanup: shared config file parser for ldap, mysql, pgsql
- lookup tables. Liviu Daia. Files: global/cfgparser.[hc],
- global/dict_ldap.c, global/dict_mtsql.c, global/dict_pgsql.c
- and documentation.
+ Cleanup: the LDAP client configuration parser is now shared
+ between the LDAP, MySQL, and PGSQL clients. Liviu Daia.
+ Files: global/cfgparser.[hc], global/dict_ldap.c,
+ global/dict_mtsql.c, global/dict_pgsql.c and documentation.
- Cleanup: moved modules with dependencies on higher-level
- code from the util directory to the global directory:
+ Cleanup: moved "util" modules with dependencies on higher-level
+ "global" code from the util directory to the global directory:
util/dict_open.c, global/cfgparser.[hc], global/dict_ldap.c,
global/dict_mtsql.c, global/dict_pgsql.c, global/mail_dict.c.
character stored. This avoids mis-leading warnings. File:
global/vstring_vstream.c.
+20040105
+
+ Cleanup: don't bother the flush daemon while deferring mail
+ if the destination is not "fast flush" eligible. File:
+ global/flush_clnt.c.
+
+ Safety: the SMTP server flushes recipients to the cleanup
+ server in order to avoid SMTP timeouts when virtual or
+ canonical expansions take a lot of time. File smtpd/smtpd.c.
+
+ Safety: add warnings to postmap and postalias when table
+ lookup results in an empty string.
+
Open problems:
Low: in the SMTP client, pass the session, request and
stay in the content filtering loop.
The "-o receive_override_options" overrides main.cf. It is
-complementary to the the options that are specified in main.cf:
+complementary to the options that are specified in main.cf:
- Disable attempts to find out if a recipient is unknown, and
disable header/body checks. This work was already done before
and adapted to snapshot 20001121 by Xavier Beaudouin. It was merged
with mainstream Postfix for snapshot 20010128 by Wietse.
+See the VIRTUAL_README file for an overview of how you can host
+multiple domains with one Postfix system.
+
Purpose of this software
========================
-Porpose of this document
+Purpose of this document
========================
-Hosting multiple domains on one server
+This document describes how to configure one Postfix system for
+final mail delivery of multiple Internet domains, using the mailbox
+and maildir delivery mechanisms that are already built into Postfix.
+See the LMTP_README file for an example of final delivery with
+third-party mailstores such as Cyrus.
-UNIX system accounts, domain shared with all users
-==================================================
+Preliminaries: local files versus databases
+===========================================
-UNIX system accounts, domains not shared
-========================================
+The examples in this text use table lookups from local files.
+These are easy to debug with the postmap "-q" command option.
-Non-UNIX accounts, domains not shared
-=====================================
+Example: postmap -q info@example.com hash:/etc/postfix/virtual
+
+See LDAP_README, MYSQL_README and PGSQL_README for how to replace
+local files by databases. The reader is strongly advised to make
+the system work with local files before migrating to database files,
+and to use the postmap "-q" command option to verify that database
+lookups produce the exact same results as local file lookup.
+
+Example: postmap -q info@example.com:ldap:/etc/postfix/virtual.cf
+
+Preliminaries: canonical versus virtual domains
+===============================================
+
+Each Postfix system does final delivery for a small number of
+canonical domains; usually these are the names of the machine that
+Postfix runs on. Sometimes the list of canonical domains also
+includes the parent domain of the machine name.
+
+Postfix can be configured to do final delivery for additional
+domains. The domains are called virtual, because they are not
+associated with the name of the machine itself.
+
+Postfix understands two types of virtual domain:
+
+- The virtual alias domain, where each virtual address is aliased
+ to a different (remote or local) address.
+
+- The virtual mailbox domain, where each virtual address can have
+ its own mailbox.
+
+A third type, the "sendmail style virtual domain" was described
+with older Postfix versions. It will not be discussed here in order
+to avoid a lot of confusion.
+
+Shared domains, UNIX system accounts
+====================================
+
+The simplest method to host an additional domain is to specify the
+user names in the UNIX password file and to specify the domain name
+in the Postfix mydestination configuration parameter.
+
+In the examples we will use "example.com" as the domain that is
+being hosted on the local Postfix machine.
+
+/etc/postfix/main.cf:
+ mydestination = $myhostname localhost.$mydomain ... example.com
+
+The downside of this approach is a total lack of separation: mail
+for info@my.host.name is delivered to the same UNIX system account
+as mail for info@example.com. If different domains need to have
+different "info" mailboxes, then you can use one of the methods
+described in the remainder of this document.
+
+Another downside of listing all users in the UNIX password file is
+that administration of large numbers of users becomes inconvenient.
+
+Virtual ALIAS domains: separate domains, UNIX system accounts
+=============================================================
+
+The simplest method to host separate domains is to create so-called
+virtual aliases that redirect mail from each virtual address to
+its own UNIX account.
+
+The example below shows how to set up the example.com domain
+as a so-called virtual alias domain:
+
+/etc/postfix/main.cf:
+ virtual_alias_domains = example.com ...other domains...
+ virtual_alias_maps = hash:/etc/postfix/virtual
+
+/etc/postfix/virtual:
+ postmaster@example.com postmaster
+ info@example.com joe
+ sales@example.com jane
+ # Uncomment entry below to implement a catch-all address
+ # @example.com jim
+ ...virtual aliases for other domains...
+
+The virtual_alias_domains setting tells Postfix that example.com
+is a so-called virtual alias domain. If you omit this step then
+Postfix will either reject mail (relay access denied) or will not
+be able to deliver it (mail for example.com loops back to myself).
+
+The /etc/postfix/virtual file contains the virtual aliases. With
+the example above, mail for postmaster@example.com goes to the
+local postmaster, while mail for info@example.com goes to the UNIX
+account joe, and mail for sales@example.com goes to the UNIX account
+jane. Mail for all other addresses in example.com is rejected with
+the error message "User unknown".
+
+The commented out entry (text after #) shows how one would implement
+a catch-all virtual alias that receives mail for every example.com
+address not listed in the virtual alias file. This is not without
+risk. Spammers nowadays try to send mail from (or mail to) every
+possible name that they can think of. A catch-all mailbox is likely
+to receive many spam messages, and many bounces for spam messages
+that were sent in the name of anything@example.com.
+
+Execute the command "postmap /etc/postfix/virtual" after changing
+the virtual file, and execute the command "postfix reload" after
+changing the main.cf file.
+
+Note: virtual aliases can resolve to a local address or to a remote
+address, or both. They don't have to resolve to UNIX system accounts
+on your machine.
+
+More details about the virtual alias file are given in the virtual(5)
+manual page, including multiple addresses on the right-hand side.
+
+Virtual aliasing solves one problem: it allows each domain to have
+its own info mail address. Virtual aliasing to UNIX system accounts
+still has the drawback that every user has to be listed in the UNIX
+password file. The next section eliminates this problem.
+
+Virtual MAILBOX domains: separate domains, non-UNIX accounts
+============================================================
+
+As a system hosts more and more domains and users, it becomes
+unpractical to give everyone their own UNIX system account.
+
+With the Postfix virtual delivery agent, every recipient address
+can have its own virtual mailbox. Unlike virtual alias domains,
+there is no translation from recipient addresses into different
+addresses.
+
+The Postfix virtual delivery agent looks up the user mailbox
+pathname, uid and gid via separate tables that are searched with
+the recipient's mail address. Maildir style delivery is turned on
+by terminating the mailbox pathname with "/".
+
+Here is an example of a virtual mailbox domain example.com:
+
+/etc/postfix/main.cf:
+ virtual_mailbox_base = /var/mail/vhosts
+ virtual_mailbox_maps = hash:/etc/postfix/vmailbox
+ virtual_mailbox_domains = example.com ...other domains...
+ virtual_minimum_uid = 100
+ virtual_uid_maps = static:5000
+ virtual_gid_maps = static:5000
+ virtual_alias_maps = hash:/etc/postfix/virtual
+
+/etc/postfix/vmailbox:
+ info@example.com example.com/info
+ sales@example.com example.com/sales/
+ # Comment out the entry below to implement a catch-all.
+ # @example.com example.com/catchall
+ ...virtual mailboxes for other domains...
+
+/etc/postfix/virtual:
+ postmaster@example.com postmaster
+
+The virtual_mailbox_base parameter specifies a prefix for all
+virtual mailbox pathnames. This is a safety mechanism that prevents
+mail from being delivered all over the file system.
+
+The virtual_mailbox_maps parameter specifies the lookup table with
+mailbox (or maildir) pathnames, indexed by the virtual mail address.
+In this example, mail for info@example.com goes to the mailbox at
+/var/mail/vhosts/example.com/info while mail for sales@example.com
+goes to the maildir located at /var/mail/vhosts/example.com/sales/.
+
+The virtual_minimum_uid prevents specifies a lower bound on the
+mailbox or maildir owner's UID. This is a safety mechanism that
+prevents mail from being written to sensitive files.
+
+In the above example, the virtual_uid_maps and virtual_gid_maps
+parameters specify that all the virtual mailboxes are owned by a
+fixed uid and gid 5000. If this is not what you want, specify
+lookup tables that are searched by the recipient's mail address.
+
+The commented out entry (text after #) shows how one would implement
+a catch-all virtual mailbox address. Be prepared to receive a lot
+of spam, as well as bounced spam that was sent in the name of
+anything@example.com.
+
+NEVER put a virtual MAILBOX wild-card in the virtual ALIAS file!!
+
+As you see above, it is possible to mix virtual aliases with virtual
+mailboxes. We use this feature to redirect mail for example.com's
+postmaster address to the local postmaster.
+
+Execute the command "postmap /etc/postfix/virtual" after changing
+the virtual file, execute "postmap /etc/postfix/vmailbox" after
+changing the vmailbox file, and execute the command "postfix reload"
+after changing the main.cf file.
+
+Note: mail delivery happens with the UID/GID privileges of the
+recipient. You must create maildirs in advance before you can use
+them. Depending on directory permissions, Postfix may be able to
+create mailbox files by itself, but it is safer to create them
+ahead of time.
+
+More details about the virtual mailbox delivery agent are given
+in the file VIRTUAL_MAILBOX_README, and in the virtual(8) manual
+page.
Aliases, mailing lists, etc.
============================
+
+The examples above already show how to direct mail for virtual
+postmaster addresses to a local postmaster. The same method can be
+used to direct mail for other virtual addresses to a local or remote
+address.
+
+Virtual aliases can't directly deliver to mailing list managers
+such as majordomo. One solution is to set up a transport mapping
+that directs the mail to the Postfix local delivery agent, and to
+use the local alias file for delivery to the mailing list manager:
+
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+
+/etc/postfix/transport:
+ listname-request@example.com local:
+ listname@example.com local:
+ owner-listname@example.com local:
+
+/etc/aliases:
+ listname: "|/some/where/majordomo/wrapper ..."
+ owner-listname: ...
+ listname-request: ...
+
+You can achieve the same result with virtual aliases that direct
+virtual addresses to the local delivery agent:
+
+/etc/postfix/main.cf:
+ virtual_alias_maps = hash:/etc/postfix/virtual
+
+/etc/postfix/virtual:
+ listname-request@example.com listname-request
+ listname@example.com listname
+ owner-listname@example.com owner-listname
+
+/etc/aliases:
+ listname: "|/some/where/majordomo/wrapper ..."
+ owner-listname: ...
+ listname-request: ...
+
+Either approach will do the job.
+
+More information about the Postfix local delivery agent can be
+found in the local(8) manual page.
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
POSTMAP(1) POSTMAP(1)
<b>NAME</b>
ARFL = $ARFL
RANLIB = $RANLIB
SYSLIBS = $AUXLIBS $SYSLIBS
-CC = $CC $CCARGS
+CC = $CC -DSNAPSHOT $CCARGS
OPT = $OPT
DEBUG = $DEBUG
AWK = $AWK
cleanup_init.o: ../../include/mail_addr.h
cleanup_init.o: ../../include/mail_params.h
cleanup_init.o: ../../include/ext_prop.h
+cleanup_init.o: ../../include/flush_clnt.h
cleanup_init.o: cleanup.h
cleanup_init.o: ../../include/vstring.h
cleanup_init.o: ../../include/vbuf.h
#include <mail_addr.h>
#include <mail_params.h>
#include <ext_prop.h>
+#include <flush_clnt.h>
/* Application-specific. */
cleanup_rcpt_bcc_maps =
maps_create(VAR_RCPT_BCC_MAPS, var_rcpt_bcc_maps,
DICT_FLAG_LOCK);
+
+ flush_init();
}
/* cleanup_post_jail - initialize after entering the chroot jail */
error.o: ../../include/mail_queue.h
error.o: ../../include/bounce.h
error.o: ../../include/deliver_completed.h
+error.o: ../../include/flush_clnt.h
error.o: ../../include/mail_server.h
#include <mail_queue.h>
#include <bounce.h>
#include <deliver_completed.h>
+#include <flush_clnt.h>
/* Single server skeleton. */
}
}
+/* pre_init - pre-jail initialization */
+
+static void pre_init(char *unused_name, char **unused_argv)
+{
+ flush_init();
+}
+
/* main - pass control to the single-threaded skeleton */
int main(int argc, char **argv)
{
- single_server_main(argc, argv, error_service, 0);
+ single_server_main(argc, argv, error_service,
+ MAIL_SERVER_PRE_INIT, pre_init,
+ 0);
}
/* SYNOPSIS
/* #include <flush_clnt.h>
/*
+/* void flush_init()
+/*
/* int flush_add(site, queue_id)
/* const char *site;
/* const char *queue_id;
/* 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.
/*
#include <mail_proto.h>
#include <mail_flush.h>
-#include <flush_clnt.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(match_parent_style(VAR_FFLUSH_DOMAINS),
+ var_fflush_domains);
+}
+
/* flush_purge - house keeping */
int flush_purge(void)
msg_info("%s: site %s", myname, site);
/*
- * Don't bother the server if the service is turned off.
+ * Don't bother the server if the service is turned off, or if the site
+ * is not eligible.
*/
- if (*var_fflush_domains == 0)
+ if (flush_domains == 0)
+ msg_panic("missing flush client initialization");
+ if (domain_list_match(flush_domains, site) == 0)
status = FLUSH_STAT_DENY;
else
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
msg_info("%s: site %s id %s", myname, site, queue_id);
/*
- * Don't bother the server if the service is turned off.
+ * Don't bother the server if the service is turned off, or if the site
+ * is not eligible.
*/
- if (*var_fflush_domains == 0)
+ if (flush_domains == 0)
+ msg_panic("missing flush client initialization");
+ if (domain_list_match(flush_domains, site) == 0)
status = FLUSH_STAT_DENY;
else
status = mail_command_client(MAIL_CLASS_PUBLIC, var_flush_service,
/*
* External interface.
*/
+extern void flush_init(void);
extern int flush_add(const char *, const char *);
extern int flush_send(const char *);
extern int flush_refresh(void);
* Patches change the patchlevel and the release date. Snapshots change the
* release date only, unless they include the same bugfix as a patch release.
*/
-#define MAIL_RELEASE_DATE "20040104"
+#define MAIL_RELEASE_DATE "20040105"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "2.0.16-" MAIL_RELEASE_DATE
lmtp.o: ../../include/mail_conf.h
lmtp.o: ../../include/debug_peer.h
lmtp.o: ../../include/mail_error.h
+lmtp.o: ../../include/flush_clnt.h
lmtp.o: ../../include/mail_server.h
lmtp.o: lmtp.h
lmtp.o: lmtp_sasl.h
#include <mail_conf.h>
#include <debug_peer.h>
#include <mail_error.h>
+#include <flush_clnt.h>
/* Single server skeleton. */
msg_warn("%s is true, but SASL support is not compiled in",
VAR_LMTP_SASL_ENABLE);
#endif
+
+ /*
+ * flush client.
+ */
+ flush_init();
}
/* cleanup - close any open connections, etc. */
local.o: ../../include/been_here.h
local.o: ../../include/ext_prop.h
local.o: ../../include/maps.h
+local.o: ../../include/flush_clnt.h
local.o: ../../include/mail_server.h
local.o: local.h
local.o: ../../include/tok822.h
#include <mail_params.h>
#include <ext_prop.h>
#include <maps.h>
+#include <flush_clnt.h>
/* Single server skeleton. */
}
alias_maps = maps_create("aliases", var_alias_maps,
DICT_FLAG_LOCK | DICT_FLAG_PARANOID);
+
+ flush_init();
}
/* main - pass control to the single-threaded skeleton */
qmgr.o: ../../include/iostuff.h
qmgr.o: ../../include/attr.h
qmgr.o: ../../include/mail_flow.h
+qmgr.o: ../../include/flush_clnt.h
qmgr.o: ../../include/master_proto.h
qmgr.o: ../../include/mail_server.h
qmgr.o: qmgr.h
#include <mail_params.h>
#include <mail_proto.h> /* QMGR_SCAN constants */
#include <mail_flow.h>
+#include <flush_clnt.h>
/* Master process interface */
}
}
+/* qmgr_pre_init - pre-jail initialization */
+
+static void qmgr_pre_init(char *unused_name, char **unused_argv)
+{
+ flush_init();
+}
+
/* qmgr_post_init - post-jail initialization */
static void qmgr_post_init(char *unused_name, char **unused_argv)
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_BOOL_TABLE, bool_table,
MAIL_SERVER_TIME_TABLE, time_table,
+ MAIL_SERVER_PRE_INIT, qmgr_pre_init,
MAIL_SERVER_POST_INIT, qmgr_post_init,
MAIL_SERVER_LOOP, qmgr_loop,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
pipe.o: ../../include/off_cvt.h
pipe.o: ../../include/quote_822_local.h
pipe.o: ../../include/quote_flags.h
+pipe.o: ../../include/flush_clnt.h
pipe.o: ../../include/mail_server.h
#include <split_addr.h>
#include <off_cvt.h>
#include <quote_822_local.h>
+#include <flush_clnt.h>
/* Single server skeleton. */
set_eugid(var_owner_uid, var_owner_gid);
}
+/* pre_init - initialize */
+
+static void pre_init(char *unused_name, char **unused_argv)
+{
+ flush_init();
+}
+
/* main - pass control to the single-threaded skeleton */
int main(int argc, char **argv)
single_server_main(argc, argv, pipe_service,
MAIL_SERVER_TIME_TABLE, time_table,
+ MAIL_SERVER_PRE_INIT, pre_init,
MAIL_SERVER_POST_INIT, drop_privileges,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
0);
dict_open3(maps[n], map_name, O_RDONLY, DICT_FLAG_LOCK) :
dict_open3(var_db_type, maps[n], O_RDONLY, DICT_FLAG_LOCK));
if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
+ if (*value == 0) {
+ msg_warn("table %s:%s: key %s: empty string result is not allowed",
+ dicts[n]->type, dicts[n]->name, STR(keybuf));
+ msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
+ dicts[n]->type, dicts[n]->name);
+ }
vstream_printf("%s: %s\n", STR(keybuf), value);
found = 1;
break;
dict = dict_open3(map_type, map_name, O_RDONLY, DICT_FLAG_LOCK);
if ((value = dict_get(dict, key)) != 0) {
+ if (*value == 0) {
+ msg_warn("table %s:%s: key %s: empty string result is not allowed",
+ map_type, map_name, key);
+ msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
+ map_type, map_name);
+ }
vstream_printf("%s\n", value);
vstream_fflush(VSTREAM_OUT);
}
dict_open3(maps[n], map_name, O_RDONLY, DICT_FLAG_LOCK) :
dict_open3(var_db_type, maps[n], O_RDONLY, DICT_FLAG_LOCK));
if ((value = dict_get(dicts[n], STR(keybuf))) != 0) {
+ if (*value == 0) {
+ msg_warn("table %s:%s: key %s: empty string result is not allowed",
+ dicts[n]->type, dicts[n]->name, STR(keybuf));
+ msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
+ dicts[n]->type, dicts[n]->name);
+ }
vstream_printf("%s %s\n", STR(keybuf), value);
found = 1;
break;
dict = dict_open3(map_type, map_name, O_RDONLY, DICT_FLAG_LOCK);
if ((value = dict_get(dict, key)) != 0) {
+ if (*value == 0) {
+ msg_warn("table %s:%s: key %s: empty string result is not allowed",
+ map_type, map_name, key);
+ msg_warn("table %s:%s should return NO RESULT in case of NOT FOUND",
+ map_type, map_name);
+ }
vstream_printf("%s\n", value);
vstream_fflush(VSTREAM_OUT);
}
qmgr.o: ../../include/iostuff.h
qmgr.o: ../../include/attr.h
qmgr.o: ../../include/mail_flow.h
+qmgr.o: ../../include/flush_clnt.h
qmgr.o: ../../include/master_proto.h
qmgr.o: ../../include/mail_server.h
qmgr.o: qmgr.h
#include <mail_params.h>
#include <mail_proto.h> /* QMGR_SCAN constants */
#include <mail_flow.h>
+#include <flush_clnt.h>
/* Master process interface */
}
}
+/* qmgr_pre_init - pre-jail initialization */
+
+static void qmgr_pre_init(char *unused_name, char **unused_argv)
+{
+ flush_init();
+}
+
/* qmgr_post_init - post-jail initialization */
static void qmgr_post_init(char *name, char **unused_argv)
MAIL_SERVER_STR_TABLE, str_table,
MAIL_SERVER_BOOL_TABLE, bool_table,
MAIL_SERVER_TIME_TABLE, time_table,
+ MAIL_SERVER_PRE_INIT, qmgr_pre_init,
MAIL_SERVER_POST_INIT, qmgr_post_init,
MAIL_SERVER_LOOP, qmgr_loop,
MAIL_SERVER_PRE_ACCEPT, pre_accept,
smtp.o: ../../include/mail_params.h
smtp.o: ../../include/mail_conf.h
smtp.o: ../../include/debug_peer.h
+smtp.o: ../../include/flush_clnt.h
smtp.o: ../../include/mail_server.h
smtp.o: smtp.h
smtp.o: smtp_sasl.h
#include <mail_params.h>
#include <mail_conf.h>
#include <debug_peer.h>
+#include <flush_clnt.h>
/* Single server skeleton. */
msg_warn("%s is true, but SASL support is not compiled in",
VAR_SMTP_SASL_ENABLE);
#endif
+
+ /*
+ * Flush client.
+ */
+ flush_init();
}
/* pre_accept - see if tables have changed */
#include <namadr_list.h>
#include <input_transp.h>
#include <anvil_clnt.h>
+#include <flush_clnt.h>
/* Single-threaded server skeleton. */
/*
* Store the recipient. Remember the first one.
+ *
+ * Flush recipients to maintain a stiffer coupling with the next stage and
+ * to better utilize parallelism.
*/
state->rcpt_count++;
if (state->recipient == 0)
state->recipient = mystrdup(argv[2].strval);
- if (state->cleanup)
+ if (state->cleanup) {
rec_fputs(state->cleanup, REC_TYPE_RCPT, argv[2].strval);
+ vstream_fflush(state->cleanup);
+ }
smtpd_chat_reply(state, "250 Ok");
return (0);
}
msg_warn("%s is true, but SASL support is not compiled in",
VAR_SMTPD_SASL_ENABLE);
#endif
+
+ /*
+ * flush client.
+ */
+ flush_init();
}
/* post_jail_init - post-jail initialization */
static DICT_OPEN_INFO dict_open_info[] = {
DICT_TYPE_ENVIRON, dict_env_open,
DICT_TYPE_UNIX, dict_unix_open,
+#ifdef SNAPSHOT
DICT_TYPE_TCP, dict_tcp_open,
+#endif
#ifdef HAS_DBM
DICT_TYPE_DBM, dict_dbm_open,
#endif
virtual.o: ../../include/mail_conf.h
virtual.o: ../../include/mail_addr_find.h
virtual.o: ../../include/maps.h
+virtual.o: ../../include/flush_clnt.h
virtual.o: ../../include/mail_server.h
virtual.o: virtual.h
virtual.o: ../../include/mbox_conf.h
#include <mail_conf.h>
#include <mail_params.h>
#include <mail_addr_find.h>
+#include <flush_clnt.h>
/* Single server skeleton. */
VAR_VIRT_MAILBOX_LIMIT, VAR_MESSAGE_LIMIT);
set_file_limit(var_virt_mailbox_limit);
}
+
+ /*
+ * flush client.
+ */
+ flush_init();
}
/* main - pass control to the single-threaded skeleton */