"""An FTP client class and some helper functions.

Based on RFC 959: File Transfer Protocol (FTP), by J. Postel and J. Reynolds

Example:

>>> from ftplib import FTP
>>> ftp = FTP('ftp.python.org') # connect to host, default port
>>> ftp.login() # default, i.e.: user anonymous, passwd user@hostname
'230 Guest login ok, access restrictions apply.'
>>> ftp.retrlines('LIST') # list directory contents
total 9
drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 .
drwxr-xr-x   8 root     wheel        1024 Jan  3  1994 ..
drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 bin
drwxr-xr-x   2 root     wheel        1024 Jan  3  1994 etc
d-wxrwxr-x   2 ftp      wheel        1024 Sep  5 13:43 incoming
drwxr-xr-x   2 root     wheel        1024 Nov 17  1993 lib
drwxr-xr-x   6 1094     wheel        1024 Sep 13 19:07 pub
drwxr-xr-x   3 root     wheel        1024 Jan  3  1994 usr
-rw-r--r--   1 root     root          312 Aug  1  1994 welcome.msg
'226 Transfer complete.'
>>> ftp.quit()
'221 Goodbye.'
>>> 

A nice test that reveals some of the network dialogue would be:
python ftplib.py -d localhost -l -p -l
"""

# 
# Changes and improvements suggested by Steve Majewski.
# Modified by Jack to work on the mac.
# Modified by Siebren to support docstrings and PASV.
#

import os
import sys
import string

# Import SOCKS module if it exists, else standard socket module socket
try:
	import SOCKS; socket = SOCKS; del SOCKS # import SOCKS as socket
	from socket import getfqdn; socket.getfqdn = getfqdn; del getfqdn
except ImportError:
	import socket


# Magic number from <socket.h>
MSG_OOB = 0x1				# Process data out of band


# The standard FTP server control port
FTP_PORT = 21


# Exception raised when an error or invalid response is received
class Error(Exception): pass
class error_reply(Error): pass		# unexpected [123]xx reply
class error_temp(Error): pass		# 4xx errors
class error_perm(Error): pass		# 5xx errors
class error_proto(Error): pass		# response does not begin with [1-5]


# All exceptions (hopefully) that may be raised here and that aren't
# (always) programming errors on our side
all_errors = (Error, socket.error, IOError, EOFError)


# Line terminators (we always output CRLF, but accept any of CRLF, CR, LF)
CRLF = '\r\n'


