⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expn.pl

📁 早期freebsd实现
💻 PL
📖 第 1 页 / 共 3 页
字号:
#!/usr/local/bin/perl'di ';'ds 00 \\"';'ig00 ';##       THIS PROGRAM IS ITS OWN MANUAL PAGE.  INSTALL IN man & bin.## hardcoded constants, should work fine for BSD-based systems$AF_INET = 2;$SOCK_STREAM = 1;$sockaddr = 'S n a4 x8';# system requirements:# 	must have 'nslookup' and 'hostname' programs.# $Header: /home/muir/bin/RCS/expn,v 3.6 1994/02/23 22:26:19 muir Exp muir $# TODO:#	less magic should apply to command-line addresses#	less magic should apply to local addresses#	add magic to deal with cross-domain cnames# Checklist: (hard addresses)#	250 Kimmo Suominen <"|/usr/local/mh/lib/slocal -user kim"@grendel.tac.nyc.ny.us>#	harry@hofmann.cs.Berkeley.EDU -> harry@tenet (.berkeley.edu)  [dead]#	bks@cs.berkeley.edu -> shiva.CS (.berkeley.edu)		      [dead]#	dan@tc.cornell.edu -> brown@tiberius (.tc.cornell.edu)###############################################################################  Copyright (c) 1993 David Muir Sharnoff#  All rights reserved.##  Redistribution and use in source and binary forms, with or without#  modification, are permitted provided that the following conditions#  are met:#  1. Redistributions of source code must retain the above copyright#     notice, this list of conditions and the following disclaimer.#  2. Redistributions in binary form must reproduce the above copyright#     notice, this list of conditions and the following disclaimer in the#     documentation and/or other materials provided with the distribution.#  3. All advertising materials mentioning features or use of this software#     must display the following acknowledgement:#       This product includes software developed by the David Muir Sharnoff.#  4. The name of David Sharnoff may not be used to endorse or promote products#     derived from this software without specific prior written permission.##  THIS SOFTWARE IS PROVIDED BY THE DAVID MUIR SHARNOFF ``AS IS'' AND#  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE#  ARE DISCLAIMED.  IN NO EVENT SHALL DAVID MUIR SHARNOFF BE LIABLE#  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL#  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS#  OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)#  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT#  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY#  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF#  SUCH DAMAGE.## This copyright notice derrived from material copyrighted by the Regents# of the University of California.## Contributions accepted.############################################################################### overall structure:#	in an effort to not trace each address individually, but rather#	ask each server in turn a whole bunch of questions, addresses to#	be expanded are queued up.##	This means that all account w.r.t. an address must be stored in#	various arrays.  Generally these arrays are indexed by the#	string "$addr *** $server" where $addr is the address to be#	expanded "foo" or maybe "foo@bar" and $server is the hostname#	of the SMTP server to contact.## important global variables:## @hosts : list of servers still to be contacted# $server : name of the current we are currently looking at# @users = $users{@hosts[0]} : addresses to expand at this server# $u = $users[0] : the current address being expanded# $names{"$users[0] *** $server"} : the 'name' associated with the address# $mxbacktrace{"$users[0] *** $server"} : record of mx expansion# $mx_secondary{$server} : other mx relays at the same priority# $domainify_fallback{"$users[0] *** $server"} : alternative names to try #	instead of $server if $server doesn't work# $temporary_redirect{"$users[0] *** $server"} : when trying alternates,#	temporarily channel all tries along current path# $giveup{$server} : do not bother expanding addresses at $server# $verbose : -v# $watch : -w# $vw : -v or -w# $debug : -d# $valid : -a# $levels : -1# S : the socket connection to $server$have_nslookup = 1;	# we have the nslookup program$port = 'smtp';$av0 = $0;$0 = "$av0 - running hostname";$ENV{'PATH'} .= ":/usr/etc" unless $ENV{'PATH'} =~ m,/usr/etc,;chop($hostname = `hostname`);select(STDERR);$usage = "Usage: $av0 [-1avwd] user[@host] [user2[host2] ...]";$0 = "$av0 - parsing args";for $a (@ARGV) {	die $usage if $a eq "-";	while ($a =~ s/^(-.*)([1avwd])/$1/) {		eval '$'."flag_$2 += 1";	}	next if $a eq "-";	die $usage if $a =~ /^-/;	&expn(&parse($a,$hostname,undef,1));}$verbose = $flag_v;$watch = $flag_w;$vw = $flag_v + $flag_w;$debug = $flag_d;$valid = $flag_a;$levels = $flag_1;die $usage unless @hosts;if ($valid) {	if ($valid == 1) {		$validRequirement = 0.8;	} elsif ($valid == 2) {		$validRequirement = 1.0;	} elsif ($valid == 3) {		$validRequirement = 0.9;	} else {		$validRequirement = (1 - (1/($valid-3)));		print "validRequirement = $validRequirement\n" if $debug;	}}$0 = "$av0 - building local socket";($name,$aliases,$proto) = getprotobyname('tcp');($name,$aliases,$port) = getservbyname($port,'tcp')	unless $port =~ /^\d+/;($name,$aliases,$type,$len,$thisaddr) = gethostbyname($hostname);$this = pack($sockaddr, $AF_INET, 0, $thisaddr);HOST:while (@hosts) {	$server = shift(@hosts);	@users = split(' ',$users{$server});	delete $users{$server};	# is this server already known to be bad?	$0 = "$av0 - looking up $server";	if ($giveup{$server}) {		&giveup('mx domainify',$giveup{$server});		next;	}	# do we already have an mx record for this host?	next HOST if &mxredirect($server,*users);	# look it up, or try for an mx.	$0 = "$av0 - gethostbyname($server)";	($name,$aliases,$type,$len,$thataddr) = gethostbyname($server);	# if we can't get an A record, try for an MX record.	unless($thataddr) {		&mxlookup(1,$server,"$server: could not resolve name",*users);		next HOST;	}					# get a connection, or look for an mx	$0 = "$av0 - socket to $server";	$that = pack($sockaddr, $AF_INET, $port, $thataddr);	socket(S, $AF_INET, $SOCK_STREAM, $proto)		|| die "socket: $!";	$0 = "$av0 - bind to $server";	bind(S, $this) 		|| die "bind $hostname,0: $!";	$0 = "$av0 - connect to $server";	print "debug = $debug server = $server\n" if $debug > 8;	if (! connect(S, $that) || ($debug == 10 && $server =~ /relay\d.UU.NET$/i)) {		$0 = "$av0 - $server: could not connect: $!\n";		$emsg = $!;		unless (&mxlookup(0,$server,"$server: could not connect: $!",*users)) {			&giveup('mx',"$server: Could not connect: $emsg");		}		next HOST;	}	select((select(S),$| = 1)[0]); # don't buffer output to S	# read the greeting	$0 = "$av0 - talking to $server";	&alarm("greeting with $server",'');	while(<S>) {		alarm(0);		print if $watch;		if (/^(\d+)([- ])/) {			if ($1 != 220) {				$0 = "$av0 - bad numeric responce from $server";				&alarm("giving up after bet responce from $server",'');				&read_response($2,$watch);				alarm(0);				print STDERR "$server: NOT 220 greeting: $_"					if ($debug || $vw);				if (&mxlookup(0,$server,"$server: did not respond with a 220 greeting",*users)) {					close(S);					next HOST;				}			}			last if ($2 eq " ");		} else {			$0 = "$av0 - bad responce from $server";			print STDERR "$server: NOT 220 greeting: $_"				if ($debug || $vw);			unless (&mxlookup(0,$server,"$server: did not respond with SMTP codes",*users)) {				&giveup('',"$server: did not talk SMTP");			}			close(S);			next HOST;		}		&alarm("greeting with $server",'');	}	alarm(0);		# if this causes problems, remove it	$0 = "$av0 - sending helo to $server";	&alarm("sending helo to $server","");	&ps("helo $hostname");	while(<S>) {		print if $watch;		last if /^\d+ /;	}	alarm(0);	# try the users, one by one	USER:	while(@users) {		$u = shift(@users);		$0 = "$av0 - expanding $u [\@$server]";		# do we already have a name for this user?		$oldname = $names{"$u *** $server"};		print &compact($u,$server)." ->\n" if ($verbose && ! $valid);		if ($valid) {			#			# when running with -a, we delay taking any action 			# on the results of our query until we have looked			# at the complete output.  @toFinal stores expansions			# that will be final if we take them.  @toExpn stores			# expnansions that are not final.  @isValid keeps			# track of our ability to send mail to each of the			# expansions.			#			@isValid = ();			@toFinal = ();			@toExpn = ();		}		($ecode,@expansion) = &expn_vrfy($u,$server);		if ($ecode) {			&giveup('',$ecode,$u);			last USER;		}		for $s (@expansion) {			$s =~ s/[\n\r]//g;			$0 = "$av0 - parsing $server: $s";			$skipwatch = $watch;			if ($s =~ /^[25]51([- ]).*<(.+)>/) {				print "$s" if $watch;				print "(pretending 250$1<$2>)" if ($debug && $watch);				print "\n" if $watch;				$s = "250$1<$2>";				$skipwatch = 0;			}			if ($s =~ /^250([- ])(.+)/) {				print "$s\n" if $skipwatch;				($done,$addr) = ($1,$2);				($newhost, $newaddr, $newname) =  &parse($addr,$server,$oldname, $#expansion == 0);				print "($newhost, $newaddr, $newname) = &parse($addr, $server, $oldname)\n" if $debug;				if (! $newhost) {					# no expansion is possible w/o a new server to call					if ($valid) {						push(@isValid, &validAddr($newaddr));						push(@toFinal,$newaddr,$server,$newname);					} else {						&verbose(&final($newaddr,$server,$newname));					}				} else {					$newmxhost = &mx($newhost,$newaddr);					print "$newmxhost = &mx($newhost)\n" 						if ($debug && $newhost ne $newmxhost);					$0 = "$av0 - parsing $newaddr [@$newmxhost]";					print "levels = $levels, level{$u *** $server} = ".$level{"$u *** $server"}."\n" if ($debug > 1);					# If the new server is the current one, 					# it would have expanded things for us					# if it could have.  Mx records must be					# followed to compare server names.					# We are also done if the recursion					# count has been exceeded.					if (&trhost($newmxhost) eq &trhost($server) || ($levels && $level{"$u *** $server"} >= $levels)) {						if ($valid) {							push(@isValid, &validAddr($newaddr));							push(@toFinal,$newaddr,$newmxhost,$newname);						} else {							&verbose(&final($newaddr,$newmxhost,$newname));						}					} else {						# more work to do...						if ($valid) {							push(@isValid, &validAddr($newaddr));							push(@toExpn,$newmxhost,$newaddr,$newname,$level{"$u *** $server"});						} else {							&verbose(&expn($newmxhost,$newaddr,$newname,$level{"$u *** $server"}));						}					}				}				last if ($done eq " ");				next;			}			# 550 is a known code...  Should the be			# included in -a output?  Might be a bug			# here.  Does it matter?  Can assume that			# there won't be UNKNOWN USER responces 			# mixed with valid users?			if ($s =~ /^(550)([- ])/) {				if ($valid) {					print STDERR "\@$server:$u ($oldname) USER UNKNOWN\n";				} else {					&verbose(&final($u,$server,$oldname,"USER UNKNOWN"));				}				last if ($2 eq " ");				next;			} 			# 553 is a known code...  			if ($s =~ /^(553)([- ])/) {				if ($valid) {					print STDERR "\@$server:$u ($oldname) USER AMBIGUOUS\n";				} else {					&verbose(&final($u,$server,$oldname,"USER AMBIGUOUS"));				}				last if ($2 eq " ");				next;			} 			# 252 is a known code...  			if ($s =~ /^(252)([- ])/) {				if ($valid) {					print STDERR "\@$server:$u ($oldname) REFUSED TO VRFY\n";				} else {					&verbose(&final($u,$server,$oldname,"REFUSED TO VRFY"));				}				last if ($2 eq " ");				next;			} 			&giveup('',"$server: did not grok '$s'",$u);			last USER;		}		if ($valid) {			#			# now we decide if we are going to take these			# expansions or roll them back.			#			$avgValid = &average(@isValid);			print "avgValid = $avgValid\n" if $debug;			if ($avgValid >= $validRequirement) {				print &compact($u,$server)." ->\n" if $verbose;				while (@toExpn) {					&verbose(&expn(splice(@toExpn,0,4)));				}				while (@toFinal) {					&verbose(&final(splice(@toFinal,0,3)));				}			} else {				print "Tossing some valid to avoid invalid ".&compact($u,$server)."\n" if ($avgValid > 0.0 && ($vw || $debug));				print &compact($u,$server)." ->\n" if $verbose;				&verbose(&final($u,$server,$newname));			}		}	}	&alarm("sending 'quit' to $server",'');	$0 = "$av0 - sending 'quit' to $server";	&ps("quit");	while(<S>) {		print if $watch;		last if /^\d+ /;	}	close(S);	alarm(0);}$0 = "$av0 - printing final results";print "----------\n" if $vw;select(STDOUT);for $f (sort @final) {	print "$f\n";}unlink("/tmp/expn$$");exit(0);# abandon all attempts deliver to $server# register the current addresses as the final onessub giveup{	local($redirect_okay,$reason,$user) = @_;	local($us,@so,$nh,@remaining_users);	$0 = "$av0 - giving up on $server: $reason";	#	# add back a user if we gave up in the middle	#	push(@users,$user) if $user;	#	# don't bother with this system anymore	#	unless ($giveup{$server}) {		$giveup{$server} = $reason;		print STDERR "$reason\n";	}	print "Giveup!!! redirect okay = $redirect_okay; $reason\n" if $debug;	#	# Wait!	# Before giving up, see if there is a chance that	# there is another host to redirect to!	# (Kids, don't do this at home!  Hacking is a dangerous	# crime and you could end up behind bars.)	#	for $u (@users) {		if ($redirect_okay =~ /\bmx\b/) {			next if &try_fallback('mx',$u,*server,				*mx_secondary,				*already_mx_fellback);		}		if ($redirect_okay =~ /\bdomainify\b/) {			next if &try_fallback('domainify',$u,*server,				*domainify_fallback,				*already_domainify_fellback);		}		push(@remaining_users,$u);	}	@users = @remaining_users;	for $u (@users) {		print &compact($u,$server)." ->\n" if ($verbose && $valid && $u);		&verbose(&final($u,$server,$names{"$u *** $server"},$reason));	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -