diff --git a/Demo/pdist/RCSProxy.py b/Demo/pdist/RCSProxy.py
new file mode 100755
index 0000000..0a12157
--- /dev/null
+++ b/Demo/pdist/RCSProxy.py
@@ -0,0 +1,285 @@
+#! /usr/local/bin/python
+
+"""RCS Proxy.
+
+Provide a simplified interface on RCS files, locally or remotely.
+The functionality is geared towards implementing some sort of
+remote CVS like utility.  It is modeled after the similar module
+FSProxy.
+
+The module defines three classes:
+
+RCSProxyLocal  -- used for local access
+RCSProxyServer -- used on the server side of remote access
+RCSProxyClient -- used on the client side of remote access
+
+The remote classes are instantiated with an IP address and an optional
+verbosity flag.
+"""
+
+import server
+import client
+import md5
+import os
+import fnmatch
+import string
+import tempfile
+
+
+okchars = string.letters + string.digits + '-_=+.'
+
+
+class RCSProxyLocal:
+	
+	def __init__(self):
+		self._dirstack = []
+	
+	def _close(self):
+		while self._dirstack:
+			self.back()
+	
+	def pwd(self):
+		return os.getcwd()
+	
+	def cd(self, name):
+		save = os.getcwd()
+		os.chdir(name)
+		self._dirstack.append(save)
+	
+	def back(self):
+		if not self._dirstack:
+			raise os.error, "empty directory stack"
+		dir = self._dirstack[-1]
+		os.chdir(dir)
+		del self._dirstack[-1]
+	
+	def _filter(self, files, pat = None):
+		if pat:
+			def keep(name, pat = pat):
+				return fnmatch.fnmatch(name, pat)
+			files = filter(keep, files)
+		files.sort()
+		return files
+
+	def isfile(self, name):
+		namev = name + ',v'
+		return os.path.isfile(namev) or \
+		       os.path.isfile(os.path.join('RCS', namev))
+	
+	def _unmangle(self, name):
+		if type(name) == type(''):
+			rev = ''
+		else:
+			name, rev = name
+		return name, rev
+	
+	def checkfile(self, name):
+		name, rev = self._unmangle(name)
+		if not self.isfile(name):
+			raise os.error, 'not an rcs file %s' % `name`
+		for c in rev:
+			if c not in okchars:
+				raise ValueError, "bad char in rev"
+		return name, rev
+	
+	def listfiles(self, pat = None):
+		def isrcs(name): return name[-2:] == ',v'
+		def striprcs(name): return name[:-2]
+		files = os.listdir(os.curdir)
+		files = filter(isrcs, files)
+		if os.path.isdir('RCS'):
+			files2 = os.listdir('RCS')
+			files2 = filter(isrcs, files2)
+			files = files + files2
+		files = map(striprcs, files)
+		return self._filter(files, pat)
+	
+	def listsubdirs(self, pat = None):
+		files = os.listdir(os.curdir)
+		files = filter(os.path.isdir, files)
+		return self._filter(files, pat)
+	
+	def isdir(self, name):
+		return os.path.isdir(name)
+
+	def _open(self, name, cmd = 'co -p'):
+		name, rev = self.checkfile(name)
+		namev = name + ',v'
+		if rev:
+			cmd = cmd + ' -r' + rev
+		return os.popen('%s %s' %  (cmd, `namev`))
+
+	def _closepipe(self, f):
+		sts = f.close()
+		if sts:
+			raise IOError, "Exit status %d" % sts
+	
+	def _remove(self, fn):
+		try:
+			os.unlink(fn)
+		except os.error:
+			pass
+	
+	def sum(self, name):
+		f = self._open(name)
+		BUFFERSIZE = 1024*8
+		sum = md5.new()
+		while 1:
+			buffer = f.read(BUFFERSIZE)
+			if not buffer:
+				break
+			sum.update(buffer)
+		self._closepipe(f)
+		return sum.digest()
+	
+	def _list(self, function, list):
+		if list is None:
+			list = self.listfiles()
+		res = []
+		for name in list:
+			try:
+				res.append((name, function(name)))
+			except (os.error, IOError):
+				res.append((name, None))
+		return res
+	
+	def sumlist(self, list = None):
+		return self.list(self.sum, list)
+	
+	def _dict(self, function, list):
+		if list is None:
+			list = self.listfiles()
+		dict = {}
+		for name in list:
+			try:
+				dict[name] = function(name)
+			except (os.error, IOError):
+				pass
+		return dict
+	
+	def sumdict(self, list = None):
+		return self.dict(self.sum, list)
+	
+	def get(self, name):
+		f = self._open(name)
+		data = f.read()
+		self._closepipe(f)
+		return data
+
+	def info(self, name):
+		f = self._open(name, 'rlog -h')
+		dict = {}
+		while 1:
+			line = f.readline()
+			if not line: break
+			if line[0] == '\t':
+				continue # XXX lock details, later
+			i = string.find(line, ':')
+			if i > 0:
+				key, value = line[:i], string.strip(line[i+1:])
+				dict[key] = value
+		self._closepipe(f)
+		return dict
+	
+	def head(self, name):
+		dict = self.info(name)
+		return dict['head']
+	
+	def log(self, name, flags = ''):
+		f = self._open(name, 'rlog %s 2>&1' % flags)
+		log = f.read()
+		self._closepipe(f)
+		return log
+
+	def put(self, fullname, data, message = ""):
+		if message and message[-1] != '\n':
+			message = message + '\n'
+		name, rev = self._unmangle(fullname)
+		new = not self.isfile(name)
+		if new:
+			for c in name:
+				if c not in okchars:
+					raise ValueError, "bad char in name"
+		else:
+			self._remove(name)
+		f = open(name, 'w')
+		f.write(data)
+		f.close()
+		tf = tempfile.mktemp()
+		try:
+			if not new:
+			    cmd = "rcs -l%s %s >>%s 2>&1" % (rev, name, tf)
+			    sts = os.system(cmd)
+			    if sts:
+				raise IOError, "rcs -l exit status %d" % sts
+			cmd = "ci -r%s %s >>%s 2>&1" % (rev, name, tf)
+			p = os.popen(cmd, 'w')
+			p.write(message)
+			sts = p.close()
+			if sts:
+				raise IOError, "ci exit status %d" % sts
+			messages = open(tf).read()
+			return messages or None
+		finally:
+			self._remove(tf)
+	
+	def mkdir(self, name):
+		os.mkdir(name, 0777)
+	
+	def rmdir(self, name):
+		os.rmdir(name)
+
+
+class RCSProxyServer(RCSProxyLocal, server.Server):
+	
+	def __init__(self, address, verbose = server.VERBOSE):
+		RCSProxyLocal.__init__(self)
+		server.Server.__init__(self, address, verbose)
+	
+	def _close(self):
+		server.Server._close(self)
+		RCSProxyLocal._close(self)
+	
+	def _serve(self):
+		server.Server._serve(self)
+		# Retreat into start directory
+		while self._dirstack: self.back()
+
+
+class RCSProxyClient(client.Client):
+	
+	def __init__(self, address, verbose = client.VERBOSE):
+		client.Client.__init__(self, address, verbose)
+
+
+def test_server():
+	import string
+	import sys
+	if sys.argv[1:]:
+		port = string.atoi(sys.argv[1])
+	else:
+		port = 4127
+	proxy = RCSProxyServer(('', port))
+	proxy._serverloop()
+
+
+def test():
+	import sys
+	if not sys.argv[1:] or sys.argv[1] and sys.argv[1][0] in '0123456789':
+		test_server()
+		sys.exit(0)
+	proxy = RCSProxyLocal()
+	what = sys.argv[1]
+	if hasattr(proxy, what):
+		attr = getattr(proxy, what)
+		if callable(attr):
+			print apply(attr, tuple(sys.argv[2:]))
+		else:
+			print `attr`
+	else:
+		print "%s: no such attribute" % what
+		sys.exit(2)
+
+
+if __name__ == '__main__':
+	test()
diff --git a/Demo/pdist/README b/Demo/pdist/README
new file mode 100644
index 0000000..738126d
--- /dev/null
+++ b/Demo/pdist/README
@@ -0,0 +1,2 @@
+This directory contains various modules and classes that support
+remote file system operations
diff --git a/Demo/pdist/cvslib.py b/Demo/pdist/cvslib.py
new file mode 100755
index 0000000..c98f0ba
--- /dev/null
+++ b/Demo/pdist/cvslib.py
@@ -0,0 +1,186 @@
+"""Utilities to read and write CVS admin files (esp. CVS/Entries)"""
+
+import string
+import os
+import time
+
+
+class Entry:
+
+	"""Class representing one (parsed) line from CVS/Entries"""
+	
+	def __init__(self, line):
+		words = string.splitfields(line, '/')
+		self.file = words[1]
+		self.rev = words[2]
+		dates = words[3] # ctime, mtime
+		if dates[:7] == 'Initial':
+			self.ctime = None
+			self.mtime = None
+			self.new = 1
+		else:
+			self.ctime = unctime(dates[:24])
+			self.mtime = unctime(dates[25:])
+			self.new = 0
+		self.extra = words[4]
+		self.sum = None
+	
+	def unparse(self):
+		if self.new:
+			dates = "Initial %s" % self.file
+		else:
+			dates = gmctime(self.ctime) + ' ' + gmctime(self.mtime)
+		return "/%s/%s/%s/%s/\n" % (
+			self.file,
+			self.rev,
+			dates,
+			self.extra)
+	
+	def setsum(self, sum):
+		self.sum = sum
+	
+	def getsum(self):
+		return self.sum
+	
+	def sethexsum(self, hexsum):
+		self.setsum(unhexify(hexsum))
+	
+	def gethexsum(self):
+		if self.sum:
+			return hexify(self.sum)
+		else:
+			return None
+
+
+class CVS:
+
+	"""Class representing the contents of CVS/Entries (and CVS/Sums)"""
+	
+	def __init__(self):
+		self.readentries()
+	
+	def readentries(self):
+		self.entries = {}
+		f = self.cvsopen("Entries")
+		while 1:
+			line = f.readline()
+			if not line: break
+			e = Entry(line)
+			self.entries[e.file] = e
+		f.close()
+	
+	def readsums(self):
+		try:
+			f = self.cvsopen("Sums")
+		except IOError:
+			return
+		while 1:
+			line = f.readline()
+			if not line: break
+			words = string.split(line)
+			[file, rev, hexsum] = words
+			e = self.entries[file]
+			if e.rev == rev:
+				e.sethexsum(hexsum)
+		f.close()
+	
+	def writeentries(self):
+		f = self.cvsopen("Entries", 'w')
+		for file in self.keys():
+			f.write(self.entries[file].unparse())
+		f.close()
+	
+	def writesums(self):
+		if self.cvsexists("Sums"):
+			f = self.cvsopen("Sums", 'w')
+		else:
+			f = None
+		for file in self.keys():
+			e = self.entries[file]
+			hexsum = e.gethexsum()
+			if hexsum:
+				if not f:
+					f = self.cvsopen("Sums", 'w')
+				f.write("%s %s %s\n" % (file, e.rev, hexsum))
+		if f:
+			f.close()
+	
+	def keys(self):
+		keys = self.entries.keys()
+		keys.sort()
+		return keys
+
+	def cvsexists(self, file):
+		file = os.path.join("CVS", file)
+		return os.path.exists(file)
+	
+	def cvsopen(self, file, mode = 'r'):
+		file = os.path.join("CVS", file)
+		if 'r' not in mode:
+			self.backup(file)
+		return open(file, mode)
+	
+	def backup(self, file):
+		if os.path.isfile(file):
+			bfile = file + '~'
+			os.rename(file, bfile)
+
+
+hexify_format = '%02x' * 16
+def hexify(sum):
+	"Return a hex representation of a 16-byte string (e.g. an MD5 digest)"
+	return hexify_format % tuple(map(ord, sum))
+
+def unhexify(hexsum):
+	"Return the original from a hexified string"
+	sum = ''
+	for i in range(0, len(hexsum), 2):
+		sum = sum + chr(string.atoi(hexsum[i:i+2], 16))
+	return sum
+
+
+unctime_monthmap = {}
+def unctime(date):
+	if not unctime_monthmap:
+		months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+			  'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+		i = 0
+		for m in months:
+			i = i+1
+			unctime_monthmap[m] = i
+	words = string.split(date) # Day Mon DD HH:MM:SS YEAR
+	year = string.atoi(words[4])
+	month = unctime_monthmap[words[1]]
+	day = string.atoi(words[2])
+	[hh, mm, ss] = map(string.atoi, string.splitfields(words[3], ':'))
+	ss = ss - time.timezone
+	return time.mktime((year, month, day, hh, mm, ss, 0, 0, 0))
+
+def gmctime(t):
+	return time.asctime(time.gmtime(t))
+
+def test_unctime():
+	now = int(time.time())
+	t = time.gmtime(now)
+	at = time.asctime(t)
+	print 'GMT', now, at
+	print 'timezone', time.timezone
+	print 'local', time.ctime(now)
+	u = unctime(at)
+	print 'unctime()', u
+	gu = time.gmtime(u)
+	print '->', gu
+	print time.asctime(gu)
+
+def test():
+	x = CVS()
+	keys = x.entries.keys()
+	keys.sort()
+	for file in keys:
+		e = x.entries[file]
+		print file, e.rev, gmctime(e.ctime), gmctime(e.mtime), e.extra,
+		print e.gethexsum()
+
+
+if __name__ == "__main__":
+	test()
diff --git a/Demo/pdist/rcvs.py b/Demo/pdist/rcvs.py
new file mode 100755
index 0000000..eb43bb8
--- /dev/null
+++ b/Demo/pdist/rcvs.py
@@ -0,0 +1,192 @@
+from cvslib import CVS, Entry
+import RCSProxy
+import client
+import md5
+import os
+import string
+import sys
+import time
+import fnmatch
+
+
+ignored_patterns = ['*.pyc', '.*', '*~', '@*']
+def ignored(file):
+	if os.path.isdir(file): return 1
+	for pat in ignored_patterns:
+		if fnmatch.fnmatch(file, pat): return 1
+	return 0
+
+
+class PCVS(CVS):
+	
+	def __init__(self, proxy):
+		CVS.__init__(self)
+		self.proxy = proxy
+		self.readsums()
+		self.calcsums()
+	
+	def calcsums(self):
+		for file in self.keys():
+			e = self.entries[file]
+			if not e.new and e.sum is None:
+				sum = self.proxy.sum((file, e.rev))
+				e.setsum(sum)
+	
+	def fullcheck(self):
+		ok = 1
+		for file in self.keys():
+			e = self.entries[file]
+			if e.new:
+				if self.proxy.isfile(file):
+					print "%s: created by someone else!"
+					ok = 0
+				continue
+			rrev = self.proxy.head(file)
+			if rrev != e.rev:
+				print "%s: out of date (%s vs. %s)" % \
+				      (file, e.rev, rrev)
+				ok = 0
+		return ok
+	
+	def update(self):
+		for file in self.keys():
+			e = self.entries[file]
+			if e.new:
+				print 'A', file
+				continue
+			rrev = self.proxy.head(file)
+			lsum = sumfile(file)
+			if rrev == e.rev:
+				if lsum == e.sum:
+					print '=', file
+				else:
+					print 'M', file
+				continue
+			if e.sum != lsum:
+				print "%s: conflict -- not updated" % file
+				continue
+			print "%s: getting ..." % file
+			data = self.proxy.get(file)
+			f = open(file, 'w')
+			f.write(data)
+			f.close()
+			nsum = md5.new(data).digest()
+			e.setsum(nsum)
+			e.rev = rrev
+			print 'U', file
+		self.writeentries()
+		self.writesums()
+	
+	def commit(self):
+		if not self.fullcheck():
+			print "correct above errors first"
+			return
+		needed = []
+		for file in self.keys():
+			e = self.entries[file]
+			if e.new:
+				needed.append(file)
+				continue
+			lsum = sumfile(file)
+			if lsum != e.sum:
+				needed.append(file)
+				continue
+		if not needed:
+			print "no changes need committing"
+			return
+		message = raw_input("One-liner: ")
+		for file in needed:
+			print "%s: putting ..." % file
+			e = self.entries[file]
+			data = open(file).read()
+			self.proxy.put(file, data, message)
+			e.rev = self.proxy.head(file)
+			e.setsum(self.proxy.sum(file))
+			# XXX get it?
+			mtime, ctime = os.stat(file)[-2:]
+			e.mtime = mtime
+			e.ctime = ctime
+		self.writeentries()
+		self.writesums()
+	
+	def report(self):
+		keys = self.keys()
+		files = os.listdir(os.curdir)
+		allfiles = files
+		for file in keys:
+			if file not in allfiles:
+				allfiles.append(file)
+		allfiles.sort()
+		for file in allfiles:
+			if file not in keys:
+				if not ignored(file):
+					print '?', file
+				continue
+			if file not in files:
+				print file, ': lost'
+				continue
+			e = self.entries[file]
+			if not os.path.exists(file):
+				print "%s: lost" % file
+				continue
+			if e.new:
+				print 'A', file
+				continue
+			lsum = sumfile(file)
+			rrev = self.proxy.head(file)
+			if rrev == e.rev:
+				if lsum == e.sum:
+					print '=', file
+				else:
+					print 'M', file
+			else:
+				if lsum == e.sum:
+					print 'U', file
+				else:
+					print 'C', file
+	
+	def add(self, file):
+		if self.entries.has_key(file):
+			print "%s: already known"
+		else:
+			self.entries[file] = Entry('/%s/0/Initial %s//\n' %
+						   (file, file))
+
+
+def sumfile(file):
+	return md5.new(open(file).read()).digest()
+
+
+def test():
+	proxy = RCSProxy.RCSProxyClient(('voorn.cwi.nl', 4127))
+	proxy.cd('/ufs/guido/voorn/python-RCS/Demo/pdist')
+	x = PCVS(proxy)
+	args = sys.argv[1:]
+	if args:
+		cmd = args[0]
+		files = args[1:]
+		if cmd == 'add':
+			if not files:
+				print "add needs at least one file argument"
+			else:
+				for file in files:
+					x.add(file)
+				x.writeentries()
+		elif cmd in ('update', 'up'):
+			if files:
+				print "updates wants no file arguments"
+			else:
+				x.update()
+		elif cmd in ('commit', 'com'):
+			if files:
+				print "commit wants no file arguments"
+			else:
+				x.commit()
+		else:
+			print "Unknown command", cmd
+	else:
+		x.report()
+		if sys.argv[1:]: x.writesums()
+
+if __name__ == "__main__":
+	test()
diff --git a/Demo/pdist/rrcs.py b/Demo/pdist/rrcs.py
new file mode 100755
index 0000000..74bce56
--- /dev/null
+++ b/Demo/pdist/rrcs.py
@@ -0,0 +1,174 @@
+#! /usr/local/bin/python
+
+import sys
+import os
+import getopt
+import string
+import md5
+import tempfile
+
+def main():
+	sys.stdout = sys.stderr
+	try:
+		opts, rest = getopt.getopt(sys.argv[1:], 'h:p:qv')
+		if not rest:
+			raise getopt.error, "missing command"
+		cmd, rest = rest[0], rest[1:]
+		if not commands.has_key(cmd):
+			raise getopt.error, "unknown command"
+		coptset, func = commands[cmd]
+		copts, files = getopt.getopt(rest, coptset)
+	except getopt.error, msg:
+		print msg
+		print "usage: rrcs [options] command [options] [file] ..."
+		print "where command can be:"
+		print "      ci|put      # checkin the given files"
+		print "      co|get      # checkout"
+		print "      info        # print header info"
+		print "      head        # print revision of head branch"
+		print "      list        # list filename if valid"
+		print "      log         # print full log"
+		print "      diff        # diff rcs file and work file"
+		print "if no files are given, all remote rcs files are assumed"
+		sys.exit(2)
+	x = openclient(opts)
+	if not files:
+		files = x.listfiles()
+	for fn in files:
+		try:
+			func(x, copts, fn)
+		except (IOError, os.error), msg:
+			print "%s: %s" % (fn, msg)
+
+def openclient(opts):
+	import client
+	import RCSProxy
+	host = 'spam'
+	port = 4127
+	verbose = client.VERBOSE
+	for o, a in opts:
+		if o == '-h':
+			host = a
+			if ':' in host:
+				i = string.find(host, ':')
+				host, p = host[:i], host[i+1:]
+				if p:
+					port = string.atoi(p)
+		if o == '-p':
+			port = string.atoi(a)
+		if o == '-v':
+			verbose = verbose + 1
+		if o == '-q':
+			verbose = 0
+	address = (host, port)
+	x = RCSProxy.RCSProxyClient(address, verbose)
+	return x
+
+def checkin(x, copts, fn):
+	f = open(fn)
+	data = f.read()
+	f.close()
+	new = not x.isfile(fn)
+	if not new and same(x, copts, fn, data):
+		print "%s: unchanged since last checkin" % fn
+		return
+	message = asklogmessage(new)
+	messages = x.put(fn, data, message)
+	if messages:
+		print messages
+
+def checkout(x, copts, fn):
+	data = x.get(fn)
+	f = open(fn, 'w')
+	f.write(data)
+	f.close()
+
+def info(x, copts, fn):
+	dict = x.info(fn)
+	keys = dict.keys()
+	keys.sort()
+	for key in keys:
+		print key + ':', dict[key]
+	print '='*70
+
+def head(x, copts, fn):
+	head = x.head(fn)
+	print fn, head
+
+def list(x, copts, fn):
+	if x.isfile(fn):
+		print fn
+
+def log(x, copts, fn):
+	flags = ''
+	for o, a in copts:
+		flags = flags + ' ' + o + a
+	flags = flags[1:]
+	messages = x.log(fn, flags)
+	print messages
+
+def diff(x, copts, fn):
+	if same(x, copts, fn):
+		return
+	flags = ''
+	for o, a in copts:
+		flags = flags + ' ' + o + a
+	flags = flags[1:]
+	data = x.get(fn)
+	tfn = tempfile.mktemp()
+	try:
+		tf = open(tfn, 'w')
+		tf.write(data)
+		tf.close()
+		print 'diff %s -r%s %s' % (flags, x.head(fn), fn)
+		sts = os.system('diff %s %s %s' % (flags, tfn, fn))
+		if sts:
+			print '='*70
+	finally:
+		remove(tfn)
+
+def same(x, copts, fn, data = None):
+	if data is None:
+		f = open(fn)
+		data = f.read()
+		f.close()
+	lsum = md5.new(data).digest()
+	rsum = x.sum(fn)
+	return lsum == rsum
+
+def asklogmessage(new):
+	if new:
+		print "enter description,",
+	else:
+		print "enter log message,",
+	print "terminate with single '.' or end of file:"
+	if new:
+		print "NOTE: This is NOT the log message!"
+	message = ""
+	while 1:
+		sys.stderr.write(">> ")
+		sys.stderr.flush()
+		line = sys.stdin.readline()
+		if not line or line == '.\n': break
+		message = message + line
+	return message
+
+def remove(fn):
+	try:
+		os.unlink(fn)
+	except os.error:
+		pass
+
+commands = {
+	'ci': ('', checkin),
+	'put': ('', checkin),
+	'co': ('', checkout),
+	'get': ('', checkout),
+	'info': ('', info),
+	'head': ('', head),
+	'list': ('', list),
+	'log': ('bhLRtd:l:r:s:w:V:', log),
+	'diff': ('c', diff),
+	}
+
+main()
