1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-29 08:08:37 +00:00

Import sendmail 8.14.1

This commit is contained in:
Gregory Neil Shapiro 2007-04-09 01:38:51 +00:00
parent 3a3ef73d37
commit d0cef73d40
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/sendmail/dist/; revision=168515
svn path=/vendor/sendmail/8.14.1/; revision=168517; tag=vendor/sendmail/8.14.1
161 changed files with 11950 additions and 5375 deletions

View File

@ -29,10 +29,10 @@ This list is not guaranteed to be complete.
* Null bytes are not handled properly in headers.
Sendmail should handle full binary data. As it stands, it handles
all values in the body, but only 0x01-0x80 and 0xA0-0xFF in
the header. Notably missing is 0x00, which would require a major
restructuring of the code -- for example, almost no C library support
could be used to handle strings.
all values in the body, but not 0x00 in the header. Changing
this would require a major restructuring of the code -- for
example, almost no C library support could be used to handle
strings.
* Header checks are not called if header value is too long or empty.
@ -170,7 +170,7 @@ Kresolve sequence dnsmx canon
When sendmail is doing 8->7 bit MIME conversions, and the message
contains certain MIME body types that cannot be converted to 7-bit,
sendmail will strip the message to 7-bit.
sendmail will pass the message as 8-bit.
* 7->8 bit MIME conversion
@ -235,9 +235,9 @@ Kresolve sequence dnsmx canon
Sendmail will deliver to a fail if the file is owned by the DefaultUser
or has the set-user-ID bit set. Unfortunately, some systems clear that bit
when a file is modified. Sendmail compensates by resetting the file mode
when a file is modified. Sendmail compensates by resetting the file mode
back to it's original settings. Unfortunately, there's still a
permission failure race as sendmail checks the permissions before locking
permission failure race as sendmail checks the permissions before locking
the file. This is unavoidable as sendmail must verify the file is safe
to open before opening it. A file can not be locked until it is open.
@ -247,4 +247,4 @@ Kresolve sequence dnsmx canon
be used if set instead of LOCAL_RELAY ($R). This will be fixed in a
future version.
$Revision: 8.57 $, Last updated $Date: 2004/12/02 23:39:01 $
$Revision: 8.59 $, Last updated $Date: 2007/02/21 23:13:58 $

View File

@ -141,6 +141,82 @@ gpExpdV7qPrw9k01j5rod5PjZlG8zV0=
=SR28
-----END PGP PUBLIC KEY BLOCK-----
Type Bits KeyID Created Expires Algorithm Use
pub 1024 0x7093B841 2006-12-16 ---------- RSA Sign & Encrypt
f16 Fingerprint16 = D9 FD C5 6B EE 1E 7A A8 CE 27 D9 B9 55 8B 56 B6
uid Sendmail Signing Key/2007 <sendmail@Sendmail.ORG>
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.5 (OpenBSD)
mQCNA0WDjKsAAAEEAOoLs+uE8cm6SP0S4gvfZrUHd74I9DWSbbiYCwsLoYUm0gcp
Tp+rTcLBDTrw93cti1vpEAlIz7f/kH+J+OoU0WNAZgBMsSCFZecJvmkrSldCsRJf
UwBh5FWgDWmb/iNZSAwUpisCa+BGnpKhUkC9g09h7Ss683GApJdDARhwk7hBAAUR
tDFTZW5kbWFpbCBTaWduaW5nIEtleS8yMDA3IDxzZW5kbWFpbEBTZW5kbWFpbC5P
Ukc+iQCVAwUQRYOMq5dDARhwk7hBAQFdSAQAuS8Etdrnf9+50VYoFC66SUsf8MLi
hvH2k8GeAH11weE/8Aij7eR7MerlnyJ5NJVupVDeqK+q7ToaGlb5hq0ya3rbYgwx
CpzxWTHfvS4/DWs15ajlR3QHkDRZC5pUBAHO0MqC1YskcbndWkmpMhlExb3YVvC6
5+RyKUmxqw1Rp96JAJUDBRBFg44uHnuzyK+VliUBAcjWA/4kZeVmOOikqAzGRm3i
coFOr5BUnhxFWTcO5DtnKSvEBPRaj1b7Xz9O0sfEwrGARDigcH2V4yMSxQLJ9Tyx
S4xjFryTXYPX3+HPLmU97c8VyDF/ANCgdldVW761hXd4i3JCfHm9LMWQBWz4XQaD
iz56GHoFwvn/nrGmBi/3K+1+/YkAlQMFEEWDjnC92o/WP+p9/QEBIoQEAKitPCB9
Lab/vs6QhHEW4UdoPTK8EcgsRQTjx+xZ0/XPC3PiLjTXM7cZk7o+oQrp5PGX1RqM
RV8bzPtJCNiwCctuYpKuYuGjljw8IhZmVxChH/5ifOo7Bw1cxGMWPGlex9x3Xel1
P4BGi7cOvGGRasEBs5gjtpq795+tDjexh0MwiQCVAwUQRYOOfnxLZ22gDhVjAQHV
IAQAhE48oNTvzCPAyFf5EEGOsnZBDazqujZS84eAiFvIQfcDcBHCFOaK4wAKsZa4
YhuYBxu8bz20Kecqfbfnsqyh4b3iJmXiHiL8gIpUzEBBOKesswlzAd7+6hA3/JqN
8a6djrSo/+GEC6QExnLk98qTnfrfHNbTk/hk4Pxf9343uziJAJUDBRBFg46u1uCh
/k++Kt0BAS3ZA/9FxlTjvDfI+ujW/Bj+OoWnwCm2OGiLjuWKoiVZjoz2Msp6ZE6I
1YbqJOwchBpqaHLNyY8x0eiXLYqbrk2kwST1PCAaGQoizK9ClPyptf2V/LUjyyCi
ppmRNH0rG+WSKsdof4rXRP8FmMicQAW4cme3n5/bq7Z7yQQ4RvSTCMru4IkAlQMF
EEWDjsuJaWK4Z4wKAwEBKOMEAIRl9rOD0eDvtDe5Uv7j4lIYGxe8xSRKstLzIl6T
K9spRcrqJk+6OmZHU6MMzkf44z8CB9VWcmozXFxjV+ZkO4SgyJKLZdRc0KGOB+ua
HL8q5WGMAJ2bLpmJPVoR0PK1Vf97e1kSOWdvIOfwxe8Y1IqoxnGAJmdQh6IJyBc0
tF6MiQCVAwUQRYOO/XCgJE0e+ZJRAQHhGwP/az5s1kZ6HoJRqg1v/8DOSZEeWECP
wBw5mgW5dGfPNZ0/Ot9lOy95jlHMu80/YDmpQ6WqsqpnV1hTmj+hYOSPRTqun72l
IiPh1l0vLl00kw+LxR7T7jPSWvX2l8SjZ176KIFqj3jZpPvMk2W5cE4sjYpvOxRA
BhheDkERTnUIY+iJAJUDBRBFg48VwCnKQBb0zOkBAVKaBACEb12dzj1pQDFog8h+
aN9spewVBI0vrxu/3PPZY0tVZJl3S71TXRVmXLYEgeVi5BL8uDuiM14NylUk0lgT
bVL/VxPsKf9HJVjdfZSbFjUBxxClTIvayTwtMSebO2AcjCiFbMpp2R6VDc791Fp/
xvuLVr3plYLSQIL9FcBG2wJR1IkAlQMFEEWDj3PvWJZk1DLhnQEBS80D/j05Rlv3
98Zt+L0hR0+R3qyuf1cFMNyxU5l4Iaf7qr9JRHltHo7iGE8fCGiX1Z3f5BGL03XA
r1QLusj7nk41W0K5tr3r33qSMjFWLpcOziLbzEAMDQbX0qJQmqCXT+cafiVpao0u
MqT84L2rKLQxldQM/fvOWExuioiZPKGyE3YuiQCVAwUQRYOPicGcHSUS00YdAQEU
PwP/Z4PmlZZIhle8P9Bv4c6pkuFkU6LBjF4bWf5bJ675s9Xyh6YwZ5SfFw0deaDZ
IPXQJQsjcHvbVGoTOxiQtm7y3ae+0TMDbuZSgFD6Fl/IdIdwP2Ob5yoBr1+q353C
qyLSEI6mX1P4sQwkI272ndSpHowJpuBv6lPr+sZ2uEFzVQSJAJUDBRBFg4+Qb1KT
2KObplUBAcTnA/9ueiH0gfV1H+8WOm6vUAcvaJ7aCBJ9gdUjheIEY/KDUH/pkGAg
3E8NDxojTWe88COlIOSqa61UQThSwrtTIx0oWc0E3Bza0cL2xR4apKfNPGWM1/Tp
kyoD+WYLoVpomT1MA8dBPYUKNuLVunohVscRwmHuUsz8bTTaE4abEnUmwYkAlQMF
EEWDj5qcHL3i41xWNQEBOJIEALestUaN+JpQ6JvH2zqBFIXPsBoISVuTP/CNlez0
LSSg9Oi1anMISRNj6cpu8iYYWJxInL05pDCV5MYySB2SzVT8HgrR+3yUdVFgJGBN
2RYdfXdFqC/d68/50muZzPo+LIwKX+G33B4y0uMSdmK76UhGNW9rfWdQgce7sBph
1Z1YiQCVAwUQRYOPqTgi20fMN08tAQE7KAQAtYpp2c7OzXPXNJRbodNihpRq1RXd
qo1nJ7qVHuLVb663GMfy4TwcXytdzJjXAaMf/Rn50skQ+4YGrbIxXC3UbY9NK3xw
UzebQlzFrjEtPmS0UVyf8GJl6yQ3xuBYZ4Pe+X2hioBDDFZ+Gjn1DA2IQjoZitE5
B0c9nlknPcv644SJAJUDBRBFg4+zIYPhsTlvB4kBAefCBADFjYutzx72jDt26otM
k44ZLD6Szv90TKLtRYM5FNhtw9VKFkg+hSo15WzUHKBsnyqBT8Qq6YKz50Wx2vts
8g2hJ8+g0A+3YuAgNnDp7h7xGS6Fgc5yGnqC0bG7T7TE/YSLfGz97vC0vbm6S6HG
9Pg+IwKl9dtoE2fkU/BMU2XO+YkAlQMFEEWDj7rI1e0plfYXcQEBi4EEAJ1tRaXf
aKj9+hVE9lTRbDukb9dsVtAKHP/rRixumf6+v5SCh4g0FzMURJ3jqlwfj2/rPrq2
MQh1NwhLjVjaEziDCLGxV/TqpK1Yn0vpjmdsaOe01XOxi2+uy/7uo/ArGqtjHSen
7TmYODY3aKQR19eVehId4TCR1sLO9GmhnYDjiQCVAwUQRY71+s8etQMiMnoBAQGq
ygP+NdG19Qz0Tf4F4pBRAZiJdIz9hGEzx/Z7rjQhLgzaaGxOQmv2iG/92Fw9/H+M
ATmTMfbz5gxpLkBsiULI15tgKQWsFwY/pphRKcL9z4+WeTmUkv+tPxVfRYE3YuUc
QS/3A3DMIv/mcJYA6fiwsf3omzEU8VCyH0uARSJrwQcdmwCJAJUDBRBFjvsM4dT8
FObQdHEBAeC5A/98yBTBWjhCYvB2XLbbL9dN0DKtV9oqXKhrPI9BAjRi/IeAi04b
ktzwUC45TLQXlVB1EK27b2mjNwPFcOtM+IrO00gIf1lNh222lSJUISv5rLnHp02j
xmyQfblYVQ9iPNiJMWNzID59+ntX+MXO71NwyA7UovMTvCcaFWhTrfGk4okAlQMF
EEWPCSBfHshviAyeVQEBS3wD/04nsshuG5NkdqgL8+E0RycXqXchIJ9GP+Vu9sxB
aGAh8qzp6xDh6r7A36JCwuUpZWCOC10z4/+QjMwZBQiLH4+deQk7j7L5LxDAWIs6
DImewMQsg2zF3XlD/Sz+TjKUA1HMwmDOagrygwpbZRYlhJscov/aUeBmUTmaEsP4
cETBiEYEEBECAAYFAkWPz+8ACgkQOIoVOB4I2B3ysQCgoPb3snzfJrbqM6T/Y+tu
YfUd59IAnifkpVQIfhZf1aWIPNYXnlYnpVrZiEYEEBECAAYFAkWPshcACgkQorv7
JAz5Vve5KACg7oh+VFz6UxqjfkiimQ6l/8uI9msAnRB9DBRE6Ebh9CjV15bvm7Y7
as8y
=w7F1
-----END PGP PUBLIC KEY BLOCK-----
Type Bits KeyID Created Expires Algorithm Use
pub 1024 0xAF959625 2005-12-31 ---------- RSA Sign & Encrypt
f16 Fingerprint16 = E3 F4 97 BC 9F DF 3F 1D 9B 0D DF D5 77 9A C9 79
@ -1653,4 +1729,4 @@ DnF3FZZEzV7oqPwC2jzv/1dD6GFhtgy0cnyoPGUJCyc=
=nES8
-----END PGP PUBLIC KEY BLOCK-----
$Revision: 8.24 $, Last updated $Date: 2006/05/01 19:10:19 $
$Revision: 8.25 $, Last updated $Date: 2007/01/02 22:38:08 $

View File

@ -1,11 +1,279 @@
SENDMAIL RELEASE NOTES
$Id: RELEASE_NOTES,v 8.1777.2.15 2006/08/07 17:22:09 ca Exp $
$Id: RELEASE_NOTES,v 8.1888 2007/04/03 23:28:40 ca Exp $
This listing shows the version of the sendmail binary, the version
of the sendmail configuration files, the date of release, and a
summary of the changes in that release.
8.14.1/8.14.1 2007/04/03
Even though a milter rejects a recipient the MTA will still keep
it in its list of recipients and deliver to it if the
transaction is accepted. This is a regression introduced
in 8.14.0 due to the change for SMFIP_RCPT_REJ. Bug
found by Andy Fiddaman.
The new DaemonPortOptions which begin with a lower case character
could not be set in 8.14.0.
If a server shut down the connection in response to a STARTTLS
command, sendmail would log a misleading error message
due to an internal inconsistency. Problem found by
Werner Wiethege.
Document how some sendmail.cf options change the behavior of mailq.
Noted by Paul Menchini of the North Carolina School of
Science and Mathematics.
CONFIG: Add confSOFT_BOUNCE m4 option for setting SoftBounce.
CONFIG: 8.14.0's RELEASE_NOTES failed to mention the addition
of the confMAX_NOOP_COMMANDS and confSHARED_MEMORY_KEY_FILE
m4 options for setting MaxNOOPCommands and
SharedMemoryKeyFile.
CONFIG: Add confMILTER_MACROS_EOH and confMILTER_MACROS_DATA m4
options for setting Milter.macros.eoh and Milter.macros.data.
CONTRIB: Use flock() and fcntl() in qtool.pl if necessary.
Patch from Daniel Carroll of Mesa State College.
LIBMILTER: Make sure an unknown command does not affect the
currently available macros. Problem found by Andy Fiddaman.
LIBMILTER: The MTA did not offer SMFIF_SETSYMLIST during option
negotiation. Problem reported by Bryan Costales.
LIBMILTER: Fix several minor errors in the documentation.
Patches from Bryan Costales.
PORTABILITY FIXES:
AIX 5.{1,2}: libsm/util.c failed to compile due to
redefinition of several macros, e.g., SIG_ERR.
Patch from Jim Pirzyk with assistance by Bob
Booth, University of Illinois at Urbana-Champaign.
Add support for QNX.6. Patch from Sean Boudreau of QNX
Software Systems.
New Files:
devtools/M4/depend/QNX6.m4
devtools/OS/QNX.6.x
include/sm/os/sm_os_qnx.h
New Files added in 8.14.0, but not shown in the release notes entry:
libmilter/docs/smfi_chgfrom.html
libmilter/docs/smfi_version.html
8.14.0/8.14.0 2007/01/31
Header field values are now 8 bit clean. Notes:
- header field names are still restricted to 7 bit.
- RFC 2822 allows only 7 bit (US-ASCII) characters in
headers.
Preserve spaces after the colon in a header. Previously, any
number of spaces after the colon would be changed to
exactly one space.
In some cases of deeply nested aliases/forwarding, mail can
be silently lost. Moreover, the MaxAliasRecursion
limit may be reached too early, e.g., the counter
may be off by a factor of 4 in case of a sequence of
.forward files that refer to others. Patch from
Motonori Nakamura of Kyoto University.
Fix a regression in 8.13.8: if InputMailFilters is set then
"sendmail -bs" can trigger an assertion because the
hostname of the client is undefined. It is now set
to "localhost" for the xxfi_connect() callback.
Avoid referencing a freed variable during cleanup when terminating.
Problem reported and diagnosed by Joe Maimon.
New option HeloName to set the name for the HELO/EHLO command.
Patch from Nik Clayton.
New option SoftBounce to issue temporary errors (4xy) instead of
permanent errors (5xy). This can be useful for testing.
New suboptions for DaemonPortOptions to set them individually
per daemon socket:
DeliveryMode DeliveryMode
refuseLA RefuseLA
delayLA DelayLA
queueLA QueueLA
children MaxDaemonChildren
New option -K for LDAP maps to replace %1 through %9 in the
lookup key with the LDAP escaped contents of the
arguments specified in the map lookup. Loosely based
on patch from Wolfgang Hottgenroth.
Log the time after which a greet_pause delay triggered. Patch
from Nik Clayton.
If a client is rejected via TCP wrapper or some other check
performed by validate_connection() (in conf.c) then do
not also invoke greet_pause. Problem noted by Jim Pirzyk
of the University of Illinois at Urbana-Champaign.
If a client terminates the SMTP connection during a pause
introduced by greet_pause, then a misleading message
was logged previously. Problem noted by Vernon Schryver
et.al., patch from Matej Vela.
New command "mstat" for control socket to provide "machine
readable" status.
New named config file rule check_eom which is called at the end
of a message, its parameter is the size of the message.
If the macro {addr_type} indicates that the current address
is a header address it also distinguishes between
recipient and sender addresses (as it is done for
envelope addresses).
When a macro is set in check_relay, then its value is accessible
by all transactions in the same SMTP session.
Increase size of key for ldap lookups to 1024 (MAXKEY).
New option MaxNOOPCommands to override default of 20 for the
number of "useless" commands before the SMTP server will
slow down responding.
New option SharedMemoryKeyFile: if shared memory support is
enabled, the MTA can be asked to select a shared memory
key itself by setting SharedMemoryKey to -1 and specifying
a file where to store the selected key.
Try to deal with open HTTP proxies that are used to send spam
by recognizing some commands from them. If the first command
from the client is GET, POST, CONNECT, or USER, then the
connection is terminated immediately.
New PrivacyOptions noactualrecipient to avoid putting
X-Actual-Recipient lines in DSNs revealing the actual
account that addresses map to. Patch from Dan Harkless.
New options B, z, and Z for DNS maps:
-B: specify a domain that is always appended to queries.
-z: specify the delimiter at which to cut off the result of
a query if it is too long.
-Z: specify the maximum number of entries to be concatenated
to form the result of a lookup.
New target "check" in the Makefile of libsm: instead of running tests
implicitly while building libsm, they must be explicitly
started by using "make check".
Fixed some inconsistent checks for NULL pointers that have been
reported by the SATURN tool which has been developed by
Isil Dillig and Thomas Dillig of Stanford University.
Fix a potential race condition caused by a signal handler for
terminated child processes. Problem noted by David F. Skoll.
When a milter deleted a recipient, that recipient could cause a
queue group selection. This has been disabled as it was not
intended.
New operator 'r' for the arith map to return a random number.
Patch from Motonori Nakamura of Kyoto University.
New compile time option MILTER_NO_NAGLE to turn off the Nagle
algorithm for communication with libmilter ("cork" on Linux),
which may improve the communication performance on some
operating systems. Patch from John Gardiner Myers of
Proofpoint.
If sendmail received input that contained a CR without subsequent LF
(thus violating RFC 2821 (2.3.7)), it could previously
generate an additional blank line in the output as the last
line.
Restarting persistent queue runners by sending a HUP signal to
the "queue control process" (QCP) works now.
Increase the length of an input line to 12288 to deal with
really long lines during SMTP AUTH negotiations.
Problem noted by Werner Wiethege.
If ARPANET mode (-ba) was selected STARTTLS would fail (due to
a missing initialization call for that case). Problem
noted by Neil Rickert of Northern Illinois University.
If sendmail is linked against a library that initializes Cyrus-SASL
before sendmail did it (such as libnss-ldap), then SMTP AUTH
could fail for the sendmail client. A patch by Moritz Both
works around the API design flaw of Cyrus-SASLv2.
CONFIG: Make it possible to unset the StatusFile option by
undefining STATUS_FILE. By not setting StatusFile,
the MTA will not attempt to open a statistics file on
each delivery.
CONFIG: New FEATURE(`require_rdns') to reject messages from SMTP
clients whose IP address does not have proper reverse DNS.
Contributed by Neil Rickert of Northern Illinois University
and John Beck of Sun Microsystems.
CONFIG: New FEATURE(`block_bad_helo') to reject messages from SMTP
clients which provide a HELO/EHLO argument which is either
unqualified, or is one of our own names (i.e., the server
name instead of the client name). Contributed by Neil
Rickert of Northern Illinois University and John Beck of
Sun Microsystems.
CONFIG: New FEATURE(`badmx') to reject envelope sender addresses
(MAIL) whose domain part resolves to a "bad" MX record.
Based on contribution from William Dell Wisner.
CONFIG: New macros SMTP_MAILER_LL and RELAY_MAILER_LL to override
the maximum line length of the smtp mailers.
CONFIG: New option `relaytofulladdress' for FEATURE(`access_db')
to allow entries in the access map to be of the form
To:user@example.com RELAY
CONFIG: New subsuboptions eoh and data to specify the list of
macros a milter should receive at those stages in the
SMTP dialogue.
CONFIG: New option confHELO_NAME for HeloName to set the name
for the HELO/EHLO command.
CONFIG: dnsbl and enhdnsbl can now also discard or quarantine
messages by using those values as second argument.
Patches from Nelson Fung.
CONTRIB: cidrexpand uses a hash symbol as comment character and
ignores everything after it unless it is in quotes or
preceeded by a backslash.
DEVTOOLS: New macro confMKDIR: if set to a program that creates
directories, then it used for "make install" to create
the required installation directories.
DEVTOOLS: New macro confCCLINK to specify the linker to use for
executables (defaults to confCC).
LIBMILTER: A new version of the milter API has been created that
has several changes which are listed below and documented
in the webpages reachable via libmilter/docs/index.html.
LIBMILTER: The meaning of the version macro SMFI_VERSION has been
changed. It now refers only to the version of libmilter,
not to the protocol version (which is used only internally,
it is not user/milter-programmer visible). Additionally,
a version function smfi_version() has been introduced such
that a milter program can check the libmilter version also
at runtime which is useful if a shared library is used.
LIBMILTER: A new callback xxfi_negotiate() can be used to
dynamically (i.e., at runtime) determine the available
protocol actions and features of the MTA and also to
specify which of these a milter wants to use. This allows
for more flexibility than hardcoding these flags in the
xxfi_flags field of the smfiDesc structure.
LIBMILTER: A new callback xxfi_data() is available so milters
can act on the DATA command.
LIBMILTER: A new callback xxfi_unknown() is available so milters
can receive also unknown SMTP commands.
LIBMILTER: A new return code SMFIS_NOREPLY has been added which
can be used by the xxfi_header() callback provided the
milter requested the SMFIP_NOHREPL protocol action.
LIBMILTER: The new return code SMFIS_SKIP can be used in the
xxfi_body() callback to skip over further body chunks
and directly advance to the xxfi_eom() callback. This
is useful if a milter can make a decision based on the
body chunks it already received without reading the entire
rest of the body and the milter wants to invoke functions
that are only available from the xxfi_eom() callback.
LIBMILTER: A new function smfi_addrcpt_par() can be used to add
new recipients including ESMTP parameters.
LIBMILTER: A new function smfi_chgfrom() can be used to change the
envelope sender including ESMTP parameters.
LIBMILTER: A milter can now request to be informed about rejected
recipients (RCPT) too. This requires to set the protocol
flag SMFIP_RCPT_REJ during option negotiation. Whether
a RCPT has been rejected can be checked by comparing the
value of the macro {rcpt_mailer} with "error".
LIBMILTER: A milter can now override the list of macros that it
wants to receive from the MTA for each protocol step
by invoking the function smfi_setsymlist() during option
negotiation.
LIBMILTER: A milter can receive header field values with all
leading spaces by requesting the SMFIP_HDR_LEADSPC
protocol action. Also, if the flag is set then the MTA
does not add a leading space to headers that are added,
inserted, or replaced.
LIBMILTER: If a milter sets the reply code to "421" for the HELO
callback, the SMTP server will terminate the SMTP session
with that error to match the behavior of all other callbacks.
New Files:
cf/feature/badmx.m4
cf/feature/block_bad_helo.m4
cf/feature/require_rdns.m4
devtools/M4/UNIX/check.m4
include/sm/misc.h
include/sm/sendmail.h
include/sm/tailq.h
libmilter/docs/smfi_addrcpt_par.html
libmilter/docs/smfi_setsymlist.html
libmilter/docs/xxfi_data.html
libmilter/docs/xxfi_negotiate.html
libmilter/docs/xxfi_unknown.html
libmilter/example.c
libmilter/monitor.c
libmilter/worker.c
libsm/memstat.c
libsm/t-memstat.c
libsm/t-qic.c
libsm/util.c
sendmail/daemon.h
sendmail/map.h
8.13.8/8.13.8 2006/08/09
Fix a regression in 8.13.7: if shared memory is activated, then
the server can erroneously report that there is
@ -1317,7 +1585,7 @@ summary of the changes in that release.
Properly count message size for mailstats during mail collection.
Problem noted by Werner Wiethege.
Log complete response from LMTP delivery agent on failure. Based on
patch from by Motonori Nakamura of Kyoto University.
patch from Motonori Nakamura of Kyoto University.
Provide workaround for getopt() implementations that do not catch
missing arguments.
Fix the message size calculation if the message body is replaced by

View File

@ -397,6 +397,9 @@ SMTP_MAILER_CHARSET [undefined] If defined, messages containing 8-bit data
that ARRIVE from an address that resolves to one of
the SMTP mailers and which are converted to MIME will
be labeled with this character set.
SMTP_MAILER_LL [990] The maximum line length for SMTP mailers
(except the relay mailer).
RELAY_MAILER_LL [2040] The maximum line length for the relay mailer.
UUCP_MAILER_PATH [/usr/bin/uux] The program used to send UUCP mail.
UUCP_MAILER_FLAGS [undefined] Flags added to UUCP mailer. Default
flags are `DFMhuU' (and `m' for uucp-new mailer,
@ -1031,12 +1034,6 @@ ldap_routing Implement LDAP-based e-mail recipient routing according to
See the LDAP ROUTING section below for more information.
nodns If you aren't running DNS at your site (for example,
you are UUCP-only connected). It's hard to consider
this a "feature", but hey, it had to go somewhere.
Actually, as of 8.7 this is a no-op -- remove "dns" from
the hosts service switch entry instead.
nullclient This is a special case -- it creates a configuration file
containing nothing but support for forwarding all mail to a
central hub via a local SMTP-based network. The argument
@ -1241,12 +1238,15 @@ use_client_ptr If this feature is enabled then check_relay will override
versions when delay_checks was not in use. See doc/op/op.*
about check_relay, {client_name}, and {client_ptr}.
dnsbl Turns on rejection of hosts found in an DNS based rejection
list. The first is used as the domain in which blocked
hosts are listed. A second argument can be used to change
the default error message. Without that second argument,
the error message will be
dnsbl Turns on rejection, discarding, or quarantining of hosts
found in a DNS based list. The first argument is used as
the domain in which blocked hosts are listed. A second
argument can be used to change the default error message,
or select one of the operations `discard' and `quarantine'.
Without that second argument, the error message will be
Rejected: IP-ADDRESS listed at SERVER
where IP-ADDRESS and SERVER are replaced by the appropriate
information. By default, temporary lookup failures are
ignored. This behavior can be changed by specifying a
@ -1485,6 +1485,81 @@ greet_pause Adds the greet_pause ruleset which enables open proxy
R$* $: $&{daemon_flags}
R$* a $* $# 0
block_bad_helo Reject messages from SMTP clients which provide a HELO/EHLO
argument which is either unqualified, or is one of our own
names (i.e., the server name instead of the client name).
This check is performed at RCPT stage and disabled for the
following cases:
- authenticated sessions,
- connections from IP addresses in class $={R}.
Currently access_db lookups can not be used to
(selectively) disable this test, moreover,
FEATURE(`delay_checks')
is required.
require_rdns Reject mail from connecting SMTP clients without proper
rDNS (reverse DNS), functional gethostbyaddr() resolution.
Note: this feature will cause false positives, i.e., there
are legitimate MTAs that do not have proper DNS entries.
Rejecting mails from those MTAs is a local policy decision.
The basic policy is to reject message with a 5xx error if
the IP address fails to resolve. However, if this is a
temporary failure, a 4xx temporary failure is returned.
If the look-up succeeds, but returns an apparently forged
value, this is treated as a temporary failure with a 4xx
error code.
EXCEPTIONS:
Exceptions based on access entries are discussed below.
Any IP address matched using $=R (the "relay-domains" file)
is excepted from the rules. Since we have explicitly
allowed relaying for this host, based on IP address, we
ignore the rDNS failure.
The philosophical assumption here is that most users do
not control their rDNS. They should be able to send mail
through their ISP, whether or not they have valid rDNS.
The class $=R, roughly speaking, contains those IP addresses
and address ranges for which we are the ISP, or are acting
as if the ISP.
If `delay_checks' is in effect (recommended), then any
sender who has authenticated is also excepted from the
restrictions. This happens because the rules produced by
this FEATURE() will not be applied to authenticated senders
(assuming `delay_checks').
ACCESS MAP ENTRIES:
Entries such as
Connect:1.2.3.4 OK
Connect:1.2 RELAY
will whitelist IP address 1.2.3.4, so that the rDNS
blocking does apply to that IP address
Entries such as
Connect:1.2.3.4 REJECT
will have the effect of forcing a temporary failure for
that address to be treated as a permanent failure.
badmx Reject envelope sender addresses (MAIL) whose domain part
resolves to a "bad" MX record. By default these are
MX records which resolve to A records that match the
regular expression:
^(127\.|10\.|0\.0\.0\.0)
This default regular expression can be overridden by
specifying an argument, e.g.,
FEATURE(`badmx', `^127\.0\.0\.1')
Note: this feature requires that the sendmail binary
has been compiled with the options MAP_REGEX and
DNSMAP.
+-------+
| HACKS |
+-------+
@ -2426,10 +2501,15 @@ definition for the database; for example
FEATURE(`access_db', `hash -T<TMPF> /etc/mail/access_map')
Notice: If a second argument is specified it must contain the option
`-T<TMPF>' as shown above. The optional third and fourth parameters
may be `skip' or `lookupdotdomain'. The former enables SKIP as
value part (see below), the latter is another way to enable the
feature of the same name (see above).
`-T<TMPF>' as shown above. The optional parameters may be
`skip' enables SKIP as value part (see below).
`lookupdotdomain' another way to enable the feature of the
same name (see above).
`relaytofulladdress' enable entries of the form
To:user@example.com RELAY
to allow relaying to just a specific
e-mail address instead of an entire domain.
Remember, since /etc/mail/access is a database, after creating the text
file as described below, you must use makemap to create the database
@ -2497,7 +2577,8 @@ The value part of the map can contain:
name is unresolvable. "Accept" does not mean
"relay", but at most acceptance for local
recipients. That is, OK allows less than RELAY.
RELAY Accept mail addressed to the indicated domain or
RELAY Accept mail addressed to the indicated domain
(or address if `relaytofulladdress' is set) or
received from the indicated domain for relaying
through your SMTP server. RELAY also serves as
an implicit OK for the other checks.
@ -2628,7 +2709,7 @@ maintained in DNS. To use such a database, specify
FEATURE(`dnsbl', `dnsbl.example.com')
This will cause sendmail to reject mail from any site listed in the
DNS based blacklist. You must select an DNSB based blacklist domain
DNS based blacklist. You must select a DNS based blacklist domain
to check by specifying an argument to the FEATURE. The default
error message is
@ -2636,10 +2717,18 @@ error message is
where IP-ADDRESS and SERVER are replaced by the appropriate
information. A second argument can be used to specify a different
text. By default, temporary lookup failures are ignored and hence
cause the connection not to be rejected by the DNS based rejection
list. This behavior can be changed by specifying a third argument,
which must be either `t' or a full error message. For example:
text or action. For example,
FEATURE(`dnsbl', `dnsbl.example.com', `quarantine')
would quarantine the message if the client IP address is listed
at `dnsbl.example.com'.
By default, temporary lookup failures are ignored
and hence cause the connection not to be rejected by the DNS based
rejection list. This behavior can be changed by specifying a third
argument, which must be either `t' or a full error message. For
example:
FEATURE(`dnsbl', `dnsbl.example.com', `',
`"451 Temporary lookup failure for " $&{client_addr} " in dnsbl.example.com"')
@ -4033,6 +4122,11 @@ confDOUBLE_BOUNCE_ADDRESS DoubleBounceAddress
"double bounce" error message to this
address. If it expands to an empty
string, double bounces are dropped.
confSOFT_BOUNCE SoftBounce [False] If set, issue temporary errors
(4xy) instead of permanent errors
(5xy). This can be useful during
testing of a new configuration to
avoid erroneous bouncing of mails.
confDEAD_LETTER_DROP DeadLetterDrop [undefined] Filename to save bounce
messages which could not be returned
to the user or sent to postmaster.
@ -4197,6 +4291,11 @@ confREQUIRES_DIR_FSYNC RequiresDirfsync [true] RequiresDirfsync can
flag REQUIRES_DIR_FSYNC at runtime.
See sendmail/README for details.
confSHARED_MEMORY_KEY SharedMemoryKey [0] Key for shared memory.
confSHARED_MEMORY_KEY_FILE
SharedMemoryKeyFile
[undefined] File where the
automatically selected key for
shared memory is stored.
confFAST_SPLIT FastSplit [1] If set to a value greater than
zero, the initial MX lookups on
addresses is suppressed when they
@ -4210,6 +4309,11 @@ confMAILBOX_DATABASE MailboxDatabase [pw] Type of lookup to find
information about local mailboxes.
confDEQUOTE_OPTS - [empty] Additional options for the
dequote map.
confMAX_NOOP_COMMANDS MaxNOOPCommands [20] Maximum number of "useless"
commands before the SMTP server
will slow down responding.
confHELO_NAME HeloName If defined, use as name for EHLO/HELO
command (instead of $j).
confINPUT_MAIL_FILTERS InputMailFilters
A comma separated list of filters
which determines which filters and
@ -4241,7 +4345,14 @@ confMILTER_MACROS_ENVRCPT Milter.macros.envrcpt
milters after RCPT TO command.
confMILTER_MACROS_EOM Milter.macros.eom
[{msg_id}] Macros to transmit to
milters after DATA command.
milters after the terminating
DATA '.' is received.
confMILTER_MACROS_EOH Milter.macros.eoh
Macros to transmit to milters
after the end of headers.
confMILTER_MACROS_DATA Milter.macros.data
Macros to transmit to milters
after DATA command is received.
See also the description of OSTYPE for some parameters that can be
@ -4588,4 +4699,4 @@ M4 DIVERSIONS
8 DNS based blacklists
9 special local rulesets (1 and 2)
$Revision: 8.706 $, Last updated $Date: 2006/04/18 22:31:06 $
$Revision: 8.722 $, Last updated $Date: 2007/04/03 21:26:58 $

View File

@ -19,7 +19,7 @@ divert(-1)
#
divert(0)
VERSIONID(`$Id: knecht.mc,v 8.61 2005/10/06 05:56:03 ca Exp $')
VERSIONID(`$Id: knecht.mc,v 8.62 2006/09/27 19:48:59 eric Exp $')
OSTYPE(bsd4.4)
DOMAIN(generic)
@ -30,6 +30,7 @@ define(`confHOST_STATUS_DIRECTORY', `.hoststat')
define(`confTO_ICONNECT', `10s')
define(`confTO_QUEUEWARN', `8h')
define(`confMIN_QUEUE_AGE', `27m')
define(`confTRUSTED_USER', `smtrust')
define(`confTRUSTED_USERS', ``www listmgr'')
define(`confPRIVACY_FLAGS', ``authwarnings,noexpn,novrfy'')
@ -42,6 +43,7 @@ define(`confCLIENT_CERT', `CERT_DIR/MYcert.pem')
define(`confCLIENT_KEY', `CERT_DIR/MYkey.pem')
define(`CYRUS_MAILER_PATH', `/usr/local/cyrus/bin/deliver')
define(`CYRUS_MAILER_FLAGS', `fAh5@/:|')
FEATURE(`access_db')
FEATURE(`blacklist_recipients')
@ -64,10 +66,16 @@ define(`confFAST_SPLIT', `10')
dnl # 10 runners, split into at most 15 recipients per envelope
QUEUE_GROUP(`mqueue', `P=/var/spool/mqueue, R=5, r=15, F=f')
dnl # enable spam assassin
INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')
dnl # enable DomainKeys and DKIM
INPUT_MAIL_FILTER(`dkim-filter', `S=unix:/var/run/smtrust/dkim.sock, F=T, T=R:2m')
dnl INPUT_MAIL_FILTER(`dk-filter', `S=unix:/var/run/smtrust/dk.sock, F=T, T=R:2m')
define(`confMILTER_MACROS_CONNECT', `j, {daemon_name}')
define(`confMILTER_MACROS_ENVFROM', `i, {auth_type}')
dnl # enable some DNSBLs
dnl FEATURE(`dnsbl', `dnsbl.sorbs.net', `"550 Mail from " $`'&{client_addr} " refused - see http://www.dnsbl.sorbs.net/"')
FEATURE(`dnsbl', `sbl-xbl.spamhaus.org', `"550 Mail from " $`'&{client_addr} " refused - see http://www.spamhaus.org/sbl/"')

View File

@ -16,8 +16,8 @@
#####
##### SENDMAIL CONFIGURATION FILE
#####
##### built by ca@nother.smi.sendmail.com on Mon Aug 7 10:37:32 PDT 2006
##### in /extra/home/ca/sm-8.13.8/OpenSource/sendmail-8.13.8/cf/cf
##### built by ca@nother.smi.sendmail.com on Tue Apr 3 16:32:55 PDT 2007
##### in /extra/home/ca/sm-8.14.1/OpenSource/sendmail-8.14.1/cf/cf
##### using ../ as configuration include directory
#####
######################################################################
@ -35,7 +35,7 @@
##### $Id: no_default_msa.m4,v 8.2 2001/02/14 05:03:22 gshapiro Exp $ #####
##### $Id: proto.m4,v 8.719 2006/03/30 20:50:13 ca Exp $ #####
##### $Id: proto.m4,v 8.730 2007/02/01 18:50:03 ca Exp $ #####
# level 10 config file format
V10/Berkeley
@ -114,7 +114,7 @@ D{MTAHost}[127.0.0.1]
# Configuration version number
DZ8.13.8/Submit
DZ8.14.1/Submit
###############
@ -260,10 +260,11 @@ O PrivacyOptions=goaway,noetrn,restrictqrun
# queue directory
O QueueDirectory=/var/spool/clientmqueue
# key for shared memory; 0 to turn off
# key for shared memory; 0 to turn off, -1 to auto-select
#O SharedMemoryKey=0
# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
#O SharedMemoryKeyFile
# timeouts (many of these)
#O Timeout.initial=5m
@ -423,6 +424,9 @@ O DontInitGroups=True
# where do errors that occur when sending errors get sent?
#O DoubleBounceAddress=postmaster
# issue temporary errors (4xy) instead of permanent errors (5xy)?
#O SoftBounce=False
# where to save bounces if all else fails
#O DeadLetterDrop=/var/tmp/dead.letter
@ -519,6 +523,12 @@ O PidFile=/var/spool/clientmqueue/sm-client.pid
# Random data source (required for systems without /dev/urandom under OpenSSL)
#O RandFile
# Maximum number of "useless" commands before slowing down
#O MaxNOOPCommands=20
# Name to use for EHLO (defaults to $j)
#O HeloName
############################
# QUEUE GROUP DEFINITIONS #
############################
@ -1042,10 +1052,12 @@ R<? $+> $* $#error $@ 5.5.4 $: "553 Domain name required for sender address " $
...remote is not
# check results
R<?> $* $: @ $1 mark address: nothing known about it
R<$={ResOk}> $* $@ <OKR> domain ok: stop
R<$={ResOk}> $* $: @ $2 domain ok
R<TEMP> $* $#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
R<PERM> $* $#error $@ 5.1.8 $: "553 Domain of sender address " $&f " does not exist"
######################################################################
### check_rcpt -- check SMTP `RCPT TO:' command argument
######################################################################
@ -1148,6 +1160,7 @@ R<?> $* $=R $@ RELAY
######################################################################
### trust_auth: is user trusted to authenticate as someone else?
###
@ -1335,7 +1348,7 @@ Mprog, P=[IPC], F=lmDFMuXk5, S=EnvFromL/HdrFromL, R=EnvToL/HdrToL, D=$z:/,
### SMTP Mailer specification ###
#####################################
##### $Id: smtp.m4,v 8.64 2001/04/03 01:52:54 gshapiro Exp $ #####
##### $Id: smtp.m4,v 8.65 2006/07/12 21:08:10 ca Exp $ #####
#
# common sender and masquerading recipient rewriting

View File

@ -1,6 +1,6 @@
divert(-1)
#
# Copyright (c) 1998-2002, 2004 Sendmail, Inc. and its suppliers.
# Copyright (c) 1998-2002, 2004, 2006 Sendmail, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
@ -10,15 +10,20 @@ divert(-1)
#
divert(0)
VERSIONID(`$Id: access_db.m4,v 8.26 2004/06/24 18:10:02 ca Exp $')
VERSIONID(`$Id: access_db.m4,v 8.27 2006/07/06 21:10:10 ca Exp $')
divert(-1)
define(`_ACCESS_TABLE_', `')
define(`_TAG_DELIM_', `:')dnl should be in OperatorChars
ifelse(lower(_ARG2_),`skip',`define(`_ACCESS_SKIP_', `1')')
ifelse(lower(_ARG2_),`lookupdotdomain',`define(`_LOOKUPDOTDOMAIN_', `1')')
ifelse(lower(_ARG2_),`relaytofulladdress',`define(`_RELAY_FULL_ADDR_', `1')')
ifelse(lower(_ARG3_),`skip',`define(`_ACCESS_SKIP_', `1')')
ifelse(lower(_ARG3_),`lookupdotdomain',`define(`_LOOKUPDOTDOMAIN_', `1')')
ifelse(lower(_ARG3_),`relaytofulladdress',`define(`_RELAY_FULL_ADDR_', `1')')
ifelse(lower(_ARG4_),`skip',`define(`_ACCESS_SKIP_', `1')')
ifelse(lower(_ARG4_),`lookupdotdomain',`define(`_LOOKUPDOTDOMAIN_', `1')')
ifelse(lower(_ARG4_),`relaytofulladdress',`define(`_RELAY_FULL_ADDR_', `1')')
define(`_ATMPF_', `<TMPF>')dnl
dnl check whether arg contains -T`'_ATMPF_
dnl unless it is a sequence map

View File

@ -0,0 +1,22 @@
divert(-1)
#
# Copyright (c) 2006 Sendmail, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
divert(0)
VERSIONID(`$Id: badmx.m4,v 1.1 2006/12/16 00:56:32 ca Exp $')
divert(-1)
define(`_BADMX_CHK_', 1)
LOCAL_CONFIG
Kmxlist bestmx -z: -T<TEMP>
Kbadmx regex -a<BADMX> ^(([0-9]{1,3}\.){3}[0-9]){0,1}\.$
KdnsA dns -R A -a. -T<TEMP>
KBadMXIP regex -a<BADMXIP> ifelse(defn(`_ARG_'), `', `^(127\.|10\.|0\.0\.0\.0)', `_ARG_')

View File

@ -0,0 +1,18 @@
divert(-1)
#
# Copyright (c) 2006 Sendmail, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
divert(0)dnl
VERSIONID(`$Id: block_bad_helo.m4,v 1.1 2006/06/15 22:49:30 ca Exp $')
divert(-1)
define(`_BLOCK_BAD_HELO_', `')dnl
RELAY_DOMAIN(`127.0.0.1')dnl
LOCAL_DOMAIN(`[127.0.0.1]')dnl

View File

@ -1,6 +1,6 @@
divert(-1)
#
# Copyright (c) 1998-2002, 2005, 2006 Sendmail, Inc. and its suppliers.
# Copyright (c) 1998-2002, 2005-2007 Sendmail, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
@ -12,7 +12,7 @@ divert(-1)
ifdef(`DNSBL_MAP', `', `define(`DNSBL_MAP', `dns -R A')')
divert(0)
ifdef(`_DNSBL_R_',`dnl',`dnl
VERSIONID(`$Id: dnsbl.m4,v 8.32 2006/03/29 22:50:16 ca Exp $')
VERSIONID(`$Id: dnsbl.m4,v 8.33 2007/01/05 18:49:29 ca Exp $')
define(`_DNSBL_R_',`')
ifelse(defn(`_ARG_'), `',
`errprint(`*** ERROR: missing argument for FEATURE(`dnsbl')')')
@ -31,5 +31,9 @@ R<?>OK $: OKSOFAR
ifelse(len(X`'_ARG3_),`1',
`R<?>$+<TMP> $: TMPOK',
`R<?>$+<TMP> $#error $@ 4.4.3 $: _DNSBL_MSG_TMP_')
R<?>$+ $#error $@ 5.7.1 $: _DNSBL_MSG_
ifelse(`X'_ARG2_,`Xquarantine',
`R<?>$+ $#error $@ quarantine $: _DNSBL_SRV_',
`X'_ARG2_,`Xdiscard',
`R<?>$+ $#discard $: _DNSBL_SRV_',
`R<?>$+ $#error $@ 5.7.1 $: _DNSBL_MSG_')
divert(-1)

View File

@ -1,6 +1,6 @@
divert(-1)
#
# Copyright (c) 2000-2002, 2005, 2006 Sendmail, Inc. and its suppliers.
# Copyright (c) 2000-2002, 2005-2007 Sendmail, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
@ -13,7 +13,7 @@ ifelse(defn(`_ARG_'), `',
`errprint(`*** ERROR: missing argument for FEATURE(`enhdnsbl')')')
divert(0)
ifdef(`_EDNSBL_R_',`dnl',`dnl
VERSIONID(`$Id: enhdnsbl.m4,v 1.11 2006/03/31 19:56:16 ca Exp $')
VERSIONID(`$Id: enhdnsbl.m4,v 1.12 2007/01/08 18:22:05 ca Exp $')
LOCAL_CONFIG
define(`_EDNSBL_R_',`')dnl
# map for enhanced DNS based blacklist lookups
@ -21,9 +21,16 @@ Kednsbl dns -R A -a. -T<TMP> -r`'ifdef(`EDNSBL_TO',`EDNSBL_TO',`5')
')
divert(-1)
define(`_EDNSBL_SRV_', `_ARG_')dnl
define(`_EDNSBL_MSG_', `ifelse(len(X`'_ARG2_),`1',`"550 Rejected: " $`'&{client_addr} " listed at '_EDNSBL_SRV_`"',`_ARG2_')')dnl
define(`_EDNSBL_MSG_',
`ifelse(len(X`'_ARG2_),`1',`"550 Rejected: " $`'&{client_addr} " listed at '_EDNSBL_SRV_`"',
X`'_ARG2_,`Xquarantine',`_EDNSBL_SRV_',
`_ARG2_')')dnl
define(`_EDNSBL_MSG_TMP_', `ifelse(_ARG3_,`t',`"451 Temporary lookup failure of " $`'&{client_addr} " at '_EDNSBL_SRV_`"',`_ARG3_')')dnl
define(`_EDNSBL_MATCH_', `ifelse(len(X`'_ARG4_),`1',`$`'+',_ARG4_)')dnl
define(`_EDNSBL_ACTION_',
`ifelse(X`'_ARG2_,`Xquarantine',`$`'#error $`'@ quarantine',
X`'_ARG2_,`Xdiscard',`$`'#discard',
`$`'#error $`'@ 5.7.1')')dnl
divert(8)
# DNS based IP address spam list _EDNSBL_SRV_
R$* $: $&{client_addr}
@ -32,15 +39,15 @@ R<?>OK $: OKSOFAR
ifelse(len(X`'_ARG3_),`1',
`R<?>$+<TMP> $: TMPOK',
`R<?>$+<TMP> $#error $@ 4.4.3 $: _EDNSBL_MSG_TMP_')
R<?>_EDNSBL_MATCH_ $#error $@ 5.7.1 $: _EDNSBL_MSG_
R<?>_EDNSBL_MATCH_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_
ifelse(len(X`'_ARG5_),`1',`dnl',
`R<?>_ARG5_ $#error $@ 5.7.1 $: _EDNSBL_MSG_')
`R<?>_ARG5_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
ifelse(len(X`'_ARG6_),`1',`dnl',
`R<?>_ARG6_ $#error $@ 5.7.1 $: _EDNSBL_MSG_')
`R<?>_ARG6_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
ifelse(len(X`'_ARG7_),`1',`dnl',
`R<?>_ARG7_ $#error $@ 5.7.1 $: _EDNSBL_MSG_')
`R<?>_ARG7_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
ifelse(len(X`'_ARG8_),`1',`dnl',
`R<?>_ARG8_ $#error $@ 5.7.1 $: _EDNSBL_MSG_')
`R<?>_ARG8_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
ifelse(len(X`'_ARG9_),`1',`dnl',
`R<?>_ARG9_ $#error $@ 5.7.1 $: _EDNSBL_MSG_')
`R<?>_ARG9_ _EDNSBL_ACTION_ $: _EDNSBL_MSG_')
divert(-1)

View File

@ -0,0 +1,16 @@
divert(-1)
#
# Copyright (c) 2006 Sendmail, Inc. and its suppliers.
# All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#
divert(0)dnl
VERSIONID(`$Id: require_rdns.m4,v 1.1 2006/06/15 22:49:30 ca Exp $')
divert(-1)
define(`_REQUIRE_RDNS_', `')

View File

@ -1,6 +1,6 @@
divert(-1)
#
# Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
# Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1983, 1995 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
@ -13,7 +13,7 @@ divert(-1)
#
divert(0)
VERSIONID(`$Id: proto.m4,v 8.719 2006/03/30 20:50:13 ca Exp $')
VERSIONID(`$Id: proto.m4,v 8.730 2007/02/01 18:50:03 ca Exp $')
# level CF_LEVEL config file format
V`'CF_LEVEL/ifdef(`VENDOR_NAME', `VENDOR_NAME', `Berkeley')
@ -396,12 +396,11 @@ _OPTION(FastSplit, `confFAST_SPLIT', `1')
# queue directory
O QueueDirectory=ifdef(`QUEUE_DIR', QUEUE_DIR, `/var/spool/mqueue')
# key for shared memory; 0 to turn off
# key for shared memory; 0 to turn off, -1 to auto-select
_OPTION(SharedMemoryKey, `confSHARED_MEMORY_KEY', `0')
ifdef(`confSHARED_MEMORY_KEY_FILE', `dnl
# file to store key for shared memory (if SharedMemoryKey = -1)
O SharedMemoryKeyFile=confSHARED_MEMORY_KEY_FILE')
# file to store auto-selected key for shared memory (SharedMemoryKey = -1)
_OPTION(SharedMemoryKeyFile, `confSHARED_MEMORY_KEY_FILE', `')
# timeouts (many of these)
_OPTION(Timeout.initial, `confTO_INITIAL', `5m')
@ -452,7 +451,7 @@ _OPTION(DontPruneRoutes, `confDONT_PRUNE_ROUTES', `False')
_OPTION(SuperSafe, `confSAFE_QUEUE', `True')
# status file
O StatusFile=ifdef(`STATUS_FILE', `STATUS_FILE', `MAIL_SETTINGS_DIR`'statistics')
_OPTION(StatusFile, `STATUS_FILE')
# time zone handling:
# if undefined, use system default
@ -565,6 +564,9 @@ ifdef(`confUNSAFE_GROUP_WRITES',
# where do errors that occur when sending errors get sent?
_OPTION(DoubleBounceAddress, `confDOUBLE_BOUNCE_ADDRESS', `postmaster')
# issue temporary errors (4xy) instead of permanent errors (5xy)?
_OPTION(SoftBounce, `confSOFT_BOUNCE', `False')
# where to save bounces if all else fails
_OPTION(DeadLetterDrop, `confDEAD_LETTER_DROP', `/var/tmp/dead.letter')
@ -648,7 +650,9 @@ _OPTION(Milter.macros.connect, `confMILTER_MACROS_CONNECT', `')
_OPTION(Milter.macros.helo, `confMILTER_MACROS_HELO', `')
_OPTION(Milter.macros.envfrom, `confMILTER_MACROS_ENVFROM', `')
_OPTION(Milter.macros.envrcpt, `confMILTER_MACROS_ENVRCPT', `')
_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')')
_OPTION(Milter.macros.eom, `confMILTER_MACROS_EOM', `')
_OPTION(Milter.macros.eoh, `confMILTER_MACROS_EOH', `')
_OPTION(Milter.macros.data, `confMILTER_MACROS_DATA', `')')
# CA directory
_OPTION(CACertPath, `confCACERT_PATH', `')
@ -669,6 +673,12 @@ _OPTION(DHParameters, `confDH_PARAMETERS', `')
# Random data source (required for systems without /dev/urandom under OpenSSL)
_OPTION(RandFile, `confRAND_FILE', `')
# Maximum number of "useless" commands before slowing down
_OPTION(MaxNOOPCommands, `confMAX_NOOP_COMMANDS', `20')
# Name to use for EHLO (defaults to $j)
_OPTION(HeloName, `confHELO_NAME')
############################
`# QUEUE GROUP DEFINITIONS #'
############################
@ -1782,6 +1792,14 @@ ifdef(`_CONN_CONTROL_IMMEDIATE_',`',`dnl
dnl workspace: ignored...
R$* $: $>"ConnControl" dummy')', `dnl')
undivert(8)
ifdef(`_REQUIRE_RDNS_', `dnl
R$* $: $&{client_addr} $| $&{client_resolve}
R$=R $* $@ RELAY We relay for these
R$* $| OK $@ OK Resolves.
R$* $| FAIL $#error $@ 5.7.1 $: 550 Fix reverse DNS for $1
R$* $| TEMP $#error $@ 4.1.8 $: 451 Client IP address $1 does not resolve
R$* $| FORGED $#error $@ 4.1.8 $: 451 Possibly forged hostname for $1
', `dnl')
######################################################################
### check_mail -- check SMTP ``MAIL FROM:'' command argument
@ -1907,7 +1925,7 @@ R<? $+> $* $#error $@ 5.5.4 $: "_CODE553 Domain name required for sender addres
...remote is not')
# check results
R<?> $* $: @ $1 mark address: nothing known about it
R<$={ResOk}> $* $@ <_RES_OK_> domain ok: stop
R<$={ResOk}> $* $: @ $2 domain ok
R<TEMP> $* $#error $@ 4.1.8 $: "451 Domain of sender address " $&f " does not resolve"
R<PERM> $* $#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does not exist"
ifdef(`_ACCESS_TABLE_', `dnl
@ -1922,6 +1940,34 @@ ifdef(`_ATMPF_', `R<_ATMPF_> $* $#error $@ 4.3.0 $: "451 Temporary system failu
dnl generic error from access map
R<$+> $* $#error $: $1 error from access db',
`dnl')
dnl workspace: @ CanonicalAddress (i.e. address in canonical form localpart<@host>)
ifdef(`_BADMX_CHK_', `dnl
R@ $*<@$+>$* $: $1<@$2>$3 $| $>BadMX $2
R$* $| $#$* $#$2
SBadMX
# Look up MX records and ferret away a copy of the original address.
# input: domain part of address to check
R$+ $:<MX><$1><:$(mxlist $1$):><:>
# workspace: <MX><domain><: mxlist-result $><:>
R<MX><$+><:$*<TEMP>:><$*> $#error $@ 4.1.2 $: "450 MX lookup failure for "$1
# workspace: <MX> <original destination> <unchecked mxlist> <checked mxlist>
# Recursively run badmx check on each mx.
R<MX><$*><:$+:$*><:$*> <MX><$1><:$3><: $4 $(badmx $2 $):>
# See if any of them fail.
R<MX><$*><$*><$*<BADMX>:$*> $#error $@ 5.1.2 $:"550 Illegal MX record for recipient host "$1
# Reverse the mxlists so we can use the same argument order again.
R<MX><$*><$*><$*> $:<MX><$1><$3><$2>
R<MX><$*><:$+:$*><:$*> <MX><$1><:$3><:$4 $(dnsA $2 $) :>
# Reverse the lists so we can use the same argument order again.
R<MX><$*><$*><$*> $:<MX><$1><$3><$2>
R<MX><$*><:$+:$*><:$*> <MX><$1><:$3><:$4 $(BadMXIP $2 $) :>
R<MX><$*><$*><$*<BADMXIP>:$*> $#error $@ 5.1.2 $:"550 Invalid MX record for recipient host "$1',
`dnl')
######################################################################
### check_rcpt -- check SMTP ``RCPT TO:'' command argument
@ -2312,6 +2358,7 @@ ifdef(`_SPAM_HATER_',
R<HATER> $+ $: $1 spam hater: continue checks
R<$*> $+ $@ $>"Delay_TLS_Clt2" NOSPAMHATER everyone else: stop
dnl',`dnl')
dnl run further checks: check_mail
dnl should we "clean up" $&f?
ifdef(`_FFR_MAIL_MACRO',
@ -2325,6 +2372,27 @@ R$* $| $#$* $#$2
R$* $| $* $: $1
', `dnl')
ifdef(`_BLOCK_BAD_HELO_', `dnl
R$* $: $1 $| <$&{auth_authen}> Get auth info
dnl Bypass the test for users who have authenticated.
R$* $| <$+> $: $1 skip if auth
R$* $| <$*> $: $1 $| <$&{client_addr}> [$&s] Get connection info
dnl Bypass for local clients -- IP address starts with $=R
R$* $| <$=R $*> [$*] $: $1 skip if local client
dnl Bypass a "sendmail -bs" session, which use 0 for client ip address
R$* $| <0> [$*] $: $1 skip if sendmail -bs
dnl Reject our IP - assumes "[ip]" is in class $=w
R$* $| <$*> $=w $#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
dnl Reject our hostname
R$* $| <$*> [$=w] $#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
dnl Pass anything else with a "." in the domain parameter
R$* $| <$*> [$+.$+] $: $1 qualified domain ok
dnl Reject if there was no "." or only an initial or final "."
R$* $| <$*> [$*] $#error $@ 5.7.1 $:"550 bogus HELO name used: " $&s
dnl Clean up the workspace
R$* $| $* $: $1
', `dnl')
ifdef(`_ACCESS_TABLE_', `dnl', `divert(-1)')
######################################################################
### F: LookUpFull -- search for an entry in access database

View File

@ -1,6 +1,6 @@
divert(-1)
#
# Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
# Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
@ -11,8 +11,8 @@ divert(-1)
# the sendmail distribution.
#
#
VERSIONID(`$Id: version.m4,v 8.150.2.8 2006/07/26 17:24:02 ca Exp $')
VERSIONID(`$Id: version.m4,v 8.178 2007/04/03 21:21:18 ca Exp $')
#
divert(0)
# Configuration version number
DZ8.13.8`'ifdef(`confCF_VERSION', `/confCF_VERSION')
DZ8.14.1`'ifdef(`confCF_VERSION', `/confCF_VERSION')

View File

@ -1,6 +1,6 @@
PUSHDIVERT(-1)
#
# Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers.
# Copyright (c) 1998-2001, 2006 Sendmail, Inc. and its suppliers.
# All rights reserved.
# Copyright (c) 1983 Eric P. Allman. All rights reserved.
# Copyright (c) 1988, 1993
@ -13,6 +13,8 @@ PUSHDIVERT(-1)
#
_DEFIFNOT(`_DEF_SMTP_MAILER_FLAGS', `mDFMuX')
_DEFIFNOT(`SMTP_MAILER_FLAGS',`')
_DEFIFNOT(`SMTP_MAILER_LL',`990')
_DEFIFNOT(`RELAY_MAILER_LL',`2040')
_DEFIFNOT(`RELAY_MAILER_FLAGS', `SMTP_MAILER_FLAGS')
ifdef(`SMTP_MAILER_ARGS',, `define(`SMTP_MAILER_ARGS', `TCP $h')')
ifdef(`ESMTP_MAILER_ARGS',, `define(`ESMTP_MAILER_ARGS', `TCP $h')')
@ -29,7 +31,7 @@ POPDIVERT
### SMTP Mailer specification ###
#####################################
VERSIONID(`$Id: smtp.m4,v 8.64 2001/04/03 01:52:54 gshapiro Exp $')
VERSIONID(`$Id: smtp.m4,v 8.65 2006/07/12 21:08:10 ca Exp $')
#
# common sender and masquerading recipient rewriting
@ -105,18 +107,18 @@ SMasqRelay
R$+ $: $>MasqSMTP $1
R$+ $: $>MasqHdr $1
Msmtp, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, SMTP_MAILER_FLAGS), `SMTP'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=990,
Msmtp, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, SMTP_MAILER_FLAGS), `SMTP'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=SMTP_MAILER_LL,
_OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_MAXMSGS', `m=', `, ')_OPTINS(`SMTP_MAILER_MAXRCPTS', `r=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP,_SMTP_QGRP
A=SMTP_MAILER_ARGS
Mesmtp, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `a', SMTP_MAILER_FLAGS), `ESMTP'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=990,
Mesmtp, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `a', SMTP_MAILER_FLAGS), `ESMTP'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=SMTP_MAILER_LL,
_OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_MAXMSGS', `m=', `, ')_OPTINS(`SMTP_MAILER_MAXRCPTS', `r=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP,_ESMTP_QGRP
A=ESMTP_MAILER_ARGS
Msmtp8, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `8', SMTP_MAILER_FLAGS), `SMTP8'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=990,
Msmtp8, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `8', SMTP_MAILER_FLAGS), `SMTP8'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=SMTP_MAILER_LL,
_OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_MAXMSGS', `m=', `, ')_OPTINS(`SMTP_MAILER_MAXRCPTS', `r=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP,_SMTP8_QGRP
A=SMTP8_MAILER_ARGS
Mdsmtp, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `a%', SMTP_MAILER_FLAGS), `DSMTP'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=990,
Mdsmtp, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `a%', SMTP_MAILER_FLAGS), `DSMTP'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `EnvToSMTP/HdrFromSMTP', `EnvToSMTP'), E=\r\n, L=SMTP_MAILER_LL,
_OPTINS(`SMTP_MAILER_MAX', `M=', `, ')_OPTINS(`SMTP_MAILER_MAXMSGS', `m=', `, ')_OPTINS(`SMTP_MAILER_MAXRCPTS', `r=', `, ')_OPTINS(`SMTP_MAILER_CHARSET', `C=', `, ')T=DNS/RFC822/SMTP,_DSMTP_QGRP
A=DSMTP_MAILER_ARGS
Mrelay, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `a8', RELAY_MAILER_FLAGS), `RELAY'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `MasqSMTP/MasqRelay', `MasqSMTP'), E=\r\n, L=2040,
Mrelay, P=[IPC], F=_MODMF_(CONCAT(_DEF_SMTP_MAILER_FLAGS, `a8', RELAY_MAILER_FLAGS), `RELAY'), S=EnvFromSMTP/HdrFromSMTP, R=ifdef(`_ALL_MASQUERADE_', `MasqSMTP/MasqRelay', `MasqSMTP'), E=\r\n, L=RELAY_MAILER_LL,
_OPTINS(`RELAY_MAILER_CHARSET', `C=', `, ')_OPTINS(`RELAY_MAILER_MAXMSGS', `m=', `, ')_OPTINS(`SMTP_MAILER_MAXRCPTS', `r=', `, ')T=DNS/RFC822/SMTP,_RELAY_QGRP
A=RELAY_MAILER_ARGS

View File

@ -1,13 +1,13 @@
#!/usr/bin/perl -w
# $Id: cidrexpand,v 8.4.2.1 2006/08/07 17:22:10 ca Exp $
# $Id: cidrexpand,v 8.8 2006/08/07 17:18:37 ca Exp $
#
# v 0.4
#
# 17 July 2000 Derek J. Balling (dredd@megacity.org)
#
#
# Acts as a preparser on /etc/mail/access_db to allow you to use address/bit
# notation.
# notation.
#
# If you have two overlapping CIDR blocks with conflicting actions
# e.g. 10.2.3.128/25 REJECT and 10.2.3.143 ACCEPT
@ -25,15 +25,25 @@
# Added code to deal with the prefix tags that may now be included in
# the access_db
#
# Added clarification in the notes for what to do if you have
# Added clarification in the notes for what to do if you have
# exceptions to a larger CIDR block.
#
# 26 Jul 2006 Richard Rognlie (richard@sendmail.com>
# Added code to strip "comments" (anything after a non-escaped #)
# # characters after a \ or within quotes (single and double) are
# left intact.
#
# e.g.
# From:1.2.3.4 550 Die spammer # spammed us 2006.07.26
# becomes
# From:1.2.3.4 550 Die spammer
#
# 3 August 2006
#
# Corrected a bug to have it handle the special case of "0.0.0.0/0"
# since Net::CIDR doesn't handle it properly.
#
# usage:
# usage:
# cidrexpand < /etc/mail/access | makemap -r hash /etc/mail/access
#
#
@ -43,32 +53,59 @@
use strict;
use Net::CIDR;
use Getopt::Std;
our ($opt_c,$opt_t);
getopts('ct:');
my $spaceregex = '\s+';
while (my $arg = shift @ARGV)
if ($opt_t)
{
if ($arg eq '-t')
{
$spaceregex = shift;
}
$spaceregex = $opt_t;
}
use strict;
my $SENDMAIL = 1;
while (<>)
{
chomp;
my ($prefix,$left,$right,$space);
if ( (/\#/) && $opt_c )
{
# print "checking...\n";
my $i;
my $qtype='';
for ($i=0 ; $i<length($_) ; $i++)
{
my $ch = substr($_,$i,1);
if ($ch eq '\\')
{
$i++;
next;
}
elsif ($qtype eq '' && $ch eq '#')
{
substr($_,$i) = '';
last;
}
elsif ($qtype ne '' && $ch eq $qtype)
{
$qtype = '';
}
elsif ($qtype eq '' && $ch =~ /[\'\"]/)
{
$qtype = $ch;
}
}
}
if (! /^(|\S\S*:)(\d+\.){3}\d+\/\d\d?$spaceregex.*/ )
{
print;
print "$_\n";
}
else
{
($prefix,$left,$space,$right) = /^(|\S\S*:)((?:\d+\.){3}\d+\/\d\d?)($spaceregex)(.*)$/;
($prefix,$left,$space,$right) =
/^(|\S\S*:)((?:\d+\.){3}\d+\/\d\d?)($spaceregex)(.*)$/;
my @new_lefts = expand_network($left);
foreach my $nl (@new_lefts)
@ -77,7 +114,7 @@ while (<>)
}
}
}
sub expand_network
{
my $left_input = shift;

View File

@ -3,7 +3,7 @@
## Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers.
## All rights reserved.
##
## $Id: qtool.pl,v 8.28 2002/06/27 23:06:16 gshapiro Exp $
## $Id: qtool.pl,v 8.29 2007/02/16 01:12:08 ca Exp $
##
use strict;
use File::Basename;
@ -69,6 +69,12 @@ my $new_condition;
my $qprefix;
my $queuegroups = 0;
my $conditions = new Compound();
my $fcntl_struct = 's H60';
my $fcntl_structlockp = pack($fcntl_struct, Fcntl::F_WRLCK,
"000000000000000000000000000000000000000000000000000000000000");
my $fcntl_structunlockp = pack($fcntl_struct, Fcntl::F_UNLCK,
"000000000000000000000000000000000000000000000000000000000000");
my $lock_both = -1;
Getopt::Std::getopts('bC:de:Qs:', \%opts);
@ -340,7 +346,9 @@ sub add_source
## Opens a file for read/write and uses flock to obtain a lock on the
## file. The flock is Perl's flock which defaults to flock on systems
## that support it. On systems without flock it falls back to fcntl
## locking.
## locking. This script will also call fcntl explicitly if flock
## uses BSD semantics (i.e. if both flock() and fcntl() can successfully
## lock the file at the same time)
##
## Parameters:
## file_name -- The name of the file to open and lock.
@ -358,6 +366,24 @@ sub lock_file
my $file_name = shift;
my $result;
if ($lock_both == -1)
{
if (open(DEVNULL, '>/dev/null'))
{
my $flock_status = flock(DEVNULL, Fcntl::LOCK_EX | Fcntl::LOCK_NB);
my $fcntl_status = fcntl (DEVNULL, Fcntl::F_SETLK, $fcntl_structlockp);
close(DEVNULL);
$lock_both = ($flock_status && $fcntl_status);
}
else
{
# Couldn't open /dev/null. Windows system?
$lock_both = 0;
}
}
$result = sysopen(FILE_TO_LOCK, $file_name, Fcntl::O_RDWR);
if (!$result)
{
@ -370,6 +396,15 @@ sub lock_file
return (undef, "Could not obtain lock on '$file_name': $!");
}
if ($lock_both)
{
my $result2 = fcntl (FILE_TO_LOCK, Fcntl::F_SETLK, $fcntl_structlockp);
if (!$result2)
{
return (undef, "Could not obtain fcntl lock on '$file_name': $!");
}
}
return (\*FILE_TO_LOCK, undef);
}
@ -396,6 +431,14 @@ sub unlock_file
{
return "Unlock failed on '$result': $!";
}
if ($lock_both)
{
my $result2 = fcntl ($file, Fcntl::F_SETLK, $fcntl_structunlockp);
if (!$result2)
{
return (undef, "Fcntl unlock failed on '$result': $!");
}
}
return undef;
}

View File

@ -9,7 +9,7 @@
.\" the sendmail distribution.
.\"
.\"
.\" $Id: op.me,v 8.708 2005/11/12 02:08:04 ca Exp $
.\" $Id: op.me,v 8.739 2007/03/22 17:56:01 ca Exp $
.\"
.\" eqn op.me | pic | troff -me
.\"
@ -90,10 +90,10 @@ Sendmail, Inc.
.de Ve
Version \\$2
..
.Ve $Revision: 8.708 $
.Ve $Revision: 8.739 $
.rm Ve
.sp
For Sendmail Version 8.13
For Sendmail Version 8.14
.)l
.(f
Sendmail is a trademark of Sendmail, Inc.
@ -982,7 +982,7 @@ This should be a link to /usr/\*(SD/sendmail.
.sh 3 "sendmail.pid"
.pp
.i sendmail
stores its current pid in the file specifed by the
stores its current pid in the file specified by the
.b PidFile
option (default is _PATH_SENDMAILPID).
.i sendmail
@ -4259,6 +4259,13 @@ It can accept or reject mail transfer between these two addresses
much like the
.i checkcompat()
function.
Note:
while other
.i check_*
rulesets are invoked during the SMTP mail receiption stage
(i.e., in the SMTP server),
.i check_compat
is invoked during the mail delivery stage.
.sh 4 "check_eoh"
.pp
The
@ -4310,6 +4317,13 @@ Keep in mind the Message-Id: header is not a required header and
is not a guaranteed spam indicator.
This ruleset is an example and
should probably not be used in production.
.sh 4 "check_eom"
.pp
The
.i check_eom
ruleset is called after the end of a message,
its parameter is the message size.
It can accept or reject the message.
.sh 4 "check_etrn"
.pp
The
@ -4827,9 +4841,6 @@ This macro contains up to three characters, the first
is either `e' or `h' for envelope/header address,
the second is a space,
and the third is either `s' or `r' for sender/recipient address.
Notice: for header addresses no distinction is currently made
between sender and recipient addresses, i.e., the macro contains
only `h'.
.ip ${alg_bits}
The maximum keylength (in bits) of the symmetric encryption algorithm
used for a TLS connection.
@ -4878,6 +4889,18 @@ IPv6 addresses are tagged with "IPv6:" before the address.
Defined in the SMTP server only.
.ip ${client_connections}
The number of open connections in the SMTP server for the client IP address.
.ip ${client_flags}
The flags specified by the
Modifier= part of
.b ClientPortOptions
where flags are separated from each other by spaces
and upper case flags are doubled.
That is,
Modifier=hA
will be represented as
"h AA" in
.b ${client_flags} ,
which is required for testing the flags in rulesets.
.ip ${client_name}
The host name of the SMTP client.
This may be the client's bracketed IP address
@ -6666,6 +6689,7 @@ A running
daemon can be controlled through this named socket.
Available commands are:
.i help,
.i mstat,
.i restart,
.i shutdown,
and
@ -6711,6 +6735,11 @@ Listen Size of listen queue (defaults to 10)
Modifier Options (flags) for the daemon
SndBufSize Size of TCP send buffer
RcvBufSize Size of TCP receive buffer
children maximum number of children per daemon, see \fBMaxDaemonChildren\fP.
DeliveryMode Delivery mode per daemon, see \fBDeliveryMode\fP.
refuseLA RefuseLA per daemon
delayLA DelayLA per daemon
queueLA QueueLA per daemon
.)b
The
.i Name
@ -7176,11 +7205,9 @@ will search first in /var/forward/\c
and then in
.i ~username /.forward
(but only if the first file does not exist).
.ip HelpFile=\fIfile\fP
[H]
Specify the help file
for SMTP.
If no file name is specified, "helpfile" is used.
.ip HeloName=\fIname\fP
[no short name]
Set the name to be used for HELO/EHLO (instead of $j).
.ip HoldExpensive
[c]
If an outgoing mailer is marked as being expensive,
@ -7305,7 +7332,7 @@ If the limit should be enforced, then a
.b DeliveryMode
other than background must be used.
If not set, there is no limit to the number of children --
that is, the system load averaging controls this.
that is, the system load average controls this.
.ip MaxHeadersLength=\fIN\fP
[no short name]
The maximum length of the sum of all headers.
@ -7346,6 +7373,13 @@ will be used.
By default,
these values are 2048 and 1024, respectively.
To allow any length, a value of 0 can be specified.
.ip MaxNOOPCommands=\fIN\fP
Override the default of
.b MAXNOOPCOMMANDS
for the number of
.i useless
commands, see Section
"Measures against Denial of Service Attacks".
.ip MaxQueueChildren=\fIN\fP
[no short name]
When set, this limits the number of concurrent queue runner processes to
@ -7385,6 +7419,16 @@ highest priority jobs)
this should be set as high as possible to avoid
.q losing
jobs that happen to fall late in the queue directory.
Note: this option also restricts the number of entries printed by
.i mailq .
That is, if
.i MaxQueueRunSize
is set to a value
.b N
larger than zero,
then only
.b N
entries are printed per queue group.
.ip MaxRecipientsPerMessage=\fIN\fP
[no short name]
The maximum number of recipients that will be accepted per message
@ -7428,9 +7472,11 @@ after a certain event occurred.
.(b
.ta \w'envfrom'u+3n
connect After session connection start
helo After HELO command
envfrom After MAIL FROM command
envrcpt After RCPT TO command
helo After EHLO/HELO command
envfrom After MAIL From command
envrcpt After RCPT To command
data After DATA command.
eoh After DATA command and header
eom After DATA command and terminating ``.''
.)b
By default the lists of macros are empty.
@ -7560,7 +7606,7 @@ The
.i opt ions
can be selected from:
.(b
.ta \w'needvrfyhelo'u+3n
.ta \w'noactualrecipient'u+3n
public Allow open access
needmailhelo Insist on HELO or EHLO command before MAIL
needexpnhelo Insist on HELO or EHLO command before EXPN
@ -7577,6 +7623,8 @@ nobodyreturn Don't return the body of a message with DSNs
goaway Disallow essentially all SMTP status queries
authwarnings Put X-Authentication-Warning: headers in messages
and log warnings
noactualrecipient Don't put X-Actual-Recipient lines in DSNs
which reveal the actual account that addresses map to.
.)b
.(f
\**N.B.:
@ -7914,20 +7962,6 @@ UNIX-style
lines at the front of headers.
Normally they are assumed redundant
and discarded.
.ip SharedMemoryKey
[no short name]
Key to use for shared memory segment;
if not set (or 0), shared memory will not be used.
Requires support for shared memory to be compiled into
.i sendmail .
If this option is set,
.i sendmail
can share some data between different instances.
For example, the number of entries in a queue directory
or the available space in a file system.
This allows for more efficient program execution, since only
one process needs to update the data instead of each individual
process gathering the data each time it is required.
.ip SendMimeErrors
[j]
If set, send error messages in MIME format
@ -7986,6 +8020,34 @@ The default file is
[7]
Strip input to seven bits for compatibility with old systems.
This shouldn't be necessary.
.ip SharedMemoryKey
[no short name]
Key to use for shared memory segment;
if not set (or 0), shared memory will not be used.
If set to
-1
.i sendmail
can select a key itself provided that also
.b SharedMemoryKeyFile
is set.
Requires support for shared memory to be compiled into
.i sendmail .
If this option is set,
.i sendmail
can share some data between different instances.
For example, the number of entries in a queue directory
or the available space in a file system.
This allows for more efficient program execution, since only
one process needs to update the data instead of each individual
process gathering the data each time it is required.
.ip SharedMemoryKeyFile
[no short name]
If
.b SharedMemoryKey
is set to
-1
then the automatically selected shared memory key will be stored
in the specified file.
.ip SingleLineFromHeader
[no short name]
If set, From: lines that have embedded newlines are unwrapped
@ -8023,6 +8085,10 @@ option.
The message printed when the SMTP server starts up.
Defaults to
.q "$j Sendmail $v ready at $b".
.ip SoftBounce
If set, issue temporary errors (4xy) instead of permanent errors (5xy).
This can be useful during testing of a new configuration to avoid
erroneous bouncing of mails.
.ip StatusFile=\fIfile\fP
[S]
Log summary statistics in the named
@ -8817,16 +8883,21 @@ R$\- $: $(storage {MyMacro} $) $1
.)b
.ip arith
Perform simple arithmetic operations.
The operation is given as key, currently +, -, *, /, %,
The operation is given as key, currently
+, -, *, /, %,
|, & (bitwise OR, AND),
l (for less than), and = are supported.
l (for less than), =,
and r (for random) are supported.
The two operands are given as arguments.
The lookup returns the result of the computation,
i.e.
i.e.,
.sm TRUE
or
.sm FALSE
for comparisons, integer values otherwise.
The r operator returns a pseudo-random number whose value
lies between the first and second operand
(which requires that the first operand is smaller than the second).
All options which are possible for maps are ignored.
A simple example is:
.(b
@ -8983,6 +9054,10 @@ For LDAP maps this is an LDAP filter string
in which %s is replaced with the literal contents of the lookup key
and %0 is replaced with the LDAP escaped contents of the lookup key
according to RFC 2254.
If the flag
.b \-K
is used, then %1 through %9 are replaced with the LDAP escaped contents
of the arguments specified in the map lookup.
.ip "\-v\fIvalcol\fP"
The value column name (for NIS+) or number
(for text lookups).
@ -9007,6 +9082,8 @@ to combine multiple values
into a single return string.
If not set,
the LDAP lookup will only return the first match found.
For DNS maps this is the separator character at which
the result of a query is cut off if is too long.
.ip "\-t"
Normally, when a map attempts to do a lookup
and the server fails
@ -9072,6 +9149,10 @@ delay: specify the resolver's retransmission time interval (in seconds).
.ip "\-r"
retry: specify the number of times to retransmit a resolver query.
.pp
The dns map has another flag:
.ip "\-B"
basedomain: specify a domain that is always appended to queries.
.pp
The following additional flags are present in the ldap map only:
.ip "\-R"
Do not auto chase referrals. sendmail must be compiled with
@ -9130,7 +9211,7 @@ LDAP search base.
.ip "\-l\fItimelimit\fP"
Time limit for LDAP queries.
.ip "\-Z\fIsizelimit\fP"
Size (number of matches) limit for LDAP queries.
Size (number of matches) limit for LDAP or DNS queries.
.ip "\-d\fIdistinguished_name\fP"
The distinguished name to use to login to the LDAP server.
.ip "\-M\fImethod\fP"
@ -9158,6 +9239,10 @@ For example,
will cause
.i sendmail
to use LDAPv3 when communicating with the LDAP server.
.ip "\-K"
Treat the LDAP search key as multi-argument and
replace %1 through %9 in the key with
the LDAP escaped contents of the lookup arguments specified in the map lookup.
.pp
The
.i dbm
@ -11339,7 +11424,7 @@ replace it with a blank sheet for double-sided output.
.\".sz 10
.\"Eric Allman
.\".sp
.\"Version $Revision: 8.708 $
.\"Version $Revision: 8.739 $
.\".ce 0
.bp 3
.ce

View File

@ -1,7 +1,8 @@
dnl $Id: Makefile.m4,v 1.5 2002/06/21 22:01:30 ca Exp $
dnl $Id: Makefile.m4,v 1.6 2006/06/28 21:08:01 ca Exp $
include(confBUILDTOOLSDIR`/M4/switch.m4')
define(`confREQUIRE_LIBSM', `true')
define(`confREQUIRE_SM_OS_H', `true')
# sendmail dir
SMSRCDIR= ifdef(`confSMSRCDIR', `confSMSRCDIR', `${SRCDIR}/sendmail')
PREPENDDEF(`confENVDEF', `confMAPDEF')

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2004 Sendmail, Inc. and its suppliers.
* Copyright (c) 1999-2004, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -7,7 +7,7 @@
* the sendmail distribution.
*
*
* $Id: mfapi.h,v 8.61 2006/05/04 17:02:01 ca Exp $
* $Id: mfapi.h,v 8.77 2006/11/02 02:44:07 ca Exp $
*/
/*
@ -18,9 +18,13 @@
# define _LIBMILTER_MFAPI_H 1
#ifndef SMFI_VERSION
# define SMFI_VERSION 2 /* version number */
# define SMFI_VERSION 0x01000000 /* libmilter version number */
#endif /* ! SMFI_VERSION */
#define SM_LM_VRS_MAJOR(v) (((v) & 0x7f000000) >> 24)
#define SM_LM_VRS_MINOR(v) (((v) & 0x007fff00) >> 8)
#define SM_LM_VRS_PLVL(v) ((v) & 0x0000007f)
# include <sys/types.h>
# include <sys/socket.h>
@ -40,11 +44,14 @@ extern "C" {
/*
** libmilter functions return one of the following to indicate
** success/failure:
** success/failure(/continue):
*/
#define MI_SUCCESS 0
#define MI_FAILURE (-1)
#if _FFR_WORKERS_POOL
# define MI_CONTINUE 1
#endif /* _FFR_WORKERS_POOL */
/* "forward" declarations */
typedef struct smfi_str SMFICTX;
@ -128,15 +135,24 @@ struct smfiDesc
/* connection cleanup */
sfsistat (*xxfi_close) SM__P((SMFICTX *));
#if SMFI_VERSION > 2
/* any unrecognized or unimplemented command filter */
sfsistat (*xxfi_unknown) SM__P((SMFICTX *, char *));
#endif /* SMFI_VERSION > 2 */
sfsistat (*xxfi_unknown) SM__P((SMFICTX *, const char *));
#if SMFI_VERSION > 3
/* SMTP DATA command filter */
sfsistat (*xxfi_data) SM__P((SMFICTX *));
#endif /* SMFI_VERSION > 3 */
/* negotiation callback */
sfsistat (*xxfi_negotiate) SM__P((SMFICTX *,
unsigned long, unsigned long,
unsigned long, unsigned long,
unsigned long *, unsigned long *,
unsigned long *, unsigned long *));
#if 0
/* signal handler callback, not yet implemented. */
int (*xxfi_signal) SM__P((int));
#endif
};
LIBMILTER_API int smfi_opensocket __P((bool));
@ -150,6 +166,7 @@ LIBMILTER_API int smfi_stop __P((void));
#if _FFR_MAXDATASIZE
LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t));
#endif /* _FFR_MAXDATASIZE */
LIBMILTER_API int smfi_version __P((unsigned int *, unsigned int *, unsigned int *));
/*
** What the filter might do -- values to be ORed together for
@ -165,6 +182,33 @@ LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t));
#define SMFIF_CHGHDRS 0x00000010L /* filter may change/delete headers */
#define SMFIF_QUARANTINE 0x00000020L /* filter may quarantine envelope */
/* filter may change "from" (envelope sender) */
#define SMFIF_CHGFROM 0x00000040L
#define SMFIF_ADDRCPT_PAR 0x00000080L /* add recipients incl. args */
/* filter can send set of symbols (macros) that it wants */
#define SMFIF_SETSYMLIST 0x00000100L
/*
** Macro "places";
** Notes:
** - must be coordinated with libmilter/engine.c and sendmail/milter.c
** - the order MUST NOT be changed as it would break compatibility between
** different versions. It's ok to append new entries however
** (hence the list is not sorted by the SMT protocol steps).
*/
#define SMFIM_FIRST 0 /* Do NOT use, internal marker only */
#define SMFIM_CONNECT 0 /* connect */
#define SMFIM_HELO 1 /* HELO/EHLO */
#define SMFIM_ENVFROM 2 /* MAIL From */
#define SMFIM_ENVRCPT 3 /* RCPT To */
#define SMFIM_DATA 4 /* DATA */
#define SMFIM_EOM 5 /* end of message (final dot) */
#define SMFIM_EOH 6 /* end of header */
#define SMFIM_LAST 6 /* Do NOT use, internal marker only */
/*
** Continue processing message/connection.
*/
@ -209,6 +253,21 @@ LIBMILTER_API size_t smfi_setmaxdatasize __P((size_t));
#define SMFIS_TEMPFAIL 4
/*
** Do not send a reply to the MTA
*/
#define SMFIS_NOREPLY 7
/*
** Skip over rest of same callbacks, e.g., body.
*/
#define SMFIS_SKIP 8
/* xxfi_negotiate: use all existing protocol options/actions */
#define SMFIS_ALL_OPTS 10
#if 0
/*
** Filter Routine Details
@ -261,12 +320,12 @@ extern sfsistat xxfi_envrcpt __P((SMFICTX *, char **));
/* unknown command filter */
extern sfsistat *xxfi_unknown __P((SMFICTX *, char *));
extern sfsistat *xxfi_unknown __P((SMFICTX *, const char *));
/*
** xxfi_unknown(ctx, arg) Invoked when SMTP command is not recognized or not
** implemented.
** char *arg; Null-terminated SMTP command
** const char *arg; Null-terminated SMTP command
*/
/* header filter */
@ -414,6 +473,17 @@ LIBMILTER_API int smfi_insheader __P((SMFICTX *, int, char *, char *));
** char *headerv; Header field value
*/
LIBMILTER_API int smfi_chgfrom __P((SMFICTX *, char *, char *));
/*
** Modify envelope sender address
**
** SMFICTX *ctx; Opaque context structure
** char *mail; New envelope sender address
** char *args; ESMTP arguments
*/
LIBMILTER_API int smfi_addrcpt __P((SMFICTX *, char *));
/*
@ -423,6 +493,17 @@ LIBMILTER_API int smfi_addrcpt __P((SMFICTX *, char *));
** char *rcpt; Recipient to be added
*/
LIBMILTER_API int smfi_addrcpt_par __P((SMFICTX *, char *, char *));
/*
** Add a recipient to the envelope
**
** SMFICTX *ctx; Opaque context structure
** char *rcpt; Recipient to be added
** char *args; ESMTP arguments
*/
LIBMILTER_API int smfi_delrcpt __P((SMFICTX *, char *));
/*
@ -486,6 +567,27 @@ LIBMILTER_API int smfi_setpriv __P((SMFICTX *, void *));
LIBMILTER_API void *smfi_getpriv __P((SMFICTX *));
/*
** Get the private data pointer
**
** SMFICTX *ctx; Opaque context structure
** void *privatedata; Pointer to private data area
*/
LIBMILTER_API int smfi_setsymlist __P((SMFICTX *, int, char *));
/*
** Set list of symbols (macros) to receive
**
** SMFICTX *ctx; Opaque context structure
** int where; where in the SMTP dialogue should the macros be sent
** char *macros; list of macros (space separated)
*/
#if _FFR_THREAD_MONITOR
LIBMILTER_API int smfi_set_max_exec_time __P((unsigned int));
#endif /* _FFR_THREAD_MONITOR */
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2005 Sendmail, Inc. and its suppliers.
* Copyright (c) 1999-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -7,7 +7,7 @@
* the sendmail distribution.
*
*
* $Id: mfdef.h,v 8.22 2005/08/05 21:49:04 ca Exp $
* $Id: mfdef.h,v 8.38 2007/03/27 18:53:48 ca Exp $
*/
/*
@ -17,83 +17,94 @@
#ifndef _LIBMILTER_MFDEF_H
# define _LIBMILTER_MFDEF_H 1
#ifndef SMFI_PROT_VERSION
# define SMFI_PROT_VERSION 6 /* MTA - libmilter protocol version */
#endif /* SMFI_PROT_VERSION */
/* Shared protocol constants */
# define MILTER_LEN_BYTES 4 /* length of 32 bit integer in bytes */
# define MILTER_OPTLEN (MILTER_LEN_BYTES * 3) /* length of options */
# define MILTER_CHUNK_SIZE 65535 /* body chunk size */
# define MILTER_MAX_DATA_SIZE 65535 /* default milter command data limit */
#define MILTER_LEN_BYTES 4 /* length of 32 bit integer in bytes */
#define MILTER_OPTLEN (MILTER_LEN_BYTES * 3) /* length of options */
#define MILTER_CHUNK_SIZE 65535 /* body chunk size */
#define MILTER_MAX_DATA_SIZE 65535 /* default milter command data limit */
/* These apply to SMFIF_* flags */
#define SMFI_V1_ACTS 0x0000000FL /* The actions of V1 filter */
#define SMFI_V2_ACTS 0x0000003FL /* The actions of V2 filter */
#define SMFI_CURR_ACTS SMFI_V2_ACTS /* The current version */
#define SMFI_CURR_ACTS 0x000001FFL /* actions of current version */
/* address families */
# define SMFIA_UNKNOWN 'U' /* unknown */
# define SMFIA_UNIX 'L' /* unix/local */
# define SMFIA_INET '4' /* inet */
# define SMFIA_INET6 '6' /* inet6 */
#define SMFIA_UNKNOWN 'U' /* unknown */
#define SMFIA_UNIX 'L' /* unix/local */
#define SMFIA_INET '4' /* inet */
#define SMFIA_INET6 '6' /* inet6 */
/* commands: don't use anything smaller than ' ' */
# define SMFIC_ABORT 'A' /* Abort */
# define SMFIC_BODY 'B' /* Body chunk */
# define SMFIC_CONNECT 'C' /* Connection information */
# define SMFIC_MACRO 'D' /* Define macro */
# define SMFIC_BODYEOB 'E' /* final body chunk (End) */
# define SMFIC_HELO 'H' /* HELO/EHLO */
# define SMFIC_HEADER 'L' /* Header */
# define SMFIC_MAIL 'M' /* MAIL from */
# define SMFIC_EOH 'N' /* EOH */
# define SMFIC_OPTNEG 'O' /* Option negotiation */
# define SMFIC_QUIT 'Q' /* QUIT */
# define SMFIC_RCPT 'R' /* RCPT to */
# if SMFI_VERSION > 3
# define SMFIC_DATA 'T' /* DATA */
# endif /* SMFI_VERSION > 3 */
# if SMFI_VERSION > 2
# define SMFIC_UNKNOWN 'U' /* Any unknown command */
# endif /* SMFI_VERSION > 2 */
#define SMFIC_ABORT 'A' /* Abort */
#define SMFIC_BODY 'B' /* Body chunk */
#define SMFIC_CONNECT 'C' /* Connection information */
#define SMFIC_MACRO 'D' /* Define macro */
#define SMFIC_BODYEOB 'E' /* final body chunk (End) */
#define SMFIC_HELO 'H' /* HELO/EHLO */
#define SMFIC_QUIT_NC 'K' /* QUIT but new connection follows */
#define SMFIC_HEADER 'L' /* Header */
#define SMFIC_MAIL 'M' /* MAIL from */
#define SMFIC_EOH 'N' /* EOH */
#define SMFIC_OPTNEG 'O' /* Option negotiation */
#define SMFIC_QUIT 'Q' /* QUIT */
#define SMFIC_RCPT 'R' /* RCPT to */
#define SMFIC_DATA 'T' /* DATA */
#define SMFIC_UNKNOWN 'U' /* Any unknown command */
/* actions (replies) */
# define SMFIR_ADDRCPT '+' /* add recipient */
# define SMFIR_DELRCPT '-' /* remove recipient */
# define SMFIR_ACCEPT 'a' /* accept */
# define SMFIR_REPLBODY 'b' /* replace body (chunk) */
# define SMFIR_CONTINUE 'c' /* continue */
# define SMFIR_DISCARD 'd' /* discard */
# define SMFIR_CONN_FAIL 'f' /* cause a connection failure */
# define SMFIR_CHGHEADER 'm' /* change header */
# define SMFIR_PROGRESS 'p' /* progress */
# define SMFIR_REJECT 'r' /* reject */
# define SMFIR_TEMPFAIL 't' /* tempfail */
# define SMFIR_SHUTDOWN '4' /* 421: shutdown (internal to MTA) */
# define SMFIR_ADDHEADER 'h' /* add header */
# define SMFIR_INSHEADER 'i' /* insert header */
# define SMFIR_REPLYCODE 'y' /* reply code etc */
# define SMFIR_QUARANTINE 'q' /* quarantine */
#define SMFIR_ADDRCPT '+' /* add recipient */
#define SMFIR_DELRCPT '-' /* remove recipient */
#define SMFIR_ADDRCPT_PAR '2' /* add recipient (incl. ESMTP args) */
#define SMFIR_SHUTDOWN '4' /* 421: shutdown (internal to MTA) */
#define SMFIR_ACCEPT 'a' /* accept */
#define SMFIR_REPLBODY 'b' /* replace body (chunk) */
#define SMFIR_CONTINUE 'c' /* continue */
#define SMFIR_DISCARD 'd' /* discard */
#define SMFIR_CHGFROM 'e' /* change envelope sender (from) */
#define SMFIR_CONN_FAIL 'f' /* cause a connection failure */
#define SMFIR_ADDHEADER 'h' /* add header */
#define SMFIR_INSHEADER 'i' /* insert header */
#define SMFIR_SETSYMLIST 'l' /* set list of symbols (macros) */
#define SMFIR_CHGHEADER 'm' /* change header */
#define SMFIR_PROGRESS 'p' /* progress */
#define SMFIR_QUARANTINE 'q' /* quarantine */
#define SMFIR_REJECT 'r' /* reject */
#define SMFIR_SKIP 's' /* skip */
#define SMFIR_TEMPFAIL 't' /* tempfail */
#define SMFIR_REPLYCODE 'y' /* reply code etc */
/* What the MTA can send/filter wants in protocol */
# define SMFIP_NOCONNECT 0x00000001L /* MTA should not send connect info */
# define SMFIP_NOHELO 0x00000002L /* MTA should not send HELO info */
# define SMFIP_NOMAIL 0x00000004L /* MTA should not send MAIL info */
# define SMFIP_NORCPT 0x00000008L /* MTA should not send RCPT info */
# define SMFIP_NOBODY 0x00000010L /* MTA should not send body */
# define SMFIP_NOHDRS 0x00000020L /* MTA should not send headers */
# define SMFIP_NOEOH 0x00000040L /* MTA should not send EOH */
# if _FFR_MILTER_NOHDR_RESP
# define SMFIP_NOHREPL 0x00000080L /* No reply for headers */
# endif /* _FFR_MILTER_NOHDR_RESP */
# define SMFIP_NOUNKNOWN 0x00000100L /* MTA should not send unknown command */
# define SMFIP_NODATA 0x00000200L /* MTA should not send DATA */
#define SMFIP_NOCONNECT 0x00000001L /* MTA should not send connect info */
#define SMFIP_NOHELO 0x00000002L /* MTA should not send HELO info */
#define SMFIP_NOMAIL 0x00000004L /* MTA should not send MAIL info */
#define SMFIP_NORCPT 0x00000008L /* MTA should not send RCPT info */
#define SMFIP_NOBODY 0x00000010L /* MTA should not send body */
#define SMFIP_NOHDRS 0x00000020L /* MTA should not send headers */
#define SMFIP_NOEOH 0x00000040L /* MTA should not send EOH */
#define SMFIP_NR_HDR 0x00000080L /* No reply for headers */
#define SMFIP_NOHREPL SMFIP_NR_HDR /* No reply for headers */
#define SMFIP_NOUNKNOWN 0x00000100L /* MTA should not send unknown commands */
#define SMFIP_NODATA 0x00000200L /* MTA should not send DATA */
#define SMFIP_SKIP 0x00000400L /* MTA understands SMFIS_SKIP */
#define SMFIP_RCPT_REJ 0x00000800L /* MTA should also send rejected RCPTs */
#define SMFIP_NR_CONN 0x00001000L /* No reply for connect */
#define SMFIP_NR_HELO 0x00002000L /* No reply for HELO */
#define SMFIP_NR_MAIL 0x00004000L /* No reply for MAIL */
#define SMFIP_NR_RCPT 0x00008000L /* No reply for RCPT */
#define SMFIP_NR_DATA 0x00010000L /* No reply for DATA */
#define SMFIP_NR_UNKN 0x00020000L /* No reply for UNKN */
#define SMFIP_NR_EOH 0x00040000L /* No reply for eoh */
#define SMFIP_NR_BODY 0x00080000L /* No reply for body chunk */
#define SMFIP_HDR_LEADSPC 0x00100000L /* header value leading space */
# define SMFI_V1_PROT 0x0000003FL /* The protocol of V1 filter */
# define SMFI_V2_PROT 0x0000007FL /* The protocol of V2 filter */
#define SMFI_V1_PROT 0x0000003FL /* The protocol of V1 filter */
#define SMFI_V2_PROT 0x0000007FL /* The protocol of V2 filter */
/* Note: the "current" version is now determined dynamically in milter.c */
# if _FFR_MILTER_NOHDR_RESP
# define SMFI_CURR_PROT 0x000000FFL
# else /* _FFR_MILTER_NOHDR_RESP */
# define SMFI_CURR_PROT SMFI_V2_PROT
# endif /* _FFR_MILTER_NOHDR_RESP */
/* all defined protocol bits */
#define SMFI_CURR_PROT 0x001FFFFFL
#endif /* !_LIBMILTER_MFDEF_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers.
* Copyright (c) 1999-2003, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -7,7 +7,7 @@
* the sendmail distribution.
*
*
* $Id: milter.h,v 8.39 2003/12/02 00:21:42 msk Exp $
* $Id: milter.h,v 8.41 2006/05/22 23:23:55 ca Exp $
*/
/*
@ -25,31 +25,4 @@
typedef pthread_t sthread_t;
typedef int socket_t;
# define MAX_MACROS_ENTRIES 5 /* max size of macro pointer array */
/*
** context for milter
** implementation hint:
** macros are stored in mac_buf[] as sequence of:
** macro_name \0 macro_value
** (just as read from the MTA)
** mac_ptr is a list of pointers into mac_buf to the beginning of each
** entry, i.e., macro_name, macro_value, ...
*/
struct smfi_str
{
sthread_t ctx_id; /* thread id */
socket_t ctx_sd; /* socket descriptor */
int ctx_dbg; /* debug level */
time_t ctx_timeout; /* timeout */
int ctx_state; /* state */
smfiDesc_ptr ctx_smfi; /* filter description */
unsigned long ctx_pflags; /* protocol flags */
char **ctx_mac_ptr[MAX_MACROS_ENTRIES];
char *ctx_mac_buf[MAX_MACROS_ENTRIES];
char *ctx_reply; /* reply code */
void *ctx_privdata; /* private data */
};
#endif /* ! _LIBMILTER_MILTER_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998-2006 Sendmail, Inc. and its suppliers.
* Copyright (c) 1998-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@ -10,14 +10,16 @@
* the sendmail distribution.
*
*
* $Id: conf.h,v 1.128 2006/01/27 18:43:44 ca Exp $
* $Id: conf.h,v 1.132 2007/03/21 23:56:18 ca Exp $
*/
/*
** CONF.H -- All user-configurable parameters for sendmail
**
** Send updates to sendmail@Sendmail.ORG so they will be
** included in the next release.
** Send updates to Sendmail.ORG so they will be
** included in the next release; see
** http://www.sendmail.org/email-addresses.html
** for current e-mail address.
*/
#ifndef SM_CONF_H
@ -160,6 +162,8 @@ extern void hard_syslog();
*/
# ifdef _AIX5
# include <sys/signal.h>
# include <sys/wait.h>
# define _AIX4 40300
# define SOCKADDR_LEN_T socklen_t /* e.g., arg#3 to accept, getsockname */
# define SOCKOPT_LEN_T socklen_t /* arg#5 to getsockopt */
@ -444,6 +448,7 @@ typedef int pid_t;
# define SMRSH_CMDDIR "/var/adm/sm.bin"
# endif /* ! SMRSH_CMDDIR */
# define SL_FUDGE 34 /* fudge offset for SyslogPrefixLen */
# define HASLDAPGETALIASBYNAME 1 /* added in S8 */
# endif /* SOLARIS >= 20800 || (SOLARIS < 10000 && SOLARIS >= 208) */
# if SOLARIS >= 20900 || (SOLARIS < 10000 && SOLARIS >= 209)
# define HASURANDOMDEV 1 /* /dev/[u]random added in S9 */
@ -852,36 +857,64 @@ extern unsigned int sleepX __P((unsigned int seconds));
# endif /* __bsdi__ */
# if defined(__QNX__)
# if defined(__QNXNTO__)
/* QNX 6 */
# include <unix.h>
# define HASUNSETENV 1 /* has unsetenv(3) call */
# define HASINITGROUPS 1 /* has initgroups(3) call */
# define HASSETSID 1 /* has POSIX setsid(2) call */
# define USESETEUID 1 /* has usable seteuid(2) call */
# define HASFCHMOD 1 /* has fchmod(2) syscall */
# define HASFCHOWN 1 /* has fchown(2) syscall */
# define HASUNAME 1 /* has uname(2) syscall */
# define HASSTRERROR 1 /* has strerror(3) */
# define BSD4_4_SOCKADDR /* has sa_len */
# define ERRLIST_PREDEFINED /* don't declare sys_errlist */
# define NETLINK 1 /* supports AF_LINK */
# define GIDSET_T gid_t
# define QUAD_T uint64_t
# define HASSNPRINTF 1 /* has snprintf(3) (all versions?) */
# define HASGETUSERSHELL 0
/*
** We have a strrev() that doesn't allocate anything.
** Make sure the one here is used.
*/
# define strrev strrev_sendmail
# else /* defined(__QNXNTO__) */
/*
** QNX 4.2x
** Contributed by Glen McCready <glen@qnx.com>.
**
** Should work with all versions of QNX.
** Should work with all versions of QNX 4.
*/
# if defined(__QNX__)
# include <unix.h>
# include <sys/select.h>
# undef NGROUPS_MAX
# define HASSETSID 1 /* has POSIX setsid(2) call */
# define USESETEUID 1 /* has usable seteuid(2) call */
# define HASFCHMOD 1 /* has fchmod(2) syscall */
# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */
# define HASSETREUID 1 /* has setreuid(2) call */
# define HASSTRERROR 1 /* has strerror(3) */
# define HASFLOCK 0
# undef HASINITGROUPS /* has initgroups(3) call */
# define SM_CONF_GETOPT 0 /* need a replacement for getopt(3) */
# define IP_SRCROUTE 1 /* can check IP source routing */
# define TZ_TYPE TZ_TMNAME /* use tmname variable */
# define GIDSET_T gid_t
# define LA_TYPE LA_ZERO
# define SFS_TYPE SFS_NONE
# define SPT_TYPE SPT_REUSEARGV
# define SPT_PADCHAR '\0' /* pad process title with nulls */
# define HASGETUSERSHELL 0
# define E_PSEUDOBASE 512
# define _FILE_H_INCLUDED
# include <unix.h>
# include <sys/select.h>
# undef NGROUPS_MAX
# define HASSETSID 1 /* has POSIX setsid(2) call */
# define USESETEUID 1 /* has usable seteuid(2) call */
# define HASFCHMOD 1 /* has fchmod(2) syscall */
# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */
# define HASSETREUID 1 /* has setreuid(2) call */
# define HASSTRERROR 1 /* has strerror(3) */
# define HASFLOCK 0
# undef HASINITGROUPS /* has initgroups(3) call */
# define SM_CONF_GETOPT 0 /* need a replacement for getopt(3) */
# define IP_SRCROUTE 1 /* can check IP source routing */
# define TZ_TYPE TZ_TMNAME /* use tmname variable */
# define GIDSET_T gid_t
# define LA_TYPE LA_ZERO
# define SFS_TYPE SFS_NONE
# define SPT_TYPE SPT_REUSEARGV
# define SPT_PADCHAR '\0' /* pad process title with nulls */
# define HASGETUSERSHELL 0
# define _FILE_H_INCLUDED
# endif /* defined(__QNXNTO__) */
# endif /* defined(__QNX__) */

View File

@ -6,7 +6,7 @@
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: errstring.h,v 1.9 2003/12/10 03:19:06 gshapiro Exp $
* $Id: errstring.h,v 1.10 2007/03/21 23:56:19 ca Exp $
*/
/*
@ -16,6 +16,10 @@
#ifndef SM_ERRSTRING_H
# define SM_ERRSTRING_H
#if defined(__QNX__)
# define E_PSEUDOBASE 512
#endif /* defined(__QNX__) */
#include <errno.h>
#if NEEDINTERRNO
extern int errno;

View File

@ -1,12 +1,12 @@
/*
* Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
* Copyright (c) 2000-2001, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: heap.h,v 1.22 2001/09/04 22:41:55 ca Exp $
* $Id: heap.h,v 1.23 2006/08/15 00:53:46 ca Exp $
*/
/*
@ -91,6 +91,16 @@ sm_fcalloc __P((
# define sm_heap_setgroup(g) (SmHeapGroup = (g))
# define sm_heap_newgroup() (SmHeapGroup = ++SmHeapMaxGroup)
#define SM_FREE(ptr) \
do \
{ \
if ((ptr) != NULL) \
{ \
sm_free(ptr); \
(ptr) = NULL; \
} \
} while (0)
extern int SmHeapGroup;
extern int SmHeapMaxGroup;

View File

@ -1,12 +1,12 @@
/*
* Copyright (c) 2001-2003, 2005 Sendmail, Inc. and its suppliers.
* Copyright (c) 2001-2003, 2005, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: ldap.h,v 1.28 2005/06/23 23:11:21 ca Exp $
* $Id: ldap.h,v 1.32 2006/08/30 22:56:58 ca Exp $
*/
#ifndef SM_LDAP_H
@ -17,7 +17,7 @@
/*
** NOTE: These should be changed from LDAPMAP_* to SM_LDAP_*
** in the next major release (8.13) of sendmail.
** in the next major release (8.x+1) of sendmail.
*/
# ifndef LDAPMAP_MAX_ATTR
@ -32,6 +32,13 @@
# if LDAPMAP
/* maximum number of arguments in a map lookup, see sendmail.h: MAX_MAP_ARGS */
# define SM_LDAP_ARGS 10
/* error codes from sm_ldap_search*() */
# define SM_LDAP_ERR (-1) /* generic error: ldap_search(3) */
# define SM_LDAP_ERR_ARG_MISS (-2) /* an argument is missing */
/* Attribute types */
# define SM_LDAP_ATTR_NONE (-1)
# define SM_LDAP_ATTR_OBJCLASS 0
@ -75,6 +82,7 @@ struct sm_ldap_struct
int ldap_attr_type[LDAPMAP_MAX_ATTR + 1];
char *ldap_attr_needobjclass[LDAPMAP_MAX_ATTR + 1];
bool ldap_attrsonly;
bool ldap_multi_args;
/* args for ldap_result */
struct timeval ldap_timeout;
@ -91,18 +99,18 @@ typedef struct sm_ldap_struct SM_LDAP_STRUCT;
struct sm_ldap_recurse_entry
{
char *lr_search;
int lr_type;
LDAPURLDesc *lr_ludp;
char **lr_attrs;
bool lr_done;
char *lr_search;
int lr_type;
LDAPURLDesc *lr_ludp;
char **lr_attrs;
bool lr_done;
};
struct sm_ldap_recurse_list
{
int lr_size;
int lr_cnt;
struct sm_ldap_recurse_entry **lr_data;
int lrl_size;
int lrl_cnt;
struct sm_ldap_recurse_entry **lrl_data;
};
typedef struct sm_ldap_recurse_entry SM_LDAP_RECURSE_ENTRY;
@ -112,6 +120,7 @@ typedef struct sm_ldap_recurse_list SM_LDAP_RECURSE_LIST;
extern void sm_ldap_clear __P((SM_LDAP_STRUCT *));
extern bool sm_ldap_start __P((char *, SM_LDAP_STRUCT *));
extern int sm_ldap_search __P((SM_LDAP_STRUCT *, char *));
extern int sm_ldap_search_m __P((SM_LDAP_STRUCT *, char **));
extern int sm_ldap_results __P((SM_LDAP_STRUCT *, int, int, int,
SM_RPOOL_T *, char **, int *, int *,
SM_LDAP_RECURSE_LIST *));

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: misc.h,v 1.1 2006/06/28 23:57:59 ca Exp $
*/
#ifndef SM_MISC_H
# define SM_MISC_H 1
int sm_memstat_open __P((void));
int sm_memstat_close __P((void));
int sm_memstat_get __P((char *, long *));
#endif /* ! SM_MISC_H */

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: sm_os_qnx.h,v 1.1 2007/03/21 23:56:20 ca Exp $
*/
/*
** sm_os_qnx.h -- platform definitions for QNX
*/
#define SM_CONF_SYS_CDEFS_H 1
#ifndef SM_CONF_SETITIMER
# define SM_CONF_SETITIMER 0
#endif /* SM_CONF_SETITIMER */

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*/
/*
** SENDMAIL.H -- MTA-specific definitions for sendmail.
*/
#ifndef _SM_SENDMAIL_H
# define _SM_SENDMAIL_H 1
/* "out of band" indicator */
#define METAQUOTE ((unsigned char)0377) /* quotes the next octet */
extern int dequote_internal_chars __P((char *, char *, int));
extern char *quote_internal_chars __P((char *, char *, int *));
extern char *str2prt __P((char *));
#endif /* ! _SM_SENDMAIL_H */

View File

@ -0,0 +1,153 @@
/* $OpenBSD: queue.h,v 1.30 2005/10/25 06:37:47 otto Exp $ */
/* $NetBSD: queue.h,v 1.11 1996/05/16 05:17:14 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef SM_TAILQ_H_
#define SM_TAILQ_H_
/*
* This file is a modified copy of queue.h from a BSD system:
* we only need tail queues here.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*/
/*
* Tail queue definitions.
*/
#define SM_TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
#define SM_TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define SM_TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
}
/*
* tail queue access methods
*/
#define SM_TAILQ_FIRST(head) ((head)->tqh_first)
#define SM_TAILQ_END(head) NULL
#define SM_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define SM_TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
#define SM_TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define SM_TAILQ_EMPTY(head) \
(SM_TAILQ_FIRST(head) == SM_TAILQ_END(head))
#define SM_TAILQ_FOREACH(var, head, field) \
for((var) = SM_TAILQ_FIRST(head); \
(var) != SM_TAILQ_END(head); \
(var) = SM_TAILQ_NEXT(var, field))
#define SM_TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for((var) = SM_TAILQ_LAST(head, headname); \
(var) != SM_TAILQ_END(head); \
(var) = SM_TAILQ_PREV(var, headname, field))
/*
* Tail queue functions.
*/
#define SM_TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
#define SM_TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
#define SM_TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
#define SM_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
#define SM_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
#define SM_TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (0)
#define SM_TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
else \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
} while (0)
#endif /* !SM_TAILQ_H_ */

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 8.1 1999/11/04 00:03:40 ca Exp $
# $Id: Makefile,v 8.2 2006/05/23 21:55:55 ca Exp $
SHELL= /bin/sh
BUILD= ./Build
@ -6,6 +6,8 @@ OPTIONS= $(CONFIG) $(FLAGS)
all: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
check: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC

View File

@ -1,19 +1,19 @@
dnl $Id: Makefile.m4,v 8.31 2002/06/21 22:01:31 ca Exp $
dnl $Id: Makefile.m4,v 8.78 2007/02/05 19:21:29 ca Exp $
include(confBUILDTOOLSDIR`/M4/switch.m4')
dnl only required for compilation of EXTRAS
define(`confREQUIRE_LIBSM', `true')
define(`confREQUIRE_SM_OS_H', `true')
define(`confMT', `true')
# sendmail dir
SMSRCDIR= ifdef(`confSMSRCDIR', `confSMSRCDIR', `${SRCDIR}/sendmail')
SMSRCDIR=ifdef(`confSMSRCDIR', `confSMSRCDIR', `${SRCDIR}/sendmail')
PREPENDDEF(`confINCDIRS', `-I${SMSRCDIR} ')
bldPRODUCT_START(`library', `libmilter')
define(`bldINSTALLABLE', `true')
define(`LIBMILTER_EXTRAS', `errstring.c strl.c')
APPENDDEF(`confENVDEF', `-DNOT_SENDMAIL -Dsm_snprintf=snprintf')
define(`bldSOURCES', `main.c engine.c listener.c handler.c comm.c smfi.c signal.c sm_gethost.c LIBMILTER_EXTRAS ')
define(`bldSOURCES', `main.c engine.c listener.c worker.c handler.c comm.c smfi.c signal.c sm_gethost.c monitor.c LIBMILTER_EXTRAS ')
define(`confBEFORE', `LIBMILTER_EXTRAS')
bldPUSH_INSTALL_TARGET(`install-mfapi')
bldPRODUCT_END

View File

@ -90,8 +90,10 @@ IPv4 socket on port 3333 of localhost. The current flags (F=) are:
R Reject connection if filter unavailable
T Temporary fail connection if filter unavailable
4 Shut down connection if filter unavailable
(with a 421 temporary error).
If neither F=R nor F=T is specified, the message is passed through sendmail
If none of these is specified, the message is passed through sendmail
in case of filter errors as if the failing filters were not present.
Finally, you can override the default timeouts used by sendmail when
@ -164,7 +166,7 @@ connected via one of these options, the session can be continued through
the use of standard SMTP commands.
% sendmail -bs
220 test.sendmail.com ESMTP Sendmail 8.11.0/8.11.0; Tue, 10 Nov 1970 13:05:23 -0500 (EST)
220 test.sendmail.com ESMTP Sendmail 8.14.0/8.14.0; Thu, 22 Jun 2006 13:05:23 -0500 (EST)
HELO localhost
250 test.sendmail.com Hello testy@localhost, pleased to meet you
MAIL From:<testy>
@ -225,248 +227,8 @@ Feedback about problems (and possible fixes) is welcome.
| SOURCE FOR SAMPLE FILTER |
+--------------------------+
Note that the filter below may not be thread safe on some operating
Note that the filter example.c may not be thread safe on some operating
systems. You should check your system man pages for the functions used
below to verify the functions are thread safe.
/* A trivial filter that logs all email to a file. */
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include "libmilter/mfapi.h"
#ifndef true
typedef int bool;
# define false 0
# define true 1
#endif /* ! true */
struct mlfiPriv
{
char *mlfi_fname;
FILE *mlfi_fp;
};
#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx))
extern sfsistat mlfi_cleanup(SMFICTX *, bool);
sfsistat
mlfi_envfrom(ctx, envfrom)
SMFICTX *ctx;
char **envfrom;
{
struct mlfiPriv *priv;
int fd = -1;
/* allocate some private memory */
priv = malloc(sizeof *priv);
if (priv == NULL)
{
/* can't accept this message right now */
return SMFIS_TEMPFAIL;
}
memset(priv, '\0', sizeof *priv);
/* open a file to store this message */
priv->mlfi_fname = strdup("/tmp/msg.XXXXXXXX");
if (priv->mlfi_fname == NULL)
{
free(priv);
return SMFIS_TEMPFAIL;
}
if ((fd = mkstemp(priv->mlfi_fname)) < 0 ||
(priv->mlfi_fp = fdopen(fd, "w+")) == NULL)
{
if (fd >= 0)
(void) close(fd);
free(priv->mlfi_fname);
free(priv);
return SMFIS_TEMPFAIL;
}
/* save the private data */
smfi_setpriv(ctx, priv);
/* continue processing */
return SMFIS_CONTINUE;
}
sfsistat
mlfi_header(ctx, headerf, headerv)
SMFICTX *ctx;
char *headerf;
char *headerv;
{
/* write the header to the log file */
fprintf(MLFIPRIV->mlfi_fp, "%s: %s\r\n", headerf, headerv);
/* continue processing */
return SMFIS_CONTINUE;
}
sfsistat
mlfi_eoh(ctx)
SMFICTX *ctx;
{
/* output the blank line between the header and the body */
fprintf(MLFIPRIV->mlfi_fp, "\r\n");
/* continue processing */
return SMFIS_CONTINUE;
}
sfsistat
mlfi_body(ctx, bodyp, bodylen)
SMFICTX *ctx;
u_char *bodyp;
size_t bodylen;
{
/* output body block to log file */
if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0)
{
/* write failed */
(void) mlfi_cleanup(ctx, false);
return SMFIS_TEMPFAIL;
}
/* continue processing */
return SMFIS_CONTINUE;
}
sfsistat
mlfi_eom(ctx)
SMFICTX *ctx;
{
return mlfi_cleanup(ctx, true);
}
sfsistat
mlfi_close(ctx)
SMFICTX *ctx;
{
return SMFIS_ACCEPT;
}
sfsistat
mlfi_abort(ctx)
SMFICTX *ctx;
{
return mlfi_cleanup(ctx, false);
}
sfsistat
mlfi_cleanup(ctx, ok)
SMFICTX *ctx;
bool ok;
{
sfsistat rstat = SMFIS_CONTINUE;
struct mlfiPriv *priv = MLFIPRIV;
char *p;
char host[512];
char hbuf[1024];
if (priv == NULL)
return rstat;
/* close the archive file */
if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF)
{
/* failed; we have to wait until later */
rstat = SMFIS_TEMPFAIL;
(void) unlink(priv->mlfi_fname);
}
else if (ok)
{
/* add a header to the message announcing our presence */
if (gethostname(host, sizeof host) < 0)
snprintf(host, sizeof host, "localhost");
p = strrchr(priv->mlfi_fname, '/');
if (p == NULL)
p = priv->mlfi_fname;
else
p++;
snprintf(hbuf, sizeof hbuf, "%s@%s", p, host);
smfi_addheader(ctx, "X-Archived", hbuf);
}
else
{
/* message was aborted -- delete the archive file */
(void) unlink(priv->mlfi_fname);
}
/* release private memory */
free(priv->mlfi_fname);
free(priv);
smfi_setpriv(ctx, NULL);
/* return status */
return rstat;
}
struct smfiDesc smfilter =
{
"SampleFilter", /* filter name */
SMFI_VERSION, /* version code -- do not change */
SMFIF_ADDHDRS, /* flags */
NULL, /* connection info filter */
NULL, /* SMTP HELO command filter */
mlfi_envfrom, /* envelope sender filter */
NULL, /* envelope recipient filter */
mlfi_header, /* header filter */
mlfi_eoh, /* end of header */
mlfi_body, /* body block filter */
mlfi_eom, /* end of message */
mlfi_abort, /* message aborted */
mlfi_close /* connection cleanup */
};
int
main(argc, argv)
int argc;
char *argv[];
{
bool setconn = false;
int c;
const char *args = "p:";
/* Process command line options */
while ((c = getopt(argc, argv, args)) != -1)
{
switch (c)
{
case 'p':
if (optarg == NULL || *optarg == '\0')
{
(void) fprintf(stderr, "Illegal conn: %s\n",
optarg);
exit(EX_USAGE);
}
(void) smfi_setconn(optarg);
setconn = true;
break;
}
}
if (!setconn)
{
fprintf(stderr, "%s: Missing required -p argument\n", argv[0]);
exit(EX_USAGE);
}
if (smfi_register(smfilter) == MI_FAILURE)
{
fprintf(stderr, "smfi_register failed\n");
exit(EX_UNAVAILABLE);
}
return smfi_main();
}
/* eof */
$Revision: 8.41 $, Last updated $Date: 2005/04/27 22:47:42 $
$Revision: 8.42 $, Last updated $Date: 2006/06/29 17:10:16 $

View File

@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: comm.c,v 8.66 2004/08/20 20:38:35 ca Exp $")
SM_RCSID("@(#)$Id: comm.c,v 8.67 2006/11/02 17:54:44 ca Exp $")
#include "libmilter.h"
#include <sm/errstring.h>
@ -352,7 +352,7 @@ mi_wr_cmd(sd, timeout, cmd, buf, len)
iov[1].iov_len = len;
iovcnt = 2;
}
l = retry_writev(sd, iov, iovcnt, timeout);
if (l == MI_FAILURE)
return MI_FAILURE;

View File

@ -1,233 +1,320 @@
<html>
<head><title>Milter API</title></head>
<body>
<HTML>
<HEAD><TITLE>Milter API</TITLE></HEAD>
<BODY>
<!--
$Id: api.html,v 1.18 2004/04/28 23:26:51 msk Exp $
$Id: api.html,v 1.35 2006/11/30 23:09:23 ca Exp $
-->
<h1>Milter API</h1>
<H1>Milter API</H1>
<h2>Contents</h2>
<ul>
<li>Library Control Functions
<li>Data Access Functions
<li>Message Modification Functions
<li>Callbacks
</ul>
<H2>Contents</H2>
<UL>
<LI><A HREF="#LibraryControlFunctions">Library Control Functions</A>
<LI><A HREF="#DataAccessFunctions">Data Access Functions</A>
<LI><A HREF="#MessageModificationFunctions">Message Modification Functions</A>
<LI><A HREF="#Callbacks">Callbacks</A>
<LI><A HREF="#Miscellaneous">Miscellaneous</A>
</UL>
<h2>Library Control Functions</h2>
<H2><A NAME="LibraryControlFunctions">Library Control Functions</A></H2>
Before handing control to libmilter (by calling <a
href="smfi_main.html">smfi_main</a>), a filter may call the following
functions to set libmilter parameters. In particular, the filter must
call <a href="smfi_register.html">smfi_register</a> to register its
callbacks. Each function will return either MI_SUCCESS or MI_FAILURE to
Before handing control to libmilter (by calling
<A HREF="smfi_main.html">smfi_main</A>), a filter may call the following
functions to set libmilter parameters.
In particular, the filter must call
<A HREF="smfi_register.html">smfi_register</A> to register its callbacks.
Each function will return either MI_SUCCESS or MI_FAILURE to
indicate the status of the operation.
<p>
<P>
None of these functions communicate with the MTA. All alter the
library's state, some of which is communicated to the MTA inside <a
href="smfi_main.html">smfi_main</a>.
<p>
<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th></tr>
library's state, some of which is communicated to the MTA inside
<A HREF="smfi_main.html">smfi_main</A>.
<tr><td><a href="smfi_opensocket.html">smfi_opensocket</a></td><td>Try to create the interface socket.</td></tr>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR>
<tr><td><a href="smfi_register.html">smfi_register</a></td><td>Register a filter.</td></tr>
<TR><TD><A HREF="smfi_opensocket.html">smfi_opensocket</A></TD><TD>Try to create the interface socket.</TD></TR>
<tr><td><a href="smfi_setconn.html">smfi_setconn</a></td><td>Specify socket to use.</td></tr>
<TR><TD><A HREF="smfi_register.html">smfi_register</A></TD><TD>Register a filter.</TD></TR>
<tr><td><a href="smfi_settimeout.html">smfi_settimeout</a></td><td>Set timeout.</td></tr>
<TR><TD><A HREF="smfi_setconn.html">smfi_setconn</A></TD><TD>Specify socket to use.</TD></TR>
<tr><td><a href="smfi_setbacklog.html">smfi_setbacklog</a></td><td>Define the incoming <i>listen</i>(2) queue size.</td></tr>
<TR><TD><A HREF="smfi_settimeout.html">smfi_settimeout</A></TD><TD>Set timeout.</TD></TR>
<tr><td><a href="smfi_setdbg.html">smfi_setdbg</a></td><td>Set the milter library debugging (tracing) level.</td></tr>
<TR><TD><A HREF="smfi_setbacklog.html">smfi_setbacklog</A></TD><TD>Define the incoming <CODE>listen(2)</CODE> queue size.</TD></TR>
<tr><td><a href="smfi_stop.html">smfi_stop</a></td><td>Cause an orderly shutdown.</td></tr>
<TR><TD><A HREF="smfi_setdbg.html">smfi_setdbg</A></TD><TD>Set the milter library debugging (tracing) level.</TD></TR>
<tr><td><a href="smfi_main.html">smfi_main</a></td><td>Hand control to libmilter.</td></tr>
<TR><TD><A HREF="smfi_stop.html">smfi_stop</A></TD><TD>Cause an orderly shutdown.</TD></TR>
</table>
<TR><TD><A HREF="smfi_main.html">smfi_main</A></TD><TD>Hand control to libmilter.</TD></TR>
<h2>Data Access Functions</h2>
</TABLE>
<H2><A NAME="DataAccessFunctions">Data Access Functions</A></H2>
The following functions may be called from within the filter-defined callbacks
to access information about the current connection or message.
<p>
<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th></tr>
<tr><td><a href="smfi_getsymval.html">smfi_getsymval</a></td><td>Return the value
of a symbol.</td></tr>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR bgcolor="#dddddd"><TH>Function</TH><TH>Description</TH></TR>
<TR><TD><A HREF="smfi_getsymval.html">smfi_getsymval</A></TD><TD>Return the value
of a symbol.</TD></TR>
<tr><td><a href="smfi_getpriv.html">smfi_getpriv</a></td><td>Get the private data
pointer.</td></tr>
<TR><TD><A HREF="smfi_getpriv.html">smfi_getpriv</A></TD><TD>Get the private data
pointer.</TD></TR>
<tr><td><a href="smfi_setpriv.html">smfi_setpriv</a></td><td>Set the private data
pointer.</td></tr>
<TR><TD><A HREF="smfi_setpriv.html">smfi_setpriv</A></TD><TD>Set the private data
pointer.</TD></TR>
<tr><td><a href="smfi_setreply.html">smfi_setreply</a></td><td>Set the specific
reply code to be used.</td></tr>
<TR><TD><A HREF="smfi_setreply.html">smfi_setreply</A></TD><TD>Set the specific
reply code to be used.</TD></TR>
<tr><td><a href="smfi_setmlreply.html">smfi_setmlreply</a></td><td>Set the
specific multi-line reply to be used.</td></tr>
<TR><TD><A HREF="smfi_setmlreply.html">smfi_setmlreply</A></TD><TD>Set the
specific multi-line reply to be used.</TD></TR>
</table>
</TABLE>
<h2>Message Modification Functions</h2>
<H2><A NAME="MessageModificationFunctions">Message Modification Functions</A></H2>
The following functions change a message's contents and attributes.
<b>They may only be called in <a href="xxfi_eom.html">xxfi_eom</a></b>.
<EM>They may only be called in <A HREF="xxfi_eom.html">xxfi_eom</A></EM>.
All of these functions may invoke additional communication with the MTA.
They will return either MI_SUCCESS or MI_FAILURE to indicate the status of
the operation.
<p>
<P>
A filter must have set the appropriate flag (listed below) in the
description passed to <a href="smfi_register.html">smfi_register</a>
description passed to <A HREF="smfi_register.html">smfi_register</A>
to call any message modification function. Failure to do so will
cause the MTA to treat a call to the function as a failure of the
filter, terminating its connection.
<p>
<P>
Note that the status returned indicates only whether or not the
filter's message was successfully sent to the MTA, not whether or not
the MTA performed the requested operation. For example, <a
href="smfi_addheader.html">smfi_addheader</a>, when called with an
the MTA performed the requested operation. For example,
<A HREF="smfi_addheader.html">smfi_addheader</A>, when called with an
illegal header name, will return MI_SUCCESS even though the MTA may
later refuse to add the illegal header.
<p>
<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th><th>SMFIF_* flag</tr>
<tr><td><a href="smfi_addheader.html">smfi_addheader</a></td><td>Add a header to
the message.</td><td>SMFIF_ADDHDRS</td></tr>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH><TH>SMFIF_* flag</TR>
<TR><TD><A HREF="smfi_addheader.html">smfi_addheader</A></TD><TD>Add a header to
the message.</TD><TD>SMFIF_ADDHDRS</TD></TR>
<tr><td><a href="smfi_chgheader.html">smfi_chgheader</a></td><td>Change or delete a header.</td><td>SMFIF_CHGHDRS</td></tr>
<TR><TD><A HREF="smfi_chgheader.html">smfi_chgheader</A></TD><TD>Change or delete a header.</TD><TD>SMFIF_CHGHDRS</TD></TR>
<tr><td><a href="smfi_insheader.html">smfi_insheader</a></td><td>Insert a
header into the message.</td><td>SMFIF_ADDHDRS</td></tr>
<TR><TD><A HREF="smfi_insheader.html">smfi_insheader</A></TD><TD>Insert a
header into the message.</TD><TD>SMFIF_ADDHDRS</TD></TR>
<tr><td><a href="smfi_addrcpt.html">smfi_addrcpt</a></td><td>Add a recipient to
the envelope.</td><td>SMFIF_ADDRCPT</td></tr>
<TR><TD><A HREF="smfi_chgfrom.html">smfi_chgfrom</A></TD><TD>Change the
envelope sender address.</TD><TD>SMFIF_CHGFROM</TD></TR>
<tr><td><a href="smfi_delrcpt.html">smfi_delrcpt</a></td><td>Delete a recipient
from the envelope.</td><td>SMFIF_DELRCPT</td></tr>
<TR><TD><A HREF="smfi_addrcpt.html">smfi_addrcpt</A></TD><TD>Add a recipient to
the envelope.</TD><TD>SMFIF_ADDRCPT</TD></TR>
<tr><td><a href="smfi_replacebody.html">smfi_replacebody</a></td><td>Replace the
body of the message.</td><td>SMFIF_CHGBODY</td></tr>
<TR><TD><A HREF="smfi_addrcpt_par.html">smfi_addrcpt_par</A></TD><TD>Add
a recipient including ESMTP parameter to the envelope.
</TD><TD>SMFIF_ADDRCPT_PAR</TD></TR>
</table>
<TR><TD><A HREF="smfi_delrcpt.html">smfi_delrcpt</A></TD><TD>Delete a recipient
from the envelope.</TD><TD>SMFIF_DELRCPT</TD></TR>
<h2>Other Message Handling Functions</h2>
<TR><TD><A HREF="smfi_replacebody.html">smfi_replacebody</A></TD><TD>Replace the
body of the message.</TD><TD>SMFIF_CHGBODY</TD></TR>
</TABLE>
<H2>Other Message Handling Functions</H2>
The following functions provide special case handling instructions for
milter or the MTA, without altering the content or status of the message.
<b>They too may only be called in <a href="xxfi_eom.html">xxfi_eom</a></b>.
<EM>They too may only be called in <A HREF="xxfi_eom.html">xxfi_eom</A></EM>.
All of these functions may invoke additional communication with the MTA.
They will return either MI_SUCCESS or MI_FAILURE to indicate the status of
the operation.
<p>
<P>
Note that the status returned indicates only whether or not the
filter's message was successfully sent to the MTA, not whether or not
the MTA performed the requested operation.
<p>
<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th></tr>
<tr><td><a href="smfi_progress.html">smfi_progress</a></td><td>Report operation in progress.</td></tr>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR>
<TR><TD><A HREF="smfi_progress.html">smfi_progress</A></TD><TD>Report operation in progress.</TD></TR>
<tr><td><a href="smfi_quarantine.html">smfi_quarantine</a></td><td>Quarantine a message.</td></tr>
<TR><TD><A HREF="smfi_quarantine.html">smfi_quarantine</A></TD><TD>Quarantine a message.</TD></TR>
</table>
</TABLE>
<h2><a name="callbacks">Callbacks</a></h2>
<H2><A NAME="Callbacks">Callbacks</A></H2>
The filter should implement one or more of the following callbacks,
which are registered via <a href="smfi_register.html">smfi_register</a>:
<p>
<table border="1" cellspacing=0 cellpadding=2><tr bgcolor="#dddddd"><th>Function</th><th>Description</th></tr>
which are registered via <A HREF="smfi_register.html">smfi_register</A>:
<tr><td><a href="xxfi_connect.html">xxfi_connect</a></td><td>connection info</td></tr>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR>
<tr><td><a href="xxfi_helo.html">xxfi_helo</a></td><td>SMTP HELO/EHLO command</td></tr>
<TR><TD><A HREF="xxfi_connect.html">xxfi_connect</A></TD><TD>connection info</TD></TR>
<tr><td><a href="xxfi_envfrom.html">xxfi_envfrom</a></td><td>envelope sender</td></tr>
<TR><TD><A HREF="xxfi_helo.html">xxfi_helo</A></TD><TD>SMTP HELO/EHLO command</TD></TR>
<tr><td><a href="xxfi_envrcpt.html">xxfi_envrcpt</a></td><td>envelope recipient</td></tr>
<TR><TD><A HREF="xxfi_envfrom.html">xxfi_envfrom</A></TD><TD>envelope sender</TD></TR>
<tr><td><a href="xxfi_header.html">xxfi_header</a></td><td>header</td></tr>
<TR><TD><A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A></TD><TD>envelope recipient</TD></TR>
<tr><td><a href="xxfi_eoh.html">xxfi_eoh</a></td><td>end of header</td></tr>
<TR><TD><A HREF="xxfi_data.html">xxfi_data</A></TD><TD>DATA command</TD></TR>
<tr><td><a href="xxfi_body.html">xxfi_body</a></td><td>body block</td></tr>
<TR><TD><A HREF="xxfi_unknown.html">xxfi_unknown</A></TD><TD>Unknown SMTP command</TD></TR>
<tr><td><a href="xxfi_eom.html">xxfi_eom</a></td><td>end of message</td></tr>
<TR><TD><A HREF="xxfi_header.html">xxfi_header</A></TD><TD>header</TD></TR>
<tr><td><a href="xxfi_abort.html">xxfi_abort</a></td><td>message aborted</td></tr>
<TR><TD><A HREF="xxfi_eoh.html">xxfi_eoh</A></TD><TD>end of header</TD></TR>
<tr><td><a href="xxfi_close.html">xxfi_close</a></td><td>connection cleanup</td></tr>
<TR><TD><A HREF="xxfi_body.html">xxfi_body</A></TD><TD>body block</TD></TR>
</table>
<TR><TD><A HREF="xxfi_eom.html">xxfi_eom</A></TD><TD>end of message</TD></TR>
<p>
<TR><TD><A HREF="xxfi_abort.html">xxfi_abort</A></TD><TD>message aborted</TD></TR>
<TR><TD><A HREF="xxfi_close.html">xxfi_close</A></TD><TD>connection cleanup</TD></TR>
<TR><TD><A HREF="xxfi_negotiate.html">xxfi_negotiate</A></TD><TD>option negotiattion</TD></TR>
</TABLE>
<P>
The above callbacks should all return one of the following return values,
having the indicated meanings. Any return other than one of the below
values constitutes an error, and will cause sendmail to terminate its
connection to the offending filter.
<p><a name="conn-spec">Milter</a> distinguishes between recipient-,
<P><A NAME="conn-spec">Milter</A> distinguishes between recipient-,
message-, and connection-oriented routines. Recipient-oriented
callbacks may affect the processing of a single message recipient;
message-oriented callbacks, a single message; connection-oriented
callbacks, an entire connection (during which multiple messages may be
delivered to multiple sets of recipients).
<a href="xxfi_envrcpt.html">xxfi_envrcpt</a> is recipient-oriented.
<a href="xxfi_connect.html">xxfi_connect</a>,
<a href="xxfi_helo.html">xxfi_helo</a> and
<a href="xxfi_close.html">xxfi_close</a> are connection-oriented. All
<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A> is recipient-oriented.
<A HREF="xxfi_connect.html">xxfi_connect</A>,
<A HREF="xxfi_helo.html">xxfi_helo</A> and
<A HREF="xxfi_close.html">xxfi_close</A> are connection-oriented. All
other callbacks are message-oriented.
<p>
<table border="1" cellspacing=0 cellpadding=2>
<tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr>
<tr valign="top">
<td>SMFIS_CONTINUE</td>
<td>Continue processing the current connection, message, or recipient.
</td>
</tr>
<tr valign="top">
<td>SMFIS_REJECT</td>
<td>For a connection-oriented routine, reject this connection; call <a href="xxfi_close.html">xxfi_close</a>.<br>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2>
<TR BGCOLOR="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR VALIGN="TOP">
<TD>SMFIS_CONTINUE</TD>
<TD>Continue processing the current connection, message, or recipient.
</TD>
</TR>
<TR VALIGN="TOP">
<TD>SMFIS_REJECT</TD>
<TD>For a connection-oriented routine, reject this connection; call <A HREF="xxfi_close.html">xxfi_close</A>.<BR>
For a message-oriented routine (except
<a href="xxfi_eom.html">xxfi_eom</a> or
<a href="xxfi_abort.html">xxfi_abort</a>), reject this message.<br>
<A HREF="xxfi_eom.html">xxfi_eom</A> or
<A HREF="xxfi_abort.html">xxfi_abort</A>), reject this message.<BR>
For a recipient-oriented routine, reject the current recipient (but continue processing the current message).
</td>
</tr>
<tr valign="top">
<td>SMFIS_DISCARD</td>
<td>For a message- or recipient-oriented routine, accept this message, but silently discard it.<br>
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_DISCARD</TD>
<TD>For a message- or recipient-oriented routine, accept this message, but silently discard it.<BR>
SMFIS_DISCARD should not be returned by a connection-oriented routine.
</td>
</tr>
<tr valign="top">
<td>SMFIS_ACCEPT</td>
<td>For a connection-oriented routine, accept this connection without further filter processing; call <a href="xxfi_close.html">xxfi_close</a>.<br>
For a message- or recipient-oriented routine, accept this message without further filtering.<br>
</td>
</tr>
<tr valign="top">
<td>SMFIS_TEMPFAIL</td>
<td>Return a temporary failure, i.e., the corresponding SMTP command will return an appropriate 4xx status code.
For a message-oriented routine (except <a href="xxfi_envfrom.html">xxfi_envfrom</a>), fail for this message. <br>
For a connection-oriented routine, fail for this connection; call <a href="xxfi_close.html">xxfi_close</a>. <br>
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_ACCEPT</TD>
<TD>For a connection-oriented routine, accept this connection without further filter processing; call <A HREF="xxfi_close.html">xxfi_close</A>.<BR>
For a message- or recipient-oriented routine, accept this message without further filtering.<BR>
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
<TD>Return a temporary failure, i.e., the corresponding SMTP command will return an appropriate 4xx status code.
For a message-oriented routine (except <A HREF="xxfi_envfrom.html">xxfi_envfrom</A>), fail for this message. <BR>
For a connection-oriented routine, fail for this connection; call <A HREF="xxfi_close.html">xxfi_close</A>. <BR>
For a recipient-oriented routine, only fail for the current recipient; continue message processing.
</td>
</tr>
</table>
</TD>
</TR>
<hr size="1">
<font size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
<TR valign="top">
<TD><A NAME="SMFIS_SKIP">SMFIS_SKIP</A></TD>
<TD>Skip further callbacks of the same type in this transaction.
Currently this return value is only allowed in
<A HREF="xxfi_body.html">xxfi_body()</A>.
It can be used if a milter has received sufficiently many
body chunks to make a decision, but still wants to invoke
message modification functions that are only allowed to be called from
<A HREF="xxfi_eom.html">xxfi_eom()</A>.
Note: the milter <EM>must</EM>
<A HREF="xxfi_negotiate.html">negotiate</A>
this behavior with the MTA, i.e., it must check whether
the protocol action
<A HREF="xxfi_negotiate.html#SMFIP_SKIP"><CODE>SMFIP_SKIP</CODE></A>
is available and if so, the milter must request it.
</TD>
</TR>
<TR valign="top">
<TD><A NAME="SMFIS_NOREPLY">SMFIS_NOREPLY</A></TD>
<TD>Do not send a reply back to the MTA.
The milter <EM>must</EM>
<A HREF="xxfi_negotiate.html">negotiate</A>
this behavior with the MTA, i.e., it must check whether
the appropriate protocol action
<A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A>
is available and if so, the milter must request it.
If you set the
<A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A>
protocol action for a callback, that callback <EM>must</EM>
always reply with
SMFIS_NOREPLY.
Using any other reply code is a violation of the API.
If in some cases your callback may return another value
(e.g., due to some resource shortages), then you
<EM>must not</EM> set
<A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A>
and you must use
SMFIS_CONTINUE as the default return code.
(Alternatively you can try to delay reporting the problem to
a later callback for which
<A HREF="xxfi_negotiate.html#SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A>
is not set.)
</TD>
</TR>
</TABLE>
<H2><A NAME="Miscellaneous">Miscellaneous</A></H2>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Function</TH><TH>Description</TH></TR>
<TR><TD><A HREF="smfi_version.html">smfi_version</A></TD><TD>libmilter (runtime) version info</TD></TR>
<TR><TD><A HREF="smfi_setsymlist.html">smfi_setsymlist</A></TD><TD>
Set the list of macros that the milter wants to receive from the MTA
for a protocol stage.
</TD></TR>
</TABLE>
<P>
<TABLE BORDER="1" CELLSPACING=0 CELLPADDING=2><TR BGCOLOR="#dddddd"><TH>Constant</TH><TH>Description</TH></TR>
<TR><TD><A HREF="smfi_version.html">SMFI_VERSION</A></TD><TD>libmilter (compile time) version info</TD></TR>
</TABLE>
<HR SIZE="1">
<FONT SIZE="-1">
Copyright (c) 2000, 2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,23 +1,23 @@
<html>
<head>
<title>Architecture</title>
</head>
<body>
<HTML>
<HEAD>
<TITLE>Architecture</TITLE>
</HEAD>
<BODY>
<!--
$Id: design.html,v 1.11 2003/03/05 19:57:54 ca Exp $
$Id: design.html,v 1.12 2006/08/08 20:55:57 ca Exp $
-->
<h1>Architecture</h1>
<H1>Architecture</H1>
<h2>Contents</h2>
<H2>Contents</H2>
<ul>
<li>Design Goals
<li>Implementing Filtering Policies
<li>MTA - Filter Communication
</ul>
<UL>
<LI>Design Goals
<LI>Implementing Filtering Policies
<LI>MTA - Filter Communication
</UL>
<h2>Goals</h2>
<H2>Goals</H2>
The Sendmail Content Management API (Milter) provides an interface for
third-party software to validate and modify messages as they pass
@ -28,7 +28,7 @@ recipients, headers, and body. The MTA configuration file specifies
which filters are to be applied, and in what order, allowing an
administrator to combine multiple independently-developed filters.
<p>
<P>
We expect to see both vendor-supplied, configurable mail filtering
applications and a multiplicity of script-like filters designed by and
for MTA administrators. A certain degree of coding sophistication and
@ -37,7 +37,7 @@ allows filters to exercise fine-grained control at the SMTP level.
However, as will be seen in the example, many filtering applications
can be written with relatively little protocol knowledge.
<p>
<P>
Given these expectations, the API is designed to achieve the following
goals:
@ -47,7 +47,7 @@ goals:
(of course, they can if required, but that is a local issue);
this will simplify coding
and limit the impact of security flaws in the filter program.
<p>
<P>
<LI>Reliability.
Coding failures in a Milter process that cause that process
to hang or core-dump
@ -59,7 +59,7 @@ goals:
The latter failure mode will generally have sendmail return
a 4xx SMTP code (although in later phases of the SMTP protocol
it may cause the mail to be queued for later processing).
<p>
<P>
<LI>Simplicity.
The API should make implementation of a new filter
no more difficult than absolutely necessary.
@ -70,12 +70,12 @@ goals:
<LI>Provide all interfaces required
while avoiding unnecessary pedanticism.
</UL>
<p>
<P>
<LI>Performance.
Simple filters should not seriously impact overall MTA performance.
</OL>
<h2>Implementing Filtering Policies</h2>
<H2>Implementing Filtering Policies</H2>
Milter is designed to allow a server administrator to combine
third-party filters to implement a desired mail filtering policy. For
@ -87,16 +87,16 @@ engine, then via a large-scale spam-catching service, and finally
append the desired footer if the message still met requisite criteria.
Any of these filters could be added or changed independently.
<p>
<P>
Thus the site administrator, not the filter writer, controls the
overall mail filtering environment. In particular, he/she must decide
which filters are run, in what order they are run, and how they
communicate with the MTA. These parameters, as well as the
actions to be taken if a filter becomes unavailable, are selectable
during MTA configuration. <a href="installation.html">Further
details</a> are available later in this document.
during MTA configuration. <A href="installation.html">Further
details</A> are available later in this document.
<h2>MTA - Filter communication</h2>
<H2>MTA - Filter communication</H2>
Filters run as separate processes, outside of the sendmail address
space. The benefits of this are threefold:
@ -112,36 +112,36 @@ space. The benefits of this are threefold:
the parallelism inherent in multiple processes.</LI>
</OL>
<p>
<P>
Each filter may communicate with multiple MTAs at the same time over
local or remote connections, using multiple threads of execution. <a
href="#figure-1">Figure 1</a> illustrates a possible network of
local or remote connections, using multiple threads of execution.
<A HREF="#figure-1">Figure 1</A> illustrates a possible network of
communication channels between a site's filters, its MTAs, and other
MTAs on the network:
</p>
<div align="center">
<a name="figure-1"><img src="figure1.jpg" ALT=""></A><br>
<b>Figure 1: A set of MTA's interacting with a set of filters.</b>
</div>
<p>
</P>
<DIV align="center">
<A name="figure-1"><IMG src="figure1.jpg" ALT=""></A><BR>
<B>Figure 1: A set of MTA's interacting with a set of filters.</B>
</DIV>
<P>
The Milter library (libmilter) implements the communication protocol.
It accepts connections from various MTAs, passes the relevant data to
the filter through callbacks, then makes appropriate responses based
on return codes. A filter may also send data to the MTA as a result
of library calls. <a href="#figure-2">Figure 2</a> shows a single
of library calls. <A href="#figure-2">Figure 2</A> shows a single
filter process processing messages from two MTAs:
</p>
<div align="center">
<img src="figure2.jpg" ALT=""><br>
<b>Figure 2: A filter handling simultaneous requests from two MTA's.</b>
</div>
<hr size="1">
<font size="-1">
</P>
<DIV align="center">
<IMG src="figure2.jpg" ALT=""><BR>
<B>Figure 2: A filter handling simultaneous requests from two MTA's.</B>
</DIV>
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,22 +1,22 @@
<html>
<head>
<title>Filtering Mail with Sendmail</title>
</head>
<body>
<HTML>
<HEAD>
<TITLE>Filtering Mail with Sendmail</TITLE>
</HEAD>
<BODY>
<!--
$Id: index.html,v 1.12 2003/03/05 19:57:54 ca Exp $
$Id: index.html,v 1.13 2006/08/08 20:55:57 ca Exp $
-->
<h1>Filtering Mail with Sendmail</h1>
<H1>Filtering Mail with Sendmail</H1>
<!--
<P><b>Disclaimer</b>:
<P><B>Disclaimer</B>:
This preliminary API description is provided for review only. This
specification may change based on feedback from reviewers, and does
not bind Sendmail to offer this functionality in any release.
-->
<h2>Introduction</h2>
<H2>Introduction</H2>
<P>
Sendmail's Content Management API (milter) provides third-party
@ -26,67 +26,67 @@ content and meta-information. Filtering policies implemented by
Milter-conformant filters may then be centrally configured and
composed in an end-user's MTA configuration file.
<p>
<P>
Possible uses for filters include spam rejection, virus
filtering, and content control. In general, Milter seeks to address
site-wide filtering concerns in a scalable way. Individual users' mail
filtering needs (e.g. sorting messages by subject) are left to
client-level programs such as <a href="http://www.procmail.org">Procmail</a>.
client-level programs such as <A href="http://www.procmail.org">Procmail</A>.
<P>
This document is a technical introduction intended for those
interested in developing Milter filters. It includes:
<ul>
<li>A description of Milter's design goals.
<UL>
<LI>A description of Milter's design goals.
<li>An explanation of Milter application architecture, including
<LI>An explanation of Milter application architecture, including
interactions between the support library and user code, and between
filters and the MTA.
<li>A specification of the C application programming interface.
<li>An example of a simple Milter filter.
</ul>
<LI>A specification of the C application programming interface.
<LI>An example of a simple Milter filter.
</UL>
<h2>Contents</h2>
<H2>Contents</H2>
<ul>
<li><a href="design.html">Architecture</a>
<ul>
<li>Design Goals
<li>Implementing Filtering Policies
<li>MTA - Filter communication
</ul>
<li><a href="overview.html">Technical Overview</a>
<ul>
<li>Initialization
<li>Control flow
<li>Multithreading
<li>Resource Management
<li>Signal Handling
</ul>
<li><a href="api.html">API Documentation</a>
<ul>
<li>Library Control Functions
<li>Data Access Functions
<li>Message Modification Functions
<li>Callbacks
</ul>
<li><a href="installation.html">Installation and Configuration</a>
<ul>
<li>Compiling and Installing Your Filter
<li>Configuring Sendmail
</ul>
<li><a href="sample.html">A Sample Filter</a>
<!-- <li><a href="other.html">Other Sources of Information</a> -->
</ul>
<UL>
<LI><A href="design.html">Architecture</A>
<UL>
<LI>Design Goals
<LI>Implementing Filtering Policies
<LI>MTA - Filter communication
</UL>
<LI><A href="overview.html">Technical Overview</A>
<UL>
<LI>Initialization
<LI>Control flow
<LI>Multithreading
<LI>Resource Management
<LI>Signal Handling
</UL>
<LI><A href="api.html">API Documentation</A>
<UL>
<LI>Library Control Functions
<LI>Data Access Functions
<LI>Message Modification Functions
<LI>Callbacks
</UL>
<LI><A href="installation.html">Installation and Configuration</A>
<UL>
<LI>Compiling and Installing Your Filter
<LI>Configuring Sendmail
</UL>
<LI><A href="sample.html">A Sample Filter</A>
<!-- <LI><A href="other.html">Other Sources of Information</A> -->
</UL>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2001, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,96 +1,90 @@
<html>
<head><title>Installation and Configuration</title>
</head>
<body>
<HTML>
<HEAD><TITLE>Installation and Configuration</TITLE>
</HEAD>
<BODY>
<!--
$Id: installation.html,v 1.20 2003/03/05 19:57:54 ca Exp $
$Id: installation.html,v 1.23 2006/08/31 17:16:03 ca Exp $
-->
<h1>Installation</h1>
<h2>Contents</h2>
<ul>
<li><a href="#compile">Compiling and Installing Your Filter</a>
<li><a href="#config">Configuring Sendmail</a>
</ul>
<H1>Installation</H1>
<H2>Contents</H2>
<UL>
<LI><A href="#compile">Compiling and Installing Your Filter</A>
<LI><A href="#config">Configuring Sendmail</A>
</UL>
<h2><a name="compile">Compiling and Installing Your Filter</A></h2>
<H2><A name="compile">Compiling and Installing Your Filter</A></H2>
To compile a filter, modify the Makefile provided with the sample program, or:
<ul>
<li>Put the include and Sendmail directories in your include path
<UL>
<LI>Put the include and Sendmail directories in your include path
(e.g. -I/path/to/include -I/path/to/sendmail).
<li>Make sure libmilter.a is in your library path, and link your
<LI>Make sure libmilter.a is in your library path, and link your
application with it (e.g. "-lmilter").
<li>Compile with pthreads, either by using -pthread for gcc, or
<LI>Compile with pthreads, either by using -pthread for gcc, or
linking with a pthreads support library (-lpthread).
</ul>
</UL>
Your compile command line will look like
<pre>
<PRE>
cc -I/path/to/include -I/path/to/sendmail -c myfile.c
</pre>
</PRE>
and your linking command line will look something like
<pre>
<PRE>
cc -o myfilter [object-files] -L[library-location] -lmilter -pthread
</pre>
</PRE>
<H2><a name="config">Configuring Sendmail</A></H2>
<H2><A name="config">Configuring Sendmail</A></H2>
First, you must compile sendmail with MILTER defined.
If you use a sendmail version older than 8.12 please see
If you use a sendmail version older than 8.13 please see
the instructions for your version.
To do this, add the following lines to your build
configuration file (devtools/Site/config.site.m4)
<pre>
APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER')
</pre>
then type <code>./Build -c</code> in your sendmail directory.
The default compilation options for sendmail enable support
for milters since 8.13.
<P>
Next, you must add the desired filters to your sendmail configuration
(.mc) file.
Mail filters have three equates:
The required <code>S=</code> equate specifies the socket where
sendmail should look for the filter; The optional <code>F=</code> and
<code>T=</code> equates specify flags and timeouts, respectively. All
equates names, equate field names, and flag values are case sensitive.
The required <CODE>S=</CODE> equate specifies the socket where
sendmail should look for the filter; the optional <CODE>F=</CODE> and
<CODE>T=</CODE> equates specify flags and timeouts, respectively.
All equates names, equate field names, and flag values are case sensitive.
<P>
The current flags (<code>F=</code>) are:
<p>
<table cellspacing="1" cellpadding=4 border=1>
<tr bgcolor="#dddddd" align=left valign=top>
<th>Flag</TH> <th align="center">Meaning</TH>
The current flags (<CODE>F=</CODE>) are:
<P>
<TABLE cellspacing="1" cellpadding=4 border=1>
<TR bgcolor="#dddddd" align=left valign=top>
<TH>Flag</TH> <TH align="center">Meaning</TH>
</TR>
<tr align="left" valign=top>
<TR align="left" valign=top>
<TD>R</TD> <TD>Reject connection if filter unavailable</TD>
</TR>
<tr align="left" valign=top>
<TR align="left" valign=top>
<TD>T</TD> <TD>Temporary fail connection if filter unavailable</TD>
</TR>
</TABLE>
If a filter is unavailable or unresponsive and no flags have been
specified, the MTA will continue normal handling of the current
connection. The MTA will try to contact the filter again on each new
connection.
The MTA will try to contact the filter again on each new connection.
<P>
There are three fields inside of the <code>T=</code> equate: S, R, and
E. Note the separator between each is a ";" (semicolon), as ","
(comma) already separates equates. The value of each field is a
decimal number followed by a single letter designating the units ("s"
for seconds, "m" for minutes). The fields have the following
meanings:
<p>
There are three fields inside of the <CODE>T=</CODE> equate: S, R, and E.
Note the separator between each is a ";" (semicolon), as ","
(comma) already separates equates.
The value of each field is a decimal number followed by a single letter
designating the units ("s" for seconds, "m" for minutes).
The fields have the following meanings:
<P>
<TABLE cellspacing="1" cellpadding=4 border=1>
<TR bgcolor="#dddddd" align=left valign=top>
<TH>Flag</TH> <TH align="center">Meaning</TH>
</TR>
<TR align="left" valign=top>
<TD>C</TD> <TD>Timeout for connecting to a filter. If set to 0, the
system's <CODE>connect()</CODE> timeout will be used.
system's <CODE>connect(2)</CODE> timeout will be used.
Default: 5m</TD>
</TR>
<TR align="left" valign=top>
@ -106,27 +100,28 @@ meanings:
</TR>
</TABLE>
<p>
The following sendmail.mc example specifies three filters. The first
two rendezvous on Unix-domain sockets in the /var/run directory; the
third uses an IP socket on port 999.
<pre>
<P>
The following sendmail.mc example specifies three filters.
The first two rendezvous on Unix-domain sockets in the /var/run directory;
the third uses an IP socket on port 999.
<PRE>
INPUT_MAIL_FILTER(`filter1', `S=unix:/var/run/f1.sock, F=R')
INPUT_MAIL_FILTER(`filter2', `S=unix:/var/run/f2.sock, F=T, T=S:1s;R:1s;E:5m')
INPUT_MAIL_FILTER(`filter3', `S=inet:999@localhost, T=C:2m')
define(`confINPUT_MAIL_FILTERS', `filter2,filter1,filter3')
<hr width="30%">
<HR width="30%">
m4 ../m4/cf.m4 myconfig.mc &gt; myconfig.cf
</pre>
</PRE>
By default, the filters would be run in the order declared,
i.e. "filter1, filter2, filter3"; however, since
<code>confINPUT_MAIL_FILTERS</code> is defined, the filters will be
run "filter2, filter1, filter3". Also note that a filter can be
defined without adding it to the input filter list by using
<CODE>confINPUT_MAIL_FILTERS</CODE> is defined, the filters will be
run "filter2, filter1, filter3".
Also note that a filter can be defined
without adding it to the input filter list by using
MAIL_FILTER() instead of INPUT_MAIL_FILTER().
<p>
<P>
The above macros will result in the following lines being added to
your .cf file:
<PRE>
@ -136,34 +131,35 @@ your .cf file:
O InputMailFilters=filter2,filter1,filter3
</PRE>
<p>
Finally, the sendmail macros accessible via <a
href="smfi_getsymval.html">smfi_getsymval</a> can be configured by
<P>
Finally, the sendmail macros accessible via
<A HREF="smfi_getsymval.html">smfi_getsymval</A> can be configured by
defining the following m4 variables (or cf options):
<table cellspacing="1" cellpadding=4 border=1>
<tr bgcolor="#dddddd" align=left valign=top>
<th align="center">In .mc file</th> <th align="center">In .cf file</TH>
<th align="center">Default Value</th>
</tr>
<tr><td>confMILTER_MACROS_CONNECT</td><td>Milter.macros.connect</td>
<td><code>j, _, {daemon_name}, {if_name}, {if_addr}</code></td></tr>
<tr><td>confMILTER_MACROS_HELO</td><td>Milter.macros.helo</td>
<td><code>{tls_version}, {cipher}, {cipher_bits}, {cert_subject},
{cert_issuer}</code></td></tr>
<tr><td>confMILTER_MACROS_ENVFROM</td><td>Milter.macros.envfrom</td>
<td><code>i, {auth_type}, {auth_authen}, {auth_ssf}, {auth_author},
{mail_mailer}, {mail_host}, {mail_addr}</code></td></tr>
<tr><td>confMILTER_MACROS_ENVRCPT</td><td>Milter.macros.envrcpt</td>
<td><code>{rcpt_mailer}, {rcpt_host}, {rcpt_addr}</code></td></tr>
</table>
<TABLE cellspacing="1" cellpadding=4 border=1>
<TR bgcolor="#dddddd" align=left valign=top>
<TH align="center">In .mc file</TH> <TH align="center">In .cf file</TH>
<TH align="center">Default Value</TH>
</TR>
<TR><TD>confMILTER_MACROS_CONNECT</TD><TD>Milter.macros.connect</TD>
<TD><CODE>j, _, {daemon_name}, {if_name}, {if_addr}</CODE></TD></TR>
<TR><TD>confMILTER_MACROS_HELO</TD><TD>Milter.macros.helo</TD>
<TD><CODE>{tls_version}, {cipher}, {cipher_bits}, {cert_subject},
{cert_issuer}</CODE></TD></TR>
<TR><TD>confMILTER_MACROS_ENVFROM</TD><TD>Milter.macros.envfrom</TD>
<TD><CODE>i, {auth_type}, {auth_authen}, {auth_ssf}, {auth_author},
{mail_mailer}, {mail_host}, {mail_addr}</CODE></TD></TR>
<TR><TD>confMILTER_MACROS_ENVRCPT</TD><TD>Milter.macros.envrcpt</TD>
<TD><CODE>{rcpt_mailer}, {rcpt_host}, {rcpt_addr}</CODE></TD></TR>
</TABLE>
For information about available macros and their meanings, please
consult the sendmail documentation.
<hr size="1">
<font size="-1">
Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body> </html>
</FONT>
</BODY>
</HTML>

View File

@ -1,18 +1,18 @@
<html>
<head><title>Other Resources</title>
</head>
<body>
<HTML>
<HEAD><TITLE>Other Resources</TITLE>
</HEAD>
<BODY>
<!--
$Id: other.html,v 1.5 2003/03/05 19:57:54 ca Exp $
$Id: other.html,v 1.6 2006/08/08 20:55:57 ca Exp $
-->
FAQ? Mailing list? More sample filters?
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,194 +1,215 @@
<html>
<head>
<title>Technical Overview</title>
</head>
<body>
<HTML>
<HEAD>
<TITLE>Technical Overview</TITLE>
</HEAD>
<BODY>
<!--
$Id: overview.html,v 1.14 2003/03/05 19:57:54 ca Exp $
$Id: overview.html,v 1.19 2006/12/21 18:23:47 ca Exp $
-->
<h1>Technical Overview</h1>
<H1>Technical Overview</H1>
<h2>Contents</h2>
<H2>Contents</H2>
<ul>
<li>Initialization
<li>Control flow
<li>Multithreading
<li>Resource Management
<li>Signal Handling
</ul>
<UL>
<LI><A HREF="#Initialization">Initialization</A>
<LI><A HREF="#ControlFlow">Control Flow</A>
<LI><A HREF="#Multithreading">Multithreading</A>
<LI><A HREF="#ResourceManagement">Resource Management</A>
<LI><A HREF="#SignalHandling">Signal Handling</A>
</UL>
<h2>Initialization</h2>
<H2><A NAME="Initialization">Initialization</A></H2>
In addition to its own initialization, libmilter expects a filter to initialize several parameters before calling <a href="smfi_main.html">smfi_main</a>:
<ul>
<li>The callbacks the filter wishes to be called, and the types of
message modification it intends to perform (required, see <a
href="smfi_register.html">smfi_register</a>).
In addition to its own initialization,
libmilter expects a filter to initialize several parameters
before calling <A HREF="smfi_main.html">smfi_main</A>:
<UL>
<LI>The callbacks the filter wishes to be called, and the types of
message modification it intends to perform (required, see
<A HREF="smfi_register.html">smfi_register</A>).
<li>The socket address to be used when communicating with the MTA
(required, see <a href="smfi_setconn.html">smfi_setconn</a>).
<LI>The socket address to be used when communicating with the MTA
(required, see <A HREF="smfi_setconn.html">smfi_setconn</A>).
<li>The number of seconds to wait for MTA connections before
timing out (optional, see <a
href="smfi_settimeout.html">smfi_settimeout</a>).
</ul>
<p>
If the filter fails to initialize libmilter, or if one or more of the
parameters it has passed are invalid, a subsequent call to smfi_main
will fail.
<LI>The number of seconds to wait for MTA connections before
timing out (optional, see
<A HREF="smfi_settimeout.html">smfi_settimeout</A>).
</UL>
<P>
If the filter fails to initialize libmilter,
or if one or more of the parameters it has passed are invalid,
a subsequent call to smfi_main will fail.
<h2>Control flow</h2>
<H2><A NAME="ControlFlow">Control Flow</A></H2>
<p>
<P>
The following pseudocode describes the filtering process from the
perspective of a set of <code>N</code> MTA's, each corresponding to a
connection. Callbacks are shown beside the processing stages in which
they are invoked; if no callbacks are defined for a particular stage,
that stage may be bypassed. Though it is not shown, processing may be
aborted at any time during a message, in which case the <a
href="xxfi_abort.html">xxfi_abort</a> callback is invoked and control
returns to <code>MESSAGE</code>.
<p>
<pre>
perspective of a set of <CODE>N</CODE> MTA's,
each corresponding to a connection.
Callbacks are shown beside the processing stages in which they are invoked;
if no callbacks are defined for a particular stage,
that stage may be bypassed.
Though it is not shown,
processing may be aborted at any time during a message,
in which case the
<A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked and control
returns to <CODE>MESSAGE</CODE>.
<P>
<PRE>
For each of N connections
{
For each filter
process connection/helo (<a href="xxfi_connect.html">xxfi_connect</a>, <a href="xxfi_helo.html">xxfi_helo</a>)
process connection/helo (<A HREF="xxfi_connect.html">xxfi_connect</A>, <A HREF="xxfi_helo.html">xxfi_helo</A>)
MESSAGE:For each message in this connection (sequentially)
{
For each filter
process sender (<a href="xxfi_envfrom.html">xxfi_envfrom</a>)
process sender (<A HREF="xxfi_envfrom.html">xxfi_envfrom</A>)
For each recipient
{
For each filter
process recipient (<a href="xxfi_envrcpt.html">xxfi_envrcpt</a>)
process recipient (<A HREF="xxfi_envrcpt.html">xxfi_envrcpt</A>)
}
For each filter
{
process DATA (<A HREF="xxfi_data.html">xxfi_data</A>)
For each header
process header (<a href="xxfi_header.html">xxfi_header</a>)
process end of headers (<a href="xxfi_eoh.html">xxfi_eoh</a>)
process header (<A HREF="xxfi_header.html">xxfi_header</A>)
process end of headers (<A HREF="xxfi_eoh.html">xxfi_eoh</A>)
For each body block
process this body block (<a href="xxfi_body.html">xxfi_body</a>)
process end of message (<a href="xxfi_eom.html">xxfi_eom</a>)
process this body block (<A HREF="xxfi_body.html">xxfi_body</A>)
process end of message (<A HREF="xxfi_eom.html">xxfi_eom</A>)
}
}
For each filter
process end of connection (<a href="xxfi_close.html">xxfi_close</a>)
process end of connection (<A HREF="xxfi_close.html">xxfi_close</A>)
}
</pre>
</PRE>
<P>Note: Filters are contacted in order defined in config file.</P>
<P>
To write a filter, a vendor supplies callbacks to process relevant
parts of a message transaction. The library then controls all
sequencing, threading, and protocol exchange with the MTA. <a
href="#figure-3">Figure 3</a> outlines control flow for a filter
parts of a message transaction.
The library then controls all sequencing, threading,
and protocol exchange with the MTA.
<A HREF="#figure-3">Figure 3</A> outlines control flow for a filter
process, showing where different callbacks are invoked.
</p>
<div align="center"><a name="figure-3"></a>
<table border=1 cellspacing=0 cellpadding=2 width="70%">
<tr bgcolor="#dddddd"><th>SMTP Commands</th><th>Milter Callbacks</th></tr>
<tr><td>(open SMTP connection)</td><td>xxfi_connect</td></tr>
<tr><td>HELO ...</td><td>xxfi_helo</td></tr>
<tr><td>MAIL From: ...</td><td>xxfi_envfrom</td></tr>
<tr><td>RCPT To: ...</td><td>xxfi_envrcpt</td></tr>
<tr><td>[more RCPTs]</td><td>[xxfi_envrcpt]</td></tr>
<tr><td>DATA</td><td>&nbsp;</td></tr>
<tr><td>Header: ...</td><td>xxfi_header</td></tr>
<tr><td>[more headers]</td><td>[xxfi_header]</td></tr>
<tr><td>&nbsp;</td><td>xxfi_eoh</td></tr>
<tr><td>body... </td><td>xxfi_body</td></tr>
<tr><td>[more body...]</td><td>[xxfi_body]</td></tr>
<tr><td>.</td><td>xxfi_eom</td></tr>
<tr><td>QUIT</td><td>xxfi_close</td></tr>
<tr><td>(close SMTP connection)</td><td>&nbsp;</td></tr>
</table>
<b>Figure 3: Milter callbacks related to an SMTP transaction.</b>
</div>
<p>
</P>
<DIV ALIGN="center"><A NAME="figure-3"></A>
<TABLE border=1 cellspacing=0 cellpadding=2 width="70%">
<TR bgcolor="#dddddd"><TH>SMTP Commands</TH><TH>Milter Callbacks</TH></TR>
<TR><TD>(open SMTP connection)</TD><TD>xxfi_connect</TD></TR>
<TR><TD>HELO ...</TD><TD>xxfi_helo</TD></TR>
<TR><TD>MAIL From: ...</TD><TD>xxfi_envfrom</TD></TR>
<TR><TD>RCPT To: ...</TD><TD>xxfi_envrcpt</TD></TR>
<TR><TD>[more RCPTs]</TD><TD>[xxfi_envrcpt]</TD></TR>
<TR><TD>DATA</TD><TD>xxfi_data</TD></TR>
<TR><TD>Header: ...</TD><TD>xxfi_header</TD></TR>
<TR><TD>[more headers]</TD><TD>[xxfi_header]</TD></TR>
<TR><TD>&nbsp;</TD><TD>xxfi_eoh</TD></TR>
<TR><TD>body... </TD><TD>xxfi_body</TD></TR>
<TR><TD>[more body...]</TD><TD>[xxfi_body]</TD></TR>
<TR><TD>.</TD><TD>xxfi_eom</TD></TR>
<TR><TD>QUIT</TD><TD>xxfi_close</TD></TR>
<TR><TD>(close SMTP connection)</TD><TD>&nbsp;</TD></TR>
</TABLE>
<B>Figure 3: Milter callbacks related to an SMTP transaction.</B>
</DIV>
<P>
Note that although only a single message is shown above, multiple
messages may be sent in a single connection. Note also that a message
and/or connection may be aborted by either the remote host or the MTA
at any point during the SMTP transaction. If this occurs during a
message (between the MAIL command and the final "."), the filter's <a
href="xxfi_abort.html">xxfi_abort</a> routine will be called. <a
href="xxfi_close.html">xxfi_close</a> is called any time the
messages may be sent in a single connection.
Note also that a message or connection may be aborted by
either the remote host or the MTA
at any point during the SMTP transaction.
f this occurs during a message (between the MAIL command and the final "."),
the filter's
<A HREF="xxfi_abort.html">xxfi_abort</A> routine will be called.
<A HREF="xxfi_close.html">xxfi_close</A> is called any time the
connection closes.
<h2>Multithreading</h2>
<H2><A NAME="Multithreading">Multithreading</A></H2>
<p>
<P>
A single filter process may handle any number of connections
simultaneously. All filtering callbacks must therefore be reentrant,
simultaneously.
All filtering callbacks must therefore be reentrant,
and use some appropriate external synchronization methods to access
global data. Furthermore, since there is not a one-to-one
correspondence between threads and connections (N connections mapped
onto M threads, M &lt;= N), connection-specific data must be accessed
through the handles provided by the Milter library. The programmer
cannot rely on library-supplied thread-specific data blocks
(e.g. pthread_getspecific()) to store connection-specific data. See
the API documentation for <a
href="smfi_setpriv.html">smfi_setpriv</a> and <a
href="smfi_getpriv.html">smfi_getpriv</a> for details.
global data.
Furthermore, since there is not a one-to-one correspondence
between threads and connections
(N connections mapped onto M threads, M &lt;= N),
connection-specific data must be accessed
through the handles provided by the Milter library.
The programmer cannot rely on library-supplied thread-specific data blocks
(e.g., <CODE>pthread_getspecific(3)</CODE>) to store connection-specific data.
See the API documentation for
<A HREF="smfi_setpriv.html">smfi_setpriv</A> and
<A HREF="smfi_getpriv.html">smfi_getpriv</A> for details.
<h2>Resource management</h2>
<H2><A NAME="ResourceManagement">Resource Management</A></H2>
Since filters are likely to be long-lived, and to handle many
connections, proper deallocation of per-connection resources is
important. The lifetime of a connection is bracketed by calls to the
callbacks <a href="xxfi_connect.html">xxfi_connect</a> and <a
href="xxfi_close.html">xxfi_close</a>. Therefore connection-specific
resources (accessed via <a href="smfi_getpriv.html">smfi_getpriv</a>
and <a href="smfi_setpriv.html">smfi_setpriv</a>) may be allocated in
<a href="xxfi_connect.html">xxfi_connect</a>, and should be freed in
<a href="xxfi_close.html">xxfi_close</a>. For further information see
the <a href="api.html#conn-msg">discussion</a> of message- versus
connection-oriented routines. In particular, note that there is only
one connection-specific data pointer per connection.
<p>
Since filters are likely to be long-lived,
and to handle many connections,
proper deallocation of per-connection resources is important.
The lifetime of a connection is bracketed by calls to the
callbacks <A HREF="xxfi_connect.html">xxfi_connect</A> and
<A HREF="xxfi_close.html">xxfi_close</A>.
Therefore connection-specific
resources (accessed via <A HREF="smfi_getpriv.html">smfi_getpriv</A>
and <A HREF="smfi_setpriv.html">smfi_setpriv</A>) may be allocated in
<A HREF="xxfi_connect.html">xxfi_connect</A>,
and should be freed in
<A HREF="xxfi_close.html">xxfi_close</A>.
For further information see
the <A HREF="api.html#conn-msg">discussion</A> of message- versus
connection-oriented routines.
In particular,
note that there is only one connection-specific data pointer per connection.
<P>
Each message is bracketed by calls to <a
href="xxfi_envfrom.html">xxfi_envfrom</a> and <a
href="xxfi_eom.html">xxfi_eom</a> (or <a
href="xxfi_abort.html">xxfi_abort</a>), implying that message-specific
resources can be allocated and reclaimed in these routines. Since the
messages in a connection are processed sequentially by each filter,
Each message is bracketed by calls to
<A HREF="xxfi_envfrom.html">xxfi_envfrom</A> and
<A HREF="xxfi_eom.html">xxfi_eom</A> (or
<A HREF="xxfi_abort.html">xxfi_abort</A>),
implying that message-specific resources can be allocated
and reclaimed in these routines.
Since the messages in a connection are processed sequentially by each filter,
there will be only one active message associated with a given
connection and filter (and connection-private data block). These
resources must still be accessed through <a
href="smfi_getpriv.html">smfi_getpriv</a> and <a
href="smfi_setpriv.html">smfi_setpriv</a>, and must be reclaimed
in <a href="xxfi_abort.html">xxfi_abort</a>.
connection and filter (and connection-private data block).
These resources must still be accessed through
<A HREF="smfi_getpriv.html">smfi_getpriv</A> and
<A HREF="smfi_setpriv.html">smfi_setpriv</A>,
and must be reclaimed in
<A HREF="xxfi_abort.html">xxfi_abort</A>.
<h2>Signal Handling</h2>
<H2><A NAME="SignalHandling">Signal Handling</A></H2>
libmilter takes care of signal handling, the filters are
not influenced directly by signals.
libmilter takes care of signal handling,
the filters are not influenced directly by signals.
There are basically two types of signal handlers:
<ol>
<li><TT>Stop</TT>: no new connections from the MTA will be accepted,
<OL>
<LI><TT>Stop</TT>: no new connections from the MTA will be accepted,
but existing connections are allowed to continue.
<li><TT>Abort</TT>: all filters will be stopped as soon as the next
<LI><TT>Abort</TT>: all filters will be stopped as soon as the next
communication with the MTA happens.
</ol>
</OL>
Filters are not terminated asynchronously (except by
signals that can't be caught).
Filters are not terminated asynchronously
(except by signals that can't be caught).
In the case of <TT>Abort</TT> the
<a href="xxfi_abort.html">xxfi_abort</a> callback is invoked.
<A HREF="xxfi_abort.html">xxfi_abort</A> callback is invoked.
<hr size="1">
<font size="-1">
Copyright (c) 2000, 2001, 2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2001, 2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,26 +1,26 @@
<html>
<head><title>A Sample Filter</title></head>
<body>
<HTML>
<HEAD><TITLE>A Sample Filter</TITLE></HEAD>
<BODY>
<!--
$Id: sample.html,v 1.18 2004/02/27 00:49:28 msk Exp $
$Id: sample.html,v 1.22 2006/10/09 23:14:51 ca Exp $
-->
<h1>A Sample Filter</h1>
<H1>A Sample Filter</H1>
The following sample logs each message to a separate temporary file,
adds a recipient given with the -a flag, and rejects a disallowed
recipient address given with the -r flag. It recognizes the following
options:
<p>
<center>
<table border="1" cellpadding=2 cellspacing=1>
<tr><td><code>-p port</code></td><td>The port through which the MTA will connect to the filter.</td></tr>
<tr><td><code>-t sec</code></td><td>The timeout value.</td></tr>
<tr><td><code>-r addr</code></td><td>A recipient to reject.</td></tr>
<tr><td><code>-a addr</code></td><td>A recipient to add.</td></tr>
</table>
</center>
<hr>
<pre>
adds a recipient given with the -a flag,
and rejects a disallowed recipient address given with the -r flag.
It recognizes the following options:
<P>
<CENTER>
<TABLE border="1" cellpadding=2 cellspacing=1>
<TR><TD><CODE>-p port</CODE></TD><TD>The port through which the MTA will connect to the filter.</TD></TR>
<TR><TD><CODE>-t sec</CODE></TD><TD>The timeout value.</TD></TR>
<TR><TD><CODE>-r addr</CODE></TD><TD>A recipient to reject.</TD></TR>
<TR><TD><CODE>-a addr</CODE></TD><TD>A recipient to add.</TD></TR>
</TABLE>
</CENTER>
<HR>
<PRE>
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;errno.h&gt;
@ -47,7 +47,7 @@ struct mlfiPriv
FILE *mlfi_fp;
};
#define MLFIPRIV ((struct mlfiPriv *) <a href="smfi_getpriv.html">smfi_getpriv</a>(ctx))
#define MLFIPRIV ((struct mlfiPriv *) <A href="smfi_getpriv.html">smfi_getpriv</A>(ctx))
extern sfsistat mlfi_cleanup(SMFICTX *, bool);
@ -56,7 +56,7 @@ char *add = NULL;
char *reject = NULL;
sfsistat
<a href="xxfi_connect.html">mlfi_connect</a>(ctx, hostname, hostaddr)
<A href="xxfi_connect.html">mlfi_connect</A>(ctx, hostname, hostaddr)
SMFICTX *ctx;
char *hostname;
_SOCK_ADDR *hostaddr;
@ -74,9 +74,9 @@ sfsistat
memset(priv, '\0', sizeof *priv);
/* save the private data */
<a href="smfi_setpriv.html">smfi_setpriv</a>(ctx, priv);
<A href="smfi_setpriv.html">smfi_setpriv</A>(ctx, priv);
ident = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "_");
ident = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "_");
if (ident == NULL)
ident = "???";
if ((priv-&gt;mlfi_connectfrom = strdup(ident)) == NULL)
@ -90,7 +90,7 @@ sfsistat
}
sfsistat
<a href="xxfi_helo.html">mlfi_helo</a>(ctx, helohost)
<A href="xxfi_helo.html">mlfi_helo</A>(ctx, helohost)
SMFICTX *ctx;
char *helohost;
{
@ -99,7 +99,7 @@ sfsistat
char *buf;
struct mlfiPriv *priv = MLFIPRIV;
tls = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "{tls_version}");
tls = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "{tls_version}");
if (tls == NULL)
tls = "No TLS";
if (helohost == NULL)
@ -120,14 +120,14 @@ sfsistat
}
sfsistat
<a href="xxfi_envfrom.html">mlfi_envfrom</a>(ctx, argv)
<A href="xxfi_envfrom.html">mlfi_envfrom</A>(ctx, argv)
SMFICTX *ctx;
char **argv;
{
int fd = -1;
int argc = 0;
struct mlfiPriv *priv = MLFIPRIV;
char *mailaddr = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "{mail_addr}");
char *mailaddr = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "{mail_addr}");
/* open a file to store this message */
if ((priv-&gt;mlfi_fname = strdup("/tmp/msg.XXXXXX")) == NULL)
@ -174,12 +174,12 @@ sfsistat
}
sfsistat
<a href="xxfi_envrcpt.html">mlfi_envrcpt</a>(ctx, argv)
<A href="xxfi_envrcpt.html">mlfi_envrcpt</A>(ctx, argv)
SMFICTX *ctx;
char **argv;
{
struct mlfiPriv *priv = MLFIPRIV;
char *rcptaddr = <a href="smfi_getsymval.html">smfi_getsymval</a>(ctx, "{rcpt_addr}");
char *rcptaddr = <A href="smfi_getsymval.html">smfi_getsymval</A>(ctx, "{rcpt_addr}");
int argc = 0;
/* count the arguments */
@ -211,7 +211,7 @@ sfsistat
}
sfsistat
<a href="xxfi_header.html">mlfi_header</a>(ctx, headerf, headerv)
<A href="xxfi_header.html">mlfi_header</A>(ctx, headerf, headerv)
SMFICTX *ctx;
char *headerf;
unsigned char *headerv;
@ -228,7 +228,7 @@ sfsistat
}
sfsistat
<a href="xxfi_eoh.html">mlfi_eoh</a>(ctx)
<A href="xxfi_eoh.html">mlfi_eoh</A>(ctx)
SMFICTX *ctx;
{
/* output the blank line between the header and the body */
@ -243,7 +243,7 @@ sfsistat
}
sfsistat
<a href="xxfi_body.html">mlfi_body</a>(ctx, bodyp, bodylen)
<A href="xxfi_body.html">mlfi_body</A>(ctx, bodyp, bodylen)
SMFICTX *ctx;
unsigned char *bodyp;
size_t bodylen;
@ -265,19 +265,19 @@ sfsistat
}
sfsistat
<a href="xxfi_eom.html">mlfi_eom</a>(ctx)
<A href="xxfi_eom.html">mlfi_eom</A>(ctx)
SMFICTX *ctx;
{
bool ok = TRUE;
/* change recipients, if requested */
if (add != NULL)
ok = (<a href="smfi_addrcpt.html">smfi_addrcpt</a>(ctx, add) == MI_SUCCESS);
ok = (<A href="smfi_addrcpt.html">smfi_addrcpt</A>(ctx, add) == MI_SUCCESS);
return mlfi_cleanup(ctx, ok);
}
sfsistat
<a href="xxfi_abort.html">mlfi_abort</a>(ctx)
<A href="xxfi_abort.html">mlfi_abort</A>(ctx)
SMFICTX *ctx;
{
return mlfi_cleanup(ctx, FALSE);
@ -317,7 +317,7 @@ mlfi_cleanup(ctx, ok)
else
p++;
snprintf(hbuf, sizeof hbuf, "%s@%s", p, host);
if (<a href="smfi_addheader.html">smfi_addheader</a>(ctx, "X-Archived", hbuf) != MI_SUCCESS)
if (<A href="smfi_addheader.html">smfi_addheader</A>(ctx, "X-Archived", hbuf) != MI_SUCCESS)
{
/* failed; we have to wait until later */
fprintf(stderr,
@ -346,7 +346,7 @@ mlfi_cleanup(ctx, ok)
}
sfsistat
<a href="xxfi_close.html">mlfi_close</a>(ctx)
<A href="xxfi_close.html">mlfi_close</A>(ctx)
SMFICTX *ctx;
{
struct mlfiPriv *priv = MLFIPRIV;
@ -358,26 +358,59 @@ sfsistat
if (priv-&gt;mlfi_helofrom != NULL)
free(priv-&gt;mlfi_helofrom);
free(priv);
<a href="smfi_setpriv.html">smfi_setpriv</a>(ctx, NULL);
<A href="smfi_setpriv.html">smfi_setpriv</A>(ctx, NULL);
return SMFIS_CONTINUE;
}
sfsistat
<A href="xxfi_unknown.html">mlfi_unknown</A>(ctx, cmd)
SMFICTX *ctx;
char *cmd;
{
return SMFIS_CONTINUE;
}
sfsistat
<A href="xxfi_data.html">mlfi_data</A>(ctx)
SMFICTX *ctx;
{
return SMFIS_CONTINUE;
}
sfsistat
<A href="xxfi_negotiate.html">mlfi_negotiate</A>(ctx, f0, f1, f2, f3, pf0, pf1, pf2, pf3)
SMFICTX *ctx;
unsigned long f0;
unsigned long f1;
unsigned long f2;
unsigned long f3;
unsigned long *pf0;
unsigned long *pf1;
unsigned long *pf2;
unsigned long *pf3;
{
return SMFIS_ALL_OPTS;
}
struct smfiDesc smfilter =
{
"SampleFilter", /* filter name */
SMFI_VERSION, /* version code -- do not change */
SMFIF_ADDHDRS|SMFIF_ADDRCPT,
/* flags */
<a href="xxfi_connect.html">mlfi_connect</a>, /* connection info filter */
<a href="xxfi_helo.html">mlfi_helo</a>, /* SMTP HELO command filter */
<a href="xxfi_envfrom.html">mlfi_envfrom</a>, /* envelope sender filter */
<a href="xxfi_envrcpt.html">mlfi_envrcpt</a>, /* envelope recipient filter */
<a href="xxfi_header.html">mlfi_header</a>, /* header filter */
<a href="xxfi_eoh.html">mlfi_eoh</a>, /* end of header */
<a href="xxfi_body.html">mlfi_body</a>, /* body block filter */
<a href="xxfi_eom.html">mlfi_eom</a>, /* end of message */
<a href="xxfi_abort.html">mlfi_abort</a>, /* message aborted */
<a href="xxfi_close.html">mlfi_close</a>, /* connection cleanup */
<A href="xxfi_connect.html">mlfi_connect</A>, /* connection info filter */
<A href="xxfi_helo.html">mlfi_helo</A>, /* SMTP HELO command filter */
<A href="xxfi_envfrom.html">mlfi_envfrom</A>, /* envelope sender filter */
<A href="xxfi_envrcpt.html">mlfi_envrcpt</A>, /* envelope recipient filter */
<A href="xxfi_header.html">mlfi_header</A>, /* header filter */
<A href="xxfi_eoh.html">mlfi_eoh</A>, /* end of header */
<A href="xxfi_body.html">mlfi_body</A>, /* body block filter */
<A href="xxfi_eom.html">mlfi_eom</A>, /* end of message */
<A href="xxfi_abort.html">mlfi_abort</A>, /* message aborted */
<A href="xxfi_close.html">mlfi_close</A>, /* connection cleanup */
<A href="xxfi_unknown.html">mlfi_unknown</A>, /* unknown SMTP commands */
<A href="xxfi_data.html">mlfi_data</A>, /* DATA command */
<A href="xxfi_negotiate.html">mlfi_negotiate</A> /* Once, at the start of each SMTP connection */
};
static void
@ -411,7 +444,7 @@ main(argc, argv)
optarg);
exit(EX_USAGE);
}
if (<a href="smfi_setconn.html">smfi_setconn</a>(optarg) == MI_FAILURE)
if (<A href="smfi_setconn.html">smfi_setconn</A>(optarg) == MI_FAILURE)
{
(void) fprintf(stderr,
"smfi_setconn failed\n");
@ -438,7 +471,7 @@ main(argc, argv)
optarg);
exit(EX_USAGE);
}
if (<a href="smfi_settimeout.html">smfi_settimeout</a>(atoi(optarg)) == MI_FAILURE)
if (<A href="smfi_settimeout.html">smfi_settimeout</A>(atoi(optarg)) == MI_FAILURE)
{
(void) fprintf(stderr,
"smfi_settimeout failed\n");
@ -481,24 +514,24 @@ main(argc, argv)
usage(argv[0]);
exit(EX_USAGE);
}
if (<a href="smfi_register.html">smfi_register</a>(smfilter) == MI_FAILURE)
if (<A href="smfi_register.html">smfi_register</A>(smfilter) == MI_FAILURE)
{
fprintf(stderr, "smfi_register failed\n");
exit(EX_UNAVAILABLE);
}
return <a href="smfi_main.html">smfi_main</a>();
return <A href="smfi_main.html">smfi_main</A>();
}
/* eof */
</pre>
<hr size="1">
<font size="-1">
Copyright (c) 2000-2004 Sendmail, Inc. and its suppliers.
</PRE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2004, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,98 +1,106 @@
<html>
<head><title>smfi_addheader</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_addheader</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_addheader.html,v 1.15 2004/05/04 17:55:50 ca Exp $
$Id: smfi_addheader.html,v 1.19 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_addheader</h1>
<H1>smfi_addheader</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_addheader(
SMFICTX *ctx,
char *headerf,
char *headerv
);
</pre>
</PRE>
Add a header to the current message.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Adds a header to the current message.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Adds a header to the current message.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>headerf</td>
<td>The header name, a non-NULL, null-terminated string.
</td></tr>
<tr valign="top"><td>headerv</td>
<td>The header value to be added, a non-NULL, null-terminated string. This may be the empty string.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>headerf</TD>
<TD>The header name, a non-NULL, null-terminated string.
</TD></TR>
<TR valign="top"><TD>headerv</TD>
<TD>The header value to be added, a non-NULL, null-terminated string.
This may be the empty string.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_addheader returns MI_FAILURE if:
<ul><li>headerf or headerv is NULL.
<li>Adding headers in the current connection state is invalid.
<li>Memory allocation fails.
<li>A network error occurs.
<li>SMFIF_ADDHDRS was not set when <a href="smfi_register.html">smfi_register</a> was called.
</ul>
<TD>smfi_addheader returns MI_FAILURE if:
<UL><LI>headerf or headerv is NULL.
<LI>Adding headers in the current connection state is invalid.
<LI>Memory allocation fails.
<LI>A network error occurs.
<LI>SMFIF_ADDHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it returns MI_SUCCESS.
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<ul><li>smfi_addheader does not change a message's existing headers.
To change a header's current value, use <a
href="smfi_chgheader.html">smfi_chgheader</a>.
<li>A filter which calls smfi_addheader must have set the SMFIF_ADDHDRS flag in the smfiDesc_str passed to <a href="smfi_register.html">smfi_register</a>.
<li>For smfi_addheader, filter order is important. <b>Later filters will see the header changes made by earlier ones.</b>
<li>Neither the name nor the value of the header is checked for
standards compliance. However, each line of the header must be under
2048 characters and should be under 998 characters. If longer headers
are needed, make them multi-line. To make a multi-line header, insert
a line feed (ASCII 0x0a, or <tt>\n</tt> in C) followed by at least
one whitespace character such as a space (ASCII 0x20) or tab (ASCII 0x09,
or <tt>\t</tt> in C). The line feed should NOT be preceded by a
carriage return (ASCII 0x0d); the MTA will add this automatically.
<b>It is the filter writer's responsibility to ensure that no standards
are violated.</b>
</ul>
</td>
</tr>
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
<UL><LI>smfi_addheader does not change a message's existing headers.
To change a header's current value, use
<A HREF="smfi_chgheader.html">smfi_chgheader</A>.
<LI>A filter which calls smfi_addheader must have set the SMFIF_ADDHDRS
flag in the smfiDesc_str passed to
<A href="smfi_register.html">smfi_register</A>.
<LI>For smfi_addheader, filter order is important.
<B>Later filters will see the header changes made by earlier ones.</B>
<LI>Neither the name nor the value of the header is checked for
standards compliance.
However, each line of the header must be under 2048 characters
and should be under 998 characters.
If longer headers are needed, make them multi-line.
To make a multi-line header,
insert a line feed (ASCII 0x0a, or <TT>\n</TT> in C)
followed by at least one whitespace character
such as a space (ASCII 0x20) or tab (ASCII 0x09, or <TT>\t</TT> in C).
The line feed should NOT be preceded by a carriage return (ASCII 0x0d);
the MTA will add this automatically.
<B>It is the filter writer's responsibility to ensure that no standards
are violated.</B>
<LI>The MTA adds a leading space to an added header value.
</UL>
</TD>
</TR>
<!----------- Example code ---------->
<tr>
<th valign="top" align=left>EXAMPLE</th>
<TR>
<TH valign="top" align=left>EXAMPLE</TH>
<td>
<pre>
<TD>
<PRE>
int ret;
SMFICTX *ctx;
@ -100,19 +108,19 @@ href="smfi_chgheader.html">smfi_chgheader</a>.
ret = smfi_addheader(ctx, "Content-Type",
"multipart/mixed;\n\tboundary=\"foobar\"");
</pre>
</td>
</tr>
</PRE>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,83 +1,83 @@
<html>
<head><title>smfi_addrcpt</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_addrcpt</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_addrcpt.html,v 1.9 2003/10/08 17:55:00 gshapiro Exp $
$Id: smfi_addrcpt.html,v 1.11 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_addrcpt</h1>
<H1>smfi_addrcpt</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_addrcpt(
SMFICTX *ctx,
char *rcpt
);
</pre>
</PRE>
Add a recipient for the current message.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Add a recipient to the message envelope.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Add a recipient to the message envelope.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>rcpt</td>
<td>The new recipient's address.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>rcpt</TD>
<TD>The new recipient's address.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_addrcpt will fail and return MI_FAILURE if:
<ul><li>rcpt is NULL.
<li>Adding recipients in the current connection state is invalid.
<li>A network error occurs.
<li>SMFIF_ADDRCPT was not set when <a href="smfi_register.html">smfi_register</a> was called.
</ul>
<TD>smfi_addrcpt will fail and return MI_FAILURE if:
<UL><LI>rcpt is NULL.
<LI>Adding recipients in the current connection state is invalid.
<LI>A network error occurs.
<LI>SMFIF_ADDRCPT was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it will return MI_SUCCESS.
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
A filter which calls smfi_addrcpt must have set the SMFIF_ADDRCPT flag
in the smfiDesc_str passed to
<a href="smfi_register.html">smfi_register</a>.
</td>
</tr>
<A href="smfi_register.html">smfi_register</A>.
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1,88 @@
<HTML>
<HEAD><TITLE>smfi_addrcpt_par</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_addrcpt_par.html,v 1.4 2007/03/19 16:38:02 ca Exp $
-->
<H1>smfi_addrcpt_par</H1>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_addrcpt_par(
SMFICTX *ctx,
char *rcpt,
char *args
);
</PRE>
Add a recipient for the current message including ESMTP arguments.
</TD></TR>
<!----------- Description ---------->
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Add a recipient to the message envelope.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>rcpt</TD>
<TD>The new recipient's address.
</TD></TR>
<TR valign="top"><TD>args</TD>
<TD>The new recipient's ESMTP parameters.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_addrcpt will fail and return MI_FAILURE if:
<UL><LI>rcpt is NULL.
<LI>Adding recipients in the current connection state is invalid.
<LI>A network error occurs.
<LI>SMFIF_ADDRCPT_PAR was not set when
<A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it will return MI_SUCCESS.
</TD>
</TR>
<!----------- Notes ---------->
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
A filter which calls smfi_addrcpt must have set the SMFIF_ADDRCPT_PAR flag
in the smfiDesc_str passed to
<A href="smfi_register.html">smfi_register</A>.
</TD>
</TR>
</TABLE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1,94 @@
<HTML>
<HEAD><TITLE>smfi_chgfrom</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_chgfrom.html,v 1.3 2006/12/21 18:30:35 ca Exp $
-->
<H1>smfi_chgfrom</H1>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_chgfrom(
SMFICTX *ctx,
const char *mail,
char *args
);
</PRE>
Change the envelope sender (MAIL From) of the current message.
</TD></TR>
<!----------- Description ---------->
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Change the envelope sender (MAIL From) of the current message.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>mail</TD>
<TD>The new sender address.
</TD></TR>
<TR valign="top"><TD>args</TD>
<TD>ESMTP arguments.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<TD>smfi_chgfrom will fail and return MI_FAILURE if:
<UL><LI>mail is NULL.
<LI>Changing the sender in the current connection state is invalid.
<LI>A network error occurs.
<LI>SMFIF_CHGFROM was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it will return MI_SUCCESS.
</TD>
</TR>
<!----------- Notes ---------->
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
A filter which calls smfi_chgfrom must have set the SMFIF_CHGFROM flag
in the smfiDesc_str passed to
<A href="smfi_register.html">smfi_register</A>.
<BR>
Even though all ESMTP arguments could be set via this call,
it does not make sense to do so for many of them,
e.g., SIZE and BODY.
Setting those may cause problems, proper care must be taken.
Moreover, there is no feedback from the MTA to the milter
whether the call was successful.
</TD>
</TR>
</TABLE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</FONT>
</BODY>
</HTML>

View File

@ -1,15 +1,15 @@
<html>
<head><title>smfi_chgheader</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_chgheader</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_chgheader.html,v 1.15 2003/04/30 22:10:53 ca Exp $
$Id: smfi_chgheader.html,v 1.17 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_chgheader</h1>
<H1>smfi_chgheader</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_chgheader(
SMFICTX *ctx,
@ -17,84 +17,84 @@ int smfi_chgheader(
mi_int32 hdridx,
char *headerv
);
</pre>
</PRE>
Change or delete a message header.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Changes a header's value for the current message.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Changes a header's value for the current message.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>headerf</td>
<td>The header name, a non-NULL, null-terminated string.
</td></tr>
<tr valign="top"><td>hdridx</td>
<td>Header index value (1-based). A hdridx value of 1 will modify the first occurrence of a header named headerf. If hdridx is greater than the number of times headerf appears, a new copy of headerf will be added.
</td></tr>
<tr valign="top"><td>headerv</td>
<td>The new value of the given header. headerv == NULL implies that the header should be deleted.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>headerf</TD>
<TD>The header name, a non-NULL, null-terminated string.
</TD></TR>
<TR valign="top"><TD>hdridx</TD>
<TD>Header index value (1-based). A hdridx value of 1 will modify the first occurrence of a header named headerf. If hdridx is greater than the number of times headerf appears, a new copy of headerf will be added.
</TD></TR>
<TR valign="top"><TD>headerv</TD>
<TD>The new value of the given header. headerv == NULL implies that the header should be deleted.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>
<TD>
smfi_chgheader will return MI_FAILURE if
<ul><li>headerf is NULL
<li>Modifying headers in the current connection state is invalid.
<li>Memory allocation fails.
<li>A network error occurs.
<li>SMFIF_CHGHDRS was not set when <a href="smfi_register.html">smfi_register</a> was called.
</ul>
<UL><LI>headerf is NULL
<LI>Modifying headers in the current connection state is invalid.
<LI>Memory allocation fails.
<LI>A network error occurs.
<LI>SMFIF_CHGHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it returns MI_SUCCESS.
</tr>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<ul><li>While smfi_chgheader may be used to add new headers, it is more efficient and far safer to use <a href="smfi_addheader.html">smfi_addheader</a>.
<li>A filter which calls smfi_chgheader must have set the SMFIF_CHGHDRS flag in the smfiDesc_str passed to <a href="smfi_register.html">smfi_register</a>.
<li>For smfi_chgheader, filter order is important. <b>Later filters will see the header changes made by earlier ones.</b>
<li>Neither the name nor the value of the header is checked for
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
<UL><LI>While smfi_chgheader may be used to add new headers, it is more efficient and far safer to use <A href="smfi_addheader.html">smfi_addheader</A>.
<LI>A filter which calls smfi_chgheader must have set the SMFIF_CHGHDRS flag in the smfiDesc_str passed to <A href="smfi_register.html">smfi_register</A>.
<LI>For smfi_chgheader, filter order is important. <B>Later filters will see the header changes made by earlier ones.</B>
<LI>Neither the name nor the value of the header is checked for
standards compliance. However, each line of the header must be under
2048 characters and should be under 998 characters. If longer headers
are needed, make them multi-line. To make a multi-line header, insert
a line feed (ASCII 0x0a, or <tt>\n</tt> in C) followed by at least
a line feed (ASCII 0x0a, or <TT>\n</TT> in C) followed by at least
one whitespace character such as a space (ASCII 0x20) or tab (ASCII 0x09,
or <tt>\t</tt> in C). The line feed should NOT be preceded by a
or <TT>\t</TT> in C). The line feed should NOT be preceded by a
carriage return (ASCII 0x0d); the MTA will add this automatically.
<b>It is the filter writer's responsibility to ensure that no standards
are violated.</b>
</ul>
</td>
</tr>
<B>It is the filter writer's responsibility to ensure that no standards
are violated.</B>
</UL>
</TD>
</TR>
<!----------- Example code ---------->
<tr>
<th valign="top" align=left>EXAMPLE</th>
<TR>
<TH valign="top" align=left>EXAMPLE</TH>
<td>
<pre>
<TD>
<PRE>
int ret;
SMFICTX *ctx;
@ -102,19 +102,19 @@ Otherwise, it returns MI_SUCCESS.
ret = smfi_chgheader(ctx, "Content-Type", 1,
"multipart/mixed;\n\tboundary=\"foobar\"");
</pre>
</td>
</tr>
</PRE>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,82 +1,82 @@
<html>
<head><title>smfi_delrcpt</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_delrcpt</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_delrcpt.html,v 1.9 2003/10/27 15:51:12 ca Exp $
$Id: smfi_delrcpt.html,v 1.11 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_delrcpt</h1>
<H1>smfi_delrcpt</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_delrcpt(
SMFICTX *ctx;
char *rcpt;
);
</pre>
</PRE>
Remove a recipient from the current message's envelope.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_delrcpt removes the named recipient from the current message's envelope.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_delrcpt removes the named recipient from the current message's envelope.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>rcpt</td>
<td>The recipient address to be removed, a non-NULL, null-terminated string.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>rcpt</TD>
<TD>The recipient address to be removed, a non-NULL, null-terminated string.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_delrcpt will fail and return MI_FAILURE if:
<ul>
<li>rcpt is NULL.
<li>Deleting recipients in the current connection state is invalid.
<li>A network error occurs.
<li>SMFIF_DELRCPT was not set when <a href="smfi_register.html">smfi_register</a> was called.
</ul>
<TD>smfi_delrcpt will fail and return MI_FAILURE if:
<UL>
<LI>rcpt is NULL.
<LI>Deleting recipients in the current connection state is invalid.
<LI>A network error occurs.
<LI>SMFIF_DELRCPT was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it will return MI_SUCCESS
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
The addresses to be removed must match exactly. For example, an address and its expanded form do not match.
</td>
</tr>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,62 +1,62 @@
<html>
<head><title>smfi_getpriv</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_getpriv</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_getpriv.html,v 1.7 2003/03/05 19:57:54 ca Exp $
$Id: smfi_getpriv.html,v 1.9 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_getpriv</h1>
<H1>smfi_getpriv</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
void* smfi_getpriv(
SMFICTX *ctx
);
</pre>
</PRE>
Get the connection-specific data pointer for this connection.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_getpriv may be called in any of the xxfi_* callbacks.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>None.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_getpriv may be called in any of the xxfi_* callbacks.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>None.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_getpriv returns the private data pointer stored by a prior call to <a href="smfi_setpriv.html">smfi_setpriv</a>, or NULL if none has been set.</td>
</tr>
<TD>smfi_getpriv returns the private data pointer stored by a prior call to <A href="smfi_setpriv.html">smfi_setpriv</A>, or NULL if none has been set.</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,99 +1,105 @@
<html>
<head><title>smfi_getsymval</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_getsymval</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_getsymval.html,v 1.10 2003/03/05 19:57:54 ca Exp $
$Id: smfi_getsymval.html,v 1.15 2007/03/19 16:49:11 ca Exp $
-->
<h1>smfi_getsymval</h1>
<H1>smfi_getsymval</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
char* smfi_getsymval(
SMFICTX *ctx,
char *symname
);
</pre>
</PRE>
Get the value of a sendmail macro.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_getsymval may be called from within any of the xxfi_* callbacks. Which macros are defined will depend on when it is called.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>None.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_getsymval may be called from within any of the xxfi_* callbacks. Which macros are defined will depend on when it is called.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>None.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>The opaque context structure.
</td></tr>
<tr valign="top"><td>symname</td>
<td>The name of a sendmail macro.
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>The opaque context structure.
</TD></TR>
<TR valign="top"><TD>symname</TD>
<TD>The name of a sendmail macro.
Single letter macros can optionally be enclosed in braces ("{" and "}"),
longer macro names must be enclosed in braces, just as in a
<tt>sendmail.cf</tt> file.
<a href="#notes">See below</a> for default macros.
</td></tr>
</table>
</td></tr>
<TT>sendmail.cf</TT> file.
<A href="#notes">See below</A> for default macros.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_getsymval returns the value of the given macro as a null-terminated string, or NULL if the macro is not defined.</td>
</tr>
<TD>smfi_getsymval returns the value of the given macro as a null-terminated string, or NULL if the macro is not defined.</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th><a name="notes">NOTES</A></th>
<td>
<TR align="left" valign=top>
<TH><A name="notes">NOTES</A></TH>
<TD>
By default, the following macros are valid in the given contexts:
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Sent With</th><th>Macros</th></tr>
<tr><td>xxfi_connect</td> <td>daemon_name, if_name, if_addr, j, _</td></tr>
<tr><td>xxfi_helo</td> <td>tls_version, cipher, cipher_bits, cert_subject, cert_issuer</td></tr>
<tr><td>xxfi_envfrom</td> <td>i, auth_type, auth_authen, auth_ssf, auth_author,
mail_mailer, mail_host, mail_addr</td></tr>
<tr><td>xxfi_envrcpt</td> <td>rcpt_mailer, rcpt_host, rcpt_addr</td></tr>
</table>
<p>
All macros stay in effect from the point they are received until the
end of the connection for the first two sets, the end of the message
for the third (xxfi_envfrom), and just for each recipient for the
final set (xxfi_envrcpt).
<p>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Sent With</TH><TH>Macros</TH></TR>
<TR><TD>xxfi_connect</TD> <TD>daemon_name, if_name, if_addr, j, _</TD></TR>
<TR><TD>xxfi_helo</TD> <TD>tls_version, cipher, cipher_bits, cert_subject, cert_issuer</TD></TR>
<TR><TD>xxfi_envfrom</TD> <TD>i, auth_type, auth_authen, auth_ssf, auth_author,
mail_mailer, mail_host, mail_addr</TD></TR>
<TR><TD>xxfi_envrcpt</TD> <TD>rcpt_mailer, rcpt_host, rcpt_addr</TD></TR>
<TR><TD>xxfi_data</TD> <TD>(none)</TD></TR>
<TR><TD>xxfi_eoh</TD> <TD>(none)</TD></TR>
<TR><TD>xxfi_eom</TD> <TD>msg_id</TD></TR>
</TABLE>
<P>
All macros stay in effect from the point they are received
until the end of the connection for the first two sets,
the end of the message for the third (xxfi_envfrom) and last (xxfi_eom),
and just for each recipient for xxfi_envrcpt.
<P>
The macro list can be changed using the confMILTER_MACROS_* options in
sendmail.mc. The scopes of such macros will be determined by when
they are set by sendmail. For descriptions of macros' values, please
see the "Sendmail Installation and Operation Guide" provided with your
sendmail distribution.
sendmail.mc.
The scopes of such macros will be determined by when they are set by sendmail.
For descriptions of macros' values,
please see the
"Sendmail Installation and Operation Guide"
provided with your sendmail distribution.
</td>
</tr>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2000, 2002-2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2002-2003, 2007 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,15 +1,15 @@
<html>
<head><title>smfi_insheader</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_insheader</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_insheader.html,v 1.3 2004/05/04 16:20:34 gshapiro Exp $
$Id: smfi_insheader.html,v 1.9 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_insheader</h1>
<H1>smfi_insheader</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_insheader(
SMFICTX *ctx,
@ -17,107 +17,129 @@ int smfi_insheader(
char *headerf,
char *headerv
);
</pre>
</PRE>
Prepend a header to the current message.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Prepends a header to the current message.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Prepends a header to the current message.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>hdridx</td>
<td>The location in the internal header list where this header should
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>hdridx</TD>
<TD>The location in the internal header list where this header should
be inserted; 0 makes it the topmost header, etc.
</td></tr>
<tr valign="top"><td>headerf</td>
<td>The header name, a non-NULL, null-terminated string.
</td></tr>
<tr valign="top"><td>headerv</td>
<td>The header value to be added, a non-NULL, null-terminated string. This may be the empty string.
</td></tr>
</table>
</td></tr>
</TD></TR>
<TR valign="top"><TD>headerf</TD>
<TD>The header name, a non-NULL, null-terminated string.
</TD></TR>
<TR valign="top"><TD>headerv</TD>
<TD>The header value to be added, a non-NULL, null-terminated string. This may be the empty string.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_insheader returns MI_FAILURE if:
<ul><li>headerf or headerv is NULL.
<li>Adding headers in the current connection state is invalid.
<li>Memory allocation fails.
<li>A network error occurs.
<li>SMFIF_ADDHDRS was not set when <a href="smfi_register.html">smfi_register</a> was called.
</ul>
<TD>smfi_insheader returns MI_FAILURE if:
<UL><LI>headerf or headerv is NULL.
<LI>Adding headers in the current connection state is invalid.
<LI>Memory allocation fails.
<LI>A network error occurs.
<LI>SMFIF_ADDHDRS was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it returns MI_SUCCESS.
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<ul><li>smfi_insheader does not change a message's existing headers.
To change a header's current value, use <a
href="smfi_chgheader.html">smfi_chgheader</a>.
<li>A filter which calls smfi_insheader must have set the SMFIF_ADDHDRS flag in the smfiDesc_str passed to <a href="smfi_register.html">smfi_register</a>.
<li>For smfi_insheader, filter order is important. <b>Later filters will see the header changes made by earlier ones.</b>
<li>If hdridx is a number larger than the number of headers in the message, the header will simply be appended.
<li>Neither the name nor the value of the header is checked for
standards compliance. However, each line of the header must be under
2048 characters and should be under 998 characters. If longer headers
are needed, make them multi-line. To make a multi-line header, insert
a line feed (ASCII 0x0a, or <tt>\n</tt> in C) followed by at least
one whitespace character such as a space (ASCII 0x20) or tab (ASCII 0x09,
or <tt>\t</tt> in C). The line feed should NOT be preceded by a
carriage return (ASCII 0x0d); the MTA will add this automatically.
<b>It is the filter writer's responsibility to ensure that no standards
are violated.</b>
</ul>
</td>
</tr>
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
<UL>
<LI>smfi_insheader does not change a message's existing headers.
To change a header's current value, use
<A HREF="smfi_chgheader.html">smfi_chgheader</A>.
<LI>A filter which calls smfi_insheader must have set the SMFIF_ADDHDRS
flag in the smfiDesc_str passed to
<A href="smfi_register.html">smfi_register</A>.
<LI>For smfi_insheader, filter order is important.
<B>Later filters will see the header changes made by earlier ones.</B>
<LI>A filter will receive <EM>only</EM> headers that have been sent
by the SMTP client and those header modifications by earlier filters.
It will <EM>not</EM> receive the headers that are inserted by sendmail
itself.
This makes the header insertion position highly dependent on
the headers that exist in the incoming message
and those that are configured to be added by sendmail.
For example, sendmail will always add a
<CODE>Received:</CODE> header to the beginning of the headers.
Setting <CODE>hdridx</CODE> to 0 will actually insert the header
before this <CODE>Received:</CODE> header.
However, later filters can be easily confused as they receive
the added header, but not the <CODE>Received:</CODE> header,
thus making it hard to insert a header at a fixed position.
<LI>If hdridx is a number larger than the number of headers in the message,
the header will simply be appended.
<LI>Neither the name nor the value of the header is checked for
standards compliance.
However, each line of the header must be under 2048 characters
and should be under 998 characters.
If longer headers are needed, make them multi-line.
To make a multi-line header,
insert a line feed (ASCII 0x0a, or <TT>\n</TT> in C)
followed by at least one whitespace character
such as a space (ASCII 0x20) or tab (ASCII 0x09, or <TT>\t</TT> in C).
The line feed should NOT be preceded by a carriage return (ASCII 0x0d);
the MTA will add this automatically.
<B>It is the filter writer's responsibility to ensure that no standards
are violated.</B>
</UL>
</TD>
</TR>
<!----------- Example code ---------->
<tr>
<th valign="top" align=left>EXAMPLE</th>
<TR>
<TH valign="top" align=left>EXAMPLE</TH>
<td>
<pre>
<TD>
<PRE>
int ret;
SMFICTX *ctx;
...
ret = smfi_insheader(ctx, 0, "First", "See me?");
</pre>
</td>
</tr>
</PRE>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2004 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2004, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,51 +1,51 @@
<html>
<head><title>smfi_main</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_main</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_main.html,v 1.7 2003/03/05 19:57:54 ca Exp $
$Id: smfi_main.html,v 1.9 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_main</h1>
<H1>smfi_main</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_main(
);
</pre>
</PRE>
Hand control to libmilter event loop.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_main is called after a filter's initialization is complete.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_main hands control to the Milter event loop.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_main is called after a filter's initialization is complete.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_main hands control to the Milter event loop.</TD>
</TR>
</TABLE>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_main will return MI_FAILURE if it fails to establish a connection. This may occur for any of a variety of reasons (e.g. invalid address passed to <a href="smfi_setconn.html">smfi_setconn</a>). The reason for the failure will be logged. Otherwise, smfi_main will return MI_SUCCESS.</td>
</tr>
<TD>smfi_main will return MI_FAILURE if it fails to establish a connection. This may occur for any of a variety of reasons (e.g. invalid address passed to <A href="smfi_setconn.html">smfi_setconn</A>). The reason for the failure will be logged. Otherwise, smfi_main will return MI_SUCCESS.</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,78 +1,78 @@
<html>
<head><title>smfi_opensocket</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_opensocket</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_opensocket.html,v 1.4 2003/10/20 22:28:57 msk Exp $
$Id: smfi_opensocket.html,v 1.6 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_opensocket</h1>
<H1>smfi_opensocket</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_opensocket(
bool rmsocket
);
</pre>
</PRE>
Attempt to create the interface socket MTAs will use to connect to the
filter.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from program mainline, before calling
<tt>smfi_main()</tt>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_opensocket attempts to create the socket specified previously by
a call to <tt>smfi_setconn()</tt> which will be the interface between MTAs
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from program mainline, before calling
<TT>smfi_main()</TT>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_opensocket attempts to create the socket specified previously by
a call to <TT>smfi_setconn()</TT> which will be the interface between MTAs
and the filter. This allows the calling application to ensure that the
socket can be created. If this is not called, <tt>smfi_main()</tt> will
do so implicitly. </td>
</tr>
</table>
socket can be created. If this is not called, <TT>smfi_main()</TT> will
do so implicitly. </TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>rmsocket</td>
<td>A flag indicating whether or not the library should try to
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>rmsocket</TD>
<TD>A flag indicating whether or not the library should try to
remove any existing UNIX domain socket before trying to create
a new one.
</td></tr>
</table>
</td></tr>
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_opensocket will fail and return MI_FAILURE if:
<ul>
<li>The interface socket could not be created for any reason.
<li><tt>rmsocket</tt> was <tt>true</tt>, and either the socket could
<TD>smfi_opensocket will fail and return MI_FAILURE if:
<UL>
<LI>The interface socket could not be created for any reason.
<LI><TT>rmsocket</TT> was <TT>true</TT>, and either the socket could
not be examined, or exists and could not be removed.
<li><tt>smfi_setconn()</tt> has not been called.
</ul>
<LI><TT>smfi_setconn()</TT> has not been called.
</UL>
Otherwise, it will return MI_SUCCESS
</td>
</tr>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,68 +1,68 @@
<html>
<head><title>smfi_progress</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_progress</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_progress.html,v 1.3 2003/03/05 19:57:54 ca Exp $
$Id: smfi_progress.html,v 1.5 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_progress</h1>
<H1>smfi_progress</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_progress(
SMFICTX *ctx;
);
</pre>
</PRE>
Notify the MTA that an operation is still in progress.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_progress notifies the MTA that the filter is still working
on a message, causing the MTA to re-start its timeouts.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_progress notifies the MTA that the filter is still working
on a message, causing the MTA to re-start its timeouts.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_progress will fail and return MI_FAILURE if:
<ul>
<li>A network error occurs.
</ul>
<TD>smfi_progress will fail and return MI_FAILURE if:
<UL>
<LI>A network error occurs.
</UL>
Otherwise, it will return MI_SUCCESS
</td>
</tr>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,73 +1,73 @@
<html>
<head><title>smfi_quarantine</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_quarantine</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_quarantine.html,v 1.3 2003/03/05 19:57:54 ca Exp $
$Id: smfi_quarantine.html,v 1.5 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_quarantine</h1>
<H1>smfi_quarantine</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_quarantine(
SMFICTX *ctx;
char *reason;
);
</pre>
</PRE>
Quarantine the message using the given reason.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_quarantine quarantines the message using the given reason.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_quarantine quarantines the message using the given reason.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>reason</td>
<td>The quarantine reason, a non-NULL and non-empty null-terminated string.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>reason</TD>
<TD>The quarantine reason, a non-NULL and non-empty null-terminated string.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_quarantine will fail and return MI_FAILURE if:
<ul>
<li>reason is NULL or empty.
<li>A network error occurs.
<li>SMFIF_QUARANTINE was not set when <a href="smfi_register.html">smfi_register</a> was called.
</ul>
<TD>smfi_quarantine will fail and return MI_FAILURE if:
<UL>
<LI>reason is NULL or empty.
<LI>A network error occurs.
<LI>SMFIF_QUARANTINE was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it will return MI_SUCCESS
</td>
</tr>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2002-2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,113 +1,129 @@
<html>
<head><title>smfi_register</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_register</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_register.html,v 1.11 2003/05/26 04:10:52 gshapiro Exp $
$Id: smfi_register.html,v 1.18 2006/12/20 18:37:11 ca Exp $
-->
<h1>smfi_register</h1>
<H1>smfi_register</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_register(
smfiDesc descr
);
</pre>
</PRE>
Register a set of filter callbacks.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=1>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_register must be called before smfi_main</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_register creates a filter using the information given in the
smfiDesc argument. Multiple calls to smfi_register within a
single process are not allowed.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=1>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_register must be called before smfi_main</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_register creates a filter using the information given in the
smfiDesc argument.
Multiple (successful) calls to smfi_register within a
single process are not allowed,
i.e., only one filter can be successfully registered.
Note, however, that the library may not check whether this restriction
is obeyed.
</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>descr</td>
<td>
A filter descriptor of type smfiDesc describing the filter's
functions. The structure has the following members:
<pre>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>descr</TD>
<TD>
A filter descriptor of type smfiDesc describing the filter's functions.
<A NAME="smfiDesc">The structure</A> has the following members:
<PRE>
struct smfiDesc
{
char *xxfi_name; /* filter name */
int xxfi_version; /* version code -- do not change */
unsigned long xxfi_flags; /* <a href="#flags">flags</a> */
unsigned long xxfi_flags; /* <A href="#flags">flags</A> */
/* connection info filter */
sfsistat (*<a href="xxfi_connect.html">xxfi_connect</a>)(SMFICTX *, char *, _SOCK_ADDR *);
sfsistat (*<A href="xxfi_connect.html">xxfi_connect</A>)(SMFICTX *, char *, _SOCK_ADDR *);
/* SMTP HELO command filter */
sfsistat (*<a href="xxfi_helo.html">xxfi_helo</a>)(SMFICTX *, char *);
sfsistat (*<A href="xxfi_helo.html">xxfi_helo</A>)(SMFICTX *, char *);
/* envelope sender filter */
sfsistat (*<a href="xxfi_envfrom.html">xxfi_envfrom</a>)(SMFICTX *, char **);
sfsistat (*<A href="xxfi_envfrom.html">xxfi_envfrom</A>)(SMFICTX *, char **);
/* envelope recipient filter */
sfsistat (*<a href="xxfi_envrcpt.html">xxfi_envrcpt</a>)(SMFICTX *, char **);
sfsistat (*<A href="xxfi_envrcpt.html">xxfi_envrcpt</A>)(SMFICTX *, char **);
/* header filter */
sfsistat (*<a href="xxfi_header.html">xxfi_header</a>)(SMFICTX *, char *, char *);
sfsistat (*<A href="xxfi_header.html">xxfi_header</A>)(SMFICTX *, char *, char *);
/* end of header */
sfsistat (*<a href="xxfi_eoh.html">xxfi_eoh</a>)(SMFICTX *);
sfsistat (*<A href="xxfi_eoh.html">xxfi_eoh</A>)(SMFICTX *);
/* body block */
sfsistat (*<a href="xxfi_body.html">xxfi_body</a>)(SMFICTX *, unsigned char *, size_t);
sfsistat (*<A href="xxfi_body.html">xxfi_body</A>)(SMFICTX *, unsigned char *, size_t);
/* end of message */
sfsistat (*<a href="xxfi_eom.html">xxfi_eom</a>)(SMFICTX *);
sfsistat (*<A href="xxfi_eom.html">xxfi_eom</A>)(SMFICTX *);
/* message aborted */
sfsistat (*<a href="xxfi_abort.html">xxfi_abort</a>)(SMFICTX *);
sfsistat (*<A href="xxfi_abort.html">xxfi_abort</A>)(SMFICTX *);
/* connection cleanup */
sfsistat (*<a href="xxfi_close.html">xxfi_close</a>)(SMFICTX *);
};
</pre>
sfsistat (*<A href="xxfi_close.html">xxfi_close</A>)(SMFICTX *);
A NULL value for any callback function indicates that the filter does
not wish to process the given type of information, simply returning
SMFIS_CONTINUE.
</td></tr>
</table>
</td></tr>
/* any unrecognized or unimplemented command filter */
sfsistat (*xxfi_unknown)(SMFICTX *, const char *);
/* SMTP DATA command filter */
sfsistat (*xxfi_data)(SMFICTX *);
/* negotiation callback */
sfsistat (*<A HREF="xxfi_negotiate.html">xxfi_negotiate</A>)(SMFICTX *,
unsigned long, unsigned long, unsigned long, unsigned long,
unsigned long *, unsigned long *, unsigned long *, unsigned long *);
};
</PRE>
A NULL value for any callback function indicates that the filter
does not wish to process the given type of information,
simply returning SMFIS_CONTINUE.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>
<TD>
smfi_register may return MI_FAILURE for any of the following reasons:
<ul>
<li>memory allocation failed.
<li>incompatible version or illegal flags value.
</ul>
<UL>
<LI>memory allocation failed.
<LI>incompatible version or illegal flags value.
</UL>
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
<a name="flags"></A>
The xxfi_flags field should contain the bitwise OR of zero or more of
<A NAME="flags">The xxfi_flags</A>
field should contain the bitwise OR of zero or more of
the following values, describing the actions the filter may take:
<TABLE BORDER CELLPADDING="1" cellspacing=1>
<tr valign="top" bgcolor="#dddddd"><th align="left">Flag</th><th align="center">Description</th></tr>
<TR valign="top" bgcolor="#dddddd"><TH align="left">Flag</TH><TH align="center">Description</TH></TR>
<TR align="left" valign=top>
<TD>
SMFIF_ADDHDRS
</TD>
<TD>
This filter may add headers.
This filter may <A HREF="smfi_addheader.html">add headers</A>.
</TD>
</TR>
<TR align="left" valign=top>
@ -115,7 +131,8 @@ the following values, describing the actions the filter may take:
SMFIF_CHGHDRS
</TD>
<TD>
This filter may change and/or delete headers.
This filter may
<A HREF="smfi_chgheader.html">change and/or delete headers</A>.
</TD>
</TR>
<TR align="left" valign=top>
@ -123,7 +140,8 @@ the following values, describing the actions the filter may take:
SMFIF_CHGBODY
</TD>
<TD>
This filter may replace the body during filtering.
This filter may
<A HREF="smfi_replacebody.html">replace the body</A> during filtering.
This may have significant performance impact
if other filters do body filtering after this filter.
</TD>
@ -133,7 +151,18 @@ the following values, describing the actions the filter may take:
SMFIF_ADDRCPT
</TD>
<TD>
This filter may add recipients to the message.
This filter may
<A HREF="smfi_addrcpt.html">add recipients</A>
to the message.
</TD>
</TR>
<TR>
<TD VALIGN="TOP">
SMFIF_ADDRCPT_PAR
</TD>
<TD>
This filter may
<A HREF="smfi_addrcpt_par.html">add recipients including ESMTP args</A>.
</TD>
</TR>
<TR>
@ -141,23 +170,55 @@ the following values, describing the actions the filter may take:
SMFIF_DELRCPT
</TD>
<TD>
This filter may remove recipients from the message.
This filter may
<A HREF="smfi_delrcpt.html">remove recipients</A> from the message.
</TD>
</TR>
<TR>
<TD VALIGN="TOP">
SMFIF_QUARANTINE
</TD>
<TD>
This filter may
<A HREF="smfi_quarantine.html">quarantine</A> a message.
</TD>
</TR>
<TR>
<TD VALIGN="TOP">
SMFIF_CHGFROM
</TD>
<TD>
This filter may
<A HREF="smfi_chgfrom.html">change the envelope sender</A> (MAIL).
</TD>
</TR>
<TR>
<TD VALIGN="TOP">
SMFIF_SETSYMLIST
</TD>
<TD>
This filter can
<A HREF="smfi_setsymlist.html">send a set of symbols (macros)</A>
that it wants.
</TD>
</TR>
</TABLE>
</td>
</tr>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2001, 2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,93 +1,93 @@
<html>
<head><title>smfi_replacebody</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_replacebody</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_replacebody.html,v 1.13 2003/03/05 19:57:54 ca Exp $
$Id: smfi_replacebody.html,v 1.15 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_replacebody</h1>
<H1>smfi_replacebody</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_replacebody(
SMFICTX *ctx,
unsigned char *bodyp,
int bodylen
);
</pre>
</PRE>
Replace message-body data.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called only from <a href="xxfi_eom.html">xxfi_eom</a>. smfi_replacebody may be called more than once.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_replacebody replaces the body of the current message. If called
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called only from <A href="xxfi_eom.html">xxfi_eom</A>. smfi_replacebody may be called more than once.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_replacebody replaces the body of the current message. If called
more than once, subsequent calls result in data being appended to the new
body.
</td>
</tr>
</table>
</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>bodyp</td>
<td>A pointer to the start of the new body data, which does not have to be null-terminated. If bodyp is NULL, it is treated as having length == 0. Body data should be in CR/LF form.
</td></tr>
<tr valign="top"><td>bodylen</td>
<td>The number of data bytes pointed to by bodyp.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>bodyp</TD>
<TD>A pointer to the start of the new body data, which does not have to be null-terminated. If bodyp is NULL, it is treated as having length == 0. Body data should be in CR/LF form.
</TD></TR>
<TR valign="top"><TD>bodylen</TD>
<TD>The number of data bytes pointed to by bodyp.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_replacebody fails and returns MI_FAILURE if:
<ul>
<li>bodyp == NULL and bodylen &gt; 0.
<li>Changing the body in the current connection state is invalid.
<li>A network error occurs.
<li>SMFIF_CHGBODY was not set when <a href="smfi_register.html">smfi_register</a> was called.
</ul>
<TD>smfi_replacebody fails and returns MI_FAILURE if:
<UL>
<LI>bodyp == NULL and bodylen &gt; 0.
<LI>Changing the body in the current connection state is invalid.
<LI>A network error occurs.
<LI>SMFIF_CHGBODY was not set when <A href="smfi_register.html">smfi_register</A> was called.
</UL>
Otherwise, it will return MI_SUCCESS.
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<ul>
<li>Since the message body may be very large, setting SMFIF_CHGBODY may significantly affect filter performance.
<li>If a filter sets SMFIF_CHGBODY but does not call smfi_replacebody, the original body remains unchanged.
<li>For smfi_replacebody, filter order is important. <b>Later filters will see the new body contents created by earlier ones.</b>
</ul>
</td>
</tr>
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
<UL>
<LI>Since the message body may be very large, setting SMFIF_CHGBODY may significantly affect filter performance.
<LI>If a filter sets SMFIF_CHGBODY but does not call smfi_replacebody, the original body remains unchanged.
<LI>For smfi_replacebody, filter order is important. <B>Later filters will see the new body contents created by earlier ones.</B>
</UL>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,63 +1,64 @@
<html>
<head><title>smfi_setbacklog</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_setbacklog</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_setbacklog.html,v 1.3 2003/03/05 19:57:54 ca Exp $
$Id: smfi_setbacklog.html,v 1.6 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_setbacklog</h1>
<H1>smfi_setbacklog</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setbacklog(
int obacklog
);
</pre>
Set the filter's listen backlog value.
</td></tr>
</PRE>
Set the filter's <CODE>listen(2)</CODE> backlog value.
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_setbacklog should only be called before <a href="smfi_main.html">smfi_main</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Sets the incoming socket backlog used by listen(). If smfi_setbacklog is not called, the operating system default is used.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_setbacklog should only be called before <A href="smfi_main.html">smfi_main</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Sets the incoming socket backlog used by <CODE>listen(2)</CODE>.
If smfi_setbacklog is not called, the operating system default is used.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>obacklog</td>
<td>The number of incoming connections to allow in the listen queue.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>obacklog</TD>
<TD>The number of incoming connections to allow in the listen queue.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_setbacklog returns MI_FAILURE if obacklog is less than or equal
to zero.</td>
</tr>
<TD>smfi_setbacklog returns MI_FAILURE if obacklog is less than or equal
to zero.</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2002-2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,92 +1,93 @@
<html>
<head><title>smfi_setconn</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_setconn</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_setconn.html,v 1.14 2003/05/26 05:09:16 gshapiro Exp $
$Id: smfi_setconn.html,v 1.17 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_setconn</h1>
<H1>smfi_setconn</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setconn(
char *oconn;
);
</pre>
</PRE>
Set the socket through which this filter should communicate with sendmail.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_setconn must be called once before <a href="smfi_main.html">smfi_main</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Sets the socket through which the filter communicates with sendmail.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_setconn must be called once before <A href="smfi_main.html">smfi_main</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Sets the socket through which the filter communicates with sendmail.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>oconn</td>
<td>The address of the desired communication socket.
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>oconn</TD>
<TD>The address of the desired communication socket.
The address should be a NULL-terminated string in "proto:address"
format:
<ul>
<li><code>{unix|local}:/path/to/file</code> -- A named pipe.
<li><code>inet:port@{hostname|ip-address}</code> -- An IPV4 socket.
<li><code>inet6:port@{hostname|ip-address}</code> -- An IPV6 socket.
</ul>
</td></tr>
</table>
</td></tr>
<UL>
<LI><CODE>{unix|local}:/path/to/file</CODE> -- A named pipe.
<LI><CODE>inet:port@{hostname|ip-address}</CODE> -- An IPV4 socket.
<LI><CODE>inet6:port@{hostname|ip-address}</CODE> -- An IPV6 socket.
</UL>
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_setconn will not fail on an invalid address.
The failure will only be detected in <a href="smfi_main.html">smfi_main</a></td>.
<TD>smfi_setconn will not fail on an invalid address.
The failure will only be detected in <A href="smfi_main.html">smfi_main</A>.
Nevertheless, smfi_setconn may fail for other reasons, e.g.,
due to a lack of memory.
</tr>
</TD>
</TR>
<tr>
<th valign="top" align=left>NOTES</th>
<TR>
<TH valign="top" align=left>NOTES</TH>
<td>
<ul>
<li>If possible, filters should not run as root when communicating
<TD>
<UL>
<LI>If possible, filters should not run as root when communicating
over unix/local domain sockets.
<li>Unix/local sockets should have their permissions set to
<LI>Unix/local sockets should have their permissions set to
0600 (read/write permission only for the socket's owner) or
0660 (read/write permission for the socket's owner and group)
which is useful if the sendmail RunAsUser option is used.
The permissions for a unix/local domain socket are determined as
usual by <code>umask</code>, which should be set to 007 or 077.
usual by <CODE>umask</CODE>, which should be set to 007 or 077.
Note some operating systems (e.g, Solaris) don't use the
permissions of the socket. On those systems, place the socket in a
protected directory.
</ul>
</td>
</tr>
</UL>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,67 +1,67 @@
<html>
<head><title>smfi_setdbg</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_setdbg</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_setdbg.html,v 1.1 2003/12/03 17:28:49 ca Exp $
$Id: smfi_setdbg.html,v 1.3 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_setdbg</h1>
<H1>smfi_setdbg</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setdbg(
int level;
);
</pre>
</PRE>
Set the debugging (tracing) level for the milter library.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called from any any routine at any time.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>smfi_setdbg sets the milter library's internal debugging level
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called from any any routine at any time.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>smfi_setdbg sets the milter library's internal debugging level
to a new level so that code details may be traced.
A level of zero turns off debugging. The greater
(more positive) the level the more detailed the debugging. Six is
the current, highest, useful value.</td>
</tr>
</table>
the current, highest, useful value.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>level</td>
<td>The new debugging level
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>level</TD>
<TD>The new debugging level
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_setdbg returns MI_SUCCESS by default.
</td>
</tr>
<TD>smfi_setdbg returns MI_SUCCESS by default.
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,15 +1,15 @@
<html>
<head><title>smfi_setmlreply</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_setmlreply</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_setmlreply.html,v 1.1 2004/01/01 00:32:45 gshapiro Exp $
$Id: smfi_setmlreply.html,v 1.4 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_setmlreply</h1>
<H1>smfi_setmlreply</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setmlreply(
SMFICTX *ctx,
@ -17,131 +17,129 @@ int smfi_setmlreply(
char *xcode,
...
);
</pre>
</PRE>
Set the default SMTP error reply code to a multi-line response. Only 4XX
and 5XX replies are accepted.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_setmlreply may be called from any of the xxfi_ callbacks
other than xxfi_connect.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Directly set the SMTP error reply code for this connection to the given
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_setmlreply may be called from any of the xxfi_ callbacks
other than xxfi_connect.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Directly set the SMTP error reply code for this connection to the given
lines after the xcode. The list of arguments must be NULL terminated.
This code will be used on subsequent error replies resulting from actions
taken by this filter.</td>
</tr>
</table>
taken by this filter.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>rcode</td>
<td>The three-digit (RFC 821/2821) SMTP reply code, as a
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>rcode</TD>
<TD>The three-digit (RFC 821/2821) SMTP reply code, as a
null-terminated string. rcode cannot be NULL, and must be a valid
4XX or 5XX reply code.
</td></tr>
<tr valign="top"><td>xcode</td>
<td>The extended (RFC 1893/2034) reply code. If xcode is NULL, no
</TD></TR>
<TR valign="top"><TD>xcode</TD>
<TD>The extended (RFC 1893/2034) reply code. If xcode is NULL, no
extended code is used. Otherwise, xcode must conform to RFC 1893/2034.
</td></tr>
<tr valign="top"><td>...</td>
<td>The remainder of the arguments are single lines of text, up to
</TD></TR>
<TR valign="top"><TD>...</TD>
<TD>The remainder of the arguments are single lines of text, up to
32 arguments, which will be used as the text part of the SMTP
reply. The list must be NULL terminated.
</td></tr>
</table>
</td></tr>
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Example ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<td>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<TD>
For example, the code:<BR>
<pre>
<PRE>
ret = smfi_setmlreply(ctx, "550", "5.7.0",
"Spammer access rejected",
"Please see our policy at:",
"http://www.example.com/spampolicy.html",
NULL);
</pre>
</PRE>
<BR>would give the SMTP response:<BR>
<pre>
<PRE>
550-5.7.0 Spammer access rejected
550-5.7.0 Please see our policy at:
550 5.7.0 http://www.example.com/spampolicy.html
</td>
</tr>
</PRE>
</TD>
</TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_setmlreply will fail and return MI_FAILURE if:
<ul>
<li>The rcode or xcode argument is invalid.
<li>A memory-allocation failure occurs.
<li>If any text line contains a carraige return or line feed.
<li>The length of any text line is more than MAXREPLYLEN (980).
<li>More than 32 lines of text replies are given.
</ul>
<TD>smfi_setmlreply will fail and return MI_FAILURE if:
<UL>
<LI>The rcode or xcode argument is invalid.
<LI>A memory-allocation failure occurs.
<LI>If any text line contains a carraige return or line feed.
<LI>The length of any text line is more than MAXREPLYLEN (980).
<LI>More than 32 lines of text replies are given.
</UL>
Otherwise, it return MI_SUCCESS.
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<ul>
<li>Values passed to smfi_setmlreply are not checked for standards compliance.
<li>The message parameter should contain only printable characters,
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
<UL>
<LI>Values passed to smfi_setmlreply are not checked for standards compliance.
<LI>The message parameter should contain only printable characters,
other characters may lead to undefined behavior.
For example, CR or LF will cause the call to fail,
single '%' characters will cause the text to be ignored
(if there really should be a '%' in the string,
use '%%' just like for <tt>printf(3)</tt>).
<li>For details about reply codes and their meanings, please see RFC's
<a href="http://www.rfc-editor.org/rfc/rfc821.txt">821</a>/
<a href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</a>
use '%%' just like for <TT>printf(3)</TT>).
<LI>For details about reply codes and their meanings, please see RFC's
<A href="http://www.rfc-editor.org/rfc/rfc821.txt">821</A>/
<A href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</A>
and
<a href="http://www.rfc-editor.org/rfc/rfc1893.txt">1893</a>/
<a href="http://www.rfc-editor.org/rfc/rfc2034.txt">2034</a>.
<li>If the reply code (rcode) given is a '4XX' code but SMFI_REJECT is used
<A href="http://www.rfc-editor.org/rfc/rfc1893.txt">1893</A>/
<A href="http://www.rfc-editor.org/rfc/rfc2034.txt">2034</A>.
<LI>If the reply code (rcode) given is a '4XX' code but SMFI_REJECT is used
for the message, the custom reply is not used.
<li>Similarly, if the reply code (rcode) given is a '5XX' code but
<LI>Similarly, if the reply code (rcode) given is a '5XX' code but
SMFI_TEMPFAIL is used for the message, the custom reply is not used.
<BR>
Note: in neither of the last two cases an error is returned to the milter,
libmilter silently ignores the reply code.
<li>
If the milter returns SMFI_TEMPFAIL
and sets the reply code to '421',
then the SMTP server will terminate the SMTP session with a 421
error code.
</ul>
</td>
</tr>
<LI>If the milter returns SMFI_TEMPFAIL and sets the reply code to '421',
then the SMTP server will terminate the SMTP session with a 421 error code.
</UL>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2002-2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,80 +1,80 @@
<html>
<head><title>smfi_setpriv</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_setpriv</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_setpriv.html,v 1.9 2003/03/05 19:57:54 ca Exp $
$Id: smfi_setpriv.html,v 1.11 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_setpriv</h1>
<H1>smfi_setpriv</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setpriv(
SMFICTX *ctx,
void *privatedata
);
</pre>
</PRE>
Set the private data pointer for this connection.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_setpriv may be called in any of the xxfi_* callbacks.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Sets the private data pointer for the context ctx.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_setpriv may be called in any of the xxfi_* callbacks.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Sets the private data pointer for the context ctx.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>privatedata</td>
<td>Pointer to private data. This value will be returned by subsequent calls to <a href="smfi_getpriv.html">smfi_getpriv</a> using ctx.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>privatedata</TD>
<TD>Pointer to private data. This value will be returned by subsequent calls to <A href="smfi_getpriv.html">smfi_getpriv</A> using ctx.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_setpriv returns MI_FAILURE if ctx is an invalid context.
Otherwise, it returns MI_SUCCESS.</td>
</tr>
<TD>smfi_setpriv returns MI_FAILURE if ctx is an invalid context.
Otherwise, it returns MI_SUCCESS.</TD>
</TR>
<tr>
<th valign="top" align=left>NOTES</th>
<TR>
<TH valign="top" align=left>NOTES</TH>
<td>There is only one private data pointer per connection; multiple
<TD>There is only one private data pointer per connection; multiple
calls to smfi_setpriv with different values will cause previous values
to be lost.
<P>
Before a filter terminates it should release the private data
and set the pointer to NULL.
</td>
</TD>
</tr>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,15 +1,15 @@
<html>
<head><title>smfi_setreply</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_setreply</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_setreply.html,v 1.14 2003/11/16 05:04:01 ca Exp $
$Id: smfi_setreply.html,v 1.17 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_setreply</h1>
<H1>smfi_setreply</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setreply(
SMFICTX *ctx,
@ -17,104 +17,101 @@ int smfi_setreply(
char *xcode,
char *message
);
</pre>
</PRE>
Set the default SMTP error reply code. Only 4XX and 5XX replies are accepted.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_setreply may be called from any of the xxfi_ callbacks
other than xxfi_connect.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Directly set the SMTP error reply code for this connection. This code
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_setreply may be called from any of the xxfi_ callbacks
other than xxfi_connect.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Directly set the SMTP error reply code for this connection. This code
will be used on subsequent error replies resulting from actions taken by
this filter.</td>
</tr>
</table>
this filter.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>rcode</td>
<td>The three-digit (RFC 821/2821) SMTP reply code, as a
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>rcode</TD>
<TD>The three-digit (RFC 821/2821) SMTP reply code, as a
null-terminated string. rcode cannot be NULL, and must be a valid
4XX or 5XX reply code.
</td></tr>
<tr valign="top"><td>xcode</td>
<td>The extended (RFC 1893/2034) reply code. If xcode is NULL, no
</TD></TR>
<TR valign="top"><TD>xcode</TD>
<TD>The extended (RFC 1893/2034) reply code. If xcode is NULL, no
extended code is used. Otherwise, xcode must conform to RFC 1893/2034.
</td></tr>
<tr valign="top"><td>message</td>
<td>The text part of the SMTP reply. If message is NULL, an empty message is used.
</td></tr>
</table>
</td></tr>
</TD></TR>
<TR valign="top"><TD>message</TD>
<TD>The text part of the SMTP reply. If message is NULL, an empty message is used.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_setreply will fail and return MI_FAILURE if:
<ul>
<li>The rcode or xcode argument is invalid.
<li>A memory-allocation failure occurs.
</ul>
<TD>smfi_setreply will fail and return MI_FAILURE if:
<UL>
<LI>The rcode or xcode argument is invalid.
<LI>A memory-allocation failure occurs.
</UL>
Otherwise, it return MI_SUCCESS.
</td>
</tr>
</TD>
</TR>
<!----------- Notes ---------->
<tr align="left" valign=top>
<th>NOTES</th>
<td>
<ul>
<li>Values passed to smfi_setreply are not checked for standards compliance.
<li>The message parameter should contain only printable characters,
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>
<UL>
<LI>Values passed to smfi_setreply are not checked for standards compliance.
<LI>The message parameter should contain only printable characters,
other characters may lead to undefined behavior.
For example, CR or LF will cause the call to fail,
single '%' characters will cause the text to be ignored
(if there really should be a '%' in the string,
use '%%' just like for <tt>printf(3)</tt>).
<li>For details about reply codes and their meanings, please see RFC's
<a href="http://www.rfc-editor.org/rfc/rfc821.txt">821</a>/
<a href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</a>
use '%%' just like for <TT>printf(3)</TT>).
<LI>For details about reply codes and their meanings, please see RFC's
<A href="http://www.rfc-editor.org/rfc/rfc821.txt">821</A>/
<A href="http://www.rfc-editor.org/rfc/rfc2821.txt">2821</A>
and
<a href="http://www.rfc-editor.org/rfc/rfc1893.txt">1893</a>/
<a href="http://www.rfc-editor.org/rfc/rfc2034.txt">2034</a>.
<li>If the reply code (rcode) given is a '4XX' code but SMFI_REJECT is used
<A href="http://www.rfc-editor.org/rfc/rfc1893.txt">1893</A>/
<A href="http://www.rfc-editor.org/rfc/rfc2034.txt">2034</A>.
<LI>If the reply code (rcode) given is a '4XX' code but SMFI_REJECT is used
for the message, the custom reply is not used.
<li>Similarly, if the reply code (rcode) given is a '5XX' code but
<LI>Similarly, if the reply code (rcode) given is a '5XX' code but
SMFI_TEMPFAIL is used for the message, the custom reply is not used.
<BR>
Note: in neither of the last two cases an error is returned to the milter,
libmilter silently ignores the reply code.
<li>
If the milter returns SMFI_TEMPFAIL
and sets the reply code to '421',
then the SMTP server will terminate the SMTP session with a 421
error code.
</ul>
</td>
</tr>
<LI>If the milter returns SMFI_TEMPFAIL and sets the reply code to '421',
then the SMTP server will terminate the SMTP session with a 421 error code.
</UL>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2002-2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1,107 @@
<HTML>
<HEAD><TITLE>smfi_setsymlist</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_setsymlist.html,v 1.5 2006/12/21 18:30:35 ca Exp $
-->
<H1>smfi_setsymlist</H1>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_setsymlist(
SMFICTX *ctx,
int stage,
char *macros
);
</PRE>
Set the list of macros that the milter wants to receive from the MTA
for a protocol stage.
</TD></TR>
<!----------- Description ---------->
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>This function must only be called during
<A HREF="xxfi_negotiate.html">xxfi_negotiate()</A>.
</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>This function can be used to override the list of macros that the
milter wants to receive from the MTA.
</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR><TD>ctx</TD>
<TD>the opaque context structure.
</TD></TR>
<TR><TD>stage</TD>
<TD>the protocol stage during which the macro list should be used.
See the file
<CODE>include/libmilter/mfapi.h</CODE> for legal values,
look for the C macros with the prefix
<CODE>SMFIM_</CODE>.
Available protocol stages are at least
the initial connection, HELO/EHLO, MAIL, RCPT, DATA,
end of header, and
the end of a message.
</TD></TR>
<TR><TD>macros</TD>
<TD>list of macros (separated by space).
Example: "{rcpt_mailer} {rcpt_host}"
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<TD>MI_FAILURE is returned if
<UL>
<LI>there is not enough free memory to make a copy of the macro list,
<LI><CODE>macros</CODE> is <CODE>NULL</CODE> or empty,
<LI><CODE>stage</CODE> is not a valid protocol stage,
<LI>the macro list for
<CODE>stage</CODE> has been set before.
</UL>
Otherwise MI_SUCCESS is returned.
</TD>
</TR>
<!----------- Notes ---------->
<TR align="left" valign=top>
<TH>NOTES</TH>
<TD>There is an internal limit on the number of macros that can be
set (currently 5),
however, this limit is not enforced by libmilter, only by the MTA,
but a possible violation of this restriction is not communicated back to
the milter.</TD>
</TR>
</TABLE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</FONT>
</BODY>
</HTML>

View File

@ -1,66 +1,66 @@
<html>
<head><title>smfi_settimeout</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_settimeout</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_settimeout.html,v 1.11 2003/03/05 19:57:54 ca Exp $
$Id: smfi_settimeout.html,v 1.14 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_settimeout</h1>
<H1>smfi_settimeout</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_settimeout(
int otimeout
);
</pre>
Set the filter's connection timeout value.
</td></tr>
</PRE>
Set the filter's I/O timeout value.
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>smfi_settimeout should only be called before <a href="smfi_main.html">smfi_main</a>.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>Sets the number of seconds libmilter will wait for an MTA connection before
timing out a socket.
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>smfi_settimeout should only be called before <A href="smfi_main.html">smfi_main</A>.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>Sets the number of seconds libmilter will wait
for an MTA communication (read or write) before timing out.
If smfi_settimeout is not called, a default timeout of 7210 seconds is used.
</td>
</tr>
</table>
</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>otimeout</td>
<td>The number of seconds to wait before timing out (&gt; 0). Zero means
no wait, <b>not</b> "wait forever".
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>otimeout</TD>
<TD>The number of seconds to wait before timing out (&gt; 0).
Zero means no wait, <B>not</B> "wait forever".
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_settimeout always returns MI_SUCCESS.</td>
</tr>
<TD>smfi_settimeout always returns MI_SUCCESS.</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2000, 2002-2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2002-2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,74 +1,74 @@
<html>
<head><title>smfi_stop</title></head>
<body>
<HTML>
<HEAD><TITLE>smfi_stop</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_stop.html,v 1.3 2005/10/27 06:08:57 ca Exp $
$Id: smfi_stop.html,v 1.6 2006/12/21 18:30:35 ca Exp $
-->
<h1>smfi_stop</h1>
<H1>smfi_stop</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_stop(void);
</pre>
</PRE>
Shutdown the milter.
No connections will be accepted after this call.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>Called from any of the <a href="api.html#callbacks">Callback</a> routines
or any error-handling routines at any time.</td>
</tr>
<tr align="left" valign=top>
<th width="80">Effects</th>
<td>The smfi_stop routine prevents that new connections
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>Called from any of the <A href="api.html#Callbacks">Callback</A> routines
or any error-handling routines at any time.</TD>
</TR>
<TR align="left" valign=top>
<TH width="80">Effects</TH>
<TD>The smfi_stop routine prevents that new connections
will be accepted,
however, it does not wait for existing connections (threads) to terminate.
It will cause
<a href="smfi_main.html">smfi_main</a> to return to the calling program,
<A href="smfi_main.html">smfi_main</A> to return to the calling program,
which may then exit or warm-restart.
</td>
</tr>
</table>
</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>void</td>
<td>Takes no arguement.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>void</TD>
<TD>Takes no arguement.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>RETURN VALUES</th>
<TR>
<TH valign="top" align=left>RETURN VALUES</TH>
<td>smfi_stop always returns SMFI_CONTINUE. But note:
<ul>
<li>Another internal routine may already have asked the milter to abort.
<li>Another routine may already have asked the milter to stop.
<li>There is no way to cancel the stop process once it has begun.
</ul>
</td>
</tr>
<TD>smfi_stop always returns SMFI_CONTINUE. But note:
<UL>
<LI>Another internal routine may already have asked the milter to abort.
<LI>Another routine may already have asked the milter to stop.
<LI>There is no way to cancel the stop process once it has begun.
</UL>
</TD>
</TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2003, 2005 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1,86 @@
<HTML>
<HEAD><TITLE>smfi_version()</TITLE></HEAD>
<BODY>
<!--
$Id: smfi_version.html,v 1.5 2007/03/22 17:30:57 ca Exp $
-->
<H1>smfi_version()</H1>
<TABLE BORDER="0" CELLSPACING=4 CELLPADDING=4>
<!---------- Synopsis ----------->
<TR><TH VALIGN="TOP" ALIGN=LEFT WIDTH=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
int smfi_version(
unsigned int *pmajor,
unsigned int *pminor,
unsigned int *ppl
);
</PRE>
Get the (runtime) version of libmilter.
</TD></TR>
<!----------- Description ---------->
<TR><TH VALIGN="TOP" ALIGN=LEFT>DESCRIPTION</TH><TD>
<TABLE BORDER="1" CELLSPACING=1 CELLPADDING=4>
<TR ALIGN="LEFT" VALIGN=TOP>
<TH WIDTH="80">Called When</TH>
<TD>smfi_version may be called at any time.</TD>
</TR>
<TR ALIGN="LEFT" VALIGN=TOP>
<TH WIDTH="80">Effects</TH>
<TD>None.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<TR><TH VALIGN="TOP" ALIGN=LEFT>ARGUMENTS</TH><TD>
<TABLE BORDER="1" CELLSPACING=0>
<TR BGCOLOR="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR VALIGN="TOP"><TD>pmajor</TD>
<TD>Pointer to an unsigned int variable to store major version number.
</TD></TR>
<TR VALIGN="TOP"><TD>pminor</TD>
<TD>Pointer to an unsigned int variable to store minor version number.
</TD></TR>
<TR VALIGN="TOP"><TD>ppl</TD>
<TD>Pointer to an unsigned int variable to store patch level number.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
<TH VALIGN="TOP" ALIGN=LEFT>RETURN VALUES</TH>
<TD>smfi_version returns MI_SUCCESS.</TD>
</TR>
</TABLE>
Note: the compile time version of libmilter is available in the macro
<CODE>SMFI_VERSION</CODE>.
A milter can check this macro to determine which functions to use
(at compile time via C preprocessor statements).
Using this macro and the
<CODE>smfi_version()</CODE>
function,
a milter can determine at runtime whether it has been (dynamically)
linked against the expected libmilter version.
To extract the major and minor version as well as the current patch level
from this macro, the macros
<CODE>SM_LM_VRS_MAJOR(v)</CODE>,
<CODE>SM_LM_VRS_MINOR(v)</CODE>, and
<CODE>SM_LM_VRS_PLVL(v)</CODE>
can be used, respectively.
<HR SIZE="1">
<FONT SIZE="-1">
Copyright (c) 2006, 2007 Sendmail, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</FONT>
</BODY>
</HTML>

View File

@ -1,83 +1,83 @@
<html>
<head><title>xxfi_abort</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_abort</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_abort.html,v 1.9 2003/03/05 19:57:55 ca Exp $
$Id: xxfi_abort.html,v 1.12 2006/12/21 18:30:35 ca Exp $
-->
<h1>xxfi_abort</h1>
<H1>xxfi_abort</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_abort)(
SMFICTX * ctx
SMFICTX *ctx
);
</pre>
</PRE>
Handle the current message's being aborted.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_abort may be called at any time during message processing (i.e. between some message-oriented routine and <a href="xxfi_eom.html">xxfi_eom</a>).</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_abort may be called at any time during message processing (i.e. between some message-oriented routine and <A href="xxfi_eom.html">xxfi_eom</A>).</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>
<ul>
<li>xxfi_abort must reclaim any resources allocated on a per-message
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>xxfi_abort must reclaim any resources allocated on a per-message
basis, and must be tolerant of being called between any two
message-oriented callbacks.
<li>Calls to xxfi_abort and <a href="xxfi_eom.html">xxfi_eom</a> are
<LI>Calls to xxfi_abort and <A href="xxfi_eom.html">xxfi_eom</A> are
mutually exclusive.
<li>xxfi_abort is not responsible for reclaiming connection-specific
data, since <a href="xxfi_close.html">xxfi_close</a> is always called
<LI>xxfi_abort is not responsible for reclaiming connection-specific
data, since <A href="xxfi_close.html">xxfi_close</A> is always called
when a connection is closed.
<li>Since the current message is already being aborted, the return
<LI>Since the current message is already being aborted, the return
value is currently ignored.
<li>xxfi_abort is only called if the message is aborted outside the
filter's control <b>and</b> the filter has not completed its
<LI>xxfi_abort is only called if the message is aborted outside the
filter's control <B>and</B> the filter has not completed its
message-oriented processing. For example, if a filter has already
returned SMFIS_ACCEPT, SMFIS_REJECT, or SMFIS_DISCARD from a
message-oriented routine, xxfi_abort will not be called even if the
message is later aborted outside its control.
</ul>
</td>
</tr>
</table>
</UL>
</TD>
</TR>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,83 +1,97 @@
<html>
<head><title>xxfi_body</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_body</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_body.html,v 1.12 2003/03/05 19:57:55 ca Exp $
$Id: xxfi_body.html,v 1.17 2007/03/26 20:12:46 ca Exp $
-->
<h1>xxfi_body</h1>
<H1>xxfi_body</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_body)(
SMFICTX * ctx,
unsigned char * bodyp,
SMFICTX *ctx,
unsigned char *bodyp,
size_t len
);
</pre>
</PRE>
Handle a piece of a message's body.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_body is called zero or more times between xxfi_eoh and xxfi_eom.</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_body is called zero or more times between xxfi_eoh and xxfi_eom.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>bodyp</td>
<td>Pointer to the start of this block of body data. bodyp is not valid outside this call to xxfi_body.
</td></tr>
<tr valign="top"><td>len</td>
<td>The amount of data pointed to by bodyp.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>bodyp</TD>
<TD>Pointer to the start of this block of body data. bodyp is not valid outside this call to xxfi_body.
</TD></TR>
<TR valign="top"><TD>len</TD>
<TD>The amount of data pointed to by bodyp.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>
<ul>
<li>bodyp points to a sequence of bytes.
It is <em>not</em> a C string (a sequence of characters that is terminated by '\0').
Therefore, do not use the usual C string functions like strlen() on this byte block.
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>bodyp points to a sequence of bytes.
It is <EM>not</EM> a C string (a sequence of characters that is terminated by '\0').
Therefore, do not use the usual C string functions like <CODE>strlen(3)</CODE>
on this byte block.
Moreover, the byte sequence may contain '\0' characters inside the block.
Hence even if a trailing '\0' is added, C string functions may still fail
to work as expected.
<li>Since message bodies can be very large, defining xxfi_body can
<LI>Since message bodies can be very large, defining xxfi_body can
significantly impact filter performance.
<li>End-of-lines are represented as received from SMTP (normally CR/LF).
<li>Later filters will see body changes made by earlier ones.
<li>Message bodies may be sent in multiple chunks, with one call to
<LI>End-of-lines are represented as received from SMTP (normally CR/LF).
<LI>Later filters will see body changes made by earlier ones.
<LI>Message bodies may be sent in multiple chunks, with one call to
xxfi_body per chunk.
</ul>
</td>
</tr>
</table>
<LI>Return
<A HREF="api.html#SMFIS_SKIP">SMFIS_SKIP</A>
if a milter has received sufficiently many
body chunks to make a decision,
but still wants to invoke
message modification functions that are only allowed to be called from
<A HREF="xxfi_eom.html">xxfi_eom()</A>.
Note: the milter <EM>must</EM>
<A HREF="xxfi_negotiate.html">negotiate</A>
this behavior with the MTA, i.e., it must check whether
the protocol action
<A HREF="xxfi_negotiate.html#SMFIP_SKIP"><CODE>SMFIP_SKIP</CODE></A>
is available and if so, the milter must request it.
</UL>
</TD>
</TR>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2003, 2007 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,52 +1,52 @@
<html>
<head><title>xxfi_close</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_close</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_close.html,v 1.10 2004/06/16 22:41:36 ca Exp $
$Id: xxfi_close.html,v 1.13 2006/12/21 18:30:35 ca Exp $
-->
<h1>xxfi_close</h1>
<H1>xxfi_close</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_close)(
SMFICTX * ctx
SMFICTX *ctx
);
</pre>
</PRE>
The current connection is being closed.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_close is always called once at the end of each connection.</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_close is always called once at the end of each connection.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>
<ul>
<li>xxfi_close may be called "out-of-order", i.e. before even the
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>xxfi_close may be called "out-of-order", i.e. before even the
xxfi_connect is called.
After a connection is established by the MTA to the filter,
if the MTA decides this connection's traffic will be discarded
@ -58,24 +58,24 @@ and developers should anticipate this possibility when crafting their
xxfi_close code.
In particular, it is incorrect to assume the private context pointer
will be something other than NULL in this callback.
<li>xxfi_close is called on close even if the previous mail
<LI>xxfi_close is called on close even if the previous mail
transaction was aborted.
<li>xxfi_close is responsible for freeing any resources allocated on a
<LI>xxfi_close is responsible for freeing any resources allocated on a
per-connection basis.
<li>Since the connection is already closing, the return value is
<LI>Since the connection is already closing, the return value is
currently ignored.
</ul>
</td>
</tr>
</table>
</UL>
</TD>
</TR>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003, 2004 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,113 +1,121 @@
<html>
<head><title>xxfi_connect</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_connect</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_connect.html,v 1.13 2003/10/29 22:54:16 msk Exp $
$Id: xxfi_connect.html,v 1.19 2007/01/15 22:24:45 ca Exp $
-->
<h1>xxfi_connect</h1>
<H1>xxfi_connect</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_connect)(
SMFICTX *ctx,
char *hostname,
_SOCK_ADDR *hostaddr);
</pre>
</td></tr>
</PRE>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr>
<th valign="top" align=left width=80>Called When</th>
<td>Once, at the start of each SMTP connection.</td>
</tr>
<tr>
<th valign="top" align=left width=80>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR>
<TH valign="top" align=left width=80>Called When</TH>
<TD>Once, at the start of each SMTP connection.</TD>
</TR>
<TR>
<TH valign="top" align=left width=80>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!--
This callback function is invoked on each connection to the mail
filter program. The callback is to be implemented by the Milter
application developers. The name of the callback can be any valid
function name. The function pointer is to be assigned to the
filter program.
The callback is to be implemented by the Milter application developers.
The name of the callback can be any valid function name.
The function pointer is to be assigned to the
smfiDesc.xxfi_connect and the pointer to the smfiDesc structure
is passed to smfi_register().
</td></tr>
</TD></TR>
-->
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr><td>ctx</td>
<td>the opaque context structure.
</td></tr>
<tr><td>hostname</td>
<td>the host name of the message sender, as determined by a
reverse lookup on the host address. If the reverse lookup
fails, hostname will contain the message sender's IP
address enclosed in square brackets (e.g. `[a.b.c.d]').
</td></tr>
<tr><td>hostaddr</td>
<td>the host address, as determined by a getpeername() call on the SMTP socket.
NULL if the type is not supported in the current version or if
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR><TD>ctx</TD>
<TD>the opaque context structure.
</TD></TR>
<TR><TD>hostname</TD>
<TD>the host name of the message sender, as determined by a
reverse lookup on the host address.
If the reverse lookup fails
or if none of the IP addresses of the resolved host name
matches the original IP address,
hostname will contain the message sender's IP
address enclosed in square brackets (e.g. `[a.b.c.d]').
If the SMTP connection is made via stdin the value is
<CODE>localhost</CODE>.
</TD></TR>
<TR><TD>hostaddr</TD>
<TD>the host address,
as determined by a <CODE>getpeername(2)</CODE> call on the SMTP socket.
NULL if the type is not supported in the current version or if
the SMTP connection is made via stdin.
</td></tr>
</table>
</td></tr>
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<!--
<tr>
<th valign="top" align=left>SPECIAL RETURN VALUES</th>
<td><table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr>
<tr valign="top">
<td>SMFIS_ACCEPT</td>
<td>Accept all commands and messages from this client without any
further contact with the filter. </td>
</td>
</tr>
<tr valign="top">
<td>SMFIS_CONTINUE</td>
<td>Continue normal processing. </td>
</tr>
<tr valign="top">
<td>SMFIS_DISCARD</td>
<td>Undefined behaviour; do not use. </td>
</tr>
<tr valign="top">
<td>SMFIS_TEMPFAIL</td>
<td>Reject all commands and messages from this client with a
temporary failure reply code. If also used in conjunction
with <tt>smfi_setreply()</tt> to set a reply whose SMTP
code is 421, the MTA will drop the connection immediately. </td>
</tr>
<tr valign="top">
<td>SMFIS_REJECT</td>
<td>Reject all commands and messages from this client with a
permanent failure reply code. </td>
</tr>
</table>
</tr>
<TR>
<TH valign="top" align=left>SPECIAL RETURN VALUES</TH>
<TD><TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR valign="top">
<TD>SMFIS_ACCEPT</TD>
<TD>Accept all commands and messages from this client without any
further contact with the filter. </TD>
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_CONTINUE</TD>
<TD>Continue normal processing. </TD>
</TR>
<TR valign="top">
<TD>SMFIS_DISCARD</TD>
<TD>Undefined behaviour; do not use. </TD>
</TR>
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
<TD>Reject all commands and messages from this client with a
temporary failure reply code.
If also used in conjunction with <CODE>smfi_setreply()</CODE>
to set a reply whose SMTP code is 421,
the MTA will drop the connection immediately. </TD>
</TR>
<TR valign="top">
<TD>SMFIS_REJECT</TD>
<TD>Reject all commands and messages from this client with a
permanent failure reply code. </TD>
</TR>
</TABLE>
</TR>
-->
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>If an earlier filter rejects the connection in its xxfi_connect()
routine, this filter's xxfi_connect() will not be called.</td>
</tr>
</table>
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>If an earlier filter rejects the connection in its xxfi_connect()
routine, this filter's xxfi_connect() will not be called.</TD>
</TR>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2000-2001, 2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000-2001, 2003, 2007 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1,89 @@
<HTML>
<HEAD><TITLE>xxfi_data</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_data.html,v 1.4 2007/01/25 01:00:20 ca Exp $
-->
<H1>xxfi_data</H1>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_data)(
SMFICTX *ctx
);
</PRE>
Handle the DATA command.
</TD></TR>
<!----------- Description ---------->
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_data is called when the client uses the DATA command.
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
<TH valign="top" align=left>SPECIAL RETURN VALUES</TH>
<TD><TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
<TD>Reject this message with a temporary error.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_REJECT</TD>
<TD>Reject this message.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_DISCARD</TD>
<TD>Accept and silently discard this message.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_ACCEPT</TD>
<TD>Accept this message.
</TD>
</TR>
</TABLE>
</TR>
<!----------- Notes ---------->
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>For more details on ESMTP responses, please see RFC
<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD>
</TR>
</TABLE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</FONT>
</BODY>
</HTML>

View File

@ -1,95 +1,97 @@
<html>
<head><title>xxfi_envfrom</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_envfrom</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_envfrom.html,v 1.9 2003/03/05 19:57:55 ca Exp $
$Id: xxfi_envfrom.html,v 1.14 2007/01/25 01:00:20 ca Exp $
-->
<h1>xxfi_envfrom</h1>
<H1>xxfi_envfrom</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_envfrom)(
SMFICTX * ctx,
char ** argv
SMFICTX *ctx,
char **argv
);
</pre>
Handle the envelope FROM command.
</td></tr>
</PRE>
Handle the MAIL (envelope sender) command.
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_envfrom is called once at the beginning of each message, before xxfi_envrcpt.</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_envfrom is called once at the beginning of each message
(MAIL command),
before xxfi_envrcpt.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>argv</td>
<td>Null-terminated SMTP command arguments;
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>argv</TD>
<TD>Null-terminated SMTP command arguments;
argv[0] is guaranteed to be the sender address.
Later arguments are the ESMTP arguments.
</td></tr>
</table>
</td></tr>
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>SPECIAL RETURN VALUES</th>
<td><table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr>
<tr valign="top">
<td>SMFIS_TEMPFAIL</td>
<td>Reject this sender and message with a temporary error; a new sender (and hence a new message) may subsequently be specified. <a href="xxfi_abort.html">xxfi_abort</a> is not called.
</td>
</tr>
<tr valign="top">
<td>SMFIS_REJECT</td>
<td>Reject this sender and message; a new sender/message may be specified. <a href="xxfi_abort.html">xxfi_abort</a> is not called.
</td>
</tr>
<tr valign="top">
<td>SMFIS_DISCARD</td>
<td>Accept and silently discard this message. <a href="xxfi_abort.html">xxfi_abort</a> is not called.
</td>
</tr>
<tr valign="top">
<td>SMFIS_ACCEPT</td>
<td>Accept this message. <a href="xxfi_abort.html">xxfi_abort</a> is not called.
</td>
</tr>
</table>
</tr>
<TR>
<TH valign="top" align=left>SPECIAL RETURN VALUES</TH>
<TD><TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
<TD>Reject this sender and message with a temporary error; a new sender (and hence a new message) may subsequently be specified. <A href="xxfi_abort.html">xxfi_abort</A> is not called.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_REJECT</TD>
<TD>Reject this sender and message; a new sender/message may be specified. <A href="xxfi_abort.html">xxfi_abort</A> is not called.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_DISCARD</TD>
<TD>Accept and silently discard this message. <A href="xxfi_abort.html">xxfi_abort</A> is not called.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_ACCEPT</TD>
<TD>Accept this message. <A href="xxfi_abort.html">xxfi_abort</A> is not called.
</TD>
</TR>
</TABLE>
</TR>
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>For more details on ESTMP responses, please see RFC
<a href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</a>.</td>
</tr>
</table>
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>For more details on ESMTP responses, please see RFC
<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD>
</TR>
</TABLE>
<hr size="1">
<font size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,97 +1,97 @@
<html>
<head><title>xxfi_envrcpt</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_envrcpt</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_envrcpt.html,v 1.11 2003/12/30 00:19:42 gshapiro Exp $
$Id: xxfi_envrcpt.html,v 1.15 2007/01/25 01:00:20 ca Exp $
-->
<h1>xxfi_envrcpt</h1>
<H1>xxfi_envrcpt</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_envrcpt)(
SMFICTX * ctx,
char ** argv
SMFICTX *ctx,
char **argv
);
</pre>
</PRE>
Handle the envelope RCPT command.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_envrcpt is called once per recipient, hence one or more times per message, immediately after xxfi_envfrom.</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_envrcpt is called once per recipient, hence one or more times per message, immediately after xxfi_envfrom.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>argv</td>
<td>Null-terminated SMTP command arguments;
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>argv</TD>
<TD>Null-terminated SMTP command arguments;
argv[0] is guaranteed to be the recipient address.
Later arguments are the ESMTP arguments.
</td></tr>
</table>
</td></tr>
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<tr>
<th valign="top" align=left>SPECIAL RETURN VALUES</th>
<td><table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Return value</th><th>Description</th></tr>
<tr valign="top">
<td>SMFIS_TEMPFAIL</td>
<td>Temporarily fail for this particular recipient; further recipients
may still be sent. <a href="xxfi_abort.html">xxfi_abort</a> is not called.
</td>
</tr>
<tr valign="top">
<td>SMFIS_REJECT</td>
<td>Reject this particular recipient; further recipients may still be sent.
<a href="xxfi_abort.html">xxfi_abort</a> is not called.
</td>
</tr>
<tr valign="top">
<td>SMFIS_DISCARD</td>
<td>Accept and discard the message. <a href="xxfi_abort.html">xxfi_abort</a> will be called.
</td>
</tr>
<tr valign="top">
<td>SMFIS_ACCEPT</td>
<td>Accept recipient. <a href="xxfi_abort.html">xxfi_abort</a> will not be called.
</td>
</tr>
</table>
</tr>
<TR>
<TH valign="top" align=left>SPECIAL RETURN VALUES</TH>
<TD><TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
<TD>Temporarily fail for this particular recipient; further recipients
may still be sent. <A href="xxfi_abort.html">xxfi_abort</A> is not called.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_REJECT</TD>
<TD>Reject this particular recipient; further recipients may still be sent.
<A href="xxfi_abort.html">xxfi_abort</A> is not called.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_DISCARD</TD>
<TD>Accept and discard the message. <A href="xxfi_abort.html">xxfi_abort</A> will be called.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_ACCEPT</TD>
<TD>Accept recipient. <A href="xxfi_abort.html">xxfi_abort</A> will not be called.
</TD>
</TR>
</TABLE>
</TR>
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>For more details on ESTMP responses, please see RFC
<a href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</a>.</td>
</tr>
</table>
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>For more details on ESMTP responses, please see RFC
<A href="http://www.rfc-editor.org/rfc/rfc1869.txt">1869</A>.</TD>
</TR>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,56 +1,56 @@
<html>
<head><title>xxfi_eoh</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_eoh</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_eoh.html,v 1.8 2003/03/05 19:57:55 ca Exp $
$Id: xxfi_eoh.html,v 1.11 2006/12/21 18:30:35 ca Exp $
-->
<h1>xxfi_eoh</h1>
<H1>xxfi_eoh</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_eoh)(
SMFICTX * ctx
SMFICTX *ctx
);
</pre>
</PRE>
Handle the end of message headers.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_eoh is called once after all headers have been sent and processed.
</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_eoh is called once after all headers have been sent and processed.
</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
</TABLE>
</TD></TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,61 +1,62 @@
<html>
<head><title>xxfi_eom</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_eom</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_eom.html,v 1.9 2003/03/05 19:57:55 ca Exp $
$Id: xxfi_eom.html,v 1.12 2006/12/21 18:30:36 ca Exp $
-->
<h1>xxfi_eom</h1>
<H1>xxfi_eom</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_eom)(
SMFICTX * ctx
SMFICTX *ctx
);
</pre>
</PRE>
End of a message.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_eom is called once after all calls to <a href="xxfi_body.html">xxfi_body</a> for a given message.</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_eom is called once after all calls to <A href="xxfi_body.html">xxfi_body</A> for a given message.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
</table>
</td></tr>
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>A filter is required to make all its modifications to the message headers, body, and envelope in xxfi_eom. Modifications are made via the smfi_* routines.
</td>
</tr>
</table>
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>A filter is required to make all its modifications to the message headers, body, and envelope in xxfi_eom.
Modifications are made via the smfi_* routines.
</TD>
</TR>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,78 +1,111 @@
<html>
<head><title>xxfi_header</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_header</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_header.html,v 1.11 2006/04/05 17:10:43 ca Exp $
$Id: xxfi_header.html,v 1.17 2006/12/21 18:30:36 ca Exp $
-->
<h1>xxfi_header</h1>
<H1>xxfi_header</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_header)(
SMFICTX * ctx,
char * headerf,
char * headerv
SMFICTX *ctx,
char *headerf,
char *headerv
);
</pre>
</PRE>
Handle a message header.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th>
<td>xxfi_header is called zero or more times between xxfi_envrcpt and xxfi_eoh, once per message header.</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_header is called once for each message header.</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>headerf</td>
<td> Header field name.
</td></tr>
<tr valign="top"><td>headerv</td>
<td>Header field value.
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>headerf</TD>
<TD> Header field name.
</TD></TR>
<TR valign="top"><TD>headerv</TD>
<TD>Header field value.
The content of the header may include folded white space,
i.e., multiple lines with following white space
where lines are separated by LF (not CR/LF).
The trailing line terminator (CR/LF) is removed.
</td></tr>
</table>
</td></tr>
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Notes ---------->
<tr>
<th valign="top" align=left>NOTES</th>
<td>
<ul>
<li>Later filters will see header changes/additions made by earlier ones.
<li>For much more detail about header format, please see
RFC <a href="http://www.rfc-editor.org/rfc/rfc822.html">822</a>
</ul>
</td>
</tr>
</table>
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>
<UL>
<LI>Starting with sendmail 8.14, spaces after the colon in a header
field are preserved if requested using the flag
<A HREF="xxfi_negotiate.html#SMFIP_HDR_LEADSPC"><CODE>SMFIP_HDR_LEADSPC</CODE></A>.
That is, the header
<hr size="1">
<font size="-1">
<PRE>
From: sender &lt;f@example.com&gt;
To: user &lt;t@example.com&gt;
Subject:no
</PRE>
will be sent to a milter as
<PRE>
"From", " sender &lt;f@example.com&gt;"
"To", " user &lt;t@example.com&gt;"
"Subject", "no"
</PRE>
while previously
(or without the flag
<A HREF="xxfi_negotiate.html#SMFIP_HDR_LEADSPC"><CODE>SMFIP_HDR_LEADSPC</CODE></A>)
it was:
<PRE>
"From", "sender &lt;f@example.com&gt;"
"To", "user &lt;t@example.com&gt;"
"Subject", "no"
</PRE>
<LI>Later filters will see header changes/additions made by earlier ones.
<LI>For much more detail about header format, please see
RFC <A href="http://www.rfc-editor.org/rfc/rfc822.html">822</A>
and
RFC <A href="http://www.rfc-editor.org/rfc/rfc2822.html">2822</A>
</UL>
</TD>
</TR>
</TABLE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003, 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -1,64 +1,64 @@
<html>
<head><title>xxfi_helo</title></head>
<body>
<HTML>
<HEAD><TITLE>xxfi_helo</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_helo.html,v 1.9 2005/08/30 23:41:45 ca Exp $
$Id: xxfi_helo.html,v 1.12 2006/12/21 18:30:36 ca Exp $
-->
<h1>xxfi_helo</h1>
<H1>xxfi_helo</H1>
<table border="0" cellspacing=4 cellpadding=4>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<tr><th valign="top" align=left width=150>SYNOPSIS</th><td>
<pre>
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_helo)(
SMFICTX * ctx,
char * helohost
SMFICTX *ctx,
char *helohost
);
</pre>
</PRE>
Handle the HELO/EHLO command.
</td></tr>
</TD></TR>
<!----------- Description ---------->
<tr><th valign="top" align=left>DESCRIPTION</th><td>
<table border="1" cellspacing=1 cellpadding=4>
<tr align="left" valign=top>
<th width="80">Called When</th> <td>xxfi_helo is called whenever the client
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH> <TD>xxfi_helo is called whenever the client
sends a HELO/EHLO command.
It may therefore be called several times or even not at all;
some restrictions can be imposed by the MTA configuration.
</td>
</tr>
<tr align="left" valign=top>
<th>Default Behavior</th>
<td>Do nothing; return SMFIS_CONTINUE.</td>
</tr>
</table>
</TD>
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<tr><th valign="top" align=left>ARGUMENTS</th><td>
<table border="1" cellspacing=0>
<tr bgcolor="#dddddd"><th>Argument</th><th>Description</th></tr>
<tr valign="top"><td>ctx</td>
<td>Opaque context structure.
</td></tr>
<tr valign="top"><td>helohost</td>
<td>Value passed to HELO/EHLO command, which should be
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>helohost</TD>
<TD>Value passed to HELO/EHLO command, which should be
the domain name of the sending host (but is, in practice,
anything the sending host wants to send).
</td></tr>
</table>
</td></tr>
</TD></TR>
</TABLE>
</TD></TR>
</table>
</TABLE>
<hr size="1">
<font size="-1">
<HR size="1">
<FONT size="-1">
Copyright (c) 2000, 2003, 2005 Sendmail, Inc. and its suppliers.
All rights reserved.
<br>
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</font>
</body>
</html>
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1,277 @@
<HTML>
<HEAD><TITLE>xxfi_negotiate</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_negotiate.html,v 1.23 2006/12/20 18:57:08 ca Exp $
-->
<H1>xxfi_negotiate</H1>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
#include &lt;libmilter/mfdef.h&gt;
sfsistat (*xxfi_negotiate)(
SMFICTX *ctx,
unsigned long f0,
unsigned long f1,
unsigned long f2,
unsigned long f3,
unsigned long *pf0,
unsigned long *pf1,
unsigned long *pf2,
unsigned long *pf3);
</PRE>
</TD></TR>
<!----------- Description ---------->
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR>
<TH valign="top" align=left width=80>Called When</TH>
<TD>Once, at the start of each SMTP connection.</TD>
</TR>
<TR>
<TH valign="top" align=left width=80>Default Behavior</TH>
<TD>Return SMFIS_ALL_OPTS to change nothing.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR><TD>ctx</TD>
<TD>the opaque context structure.
</TD></TR>
<TR><TD>f0</TD>
<TD>the actions offered by the MTA.
</TD></TR>
<TR><TD>f1</TD>
<TD>the protocol steps offered by the MTA.
<TR><TD>f2</TD>
<TD>for future extensions.
</TD></TR>
<TR><TD>f3</TD>
<TD>for future extensions.
</TD></TR>
<TR><TD>pf0</TD>
<TD>the actions requested by the milter.
</TD></TR>
<TR><TD>pf1</TD>
<TD>the protocol steps requested by the milter.
<TR><TD>pf2</TD>
<TD>for future extensions.
</TD></TR>
<TR><TD>pf3</TD>
<TD>for future extensions.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
<TH valign="top" align=left>SPECIAL RETURN VALUES</TH>
<TD><TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR valign="top">
<TD>SMFIS_ALL_OPTS</TD>
<TD>
If a milter just wants to inspect the available protocol steps
and actions, then it can return
SMFIS_ALL_OPTS
and the MTA will make all protocol steps and actions available
to the milter.
In this case, no values should be assigned to the output parameters
<CODE>pf0</CODE> - <CODE>pf3</CODE>
as they will be ignored.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_REJECT</TD>
<TD>Milter startup fails and it will not be contacted again
(for the current connection).
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_CONTINUE</TD>
<TD>Continue processing.
In this case the milter <EM>must</EM> set all output parameters
<CODE>pf0</CODE> - <CODE>pf3</CODE>.
See below for an explanation how to set those output parameters.
</TD>
</TR>
</TABLE>
</TR>
<!----------- Notes ---------->
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>This function allows a milter to dynamically determine and
request operations and actions during startup.
In previous versions, the actions (f0) were fixed in the
<A HREF="smfi_register.html#flags">flags</A> field of the
<A HREF="smfi_register.html#smfiDesc">smfiDesc</A>
structure
and the protocol steps (f1) were implicitly derived by checking whether
a callback was defined.
Due to the extensions in the new milter version,
such a static selection will not work if a milter requires
new actions that are not available when talking to an older MTA.
Hence in the negotiation callback a milter can determine
which operations are available and dynamically select
those which it needs and which are offered.
If some operations are not available, the milter may either fall back
to an older mode or abort the session and ask the user to upgrade.
<!--
<P>
The protocol steps are defined in
<CODE>include/libmilter/mfdef.h</CODE>:
the macros start with
<CODE>SMFIP_</CODE>.
-->
<P>
Protocol steps
(<CODE>f1</CODE>, <CODE>*pf1</CODE>):
<UL>
<LI><A NAME="SMFIP_RCPT_REJ"><CODE>SMFIP_RCPT_REJ</CODE></A>:
By setting this bit, a milter can request that the
MTA should also send <CODE>RCPT</CODE> commands that have been rejected
because the user is unknown (or similar reasons), but not those
which have been rejected because of syntax errors etc.
If a milter requests this protocol step,
then it should check the macro
<CODE>{rcpt_mailer}</CODE>:
if that is set to
<CODE>error</CODE>,
then the recipient will be rejected by the MTA.
Usually the macros
<CODE>{rcpt_host}</CODE> and <CODE>{rcpt_addr}</CODE>
will contain an enhanced status code and an error text
in that case, respectively.
<LI><A NAME="SMFIP_SKIP"><CODE>SMFIP_SKIP</CODE></A>
indicates that the MTA understand the
<A HREF="api.html#SMFIS_SKIP">SMFIS_SKIP</A>
return code.
<LI><A NAME="SMFIP_NR_"><CODE>SMFIP_NR_*</CODE></A>
indicates that the MTA understand the
<A HREF="api.html#SMFIS_NOREPLY">SMFIS_NOREPLY</A>
return code.
There are flags for various protocol stages:
<UL>
<LI><A NAME="SMFIP_NR_CONN"><CODE>SMFIP_NR_CONN</CODE></A>:
<A HREF="xxfi_connect.html">xxfi_connect()</A>
<LI><A NAME="SMFIP_NR_HELO"><CODE>SMFIP_NR_HELO</CODE></A>:
<A HREF="xxfi_helo.html">xxfi_helo()</A>
<LI><A NAME="SMFIP_NR_MAIL"><CODE>SMFIP_NR_MAIL</CODE></A>:
<A HREF="xxfi_envfrom.html">xxfi_envfrom()</A>
<LI><A NAME="SMFIP_NR_RCPT"><CODE>SMFIP_NR_RCPT</CODE></A>:
<A HREF="xxfi_envrcpt.html">xxfi_envrcpt()</A>
<LI><A NAME="SMFIP_NR_DATA"><CODE>SMFIP_NR_DATA</CODE></A>:
<A HREF="xxfi_data.html">xxfi_data()</A>
<LI><A NAME="SMFIP_NR_UNKN"><CODE>SMFIP_NR_UNKN</CODE></A>:
<A HREF="xxfi_unknown.html">xxfi_unknown()</A>
<LI><A NAME="SMFIP_NR_EOH"><CODE>SMFIP_NR_EOH</CODE></A>:
<A HREF="xxfi_eoh.html">xxfi_eoh()</A>
<LI><A NAME="SMFIP_NR_BODY"><CODE>SMFIP_NR_BODY</CODE></A>:
<A HREF="xxfi_body.html">xxfi_body()</A>
<LI><A NAME="SMFIP_NR_HDR"><CODE>SMFIP_NR_HDR</CODE></A>:
<A HREF="xxfi_header.html">xxfi_header()</A>
</UL>
<LI><A NAME="SMFIP_HDR_LEADSPC"><CODE>SMFIP_HDR_LEADSPC</CODE></A>
indicates that the MTA can send header values with leading space intact.
If this protocol step is requested, then the MTA will also not add a leading
space to headers when they are added, inserted, or changed.
<!--
:'a,.s;^#define \(SMFIP_NO[A-Z]*\)[ ].*;<LI><A NAME="\1"><CODE>\1</CODE></A>:;
-->
<LI>The MTA can be instructed not to send information about
various SMTP stages, these flags start with:
<A NAME="SMFIP_NO"><CODE>SMFIP_NO*</CODE></A>.
<UL>
<LI><A NAME="SMFIP_NOCONNECT"><CODE>SMFIP_NOCONNECT</CODE></A>:
<A HREF="xxfi_connect.html">xxfi_connect()</A>
<LI><A NAME="SMFIP_NOHELO"><CODE>SMFIP_NOHELO</CODE></A>:
<A HREF="xxfi_header.html">xxfi_header()</A>
<LI><A NAME="SMFIP_NOMAIL"><CODE>SMFIP_NOMAIL</CODE></A>:
<A HREF="xxfi_envfrom.html">xxfi_envfrom()</A>
<LI><A NAME="SMFIP_NORCPT"><CODE>SMFIP_NORCPT</CODE></A>:
<A HREF="xxfi_envrcpt.html">xxfi_envrcpt()</A>
<LI><A NAME="SMFIP_NOBODY"><CODE>SMFIP_NOBODY</CODE></A>:
<A HREF="xxfi_body.html">xxfi_body()</A>
<LI><A NAME="SMFIP_NOHDRS"><CODE>SMFIP_NOHDRS</CODE></A>:
<A HREF="xxfi_header.html">xxfi_header()</A>
<LI><A NAME="SMFIP_NOEOH"><CODE>SMFIP_NOEOH</CODE></A>:
<A HREF="xxfi_eoh.html">xxfi_eoh()</A>
<LI><A NAME="SMFIP_NOUNKNOWN"><CODE>SMFIP_NOUNKNOWN</CODE></A>:
<A HREF="xxfi_unknown.html">xxfi_unknown()</A>
<LI><A NAME="SMFIP_NODATA"><CODE>SMFIP_NODATA</CODE></A>:
<A HREF="xxfi_data.html">xxfi_data()</A>
</UL>
For each of these xxfi_* callbacks that a milter does not use
the corresponding flag <EM>should</EM> be set in
<CODE>*pf1</CODE>.
</UL>
<P>
The available actions
(<CODE>f0</CODE>, <CODE>*pf0</CODE>)
are
<!--
defined in
<CODE>include/libmilter/mfapi.h</CODE>:
the macros start with
<CODE>SMFIF_</CODE>;
these are
-->
described
<A HREF="smfi_register.html#flags">elsewhere (xxfi_flags)</A>.
<P>
If a milter returns SMFIS_CONTINUE, then it <EM>must</EM>
set the desired actions and protocol steps
via the (output) parameters
<CODE>pf0</CODE>
and
<CODE>pf1</CODE>
(which correspond to
<CODE>f0</CODE>
and
<CODE>f1</CODE>, respectively).
The (output) parameters
<CODE>pf2</CODE> and
<CODE>pf3</CODE>
should be set to 0 for compatibility with future versions.
</TD>
</TR>
</TABLE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</FONT>
</BODY>
</HTML>

View File

@ -0,0 +1,84 @@
<HTML>
<HEAD><TITLE>xxfi_unknown</TITLE></HEAD>
<BODY>
<!--
$Id: xxfi_unknown.html,v 1.3 2006/12/21 18:30:36 ca Exp $
-->
<H1>xxfi_unknown</H1>
<TABLE border="0" cellspacing=4 cellpadding=4>
<!---------- Synopsis ----------->
<TR><TH valign="top" align=left width=100>SYNOPSIS</TH><TD>
<PRE>
#include &lt;libmilter/mfapi.h&gt;
sfsistat (*xxfi_unknown)(
SMFICTX *ctx,
const char *arg
);
</PRE>
Handle unknown and unimplemented SMTP commands.
</TD></TR>
<!----------- Description ---------->
<TR><TH valign="top" align=left>DESCRIPTION</TH><TD>
<TABLE border="1" cellspacing=1 cellpadding=4>
<TR align="left" valign=top>
<TH width="80">Called When</TH>
<TD>xxfi_unknown is called when the client uses an SMTP command
that is either unknown or not implemented by the MTA.
</TR>
<TR align="left" valign=top>
<TH>Default Behavior</TH>
<TD>Do nothing; return SMFIS_CONTINUE.</TD>
</TR>
</TABLE>
<!----------- Arguments ---------->
<TR><TH valign="top" align=left>ARGUMENTS</TH><TD>
<TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Argument</TH><TH>Description</TH></TR>
<TR valign="top"><TD>ctx</TD>
<TD>Opaque context structure.
</TD></TR>
<TR valign="top"><TD>arg</TD>
<TD>SMTP command including all arguments.
</TD></TR>
</TABLE>
</TD></TR>
<!----------- Return values ---------->
<TR>
<TH valign="top" align=left>SPECIAL RETURN VALUES</TH>
<TD><TABLE border="1" cellspacing=0>
<TR bgcolor="#dddddd"><TH>Return value</TH><TH>Description</TH></TR>
<TR valign="top">
<TD>SMFIS_TEMPFAIL</TD>
<TD>Reject this message with a temporary error.
</TD>
</TR>
<TR valign="top">
<TD>SMFIS_REJECT</TD>
<TD>Reject this message.
</TD>
</TR>
</TABLE>
</TR>
<!----------- Notes ---------->
<TR>
<TH valign="top" align=left>NOTES</TH>
<TD>The SMTP command will always be rejected by the server,
it is only possible to return a different error code.
</TR>
</TABLE>
<HR size="1">
<FONT size="-1">
Copyright (c) 2006 Sendmail, Inc. and its suppliers.
All rights reserved.
<BR>
By using this file, you agree to the terms and conditions set
forth in the LICENSE.
</FONT>
</BODY>
</HTML>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,298 @@
/*
* Copyright (c) 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: example.c,v 8.3 2006/12/20 21:22:34 ca Exp $
*/
/*
** A trivial example filter that logs all email to a file.
** This milter also has some callbacks which it does not really use,
** but they are defined to serve as an example.
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include "libmilter/mfapi.h"
#include "libmilter/mfdef.h"
#ifndef true
# define false 0
# define true 1
#endif /* ! true */
struct mlfiPriv
{
char *mlfi_fname;
FILE *mlfi_fp;
};
#define MLFIPRIV ((struct mlfiPriv *) smfi_getpriv(ctx))
static unsigned long mta_caps = 0;
sfsistat
mlfi_cleanup(ctx, ok)
SMFICTX *ctx;
bool ok;
{
sfsistat rstat = SMFIS_CONTINUE;
struct mlfiPriv *priv = MLFIPRIV;
char *p;
char host[512];
char hbuf[1024];
if (priv == NULL)
return rstat;
/* close the archive file */
if (priv->mlfi_fp != NULL && fclose(priv->mlfi_fp) == EOF)
{
/* failed; we have to wait until later */
rstat = SMFIS_TEMPFAIL;
(void) unlink(priv->mlfi_fname);
}
else if (ok)
{
/* add a header to the message announcing our presence */
if (gethostname(host, sizeof host) < 0)
snprintf(host, sizeof host, "localhost");
p = strrchr(priv->mlfi_fname, '/');
if (p == NULL)
p = priv->mlfi_fname;
else
p++;
snprintf(hbuf, sizeof hbuf, "%s@%s", p, host);
smfi_addheader(ctx, "X-Archived", hbuf);
}
else
{
/* message was aborted -- delete the archive file */
(void) unlink(priv->mlfi_fname);
}
/* release private memory */
free(priv->mlfi_fname);
free(priv);
smfi_setpriv(ctx, NULL);
/* return status */
return rstat;
}
sfsistat
mlfi_envfrom(ctx, envfrom)
SMFICTX *ctx;
char **envfrom;
{
struct mlfiPriv *priv;
int fd = -1;
/* allocate some private memory */
priv = malloc(sizeof *priv);
if (priv == NULL)
{
/* can't accept this message right now */
return SMFIS_TEMPFAIL;
}
memset(priv, '\0', sizeof *priv);
/* open a file to store this message */
priv->mlfi_fname = strdup("/tmp/msg.XXXXXXXX");
if (priv->mlfi_fname == NULL)
{
free(priv);
return SMFIS_TEMPFAIL;
}
if ((fd = mkstemp(priv->mlfi_fname)) < 0 ||
(priv->mlfi_fp = fdopen(fd, "w+")) == NULL)
{
if (fd >= 0)
(void) close(fd);
free(priv->mlfi_fname);
free(priv);
return SMFIS_TEMPFAIL;
}
/* save the private data */
smfi_setpriv(ctx, priv);
/* continue processing */
return SMFIS_CONTINUE;
}
sfsistat
mlfi_header(ctx, headerf, headerv)
SMFICTX *ctx;
char *headerf;
char *headerv;
{
/* write the header to the log file */
fprintf(MLFIPRIV->mlfi_fp, "%s: %s\r\n", headerf, headerv);
/* continue processing */
return ((mta_caps & SMFIP_NR_HDR) != 0)
? SMFIS_NOREPLY : SMFIS_CONTINUE;
}
sfsistat
mlfi_eoh(ctx)
SMFICTX *ctx;
{
/* output the blank line between the header and the body */
fprintf(MLFIPRIV->mlfi_fp, "\r\n");
/* continue processing */
return SMFIS_CONTINUE;
}
sfsistat
mlfi_body(ctx, bodyp, bodylen)
SMFICTX *ctx;
u_char *bodyp;
size_t bodylen;
{
/* output body block to log file */
if (fwrite(bodyp, bodylen, 1, MLFIPRIV->mlfi_fp) <= 0)
{
/* write failed */
(void) mlfi_cleanup(ctx, false);
return SMFIS_TEMPFAIL;
}
/* continue processing */
return SMFIS_CONTINUE;
}
sfsistat
mlfi_eom(ctx)
SMFICTX *ctx;
{
return mlfi_cleanup(ctx, true);
}
sfsistat
mlfi_close(ctx)
SMFICTX *ctx;
{
return SMFIS_ACCEPT;
}
sfsistat
mlfi_abort(ctx)
SMFICTX *ctx;
{
return mlfi_cleanup(ctx, false);
}
sfsistat
mlfi_unknown(ctx, cmd)
SMFICTX *ctx;
char *cmd;
{
return SMFIS_CONTINUE;
}
sfsistat
mlfi_data(ctx)
SMFICTX *ctx;
{
return SMFIS_CONTINUE;
}
sfsistat
mlfi_negotiate(ctx, f0, f1, f2, f3, pf0, pf1, pf2, pf3)
SMFICTX *ctx;
unsigned long f0;
unsigned long f1;
unsigned long f2;
unsigned long f3;
unsigned long *pf0;
unsigned long *pf1;
unsigned long *pf2;
unsigned long *pf3;
{
/* milter actions: add headers */
*pf0 = SMFIF_ADDHDRS;
/* milter protocol steps: all but connect, HELO, RCPT */
*pf1 = SMFIP_NOCONNECT|SMFIP_NOHELO|SMFIP_NORCPT;
mta_caps = f1;
if ((mta_caps & SMFIP_NR_HDR) != 0)
*pf1 |= SMFIP_NR_HDR;
*pf2 = 0;
*pf3 = 0;
return SMFIS_CONTINUE;
}
struct smfiDesc smfilter =
{
"SampleFilter", /* filter name */
SMFI_VERSION, /* version code -- do not change */
SMFIF_ADDHDRS, /* flags */
NULL, /* connection info filter */
NULL, /* SMTP HELO command filter */
mlfi_envfrom, /* envelope sender filter */
NULL, /* envelope recipient filter */
mlfi_header, /* header filter */
mlfi_eoh, /* end of header */
mlfi_body, /* body block filter */
mlfi_eom, /* end of message */
mlfi_abort, /* message aborted */
mlfi_close, /* connection cleanup */
mlfi_unknown, /* unknown/unimplemented SMTP commands */
mlfi_data, /* DATA command filter */
mlfi_negotiate /* option negotation at connection startup */
};
int
main(argc, argv)
int argc;
char *argv[];
{
bool setconn;
int c;
setconn = false;
/* Process command line options */
while ((c = getopt(argc, argv, "p:")) != -1)
{
switch (c)
{
case 'p':
if (optarg == NULL || *optarg == '\0')
{
(void) fprintf(stderr, "Illegal conn: %s\n",
optarg);
exit(EX_USAGE);
}
(void) smfi_setconn(optarg);
setconn = true;
break;
}
}
if (!setconn)
{
fprintf(stderr, "%s: Missing required -p argument\n", argv[0]);
exit(EX_USAGE);
}
if (smfi_register(smfilter) == MI_FAILURE)
{
fprintf(stderr, "smfi_register failed\n");
exit(EX_UNAVAILABLE);
}
return smfi_main();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers.
* Copyright (c) 1999-2003, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -9,11 +9,11 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: handler.c,v 8.36 2003/09/08 21:27:14 yuri Exp $")
SM_RCSID("@(#)$Id: handler.c,v 8.38 2006/11/02 02:38:22 ca Exp $")
#include "libmilter.h"
#if !_FFR_WORKERS_POOL
/*
** HANDLE_SESSION -- Handle a connected session in its own context
**
@ -64,3 +64,4 @@ mi_handle_session(ctx)
ctx = NULL;
return ret;
}
#endif /* !_FFR_WORKERS_POOL */

View File

@ -19,19 +19,108 @@
#ifdef _DEFINE
# define EXTERN
# define INIT(x) = x
SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.51 2006/01/04 02:24:37 ca Exp $")
SM_IDSTR(MilterlId, "@(#)$Id: libmilter.h,v 8.74 2006/12/19 18:19:52 ca Exp $")
#else /* _DEFINE */
# define EXTERN extern
# define INIT(x)
#endif /* _DEFINE */
#include "sm/tailq.h"
#define NOT_SENDMAIL 1
#define _SOCK_ADDR union bigsockaddr
#include "sendmail.h"
#ifdef SM_ASSERT
#undef SM_ASSERT
#endif
#ifndef SM_ASSERT
#include <assert.h>
#define SM_ASSERT(x) assert(x)
#endif
#include "libmilter/milter.h"
#define MAX_MACROS_ENTRIES 7 /* max size of macro pointer array */
typedef SM_TAILQ_HEAD(, smfi_str) smfi_hd_T;
typedef struct smfi_str smfi_str_S;
/*
** Context for one milter session.
**
** Notes:
** There is a 1-1 correlation between a sendmail SMTP server process,
** an SMTP session, and an milter context. Due to the nature of SMTP
** session handling in sendmail 8, this libmilter implementation deals
** only with a single SMTP session per MTA - libmilter connection.
**
** There is no "global" context for libmilter, global variables are
** just that (they are not "collected" in a context).
**
** Implementation hint:
** macros are stored in mac_buf[] as sequence of:
** macro_name \0 macro_value
** (just as read from the MTA)
** mac_ptr is a list of pointers into mac_buf to the beginning of each
** entry, i.e., macro_name, macro_value, ...
*/
struct smfi_str
{
sthread_t ctx_id; /* thread id */
socket_t ctx_sd; /* socket descriptor */
int ctx_dbg; /* debug level */
time_t ctx_timeout; /* timeout */
int ctx_state; /* state */
smfiDesc_ptr ctx_smfi; /* filter description */
int ctx_prot_vers; /* libmilter protocol version */
unsigned long ctx_aflags; /* milter action flags */
unsigned long ctx_pflags; /* milter protocol flags */
/*
** milter protocol flags that are sent to the MTA;
** this is the same as ctx_pflags except for those flags that
** are not offered by the MTA but emulated in libmilter.
*/
unsigned long ctx_pflags2mta;
/*
** milter protocol version that is sent to the MTA;
** this is the same as ctx_prot_vers unless the
** MTA protocol version (ctx_mta_prot_vers) is smaller
** but still "acceptable".
*/
int ctx_prot_vers2mta;
char **ctx_mac_ptr[MAX_MACROS_ENTRIES];
char *ctx_mac_buf[MAX_MACROS_ENTRIES];
char *ctx_mac_list[MAX_MACROS_ENTRIES];
char *ctx_reply; /* reply code */
void *ctx_privdata; /* private data */
int ctx_mta_prot_vers; /* MTA protocol version */
unsigned long ctx_mta_pflags; /* MTA protocol flags */
unsigned long ctx_mta_aflags; /* MTA action flags */
#if _FFR_THREAD_MONITOR
time_t ctx_start; /* start time of thread */
SM_TAILQ_ENTRY(smfi_str) ctx_mon_link;
#endif /* _FFR_THREAD_MONITOR */
#if _FFR_WORKERS_POOL
long ctx_sid; /* session identifier */
int ctx_wstate; /* state of the session (worker pool) */
int ctx_wait; /* elapsed time waiting for sm cmd */
SM_TAILQ_ENTRY(smfi_str) ctx_link;
#endif /* _FFR_WORKERS_POOL */
};
# define ValidSocket(sd) ((sd) >= 0)
# define INVALID_SOCKET (-1)
# define closesocket close
@ -49,6 +138,34 @@ typedef pthread_mutex_t smutex_t;
# define smutex_unlock(mp) (pthread_mutex_unlock(mp) == 0)
# define smutex_trylock(mp) (pthread_mutex_trylock(mp) == 0)
#if _FFR_WORKERS_POOL
/* SM_CONF_POLL shall be defined with _FFR_WORKERS_POOL */
# if !SM_CONF_POLL
# define SM_CONF_POLL 1
# endif /* SM_CONF_POLL */
#endif /* _FFR_WORKERS_POOL */
typedef pthread_cond_t scond_t;
#define scond_init(cp) pthread_cond_init(cp, NULL)
#define scond_destroy(cp) pthread_cond_destroy(cp)
#define scond_wait(cp, mp) pthread_cond_wait(cp, mp)
#define scond_signal(cp) pthread_cond_signal(cp)
#define scond_broadcast(cp) pthread_cond_broadcast(cp)
#define scond_timedwait(cp, mp, to) \
do \
{ \
struct timespec timeout; \
struct timeval now; \
gettimeofday(&now, NULL); \
timeout.tv_sec = now.tv_sec + to; \
timeout.tv_nsec = now.tv_usec / 1000; \
r = pthread_cond_timedwait(cp,mp,&timeout); \
if (r != 0 && r != ETIMEDOUT) \
smi_log(SMI_LOG_ERR, \
"pthread_cond_timedwait error %d", r); \
} while (0)
#if SM_CONF_POLL
# include <poll.h>
@ -117,10 +234,6 @@ typedef pthread_mutex_t smutex_t;
#include <sys/time.h>
/* version info */
#define MILTER_PRODUCT_NAME "libmilter"
#define MILTER_VERSION 100
/* some defaults */
#define MI_TIMEOUT 7210 /* default timeout for read/write */
#define MI_CHK_TIME 5 /* checking whether to terminate */
@ -184,4 +297,38 @@ extern int mi_wr_cmd __P((socket_t, struct timeval *, int, char *, size_t));
extern bool mi_sendok __P((SMFICTX_PTR, int));
#if _FFR_THREAD_MONITOR
extern bool Monitor;
#define MI_MONITOR_INIT() mi_monitor_init()
#define MI_MONITOR_BEGIN(ctx, cmd) \
do \
{ \
if (Monitor) \
mi_monitor_work_begin(ctx, cmd);\
} while (0)
#define MI_MONITOR_END(ctx, cmd) \
do \
{ \
if (Monitor) \
mi_monitor_work_end(ctx, cmd); \
} while (0)
int mi_monitor_init __P((void));
int mi_monitor_work_begin __P((SMFICTX_PTR, int));
int mi_monitor_work_end __P((SMFICTX_PTR, int));
#else /* _FFR_THREAD_MONITOR */
#define MI_MONITOR_INIT() MI_SUCCESS
#define MI_MONITOR_BEGIN(ctx, cmd)
#define MI_MONITOR_END(ctx, cmd)
#endif /* _FFR_THREAD_MONITOR */
#if _FFR_WORKERS_POOL
extern int mi_pool_manager_init __P((void));
extern int mi_pool_controller_init __P((void));
extern int mi_start_session __P((SMFICTX_PTR));
#endif /* _FFR_WORKERS_POOL */
#endif /* ! _LIBMILTER_H */

View File

@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: listener.c,v 8.115 2006/01/24 00:48:39 ca Exp $")
SM_RCSID("@(#)$Id: listener.c,v 8.122 2006/11/02 17:54:44 ca Exp $")
/*
** listener.c -- threaded network listener
@ -25,6 +25,10 @@ SM_RCSID("@(#)$Id: listener.c,v 8.115 2006/01/24 00:48:39 ca Exp $")
# if NETINET || NETINET6
# include <arpa/inet.h>
# endif /* NETINET || NETINET6 */
# if SM_CONF_POLL
# undef SM_FD_OK_SELECT
# define SM_FD_OK_SELECT(fd) true
# endif /* SM_CONF_POLL */
static smutex_t L_Mutex;
static int L_family;
@ -32,7 +36,9 @@ static SOCKADDR_LEN_T L_socksize;
static socket_t listenfd = INVALID_SOCKET;
static socket_t mi_milteropen __P((char *, int, bool, char *));
#if !_FFR_WORKERS_POOL
static void *mi_thread_handle_wrapper __P((void *));
#endif /* !_FFR_WORKERS_POOL */
/*
** MI_OPENSOCKET -- create the socket where this filter and the MTA will meet
@ -80,7 +86,6 @@ mi_opensocket(conn, backlog, dbg, rmsocket, smfi)
(void) smutex_unlock(&L_Mutex);
return MI_FAILURE;
}
#if !SM_CONF_POLL
if (!SM_FD_OK_SELECT(listenfd))
{
smi_log(SMI_LOG_ERR, "%s: fd %d is larger than FD_SETSIZE %d",
@ -88,7 +93,6 @@ mi_opensocket(conn, backlog, dbg, rmsocket, smfi)
(void) smutex_unlock(&L_Mutex);
return MI_FAILURE;
}
#endif /* !SM_CONF_POLL */
(void) smutex_unlock(&L_Mutex);
return MI_SUCCESS;
}
@ -549,6 +553,8 @@ mi_milteropen(conn, backlog, rmsocket, name)
L_family = addr.sa.sa_family;
return sock;
}
#if !_FFR_WORKERS_POOL
/*
** MI_THREAD_HANDLE_WRAPPER -- small wrapper to handle session
**
@ -563,8 +569,16 @@ static void *
mi_thread_handle_wrapper(arg)
void *arg;
{
/*
** Note: on some systems this generates a compiler warning:
** cast to pointer from integer of different size
** You can safely ignore this warning as the result of this function
** is not used anywhere.
*/
return (void *) mi_handle_session(arg);
}
#endif /* _FFR_WORKERS_POOL */
/*
** MI_CLOSENER -- close listen socket
@ -714,7 +728,9 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
int acnt = 0; /* error count for accept() failures */
int scnt = 0; /* error count for select() failures */
int save_errno = 0;
#if !_FFR_WORKERS_POOL
sthread_t thread_id;
#endif /* !_FFR_WORKERS_POOL */
_SOCK_ADDR cliaddr;
SOCKADDR_LEN_T clilen;
SMFICTX_PTR ctx;
@ -724,6 +740,11 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
if (mi_opensocket(conn, backlog, dbg, false, smfi) == MI_FAILURE)
return MI_FAILURE;
#if _FFR_WORKERS_POOL
if (mi_pool_controller_init() == MI_FAILURE)
return MI_FAILURE;
#endif /* _FFR_WORKERS_POOL */
clilen = L_socksize;
while ((mistop = mi_stop()) == MILTER_CONT)
{
@ -786,9 +807,8 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
(void) smutex_unlock(&L_Mutex);
/*
** If remote side closes before
** accept() finishes, sockaddr
** might not be fully filled in.
** If remote side closes before accept() finishes,
** sockaddr might not be fully filled in.
*/
if (ValidSocket(connfd) &&
@ -803,7 +823,6 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
save_errno = EINVAL;
}
#if !SM_CONF_POLL
/* check if acceptable for select() */
if (ValidSocket(connfd) && !SM_FD_OK_SELECT(connfd))
{
@ -811,7 +830,6 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
connfd = INVALID_SOCKET;
save_errno = ERANGE;
}
#endif /* !SM_CONF_POLL */
if (!ValidSocket(connfd))
{
@ -858,11 +876,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
acnt = 0; /* reset error counter for accept() */
#if _FFR_DUP_FD
dupfd = fcntl(connfd, F_DUPFD, 256);
if (ValidSocket(dupfd)
# if !SM_CONF_POLL
&& SM_FD_OK_SELECT(dupfd)
# endif /* !SM_CONF_POLL */
)
if (ValidSocket(dupfd) && SM_FD_OK_SELECT(dupfd))
{
close(connfd);
connfd = dupfd;
@ -899,12 +913,6 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
ctx->ctx_dbg = dbg;
ctx->ctx_timeout = timeout;
ctx->ctx_smfi = smfi;
#if 0
if (smfi->xxfi_eoh == NULL)
if (smfi->xxfi_eom == NULL)
if (smfi->xxfi_abort == NULL)
if (smfi->xxfi_close == NULL)
#endif /* 0 */
if (smfi->xxfi_connect == NULL)
ctx->ctx_pflags |= SMFIP_NOCONNECT;
if (smfi->xxfi_helo == NULL)
@ -919,14 +927,24 @@ mi_listener(conn, dbg, smfi, timeout, backlog)
ctx->ctx_pflags |= SMFIP_NOEOH;
if (smfi->xxfi_body == NULL)
ctx->ctx_pflags |= SMFIP_NOBODY;
if (smfi->xxfi_data == NULL)
ctx->ctx_pflags |= SMFIP_NODATA;
if (smfi->xxfi_unknown == NULL)
ctx->ctx_pflags |= SMFIP_NOUNKNOWN;
#if _FFR_WORKERS_POOL
# define LOG_CRT_FAIL "%s: mi_start_session() failed: %d, %s"
if ((r = mi_start_session(ctx)) != MI_SUCCESS)
#else /* _FFR_WORKERS_POOL */
# define LOG_CRT_FAIL "%s: thread_create() failed: %d, %s"
if ((r = thread_create(&thread_id,
mi_thread_handle_wrapper,
(void *) ctx)) != 0)
#endif /* _FFR_WORKERS_POOL */
{
tcnt++;
smi_log(SMI_LOG_ERR,
"%s: thread_create() failed: %d, %s",
LOG_CRT_FAIL,
smfi->xxfi_name, r,
tcnt >= MAX_FAILS_T ? "abort" : "try again");
MI_SLEEP(tcnt);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers.
* Copyright (c) 1999-2003, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: main.c,v 8.79 2003/10/20 22:25:09 ca Exp $")
SM_RCSID("@(#)$Id: main.c,v 8.81 2006/11/02 18:31:43 ca Exp $")
#define _DEFINE 1
#include "libmilter.h"
@ -232,7 +232,7 @@ smfi_main()
smfi->xxfi_name);
return MI_FAILURE;
}
r = MI_SUCCESS;
r = MI_MONITOR_INIT();
/* Startup the listener */
if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS)

View File

@ -0,0 +1,225 @@
/*
* Copyright (c) 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
*/
#include "libmilter.h"
#if _FFR_THREAD_MONITOR
/*
** Thread Monitoring
** Todo: more error checking (return code from function calls)
** add comments.
*/
bool Monitor = false; /* use monitoring? */
static unsigned int Mon_exec_time = 0;
/* mutex protects Mon_cur_ctx, Mon_ctx_head, and ctx_start */
static smutex_t Mon_mutex;
static scond_t Mon_cv;
/*
** Current ctx to monitor.
** Invariant:
** Mon_cur_ctx == NULL || Mon_cur_ctx is thread which was started the longest
** time ago.
**
** Basically the entries in the list are ordered by time because new
** entries are appended at the end. However, due to the concurrent
** execution (multi-threaded) and no guaranteed order of wakeups
** after a mutex_lock() attempt, the order might not be strict,
** i.e., if the list contains e1 and e2 (in that order) then
** the the start time of e2 can be (slightly) smaller than that of e1.
** However, this slight inaccurracy should not matter for the proper
** working of this algorithm.
*/
static SMFICTX_PTR Mon_cur_ctx = NULL;
static smfi_hd_T Mon_ctx_head; /* head of the linked list of active contexts */
/*
** SMFI_SET_MAX_EXEC_TIME -- set maximum execution time for a thread
**
** Parameters:
** tm -- maximum execution time for a thread
**
** Returns:
** MI_SUCCESS
*/
int
smfi_set_max_exec_time(tm)
unsigned int tm;
{
Mon_exec_time = tm;
return MI_SUCCESS;
}
/*
** MI_MONITOR_THREAD -- monitoring thread
**
** Parameters:
** arg -- ignored (required by pthread_create())
**
** Returns:
** NULL on termination.
*/
static void *
mi_monitor_thread(arg)
void *arg;
{
sthread_t tid;
int r;
time_t now, end;
SM_ASSERT(Monitor);
SM_ASSERT(Mon_exec_time > 0);
tid = (sthread_t) sthread_get_id();
if (pthread_detach(tid) != 0)
{
/* log an error */
return (void *)1;
}
/*
** NOTE: this is "flow through" code,
** do NOT use do { } while ("break" is used here!)
*/
#define MON_CHK_STOP \
now = time(NULL); \
end = Mon_cur_ctx->ctx_start + Mon_exec_time; \
if (now > end) \
{ \
smi_log(SMI_LOG_ERR, \
"WARNING: monitor timeout triggered, now=%ld, end=%ld, tid=%ld, state=0x%x",\
(long) now, (long) end, \
(long) Mon_cur_ctx->ctx_id, Mon_cur_ctx->ctx_state);\
mi_stop_milters(MILTER_STOP); \
break; \
}
(void) smutex_lock(&Mon_mutex);
while (mi_stop() == MILTER_CONT)
{
if (Mon_cur_ctx != NULL && Mon_cur_ctx->ctx_start > 0)
{
struct timespec abstime;
MON_CHK_STOP;
abstime.tv_sec = end;
abstime.tv_nsec = 0;
r = pthread_cond_timedwait(&Mon_cv, &Mon_mutex,
&abstime);
}
else
r = pthread_cond_wait(&Mon_cv, &Mon_mutex);
if (mi_stop() != MILTER_CONT)
break;
if (Mon_cur_ctx != NULL && Mon_cur_ctx->ctx_start > 0)
{
MON_CHK_STOP;
}
}
(void) smutex_unlock(&Mon_mutex);
return NULL;
}
/*
** MI_MONITOR_INIT -- initialize monitoring thread
**
** Parameters: none
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
int
mi_monitor_init()
{
int r;
sthread_t tid;
SM_ASSERT(!Monitor);
if (Mon_exec_time <= 0)
return MI_SUCCESS;
Monitor = true;
if (!smutex_init(&Mon_mutex))
return MI_FAILURE;
if (scond_init(&Mon_cv) != 0)
return MI_FAILURE;
SM_TAILQ_INIT(&Mon_ctx_head);
r = thread_create(&tid, mi_monitor_thread, (void *)NULL);
if (r != 0)
return r;
return MI_SUCCESS;
}
/*
** MI_MONITOR_WORK_BEGIN -- record start of thread execution
**
** Parameters:
** ctx -- session context
** cmd -- milter command char
**
** Returns:
** 0
*/
int
mi_monitor_work_begin(ctx, cmd)
SMFICTX_PTR ctx;
int cmd;
{
(void) smutex_lock(&Mon_mutex);
if (NULL == Mon_cur_ctx)
{
Mon_cur_ctx = ctx;
(void) scond_signal(&Mon_cv);
}
ctx->ctx_start = time(NULL);
SM_TAILQ_INSERT_TAIL(&Mon_ctx_head, ctx, ctx_mon_link);
(void) smutex_unlock(&Mon_mutex);
return 0;
}
/*
** MI_MONITOR_WORK_END -- record end of thread execution
**
** Parameters:
** ctx -- session context
** cmd -- milter command char
**
** Returns:
** 0
*/
int
mi_monitor_work_end(ctx, cmd)
SMFICTX_PTR ctx;
int cmd;
{
(void) smutex_lock(&Mon_mutex);
ctx->ctx_start = 0;
SM_TAILQ_REMOVE(&Mon_ctx_head, ctx, ctx_mon_link);
if (Mon_cur_ctx == ctx)
{
if (SM_TAILQ_EMPTY(&Mon_ctx_head))
Mon_cur_ctx = NULL;
else
Mon_cur_ctx = SM_TAILQ_FIRST(&Mon_ctx_head);
}
(void) smutex_unlock(&Mon_mutex);
return 0;
}
#endif /* _FFR_THREAD_MONITOR */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999-2005 Sendmail, Inc. and its suppliers.
* Copyright (c) 1999-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: smfi.c,v 8.74 2005/03/30 00:44:07 ca Exp $")
SM_RCSID("@(#)$Id: smfi.c,v 8.82 2007/01/20 06:37:19 ca Exp $")
#include <sm/varargs.h>
#include "libmilter.h"
@ -30,7 +30,6 @@ static int myisenhsc __P((const char *, int));
** headerf -- Header field name
** headerv -- Header field value
**
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
@ -153,6 +152,221 @@ smfi_chgheader(ctx, headerf, hdridx, headerv)
return smfi_header(ctx, SMFIR_CHGHEADER, hdridx, headerf, headerv);
}
#if 0
/*
** BUF_CRT_SEND -- construct buffer to send from arguments
**
** Parameters:
** ctx -- Opaque context structure
** cmd -- command
** arg0 -- first argument
** argv -- list of arguments (NULL terminated)
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
static int
buf_crt_send __P((SMFICTX *, int cmd, char *, char **));
static int
buf_crt_send(ctx, cmd, arg0, argv)
SMFICTX *ctx;
int cmd;
char *arg0;
char **argv;
{
size_t len, l0, l1, offset;
int r;
char *buf, *arg, **argvl;
struct timeval timeout;
if (arg0 == NULL || *arg0 == '\0')
return MI_FAILURE;
timeout.tv_sec = ctx->ctx_timeout;
timeout.tv_usec = 0;
l0 = strlen(arg0) + 1;
len = l0;
argvl = argv;
while (argvl != NULL && (arg = *argv) != NULL && *arg != '\0')
{
l1 = strlen(arg) + 1;
len += l1;
SM_ASSERT(len > l1);
}
buf = malloc(len);
if (buf == NULL)
return MI_FAILURE;
(void) memcpy(buf, arg0, l0);
offset = l0;
argvl = argv;
while (argvl != NULL && (arg = *argv) != NULL && *arg != '\0')
{
l1 = strlen(arg) + 1;
SM_ASSERT(offset < len);
SM_ASSERT(offset + l1 <= len);
(void) memcpy(buf + offset, arg, l1);
offset += l1;
SM_ASSERT(offset > l1);
}
r = mi_wr_cmd(ctx->ctx_sd, &timeout, cmd, buf, len);
free(buf);
return r;
}
#endif /* 0 */
/*
** SEND2 -- construct buffer to send from arguments
**
** Parameters:
** ctx -- Opaque context structure
** cmd -- command
** arg0 -- first argument
** argv -- list of arguments (NULL terminated)
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
static int
send2 __P((SMFICTX *, int cmd, char *, char *));
static int
send2(ctx, cmd, arg0, arg1)
SMFICTX *ctx;
int cmd;
char *arg0;
char *arg1;
{
size_t len, l0, l1, offset;
int r;
char *buf;
struct timeval timeout;
if (arg0 == NULL || *arg0 == '\0')
return MI_FAILURE;
timeout.tv_sec = ctx->ctx_timeout;
timeout.tv_usec = 0;
l0 = strlen(arg0) + 1;
len = l0;
if (arg1 != NULL)
{
l1 = strlen(arg1) + 1;
len += l1;
SM_ASSERT(len > l1);
}
buf = malloc(len);
if (buf == NULL)
return MI_FAILURE;
(void) memcpy(buf, arg0, l0);
offset = l0;
if (arg1 != NULL)
{
l1 = strlen(arg1) + 1;
SM_ASSERT(offset < len);
SM_ASSERT(offset + l1 <= len);
(void) memcpy(buf + offset, arg1, l1);
offset += l1;
SM_ASSERT(offset > l1);
}
r = mi_wr_cmd(ctx->ctx_sd, &timeout, cmd, buf, len);
free(buf);
return r;
}
/*
** SMFI_CHGFROM -- change enveloper sender ("from") address
**
** Parameters:
** ctx -- Opaque context structure
** from -- new envelope sender address ("MAIL From")
** args -- ESMTP arguments
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
int
smfi_chgfrom(ctx, from, args)
SMFICTX *ctx;
char *from;
char *args;
{
if (from == NULL || *from == '\0')
return MI_FAILURE;
if (!mi_sendok(ctx, SMFIF_CHGFROM))
return MI_FAILURE;
return send2(ctx, SMFIR_CHGFROM, from, args);
}
/*
** SMFI_SETSYMLIST -- set list of macros that the MTA should send.
**
** Parameters:
** ctx -- Opaque context structure
** where -- SMTP stage
** macros -- list of macros
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
int
smfi_setsymlist(ctx, where, macros)
SMFICTX *ctx;
int where;
char *macros;
{
SM_ASSERT(ctx != NULL);
if (macros == NULL || *macros == '\0')
return MI_FAILURE;
if (where < SMFIM_FIRST || where > SMFIM_LAST)
return MI_FAILURE;
if (where < 0 || where >= MAX_MACROS_ENTRIES)
return MI_FAILURE;
if (ctx->ctx_mac_list[where] != NULL)
return MI_FAILURE;
ctx->ctx_mac_list[where] = strdup(macros);
if (ctx->ctx_mac_list[where] == NULL)
return MI_FAILURE;
return MI_SUCCESS;
}
/*
** SMFI_ADDRCPT_PAR -- send an additional recipient to the MTA
**
** Parameters:
** ctx -- Opaque context structure
** rcpt -- recipient address
** args -- ESMTP arguments
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
int
smfi_addrcpt_par(ctx, rcpt, args)
SMFICTX *ctx;
char *rcpt;
char *args;
{
if (rcpt == NULL || *rcpt == '\0')
return MI_FAILURE;
if (!mi_sendok(ctx, SMFIF_ADDRCPT_PAR))
return MI_FAILURE;
return send2(ctx, SMFIR_ADDRCPT_PAR, rcpt, args);
}
/*
** SMFI_ADDRCPT -- send an additional recipient to the MTA
**
@ -646,3 +860,30 @@ smfi_progress(ctx)
return mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_PROGRESS, NULL, 0);
}
/*
** SMFI_VERSION -- return (runtime) version of libmilter
**
** Parameters:
** major -- (pointer to) major version
** minor -- (pointer to) minor version
** patchlevel -- (pointer to) patchlevel version
**
** Return value:
** MI_SUCCESS
*/
int
smfi_version(major, minor, patchlevel)
unsigned int *major;
unsigned int *minor;
unsigned int *patchlevel;
{
if (major != NULL)
*major = SM_LM_VRS_MAJOR(SMFI_VERSION);
if (minor != NULL)
*minor = SM_LM_VRS_MINOR(SMFI_VERSION);
if (patchlevel != NULL)
*patchlevel = SM_LM_VRS_MINOR(SMFI_VERSION);
return MI_SUCCESS;
}

View File

@ -0,0 +1,792 @@
/*
* Copyright (c) 2003-2004, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* Contributed by Jose Marcio Martins da Cruz - Ecole des Mines de Paris
* Jose-Marcio.Martins@ensmp.fr
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: worker.c,v 8.9 2006/12/18 18:26:51 ca Exp $")
#include "libmilter.h"
#if _FFR_WORKERS_POOL
typedef struct taskmgr_S taskmgr_T;
#define TM_SIGNATURE 0x23021957
struct taskmgr_S
{
long tm_signature; /* has the controller been initialized */
sthread_t tm_tid; /* thread id of controller */
smfi_hd_T tm_ctx_head; /* head of the linked list of contexts */
int tm_nb_workers; /* number of workers in the pool */
int tm_nb_idle; /* number of workers waiting */
int tm_p[2]; /* poll control pipe */
smutex_t tm_w_mutex; /* linked list access mutex */
scond_t tm_w_cond; /* */
};
static taskmgr_T Tskmgr = {0};
#define WRK_CTX_HEAD Tskmgr.tm_ctx_head
#define RD_PIPE (Tskmgr.tm_p[0])
#define WR_PIPE (Tskmgr.tm_p[1])
#define PIPE_SEND_SIGNAL() \
do \
{ \
char evt = 0x5a; \
int fd = WR_PIPE; \
if (write(fd, &evt, sizeof(evt)) != sizeof(evt)) \
smi_log(SMI_LOG_ERR, \
"Error writing to event pipe: %s", \
sm_errstring(errno)); \
} while (0)
#ifndef USE_PIPE_WAKE_POLL
# define USE_PIPE_WAKE_POLL 1
#endif /* USE_PIPE_WAKE_POLL */
/* poll check periodicity (default 10000 - 10 s) */
#define POLL_TIMEOUT 10000
/* worker conditional wait timeout (default 10 s) */
#define COND_TIMEOUT 10
/* functions */
static int mi_close_session __P((SMFICTX_PTR));
static void *mi_worker __P((void *));
static void *mi_pool_controller __P((void *));
static int mi_list_add_ctx __P((SMFICTX_PTR));
static int mi_list_del_ctx __P((SMFICTX_PTR));
/*
** periodicity of cleaning up old sessions (timedout)
** sessions list will be checked to find old inactive
** sessions each DT_CHECK_OLD_SESSIONS sec
*/
#define DT_CHECK_OLD_SESSIONS 600
#ifndef OLD_SESSION_TIMEOUT
# define OLD_SESSION_TIMEOUT ctx->ctx_timeout
#endif /* OLD_SESSION_TIMEOUT */
/* session states - with respect to the pool of workers */
#define WKST_INIT 0 /* initial state */
#define WKST_READY_TO_RUN 1 /* command ready do be read */
#define WKST_RUNNING 2 /* session running on a worker */
#define WKST_READY_TO_WAIT 3 /* session just finished by a worker */
#define WKST_WAITING 4 /* waiting for new command */
#define WKST_CLOSING 5 /* session finished */
#ifndef MIN_WORKERS
# define MIN_WORKERS 2 /* minimum number of threads to keep around */
#endif
#define MIN_IDLE 1 /* minimum number of idle threads */
/*
** Macros for threads and mutex management
*/
#define TASKMGR_LOCK() \
do \
{ \
if (!smutex_lock(&Tskmgr.tm_w_mutex)) \
smi_log(SMI_LOG_ERR, "TASKMGR_LOCK error"); \
} while (0)
#define TASKMGR_UNLOCK() \
do \
{ \
if (!smutex_unlock(&Tskmgr.tm_w_mutex)) \
smi_log(SMI_LOG_ERR, "TASKMGR_UNLOCK error"); \
} while (0)
#define TASKMGR_COND_WAIT() \
scond_timedwait(&Tskmgr.tm_w_cond, &Tskmgr.tm_w_mutex, COND_TIMEOUT)
#define TASKMGR_COND_SIGNAL() \
do \
{ \
if (scond_signal(&Tskmgr.tm_w_cond) != 0) \
smi_log(SMI_LOG_ERR, "TASKMGR_COND_SIGNAL error"); \
} while (0)
#define LAUNCH_WORKER(ctx) \
do \
{ \
int r; \
sthread_t tid; \
\
if ((r = thread_create(&tid, mi_worker, ctx)) != 0) \
smi_log(SMI_LOG_ERR, "LAUNCH_WORKER error: %s",\
sm_errstring(r)); \
} while (0)
#if POOL_DEBUG
# define POOL_LEV_DPRINTF(lev, x) \
do { \
if ((lev) < ctx->ctx_dbg) \
sm_dprintf x; \
} while (0)
#else /* POOL_DEBUG */
# define POOL_LEV_DPRINTF(lev, x)
#endif /* POOL_DEBUG */
/*
** MI_START_SESSION -- Start a session in the pool of workers
**
** Parameters:
** ctx -- context structure
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
int
mi_start_session(ctx)
SMFICTX_PTR ctx;
{
static long id = 0;
SM_ASSERT(Tskmgr.tm_signature == TM_SIGNATURE);
SM_ASSERT(ctx != NULL);
POOL_LEV_DPRINTF(4, ("PIPE r=[%d] w=[%d]", RD_PIPE, WR_PIPE));
TASKMGR_LOCK();
if (mi_list_add_ctx(ctx) != MI_SUCCESS)
{
TASKMGR_UNLOCK();
return MI_FAILURE;
}
ctx->ctx_sid = id++;
/* if there is an idle worker, signal it, otherwise start new worker */
if (Tskmgr.tm_nb_idle > 0)
{
ctx->ctx_wstate = WKST_READY_TO_RUN;
TASKMGR_COND_SIGNAL();
}
else
{
ctx->ctx_wstate = WKST_RUNNING;
LAUNCH_WORKER(ctx);
}
TASKMGR_UNLOCK();
return MI_SUCCESS;
}
/*
** MI_CLOSE_SESSION -- Close a session and clean up data structures
**
** Parameters:
** ctx -- context structure
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
static int
mi_close_session(ctx)
SMFICTX_PTR ctx;
{
SM_ASSERT(ctx != NULL);
(void) mi_list_del_ctx(ctx);
if (ValidSocket(ctx->ctx_sd))
{
(void) closesocket(ctx->ctx_sd);
ctx->ctx_sd = INVALID_SOCKET;
}
if (ctx->ctx_reply != NULL)
{
free(ctx->ctx_reply);
ctx->ctx_reply = NULL;
}
if (ctx->ctx_privdata != NULL)
{
smi_log(SMI_LOG_WARN, "%s: private data not NULL",
ctx->ctx_smfi->xxfi_name);
}
mi_clr_macros(ctx, 0);
free(ctx);
return MI_SUCCESS;
}
/*
** MI_POOL_CONTROLER_INIT -- Launch the worker pool controller
** Must be called before starting sessions.
**
** Parameters:
** none
**
** Returns:
** MI_SUCCESS/MI_FAILURE
*/
int
mi_pool_controller_init()
{
sthread_t tid;
int r, i;
if (Tskmgr.tm_signature == TM_SIGNATURE)
return MI_SUCCESS;
SM_TAILQ_INIT(&WRK_CTX_HEAD);
Tskmgr.tm_tid = (sthread_t) -1;
Tskmgr.tm_nb_workers = 0;
Tskmgr.tm_nb_idle = 0;
if (pipe(Tskmgr.tm_p) != 0)
{
smi_log(SMI_LOG_ERR, "can't create event pipe: %s",
sm_errstring(r));
return MI_FAILURE;
}
POOL_LEV_DPRINTF(4, ("PIPE r=[%d] w=[%d]", RD_PIPE, WR_PIPE));
(void) smutex_init(&Tskmgr.tm_w_mutex);
(void) scond_init(&Tskmgr.tm_w_cond);
/* Launch the pool controller */
if ((r = thread_create(&tid, mi_pool_controller, (void *) NULL)) != 0)
{
smi_log(SMI_LOG_ERR, "can't create controller thread: %s",
sm_errstring(r));
return MI_FAILURE;
}
Tskmgr.tm_tid = tid;
Tskmgr.tm_signature = TM_SIGNATURE;
/* Create the pool of workers */
for (i = 0; i < MIN_WORKERS; i++)
{
if ((r = thread_create(&tid, mi_worker, (void *) NULL)) != 0)
{
smi_log(SMI_LOG_ERR, "can't create workers crew: %s",
sm_errstring(r));
return MI_FAILURE;
}
}
return MI_SUCCESS;
}
/*
** MI_POOL_CONTROLLER -- manage the pool of workers
** This thread must be running when listener begins
** starting sessions
**
** Parameters:
** arg -- unused
**
** Returns:
** NULL
**
** Control flow:
** for (;;)
** Look for timed out sessions
** Select sessions to wait for sendmail command
** Poll set of file descriptors
** if timeout
** continue
** For each file descriptor ready
** launch new thread if no worker available
** else
** signal waiting worker
*/
/* Poll structure array (pollfd) size step */
#define PFD_STEP 256
#define WAIT_FD(i) (pfd[i].fd)
#define WAITFN "POLL"
static void *
mi_pool_controller(arg)
void *arg;
{
struct pollfd *pfd = NULL;
int dim_pfd = 0;
bool rebuild_set = true;
int pcnt = 0; /* error count for poll() failures */
Tskmgr.tm_tid = sthread_get_id();
if (pthread_detach(Tskmgr.tm_tid) != 0)
{
smi_log(SMI_LOG_ERR, "Failed to detach pool controller thread");
return NULL;
}
pfd = (struct pollfd *) malloc(PFD_STEP * sizeof(struct pollfd));
if (pfd == NULL)
{
smi_log(SMI_LOG_ERR, "Failed to malloc pollfd array: %s",
sm_errstring(errno));
return NULL;
}
dim_pfd = PFD_STEP;
for (;;)
{
SMFICTX_PTR ctx;
int nfd, rfd, i;
time_t now;
time_t lastcheck;
POOL_LEV_DPRINTF(4, ("Let's %s again...", WAITFN));
if (mi_stop() != MILTER_CONT)
break;
TASKMGR_LOCK();
now = time(NULL);
/* check for timed out sessions? */
if (lastcheck + DT_CHECK_OLD_SESSIONS < now)
{
SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
{
if (ctx->ctx_wstate == WKST_WAITING)
{
if (ctx->ctx_wait == 0)
{
ctx->ctx_wait = now;
continue;
}
/* if session timed out, close it */
if (ctx->ctx_wait + OLD_SESSION_TIMEOUT
< now)
{
sfsistat (*fi_close) __P((SMFICTX *));
POOL_LEV_DPRINTF(4,
("Closing old connection: sd=%d id=%d",
ctx->ctx_sd,
ctx->ctx_sid));
if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL)
(void) (*fi_close)(ctx);
mi_close_session(ctx);
ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD);
continue;
}
}
}
lastcheck = now;
}
if (rebuild_set)
{
/*
** Initialize poll set.
** Insert into the poll set the file descriptors of
** all sessions waiting for a command from sendmail.
*/
nfd = 0;
/* begin with worker pipe */
pfd[nfd].fd = RD_PIPE;
pfd[nfd].events = MI_POLL_RD_FLAGS;
pfd[nfd].revents = 0;
nfd++;
SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
{
/*
** update ctx_wait - start of wait moment -
** for timeout
*/
if (ctx->ctx_wstate == WKST_READY_TO_WAIT)
ctx->ctx_wait = now;
/* add the session to the pollfd array? */
if ((ctx->ctx_wstate == WKST_READY_TO_WAIT) ||
(ctx->ctx_wstate == WKST_WAITING))
{
/*
** Resize the pollfd array if it
** isn't large enough.
*/
if (nfd >= dim_pfd)
{
struct pollfd *tpfd;
size_t new;
new = (dim_pfd + PFD_STEP) *
sizeof(*tpfd);
tpfd = (struct pollfd *)
realloc(pfd, new);
if (tpfd != NULL)
{
pfd = tpfd;
dim_pfd += PFD_STEP;
}
else
{
smi_log(SMI_LOG_ERR,
"Failed to realloc pollfd array:%s",
sm_errstring(errno));
}
}
/* add the session to pollfd array */
if (nfd < dim_pfd)
{
ctx->ctx_wstate = WKST_WAITING;
pfd[nfd].fd = ctx->ctx_sd;
pfd[nfd].events = MI_POLL_RD_FLAGS;
pfd[nfd].revents = 0;
nfd++;
}
}
}
}
TASKMGR_UNLOCK();
/* Everything is ready, let's wait for an event */
rfd = poll(pfd, nfd, POLL_TIMEOUT);
POOL_LEV_DPRINTF(4, ("%s returned: at epoch %d value %d",
WAITFN, now, nfd));
/* timeout */
if (rfd == 0)
continue;
rebuild_set = true;
/* error */
if (rfd < 0)
{
if (errno == EINTR)
continue;
pcnt++;
smi_log(SMI_LOG_ERR,
"%s() failed (%s), %s",
WAITFN, sm_errstring(errno),
pcnt >= MAX_FAILS_S ? "abort" : "try again");
if (pcnt >= MAX_FAILS_S)
goto err;
}
pcnt = 0;
/* something happened */
for (i = 0; i < nfd; i++)
{
if (pfd[i].revents == 0)
continue;
POOL_LEV_DPRINTF(4, ("%s event on pfd[%d/%d]=%d ",
WAITFN, i, nfd,
WAIT_FD(i)));
/* has a worker signaled an end of task ? */
if (WAIT_FD(i) == RD_PIPE)
{
char evt = 0;
int r = 0;
POOL_LEV_DPRINTF(4,
("PIPE WILL READ evt = %08X %08X",
pfd[i].events, pfd[i].revents));
if ((pfd[i].revents & MI_POLL_RD_FLAGS) != 0)
{
r = read(RD_PIPE, &evt, sizeof(evt));
if (r == sizeof(evt))
{
/* Do nothing */
}
}
POOL_LEV_DPRINTF(4,
("PIPE DONE READ i=[%d] fd=[%d] r=[%d] evt=[%d]",
i, RD_PIPE, r, evt));
if ((pfd[i].revents & ~MI_POLL_RD_FLAGS) != 0)
{
/* Exception handling */
}
continue;
}
/* no ! sendmail wants to send a command */
SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link)
{
if (ctx->ctx_wstate != WKST_WAITING)
continue;
POOL_LEV_DPRINTF(4,
("Checking context sd=%d - fd=%d ",
ctx->ctx_sd , WAIT_FD(i)));
if (ctx->ctx_sd == pfd[i].fd)
{
TASKMGR_LOCK();
POOL_LEV_DPRINTF(4,
("TASK: found %d for fd[%d]=%d",
ctx->ctx_sid, i, WAIT_FD(i)));
if (Tskmgr.tm_nb_idle > 0)
{
ctx->ctx_wstate = WKST_READY_TO_RUN;
TASKMGR_COND_SIGNAL();
}
else
{
ctx->ctx_wstate = WKST_RUNNING;
LAUNCH_WORKER(ctx);
}
TASKMGR_UNLOCK();
break;
}
}
POOL_LEV_DPRINTF(4,
("TASK %s FOUND - Checking PIPE for fd[%d]",
ctx != NULL ? "" : "NOT", WAIT_FD(i)));
}
}
err:
if (pfd != NULL)
free(pfd);
Tskmgr.tm_signature = 0;
for (;;)
{
SMFICTX_PTR ctx;
ctx = SM_TAILQ_FIRST(&WRK_CTX_HEAD);
if (ctx == NULL)
break;
mi_close_session(ctx);
}
(void) smutex_destroy(&Tskmgr.tm_w_mutex);
(void) scond_destroy(&Tskmgr.tm_w_cond);
return NULL;
}
/*
** Look for a task ready to run.
** Value of ctx is NULL or a pointer to a task ready to run.
*/
#define GET_TASK_READY_TO_RUN() \
SM_TAILQ_FOREACH(ctx, &WRK_CTX_HEAD, ctx_link) \
{ \
if (ctx->ctx_wstate == WKST_READY_TO_RUN) \
{ \
ctx->ctx_wstate = WKST_RUNNING; \
break; \
} \
}
/*
** MI_WORKER -- worker thread
** executes tasks distributed by the mi_pool_controller
** or by mi_start_session
**
** Parameters:
** arg -- pointer to context structure
**
** Returns:
** NULL pointer
*/
static void *
mi_worker(arg)
void *arg;
{
SMFICTX_PTR ctx;
bool done;
sthread_t t_id;
int r;
ctx = (SMFICTX_PTR) arg;
done = false;
if (ctx != NULL)
ctx->ctx_wstate = WKST_RUNNING;
t_id = sthread_get_id();
if (pthread_detach(t_id) != 0)
{
smi_log(SMI_LOG_ERR, "Failed to detach worker thread");
if (ctx != NULL)
ctx->ctx_wstate = WKST_READY_TO_RUN;
return NULL;
}
TASKMGR_LOCK();
Tskmgr.tm_nb_workers++;
TASKMGR_UNLOCK();
while (!done)
{
if (mi_stop() != MILTER_CONT)
break;
/* let's handle next task... */
if (ctx != NULL)
{
int res;
POOL_LEV_DPRINTF(4,
("worker %d: new task -> let's handle it",
t_id));
res = mi_engine(ctx);
POOL_LEV_DPRINTF(4,
("worker %d: mi_engine returned %d", t_id, res));
TASKMGR_LOCK();
if (res != MI_CONTINUE)
{
ctx->ctx_wstate = WKST_CLOSING;
/*
** Delete context from linked list of
** sessions and close session.
*/
mi_close_session(ctx);
}
else
{
ctx->ctx_wstate = WKST_READY_TO_WAIT;
POOL_LEV_DPRINTF(4,
("writing to event pipe..."));
/*
** Signal task controller to add new session
** to poll set.
*/
PIPE_SEND_SIGNAL();
}
TASKMGR_UNLOCK();
ctx = NULL;
}
/* check if there is any task waiting to be served */
TASKMGR_LOCK();
GET_TASK_READY_TO_RUN();
/* Got a task? */
if (ctx != NULL)
{
TASKMGR_UNLOCK();
continue;
}
/*
** if not, let's check if there is enough idle workers
** if yes: quit
*/
if (Tskmgr.tm_nb_workers > MIN_WORKERS &&
Tskmgr.tm_nb_idle > MIN_IDLE)
done = true;
POOL_LEV_DPRINTF(4, ("worker %d: checking ... %d %d", t_id,
Tskmgr.tm_nb_workers, Tskmgr.tm_nb_idle + 1));
if (done)
{
POOL_LEV_DPRINTF(4, ("worker %d: quitting... ", t_id));
Tskmgr.tm_nb_workers--;
TASKMGR_UNLOCK();
continue;
}
/*
** if no task ready to run, wait for another one
*/
Tskmgr.tm_nb_idle++;
TASKMGR_COND_WAIT();
Tskmgr.tm_nb_idle--;
/* look for a task */
GET_TASK_READY_TO_RUN();
TASKMGR_UNLOCK();
}
return NULL;
}
/*
** MI_LIST_ADD_CTX -- add new session to linked list
**
** Parameters:
** ctx -- context structure
**
** Returns:
** MI_FAILURE/MI_SUCCESS
*/
static int
mi_list_add_ctx(ctx)
SMFICTX_PTR ctx;
{
SM_ASSERT(ctx != NULL);
SM_TAILQ_INSERT_TAIL(&WRK_CTX_HEAD, ctx, ctx_link);
return MI_SUCCESS;
}
/*
** MI_LIST_DEL_CTX -- remove session from linked list when finished
**
** Parameters:
** ctx -- context structure
**
** Returns:
** MI_FAILURE/MI_SUCCESS
*/
static int
mi_list_del_ctx(ctx)
SMFICTX_PTR ctx;
{
SM_ASSERT(ctx != NULL);
if (SM_TAILQ_EMPTY(&WRK_CTX_HEAD))
return MI_FAILURE;
SM_TAILQ_REMOVE(&WRK_CTX_HEAD, ctx, ctx_link);
return MI_SUCCESS;
}
#endif /* _FFR_WORKERS_POOL */

View File

@ -1,4 +1,4 @@
# $Id: Makefile,v 1.1 2000/03/27 19:26:48 dmoen Exp $
# $Id: Makefile,v 1.2 2006/08/16 21:06:30 ca Exp $
SHELL= /bin/sh
BUILD= ./Build
@ -10,6 +10,8 @@ clean: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
install: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
check: FRC
$(SHELL) $(BUILD) $(OPTIONS) $@
fresh: FRC
$(SHELL) $(BUILD) $(OPTIONS) -c

View File

@ -1,38 +1,44 @@
dnl $Id: Makefile.m4,v 1.70 2005/12/22 18:31:11 ca Exp $
dnl $Id: Makefile.m4,v 1.72 2006/08/16 21:06:31 ca Exp $
define(`confREQUIRE_LIBUNIX')
include(confBUILDTOOLSDIR`/M4/switch.m4')
define(`confREQUIRE_LIBSM', `true')
define(`confREQUIRE_SM_OS_H', `true')
PREPENDDEF(`confENVDEF', `confMAPDEF')
bldPRODUCT_START(`library', `libsm')
define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c ')
define(`bldSOURCES', ` assert.c debug.c errstring.c exc.c heap.c match.c rpool.c strdup.c strerror.c strl.c clrerr.c fclose.c feof.c ferror.c fflush.c fget.c fpos.c findfp.c flags.c fopen.c fprintf.c fpurge.c fput.c fread.c fscanf.c fseek.c fvwrite.c fwalk.c fwrite.c get.c makebuf.c put.c refill.c rewind.c setvbuf.c smstdio.c snprintf.c sscanf.c stdio.c strio.c ungetc.c vasprintf.c vfprintf.c vfscanf.c vprintf.c vsnprintf.c wbuf.c wsetup.c string.c stringf.c xtrap.c strto.c test.c path.c strcasecmp.c strrevcmp.c signal.c clock.c config.c shm.c sem.c mbdb.c strexit.c cf.c ldap.c niprop.c mpeix.c memstat.c util.c ')
bldPRODUCT_END
dnl msg.c
dnl syslogio.c
include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/sm-test.m4')
smtest(`t-event', `run')
smtest(`t-exc', `run')
smtest(`t-rpool', `run')
smtest(`t-string', `run')
smtest(`t-smstdio', `run')
smtest(`t-match', `run')
smtest(`t-strio', `run')
smtest(`t-heap', `run')
smtest(`t-fopen', `run')
smtest(`t-strl', `run')
smtest(`t-strrevcmp', `run')
smtest(`t-types', `run')
smtest(`t-path', `run')
smtest(`t-float', `run')
smtest(`t-scanf', `run')
smtest(`t-shm', `run')
smtest(`t-sem', `run')
dnl smtest(`t-msg', `run')
smtest(`t-cf')
smtest(`b-strcmp')
define(`confCHECK_LIBS',`libsm.a')dnl
include(confBUILDTOOLSDIR`/M4/'bldM4_TYPE_DIR`/check.m4')
smcheck(`t-event', `compile-run')
smcheck(`t-exc', `compile-run')
smcheck(`t-rpool', `compile-run')
smcheck(`t-string', `compile-run')
smcheck(`t-smstdio', `compile-run')
smcheck(`t-match', `compile-run')
smcheck(`t-strio', `compile-run')
smcheck(`t-heap', `compile-run')
smcheck(`t-fopen', `compile-run')
smcheck(`t-strl', `compile-run')
smcheck(`t-strrevcmp', `compile-run')
smcheck(`t-types', `compile-run')
smcheck(`t-path', `compile-run')
smcheck(`t-float', `compile-run')
smcheck(`t-scanf', `compile-run')
smcheck(`t-shm', `compile-run')
smcheck(`t-sem', `compile-run')
dnl smcheck(`t-msg', `compile-run')
smcheck(`t-cf')
smcheck(`b-strcmp')
dnl SM_CONF_STRL cannot be turned off
dnl smtest(`b-strl')
smtest(`t-memstat')
dnl smcheck(`b-strl')
smcheck(`t-memstat')
smcheck(`t-qic', `compile-run')
divert(bldTARGETS_SECTION)
divert(0)
bldFINISH

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2003 Sendmail, Inc. and its suppliers.
* Copyright (c) 2000-2003, 2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: config.c,v 1.30 2003/12/10 03:19:07 gshapiro Exp $")
SM_RCSID("@(#)$Id: config.c,v 1.31 2007/03/14 21:21:49 ca Exp $")
#include <stdlib.h>
#include <sm/heap.h>
@ -247,5 +247,14 @@ char *SmCompileOptions[] =
#if SM_VA_STD
"SM_VA_STD",
#endif /* SM_VA_STD */
#if USEKSTAT
"USEKSTAT",
#endif /* USEKSTAT */
#if USEPROCMEMINFO
"USEPROCMEMINFO",
#endif /* USEPROCMEMINFO */
#if USESWAPCTL
"USESWAPCTL",
#endif /* USESWAPCTL */
NULL
};

View File

@ -9,7 +9,7 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: exc.c,v 1.48 2003/12/05 22:45:24 ca Exp $")
SM_RCSID("@(#)$Id: exc.c,v 1.49 2006/12/19 19:28:09 ca Exp $")
/*
** exception handling
@ -229,7 +229,9 @@ const SM_EXC_TYPE_T SmEtypeErr =
** an out-of-memory exception so that exc is not leaked.
*/
SM_EXC_T *
static SM_EXC_T *sm_exc_vnew_x __P((const SM_EXC_TYPE_T *, va_list SM_NONVOLATILE));
static SM_EXC_T *
sm_exc_vnew_x(etype, ap)
const SM_EXC_TYPE_T *etype;
va_list SM_NONVOLATILE ap;
@ -418,26 +420,6 @@ sm_exc_new_x(etype, va_alist)
return exc;
}
/*
** SM_ADDREF -- Add a reference to an exception object.
**
** Parameters:
** exc -- exception object.
**
** Returns:
** exc itself.
*/
SM_EXC_T *
sm_addref(exc)
SM_EXC_T *exc;
{
SM_REQUIRE_ISA(exc, SmExcMagic);
if (exc->exc_refcount != 0)
++exc->exc_refcount;
return exc;
}
/*
** SM_EXC_FREE -- Destroy a reference to an exception object.
**

View File

@ -8,7 +8,7 @@
<center>
<h1> libsm : Exception Handling </h1>
<br> $Id: exc.html,v 1.12 2001/02/13 21:21:25 gshapiro Exp $
<br> $Id: exc.html,v 1.13 2006/06/20 17:18:16 ca Exp $
</center>
<h2> Introduction </h2>
@ -28,7 +28,7 @@ Here are the basic concepts:
<p>
<li>
Errors are not represented by a single integer error code,
because that you can't represent everything that an error handler
because then you can't represent everything that an error handler
might need to know about an error by a single integer.
Instead, errors are represented by exception objects.
An exception object contains an exception code and an array

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers.
* Copyright (c) 2000-2002, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@ -13,7 +13,7 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: findfp.c,v 1.66 2002/02/20 02:40:24 ca Exp $")
SM_RCSID("@(#)$Id: findfp.c,v 1.67 2006/08/28 21:24:46 ca Exp $")
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
@ -365,6 +365,11 @@ sm_io_getinfo(fp, what, valp)
switch (what)
{
case SM_IO_WHAT_VECTORS:
if (valp == NULL)
{
errno = EINVAL;
return -1;
}
/* This is the "generic" available for all */
v->f_close = fp->f_close;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2001, 2004 Sendmail, Inc. and its suppliers.
* Copyright (c) 2000-2001, 2004, 2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
@ -13,11 +13,12 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: flags.c,v 1.22 2004/03/03 19:20:29 ca Exp $")
SM_RCSID("@(#)$Id: flags.c,v 1.23 2006/12/19 19:44:23 ca Exp $")
#include <sys/types.h>
#include <sys/file.h>
#include <errno.h>
#include <sm/io.h>
#include "local.h"
/*
** SM_FLAGS -- translate external (user) flags into internal flags
@ -31,9 +32,9 @@ SM_RCSID("@(#)$Id: flags.c,v 1.22 2004/03/03 19:20:29 ca Exp $")
int
sm_flags(flags)
register int flags;
int flags;
{
register int ret;
int ret;
switch(SM_IO_MODE(flags))
{

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001-2005 Sendmail, Inc. and its suppliers.
* Copyright (c) 2001-2006 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -7,8 +7,11 @@
* the sendmail distribution.
*/
/* some "deprecated" calls are used, e.g., ldap_get_values() */
#define LDAP_DEPRECATED 1
#include <sm/gen.h>
SM_RCSID("@(#)$Id: ldap.c,v 1.67 2005/12/14 00:08:03 ca Exp $")
SM_RCSID("@(#)$Id: ldap.c,v 1.78 2006/08/30 22:56:59 ca Exp $")
#if LDAPMAP
# include <sys/types.h>
@ -95,6 +98,7 @@ sm_ldap_clear(lmap)
lmap->ldap_res = NULL;
lmap->ldap_next = NULL;
lmap->ldap_pid = 0;
lmap->ldap_multi_args = false;
}
/*
@ -280,35 +284,67 @@ ldaptimeout(unused)
}
/*
** SM_LDAP_SEARCH -- initiate LDAP search
** SM_LDAP_SEARCH_M -- initiate multi-key LDAP search
**
** Initiate an LDAP search, return the msgid.
** The calling function must collect the results.
**
** Parameters:
** lmap -- LDAP map information
** key -- key to substitute in LDAP filter
** argv -- key vector of substitutions in LDAP filter
** NOTE: argv must have SM_LDAP_ARGS elements to prevent
** out of bound array references
**
** Returns:
** -1 on failure, msgid on success
** <0 on failure (SM_LDAP_ERR*), msgid on success
**
*/
int
sm_ldap_search(lmap, key)
sm_ldap_search_m(lmap, argv)
SM_LDAP_STRUCT *lmap;
char *key;
char **argv;
{
int msgid;
char *fp, *p, *q;
char filter[LDAPMAP_MAX_FILTER + 1];
/* substitute key into filter, perhaps multiple times */
SM_REQUIRE(lmap != NULL);
SM_REQUIRE(argv != NULL);
SM_REQUIRE(argv[0] != NULL);
memset(filter, '\0', sizeof filter);
fp = filter;
p = lmap->ldap_filter;
while ((q = strchr(p, '%')) != NULL)
{
char *key;
if (lmap->ldap_multi_args)
{
#if SM_LDAP_ARGS < 10
# ERROR _SM_LDAP_ARGS must be 10
#endif /* SM_LDAP_ARGS < 10 */
if (q[1] == 's')
key = argv[0];
else if (q[1] >= '0' && q[1] <= '9')
{
key = argv[q[1] - '0'];
if (key == NULL)
{
# if SM_LDAP_ERROR_ON_MISSING_ARGS
return SM_LDAP_ERR_ARG_MISS;
# else /* SM_LDAP_ERROR_ON_MISSING_ARGS */
key = "";
# endif /* SM_LDAP_ERROR_ON_MISSING_ARGS */
}
}
else
key = NULL;
}
else
key = argv[0];
if (q[1] == 's')
{
(void) sm_snprintf(fp, SPACELEFT(filter, fp),
@ -316,7 +352,8 @@ sm_ldap_search(lmap, key)
fp += strlen(fp);
p = q + 2;
}
else if (q[1] == '0')
else if (q[1] == '0' ||
(lmap->ldap_multi_args && q[1] >= '0' && q[1] <= '9'))
{
char *k = key;
@ -367,6 +404,34 @@ sm_ldap_search(lmap, key)
return msgid;
}
/*
** SM_LDAP_SEARCH -- initiate LDAP search
**
** Initiate an LDAP search, return the msgid.
** The calling function must collect the results.
** Note this is just a wrapper into sm_ldap_search_m()
**
** Parameters:
** lmap -- LDAP map information
** key -- key to substitute in LDAP filter
**
** Returns:
** <0 on failure, msgid on success
**
*/
int
sm_ldap_search(lmap, key)
SM_LDAP_STRUCT *lmap;
char *key;
{
char *argv[SM_LDAP_ARGS];
memset(argv, '\0', sizeof argv);
argv[0] = key;
return sm_ldap_search_m(lmap, argv);
}
/*
** SM_LDAP_HAS_OBJECTCLASS -- determine if an LDAP entry is part of a
** particular objectClass
@ -480,29 +545,29 @@ sm_ldap_add_recurse(top, item, type, rpool)
{
/* Allocate an initial SM_LDAP_RECURSE_LIST struct */
*top = sm_rpool_malloc_x(rpool, sizeof **top);
(*top)->lr_cnt = 0;
(*top)->lr_size = 0;
(*top)->lr_data = NULL;
(*top)->lrl_cnt = 0;
(*top)->lrl_size = 0;
(*top)->lrl_data = NULL;
}
if ((*top)->lr_cnt >= (*top)->lr_size)
if ((*top)->lrl_cnt >= (*top)->lrl_size)
{
/* Grow the list of SM_LDAP_RECURSE_ENTRY ptrs */
olddata = (*top)->lr_data;
if ((*top)->lr_size == 0)
olddata = (*top)->lrl_data;
if ((*top)->lrl_size == 0)
{
oldsizeb = 0;
(*top)->lr_size = 256;
(*top)->lrl_size = 256;
}
else
{
oldsizeb = (*top)->lr_size * sizeof *((*top)->lr_data);
(*top)->lr_size *= 2;
oldsizeb = (*top)->lrl_size * sizeof *((*top)->lrl_data);
(*top)->lrl_size *= 2;
}
(*top)->lr_data = sm_rpool_malloc_x(rpool,
(*top)->lr_size * sizeof *((*top)->lr_data));
(*top)->lrl_data = sm_rpool_malloc_x(rpool,
(*top)->lrl_size * sizeof *((*top)->lrl_data));
if (oldsizeb > 0)
memcpy((*top)->lr_data, olddata, oldsizeb);
memcpy((*top)->lrl_data, olddata, oldsizeb);
}
/*
@ -511,7 +576,7 @@ sm_ldap_add_recurse(top, item, type, rpool)
*/
n = 0;
m = (*top)->lr_cnt - 1;
m = (*top)->lrl_cnt - 1;
if (m < 0)
insertat = 0;
else
@ -521,21 +586,21 @@ sm_ldap_add_recurse(top, item, type, rpool)
{
p = (m + n) / 2;
rc = sm_strcasecmp(item, (*top)->lr_data[p]->lr_search);
rc = sm_strcasecmp(item, (*top)->lrl_data[p]->lr_search);
if (rc == 0)
rc = type - (*top)->lr_data[p]->lr_type;
rc = type - (*top)->lrl_data[p]->lr_type;
if (rc < 0)
m = p - 1;
else if (rc > 0)
n = p + 1;
else
return (*top)->lr_data[p];
return (*top)->lrl_data[p];
if (m == -1)
insertat = 0;
else if (n >= (*top)->lr_cnt)
insertat = (*top)->lr_cnt;
else if (n >= (*top)->lrl_cnt)
insertat = (*top)->lrl_cnt;
else if (m < n)
insertat = m + 1;
}
@ -548,10 +613,10 @@ sm_ldap_add_recurse(top, item, type, rpool)
newe = sm_rpool_malloc_x(rpool, sizeof *newe);
if (newe != NULL)
{
moveb = ((*top)->lr_cnt - insertat) * sizeof *((*top)->lr_data);
moveb = ((*top)->lrl_cnt - insertat) * sizeof *((*top)->lrl_data);
if (moveb > 0)
memmove(&((*top)->lr_data[insertat + 1]),
&((*top)->lr_data[insertat]),
memmove(&((*top)->lrl_data[insertat + 1]),
&((*top)->lrl_data[insertat]),
moveb);
newe->lr_search = sm_rpool_strdup_x(rpool, item);
@ -560,8 +625,8 @@ sm_ldap_add_recurse(top, item, type, rpool)
newe->lr_attrs = NULL;
newe->lr_done = false;
((*top)->lr_data)[insertat] = newe;
(*top)->lr_cnt++;
((*top)->lrl_data)[insertat] = newe;
(*top)->lrl_cnt++;
}
return newe;
}
@ -1082,13 +1147,14 @@ sm_ldap_results(lmap, msgid, flags, delim, rpool, result,
** will be expanded by the top level.
*/
for (rlidx = 0; recurse != NULL && rlidx < recurse->lr_cnt; rlidx++)
for (rlidx = 0; recurse != NULL && rlidx < recurse->lrl_cnt;
rlidx++)
{
int newflags;
int sid;
int status;
rl = recurse->lr_data[rlidx];
rl = recurse->lrl_data[rlidx];
newflags = flags;
if (rl->lr_done)

View File

@ -11,7 +11,7 @@
* forth in the LICENSE file which can be found at the top level of
* the sendmail distribution.
*
* $Id: local.h,v 1.57 2006/02/28 18:48:25 ca Exp $
* $Id: local.h,v 1.58 2006/12/19 19:44:23 ca Exp $
*/
/*
@ -102,6 +102,8 @@ extern const char SmFileMagic[];
#define sm_io_flockfile(fp) ((void) 0)
#define sm_io_funlockfile(fp) ((void) 0)
int sm_flags __P((int));
#ifndef FDSET_CAST
# define FDSET_CAST /* empty cast for fd_set arg to select */
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005 Sendmail, Inc. and its suppliers.
* Copyright (c) 2005-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -8,9 +8,10 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: memstat.c,v 1.4 2005/12/10 00:38:48 ca Exp $")
SM_RCSID("@(#)$Id: memstat.c,v 1.6 2007/03/20 23:26:12 ca Exp $")
#include <errno.h>
#include <sm/misc.h>
#if USESWAPCTL
#include <sys/stat.h>
@ -265,6 +266,8 @@ sm_memstat_get(resource, pvalue)
return -1; /* try to reopen? */
rewind(fp);
l = strlen(resource);
if (l >= sizeof(buf))
return EINVAL;
while (fgets(buf, sizeof(buf), fp) != NULL)
{
if (strncmp(buf, resource, l) == 0 && buf[l] == ':')

View File

@ -13,10 +13,11 @@
*/
#include <sm/gen.h>
SM_RCSID("@(#)$Id: snprintf.c,v 1.23 2001/09/11 04:04:49 gshapiro Exp $")
SM_RCSID("@(#)$Id: snprintf.c,v 1.24 2006/10/12 21:50:10 ca Exp $")
#include <limits.h>
#include <sm/varargs.h>
#include <sm/io.h>
#include <sm/string.h>
#include "local.h"
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2006 Sendmail, Inc. and its suppliers.
* Copyright (c) 2005-2007 Sendmail, Inc. and its suppliers.
* All rights reserved.
*
* By using this file, you agree to the terms and conditions set
@ -8,7 +8,9 @@
*/
#include <sm/gen.h>
SM_IDSTR(id, "@(#)$Id: t-memstat.c,v 1.6 2006/03/27 22:34:47 ca Exp $")
SM_IDSTR(id, "@(#)$Id: t-memstat.c,v 1.9 2007/03/14 21:41:09 ca Exp $")
#include <sm/misc.h>
/*
** Simple test program for memstat
@ -23,6 +25,18 @@ SM_IDSTR(id, "@(#)$Id: t-memstat.c,v 1.6 2006/03/27 22:34:47 ca Exp $")
extern char *optarg;
extern int optind;
void
usage(prg)
char *prg;
{
fprintf(stderr, "usage: %s [options]\n", prg);
fprintf(stderr, "options:\n");
fprintf(stderr, "-l n loop n times\n");
fprintf(stderr, "-m n allocate n bytes per iteration\n");
fprintf(stderr, "-r name use name as resource to query\n");
fprintf(stderr, "-s n sleep n seconds per iteration\n");
}
int
main(argc, argv)
int argc;
@ -56,7 +70,8 @@ main(argc, argv)
break;
default:
break;
usage(argv[0]);
exit(1);
}
}

Some files were not shown because too many files have changed in this diff Show More