aboutsummaryrefslogtreecommitdiffstats
path: root/package/system/opkg
diff options
context:
space:
mode:
Diffstat (limited to 'package/system/opkg')
-rw-r--r--package/system/opkg/Makefile102
-rw-r--r--package/system/opkg/files/opkg.conf5
-rw-r--r--package/system/opkg/patches/001-ship-pkg-m4.patch168
-rw-r--r--package/system/opkg/patches/002-no-shave.patch37
-rw-r--r--package/system/opkg/patches/004-host_cpu.patch20
-rw-r--r--package/system/opkg/patches/007-force_static.patch71
-rw-r--r--package/system/opkg/patches/009-remove-upgrade-all.patch41
-rw-r--r--package/system/opkg/patches/011-old-config-location.patch12
-rw-r--r--package/system/opkg/patches/012-strip-trailing-conffiles-whitespace.patch23
-rw-r--r--package/system/opkg/patches/014-errors-to-stderr.patch15
-rw-r--r--package/system/opkg/patches/020-avoid_getline.patch317
-rw-r--r--package/system/opkg/patches/030-fix-double-free.patch10
-rw-r--r--package/system/opkg/patches/040-wrap-descriptions-only-on-ttys.patch31
-rw-r--r--package/system/opkg/patches/050-add-case-insensitive-flag.patch169
-rw-r--r--package/system/opkg/patches/060-add-find-command.patch58
-rw-r--r--package/system/opkg/patches/070-use_gzipped_pkg_list.patch120
16 files changed, 1199 insertions, 0 deletions
diff --git a/package/system/opkg/Makefile b/package/system/opkg/Makefile
new file mode 100644
index 0000000000..6407ab451f
--- /dev/null
+++ b/package/system/opkg/Makefile
@@ -0,0 +1,102 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+include $(INCLUDE_DIR)/version.mk
+
+PKG_NAME:=opkg
+PKG_REV:=618
+PKG_VERSION:=$(PKG_REV)
+PKG_RELEASE:=3
+
+PKG_SOURCE_PROTO:=svn
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_SOURCE_SUBDIR:=opkg-$(PKG_VERSION)
+PKG_SOURCE_URL:=http://opkg.googlecode.com/svn/trunk/
+PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
+PKG_FIXUP:=autoreconf
+PKG_REMOVE_FILES = autogen.sh aclocal.m4
+
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+HOST_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/opkg
+ SECTION:=base
+ CATEGORY:=Base system
+ TITLE:=opkg package management system
+ MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
+ URL:=http://wiki.openmoko.org/wiki/Opkg
+endef
+
+define Package/opkg/description
+ Lightweight package management system
+ opkg is the opkg Package Management System, for handling
+ installation and removal of packages on a system. It can
+ recursively follow dependencies and download all packages
+ necessary to install a particular package.
+
+ opkg knows how to install both .ipk and .deb packages.
+endef
+
+define Package/opkg/conffiles
+/etc/opkg.conf
+endef
+
+TARGET_CFLAGS += $(if $(CONFIG_GCC_VERSION_4_3)$(CONFIG_GCC_VERSION_4_4),-Wno-array-bounds)
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+EXTRA_CFLAGS += $(TARGET_CPPFLAGS)
+
+CONFIGURE_ARGS += \
+ --disable-curl \
+ --disable-gpg \
+ --with-opkgetcdir=/etc \
+ --with-opkglockfile=/var/lock/opkg.lock
+
+MAKE_FLAGS = \
+ CC="$(TARGET_CC)" \
+ DESTDIR="$(PKG_INSTALL_DIR)" \
+ HOST_CPU="$(PKGARCH)" \
+ LDFLAGS="-Wl,--gc-sections" \
+
+define Package/opkg/install
+ $(INSTALL_DIR) $(1)/usr/lib/opkg
+ $(INSTALL_DIR) $(1)/bin
+ $(INSTALL_DIR) $(1)/etc
+ $(INSTALL_DATA) ./files/opkg.conf $(1)/etc/
+ $(VERSION_SED) $(1)/etc/opkg.conf
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/opkg-cl $(1)/bin/opkg
+endef
+
+define Build/InstallDev
+ mkdir -p $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/libopkg $(1)/usr/include/
+endef
+
+
+HOST_CONFIGURE_ARGS+= \
+ --disable-curl \
+ --disable-gpg \
+ --with-opkgetcdir=/etc \
+ --with-opkglockfile=/tmp/opkg.lock
+
+define Host/Compile
+ +$(MAKE) $(HOST_JOBS) -C $(HOST_BUILD_DIR) CC="$(HOSTCC)" all
+endef
+
+define Host/Install
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/opkg-cl $(STAGING_DIR_HOST)/bin/opkg
+endef
+
+$(eval $(call BuildPackage,opkg))
+$(eval $(call HostBuild))
diff --git a/package/system/opkg/files/opkg.conf b/package/system/opkg/files/opkg.conf
new file mode 100644
index 0000000000..6fb42b7fa4
--- /dev/null
+++ b/package/system/opkg/files/opkg.conf
@@ -0,0 +1,5 @@
+src/gz %n %U
+dest root /
+dest ram /tmp
+lists_dir ext /var/opkg-lists
+option overlay_root /overlay
diff --git a/package/system/opkg/patches/001-ship-pkg-m4.patch b/package/system/opkg/patches/001-ship-pkg-m4.patch
new file mode 100644
index 0000000000..4ca0f88970
--- /dev/null
+++ b/package/system/opkg/patches/001-ship-pkg-m4.patch
@@ -0,0 +1,168 @@
+--- /dev/null
++++ b/m4/pkg.m4
+@@ -0,0 +1,157 @@
++# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
++#
++# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
++#
++# 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.
++#
++# As a special exception to the GNU General Public License, if you
++# distribute this file as part of a program that contains a
++# configuration script generated by Autoconf, you may include it under
++# the same distribution terms that you use for the rest of that program.
++
++# PKG_PROG_PKG_CONFIG([MIN-VERSION])
++# ----------------------------------
++AC_DEFUN([PKG_PROG_PKG_CONFIG],
++[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
++m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
++AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
++ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
++fi
++if test -n "$PKG_CONFIG"; then
++ _pkg_min_version=m4_default([$1], [0.9.0])
++ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
++ AC_MSG_RESULT([yes])
++ else
++ AC_MSG_RESULT([no])
++ PKG_CONFIG=""
++ fi
++
++fi[]dnl
++])# PKG_PROG_PKG_CONFIG
++
++# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
++#
++# Check to see whether a particular set of modules exists. Similar
++# to PKG_CHECK_MODULES(), but does not set variables or print errors.
++#
++#
++# Similar to PKG_CHECK_MODULES, make sure that the first instance of
++# this or PKG_CHECK_MODULES is called, or make sure to call
++# PKG_CHECK_EXISTS manually
++# --------------------------------------------------------------
++AC_DEFUN([PKG_CHECK_EXISTS],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++if test -n "$PKG_CONFIG" && \
++ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
++ m4_ifval([$2], [$2], [:])
++m4_ifvaln([$3], [else
++ $3])dnl
++fi])
++
++
++# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
++# ---------------------------------------------
++m4_define([_PKG_CONFIG],
++[if test -n "$PKG_CONFIG"; then
++ if test -n "$$1"; then
++ pkg_cv_[]$1="$$1"
++ else
++ PKG_CHECK_EXISTS([$3],
++ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
++ [pkg_failed=yes])
++ fi
++else
++ pkg_failed=untried
++fi[]dnl
++])# _PKG_CONFIG
++
++# _PKG_SHORT_ERRORS_SUPPORTED
++# -----------------------------
++AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
++ _pkg_short_errors_supported=yes
++else
++ _pkg_short_errors_supported=no
++fi[]dnl
++])# _PKG_SHORT_ERRORS_SUPPORTED
++
++
++# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
++# [ACTION-IF-NOT-FOUND])
++#
++#
++# Note that if there is a possibility the first call to
++# PKG_CHECK_MODULES might not happen, you should be sure to include an
++# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
++#
++#
++# --------------------------------------------------------------
++AC_DEFUN([PKG_CHECK_MODULES],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
++AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
++
++pkg_failed=no
++AC_MSG_CHECKING([for $1])
++
++_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
++_PKG_CONFIG([$1][_LIBS], [libs], [$2])
++
++m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
++and $1[]_LIBS to avoid the need to call pkg-config.
++See the pkg-config man page for more details.])
++
++if test $pkg_failed = yes; then
++ _PKG_SHORT_ERRORS_SUPPORTED
++ if test $_pkg_short_errors_supported = yes; then
++ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
++ else
++ $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
++ fi
++ # Put the nasty error message in config.log where it belongs
++ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
++
++ ifelse([$4], , [AC_MSG_ERROR(dnl
++[Package requirements ($2) were not met:
++
++$$1_PKG_ERRORS
++
++Consider adjusting the PKG_CONFIG_PATH environment variable if you
++installed software in a non-standard prefix.
++
++_PKG_TEXT
++])],
++ [AC_MSG_RESULT([no])
++ $4])
++elif test $pkg_failed = untried; then
++ ifelse([$4], , [AC_MSG_FAILURE(dnl
++[The pkg-config script could not be found or is too old. Make sure it
++is in your PATH or set the PKG_CONFIG environment variable to the full
++path to pkg-config.
++
++_PKG_TEXT
++
++To get pkg-config, see <http://pkg-config.freedesktop.org/>.])],
++ [$4])
++else
++ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
++ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
++ AC_MSG_RESULT([yes])
++ ifelse([$3], , :, [$3])
++fi[]dnl
++])# PKG_CHECK_MODULES
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-ACLOCAL_AMFLAGS = -I shave
++ACLOCAL_AMFLAGS = -I shave -I m4
+
+ SUBDIRS = libbb libopkg src tests utils man
+
diff --git a/package/system/opkg/patches/002-no-shave.patch b/package/system/opkg/patches/002-no-shave.patch
new file mode 100644
index 0000000000..313aa71b00
--- /dev/null
+++ b/package/system/opkg/patches/002-no-shave.patch
@@ -0,0 +1,37 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -4,7 +4,6 @@ AC_CONFIG_SRCDIR([libopkg/pkg.c])
+
+ AC_CONFIG_AUX_DIR([conf])
+ AC_CONFIG_MACRO_DIR([m4])
+-AC_CONFIG_MACRO_DIR([shave])
+
+ AM_INIT_AUTOMAKE
+ AM_CONFIG_HEADER(libopkg/config.h)
+@@ -277,9 +276,6 @@ AC_SUBST(opkgetcdir)
+ AC_SUBST(opkglockfile)
+ AC_SUBST([CLEAN_DATE])
+
+-# Setup output beautifier.
+-SHAVE_INIT([shave], [enable])
+-
+ AC_OUTPUT(
+ Makefile
+ libopkg/Makefile
+@@ -289,8 +285,6 @@ AC_OUTPUT(
+ utils/Makefile
+ utils/update-alternatives
+ libopkg.pc
+- shave/shave
+- shave/shave-libtool
+ man/Makefile
+ man/opkg-cl.1
+ man/opkg-key.1
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-ACLOCAL_AMFLAGS = -I shave -I m4
++ACLOCAL_AMFLAGS = -I m4
+
+ SUBDIRS = libbb libopkg src tests utils man
+
diff --git a/package/system/opkg/patches/004-host_cpu.patch b/package/system/opkg/patches/004-host_cpu.patch
new file mode 100644
index 0000000000..d500d603da
--- /dev/null
+++ b/package/system/opkg/patches/004-host_cpu.patch
@@ -0,0 +1,20 @@
+--- a/libbb/Makefile.am
++++ b/libbb/Makefile.am
+@@ -1,6 +1,6 @@
+ HOST_CPU=@host_cpu@
+ BUILD_CPU=@build_cpu@
+-ALL_CFLAGS=-g -O -Wall -DHOST_CPU_STR=\"@host_cpu@\" -DBUILD_CPU=@build_cpu@
++ALL_CFLAGS=-g -O -Wall -DHOST_CPU_STR=\"$(HOST_CPU)\" -DBUILD_CPU=@build_cpu@
+
+ noinst_LTLIBRARIES = libbb.la
+
+--- a/libopkg/Makefile.am
++++ b/libopkg/Makefile.am
+@@ -1,5 +1,5 @@
+-
+-AM_CFLAGS=-Wall -DHOST_CPU_STR=\"@host_cpu@\" -DBUILD_CPU=@build_cpu@ -DLIBDIR=\"@libdir@\" -DOPKGLIBDIR=\"@opkglibdir@\" -DOPKGETCDIR=\"@opkgetcdir@\" -DOPKGLOCKFILE=\"@opkglockfile@\" -DDATADIR=\"@datadir@\" -I$(top_srcdir) $(BIGENDIAN_CFLAGS) $(CURL_CFLAGS) $(GPGME_CFLAGS) $(PATHFINDER_CFLAGS)
++HOST_CPU=@host_cpu@
++AM_CFLAGS=-Wall -DHOST_CPU_STR=\"$(HOST_CPU)\" -DBUILD_CPU=@build_cpu@ -DLIBDIR=\"@libdir@\" -DOPKGLIBDIR=\"@opkglibdir@\" -DOPKGETCDIR=\"@opkgetcdir@\" -DOPKGLOCKFILE=\"@opkglockfile@\" -DDATADIR=\"@datadir@\" -I$(top_srcdir) $(BIGENDIAN_CFLAGS) $(CURL_CFLAGS) $(GPGME_CFLAGS) $(PATHFINDER_CFLAGS)
+
+ libopkg_includedir=$(includedir)/libopkg
+ libopkg_include_HEADERS= *.h
diff --git a/package/system/opkg/patches/007-force_static.patch b/package/system/opkg/patches/007-force_static.patch
new file mode 100644
index 0000000000..80a9815a8e
--- /dev/null
+++ b/package/system/opkg/patches/007-force_static.patch
@@ -0,0 +1,71 @@
+--- a/libopkg/Makefile.am
++++ b/libopkg/Makefile.am
+@@ -38,16 +38,10 @@ if HAVE_SHA256
+ opkg_util_sources += sha256.c sha256.h
+ endif
+
+-lib_LTLIBRARIES = libopkg.la
+-libopkg_la_SOURCES = \
++noinst_LIBRARIES = libopkg.a
++libopkg_a_SOURCES = \
+ $(opkg_libcore_sources) \
+ $(opkg_cmd_sources) $(opkg_db_sources) \
+ $(opkg_util_sources) $(opkg_list_sources)
+
+-libopkg_la_LIBADD = $(top_builddir)/libbb/libbb.la $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS) $(PATHFINDER_LIBS)
+-
+-# make sure we only export symbols that are for public use
+-#libopkg_la_LDFLAGS = -export-symbols-regex "^opkg_.*"
+-
+-
+-
++libopkg_a_LIBADD = $(top_builddir)/libbb/libbb.a $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS) $(PATHFINDER_LIBS)
+--- a/libbb/Makefile.am
++++ b/libbb/Makefile.am
+@@ -2,9 +2,9 @@ HOST_CPU=@host_cpu@
+ BUILD_CPU=@build_cpu@
+ ALL_CFLAGS=-g -O -Wall -DHOST_CPU_STR=\"$(HOST_CPU)\" -DBUILD_CPU=@build_cpu@
+
+-noinst_LTLIBRARIES = libbb.la
++noinst_LIBRARIES = libbb.a
+
+-libbb_la_SOURCES = gz_open.c \
++libbb_a_SOURCES = gz_open.c \
+ libbb.h \
+ unzip.c \
+ wfopen.c \
+--- a/tests/Makefile.am
++++ b/tests/Makefile.am
+@@ -4,11 +4,11 @@ AM_CFLAGS = $(ALL_CFLAGS) -Wall -g -O3 -
+ #noinst_PROGRAMS = libopkg_test opkg_active_list_test
+ noinst_PROGRAMS = libopkg_test
+
+-#opkg_hash_test_LDADD = $(top_builddir)/libbb/libbb.la $(top_builddir)/libopkg/libopkg.la
++#opkg_hash_test_LDADD = $(top_builddir)/libbb/libbb.a $(top_builddir)/libopkg/libopkg.a
+ #opkg_hash_test_SOURCES = opkg_hash_test.c
+ #opkg_hash_test_CFLAGS = $(ALL_CFLAGS) -I$(top_srcdir)
+
+-#opkg_extract_test_LDADD = $(top_builddir)/libbb/libbb.la $(top_builddir)/libopkg/libopkg.la
++#opkg_extract_test_LDADD = $(top_builddir)/libbb/libbb.a $(top_builddir)/libopkg/libopkg.a
+ #opkg_extract_test_SOURCES = opkg_extract_test.c
+ #opkg_extract_test_CFLAGS = $(ALL_CFLAGS) -I$(top_srcdir)
+
+@@ -16,7 +16,7 @@ noinst_PROGRAMS = libopkg_test
+ #opkg_active_list_test_SOURCES = opkg_active_list_test.c
+ #opkg_active_list_test_CFLAGS = $(ALL_CFLAGS) -I$(top_srcdir)
+
+-libopkg_test_LDADD = $(top_builddir)/libopkg/libopkg.la
++libopkg_test_LDADD = $(top_builddir)/libopkg/libopkg.a $(top_builddir)/libbb/libbb.a
+ libopkg_test_SOURCE = libopkg_test.c
+ libopkg_test_LDFLAGS = -static
+
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -2,5 +2,5 @@ AM_CFLAGS = -I${top_srcdir}/libopkg ${AL
+ bin_PROGRAMS = opkg-cl
+
+ opkg_cl_SOURCES = opkg-cl.c
+-opkg_cl_LDADD = $(top_builddir)/libopkg/libopkg.la \
+- $(top_builddir)/libbb/libbb.la
++opkg_cl_LDADD = $(top_builddir)/libopkg/libopkg.a \
++ $(top_builddir)/libbb/libbb.a
diff --git a/package/system/opkg/patches/009-remove-upgrade-all.patch b/package/system/opkg/patches/009-remove-upgrade-all.patch
new file mode 100644
index 0000000000..395a2a6f91
--- /dev/null
+++ b/package/system/opkg/patches/009-remove-upgrade-all.patch
@@ -0,0 +1,41 @@
+--- a/libopkg/opkg_cmd.c
++++ b/libopkg/opkg_cmd.c
+@@ -551,18 +551,6 @@ opkg_upgrade_cmd(int argc, char **argv)
+ err = -1;
+ }
+ }
+- } else {
+- pkg_vec_t *installed = pkg_vec_alloc();
+-
+- pkg_info_preinstall_check();
+-
+- pkg_hash_fetch_all_installed(installed);
+- for (i = 0; i < installed->len; i++) {
+- pkg = installed->pkgs[i];
+- if (opkg_upgrade_pkg(pkg))
+- err = -1;
+- }
+- pkg_vec_free(installed);
+ }
+
+ if (opkg_configure_packages(NULL))
+@@ -1258,7 +1246,7 @@ opkg_print_architecture_cmd(int argc, ch
+ array for easier maintenance */
+ static opkg_cmd_t cmds[] = {
+ {"update", 0, (opkg_cmd_fun_t)opkg_update_cmd, PFM_DESCRIPTION|PFM_SOURCE},
+- {"upgrade", 0, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
++ {"upgrade", 1, (opkg_cmd_fun_t)opkg_upgrade_cmd, PFM_DESCRIPTION|PFM_SOURCE},
+ {"list", 0, (opkg_cmd_fun_t)opkg_list_cmd, PFM_SOURCE},
+ {"list_installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
+ {"list-installed", 0, (opkg_cmd_fun_t)opkg_list_installed_cmd, PFM_SOURCE},
+--- a/src/opkg-cl.c
++++ b/src/opkg-cl.c
+@@ -221,7 +221,7 @@ usage()
+
+ printf("\nPackage Manipulation:\n");
+ printf("\tupdate Update list of available packages\n");
+- printf("\tupgrade Upgrade installed packages\n");
++ printf("\tupgrade <pkgs> Upgrade packages\n");
+ printf("\tinstall <pkgs> Install package(s)\n");
+ printf("\tconfigure <pkgs> Configure unpacked package(s)\n");
+ printf("\tremove <pkgs|regexp> Remove package(s)\n");
diff --git a/package/system/opkg/patches/011-old-config-location.patch b/package/system/opkg/patches/011-old-config-location.patch
new file mode 100644
index 0000000000..0555926864
--- /dev/null
+++ b/package/system/opkg/patches/011-old-config-location.patch
@@ -0,0 +1,12 @@
+--- a/src/opkg-cl.c
++++ b/src/opkg-cl.c
+@@ -207,6 +207,9 @@ args_parse(int argc, char *argv[])
+ }
+ }
+
++ if(!conf->conf_file && !conf->offline_root)
++ conf->conf_file = xstrdup("/etc/opkg.conf");
++
+ if (parse_err)
+ return parse_err;
+ else
diff --git a/package/system/opkg/patches/012-strip-trailing-conffiles-whitespace.patch b/package/system/opkg/patches/012-strip-trailing-conffiles-whitespace.patch
new file mode 100644
index 0000000000..a47ae77cee
--- /dev/null
+++ b/package/system/opkg/patches/012-strip-trailing-conffiles-whitespace.patch
@@ -0,0 +1,23 @@
+--- a/libopkg/opkg_install.c
++++ b/libopkg/opkg_install.c
+@@ -274,6 +274,7 @@ unpack_pkg_control_files(pkg_t *pkg)
+ while (1) {
+ char *cf_name;
+ char *cf_name_in_dest;
++ int i;
+
+ cf_name = file_read_line_alloc(conffiles_file);
+ if (cf_name == NULL) {
+@@ -282,6 +283,12 @@ unpack_pkg_control_files(pkg_t *pkg)
+ if (cf_name[0] == '\0') {
+ continue;
+ }
++ for (i = strlen(cf_name) - 1;
++ (i >= 0) && (cf_name[i] == ' ' || cf_name[i] == '\t');
++ i--
++ ) {
++ cf_name[i] = '\0';
++ }
+
+ /* Prepend dest->root_dir to conffile name.
+ Take pains to avoid multiple slashes. */
diff --git a/package/system/opkg/patches/014-errors-to-stderr.patch b/package/system/opkg/patches/014-errors-to-stderr.patch
new file mode 100644
index 0000000000..f0a93a8717
--- /dev/null
+++ b/package/system/opkg/patches/014-errors-to-stderr.patch
@@ -0,0 +1,15 @@
+--- a/libopkg/opkg_message.c
++++ b/libopkg/opkg_message.c
+@@ -64,10 +64,10 @@ print_error_list(void)
+ struct errlist *err = error_list_head;
+
+ if (err) {
+- printf("Collected errors:\n");
++ fprintf(stderr, "Collected errors:\n");
+ /* Here we print the errors collected and free the list */
+ while (err != NULL) {
+- printf(" * %s", err->errmsg);
++ fprintf(stderr, " * %s", err->errmsg);
+ err = err->next;
+ }
+ }
diff --git a/package/system/opkg/patches/020-avoid_getline.patch b/package/system/opkg/patches/020-avoid_getline.patch
new file mode 100644
index 0000000000..8a1a8f6272
--- /dev/null
+++ b/package/system/opkg/patches/020-avoid_getline.patch
@@ -0,0 +1,317 @@
+--- a/libopkg/parse_util.c
++++ b/libopkg/parse_util.c
+@@ -22,6 +22,7 @@
+ #include "libbb/libbb.h"
+
+ #include "parse_util.h"
++#include "pkg_parse.h"
+
+ int
+ is_field(const char *type, const char *line)
+@@ -86,3 +87,84 @@ parse_list(const char *raw, unsigned int
+ *count = line_count;
+ return depends;
+ }
++
++int
++parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
++ char **buf0, size_t buf0len)
++{
++ int ret, lineno;
++ char *buf, *nl;
++ size_t buflen;
++
++ lineno = 1;
++ ret = 0;
++
++ buflen = buf0len;
++ buf = *buf0;
++ buf[0] = '\0';
++
++ while (1) {
++ if (fgets(buf, (int)buflen, fp) == NULL) {
++ if (ferror(fp)) {
++ opkg_perror(ERROR, "fgets");
++ ret = -1;
++ } else if (strlen(*buf0) == buf0len-1) {
++ opkg_msg(ERROR, "Missing new line character"
++ " at end of file!\n");
++ parse_line(item, *buf0, mask);
++ }
++ break;
++ }
++
++ nl = strchr(buf, '\n');
++ if (nl == NULL) {
++ if (strlen(buf) < buflen-1) {
++ /*
++ * Line could be exactly buflen-1 long and
++ * missing a newline, but we won't know until
++ * fgets fails to read more data.
++ */
++ opkg_msg(ERROR, "Missing new line character"
++ " at end of file!\n");
++ parse_line(item, *buf0, mask);
++ break;
++ }
++ if (buf0len >= EXCESSIVE_LINE_LEN) {
++ opkg_msg(ERROR, "Excessively long line at "
++ "%d. Corrupt file?\n",
++ lineno);
++ ret = -1;
++ break;
++ }
++
++ /*
++ * Realloc and point buf past the data already read,
++ * at the NULL terminator inserted by fgets.
++ * |<--------------- buf0len ----------------->|
++ * | |<------- buflen ---->|
++ * |---------------------|---------------------|
++ * buf0 buf
++ */
++ buflen = buf0len +1;
++ buf0len *= 2;
++ *buf0 = xrealloc(*buf0, buf0len);
++ buf = *buf0 + buflen -2;
++
++ continue;
++ }
++
++ *nl = '\0';
++
++ lineno++;
++
++ if (parse_line(item, *buf0, mask))
++ break;
++
++ buf = *buf0;
++ buflen = buf0len;
++ buf[0] = '\0';
++ }
++
++ return ret;
++}
++
+--- a/libopkg/parse_util.h
++++ b/libopkg/parse_util.h
+@@ -22,4 +22,8 @@ int is_field(const char *type, const cha
+ char *parse_simple(const char *type, const char *line);
+ char **parse_list(const char *raw, unsigned int *count, const char sep, int skip_field);
+
++typedef int (*parse_line_t)(void *, const char *, uint);
++int parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE *fp, uint mask,
++ char **buf0, size_t buf0len);
++
+ #endif
+--- a/libopkg/pkg_hash.c
++++ b/libopkg/pkg_hash.c
+@@ -23,6 +23,7 @@
+ #include "opkg_message.h"
+ #include "pkg_vec.h"
+ #include "pkg_hash.h"
++#include "parse_util.h"
+ #include "pkg_parse.h"
+ #include "opkg_utils.h"
+ #include "sprintf_alloc.h"
+@@ -119,8 +120,14 @@ pkg_hash_add_from_file(const char *file_
+ pkg->src = src;
+ pkg->dest = dest;
+
+- ret = pkg_parse_from_stream_nomalloc(pkg, fp, 0,
++ ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, 0,
+ &buf, len);
++
++ if (pkg->name == NULL) {
++ /* probably just a blank line */
++ ret = 1;
++ }
++
+ if (ret) {
+ pkg_deinit (pkg);
+ free(pkg);
+--- a/libopkg/pkg_parse.c
++++ b/libopkg/pkg_parse.c
+@@ -104,9 +104,11 @@ get_arch_priority(const char *arch)
+ return 0;
+ }
+
+-static int
+-pkg_parse_line(pkg_t *pkg, const char *line, uint mask)
++int
++pkg_parse_line(void *ptr, const char *line, uint mask)
+ {
++ pkg_t *pkg = (pkg_t *) ptr;
++
+ /* these flags are a bit hackish... */
+ static int reading_conffiles = 0, reading_description = 0;
+ int ret = 0;
+@@ -266,91 +268,6 @@ dont_reset_flags:
+ }
+
+ int
+-pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask,
+- char **buf0, size_t buf0len)
+-{
+- int ret, lineno;
+- char *buf, *nl;
+- size_t buflen;
+-
+- lineno = 1;
+- ret = 0;
+-
+- buflen = buf0len;
+- buf = *buf0;
+- buf[0] = '\0';
+-
+- while (1) {
+- if (fgets(buf, (int)buflen, fp) == NULL) {
+- if (ferror(fp)) {
+- opkg_perror(ERROR, "fgets");
+- ret = -1;
+- } else if (strlen(*buf0) == buf0len-1) {
+- opkg_msg(ERROR, "Missing new line character"
+- " at end of file!\n");
+- pkg_parse_line(pkg, *buf0, mask);
+- }
+- break;
+- }
+-
+- nl = strchr(buf, '\n');
+- if (nl == NULL) {
+- if (strlen(buf) < buflen-1) {
+- /*
+- * Line could be exactly buflen-1 long and
+- * missing a newline, but we won't know until
+- * fgets fails to read more data.
+- */
+- opkg_msg(ERROR, "Missing new line character"
+- " at end of file!\n");
+- pkg_parse_line(pkg, *buf0, mask);
+- break;
+- }
+- if (buf0len >= EXCESSIVE_LINE_LEN) {
+- opkg_msg(ERROR, "Excessively long line at "
+- "%d. Corrupt file?\n",
+- lineno);
+- ret = -1;
+- break;
+- }
+-
+- /*
+- * Realloc and point buf past the data already read,
+- * at the NULL terminator inserted by fgets.
+- * |<--------------- buf0len ----------------->|
+- * | |<------- buflen ---->|
+- * |---------------------|---------------------|
+- * buf0 buf
+- */
+- buflen = buf0len +1;
+- buf0len *= 2;
+- *buf0 = xrealloc(*buf0, buf0len);
+- buf = *buf0 + buflen -2;
+-
+- continue;
+- }
+-
+- *nl = '\0';
+-
+- lineno++;
+-
+- if (pkg_parse_line(pkg, *buf0, mask))
+- break;
+-
+- buf = *buf0;
+- buflen = buf0len;
+- buf[0] = '\0';
+- }
+-
+- if (pkg->name == NULL) {
+- /* probably just a blank line */
+- ret = 1;
+- }
+-
+- return ret;
+-}
+-
+-int
+ pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask)
+ {
+ int ret;
+@@ -358,8 +275,13 @@ pkg_parse_from_stream(pkg_t *pkg, FILE *
+ const size_t len = 4096;
+
+ buf = xmalloc(len);
+- ret = pkg_parse_from_stream_nomalloc(pkg, fp, mask, &buf, len);
++ ret = parse_from_stream_nomalloc(pkg_parse_line, pkg, fp, mask, &buf, len);
+ free(buf);
+
++ if (pkg->name == NULL) {
++ /* probably just a blank line */
++ ret = 1;
++ }
++
+ return ret;
+ }
+--- a/libopkg/pkg_parse.h
++++ b/libopkg/pkg_parse.h
+@@ -18,10 +18,11 @@
+ #ifndef PKG_PARSE_H
+ #define PKG_PARSE_H
+
++#include "pkg.h"
++
+ int parse_version(pkg_t *pkg, const char *raw);
+ int pkg_parse_from_stream(pkg_t *pkg, FILE *fp, uint mask);
+-int pkg_parse_from_stream_nomalloc(pkg_t *pkg, FILE *fp, uint mask,
+- char **buf0, size_t buf0len);
++int pkg_parse_line(void *ptr, const char *line, uint mask);
+
+ #define EXCESSIVE_LINE_LEN (4096 << 8)
+
+--- a/libopkg/release_parse.c
++++ b/libopkg/release_parse.c
+@@ -23,8 +23,10 @@
+ #include "parse_util.h"
+
+ static int
+-release_parse_line(release_t *release, const char *line)
++release_parse_line(void *ptr, const char *line, uint mask)
+ {
++ release_t *release = (release_t *) ptr;
++
+ int ret = 0;
+ unsigned int count = 0;
+ char **list = 0;
+@@ -111,25 +113,14 @@ dont_reset_flags:
+ int
+ release_parse_from_stream(release_t *release, FILE *fp)
+ {
+- int ret = 0;
+- char *buf = NULL;
+- size_t buflen, nread;
+-
+- nread = getline(&buf, &buflen, fp);
+- while ( nread != -1 ) {
+- if (buf[nread-1] == '\n') buf[nread-1] = '\0';
+- if (release_parse_line(release, buf))
+- opkg_msg(DEBUG, "Failed to parse release line for %s:\n\t%s\n",
+- release->name, buf);
+- nread = getline(&buf, &buflen, fp);
+- }
+-
+- if (!feof(fp)) {
+- opkg_perror(ERROR, "Problems reading Release file for %sd\n", release->name);
+- ret = -1;
+- }
++ int ret;
++ char *buf;
++ const size_t len = 4096;
+
++ buf = xmalloc(len);
++ ret = parse_from_stream_nomalloc(release_parse_line, release, fp, 0, &buf, len);
+ free(buf);
++
+ return ret;
+ }
+
diff --git a/package/system/opkg/patches/030-fix-double-free.patch b/package/system/opkg/patches/030-fix-double-free.patch
new file mode 100644
index 0000000000..312e06c548
--- /dev/null
+++ b/package/system/opkg/patches/030-fix-double-free.patch
@@ -0,0 +1,10 @@
+--- a/libopkg/opkg_remove.c
++++ b/libopkg/opkg_remove.c
+@@ -138,7 +138,6 @@ opkg_remove_dependent_pkgs(pkg_t *pkg, a
+ for (i = 0; i < dependent_pkgs->len; i++) {
+ err = opkg_remove_pkg(dependent_pkgs->pkgs[i],0);
+ if (err) {
+- pkg_vec_free(dependent_pkgs);
+ break;
+ }
+ }
diff --git a/package/system/opkg/patches/040-wrap-descriptions-only-on-ttys.patch b/package/system/opkg/patches/040-wrap-descriptions-only-on-ttys.patch
new file mode 100644
index 0000000000..95406687b6
--- /dev/null
+++ b/package/system/opkg/patches/040-wrap-descriptions-only-on-ttys.patch
@@ -0,0 +1,31 @@
+--- a/libopkg/pkg_parse.c
++++ b/libopkg/pkg_parse.c
+@@ -20,6 +20,7 @@
+
+ #include <stdio.h>
+ #include <ctype.h>
++#include <unistd.h>
+
+ #include "pkg.h"
+ #include "opkg_utils.h"
+@@ -239,10 +240,16 @@ pkg_parse_line(void *ptr, const char *li
+
+ case ' ':
+ if ((mask & PFM_DESCRIPTION) && reading_description) {
+- pkg->description = xrealloc(pkg->description,
+- strlen(pkg->description)
+- + 1 + strlen(line) + 1);
+- strcat(pkg->description, "\n");
++ if (isatty(1)) {
++ pkg->description = xrealloc(pkg->description,
++ strlen(pkg->description)
++ + 1 + strlen(line) + 1);
++ strcat(pkg->description, "\n");
++ } else {
++ pkg->description = xrealloc(pkg->description,
++ strlen(pkg->description)
++ + 1 + strlen(line));
++ }
+ strcat(pkg->description, (line));
+ goto dont_reset_flags;
+ } else if ((mask & PFM_CONFFILES) && reading_conffiles) {
diff --git a/package/system/opkg/patches/050-add-case-insensitive-flag.patch b/package/system/opkg/patches/050-add-case-insensitive-flag.patch
new file mode 100644
index 0000000000..4b9215b87a
--- /dev/null
+++ b/package/system/opkg/patches/050-add-case-insensitive-flag.patch
@@ -0,0 +1,169 @@
+--- a/libopkg/opkg_cmd.c
++++ b/libopkg/opkg_cmd.c
+@@ -436,7 +436,7 @@ opkg_configure_packages(char *pkg_name)
+ for(i = 0; i < ordered->len; i++) {
+ pkg = ordered->pkgs[i];
+
+- if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
++ if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
+ continue;
+
+ if (pkg->state_status == SS_UNPACKED) {
+@@ -610,7 +610,7 @@ opkg_list_cmd(int argc, char **argv)
+ for (i=0; i < available->len; i++) {
+ pkg = available->pkgs[i];
+ /* if we have package name or pattern and pkg does not match, then skip it */
+- if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
++ if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
+ continue;
+ print_pkg(pkg);
+ }
+@@ -637,7 +637,7 @@ opkg_list_installed_cmd(int argc, char *
+ for (i=0; i < available->len; i++) {
+ pkg = available->pkgs[i];
+ /* if we have package name or pattern and pkg does not match, then skip it */
+- if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
++ if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
+ continue;
+ print_pkg(pkg);
+ }
+@@ -666,7 +666,7 @@ opkg_list_changed_conffiles_cmd(int argc
+ for (i=0; i < available->len; i++) {
+ pkg = available->pkgs[i];
+ /* if we have package name or pattern and pkg does not match, then skip it */
+- if (pkg_name && fnmatch(pkg_name, pkg->name, 0))
++ if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
+ continue;
+ if (nv_pair_list_empty(&pkg->conffiles))
+ continue;
+@@ -722,7 +722,7 @@ opkg_info_status_cmd(int argc, char **ar
+
+ for (i=0; i < available->len; i++) {
+ pkg = available->pkgs[i];
+- if (pkg_name && fnmatch(pkg_name, pkg->name, 0)) {
++ if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase)) {
+ continue;
+ }
+
+@@ -792,7 +792,7 @@ opkg_remove_cmd(int argc, char **argv)
+ for (i=0; i<argc; i++) {
+ for (a=0; a<available->len; a++) {
+ pkg = available->pkgs[a];
+- if (fnmatch(argv[i], pkg->name, 0)) {
++ if (fnmatch(argv[i], pkg->name, conf->nocase)) {
+ continue;
+ }
+ if (conf->restrict_to_default_dest) {
+@@ -926,7 +926,7 @@ opkg_depends_cmd(int argc, char **argv)
+ for (j=0; j<available_pkgs->len; j++) {
+ pkg = available_pkgs->pkgs[j];
+
+- if (fnmatch(argv[i], pkg->name, 0) != 0)
++ if (fnmatch(argv[i], pkg->name, conf->nocase) != 0)
+ continue;
+
+ depends_count = pkg->depends_count +
+@@ -1147,9 +1147,9 @@ opkg_what_provides_replaces_cmd(enum wha
+ ((what_field_type == WHATPROVIDES)
+ ? pkg->provides[k]
+ : pkg->replaces[k]);
+- if (fnmatch(target, apkg->name, 0) == 0) {
++ if (fnmatch(target, apkg->name, conf->nocase) == 0) {
+ opkg_msg(NOTICE, " %s", pkg->name);
+- if (strcmp(target, apkg->name) != 0)
++ if ((conf->nocase ? strcasecmp(target, apkg->name) : strcmp(target, apkg->name)) != 0)
+ opkg_msg(NOTICE, "\t%s %s\n",
+ rel_str, apkg->name);
+ opkg_message(NOTICE, "\n");
+@@ -1200,7 +1200,7 @@ opkg_search_cmd(int argc, char **argv)
+
+ for (iter = str_list_first(installed_files); iter; iter = str_list_next(installed_files, iter)) {
+ installed_file = (char *)iter->data;
+- if (fnmatch(argv[0], installed_file, 0)==0)
++ if (fnmatch(argv[0], installed_file, conf->nocase)==0)
+ print_pkg(pkg);
+ }
+
+--- a/libopkg/opkg_conf.c
++++ b/libopkg/opkg_conf.c
+@@ -62,6 +62,7 @@ opkg_option_t options[] = {
+ { "noaction", OPKG_OPT_TYPE_BOOL, &_conf.noaction },
+ { "download_only", OPKG_OPT_TYPE_BOOL, &_conf.download_only },
+ { "nodeps", OPKG_OPT_TYPE_BOOL, &_conf.nodeps },
++ { "nocase", OPKG_OPT_TYPE_BOOL, &_conf.nocase },
+ { "offline_root", OPKG_OPT_TYPE_STRING, &_conf.offline_root },
+ { "overlay_root", OPKG_OPT_TYPE_STRING, &_conf.overlay_root },
+ { "proxy_passwd", OPKG_OPT_TYPE_STRING, &_conf.proxy_passwd },
+--- a/libopkg/opkg_conf.h
++++ b/libopkg/opkg_conf.h
+@@ -24,6 +24,7 @@ extern opkg_conf_t *conf;
+ #include "config.h"
+
+ #include <stdarg.h>
++#include <fnmatch.h> /* FNM_CASEFOLD */
+
+ #include "hash_table.h"
+ #include "pkg_src_list.h"
+@@ -79,6 +80,7 @@ struct opkg_conf
+ int force_remove;
+ int check_signature;
+ int nodeps; /* do not follow dependencies */
++ int nocase; /* perform case insensitive matching */
+ char *offline_root;
+ char *overlay_root;
+ int query_all;
+--- a/src/opkg-cl.c
++++ b/src/opkg-cl.c
+@@ -47,6 +47,7 @@ enum {
+ ARGS_OPT_NOACTION,
+ ARGS_OPT_DOWNLOAD_ONLY,
+ ARGS_OPT_NODEPS,
++ ARGS_OPT_NOCASE,
+ ARGS_OPT_AUTOREMOVE,
+ ARGS_OPT_CACHE,
+ };
+@@ -86,6 +87,7 @@ static struct option long_options[] = {
+ {"noaction", 0, 0, ARGS_OPT_NOACTION},
+ {"download-only", 0, 0, ARGS_OPT_DOWNLOAD_ONLY},
+ {"nodeps", 0, 0, ARGS_OPT_NODEPS},
++ {"nocase", 0, 0, ARGS_OPT_NOCASE},
+ {"offline", 1, 0, 'o'},
+ {"offline-root", 1, 0, 'o'},
+ {"add-arch", 1, 0, ARGS_OPT_ADD_ARCH},
+@@ -107,7 +109,7 @@ args_parse(int argc, char *argv[])
+ char *tuple, *targ;
+
+ while (1) {
+- c = getopt_long_only(argc, argv, "Ad:f:no:p:t:vV::",
++ c = getopt_long_only(argc, argv, "Ad:f:ino:p:t:vV::",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+@@ -122,6 +124,9 @@ args_parse(int argc, char *argv[])
+ case 'f':
+ conf->conf_file = xstrdup(optarg);
+ break;
++ case 'i':
++ conf->nocase = FNM_CASEFOLD;
++ break;
+ case 'o':
+ conf->offline_root = xstrdup(optarg);
+ break;
+@@ -176,6 +181,9 @@ args_parse(int argc, char *argv[])
+ case ARGS_OPT_NODEPS:
+ conf->nodeps = 1;
+ break;
++ case ARGS_OPT_NOCASE:
++ conf->nocase = FNM_CASEFOLD;
++ break;
+ case ARGS_OPT_ADD_ARCH:
+ case ARGS_OPT_ADD_DEST:
+ tuple = xstrdup(optarg);
+@@ -287,6 +295,7 @@ usage()
+ printf("\t--noaction No action -- test only\n");
+ printf("\t--download-only No action -- download only\n");
+ printf("\t--nodeps Do not follow dependencies\n");
++ printf("\t--nocase Perform case insensitive pattern matching\n");
+ printf("\t--force-removal-of-dependent-packages\n");
+ printf("\t Remove package and all dependencies\n");
+ printf("\t--autoremove Remove packages that were installed\n");
diff --git a/package/system/opkg/patches/060-add-find-command.patch b/package/system/opkg/patches/060-add-find-command.patch
new file mode 100644
index 0000000000..17625349f8
--- /dev/null
+++ b/package/system/opkg/patches/060-add-find-command.patch
@@ -0,0 +1,58 @@
+--- a/libopkg/opkg_cmd.c
++++ b/libopkg/opkg_cmd.c
+@@ -594,7 +594,7 @@ opkg_download_cmd(int argc, char **argv)
+
+
+ static int
+-opkg_list_cmd(int argc, char **argv)
++opkg_list_find_cmd(int argc, char **argv, int use_desc)
+ {
+ int i;
+ pkg_vec_t *available;
+@@ -610,7 +610,8 @@ opkg_list_cmd(int argc, char **argv)
+ for (i=0; i < available->len; i++) {
+ pkg = available->pkgs[i];
+ /* if we have package name or pattern and pkg does not match, then skip it */
+- if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase))
++ if (pkg_name && fnmatch(pkg_name, pkg->name, conf->nocase) &&
++ (!use_desc || !pkg->description || fnmatch(pkg_name, pkg->description, conf->nocase)))
+ continue;
+ print_pkg(pkg);
+ }
+@@ -619,6 +620,18 @@ opkg_list_cmd(int argc, char **argv)
+ return 0;
+ }
+
++static int
++opkg_list_cmd(int argc, char **argv)
++{
++ return opkg_list_find_cmd(argc, argv, 0);
++}
++
++static int
++opkg_find_cmd(int argc, char **argv)
++{
++ return opkg_list_find_cmd(argc, argv, 1);
++}
++
+
+ static int
+ opkg_list_installed_cmd(int argc, char **argv)
+@@ -1262,6 +1275,7 @@ static opkg_cmd_t cmds[] = {
+ {"configure", 0, (opkg_cmd_fun_t)opkg_configure_cmd, PFM_DESCRIPTION|PFM_SOURCE},
+ {"files", 1, (opkg_cmd_fun_t)opkg_files_cmd, PFM_DESCRIPTION|PFM_SOURCE},
+ {"search", 1, (opkg_cmd_fun_t)opkg_search_cmd, PFM_DESCRIPTION|PFM_SOURCE},
++ {"find", 1, (opkg_cmd_fun_t)opkg_find_cmd, PFM_SOURCE},
+ {"download", 1, (opkg_cmd_fun_t)opkg_download_cmd, PFM_DESCRIPTION|PFM_SOURCE},
+ {"compare_versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
+ {"compare-versions", 1, (opkg_cmd_fun_t)opkg_compare_versions_cmd, PFM_DESCRIPTION|PFM_SOURCE},
+--- a/src/opkg-cl.c
++++ b/src/opkg-cl.c
+@@ -246,6 +246,7 @@ usage()
+ printf("\tlist-changed-conffiles List user modified configuration files\n");
+ printf("\tfiles <pkg> List files belonging to <pkg>\n");
+ printf("\tsearch <file|regexp> List package providing <file>\n");
++ printf("\tfind <regexp> List packages whose name or description matches <regexp>\n");
+ printf("\tinfo [pkg|regexp] Display all info for <pkg>\n");
+ printf("\tstatus [pkg|regexp] Display all status for <pkg>\n");
+ printf("\tdownload <pkg> Download <pkg> to current directory\n");
diff --git a/package/system/opkg/patches/070-use_gzipped_pkg_list.patch b/package/system/opkg/patches/070-use_gzipped_pkg_list.patch
new file mode 100644
index 0000000000..d32b519182
--- /dev/null
+++ b/package/system/opkg/patches/070-use_gzipped_pkg_list.patch
@@ -0,0 +1,120 @@
+--- a/libopkg/opkg.c
++++ b/libopkg/opkg.c
+@@ -592,49 +592,8 @@ opkg_update_package_lists(opkg_progress_
+ src->gzip ? "Packages.gz" : "Packages");
+
+ sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
+- if (src->gzip) {
+- FILE *in, *out;
+- struct _curl_cb_data cb_data;
+- char *tmp_file_name = NULL;
+
+- sprintf_alloc(&tmp_file_name, "%s/%s.gz", tmp,
+- src->name);
+-
+- opkg_msg(INFO, "Downloading %s to %s...\n", url,
+- tmp_file_name);
+-
+- cb_data.cb = progress_callback;
+- cb_data.progress_data = &pdata;
+- cb_data.user_data = user_data;
+- cb_data.start_range =
+- 100 * sources_done / sources_list_count;
+- cb_data.finish_range =
+- 100 * (sources_done + 1) / sources_list_count;
+-
+- err = opkg_download(url, tmp_file_name,
+- (curl_progress_func) curl_progress_cb,
+- &cb_data, 0);
+-
+- if (err == 0) {
+- opkg_msg(INFO, "Inflating %s...\n",
+- tmp_file_name);
+- in = fopen(tmp_file_name, "r");
+- out = fopen(list_file_name, "w");
+- if (in && out)
+- unzip(in, out);
+- else
+- err = 1;
+- if (in)
+- fclose(in);
+- if (out)
+- fclose(out);
+- unlink(tmp_file_name);
+- }
+- free(tmp_file_name);
+- } else
+- err = opkg_download(url, list_file_name, NULL, NULL, 0);
+-
+- if (err) {
++ if (opkg_download(url, list_file_name, NULL, NULL, 0)) {
+ opkg_msg(ERROR, "Couldn't retrieve %s\n", url);
+ result = -1;
+ }
+--- a/libopkg/opkg_cmd.c
++++ b/libopkg/opkg_cmd.c
+@@ -162,30 +162,7 @@ opkg_update_cmd(int argc, char **argv)
+ sprintf_alloc(&url, "%s/%s", src->value, src->gzip ? "Packages.gz" : "Packages");
+
+ sprintf_alloc(&list_file_name, "%s/%s", lists_dir, src->name);
+- if (src->gzip) {
+- char *tmp_file_name;
+- FILE *in, *out;
+-
+- sprintf_alloc (&tmp_file_name, "%s/%s.gz", tmp, src->name);
+- err = opkg_download(url, tmp_file_name, NULL, NULL, 0);
+- if (err == 0) {
+- opkg_msg(NOTICE, "Inflating %s.\n", url);
+- in = fopen (tmp_file_name, "r");
+- out = fopen (list_file_name, "w");
+- if (in && out)
+- unzip (in, out);
+- else
+- err = 1;
+- if (in)
+- fclose (in);
+- if (out)
+- fclose (out);
+- unlink (tmp_file_name);
+- }
+- free(tmp_file_name);
+- } else
+- err = opkg_download(url, list_file_name, NULL, NULL, 0);
+- if (err) {
++ if (opkg_download(url, list_file_name, NULL, NULL, 0)) {
+ failures++;
+ } else {
+ opkg_msg(NOTICE, "Updated list of available packages in %s.\n",
+--- a/libopkg/pkg_hash.c
++++ b/libopkg/pkg_hash.c
+@@ -102,12 +102,18 @@ pkg_hash_add_from_file(const char *file_
+ pkg_src_t *src, pkg_dest_t *dest, int is_status_file)
+ {
+ pkg_t *pkg;
+- FILE *fp;
++ FILE *fp, *fp_c = NULL;
+ char *buf;
+ const size_t len = 4096;
+ int ret = 0;
++ int pid;
+
+ fp = fopen(file_name, "r");
++ if (fp && src && src->gzip) {
++ fp_c = fp;
++ fp = gz_open(fp_c, &pid);
++ }
++
+ if (fp == NULL) {
+ opkg_perror(ERROR, "Failed to open %s", file_name);
+ return -1;
+@@ -154,6 +160,10 @@ pkg_hash_add_from_file(const char *file_
+
+ free(buf);
+ fclose(fp);
++ if (fp_c) {
++ fclose(fp_c);
++ gz_close(pid);
++ }
+
+ return ret;
+ }