]> granicus.if.org Git - python/commitdiff
Dangerous feature added: when removing local files (i.e., only when -r
authorGuido van Rossum <guido@python.org>
Sun, 4 Jan 1998 02:03:12 +0000 (02:03 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 4 Jan 1998 02:03:12 +0000 (02:03 +0000)
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.

Tools/scripts/ftpmirror.py

index f25864be497d3ad0720da5e62a57fb2142b8e4a3..123f479956a400c520ed33cb7b09172d0ac3141e 100755 (executable)
@@ -1,22 +1,7 @@
 #! /usr/bin/env python
 
-# Mirror a remote ftp subtree into a local directory tree.
-# Basic usage: ftpmirror [options] host remotedir localdir
-#
-# XXX To do:
-# - handle symbolic links
-# - back up .mirrorinfo before overwriting
-# - use pickles for .mirrorinfo?
-
-import os
-import sys
-import time
-import getopt
-import string
-import ftplib
-from fnmatch import fnmatch
+"""Mirror a remote ftp subtree into a local directory tree.
 
-usage_msg = """
 usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat]
                  [-l username [-p passwd [-a account]]]
                 hostname [remotedir [localdir]]
@@ -25,17 +10,31 @@ usage: ftpmirror [-v] [-q] [-i] [-m] [-n] [-r] [-s pat]
 -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
+-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
+
+import os
+import sys
+import time
+import getopt
+import string
+import ftplib
+from fnmatch import fnmatch
+
+# 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 @@ rmok = 0
 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 @@ def main():
        #
        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 @@ def mirrorsubdir(f, localdir):
                                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 @@ def mirrorsubdir(f, localdir):
                                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 @@ def mirrorsubdir(f, localdir):
                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):