| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | #! /usr/local/bin/python | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """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. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  | The module defines two classes: | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | RCSProxyLocal  -- used for local access | 
					
						
							|  |  |  | RCSProxyServer -- used on the server side of remote access | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-23 22:37:53 +00:00
										 |  |  | The corresponding client class, RCSProxyClient, is defined in module | 
					
						
							|  |  |  | rcsclient. | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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 | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  | class RCSProxyLocal(rcslib.RCS, DirSupport): | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  |     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) | 
					
						
							| 
									
										
										
										
											1995-06-23 22:37:53 +00:00
										 |  |  | 	self._remove(name) | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-06-21 02:09:20 +00:00
										 |  |  | class RCSProxyServer(RCSProxyLocal, server.SecureServer): | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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() | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test_server(): | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  |     import string | 
					
						
							|  |  |  |     import sys | 
					
						
							|  |  |  |     if sys.argv[1:]: | 
					
						
							|  |  |  | 	port = string.atoi(sys.argv[1]) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  | 	port = 4127 | 
					
						
							|  |  |  |     proxy = RCSProxyServer(('', port)) | 
					
						
							|  |  |  |     proxy._serverloop() | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | def test(): | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  |     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:])) | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 	else: | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  | 	    print `attr` | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  | 	print "%s: no such attribute" % what | 
					
						
							|  |  |  | 	sys.exit(2) | 
					
						
							| 
									
										
										
										
											1995-04-26 22:57:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							| 
									
										
										
										
											1995-06-23 22:07:17 +00:00
										 |  |  |     test() |