diff --git a/Mac/scripts/MkDistr.py b/Mac/scripts/MkDistr.py
new file mode 100644
index 0000000..deda71b
--- /dev/null
+++ b/Mac/scripts/MkDistr.py
@@ -0,0 +1,280 @@
+#
+# Interactively decide what to distribute
+#
+# The distribution type is signalled by a letter. The currently
+# defined letters are:
+# p		PPC normal distribution
+# P		PPC development distribution
+# m		68K normal distribution
+# M		68K development distribution
+#
+# The exclude file signals files to always exclude,
+# The pattern file records are of the form
+# ('pm', '*.c')
+# This excludes all files ending in .c for normal distributions.
+#
+# The include file signals files and directories to include.
+# Records are of the form
+# ('pPmM', 'Lib')
+# This includes the Lib dir in all distributions
+# ('pPmM', 'Tools:bgen:AE:AppleEvents.py', 'Lib:MacToolbox:AppleEvents.py')
+# This includes the specified file, putting it in the given place.
+#
+from MkDistr_ui import *
+import fnmatch
+import regex
+import os
+import sys
+import macfs
+import macostools
+
+SyntaxError='Include/exclude file syntax error'
+
+class Matcher:
+	"""Include/exclude database, common code"""
+	
+	def __init__(self, type, filename):
+		self.type = type
+		self.filename = filename
+		self.rawdata = []
+		self.parse(filename)
+		self.rawdata.sort()
+		self.rebuild()
+		self.modified = 0
+
+	def parse(self, dbfile):
+		try:
+			fp = open(dbfile)
+		except IOError:
+			return
+		data = fp.readlines()
+		fp.close()
+		for d in data:
+			d = d[:-1]
+			if not d or d[0] == '#': continue
+			pat = self.parseline(d)
+			self.rawdata.append(pat)
+				
+	def parseline(self, line):
+		try:
+			data = eval(line)
+		except:
+			raise SyntaxError, line
+		if type(data) <> type(()) or len(data) not in (2,3):
+			raise SyntaxError, line
+		if len(data) == 2:
+			data = data + ('',)
+		return data
+		
+	def save(self):
+		fp = open(self.filename, 'w')
+		for d in self.rawdata:
+			fp.write(`d`+'\n')
+		self.modified = 0
+			
+	def add(self, value):
+		if len(value) == 2:
+			value = value + ('',)
+		self.rawdata.append(value)
+		self.rebuild1(value)
+		self.modified = 1
+		
+	def delete(self, value):
+		key = value
+		for i in range(len(self.rawdata)):
+			if self.rawdata[i][1] == key:
+				del self.rawdata[i]
+				self.unrebuild1(i, key)
+				self.modified = 1
+				return
+		print 'Not found!', key
+				
+	def getall(self):
+		return map(lambda x: x[1], self.rawdata)
+	
+	def get(self, value):
+		for t, src, dst in self.rawdata:
+			if src == value:
+				return t, src, dst
+		print 'Not found!', value
+				
+	def is_modified(self):
+		return self.modified
+							
+class IncMatcher(Matcher):
+	"""Include filename database and matching engine"""
+
+	def rebuild(self):
+		self.idict = {}
+		self.edict = {}
+		for v in self.rawdata:
+			self.rebuild1(v)
+			
+	def rebuild1(self, (tp, src, dst)):
+		if self.type in tp:
+			if dst == '':
+				dst = src
+			self.idict[src] = dst
+		else:
+			self.edict[src] = ''
+			
+	def unrebuild1(self, num, src):
+		if self.idict.has_key(src):
+			del self.idict[src]
+		else:
+			del self.edict[src]
+	
+	def match(self, patharg):
+		removed = []
+		# First check the include directory
+		path = patharg
+		while 1:
+			if self.idict.has_key(path):
+				# We know of this path (or initial piece of path)
+				dstpath = self.idict[path]
+				# We do want it distributed. Tack on the tail.
+				while removed:
+					dstpath = os.path.join(dstpath, removed[0])
+					removed = removed[1:]
+				# Finally, if the resultant string ends in a separator
+				# tack on our input filename
+				if dstpath[-1] == os.sep:
+					dir, file = os.path.split(path)
+					dstpath = os.path.join(dstpath, path)
+				return dstpath
+			path, lastcomp = os.path.split(path)
+			if not path:
+				break
+			removed[0:0] = [lastcomp]
+		# Next check the exclude directory
+		path = patharg
+		while 1:
+			if self.edict.has_key(path):
+				return ''
+			path, lastcomp = os.path.split(path)
+			if not path:
+				break
+			removed[0:0] = [lastcomp]
+		return None
+			
+	def checksourcetree(self):
+		rv = []
+		for name in self.idict.keys():
+			if not os.path.exists(name):
+				rv.append(name)
+		return rv
+				
+class ExcMatcher(Matcher):
+	"""Exclude pattern database and matching engine"""
+
+	def rebuild(self):
+		self.relist = []
+		for v in self.rawdata:
+			self.rebuild1(v)
+		
+	def rebuild1(self, (tp, src, dst)):
+		if self.type in tp:
+			pat = fnmatch.translate(src)
+			self.relist.append(regex.compile(pat))
+		else:
+			self.relist.append(None)
+			
+	def unrebuild1(self, num, src):
+		del self.relist[num]
+	
+	def match(self, path):
+		comps = os.path.split(path)
+		file = comps[-1]
+		for pat in self.relist:
+			if pat and pat.match(file) == len(file):
+				return 1
+		return 0		
+		 
+		
+class Main:
+	"""The main program glueing it all together"""
+	
+	def __init__(self):
+		InitUI()
+		fss, ok = macfs.GetDirectory('Source directory:')
+		if not ok:
+			sys.exit(0)
+		os.chdir(fss.as_pathname())
+		self.typedist = GetType()
+		print 'TYPE', self.typedist
+		self.inc = IncMatcher(self.typedist, '(MkDistr.include)')
+		self.exc = ExcMatcher(self.typedist, '(MkDistr.exclude)')
+		self.ui = MkDistrUI(self)
+		self.ui.mainloop()
+		
+	def check(self):
+		return self.checkdir(':', 1)
+		
+	def checkdir(self, path, istop):
+		files = os.listdir(path)
+		rv = []
+		todo = []
+		for f in files:
+			if self.exc.match(f):
+				continue
+			fullname = os.path.join(path, f)
+			if self.inc.match(fullname) == None:
+				if os.path.isdir(fullname):
+					todo.append(fullname)
+				else:
+					rv.append(fullname)
+		for d in todo:
+			if len(rv) > 100:
+				if istop:
+					rv.append('... and more ...')
+				return rv
+			rv = rv + self.checkdir(d, 0)
+		return rv
+		
+	def run(self, destprefix):
+		missing = self.inc.checksourcetree()
+		if missing:
+			print '==== Missing source files ===='
+			for i in missing:
+				print i
+			print '==== Fix and retry ===='
+			return
+		if not self.rundir(':', destprefix, 0):
+			return
+		self.rundir(':', destprefix, 1)
+
+	def rundir(self, path, destprefix, doit):
+		files = os.listdir(path)
+		todo = []
+		rv = 1
+		for f in files:
+			if self.exc.match(f):
+				continue
+			fullname = os.path.join(path, f)
+			if os.path.isdir(fullname):
+				todo.append(fullname)
+			else:
+				dest = self.inc.match(fullname)
+				if dest == None:
+					print 'Not yet resolved:', fullname
+					rv = 0
+				if dest:
+					if doit:
+						print 'COPY ', fullname
+						print '  -> ', os.path.join(destprefix, dest)
+						macostools.copy(fullname, os.path.join(destprefix, dest), 1)
+		for d in todo:
+			if not self.rundir(d, destprefix, doit):
+				rv = 0
+		return rv
+		
+	def save(self):
+		self.inc.save()
+		self.exc.save()
+		
+	def is_modified(self):
+		return self.inc.is_modified() or self.exc.is_modified()
+
+if __name__ == '__main__':
+	Main()
+	
diff --git a/Mac/scripts/MkDistr.rsrc.hqx b/Mac/scripts/MkDistr.rsrc.hqx
new file mode 100644
index 0000000..b8c4478
--- /dev/null
+++ b/Mac/scripts/MkDistr.rsrc.hqx
@@ -0,0 +1,31 @@
+(This file may be decompressed with BinHex 4.0)
+
+:$%eV4'PcG()ZFR0bB`"bFh*M8P0&4!%!N!F&SINN!*!%!3!!!!5[!!!$V`!!!2)8
+T8SJ&+9+%"5P5rJ6'6!)%!!!#"!!!!J3!!!)%!!!#!a0Dd4TFh4b,R*cFQ0b!J!!
+!(*cFQ058d9%!3$rN!3!!(*cFQ058d9%!3$rN!3!N"+XA"N$!*!'"D(rq"rrrJ!I
+rrm!(rrrJ"rrrm!IrrrJ(rrrm"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJI
+rrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri(rrrq"rrrrJI
+rrri(rrrq"rrrrJIrrri(rrrq"rrrrJIrrri!!!!&3"F!$i!rJ'K!!8"!!%!N!8#
+!*!&&3"F!$i!rJ'K!!8"!!%!N!8#!3#3"-`!#!#3"B)")J#@!9`%!Np,!*!&JJ!+
+!*B!4!3'3f&ZBf9X!*!&C!$F!(B"@`8'8fpeFQ0P!*!&8!$F!')"@`8,8&"$)'4P
+GQ9XEh!!N!C3!'i!BJ$B"3Sf1%XJ3QPZBA*j!*!&C!"Z!(B!f!8+8&"$)'*TEQ&b
+H3#3"43!EJ!M!9B3#89NDA3J9'9iG&X!N!88!!S!*!"KL!K3BA4dCA*Z1J#3"9!!
+#J"J!'+)#d9iBfaeC'8JD@ik!*!%p!!+!*!&JJ%L!*B"A!3#6dX!N!@#!!S!PJ"%
+"!C$B@jMC@`!N!9N!0`!GJ&E"3C6Eh9bBf8!N!93!0`!BJ&E"3Y38%-JC'9fC@a[
+F!#3"P!!EJ"L!0J&#MBi5b"#D@jKFRN!N!9N!'i!GJ$B"3T38%-JBQPZBA*j!*!&
+&!"Z!#-"9K!*4@4TG#"8CAKd@`#3"6)!EJ""!9F3!*!'&!!+!#3!BBJ(8fpeFQ0P
+1Jm!N!8b!!S!3J"KL!a%CA0dD@jKG'P[EMS!N!93!!S!B!"LL!Y*EQ0XG@4P)'PZ
+1Q`!!!!9!#J!+!%k!F3!!!%!!3#3"3)#!*!%&3!S!#J"1J(%!!!"!!%!N!8#!`#3
+"%i!!`#3"3S!#J$G!Bi!N!I`!33""!'2"!C%C@aPG'8!N!A`!'i""!$j"!G&C'Pd
+,LiZ!*!'m!!+!33!BJ3'3@4N,LiZ!!!!&3"`!'i!k`&E!!!"!!%!N!8#"!#3"+)!
+"!#3"4i!&!!`!13'#dCeE'`JFfpeFQ0PG!#3"6)!&!"%!13'$e"33b"NCACPE'p`
+E@9ZG1F!N!9'!"3!@!$N"Jmf1%XJBQPZBA*j,@pZE(RR!*!&@J!8!'`!j!B28&"$
+)'*TEQ&bH5e[EQajj`#3"3S!#J!D!1D)(P4jF'8JEfBJC'PcG(*TBR9dD@pZ)(4[
+)'*eD@aN1J!!!'i!"!#3"3S!#J$G!Bi!N!I`!6B""3'-"!T%DA0dFQPLGA4P!*!&
+m!$5!33",J3+3fKPBfXJG(*PC3#3"I!!#J%%!')%#NPZBfaeC'8Z,Li!N!A`!'i"
+"!$'"!G&H'0XG@4P!!!!!3!!!!5[!!!$V`!!!2)!cC58%83!!!!F!+B!!84-6dF!
+"!!54%P86!!%!%i#!*!)cC0`!J%!$`!!!"N!cC0i!J)!(J!!!IS!cC0X!J-!)`!!
+!K-!cC0S!J3!1J!!!Ri!cC0N!J$rr`!!!3)!N!3#!Irr!!!!-J#3"!)#rrm!!!-p
+!-f52!)$rrm!!!)X!*!%!J6rr`!!!TF!N!315@jME(9NC5"ND@&XEfF14AKME(9N
+C5"ND@&XEfF%6@&TEKC*EQ0XG@4P,f9iBfaeC'8JGfPZC'ph%84TFh4bD@*eG'P[
+EL"dHA"PJqX:
diff --git a/Mac/scripts/MkDistr_ui.py b/Mac/scripts/MkDistr_ui.py
new file mode 100644
index 0000000..f9192f5
--- /dev/null
+++ b/Mac/scripts/MkDistr_ui.py
@@ -0,0 +1,346 @@
+#
+# MkDistr - User Interface.
+#
+# Jack Jansen, CWI, August 1995
+#
+# XXXX To be done (requires mods of FrameWork and toolbox interfaces too):
+# - Give dialogs titles (need dlg->win conversion)
+# - Place dialogs better (???)
+# - <return> as <ok>
+# - big box around ok button
+# - window-close crashes on reopen (why?)
+# - Box around lists (???)
+# - Change cursor while busy (need cursor support in Qd)
+#
+import Res
+import Dlg
+import Ctl
+import List
+import Win
+import Qd
+from FrameWork import *
+import EasyDialogs
+import macfs
+
+# Resource IDs
+ID_MAIN = 514
+MAIN_LIST=1
+MAIN_MKDISTR=2
+MAIN_CHECK=3
+MAIN_INCLUDE=4
+MAIN_EXCLUDE=5
+
+ID_INCEXC=515
+INCEXC_DELETE=2
+INCEXC_CHANGE=3
+INCEXC_ADD=4
+
+ID_INCLUDE=512
+ID_EXCLUDE=513
+DLG_OK=1
+DLG_CANCEL=2
+DLG_FULL=3
+DLG_PPCDEV=4
+DLG_68K=5
+DLG_PPC=6
+DLG_BUTTONS=[DLG_FULL, DLG_PPCDEV, DLG_68K, DLG_PPC]
+DLG_LETTERS=['S', 'P', 'm', 'p']
+DLG_SRCPATH=7
+DLG_DSTPATH=8
+
+ID_DTYPE=516
+
+class EditDialogWindow(DialogWindow):
+	"""Include/exclude editor (modeless dialog window)"""
+	
+	def open(self, id, (type, src, dst), callback, cancelrv):
+		self.id = id
+		if id == ID_INCLUDE:
+			title = "Include file dialog"
+		else:
+			title = "Exclude pattern dialog"
+		#self.wid.as_Window().SetWTitle(title)
+		self.callback = callback
+		self.cancelrv = cancelrv
+		DialogWindow.open(self, id)
+		tp, h, rect = self.wid.GetDialogItem(DLG_SRCPATH)
+		Dlg.SetDialogItemText(h, src)
+		if id == ID_INCLUDE:
+			tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH)
+			Dlg.SetDialogItemText(h, dst)
+		for b in range(len(DLG_BUTTONS)):
+			if type == None or DLG_LETTERS[b] in type:
+				self.setbutton(DLG_BUTTONS[b], 1)
+
+	def setbutton(self, num, value):
+		tp, h, rect = self.wid.GetDialogItem(num)
+		h.as_Control().SetControlValue(value)
+		
+	def getbutton(self, num):
+		tp, h, rect = self.wid.GetDialogItem(num)
+		return h.as_Control().GetControlValue()
+	
+	def do_itemhit(self, item, event):
+		if item in (DLG_OK, DLG_CANCEL):
+			self.done(item)
+		elif item in DLG_BUTTONS:
+			v = self.getbutton(item)
+			self.setbutton(item, (not v))
+		# else it is not interesting
+		
+	def done(self, item):
+		if item == DLG_OK:
+			distlist = ''
+			for i in range(len(DLG_BUTTONS)):
+				if self.getbutton(DLG_BUTTONS[i]):
+					distlist = distlist + DLG_LETTERS[i]
+			tp, h, rect = self.wid.GetDialogItem(DLG_SRCPATH)
+			src = Dlg.GetDialogItemText(h)
+			if self.id == ID_INCLUDE:
+				tp, h, rect = self.wid.GetDialogItem(DLG_DSTPATH)
+				dst = Dlg.GetDialogItemText(h)
+				rv = (distlist, src, dst)
+			else:
+				rv = (distlist, src)
+		else:
+			rv = self.cancelrv
+		self.close()
+		self.callback((item==DLG_OK), rv)
+		
+class ListWindow(DialogWindow):
+	"""A dialog window containing a list as its main item"""
+	
+	def open(self, id, contents):
+		self.id = id
+		DialogWindow.open(self, id)
+		tp, h, rect = self.wid.GetDialogItem(MAIN_LIST)
+		rect2 = rect[0], rect[1], rect[2]-16, rect[3]-16	# Scroll bar space
+		self.list = List.LNew(rect2, (0, 0, 1, len(contents)), (0,0), 0, self.wid,
+				0, 1, 1, 1)
+		self.setlist(contents)
+
+	def setlist(self, contents):
+		self.list.LDelRow(0, 0)
+		self.list.LSetDrawingMode(0)
+		if contents:
+			self.list.LAddRow(len(contents), 0)
+			for i in range(len(contents)):
+				self.list.LSetCell(contents[i], (0, i))
+		self.list.LSetDrawingMode(1)
+		self.list.LUpdate()
+		
+	def additem(self, item):
+		where = self.list.LAddRow(1, 0)
+		self.list.LSetCell(item, (0, where))
+		
+	def delgetitem(self, item):
+		data = self.list.LGetCell(1000, (0, item))
+		self.list.LDelRow(1, item)
+		return data
+		
+	def do_listhit(self, event):
+		(what, message, when, where, modifiers) = event
+		Qd.SetPort(self.wid)
+		where = Qd.GlobalToLocal(where)
+		if self.list.LClick(where, modifiers):
+			self.do_dclick(self.delgetselection())
+		
+	def delgetselection(self):
+		items = []
+		point = (0,0)
+		while 1:
+			ok, point = self.list.LGetSelect(1, point)
+			if not ok:
+				break
+			items.append(point[1])
+			point = point[0], point[1]+1
+		values = []
+		items.reverse()
+		for i in items:
+			values.append(self.delgetitem(i))
+		return values
+		
+	def do_rawupdate(self, window, event):
+		self.list.LUpdate()
+		
+	def do_close(self):
+		self.close()
+		
+	def close(self):
+		del self.list
+		DialogWindow.close(self)
+		
+	def mycb_add(self, ok, item):
+		if item:
+			self.additem(item[1])
+			self.cb_add(item)
+		
+class MainListWindow(ListWindow):
+	"""The main window"""
+
+	def open(self, id, cb_check, cb_run, cb_add):
+		ListWindow.open(self, id, [])
+		title = "MkDistr: Unresolved files"
+		#self.wid.as_Window().SetWTitle(title)
+		self.cb_run = cb_run
+		self.cb_check = cb_check
+		self.cb_add = cb_add
+
+	def do_itemhit(self, item, event):
+		if item == MAIN_LIST:
+			self.do_listhit(event)
+		if item == MAIN_MKDISTR:
+			fss, ok = macfs.StandardPutFile('Destination folder:')
+			if not ok:
+				return
+			self.cb_run(fss.as_pathname())
+		if item == MAIN_CHECK:
+			list = self.cb_check()
+			self.setlist(list)
+		if item == MAIN_INCLUDE:
+			self.do_dclick(self.delgetselection())
+		if item == MAIN_EXCLUDE:
+			for i in self.delgetselection():
+				self.cb_add(('', i, ''))
+			
+	def do_dclick(self, list):
+		if not list:
+			list = ['']
+		for l in list:
+			w = EditDialogWindow(self.parent)
+			w.open(ID_INCLUDE, (None, l, ''), self.mycb_add, None)
+
+	def mycb_add(self, ok, item):
+		if item:
+			self.cb_add(item)
+
+class IncListWindow(ListWindow):
+	"""An include/exclude window"""
+	def open(self, id, editid, contents, cb_add, cb_del, cb_get):
+		ListWindow.open(self, id, contents)
+		if editid == ID_INCLUDE:
+			title = "MkDistr: files to include"
+		else:
+			title = "MkDistr: patterns to exclude"
+		#self.wid.as_Window().SetWTitle(title)
+		self.editid = editid
+		self.cb_add = cb_add
+		self.cb_del = cb_del
+		self.cb_get = cb_get
+
+	def do_itemhit(self, item, event):
+		if item == MAIN_LIST:
+			self.do_listhit(event)
+		if item == INCEXC_DELETE:
+			old = self.delgetselection()
+			for i in old:
+				self.cb_del(i)
+		if item == INCEXC_CHANGE:
+			self.do_dclick(self.delgetselection())
+		if item == INCEXC_ADD:
+			w = EditDialogWindow(self.parent)
+			w.open(self.editid, (None, '', ''), self.mycb_add, None)
+			
+	def do_dclick(self, list):
+		if not list:
+			list = ['']
+		for l in list:
+			old = self.cb_get(l)
+			self.cb_del(l)
+			w = EditDialogWindow(self.parent)
+			w.open(self.editid, old, self.mycb_add, old)
+
+class MkDistrUI(Application):
+	def __init__(self, main):
+		self.main = main
+		Application.__init__(self)
+		self.mwin = MainListWindow(self)
+		self.mwin.open(ID_MAIN, self.main.check, self.main.run, self.main.inc.add)
+		self.iwin = None
+		self.ewin = None	
+		
+	def makeusermenus(self):
+		self.filemenu = m = Menu(self.menubar, "File")
+		self.includeitem = MenuItem(m, "Show Include window", "", self.showinc)
+		self.excludeitem = MenuItem(m, "Show Exclude window", "", self.showexc)
+		self.saveitem = MenuItem(m, "Save databases", "S", self.save)
+		self.quititem = MenuItem(m, "Quit", "Q", self.quit)
+		
+	def quit(self, *args):
+		if self.main.is_modified():
+			rv = EasyDialogs.AskYesNoCancel('Database modified. Save?', -1)
+			if rv == -1:
+				return
+			if rv == 1:
+				self.main.save()
+		raise self
+		
+	def save(self, *args):
+		self.main.save()
+		
+	def showinc(self, *args):
+		if self.iwin:
+			if self._windows.has_key(self.iwin):
+				self.iwin.close()
+			del self.iwin
+		self.iwin = IncListWindow(self)
+		self.iwin.open(ID_INCEXC, ID_INCLUDE, self.main.inc.getall(), self.main.inc.add,
+			self.main.inc.delete, self.main.inc.get)
+		
+	def showexc(self, *args):
+		if self.ewin:
+			if self._windows.has_key(self.ewin):
+				self.ewin.close()
+			del self.ewin
+		self.ewin = IncListWindow(self)
+		self.ewin.open(ID_INCEXC, ID_EXCLUDE, self.main.exc.getall(), self.main.exc.add,
+			self.main.exc.delete, self.main.exc.get)
+
+	def do_about(self, id, item, window, event):
+		EasyDialogs.Message("Test the MkDistr user interface.")
+		
+def GetType():
+	"""Ask user for distribution type"""
+	d = Dlg.GetNewDialog(ID_DTYPE, -1)
+	while 1:
+		rv = ModalDialog(None)
+		if rv >= 1 and rv <= 4:
+			return DLG_LETTERS[rv-1]
+			
+def InitUI():
+	"""Initialize stuff needed by UI (a resource file)"""
+	Res.OpenResFile('MkDistr.rsrc')
+
+class _testerhelp:
+	def __init__(self, which):
+		self.which = which
+		
+	def get(self):
+		return [self.which+'-one', self.which+'-two']
+		
+	def add(self, value):
+		if value:
+			print 'ADD', self.which, value
+			
+	def delete(self, value):
+		print 'DEL', self.which, value
+		
+class _test:
+	def __init__(self):
+		import sys
+		Res.OpenResFile('MkDistr.rsrc')
+		self.inc = _testerhelp('include')
+		self.exc = _testerhelp('exclude')
+		self.ui = MkDistrUI(self)
+		self.ui.mainloop()
+		sys.exit(1)
+		
+	def check(self):
+		print 'CHECK'
+		return ['rv1', 'rv2']
+		
+	def run(self):
+		print 'RUN'
+		
+if __name__ == '__main__':
+	_test()
