blob: 7c3b24f8ad71f8586c4a9454285c7f8613b8314b [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossum5f07b841995-04-26 22:57:11 +00002
3"""RCS Proxy.
4
5Provide a simplified interface on RCS files, locally or remotely.
6The functionality is geared towards implementing some sort of
7remote CVS like utility. It is modeled after the similar module
8FSProxy.
9
Guido van Rossumab75eb21995-06-23 22:07:17 +000010The module defines two classes:
Guido van Rossum5f07b841995-04-26 22:57:11 +000011
12RCSProxyLocal -- used for local access
13RCSProxyServer -- used on the server side of remote access
Guido van Rossumab75eb21995-06-23 22:07:17 +000014
Guido van Rossumbab47251995-06-23 22:37:53 +000015The corresponding client class, RCSProxyClient, is defined in module
16rcsclient.
Guido van Rossum5f07b841995-04-26 22:57:11 +000017
18The remote classes are instantiated with an IP address and an optional
19verbosity flag.
20"""
21
22import server
Guido van Rossum5f07b841995-04-26 22:57:11 +000023import md5
24import os
25import fnmatch
26import string
27import tempfile
Guido van Rossumab75eb21995-06-23 22:07:17 +000028import rcslib
Guido van Rossum5f07b841995-04-26 22:57:11 +000029
30
Guido van Rossumab75eb21995-06-23 22:07:17 +000031class DirSupport:
32
33 def __init__(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000034 self._dirstack = []
Guido van Rossumab75eb21995-06-23 22:07:17 +000035
36 def __del__(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000037 self._close()
Guido van Rossumab75eb21995-06-23 22:07:17 +000038
39 def _close(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000040 while self._dirstack:
41 self.back()
Guido van Rossumab75eb21995-06-23 22:07:17 +000042
43 def pwd(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000044 return os.getcwd()
Guido van Rossumab75eb21995-06-23 22:07:17 +000045
46 def cd(self, name):
Guido van Rossum4117e541998-09-14 16:44:15 +000047 save = os.getcwd()
48 os.chdir(name)
49 self._dirstack.append(save)
Guido van Rossumab75eb21995-06-23 22:07:17 +000050
51 def back(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000052 if not self._dirstack:
Collin Winter6f2df4d2007-07-17 20:59:35 +000053 raise os.error("empty directory stack")
Guido van Rossum4117e541998-09-14 16:44:15 +000054 dir = self._dirstack[-1]
55 os.chdir(dir)
56 del self._dirstack[-1]
Guido van Rossumab75eb21995-06-23 22:07:17 +000057
58 def listsubdirs(self, pat = None):
Guido van Rossum4117e541998-09-14 16:44:15 +000059 files = os.listdir(os.curdir)
Collin Winter6f2df4d2007-07-17 20:59:35 +000060 files = list(filter(os.path.isdir, files))
Guido van Rossum4117e541998-09-14 16:44:15 +000061 return self._filter(files, pat)
Guido van Rossumab75eb21995-06-23 22:07:17 +000062
63 def isdir(self, name):
Guido van Rossum4117e541998-09-14 16:44:15 +000064 return os.path.isdir(name)
Guido van Rossumab75eb21995-06-23 22:07:17 +000065
66 def mkdir(self, name):
Collin Winter6f2df4d2007-07-17 20:59:35 +000067 os.mkdir(name, 0o777)
Guido van Rossumab75eb21995-06-23 22:07:17 +000068
69 def rmdir(self, name):
Guido van Rossum4117e541998-09-14 16:44:15 +000070 os.rmdir(name)
Guido van Rossum5f07b841995-04-26 22:57:11 +000071
72
Guido van Rossumab75eb21995-06-23 22:07:17 +000073class RCSProxyLocal(rcslib.RCS, DirSupport):
Guido van Rossum5f07b841995-04-26 22:57:11 +000074
Guido van Rossumab75eb21995-06-23 22:07:17 +000075 def __init__(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000076 rcslib.RCS.__init__(self)
77 DirSupport.__init__(self)
Guido van Rossum5f07b841995-04-26 22:57:11 +000078
Guido van Rossumab75eb21995-06-23 22:07:17 +000079 def __del__(self):
Guido van Rossum4117e541998-09-14 16:44:15 +000080 DirSupport.__del__(self)
81 rcslib.RCS.__del__(self)
Guido van Rossum5f07b841995-04-26 22:57:11 +000082
Guido van Rossumab75eb21995-06-23 22:07:17 +000083 def sumlist(self, list = None):
Guido van Rossum4117e541998-09-14 16:44:15 +000084 return self._list(self.sum, list)
Guido van Rossum5f07b841995-04-26 22:57:11 +000085
Guido van Rossumab75eb21995-06-23 22:07:17 +000086 def sumdict(self, list = None):
Guido van Rossum4117e541998-09-14 16:44:15 +000087 return self._dict(self.sum, list)
Guido van Rossum5f07b841995-04-26 22:57:11 +000088
Guido van Rossumab75eb21995-06-23 22:07:17 +000089 def sum(self, name_rev):
Guido van Rossum4117e541998-09-14 16:44:15 +000090 f = self._open(name_rev)
91 BUFFERSIZE = 1024*8
92 sum = md5.new()
93 while 1:
94 buffer = f.read(BUFFERSIZE)
95 if not buffer:
96 break
97 sum.update(buffer)
98 self._closepipe(f)
99 return sum.digest()
Guido van Rossumab75eb21995-06-23 22:07:17 +0000100
101 def get(self, name_rev):
Guido van Rossum4117e541998-09-14 16:44:15 +0000102 f = self._open(name_rev)
103 data = f.read()
104 self._closepipe(f)
105 return data
Guido van Rossumab75eb21995-06-23 22:07:17 +0000106
107 def put(self, name_rev, data, message=None):
Guido van Rossum4117e541998-09-14 16:44:15 +0000108 name, rev = self._unmangle(name_rev)
109 f = open(name, 'w')
110 f.write(data)
111 f.close()
112 self.checkin(name_rev, message)
113 self._remove(name)
Guido van Rossumab75eb21995-06-23 22:07:17 +0000114
115 def _list(self, function, list = None):
Guido van Rossum4117e541998-09-14 16:44:15 +0000116 """INTERNAL: apply FUNCTION to all files in LIST.
Guido van Rossumab75eb21995-06-23 22:07:17 +0000117
Guido van Rossum4117e541998-09-14 16:44:15 +0000118 Return a list of the results.
Guido van Rossumab75eb21995-06-23 22:07:17 +0000119
Guido van Rossum4117e541998-09-14 16:44:15 +0000120 The list defaults to all files in the directory if None.
Guido van Rossumab75eb21995-06-23 22:07:17 +0000121
Guido van Rossum4117e541998-09-14 16:44:15 +0000122 """
123 if list is None:
124 list = self.listfiles()
125 res = []
126 for name in list:
127 try:
128 res.append((name, function(name)))
129 except (os.error, IOError):
130 res.append((name, None))
131 return res
Guido van Rossumab75eb21995-06-23 22:07:17 +0000132
133 def _dict(self, function, list = None):
Guido van Rossum4117e541998-09-14 16:44:15 +0000134 """INTERNAL: apply FUNCTION to all files in LIST.
Guido van Rossumab75eb21995-06-23 22:07:17 +0000135
Guido van Rossum4117e541998-09-14 16:44:15 +0000136 Return a dictionary mapping files to results.
Guido van Rossumab75eb21995-06-23 22:07:17 +0000137
Guido van Rossum4117e541998-09-14 16:44:15 +0000138 The list defaults to all files in the directory if None.
Guido van Rossumab75eb21995-06-23 22:07:17 +0000139
Guido van Rossum4117e541998-09-14 16:44:15 +0000140 """
141 if list is None:
142 list = self.listfiles()
143 dict = {}
144 for name in list:
145 try:
146 dict[name] = function(name)
147 except (os.error, IOError):
148 pass
149 return dict
Guido van Rossum5f07b841995-04-26 22:57:11 +0000150
151
Guido van Rossumf3d39ab1995-06-21 02:09:20 +0000152class RCSProxyServer(RCSProxyLocal, server.SecureServer):
Guido van Rossum5f07b841995-04-26 22:57:11 +0000153
Guido van Rossumab75eb21995-06-23 22:07:17 +0000154 def __init__(self, address, verbose = server.VERBOSE):
Guido van Rossum4117e541998-09-14 16:44:15 +0000155 RCSProxyLocal.__init__(self)
156 server.SecureServer.__init__(self, address, verbose)
Guido van Rossum5f07b841995-04-26 22:57:11 +0000157
Guido van Rossumab75eb21995-06-23 22:07:17 +0000158 def _close(self):
Guido van Rossum4117e541998-09-14 16:44:15 +0000159 server.SecureServer._close(self)
160 RCSProxyLocal._close(self)
Guido van Rossumab75eb21995-06-23 22:07:17 +0000161
162 def _serve(self):
Guido van Rossum4117e541998-09-14 16:44:15 +0000163 server.SecureServer._serve(self)
164 # Retreat into start directory
165 while self._dirstack: self.back()
Guido van Rossum5f07b841995-04-26 22:57:11 +0000166
167
168def test_server():
Guido van Rossumab75eb21995-06-23 22:07:17 +0000169 import string
170 import sys
171 if sys.argv[1:]:
Guido van Rossum4117e541998-09-14 16:44:15 +0000172 port = string.atoi(sys.argv[1])
Guido van Rossumab75eb21995-06-23 22:07:17 +0000173 else:
Guido van Rossum4117e541998-09-14 16:44:15 +0000174 port = 4127
Guido van Rossumab75eb21995-06-23 22:07:17 +0000175 proxy = RCSProxyServer(('', port))
176 proxy._serverloop()
Guido van Rossum5f07b841995-04-26 22:57:11 +0000177
178
179def test():
Guido van Rossumab75eb21995-06-23 22:07:17 +0000180 import sys
181 if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
Guido van Rossum4117e541998-09-14 16:44:15 +0000182 test_server()
183 sys.exit(0)
Guido van Rossumab75eb21995-06-23 22:07:17 +0000184 proxy = RCSProxyLocal()
185 what = sys.argv[1]
186 if hasattr(proxy, what):
Guido van Rossum4117e541998-09-14 16:44:15 +0000187 attr = getattr(proxy, what)
Guido van Rossumd59da4b2007-05-22 18:11:13 +0000188 if hasattr(attr, '__call__'):
Collin Winter6f2df4d2007-07-17 20:59:35 +0000189 print(attr(*sys.argv[2:]))
Guido van Rossum4117e541998-09-14 16:44:15 +0000190 else:
Collin Winter6f2df4d2007-07-17 20:59:35 +0000191 print(repr(attr))
Guido van Rossumab75eb21995-06-23 22:07:17 +0000192 else:
Collin Winter6f2df4d2007-07-17 20:59:35 +0000193 print("%s: no such attribute" % what)
Guido van Rossum4117e541998-09-14 16:44:15 +0000194 sys.exit(2)
Guido van Rossum5f07b841995-04-26 22:57:11 +0000195
196
197if __name__ == '__main__':
Guido van Rossumab75eb21995-06-23 22:07:17 +0000198 test()