Index: /ipk/ipkg-utils-050831/CONTROL/CVS/Entries
===================================================================
--- /ipk/ipkg-utils-050831/CONTROL/CVS/Entries	(revision 4860)
+++ /ipk/ipkg-utils-050831/CONTROL/CVS/Entries	(revision 4860)
@@ -0,0 +1,2 @@
+/control/1.2/Tue Dec 28 15:02:18 2004//
+D
Index: /ipk/ipkg-utils-050831/CONTROL/CVS/Repository
===================================================================
--- /ipk/ipkg-utils-050831/CONTROL/CVS/Repository	(revision 4860)
+++ /ipk/ipkg-utils-050831/CONTROL/CVS/Repository	(revision 4860)
@@ -0,0 +1,1 @@
+ipkg-utils/CONTROL
Index: /ipk/ipkg-utils-050831/CONTROL/CVS/Root
===================================================================
--- /ipk/ipkg-utils-050831/CONTROL/CVS/Root	(revision 4860)
+++ /ipk/ipkg-utils-050831/CONTROL/CVS/Root	(revision 4860)
@@ -0,0 +1,1 @@
+/cvs
Index: /ipk/ipkg-utils-050831/CONTROL/control
===================================================================
--- /ipk/ipkg-utils-050831/CONTROL/control	(revision 4860)
+++ /ipk/ipkg-utils-050831/CONTROL/control	(revision 4860)
@@ -0,0 +1,8 @@
+Package: ipkg-build
+Section: base
+Priority: optional
+Version: 1.7
+Architecture: all
+Maintainer: Carl Worth <cworth@handhelds.org>
+Depends: sed, grep, gzip, tar
+Description: Script for building .ipk packages for the ipkg system.
Index: /ipk/ipkg-utils-050831/COPYING
===================================================================
--- /ipk/ipkg-utils-050831/COPYING	(revision 4860)
+++ /ipk/ipkg-utils-050831/COPYING	(revision 4860)
@@ -0,0 +1,345 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /ipk/ipkg-utils-050831/Makefile
===================================================================
--- /ipk/ipkg-utils-050831/Makefile	(revision 4860)
+++ /ipk/ipkg-utils-050831/Makefile	(revision 4860)
@@ -0,0 +1,30 @@
+UTILS = ipkg-build ipkg-upload
+
+PREFIX=/usr/local
+
+all: build
+
+build: ipkg-compare-versions
+	python setup.py build
+
+ipkg-compare-versions: ipkg-compare-versions.c
+	$(CC) $(CFLAGS) -o ipkg-compare-versions ipkg-compare-versions.c
+
+install: ${UTILS}
+	cp ${UTILS} $(PREFIX)/bin
+	echo "Copying build/lib/ipkg.py into $(PREFIX)/bin"
+	cp build/lib/ipkg.py $(PREFIX)/bin
+	chmod agu+rx ipkg-make-index
+	cp -f ipkg-make-index $(PREFIX)/bin
+
+binary: build
+	mkdir -p ipkg-build-binary/usr/bin
+	cp ipkg-build ipkg-build-binary/usr/bin
+	mkdir -p ipkg-build-binary/CONTROL
+	cp CONTROL/control ipkg-build-binary/CONTROL
+	chown -R root:root ipkg-build-binary
+	ipkg-build ipkg-build-binary .
+	rm -rf ipkg-build-binary
+
+clean:
+	rm -rf ipkg-build-binary ipkg-compare-versions *.pyc build
Index: /ipk/ipkg-utils-050831/Makefile.python
===================================================================
--- /ipk/ipkg-utils-050831/Makefile.python	(revision 4860)
+++ /ipk/ipkg-utils-050831/Makefile.python	(revision 4860)
@@ -0,0 +1,7 @@
+
+
+install:
+	python setup.py build
+	python setup.py install
+	chmod agu+rx ipkg-make-index
+	cp -f ipkg-make-index /usr/local/bin
Index: /ipk/ipkg-utils-050831/build/lib/ipkg.py
===================================================================
--- /ipk/ipkg-utils-050831/build/lib/ipkg.py	(revision 4860)
+++ /ipk/ipkg-utils-050831/build/lib/ipkg.py	(revision 4860)
@@ -0,0 +1,462 @@
+#!/usr/bin/env python
+#   Copyright (C) 2001 Alexander S. Guy <a7r@andern.org>
+#                      Andern Research Labs
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2, or (at your option)
+#   any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place - Suite 330,
+#   Boston, MA 02111-1307, USA.  */
+#
+#   Copyright 2001, Russell Nelson <ipkg.py@russnelson.com>
+#   Added reading in of packages.
+#   Added missing package information fields.
+#   Changed render_control() to __repr__().
+#
+# Current Issues:
+#    The API doesn't validate package information fields.  It should be
+#        throwing exceptions in the right places.
+#    Executions of tar could silently fail.
+#    Executions of tar *do* fail, and loudly, because you have to specify a full filename,
+#        and tar complains if any files are missing, and the ipkg spec doesn't require
+#        people to say "./control.tar.gz" or "./control" when they package files.
+#        It would be much better to require ./control or disallow ./control (either)
+#        rather than letting people pick.  Some freedoms aren't worth their cost.
+
+import tempfile
+import os
+import sys
+import glob
+import md5
+import re
+import string
+import commands
+from stat import ST_SIZE
+
+class Version:
+    """A class for holding parsed package version information."""
+    def __init__(self, epoch, version):
+        self.epoch = epoch
+        self.version = version
+
+    def _versioncompare(self, ref):
+        selfversion = self.version
+        refversion = ref.version
+        while 1:
+            ## first look for non-numeric version component
+            selfm = re.match('([^0-9]*)(.*)', selfversion)
+            #print 'selfm', selfm.groups()
+            (selfalpha, selfversion) = selfm.groups()
+            refm = re.match('([^0-9]*)(.*)', refversion)
+            #print 'refm', refm.groups()
+            (refalpha, refversion) = refm.groups()
+            if (selfalpha > refalpha):
+                return 1
+            elif (selfalpha < refalpha):
+                return -1
+            ## now look for numeric version component
+            (selfnum, selfversion) = re.match('([0-9]*)(.*)', selfversion).groups()
+            (refnum, refversion) = re.match('([0-9]*)(.*)', refversion).groups()
+            #print 'selfnum', selfnum, selfversion
+            #print 'refnum', refnum, refversion
+            if (selfnum != ''):
+                selfnum = int(selfnum)
+            else:
+                selfnum = -1
+            if (refnum != ''):
+                refnum = int(refnum)
+            else:
+                refnum = -1
+            if (selfnum > refnum):
+                return 1
+            elif (selfnum < refnum):
+                return -1
+            if selfversion == '' and refversion == '':
+                return 0
+
+    def compare(self, ref):
+        if (self.epoch > ref.epoch):
+            return 1
+        elif (self.epoch < ref.epoch):
+            return -1
+        else:
+            return self._versioncompare(ref)
+
+def parse_version(versionstr):
+    epoch = 0
+    # check for epoch
+    m = re.match('([0-9]*):(.*)', versionstr)
+    if m:
+        (epochstr, versionstr) = m.groups()
+        epoch = int(epochstr)
+    return Version(epoch, versionstr)
+
+class Package:
+    """A class for creating objects to manipulate (e.g. create) ipkg
+       packages."""
+    def __init__(self, fn=None):
+	self.package = None
+	self.version = 'none'
+	self.parsed_version = None
+	self.architecture = None
+	self.maintainer = None
+	self.source = None
+	self.description = None
+	self.depends = None
+	self.provides = None
+	self.replaces = None
+	self.conflicts = None
+        self.recommends = None
+	self.suggests = None
+	self.section = None
+        self.filename_header = None
+	self.file_list = []
+        self.md5 = None
+        self.size = None
+        self.installed_size = None
+        self.filename = None
+        self.isdeb = 0
+
+	if fn:
+            # see if it is deb format
+            f = open(fn, "r")
+            magic = f.read(4)
+            f.close()
+            if (magic == "!<ar"):
+                self.isdeb = 1
+
+            # compute the MD5.
+            f = open(fn, "r")
+            sum = md5.new()
+            while 1:
+                data = f.read(1024)
+                if not data: break
+                sum.update(data)
+            f.close()
+            if sys.version[:1] > '2':
+                # when using Python 2.0 or newer
+                self.md5 = sum.hexdigest() 
+            else:
+                self.md5 = string.join(map((lambda x:"%02x" % ord(x)),sum.digest()),'')
+            stat = os.stat(fn)
+            self.size = stat[ST_SIZE]
+            self.filename = os.path.basename(fn)
+	    ## sys.stderr.write("  extracting control.tar.gz from %s\n"% (fn,)) 
+            if self.isdeb:
+                control = os.popen("ar p "+fn+" control.tar.gz | tar xfzO - './control'","r")
+            else:
+                control = os.popen("tar xfzO "+fn+" '*control.tar.gz' | tar xfzO - './control'","r")
+            line = control.readline()
+            while 1:
+                if not line: break
+                line = string.rstrip(line)
+                lineparts = re.match(r'([\w-]*?):\s*(.*)', line)
+		if lineparts:
+                    name = string.lower(lineparts.group(1))
+		    value = lineparts.group(2)
+		    while 1:
+			line = control.readline()
+			if not line: break
+			if line[0] != ' ': break
+                        line = string.rstrip(line)
+			value = value + '\n' + line
+                    # don't allow package to override its own filename
+                    if name == "filename":
+                        self.filename_header = value
+                    else:
+                        if self.__dict__.has_key(name):
+                            self.__dict__[name] = value
+                else:
+                    line = control.readline()
+            control.close()
+            if self.isdeb:
+                data = os.popen("ar p "+fn+" data.tar.gz | tar tfz -","r")
+            else:
+                data = os.popen("tar xfzO "+fn+" '*data.tar.gz' | tar tfz -","r")
+            while 1:
+                line = data.readline()
+                if not line: break
+                self.file_list.append(string.rstrip(line))
+            data.close()
+
+	self.scratch_dir = None
+	self.file_dir = None
+	self.meta_dir = None
+
+    def read_control(self, control):
+        import os
+
+        line = control.readline()
+        while 1:
+            if not line: break
+            line = string.rstrip(line)
+            lineparts = re.match(r'([\w-]*?):\s*(.*)', line)
+            if lineparts:
+                name = string.lower(lineparts.group(1))
+                value = lineparts.group(2)
+                while 1:
+                    line = control.readline()
+                    if not line: break
+                    if line[0] != ' ': break
+                    value = value + '\n' + line
+                if name == 'size':
+                    self.size = int(value)
+                elif self.__dict__.has_key(name):
+                    self.__dict__[name] = value
+                if line[0] == '\n':
+                    return # consumes one blank line at end of package descriptoin
+            else:
+                line = control.readline()
+                pass
+        return    
+
+    def _setup_scratch_area(self):
+	self.scratch_dir = "%s/%sipkg" % (tempfile.gettempdir(),
+					   tempfile.gettempprefix())
+	self.file_dir = "%s/files" % (self.scratch_dir)
+	self.meta_dir = "%s/meta" % (self.scratch_dir)
+
+	os.mkdir(self.scratch_dir)
+	os.mkdir(self.file_dir)
+	os.mkdir(self.meta_dir)
+
+    def set_package(self, package):
+	self.package = package
+
+    def get_package(self):
+	return self.package
+		
+    def set_version(self, version):
+	self.version = version
+        self.parsed_version = parse_version(version)
+
+    def get_version(self):
+	return self.version
+
+    def set_architecture(self, architecture):
+	self.architecture = architecture
+
+    def get_architecture(self):
+	return self.architecture
+
+    def set_maintainer(self, maintainer):
+	self.maintainer = maintainer
+
+    def get_maintainer(self):
+	return self.maintainer
+
+    def set_source(self, source):
+	self.source = source
+
+    def get_source(self):
+	return self.source
+
+    def set_description(self, description):
+	self.description = description
+
+    def get_description(self):
+	return self.description
+
+    def set_depends(self, depends):
+	self.depends = depends
+
+    def get_depends(self, depends):
+	return self.depends
+
+    def set_provides(self, provides):
+	self.provides = provides
+
+    def get_provides(self, provides):
+	return self.provides
+
+    def set_replaces(self, replaces):
+	self.replaces = replaces
+
+    def get_replaces(self, replaces):
+	return self.replaces
+
+    def set_conflicts(self, conflicts):
+	self.conflicts = conflicts
+
+    def get_conflicts(self, conflicts):
+	return self.conflicts
+
+    def set_suggests(self, suggests):
+	self.suggests = suggests
+
+    def get_suggests(self, suggests):
+	return self.suggests
+
+    def set_section(self, section):
+	self.section = section
+
+    def get_section(self, section):
+	return self.section
+
+    def get_file_list(self):
+	return self.file_list
+
+    def write_package(self, dirname):
+        buf = self.render_control()
+	file = open("%s/control" % self.meta_dir, 'w')
+	file.write(buf)
+
+	self._setup_scratch_area()
+	cmd = "cd %s ; tar cvfz %s/control.tar.gz control" % (self.meta_dir,
+							      self.scratch_dir)
+
+	cmd_out, cmd_in, cmd_err = os.popen3(cmd)
+	
+	while cmd_err.readline() != "":
+	    pass
+
+	cmd_out.close()
+	cmd_in.close()
+	cmd_err.close()
+
+	bits = "control.tar.gz"
+
+	if self.file_list:
+		cmd = "cd %s ; tar cvfz %s/data.tar.gz" % (self.file_dir,
+					   		   self.scratch_dir)
+
+		cmd_out, cmd_in, cmd_err = os.popen3(cmd)
+
+		while cmd_err.readline() != "":
+		    pass
+
+		cmd_out.close()
+		cmd_in.close()
+		cmd_err.close()
+
+		bits = bits + " data.tar.gz"
+
+	file = "%s_%s_%s.ipk" % (self.package, self.version, self.architecture)
+	cmd = "cd %s ; tar cvfz %s/%s %s" % (self.scratch_dir,
+					     dirname,
+					     file,
+					     bits)
+
+	cmd_out, cmd_in, cmd_err = os.popen3(cmd)
+
+	while cmd_err.readline() != "":
+	    pass
+
+	cmd_out.close()
+	cmd_in.close()
+	cmd_err.close()
+
+    def compare_version(self, ref):
+        """Compare package versions of self and ref"""
+        if not self.version:
+            print 'No version for package %s' % self.package
+        if not ref.version:
+            print 'No version for package %s' % ref.package
+        if not self.parsed_version:
+            self.parsed_version = parse_version(self.version)
+        if not ref.parsed_version:
+            ref.parsed_version = parse_version(ref.version)
+        return self.parsed_version.compare(ref.parsed_version)
+
+    def __repr__(self):
+	out = ""
+
+	# XXX - Some checks need to be made, and some exceptions
+	#       need to be thrown. -- a7r
+
+        if self.package: out = out + "Package: %s\n" % (self.package)
+        if self.version: out = out + "Version: %s\n" % (self.version)
+        if self.depends: out = out + "Depends: %s\n" % (self.depends)
+        if self.provides: out = out + "Provides: %s\n" % (self.provides)
+        if self.replaces: out = out + "Replaces: %s\n" % (self.replaces)
+        if self.conflicts: out = out + "Conflicts: %s\n" % (self.conflicts)
+        if self.suggests: out = out + "Suggests: %s\n" % (self.suggests)
+        if self.recommends: out = out + "Recommends: %s\n" % (self.recommends)
+        if self.section: out = out + "Section: %s\n" % (self.section)
+        if self.architecture: out = out + "Architecture: %s\n" % (self.architecture)
+        if self.maintainer: out = out + "Maintainer: %s\n" % (self.maintainer)
+        if self.md5: out = out + "MD5Sum: %s\n" % (self.md5)
+        if self.size: out = out + "Size: %d\n" % int(self.size)
+        if self.installed_size: out = out + "InstalledSize: %d\n" % int(self.installed_size)
+        if self.filename: out = out + "Filename: %s\n" % (self.filename)
+        if self.source: out = out + "Source: %s\n" % (self.source)
+        if self.description: out = out + "Description: %s\n" % (self.description)
+	out = out + "\n"
+
+	return out
+
+    def __del__(self):
+	# XXX - Why is the `os' module being yanked out before Package objects
+	#       are being destroyed?  -- a7r
+        pass
+
+class Packages:
+    """A currently unimplemented wrapper around the ipkg utility."""
+    def __init__(self):
+        self.packages = {}
+        return
+
+    def add_package(self, pkg):
+        package = pkg.package
+        arch = pkg.architecture
+        name = ("%s:%s" % (package, arch))
+        if (not self.packages.has_key(name)):
+            self.packages[name] = pkg
+        
+        if pkg.compare_version(self.packages[name]) >= 0:
+            self.packages[name] = pkg
+            return 0
+        else:
+            return 1
+
+    def read_packages_file(self, fn):
+        f = open(fn, "r")
+        while 1:
+            pkg = Package()
+            pkg.read_control(f)
+            if pkg.get_package():
+                self.add_package(pkg)
+            else:
+                break
+        f.close()    
+        return
+
+    def write_packages_file(self, fn):
+        f = open(fn, "w")
+        names = self.packages.keys()
+        names.sort()
+        for name in names:
+            f.write(self.packages[name].__repr__())
+        return    
+
+    def keys(self):
+        return self.packages.keys()
+
+    def __getitem__(self, key):
+        return self.packages[key]
+
+if __name__ == "__main__":
+    package = Package()
+
+    package.set_package("FooBar")
+    package.set_version("0.1-fam1")
+    package.set_architecture("arm")
+    package.set_maintainer("Testing <testing@testing.testing>")
+    package.set_depends("libc")
+    package.set_description("A test of the APIs.")
+
+    print "<"
+    sys.stdout.write(package)
+    print ">"
+
+    package.write_package("/tmp")
+
Index: /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-build
===================================================================
--- /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-build	(revision 4860)
+++ /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-build	(revision 4860)
@@ -0,0 +1,246 @@
+#!/bin/sh
+
+# ipkg-build -- construct a .ipk from a directory
+# Carl Worth <cworth@east.isi.edu>
+# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
+# 2003-04-25 rea@sr.unh.edu
+#   Updated to work on Familiar Pre0.7rc1, with busybox tar.
+#   Note it Requires: binutils-ar (since the busybox ar can't create)
+#   For UID debugging it needs a better "find".
+set -e
+
+version=1.0
+
+ipkg_extract_value() {
+	sed -e "s/^[^:]*:[[:space:]]*//"
+}
+
+required_field() {
+	field=$1
+
+	value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
+	if [ -z "$value" ]; then
+		echo "*** Error: $CONTROL/control is missing field $field" >&2
+		return 1
+	fi
+	echo $value
+	return 0
+}
+
+disallowed_field() {
+	field=$1
+
+	value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
+	if [ -n "$value" ]; then
+		echo "*** Error: $CONTROL/control contains disallowed field $field" >&2
+		return 1
+	fi
+	echo $value
+	return 0
+}
+
+pkg_appears_sane() {
+	local pkg_dir=$1
+
+	local owd=`pwd`
+	cd $pkg_dir
+
+	PKG_ERROR=0
+
+	tilde_files=`find . -name '*~'`
+	if [ -n "$tilde_files" ]; then
+	    if [ "$noclean" = "1" ]; then
+		echo "*** Warning: The following files have names ending in '~'.
+You probably want to remove them: " >&2
+		ls -ld $tilde_files
+		echo >&2
+	    else
+		echo "*** Removing the following files: $tilde_files"
+		rm -f "$tilde_files"
+	    fi
+	fi
+
+	large_uid_files=`find . -uid +99 || true`
+
+	if [ "$ogargs" = "" ]  && [ -n "$large_uid_files" ]; then
+		echo "*** Warning: The following files have a UID greater than 99.
+You probably want to chown these to a system user: " >&2
+		ls -ld $large_uid_files
+		echo >&2
+	fi
+	    
+
+	if [ ! -f "$CONTROL/control" ]; then
+		echo "*** Error: Control file $pkg_dir/$CONTROL/control not found." >&2
+		cd $owd
+		return 1
+	fi
+
+	pkg=`required_field Package`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	version=`required_field Version | sed 's/Version://; s/^.://g;'`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	arch=`required_field Architecture`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	required_field Maintainer >/dev/null
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	required_field Description >/dev/null
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	section=`required_field Section`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$section" ]; then
+	    echo "The Section field should have one of the following values:" >&2
+	    echo "admin, base, comm, editors, extras, games, graphics, kernel, libs, misc, net, text, web, x11" >&2
+	fi
+
+	priority=`required_field Priority`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$priority" ]; then
+	    echo "The Priority field should have one of the following values:" >&2
+	    echo "required, important, standard, optional, extra." >&2
+	    echo "If you don't know which priority value you should be using, then use \`optional'" >&2
+	fi
+
+	source=`required_field Source`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$source" ]; then
+	    echo "The Source field contain the URL's or filenames of the source code and any patches" 
+	    echo "used to build this package.  Either gnu-style tarballs or Debian source packages "
+	    echo "are acceptable.  Relative filenames may be used if they are distributed in the same"
+	    echo "directory as the .ipk file."
+	fi
+
+	disallowed_filename=`disallowed_field Filename`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	if echo $pkg | grep '[^a-z0-9.+-]'; then
+		echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
+		PKG_ERROR=1;
+	fi
+
+	local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
+	if [ -n "$bad_fields" ]; then
+		bad_fields=`echo $bad_fields`
+		echo "*** Error: The following fields in $CONTROL/control are missing a ':'" >&2
+		echo "	$bad_fields" >&2
+		echo "ipkg-build: This may be due to a missing initial space for a multi-line field value" >&2
+		PKG_ERROR=1
+	fi
+
+	for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
+		if [ -f $script -a ! -x $script ]; then
+			echo "*** Error: package script $script is not executable" >&2
+			PKG_ERROR=1
+		fi
+	done
+
+	if [ -f $CONTROL/conffiles ]; then
+		for cf in `cat $CONTROL/conffiles`; do
+			if [ ! -f ./$cf ]; then
+				echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2
+				PKG_ERROR=1
+			fi
+		done
+	fi
+
+	cd $owd
+	return $PKG_ERROR
+}
+
+###
+# ipkg-build "main"
+###
+ogargs=""
+outer=ar
+noclean=0
+usage="Usage: $0 [-c] [-C] [-o owner] [-g group] <pkg_directory> [<destination_directory>]"
+while getopts "cg:ho:v" opt; do
+    case $opt in
+	o ) owner=$OPTARG
+	    ogargs="--owner=$owner"
+	    ;;
+	g ) group=$OPTARG
+	    ogargs="$ogargs --group=$group"
+	    ;;
+        c ) outer=tar
+            ;;
+        C ) noclean=1
+            ;;
+	v ) echo $version
+	    exit 0
+	    ;;
+	h ) 	echo $usage  >&2 ;;
+	\? ) 	echo $usage  >&2
+	esac
+done
+
+
+shift $(($OPTIND - 1))
+
+# continue on to process additional arguments
+
+case $# in
+1)
+	dest_dir=$PWD
+	;;
+2)
+	dest_dir=$2
+	if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
+	    dest_dir=$PWD
+	fi
+	;;
+*)
+	echo $usage >&2
+	exit 1 
+	;;
+esac
+
+pkg_dir=$1
+
+if [ ! -d $pkg_dir ]; then
+	echo "*** Error: Directory $pkg_dir does not exist" >&2
+	exit 1
+fi
+
+# CONTROL is second so that it takes precedence
+CONTROL=
+[ -d $pkg_dir/DEBIAN ] && CONTROL=DEBIAN
+[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
+if [ -z "$CONTROL" ]; then
+	echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
+	exit 1
+fi
+
+if ! pkg_appears_sane $pkg_dir; then
+	echo >&2
+	echo "ipkg-build: Please fix the above errors and try again." >&2
+	exit 1
+fi
+
+tmp_dir=$dest_dir/IPKG_BUILD.$$
+mkdir $tmp_dir
+
+echo $CONTROL > $tmp_dir/tarX
+( cd $pkg_dir && tar $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . )
+( cd $pkg_dir/$CONTROL && tar $ogargs -czf $tmp_dir/control.tar.gz . )
+rm $tmp_dir/tarX
+
+echo "2.0" > $tmp_dir/debian-binary
+
+pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
+rm -f $pkg_file
+if [ "$outer" = "ar" ] ; then
+  ( cd $tmp_dir && ar -crf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
+else
+  ( cd $tmp_dir && tar -zcf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
+fi
+
+rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
+rmdir $tmp_dir
+
+echo "Packaged contents of $pkg_dir into $pkg_file"
Index: /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-compare-indexes
===================================================================
--- /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-compare-indexes	(revision 4860)
+++ /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-compare-indexes	(revision 4860)
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+
+import sys, os
+from glob import glob
+import commands
+import ipkg
+
+pkg_dir1 = sys.argv[1]
+pkg_dir2 = sys.argv[2]
+
+if ( not pkg_dir1 or not pkg_dir2 ):
+	sys.stderr.write("Usage: ipkg-update-index <package_directory1> <package_directory2>\n")
+	sys.exit(1)
+
+pkgs1 = ipkg.Packages()
+pkgs1.read_packages_file(pkg_dir1 + '/Packages')
+
+pkgs2 = ipkg.Packages()
+pkgs2.read_packages_file(pkg_dir2 + '/Packages')
+
+names1 = pkgs1.packages.keys()
+names2 = pkgs2.packages.keys()
+
+## union of the two names lists
+pkgs = {}
+for name in names1:
+    pkgs[name] = pkgs1.packages[name]
+for name in names2:
+    pkgs[name] = pkgs2.packages[name]
+
+names = pkgs.keys()
+names.sort() 
+for name in names:
+    pkg1 = None
+    pkg2 = None
+    if pkgs1.packages.has_key(name):
+        pkg1 = pkgs1.packages[name]
+    if pkgs2.packages.has_key(name):
+        pkg2 = pkgs2.packages[name]
+    if pkg1 and pkg2 and pkg1.version != pkg2.version:
+        print "CHANGED: %s from version %s to %s (%s)" % (pkg1.package, pkg1.version, pkg2.version, pkg2.maintainer)
+        cmd = "ipkg-diff %s %s > %s " % ((pkg_dir1 + pkg1.filename),  (pkg_dir2 + pkg2.filename), (pkg1.package + '.diff'))
+        print cmd
+	commands.getstatusoutput(cmd)
+    if not pkg1:
+        print "NEW: %s version %s (%s)"% (pkg2.package, pkg2.version, pkg2.maintainer)
+    if not pkg2:
+        print "DELETE: %s version %s (%s)"% (pkg1.package, pkg1.version, pkg1.maintainer)
+    
Index: /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-make-index
===================================================================
--- /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-make-index	(revision 4860)
+++ /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-make-index	(revision 4860)
@@ -0,0 +1,179 @@
+#!/usr/bin/python
+# $Id: ipkg-make-index,v 1.22 2005/03/03 16:39:04 jamey Exp $
+
+import sys, os, posixpath
+from glob import glob
+import commands
+import ipkg
+import getopt
+import string
+import re
+
+verbose = 0
+
+def usage():
+     sys.stderr.write("%s [-h] [-s] [-m] [-l Packages.filelist] [-p Packages] [-r Packages.old] [-L localesdir] [-v] packagesdir\n" % (sys.argv[0],))
+     sys.exit(-1)
+
+def to_morgue(filename):
+     morgue_dir = pkg_dir + "/morgue"
+     if verbose:
+          sys.stderr.write ("Moving " + filename + " to morgue\n")
+     if not os.path.exists(morgue_dir):
+          os.mkdir(morgue_dir)
+     if os.path.exists(pkg_dir + "/" + filename):
+          os.rename(pkg_dir + "/" + filename, morgue_dir + "/" + filename)
+     if os.path.exists(pkg_dir + "/" + filename + ".asc"):
+          os.rename(pkg_dir + "/" + filename + ".asc", morgue_dir + "/" + filename + ".asc")
+
+locales_dir = None
+def to_locale(filename, locale):
+     locale_dir = pkg_dir + '/' + locales_dir + '/' + locale + "/"
+     if verbose:
+          sys.stderr.write ("Moving " + filename + " to " + locale_dir + "\n")
+     if not os.path.exists(locale_dir):
+          os.mkdir(locale_dir)
+     os.rename(pkg_dir + "/" + filename, locale_dir + "/" + filename)
+     if os.path.exists(pkg_dir + "/" + filename + ".asc"):
+          os.rename(pkg_dir + "/" + filename + ".asc", locale_dir + "/" + filename + ".asc")
+
+old_filename = None
+packages_filename = None
+filelist_filename = "Packages.filelist"
+opt_s = 0
+opt_m = 0
+(opts, remaining_args) = getopt.getopt(sys.argv[1:], "hl:p:vsmr:L:")
+for (optkey, optval) in opts:
+     if optkey == '-h': 
+          usage()
+     if optkey == '-s': 
+          opt_s = 1
+     if optkey == '-p': 
+          packages_filename = optval
+     if optkey == '-l':
+          filelist_filename = optval
+     if optkey == '-v':
+          verbose = 1
+     if optkey == '-m':
+          opt_m = 1
+     if optkey == '-r':
+          old_filename = optval
+     if optkey == '-L':
+          locales_dir = optval
+
+if ( not remaining_args ):
+     usage()
+
+pkg_dir=remaining_args[0]
+
+packages = ipkg.Packages()
+
+old_pkg_hash = {}
+if packages_filename and not old_filename and os.path.exists(packages_filename):
+     old_filename = packages_filename
+
+if old_filename:
+     if (verbose):
+          sys.stderr.write("Reading package list from " + old_filename + "\n")
+     old_packages = ipkg.Packages()
+     old_packages.read_packages_file(old_filename)
+     for k in old_packages.packages.keys():
+          p = old_packages.packages[k]
+          old_pkg_hash[p.filename] = p
+
+if (verbose):
+     sys.stderr.write("Reading in all the package info from %s\n" % (pkg_dir, ))
+files=glob(pkg_dir + '/*.ipk') + glob(pkg_dir + '/*.deb')
+files.sort()
+for filename in files:
+     basename = os.path.basename(filename)
+     if old_pkg_hash.has_key(basename):
+          if (verbose):
+               sys.stderr.write("Found %s in Packages\n" % (filename,))
+          pkg = old_pkg_hash[basename]
+     else:
+          if (verbose):
+               sys.stderr.write("Reading info for package %s\n" % (filename,))
+          pkg = ipkg.Package(filename)
+     pkg_key = ("%s:%s" % (pkg.package, pkg.architecture))
+     if (packages.packages.has_key(pkg_key)):
+          old_filename = packages.packages[pkg_key].filename
+     else:
+          old_filename = ""
+     s = packages.add_package(pkg)
+     if s == 0:
+          if old_filename:
+               # old package was displaced by newer
+               if opt_m:
+                    to_morgue(old_filename)
+               if opt_s:
+                    print pkg_dir + "/" + old_filename
+     else:
+          if opt_m:
+               to_morgue(basename)
+          if opt_s:
+               print filename
+
+if opt_s:
+     sys.exit(0)
+
+if verbose:
+     sys.stderr.write("Generating Packages file\n")
+if packages_filename:
+     old_stdout = sys.stdout
+     tmp_packages_filename = ("%s.%d" % (packages_filename, os.getpid()))
+     sys.stdout = open(tmp_packages_filename, "w")
+names = packages.packages.keys()
+names.sort()
+for name in names:
+     pkg = packages.packages[name]
+     if locales_dir and pkg.depends:
+         depends = string.split(pkg.depends, ',')
+         locale = None
+         for d in depends:
+              m = re.match('.*virtual-locale-([a-zA-Z]+).*', d)
+              mp = re.match('locale-base-([a-zA-Z]+)([-+])?.*', pkg.package)
+              if m:
+                   locale = m.group(1)
+              if mp:
+                   locale = mp.group(1)
+         if locale:
+              to_locale(pkg.filename, locale)
+              continue
+     if (verbose):
+          sys.stderr.write("Writing info for package %s\n" % (pkg.package,))
+     print pkg
+if packages_filename:
+     sys.stdout.close()
+     sys.stdout = old_stdout
+     gzip_filename = ("%s.gz" % packages_filename)
+     tmp_gzip_filename = ("%s.%d" % (gzip_filename, os.getpid()))
+     gzip_cmd = "gzip -9c < %s > %s" % (tmp_packages_filename, tmp_gzip_filename)
+     (rc, outtext) = commands.getstatusoutput(gzip_cmd)
+     print outtext
+     os.rename(tmp_packages_filename, packages_filename)
+     os.rename(tmp_gzip_filename, gzip_filename)
+
+if verbose:	
+     sys.stderr.write("Generate Packages.filelist file\n")
+files = {}
+names = packages.packages.keys()
+names.sort()
+for name in names:
+     for fn in packages[name].get_file_list():
+          (h,t) = os.path.split(fn)
+          if not t: continue
+          if not files.has_key(t): files[t] = name+':'+fn
+          else: files[t] = files[t] + ',' + name+':'+fn
+
+if filelist_filename:
+     tmp_filelist_filename = ("%s.%d" % (filelist_filename, os.getpid()))
+     sys.stdout = open(tmp_filelist_filename, "w")
+     names = files.keys()
+     names.sort()
+     for name in names:
+          print name,files[name]
+     sys.stdout.close()
+     if posixpath.exists(filelist_filename):
+          os.unlink(filelist_filename)
+     os.rename(tmp_filelist_filename, filelist_filename)
Index: /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-unbuild
===================================================================
--- /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-unbuild	(revision 4860)
+++ /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-unbuild	(revision 4860)
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+
+import sys, os, re
+
+if (len(sys.argv) == 0):
+    print 'usage: %s: package.ipk' % sys.argv[0]
+    sys.exit(1)
+
+for filename in sys.argv[1:]:
+    m = re.match('((.*/)*)(.*)', filename)
+    pkg = m.group(3)
+    m = re.match('(.*)((.ipk)|(.deb))', filename)
+    if m:
+        pkg = m.group(1)
+
+    os.system('rm -fr %s' % pkg)
+    os.mkdir(pkg)
+    os.mkdir(pkg + '/CONTROL')
+
+    os.system('cd %s; (ar x ../%s || tar zxf ../%s) >& /dev/null' % (pkg, filename, filename))
+
+    os.system('tar xzf %s/data.tar.gz -C %s' % (pkg, pkg))
+    os.system('tar xzf %s/control.tar.gz -C %s/CONTROL' % (pkg, pkg))
+    os.system('rm -f %s/control.tar.gz %s/data.tar.gz %s/debian-binary' % (pkg, pkg, pkg))
Index: /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-update-index
===================================================================
--- /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-update-index	(revision 4860)
+++ /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-update-index	(revision 4860)
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+
+import sys, os
+from glob import glob
+import commands
+import ipkg
+
+pkg_dir=sys.argv[1]
+pkg_filename = sys.argv[2]
+
+if ( not pkg_dir or not pkg_filename ):
+	sys.stderr.write("Usage: ipkg-update-index <package_directory> <pkgfilename>\n")
+	sys.exit(1)
+
+packages = ipkg.Packages()
+
+packages.read_packages_file(pkg_dir + '/Packages')
+
+names = packages.packages.keys()
+
+packages.add_package(ipkg.Package(pkg_filename))
+
+packages.write_packages_file(pkg_dir + '/Packages.new')
+os.rename(pkg_dir + '/Packages.new', pkg_dir + '/Packages')
Index: /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-upload
===================================================================
--- /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-upload	(revision 4860)
+++ /ipk/ipkg-utils-050831/build/scripts-2.5/ipkg-upload	(revision 4860)
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+
+import sys, os, os.path, re
+
+# User-configurable options
+
+url='http://handhelds.org/~familiar/cgi-bin/upload-package.cgi'
+feed='unstable'
+
+def error(*msgs):
+    for m in msgs:
+        sys.stderr.write(m)
+        sys.stderr.write('\n')
+    sys.exit(1)
+
+# The actual script
+
+if len(sys.argv) == 1:
+    error(("Usage: %s file.ipk [file2.ipk ...]\n" % sys.argv[0]) ,
+          ("Uploads packages to Familiar's %s feed at handhelds.org" % feed))
+
+if os.system('which curl >/dev/null 2>&1') != 0:
+    error("Sorry: %s requires curl which appears to not be available." % sys.argv[0])
+
+for pkg in sys.argv[1:]:
+    if not os.path.exists(pkg):
+        error("%s: No such file or directory")
+    if not os.path.exists(pkg + '.asc'):
+        os.system('gpg -sb --armor %s' % pkg)
+
+
+for pkg in sys.argv[1:]:
+    print "Uploading %s to %s feed" % (pkg, feed)
+    m = re.match('.*.batch', pkg)
+    dict = {'feed': feed, 'pkg': pkg, 'url': url}
+    if m:
+        dict['tarfile'] = ('/tmp/ipkg-upload.%d.tar' % os.getpid())
+	os.system('rm -rf %(tarfile)s' % dict)
+        os.system('tar cf %(tarfile)s `awk \'{ print $2 }\' < %(pkg)s`' % dict)
+        os.system('curl \
+			-F feedname=%(feed)s \
+			-F datafilename=@%(tarfile)s \
+			-F batchfilename=@%(pkg)s \
+			-F signaturefilename=@%(pkg)s.asc \
+			$url 2>&1 | tee %(pkg)s.upload.html | egrep "(Error|Warning):" | sed \'s:</*p>::g;s:</*b>::g\''
+                  % dict)
+        os.system('rm -f %(tarfile)s' % dict)
+        os.system('grep -i signature %(pkg)s.upload.html' % dict)
+    else:
+        os.system('curl \
+            		-F feedname=%(feed)s \
+			-F filename=@%(pkg)s \
+			-F signaturefilename=@%(pkg)s.asc \
+		        -F sourcefilename="" \
+			%(url)s 2>&1 | tee %(pkg)s.upload.html | egrep "(Error|Warning):" | sed "s:</*p>::g;s:</*b>::g"'
+                  % dict)
+        os.system('grep -i signature %(pkg)s.upload.html' % dict)
+    print ("Done. See complete results in %(pkg)s.upload.html" % dict)
+
+
Index: /ipk/ipkg-utils-050831/ipkg-accept-incoming
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-accept-incoming	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-accept-incoming	(revision 4860)
@@ -0,0 +1,18 @@
+#!/bin/sh
+set -e
+
+INCOMING="/home/familiar/incoming"
+OUTGOING="/home/familiar/website/data/familiar/releases/unstable/binary/armv4l/"
+
+pkgs=`find -maxdepth 1 $INCOMING -name '*.ipk'`
+
+if [ -n "$pkgs" ]; then
+	for pkg in $pkgs; do
+		(cd $OUTGOING/unpacked; ipkg-unbuild $pkg)
+		mv $pkg $OUTGOING
+	done
+
+	cd $OUTGOING
+	ipkg-make-index . > Packages
+fi
+
Index: /ipk/ipkg-utils-050831/ipkg-build
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-build	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-build	(revision 4860)
@@ -0,0 +1,246 @@
+#!/bin/sh
+
+# ipkg-build -- construct a .ipk from a directory
+# Carl Worth <cworth@east.isi.edu>
+# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
+# 2003-04-25 rea@sr.unh.edu
+#   Updated to work on Familiar Pre0.7rc1, with busybox tar.
+#   Note it Requires: binutils-ar (since the busybox ar can't create)
+#   For UID debugging it needs a better "find".
+set -e
+
+version=1.0
+
+ipkg_extract_value() {
+	sed -e "s/^[^:]*:[[:space:]]*//"
+}
+
+required_field() {
+	field=$1
+
+	value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
+	if [ -z "$value" ]; then
+		echo "*** Error: $CONTROL/control is missing field $field" >&2
+		return 1
+	fi
+	echo $value
+	return 0
+}
+
+disallowed_field() {
+	field=$1
+
+	value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
+	if [ -n "$value" ]; then
+		echo "*** Error: $CONTROL/control contains disallowed field $field" >&2
+		return 1
+	fi
+	echo $value
+	return 0
+}
+
+pkg_appears_sane() {
+	local pkg_dir=$1
+
+	local owd=`pwd`
+	cd $pkg_dir
+
+	PKG_ERROR=0
+
+	tilde_files=`find . -name '*~'`
+	if [ -n "$tilde_files" ]; then
+	    if [ "$noclean" = "1" ]; then
+		echo "*** Warning: The following files have names ending in '~'.
+You probably want to remove them: " >&2
+		ls -ld $tilde_files
+		echo >&2
+	    else
+		echo "*** Removing the following files: $tilde_files"
+		rm -f "$tilde_files"
+	    fi
+	fi
+
+	large_uid_files=`find . -uid +99 || true`
+
+	if [ "$ogargs" = "" ]  && [ -n "$large_uid_files" ]; then
+		echo "*** Warning: The following files have a UID greater than 99.
+You probably want to chown these to a system user: " >&2
+		ls -ld $large_uid_files
+		echo >&2
+	fi
+	    
+
+	if [ ! -f "$CONTROL/control" ]; then
+		echo "*** Error: Control file $pkg_dir/$CONTROL/control not found." >&2
+		cd $owd
+		return 1
+	fi
+
+	pkg=`required_field Package`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	version=`required_field Version | sed 's/Version://; s/^.://g;'`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	arch=`required_field Architecture`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	required_field Maintainer >/dev/null
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	required_field Description >/dev/null
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	section=`required_field Section`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$section" ]; then
+	    echo "The Section field should have one of the following values:" >&2
+	    echo "admin, base, comm, editors, extras, games, graphics, kernel, libs, misc, net, text, web, x11" >&2
+	fi
+
+	priority=`required_field Priority`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$priority" ]; then
+	    echo "The Priority field should have one of the following values:" >&2
+	    echo "required, important, standard, optional, extra." >&2
+	    echo "If you don't know which priority value you should be using, then use \`optional'" >&2
+	fi
+
+	source=`required_field Source`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$source" ]; then
+	    echo "The Source field contain the URL's or filenames of the source code and any patches" 
+	    echo "used to build this package.  Either gnu-style tarballs or Debian source packages "
+	    echo "are acceptable.  Relative filenames may be used if they are distributed in the same"
+	    echo "directory as the .ipk file."
+	fi
+
+	disallowed_filename=`disallowed_field Filename`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	if echo $pkg | grep '[^a-z0-9.+-]'; then
+		echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
+		PKG_ERROR=1;
+	fi
+
+	local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
+	if [ -n "$bad_fields" ]; then
+		bad_fields=`echo $bad_fields`
+		echo "*** Error: The following fields in $CONTROL/control are missing a ':'" >&2
+		echo "	$bad_fields" >&2
+		echo "ipkg-build: This may be due to a missing initial space for a multi-line field value" >&2
+		PKG_ERROR=1
+	fi
+
+	for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
+		if [ -f $script -a ! -x $script ]; then
+			echo "*** Error: package script $script is not executable" >&2
+			PKG_ERROR=1
+		fi
+	done
+
+	if [ -f $CONTROL/conffiles ]; then
+		for cf in `cat $CONTROL/conffiles`; do
+			if [ ! -f ./$cf ]; then
+				echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2
+				PKG_ERROR=1
+			fi
+		done
+	fi
+
+	cd $owd
+	return $PKG_ERROR
+}
+
+###
+# ipkg-build "main"
+###
+ogargs=""
+outer=ar
+noclean=0
+usage="Usage: $0 [-c] [-C] [-o owner] [-g group] <pkg_directory> [<destination_directory>]"
+while getopts "cg:ho:v" opt; do
+    case $opt in
+	o ) owner=$OPTARG
+	    ogargs="--owner=$owner"
+	    ;;
+	g ) group=$OPTARG
+	    ogargs="$ogargs --group=$group"
+	    ;;
+        c ) outer=tar
+            ;;
+        C ) noclean=1
+            ;;
+	v ) echo $version
+	    exit 0
+	    ;;
+	h ) 	echo $usage  >&2 ;;
+	\? ) 	echo $usage  >&2
+	esac
+done
+
+
+shift $(($OPTIND - 1))
+
+# continue on to process additional arguments
+
+case $# in
+1)
+	dest_dir=$PWD
+	;;
+2)
+	dest_dir=$2
+	if [ "$dest_dir" = "." -o "$dest_dir" = "./" ] ; then
+	    dest_dir=$PWD
+	fi
+	;;
+*)
+	echo $usage >&2
+	exit 1 
+	;;
+esac
+
+pkg_dir=$1
+
+if [ ! -d $pkg_dir ]; then
+	echo "*** Error: Directory $pkg_dir does not exist" >&2
+	exit 1
+fi
+
+# CONTROL is second so that it takes precedence
+CONTROL=
+[ -d $pkg_dir/DEBIAN ] && CONTROL=DEBIAN
+[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
+if [ -z "$CONTROL" ]; then
+	echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
+	exit 1
+fi
+
+if ! pkg_appears_sane $pkg_dir; then
+	echo >&2
+	echo "ipkg-build: Please fix the above errors and try again." >&2
+	exit 1
+fi
+
+tmp_dir=$dest_dir/IPKG_BUILD.$$
+mkdir $tmp_dir
+
+echo $CONTROL > $tmp_dir/tarX
+( cd $pkg_dir && tar $ogargs -X $tmp_dir/tarX -czf $tmp_dir/data.tar.gz . )
+( cd $pkg_dir/$CONTROL && tar $ogargs -czf $tmp_dir/control.tar.gz . )
+rm $tmp_dir/tarX
+
+echo "2.0" > $tmp_dir/debian-binary
+
+pkg_file=$dest_dir/${pkg}_${version}_${arch}.ipk
+rm -f $pkg_file
+if [ "$outer" = "ar" ] ; then
+  ( cd $tmp_dir && ar -crf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
+else
+  ( cd $tmp_dir && tar -zcf $pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz )
+fi
+
+rm $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
+rmdir $tmp_dir
+
+echo "Packaged contents of $pkg_dir into $pkg_file"
Index: /ipk/ipkg-utils-050831/ipkg-buildpackage
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-buildpackage	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-buildpackage	(revision 4860)
@@ -0,0 +1,226 @@
+#!/bin/sh
+#
+# $Id: ipkg-buildpackage,v 1.1 2001/07/26 15:36:36 oku Exp $
+#
+# Author: Oliver Kurth <oliver.kurth@innominate.com>
+#
+# Description:
+# builds an ipkg package from a source tarball using ipkg-build. Idea stolen
+# from Debian dpkg-buildpackage.
+# 
+# - unpack the source tarball.
+# - cd to the source distribution, change whatever you need to make the
+#   package compile and work on the ipaq.
+# - create a directory 'ipkg'
+# - put all files which go to the 'CONTROL' directory of the root of the
+#   installed package into ipkg.
+# - the version (Version field in control) should match the version of the
+#   source tarball, optionally with a digit (eg. -1) appended.
+# - additionally, put a file there called 'rules' which is a shell script
+#   accepting arguments 'build', 'install' and 'clean'. It can be a 
+#   Makefile starting with the line '#!/usr/bin/make -f'
+#   * the build target does things like ./configure and make.
+#   * the install target installs to a temporary directory (make
+#   DESTDIR=/tmp/package) and removes unnecessary items (eg. man pages)
+#   * clean cleans ;-)
+#
+# You should run this with fakeroot (1) or as root.
+# If all went well, you will find a diff file and an *.ipk file in the
+# directory above.
+
+set -e
+
+#SCRIPTDIR=/usr/local/bin
+SCRIPTDIR=/other/kurth/ipaq-dev/familiar/dist/ipkg/util/
+
+SCRIPTNAME=`basename $0`
+
+ipkg_extract_value() {
+	sed -e "s/^[^:]*:[[:space:]]*//"
+}
+
+required_field() {
+	field=$1
+
+	value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
+	if [ -z "$value" ]; then
+		echo "ipkg-build: Error: $CONTROL/control is missing field $field" ;
+		PKG_ERROR=1
+	fi
+	echo $value
+}
+
+pkg_appears_sane_control() {
+	local pkg_dir=$1
+
+	local owd=`pwd`
+	cd $pkg_dir
+
+	if [ ! -f "$CONTROL/control" ]; then
+		echo "ipkg-build: Error: Control file $pkg_dir/$CONTROL/control not found."
+		cd $owd
+		return 1
+	fi
+
+	pkg=`required_field Package`
+	version=`required_field Version | sed 's/.*://;'`
+	arch=`required_field Architecture`
+	required_field Maintainer >/dev/null
+	required_field Description >/dev/null
+
+	if echo $pkg | grep '[^a-z0-9.+-]'; then
+		echo "ipkg-build: Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])"
+		PKG_ERROR=1;
+	fi
+
+	local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
+	if [ -n "$bad_fields" ]; then
+		bad_fields=`echo $bad_fields`
+		echo "ipkg-build: Error: The following fields in $CONTROL/control are missing a ':'"
+		echo "	$bad_fields"
+		echo "ipkg-build: This may be due to a missing initial space for a multi-line field value"
+		PKG_ERROR=1
+	fi
+
+	cd $owd
+	return $PKG_ERROR
+}
+
+pkg_appears_sane_scripts() {
+	local pkg_dir=$1
+
+	local owd=`pwd`
+	cd $pkg_dir
+
+	for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
+		if [ -f $script -a ! -x $script ]; then
+			echo "ipkg-build: Error: package script $script is not executable"
+			PKG_ERROR=1
+		fi
+	done
+
+	cd $owd
+	return $PKG_ERROR
+}
+
+pkg_dir_abs=`pwd`
+pkg_dir_base=`basename ${pkg_dir_abs}`
+
+pkg_dir=.
+
+[ -d ./CONTROL ] && CONTROL=./CONTROL
+[ -d ./ipkg ] && CONTROL=./ipkg
+if [ -z "$CONTROL" ]; then
+        echo "${SCRIPT_NAME}: Error: Directory $pkg_dir has no ipkg or CONTROL subdirectory."
+        exit 1
+fi
+
+if ! pkg_appears_sane_control $pkg_dir && pkg_appears_sane_control $pkg_dir; then
+        echo "Please fix the above errors and try again."
+        exit 1
+fi
+
+echo "Package = $pkg"
+echo "Version = $version"
+version_up=`echo ${version} | sed "s/\-[0-9]\+//"`
+echo "Upstream Version = $version_up"
+pkg_upname=${pkg}-${version_up}
+echo "Package Name = $pkg_upname"
+pkg_tarball=${pkg_upname}.tar.gz
+echo "Tarball Name = $pkg_tarball"
+
+if [ ! -x ${CONTROL}/rules ]; then
+	echo "${CONTROL}/rules not found or not executable."
+	exit 1
+fi
+
+#
+# unpack upstream tarball and make diff
+#
+if [ -e ../${pkg_tarball} ] ; then
+	(
+	set +e
+
+	cd ..
+
+	rm -rf ${pkg_upname}.tmp
+	rm -rf ${pkg_upname}.orig
+
+	mkdir ${pkg_upname}.tmp
+	cd ${pkg_upname}.tmp
+	echo "unpacking source tarball ${pkg_tarball}"
+	tar zxf ${pkg_dir_abs}/../${pkg_tarball}
+	dir=`find . -maxdepth 1 -name "*" -type d`
+	cnt=`echo $dir | wc -l`
+	if [ ${cnt} != 1 ] ; then
+		echo "Arrghh !!!!"
+		echo "upstream package contains more than one top level directory"
+		echo "giving up..."
+		exit 1
+	fi
+	mv ${dir} ${pkg_upname}.orig
+	mv ${pkg_upname}.orig ..
+	cd ..
+	echo "creating diff"
+	diff -uNr  ${pkg_upname}.orig ${pkg_dir_base} > ${pkg}-${version}.diff
+	rm -f ${pkg}-${version}.diff.gz
+	echo "gzipping ${pkg}-${version}.diff"
+	gzip ${pkg}-${version}.diff
+
+	echo "Removing temporary source directorys"
+	rm -rf ${pkg_upname}.tmp
+	rm -rf ${pkg_upname}.orig
+	)
+fi
+
+# build package
+if ! ${CONTROL}/rules build; then
+	echo "Build failed"
+	exit 1
+fi
+
+# install it to tmp directory
+if ! ${CONTROL}/rules install; then
+	echo "Install failed"
+	exit 1
+fi
+
+# copy contents of control directory
+mkdir /tmp/${pkg}/CONTROL
+
+files_required="control"
+files_optional="preinst postinst prerm postrm"
+
+for i in ${files_required} ; do
+	file=${CONTROL}/$i
+	
+	if [ -e ${file} ] ; then
+		cp $file /tmp/${pkg}/CONTROL
+	else
+		echo "required file ${file} missing"
+	fi
+done
+
+for i in ${files_optional} ; do
+	file=${CONTROL}/$i
+	
+	if [ -e ${file} ] ; then
+		cp $file /tmp/${pkg}/CONTROL
+	fi
+done
+
+# build the ipk package
+owd=`pwd`
+cd ..
+ipkg-build /tmp/${pkg} || exit 1
+
+rm -rf /tmp/${pkg}
+
+cd $owd
+if ! ${CONTROL}/rules clean; then
+	echo "Clean failed"
+	exit 1
+fi
+
+# Yep. That's it!
+exit 0
Index: /ipk/ipkg-utils-050831/ipkg-compare-indexes
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-compare-indexes	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-compare-indexes	(revision 4860)
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+import sys, os
+from glob import glob
+import commands
+import ipkg
+
+pkg_dir1 = sys.argv[1]
+pkg_dir2 = sys.argv[2]
+
+if ( not pkg_dir1 or not pkg_dir2 ):
+	sys.stderr.write("Usage: ipkg-update-index <package_directory1> <package_directory2>\n")
+	sys.exit(1)
+
+pkgs1 = ipkg.Packages()
+pkgs1.read_packages_file(pkg_dir1 + '/Packages')
+
+pkgs2 = ipkg.Packages()
+pkgs2.read_packages_file(pkg_dir2 + '/Packages')
+
+names1 = pkgs1.packages.keys()
+names2 = pkgs2.packages.keys()
+
+## union of the two names lists
+pkgs = {}
+for name in names1:
+    pkgs[name] = pkgs1.packages[name]
+for name in names2:
+    pkgs[name] = pkgs2.packages[name]
+
+names = pkgs.keys()
+names.sort() 
+for name in names:
+    pkg1 = None
+    pkg2 = None
+    if pkgs1.packages.has_key(name):
+        pkg1 = pkgs1.packages[name]
+    if pkgs2.packages.has_key(name):
+        pkg2 = pkgs2.packages[name]
+    if pkg1 and pkg2 and pkg1.version != pkg2.version:
+        print "CHANGED: %s from version %s to %s (%s)" % (pkg1.package, pkg1.version, pkg2.version, pkg2.maintainer)
+        cmd = "ipkg-diff %s %s > %s " % ((pkg_dir1 + pkg1.filename),  (pkg_dir2 + pkg2.filename), (pkg1.package + '.diff'))
+        print cmd
+	commands.getstatusoutput(cmd)
+    if not pkg1:
+        print "NEW: %s version %s (%s)"% (pkg2.package, pkg2.version, pkg2.maintainer)
+    if not pkg2:
+        print "DELETE: %s version %s (%s)"% (pkg1.package, pkg1.version, pkg1.maintainer)
+    
Index: /ipk/ipkg-utils-050831/ipkg-compare-versions.c
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-compare-versions.c	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-compare-versions.c	(revision 4860)
@@ -0,0 +1,172 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * vercmp.c - comparison of version numbers
+ *
+ * Copyright (C) 1995 Ian Jackson <iwj10@cus.cam.ac.uk>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2,
+ * or (at your option) any later version.
+ *
+ * This 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 dpkg; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+# define _(Text) Text
+
+struct versionrevision {
+  unsigned long epoch;
+  char *version;
+#if 0
+  const char *revision;
+  const char *familiar_revision;
+#endif
+};  
+
+static int verrevcmp(const char *val, const char *ref) 
+{
+  int vc, rc;
+  long vl, rl;
+  const char *vp, *rp;
+  const char *vsep, *rsep;
+
+  if (!val) val= "";
+  if (!ref) ref= "";
+  for (;;) {
+    vp= val;  while (*vp && !isdigit(*vp)) vp++;
+    rp= ref;  while (*rp && !isdigit(*rp)) rp++;
+    for (;;) {
+      vc= val == vp ? 0 : *val++;
+      rc= ref == rp ? 0 : *ref++;
+      if (!rc && !vc) break;
+      if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */
+      if (rc && !isalpha(rc)) rc += 256;
+      if (vc != rc) return vc - rc;
+    }
+    val= vp;
+    ref= rp;
+    vl=0;  if (isdigit(*vp)) vl= strtol(val,(char**)&val,10);
+    rl=0;  if (isdigit(*rp)) rl= strtol(ref,(char**)&ref,10);
+    if (vl != rl) return vl - rl;
+
+    vc = *val;
+    rc = *ref;
+    vsep = strchr(".-", vc);
+    rsep = strchr(".-", rc);
+    if (vsep && !rsep) return -1;
+    if (!vsep && rsep) return +1;
+
+    if (!*val && !*ref) return 0;
+    if (!*val) return -1;
+    if (!*ref) return +1;
+  }
+}
+
+int versioncompare(const struct versionrevision *version,
+                   const struct versionrevision *refversion) 
+{
+  int r;
+
+  if (version->epoch > refversion->epoch) return 1;
+  if (version->epoch < refversion->epoch) return -1;
+  r= verrevcmp(version->version,refversion->version);  if (r) return r;
+  return r;
+#if 0
+  r= verrevcmp(version->revision,refversion->revision); if (r) return r;
+  return verrevcmp(version->familiar_revision,refversion->familiar_revision);
+#endif
+}
+
+int versionsatisfied3(const struct versionrevision *it,
+                      const struct versionrevision *ref,
+                      const char *op) 
+{
+  int r;
+  r= versioncompare(it,ref);
+  if (strcmp(op, "<=") == 0 || strcmp(op, "<") == 0)
+    return r <= 0;
+  if (strcmp(op, ">=") == 0 || strcmp(op, ">") == 0)
+    return r >= 0;
+  if (strcmp(op, "<<") == 0)
+    return r < 0;
+  if (strcmp(op, ">>") == 0)
+    return r > 0;
+  if (strcmp(op, "=") == 0)
+    return r == 0;
+  fprintf(stderr, "unknown operator: %s", op);
+
+  exit(1);
+}
+
+const char *parseversion(struct versionrevision *rversion, const char *string) 
+{
+  char *hyphen, *colon, *eepochcolon;
+  unsigned long epoch;
+
+  if (!*string) return _("version string is empty");
+  
+  colon= strchr(string,':');
+  if (colon) {
+    epoch= strtoul(string,&eepochcolon,10);
+    if (colon != eepochcolon) return _("epoch in version is not number");
+    if (!*++colon) return _("nothing after colon in version number");
+    string= colon;
+    rversion->epoch= epoch;
+  } else {
+    rversion->epoch= 0;
+  }
+
+#if 0
+  rversion->revision = "";
+  rversion->familiar_revision = "";
+#endif
+
+  rversion->version= malloc(strlen(string)+1);
+  strcpy(rversion->version, string);
+
+#if 0
+  fprintf(stderr,"Parsed version: %lu, %s\n",
+	  rversion->epoch,
+	  rversion->version);
+#endif
+	  
+  return 0;
+}
+
+int main(int argc, char *argv[]) 
+{
+  const char *err;
+  struct versionrevision ver, ref;
+
+  if (argc < 4) {
+    fprintf(stderr, "usage: %s: version op refversion\n", argv[0]);
+    return 2;
+  }
+
+  err = parseversion(&ver, argv[1]);
+  if (err) {
+    fprintf(stderr, "Invalid version `%s': %s\n", argv[1], err);
+    return 2;
+  }
+    
+  err = parseversion(&ref, argv[3]);
+  if (err) {
+    fprintf(stderr, "Invalid version `%s': %s\n", argv[3], err);
+    return 2;
+  }
+
+  return ! versionsatisfied3(&ver, &ref, argv[2]);
+}
+
+
Index: /ipk/ipkg-utils-050831/ipkg-compare-versions.sh
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-compare-versions.sh	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-compare-versions.sh	(revision 4860)
@@ -0,0 +1,77 @@
+#!/bin/sh
+set -e
+
+# This is a little experiment to see how expensive it would be to
+# compare versions in a shell script. This script is not done yet
+# and the nasiest part is still left undone, (the fact that in Debian
+# versions all letters compare less than all non-letters).
+#
+# It looks to me like version comprehension might be the feature that pushes 
+# ipkg from /bin/sh to compiled C code...
+
+if [ $# -lt 3 ]; then
+	echo "
+usage: ipkg-compare-versions v1 op v2
+	where op in (<<, <=, =, >=, >>)
+Return value is 0 if v1 op v2 is satisfied, 1 otherwise"
+	exit 2
+fi
+
+v1=$1
+op=$2
+v2=$3
+
+# Debian has a little historical problem with operators...
+may_be_equal=0
+case $op in
+'>>')
+	op="-gt"
+;;
+'<<')
+	op="-lt"
+;;
+'>'|'>=')
+	op="-gt"
+	may_be_equal=1
+;;
+'<'|'<=')
+	op="-lt"
+	may_be_equal=1
+;;
+'=')
+	may_be_equal=1
+;;
+*)
+	echo "ipkg_compare_versions: Invalid operator \`$op' valid operators are (<<, <=, =, >=, >>)"
+	exit 1
+;;
+esac
+
+if [ $may_be_equal == 1 -a $v1 == $v2 ]; then
+	exit 0;
+elif [ $op == '=' ]; then
+	exit 1;
+fi
+
+epoch1=`echo $v1 | sed -ne 's/:.*//p'`
+v1=`echo $v1 | sed -e 's/^[^:]*://'`
+epoch2=`echo $v2 | sed -ne 's/:.*//p'`
+v2=`echo $v2 | sed -e 's/^[^:]*://'`
+
+upstream1=`echo $v1 | sed -e '/-/s/\(.*\)-.*/\1/'`
+debian_rev1=`echo $v1 | sed -ne 's/.*-//p'`
+upstream2=`echo $v2 | sed -e '/-/s/\(.*\)-.*/\1/'`
+debian_rev2=`echo $v2 | sed -ne 's/.*-//p'`
+
+echo "$epoch1:$upstream1-$debian_rev1 $op $epoch2:$upstream2-$debian_rev2"
+
+exit 3
+
+[ -z $epoch1 ] && epoch1="0"
+[ -z $epoch2 ] && epoch2="0"
+
+if [ $epoch1 != $epoch2 ]; then
+	exit `[ $epoch1 $op $epoch2 ]`
+fi
+
+exit 3
Index: /ipk/ipkg-utils-050831/ipkg-deb-build
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-deb-build	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-deb-build	(revision 4860)
@@ -0,0 +1,176 @@
+#!/bin/sh
+
+# ipkg-deb-build -- construct a debian file format .ipk from a directory
+# Jamey Hicks <jamey.hicks@hp.com>
+# Carl Worth <cworth@east.isi.edu>
+# based on a script by Steve Redler IV, steve@sr-tech.com 5-21-2001
+set -e
+
+ipkg_extract_value() {
+	sed -e "s/^[^:]*:[[:space:]]*//"
+}
+
+required_field() {
+	field=$1
+
+	value=`grep "^$field:" < $CONTROL/control | ipkg_extract_value`
+	if [ -z "$value" ]; then
+		echo "*** Error: $CONTROL/control is missing field $field" >&2
+		return 1
+	fi
+	echo $value
+	return 0
+}
+
+pkg_appears_sane() {
+	local pkg_dir=$1
+
+	local owd=`pwd`
+	cd $pkg_dir
+
+	PKG_ERROR=0
+
+	tilde_files=`find . -name '*~'`
+	if [ -n "$tilde_files" ]; then
+		echo "*** Warning: The following files have names ending in '~'.
+You probably want to remove them: " >&2
+		ls -ld $tilde_files
+		echo >&2
+	fi
+
+	large_uid_files=`find . -uid +99`
+	if [ -n "$large_uid_files" ]; then
+		echo "*** Warning: The following files have a UID greater than 99.
+You probably want to chown these to a system user: " >&2
+		ls -ld $large_uid_files
+		echo >&2
+	fi
+	    
+
+	if [ ! -f "$CONTROL/control" ]; then
+		echo "*** Error: Control file $pkg_dir/$CONTROL/control not found." >&2
+		cd $owd
+		return 1
+	fi
+
+	pkg=`required_field Package`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	version=`required_field Version | sed 's/.*://;'`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	arch=`required_field Architecture`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	required_field Maintainer >/dev/null
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	required_field Description >/dev/null
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+
+	section=`required_field Section`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$section" ]; then
+	    echo "The Section field should have one of the following values:" >&2
+	    echo "admin, base, comm, editors, extras, games, graphics, kernel, libs, misc, net, text, web, x11" >&2
+	fi
+
+	priority=`required_field Priority`
+	[ "$?" -ne 0 ] && PKG_ERROR=1
+	if [ -z "$priority" ]; then
+	    echo "The Priority field should have one of the following values:" >&2
+	    echo "required, important, standard, optional, extra." >&2
+	    echo "If you don't know which priority value you should be using, then use \`optional'" >&2
+	fi
+
+	if echo $pkg | grep '[^a-z0-9.+-]'; then
+		echo "*** Error: Package name $name contains illegal characters, (other than [a-z0-9.+-])" >&2
+		PKG_ERROR=1;
+	fi
+
+	local bad_fields=`sed -ne 's/^\([^[:space:]][^:[:space:]]\+[[:space:]]\+\)[^:].*/\1/p' < $CONTROL/control | sed -e 's/\\n//'`
+	if [ -n "$bad_fields" ]; then
+		bad_fields=`echo $bad_fields`
+		echo "*** Error: The following fields in $CONTROL/control are missing a ':'" >&2
+		echo "	$bad_fields" >&2
+		echo "ipkg-build: This may be due to a missing initial space for a multi-line field value" >&2
+		PKG_ERROR=1
+	fi
+
+	for script in $CONTROL/preinst $CONTROL/postinst $CONTROL/prerm $CONTROL/postrm; do
+		if [ -f $script -a ! -x $script ]; then
+			echo "*** Error: package script $script is not executable" >&2
+			PKG_ERROR=1
+		fi
+	done
+
+	if [ -f $CONTROL/conffiles ]; then
+		for cf in `cat $CONTROL/conffiles`; do
+			if [ ! -f ./$cf ]; then
+				echo "*** Error: $CONTROL/conffiles mentions conffile $cf which does not exist" >&2
+				PKG_ERROR=1
+			fi
+		done
+	fi
+
+	cd $owd
+	return $PKG_ERROR
+}
+
+###
+# ipkg-build "main"
+###
+
+case $# in
+1)
+	dest_dir=.
+	;;
+2)
+	dest_dir=$2
+	;;
+*)
+	echo "Usage: ipkg-build <pkg_directory> [<destination_directory>]" >&2
+	exit 1 
+	;;
+esac
+
+pkg_dir=$1
+
+if [ ! -d $pkg_dir ]; then
+	echo "*** Error: Directory $pkg_dir does not exist" >&2
+	exit 1
+fi
+
+# CONTROL is second so that it takes precedence
+CONTROL=
+[ -d $pkg_dir/DEBIAN ] && CONTROL=DEBIAN
+[ -d $pkg_dir/CONTROL ] && CONTROL=CONTROL
+if [ -z "$CONTROL" ]; then
+	echo "*** Error: Directory $pkg_dir has no CONTROL subdirectory." >&2
+	exit 1
+fi
+
+if ! pkg_appears_sane $pkg_dir; then
+	echo >&2
+	echo "ipkg-build: Please fix the above errors and try again." >&2
+	exit 1
+fi
+
+tmp_dir=$dest_dir/IPKG_BUILD.$$
+mkdir $tmp_dir
+
+tar -C $pkg_dir -czf $tmp_dir/data.tar.gz . --exclude=$CONTROL
+tar -C $pkg_dir/$CONTROL -czf $tmp_dir/control.tar.gz .
+
+echo "2.0" > $tmp_dir/debian-binary
+
+pkg_file=${pkg}_${version}_${arch}.ipk
+pkg_dir=$PWD
+cd $tmp_dir
+ar crf $pkg_dir/$pkg_file ./debian-binary ./data.tar.gz ./control.tar.gz
+cd $pkg_dir
+mv $pkg_file $dest_dir
+rm -f $tmp_dir/debian-binary $tmp_dir/data.tar.gz $tmp_dir/control.tar.gz
+rmdir $tmp_dir
+
+echo "Packaged contents of $pkg_dir into $pkg_file"
Index: /ipk/ipkg-utils-050831/ipkg-deb-unbuild
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-deb-unbuild	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-deb-unbuild	(revision 4860)
@@ -0,0 +1,25 @@
+#!/bin/bash
+set -e
+
+if [ $# -lt 1 ]; then
+	echo "usage: $0 package_name"
+	exit 1
+fi
+
+## This script is a nasty hack... especially the cp of $filename. Yuck!
+
+filename="$1"
+basefile=`echo $filename | sed 's/.*\///'`
+pkg=`echo $basefile | sed 's/\.deb$//' | sed 's/\.ipk$//'`
+
+mkdir $pkg
+cp $filename $pkg
+cd $pkg
+ar -x $basefile
+tar xzf data.tar.gz
+mkdir DEBIAN
+cd DEBIAN
+tar xzf ../control.tar.gz
+cd ..
+rm -f control.tar.gz data.tar.gz debian-binary $basefile
+cd ../..
Index: /ipk/ipkg-utils-050831/ipkg-diff
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-diff	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-diff	(revision 4860)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+pkg1=$1
+dir1=`echo $pkg1 | sed s/.ipk//`
+dir1=`basename $dir1` 
+pkg2=$2
+dir2=`echo $pkg2 | sed s/.ipk//`
+dir2=`basename $dir2` 
+
+ipkg-unbuild $pkg2
+ipkg-unbuild $pkg1
+
+diff -urN $dir1 $dir2
+
+rm -fr $dir1 $dir2
Index: /ipk/ipkg-utils-050831/ipkg-extract-file
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-extract-file	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-extract-file	(revision 4860)
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+set -e
+
+if [ $# -lt 1 ]; then
+	echo "usage: $0: package.ipk filename ..."
+	exit 1
+fi
+
+if [ $# -eq 2 ]; then
+  ipkgfilename=$1
+  filename=$2
+else
+  echo "usage: $0 ipkgfilename filename"  
+  exit -1
+fi
+
+case $ipkgfilename in
+http:*)
+    wget -N $ipkgfilename
+    ipkgfilename=`basename $ipkgfilename`
+    echo eez http url $ipkgfilename
+;;
+ftp:*)
+    wget -N $ipkgfilename
+    ipkgfilename=`basename $ipkgfilename`
+    echo eez ftp url $ipkgfilename
+;;
+esac
+
+
+tmpdir=/tmp/ipkg-extract-$$
+mkdir $tmpdir
+
+pkgdir=$tmpdir/`basename $ipkgfilename | sed 's/.*\///;s/.ipk$//;s/.deb$//'`
+
+mkdir -p $pkgdir/CONTROL
+
+cur_dir=$PWD
+cd $pkgdir; (ar x $cur_dir/$ipkgfilename || tar zxf $cur_dir/$ipkgfilename) >& /dev/null
+cd $cur_dir
+
+tar xzf $pkgdir/data.tar.gz -C $pkgdir
+tar xzf $pkgdir/control.tar.gz -C $pkgdir/CONTROL
+rm -f $pkgdir/control.tar.gz $pkgdir/data.tar.gz $pkgdir/debian-binary
+
+cp $pkgdir/$filename `basename $filename`
+ls -l `basename $filename`
+file `basename $filename`
+rm -fr $tmpdir
Index: /ipk/ipkg-utils-050831/ipkg-ipk
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-ipk	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-ipk	(revision 4860)
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo "ipkg-ipk is now deprecated in favor of the new ipkg-build."
+echo "please use ipkg-build instead"
+
+exit 1
Index: /ipk/ipkg-utils-050831/ipkg-link
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-link	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-link	(revision 4860)
@@ -0,0 +1,136 @@
+#!/bin/sh
+#
+# <zaurus@bredband.net>
+# Modified by Aman Gupta <oz@themastermind1.net>
+# Modified by Matthias Hentges to adjust to changes in OZ <oe@hentges.net>
+
+usage () {
+	echo "Usage: "
+	echo "    $0 add    packagename (links \"packagename\" to root filesystem)"
+	echo "    $0 remove packagename (unlinks \"packagename\" from root filesystem)"
+	echo "    $0 list   mountpoint  (lists packages on \"mountpoint\", e.g. '/mnt/card')"
+	echo "    $0 mount  mountpoint  (links all packages on \"mountpoint\", e.g. '/mnt/card')"
+	echo "    $0 umount mountpoint  (unlinks all packages on \"mountpoint\", e.g. '/mnt/card')"
+	exit
+}
+
+findpackage () {
+	echo "*** Locating package"
+		
+	if test -e /etc/ipkg.conf
+	then
+		valid_mount_points=`cat /etc/ipkg.conf| grep ^dest| awk '{print $3}'|sed "s/\/$//"`
+	else
+		valid_mount_points="/mnt/card /mnt/cf /mnt/ram /media/card /media/cf /media/ram"
+	fi
+	
+	for mount_point in $valid_mount_points
+	do
+		if [ -e "$mount_point/usr/lib/ipkg/info/$PACKAGE.list" ]; then
+			PREFIX="$mount_point"
+			files=`cat "$PREFIX/usr/lib/ipkg/info/$PACKAGE.list" |sed -e "s#$mount_point##g"`
+		fi
+	done
+	
+	
+	if test -z "$files"
+	then
+		echo "Package \"$PACKAGE\" not found."
+		exit
+	else	
+		echo "*** Found package on $PREFIX"
+	fi
+}
+
+add () {
+	echo "*** Adding $PACKAGE"
+	echo "$files" |
+	while read line; do
+		test -L "$line" && rm "$line"
+		if [ ! -e "$line" ]; then
+			# Only if it doesn't already exist.
+			if [ -d "$PREFIX$line" ]; then
+				# It's a directory.
+				`mkdir "$line"`
+			else
+				# It's a file.
+				[ ! -d `dirname $line` ] && mkdir -p `dirname $line`
+				`ln -s "$PREFIX$line" "$line"`
+			fi
+		fi
+	done
+}
+
+remove () {
+	echo "*** Removing $PACKAGE"
+
+	echo "$files" |
+	while read line; do
+		if [ -e "$line" ]; then
+			# File/Directory exists.
+			if [ -d "$line" ]; then
+				# Directory.
+				contents=$(ls -1 "$line")
+				if [ ! "$contents" ]; then
+					# Empty directory
+					rmdir "$line"
+				fi
+			elif [ -L "$line" ]; then
+				rm "$line"
+			fi
+		fi
+	done
+}
+
+list () {
+	filelist=""
+	files=`ls -1 $LOCATION/usr/lib/ipkg/info/*.list`
+	for filename in $files; do
+		filename=${filename##*/}
+		filename=${filename%%.list}
+		filelist="$filelist $filename"
+	done
+}
+
+COMMAND=$1
+PACKAGE=$2
+LOCATION=$2
+
+if [ $# -ne 2 ]
+then
+	usage
+fi
+
+echo "*** Command: $COMMAND"
+case "$COMMAND" in
+	"add" )
+		findpackage
+		add
+		;;
+	"remove" )
+		findpackage
+		remove
+		;;
+	"list" )
+		list
+		for file in $filelist; do
+			echo $file
+		done
+		;;
+	"mount" )
+		list
+		for file in $filelist; do
+			$0 add $file
+		done
+		;;
+	"umount" )
+		list
+		for file in $filelist; do
+			$0 remove $file
+		done
+esac
+
+echo "*** Done."
+echo ""
+exit
+
Index: /ipk/ipkg-utils-050831/ipkg-make-familiar
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-make-familiar	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-make-familiar	(revision 4860)
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+set -e
+
+. /etc/ipkg.conf
+
+MKFSJFFS2_FLAGS="-p -e 0x40000"
+
+ipkg update
+
+if ! ipkg install $*; then
+	echo "ipkg-make-familiar: *** Crash and Burn ***"
+	exit 1
+fi
+
+echo "Creating familiar.jffs2"
+chown -R root:root $IPKG_ROOT
+cd $IPKG_ROOT
+mkfs.jffs2 $MKFSJFFS2_FLAGS > ../familiar.jffs2
Index: /ipk/ipkg-utils-050831/ipkg-make-index
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-make-index	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-make-index	(revision 4860)
@@ -0,0 +1,183 @@
+#!/usr/bin/python
+# $Id: ipkg-make-index,v 1.22 2005/03/03 16:39:04 jamey Exp $
+
+import sys, os, posixpath
+from glob import glob
+import commands
+import ipkg
+import getopt
+import string
+import re
+print "start"
+verbose = 0
+
+sys.stderr.write("hallo!")
+
+def usage():
+     sys.stderr.write("%s [-h] [-s] [-m] [-l Packages.filelist] [-p Packages] [-r Packages.old] [-L localesdir] [-v] packagesdir\n" % (sys.argv[0],))
+     sys.exit(-1)
+
+def to_morgue(filename):
+     morgue_dir = pkg_dir + "/morgue"
+     if verbose:
+          sys.stderr.write ("Moving " + filename + " to morgue\n")
+     if not os.path.exists(morgue_dir):
+          os.mkdir(morgue_dir)
+     if os.path.exists(pkg_dir + "/" + filename):
+          os.rename(pkg_dir + "/" + filename, morgue_dir + "/" + filename)
+     if os.path.exists(pkg_dir + "/" + filename + ".asc"):
+          os.rename(pkg_dir + "/" + filename + ".asc", morgue_dir + "/" + filename + ".asc")
+
+locales_dir = None
+def to_locale(filename, locale):
+     locale_dir = pkg_dir + '/' + locales_dir + '/' + locale + "/"
+     if verbose:
+          sys.stderr.write ("Moving " + filename + " to " + locale_dir + "\n")
+     if not os.path.exists(locale_dir):
+          os.mkdir(locale_dir)
+     os.rename(pkg_dir + "/" + filename, locale_dir + "/" + filename)
+     if os.path.exists(pkg_dir + "/" + filename + ".asc"):
+          os.rename(pkg_dir + "/" + filename + ".asc", locale_dir + "/" + filename + ".asc")
+
+old_filename = None
+packages_filename = None
+filelist_filename = "Packages.filelist"
+opt_s = 0
+opt_m = 0
+(opts, remaining_args) = getopt.getopt(sys.argv[1:], "hl:p:vsmr:L:")
+for (optkey, optval) in opts:
+     if optkey == '-h': 
+          usage()
+     if optkey == '-s': 
+          opt_s = 1
+     if optkey == '-p': 
+          packages_filename = optval
+     if optkey == '-l':
+          filelist_filename = optval
+     if optkey == '-v':
+          verbose = 1
+     if optkey == '-m':
+          opt_m = 1
+     if optkey == '-r':
+          old_filename = optval
+     if optkey == '-L':
+          locales_dir = optval
+
+if ( not remaining_args ):
+     usage()
+
+pkg_dir=remaining_args[0]
+
+packages = ipkg.Packages()
+
+old_pkg_hash = {}
+if packages_filename and not old_filename and os.path.exists(packages_filename):
+     old_filename = packages_filename
+
+if old_filename:
+     if (verbose):
+          sys.stderr.write("Reading package list from " + old_filename + "\n")
+     old_packages = ipkg.Packages()
+     old_packages.read_packages_file(old_filename)
+     for k in old_packages.packages.keys():
+          p = old_packages.packages[k]
+          old_pkg_hash[p.filename] = p
+
+if (verbose):
+     sys.stderr.write("Reading in all the package info from %s\n" % (pkg_dir, ))
+files=glob(pkg_dir + '/*.ipk') + glob(pkg_dir + '/*.deb')
+files.sort()
+for filename in files:
+     basename = os.path.basename(filename)
+     if old_pkg_hash.has_key(basename):
+          if (verbose):
+               sys.stderr.write("Found %s in Packages\n" % (filename,))
+          pkg = old_pkg_hash[basename]
+     else:
+          if (verbose):
+               sys.stderr.write("Reading info for package %s\n" % (filename,))
+          pkg = ipkg.Package(filename)
+     pkg_key = ("%s:%s" % (pkg.package, pkg.architecture))
+     if (packages.packages.has_key(pkg_key)):
+          old_filename = packages.packages[pkg_key].filename
+     else:
+          old_filename = ""
+     s = packages.add_package(pkg)
+     if s == 0:
+          if old_filename:
+               # old package was displaced by newer
+               if opt_m:
+                    to_morgue(old_filename)
+               if opt_s:
+                    print pkg_dir + "/" + old_filename
+     else:
+          if opt_m:
+               to_morgue(basename)
+          if opt_s:
+               print filename
+
+if opt_s:
+     sys.exit(0)
+
+if verbose:
+     sys.stderr.write("Generating Packages file\n")
+if packages_filename:
+     old_stdout = sys.stdout
+     tmp_packages_filename = ("%s.%d" % (packages_filename, os.getpid()))
+     sys.stdout = open(tmp_packages_filename, "w")
+names = packages.packages.keys()
+names.sort()
+for name in names:
+     pkg = packages.packages[name]
+     if locales_dir and pkg.depends:
+         depends = string.split(pkg.depends, ',')
+         locale = None
+         for d in depends:
+              m = re.match('.*virtual-locale-([a-zA-Z]+).*', d)
+              mp = re.match('locale-base-([a-zA-Z]+)([-+])?.*', pkg.package)
+              if m:
+                   locale = m.group(1)
+              if mp:
+                   locale = mp.group(1)
+         if locale:
+              to_locale(pkg.filename, locale)
+              continue
+     if (verbose):
+          sys.stderr.write("Writing info for package %s\n" % (pkg.package,))
+     print pkg
+if packages_filename:
+     sys.stdout.close()
+     sys.stdout = old_stdout
+     gzip_filename = ("%s.gz" % packages_filename)
+     tmp_gzip_filename = ("%s.%d" % (gzip_filename, os.getpid()))
+     gzip_cmd = "gzip -9c < %s > %s" % (tmp_packages_filename, tmp_gzip_filename)
+#     gzip_cmd = "gzip -c < %s > %s" % (tmp_packages_filename, tmp_gzip_filename)
+     (rc, outtext) = commands.getstatusoutput(gzip_cmd)
+     print outtext
+     os.rename(tmp_packages_filename, packages_filename)
+     os.rename(tmp_gzip_filename, gzip_filename)
+
+
+if verbose:	
+     sys.stderr.write("Generate Packages.filelist file\n")
+files = {}
+names = packages.packages.keys()
+names.sort()
+for name in names:
+     for fn in packages[name].get_file_list():
+          (h,t) = os.path.split(fn)
+          if not t: continue
+          if not files.has_key(t): files[t] = name+':'+fn
+          else: files[t] = files[t] + ',' + name+':'+fn
+
+if filelist_filename:
+     tmp_filelist_filename = ("%s.%d" % (filelist_filename, os.getpid()))
+     sys.stdout = open(tmp_filelist_filename, "w")
+     names = files.keys()
+     names.sort()
+     for name in names:
+          print name,files[name]
+     sys.stdout.close()
+     if posixpath.exists(filelist_filename):
+          os.unlink(filelist_filename)
+     os.rename(tmp_filelist_filename, filelist_filename)
Index: /ipk/ipkg-utils-050831/ipkg-show-deps
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-show-deps	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-show-deps	(revision 4860)
@@ -0,0 +1,89 @@
+#!/usr/bin/python
+# $Id: ipkg-show-deps,v 1.2 2004/03/06 13:08:33 pb Exp $
+
+import sys, os, posixpath
+from glob import glob
+import commands
+import ipkg
+import getopt
+import string
+import re
+
+verbose = 0
+
+def usage():
+     sys.stderr.write("%s [-p Packages] package ...\n" % (sys.argv[0],))
+     sys.exit(-1)
+
+packages_filename = "Packages"
+(opts, remaining_args) = getopt.getopt(sys.argv[1:], "hp:")
+for (optkey, optval) in opts:
+     if optkey == '-h': 
+          usage()
+     if optkey == '-p': 
+          packages_filename = optval
+
+if ( not remaining_args ):
+     usage()
+
+packages = ipkg.Packages()
+packages.read_packages_file(packages_filename)
+
+required = {}
+provider_hash = {}
+
+def split_list(str):
+     r = []
+     l = string.split(str, ",")
+     for i in l:
+          ll = string.split(i, "|")
+          for ii in ll:
+               ii = string.strip(ii)
+               r.append(ii)
+     return r
+
+for i in packages.packages.keys():
+     p = packages.packages[i]
+     if not provider_hash.has_key(p.package):
+          provider_hash[p.package] = []
+     provider_hash[p.package].append(p)
+     if p.provides:
+          provides = string.split(p.provides, ",")
+          for prov in provides:
+               prov = string.strip(prov)
+               if not provider_hash.has_key(prov):
+                    provider_hash[prov] = []
+               provider_hash[prov].append(p)
+
+def find_package(name):
+     if provider_hash.has_key(name):
+          return provider_hash[name]
+     return None
+
+def recurse(pkg):
+     required[pkg.package] = 1
+     if pkg.depends:
+          deps = split_list(pkg.depends)
+          for dep in deps:
+               dep = re.sub("\s*\(.*\)", "", dep)
+               dep = re.sub("\*$", "", dep)
+               newpkgs = find_package(dep)
+               if newpkgs:
+                    for newpkg in newpkgs:
+	                 if required.has_key(newpkg.package):
+			      return
+                    recurse(newpkgs[0])
+               else:
+                    sys.stderr.write("unsatisfied dependency of %s on '%s'\n" % (pkg.package, dep))
+
+for root in remaining_args:
+     pkgs = find_package(root)
+     if not pkgs:
+          sys.stderr.write("Can't find root package '%s'\n" % root)
+          sys.exit(-1)
+     for p in pkgs:
+          recurse(p)
+     
+for pkg in required.keys():
+     print pkg
+
Index: /ipk/ipkg-utils-050831/ipkg-unbuild
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-unbuild	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-unbuild	(revision 4860)
@@ -0,0 +1,24 @@
+#!/usr/bin/python
+
+import sys, os, re
+
+if (len(sys.argv) == 0):
+    print 'usage: %s: package.ipk' % sys.argv[0]
+    sys.exit(1)
+
+for filename in sys.argv[1:]:
+    m = re.match('((.*/)*)(.*)', filename)
+    pkg = m.group(3)
+    m = re.match('(.*)((.ipk)|(.deb))', filename)
+    if m:
+        pkg = m.group(1)
+
+    os.system('rm -fr %s' % pkg)
+    os.mkdir(pkg)
+    os.mkdir(pkg + '/CONTROL')
+
+    os.system('cd %s; (ar x ../%s || tar zxf ../%s) >& /dev/null' % (pkg, filename, filename))
+
+    os.system('tar xzf %s/data.tar.gz -C %s' % (pkg, pkg))
+    os.system('tar xzf %s/control.tar.gz -C %s/CONTROL' % (pkg, pkg))
+    os.system('rm -f %s/control.tar.gz %s/data.tar.gz %s/debian-binary' % (pkg, pkg, pkg))
Index: /ipk/ipkg-utils-050831/ipkg-update-index
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-update-index	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-update-index	(revision 4860)
@@ -0,0 +1,24 @@
+#!/usr/bin/env python2.1
+
+import sys, os
+from glob import glob
+import commands
+import ipkg
+
+pkg_dir=sys.argv[1]
+pkg_filename = sys.argv[2]
+
+if ( not pkg_dir or not pkg_filename ):
+	sys.stderr.write("Usage: ipkg-update-index <package_directory> <pkgfilename>\n")
+	sys.exit(1)
+
+packages = ipkg.Packages()
+
+packages.read_packages_file(pkg_dir + '/Packages')
+
+names = packages.packages.keys()
+
+packages.add_package(ipkg.Package(pkg_filename))
+
+packages.write_packages_file(pkg_dir + '/Packages.new')
+os.rename(pkg_dir + '/Packages.new', pkg_dir + '/Packages')
Index: /ipk/ipkg-utils-050831/ipkg-upload
===================================================================
--- /ipk/ipkg-utils-050831/ipkg-upload	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg-upload	(revision 4860)
@@ -0,0 +1,60 @@
+#!/usr/bin/python
+
+import sys, os, os.path, re
+
+# User-configurable options
+
+url='http://handhelds.org/~familiar/cgi-bin/upload-package.cgi'
+feed='unstable'
+
+def error(*msgs):
+    for m in msgs:
+        sys.stderr.write(m)
+        sys.stderr.write('\n')
+    sys.exit(1)
+
+# The actual script
+
+if len(sys.argv) == 1:
+    error(("Usage: %s file.ipk [file2.ipk ...]\n" % sys.argv[0]) ,
+          ("Uploads packages to Familiar's %s feed at handhelds.org" % feed))
+
+if os.system('which curl >/dev/null 2>&1') != 0:
+    error("Sorry: %s requires curl which appears to not be available." % sys.argv[0])
+
+for pkg in sys.argv[1:]:
+    if not os.path.exists(pkg):
+        error("%s: No such file or directory")
+    if not os.path.exists(pkg + '.asc'):
+        os.system('gpg -sb --armor %s' % pkg)
+
+
+for pkg in sys.argv[1:]:
+    print "Uploading %s to %s feed" % (pkg, feed)
+    m = re.match('.*.batch', pkg)
+    dict = {'feed': feed, 'pkg': pkg, 'url': url}
+    if m:
+        dict['tarfile'] = ('/tmp/ipkg-upload.%d.tar' % os.getpid())
+	os.system('rm -rf %(tarfile)s' % dict)
+        os.system('tar cf %(tarfile)s `awk \'{ print $2 }\' < %(pkg)s`' % dict)
+        os.system('curl \
+			-F feedname=%(feed)s \
+			-F datafilename=@%(tarfile)s \
+			-F batchfilename=@%(pkg)s \
+			-F signaturefilename=@%(pkg)s.asc \
+			$url 2>&1 | tee %(pkg)s.upload.html | egrep "(Error|Warning):" | sed \'s:</*p>::g;s:</*b>::g\''
+                  % dict)
+        os.system('rm -f %(tarfile)s' % dict)
+        os.system('grep -i signature %(pkg)s.upload.html' % dict)
+    else:
+        os.system('curl \
+            		-F feedname=%(feed)s \
+			-F filename=@%(pkg)s \
+			-F signaturefilename=@%(pkg)s.asc \
+		        -F sourcefilename="" \
+			%(url)s 2>&1 | tee %(pkg)s.upload.html | egrep "(Error|Warning):" | sed "s:</*p>::g;s:</*b>::g"'
+                  % dict)
+        os.system('grep -i signature %(pkg)s.upload.html' % dict)
+    print ("Done. See complete results in %(pkg)s.upload.html" % dict)
+
+
Index: /ipk/ipkg-utils-050831/ipkg.py
===================================================================
--- /ipk/ipkg-utils-050831/ipkg.py	(revision 4860)
+++ /ipk/ipkg-utils-050831/ipkg.py	(revision 4860)
@@ -0,0 +1,462 @@
+#!/usr/bin/env python
+#   Copyright (C) 2001 Alexander S. Guy <a7r@andern.org>
+#                      Andern Research Labs
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2, or (at your option)
+#   any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 59 Temple Place - Suite 330,
+#   Boston, MA 02111-1307, USA.  */
+#
+#   Copyright 2001, Russell Nelson <ipkg.py@russnelson.com>
+#   Added reading in of packages.
+#   Added missing package information fields.
+#   Changed render_control() to __repr__().
+#
+# Current Issues:
+#    The API doesn't validate package information fields.  It should be
+#        throwing exceptions in the right places.
+#    Executions of tar could silently fail.
+#    Executions of tar *do* fail, and loudly, because you have to specify a full filename,
+#        and tar complains if any files are missing, and the ipkg spec doesn't require
+#        people to say "./control.tar.gz" or "./control" when they package files.
+#        It would be much better to require ./control or disallow ./control (either)
+#        rather than letting people pick.  Some freedoms aren't worth their cost.
+
+import tempfile
+import os
+import sys
+import glob
+import md5
+import re
+import string
+import commands
+from stat import ST_SIZE
+
+class Version:
+    """A class for holding parsed package version information."""
+    def __init__(self, epoch, version):
+        self.epoch = epoch
+        self.version = version
+
+    def _versioncompare(self, ref):
+        selfversion = self.version
+        refversion = ref.version
+        while 1:
+            ## first look for non-numeric version component
+            selfm = re.match('([^0-9]*)(.*)', selfversion)
+            #print 'selfm', selfm.groups()
+            (selfalpha, selfversion) = selfm.groups()
+            refm = re.match('([^0-9]*)(.*)', refversion)
+            #print 'refm', refm.groups()
+            (refalpha, refversion) = refm.groups()
+            if (selfalpha > refalpha):
+                return 1
+            elif (selfalpha < refalpha):
+                return -1
+            ## now look for numeric version component
+            (selfnum, selfversion) = re.match('([0-9]*)(.*)', selfversion).groups()
+            (refnum, refversion) = re.match('([0-9]*)(.*)', refversion).groups()
+            #print 'selfnum', selfnum, selfversion
+            #print 'refnum', refnum, refversion
+            if (selfnum != ''):
+                selfnum = int(selfnum)
+            else:
+                selfnum = -1
+            if (refnum != ''):
+                refnum = int(refnum)
+            else:
+                refnum = -1
+            if (selfnum > refnum):
+                return 1
+            elif (selfnum < refnum):
+                return -1
+            if selfversion == '' and refversion == '':
+                return 0
+
+    def compare(self, ref):
+        if (self.epoch > ref.epoch):
+            return 1
+        elif (self.epoch < ref.epoch):
+            return -1
+        else:
+            return self._versioncompare(ref)
+
+def parse_version(versionstr):
+    epoch = 0
+    # check for epoch
+    m = re.match('([0-9]*):(.*)', versionstr)
+    if m:
+        (epochstr, versionstr) = m.groups()
+        epoch = int(epochstr)
+    return Version(epoch, versionstr)
+
+class Package:
+    """A class for creating objects to manipulate (e.g. create) ipkg
+       packages."""
+    def __init__(self, fn=None):
+	self.package = None
+	self.version = 'none'
+	self.parsed_version = None
+	self.architecture = None
+	self.maintainer = None
+	self.source = None
+	self.description = None
+	self.depends = None
+	self.provides = None
+	self.replaces = None
+	self.conflicts = None
+        self.recommends = None
+	self.suggests = None
+	self.section = None
+        self.filename_header = None
+	self.file_list = []
+        self.md5 = None
+        self.size = None
+        self.installed_size = None
+        self.filename = None
+        self.isdeb = 0
+
+	if fn:
+            # see if it is deb format
+            f = open(fn, "r")
+            magic = f.read(4)
+            f.close()
+            if (magic == "!<ar"):
+                self.isdeb = 1
+
+            # compute the MD5.
+            f = open(fn, "r")
+            sum = md5.new()
+            while 1:
+                data = f.read(1024)
+                if not data: break
+                sum.update(data)
+            f.close()
+            if sys.version[:1] > '2':
+                # when using Python 2.0 or newer
+                self.md5 = sum.hexdigest() 
+            else:
+                self.md5 = string.join(map((lambda x:"%02x" % ord(x)),sum.digest()),'')
+            stat = os.stat(fn)
+            self.size = stat[ST_SIZE]
+            self.filename = os.path.basename(fn)
+	    ## sys.stderr.write("  extracting control.tar.gz from %s\n"% (fn,)) 
+            if self.isdeb:
+                control = os.popen("ar p "+fn+" control.tar.gz | tar xfzO - './control'","r")
+            else:
+                control = os.popen("tar xfzO "+fn+" '*control.tar.gz' | tar xfzO - './control'","r")
+            line = control.readline()
+            while 1:
+                if not line: break
+                line = string.rstrip(line)
+                lineparts = re.match(r'([\w-]*?):\s*(.*)', line)
+		if lineparts:
+                    name = string.lower(lineparts.group(1))
+		    value = lineparts.group(2)
+		    while 1:
+			line = control.readline()
+			if not line: break
+			if line[0] != ' ': break
+                        line = string.rstrip(line)
+			value = value + '\n' + line
+                    # don't allow package to override its own filename
+                    if name == "filename":
+                        self.filename_header = value
+                    else:
+                        if self.__dict__.has_key(name):
+                            self.__dict__[name] = value
+                else:
+                    line = control.readline()
+            control.close()
+            if self.isdeb:
+                data = os.popen("ar p "+fn+" data.tar.gz | tar tfz -","r")
+            else:
+                data = os.popen("tar xfzO "+fn+" '*data.tar.gz' | tar tfz -","r")
+            while 1:
+                line = data.readline()
+                if not line: break
+                self.file_list.append(string.rstrip(line))
+            data.close()
+
+	self.scratch_dir = None
+	self.file_dir = None
+	self.meta_dir = None
+
+    def read_control(self, control):
+        import os
+
+        line = control.readline()
+        while 1:
+            if not line: break
+            line = string.rstrip(line)
+            lineparts = re.match(r'([\w-]*?):\s*(.*)', line)
+            if lineparts:
+                name = string.lower(lineparts.group(1))
+                value = lineparts.group(2)
+                while 1:
+                    line = control.readline()
+                    if not line: break
+                    if line[0] != ' ': break
+                    value = value + '\n' + line
+                if name == 'size':
+                    self.size = int(value)
+                elif self.__dict__.has_key(name):
+                    self.__dict__[name] = value
+                if line[0] == '\n':
+                    return # consumes one blank line at end of package descriptoin
+            else:
+                line = control.readline()
+                pass
+        return    
+
+    def _setup_scratch_area(self):
+	self.scratch_dir = "%s/%sipkg" % (tempfile.gettempdir(),
+					   tempfile.gettempprefix())
+	self.file_dir = "%s/files" % (self.scratch_dir)
+	self.meta_dir = "%s/meta" % (self.scratch_dir)
+
+	os.mkdir(self.scratch_dir)
+	os.mkdir(self.file_dir)
+	os.mkdir(self.meta_dir)
+
+    def set_package(self, package):
+	self.package = package
+
+    def get_package(self):
+	return self.package
+		
+    def set_version(self, version):
+	self.version = version
+        self.parsed_version = parse_version(version)
+
+    def get_version(self):
+	return self.version
+
+    def set_architecture(self, architecture):
+	self.architecture = architecture
+
+    def get_architecture(self):
+	return self.architecture
+
+    def set_maintainer(self, maintainer):
+	self.maintainer = maintainer
+
+    def get_maintainer(self):
+	return self.maintainer
+
+    def set_source(self, source):
+	self.source = source
+
+    def get_source(self):
+	return self.source
+
+    def set_description(self, description):
+	self.description = description
+
+    def get_description(self):
+	return self.description
+
+    def set_depends(self, depends):
+	self.depends = depends
+
+    def get_depends(self, depends):
+	return self.depends
+
+    def set_provides(self, provides):
+	self.provides = provides
+
+    def get_provides(self, provides):
+	return self.provides
+
+    def set_replaces(self, replaces):
+	self.replaces = replaces
+
+    def get_replaces(self, replaces):
+	return self.replaces
+
+    def set_conflicts(self, conflicts):
+	self.conflicts = conflicts
+
+    def get_conflicts(self, conflicts):
+	return self.conflicts
+
+    def set_suggests(self, suggests):
+	self.suggests = suggests
+
+    def get_suggests(self, suggests):
+	return self.suggests
+
+    def set_section(self, section):
+	self.section = section
+
+    def get_section(self, section):
+	return self.section
+
+    def get_file_list(self):
+	return self.file_list
+
+    def write_package(self, dirname):
+        buf = self.render_control()
+	file = open("%s/control" % self.meta_dir, 'w')
+	file.write(buf)
+
+	self._setup_scratch_area()
+	cmd = "cd %s ; tar cvfz %s/control.tar.gz control" % (self.meta_dir,
+							      self.scratch_dir)
+
+	cmd_out, cmd_in, cmd_err = os.popen3(cmd)
+	
+	while cmd_err.readline() != "":
+	    pass
+
+	cmd_out.close()
+	cmd_in.close()
+	cmd_err.close()
+
+	bits = "control.tar.gz"
+
+	if self.file_list:
+		cmd = "cd %s ; tar cvfz %s/data.tar.gz" % (self.file_dir,
+					   		   self.scratch_dir)
+
+		cmd_out, cmd_in, cmd_err = os.popen3(cmd)
+
+		while cmd_err.readline() != "":
+		    pass
+
+		cmd_out.close()
+		cmd_in.close()
+		cmd_err.close()
+
+		bits = bits + " data.tar.gz"
+
+	file = "%s_%s_%s.ipk" % (self.package, self.version, self.architecture)
+	cmd = "cd %s ; tar cvfz %s/%s %s" % (self.scratch_dir,
+					     dirname,
+					     file,
+					     bits)
+
+	cmd_out, cmd_in, cmd_err = os.popen3(cmd)
+
+	while cmd_err.readline() != "":
+	    pass
+
+	cmd_out.close()
+	cmd_in.close()
+	cmd_err.close()
+
+    def compare_version(self, ref):
+        """Compare package versions of self and ref"""
+        if not self.version:
+            print 'No version for package %s' % self.package
+        if not ref.version:
+            print 'No version for package %s' % ref.package
+        if not self.parsed_version:
+            self.parsed_version = parse_version(self.version)
+        if not ref.parsed_version:
+            ref.parsed_version = parse_version(ref.version)
+        return self.parsed_version.compare(ref.parsed_version)
+
+    def __repr__(self):
+	out = ""
+
+	# XXX - Some checks need to be made, and some exceptions
+	#       need to be thrown. -- a7r
+
+        if self.package: out = out + "Package: %s\n" % (self.package)
+        if self.version: out = out + "Version: %s\n" % (self.version)
+        if self.depends: out = out + "Depends: %s\n" % (self.depends)
+        if self.provides: out = out + "Provides: %s\n" % (self.provides)
+        if self.replaces: out = out + "Replaces: %s\n" % (self.replaces)
+        if self.conflicts: out = out + "Conflicts: %s\n" % (self.conflicts)
+        if self.suggests: out = out + "Suggests: %s\n" % (self.suggests)
+        if self.recommends: out = out + "Recommends: %s\n" % (self.recommends)
+        if self.section: out = out + "Section: %s\n" % (self.section)
+        if self.architecture: out = out + "Architecture: %s\n" % (self.architecture)
+        if self.maintainer: out = out + "Maintainer: %s\n" % (self.maintainer)
+        if self.md5: out = out + "MD5Sum: %s\n" % (self.md5)
+        if self.size: out = out + "Size: %d\n" % int(self.size)
+        if self.installed_size: out = out + "InstalledSize: %d\n" % int(self.installed_size)
+        if self.filename: out = out + "Filename: %s\n" % (self.filename)
+        if self.source: out = out + "Source: %s\n" % (self.source)
+        if self.description: out = out + "Description: %s\n" % (self.description)
+	out = out + "\n"
+
+	return out
+
+    def __del__(self):
+	# XXX - Why is the `os' module being yanked out before Package objects
+	#       are being destroyed?  -- a7r
+        pass
+
+class Packages:
+    """A currently unimplemented wrapper around the ipkg utility."""
+    def __init__(self):
+        self.packages = {}
+        return
+
+    def add_package(self, pkg):
+        package = pkg.package
+        arch = pkg.architecture
+        name = ("%s:%s" % (package, arch))
+        if (not self.packages.has_key(name)):
+            self.packages[name] = pkg
+        
+        if pkg.compare_version(self.packages[name]) >= 0:
+            self.packages[name] = pkg
+            return 0
+        else:
+            return 1
+
+    def read_packages_file(self, fn):
+        f = open(fn, "r")
+        while 1:
+            pkg = Package()
+            pkg.read_control(f)
+            if pkg.get_package():
+                self.add_package(pkg)
+            else:
+                break
+        f.close()    
+        return
+
+    def write_packages_file(self, fn):
+        f = open(fn, "w")
+        names = self.packages.keys()
+        names.sort()
+        for name in names:
+            f.write(self.packages[name].__repr__())
+        return    
+
+    def keys(self):
+        return self.packages.keys()
+
+    def __getitem__(self, key):
+        return self.packages[key]
+
+if __name__ == "__main__":
+    package = Package()
+
+    package.set_package("FooBar")
+    package.set_version("0.1-fam1")
+    package.set_architecture("arm")
+    package.set_maintainer("Testing <testing@testing.testing>")
+    package.set_depends("libc")
+    package.set_description("A test of the APIs.")
+
+    print "<"
+    sys.stdout.write(package)
+    print ">"
+
+    package.write_package("/tmp")
+
Index: /ipk/ipkg-utils-050831/makePackage
===================================================================
--- /ipk/ipkg-utils-050831/makePackage	(revision 4860)
+++ /ipk/ipkg-utils-050831/makePackage	(revision 4860)
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+
+# The general algorithm this program follows goes like this:
+#   Run tar to extract control from control.tar.gz from the package.
+#   Insert the filename, size, and md5 lines before the description.
+# Call it like this:
+#  find . -name \*.ipk | xargs -n 1 makePackage > Packages
+
+import sys
+import ipkg
+
+fn = sys.argv[1]
+pkg = ipkg.Package(fn)
+print pkg
Index: /ipk/ipkg-utils-050831/setup.py
===================================================================
--- /ipk/ipkg-utils-050831/setup.py	(revision 4860)
+++ /ipk/ipkg-utils-050831/setup.py	(revision 4860)
@@ -0,0 +1,21 @@
+import distutils.core
+
+long_description = """
+iPKG utilities implemented in Python
+
+ipkg.py              implements Package class
+"""
+
+distutils.core.setup( name = 'ipkg-utils',
+                      version = '1.7.3',
+                      description = 'ipkg utilities implemented in python',
+		      long_description = long_description,
+                      author = 'Jamey Hicks',
+                      author_email = 'jamey@handhelds.org',
+		      license = 'GPL',
+		      platforms = 'POSIX',
+		      keywords = 'ipkg familiar',
+                      url = 'http://www.handhelds.org/sources.html/',
+                      py_modules = [ 'ipkg' ],
+		      scripts = ['ipkg-compare-indexes', 'ipkg-make-index', 'ipkg-update-index', 'ipkg-build', 'ipkg-unbuild', 'ipkg-upload']
+                      )
Index: /ipk/ipkg-utils-050831/upload-package.cgi
===================================================================
--- /ipk/ipkg-utils-050831/upload-package.cgi	(revision 4860)
+++ /ipk/ipkg-utils-050831/upload-package.cgi	(revision 4860)
@@ -0,0 +1,511 @@
+#!/usr/bin/python
+
+import sys, os, cgi, commands, time
+import re
+import posixfile
+import ConfigParser
+import ipkg
+import smtplib
+import libxml2
+import newtempfile
+import string
+
+config = '/etc/packman.conf'
+
+
+feeds_base = '/home/jamey/feeds'
+feeds_base = '/home/ftp/feeds'
+cgi.logfile = '/tmp/upload'
+tmp_dir = '/tmp'
+ipkgfind_url = 'http://ipkgfind.handhelds.org'
+
+update_package_list = 0
+cp = ConfigParser.ConfigParser()
+cp.read(config)
+try:
+    if cp.has_option('config', 'feeds_base'):
+        feeds_base = cp.get('config', 'feeds_base')
+    if cp.has_option('config', 'logfile'):
+        cgi.logfile = cp.get('config', 'logfile')
+    if cp.has_option('config', 'tmp_dir'):
+        tmp_dir = cp.get('config', 'tmp_dir')
+    if cp.has_option('config', 'update_index'):
+        update_package_list = cp.get('config', 'update_index')
+except:
+    pass
+cp = None
+
+logprefix = time.strftime('%c') + ' -- '
+try:
+     for k in ['REMOTE_ADDR']:
+          if (os.environ.has_key(k)):
+               logprefix = logprefix + ('%s' % (os.environ[k],))
+except:
+     pass
+
+def log(string):
+     cgi.log(logprefix + ': ' + string)
+
+def filename_is_valid(filename):
+     if re.match(r'^[+-._A-Za-z0-9]+$', filename): return 1
+     return 0
+
+def copy(srcfilename, dstfilename):
+    srcfile = open(srcfilename, 'r')
+    dstfile = open(dstfilename, 'w')
+    if not srcfile:
+	return 1	
+    if not dstfile:
+	return 1	
+    while (1):
+        str = srcfile.read(512)
+        if (str):
+            nbytes = dstfile.write(str)
+        else:
+            break
+    dstfile.close()
+    srcfile.close()
+    return 0	
+
+def make_index(feed_dir):
+    os.chdir(feed_dir)
+    f = posixfile.open(tmp_dir + "/Packages.lck", 'w')
+    f.lock('w|')
+    (rc, outtext) = commands.getstatusoutput('/usr/local/bin/ipkg-make-index . > /tmp/Packages')
+    if (rc != 0):
+        print ('<b>Failed to create Packages file with error=%s and output=%s</b>' % (rc,outtext)) 
+    else:
+        commands.getstatusoutput('mv /tmp/Packages Packages')
+    f.lock('u')
+    f.close()
+    print '<b>Updated Packages</b>'	
+    return
+
+def update_index(feed_dir, pkgfilename):
+    f = posixfile.open(tmp_dir + "/Packages.lck", 'w')
+    f.lock('w|')
+    (rc, outtext) = commands.getstatusoutput('ipkg-update-index %s %s' % (feed_dir, pkgfilename) )
+    if (rc != 0):
+        print ('<b>Failed to update Packages file with error=%s and output=%s</b>' % (rc,outtext)) 
+    f.lock('u')
+    f.close()
+    print ('<b>added %s to Packages</b>' % (pkgfilename,))
+    return
+
+def announce_to_cia(uploader, feedname, filename, changenotice=None):
+    msg = "From: commits@handhelds.org\r\nTo: commits@picogui.org\r\nContent-Type: text/plain;\r\nSubject: SendToChannels handhelds.org\r\n\r\n{light blue}" + filename +"{normal} uploaded to {light green}" + feedname + "{normal} by {orange}" + uploader + "{normal}\r\n"
+    mailmsg = "From: " + uploader + "\r\nTo: familiar-updates@handhelds.org\r\nContent-Type: text/plain;\r\nSubject: " + filename + " uploaded to " + feedname + "\r\n\r\n\r\n"
+    if changenotice:
+       mailmsg = mailmsg + changenotice + "\r\n"
+    server = smtplib.SMTP('localhost')
+    server.sendmail('commits@handhelds.org', 'commits@picogui.org', msg)
+    server.sendmail(uploader, 'familiar-updates@handhelds.org', mailmsg)
+    server.quit()
+
+def fixup_filename(filename):
+    if filename and filename[:8] == "C:\\Temp\\":
+	filename = filename[8:] 	
+    return filename
+
+def update_feed_rss(uploader, feedname, filename, upload_time):
+    rss_filename = feeds_base + '/' + feedname + '/upload.rss'
+    m = re.match(r'([^_]+)_([^_]+)_([^_]+).ipk', filename)
+    if not m:
+        return
+    (pkg_name, pkg_version, pkg_arch) = m.groups()
+    doc = libxml2.parseFile(rss_filename)
+    items = []
+    c = doc.children.children
+    while c:
+        if c.name == 'item':
+	    items.append(c)
+        c = c.next
+    oldest = items[len(items)-1]
+    items_parent = items[0].parent
+    c = oldest.children
+    while c:
+        if c.name == 'title':
+            c.children.setContent('%s (version %s arch %s by %s on %s)' % (pkg_name, pkg_version, pkg_arch, uploader, upload_time))
+        elif c.name == 'link':
+            c.children.setContent(ipkgfind_url + '/details.phtml?package=' + pkg_name)
+        else:
+            pass
+        c = c.next
+    # now move c from end of list to head of list
+    oldest.unlinkNode()
+    items_parent.children.addPrevSibling(oldest)
+    f = open(rss_filename, 'w')
+    doc.dump(f)
+
+def handle_batch_upload(feeditem, batchitem, tarfileitem, sigfileitem, changenotice=None):
+     global logprefix
+     global update_package_list	
+     
+     feedname    = feeditem.value
+     sigfilename = sigfileitem.filename
+     batchfilename = batchitem.filename
+     sigfilename = fixup_filename(sigfilename)
+     batchfilename = fixup_filename(batchfilename)
+
+     if not filename_is_valid(feedname):
+          print ('<b>%s</b> is an invalid filename\n' % (feedname,))
+          log('invalid feedname %s' % (feedname,))
+          return 0
+
+     feed_dir = feeds_base + '/' + feedname + '/'
+
+     if not filename_is_valid(batchfilename):
+          print ('<b>%s</b> is an invalid filename\n' % (batchfilename,))
+          log('invalid filename %s' % (batchfilename,))
+          return 0
+     if not filename_is_valid(sigfilename):
+          print ('<b>%s</b> is an invalid filename\n' % (sigfilename,))
+          log('invalid sigfilename %s' % (sigfilename,))
+          return 0
+     if (batchfilename == 'keyring.gpg' or sigfilename == 'keyring.gpg'):
+         print '<b>not allowed to overwrite keyring</b>'
+         return 0
+     if (os.path.exists(feed_dir + '/' + batchfilename)):
+          print ('<b>%s</b> already exists in feed directory' % (batchfilename,))
+          return 0
+     if (os.path.exists(feed_dir + '/' + sigfilename)):
+          print ('<b>%s</b> already exists in feed directory' % (sigfilename,))
+          return 0
+
+     files = []
+     
+     for line in string.split(batchitem.value, "\n"):
+     	 fields = string.split(line)
+         if not fields:
+              continue
+         md5sum = fields[0]
+         filename = fields[1]
+         if not filename_is_valid(filename):
+              print ('<b>%s</b> is an invalid filename' % (filename,))
+              return 0
+         if (filename == 'keyring.gpg' or sigfilename == 'keyring.gpg'):
+              print '<b>not allowed to overwrite keyring</b>'
+              return 0
+         if (os.path.exists(feed_dir + '/' + filename)):
+              print ('<b>%s</b> already exists in feed directory' % (filename,))
+              return 0
+         files.append(filename)
+
+     tmpdir = newtempfile.mkdtemp();
+
+     try:
+          batchfile = open(tmpdir + "/" + batchfilename, 'w')
+          batchfile.write(batchitem.value)
+          batchfile.close()
+
+          sigfile = open(tmpdir + "/" + sigfilename, 'w')
+          sigfile.write(sigfileitem.value)
+          sigfile.close()
+
+          keyringfile = feed_dir + 'keyring.gpg'
+          try:
+               (exitstatus, outtext) = commands.getstatusoutput("/usr/bin/gpgv --keyring %s %s" % (keyringfile, tmpdir + '/' + sigfilename))
+          except:
+               cgi.log('caught an exception in gpg')
+               raise
+          print '<pre>' + outtext + '</pre>'
+          if (exitstatus != 0):
+               log('/usr/bin/gpgv %s %s exitstatus=%d' % (filename, sigfilename, exitstatus,)) 
+               log('  ' + outtext)
+               rc = exitstatus
+               raise "failed"
+
+          match = re.search("Good signature from.*\<(.+)\>", outtext)
+          if (match):
+               uploader = match.group(1)
+          else:
+               log('Could not extract uploader name from gpg output:')
+               log('  ' + outtext)
+               print "Something went wrong parsing output from gpg!"
+               raise "failed"
+
+          tarcmd = "tar --directory=%s -f - -x %s" % (tmpdir, string.join(files, " "))
+
+          tarpipe, tarout, tarerr = os.popen3(tarcmd)
+          tarpipe.write(tarfileitem.value)
+          tarpipe.close()
+               
+          while tarerr.readline() != "":
+               pass
+               
+          tarout.close()
+          tarerr.close()
+     
+          os.chdir(tmpdir)
+          md5sumcmd = "md5sum -c %s" % (batchfilename,)
+
+          try:
+               (exitstatus, outtext) = commands.getstatusoutput(md5sumcmd)
+          except:
+               print "md5sum threw an exception"
+               cgi.log('caught an exception in md5sum')
+               raise
+          
+          if (exitstatus != 0):
+              print "<b>md5sum check failed</b>"
+              print outtext
+              raise "failed"
+
+          os.chdir("/")
+
+          for filename in files:
+               if (re.search(".*\.ipk$", filename)):
+                    ipk = ipkg.Package(tmpdir + "/" + filename)
+                    if not ipk:
+                         print '<p>Unable to parse ' + filename + '</p>'
+                         raise "failed"
+                    if not ipk.source:
+                         print '<p><b>Error:</b> ' + filename + ' lacks a Source field in its control file.</p>'
+                         raise "failed"
+                    if not ipk.isdeb:
+                         print '<p><b>Error:</b> ' + filename + ' is an old-format archive.  Please upgrade ipkg-build.</p>'
+                         raise "failed"
+                    if ipk.filename_header:
+                         print '<p><b>Error:</b> ' + filename + ' has a Filename header in its control file.</p>'
+                         raise "failed"
+
+          for filename in files:
+               rc = copy(tmpdir + "/" + filename, feed_dir + "/" + filename)
+               if (rc != 0):
+                    print ('<p>error %s copying %s to %s' % (rc, tmpdir + "/" + filename, feed_dir + "/" + filename))
+               os.unlink(tmpdir + "/" + filename)
+
+               log('Uploaded %s to %s' % (filename, feed_dir))
+
+               if (re.search(".*\.ipk$", filename)):
+                    announce_to_cia(uploader, feedname, filename)
+                    update_feed_rss(uploader, feedname, filename, time.strftime('%c'))
+               
+          copy(tmpdir + "/" + sigfilename, feed_dir + "/" + sigfilename)
+          copy(tmpdir + "/" + batchfilename, feed_dir + "/" + batchfilename)
+                    
+     except:
+          print "Caught an exception"
+          os.chdir("/")
+          os.system("rm -r " + tmpdir)
+          raise
+
+     os.system("rm -r " + tmpdir)
+
+     print "<p>Packages file now updated every 10 minutes by cron job</p>\n"
+
+     return 1
+
+def handle_upload(feeditem, fileitem, sigfileitem, srcfileitem, changenotice=None):
+     global logprefix
+     global update_package_list	
+     
+     feedname    = feeditem.value
+     filename    = fileitem.filename
+     sigfilename = sigfileitem.filename
+     srcfilename = srcfileitem.filename
+     filename = fixup_filename(filename)
+     sigfilename = fixup_filename(sigfilename)
+     srcfilename = fixup_filename(srcfilename)
+     # print "filename=%s\n" % (filename,)
+     # print "sigfilename=%s\n" % (sigfilename,)
+     # print "srcfilename=%s\n" % (srcfilename,)
+
+     if not filename_is_valid(feedname):
+          print ('<b>%s</b> is an invalid filename\n' % (feedname,))
+          log('invalid feedname %s' % (feedname,))
+          return 0
+     if not filename_is_valid(filename):
+          print ('<b>%s</b> is an invalid filename\n' % (filename,))
+          log('invalid filename %s' % (filename,))
+          return 0
+     if not filename_is_valid(sigfilename):
+          print ('<b>%s</b> is an invalid filename\n' % (sigfilename,))
+          log('invalid sigfilename %s' % (sigfilename,))
+          return 0
+     if srcfilename and not filename_is_valid(srcfilename):
+          print ('<b>%s</b> is an invalid filename\n' % (srcfilename,))
+	  log('invalid srcfilename %s' % (srcfilename,))
+	  return 0
+     if (filename == 'keyring.gpg' or sigfilename == 'keyring.gpg'):
+         print '<b>not allowed to overwrite keyring</b>'
+         return 0
+
+     feed_dir = feeds_base + '/' + feedname + '/'
+     tmp_dir = "/tmp/"
+     file = open(tmp_dir + filename, 'w')
+     file.write(fileitem.value)
+     file.close()
+     sigfile = open(tmp_dir + sigfilename, 'w')
+     sigfile.write(sigfileitem.value)
+     sigfile.close()
+     
+     ipk = ipkg.Package(tmp_dir + filename)
+     if not ipk:
+          print '<p>Unable to parse ' + filename + '</p>'
+          return 0
+     if not srcfilename and not ipk.source:
+          print '<p><b>Error:</b> ' + filename + ' lacks a Source field in its control file.</p>'
+          return 0
+     if not ipk.isdeb:
+	  print '<p><b>Error:</b> ' + filename + ' is an old-format archive.  Please upgrade ipkg-build.</p>'
+          return 0
+     if ipk.filename_header:
+          print '<p><b>Error:</b> ' + filename + ' has a Filename header in its control file.</p>'
+          return 0
+
+     keyringfile = feed_dir + 'keyring.gpg'
+     try:
+          (exitstatus, outtext) = commands.getstatusoutput("/usr/bin/gpgv --keyring %s %s" % (keyringfile, tmp_dir + sigfilename))
+     except:
+          cgi.log('caught an exception')
+          return 0
+     print '<pre>' + outtext + '</pre>'
+     if (exitstatus != 0):
+          log('/usr/bin/gpgv %s %s exitstatus=%d' % (filename, sigfilename, exitstatus,)) 
+          log('  ' + outtext)
+     rc = exitstatus
+     if (rc != 0):
+         return 0
+     
+     match = re.search("Good signature from.*\<(.+)\>", outtext)
+     if (match):
+         uploader = match.group(1)
+         announce_to_cia(uploader, feedname, filename)
+         update_feed_rss(uploader, feedname, filename, time.strftime('%c'))
+
+     rc = copy(tmp_dir + filename, feed_dir + filename)
+     if (rc != 0):
+         print ('<p>error %s copying %s to %s' % (rc, tmp_dir + filename, feed_dir + filename))
+     os.unlink(tmp_dir + filename)
+         
+     rc = copy(tmp_dir + sigfilename, feed_dir + sigfilename)
+     if (rc != 0):
+         print ('<p>error %s copying %s to %s' % (rc, tmp_dir + sigfilename, feed_dir + sigfilename))
+     os.unlink(tmp_dir + sigfilename)
+     cgi.logfile = feed_dir + 'upload.log'	
+     log('uploaded %s the package %s %s' % (feedname, filename, sigfilename))
+     if changenotice:
+         cgi.log('\t' + changenotice)
+     if srcfilename:
+         log('srcfile=' + srcfilename)
+         overridefile = open(feed_dir + filename + ".override", 'w')
+         overridefile.write('Source: ' + srcfilename + '\n')
+         overridefile.close()
+         srcfile= open(tmp_dir + srcfilename, 'w')
+         srcfile.write(srcfileitem.value)
+         srcfile.close()
+         log('srcfile written to /tmp')
+
+         rc = copy(tmp_dir + srcfilename, feed_dir + srcfilename)
+         log('copied srcfile to feed, rc=%s' % (rc,))
+         if (rc != 0):
+             print ('<p>error %s copying %s to %s' % (rc, tmp_dir + sigfilename, feed_dir + sigfilename))
+         os.unlink(tmp_dir + srcfilename)
+         log('uploaded %s the source file %s' % (feedname, srcfilename))
+
+     print "<p>Packages file now updated every 10 minutes by cron job</p>\n"
+     # remove the tmp files
+     return 1
+
+def main():
+    global update_package_list
+    print "Content-type: text/html\n"
+    form = cgi.FieldStorage()
+    print '<html>'
+    print '<head><title>Handhelds.Org Package Manager -- upload</title></head>'
+    print '<body><h1>Handhelds.Org Package Manager -- upload</h1>'
+    if form and form.has_key("batchfilename") and form.has_key("signaturefilename") and form.has_key("datafilename"):
+	 print '<ul>'
+	 print '<li>'
+	 print form["feedname"].value
+	 print '<li>'
+	 print form["batchfilename"].filename
+	 print '<li>'
+         print form["signaturefilename"].filename
+         print '</ul>'
+         if form.has_key('update_index'):
+             update_package_list = form["update_index"]
+	 if form.has_key('changenotice'):
+	     changenotice= form['changenotice']
+	 else:
+	     changenotice=None
+         if handle_batch_upload(form["feedname"], form["batchfilename"], form["datafilename"], form["signaturefilename"], changenotice):
+              print '<p><b>Upload completed successfully</b>'
+              print ('<p><a href="/feeds/%s/Packages">Updated Packages File</a>' % (form["feedname"].value, ))
+         else:
+              print '<p><b>Upload failed</b>'
+    elif form and form.has_key("filename") and form.has_key("signaturefilename") and form.has_key("sourcefilename"):
+	 print '<ul>'
+	 print '<li>'
+	 print form["feedname"].value
+	 print '<li>'
+	 print form["filename"].filename
+	 print '<li>'
+         print form["signaturefilename"].filename
+	 print '<li>'
+         print form["sourcefilename"].filename
+         print '</ul>'
+         if form.has_key('update_index'):
+             update_package_list = form["update_index"]
+	 if form.has_key('changenotice'):
+	     changenotice= form['changenotice']
+	 else:
+	     changenotice=None
+         if handle_upload(form["feedname"], form["filename"], form["signaturefilename"],form["sourcefilename"], changenotice):
+              print '<p><b>Upload completed successfully</b>'
+              print ('<p><a href="/feeds/%s/Packages">Updated Packages File</a>' % (form["feedname"].value, ))
+         else:
+              print '<p><b>Upload failed</b>'
+    elif form and form.has_key("feedname") and form.has_key("update_index"):
+       # feed_dir = feeds_base + '/' + form["feedname"].value + '/'
+       # make_index(feed_dir)
+       print "Packages file now updated hourly by cron job at 11 after the hour\n"
+    else:
+       print """
+       <h1>Signing Packages</h1>
+       The following command will generate the file foo.ipk.asc, containing
+       an ASCII signature of the package foo.ipk:
+       <pre>
+           gpg -sb --armor foo.ipk
+       </pre>
+       <p>
+
+       See <a
+       href="/pipermail/familiar/2001-December/003955.html">Jamey's
+       announcement of this package upload utility</a> for some more
+       details.
+
+       <h1>Package to Upload</h1>
+       <form action="/cgi-bin/upload-package.cgi" method="POST" enctype="multipart/form-data">
+       <table>
+       <tr><td>Feed Name <td><select name="feedname">
+          <option selected>unstable</option>
+          <option>devel</option>
+       </select></tr>
+       <tr><td>Filename <td><input type="file" name="filename"></tr>
+       <tr><td>OpenPGP Signature Filename <td> <input type="file" name="signaturefilename"></tr>
+       <tr><td>Sources Filename - Optional <td> <input type="file" name="sourcefilename"></tr>
+       <tr><td>Change Notice - Optional <td> <input type="file" name="changenotice"></tr>
+       </table>
+       <p>Please make sure that your package's
+       control file has a Source field.
+       <p>The Source field is intended to allow automated retrieval of the source
+       package from which your package was built.  If you are uploading a source
+       package along with your binary package, the Source field should contain
+       the name of the source package.  Otherwise, it should contain one of the
+       following:
+       <ul>
+       <li>a single URL pointing to a source tarball
+       <li>multiple URLs pointing to the multiple files (.dsc, .orig.tar.gz, .diff.gz)
+       comprising a Debian source package
+       </ul>
+       <input type="submit">
+       </form>
+"""
+    print '</body>'
+    print '</html>'
+
+main()
+
+
Index: /ipk/make-ipk
===================================================================
--- /ipk/make-ipk	(revision 4859)
+++ /ipk/make-ipk	(revision 4860)
@@ -12,23 +12,9 @@
 
 if [ `which ipkg-build | wc -l` -eq 0 ]; then
