Previous Section Next Section

D.1 How checkcompat( ) Works

When sendmail prepares to deliver mail, it first checks the size of the mail message and rejects (bounces) it if it is larger than the limit imposed by the M= delivery agent equate (see M=). V8.8 and above sendmail then call the check_compat rule set (see Section 7.1.4). After that, all versions of sendmail call the checkcompat( ) routine.

The checkcompat( ) routine lies in a unique position within the sendmail code. It is the one place where both the sender and already aliased recipient addresses are available at the same time. Because it is invoked immediately before actual delivery, all the information needed for delivery is available to you for checking.

If checkcompat( ) returns EX_OK, as defined in <sysexits.h>, the mail message is considered OK and delivered. Otherwise the message is bounced. If you wish the message to be requeued instead of bounced, you can return EX_TEMPFAIL.

Again note that the checkcompat( ) routine is called once for each already aliased recipient.

D.1.1 Arguments Passed to checkcompat( )

The checkcompat( ) is found in the C-language source file sendmail/conf.c. Inside that file you will find it declared like this:

checkcompat(to, e)
        register ADDRESS *to;
        register ENVELOPE *e;

Here, to is a pointer to a structure of typedef ADDRESS which contains information about the recipient. And e is a pointer to a structure of typedef ENVELOPE which contains information about the current envelope. (Actually, both are linked lists of structures.)

The members of the ADDRESS *to structure are shown in Table D-1. Note that these members are correct for V8.12 sendmail only. Also note that the table shows only those members that can be useful in a checkcompat( ) routine (see sendmail.h for the other members of *to).

Table D-1. ADDRESS *to members

Type

Member

Description

struct address *

q_alias

The alias that yielded this address

char *

q_finalrcpt

This is a Final-Recipient: DSN header

unsigned long

q_flags

Address flags (see Table 16-3)

char *

q_fullname

The (GECOS) full name of q_ruser, if known

gid_t

q_gid

The gid of the q_ruser, if known

char *

q_home

The home directory (path), if F=w delivery-agent flag is set

char *

q_host

The host part ($@) from rule set 0 (seeSection 19.5)

struct mailer *

q_mailer

The delivery agent ($#) from rule set 0 (see Section 19.5)

char *

q_message

Message regarding address (not always an error)

struct address *

q_next

Link to the next ADDRESS in the chain

char *

q_orcpt

The ORCPT parameter from RCPT TO: line was set

char *

q_owner

The owner of q_alias

char *

q_paddr

The address in a form suitable for printing

int

q_qdir

Queue directory inside group

int

q_qgrp

Index into queue groups

char *

q_ruser

The login name for this user, if known

time_t

q_statdate

The date of the status change

short

q_state

The state of the address

char *

q_statmta

Which MTA generated q_rstatus

uid_t

q_uid

The uid of the q_ruser, if known

char *

q_user

The user part ($:) from rule set 0 (seeSection 19.5)

The members of the ENVELOPE *e structure are shown in Table D-2. Note that these members are correct for V8.12 sendmail only. Also note that the table shows only those members that can be useful in a checkcompat( ) routine (see sendmail.h for other members of *e).

Table D-2. ENVELOPE *e members

Type

Member

Description

char *

e_auth_param

The parameters set by AUTH=

char *

e_bodytype

The type of message body

short

e_class

The message class (priority, junk, etc.)

time_t

e_ctime

The time this message was accepted

long

e_deliver_by

The DELIVERYBY BY= interval

int

e_dlvr_flag

The DELIVERYBY BY= flags

SM_FILE_T *

e_dfp

The datafile

int

e_dfqgrp

The datafile's queue group index

int

e_dfqdir

The datafile's queue directory index

time_t

e_dtime

The time of the last delivery attempt

char *

e_envid

Envelope ID from MAIL FROM:

short

e_errormode

The error return mode

ADDRESS *

e_errorqueue

The queue for error responses

unsigned long

e_flags

Envelope flags (see Table 16-6)

ADDRESS

e_from

The sender address structure

char **

e_fromdomain

The domain part of the sender

HDR *

e_header

Linked list of headers

short

e_hopcount

The hop count for the message

char *

e_id

The ID for this entry

char *

e_message

The error message

char *

e_msgid

The message ID (for logging)

long

e_msgpriority

The adjusted priority of this message

long

e_msgsize

The size of the message in bytes

int

e_nrcpts

The number of recipients

int

e_ntries

The number of delivery attempts

int

e_qgrp

The queue group (index into queues)

int

e_qdir

The index into queue directories

char *

e_sender

Sender address with comments stripped

ADDRESS *

e_sendqueue

Linked list of recipients

char *

e_statmsg

The status message (changes per delivery)

char *

e_status

The DSN status for this message

short

e_timeoutclass

The message timeout class

The checkcompat( ) routine is a powerful internal hook inside sendmail. It is so internal and powerful, in fact, that if you are truly clever you can even use checkcompat( ) to modify rewrite rules at runtime (scary, but possible).

D.1.2 Global Variables

V8.8 sendmail uses more than 100 variables. They are all listed in sendmail.h and conf.c with "lite" comments. Global variables store information such as sendmail's option values, file descriptor values, macro values, class lists, and database access information. Any can be modified inside checkcompat, but before attempting to do so, study the sendmail C source code to anticipate any unexpected side effects.

In general you can use almost any of the global variables when designing your own checkcompat( ) routine. The four most interesting are:

RealHostAddr

The IP address of the sending host. This is a union of several sockaddr_ types depending on your selection of protocol types. This can be zero for locally submitted mail.

RealHostName

A string containing the definitive canonical name of the sending host. If it can't be resolved to a name, it will contain the host's IP number in text form, surrounded by square brackets.

LogLevel

This variable determines the amount of logging that sendmail does, and is set using the LogLevel option (LogLevel). You can use this LogLevel variable to decide how much, if anything, you wish to log about what you are doing inside the checkcompat( ) function.

CurrentLA

An integer representation of the current load average. You might want to use checkcompat( ) to defer mail between selected senders and recipients when the load is very high.

Verbose

An integer that, if it is nonzero, means that you can allow checkcompat( ) to show (print to the standard output) what it is doing.

    Previous Section Next Section