diff --git a/COPYING b/COPYING
new file mode 100644
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,342 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+* arch-tag: Program license
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,15 @@
+Copyright (C) 2007-2010 John Goerzen
+<jgoerzen@complete.org>
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,33 @@
+# arch-tag: Primary makefile
+# Copyright (c) 2004-2006 John Goerzen
+#
+
+DESTDIR ?= /usr/local
+all: setup			# GHC build
+	./setup configure --prefix=$(DESTDIR)
+	./setup build
+
+install:
+	./setup install
+	@echo "Please manually install docs/gtkrsync.1"
+
+hugsbuild: setup
+	./setup configure --hugs
+	./setup build
+
+setup: Setup.lhs
+	ghc -package Cabal Setup.lhs -o setup
+
+clean: clean-code clean-doc
+
+clean-code:
+	-./setup clean
+	-cd libsrc && ../setup clean
+	-rm -rf dist libsrc/dist *.ho *.hi *.o *.a setup *~
+	-rm -f `find . -name "*~"` `find . -name "*.o"`
+	-rm -f `find . -name "*.cm*"`
+
+clean-doc:
+	-cd doc && scons -c && scons -c html pdf text ps gtkrsync.1
+	-rm -rf docs/.sconsign* .depend test
+	-rm -f docs/manpage*
diff --git a/RsyncGUI.hs b/RsyncGUI.hs
new file mode 100644
--- /dev/null
+++ b/RsyncGUI.hs
@@ -0,0 +1,169 @@
+{- Copyright (c) 2007 John Goerzen <jgoerzen@complete.org>
+   Please see the COPYRIGHT file -}
+
+module RsyncGUI where
+
+import System.IO
+import Control.Concurrent.MVar
+import Control.Concurrent
+import Data.List
+import Text.Regex.Posix
+import Graphics.UI.Gtk
+import Graphics.UI.Gtk.Glade
+import Control.Monad
+import System.Exit
+import Data.Progress.Tracker
+import System.Time.Utils
+import RsyncParser
+import Paths_gtkrsync(getDataFileName)
+
+data GUIParts = GUIParts {
+    lfile :: Label,
+    ltotal :: Label,
+    mainwin :: Window,
+    pbfile :: ProgressBar,
+    pbtotal :: ProgressBar,
+    messages :: TextView,
+    messageswin :: ScrolledWindow,
+    btdone :: Button}
+
+initRsyncGUI :: IO () -> IO GUIParts
+initRsyncGUI exitfunc = 
+     do initGUI
+        timeoutAddFull (yield >> return True)
+                       priorityDefaultIdle 50
+        gladefn <- getDataFileName "gtkrsync.glade"
+        Just xml <- xmlNew gladefn
+        -- Just xml <- xmlNew "gtkrsync.glade"
+
+        window' <- xmlGetWidget xml castToWindow "mainwindow"
+        onDestroy window' exitfunc
+
+        pbfile' <- xmlGetWidget xml castToProgressBar "progressbarfile"
+        pbtotal' <- xmlGetWidget xml castToProgressBar "progressbaroverall"
+        lfile' <- xmlGetWidget xml castToLabel "labelfile"
+        ltotal' <- xmlGetWidget xml castToLabel "labeloverall"
+        messages' <- xmlGetWidget xml castToTextView "messages"
+        messageswin' <- xmlGetWidget xml castToScrolledWindow "messageswindow"
+        button' <- xmlGetWidget xml castToButton "donebutton"
+        onClicked button' exitfunc
+
+        let gui = GUIParts lfile' ltotal' window' pbfile' pbtotal' messages'
+                  messageswin' button'
+        
+        forkIO mainGUI
+        return gui
+
+runGUI gui rsyncstream exitmv = 
+    do streamWithMsgActions <- procmessages gui rsyncstream
+       procstream gui streamWithMsgActions
+       modifyMVar_ exitmv mvdone
+
+       labelSetText (lfile gui) ""
+       labelSetText (ltotal gui) "Sync process has finished"
+       progressBarSetFraction (pbfile gui) 1.0
+       progressBarSetText (pbfile gui) ""
+       progressBarSetFraction (pbtotal gui) 1.0
+       progressBarSetText (pbtotal gui) ""
+       buttonSetLabel (btdone gui) "gtk-close"
+    where mvdone Nothing = return (Just ExitSuccess)
+          mvdone (Just x) = return (Just x)
+
+exitApp exitmv = 
+    do mainQuit
+       ec <- takeMVar exitmv
+       case ec of
+            Nothing -> exitWith (ExitFailure 20)
+            Just x -> exitWith x
+
+procmessages gui stream = 
+    do buf <- textViewGetBuffer (messages gui)
+       iter <- textBufferGetEndIter buf
+       mark <- textBufferCreateMark buf Nothing iter True
+       -- tag <- textTagNew Nothing
+       -- set tag [textTagFamily := "Monospace"]
+       -- textBufferApplyTag buf tag iter iter
+       return $ map (\x -> (procmsg gui buf mark x, snd x)) stream
+
+procmsg gui buf mark (ltype, msg) =
+    do end <- textBufferGetEndIter buf
+       ipoint <- textBufferGetIterAtMark buf mark
+       textBufferDelete buf ipoint end
+       textBufferInsert buf ipoint ('\n' : msg)
+
+       lines <- textBufferGetLineCount buf
+       when (lines > 500) $ do
+               start <- textBufferGetStartIter buf
+               eol <- textBufferGetIterAtLine buf 1
+               textBufferDelete buf start eol 
+
+       -- scroll to the end of the buffer
+       adj <- scrolledWindowGetVAdjustment (messageswin gui)
+       upper <- adjustmentGetUpper adj
+       adjustmentSetValue adj upper
+
+       -- Update the iterator the new offset
+       case ltype of
+            HardLine -> do end <- textBufferGetEndIter buf
+                           textBufferMoveMark buf mark end
+            SoftLine -> return () -- leave the mark where it is
+       return ()
+
+procstream gui stream =
+    do (totalfiles, remainingstream) <- procscanning gui stream
+       progress <- newProgress "total" totalfiles
+       mapM_ (procprogress gui progress) remainingstream
+
+procscanning gui [] = return (0, [])
+procscanning gui ((action,x):xs)
+    | isSuffixOf "files..." x = 
+        action 
+        >> labelSetText (ltotal gui) ("Scanned " ++ (head (words x)) ++ " files")
+        >> progressBarPulse (pbtotal gui)
+        >> procscanning gui xs
+    | isSuffixOf "files to consider" x =
+        action
+        >> labelSetText (ltotal gui) "" 
+        >> progressBarSetFraction (pbtotal gui) 0.0
+        >> return (read . head . words $ x, xs)
+    | otherwise = action >> procscanning gui xs
+
+procprogress gui progress (action, line)
+    | progressl /= [] =
+        do action
+           case head progressl of
+             [_, bytes, pct] -> 
+               progressBarSetFraction (pbfile gui) ((read pct) / 100)
+               >> progressBarSetText (pbfile gui) (pct ++ "%")
+             x -> fail $ "Couldn't handle " ++ show x
+           case tocheck of
+             [] -> return ()
+             [[_, thisfile, total]] ->
+                 progressBarSetFraction (pbtotal gui) 
+                    (1.0 - (ithisfile / itotal))
+                 >> progressBarSetText (pbtotal gui)
+                      ("File " ++ show (floor (itotal - ithisfile))
+                       ++ " of " ++ total ++ " (" ++ show (intpct) ++ "%)")
+                 >> setP progress (floor (itotal - ithisfile))
+                 >> setetr
+                 where itotal = read total 
+                       ithisfile = read thisfile 
+                       intpct = floor (100 * (1.0 - (ithisfile / itotal)))
+                       setetr = do etr <- getETR progress
+                                   labelSetText (ltotal gui) 
+                                     ("ETA: " ++ renderSecs etr)
+             x -> fail $ "Tocheck couldn't handle " ++ show x
+    | otherwise =
+        action >> labelSetText (lfile gui) line
+
+    where progressl :: [[String]]
+          progressl = line =~ "^ *([0-9]+) +([0-9]+)%" -- .+[0-9]+:[0-9]+:[0-9]+" =~ line
+          tocheck = line =~ "xfer#[0-9]+, to-check=([0-9]+)/([0-9]+)"
+
+oobError gui msg = 
+    do dlg <- messageDialogNew (Just (mainwin gui)) [] MessageError ButtonsOk
+              ("An error has been detected:\n\n" ++ msg ++ 
+               "\n\nExpand the Messages area in the main window for details.")
+       dialogRun dlg
+       widgetDestroy dlg
+
diff --git a/RsyncParser.hs b/RsyncParser.hs
new file mode 100644
--- /dev/null
+++ b/RsyncParser.hs
@@ -0,0 +1,25 @@
+{- Copyright (c) 2007 John Goerzen <jgoerzen@complete.org>
+   Please see the COPYRIGHT file -}
+
+module RsyncParser where
+
+import Data.List
+
+data LineType = SoftLine | HardLine
+    deriving (Eq, Read, Show)
+
+-- | A line of input.  The 'LineType' corresponds to the type of EOL
+-- character that occured **BEFORE** the String.
+type RsyncLine = (LineType, String)
+
+customlines :: String -> [RsyncLine]
+customlines "" = []
+customlines x = 
+    case xs of
+         [] -> [(HardLine, line)]
+         -- ('\n' : '\r' : next) -> (HardLine, line) : customlines next
+         ('\n' : next) -> (HardLine, line) : customlines next
+         -- ('\r' : '\n' : next) -> (HardLine, line) : customlines next
+         ('\r' : next) -> (SoftLine, line) : customlines next
+    where (line, xs) = break (`elem` "\n\r") x
+
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,7 @@
+#!/usr/bin/env runhugs
+arch-tag: Main setup script
+
+> import Distribution.Simple
+
+> main = defaultMain
+
diff --git a/docs/SConstruct b/docs/SConstruct
new file mode 100644
--- /dev/null
+++ b/docs/SConstruct
@@ -0,0 +1,29 @@
+# Copyright (C) 2004 John Goerzen <jgoerzen@complete.org>
+# arch-tag: primary build for docs
+# <jgoerzen@complete.org>
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+env = Environment()
+env.Export("env")
+env.Append(MASTERBASE = 'hg', TOPNODE = 'hg', DOINDEX = 1,
+        HTMLARGS = '-s local', PDFARGS = '-s local=printlocal')
+
+execfile('sgml-common/SConstruct')
+
+manpages = []
+for manpage in ['gtkrsync']:
+    manpages.append(env.MAN('%s.1' % manpage, 'man.%s.sgml' % manpage))
+env.Alias('manpages', manpages)
diff --git a/docs/gtkrsync.1 b/docs/gtkrsync.1
new file mode 100644
--- /dev/null
+++ b/docs/gtkrsync.1
@@ -0,0 +1,121 @@
+.\" This manpage has been automatically generated by docbook2man 
+.\" from a DocBook document.  This tool can be found at:
+.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/> 
+.\" Please send any bug reports, improvements, comments, patches, 
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "GTKRSYNC" "1" "19 February 2010" "John Goerzen" "gtkrsync Manual"
+
+.SH NAME
+gtkrsync \- GUI front-end for rsync
+.SH SYNOPSIS
+
+\fBgtkrsync\fR [ \fB\fIargs for rsync\fB\fR\fI ...\fR ]
+
+
+\fBgtkrsyncp\fR
+
+.SH "DESCRIPTION"
+.PP
+\fBgtkrsync\fR is a graphical interface for displaying the progress of
+an \fBrsync\fR(1) session.  It displays a running status display from
+parsing the output of rsync --progress -v
+(with --no-inc-recursive with \fBrsync\fR v3.0 or
+above).  This
+status display includes a per-file and overall status bar, overall
+estimated time to completion, and an expandable button that shows
+all rsync status output.
+.PP
+Unlike other GUI rsync frontends such as grsync, \fBgtkrsync\fR does
+not have any GUI tools for configuring or invoking rsync.  \fBgtkrsync\fR
+is designed to be invoked from the command line or shell scripts,
+which already specify all the needed rsync options.  It is thus ideal
+for scripted \fBrsync\fR runs that need a GUI, or for command-line users
+that would like a GUI to monitor their \fBrsync\fR progress.
+.PP
+\fBgtkrsync\fR is a drop-in replacement
+for rsync.  It fires up the GUI and invokes \fBrsync\fR, passing all args to
+it.  When invoked this way, \fBgtkrsync\fR is able to detect if \fBrsync\fR exits
+in error and alerts the user.  \fBgtkrsync\fR can also monitor both stdout
+and stderr from \fBrsync\fR, and displays both.  The cancel button in
+\fBgtkrsync\fR also will kill off the \fBrsync\fR process.  You must make sure to
+pass --progress -v on the \fBgtkrsync\fR command line in
+order to get enough information out of \fBrsync\fR to build a proper GUI.
+.PP
+If ysing \fBrsync\fR version 3.0 or above, you must also add
+--no-inc-recursive to your command line.
+These newer versions of \fBrsync\fR use incremental tree scanning
+by default.  As a result, they do not emit information up
+front about the expected number of files to transfer, and thus
+\fBgtkrsync\fR would lack enough information to display its
+progress bars.
+.PP
+Besides \fBgtkrsync\fR, the other binary is \fBgtkrsyncp\fR\&.  This program accepts the output of
+rsync --progress -v on standard input and displays it in a GUI.  It
+cannot detect whether \fBrsync\fR exited in error and cannot kill \fBrsync\fR when
+Cancel is pressed.  However, this program may be useful in some cases
+when direct control of \fBrsync\fR is handled elsewhere.
+.SH "OPTIONS"
+.PP
+All options passed to \fBgtkrsync\fR are sent directly to
+\fBrsync\fR(1).  \fBgtkrsyncp\fR takes no options.
+.SH "EXIT VALUES"
+.PP
+\fBgtkrsync\fR and \fBgtkrsyncp\fR both return 0 on success or 20 if the user
+clicked Cancel or closed the window before the \fBrsync\fR was complete.
+20 is also the code that \fBrsync\fR uses to indicate a transfer
+interrupted by the user.
+.PP
+In all other cases, \fBgtkrsync\fR returns the result code that \fBrsync\fR
+returned.  \fBgtkrsyncp\fR returns 0.
+.SH "ENVIRONMENT VARIABLES"
+.PP
+\fBgtkrsync\fR will look for an RSYNC environment
+variable.  If set, it is taken to be the name of the \fBrsync\fR binary.
+If not given, rsync is used.  \fBgtkrsyncp\fR does not
+use this variable.
+.PP
+This application uses no other environment variables directly, but other
+programs or standard libraries may do so.  DISPLAY,
+for instance, must be set for the X libraries to work.
+.PP
+Users using \fBrsync\fR over \fBssh\fR may find the
+SSH_ASKPASS variable useful.  This is interpreted
+directly by \fBssh\fR and can specify a GUI tool
+to use to prompt the user for a password when needed.
+.SH "COPYRIGHT"
+.PP
+\fBgtkrsync\fR, all associated scripts and programs, this manual,
+and all build scripts are Copyright (C) 2007-2010 John Goerzen.
+.PP
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+.PP
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+.PP
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+.SH "AUTHOR"
+.PP
+\fBgtkrsync\fR, its modules, documentation, executables, and all
+included files, except where noted, was written by
+John Goerzen <jgoerzen@complete.org> and
+copyright is held as stated in the COPYRIGHT section.
+.PP
+\fBgtkrsync\fR may be downloaded from the Debian packaging system or at
+ <URL:http://packages.debian.org/gtkrsync>\&.
+.PP
+\fBgtkrsync\fR may also be downloaded using git by running
+\fBgit clone
+git://git.complete.org/gtkrsync\fR\&.
+.SH "SEE ALSO"
+.PP
+\fBrsync\fR(1),
+\fBgtkrsync\fR(1),
+\fBgtkrsyncp\fR(1),
+\fBssh\fR(1).
diff --git a/docs/man.gtkrsync.sgml b/docs/man.gtkrsync.sgml
new file mode 100644
--- /dev/null
+++ b/docs/man.gtkrsync.sgml
@@ -0,0 +1,202 @@
+<!-- vim: set filetype=docbkxml shiftwidth=2 autoindent expandtab tw=77 : -->
+<!DOCTYPE reference PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+  <!ENTITY package "<application>gtkrsync</application>">
+  <!ENTITY gtkrsync "<application>gtkrsync</application>">
+  <!ENTITY gtkrsyncp "<application>gtkrsyncp</application>">
+  <!ENTITY rsync "<application>rsync</application>">
+]>
+
+<reference>
+<title>gtkrsync Manual</title>
+
+  <refentry id="man.gtkrsync">
+    <indexterm><primary>gtkrsync</><secondary>Reference For</></>
+    <refentryinfo>
+      <address><email>jgoerzen@complete.org</email></address>
+      <author><firstname>John</firstname><surname>Goerzen</surname></author>
+    </refentryinfo>
+
+    <refmeta>
+      <refentrytitle>gtkrsync</refentrytitle>
+      <manvolnum>1</manvolnum>
+      <refmiscinfo>John Goerzen</refmiscinfo>
+    </refmeta>
+
+    <refnamediv>
+      <refname>gtkrsync</refname>
+      <refpurpose>GUI front-end for rsync</refpurpose>
+    </refnamediv>
+
+    <refsynopsisdiv>
+      <cmdsynopsis>
+      <command>gtkrsync</command>
+	<arg rep="repeat"><replaceable>args for rsync</replaceable></arg>
+      </cmdsynopsis>
+      <cmdsynopsis><command>gtkrsyncp</command></cmdsynopsis>
+    </refsynopsisdiv>
+
+    <refsect1 id="gtkrsync.desc">
+      <title>Description</title>
+      <para>
+        &gtkrsync; is a graphical interface for displaying the progress of
+        an &rsync;(1) session.  It displays a running status display from
+        parsing the output of <literal>rsync --progress -v</literal>
+        (with <literal>--no-inc-recursive</literal> with &rsync; v3.0 or
+        above).  This
+        status display includes a per-file and overall status bar, overall
+        estimated time to completion, and an expandable button that shows
+        all rsync status output.
+      </para> 
+
+      <para> Unlike other GUI rsync frontends such as grsync, &gtkrsync; does
+        not have any GUI tools for configuring or invoking rsync.  &gtkrsync;
+        is designed to be invoked from the command line or shell scripts,
+        which already specify all the needed rsync options.  It is thus ideal
+        for scripted &rsync; runs that need a GUI, or for command-line users
+        that would like a GUI to monitor their &rsync; progress.
+      </para>
+
+      <para>
+        &gtkrsync; is a drop-in replacement
+ for rsync.  It fires up the GUI and invokes &rsync;, passing all args to
+ it.  When invoked this way, &gtkrsync; is able to detect if &rsync; exits
+ in error and alerts the user.  &gtkrsync; can also monitor both stdout
+ and stderr from &rsync;, and displays both.  The cancel button in
+ &gtkrsync; also will kill off the &rsync; process.  You must make sure to
+ pass <literal>--progress -v</literal> on the &gtkrsync; command line in
+ order to get enough information out of &rsync; to build a proper GUI.
+      </para>
+
+      <para>
+        If ysing &rsync; version 3.0 or above, you must also add
+        <literal>--no-inc-recursive</literal> to your command line.
+        These newer versions of &rsync; use incremental tree scanning
+        by default.  As a result, they do not emit information up
+        front about the expected number of files to transfer, and thus
+        &gtkrsync; would lack enough information to display its
+        progress bars.
+      </para>
+
+      <para>
+        Besides &gtkrsync;, the other binary is &gtkrsyncp;.  This program accepts the output of
+        <literal>rsync --progress -v</literal> on standard input and displays it in a GUI.  It
+ cannot detect whether &rsync; exited in error and cannot kill &rsync; when
+ Cancel is pressed.  However, this program may be useful in some cases
+ when direct control of &rsync; is handled elsewhere.
+      </para>
+
+    </refsect1>
+
+    <refsect1 id="hg.man.hg.buildpackage.options">
+      <title>Options</title>
+      <para>
+        All options passed to &gtkrsync; are sent directly to
+        <application>rsync</application>(1).  &gtkrsyncp; takes no options.
+      </para>
+    </refsect1>
+
+    <refsect1 id="exit">
+      <title>EXIT VALUES</title>
+      <para>
+        &gtkrsync; and &gtkrsyncp; both return 0 on success or 20 if the user
+        clicked Cancel or closed the window before the &rsync; was complete.
+        20 is also the code that &rsync; uses to indicate a transfer
+        interrupted by the user.
+      </para>
+      <para>
+        In all other cases, &gtkrsync; returns the result code that &rsync;
+        returned.  &gtkrsyncp; returns 0.
+      </para>
+    </refsect1>
+
+    <refsect1 id="environment">
+      <title>ENVIRONMENT VARIABLES</title>
+      <para>
+        &gtkrsync; will look for an <literal>RSYNC</literal> environment
+        variable.  If set, it is taken to be the name of the &rsync; binary.
+        If not given, <literal>rsync</literal> is used.  &gtkrsyncp; does not
+        use this variable.
+      </para>
+      <para>
+        This application uses no other environment variables directly, but other
+        programs or standard libraries may do so.  <literal>DISPLAY</literal>,
+        for instance, must be set for the X libraries to work.
+      </para>
+      <para>
+        Users using &rsync; over <application>ssh</application> may find the
+        <literal>SSH_ASKPASS</literal> variable useful.  This is interpreted
+        directly by <application>ssh</application> and can specify a GUI tool
+        to use to prompt the user for a password when needed.
+      </para>
+    </refsect1>
+
+    <refsect1>
+      <title>Copyright</title>
+  <para>
+    &gtkrsync;, all associated scripts and programs, this manual,
+    and all build scripts are Copyright &copy; 2007-2010 John Goerzen.
+  </para>
+      <para>
+        This program is free software; you can redistribute it and/or modify
+        it under the terms of the GNU General Public License as published by
+        the Free Software Foundation; either version 2 of the License, or
+        (at your option) any later version.
+      </para>
+
+      <para>
+        This program is distributed in the hope that it will be useful,
+        but WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+        GNU General Public License for more details.
+      </para>
+
+      <para>
+        You should have received a copy of the GNU General Public License
+        along with this program; if not, write to the Free Software
+        Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+      </para>
+    </refsect1>
+
+
+    <refsect1>
+      <title>Author</title>
+      <para>
+	&package;, its modules, documentation, executables, and all
+	included files, except where noted, was written by
+	John Goerzen <email>jgoerzen@complete.org</email> and
+	copyright is held as stated in the COPYRIGHT section.
+      </para>
+      <para>
+	&package; may be downloaded from the Debian packaging system or at
+	<ulink
+	  url="http://packages.debian.org/gtkrsync"></ulink>.
+      </para>
+      <para>
+	&package; may also be downloaded using git by running
+        <command>git clone
+        git://git.complete.org/gtkrsync</command>.
+      </para>
+    </refsect1>
+
+  <refsect1>
+          <title>See Also</title>
+  <para>
+    <application>rsync</application>(1),
+    <application>gtkrsync</application>(1),
+    <application>gtkrsyncp</application>(1),
+    <application>ssh</application>(1).
+  </para>
+  </refsect1>
+
+  </refentry>
+  
+<!-- </reference> -->
+
+<!--
+Local Variables:
+mode: sgml
+sgml-set-face: T
+End:
+
+-->
+</reference>
diff --git a/docs/sgml-common/COPYING b/docs/sgml-common/COPYING
new file mode 100644
--- /dev/null
+++ b/docs/sgml-common/COPYING
@@ -0,0 +1,342 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
+
+# arch-tag: License for sgml-common
diff --git a/docs/sgml-common/COPYRIGHT b/docs/sgml-common/COPYRIGHT
new file mode 100644
--- /dev/null
+++ b/docs/sgml-common/COPYRIGHT
@@ -0,0 +1,39 @@
+Copyright for all code except ps2epsi
+-------------------------------------
+# Copyright (C) 2002, 2003 John Goerzen
+# <jgoerzen@complete.org>
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+Copyright for ps2epsi
+---------------------
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+
+My local changes were to the page size.
+
+# arch-tag: Copyright statements and information for sgml-common
diff --git a/docs/sgml-common/ChangeLog b/docs/sgml-common/ChangeLog
new file mode 100644
--- /dev/null
+++ b/docs/sgml-common/ChangeLog
@@ -0,0 +1,265 @@
+# do not edit -- automatically generated by arch changelog
+# arch-tag: automatic-ChangeLog--jgoerzen@complete.org--projects/sgml-common--head--1.0
+#
+
+2004-05-21 14:28:00 GMT	John Goerzen <jgoerzen@complete.org>	patch-20
+
+    Summary:
+      Fixed text target
+    Revision:
+      sgml-common--head--1.0--patch-20
+
+
+    modified files:
+     ChangeLog SConstruct
+
+
+2004-02-27 15:22:59 GMT	John Goerzen <jgoerzen@complete.org>	patch-19
+
+    Summary:
+      Added manpage generation support
+    Revision:
+      sgml-common--head--1.0--patch-19
+
+
+    modified files:
+     ChangeLog SConstruct
+
+
+2004-02-03 19:50:11 GMT	John Goerzen <jgoerzen@complete.org>	patch-18
+
+    Summary:
+      More clearing up of REs
+    Revision:
+      sgml-common--head--1.0--patch-18
+
+
+    modified files:
+     ChangeLog SConstruct
+
+
+2004-02-03 19:40:22 GMT	John Goerzen <jgoerzen@complete.org>	patch-17
+
+    Summary:
+      Tightened up re for finding image tags
+    Revision:
+      sgml-common--head--1.0--patch-17
+
+
+    modified files:
+     ChangeLog SConstruct
+
+
+2004-02-03 19:28:03 GMT	John Goerzen <jgoerzen@complete.org>	patch-16
+
+    Summary:
+      More changes to support scanner
+    Revision:
+      sgml-common--head--1.0--patch-16
+
+    Removed outdated code and made more bugfixes relevant to documents without
+    images or with only pre-generated images.
+
+    new files:
+     ChangeLog
+
+    modified files:
+     SConstruct
+
+
+2004-02-03 18:41:51 GMT	John Goerzen <jgoerzen@complete.org>	patch-15
+
+    Summary:
+      HTML gen now basically functional with scanning
+    Revision:
+      sgml-common--head--1.0--patch-15
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-03 17:41:51 GMT	John Goerzen <jgoerzen@complete.org>	patch-14
+
+    Summary:
+      Auto-scanning is now close for PDFs.
+    Revision:
+      sgml-common--head--1.0--patch-14
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-03 16:59:02 GMT	John Goerzen <jgoerzen@complete.org>	patch-13
+
+    Summary:
+      Scanners starting to work
+    Revision:
+      sgml-common--head--1.0--patch-13
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-03 16:22:51 GMT	John Goerzen <jgoerzen@complete.org>	patch-12
+
+    Summary:
+      Cleaned up HTML situation
+    Revision:
+      sgml-common--head--1.0--patch-12
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 22:33:50 GMT	John Goerzen <jgoerzen@complete.org>	patch-11
+
+    Summary:
+      SConstruct file now working
+    Revision:
+      sgml-common--head--1.0--patch-11
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 22:07:27 GMT	John Goerzen <jgoerzen@complete.org>	patch-10
+
+    Summary:
+      Fixed nasty PNG gen bug
+    Revision:
+      sgml-common--head--1.0--patch-10
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 21:57:32 GMT	John Goerzen <jgoerzen@complete.org>	patch-9
+
+    Summary:
+      Checkpointing some more...
+    Revision:
+      sgml-common--head--1.0--patch-9
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 21:37:29 GMT	John Goerzen <jgoerzen@complete.org>	patch-8
+
+    Summary:
+      Checkpointing some more...
+    Revision:
+      sgml-common--head--1.0--patch-8
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 20:19:02 GMT	John Goerzen <jgoerzen@complete.org>	patch-7
+
+    Summary:
+      Checkpointing
+    Revision:
+      sgml-common--head--1.0--patch-7
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 19:18:40 GMT	John Goerzen <jgoerzen@complete.org>	patch-6
+
+    Summary:
+      Added Plucker
+    Revision:
+      sgml-common--head--1.0--patch-6
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 19:09:16 GMT	John Goerzen <jgoerzen@complete.org>	patch-5
+
+    Summary:
+      Added cleanup rules
+    Revision:
+      sgml-common--head--1.0--patch-5
+
+
+    modified files:
+     SConstruct
+
+
+2004-02-02 18:58:11 GMT	John Goerzen <jgoerzen@complete.org>	patch-4
+
+    Summary:
+      sources now checks only chapters/ to prevent dep cycle with index
+    Revision:
+      sgml-common--head--1.0--patch-4
+
+
+    modified files:
+     Makefile.common SConstruct {arch}/=tagging-method
+
+
+2004-02-02 17:51:27 GMT	John Goerzen <jgoerzen@complete.org>	patch-3
+
+    Summary:
+      Experimental SCons conversion
+    Revision:
+      sgml-common--head--1.0--patch-3
+
+
+    new files:
+     SConstruct
+
+
+2003-10-21 20:24:04 GMT	John Goerzen <jgoerzen@complete.org>	patch-2
+
+    Summary:
+      Added plain text generation target
+    Revision:
+      sgml-common--head--1.0--patch-2
+
+    Added plain text generation target
+    
+
+    modified files:
+     ./Makefile.common
+
+
+2003-09-10 14:27:58 GMT	John Goerzen <jgoerzen@complete.org>	patch-1
+
+    Summary:
+      Minor updates to PNG generation and gtk-doc icon locations
+    Revision:
+      sgml-common--head--1.0--patch-1
+
+
+    modified files:
+     Makefile.common
+
+
+2003-09-10 14:24:24 GMT	John Goerzen <jgoerzen@complete.org>	base-0
+
+    Summary:
+      initial import
+    Revision:
+      sgml-common--head--1.0--base-0
+
+    
+    (automatically generated log message)
+
+    new files:
+     COPYING COPYRIGHT Makefile.common ps2epsi
+
+
diff --git a/docs/sgml-common/Makefile.common b/docs/sgml-common/Makefile.common
new file mode 100644
--- /dev/null
+++ b/docs/sgml-common/Makefile.common
@@ -0,0 +1,229 @@
+# -*- Mode: makefile; -*-
+# arch-tag: Primary sgml-common top-level Makefile
+# Common Makefile for SGML documents
+#
+# Copyright (C) 2002, 2003 John Goerzen
+# <jgoerzen@complete.org>
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+# The following variables should be set:
+# MASTERBASE -- basename of master file -- example: my-guide
+# BASICDEPS -- various dependencies of the master file.  For instance,
+#   this might include files included in the SGML.  It could also be empty.
+# TOPNODE -- Basename of top id for HTML link.
+
+MASTER := $(MASTERBASE).sgml
+FIGUREDIRS := $(wildcard figures/*)
+DOINDEX ?= yes
+
+######################################################################
+# Index generation
+######################################################################
+
+ifeq ($(DOINDEX), yes)
+
+INDEXSGMLFILE := index/index.sgml
+INDEXDATAFILE := index/HTML.index
+
+$(INDEXSGMLFILE): $(INDEXDATAFILE)
+	@echo " *** Generating SGML index from index list"
+	collateindex.pl -i ch.index -g -o index/index.sgml index/HTML.index
+
+$(INDEXDATAFILE): $(MASTER) $(BASICDEPS)
+#	jade -t sgml -d docbook.dsl -V html-index $(MASTER)
+#	jade -t sgml -V html-index $(MASTER)
+	@echo " *** Generating index list from document"
+	-rm -r index
+	mkdir index
+	collateindex.pl -i ch.index -N -o index/index.sgml
+	#mkdir html-temp
+	#docbook2html --output html-temp -V html-index $(MASTER)
+	docbook-2-html -O -V -O html-index $(HTMLARGS) $(MASTER)
+	mv $(MASTERBASE)-html/HTML.index index/
+	rm -r $(MASTERBASE)-html
+endif # DOINDEX
+
+######################################################################
+# Text generation
+######################################################################
+$(MASTERBASE).txt: $(MASTER) $(BASICDEPS) $(INDEXSGMLFILE)
+	@echo " *** Generating text output"
+	docbook2txt $(MASTER)
+
+######################################################################
+# PostScript generation
+######################################################################
+
+$(MASTERBASE).ps: $(MASTER) $(BASICDEPS) $(INDEXSGMLFILE) $(EPSFILES)
+	@echo " *** Generating PostScript output"
+# This works too: docbook2ps -V paper-size=Letter $(MASTER)
+	docbook-2-ps -q -O -V -O paper-size=Letter $(PSARGS) $(MASTER)
+
+######################################################################
+# Figure generation
+######################################################################
+
+%_1.epi: %.ps
+	$(get-epi)
+%_2.epi: %.ps
+	$(get-epi)
+%_3.epi: %.ps
+	$(get-epi)
+%_4.epi: %.ps
+	$(get-epi)
+%_5.epi: %.ps
+	$(get-epi)
+%_6.epi: %.ps
+	$(get-epi)
+%_7.epi: %.ps
+	$(get-epi)
+%_8.epi: %.ps
+	$(get-epi)
+%_9.epi: %.ps
+	$(get-epi)
+%_10.epi: %.ps
+	$(get-epi)
+%_11.epi: %.ps
+	$(get-epi)
+%_12.epi: %.ps
+	$(get-epi)
+
+%_1_l.epi: %.ps
+	$(get-epil)
+%_2_l.epi: %.ps
+	$(get-epil)
+%_3_l.epi: %.ps
+	$(get-epil)
+%_4_l.epi: %.ps
+	$(get-epil)
+%_5_l.epi: %.ps
+	$(get-epil)
+%_6_l.epi: %.ps
+	$(get-epil)
+%_7_l.epi: %.ps
+	$(get-epil)
+%_8_l.epi: %.ps
+	$(get-epil)
+%_9_l.epi: %.ps
+	$(get-epil)
+%_10_l.epi: %.ps
+	$(get-epil)
+%_11_l.epi: %.ps
+	$(get-epil)
+%_12_l.epi: %.ps
+	$(get-epil)
+
+%.png: %_l.epi
+	@echo " *** Generating PNG image for $<"
+	gs -q -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -r90 -dBATCH -dNOPAUSE \
+		-dSAFER -sOutputFile=$@ -sDEVICE=png16m $< -c showpage
+
+%.ps: %.pdf
+	pdftops $<
+
+######################################################################
+# HTML generation
+######################################################################
+
+define copy-figures-worker
+mkdir html/figures
+for DIRECTORY in $(FIGUREDIRS); do mkdir html/$$DIRECTORY; cp -v $$DIRECTORY/*.png html/$$DIRECTORY/; done
+endef
+
+define copy-figures
+$(if $(FIGUREDIRS),$(copy-figures-worker))
+endef
+
+html/index.html: $(MASTER) $(BASICDEPS) $(INDEXSGMLFILE) $(PNGFILES)
+	@echo " *** Generating HTML output"
+	-rm -r html
+	mkdir html
+	#docbook2html --output html $(MASTER)
+	docbook-2-html $(HTMLARGS) $(MASTER)
+	mv $(MASTERBASE)-html/* html/
+	rmdir $(MASTERBASE)-html
+	$(copy-figures)
+#	tidy -m html/*.html
+	ln -s $(TOPNODE).html html/index.html
+	-cp -v /usr/share/gtk-doc/data/*.png html/
+
+######################################################################
+# Cleaning
+######################################################################
+
+clean:
+	-rm -f `find . -name "*~"` `find . -name "*.png"` `find . -name "*.epi"`
+	-rm -r html-temp html index $(MASTERBASE).txt
+	-rm *.aux *.log *.dvi *.tex *.jtex *.ps *.html *.log *.out jadetex.cfg
+	-rm *.ps html/*.html figures/topology/*.epi figures/topology/*.png
+	-rm *.log *.pdb
+	-rm `find . -name ".ps"` `find . -name "*.epi"` *.pdf
+	-rm `find . -name "*.png"`
+
+######################################################################
+# Utility functions
+######################################################################
+
+GETPAGE=$(shell echo $(1) | sed -e "s/^.*_\([0-9]*\).epi/\\1/g")
+define get-epi
+@echo " *** Generating EPI image for $<"
+psselect -q $(call GETPAGE,$@) $< temp.ps
+psresize -w 6.375in -h 8.25in temp.ps temp2.ps
+../sgml-common/ps2epsi temp2.ps $@
+rm temp.ps temp2.ps
+endef
+
+GETPAGEL=$(shell echo $(1) | sed -e "s/^.*_\([0-9]*\)_l.epi/\\1/g")
+define get-epil
+@echo " *** Generating large EPI image for $<"
+psselect -q $(call GETPAGEL,$@) $< temp.ps
+psresize -w 8.5in -h 11in temp.ps temp2.ps
+../sgml-common/ps2epsi temp2.ps $@
+rm temp.ps temp2.ps
+endef
+
+
+pdf: $(MASTERBASE).pdf
+
+$(MASTERBASE).pdf: $(MASTERBASE).ps
+	ps2pdf14 $(MASTERBASE).ps
+
+plucker: $(MASTERBASE).pdb
+$(MASTERBASE).pdb: html
+	plucker-build --bpp=4 --compression=zlib --doc-name="$(MASTERBASE)" \
+	-H file:`pwd`/html/index.html -M 5 \
+	--maxheight=320 --maxwidth=310 \
+	--staybelow=file:`pwd`/html --title="$(MASTERBASE)" -p . \
+	-f $(MASTERBASE)
+
+###########################################################################
+# These are obsolete but should still work.
+###########################################################################
+
+
+$(MASTERBASE).dvi: $(MASTERBASE).tex
+	@echo " *** Generating DVI file."
+	jadetex unix-guide.tex
+	jadetex unix-guide.tex
+	jadetex unix-guide.tex
+
+$(MASTERBASE).tex: $(MASTER) $(BASICDEPS) $(INDEXSGMLFILE)
+	@echo " *** Generating TeX files."
+	docbook2tex -V paper-size=Letter $(MASTER)
+#	jade -t tex -V tex-backend -d \
+#		/usr/share/sgml/docbook/stylesheet/dsssl/modular/print/docbook.dsl \
+#		$(MASTER)
+
diff --git a/docs/sgml-common/SConstruct b/docs/sgml-common/SConstruct
new file mode 100644
--- /dev/null
+++ b/docs/sgml-common/SConstruct
@@ -0,0 +1,208 @@
+# vim: set filetype=python :
+# arch-tag: general-purpose SCons build file for sgml-common
+
+from glob import glob
+import os, re
+
+############################################################
+# Setup
+############################################################
+
+SConsignFile('.sconsign-master')
+#Import('env')
+d = env.Dictionary()
+if not 'JADE' in d:
+    d['JADE'] = 'jade'
+if not 'INDEXNODE' in d:
+    d['INDEXNODE'] = 'ch.index'
+if not 'GTKIMGPATH' in d:
+    d['GTKIMGPATH'] = '/usr/share/gtk-doc/data'
+if not 'PS2EPSI' in d:
+    d['PS2EPSI'] = '../sgml-common/ps2epsi'
+
+def removeindex(l):
+    while 'index/index.sgml' in l:
+        l.remove('index/index.sgml')
+
+master = d['MASTERBASE'] 
+mastersgml = master + '.sgml'
+sources = [mastersgml] + glob('*/*.sgml') + glob('*/*/*.sgml')
+removeindex(sources)
+db2htmlcmd = 'docbook-2-html -D $JADE ${HTMLARGS}  ${SOURCE}'
+db2htmlindexcmd = 'docbook-2-html -D $JADE -O -V -O html-index ${HTMLARGS} ${SOURCE}'
+
+##################################################
+# SCANNERS
+##################################################
+def recursescan(scanner, node, env):
+    result = scanner(node, env) 
+    retval = []
+    for item in result:
+        retval.append(item)
+        retval.extend(recursescan(scanner, item, env))
+    return retval
+
+SGML_includes_re = re.compile(r'<!ENTITY[^>]+SYSTEM[^>]+"(.+)"', re.M)
+def SGML_includes_scan(node, env, path):
+    ret = SGML_includes_re.findall(node.get_contents())
+    removeindex(ret)
+    return ret
+
+SGML_includes_scanner = Scanner(name = 'SGML_includes',
+    function = SGML_includes_scan, recursive = 1, skeys = ['.sgml', '.ent'])
+
+SGML_image_pdf_re = re.compile(r'<(graphic|imagedata).+?fileref="([^"]+\.pdf)"', re.S)
+SGML_image_png_re = re.compile(r'<(graphic|imagedata).+?fileref="([^"]+\.png)"', re.S)
+def SGML_image_scanner(node, env, path, arg):
+    root, ext = os.path.splitext(str(node))
+    contents = node.get_contents()
+    return SGML_includes_scan(node, env, path) + \
+            [os.getcwd() + '/' + x[1] for x in arg.findall(contents)]
+
+SGML_pdf_scanner = Scanner(name = 'SGML_pdf',
+         function = SGML_image_scanner, argument = SGML_image_pdf_re,
+         recursive = 1)
+SGML_png_scanner = Scanner(name = 'SGML_png',
+        function = SGML_image_scanner, argument = SGML_image_png_re,
+        recursive = 1)
+
+##################################################
+# BUILDERS
+##################################################
+
+#### PLAIN TEXT
+Btxt = Builder(action="docbook2txt $SOURCE", src_suffix='.sgml', suffix='.txt')
+
+#### PDF / POSTSCRIPT
+Bpdf = Builder(action="docbook-2-pdf -D ${JADE} -q -O -V -O paper-size=Letter ${PDFARGS} ${SOURCE}",
+        src_suffix='.sgml', suffix='.pdf')
+Bpdf2ps = Builder(action="pdftops ${SOURCE}", src_suffix='.pdf', suffix='.ps')
+
+#### MAN PAGES
+# FIXME: test this
+Bman = Builder(action="docbook2man $SOURCE", src_suffix='.sgml', suffix='.1')
+
+#### HTML
+Bhtml = Builder(action = [ \
+        'if test -d ${TARGET.dir} ; then rm -r ${TARGET.dir} ; fi',
+        'mkdir ${TARGET.dir}',
+        db2htmlcmd,
+        'mv ${MASTERBASE}-html/* ${TARGET.dir}/',
+        'rmdir ${MASTERBASE}-html',
+        'ln -s ${TOPNODE}.html ${TARGET.dir}/index.html',
+        'cp ${GTKIMGPATH}/*.png ${TARGET.dir}/'])
+
+#### PNG
+Bepip2png = Builder(action = 'gs -q -dTextAlphaBits=4 -dGraphicsAlphaBits=4 ' +\
+        '-r90 -dBATCH -dNOPAUSE -dSAFER -sOutputFile=$TARGET ' + \
+        '-sDEVICE=png16m $SOURCE -c showpage', suffix='.png', src_suffix='.pngepi')
+
+#### EPI from PS
+def getpagenumfromname(target, source, env, for_signature):
+    return re.search('^.*_(\d+)\.(png){0,1}epi$', str(target[0])).group(1)
+d['GETPAGE'] = getpagenumfromname
+
+Aps2epi = Action(['psselect -q ${GETPAGE} $SOURCE temp.ps',
+        'psresize -w ${WIDTH} -h ${HEIGHT} temp.ps temp2.ps',
+        '$PS2EPSI temp2.ps $TARGET',
+        'rm temp.ps temp2.ps'])
+Bps2epi = Builder(action=Aps2epi, src_suffix='.ps', suffix='.epi')
+Bps2epip = Builder(action=Aps2epi, src_suffix='.ps', suffix='.pngepi')
+Bepi2pdf = Builder(action="epstopdf -o=${TARGET} ${SOURCE}", suffix='.pdf',
+        src_suffix='.epi')
+
+#### PLUCKER
+Bplucker = Builder(action = 'plucker-build --bpp=4 --compression=zlib ' + \
+        '--doc-name="${MASTERBASE}" -H file:${SOURCE.abspath} -M 5 ' + \
+        '--maxheight=320 --maxwidth=310 --staybelow=file:`pwd`/${SOURCE.dir} ' + \
+        '--title="${MASTERBASE}" -p . -f ${MASTERBASE}')
+
+##################################################
+# General setup
+##################################################
+
+env.Append(BUILDERS = {'Text': Btxt, 'PDF2PS': Bpdf2ps, 'PDF': Bpdf, 'HTML': Bhtml,
+        'Plucker': Bplucker, 'PS2EPI': Bps2epi, 'PS2EPIP': Bps2epip,
+        'EPI2PDF': Bepi2pdf, 'EPIP2PNG': Bepip2png, 'MAN': Bman})
+
+#### INDEX GENERATION
+if 'DOINDEX' in d:
+    Bindex = Builder(action = ['if test -d ${TARGET.dir}  ; then rm -r ${TARGET.dir} ; fi',
+        "mkdir ${TARGET.dir}",
+        "collateindex.pl -i $INDEXNODE -N -o $TARGET",
+        db2htmlindexcmd,
+        "mv ${MASTERBASE}-html/HTML.index ${TARGET.dir}/",
+        "rm -r ${MASTERBASE}-html",
+        "collateindex.pl -i $INDEXNODE -g -o $TARGET ${TARGET.dir}/HTML.index"])
+    env['BUILDERS']['Index'] = Bindex
+    index = env.Index('index/index.sgml', mastersgml)
+    env.Depends(index, sources)
+    env.Clean(index, 'index')
+    deps = sources + [index]
+else:
+    deps = sources
+
+##################################################
+# BUILD RULES
+###################################################
+# Text
+text = env.Text(mastersgml)
+env.Depends(text, deps)
+env.Alias('text', text)
+
+# PDF
+pdfsgml = File(mastersgml)
+pdf = env.PDF(pdfsgml)
+figsindoc = [x for x in recursescan(SGML_pdf_scanner, pdfsgml, env) if str(x).endswith('.pdf')]
+epipdf = []
+for file in figsindoc:
+    pdfname = re.sub('_\d+\.pdf$', '.pdf', str(file))
+    if pdfname == str(file):
+        # This is not a filename that fits our pattern; add unmodified.
+        epipdf.append(file)
+        continue
+    psfile = env.PDF2PS(source = pdfname)
+    epifile = env.PS2EPI(str(file).replace(".pdf", ".epi"), psfile,
+            WIDTH='6.375in', HEIGHT='8.25in')
+    epipdf.append(env.EPI2PDF(source = epifile))
+
+env.Depends(pdf, deps)
+env.Depends(pdf, epipdf)
+env.Alias('pdf', pdf)
+env.Clean(pdf, ['jadetex.cfg', '${MASTERBASE}.aux', '${MASTERBASE}.dvi',
+        '${MASTERBASE}.jtex', '${MASTERBASE}.log', '${MASTERBASE}.out',
+        'jade-out.fot'])
+
+# PS
+ps = env.PDF2PS(source = pdf)
+env.Alias('ps', ps)
+
+# HTML
+htmlsgml = File(mastersgml)
+buildhtml = env.HTML('html/index.html', htmlsgml)
+figsindoc = [x for x in recursescan(SGML_png_scanner, htmlsgml, env) if str(x).endswith('.png')]
+epipng = []
+for file in figsindoc:
+    pdfname = re.sub('_\d+\.png$', '.pdf', str(file))
+    if pdfname == str(file):
+        # This is not a filename that fits our pattern; add unmodified. 
+        epipng.append(file)
+        continue
+    psfile = env.PDF2PS(source = pdfname)
+    epifile = env.PS2EPIP(str(file).replace(".png", ".pngepi"), psfile,
+            WIDTH='8.5in', HEIGHT='11in')
+    epipng.append(env.EPIP2PNG(source = epifile))
+
+env.Depends(buildhtml, epipng)
+env.Depends(buildhtml, deps)
+pnginstalls = env.InstallAs(['html/' + str(x) for x in epipng], epipng)
+env.Depends(pnginstalls, buildhtml)
+html = env.Alias('html', buildhtml)
+html = env.Alias('html', pnginstalls)
+env.Clean(buildhtml, 'html')
+
+# Plucker
+plucker = env.Plucker(master + '.pdb', 'html/index.html')
+env.Alias('plucker', plucker)
+
+env.Default(html)
diff --git a/docs/sgml-common/ps2epsi b/docs/sgml-common/ps2epsi
new file mode 100644
--- /dev/null
+++ b/docs/sgml-common/ps2epsi
@@ -0,0 +1,77 @@
+#!/bin/sh
+# $RCSfile: ps2epsi,v $ $Revision: 1.4.2.2 $
+# arch-tag: ps2epsi customized for sgml-common
+
+tmpfile=/tmp/ps2epsi$$
+
+export outfile
+
+if [ $# -lt 1 -o $# -gt 2 ]; then
+	echo "Usage: `basename $0` file.ps [file.epsi]" 1>&2
+	exit 1
+fi
+
+infile=$1;
+
+if [ $# -eq 1 ]
+then
+	case "${infile}" in
+	  *.ps)		base=`basename ${infile} .ps` ;;
+	  *.cps)	base=`basename ${infile} .cps` ;;
+	  *.eps)	base=`basename ${infile} .eps` ;;
+	  *.epsf)	base=`basename ${infile} .epsf` ;;
+	  *)		base=`basename ${infile}` ;;
+	esac
+	outfile=${base}.epsi
+else
+	outfile=$2
+fi
+
+ls -l ${infile} |
+awk 'F==1	{
+		cd="%%CreationDate: " $6 " " $7 " " $8;
+		t="%%Title: " $9;
+		f="%%For:" U " " $3;
+		c="%%Creator: Ghostscript ps2epsi from " $9;
+		next;
+		}
+	/^%!/	{next;}
+	/^%%Title:/	{t=$0; next;}
+	/^%%Creator:/	{c=$0; next;}
+	/^%%CreationDate:/	{cd=$0; next;}
+	/^%%For:/	{f=$0; next;}
+	!/^%/	{
+		print "/ps2edict 30 dict def";
+		print "ps2edict begin";
+		print "/epsititle (" t "\\n) def";
+		print "/epsicreator (" c "\\n) def";
+		print "/epsicrdt (" cd "\\n) def";
+		print "/epsifor (" f "\\n) def";
+		print "end";
+		exit(0);
+		}
+	' U="$USERNAME$LOGNAME"  F=1 - F=2 ${infile} >$tmpfile
+
+gs -q -dNOPAUSE -dSAFER -dDELAYSAFER -r72 -sDEVICE=bit -sOutputFile=/dev/null $tmpfile ps2epsi.ps $tmpfile <${infile} 1>&2
+rm -f $tmpfile
+
+(
+cat << BEGINEPS
+save countdictstack mark newpath /showpage {} def /setpagedevice {pop} def
+%%EndProlog
+%%Page 1 1
+BEGINEPS
+
+cat ${infile} |
+sed -e '/^%%BeginPreview:/,/^%%EndPreview[^!-~]*$/d' -e '/^%!PS-Adobe/d'\
+    -e '/^%%[A-Za-z][A-Za-z]*[^!-~]*$/d' -e '/^%%[A-Za-z][A-Za-z]*: /d'
+
+cat << ENDEPS
+%%Trailer
+cleartomark countdictstack exch sub { end } repeat restore
+%%EOF
+ENDEPS
+
+) >> ${outfile}
+
+exit 0
diff --git a/gtkrsync.cabal b/gtkrsync.cabal
new file mode 100644
--- /dev/null
+++ b/gtkrsync.cabal
@@ -0,0 +1,43 @@
+Name: gtkrsync
+Version: 1.0.4
+License: GPL
+Maintainer: John Goerzen <jgoerzen@complete.org>
+Author: John Goerzen
+Stability: Beta
+Copyright: Copyright (c) 2007-2010 John Goerzen
+license-file: COPYRIGHT
+build-type: Simple
+extra-source-files: COPYING,
+                    docs/gtkrsync.1,
+                    docs/man.gtkrsync.sgml,
+                    docs/SConstruct,
+                    docs/sgml-common/ChangeLog,
+                    docs/sgml-common/COPYING,
+                    docs/sgml-common/COPYRIGHT,
+                    docs/sgml-common/Makefile.common,
+                    docs/sgml-common/ps2epsi,
+                    docs/sgml-common/SConstruct,
+                    gtkrsync.gladep,
+                    Makefile,
+                    screenshot1.png,
+                    screenshot2.png,
+                    RsyncGUI.hs,
+                    RsyncParser.hs
+homepage: http://hg.complete.org/gtkrsync
+Category: Network
+Synopsis: Gnome rsync progress display
+Description: gtkrsync is a simple GUI that displays a running status display
+ built from rsync.  This status display includes a per-file and overall status
+ bar, overall estimated time to completion, and an expandable button that shows
+ all rsync status output.
+Build-Depends: base < 5, unix, gtk, gconf, glade, regex-posix, MissingH, process
+data-files: gtkrsync.glade
+
+Executable: gtkrsync
+Main-Is: gtkrsync.hs
+GHC-Options: -O2
+
+Executable: gtkrsyncp
+Main-Is: gtkrsyncp.hs
+GHC-Options: -O2
+
diff --git a/gtkrsync.glade b/gtkrsync.glade
new file mode 100644
--- /dev/null
+++ b/gtkrsync.glade
@@ -0,0 +1,359 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
+
+<glade-interface>
+
+<widget class="GtkWindow" id="mainwindow">
+  <property name="width_request">400</property>
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">gtkrsync</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">False</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+
+  <child>
+    <widget class="GtkVBox" id="vbox1">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child>
+	<widget class="GtkFrame" id="frame1">
+	  <property name="visible">True</property>
+	  <property name="label_xalign">0</property>
+	  <property name="label_yalign">0.5</property>
+	  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment1">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">12</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox2">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkProgressBar" id="progressbarfile">
+		      <property name="visible">True</property>
+		      <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+		      <property name="fraction">0</property>
+		      <property name="pulse_step">0.10000000149</property>
+		      <property name="text" translatable="yes"> </property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="labelfile">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Scanning data...</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label2">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Per-File Progress&lt;/b&gt;</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">label_item</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkFrame" id="frame2">
+	  <property name="visible">True</property>
+	  <property name="label_xalign">0</property>
+	  <property name="label_yalign">0.5</property>
+	  <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
+
+	  <child>
+	    <widget class="GtkAlignment" id="alignment2">
+	      <property name="visible">True</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xscale">1</property>
+	      <property name="yscale">1</property>
+	      <property name="top_padding">0</property>
+	      <property name="bottom_padding">0</property>
+	      <property name="left_padding">12</property>
+	      <property name="right_padding">0</property>
+
+	      <child>
+		<widget class="GtkVBox" id="vbox3">
+		  <property name="visible">True</property>
+		  <property name="homogeneous">False</property>
+		  <property name="spacing">0</property>
+
+		  <child>
+		    <widget class="GtkProgressBar" id="progressbaroverall">
+		      <property name="visible">True</property>
+		      <property name="orientation">GTK_PROGRESS_LEFT_TO_RIGHT</property>
+		      <property name="fraction">0</property>
+		      <property name="pulse_step">0.10000000149</property>
+		      <property name="text" translatable="yes"> </property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+
+		  <child>
+		    <widget class="GtkLabel" id="labeloverall">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">Initializing...</property>
+		      <property name="use_underline">False</property>
+		      <property name="use_markup">False</property>
+		      <property name="justify">GTK_JUSTIFY_LEFT</property>
+		      <property name="wrap">False</property>
+		      <property name="selectable">False</property>
+		      <property name="xalign">0.5</property>
+		      <property name="yalign">0.5</property>
+		      <property name="xpad">0</property>
+		      <property name="ypad">0</property>
+		      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		      <property name="width_chars">-1</property>
+		      <property name="single_line_mode">False</property>
+		      <property name="angle">0</property>
+		    </widget>
+		    <packing>
+		      <property name="padding">0</property>
+		      <property name="expand">False</property>
+		      <property name="fill">False</property>
+		    </packing>
+		  </child>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label3">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Overall Progress&lt;/b&gt;</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">label_item</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkExpander" id="expander1">
+	  <property name="visible">True</property>
+	  <property name="can_focus">True</property>
+	  <property name="expanded">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkScrolledWindow" id="messageswindow">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
+	      <property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
+	      <property name="shadow_type">GTK_SHADOW_IN</property>
+	      <property name="window_placement">GTK_CORNER_TOP_LEFT</property>
+
+	      <child>
+		<widget class="GtkTextView" id="messages">
+		  <property name="height_request">174</property>
+		  <property name="visible">True</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">False</property>
+		  <property name="overwrite">False</property>
+		  <property name="accepts_tab">True</property>
+		  <property name="justification">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap_mode">GTK_WRAP_NONE</property>
+		  <property name="cursor_visible">False</property>
+		  <property name="pixels_above_lines">0</property>
+		  <property name="pixels_below_lines">0</property>
+		  <property name="pixels_inside_wrap">0</property>
+		  <property name="left_margin">0</property>
+		  <property name="right_margin">0</property>
+		  <property name="indent">0</property>
+		  <property name="text" translatable="yes"></property>
+		</widget>
+	      </child>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkLabel" id="label6">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes">&lt;b&gt;Messages&lt;/b&gt;</property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">True</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="type">label_item</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox1">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkLabel" id="label7">
+	      <property name="visible">True</property>
+	      <property name="label" translatable="yes"></property>
+	      <property name="use_underline">False</property>
+	      <property name="use_markup">False</property>
+	      <property name="justify">GTK_JUSTIFY_LEFT</property>
+	      <property name="wrap">False</property>
+	      <property name="selectable">False</property>
+	      <property name="xalign">0.5</property>
+	      <property name="yalign">0.5</property>
+	      <property name="xpad">0</property>
+	      <property name="ypad">0</property>
+	      <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+	      <property name="width_chars">-1</property>
+	      <property name="single_line_mode">False</property>
+	      <property name="angle">0</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">True</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+
+	  <child>
+	    <placeholder/>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="donebutton">
+	      <property name="visible">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	    </widget>
+	    <packing>
+	      <property name="padding">0</property>
+	      <property name="expand">False</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">True</property>
+	  <property name="fill">True</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
+</glade-interface>
diff --git a/gtkrsync.gladep b/gtkrsync.gladep
new file mode 100644
--- /dev/null
+++ b/gtkrsync.gladep
@@ -0,0 +1,8 @@
+<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
+<!DOCTYPE glade-project SYSTEM "http://glade.gnome.org/glade-project-2.0.dtd">
+
+<glade-project>
+  <name>Gtkrsync</name>
+  <program_name>gtkrsync</program_name>
+  <gnome_support>FALSE</gnome_support>
+</glade-project>
diff --git a/gtkrsync.hs b/gtkrsync.hs
new file mode 100644
--- /dev/null
+++ b/gtkrsync.hs
@@ -0,0 +1,74 @@
+{- Copyright (c) 2007 John Goerzen <jgoerzen@complete.org>
+   Please see the COPYRIGHT file -}
+
+import System.IO
+import Control.Concurrent.MVar
+import RsyncParser
+import RsyncGUI
+import System.Environment
+import System.Process
+import System.Posix.IO
+import System.Posix.Signals
+import System.Posix.Process
+import System.Exit
+
+main = do
+    args <- getArgs
+    rsyncbin <- catch (getEnv "RSYNC") (\_ -> return "rsync")
+
+    (readfd, writefd) <- createPipe
+    pid <- forkProcess (childFunc args rsyncbin readfd writefd)
+    closeFd writefd
+    hasExited <- newMVar False
+
+    readh <- fdToHandle readfd
+    hSetBuffering readh (BlockBuffering Nothing)
+
+    rsyncinput <- hGetContents readh
+    let rsyncstream = customlines rsyncinput
+    exitmv <- newMVar Nothing
+    gui <- initRsyncGUI (exitButton pid hasExited exitmv)
+    installHandler sigCHLD (Catch (chldHandler gui pid hasExited exitmv)) Nothing
+
+    -- Check to see if we died before installing the handler
+    ps <- getProcessStatus False False pid
+    case ps of
+         Nothing -> return ()
+         Just x -> chldPs gui x hasExited exitmv
+
+    runGUI gui rsyncstream exitmv
+
+exitButton pid mv exitmv = withMVar mv $ \hasexited ->
+    if hasexited
+       then exitApp exitmv
+       else do -- Cancel signal handler since we don't want notification to
+               -- user of exit due to user's own action
+               installHandler sigCHLD Default Nothing
+               -- No need to update the MVar here since there won't be
+               -- anything else to read it.  Besides, doing so would cause
+               -- deadlock anyway.
+               signalProcess sigKILL pid
+               exitApp exitmv
+
+childFunc args rsyncbin readfd writefd =
+    do closeFd readfd
+       dupTo writefd stdOutput
+       dupTo writefd stdError
+       closeFd writefd
+       executeFile rsyncbin True args Nothing
+
+chldHandler gui pid mv exitmv = 
+    do ps <- getProcessStatus True False pid
+       case ps of
+            Just ps -> chldPs gui ps mv exitmv
+            Nothing -> return ()
+
+chldPs gui ps mv exitmv =
+    do installHandler sigCHLD Default Nothing
+       swapMVar mv True
+       case ps of
+         Exited ExitSuccess -> return ()
+         Exited x -> do oobError gui ("rsync exited with unexpected error: " ++ show x)
+                        swapMVar exitmv (Just x) >> return ()
+         x -> do oobError gui ("rsync exited with unexpected condition: " ++ show x)
+                 swapMVar exitmv (Just (ExitFailure 255)) >> return ()
diff --git a/gtkrsyncp.hs b/gtkrsyncp.hs
new file mode 100644
--- /dev/null
+++ b/gtkrsyncp.hs
@@ -0,0 +1,17 @@
+{- Copyright (c) 2007 John Goerzen <jgoerzen@complete.org>
+   Please see the COPYRIGHT file -}
+
+import System.IO
+import Control.Concurrent.MVar
+import RsyncParser
+import RsyncGUI
+import System.Exit
+
+main = do
+    hSetBuffering stdin (BlockBuffering Nothing)
+    rsyncinput <- getContents
+    let rsyncstream = customlines rsyncinput
+    exitmv <- newMVar Nothing
+    gui <- initRsyncGUI (exitApp exitmv)
+    runGUI gui rsyncstream exitmv
+
diff --git a/screenshot1.png b/screenshot1.png
new file mode 100644
Binary files /dev/null and b/screenshot1.png differ
diff --git a/screenshot2.png b/screenshot2.png
new file mode 100644
Binary files /dev/null and b/screenshot2.png differ