# The class itself
class FTP:

	'''An FTP client class.

	To create a connection, call the class using these argument:
		host, user, passwd, acct
	These are all strings, and have default value ''.
	Then use self.connect() with optional host and port argument.

	To download a file, use ftp.retrlines('RETR ' + filename),
	or ftp.retrbinary() with slightly different arguments.
	To upload a file, use ftp.storlines() or ftp.storbinary(),
	which have an open file as argument (see their definitions
	below for details).
	The download/upload functions first issue appropriate TYPE
	and PORT or PASV commands.
'''

	# Initialization method (called by class instantiation).
	# Initialize host to localhost, port to standard ftp port
	# Optional arguments are host (for connect()),
	# and user, passwd, acct (for login())
	def __init__(self, host = '', user = '', passwd = '', acct = ''):
		# Initialize the instance to something mostly harmless
		self.debugging = 0
		self.host = ''
		self.port = FTP_PORT
		self.sock = None
		self.file = None
		self.welcome = None
		resp = None
		if host:
			resp = self.connect(host)
			if user: resp = self.login(user, passwd, acct)

	def connect(self, host = '', port = 0):
		'''Connect to host.  Arguments are:
		- host: hostname to connect to (string, default previous host)
		- port: port to connect to (integer, default previous port)'''
		if host: self.host = host
		if port: self.port = port
		self.passiveserver = 0
		self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		self.sock.connect((self.host, self.port))
		self.file = self.sock.makefile('rb')
		self.welcome = self.getresp()
		return self.welcome

	def getwelcome(self):
		'''Get the welcome message from the server.
		(this is read and squirreled away by connect())'''
		if self.debugging:
			print '*welcome*', self.sanitize(self.welcome)
		return self.welcome

	def set_debuglevel(self, level):
		'''Set the debugging level.
		The required argument level means:
		0: no debugging output (default)
		1: print commands and responses but not body text etc.
		2: also print raw lines read and sent before stripping CR/LF'''
		self.debugging = level
	debug = set_debuglevel

	def set_pasv(self, val):
		'''Use passive or active mode for data transfers.
		With a false argument, use the normal PORT mode,
		With a true argument, use the PASV command.'''
		self.passiveserver = val

	# Internal: "sanitize" a string for printing
	def sanitize(self, s):
		if s[:5] == 'pass ' or s[:5] == 'PASS ':
			i = len(s)
			while i > 5 and s[i-1] in '\r\n':
				i = i-1
			s = s[:5] + '*'*(i-5) + s[i:]
		return `s`

	# Internal: send one line to the server, appending CRLF
	def putline(self, line):
		line = line + CRLF
		if self.debugging > 1: print '*put*', self.sanitize(line)
		self.sock.send(line)

	# Internal: send one command to the server (through putline())
	def putcmd(self, line):
		if self.debugging: print '*cmd*', self.sanitize(line)
		self.putline(line)

	# Internal: return one line from the server, stripping CRLF.
	# Raise EOFError if the connection is closed
	def getline(self):
		line = self.file.readline()
		if self.debugging > 1:
			print '*get*', self.sanitize(line)
		if not line: raise EOFError
		if line[-2:] == CRLF: line = line[:-2]
		elif line[-1:] in CRLF: line = line[:-1]
		return line

	# Internal: get a response from the server, which may possibly
	# consist of multiple lines.  Return a single string with no
	# trailing CRLF.  If the response consists of multiple lines,
	# these are separated by '\n' characters in the string
	def getmultiline(self):
		line = self.getline()
		if line[3:4] == '-':
			code = line[:3]
			while 1:
				nextline = self.getline()
				line = line + ('\n' + nextline)
				if nextline[:3] == code and \
					nextline[3:4] != '-':
					break
		return line

	# Internal: get a response from the server.
	# Raise various errors if the response indicates an error
	def getresp(self):
		resp = self.getmultiline()
		if self.debugging: print '*resp*', self.sanitize(resp)
		self.lastresp = resp[:3]
		c = resp[:1]
		if c == '4':
			raise error_temp, resp
		if c == '5':
			raise error_perm, resp
		if c not in '123':
			raise error_proto, resp
		return resp

	def voidresp(self):
		"""Expect a response beginning with '2'."""
		resp = self.getresp()
		if resp[0] != '2':
			raise error_reply, resp
		return resp

	def abort(self):
		'''Abort a file transfer.  Uses out-of-band data.
		This does not follow the procedure from the RFC to send Telnet
		IP and Synch; that doesn't seem to work with the servers I've
		tried.  Instead, just send the ABOR command as OOB data.'''
		line = 'ABOR' + CRLF
		if self.debugging > 1: print '*put urgent*', self.sanitize(line)
		self.sock.send(line, MSG_OOB)
		resp = self.getmultiline()
		if resp[:3] not in ('426', '226'):
			raise error_proto, resp

	def sendcmd(self, cmd):
		'''Send a command and return the response.'''
		self.putcmd(cmd)
		return self.getresp()

	def voidcmd(self, cmd):
		"""Send a command and expect a response beginning with '2'."""
		self.putcmd(cmd)
		return self.voidresp()

	def sendport(self, host, port):
		'''Send a PORT command with the current host and the given
		port number.
		'''
		hbytes = string.splitfields(host, '.')
		pbytes = [`port/256`, `port%256`]
		bytes = hbytes + pbytes
		cmd = 'PORT ' + string.joinfields(bytes, ',')
		return self.voidcmd(cmd)

	def makeport(self):
		'''Create a new socket and send a PORT command for it.'''
		global nextport
		sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		sock.bind(('', 0))
		sock.listen(1)
		dummyhost, port = sock.getsockname() # Get proper port
		host, dummyport = self.sock.getsockname() # Get proper host
		resp = self.sendport(host, port)
		return sock

	def ntransfercmd(self, cmd, rest=None):
		"""Initiate a transfer over the data connection.

		If the transfer is active, send a port command and the
		transfer command, and accept the connection.  If the server is
		passive, send a pasv command, connect to it, and start the
		transfer command.  Either way, return the socket for the
		connection and the expected size of the transfer.  The
		expected size may be None if it could not be determined.

		Optional `rest' argument can be a string that is sent as the
		argument to a RESTART command.  This is essentially a server
		marker used to tell the server to skip over any data up to the
		given marker.
		"""
		size = None
		if self.passiveserver:
			host, port = parse227(self.sendcmd('PASV'))
			conn=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			conn.connect((host, port))
			if rest is not None:
				self.sendcmd("REST %s" % rest)
			resp = self.sendcmd(cmd)
			if resp[0] != '1':
				raise error_reply, resp
		else:
			sock = self.makeport()
			if rest is not None:
				self.sendcmd("REST %s" % rest)
			resp = self.sendcmd(cmd)
			if resp[0] != '1':
				raise error_reply, resp
			conn, sockaddr = sock.accept()
		if resp[:3] == '150':
			# this is conditional in case we received a 125
			size = parse150(resp)
		return conn, size

	def transfercmd(self, cmd, rest=None):
		"""Like nstransfercmd() but returns only the socket."""
		return self.ntransfercmd(cmd, rest)[0]

	def login(self, user = '', passwd = '', acct = ''):
		'''Login, default anonymous.'''
		if not user: user = 'anonymous'
		if not passwd: passwd = ''
		if not acct: acct = ''
		if user == 'anonymous' and passwd in ('', '-'):
			# get fully qualified domain name of local host
			thishost = socket.getfqdn()
			try:
				if os.environ.has_key('LOGNAME'):
					realuser = os.environ['LOGNAME']
				elif os.environ.has_key('USER'):
					realuser = os.environ['USER']
				else:
					realuser = 'anonymous'
			except AttributeError:
				# Not all systems have os.environ....
				realuser = 'anonymous'
			passwd = passwd + realuser + '@' + thishost
		resp = self.sendcmd('USER ' + user)
		if resp[0] == '3': resp = self.sendcmd('PASS ' + passwd)
		if resp[0] == '3': resp = self.sendcmd('ACCT ' + acct)
		if resp[0] != '2':
			raise error_reply, resp
		return resp

	def retrbinary(self, cmd, callback, blocksize=8192, rest=None):
		"""Retrieve data in binary mode.
		
		`cmd' is a RETR command.  `callback' is a callback function is
		called for each block.  No more than `blocksize' number of
		bytes will be read from the socket.  Optional `rest' is passed
		to transfercmd().

		A new port is created for you.  Return the response code.
		"""
		self.voidcmd('TYPE I')
		conn = self.transfercmd(cmd, rest)
		while 1:
			data = conn.recv(blocksize)
			if not data:
				break
			callback(data)
		conn.close()
		return self.voidresp()

	def retrlines(self, cmd, callback = None):
		'''Retrieve data in line mode.
		The argument is a RETR or LIST command.
		The callback function (2nd argument) is called for each line,
		with trailing CRLF stripped.  This creates a new port for you.
		print_line() is the default callback.'''
		if not callback: callback = print_line
		resp = self.sendcmd('TYPE A')
		conn = self.transfercmd(cmd)
		fp = conn.makefile('rb')
		while 1:
			line = fp.readline()
			if self.debugging > 2: print '*retr*', `line`
			if not line:
				break
			if line[-2:] == CRLF:
				line = line[:-2]
			elif line[-1:] == '\n':
				line = line[:-1]
			callback(line)
		fp.close()
		conn.close()
		return self.voidresp()

	def storbinary(self, cmd, fp, blocksize):
		'''Store a file in binary mode.'''
		self.voidcmd('TYPE I')
		conn = self.transfercmd(cmd)
		while 1:
			buf = fp.read(blocksize)
			if not buf: break
			conn.send(buf)
		conn.close()
		return self.voidresp()

	def storlines(self, cmd, fp):
		'''Store a file in line mode.'''
		self.voidcmd('TYPE A')
		conn = self.transfercmd(cmd)
		while 1:
			buf = fp.readline()
			if not buf: break
			if buf[-2:] != CRLF:
				if buf[-1] in CRLF: buf = buf[:-1]
				buf = buf + CRLF
			conn.send(buf)
		conn.close()
		return self.voidresp()

	def acct(self, password):
		'''Send new account name.'''
		cmd = 'ACCT ' + password
		return self.voidcmd(cmd)

	def nlst(self, *args):
		'''Return a list of files in a given directory (default the current).'''
		cmd = 'NLST'
		for arg in args:
			cmd = cmd + (' ' + arg)
		files = []
		self.retrlines(cmd, files.append)
		return files

	def dir(self, *args):
		'''List a directory in long form.
		By default list current directory to stdout.
		Optional last argument is callback function; all
		non-empty arguments before it are concatenated to the
		LIST command.  (This *should* only be used for a pathname.)'''
		cmd = 'LIST' 
		func = None
		if args[-1:] and type(args[-1]) != type(''):
			args, func = args[:-1], args[-1]
		for arg in args:
			if arg:
				cmd = cmd + (' ' + arg) 
		self.retrlines(cmd, func)

	def rename(self, fromname, toname):
		'''Rename a file.'''
		resp = self.sendcmd('RNFR ' + fromname)
		if resp[0] != '3':
			raise error_reply, resp
		return self.voidcmd('RNTO ' + toname)

	def delete(self, filename):
		'''Delete a file.'''
		resp = self.sendcmd('DELE ' + filename)
		if resp[:3] in ('250', '200'):
			return resp
		elif resp[:1] == '5':
			raise error_perm, resp
		else:
			raise error_reply, resp

	def cwd(self, dirname):
		'''Change to a directory.'''
		if dirname == '..':
			try:
				return self.voidcmd('CDUP')
			except error_perm, msg:
				if msg[:3] != '500':
					raise error_perm, msg
		elif dirname == '':
			dirname = '.'  # does nothing, but could return error
		cmd = 'CWD ' + dirname
		return self.voidcmd(cmd)

	def size(self, filename):
		'''Retrieve the size of a file.'''
		# Note that the RFC doesn't say anything about 'SIZE'
		resp = self.sendcmd('SIZE ' + filename)
		if resp[:3] == '213':
			return string.atoi(string.strip(resp[3:]))

	def mkd(self, dirname):
		'''Make a directory, return its full pathname.'''
		resp = self.sendcmd('MKD ' + dirname)
		return parse257(resp)

	def rmd(self, dirname):
		'''Remove a directory.'''
		return self.voidcmd('RMD ' + dirname)

	def pwd(self):
		'''Return current working directory.'''
		resp = self.sendcmd('PWD')
		return parse257(resp)

	def quit(self):
		'''Quit, and close the connection.'''
		resp = self.voidcmd('QUIT')
		self.close()
		return resp

	def close(self):
		'''Close the connection without assuming anything about it.'''
		self.file.close()
		self.sock.close()
		del self.file, self.sock


