| Filesystem, RCS and CVS client and server classes |
| ================================================= |
| |
| *** See the security warning at the end of this file! *** |
| |
| This directory contains various modules and classes that support |
| remote file system operations. |
| |
| CVS stuff |
| --------- |
| |
| rcvs Script to put in your bin directory |
| rcvs.py Remote CVS client command line interface |
| |
| cvslib.py CVS admin files classes (used by rrcs) |
| cvslock.py CVS locking algorithms |
| |
| RCS stuff |
| --------- |
| |
| rrcs Script to put in your bin directory |
| rrcs.py Remote RCS client command line interface |
| |
| rcsclient.py Return an RCSProxyClient instance |
| (has reasonable default server/port/directory) |
| |
| RCSProxy.py RCS proxy and server classes (on top of rcslib.py) |
| |
| rcslib.py Local-only RCS base class (affects stdout & |
| local work files) |
| |
| FSProxy stuff |
| ------------- |
| |
| sumtree.py Old demo for FSProxy |
| cmptree.py First FSProxy client (used to sync from the Mac) |
| FSProxy.py Filesystem interface classes |
| |
| Generic client/server stuff |
| --------------------------- |
| |
| client.py Client class |
| server.py Server class |
| |
| security.py Security mix-in class (not very secure I think) |
| |
| Other generic stuff |
| ------------------- |
| |
| cmdfw.py CommandFrameWork class |
| (used by rcvs, should be used by rrcs as well) |
| |
| |
| Client/Server operation |
| ----------------------- |
| |
| The Client and Server classes implement a simple-minded RPC protocol, |
| using Python's pickle module to transfer arguments, return values and |
| exceptions with the most generality. The Server class is instantiated |
| with a port number on which it should listen for requests; the Client |
| class is instantiated with a host name and a port number where it |
| should connect to. Once a client is connected, a TCP connection is |
| maintained between client and server. |
| |
| The Server class currently handles only one connection at a time; |
| however it could be rewritten to allow various modes of operations, |
| using multiple threads or processes or the select() system call as |
| desired to serve multiple clients simultaneously (when using select(), |
| still handling one request at a time). This would not require |
| rewriting of the Client class. It may also be possible to adapt the |
| code to use UDP instead of TCP, but then both classes will have to be |
| rewritten (and unless extensive acknowlegements and request serial |
| numbers are used, the server should handle duplicate requests, so its |
| semantics should be idempotent -- shrudder). |
| |
| Even though the FSProxy and RCSProxy modules define client classes, |
| the client class is fully generic -- what methods it supports is |
| determined entirely by the server. The server class, however, must be |
| derived from. This is generally done as follows: |
| |
| from server import Server |
| from client import Client |
| |
| # Define a class that performs the operations locally |
| class MyClassLocal: |
| def __init__(self): ... |
| def _close(self): ... |
| |
| # Derive a server class using multiple inheritance |
| class MyClassServer(MyClassLocal, Server): |
| def __init__(self, address): |
| # Must initialize MyClassLocal as well as Server |
| MyClassLocal.__init__(self) |
| Server.__init__(self, address) |
| def _close(self): |
| Server._close() |
| MyClassLocal._close() |
| |
| # A dummy client class |
| class MyClassClient(Client): pass |
| |
| Note that because MyClassLocal isn't used in the definition of |
| MyClassClient, it would actually be better to place it in a separate |
| module so the definition of MyClassLocal isn't executed when we only |
| instantiate a client. |
| |
| The modules client and server should probably be renamed to Client and |
| Server in order to match the class names. |
| |
| |
| *** Security warning: this version requires that you have a file |
| $HOME/.python_keyfile at the server and client side containing two |
| comma- separated numbers. The security system at the moment makes no |
| guarantees of actuallng being secure -- however it requires that the |
| key file exists and contains the same numbers at both ends for this to |
| work. (You can specify an alternative keyfile in $PYTHON_KEYFILE). |
| Have a look at the Security class in security.py for details; |
| basically, if the key file contains (x, y), then the security server |
| class chooses a random number z (the challenge) in the range |
| 10..100000 and the client must be able to produce pow(z, x, y) |
| (i.e. z**x mod y). |