Adding the BeOS port. More checkins to follow.
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">> 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)