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