| 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). | 
|---|