+this is a timestamp
+(trace)
+field.
+If the number of trace fields in a message
+exceeds a preset amount
+the message is returned
+on the assumption that it has an aliasing loop.
+.ip H_RCPT
+If set,
+this field contains recipient addresses.
+This is used by the
+.b \-t
+flag to determine who to send to
+when it is collecting recipients from the message.
+.ip H_FROM
+This flag indicates that this field
+specifies a sender.
+The order of these fields in the
+.i HdrInfo
+table specifies
+.i sendmail's
+preference
+for which field to return error messages to.
+.nr ii 5n
+.lp
+Let's look at a sample
+.i HdrInfo
+specification:
+.(b
+.ta 4n +\w'"return-receipt-to", 'u
+struct hdrinfo HdrInfo[] =
+\&{
+ /* originator fields, most to least significant */
+ "resent-sender", H_FROM,
+ "resent-from", H_FROM,
+ "sender", H_FROM,
+ "from", H_FROM,
+ "full-name", H_ACHECK,
+ /* destination fields */
+ "to", H_RCPT,
+ "resent-to", H_RCPT,
+ "cc", H_RCPT,
+ /* message identification and control */
+ "message", H_EOH,
+ "text", H_EOH,
+ /* trace fields */
+ "received", H_TRACE|H_FORCE,
+
+ NULL, 0,
+};
+.)b
+This structure indicates that the
+.q To: ,
+.q Resent-To: ,
+and
+.q Cc:
+fields
+all specify recipient addresses.
+Any
+.q Full-Name:
+field will be deleted unless the required mailer flag
+(indicated in the configuration file)
+is specified.
+The
+.q Message:
+and
+.q Text:
+fields will terminate the header;
+these are used by random dissenters around the network world.
+The
+.q Received:
+field will always be added,
+and can be used to trace messages.
+.pp
+There are a number of important points here.
+First,
+header fields are not added automatically just because they are in the
+.i HdrInfo
+structure;
+they must be specified in the configuration file
+in order to be added to the message.
+Any header fields mentioned in the configuration file but not
+mentioned in the
+.i HdrInfo
+structure have default processing performed;
+that is,
+they are added unless they were in the message already.
+Second,
+the
+.i HdrInfo
+structure only specifies cliched processing;
+certain headers are processed specially by ad hoc code
+regardless of the status specified in
+.i HdrInfo .
+For example,
+the
+.q Sender:
+and
+.q From:
+fields are always scanned on ARPANET mail
+to determine the sender\**;
+.(f
+\**Actually, this is no longer true in SMTP;
+this information is contained in the envelope.
+The older ARPANET protocols did not completely distinguish
+envelope from header.
+.)f
+this is used to perform the
+.q "return to sender"
+function.
+The
+.q "From:"
+and
+.q "Full-Name:"
+fields are used to determine the full name of the sender
+if possible;
+this is stored in the macro
+.b $x
+and used in a number of ways.
+.sh 3 "SMTP Reply Codes"
+.pp
+The file
+.i conf.c
+also contains the specification of Internet reply codes\**.
+.(f
+\**Called Arpanet in the source code
+for historic reasons.
+.)f
+There are four classifications these fall into:
+.(b
+.sz -1
+.ta \w'char 'u +\w'Arpa_TUsrerr[] = 'u +\w'"888"; 'u
+char Arpa_Info[] = "050"; /* arbitrary info */
+char Arpa_TSyserr[] = "455"; /* some (transient) system error */
+char Arpa_PSyserr[] = "554"; /* some (permanent) system error */
+char Arpa_Usrerr[] = "554"; /* some (fatal) user error */
+.sz
+.)b
+The class
+.i Arpa_Info
+is for any information that is not required by the protocol,
+such as forwarding information.
+.i Arpa_TSyserr
+and
+.i Arpa_PSyserr
+is printed by the
+.i syserr
+routine.
+TSyserr
+is printed out for transient errors,
+that is,
+errors that are likely to go away without explicit action
+on the part of a systems administrator.
+PSyserr
+is printed for permanent errors.
+The distinction is made based on the value of
+.i errno .
+Finally,
+.i Arpa_Usrerr
+is the result of a user error
+and is generated by the
+.i usrerr
+routine;
+these are generated when the user has specified something wrong,
+and hence the error is permanent,
+i.e.,
+it will not work simply by resubmitting the request.
+.sh 3 "Restricting Use of Email"
+.pp
+If it is necessary to restrict mail through a relay,
+the
+.i checkcompat
+routine can be modified.
+This routine is called for every recipient address.
+It returns an exit status
+indicating the status of the message.
+The status
+.sm EX_OK
+accepts the address,
+.sm EX_TEMPFAIL
+queues the message for a later try,
+and other values
+(commonly
+.sm EX_UNAVAILABLE )
+reject the message.
+It is up to
+.i checkcompat
+to print an error message
+(using
+.i usrerr )
+if the message is rejected.
+For example,
+.i checkcompat
+could read:
+.(b
+.re
+.sz -1
+.ta 4n +4n +4n +4n +4n +4n +4n
+int
+checkcompat(to, e)
+ register ADDRESS *to;
+ register ENVELOPE *e;
+\&{
+ register STAB *s;
+
+ s = stab("private", ST_MAILER, ST_FIND);
+ if (s != NULL && e\->e_from.q_mailer != LocalMailer &&
+ to->q_mailer == s->s_mailer)
+ {
+ usrerr("No private net mail allowed through this machine");
+ return (EX_UNAVAILABLE);
+ }
+ if (MsgSize > 50000 && to\->q_mailer != LocalMailer)
+ {
+ usrerr("Message too large for non-local delivery");
+ NoReturn = TRUE;
+ return (EX_UNAVAILABLE);
+ }
+ return (EX_OK);
+}
+.sz
+.)b
+This would reject messages greater than 50000 bytes
+unless they were local.
+The
+.i NoReturn
+flag can be sent to suppress the return of the actual body
+of the message in the error return.
+The actual use of this routine is highly dependent on the
+implementation,
+and use should be limited.
+.sh 3 "Load Average Computation"
+.pp
+The routine
+.i getla
+should return an approximation of the current system load average
+as an integer.
+There are four versions included on compilation flags
+as described above.
+.sh 3 "New Database Map Classes"
+.pp
+New key maps can be added by creating a class initialization function
+and a lookup function.
+These are then added to the routine
+.i setupmaps.
+.pp
+The initialization function is called as
+.(b
+\fIxxx\fP_map_init(MAP *map, char *mapname, char *args)
+.)b
+The
+.i map
+is an internal data structure.
+The
+.i mapname
+is the name of the map (used for error messages).
+The
+.i args
+is a pointer to the rest of the configuration file line;
+flags and filenames can be extracted from this line.
+The initialization function must return
+.sm TRUE
+if it successfully opened the map,
+.sm FALSE
+otherwise.
+.pp
+The lookup function is called as
+.(b
+\fIxxx\fP_map_lookup(MAP *map, char buf[], int bufsize, char **av)
+.)b
+The
+.i map
+defines the map internally.
+The parameters
+.i buf
+and
+.i bufsize
+have the input key.
+This may be (and often is) used destructively.
+The
+.i av
+is a list of arguments passed in from the rewrite line.
+The lookup function should return a pointer to the new value.
+.sh 3 "Queueing Function"
+.pp
+The routine
+.i shouldqueue
+is called to decide if a message should be queued
+or processed immediately.
+Typically this compares the message priority to the current load average.
+The default definition is:
+.(b
+bool
+shouldqueue(pri, ctime)
+ long pri;
+ time_t ctime;
+{
+ if (CurrentLA < QueueLA)
+ return (FALSE);
+ if (CurrentLA >= RefuseLA)
+ return (TRUE);
+ return (pri > (QueueFactor / (CurrentLA \- QueueLA + 1)));
+}
+.)b
+If the current load average
+(global variable
+.i CurrentLA ,
+which is set before this function is called)
+is less than the low threshold load average
+(option
+.b x ,
+variable
+.i QueueLA ),
+.i shouldqueue
+returns
+.sm FALSE
+immediately
+(that is, it should
+.i not
+queue).
+If the current load average exceeds the high threshold load average
+(option
+.b X ,
+variable
+.i RefuseLA ),
+.i shouldqueue
+returns
+.sm TRUE
+immediately.
+Otherwise, it computes the function based on the message priority,
+the queue factor
+(option
+.b q ,
+global variable
+.i QueueFactor ),
+and the current and threshold load averages.
+.pp
+An implementation wishing to take the actual age of the message into account
+can also use the
+.i ctime
+parameter,
+which is the time that the message was first submitted to
+.i sendmail .
+Note that the
+.i pri
+parameter is already weighted
+by the number of times the message has been tried
+(although this tends to lower the priority of the message with time);
+the expectation is that the
+.i ctime
+would be used as an
+.q "escape clause"
+to ensure that messages are eventually processed.
+.sh 3 "Refusing Incoming SMTP Connections"
+.pp
+The function
+.i refuseconnections
+returns
+.sm TRUE
+if incoming SMTP connections should be refused.
+The current implementation is based exclusively on the current load average
+and the refuse load average option
+(option
+.b X ,
+global variable
+.i RefuseLA ):
+.(b
+bool
+refuseconnections()
+{
+ return (CurrentLA >= RefuseLA);
+}
+.)b
+A more clever implementation
+could look at more system resources.
+.sh 3 "Load Average Computation"
+.pp
+The routine
+.i getla
+returns the current load average (as a rounded integer).
+The distribution includes several possible implementations.
+.sh 2 "Configuration in src/daemon.c"
+.pp
+The file
+.i src/daemon.c
+contains a number of routines that are dependent
+on the local networking environment.
+The version supplied is specific to 4.3 BSD.
+.pp
+In previous releases,
+we recommended that you modify the routine
+.i maphostname
+if you wanted to generalize
+.b $[
+\&...\&
+.b $]
+lookups.
+We now recommend that you create a new keyed map instead.
+.sh 1 "CHANGES IN RELEASE 6"
+.pp
+The following summarizes changes
+since the last commonly available version of