summaryrefslogtreecommitdiffstats
path: root/Tools/scripts/ftpmirror.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1998-06-29 23:17:16 (GMT)
committerGuido van Rossum <guido@python.org>1998-06-29 23:17:16 (GMT)
commita25969620ad128c95dde9cf500b28fa3e57611c9 (patch)
tree761f7a627f5b860937099728166c8d946837c79b /Tools/scripts/ftpmirror.py
parent6c373f758f2dede94522f99d5f1557101654742a (diff)
downloadcpython-a25969620ad128c95dde9cf500b28fa3e57611c9.zip
cpython-a25969620ad128c95dde9cf500b28fa3e57611c9.tar.gz
cpython-a25969620ad128c95dde9cf500b28fa3e57611c9.tar.bz2
Fix by Sjoerd Mullender to support symbolic links and make a backup of
.mirrorinfo. Fix by me to call string.lstrip(filename) to cope with a bug in strop.strip() in Python 1.4. Additionally, I changed all print statements that print filenames etc. to put them in backquotes so that it will be more obvious when there's a funny character on one of them (such as a space...).
Diffstat (limited to 'Tools/scripts/ftpmirror.py')
-rwxr-xr-xTools/scripts/ftpmirror.py136
1 files changed, 80 insertions, 56 deletions
diff --git a/Tools/scripts/ftpmirror.py b/Tools/scripts/ftpmirror.py
index c73251a..857ba76 100755
--- a/Tools/scripts/ftpmirror.py
+++ b/Tools/scripts/ftpmirror.py
@@ -18,10 +18,6 @@ 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
@@ -76,11 +72,11 @@ def main():
if args[3:]: usage('too many arguments')
#
f = ftplib.FTP()
- if verbose: print 'Connecting to %s...' % host
+ if verbose: print 'Connecting to %s...' % `host`
f.connect(host)
if not nologin:
if verbose:
- print 'Logging in as %s...' % (login or 'anonymous')
+ print 'Logging in as %s...' % `login or 'anonymous'`
f.login(login, passwd, account)
if verbose: print 'OK.'
pwd = f.pwd()
@@ -98,11 +94,11 @@ def main():
def mirrorsubdir(f, localdir):
pwd = f.pwd()
if localdir and not os.path.isdir(localdir):
- if verbose: print 'Creating local directory', localdir
+ if verbose: print 'Creating local directory', `localdir`
try:
makedir(localdir)
except os.error, msg:
- print "Failed to establish local directory", localdir
+ print "Failed to establish local directory", `localdir`
return
infofilename = os.path.join(localdir, '.mirrorinfo')
try:
@@ -112,11 +108,11 @@ def mirrorsubdir(f, localdir):
try:
info = eval(text)
except (SyntaxError, NameError):
- print 'Bad mirror info in %s' % infofilename
+ print 'Bad mirror info in %s' % `infofilename`
info = {}
subdirs = []
listing = []
- if verbose: print 'Listing remote directory %s...' % pwd
+ if verbose: print 'Listing remote directory %s...' % `pwd`
f.retrlines('LIST', listing.append)
filesfound = []
for line in listing:
@@ -136,33 +132,35 @@ def mirrorsubdir(f, localdir):
if len(words) < 6:
if verbose > 1: print 'Skipping short line'
continue
- filename = words[-1]
- if string.find(filename, " -> ") >= 0:
+ filename = string.lstrip(words[-1])
+ i = string.find(filename, " -> ")
+ if i >= 0:
+ # words[0] had better start with 'l'...
if verbose > 1:
- print 'Skipping symbolic link %s' % \
- filename
- continue
+ print 'Found symbolic link %s' % `filename`
+ linkto = filename[i+4:]
+ filename = filename[:i]
infostuff = words[-5:-1]
mode = words[0]
skip = 0
for pat in skippats:
if fnmatch(filename, pat):
if verbose > 1:
- print 'Skip pattern', pat,
- print 'matches', filename
+ print 'Skip pattern', `pat`,
+ print 'matches', `filename`
skip = 1
break
if skip:
continue
if mode[0] == 'd':
if verbose > 1:
- print 'Remembering subdirectory', filename
+ print 'Remembering subdirectory', `filename`
subdirs.append(filename)
continue
filesfound.append(filename)
if info.has_key(filename) and info[filename] == infostuff:
if verbose > 1:
- print 'Already have this version of', filename
+ print 'Already have this version of',`filename`
continue
fullname = os.path.join(localdir, filename)
tempname = os.path.join(localdir, '@'+filename)
@@ -176,28 +174,41 @@ def mirrorsubdir(f, localdir):
os.unlink(tempname)
except os.error:
pass
- try:
- fp = open(tempname, 'wb')
- except IOError, msg:
- print "Can't create %s: %s" % (tempname, str(msg))
- continue
- if verbose:
- print 'Retrieving %s from %s as %s...' % \
- (filename, pwd, fullname)
- if verbose:
- fp1 = LoggingFile(fp, 1024, sys.stdout)
+ if mode[0] == 'l':
+ if verbose:
+ print "Creating symlink %s -> %s" % (
+ `filename`, `linkto`)
+ try:
+ os.symlink(linkto, tempname)
+ except IOError, msg:
+ print "Can't create %s: %s" % (
+ `tempname`, str(msg))
+ continue
else:
- fp1 = fp
- t0 = time.time()
- try:
- f.retrbinary('RETR ' + filename, fp1.write, 8*1024)
- except ftplib.error_perm, msg:
- print msg
- t1 = time.time()
- bytes = fp.tell()
- fp.close()
- if fp1 != fp:
- fp1.close()
+ try:
+ fp = open(tempname, 'wb')
+ except IOError, msg:
+ print "Can't create %s: %s" % (
+ `tempname`, str(msg))
+ continue
+ if verbose:
+ print 'Retrieving %s from %s as %s...' % \
+ (`filename`, `pwd`, `fullname`)
+ if verbose:
+ fp1 = LoggingFile(fp, 1024, sys.stdout)
+ else:
+ fp1 = fp
+ t0 = time.time()
+ try:
+ f.retrbinary('RETR ' + filename,
+ fp1.write, 8*1024)
+ except ftplib.error_perm, msg:
+ print msg
+ t1 = time.time()
+ bytes = fp.tell()
+ fp.close()
+ if fp1 != fp:
+ fp1.close()
try:
os.unlink(fullname)
except os.error:
@@ -205,13 +216,13 @@ def mirrorsubdir(f, localdir):
try:
os.rename(tempname, fullname)
except os.error, msg:
- print "Can't rename %s to %s: %s" % (tempname,
- fullname,
+ print "Can't rename %s to %s: %s" % (`tempname`,
+ `fullname`,
str(msg))
continue
info[filename] = infostuff
writedict(info, infofilename)
- if verbose:
+ if verbose and mode[0] != 'l':
dt = t1 - t0
kbytes = bytes / 1024.0
print int(round(kbytes)),
@@ -229,7 +240,7 @@ def mirrorsubdir(f, localdir):
if filename not in filesfound:
if verbose:
print "Removing obsolete info entry for",
- print filename, "in", localdir or "."
+ print `filename`, "in", `localdir or "."`
del info[filename]
deletions = deletions + 1
if deletions:
@@ -248,8 +259,8 @@ def mirrorsubdir(f, localdir):
for pat in skippats:
if fnmatch(name, pat):
if verbose > 1:
- print 'Skip pattern', pat,
- print 'matches', name
+ print 'Skip pattern', `pat`,
+ print 'matches', `name`
skip = 1
break
if skip:
@@ -257,10 +268,10 @@ def mirrorsubdir(f, localdir):
fullname = os.path.join(localdir, name)
if not rmok:
if verbose:
- print 'Local file', fullname,
+ print 'Local file', `fullname`,
print 'is no longer pertinent'
continue
- if verbose: print 'Removing local file/dir', fullname
+ if verbose: print 'Removing local file/dir', `fullname`
remove(fullname)
#
# Recursively mirror subdirectories
@@ -268,18 +279,18 @@ def mirrorsubdir(f, localdir):
if interactive:
doit = askabout('subdirectory', subdir, pwd)
if not doit: continue
- if verbose: print 'Processing subdirectory', subdir
+ if verbose: print 'Processing subdirectory', `subdir`
localsubdir = os.path.join(localdir, subdir)
pwd = f.pwd()
if verbose > 1:
- print 'Remote directory now:', pwd
- print 'Remote cwd', subdir
+ print 'Remote directory now:', `pwd`
+ print 'Remote cwd', `subdir`
try:
f.cwd(subdir)
except ftplib.error_perm, msg:
- print "Can't chdir to", subdir, ":", msg
+ print "Can't chdir to", `subdir`, ":", `msg`
else:
- if verbose: print 'Mirroring as', localsubdir
+ if verbose: print 'Mirroring as', `localsubdir`
mirrorsubdir(f, localsubdir)
if verbose > 1: print 'Remote cwd ..'
f.cwd('..')
@@ -308,14 +319,14 @@ def remove(fullname):
os.rmdir(fullname)
except os.error, msg:
print "Can't remove local directory %s: %s" % \
- (fullname, str(msg))
+ (`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))
+ (`fullname`, str(msg))
return 0
return 1
@@ -360,12 +371,25 @@ def makedir(pathname):
# Write a dictionary to a file in a way that can be read back using
# rval() but is still somewhat readable (i.e. not a single long line).
+# Also creates a backup file.
def writedict(dict, filename):
- fp = open(filename, 'w')
+ dir, file = os.path.split(filename)
+ tempname = os.path.join(dir, '@' + file)
+ backup = os.path.join(dir, file + '~')
+ try:
+ os.unlink(backup)
+ except os.error:
+ pass
+ fp = open(tempname, 'w')
fp.write('{\n')
for key, value in dict.items():
fp.write('%s: %s,\n' % (`key`, `value`))
fp.write('}\n')
fp.close()
+ try:
+ os.rename(filename, backup)
+ except os.error:
+ pass
+ os.rename(tempname, filename)
main()