From acbad78022027cf7d94c4b9d60b1a1f44441ad93 Mon Sep 17 00:00:00 2001 From: Tim Peters Date: Sun, 18 Jul 2004 05:56:09 +0000 Subject: Whitespace normalization. Ran reindent.py over the entire source tree. --- Demo/pdist/FSProxy.py | 556 ++++++++++++++++----------------- Demo/pdist/client.py | 267 ++++++++-------- Demo/pdist/cmdfw.py | 266 ++++++++-------- Demo/pdist/cmptree.py | 354 ++++++++++----------- Demo/pdist/cvslib.py | 656 +++++++++++++++++++-------------------- Demo/pdist/cvslock.py | 332 ++++++++++---------- Demo/pdist/mac.py | 24 +- Demo/pdist/rcsclient.py | 90 +++--- Demo/pdist/rcslib.py | 6 +- Demo/pdist/rcvs.py | 802 ++++++++++++++++++++++++------------------------ Demo/pdist/rrcs.py | 238 +++++++------- Demo/pdist/security.py | 56 ++-- Demo/pdist/server.py | 248 +++++++-------- Demo/pdist/sumtree.py | 32 +- 14 files changed, 1963 insertions(+), 1964 deletions(-) (limited to 'Demo/pdist') diff --git a/Demo/pdist/FSProxy.py b/Demo/pdist/FSProxy.py index 7510d1e6fd..a1ab635c08 100755 --- a/Demo/pdist/FSProxy.py +++ b/Demo/pdist/FSProxy.py @@ -24,299 +24,299 @@ import time import fnmatch if os.name == 'mac': - import macfs - maxnamelen = 31 + import macfs + maxnamelen = 31 else: - macfs = None - maxnamelen = 255 + macfs = None + maxnamelen = 255 skipnames = (os.curdir, os.pardir) class FSProxyLocal: - - def __init__(self): - self._dirstack = [] - self._ignore = ['*.pyc'] + self._readignore() - - def _close(self): - while self._dirstack: - self.back() - - def _readignore(self): - file = self._hide('ignore') - try: - f = open(file) - except IOError: - file = self._hide('synctree.ignorefiles') - try: - f = open(file) - except IOError: - return [] - ignore = [] - while 1: - line = f.readline() - if not line: break - if line[-1] == '\n': line = line[:-1] - ignore.append(line) - f.close() - return ignore - - def _hidden(self, name): - if os.name == 'mac': - return name[0] == '(' and name[-1] == ')' - else: - return name[0] == '.' - - def _hide(self, name): - if os.name == 'mac': - return '(%s)' % name - else: - return '.%s' % name - - def visible(self, name): - if len(name) > maxnamelen: return 0 - if name[-1] == '~': return 0 - if name in skipnames: return 0 - if self._hidden(name): return 0 - head, tail = os.path.split(name) - if head or not tail: return 0 - if macfs: - if os.path.exists(name) and not os.path.isdir(name): - try: - fs = macfs.FSSpec(name) - c, t = fs.GetCreatorType() - if t != 'TEXT': return 0 - except macfs.error, msg: - print "***", name, msg - return 0 - else: - if os.path.islink(name): return 0 - if '\0' in open(name, 'rb').read(512): return 0 - for ign in self._ignore: - if fnmatch.fnmatch(name, ign): return 0 - return 1 - - def check(self, name): - if not self.visible(name): - raise os.error, "protected name %s" % repr(name) - - def checkfile(self, name): - self.check(name) - if not os.path.isfile(name): - raise os.error, "not a plain file %s" % repr(name) - - def pwd(self): - return os.getcwd() - - def cd(self, name): - self.check(name) - save = os.getcwd(), self._ignore - os.chdir(name) - self._dirstack.append(save) - self._ignore = self._ignore + self._readignore() - - def back(self): - if not self._dirstack: - raise os.error, "empty directory stack" - dir, ignore = self._dirstack[-1] - os.chdir(dir) - del self._dirstack[-1] - self._ignore = ignore - - def _filter(self, files, pat = None): - if pat: - def keep(name, pat = pat): - return fnmatch.fnmatch(name, pat) - files = filter(keep, files) - files = filter(self.visible, files) - files.sort() - return files - - def list(self, pat = None): - files = os.listdir(os.curdir) - return self._filter(files, pat) - - def listfiles(self, pat = None): - files = os.listdir(os.curdir) - files = filter(os.path.isfile, files) - return self._filter(files, pat) - - def listsubdirs(self, pat = None): - files = os.listdir(os.curdir) - files = filter(os.path.isdir, files) - return self._filter(files, pat) - - def exists(self, name): - return self.visible(name) and os.path.exists(name) - - def isdir(self, name): - return self.visible(name) and os.path.isdir(name) - - def islink(self, name): - return self.visible(name) and os.path.islink(name) - - def isfile(self, name): - return self.visible(name) and os.path.isfile(name) - - def sum(self, name): - self.checkfile(name) - BUFFERSIZE = 1024*8 - f = open(name) - sum = md5.new() - while 1: - buffer = f.read(BUFFERSIZE) - if not buffer: - break - sum.update(buffer) - return sum.digest() - - def size(self, name): - self.checkfile(name) - return os.stat(name)[ST_SIZE] - - def mtime(self, name): - self.checkfile(name) - return time.localtime(os.stat(name)[ST_MTIME]) - - def stat(self, name): - self.checkfile(name) - size = os.stat(name)[ST_SIZE] - mtime = time.localtime(os.stat(name)[ST_MTIME]) - return size, mtime - - def info(self, name): - sum = self.sum(name) - size = os.stat(name)[ST_SIZE] - mtime = time.localtime(os.stat(name)[ST_MTIME]) - return sum, size, mtime - - def _list(self, function, list): - if list is None: - list = self.listfiles() - res = [] - for name in list: - try: - res.append((name, function(name))) - except (os.error, IOError): - res.append((name, None)) - return res - - def sumlist(self, list = None): - return self._list(self.sum, list) - - def statlist(self, list = None): - return self._list(self.stat, list) - - def mtimelist(self, list = None): - return self._list(self.mtime, list) - - def sizelist(self, list = None): - return self._list(self.size, list) - - def infolist(self, list = None): - return self._list(self.info, list) - - def _dict(self, function, list): - if list is None: - list = self.listfiles() - dict = {} - for name in list: - try: - dict[name] = function(name) - except (os.error, IOError): - pass - return dict - - def sumdict(self, list = None): - return self.dict(self.sum, list) - - def sizedict(self, list = None): - return self.dict(self.size, list) - - def mtimedict(self, list = None): - return self.dict(self.mtime, list) - - def statdict(self, list = None): - return self.dict(self.stat, list) - - def infodict(self, list = None): - return self._dict(self.info, list) - - def read(self, name, offset = 0, length = -1): - self.checkfile(name) - f = open(name) - f.seek(offset) - if length == 0: - data = '' - elif length < 0: - data = f.read() - else: - data = f.read(length) - f.close() - return data - - def create(self, name): - self.check(name) - if os.path.exists(name): - self.checkfile(name) - bname = name + '~' - try: - os.unlink(bname) - except os.error: - pass - os.rename(name, bname) - f = open(name, 'w') - f.close() - - def write(self, name, data, offset = 0): - self.checkfile(name) - f = open(name, 'r+') - f.seek(offset) - f.write(data) - f.close() - - def mkdir(self, name): - self.check(name) - os.mkdir(name, 0777) - - def rmdir(self, name): - self.check(name) - os.rmdir(name) + + def __init__(self): + self._dirstack = [] + self._ignore = ['*.pyc'] + self._readignore() + + def _close(self): + while self._dirstack: + self.back() + + def _readignore(self): + file = self._hide('ignore') + try: + f = open(file) + except IOError: + file = self._hide('synctree.ignorefiles') + try: + f = open(file) + except IOError: + return [] + ignore = [] + while 1: + line = f.readline() + if not line: break + if line[-1] == '\n': line = line[:-1] + ignore.append(line) + f.close() + return ignore + + def _hidden(self, name): + if os.name == 'mac': + return name[0] == '(' and name[-1] == ')' + else: + return name[0] == '.' + + def _hide(self, name): + if os.name == 'mac': + return '(%s)' % name + else: + return '.%s' % name + + def visible(self, name): + if len(name) > maxnamelen: return 0 + if name[-1] == '~': return 0 + if name in skipnames: return 0 + if self._hidden(name): return 0 + head, tail = os.path.split(name) + if head or not tail: return 0 + if macfs: + if os.path.exists(name) and not os.path.isdir(name): + try: + fs = macfs.FSSpec(name) + c, t = fs.GetCreatorType() + if t != 'TEXT': return 0 + except macfs.error, msg: + print "***", name, msg + return 0 + else: + if os.path.islink(name): return 0 + if '\0' in open(name, 'rb').read(512): return 0 + for ign in self._ignore: + if fnmatch.fnmatch(name, ign): return 0 + return 1 + + def check(self, name): + if not self.visible(name): + raise os.error, "protected name %s" % repr(name) + + def checkfile(self, name): + self.check(name) + if not os.path.isfile(name): + raise os.error, "not a plain file %s" % repr(name) + + def pwd(self): + return os.getcwd() + + def cd(self, name): + self.check(name) + save = os.getcwd(), self._ignore + os.chdir(name) + self._dirstack.append(save) + self._ignore = self._ignore + self._readignore() + + def back(self): + if not self._dirstack: + raise os.error, "empty directory stack" + dir, ignore = self._dirstack[-1] + os.chdir(dir) + del self._dirstack[-1] + self._ignore = ignore + + def _filter(self, files, pat = None): + if pat: + def keep(name, pat = pat): + return fnmatch.fnmatch(name, pat) + files = filter(keep, files) + files = filter(self.visible, files) + files.sort() + return files + + def list(self, pat = None): + files = os.listdir(os.curdir) + return self._filter(files, pat) + + def listfiles(self, pat = None): + files = os.listdir(os.curdir) + files = filter(os.path.isfile, files) + return self._filter(files, pat) + + def listsubdirs(self, pat = None): + files = os.listdir(os.curdir) + files = filter(os.path.isdir, files) + return self._filter(files, pat) + + def exists(self, name): + return self.visible(name) and os.path.exists(name) + + def isdir(self, name): + return self.visible(name) and os.path.isdir(name) + + def islink(self, name): + return self.visible(name) and os.path.islink(name) + + def isfile(self, name): + return self.visible(name) and os.path.isfile(name) + + def sum(self, name): + self.checkfile(name) + BUFFERSIZE = 1024*8 + f = open(name) + sum = md5.new() + while 1: + buffer = f.read(BUFFERSIZE) + if not buffer: + break + sum.update(buffer) + return sum.digest() + + def size(self, name): + self.checkfile(name) + return os.stat(name)[ST_SIZE] + + def mtime(self, name): + self.checkfile(name) + return time.localtime(os.stat(name)[ST_MTIME]) + + def stat(self, name): + self.checkfile(name) + size = os.stat(name)[ST_SIZE] + mtime = time.localtime(os.stat(name)[ST_MTIME]) + return size, mtime + + def info(self, name): + sum = self.sum(name) + size = os.stat(name)[ST_SIZE] + mtime = time.localtime(os.stat(name)[ST_MTIME]) + return sum, size, mtime + + def _list(self, function, list): + if list is None: + list = self.listfiles() + res = [] + for name in list: + try: + res.append((name, function(name))) + except (os.error, IOError): + res.append((name, None)) + return res + + def sumlist(self, list = None): + return self._list(self.sum, list) + + def statlist(self, list = None): + return self._list(self.stat, list) + + def mtimelist(self, list = None): + return self._list(self.mtime, list) + + def sizelist(self, list = None): + return self._list(self.size, list) + + def infolist(self, list = None): + return self._list(self.info, list) + + def _dict(self, function, list): + if list is None: + list = self.listfiles() + dict = {} + for name in list: + try: + dict[name] = function(name) + except (os.error, IOError): + pass + return dict + + def sumdict(self, list = None): + return self.dict(self.sum, list) + + def sizedict(self, list = None): + return self.dict(self.size, list) + + def mtimedict(self, list = None): + return self.dict(self.mtime, list) + + def statdict(self, list = None): + return self.dict(self.stat, list) + + def infodict(self, list = None): + return self._dict(self.info, list) + + def read(self, name, offset = 0, length = -1): + self.checkfile(name) + f = open(name) + f.seek(offset) + if length == 0: + data = '' + elif length < 0: + data = f.read() + else: + data = f.read(length) + f.close() + return data + + def create(self, name): + self.check(name) + if os.path.exists(name): + self.checkfile(name) + bname = name + '~' + try: + os.unlink(bname) + except os.error: + pass + os.rename(name, bname) + f = open(name, 'w') + f.close() + + def write(self, name, data, offset = 0): + self.checkfile(name) + f = open(name, 'r+') + f.seek(offset) + f.write(data) + f.close() + + def mkdir(self, name): + self.check(name) + os.mkdir(name, 0777) + + def rmdir(self, name): + self.check(name) + os.rmdir(name) class FSProxyServer(FSProxyLocal, server.Server): - - def __init__(self, address, verbose = server.VERBOSE): - FSProxyLocal.__init__(self) - server.Server.__init__(self, address, verbose) - - def _close(self): - server.Server._close(self) - FSProxyLocal._close(self) - - def _serve(self): - server.Server._serve(self) - # Retreat into start directory - while self._dirstack: self.back() + + def __init__(self, address, verbose = server.VERBOSE): + FSProxyLocal.__init__(self) + server.Server.__init__(self, address, verbose) + + def _close(self): + server.Server._close(self) + FSProxyLocal._close(self) + + def _serve(self): + server.Server._serve(self) + # Retreat into start directory + while self._dirstack: self.back() class FSProxyClient(client.Client): - - def __init__(self, address, verbose = client.VERBOSE): - client.Client.__init__(self, address, verbose) + + def __init__(self, address, verbose = client.VERBOSE): + client.Client.__init__(self, address, verbose) def test(): - import string - import sys - if sys.argv[1:]: - port = string.atoi(sys.argv[1]) - else: - port = 4127 - proxy = FSProxyServer(('', port)) - proxy._serverloop() + import string + import sys + if sys.argv[1:]: + port = string.atoi(sys.argv[1]) + else: + port = 4127 + proxy = FSProxyServer(('', port)) + proxy._serverloop() if __name__ == '__main__': - test() + test() diff --git a/Demo/pdist/client.py b/Demo/pdist/client.py index a00f005bbc..3e97d84690 100755 --- a/Demo/pdist/client.py +++ b/Demo/pdist/client.py @@ -12,118 +12,118 @@ VERBOSE = 1 class Client: - - """RPC Client class. No need to derive a class -- it's fully generic.""" - - def __init__(self, address, verbose = VERBOSE): - self._pre_init(address, verbose) - self._post_init() - - def _pre_init(self, address, verbose = VERBOSE): - if type(address) == type(0): - address = ('', address) - self._address = address - self._verbose = verbose - if self._verbose: print "Connecting to %s ..." % repr(address) - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.connect(address) - if self._verbose: print "Connected." - self._lastid = 0 # Last id for which a reply has been received - self._nextid = 1 # Id of next request - self._replies = {} # Unprocessed replies - self._rf = self._socket.makefile('r') - self._wf = self._socket.makefile('w') - - def _post_init(self): - self._methods = self._call('.methods') - - def __del__(self): - self._close() - - def _close(self): - if self._rf: self._rf.close() - self._rf = None - if self._wf: self._wf.close() - self._wf = None - if self._socket: self._socket.close() - self._socket = None - - def __getattr__(self, name): - if name in self._methods: - method = _stub(self, name) - setattr(self, name, method) # XXX circular reference - return method - raise AttributeError, name - - def _setverbose(self, verbose): - self._verbose = verbose - - def _call(self, name, *args): - return self._vcall(name, args) - - def _vcall(self, name, args): - return self._recv(self._vsend(name, args)) - - def _send(self, name, *args): - return self._vsend(name, args) - - def _send_noreply(self, name, *args): - return self._vsend(name, args, 0) - - def _vsend_noreply(self, name, args): - return self._vsend(name, args, 0) - - def _vsend(self, name, args, wantreply = 1): - id = self._nextid - self._nextid = id+1 - if not wantreply: id = -id - request = (name, args, id) - if self._verbose > 1: print "sending request: %s" % repr(request) - wp = pickle.Pickler(self._wf) - wp.dump(request) - return id - - def _recv(self, id): - exception, value, rid = self._vrecv(id) - if rid != id: - raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid) - if exception is None: - return value - x = exception - if hasattr(__builtin__, exception): - x = getattr(__builtin__, exception) - elif exception in ('posix.error', 'mac.error'): - x = os.error - if x == exception: - exception = x - raise exception, value - - def _vrecv(self, id): - self._flush() - if self._replies.has_key(id): - if self._verbose > 1: print "retrieving previous reply, id = %d" % id - reply = self._replies[id] - del self._replies[id] - return reply - aid = abs(id) - while 1: - if self._verbose > 1: print "waiting for reply, id = %d" % id - rp = pickle.Unpickler(self._rf) - reply = rp.load() - del rp - if self._verbose > 1: print "got reply: %s" % repr(reply) - rid = reply[2] - arid = abs(rid) - if arid == aid: - if self._verbose > 1: print "got it" - return reply - self._replies[rid] = reply - if arid > aid: - if self._verbose > 1: print "got higher id, assume all ok" - return (None, None, id) - - def _flush(self): - self._wf.flush() + + """RPC Client class. No need to derive a class -- it's fully generic.""" + + def __init__(self, address, verbose = VERBOSE): + self._pre_init(address, verbose) + self._post_init() + + def _pre_init(self, address, verbose = VERBOSE): + if type(address) == type(0): + address = ('', address) + self._address = address + self._verbose = verbose + if self._verbose: print "Connecting to %s ..." % repr(address) + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.connect(address) + if self._verbose: print "Connected." + self._lastid = 0 # Last id for which a reply has been received + self._nextid = 1 # Id of next request + self._replies = {} # Unprocessed replies + self._rf = self._socket.makefile('r') + self._wf = self._socket.makefile('w') + + def _post_init(self): + self._methods = self._call('.methods') + + def __del__(self): + self._close() + + def _close(self): + if self._rf: self._rf.close() + self._rf = None + if self._wf: self._wf.close() + self._wf = None + if self._socket: self._socket.close() + self._socket = None + + def __getattr__(self, name): + if name in self._methods: + method = _stub(self, name) + setattr(self, name, method) # XXX circular reference + return method + raise AttributeError, name + + def _setverbose(self, verbose): + self._verbose = verbose + + def _call(self, name, *args): + return self._vcall(name, args) + + def _vcall(self, name, args): + return self._recv(self._vsend(name, args)) + + def _send(self, name, *args): + return self._vsend(name, args) + + def _send_noreply(self, name, *args): + return self._vsend(name, args, 0) + + def _vsend_noreply(self, name, args): + return self._vsend(name, args, 0) + + def _vsend(self, name, args, wantreply = 1): + id = self._nextid + self._nextid = id+1 + if not wantreply: id = -id + request = (name, args, id) + if self._verbose > 1: print "sending request: %s" % repr(request) + wp = pickle.Pickler(self._wf) + wp.dump(request) + return id + + def _recv(self, id): + exception, value, rid = self._vrecv(id) + if rid != id: + raise RuntimeError, "request/reply id mismatch: %d/%d" % (id, rid) + if exception is None: + return value + x = exception + if hasattr(__builtin__, exception): + x = getattr(__builtin__, exception) + elif exception in ('posix.error', 'mac.error'): + x = os.error + if x == exception: + exception = x + raise exception, value + + def _vrecv(self, id): + self._flush() + if self._replies.has_key(id): + if self._verbose > 1: print "retrieving previous reply, id = %d" % id + reply = self._replies[id] + del self._replies[id] + return reply + aid = abs(id) + while 1: + if self._verbose > 1: print "waiting for reply, id = %d" % id + rp = pickle.Unpickler(self._rf) + reply = rp.load() + del rp + if self._verbose > 1: print "got reply: %s" % repr(reply) + rid = reply[2] + arid = abs(rid) + if arid == aid: + if self._verbose > 1: print "got it" + return reply + self._replies[rid] = reply + if arid > aid: + if self._verbose > 1: print "got higher id, assume all ok" + return (None, None, id) + + def _flush(self): + self._wf.flush() from security import Security @@ -131,28 +131,27 @@ from security import Security class SecureClient(Client, Security): - def __init__(self, *args): - import string - apply(self._pre_init, args) - Security.__init__(self) - self._wf.flush() - line = self._rf.readline() - challenge = string.atoi(string.strip(line)) - response = self._encode_challenge(challenge) - line = repr(long(response)) - if line[-1] in 'Ll': line = line[:-1] - self._wf.write(line + '\n') - self._wf.flush() - self._post_init() + def __init__(self, *args): + import string + apply(self._pre_init, args) + Security.__init__(self) + self._wf.flush() + line = self._rf.readline() + challenge = string.atoi(string.strip(line)) + response = self._encode_challenge(challenge) + line = repr(long(response)) + if line[-1] in 'Ll': line = line[:-1] + self._wf.write(line + '\n') + self._wf.flush() + self._post_init() class _stub: - - """Helper class for Client -- each instance serves as a method of the client.""" - - def __init__(self, client, name): - self._client = client - self._name = name - - def __call__(self, *args): - return self._client._vcall(self._name, args) + """Helper class for Client -- each instance serves as a method of the client.""" + + def __init__(self, client, name): + self._client = client + self._name = name + + def __call__(self, *args): + return self._client._vcall(self._name, args) diff --git a/Demo/pdist/cmdfw.py b/Demo/pdist/cmdfw.py index 25584b78f8..e2edd0a86e 100755 --- a/Demo/pdist/cmdfw.py +++ b/Demo/pdist/cmdfw.py @@ -3,142 +3,142 @@ class CommandFrameWork: - """Framework class for command line interfaces like CVS. - - The general command line structure is - - command [flags] subcommand [subflags] [argument] ... - - There's a class variable GlobalFlags which specifies the - global flags options. Subcommands are defined by defining - methods named do_. Flags for the subcommand are - defined by defining class or instance variables named - flags_. If there's no command, method default() - is called. The __doc__ strings for the do_ methods are used - for the usage message, printed after the general usage message - which is the class variable UsageMessage. The class variable - PostUsageMessage is printed after all the do_ methods' __doc__ - strings. The method's return value can be a suggested exit - status. [XXX Need to rewrite this to clarify it.] - - Common usage is to derive a class, instantiate it, and then call its - run() method; by default this takes its arguments from sys.argv[1:]. - """ - - UsageMessage = \ - "usage: (name)s [flags] subcommand [subflags] [argument] ..." - - PostUsageMessage = None - - GlobalFlags = '' - - def __init__(self): - """Constructor, present for completeness.""" - pass - - def run(self, args = None): - """Process flags, subcommand and options, then run it.""" - import getopt, sys - if args is None: args = sys.argv[1:] - try: - opts, args = getopt.getopt(args, self.GlobalFlags) - except getopt.error, msg: - return self.usage(msg) - self.options(opts) - if not args: - self.ready() - return self.default() - else: - cmd = args[0] - mname = 'do_' + cmd - fname = 'flags_' + cmd - try: - method = getattr(self, mname) - except AttributeError: - return self.usage("command %r unknown" % (cmd,)) - try: - flags = getattr(self, fname) - except AttributeError: - flags = '' - try: - opts, args = getopt.getopt(args[1:], flags) - except getopt.error, msg: - return self.usage( - "subcommand %s: " % cmd + str(msg)) - self.ready() - return method(opts, args) - - def options(self, opts): - """Process the options retrieved by getopt. - Override this if you have any options.""" - if opts: - print "-"*40 - print "Options:" - for o, a in opts: - print 'option', o, 'value', repr(a) - print "-"*40 - - def ready(self): - """Called just before calling the subcommand.""" - pass - - def usage(self, msg = None): - """Print usage message. Return suitable exit code (2).""" - if msg: print msg - print self.UsageMessage % {'name': self.__class__.__name__} - docstrings = {} - c = self.__class__ - while 1: - for name in dir(c): - if name[:3] == 'do_': - if docstrings.has_key(name): - continue - try: - doc = getattr(c, name).__doc__ - except: - doc = None - if doc: - docstrings[name] = doc - if not c.__bases__: - break - c = c.__bases__[0] - if docstrings: - print "where subcommand can be:" - names = docstrings.keys() - names.sort() - for name in names: - print docstrings[name] - if self.PostUsageMessage: - print self.PostUsageMessage - return 2 - - def default(self): - """Default method, called when no subcommand is given. - You should always override this.""" - print "Nobody expects the Spanish Inquisition!" + """Framework class for command line interfaces like CVS. + + The general command line structure is + + command [flags] subcommand [subflags] [argument] ... + + There's a class variable GlobalFlags which specifies the + global flags options. Subcommands are defined by defining + methods named do_. Flags for the subcommand are + defined by defining class or instance variables named + flags_. If there's no command, method default() + is called. The __doc__ strings for the do_ methods are used + for the usage message, printed after the general usage message + which is the class variable UsageMessage. The class variable + PostUsageMessage is printed after all the do_ methods' __doc__ + strings. The method's return value can be a suggested exit + status. [XXX Need to rewrite this to clarify it.] + + Common usage is to derive a class, instantiate it, and then call its + run() method; by default this takes its arguments from sys.argv[1:]. + """ + + UsageMessage = \ + "usage: (name)s [flags] subcommand [subflags] [argument] ..." + + PostUsageMessage = None + + GlobalFlags = '' + + def __init__(self): + """Constructor, present for completeness.""" + pass + + def run(self, args = None): + """Process flags, subcommand and options, then run it.""" + import getopt, sys + if args is None: args = sys.argv[1:] + try: + opts, args = getopt.getopt(args, self.GlobalFlags) + except getopt.error, msg: + return self.usage(msg) + self.options(opts) + if not args: + self.ready() + return self.default() + else: + cmd = args[0] + mname = 'do_' + cmd + fname = 'flags_' + cmd + try: + method = getattr(self, mname) + except AttributeError: + return self.usage("command %r unknown" % (cmd,)) + try: + flags = getattr(self, fname) + except AttributeError: + flags = '' + try: + opts, args = getopt.getopt(args[1:], flags) + except getopt.error, msg: + return self.usage( + "subcommand %s: " % cmd + str(msg)) + self.ready() + return method(opts, args) + + def options(self, opts): + """Process the options retrieved by getopt. + Override this if you have any options.""" + if opts: + print "-"*40 + print "Options:" + for o, a in opts: + print 'option', o, 'value', repr(a) + print "-"*40 + + def ready(self): + """Called just before calling the subcommand.""" + pass + + def usage(self, msg = None): + """Print usage message. Return suitable exit code (2).""" + if msg: print msg + print self.UsageMessage % {'name': self.__class__.__name__} + docstrings = {} + c = self.__class__ + while 1: + for name in dir(c): + if name[:3] == 'do_': + if docstrings.has_key(name): + continue + try: + doc = getattr(c, name).__doc__ + except: + doc = None + if doc: + docstrings[name] = doc + if not c.__bases__: + break + c = c.__bases__[0] + if docstrings: + print "where subcommand can be:" + names = docstrings.keys() + names.sort() + for name in names: + print docstrings[name] + if self.PostUsageMessage: + print self.PostUsageMessage + return 2 + + def default(self): + """Default method, called when no subcommand is given. + You should always override this.""" + print "Nobody expects the Spanish Inquisition!" def test(): - """Test script -- called when this module is run as a script.""" - import sys - class Hello(CommandFrameWork): - def do_hello(self, opts, args): - "hello -- print 'hello world', needs no arguments" - print "Hello, world" - x = Hello() - tests = [ - [], - ['hello'], - ['spam'], - ['-x'], - ['hello', '-x'], - None, - ] - for t in tests: - print '-'*10, t, '-'*10 - sts = x.run(t) - print "Exit status:", repr(sts) + """Test script -- called when this module is run as a script.""" + import sys + class Hello(CommandFrameWork): + def do_hello(self, opts, args): + "hello -- print 'hello world', needs no arguments" + print "Hello, world" + x = Hello() + tests = [ + [], + ['hello'], + ['spam'], + ['-x'], + ['hello', '-x'], + None, + ] + for t in tests: + print '-'*10, t, '-'*10 + sts = x.run(t) + print "Exit status:", repr(sts) if __name__ == '__main__': - test() + test() diff --git a/Demo/pdist/cmptree.py b/Demo/pdist/cmptree.py index 8a34f3f681..f6c611f696 100755 --- a/Demo/pdist/cmptree.py +++ b/Demo/pdist/cmptree.py @@ -7,202 +7,202 @@ import time import os def main(): - pwd = os.getcwd() - s = raw_input("chdir [%s] " % pwd) - if s: - os.chdir(s) - pwd = os.getcwd() - host = ask("host", 'voorn.cwi.nl') - port = 4127 - verbose = 1 - mode = '' - print """\ + pwd = os.getcwd() + s = raw_input("chdir [%s] " % pwd) + if s: + os.chdir(s) + pwd = os.getcwd() + host = ask("host", 'voorn.cwi.nl') + port = 4127 + verbose = 1 + mode = '' + print """\ Mode should be a string of characters, indicating what to do with differences. r - read different files to local file system w - write different files to remote file system c - create new files, either remote or local d - delete disappearing files, either remote or local """ - s = raw_input("mode [%s] " % mode) - if s: mode = s - address = (host, port) - t1 = time.time() - local = FSProxy.FSProxyLocal() - remote = FSProxy.FSProxyClient(address, verbose) - compare(local, remote, mode) - remote._close() - local._close() - t2 = time.time() - dt = t2-t1 - mins, secs = divmod(dt, 60) - print mins, "minutes and", round(secs), "seconds" - raw_input("[Return to exit] ") + s = raw_input("mode [%s] " % mode) + if s: mode = s + address = (host, port) + t1 = time.time() + local = FSProxy.FSProxyLocal() + remote = FSProxy.FSProxyClient(address, verbose) + compare(local, remote, mode) + remote._close() + local._close() + t2 = time.time() + dt = t2-t1 + mins, secs = divmod(dt, 60) + print mins, "minutes and", round(secs), "seconds" + raw_input("[Return to exit] ") def ask(prompt, default): - s = raw_input("%s [%s] " % (prompt, default)) - return s or default + s = raw_input("%s [%s] " % (prompt, default)) + return s or default def askint(prompt, default): - s = raw_input("%s [%s] " % (prompt, str(default))) - if s: return string.atoi(s) - return default + s = raw_input("%s [%s] " % (prompt, str(default))) + if s: return string.atoi(s) + return default def compare(local, remote, mode): - print - print "PWD =", repr(os.getcwd()) - sums_id = remote._send('sumlist') - subdirs_id = remote._send('listsubdirs') - remote._flush() - print "calculating local sums ..." - lsumdict = {} - for name, info in local.sumlist(): - lsumdict[name] = info - print "getting remote sums ..." - sums = remote._recv(sums_id) - print "got", len(sums) - rsumdict = {} - for name, rsum in sums: - rsumdict[name] = rsum - if not lsumdict.has_key(name): - print repr(name), "only remote" - if 'r' in mode and 'c' in mode: - recvfile(local, remote, name) - else: - lsum = lsumdict[name] - if lsum != rsum: - print repr(name), - rmtime = remote.mtime(name) - lmtime = local.mtime(name) - if rmtime > lmtime: - print "remote newer", - if 'r' in mode: - recvfile(local, remote, name) - elif lmtime > rmtime: - print "local newer", - if 'w' in mode: - sendfile(local, remote, name) - else: - print "same mtime but different sum?!?!", - print - for name in lsumdict.keys(): - if not rsumdict.keys(): - print repr(name), "only locally", - fl() - if 'w' in mode and 'c' in mode: - sendfile(local, remote, name) - elif 'r' in mode and 'd' in mode: - os.unlink(name) - print "removed." - print - print "gettin subdirs ..." - subdirs = remote._recv(subdirs_id) - common = [] - for name in subdirs: - if local.isdir(name): - print "Common subdirectory", repr(name) - common.append(name) - else: - print "Remote subdirectory", repr(name), "not found locally" - if 'r' in mode and 'c' in mode: - pr = "Create local subdirectory %s? [y] " % \ - repr(name) - if 'y' in mode: - ok = 'y' - else: - ok = ask(pr, "y") - if ok[:1] in ('y', 'Y'): - local.mkdir(name) - print "Subdirectory %s made" % \ - repr(name) - common.append(name) - lsubdirs = local.listsubdirs() - for name in lsubdirs: - if name not in subdirs: - print "Local subdirectory", repr(name), "not found remotely" - for name in common: - print "Entering subdirectory", repr(name) - local.cd(name) - remote.cd(name) - compare(local, remote, mode) - remote.back() - local.back() + print + print "PWD =", repr(os.getcwd()) + sums_id = remote._send('sumlist') + subdirs_id = remote._send('listsubdirs') + remote._flush() + print "calculating local sums ..." + lsumdict = {} + for name, info in local.sumlist(): + lsumdict[name] = info + print "getting remote sums ..." + sums = remote._recv(sums_id) + print "got", len(sums) + rsumdict = {} + for name, rsum in sums: + rsumdict[name] = rsum + if not lsumdict.has_key(name): + print repr(name), "only remote" + if 'r' in mode and 'c' in mode: + recvfile(local, remote, name) + else: + lsum = lsumdict[name] + if lsum != rsum: + print repr(name), + rmtime = remote.mtime(name) + lmtime = local.mtime(name) + if rmtime > lmtime: + print "remote newer", + if 'r' in mode: + recvfile(local, remote, name) + elif lmtime > rmtime: + print "local newer", + if 'w' in mode: + sendfile(local, remote, name) + else: + print "same mtime but different sum?!?!", + print + for name in lsumdict.keys(): + if not rsumdict.keys(): + print repr(name), "only locally", + fl() + if 'w' in mode and 'c' in mode: + sendfile(local, remote, name) + elif 'r' in mode and 'd' in mode: + os.unlink(name) + print "removed." + print + print "gettin subdirs ..." + subdirs = remote._recv(subdirs_id) + common = [] + for name in subdirs: + if local.isdir(name): + print "Common subdirectory", repr(name) + common.append(name) + else: + print "Remote subdirectory", repr(name), "not found locally" + if 'r' in mode and 'c' in mode: + pr = "Create local subdirectory %s? [y] " % \ + repr(name) + if 'y' in mode: + ok = 'y' + else: + ok = ask(pr, "y") + if ok[:1] in ('y', 'Y'): + local.mkdir(name) + print "Subdirectory %s made" % \ + repr(name) + common.append(name) + lsubdirs = local.listsubdirs() + for name in lsubdirs: + if name not in subdirs: + print "Local subdirectory", repr(name), "not found remotely" + for name in common: + print "Entering subdirectory", repr(name) + local.cd(name) + remote.cd(name) + compare(local, remote, mode) + remote.back() + local.back() def sendfile(local, remote, name): - try: - remote.create(name) - except (IOError, os.error), msg: - print "cannot create:", msg - return - - print "sending ...", - fl() - - data = open(name).read() - - t1 = time.time() - - remote._send_noreply('write', name, data) - remote._flush() - - t2 = time.time() - - dt = t2-t1 - print len(data), "bytes in", round(dt), "seconds", - if dt: - print "i.e.", round(len(data)/dt), "bytes/sec", - print + try: + remote.create(name) + except (IOError, os.error), msg: + print "cannot create:", msg + return + + print "sending ...", + fl() + + data = open(name).read() + + t1 = time.time() + + remote._send_noreply('write', name, data) + remote._flush() + + t2 = time.time() + + dt = t2-t1 + print len(data), "bytes in", round(dt), "seconds", + if dt: + print "i.e.", round(len(data)/dt), "bytes/sec", + print def recvfile(local, remote, name): - ok = 0 - try: - rv = recvfile_real(local, remote, name) - ok = 1 - return rv - finally: - if not ok: - print "*** recvfile of %r failed, deleting" % (name,) - local.delete(name) + ok = 0 + try: + rv = recvfile_real(local, remote, name) + ok = 1 + return rv + finally: + if not ok: + print "*** recvfile of %r failed, deleting" % (name,) + local.delete(name) def recvfile_real(local, remote, name): - try: - local.create(name) - except (IOError, os.error), msg: - print "cannot create:", msg - return - - print "receiving ...", - fl() - - f = open(name, 'w') - t1 = time.time() - - length = 4*1024 - offset = 0 - id = remote._send('read', name, offset, length) - remote._flush() - while 1: - newoffset = offset + length - newid = remote._send('read', name, newoffset, length) - data = remote._recv(id) - id = newid - if not data: break - f.seek(offset) - f.write(data) - offset = newoffset - size = f.tell() - - t2 = time.time() - f.close() - - dt = t2-t1 - print size, "bytes in", round(dt), "seconds", - if dt: - print "i.e.", int(size/dt), "bytes/sec", - print - remote._recv(id) # ignored + try: + local.create(name) + except (IOError, os.error), msg: + print "cannot create:", msg + return + + print "receiving ...", + fl() + + f = open(name, 'w') + t1 = time.time() + + length = 4*1024 + offset = 0 + id = remote._send('read', name, offset, length) + remote._flush() + while 1: + newoffset = offset + length + newid = remote._send('read', name, newoffset, length) + data = remote._recv(id) + id = newid + if not data: break + f.seek(offset) + f.write(data) + offset = newoffset + size = f.tell() + + t2 = time.time() + f.close() + + dt = t2-t1 + print size, "bytes in", round(dt), "seconds", + if dt: + print "i.e.", int(size/dt), "bytes/sec", + print + remote._recv(id) # ignored def fl(): - sys.stdout.flush() + sys.stdout.flush() if __name__ == '__main__': - main() + main() diff --git a/Demo/pdist/cvslib.py b/Demo/pdist/cvslib.py index 0f689c498b..ebcc69747c 100755 --- a/Demo/pdist/cvslib.py +++ b/Demo/pdist/cvslib.py @@ -7,358 +7,358 @@ import md5 import fnmatch if not hasattr(time, 'timezone'): - time.timezone = 0 + time.timezone = 0 class File: - """Represent a file's status. - - Instance variables: - - file -- the filename (no slashes), None if uninitialized - lseen -- true if the data for the local file is up to date - eseen -- true if the data from the CVS/Entries entry is up to date - (this implies that the entry must be written back) - rseen -- true if the data for the remote file is up to date - proxy -- RCSProxy instance used to contact the server, or None - - Note that lseen and rseen don't necessary mean that a local - or remote file *exists* -- they indicate that we've checked it. - However, eseen means that this instance corresponds to an - entry in the CVS/Entries file. - - If lseen is true: - - lsum -- checksum of the local file, None if no local file - lctime -- ctime of the local file, None if no local file - lmtime -- mtime of the local file, None if no local file - - If eseen is true: - - erev -- revision, None if this is a no revision (not '0') - enew -- true if this is an uncommitted added file - edeleted -- true if this is an uncommitted removed file - ectime -- ctime of last local file corresponding to erev - emtime -- mtime of last local file corresponding to erev - extra -- 5th string from CVS/Entries file - - If rseen is true: - - rrev -- revision of head, None if non-existent - rsum -- checksum of that revision, Non if non-existent - - If eseen and rseen are both true: - - esum -- checksum of revision erev, None if no revision - - Note - """ - - def __init__(self, file = None): - if file and '/' in file: - raise ValueError, "no slash allowed in file" - self.file = file - self.lseen = self.eseen = self.rseen = 0 - self.proxy = None - - def __cmp__(self, other): - return cmp(self.file, other.file) - - def getlocal(self): - try: - self.lmtime, self.lctime = os.stat(self.file)[-2:] - except os.error: - self.lmtime = self.lctime = self.lsum = None - else: - self.lsum = md5.new(open(self.file).read()).digest() - self.lseen = 1 - - def getentry(self, line): - words = string.splitfields(line, '/') - if self.file and words[1] != self.file: - raise ValueError, "file name mismatch" - self.file = words[1] - self.erev = words[2] - self.edeleted = 0 - self.enew = 0 - self.ectime = self.emtime = None - if self.erev[:1] == '-': - self.edeleted = 1 - self.erev = self.erev[1:] - if self.erev == '0': - self.erev = None - self.enew = 1 - else: - dates = words[3] - self.ectime = unctime(dates[:24]) - self.emtime = unctime(dates[25:]) - self.extra = words[4] - if self.rseen: - self.getesum() - self.eseen = 1 - - def getremote(self, proxy = None): - if proxy: - self.proxy = proxy - try: - self.rrev = self.proxy.head(self.file) - except (os.error, IOError): - self.rrev = None - if self.rrev: - self.rsum = self.proxy.sum(self.file) - else: - self.rsum = None - if self.eseen: - self.getesum() - self.rseen = 1 - - def getesum(self): - if self.erev == self.rrev: - self.esum = self.rsum - elif self.erev: - name = (self.file, self.erev) - self.esum = self.proxy.sum(name) - else: - self.esum = None - - def putentry(self): - """Return a line suitable for inclusion in CVS/Entries. - - The returned line is terminated by a newline. - If no entry should be written for this file, - return "". - """ - if not self.eseen: - return "" - - rev = self.erev or '0' - if self.edeleted: - rev = '-' + rev - if self.enew: - dates = 'Initial ' + self.file - else: - dates = gmctime(self.ectime) + ' ' + \ - gmctime(self.emtime) - return "/%s/%s/%s/%s/\n" % ( - self.file, - rev, - dates, - self.extra) - - def report(self): - print '-'*50 - def r(key, repr=repr, self=self): - try: - value = repr(getattr(self, key)) - except AttributeError: - value = "?" - print "%-15s:" % key, value - r("file") - if self.lseen: - r("lsum", hexify) - r("lctime", gmctime) - r("lmtime", gmctime) - if self.eseen: - r("erev") - r("enew") - r("edeleted") - r("ectime", gmctime) - r("emtime", gmctime) - if self.rseen: - r("rrev") - r("rsum", hexify) - if self.eseen: - r("esum", hexify) + """Represent a file's status. + + Instance variables: + + file -- the filename (no slashes), None if uninitialized + lseen -- true if the data for the local file is up to date + eseen -- true if the data from the CVS/Entries entry is up to date + (this implies that the entry must be written back) + rseen -- true if the data for the remote file is up to date + proxy -- RCSProxy instance used to contact the server, or None + + Note that lseen and rseen don't necessary mean that a local + or remote file *exists* -- they indicate that we've checked it. + However, eseen means that this instance corresponds to an + entry in the CVS/Entries file. + + If lseen is true: + + lsum -- checksum of the local file, None if no local file + lctime -- ctime of the local file, None if no local file + lmtime -- mtime of the local file, None if no local file + + If eseen is true: + + erev -- revision, None if this is a no revision (not '0') + enew -- true if this is an uncommitted added file + edeleted -- true if this is an uncommitted removed file + ectime -- ctime of last local file corresponding to erev + emtime -- mtime of last local file corresponding to erev + extra -- 5th string from CVS/Entries file + + If rseen is true: + + rrev -- revision of head, None if non-existent + rsum -- checksum of that revision, Non if non-existent + + If eseen and rseen are both true: + + esum -- checksum of revision erev, None if no revision + + Note + """ + + def __init__(self, file = None): + if file and '/' in file: + raise ValueError, "no slash allowed in file" + self.file = file + self.lseen = self.eseen = self.rseen = 0 + self.proxy = None + + def __cmp__(self, other): + return cmp(self.file, other.file) + + def getlocal(self): + try: + self.lmtime, self.lctime = os.stat(self.file)[-2:] + except os.error: + self.lmtime = self.lctime = self.lsum = None + else: + self.lsum = md5.new(open(self.file).read()).digest() + self.lseen = 1 + + def getentry(self, line): + words = string.splitfields(line, '/') + if self.file and words[1] != self.file: + raise ValueError, "file name mismatch" + self.file = words[1] + self.erev = words[2] + self.edeleted = 0 + self.enew = 0 + self.ectime = self.emtime = None + if self.erev[:1] == '-': + self.edeleted = 1 + self.erev = self.erev[1:] + if self.erev == '0': + self.erev = None + self.enew = 1 + else: + dates = words[3] + self.ectime = unctime(dates[:24]) + self.emtime = unctime(dates[25:]) + self.extra = words[4] + if self.rseen: + self.getesum() + self.eseen = 1 + + def getremote(self, proxy = None): + if proxy: + self.proxy = proxy + try: + self.rrev = self.proxy.head(self.file) + except (os.error, IOError): + self.rrev = None + if self.rrev: + self.rsum = self.proxy.sum(self.file) + else: + self.rsum = None + if self.eseen: + self.getesum() + self.rseen = 1 + + def getesum(self): + if self.erev == self.rrev: + self.esum = self.rsum + elif self.erev: + name = (self.file, self.erev) + self.esum = self.proxy.sum(name) + else: + self.esum = None + + def putentry(self): + """Return a line suitable for inclusion in CVS/Entries. + + The returned line is terminated by a newline. + If no entry should be written for this file, + return "". + """ + if not self.eseen: + return "" + + rev = self.erev or '0' + if self.edeleted: + rev = '-' + rev + if self.enew: + dates = 'Initial ' + self.file + else: + dates = gmctime(self.ectime) + ' ' + \ + gmctime(self.emtime) + return "/%s/%s/%s/%s/\n" % ( + self.file, + rev, + dates, + self.extra) + + def report(self): + print '-'*50 + def r(key, repr=repr, self=self): + try: + value = repr(getattr(self, key)) + except AttributeError: + value = "?" + print "%-15s:" % key, value + r("file") + if self.lseen: + r("lsum", hexify) + r("lctime", gmctime) + r("lmtime", gmctime) + if self.eseen: + r("erev") + r("enew") + r("edeleted") + r("ectime", gmctime) + r("emtime", gmctime) + if self.rseen: + r("rrev") + r("rsum", hexify) + if self.eseen: + r("esum", hexify) class CVS: - - """Represent the contents of a CVS admin file (and more). - - Class variables: - - FileClass -- the class to be instantiated for entries - (this should be derived from class File above) - IgnoreList -- shell patterns for local files to be ignored - - Instance variables: - - entries -- a dictionary containing File instances keyed by - their file name - proxy -- an RCSProxy instance, or None - """ - - FileClass = File - - IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc'] - - def __init__(self): - self.entries = {} - self.proxy = None - - def setproxy(self, proxy): - if proxy is self.proxy: - return - self.proxy = proxy - for e in self.entries.values(): - e.rseen = 0 - - def getentries(self): - """Read the contents of CVS/Entries""" - self.entries = {} - f = self.cvsopen("Entries") - while 1: - line = f.readline() - if not line: break - e = self.FileClass() - e.getentry(line) - self.entries[e.file] = e - f.close() - - def putentries(self): - """Write CVS/Entries back""" - f = self.cvsopen("Entries", 'w') - for e in self.values(): - f.write(e.putentry()) - f.close() - - def getlocalfiles(self): - list = self.entries.keys() - addlist = os.listdir(os.curdir) - for name in addlist: - if name in list: - continue - if not self.ignored(name): - list.append(name) - list.sort() - for file in list: - try: - e = self.entries[file] - except KeyError: - e = self.entries[file] = self.FileClass(file) - e.getlocal() - - def getremotefiles(self, proxy = None): - if proxy: - self.proxy = proxy - if not self.proxy: - raise RuntimeError, "no RCS proxy" - addlist = self.proxy.listfiles() - for file in addlist: - try: - e = self.entries[file] - except KeyError: - e = self.entries[file] = self.FileClass(file) - e.getremote(self.proxy) - - def report(self): - for e in self.values(): - e.report() - print '-'*50 - - def keys(self): - keys = self.entries.keys() - keys.sort() - return keys - - def values(self): - def value(key, self=self): - return self.entries[key] - return map(value, self.keys()) - - def items(self): - def item(key, self=self): - return (key, self.entries[key]) - return map(item, self.keys()) - - def cvsexists(self, file): - file = os.path.join("CVS", file) - return os.path.exists(file) - - def cvsopen(self, file, mode = 'r'): - file = os.path.join("CVS", file) - if 'r' not in mode: - self.backup(file) - return open(file, mode) - - def backup(self, file): - if os.path.isfile(file): - bfile = file + '~' - try: os.unlink(bfile) - except os.error: pass - os.rename(file, bfile) - - def ignored(self, file): - if os.path.isdir(file): return True - for pat in self.IgnoreList: - if fnmatch.fnmatch(file, pat): return True - return False + + """Represent the contents of a CVS admin file (and more). + + Class variables: + + FileClass -- the class to be instantiated for entries + (this should be derived from class File above) + IgnoreList -- shell patterns for local files to be ignored + + Instance variables: + + entries -- a dictionary containing File instances keyed by + their file name + proxy -- an RCSProxy instance, or None + """ + + FileClass = File + + IgnoreList = ['.*', '@*', ',*', '*~', '*.o', '*.a', '*.so', '*.pyc'] + + def __init__(self): + self.entries = {} + self.proxy = None + + def setproxy(self, proxy): + if proxy is self.proxy: + return + self.proxy = proxy + for e in self.entries.values(): + e.rseen = 0 + + def getentries(self): + """Read the contents of CVS/Entries""" + self.entries = {} + f = self.cvsopen("Entries") + while 1: + line = f.readline() + if not line: break + e = self.FileClass() + e.getentry(line) + self.entries[e.file] = e + f.close() + + def putentries(self): + """Write CVS/Entries back""" + f = self.cvsopen("Entries", 'w') + for e in self.values(): + f.write(e.putentry()) + f.close() + + def getlocalfiles(self): + list = self.entries.keys() + addlist = os.listdir(os.curdir) + for name in addlist: + if name in list: + continue + if not self.ignored(name): + list.append(name) + list.sort() + for file in list: + try: + e = self.entries[file] + except KeyError: + e = self.entries[file] = self.FileClass(file) + e.getlocal() + + def getremotefiles(self, proxy = None): + if proxy: + self.proxy = proxy + if not self.proxy: + raise RuntimeError, "no RCS proxy" + addlist = self.proxy.listfiles() + for file in addlist: + try: + e = self.entries[file] + except KeyError: + e = self.entries[file] = self.FileClass(file) + e.getremote(self.proxy) + + def report(self): + for e in self.values(): + e.report() + print '-'*50 + + def keys(self): + keys = self.entries.keys() + keys.sort() + return keys + + def values(self): + def value(key, self=self): + return self.entries[key] + return map(value, self.keys()) + + def items(self): + def item(key, self=self): + return (key, self.entries[key]) + return map(item, self.keys()) + + def cvsexists(self, file): + file = os.path.join("CVS", file) + return os.path.exists(file) + + def cvsopen(self, file, mode = 'r'): + file = os.path.join("CVS", file) + if 'r' not in mode: + self.backup(file) + return open(file, mode) + + def backup(self, file): + if os.path.isfile(file): + bfile = file + '~' + try: os.unlink(bfile) + except os.error: pass + os.rename(file, bfile) + + def ignored(self, file): + if os.path.isdir(file): return True + for pat in self.IgnoreList: + if fnmatch.fnmatch(file, pat): return True + return False # hexify and unhexify are useful to print MD5 checksums in hex format hexify_format = '%02x' * 16 def hexify(sum): - "Return a hex representation of a 16-byte string (e.g. an MD5 digest)" - if sum is None: - return "None" - return hexify_format % tuple(map(ord, sum)) + "Return a hex representation of a 16-byte string (e.g. an MD5 digest)" + if sum is None: + return "None" + return hexify_format % tuple(map(ord, sum)) def unhexify(hexsum): - "Return the original from a hexified string" - if hexsum == "None": - return None - sum = '' - for i in range(0, len(hexsum), 2): - sum = sum + chr(string.atoi(hexsum[i:i+2], 16)) - return sum + "Return the original from a hexified string" + if hexsum == "None": + return None + sum = '' + for i in range(0, len(hexsum), 2): + sum = sum + chr(string.atoi(hexsum[i:i+2], 16)) + return sum unctime_monthmap = {} def unctime(date): - if date == "None": return None - if not unctime_monthmap: - months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - i = 0 - for m in months: - i = i+1 - unctime_monthmap[m] = i - words = string.split(date) # Day Mon DD HH:MM:SS YEAR - year = string.atoi(words[4]) - month = unctime_monthmap[words[1]] - day = string.atoi(words[2]) - [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':')) - ss = ss - time.timezone - return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0)) + if date == "None": return None + if not unctime_monthmap: + months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] + i = 0 + for m in months: + i = i+1 + unctime_monthmap[m] = i + words = string.split(date) # Day Mon DD HH:MM:SS YEAR + year = string.atoi(words[4]) + month = unctime_monthmap[words[1]] + day = string.atoi(words[2]) + [hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':')) + ss = ss - time.timezone + return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0)) def gmctime(t): - if t is None: return "None" - return time.asctime(time.gmtime(t)) + if t is None: return "None" + return time.asctime(time.gmtime(t)) def test_unctime(): - now = int(time.time()) - t = time.gmtime(now) - at = time.asctime(t) - print 'GMT', now, at - print 'timezone', time.timezone - print 'local', time.ctime(now) - u = unctime(at) - print 'unctime()', u - gu = time.gmtime(u) - print '->', gu - print time.asctime(gu) + now = int(time.time()) + t = time.gmtime(now) + at = time.asctime(t) + print 'GMT', now, at + print 'timezone', time.timezone + print 'local', time.ctime(now) + u = unctime(at) + print 'unctime()', u + gu = time.gmtime(u) + print '->', gu + print time.asctime(gu) def test(): - x = CVS() - x.getentries() - x.getlocalfiles() -## x.report() - import rcsclient - proxy = rcsclient.openrcsclient() - x.getremotefiles(proxy) - x.report() + x = CVS() + x.getentries() + x.getlocalfiles() +## x.report() + import rcsclient + proxy = rcsclient.openrcsclient() + x.getremotefiles(proxy) + x.report() if __name__ == "__main__": - test() + test() diff --git a/Demo/pdist/cvslock.py b/Demo/pdist/cvslock.py index 75f866ee35..8f6d008cbf 100755 --- a/Demo/pdist/cvslock.py +++ b/Demo/pdist/cvslock.py @@ -22,25 +22,25 @@ a write lock is held. - To set a read lock: - - acquire the meta-lock - - create the file "#cvs.rfl." - - release the meta-lock + - acquire the meta-lock + - create the file "#cvs.rfl." + - release the meta-lock - To set a write lock: - - acquire the meta-lock - - check that there are no files called "#cvs.rfl.*" - - if there are, release the meta-lock, sleep, try again - - create the file "#cvs.wfl." + - acquire the meta-lock + - check that there are no files called "#cvs.rfl.*" + - if there are, release the meta-lock, sleep, try again + - create the file "#cvs.wfl." - To release a write lock: - - remove the file "#cvs.wfl." - - rmdir the meta-lock + - remove the file "#cvs.wfl." + - rmdir the meta-lock - To release a read lock: - - remove the file "#cvs.rfl." + - remove the file "#cvs.rfl." Additional notes @@ -93,188 +93,188 @@ CVSWFL = "#cvs.wfl." class Error: - def __init__(self, msg): - self.msg = msg + def __init__(self, msg): + self.msg = msg - def __repr__(self): - return repr(self.msg) + def __repr__(self): + return repr(self.msg) - def __str__(self): - return str(self.msg) + def __str__(self): + return str(self.msg) class Locked(Error): - pass + pass class Lock: - def __init__(self, repository = ".", delay = DELAY): - self.repository = repository - self.delay = delay - self.lockdir = None - self.lockfile = None - pid = repr(os.getpid()) - self.cvslck = self.join(CVSLCK) - self.cvsrfl = self.join(CVSRFL + pid) - self.cvswfl = self.join(CVSWFL + pid) - - def __del__(self): - print "__del__" - self.unlock() - - def setlockdir(self): - while 1: - try: - self.lockdir = self.cvslck - os.mkdir(self.cvslck, 0777) - return - except os.error, msg: - self.lockdir = None - if msg[0] == EEXIST: - try: - st = os.stat(self.cvslck) - except os.error: - continue - self.sleep(st) - continue - raise Error("failed to lock %s: %s" % ( - self.repository, msg)) - - def unlock(self): - self.unlockfile() - self.unlockdir() - - def unlockfile(self): - if self.lockfile: - print "unlink", self.lockfile - try: - os.unlink(self.lockfile) - except os.error: - pass - self.lockfile = None - - def unlockdir(self): - if self.lockdir: - print "rmdir", self.lockdir - try: - os.rmdir(self.lockdir) - except os.error: - pass - self.lockdir = None - - def sleep(self, st): - sleep(st, self.repository, self.delay) - - def join(self, name): - return os.path.join(self.repository, name) + def __init__(self, repository = ".", delay = DELAY): + self.repository = repository + self.delay = delay + self.lockdir = None + self.lockfile = None + pid = repr(os.getpid()) + self.cvslck = self.join(CVSLCK) + self.cvsrfl = self.join(CVSRFL + pid) + self.cvswfl = self.join(CVSWFL + pid) + + def __del__(self): + print "__del__" + self.unlock() + + def setlockdir(self): + while 1: + try: + self.lockdir = self.cvslck + os.mkdir(self.cvslck, 0777) + return + except os.error, msg: + self.lockdir = None + if msg[0] == EEXIST: + try: + st = os.stat(self.cvslck) + except os.error: + continue + self.sleep(st) + continue + raise Error("failed to lock %s: %s" % ( + self.repository, msg)) + + def unlock(self): + self.unlockfile() + self.unlockdir() + + def unlockfile(self): + if self.lockfile: + print "unlink", self.lockfile + try: + os.unlink(self.lockfile) + except os.error: + pass + self.lockfile = None + + def unlockdir(self): + if self.lockdir: + print "rmdir", self.lockdir + try: + os.rmdir(self.lockdir) + except os.error: + pass + self.lockdir = None + + def sleep(self, st): + sleep(st, self.repository, self.delay) + + def join(self, name): + return os.path.join(self.repository, name) def sleep(st, repository, delay): - if delay <= 0: - raise Locked(st) - uid = st[stat.ST_UID] - try: - pwent = pwd.getpwuid(uid) - user = pwent[0] - except KeyError: - user = "uid %d" % uid - print "[%s]" % time.ctime(time.time())[11:19], - print "Waiting for %s's lock in" % user, repository - time.sleep(delay) + if delay <= 0: + raise Locked(st) + uid = st[stat.ST_UID] + try: + pwent = pwd.getpwuid(uid) + user = pwent[0] + except KeyError: + user = "uid %d" % uid + print "[%s]" % time.ctime(time.time())[11:19], + print "Waiting for %s's lock in" % user, repository + time.sleep(delay) class ReadLock(Lock): - def __init__(self, repository, delay = DELAY): - Lock.__init__(self, repository, delay) - ok = 0 - try: - self.setlockdir() - self.lockfile = self.cvsrfl - fp = open(self.lockfile, 'w') - fp.close() - ok = 1 - finally: - if not ok: - self.unlockfile() - self.unlockdir() + def __init__(self, repository, delay = DELAY): + Lock.__init__(self, repository, delay) + ok = 0 + try: + self.setlockdir() + self.lockfile = self.cvsrfl + fp = open(self.lockfile, 'w') + fp.close() + ok = 1 + finally: + if not ok: + self.unlockfile() + self.unlockdir() class WriteLock(Lock): - def __init__(self, repository, delay = DELAY): - Lock.__init__(self, repository, delay) - self.setlockdir() - while 1: - uid = self.readers_exist() - if not uid: - break - self.unlockdir() - self.sleep(uid) - self.lockfile = self.cvswfl - fp = open(self.lockfile, 'w') - fp.close() - - def readers_exist(self): - n = len(CVSRFL) - for name in os.listdir(self.repository): - if name[:n] == CVSRFL: - try: - st = os.stat(self.join(name)) - except os.error: - continue - return st - return None + def __init__(self, repository, delay = DELAY): + Lock.__init__(self, repository, delay) + self.setlockdir() + while 1: + uid = self.readers_exist() + if not uid: + break + self.unlockdir() + self.sleep(uid) + self.lockfile = self.cvswfl + fp = open(self.lockfile, 'w') + fp.close() + + def readers_exist(self): + n = len(CVSRFL) + for name in os.listdir(self.repository): + if name[:n] == CVSRFL: + try: + st = os.stat(self.join(name)) + except os.error: + continue + return st + return None def MultipleWriteLock(repositories, delay = DELAY): - while 1: - locks = [] - for r in repositories: - try: - locks.append(WriteLock(r, 0)) - except Locked, instance: - del locks - break - else: - break - sleep(instance.msg, r, delay) - return list + while 1: + locks = [] + for r in repositories: + try: + locks.append(WriteLock(r, 0)) + except Locked, instance: + del locks + break + else: + break + sleep(instance.msg, r, delay) + return list def test(): - import sys - if sys.argv[1:]: - repository = sys.argv[1] - else: - repository = "." - rl = None - wl = None - try: - print "attempting write lock ..." - wl = WriteLock(repository) - print "got it." - wl.unlock() - print "attempting read lock ..." - rl = ReadLock(repository) - print "got it." - rl.unlock() - finally: - print [1] - sys.exc_traceback = None - print [2] - if rl: - rl.unlock() - print [3] - if wl: - wl.unlock() - print [4] - rl = None - print [5] - wl = None - print [6] + import sys + if sys.argv[1:]: + repository = sys.argv[1] + else: + repository = "." + rl = None + wl = None + try: + print "attempting write lock ..." + wl = WriteLock(repository) + print "got it." + wl.unlock() + print "attempting read lock ..." + rl = ReadLock(repository) + print "got it." + rl.unlock() + finally: + print [1] + sys.exc_traceback = None + print [2] + if rl: + rl.unlock() + print [3] + if wl: + wl.unlock() + print [4] + rl = None + print [5] + wl = None + print [6] if __name__ == '__main__': - test() + test() diff --git a/Demo/pdist/mac.py b/Demo/pdist/mac.py index 516ee153e4..107113c18a 100755 --- a/Demo/pdist/mac.py +++ b/Demo/pdist/mac.py @@ -3,17 +3,17 @@ import string import rcvs def main(): - while 1: - try: - line = raw_input('$ ') - except EOFError: - break - words = string.split(line) - if not words: - continue - if words[0] != 'rcvs': - words.insert(0, 'rcvs') - sys.argv = words - rcvs.main() + while 1: + try: + line = raw_input('$ ') + except EOFError: + break + words = string.split(line) + if not words: + continue + if words[0] != 'rcvs': + words.insert(0, 'rcvs') + sys.argv = words + rcvs.main() main() diff --git a/Demo/pdist/rcsclient.py b/Demo/pdist/rcsclient.py index 5d88a57981..d8cb004b2f 100755 --- a/Demo/pdist/rcsclient.py +++ b/Demo/pdist/rcsclient.py @@ -21,51 +21,51 @@ import client class RCSProxyClient(client.SecureClient): - - def __init__(self, address, verbose = client.VERBOSE): - client.SecureClient.__init__(self, address, verbose) + + def __init__(self, address, verbose = client.VERBOSE): + client.SecureClient.__init__(self, address, verbose) def openrcsclient(opts = []): - "open an RCSProxy client based on a list of options returned by getopt" - import RCSProxy - host = HOST - port = PORT - verbose = VERBOSE - local = LOCAL - directory = None - for o, a in opts: - if o == '-h': - host = a - if ':' in host: - i = string.find(host, ':') - host, p = host[:i], host[i+1:] - if p: - port = string.atoi(p) - if o == '-p': - port = string.atoi(a) - if o == '-d': - directory = a - if o == '-v': - verbose = verbose + 1 - if o == '-q': - verbose = 0 - if o == '-L': - local = 1 - if local: - import RCSProxy - x = RCSProxy.RCSProxyLocal() - else: - address = (host, port) - x = RCSProxyClient(address, verbose) - if not directory: - try: - directory = open(os.path.join("CVS", "Repository")).readline() - except IOError: - pass - else: - if directory[-1] == '\n': - directory = directory[:-1] - if directory: - x.cd(directory) - return x + "open an RCSProxy client based on a list of options returned by getopt" + import RCSProxy + host = HOST + port = PORT + verbose = VERBOSE + local = LOCAL + directory = None + for o, a in opts: + if o == '-h': + host = a + if ':' in host: + i = string.find(host, ':') + host, p = host[:i], host[i+1:] + if p: + port = string.atoi(p) + if o == '-p': + port = string.atoi(a) + if o == '-d': + directory = a + if o == '-v': + verbose = verbose + 1 + if o == '-q': + verbose = 0 + if o == '-L': + local = 1 + if local: + import RCSProxy + x = RCSProxy.RCSProxyLocal() + else: + address = (host, port) + x = RCSProxyClient(address, verbose) + if not directory: + try: + directory = open(os.path.join("CVS", "Repository")).readline() + except IOError: + pass + else: + if directory[-1] == '\n': + directory = directory[:-1] + if directory: + x.cd(directory) + return x diff --git a/Demo/pdist/rcslib.py b/Demo/pdist/rcslib.py index 78de111b14..d5f7b65d96 100755 --- a/Demo/pdist/rcslib.py +++ b/Demo/pdist/rcslib.py @@ -83,7 +83,7 @@ class RCS: if line[0] == '\t': # XXX could be a lock or symbolic name # Anything else? - continue + continue i = string.find(line, ':') if i > 0: key, value = line[:i], string.strip(line[i+1:]) @@ -287,7 +287,7 @@ class RCS: if reason&0x80: code = code + '(coredump)' return code, signal - + def _system(self, cmd): """INTERNAL: run COMMAND in a subshell. @@ -311,7 +311,7 @@ class RCS: If a second PATTERN argument is given, only files matching it are kept. No check for valid filenames is made. - + """ if pat: def keep(name, pat = pat): diff --git a/Demo/pdist/rcvs.py b/Demo/pdist/rcvs.py index 24036c7721..8b8bae63b9 100755 --- a/Demo/pdist/rcvs.py +++ b/Demo/pdist/rcvs.py @@ -40,188 +40,188 @@ import sys from cmdfw import CommandFrameWork -DEF_LOCAL = 1 # Default -l +DEF_LOCAL = 1 # Default -l class MyFile(File): - def action(self): - """Return a code indicating the update status of this file. - - The possible return values are: - - '=' -- everything's fine - '0' -- file doesn't exist anywhere - '?' -- exists locally only - 'A' -- new locally - 'R' -- deleted locally - 'U' -- changed remotely, no changes locally - (includes new remotely or deleted remotely) - 'M' -- changed locally, no changes remotely - 'C' -- conflict: changed locally as well as remotely - (includes cases where the file has been added - or removed locally and remotely) - 'D' -- deleted remotely - 'N' -- new remotely - 'r' -- get rid of entry - 'c' -- create entry - 'u' -- update entry - - (and probably others :-) - """ - if not self.lseen: - self.getlocal() - if not self.rseen: - self.getremote() - if not self.eseen: - if not self.lsum: - if not self.rsum: return '0' # Never heard of - else: - return 'N' # New remotely - else: # self.lsum - if not self.rsum: return '?' # Local only - # Local and remote, but no entry - if self.lsum == self.rsum: - return 'c' # Restore entry only - else: return 'C' # Real conflict - else: # self.eseen - if not self.lsum: - if self.edeleted: - if self.rsum: return 'R' # Removed - else: return 'r' # Get rid of entry - else: # not self.edeleted - if self.rsum: - print "warning:", - print self.file, - print "was lost" - return 'U' - else: return 'r' # Get rid of entry - else: # self.lsum - if not self.rsum: - if self.enew: return 'A' # New locally - else: return 'D' # Deleted remotely - else: # self.rsum - if self.enew: - if self.lsum == self.rsum: - return 'u' - else: - return 'C' - if self.lsum == self.esum: - if self.esum == self.rsum: - return '=' - else: - return 'U' - elif self.esum == self.rsum: - return 'M' - elif self.lsum == self.rsum: - return 'u' - else: - return 'C' - - def update(self): - code = self.action() - if code == '=': return - print code, self.file - if code in ('U', 'N'): - self.get() - elif code == 'C': - print "%s: conflict resolution not yet implemented" % \ - self.file - elif code == 'D': - remove(self.file) - self.eseen = 0 - elif code == 'r': - self.eseen = 0 - elif code in ('c', 'u'): - self.eseen = 1 - self.erev = self.rrev - self.enew = 0 - self.edeleted = 0 - self.esum = self.rsum - self.emtime, self.ectime = os.stat(self.file)[-2:] - self.extra = '' - - def commit(self, message = ""): - code = self.action() - if code in ('A', 'M'): - self.put(message) - return 1 - elif code == 'R': - print "%s: committing removes not yet implemented" % \ - self.file - elif code == 'C': - print "%s: conflict resolution not yet implemented" % \ - self.file - - def diff(self, opts = []): - self.action() # To update lseen, rseen - flags = '' - rev = self.rrev - # XXX should support two rev options too! - for o, a in opts: - if o == '-r': - rev = a - else: - flags = flags + ' ' + o + a - if rev == self.rrev and self.lsum == self.rsum: - return - flags = flags[1:] - fn = self.file - data = self.proxy.get((fn, rev)) - sum = md5.new(data).digest() - if self.lsum == sum: - return - import tempfile - tf = tempfile.NamedTemporaryFile() - tf.write(data) - tf.flush() - print 'diff %s -r%s %s' % (flags, rev, fn) - sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) - if sts: - print '='*70 - - def commitcheck(self): - return self.action() != 'C' - - def put(self, message = ""): - print "Checking in", self.file, "..." - data = open(self.file).read() - if not self.enew: - self.proxy.lock(self.file) - messages = self.proxy.put(self.file, data, message) - if messages: - print messages - self.setentry(self.proxy.head(self.file), self.lsum) - - def get(self): - data = self.proxy.get(self.file) - f = open(self.file, 'w') - f.write(data) - f.close() - self.setentry(self.rrev, self.rsum) - - def log(self, otherflags): - print self.proxy.log(self.file, otherflags) - - def add(self): - self.eseen = 0 # While we're hacking... - self.esum = self.lsum - self.emtime, self.ectime = 0, 0 - self.erev = '' - self.enew = 1 - self.edeleted = 0 - self.eseen = 1 # Done - self.extra = '' - - def setentry(self, erev, esum): - self.eseen = 0 # While we're hacking... - self.esum = esum - self.emtime, self.ectime = os.stat(self.file)[-2:] - self.erev = erev - self.enew = 0 - self.edeleted = 0 - self.eseen = 1 # Done - self.extra = '' + def action(self): + """Return a code indicating the update status of this file. + + The possible return values are: + + '=' -- everything's fine + '0' -- file doesn't exist anywhere + '?' -- exists locally only + 'A' -- new locally + 'R' -- deleted locally + 'U' -- changed remotely, no changes locally + (includes new remotely or deleted remotely) + 'M' -- changed locally, no changes remotely + 'C' -- conflict: changed locally as well as remotely + (includes cases where the file has been added + or removed locally and remotely) + 'D' -- deleted remotely + 'N' -- new remotely + 'r' -- get rid of entry + 'c' -- create entry + 'u' -- update entry + + (and probably others :-) + """ + if not self.lseen: + self.getlocal() + if not self.rseen: + self.getremote() + if not self.eseen: + if not self.lsum: + if not self.rsum: return '0' # Never heard of + else: + return 'N' # New remotely + else: # self.lsum + if not self.rsum: return '?' # Local only + # Local and remote, but no entry + if self.lsum == self.rsum: + return 'c' # Restore entry only + else: return 'C' # Real conflict + else: # self.eseen + if not self.lsum: + if self.edeleted: + if self.rsum: return 'R' # Removed + else: return 'r' # Get rid of entry + else: # not self.edeleted + if self.rsum: + print "warning:", + print self.file, + print "was lost" + return 'U' + else: return 'r' # Get rid of entry + else: # self.lsum + if not self.rsum: + if self.enew: return 'A' # New locally + else: return 'D' # Deleted remotely + else: # self.rsum + if self.enew: + if self.lsum == self.rsum: + return 'u' + else: + return 'C' + if self.lsum == self.esum: + if self.esum == self.rsum: + return '=' + else: + return 'U' + elif self.esum == self.rsum: + return 'M' + elif self.lsum == self.rsum: + return 'u' + else: + return 'C' + + def update(self): + code = self.action() + if code == '=': return + print code, self.file + if code in ('U', 'N'): + self.get() + elif code == 'C': + print "%s: conflict resolution not yet implemented" % \ + self.file + elif code == 'D': + remove(self.file) + self.eseen = 0 + elif code == 'r': + self.eseen = 0 + elif code in ('c', 'u'): + self.eseen = 1 + self.erev = self.rrev + self.enew = 0 + self.edeleted = 0 + self.esum = self.rsum + self.emtime, self.ectime = os.stat(self.file)[-2:] + self.extra = '' + + def commit(self, message = ""): + code = self.action() + if code in ('A', 'M'): + self.put(message) + return 1 + elif code == 'R': + print "%s: committing removes not yet implemented" % \ + self.file + elif code == 'C': + print "%s: conflict resolution not yet implemented" % \ + self.file + + def diff(self, opts = []): + self.action() # To update lseen, rseen + flags = '' + rev = self.rrev + # XXX should support two rev options too! + for o, a in opts: + if o == '-r': + rev = a + else: + flags = flags + ' ' + o + a + if rev == self.rrev and self.lsum == self.rsum: + return + flags = flags[1:] + fn = self.file + data = self.proxy.get((fn, rev)) + sum = md5.new(data).digest() + if self.lsum == sum: + return + import tempfile + tf = tempfile.NamedTemporaryFile() + tf.write(data) + tf.flush() + print 'diff %s -r%s %s' % (flags, rev, fn) + sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) + if sts: + print '='*70 + + def commitcheck(self): + return self.action() != 'C' + + def put(self, message = ""): + print "Checking in", self.file, "..." + data = open(self.file).read() + if not self.enew: + self.proxy.lock(self.file) + messages = self.proxy.put(self.file, data, message) + if messages: + print messages + self.setentry(self.proxy.head(self.file), self.lsum) + + def get(self): + data = self.proxy.get(self.file) + f = open(self.file, 'w') + f.write(data) + f.close() + self.setentry(self.rrev, self.rsum) + + def log(self, otherflags): + print self.proxy.log(self.file, otherflags) + + def add(self): + self.eseen = 0 # While we're hacking... + self.esum = self.lsum + self.emtime, self.ectime = 0, 0 + self.erev = '' + self.enew = 1 + self.edeleted = 0 + self.eseen = 1 # Done + self.extra = '' + + def setentry(self, erev, esum): + self.eseen = 0 # While we're hacking... + self.esum = esum + self.emtime, self.ectime = os.stat(self.file)[-2:] + self.erev = erev + self.enew = 0 + self.edeleted = 0 + self.eseen = 1 # Done + self.extra = '' SENDMAIL = "/usr/lib/sendmail -t" @@ -231,247 +231,247 @@ Subject: CVS changes: %s ...Message from rcvs... Committed files: - %s + %s Log message: - %s + %s """ class RCVS(CVS): - FileClass = MyFile - - def __init__(self): - CVS.__init__(self) - - def update(self, files): - for e in self.whichentries(files, 1): - e.update() - - def commit(self, files, message = ""): - list = self.whichentries(files) - if not list: return - ok = 1 - for e in list: - if not e.commitcheck(): - ok = 0 - if not ok: - print "correct above errors first" - return - if not message: - message = raw_input("One-liner: ") - committed = [] - for e in list: - if e.commit(message): - committed.append(e.file) - self.mailinfo(committed, message) - - def mailinfo(self, files, message = ""): - towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX - mailtext = MAILFORM % (towhom, string.join(files), - string.join(files), message) - print '-'*70 - print mailtext - print '-'*70 - ok = raw_input("OK to mail to %s? " % towhom) - if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'): - p = os.popen(SENDMAIL, "w") - p.write(mailtext) - sts = p.close() - if sts: - print "Sendmail exit status %s" % str(sts) - else: - print "Mail sent." - else: - print "No mail sent." - - def report(self, files): - for e in self.whichentries(files): - e.report() - - def diff(self, files, opts): - for e in self.whichentries(files): - e.diff(opts) - - def add(self, files): - if not files: - raise RuntimeError, "'cvs add' needs at least one file" - list = [] - for e in self.whichentries(files, 1): - e.add() - - def rm(self, files): - if not files: - raise RuntimeError, "'cvs rm' needs at least one file" - raise RuntimeError, "'cvs rm' not yet imlemented" - - def log(self, files, opts): - flags = '' - for o, a in opts: - flags = flags + ' ' + o + a - for e in self.whichentries(files): - e.log(flags) - - def whichentries(self, files, localfilestoo = 0): - if files: - list = [] - for file in files: - if self.entries.has_key(file): - e = self.entries[file] - else: - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - else: - list = self.entries.values() - for file in self.proxy.listfiles(): - if self.entries.has_key(file): - continue - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - if localfilestoo: - for file in os.listdir(os.curdir): - if not self.entries.has_key(file) \ - and not self.ignored(file): - e = self.FileClass(file) - self.entries[file] = e - list.append(e) - list.sort() - if self.proxy: - for e in list: - if e.proxy is None: - e.proxy = self.proxy - return list + FileClass = MyFile + + def __init__(self): + CVS.__init__(self) + + def update(self, files): + for e in self.whichentries(files, 1): + e.update() + + def commit(self, files, message = ""): + list = self.whichentries(files) + if not list: return + ok = 1 + for e in list: + if not e.commitcheck(): + ok = 0 + if not ok: + print "correct above errors first" + return + if not message: + message = raw_input("One-liner: ") + committed = [] + for e in list: + if e.commit(message): + committed.append(e.file) + self.mailinfo(committed, message) + + def mailinfo(self, files, message = ""): + towhom = "sjoerd@cwi.nl, jack@cwi.nl" # XXX + mailtext = MAILFORM % (towhom, string.join(files), + string.join(files), message) + print '-'*70 + print mailtext + print '-'*70 + ok = raw_input("OK to mail to %s? " % towhom) + if string.lower(string.strip(ok)) in ('y', 'ye', 'yes'): + p = os.popen(SENDMAIL, "w") + p.write(mailtext) + sts = p.close() + if sts: + print "Sendmail exit status %s" % str(sts) + else: + print "Mail sent." + else: + print "No mail sent." + + def report(self, files): + for e in self.whichentries(files): + e.report() + + def diff(self, files, opts): + for e in self.whichentries(files): + e.diff(opts) + + def add(self, files): + if not files: + raise RuntimeError, "'cvs add' needs at least one file" + list = [] + for e in self.whichentries(files, 1): + e.add() + + def rm(self, files): + if not files: + raise RuntimeError, "'cvs rm' needs at least one file" + raise RuntimeError, "'cvs rm' not yet imlemented" + + def log(self, files, opts): + flags = '' + for o, a in opts: + flags = flags + ' ' + o + a + for e in self.whichentries(files): + e.log(flags) + + def whichentries(self, files, localfilestoo = 0): + if files: + list = [] + for file in files: + if self.entries.has_key(file): + e = self.entries[file] + else: + e = self.FileClass(file) + self.entries[file] = e + list.append(e) + else: + list = self.entries.values() + for file in self.proxy.listfiles(): + if self.entries.has_key(file): + continue + e = self.FileClass(file) + self.entries[file] = e + list.append(e) + if localfilestoo: + for file in os.listdir(os.curdir): + if not self.entries.has_key(file) \ + and not self.ignored(file): + e = self.FileClass(file) + self.entries[file] = e + list.append(e) + list.sort() + if self.proxy: + for e in list: + if e.proxy is None: + e.proxy = self.proxy + return list class rcvs(CommandFrameWork): - GlobalFlags = 'd:h:p:qvL' - UsageMessage = \ + GlobalFlags = 'd:h:p:qvL' + UsageMessage = \ "usage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]" - PostUsageMessage = \ - "If no subcommand is given, the status of all files is listed" - - def __init__(self): - """Constructor.""" - CommandFrameWork.__init__(self) - self.proxy = None - self.cvs = RCVS() - - def close(self): - if self.proxy: - self.proxy._close() - self.proxy = None - - def recurse(self): - self.close() - names = os.listdir(os.curdir) - for name in names: - if name == os.curdir or name == os.pardir: - continue - if name == "CVS": - continue - if not os.path.isdir(name): - continue - if os.path.islink(name): - continue - print "--- entering subdirectory", name, "---" - os.chdir(name) - try: - if os.path.isdir("CVS"): - self.__class__().run() - else: - self.recurse() - finally: - os.chdir(os.pardir) - print "--- left subdirectory", name, "---" - - def options(self, opts): - self.opts = opts - - def ready(self): - import rcsclient - self.proxy = rcsclient.openrcsclient(self.opts) - self.cvs.setproxy(self.proxy) - self.cvs.getentries() - - def default(self): - self.cvs.report([]) - - def do_report(self, opts, files): - self.cvs.report(files) - - def do_update(self, opts, files): - """update [-l] [-R] [file] ...""" - local = DEF_LOCAL - for o, a in opts: - if o == '-l': local = 1 - if o == '-R': local = 0 - self.cvs.update(files) - self.cvs.putentries() - if not local and not files: - self.recurse() - flags_update = '-lR' - do_up = do_update - flags_up = flags_update - - def do_commit(self, opts, files): - """commit [-m message] [file] ...""" - message = "" - for o, a in opts: - if o == '-m': message = a - self.cvs.commit(files, message) - self.cvs.putentries() - flags_commit = 'm:' - do_com = do_commit - flags_com = flags_commit - - def do_diff(self, opts, files): - """diff [difflags] [file] ...""" - self.cvs.diff(files, opts) - flags_diff = 'cbitwcefhnlr:sD:S:' - do_dif = do_diff - flags_dif = flags_diff - - def do_add(self, opts, files): - """add file ...""" - if not files: - print "'rcvs add' requires at least one file" - return - self.cvs.add(files) - self.cvs.putentries() - - def do_remove(self, opts, files): - """remove file ...""" - if not files: - print "'rcvs remove' requires at least one file" - return - self.cvs.remove(files) - self.cvs.putentries() - do_rm = do_remove - - def do_log(self, opts, files): - """log [rlog-options] [file] ...""" - self.cvs.log(files, opts) - flags_log = 'bhLNRtd:s:V:r:' + PostUsageMessage = \ + "If no subcommand is given, the status of all files is listed" + + def __init__(self): + """Constructor.""" + CommandFrameWork.__init__(self) + self.proxy = None + self.cvs = RCVS() + + def close(self): + if self.proxy: + self.proxy._close() + self.proxy = None + + def recurse(self): + self.close() + names = os.listdir(os.curdir) + for name in names: + if name == os.curdir or name == os.pardir: + continue + if name == "CVS": + continue + if not os.path.isdir(name): + continue + if os.path.islink(name): + continue + print "--- entering subdirectory", name, "---" + os.chdir(name) + try: + if os.path.isdir("CVS"): + self.__class__().run() + else: + self.recurse() + finally: + os.chdir(os.pardir) + print "--- left subdirectory", name, "---" + + def options(self, opts): + self.opts = opts + + def ready(self): + import rcsclient + self.proxy = rcsclient.openrcsclient(self.opts) + self.cvs.setproxy(self.proxy) + self.cvs.getentries() + + def default(self): + self.cvs.report([]) + + def do_report(self, opts, files): + self.cvs.report(files) + + def do_update(self, opts, files): + """update [-l] [-R] [file] ...""" + local = DEF_LOCAL + for o, a in opts: + if o == '-l': local = 1 + if o == '-R': local = 0 + self.cvs.update(files) + self.cvs.putentries() + if not local and not files: + self.recurse() + flags_update = '-lR' + do_up = do_update + flags_up = flags_update + + def do_commit(self, opts, files): + """commit [-m message] [file] ...""" + message = "" + for o, a in opts: + if o == '-m': message = a + self.cvs.commit(files, message) + self.cvs.putentries() + flags_commit = 'm:' + do_com = do_commit + flags_com = flags_commit + + def do_diff(self, opts, files): + """diff [difflags] [file] ...""" + self.cvs.diff(files, opts) + flags_diff = 'cbitwcefhnlr:sD:S:' + do_dif = do_diff + flags_dif = flags_diff + + def do_add(self, opts, files): + """add file ...""" + if not files: + print "'rcvs add' requires at least one file" + return + self.cvs.add(files) + self.cvs.putentries() + + def do_remove(self, opts, files): + """remove file ...""" + if not files: + print "'rcvs remove' requires at least one file" + return + self.cvs.remove(files) + self.cvs.putentries() + do_rm = do_remove + + def do_log(self, opts, files): + """log [rlog-options] [file] ...""" + self.cvs.log(files, opts) + flags_log = 'bhLNRtd:s:V:r:' def remove(fn): - try: - os.unlink(fn) - except os.error: - pass + try: + os.unlink(fn) + except os.error: + pass def main(): - r = rcvs() - try: - r.run() - finally: - r.close() + r = rcvs() + try: + r.run() + finally: + r.close() if __name__ == "__main__": - main() + main() diff --git a/Demo/pdist/rrcs.py b/Demo/pdist/rrcs.py index a07260c647..4d23e6c1ee 100755 --- a/Demo/pdist/rrcs.py +++ b/Demo/pdist/rrcs.py @@ -11,150 +11,150 @@ import tempfile from rcsclient import openrcsclient def main(): - sys.stdout = sys.stderr - try: - opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL') - if not rest: - cmd = 'head' - else: - cmd, rest = rest[0], rest[1:] - if not commands.has_key(cmd): - raise getopt.error, "unknown command" - coptset, func = commands[cmd] - copts, files = getopt.getopt(rest, coptset) - except getopt.error, msg: - print msg - print "usage: rrcs [options] command [options] [file] ..." - print "where command can be:" - print " ci|put # checkin the given files" - print " co|get # checkout" - print " info # print header info" - print " head # print revision of head branch" - print " list # list filename if valid" - print " log # print full log" - print " diff # diff rcs file and work file" - print "if no files are given, all remote rcs files are assumed" - sys.exit(2) - x = openrcsclient(opts) - if not files: - files = x.listfiles() - for fn in files: - try: - func(x, copts, fn) - except (IOError, os.error), msg: - print "%s: %s" % (fn, msg) + sys.stdout = sys.stderr + try: + opts, rest = getopt.getopt(sys.argv[1:], 'h:p:d:qvL') + if not rest: + cmd = 'head' + else: + cmd, rest = rest[0], rest[1:] + if not commands.has_key(cmd): + raise getopt.error, "unknown command" + coptset, func = commands[cmd] + copts, files = getopt.getopt(rest, coptset) + except getopt.error, msg: + print msg + print "usage: rrcs [options] command [options] [file] ..." + print "where command can be:" + print " ci|put # checkin the given files" + print " co|get # checkout" + print " info # print header info" + print " head # print revision of head branch" + print " list # list filename if valid" + print " log # print full log" + print " diff # diff rcs file and work file" + print "if no files are given, all remote rcs files are assumed" + sys.exit(2) + x = openrcsclient(opts) + if not files: + files = x.listfiles() + for fn in files: + try: + func(x, copts, fn) + except (IOError, os.error), msg: + print "%s: %s" % (fn, msg) def checkin(x, copts, fn): - f = open(fn) - data = f.read() - f.close() - new = not x.isvalid(fn) - if not new and same(x, copts, fn, data): - print "%s: unchanged since last checkin" % fn - return - print "Checking in", fn, "..." - message = asklogmessage(new) - messages = x.put(fn, data, message) - if messages: - print messages + f = open(fn) + data = f.read() + f.close() + new = not x.isvalid(fn) + if not new and same(x, copts, fn, data): + print "%s: unchanged since last checkin" % fn + return + print "Checking in", fn, "..." + message = asklogmessage(new) + messages = x.put(fn, data, message) + if messages: + print messages def checkout(x, copts, fn): - data = x.get(fn) - f = open(fn, 'w') - f.write(data) - f.close() + data = x.get(fn) + f = open(fn, 'w') + f.write(data) + f.close() def lock(x, copts, fn): - x.lock(fn) + x.lock(fn) def unlock(x, copts, fn): - x.unlock(fn) + x.unlock(fn) def info(x, copts, fn): - dict = x.info(fn) - keys = dict.keys() - keys.sort() - for key in keys: - print key + ':', dict[key] - print '='*70 + dict = x.info(fn) + keys = dict.keys() + keys.sort() + for key in keys: + print key + ':', dict[key] + print '='*70 def head(x, copts, fn): - head = x.head(fn) - print fn, head + head = x.head(fn) + print fn, head def list(x, copts, fn): - if x.isvalid(fn): - print fn + if x.isvalid(fn): + print fn def log(x, copts, fn): - flags = '' - for o, a in copts: - flags = flags + ' ' + o + a - flags = flags[1:] - messages = x.log(fn, flags) - print messages + flags = '' + for o, a in copts: + flags = flags + ' ' + o + a + flags = flags[1:] + messages = x.log(fn, flags) + print messages def diff(x, copts, fn): - if same(x, copts, fn): - return - flags = '' - for o, a in copts: - flags = flags + ' ' + o + a - flags = flags[1:] - data = x.get(fn) - tf = tempfile.NamedTemporaryFile() - tf.write(data) - tf.flush() - print 'diff %s -r%s %s' % (flags, x.head(fn), fn) - sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) - if sts: - print '='*70 + if same(x, copts, fn): + return + flags = '' + for o, a in copts: + flags = flags + ' ' + o + a + flags = flags[1:] + data = x.get(fn) + tf = tempfile.NamedTemporaryFile() + tf.write(data) + tf.flush() + print 'diff %s -r%s %s' % (flags, x.head(fn), fn) + sts = os.system('diff %s %s %s' % (flags, tf.name, fn)) + if sts: + print '='*70 def same(x, copts, fn, data = None): - if data is None: - f = open(fn) - data = f.read() - f.close() - lsum = md5.new(data).digest() - rsum = x.sum(fn) - return lsum == rsum + if data is None: + f = open(fn) + data = f.read() + f.close() + lsum = md5.new(data).digest() + rsum = x.sum(fn) + return lsum == rsum def asklogmessage(new): - if new: - print "enter description,", - else: - print "enter log message,", - print "terminate with single '.' or end of file:" - if new: - print "NOTE: This is NOT the log message!" - message = "" - while 1: - sys.stderr.write(">> ") - sys.stderr.flush() - line = sys.stdin.readline() - if not line or line == '.\n': break - message = message + line - return message + if new: + print "enter description,", + else: + print "enter log message,", + print "terminate with single '.' or end of file:" + if new: + print "NOTE: This is NOT the log message!" + message = "" + while 1: + sys.stderr.write(">> ") + sys.stderr.flush() + line = sys.stdin.readline() + if not line or line == '.\n': break + message = message + line + return message def remove(fn): - try: - os.unlink(fn) - except os.error: - pass + try: + os.unlink(fn) + except os.error: + pass commands = { - 'ci': ('', checkin), - 'put': ('', checkin), - 'co': ('', checkout), - 'get': ('', checkout), - 'info': ('', info), - 'head': ('', head), - 'list': ('', list), - 'lock': ('', lock), - 'unlock': ('', unlock), - 'log': ('bhLRtd:l:r:s:w:V:', log), - 'diff': ('c', diff), - } + 'ci': ('', checkin), + 'put': ('', checkin), + 'co': ('', checkout), + 'get': ('', checkout), + 'info': ('', info), + 'head': ('', head), + 'list': ('', list), + 'lock': ('', lock), + 'unlock': ('', unlock), + 'log': ('bhLRtd:l:r:s:w:V:', log), + 'diff': ('c', diff), + } if __name__ == '__main__': - main() + main() diff --git a/Demo/pdist/security.py b/Demo/pdist/security.py index 0ffd511a07..b63081ee39 100755 --- a/Demo/pdist/security.py +++ b/Demo/pdist/security.py @@ -1,33 +1,33 @@ class Security: - def __init__(self): - import os - env = os.environ - if env.has_key('PYTHON_KEYFILE'): - keyfile = env['PYTHON_KEYFILE'] - else: - keyfile = '.python_keyfile' - if env.has_key('HOME'): - keyfile = os.path.join(env['HOME'], keyfile) - if not os.path.exists(keyfile): - import sys - for dir in sys.path: - kf = os.path.join(dir, keyfile) - if os.path.exists(kf): - keyfile = kf - break - try: - self._key = eval(open(keyfile).readline()) - except IOError: - raise IOError, "python keyfile %s: cannot open" % keyfile + def __init__(self): + import os + env = os.environ + if env.has_key('PYTHON_KEYFILE'): + keyfile = env['PYTHON_KEYFILE'] + else: + keyfile = '.python_keyfile' + if env.has_key('HOME'): + keyfile = os.path.join(env['HOME'], keyfile) + if not os.path.exists(keyfile): + import sys + for dir in sys.path: + kf = os.path.join(dir, keyfile) + if os.path.exists(kf): + keyfile = kf + break + try: + self._key = eval(open(keyfile).readline()) + except IOError: + raise IOError, "python keyfile %s: cannot open" % keyfile - def _generate_challenge(self): - import random - return random.randint(100, 100000) + def _generate_challenge(self): + import random + return random.randint(100, 100000) - def _compare_challenge_response(self, challenge, response): - return self._encode_challenge(challenge) == response + def _compare_challenge_response(self, challenge, response): + return self._encode_challenge(challenge) == response - def _encode_challenge(self, challenge): - p, m = self._key - return pow(long(challenge), p, m) + def _encode_challenge(self, challenge): + p, m = self._key + return pow(long(challenge), p, m) diff --git a/Demo/pdist/server.py b/Demo/pdist/server.py index 4e4ab0d252..e692eea7ff 100755 --- a/Demo/pdist/server.py +++ b/Demo/pdist/server.py @@ -12,103 +12,103 @@ VERBOSE = 1 class Server: - - """RPC Server class. Derive a class to implement a particular service.""" - - def __init__(self, address, verbose = VERBOSE): - if type(address) == type(0): - address = ('', address) - self._address = address - self._verbose = verbose - self._socket = None - self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self._socket.bind(address) - self._socket.listen(1) - self._listening = 1 - - def _setverbose(self, verbose): - self._verbose = verbose - - def __del__(self): - self._close() - - def _close(self): - self._listening = 0 - if self._socket: - self._socket.close() - self._socket = None - - def _serverloop(self): - while self._listening: - self._serve() - - def _serve(self): - if self._verbose: print "Wait for connection ..." - conn, address = self._socket.accept() - if self._verbose: print "Accepted connection from %s" % repr(address) - if not self._verify(conn, address): - print "*** Connection from %s refused" % repr(address) - conn.close() - return - rf = conn.makefile('r') - wf = conn.makefile('w') - ok = 1 - while ok: - wf.flush() - if self._verbose > 1: print "Wait for next request ..." - ok = self._dorequest(rf, wf) - - _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*'] - - def _verify(self, conn, address): - host, port = address - for pat in self._valid: - if fnmatch(host, pat): return 1 - return 0 - - def _dorequest(self, rf, wf): - rp = pickle.Unpickler(rf) - try: - request = rp.load() - except EOFError: - return 0 - if self._verbose > 1: print "Got request: %s" % repr(request) - try: - methodname, args, id = request - if '.' in methodname: - reply = (None, self._special(methodname, args), id) - elif methodname[0] == '_': - raise NameError, "illegal method name %s" % repr(methodname) - else: - method = getattr(self, methodname) - reply = (None, apply(method, args), id) - except: - reply = (sys.exc_type, sys.exc_value, id) - if id < 0 and reply[:2] == (None, None): - if self._verbose > 1: print "Suppress reply" - return 1 - if self._verbose > 1: print "Send reply: %s" % repr(reply) - wp = pickle.Pickler(wf) - wp.dump(reply) - return 1 - - def _special(self, methodname, args): - if methodname == '.methods': - if not hasattr(self, '_methods'): - self._methods = tuple(self._listmethods()) - return self._methods - raise NameError, "unrecognized special method name %s" % repr(methodname) - - def _listmethods(self, cl=None): - if not cl: cl = self.__class__ - names = cl.__dict__.keys() - names = filter(lambda x: x[0] != '_', names) - names.sort() - for base in cl.__bases__: - basenames = self._listmethods(base) - basenames = filter(lambda x, names=names: x not in names, basenames) - names[len(names):] = basenames - return names + + """RPC Server class. Derive a class to implement a particular service.""" + + def __init__(self, address, verbose = VERBOSE): + if type(address) == type(0): + address = ('', address) + self._address = address + self._verbose = verbose + self._socket = None + self._socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self._socket.bind(address) + self._socket.listen(1) + self._listening = 1 + + def _setverbose(self, verbose): + self._verbose = verbose + + def __del__(self): + self._close() + + def _close(self): + self._listening = 0 + if self._socket: + self._socket.close() + self._socket = None + + def _serverloop(self): + while self._listening: + self._serve() + + def _serve(self): + if self._verbose: print "Wait for connection ..." + conn, address = self._socket.accept() + if self._verbose: print "Accepted connection from %s" % repr(address) + if not self._verify(conn, address): + print "*** Connection from %s refused" % repr(address) + conn.close() + return + rf = conn.makefile('r') + wf = conn.makefile('w') + ok = 1 + while ok: + wf.flush() + if self._verbose > 1: print "Wait for next request ..." + ok = self._dorequest(rf, wf) + + _valid = ['192.16.201.*', '192.16.197.*', '132.151.1.*', '129.6.64.*'] + + def _verify(self, conn, address): + host, port = address + for pat in self._valid: + if fnmatch(host, pat): return 1 + return 0 + + def _dorequest(self, rf, wf): + rp = pickle.Unpickler(rf) + try: + request = rp.load() + except EOFError: + return 0 + if self._verbose > 1: print "Got request: %s" % repr(request) + try: + methodname, args, id = request + if '.' in methodname: + reply = (None, self._special(methodname, args), id) + elif methodname[0] == '_': + raise NameError, "illegal method name %s" % repr(methodname) + else: + method = getattr(self, methodname) + reply = (None, apply(method, args), id) + except: + reply = (sys.exc_type, sys.exc_value, id) + if id < 0 and reply[:2] == (None, None): + if self._verbose > 1: print "Suppress reply" + return 1 + if self._verbose > 1: print "Send reply: %s" % repr(reply) + wp = pickle.Pickler(wf) + wp.dump(reply) + return 1 + + def _special(self, methodname, args): + if methodname == '.methods': + if not hasattr(self, '_methods'): + self._methods = tuple(self._listmethods()) + return self._methods + raise NameError, "unrecognized special method name %s" % repr(methodname) + + def _listmethods(self, cl=None): + if not cl: cl = self.__class__ + names = cl.__dict__.keys() + names = filter(lambda x: x[0] != '_', names) + names.sort() + for base in cl.__bases__: + basenames = self._listmethods(base) + basenames = filter(lambda x, names=names: x not in names, basenames) + names[len(names):] = basenames + return names from security import Security @@ -116,30 +116,30 @@ from security import Security class SecureServer(Server, Security): - def __init__(self, *args): - apply(Server.__init__, (self,) + args) - Security.__init__(self) - - def _verify(self, conn, address): - import string - challenge = self._generate_challenge() - conn.send("%d\n" % challenge) - response = "" - while "\n" not in response and len(response) < 100: - data = conn.recv(100) - if not data: - break - response = response + data - try: - response = string.atol(string.strip(response)) - except string.atol_error: - if self._verbose > 0: - print "Invalid response syntax", repr(response) - return 0 - if not self._compare_challenge_response(challenge, response): - if self._verbose > 0: - print "Invalid response value", repr(response) - return 0 - if self._verbose > 1: - print "Response matches challenge. Go ahead!" - return 1 + def __init__(self, *args): + apply(Server.__init__, (self,) + args) + Security.__init__(self) + + def _verify(self, conn, address): + import string + challenge = self._generate_challenge() + conn.send("%d\n" % challenge) + response = "" + while "\n" not in response and len(response) < 100: + data = conn.recv(100) + if not data: + break + response = response + data + try: + response = string.atol(string.strip(response)) + except string.atol_error: + if self._verbose > 0: + print "Invalid response syntax", repr(response) + return 0 + if not self._compare_challenge_response(challenge, response): + if self._verbose > 0: + print "Invalid response value", repr(response) + return 0 + if self._verbose > 1: + print "Response matches challenge. Go ahead!" + return 1 diff --git a/Demo/pdist/sumtree.py b/Demo/pdist/sumtree.py index 92c1fd0552..9291a56b99 100755 --- a/Demo/pdist/sumtree.py +++ b/Demo/pdist/sumtree.py @@ -2,23 +2,23 @@ import time import FSProxy def main(): - t1 = time.time() - #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127)) - proxy = FSProxy.FSProxyLocal() - sumtree(proxy) - proxy._close() - t2 = time.time() - print t2-t1, "seconds" - raw_input("[Return to exit] ") + t1 = time.time() + #proxy = FSProxy.FSProxyClient(('voorn.cwi.nl', 4127)) + proxy = FSProxy.FSProxyLocal() + sumtree(proxy) + proxy._close() + t2 = time.time() + print t2-t1, "seconds" + raw_input("[Return to exit] ") def sumtree(proxy): - print "PWD =", proxy.pwd() - files = proxy.listfiles() - proxy.infolist(files) - subdirs = proxy.listsubdirs() - for name in subdirs: - proxy.cd(name) - sumtree(proxy) - proxy.back() + print "PWD =", proxy.pwd() + files = proxy.listfiles() + proxy.infolist(files) + subdirs = proxy.listsubdirs() + for name in subdirs: + proxy.cd(name) + sumtree(proxy) + proxy.back() main() -- cgit v1.2.1