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