Dangerous feature added: when removing local files (i.e., only when -r
is used), do a recursive delete.  Use -r with even more caution!
Also changed usage message into a doc string, added a comment or two,
and rearranged a long line.
diff --git a/Tools/scripts/ftpmirror.py b/Tools/scripts/ftpmirror.py
index f25864b..123f479 100755
--- a/Tools/scripts/ftpmirror.py
+++ b/Tools/scripts/ftpmirror.py
@@ -1,12 +1,26 @@
 #! /usr/bin/env python
 
-# Mirror a remote ftp subtree into a local directory tree.
-# Basic usage: ftpmirror [options] host remotedir localdir
-#
+"""Mirror a remote ftp subtree into a local directory tree.
+
+usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat]
+                 [-l username [-p passwd [-a account]]]
+		 hostname [remotedir [localdir]]
+-v: verbose
+-q: quiet
+-i: interactive mode
+-m: macintosh server (NCSA telnet 2.4) (implies -n -s '*.o')
+-n: don't log in
+-r: remove local files/directories no longer pertinent
+-l username [-p passwd [-a account]]: login info (default anonymous ftp)
+-s pat: skip files matching pattern
+hostname: remote host
+remotedir: remote directory (default initial)
+localdir: local directory (default current)
+"""
+
 # XXX To do:
 # - handle symbolic links
 # - back up .mirrorinfo before overwriting
-# - use pickles for .mirrorinfo?
 
 import os
 import sys
@@ -16,26 +30,11 @@
 import ftplib
 from fnmatch import fnmatch
 
-usage_msg = """
-usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat]
-                 [-l username [-p passwd [-a account]]]
-		 hostname [remotedir [localdir]]
--v: verbose
--q: quiet
--i: interactive mode
--m: macintosh server (NCSA telnet 2.4) (implies -n -s '*.o')
--n: don't log in
--r: remove files no longer pertinent
--l username [-p passwd [-a account]]: login info (default anonymous ftp)
--s pat: skip files matching pattern
-hostname: remote host
-remotedir: remote directory (default initial)
-localdir: local directory (default current)
-"""
+# Print usage message and exit
 def usage(*args):
 	sys.stdout = sys.stderr
 	for msg in args: print msg
-	print usage_msg
+	print __doc__
 	sys.exit(2)
 
 verbose = 1 # 0 for -q, 2 for -v
@@ -45,6 +44,7 @@
 nologin = 0
 skippats = ['.', '..', '.mirrorinfo']
 
+# Main program: parse command line and start processing
 def main():
 	global verbose, interactive, mac, rmok, nologin
 	try:
@@ -94,6 +94,7 @@
 	#
 	mirrorsubdir(f, localdir)
 
+# Core logic: mirror one subdirectory (recursively)
 def mirrorsubdir(f, localdir):
 	pwd = f.pwd()
 	if localdir and not os.path.isdir(localdir):
@@ -137,7 +138,7 @@
 				continue
 			if words[-2] == '->':
 				if verbose > 1:
-					print 'Skipping symbolic link %s -> %s' % \
+				    print 'Skipping symbolic link %s -> %s' % \
 						  (words[-3], words[-1])
 				continue
 			filename = words[-1]
@@ -259,12 +260,8 @@
 				print 'Local file', fullname,
 				print 'is no longer pertinent'
 			continue
-		if verbose: print 'Removing local file', fullname
-		try:
-			os.unlink(fullname)
-		except os.error, msg:
-			print "Can't remove local file %s: %s" % \
-				  (fullname, str(msg))
+		if verbose: print 'Removing local file/dir', fullname
+		remove(fullname)
 	#
 	# Recursively mirror subdirectories
 	for subdir in subdirs:
@@ -294,6 +291,34 @@
 		else:
 			if verbose > 1: print 'OK.'
 
+# Helper to remove a file or directory tree
+def remove(fullname):
+	if os.path.isdir(fullname) and not os.path.islink(fullname):
+		try:
+			names = os.listdir(fullname)
+		except os.error:
+			names = []
+		ok = 1
+		for name in names:
+			if not remove(os.path.join(fullname, name)):
+				ok = 0
+		if not ok:
+			return 0
+		try:
+			os.rmdir(fullname)
+		except os.error, msg:
+			print "Can't remove local directory %s: %s" % \
+			      (fullname, str(msg))
+			return 0
+	else:
+		try:
+			os.unlink(fullname)
+		except os.error, msg:
+			print "Can't remove local file %s: %s" % \
+			      (fullname, str(msg))
+			return 0
+	return 1
+
 # Wrapper around a file for writing to write a hash sign every block.
 class LoggingFile:
 	def __init__(self, fp, blocksize, outfp):