Path: seismo!harvard!talcott!panda!Jim Crammond From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: Sendmail UK-1.4 part 3 of 5 Message-ID: <1639@panda.UUCP> Date: 10 Apr 86 23:05:18 GMT Sender: jpn@panda.UUCP Lines: 785 Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 58 Submitted by: Jim Crammond # This is a shell archive. # Remove everything above and including the cut line. # Then run the rest of the file through sh. -----cut here-----cut here-----cut here-----cut here----- #!/bin/sh # shar: Shell Archiver # Run the following text with /bin/sh to create: # chn # This archive created: Mon Mar 17 16:56:47 1986 echo shar: creating directory chn mkdir chn cd chn echo shar: extracting MAKE '(8731 characters)' cat << \SHAR_EOF > MAKE #!/bin/sh # # shell script to generate a sendmail .chn file containing all # the routing information for this host from a set of per-mailer channel # files containing in this directory. # if [ $# -le 1 ] then echo usage: make host files... exit fi strip="sed -e /^#/d -e /^\$/d" host=$1 shift rm -f $host.chn cp /dev/null chn.classes cp /dev/null S15 cp /dev/null S16 cp /dev/null S17 # # sort out which files refer to which mailers # rm -f $$.local $$.ether $$.luucp $$.csnet $$.janet $$.bitnet $$.uucp $$.top for i in $* do case $i in *local.chn) $strip $i >> $$.local ;; *ether.chn) $strip $i >> $$.ether ;; *luucp.chn) $strip $i >> $$.luucp ;; *csnet.chn) $strip $i >> $$.csnet ;; *janet.chn) $strip $i >> $$.janet ;; *bitnet.chn) $strip $i >> $$.bitnet ;; *uucp.chn) $strip $i >> $$.uucp ;; *top.chn) $strip $i >> $$.top ;; esac done # # # if [ -f $$.local ] then awk '{ printf "R$+@%s\t\t$@$>15$1@$J\n", $1 }' $$.local > S15 fi # # Standard format channel tables # for chnf in $$.ether $$.luucp $$.csnet do if [ -f $chnf ] then awk ' BEGIN { mailer=substr(FILENAME, index(FILENAME,".")+1) MINCLSIZE = 3 if (mailer == "ether") { print "# Ethernet" >>"S17" classes = "KLM" } else if (mailer == "luucp") { print "# Local UUCP" >>"S17" classes = "NOP" } else if (mailer == "csnet") { print "# CSNet" >>"S17" classes = "QRS" } c = 1 } /^#/ { break } { i = index($1, ".") subdom = substr($1,1,i-1) restdom = substr($1,i+1) if (subdom == $2) direct[restdom] = direct[restdom] " " subdom else printf "R$+@%s\t\t$@<$1@%s>%s.%s\n", $1, $1, $2, mailer >>"S17" } END { for (i in direct) { n = split(direct[i], sub, " ") if (n >= MINCLSIZE && c <= length(classes)) { C = substr(classes, c, 1) c++ printf "C%s%s\n", C , direct[i] >>"chn.classes" printf "R$+@$=%s.%s\t\t$@<$1@$2.%s>$2.%s\n",C,i,i,mailer >>"S17" } else { for (j=1; j<=n; j++) printf "R$+@%s.%s\t\t$@<$1@%s.%s>%s.%s\n", \ sub[j], i, sub[j], i, sub[j], mailer >>"S17" } } print "" >>"chn.classes" print "" >>"S17" } ' $chnf fi done # # The Janet channel # if [ -f $$.janet ] then awk ' BEGIN { print "# Janet sites" print "# convert domain order to NRS style" print "R$+@$+ $:$>9$1@$2" print "" } { if ( $1 == $2 ) { if ( $1 ~ /^uk\./ ) # general rule will catch this break printf "R$+@%s\t\t$@<$1@%s>%s.janet\n", $1, $1, $1 } else # application relays { jntaddr = "$1%" $1 for (i=NF; i>2; i--) jntaddr = jntaddr "%" $i jntaddr = jntaddr "@" $2 if ( $2 ~ /^uk\.ac\./ ) # uk.ac nodes printf "R$+@%s\t\t$@<%s>%s.janet\n", $1, jntaddr, substr($2,7) else # all others printf "R$+@%s\t\t$@<%s>%s.janet\n", $1, jntaddr, $2 } } END { print "" print "# convert domain order back to 822 style" print "R$+@$+ $:$>9$1@$2" print "" } ' $$.janet >>S17 fi # # The Bitnet channel # if [ -f $$.bitnet ] then awk ' BEGIN { print "# Bitnet sites" } { if ($1 == $2 ".bitnet") # general rule will catch this break printf "R$+@%s\t\t$@<$1>%s.bitnet\n", $1, $2 } END { print "" } ' $$.bitnet >>S17 fi # # The UUCP channel # if [ -f $$.uucp ] then (sort +1 $$.uucp ; echo 'x.y z!x!%s') | awk ' BEGIN { MINCLSIZE = 3 classes = "UVWXYZ" c = 1 m = 0 print "# UUCP sites" >>"S17" print "# convert to uucp addresses and try to find a match" >>"S17" print "R$+@$+ $:$>8$1@$2" >>"S17" print "" >>"S17" } { i = index($1, ".") subdom = substr($1,1,i-1) restdom = substr($1,i+1) p = index($2, subdom) ps = subdom "!%s" if (p == 1 && $2 == ps) direct[restdom] = direct[restdom] " " subdom else if (p > 1 && substr($2, p-1) == ("!" ps)) { path = substr($2, 1, p-1) if (path != lastpath || restdom != lastrest) { if (m >= MINCLSIZE && c <= length(classes)) { j = index(lastpath, "!") host = substr(lastpath,1,j-1) addr = substr(lastpath,j+1) rclass = "" for (j=1; j<=m; j++) rclass = rclass " " sub[j] C = substr(classes, c, 1) c++ printf "C%s%s\n", C, rclass >>"chn.classes" printf "R$=%s.%s!$+\t\t$@<%s$1!$2>%s.uucp\n", \ C, lastrest, addr, host >>"S17.2" } else { for (i=1; i<=m; i++) { j = index(lastpath, "!") host = substr(lastpath,1,j-1) addr = substr(lastpath,j+1) sub[i] printf "R%s.%s!$+\t\t$@<%s!$1>%s.uucp\n",\ sub[i], lastrest, addr, host >>"S17.2" } } lastpath = path lastrest = restdom m = 0 } sub[++m] = subdom } else { i = index($2, "!") host = substr($2,1,i-1) addr = substr($2,i+1) addr = sprintf(addr,"$1") printf "R%s!$+\t\t$@<%s>%s.uucp\n", $1, addr, host >>"S17.2" } } END { for (i in direct) { n = split(direct[i],sub," ") if (n >= MINCLSIZE && c <= length(classes)) { C = substr(classes, c, 1) c++ printf "C%s%s\n", C , direct[i] >>"chn.classes" printf "R$=%s.%s!$+\t\t$@<$2>$1.uucp\n", C, i >>"S17" } else { for (j=1; j<=n; j++) printf "R%s.%s!$+\t\t$@<$1>%s.uucp\n", \ sub[j], i, sub[j] >>"S17" } } print "" >>"chn.classes" print "" >>"S17.2" print "# no match in uucp - change back to domain style" >>"S17.2" print "R$+!$+ $:$>7$1!$2" >>"S17.2" print "" >>"S17.2" } ' cat S17.2 >> S17 rm -f S17.2 fi # # catch errors # cat >>S17 <<'EOF' # Catch unknown subdomains local domain names R$+@$J $@<$1@$J>error EOF if [ -f $$.local ] then awk '{ printf "R$+@%s\t\t$@<$1@$J>error\n", $1 }' $$.local >> S17 fi # # complete ruleset 17 # cat >>S17 <<'EOF' # no match, return "
" R$+ $@<$1> EOF # # Top Level Domain relaying # awk '{ printf "R<$+@%s>\t\t$@$>16$1@%s\n", $1, $2 }' $$.top > S16 # # The header # cat > $host.chn <> $host.chn # # the rules # cat - S15 >> $host.chn <<'EOF' ########################################### # Ruleset 15 -- local domain handling # ########################################### # # This rule strips the domain part from local addresses # and passes the local part back into ruleset 3 # S15 R$+@$J $>3$1 strip local domain EOF cat - S16 >> $host.chn <<'EOF' ############################# # Ruleset 16 -- routing # ############################# # # This rule trys to find an "
host.network" triple for a given # domain address. Given a domain address "u@a.b.c.d", it calls the # channel matcher with u@a.b.c.d, and if nothing matched, it calls # the channel matcher again, with "u%a.b.c.d@b.c.d" and "u%a.b.c.d@c.d". # If there's still no match, then the top level domain relaying is done # e.g. "u%a.b.c.d@d" -> "u%a.b.c.d@x.y.z" and the rule is retried. # S16 R$+@$+ $:$>17$1@$2 initial routing R<$+>$+ $@<$1>$2 success, return triple # initial match failed, retry with successively higher level domains R<$+@$+> $:<$1%$2@$2> u@a.b.c -> u%a.b.c@a.b.c R<$+@$-.$+> $>17$1@$3 retry routing R<$+>$+ $@<$1>$2 success, return triple ifdef(`JANETNAME',` # general rule for janet - pass all uk addresses to hhcp R<$+@uk> $:$>4$1.janet restore @ in address R$+@$+.janet $:$>9$1@janet.$2 convert to NRS order R$+@uk.ac.$+.janet $@<$1@uk.ac.$2>$2.janet uk.ac nodes R$+@$+.janet $@<$1@$2>$2.janet all others ') ifdef(`BITNETNAME',` # general rule for bitnet - pass all bitnet addresses to rscs R<$+@bitnet> $:$>4$1 restore address R$+@$+.bitnet $@<$1>$2.bitnet returns host.bitnet # arpa and uucp relays via Bitnet R<$+@arpa> $:$>4$1.arpa restore address R$+@$+.arpa $@<$1@$2>smtpuser@wiscvm.bsmtp R<$+@uucp> $:$>4$1.uucp restore address R$+@$+.uucp $@<$1@$2>uucp@psuvax1.bsmtp ') # # top level domain - relaying sites # # This is a list of default relaying sites for addresses # that dont match anything in the channel matcher. # EOF cat - S17 >> $host.chn <<'EOF' ###################################### # Ruleset 17 -- channel matching # ###################################### # # This rule takes a full domain address and trys to match it with a # domain given on the LHS of a rule. # If one matches, the "
host.network" triple given on the RHS # is returned. Else "
" is returned. # S17 EOF rm -f chn.classes S15 S16 S17 $$.* echo $host.chn made exit SHAR_EOF if test 8731 -ne "`wc -c MAKE`" then echo shar: error transmitting MAKE '(should have been 8731 characters)' else chmod a+x MAKE fi echo shar: extracting README '(5870 characters)' cat << \SHAR_EOF > README General ------- Having expanded addresses into fully qualified domain addresses, sendmail then selects the appropriate mailer and routing. The channel tables provide the information to associate a domain name with a mailer and transport address (or route). The channel tables contain rules (1 per line) containing two strings seperated by white space. In general, the string on the LHS is a fully qualified domain name and the string on the RHS is the route or "host to send to", e.g.: usc.ac.uk vax6 specifies that addresses of the form "user@usc.ac.uk" should be send to the host "vax1". The actual format of the channel tables depends on the mailer, (see below) which is determined by the file name containing the rules. For example, any file whose name ends with "janet.chn" is assumed to be a janet mailer channel table. The minimum information you need to specify depends on what mailers you have, but is essentially: a) the domain name(s) the local host is known by, b) the names of directly connected hosts, c) the list of top level domain relaying sites (see below). The maximum information you can specify is limited by practical considerations such as the number of rules sendmail can cope with before running very slowly. As a guide, if more than 100 rules are generated in the sendmail .chn file, you may need to cut down the number of entries in the channel tables. Careful use of top level domain relays will often help (particularly with uucp). For example, for uk sites, if ukc.ac.uk is specified as the uucp relay, then there is no need to specify any routes for uucp sites which has "ukc!" in the path. Ukc has an extensive nameserver to do further routing. Channel Table Formats --------------------- local.chn: This contains a list of (fully qualified) domain names which are to be treated as local mail. ether.chn, luucp.chn, csnet.chn: These have the format described above; a domain name on the LHS and a hostname to send/relay to on the RHS. janet.chn: The LHS domain name is in big-endian form in this table. The RHS contains domain name(s), also big-endian, which specify the route to reach the domain on the LHS. By default, all "uk" sites are assumed to be directly connected. Thus this table need only contain (a) directly connected non-"uk" sites, and (b) application relays. E.g. cern.cernvm cern.cernvm uk.ac.cam.phx uk.ac.cam.eng-icf The RHS may contain more than one domain: domain1 domainA domainB will send the mail to domainA, then to domainB and onto domain1. "uk.ac." domains on the RHS should have a corresponding entry in the x25/directory with the "uk.ac." part stripped; other domains on the RHS should have a matching entry in the directory. bitnet.chn: This has the same format as the ether, luucp and csnet channel tables. In addition, by default, all ".bitnet" domains are routed to "" (actual routing is done by RSCS). Further, all arpa addresses are sent to usersmtp@wiscvm and uucp addresses to uucp@psuvax1, using the bsmtp program. uucp.chn: This has a slightly different RHS syntax which the same as that produced by pathalias(1), e.g.: usc.ac.uk vax2!vax1!%s where %s is the user part of the address (converted to uucp form). top.chn: This has a top level domain name on the LHS and a domain name on the RHS, for example.: uk ukc.ac.uk which states that any address in the "uk" domain, which did not match a domain name in one of the mailer channel tables, is sent to ukc.ac.uk. When sendmail fails to find a match for a domain, e.g. "vax6.cs.hw.ac.uk" in the main channel tables, then it retries with successively higher level domains, e.g. "cs.hw.ac.uk", "hw.ac.uk" and "ac.uk". If these fail then the top level domain relaying rule is applied and matching begins again with the RHS of the relaying rule. Examples -------- The archive Examples.a contains sample mailer channel files. How to compile the channel tables --------------------------------- 1. Create a mailer channel file for each mailer you have. This is best done by extracting sample channel files from Examples.a and editing them to contain the relevent data for this host. 2. Run "MAKE host file1 file2... " This generates the sendmail classes and rules for channel selection and routing in a file .chn. e.g. MAKE hwcs local.chn luucp.chn ukuucp.chn This shell script does a lot of work so be prepared to wait! Supported Mailers ----------------- MAKE looks for tables for the following mailers: local.chn (local mail) ether.chn (ethernet) luucp.chn (local uucp) uucp.chn (uucp) janet.chn (janet) bitnet.chn (bitnet) csnet.chn (csnet) top.chn (top level relaying) If you have other mailers not listed here, then you will need to add some code the the MAKE shell script. Good Luck! Note ---- Make sure that the domains on the RHS of the relaying rules in top.chn eventually match some domain on the LHS of a rule in one of the mailer channel tables. Running Shared Configuration Files ---------------------------------- Suppose we have ten workstations connected to an ethernet with a central machine attached that has connections to some external network. Those ten workstations can share the same configuration file. To do this we need to "generalise" the host dependent parts of the channel tables so that all the workstations can use the same .chn. The trick is to use "$w" when specifying the host specific names in the local.chn table (e.g. $w.cs.hw.ac.uk); and to have, in above example, all ten workstations in the ether.chn. The two key components to this are that: (a) sendmail will determine whether a domain is local or not before it attempts to locate the domain in the other channel tables, and (b) sendmail's "$w" macro expands to the local hostname at runtime. SHAR_EOF if test 5870 -ne "`wc -c README`" then echo shar: error transmitting README '(should have been 5870 characters)' fi echo shar: extracting Examples.a '(4550 characters)' cat << \SHAR_EOF > Examples.a ! ether.chn 508609177 217 4 100644 168 ` # # Ethernet channel table # The domain name on the LHS is routed to the host on the RHS. # brahma.cs.hw.ac.uk brahma oberon.cs.hw.ac.uk oberon odin.cs.hw.ac.uk odin luucp.chn 508609295 217 4 100644 155 ` # # Local UUCP channel table # The domain name on the LHS is routed to the host on the RHS. # ra.cs.hw.ac.uk ra jove.cs.hw.ac.uk ra zeus.cs.hw.ac.uk ra uucp.chn 508610006 217 4 100644 987 ` # UUCP Channel Table # The domain name on the LHS is mapped to a path on the RHS. # If "%s" is included in the RHS then the user part goes here # e.g. jim@hwcs.ac.uk -> hwcs!%s -> hwcs!jim # standard NRS names aimmi.heriot-watt.ac.uk aimmi!%s ee.heriot-watt.ac.uk hwee!%s cstvax.edinburgh.ac.uk cstvax!%s caad.edinburgh.ac.uk edcaad!%s cs.kcl.ac.uk kcl-cs!%s spider.co.uk spider!%s stl.stc.co.uk stl!%s stc.co.uk stl!stc!%s dcs.leeds.ac.uk ulcs!%s cs.ucl.ac.uk cstvax!cs.ucl.ac.uk!%s ukc.ac.uk cstvax!ukc.ac.uk!%s # abbreviated NRS names (where different from above) aimmi.hw.ac.uk aimmi!%s ee.hw.ac.uk hwee!%s cstvax.ed.ac.uk cstvax!%s caad.ed.ac.uk edcaad!%s # old uucp names aimmi.uucp aimmi!%s cstvax.uucp cstvax!%s edcaad.uucp edcaad!%s kcl-cs.uucp kcl-cs!%s spider.uucp spider!%s stl.uucp stl!%s stc.uucp stl!stc!%s ulcs.uucp ulcs!%s ucl-cs.uucp cstvax!cs.ucl.ac.uk!%s ukc.uucp cstvax!ukc.ac.uk!%s # everything else goes to ukc for further routing janet.chn 511450060 217 4 100644 783 ` # # Janet channel table # The domain name on the LHS is routed to the domain name on the RHS. # Note that the domain names on the LHS are in big-endian form. # The domains on the RHS correspond to entries in the x25/directory as # follows: # uk.ac. -> # uk. -> uk. # # Defining the janet mailer automatically includes the default rule # that all "uk" sites are directly connected. # So, only non-"uk" sites and application relays are required here. # cern.cernvm cern.cernvm cern.gec-a cern.gec-a uk.ac.cam.eng-dsl uk.ac.cam.cl-jenny uk.ac.cam.eng-44 uk.ac.cam.cl-jenny uk.ac.cam.eng-dsl uk.ac.cam.phx uk.ac.cam.eng-icf uk.ac.ncl.kelpie uk.ac.ncl.cheviot uk.ac.nott.maths uk.ac.nott.cs uk.ac.york.com uk.ac.york.kl uk.alvey uk.ac.rl.gm bitnet.chn 508610388 217 4 100644 400 ` # # Bitnet channel table # Actual routing is done by the bitnet mailer itself. # Defining the bitnet mailer automatically includes the following mappings: # .bitnet -> # .arpa -> smtpuser@wiscvm (using bsmtp) # .uucp -> uucp@psuvax1 (using bsmtp) # # So, only bitnet sites with other domain names should be included here # e.g. ucbjade.cc ucbjade # top.chn 508609427 217 4 100644 469 ` # Top level domains # If an address hasn't matched a domain name in any other table then # it should match something here. The RHS is a domain which specifies # where the message should be relayed for further routing. # uk cstvax.ed.ac.uk uucp ukc.ac.uk arpa cs.ucl.ac.uk com cs.ucl.ac.uk edu cs.ucl.ac.uk gov cs.ucl.ac.uk mil cs.ucl.ac.uk org cs.ucl.ac.uk oz ukc.ac.uk csnet relay.cs.net bitnet wiscvm.wisc.edu mailnet multics.mit.edu dec decwrl.dec.com local.chn 508609283 217 4 100644 289 ` # # The Local channel # The domain names listed here are local to this host # # NRS names cs.hw.ac.uk cs.heriot-watt.ac.uk # UUCP name hwcs.uucp # # As we are a multihost site, we must include the following host names # brahma.cs.hw.ac.uk brahma.cs.heriot-watt.ac.uk brahma.hwcs.uucp gen.top.chn 508609252 217 4 100644 381 ` # Top level domains # This table sends uk mail to ukc, and all other top level domains to ucl. # # The name "$=T" can be used to match all top level domains given in the # top.dom table. This can save on the number of rules generated by MAKE # # NOTE: A list of top level domains would need to be explicitly # specified in ../dom/top.dom. # uk ukc.ac.uk $=T cs.ucl.ac.uk csnet.chn 508609142 217 4 100644 363 ` # # CSNet PhoneNet channel table # The domain name on the LHS is routed to the host on the RHS. # # Since PhoneNet sites all call csnet-relay, you just need to specify # the different names of csnet-relay in this table. All other routing # is done in the top.chn table. # csnet-relay.csnet csnet-relay csnet-relay.arpa csnet-relay relay.cs.net csnet-relay SHAR_EOF if test 4550 -ne "`wc -c Examples.a`" then echo shar: error transmitting Examples.a '(should have been 4550 characters)' fi echo shar: done with directory chn cd .. # End of shell archive exit 0