1 | Filesystem, RCS and CVS client and server classes
|
---|
2 | =================================================
|
---|
3 |
|
---|
4 | *** See the security warning at the end of this file! ***
|
---|
5 |
|
---|
6 | This directory contains various modules and classes that support
|
---|
7 | remote file system operations.
|
---|
8 |
|
---|
9 | CVS stuff
|
---|
10 | ---------
|
---|
11 |
|
---|
12 | rcvs Script to put in your bin directory
|
---|
13 | rcvs.py Remote CVS client command line interface
|
---|
14 |
|
---|
15 | cvslib.py CVS admin files classes (used by rrcs)
|
---|
16 | cvslock.py CVS locking algorithms
|
---|
17 |
|
---|
18 | RCS stuff
|
---|
19 | ---------
|
---|
20 |
|
---|
21 | rrcs Script to put in your bin directory
|
---|
22 | rrcs.py Remote RCS client command line interface
|
---|
23 |
|
---|
24 | rcsclient.py Return an RCSProxyClient instance
|
---|
25 | (has reasonable default server/port/directory)
|
---|
26 |
|
---|
27 | RCSProxy.py RCS proxy and server classes (on top of rcslib.py)
|
---|
28 |
|
---|
29 | rcslib.py Local-only RCS base class (affects stdout &
|
---|
30 | local work files)
|
---|
31 |
|
---|
32 | FSProxy stuff
|
---|
33 | -------------
|
---|
34 |
|
---|
35 | sumtree.py Old demo for FSProxy
|
---|
36 | cmptree.py First FSProxy client (used to sync from the Mac)
|
---|
37 | FSProxy.py Filesystem interface classes
|
---|
38 |
|
---|
39 | Generic client/server stuff
|
---|
40 | ---------------------------
|
---|
41 |
|
---|
42 | client.py Client class
|
---|
43 | server.py Server class
|
---|
44 |
|
---|
45 | security.py Security mix-in class (not very secure I think)
|
---|
46 |
|
---|
47 | Other generic stuff
|
---|
48 | -------------------
|
---|
49 |
|
---|
50 | cmdfw.py CommandFrameWork class
|
---|
51 | (used by rcvs, should be used by rrcs as well)
|
---|
52 |
|
---|
53 |
|
---|
54 | Client/Server operation
|
---|
55 | -----------------------
|
---|
56 |
|
---|
57 | The Client and Server classes implement a simple-minded RPC protocol,
|
---|
58 | using Python's pickle module to transfer arguments, return values and
|
---|
59 | exceptions with the most generality. The Server class is instantiated
|
---|
60 | with a port number on which it should listen for requests; the Client
|
---|
61 | class is instantiated with a host name and a port number where it
|
---|
62 | should connect to. Once a client is connected, a TCP connection is
|
---|
63 | maintained between client and server.
|
---|
64 |
|
---|
65 | The Server class currently handles only one connection at a time;
|
---|
66 | however it could be rewritten to allow various modes of operations,
|
---|
67 | using multiple threads or processes or the select() system call as
|
---|
68 | desired to serve multiple clients simultaneously (when using select(),
|
---|
69 | still handling one request at a time). This would not require
|
---|
70 | rewriting of the Client class. It may also be possible to adapt the
|
---|
71 | code to use UDP instead of TCP, but then both classes will have to be
|
---|
72 | rewritten (and unless extensive acknowlegements and request serial
|
---|
73 | numbers are used, the server should handle duplicate requests, so its
|
---|
74 | semantics should be idempotent -- shrudder).
|
---|
75 |
|
---|
76 | Even though the FSProxy and RCSProxy modules define client classes,
|
---|
77 | the client class is fully generic -- what methods it supports is
|
---|
78 | determined entirely by the server. The server class, however, must be
|
---|
79 | derived from. This is generally done as follows:
|
---|
80 |
|
---|
81 | from server import Server
|
---|
82 | from client import Client
|
---|
83 |
|
---|
84 | # Define a class that performs the operations locally
|
---|
85 | class MyClassLocal:
|
---|
86 | def __init__(self): ...
|
---|
87 | def _close(self): ...
|
---|
88 |
|
---|
89 | # Derive a server class using multiple inheritance
|
---|
90 | class MyClassServer(MyClassLocal, Server):
|
---|
91 | def __init__(self, address):
|
---|
92 | # Must initialize MyClassLocal as well as Server
|
---|
93 | MyClassLocal.__init__(self)
|
---|
94 | Server.__init__(self, address)
|
---|
95 | def _close(self):
|
---|
96 | Server._close()
|
---|
97 | MyClassLocal._close()
|
---|
98 |
|
---|
99 | # A dummy client class
|
---|
100 | class MyClassClient(Client): pass
|
---|
101 |
|
---|
102 | Note that because MyClassLocal isn't used in the definition of
|
---|
103 | MyClassClient, it would actually be better to place it in a separate
|
---|
104 | module so the definition of MyClassLocal isn't executed when we only
|
---|
105 | instantiate a client.
|
---|
106 |
|
---|
107 | The modules client and server should probably be renamed to Client and
|
---|
108 | Server in order to match the class names.
|
---|
109 |
|
---|
110 |
|
---|
111 | *** Security warning: this version requires that you have a file
|
---|
112 | $HOME/.python_keyfile at the server and client side containing two
|
---|
113 | comma- separated numbers. The security system at the moment makes no
|
---|
114 | guarantees of actuallng being secure -- however it requires that the
|
---|
115 | key file exists and contains the same numbers at both ends for this to
|
---|
116 | work. (You can specify an alternative keyfile in $PYTHON_KEYFILE).
|
---|
117 | Have a look at the Security class in security.py for details;
|
---|
118 | basically, if the key file contains (x, y), then the security server
|
---|
119 | class chooses a random number z (the challenge) in the range
|
---|
120 | 10..100000 and the client must be able to produce pow(z, x, y)
|
---|
121 | (i.e. z**x mod y).
|
---|