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