r4534 - trunk/src/host/opkg-utils
zecke at docs.openmoko.org
zecke at docs.openmoko.org
Fri Jul 18 13:29:53 CEST 2008
Author: zecke
Date: 2008-07-18 13:29:53 +0200 (Fri, 18 Jul 2008)
New Revision: 4534
Added:
trunk/src/host/opkg-utils/COPYING
trunk/src/host/opkg-utils/Makefile
trunk/src/host/opkg-utils/arfile.py
trunk/src/host/opkg-utils/makePackage
trunk/src/host/opkg-utils/opkg-build
trunk/src/host/opkg-utils/opkg-buildpackage
trunk/src/host/opkg-utils/opkg-compare-indexes
trunk/src/host/opkg-utils/opkg-compare-versions.c
trunk/src/host/opkg-utils/opkg-compare-versions.sh
trunk/src/host/opkg-utils/opkg-diff
trunk/src/host/opkg-utils/opkg-extract-file
trunk/src/host/opkg-utils/opkg-list-fields
trunk/src/host/opkg-utils/opkg-make-index
trunk/src/host/opkg-utils/opkg-show-deps
trunk/src/host/opkg-utils/opkg-unbuild
trunk/src/host/opkg-utils/opkg-update-index
trunk/src/host/opkg-utils/opkg.py
Log:
[opkg-utils] Add opkg-utils to the repository courtsey Richard Purdie of o-hand.com
I've attached a first attempt at this, its basically a small set of
helper scripts which OE/Poky use when working with ipks. I've applied
the various OE improvements and tweaks and removed a ton of cruft we
don't need.
Added: trunk/src/host/opkg-utils/COPYING
===================================================================
--- trunk/src/host/opkg-utils/COPYING (rev 0)
+++ trunk/src/host/opkg-utils/COPYING 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <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.
Added: trunk/src/host/opkg-utils/Makefile
===================================================================
--- trunk/src/host/opkg-utils/Makefile (rev 0)
+++ trunk/src/host/opkg-utils/Makefile 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,19 @@
+UTILS = opkg-build opkg-unbuild opkg-compare-versions opkg-make-index opkg.py \
+ opkg-list-fields arfile.py opkg-buildpackage opkg-diff opkg-extract-file opkg-show-deps \
+ opkg-compare-indexes opkg-compare-versions.sh
+
+DESTDIR=
+PREFIX=/usr/local
+bindir=${prefix}/bin
+
+all: opkg-compare-versions
+
+opkg-compare-versions: opkg-compare-versions.c
+ $(CC) $(CFLAGS) -o opkg-compare-versions opkg-compare-versions.c
+
+install: opkg-compare-versions
+ install -d $(DESTDIR)$(bindir)
+ install -m 744 $(UTILS) $(DESTDIR)$(bindir)
+
+clean:
+ rm -rf opkg-compare-versions
Added: trunk/src/host/opkg-utils/arfile.py
===================================================================
--- trunk/src/host/opkg-utils/arfile.py (rev 0)
+++ trunk/src/host/opkg-utils/arfile.py 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,125 @@
+"""
+arfile - A module to parse GNU ar archives.
+
+Copyright (c) 2006-7 Paul Sokolovsky
+This file is released under the terms
+of GNU General Public License v2 or later.
+"""
+import sys
+import os
+import tarfile
+
+
+class FileSection:
+ "A class which allows to treat portion of file as separate file object."
+
+ def __init__(self, f, offset, size):
+ self.f = f
+ self.offset = offset
+ self.size = size
+ self.seek(0, 0)
+
+ def seek(self, offset, whence = 0):
+# print "seek(%x, %d)" % (offset, whence)
+ if whence == 0:
+ return self.f.seek(offset + self.offset, whence)
+ elif whence == 1:
+ return self.f.seek(offset, whence)
+ elif whence == 2:
+ return self.f.seek(self.offset + self.size + offset, 0)
+ else:
+ assert False
+
+ def tell(self):
+# print "tell()"
+ return self.f.tell() - self.offset
+
+ def read(self, size = -1):
+# print "read(%d)" % size
+ return self.f.read(size)
+
+class ArFile:
+
+ def __init__(self, f):
+ self.f = f
+ self.directory = {}
+ self.directoryRead = False
+
+ signature = self.f.readline()
+ assert signature == "!<arch>\n"
+ self.directoryOffset = self.f.tell()
+
+ def open(self, fname):
+ if self.directory.has_key(fname):
+ return FileSection(self.f, self.directory[fname][-1], int(self.directory[fname][5]))
+
+ if self.directoryRead:
+ raise IOError, (2, "AR member not found: " + fname)
+
+ f = self._scan(fname)
+ if f == None:
+ raise IOError, (2, "AR member not found: " + fname)
+ return f
+
+
+ def _scan(self, fname):
+ self.f.seek(self.directoryOffset, 0)
+
+ while True:
+ l = self.f.readline()
+ if not l:
+ self.directoryRead = True
+ return None
+
+ if l == "\n":
+ l = self.f.readline()
+ if not l: break
+ l = l.replace('`', '')
+ descriptor = l.split()
+# print descriptor
+ size = int(descriptor[5])
+ memberName = descriptor[0][:-1]
+ self.directory[memberName] = descriptor + [self.f.tell()]
+# print "read:", memberName
+ if memberName == fname:
+ # Record directory offset to start from next time
+ self.directoryOffset = self.f.tell() + size
+ return FileSection(self.f, self.f.tell(), size)
+
+ # Skip data and loop
+ data = self.f.seek(size, 1)
+# print hex(f.tell())
+
+
+if __name__ == "__main__":
+ if None:
+ f = open(sys.argv[1], "rb")
+
+ ar = ArFile(f)
+ tarStream = ar.open("data.tar.gz")
+ print "--------"
+ tarStream = ar.open("data.tar.gz")
+ print "--------"
+ tarStream = ar.open("control.tar.gz")
+ print "--------"
+ tarStream = ar.open("control.tar.gz2")
+
+ sys.exit(0)
+
+
+ dir = "."
+ if len(sys.argv) > 1:
+ dir = sys.argv[1]
+ for f in os.listdir(dir):
+ if not f.endswith(".ipk"): continue
+
+ print "=== %s ===" % f
+ f = open(dir + "/" + f, "rb")
+
+ ar = ArFile(f)
+ tarStream = ar.open("control.tar.gz")
+ tarf = tarfile.open("control.tar.gz", "r", tarStream)
+ #tarf.list()
+
+ f2 = tarf.extractfile("control")
+ print f2.read()
Added: trunk/src/host/opkg-utils/makePackage
===================================================================
--- trunk/src/host/opkg-utils/makePackage (rev 0)
+++ trunk/src/host/opkg-utils/makePackage 2008-07-18 11:29:53 UTC (rev 4534)
@@ -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 opkg
+
+fn = sys.argv[1]
+pkg = opkg.Package(fn)
+print pkg
Property changes on: trunk/src/host/opkg-utils/makePackage
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-build
===================================================================
--- trunk/src/host/opkg-utils/opkg-build (rev 0)
+++ trunk/src/host/opkg-utils/opkg-build 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,246 @@
+#!/bin/sh
+
+# opkg-build -- construct a .ipk from a directory
+# Carl Worth <cworth at east.isi.edu>
+# based on a script by Steve Redler IV, steve at sr-tech.com 5-21-2001
+# 2003-04-25 rea at 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
+
+opkg_extract_value() {
+ sed -e "s/^[^:]*:[[:space:]]*//"
+}
+
+required_field() {
+ field=$1
+
+ value=`grep "^$field:" < $CONTROL/control | opkg_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 | opkg_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 "opkg-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
+}
+
+###
+# opkg-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 "opkg-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"
Property changes on: trunk/src/host/opkg-utils/opkg-build
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-buildpackage
===================================================================
--- trunk/src/host/opkg-utils/opkg-buildpackage (rev 0)
+++ trunk/src/host/opkg-utils/opkg-buildpackage 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,223 @@
+#!/bin/sh
+#
+# Author: Oliver Kurth <oliver.kurth at innominate.com>
+#
+# Description:
+# builds an opkg package from a source tarball using opkg-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 'opkg'
+# - put all files which go to the 'CONTROL' directory of the root of the
+# installed package into opkg.
+# - 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
+
+SCRIPTNAME=`basename $0`
+
+opkg_extract_value() {
+ sed -e "s/^[^:]*:[[:space:]]*//"
+}
+
+required_field() {
+ field=$1
+
+ value=`grep "^$field:" < $CONTROL/control | opkg_extract_value`
+ if [ -z "$value" ]; then
+ echo "opkg-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 "opkg-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 "opkg-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 "opkg-build: Error: The following fields in $CONTROL/control are missing a ':'"
+ echo " $bad_fields"
+ echo "opkg-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 "opkg-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 ./opkg ] && CONTROL=./opkg
+if [ -z "$CONTROL" ]; then
+ echo "${SCRIPT_NAME}: Error: Directory $pkg_dir has no opkg 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 ..
+opkg-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
Property changes on: trunk/src/host/opkg-utils/opkg-buildpackage
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-compare-indexes
===================================================================
--- trunk/src/host/opkg-utils/opkg-compare-indexes (rev 0)
+++ trunk/src/host/opkg-utils/opkg-compare-indexes 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,49 @@
+#!/usr/bin/env python
+
+import sys, os
+from glob import glob
+import commands
+import opkg
+
+pkg_dir1 = sys.argv[1]
+pkg_dir2 = sys.argv[2]
+
+if ( not pkg_dir1 or not pkg_dir2 ):
+ sys.stderr.write("Usage: opkg-update-index <package_directory1> <package_directory2>\n")
+ sys.exit(1)
+
+pkgs1 = opkg.Packages()
+pkgs1.read_packages_file(pkg_dir1 + '/Packages')
+
+pkgs2 = opkg.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 = "opkg-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)
+
Property changes on: trunk/src/host/opkg-utils/opkg-compare-indexes
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-compare-versions.c
===================================================================
--- trunk/src/host/opkg-utils/opkg-compare-versions.c (rev 0)
+++ trunk/src/host/opkg-utils/opkg-compare-versions.c 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,163 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * vercmp.c - comparison of version numbers
+ *
+ * Copyright (C) 1995 Ian Jackson <iwj10 at 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;
+ const char *revision;
+};
+
+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;
+ r= verrevcmp(version->revision,refversion->revision); if (r) return r;
+ return r;
+}
+
+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;
+ }
+
+ rversion->revision = "";
+
+ 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]);
+}
+
+
Property changes on: trunk/src/host/opkg-utils/opkg-compare-versions.c
___________________________________________________________________
Name: svn:eol-style
+ native
Added: trunk/src/host/opkg-utils/opkg-compare-versions.sh
===================================================================
--- trunk/src/host/opkg-utils/opkg-compare-versions.sh (rev 0)
+++ trunk/src/host/opkg-utils/opkg-compare-versions.sh 2008-07-18 11:29:53 UTC (rev 4534)
@@ -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
+# opkg from /bin/sh to compiled C code...
+
+if [ $# -lt 3 ]; then
+ echo "
+usage: opkg-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 "opkg_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
Property changes on: trunk/src/host/opkg-utils/opkg-compare-versions.sh
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-diff
===================================================================
--- trunk/src/host/opkg-utils/opkg-diff (rev 0)
+++ trunk/src/host/opkg-utils/opkg-diff 2008-07-18 11:29:53 UTC (rev 4534)
@@ -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`
+
+opkg-unbuild $pkg2
+opkg-unbuild $pkg1
+
+diff -urN $dir1 $dir2
+
+rm -fr $dir1 $dir2
Property changes on: trunk/src/host/opkg-utils/opkg-diff
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-extract-file
===================================================================
--- trunk/src/host/opkg-utils/opkg-extract-file (rev 0)
+++ trunk/src/host/opkg-utils/opkg-extract-file 2008-07-18 11:29:53 UTC (rev 4534)
@@ -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
+ opkgfilename=$1
+ filename=$2
+else
+ echo "usage: $0 opkgfilename filename"
+ exit -1
+fi
+
+case $opkgfilename in
+http:*)
+ wget -N $opkgfilename
+ opkgfilename=`basename $opkgfilename`
+ echo eez http url $opkgfilename
+;;
+ftp:*)
+ wget -N $opkgfilename
+ opkgfilename=`basename $opkgfilename`
+ echo eez ftp url $opkgfilename
+;;
+esac
+
+
+tmpdir=/tmp/opkg-extract-$$
+mkdir $tmpdir
+
+pkgdir=$tmpdir/`basename $opkgfilename | sed 's/.*\///;s/.ipk$//;s/.deb$//'`
+
+mkdir -p $pkgdir/CONTROL
+
+cur_dir=$PWD
+cd $pkgdir; (ar x $cur_dir/$opkgfilename || tar zxf $cur_dir/$opkgfilename) >& /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
Property changes on: trunk/src/host/opkg-utils/opkg-extract-file
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-list-fields
===================================================================
--- trunk/src/host/opkg-utils/opkg-list-fields (rev 0)
+++ trunk/src/host/opkg-utils/opkg-list-fields 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+
+import sys, opkg
+
+def usage():
+ sys.stderr.write("%s ipk\n" % (sys.argv[0],))
+ sys.exit(-1)
+
+if (len(sys.argv) < 2):
+ usage()
+
+print opkg.Package(sys.argv[1])
+
Property changes on: trunk/src/host/opkg-utils/opkg-list-fields
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-make-index
===================================================================
--- trunk/src/host/opkg-utils/opkg-make-index (rev 0)
+++ trunk/src/host/opkg-utils/opkg-make-index 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,201 @@
+#!/usr/bin/python
+
+import sys, os, posixpath
+from glob import glob
+import commands
+import opkg
+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"
+stamplist_filename = "Packages.stamps"
+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
+ stamplist_filename = optval + ".stamps"
+ 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 = opkg.Packages()
+
+old_pkg_hash = {}
+if packages_filename and not old_filename and os.path.exists(packages_filename):
+ old_filename = packages_filename
+
+pkgsStamps = {}
+if old_filename:
+ if (verbose):
+ sys.stderr.write("Reading package list from " + old_filename + "\n")
+ old_packages = opkg.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
+ try:
+ f = open(stamplist_filename, "r")
+ for l in f:
+ l = l.strip()
+ s, f = l.split(" ", 1)
+ pkgsStamps[f] = int(s)
+ except IOError:
+ pass
+
+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)
+ pkg = None
+ fnameStat = os.stat(filename)
+ if old_pkg_hash.has_key(basename):
+ if pkgsStamps.has_key(basename) and fnameStat.st_mtime == pkgsStamps[basename]:
+ if (verbose):
+ sys.stderr.write("Found %s in Packages\n" % (filename,))
+ pkg = old_pkg_hash[basename]
+ else:
+ sys.stderr.write("Found %s in Packages, but mtime differs - re-reading\n" % (filename,))
+
+ if not pkg:
+ if (verbose):
+ sys.stderr.write("Reading info for package %s\n" % (filename,))
+ pkg = opkg.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)
+ pkgsStamps[basename] = fnameStat.st_mtime
+ 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
+
+pkgsStampsFile = open(stamplist_filename, "w")
+for f in pkgsStamps.keys():
+ pkgsStampsFile.write("%d %s\n" % (pkgsStamps[f], f))
+pkgsStampsFile.close()
+
+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)
Property changes on: trunk/src/host/opkg-utils/opkg-make-index
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-show-deps
===================================================================
--- trunk/src/host/opkg-utils/opkg-show-deps (rev 0)
+++ trunk/src/host/opkg-utils/opkg-show-deps 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+
+import sys, os, posixpath
+from glob import glob
+import commands
+import opkg
+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 = opkg.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
+
Property changes on: trunk/src/host/opkg-utils/opkg-show-deps
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-unbuild
===================================================================
--- trunk/src/host/opkg-utils/opkg-unbuild (rev 0)
+++ trunk/src/host/opkg-utils/opkg-unbuild 2008-07-18 11:29:53 UTC (rev 4534)
@@ -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))
Property changes on: trunk/src/host/opkg-utils/opkg-unbuild
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg-update-index
===================================================================
--- trunk/src/host/opkg-utils/opkg-update-index (rev 0)
+++ trunk/src/host/opkg-utils/opkg-update-index 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,24 @@
+#!/usr/bin/env python2.1
+
+import sys, os
+from glob import glob
+import commands
+import opkg
+
+pkg_dir=sys.argv[1]
+pkg_filename = sys.argv[2]
+
+if ( not pkg_dir or not pkg_filename ):
+ sys.stderr.write("Usage: opkg-update-index <package_directory> <pkgfilename>\n")
+ sys.exit(1)
+
+packages = opkg.Packages()
+
+packages.read_packages_file(pkg_dir + '/Packages')
+
+names = packages.packages.keys()
+
+packages.add_package(opkg.Package(pkg_filename))
+
+packages.write_packages_file(pkg_dir + '/Packages.new')
+os.rename(pkg_dir + '/Packages.new', pkg_dir + '/Packages')
Property changes on: trunk/src/host/opkg-utils/opkg-update-index
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/src/host/opkg-utils/opkg.py
===================================================================
--- trunk/src/host/opkg-utils/opkg.py (rev 0)
+++ trunk/src/host/opkg-utils/opkg.py 2008-07-18 11:29:53 UTC (rev 4534)
@@ -0,0 +1,487 @@
+#!/usr/bin/env python
+# Copyright (C) 2001 Alexander S. Guy <a7r at 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 <opkg.py at 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 opkg 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
+import arfile
+import tarfile
+
+class Version:
+ """A class for holding parsed package version information."""
+ def __init__(self, epoch, version):
+ self.epoch = epoch
+ self.version = version
+
+ def _versioncompare(self, selfversion, refversion):
+ if not selfversion: selfversion = ""
+ if not refversion: refversion = ""
+ 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:
+ self_ver_comps = re.match(r"(.+?)(-r.+)?$", self.version)
+ ref_ver_comps = re.match(r"(.+?)(-r.+)?$", ref.version)
+ #print (self_ver_comps.group(1), self_ver_comps.group(2))
+ #print (ref_ver_comps.group(1), ref_ver_comps.group(2))
+ r = self._versioncompare(self_ver_comps.group(1), ref_ver_comps.group(1))
+ if r == 0:
+ r = self._versioncompare(self_ver_comps.group(2), ref_ver_comps.group(2))
+ #print "compare: %s vs %s = %d" % (self, ref, r)
+ return r
+
+ def __str__(self):
+ return str(self.epoch) + ":" + self.version
+
+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) opkg
+ 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 = []
+ # md5 is lazy attribute, computed on demand
+ #self.md5 = None
+ self.size = None
+ self.installed_size = None
+ self.filename = None
+ self.isdeb = 0
+ self.homepage = None
+ self.oe = None
+ self.priority = None
+ self.fn = fn
+
+ if fn:
+ # see if it is deb format
+ f = open(fn, "rb")
+ magic = f.read(4)
+ f.seek(0, 0)
+ if (magic == "!<ar"):
+ self.isdeb = 1
+
+
+ self.filename = os.path.basename(fn)
+ assert self.isdeb == 1, "Old ipk format (non-deb) is unsupported"
+
+ ## sys.stderr.write(" extracting control.tar.gz from %s\n"% (fn,))
+
+ ar = arfile.ArFile(f)
+ tarStream = ar.open("control.tar.gz")
+ tarf = tarfile.open("control.tar.gz", "r", tarStream)
+
+ try:
+ control = tarf.extractfile("control")
+ except KeyError:
+ control = tarf.extractfile("./control")
+ self.read_control(control)
+ control.close()
+
+ self.scratch_dir = None
+ self.file_dir = None
+ self.meta_dir = None
+
+ def __getattr__(self, name):
+ if name == "md5":
+ self._computeFileMD5()
+ return self.md5
+ else:
+ raise AttributeError, name
+
+ def _computeFileMD5(self):
+ # compute the MD5.
+ f = open(self.fn, "rb")
+ sum = md5.new()
+ while 1:
+ data = f.read(1024)
+ if not data: break
+ sum.update(data)
+ f.close()
+ self.md5 = sum.hexdigest()
+
+ 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 name == 'md5sum':
+ self.md5 = value
+ elif self.__dict__.has_key(name):
+ self.__dict__[name] = value
+ else:
+ print "Lost field %s, %s" % (name,value)
+ pass
+
+ if line and 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/%sopkg" % (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):
+ if not self.fn:
+ return []
+ f = open(self.fn, "rb")
+ ar = arfile.ArFile(f)
+ tarStream = ar.open("data.tar.gz")
+ tarf = tarfile.open("data.tar.gz", "r", tarStream)
+ self.file_list = tarf.getnames()
+ self.file_list = map(lambda a: ["./", ""][a.startswith("./")] + a, self.file_list)
+
+ f.close()
+ 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)
+ if self.oe: out = out + "OE: %s\n" % (self.oe)
+ if self.homepage: out = out + "HomePage: %s\n" % (self.homepage)
+ if self.priority: out = out + "Priority: %s\n" % (self.priority)
+ 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 opkg 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__":
+
+ assert Version(0, "1.2.2-r1").compare(Version(0, "1.2.3-r0")) == -1
+ assert Version(0, "1.2.2-r0").compare(Version(0, "1.2.2+cvs20070308-r0")) == -1
+ assert Version(0, "1.2.2+cvs20070308").compare(Version(0, "1.2.2-r0")) == 1
+ assert Version(0, "1.2.2-r0").compare(Version(0, "1.2.2-r0")) == 0
+ assert Version(0, "1.2.2-r5").compare(Version(0, "1.2.2-r0")) == 1
+
+ package = Package()
+
+ package.set_package("FooBar")
+ package.set_version("0.1-fam1")
+ package.set_architecture("arm")
+ package.set_maintainer("Testing <testing at testing.testing>")
+ package.set_depends("libc")
+ package.set_description("A test of the APIs.")
+
+ print "<"
+ sys.stdout.write(package)
+ print ">"
+
+ package.write_package("/tmp")
+
More information about the commitlog
mailing list