_150_re = None

def parse150(resp):
	'''Parse the '150' response for a RETR request.
	Returns the expected transfer size or None; size is not guaranteed to
	be present in the 150 message.
	'''
	if resp[:3] != '150':
		raise error_reply, resp
	global _150_re
	if _150_re is None:
		import re
		_150_re = re.compile("150 .* \((\d+) bytes\)", re.IGNORECASE)
	m = _150_re.match(resp)
	if m:
		return string.atoi(m.group(1))
	return None


def parse227(resp):
	'''Parse the '227' response for a PASV request.
	Raises error_proto if it does not contain '(h1,h2,h3,h4,p1,p2)'
	Return ('host.addr.as.numbers', port#) tuple.'''

	if resp[:3] != '227':
		raise error_reply, resp
	left = string.find(resp, '(')
	if left < 0: raise error_proto, resp
	right = string.find(resp, ')', left + 1)
	if right < 0:
		raise error_proto, resp	# should contain '(h1,h2,h3,h4,p1,p2)'
	numbers = string.split(resp[left+1:right], ',')
	if len(numbers) != 6:
		raise error_proto, resp
	host = string.join(numbers[:4], '.')
	port = (string.atoi(numbers[4]) << 8) + string.atoi(numbers[5])
	return host, port


def parse257(resp):
	'''Parse the '257' response for a MKD or PWD request.
	This is a response to a MKD or PWD request: a directory name.
	Returns the directoryname in the 257 reply.'''

	if resp[:3] != '257':
		raise error_reply, resp
	if resp[3:5] != ' "':
		return '' # Not compliant to RFC 959, but UNIX ftpd does this
	dirname = ''
	i = 5
	n = len(resp)
	while i < n:
		c = resp[i]
		i = i+1
		if c == '"':
			if i >= n or resp[i] != '"':
				break
			i = i+1
		dirname = dirname + c
	return dirname


