summaryrefslogtreecommitdiffstats
path: root/Lib/ftplib.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/ftplib.py')
-rw-r--r--Lib/ftplib.py54
1 files changed, 42 insertions, 12 deletions
diff --git a/Lib/ftplib.py b/Lib/ftplib.py
index dc66241..22852bc 100644
--- a/Lib/ftplib.py
+++ b/Lib/ftplib.py
@@ -1,6 +1,8 @@
# An FTP client class. Based on RFC 959: File Transfer Protocol
# (FTP), by J. Postel and J. Reynolds
+# Changes and improvements suggested by Steve Majewski
+
# Example:
#
@@ -70,6 +72,8 @@ class FTP:
# New 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, *args):
# Initialize the instance to something mostly harmless
self.debugging = 0
@@ -79,7 +83,9 @@ class FTP:
self.file = None
self.welcome = None
if args:
- apply(self.connect, args)
+ self.connect(args[0])
+ if args[1:]:
+ apply(self.login, args[1:])
# Old init method (explicitly called by caller)
def init(self, *args):
@@ -89,7 +95,7 @@ class FTP:
# Connect to host. Arguments:
# - host: hostname to connect to (default previous host)
# - port: port to connect to (default previous port)
- def init(self, *args):
+ def connect(self, *args):
if args: self.host = args[0]
if args[1:]: self.port = args[1]
if args[2:]: raise TypeError, 'too many args'
@@ -97,7 +103,6 @@ class FTP:
self.sock.connect(self.host, self.port)
self.file = self.sock.makefile('r')
self.welcome = self.getresp()
- return self
# Get the welcome message from the server
# (this is read and squirreled away by init())
@@ -276,8 +281,14 @@ class FTP:
# Retrieve data in line mode.
# The argument is a RETR or LIST command.
# The callback function is called for each line, with trailing
- # CRLF stripped. This creates a new port for you
- def retrlines(self, cmd, callback):
+ # CRLF stripped. This creates a new port for you.
+ # print_lines is the default callback
+ def retrlines(self, cmd, args):
+ callback = None
+ if args:
+ callback = args[0]
+ if args[1:]: raise TypeError, 'too many args'
+ if not callback: callback = print_line
resp = self.sendcmd('TYPE A')
conn = self.transfercmd(cmd)
fp = conn.makefile('r')
@@ -328,6 +339,20 @@ class FTP:
self.retrlines(cmd, files.append)
return files
+ # 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.)
+ def dir(self, *args):
+ 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)
+
# Rename a file
def rename(self, fromname, toname):
resp = self.sendcmd('RNFR ' + fromname)
@@ -338,9 +363,13 @@ class FTP:
# Change to a directory
def cwd(self, dirname):
if dirname == '..':
- cmd = 'CDUP'
- else:
- cmd = 'CWD ' + dirname
+ try:
+ self.voidcmd('CDUP')
+ return
+ except error_perm, msg:
+ if msg[:3] != '500':
+ raise error_perm, msg
+ cmd = 'CWD ' + dirname
self.voidcmd(cmd)
# Retrieve the size of a file
@@ -390,6 +419,10 @@ def parse257(resp):
dirname = dirname + c
return dirname
+# Default retrlines callback to print a line
+def print_line(line):
+ print line
+
# Test program.
# Usage: ftp [-d] host [-l[dir]] [-d[dir]] [file] ...
@@ -409,12 +442,9 @@ def test():
ftp = FTP(host)
ftp.set_debuglevel(debugging)
ftp.login()
- def writeln(line): print line
for file in sys.argv[2:]:
if file[:2] == '-l':
- cmd = 'LIST'
- if file[2:]: cmd = cmd + ' ' + file[2:]
- ftp.retrlines(cmd, writeln)
+ ftp.dir(file[2:])
elif file[:2] == '-d':
cmd = 'CWD'
if file[2:]: cmd = cmd + ' ' + file[2:]