[Pkg-uml-commit] r1 - / uml-utilities-20060110 uml-utilities-20060110/uml-utilities uml-utilities-20060110/uml-utilities/branches uml-utilities-20060110/uml-utilities/branches/upstream uml-utilities-20060110/uml-utilities/branches/upstream/current uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/gdb uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify uml-utilities-20060110/uml-utilities/branches/upstream/current/jail uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/moo uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS

Stefano Melchior stex-guest at costa.debian.org
Thu Jan 12 14:19:41 UTC 2006


Author: stex-guest
Date: 2006-01-12 14:18:51 +0000 (Thu, 12 Jan 2006)
New Revision: 1

Added:
   uml-utilities-20060110/
   uml-utilities-20060110/uml-utilities/
   uml-utilities-20060110/uml-utilities/branches/
   uml-utilities-20060110/uml-utilities/branches/upstream/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/COPYING
   uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdb/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdb/gdbinit
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/gdbbot.pl
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/honeypot.pl
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfs.pm
   uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfslib.pm
   uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/humfsify
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/cell.tar
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/db_out.pm
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jail_uml.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jailer.pl
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/playlog.pl
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pl
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pm
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_out.pm
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/jailtest.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/.cvsignore
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/notify.pl
   uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/uml_mconsole.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/.cvsignore
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow_sys.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_mkcow.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_moo.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/port-helper.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/tunctl.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/.cvsignore
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/ethertap.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/slip.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/tuntap.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/uml_net.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/.cvsignore
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/core
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/switch.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.h
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/uml_switch.c
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec
   uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec.in
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/umlgdb
   uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/
   uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Entries
   uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Repository
   uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Root
   uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/Makefile
   uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/uml_watchdog.c
   uml-utilities-20060110/uml-utilities/tags/
Log:
[svn-inject] Installing original source of uml-utilities

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/COPYING
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/COPYING	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/COPYING	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,340 @@
+		    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) 19yy  <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) 19yy 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.

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,21 @@
+/COPYING/1.1/Tue Oct  9 02:22:36 2001//
+D/gdbbot////
+D/mconsole////
+D/moo////
+D/net////
+D/redhat////
+D/rpm////
+D/test////
+D/transformiix////
+D/uml_net////
+D/uml_router////
+D/umn////
+D/port-helper////
+D/jailtest////
+D/tunctl////
+D/umlgdb////
+D/watchdog////
+D/jail////
+D/honeypot////
+/Makefile/1.13/Sat Feb  8 04:01:52 2003//
+/uml_util.spec.in/1.4/Wed Jan 14 09:56:31 2004//

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,24 @@
+TUNCTL = $(shell [ -e /usr/include/linux/if_tun.h ] && echo tunctl)
+
+SUBDIRS = jail jailtest humfsify mconsole moo port-helper $(TUNCTL) uml_net \
+	uml_router watchdog
+UMLVER = $(shell date +%Y%m%d)
+TARBALL = uml_utilities_$(UMLVER).tar
+BIN_DIR = /usr/bin
+LIB_DIR = /usr/lib/uml
+
+export BIN_DIR LIB_DIR
+
+all install: 
+	set -e ; for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@; done
+
+tarball : clean spec
+	cd .. ; tar cf $(TARBALL) tools ; bzip2 -f $(TARBALL)
+
+clean:
+	rm -rf *~
+	rm -f uml_util.spec
+	set -e ; for dir in $(SUBDIRS); do $(MAKE) -C $$dir $@; done
+
+spec:	
+	sed -e 's/__UMLVER__/$(UMLVER)/' < uml_util.spec.in > uml_util.spec

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/gdb/gdbinit
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/gdb/gdbinit	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/gdb/gdbinit	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,61 @@
+#Give this a task like
+#uml-task-info current_task
+#it will dump info about it
+define uml-task-info
+set $tstate = "Unknown"
+if $arg0->state == 0
+ set $tstate = "R"
+end
+if $arg0->state == 1
+ set $tstate = "S"
+end
+if $arg0->state == 2
+ set $tstate = "D"
+end
+if $arg0->state == 4
+ set $tstate = "Z"
+end
+if $arg0->state == 8
+ set $tstate = "T"
+end
+printf "PID(ext): %d(%d)\tState: %s UID(E): %d(%d) \tCmd: %10s @ 0x%x\n", $arg0->pid, $arg0->thread.extern_pid, $tstate, \
+ $arg0->uid, $arg0->euid, $arg0->comm, $arg0
+end
+
+#dump out the info for the files the task has open
+define uml-task-files
+set $files = $arg0->files
+set $max = $files->max_fds
+set $i = 0
+if $max > 32
+ set $max = 32
+end
+while $i < $max
+ if $files->fd_array[$i] != 0
+  printf "     File fd = %d Name: %s\n", $i, $files->fd_array[$i]->f_dentry.d_iname
+ end
+ set $i = $i + 1
+end
+end
+
+#walk though the task list and print info about them
+define uml-tasks
+set $current_task = (struct task_struct *)cpu_tasks[0].task
+uml-task-info $current_task
+set $p = $current_task.next_task
+while $p != $current_task
+ uml-task-info $p
+ if $uml_task > 1
+  uml-task-files $p
+ end
+ set $p = $p->next_task
+end
+end
+
+
+#Vars depend on how much info we dump
+#$uml_task = (*  ) always dump some info
+#$uml_task = (> 0) dump open files
+set $uml_task = 0
+
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,2 @@
+/gdbbot.pl/1.3/Thu Jul  5 19:18:58 2001//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/gdbbot

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/gdbbot.pl
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/gdbbot.pl	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/gdbbot/gdbbot.pl	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,107 @@
+use IO::Pty;
+use IPC::Open2;
+use Net::IRC;
+use POSIX;
+use Fcntl;
+use strict;
+
+my $irc = new Net::IRC;
+my $pty = new IO::Pty;
+my $pid;
+my $key;
+my %trust = ();
+
+my $conn = $irc->newconn(Server   => 'irc.openprojects.net',
+			 Port     => 6667,
+			 Nick     => 'gdbbot',
+			 Ircname  => 'Vlad the Debugger',
+			 Username => 'gdb')
+    or die "gdbbot: Can't connect to IRC server.\n";
+
+sub start_gdb {
+    my $cmd = shift;
+    $pid = fork();
+
+    !defined($pid) and die "Couldn't fork : $!";
+    if($pid == 0){
+        POSIX::setsid() || warn "Couldn't perform setsid $!\n";
+	my $tty = $pty->slave();
+        my $name = $tty->ttyname();
+#	close($pty);
+	close STDIN; close STDOUT; close STDERR;
+	open(STDIN,"<&". $tty->fileno()) || 
+	    die "Couldn't reopen ". $name ." for reading, $!";
+	open(STDOUT,">&". $tty->fileno()) || 
+	    die "Couldn't reopen ". $name ." for writing, $!";
+	open(STDERR,">&". fileno(STDOUT)) || 
+	    die "Couldn't redirect STDERR, $!";
+	exec ($cmd);
+	die "Couldn't exec : $!";  
+    }
+    else {
+	fcntl($pty, Fcntl::F_SETFL, Fcntl::O_NONBLOCK);
+	print "gdb pid is $pid\n";
+	return $pty;
+    }
+}
+
+sub on_connect {
+    my $self = shift;
+
+    print "Joining \#umldebug...\n";
+    $self->join("#umldebug");
+
+    $key = rand(1<<31);
+    print "Your secret is $key\n";
+    my $cmd = "gdb linux";
+    my $pty = start_gdb($cmd);
+    $irc->addfh($pty->fileno(), \&gdb_output, "rw");
+}
+
+sub on_public {
+    my ($self, $event) = @_;
+    my @to = $event->to;
+    my ($nick, $mynick) = ($event->nick, $self->nick);
+    my ($arg) = ($event->args);
+
+    $arg !~ /^gdbbot/ and return;
+    $arg =~ s/^gdbbot:\s*//;
+    if($arg =~ /\^C/){
+	kill 2, $pid;
+    }
+    elsif(defined($key) && ($arg eq $key)){
+	$self->me("#umldebug", "trusts $nick");
+	$trust{$nick} = 1;
+	$key = undef;
+    }
+    elsif($trust{$nick} == 1){
+	if($arg =~ /trust (.*)/){
+	    $trust{$1} = 1;
+	    $self->me("#umldebug", "trusts $1");
+	}
+	else {
+	    print $pty "$arg\n";
+	}
+    }
+    else {
+	$self->me("#umldebug", "doesn't trust $nick");
+    }
+}
+
+sub gdb_output {
+    while(<$pty>){
+	$conn->privmsg("#umldebug", "$_");
+    }
+}
+
+sub on_msg {
+    my ($self, $event) = @_;
+    my $nick = $event->nick;
+    $self->privmsg($nick, "Sorry, I don't understand messages yet.");
+}
+
+$conn->add_global_handler(376, \&on_connect);
+$conn->add_handler('msg',    \&on_msg);
+$conn->add_handler('public', \&on_public);
+
+$irc->start;

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/honeypot/CVS

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,4 @@
+D/CVS////
+/hppfs.pm/1.3/Wed Jan 22 20:40:26 2003//
+/honeypot.pl/1.6/Thu Jul 31 18:10:52 2003//
+/hppfslib.pm/1.4/Thu Jul 31 18:12:39 2003//

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/honeypot

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/honeypot.pl
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/honeypot.pl	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/honeypot.pl	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,38 @@
+# 
+# Copyright (C) 2002, 2003 Jeff Dike (jdike at karaya.com)
+# Licensed under the GPL
+#
+
+use hppfs;
+use hppfslib;
+use strict;
+
+my $dir;
+
+ at ARGV and $dir = $ARGV[0];
+
+my $hppfs = hppfs->new($dir);
+
+my $remove_filesystems = remove_lines("hppfs", "hostfs");
+
+# Need to be able to add directories, i.e. driver, bus/pci
+# partitions needs work
+# slabinfo if UML ever uses the slab cache for anything
+
+$hppfs->add("cmdline" => proc("cmdline"),
+	    "cpuinfo" => proc("cpuinfo"),
+	    "dma" => proc("dma"),
+	    "devices" => remove_lines("ubd"),
+	    "exitcode" => "remove",
+	    "filesystems" => $remove_filesystems,
+	    "interrupts" => proc("interrupts"),
+	    "iomem" => proc("iomem"),
+	    "ioports" => proc("ioports"),
+	    "mounts" => $remove_filesystems,
+	    "pid/mounts" => $remove_filesystems,
+	    "stat" => proc("stat"),
+	    "uptime" => proc("uptime"),
+	    "version" => proc("version"),
+	    dup_proc_dir("bus", $dir) );
+
+$hppfs->handler();

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfs.pm
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfs.pm	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfs.pm	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,131 @@
+# 
+# Copyright (C) 2002 Jeff Dike (jdike at karaya.com)
+# Licensed under the GPL
+#
+
+package hppfs;
+
+use Socket;
+use IO::Select;
+
+use strict;
+
+sub new {
+    my $class = shift;
+    my $base = shift;
+
+    !defined($base) and $base = ".";
+    my $me = { files => { }, handles => { }, base => $base };
+
+    bless($me, $class);
+    return($me);
+}
+
+sub add {
+    my $me = shift;
+
+    while(@_){
+	my $file = shift;
+	my $handler = shift;
+
+	$me->{files}->{$file} = $handler;
+    }
+}
+
+sub prepare {
+    my $me = shift;
+    my $dir = shift;
+    my $file = shift;
+
+    my $full = $me->{base} . "/proc/$dir";
+    if(! -d $full){
+	unlink $full;
+	my $out = `mkdir -p $full 2>&1`;
+	$? and die "mkdir '$full' failed : $out";
+    }
+
+    my $out = `chmod 755 $full 2>&1`;
+    $? and die "chmod 755 $full failed : $out";
+
+    defined($file) and unlink "$full/$file";
+    return("$full/$file");
+}
+
+sub setup_sock {
+    my ($me, $file, undef, $mode) = @_;
+
+    my $full = $me->prepare($file, $mode);
+
+    my $sock = sockaddr_un($full);
+    !defined($sock) and die "sockaddr_un of '$sock' failed : $!";
+
+    !defined(socket(my $fh, AF_UNIX, SOCK_STREAM, 0)) and 
+	die "socket failed : $!";
+
+    !defined(bind($fh, $sock)) and die "bind failed : $!";
+    my $out = `chmod 777 $full 2>&1`;
+    $? ne 0 and die "'chmod 777 $full' failed : $!";
+
+    !defined(listen($fh, 5)) and die "listen failed : $!";
+
+    $me->{select}->add(\*$fh);
+    $me->{handles}->{fileno(\*$fh)} = $file;
+}
+
+sub setup_remove {
+    my ($me, $file) = @_;
+
+    my $full = $me->prepare($file);
+
+    my $out = `touch $full/remove 2>&1`;
+    $? != 0 and die "touch $full/remove failed : $out";
+}
+
+sub handler {
+    my $me = shift;
+    $me->{select} = IO::Select->new();
+
+    foreach my $file (keys(%{$me->{files}})){
+	my $handler = $me->{files}->{$file};
+	if(ref($handler) eq "ARRAY"){
+	    $me->setup_sock($file, @$handler);
+	}
+	elsif($handler eq "remove"){
+	    $me->setup_remove($file);
+	}
+	else {
+	    die "Bad handler for '$file'";
+	}
+    }
+
+    while(1){
+	my @ready = $me->{select}->can_read();
+	
+	foreach my $sock (@ready){
+	    my $file = $me->{handles}->{fileno($sock)};
+	    !defined($file) and die "Couldn't map from socket to file";
+
+	    !accept(CONN, $sock) and die "accept failed : $!";
+
+	    my ($handler, $mode) = @{$me->{files}->{$file}};
+
+	    (!defined($handler) || !defined($mode)) and 
+		die "Couldn't map from file to handler";
+
+	    my $output;
+
+	    if($mode eq "rw"){
+		my $input = join("", <CONN>);
+		$output = $handler->($input);
+	    }
+	    else {
+		$output = $handler->();
+	    }
+
+	    print CONN $output;
+	    close CONN;
+	}
+    }
+}
+
+1;

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfslib.pm
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfslib.pm	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/honeypot/hppfslib.pm	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,64 @@
+# 
+# Copyright (C) 2002, 2003 Jeff Dike (jdike at karaya.com)
+# Licensed under the GPL
+#
+
+package hppfslib;
+
+use Exporter   ();
+use vars       qw(@ISA @EXPORT);
+
+use strict;
+
+ at ISA         = qw(Exporter);
+ at EXPORT      = qw(&remove_lines &host &proc &dup_proc_dir);
+
+sub remove_lines {
+    my @remove = @_;
+
+    return( [ sub { my $input = shift;
+
+		    foreach my $str (@remove){
+			$input =~ s/^.*$str.*\n//mg;
+		    }
+		    return($input) }, 
+	      "rw" ] );
+}
+
+sub host {
+    my $file = shift;
+
+    return( [ sub { return(`cat $file`); },
+	      "r" ] );
+}
+
+sub proc {
+    my $file = shift;
+
+    return(host("/proc/$file"));
+}
+
+sub dup_proc_dir {
+    my $to = shift;
+    my $root = shift;
+    my $new = "$root/$to";
+    
+    -e $new and `rm -rf $new`;
+    !mkdir $new and warn "Couldn't create '$new' : $!";
+
+    my @dirs = `cd /proc/$to ; find . -type d -print`;
+    chomp @dirs;
+    foreach my $dir (@dirs){
+	$dir eq "." and next;
+
+	my $new_dir = "$new/$dir";
+	!mkdir $new_dir and warn "Couldn't create '$new_dir' : $!";
+    }
+
+    my @files = `cd /proc ; find $to -type f -print`;
+    chomp @files;
+
+    return(map { $_ => proc($_) } @files);
+}
+
+1;

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,4 @@
+all install:
+
+clean:
+	rm -f *~

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/humfsify
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/humfsify	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/humfsify	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,57 @@
+user=$1 ;
+group=$2 ;
+size=$3 ;
+
+if [ -z "$user" -o -z "$group" -o -z "$size"]
+then
+    echo Usage : humfsify user group size;
+    exit 1 ;
+fi
+
+case $size in
+    [0-9]*K) $size=$[ `echo $size | sed s/K$//` * 1024 ] ;;
+    [0-9]*M) $size=$[ `echo $size | sed s/M$//` * 1024 * 1024 ] ;;
+    [0-9]*G) $size=$[ `echo $size | sed s/G$//` * 1024 * 1024 * 1024] ;;
+    [0-9]*) ;;
+    *) echo "Bad filesystem size - '$size'";
+       exit 1 ;;
+esac
+
+used=$[ `du -sk data | awk '{print $1}'` * 1024 ];
+
+if [ $used -gt $size ]
+then
+    echo "Current disk usage greater than the requested size - $used vs $size" ;
+    exit 1
+fi
+
+for f in `cd data ; find .` ; do
+    full=data/$f;
+
+    uid=`cd data ; ls -ld $f | awk '{print $3}'` ;
+    [ `echo $uid | sed 's/^[0-9]*$//'` ] && uid=`id -u $uid` ;
+
+    gid=`cd data ; ls -ld $f | awk '{print $4}'` ;
+    [ `echo $gid | sed 's/^[0-9]*$//'` ] &&
+        gid=`awk -F: "{ if(\\$1==\"$gid\") print \\$3 }" /etc/group | head -1` ;
+    
+    meta=metadata/$f ;
+    if [ -d $full ]
+    then
+	mkdir -p $meta ;
+	chown $user.$group $meta ;
+	meta=$meta/metadata ;
+    else
+	mkdir -p metadata/`dirname $f` ;
+	chown $user.$group metadata/`dirname $f` ;
+    fi
+    chown $user.$group $full ;
+    echo $uid $gid >> $meta ;
+    chown $user.$group $meta ;
+done
+
+cat >> superblock <<EOF
+version 1
+used $used
+total $size
+EOF


Property changes on: uml-utilities-20060110/uml-utilities/branches/upstream/current/humfsify/humfsify
___________________________________________________________________
Name: svn:executable
   + 

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,10 @@
+/cell.tar/1.1/Fri Jun 14 01:08:18 2002//
+/jail_uml.c/1.2/Mon Jul 22 17:37:43 2002//
+/Makefile/1.3/Wed Jan 22 18:23:54 2003//
+/tty_log.pl/1.2/Wed Jan 29 18:14:40 2003//
+/tty_log.pm/1.3/Thu Jun 12 17:10:50 2003//
+/db_out.pm/1.1/Wed Nov 19 10:46:34 2003//
+/playlog.pl/1.4/Wed Nov 19 10:47:41 2003//
+/tty_out.pm/1.1/Wed Nov 19 10:46:28 2003//
+/jailer.pl/1.7/Thu Sep 25 20:43:37 2003//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/jail

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,9 @@
+all : jail_uml
+
+jail_uml : jail_uml.c
+
+# Don't install anything as yet
+install :
+
+clean :
+	rm -rf *~ jail_uml cell[0-9]* core* tty_log_cell*

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/cell.tar
===================================================================
(Binary files differ)