def print_line(line):
	'''Default retrlines callback to print a line.'''
	print line


def ftpcp(source, sourcename, target, targetname = '', type = 'I'):
	'''Copy file from one FTP-instance to another.'''
	if not targetname: targetname = sourcename
	type = 'TYPE ' + type
	source.voidcmd(type)
	target.voidcmd(type)
	sourcehost, sourceport = parse227(source.sendcmd('PASV'))
	target.sendport(sourcehost, sourceport)
	# RFC 959: the user must "listen" [...] BEFORE sending the
	# transfer request.
	# So: STOR before RETR, because here the target is a "user".
	treply = target.sendcmd('STOR ' + targetname)
	if treply[:3] not in ('125', '150'): raise error_proto	# RFC 959
	sreply = source.sendcmd('RETR ' + sourcename)
	if sreply[:3] not in ('125', '150'): raise error_proto	# RFC 959
	source.voidresp()
	target.voidresp()


class Netrc:
	"""Class to parse & provide access to 'netrc' format files.

	See the netrc(4) man page for information on the file format.

	WARNING: This class is obsolete -- use module netrc instead.

	"""
	__defuser = None
	__defpasswd = None
	__defacct = None

	def __init__(self, filename=None):
		if not filename:
			if os.environ.has_key("HOME"):
				filename = os.path.join(os.environ["HOME"],
							".netrc")
			else:
				raise IOError, \
				      "specify file to load or set $HOME"
		self.__hosts = {}
		self.__macros = {}
		fp = open(filename, "r")
		in_macro = 0
		while 1:
			line = fp.readline()
			if not line: break
			if in_macro and string.strip(line):
				macro_lines.append(line)
				continue
			elif in_macro:
				self.__macros[macro_name] = tuple(macro_lines)
				in_macro = 0
			words = string.split(line)
			host = user = passwd = acct = None
			default = 0
			i = 0
			while i < len(words):
				w1 = words[i]
				if i+1 < len(words):
					w2 = words[i + 1]
				else:
					w2 = None
				if w1 == 'default':
					default = 1
				elif w1 == 'machine' and w2:
					host = string.lower(w2)
					i = i + 1
				elif w1 == 'login' and w2:
					user = w2
					i = i + 1
				elif w1 == 'password' and w2:
					passwd = w2
					i = i + 1
				elif w1 == 'account' and w2:
					acct = w2
					i = i + 1
				elif w1 == 'macdef' and w2:
					macro_name = w2
					macro_lines = []
					in_macro = 1
					break
				i = i + 1
			if default:
				self.__defuser = user or self.__defuser
				self.__defpasswd = passwd or self.__defpasswd
				self.__defacct = acct or self.__defacct
			if host:
				if self.__hosts.has_key(host):
					ouser, opasswd, oacct = \
					       self.__hosts[host]
					user = user or ouser
					passwd = passwd or opasswd
					acct = acct or oacct
				self.__hosts[host] = user, passwd, acct
		fp.close()

	def get_hosts(self):
		"""Return a list of hosts mentioned in the .netrc file."""
		return self.__hosts.keys()

	def get_account(self, host):
		"""Returns login information for the named host.

		The return value is a triple containing userid,
		password, and the accounting field.

		"""
		host = string.lower(host)
		user = passwd = acct = None
		if self.__hosts.has_key(host):
			user, passwd, acct = self.__hosts[host]
		user = user or self.__defuser
		passwd = passwd or self.__defpasswd
		acct = acct or self.__defacct
		return user, passwd, acct

	def get_macros(self):
		"""Return a list of all defined macro names."""
		return self.__macros.keys()

	def get_macro(self, macro):
		"""Return a sequence of lines which define a named macro."""
		return self.__macros[macro]



