Index: /releases/launch/1.0/launch/README
===================================================================
--- /releases/launch/1.0/launch/README	(revision 147)
+++ /releases/launch/1.0/launch/README	(revision 147)
@@ -0,0 +1,288 @@
+launch 1.0 [23 October 2003]
+==========
+
+A command-line launcher for Mac OS X in the spirit of open(1).
+
+Written by Nicholas Riley <mailto:launchsw@sabi.net>.
+Obtain updates from <http://web.sabi.net/nriley/software/>.
+
+WHAT IS IT?
+-----------
+
+Apple provides a simple command-line launching program called 'open'
+with Mac OS X.  It offers few options - launching applications by name
+or by path, launching TextEdit, or opening a number of applications,
+documents, folders, or URLs.  With the exception of special support for
+TextEdit (open -a), 'launch' does all this and:
+
+- opens URLs, directly or in your preferred helper application (-l)
+- lets you specify applications by their four-character creator
+  (e.g. 'ToyS') or Java-style bundle ID (e.g. com.apple.scripteditor),
+  both of which allow you to move or rename an application without
+  changing references to it
+- asks applications to print documents, something the OS X Finder
+  no longer permits
+- allows you to pipe output to GUI applictions
+- launches applications in the background
+- launches Carbon applications in Classic
+- displays file information including type, creator, bundle ID,
+  data and resource fork sizes, dates and version
+- reports errors intelligibly
+- and much more!
+
+'launch' is useful by itself, but is even better when used in scripts.
+Assign a shell command to your favorite Mac OS text, graphics or
+resource editor.  Go to your favorite Web site with a few keystrokes.
+
+Like 'open', 'launch' provides one half of the round-trip between
+Terminal.app and the Finder.  You can drag and drop icons or proxy icons
+into Terminal.app to insert their paths into command lines.  To go in the
+other direction, just type 'launch .' (or 'open .') to open a Finder window
+showing the current directory.
+
+INSTALLATION
+------------
+
+The commands below install the 'launch' tool in /usr/local/bin, which
+is in the default path.  You should subsequently be able to use
+'launch' by typing its name.  If you wish to install it somewhere else,
+modify the install line as appropriate.
+
+% sudo /usr/bin/install -d /usr/local/bin /usr/local/man/man1
+% sudo /usr/bin/install -c build/launch /usr/local/bin
+% sudo /usr/bin/install -c launch.1 /usr/local/man/man1
+% rehash
+
+Uninstallation:
+
+% sudo rm -f /usr/local/bin/launch /usr/local/man/man1/appswitch.1
+
+COMPILATION
+-----------
+
+An Xcode/Project Builder project, 'launch.pbproj', is included.  A
+precompiled binary is also provided.  'launch' was developed and
+tested under Mac OS 10.3 with the October 2003 Developer Tools, and
+does not require any additional software to build.
+
+USAGE
+-----
+
+Just type 'launch' by itself to receive usage information.
+
+Some examples:
+
+% launch -c 'R*ch'
+[BBEdit opens]
+                                
+% launch -pbc 'R*ch' test.txt
+[BBEdit starts printing test.txt in the background]
+
+% ls -l | launch -c CWIE -
+[CodeWarrior IDE opens with an untitled document containing the file list]
+
+% launch -i org.mozilla.navigator http://www.apple.com/
+[Camino opens Apple's Web site]
+
+% launch -l launchsw@sabi.net
+[Your preferred email client opens a new message to comment on launch]
+
+% launch -f /Applications/Preview.app
+/Applications/Preview.app: Mac OS X application package 
+        type: 'APPL'    creator: 'prvw'
+        bundle ID: com.apple.Preview
+        version: 2.1.0
+        kind: Application
+        contents: 1 item
+[...]
+
+A scripting example: a zsh function which provides an OS X wrapper
+around emacsclient and the Carbon build of GNU Emacs, using launch and
+appswitch (another one of my command-line tools).
+
+    e() {
+      ( emacsclient -n $@ >&/dev/null && \
+	appswitch -a Emacs ) || \
+      ( launch -ba Emacs && \
+  	until { emacsclient -n $@ >&/dev/null } do sleep 1; done;
+        appswitch -a Emacs )
+      export EDITOR=emacsclient
+    }
+
+FREQUENTLY ASKED QUESTIONS
+--------------------------
+
+Q. How do I discover bundle IDs for applications?
+
+A. The -f option to launch can help.  Say you have OmniWeb in the
+/Applications/Internet folder, and want to find out its bundle ID.
+Type 'launch -f', and drop the OmniWeb icon on Terminal:
+
+% launch -f /Applications/Internet/OmniWeb.app
+/Applications/Internet/OmniWeb.app: Mac OS X application package 
+        type: 'APPL'    creator: 'OWEB'
+        bundle ID: com.omnigroup.OmniWeb
+        version: 4.5
+        kind: Application
+
+Note that bundle IDs are not case-sensitive: com.barebones.BBEdit is
+the same as com.barebones.bbedit.
+
+
+Q. Why does application X open a file with a name beginning with 
+'launch-stationery-'?  
+
+A. Your application does not support stationery.  Applications which
+support stationery respond to it by creating a new untitled document
+with the contents of the stationery.  Most Cocoa applications, such as
+TextEdit, do not support stationery.  (Omni Group applications are a
+notable exception.)  If you're looking for a text editor which
+supports stationery, try BBEdit, Tex-Edit Plus, the CodeWarrior IDE,
+or almost any other Carbon editor.
+
+For the curious: launch processes input by simultaneously reading it
+and writing to a temporary stationery file.  Once reading is complete,
+launch opens the stationery file with your selected application, and
+deletes the stationery after one minute (as a safeguard, it is not
+possible to accurately gauge how long it will take for the application
+to open the stationery).
+
+
+Q. Why can't I use -f with -c to get info on an application with a
+given creator (or -f with -i for a bundle ID)?
+
+A. This feature may be added to a later version (or add it yourself!),
+but there is a workaround.  Instead of:
+
+% launch -f -c 'Doug'
+launch: can't get information (-f) on item(s) using an application (-u, -c, -i, -a)
+
+use:
+
+% launch -f "`launch -nc 'Doug'`"
+/Volumes/GrayApps/Utilities/Resorcerer 2.4/Resorcerer: scriptable Mac OS X application [Carbon, prefers native OS X]
+        type: 'APPL'    creator: 'Doug'
+        bundle ID: com.mathemaesthetics.resorcerer
+        version: 2.4 [0x2418010 = 37847056]
+        kind: Application
+[...]
+
+
+Q. Why won't launch locate non-packaged applications by their bundle
+identifier?
+
+A. This was a LaunchServices/CFBundle bug, fixed in Mac OS X 10.2.
+For example, BBEdit 6.1 for OS X was a packaged application; BBEdit
+6.5 is not, however its 'plst' resource contains a bundle ID.
+LaunchServices prior to OS X 10.2 was unable to locate BBEdit 6.5 by
+its bundle ID.
+
+Non-packaged applications usually originated as Mac OS applications,
+so they will have creators.  If you're using Mac OS X 10.1.x, try
+using the creator instead of the bundle ID as a workaround (-c instead
+of -i).
+
+
+Q. Why doesn't launch support opening items as root?
+
+A. Apple eliminated this capability with the Mac OS X 10.1 Security
+Update.  If at some point Apple restores this capability, 'launch'
+will be ready to support it.
+
+
+Q. Why do I get an error -600?
+
+A. A typical occurrence of this would be:
+
+% launch -n .
+launch: can't open items: unable to connect to system service.
+Are you logged in? (-600)
+
+In order to perform certain operations, launch needs to talk to
+various system services owned by the currently logged-on user.  If you
+aren't using 'launch' from a terminal currently logged into the Mac OS
+X GUI, certain operations may not work.  Try opening Terminal.app,
+creating a new terminal, and trying again.
+
+Another possibility is to create your own interprocess messaging.
+For example, place this script in a file:
+
+#!/bin/sh
+PIPE=/tmp/.launchpipe
+[ -e $PIPE ] || mkfifo $PIPE
+while true; do
+    read opts < $PIPE
+    eval "/path/to/launch $opts" & # change this to launch's path
+done
+
+Then, define a function or alias.  For zsh:
+
+rlaunch() { echo $@ > /tmp/.launchpipe }
+
+Or for tcsh:
+
+alias rlaunch 'echo \!* > /tmp/.launchpipe'
+
+Start the shell script above from the console, then you can use
+'rlaunch' in place of 'launch' logged in from anywhere else.
+
+Thanks to robert <robert@allyourbass.org> for this suggestion.
+
+COMMENTS, SUGGESTIONS, BUG REPORTS, ETC.
+----------------------------------------
+
+Please send to the author, Nicholas Riley, at <launchsw@sabi.net>.
+
+VERSION HISTORY
+---------------
+
+1.0 - 23 October 2003
+ - work around CFBundle bug to report bundle identifiers and versions
+   from resource forks of unpackaged Carbon applications and Classic
+   applications [Lloyd Dupont]
+ - added descriptions for more error codes and clarified error
+   reporting
+ - output all errors to stderr
+ - provide better errors for -X option
+ - restored -m: OS X bug is fixed in Panther
+ - fixed a couple of tiny memory leaks
+ - added man page [Hisashi T Fujinaka]
+ - work around bug in LSOpenFromURLSpec opening multiple items in
+   Mac OS X 10.3
+1.0b2 - 9 March 2003
+ - fixed install instructions to create /usr/local/bin if needed
+ - show bundle version with text, hex and integer representations
+1.0b1 - 14 December 2002
+ - accept "slack" (default http) URLs and email addresses with -l
+ - accept input from stdin with '-'
+ - open URLs with arbitrary applications when specified without -l
+ - builds without compiler warnings
+1.0a9 - 2 April 2002
+ - license, comments changes
+1.0a8 - 29 March 2002
+ - errors with -l (from ICeCoffEE), added rlaunch script
+1.0a7 - 3 March 2002
+ - print dates, sizes, folder valence, locked status for -f
+ - don't abort on failure to obtain bundle information
+1.0a6 - 30 November 2001
+ - fixed incorrect messages, broken -u and crash on -nu
+1.0a5 - 28 November 2001
+ - print kind string for -f, still no new installer
+1.0a4 - 20 November 2001
+ - [try to] use Installer VISE instead of InstallAnywhere
+1.0a3 - 15 November 2001
+ - fixed package identification in -f, updated examples
+1.0a2 - 15 November 2001
+ - -f, removed broken -m
+1.0a1 - 14 November 2001
+ - renamed from "FindApp", launch by default, -u
+1.0d5 - 7 November 2001
+ - option -s for launching as root [nonfunctional]
+1.0d4 - 6 November 2001
+ - URL launching and Internet Config support
+1.0d3 - 4 November 2001
+ - more robust, support for docs without app
+1.0d2 - 4 November 2001
+ - options -opsbmhCX, -cin, documents
+1.0d1 - 26 August 2001
+ - returns path of application identified by creator
Index: /releases/launch/1.0/launch/VERSION
===================================================================
--- /releases/launch/1.0/launch/VERSION	(revision 147)
+++ /releases/launch/1.0/launch/VERSION	(revision 147)
@@ -0,0 +1,1 @@
+1.0
Index: /releases/launch/1.0/launch/launch.1
===================================================================
--- /releases/launch/1.0/launch/launch.1	(revision 147)
+++ /releases/launch/1.0/launch/launch.1	(revision 147)
@@ -0,0 +1,132 @@
+.Dd Wed Oct 22 2003      \" DATE 
+.Dt LAUNCH 1 LOCAL	 \" Program name and manual section number 
+.Os launch 1.0
+.Sh NAME
+.Nm launch
+.Nd find, open, print, or get information about files, folders, disks and URLs
+.Sh SYNOPSIS
+.Nm launch
+.Op Fl npswbmhCX         \" [-npswbmhCX]
+.Op Fl c Ar creator      \" [-c creator]
+.Op Fl i Ar bundleID     \" [-i bundleID]
+.Op Fl u Ar URL          \" [-u URL]
+.Op Fl a Ar name         \" [-a name]
+.Op Ar item ...          \" [item ...]
+.Op Ar -                 \" [-]
+.Nm 
+.Op Fl npflswbmhCX
+.Ar item ...
+.Sh DESCRIPTION
+The
+.Nm
+command is a replacement for Mac OS X's
+.Xr open 1
+command and opens a file (or a folder/directory or URL), as if you had
+double-clicked its icon in the Finder. If no application is specified,
+the default application determined by LaunchServices is used to open
+items.
+.Pp
+.Nm
+invoked with a file or URL argument will open the URL directly or in
+your preferred helper application. Applications can be specified by
+their four-character creators (e.g. 'ToyS') or Java-style bundle ID
+(e.g. com.apple.scripteditor).
+.Pp
+.Nm
+can ask applications to print documents, a feature the OS X Finder is
+still missing.  It can open applications in the background; can open
+multiple copies of applications; can open Carbon applications in
+Classic, or prevent Classic from starting; and can show information
+about any item on disk, including file type, creator, data and
+resource fork sizes, dates, and bundle ID.
+.Pp
+The options to
+.Nm
+are divided in three sections according to purpose. You can give
+.Nm
+a reference to an application in many ways, using the matching
+options. Once
+.Nm
+has identified one or more items, the action options indicate what to
+do with these items. Finally, if the action involves launching an
+application, the launch options allow further customization.
+.Ss Matching options
+.Bl -tag -width -indent
+.It Fl c Ar creator
+Match by creator (a four-character code, also known as a signature).
+.It Fl i Ar bundleID
+Match by bundle identifier, usually consisting of the reversed dot
+(.)-separated components of the application developer's Internet domain
+name, followed by the application name.  For example, the Finder's
+bundle identifier is
+.Ar com.apple.Finder .
+Bundle identifiers are not case-sensitive.
+.It Fl u Ar URL
+Match application at
+.Ar URL
+(which must be a file:// URL).
+.El
+.Pp
+In addition to the above, you can specify applications, documents,
+folders, disks and URLs as item arguments.
+.Ss Action options
+.Bl -tag -width -indent
+.It Fl n
+Print matching paths/URLs instead of opening them.
+.It Fl p
+Ask application(s) to print document(s).
+.It Fl f
+Display information about item(s).
+.It Fl l
+Launch URLs, treating "http://" URLs as Web sites instead of WebDAV
+resources.
+.El
+.Ss Launch options
+.Bl -tag -width -indent
+.It Fl s
+Launch target(s) as superuser, authenticating if needed.
+.It Fl w
+Wait for application to finish opening before exiting.
+.It Fl b
+Launch application in the background.
+.It Fl m
+Launch application again, even if already running.
+.It Fl h
+Hide application after it finishes opening.
+.It Fl C
+Force CFM/PEF Carbon application to open in Classic.
+.It Fl X
+Don't start the Classic environment for this Classic application if
+Classic isn't running.
+.El
+.Sh SEE ALSO 
+.\" List links in ascending order by section, alphabetically within a section.
+.\" Please do not reference files that do not exist without filing a bug report
+.Xr appswitch 1 ,
+.Xr GetFileInfo 1 ,
+.Xr open 1
+.Sh BUGS              \" Document known, unremedied bugs
+Launching may be very slow on Mac OS X 10.2.8 and earlier; this is an
+acknowledged Mac OS X bug with no known workaround, and may affect
+Apple's
+.Xr open 1
+command as well in certain cases.  It is fixed in Mac OS X 10.3.
+.Pp
+The
+.Fl m
+option may not work well (or at all) before Mac OS X 10.3 because of
+Mac OS X bugs.
+.Pp
+The
+.Fl h
+option requires the
+.Fl b
+option to be used as well, or Cocoa applications will not hide on
+startup.  This is a Mac OS X bug which is still unfixed as of Mac OS X
+10.3.
+.Sh AUTHOR
+.An "Nicholas Riley" Aq launchsw@sabi.net
+.Pp
+This page written in part by
+.An "Hisashi T Fujinaka" Aq htodd@twofifty.com .
+.\" .Sh HISTORY           \" Document history if command behaves in a unique manner 
Index: /releases/launch/1.0/launch/launch.pbproj/nicholas.pbxuser
===================================================================
--- /releases/launch/1.0/launch/launch.pbproj/nicholas.pbxuser	(revision 147)
+++ /releases/launch/1.0/launch/launch.pbproj/nicholas.pbxuser	(revision 147)
@@ -0,0 +1,613 @@
+// !$*UTF8*$!
+{
+	08FB7793FE84155DC02AAC07 = {
+		activeBuildStyle = 014CEA490018CE3211CA2923;
+		activeExecutable = F561F49E0139D79101AEEDB1;
+		activeTarget = 08FB779FFE84155DC02AAC07;
+		addToTargets = (
+			08FB779FFE84155DC02AAC07,
+		);
+		breakpoints = (
+			E14C949A052A8B0600142529,
+		);
+		codeSenseManager = E14C945F052A896100142529;
+		executables = (
+			F561F49E0139D79101AEEDB1,
+		);
+		perUserDictionary = {
+			PBXConfiguration.PBXFileTableDataSource3.PBXErrorsWarningsDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = -1;
+				PBXFileTableDataSourceColumnSortingKey = PBXErrorsWarningsDataSource_LocationID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					353.8799,
+					199.2085,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXErrorsWarningsDataSource_TypeID,
+					PBXErrorsWarningsDataSource_MessageID,
+					PBXErrorsWarningsDataSource_LocationID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					22,
+					407.7974,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXExecutablesDataSource_ActiveFlagID,
+					PBXExecutablesDataSource_NameID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = -1;
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					341,
+					20,
+					65,
+					43,
+					43,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+					PBXFileDataSource_Target_ColumnID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXFindDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFindDataSource_LocationID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					284.2974,
+					287.2085,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFindDataSource_MessageID,
+					PBXFindDataSource_LocationID,
+				);
+			};
+			PBXPerProjectTemplateStateSaveDate = 88634057;
+			PBXWorkspaceContents = (
+				{
+					PBXProjectWorkspaceModule_StateKey_Rev36 = {
+						PBXProjectWorkspaceModule_EditorOpen = true;
+						PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
+							Split0 = {
+								bookmark = E1A087D20548746200594651;
+								history = (
+									E1375C530530898300FE8BF8,
+									E103506B05355596002A18D1,
+									E11E9B8E0544EE7900045D4F,
+									E11E9B8F0544EE7900045D4F,
+									E1A087BB0548731500594651,
+									E1A087CE0548746200594651,
+									E1A087CF0548746200594651,
+									E1A087D00548746200594651,
+								);
+								nextStack = (
+									E1A087D10548746200594651,
+								);
+								prevStack = (
+									E1375C560530898300FE8BF8,
+									E103506C05355596002A18D1,
+								);
+							};
+							SplitCount = 1;
+						};
+						PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {595, 0}}";
+						PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 0}, {595, 671}}";
+						PBXProjectWorkspaceModule_OldSuperviewFrame = "{{180, 0}, {595, 671}}";
+						PBXProjectWorkspaceModule_RunWindowVisible = true;
+						PBXProjectWorkspaceModule_SGTM = {
+							PBXBottomSmartGroupGIDs = (
+								1C37FBAC04509CD000000102,
+								1C37FAAC04509CD000000102,
+								1C08E77C0454961000C914BD,
+								1CC0EA4004350EF90044410B,
+								1CC0EA4004350EF90041110B,
+								1C37FABC05509CD000000102,
+								1C37FABC05539CD112110102,
+								1C37FABC04509CD000100104,
+							);
+							PBXTopSmartGroupGIDs = (
+							);
+						};
+					};
+				},
+				{
+					PBXProjectWorkspaceModule_StateKey_Rev36 = {
+						PBXProjectWorkspaceModule_EditorOpen = true;
+						PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
+							Split0 = {
+								bookmark = E1A087D40548746200594651;
+								history = (
+									E1A087D30548746200594651,
+								);
+							};
+							SplitCount = 1;
+						};
+						PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {600, 115}}";
+						PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 115}, {600, 186}}";
+						PBXProjectWorkspaceModule_OldSuperviewFrame = "{{0, 0}, {600, 301}}";
+						PBXProjectWorkspaceModule_SGTM = {
+							PBXBottomSmartGroupGIDs = (
+							);
+							PBXTopSmartGroupGIDs = (
+							);
+						};
+					};
+				},
+			);
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
+			};
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = {
+			};
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
+			};
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugSessionModule" = {
+			};
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXDebugSingleDataValueViewModule" = {
+			};
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
+				Split0 = {
+					bookmark = E1A087CB0548731E00594651;
+					history = (
+						E1A087CA0548731E00594651,
+					);
+				};
+				SplitCount = 1;
+			};
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
+				PBXProjectWorkspaceModule_StateKey_Rev36 = {
+					PBXProjectWorkspaceModule_EditorOpen = true;
+					PBXProjectWorkspaceModule_EmbeddedNavigatorGroup = {
+						Split0 = {
+							bookmark = E1A087C60548731900594651;
+							history = (
+								E1A087C40548731800594651,
+							);
+						};
+						SplitCount = 1;
+					};
+					PBXProjectWorkspaceModule_OldDetailFrame = "{{0, 0}, {600, 115}}";
+					PBXProjectWorkspaceModule_OldEditorFrame = "{{0, 115}, {600, 186}}";
+					PBXProjectWorkspaceModule_OldSuperviewFrame = "{{0, 0}, {600, 301}}";
+					PBXProjectWorkspaceModule_SGTM = {
+						PBXBottomSmartGroupGIDs = (
+						);
+						PBXTopSmartGroupGIDs = (
+						);
+					};
+				};
+			};
+			"PBXWorkspaceContents:PBXConfiguration.PBXModule.PBXRunSessionModule" = {
+			};
+			PBXWorkspaceGeometries = (
+				{
+					Frame = "{{0, 0}, {775, 691}}";
+					PBXProjectWorkspaceModule_GeometryKey_Rev11 = {
+						PBXProjectWorkspaceModule_SGTM_Geometry = {
+							_collapsingFrameDimension = 182;
+							_indexOfCollapsedView = 0;
+							_percentageOfCollapsedView = 0.2363636;
+							sizes = (
+								"{{0, 0}, {180, 671}}",
+								"{{180, 0}, {595, 671}}",
+							);
+						};
+					};
+					WindowFrame = "{{8, 70}, {775, 753}}";
+				},
+				{
+					Frame = "{{0, 0}, {600, 321}}";
+					PBXProjectWorkspaceModule_GeometryKey_Rev11 = {
+						GroupTreeCollapsed = yes;
+						PBXProjectWorkspaceModule_SGTM_Geometry = {
+							_collapsingFrameDimension = 182;
+							_indexOfCollapsedView = 0;
+							_percentageOfCollapsedView = 0.3033333;
+							sizes = (
+								"{{0, 0}, {600, 301}}",
+							);
+						};
+					};
+					WindowFrame = "{{523, 63}, {600, 383}}";
+				},
+			);
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXBuildResultsModule" = {
+				Frame = "{{0, 0}, {480, 216}}";
+				WindowFrame = "{{790, 46}, {480, 294}}";
+			};
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugBreakpointsModule" = {
+				BreakpointsTreeTableConfiguration = (
+					enabledColumn,
+					16,
+					breakpointColumn,
+					141.583,
+				);
+				Frame = "{{0, 0}, {180, 158}}";
+				WindowFrame = "{{62, 4}, {180, 180}}";
+			};
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugCLIModule" = {
+				Frame = "{{0, 0}, {500, 278}}";
+				WindowFrame = "{{200, 200}, {500, 300}}";
+			};
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugSessionModule" = {
+				DebugConsoleDrawerSize = "{100, 120}";
+				DebugConsoleVisible = None;
+				DebugConsoleWindowFrame = "{{200, 200}, {500, 300}}";
+				DebugSTDIOWindowFrame = "{{200, 200}, {500, 300}}";
+				Frame = "{{0, 0}, {745, 442}}";
+				WindowFrame = "{{267, 311}, {745, 511}}";
+			};
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXDebugSingleDataValueViewModule" = {
+				Frame = "{{0, 0}, {400, 66}}";
+				WindowFrame = "{{20, 632}, {400, 88}}";
+			};
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXNavigatorGroup" = {
+				Frame = "{{0, 0}, {750, 480}}";
+				WindowFrame = "{{15, 325}, {750, 502}}";
+			};
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXProjectWorkspaceModule" = {
+				Frame = "{{0, 0}, {600, 321}}";
+				PBXProjectWorkspaceModule_GeometryKey_Rev11 = {
+					GroupTreeCollapsed = yes;
+					PBXProjectWorkspaceModule_SGTM_Geometry = {
+						_collapsingFrameDimension = 182;
+						_indexOfCollapsedView = 0;
+						_percentageOfCollapsedView = 0.3033333;
+						sizes = (
+							"{{0, 0}, {600, 301}}",
+						);
+					};
+				};
+				WindowFrame = "{{523, 63}, {600, 383}}";
+			};
+			"PBXWorkspaceGeometries:PBXConfiguration.PBXModule.PBXRunSessionModule" = {
+				Frame = "{{0, 0}, {517, 227}}";
+				WindowFrame = "{{723, 149}, {517, 249}}";
+			};
+			PBXWorkspaceStateSaveDate = 88634057;
+		};
+		perUserProjectItems = {
+			E103506B05355596002A18D1 = E103506B05355596002A18D1;
+			E103506C05355596002A18D1 = E103506C05355596002A18D1;
+			E11E9B8E0544EE7900045D4F = E11E9B8E0544EE7900045D4F;
+			E11E9B8F0544EE7900045D4F = E11E9B8F0544EE7900045D4F;
+			E1375C530530898300FE8BF8 = E1375C530530898300FE8BF8;
+			E1375C560530898300FE8BF8 = E1375C560530898300FE8BF8;
+			E1A087BB0548731500594651 = E1A087BB0548731500594651;
+			E1A087CE0548746200594651 = E1A087CE0548746200594651;
+			E1A087CF0548746200594651 = E1A087CF0548746200594651;
+			E1A087D00548746200594651 = E1A087D00548746200594651;
+			E1A087D10548746200594651 = E1A087D10548746200594651;
+			E1A087D20548746200594651 = E1A087D20548746200594651;
+			E1A087D30548746200594651 = E1A087D30548746200594651;
+			E1A087D40548746200594651 = E1A087D40548746200594651;
+		};
+		sourceControlManager = E14C945E052A896100142529;
+		userBookmarkGroup = E190CFF903AAA80600AEFBE0;
+		userBuildSettings = {
+		};
+	};
+	08FB7796FE84155DC02AAC07 = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {559, 13579}}";
+			sepNavSelRange = "{33212, 0}";
+			sepNavVisRect = "{{0, 12355}, {559, 169}}";
+			sepNavWindowFrame = "{{265, 76}, {725, 703}}";
+		};
+	};
+	08FB779FFE84155DC02AAC07 = {
+		activeExec = 0;
+		executables = (
+			F561F49E0139D79101AEEDB1,
+		);
+	};
+	E103506B05355596002A18D1 = {
+		fRef = E1375C5D0530898300FE8BF8;
+		isa = PBXTextBookmark;
+		name = "LSOpen.h: 241";
+		rLen = 0;
+		rLoc = 8490;
+		rType = 0;
+		vrLen = 1029;
+		vrLoc = 7546;
+	};
+	E103506C05355596002A18D1 = {
+		fRef = E1375C5D0530898300FE8BF8;
+		isa = PBXTextBookmark;
+		name = "LSOpen.h: 241";
+		rLen = 0;
+		rLoc = 8490;
+		rType = 0;
+		vrLen = 1029;
+		vrLoc = 7546;
+	};
+	E103508E0535B52C002A18D1 = {
+		isa = PBXFileReference;
+		name = CFString.h;
+		path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFString.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	E11E9B8E0544EE7900045D4F = {
+		fRef = E11E9B950544EE9700045D4F;
+		isa = PBXTextBookmark;
+		name = "(null): 158";
+		rLen = 0;
+		rLoc = 8234;
+		rType = 0;
+		vrLen = 1977;
+		vrLoc = 6660;
+	};
+	E11E9B8F0544EE7900045D4F = {
+		fRef = E103508E0535B52C002A18D1;
+		isa = PBXTextBookmark;
+		name = "CFString.h: CFStringCreateWithCString";
+		rLen = 16;
+		rLoc = 6861;
+		rType = 0;
+		vrLen = 2215;
+		vrLoc = 5649;
+	};
+	E11E9B940544EE9700045D4F = {
+		expectedFileType = sourcecode.c.h;
+		isa = PBXFileReference;
+		name = CFURL.h;
+		path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFURL.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {554, 6019}}";
+			sepNavSelRange = "{18538, 58}";
+			sepNavVisRect = "{{0, 5362}, {554, 654}}";
+		};
+	};
+	E11E9B950544EE9700045D4F = {
+		isa = PBXFileReference;
+		name = CFStringEncodingExt.h;
+		path = /System/Library/Frameworks/CoreFoundation.framework/Versions/A/Headers/CFStringEncodingExt.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	E11E9B960544EE9700045D4F = {
+		expectedFileType = sourcecode.c.h;
+		isa = PBXFileReference;
+		name = LSOpen.h;
+		path = /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LSOpen.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {578, 3891}}";
+			sepNavSelRange = "{2548, 27}";
+			sepNavVisRect = "{{0, 856}, {578, 654}}";
+		};
+	};
+	E1375C530530898300FE8BF8 = {
+		fRef = E1375C5C0530898300FE8BF8;
+		isa = PBXTextBookmark;
+		name = "(null): 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 688;
+		vrLoc = 0;
+	};
+	E1375C560530898300FE8BF8 = {
+		fRef = E1375C5B0530898300FE8BF8;
+		isa = PBXTextBookmark;
+		name = "(null): 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 688;
+		vrLoc = 0;
+	};
+	E1375C5B0530898300FE8BF8 = {
+		isa = PBXFileReference;
+		name = LaunchServices.h;
+		path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LaunchServices.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	E1375C5C0530898300FE8BF8 = {
+		isa = PBXFileReference;
+		name = LaunchServices.h;
+		path = /Developer/SDKs/MacOSX10.2.7.sdk/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LaunchServices.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	E1375C5D0530898300FE8BF8 = {
+		isa = PBXFileReference;
+		name = LSOpen.h;
+		path = /Developer/SDKs/MacOSX10.3.0.sdk/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Headers/LSOpen.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	E14C945E052A896100142529 = {
+		isa = PBXSourceControlManager;
+		scmConfiguration = {
+		};
+		scmType = scm.cvs;
+	};
+	E14C945F052A896100142529 = {
+		indexTemplatePath = "";
+		isa = PBXCodeSenseManager;
+		usesDefaults = 1;
+		wantsCodeCompletion = 1;
+		wantsCodeCompletionAutoPopup = 0;
+		wantsCodeCompletionAutoSuggestions = 0;
+		wantsCodeCompletionCaseSensitivity = 1;
+		wantsCodeCompletionOnlyMatchingItems = 1;
+		wantsCodeCompletionParametersIncluded = 1;
+		wantsCodeCompletionPlaceholdersInserted = 1;
+		wantsCodeCompletionTabCompletes = 1;
+		wantsIndex = 1;
+	};
+	E14C949A052A8B0600142529 = {
+		fileReference = 08FB7796FE84155DC02AAC07;
+		isa = PBXFileBreakpoint;
+		lineNumber = 674;
+		state = 1;
+	};
+	E190CFF903AAA80600AEFBE0 = {
+		children = (
+			E190CFFB03AAA84B00AEFBE0,
+		);
+		isa = PBXBookmarkGroup;
+		name = Root;
+	};
+	E190CFFB03AAA84B00AEFBE0 = {
+		fRef = 08FB7796FE84155DC02AAC07;
+		isa = PBXTextBookmark;
+		name = "handle URL/file arguments";
+		rLen = 0;
+		rLoc = 17894;
+		rType = 0;
+		vrLen = 1773;
+		vrLoc = 14523;
+	};
+	E1A087BB0548731500594651 = {
+		fRef = E11E9B960544EE9700045D4F;
+		isa = PBXTextBookmark;
+		name = "LSOpen.h: LSLaunchFSRefSpec";
+		rLen = 27;
+		rLoc = 2548;
+		rType = 0;
+		vrLen = 2176;
+		vrLoc = 1426;
+	};
+	E1A087C80548731D00594651 = {
+		expectedFileType = sourcecode.c.c;
+		isa = PBXFileReference;
+		name = main.c;
+		path = /Volumes/Ti/Users/nicholas/Documents/Development/launch/launch/main.c;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	E1A087CE0548746200594651 = {
+		fRef = E11E9B940544EE9700045D4F;
+		isa = PBXTextBookmark;
+		name = "CFURL.h: CFURLGetFSRef";
+		rLen = 58;
+		rLoc = 18538;
+		rType = 0;
+		vrLen = 1812;
+		vrLoc = 16881;
+	};
+	E1A087CF0548746200594651 = {
+		fRef = E1A087D50548746200594651;
+		isa = PBXTextBookmark;
+		name = "(null): 5155";
+		rLen = 0;
+		rLoc = 175675;
+		rType = 0;
+		vrLen = 2070;
+		vrLoc = 174398;
+	};
+	E1A087D00548746200594651 = {
+		fRef = 08FB7796FE84155DC02AAC07;
+		isa = PBXTextBookmark;
+		name = "main.c: 805";
+		rLen = 5;
+		rLoc = 33076;
+		rType = 0;
+		vrLen = 1438;
+		vrLoc = 31911;
+	};
+	E1A087D10548746200594651 = {
+		fRef = E1A087D60548746200594651;
+		isa = PBXTextBookmark;
+		name = "(null): 5155";
+		rLen = 0;
+		rLoc = 175675;
+		rType = 0;
+		vrLen = 2070;
+		vrLoc = 174398;
+	};
+	E1A087D20548746200594651 = {
+		fRef = 08FB7796FE84155DC02AAC07;
+		isa = PBXTextBookmark;
+		name = "main.c: 805";
+		rLen = 0;
+		rLoc = 33089;
+		rType = 0;
+		vrLen = 1436;
+		vrLoc = 31909;
+	};
+	E1A087D30548746200594651 = {
+		fRef = E1A087C80548731D00594651;
+		isa = PBXTextBookmark;
+		rLen = 1;
+		rLoc = 808;
+		rType = 1;
+	};
+	E1A087D40548746200594651 = {
+		fRef = 08FB7796FE84155DC02AAC07;
+		isa = PBXTextBookmark;
+		name = "main.c: 809";
+		rLen = 0;
+		rLoc = 33212;
+		rType = 0;
+		vrLen = 325;
+		vrLoc = 33020;
+	};
+	E1A087D50548746200594651 = {
+		isa = PBXFileReference;
+		name = Files.h;
+		path = /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/Files.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	E1A087D60548746200594651 = {
+		isa = PBXFileReference;
+		name = Files.h;
+		path = /System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/Headers/Files.h;
+		refType = 0;
+		sourceTree = "<absolute>";
+	};
+	F561F49E0139D79101AEEDB1 = {
+		activeArgIndex = 2;
+		activeArgIndices = (
+			NO,
+			NO,
+			YES,
+		);
+		argumentStrings = (
+			"-nu file:///Applications/Prerelease/Mozilla.app",
+			"-c MSIE http://web.sabi.net/",
+			"-f /Volumes/Ti/Applications/iTunes.app",
+		);
+		configStateDict = {
+		};
+		debuggerPlugin = GDBDebugging;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		isa = PBXExecutable;
+		name = launch;
+		shlibInfoDictList = (
+		);
+		sourceDirectories = (
+		);
+	};
+	F5C0CA9501B5740C01AEEDB1 = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {709, 3779}}";
+			sepNavSelRange = "{7907, 0}";
+			sepNavVisRect = "{{0, 3118}, {709, 443}}";
+			sepNavWindowFrame = "{{38, 304}, {750, 502}}";
+		};
+	};
+}
Index: /releases/launch/1.0/launch/launch.pbproj/project.pbxproj
===================================================================
--- /releases/launch/1.0/launch/launch.pbproj/project.pbxproj	(revision 147)
+++ /releases/launch/1.0/launch/launch.pbproj/project.pbxproj	(revision 147)
@@ -0,0 +1,305 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 39;
+	objects = {
+		014CEA490018CE3211CA2923 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = NO;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				OPTIMIZATION_CFLAGS = "-O0";
+				ZERO_LINK = YES;
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		014CEA4A0018CE3211CA2923 = {
+			buildRules = (
+			);
+			buildSettings = {
+				COPY_PHASE_STRIP = YES;
+				GCC_ENABLE_FIX_AND_CONTINUE = NO;
+				ZERO_LINK = NO;
+			};
+			isa = PBXBuildStyle;
+			name = Deployment;
+		};
+//010
+//011
+//012
+//013
+//014
+//030
+//031
+//032
+//033
+//034
+		034768E2FF38A6DC11DB9C8B = {
+			expectedFileType = "compiled.mach-o.executable";
+			fallbackIsa = PBXFileReference;
+			isa = PBXExecutableFileReference;
+			path = launch;
+			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+//030
+//031
+//032
+//033
+//034
+//080
+//081
+//082
+//083
+//084
+		08FB7793FE84155DC02AAC07 = {
+			buildSettings = {
+			};
+			buildStyles = (
+				014CEA490018CE3211CA2923,
+				014CEA4A0018CE3211CA2923,
+			);
+			hasScannedForEncodings = 1;
+			isa = PBXProject;
+			mainGroup = 08FB7794FE84155DC02AAC07;
+			projectDirPath = "";
+			targets = (
+				08FB779FFE84155DC02AAC07,
+			);
+		};
+		08FB7794FE84155DC02AAC07 = {
+			children = (
+				08FB7795FE84155DC02AAC07,
+				08FB779DFE84155DC02AAC07,
+				19C28FBDFE9D53C911CA2CBB,
+				F5C0CA9501B5740C01AEEDB1,
+				F574340B01B8A47B01AEEDB1,
+			);
+			isa = PBXGroup;
+			name = launch;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		08FB7795FE84155DC02AAC07 = {
+			children = (
+				08FB7796FE84155DC02AAC07,
+			);
+			isa = PBXGroup;
+			name = Source;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		08FB7796FE84155DC02AAC07 = {
+			expectedFileType = sourcecode.c.c;
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			path = main.c;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		08FB779DFE84155DC02AAC07 = {
+			children = (
+				F5E819BF0198DFF701AEEDB1,
+				F561F49F0139D7DD01AEEDB1,
+				09AB6884FE841BABC02AAC07,
+				F579CF4B019A1C6D01AEEDB1,
+			);
+			isa = PBXGroup;
+			name = "External Frameworks and Libraries";
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		08FB779FFE84155DC02AAC07 = {
+			buildPhases = (
+				08FB77A0FE84155DC02AAC07,
+				08FB77A1FE84155DC02AAC07,
+				08FB77A3FE84155DC02AAC07,
+				08FB77A5FE84155DC02AAC07,
+			);
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = "";
+				HEADER_SEARCH_PATHS = "";
+				INSTALL_PATH = "\U0001$(HOME)/bin";
+				LIBRARY_SEARCH_PATHS = "";
+				OTHER_CFLAGS = "";
+				OTHER_LDFLAGS = "";
+				OTHER_REZFLAGS = "";
+				PRODUCT_NAME = launch;
+				REZ_EXECUTABLE = YES;
+				SECTORDER_FLAGS = "";
+				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
+			};
+			dependencies = (
+			);
+			isa = PBXToolTarget;
+			name = launch;
+			productInstallPath = "$(HOME)/bin";
+			productName = launch;
+			productReference = 034768E2FF38A6DC11DB9C8B;
+		};
+		08FB77A0FE84155DC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXHeadersBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		08FB77A1FE84155DC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				08FB77A2FE84155DC02AAC07,
+			);
+			isa = PBXSourcesBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		08FB77A2FE84155DC02AAC07 = {
+			fileRef = 08FB7796FE84155DC02AAC07;
+			isa = PBXBuildFile;
+			settings = {
+				ATTRIBUTES = (
+				);
+			};
+		};
+		08FB77A3FE84155DC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+				09AB6885FE841BABC02AAC07,
+				F561F4A00139D7DD01AEEDB1,
+				F5E819C00198DFF701AEEDB1,
+				F579CF4C019A1C6D01AEEDB1,
+			);
+			isa = PBXFrameworksBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		08FB77A5FE84155DC02AAC07 = {
+			buildActionMask = 2147483647;
+			files = (
+			);
+			isa = PBXRezBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+//080
+//081
+//082
+//083
+//084
+//090
+//091
+//092
+//093
+//094
+		09AB6884FE841BABC02AAC07 = {
+			expectedFileType = wrapper.framework;
+			fallbackIsa = PBXFileReference;
+			isa = PBXFrameworkReference;
+			name = CoreFoundation.framework;
+			path = /System/Library/Frameworks/CoreFoundation.framework;
+			refType = 0;
+			sourceTree = "<absolute>";
+		};
+		09AB6885FE841BABC02AAC07 = {
+			fileRef = 09AB6884FE841BABC02AAC07;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+//090
+//091
+//092
+//093
+//094
+//190
+//191
+//192
+//193
+//194
+		19C28FBDFE9D53C911CA2CBB = {
+			children = (
+				034768E2FF38A6DC11DB9C8B,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+//190
+//191
+//192
+//193
+//194
+//F50
+//F51
+//F52
+//F53
+//F54
+		F561F49F0139D7DD01AEEDB1 = {
+			expectedFileType = wrapper.framework;
+			fallbackIsa = PBXFileReference;
+			isa = PBXFrameworkReference;
+			name = ApplicationServices.framework;
+			path = /System/Library/Frameworks/ApplicationServices.framework;
+			refType = 0;
+			sourceTree = "<absolute>";
+		};
+		F561F4A00139D7DD01AEEDB1 = {
+			fileRef = F561F49F0139D7DD01AEEDB1;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F574340B01B8A47B01AEEDB1 = {
+			expectedFileType = text;
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			path = VERSION;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		F579CF4B019A1C6D01AEEDB1 = {
+			expectedFileType = wrapper.framework;
+			fallbackIsa = PBXFileReference;
+			isa = PBXFrameworkReference;
+			name = Security.framework;
+			path = /System/Library/Frameworks/Security.framework;
+			refType = 0;
+			sourceTree = "<absolute>";
+		};
+		F579CF4C019A1C6D01AEEDB1 = {
+			fileRef = F579CF4B019A1C6D01AEEDB1;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F5C0CA9501B5740C01AEEDB1 = {
+			expectedFileType = text;
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			path = README;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		F5E819BF0198DFF701AEEDB1 = {
+			expectedFileType = wrapper.framework;
+			fallbackIsa = PBXFileReference;
+			isa = PBXFrameworkReference;
+			name = Carbon.framework;
+			path = /System/Library/Frameworks/Carbon.framework;
+			refType = 0;
+			sourceTree = "<absolute>";
+		};
+		F5E819C00198DFF701AEEDB1 = {
+			fileRef = F5E819BF0198DFF701AEEDB1;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+	};
+	rootObject = 08FB7793FE84155DC02AAC07;
+}
Index: /releases/launch/1.0/launch/main.c
===================================================================
--- /releases/launch/1.0/launch/main.c	(revision 147)
+++ /releases/launch/1.0/launch/main.c	(revision 147)
@@ -0,0 +1,886 @@
+/*
+ launch - a smarter 'open' replacement
+ Nicholas Riley <launchsw@sabi.net>
+
+ Copyright (c) 2001-03, Nicholas Riley
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+ * Neither the name of this software nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ 
+*/
+
+/* To do/think about:
+
+- Launching as root: use authentication framework - doesn't work.
+
+- launch URL with specified URL handler (done, except for IC)
+
+- launch apps by IC protocol handler (esp. editor)
+
+Thanks to:
+
+- Nat Irons, for encouragement and suggestions
+
+- Brian Hill, for the great Security.framework tutorial and sample code
+
+*/
+
+/* #define DEBUG 1 */
+#define BROKEN_AUTHORIZATION 1
+#define BROKEN_LSOPENFROMURLSPEC 1
+#define kComponentSignatureString "launch"
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <Carbon/Carbon.h>
+#include <CoreServices/CoreServices.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <ApplicationServices/ApplicationServices.h>
+
+#ifndef BROKEN_AUTHORIZATION
+#include <Security/Authorization.h>
+#include <Security/AuthorizationTags.h>
+#endif
+
+const char *APP_NAME;
+
+#define VERSION "1.0"
+
+#define STRBUF_LEN 1024
+#define ACTION_DEFAULT ACTION_OPEN
+
+struct {
+    OSType creator;
+    CFStringRef bundleID, name;
+    enum { ACTION_FIND, ACTION_FIND_ITEMS,
+	   ACTION_OPEN, ACTION_OPEN_ITEMS, 
+	   ACTION_INFO_ITEMS, ACTION_LAUNCH_URLS } action;
+} OPTS = 
+{
+    kLSUnknownCreator, NULL, NULL,
+    ACTION_DEFAULT
+};
+
+#define DEFAULT_LAUNCH_FLAGS (kLSLaunchNoParams | kLSLaunchStartClassic | kLSLaunchAsync)
+
+LSLaunchURLSpec LSPEC = {NULL, NULL, NULL, DEFAULT_LAUNCH_FLAGS, NULL};
+
+char *TEMPFILE = NULL;
+
+typedef struct {
+    OSStatus status;
+    const char *desc;
+} errRec, errList[];
+
+static errList ERRS = {
+    // Launch Services errors
+    { kLSUnknownErr, "unknown Launch Services error" },
+    { kLSApplicationNotFoundErr, "application not found" },
+    { kLSLaunchInProgressErr, "application is being opened; please try again after the application is open" },
+    { kLSNotRegisteredErr, "application not registered in Launch Services database" },
+    { kLSNoExecutableErr, "application package contains no executable, or an unusable executable" },
+    { kLSNoClassicEnvironmentErr, "Classic environment required but not available" },
+#ifndef BROKEN_AUTHORIZATION
+    // Security framework errors
+    { errAuthorizationDenied, "authorization denied" },
+    { errAuthorizationCanceled, "authentication was cancelled" },
+#endif
+    // Internet Config errors
+    { icPrefNotFoundErr, "no helper application is defined for the URL's scheme" },
+    { icNoURLErr, "not a URL" },
+    { icInternalErr, "internal Internet Config error" },
+    // Misc. errors
+    { procNotFound, "unable to connect to system service.\nAre you logged in?" },
+    { kCGErrorIllegalArgument, "window server error.\nAre you logged in?" },
+    { kCGErrorApplicationRequiresNewerSystem, "application requires a newer Mac OS X version" },
+    { fnfErr, "file not found" },
+    { 0, NULL }
+};
+
+void usage() {
+    fprintf(stderr, "usage: %s [-npswbmhCX] [-c creator] [-i bundleID] [-u URL] [-a name] [item ...] [-]\n"
+                    "   or: %s [-npflswbmhCX] item ...\n", APP_NAME, APP_NAME);
+    fprintf(stderr,
+        "  -n            print matching paths/URLs instead of opening them\n"
+        "  -p            ask application(s) to print document(s)\n"
+	"  -f            display information about item(s)\n"
+        "  -l            launch URLs (e.g. treat http:// URLs as Web sites, not WebDAV)\n"
+#ifndef BROKEN_AUTHORIZATION
+        "  -s            launch target(s) as superuser (authenticating if needed)\n"
+#endif
+        "  -w            wait for application to finish opening before exiting\n"
+        "  -b            launch application in the background\n"
+        "  -m            launch application again, even if already running\n"
+        "  -h            hide application once it's finished opening\n"
+        "  -C            force CFM/PEF Carbon application to launch in Classic\n"
+        "  -X            don't start Classic for this app if Classic isn't running\n"
+        "  -c creator    match application by four-character creator code ('ToyS')\n"
+        "  -i bundle ID  match application by bundle identifier (com.apple.scripteditor)\n"
+        "  -u URL        open application at file:// URL (NOT RECOMMENDED for scripts)\n"
+        "  -a name       match application by name (NOT RECOMMENDED, very fragile)\n"
+        "'document' may be a file, folder, or disk - whatever the application can open.\n"
+        "'item' may be a file, folder, disk, or URL.\n\n");
+    fprintf(stderr, "launch "VERSION" (c) 2001-03 Nicholas Riley <http://web.sabi.net/nriley/software/>.\n"
+	            "Please send bugs, suggestions, etc. to <launchsw@sabi.net>.\n");
+
+    exit(1);
+}
+
+char *osstatusstr(OSStatus err) {
+    errRec *rec;
+    const char *errDesc = "unknown error";
+    char * const failedStr = "(unable to retrieve error message)";
+    static char *str = NULL;
+    size_t len;
+    if (str != NULL && str != failedStr) free(str);
+    for (rec = &(ERRS[0]) ; rec->status != 0 ; rec++)
+        if (rec->status == err) {
+            errDesc = rec->desc;
+            break;
+        }
+    len = strlen(errDesc) + 10 * sizeof(char);
+    str = (char *)malloc(len);
+    if (str != NULL)
+        snprintf(str, len, "%s (%ld)", errDesc, err);
+    else
+        str = failedStr;
+    return str;
+}
+
+void osstatusexit(OSStatus err, const char *fmt, ...) {
+    va_list ap;
+    const char *errDesc = osstatusstr(err);
+    va_start(ap, fmt);
+    fprintf(stderr, "%s: ", APP_NAME);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, ": %s\n", errDesc);
+    exit(1);
+}
+
+void errexit(const char *fmt, ...) {
+    va_list ap;
+    va_start(ap, fmt);
+    fprintf(stderr, "%s: ", APP_NAME);
+    vfprintf(stderr, fmt, ap);
+    fprintf(stderr, "\n");
+    exit(1);
+}
+
+#ifndef BROKEN_AUTHORIZATION
+
+Boolean authenticated(AuthorizationItem item, AuthorizationRef *pAuthRef) {
+    AuthorizationRights rights;
+    AuthorizationRights *authorizedRights;
+    AuthorizationFlags flags;
+    OSStatus err;
+
+    // Create an AuthorizationRef yet with the kAuthorizationFlagDefaults
+    // flags to get the user's current authorization rights.
+    rights.count = 0;
+    rights.items = NULL;
+    
+    flags = kAuthorizationFlagDefaults;
+
+    err = AuthorizationCreate(&rights,
+        kAuthorizationEmptyEnvironment, flags,
+        pAuthRef);
+        
+    rights.count = 1;
+    rights.items = &item;
+    
+    flags = kAuthorizationFlagExtendRights;
+    
+    // don't ask for a password, just return failure if no rights
+    err = AuthorizationCopyRights(*pAuthRef, &rights,
+        kAuthorizationEmptyEnvironment, flags, &authorizedRights);
+
+    switch (err) {
+    case errAuthorizationSuccess:
+        // we don't need these items, and they need to be disposed of
+        AuthorizationFreeItemSet(authorizedRights);
+        return true;
+    case errAuthorizationInteractionNotAllowed:
+        return false;
+    default:
+        osstatusexit(err, "unable to determine authentication status");
+    }
+    return false; // to satisfy compiler
+}
+
+void authenticate(AuthorizationItem item, AuthorizationRef authorizationRef) {
+    AuthorizationRights rights = {1, &item};
+    AuthorizationRights *authorizedRights;
+    AuthorizationFlags flags;
+    OSStatus err;
+
+    flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights;
+
+    // Here, since we've specified kAuthorizationFlagExtendRights and
+    // have also specified kAuthorizationFlagInteractionAllowed, if the
+    // user isn't currently authorized to execute tools as root 
+    // (kAuthorizationRightExecute), they will be asked for their password. 
+    // The err return value will indicate authorization success or failure.
+    err = AuthorizationCopyRights(authorizationRef,&rights,
+                        kAuthorizationEmptyEnvironment,
+                        flags,&authorizedRights);
+    
+    if (errAuthorizationSuccess == err)
+        AuthorizationFreeItemSet(authorizedRights);
+    else
+        osstatusexit(err, "unable to authenticate");
+}
+#endif
+
+CFURLRef normalizedURLFromString(CFStringRef str) {
+    CFURLRef url = CFURLCreateWithString(NULL, str, NULL);
+    if (url != NULL) {
+        CFURLRef absURL = CFURLCopyAbsoluteURL(url);
+        CFRelease(url);
+        url = NULL;
+        if (absURL != NULL) {
+            CFStringRef scheme = CFURLCopyScheme(absURL);
+            url = absURL;
+            if (scheme == NULL) {
+                CFRelease(url);
+                url = NULL;
+            } else {
+	        CFRelease(scheme);
+	    }
+        }
+    }
+    return url;
+}
+
+CFURLRef normalizedURLFromPrefixSlack(CFStringRef prefix, CFStringRef slackStr) {
+    CFStringRef str = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@%@"),
+                                               prefix, slackStr);
+    CFURLRef normalizedURL = normalizedURLFromString(str);
+    CFRelease(str);
+    return normalizedURL;
+}
+
+char *tempFile(int *fd) {
+    char *tmpDir = getenv("TMPDIR");
+    const char * const tempTemplate = "/launch-stationery-XXXXXXXX";
+    char *tempPath;
+    OSStatus err;
+    FSRef fsr;
+    FSCatalogInfo catalogInfo;
+    FileInfo *fInfo;
+
+    // create temporary file
+    if (tmpDir == NULL) tmpDir = "/tmp";
+    tempPath = (char *)malloc(strlen(tmpDir) + strlen(tempTemplate) + 1);
+    if (tempPath == NULL) errexit("can't allocate memory");
+    strcpy(tempPath, tmpDir);
+    strcat(tempPath, tempTemplate);
+    if ( (*fd = mkstemp(tempPath)) == -1)
+        errexit("can't create temporary file '%s'", tempPath);
+    // mark file as stationery
+    err = FSPathMakeRef(tempPath, &fsr, NULL);
+    if (err != noErr) osstatusexit(err, "can't find '%s'", tempPath);
+    err = FSGetCatalogInfo(&fsr, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL);
+    if (err != noErr) osstatusexit(err, "can't get information for '%s'", tempPath);
+    fInfo = (FileInfo *)&(catalogInfo.finderInfo);
+    fInfo->finderFlags |= kIsStationery;
+    err = FSSetCatalogInfo(&fsr, kFSCatInfoFinderInfo, &catalogInfo);
+    if (err != noErr) osstatusexit(err, "can't set information for '%s'", tempPath);
+    
+    return tempPath;
+}
+
+char *stdinAsTempFile() {
+    unsigned char *buf;
+    int bufsize;
+    // Actual number of characters read, and therefore written.
+    ssize_t charCount;
+    int fd;
+    struct stat stat_buf;
+    char *tempFilePath;
+
+    tempFilePath = tempFile(&fd);
+
+    if (fstat(fd, &stat_buf) == -1)
+        errexit("can't fstat temporary file '%s'", tempFilePath);
+
+    bufsize = stat_buf.st_blksize;
+    if ( (buf = (unsigned char *)malloc(bufsize * sizeof(unsigned char))) == NULL)
+        errexit("can't allocate %ld bytes of buffer memory",
+                bufsize * sizeof(unsigned char));
+
+    // Loop until the end of the file.
+    while (1) {
+        // Read a block of input.
+        charCount = read(STDIN_FILENO, buf, bufsize);
+        if (charCount < 0) {
+            errexit("can't read from standard input");
+        }
+        // End of this file?
+        if (charCount == 0)
+            break;
+        // Write this block out.
+        if (write(fd, buf, charCount) != charCount)
+            errexit("error writing to file '%s'", tempFilePath);
+    }
+    free(buf);
+    return tempFilePath;
+}
+
+void getargs(int argc, char * const argv[]) {
+    extern char *optarg;
+    extern int optind;
+    int ch;
+    Boolean appSpecified = false;
+
+    if (argc == 1) usage();
+    
+    while ( (ch = getopt(argc, argv, "npflswbmhCXc:i:u:a:")) != -1) {
+        switch (ch) {
+        case 'n':
+            if (OPTS.action != ACTION_DEFAULT) errexit("choose only one of -n, -p, -f, -l options");
+            OPTS.action = ACTION_FIND;
+            break;
+        case 'p':
+            if (OPTS.action != ACTION_DEFAULT) errexit("choose only one of -n, -p, -f, -l options");
+            OPTS.action = ACTION_OPEN;
+            LSPEC.launchFlags |= kLSLaunchAndPrint;
+            break;
+        case 'f':
+            if (OPTS.action != ACTION_DEFAULT) errexit("choose only one of -n, -p, -f, -l options");
+            OPTS.action = ACTION_INFO_ITEMS;
+            break;
+        case 'l':
+            if (OPTS.action != ACTION_DEFAULT) errexit("choose only one of -n, -p, -f, -l options");
+            OPTS.action = ACTION_LAUNCH_URLS;
+            break;
+        case 's':
+#ifdef BROKEN_AUTHORIZATION
+	    errexit("-s option no longer functional after 10.1 Security Update, sorry");
+#else
+        {
+            AuthorizationRef authRef;
+            AuthorizationItem item = { kAuthorizationRightExecute, strlen(argv[0]), argv[0], 0 };
+            OSStatus err;
+            
+            if (authenticated(item, &authRef)) {
+                continue;
+            }
+            authenticate(item, authRef);
+            err = AuthorizationExecuteWithPrivileges(authRef, argv[0], 0, &argv[1], NULL);
+            if (err != noErr) osstatusexit(err, "unable to launch '%s' with superuser privileges", argv[0]);
+            exit(0); // XXX exit status propagate?
+        }
+#endif
+        case 'w': LSPEC.launchFlags ^= kLSLaunchAsync; break;      // synchronous
+        case 'b': LSPEC.launchFlags |= kLSLaunchDontSwitch; break; // open in background
+        case 'm': LSPEC.launchFlags |= kLSLaunchNewInstance; break;// open multiple
+        case 'h': LSPEC.launchFlags |= kLSLaunchAndHide; break;    // hide once launched
+        case 'C': LSPEC.launchFlags |= kLSLaunchInClassic; break;  // force Classic
+        case 'X': LSPEC.launchFlags ^= kLSLaunchStartClassic; break;// don't start Classic for app
+        case 'c':
+            if (strlen(optarg) != 4) errexit("creator (argument of -c) must be four characters long");
+            OPTS.creator = *(OSTypePtr)optarg;
+	    appSpecified = true;
+            break;
+        case 'i':
+            OPTS.bundleID = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding());
+	    appSpecified = true;
+            break;
+        case 'a':
+            OPTS.name = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding());
+	    appSpecified = true;
+            break;
+	case 'u':
+            { CFStringRef str = CFStringCreateWithCString(NULL, optarg, CFStringGetSystemEncoding());
+	      LSPEC.appURL = CFURLCreateWithString(NULL, str, NULL);
+              if (str != NULL) CFRelease(str);
+            }
+	    if (LSPEC.appURL == NULL) {
+		errexit("invalid URL (argument of -u)");
+	    } else {
+		CFURLRef absURL = CFURLCopyAbsoluteURL(LSPEC.appURL);
+		CFRelease(LSPEC.appURL);
+		LSPEC.appURL = NULL;
+		if (absURL != NULL) {
+		    CFStringRef scheme = CFURLCopyScheme(absURL);
+		    LSPEC.appURL = absURL;
+		    if (scheme == NULL || !CFEqual(scheme, CFSTR("file")))
+			errexit("invalid file:// URL (argument of -u)");
+		    CFRelease(scheme);
+		}
+	    }
+	    appSpecified = true;
+	    break;
+        default: usage();
+        }
+    }
+    
+    argc -= optind;
+    argv += optind;
+    
+    if ( (OPTS.action == ACTION_FIND || OPTS.action == ACTION_LAUNCH_URLS ||
+	  OPTS.action == ACTION_INFO_ITEMS) && LSPEC.launchFlags != DEFAULT_LAUNCH_FLAGS)
+        errexit("options -s, -b, -m, -h, -C, -X apply to application launch (not -n, -f or -l)");
+    
+    if (OPTS.creator == kLSUnknownCreator && OPTS.bundleID == NULL && OPTS.name == NULL) {
+	if (argc == 0 && LSPEC.appURL == NULL)
+	    errexit("must specify an application by -u, or one or more of -c, -i, -a");
+        if (!appSpecified) {
+            if (OPTS.action == ACTION_FIND)
+                OPTS.action = ACTION_FIND_ITEMS;
+            if (OPTS.action == ACTION_OPEN)
+                OPTS.action = ACTION_OPEN_ITEMS;
+        }
+    } else {
+	if (LSPEC.appURL != NULL)
+	    errexit("application URL (argument of -u) incompatible with matching by -c, -i, -a");
+    }
+
+    if (OPTS.action == ACTION_LAUNCH_URLS && appSpecified)
+        errexit("launching URLs with a given application is not supported; try without -l");
+
+    if (OPTS.action == ACTION_INFO_ITEMS && appSpecified)
+	errexit("can't get information (-f) on item(s) using an application (-u, -c, -i, -a)");
+
+    if (argc == 0 && OPTS.action == ACTION_OPEN && LSPEC.launchFlags & kLSLaunchAndPrint)
+        errexit("print option (-p) must be accompanied by document(s) to print");
+    
+    if (argc != 0) {
+        int i;
+        OSStatus err;
+        CFStringRef argStr;
+        CFURLRef itemURL;
+        LSItemInfoRecord docInfo;
+
+        if (OPTS.action == ACTION_FIND)
+            errexit("application with documents only supported for open or print, not find");
+
+        // handle document/item/URL arguments
+        LSPEC.itemURLs = CFArrayCreateMutable(NULL, argc, NULL);
+        for (i = 0 ; i < argc ; i++) {
+            argStr = NULL;
+            if (strcmp(argv[i], "-") == 0) {
+                TEMPFILE = stdinAsTempFile();
+                itemURL = CFURLCreateFromFileSystemRepresentation(NULL, TEMPFILE, strlen(TEMPFILE), false);
+                LSPEC.launchFlags ^= kLSLaunchAsync;
+            } else {
+                argStr = CFStringCreateWithCString(NULL, argv[i], CFStringGetSystemEncoding());
+                // check for URLs
+                itemURL = normalizedURLFromString(argStr);
+                if (itemURL == NULL && OPTS.action == ACTION_LAUNCH_URLS) {
+                    // check for email addresses
+                    if (strchr(argv[i], '@') != NULL && strchr(argv[i], '/') == NULL)
+                        itemURL = normalizedURLFromPrefixSlack(CFSTR("mailto:"), argStr);
+                    // check for "slack" URLs
+                    if (itemURL == NULL && strchr(argv[i], '.') != NULL && strchr(argv[i], '/') != argv[i])
+                        itemURL = normalizedURLFromPrefixSlack(CFSTR("http://"), argStr);
+                }
+                if (itemURL == NULL) {
+                    // check for file paths
+                    itemURL = CFURLCreateWithFileSystemPath(NULL, argStr, kCFURLPOSIXPathStyle, false);
+                    err = LSCopyItemInfoForURL(itemURL, kLSRequestExtensionFlagsOnly, &docInfo);
+                    if (err != noErr) osstatusexit(err, "unable to locate '%s'", argv[i]);
+                }
+            }
+            CFArrayAppendValue((CFMutableArrayRef)LSPEC.itemURLs, itemURL);
+            // don't CFRelease the itemURL because CFArray doesn't retain it by default
+            if (argStr != NULL) CFRelease(argStr);
+        }
+    }
+}
+
+void printPathFromURL(CFURLRef url, FILE *stream) {
+    CFStringRef scheme, pathOrURL;
+    static char strBuffer[STRBUF_LEN];
+    
+    check(url != NULL && stream != NULL);
+
+    scheme = CFURLCopyScheme(url);
+    
+    if (CFEqual(scheme, CFSTR("file")))
+        pathOrURL = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+    else
+        pathOrURL = CFURLGetString(url);
+
+    strBuffer[0] = '\0';
+    CFStringGetCString(pathOrURL, strBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); // XXX buffer size issues?
+    fprintf(stream, "%s\n", strBuffer);
+    CFRelease(scheme);
+    CFRelease(pathOrURL);
+}
+
+void printDateTime(const char *label, UTCDateTime *utcTime, const char *postLabel, Boolean printIfEmpty) {
+    static Str255 dateStr, timeStr;
+    LocalDateTime localTime;
+    LongDateTime longTime;
+    OSStatus err;
+
+    err = ConvertUTCToLocalDateTime(utcTime, &localTime);
+    if (err == kUTCUnderflowErr) {
+        if (printIfEmpty) printf("\t%s: (not set)\n", label);
+        return;
+    }
+    if (err != noErr) osstatusexit(err, "unable to convert UTC %s date to local", label);
+
+    longTime = localTime.highSeconds;
+    longTime <<= 32;
+    longTime |= localTime.lowSeconds;
+
+    // strings include trailing newlines; strip them.
+    LongDateString(&longTime, shortDate, dateStr, nil); dateStr[dateStr[0] + 1] = '\0';
+    LongTimeString(&longTime, true, timeStr, nil); timeStr[timeStr[0] + 1] = '\0';
+    printf("\t%s: %s %s%s\n", label, dateStr + 1, timeStr + 1, postLabel);
+}
+
+#define DFORMAT(SIZE) ((float)(SIZE) / 1024.)
+
+void printSizes(const char *label, UInt64 logicalSize, UInt64 physicalSize, Boolean printIfZero) {
+    UInt32 bigSize = physicalSize >> 32, littleSize = physicalSize;
+    if (!printIfZero && bigSize == 0 && littleSize == 0) return;
+    printf("\t%s: ", label);
+    if (bigSize == 0) {
+        if (littleSize == 0) {
+            printf("zero bytes on disk (zero bytes used)\n"); return;
+        } else if (littleSize < 1024) printf("%lu bytes", littleSize);
+        else {
+            UInt32 adjSize = littleSize >> 10;
+            if (adjSize < 1024) printf("%.1f KB", DFORMAT(littleSize));
+            else {
+                adjSize >>= 10; littleSize >>= 10;
+                if (adjSize < 1024) printf("%.2f MB", DFORMAT(littleSize));
+                else {
+                    adjSize >>= 10; littleSize >>= 10;
+                    printf("%.2f GB", DFORMAT(littleSize));
+                }
+            }
+        }
+    } else {
+        if (bigSize < 256) printf("%lu GB", bigSize);
+        else {
+            bigSize >>= 2;
+            printf("%lu TB", bigSize);
+        }
+    }
+    printf(" on disk (%llu bytes used)\n", logicalSize);
+        
+}
+
+void printMoreInfoFromURL(CFURLRef url) {
+    FSRef fsr;
+    OSStatus err;
+    FSCatalogInfo fscInfo;
+
+    if (!CFURLGetFSRef(url, &fsr)) return;
+    err = FSGetCatalogInfo(&fsr, kFSCatInfoNodeFlags | kFSCatInfoAllDates | kFSCatInfoDataSizes | kFSCatInfoRsrcSizes | kFSCatInfoValence, &fscInfo, NULL, NULL, NULL);
+    if (err != noErr) osstatusexit(err, "unable to get catalog information for file");
+
+    if (fscInfo.nodeFlags & kFSNodeIsDirectoryMask) {
+        printf("\tcontents: %lu item%s\n", fscInfo.valence, fscInfo.valence != 1 ? "s" : "");
+    } else {
+        printSizes("data fork size", fscInfo.dataLogicalSize, fscInfo.dataPhysicalSize, true);
+        printSizes("rsrc fork size", fscInfo.rsrcLogicalSize, fscInfo.rsrcPhysicalSize, false);
+    }
+
+    if (fscInfo.nodeFlags & (kFSNodeLockedMask | kFSNodeForkOpenMask)) {
+        printf("\tstatus:");
+        if (fscInfo.nodeFlags & kFSNodeLockedMask) {
+            if (fscInfo.nodeFlags & kFSNodeForkOpenMask) printf(" in use,");
+            printf(" locked");
+        } else {
+            printf(" in use");
+        }
+        printf("\n");
+    }
+    
+    printDateTime("created", &fscInfo.createDate, "", true);
+    printDateTime("modified", &fscInfo.contentModDate, "", true);
+    printDateTime("accessed", &fscInfo.accessDate, " [only updated by Mac OS X]", false);
+    printDateTime("backed up", &fscInfo.backupDate, "", false);
+}
+
+// 'context' is to match prototype for CFArrayApplierFunction, it's unused
+void printInfoFromURL(CFURLRef url, void *context) {
+    CFStringRef scheme, pathOrURL, kind;
+    Boolean isRemote;
+    static char strBuffer[STRBUF_LEN], tmpBuffer[STRBUF_LEN];
+    
+    check(url != NULL && context == NULL);
+
+    scheme = CFURLCopyScheme(url);
+    
+    isRemote = !CFEqual(scheme, CFSTR("file"));
+    if (isRemote)
+        pathOrURL = CFURLGetString(url);
+    else
+        pathOrURL = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+
+    strBuffer[0] = '\0';
+    CFStringGetCString(pathOrURL, strBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); // XXX buffer size issues?
+    if (isRemote)
+        printf("<%s>: URL\n", strBuffer);
+    else {
+        static LSItemInfoRecord info;
+        OSStatus err = LSCopyItemInfoForURL(url, kLSRequestAllInfo, &info);
+        if (err != noErr) osstatusexit(err, "unable to get information about '%s'", strBuffer);
+        
+        printf("%s: ", strBuffer);
+        
+        // modifiers
+        if (info.flags & kLSItemInfoIsInvisible) printf("invisible ");
+        if (info.flags & kLSItemInfoAppIsScriptable) printf("scriptable ");
+        if (info.flags & kLSItemInfoIsNativeApp) printf("Mac OS X ");
+        if (info.flags & kLSItemInfoIsClassicApp) printf("Classic ");
+        
+        // kind
+        if (info.flags & kLSItemInfoIsVolume) printf("volume");
+        else if (info.flags & kLSItemInfoIsApplication) printf("application ");
+        else if (info.flags & kLSItemInfoIsPackage) printf("non-application ");
+        else if (info.flags & kLSItemInfoIsContainer) printf("folder");
+        else if (info.flags & kLSItemInfoIsAliasFile) printf("alias");
+        else if (info.flags & kLSItemInfoIsSymlink) printf("symbolic link");
+        else if (info.flags & kLSItemInfoIsPlainFile) printf("document");
+        else printf("unknown file system entity");
+
+        if (info.flags & kLSItemInfoIsPackage) printf("package ");
+
+        if (info.flags & kLSItemInfoAppPrefersNative) printf("[Carbon, prefers native OS X]");
+        else if (info.flags & kLSItemInfoAppPrefersClassic) printf("[Carbon, prefers Classic]");
+
+        printf("\n");
+        if (!(info.flags & kLSItemInfoIsContainer) || info.flags & kLSItemInfoIsPackage) {
+            tmpBuffer[4] = '\0';
+            strncpy(tmpBuffer, (char *)&info.filetype, 4); printf("\ttype: '%s'", tmpBuffer);
+            strncpy(tmpBuffer, (char *)&info.creator, 4); printf("\tcreator: '%s'\n", tmpBuffer);
+        }
+        if (info.flags & kLSItemInfoIsPackage || info.flags & kLSItemInfoIsApplication) {
+        	// a package, or possibly a native app with a 'plst' resource
+            CFBundleRef bundle = CFBundleCreate(NULL, url);
+            CFStringRef bundleID = NULL;
+            CFStringRef appVersion = NULL;
+            UInt32 intVersion = 0;
+            if (bundle == NULL && (info.flags & kLSItemInfoIsApplication)) {
+                FSRef fsr;
+                if (info.flags & kLSItemInfoIsPackage || !CFURLGetFSRef(url, &fsr)) {
+                    printf("\t[can't access CFBundle for application]\n");
+                } else { // OS X bug causes this to fail when it shouldn't, so fake it
+                    SInt16 resFork = FSOpenResFile(&fsr, fsRdPerm);
+                    OSStatus err = ResError();
+                    if (err != noErr) {
+                        printf("\t[can't open resource fork: %s]\n", osstatusstr(err));
+                    } else {
+                        Handle h = Get1Resource('plst', 0);
+                        if ( (err = ResError()) != noErr || h == NULL) {
+                            if (err != noErr && err != resNotFound) osstatusexit(err, "unable to read 'plst' 0 resource");
+                        } else {
+                            CFDataRef plstData = CFDataCreate(NULL, *h, GetHandleSize(h));
+                            CFStringRef error;
+                            CFPropertyListRef infoPlist = CFPropertyListCreateFromXMLData(NULL, plstData, kCFPropertyListImmutable, &error);
+			    if (plstData != NULL) {
+			        CFRelease(plstData);
+			        plstData = NULL;
+			    }
+                            if (infoPlist == NULL) {
+                                CFStringGetCString(error, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding());
+                                printf("\t['plst' 0 resource invalid: %s]\n", tmpBuffer);
+                                CFRelease(error);
+                            } else {
+                                // mimic CFBundle logic below
+                                bundleID = CFDictionaryGetValue(infoPlist, kCFBundleIdentifierKey);
+                                if (bundleID != NULL) CFRetain(bundleID);
+                                appVersion = CFDictionaryGetValue(infoPlist, CFSTR("CFBundleShortVersionString"));
+                                if (appVersion == NULL)
+                                    appVersion = CFDictionaryGetValue(infoPlist, kCFBundleVersionKey);
+                                if (appVersion != NULL) CFRetain(appVersion);
+                                CFRelease(infoPlist);
+                            }
+                        }
+                        VersRecHndl vers = (VersRecHndl)Get1Resource('vers', 1);
+                        if ( (err = ResError()) != noErr || vers == NULL) {
+                            if (err != noErr && err != resNotFound) osstatusexit(err, "unable to read 'vers' 1 resource");
+                        } else {
+                            if (appVersion == NULL) { // prefer 'plst' version
+                                appVersion = CFStringCreateWithPascalString(NULL, vers[0]->shortVersion, CFStringGetSystemEncoding()); // XXX use country code instead?
+                            }
+                            intVersion = ((NumVersionVariant)vers[0]->numericVersion).whole;
+                        }
+                        CloseResFile(resFork);
+                    }
+                }
+            } else {
+                bundleID = CFBundleGetIdentifier(bundle);
+                if (bundleID != NULL) CFRetain(bundleID);
+		// prefer a short version string, e.g. "1.0 Beta" instead of "51" for Safari
+                appVersion = CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("CFBundleShortVersionString"));
+		if (appVersion == NULL)
+		    appVersion = CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
+                if (appVersion != NULL) {
+                    CFRetain(appVersion);
+                    intVersion = CFBundleGetVersionNumber(bundle);
+                }
+                CFRelease(bundle);
+            }
+            if (bundleID != NULL) {
+                CFStringGetCString(bundleID, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding());
+                printf("\tbundle ID: %s\n", tmpBuffer);
+                CFRelease(bundleID);
+            }
+            if (appVersion != NULL) {
+                CFStringGetCString(appVersion, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding());
+                printf("\tversion: %s", tmpBuffer);
+                if (intVersion != 0) printf(" [0x%lx = %lu]", intVersion, intVersion);
+                putchar('\n');
+                CFRelease(appVersion);
+            }
+        }
+        
+        // kind string
+        err = LSCopyKindStringForURL(url, &kind);
+        if (err != noErr) osstatusexit(err, "unable to get kind of '%s'", strBuffer);
+        CFStringGetCString(kind, tmpBuffer, STRBUF_LEN, CFStringGetSystemEncoding());
+        printf("\tkind: %s\n", tmpBuffer);
+	CFRelease(kind);
+        printMoreInfoFromURL(url);
+    }
+    CFRelease(scheme);
+    CFRelease(pathOrURL);
+}
+
+
+void launchURL(CFURLRef url, ICInstance icInst) {
+    CFStringRef urlStr = CFURLGetString(url);
+    static char strBuffer[STRBUF_LEN];
+    long strStart, strEnd;
+    OSStatus err;
+
+    strBuffer[0] = '\0';
+    CFStringGetCString(urlStr, strBuffer, STRBUF_LEN, CFStringGetSystemEncoding()); // XXX buffer size issues?
+    strStart = 0;
+    strEnd = strlen(strBuffer);
+    err = ICLaunchURL(icInst, "\p", strBuffer, strEnd, &strStart, &strEnd);
+    if (err != noErr) {
+        fprintf(stderr, "%s: unable to launch URL <%s>: %s\n", APP_NAME, strBuffer, osstatusstr(err));
+    }
+    
+    CFRelease(urlStr);
+}
+
+OSStatus openFromURLSpec() {
+#ifndef BROKEN_LSOPENFROMURLSPEC
+    return LSOpenFromURLSpec(&LSPEC, NULL);
+#else
+    LSLaunchFSRefSpec spec = {NULL, 0, NULL, LSPEC.passThruParams,
+			      LSPEC.launchFlags, LSPEC.asyncRefCon};
+    CFIndex urlIndex, urlCount = LSPEC.itemURLs ? CFArrayGetCount(LSPEC.itemURLs) : 0;
+    FSRef *itemRefs = malloc(urlCount * sizeof(FSRef));
+    CFURLRef url;
+    CFStringRef scheme, fileScheme = CFSTR("file");
+    int itemIndex = 0;
+    OSStatus err;
+
+    for (urlIndex = 0 ; urlIndex < urlCount ; urlIndex++) {
+	url = CFArrayGetValueAtIndex(LSPEC.itemURLs, urlIndex);
+	scheme = CFURLCopyScheme(url);
+	if (CFEqual(scheme, fileScheme)) {
+	    if (CFURLGetFSRef(url, &itemRefs[itemIndex])) {
+		itemIndex++;
+		CFArrayRemoveValueAtIndex((CFMutableArrayRef)LSPEC.itemURLs, urlIndex);
+		urlIndex--;
+		urlCount--;
+	    } else {
+		fprintf(stderr, "%s: unable to locate: ", APP_NAME);
+		printPathFromURL(url, stderr);
+	    }
+	}
+        CFRelease(scheme);
+    }
+
+    if (urlCount > 0 || itemIndex == 0) { /* URLs, or no items */
+	err = LSOpenFromURLSpec(&LSPEC, NULL);
+	if (err != noErr)
+	    return err;
+    }
+    if (itemIndex > 0) {
+        FSRef appRef;
+	spec.numDocs = itemIndex;
+	spec.itemRefs = itemRefs;
+	if (LSPEC.appURL != NULL) {
+	    if (!CFURLGetFSRef(LSPEC.appURL, &appRef)) {
+		errexit("can't find application");
+	    }
+            spec.appRef = &appRef;
+	}
+	return LSOpenFromRefSpec(&spec, NULL);
+    }
+    return noErr;
+#endif
+}
+
+int main (int argc, char * const argv[]) {
+    OSStatus err;
+    
+    APP_NAME = argv[0];
+    getargs(argc, argv);
+
+    if (OPTS.action == ACTION_FIND || OPTS.action == ACTION_OPEN) {
+        if (LSPEC.appURL != NULL) goto findOK; // already have an application URL
+	err = LSFindApplicationForInfo(OPTS.creator, OPTS.bundleID, OPTS.name, NULL, &LSPEC.appURL);
+        
+	if (err != noErr) {
+	    if (OPTS.name != NULL && !CFStringHasSuffix(OPTS.name, CFSTR(".app"))) {
+		OPTS.name = CFStringCreateMutableCopy(NULL, CFStringGetLength(OPTS.name) + 4, OPTS.name);
+		CFStringAppend((CFMutableStringRef)OPTS.name, CFSTR(".app"));
+		err = LSFindApplicationForInfo(OPTS.creator, OPTS.bundleID, OPTS.name, NULL, &LSPEC.appURL);
+		if (err == noErr) goto findOK;
+	    }
+	    osstatusexit(err, "can't locate application", argv[1]);
+        findOK: ;
+	}
+    }
+    
+    switch (OPTS.action) {
+    case ACTION_FIND:
+	printPathFromURL(LSPEC.appURL, stdout);
+	break;
+    case ACTION_OPEN:
+	err = openFromURLSpec();
+	if (err != noErr) osstatusexit(err, "can't open application", argv[1]);
+	break;
+    case ACTION_FIND_ITEMS:
+        CFArrayApplyFunction(LSPEC.itemURLs, CFRangeMake(0, CFArrayGetCount(LSPEC.itemURLs)),
+			     (CFArrayApplierFunction) printPathFromURL, stdout);
+	break;
+    case ACTION_OPEN_ITEMS:
+	err = openFromURLSpec();
+	if (err != noErr) osstatusexit(err, "can't open items", argv[1]);
+	break;
+    case ACTION_INFO_ITEMS:
+        CFArrayApplyFunction(LSPEC.itemURLs, CFRangeMake(0, CFArrayGetCount(LSPEC.itemURLs)),
+			     (CFArrayApplierFunction) printInfoFromURL, NULL);
+	break;
+    case ACTION_LAUNCH_URLS:
+    {
+        ICInstance icInst;
+        err = ICStart(&icInst, '\?\?\?\?'); // in case GCC trigraph handling is enabled
+        if (err != noErr) osstatusexit(err, "can't initialize Internet Config", argv[1]);
+        CFArrayApplyFunction(LSPEC.itemURLs, CFRangeMake(0, CFArrayGetCount(LSPEC.itemURLs)),
+                             (CFArrayApplierFunction) launchURL, icInst);
+        ICStop(icInst);
+        break;
+    }
+    }
+
+    if (TEMPFILE != NULL) {
+        // the application may take a while to finish opening the temporary file
+        daemon(0, 0);
+        sleep(60);
+        unlink(TEMPFILE);
+    }
+
+    return 0;
+}
Index: /releases/launch/1.0/openUp.c
===================================================================
--- /releases/launch/1.0/openUp.c	(revision 147)
+++ /releases/launch/1.0/openUp.c	(revision 147)
@@ -0,0 +1,109 @@
+/*
+  * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
+  *
+  * @APPLE_LICENSE_HEADER_START@
+  *
+  * The contents of this file constitute Original Code as defined in and
+  * are subject to the Apple Public Source License Version 1.1 (the
+  * "License").  You may not use this file except in compliance with the
+  * License.  Please obtain a copy of the License at
+  * http://www.apple.com/publicsource and read it before using this file.
+  *
+  * This Original Code and all software distributed under the License are
+  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+  * License for the specific language governing rights and limitations
+  * under the License.
+  *
+  * @APPLE_LICENSE_HEADER_END@
+  */
+/*
+  * Shantonu Sen <ssen@apple.com>
+  * openUp.c - program to set the "first-open-window" field of a volume
+  *
+  * Get the directory ID for the first argument, and set it as word 2
+  * of the Finder Info fields for the volume it lives on
+  *
+  * cc -o openUp openUp.c
+  * Usage: openUp /Volumes/Foo/OpenMe/
+  *
+  */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/attr.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+
+struct directoryinfo {
+	unsigned long length;
+	u_int32_t dirid;
+};
+
+struct volumeinfo {
+	unsigned long length;
+	u_int32_t  finderinfo[8];
+};
+
+const char *APP_NAME;
+
+void errnoexit(const char *fmt, ...) {
+	va_list ap;
+	va_start(ap, fmt);
+	fprintf(stderr, "%s: ", APP_NAME);
+	vfprintf(stderr, fmt, ap);
+	fprintf(stderr, " (%s)\n", strerror(errno));
+	exit(1);
+}
+
+int main(int argc, char *argv[]) {
+	
+	char *path = NULL;
+	struct attrlist alist;
+	struct directoryinfo dirinfo;
+	struct volumeinfo volinfo;
+	struct statfs sfs;
+	int err;
+	
+	APP_NAME = argv[0];
+	
+	if (argc != 2) {
+		fprintf(stderr, "usage: %s <path to folder whose window should open when volume is mounted>\n",
+				APP_NAME);
+		exit(1);
+	}
+	
+	path = argv[1];
+	
+	bzero(&alist, sizeof(alist));
+	alist.bitmapcount = 5;
+	alist.commonattr = ATTR_CMN_OBJID;
+	
+	if (getattrlist(path, &alist, &dirinfo, sizeof(dirinfo), 0))
+		errnoexit("getattrlist on path failed");
+	
+	printf("directory id: %lu\n", dirinfo.dirid);
+	
+	if (statfs(path, &sfs))
+		errnoexit("statfs failed");
+	
+	printf("mountpoint: %s\n", sfs.f_mntonname);
+	
+	alist.commonattr = ATTR_CMN_FNDRINFO;
+	alist.volattr = ATTR_VOL_INFO;
+	
+	if (getattrlist(sfs.f_mntonname, &alist, &volinfo, sizeof(volinfo), 0))
+		errnoexit("getattrlist on mount point failed");
+	volinfo.finderinfo[2] = dirinfo.dirid;
+	if (setattrlist(sfs.f_mntonname, &alist, volinfo.finderinfo,
+		sizeof(volinfo.finderinfo), 0))
+		errnoexit("setattrlist on mount point failed");
+	
+	return 0;
+
+}
+
Index: /releases/launch/1.0/package-launch.sh
===================================================================
--- /releases/launch/1.0/package-launch.sh	(revision 147)
+++ /releases/launch/1.0/package-launch.sh	(revision 147)
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+set -x -v
+
+cd launch && \
+find . -name \*~ -exec rm '{}' \; && \
+pbxbuild && \ 
+SetFile -c 'R*ch' -t 'TEXT' README VERSION launch.1 && \
+strip build/launch && \
+sudo /usr/bin/install -c build/launch /usr/local/bin && \
+sudo /usr/bin/install -c launch.1 /usr/local/man/man1 && \
+rm -rf build/launch.build build/intermediates build/.gdb_history && \
+VERSION=`cat VERSION` TARBALL="launch-$VERSION.tar.gz" && \
+DMG="launch-$VERSION.dmg" VOL="launch $VERSION" MOUNTPOINT="/Volumes/$VOL" && \
+cd .. && \
+rm -f launch-$VERSION $TARBALL $DMG && \
+ln -s launch launch-$VERSION && \
+tar --exclude=.DS_Store -zchf launch-$VERSION.tar.gz launch-$VERSION && \
+#hdiutil create $DMG -megabytes 5 -ov -type UDIF && \
+#DISK=`hdid $DMG | sed -ne ' /Apple_partition_scheme/ s|^/dev/\([^ ]*\).*$|\1|p'` && \
+#newfs_hfs -v "$VOL" /dev/r${DISK}s2 && \
+#hdiutil eject $DISK && \
+#hdid $DMG && \
+#ditto -rsrc launch "$MOUNTPOINT" && \
+#ditto -rsrc "InstallAnywhere/launch_Web_Installers/InstData/MacOSX/Install launch $VERSION.sit" "/Volumes/launch $VERSION" && \
+#launch "$MOUNTPOINT/Install launch $VERSION.sit" && \
+#./openUp "$MOUNTPOINT" && \
+#sleep 2 && \
+## hdiutil eject $DISK && \ # this doesn't work
+#osascript -e "tell application \"Finder\" to eject disk \"$VOL\"" && \
+#hdiutil convert $DMG -format UDZO -o z$DMG && \
+#mv z$DMG $DMG && \
+scp $TARBALL ainaz:web/nriley/software/ #$DMG 
+:
