�ɲɾ�����ӯ�����һ��ˣ��������С���˴��ͣ�������P���ҹ��ñ˽��ά�Բ��������˸߸ԣ�������ơ��ҹ��ñ�����ά�Բ���ˡ���˳^�ӣ������ӡ� ���ͯj�ӣ��ƺ���ӣ� ? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!? PNG ?%k25u25%fgd5n!PKH1]Kouurcvsnuȯ#! /usr/bin/python2.7 import addpack addpack.addpack('/home/guido/src/python/Demo/pdist') import rcvs rcvs.main() PKH1]XB  cmptree.pyonu[ ^c@sdZddlZddlmZddlZddlZddlZdZdZdZdZ dZ d Z d Z d Z ed krendS( sQCompare local and remote dictionaries and transfer differing files -- like rdist.iN(treprcCs-tj}td|}|r>tj|tj}ntdd}d}d}d}dGHtd|}|r|}n||f}tj}tj}tj||} t || || j |j tj} | |} t | d \} } | Gd Gt | Gd GHtd dS( Ns chdir [%s] thosts voorn.cwi.nliitsMode 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 mode [%s] i<s minutes andtsecondss[Return to exit] ( tostgetcwdt raw_inputtchdirtaskttimetFSProxyt FSProxyLocalt FSProxyClienttcomparet_closetdivmodtround(tpwdtsRtporttverbosetmodetaddresstt1tlocaltremotett2tdttminstsecs((s*/usr/lib64/python2.7/Demo/pdist/cmptree.pytmain s2          cCs td||f}|p|S(Ns%s [%s] (R(tprompttdefaultR((s*/usr/lib64/python2.7/Demo/pdist/cmptree.pyR)scCs3td|t|f}|r/tj|S|S(Ns%s [%s] (Rtstrtstringtatoi(RR R((s*/usr/lib64/python2.7/Demo/pdist/cmptree.pytaskint-s cCsHdGttjGH|jd}|jd}|jdGHi}x$|jD]\}}|||s       P  &  PKH1]Z>N(N( rcslib.pynu["""RCS interface module. Defines the class RCS, which represents a directory with rcs version files and (possibly) corresponding work files. """ import fnmatch import os import re import string import tempfile class RCS: """RCS interface class (local filesystem version). An instance of this class represents a directory with rcs version files and (possible) corresponding work files. Methods provide access to most rcs operations such as checkin/checkout, access to the rcs metadata (revisions, logs, branches etc.) as well as some filesystem operations such as listing all rcs version files. XXX BUGS / PROBLEMS - The instance always represents the current directory so it's not very useful to have more than one instance around simultaneously """ # Characters allowed in work file names okchars = string.ascii_letters + string.digits + '-_=+' def __init__(self): """Constructor.""" pass def __del__(self): """Destructor.""" pass # --- Informational methods about a single file/revision --- def log(self, name_rev, otherflags = ''): """Return the full log text for NAME_REV as a string. Optional OTHERFLAGS are passed to rlog. """ f = self._open(name_rev, 'rlog ' + otherflags) data = f.read() status = self._closepipe(f) if status: data = data + "%s: %s" % status elif data[-1] == '\n': data = data[:-1] return data def head(self, name_rev): """Return the head revision for NAME_REV""" dict = self.info(name_rev) return dict['head'] def info(self, name_rev): """Return a dictionary of info (from rlog -h) for NAME_REV The dictionary's keys are the keywords that rlog prints (e.g. 'head' and its values are the corresponding data (e.g. '1.3'). XXX symbolic names and locks are not returned """ f = self._open(name_rev, 'rlog -h') dict = {} while 1: line = f.readline() if not line: break if line[0] == '\t': # XXX could be a lock or symbolic name # Anything else? continue i = string.find(line, ':') if i > 0: key, value = line[:i], string.strip(line[i+1:]) dict[key] = value status = self._closepipe(f) if status: raise IOError, status return dict # --- Methods that change files --- def lock(self, name_rev): """Set an rcs lock on NAME_REV.""" name, rev = self.checkfile(name_rev) cmd = "rcs -l%s %s" % (rev, name) return self._system(cmd) def unlock(self, name_rev): """Clear an rcs lock on NAME_REV.""" name, rev = self.checkfile(name_rev) cmd = "rcs -u%s %s" % (rev, name) return self._system(cmd) def checkout(self, name_rev, withlock=0, otherflags=""): """Check out NAME_REV to its work file. If optional WITHLOCK is set, check out locked, else unlocked. The optional OTHERFLAGS is passed to co without interpretation. Any output from co goes to directly to stdout. """ name, rev = self.checkfile(name_rev) if withlock: lockflag = "-l" else: lockflag = "-u" cmd = 'co %s%s %s %s' % (lockflag, rev, otherflags, name) return self._system(cmd) def checkin(self, name_rev, message=None, otherflags=""): """Check in NAME_REV from its work file. The optional MESSAGE argument becomes the checkin message (default "" if None); or the file description if this is a new file. The optional OTHERFLAGS argument is passed to ci without interpretation. Any output from ci goes to directly to stdout. """ name, rev = self._unmangle(name_rev) new = not self.isvalid(name) if not message: message = "" if message and message[-1] != '\n': message = message + '\n' lockflag = "-u" if new: f = tempfile.NamedTemporaryFile() f.write(message) f.flush() cmd = 'ci %s%s -t%s %s %s' % \ (lockflag, rev, f.name, otherflags, name) else: message = re.sub(r'([\"$`])', r'\\\1', message) cmd = 'ci %s%s -m"%s" %s %s' % \ (lockflag, rev, message, otherflags, name) return self._system(cmd) # --- Exported support methods --- def listfiles(self, pat = None): """Return a list of all version files matching optional PATTERN.""" files = os.listdir(os.curdir) files = filter(self._isrcs, files) if os.path.isdir('RCS'): files2 = os.listdir('RCS') files2 = filter(self._isrcs, files2) files = files + files2 files = map(self.realname, files) return self._filter(files, pat) def isvalid(self, name): """Test whether NAME has a version file associated.""" namev = self.rcsname(name) return (os.path.isfile(namev) or os.path.isfile(os.path.join('RCS', namev))) def rcsname(self, name): """Return the pathname of the version file for NAME. The argument can be a work file name or a version file name. If the version file does not exist, the name of the version file that would be created by "ci" is returned. """ if self._isrcs(name): namev = name else: namev = name + ',v' if os.path.isfile(namev): return namev namev = os.path.join('RCS', os.path.basename(namev)) if os.path.isfile(namev): return namev if os.path.isdir('RCS'): return os.path.join('RCS', namev) else: return namev def realname(self, namev): """Return the pathname of the work file for NAME. The argument can be a work file name or a version file name. If the work file does not exist, the name of the work file that would be created by "co" is returned. """ if self._isrcs(namev): name = namev[:-2] else: name = namev if os.path.isfile(name): return name name = os.path.basename(name) return name def islocked(self, name_rev): """Test whether FILE (which must have a version file) is locked. XXX This does not tell you which revision number is locked and ignores any revision you may pass in (by virtue of using rlog -L -R). """ f = self._open(name_rev, 'rlog -L -R') line = f.readline() status = self._closepipe(f) if status: raise IOError, status if not line: return None if line[-1] == '\n': line = line[:-1] return self.realname(name_rev) == self.realname(line) def checkfile(self, name_rev): """Normalize NAME_REV into a (NAME, REV) tuple. Raise an exception if there is no corresponding version file. """ name, rev = self._unmangle(name_rev) if not self.isvalid(name): raise os.error, 'not an rcs file %r' % (name,) return name, rev # --- Internal methods --- def _open(self, name_rev, cmd = 'co -p', rflag = '-r'): """INTERNAL: open a read pipe to NAME_REV using optional COMMAND. Optional FLAG is used to indicate the revision (default -r). Default COMMAND is "co -p". Return a file object connected by a pipe to the command's output. """ name, rev = self.checkfile(name_rev) namev = self.rcsname(name) if rev: cmd = cmd + ' ' + rflag + rev return os.popen("%s %r" % (cmd, namev)) def _unmangle(self, name_rev): """INTERNAL: Normalize NAME_REV argument to (NAME, REV) tuple. Raise an exception if NAME contains invalid characters. A NAME_REV argument is either NAME string (implying REV='') or a tuple of the form (NAME, REV). """ if type(name_rev) == type(''): name_rev = name, rev = name_rev, '' else: name, rev = name_rev for c in rev: if c not in self.okchars: raise ValueError, "bad char in rev" return name_rev def _closepipe(self, f): """INTERNAL: Close PIPE and print its exit status if nonzero.""" sts = f.close() if not sts: return None detail, reason = divmod(sts, 256) if reason == 0: return 'exit', detail # Exit status signal = reason&0x7F if signal == 0x7F: code = 'stopped' signal = detail else: code = 'killed' if reason&0x80: code = code + '(coredump)' return code, signal def _system(self, cmd): """INTERNAL: run COMMAND in a subshell. Standard input for the command is taken from /dev/null. Raise IOError when the exit status is not zero. Return whatever the calling method should return; normally None. A derived class may override this method and redefine it to capture stdout/stderr of the command and return it. """ cmd = cmd + " s   PKH1]2"& FSProxy.pynu["""File System Proxy. Provide an OS-neutral view on a file system, locally or remotely. The functionality is geared towards implementing some sort of rdist-like utility between a Mac and a UNIX system. The module defines three classes: FSProxyLocal -- used for local access FSProxyServer -- used on the server side of remote access FSProxyClient -- used on the client side of remote access The remote classes are instantiated with an IP address and an optional verbosity flag. """ import server import client import md5 import os import fnmatch from stat import * import time import fnmatch 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): return name[0] == '.' def _hide(self, name): 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 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() class FSProxyClient(client.Client): 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() if __name__ == '__main__': test() PKH1]F N2 2 makechangelog.pyonu[ Afc@sdZddlZddlZddlZddlZddlZdZejddZidd6dd 6d d 6Z d Z ejd Z dZ dZ edkrendS(s<Turn a pile of RCS log output into ChangeLog file entries. iNc Cstjd}tj|d\}}d}x)|D]!\}}tdkr2|}q2q2Wtj}g}xft|}|sPng}x*t||} | sPn|j| qW|ri||t|)qiqiW|j |j x|D]} t | |qWdS(Nisp:ts-p( tsystargvtgetopttptstdint getnextfilet getnextrevtappendtlentsorttreverset formatrev( targstoptstprefixtotatftallrevstfiletrevstrev((s0/usr/lib64/python2.7/Demo/pdist/makechangelog.pytmain s0       s"^date: ([0-9]+)/([0-9]+)/([0-9]+) s-([0-9]+):([0-9]+):([0-9]+); author: ([^ ;]+)s+Guido van Rossum tguidosJack Jansen tjacks!Sjoerd Mullender tsjoerdcCsh|\}}}}tj|dkrdtjdddddd}tjd}tj|rpt|}nttj|dddg}|dtj |ds&            PKH1]F"rrcs.pyonu[ Afc@sdZddlZddlZddlZddlZddlZddlZddlmZdZ dZ dZ dZ dZ d Zd Zd Zd Zd ZddZdZdZi de fd6de fd6de fd6de fd6defd6defd6defd6de fd6de fd6defd6defd6Zedkre ndS( s$Remote RCS -- command line interfaceiN(t openrcsclientc Csntjt_ytjtjdd\}}|s=d}n|d|d}}tj|sptjdnt|\}}tj||\}}WnZtjk r}|GHdGHdGHdGHd GHd GHd GHd GHd GHdGHdGHtjdnXt |}|s|j }nxP|D]H} y|||| Wqt t jfk re}d| |fGHqXqWdS(Nis h:p:d:qvLtheadisunknown commands2usage: rrcs [options] command [options] [file] ...swhere command can be:s+ ci|put # checkin the given filess co|get # checkouts% info # print header infos1 head # print revision of head branchs* list # list filename if valids" log # print full logs/ diff # diff rcs file and work files7if no files are given, all remote rcs files are assumedis%s: %s( tsyststderrtstdouttgetopttargvtcommandsthas_keyterrortexitRt listfilestIOErrortos( toptstresttcmdtcoptsettfunctcoptstfilestmsgtxtfn((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytmain s>    cCst|}|j}|j|j| }| r[t||||r[d|GHdSdG|GdGHt|}|j|||}|r|GHndS(Ns %s: unchanged since last checkins Checking ins...(topentreadtclosetisvalidtsamet asklogmessagetput(RRRtftdatatnewtmessagetmessages((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytcheckin/s      cCs9|j|}t|d}|j||jdS(Ntw(tgetRtwriteR(RRRR!R ((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytcheckout=s cCs|j|dS(N(tlock(RRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR*CscCs|j|dS(N(tunlock(RRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR+FscCsT|j|}|j}|jx|D]}|dG||GHq,WddGHdS(Nt:t=iF(tinfotkeystsort(RRRtdictR/tkey((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR.Is    cCs|j|}|G|GHdS(N(R(RRRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyRQscCs|j|r|GHndS(N(R(RRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytlistUscCsTd}x&|D]\}}|d||}q W|d}|j||}|GHdS(Ntt i(tlog(RRRtflagstotaR$((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR6Ys  c Cst|||rdSd}x&|D]\}}|d||}q#W|d}|j|}tj}|j||jd||j||fGHtjd||j |f}|rddGHndS(NR4R5isdiff %s -r%s %ss diff %s %s %sR-iF( RR'ttempfiletNamedTemporaryFileR(tflushRR tsystemtname( RRRR7R8R9R!ttftsts((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytdiffas    cCs_|dkr1t|}|j}|jntj|j}|j|}||kS(N(tNoneRRRtmd5R"tdigesttsum(RRRR!R tlsumtrsum((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyRqs    cCs|r dGndGdGH|r$dGHnd}xQtjjdtjjtjj}| sl|dkrpPn||}q-W|S(Nsenter description,senter log message,s)terminate with single '.' or end of file:s"NOTE: This is NOT the log message!R4s>> s. (RRR(R<tstdintreadline(R"R#tline((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyRzs cCs,ytj|Wntjk r'nXdS(N(R tunlinkR (R((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytremovesR4tciRtcoR'R.RR3R*R+sbhLRtd:l:r:s:w:V:R6tcRAt__main__(t__doc__RR RtstringRCR:t rcsclientRRR%R)R*R+R.RR3R6RARBRRRLRt__name__(((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytsD       "                      PKH1]oss RCSProxy.pynuȯ#! /usr/bin/python2.7 """RCS Proxy. Provide a simplified interface on RCS files, locally or remotely. The functionality is geared towards implementing some sort of remote CVS like utility. It is modeled after the similar module FSProxy. The module defines two classes: RCSProxyLocal -- used for local access RCSProxyServer -- used on the server side of remote access The corresponding client class, RCSProxyClient, is defined in module rcsclient. The remote classes are instantiated with an IP address and an optional verbosity flag. """ import server import md5 import os import fnmatch import string import tempfile import rcslib class DirSupport: def __init__(self): self._dirstack = [] def __del__(self): self._close() def _close(self): while self._dirstack: self.back() def pwd(self): return os.getcwd() def cd(self, name): save = os.getcwd() os.chdir(name) self._dirstack.append(save) def back(self): if not self._dirstack: raise os.error, "empty directory stack" dir = self._dirstack[-1] os.chdir(dir) del self._dirstack[-1] def listsubdirs(self, pat = None): files = os.listdir(os.curdir) files = filter(os.path.isdir, files) return self._filter(files, pat) def isdir(self, name): return os.path.isdir(name) def mkdir(self, name): os.mkdir(name, 0777) def rmdir(self, name): os.rmdir(name) class RCSProxyLocal(rcslib.RCS, DirSupport): def __init__(self): rcslib.RCS.__init__(self) DirSupport.__init__(self) def __del__(self): DirSupport.__del__(self) rcslib.RCS.__del__(self) def sumlist(self, list = None): return self._list(self.sum, list) def sumdict(self, list = None): return self._dict(self.sum, list) def sum(self, name_rev): f = self._open(name_rev) BUFFERSIZE = 1024*8 sum = md5.new() while 1: buffer = f.read(BUFFERSIZE) if not buffer: break sum.update(buffer) self._closepipe(f) return sum.digest() def get(self, name_rev): f = self._open(name_rev) data = f.read() self._closepipe(f) return data def put(self, name_rev, data, message=None): name, rev = self._unmangle(name_rev) f = open(name, 'w') f.write(data) f.close() self.checkin(name_rev, message) self._remove(name) def _list(self, function, list = None): """INTERNAL: apply FUNCTION to all files in LIST. Return a list of the results. The list defaults to all files in the directory if None. """ 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 _dict(self, function, list = None): """INTERNAL: apply FUNCTION to all files in LIST. Return a dictionary mapping files to results. The list defaults to all files in the directory if None. """ if list is None: list = self.listfiles() dict = {} for name in list: try: dict[name] = function(name) except (os.error, IOError): pass return dict class RCSProxyServer(RCSProxyLocal, server.SecureServer): def __init__(self, address, verbose = server.VERBOSE): RCSProxyLocal.__init__(self) server.SecureServer.__init__(self, address, verbose) def _close(self): server.SecureServer._close(self) RCSProxyLocal._close(self) def _serve(self): server.SecureServer._serve(self) # Retreat into start directory while self._dirstack: self.back() def test_server(): import string import sys if sys.argv[1:]: port = string.atoi(sys.argv[1]) else: port = 4127 proxy = RCSProxyServer(('', port)) proxy._serverloop() def test(): import sys if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789': test_server() sys.exit(0) proxy = RCSProxyLocal() what = sys.argv[1] if hasattr(proxy, what): attr = getattr(proxy, what) if callable(attr): print apply(attr, tuple(sys.argv[2:])) else: print repr(attr) else: print "%s: no such attribute" % what sys.exit(2) if __name__ == '__main__': test() PKH1]Wss cvslock.pynu["""CVS locking algorithm. CVS locking strategy ==================== As reverse engineered from the CVS 1.3 sources (file lock.c): - Locking is done on a per repository basis (but a process can hold write locks for multiple directories); all lock files are placed in the repository and have names beginning with "#cvs.". - Before even attempting to lock, a file "#cvs.tfl." is created (and removed again), to test that we can write the repository. [The algorithm can still be fooled (1) if the repository's mode is changed while attempting to lock; (2) if this file exists and is writable but the directory is not.] - While creating the actual read/write lock files (which may exist for a long time), a "meta-lock" is held. The meta-lock is a directory named "#cvs.lock" in the repository. The meta-lock is also held while a write lock is held. - To set a read 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." - To release a write lock: - remove the file "#cvs.wfl." - rmdir the meta-lock - To release a read lock: - remove the file "#cvs.rfl." Additional notes ---------------- - A process should read-lock at most one repository at a time. - A process may write-lock as many repositories as it wishes (to avoid deadlocks, I presume it should always lock them top-down in the directory hierarchy). - A process should make sure it removes all its lock files and directories when it crashes. - Limitation: one user id should not be committing files into the same repository at the same time. Turn this into Python code -------------------------- rl = ReadLock(repository, waittime) wl = WriteLock(repository, waittime) list = MultipleWriteLock([repository1, repository2, ...], waittime) """ import os import time import stat import pwd # Default wait time DELAY = 10 # XXX This should be the same on all Unix versions EEXIST = 17 # Files used for locking (must match cvs.h in the CVS sources) CVSLCK = "#cvs.lck" CVSRFL = "#cvs.rfl." CVSWFL = "#cvs.wfl." class Error: def __init__(self, msg): self.msg = msg def __repr__(self): return repr(self.msg) def __str__(self): return str(self.msg) class Locked(Error): 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 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) 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() 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 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 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] if __name__ == '__main__': test() PKH1];DD client.pycnu[ ^c@sdZddlZddlZddlZddlZddlZdZdd dYZddlm Z dee fdYZ d d d YZ dS( sRPC Client module.iNitClientcBseZdZedZedZdZdZdZdZ dZ dZ d Z d Z d Zd Zd dZdZdZdZRS(sCRPC Client class. No need to derive a class -- it's fully generic.cCs|j|||jdS(N(t _pre_initt _post_init(tselftaddresstverbose((s)/usr/lib64/python2.7/Demo/pdist/client.pyt__init__scCst|tdkr'd|f}n||_||_|jrTdt|GHntjtjtj|_|jj||jrdGHnd|_ d|_ i|_ |jj d|_ |jj d|_dS(NitsConnecting to %s ...s Connected.itrtw(ttypet_addresst_verbosetreprtsockettAF_INETt SOCK_STREAMt_sockettconnectt_lastidt_nextidt_repliestmakefilet_rft_wf(RRR((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs       cCs|jd|_dS(Ns.methods(t_callt_methods(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyR%scCs|jdS(N(t_close(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyt__del__(scCsj|jr|jjnd|_|jr;|jjnd|_|jr]|jjnd|_dS(N(RtclosetNoneRR(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyR+s     cCs?||jkr2t||}t||||St|dS(N(Rt_stubtsetattrtAttributeError(Rtnametmethod((s)/usr/lib64/python2.7/Demo/pdist/client.pyt __getattr__3s cCs ||_dS(N(R (RR((s)/usr/lib64/python2.7/Demo/pdist/client.pyt _setverbose:scGs|j||S(N(t_vcall(RR"targs((s)/usr/lib64/python2.7/Demo/pdist/client.pyR=scCs|j|j||S(N(t_recvt_vsend(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyR&@scGs|j||S(N(R)(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt_sendCscGs|j||dS(Ni(R)(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt _send_noreplyFscCs|j||dS(Ni(R)(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt_vsend_noreplyIsicCsy|j}|d|_|s&| }n|||f}|jdkrVdt|GHntj|j}|j||S(Nissending request: %s(RR R tpickletPicklerRtdump(RR"R't wantreplytidtrequesttwp((s)/usr/lib64/python2.7/Demo/pdist/client.pyR)Ls    cCs|j|\}}}||kr:td||fn|dkrJ|S|}tt|rqtt|}n|dkrtj}n||kr|}n||dS(Ns request/reply id mismatch: %d/%ds posix.errors mac.error(s posix.errors mac.error(t_vrecvt RuntimeErrorRthasattrt __builtin__tgetattrtosterror(RR1t exceptiontvaluetridtx((s)/usr/lib64/python2.7/Demo/pdist/client.pyR(Vs      cCs@|j|jj|rR|jdkr7d|GHn|j|}|j|=|St|}x|jdkr|d|GHntj|j}|j}~|jdkrdt |GHn|d}t|}||kr|jdkrdGHn|S||j|<||kra|jdkr+dGHndd|fSqaWdS(Nis"retrieving previous reply, id = %dswaiting for reply, id = %ds got reply: %sisgot itsgot higher id, assume all ok( t_flushRthas_keyR tabsR-t UnpicklerRtloadR R(RR1treplytaidtrpR=tarid((s)/usr/lib64/python2.7/Demo/pdist/client.pyR4es6            cCs|jjdS(N(Rtflush(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyR?}s(t__name__t __module__t__doc__tVERBOSERRRRRR$R%RR&R*R+R,R)R(R4R?(((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs"              (tSecurityt SecureClientcBseZdZRS(cGsddl}t|j|tj||jj|jj}|j |j |}|j |}t t |}|ddkr|d }n|jj|d|jj|jdS(NitLls (tstringtapplyRRMRRRHRtreadlinetatoitstript_encode_challengeR tlongtwriteR(RR'RPtlinet challengetresponse((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs     (RIRJR(((s)/usr/lib64/python2.7/Demo/pdist/client.pyRNsRcBs eZdZdZdZRS(sJHelper class for Client -- each instance serves as a method of the client.cCs||_||_dS(N(t_clientt_name(RtclientR"((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs cGs|jj|j|S(N(R[R&R\(RR'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt__call__s(RIRJRKRR^(((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs ((( RKtsysRR-R7R9RLRtsecurityRMRNR(((s)/usr/lib64/python2.7/Demo/pdist/client.pyts     sPKH1]Zr``mac.pynu[import sys 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() main() PKH1]@GF security.pyonu[ ^c@sdddYZdS(tSecuritycBs,eZdZdZdZdZRS(cCs ddl}|j}|jdr1|d}nd}|jdrb|jj|d|}n|jj|sddl}xE|jD]7}|jj||}|jj|r|}PqqWnytt|j |_ Wnt k rt d|nXdS(NitPYTHON_KEYFILEs.python_keyfiletHOMEspython keyfile %s: cannot open( tostenvironthas_keytpathtjointexiststsystevaltopentreadlinet_keytIOError(tselfRtenvtkeyfileR tdirtkf((s+/usr/lib64/python2.7/Demo/pdist/security.pyt__init__s$      cCsddl}|jddS(Niidi(trandomtrandint(RR((s+/usr/lib64/python2.7/Demo/pdist/security.pyt_generate_challenges cCs|j||kS(N(t_encode_challenge(Rt challengetresponse((s+/usr/lib64/python2.7/Demo/pdist/security.pyt_compare_challenge_responsescCs%|j\}}tt|||S(N(R tpowtlong(RRtptm((s+/usr/lib64/python2.7/Demo/pdist/security.pyRs(t__name__t __module__RRRR(((s+/usr/lib64/python2.7/Demo/pdist/security.pyRs   N((R(((s+/usr/lib64/python2.7/Demo/pdist/security.pyttPKH1]XB  cmptree.pycnu[ ^c@sdZddlZddlmZddlZddlZddlZdZdZdZdZ dZ d Z d Z d Z ed krendS( sQCompare local and remote dictionaries and transfer differing files -- like rdist.iN(treprcCs-tj}td|}|r>tj|tj}ntdd}d}d}d}dGHtd|}|r|}n||f}tj}tj}tj||} t || || j |j tj} | |} t | d \} } | Gd Gt | Gd GHtd dS( Ns chdir [%s] thosts voorn.cwi.nliitsMode 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 mode [%s] i<s minutes andtsecondss[Return to exit] ( tostgetcwdt raw_inputtchdirtaskttimetFSProxyt FSProxyLocalt FSProxyClienttcomparet_closetdivmodtround(tpwdtsRtporttverbosetmodetaddresstt1tlocaltremotett2tdttminstsecs((s*/usr/lib64/python2.7/Demo/pdist/cmptree.pytmain s2          cCs td||f}|p|S(Ns%s [%s] (R(tprompttdefaultR((s*/usr/lib64/python2.7/Demo/pdist/cmptree.pyR)scCs3td|t|f}|r/tj|S|S(Ns%s [%s] (Rtstrtstringtatoi(RR R((s*/usr/lib64/python2.7/Demo/pdist/cmptree.pytaskint-s cCsHdGttjGH|jd}|jd}|jdGHi}x$|jD]\}}|||s       P  &  PKH1](q makechangelog.pynuȯ#! /usr/bin/python2.7 """Turn a pile of RCS log output into ChangeLog file entries. """ import sys import string import re import getopt import time def main(): args = sys.argv[1:] opts, args = getopt.getopt(args, 'p:') prefix = '' for o, a in opts: if p == '-p': prefix = a f = sys.stdin allrevs = [] while 1: file = getnextfile(f) if not file: break revs = [] while 1: rev = getnextrev(f, file) if not rev: break revs.append(rev) if revs: allrevs[len(allrevs):] = revs allrevs.sort() allrevs.reverse() for rev in allrevs: formatrev(rev, prefix) parsedateprog = re.compile( '^date: ([0-9]+)/([0-9]+)/([0-9]+) ' + '([0-9]+):([0-9]+):([0-9]+); author: ([^ ;]+)') authormap = { 'guido': 'Guido van Rossum ', 'jack': 'Jack Jansen ', 'sjoerd': 'Sjoerd Mullender ', } def formatrev(rev, prefix): dateline, file, revline, log = rev if parsedateprog.match(dateline) >= 0: fields = parsedateprog.group(1, 2, 3, 4, 5, 6) author = parsedateprog.group(7) if authormap.has_key(author): author = authormap[author] tfields = map(string.atoi, fields) + [0, 0, 0] tfields[5] = tfields[5] - time.timezone t = time.mktime(tuple(tfields)) print time.ctime(t), '', author words = string.split(log) words[:0] = ['*', prefix + file + ':'] maxcol = 72-8 col = maxcol for word in words: if col > 0 and col + len(word) >= maxcol: print print '\t' + word, col = -1 else: print word, col = col + 1 + len(word) print print startprog = re.compile("^Working file: (.*)$") def getnextfile(f): while 1: line = f.readline() if not line: return None if startprog.match(line) >= 0: file = startprog.group(1) # Skip until first revision while 1: line = f.readline() if not line: return None if line[:10] == '='*10: return None if line[:10] == '-'*10: break ## print "Skipped", line, return file ## else: ## print "Ignored", line, def getnextrev(f, file): # This is called when we are positioned just after a '---' separator revline = f.readline() dateline = f.readline() log = '' while 1: line = f.readline() if not line: break if line[:10] == '='*10: # Ignore the *last* log entry for each file since it # is the revision since which we are logging. return None if line[:10] == '-'*10: break log = log + line return dateline, file, revline, log if __name__ == '__main__': main() PKH1])SS server.pycnu[ ^c@sdZddlZddlZddlZddlmZddlmZdZdd dYZddlm Z d ee fd YZ dS( sRPC Server module.iN(tfnmatch(trepritServercBseZdZedZdZdZdZdZdZ ddd d gZ d Z d Z d Z ddZRS(sDRPC Server class. Derive a class to implement a particular service.cCst|tdkr'd|f}n||_||_d|_tjtjtj|_|jj||jj dd|_ dS(Niti( ttypet_addresst_verbosetNonet_sockettsockettAF_INETt SOCK_STREAMtbindtlistent _listening(tselftaddresstverbose((s)/usr/lib64/python2.7/Demo/pdist/server.pyt__init__s   cCs ||_dS(N(R(RR((s)/usr/lib64/python2.7/Demo/pdist/server.pyt _setverbosescCs|jdS(N(t_close(R((s)/usr/lib64/python2.7/Demo/pdist/server.pyt__del__ scCs/d|_|jr"|jjnd|_dS(Ni(RRtcloseR(R((s)/usr/lib64/python2.7/Demo/pdist/server.pyR#s  cCsx|jr|jqWdS(N(Rt_serve(R((s)/usr/lib64/python2.7/Demo/pdist/server.pyt _serverloop)s cCs|jrdGHn|jj\}}|jrAdt|GHn|j||spdt|GH|jdS|jd}|jd}d}x=|r|j|jdkrdGHn|j||}qWdS(NsWait for connection ...sAccepted connection from %ss*** Connection from %s refusedtrtwisWait for next request ...( RRtacceptRt_verifyRtmakefiletflusht _dorequest(RtconnRtrftwftok((s)/usr/lib64/python2.7/Demo/pdist/server.pyR-s"     s 192.16.201.*s 192.16.197.*s 132.151.1.*s 129.6.64.*cCs7|\}}x$|jD]}t||rdSqWdS(Nii(t_validR(RR Rthosttporttpat((s)/usr/lib64/python2.7/Demo/pdist/server.pyR?s  c Csvtj|}y|j}Wntk r3dSX|jdkrUdt|GHny|\}}}d|krd|j|||f}nM|ddkrtdt|n't ||} dt | ||f}Wnt j t j |f}nX|dkr5|d d kr5|jdkr1dGHndS|jdkrVd t|GHntj|} | j|dS( NiisGot request: %st.t_sillegal method name %sisSuppress replysSend reply: %s(NN(tpicklet UnpicklertloadtEOFErrorRRRt_specialt NameErrortgetattrtapplytsystexc_typet exc_valuetPicklertdump( RR!R"trptrequestt methodnametargstidtreplytmethodtwp((s)/usr/lib64/python2.7/Demo/pdist/server.pyREs4   cCsQ|dkr:t|ds3t|j|_n|jStdt|dS(Ns.methodst_methodss#unrecognized special method name %s(thasattrttuplet _listmethodsR?R/R(RR9R:((s)/usr/lib64/python2.7/Demo/pdist/server.pyR._s  cCs|s|j}n|jj}td|}|jxE|jD]:}|j|}t|d|}||t|)qGW|S(NcSs|ddkS(NiR)((tx((s)/usr/lib64/python2.7/Demo/pdist/server.pytiRcSs ||kS(N((RCtnames((s)/usr/lib64/python2.7/Demo/pdist/server.pyRDmR(t __class__t__dict__tkeystfiltertsortt __bases__RBtlen(RtclREtbaset basenames((s)/usr/lib64/python2.7/Demo/pdist/server.pyRBfs  N(t__name__t __module__t__doc__tVERBOSERRRRRRR$RRR.RRB(((s)/usr/lib64/python2.7/Demo/pdist/server.pyRs        (tSecurityt SecureServercBseZdZdZRS(cGs(ttj|f|tj|dS(N(R1RRRT(RR:((s)/usr/lib64/python2.7/Demo/pdist/server.pyRwscCsddl}|j}|jd|d}xEd|krvt|dkrv|jd}|siPn||}q2Wy|j|j|}Wn6|jk r|jdkrdGt |GHndSX|j ||s|jdkrdGt |GHndS|jd krd GHnd S( Nis%d Rs idisInvalid response syntaxsInvalid response valueis&Response matches challenge. Go ahead!( tstringt_generate_challengetsendRLtrecvtatoltstript atol_errorRRt_compare_challenge_response(RR RRVt challengetresponsetdata((s)/usr/lib64/python2.7/Demo/pdist/server.pyR{s,  !(RPRQRR(((s)/usr/lib64/python2.7/Demo/pdist/server.pyRUus (( RRR2R R*RRRSRtsecurityRTRU(((s)/usr/lib64/python2.7/Demo/pdist/server.pyts   dPKH1]HxT3T3 cvslib.pyonu[ ^c@sdZddlZddlZddlZddlZddlZeeds]de_ndddYZdddYZ d d Z d Z d Z iZ d ZdZdZdZedkrendS(s!Utilities for CVS administration.iNttimezoneitFilecBs\eZdZd dZdZdZdZd dZdZ dZ dZ RS( sRepresent 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 cCsK|rd|krtdn||_d|_|_|_d|_dS(Nt/sno slash allowed in filei(t ValueErrortfiletlseenteseentrseentNonetproxy(tselfR((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt__init__9s   cCst|j|jS(N(tcmpR(R tother((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt__cmp__@scCsy&tj|jd\|_|_Wn+tjk rSd|_|_|_n(Xtj t |jj j |_d|_ dS(Nii(toststatRtlmtimetlctimeterrorRtlsumtmd5tnewtopentreadtdigestR(R ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytgetlocalCs &'cCs)tj|d}|jr:|d|jkr:tdn|d|_|d|_d|_d|_d|_|_ |jd dkrd|_|jd|_n|jdkrd|_d|_n0|d}t |d |_t |d |_ |d |_ |j r|j nd|_dS( NRisfile name mismatchiit-t0iiii(tstringt splitfieldsRRterevtedeletedtenewRtectimetemtimetunctimetextraRtgetesumR(R tlinetwordstdates((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytgetentryLs*            cCs|r||_ny|jj|j|_Wn#tjtfk rSd|_nX|jrx|jj|j|_ n d|_ |j r|j nd|_ dS(Ni( R theadRtrrevRRtIOErrorRtsumtrsumRR&R(R R ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt getremoteds      cCsa|j|jkr!|j|_n<|jrT|j|jf}|jj||_n d|_dS(N(RR,R/tesumRR R.R(R tname((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR&ss  cCs|js dS|jpd}|jr2d|}n|jrKd|j}n t|jdt|j}d|j|||jfS(sReturn 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 "". tRRsInitial t s/%s/%s/%s/%s/ ( RRR R!RtgmctimeR"R#R%(R trevR)((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytputentry|s    cCsddGHt|d}|d|jrU|dt|dt|dtn|jr|d|d |d |d t|d tn|jr|d |dt|jr|dtqndS(NRi2cSsDy|t||}Wntk r2d}nXd|G|GHdS(Nt?s%-15s:(tgetattrtAttributeError(tkeytreprR tvalue((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytrs   RRRRRR!R R"R#R,R/R1(R<RthexifyR5RR(R R>((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytreports$              N( t__name__t __module__t__doc__RR RRR*R0R&R7R@(((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR s+     tCVScBseZdZeZddddddddgZd Zd Zd Zd Z d Z ddZ dZ dZdZdZdZddZdZdZRS(sRepresent 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 s.*s@*s,*s*~s*.os*.as*.sos*.pyccCsi|_d|_dS(N(tentriesRR (R ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR s cCsC||jkrdS||_x |jjD]}d|_q,WdS(Ni(R REtvaluesR(R R te((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytsetproxys  cCsli|_|jd}xC|j}|s1Pn|j}|j|||j|jcCs>tjjd|}d|kr1|j|nt||S(NRDR>(RRcRdtbackupR(R Rtmode((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRJs cCs[tjj|rW|d}ytj|Wntjk rCnXtj||ndS(Nt~(RRctisfiletunlinkRtrename(R Rtbfile((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRgs cCsDtjj|rtSx'|jD]}tj||r tSq WtS(N(RRctisdirtTruet IgnoreListtfnmatchtFalse(R Rtpat((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRV#s N(RARBRCRRLRpR RHRORRR\RR_R@RSRFRbRfRJRgRV(((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRDs"           s%02xicCs'|dkrdStttt|S(sDReturn a hex representation of a 16-byte string (e.g. an MD5 digest)RN(Rt hexify_formatttupleR`tord(R.((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR?-s cCsd|dkrdSd}xGtdt|dD]-}|ttj|||d!d}q/W|S(s*Return the original from a hexified stringRR3iiiN(RtrangetlentchrRtatoi(thexsumR.ti((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytunhexify3s  +c Cs|dkrdStsndddddddd d d d d g }d}x%|D]}|d}|t|s    + cCs&|dkrdStjtj|S(NR(RRtasctimetgmtime(tt((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR5Os cCsttj}tj|}tj|}dG|G|GHdGtjGHdGtj|GHt|}dG|GHtj|}dG|GHtj|GHdS(NtGMTRtlocals unctime()s->(tintRRRRtctimeR$(tnowRtattutgu((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt test_unctimeSs     cCsPt}|j|jddl}|j}|j||jdS(Ni(RDROR\t rcsclientt openrcsclientR_R@(txRR ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyttest`s      t__main__(((RCRRRRRqthasattrRRRDRtR?R}RR$R5RRRA(((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyts&      ~      PKH1]GG RCSProxy.pycnu[ Afc@sdZddlZddlZddlZddlZddlZddlZddlZdd dYZdej efdYZ de ej fdYZ d Z d Zed krendS( sRCS Proxy. Provide a simplified interface on RCS files, locally or remotely. The functionality is geared towards implementing some sort of remote CVS like utility. It is modeled after the similar module FSProxy. The module defines two classes: RCSProxyLocal -- used for local access RCSProxyServer -- used on the server side of remote access The corresponding client class, RCSProxyClient, is defined in module rcsclient. The remote classes are instantiated with an IP address and an optional verbosity flag. iNt DirSupportcBseeZdZdZdZdZdZdZd dZ dZ dZ d Z RS( cCs g|_dS(N(t _dirstack(tself((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt__init__!scCs|jdS(N(t_close(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt__del__$scCsx|jr|jqWdS(N(Rtback(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR's cCs tjS(N(tostgetcwd(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytpwd+scCs-tj}tj||jj|dS(N(RRtchdirRtappend(Rtnametsave((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytcd.s  cCs@|jstjdn|jd}tj||jd=dS(Nsempty directory stacki(RRterrorR (Rtdir((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR3s    cCs7tjtj}ttjj|}|j||S(N(Rtlistdirtcurdirtfiltertpathtisdirt_filter(Rtpattfiles((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt listsubdirs:scCstjj|S(N(RRR(RR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR?scCstj|ddS(Ni(Rtmkdir(RR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRBscCstj|dS(N(Rtrmdir(RR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyREsN( t__name__t __module__RRRR RRtNoneRRRR(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRs         t RCSProxyLocalcBsheZdZdZd dZd dZdZdZd dZ d dZ d dZ RS( cCs!tjj|tj|dS(N(trcslibtRCSRR(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRKscCs!tj|tjj|dS(N(RRR R!(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyROs cCs|j|j|S(N(t_listtsum(Rtlist((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytsumlistSscCs|j|j|S(N(t_dictR#(RR$((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytsumdictVscCse|j|}d}tj}x*|j|}|s=Pn|j|q$W|j||jS(Niii (t_opentmd5tnewtreadtupdatet _closepipetdigest(Rtname_revtft BUFFERSIZER#tbuffer((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR#Ys  cCs,|j|}|j}|j||S(N(R(R+R-(RR/R0tdata((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytgetes  cCs\|j|\}}t|d}|j||j|j|||j|dS(Ntw(t _unmangletopentwritetclosetcheckint_remove(RR/R3tmessageR trevR0((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytputks   cCs|dkr|j}ng}x[|D]S}y|j|||fWq(tjtfk rz|j|dfq(Xq(W|S(sINTERNAL: apply FUNCTION to all files in LIST. Return a list of the results. The list defaults to all files in the directory if None. N(Rt listfilesR RRtIOError(RtfunctionR$tresR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR"ss  cCsg|dkr|j}ni}x?|D]7}y||||R"R&(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRIs       tRCSProxyServercBs)eZejdZdZdZRS(cCs'tj|tjj|||dS(N(RRtservert SecureServer(Rtaddresstverbose((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRs cCs!tjj|tj|dS(N(RERFRR(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRscCs.tjj|x|jr)|jqWdS(N(RERFt_serveRR(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRIs (RRREtVERBOSERRRI(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRDs cCsdddl}ddl}|jdr>|j|jd}nd}td|f}|jdS(Niiit(tstringtsystargvtatoiRDt _serverloop(RLRMtporttproxy((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt test_servers   cCsddl}|jd s>|jdrU|jdddkrUt|jdnt}|jd}t||rt||}t|rt|t |jdGHqt |GHnd|GH|jddS(Niiit 0123456789is%s: no such attribute( RMRNRStexitRthasattrtgetattrtcallabletapplyttupletrepr(RMRRtwhattattr((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyttests 2    t__main__((t__doc__RER)RtfnmatchRLttempfileR RR!RRFRDRSR^R(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyts       *O  PKH1];DD client.pyonu[ ^c@sdZddlZddlZddlZddlZddlZdZdd dYZddlm Z dee fdYZ d d d YZ dS( sRPC Client module.iNitClientcBseZdZedZedZdZdZdZdZ dZ dZ d Z d Z d Zd Zd dZdZdZdZRS(sCRPC Client class. No need to derive a class -- it's fully generic.cCs|j|||jdS(N(t _pre_initt _post_init(tselftaddresstverbose((s)/usr/lib64/python2.7/Demo/pdist/client.pyt__init__scCst|tdkr'd|f}n||_||_|jrTdt|GHntjtjtj|_|jj||jrdGHnd|_ d|_ i|_ |jj d|_ |jj d|_dS(NitsConnecting to %s ...s Connected.itrtw(ttypet_addresst_verbosetreprtsockettAF_INETt SOCK_STREAMt_sockettconnectt_lastidt_nextidt_repliestmakefilet_rft_wf(RRR((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs       cCs|jd|_dS(Ns.methods(t_callt_methods(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyR%scCs|jdS(N(t_close(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyt__del__(scCsj|jr|jjnd|_|jr;|jjnd|_|jr]|jjnd|_dS(N(RtclosetNoneRR(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyR+s     cCs?||jkr2t||}t||||St|dS(N(Rt_stubtsetattrtAttributeError(Rtnametmethod((s)/usr/lib64/python2.7/Demo/pdist/client.pyt __getattr__3s cCs ||_dS(N(R (RR((s)/usr/lib64/python2.7/Demo/pdist/client.pyt _setverbose:scGs|j||S(N(t_vcall(RR"targs((s)/usr/lib64/python2.7/Demo/pdist/client.pyR=scCs|j|j||S(N(t_recvt_vsend(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyR&@scGs|j||S(N(R)(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt_sendCscGs|j||dS(Ni(R)(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt _send_noreplyFscCs|j||dS(Ni(R)(RR"R'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt_vsend_noreplyIsicCsy|j}|d|_|s&| }n|||f}|jdkrVdt|GHntj|j}|j||S(Nissending request: %s(RR R tpickletPicklerRtdump(RR"R't wantreplytidtrequesttwp((s)/usr/lib64/python2.7/Demo/pdist/client.pyR)Ls    cCs|j|\}}}||kr:td||fn|dkrJ|S|}tt|rqtt|}n|dkrtj}n||kr|}n||dS(Ns request/reply id mismatch: %d/%ds posix.errors mac.error(s posix.errors mac.error(t_vrecvt RuntimeErrorRthasattrt __builtin__tgetattrtosterror(RR1t exceptiontvaluetridtx((s)/usr/lib64/python2.7/Demo/pdist/client.pyR(Vs      cCs@|j|jj|rR|jdkr7d|GHn|j|}|j|=|St|}x|jdkr|d|GHntj|j}|j}~|jdkrdt |GHn|d}t|}||kr|jdkrdGHn|S||j|<||kra|jdkr+dGHndd|fSqaWdS(Nis"retrieving previous reply, id = %dswaiting for reply, id = %ds got reply: %sisgot itsgot higher id, assume all ok( t_flushRthas_keyR tabsR-t UnpicklerRtloadR R(RR1treplytaidtrpR=tarid((s)/usr/lib64/python2.7/Demo/pdist/client.pyR4es6            cCs|jjdS(N(Rtflush(R((s)/usr/lib64/python2.7/Demo/pdist/client.pyR?}s(t__name__t __module__t__doc__tVERBOSERRRRRR$R%RR&R*R+R,R)R(R4R?(((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs"              (tSecurityt SecureClientcBseZdZRS(cGsddl}t|j|tj||jj|jj}|j |j |}|j |}t t |}|ddkr|d }n|jj|d|jj|jdS(NitLls (tstringtapplyRRMRRRHRtreadlinetatoitstript_encode_challengeR tlongtwriteR(RR'RPtlinet challengetresponse((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs     (RIRJR(((s)/usr/lib64/python2.7/Demo/pdist/client.pyRNsRcBs eZdZdZdZRS(sJHelper class for Client -- each instance serves as a method of the client.cCs||_||_dS(N(t_clientt_name(RtclientR"((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs cGs|jj|j|S(N(R[R&R\(RR'((s)/usr/lib64/python2.7/Demo/pdist/client.pyt__call__s(RIRJRKRR^(((s)/usr/lib64/python2.7/Demo/pdist/client.pyRs ((( RKtsysRR-R7R9RLRtsecurityRMRNR(((s)/usr/lib64/python2.7/Demo/pdist/client.pyts     sPKH1]Udd client.pynu["""RPC Client module.""" import sys import socket import pickle import __builtin__ import os # Default verbosity (0 = silent, 1 = print connections, 2 = print requests too) 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() 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() 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) PKH1]#)-- rcslib.pycnu[ ^c@sYdZddlZddlZddlZddlZddlZdddYZdS(sRCS interface module. Defines the class RCS, which represents a directory with rcs version files and (possibly) corresponding work files. iNtRCScBseZdZejejdZdZdZddZ dZ dZ dZ d Z d dd Zddd Zdd ZdZdZdZdZdZdddZdZdZdZddZdZdZRS(s7RCS interface class (local filesystem version). An instance of this class represents a directory with rcs version files and (possible) corresponding work files. Methods provide access to most rcs operations such as checkin/checkout, access to the rcs metadata (revisions, logs, branches etc.) as well as some filesystem operations such as listing all rcs version files. XXX BUGS / PROBLEMS - The instance always represents the current directory so it's not very useful to have more than one instance around simultaneously s-_=+cCsdS(s Constructor.N((tself((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyt__init__&scCsdS(s Destructor.N((R((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyt__del__*stcCsi|j|d|}|j}|j|}|rH|d|}n|ddkre|d }n|S(smReturn the full log text for NAME_REV as a string. Optional OTHERFLAGS are passed to rlog. srlog s%s: %sis (t_opentreadt _closepipe(Rtname_revt otherflagstftdatatstatus((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pytlog0s  cCs|j|}|dS(s%Return the head revision for NAME_REVthead(tinfo(RRtdict((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR?sc Cs|j|d}i}x}|j}|s1Pn|ddkrGqntj|d}|dkr|| tj||d}}|||" if None); or the file description if this is a new file. The optional OTHERFLAGS argument is passed to ci without interpretation. Any output from ci goes to directly to stdout. sis s-usci %s%s -t%s %s %ss([\"$`])s\\\1sci %s%s -m"%s" %s %s( t _unmangletisvalidttempfiletNamedTemporaryFiletwritetflushRtretsubR( RRtmessageR RRtnewR#R R((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pytcheckins"      cCstjtj}t|j|}tjjdrdtjd}t|j|}||}nt|j|}|j ||S(s=Return a list of all version files matching optional PATTERN.R( tostlistdirtcurdirtfiltert_isrcstpathtisdirtmaptrealnamet_filter(Rtpattfilestfiles2((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyt listfiless cCs@|j|}tjj|p?tjjtjjd|S(s0Test whether NAME has a version file associated.R(trcsnameR0R5tisfiletjoin(RRtnamev((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR&scCs|j|r|}n |d}tjj|r8|Stjjdtjj|}tjj|ro|Stjjdrtjjd|S|SdS(sReturn the pathname of the version file for NAME. The argument can be a work file name or a version file name. If the version file does not exist, the name of the version file that would be created by "ci" is returned. s,vRN(R4R0R5R?R@tbasenameR6(RRRA((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR>s  !cCsN|j|r|d }n|}tjj|r8|Stjj|}|S(sReturn the pathname of the work file for NAME. The argument can be a work file name or a version file name. If the work file does not exist, the name of the work file that would be created by "co" is returned. i(R4R0R5R?RB(RRAR((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR8s cCs|j|d}|j}|j|}|r?t|n|sIdS|ddkrf|d }n|j||j|kS(sTest whether FILE (which must have a version file) is locked. XXX This does not tell you which revision number is locked and ignores any revision you may pass in (by virtue of using rlog -L -R). s rlog -L -Ris N(RRRRtNoneR8(RRR RR ((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pytislockeds   cCsD|j|\}}|j|s:tjd|fn||fS(s}Normalize NAME_REV into a (NAME, REV) tuple. Raise an exception if there is no corresponding version file. snot an rcs file %r(R%R&R0terror(RRRR((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRssco -ps-rcCsV|j|\}}|j|}|r?|d||}ntjd||fS(sINTERNAL: open a read pipe to NAME_REV using optional COMMAND. Optional FLAG is used to indicate the revision (default -r). Default COMMAND is "co -p". Return a file object connected by a pipe to the command's output. t s%s %r(RR>R0tpopen(RRRtrflagRRRA((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRs cCsmt|tdkr1|df}\}}n |\}}x)|D]!}||jkrDtdqDqDW|S(sINTERNAL: Normalize NAME_REV argument to (NAME, REV) tuple. Raise an exception if NAME contains invalid characters. A NAME_REV argument is either NAME string (implying REV='') or a tuple of the form (NAME, REV). Rsbad char in rev(ttypetokcharst ValueError(RRRRtc((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR%s   cCs|j}|sd St|d\}}|dkrAd|fS|d@}|dkrfd}|}nd}|d@r|d}n||fS( s:INTERNAL: Close PIPE and print its exit status if nonzero.iitexititstoppedtkilledis (coredump)N(tcloseRCtdivmod(RR tststdetailtreasontsignaltcode((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRs       cCs3|d}tj|}|r/td|ndS(s{INTERNAL: run COMMAND in a subshell. Standard input for the command is taken from /dev/null. Raise IOError when the exit status is not zero. Return whatever the calling method should return; normally None. A derived class may override this method and redefine it to capture stdout/stderr of the command and return it. s R8RDRRR%RRR9R]R4(((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRs0       !          ((R`RXR0R+RR'R(((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyts      PKH1]GG RCSProxy.pyonu[ Afc@sdZddlZddlZddlZddlZddlZddlZddlZdd dYZdej efdYZ de ej fdYZ d Z d Zed krendS( sRCS Proxy. Provide a simplified interface on RCS files, locally or remotely. The functionality is geared towards implementing some sort of remote CVS like utility. It is modeled after the similar module FSProxy. The module defines two classes: RCSProxyLocal -- used for local access RCSProxyServer -- used on the server side of remote access The corresponding client class, RCSProxyClient, is defined in module rcsclient. The remote classes are instantiated with an IP address and an optional verbosity flag. iNt DirSupportcBseeZdZdZdZdZdZdZd dZ dZ dZ d Z RS( cCs g|_dS(N(t _dirstack(tself((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt__init__!scCs|jdS(N(t_close(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt__del__$scCsx|jr|jqWdS(N(Rtback(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR's cCs tjS(N(tostgetcwd(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytpwd+scCs-tj}tj||jj|dS(N(RRtchdirRtappend(Rtnametsave((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytcd.s  cCs@|jstjdn|jd}tj||jd=dS(Nsempty directory stacki(RRterrorR (Rtdir((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR3s    cCs7tjtj}ttjj|}|j||S(N(Rtlistdirtcurdirtfiltertpathtisdirt_filter(Rtpattfiles((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt listsubdirs:scCstjj|S(N(RRR(RR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR?scCstj|ddS(Ni(Rtmkdir(RR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRBscCstj|dS(N(Rtrmdir(RR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyREsN( t__name__t __module__RRRR RRtNoneRRRR(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRs         t RCSProxyLocalcBsheZdZdZd dZd dZdZdZd dZ d dZ d dZ RS( cCs!tjj|tj|dS(N(trcslibtRCSRR(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRKscCs!tj|tjj|dS(N(RRR R!(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyROs cCs|j|j|S(N(t_listtsum(Rtlist((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytsumlistSscCs|j|j|S(N(t_dictR#(RR$((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytsumdictVscCse|j|}d}tj}x*|j|}|s=Pn|j|q$W|j||jS(Niii (t_opentmd5tnewtreadtupdatet _closepipetdigest(Rtname_revtft BUFFERSIZER#tbuffer((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR#Ys  cCs,|j|}|j}|j||S(N(R(R+R-(RR/R0tdata((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytgetes  cCs\|j|\}}t|d}|j||j|j|||j|dS(Ntw(t _unmangletopentwritetclosetcheckint_remove(RR/R3tmessageR trevR0((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pytputks   cCs|dkr|j}ng}x[|D]S}y|j|||fWq(tjtfk rz|j|dfq(Xq(W|S(sINTERNAL: apply FUNCTION to all files in LIST. Return a list of the results. The list defaults to all files in the directory if None. N(Rt listfilesR RRtIOError(RtfunctionR$tresR ((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyR"ss  cCsg|dkr|j}ni}x?|D]7}y||||R"R&(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRIs       tRCSProxyServercBs)eZejdZdZdZRS(cCs'tj|tjj|||dS(N(RRtservert SecureServer(Rtaddresstverbose((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRs cCs!tjj|tj|dS(N(RERFRR(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRscCs.tjj|x|jr)|jqWdS(N(RERFt_serveRR(R((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRIs (RRREtVERBOSERRRI(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyRDs cCsdddl}ddl}|jdr>|j|jd}nd}td|f}|jdS(Niiit(tstringtsystargvtatoiRDt _serverloop(RLRMtporttproxy((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyt test_servers   cCsddl}|jd s>|jdrU|jdddkrUt|jdnt}|jd}t||rt||}t|rt|t |jdGHqt |GHnd|GH|jddS(Niiit 0123456789is%s: no such attribute( RMRNRStexitRthasattrtgetattrtcallabletapplyttupletrepr(RMRRtwhattattr((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyttests 2    t__main__((t__doc__RER)RtfnmatchRLttempfileR RR!RRFRDRSR^R(((s+/usr/lib64/python2.7/Demo/pdist/RCSProxy.pyts       *O  PKH1]Șy cmptree.pynu["""Compare local and remote dictionaries and transfer differing files -- like rdist.""" import sys from repr import repr import FSProxy 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 """\ 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] ") def ask(prompt, 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 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() 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 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) 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.", size//dt, "bytes/sec", print remote._recv(id) # ignored def fl(): sys.stdout.flush() if __name__ == '__main__': main() PKH1]5tVVmac.pycnu[ ^c@s8ddlZddlZddlZdZedS(iNcCsxzytd}Wntk r'PnXtj|}|sCqn|ddkrf|jddn|t_tjqWdS(Ns$ itrcvs( t raw_inputtEOFErrortstringtsplittinserttsystargvRtmain(tlinetwords((s&/usr/lib64/python2.7/Demo/pdist/mac.pyRs  (RRRR(((s&/usr/lib64/python2.7/Demo/pdist/mac.pyts    PKH1]l!!cmdfw.pynu["Framework for command line interfaces like CVS. See class CmdFrameWork." 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!" 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) if __name__ == '__main__': test() PKH1]F N2 2 makechangelog.pycnu[ Afc@sdZddlZddlZddlZddlZddlZdZejddZidd6dd 6d d 6Z d Z ejd Z dZ dZ edkrendS(s<Turn a pile of RCS log output into ChangeLog file entries. iNc Cstjd}tj|d\}}d}x)|D]!\}}tdkr2|}q2q2Wtj}g}xft|}|sPng}x*t||} | sPn|j| qW|ri||t|)qiqiW|j |j x|D]} t | |qWdS(Nisp:ts-p( tsystargvtgetopttptstdint getnextfilet getnextrevtappendtlentsorttreverset formatrev( targstoptstprefixtotatftallrevstfiletrevstrev((s0/usr/lib64/python2.7/Demo/pdist/makechangelog.pytmain s0       s"^date: ([0-9]+)/([0-9]+)/([0-9]+) s-([0-9]+):([0-9]+):([0-9]+); author: ([^ ;]+)s+Guido van Rossum tguidosJack Jansen tjacks!Sjoerd Mullender tsjoerdcCsh|\}}}}tj|dkrdtjdddddd}tjd}tj|rpt|}nttj|dddg}|dtj |ds&            PKH1]Op!p! cvslock.pycnu[ ^c@sdZddlZddlZddlZddlZdZdZdZdZdZ ddd YZ d e fd YZ d dd YZ dZ de fdYZde fdYZedZdZedkrendS(sCVS locking algorithm. CVS locking strategy ==================== As reverse engineered from the CVS 1.3 sources (file lock.c): - Locking is done on a per repository basis (but a process can hold write locks for multiple directories); all lock files are placed in the repository and have names beginning with "#cvs.". - Before even attempting to lock, a file "#cvs.tfl." is created (and removed again), to test that we can write the repository. [The algorithm can still be fooled (1) if the repository's mode is changed while attempting to lock; (2) if this file exists and is writable but the directory is not.] - While creating the actual read/write lock files (which may exist for a long time), a "meta-lock" is held. The meta-lock is a directory named "#cvs.lock" in the repository. The meta-lock is also held while a write lock is held. - To set a read 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." - To release a write lock: - remove the file "#cvs.wfl." - rmdir the meta-lock - To release a read lock: - remove the file "#cvs.rfl." Additional notes ---------------- - A process should read-lock at most one repository at a time. - A process may write-lock as many repositories as it wishes (to avoid deadlocks, I presume it should always lock them top-down in the directory hierarchy). - A process should make sure it removes all its lock files and directories when it crashes. - Limitation: one user id should not be committing files into the same repository at the same time. Turn this into Python code -------------------------- rl = ReadLock(repository, waittime) wl = WriteLock(repository, waittime) list = MultipleWriteLock([repository1, repository2, ...], waittime) iNi is#cvs.lcks #cvs.rfl.s #cvs.wfl.tErrorcBs#eZdZdZdZRS(cCs ||_dS(N(tmsg(tselfR((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt__init__`scCs t|jS(N(treprR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt__repr__cscCs t|jS(N(tstrR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt__str__fs(t__name__t __module__RRR(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR^s  tLockedcBseZRS((RR (((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR jstLockcBsVeZdedZdZdZdZdZdZdZ dZ RS( t.cCsx||_||_d|_d|_ttj}|jt |_ |jt ||_ |jt ||_dS(N(t repositorytdelaytNonetlockdirtlockfileRtostgetpidtjointCVSLCKtcvslcktCVSRFLtcvsrfltCVSWFLtcvswfl(RR Rtpid((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRps    cCsdGH|jdS(Nt__del__(tunlock(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRzscCsxy'|j|_tj|jddSWqtjk r}d|_|dtkrytj|j}Wntjk rqnX|j|qnt d|j |fqXqWdS(Niisfailed to lock %s: %s( RRRtmkdirterrorRtEEXISTtstattsleepRR (RRtst((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt setlockdir~s    cCs|j|jdS(N(t unlockfilet unlockdir(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs cCsP|jrLdG|jGHytj|jWntjk r?nXd|_ndS(Ntunlink(RRR'RR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR%s  cCsP|jrLdG|jGHytj|jWntjk r?nXd|_ndS(Ntrmdir(RRR(RR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR&s  cCst||j|jdS(N(R"R R(RR#((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR"scCstjj|j|S(N(RtpathRR (Rtname((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs( RR tDELAYRRR$RR%R&R"R(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR ns    cCs|dkrt|n|tj}ytj|}|d}Wntk rbd|}nXdtjtjdd!Gd|G|GHtj|dS(Nisuid %ds[%s]i isWaiting for %s's lock in( R R!tST_UIDtpwdtgetpwuidtKeyErrorttimetctimeR"(R#R Rtuidtpwenttuser((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR"s    tReadLockcBseZedZRS(cCsztj|||d}z<|j|j|_t|jd}|jd}Wd|sk|jn|jXdS(Nitwi( R RR$RRtopentcloseR%R&(RR Rtoktfp((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs     (RR R+R(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR5st WriteLockcBseZedZdZRS(cCs}tj||||jx1|j}|s6Pn|j|j|q W|j|_t|jd}|j dS(NR6( R RR$t readers_existR&R"RRR7R8(RR RR2R:((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs    cCswtt}xdtj|jD]P}|| tkrytj|j|}Wntjk rjqnX|SqWdS(N( tlenRRtlistdirR R!RRR(RtnR*R#((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR<s (RR R+RR<(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR;s cCsjxcg}xC|D]:}y|jt|dWqtk rI}~PqXqWPt|j||qWtS(Ni(tappendR;R R"Rtlist(t repositoriesRtlockstrtinstance((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pytMultipleWriteLocks  cCsddl}|jdr)|jd}nd}d}d}zDdGHt|}dGH|jdGHt|}dGH|jWddgGHd|_dgGH|r|jndgGH|r|jnd gGHd}d gGHd}d gGHXdS( NiiR sattempting write lock ...sgot it.sattempting read lock ...iiiii(tsystargvRR;RR5t exc_traceback(RGR trltwl((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyttests8        t__main__(((t__doc__RR0R!R-R+R RRRRR R R"R5R;RFRLR(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pytGs&     ?   ! PKH1] ,READMEnu[Filesystem, RCS and CVS client and server classes ================================================= *** See the security warning at the end of this file! *** This directory contains various modules and classes that support remote file system operations. CVS stuff --------- rcvs Script to put in your bin directory rcvs.py Remote CVS client command line interface cvslib.py CVS admin files classes (used by rrcs) cvslock.py CVS locking algorithms RCS stuff --------- rrcs Script to put in your bin directory rrcs.py Remote RCS client command line interface rcsclient.py Return an RCSProxyClient instance (has reasonable default server/port/directory) RCSProxy.py RCS proxy and server classes (on top of rcslib.py) rcslib.py Local-only RCS base class (affects stdout & local work files) FSProxy stuff ------------- sumtree.py Old demo for FSProxy cmptree.py First FSProxy client (used to sync from the Mac) FSProxy.py Filesystem interface classes Generic client/server stuff --------------------------- client.py Client class server.py Server class security.py Security mix-in class (not very secure I think) Other generic stuff ------------------- cmdfw.py CommandFrameWork class (used by rcvs, should be used by rrcs as well) Client/Server operation ----------------------- The Client and Server classes implement a simple-minded RPC protocol, using Python's pickle module to transfer arguments, return values and exceptions with the most generality. The Server class is instantiated with a port number on which it should listen for requests; the Client class is instantiated with a host name and a port number where it should connect to. Once a client is connected, a TCP connection is maintained between client and server. The Server class currently handles only one connection at a time; however it could be rewritten to allow various modes of operations, using multiple threads or processes or the select() system call as desired to serve multiple clients simultaneously (when using select(), still handling one request at a time). This would not require rewriting of the Client class. It may also be possible to adapt the code to use UDP instead of TCP, but then both classes will have to be rewritten (and unless extensive acknowlegements and request serial numbers are used, the server should handle duplicate requests, so its semantics should be idempotent -- shrudder). Even though the FSProxy and RCSProxy modules define client classes, the client class is fully generic -- what methods it supports is determined entirely by the server. The server class, however, must be derived from. This is generally done as follows: from server import Server from client import Client # Define a class that performs the operations locally class MyClassLocal: def __init__(self): ... def _close(self): ... # Derive a server class using multiple inheritance class MyClassServer(MyClassLocal, Server): def __init__(self, address): # Must initialize MyClassLocal as well as Server MyClassLocal.__init__(self) Server.__init__(self, address) def _close(self): Server._close() MyClassLocal._close() # A dummy client class class MyClassClient(Client): pass Note that because MyClassLocal isn't used in the definition of MyClassClient, it would actually be better to place it in a separate module so the definition of MyClassLocal isn't executed when we only instantiate a client. The modules client and server should probably be renamed to Client and Server in order to match the class names. *** Security warning: this version requires that you have a file $HOME/.python_keyfile at the server and client side containing two comma- separated numbers. The security system at the moment makes no guarantees of actuallng being secure -- however it requires that the key file exists and contains the same numbers at both ends for this to work. (You can specify an alternative keyfile in $PYTHON_KEYFILE). Have a look at the Security class in security.py for details; basically, if the key file contains (x, y), then the security server class chooses a random number z (the challenge) in the range 10..100000 and the client must be able to produce pow(z, x, y) (i.e. z**x mod y). PKH1]%{Șrrcs.pynuȯ#! /usr/bin/python2.7 "Remote RCS -- command line interface" import sys import os import getopt import string import md5 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) 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 def checkout(x, copts, fn): data = x.get(fn) f = open(fn, 'w') f.write(data) f.close() def lock(x, copts, fn): x.lock(fn) def unlock(x, copts, 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 def head(x, copts, fn): head = x.head(fn) print fn, head def list(x, copts, 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 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 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 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 def remove(fn): 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), } if __name__ == '__main__': main() PKH1]Op!p! cvslock.pyonu[ ^c@sdZddlZddlZddlZddlZdZdZdZdZdZ ddd YZ d e fd YZ d dd YZ dZ de fdYZde fdYZedZdZedkrendS(sCVS locking algorithm. CVS locking strategy ==================== As reverse engineered from the CVS 1.3 sources (file lock.c): - Locking is done on a per repository basis (but a process can hold write locks for multiple directories); all lock files are placed in the repository and have names beginning with "#cvs.". - Before even attempting to lock, a file "#cvs.tfl." is created (and removed again), to test that we can write the repository. [The algorithm can still be fooled (1) if the repository's mode is changed while attempting to lock; (2) if this file exists and is writable but the directory is not.] - While creating the actual read/write lock files (which may exist for a long time), a "meta-lock" is held. The meta-lock is a directory named "#cvs.lock" in the repository. The meta-lock is also held while a write lock is held. - To set a read 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." - To release a write lock: - remove the file "#cvs.wfl." - rmdir the meta-lock - To release a read lock: - remove the file "#cvs.rfl." Additional notes ---------------- - A process should read-lock at most one repository at a time. - A process may write-lock as many repositories as it wishes (to avoid deadlocks, I presume it should always lock them top-down in the directory hierarchy). - A process should make sure it removes all its lock files and directories when it crashes. - Limitation: one user id should not be committing files into the same repository at the same time. Turn this into Python code -------------------------- rl = ReadLock(repository, waittime) wl = WriteLock(repository, waittime) list = MultipleWriteLock([repository1, repository2, ...], waittime) iNi is#cvs.lcks #cvs.rfl.s #cvs.wfl.tErrorcBs#eZdZdZdZRS(cCs ||_dS(N(tmsg(tselfR((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt__init__`scCs t|jS(N(treprR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt__repr__cscCs t|jS(N(tstrR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt__str__fs(t__name__t __module__RRR(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR^s  tLockedcBseZRS((RR (((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR jstLockcBsVeZdedZdZdZdZdZdZdZ dZ RS( t.cCsx||_||_d|_d|_ttj}|jt |_ |jt ||_ |jt ||_dS(N(t repositorytdelaytNonetlockdirtlockfileRtostgetpidtjointCVSLCKtcvslcktCVSRFLtcvsrfltCVSWFLtcvswfl(RR Rtpid((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRps    cCsdGH|jdS(Nt__del__(tunlock(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRzscCsxy'|j|_tj|jddSWqtjk r}d|_|dtkrytj|j}Wntjk rqnX|j|qnt d|j |fqXqWdS(Niisfailed to lock %s: %s( RRRtmkdirterrorRtEEXISTtstattsleepRR (RRtst((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyt setlockdir~s    cCs|j|jdS(N(t unlockfilet unlockdir(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs cCsP|jrLdG|jGHytj|jWntjk r?nXd|_ndS(Ntunlink(RRR'RR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR%s  cCsP|jrLdG|jGHytj|jWntjk r?nXd|_ndS(Ntrmdir(RRR(RR(R((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR&s  cCst||j|jdS(N(R"R R(RR#((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR"scCstjj|j|S(N(RtpathRR (Rtname((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs( RR tDELAYRRR$RR%R&R"R(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR ns    cCs|dkrt|n|tj}ytj|}|d}Wntk rbd|}nXdtjtjdd!Gd|G|GHtj|dS(Nisuid %ds[%s]i isWaiting for %s's lock in( R R!tST_UIDtpwdtgetpwuidtKeyErrorttimetctimeR"(R#R Rtuidtpwenttuser((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR"s    tReadLockcBseZedZRS(cCsztj|||d}z<|j|j|_t|jd}|jd}Wd|sk|jn|jXdS(Nitwi( R RR$RRtopentcloseR%R&(RR Rtoktfp((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs     (RR R+R(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR5st WriteLockcBseZedZdZRS(cCs}tj||||jx1|j}|s6Pn|j|j|q W|j|_t|jd}|j dS(NR6( R RR$t readers_existR&R"RRR7R8(RR RR2R:((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyRs    cCswtt}xdtj|jD]P}|| tkrytj|j|}Wntjk rjqnX|SqWdS(N( tlenRRtlistdirR R!RRR(RtnR*R#((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR<s (RR R+RR<(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyR;s cCsjxcg}xC|D]:}y|jt|dWqtk rI}~PqXqWPt|j||qWtS(Ni(tappendR;R R"Rtlist(t repositoriesRtlockstrtinstance((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pytMultipleWriteLocks  cCsddl}|jdr)|jd}nd}d}d}zDdGHt|}dGH|jdGHt|}dGH|jWddgGHd|_dgGH|r|jndgGH|r|jnd gGHd}d gGHd}d gGHXdS( NiiR sattempting write lock ...sgot it.sattempting read lock ...iiiii(tsystargvRR;RR5t exc_traceback(RGR trltwl((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pyttests8        t__main__(((t__doc__RR0R!R-R+R RRRRR R R"R5R;RFRLR(((s*/usr/lib64/python2.7/Demo/pdist/cvslock.pytGs&     ?   ! PKH1]Mi$11 FSProxy.pyonu[ ^c@sdZddlZddlZddlZddlZddlZddlTddlZddlZdZej ej fZ dd dYZ de ej fdYZd ejfd YZd Zed krendS(sFile System Proxy. Provide an OS-neutral view on a file system, locally or remotely. The functionality is geared towards implementing some sort of rdist-like utility between a Mac and a UNIX system. The module defines three classes: FSProxyLocal -- used for local access FSProxyServer -- used on the server side of remote access FSProxyClient -- used on the client side of remote access The remote classes are instantiated with an IP address and an optional verbosity flag. iN(t*it FSProxyLocalcBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d+d Zd+d Zd+d Zd+dZdZdZdZdZdZdZdZdZdZdZd+dZd+dZd+dZd+dZd+dZ dZ!d+dZ"d+d Z#d+d!Z$d+d"Z%d+d#Z&d$d%d&Z'd'Z(d$d(Z)d)Z*d*Z+RS(,cCs#g|_dg|j|_dS(Ns*.pyc(t _dirstackt _readignoret_ignore(tself((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt__init__!s cCsx|jr|jqWdS(N(Rtback(R((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_close%s cCs|jd}yt|}WnEtk rf|jd}yt|}Wqgtk rbgSXnXg}xD|j}|sPn|ddkr|d }n|j|qpW|j|S(Ntignoressynctree.ignorefilesis (t_hidetopentIOErrortreadlinetappendtclose(RtfiletfR tline((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR)s&      cCs|ddkS(Nit.((Rtname((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_hidden<scCsd|S(Ns.%s((RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR ?scCst|tkrdS|ddkr*dS|tkr:dS|j|rMdStjj|\}}|sr| rvdStjj|rdSdt|dj dkrdSx'|j D]}t j ||rdSqWdS(Niit~strbii( tlent maxnamelent skipnamesRtostpathtsplittislinkR treadRtfnmatch(RRtheadttailtign((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytvisibleBs&  cCs,|j|s(tjdt|ndS(Nsprotected name %s(R$Rterrortrepr(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytcheckOscCs<|j|tjj|s8tjdt|ndS(Nsnot a plain file %s(R'RRtisfileR%R&(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt checkfileSs cCs tjS(N(Rtgetcwd(R((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytpwdXscCsY|j|tj|jf}tj||jj||j|j|_dS(N(R'RR*RtchdirRRR(RRtsave((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytcd[s   cCsO|jstjdn|jd\}}tj||jd=||_dS(Nsempty directory stacki(RRR%R,R(RtdirR ((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRbs    cCsD|r$|d}t||}nt|j|}|j|S(NcSstj||S(N(R (Rtpat((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytkeepls(tfilterR$tsort(RtfilesR0R1((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_filterjs   cCs"tjtj}|j||S(N(RtlistdirtcurdirR5(RR0R4((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytlistsscCs7tjtj}ttjj|}|j||S(N(RR6R7R2RR(R5(RR0R4((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt listfileswscCs7tjtj}ttjj|}|j||S(N(RR6R7R2RtisdirR5(RR0R4((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt listsubdirs|scCs|j|otjj|S(N(R$RRtexists(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR<scCs|j|otjj|S(N(R$RRR:(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR:scCs|j|otjj|S(N(R$RRR(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRscCs|j|otjj|S(N(R$RRR((RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR(scCsb|j|d}t|}tj}x*|j|}|sGPn|j|q.W|jS(Niii (R)R tmd5tnewRtupdatetdigest(RRt BUFFERSIZERtsumtbuffer((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRBs   cCs|j|tj|tS(N(R)RtstattST_SIZE(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytsizes cCs'|j|tjtj|tS(N(R)ttimet localtimeRRDtST_MTIME(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytmtimes cCsF|j|tj|t}tjtj|t}||fS(N(R)RRDRERGRHRI(RRRFRJ((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRDs cCsK|j|}tj|t}tjtj|t}|||fS(N(RBRRDRERGRHRI(RRRBRFRJ((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytinfoscCs|dkr|j}ng}x[|D]S}y|j|||fWq(tjtfk rz|j|dfq(Xq(W|S(N(tNoneR9RRR%R (RtfunctionR8tresR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_lists  cCs|j|j|S(N(RORB(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytsumlistscCs|j|j|S(N(RORD(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytstatlistscCs|j|j|S(N(RORJ(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt mtimelistscCs|j|j|S(N(RORF(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytsizelistscCs|j|j|S(N(RORK(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytinfolistscCsg|dkr|j}ni}x?|D]7}y|||||j|jd}nd}td|f}|jdS(NiiiR\(tstringtsystargvtatoiRkt _serverloop(RuRvtporttproxy((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyttest!s   t__main__((t__doc__RlRsR=RR RDRGRR7tpardirRRRmRkRtRrR|Ri(((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyts          PKH1]HxT3T3 cvslib.pycnu[ ^c@sdZddlZddlZddlZddlZddlZeeds]de_ndddYZdddYZ d d Z d Z d Z iZ d ZdZdZdZedkrendS(s!Utilities for CVS administration.iNttimezoneitFilecBs\eZdZd dZdZdZdZd dZdZ dZ dZ RS( sRepresent 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 cCsK|rd|krtdn||_d|_|_|_d|_dS(Nt/sno slash allowed in filei(t ValueErrortfiletlseenteseentrseentNonetproxy(tselfR((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt__init__9s   cCst|j|jS(N(tcmpR(R tother((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt__cmp__@scCsy&tj|jd\|_|_Wn+tjk rSd|_|_|_n(Xtj t |jj j |_d|_ dS(Nii(toststatRtlmtimetlctimeterrorRtlsumtmd5tnewtopentreadtdigestR(R ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytgetlocalCs &'cCs)tj|d}|jr:|d|jkr:tdn|d|_|d|_d|_d|_d|_|_ |jd dkrd|_|jd|_n|jdkrd|_d|_n0|d}t |d |_t |d |_ |d |_ |j r|j nd|_dS( NRisfile name mismatchiit-t0iiii(tstringt splitfieldsRRterevtedeletedtenewRtectimetemtimetunctimetextraRtgetesumR(R tlinetwordstdates((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytgetentryLs*            cCs|r||_ny|jj|j|_Wn#tjtfk rSd|_nX|jrx|jj|j|_ n d|_ |j r|j nd|_ dS(Ni( R theadRtrrevRRtIOErrorRtsumtrsumRR&R(R R ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt getremoteds      cCsa|j|jkr!|j|_n<|jrT|j|jf}|jj||_n d|_dS(N(RR,R/tesumRR R.R(R tname((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR&ss  cCs|js dS|jpd}|jr2d|}n|jrKd|j}n t|jdt|j}d|j|||jfS(sReturn 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 "". tRRsInitial t s/%s/%s/%s/%s/ ( RRR R!RtgmctimeR"R#R%(R trevR)((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytputentry|s    cCsddGHt|d}|d|jrU|dt|dt|dtn|jr|d|d |d |d t|d tn|jr|d |dt|jr|dtqndS(NRi2cSsDy|t||}Wntk r2d}nXd|G|GHdS(Nt?s%-15s:(tgetattrtAttributeError(tkeytreprR tvalue((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytrs   RRRRRR!R R"R#R,R/R1(R<RthexifyR5RR(R R>((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytreports$              N( t__name__t __module__t__doc__RR RRR*R0R&R7R@(((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR s+     tCVScBseZdZeZddddddddgZd Zd Zd Zd Z d Z ddZ dZ dZdZdZdZddZdZdZRS(sRepresent 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 s.*s@*s,*s*~s*.os*.as*.sos*.pyccCsi|_d|_dS(N(tentriesRR (R ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR s cCsC||jkrdS||_x |jjD]}d|_q,WdS(Ni(R REtvaluesR(R R te((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytsetproxys  cCsli|_|jd}xC|j}|s1Pn|j}|j|||j|jcCs>tjjd|}d|kr1|j|nt||S(NRDR>(RRcRdtbackupR(R Rtmode((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRJs cCs[tjj|rW|d}ytj|Wntjk rCnXtj||ndS(Nt~(RRctisfiletunlinkRtrename(R Rtbfile((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRgs cCsDtjj|rtSx'|jD]}tj||r tSq WtS(N(RRctisdirtTruet IgnoreListtfnmatchtFalse(R Rtpat((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRV#s N(RARBRCRRLRpR RHRORRR\RR_R@RSRFRbRfRJRgRV(((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyRDs"           s%02xicCs'|dkrdStttt|S(sDReturn a hex representation of a 16-byte string (e.g. an MD5 digest)RN(Rt hexify_formatttupleR`tord(R.((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR?-s cCsd|dkrdSd}xGtdt|dD]-}|ttj|||d!d}q/W|S(s*Return the original from a hexified stringRR3iiiN(RtrangetlentchrRtatoi(thexsumR.ti((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pytunhexify3s  +c Cs|dkrdStsndddddddd d d d d g }d}x%|D]}|d}|t|s    + cCs&|dkrdStjtj|S(NR(RRtasctimetgmtime(tt((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyR5Os cCsttj}tj|}tj|}dG|G|GHdGtjGHdGtj|GHt|}dG|GHtj|}dG|GHtj|GHdS(NtGMTRtlocals unctime()s->(tintRRRRtctimeR$(tnowRtattutgu((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyt test_unctimeSs     cCsPt}|j|jddl}|j}|j||jdS(Ni(RDROR\t rcsclientt openrcsclientR_R@(txRR ((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyttest`s      t__main__(((RCRRRRRqthasattrRRRDRtR?R}RR$R5RRRA(((s)/usr/lib64/python2.7/Demo/pdist/cvslib.pyts&      ~      PKH1]F"rrcs.pycnu[ Afc@sdZddlZddlZddlZddlZddlZddlZddlmZdZ dZ dZ dZ dZ d Zd Zd Zd Zd ZddZdZdZi de fd6de fd6de fd6de fd6defd6defd6defd6de fd6de fd6defd6defd6Zedkre ndS( s$Remote RCS -- command line interfaceiN(t openrcsclientc Csntjt_ytjtjdd\}}|s=d}n|d|d}}tj|sptjdnt|\}}tj||\}}WnZtjk r}|GHdGHdGHdGHd GHd GHd GHd GHd GHdGHdGHtjdnXt |}|s|j }nxP|D]H} y|||| Wqt t jfk re}d| |fGHqXqWdS(Nis h:p:d:qvLtheadisunknown commands2usage: rrcs [options] command [options] [file] ...swhere command can be:s+ ci|put # checkin the given filess co|get # checkouts% info # print header infos1 head # print revision of head branchs* list # list filename if valids" log # print full logs/ diff # diff rcs file and work files7if no files are given, all remote rcs files are assumedis%s: %s( tsyststderrtstdouttgetopttargvtcommandsthas_keyterrortexitRt listfilestIOErrortos( toptstresttcmdtcoptsettfunctcoptstfilestmsgtxtfn((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytmain s>    cCst|}|j}|j|j| }| r[t||||r[d|GHdSdG|GdGHt|}|j|||}|r|GHndS(Ns %s: unchanged since last checkins Checking ins...(topentreadtclosetisvalidtsamet asklogmessagetput(RRRtftdatatnewtmessagetmessages((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytcheckin/s      cCs9|j|}t|d}|j||jdS(Ntw(tgetRtwriteR(RRRR!R ((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytcheckout=s cCs|j|dS(N(tlock(RRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR*CscCs|j|dS(N(tunlock(RRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR+FscCsT|j|}|j}|jx|D]}|dG||GHq,WddGHdS(Nt:t=iF(tinfotkeystsort(RRRtdictR/tkey((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR.Is    cCs|j|}|G|GHdS(N(R(RRRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyRQscCs|j|r|GHndS(N(R(RRR((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytlistUscCsTd}x&|D]\}}|d||}q W|d}|j||}|GHdS(Ntt i(tlog(RRRtflagstotaR$((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyR6Ys  c Cst|||rdSd}x&|D]\}}|d||}q#W|d}|j|}tj}|j||jd||j||fGHtjd||j |f}|rddGHndS(NR4R5isdiff %s -r%s %ss diff %s %s %sR-iF( RR'ttempfiletNamedTemporaryFileR(tflushRR tsystemtname( RRRR7R8R9R!ttftsts((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytdiffas    cCs_|dkr1t|}|j}|jntj|j}|j|}||kS(N(tNoneRRRtmd5R"tdigesttsum(RRRR!R tlsumtrsum((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyRqs    cCs|r dGndGdGH|r$dGHnd}xQtjjdtjjtjj}| sl|dkrpPn||}q-W|S(Nsenter description,senter log message,s)terminate with single '.' or end of file:s"NOTE: This is NOT the log message!R4s>> s. (RRR(R<tstdintreadline(R"R#tline((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pyRzs cCs,ytj|Wntjk r'nXdS(N(R tunlinkR (R((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytremovesR4tciRtcoR'R.RR3R*R+sbhLRtd:l:r:s:w:V:R6tcRAt__main__(t__doc__RR RtstringRCR:t rcsclientRRR%R)R*R+R.RR3R6RARBRRRLRt__name__(((s'/usr/lib64/python2.7/Demo/pdist/rrcs.pytsD       "                      PKH1]C sumtree.pyonu[ ^c@s5ddlZddlZdZdZedS(iNcCsStj}tj}t||jtj}||GdGHtddS(Ntsecondss[Return to exit] (ttimetFSProxyt FSProxyLocaltsumtreet_closet raw_input(tt1tproxytt2((s*/usr/lib64/python2.7/Demo/pdist/sumtree.pytmains      cCsjdG|jGH|j}|j||j}x/|D]'}|j|t||jq;WdS(NsPWD =(tpwdt listfilestinfolistt listsubdirstcdRtback(Rtfilestsubdirstname((s*/usr/lib64/python2.7/Demo/pdist/sumtree.pyRs      (RRR R(((s*/usr/lib64/python2.7/Demo/pdist/sumtree.pyts   PKH1]P]rcsbumpnuȯ#! /usr/bin/python2.7 # -*- python -*- # # guido's version, from rcsbump,v 1.2 1995/06/22 21:27:27 bwarsaw Exp # # Python script for bumping up an RCS major revision number. import sys import re import rcslib import string WITHLOCK = 1 majorrev_re = re.compile('^[0-9]+') dir = rcslib.RCS() if sys.argv[1:]: files = sys.argv[1:] else: files = dir.listfiles() for file in files: # get the major revnumber of the file headbranch = dir.info(file)['head'] majorrev_re.match(headbranch) majorrev = string.atoi(majorrev_re.group(0)) + 1 if not dir.islocked(file): dir.checkout(file, WITHLOCK) msg = "Bumping major revision number (to %d)" % majorrev dir.checkin((file, "%s.0" % majorrev), msg, "-f") PKH1] >L5L5rcvs.pynuȯ#! /usr/bin/python2.7 """Remote CVS -- command line interface""" # XXX To do: # # Bugs: # - if the remote file is deleted, "rcvs update" will fail # # Functionality: # - cvs rm # - descend into directories (alraedy done for update) # - conflict resolution # - other relevant commands? # - branches # # - Finesses: # - retain file mode's x bits # - complain when "nothing known about filename" # - edit log message the way CVS lets you edit it # - cvs diff -rREVA -rREVB # - send mail the way CVS sends it # # Performance: # - cache remote checksums (for every revision ever seen!) # - translate symbolic revisions to numeric revisions # # Reliability: # - remote locking # # Security: # - Authenticated RPC? from cvslib import CVS, File import md5 import os import string import sys from cmdfw import CommandFrameWork 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 = '' SENDMAIL = "/usr/lib/sendmail -t" MAILFORM = """To: %s Subject: CVS changes: %s ...Message from rcvs... Committed files: %s Log message: %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 class rcvs(CommandFrameWork): 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:' def remove(fn): try: os.unlink(fn) except os.error: pass def main(): r = rcvs() try: r.run() finally: r.close() if __name__ == "__main__": main() PKH1]e'ww cmdfw.pycnu[ ^c@s<dZdddYZdZedkr8endS(sHFramework for command line interfaces like CVS. See class CmdFrameWork.tCommandFrameWorkcBs\eZdZdZd ZdZdZd dZdZ dZ d dZ dZ RS( sFramework 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:]. s;usage: (name)s [flags] subcommand [subflags] [argument] ...tcCsdS(s&Constructor, present for completeness.N((tself((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pyt__init__#sc Csddl}ddl}|dkr4|jd}ny|j||j\}}Wn |jk ru}|j|SX|j||s|j|j S|d}d|}d|}yt ||} Wn"t k r|jd|fSXyt ||} Wnt k rd} nXy |j|d| \}}Wn.|jk rp}|jd |t |SX|j| ||SdS( s3Process flags, subcommand and options, then run it.iNiitdo_tflags_scommand %r unknownRssubcommand %s: ( tgetopttsystNonetargvt GlobalFlagsterrortusagetoptionstreadytdefaulttgetattrtAttributeErrortstr( RtargsRRtoptstmsgtcmdtmnametfnametmethodtflags((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pytrun's:            cCsR|rNddGHdGHx+|D]#\}}dG|GdGt|GHqWddGHndS(sWProcess the options retrieved by getopt. Override this if you have any options.t-i(sOptions:toptiontvalueN(trepr(RRtota((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pyR Gs  cCsdS(s*Called just before calling the subcommand.N((R((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pyRQscCs%|r|GHn|ji|jjd6GHi}|j}xxut|D]g}|d dkrF|j|rqqFnyt||j}Wn d}nX|r|||su  PKH1]roQ8Q8rcvs.pycnu[ Afc@sdZddlmZmZddlZddlZddlZddlZddlm Z dZ defdYZ dZ d Z d efd YZd e fd YZdZdZedkrendS(s$Remote CVS -- command line interfacei(tCVStFileN(tCommandFrameWorkitMyFilecBskeZdZdZddZgdZdZddZdZdZ d Z d Z RS( cCsl|js|jn|js,|jn|js||jsR|jsKdSdSqh|js_dS|j|jkrudSdSn|js|jr|jrdSdSqh|jrdG|jGd GHd SdSn|js|j rd Sd Sn|j r |j|jkrd SdSn|j|j kr8|j |jkr1dSd Sn0|j |jkrNdS|j|jkrdd SdSdS(sReturn 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 :-) t0tNt?tctCtRtrswarning:swas losttUtAtDtut=tMN( tlseentgetlocaltrseent getremoteteseentlsumtrsumtedeletedtfiletenewtesum(tself((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytaction0sT               cCs |j}|dkrdS|G|jGH|dkrA|jn|dkr\d|jGHn|dkrt|jd|_n|dkrd|_nm|dkrd |_|j|_d|_d|_|j |_ t j |jd \|_ |_d |_ndS(NRR RRs+%s: conflict resolution not yet implementedR iR RRiit(R R(RR(RRtgettremoveRtrrevterevRRRRtoststattemtimetectimetextra(Rtcode((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytupdateys,                  "RcCsc|j}|dkr)|j|dS|dkrDd|jGHn|dkr_d|jGHndS( NR RiR s*%s: committing removes not yet implementedRs+%s: conflict resolution not yet implemented(R R(RtputR(RtmessageR(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytcommits      c CsE|jd}|j}x;|D]3\}}|dkrA|}q |d||}q W||jkr||j|jkr|dS|d}|j}|jj||f}tj|j }|j|krdSddl } | j } | j || j d|||fGHtjd|| j|f} | rAdd GHndS( NRs-rt iisdiff %s -r%s %ss diff %s %s %sRiF(RR!RRRtproxyRtmd5tnewtdigestttempfiletNamedTemporaryFiletwritetflushR#tsystemtname( RtoptstflagstrevtotatfntdatatsumR2ttftsts((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdiffs.    !      cCs|jdkS(NR(R(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt commitcheckscCsdG|jGdGHt|jj}|jsD|jj|jn|jj|j||}|rm|GHn|j|jj|j|j dS(Ns Checking ins...( RtopentreadRR.tlockR*tsetentrytheadR(RR+R>tmessages((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR*s cCsX|jj|j}t|jd}|j||j|j|j|jdS(Ntw( R.RRRDR4tcloseRGR!R(RR>tf((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRs   cCs|jj|j|GHdS(N(R.tlogR(Rt otherflags((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRMscCsXd|_|j|_d\|_|_d|_d|_d|_d|_d|_dS(NiRi(ii( RRRR%R&R"RRR'(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytadds      cCsed|_||_tj|jd\|_|_||_d|_d|_ d|_d|_ dS(NiiiR( RRR#R$RR%R&R"RRR'(RR"R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRGs  "    ( t__name__t __module__RR)R,RBRCR*RRMRORG(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR.s I      s/usr/lib/sendmail -tsoTo: %s Subject: CVS changes: %s ...Message from rcvs... Committed files: %s Log message: %s tRCVScBsqeZeZdZdZddZddZdZdZ dZ dZ d Z d d Z RS( cCstj|dS(N(Rt__init__(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRSscCs+x$|j|dD]}|jqWdS(Ni(t whichentriesR)(Rtfileste((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR)sRcCs|j|}|sdSd}x#|D]}|js&d}q&q&W|sTdGHdS|sitd}ng}x0|D](}|j|rv|j|jqvqvW|j||dS(Niiscorrect above errors firsts One-liner: (RTRCt raw_inputR,tappendRtmailinfo(RRUR+tlisttokRVt committed((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR,s"    cCsd}t|tj|tj||f}ddGH|GHddGHtd|}tjtj|d krtjtd}|j ||j }|rd t |GHqd GHnd GHdS( Nssjoerd@cwi.nl, jack@cwi.nlt-iFsOK to mail to %s? tytyetyesRJsSendmail exit status %ss Mail sent.s No mail sent.(R^R_R`( tMAILFORMtstringtjoinRWtlowertstripR#tpopentSENDMAILR4RKtstr(RRUR+ttowhomtmailtextR[tpRA((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRYs    cCs(x!|j|D]}|jqWdS(N(RTtreport(RRURV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRl!scCs+x$|j|D]}|j|qWdS(N(RTRB(RRUR8RV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRB%scCsC|stdng}x$|j|dD]}|jq+WdS(Ns!'cvs add' needs at least one filei(t RuntimeErrorRTRO(RRURZRV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRO)s  cCs|stdntddS(Ns 'cvs rm' needs at least one files'cvs rm' not yet imlemented(Rm(RRU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytrm0s cCsZd}x&|D]\}}|d||}q Wx$|j|D]}|j|q?WdS(NRR-(RTRM(RRUR8R9R;R<RV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRM5s icCs|rkg}xE|D]Q}|jj|r;|j|}n|j|}||j|<|j|qWn|jj}xX|jjD]G}|jj|rqn|j|}||j|<|j|qW|rJxltjtj D]U}|jj| r|j | r|j|}||j|<|j|qqWn|j |jrx/|D]$}|jdkrd|j|_qdqdWn|S(N( tentriesthas_keyt FileClassRXtvaluesR.t listfilesR#tlistdirtcurdirtignoredtsorttNone(RRUt localfilestooRZRRV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRT<s8       (RPRQRRqRSR)R,RYRlRBRORnRMRT(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRRs         trcvscBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z e Ze Zd Zd ZeZeZdZdZeZeZdZdZeZdZdZRS(s d:h:p:qvLsMusage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]s<If no subcommand is given, the status of all files is listedcCs&tj|d|_t|_dS(s Constructor.N(RRSRxR.RRtcvs(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRSes  cCs&|jr|jjnd|_dS(N(R.t_closeRx(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRKks cCs|jtjtj}x|D]}|tjks#|tjkrMq#n|dkr_q#ntjj|swq#ntjj|rq#ndG|GdGHtj|z3tjjdr|j j n |j WdtjtjdG|GdGHXq#WdS(NRs--- entering subdirectorys---s--- left subdirectory( RKR#RtRutpardirtpathtisdirtislinktchdirt __class__truntrecurse(RtnamesR7((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRps&     cCs ||_dS(N(R8(RR8((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytoptionsscCsEddl}|j|j|_|jj|j|jjdS(Ni(t rcsclientt openrcsclientR8R.R{tsetproxyt getentries(RR((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytreadys cCs|jjgdS(N(R{Rl(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdefaultscCs|jj|dS(N(R{Rl(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_reportscCst}x>|D]6\}}|dkr.d}n|dkr d}q q W|jj||jj| r| r|jndS(supdate [-l] [-R] [file] ...s-lis-RiN(t DEF_LOCALR{R)t putentriesR(RR8RUtlocalR;R<((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_updates   s-lRcCsVd}x)|D]!\}}|dkr |}q q W|jj|||jjdS(scommit [-m message] [file] ...Rs-mN(R{R,R(RR8RUR+R;R<((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_commits  sm:cCs|jj||dS(sdiff [difflags] [file] ...N(R{RB(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdo_diffsscbitwcefhnlr:sD:S:cCs0|sdGHdS|jj||jjdS(s add file ...s%'rcvs add' requires at least one fileN(R{ROR(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdo_adds cCs0|sdGHdS|jj||jjdS(sremove file ...s('rcvs remove' requires at least one fileN(R{R R(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_removes cCs|jj||dS(slog [rlog-options] [file] ...N(R{RM(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdo_logssbhLNRtd:s:V:r:(RPRQt GlobalFlagst UsageMessagetPostUsageMessageRSRKRRRRRRt flags_updatetdo_uptflags_upRt flags_committdo_comt flags_comRt flags_difftdo_dift flags_difRRtdo_rmRt flags_log(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRz]s6             cCs,ytj|Wntjk r'nXdS(N(R#tunlinkterror(R=((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR scCs)t}z|jWd|jXdS(N(RzRRK(R ((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytmains t__main__(t__doc__tcvslibRRR/R#RbtsystcmdfwRRRRgRaRRRzR RRP(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyts       lp   PKH1]e'ww cmdfw.pyonu[ ^c@s<dZdddYZdZedkr8endS(sHFramework for command line interfaces like CVS. See class CmdFrameWork.tCommandFrameWorkcBs\eZdZdZd ZdZdZd dZdZ dZ d dZ dZ RS( sFramework 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:]. s;usage: (name)s [flags] subcommand [subflags] [argument] ...tcCsdS(s&Constructor, present for completeness.N((tself((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pyt__init__#sc Csddl}ddl}|dkr4|jd}ny|j||j\}}Wn |jk ru}|j|SX|j||s|j|j S|d}d|}d|}yt ||} Wn"t k r|jd|fSXyt ||} Wnt k rd} nXy |j|d| \}}Wn.|jk rp}|jd |t |SX|j| ||SdS( s3Process flags, subcommand and options, then run it.iNiitdo_tflags_scommand %r unknownRssubcommand %s: ( tgetopttsystNonetargvt GlobalFlagsterrortusagetoptionstreadytdefaulttgetattrtAttributeErrortstr( RtargsRRtoptstmsgtcmdtmnametfnametmethodtflags((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pytrun's:            cCsR|rNddGHdGHx+|D]#\}}dG|GdGt|GHqWddGHndS(sWProcess the options retrieved by getopt. Override this if you have any options.t-i(sOptions:toptiontvalueN(trepr(RRtota((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pyR Gs  cCsdS(s*Called just before calling the subcommand.N((R((s(/usr/lib64/python2.7/Demo/pdist/cmdfw.pyRQscCs%|r|GHn|ji|jjd6GHi}|j}xxut|D]g}|d dkrF|j|rqqFnyt||j}Wn d}nX|r|||su  PKH1]#)-- rcslib.pyonu[ ^c@sYdZddlZddlZddlZddlZddlZdddYZdS(sRCS interface module. Defines the class RCS, which represents a directory with rcs version files and (possibly) corresponding work files. iNtRCScBseZdZejejdZdZdZddZ dZ dZ dZ d Z d dd Zddd Zdd ZdZdZdZdZdZdddZdZdZdZddZdZdZRS(s7RCS interface class (local filesystem version). An instance of this class represents a directory with rcs version files and (possible) corresponding work files. Methods provide access to most rcs operations such as checkin/checkout, access to the rcs metadata (revisions, logs, branches etc.) as well as some filesystem operations such as listing all rcs version files. XXX BUGS / PROBLEMS - The instance always represents the current directory so it's not very useful to have more than one instance around simultaneously s-_=+cCsdS(s Constructor.N((tself((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyt__init__&scCsdS(s Destructor.N((R((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyt__del__*stcCsi|j|d|}|j}|j|}|rH|d|}n|ddkre|d }n|S(smReturn the full log text for NAME_REV as a string. Optional OTHERFLAGS are passed to rlog. srlog s%s: %sis (t_opentreadt _closepipe(Rtname_revt otherflagstftdatatstatus((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pytlog0s  cCs|j|}|dS(s%Return the head revision for NAME_REVthead(tinfo(RRtdict((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR?sc Cs|j|d}i}x}|j}|s1Pn|ddkrGqntj|d}|dkr|| tj||d}}|||" if None); or the file description if this is a new file. The optional OTHERFLAGS argument is passed to ci without interpretation. Any output from ci goes to directly to stdout. sis s-usci %s%s -t%s %s %ss([\"$`])s\\\1sci %s%s -m"%s" %s %s( t _unmangletisvalidttempfiletNamedTemporaryFiletwritetflushRtretsubR( RRtmessageR RRtnewR#R R((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pytcheckins"      cCstjtj}t|j|}tjjdrdtjd}t|j|}||}nt|j|}|j ||S(s=Return a list of all version files matching optional PATTERN.R( tostlistdirtcurdirtfiltert_isrcstpathtisdirtmaptrealnamet_filter(Rtpattfilestfiles2((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyt listfiless cCs@|j|}tjj|p?tjjtjjd|S(s0Test whether NAME has a version file associated.R(trcsnameR0R5tisfiletjoin(RRtnamev((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR&scCs|j|r|}n |d}tjj|r8|Stjjdtjj|}tjj|ro|Stjjdrtjjd|S|SdS(sReturn the pathname of the version file for NAME. The argument can be a work file name or a version file name. If the version file does not exist, the name of the version file that would be created by "ci" is returned. s,vRN(R4R0R5R?R@tbasenameR6(RRRA((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR>s  !cCsN|j|r|d }n|}tjj|r8|Stjj|}|S(sReturn the pathname of the work file for NAME. The argument can be a work file name or a version file name. If the work file does not exist, the name of the work file that would be created by "co" is returned. i(R4R0R5R?RB(RRAR((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR8s cCs|j|d}|j}|j|}|r?t|n|sIdS|ddkrf|d }n|j||j|kS(sTest whether FILE (which must have a version file) is locked. XXX This does not tell you which revision number is locked and ignores any revision you may pass in (by virtue of using rlog -L -R). s rlog -L -Ris N(RRRRtNoneR8(RRR RR ((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pytislockeds   cCsD|j|\}}|j|s:tjd|fn||fS(s}Normalize NAME_REV into a (NAME, REV) tuple. Raise an exception if there is no corresponding version file. snot an rcs file %r(R%R&R0terror(RRRR((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRssco -ps-rcCsV|j|\}}|j|}|r?|d||}ntjd||fS(sINTERNAL: open a read pipe to NAME_REV using optional COMMAND. Optional FLAG is used to indicate the revision (default -r). Default COMMAND is "co -p". Return a file object connected by a pipe to the command's output. t s%s %r(RR>R0tpopen(RRRtrflagRRRA((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRs cCsmt|tdkr1|df}\}}n |\}}x)|D]!}||jkrDtdqDqDW|S(sINTERNAL: Normalize NAME_REV argument to (NAME, REV) tuple. Raise an exception if NAME contains invalid characters. A NAME_REV argument is either NAME string (implying REV='') or a tuple of the form (NAME, REV). Rsbad char in rev(ttypetokcharst ValueError(RRRRtc((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyR%s   cCs|j}|sd St|d\}}|dkrAd|fS|d@}|dkrfd}|}nd}|d@r|d}n||fS( s:INTERNAL: Close PIPE and print its exit status if nonzero.iitexititstoppedtkilledis (coredump)N(tcloseRCtdivmod(RR tststdetailtreasontsignaltcode((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRs       cCs3|d}tj|}|r/td|ndS(s{INTERNAL: run COMMAND in a subshell. Standard input for the command is taken from /dev/null. Raise IOError when the exit status is not zero. Return whatever the calling method should return; normally None. A derived class may override this method and redefine it to capture stdout/stderr of the command and return it. s R8RDRRR%RRR9R]R4(((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyRs0       !          ((R`RXR0R+RR'R(((s)/usr/lib64/python2.7/Demo/pdist/rcslib.pyts      PKH1]'' cvslib.pynu["""Utilities for CVS administration.""" import string import os import time import md5 import fnmatch if not hasattr(time, 'timezone'): 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) 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 # 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)) 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 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)) def gmctime(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) def test(): x = CVS() x.getentries() x.getlocalfiles() ## x.report() import rcsclient proxy = rcsclient.openrcsclient() x.getremotefiles(proxy) x.report() if __name__ == "__main__": test() PKH1]roQ8Q8rcvs.pyonu[ Afc@sdZddlmZmZddlZddlZddlZddlZddlm Z dZ defdYZ dZ d Z d efd YZd e fd YZdZdZedkrendS(s$Remote CVS -- command line interfacei(tCVStFileN(tCommandFrameWorkitMyFilecBskeZdZdZddZgdZdZddZdZdZ d Z d Z RS( cCsl|js|jn|js,|jn|js||jsR|jsKdSdSqh|js_dS|j|jkrudSdSn|js|jr|jrdSdSqh|jrdG|jGd GHd SdSn|js|j rd Sd Sn|j r |j|jkrd SdSn|j|j kr8|j |jkr1dSd Sn0|j |jkrNdS|j|jkrdd SdSdS(sReturn 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 :-) t0tNt?tctCtRtrswarning:swas losttUtAtDtut=tMN( tlseentgetlocaltrseent getremoteteseentlsumtrsumtedeletedtfiletenewtesum(tself((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytaction0sT               cCs |j}|dkrdS|G|jGH|dkrA|jn|dkr\d|jGHn|dkrt|jd|_n|dkrd|_nm|dkrd |_|j|_d|_d|_|j |_ t j |jd \|_ |_d |_ndS(NRR RRs+%s: conflict resolution not yet implementedR iR RRiit(R R(RR(RRtgettremoveRtrrevterevRRRRtoststattemtimetectimetextra(Rtcode((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytupdateys,                  "RcCsc|j}|dkr)|j|dS|dkrDd|jGHn|dkr_d|jGHndS( NR RiR s*%s: committing removes not yet implementedRs+%s: conflict resolution not yet implemented(R R(RtputR(RtmessageR(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytcommits      c CsE|jd}|j}x;|D]3\}}|dkrA|}q |d||}q W||jkr||j|jkr|dS|d}|j}|jj||f}tj|j }|j|krdSddl } | j } | j || j d|||fGHtjd|| j|f} | rAdd GHndS( NRs-rt iisdiff %s -r%s %ss diff %s %s %sRiF(RR!RRRtproxyRtmd5tnewtdigestttempfiletNamedTemporaryFiletwritetflushR#tsystemtname( RtoptstflagstrevtotatfntdatatsumR2ttftsts((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdiffs.    !      cCs|jdkS(NR(R(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt commitcheckscCsdG|jGdGHt|jj}|jsD|jj|jn|jj|j||}|rm|GHn|j|jj|j|j dS(Ns Checking ins...( RtopentreadRR.tlockR*tsetentrytheadR(RR+R>tmessages((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR*s cCsX|jj|j}t|jd}|j||j|j|j|jdS(Ntw( R.RRRDR4tcloseRGR!R(RR>tf((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRs   cCs|jj|j|GHdS(N(R.tlogR(Rt otherflags((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRMscCsXd|_|j|_d\|_|_d|_d|_d|_d|_d|_dS(NiRi(ii( RRRR%R&R"RRR'(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytadds      cCsed|_||_tj|jd\|_|_||_d|_d|_ d|_d|_ dS(NiiiR( RRR#R$RR%R&R"RRR'(RR"R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRGs  "    ( t__name__t __module__RR)R,RBRCR*RRMRORG(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR.s I      s/usr/lib/sendmail -tsoTo: %s Subject: CVS changes: %s ...Message from rcvs... Committed files: %s Log message: %s tRCVScBsqeZeZdZdZddZddZdZdZ dZ dZ d Z d d Z RS( cCstj|dS(N(Rt__init__(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRSscCs+x$|j|dD]}|jqWdS(Ni(t whichentriesR)(Rtfileste((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR)sRcCs|j|}|sdSd}x#|D]}|js&d}q&q&W|sTdGHdS|sitd}ng}x0|D](}|j|rv|j|jqvqvW|j||dS(Niiscorrect above errors firsts One-liner: (RTRCt raw_inputR,tappendRtmailinfo(RRUR+tlisttokRVt committed((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR,s"    cCsd}t|tj|tj||f}ddGH|GHddGHtd|}tjtj|d krtjtd}|j ||j }|rd t |GHqd GHnd GHdS( Nssjoerd@cwi.nl, jack@cwi.nlt-iFsOK to mail to %s? tytyetyesRJsSendmail exit status %ss Mail sent.s No mail sent.(R^R_R`( tMAILFORMtstringtjoinRWtlowertstripR#tpopentSENDMAILR4RKtstr(RRUR+ttowhomtmailtextR[tpRA((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRYs    cCs(x!|j|D]}|jqWdS(N(RTtreport(RRURV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRl!scCs+x$|j|D]}|j|qWdS(N(RTRB(RRUR8RV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRB%scCsC|stdng}x$|j|dD]}|jq+WdS(Ns!'cvs add' needs at least one filei(t RuntimeErrorRTRO(RRURZRV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRO)s  cCs|stdntddS(Ns 'cvs rm' needs at least one files'cvs rm' not yet imlemented(Rm(RRU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytrm0s cCsZd}x&|D]\}}|d||}q Wx$|j|D]}|j|q?WdS(NRR-(RTRM(RRUR8R9R;R<RV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRM5s icCs|rkg}xE|D]Q}|jj|r;|j|}n|j|}||j|<|j|qWn|jj}xX|jjD]G}|jj|rqn|j|}||j|<|j|qW|rJxltjtj D]U}|jj| r|j | r|j|}||j|<|j|qqWn|j |jrx/|D]$}|jdkrd|j|_qdqdWn|S(N( tentriesthas_keyt FileClassRXtvaluesR.t listfilesR#tlistdirtcurdirtignoredtsorttNone(RRUt localfilestooRZRRV((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRT<s8       (RPRQRRqRSR)R,RYRlRBRORnRMRT(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRRs         trcvscBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d Z e Ze Zd Zd ZeZeZdZdZeZeZdZdZeZdZdZRS(s d:h:p:qvLsMusage: rcvs [-d directory] [-h host] [-p port] [-q] [-v] [subcommand arg ...]s<If no subcommand is given, the status of all files is listedcCs&tj|d|_t|_dS(s Constructor.N(RRSRxR.RRtcvs(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRSes  cCs&|jr|jjnd|_dS(N(R.t_closeRx(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRKks cCs|jtjtj}x|D]}|tjks#|tjkrMq#n|dkr_q#ntjj|swq#ntjj|rq#ndG|GdGHtj|z3tjjdr|j j n |j WdtjtjdG|GdGHXq#WdS(NRs--- entering subdirectorys---s--- left subdirectory( RKR#RtRutpardirtpathtisdirtislinktchdirt __class__truntrecurse(RtnamesR7((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRps&     cCs ||_dS(N(R8(RR8((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytoptionsscCsEddl}|j|j|_|jj|j|jjdS(Ni(t rcsclientt openrcsclientR8R.R{tsetproxyt getentries(RR((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytreadys cCs|jjgdS(N(R{Rl(R((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdefaultscCs|jj|dS(N(R{Rl(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_reportscCst}x>|D]6\}}|dkr.d}n|dkr d}q q W|jj||jj| r| r|jndS(supdate [-l] [-R] [file] ...s-lis-RiN(t DEF_LOCALR{R)t putentriesR(RR8RUtlocalR;R<((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_updates   s-lRcCsVd}x)|D]!\}}|dkr |}q q W|jj|||jjdS(scommit [-m message] [file] ...Rs-mN(R{R,R(RR8RUR+R;R<((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_commits  sm:cCs|jj||dS(sdiff [difflags] [file] ...N(R{RB(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdo_diffsscbitwcefhnlr:sD:S:cCs0|sdGHdS|jj||jjdS(s add file ...s%'rcvs add' requires at least one fileN(R{ROR(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdo_adds cCs0|sdGHdS|jj||jjdS(sremove file ...s('rcvs remove' requires at least one fileN(R{R R(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyt do_removes cCs|jj||dS(slog [rlog-options] [file] ...N(R{RM(RR8RU((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytdo_logssbhLNRtd:s:V:r:(RPRQt GlobalFlagst UsageMessagetPostUsageMessageRSRKRRRRRRt flags_updatetdo_uptflags_upRt flags_committdo_comt flags_comRt flags_difftdo_dift flags_difRRtdo_rmRt flags_log(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyRz]s6             cCs,ytj|Wntjk r'nXdS(N(R#tunlinkterror(R=((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyR scCs)t}z|jWd|jXdS(N(RzRRK(R ((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pytmains t__main__(t__doc__tcvslibRRR/R#RbtsystcmdfwRRRRgRaRRRzR RRP(((s'/usr/lib64/python2.7/Demo/pdist/rcvs.pyts       lp   PKH1]5tVVmac.pyonu[ ^c@s8ddlZddlZddlZdZedS(iNcCsxzytd}Wntk r'PnXtj|}|sCqn|ddkrf|jddn|t_tjqWdS(Ns$ itrcvs( t raw_inputtEOFErrortstringtsplittinserttsystargvRtmain(tlinetwords((s&/usr/lib64/python2.7/Demo/pdist/mac.pyRs  (RRRR(((s&/usr/lib64/python2.7/Demo/pdist/mac.pyts    PKH1]G sumtree.pynu[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] ") 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() main() PKH1]Mi$11 FSProxy.pycnu[ ^c@sdZddlZddlZddlZddlZddlZddlTddlZddlZdZej ej fZ dd dYZ de ej fdYZd ejfd YZd Zed krendS(sFile System Proxy. Provide an OS-neutral view on a file system, locally or remotely. The functionality is geared towards implementing some sort of rdist-like utility between a Mac and a UNIX system. The module defines three classes: FSProxyLocal -- used for local access FSProxyServer -- used on the server side of remote access FSProxyClient -- used on the client side of remote access The remote classes are instantiated with an IP address and an optional verbosity flag. iN(t*it FSProxyLocalcBseZdZdZdZdZdZdZdZdZ dZ d Z d Z d+d Zd+d Zd+d Zd+dZdZdZdZdZdZdZdZdZdZdZd+dZd+dZd+dZd+dZd+dZ dZ!d+dZ"d+d Z#d+d!Z$d+d"Z%d+d#Z&d$d%d&Z'd'Z(d$d(Z)d)Z*d*Z+RS(,cCs#g|_dg|j|_dS(Ns*.pyc(t _dirstackt _readignoret_ignore(tself((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt__init__!s cCsx|jr|jqWdS(N(Rtback(R((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_close%s cCs|jd}yt|}WnEtk rf|jd}yt|}Wqgtk rbgSXnXg}xD|j}|sPn|ddkr|d }n|j|qpW|j|S(Ntignoressynctree.ignorefilesis (t_hidetopentIOErrortreadlinetappendtclose(RtfiletfR tline((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR)s&      cCs|ddkS(Nit.((Rtname((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_hidden<scCsd|S(Ns.%s((RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR ?scCst|tkrdS|ddkr*dS|tkr:dS|j|rMdStjj|\}}|sr| rvdStjj|rdSdt|dj dkrdSx'|j D]}t j ||rdSqWdS(Niit~strbii( tlent maxnamelent skipnamesRtostpathtsplittislinkR treadRtfnmatch(RRtheadttailtign((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytvisibleBs&  cCs,|j|s(tjdt|ndS(Nsprotected name %s(R$Rterrortrepr(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytcheckOscCs<|j|tjj|s8tjdt|ndS(Nsnot a plain file %s(R'RRtisfileR%R&(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt checkfileSs cCs tjS(N(Rtgetcwd(R((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytpwdXscCsY|j|tj|jf}tj||jj||j|j|_dS(N(R'RR*RtchdirRRR(RRtsave((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytcd[s   cCsO|jstjdn|jd\}}tj||jd=||_dS(Nsempty directory stacki(RRR%R,R(RtdirR ((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRbs    cCsD|r$|d}t||}nt|j|}|j|S(NcSstj||S(N(R (Rtpat((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytkeepls(tfilterR$tsort(RtfilesR0R1((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_filterjs   cCs"tjtj}|j||S(N(RtlistdirtcurdirR5(RR0R4((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytlistsscCs7tjtj}ttjj|}|j||S(N(RR6R7R2RR(R5(RR0R4((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt listfileswscCs7tjtj}ttjj|}|j||S(N(RR6R7R2RtisdirR5(RR0R4((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt listsubdirs|scCs|j|otjj|S(N(R$RRtexists(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR<scCs|j|otjj|S(N(R$RRR:(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR:scCs|j|otjj|S(N(R$RRR(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRscCs|j|otjj|S(N(R$RRR((RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyR(scCsb|j|d}t|}tj}x*|j|}|sGPn|j|q.W|jS(Niii (R)R tmd5tnewRtupdatetdigest(RRt BUFFERSIZERtsumtbuffer((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRBs   cCs|j|tj|tS(N(R)RtstattST_SIZE(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytsizes cCs'|j|tjtj|tS(N(R)ttimet localtimeRRDtST_MTIME(RR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytmtimes cCsF|j|tj|t}tjtj|t}||fS(N(R)RRDRERGRHRI(RRRFRJ((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyRDs cCsK|j|}tj|t}tjtj|t}|||fS(N(RBRRDRERGRHRI(RRRBRFRJ((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytinfoscCs|dkr|j}ng}x[|D]S}y|j|||fWq(tjtfk rz|j|dfq(Xq(W|S(N(tNoneR9RRR%R (RtfunctionR8tresR((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt_lists  cCs|j|j|S(N(RORB(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytsumlistscCs|j|j|S(N(RORD(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytstatlistscCs|j|j|S(N(RORJ(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyt mtimelistscCs|j|j|S(N(RORF(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytsizelistscCs|j|j|S(N(RORK(RR8((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pytinfolistscCsg|dkr|j}ni}x?|D]7}y|||||j|jd}nd}td|f}|jdS(NiiiR\(tstringtsystargvtatoiRkt _serverloop(RuRvtporttproxy((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyttest!s   t__main__((t__doc__RlRsR=RR RDRGRR7tpardirRRRmRkRtRrR|Ri(((s*/usr/lib64/python2.7/Demo/pdist/FSProxy.pyts          PKH1]@GF security.pycnu[ ^c@sdddYZdS(tSecuritycBs,eZdZdZdZdZRS(cCs ddl}|j}|jdr1|d}nd}|jdrb|jj|d|}n|jj|sddl}xE|jD]7}|jj||}|jj|r|}PqqWnytt|j |_ Wnt k rt d|nXdS(NitPYTHON_KEYFILEs.python_keyfiletHOMEspython keyfile %s: cannot open( tostenvironthas_keytpathtjointexiststsystevaltopentreadlinet_keytIOError(tselfRtenvtkeyfileR tdirtkf((s+/usr/lib64/python2.7/Demo/pdist/security.pyt__init__s$      cCsddl}|jddS(Niidi(trandomtrandint(RR((s+/usr/lib64/python2.7/Demo/pdist/security.pyt_generate_challenges cCs|j||kS(N(t_encode_challenge(Rt challengetresponse((s+/usr/lib64/python2.7/Demo/pdist/security.pyt_compare_challenge_responsescCs%|j\}}tt|||S(N(R tpowtlong(RRtptm((s+/usr/lib64/python2.7/Demo/pdist/security.pyRs(t__name__t __module__RRRR(((s+/usr/lib64/python2.7/Demo/pdist/security.pyRs   N((R(((s+/usr/lib64/python2.7/Demo/pdist/security.pyttPKH1]GT[DD security.pynu[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 _generate_challenge(self): import random return random.randint(100, 100000) 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) PKH1]" t server.pynu["""RPC Server module.""" import sys import socket import pickle from fnmatch import fnmatch from repr import repr # Default verbosity (0 = silent, 1 = print connections, 2 = print requests too) 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 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 PKH1]#44 rcsclient.pycnu[ ^c@skdZddlZddlZdZdZdZdZddlZdejfdYZ gd Z dS( sCustomize this file to change the default client etc. (In general, it is probably be better to make local operation the default and to require something like an RCSSERVER environment variable to enable remote operation.) iNs voorn.cwi.nliiitRCSProxyClientcBseZejdZRS(cCstjj|||dS(N(tclientt SecureClientt__init__(tselftaddresstverbose((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyRs(t__name__t __module__RtVERBOSER(((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyRsc Csddl}t}t}t}t}d}x|D]\}}|dkr|}d|krtj|d} || || d}} | rtj| }qqn|dkrtj|}n|dkr|}n|dkr|d}n|d krd }n|d kr1d}q1q1W|r?ddl}|j } n||f} t | |} |sy%t t j jd d j}Wntk rqX|ddkr|d }qn|r| j|n| S(sEopen an RCSProxy client based on a list of options returned by getoptiNs-ht:is-ps-ds-vs-qis-LtCVSt Repositorys (tRCSProxytHOSTtPORTR tLOCALtNonetstringtfindtatoit RCSProxyLocalRtopentostpathtjointreadlinetIOErrortcd( toptsR thosttportRtlocalt directorytotatitptxR((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyt openrcsclientsN              % ( t__doc__RRRRR RRRRR'(((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyts   PKH1]l   rcsclient.pynu["""Customize this file to change the default client etc. (In general, it is probably be better to make local operation the default and to require something like an RCSSERVER environment variable to enable remote operation.) """ import string import os # These defaults don't belong here -- they should be taken from the # environment or from a hidden file in the current directory HOST = 'voorn.cwi.nl' PORT = 4127 VERBOSE = 1 LOCAL = 0 import client class RCSProxyClient(client.SecureClient): 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 PKH1]#44 rcsclient.pyonu[ ^c@skdZddlZddlZdZdZdZdZddlZdejfdYZ gd Z dS( sCustomize this file to change the default client etc. (In general, it is probably be better to make local operation the default and to require something like an RCSSERVER environment variable to enable remote operation.) iNs voorn.cwi.nliiitRCSProxyClientcBseZejdZRS(cCstjj|||dS(N(tclientt SecureClientt__init__(tselftaddresstverbose((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyRs(t__name__t __module__RtVERBOSER(((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyRsc Csddl}t}t}t}t}d}x|D]\}}|dkr|}d|krtj|d} || || d}} | rtj| }qqn|dkrtj|}n|dkr|}n|dkr|d}n|d krd }n|d kr1d}q1q1W|r?ddl}|j } n||f} t | |} |sy%t t j jd d j}Wntk rqX|ddkr|d }qn|r| j|n| S(sEopen an RCSProxy client based on a list of options returned by getoptiNs-ht:is-ps-ds-vs-qis-LtCVSt Repositorys (tRCSProxytHOSTtPORTR tLOCALtNonetstringtfindtatoit RCSProxyLocalRtopentostpathtjointreadlinetIOErrortcd( toptsR thosttportRtlocalt directorytotatitptxR((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyt openrcsclientsN              % ( t__doc__RRRRR RRRRR'(((s,/usr/lib64/python2.7/Demo/pdist/rcsclient.pyts   PKH1])SS server.pyonu[ ^c@sdZddlZddlZddlZddlmZddlmZdZdd dYZddlm Z d ee fd YZ dS( sRPC Server module.iN(tfnmatch(trepritServercBseZdZedZdZdZdZdZdZ ddd d gZ d Z d Z d Z ddZRS(sDRPC Server class. Derive a class to implement a particular service.cCst|tdkr'd|f}n||_||_d|_tjtjtj|_|jj||jj dd|_ dS(Niti( ttypet_addresst_verbosetNonet_sockettsockettAF_INETt SOCK_STREAMtbindtlistent _listening(tselftaddresstverbose((s)/usr/lib64/python2.7/Demo/pdist/server.pyt__init__s   cCs ||_dS(N(R(RR((s)/usr/lib64/python2.7/Demo/pdist/server.pyt _setverbosescCs|jdS(N(t_close(R((s)/usr/lib64/python2.7/Demo/pdist/server.pyt__del__ scCs/d|_|jr"|jjnd|_dS(Ni(RRtcloseR(R((s)/usr/lib64/python2.7/Demo/pdist/server.pyR#s  cCsx|jr|jqWdS(N(Rt_serve(R((s)/usr/lib64/python2.7/Demo/pdist/server.pyt _serverloop)s cCs|jrdGHn|jj\}}|jrAdt|GHn|j||spdt|GH|jdS|jd}|jd}d}x=|r|j|jdkrdGHn|j||}qWdS(NsWait for connection ...sAccepted connection from %ss*** Connection from %s refusedtrtwisWait for next request ...( RRtacceptRt_verifyRtmakefiletflusht _dorequest(RtconnRtrftwftok((s)/usr/lib64/python2.7/Demo/pdist/server.pyR-s"     s 192.16.201.*s 192.16.197.*s 132.151.1.*s 129.6.64.*cCs7|\}}x$|jD]}t||rdSqWdS(Nii(t_validR(RR Rthosttporttpat((s)/usr/lib64/python2.7/Demo/pdist/server.pyR?s  c Csvtj|}y|j}Wntk r3dSX|jdkrUdt|GHny|\}}}d|krd|j|||f}nM|ddkrtdt|n't ||} dt | ||f}Wnt j t j |f}nX|dkr5|d d kr5|jdkr1dGHndS|jdkrVd t|GHntj|} | j|dS( NiisGot request: %st.t_sillegal method name %sisSuppress replysSend reply: %s(NN(tpicklet UnpicklertloadtEOFErrorRRRt_specialt NameErrortgetattrtapplytsystexc_typet exc_valuetPicklertdump( RR!R"trptrequestt methodnametargstidtreplytmethodtwp((s)/usr/lib64/python2.7/Demo/pdist/server.pyREs4   cCsQ|dkr:t|ds3t|j|_n|jStdt|dS(Ns.methodst_methodss#unrecognized special method name %s(thasattrttuplet _listmethodsR?R/R(RR9R:((s)/usr/lib64/python2.7/Demo/pdist/server.pyR._s  cCs|s|j}n|jj}td|}|jxE|jD]:}|j|}t|d|}||t|)qGW|S(NcSs|ddkS(NiR)((tx((s)/usr/lib64/python2.7/Demo/pdist/server.pytiRcSs ||kS(N((RCtnames((s)/usr/lib64/python2.7/Demo/pdist/server.pyRDmR(t __class__t__dict__tkeystfiltertsortt __bases__RBtlen(RtclREtbaset basenames((s)/usr/lib64/python2.7/Demo/pdist/server.pyRBfs  N(t__name__t __module__t__doc__tVERBOSERRRRRRR$RRR.RRB(((s)/usr/lib64/python2.7/Demo/pdist/server.pyRs        (tSecurityt SecureServercBseZdZdZRS(cGs(ttj|f|tj|dS(N(R1RRRT(RR:((s)/usr/lib64/python2.7/Demo/pdist/server.pyRwscCsddl}|j}|jd|d}xEd|krvt|dkrv|jd}|siPn||}q2Wy|j|j|}Wn6|jk r|jdkrdGt |GHndSX|j ||s|jdkrdGt |GHndS|jd krd GHnd S( Nis%d Rs idisInvalid response syntaxsInvalid response valueis&Response matches challenge. Go ahead!( tstringt_generate_challengetsendRLtrecvtatoltstript atol_errorRRt_compare_challenge_response(RR RRVt challengetresponsetdata((s)/usr/lib64/python2.7/Demo/pdist/server.pyR{s,  !(RPRQRR(((s)/usr/lib64/python2.7/Demo/pdist/server.pyRUus (( RRR2R R*RRRSRtsecurityRTRU(((s)/usr/lib64/python2.7/Demo/pdist/server.pyts   dPKH1]Zuurrcsnuȯ#! /usr/bin/python2.7 import addpack addpack.addpack('/home/guido/src/python/Demo/pdist') import rrcs rrcs.main() PKH1]KouurcvsnuȯPKH1]XB  cmptree.pyonu[PKH1]Z>N(N( rcslib.pynu[PKH1]C VAsumtree.pycnu[PKH1]2"& EFSProxy.pynu[PKH1]F N2 2 cmakechangelog.pyonu[PKH1]F"Yprrcs.pyonu[PKH1]oss RCSProxy.pynuȯPKH1]Wss <cvslock.pynu[PKH1];DD client.pycnu[PKH1]Zr``gmac.pynu[PKH1]@GF security.pyonu[PKH1]XB  cmptree.pycnu[PKH1](q makechangelog.pynuȯPKH1])SS server.pycnu[PKH1]HxT3T3 icvslib.pyonu[PKH1]GG ERCSProxy.pycnu[PKH1];DD zdclient.pyonu[PKH1]Udd ~client.pynu[PKH1]#)-- rcslib.pycnu[PKH1]GG RCSProxy.pyonu[PKH1]Șy ncmptree.pynu[PKH1]5tVV:mac.pycnu[PKH1]l!!cmdfw.pynu[PKH1]F N2 2  makechangelog.pycnu[PKH1]Op!p! cvslock.pycnu[PKH1] ,>7READMEnu[PKH1]%{ȘHrrcs.pynuȯPKH1]Op!p! Wcvslock.pyonu[PKH1]Mi$11 yFSProxy.pyonu[PKH1]HxT3T3 ̫cvslib.pycnu[PKH1]F"Zrrcs.pycnu[PKH1]C sumtree.pyonu[PKH1]P]QrcsbumpnuȯPKH1] >L5L5qrcvs.pynuȯPKH1]e'ww 1cmdfw.pycnu[PKH1]roQ8Q8Frcvs.pycnu[PKH1]e'ww -cmdfw.pyonu[PKH1]#)-- ݓrcslib.pyonu[PKH1]'' 3cvslib.pynu[PKH1]roQ8Q8+rcvs.pyonu[PKH1]5tVV!mac.pyonu[PKH1]G A$sumtree.pynu[PKH1]Mi$11 &FSProxy.pycnu[PKH1]@GF Xsecurity.pycnu[PKH1]GT[DD _security.pynu[PKH1]" t dserver.pynu[PKH1]#44 !vrcsclient.pycnu[PKH1]l   ~rcsclient.pynu[PKH1]#44 مrcsclient.pyonu[PKH1])SS Jserver.pyonu[PKH1]ZuuץrrcsnuȯPK44