/usr/share/pyshared/execnet/rsync_remote.py is in python-execnet 1.0.9-0.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | """
(c) 2006-2009, Armin Rigo, Holger Krekel, Maciej Fijalkowski
"""
def serve_rsync(channel):
import os, stat, shutil
try:
from hashlib import md5
except ImportError:
from md5 import md5
destdir, options = channel.receive()
modifiedfiles = []
def remove(path):
assert path.startswith(destdir)
try:
os.unlink(path)
except OSError:
# assume it's a dir
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)
mode = msg.pop(0)
if mode:
os.chmod(path, mode)
entrynames = {}
for entryname in msg:
destpath = os.path.join(path, entryname)
receive_directory_structure(destpath, 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:
assert isinstance(msg, tuple)
checksum = None
if st:
if stat.S_ISREG(st.st_mode):
msg_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(f.read()).digest()
f.close()
elif msg_mode and msg_mode != st.st_mode:
os.chmod(path, msg_mode)
return
else:
return # already fine
else:
remove(path)
channel.send(("send", (relcomponents, checksum)))
modifiedfiles.append((path, msg))
receive_directory_structure(destdir, [])
STRICT_CHECK = False # seems most useful this way for py.test
channel.send(("list_done", None))
for path, (mode, 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:
if mode:
os.chmod(path, mode)
os.utime(path, (time, time))
except OSError:
pass
del data
channel.send(("links", None))
msg = channel.receive()
while msg != 42:
# we get symlink
_type, relpath, linkpoint = msg
path = os.path.join(destdir, relpath)
try:
remove(path)
except OSError:
pass
if _type == "linkbase":
src = os.path.join(destdir, linkpoint)
else:
assert _type == "link", _type
src = linkpoint
os.symlink(src, path)
msg = channel.receive()
channel.send(("done", None))
if __name__ == '__channelexec__':
serve_rsync(channel)
|