Property changes on: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/cell.tar
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/db_out.pm
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/db_out.pm	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/db_out.pm	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,147 @@
+# 
+# Copyright (C) 2003 George Bakos, ISTS at Dartmouth College and 
+# 	Jeff Dike (jdike at addtoit.com)
+# Licensed under the GPL
+#
+
+package db_out;
+
+use strict;
+
+INIT {
+    my %options = ( dbh => undef,
+		    table => undef );
+
+    main::register_output("sql", 
+			  sub { my $options = shift; 
+				check_option($options, \%options); },
+			  sub { my $record = shift;
+				output($record, \%options); },
+			  0,
+"    -d enables logging to a database.   You will need to pass
+additional parameters so that playlog knows how to connect to the database.
+The syntax is name=value,name=value,name=value, etc. Examples:
+
+perl playlog.pl -d host=loghost.my.org,db=uml,user=gbakos,pass=foobar,table=cell0_log tty_log_cell0
+perl playlog.pl -f -d db=uml tty_log_cell0
+
+The only mandatory parameter is:
+	db - database name
+        
+The following default values will be used if not otherwise specified:
+
+parameter  default value     description
+---------- ----------------- ---------------------------------------------
+host       localhost         Hostname or IP address of database server
+port       3306              TCP port of the database server
+user       current user name Database account name
+passwd     '' (null)         Password for authenticating with the database
+table      ttylog            Name of the database table to create and/or append
+
+NOTE: Database must already exist and the user must have appropriate rights.
+      See http://www.mysql.com/doc for additional information.
+");
+}
+
+sub check_option {
+    my $options = shift;
+    my $arg = shift;
+    my $option = shift @$options;
+    my $ret = 1;
+
+    if($option eq "-d"){
+	my $db_args = shift @$options;
+	($arg->{dbh}, $arg->{table}) = db_intercon_connect($db_args);
+	db_intercon_create($arg->{dbh}, $arg->{table});
+    }
+    else {
+	unshift @$options, $option;
+	$ret = 0;
+    }
+
+    return($ret);
+}
+
+sub output {
+    my $record = shift;
+    my $arg = shift;
+
+    db_intercon_append($record, $arg->{dbh}, $arg->{table});
+}
+
+my $dbhost = "localhost";
+my $dbport = 3306;
+my $dbuser = (getpwuid $>)[0];
+my $dbpasswd = "";
+my $dbtable = "ttylog";
+
+sub db_intercon_connect {
+    my $args = shift;
+    my @db = split(",", $args);
+    my %dbparams = ();
+
+    print STDERR "Connecting to MySqld with params: @db:\t";
+
+    map { my ($key,$val) = split("=", $_) or Usage();
+	  $dbparams{$key} = $val; } @db;
+
+    !$dbparams{host} and $dbparams{host} = $dbhost;
+    !$dbparams{port} and $dbparams{port} = $dbport;
+    !$dbparams{user} and $dbparams{user} = $dbuser;
+    !$dbparams{passwd} and $dbparams{passwd} = $dbpasswd;
+    !$dbparams{table} and $dbparams{table} = $dbtable;
+
+    require DBD::mysql;
+    my $connect = "DBI:mysql:$dbparams{db}:$dbparams{host}:$dbparams{port}";
+    my $dbh = DBI->connect($connect, $dbparams{user}, $dbparams{pass})
+        or die "\nFatal: can't connect to database $!\n";
+    print STDERR "success\n";
+
+    return($dbh, $dbparams{table});
+}
+
+sub db_intercon_create {
+    my $dbh = shift;
+    my $table = shift;
+
+    $dbh->do("
+        CREATE TABLE IF NOT EXISTS $table
+        (
+            string BLOB null, 
+            timeusecs BIGINT UNSIGNED not null, 
+            old_tty INT UNSIGNED null, 
+            tty INT UNSIGNED null, 
+            op TINYTEXT not null, 
+            direction TINYTEXT null
+        )
+    ")
+     or die "\nFatal: can't access/create table $!\n";
+}
+
+sub db_intercon_append {
+    my $op = shift;
+    my $dbh = shift;
+    my $table = shift;
+
+# Uncomment the following to send logging to STDERR as well as the database
+
+#    foreach my $key(sort keys %$op){ 
+#        print STDERR "$key=$$op{$key},";
+#    }
+#    print STDERR "\n";
+
+    my $string = $dbh->quote("$op->{string}");
+    my $secs = $op->{secs};
+    my $usecs = $op->{usecs};
+    my $old_tty = $dbh->quote("$op->{old_tty}");
+    my $tty = $dbh->quote("$op->{tty}");
+    my $direction = $dbh->quote("$op->{direction}");
+    my $op = $dbh->quote("$op->{op}");
+    my $timeusecs = (($secs * 1000000) + $usecs);
+
+    $dbh->do("INSERT INTO $table(string, timeusecs, old_tty, tty, " .
+	     "op, direction) 
+            VALUES ($string, $timeusecs, $old_tty, $tty, $op, $direction)");
+}
+
+1;

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jail_uml.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jail_uml.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jail_uml.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,48 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+static void Usage(void)
+{
+  fprintf(stderr, "Usage : jail_uml jail-directory uid "
+	  "uml-command-line ...\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  char *dir, *end;
+  int uid;
+
+  if(geteuid() != 0){
+    fprintf(stderr, "jail_uml must be run as root\n");
+    exit(1);
+  }
+
+  if(argc < 3) Usage();
+  dir = argv[1];
+  uid = strtoul(argv[2], &end, 0);
+  if(*end != '\0') Usage();
+  argc -= 3;
+  argv += 3;
+
+  if(chdir(dir)){
+    perror("chdir");
+    exit(1);
+  }
+
+  if(chroot(".")){
+    perror("chroot");
+    exit(1);
+  }
+
+  if(setuid(uid)){
+    perror("setuid");
+    exit(1);
+  }
+
+  execv(argv[0], argv);
+  fprintf(stderr, "execve of %s failed : ", argv[0]);
+  perror("");
+  exit(1);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jailer.pl
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jailer.pl	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/jailer.pl	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,301 @@
+#!/usr/bin/perl
+
+use strict;
+use English;
+
+# Make sure things like ifconfig and route are accessible
+$ENV{PATH} .= ":/sbin:/usr/sbin";
+
+sub Usage {
+    print "Usage : jailer.pl uml-binary root-filesystem uid [ -n ] " .
+	"[ -v ]\n";
+    print "\t[ -net 0.0.0.0 uml-ip -bridge device,device,... ]\n";
+    print "\t[ -net host-ip uml-ip] [ -tty-log ] [ -r cell ] [ -p ]\n";
+    print "[ more uml arguments ... ]\n";
+    print "Required arguments:\n";
+    print "\tuml-binary is the path of the UML 'linux' executable\n\n";
+    print "\troot-filesystem is the path of the filesystem that it will " .
+	"boot on.\n";
+    print "\tThis will be copied into the jail, and the copy will be "
+	. "booted\n\n";
+    print "\tuid is the user id that the UML will run as - an otherwise " .
+	"unused uid\n";
+    print "\tis a good idea\n\n";
+    print "Optional arguments:\n";
+    print "\t-n prints its commands without executing them\n\n";
+    print "\t-v prints its commands as well as executing them\n\n";
+    print "\t-net configures a network - with a non-bridged configuration, " .
+	"IP\n";
+    print "\taddresses for both ends of the TAP device are required.  With \n";
+    print "\t-bridge, the new TAP device will be bridged with the devices\n";
+    print "\tspecified.  The host-ip address will assigned to the bridge.\n";
+    print "\t-tty-log enables logging of tty traffic and process execs\n\n";
+    print "\t-r specifies a cell to reuse\n";
+    print "\t-p the cell will be persistent (not be removed after the UML\n";
+    print "\texits)\n";
+    print "Any further arguments will simply be appended to the UML command " .
+	"line\n";
+	
+    exit 1;
+}
+
+my ($uml, $rootfs, $uid, @uml_args) = @ARGV;
+my ($tap, $host_ip, $uml_ip);
+my @net_cmds = ();
+my $tty_log = 0;
+my $verbose = 0;
+my @bridge_devices = ();
+my $dry_run = 0;
+my $persistent = 0;
+my $reuse;
+
+while(1){
+    if($uml_args[0] eq "-net"){
+	(undef, $host_ip, $uml_ip, @uml_args) = @uml_args;
+	(!defined($host_ip) || !defined($uml_ip)) and Usage();
+	push @net_cmds, ( "tunctl", "ifconfig", "route" );
+    }
+    elsif($uml_args[0] eq "-bridge"){
+	shift @uml_args;
+	push @bridge_devices, split(",", shift @uml_args);
+	push @net_cmds, "brctl";
+    }
+    elsif($uml_args[0] eq "-tty-log"){
+	shift @uml_args;
+	$tty_log = 1;
+    }
+    elsif($uml_args[0] eq "-v"){
+        shift @uml_args;
+        $verbose = 1;
+    }
+    elsif($uml_args[0] eq "-n"){
+        shift @uml_args;
+        $dry_run = 1;
+    }
+    elsif($uml_args[0] eq "-r"){
+	(undef, $reuse, @uml_args) = @uml_args;
+	! -d $reuse and die "'$reuse' is not a directory";
+    }
+    elsif($uml_args[0] eq "-p"){
+	shift @uml_args;
+	$persistent = 1;
+    }
+    else {
+	last;
+    }
+}
+
+(!defined($uml) || !defined($rootfs) || !defined($uid)) and Usage();
+
+my $status = run_output_status("ldd $uml");
+$status == 0 and die "The UML binary should be statically linked - enable " .
+    "CONFIG_STATIC_LINK in the UML build";
+
+if(@bridge_devices && !defined($uml_ip)){
+    print "-bridge requires -net\n";
+    Usage();
+}
+
+my @cmds = ("tar", "cp", "basename", "rm", @net_cmds );
+
+!defined($reuse) and push @cmds, "mkdir";
+
+my $sudo = "";
+if($UID != 0){
+    $sudo = "sudo";
+    push @cmds, $sudo;
+}
+
+my @dont_have = ();
+
+foreach my $cmd (@cmds){
+    `which $cmd 2>&1 > /dev/null`;
+    $? != 0 and push @dont_have, $cmd;
+}
+
+if(@dont_have){
+    print "Can't find the following utilities: " . 
+	join(" ", @dont_have) . "\n";
+    exit 1;
+}
+
+my $out;
+my @more_args = ();
+
+sub run_output_status {
+    my $cmd = shift;
+
+    $verbose || $dry_run and print "$cmd\n";
+    $dry_run and return("", 0);
+
+    my $out = `$cmd 2>&1`;
+    my $status = $?;
+    $verbose and print "$out\n";
+    return($out, $status);
+}
+
+sub run_output {
+    my $cmd = shift;
+    my ($output, $status) = run_output_status($cmd);
+
+    $status ne 0 and die "Running '$cmd' failed : output = '$out'";
+    return($output);
+}
+
+sub run_status {
+    my $cmd = shift;
+    my (undef, $status) = run_output_status($cmd);
+
+    return($status);
+}
+
+sub run {
+    my $cmd = shift;
+    my ($output, $status) = run_output_status($cmd);
+
+    $status ne 0 and die "Running '$cmd' failed : output = '$output'";
+}
+
+if(defined($uml_ip)){
+    $out = run_output("tunctl -u $uid");
+    if($out =~ /(tap\d+)/){
+	$tap = $1;
+	push @more_args, "eth0=tuntap,$tap";
+
+	my $tap_ifconfig = "$sudo ifconfig $tap up";
+	!@bridge_devices and $tap_ifconfig .= " $host_ip";
+
+	run($tap_ifconfig);
+
+	if(@bridge_devices){
+	    my @non_existant = map { run_status("ifconfig $_") ? $_ : ()
+				     } @bridge_devices;
+	    my @bridges = map { run_status("sudo brctl showstp $_") ? () : $_ 
+				} @bridge_devices;
+
+	    @non_existant + @bridges != 1 and 
+		die "-bridge must specify one already-existing bridge or " .
+		    "non-existant device";
+
+	    my $create = @non_existant;
+	    my $bridge = shift @{ [@non_existant, @bridges] };
+
+	    if($create){
+		run("sudo brctl addbr $bridge");
+		run("sudo brctl stp $bridge off");
+	    }
+
+	    map { if($_ ne $bridge){
+		      run("sudo brctl addif $bridge $_");
+		      run("sudo ifconfig $_ 0.0.0.0 promisc up");
+		  }
+	      } (@bridge_devices, $tap);
+
+	    run("sudo ifconfig $bridge $host_ip");
+	}
+	else {
+	    defined($host_ip) and run("$sudo route add -host $uml_ip dev $tap");
+	    run("$sudo bash -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'");
+	}
+    }
+    else {
+	die "Couldn't find tap device name in '$out'";
+    }
+}
+
+if($tty_log == 1){
+    push @more_args, "tty_log_fd=3"
+}
+
+push @more_args, "uml_dir=/tmp";
+
+my $cell;
+
+if(!defined($reuse)){
+    my $n = 0;
+
+    while(-e "cell$n"){
+	$n++;
+    }
+    $cell = "cell$n";
+}
+else {
+    $cell = $reuse;
+}
+
+print "New inmate assigned to '$cell'\n";
+print "	UML image : $uml\n";
+print "	Root filesystem : $rootfs\n";
+if(defined($tap)){
+    if(defined($host_ip)){
+	print "	Network : routing through $tap, host = $host_ip, " . 
+	    "uml = $uml_ip\n";
+    }
+    else {
+	print "	Network : bridging $tap, uml = $uml_ip\n";
+    }
+}
+else {
+    print "	No network configured\n";
+}
+if($tty_log == 1){
+    print "	TTY logging to tty_log_$cell\n";
+    push @more_args, "3>tty_log_$cell";
+}
+print "	Extra arguments : '" . join(" ", @uml_args) . "'\n";
+print "\n";
+
+if(!defined($reuse)){
+    run("mkdir $cell");
+    run("chmod 755 $cell");
+
+    my $cell_tar = "cell.tar";
+    run("cd $cell ; $sudo tar xpf ../$cell_tar");
+
+    run("$sudo chown $uid $cell/tmp");
+    run("$sudo chmod 777 $cell/tmp");
+
+    print "Copying '$uml' and '$rootfs' to '$cell'...";
+    run("cp $uml $rootfs $cell");
+    print "done\n\n";
+
+    if(-e "/proc/mm"){
+	run("mkdir $cell/proc");
+	run("chmod 755 $cell/proc");
+	run("touch $cell/proc/mm");
+	run("$sudo mount --bind /proc/mm $cell/proc/mm");
+    }
+}
+
+$uml = `basename $uml`;
+chomp $uml;
+
+$rootfs = `basename $rootfs`;
+chomp $rootfs;
+
+run("$sudo chmod 666 $cell/$rootfs");
+run("$sudo chmod 755 $cell/$uml");
+
+my @args = ( "bash", "-c", "./jail_uml $cell $uid /$uml ubd0=/$rootfs " . 
+	     join(" ", @uml_args, @more_args) );
+
+$sudo ne "" and unshift @args, $sudo;
+
+if(!$dry_run){
+    system @args;
+}
+else {
+    print join(" ", @args) . "\n";
+}
+
+if(!$persistent){
+    -e "$cell/proc/mm" and run("$sudo umount $cell/proc/mm");
+    run("$sudo rm -rf $cell");
+}
+
+if(defined($tap)){
+    run("$sudo ifconfig $tap down");
+    run("$sudo tunctl -d $tap");
+}
+
+exit 0;

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/playlog.pl
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/playlog.pl	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/playlog.pl	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,132 @@
+# 
+# Copyright (C) 2003 Jeff Dike (jdike at karaya.com)
+# Licensed under the GPL
+#
+# Translated from playlog.py, by Upi Tamminen
+
+my @option_handlers;
+
+use tty_log;
+use tty_out;
+use db_out;
+use IO::Handle;
+
+use strict;
+
+my $usage_string = 
+"Usage : perl playlog.pl [ options ] log-file [tty-id]
+	-f - follow the log, similar to 'tail -f'
+";
+
+sub Usage {
+    print $usage_string;
+
+    foreach my $handler (@option_handlers){
+	print $handler->{usage};
+    }
+    exit(1);
+}
+
+sub register_output {
+    my $name = shift;
+    my $option_proc = shift;
+    my $output_proc = shift;
+    my $one_tty = shift;
+    my $usage = shift;
+
+    push @option_handlers, { active => 0,
+			     name => $name,
+			     option => $option_proc, 
+			     output => $output_proc,
+			     one_tty => $one_tty,
+			     usage => $usage };
+}
+
+my $follow = 0;
+
+LOOP: while(@ARGV){
+    my $arg = shift @ARGV;
+
+    if($arg eq "-f"){
+	$follow = 1;
+    }
+    else {
+	unshift @ARGV, $arg;
+
+	foreach my $handler (@option_handlers){
+	    if($handler->{option}(\@ARGV)){
+		$handler->{active} = 1;
+		next LOOP;
+	    }
+	}
+
+	last;
+    }
+}
+
+!@ARGV and Usage();
+
+if(!map { $_->{active} ? 1 : () } @option_handlers){
+    my @tty_out = map { $_->{name} eq "tty" ? $_ : () } @option_handlers;
+    !@tty_out and 
+        die "No output handlers active and no tty output handler defined";
+    $tty_out[0]->{active} = 1;
+}
+
+my $file = shift @ARGV;
+
+ at ARGV > 1 and Usage();
+
+my $tty_id;
+ at ARGV and my $tty_id = $ARGV[0];
+
+open FILE, "<$file" or die "Couldn't open $file : $!";
+binmode(FILE);
+
+my @ops = ();
+
+while(1){
+    my $op = read_log_line($file, \*FILE, 0);
+    !defined($op) and last;
+
+    push @ops, $op;
+}
+
+my @ttys = map { $_->{op} eq "open" && (($_->{old_tty} == 0) || 
+					($_->{old_tty} == $_->{tty})) ? 
+					    $_->{tty} : () } @ops;
+
+my %unique_ttys = ();
+foreach my $tty (@ttys){
+    $unique_ttys{$tty} = 1;
+}
+
+ at ttys = keys(%unique_ttys);
+
+my @need_tty = map { $_->{active} && $_->{one_tty} ? $_->{name} : () 
+		     } @option_handlers;
+
+if((@ttys > 1) && !defined($tty_id) && @need_tty){
+    print join(" and ", @need_tty) . " output(s) need a tty id to follow\n";
+    print "You have the following ttys to choose from:\n";
+    print join(" ", @ttys) . "\n";
+    exit(0);
+}
+
+!defined($tty_id) and $tty_id = $ttys[0];
+
+foreach my $op (@ops){
+    foreach my $handler (@option_handlers){
+	if($handler->{active} && 
+	   (!$handler->{one_tty} || ($op->{tty} == $tty_id))){
+	    $handler->{output}->($op);
+	}
+    }
+}
+
+!$follow and exit 0;
+
+while(1){
+    my $op = read_log_line($file, \*FILE, 1);
+
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pl
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pl	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pl	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,38 @@
+# 
+# Copyright (C) 2002, 2003 Jeff Dike (jdike at karaya.com)
+# Licensed under the GPL
+#
+
+use tty_log;
+
+use strict;
+
+!@ARGV and die "Usage : perl tty_log.pl log-file";
+
+my $file = $ARGV[0];
+
+my @ops = read_log($file);
+
+foreach my $op (@ops){
+    if($op->{op} eq "open"){
+	printf("Opening new tty 0x%x from tty 0x%x\n", $op->{tty}, 
+	       $op->{old_tty});
+    }
+    elsif($op->{op} eq "close"){
+	printf("Closing tty 0x%x\n", $op->{tty});
+    }
+    elsif($op->{op} eq "write"){
+	if($op->{direction} eq "read"){
+	    printf("Read from tty 0x%x - '%s'\n", $op->{tty}, $op->{string});
+	}
+	elsif($op->{direction} eq "write"){
+	    printf("Write to tty 0x%x - '%s'\n", $op->{tty}, $op->{string});
+	}
+	else {
+	    die "Bad direction - '$op->{direction}'";
+	}
+    }
+    else {
+	die "Bad op - " . $op->{op};
+    }
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pm
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pm	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_log.pm	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,123 @@
+# 
+# Copyright (C) 2003 Jeff Dike (jdike at karaya.com)
+# Licensed under the GPL
+#
+
+package tty_log;
+
+use File::stat;
+use Time::HiRes qw(usleep);
+
+use Exporter   ();
+use vars       qw(@ISA @EXPORT);
+
+use strict;
+
+
+ at ISA         = qw(Exporter);
+ at EXPORT      = qw(&read_log &read_log_line);
+
+my $TTY_LOG_OPEN = 1;
+my $TTY_LOG_CLOSE = 2;
+my $TTY_LOG_WRITE = 3;
+my $TTY_LOG_EXEC = 4;
+
+my $TTY_READ = 1;
+my $TTY_WRITE = 2;
+
+my %op_names = ($TTY_READ => "read", $TTY_WRITE => "write");
+
+sub read_log_item {
+    my $filename = shift;
+    my $handle = shift;
+    my $len = shift;
+    my $wait = shift;
+    my $offset = 0;
+    my $data;
+
+    while(1){
+	my $size = stat($filename)->size();
+	my $n = sysread($handle, $data, $len, $offset);
+	$n == $len and return($data);
+
+	if(!$wait){
+	    !defined($n) and die "read failed - $!";
+	    $n == 0 and return(undef);
+
+	    die "Short file - expected $len bytes, got $n";
+	}
+
+	$offset += $n;
+
+	while(1){
+	    usleep(100 * 1000);
+	    my $new_size = stat($filename)->size();
+	    $new_size != $size and last;
+	}
+    }
+}
+
+sub read_log_line {
+    my $filename = shift;
+    my $handle = shift;
+    my $wait = shift;
+
+    my $record_len = length(pack("iIiiII", "0" x 6));
+
+    my $record = read_log_item($filename, $handle, $record_len, $wait);
+    !defined($record) and return(undef);
+
+    my ($op, $tty, $len, $direction, $sec, $usecs) = 
+	unpack("iIiiIIa*", $record);
+
+    my $data;
+
+    $len != 0 and $data = read_log_item($filename, $handle, $len, $wait);
+
+    if($op == $TTY_LOG_OPEN){
+	my ($old_tty) = unpack("I", $data);
+	return( { op => "open", tty => $tty, old_tty => $old_tty,
+		  secs => $sec, usecs => $usecs } );
+    }
+    elsif($op == $TTY_LOG_CLOSE){
+	return( { op => "close", tty => $tty, secs => $sec, 
+		  usecs => $usecs } );
+    }
+    elsif($op == $TTY_LOG_WRITE){
+	my $op_name = $op_names{$direction};
+	!defined($op_name) and die "Bad direction - '$direction'";
+
+	return( { op => "write", tty => $tty, string => $data, 
+		  direction => $op_name, secs => $sec, usecs => $usecs } );
+    }
+    elsif($op == $TTY_LOG_EXEC){
+	my @cmd = split("\0", $data);
+	my $string = join(" ", @cmd);
+	return( { op => "exec", tty => $tty, string => $string, secs => $sec, 
+		  usecs => $usecs } );
+    }
+    else {
+	die "Bad tty_log op - $op";
+    }
+}
+
+sub read_log {
+    my $file = shift;
+
+    open FILE, "<$file" or die "Couldn't open $file : $!";
+    binmode(FILE);
+
+    my @ops = ();
+
+    while(1){
+	my $op = read_log_line($file, \*FILE, 0);
+	!defined($op) and last;
+
+	push @ops, $op;
+    }
+
+    close FILE;
+    return(@ops);
+}
+
+1;

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_out.pm
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_out.pm	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jail/tty_out.pm	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,107 @@
+# 
+# Copyright (C) 2003 Jeff Dike (jdike at karaya.com)
+# Licensed under the GPL
+#
+
+package tty_out;
+
+use Time::HiRes qw(usleep);
+
+use strict;
+
+INIT {
+    my %options = ( fast => 0, 
+		    all => 0, 
+		    execs => 0, 
+		    first_record => 1,
+		    last_time => undef );
+
+    main::register_output("tty", 
+			     sub { my $options = shift; 
+				   check_option($options, \%options); },
+			     sub { my $record = shift;
+				   output($record, \%options); },
+			     1,
+"	-n - full-speed playback, without mimicing the original timing
+	-a - all traffic, including both tty reads and writes
+	-e - print out logged execs
+    By default, playlog will retain the original timing in the log.  -n will
+just dump the log out without that timing.  Also by default, only tty writes
+will be output.  This will provide an authentic view of what the original
+user saw, but it will omit non-echoed characters, such as passwords.  
+-a will output ttys reads as well, but this has the side-effect of duplicating
+all normal, echoed, user input.
+    The -e option prints out logged execs.  This option exists because it's
+possible to run commands on a system without anything allocating a terminal.
+In this situation, tty logging is useless because no data flows through a 
+terminal.  However, execs will be logged, and the -e switch will print them
+out, allowing you to see everything that an intruder did without a terminal.
+");			  
+}
+
+sub check_option {
+    my $options = shift;
+    my $arg = shift;
+    my $option = shift @$options;
+    my $ret = 1;
+
+    if($option eq "-n"){
+	$arg->{fast} = 1;
+    }
+    elsif($option eq "-a"){
+	$arg->{all} = 1;
+    }
+    elsif($option eq "-e"){
+	$arg->{execs} = 1;
+    }
+    else {
+	unshift @$options, $option;
+	$ret = 0;
+    }
+
+    return($ret);
+}
+
+sub output {
+    my $record = shift;
+    my $arg = shift;
+
+    if($arg->{first_record}){
+	STDOUT->autoflush(1);
+	$arg->{first_record} = 0;
+    }
+
+    !defined($arg->{last_time}) and 
+	$arg->{last_time} = $record->{secs} * 1000 * 1000 + $record->{usecs};
+
+    my $next = $record->{secs} * 1000 * 1000 + $record->{usecs};
+    !$arg->{fast} and usleep($next - $arg->{last_time});
+
+    print_op($record, $arg, $arg);
+
+    $arg->{last_time} = $next;
+}
+
+sub print_op {
+    my $op = shift;
+    my $arg = shift;
+
+    if(($op->{op} eq "exec") && !$arg->{execs}){
+	return;
+    }
+    elsif($arg->{execs} and ($op->{op} ne "exec")){
+	return;
+    }
+    elsif(($op->{op} eq "open") || ($op->{op} eq "close")){
+	return;
+    }
+    elsif($op->{op} eq "write"){
+	($op->{direction} ne "write") && !$arg->{all} and return;
+    }
+
+    print $op->{string};
+
+    $op->{op} eq "exec" and print "\n";
+}
+
+1;

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/jailtest/CVS

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,3 @@
+D/CVS////
+/jailtest.c/1.1/Fri Jan 25 19:59:48 2002//
+/Makefile/1.2/Sat Feb  8 04:10:27 2003//

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/jailtest

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,17 @@
+OBJS = jailtest.o
+BIN = jailtest
+CFLAGS = -g -Wall
+
+BIN_DIR ?= /usr/bin
+
+all : $(BIN)
+
+$(BIN) : $(OBJS)
+	$(CC) $(CFLAGS) -o $(BIN) $(OBJS)
+
+clean : 
+	rm -f $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -s $(BIN) $(DESTDIR)$(BIN_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/jailtest.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/jailtest.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/jailtest/jailtest.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <signal.h>
+#include <wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#define KERNEL_ADDRESS ((unsigned long *) (0xa0800000))
+
+int main(int argc, char **argv)
+{
+  int pid, status, fd, n;
+
+  printf("Trying to directly write %p...", KERNEL_ADDRESS);
+  fflush(stdout);
+  if((pid = fork()) != 0){
+    if(waitpid(pid, &status, 0) < 0){
+      perror("waitpid");
+      exit(1);
+    }
+    if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGSEGV))
+      printf("No segv (status = 0x%x) - BAD!\n", status);
+    else printf("Segv - GOOD\n");
+  }
+  else {
+    *KERNEL_ADDRESS = 0xdeadbeef;
+    exit(1);
+  }
+
+  printf("Trying to write %p via read...", KERNEL_ADDRESS);
+  if((fd = open("/etc/passwd", O_RDONLY)) < 0){
+    perror("open");
+    exit(1);
+  }
+  n = read(fd, (char *) KERNEL_ADDRESS, sizeof(*KERNEL_ADDRESS));
+  if((n > 0) || (errno != EFAULT))
+    printf("Didn't return EFAULT - BAD!\n");
+  else printf("Returned EFAULT - GOOD\n");
+
+  printf("Trying to open /dev/mem...");
+  fd = open("/dev/mem", O_WRONLY);
+  if((fd >= 0) || (errno != EPERM))
+    printf("Didn't fail with EPERM (fd = %d, errno = %d) - BAD!\n", fd, 
+	   errno);
+  else printf("Failed with EPERM - GOOD\n");
+
+  printf("Trying to open /dev/kmem...");
+  fd = open("/dev/kmem", O_WRONLY);
+  if((fd >= 0) || (errno != EPERM))
+    printf("Didn't fail with EPERM (fd = %d, errno = %d) - BAD!\n", fd, 
+	   errno);
+  else printf("Failed with EPERM - GOOD\n");
+
+  return(0);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/.cvsignore
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/.cvsignore	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/.cvsignore	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+uml_mconsole

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,5 @@
+/.cvsignore/1.1/Fri Jan 11 05:21:31 2002//
+/notify.pl/1.1/Tue Feb  4 20:11:39 2003//
+/Makefile/1.6/Sat Feb  8 04:10:08 2003//
+/uml_mconsole.c/1.14/Fri Aug 29 20:47:14 2003//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/mconsole

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,17 @@
+BIN = uml_mconsole
+OBJS = $(BIN).o
+CFLAGS = -g -Wall
+
+BIN_DIR ?= /usr/bin
+
+all : $(BIN)
+
+$(BIN) : $(OBJS)
+	$(CC) $(CFLAGS) -o $(BIN) $(OBJS) -lreadline -lncurses
+
+clean : 
+	rm -f $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -s $(BIN) $(DESTDIR)$(BIN_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/notify.pl
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/notify.pl	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/notify.pl	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,42 @@
+use Socket;
+use strict;
+
+my $MCONSOLE_SOCKET = 0;
+my $MCONSOLE_PANIC = 1;
+my $MCONSOLE_HANG = 2;
+my $MCONSOLE_USER_NOTIFY = 3;
+
+my @types = ( "socket", "panic", "hang", "user notification" );
+
+!defined(socket(SOCK, AF_UNIX, SOCK_DGRAM, 0)) and 
+    die "socket() failed : $!\n";
+
+# XXX the -u causes mktemp to unlink the file - this is needed because
+# we don't want a normal file, we want a socket.
+
+my $file = `mktemp -u /tmp/mconsole.XXXXXX`;
+$? != 0 and die "mktemp failed with status $?\n";
+chomp $file;
+
+print "The notification socket is '$file'\n";
+
+!defined(bind(SOCK, sockaddr_un($file))) and 
+    die "binding '$file' failed : $!\n";
+
+print "Run UML with\n\tmconsole=notify:$file\non the command line.\n";
+print "Then, inside UML, write messages into /proc/mconsole\n";
+
+while(1){
+    my $data;
+
+    !defined(recv(SOCK, $data, 4096, 0)) and 
+	die "recv from '$file' failed : $!";
+
+    my ($magic, $version, $type, $len, $message) = unpack("LiiiA*", $data);
+    print "Received message -\n";
+    printf "\tmagic = 0x%x\n", $magic;
+    print "\tversion = $version\n";
+    print "\tmessage type = $type (" . $types[$type] . ")\n";
+    print "\tmessage length = $len\n";
+    print "\tmessage = '$message'\n\n";
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/uml_mconsole.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/uml_mconsole.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/mconsole/uml_mconsole.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,460 @@
+/* (c) Copyright 2001-2004 Jeff Dike and others
+ * Licensed under the GPL, see file COPYING
+ *
+ * This is uml_console version 2, a tool for querying a User Mode Linux 
+ * instance over a local pipe connection. This tool needs to be in sync
+ * with the version of the UML kernel.
+ *
+ * There are a very few local commands that this program knows
+ * about, but by default everything gets processed by UML.
+ *
+ * The uml_mconsole documentation distributed with covers all mconsole
+ * commands, so the docs have to be kept in sync with the kernel.
+ * In future it should be possible for the docs to come from (or be
+ * in common with) something over in the kernel source.
+ *
+ * If you are looking for the command implementation, go to the
+ * files mconsole_kern.c in the Linux kernel source under arch/um.
+ * 
+ * The program exits with error values of:
+ *
+ *      0    No error
+ *      1    Error     (need better breakdown of error type in future)
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include <stdint.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/uio.h>
+#include <readline/readline.h>
+#include <readline/history.h>
+
+static char uml_name[11];
+static struct sockaddr_un sun;
+
+static int do_switch(char *file, char *name)
+{
+  struct stat buf;
+
+  if(stat(file, &buf) == -1){
+    fprintf(stderr, "Warning: couldn't stat file: %s - ", file);
+    perror("");
+    return(1);
+  }
+  sun.sun_family = AF_UNIX;
+  strncpy(sun.sun_path, file, sizeof(sun.sun_path));
+  strncpy(uml_name, name, sizeof(uml_name));
+  return(0);
+}
+
+static int switch_common(char *name)
+{
+  char file[MAXPATHLEN + 1], dir[MAXPATHLEN + 1], tmp[MAXPATHLEN + 1], *home;
+  int try_file = 1;
+
+  if((home = getenv("HOME")) != NULL){
+    snprintf(dir, sizeof(dir), "%s/.uml", home);
+    snprintf(file, sizeof(file), "%s/%s/mconsole", dir, name);
+    if(strncmp(name, dir, strlen(dir))){
+      if(!do_switch(file, name)) return(0);
+      try_file = 0;
+    }
+  }
+
+  snprintf(tmp, sizeof(tmp), "/tmp/uml/%s/mconsole", name);
+  if(strncmp(name, "/tmp/uml/", strlen("/tmp/uml/"))){
+    if(!do_switch(tmp, name)) return(0);
+  }
+
+  if(!do_switch(name, name)) return(0);
+  if(!try_file) return(-1);
+  return(do_switch(file, name));
+}
+
+#define MCONSOLE_MAGIC (0xcafebabe)
+#define MCONSOLE_MAX_DATA (512)
+#define MCONSOLE_VERSION (2)
+
+struct mconsole_request {
+	uint32_t magic;
+	uint32_t version;
+	uint32_t len;
+	char data[MCONSOLE_MAX_DATA];
+};
+
+struct mconsole_reply {
+	uint32_t err;
+	uint32_t more;
+	uint32_t len;
+	char data[MCONSOLE_MAX_DATA];
+};
+
+static char *absolutize(char *to, int size, char *from)
+{
+  char save_cwd[MAXPATHLEN + 1], *slash;
+  int remaining;
+
+  if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
+    perror("absolutize : unable to get cwd");
+    return(NULL);
+  }
+  slash = strrchr(from, '/');
+  if(slash != NULL){
+    *slash = '\0';
+    if(chdir(from)){
+      fprintf(stderr, "absolutize : Can't cd to '%s', ", from);
+      *slash = '/';
+      perror("");
+      return(NULL);
+    }
+    *slash = '/';
+    if(getcwd(to, size) == NULL){
+      fprintf(stderr, "absolutize : unable to get cwd of '%s'", from);
+      perror("");
+      return(NULL);
+    }
+    remaining = size - strlen(to);
+    if(strlen(slash) + 1 > remaining){
+      fprintf(stderr, "absolutize : unable to fit '%s' into %d chars\n", from,
+	      size);
+      return(NULL);
+    }
+    strcat(to, slash);
+  }
+  else {
+    if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
+      fprintf(stderr, "absolutize : unable to fit '%s' into %d chars\n", from,
+	      size);
+      return(NULL);
+    }
+    strcpy(to, save_cwd);
+    strcat(to, "/");
+    strcat(to, from);
+  }
+  chdir(save_cwd);
+  return(to);
+}
+
+static int fix_filenames(char **cmd_ptr)
+{
+  char *cow_file, *backing_file, *equal, *new, *ptr = *cmd_ptr;
+  char full_backing[MAXPATHLEN + 1], full_cow[MAXPATHLEN + 1];
+  int len;
+
+  if(strncmp(ptr, "config", strlen("config"))) return(0);
+  ptr += strlen("config");
+
+  while(isspace(*ptr) && (*ptr != '\0')) ptr++;
+  if(*ptr == '\0') return(0);
+
+  if(strncmp(ptr, "ubd", strlen("ubd"))) return(0);
+
+  while((*ptr != '=') && (*ptr != '\0')) ptr++;
+  if(*ptr == '\0') return(0);
+
+  equal = ptr;
+  cow_file = ptr + 1;
+  while((*ptr != ',') && (*ptr != '\0')) ptr++;
+  if(*ptr == '\0'){
+    backing_file = cow_file;
+    cow_file = NULL;
+  }
+  else {
+    *ptr = '\0';
+    backing_file = ptr + 1;
+  }
+
+  ptr = absolutize(full_backing, sizeof(full_backing), backing_file);
+  backing_file = ptr ? ptr : backing_file;
+
+  if(cow_file != NULL){
+    ptr = absolutize(full_cow, sizeof(full_cow), cow_file);
+    cow_file = ptr ? ptr : cow_file;
+  }
+
+  len = equal - *cmd_ptr;
+  len += strlen("=") + strlen(backing_file) + 1;
+  if(cow_file != NULL){
+    len += strlen(",") + strlen(cow_file);
+  }
+
+  new = malloc(len * sizeof(char));
+  if(new == NULL) return(0);
+
+  strncpy(new, *cmd_ptr, equal - *cmd_ptr);
+  ptr = new + (equal - *cmd_ptr);
+  *ptr++ = '=';
+
+  if(cow_file != NULL){
+    sprintf(ptr, "%s,", cow_file);
+    ptr += strlen(ptr);
+  }
+  strcpy(ptr, backing_file);
+
+  *cmd_ptr = new;
+  return(1);
+}
+
+static int default_cmd(int fd, char *command)
+{
+  struct mconsole_request request;
+  struct mconsole_reply reply;
+  char name[128];
+  int n, free_command, first;
+
+  if((sscanf(command, "%128[^: \f\n\r\t\v]:", name) == 1) &&
+     (*(name + 1) == ':')){
+    if(switch_common(name)) 
+      return(1);
+    command = strchr(command, ':');
+    *command++ = '\0';
+    while(isspace(*command)) command++;
+  }
+
+  free_command = fix_filenames(&command);
+
+  request.magic = MCONSOLE_MAGIC;
+  request.version = MCONSOLE_VERSION;
+  request.len = MIN(strlen(command), sizeof(reply.data) - 1);
+  strncpy(request.data, command, request.len);
+  request.data[request.len] = '\0';
+
+  if(free_command) free(command);
+
+  if(sendto(fd, &request, sizeof(request), 0, (struct sockaddr *) &sun, 
+	    sizeof(sun)) < 0){
+    fprintf(stderr, "Sending command to '%s' : ", sun.sun_path);
+    perror("");
+    return(1);
+  }
+
+  first = 1;
+  do {
+    n = recvfrom(fd, &reply, sizeof(reply), 0, NULL, 0);
+    if(n < 0){
+      perror("recvmsg");
+      return(1);
+    }
+
+    if(first){
+      if(reply.err) printf("ERR ");
+      else printf("OK ");
+
+      first = 0;
+    }
+
+    printf("%s", reply.data);
+  } while(reply.more);
+
+  printf("\n");
+  return(reply.err);
+}
+
+char *local_help = 
+"Additional local mconsole commands:\n\
+    quit - Quit mconsole\n\
+    switch <socket-name> - Switch control to the given machine\n\
+    log -f <filename> - use contents of <filename> as UML log messages\n\
+    mconsole-version - version of this mconsole program\n";
+
+static int help_cmd(int fd, char *command)
+{
+  default_cmd(fd, command);
+  printf("%s", local_help);
+  return(0);
+}
+
+static int switch_cmd(int fd, char *command)
+{
+  char *ptr;
+
+  ptr = &command[strlen("switch")];
+  while(isspace(*ptr)) ptr++;
+  if(switch_common(ptr)) return(1);
+  printf("Switched to '%s'\n", ptr);
+  return(0);
+}
+
+static int log_cmd(int fd, char *command)
+{
+  int len, max, chunk, input_fd, newline = 0;
+  char *ptr, buf[sizeof(((struct mconsole_request *) NULL)->data)];
+
+  ptr = &command[strlen("log")];
+  while(isspace(*ptr)) ptr++;
+
+  max = sizeof(((struct mconsole_request *) NULL)->data) - sizeof("log ") - 1;
+
+  if(!strncmp(ptr, "-f", strlen("-f"))){
+    ptr = &ptr[strlen("-f")];
+    while(isspace(*ptr)) ptr++;
+    input_fd = open(ptr, O_RDONLY);
+    if(input_fd < 0){
+      perror("opening file");
+      exit(1);
+    }
+    strcpy(buf, "log ");
+    ptr = buf + strlen(buf);
+    while((len = read(input_fd, ptr, max)) > 0){
+      ptr[len] = '\0';
+      default_cmd(fd, buf);
+      newline = (ptr[len - 1] == '\n');
+    }
+    if(len < 0){
+      perror("reading file");
+      exit(1);
+    }
+  }
+  else {
+    len = strlen(ptr);
+    while(len > 0){
+      chunk = MIN(len, max);
+      sprintf(buf, "log %.*s", chunk, ptr);
+      default_cmd(fd, buf);
+      newline = (ptr[chunk - 1] == '\n');
+
+      len -= chunk;
+      ptr += chunk;
+    }
+  }
+  if(!newline){
+    sprintf(buf, "log \n");
+    default_cmd(fd, buf);
+  }
+  return(0);
+}
+
+static int quit_cmd(int fd, char *command)
+{
+  exit(0);
+}
+
+static int mversion_cmd(int fd, char *command)
+{
+  printf("uml_mconsole client version %d\n", MCONSOLE_VERSION);
+  return(0);
+}
+
+struct cmd {
+  char *command;
+  int (*proc)(int, char *);
+};
+
+static struct cmd cmds[] = {
+  { "quit", quit_cmd },
+  { "help", help_cmd },
+  { "switch", switch_cmd },
+  { "log", log_cmd },
+  { "mconsole-version", mversion_cmd },
+  { NULL, default_cmd }
+  /* default_cmd means "send it to the UML" */
+};
+
+/* sends a command */
+int issue_command(int fd, char *command)
+{
+  char *ptr;
+  int i = 0;
+
+  /* Trim trailing spaces left by readline's filename completion */
+  ptr = &command[strlen(command) - 1];
+  while(isspace(*ptr)) *ptr-- = '\0';
+    
+  for(i = 0; i < sizeof(cmds)/sizeof(cmds[0]); i++){
+    if((cmds[i].command == NULL) || 
+       !strncmp(cmds[i].command, command, strlen(cmds[i].command))){
+      return((*cmds[i].proc)(fd, command));
+    }
+  }
+
+  /* Should never get here, considering the NULL test above will match the last
+   * entry of cmds */
+  return(0);
+}
+
+/* sends a command in argv style array */
+int issue_commandv(int fd, char **argv)
+{
+  char *command;
+  int len = -1, i = 0, status;
+
+  len = 1;  /* space for trailing null */
+  for(i = 0; argv[i] != NULL; i++)
+    len += strlen(argv[i]) + 1;  /* space for space */
+
+  command = malloc(len);
+  if(command == NULL){
+    perror("issue_command");
+    return(1);
+  }
+  command[0] = '\0';
+
+  for(i = 0; argv[i] != NULL; i++) {
+    strcat(command, argv[i]);
+    if(argv[i+1] != NULL) strcat(command, " ");
+  }
+
+  status = issue_command(fd, command);
+
+  free(command);
+
+  return(status);
+}
+
+static void Usage(void)
+{
+  fprintf(stderr, "Usage : uml_mconsole socket-name [command]\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  struct sockaddr_un here;
+  char *sock;
+  int fd;
+
+  if(argc < 2) Usage();
+  strcpy(uml_name, "[None]");
+  sock = argv[1];
+  switch_common(sock);
+
+  if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
+    perror("socket");
+    exit(1);
+  }
+  here.sun_family = AF_UNIX;
+  memset(here.sun_path, 0, sizeof(here.sun_path));
+
+  sprintf(&here.sun_path[1], "%5d", getpid());
+  if(bind(fd, (struct sockaddr *) &here, sizeof(here)) < 0){
+    perror("bind");
+    exit(1);
+  }
+
+  if(argc>2)
+    exit(issue_commandv(fd, argv+2));
+
+  while(1){
+    char *command, prompt[1 + sizeof(uml_name) + 2 + 1];
+
+    sprintf(prompt, "(%s) ", uml_name);
+    command = readline(prompt);
+    if(command == NULL) break;
+
+    if(*command) add_history(command);
+
+    issue_command(fd, command);
+    free(command);
+  }
+  printf("\n");
+  exit(0);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/.cvsignore
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/.cvsignore	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/.cvsignore	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+uml_moo

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,8 @@
+/.cvsignore/1.1/Fri Jan 11 05:21:31 2002//
+/Makefile/1.7/Thu Jun 26 16:27:00 2003//
+/cow.c/1.2/Wed Sep  3 16:35:07 2003//
+/cow.h/1.2/Wed Sep  3 16:35:52 2003//
+/cow_sys.h/1.2/Thu Aug 28 01:44:05 2003//
+/uml_mkcow.c/1.2/Mon Sep  8 21:20:29 2003//
+/uml_moo.c/1.10/Mon Sep  8 21:39:46 2003//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/moo

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,25 @@
+BIN = uml_moo uml_mkcow
+
+uml_moo_OBJS = uml_moo.o cow.o
+uml_mkcow_OBJS = uml_mkcow.o cow.o
+
+CFLAGS = -g -Wall -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
+
+BIN_DIR ?= /usr/bin
+
+all : $(BIN)
+
+uml_moo : $(uml_moo_OBJS)
+	$(CC) $(CFLAGS) -o $@ $($@_OBJS)
+
+uml_mkcow : $(uml_mkcow_OBJS)
+	$(CC) $(CFLAGS) -o $@ $($@_OBJS)
+
+$(uml_moo_OBJS) $(uml_mkcow_OBJS) : cow.h cow_sys.h
+
+clean : 
+	rm -f $(foreach bin,$(BIN),$($(bin)_OBJS)) $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -s $(BIN) $(DESTDIR)$(BIN_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,376 @@
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <byteswap.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <netinet/in.h>
+
+#include "cow.h"
+#include "cow_sys.h"
+
+#define PATH_LEN_V1 256
+
+struct cow_header_v1 {
+	int magic;
+	int version;
+	char backing_file[PATH_LEN_V1];
+	time_t mtime;
+	__u64 size;
+	int sectorsize;
+};
+
+#define PATH_LEN_V2 MAXPATHLEN
+
+struct cow_header_v2 {
+	unsigned long magic;
+	unsigned long version;
+	char backing_file[PATH_LEN_V2];
+	time_t mtime;
+	__u64 size;
+	int sectorsize;
+};
+
+/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in 
+ * case other systems have different values for MAXPATHLEN
+ */
+#define PATH_LEN_V3 4096
+
+/* Changes from V2 - 
+ *	PATH_LEN_V3 as described above
+ *	Explicitly specify field bit lengths for systems with different
+ *		lengths for the usual C types.  Not sure whether char or
+ *		time_t should be changed, this can be changed later without
+ *		breaking compatibility
+ *	Add alignment field so that different alignments can be used for the
+ *		bitmap and data
+ * 	Add cow_format field to allow for the possibility of different ways
+ *		of specifying the COW blocks.  For now, the only value is 0,
+ * 		for the traditional COW bitmap.
+ *	Move the backing_file field to the end of the header.  This allows
+ *		for the possibility of expanding it into the padding required
+ *		by the bitmap alignment.
+ * 	The bitmap and data portions of the file will be aligned as specified
+ * 		by the alignment field.  This is to allow COW files to be
+ *		put on devices with restrictions on access alignments, such as
+ *		/dev/raw, with a 512 byte alignment restriction.  This also
+ *		allows the data to be more aligned more strictly than on
+ *		sector boundaries.  This is needed for ubd-mmap, which needs
+ *		the data to be page aligned.
+ *	Fixed (finally!) the rounding bug
+ */
+
+struct cow_header_v3 {
+	__u32 magic;
+	__u32 version;
+	time_t mtime;
+	__u64 size;
+	__u32 sectorsize;
+	__u32 alignment;
+	__u32 cow_format;
+	char backing_file[PATH_LEN_V3];
+};
+
+/* COW format definitions - for now, we have only the usual COW bitmap */
+#define COW_BITMAP 0
+
+union cow_header {
+	struct cow_header_v1 v1;
+	struct cow_header_v2 v2;
+	struct cow_header_v3 v3;
+};
+
+#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
+#define COW_VERSION 3
+
+#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
+#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
+
+void cow_sizes(int version, __u64 size, int sectorsize, int align, 
+	       int bitmap_offset, unsigned long *bitmap_len_out, 
+	       int *data_offset_out)
+{
+	if(version < 3){
+		*bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
+
+		*data_offset_out = bitmap_offset + *bitmap_len_out;
+		*data_offset_out = (*data_offset_out + sectorsize - 1) / 
+			sectorsize;
+		*data_offset_out *= sectorsize;
+	}
+	else {
+		*bitmap_len_out = DIV_ROUND(size, sectorsize);
+		*bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
+
+		*data_offset_out = bitmap_offset + *bitmap_len_out;
+		*data_offset_out = ROUND_UP(*data_offset_out, align);
+	}
+}
+
+static int absolutize(char *to, int size, char *from)
+{
+	char save_cwd[256], *slash;
+	int remaining;
+
+	if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
+		cow_printf("absolutize : unable to get cwd - errno = %d\n", 
+			   errno);
+		return(-1);
+	}
+	slash = strrchr(from, '/');
+	if(slash != NULL){
+		*slash = '\0';
+		if(chdir(from)){
+			*slash = '/';
+			cow_printf("absolutize : Can't cd to '%s' - " 
+				   "errno = %d\n", from, errno);
+			return(-1);
+		}
+		*slash = '/';
+		if(getcwd(to, size) == NULL){
+			cow_printf("absolutize : unable to get cwd of '%s' - "
+			       "errno = %d\n", from, errno);
+			return(-1);
+		}
+		remaining = size - strlen(to);
+		if(strlen(slash) + 1 > remaining){
+			cow_printf("absolutize : unable to fit '%s' into %d "
+			       "chars\n", from, size);
+			return(-1);
+		}
+		strcat(to, slash);
+	}
+	else {
+		if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
+			cow_printf("absolutize : unable to fit '%s' into %d "
+			       "chars\n", from, size);
+			return(-1);
+		}
+		strcpy(to, save_cwd);
+		strcat(to, "/");
+		strcat(to, from);
+	}
+	chdir(save_cwd);
+	return(0);
+}
+
+int write_cow_header(char *cow_file, int fd, char *backing_file, 
+		     int sectorsize, int alignment, long long *size)
+{
+        struct cow_header_v3 *header;
+	struct stat64 buf;
+	int err;
+
+	err = cow_seek_file(fd, 0);
+	if(err != 0){
+		cow_printf("write_cow_header - lseek failed, errno = %d\n", 
+			   errno);
+		return(-errno);
+	}
+
+	err = -ENOMEM;
+	header = cow_malloc(sizeof(*header));
+	if(header == NULL){
+		cow_printf("Failed to allocate COW V3 header\n");
+		goto out;
+	}
+	header->magic = htonl(COW_MAGIC);
+	header->version = htonl(COW_VERSION);
+
+	err = -EINVAL;
+	if(strlen(backing_file) > sizeof(header->backing_file) - 1){
+		cow_printf("Backing file name \"%s\" is too long - names are "
+			   "limited to %d characters\n", backing_file, 
+			   sizeof(header->backing_file) - 1);
+		goto out_free;
+	}
+
+	if(absolutize(header->backing_file, sizeof(header->backing_file), 
+		      backing_file))
+		goto out_free;
+
+	err = stat64(header->backing_file, &buf);
+	if(err < 0){
+		cow_printf("Stat of backing file '%s' failed, errno = %d\n",
+			   header->backing_file, errno);
+		err = -errno;
+		goto out_free;
+	}
+
+	err = cow_file_size(header->backing_file, size);
+	if(err){
+		cow_printf("Couldn't get size of backing file '%s', "
+			   "errno = %d\n", header->backing_file, -*size);
+		goto out_free;
+	}
+
+	header->mtime = htonl(buf.st_mtime);
+	header->size = htonll(*size);
+	header->sectorsize = htonl(sectorsize);
+	header->alignment = htonl(alignment);
+	header->cow_format = COW_BITMAP;
+
+	err = write(fd, header, sizeof(*header));
+	if(err != sizeof(*header)){
+		cow_printf("Write of header to new COW file '%s' failed, "
+			   "errno = %d\n", cow_file, errno);
+		goto out_free;
+	}
+	err = 0;
+ out_free:
+	cow_free(header);
+ out:
+	return(err);
+}
+
+int file_reader(__u64 offset, char *buf, int len, void *arg)
+{
+	int fd = *((int *) arg);
+
+	return(pread(fd, buf, len, offset));
+}
+
+/* XXX Need to sanity-check the values read from the header */
+
+int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
+		    __u32 *version_out, char **backing_file_out, 
+		    time_t *mtime_out, __u64 *size_out, 
+		    int *sectorsize_out, __u32 *align_out, 
+		    int *bitmap_offset_out)
+{
+	union cow_header *header;
+	char *file;
+	int err, n;
+	unsigned long version, magic;
+
+	header = cow_malloc(sizeof(*header));
+	if(header == NULL){
+	        cow_printf("read_cow_header - Failed to allocate header\n");
+		return(-ENOMEM);
+	}
+	err = -EINVAL;
+	n = (*reader)(0, (char *) header, sizeof(*header), arg);
+	if(n < offsetof(typeof(header->v1), backing_file)){
+		cow_printf("read_cow_header - short header\n");
+		goto out;
+	}
+
+	magic = header->v1.magic;
+	if(magic == COW_MAGIC) {
+		version = header->v1.version;
+	}
+	else if(magic == ntohl(COW_MAGIC)){
+		version = ntohl(header->v1.version);
+	}
+	/* No error printed because the non-COW case comes through here */
+	else goto out;
+
+	*version_out = version;
+
+	if(version == 1){
+		if(n < sizeof(header->v1)){
+			cow_printf("read_cow_header - failed to read V1 "
+				   "header\n");
+			goto out;
+		}
+		*mtime_out = header->v1.mtime;
+		*size_out = header->v1.size;
+		*sectorsize_out = header->v1.sectorsize;
+		*bitmap_offset_out = sizeof(header->v1);
+		*align_out = *sectorsize_out;
+		file = header->v1.backing_file;
+	}
+	else if(version == 2){
+		if(n < sizeof(header->v2)){
+			cow_printf("read_cow_header - failed to read V2 "
+				   "header\n");
+			goto out;
+		}
+		*mtime_out = ntohl(header->v2.mtime);
+		*size_out = ntohll(header->v2.size);
+		*sectorsize_out = ntohl(header->v2.sectorsize);
+		*bitmap_offset_out = sizeof(header->v2);
+		*align_out = *sectorsize_out;
+		file = header->v2.backing_file;
+	}
+	else if(version == 3){
+		if(n < sizeof(header->v3)){
+			cow_printf("read_cow_header - failed to read V2 "
+				   "header\n");
+			goto out;
+		}
+		*mtime_out = ntohl(header->v3.mtime);
+		*size_out = ntohll(header->v3.size);
+		*sectorsize_out = ntohl(header->v3.sectorsize);
+		*align_out = ntohl(header->v3.alignment);
+		*bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
+		file = header->v3.backing_file;
+	}
+	else {
+		cow_printf("read_cow_header - invalid COW version\n");
+		goto out;		
+	}
+	err = -ENOMEM;
+	*backing_file_out = cow_strdup(file);
+	if(*backing_file_out == NULL){
+		cow_printf("read_cow_header - failed to allocate backing "
+			   "file\n");
+		goto out;
+	}
+	err = 0;
+ out:
+	cow_free(header);
+	return(err);
+}
+
+int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
+		  int alignment, int *bitmap_offset_out, 
+		  unsigned long *bitmap_len_out, int *data_offset_out)
+{
+	__u64 size, offset;
+	char zero = 0;
+	int err;
+
+	err = write_cow_header(cow_file, fd, backing_file, sectorsize, 
+			       alignment, &size);
+	if(err) 
+		goto out;
+	
+	*bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
+	cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
+		  bitmap_len_out, data_offset_out);
+
+	offset = *data_offset_out + size - sizeof(zero);
+	err = cow_seek_file(fd, offset);
+	if(err){
+		cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
+		goto out;
+	}
+
+	/* does not really matter how much we write it is just to set EOF 
+	 * this also sets the entire COW bitmap
+	 * to zero without having to allocate it 
+	 */
+	err = cow_write_file(fd, &zero, sizeof(zero));
+	if(err != sizeof(zero)){
+		err = -EINVAL;
+		cow_printf("Write of bitmap to new COW file '%s' failed, "
+			   "errno = %d\n", cow_file, errno);
+		goto out;
+	}
+
+	return(0);
+
+ out:
+	return(err);
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,41 @@
+#ifndef __COW_H__
+#define __COW_H__
+
+#include <asm/types.h>
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+# define ntohll(x) (x)
+# define htonll(x) (x)
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+# define ntohll(x)  bswap_64(x)
+# define htonll(x)  bswap_64(x)
+#else
+#error "__BYTE_ORDER not defined"
+#endif
+
+extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
+			 int sectorsize, int alignment, int *bitmap_offset_out, 
+			 unsigned long *bitmap_len_out, int *data_offset_out);
+
+extern int file_reader(__u64 offset, char *buf, int len, void *arg);
+extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
+			   void *arg, __u32 *version_out, 
+			   char **backing_file_out, time_t *mtime_out, 
+			   __u64 *size_out, int *sectorsize_out, 
+			   __u32 *align_out, int *bitmap_offset_out);
+
+extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
+			    int sectorsize, int alignment, long long *size);
+
+extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
+		      int bitmap_offset, unsigned long *bitmap_len_out, 
+		      int *data_offset_out);
+
+#endif
+
+/*
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow_sys.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow_sys.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/cow_sys.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,91 @@
+#ifndef __COW_SYS_H__
+#define __COW_SYS_H__
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/mount.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+static inline void *cow_malloc(int size)
+{
+	return(malloc(size));
+}
+
+static inline void cow_free(void *ptr)
+{
+	free(ptr);
+}
+
+static inline int cow_printf(char *fmt, ...)
+{
+	va_list args;
+	int n;
+
+	va_start(args, fmt);
+	n = vprintf(fmt, args);
+	va_end(args);
+	return(n);
+}
+
+static inline char *cow_strdup(char *str)
+{
+	return(strdup(str));
+}
+
+static inline int cow_seek_file(int fd, __u64 offset)
+{
+	__u64 actual;
+
+	actual = lseek(fd, offset, SEEK_SET);
+	if(actual != offset)
+		return(-errno);
+	return(0);
+}
+
+static inline int cow_file_size(char *file, long long *size_out)
+{
+	struct stat buf;
+
+	if(stat(file, &buf) == -1){
+		cow_printf("Couldn't stat \"%s\" : errno = %d\n", file, errno);
+		return(-errno);
+	}
+	if(S_ISBLK(buf.st_mode)){
+		int fd, blocks;
+
+		if((fd = open(file, O_RDONLY)) < 0){
+			cow_printf("Couldn't open \"%s\", errno = %d\n", file,
+				   errno);
+			return(-errno);
+		}
+		if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
+			cow_printf("Couldn't get the block size of \"%s\", "
+				   "errno = %d\n", file, errno);
+			close(fd);
+			return(-errno);
+		}
+		*size_out = ((long long) blocks) * 512;
+		close(fd);
+		return(0);
+	}
+	*size_out = buf.st_size;
+	return(0);
+}
+
+static inline int cow_write_file(int fd, char *buf, int size)
+{
+	return(write(fd, buf, size));
+}
+
+#endif
+
+/*
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_mkcow.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_mkcow.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_mkcow.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,70 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "cow.h"
+
+void usage(const char progname[])
+{
+	fprintf(stderr, "%s usage: \n", progname);
+	fprintf(stderr, "\t%s [-f] <COW file> <backing file>\n", progname);
+	fprintf(stderr, "\t-f forces overwrite of an existing COW file\n");
+	exit(2);
+}
+
+int main(int argc, char *argv[]) 
+{
+  int fd; 
+  char *cow_file;
+  char *backing_file;
+  int bitmap_offset_out;
+  unsigned long bitmap_len_out;
+  int data_offset_out;
+  int flags;
+  mode_t mode;
+  char *progname;
+  
+  progname = argv[0];
+  argv++;
+  argc--;
+
+  if(argc < 1)
+        usage(progname);
+
+  flags = O_RDWR | O_CREAT | O_LARGEFILE;
+  mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+  if(strcmp("-f", argv[0]) != 0){
+	/* not forced, creating as exclusive */
+	flags |= O_EXCL;
+  }
+  else {
+  	argv++;
+  	argc--;
+  }
+  
+  if (argc < 2)
+	usage(progname);
+  
+  cow_file = argv[0];
+  backing_file = argv[1];
+  
+  if((fd = open(cow_file, flags, mode)) == -1) {
+	perror("open COW file");
+	exit(1);
+  }
+  
+  if(init_cow_file(fd, cow_file, backing_file, 512, sysconf(_SC_PAGESIZE), 
+		   &bitmap_offset_out, &bitmap_len_out, &data_offset_out)){
+	perror("write_cow_header");
+	exit(1);
+  }
+
+  return (0);
+}
+
+/* vim: ts=4 tw=74 
+ */

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_moo.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_moo.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/moo/uml_moo.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,254 @@
+/* Copyrighted (C) 2001 RidgeRun,Inc (glonnon at ridgerun.com)
+ * With modifications by Jeff Dike, James McMechan, and Steve Schmidtke.
+ * Licensed under the GPL
+ */ 
+
+#define _XOPEN_SOURCE 500
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <time.h>
+#include <fcntl.h>
+#include <string.h>
+#include <byteswap.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include "cow.h"
+
+static inline int ubd_test_bit(int bit, unsigned long *data)
+{
+	int bits, n, off;
+
+	bits = sizeof(data[0]) * 8;
+	n = bit / bits;
+	off = bit % bits;
+	return((data[n] & (1 << off)) != 0);
+}
+
+static inline void ubd_set_bit(int bit, unsigned long *data)
+{
+	int bits, n, off;
+
+	bits = sizeof(data[0]) * 8;
+	n = bit / bits;
+	off = bit % bits;
+	data[n] |= (1 << off);
+}
+
+int create_backing_file(char *in, char *out, char *actual_backing)
+{
+	int cow_fd, back_fd, in_fd, out_fd;
+	struct stat buf;
+	unsigned long *bitmap;
+	unsigned long bitmap_len;
+	int sectors;
+	void *sector, *zeros;
+	__u64 size, offset, i; /* i is u64 to prevent 32 bit overflow */
+	__u32 version, alignment;
+	int data_offset;
+        char *backing_file;
+        time_t mtime;
+        int sectorsize, bitmap_offset, perms, n;
+
+	if((cow_fd = open(in,  O_RDONLY)) < 0){
+		perror("COW file open");
+		exit(1);
+	}
+
+	if(read_cow_header(file_reader, &cow_fd, &version, &backing_file, 
+			   &mtime, &size, &sectorsize, &alignment,
+			   &bitmap_offset)){
+		fprintf(stderr, "Reading COW header failed\n");
+		exit(1);
+	}
+
+	if(actual_backing != NULL)
+		backing_file = actual_backing;
+
+	if(stat(backing_file, &buf) < 0) {
+		perror("Stating backing file");
+		exit(1);
+	}
+
+	if(buf.st_size != size){
+		fprintf(stderr,"Size mismatch (%ld vs %ld) of COW header "
+			"vs backing file \"%s\"\n", (long int) size, 
+			(long int) buf.st_size, backing_file);
+		exit(1);
+	}
+	if(buf.st_mtime != mtime) {
+		fprintf(stderr,"mtime mismatch (%ld vs %ld) of COW "
+			"header vs backing file \"%s\"\n", mtime, buf.st_mtime,
+			backing_file);
+		exit(1);
+	}
+
+	perms = (out != NULL) ? O_RDONLY : O_RDWR;
+
+	if((back_fd = open(backing_file, perms)) < 0){
+		perror("Opening backing file");
+		exit(1);
+	}
+
+	if(out != NULL){
+		if((out_fd = creat(out, 0644)) < 0){
+			perror("Output file open");
+			exit(1);
+		}
+	}
+	else out_fd = back_fd;
+
+	cow_sizes(version, size, sectorsize, alignment, bitmap_offset, 
+		  &bitmap_len, &data_offset);
+		
+	bitmap = (unsigned long *) malloc(bitmap_len);
+	if(bitmap == NULL) {
+		perror("Can't allocate bitmap");
+		exit(1);
+	}
+
+	if(pread(cow_fd, bitmap, bitmap_len, bitmap_offset) != bitmap_len){
+		perror("Reading COW bitmap");
+		exit(1);
+	}
+
+	sectors = size / sectorsize;
+	sector = malloc(sectorsize);
+	zeros = malloc(sectorsize);
+	if((sector == NULL) || (zeros == NULL)){
+		perror("Malloc of buffers");
+		exit(1);
+	}
+
+	memset(zeros, 0, sectorsize);
+
+	for(i = 0; i < sectors; i++){
+		offset = i * sectorsize;
+		if(ubd_test_bit(i, bitmap)){
+			offset += data_offset;
+			in_fd = cow_fd;
+		}
+		else in_fd = back_fd;
+
+		/* If we're doing a destructive merge, and the backing file
+		 * sector is up to date, then there's nothing to do.
+		 */
+		if((out_fd == back_fd) && (in_fd == back_fd))
+			continue;
+
+		if(pread(in_fd, sector, sectorsize, offset) != sectorsize){
+			perror("Reading data");
+			exit(1);
+		}
+
+		/* Sparse file creation - if the sector is all zeros and it's
+		 * not the last sector (which always gets written out in order
+		 * to make the file size right), maybe it doesn't need to be
+		 * written out.
+		 */
+
+		if((i < sectors - 1) && !memcmp(sector, zeros, sectorsize)){
+			/* If we're doing a non-destructive merge, then zero 
+			 * sectors can just be skipped.
+			 */
+			if(out_fd != back_fd)
+				continue;
+
+			/* Otherwise, we are doing a destructive merge, and
+			 * we need to check the backing file for a zero
+			 * sector.
+			 */
+			n = pread(back_fd, sector, sectorsize, i * sectorsize);
+			if(n != sectorsize){
+				perror("Checking backing file for zeros");
+				exit(1);
+			}
+
+			if(!memcmp(sector, zeros, sectorsize))
+				continue;
+
+			/* The backing file sector isn't zeros, so the sector
+			 * of zeros in the COW file needs to be written out.
+			 */
+			memset(sector, 0, sectorsize);
+		}
+
+		/* The offset can't be 'offset' because that's used as an
+		 * input offset, which may be offset by the COW header.
+		 */
+		n = pwrite(out_fd, sector, sectorsize, i * sectorsize);
+		if(n != sectorsize){
+			perror("Writing data");
+			exit(1);
+		}
+	}
+	free(bitmap);
+	free(sector);
+	free(zeros);
+	close(cow_fd);
+	close(out_fd);
+	close(back_fd);
+	return(0);
+}
+
+static char *usage_string = 
+"%s usage:\n"
+"\t%s [ -b <actual backing file> ] <COW file> <new backing file>\n"
+"\t%s [ -b <actual backing file> ] -d <COW file>\n"
+"Creates a new filesystem image from the COW file and its backing file.\n"
+"Specifying -d will cause a destructive, in-place merge of the COW file into\n"
+"its current backing file\n"
+"Specifying -b overrides the backing_file specified in the COW file.  This is\n"
+"needed when dealing with a COW file that was created inside a chroot jail.\n"
+"%s supports version 1 and 2 COW files.\n"
+"";
+
+static int Usage(char *prog) {
+	fprintf(stderr, usage_string, prog, prog, prog, prog);
+	exit(1);
+}
+    
+int main(int argc, char **argv)
+{
+	char *prog = argv[0];
+	char *actual_backing_file = NULL;
+	int in_place = 0;
+
+	argv++;
+	argc--;
+
+	if(argc == 0)
+		Usage(prog);
+
+	if(!strcmp(argv[0], "-d")){
+		in_place = 1;
+		argv++;
+		argc--;
+	}
+
+	if(!strcmp(argv[0], "-b")){
+		actual_backing_file = argv[1];
+		argv += 2;
+		argc -= 2;
+	}
+
+	if(in_place){
+		if(argc != 1) Usage(prog);
+		create_backing_file(argv[0], NULL, actual_backing_file);
+	}
+	else {
+		if(argc != 2) Usage(prog);
+		create_backing_file(argv[0], argv[1], actual_backing_file);
+	}
+	return 0;
+}
+
+/*
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/port-helper/CVS

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,3 @@
+D/CVS////
+/port-helper.c/1.6/Thu Jul 25 01:27:37 2002//
+/Makefile/1.3/Sat Feb  8 04:05:31 2003//

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/port-helper

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,17 @@
+OBJS = port-helper.o
+BIN = port-helper
+CFLAGS = -g -Wall
+
+LIB_DIR ?= /usr/lib/uml
+
+all : $(BIN)
+
+$(BIN) : $(OBJS)
+	$(CC) $(CFLAGS) -o $(BIN) $(OBJS)
+
+clean : 
+	rm -f $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(LIB_DIR)
+	install -s $(BIN) $(DESTDIR)$(LIB_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/port-helper.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/port-helper.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/port-helper/port-helper.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,114 @@
+/* port-helper
+
+Used by the port and xterm console channels for User Mode Linux.
+
+Tells UML "here is a file descriptor for my stdin as given to me by 
+xterm or telnetd". Once UML has that (with os_rcv_fd()) UML opens it
+for read and write, and the console is functional.
+
+(c) Jeff Dike 2002-2004
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/uio.h>
+
+/* pass the fd over an fd that is already connected to a socket */
+static void send_fd(int fd, int target)
+{
+
+  /* File descriptors are specific to a process and normally only
+     sharable with another process by inheritence with fork(). The 
+     alternative is to use sendmsg with a special flag that says 
+     "I'm knowingly giving another process information from my private 
+     file descriptor table" (SCM_RIGHTS) 
+  */
+
+  char anc[CMSG_SPACE(sizeof(fd))];
+  struct msghdr msg;
+  struct cmsghdr *cmsg;
+  struct iovec iov;
+  int *fd_ptr, pid = getpid();
+
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  iov = ((struct iovec) { iov_base : &pid,
+			  iov_len :  sizeof(pid) });
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+  msg.msg_flags = 0;
+  msg.msg_control = anc;
+  msg.msg_controllen = sizeof(anc);
+
+  cmsg = CMSG_FIRSTHDR(&msg);
+  cmsg->cmsg_level = SOL_SOCKET;
+  cmsg->cmsg_type = SCM_RIGHTS;
+  cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+
+  fd_ptr = (int *) CMSG_DATA(cmsg);
+  *fd_ptr = fd;
+
+  msg.msg_controllen = cmsg->cmsg_len;
+
+  if(sendmsg(target, &msg, 0) < 0){
+    perror("sendmsg");
+    exit(1);
+  }
+}
+
+/* for xterm we don't have an open socket, we only have the name
+ of a file used as a Unix socket by UML. So we need to open it. */
+static int open_socket(char *name)
+{
+  struct sockaddr_un sock;
+  int fd;
+
+  if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
+    perror("socket");
+    exit(1);
+  }
+
+  sock.sun_family = AF_UNIX;
+  memset(sock.sun_path, 0, sizeof(sock.sun_path));
+  sprintf(&sock.sun_path[1], "%5d", getpid());
+
+  if(bind(fd, (struct sockaddr *) &sock, sizeof(sock)) < 0){
+    perror("bind");
+    exit(1);
+  }
+
+  snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
+  if(connect(fd, (struct sockaddr *) &sock, sizeof(sock))){
+    perror("connect");
+    exit(1);
+  }
+
+  return(fd);
+}
+
+int main(int argc, char **argv)
+{
+  int fd;
+
+  if((argc > 1) && !strcmp(argv[1], "-uml-socket")) {
+	/* inherited a filename not an open fd */
+	fd = open_socket(argv[2]);
+  } else {
+	/* inherited fd of the listening TCP socket */
+	fd = 3;
+  }
+
+  signal(SIGHUP, SIG_IGN);
+  if(ioctl(0, TIOCNOTTY, 0) < 0)
+    perror("TIOCNOTTY failed in port-helper, check UML's exec call for xterm or telnetd");
+  send_fd(0, fd);
+  pause();
+  return(0);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,3 @@
+/tunctl.c/1.4/Tue Sep 10 22:18:06 2002//
+/Makefile/1.2/Sat Feb  8 04:05:04 2003//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/tunctl

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,17 @@
+OBJS = tunctl.o
+BIN = tunctl
+CFLAGS = -g -Wall
+
+BIN_DIR ?= /usr/bin
+
+all : $(BIN)
+
+$(BIN) : $(OBJS)
+	$(CC) $(CFLAGS) -o $(BIN) $(OBJS)
+
+clean : 
+	rm -f $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -s $(BIN) $(DESTDIR)$(BIN_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/tunctl.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/tunctl.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/tunctl/tunctl.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,113 @@
+/* Copyright 2002 Jeff Dike
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <linux/if_tun.h>
+
+static void Usage(char *name)
+{
+  fprintf(stderr, "Create: %s [-b] [-u owner] [-t device-name] "
+	  "[-f tun-clone-device]\n", name);
+  fprintf(stderr, "Delete: %s -d device-name [-f tun-clone-device]\n\n", 
+	  name);
+  fprintf(stderr, "The default tun clone device is /dev/net/tun - some systems"
+	  " use\n/dev/misc/net/tun instead\n\n");
+  fprintf(stderr, "-b will result in brief output (just the device name)\n");
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  struct ifreq ifr;
+  struct passwd *pw;
+  long owner = geteuid();
+  int tap_fd, opt, delete = 0, brief = 0;
+  char *tun = "", *file = "/dev/net/tun", *name = argv[0], *end;
+
+  while((opt = getopt(argc, argv, "bd:f:t:u:")) > 0){
+    switch(opt) {
+      case 'b':
+        brief = 1;
+        break;
+      case 'd':
+        delete = 1;
+	tun = optarg;
+        break;
+      case 'f':
+	file = optarg;
+	break;
+      case 'u':
+	pw = getpwnam(optarg);
+	if(pw != NULL){
+	  owner = pw->pw_uid;
+	  break;
+	}
+        owner = strtol(optarg, &end, 0);
+	if(*end != '\0'){
+	  fprintf(stderr, "'%s' is neither a username nor a numeric uid.\n",
+		  optarg);
+	  Usage(name);
+	}
+        break;
+      case 't':
+        tun = optarg;
+        break;
+      case 'h':
+      default:
+        Usage(name);
+    }
+  }
+
+  argv += optind;
+  argc -= optind;
+
+  if(argc > 0)
+    Usage(name);
+
+  if((tap_fd = open(file, O_RDWR)) < 0){
+    fprintf(stderr, "Failed to open '%s' : ", file);
+    perror("");
+    exit(1);
+  }
+
+  memset(&ifr, 0, sizeof(ifr));
+
+  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+  strncpy(ifr.ifr_name, tun, sizeof(ifr.ifr_name) - 1);
+  if(ioctl(tap_fd, TUNSETIFF, (void *) &ifr) < 0){
+    perror("TUNSETIFF");
+    exit(1);
+  }
+
+  if(delete){
+    if(ioctl(tap_fd, TUNSETPERSIST, 0) < 0){
+      perror("TUNSETPERSIST");
+      exit(1);
+    }    
+    printf("Set '%s' nonpersistent\n", ifr.ifr_name);
+  }
+  else {
+    if(ioctl(tap_fd, TUNSETPERSIST, 1) < 0){
+      perror("TUNSETPERSIST");
+      exit(1);
+    }
+    if(ioctl(tap_fd, TUNSETOWNER, owner) < 0){
+      perror("TUNSETPERSIST");
+      exit(1);
+    } 
+    if(brief)
+      printf("%s\n", ifr.ifr_name);
+    else printf("Set '%s' persistent and owned by uid %ld\n", ifr.ifr_name, 
+		owner);
+  }
+  return(0);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/.cvsignore
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/.cvsignore	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/.cvsignore	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,2 @@
+uml_net
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,11 @@
+/output.h/1.1/Tue Nov 13 05:25:26 2001//
+/host.h/1.3/Mon Dec 10 04:36:26 2001//
+/.cvsignore/1.1/Fri Jan 11 05:21:31 2002//
+/host.c/1.6/Sun Apr 28 13:26:07 2002//
+/output.c/1.2/Sun Apr 28 13:38:44 2002//
+/slip.c/1.5/Sun Apr 28 19:47:35 2002//
+/Makefile/1.8/Sat Feb  8 04:04:55 2003//
+/uml_net.c/1.19/Tue May 27 02:52:21 2003//
+/ethertap.c/1.9/Sat Nov  8 13:15:25 2003//
+/tuntap.c/1.6/Sat Nov  8 13:04:58 2003//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/uml_net

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,24 @@
+TUNTAP = $(shell [ -e /usr/include/linux/if_tun.h ] && echo -DTUNTAP)
+
+BIN = uml_net
+CFLAGS = -g -Wall $(TUNTAP)
+
+BIN_DIR ?= /usr/bin
+
+OBJS = ethertap.o host.o output.o slip.o uml_net.o
+
+ifneq ($(TUNTAP),)
+	OBJS += tuntap.o
+endif
+
+all : $(BIN)
+
+$(BIN) : $(OBJS)
+	$(CC) $(CFLAGS) -o $(BIN) $(OBJS)
+
+clean : 
+	rm -f $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -s -m 04755 $(BIN) $(DESTDIR)$(BIN_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/ethertap.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/ethertap.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/ethertap.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,274 @@
+/* Copyright 2001 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include "host.h"
+#include "output.h"
+
+static void fail(int fd)
+{
+  char c = 0;
+
+  if(write(fd, &c, sizeof(c)) != sizeof(c))
+    perror("Writing failure byte");
+}
+
+void output_fail(struct output *output, int fd)
+{
+  fail(fd);
+  write_output(fd, output);
+  exit(1);
+}
+
+/* Shouldn't there be some other way to figure out the major and minor
+ * number of the tap device other than hard-wiring it here? Does FreeBSD
+ * have a 'tap' device? Should we have some kind of #ifdef here?
+ */
+#define TAP_MAJOR 36
+#define TAP_MINOR 16  /* plus whatever tap device it was. */
+
+static int maybe_insmod(char *dev, struct output *output)
+{
+  struct ifreq ifr;
+  int fd, unit;
+  char unit_buf[sizeof("unit=nnn\0")];
+  char ethertap_buf[sizeof("ethertapnnn\0")];
+  char *ethertap_argv[] = { "modprobe", "ethertap", unit_buf, "-o", 
+			    ethertap_buf, NULL };
+  char *netlink_argv[] = { "modprobe", "netlink_dev", NULL };
+  char buf[256];
+  
+  if((fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0){
+    output_errno(output, "socket");
+    return(-1);
+  }
+  strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name) - 1);
+  ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
+  if(ioctl(fd, SIOCGIFFLAGS, &ifr) == 0) return(0);
+  if(errno != ENODEV){
+    output_errno(output, "SIOCGIFFLAGS on tap device");
+    return(-1);
+  }
+  if(sscanf(dev, "tap%d", &unit) != 1){
+    snprintf(buf, sizeof(buf), "failed to get unit number from '%s'\n", dev);
+    add_output(output, buf, -1);
+    return(-1);
+  }
+  snprintf(unit_buf, sizeof(unit_buf) - 1, "unit=%d", unit);
+  snprintf(ethertap_buf, sizeof(ethertap_buf) - 1, "ethertap%d", unit);
+  do_exec(netlink_argv, 0, output);
+  return(do_exec(ethertap_argv, 0, output));
+}
+
+#define BUF_SIZE 1500
+
+#define max(i, j) (((i) > (j)) ? (i) : (j))
+
+static void ethertap(char *dev, int data_fd, int control_fd, char *gate, 
+		     char *remote, int collect_output, 
+		     int (*control_cb)(int, char *, struct output *))
+{
+  struct output output = INIT_OUTPUT, *o = NULL;
+  int ip[4];
+  char *ifconfig_argv[] = { "ifconfig", dev, "arp", "mtu", "1500", gate,
+			    "netmask", "255.255.255.255", "up", NULL };
+  char *down_argv[] = { "ifconfig", dev, "0.0.0.0", "down", NULL };
+  char dev_file[sizeof("/dev/tapxxxx\0")], buf[256], c;
+  int tap, minor;
+
+  if(collect_output) o = &output;
+  if(setreuid(0, 0) < 0){
+    output_errno(o, "setreuid");
+    output_fail(o, control_fd);
+  }
+  if(gate != NULL){
+    sscanf(gate, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3]);
+    if(maybe_insmod(dev, o)) output_fail(o, control_fd);
+
+    if(do_exec(ifconfig_argv, 1, o)) output_fail(o, control_fd);
+
+    if((remote != NULL) && route_and_arp(dev, remote, NULL, 1, o)) 
+      output_fail(o, control_fd);
+
+    forward_ip(o);
+  }
+
+  if(!is_a_device(dev)){
+    add_output(o, "Device doesn't contain only alphanumeric characters\n", -1);
+    output_fail(o, control_fd);
+  }
+  snprintf(dev_file, sizeof(dev_file) - 1, "/dev/%.7s", dev);
+
+  /* do a mknod on it in case it doesn't exist. */
+
+  if(sscanf(dev_file, "/dev/tap%d", &minor) != 1){
+    snprintf(buf, sizeof(buf), "failed to get unit number from '%s'\n", 
+	     dev_file);
+    add_output(o, buf, -1);
+    output_fail(o, control_fd);
+  }
+  minor += TAP_MINOR;
+  mk_node(dev_file, TAP_MAJOR, minor); 
+
+  if((tap = open(dev_file, O_RDWR | O_NONBLOCK)) < 0){
+    output_errno(o, "open");
+    output_fail(o, control_fd);
+  }
+
+  c = 1;
+  if(write(control_fd, &c, sizeof(c)) != sizeof(c)){
+    output_errno(o, "write");
+    output_fail(o, control_fd);
+  }
+  write_output(control_fd, o);
+
+  while(1){
+    fd_set fds, except;
+    char buf[BUF_SIZE];
+    int n, max_fd;
+
+    FD_ZERO(&fds);
+    FD_SET(tap, &fds);
+    FD_SET(data_fd, &fds);
+    FD_SET(control_fd, &fds);
+    except = fds;
+    max_fd = max(max(tap, data_fd), control_fd) + 1;
+    if(select(max_fd, &fds, NULL, &except, NULL) < 0){
+      perror("select");
+      continue;
+    }
+    if(FD_ISSET(tap, &fds)){
+      n = read(tap, buf, sizeof(buf));
+      if(n == 0) break;
+      else if(n < 0){
+	perror("read");
+	continue;
+      }
+      n = send(data_fd, buf, n, 0);
+      if((n < 0) && (errno != EAGAIN)){
+	perror("send");
+	break;
+      }
+    }
+    else if(FD_ISSET(data_fd, &fds)){
+      n = recvfrom(data_fd, buf, sizeof(buf), 0, NULL, NULL);
+      if(n == 0) break;
+      else if(n < 0) perror("recvfrom");
+      n = write(tap, buf, n);
+      if(n < 0) perror("write");      
+    }
+    else if(FD_ISSET(control_fd, &fds)){
+      if((*control_cb)(control_fd, dev, o)) break;
+    }
+  }
+  if(gate != NULL) do_exec(down_argv, 0, NULL);
+  if(remote != NULL) no_route_and_arp(dev, remote, NULL, NULL);
+}
+
+struct addr_change_v1_v3 {
+  enum change_type what;
+  unsigned char addr[4];
+};
+
+static int control_v1_v3(int fd, char *dev, struct output *output)
+{
+  struct addr_change_v1_v3 change;
+  int n;
+
+  n = read(fd, &change, sizeof(change));
+  if(n == sizeof(change)) 
+    address_change(change.what, change.addr, dev, NULL, output);
+  else if(n == 0) return(1);
+  else {
+    fprintf(stderr, "read from UML failed, n = %d, errno = %d\n", n, 
+	    errno);
+    return(1);
+  }
+  if(output) write_output(fd, output);
+  return(0);
+}
+
+struct addr_change_v4 {
+  enum change_type what;
+  unsigned char addr[4];
+  unsigned char netmask[4];
+};
+
+static int control_v4(int fd, char *dev, struct output *output)
+{
+  struct addr_change_v4 change;
+  int n;
+
+  n = read(fd, &change, sizeof(change));
+  if(n == sizeof(change)) 
+    address_change(change.what, change.addr, dev, change.netmask, output);
+  else if(n == 0) return(1);
+  else {
+    fprintf(stderr, "read from UML failed, n = %d, errno = %d\n", n, 
+	    errno);
+    return(1);
+  }
+  if(output) write_output(fd, output);
+  return(0);
+}
+
+void ethertap_v0(int argc, char **argv)
+{
+  char *dev = argv[0];
+  int fd = atoi(argv[1]);
+  char *gate_addr = NULL;
+  char *remote_addr = NULL;
+
+  if(argc > 2){
+    gate_addr = argv[2];
+    remote_addr = argv[3];
+  }
+  ethertap(dev, fd, -1, gate_addr, remote_addr, 0, NULL);
+}
+
+void ethertap_v1_v2(int argc, char **argv)
+{
+  char *dev = argv[0];
+  int data_fd = atoi(argv[1]);
+  int control_fd = atoi(argv[2]);
+  char *gate_addr = NULL;
+
+  if(argc > 3) gate_addr = argv[3];
+  ethertap(dev, data_fd, control_fd, gate_addr, NULL, 0, control_v1_v3);
+}
+
+void ethertap_v3(int argc, char **argv)
+{
+  char *dev = argv[0];
+  int data_fd = atoi(argv[1]);
+  char *gate = argv[2];
+
+  ethertap(dev, data_fd, 1, gate, NULL, 1, control_v1_v3);
+}
+
+void ethertap_v4(int argc, char **argv)
+{
+  char *dev, *gate;
+  int data_fd;
+  struct output output = INIT_OUTPUT;
+
+  if(argc < 2){
+    add_output(&output, "uml_net : Too few arguments to ethertap_v4\n", -1);
+    output_fail(&output, 1);
+  }
+  dev = argv[0];
+  data_fd = atoi(argv[1]);
+  gate = argc >= 3 ? argv[2] : NULL;
+  ethertap(dev, data_fd, 1, gate, NULL, 1, control_v4);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,251 @@
+/* Copyright 2001 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include "output.h"
+#include "host.h"
+
+int do_exec(char **args, int need_zero, struct output *output)
+{
+  int pid, status, fds[2], n;
+  char buf[256], **arg;
+
+  if(output){
+    add_output(output, "*", -1);
+    for(arg = args; *arg; arg++){
+      add_output(output, " ", -1);
+      add_output(output, *arg, -1);
+    }
+    add_output(output, "\n", -1);
+    if(pipe(fds) < 0){
+      perror("Creating pipe");
+      output = NULL;
+    }
+  }
+  if((pid = fork()) == 0){
+    if(output){
+      close(fds[0]);
+      if((dup2(fds[1], 1) < 0) || (dup2(fds[1], 2) < 0)) perror("dup2");
+    }
+    execvp(args[0], args);
+    fprintf(stderr, "Failed to exec '%s'", args[0]);
+    perror("");
+    exit(1);
+  }
+  else if(pid < 0){
+    output_errno(output, "fork failed");
+    return(-1);
+  }
+  if(output){
+    close(fds[1]);
+    while((n = read(fds[0], buf, sizeof(buf))) > 0) add_output(output, buf, n);
+    if(n < 0) output_errno(output, "Reading command output");
+  }
+  if(waitpid(pid, &status, 0) < 0){
+    output_errno(output, "waitpid");
+    return(-1);
+  }
+  if(need_zero && (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))){
+    sprintf(buf, "'%s' didn't exit with status 0\n", args[0]);
+    add_output(output, buf, -1);
+    return(-1);
+  }
+  return(0);
+}
+
+static void local_net_do(char **argv, int if_index, char *addr_str, 
+			 char *netmask_str, char *skip_dev,
+			 struct output *output)
+{
+  FILE *fp;
+  unsigned long addr, netmask, if_addr;
+  int a[4], n[4];
+  char buf[1024], iface[32], out[1024];
+
+  if(sscanf(addr_str, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) != 4){
+    add_output(output, "local_net_do didn't parse address", -1);
+    return;
+  }
+  addr = (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0];
+  if(sscanf(netmask_str, "%d.%d.%d.%d", &n[0], &n[1], &n[2], &n[3]) != 4){
+    add_output(output, "local_net_do didn't parse netmask", -1);
+    return;
+  }
+  netmask = (n[3] << 24) | (n[2] << 16) | (n[1] << 8) | n[0];
+  argv[if_index] = iface;
+  if((fp = fopen("/proc/net/route", "r")) == NULL){
+    output_errno(output, "Couldn't open /proc/net/route");
+    return;
+  }
+  if(fgets(buf, sizeof(buf), fp) == NULL) return;
+  buf[0] = '\0';
+  while(fgets(buf, sizeof(buf), fp) != NULL){
+    int n;
+    n = sscanf(buf, "%32s %lx %*x %*x %*x %*x %*x", iface, &if_addr);
+    if(n != 2){
+      sprintf(out, "Didn't parse /proc/net/route, got %d\n on '%s'", n, buf);
+      add_output(output, out, -1);
+      return;
+    }
+    if(strcmp(skip_dev, iface) && ((addr & netmask) == (if_addr & netmask)))
+      do_exec(argv, 0, output);
+    buf[0] = '\0';
+  }
+  fclose(fp);
+}
+
+int is_a_device(char *dev)
+{
+  int i;
+
+  for(i = 0; i < strlen(dev); i++){
+    if(!isalnum(dev[i])) return(0);
+  }
+  return(1);
+}
+
+int route_and_arp(char *dev, char *addr, char *netmask, int need_route,
+		  struct output *output)
+{
+  char echo[sizeof("echo 1 > /proc/sys/net/ipv4/conf/XXXXXXXXX/proxy_arp")];
+  char *echo_argv[] = { "bash", "-c", echo, NULL };
+  char *route_argv[] = { "route", "add", "-host", addr, "dev", dev, NULL };
+  char *arp_argv[] = { "arp", "-Ds", addr, "eth0",  "pub", NULL };
+
+  if(!is_a_device(dev)){
+    add_output(output, "Device doesn't contain only alphanumeric characters\n",
+	       -1);
+    return(-1);
+  }
+  if(do_exec(route_argv, need_route, output)) return(-1);
+  snprintf(echo, sizeof(echo) - 1, 
+	   "echo 1 > /proc/sys/net/ipv4/conf/%.9s/proxy_arp", dev);
+  do_exec(echo_argv, 0, output);
+  if(netmask) local_net_do(arp_argv, 3, addr, netmask, dev, output);
+  else do_exec(arp_argv, 0, output);
+  return(0);
+}
+
+int no_route_and_arp(char *dev, char *addr, char *netmask, 
+		     struct output *output)
+{
+  char echo[sizeof("echo 0 > /proc/sys/net/ipv4/conf/XXXXXXXXX/proxy_arp")];
+  char *no_echo_argv[] = { "bash", "-c", echo, NULL };
+  char *no_route_argv[] = { "route", "del", "-host", addr, "dev", dev, NULL };
+  char *no_arp_argv[] = { "arp", "-i", "eth0", "-d", addr, "pub", NULL };
+
+  if(!is_a_device(dev)){
+    add_output(output, "Device doesn't contain only alphanumeric characters\n",
+	       -1);
+    return(-1);
+  }
+  do_exec(no_route_argv, 0, output);
+  snprintf(echo, sizeof(echo) - 1, 
+	   "echo 0 > /proc/sys/net/ipv4/conf/%.9s/proxy_arp", dev);
+  do_exec(no_echo_argv, 0, output);
+  if(netmask) local_net_do(no_arp_argv, 2, addr, netmask, dev, output);
+  else do_exec(no_arp_argv, 0, output);
+  return(0);
+}
+
+void forward_ip(struct output *output)
+{
+  char *forw_argv[] = { "bash",  "-c", 
+			"echo 1 > /proc/sys/net/ipv4/ip_forward", NULL };
+  do_exec(forw_argv, 0, output);
+}
+
+void address_change(enum change_type what, unsigned char *addr_str, char *dev, 
+		    unsigned char *netmask_str, struct output *output)
+{
+  char addr[sizeof("255.255.255.255\0")];
+  char netmask[sizeof("255.255.255.255\0")], *n = NULL;
+
+  snprintf(addr, sizeof(addr) - 1, "%d.%d.%d.%d", addr_str[0], addr_str[1], 
+	   addr_str[2], addr_str[3]);
+  if(netmask_str != NULL){
+    snprintf(netmask, sizeof(netmask) - 1, "%d.%d.%d.%d", netmask_str[0], 
+	     netmask_str[1], netmask_str[2], netmask_str[3]);
+    n = netmask;
+  }
+  switch(what){
+  case ADD_ADDR:
+    route_and_arp(dev, addr, n, 0, output);
+    break;
+  case DEL_ADDR:
+    no_route_and_arp(dev, addr, n, output);
+    break;
+  default:
+    fprintf(stderr, "address_change - bad op : %d\n", what);
+    return;
+  }
+}
+
+/* This is a routine to do a 'mknod' on the /dev/tap<n> if possible:
+ * Return: 0 is ok, -1=already open, etc.
+ */
+
+int mk_node(char *devname, int major, int minor)
+{
+  struct stat statval;
+  int retval;
+
+  /* first do a stat on the node to see whether it exists and we
+   * had some other reason to fail:
+   */
+  retval = stat(devname, &statval);
+  if(retval == 0) return(0);
+  else if(errno != ENOENT){
+    /* it does exist. We are just going to return -1, 'cause there
+     * was some other problem in the open :-(.
+     */
+    return -1;
+  }
+
+  /* It doesn't exist. We can create it. */
+
+  return(mknod(devname, S_IFCHR|S_IREAD|S_IWRITE, makedev(major, minor)));
+}
+
+void add_address_v4(int argc, char **argv)
+{
+  struct output output = INIT_OUTPUT;
+  
+  if(setreuid(0, 0) < 0){
+    output_errno(&output, "setreuid");
+    exit(1);
+  }
+  route_and_arp(argv[0], argv[1], argv[2], 0, &output);
+  write_output(1, &output);
+}
+
+void del_address_v4(int argc, char **argv)
+{
+  struct output output = INIT_OUTPUT;
+  
+  if(setreuid(0, 0) < 0){
+    output_errno(&output, "setreuid");
+    exit(1);
+  }
+  no_route_and_arp(argv[0], argv[1], argv[2], &output);
+  write_output(1, &output);
+}
+
+void change_addr(char *op, char *dev, char *address, char *netmask,
+		 struct output *output)
+{
+  if(setreuid(0, 0) < 0){
+    output_errno(output, "setreuid");
+    exit(1);
+  }
+  if(!strcmp(op, "add")) route_and_arp(dev, address, netmask, 0, output);
+  else no_route_and_arp(dev, address, netmask, output);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/host.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,27 @@
+/* Copyright 2001 Jeff Dike
+ * Licensed under the GPL
+ */
+
+#ifndef __HOST_H
+#define __HOST_H
+
+#include "output.h"
+
+enum change_type { ADD_ADDR, DEL_ADDR };
+
+extern int do_exec(char **args, int need_zero, struct output *output);
+extern int route_and_arp(char *dev, char *addr, char *netmask, int need_route, 
+			 struct output *output);
+extern int no_route_and_arp(char *dev, char *addr, char *netmask, 
+			    struct output *output);
+extern void forward_ip(struct output *output);
+
+extern void address_change(enum change_type what, unsigned char *addr_str, 
+			   char *dev, unsigned char *netmask, 
+			   struct output *output);
+extern int mk_node(char *devname, int major, int minor);
+extern void change_addr(char *op, char *dev, char *address, char *netmask,
+			struct output *output);
+extern int is_a_device(char *dev);
+
+#endif

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,71 @@
+/* Copyright 2001 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include "output.h"
+
+void write_output(int fd, struct output *output)
+{
+  if(output == NULL) return;
+  if(write(fd, &output->used, sizeof(output->used)) != sizeof(output->used)){
+    perror("write_output : write of length failed");
+    exit(1);
+  }
+  if(write(fd, output->buffer, output->used) != output->used){
+    perror("write_output : write of data failed");
+    exit(1);
+  }
+  output->used = 0;
+}
+
+void add_output(struct output *output, char *new, int len)
+{
+  int n, start;
+
+  if(output == NULL){
+    fprintf(stderr, "%s", new);
+    return;
+  }
+
+  if(len == -1) len = strlen(new);
+  n = len;
+  if(output->used == 0) n++;
+  if(output->used + n > output->total){
+    output->total = output->used + n;
+    output->total = (output->total + 4095) & ~4095;
+    if(output->buffer == NULL){
+      if((output->buffer = malloc(output->total)) == NULL){
+	perror("mallocing new output buffer");
+	*output = ((struct output) { 0, 0, NULL});
+	return;
+      }
+    }
+    else if((output->buffer = realloc(output->buffer, output->total)) == NULL){
+	perror("reallocing new output buffer");
+	*output = ((struct output) { 0, 0, NULL});
+	return;
+    }
+  }
+  if(output->used == 0) start = 0;
+  else start = output->used - 1;
+  strncpy(&output->buffer[start], new, len);
+  output->used += n;
+  output->buffer[output->used - 1] = '\0';
+}
+
+void output_errno(struct output *output, char *str)
+{
+  if(output == NULL) perror(str);
+  else {
+    add_output(output, str, -1);
+    add_output(output, ": ", -1);
+    add_output(output, strerror(errno), -1);
+    add_output(output, "\n", -1);
+  }
+}
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/output.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,20 @@
+/* Copyright 2001 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#ifndef __OUTPUT_H
+#define __OUTPUT_H
+
+struct output {
+  int total;
+  int used;
+  char *buffer;
+};
+
+#define INIT_OUTPUT { 0, 0, NULL }
+
+extern void write_output(int fd, struct output *output);
+extern void add_output(struct output *output, char *new, int len);
+extern void output_errno(struct output *output, char *str);
+
+#endif

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/slip.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/slip.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/slip.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,146 @@
+/* Copyright 2001, 2002 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/ioctl.h>
+#include "host.h"
+#include "output.h"
+
+static void slip_up(int fd, char *gate_addr, char *remote_addr, 
+		    char *netmask, struct output *output)
+{
+  char slip_name[sizeof("slxxxx\0")];
+  char *up_argv[] = { "ifconfig", slip_name, gate_addr, "mtu", "1500", "up", 
+		      NULL };
+  int disc, sencap, n;
+  
+  disc = N_SLIP;
+  if((n = ioctl(fd, TIOCSETD, &disc)) < 0){
+    output_errno(output, "Setting slip line discipline");
+    write_output(1, output);
+    exit(1);
+  }
+  sencap = 0;
+  if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
+    output_errno(output, "Setting slip encapsulation");
+    write_output(1, output);
+    exit(1);
+  }
+  snprintf(slip_name, sizeof(slip_name) - 1, "sl%d", n);
+  if(do_exec(up_argv, 1, output)){
+    write_output(1, output);
+    exit(1);
+  }
+  forward_ip(output);
+  if(remote_addr != NULL)
+    route_and_arp(slip_name, remote_addr, netmask, 0, output);
+}
+
+static void slip_down(char *dev, char *remote_addr, char *netmask,
+		      struct output *output)
+{
+  char *down_argv[] = { "ifconfig", dev, "0.0.0.0", "down", NULL };
+
+  if(remote_addr != NULL)
+    no_route_and_arp(dev, remote_addr, netmask, output);
+  if(do_exec(down_argv, 1, output)){
+    write_output(1, output);
+    exit(1);
+  }
+}
+
+static void slip_name(int fd, char *name, struct output *output)
+{
+  if(ioctl(fd, SIOCGIFNAME, name) < 0){
+    output_errno(output, "Getting slip line discipline");
+    write_output(1, output);
+    exit(1);
+  }
+}
+
+void slip_v0_v2(int argc, char **argv)
+{
+  char *op = argv[0], dev[sizeof("slnnnnn\0")];
+
+  if(setreuid(0, 0) < 0){
+    perror("slip - setreuid failed");
+    exit(1);
+  }
+  
+  if(!strcmp(op, "up")) 
+    slip_up(atoi(argv[1]), argv[2], argv[3], NULL, NULL);
+  else if(!strcmp(op, "down")){
+    slip_name(atoi(argv[1]), dev, NULL);
+    slip_down(dev, argv[2], NULL, NULL);
+  }
+  else {
+    printf("slip - Unknown op '%s'\n", op);
+    exit(1);
+  }
+}
+
+void slip_v3(int argc, char **argv)
+{
+  struct output output = INIT_OUTPUT;
+  char *op = argv[0], dev[sizeof("slnnnnn\0")];
+
+  if(setreuid(0, 0) < 0){
+    output_errno(&output, "slip - setreuid failed");
+    exit(1);
+  }
+
+  if(!strcmp(op, "up")) 
+    slip_up(atoi(argv[1]), argv[2], argv[3], NULL, &output);
+  else if(!strcmp(op, "down")){
+    slip_name(atoi(argv[1]), dev, &output);
+    slip_down(dev, argv[2], NULL, &output);
+  }
+  else {
+    printf("slip - Unknown op '%s'\n", op);
+    exit(1);
+  }
+  write_output(1, &output);
+}
+
+void slip_v4(int argc, char **argv)
+{
+  struct output output = INIT_OUTPUT;
+  char *op;
+
+  if(setreuid(0, 0) < 0){
+    output_errno(&output, "slip - setreuid failed");
+    exit(1);
+  }
+
+  if(argc < 1){
+    add_output(&output, "uml_net : too few arguments to slip_v4\n", -1);
+    write_output(1, &output);
+    exit(1);
+  }
+
+  op = argv[0];
+  if(argc < 2){
+      add_output(&output, "uml_net : too few arguments to slip_v4\n", -1);
+      write_output(1, &output);
+      exit(1);
+  }
+    
+  if(!strcmp(op, "up")){
+    slip_up(0, argv[1], NULL, NULL, &output);
+  }
+  else if(!strcmp(op, "down")){
+    slip_down(argv[1], NULL, NULL, &output);
+  }
+  else {
+    printf("slip - Unknown op '%s'\n", op);
+    exit(1);
+  }
+  write_output(1, &output);
+}
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/tuntap.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/tuntap.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/tuntap.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,169 @@
+/* Copyright 2001 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <net/if.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/uio.h>
+#include <linux/if_tun.h>
+#include "host.h"
+#include "output.h"
+
+static int do_tuntap_up(char *gate_addr, struct output *output, 
+			struct ifreq *ifr)
+{
+  int tap_fd;
+  char *ifconfig_argv[] = { "ifconfig", ifr->ifr_name, gate_addr, "netmask", 
+			    "255.255.255.255", "up", NULL };
+  char *insmod_argv[] = { "modprobe", "tun", NULL };
+
+  if(setreuid(0, 0) < 0){
+    output_errno(output, "setreuid to root failed : ");
+    return(-1);
+  }
+
+  /* XXX hardcoded dir name and perms */
+  umask(0);
+  mkdir("/dev/net", 0755);
+
+  /* #includes for MISC_MAJOR and TUN_MINOR bomb in userspace */
+  mk_node("/dev/net/tun", 10, 200);
+
+  do_exec(insmod_argv, 0, output);
+  
+  if((tap_fd = open("/dev/net/tun", O_RDWR)) < 0){
+    output_errno(output, "Opening /dev/net/tun failed : ");
+    return(-1);
+  }
+  memset(ifr, 0, sizeof(*ifr));
+  ifr->ifr_flags = IFF_TAP | IFF_NO_PI;
+  ifr->ifr_name[0] = '\0';
+  if(ioctl(tap_fd, TUNSETIFF, (void *) ifr) < 0){
+    output_errno(output, "TUNSETIFF : ");
+    return(-1);
+  }
+
+  if((*gate_addr != '\0') && do_exec(ifconfig_argv, 1, output))
+    return(-1);
+  forward_ip(output);
+  return(tap_fd);
+}
+
+static void tuntap_up(int fd, int argc, char **argv)
+{
+  struct ifreq ifr;
+  struct msghdr msg;
+  struct cmsghdr *cmsg;
+  struct output output = INIT_OUTPUT;
+  struct iovec iov[2];
+  int tap_fd, *fd_ptr;
+  char anc[CMSG_SPACE(sizeof(tap_fd))];
+  char *gate_addr;
+
+  msg.msg_control = NULL;
+  msg.msg_controllen = 0;
+
+  iov[0].iov_base = NULL;
+  iov[0].iov_len = 0;
+
+  if(argc < 1){
+    add_output(&output, "Too few arguments to tuntap_up\n", -1);
+    goto out;
+  }
+
+  gate_addr = argv[0];
+  if((tap_fd = do_tuntap_up(gate_addr, &output, &ifr)) > 0){
+    iov[0].iov_base = ifr.ifr_name;
+    iov[0].iov_len = IFNAMSIZ;
+
+    msg.msg_control = anc;
+    msg.msg_controllen = sizeof(anc);
+  
+    cmsg = CMSG_FIRSTHDR(&msg);
+    cmsg->cmsg_level = SOL_SOCKET;
+    cmsg->cmsg_type = SCM_RIGHTS;
+    cmsg->cmsg_len = CMSG_LEN(sizeof(tap_fd));
+
+    msg.msg_controllen = cmsg->cmsg_len;
+
+    fd_ptr = (int *) CMSG_DATA(cmsg);
+    *fd_ptr = tap_fd;
+  }
+
+ out:
+  iov[1].iov_base = output.buffer;
+  iov[1].iov_len = output.used;
+
+  msg.msg_name = NULL;
+  msg.msg_namelen = 0;
+  msg.msg_iov = iov;
+  msg.msg_iovlen = sizeof(iov)/sizeof(iov[0]);
+  msg.msg_flags = 0;
+
+  if(sendmsg(fd, &msg, 0) < 0){
+    perror("sendmsg");
+    exit(1);
+  }
+}
+
+void tuntap_v2(int argc, char **argv)
+{
+  char *op = argv[0];
+
+  if(!strcmp(op, "up")) tuntap_up(atoi(argv[2]), argc - 3, argv + 3);
+  else if(!strcmp(op, "add") || !strcmp(op, "del"))
+    change_addr(argv[1], argv[2], argv[3], NULL, NULL);
+  else {
+    fprintf(stderr, "Bad tuntap op : '%s'\n", op);
+    exit(1);
+  }
+}
+
+void tuntap_v3(int argc, char **argv)
+{
+  char *op = argv[0];
+  struct output output = INIT_OUTPUT;
+
+  if(!strcmp(op, "up")) tuntap_up(1, argc - 2, argv + 2);
+  else if(!strcmp(op, "add") || !strcmp(op, "del"))
+    change_addr(op, argv[1], argv[2], NULL, &output);
+  else {
+    fprintf(stderr, "Bad tuntap op : '%s'\n", op);
+    exit(1);
+  }
+  write_output(1, &output);
+}
+
+void tuntap_v4(int argc, char **argv)
+{
+  char *op;
+  struct output output = INIT_OUTPUT;
+
+  if(argc < 1){
+    add_output(&output, "uml_net : too few arguments to tuntap_v4\n", -1);
+    write_output(1, &output);
+    exit(1);
+  }
+  op = argv[0];
+  if(!strcmp(op, "up")) tuntap_up(1, argc - 1, argv + 1);
+  else if(!strcmp(op, "add") || !strcmp(op, "del")){
+    if(argc < 4)
+      add_output(&output, "uml_net : too few arguments to tuntap "
+		 "change_addr\n", -1);
+    else change_addr(op, argv[1], argv[2], argv[3], &output);
+    write_output(1, &output);
+  }
+  else {
+    fprintf(stderr, "Bad tuntap op : '%s'\n", op);
+    exit(1);
+  }
+}
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/uml_net.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/uml_net.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_net/uml_net.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,139 @@
+/* Copyright 2001 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+
+#define CURRENT_VERSION (4)
+
+extern void ethertap_v0(int argc, char **argv);
+extern void ethertap_v1_v2(int argc, char **argv);
+extern void ethertap_v1_v2(int argc, char **argv);
+extern void ethertap_v3(int argc, char **argv);
+extern void ethertap_v4(int argc, char **argv);
+
+void (*ethertap_handlers[])(int argc, char **argv) = {
+  ethertap_v0, 
+  ethertap_v1_v2,
+  ethertap_v1_v2,
+  ethertap_v3,
+  ethertap_v4,
+};
+
+extern void slip_v0_v2(int argc, char **argv);
+extern void slip_v3(int argc, char **argv);
+extern void slip_v4(int argc, char **argv);
+
+void (*slip_handlers[])(int argc, char **argv) = { 
+  slip_v0_v2, 
+  slip_v0_v2,
+  slip_v0_v2, 
+  slip_v3, 
+  slip_v4, 
+};
+
+#ifdef TUNTAP
+
+extern void tuntap_v2(int argc, char **argv);
+extern void tuntap_v3(int argc, char **argv);
+extern void tuntap_v4(int argc, char **argv);
+
+void (*tuntap_handlers[])(int argc, char **argv) = {
+  NULL,
+  NULL,
+  tuntap_v2,
+  tuntap_v3,
+  tuntap_v4,
+};
+
+#endif
+
+extern void add_address_v4(int argc, char **argv);
+
+void (*add_handlers[])(int argc, char **argv) = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  add_address_v4,
+};
+
+extern void del_address_v4(int argc, char **argv);
+
+void (*del_handlers[])(int argc, char **argv) = {
+  NULL,
+  NULL,
+  NULL,
+  NULL,
+  del_address_v4,
+};
+
+static void handler(int sig)
+{
+}
+
+int main(int argc, char **argv)
+{
+  char *version = argv[1];
+  char *transport = argv[2];
+  void (**handlers)(int, char **);
+  struct sigaction sa;
+  char *out;
+  int n = 3;
+  unsigned int v;
+
+  if(sigaction(SIGCHLD, NULL, &sa) < 0){
+    perror("sigaction");
+    exit(1);
+  }
+  sa.sa_handler = handler;
+  sa.sa_flags &= ~SA_NOCLDWAIT;
+  sa.sa_flags |= SA_RESTART;
+  if(sigaction(SIGCHLD, &sa, NULL) < 0){
+    perror("sigaction");
+    exit(1);
+  }
+
+  if(argc < 3){
+    fprintf(stderr, 
+	    "uml_net : bad argument list - if you're running uml_net by\n"
+	    "hand, don't bother.  uml_net is run automatically by UML when\n"
+	    "necessary.\n");
+    exit(1);
+  }
+  setenv("PATH", "/bin:/usr/bin:/sbin:/usr/sbin", 1);
+  v = strtoul(version, &out, 0);
+  if(out != version){
+    if(v > CURRENT_VERSION){
+      fprintf(stderr, "Version mismatch - requested version %d, uml_net "
+	      "supports up to version %d\n", v, CURRENT_VERSION);
+      exit(1);
+    }
+  }
+  else {
+    v = 0;
+    transport = version;
+    n = 2;
+  }
+  if(!strcmp(transport, "ethertap")) handlers = ethertap_handlers;
+  else if(!strcmp(transport, "slip")) handlers = slip_handlers;
+#ifdef TUNTAP
+  else if(!strcmp(transport, "tuntap")) handlers = tuntap_handlers;
+#endif
+  else if(!strcmp(transport, "add")) handlers = add_handlers;
+  else if(!strcmp(transport, "del")) handlers = del_handlers;
+  else {
+    printf("Unknown transport : '%s'\n", transport);
+    exit(1);
+  }
+  if(handlers[v] != NULL) (*handlers[v])(argc - n, &argv[n]);
+  else {
+    printf("No version #%d handler for '%s'\n", v, transport);
+    exit(1);
+  }
+  return(0);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/.cvsignore
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/.cvsignore	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/.cvsignore	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,2 @@
+uml_switch
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,11 @@
+/.cvsignore/1.1/Fri Jan 11 05:21:31 2002//
+/switch.h/1.1/Sun Apr  7 17:57:12 2002//
+/tuntap.h/1.1/Wed Apr 10 11:21:56 2002//
+/port.h/1.1/Wed Apr 10 13:07:02 2002//
+/hash.h/1.2/Tue Apr  9 14:38:23 2002//
+/hash.c/1.3/Sat Apr 27 15:42:04 2002//
+/tuntap.c/1.2/Wed Apr 24 00:13:30 2002//
+/Makefile/1.10/Sat Feb  8 04:04:39 2003//
+/port.c/1.4/Wed Mar 12 15:19:03 2003//
+/uml_switch.c/1.11/Fri Aug 15 19:03:58 2003//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/uml_router

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,23 @@
+TUNTAP = $(shell [ -e /usr/include/linux/if_tun.h ] && echo -DTUNTAP)
+
+OBJS = hash.o port.o uml_switch.o 
+BIN = uml_switch
+CFLAGS = -g -Wall $(TUNTAP)
+
+BIN_DIR ?= /usr/bin
+
+ifneq ($(TUNTAP),)
+	OBJS += tuntap.o
+endif
+
+all : $(BIN)
+
+$(BIN) : $(OBJS)
+	$(CC) $(CFLAGS) -o $(BIN) $(OBJS)
+
+clean : 
+	rm -f $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -s $(BIN) $(DESTDIR)$(BIN_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/core
===================================================================
(Binary files differ)


Property changes on: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/core
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,175 @@
+/* Copyright 2002 Yon Uriarte and Jeff Dike
+ * Licensed under the GPL
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/signal.h>
+#include "switch.h"
+#include "hash.h"
+
+#define HASH_SIZE 128
+#define HASH_MOD 11
+
+struct hash_entry {
+  struct hash_entry *next;
+  struct hash_entry *prev;
+  time_t last_seen;
+  void *port;
+  unsigned char dst[ETH_ALEN];
+};
+
+static struct hash_entry *h[HASH_SIZE];
+
+static int calc_hash(char *src)
+{
+  return ((*(u_int32_t *) &src[0] % HASH_MOD) ^ src[4] ^ src[5] ) % HASH_SIZE ;
+}
+
+static struct hash_entry *find_entry(char *dst)
+{
+  struct hash_entry *e;
+  int k = calc_hash(dst);
+
+  for(e = h[k]; e; e = e->next){
+    if(!memcmp(&e->dst, dst, ETH_ALEN)) return(e);
+  }
+  return(NULL);  
+}
+
+void *find_in_hash(char *dst)
+{
+  struct hash_entry *e = find_entry(dst);
+  if(e == NULL) return(NULL);
+  return(e->port);
+}
+
+void insert_into_hash(char *src, void *port)
+{
+  struct hash_entry *new;
+  int k = calc_hash(src);
+
+  new = find_in_hash(src);
+  if(new != NULL) return;
+
+  new = malloc(sizeof(*new));
+  if(new == NULL){
+    perror("Failed to malloc hash entry");
+    return;
+  }
+
+  memcpy(&new->dst, src, ETH_ALEN );
+  if(h[k] != NULL) h[k]->prev = new;
+  new->next = h[k];
+  new->prev = NULL;
+  new->port = port;
+  new->last_seen = 0;
+  h[k] = new;
+}
+
+void update_entry_time(char *src)
+{
+  struct hash_entry *e;
+
+  e = find_entry(src);
+  if(e == NULL) return;
+  e->last_seen = time(NULL);
+}
+
+static void delete_hash_entry(struct hash_entry *old)
+{
+  int k = calc_hash(old->dst);
+
+  if(old->prev != NULL) old->prev->next = old->next;
+  if(old->next != NULL) old->next->prev = old->prev;
+  if(h[k] == old) h[k] = old->next;
+  free(old);
+}
+
+void delete_hash(char *dst)
+{
+  struct hash_entry *old = find_entry(dst);
+
+  if(old == NULL) return;
+  delete_hash_entry(old);
+}
+
+static void for_all_hash(void (*f)(struct hash_entry *, void *), void *arg)
+{
+  int i;
+  struct hash_entry *e, *next;
+
+  for(i = 0; i < HASH_SIZE; i++){
+    for(e = h[i]; e; e = next){
+      next = e->next;
+      (*f)(e, arg);
+    }
+  }
+}
+
+struct printer {
+  time_t now;
+  char *(*port_id)(void *);
+};
+
+static void print_hash_entry(struct hash_entry *e, void *arg)
+{
+  struct printer *p = arg;
+
+  printf("Hash: %d Addr: %02x:%02x:%02x:%02x:%02x:%02x to port: %s  " 
+	 "age %ld secs\n", calc_hash(e->dst),
+	 e->dst[0], e->dst[1], e->dst[2], e->dst[3], e->dst[4], e->dst[5],
+	 (*p->port_id)(e->port), (int) p->now - e->last_seen);
+}
+
+void print_hash(char *(*port_id)(void *))
+{
+  struct printer p = ((struct printer) { now : 		time(NULL),
+					 port_id :	port_id });
+
+  for_all_hash(print_hash_entry, &p);
+}
+
+#define GC_INTERVAL 2
+#define GC_EXPIRE 100
+
+static void gc(struct hash_entry *e, void *now)
+{
+  time_t t = *(time_t *) now;
+
+  if(e->last_seen + GC_EXPIRE < t)
+    delete_hash_entry(e);
+}
+
+static void sig_alarm(int sig)
+{
+  struct itimerval it;
+  time_t t = time(NULL);
+  for_all_hash(&gc, &t);
+
+  it.it_value.tv_sec = GC_INTERVAL;
+  it.it_value.tv_usec = 0 ;
+  it.it_interval.tv_sec = 0;
+  it.it_interval.tv_usec = 0 ;
+  setitimer(ITIMER_REAL, &it, NULL);
+}
+
+void hash_init(void)
+{
+  struct sigaction sa;
+
+  sa.sa_handler = sig_alarm;
+  sa.sa_flags = SA_RESTART;
+  if(sigaction(SIGALRM, &sa, NULL) < 0){
+    perror("Setting handler for SIGALRM");
+    return;
+  }
+  kill(getpid(), SIGALRM);
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/hash.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,15 @@
+/* Copyright 2002 Yon Uriarte and Jeff Dike
+ * Licensed under the GPL
+ */
+
+#ifndef __HASH_H__
+#define __HASH_H__
+
+extern void *find_in_hash(char *dst);
+extern void insert_into_hash(char *src, void *port);
+extern void delete_hash(char *dst);
+extern void print_hash(char *(*port_id)(void *));
+extern void update_entry_time(char *src);
+extern void hash_init(void);
+
+#endif

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,255 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "switch.h"
+#include "hash.h"
+#include "port.h"
+
+struct packet {
+  struct {
+    unsigned char dest[ETH_ALEN];
+    unsigned char src[ETH_ALEN];
+    unsigned char proto[2];
+  } header;
+  unsigned char data[1500];
+};
+
+struct port {
+  struct port *next;
+  struct port *prev;
+  int control;
+  void *data;
+  int data_len;
+  unsigned char src[ETH_ALEN];
+  void (*sender)(int fd, void *packet, int len, void *data);
+};
+
+static struct port *head = NULL;
+
+#define IS_BROADCAST(addr) ((addr[0] & 1) == 1)
+
+static void free_port(struct port *port)
+{
+  if(port->prev) port->prev->next = port->next;
+  else head = port->next;
+  if(port->next) port->next->prev = port->prev;
+  free(port);
+}
+
+void close_port(int fd)
+{
+  struct port *port;
+
+  for(port = head; port != NULL; port = port->next){
+    if(port->control == fd) break;
+  }
+  if(port == NULL){
+    fprintf(stderr, "No port associated with descriptor %d\n", fd);
+    return;
+  }
+  delete_hash(port->src);
+  free_port(port);
+}
+
+static void update_src(struct port *port, struct packet *p)
+{
+  struct port *last;
+
+  /* We don't like broadcast source addresses */
+  if(IS_BROADCAST(p->header.src)) return;  
+
+  last = find_in_hash(p->header.src);
+
+  if(port != last){
+    /* old value differs from actual input port */
+
+    printf(" Addr: %02x:%02x:%02x:%02x:%02x:%02x New port %d",
+	   p->header.src[0], p->header.src[1], p->header.src[2],
+	   p->header.src[3], p->header.src[4], p->header.src[5],
+	   port->control);
+
+    if(last != NULL){
+      printf(" old port %d", last->control);
+      delete_hash(p->header.src);
+    }
+    printf("\n");
+
+    memcpy(port->src, p->header.src, sizeof(port->src));
+    insert_into_hash(p->header.src, port);
+  }
+  update_entry_time(p->header.src);
+}
+
+static void send_dst(struct port *port, struct packet *packet, int len, 
+		     int hub)
+{
+  struct port *target, *p;
+
+  target = find_in_hash(packet->header.dest);
+  if((target == NULL) || IS_BROADCAST(packet->header.dest) || hub){
+    if((target == NULL) && !IS_BROADCAST(packet->header.dest)){
+      printf("unknown Addr: %02x:%02x:%02x:%02x:%02x:%02x from port ",
+	     packet->header.src[0], packet->header.src[1], 
+	     packet->header.src[2], packet->header.src[3], 
+	     packet->header.src[4], packet->header.src[5]);
+      if(port == NULL) printf("UNKNOWN\n");
+      else printf("%d\n", port->control);
+    } 
+
+    /* no cache or broadcast/multicast == all ports */
+    for(p = head; p != NULL; p = p->next){
+      /* don't send it back the port it came in */
+      if(p == port) continue;
+
+      (*p->sender)(p->control, packet, len, p->data);
+    }
+  }
+  else (*target->sender)(target->control, packet, len, target->data);
+}
+
+static void handle_data(int fd, int hub, struct packet *packet, int len, 
+			void *data, int (*matcher)(int port_fd, int data_fd, 
+						   void *port_data,
+						   int port_data_len, 
+						   void *data))
+{
+  struct port *p;
+
+  for(p = head; p != NULL; p = p->next){
+    if((*matcher)(p->control, fd, p->data, p->data_len, data)) break;
+  }
+  
+  /* if we have an incoming port (we should) */
+  if(p != NULL) update_src(p, packet);
+  else printf("Unknown connection for packet, shouldn't happen.\n");
+
+  send_dst(p, packet, len, hub);  
+}
+
+static int match_tap(int port_fd, int data_fd, void *port_data, 
+		     int port_data_len, void *data)
+{
+  return(port_fd == data_fd);
+}
+
+void handle_tap_data(int fd, int hub)
+{
+  struct packet packet;
+  int len;
+
+  len = read(fd, &packet, sizeof(packet));
+  if(len < 0){
+    if(errno != EAGAIN) perror("Reading tap data");
+    return;
+  }
+  handle_data(fd, hub, &packet, len, NULL, match_tap);
+}
+
+int setup_port(int fd, void (*sender)(int fd, void *packet, int len, 
+				      void *data), void *data, int data_len)
+{
+  struct port *port;
+
+  port = malloc(sizeof(struct port));
+  if(port == NULL){
+    perror("malloc");
+    return(-1);
+  }
+  port->next = head;
+  if(head) head->prev = port;
+  port->prev = NULL;
+  port->control = fd;
+  port->data = data;
+  port->data_len = data_len;
+  port->sender = sender;
+  head = port;
+  printf("New connection\n");
+  return(0);
+}
+
+struct sock_data {
+  int fd;
+  struct sockaddr_un sock;
+};
+
+static void send_sock(int fd, void *packet, int len, void *data)
+{
+  struct sock_data *mine = data;
+  int err;
+  
+  err = sendto(mine->fd, packet, len, 0, (struct sockaddr *) &mine->sock,
+	       sizeof(mine->sock));
+  if(err != len){
+    fprintf(stderr, "send_sock sending to fd %d ", mine->fd);
+    perror("");
+  }
+}
+
+static int match_sock(int port_fd, int data_fd, void *port_data, 
+		      int port_data_len, void *data)
+{
+  struct sock_data *mine = data;
+  struct sock_data *port = port_data;
+
+  if(port_data_len != sizeof(*mine)) return(0);
+  return(!memcmp(&port->sock, &mine->sock, sizeof(mine->sock)));
+}
+
+void handle_sock_data(int fd, int hub)
+{
+  struct packet packet;
+  struct sock_data data;
+  int len, socklen = sizeof(data.sock);
+
+  len = recvfrom(fd, &packet, sizeof(packet), 0, 
+		 (struct sockaddr *) &data.sock, &socklen);
+  if(len < 0){
+    if(errno != EAGAIN) perror("handle_sock_data");
+    return;
+  }
+  data.fd = fd;
+
+  handle_data(fd, hub, &packet, len, &data, match_sock);
+}
+
+int setup_sock_port(int fd, struct sockaddr_un *name, int data_fd)
+{
+  struct sock_data *data;
+
+  data = malloc(sizeof(*data));
+  if(data == NULL){
+    perror("setup_sock_port");
+    return(-1);
+  }
+  *data = ((struct sock_data) { fd : 	data_fd,
+				sock :	*name });
+  return(setup_port(fd, send_sock, data, sizeof(*data)));
+}
+
+static void service_port(struct port *port)
+{
+  int n;
+  char c;
+
+  n = read(port->control, &c, sizeof(c));
+  if(n < 0) perror("Reading request");
+  else if(n == 0) printf("Disconnect\n");
+  else printf("Bad request\n");  
+}
+
+int handle_port(int fd)
+{
+  struct port *p;
+
+  for(p = head; p != NULL; p = p->next){
+    if(p->control == fd){
+      service_port(p);
+      return(0);
+    }
+  }
+  return(1);
+}
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/port.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,20 @@
+/* Copyright 2002 Jeff Dike
+ * Licensed under the GPL
+ */
+
+#ifndef __PORT_H__
+#define __PORT_H__
+
+#include <sys/socket.h>
+#include <sys/un.h>
+
+extern int handle_port(int fd);
+extern void close_port(int fd);
+extern int setup_sock_port(int fd, struct sockaddr_un *name, int data_fd);
+extern int setup_port(int fd, void (*sender)(int fd, void *packet, int len, 
+					     void *data), void *data, 
+		      int data_len);
+extern void handle_tap_data(int fd, int hub);
+extern void handle_sock_data(int fd, int hub);
+
+#endif

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/switch.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/switch.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/switch.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,10 @@
+/* Copyright 2002 Jeff Dike
+ * Licensed under the GPL
+ */
+
+#ifndef __SWITCH_H__
+#define __SWITCH_H__
+
+#define ETH_ALEN 6
+
+#endif

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/if_tun.h>
+#include "port.h"
+
+static void send_tap(int fd, void *packet, int len, void *unused)
+{
+  int n;
+
+  n = write(fd, packet, len);
+  if(n != len){
+    if(errno != EAGAIN) perror("send_tap");
+  }
+}
+
+int open_tap(char *dev)
+{
+  struct ifreq ifr;
+  int fd, err;
+
+  if((fd = open("/dev/net/tun", O_RDWR)) < 0){
+    perror("Failed to open /dev/net/tun");
+    return(-1);
+  }
+  memset(&ifr, 0, sizeof(ifr));
+  ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+  strncpy(ifr.ifr_name, dev, sizeof(ifr.ifr_name) - 1);
+  if(ioctl(fd, TUNSETIFF, (void *) &ifr) < 0){
+    perror("TUNSETIFF failed");
+    close(fd);
+    return(-1);
+  }
+  err = setup_port(fd, send_tap, NULL, 0);
+  if(err) return(err);
+  return(fd);
+}
+

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.h
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.h	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/tuntap.h	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,11 @@
+/* Copyright 2002 Jeff Dike
+ * Licensed under the GPL
+ */
+
+#ifndef __TUNTAP_H__
+#define __TUNTAP_H__
+
+extern int open_tap(char *dev);
+extern void handle_tap(int fd, int hub);
+
+#endif

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/uml_switch.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/uml_switch.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_router/uml_switch.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,568 @@
+/* Copyright 2001, 2002 Jeff Dike and others
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/poll.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include "switch.h"
+#include "port.h"
+#include "hash.h"
+#ifdef TUNTAP
+#include "tuntap.h"
+#endif
+
+#ifdef notdef
+#include <stddef.h>
+#endif
+
+static int hub = 0;
+static int compat_v0 = 0;
+
+enum request_type { REQ_NEW_CONTROL };
+
+struct request_v0 {
+  enum request_type type;
+  union {
+    struct {
+      unsigned char addr[ETH_ALEN];
+      struct sockaddr_un name;
+    } new_control;
+  } u;
+};
+
+#define SWITCH_MAGIC 0xfeedface
+
+struct request_v1 {
+  uint32_t magic;
+  enum request_type type;
+  union {
+    struct {
+      unsigned char addr[ETH_ALEN];
+      struct sockaddr_un name;
+    } new_control;
+  } u;
+};
+
+struct request_v2 {
+  uint32_t magic;
+  uint32_t version;
+  enum request_type type;
+  struct sockaddr_un sock;
+};
+
+struct reply_v2 {
+  unsigned char mac[ETH_ALEN];
+  struct sockaddr_un sock;
+};
+
+struct request_v3 {
+  uint32_t magic;
+  uint32_t version;
+  enum request_type type;
+  struct sockaddr_un sock;
+};
+
+union request {
+  struct request_v0 v0;
+  struct request_v1 v1;
+  struct request_v2 v2;
+  struct request_v3 v3;
+};
+
+static char *ctl_socket = "/tmp/uml.ctl";
+
+static char *data_socket = NULL;
+static struct sockaddr_un data_sun;
+
+static void cleanup(void)
+{
+  if(unlink(ctl_socket) < 0){
+    printf("Couldn't remove control socket '%s' : ", ctl_socket);
+    perror("");
+  }
+  if((data_socket != NULL) && (unlink(data_socket) < 0)){
+    printf("Couldn't remove data socket '%s' : ", data_socket);
+    perror("");
+  }
+}
+
+static struct pollfd *fds = NULL;
+static int maxfds = 0;
+static int nfds = 0;
+
+static void add_fd(int fd)
+{
+  struct pollfd *p;
+
+  if(nfds == maxfds){
+    maxfds = maxfds ? 2 * maxfds : 4;
+    if((fds = realloc(fds, maxfds * sizeof(struct pollfd))) == NULL){
+      perror("realloc");
+      cleanup();
+      exit(1);
+    }
+  }
+  p = &fds[nfds++];
+  p->fd = fd;
+  p->events = POLLIN;
+}
+
+static void remove_fd(int fd)
+{
+  int i;
+
+  for(i = 0; i < nfds; i++){
+    if(fds[i].fd == fd) break;
+  }
+  if(i == nfds){
+    fprintf(stderr, "remove_fd : Couldn't find descriptor %d\n", fd);
+  }
+  memmove(&fds[i], &fds[i + 1], (maxfds - i - 1) * sizeof(struct pollfd));
+  nfds--;
+}
+
+static void sig_handler(int sig)
+{
+  printf("Caught signal %d, cleaning up and exiting\n", sig);
+  cleanup();
+  signal(sig, SIG_DFL);
+  kill(getpid(), sig);
+}
+
+static void close_descriptor(int fd)
+{
+  remove_fd(fd);
+  close(fd);
+  close_port(fd);
+}
+
+static void new_port_v0(int fd, struct request_v0 *req, int data_fd)
+{
+  switch(req->type){
+  case REQ_NEW_CONTROL:
+    setup_sock_port(fd, &req->u.new_control.name, data_fd);
+    break;
+  default:
+    printf("Bad request type : %d\n", req->type);
+    close_descriptor(fd);
+  }
+}
+
+static void new_port_v1_v3(int fd, enum request_type type, 
+			   struct sockaddr_un *sock, int data_fd)
+{
+  int n, err;
+
+  switch(type){
+  case REQ_NEW_CONTROL:
+    err = setup_sock_port(fd, sock, data_fd);
+    if(err) return;
+    n = write(fd, &data_sun, sizeof(data_sun));
+    if(n != sizeof(data_sun)){
+      perror("Sending data socket name");
+      close_descriptor(fd);
+    }
+    break;
+  default:
+    printf("Bad request type : %d\n", type);
+    close_descriptor(fd);
+  }
+}
+
+static void new_port_v2(int fd, struct request_v2 *req, int data_fd)
+{
+  fprintf(stderr, "Version 2 is not supported\n");
+  close_descriptor(fd);
+}
+
+static void new_port(int fd, int data_fd)
+{
+  union request req;
+  int len;
+
+  len = read(fd, &req, sizeof(req));
+  if(len < 0){
+    if(errno != EAGAIN){
+      perror("Reading request");
+      close_descriptor(fd);
+    }
+    return;
+  }
+  else if(len == 0){
+    printf("EOF from new port\n");
+    close_descriptor(fd);
+    return;
+  }
+  if(req.v1.magic == SWITCH_MAGIC){
+    if(req.v2.version == 2) new_port_v2(fd, &req.v2, data_fd);
+    if(req.v3.version == 3) 
+      new_port_v1_v3(fd, req.v3.type, &req.v3.sock, data_fd);
+    else if(req.v2.version > 2) 
+      fprintf(stderr, "Request for a version %d port, which this "
+	      "uml_switch doesn't support\n", req.v2.version);
+    else new_port_v1_v3(fd, req.v1.type, &req.v1.u.new_control.name, data_fd);
+  }
+  else new_port_v0(fd, &req.v0, data_fd);
+}
+
+void accept_connection(int fd)
+{
+  struct sockaddr addr;
+  int len, new;
+
+  len = sizeof(addr);
+  new = accept(fd, &addr, &len);
+  if(new < 0){
+    perror("accept");
+    return;
+  }
+  if(fcntl(new, F_SETFL, O_NONBLOCK) < 0){
+    perror("fcntl - setting O_NONBLOCK");
+    close(new);
+    return;
+  }
+  add_fd(new);
+}
+
+int still_used(struct sockaddr_un *sun)
+{
+  int test_fd, ret = 1;
+
+  if((test_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){
+    perror("socket");
+    exit(1);
+  }
+  if(connect(test_fd, (struct sockaddr *) sun, sizeof(*sun)) < 0){
+    if(errno == ECONNREFUSED){
+      if(unlink(sun->sun_path) < 0){
+	fprintf(stderr, "Failed to removed unused socket '%s': ", 
+		sun->sun_path);
+	perror("");
+      }
+      ret = 0;
+    }
+    else perror("connect");
+  }
+  close(test_fd);
+  return(ret);
+}
+
+int bind_socket(int fd, const char *name, struct sockaddr_un *sock_out)
+{
+  struct sockaddr_un sun;
+
+  sun.sun_family = AF_UNIX;
+  strncpy(sun.sun_path, name, sizeof(sun.sun_path));
+  
+  if(bind(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){
+    if((errno == EADDRINUSE) && still_used(&sun)) return(EADDRINUSE);
+    else if(bind(fd, (struct sockaddr *) &sun, sizeof(sun)) < 0){
+      perror("bind");
+      return(EPERM);
+    }
+  }
+  if(sock_out != NULL) *sock_out = sun;
+  return(0);
+}
+
+static char *prog;
+
+void bind_sockets_v0(int ctl_fd, const char *ctl_name, 
+		     int data_fd, const char *data_name)
+{
+  int ctl_err, ctl_present = 0, ctl_used = 0;
+  int data_err, data_present = 0, data_used = 0;
+  int try_remove_ctl, try_remove_data;
+
+  ctl_err = bind_socket(ctl_fd, ctl_name, NULL);
+  if(ctl_err != 0) ctl_present = 1;
+  if(ctl_err == EADDRINUSE) ctl_used = 1;
+
+  data_err = bind_socket(data_fd, data_name, &data_sun);
+  if(data_err != 0) data_present = 1;
+  if(data_err == EADDRINUSE) data_used = 1;
+
+  if(!ctl_err && !data_err){
+    return;
+  }
+
+  try_remove_ctl = ctl_present;
+  try_remove_data = data_present;
+  if(ctl_present && ctl_used){
+    fprintf(stderr, "The control socket '%s' has another server "
+	    "attached to it\n", ctl_name);
+    try_remove_ctl = 0;
+  }
+  else if(ctl_present && !ctl_used)
+    fprintf(stderr, "The control socket '%s' exists, isn't used, but couldn't "
+	    "be removed\n", ctl_name);
+  if(data_present && data_used){
+    fprintf(stderr, "The data socket '%s' has another server "
+	    "attached to it\n", data_name);
+    try_remove_data = 0;
+  }
+  else if(data_present && !data_used)
+    fprintf(stderr, "The data socket '%s' exists, isn't used, but couldn't "
+	    "be removed\n", data_name);
+  if(try_remove_ctl || try_remove_data){
+    fprintf(stderr, "You can either\n");
+    if(try_remove_ctl && !try_remove_data) 
+      fprintf(stderr, "\tremove '%s'\n", ctl_socket);
+    else if(!try_remove_ctl && try_remove_data) 
+      fprintf(stderr, "\tremove '%s'\n", data_socket);
+    else fprintf(stderr, "\tremove '%s' and '%s'\n", ctl_socket, data_socket);
+    fprintf(stderr, "\tor rerun with different, unused filenames for "
+	    "sockets:\n");
+    fprintf(stderr, "\t\t%s -unix <control> <data>\n", prog);
+    fprintf(stderr, "\t\tand run the UMLs with "
+	    "'eth0=daemon,,unix,<control>,<data>\n");
+    exit(1);
+  }
+  else {
+    fprintf(stderr, "You should rerun with different, unused filenames for "
+	    "sockets:\n");
+    fprintf(stderr, "\t%s -unix <control> <data>\n", prog);
+    fprintf(stderr, "\tand run the UMLs with "
+	    "'eth0=daemon,,unix,<control>,<data>'\n");
+    exit(1);
+  }
+}
+
+void bind_data_socket(int fd, struct sockaddr_un *sun)
+{
+  struct {
+    char zero;
+    int pid;
+    int usecs;
+  } name;
+  struct timeval tv;
+
+  name.zero = 0;
+  name.pid = getpid();
+  gettimeofday(&tv, NULL);
+  name.usecs = tv.tv_usec;
+  sun->sun_family = AF_UNIX;
+  memcpy(sun->sun_path, &name, sizeof(name));
+  if(bind(fd, (struct sockaddr *) sun, sizeof(*sun)) < 0){
+    perror("Binding to data socket");
+    exit(1);
+  }
+}
+
+void bind_sockets(int ctl_fd, const char *ctl_name, int data_fd)
+{
+  int err, used;
+
+  err = bind_socket(ctl_fd, ctl_name, NULL);
+  if(err == 0){
+    bind_data_socket(data_fd, &data_sun);
+    return;
+  }
+  else if(err == EADDRINUSE) used = 1;
+  
+  if(used){
+    fprintf(stderr, "The control socket '%s' has another server "
+	    "attached to it\n", ctl_name);
+    fprintf(stderr, "You can either\n");
+    fprintf(stderr, "\tremove '%s'\n", ctl_name);
+    fprintf(stderr, "\tor rerun with a different, unused filename for a "
+	    "socket\n");
+  }
+  else
+    fprintf(stderr, "The control socket '%s' exists, isn't used, but couldn't "
+	    "be removed\n", ctl_name);
+  exit(1);
+}
+
+static void Usage(void)
+{
+  char *tap_str = "";
+
+#ifdef TUNTAP
+  tap_str = "[ -tap tap-device ]";
+#endif
+
+  fprintf(stderr, "Usage : %s [ -unix control-socket ] [ -hub ] %s\n"
+	  "or : %s -compat-v0 [ -unix control-socket data-socket ] "
+	  "[ -hub ] %s\n", prog, tap_str, prog, tap_str);
+
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  int connect_fd, data_fd, n, i, new, one = 1, daemonize = 0;
+  char *tap_dev = NULL;
+#ifdef TUNTAP
+  int tap_fd  = -1;
+#endif
+
+  prog = argv[0];
+  argv++;
+  argc--;
+  while(argc > 0){
+    if(!strcmp(argv[0], "-unix")){
+      if(argc < 2) 
+	Usage();
+      ctl_socket = argv[1];
+      argc -= 2;
+      argv += 2;
+      if(!compat_v0) 
+	continue;
+      if(argc < 1) 
+	Usage();
+      data_socket = argv[0];
+      argc--;
+      argv++;
+    }
+    else if(!strcmp(argv[0], "-tap")){
+#ifdef TUNTAP
+      if(argc < 2) 
+	Usage();
+      tap_dev = argv[1];
+      argv += 2;
+      argc -= 2;
+#else
+      fprintf(stderr, "-tap isn't supported since TUNTAP isn't enabled\n");
+      Usage();
+#endif      
+    }
+    else if(!strcmp(argv[0], "-hub")){
+      printf("%s will be a hub instead of a switch\n", prog);
+      hub = 1;
+      argc--;
+      argv++;
+    }
+    else if(!strcmp(argv[0], "-compat-v0")){
+      printf("Control protocol 0 compatibility\n");
+      compat_v0 = 1;
+      data_socket = "/tmp/uml.data";
+      argc--;
+      argv++;
+    }
+    else if(!strcmp(argv[0], "-daemon")){
+      daemonize = 1;
+      argc--;
+      argv++;
+    }
+    else Usage();
+  }
+
+  if((connect_fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0){
+    perror("socket");
+    exit(1);
+  }
+  if(setsockopt(connect_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, 
+		sizeof(one)) < 0){
+    perror("setsockopt");
+    exit(1);
+  }
+  if(fcntl(connect_fd, F_SETFL, O_NONBLOCK) < 0){
+    perror("Setting O_NONBLOCK on connection fd");
+    exit(1);
+  }
+  if((data_fd = socket(PF_UNIX, SOCK_DGRAM, 0)) < 0){
+    perror("socket");
+    exit(1);
+  }
+  if(fcntl(data_fd, F_SETFL, O_NONBLOCK) < 0){
+    perror("Setting O_NONBLOCK on data fd");
+    exit(1);
+  }
+
+  if(compat_v0) bind_sockets_v0(connect_fd, ctl_socket, data_fd, data_socket);
+  else bind_sockets(connect_fd, ctl_socket, data_fd);
+
+  if(listen(connect_fd, 15) < 0){
+    perror("listen");
+    exit(1);
+  }
+
+  if(signal(SIGINT, sig_handler) < 0)
+    perror("Setting handler for SIGINT");
+  hash_init();
+
+  if(compat_v0) 
+    printf("%s attached to unix sockets '%s' and '%s'", prog, ctl_socket,
+	   data_socket);
+  else printf("%s attached to unix socket '%s'", prog, ctl_socket);
+
+#ifdef TUNTAP
+  if(tap_dev != NULL)
+    printf(" tap device '%s'", tap_dev);
+#endif
+  printf("\n");
+
+  if(isatty(0))
+    add_fd(0);
+  add_fd(connect_fd);
+  add_fd(data_fd);
+
+#ifdef TUNTAP
+  if(tap_dev != NULL) tap_fd = open_tap(tap_dev);
+  if(tap_fd > -1) add_fd(tap_fd);
+#endif
+
+  if (daemonize && daemon(0, 1)) {
+    perror("daemon");
+    exit(1);
+  }
+
+  while(1){
+    char buf[128];
+
+    n = poll(fds, nfds, -1);
+    if(n < 0){
+      if(errno == EINTR) continue;
+      perror("poll");
+      break;
+    }
+    for(i = 0; i < nfds; i++){
+      if(fds[i].revents == 0) continue;
+      if(fds[i].fd == 0){
+	if(fds[i].revents & POLLHUP){
+	  printf("EOF on stdin, cleaning up and exiting\n");
+	  goto out;
+	}
+
+	n = read(0, buf, sizeof(buf));
+	if(n < 0){
+	  perror("Reading from stdin");
+	  break;
+	}
+	else if(n == 0){
+	  printf("EOF on stdin, cleaning up and exiting\n");
+	  goto out;
+	}
+      }
+      else if(fds[i].fd == connect_fd){
+	if(fds[i].revents & POLLHUP){
+	  printf("Error on connection fd\n");
+	  continue;
+	}
+	accept_connection(connect_fd);
+      }
+      else if(fds[i].fd == data_fd) handle_sock_data(data_fd, hub);
+#ifdef TUNTAP
+      else if(fds[i].fd == tap_fd) handle_tap_data(tap_fd, hub);
+#endif
+      else {
+	new = handle_port(fds[i].fd);
+	if(new) new_port(fds[i].fd, data_fd);
+	else close_descriptor(fds[i].fd);
+      }
+    }
+  }
+ out:
+  cleanup();
+  return 0;
+}

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,46 @@
+# Generated by RPM Workshop.  v0.1
+
+# Macro definitions
+%define ver    20040406
+%define rel    1
+
+Name:      uml_utilities
+Version:   %{ver}
+Release:   %{rel}
+Copyright: GPL
+Packager:  Someone
+URL:       http://user-mode-linux.sourceforge.net/index.html
+Source:    http://prdownloads.sourceforge.net/user-mode-linux/uml_utilities_%{ver}.tar.bz2
+BuildRoot: %{_tmppath}/%{name}-%{ver}-root
+Group:     System
+Summary: Utilities for user-mode linux kernel
+
+%description 
+This package contains the utilities for user-mode linux for networking, 
+COW, etc.
+
+
+%prep
+%setup -n tools
+
+%build
+make DESTDIR=$RPM_BUILD_ROOT
+
+%install
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%files
+%attr(755,root,root)			%{_bindir}/jailtest
+#%attr(755,root,root)			%{_bindir}/mkrootfs
+%attr(755,root,root)			%{_bindir}/tunctl
+%attr(755,root,root)			%{_bindir}/uml_mconsole
+%attr(755,root,root)			%{_bindir}/uml_moo
+%attr(4755,root,root)			%{_bindir}/uml_net
+%attr(755,root,root)			%{_bindir}/uml_switch
+%attr(755,root,root)		%dir	%{_libdir}/uml
+%attr(755,root,root)			%{_bindir}/uml_mkcow
+%attr(755,root,root)			%{_bindir}/uml_watchdog
+#%attr(755,root,root)			%{_libdir}/uml/functions
+%attr(755,root,root)			%{_libdir}/uml/port-helper
+
+%clean

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec.in
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec.in	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/uml_util.spec.in	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,46 @@
+# Generated by RPM Workshop.  v0.1
+
+# Macro definitions
+%define ver    __UMLVER__
+%define rel    1
+
+Name:      uml_utilities
+Version:   %{ver}
+Release:   %{rel}
+Copyright: GPL
+Packager:  Someone
+URL:       http://user-mode-linux.sourceforge.net/index.html
+Source:    http://prdownloads.sourceforge.net/user-mode-linux/uml_utilities_%{ver}.tar.bz2
+BuildRoot: %{_tmppath}/%{name}-%{ver}-root
+Group:     System
+Summary: Utilities for user-mode linux kernel
+
+%description 
+This package contains the utilities for user-mode linux for networking, 
+COW, etc.
+
+
+%prep
+%setup -n tools
+
+%build
+make DESTDIR=$RPM_BUILD_ROOT
+
+%install
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%files
+%attr(755,root,root)			%{_bindir}/jailtest
+#%attr(755,root,root)			%{_bindir}/mkrootfs
+%attr(755,root,root)			%{_bindir}/tunctl
+%attr(755,root,root)			%{_bindir}/uml_mconsole
+%attr(755,root,root)			%{_bindir}/uml_moo
+%attr(4755,root,root)			%{_bindir}/uml_net
+%attr(755,root,root)			%{_bindir}/uml_switch
+%attr(755,root,root)		%dir	%{_libdir}/uml
+%attr(755,root,root)			%{_bindir}/uml_mkcow
+%attr(755,root,root)			%{_bindir}/uml_watchdog
+#%attr(755,root,root)			%{_libdir}/uml/functions
+%attr(755,root,root)			%{_libdir}/uml/port-helper
+
+%clean

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/umlgdb/CVS

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,3 @@
+D/CVS////
+/Makefile/1.1/Sun Apr 14 20:37:39 2002//
+/umlgdb/1.3/Sat Nov  8 13:20:29 2003//

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/umlgdb

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,8 @@
+all :
+
+install :
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -m 755 umlgdb $(DESTDIR)$(BIN_DIR)
+
+clean :
+	rm -f *~

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/umlgdb
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/umlgdb	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/umlgdb/umlgdb	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,346 @@
+#!/usr/bin/expect
+
+#######################################################################
+# Name: umlgdl
+#
+# Description:
+# umlgdb is a expect shell for gdb, which is specialised
+# to handle re-loading symbols of kernel modules as they
+# are reloaded using rmmod and insmod.
+#
+# It spawns GDB and prints out its pid which should be 
+# be used to start the UML session as follows.
+#
+# ./linux <kernel switches> debug gdb-pid=<pid>
+#
+# Once the kernel starts booting, proceed with the gdb and enter 'att 1'
+# to attach to the kernel and 'c' to continue.
+#
+# When any module is loaded with an insmod <module> command,
+# gdb breaks automatically at sys_init_module
+# and executes the appropriate gdb commands to reload all the symbols 
+# for the kernel and the symbols for the recently laoded module.
+#
+# It then passes control to the user who can proceed with their debugging
+# as usual.
+#
+# umlgdb session is very much like a session started with the normal gdb
+# except for the special handling of breakpoints at sys_init_modle.
+#
+# Its very easy to extend the behaviour opf umlgdb to handle different
+# debugging situations that need automation.
+#
+# Author: Chandan Kudige, April 11, 2002
+#######################################################################
+
+#######################################################################
+# Customisation: most of the defaults here should suffice. But feel
+#  free to change anything to suit custom requirements.
+#######################################################################
+
+##
+# GDB program name
+##
+set PROG "gdb"
+
+##
+# Kernel path relative to current directory.
+##
+set ARG "./linux"
+
+##
+# GDB prompt - Anyway valid TCL regex. Defaults to '(gdb)'
+##
+set GDB {\(gdb\)}
+
+##
+# Regex pattern printed out by the gdb when 'sys_init_module' 
+# breakpoint is hit.
+# The name of the module is matched by the regex.
+##
+set RE_BREAKPOINT {Breakpoint 1, sys_init_module \(name_user=[x0-9a-f]+ "(.+)"}
+
+##
+# Special character for quitting the UML session.
+# Type the actual character (using your editor's escape)
+##
+set QUIT_CHAR ""
+
+###
+# Module paths:
+# You can add paths for modules that are not in the gdb load-path.
+# This is basically a list with alternating module name and module path.
+# 
+# When a module is loaded, umlgdb tries to load the symbols from the
+# path given here. If the module is not listed then no symbols are loaded.
+###
+
+set MODULE_PATHS {
+"hostfs" "/home/jdike/linux/2.4/um/arch/um/fs/hostfs/hostfs.o"
+}
+
+
+#######################################################################
+# Script starts here.
+#######################################################################
+
+log_user 0
+system stty -echo raw
+set timeout -1
+
+proc get_module_path {modname} {
+    global MODULE_PATHS ARG env
+
+    set idx [lsearch $MODULE_PATHS $modname]
+    if {$idx == -1} {
+	set version "[exec ./linux --version]"
+	set path "[exec find $env(PWD)/lib/modules/$version/ -name ${modname}.o ]"
+	if {$path != ""} {
+	    return $path
+	}
+        return 0
+    }
+
+    incr idx
+
+    return [lindex $MODULE_PATHS $idx]
+}
+
+#######################################################################
+# do_insmod() hook is invoked when umlgdb detects that the breakpoint
+# at sys_init_module has been hit.
+#
+# Args:
+#   name - name of the module being loaded
+#
+# Returns: None
+#######################################################################
+
+proc do_insmod {name} {
+    global GDB ARG
+
+    set timeout 5
+
+    ##
+    # Let the sys_init_module return
+    # since module_list struct is initialised in this routine.
+    ##
+    prompt_wait $GDB
+    send "finish\r"
+    prompt_wait $GDB
+
+    ##
+    # find the start address of the module.
+    ##
+    set tmp "p/x (int)module_list + module_list->size_of_struct\r"
+    send $tmp
+
+    ##
+    # gdb prints the expression values as
+    # $<num> = 0x<hex value>
+    # Capture the hex value into modstart
+    ##
+    set buf [prompt_wait {= (0x[0-9a-f]+)}]
+    set succ [regexp "= (.+)" $buf tmp modstart]
+
+    set modpath [get_module_path $name]
+
+    ##
+    # Reload symbols only if we have a module path
+    ##
+
+    if {$modpath != 0} {
+        ##
+        # Reload all kernel symbols
+        ##
+        prompt_wait $GDB
+        send "symbol-file $ARG\r"
+        prompt_wait "y or n"
+        send "y\r"
+
+        ##
+        # Load the symbols for our module
+        ##
+        prompt_wait $GDB
+
+
+        send "add-symbol-file $modpath $modstart\r"
+        prompt_wait "y or n"
+        send "y\r"
+
+        ##
+        # print the module_list head to make sure init() and cleanup()
+        # are valid addresses
+        ##
+        prompt_wait $GDB
+        send "p *module_list\r"
+        prompt_wait $GDB
+        puts "\r\r>> Finished loading symbols for $name ...\r"
+
+        send " \r"
+    }
+
+    prompt_wait $GDB
+
+    ##
+    # Back to user
+    ##
+    set timeout -1
+}
+
+#######################################################################
+# shell() is the main dispatch loop.
+# 
+# - Passes user 
+#
+# Args:
+#   name - name of the module being loaded
+#
+# Returns: None
+#######################################################################
+
+proc shell {} {
+    global spawn_id, user_spawn_id
+    global RE_BREAKPOINT
+    global QUIT_CHAR
+
+    while 1 {
+    	expect {
+            ##
+            # gracefully exit when the gdb exits.
+            ##
+            eof {
+                return
+                }
+            
+            ##
+            # Hooks for gdb output.
+            # Note: order is important
+            ##
+            -re     $RE_BREAKPOINT {
+                    set modname $expect_out(1,string);
+                    set bpline $expect_out(buffer); 
+
+                    puts "\r *** Module $modname loaded *** \r"
+                    send_user -raw  -- $bpline
+                    do_insmod $modname
+               }
+
+            ##
+            # Catch all from gdb and pass it to the user
+            ##
+            -re ".+" {
+                    send_user -raw -- $expect_out(buffer);
+               }
+
+            ##
+            # Catch user QUIT sequence.
+            # Currently should be a single character.
+            ##
+	    	-i $user_spawn_id $QUIT_CHAR {return}
+
+            ##
+            # Catch all from user and pass it to gdb
+            ##
+            -i $user_spawn_id -re .+ {
+                    send -- $expect_out(buffer); 
+               }
+
+        }
+	}
+}
+
+#######################################################################
+# prompt_wait() : Can be called anytime we wait for a prompt.
+# Respects user input while waiting for the prompt.
+#######################################################################
+
+proc prompt_wait {prompt} {
+    global user_spawn_id
+    global QUIT_CHAR
+
+    set buf "<none>"
+
+    expect {
+        -re $prompt {
+                set buf $expect_out(buffer);
+                send_user -raw -- $buf
+            }
+
+        -re ".+" {
+                set buf $expect_out(buffer);
+                send_user -raw -- $buf
+                exp_continue;
+            }
+
+           timeout {
+                puts "\rTIMEDOUT on prompt $prompt!!!\r"
+                return 0;
+            }
+
+	    	-i $user_spawn_id $QUIT_CHAR {return}
+            -i $user_spawn_id -re .+ {
+                    send -- $expect_out(buffer); 
+            }
+    }
+
+    return $buf
+}
+
+##
+# Setup a breakpoint at sys_init_module
+# Prepare to enter "att 1"
+##
+proc initgdb {pid} {
+    global GDB
+
+##
+# user can press the 'enter' once they start the UML kernel.
+##
+
+    prompt_wait $GDB
+    send "att 1"
+
+    prompt_wait $GDB
+    send "b sys_init_module\r"
+
+    prompt_wait $GDB
+    send "b panic\r"
+
+    prompt_wait $GDB
+    send "b stop\r"
+
+    prompt_wait $GDB
+    send "handle SIGWINCH nostop noprint pass\r"
+
+    prompt_wait $GDB
+    send "b start_kernel\r"
+
+    prompt_wait $GDB
+    send "c\r"
+}
+
+##
+# Spawn our gdb with linux
+##
+set pid [spawn $PROG $ARG]
+
+puts "\r\n\n            ******** GDB pid is $pid ********\r"
+puts "Start UML as: $ARG <kernel switches> debug gdb-pid=$pid\r\n\r\n\r\n"
+
+##
+# Initialise gdb
+##
+initgdb $pid
+
+##
+# Main dispatch loop
+##
+shell
+
+##
+# Cleanup
+##
+system stty sane
+
+puts "\r----- umlgdb finished----\r"

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Entries
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Entries	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Entries	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,3 @@
+/uml_watchdog.c/1.1/Tue Jun  4 02:53:57 2002//
+/Makefile/1.2/Sat Feb  8 04:04:25 2003//
+D

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Repository
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Repository	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Repository	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+tools/watchdog

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Root
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Root	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/CVS/Root	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1 @@
+jdike at cvs.user-mode-linux.sourceforge.net:/cvsroot/user-mode-linux

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/Makefile
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/Makefile	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/Makefile	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,17 @@
+BIN = uml_watchdog
+OBJS = $(BIN).o
+CFLAGS = -g -Wall
+
+BIN_DIR ?= /usr/bin
+
+all : $(BIN)
+
+$(BIN) : $(OBJS)
+	$(CC) $(CFLAGS) -o $(BIN) $(OBJS)
+
+clean : 
+	rm -f $(BIN) $(OBJS) *~
+
+install : $(BIN)
+	install -d $(DESTDIR)$(BIN_DIR)
+	install -s $(BIN) $(DESTDIR)$(BIN_DIR)

Added: uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/uml_watchdog.c
===================================================================
--- uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/uml_watchdog.c	2005-01-01 20:19:13 UTC (rev 0)
+++ uml-utilities-20060110/uml-utilities/branches/upstream/current/watchdog/uml_watchdog.c	2006-01-12 14:18:51 UTC (rev 1)
@@ -0,0 +1,93 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#define MCONSOLE_MAGIC (0xcafebabe)
+#define MCONSOLE_MAX_DATA (512)
+#define MCONSOLE_VERSION 2
+
+struct mconsole_notify {
+	unsigned long magic;
+	int version;	
+	enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG } type;
+	int len;
+	char data[MCONSOLE_MAX_DATA];
+};
+
+static char *sock_name = NULL;
+
+static void notify(int sig)
+{
+  struct sockaddr_un target;
+  struct mconsole_notify packet;
+  int sock, len, n;
+
+  sock = socket(PF_UNIX, SOCK_DGRAM, 0);
+  if(sock < 0){
+    perror("socket");
+    exit(1);
+  }
+
+  target.sun_family = AF_UNIX;
+  strcpy(target.sun_path, sock_name);
+
+  packet.magic = MCONSOLE_MAGIC;
+  packet.version = MCONSOLE_VERSION;
+  packet.type = MCONSOLE_HANG;
+  packet.len = 0;
+
+  len = sizeof(packet) + packet.len - sizeof(packet.data);
+  n = sendto(sock, &packet, len, 0, (struct sockaddr *) &target, 
+	     sizeof(target));
+  if(n < 0)
+    perror("sendto");
+  exit(1);
+}
+
+static int tracing_pid = -1;
+
+static void kill_tracer(int sig)
+{
+  kill(tracing_pid, SIGINT);
+  sleep(1);
+  kill(tracing_pid, SIGINT);
+  sleep(1);
+  kill(tracing_pid, SIGKILL);
+  exit(1);
+}
+
+int main(int argc, char **argv)
+{
+  void (*handler)(int);
+  int n;
+  char c, *end;
+
+  if(argc < 3) exit(1);
+
+  if(!strcmp(argv[1], "-pid")){
+    tracing_pid = strtol(argv[2], &end, 0);
+    if(*end != '\0') exit(1);
+    if(kill(tracing_pid, 0)) exit(1);
+    handler = kill_tracer;
+  }
+  else if(!strcmp(argv[1], "-mconsole")){
+    sock_name = argv[2];
+    handler = notify;
+  }
+  else exit(1);
+
+  if(signal(SIGALRM, handler)) exit(1);
+
+  if(write(1, &c, sizeof(c)) != sizeof(c)) exit(1);
+
+  while(1){
+    alarm(60);
+    n = read(0, &c, sizeof(c));
+    if(n == 0) exit(0);
+    else if(n < 0) exit(1);
+  }
+}




More information about the Pkg-uml-commit mailing list