def test():
	'''Test program.
	Usage: ftp [-d] [-r[file]] host [-l[dir]] [-d[dir]] [-p] [file] ...'''

	debugging = 0
	rcfile = None
	while sys.argv[1] == '-d':
		debugging = debugging+1
		del sys.argv[1]
	if sys.argv[1][:2] == '-r':
		# get name of alternate ~/.netrc file:
		rcfile = sys.argv[1][2:]
		del sys.argv[1]
	host = sys.argv[1]
	ftp = FTP(host)
	ftp.set_debuglevel(debugging)
	userid = passwd = acct = ''
	try:
		netrc = Netrc(rcfile)
	except IOError:
		if rcfile is not None:
			sys.stderr.write("Could not open account file"
					 " -- using anonymous login.")
	else:
		try:
			userid, passwd, acct = netrc.get_account(host)
		except KeyError:
			# no account for host
			sys.stderr.write(
				"No account -- using anonymous login.")
	ftp.login(userid, passwd, acct)
	for file in sys.argv[2:]:
		if file[:2] == '-l':
			ftp.dir(file[2:])
		elif file[:2] == '-d':
			cmd = 'CWD'
			if file[2:]: cmd = cmd + ' ' + file[2:]
			resp = ftp.sendcmd(cmd)
		elif file == '-p':
			ftp.set_pasv(not ftp.passiveserver)
		else:
			ftp.retrbinary('RETR ' + file, \
				       sys.stdout.write, 1024)
	ftp.quit()


if __name__ == '__main__':
	test()
