Sendmail 8.1c -> 8.3 (From NetBSD with hacked Makefiles)
[unix-history] / usr.sbin / sendmail / cf / m4 / proto.m4
CommitLineData
6f14531a
RG
1divert(-1)
2#
3# Copyright (c) 1983 Eric P. Allman
4# Copyright (c) 1988, 1993
5# The Regents of the University of California. All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# 3. All advertising materials mentioning features or use of this software
16# must display the following acknowledgement:
17# This product includes software developed by the University of
18# California, Berkeley and its contributors.
19# 4. Neither the name of the University nor the names of its contributors
20# may be used to endorse or promote products derived from this software
21# without specific prior written permission.
22#
23# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33# SUCH DAMAGE.
34#
35divert(0)
36
3a363396 37VERSIONID(`@(#)proto.m4 8.2 (Berkeley) 7/11/93')
6f14531a
RG
38
39MAILER(local)dnl
40
41ifdef(`_OLD_SENDMAIL_',
42`define(`_SET_96_', 6)dnl
43define(`_SET_97_', 7)dnl',
44`# level 4 config file format
45V4
46define(`_SET_96_', 96)dnl
47define(`_SET_97_', 97)dnl')
48
49##################
50# local info #
51##################
52
53CP.
54
55Cwlocalhost
56ifdef(`USE_CW_FILE',
57`# file containing names of hosts for which we receive email
58CONCAT(`Fw', confCW_FILE)', `dnl')
59
60ifdef(`UUCP_RELAY',
61`# UUCP relay host
62CONCAT(DY, UUCP_RELAY)
63CPUUCP
64
65')dnl
66ifdef(`BITNET_RELAY',
67`# BITNET relay host
68CONCAT(DB, BITNET_RELAY)
69CPBITNET
70
71')dnl
72ifdef(`CSNET_RELAY',
73`# CSNET relay host
74CONCAT(DC, CSNET_RELAY)
75CPCSNET
76
77')dnl
78ifdef(`FAX_RELAY',
79`# FAX relay host
80CONCAT(DF, FAX_RELAY)
81CPFAX
82
83')dnl
84ifdef(`SMART_HOST',
85`# "Smart" UUCP relay host
86CONCAT(DS, SMART_HOST)
87
88')dnl
89ifdef(`MAILER_TABLE',
90`# Mailer table (overriding domains)
91Kmailertable MAILER_TABLE
92
3a363396
NW
93')dnl
94ifdef(`DOMAIN_TABLE',
95`# Domain table (adding domains)
96Kdomaintable DOMAIN_TABLE
97
6f14531a
RG
98')dnl
99# who I send unqualified names to (null means deliver locally)
100CONCAT(DR, ifdef(`LOCAL_RELAY', LOCAL_RELAY))
101
102# who gets all local email traffic ($R has precedence for unqualified names)
103CONCAT(DH, ifdef(`MAIL_HUB', MAIL_HUB))
104
105# my official hostname ($w or $w.$D)
106CONCAT(Dj$w, ifdef(`NEED_DOMAIN', .$D))
107
108# who I masquerade as (can be $j)
109CONCAT(DM, ifdef(`MASQUERADE_NAME', MASQUERADE_NAME, $j))
110
111# class L: names that should be delivered locally, even if we have a relay
112# class E: names that should be exposed as from this host, even if we masquerade
113CLroot
114CEroot
115undivert(5)dnl
116
117# operators that cannot be in local usernames (i.e., network indicators)
118CO @ % ifdef(`_NO_UUCP_', `', `!')
119
120# a class with just dot (for identifying canonical names)
121C..
122
123ifdef(`_OLD_SENDMAIL_', `dnl',
124`# dequoting map
125Kdequote dequote')
126
127undivert(6)dnl
128
129######################
130# Special macros #
131######################
132
133# SMTP initial login message
134CONCAT(De, confSMTP_LOGIN_MSG)
135
136# UNIX initial From header format
137CONCAT(Dl, confFROM_LINE)
138
139# my name for error messages
140CONCAT(Dn, confMAILER_NAME)
141
142# delimiter (operator) characters
143CONCAT(Do, confOPERATORS)
144
145# format of a total name
146CONCAT(Dq, ifdef(`confFROM_HEADER', confFROM_HEADER,
147 ifdef(`_OLD_SENDMAIL_', `$g$?x ($x)$.', `$?x$x <$g>$|$g$.')))
148include(`../m4/version.m4')
149
150###############
151# Options #
152###############
153
154# strip message body to 7 bits on input?
155CONCAT(O7, confSEVEN_BIT_INPUT)
156
157# wait (in minutes) for alias file rebuild
158CONCAT(Oa, confALIAS_WAIT)
159
160# location of alias file
161CONCAT(OA, ifdef(`ALIAS_FILE', ALIAS_FILE, /etc/aliases))
162
163# minimum number of free blocks on filesystem
164CONCAT(Ob, confMIN_FREE_BLOCKS)
165
166# substitution for space (blank) characters
167CONCAT(OB, confBLANK_SUB)
168
169# connect to "expensive" mailers on initial submission?
170CONCAT(Oc, confCON_EXPENSIVE)
171
172# checkpoint queue runs after every N successful deliveries
173CONCAT(OC, confCHECKPOINT_INTERVAL)
174
175# default delivery mode
176CONCAT(Od, confDELIVERY_MODE)
177
178# automatically rebuild the alias database?
179CONCAT(OD, confAUTO_REBUILD)
180
181# error message header/file */
182ifdef(`confERROR_MESSAGE',
183 CONCAT(OE, confERROR_MESSAGE),
184 #OE/etc/sendmail.oE)
185
186# error mode
187ifdef(`confERROR_MODE',
188 CONCAT(Oe, confERROR_MODE),
189 #Oep)
190
191# save Unix-style "From_" lines at top of header?
192CONCAT(Of, confSAVE_FROM_LINES)
193
194# temporary file mode
195CONCAT(OF, confTEMP_FILE_MODE)
196
197# match recipients against GECOS field?
198CONCAT(OG, confMATCH_GECOS)
199
200# default GID
201CONCAT(Og, confDEF_GROUP_ID)
202
203# maximum hop count
204CONCAT(Oh, confMAX_HOP)
205
206# location of help file
207CONCAT(OH, ifdef(`HELP_FILE', HELP_FILE, /usr/lib/sendmail.hf))
208
209# ignore dots as terminators in incoming messages?
210CONCAT(Oi, confIGNORE_DOTS)
211
212# Insist that the BIND name server be running to resolve names
213ifdef(`confBIND_OPTS',
214 CONCAT(OI, confBIND_OPTS),
215 #OI)
216
217# deliver MIME-encapsulated error messages?
218CONCAT(Oj, confMIME_FORMAT_ERRORS)
219
220# Forward file search path
221ifdef(`confFORWARD_PATH',
222 CONCAT(OJ, confFORWARD_PATH),
223 #OJ/var/forward/$u:$z/.forward.$w:$z/.forward)
224
225# open connection cache size
226CONCAT(Ok, confMCI_CACHE_SIZE)
227
228# open connection cache timeout
229CONCAT(OK, confMCI_CACHE_TIMEOUT)
230
231# use Errors-To: header?
232CONCAT(Ol, confUSE_ERRORS_TO)
233
234# log level
235CONCAT(OL, confLOG_LEVEL)
236
237# send to me too, even in an alias expansion?
238CONCAT(Om, confME_TOO)
239
240# verify RHS in newaliases?
241CONCAT(On, confCHECK_ALIASES)
242
243# default messages to old style headers if no special punctuation?
244CONCAT(Oo, confOLD_STYLE_HEADERS)
245
246# SMTP daemon options
247ifdef(`confDAEMON_OPTIONS',
248 CONCAT(OO, confDAEMON_OPTIONS),
249 #OOPort=esmtp)
250
251# privacy flags
252CONCAT(Op, confPRIVACY_FLAGS)
253
254# who (if anyone) should get extra copies of error messages
255ifdef(`confCOPY_ERRORS_TO',
256 CONCAT(OP, confCOPY_ERRORS_TO),
257 #OPPostmaster)
258
259# slope of queue-only function
260ifdef(`confQUEUE_FACTOR',
261 CONCAT(Oq, confQUEUE_FACTOR),
262 #Oq600000)
263
264# queue directory
265CONCAT(OQ, ifdef(`QUEUE_DIR', QUEUE_DIR, /var/spool/mqueue))
266
267# read timeout -- now OK per RFC 1123 section 5.3.2
268ifdef(`confREAD_TIMEOUT',
269 CONCAT(Or, confREAD_TIMEOUT),
270 #Ordatablock=10m)
271
272# queue up everything before forking?
273CONCAT(Os, confSAFE_QUEUE)
274
275# status file
276CONCAT(OS, ifdef(`STATUS_FILE', STATUS_FILE, /etc/sendmail.st))
277
278# default message timeout interval
279CONCAT(OT, confMESSAGE_TIMEOUT)
280
281# time zone handling:
282# if undefined, use system default
283# if defined but null, use TZ envariable passed in
284# if defined and non-null, use that info
285ifelse(confTIME_ZONE, `USE_SYSTEM', `#Ot',
286 confTIME_ZONE, `USE_TZ', `',
287 `CONCAT(Ot, confTIME_ZONE)')
288
289# default UID
290CONCAT(Ou, confDEF_USER_ID)
291
292# list of locations of user database file (null means no lookup)
293OU`'ifdef(`confUSERDB_SPEC', `confUSERDB_SPEC')
294
295# fallback MX host
296ifdef(`confFALLBACK_MX',
297 CONCAT(OV, confFALLBACK_MX),
298 #OVfall.back.host.net)
299
300# load average at which we just queue messages
301CONCAT(Ox, confQUEUE_LA)
302
303# load average at which we refuse connections
304CONCAT(OX, confREFUSE_LA)
305
306# work recipient factor
307ifdef(`confWORK_RECIPIENT_FACTOR',
308 CONCAT(Oy, confWORK_RECIPIENT_FACTOR),
309 #Oy30000)
310
311# deliver each queued job in a separate process?
312CONCAT(OY, confSEPARATE_PROC)
313
314# work class factor
315ifdef(`confWORK_CLASS_FACTOR',
316 CONCAT(Oz, confWORK_CLASS_FACTOR),
317 #Oz1800)
318
319# work time factor
320ifdef(`confWORK_TIME_FACTOR',
321 CONCAT(OZ, confWORK_TIME_FACTOR),
322 #OZ90000)
323
324###########################
325# Message precedences #
326###########################
327
328Pfirst-class=0
329Pspecial-delivery=100
330Plist=-30
331Pbulk=-60
332Pjunk=-100
333
334#####################
335# Trusted users #
336#####################
337
338Troot
339Tdaemon
340Tuucp
341
342#########################
343# Format of headers #
344#########################
345
346H?P?Return-Path: $g
347HReceived: $?sfrom $s $.$?_($_) $.by $j ($v/$Z)$?r with $r$. id $i; $b
348H?D?Resent-Date: $a
349H?D?Date: $a
350H?F?Resent-From: $q
351H?F?From: $q
352H?x?Full-Name: $x
353HSubject:
354# HPosted-Date: $a
355# H?l?Received-Date: $b
356H?M?Resent-Message-Id: <$t.$i@$j>
357H?M?Message-Id: <$t.$i@$j>
358#\f
359######################################################################
360######################################################################
361#####
362##### REWRITING RULES
363#####
364######################################################################
365######################################################################
366
367undivert(9)dnl
368
369###########################################
370### Rulset 3 -- Name Canonicalization ###
371###########################################
372S3
373
374# handle null input and list syntax (translate to <@> special case)
375R$@ $@ <@>
376R$*:;$* $@ $1 :; <@>
377
378# basic textual canonicalization -- note RFC733 heuristic here
379R$*<$*>$*<$*>$* <$2>$3$4$5 strip multiple <> <>
380R$*<$*<$+>$*>$* <$3>$5 2-level <> nesting
381R$*<>$* $@ <@> MAIL FROM:<> case
382R$*<$+>$* $2 basic RFC821/822 parsing
383
384# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
385R@ $+ , $+ @ $1 : $2 change all "," to ":"
386
387# localize and dispose of route-based addresses
388R@ $+ : $+ $@ $>_SET_96_ < @$1 > : $2 handle <route-addr>
389
390# find focus for list syntax
391R $+ : $* ; @ $+ $@ $>_SET_96_ $1 : $2 ; < @ $3 > list syntax
392R $+ : $* ; $@ $1 : $2; list syntax
393
394# find focus for @ syntax addresses
395R$+ @ $+ $: $1 < @ $2 > focus on domain
396R$+ < $+ @ $+ > $1 $2 < @ $3 > move gaze right
397R$+ < @ $+ > $@ $>_SET_96_ $1 < @ $2 > already canonical
398
399ifdef(`_NO_UUCP_', `dnl',
400`# convert old-style addresses to a domain-based address
401R$- ! $+ $@ $>_SET_96_ $2 < @ $1 .UUCP > resolve uucp names
402R$+ . $- ! $+ $@ $>_SET_96_ $3 < @ $1 . $2 > domain uucps
403R$+ ! $+ $@ $>_SET_96_ $2 < @ $1 .UUCP > uucp subdomains')
404
405# if we have % signs, take the rightmost one
406R$* % $* $1 @ $2 First make them all @s.
407R$* @ $* @ $* $1 % $2 @ $3 Undo all but the last.
408R$* @ $* $@ $>_SET_96_ $1 < @ $2 > Insert < > and finish
409
410# else we must be a local name
411
412
413################################################
414### Ruleset _SET_96_ -- bottom half of ruleset 3 ###
415################################################
416
417# At this point, everything should be in a "local_part<@domain>extra" format.
418S`'_SET_96_
419
420# handle special cases for local names
421R$* < @ localhost > $* $: $1 < @ $j . > $2 no domain at all
422R$* < @ localhost . $m > $* $: $1 < @ $j . > $2 local domain
423ifdef(`_NO_UUCP_', `dnl',
424`R$* < @ localhost . UUCP > $* $: $1 < @ $j . > $2 .UUCP domain')
3a363396
NW
425ifdef(`DOMAIN_TABLE', `
426# look up unqualified domains in the domain table
427R$* < @ $- > $* $: $1 < @ $(domaintable $2 $) > $3',
428`dnl')
6f14531a
RG
429undivert(2)dnl
430
431ifdef(`_NO_UUCP_', `dnl',
432`ifdef(`UUCP_RELAY',
433`# pass UUCP addresses straight through
434R$* < @ $+ . UUCP > $* $@ $1 < @ $2 . UUCP > $3',
435`# if really UUCP, handle it immediately
436ifdef(`_CLASS_U_',
437`R$* < @ $=U . UUCP > $* $@ $1 < @ $2 . UUCP > $3', `dnl')
438ifdef(`_CLASS_V_',
439`R$* < @ $=V . UUCP > $* $@ $1 < @ $2 . UUCP > $3', `dnl')
440ifdef(`_CLASS_W_',
441`R$* < @ $=W . UUCP > $* $@ $1 < @ $2 . UUCP > $3', `dnl')
442ifdef(`_CLASS_X_',
443`R$* < @ $=X . UUCP > $* $@ $1 < @ $2 . UUCP > $3', `dnl')
444ifdef(`_CLASS_Y_',
445`R$* < @ $=Y . UUCP > $* $@ $1 < @ $2 . UUCP > $3', `dnl')
446
447# try UUCP traffic as a local address
448R$* < @ $+ . UUCP > $* $: $1 < @ $[ $2 $] . UUCP > $3
449ifdef(`_OLD_SENDMAIL_',
450`R$* < @ $+ . $+ . UUCP > $* $@ $1 < @ $2 . $3 . > $4',
451`R$* < @ $+ . . UUCP > $* $@ $1 < @ $2 . > $3')')
452')
453ifdef(`_NO_CANONIFY_',
454`# make sure local host names appear canonical
455R$* < @ $=w > $* $: $1 < @ $2 . > $3',
456`# pass to name server to make hostname canonical
457R$* < @ $* $~P > $* $: $1 < @ $[ $2 $3 $] > $4')
458
459undivert(8)dnl
460
461# if this is the local hostname, make sure we treat is as canonical
462R$* < @ $j > $* $: $1 < @ $j . > $2
463
464
465##################################################
466### Ruleset 4 -- Final Output Post-rewriting ###
467##################################################
468S4
469
470R$*<@> $@ $1 handle <> and list:;
471
472# resolve numeric addresses to name if possible
473R$* < @ [ $+ ] > $* $: $1 < @ $[ [$2] $] > $3 lookup numeric internet addr
474
475# strip trailing dot off possibly canonical name
476R$* < @ $+ . > $* $1 < @ $2 > $3
477
478# externalize local domain info
479R$* < $+ > $* $1 $2 $3 defocus
480R@ $+ : @ $+ : $+ @ $1 , @ $2 : $3 <route-addr> canonical
481R@ $* $@ @ $1 ... and exit
482
483ifdef(`_NO_UUCP_', `dnl',
484`# UUCP must always be presented in old form
485R$+ @ $- . UUCP $2!$1 u@h.UUCP => h!u')
486
487# delete duplicate local names
488R$+ % $=w @ $=w $1 @ $j u%host@host => u@host
489
490
491
492##############################################################
493### Ruleset _SET_97_ -- recanonicalize and call ruleset zero ###
494### (used for recursive calls) ###
495##############################################################
496
497S`'_SET_97_
498R$* $: $>3 $1
499R$* $@ $>0 $1
500
501
502######################################
503### Ruleset 0 -- Parse Address ###
504######################################
505
506S0
507
508R<@> $#local $: <> special case error msgs
509R$*:;<@> $#error $@ USAGE $: "list:; syntax illegal for recipient addresses"
510
511ifdef(`_MAILER_smtp_',
512`# handle numeric address spec
513R$* < @ [ $+ ] > $* $: $1 < @ $[ [$2] $] > $3 numeric internet addr
514R$* < @ [ $+ ] > $* $#smtp $@ [$2] $: $1 @ [$2] $3 numeric internet spec',
515`dnl')
516
517# now delete the local info -- note $=O to find characters that cause forwarding
518R$* < @ > $* $@ $>_SET_97_ $1 user@ => user
519R< @ $=w . > : $* $@ $>_SET_97_ $2 @here:... -> ...
520R$* $=O $* < @ $=w . > $@ $>_SET_97_ $1 $2 $3 ...@here -> ...
521ifdef(`MAILER_TABLE',
522`
523# try mailer table lookup
524R$* <@ $+ > $* $: < $2 > $1 < @ $2 > $3 extract host name
525R< $+ . > $* $: < $1 > $2 strip trailing dot
526R< $+ > $* $: < $(mailertable $1 $) > $2 lookup
527R< $- : $+ > $* $# $1 $@ $2 $: $3 check -- resolved?
528R< $+ > $* $: $>90 <$1> $2 try domain',
529`dnl')
530
531# short circuit local delivery so forwarded email works
532ifdef(`_LOCAL_NOT_STICKY_',
533`R$=L < @ $=w . > $#local $: @ $1 special local names
534R$+ < @ $=w . > $#local $: $1 dispose directly',
535`R$+ < @ $=w . > $: $1 < @ $2 @ $H > first try hub
536ifdef(`_OLD_SENDMAIL_',
537`R$+ < $+ @ $-:$+ > $# $3 $@ $4 $: $1 < $2 > yep ....
538R$+ < $+ @ $+ > $#relay $@ $3 $: $1 < $2 > yep ....
539R$+ < $+ @ > $#local $: $1 nope, local address',
540`R$+ < $+ @ $+ > $#local $: $1 yep ....
541R$+ < $+ @ > $#local $: @ $1 nope, local address')')
542undivert(3)dnl
543undivert(4)dnl
544
545ifdef(`_NO_UUCP_', `dnl',
546`# resolve remotely connected UUCP links (if any)
547ifdef(`_CLASS_V_',
548`R$* < @ $=V . UUCP > $* $#smtp $@ $V $: <@ $V> : $1 @ $2.UUCP $3',
549 `dnl')
550ifdef(`_CLASS_W_',
551`R$* < @ $=W . UUCP > $* $#smtp $@ $W $: <@ $W> : $1 @ $2.UUCP $3',
552 `dnl')
553ifdef(`_CLASS_X_',
554`R$* < @ $=X . UUCP > $* $#smtp $@ $X $: <@ $X> : $1 @ $2.UUCP $3',
555 `dnl')')
556
557# resolve fake top level domains by forwarding to other hosts
558ifdef(`BITNET_RELAY',
559`R$*<@$+.BITNET>$* $#smtp $@ $B $: $1 <@$2.BITNET> $3 user@host.BITNET',
560 `dnl')
561ifdef(`CSNET_RELAY',
562`R$*<@$+.CSNET>$* $#smtp $@ $C $: $1 <@$2.CSNET> $3 user@host.CSNET',
563 `dnl')
564ifdef(`_MAILER_fax_',
565`R$+ < @ $+ .FAX > $#fax $@ $2 $: $1 user@host.FAX',
566`ifdef(`FAX_RELAY',
567`R$*<@$+.FAX>$* $#smtp $@ $F $: $1 <@$2.FAX> $3 user@host.FAX',
568 `dnl')')
569
570ifdef(`UUCP_RELAY',
571`# forward non-local UUCP traffic to our UUCP relay
572R$*<@$*.UUCP>$* $#smtp $@ $Y $: <@ $Y> : $1 @ $2.UUCP $3 uucp mail',
573`ifdef(`_MAILER_uucp_',
574`# forward other UUCP traffic straight to UUCP
575R< @ $+ .UUCP > : $+ $#uucp $@ $1 $: $2 @host.UUCP:...
576R$+ < @ $+ .UUCP > $#uucp $@ $2 $: $1 user@host.UUCP',
577 `dnl')')
578
3a363396
NW
579ifdef(`_MAILER_USENET_', `
580# addresses sent to net.group.USENET will get forwarded to a newsgroup
581R$+ . USENET $# usenet $: $1',
582`dnl')
583
6f14531a
RG
584ifdef(`_LOCAL_RULES_',
585`# figure out what should stay in our local mail system
3a363396
NW
586undivert(1)', `dnl')
587
6f14531a
RG
588ifdef(`SMART_HOST', `
589# pass names that still have a host to a smarthost
590R$* < @ $* > $* $: < $S > $1 < @ $2 > $3 glue on smarthost name
591R<$-:$+> $* < @$* > $* $# $1 $@ $2 $: $3 < @ $4 > $5 if non-null, use it
592R<$+> $* < @$* > $* $#suucp $@ $1 $: $2 < @ $3 > $4 if non-null, use it
593R<> $* < @ $* > $* $1 < @ $2 > $3 else strip off gunk',
3a363396 594
6f14531a
RG
595`ifdef(`_LOCAL_RULES_', `
596# reject messages that have host names we do not understand
597R$* < @ $* > $* $#error $@ NOHOST $: Unrecognized host name $2',
3a363396
NW
598`ifdef(`_MAILER_smtp_',
599`# deal with other remote names
600R$* < @ $* > $* $#smtp $@ $2 $: $1 < @ $2 > $3 user@host.domain')')')
6f14531a
RG
601
602ifdef(`_OLD_SENDMAIL_',
603`# forward remaining names to local relay, if any
604R$=L $#local $: $1 special local names
605R$+ $: $1 < @ $R > append relay
606R$+ < @ > $: $1 < @ $H > no relay, try hub
607R$+ < @ > $#local $: $1 no relay or hub: local
608R$+ < @ $=w > $#local $: $1 we are relay/hub: local
609R$+ < @ $-:$+ > $# $2 $@ $3 $: $1 deliver to relay/hub
610R$+ < @ $+ > $#relay $@ $2 $: $1 deliver to relay/hub',
611
612`# if this is quoted, strip the quotes and try again
613R$+ $: $(dequote $1 $) strip quotes
614R$* $=O $* $@ $>_SET_97_ $1 $2 $3 try again
615
616# handle locally delivered names
617R$=L $#local $: @ $1 special local names
618R$+ $#local $: $1 regular local names
619
620###########################################################################
621### Ruleset 5 -- special rewriting after aliases have been expanded ###
622### (new sendmail only) ###
623###########################################################################
624
625S5
626
627# see if we have a relay or a hub
628R$+ $: $1 < @ $R >
629R$+ < @ > $: $1 < @ $H > no relay, try hub
630R$+ < @ $=w > $@ $1 we are relay/hub: local
631R$+ < @ $-:$+ > $# $2 $@ $3 $: $1 send to relay or hub
632ifdef(`_MAILER_smtp_',
633`R$+ < @ $+ > $#relay $@ $2 $: $1 send to relay or hub')')
634ifdef(`MAILER_TABLE',
635`
636
637###########################################################################
638### Ruleset 90 -- try domain part of mailertable entry ###
639### (new sendmail only) ###
640###########################################################################
641
642S90
643R<$- . $+ > $* $: < $(mailertable .$2 $) > $3 lookup
644R<$- : $+ > $* $# $1 $@ $2 $: $3 check -- resolved?
645R< . $+ > $* $@ $>90 <$1> $2 no -- strip & try again
646R<$*> $* $@ $2 no match',
647`dnl')
648#\f
649######################################################################
650######################################################################
651#####
652`##### MAILER DEFINITIONS'
653#####
654######################################################################
655######################################################################
656undivert(7)dnl