|
def f(): |
import os, stat, shutil, md5 |
destdir, options = channel.receive() |
modifiedfiles = [] |
|
def remove(path): |
assert path.startswith(destdir) |
try: |
os.unlink(path) |
except OSError: |
|
shutil.rmtree(path) |
|
def receive_directory_structure(path, relcomponents): |
try: |
st = os.lstat(path) |
except OSError: |
st = None |
msg = channel.receive() |
if isinstance(msg, list): |
if st and not stat.S_ISDIR(st.st_mode): |
os.unlink(path) |
st = None |
if not st: |
os.makedirs(path) |
entrynames = {} |
for entryname in msg: |
receive_directory_structure(os.path.join(path, entryname), |
relcomponents + [entryname]) |
entrynames[entryname] = True |
if options.get('delete'): |
for othername in os.listdir(path): |
if othername not in entrynames: |
otherpath = os.path.join(path, othername) |
remove(otherpath) |
elif msg is not None: |
checksum = None |
if st: |
if stat.S_ISREG(st.st_mode): |
msg_mtime, msg_size = msg |
if msg_size != st.st_size: |
pass |
elif msg_mtime != st.st_mtime: |
f = open(path, 'rb') |
checksum = md5.md5(f.read()).digest() |
f.close() |
else: |
return |
else: |
remove(path) |
channel.send(("send", (relcomponents, checksum))) |
modifiedfiles.append((path, msg)) |
receive_directory_structure(destdir, []) |
|
STRICT_CHECK = False |
channel.send(("list_done", None)) |
|
for path, (time, size) in modifiedfiles: |
data = channel.receive() |
channel.send(("ack", path[len(destdir) + 1:])) |
if data is not None: |
if STRICT_CHECK and len(data) != size: |
raise IOError('file modified during rsync: %r' % (path,)) |
f = open(path, 'wb') |
f.write(data) |
f.close() |
try: |
os.utime(path, (time, time)) |
except OSError: |
pass |
del data |
channel.send(("links", None)) |
|
msg = channel.receive() |
while msg is not 42: |
|
_type, relpath, linkpoint = msg |
assert _type == "link" |
path = os.path.join(destdir, relpath) |
try: |
remove(path) |
except OSError: |
pass |
|
os.symlink(os.path.join(destdir, linkpoint), path) |
msg = channel.receive() |
channel.send(("done", None)) |
|
|