expn.1 (82794) | expn.1 (119679) |
---|---|
1#!@PERL@ 2'di '; 3'ds 00 \\"'; 4'ig 00 '; 5# 6# THIS PROGRAM IS ITS OWN MANUAL PAGE. INSTALL IN man & bin. 7# 8 9# hardcoded constants, should work fine for BSD-based systems 10#require 'sys/socket.ph'; # perl 4 11use Socket; # perl 5 12$AF_INET = &AF_INET; 13$SOCK_STREAM = &SOCK_STREAM; 14$sockaddr = 'S n a4 x8'; 15 16# system requirements: 17# must have 'nslookup' and 'hostname' programs. 18 | 1#!@PERL@ 2'di '; 3'ds 00 \\"'; 4'ig 00 '; 5# 6# THIS PROGRAM IS ITS OWN MANUAL PAGE. INSTALL IN man & bin. 7# 8 9# hardcoded constants, should work fine for BSD-based systems 10#require 'sys/socket.ph'; # perl 4 11use Socket; # perl 5 12$AF_INET = &AF_INET; 13$SOCK_STREAM = &SOCK_STREAM; 14$sockaddr = 'S n a4 x8'; 15 16# system requirements: 17# must have 'nslookup' and 'hostname' programs. 18 |
19# $Header: /proj/bank/cvsroot/am-utils/scripts/expn.1,v 1.1.1.1 1998/11/05 02:04:58 ezk Exp $ | 19# $Header: /proj/bank/cvsroot/am-utils/scripts/expn.1,v 1.1.1.1.2.2 2003/03/16 01:47:01 ezk Exp $ |
20 21# TODO: 22# less magic should apply to command-line addresses 23# less magic should apply to local addresses 24# add magic to deal with cross-domain cnames 25 26# Checklist: (hard addresses) 27# 250 Kimmo Suominen <"|/usr/local/mh/lib/slocal -user kim"@grendel.tac.nyc.ny.us> --- 10 unchanged lines hidden (view full) --- 38# modification, are permitted provided that the following conditions 39# are met: 40# 1. Redistributions of source code must retain the above copyright 41# notice, this list of conditions and the following disclaimer. 42# 2. Redistributions in binary form must reproduce the above copyright 43# notice, this list of conditions and the following disclaimer in the 44# documentation and/or other materials provided with the distribution. 45# 3. All advertising materials mentioning features or use of this software | 20 21# TODO: 22# less magic should apply to command-line addresses 23# less magic should apply to local addresses 24# add magic to deal with cross-domain cnames 25 26# Checklist: (hard addresses) 27# 250 Kimmo Suominen <"|/usr/local/mh/lib/slocal -user kim"@grendel.tac.nyc.ny.us> --- 10 unchanged lines hidden (view full) --- 38# modification, are permitted provided that the following conditions 39# are met: 40# 1. Redistributions of source code must retain the above copyright 41# notice, this list of conditions and the following disclaimer. 42# 2. Redistributions in binary form must reproduce the above copyright 43# notice, this list of conditions and the following disclaimer in the 44# documentation and/or other materials provided with the distribution. 45# 3. All advertising materials mentioning features or use of this software |
46# must display the following acknowledgement: | 46# must display the following acknowledgment: |
47# This product includes software developed by the David Muir Sharnoff. 48# 4. The name of David Sharnoff may not be used to endorse or promote products 49# derived from this software without specific prior written permission. 50# 51# THIS SOFTWARE IS PROVIDED BY THE DAVID MUIR SHARNOFF ``AS IS'' AND 52# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54# ARE DISCLAIMED. IN NO EVENT SHALL DAVID MUIR SHARNOFF BE LIABLE 55# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61# SUCH DAMAGE. 62# | 47# This product includes software developed by the David Muir Sharnoff. 48# 4. The name of David Sharnoff may not be used to endorse or promote products 49# derived from this software without specific prior written permission. 50# 51# THIS SOFTWARE IS PROVIDED BY THE DAVID MUIR SHARNOFF ``AS IS'' AND 52# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 53# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 54# ARE DISCLAIMED. IN NO EVENT SHALL DAVID MUIR SHARNOFF BE LIABLE 55# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 56# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 57# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 58# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 59# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 60# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 61# SUCH DAMAGE. 62# |
63# This copyright notice derrived from material copyrighted by the Regents | 63# This copyright notice derived from material copyrighted by the Regents |
64# of the University of California. 65# 66# Contributions accepted. 67# 68############################################################################# 69 70# overall structure: 71# in an effort to not trace each address individually, but rather --- 11 unchanged lines hidden (view full) --- 83# 84# @hosts : list of servers still to be contacted 85# $server : name of the current we are currently looking at 86# @users = $users{@hosts[0]} : addresses to expand at this server 87# $u = $users[0] : the current address being expanded 88# $names{"$users[0] *** $server"} : the 'name' associated with the address 89# $mxbacktrace{"$users[0] *** $server"} : record of mx expansion 90# $mx_secondary{$server} : other mx relays at the same priority | 64# of the University of California. 65# 66# Contributions accepted. 67# 68############################################################################# 69 70# overall structure: 71# in an effort to not trace each address individually, but rather --- 11 unchanged lines hidden (view full) --- 83# 84# @hosts : list of servers still to be contacted 85# $server : name of the current we are currently looking at 86# @users = $users{@hosts[0]} : addresses to expand at this server 87# $u = $users[0] : the current address being expanded 88# $names{"$users[0] *** $server"} : the 'name' associated with the address 89# $mxbacktrace{"$users[0] *** $server"} : record of mx expansion 90# $mx_secondary{$server} : other mx relays at the same priority |
91# $domainify_fallback{"$users[0] *** $server"} : alternative names to try | 91# $domainify_fallback{"$users[0] *** $server"} : alternative names to try |
92# instead of $server if $server doesn't work 93# $temporary_redirect{"$users[0] *** $server"} : when trying alternates, 94# temporarily channel all tries along current path 95# $giveup{$server} : do not bother expanding addresses at $server 96# $verbose : -v 97# $watch : -w 98# $vw : -v or -w 99# $debug : -d --- 72 unchanged lines hidden (view full) --- 172 $0 = "$av0 - gethostbyname($server)"; 173 174 ($name,$aliases,$type,$len,$thataddr) = gethostbyname($server); 175 # if we can't get an A record, try for an MX record. 176 unless($thataddr) { 177 &mxlookup(1,$server,"$server: could not resolve name",*users); 178 next HOST; 179 } | 92# instead of $server if $server doesn't work 93# $temporary_redirect{"$users[0] *** $server"} : when trying alternates, 94# temporarily channel all tries along current path 95# $giveup{$server} : do not bother expanding addresses at $server 96# $verbose : -v 97# $watch : -w 98# $vw : -v or -w 99# $debug : -d --- 72 unchanged lines hidden (view full) --- 172 $0 = "$av0 - gethostbyname($server)"; 173 174 ($name,$aliases,$type,$len,$thataddr) = gethostbyname($server); 175 # if we can't get an A record, try for an MX record. 176 unless($thataddr) { 177 &mxlookup(1,$server,"$server: could not resolve name",*users); 178 next HOST; 179 } |
180 | 180 |
181 # get a connection, or look for an mx 182 $0 = "$av0 - socket to $server"; 183 $that = pack($sockaddr, &AF_INET, $port, $thataddr); 184 socket(S, &AF_INET, &SOCK_STREAM, $proto) 185 || die "socket: $!"; 186 $0 = "$av0 - bind to $server"; | 181 # get a connection, or look for an mx 182 $0 = "$av0 - socket to $server"; 183 $that = pack($sockaddr, &AF_INET, $port, $thataddr); 184 socket(S, &AF_INET, &SOCK_STREAM, $proto) 185 || die "socket: $!"; 186 $0 = "$av0 - bind to $server"; |
187 bind(S, $this) | 187 bind(S, $this) |
188 || die "bind $hostname,0: $!"; 189 $0 = "$av0 - connect to $server"; 190 print "debug = $debug server = $server\n" if $debug > 8; 191 if (! connect(S, $that) || ($debug == 10 && $server =~ /relay\d.UU.NET$/i)) { 192 $0 = "$av0 - $server: could not connect: $!\n"; 193 $emsg = $!; 194 unless (&mxlookup(0,$server,"$server: could not connect: $!",*users)) { 195 &giveup('mx',"$server: Could not connect: $emsg"); --- 30 unchanged lines hidden (view full) --- 226 &giveup('',"$server: did not talk SMTP"); 227 } 228 close(S); 229 next HOST; 230 } 231 &alarm("greeting with $server",''); 232 } 233 alarm(0); | 188 || die "bind $hostname,0: $!"; 189 $0 = "$av0 - connect to $server"; 190 print "debug = $debug server = $server\n" if $debug > 8; 191 if (! connect(S, $that) || ($debug == 10 && $server =~ /relay\d.UU.NET$/i)) { 192 $0 = "$av0 - $server: could not connect: $!\n"; 193 $emsg = $!; 194 unless (&mxlookup(0,$server,"$server: could not connect: $!",*users)) { 195 &giveup('mx',"$server: Could not connect: $emsg"); --- 30 unchanged lines hidden (view full) --- 226 &giveup('',"$server: did not talk SMTP"); 227 } 228 close(S); 229 next HOST; 230 } 231 &alarm("greeting with $server",''); 232 } 233 alarm(0); |
234 | 234 |
235 # if this causes problems, remove it 236 $0 = "$av0 - sending helo to $server"; 237 &alarm("sending helo to $server",""); 238 &ps("helo $hostname"); 239 while(<S>) { 240 print if $watch; 241 last if /^\d+ /; 242 } --- 6 unchanged lines hidden (view full) --- 249 $0 = "$av0 - expanding $u [\@$server]"; 250 251 # do we already have a name for this user? 252 $oldname = $names{"$u *** $server"}; 253 254 print &compact($u,$server)." ->\n" if ($verbose && ! $valid); 255 if ($valid) { 256 # | 235 # if this causes problems, remove it 236 $0 = "$av0 - sending helo to $server"; 237 &alarm("sending helo to $server",""); 238 &ps("helo $hostname"); 239 while(<S>) { 240 print if $watch; 241 last if /^\d+ /; 242 } --- 6 unchanged lines hidden (view full) --- 249 $0 = "$av0 - expanding $u [\@$server]"; 250 251 # do we already have a name for this user? 252 $oldname = $names{"$u *** $server"}; 253 254 print &compact($u,$server)." ->\n" if ($verbose && ! $valid); 255 if ($valid) { 256 # |
257 # when running with -a, we delay taking any action | 257 # when running with -a, we delay taking any action |
258 # on the results of our query until we have looked 259 # at the complete output. @toFinal stores expansions 260 # that will be final if we take them. @toExpn stores | 258 # on the results of our query until we have looked 259 # at the complete output. @toFinal stores expansions 260 # that will be final if we take them. @toExpn stores |
261 # expnansions that are not final. @isValid keeps | 261 # expansions that are not final. @isValid keeps |
262 # track of our ability to send mail to each of the 263 # expansions. 264 # 265 @isValid = (); 266 @toFinal = (); 267 @toExpn = (); 268 } 269 --- 29 unchanged lines hidden (view full) --- 299 if ($valid) { 300 push(@isValid, &validAddr($newaddr)); 301 push(@toFinal,$newaddr,$server,$newname); 302 } else { 303 &verbose(&final($newaddr,$server,$newname)); 304 } 305 } else { 306 $newmxhost = &mx($newhost,$newaddr); | 262 # track of our ability to send mail to each of the 263 # expansions. 264 # 265 @isValid = (); 266 @toFinal = (); 267 @toExpn = (); 268 } 269 --- 29 unchanged lines hidden (view full) --- 299 if ($valid) { 300 push(@isValid, &validAddr($newaddr)); 301 push(@toFinal,$newaddr,$server,$newname); 302 } else { 303 &verbose(&final($newaddr,$server,$newname)); 304 } 305 } else { 306 $newmxhost = &mx($newhost,$newaddr); |
307 print "$newmxhost = &mx($newhost)\n" | 307 print "$newmxhost = &mx($newhost)\n" |
308 if ($debug && $newhost ne $newmxhost); 309 $0 = "$av0 - parsing $newaddr [@$newmxhost]"; 310 print "levels = $levels, level{$u *** $server} = ".$level{"$u *** $server"}."\n" if ($debug > 1); | 308 if ($debug && $newhost ne $newmxhost); 309 $0 = "$av0 - parsing $newaddr [@$newmxhost]"; 310 print "levels = $levels, level{$u *** $server} = ".$level{"$u *** $server"}."\n" if ($debug > 1); |
311 # If the new server is the current one, | 311 # If the new server is the current one, |
312 # it would have expanded things for us 313 # if it could have. Mx records must be 314 # followed to compare server names. 315 # We are also done if the recursion 316 # count has been exceeded. 317 if (&trhost($newmxhost) eq &trhost($server) || ($levels && $level{"$u *** $server"} >= $levels)) { 318 if ($valid) { 319 push(@isValid, &validAddr($newaddr)); --- 12 unchanged lines hidden (view full) --- 332 } 333 } 334 last if ($done eq " "); 335 next; 336 } 337 # 550 is a known code... Should the be 338 # included in -a output? Might be a bug 339 # here. Does it matter? Can assume that | 312 # it would have expanded things for us 313 # if it could have. Mx records must be 314 # followed to compare server names. 315 # We are also done if the recursion 316 # count has been exceeded. 317 if (&trhost($newmxhost) eq &trhost($server) || ($levels && $level{"$u *** $server"} >= $levels)) { 318 if ($valid) { 319 push(@isValid, &validAddr($newaddr)); --- 12 unchanged lines hidden (view full) --- 332 } 333 } 334 last if ($done eq " "); 335 next; 336 } 337 # 550 is a known code... Should the be 338 # included in -a output? Might be a bug 339 # here. Does it matter? Can assume that |
340 # there won't be UNKNOWN USER responses | 340 # there won't be UNKNOWN USER responses |
341 # mixed with valid users? 342 if ($s =~ /^(550)([- ])/) { 343 if ($valid) { 344 print STDERR "\@$server:$u ($oldname) USER UNKNOWN\n"; 345 } else { 346 &verbose(&final($u,$server,$oldname,"USER UNKNOWN")); 347 } 348 last if ($2 eq " "); 349 next; | 341 # mixed with valid users? 342 if ($s =~ /^(550)([- ])/) { 343 if ($valid) { 344 print STDERR "\@$server:$u ($oldname) USER UNKNOWN\n"; 345 } else { 346 &verbose(&final($u,$server,$oldname,"USER UNKNOWN")); 347 } 348 last if ($2 eq " "); 349 next; |
350 } 351 # 553 is a known code... | 350 } 351 # 553 is a known code... |
352 if ($s =~ /^(553)([- ])/) { 353 if ($valid) { 354 print STDERR "\@$server:$u ($oldname) USER AMBIGUOUS\n"; 355 } else { 356 &verbose(&final($u,$server,$oldname,"USER AMBIGUOUS")); 357 } 358 last if ($2 eq " "); 359 next; | 352 if ($s =~ /^(553)([- ])/) { 353 if ($valid) { 354 print STDERR "\@$server:$u ($oldname) USER AMBIGUOUS\n"; 355 } else { 356 &verbose(&final($u,$server,$oldname,"USER AMBIGUOUS")); 357 } 358 last if ($2 eq " "); 359 next; |
360 } 361 # 252 is a known code... | 360 } 361 # 252 is a known code... |
362 if ($s =~ /^(252)([- ])/) { 363 if ($valid) { 364 print STDERR "\@$server:$u ($oldname) REFUSED TO VRFY\n"; 365 } else { 366 &verbose(&final($u,$server,$oldname,"REFUSED TO VRFY")); 367 } 368 last if ($2 eq " "); 369 next; | 362 if ($s =~ /^(252)([- ])/) { 363 if ($valid) { 364 print STDERR "\@$server:$u ($oldname) REFUSED TO VRFY\n"; 365 } else { 366 &verbose(&final($u,$server,$oldname,"REFUSED TO VRFY")); 367 } 368 last if ($2 eq " "); 369 next; |
370 } | 370 } |
371 &giveup('',"$server: did not grok '$s'",$u); 372 last USER; 373 } 374 375 if ($valid) { 376 # 377 # now we decide if we are going to take these 378 # expansions or roll them back. --- 83 unchanged lines hidden (view full) --- 462 for $u (@users) { 463 print &compact($u,$server)." ->\n" if ($verbose && $valid && $u); 464 &verbose(&final($u,$server,$names{"$u *** $server"},$reason)); 465 } 466} 467# 468# This routine is used only within &giveup. It checks to 469# see if we really have to giveup or if there is a second | 371 &giveup('',"$server: did not grok '$s'",$u); 372 last USER; 373 } 374 375 if ($valid) { 376 # 377 # now we decide if we are going to take these 378 # expansions or roll them back. --- 83 unchanged lines hidden (view full) --- 462 for $u (@users) { 463 print &compact($u,$server)." ->\n" if ($verbose && $valid && $u); 464 &verbose(&final($u,$server,$names{"$u *** $server"},$reason)); 465 } 466} 467# 468# This routine is used only within &giveup. It checks to 469# see if we really have to giveup or if there is a second |
470# chance because we did something before that can be | 470# chance because we did something before that can be |
471# backtracked. 472# 473# %fallback{"$user *** $host"} tracks what is able to fallback 474# %fellback{"$user *** $host"} tracks what has fallen back 475# 476# If there is a valid backtrack, then queue up the new possibility 477# 478sub try_fallback --- 7 unchanged lines hidden (view full) --- 486 print "\t'$i'\t\t'$fall_table{$i}'\n"; 487 } 488 print "Fellback table $method:\n"; 489 for $i (sort keys %fellback) { 490 print "\t'$i'\t\t'$fellback{$i}'\n"; 491 } 492 print "U: $user H: $host\n"; 493 } | 471# backtracked. 472# 473# %fallback{"$user *** $host"} tracks what is able to fallback 474# %fellback{"$user *** $host"} tracks what has fallen back 475# 476# If there is a valid backtrack, then queue up the new possibility 477# 478sub try_fallback --- 7 unchanged lines hidden (view full) --- 486 print "\t'$i'\t\t'$fall_table{$i}'\n"; 487 } 488 print "Fellback table $method:\n"; 489 for $i (sort keys %fellback) { 490 print "\t'$i'\t\t'$fellback{$i}'\n"; 491 } 492 print "U: $user H: $host\n"; 493 } |
494 | 494 |
495 $us = "$user *** $host"; 496 if (defined $fellback{$us}) { 497 # 498 # Undo a previous fallback so that we can try again 499 # Nested fallbacks are avoided because they could 500 # lead to infinite loops 501 # 502 $fallhost = $fellback{$us}; --- 31 unchanged lines hidden (view full) --- 534 if (@so) { 535 print "Can still $method $us: @so\n" if $debug; 536 $fall_table{$ft} = join(' ',@so); 537 } else { 538 print "No more fallbacks for $us\n" if $debug; 539 delete $fall_table{$ft}; 540 } 541 if (defined $create_host_backtrack{$us}) { | 495 $us = "$user *** $host"; 496 if (defined $fellback{$us}) { 497 # 498 # Undo a previous fallback so that we can try again 499 # Nested fallbacks are avoided because they could 500 # lead to infinite loops 501 # 502 $fallhost = $fellback{$us}; --- 31 unchanged lines hidden (view full) --- 534 if (@so) { 535 print "Can still $method $us: @so\n" if $debug; 536 $fall_table{$ft} = join(' ',@so); 537 } else { 538 print "No more fallbacks for $us\n" if $debug; 539 delete $fall_table{$ft}; 540 } 541 if (defined $create_host_backtrack{$us}) { |
542 $create_host_backtrack{"$user *** $newhost"} | 542 $create_host_backtrack{"$user *** $newhost"} |
543 = $create_host_backtrack{$us}; 544 } 545 $fellback{"$user *** $newhost"} = $oldhost; 546 &expn($newhost,$user,$names{$us},$level{$us}); 547 return 1; 548 } 549 delete $temporary_redirect{$us}; 550 $host = $oldhost; --- 63 unchanged lines hidden (view full) --- 614 if ($s !~ /^(\d+)([- ])/) { 615 return "$server: garbled reply to '$c $try_u'"; 616 } 617 if ($1 == 250) { 618 $code = 250; 619 @ret = ("",$s); 620 push(@ret,&read_response($2,$debug)); 621 return (@ret); | 543 = $create_host_backtrack{$us}; 544 } 545 $fellback{"$user *** $newhost"} = $oldhost; 546 &expn($newhost,$user,$names{$us},$level{$us}); 547 return 1; 548 } 549 delete $temporary_redirect{$us}; 550 $host = $oldhost; --- 63 unchanged lines hidden (view full) --- 614 if ($s !~ /^(\d+)([- ])/) { 615 return "$server: garbled reply to '$c $try_u'"; 616 } 617 if ($1 == 250) { 618 $code = 250; 619 @ret = ("",$s); 620 push(@ret,&read_response($2,$debug)); 621 return (@ret); |
622 } | 622 } |
623 if ($1 == 551 || $1 == 251) { 624 $code = $1; 625 @ret = ("",$s); 626 push(@ret,&read_response($2,$debug)); 627 next; 628 } 629 if ($1 == 252 && ($code == 0 || $code == 550)) { 630 $code = 252; --- 9 unchanged lines hidden (view full) --- 640 } 641 &read_response($2,$watch); 642 } 643 } 644 return "$server: expn/vrfy not implemented" unless @ret; 645 return @ret; 646} 647# sometimes the old parse routine (now parse2) didn't | 623 if ($1 == 551 || $1 == 251) { 624 $code = $1; 625 @ret = ("",$s); 626 push(@ret,&read_response($2,$debug)); 627 next; 628 } 629 if ($1 == 252 && ($code == 0 || $code == 550)) { 630 $code = 252; --- 9 unchanged lines hidden (view full) --- 640 } 641 &read_response($2,$watch); 642 } 643 } 644 return "$server: expn/vrfy not implemented" unless @ret; 645 return @ret; 646} 647# sometimes the old parse routine (now parse2) didn't |
648# reject funky addresses. | 648# reject funky addresses. |
649sub parse 650{ 651 local($oldaddr,$server,$oldname,$one_to_one) = @_; 652 local($newhost, $newaddr, $newname, $um) = &parse2($oldaddr,$server,$oldname,$one_to_one); 653 if ($newaddr =~ m,^["/],) { 654 return (undef, $oldaddr, $newname) if $valid; 655 return (undef, $um, $newname); 656 } 657 return ($newhost, $newaddr, $newname); 658} 659 660# returns ($new_smtp_server,$new_address,$new_name) | 649sub parse 650{ 651 local($oldaddr,$server,$oldname,$one_to_one) = @_; 652 local($newhost, $newaddr, $newname, $um) = &parse2($oldaddr,$server,$oldname,$one_to_one); 653 if ($newaddr =~ m,^["/],) { 654 return (undef, $oldaddr, $newname) if $valid; 655 return (undef, $um, $newname); 656 } 657 return ($newhost, $newaddr, $newname); 658} 659 660# returns ($new_smtp_server,$new_address,$new_name) |
661# given a response from a SMTP server ($newaddr), the | 661# given a response from a SMTP server ($newaddr), the |
662# current host ($server), the old "name" and a flag that | 662# current host ($server), the old "name" and a flag that |
663# indicates if it is being called during the initial | 663# indicates if it is being called during the initial |
664# command line parsing ($parsing_args) 665sub parse2 666{ 667 local($newaddr,$context_host,$old_name,$parsing_args) = @_; 668 local(@names) = $old_name; 669 local($urx) = "[-A-Za-z_.0-9+]+"; 670 local($unmangle); 671 --- 86 unchanged lines hidden (view full) --- 758 for $v (@v) { 759 $v =~ s/^\s+//; 760 $v =~ s/\s+$//; 761 push(@r,$v) if ($v =~ /\S/); 762 } 763 return(@r); 764} 765# using the host part of an address, and the server name, add the | 664# command line parsing ($parsing_args) 665sub parse2 666{ 667 local($newaddr,$context_host,$old_name,$parsing_args) = @_; 668 local(@names) = $old_name; 669 local($urx) = "[-A-Za-z_.0-9+]+"; 670 local($unmangle); 671 --- 86 unchanged lines hidden (view full) --- 758 for $v (@v) { 759 $v =~ s/^\s+//; 760 $v =~ s/\s+$//; 761 push(@r,$v) if ($v =~ /\S/); 762 } 763 return(@r); 764} 765# using the host part of an address, and the server name, add the |
766# servers' domain to the address if it doesn't already have a | 766# servers' domain to the address if it doesn't already have a |
767# domain. Since this sometimes fails, save a back reference so 768# it can be unrolled. 769sub domainify 770{ 771 local($host,$domain_host,$u) = @_; 772 local($domain,$newhost); 773 | 767# domain. Since this sometimes fails, save a back reference so 768# it can be unrolled. 769sub domainify 770{ 771 local($host,$domain_host,$u) = @_; 772 local($domain,$newhost); 773 |
774 # cut of trailing dots | 774 # cut of trailing dots |
775 $host =~ s/\.$//; 776 $domain_host =~ s/\.$//; 777 778 if ($domain_host !~ /\./) { 779 # 780 # domain host isn't, keep $host whatever it is 781 # 782 print "domainify($host,$domain_host) = $host\n" if $debug; 783 return $host; 784 } 785 | 775 $host =~ s/\.$//; 776 $domain_host =~ s/\.$//; 777 778 if ($domain_host !~ /\./) { 779 # 780 # domain host isn't, keep $host whatever it is 781 # 782 print "domainify($host,$domain_host) = $host\n" if $debug; 783 return $host; 784 } 785 |
786 # 787 # There are several weird situtations that need to be | 786 # 787 # There are several weird situations that need to be |
788 # accounted for. They have to do with domain relay hosts. 789 # | 788 # accounted for. They have to do with domain relay hosts. 789 # |
790 # Examples: | 790 # Examples: |
791 # host server "right answer" | 791 # host server "right answer" |
792 # | 792 # |
793 # shiva.cs cs.berkeley.edu shiva.cs.berkeley.edu 794 # shiva cs.berkeley.edu shiva.cs.berekley.edu 795 # cumulus reed.edu @reed.edu:cumulus.uucp 796 # tiberius tc.cornell.edu tiberius.tc.cornell.edu 797 # | 793 # shiva.cs cs.berkeley.edu shiva.cs.berkeley.edu 794 # shiva cs.berkeley.edu shiva.cs.berekley.edu 795 # cumulus reed.edu @reed.edu:cumulus.uucp 796 # tiberius tc.cornell.edu tiberius.tc.cornell.edu 797 # |
798 # The first try must always be to cut the domain part out of | 798 # The first try must always be to cut the domain part out of |
799 # the server and tack it onto the host. 800 # 801 # A reasonable second try is to tack the whole server part onto | 799 # the server and tack it onto the host. 800 # 801 # A reasonable second try is to tack the whole server part onto |
802 # the host and for each possible repeated element, eliminate | 802 # the host and for each possible repeated element, eliminate |
803 # just that part. 804 # 805 # These extra "guesses" get put into the %domainify_fallback 806 # array. They will be used to give addresses a second chance 807 # in the &giveup routine 808 # 809 810 local(%fallback); 811 | 803 # just that part. 804 # 805 # These extra "guesses" get put into the %domainify_fallback 806 # array. They will be used to give addresses a second chance 807 # in the &giveup routine 808 # 809 810 local(%fallback); 811 |
812 local($long); | 812 local($long); |
813 $long = "$host $domain_host"; 814 $long =~ tr/A-Z/a-z/; 815 print "long = $long\n" if $debug; 816 if ($long =~ s/^([^ ]+\.)([^ ]+) \2(\.[^ ]+\.[^ ]+)/$1$2$3/) { 817 # matches shiva.cs cs.berkeley.edu and returns shiva.cs.berkeley.edu 818 print "condensed fallback $host $domain_host -> $long\n" if $debug; 819 $fallback{$long} = 9; 820 } --- 28 unchanged lines hidden (view full) --- 849 $newhost = "$host$domain"; 850 851 $create_host_backtrack{"$u *** $newhost"} = $domain_host; 852 print "domainify($host,$domain_host) = $newhost\n" if $debug; 853 delete $fallback{$newhost}; 854 $domainify_fallback{"$u *** $newhost"} = join(' ',sort {$fallback{$b} <=> $fallback{$a};} keys %fallback) if %fallback; 855 if ($debug) { 856 print "fallback = "; | 813 $long = "$host $domain_host"; 814 $long =~ tr/A-Z/a-z/; 815 print "long = $long\n" if $debug; 816 if ($long =~ s/^([^ ]+\.)([^ ]+) \2(\.[^ ]+\.[^ ]+)/$1$2$3/) { 817 # matches shiva.cs cs.berkeley.edu and returns shiva.cs.berkeley.edu 818 print "condensed fallback $host $domain_host -> $long\n" if $debug; 819 $fallback{$long} = 9; 820 } --- 28 unchanged lines hidden (view full) --- 849 $newhost = "$host$domain"; 850 851 $create_host_backtrack{"$u *** $newhost"} = $domain_host; 852 print "domainify($host,$domain_host) = $newhost\n" if $debug; 853 delete $fallback{$newhost}; 854 $domainify_fallback{"$u *** $newhost"} = join(' ',sort {$fallback{$b} <=> $fallback{$a};} keys %fallback) if %fallback; 855 if ($debug) { 856 print "fallback = "; |
857 print $domainify_fallback{"$u *** $newhost"} | 857 print $domainify_fallback{"$u *** $newhost"} |
858 if defined($domainify_fallback{"$u *** $newhost"}); 859 print "\n"; 860 } 861 return $newhost; 862} 863# return the first non-empty element of an array 864sub firstname 865{ --- 40 unchanged lines hidden (view full) --- 906# print to the server (also to stdout, if -w) 907sub ps 908{ 909 local($p) = @_; 910 print ">>> $p\n" if $watch; 911 print S "$p\n"; 912} 913# return case-adjusted name for a host (for comparison purposes) | 858 if defined($domainify_fallback{"$u *** $newhost"}); 859 print "\n"; 860 } 861 return $newhost; 862} 863# return the first non-empty element of an array 864sub firstname 865{ --- 40 unchanged lines hidden (view full) --- 906# print to the server (also to stdout, if -w) 907sub ps 908{ 909 local($p) = @_; 910 print ">>> $p\n" if $watch; 911 print S "$p\n"; 912} 913# return case-adjusted name for a host (for comparison purposes) |
914sub trhost | 914sub trhost |
915{ 916 # treat foo.bar as an alias for Foo.BAR 917 local($host) = @_; 918 local($trhost) = $host; 919 $trhost =~ tr/A-Z/a-z/; 920 if ($trhost{$trhost}) { 921 $host = $trhost{$trhost}; 922 } else { --- 27 unchanged lines hidden (view full) --- 950 return $nserver; 951 } else { 952 return undef; 953 } 954 } 955 return undef; 956} 957# follow mx records, return a hostname | 915{ 916 # treat foo.bar as an alias for Foo.BAR 917 local($host) = @_; 918 local($trhost) = $host; 919 $trhost =~ tr/A-Z/a-z/; 920 if ($trhost{$trhost}) { 921 $host = $trhost{$trhost}; 922 } else { --- 27 unchanged lines hidden (view full) --- 950 return $nserver; 951 } else { 952 return undef; 953 } 954 } 955 return undef; 956} 957# follow mx records, return a hostname |
958# also follow temporary redirections comming from &domainify and | 958# also follow temporary redirections coming from &domainify and |
959# &mxlookup 960sub mx 961{ 962 local($h,$u) = @_; 963 964 for (;;) { 965 if (defined $mx{&trhost($h)} && $h ne $mx{&trhost($h)}) { 966 $0 = "$av0 - mx expand $h"; --- 18 unchanged lines hidden (view full) --- 985 } 986 } 987 return $h; 988 } 989} 990# look up mx records with the name server. 991# re-queue expansion requests if possible 992# optionally give up on this host. | 959# &mxlookup 960sub mx 961{ 962 local($h,$u) = @_; 963 964 for (;;) { 965 if (defined $mx{&trhost($h)} && $h ne $mx{&trhost($h)}) { 966 $0 = "$av0 - mx expand $h"; --- 18 unchanged lines hidden (view full) --- 985 } 986 } 987 return $h; 988 } 989} 990# look up mx records with the name server. 991# re-queue expansion requests if possible 992# optionally give up on this host. |
993sub mxlookup | 993sub mxlookup |
994{ 995 local($lastchance,$server,$giveup,*users) = @_; 996 local(*T); 997 local(*NSLOOKUP); 998 local($nh, $pref,$cpref); 999 local($o0) = $0; 1000 local($nserver); 1001 local($name,$aliases,$type,$len,$thataddr); --- 26 unchanged lines hidden (view full) --- 1028 $cpref = $pref; 1029 } elsif ($pref) { 1030 $fallback{$pref} .= " $nh"; 1031 } 1032 } 1033 } 1034 if (/Non-existent domain/) { 1035 # | 994{ 995 local($lastchance,$server,$giveup,*users) = @_; 996 local(*T); 997 local(*NSLOOKUP); 998 local($nh, $pref,$cpref); 999 local($o0) = $0; 1000 local($nserver); 1001 local($name,$aliases,$type,$len,$thataddr); --- 26 unchanged lines hidden (view full) --- 1028 $cpref = $pref; 1029 } elsif ($pref) { 1030 $fallback{$pref} .= " $nh"; 1031 } 1032 } 1033 } 1034 if (/Non-existent domain/) { 1035 # |
1036 # These addresss are hosed. Kaput! Dead! | 1036 # These addresses are hosed. Kaput! Dead! |
1037 # However, if we created the address in the | 1037 # However, if we created the address in the |
1038 # first place then there is a chance of | 1038 # first place then there is a chance of |
1039 # salvation. 1040 # | 1039 # salvation. 1040 # |
1041 1 while(<NSLOOKUP>); | 1041 1 while( |
1042 close(NSLOOKUP); 1043 return 0 unless $lastchance; 1044 &giveup('domainify',"$server: Non-existent domain",undef,1); | 1042 close(NSLOOKUP); 1043 return 0 unless $lastchance; 1044 &giveup('domainify',"$server: Non-existent domain",undef,1); |
1045 return 0; | 1045 return 0; |
1046 } | 1046 } |
1047 | 1047 |
1048 } 1049 close(NSLOOKUP); 1050 unlink("/tmp/expn$$"); 1051 unless ($nserver) { 1052 $0 = "$o0 - finished mxlookup"; 1053 return 0 unless $lastchance; 1054 &giveup('mx domainify',"$server: Could not resolve address"); 1055 return 0; --- 21 unchanged lines hidden (view full) --- 1077 return 0 unless $lastchance; 1078 &giveup('mx domainify',"$nserver: only one level of mx redirect allowed"); 1079 return 0; 1080 } 1081 $0 = "$o0 - finished mxlookup"; 1082 return 1; 1083} 1084# if mx expansion did not help to resolve an address | 1048 } 1049 close(NSLOOKUP); 1050 unlink("/tmp/expn$$"); 1051 unless ($nserver) { 1052 $0 = "$o0 - finished mxlookup"; 1053 return 0 unless $lastchance; 1054 &giveup('mx domainify',"$server: Could not resolve address"); 1055 return 0; --- 21 unchanged lines hidden (view full) --- 1077 return 0 unless $lastchance; 1078 &giveup('mx domainify',"$nserver: only one level of mx redirect allowed"); 1079 return 0; 1080 } 1081 $0 = "$o0 - finished mxlookup"; 1082 return 1; 1083} 1084# if mx expansion did not help to resolve an address |
1085# (ie: foo@bar became @baz:foo@bar, then undo the | 1085# (ie: foo@bar became @baz:foo@bar, then undo the |
1086# expansion). 1087# this is only used by &final 1088sub mxunroll 1089{ 1090 local(*host,*addr) = @_; 1091 local($r) = 0; 1092 print "looking for mxbacktrace{$addr *** $host}\n" 1093 if ($debug > 1); 1094 while (defined $mxbacktrace{"$addr *** $host"}) { | 1086# expansion). 1087# this is only used by &final 1088sub mxunroll 1089{ 1090 local(*host,*addr) = @_; 1091 local($r) = 0; 1092 print "looking for mxbacktrace{$addr *** $host}\n" 1093 if ($debug > 1); 1094 while (defined $mxbacktrace{"$addr *** $host"}) { |
1095 print "Unrolling MX expnasion: \@$host:$addr -> " | 1095 print "Unrolling MX expansion: \@$host:$addr -> " |
1096 if ($debug || $verbose); 1097 $host = $mxbacktrace{"$addr *** $host"}; | 1096 if ($debug || $verbose); 1097 $host = $mxbacktrace{"$addr *** $host"}; |
1098 print "\@$host:$addr\n" | 1098 print "\@$host:$addr\n" |
1099 if ($debug || $verbose); 1100 $r = 1; 1101 } 1102 return 1 if $r; 1103 $addr = "\@$host:$addr" 1104 if ($host =~ /\./); 1105 return 0; 1106} | 1099 if ($debug || $verbose); 1100 $r = 1; 1101 } 1102 return 1 if $r; 1103 $addr = "\@$host:$addr" 1104 if ($host =~ /\./); 1105 return 0; 1106} |
1107# register a completed expnasion. Make the final address as | 1107# register a completed expansion. Make the final address as |
1108# simple as possible. 1109sub final 1110{ 1111 local($addr,$host,$name,$error) = @_; 1112 local($he); 1113 local($hb,$hr); 1114 local($au,$ah); 1115 1116 if ($error =~ /Non-existent domain/) { | 1108# simple as possible. 1109sub final 1110{ 1111 local($addr,$host,$name,$error) = @_; 1112 local($he); 1113 local($hb,$hr); 1114 local($au,$ah); 1115 1116 if ($error =~ /Non-existent domain/) { |
1117 # | 1117 # |
1118 # If we created the domain, then let's undo the 1119 # damage... 1120 # 1121 if (defined $create_host_backtrack{"$addr *** $host"}) { 1122 while (defined $create_host_backtrack{"$addr *** $host"}) { 1123 print "Un&domainifying($host) = " if $debug; 1124 $host = $create_host_backtrack{"$addr *** $host"}; 1125 print "$host\n" if $debug; 1126 } 1127 $error = "$host: could not locate"; 1128 } else { | 1118 # If we created the domain, then let's undo the 1119 # damage... 1120 # 1121 if (defined $create_host_backtrack{"$addr *** $host"}) { 1122 while (defined $create_host_backtrack{"$addr *** $host"}) { 1123 print "Un&domainifying($host) = " if $debug; 1124 $host = $create_host_backtrack{"$addr *** $host"}; 1125 print "$host\n" if $debug; 1126 } 1127 $error = "$host: could not locate"; 1128 } else { |
1129 # | 1129 # |
1130 # If we only want valid addresses, toss out 1131 # bad host names. 1132 # 1133 if ($valid) { 1134 print STDERR "\@$host:$addr ($name) Non-existent domain\n"; 1135 return ""; 1136 } 1137 } --- 18 unchanged lines hidden (view full) --- 1156 } 1157 } 1158 # addr does not contain full host 1159 if ($valid) { 1160 if ($host =~ /^([^\.]+)(\..+)$/) { 1161 # host part has a . in it - foo.bar 1162 ($hb, $hr) = ($1, $2); 1163 if ($addr =~ /\@([^\.\@]+)$/ && ($1 eq $hb)) { | 1130 # If we only want valid addresses, toss out 1131 # bad host names. 1132 # 1133 if ($valid) { 1134 print STDERR "\@$host:$addr ($name) Non-existent domain\n"; 1135 return ""; 1136 } 1137 } --- 18 unchanged lines hidden (view full) --- 1156 } 1157 } 1158 # addr does not contain full host 1159 if ($valid) { 1160 if ($host =~ /^([^\.]+)(\..+)$/) { 1161 # host part has a . in it - foo.bar 1162 ($hb, $hr) = ($1, $2); 1163 if ($addr =~ /\@([^\.\@]+)$/ && ($1 eq $hb)) { |
1164 # addr part has not . | 1164 # addr part has not . |
1165 # and matches beginning of | 1165 # and matches beginning of |
1166 # host part -- tack on a | 1166 # host part -- tack on a |
1167 # domain name. 1168 $addr .= $hr; 1169 } else { | 1167 # domain name. 1168 $addr .= $hr; 1169 } else { |
1170 &mxunroll(*host,*addr) | 1170 &mxunroll(*host,*addr) |
1171 && redo MXUNWIND; 1172 } 1173 } else { | 1171 && redo MXUNWIND; 1172 } 1173 } else { |
1174 &mxunroll(*host,*addr) | 1174 &mxunroll(*host,*addr) |
1175 && redo MXUNWIND; 1176 } 1177 } else { 1178 $addr = "${addr}[\@$host]" 1179 if ($host =~ /\./); 1180 } 1181 } 1182 } --- 43 unchanged lines hidden (view full) --- 1226# to pass perl -w: 1227@tp; 1228$flag_a; 1229$flag_d; 1230$flag_1; 1231%already_domainify_fellback; 1232%already_mx_fellback; 1233&handle_alarm; | 1175 && redo MXUNWIND; 1176 } 1177 } else { 1178 $addr = "${addr}[\@$host]" 1179 if ($host =~ /\./); 1180 } 1181 } 1182 } --- 43 unchanged lines hidden (view full) --- 1226# to pass perl -w: 1227@tp; 1228$flag_a; 1229$flag_d; 1230$flag_1; 1231%already_domainify_fellback; 1232%already_mx_fellback; 1233&handle_alarm; |
1234################### BEGIN PERL/TROFF TRANSITION 1235.00 ; | 1234################### BEGIN PERL/TROFF TRANSITION 1235.00 ; |
1236 1237'di 1238.nr nl 0-1 1239.nr % 0 | 1236 1237'di 1238.nr nl 0-1 1239.nr % 0 |
1240.\\"'; __END__ | 1240.\\"'; __END__ |
1241.\" ############## END PERL/TROFF TRANSITION 1242.TH EXPN 1 "March 11, 1993" 1243.AT 3 1244.SH NAME 1245expn \- recursively expand mail aliases 1246.SH SYNOPSIS 1247.B expn 1248.RI [ -a ] 1249.RI [ -v ] 1250.RI [ -w ] 1251.RI [ -d ] 1252.RI [ -1 ] 1253.IR user [@ hostname ] 1254.RI [ user [@ hostname ]]... 1255.SH DESCRIPTION 1256.B expn 1257will use the SMTP 1258.B expn | 1241.\" ############## END PERL/TROFF TRANSITION 1242.TH EXPN 1 "March 11, 1993" 1243.AT 3 1244.SH NAME 1245expn \- recursively expand mail aliases 1246.SH SYNOPSIS 1247.B expn 1248.RI [ -a ] 1249.RI [ -v ] 1250.RI [ -w ] 1251.RI [ -d ] 1252.RI [ -1 ] 1253.IR user [@ hostname ] 1254.RI [ user [@ hostname ]]... 1255.SH DESCRIPTION 1256.B expn 1257will use the SMTP 1258.B expn |
1259and | 1259and |
1260.B vrfy | 1260.B vrfy |
1261commands to expand mail aliases. | 1261commands to expand mail aliases. |
1262It will first look up the addresses you provide on the command line. | 1262It will first look up the addresses you provide on the command line. |
1263If those expand into addresses on other systems, it will 1264connect to the other systems and expand again. It will keep | 1263If those expand into addresses on other systems, it will 1264connect to the other systems and expand again. It will keep |
1265doing this until no further expansion is possible. 1266.SH OPTIONS | 1265doing this until no further expansion is possible. 1266.SH OPTIONS |
1267The default output of | 1267The default output of |
1268.B expn 1269can contain many lines which are not valid | 1268.B expn 1269can contain many lines which are not valid |
1270email addresses. With the | 1270email addresses. With the |
1271.I -aa 1272flag, only expansions that result in legal addresses 1273are used. Since many mailing lists have an illegal 1274address or two, the single 1275.IR -a , 1276address, flag specifies that a few illegal addresses can | 1271.I -aa 1272flag, only expansions that result in legal addresses 1273are used. Since many mailing lists have an illegal 1274address or two, the single 1275.IR -a , 1276address, flag specifies that a few illegal addresses can |
1277be mixed into the results. More | 1277be mixed into the results. More |
1278.I -a 1279flags vary the ratio. Read the source to track down 1280the formula. With the 1281.I -a 1282option, you should be able to construct a new mailing 1283list out of an existing one. 1284.LP | 1278.I -a 1279flags vary the ratio. Read the source to track down 1280the formula. With the 1281.I -a 1282option, you should be able to construct a new mailing 1283list out of an existing one. 1284.LP |
1285If you wish to limit the number of levels deep that | 1285If you wish to limit the number of levels deep that |
1286.B expn 1287will recurse as it traces addresses, use the 1288.I -1 | 1286.B expn 1287will recurse as it traces addresses, use the 1288.I -1 |
1289option. For each | 1289option. For each |
1290.I -1 | 1290.I -1 |
1291another level will be traversed. So, | 1291another level will be traversed. So, |
1292.I -111 1293will traverse no more than three levels deep. 1294.LP 1295The normal mode of operation for 1296.B expn 1297is to do all of its work silently. 1298The following options make it more verbose. 1299It is not necessary to make it verbose to see what it is | 1292.I -111 1293will traverse no more than three levels deep. 1294.LP 1295The normal mode of operation for 1296.B expn 1297is to do all of its work silently. 1298The following options make it more verbose. 1299It is not necessary to make it verbose to see what it is |
1300doing because as it works, it changes its | 1300doing because as it works, it changes its |
1301.BR argv [0] 1302variable to reflect its current activity. | 1301.BR argv [0] 1302variable to reflect its current activity. |
1303To see how it is expanding things, the | 1303To see how it is expanding things, the |
1304.IR -v , | 1304.IR -v , |
1305verbose, flag will cause 1306.B expn | 1305verbose, flag will cause 1306.B expn |
1307to show each address before 1308and after translation as it works. | 1307to show each address before 1308and after translation as it works. |
1309The | 1309The |
1310.IR -w , 1311watch, flag will cause 1312.B expn 1313to show you its conversations with the mail daemons. | 1310.IR -w , 1311watch, flag will cause 1312.B expn 1313to show you its conversations with the mail daemons. |
1314Finally, the | 1314Finally, the |
1315.IR -d , 1316debug, flag will expose many of the inner workings so that 1317it is possible to eliminate bugs. 1318.SH ENVIRONMENT | 1315.IR -d , 1316debug, flag will expose many of the inner workings so that 1317it is possible to eliminate bugs. 1318.SH ENVIRONMENT |
1319No enviroment variables are used. | 1319No environment variables are used. |
1320.SH FILES 1321.PD 0 1322.B /tmp/expn$$ | 1320.SH FILES 1321.PD 0 1322.B /tmp/expn$$ |
1323.B temporary file used as input to | 1323.B temporary file used as input to |
1324.BR nslookup . 1325.SH SEE ALSO | 1324.BR nslookup . 1325.SH SEE ALSO |
1326.BR aliases (5), | 1326.BR aliases (5), |
1327.BR sendmail (8), 1328.BR nslookup (8), 1329RFC 823, and RFC 1123. 1330.SH BUGS | 1327.BR sendmail (8), 1328.BR nslookup (8), 1329RFC 823, and RFC 1123. 1330.SH BUGS |
1331Not all mail daemons will implement | 1331Not all mail daemons will implement |
1332.B expn 1333or 1334.BR vrfy . 1335It is not possible to verify addresses that are served 1336by such daemons. 1337.LP 1338When attempting to connect to a system to verify an address, 1339.B expn 1340only tries one IP address. Most mail daemons 1341will try harder. 1342.LP | 1332.B expn 1333or 1334.BR vrfy . 1335It is not possible to verify addresses that are served 1336by such daemons. 1337.LP 1338When attempting to connect to a system to verify an address, 1339.B expn 1340only tries one IP address. Most mail daemons 1341will try harder. 1342.LP |
1343It is assumed that you are running domain names and that 1344the 1345.BR nslookup (8) 1346program is available. If not, | 1343It is assumed that you are running domain names and that 1344the 1345.BR nslookup (8) 1346program is available. If not, |
1347.B expn 1348will not be able to verify many addresses. It will also pause 1349for a long time unless you change the code where it says 1350.I $have_nslookup = 1 1351to read | 1347.B expn 1348will not be able to verify many addresses. It will also pause 1349for a long time unless you change the code where it says 1350.I $have_nslookup = 1 1351to read |
1352.I $have_nslookup = | 1352.I $have_nslookup = |
1353.IR 0 . 1354.LP | 1353.IR 0 . 1354.LP |
1355Lastly, | 1355Lastly, |
1356.B expn 1357does not handle every valid address. If you have an example, 1358please submit a bug report. 1359.SH CREDITS 1360In 1986 or so, Jon Broome wrote a program of the same name 1361that did about the same thing. It has since suffered bit rot 1362and Jon Broome has dropped off the face of the earth! 1363(Jon, if you are out there, drop me a line) 1364.SH AVAILABILITY | 1356.B expn 1357does not handle every valid address. If you have an example, 1358please submit a bug report. 1359.SH CREDITS 1360In 1986 or so, Jon Broome wrote a program of the same name 1361that did about the same thing. It has since suffered bit rot 1362and Jon Broome has dropped off the face of the earth! 1363(Jon, if you are out there, drop me a line) 1364.SH AVAILABILITY |
1365The latest version of | 1365The latest version of |
1366.B expn 1367is available through anonymous ftp at 1368.IR ftp://ftp.idiom.com/pub/muir-programs/expn . 1369.SH AUTHOR 1370.I David Muir Sharnoff\ \ \ \ <muir@idiom.com> | 1366.B expn 1367is available through anonymous ftp at 1368.IR ftp://ftp.idiom.com/pub/muir-programs/expn . 1369.SH AUTHOR 1370.I David Muir Sharnoff\ \ \ \ <muir@idiom.com> |