Revert "opkg: vfork external gzip command to uncompress data"
authorStijn Tintel <stijn@linux-ipv6.be>
Tue, 27 Dec 2016 03:41:30 +0000 (04:41 +0100)
committerStijn Tintel <stijn@linux-ipv6.be>
Tue, 27 Dec 2016 03:41:30 +0000 (04:41 +0100)
This reverts commit 0090adcd5c94adad2168cd9b338f45827533c81d.
It breaks reading package list in /tmp/opkg-lists, making it impossible
to install packages from feeds in snapshots.

package/system/opkg/Makefile
package/system/opkg/patches/070-use_external_gzip.patch [deleted file]
package/system/opkg/patches/070-use_gzipped_pkg_list.patch [new file with mode: 0644]
package/system/opkg/patches/071-use_gzipped_pkg_list.patch [deleted file]
package/system/opkg/patches/220-drop-release-support.patch

index cbd731f..8b8904a 100644 (file)
@@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/version.mk
 include $(INCLUDE_DIR)/feeds.mk
 
 PKG_NAME:=opkg
-PKG_RELEASE:=16
+PKG_RELEASE:=15
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=http://git.yoctoproject.org/git/opkg
diff --git a/package/system/opkg/patches/070-use_external_gzip.patch b/package/system/opkg/patches/070-use_external_gzip.patch
deleted file mode 100644 (file)
index b3e70e4..0000000
+++ /dev/null
@@ -1,719 +0,0 @@
---- a/libbb/unarchive.c
-+++ b/libbb/unarchive.c
-@@ -28,6 +28,7 @@
- #include <libgen.h>
- #include "libbb.h"
-+#include "gzip.h"
- #define CONFIG_FEATURE_TAR_OLDGNU_COMPATABILITY 1
- #define CONFIG_FEATURE_TAR_GNU_EXTENSIONS
-@@ -39,38 +40,15 @@ static char *linkname = NULL;
- off_t archive_offset;
--#define SEEK_BUF 4096
- static ssize_t
--seek_by_read(FILE* fd, size_t len)
--{
--        ssize_t cc, total = 0;
--        char buf[SEEK_BUF];
--
--        while (len) {
--                cc = fread(buf, sizeof(buf[0]),
--                                len > SEEK_BUF ? SEEK_BUF : len,
--                                fd);
--
--                total += cc;
--                len -= cc;
--
--                if(feof(fd) || ferror(fd))
--                        break;
--        }
--        return total;
--}
--
--static void
--seek_sub_file(FILE *fd, const int count)
-+seek_forward(struct gzip_handle *zh, ssize_t len)
- {
--      archive_offset += count;
-+      ssize_t slen = gzip_seek(zh, len);
--      /* Do not use fseek() on a pipe. It may fail with ESPIPE, leaving the
--       * stream at an undefined location.
--       */
--        seek_by_read(fd, count);
-+      if (slen == len)
-+              archive_offset += len;
--      return;
-+      return slen;
- }
-@@ -87,7 +65,7 @@ seek_sub_file(FILE *fd, const int count)
-  * trailing '/' or else the last dir will be assumed to be the file prefix
-  */
- static char *
--extract_archive(FILE *src_stream, FILE *out_stream,
-+extract_archive(struct gzip_handle *src_stream, FILE *out_stream,
-               const file_header_t *file_entry, const int function,
-               const char *prefix,
-               int *err)
-@@ -129,14 +107,14 @@ extract_archive(FILE *src_stream, FILE *
-       if (function & extract_to_stream) {
-               if (S_ISREG(file_entry->mode)) {
--                      *err = copy_file_chunk(src_stream, out_stream, file_entry->size);
-+                      *err = gzip_copy(src_stream, out_stream, file_entry->size);
-                       archive_offset += file_entry->size;
-               }
-       }
-       else if (function & extract_one_to_buffer) {
-               if (S_ISREG(file_entry->mode)) {
-                       buffer = (char *) xmalloc(file_entry->size + 1);
--                      fread(buffer, 1, file_entry->size, src_stream);
-+                      gzip_read(src_stream, buffer, file_entry->size);
-                       buffer[file_entry->size] = '\0';
-                       archive_offset += file_entry->size;
-                       goto cleanup;
-@@ -156,7 +134,7 @@ extract_archive(FILE *src_stream, FILE *
-                                       *err = -1;
-                                       error_msg("%s not created: newer or same age file exists", file_entry->name);
-                               }
--                              seek_sub_file(src_stream, file_entry->size);
-+                              seek_forward(src_stream, file_entry->size);
-                               goto cleanup;
-                       }
-               }
-@@ -185,11 +163,11 @@ extract_archive(FILE *src_stream, FILE *
-                               } else {
-                                       if ((dst_stream = wfopen(full_name, "w")) == NULL) {
-                                               *err = -1;
--                                              seek_sub_file(src_stream, file_entry->size);
-+                                              seek_forward(src_stream, file_entry->size);
-                                               goto cleanup;
-                                       }
-                                       archive_offset += file_entry->size;
--                                      *err = copy_file_chunk(src_stream, dst_stream, file_entry->size);
-+                                      *err = gzip_copy(src_stream, dst_stream, file_entry->size);
-                                       fclose(dst_stream);
-                               }
-                               break;
-@@ -250,7 +228,7 @@ extract_archive(FILE *src_stream, FILE *
-               /* If we arent extracting data we have to skip it,
-                * if data size is 0 then then just do it anyway
-                * (saves testing for it) */
--              seek_sub_file(src_stream, file_entry->size);
-+              seek_forward(src_stream, file_entry->size);
-       }
-       /* extract_list and extract_verbose_list can be used in conjunction
-@@ -274,8 +252,8 @@ cleanup:
- }
- static char *
--unarchive(FILE *src_stream, FILE *out_stream,
--              file_header_t *(*get_headers)(FILE *),
-+unarchive(struct gzip_handle *src_stream, FILE *out_stream,
-+              file_header_t *(*get_headers)(struct gzip_handle *),
-               void (*free_headers)(file_header_t *),
-               const int extract_function,
-               const char *prefix,
-@@ -329,7 +307,7 @@ unarchive(FILE *src_stream, FILE *out_st
-                       }
-               } else {
-                       /* seek past the data entry */
--                      seek_sub_file(src_stream, file_entry->size);
-+                      seek_forward(src_stream, file_entry->size);
-               }
-               free_headers(file_entry);
-       }
-@@ -337,108 +315,9 @@ unarchive(FILE *src_stream, FILE *out_st
-       return buffer;
- }
--static file_header_t *
--get_header_ar(FILE *src_stream)
--{
--      file_header_t *typed;
--      union {
--              char raw[60];
--              struct {
--                      char name[16];
--                      char date[12];
--                      char uid[6];
--                      char gid[6];
--                      char mode[8];
--                      char size[10];
--                      char magic[2];
--              } formated;
--      } ar;
--      static char *ar_long_names;
--
--      if (fread(ar.raw, 1, 60, src_stream) != 60) {
--              return(NULL);
--      }
--      archive_offset += 60;
--      /* align the headers based on the header magic */
--      if ((ar.formated.magic[0] != '`') || (ar.formated.magic[1] != '\n')) {
--              /* some version of ar, have an extra '\n' after each data entry,
--               * this puts the next header out by 1 */
--              if (ar.formated.magic[1] != '`') {
--                      error_msg("Invalid magic");
--                      return(NULL);
--              }
--              /* read the next char out of what would be the data section,
--               * if its a '\n' then it is a valid header offset by 1*/
--              archive_offset++;
--              if (fgetc(src_stream) != '\n') {
--                      error_msg("Invalid magic");
--                      return(NULL);
--              }
--              /* fix up the header, we started reading 1 byte too early */
--              /* raw_header[60] wont be '\n' as it should, but it doesnt matter */
--              memmove(ar.raw, &ar.raw[1], 59);
--      }
--
--      typed = (file_header_t *) xcalloc(1, sizeof(file_header_t));
--
--      typed->size = (size_t) atoi(ar.formated.size);
--      /* long filenames have '/' as the first character */
--      if (ar.formated.name[0] == '/') {
--              if (ar.formated.name[1] == '/') {
--                      /* If the second char is a '/' then this entries data section
--                       * stores long filename for multiple entries, they are stored
--                       * in static variable long_names for use in future entries */
--                      ar_long_names = (char *) xrealloc(ar_long_names, typed->size);
--                      fread(ar_long_names, 1, typed->size, src_stream);
--                      archive_offset += typed->size;
--                      /* This ar entries data section only contained filenames for other records
--                       * they are stored in the static ar_long_names for future reference */
--                      return (get_header_ar(src_stream)); /* Return next header */
--              } else if (ar.formated.name[1] == ' ') {
--                      /* This is the index of symbols in the file for compilers */
--                      seek_sub_file(src_stream, typed->size);
--                      return (get_header_ar(src_stream)); /* Return next header */
--              } else {
--                      /* The number after the '/' indicates the offset in the ar data section
--                      (saved in variable long_name) that conatains the real filename */
--                      if (!ar_long_names) {
--                              error_msg("Cannot resolve long file name");
--                              return (NULL);
--                      }
--                      typed->name = xstrdup(ar_long_names + atoi(&ar.formated.name[1]));
--              }
--      } else {
--              /* short filenames */
--              typed->name = xcalloc(1, 16);
--              strncpy(typed->name, ar.formated.name, 16);
--      }
--      typed->name[strcspn(typed->name, " /")]='\0';
--
--      /* convert the rest of the now valid char header to its typed struct */
--      parse_mode(ar.formated.mode, &typed->mode);
--      typed->mtime = atoi(ar.formated.date);
--      typed->uid = atoi(ar.formated.uid);
--      typed->gid = atoi(ar.formated.gid);
--
--      return(typed);
--}
--
--static void
--free_header_ar(file_header_t *ar_entry)
--{
--      if (ar_entry == NULL)
--              return;
--
--      free(ar_entry->name);
--      if (ar_entry->link_name)
--              free(ar_entry->link_name);
--
--      free(ar_entry);
--}
--
- static file_header_t *
--get_header_tar(FILE *tar_stream)
-+get_header_tar(struct gzip_handle *tar_stream)
- {
-       union {
-               unsigned char raw[512];
-@@ -467,10 +346,10 @@ get_header_tar(FILE *tar_stream)
-       long sum = 0;
-       if (archive_offset % 512 != 0) {
--              seek_sub_file(tar_stream, 512 - (archive_offset % 512));
-+              seek_forward(tar_stream, 512 - (archive_offset % 512));
-       }
--      if (fread(tar.raw, 1, 512, tar_stream) != 512) {
-+      if (gzip_read(tar_stream, tar.raw, 512) != 512) {
-               /* Unfortunately its common for tar files to have all sorts of
-                * trailing garbage, fail silently */
- //            error_msg("Couldnt read header");
-@@ -557,7 +436,7 @@ get_header_tar(FILE *tar_stream)
- # ifdef CONFIG_FEATURE_TAR_GNU_EXTENSIONS
-       case 'L': {
-                       longname = xmalloc(tar_entry->size + 1);
--                        if(fread(longname, tar_entry->size, 1, tar_stream) != 1)
-+                        if(gzip_read(tar_stream, longname, tar_entry->size) != tar_entry->size)
-                                 return NULL;
-                       longname[tar_entry->size] = '\0';
-                       archive_offset += tar_entry->size;
-@@ -566,7 +445,7 @@ get_header_tar(FILE *tar_stream)
-               }
-       case 'K': {
-                       linkname = xmalloc(tar_entry->size + 1);
--                        if(fread(linkname, tar_entry->size, 1, tar_stream) != 1)
-+                        if(gzip_read(tar_stream, linkname, tar_entry->size) != tar_entry->size)
-                                 return NULL;
-                       linkname[tar_entry->size] = '\0';
-                       archive_offset += tar_entry->size;
-@@ -642,6 +521,9 @@ deb_extract(const char *package_filename
-       char *ared_file = NULL;
-       char ar_magic[8];
-       int gz_err;
-+      struct gzip_handle tar_outer, tar_inner;
-+      file_header_t *tar_header;
-+      ssize_t len;
-       *err = 0;
-@@ -672,111 +554,44 @@ deb_extract(const char *package_filename
-       /* set the buffer size */
-       setvbuf(deb_stream, NULL, _IOFBF, 0x8000);
--      /* check ar magic */
--      fread(ar_magic, 1, 8, deb_stream);
--
--      if (strncmp(ar_magic,"!<arch>",7) == 0) {
--              archive_offset = 8;
-+      memset(&tar_outer, 0, sizeof(tar_outer));
-+      tar_outer.file = deb_stream;
-+      gzip_exec(&tar_outer, NULL);
--              while ((ar_header = get_header_ar(deb_stream)) != NULL) {
--                      if (strcmp(ared_file, ar_header->name) == 0) {
--                              int gunzip_pid = 0;
--                              FILE *uncompressed_stream;
--                              /* open a stream of decompressed data */
--                              uncompressed_stream = gz_open(deb_stream, &gunzip_pid);
--                              if (uncompressed_stream == NULL) {
--                                      *err = -1;
--                                      goto cleanup;
--                              }
-+      /* walk through outer tar file to find ared_file */
-+      while ((tar_header = get_header_tar(&tar_outer)) != NULL) {
-+                    int name_offset = 0;
-+                    if (strncmp(tar_header->name, "./", 2) == 0)
-+                            name_offset = 2;
--                              archive_offset = 0;
--                              output_buffer = unarchive(uncompressed_stream,
--                                              out_stream, get_header_tar,
--                                              free_header_tar,
--                                              extract_function, prefix,
--                                              file_list, err);
--                              fclose(uncompressed_stream);
--                              gz_err = gz_close(gunzip_pid);
--                              if (gz_err)
--                                      *err = -1;
--                              free_header_ar(ar_header);
--                              break;
--                      }
--                      if (fseek(deb_stream, ar_header->size, SEEK_CUR) == -1) {
--                              opkg_perror(ERROR, "Couldn't fseek into %s", package_filename);
--                              *err = -1;
--                              free_header_ar(ar_header);
--                              goto cleanup;
--                      }
--                      free_header_ar(ar_header);
--              }
--              goto cleanup;
--      } else if (strncmp(ar_magic, "\037\213", 2) == 0) {
--              /* it's a gz file, let's assume it's an opkg */
--              int unzipped_opkg_pid;
--              FILE *unzipped_opkg_stream;
--              file_header_t *tar_header;
--              archive_offset = 0;
--              if (fseek(deb_stream, 0, SEEK_SET) == -1) {
--                      opkg_perror(ERROR, "Couldn't fseek into %s", package_filename);
--                      *err = -1;
--                      goto cleanup;
--              }
--              unzipped_opkg_stream = gz_open(deb_stream, &unzipped_opkg_pid);
--              if (unzipped_opkg_stream == NULL) {
--                      *err = -1;
--                      goto cleanup;
--              }
-+              if (strcmp(ared_file, tar_header->name+name_offset) == 0) {
-+                      memset(&tar_inner, 0, sizeof(tar_inner));
-+                      tar_inner.gzip = &tar_outer;
-+                      gzip_exec(&tar_inner, NULL);
--              /* walk through outer tar file to find ared_file */
--              while ((tar_header = get_header_tar(unzipped_opkg_stream)) != NULL) {
--                        int name_offset = 0;
--                        if (strncmp(tar_header->name, "./", 2) == 0)
--                                name_offset = 2;
--                      if (strcmp(ared_file, tar_header->name+name_offset) == 0) {
--                              int gunzip_pid = 0;
--                              FILE *uncompressed_stream;
--                              /* open a stream of decompressed data */
--                              uncompressed_stream = gz_open(unzipped_opkg_stream, &gunzip_pid);
--                              if (uncompressed_stream == NULL) {
--                                      *err = -1;
--                                      goto cleanup;
--                              }
--                              archive_offset = 0;
-+                      archive_offset = 0;
--                              output_buffer = unarchive(uncompressed_stream,
--                                                        out_stream,
--                                                        get_header_tar,
--                                                        free_header_tar,
--                                                        extract_function,
--                                                        prefix,
--                                                        file_list,
--                                                        err);
-+                      output_buffer = unarchive(&tar_inner,
-+                                                out_stream,
-+                                                get_header_tar,
-+                                                free_header_tar,
-+                                                extract_function,
-+                                                prefix,
-+                                                file_list,
-+                                                err);
--                              free_header_tar(tar_header);
--                              fclose(uncompressed_stream);
--                              gz_err = gz_close(gunzip_pid);
--                              if (gz_err)
--                                      *err = -1;
--                              break;
--                      }
--                      seek_sub_file(unzipped_opkg_stream, tar_header->size);
-                       free_header_tar(tar_header);
-+                      gzip_close(&tar_inner);
-+                      break;
-               }
--              fclose(unzipped_opkg_stream);
--              gz_err = gz_close(unzipped_opkg_pid);
--              if (gz_err)
--                      *err = -1;
--              goto cleanup;
--      } else {
--              *err = -1;
--              error_msg("%s: invalid magic", package_filename);
-+              seek_forward(&tar_outer, tar_header->size);
-+              free_header_tar(tar_header);
-       }
- cleanup:
--      if (deb_stream)
--              fclose(deb_stream);
-+      gzip_close(&tar_outer);
-+
-       if (file_list)
-               free(file_list);
---- /dev/null
-+++ b/libbb/gzip.h
-@@ -0,0 +1,41 @@
-+/*
-+ *  Copyright (C) 2016 Jo-Philipp Wich <jo@mein.io>
-+ *
-+ *  Zlib decrompression utility routines.
-+ *
-+ *  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 Library 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.
-+ */
-+
-+#include <stdio.h>
-+#include <signal.h>
-+#include <pthread.h>
-+
-+struct gzip_handle {
-+      FILE *file;
-+      struct gzip_handle *gzip;
-+
-+      pid_t pid;
-+      int rfd, wfd;
-+      struct sigaction pipe_sa;
-+      pthread_t thread;
-+};
-+
-+int gzip_exec(struct gzip_handle *zh, const char *filename);
-+ssize_t gzip_read(struct gzip_handle *zh, char *buf, ssize_t len);
-+ssize_t gzip_copy(struct gzip_handle *zh, FILE *out, ssize_t len);
-+int gzip_close(struct gzip_handle *zh);
-+FILE *gzip_fdopen(struct gzip_handle *zh, const char *filename);
-+
-+#define gzip_seek(zh, len) gzip_copy(zh, NULL, len)
---- a/libbb/Makefile.am
-+++ b/libbb/Makefile.am
-@@ -4,9 +4,8 @@ ALL_CFLAGS=-g -O -Wall -DHOST_CPU_STR=\"
- noinst_LIBRARIES = libbb.a
--libbb_a_SOURCES = gz_open.c \
-+libbb_a_SOURCES = \
-       libbb.h \
--      unzip.c \
-       wfopen.c \
-       unarchive.c \
-       copy_file.c \
-@@ -20,7 +19,8 @@ libbb_a_SOURCES = gz_open.c \
-       parse_mode.c \
-       time_string.c \
-       all_read.c \
--      mode_string.c
-+      mode_string.c \
-+      gzip.c
- libbb_la_CFLAGS = $(ALL_CFLAGS)
- #libbb_la_LDFLAGS = -static
---- /dev/null
-+++ b/libbb/gzip.c
-@@ -0,0 +1,208 @@
-+/*
-+ *  Copyright (C) 2016 Jo-Philipp Wich <jo@mein.io>
-+ *  Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
-+ *
-+ *  Zlib decrompression utility routines.
-+ *
-+ *  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 Library 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.
-+ */
-+
-+#include <string.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <poll.h>
-+#include <stdlib.h>
-+#include <sys/stat.h>
-+#include <sys/wait.h>
-+
-+#include "gzip.h"
-+
-+static void
-+to_devnull(int fd)
-+{
-+      int devnull = open("/dev/null", fd ? O_WRONLY : O_RDONLY);
-+
-+      if (devnull >= 0)
-+              dup2(devnull, fd);
-+
-+      if (devnull > STDERR_FILENO)
-+              close(devnull);
-+}
-+
-+void *
-+gzip_thread(void *ptr)
-+{
-+      struct gzip_handle *zh = ptr;
-+      char buf[4096];
-+      int len, ret;
-+
-+      while (1) {
-+              if (zh->file)
-+                      len = fread(buf, 1, sizeof(buf), zh->file);
-+              else if (zh->gzip)
-+                      len = gzip_read(zh->gzip, buf, sizeof(buf));
-+
-+              if (len <= 0)
-+                      break;
-+
-+              do {
-+                      ret = write(zh->wfd, buf, len);
-+              } while (ret == -1 && errno == EINTR);
-+      }
-+
-+      close(zh->wfd);
-+      zh->wfd = -1;
-+}
-+
-+int
-+gzip_exec(struct gzip_handle *zh, const char *filename)
-+{
-+      int rpipe[2] = { -1, -1 }, wpipe[2] = { -1, -1 };
-+      struct sigaction pipe_sa = { .sa_handler = SIG_IGN };
-+
-+      zh->rfd = -1;
-+      zh->wfd = -1;
-+
-+      if (sigaction(SIGPIPE, &pipe_sa, &zh->pipe_sa) < 0)
-+              return -1;
-+
-+      if (pipe(rpipe) < 0)
-+              return -1;
-+
-+      if (!filename && pipe(wpipe) < 0) {
-+              close(rpipe[0]);
-+              close(rpipe[1]);
-+              return -1;
-+      }
-+
-+      zh->pid = vfork();
-+
-+      switch (zh->pid) {
-+              case -1:
-+                      return -1;
-+
-+              case 0:
-+                      to_devnull(STDERR_FILENO);
-+
-+                      if (filename) {
-+                              to_devnull(STDIN_FILENO);
-+                      }
-+                      else {
-+                              dup2(wpipe[0], STDIN_FILENO);
-+                              close(wpipe[0]);
-+                              close(wpipe[1]);
-+                      }
-+
-+                      dup2(rpipe[1], STDOUT_FILENO);
-+                      close(rpipe[0]);
-+                      close(rpipe[1]);
-+
-+                      execlp("gzip", "gzip", "-d", filename ? filename : "-c", NULL);
-+                      exit(-1);
-+
-+              default:
-+                      zh->rfd = rpipe[0];
-+                      zh->wfd = wpipe[1];
-+
-+                      fcntl(zh->rfd, F_SETFD, fcntl(zh->rfd, F_GETFD) | FD_CLOEXEC);
-+                      close(rpipe[1]);
-+
-+                      if (zh->wfd >= 0) {
-+                              fcntl(zh->wfd, F_SETFD, fcntl(zh->wfd, F_GETFD) | FD_CLOEXEC);
-+                              close(wpipe[0]);
-+                              pthread_create(&zh->thread, NULL, gzip_thread, zh);
-+                      }
-+      }
-+
-+      return 0;
-+}
-+
-+ssize_t
-+gzip_read(struct gzip_handle *zh, char *buf, ssize_t len)
-+{
-+      ssize_t ret;
-+
-+      do {
-+              ret = read(zh->rfd, buf, len);
-+      } while (ret == -1 && errno != EINTR);
-+
-+      return ret;
-+}
-+
-+ssize_t
-+gzip_copy(struct gzip_handle *zh, FILE *out, ssize_t len)
-+{
-+      char buf[4096];
-+      ssize_t rlen, total = 0;
-+
-+      while (len > 0) {
-+              rlen = gzip_read(zh, buf,
-+                                  (len > sizeof(buf)) ? sizeof(buf) : len);
-+
-+              if (rlen <= 0)
-+                      break;
-+
-+              if (out != NULL) {
-+                      if (fwrite(buf, 1, rlen, out) != rlen)
-+                              break;
-+              }
-+
-+              len -= rlen;
-+              total += rlen;
-+      }
-+
-+      return total;
-+}
-+
-+FILE *
-+gzip_fdopen(struct gzip_handle *zh, const char *filename)
-+{
-+      memset(zh, 0, sizeof(*zh));
-+
-+      if (!filename || gzip_exec(zh, filename) < 0)
-+              return NULL;
-+
-+      fcntl(zh->rfd, F_SETFL, fcntl(zh->rfd, F_GETFL) & ~O_NONBLOCK);
-+
-+      return fdopen(zh->rfd, "r");
-+}
-+
-+int
-+gzip_close(struct gzip_handle *zh)
-+{
-+      int code = -1;
-+
-+      if (zh->rfd >= 0)
-+              close(zh->rfd);
-+
-+      if (zh->wfd >= 0)
-+              close(zh->wfd);
-+
-+      if (zh->pid > 0) {
-+              kill(zh->pid, SIGKILL);
-+              waitpid(zh->pid, &code, 0);
-+      }
-+
-+      if (zh->file)
-+              fclose(zh->file);
-+
-+      if (zh->thread)
-+              pthread_join(zh->thread, NULL);
-+
-+      sigaction(SIGPIPE, &zh->pipe_sa, NULL);
-+
-+      return WIFEXITED(code) ? WEXITSTATUS(code) : -1;
-+}
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -3,4 +3,4 @@ bin_PROGRAMS = opkg-cl
- opkg_cl_SOURCES = opkg-cl.c
- opkg_cl_LDADD = $(top_builddir)/libopkg/libopkg.a \
--                $(top_builddir)/libbb/libbb.a $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS) $(PATHFINDER_LIBS)
-+                $(top_builddir)/libbb/libbb.a $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS) $(PATHFINDER_LIBS) -lpthread
---- a/tests/Makefile.am
-+++ b/tests/Makefile.am
-@@ -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.a $(top_builddir)/libbb/libbb.a $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS) $(PATHFINDER_LIBS)
-+libopkg_test_LDADD = $(top_builddir)/libopkg/libopkg.a $(top_builddir)/libbb/libbb.a $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS) $(PATHFINDER_LIBS) -lpthread
- libopkg_test_SOURCE = libopkg_test.c
- libopkg_test_LDFLAGS = -static
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 (file)
index 0000000..d32b519
--- /dev/null
@@ -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;
+ }
diff --git a/package/system/opkg/patches/071-use_gzipped_pkg_list.patch b/package/system/opkg/patches/071-use_gzipped_pkg_list.patch
deleted file mode 100644 (file)
index e102868..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
---- 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
-@@ -29,6 +29,7 @@
- #include "sprintf_alloc.h"
- #include "file_util.h"
- #include "libbb/libbb.h"
-+#include "libbb/gzip.h"
- void
- pkg_hash_init(void)
-@@ -106,8 +107,15 @@ pkg_hash_add_from_file(const char *file_
-       char *buf;
-       const size_t len = 4096;
-       int ret = 0;
-+      struct gzip_handle zh;
-+
-+      if (src && src->gzip) {
-+              fp = gzip_fdopen(&zh, file_name);
-+      }
-+      else {
-+              fp = fopen(file_name, "r");
-+      }
--      fp = fopen(file_name, "r");
-       if (fp == NULL) {
-               opkg_perror(ERROR, "Failed to open %s", file_name);
-               return -1;
-@@ -155,6 +163,9 @@ pkg_hash_add_from_file(const char *file_
-       free(buf);
-       fclose(fp);
-+      if (src && src->gzip)
-+              gzip_close(&zh);
-+
-       return ret;
- }
index b674e33..131c2cb 100644 (file)
  #include "pkg.h"
  #include "opkg_message.h"
  #include "pkg_vec.h"
-@@ -184,40 +183,6 @@ pkg_hash_load_feeds(void)
+@@ -183,40 +182,6 @@ pkg_hash_load_feeds(void)
        lists_dir = conf->restrict_to_default_dest ?
                conf->default_dest->lists_dir : conf->lists_dir;