Kaydet (Commit) a2596962 authored tarafından Guido van Rossum's avatar Guido van Rossum

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...).
üst 6c373f75
...@@ -18,10 +18,6 @@ remotedir: remote directory (default initial) ...@@ -18,10 +18,6 @@ remotedir: remote directory (default initial)
localdir: local directory (default current) localdir: local directory (default current)
""" """
# XXX To do:
# - handle symbolic links
# - back up .mirrorinfo before overwriting
import os import os
import sys import sys
import time import time
...@@ -76,11 +72,11 @@ def main(): ...@@ -76,11 +72,11 @@ def main():
if args[3:]: usage('too many arguments') if args[3:]: usage('too many arguments')
# #
f = ftplib.FTP() f = ftplib.FTP()
if verbose: print 'Connecting to %s...' % host if verbose: print 'Connecting to %s...' % `host`
f.connect(host) f.connect(host)
if not nologin: if not nologin:
if verbose: if verbose:
print 'Logging in as %s...' % (login or 'anonymous') print 'Logging in as %s...' % `login or 'anonymous'`
f.login(login, passwd, account) f.login(login, passwd, account)
if verbose: print 'OK.' if verbose: print 'OK.'
pwd = f.pwd() pwd = f.pwd()
...@@ -98,11 +94,11 @@ def main(): ...@@ -98,11 +94,11 @@ def main():
def mirrorsubdir(f, localdir): def mirrorsubdir(f, localdir):
pwd = f.pwd() pwd = f.pwd()
if localdir and not os.path.isdir(localdir): if localdir and not os.path.isdir(localdir):
if verbose: print 'Creating local directory', localdir if verbose: print 'Creating local directory', `localdir`
try: try:
makedir(localdir) makedir(localdir)
except os.error, msg: except os.error, msg:
print "Failed to establish local directory", localdir print "Failed to establish local directory", `localdir`
return return
infofilename = os.path.join(localdir, '.mirrorinfo') infofilename = os.path.join(localdir, '.mirrorinfo')
try: try:
...@@ -112,11 +108,11 @@ def mirrorsubdir(f, localdir): ...@@ -112,11 +108,11 @@ def mirrorsubdir(f, localdir):
try: try:
info = eval(text) info = eval(text)
except (SyntaxError, NameError): except (SyntaxError, NameError):
print 'Bad mirror info in %s' % infofilename print 'Bad mirror info in %s' % `infofilename`
info = {} info = {}
subdirs = [] subdirs = []
listing = [] listing = []
if verbose: print 'Listing remote directory %s...' % pwd if verbose: print 'Listing remote directory %s...' % `pwd`
f.retrlines('LIST', listing.append) f.retrlines('LIST', listing.append)
filesfound = [] filesfound = []
for line in listing: for line in listing:
...@@ -136,33 +132,35 @@ def mirrorsubdir(f, localdir): ...@@ -136,33 +132,35 @@ def mirrorsubdir(f, localdir):
if len(words) < 6: if len(words) < 6:
if verbose > 1: print 'Skipping short line' if verbose > 1: print 'Skipping short line'
continue continue
filename = words[-1] filename = string.lstrip(words[-1])
if string.find(filename, " -> ") >= 0: i = string.find(filename, " -> ")
if i >= 0:
# words[0] had better start with 'l'...
if verbose > 1: if verbose > 1:
print 'Skipping symbolic link %s' % \ print 'Found symbolic link %s' % `filename`
filename linkto = filename[i+4:]
continue filename = filename[:i]
infostuff = words[-5:-1] infostuff = words[-5:-1]
mode = words[0] mode = words[0]
skip = 0 skip = 0
for pat in skippats: for pat in skippats:
if fnmatch(filename, pat): if fnmatch(filename, pat):
if verbose > 1: if verbose > 1:
print 'Skip pattern', pat, print 'Skip pattern', `pat`,
print 'matches', filename print 'matches', `filename`
skip = 1 skip = 1
break break
if skip: if skip:
continue continue
if mode[0] == 'd': if mode[0] == 'd':
if verbose > 1: if verbose > 1:
print 'Remembering subdirectory', filename print 'Remembering subdirectory', `filename`
subdirs.append(filename) subdirs.append(filename)
continue continue
filesfound.append(filename) filesfound.append(filename)
if info.has_key(filename) and info[filename] == infostuff: if info.has_key(filename) and info[filename] == infostuff:
if verbose > 1: if verbose > 1:
print 'Already have this version of', filename print 'Already have this version of',`filename`
continue continue
fullname = os.path.join(localdir, filename) fullname = os.path.join(localdir, filename)
tempname = os.path.join(localdir, '@'+filename) tempname = os.path.join(localdir, '@'+filename)
...@@ -176,28 +174,41 @@ def mirrorsubdir(f, localdir): ...@@ -176,28 +174,41 @@ def mirrorsubdir(f, localdir):
os.unlink(tempname) os.unlink(tempname)
except os.error: except os.error:
pass pass
try: if mode[0] == 'l':
fp = open(tempname, 'wb') if verbose:
except IOError, msg: print "Creating symlink %s -> %s" % (
print "Can't create %s: %s" % (tempname, str(msg)) `filename`, `linkto`)
continue try:
if verbose: os.symlink(linkto, tempname)
print 'Retrieving %s from %s as %s...' % \ except IOError, msg:
(filename, pwd, fullname) print "Can't create %s: %s" % (
if verbose: `tempname`, str(msg))
fp1 = LoggingFile(fp, 1024, sys.stdout) continue
else: else:
fp1 = fp try:
t0 = time.time() fp = open(tempname, 'wb')
try: except IOError, msg:
f.retrbinary('RETR ' + filename, fp1.write, 8*1024) print "Can't create %s: %s" % (
except ftplib.error_perm, msg: `tempname`, str(msg))
print msg continue
t1 = time.time() if verbose:
bytes = fp.tell() print 'Retrieving %s from %s as %s...' % \
fp.close() (`filename`, `pwd`, `fullname`)
if fp1 != fp: if verbose:
fp1.close() 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: try:
os.unlink(fullname) os.unlink(fullname)
except os.error: except os.error:
...@@ -205,13 +216,13 @@ def mirrorsubdir(f, localdir): ...@@ -205,13 +216,13 @@ def mirrorsubdir(f, localdir):
try: try:
os.rename(tempname, fullname) os.rename(tempname, fullname)
except os.error, msg: except os.error, msg:
print "Can't rename %s to %s: %s" % (tempname, print "Can't rename %s to %s: %s" % (`tempname`,
fullname, `fullname`,
str(msg)) str(msg))
continue continue
info[filename] = infostuff info[filename] = infostuff
writedict(info, infofilename) writedict(info, infofilename)
if verbose: if verbose and mode[0] != 'l':
dt = t1 - t0 dt = t1 - t0
kbytes = bytes / 1024.0 kbytes = bytes / 1024.0
print int(round(kbytes)), print int(round(kbytes)),
...@@ -229,7 +240,7 @@ def mirrorsubdir(f, localdir): ...@@ -229,7 +240,7 @@ def mirrorsubdir(f, localdir):
if filename not in filesfound: if filename not in filesfound:
if verbose: if verbose:
print "Removing obsolete info entry for", print "Removing obsolete info entry for",
print filename, "in", localdir or "." print `filename`, "in", `localdir or "."`
del info[filename] del info[filename]
deletions = deletions + 1 deletions = deletions + 1
if deletions: if deletions:
...@@ -248,8 +259,8 @@ def mirrorsubdir(f, localdir): ...@@ -248,8 +259,8 @@ def mirrorsubdir(f, localdir):
for pat in skippats: for pat in skippats:
if fnmatch(name, pat): if fnmatch(name, pat):
if verbose > 1: if verbose > 1:
print 'Skip pattern', pat, print 'Skip pattern', `pat`,
print 'matches', name print 'matches', `name`
skip = 1 skip = 1
break break
if skip: if skip:
...@@ -257,10 +268,10 @@ def mirrorsubdir(f, localdir): ...@@ -257,10 +268,10 @@ def mirrorsubdir(f, localdir):
fullname = os.path.join(localdir, name) fullname = os.path.join(localdir, name)
if not rmok: if not rmok:
if verbose: if verbose:
print 'Local file', fullname, print 'Local file', `fullname`,
print 'is no longer pertinent' print 'is no longer pertinent'
continue continue
if verbose: print 'Removing local file/dir', fullname if verbose: print 'Removing local file/dir', `fullname`
remove(fullname) remove(fullname)
# #
# Recursively mirror subdirectories # Recursively mirror subdirectories
...@@ -268,18 +279,18 @@ def mirrorsubdir(f, localdir): ...@@ -268,18 +279,18 @@ def mirrorsubdir(f, localdir):
if interactive: if interactive:
doit = askabout('subdirectory', subdir, pwd) doit = askabout('subdirectory', subdir, pwd)
if not doit: continue if not doit: continue
if verbose: print 'Processing subdirectory', subdir if verbose: print 'Processing subdirectory', `subdir`
localsubdir = os.path.join(localdir, subdir) localsubdir = os.path.join(localdir, subdir)
pwd = f.pwd() pwd = f.pwd()
if verbose > 1: if verbose > 1:
print 'Remote directory now:', pwd print 'Remote directory now:', `pwd`
print 'Remote cwd', subdir print 'Remote cwd', `subdir`
try: try:
f.cwd(subdir) f.cwd(subdir)
except ftplib.error_perm, msg: except ftplib.error_perm, msg:
print "Can't chdir to", subdir, ":", msg print "Can't chdir to", `subdir`, ":", `msg`
else: else:
if verbose: print 'Mirroring as', localsubdir if verbose: print 'Mirroring as', `localsubdir`
mirrorsubdir(f, localsubdir) mirrorsubdir(f, localsubdir)
if verbose > 1: print 'Remote cwd ..' if verbose > 1: print 'Remote cwd ..'
f.cwd('..') f.cwd('..')
...@@ -308,14 +319,14 @@ def remove(fullname): ...@@ -308,14 +319,14 @@ def remove(fullname):
os.rmdir(fullname) os.rmdir(fullname)
except os.error, msg: except os.error, msg:
print "Can't remove local directory %s: %s" % \ print "Can't remove local directory %s: %s" % \
(fullname, str(msg)) (`fullname`, str(msg))
return 0 return 0
else: else:
try: try:
os.unlink(fullname) os.unlink(fullname)
except os.error, msg: except os.error, msg:
print "Can't remove local file %s: %s" % \ print "Can't remove local file %s: %s" % \
(fullname, str(msg)) (`fullname`, str(msg))
return 0 return 0
return 1 return 1
...@@ -360,12 +371,25 @@ def makedir(pathname): ...@@ -360,12 +371,25 @@ def makedir(pathname):
# Write a dictionary to a file in a way that can be read back using # 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). # rval() but is still somewhat readable (i.e. not a single long line).
# Also creates a backup file.
def writedict(dict, filename): 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') fp.write('{\n')
for key, value in dict.items(): for key, value in dict.items():
fp.write('%s: %s,\n' % (`key`, `value`)) fp.write('%s: %s,\n' % (`key`, `value`))
fp.write('}\n') fp.write('}\n')
fp.close() fp.close()
try:
os.rename(filename, backup)
except os.error:
pass
os.rename(tempname, filename)
main() main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment