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