'''An FTP client class, and some helper functions.
Based on RFC 959: File Transfer Protocol
(FTP), by J. Postel and J. Reynolds

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


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
'''


import os
import sys
import string

# Import SOCKS module if it exists, else standard socket module socket
try:
    import SOCKS; socket = SOCKS
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
error_reply = 'ftplib.error_reply'	# unexpected [123]xx reply
error_temp = 'ftplib.error_temp'	# 4xx errors
error_perm = 'ftplib.error_perm'	# 5xx errors
error_proto = 'ftplib.error_proto'	# 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_reply, error_temp, error_perm, error_proto, \
	      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):
		'''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.'''
		size = None
		if self.passiveserver:
			host, port = parse227(self.sendcmd('PASV'))
			conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			conn.connect(host, port)
			resp = self.sendcmd(cmd)
			if resp[0] <> '1':
				raise error_reply, resp
		else:
			sock = self.makeport()
			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):
		'''Initiate a transfer over the data connection.  Returns
		the socket for the connection.  See also ntransfercmd().'''
		return self.ntransfercmd(cmd)[0]

	def login(self, user = '', passwd = '', acct = ''):
		'''Login, default anonymous.'''
		if not user: user = 'anonymous'
		if user == 'anonymous' and passwd in ('', '-'):
			thishost = socket.gethostname()
			# Make sure it is fully qualified
			if not '.' in thishost:
			    thisaddr = socket.gethostbyname(thishost)
			    firstname, names, unused = \
				       socket.gethostbyaddr(thisaddr)
			    names.insert(0, firstname)
			    for name in names:
				    if '.' in name:
					    thishost = name
					    break
			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):
		'''Retrieve data in binary mode.
		The argument is a RETR command.
		The callback function is called for each block.
		This creates a new port for you'''
		self.voidcmd('TYPE I')
		conn = self.transfercmd(cmd)
		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_lines 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] == '250':
                        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
		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 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 .* \(([0-9][0-9]*) 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 RMD request.
	This is a response to a MKD or RMD 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.

    """
    __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()