-	echo "[make-ipk] install ipkg-build source"
-	echo "[make-ipk] cd $HOME"
-	echo "[make-ipk] mkdir src"
-	echo "[make-ipk] cd src"
-	echo "[make-ipk] wget http://www.pengutronix.de/software/ptxdist/temporary-src/ipkg-utils-050831.tar.gz"
-	echo "[make-ipk] tar -zxvf ipkg-utils-050831.tar.gz"
-	echo "[make-ipk] sudo ln -s $HOME/src/ipkg-utils-050831/ipkg-build /sbin"
-	echo "[make-ipk] sudo ln -s $HOME/src/ipkg-utils-050831/ipkg-make-index /sbin"
-	exit
+	ln -s $HOMEDIR/ipkg-utils-050831/ipkg-build /sbin
+	ln -s $HOMEDIR/ipkg-utils-050831/ipkg-build /bin
 elif [ `which ipkg-make-index | wc -l` -eq 0 ]; then
-	echo "[make-ipk] install ipkg-build source"
-	echo "[make-ipk] cd $HOME"
-	echo "[make-ipk] mkdir src"
-	echo "[make-ipk] cd src"
-	echo "[make-ipk] wget http://www.pengutronix.de/software/ptxdist/temporary-src/ipkg-utils-050831.tar.gz"
-	echo "[make-ipk] tar -zxvf ipkg-utils-050831.tar.gz"
-	echo "[make-ipk] sudo ln -s $HOME/src/ipkg-utils-050831/ipkg-build /sbin"
-	echo "[make-ipk] sudo ln -s $HOME/src/ipkg-utils-050831/ipkg-make-index /sbin"
-	exit
+	ln -s $HOMEDIR/ipkg-utils-050831/ipkg-make-index /sbin
+	ln -s $HOMEDIR/ipkg-utils-050831/ipkg-make-index /bin
 elif [ `which gzip | wc -l` -eq 0 ]; then
 	echo "[make-ipk] install gzip"
@@ -43,7 +29,4 @@
 	exit
 fi
-
-echo "fix IPKG.py TAR BUG"
-cp -a "$HOME"/patch/src/ipkg-utils-050831/* "$HOMEDIR"/src/ipkg-utils-050831
 
 if [ "$MAKETYPE" = "online" ];then
