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

📄 ftp.pl

📁 站点映像程序
💻 PL
📖 第 1 页 / 共 3 页
字号:
#-*-perl-*-# This is a wrapper to the lchat.pl routines that make life easier# to do ftp type work.#### Copyright (C) 1990 - 1998   Lee McLoughlin## Permission to use, copy, and distribute this software and its# documentation for any purpose with or without fee is hereby granted,# provided that the above copyright notice appear in all copies and# that both that copyright notice and this permission notice appear# in supporting documentation.## Permission to modify the software is granted, but not the right to# distribute the modified code.  Modifications are to be distributed# as patches to released version.## This software is provided "as is" without express or implied warranty.### based on original version by Alan R. Martello <al@ee.pitt.edu># And by A.Macpherson@bnr.co.uk for multi-homed hosts### Basic usage:#  require 'ftp.pl';#  $ftp_port = 21;#  $retry_call = 1;#  $attempts = 2;#  if( &ftp'open( $site, $ftp_port, $retry_call, $attempts ) != 1 ){#   die "failed to open ftp connection";#  }#  if( ! &ftp'login( $user, $pass ) ){#   die "failed to login";#  }#  &ftp'type( $text_mode ? 'A' : 'I' );#  if( ! &ftp'get( $remote_filename, $local_filename, 0 ) ){#   die "failed to get file";#  }#  &ftp'close();### $Id: ftp.pl,v 2.9 1998/05/29 19:02:00 lmjm Exp lmjm $# $Log: ftp.pl,v $# Revision 2.9  1998/05/29 19:02:00  lmjm# Lots of changes.  See CHANGES since 2.8 file.## Revision 2.6  1994/06/06  18:37:37  lmjm# Switched to lchat - a subset of chat.# Allow for 'remote help's need to parse the help strings in the continuations# Use real_site for proxy connections.# Allow for cr stripping and corrected use of buffer (from Andrew).## Revision 2.5  1994/04/29  20:11:04  lmjm# Converted to use rfc1123.## Revision 2.4  1994/01/26  14:59:07  lmjm# Added DG result code.## Revision 2.3  1994/01/18  21:58:18  lmjm# Reduce calls to sigset.# Reset to old signal after use.## Revision 2.2  1993/12/14  11:09:06  lmjm# Use installed socket.ph.# Allow for more returns.## Revision 2.1  1993/06/28  15:02:00  lmjm# Full 2.1 release### lchat.pl is a special subset of chat2.pl that avoids some memory leaks.# This will drag in the correct socket libraryrequire 'lchat.pl';package ftp;$retry_pause = 60;	# Pause before retrying a login.# If the remote ftp daemon doesn't respond within this time presume its dead# or something.$timeout = 120;# Timeout a read if I don't get data back within this many seconds$timeout_read = 3 * $timeout;# Timeout an open$timeout_open = $timeout;$version = '$Revision: 2.9 $';# This is a "global" it contains the last response from the remote ftp server# for use in error messages$ftp'response = "";# Also ftp'NS is the socket containing the data coming in from the remote ls# command.# The size of block to be read or written when talking to the remote# ftp server$ftpbufsize = 4096;# How often to print a hash out, when debugging$hashevery = 1024;# Output a newline after this many hashes to prevent outputing very long lines$hashnl = 70;# Is there a connection open?$service_open = 0;# If a proxy connection then who am I really talking to?$real_site = "";# "Global" Where error/log reports are sent to$ftp'showfd = 'STDERR';# Should a 421 be treated as a connection close and return 99 from# ftp'expect.  This is against rfc1123 recommendations but I've found# it to be a wise default.$ftp'drop_on_421 = 1;# Name of a function to call on a pathname to map it into a remote# pathname.$mapunixout = '';$mapunixin = '';# This is just a tracing aid.$ftp_show = 0;# Global set on a error that aborts the connection$ftp'fatalerror = 0;# Whether to keep the continuation messages so the user can look at them$keep_continuations = 0;# Used in select() statements in read().$read_in = undef;# should we use the PASV extension to the ftp protocol?$ftp'use_pasv = 0;    # 0=no (default), 1=yes# Variable only used if proxying$proxy = $proxy_gateway = $proxy_ftp_port = '';# EXPERIMENTAL:# Used for skey password handling# (Normally set elsewhere - this is just a sensible default.)# Is expected to take count and code as arguments and prompt# for the secret key  with 'password:' on stdout and then print the password.$ftp'keygen_prog = '/usr/local/bin/key';# Uncomment to turn on lots of debugging.# &debug( 10 );# Limit how much data any one ftp'get can pull back# Negative values cause the size check to be skipped.$max_get_size = -1;# Where I am connected to.$connect_site = '';# &ftp'debug( debugging_level )# Turn on debugging ranging from 1 = some to 10 = everythingsub ftp'debug{	$ftp_show = $_[0];	if( $ftp_show > 9 ){		$chat'debug = 1;	}}# &ftp'set_timeout( seconds )sub ftp'set_timeout{	local( $to ) = @_;	return if $to == $timeout;	$timeout = $to;	$timeout_open = $timeout;	$timeout_read = 3 * $timeout;	if( $ftp_show ){		print $showfd "ftp timeout set to $timeout\n";	}}sub open_alarm{	die "timeout: open";}sub timed_open{	local( $site, $ftp_port, $retry_call, $attempts ) = @_;	local( $connect_port );	local( $ret );	&alarm( $timeout_open );	while( $attempts-- ){		if( $ftp_show ){			print $showfd "proxy connecting via $proxy_gateway [$proxy_ftp_port]\n" if $proxy;			print $showfd "Connecting to $site";			if( $ftp_port != 21 ){				print $showfd " [port $ftp_port]";			}			print $showfd "\n";		}				if( $proxy ) {			if( ! $proxy_gateway ) {				# if not otherwise set				$proxy_gateway = "internet-gateway";			}			if( $debug ) {				print $showfd "using proxy services of $proxy_gateway, ";				print $showfd "at $proxy_ftp_port\n";			}			$connect_site = $proxy_gateway;			$connect_port = $proxy_ftp_port;			$real_site = $site;		}		else {			$connect_site = $site;			$connect_port = $ftp_port;		}		if( ! &chat'open_port( $connect_site, $connect_port ) ){			if( $retry_call ){				print $showfd "Failed to connect\n" if $ftp_show;				next;			}			else {				print $showfd "proxy connection failed " if $proxy;				print $showfd "Cannot open ftp to $connect_site\n" if $ftp_show;				return 0;			}		}		$ret = &expect( $timeout,			2, 1 ); # ready for login to $site		if( $ret != 1 ){			&chat'close();			next;		}		return 1;	}	continue {		print $showfd "Pausing between retries\n";		sleep( $retry_pause );	}	return 0;}# Routine called when a signal raised.sub ftp__sighandler{	local( $sig ) = @_;	local( $msg ) = "Caught a SIG$sig flagging connection down";	$service_open = 0;	if( $ftp_logger ){		eval "&$ftp_logger( \$msg )";	}}# Setup a signal handler for possible errors.sub ftp'set_signals{	$ftp_logger = @_;	$SIG{ 'PIPE' } = "ftp'ftp__sighandler";}# &ftp'set_namemap( function to map outgoing name,  function to map incoming )sub ftp'set_namemap{	($mapunixout, $mapunixin) = @_;	if( $debug ) {		print $showfd "mapunixout = $mapunixout, $mapunixin = $mapunixin\n";	}}# &ftp'open( hostname or address,#            port to use,#            retry on call failure,#	     number of attempts to retry )# returns 1 if connected, 0 otherwisesub ftp'open{	local( $site, $ftp_port, $retry_call, $attempts ) = @_;	$site =~ s/\s//g;	local( $old_sig ) = $SIG{ 'ALRM' };	if( ! defined $old_sig ){	    $old_sig = '';	}	$SIG{ 'ALRM' } = "ftp\'open_alarm";	local( $ret ) = eval "&timed_open( '$site', $ftp_port, $retry_call, $attempts )";	&alarm( 0 );	$SIG{ 'ALRM' } = $old_sig;	if( $@ =~ /^timeout/ ){		return -1;	}	if( $ret ){		$service_open = 1;	}	return $ret;}# &ftp'login( user, password, account )# the account part is optional unless the remote service requires one.sub ftp'login{	local( $remote_user, $remote_password, $remote_account ) = @_;        local( $ret );	if( ! $service_open ){		return 0;	}	if( $proxy ){		# Should site or real_site be used here?		&send( "USER $remote_user\@$real_site" );	}	else {		&send( "USER $remote_user" );	}	# Loop to ignore any remote banner (from proxy)	$ret = &expect( $timeout,		       2, 1,   # $remote_user logged in		       331, 2,   # send password for $remote_user		       332, 2 ); # account for login - not yet supported	if( $ret == 99 ){		&service_closed();		$ret = 0;	}	if( $ret == 1 ){		# Logged in no password needed		return 1;	}	elsif( $ret == 2 ){		# A password is needed		# check for s/key challenge - eg, [s/key 994 ph29005]		# If we are talking to skey then use remote_password as the		# secret to generate a real password		if( $ftp'response =~ m#\[s/key (\d+) (\w+)\]# ){			local( $count, $code ) = ($1, $2);			# TODO: report open failure & remove need for echo			open( SKEY, "echo $remote_password | $ftp'keygen_prog $count $code |" );			while( <SKEY> ){				if( ! /password:/ ){					chop( $remote_password = $_ );				}			}			close SKEY;			print $showfd "skey pass: $remote_password\n";		}		&send( "PASS $remote_password" );		$ret = &expect( $timeout,			332, 2, # need extra account for login			2, 1 ); # $remote_user logged in		if( $ret == 99 ){			&service_closed();		}		elsif( $ret == 1 ){			# Logged in			return 1;		}		elsif( $ret == 2 ){			if( !defined( $remote_account ) || $remote_account eq '' ){				&service_closed();				$ret = 0;			}			&send( "ACCT $remote_account");			$ret = &expect( $timeout,				230, 1, # $remote_user logged in				202, 0, # command not implemented				332, 0, # account for login not supported				5, 0, # not logged in or error				421, 99 ); # service unavailable, closing connection			if( $ret == 99 ){				&service_closed();				$ret = 0;			}			if( $ret == 1 ){				# Logged in				return 1;			}		}	}	# If I got here I failed to login	return 0;}sub service_closed{	$service_open = 0;	&chat'close();}# Close down the current ftp connecting in an orderly way.sub ftp'close{	&quit();	$service_open = 0;	&chat'close();}# &ftp'cwd( directory )# Change to the given directory# return 1 if successful, 0 otherwisesub ftp'cwd{	local( $dir ) = @_;	local( $ret );	if( ! $service_open ){		return 0;	}	if( $mapunixout ){		$dir = eval "&$mapunixout( \$dir, 'd' )";	}	&send( "CWD $dir" );	$ret = &expect( $timeout,		2, 1 ); # working directory = $dir	if( $ret == 99 ){		&service_closed();		$ret = 0;	}	return $ret;}# Send the PASV option to the remote server# &pasv()# Gets: nothing# Returns: nothing# Assumptions: you are connecting to an ftp server that implements PASV.# The PASV is necessary when using SOCKS and firewalls because the firewall# acts as a proxy.sub pasv{	# At some point I need to close/free S2, no?	unless( socket( S2, $main'pf_inet, $main'sock_stream, $main'tcp_proto ) ){		($!) = ($!, close(S2)); # close S2 while saving $!		return undef;	}	&send( "PASV" );	$ret = &expect( $timeout,		150, 0, # reading directory		227, 1, # entering passive mode		125, 1, # data connection already open? transfer starting			   		4, 0, # file unavailable		5, 0, # error		        421, 99 ); # service unavailable, closing connection	if( $ret == 99 ){		&service_closed();		$ret = 0;	}	if( ! $ret ){		&close_data_socket;		return 0;	}	if( $ret == 1 ) {		if( $response =~ m/^227 Entering Passive Mode \((\d+),(\d+),(\d+),(\d+),(\d+),(\d+)\)/ ){			$newhost = sprintf( "%d.%d.%d.%d", $1, $2, $3, $4 );			$newport = $5 * 256 + $6;		}		else {			print $showfd "Cannot parse passive response\n" if $ftp_show;			return 0;		}	}	# now need to connect() the new socket	if( ! &chat'open_newport( $newhost, $newport, *S2 ) ){		if( $retry_call ){			print $showfd "Failed to connect newport\n" if $ftp_show;			next;		}		else {			print $showfd "proxy connection failed " if $proxy;			print $showfd "Cannot open pasv ftp to $connect_site\n" if $ftp_show;			return 0;		}	}}# &ftp'dir( remote LIST options )# Start a list going with the given options.# Presuming that the remote deamon uses the ls command to generate the# data to send back then then you can send it some extra options (eg: -lRa)# return 1 if sucessful, 0 otherwisesub ftp'dir_open{	local( $options ) = @_;	local( $ret );		if( ! $service_open ){		return 0;	}	if( ! &open_data_socket() ){		return 0;	}	if( $use_pasv ){		&pasv();	}	if( $options ){		&send( "LIST $options" );	}	else {		&send( "LIST" );	}		$ret = &expect( $timeout,		1, 1 ); # reading directory	if( $ret == 99 ){

⌨️ 快捷键说明

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