Adding the BeOS port.  More checkins to follow.
diff --git a/BeOS/PyImport_BeImageID.html b/BeOS/PyImport_BeImageID.html
new file mode 100644
index 0000000..2d04528
--- /dev/null
+++ b/BeOS/PyImport_BeImageID.html
@@ -0,0 +1,47 @@
+<html>
+<head>
+<title>PyImport_BeImageID()</title>
+</head>
+<body text="#000000" bgcolor="#ffffff">
+
+<h1>PyImport_BeImageID()</h1>
+
+<dl compact>
+
+<dt><strong>NOTE:</strong><dt>
+
+<dd>This is documentation for the BeOS-specific 
+	<code>PyImport_BeImageID()</code> function defined in 
+	<tt>Python/importdl.c</tt>; it should be merged with the
+	<cite>Importing Modules</cite> section of the <cite>Python/C API</cite> 
+	reference (or it should be the first member of a BeOS-specific 
+	document in the <tt>BeOS</tt> directory).</dd>
+
+</dl>
+
+<dl compact
+
+<dt><code>image_id <b>PyImport_BeImageID</b>( char *<i>name</i> )</code></dt>
+
+<dd>Return the BeOS image ID (see the
+	<a href="file:///boot/beos/documentation/Be%20Book/The%20Kernel%20Kit/Images.html">Images</a>
+	section in the 
+	<a href="file:///boot/beos/documentation/Be%20Book/The%20Kernel%20Kit/index.html">Kernel 
+	Kit</a>) for the module object corresponding to a module <i>name</i>.
+	If the specified module is not dynamically loaded, 
+	<code>PyImport_BeImageID()</code> will return <code>B_ERROR</code>,
+	otherwise it will return a valid <code>image_id</code>.
+
+	<p>Using <code>PyImport_BeImageID()</code> outside of a BeOS-specific
+	module is probably a very bad idea.</p></dd>
+
+</dl>
+
+<hr>
+<p>Function added by Donn Cave 
+(<a href="mailto:donn@u.washington.edu"><tt>donn@u.washington.edu</tt></a>),
+documented by Chris Herborth
+(<a href="mailto:chrish@qnx.com"><tt>chrish@qnx.com</tt></a>).</p>
+
+</body>
+</html>
diff --git a/BeOS/README b/BeOS/README
new file mode 100644
index 0000000..c801afb
--- /dev/null
+++ b/BeOS/README
@@ -0,0 +1,140 @@
+Python 1.5.1 for BeOS
+
+This directory contains several useful things to help you build your own
+version of Python for BeOS.
+
+At this time, Python only supports BeOS on the PowerPC platform; if you'd
+like to help me port it to the x86 platform, please let me know (I only
+have limited access to BeOS on an x86 system).  If you'd like to lend
+me an x86 laptop running BeOS to do the port, _definitely_ let me know! :-)
+I'll even give it back when I'm done.
+
+What's Here?
+
+ar-1.1 - An "ar" command with a POSIX 1003.2 interface; you'll need
+         this for building the Python libraries under BeOS
+         (/bin/ar just won't cut it).
+
+linkcc - A shell script used by the build process to build the Python
+         shared library.
+
+linkmodule - A shell script used by the build process to build the
+             shared library versions of the standard modules; you'll
+             probably need this if you want to build dynamically loaded
+             modules from the Python archives.
+
+PyImport_BeImageID.html - Documentation for a function added to the
+                          Python interpreter under BeOS; not interesting
+                          unless you're writing your own BeOS-specific
+                          modules for dealing with dynamically-loaded
+                          Python modules.
+
+README - This file (obviously!).
+
+README.readline-2.2 - Instructions for compiling/installing GNU readline 2.2.
+                      You'll have to grab the GNU readline source code from 
+                      prep.ai.mit.edu:/pub/GNU or any other GNU mirror.
+
+                      The Python interpreter is much nicer to work with
+                      interactively if you've got readline installed.  Highly
+                      recommended.
+
+Compiling Your Own Version
+
+To compile your own version of Python 1.5.1 for BeOS (with any luck,
+Python 1.6 will compile "out of the box" on BeOS), try this:
+
+1) Get the Python 1.5.1 source code from ftp.python.org.
+
+2) Get the Python 1.5.1 diffs from my web pages 
+   (http://www.qnx.com/~chrish/Be/software/); if you can't get them through
+   a web browser, send me email and I'll mail them back to you.  These
+   diffs should also be available at ftp.python.org along with the BeOS
+   binary archive.
+   
+   Run autoconf.  If you don't have autoconf, you can get a precompiled
+   version from GeekGadgets (ftp://ftp.ninemoons.com/pub/geekgadgets/...).
+
+3) Compile and install the POSIX ar from the ar-1.1 directory; see the
+   README in there for details.
+
+4) Configure with:
+
+   AR=ar-posix RANLIB=: ./configure --verbose --without-gcc \
+   --prefix=/boot/home/config --with-thread
+   
+   The only strange thing that happens during the configure is that
+   we fail the "genuine getopt()" test; this is odd because we've got
+   a real live GNU getopt() in the system libs.  Other packages built
+   using configure (such as all of the goodies in GeekGadgets) suffer
+   the same fate though, so it's not a Python problem.
+
+5) Copy Modules/Setup.in to Modules/Setup.
+
+6) Edit Modules/Setup to turn on all the modules you want built.  I've
+   personally built the following modules:
+
+   array, audioop, binascii, cPickle, cStringIO, cmath, crypt, curses,
+   errno, fcntl, gdbm, grp, imageop, math, md5, new, operator, parser,
+   pcre, posix, pwd, readline, regex, reop, rgbimg, rotor, select,
+   signal, socket, soundex, strop, struct, syslog, termios, thread,
+   time, timing, zlib
+
+   Newly compiled/tested with 1.5.1:
+   
+   _locale
+
+   You can get precompiled gdbm, ncurses, and zlib libraries from the
+   GeekGadgets repository (ftp://ftp.ninemoons.com/pub/geekgadgets/...).
+   
+   Make sure you use _socket instead of socket for the name of the
+   socketmodule on BeOS.
+
+7) Make:
+
+   make
+   
+   or, if you feel the need for speed:
+   
+   make OPT="-O7 -opt schedule604"
+   
+   You can safely ignore any warnings you see during the build (and you'll
+   see several if you use full warnings; I compiled the distribution with
+   -w9 -ansi strict and cleaned up any errors...).
+
+8) Test:
+
+   make test
+
+   Expect the following errors:
+
+   test_builtin failed -- round(1000000000.0)
+   test_fcntl skipped -- an optional feature could not be imported
+   test_grp crashed -- exceptions.KeyError : getgrnam(): name not found
+   test_pwd failed -- Writing: 'fakename', expected: 'caught e'
+   test_socket crashed -- exceptions.AttributeError : SOCK_RAW
+
+   These are all due to either partial support for certain things (like
+   sockets), or valid differences between systems (like the round()
+   error; different CPUs represent floating point numbers differently,
+   which can cause minor rounding errors).
+
+9) Install:
+
+   make install
+
+10) Enjoy!
+
+NOTE
+
+If you're going to build your own C/C++-based Python modules, link them
+against the libpython1.5.so shared library (in /boot/home/config/lib)
+instead of the libpython1.5.a (in /boot/home/config/lib/python1.5/config),
+unless you're building a statically-linked python interpreter (then you
+could try linking against _APP_ instead).
+
+Mixing modules linked against the shared library with a statically-linked
+interpreter is a bad idea (and it'll fail in _interesting_ ways).
+
+- Chris Herborth (chrish@qnx.com)
+  April 25, 1998
diff --git a/BeOS/README.readline-2.2 b/BeOS/README.readline-2.2
new file mode 100644
index 0000000..db53ac9
--- /dev/null
+++ b/BeOS/README.readline-2.2
@@ -0,0 +1,56 @@
+GNU readline 2.2 for BeOS
+
+You can get the original GNU readline 2.2 source code from your favourite
+GNU software repository, such as ftp://prep.ai.mit.edu/pub/gnu/.
+
+You can get the only-slightly-modified-for-BeOS version of GNU readline 2.2
+from the GeekGadgets repository; ftp://ftp.ninemoons.com/pub/geekgadgets/.
+
+BUILDING libreadline for BeOS hosts
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Note that we don't build a shared library version of libreadline and
+libhistory.  That's left as an exercise for the reader.
+
+You won't be able to link against libreadline.a using the limited linker.
+
+1) If you're on a PowerPC system, install the POSIX ar from 
+   http://www.qnx.com/~chrish/Be/software/index.html#programming
+   (note that it's currently packaged with Python, in the BeOS/ar-1.1
+   directory).
+   
+   If you're on an x86 system, you can leave out the "AR=ar-posix" part
+   of the following instructions.  In fact, you'll have to...
+
+2) For PowerPC, configure with:
+
+   CC=mwcc CFLAGS="-O7 -i- -I." AR=ar-posix RANLIB=: ./configure --verbose \
+   --without-gcc --prefix=/boot/home/config powerpc-*-beos
+
+   For x86, configure with:
+   
+   CC=mwcc CFLAGS="-O2 -i- -I." RANLIB=: ./configure --verbose \
+   --without-gcc --prefix=/boot/home/config x86-*-beos
+
+   Don't worry about the warnings/errors configure spews for
+   powerpc-*-beos or x86-*-beos; readline doesn't actually use this host 
+   information    for anything, although configure will die if you don't 
+   specify it.
+
+3) Edit config.h to comment out "#define HAVE_SELECT 1"; select() on
+   BeOS doesn't work on file descriptors (such as stdin).
+
+4) For PowerPC, make with:
+
+   make AR=ar-posix 
+
+   For x86, make with:
+   
+   make
+
+5) Install with:
+
+   make install
+
+- Chris Herborth (chrish@qnx.com)
+  April 21, 1998
diff --git a/BeOS/ar-1.1/Makefile b/BeOS/ar-1.1/Makefile
new file mode 100644
index 0000000..8fb11ec
--- /dev/null
+++ b/BeOS/ar-1.1/Makefile
@@ -0,0 +1,48 @@
+######################################################################
+# Makefile for ar
+#
+# Dec. 14, 1997 Chris Herborth (chrish@kagi.com)
+#
+# $Id$
+######################################################################
+
+AR_VERSION=1.1
+
+# Make variables
+CC=mwcc
+LD=mwcc
+
+CFLAGS=-w9 -rostr -O3 -g
+CFLAGS_O=-w9 -rostr -O7 -opt schedule604
+LDFLAGS=-g -map ar.xMAP
+LDFLAGS_O=
+
+INSTALL=install -m 755
+
+DESTINATION=/boot/home/config/bin
+
+PARTS=main.o mwlib.o commands.o copy_attrs.o
+
+all: ar
+
+nodebug:
+	-rm -f ar $(PARTS) ar.dbg ar.xSYM
+	$(MAKE) CFLAGS="$(CFLAGS_O) -DNO_DEBUG" LDFLAGS="$(LDFLAGS_O)" ar
+
+ar: $(PARTS)
+	$(LD) $(LDFLAGS) -o $@ $(PARTS)
+
+install: ar
+	$(INSTALL) ar $(DESTINATION)
+	ln -sf $(DESTINATION)/ar $(DESTINATION)/ar-posix
+
+clean:
+	-rm -f $(PARTS) ar ar.dbg ar.xSYM
+
+zip:
+	(cd .. ; zip -9ry ar-$(AR_VERSION).zip ar-$(AR_VERSION) \
+		-x ar-$(AR_VERSION)/RCS -x ar-$(AR_VERSION)/docs/RCS \
+		-x ar-$(AR_VERSION)/RCS/\* -x ar-$(AR_VERSION)/docs/RCS/\*)
+
+%.o: %.c
+	$(CC) $(CFLAGS) -c $< -o $@
diff --git a/BeOS/ar-1.1/README.html b/BeOS/ar-1.1/README.html
new file mode 100644
index 0000000..607c03a
--- /dev/null
+++ b/BeOS/ar-1.1/README.html
@@ -0,0 +1 @@
+docs/ar.html
\ No newline at end of file
diff --git a/BeOS/ar-1.1/README.txt b/BeOS/ar-1.1/README.txt
new file mode 100644
index 0000000..f995789
--- /dev/null
+++ b/BeOS/ar-1.1/README.txt
@@ -0,0 +1,29 @@
+ar - POSIX 1003.2 interface to library files
+
+Here's the source and PowerPC binary for a POSIX 1003.2 interface "ar"
+command; this is extremely useful when you're porting complex UNIX/POSIX
+software to BeOS for PowerPC (I originally wrote it to support my Python
+port).
+
+To build/install ar, do this in a Terminal:
+
+make nodebug install
+
+This will create ar and ar-posix (a symlink to ar) in ~/config/bin.  The
+ar-posix symlink is to make things a little easier if you happen to
+have GeekGadgets (see www.ninemoons.com) installed; it comes with an
+ar that only works on objects/libraries produced by GNU C for BeOS.
+
+To use the POSIX ar with your port, do something like this:
+
+AR=ar-posix ./configure ... normal configure arguments ...
+
+and then:
+
+make AR=ar-posix
+
+You may need to check the Makefiles; people seem to be quite sloppy about
+using just plain "ar cr libfoo.a ..." instead of "$(AR) cr libfoo.a ...".
+
+- Chris Herborth, April 18, 1998
+  (chrish@kagi.com)
diff --git a/BeOS/ar-1.1/ar b/BeOS/ar-1.1/ar
new file mode 100644
index 0000000..e44e2dc
--- /dev/null
+++ b/BeOS/ar-1.1/ar
Binary files differ
diff --git a/BeOS/ar-1.1/ar.xMAP b/BeOS/ar-1.1/ar.xMAP
new file mode 100644
index 0000000..bee438d
--- /dev/null
+++ b/BeOS/ar-1.1/ar.xMAP
@@ -0,0 +1,461 @@
+File:    0	"/boot/src/ar-1.0/main.c"
+File:    1	"/boot/src/ar-1.0/mwlib.c"
+File:    2	"/boot/src/ar-1.0/commands.c"
+File:    3	"/boot/src/ar-1.0/copy_attrs.c"
+File:    5	"/boot/rel/src/kit/glue/common/global_destructor_chain.c"
+File:    6	"/boot/rel/src/kit/glue/ppc/runtime.c"
+File:    9	"/boot/rel/src/kit/glue/common/init_term_dyn.c"
+File:   10	"/boot/rel/src/kit/glue/common/start_dyn.c"
+File:   11	"/boot/develop/lib/ppc/libroot.so"
+
+Files that were not referenced:
+"libbe.so"
+"libtracker.so"
+"libmedia.so"
+"libnet.so"
+"libnetdev.so"
+"libdevice.so"
+"libmidi.so"
+"libgame.so"
+"libatalk.so"
+"libmail.so"
+
+Code section, size = 16672 bytes
+000000	PR 	.__sinit									file = "*Linker-Generated*"
+00001C	PR 	.usage										file = "main.c"
+000050	PR 	.version
+000094	PR 	.check_command
+000128	PR 	.main
+0005A0	PR 	.load_MW_lib								file = "mwlib.c"
+000A1C	PR 	.load_MWLibFile
+000BAC	PR 	.fwrite_big32
+000C10	PR 	.fwrite_big32_seek
+000CA4	PR 	.add_object_sizes
+000DA4	PR 	.setfiletype
+000EA8	PR 	.write_MW_lib
+001850	PR 	.do_match									file = "commands.c"
+001958	PR 	.do_delete
+001A84	PR 	.delete_lib_entry
+001C5C	PR 	.do_print
+001D98	PR 	.print_lib_entry
+001E90	PR 	.load_lib_file
+0020F4	PR 	.do_replace
+0023B8	PR 	.add_lib_entry
+00256C	PR 	.replace_lib_entry
+00272C	PR 	.do_table
+002868	PR 	.table_lib_entry
+0029E8	PR 	.do_extract
+002B24	PR 	.extract_lib_entry
+002E20	PR 	.copy_attrs									file = "copy_attrs.c"
+00306C	PR 	.__destroy_global_chain						file = "global_destructor_chain.c"
+0030C0	PR 	.__RTOC										file = "init_term_dyn.c"
+0030C8	PR 	._init_routine_
+003118	PR 	._term_routine_
+003148	PR 	.__start									file = "start_dyn.c"
+003204	GL 	.__register_fragment						file = "*Linker-Generated*"
+00321C	GL 	.find_thread
+003234	GL 	.memcpy
+00324C	GL 	._call_init_routines_
+003264	GL 	.printf
+00327C	GL 	.exit
+003294	GL 	.getopt
+0032AC	GL 	.malloc
+0032C4	GL 	.__assertion_failed
+0032DC	GL 	.fprintf
+0032F4	GL 	.fopen
+00330C	GL 	.fread
+003324	GL 	.fseek
+00333C	GL 	.fgets
+003354	GL 	.strdup
+00336C	GL 	.fclose
+003384	GL 	.strrchr
+00339C	GL 	.strcmp
+0033B4	GL 	.free
+0033CC	GL 	.memset
+0033E4	GL 	.access
+0033FC	GL 	.stat
+003414	GL 	._errnop
+00342C	GL 	.strerror
+003444	GL 	.strlen
+00345C	GL 	.sprintf
+003474	GL 	.unlink
+00348C	GL 	.rename
+0034A4	GL 	.fwrite
+0034BC	GL 	.ftell
+0034D4	GL 	.chmod
+0034EC	GL 	.open
+003504	GL 	.close
+00351C	GL 	.fs_fopen_attr_dir
+003534	GL 	.fs_read_attr_dir
+00354C	GL 	.fs_stat_attr
+003564	GL 	.fs_read_attr
+00357C	GL 	.fs_write_attr
+003594	GL 	.fflush
+0035AC	GL 	.realloc
+0035C4	GL 	.localtime
+0035DC	GL 	.strftime
+0035F4	GL 	.getgid
+00360C	GL 	.getuid
+003624	GL 	.utime
+00363C	GL 	._thread_do_exit_notification
+003654	GL 	.__unregister_fragment
+00366C	GL 	.__ptr_glue									file = "runtime.c"
+003680	RO 	@10											file = "main.c"
+003690	RO 	@13
+0036B4	RO 	@16
+0036D8	RO 	@17
+0036FC	RO 	@18
+003739	RO 	@30
+003769	RO 	@109
+00378A	RO 	@110
+0037A2	RO 	@111
+0037BA	RO 	@112
+0037D3	RO 	@113
+0037DD	RO 	@114
+0037FD	RO 	@115
+003815	RO 	@116
+003829	RO 	@117
+00383D	RO 	@118
+003871	RO 	@119
+00388C	RO 	@120
+0038A5	RO 	@121
+0038B9	RO 	@78											file = "mwlib.c"
+0038C3	RO 	@79
+0038CB	RO 	@80
+0038DA	RO 	@81
+0038DC	RO 	@98
+0038E7	RO 	@99
+0038F5	RO 	@104
+0038FE	RO 	@122
+003908	RO 	@123
+003913	RO 	@124
+00391E	RO 	@133
+003947	RO 	@134
+003951	RO 	@135
+00397B	RO 	@235
+003980	RO 	@236
+0039AC	RO 	@237
+0039C3	RO 	@238
+0039F5	RO 	@239
+0039F9	RO 	@240
+003A12	RO 	@241
+003A33	RO 	@242
+003A35	RO 	@243
+003A56	RO 	@244
+003A7B	RO 	@245
+003AA7	RO 	@246
+003AD1	RO 	@247
+003AF0	RO 	@248
+003B14	RO 	@249
+003B3D	RO 	@250
+003B69	RO 	@251
+003B90	RO 	@252
+003BBB	RO 	@253
+003BD8	RO 	@254
+003BF1	RO 	@255
+003C11	RO 	@29											file = "commands.c"
+003C1B	RO 	@30
+003C26	RO 	@31
+003C31	RO 	@32
+003C3B	RO 	@53
+003C4E	RO 	@54
+003C65	RO 	@55
+003C7D	RO 	@81
+003C9E	RO 	@82
+003CA6	RO 	@120
+003CAE	RO 	@121
+003CC5	RO 	@142
+003CD4	RO 	@143
+003CDF	RO 	@144
+003CF6	RO 	@145
+003D0C	RO 	@146
+003D2E	RO 	@147
+003D30	RO 	@148
+003D47	RO 	@149
+003D5E	RO 	@198
+003D6F	RO 	@199
+003D89	RO 	@200
+003DAA	RO 	@222
+003DCF	RO 	@223
+003DE8	RO 	@224
+003E12	RO 	@225
+003E1A	RO 	@242
+003E39	RO 	@243
+003E65	RO 	@244
+003E6D	RO 	@284
+003E85	RO 	@285
+003E88	RO 	@286
+003E9F	RO 	@287
+003EBE	RO 	@288
+003EC9	RO 	@289
+003ECD	RO 	@343
+003EE6	RO 	@344
+003EEE	RO 	@345
+003EF0	RO 	@346
+003F11	RO 	@347
+003F27	RO 	@348
+003F53	RO 	@349
+003F7E	RO 	@350
+003F97	RO 	@43											file = "copy_attrs.c"
+003FA6	RO 	@44
+003FB3	RO 	@45
+003FC4	TI 	@14											file = "main.c"
+003FD0	TI 	@19
+003FDC	TI 	@32
+003FE8	TI 	@124
+003FF4	TI 	@82											file = "mwlib.c"
+004000	TI 	@100
+00400C	TI 	@105
+004018	TI 	@111
+004024	TI 	@125
+004030	TI 	@136
+00403C	TI 	@256
+004048	TI 	@33											file = "commands.c"
+004054	TI 	@56
+004060	TI 	@83
+00406C	TI 	@110
+004078	TI 	@122
+004084	TI 	@150
+004090	TI 	@201
+00409C	TI 	@226
+0040A8	TI 	@245
+0040B4	TI 	@272
+0040C0	TI 	@290
+0040CC	TI 	@317
+0040D8	TI 	@351
+0040E4	TI 	@46											file = "copy_attrs.c"
+0040F0	TI 	@7											file = "global_destructor_chain.c"
+0040FC	TI 	@2											file = "init_term_dyn.c"
+004108	TI 	@4
+004114	TI 	@17											file = "start_dyn.c"
+
+Data section, size = 1084 bytes (TOC anchor = 000000)
+000000	TC 	fs_write_attr								file = "*Linker-Generated*"
+000004	TC 	strftime
+000008	TC 	fwrite
+00000C	TC 	sprintf
+000010	TC 	open
+000014	TC 	fread
+000018	TC 	fs_fopen_attr_dir
+00001C	TC 	fseek
+000020	TC 	strrchr
+000024	TC 	free
+000028	TC 	printf
+00002C	TC 	ftell
+000030	TC 	exit
+000034	TC 	strerror
+000038	TC 	__register_fragment
+00003C	TC 	memcpy
+000040	TC 	strcmp
+000044	TC 	strlen
+000048	TC 	_call_init_routines_
+00004C	TC 	strdup
+000050	TC 	_files
+000054	TC 	fgets
+000058	TC 	malloc
+00005C	TC 	find_thread
+000060	TC 	close
+000064	TC 	memset
+000068	TC 	chmod
+00006C	TC 	fopen
+000070	TC 	stat
+000074	TC 	fs_read_attr
+000078	TC 	access
+00007C	TC 	fs_read_attr_dir
+000080	TC 	unlink
+000084	TC 	getopt
+000088	TC 	getgid
+00008C	TC 	__unregister_fragment
+000090	TC 	_errnop
+000094	TC 	fprintf
+000098	TC 	optind
+00009C	TC 	__assertion_failed
+0000A0	TC 	rename
+0000A4	TC 	utime
+0000A8	TC 	getuid
+0000AC	TC 	fs_stat_attr
+0000B0	TC 	fflush
+0000B4	TC 	_thread_do_exit_notification
+0000B8	TC 	fclose
+0000BC	TC 	localtime
+0000C0	TC 	realloc
+0000C4	TC 	__global_destructor_chain
+0000C8	TC 	__exception_table_end__
+0000CC	TC 	__exception_table_start__
+0000D0	TC 	__data_end__
+0000D4	TC 	__data_start__
+0000D8	TC 	__code_end__
+0000DC	TC 	__code_start__
+0000E0	TC 	__main_thread_id
+0000E4	TC 	environ
+0000E8	TC 	argv_save
+0000EC	TC 	@123										file = "main.c"
+0000F0	TC 	@122
+0000F4	TC 	@121
+0000F8	TC 	@120
+0000FC	TC 	@119
+000100	TC 	@118
+000104	TC 	@117
+000108	TC 	@116
+00010C	TC 	@115
+000110	TC 	@114
+000114	TC 	@113
+000118	TC 	@112
+00011C	TC 	@111
+000120	TC 	@110
+000124	TC 	@109
+000128	TC 	@31
+00012C	TC 	@30
+000130	TC 	@18
+000134	TC 	@17
+000138	TC 	@16
+00013C	TC 	@13
+000140	TC 	@255										file = "mwlib.c"
+000144	TC 	@254
+000148	TC 	@253
+00014C	TC 	@252
+000150	TC 	@251
+000154	TC 	@250
+000158	TC 	@249
+00015C	TC 	@248
+000160	TC 	@247
+000164	TC 	@246
+000168	TC 	@245
+00016C	TC 	@244
+000170	TC 	@243
+000174	TC 	@242
+000178	TC 	@241
+00017C	TC 	@240
+000180	TC 	@239
+000184	TC 	@238
+000188	TC 	@237
+00018C	TC 	@236
+000190	TC 	@235
+000194	TC 	@135
+000198	TC 	@134
+00019C	TC 	@133
+0001A0	TC 	@124
+0001A4	TC 	@123
+0001A8	TC 	@122
+0001AC	TC 	@104
+0001B0	TC 	@99
+0001B4	TC 	@98
+0001B8	TC 	@81
+0001BC	TC 	@80
+0001C0	TC 	@79
+0001C4	TC 	@78
+0001C8	TC 	@350										file = "commands.c"
+0001CC	TC 	@349
+0001D0	TC 	@348
+0001D4	TC 	@347
+0001D8	TC 	@346
+0001DC	TC 	@345
+0001E0	TC 	@344
+0001E4	TC 	@343
+0001E8	TC 	@289
+0001EC	TC 	@288
+0001F0	TC 	@287
+0001F4	TC 	@286
+0001F8	TC 	@285
+0001FC	TC 	@284
+000200	TC 	@244
+000204	TC 	@243
+000208	TC 	@242
+00020C	TC 	@225
+000210	TC 	@224
+000214	TC 	@223
+000218	TC 	@222
+00021C	TC 	@200
+000220	TC 	@199
+000224	TC 	@198
+000228	TC 	@149
+00022C	TC 	@148
+000230	TC 	@147
+000234	TC 	@146
+000238	TC 	@145
+00023C	TC 	@144
+000240	TC 	@143
+000244	TC 	@142
+000248	TC 	@121
+00024C	TC 	@120
+000250	TC 	@82
+000254	TC 	@81
+000258	TC 	@55
+00025C	TC 	@54
+000260	TC 	@53
+000264	TC 	@32
+000268	TC 	@31
+00026C	TC 	@30
+000270	TC 	@29
+000274	TC 	@45											file = "copy_attrs.c"
+000278	TC 	@44
+00027C	TC 	@43
+000280	TC 	magic_template								file = "start_dyn.c"
+000284	TC 	default_environ
+000288	TD 	ar_version_id								file = "main.c"
+00028C	TD 	fragmentID									file = "init_term_dyn.c"
+000290	DS 	_term_routine_								file = "init_term_dyn.c"
+000298	DS 	_init_routine_
+0002A0	DS 	__start										file = "start_dyn.c"
+0002A8	RW 	@31											file = "main.c"
+0002FC	RW 	@123
+000388	RW 	@122
+000414	RW 	magic_template								file = "start_dyn.c"
+00041C	RW 	@13
+00042C	RW 	default_environ
+000434	RW 	__global_destructor_chain					file = "global_destructor_chain.c"
+
+Import container "libroot.so"
+Current Version = 00000000, Old Implementation = 00000000
+000000	DS 	fs_write_attr
+000001	DS 	strftime
+000002	DS 	fwrite
+000003	DS 	sprintf
+000004	DS 	open
+000005	DS 	fread
+000006	DS 	fs_fopen_attr_dir
+000007	DS 	fseek
+000008	DS 	strrchr
+000009	DS 	free
+00000A	RW 	environ
+00000B	DS 	printf
+00000C	DS 	ftell
+00000D	DS 	exit
+00000E	DS 	strerror
+00000F	DS 	__register_fragment
+000010	DS 	memcpy
+000011	DS 	strcmp
+000012	DS 	strlen
+000013	DS 	_call_init_routines_
+000014	DS 	strdup
+000015	RW 	argv_save
+000016	RW 	_files
+000017	DS 	fgets
+000018	DS 	malloc
+000019	DS 	find_thread
+00001A	DS 	close
+00001B	DS 	memset
+00001C	DS 	chmod
+00001D	DS 	fopen
+00001E	DS 	stat
+00001F	DS 	fs_read_attr
+000020	DS 	access
+000021	DS 	fs_read_attr_dir
+000022	DS 	unlink
+000023	DS 	getopt
+000024	DS 	getgid
+000025	DS 	__unregister_fragment
+000026	DS 	_errnop
+000027	DS 	fprintf
+000028	RW 	optind
+000029	DS 	__assertion_failed
+00002A	DS 	rename
+00002B	DS 	utime
+00002C	RW 	__main_thread_id
+00002D	DS 	getuid
+00002E	DS 	fs_stat_attr
+00002F	DS 	fflush
+000030	DS 	_thread_do_exit_notification
+000031	DS 	fclose
+000032	DS 	localtime
+000033	DS 	realloc
diff --git a/BeOS/ar-1.1/commands.c b/BeOS/ar-1.1/commands.c
new file mode 100644
index 0000000..f9304d0
--- /dev/null
+++ b/BeOS/ar-1.1/commands.c
@@ -0,0 +1,809 @@
+/*
+** commands.c - POSIX 1003.2 "ar" command
+**
+** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks
+** Library files, not general-purpose POSIX 1003.2 format archives.
+**
+** Dec. 14, 1997 Chris Herborth (chrish@kagi.com)
+**
+** This code is donated to the PUBLIC DOMAIN.  You can use, abuse, modify,
+** redistribute, steal, or otherwise manipulate this code.  No restrictions
+** at all.  If you laugh at this code, you can't use it.
+**
+** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for
+** the interface, and Metrowerk's published docs detailing their library
+** format.  Look inside for clues about how reality differs from MW's
+** documentation on BeOS...
+*/
+
+#include <support/Errors.h>
+#include <support/byteorder.h>
+#ifndef NO_DEBUG
+#include <assert.h>
+#define ASSERT(cond) assert(cond)
+#else
+#define ASSERT(cond) ((void)0)
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <utime.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "mwlib.h"
+#include "commands.h"
+
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+static const char *rcs_version_id = "$Id$";
+
+/* ----------------------------------------------------------------------
+** Local functions
+**
+** do_match() - find the index of the file, if it's in the archive; return
+**              TRUE if found, else FALSE
+**/
+static int do_match( MWLib *lib, const char *file, int *idx );
+
+static int do_match( MWLib *lib, const char *file, int *idx )
+{
+	int which = 0;
+	char *name_ptr;
+
+	ASSERT( lib != NULL );
+	ASSERT( file != NULL );
+	ASSERT( idx != NULL );
+
+	/* Skip over the path, if any, so we can compare just the file name.
+	*/
+	name_ptr = strrchr( file, '/' );
+	if( name_ptr == NULL ) {
+		name_ptr = (char *)file;
+	} else {
+		name_ptr++;
+	}
+
+	for( which = 0; which < lib->header.num_objects; which++ ) {
+		if( !strcmp( name_ptr, lib->names[which] ) ) {
+			*idx = which;
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+/* ----------------------------------------------------------------------
+** Delete an archive member.
+**
+** This isn't really optimal; you could make a more efficient version
+** using a linked list instead of arrays for the data.  This was easier
+** to write, and speed shouldn't be that big a deal here... you're not
+** likely to be dealing with thousands of files.
+*/
+static status_t delete_lib_entry( MWLib *lib, int idx, int verbose );
+
+status_t do_delete( const char *archive_name, char **files, int verbose )
+{
+	status_t retval = B_OK;
+	MWLib lib;
+	int idx = 0;
+	int which = 0;
+
+	ASSERT( archive_name != NULL );
+
+	if( files == NULL ) {
+		fprintf( stderr, "ar: %s, nothing to do\n", archive_name );
+		return B_ERROR;
+	}
+
+	retval = load_MW_lib( &lib, archive_name );
+	if( retval != B_OK ) {
+		switch( retval ) {
+		case B_FILE_NOT_FOUND:
+			fprintf( stderr, "ar: %s, file not found\n", archive_name );
+			return retval;
+			break;
+			
+		default:
+			return retval;
+			break;
+		}
+	}
+
+	/* Delete the specified files.
+	*/
+	for( idx = 0; files[idx] != NULL; idx++ ) {
+		if( do_match( &lib, files[idx], &which ) ) {
+			retval = delete_lib_entry( &lib, which, verbose );
+		}
+		which = 0;
+	}
+
+	/* Write the new file.
+	*/
+	retval = write_MW_lib( &lib, archive_name );
+
+	return retval;
+}
+
+static status_t delete_lib_entry( MWLib *lib, int which, int verbose )
+{
+	uint32 new_num;
+	MWLibFile *new_files = NULL;
+	char **new_names = NULL;
+	char **new_data = NULL;
+	int ctr = 0;
+	int idx = 0;
+
+	ASSERT( lib != NULL );
+	ASSERT( which <= lib->header.num_objects );
+
+	new_num = lib->header.num_objects - 1;
+
+	new_files = (MWLibFile *)malloc( new_num * ( sizeof( MWLibFile ) ) );
+	new_names = (char **)malloc( new_num * ( sizeof( char * ) ) );
+	new_data = (char **)malloc( new_num * ( sizeof( char * ) ) );
+	if( new_files == NULL || new_names == NULL || new_data == NULL ) {
+		return B_NO_MEMORY;
+	}
+
+	/* Copy the contents of the old lib to the new lib, skipping the one
+	** we want to delete.
+	*/
+	for( ctr = 0; ctr < lib->header.num_objects; ctr++ ) {
+		if( ctr != which ) {
+			memcpy( &(new_files[idx]), &(lib->files[ctr]), 
+					sizeof( MWLibFile ) );
+			new_names[idx] = lib->names[ctr];
+			new_data[idx] = lib->data[ctr];
+
+			idx++;
+		} else { 
+			/* Free up the name and data.
+			*/
+			if( verbose ) {
+				printf( "d - %s\n", lib->names[ctr] );
+			}
+
+			free( lib->names[idx] );
+			lib->names[idx] = NULL;
+			free( lib->data[idx] );
+			lib->data[idx] = NULL;
+		}
+	}
+
+	/* Free up the old lib's data.
+	*/
+	free( lib->files );
+	free( lib->names );
+	free( lib->data );
+
+	lib->files = new_files;
+	lib->names = new_names;
+	lib->data = new_data;
+
+	lib->header.num_objects = new_num;
+
+	return B_OK;
+}
+
+/* ----------------------------------------------------------------------
+** Print an archive member to stdout.
+*/
+static status_t print_lib_entry( MWLib *lib, int idx, int verbose );
+
+status_t do_print( const char *archive_name, char **files, int verbose )
+{
+	status_t retval = B_OK;
+	MWLib lib;
+	int idx = 0;
+
+	ASSERT( archive_name != NULL );
+
+	retval = load_MW_lib( &lib, archive_name );
+	if( retval != B_OK ) {
+		switch( retval ) {
+		case B_FILE_NOT_FOUND:
+			fprintf( stderr, "ar: %s, file not found\n", archive_name );
+			return retval;
+			break;
+
+		default:
+			return retval;
+			break;
+		}
+	}
+
+	if( files == NULL ) {
+		/* Then we print the entire archive.
+		*/
+		for( idx = 0; idx < lib.header.num_objects; idx++ ) {
+			retval = print_lib_entry( &lib, idx, verbose );
+		}
+	} else {
+		/* Then we print the specified files.
+		*/
+		int which = 0;
+
+		for( idx = 0; files[idx] != NULL; idx++ ) {
+			if( do_match( &lib, files[idx], &which ) ) {
+				retval = print_lib_entry( &lib, which, verbose );
+			}
+			which = 0;
+		}
+	}
+
+	return retval;
+}
+
+static status_t print_lib_entry( MWLib *lib, int idx, int verbose )
+{
+	int recs;
+
+	ASSERT( lib != NULL );
+
+	if( verbose ) {
+		printf( "\n<%s>\n\n", lib->names[idx] );
+	}
+
+	recs = fwrite( lib->data[idx], lib->files[idx].object_size, 1, stdout );
+	fflush( stdout );
+	if( recs != 1 ) {
+		fprintf( stderr, "error printing %s, %s\n", lib->names[idx],
+				 strerror( errno ) );
+		return B_OK;
+	}
+
+	return B_OK;
+}
+
+/* ----------------------------------------------------------------------
+** Add/replace/update files in an archive.
+*/
+static status_t add_lib_entry( MWLib *lib, const char *filename, int verbose );
+static status_t replace_lib_entry( MWLib *lib, const char *filename, 
+								   int idx, int verbose );
+static status_t load_lib_file( const char *filename,
+							   char **data, MWLibFile *info );
+
+static status_t load_lib_file( const char *filename,
+							   char **data, MWLibFile *info )
+{
+	status_t retval = B_OK;
+	struct stat s;
+	FILE *fp;
+	uint32 recs;
+
+	ASSERT( filename != NULL );
+	ASSERT( info != NULL );
+
+	/* Initialize the info area.
+	*/
+	info->m_time = (time_t)0;	/* Only this... */
+	info->off_filename = 0;
+	info->off_fullpath = 0;
+	info->off_object = 0;
+	info->object_size = 0;		/* ... and this will actually be updated. */
+
+	/* stat() the file to get the info we need.
+	*/
+	retval = stat( filename, &s );
+	if( retval != 0 ) {
+		fprintf( stderr, "ar: can't stat %s, %s\n", filename,
+				 strerror( errno ) );
+		return B_FILE_NOT_FOUND;
+	}
+
+	/* Possible errors here; if you have an object that's larger
+	** than a size_t can hold (malloc() can only allocate a size_t size,
+	** not a full off_t)...
+	*/
+	if( s.st_size > (off_t)ULONG_MAX ) {
+		fprintf( stderr, "ar: %s is too large!\n", filename );
+		return B_NO_MEMORY;
+	}
+
+	/* Allocate enough memory to hold the file data.
+	*/
+	*data = (char *)malloc( (size_t)s.st_size );
+	if( *data == NULL ) {
+		fprintf( stderr, "ar: can't allocate memory for %s\n", filename );
+		return B_NO_MEMORY;
+	}
+
+	/* Read the file's data.
+	*/
+	fp = fopen( filename, "r" );
+	if( fp == NULL ) {
+		fprintf( stderr, "ar: can't open %s, %s\n", filename,
+				 strerror( errno ) );
+		retval = B_FILE_NOT_FOUND;
+		goto free_data_return;
+	}
+
+	recs = fread( *data, (size_t)s.st_size, 1, fp );
+	if( recs != 1 ) {
+		fprintf( stderr, "ar: can't read %s, %s\n", filename,
+				 strerror( errno ) );
+		retval = B_IO_ERROR;
+		goto close_fp_return;
+	}
+
+	fclose( fp );
+
+	/* Now that all the stuff that can fail has succeeded, fill in the info
+	** we need.
+	*/
+	info->m_time = s.st_mtime;
+	info->object_size = (uint32)s.st_size;
+
+	return B_OK;
+
+	/* How we should return if an error occurred.
+	*/
+close_fp_return:
+	fclose( fp );
+
+free_data_return:
+	free( *data );
+	*data = NULL;
+
+	return retval;
+}
+
+status_t do_replace( const char *archive_name, char **files, int verbose,
+					 int create, int update )
+{
+	status_t retval = B_OK;
+	MWLib lib;
+	int idx = 0;
+	int which = 0;
+
+	ASSERT( archive_name != NULL );
+
+	memset( &lib, 0, sizeof( MWLib ) );
+
+	if( files == NULL ) {
+		fprintf( stderr, "ar: %s, nothing to do\n", archive_name );
+		return B_ERROR;
+	}
+
+	retval = load_MW_lib( &lib, archive_name );
+	if( retval != B_OK ) {
+		switch( retval ) {
+		case B_FILE_NOT_FOUND:
+			lib.header.magicword = 'MWOB';
+			lib.header.magicproc = 'PPC ';
+			lib.header.magicflags = 0;
+			lib.header.version = 1;
+
+			if( lib.files != NULL ) {
+				free( lib.files );
+				lib.files = NULL;
+			}
+
+			if( lib.names != NULL ) {
+				free( lib.names );
+				lib.names = NULL;
+			}
+
+			if( lib.data != NULL ) {
+				lib.data = NULL;
+			}
+
+			if( !create ) {
+				fprintf( stderr, "ar: creating %s\n", archive_name );
+			}
+
+			if( update ) {
+				fprintf( stderr, "ar: nothing to do for %s\n", archive_name );
+				return retval;
+			}
+			break;
+
+		default:
+			return retval;
+			break;
+		}
+	}
+
+	for( idx = 0; files[idx] != NULL; idx++ ) {
+		if( do_match( &lib, files[idx], &which ) ) {
+			/* Then the file exists, and we need to replace it or update it.
+			*/
+			if( update ) {
+				/* Compare m_times
+				** then replace this entry
+				*/
+				struct stat s;
+
+				retval = stat( files[idx], &s );
+				if( retval != 0 ) {
+					fprintf( stderr, "ar: can't stat %s, %s\n", files[idx],
+							 strerror( errno ) );
+				}
+
+				if( s.st_mtime >= lib.files[which].m_time ) {
+					retval = replace_lib_entry( &lib, files[idx], which, 
+												verbose );
+				} else {
+					fprintf( stderr, "ar: a newer %s is already in %s\n",
+							 files[idx], archive_name );
+				}
+			} else {
+				/* replace this entry
+				*/
+				retval = replace_lib_entry( &lib, files[idx], which, verbose );
+			}
+		} else {
+			/* add this entry
+			*/
+			retval = add_lib_entry( &lib, files[idx], verbose );
+		}
+	}
+
+	/* Write the new file.
+	*/
+	retval = write_MW_lib( &lib, archive_name );
+
+	return retval;
+}
+
+static status_t add_lib_entry( MWLib *lib, const char *filename, int verbose )
+{
+	status_t retval = B_OK;
+	uint32 new_num_objects;
+	uint32 idx;
+
+	ASSERT( lib != NULL );
+	ASSERT( filename != NULL );
+
+	/* Find out how many objects we'll have after we add this one.
+	*/
+	new_num_objects = lib->header.num_objects + 1;
+	idx = lib->header.num_objects;
+
+	/* Attempt to reallocate the MWLib's buffers.  If one of these fails,
+	** we could leak a little memory, but it shouldn't be a big deal in
+	** a short-lived app like this.
+	*/
+	lib->files = (MWLibFile *)realloc( lib->files, 
+									   sizeof(MWLibFile) * new_num_objects );
+	lib->names = (char **)realloc( lib->names,
+								   sizeof(char *) * new_num_objects );
+	lib->data = (char **)realloc( lib->data,
+								  sizeof(char *) * new_num_objects );
+	if( lib->files == NULL || lib->names == NULL || lib->data == NULL ) {
+		fprintf( stderr, "ar: can't allocate memory to add %s\n", filename );
+		return B_NO_MEMORY;
+	}
+
+	/* Load the file's data and info into the MWLib structure.
+	*/
+	retval = load_lib_file( filename, &(lib->data[idx]), &(lib->files[idx]) );
+	if( retval != B_OK ) {
+		fprintf( stderr, "ar: error adding %s, %s\n", filename,
+				 strerror( errno ) );
+
+		return retval;
+	}
+
+	/* Save a copy of the filename.  This is where we leak 
+	** sizeof(MWLibFile) + 2 * sizeof(char *) bytes because we don't
+	** shrink lib->files, lib->names, and lib->data.
+	*/
+	lib->names[idx] = strdup( filename );
+	if( lib->names == NULL ) {
+		fprintf( stderr, "ar: error allocating memory for filename\n" );
+
+		return B_NO_MEMORY;
+	}
+
+	/* Now that everything's OK, we can update the MWLib header.
+	*/
+	lib->header.num_objects++;
+
+	/* Give a little feedback.
+	*/
+	if( verbose ) {
+		printf( "a - %s\n", filename );
+	}
+
+	return B_OK;
+}
+
+static status_t replace_lib_entry( MWLib *lib, const char *filename, 
+								   int idx, int verbose )
+{
+	char *buff;
+	MWLibFile info;
+	char *dup_name;
+
+	status_t retval = B_OK;
+
+	ASSERT( lib != NULL );
+	ASSERT( filename != NULL );
+	ASSERT( idx <= lib->header.num_objects );
+
+	/* Load the file's data and info into the MWLib structure.
+	**
+	** We'll do it safely so we don't end up writing a bogus library in
+	** the event of failure.
+	*/
+	retval = load_lib_file( filename, &buff, &info );
+	if( retval != B_OK ) {
+		fprintf( stderr, "ar: error adding %s, %s\n", filename,
+				 strerror( errno ) );
+
+		return retval;
+	}
+
+	/* Attempt to allocate memory for a duplicate of the file name.
+	*/
+	dup_name = strdup( filename );
+	if( dup_name == NULL ) {
+		fprintf( stderr, "ar: unable to allocate memory for filename\n",
+				 filename );
+
+		free( buff );
+
+		return B_NO_MEMORY;
+	}
+
+	/* All is well, so let's update the MWLib object appropriately.
+	*/
+	lib->files[idx].m_time = info.m_time;
+	lib->files[idx].off_filename = 0;
+	lib->files[idx].off_fullpath = 0;
+	lib->files[idx].off_object = 0;
+	lib->files[idx].object_size = info.object_size;
+
+	lib->data[idx] = buff;
+
+	free( lib->names[idx] );
+	lib->names[idx] = dup_name;
+
+	/* Give a little feedback.
+	*/
+	if( verbose ) {
+		printf( "r - %s\n", filename );
+	}
+
+	return B_OK;
+}
+
+/* ----------------------------------------------------------------------
+** Print the table for an archive.
+*/
+static status_t table_lib_entry( MWLib *lib, int idx, int verbose );
+
+status_t do_table( const char *archive_name, char **files, int verbose )
+{
+	status_t retval = B_OK;
+	MWLib lib;
+	int idx = 0;
+
+	ASSERT( archive_name != NULL );
+
+	retval = load_MW_lib( &lib, archive_name );
+	if( retval != B_OK ) {
+		switch( retval ) {
+		case B_FILE_NOT_FOUND:
+			fprintf( stderr, "ar: %s, file not found\n", archive_name );
+			return retval;
+			break;
+
+		default:
+			return retval;
+			break;
+		}
+	}
+
+	if( files == NULL ) {
+		/* Then we print the table for the entire archive.
+		*/
+		for( idx = 0; idx < lib.header.num_objects; idx++ ) {
+			retval = table_lib_entry( &lib, idx, verbose );
+		}
+	} else {
+		/* Then we print the table for the specified files.
+		*/
+		int which = 0;
+
+		for( idx = 0; files[idx] != NULL; idx++ ) {
+			if( do_match( &lib, files[idx], &which ) ) {
+				retval = table_lib_entry( &lib, which, verbose );
+			}
+			which = 0;
+		}
+	}
+
+	return retval;
+}
+
+static status_t table_lib_entry( MWLib *lib, int idx, int verbose )
+{
+	struct tm *t;
+	char month_buff[4];
+
+	ASSERT( lib != NULL );
+
+	if( verbose ) {
+		t = localtime( &(lib->files[idx].m_time) );
+		if( t == NULL ) {
+			fprintf( stderr, "localtime() failed, %s\n",
+					 strerror( errno ) );
+			return B_OK;
+		}
+
+		if( strftime( month_buff, sizeof( month_buff ),
+					  "%b", t ) == 0 ) {
+			/* TODO: error message */
+			fprintf( stderr, "strftime() failed, %s\n",
+					 strerror( errno ) );
+			return B_OK;
+		}
+
+		/* I wish POSIX allowed for a nicer format; even using tabs
+		 * between some entries would be better.
+		 */
+		printf( "%s %u/%u %u %s %d %d:%d %d %s\n",
+				"-rw-r--r--", /* simulated mode */
+				getuid(), getgid(), /* simulated uid & gid */
+				lib->files[idx].object_size,
+				month_buff, /* abbreviated month */
+				t->tm_mon, /* day of month */
+				t->tm_hour, /* hour */
+				t->tm_min, /* minute */
+				t->tm_year, /* year */
+				lib->names[idx] );
+	} else {
+		printf( "%s\n", lib->names[idx] );
+	}
+
+	return B_OK;
+}
+
+/* ----------------------------------------------------------------------
+** Extract one or more files from the archive.
+*/
+static status_t extract_lib_entry( MWLib *lib, int idx, int verbose );
+
+status_t do_extract( const char *archive_name, char **files, int verbose )
+{
+	status_t retval = B_OK;
+	MWLib lib;
+	int idx = 0;
+
+	ASSERT( archive_name != NULL );
+
+	retval = load_MW_lib( &lib, archive_name );
+	if( retval != B_OK ) {
+		switch( retval ) {
+		case B_FILE_NOT_FOUND:
+			fprintf( stderr, "ar: %s, file not found\n", archive_name );
+			return retval;
+			break;
+
+		default:
+			return retval;
+			break;
+		}
+	}
+
+	if( files == NULL ) {
+		/* Then we extract all the files.
+		*/
+		for( idx = 0; idx < lib.header.num_objects; idx++ ) {
+			retval = extract_lib_entry( &lib, idx, verbose );
+		}
+	} else {
+		/* Then we extract the specified files.
+		*/
+		int which = 0;
+
+		for( idx = 0; files[idx] != NULL; idx++ ) {
+			if( do_match( &lib, files[idx], &which ) ) {
+				retval = extract_lib_entry( &lib, which, verbose );
+			}
+			which = 0;
+		}
+	}
+
+	return retval;
+}
+
+static status_t extract_lib_entry( MWLib *lib, int idx, int verbose )
+{
+	FILE *fp;
+	int recs;
+	status_t retval = B_OK;
+	struct stat s;
+	mode_t mode_bits = 0666;	/* TODO: use user's umask() instead */
+
+	ASSERT( lib != NULL );
+
+	/* Delete the file if it already exists.
+	*/
+	retval = access( lib->names[idx], F_OK );
+	if( retval == 0 ) {
+		retval = stat( lib->names[idx], &s );
+		if( retval != 0 ) {
+			fprintf( stderr, "ar: can't stat %s, %s\n", lib->names[idx],
+					 strerror( errno ) );
+		} else {
+			mode_bits = s.st_mode;
+		}
+		retval = unlink( lib->names[idx] );
+		if( retval != 0 ) {
+			fprintf( stderr, "ar: can't unlink %s, %s\n", lib->names[idx],
+					strerror( retval ) );
+			return B_OK;
+		}
+	}
+
+	/* Write the file.
+	*/
+	if( verbose ) {
+		printf( "x - %s\n", lib->names[idx] );
+	}
+
+	fp = fopen( lib->names[idx], "w" );
+	if( fp == NULL ) {
+		fprintf( stderr, "ar: can't open %s for write, %s\n", lib->names[idx],
+				 strerror( errno ) );
+		return B_OK;
+	}
+
+	recs = fwrite( lib->data[idx], lib->files[idx].object_size, 1, fp );
+	if( recs != 1 ) {
+		fprintf( stderr, "error writing %s, %s\n", lib->names[idx],
+				 strerror( errno ) );
+	}
+
+	retval = fclose( fp );
+
+	/* Set the newly extracted file's modification time to the time
+	** stored in the archive.
+	*/
+	retval = stat( lib->names[idx], &s );
+	if( retval != 0 ) {
+		fprintf( stderr, "ar: can't stat %s, %s\n", lib->names[idx], 
+				strerror( errno ) );
+	} else {
+		struct utimbuf new_times;
+
+		new_times.actime = s.st_atime;
+		new_times.modtime = lib->files[idx].m_time;
+
+		retval = utime( lib->names[idx], &new_times );
+		if( retval != 0 ) {
+			fprintf( stderr, "ar: can't set modification time for %s, %s\n",
+					 lib->names[idx], strerror( retval ) );
+		}
+	}
+
+	/* Set the newly extracted file's mode.
+	*/
+	retval = chmod( lib->names[idx], mode_bits );
+	if( retval != 0 ) {
+		fprintf( stderr, "ar: unable to change file mode for %s, %s\n",
+				 lib->names[idx], strerror( errno ) );
+	}
+
+	/* Set the newly extracted file's type.
+	*/
+	setfiletype( lib->names[idx], "application/x-mw-library" );
+
+	return B_OK;
+}
diff --git a/BeOS/ar-1.1/commands.h b/BeOS/ar-1.1/commands.h
new file mode 100644
index 0000000..e5c28c2
--- /dev/null
+++ b/BeOS/ar-1.1/commands.h
@@ -0,0 +1,28 @@
+/*
+** commands.h - POSIX 1003.2 "ar" command
+**
+** $Id$
+**
+** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks
+** Library files, not general-purpose POSIX 1003.2 format archives.
+**
+** Dec. 14, 1997 Chris Herborth (chrish@kagi.com)
+**
+** This code is donated to the PUBLIC DOMAIN.  You can use, abuse, modify,
+** redistribute, steal, or otherwise manipulate this code.  No restrictions
+** at all.  If you laugh at this code, you can't use it.
+**
+** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for
+** the interface, and Metrowerk's published docs detailing their library
+** format.  Look inside for clues about how reality differs from MW's
+** documentation on BeOS...
+*/
+
+#include <be/support/SupportDefs.h>
+
+status_t do_delete( const char *archive_name, char **files, int verbose );
+status_t do_print( const char *archive_name, char **files, int verbose );
+status_t do_replace( const char *archive_name, char **files, int verbose,
+					 int create, int update );
+status_t do_table( const char *archive_name, char **files, int verbose );
+status_t do_extract( const char *archive_name, char **files, int verobse );
diff --git a/BeOS/ar-1.1/copy_attrs.c b/BeOS/ar-1.1/copy_attrs.c
new file mode 100644
index 0000000..c9f978d
--- /dev/null
+++ b/BeOS/ar-1.1/copy_attrs.c
@@ -0,0 +1,128 @@
+/*
+** copy_attrs.h - copy BeFS attributes from one file to another
+**
+** Jan. 11, 1998 Chris Herborth (chrish@qnx.com)
+**
+** This code is donated to the PUBLIC DOMAIN.  You can use, abuse, modify,
+** redistribute, steal, or otherwise manipulate this code.  No restrictions
+** at all.  If you laugh at this code, you can't use it.
+*/
+
+#include <support/Errors.h>
+#ifndef NO_DEBUG
+#include <assert.h>
+#define ASSERT(cond) assert(cond)
+#else
+#define ASSERT(cond) ((void)0)
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <kernel/fs_attr.h>
+#include <fcntl.h>
+
+#include "copy_attrs.h"
+
+static const char *rcs_version_id = "$Id$";
+
+/* ----------------------------------------------------------------------
+** Copy file attributes from src_file to dst_file.
+*/
+
+status_t copy_attrs( const char *dst_file, const char *src_file )
+{
+	int dst_fd, src_fd;
+	status_t retval = B_OK;
+	DIR *fa_dir = NULL;
+	struct dirent *fa_ent = NULL;
+	char *buff = NULL;
+	struct attr_info fa_info;
+	off_t read_bytes, wrote_bytes;
+
+	ASSERT( dst_file != NULL );
+	ASSERT( src_file != NULL );
+
+	/* Attempt to open the files.
+	*/
+	src_fd = open( src_file, O_RDONLY );
+	if( src_fd < 0 ) {
+		return B_FILE_NOT_FOUND;
+	}
+
+	dst_fd = open( dst_file, O_WRONLY );
+	if( dst_fd < 0 ) {
+		close( src_fd );
+		return B_FILE_NOT_FOUND;
+	}
+
+	/* Read the attributes, and write them to the destination file.
+	*/
+	fa_dir = fs_fopen_attr_dir( src_fd );
+	if( fa_dir == NULL ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	}
+
+	fa_ent = fs_read_attr_dir( fa_dir );
+	while( fa_ent != NULL ) {
+		retval = fs_stat_attr( src_fd, fa_ent->d_name, &fa_info );
+		if( retval != B_OK ) {
+			/* TODO: Print warning message?
+			*/
+			goto read_next_attr;
+		}
+
+		if( fa_info.size > (off_t)UINT_MAX ) {
+			/* TODO: That's too big.  Print a warning message?  You could
+			**       copy it in chunks...
+			*/
+			goto read_next_attr;
+		}
+
+		if( fa_info.size > (off_t)0 ) {
+			buff = malloc( (size_t)fa_info.size );
+			if( buff == NULL ) {
+				/* TODO: Can't allocate memory for this attribute.  Warning?
+				*/
+				goto read_next_attr;
+			}
+			
+			read_bytes = fs_read_attr( src_fd, fa_ent->d_name, fa_info.type,
+									   0, buff, fa_info.size );
+			if( read_bytes != fa_info.size ) {
+				/* TODO: Couldn't read entire attribute.  Warning?
+				*/
+				goto free_attr_buff;
+			}
+			
+			wrote_bytes = fs_write_attr( dst_fd, fa_ent->d_name, fa_info.type,
+										 0, buff, fa_info.size );
+			if( wrote_bytes != fa_info.size ) {
+				/* TODO: Couldn't write entire attribute.  Warning?
+				*/
+				;
+			}
+
+		free_attr_buff:
+			free( buff );
+
+			retval = B_OK;
+		}
+
+		/* Read the next entry.
+		*/
+	read_next_attr:
+		fa_ent = fs_read_attr_dir( fa_dir );
+	}
+
+close_return:
+	close( dst_fd );
+	close( src_fd );
+
+	return retval;
+}
+
diff --git a/BeOS/ar-1.1/copy_attrs.h b/BeOS/ar-1.1/copy_attrs.h
new file mode 100644
index 0000000..a761636
--- /dev/null
+++ b/BeOS/ar-1.1/copy_attrs.h
@@ -0,0 +1,24 @@
+/*
+** copy_attrs.h - copy BeFS attributes from one file to another
+**
+** $Id$
+**
+** Jan. 11, 1998 Chris Herborth (chrish@qnx.com)
+**
+** This code is donated to the PUBLIC DOMAIN.  You can use, abuse, modify,
+** redistribute, steal, or otherwise manipulate this code.  No restrictions
+** at all.  If you laugh at this code, you can't use it.
+*/
+
+/* ----------------------------------------------------------------------
+** Function prototypes
+**
+** copy_attrs() - copy BeFS attributes from one file to another
+**
+** Returns:
+**    B_OK - all is well
+**    B_FILE_NOT_FOUND - can't open one of the named files
+**    B_IO_ERROR - can't read/write some of the file attributes
+**    B_NO_MEMORY - unable to allocate a buffer for the attribute data
+*/
+status_t copy_attrs( const char *dest_file, const char *src_file );
diff --git a/BeOS/ar-1.1/docs/ar.html b/BeOS/ar-1.1/docs/ar.html
new file mode 100644
index 0000000..50f002e
--- /dev/null
+++ b/BeOS/ar-1.1/docs/ar.html
@@ -0,0 +1,234 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML3.2//EN">
+<!-- $Id$ -->
+<html> <head>
+<title>ar - create and maintain library archives</title>
+</head>
+
+<body bgcolor="#ffffcb">
+<h1>ar</h1>
+<h4 align="right">create and maintain library archives</h4>
+
+<h2>Synopsis</h2>
+
+<pre>
+ar [-][dprtx][cuv] <i>archive</i> [<i>file</i> ...]
+</pre>
+
+<h2>Options</h2>
+
+<table>
+<tr>
+	<td valign="top"><b>-</b></td>
+	<td valign="top">
+	The <b>-</b> is optional for introducing <tt>ar</tt> command-line
+	arguments; this is a POSIX requirement, and I've never seen anyone
+	use it.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>c</b></td>
+	<td valign="top">
+	Don't print a diagnostic message to <i>stderr</i> when
+	<i>archive</i> is created.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>d</b></td>
+	<td valign="top">
+	Delete <i>file(s)</i> from <i>archive</i>.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>p</b></td>
+	<td valign="top">
+	Write the contents of the named <i>file(s)</i> to <i>stdout</i>.
+	If no <i>file(s)</i> are specified, all of the files in
+	<i>archive</i> are written in the order of the archive.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>r</b></td>
+	<td valign="top">
+	Replace or add <i>file(s)</i> to the <i>archive</i>.  This will
+	create <i>archive</i> if it doesn't already exist.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>t</b></td>
+	<td valign="top">
+	Write the table of contents of <i>archive</i> to <i>stdout</i>.
+	If not <i>file(s)</i> are specified, list all of the files,
+	otherwise only list the specified files.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>u</b></td>
+	<td valign="top">
+	Update older files.  When used with the <b>r</b> option, files
+	within the archive are only replaced if <i>file</i> has a
+	modification date at least as new as the <i>file</i> already in
+	the archive.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>v</b></td>
+	<td valign="top">Give verbose output.</td>
+</tr>
+
+<tr>
+	<td valign="top"><b>x</b></td>
+	<td valign="top">
+	Extract <i>file(s)</i> from the <i>archive</i>.  If no
+	<i>file(s)</i> are specified, all of the files in <i>archive</i>
+	are extracted.</td>
+</tr>
+
+<tr>
+	<td valign="top"><i>archive</i></td>
+	<td valign="top">
+	The pathname of an archive file.</td>
+</tr>
+
+<tr>
+	<td valign="top"><i>file</i></td>
+	<td valign="top">
+	One more more pathnames of object files; only the file name is
+	used when comparing against the names of files in the
+	archive.</td>
+</tr>
+
+</table>
+
+<h2>Description</h2>
+
+<p>The <tt>ar</tt> utility creates and maintains groups of files
+combined into a library.  Once a library has been created, you can
+add new files, and extract, delete, or replace existing files.</p>
+
+<h2>Exit status</h2>
+
+<p><tt>ar</tt> exits with one of the following values:</p>
+
+<table>
+<tr><td valign="top">0</td>
+	<td valign="top">Successful completion.</td></tr>
+<tr><td valign="top">&gt; 0</td>
+	<td>An error occurred.</td></tr>
+</table>
+
+<h2>Bugs</h2>
+
+<p>No known bugs, but <em>please</em> read the comments in the code if
+you want to use it in another application.</p>
+
+<h2>Comments</h2>
+
+<p>This is a POSIX 1003.2-1992 based <tt>ar</tt> command; it's not
+100% POSIX 1003.2 because POSIX specifies a file format for
+<tt>ar</tt> archives.  The BeOS <tt>ar</tt> produces library files
+compatible (at least in theory <tt>:-)</tt>) with Metrowerks
+CodeWarrior for PowerPC.</p>
+
+<p>This <tt>ar</tt> and its source code were written as a service to
+the Be developer community, to make it easier for us to port UNIX
+applications and libraries.  The code was written from scratch, after
+reverse-engineering the Metrowerks library and object file format
+(mostly because the library/object file format documentation was
+incorrect).</p>
+
+<p>If you find this useful, please
+<a href="mailto:chrish@kagi.com">let me know</a>, and tell me what
+you're working on.  Be sure to include a URL for your homepage or your
+product homepages for my
+<a href="http://www.qnx.com/~chrish/Be/community/">Be Community</a>
+pages.</p>
+
+<p>If you find any bugs, please try to fix them, and send me a context
+diff (use <tt>diff -c original_file fixed_file</tt>) so I can include
+your fixes in the next update.  I <i>have</i> tested this, but these
+things have a way of slipping though.</p>
+
+<p>If you'd like to know what other things I'm working on, take a look
+at my <a href="http://www.qnx.com/~chrish/Be/software/">Be
+Software</a> pages, and my
+<a href="http://www.qnx.com/~chrish/Be/">Be Happy!</a> pages.</p>
+
+<h2>License</h2>
+
+<p>This program binary and its source code have been donated to the
+BeOS Developer Community by Arcane Dragon Software free of charge.  
+You can do whatever you want with it.</p>
+
+<p>If you <em>really</em> want to show your appreciation, you could
+always send me a gift of some sort; cool software you wrote, nice
+pictures for my desktop, ZIP drive disks, RAM, hard drives, post
+cards, a pointer to a really cool/useful/interesting web site,
+an MPEG audio file of an interesting band (make sure you can give me
+enough information to track down their CDs if I like it!), <i>etc.</i>  
+Send me some <a href="mailto:chrish@kagi.com">email</a> and I'll let you 
+know where to send it.</p>
+
+<p>But you don't have to do anything.  Just write good BeOS software.
+But you're already doing that, right?</p>
+
+<h2>Disclaimer</h2>
+
+<p>You use this at your own risk.  I've tried to ensure that the code
+is correct, but software usually has bugs.  If <tt>ar</tt> destroys
+your valuable data, formats your hard drive, kicks your cat, and lets
+the air out of your tires, I'm not responsible for it.  The code is
+here, so you should feel fairly safe that there's nothing evil going
+on.</p>
+
+<p>And, as I learned once again in December 1997, you really should
+keep backups of everything.  I only lost a day's work, but it was
+still annoying, and it could've been much, much worse.</p>
+
+<h3>A word about the code</h3>
+
+<p>This code isn't meant to be the ultimate in efficiency or speed,
+it's intended to be fairly easy to understand and maintain
+(hopefully).  I was also quite keen on having something that was
+correct, without jumping through a lot of unnecessary hoops.</p>
+
+<p>If you think this code sucks, don't use it.  You're already applying
+this to your choice of operating system!  <tt>:-)</tt></p>
+
+<h2>Versions</h2>
+
+<dl compact>
+
+<dt><strong>1.1 (April 18, 1998)</strong></dt>
+<dd>Changes include:
+	<ul>
+	  <li>Extract option (<b>x</b>) will preserve a file's mode bits
+		  when overwriting an existing file (this may go away if it's
+		  not POSIX behaviour).</li>
+
+	  <li>Extracted files will now have the proper file type.</li>
+
+	  <li>Removed attempt to use <i>umask()</i> to set newly created
+		  archive's mode bits; apparently, I'm not sure how it
+		  works and my POSIX manual isn't helping.</li>
+
+	  <li>Should be 100% endian-neutral now; using this on BeOS for
+	  	  x86 is only useful if you're manipulating <em>PowerPC</em>
+	  	  objects though.  The <tt>ar</tt> in
+	  	  <a href="http://www.ninemoons.com/GG/index.html">GeekGadgets</a>
+	  	  should work fine for x86 objects/libraries.</li>
+	  	  
+	  <li>Updated the <tt>README.txt</tt> file; now it's got useful
+	  	  information about building/using the POSIX ar.</li>
+	</ul></dd>
+
+<dt><strong>1.0 (January 13, 1998)</strong></dt>
+<dd>Initial release.</dd>
+
+</dl>
+
+<hr>
+<p>Chris Herborth (<a href="mailto:chrish@qnx.com">chrish@qnx.com</a>)</p>
+<!-- hhmts start -->
+Last modified: $Date$
+<!-- hhmts end -->
+</body> </html>
diff --git a/BeOS/ar-1.1/docs/dumpar.py b/BeOS/ar-1.1/docs/dumpar.py
new file mode 100644
index 0000000..93e2283
--- /dev/null
+++ b/BeOS/ar-1.1/docs/dumpar.py
@@ -0,0 +1,271 @@
+#! /bin/env python
+""" Dump data about a Metrowerks archive file.
+
+$Id$
+
+Based on reverse-engineering the library file format.
+
+Copyright (C) 1997 Chris Herborth (chrish@qnx.com)
+"""
+
+# ----------------------------------------------------------------------
+# Standard modules
+import sys
+import getopt
+import string
+import time
+
+# ----------------------------------------------------------------------
+def usage():
+	""" Display a usage message and exit.
+	"""
+	print "dumpar [-v] library1 [library2 ... libraryn]"
+	print
+	print "Attempt to display some useful information about the contents"
+	print "of the given Metrowerks library file(s)."
+	print
+	print "-v        Be verbose (displays offsets along with the data)"
+	raise SystemExit
+
+# ----------------------------------------------------------------------
+def mk_long( str ):
+	""" convert a 4-byte string into a number
+
+	Assumes big-endian!
+	"""
+	if len( str ) < 4:
+		raise ValueError, "str must be 4 bytes long"
+
+	num = ord( str[3] )
+	num = num + ord( str[2] ) * 0x100
+	num = num + ord( str[1] ) * 0x10000
+	num = num + ord( str[0] ) * 0x1000000
+
+	return num
+
+# ----------------------------------------------------------------------
+def str2hex( str ):
+	""" convert a string into a string of hex numbers
+	"""
+	ret = []
+	for c in str:
+		h = hex( ord( c ) )
+		ret.append( string.zfill( "%s" % ( h[2:] ), 2 ) )
+
+	return string.join( ret )
+
+# ----------------------------------------------------------------------
+def print_offset( offset ):
+	""" print the offset nicely
+	"""
+
+	# Turn the offset into a hex number and strip off the leading "0x".
+	val = "%s" % ( hex( offset ) )
+	val = val[2:]
+
+	out = "0x" + string.zfill( val, 8 )
+
+	print out,
+
+# ----------------------------------------------------------------------
+def get_string( data ):
+	""" dig a C string out of a data stream
+
+	returns the string
+	"""
+	len = 0
+	while data[len] != '\0':
+		len = len + 1
+
+	return data[:len]
+
+# ----------------------------------------------------------------------
+def dump_lib( file, verbose ):
+	""" dump information about a Metrowerks library file
+	"""
+	offset = 0
+
+	print "Dumping library:", file
+
+	# Attempt to read the data.
+	try:
+		data = open( file ).read()
+	except IOError, retval:
+		print "*** Unable to open file %s: %s" % ( file, retval[1] )
+		return
+
+	# Check the magic number.
+	if verbose:
+		print_offset( offset )
+	print "Magic:",
+	magic = data[offset:offset + 8]
+	print "'%s'" % ( magic )
+	if magic != "MWOBPPC ":
+		print "*** Invalid magic number!"
+		return
+
+	offset = offset + 8
+
+	# File flags
+	if verbose:
+		print_offset( offset )
+	print "file flags:",
+	print mk_long( data[offset:offset + 4] )
+	offset = offset + 4
+
+	if verbose:
+		print_offset( offset )
+	print "file version:",
+	print mk_long( data[offset:offset + 4] )
+	offset = offset + 4
+
+	# code size
+	if verbose:
+		print_offset( offset )
+	print "code size:", mk_long( data[offset:offset + 4] )
+	offset = offset + 4
+
+	# data size
+	if verbose:
+		print_offset( offset )
+	print "data size:", mk_long( data[offset:offset + 4] )
+	offset = offset + 4
+
+	# number of objects
+	if verbose:
+		print_offset( offset )
+	print "number of objects:",
+	num_objs = mk_long( data[offset:offset + 4] )
+	print num_objs
+
+	offset = offset + 4
+
+	print
+
+	# Now loop through the objects.
+	obj_sizes = [ 0, ] * num_objs
+	obj_data_offsets = [ 0, ] * num_objs
+
+	for obj in range( num_objs ):
+		# Magic?
+		if verbose:
+			print_offset( offset )
+		print "modification time:",
+		modtime = mk_long( data[offset:offset + 4] )
+		print "[%s]" % ( ( time.localtime( modtime ), ) )
+
+		offset = offset + 4
+
+		# Offsets?
+		if verbose:
+			print_offset( offset )
+		print "file name offset 1:",
+		file_offset1 = mk_long( data[offset:offset + 4] )
+		unknown = "%s" % ( hex( file_offset1 ) )
+		print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) )
+
+		offset = offset + 4
+
+		if verbose:
+			print_offset( offset )
+		print "file name offset 2:",
+		file_offset2 = mk_long( data[offset:offset + 4] )
+		unknown = "%s" % ( hex( file_offset2 ) )
+		print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) )
+
+		offset = offset + 4
+
+		# Extra -1 for NUL character.
+		print "           >>>> File name should be %s characters." % \
+			  ( file_offset2 - file_offset1 - 1)
+
+		if verbose:
+			print_offset( offset )
+		print "object data offset:",
+		file_data_offset = mk_long( data[offset:offset + 4] )
+		unknown = "%s" % ( hex( file_data_offset ) )
+		print "%s (%s)" % ( unknown, str2hex( data[offset:offset + 4] ) )
+
+		obj_data_offsets[obj] = file_data_offset
+
+		offset = offset + 4
+
+		# object size
+		if verbose:
+			print_offset( offset )
+		print "object size:",
+		obj_sizes[obj] = mk_long( data[offset:offset + 4] )
+		print "%s bytes" % ( obj_sizes[obj] )
+
+		offset = offset + 4
+
+		print
+
+	# Now loop through the object names.
+	for obj in range( num_objs ):
+		# First name
+		if verbose:
+			print_offset( offset )
+		print "object",
+		print obj,
+		print "name 1:",
+		name1 = get_string( data[offset:] )
+		print "[%s] %s chars" % ( name1, len( name1 ) )
+
+		offset = offset + len( name1 ) + 1
+
+		# Second name
+		if verbose:
+			print_offset( offset )
+		print "object",
+		print obj,
+		print "name 2:",
+		name2 = get_string( data[offset:] )
+		print "[%s] %s chars" % ( name2, len( name1 ) )
+
+		offset = offset + len( name2 ) + 1
+
+		# See if we've got a magic cookie in the object data
+		if verbose:
+			print_offset( obj_data_offsets[obj] )
+
+		cookie = data[obj_data_offsets[obj]:obj_data_offsets[obj] + 8]
+		print "object",
+		print obj,
+		print "cookie: '%s'" % ( cookie )
+
+		print
+
+	# Now loop through the data and check for magic numbers there.
+	return
+
+# ----------------------------------------------------------------------
+def main():
+	""" mainline
+	"""
+
+	# Set up some defaults
+	be_verbose = 0
+
+	# First, check the command-line arguments
+	try:
+		opt, args = getopt.getopt( sys.argv[1:], "vh?" )
+	except getopt.error:
+		print "*** Error parsing command-line options!"
+		usage()
+
+	for o in opt:
+		if o[0] == "-h" or o[0] == "-?":
+			usage()
+		elif o[0] == "-v":
+			be_verbose = 1
+		else:
+			print "*** Unknown command-line option!"
+			usage()
+
+	# Now we can attempt to dump info about the arguments.
+	for lib in args:
+		dump_lib( lib, be_verbose )
+
+if __name__ == "__main__":
+	main()
diff --git a/BeOS/ar-1.1/docs/dumpar.pyc b/BeOS/ar-1.1/docs/dumpar.pyc
new file mode 100644
index 0000000..bc5045f
--- /dev/null
+++ b/BeOS/ar-1.1/docs/dumpar.pyc
Binary files differ
diff --git a/BeOS/ar-1.1/docs/dumpo.py b/BeOS/ar-1.1/docs/dumpo.py
new file mode 100644
index 0000000..91bd8db
--- /dev/null
+++ b/BeOS/ar-1.1/docs/dumpo.py
@@ -0,0 +1,126 @@
+#! /bin/env python
+""" Dump data about a Metrowerks object file.
+
+Based on reverse-engineering the library file format, since the docs are
+wrong.
+
+Copyright (C) 1997 Chris Herborth (chrish@qnx.com)
+"""
+
+# ----------------------------------------------------------------------
+# Standard modules
+import sys, getopt, string, time
+
+# ----------------------------------------------------------------------
+# Extra goodies
+from dumpar import mk_long, str2hex, print_offset, get_string
+
+# ----------------------------------------------------------------------
+def mk_short( str ):
+	""" convert a 2-byte string into a number
+
+	Assumes big-endian!
+	"""
+	if len( str ) < 2:
+		raise ValueError, "str must be 2 bytes long"
+
+	num = ord( str[1] )
+	num = num + ord( str[0] ) * 0x100
+
+	return num
+
+# ----------------------------------------------------------------------
+def usage():
+	""" Display a usage message and exit.
+	"""
+	print "dumpo [-v] object1 [object2 ... objectn]"
+	print
+	print "Attempt to display some useful information about the contents"
+	print "of the given Metrowerks object file(s)."
+	print
+	print "-v        Be verbose (displays offsets along with the data)"
+	raise SystemExit
+
+# ----------------------------------------------------------------------
+def dump_o( file, verbose ):
+	""" dump information about a Metrowerks object file
+
+	Note that there is more info there, 6 more quads before the file name.
+	"""
+	offset = 0
+
+	print "Dumping object:", file
+
+	# Attempt to read the data.
+	try:
+		data = open( file ).read()
+	except IOError, retval:
+		print "*** Unable to open file %s: %s" % ( file, retval[1] )
+		return
+
+	# Check the magic number.
+	if verbose:
+		print_offset( offset )
+	print "Magic:",
+	magic = data[offset:offset + 8]
+	print "'%s'" % ( magic )
+	if magic != "MWOBPPC ":
+		print "*** Invalid magic  number!"
+		return
+
+	offset = offset + 8
+
+	# version
+	if verbose:
+		print_offset( offset )
+	print "version:", mk_long( data[offset:offset + 4] )
+	offset = offset + 4
+
+	# flags
+	if verbose:
+		print_offset( offset )
+	print "flags:", str2hex( data[offset:offset + 4] )
+	offset = offset + 4
+
+	# code size
+	if verbose:
+		print_offset( offset )
+	print "code size:", mk_long( data[offset:offset + 4] )
+	offset = offset + 4
+
+	# data size
+	if verbose:
+		print_offset( offset )
+	print "data size:", mk_long( data[offset:offset + 4] )
+	offset = offset + 4
+
+# ----------------------------------------------------------------------
+def main():
+	""" mainline
+	"""
+
+	# Set up some defaults
+	be_verbose = 0
+
+	# First, check the command-line arguments
+	try:
+		opt, args = getopt.getopt( sys.argv[1:], "vh?" )
+	except getopt.error:
+		print "*** Error parsing command-line options!"
+		usage()
+
+	for o in opt:
+		if o[0] == "-h" or o[0] == "-?":
+			usage()
+		elif o[0] == "-v":
+			be_verbose = 1
+		else:
+			print "*** Unknown command-line option!"
+			usage()
+
+	# Now we can attempt to dump info about the arguments.
+	for obj in args:
+		dump_o( obj, be_verbose )
+
+if __name__ == "__main__":
+	main()
diff --git a/BeOS/ar-1.1/docs/notes b/BeOS/ar-1.1/docs/notes
new file mode 100644
index 0000000..4a90a16
--- /dev/null
+++ b/BeOS/ar-1.1/docs/notes
@@ -0,0 +1,34 @@
+MW library layout:
+
+header
+	magic word, magic processor flag ('MWOBPPC ') - 2x 4 bytes
+	magic flags, version (file format version?) - 2x 4 bytes
+	code size - 4 bytes
+	data size - 4 bytes
+	# of objects - 4 bytes
+
+	header for file 1 - 20 bytes
+		- modification time - 4 bytes
+		- offset to filename - 4 bytes
+		- offset to full path - 4 bytes (NOTE: NOT a full path in reality!)
+		- offset to object data - 4 bytes
+		- size of object data - 4 bytes
+
+	...
+
+	header for file n - 20 bytes
+
+	file 1 name + NUL - variable
+	file 1 name + NUL - variable
+	file 2 name + NUL - variable
+	file 2 name + NUL - variable
+	...
+	file n name + NUL - variable
+	file n name + NUL - variable
+
+	padding to multiple of 4 bytes - 0 - 3 bytes
+
+file 1 data - variable (padded to 4-byte boundary)
+file 2 data - variable (padded to 4-byte boundary)
+...
+file n data - variable (padded to 4-byte boundary)
diff --git a/BeOS/ar-1.1/main.c b/BeOS/ar-1.1/main.c
new file mode 100644
index 0000000..225ee62
--- /dev/null
+++ b/BeOS/ar-1.1/main.c
@@ -0,0 +1,312 @@
+/*
+** main.c - POSIX 1003.2 "ar" command
+**
+** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks
+** Library files, not general-purpose POSIX 1003.2 format archives.
+**
+** Dec. 14, 1997 Chris Herborth (chrish@kagi.com)
+**
+** This code is donated to the PUBLIC DOMAIN.  You can use, abuse, modify,
+** redistribute, steal, or otherwise manipulate this code.  No restrictions
+** at all.  If you laugh at this code, you can't use it.
+**
+** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for
+** the interface, and Metrowerk's published docs detailing their library
+** format.  Look inside for clues about how reality differs from MW's
+** documentation on BeOS...
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <getopt.h>
+
+#include "commands.h"
+
+static const char *rcs_version_id = "$Id$";
+static const char *ar_version_id = "1.0 " __DATE__;
+
+/* ---------------------------------------------------------------------- */
+typedef enum {
+	delete_cmd,
+	print_cmd,
+	replace_cmd,
+	table_cmd,
+	extract_cmd,
+	no_cmd = -1 } command;
+
+/* ----------------------------------------------------------------------
+** Prototypes
+*/
+void usage( void );
+void version( void );
+void check_command( command *cmd, int arg );
+
+/* ----------------------------------------------------------------------
+** Print a usage message and exit.
+*/
+void usage( void )
+{
+	printf( "ar [dprtx][cuv] archive [file ...]\n" );
+
+	exit( EXIT_FAILURE );
+}
+
+/* ----------------------------------------------------------------------
+** Print a version message and exit.
+*/
+void version( void )
+{
+	printf( "ar (POSIX 1003.2-1992), version %s\n", ar_version_id );
+	printf( "by Chris Herborth (chrish@qnx.com)\n" );
+	printf( "This code has been donated to the BeOS developer community.\n" );
+
+	return;
+}
+
+/* ----------------------------------------------------------------------
+** Set *cmd to the appropriate command enum if it isn't already set.
+*/
+void check_command( command *cmd, int arg )
+{
+	if( *cmd == no_cmd ) {
+		switch( arg ) {
+		case 'd':
+			*cmd = delete_cmd;
+			break;
+		case 'p':
+			*cmd = print_cmd;
+			break;
+		case 'r':
+			*cmd = replace_cmd;
+			break;
+		case 't':
+			*cmd = table_cmd;
+			break;
+		case 'x':
+			*cmd = extract_cmd;
+			break;
+		}
+	} else {
+		printf( "ar: you can only specify one command at a time\n" );
+		usage();
+	}
+}
+
+/* ----------------------------------------------------------------------
+** Mainline
+*/
+int main( int argc, char **argv )
+{
+	command cmd = no_cmd;
+	int verbose_flag = 0;
+	int create_flag = 0;	/* these two only apply to replace_cmd */
+	int update_flag = 0;
+	int c = 0;
+
+	char *archive_name;
+	char **files_list;
+	int num_files;
+
+	int idx;
+	status_t retval;
+
+	/* The argument parsing is a little hairier than usual; the idea is
+	** to support the POSIX 1003.2 style of arguments, and the much more
+	** common traditional argument style.
+	*/
+	if( argc < 3 ) {
+		printf( "ar: invalid number of arguments\n" );
+		usage();
+	}
+
+	/* Do we have traditional or POSIX-style args? */
+	if( argv[1][0] == '-' ) {
+		while( ( c = getopt( argc, argv, "dprtxcuvV" ) ) != EOF ) {
+			switch( c ) {
+			case 'd':	/* fall-through */
+			case 'p':	/* fall-through */
+			case 'r':	/* fall-through */
+			case 't':	/* fall-through */
+			case 'x':	/* fall-through */
+				check_command( &cmd, c );
+				break;
+
+			case 'v':
+				verbose_flag = 1;
+				break;
+
+			case 'c':
+				if( cmd != no_cmd && cmd != replace_cmd ) {
+					printf( "ar: invalid option, -c\n" );
+					usage();
+				} else {
+					create_flag = 1;
+				}
+				break;
+
+			case 'u':
+				if( cmd != no_cmd && cmd != replace_cmd ) {
+					printf( "ar: invalid option, -u\n" );
+					usage();
+				} else {
+					update_flag = 1;
+				}
+				break;
+
+			case 'V':
+				version();
+				break;
+
+			default:
+				printf( "ar: invalid option, -%c\n", c );
+				usage();
+				break;
+			}
+
+			idx = optind;
+		}
+	} else {
+		/* In the traditional way, arguments ar:
+		**
+		** argv[1] = [dprtx][cuv]
+		** argv[2] = archive
+		** argv[...] = file ...
+		**/
+		char *ptr;
+
+		idx = 1;
+
+		ptr = argv[idx++];
+
+		while( *ptr != '\0' ) {
+			switch( *ptr ) {
+			case 'd':	/* fall-through */
+			case 'p':	/* fall-through */
+			case 'r':	/* fall-through */
+			case 't':	/* fall-through */
+			case 'x':	/* fall-through */
+				check_command( &cmd, *ptr );
+				break;
+
+			case 'v':
+				verbose_flag = 1;
+				break;
+
+			case 'c':
+				if( cmd != no_cmd && cmd != replace_cmd ) {
+					printf( "ar: invalid option, -c\n" );
+					usage();
+				} else {
+					create_flag = 1;
+				}
+				break;
+
+			case 'u':
+				if( cmd != no_cmd && cmd != replace_cmd ) {
+					printf( "ar: invalid option, -u\n" );
+					usage();
+				} else {
+					update_flag = 1;
+				}
+				break;
+
+			case 'V':
+				version();
+				break;
+
+			default:
+				printf( "ar: invalid option, -%c\n", c );
+				usage();
+				break;
+			}
+
+			ptr++;
+		}
+	}
+
+	/* Next arg is the archive. */
+	archive_name = argv[idx++];
+
+	/* Next are the files. */
+	num_files = argc - idx;
+
+	if( num_files == 0 ) {
+		files_list = NULL;
+	} else {
+		int ctr = 0;
+
+		files_list = (char **)malloc( ( num_files + 1 ) * sizeof( char * ) );
+
+		while( idx < argc ) {
+			files_list[ctr++] = argv[idx++];
+		}
+
+		files_list[idx] = NULL;
+	}
+
+	/* Now we can attempt to manipulate the archive. */
+	switch( cmd ) {
+	case delete_cmd:
+		retval = do_delete( archive_name, files_list, verbose_flag );
+		break;
+
+	case print_cmd:
+		retval = do_print( archive_name, files_list, verbose_flag );
+		break;
+
+	case replace_cmd:
+		retval = do_replace( archive_name, files_list, verbose_flag,
+							 create_flag, update_flag );
+		break;
+
+	case table_cmd:
+		retval = do_table( archive_name, files_list, verbose_flag );
+		break;
+
+	case extract_cmd:
+		retval = do_extract( archive_name, files_list, verbose_flag );
+		break;
+
+	default:
+		printf( "ar: you must specify a command\n" );
+		usage();
+		break;
+	}
+
+	/* Check the return value.
+	*/
+	switch( retval ) {
+	case B_OK:
+		break;
+	case B_FILE_NOT_FOUND:
+		printf( "can't open the file %s\n", archive_name );
+		return EXIT_FAILURE;
+		break;
+	case B_IO_ERROR:
+		printf( "can't read from %s\n", archive_name );
+		return EXIT_FAILURE;
+		break;
+	case B_BAD_VALUE:
+		printf( "invalid magic word\n" );
+		return EXIT_FAILURE;
+		break;
+	case B_MISMATCHED_VALUES:
+		printf( "invalid processor value, or magicflags, or version\n" );
+		return EXIT_FAILURE;
+		break;
+	case B_NO_MEMORY:
+		printf( "unable to allocate memory\n" );
+		return EXIT_FAILURE;
+		break;
+	case B_ERROR:
+		printf( "error during processing\n" );
+		return EXIT_FAILURE;
+	default:
+		printf( "unknown error: %ld\n", retval );
+		return EXIT_FAILURE;
+		break;
+	}
+
+	return EXIT_SUCCESS;
+}
diff --git a/BeOS/ar-1.1/mwlib.c b/BeOS/ar-1.1/mwlib.c
new file mode 100644
index 0000000..f3b8660
--- /dev/null
+++ b/BeOS/ar-1.1/mwlib.c
@@ -0,0 +1,711 @@
+/*
+** mwlib.c - POSIX 1003.2 "ar" command
+**
+** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks
+** Library files, not general-purpose POSIX 1003.2 format archives.
+**
+** Dec. 14, 1997 Chris Herborth (chrish@kagi.com)
+**
+** This code is donated to the PUBLIC DOMAIN.  You can use, abuse, modify,
+** redistribute, steal, or otherwise manipulate this code.  No restrictions
+** at all.  If you laugh at this code, you can't use it.
+**
+** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for
+** the interface, and Metrowerk's published docs detailing their library
+** format.  Look inside for clues about how reality differs from MW's
+** documentation on BeOS...
+*/
+
+#include <support/Errors.h>
+#include <support/byteorder.h>
+#ifndef NO_DEBUG
+#include <assert.h>
+#define ASSERT(cond) assert(cond)
+#else
+#define ASSERT(cond) ((void)0)
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <kernel/fs_attr.h>
+#include <fcntl.h>			/* is open() really here?!? sheesh... */
+#include <storage/Mime.h>
+#include <sys/stat.h>
+
+#include "mwlib.h"
+#include "copy_attrs.h"
+
+static const char *rcs_version_id = "$Id$";
+
+/* ----------------------------------------------------------------------
+** Local prototypes
+*/
+static status_t load_MWLibFile( FILE *file, MWLibFile *libfile );
+static size_t fwrite_big32( uint32 x, FILE *fp );
+static size_t fwrite_big32_seek( uint32 x, long offset, FILE *fp );
+static status_t add_object_sizes( MWObject *obj, uint32 *code, uint32 *data );
+
+/* ----------------------------------------------------------------------
+** Load a Metrowerks library file into the given MWLib object.
+**
+** Returns:
+**    B_OK - all is well
+**    B_FILE_NOT_FOUND - can't open the given file
+**    B_IO_ERROR - can't read from the given file
+**    B_BAD_VALUE - invalid magic word in the file
+**    B_MISMATCHED_VALUES - invalid processor value (ie, not a PowerPC lib),
+**                          or the magicflags member is not 0, or the file
+**                          version number isn't 1.
+**    B_NO_MEMORY - unable to allocate memory while loading the lib
+*/
+status_t load_MW_lib( MWLib *lib, const char *filename )
+{
+	FILE *fp = NULL;
+	size_t recs = 0;
+	status_t retval = B_OK;
+	uint32 tmp32 = 0;
+	uint32 idx = 0;
+	char obj_name[PATH_MAX];
+
+	ASSERT( lib != NULL );
+	ASSERT( filename != NULL );
+
+	fp = fopen( filename, "r" );
+	if( !fp ) {
+		return B_FILE_NOT_FOUND;
+	}
+
+	/* Read and check the magic number.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, fp );
+	lib->header.magicword = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	} else if( lib->header.magicword != MWLIB_MAGIC_WORD ) {
+		retval = B_BAD_VALUE;
+		goto close_return;
+	}
+
+	/* Read and check the processor.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, fp );
+	lib->header.magicproc = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	} else if( lib->header.magicproc != MWLIB_MAGIC_PROC ) {
+		retval = B_MISMATCHED_VALUES;
+		goto close_return;
+	}
+
+	/* Read and check the flags.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, fp );
+	lib->header.magicflags = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	} else if( lib->header.magicflags != 0 ) {
+		retval = B_MISMATCHED_VALUES;
+		goto close_return;
+	}
+
+	/* Read and check the file version.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, fp );
+	lib->header.version = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	} else if( lib->header.version != 1 ) {
+		retval = B_MISMATCHED_VALUES;
+		goto close_return;
+	}
+
+	/* Read the code size, data size, and number of objects.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, fp );
+	lib->header.code_size = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	}
+
+	recs = fread( &tmp32, sizeof( uint32 ), 1, fp );
+	lib->header.data_size = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	}
+
+	recs = fread( &tmp32, sizeof( uint32 ), 1, fp );
+	lib->header.num_objects = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		retval = B_IO_ERROR;
+		goto close_return;
+	}
+
+	/* Load the MWLibFile objects from the lib.
+	*/
+	lib->files = (MWLibFile *)malloc( lib->header.num_objects * sizeof( MWLibFile ) );
+	if( lib->files == NULL ) {
+		retval = B_NO_MEMORY;
+		goto close_return;
+	}
+
+	for( idx = 0; idx < lib->header.num_objects; idx++ ) {
+		retval = load_MWLibFile( fp, &(lib->files[idx]) );
+		if( retval != B_OK ) {
+			goto close_return;
+		}
+	}
+
+	/* Load the file names and object data.
+	**
+	** The file name actually appears twice in the library file; according
+	** to the docs, one is the file name, the other is the "full path name".
+	** In all of the libraries on my system, they're the same.
+	*/
+	lib->names = (char **)malloc( lib->header.num_objects * sizeof( char * ) );
+	lib->data = (char **)malloc( lib->header.num_objects * sizeof( char * ) );
+	if( lib->names == NULL || lib->data == NULL ) {
+		retval = B_NO_MEMORY;
+		goto close_return;
+	}
+
+	for( idx = 0; idx < lib->header.num_objects; idx ++ ) {
+		/* Load the name and copy it into the right spot.
+		*/
+		retval = fseek( fp, lib->files[idx].off_filename, SEEK_SET );
+		if( retval ) {
+			retval = B_IO_ERROR;
+			goto close_return;
+		}
+
+		if( fgets( obj_name, PATH_MAX, fp ) == NULL ) {
+			retval = B_IO_ERROR;
+			goto close_return;
+		}
+
+		lib->names[idx] = strdup( obj_name );
+		if( lib->names[idx] == NULL ) {
+			retval = B_NO_MEMORY;
+			goto close_return;
+		}
+
+		/* Load the object data.
+		*/
+		lib->data[idx] = (char *)malloc( lib->files[idx].object_size );
+		if( lib->data[idx] == NULL ) {
+			retval = B_NO_MEMORY;
+			goto close_return;
+		}
+
+		retval = fseek( fp, lib->files[idx].off_object, SEEK_SET );
+		if( retval ) {
+			retval = B_IO_ERROR;
+			goto close_return;
+		}
+
+		recs = fread( lib->data[idx], lib->files[idx].object_size, 1, fp );
+		if( recs != 1 ) {
+			retval = B_IO_ERROR;
+			goto close_return;
+		}
+	}
+
+close_return:
+	fclose( fp );
+	return retval;
+}
+
+/* ----------------------------------------------------------------------
+** Load the file header from a Metrowerks library file.
+**
+** Returns:
+**    B_OK - All is well
+**    B_IO_ERROR - Error reading the file
+*/
+static status_t load_MWLibFile( FILE *file, MWLibFile *libfile )
+{
+	size_t recs = 0;
+	uint32 tmp32 = 0;
+
+	ASSERT( file != NULL );
+	ASSERT( libfile != NULL );
+
+	/* Load the modification time.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, file );
+	libfile->m_time = (time_t)B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		return B_IO_ERROR;
+	}
+
+	/* Load the various offsets.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, file );
+	libfile->off_filename = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		return B_IO_ERROR;
+	}
+
+	recs = fread( &tmp32, sizeof( uint32 ), 1, file );
+	libfile->off_fullpath = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		return B_IO_ERROR;
+	}
+
+	recs = fread( &tmp32, sizeof( uint32 ), 1, file );
+	libfile->off_object = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		return B_IO_ERROR;
+	}
+
+	/* Load the object size.
+	*/
+	recs = fread( &tmp32, sizeof( uint32 ), 1, file );
+	libfile->object_size = B_BENDIAN_TO_HOST_INT32( tmp32 );
+	if( recs != 1 ) {
+		return B_IO_ERROR;
+	}
+
+	return B_OK;
+}
+
+/* ----------------------------------------------------------------------
+** Write a Metrowerks library file.
+**
+** Returns:
+**    B_OK - all is well; doesn't necessarily mean the file was written
+**           properly, just that you didn't lose any data
+**    B_NO_MEMORY - unable to allocate offset buffers
+**    B_ERROR - problem with backup file (can't rename existing file)
+**
+** Note:
+**    If you use this in a long-lived program, it leaks memory; the MWLib
+**    contents are never free()'d.
+**
+** Two-pass technique:
+**
+** pass 1 - write file header (need CODE SIZE and DATA SIZE)
+** 		 write object headers (need offsets for FILENAME, FULL PATH, DATA)
+** 		 write filenames (store offsets for object headers)
+** 		 write padding (file size % 4 bytes)
+** 		 write file data (store offset for object header; add to code/data
+** 		                  size for file header; pad data size % 4 bytes)
+**
+** pass 2 - fill in file header CODE SIZE and DATA SIZE
+** 		 fill in object headers FILENAME, FULL PATH, DATA
+**
+** You could avoid this by building up the file headers in memory, but this is
+** easier (?) and I'm not that concerned with speed...
+**
+*/
+
+typedef struct file_header_offsets {
+	long codesize_offset;
+	long datasize_offset;
+} file_header_offsets;
+
+typedef struct obj_header_offsets {
+	long filename_offset;
+	uint32 filename_offset_value;
+
+	long fullpath_offset;
+	uint32 fullpath_offset_value;
+
+	long data_offset;
+	uint32 data_offset_value;
+} obj_header_offsets;
+
+static size_t fwrite_big32( uint32 x, FILE *fp )
+{
+	uint32 tmp32 = B_HOST_TO_BENDIAN_INT32( x );
+
+	ASSERT( fp != NULL );
+
+	return fwrite( &tmp32, sizeof(tmp32), 1, fp );
+}
+
+static size_t fwrite_big32_seek( uint32 x, long offset, FILE *fp )
+{
+	uint32 tmp32 = B_HOST_TO_BENDIAN_INT32( x );
+
+	ASSERT( fp != NULL );
+
+	if( fseek( fp, offset, SEEK_SET ) ) {
+		return 0;
+	}
+
+	return fwrite( &tmp32, sizeof(tmp32), 1, fp );
+}
+
+static status_t add_object_sizes( MWObject *obj, uint32 *code, uint32 *data )
+{
+	ASSERT( obj != NULL );
+	ASSERT( code != NULL );
+	ASSERT( data != NULL );
+
+	if( B_BENDIAN_TO_HOST_INT32( obj->magic_word ) != 'MWOB' || 
+		B_BENDIAN_TO_HOST_INT32( obj->arch ) != 'PPC ' ) {
+		return B_ERROR;
+	}
+
+	*code += B_BENDIAN_TO_HOST_INT32( obj->code_size );
+	*data += B_BENDIAN_TO_HOST_INT32( obj->data_size );
+
+	return B_OK;
+}
+
+void setfiletype( const char *file, const char *type )
+{
+    int fd;
+    attr_info fa;
+    ssize_t wrote_bytes;
+
+    fd = open( file, O_RDWR );
+    if( fd < 0 ) {
+        fprintf( stderr, "ar: can't open %s to write file type, %s",
+				 file, strerror( errno ) );
+        return;
+    }
+
+    fa.type = B_MIME_STRING_TYPE;
+    fa.size = (off_t)(strlen( type ) + 1);
+
+    wrote_bytes = fs_write_attr( fd, "BEOS:TYPE", fa.type, 0,
+                                 type, fa.size );
+    if( wrote_bytes != (ssize_t)fa.size ) {
+        fprintf( stderr, "ar: couldn't write complete file type, %s",
+				 strerror( errno ) );
+    }
+
+    close( fd );
+}
+
+status_t write_MW_lib( MWLib *lib, const char *filename )
+{
+	char *padding = "\0\0\0\0";
+	long pad_amount;
+
+	file_header_offsets head_offs;
+	obj_header_offsets *obj_offs;
+	uint32 codesize = 0;
+	uint32 datasize = 0;
+	uint32 num_objects = 0;
+
+	FILE *fp;
+	char *tmp_filename = NULL;
+	uint32 idx = 0;
+	size_t recs;
+	status_t retval;
+
+	mode_t mode_bits = 0666;
+
+	ASSERT( lib != NULL );
+	ASSERT( filename != NULL );
+
+#if 0
+/* Apparently, I don't understand umask()... */
+
+	/* Find the default file creation mask.  The semantics of umask() suck.
+	*/
+	mode_bits = umask( (mode_t)0 );
+	(void)umask( mode_bits );
+#endif
+
+	/* Easier access to the number of objects.
+	*/
+	num_objects = lib->header.num_objects;
+
+	/* Allocate some storage for keeping track of the things we need to
+	** write out in the second pass.
+	*/
+	head_offs.codesize_offset = 0;
+	head_offs.datasize_offset = 0;
+
+	obj_offs = (obj_header_offsets *)malloc( sizeof(obj_header_offsets) *
+											 num_objects );
+	if( obj_offs == NULL ) {
+		fprintf( stderr, "ar: can't allocate memory for writing file\n" );
+
+		return B_NO_MEMORY;
+	}
+	memset( obj_offs, 0, sizeof(obj_header_offsets) * num_objects );
+
+	/* If the file exists, move it somewhere so we can recover if there's
+	** an error.
+	*/
+	retval = access( filename, F_OK );
+	if( retval == 0 ) {
+		struct stat s;
+
+		/* Preserve the mode bits.
+		*/
+		retval = stat( filename, &s );
+		if( retval != 0 ) {
+			fprintf( stderr, "ar: can't stat %s, %s\n", filename,
+					 strerror( errno ) );
+		} else {
+			mode_bits = s.st_mode;
+		}
+
+		tmp_filename = (char *)malloc( strlen( filename ) + 2 );
+		if( tmp_filename == NULL ) {
+			fprintf( stderr, 
+					 "ar: can't allocate memory for temporary filename\n" );
+		} else {
+			sprintf( tmp_filename, "%s~", filename );
+
+			retval = access( tmp_filename, F_OK );
+			if( retval == 0 ) {
+				retval = unlink( tmp_filename );
+				if( retval != 0 ) {
+					fprintf( stderr, "ar: can't unlink %s, %s\n", tmp_filename,
+							 strerror( errno ) );
+
+					free( tmp_filename );
+					tmp_filename = NULL;
+				}
+			}
+
+			if( tmp_filename ) {
+				retval = rename( filename, tmp_filename );
+				if( retval != 0 ) {
+					fprintf( stderr, "ar: can't move %s to backup, %s\n",
+							 filename, strerror( errno ) );
+
+					return B_ERROR;
+				}
+			}
+		}
+	}
+
+	/* Attempt to open the archive file.
+	*/
+	fp = fopen( filename, "w" );
+	if( fp == NULL ) {
+		fprintf( stderr, "ar: can't open %s for write, %s\n", filename,
+				 strerror( errno ) );
+		goto error_return;
+	}
+
+	/* ----------------------------------------------------------------------
+	** Write the file.  Pass 1.
+	*/
+	recs = fwrite_big32( lib->header.magicword, fp );
+	recs += fwrite_big32( lib->header.magicproc, fp );
+	recs += fwrite_big32( lib->header.magicflags, fp );
+	recs += fwrite_big32( lib->header.version, fp );
+	if( recs != 4 ) {
+		fprintf( stderr, "ar: error writing header for %s, %s\n", filename,
+				 strerror( errno ) );
+		goto error_return;
+	}
+
+	/* Keep track of the code/data size offsets.
+	*/
+	head_offs.codesize_offset = ftell( fp );
+	recs = fwrite_big32( codesize, fp );
+	head_offs.datasize_offset = ftell( fp );
+	recs += fwrite_big32( datasize, fp );
+	if( recs != 2 ) {
+		fprintf( stderr, "ar: error writing header for %s, %s\n", filename,
+				 strerror( errno ) );
+		goto error_return;
+	}
+
+	recs = fwrite_big32( num_objects, fp );
+	if( recs != 1 ) {
+		fprintf( stderr, "ar: error writing header for %s, %s\n", filename,
+				 strerror( errno ) );
+		goto error_return;
+	}
+
+	/* Write the object headers.
+	*/
+	for( idx = 0; idx < num_objects; idx++ ) {
+		recs = fwrite_big32( lib->files[idx].m_time, fp );
+
+		/* Keep track of the offsets, and write 0 for now.
+		*/
+		obj_offs[idx].filename_offset = ftell( fp );
+		recs += fwrite_big32( 0, fp );
+		obj_offs[idx].fullpath_offset = ftell( fp );
+		recs += fwrite_big32( 0, fp );
+		obj_offs[idx].data_offset = ftell( fp );
+		recs += fwrite_big32( 0, fp );
+
+		recs += fwrite_big32( lib->files[idx].object_size, fp );
+
+		if( recs != 5 ) {
+			fprintf( stderr, "ar: error writing object header for %s, %s\n", 
+					 filename, strerror( errno ) );
+			goto error_return;
+		}
+	}
+
+	/* Write the file names.
+	*/
+	for( idx = 0; idx < num_objects; idx++ ) {
+		/* Need to make sure that all the file names we write into the
+		** library DO NOT HAVE PATHS IN THEM, the world might end or something.
+		*/
+		size_t name_len = 0;
+		char *name_ptr = strrchr( lib->names[idx], '/' );
+
+		if( name_ptr == NULL ) {
+			name_ptr = lib->names[idx];
+		} else {
+			name_ptr++;
+		}
+
+		name_len = strlen( name_ptr ) + 1;
+
+		obj_offs[idx].filename_offset_value = ftell( fp );
+		recs = fwrite( name_ptr, name_len, 1, fp );
+		obj_offs[idx].fullpath_offset_value = ftell( fp );
+		recs += fwrite( name_ptr, name_len, 1, fp );
+
+		if( recs != 2 ) {
+			fprintf( stderr, "ar: error writing object name for %s, %s\n", 
+					 filename, strerror( errno ) );
+			goto error_return;
+		}
+	}
+
+	/* Pad the file if necessary.
+	*/
+	pad_amount = ftell( fp ) % 4;
+	if( pad_amount > 0 ) {
+		recs = fwrite( padding, pad_amount, 1, fp );
+
+		if( recs != 1 ) {
+			fprintf( stderr, "ar: error padding file %s, %s\n", filename,
+					 strerror( errno ) );
+			goto error_return;
+		}
+	}
+
+	/* Write the object file data.
+	*/
+	for( idx = 0; idx < num_objects; idx++ ) {
+		obj_offs[idx].data_offset_value = ftell( fp );
+
+		recs = fwrite( lib->data[idx], lib->files[idx].object_size, 1, fp );
+		if( recs != 1 ) {
+			fprintf( stderr, "ar: writing object data for %s, %s\n", filename,
+					 strerror( errno ) );
+			goto error_return;
+		}
+
+		/* Add up the code/data size.
+		*/
+		retval = add_object_sizes( (MWObject *)lib->data[idx], 
+								   &codesize, &datasize );
+		if( retval != B_OK ) {
+			fprintf( stderr, "ar - warning: %s is not an object file!\n",
+					 lib->names[idx] );
+			goto error_return;
+		}
+
+		pad_amount = ftell( fp ) % 4;
+		if( pad_amount > 0 ) {
+			recs = fwrite( padding, pad_amount, 1, fp );
+
+			if( recs != 1 ) {
+				fprintf( stderr, "ar: error padding file %s, %s\n", filename,
+						 strerror( errno ) );
+				goto error_return;
+			}
+		}
+	}
+
+	/* ----------------------------------------------------------------------
+	** Write the offsets into the file.  Pass 2.
+	*/
+
+	/* Write the code/data sizes.
+	*/
+	recs = fwrite_big32_seek( codesize, head_offs.codesize_offset, fp );
+	recs += fwrite_big32_seek( datasize, head_offs.datasize_offset, fp );
+	if( recs != 2 ) {
+		fprintf( stderr, "ar - error writing code and data sizes, %s\n",
+				 strerror( errno ) );
+		goto error_return;
+	}
+
+	/* Write the offsets for each file.
+	*/
+	for( idx = 0; idx < num_objects; idx++ ) {
+		recs = fwrite_big32_seek( obj_offs[idx].filename_offset_value,
+								  obj_offs[idx].filename_offset, fp );
+		recs += fwrite_big32_seek( obj_offs[idx].fullpath_offset_value,
+								   obj_offs[idx].fullpath_offset, fp );
+		recs += fwrite_big32_seek( obj_offs[idx].data_offset_value,
+								   obj_offs[idx].data_offset, fp );
+
+		if( recs != 3 ) {
+			fprintf( stderr, "ar - error writing object offsets, %s\n",
+					 strerror( errno ) );
+			goto error_return;
+		}
+	}
+
+	/* If all is OK, close the file and get out of here after nuking the
+	** temp file (if any), preserving the original file mode, and preserving
+	** the file attributes.
+	*/
+
+	fclose( fp );
+
+	/* Preserve the original file mode bits.
+	*/
+	retval = chmod( filename, mode_bits );
+	if( retval != 0 ) {
+		fprintf( stderr, "ar: unable to change file mode for %s, %s\n",
+				 filename, strerror( errno ) );
+	}
+
+	/* Nuke the temp file (if any), after copying over any file attributes.
+	*/
+	if( tmp_filename != NULL ) {
+		retval = copy_attrs( filename, tmp_filename );
+
+		retval = unlink( tmp_filename );
+		if( retval != 0 ) {
+			fprintf( stderr, "ar - error unlinking %s, %s\n", tmp_filename,
+					 strerror( errno ) );
+		}
+		free( tmp_filename );
+	} else {
+		/* If there isn't a temp file, we should still give this new
+		** file a file type attribute.
+		*/
+		setfiletype( filename, "application/x-mw-library" );
+	}
+
+	return B_OK;
+
+error_return:
+	/* Restore the original file if we had any problems.
+	*/
+	fclose( fp );
+
+	if( tmp_filename != NULL ) {
+		retval = unlink( filename );
+		retval = rename( tmp_filename, filename );
+		if( retval != 0 ) {
+			fprintf( stderr, "ar: can't restore %s to %s, %s\n",
+					 tmp_filename, filename, strerror( errno ) );
+		}
+	}
+
+	return B_ERROR;
+}
diff --git a/BeOS/ar-1.1/mwlib.h b/BeOS/ar-1.1/mwlib.h
new file mode 100644
index 0000000..67af325
--- /dev/null
+++ b/BeOS/ar-1.1/mwlib.h
@@ -0,0 +1,118 @@
+/*
+** mwlib.h - POSIX 1003.2 "ar" command
+**
+** $Id$
+**
+** This isn't a pure POSIX 1003.2 ar; it only manipulates Metrowerks
+** Library files, not general-purpose POSIX 1003.2 format archives.
+**
+** Dec. 14, 1997 Chris Herborth (chrish@qnx.com)
+**
+** This code is donated to the PUBLIC DOMAIN.  You can use, abuse, modify,
+** redistribute, steal, or otherwise manipulate this code.  No restrictions
+** at all.  If you laugh at this code, you can't use it.
+**
+** This "ar" was implemented using IEEE Std 1003.2-1992 as the basis for
+** the interface, and Metrowerk's published docs detailing their library
+** format.  Look inside for clues about how reality differs from MW's
+** documentation on BeOS...
+*/
+
+#include <support/SupportDefs.h>
+#include <time.h>
+
+/* ----------------------------------------------------------------------
+** Constants
+**
+*/
+#define MWLIB_MAGIC_WORD 'MWOB'
+#define MWLIB_MAGIC_PROC 'PPC '
+
+/* ----------------------------------------------------------------------
+** Structures
+**
+** This is based on the "Metrowerks CodeWarrior Library Reference
+** Specification", which isn't 100% accurate for BeOS.
+*/
+
+typedef struct MWLibHeader {
+	uint32 magicword;
+	uint32 magicproc;
+	uint32 magicflags;
+	uint32 version;
+
+	uint32 code_size;
+	uint32 data_size;
+
+	uint32 num_objects;
+} MWLibHeader;
+
+typedef struct MWLibFile {
+	time_t m_time;
+
+	uint32 off_filename;
+	uint32 off_fullpath;
+	uint32 off_object;
+	uint32 object_size;
+} MWLibFile;
+
+typedef struct MWLib {
+	MWLibHeader header;
+
+	MWLibFile *files;
+
+	char **names;
+
+	char **data;
+} MWLib;
+
+/* This bears no resemblance to what's in the Metrowerks docs.
+**
+** Note that this is incomplete; this is all the info I needed for
+** ar though.
+*/
+typedef struct MWObject {
+	uint32 magic_word;			/* 'MWOB' */
+	uint32 arch;				/* 'PPC '; this isn't in the docs */
+	uint32 version;
+	uint32 flags;
+
+	uint32 code_size;
+	uint32 data_size;
+} MWObject;
+
+/* ----------------------------------------------------------------------
+** Function prototypes
+**
+** load_MW_lib() - load a Metrowerks library
+**
+** Returns:
+**    B_OK - all is well
+**    B_FILE_NOT_FOUND - can't open the given file
+**    B_IO_ERROR - can't read from the given file
+**    B_BAD_VALUE - invalid magic word in the file
+**    B_MISMATCHED_VALUES - invalid processor value (ie, not a PowerPC lib),
+**                          or the magicflags member is not 0, or the file
+**                          version number isn't 1.
+**    B_NO_MEMORY - unable to allocate memory while loading the lib
+**
+** write_MW_lib() - write a Metrowerks library
+**
+** Returns:
+**    B_OK - all is well
+**
+** write_MW_lib() - write a Metrowerks library file
+**
+** Returns:
+**    B_OK - all is well; doesn't necessarily mean the file was written
+**           properly, just that you didn't lose any data
+**    B_NO_MEMORY - unable to allocate offset buffers
+**    B_ERROR - problem with backup file (can't rename existing file)
+**
+** Note:
+**    If you use this in a long-lived program, it leaks memory; the MWLib
+**    contents are never free()'d.
+*/
+status_t load_MW_lib( MWLib *lib, const char *filename );
+status_t write_MW_lib( MWLib *lib, const char *filename );
+void setfiletype( const char *filename, const char *type );
diff --git a/BeOS/linkcc b/BeOS/linkcc
new file mode 100755
index 0000000..9b95635
--- /dev/null
+++ b/BeOS/linkcc
@@ -0,0 +1,102 @@
+#! /bin/sh
+#
+# linkcc for Python
+# Chris Herborth (chrish@qnx.com)
+#
+# This is covered by the same copyright/licensing terms as the rest of
+# Python.
+#
+# Shell script to build the Python shared library properly; if we haven't
+# already built the export list, we'll need to link twice (argh...) so we
+# can eliminate some unwatnted global symbols from the system glue/init
+# objects.
+#
+# This is called by the Modules/Makefile as part of $(LINKCC):
+#
+# $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) $(MAINOBJ) \
+#	-L.. -lpython$(VERSION) $(MODLIBS) $(LIBS) $(SYSLIBS) -o python $(LDLAST)
+#
+# In 1.5.1 this changed to:
+#
+# $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) $(MAINOBJ) \
+#	$(LIBRARY) $(MODLIBS) $(LIBS) $(SYSLIBS) -o python $(LDLAST)
+#
+# For BeOS we should set $(LINKCC) to this in configure (similar to the
+# AIX situation):
+#
+# $(srcdir)../BeOS/linkcc $(LIBRARY) $(PURIFY) $(CC) -nodup $(OPT)
+#
+# -L.. -lpython$(VERSION) will automagically pick up the shared library.
+
+# Check to make sure we know what we're doing.
+system="`uname -m`"
+if [ "$system" != "BeMac" ] && [ "$system" != "BeBox" ] ; then
+	echo "Sorry, BeOS Python doesn't support x86 yet."
+	exit 1
+fi
+
+LIBRARY="$1"; shift
+
+# What we want to end up with.
+EXPORTS=${LIBRARY%.a}.exp
+DYNAMIC=${LIBRARY%.a}.so
+LINK_DYNAMIC="-l`echo ${DYNAMIC%.so} | sed -e s,\\\.\\\./,, -e s,lib,,`"
+
+# Grab the rest of the args and build them into the command used to
+# link the python binary.  Make sure we link against the shared lib
+# and not the static lib.
+LINK_CMD=""
+while [ "$#" != "0" ] ; do
+	case "$1" in
+		$LIBRARY)
+			LINK_CMD="$LINK_CMD -L.. $LINK_DYNAMIC"
+			shift
+			;;
+		*)
+			LINK_CMD="$LINK_CMD $1"
+			shift
+			;;
+	esac
+done
+
+# The shared libraries and glue objects we need to link against.
+LIBS="-lbe -lnet -lroot"
+GLUE="/boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o"
+
+# Unwanted symbols we need to eliminate; these are regular expressions
+# passed to egrep.
+SYMS="opterr optind optarg getopt __.* longjmp _.*_"
+
+# Check to see if we've already got an exports file, and delete it if
+# it's older than the lib.
+if [ -e $EXPORTS ] && [ $LIBRARY -nt $EXPORTS ] ; then
+	echo "Deleting old exports file for $DYNAMIC..."
+	rm -f $EXPORTS
+fi
+
+if [ ! -e $EXPORTS ] ; then
+	# First link; create the exports file with the unwanted global symbols
+	# in it.  It's a pity we don't have "nm" or something like that...
+	rm -f temp-exports.exp
+	mwcc -xms -f temp-exports.exp -o $DYNAMIC $LIBRARY $GLUE $LIBS -nodup
+
+	# Now clean out those bad symbols.
+	for sym in $SYMS ; do 
+		rm -f temp-exports.exp2
+		egrep -v "^$sym$" < temp-exports.exp > temp-exports.exp2
+		mv -f temp-exports.exp2 temp-exports.exp
+	done
+
+	rm -f temp-exports.exp2
+	mv -f temp-exports.exp $EXPORTS
+fi
+
+# Now link against the clean exports file.
+mwcc -xms -f $EXPORTS -o $DYNAMIC $LIBRARY $GLUE $LIBS -nodup
+
+# We'll need this or the python binary won't load libpython.so...
+( cd .. ; ln -sf `pwd` lib )
+
+# Now build the python binary.
+echo "Link command: $LINK_CMD"
+$LINK_CMD
diff --git a/BeOS/linkmodule b/BeOS/linkmodule
new file mode 100755
index 0000000..f0a6f9f
--- /dev/null
+++ b/BeOS/linkmodule
@@ -0,0 +1,70 @@
+#! /bin/sh
+#
+# linkmodule for Python
+# Chris Herborth (chrish@qnx.com)
+#
+# This is covered by the same copyright/licensing terms as the rest of
+# Python
+#
+# Shell script to build shared library versions of the modules; the
+# idea is to build an export list containing only the init*() function
+# for the module.  We _could_ assume for foomodule.o it was initfoo, but
+# that's asking for trouble... this is a little less efficient but correct.
+#
+# This is called by the Modules/Makefile as $(LDSHARED):
+#
+# $(LDSHARED) foomodule.o -o foomodule$(SO)
+#
+# Could also be called as:
+#
+# $(LDSHARED)  readline.o  -L/boot/home/config/lib -lreadline -ltermcap \
+# -o readline$(SO)
+
+# Check to make sure we know what we're doing.
+system="`uname -m`"
+if [ "$system" != "BeMac" ] && [ "$system" != "BeBox" ] ; then
+	echo "Sorry, BeOS Python doesn't support x86 yet."
+	exit 1
+fi
+
+# Make sure we got reasonable arguments.
+TARGET=""
+ARGS=""
+
+while [ "$#" != "0" ]; do
+	case "$1" in
+		-o)	TARGET="$2"; shift; shift;;
+		*)	ARGS="$ARGS $1"; shift;;
+	esac
+done
+
+if [ "$TARGET" = "" ] ; then
+	echo "Usage:"
+	echo
+	echo "	$0 [args] -o foomodule.so [args] foomodule.o [args]"
+	echo
+	echo "Where:"
+	echo
+	echo "	[args]	normal mwcc arguments"
+	exit 1
+fi
+
+EXPORTS=${TARGET%.so}.exp
+
+# The shared libraries and glue objects we need to link against; these
+# libs are overkill for most of the standard modules, but it makes life
+# in this shell script easier.
+LIBS="-L.. -lpython1.5 -lbe -lnet -lroot"
+GLUE="/boot/develop/lib/ppc/glue-noinit.a /boot/develop/lib/ppc/init_term_dyn.o"
+
+# Check to see if we've already got an exports file; we don't need to
+# update this once we've got it because we only ever want to export
+# one symbol.
+if [ ! -e $EXPORTS ] ; then
+	# The init*() function has to be related to the module's .so name
+	# for importdl to work.
+	echo init${TARGET%.so} | sed -e s/module// > $EXPORTS
+fi
+
+# Now link against the clean exports file.
+mwcc -xms -f $EXPORTS -o $TARGET $ARGS $GLUE $LIBS -nodup