summaryrefslogtreecommitdiff
path: root/pkgtools
diff options
context:
space:
mode:
authorjoerg <joerg@pkgsrc.org>2010-04-14 18:24:58 +0000
committerjoerg <joerg@pkgsrc.org>2010-04-14 18:24:58 +0000
commit0447709a57d8dc1616b2ff998ad27c64ead6906b (patch)
treef15fffc4b32aedcf2f3552c212993aacadb7a846 /pkgtools
parent6891d402e90bfcbfd323f50e310eadf81577975d (diff)
downloadpkgsrc-0447709a57d8dc1616b2ff998ad27c64ead6906b.tar.gz
pkg_install-20100405:
- Try to detect common forms of pkgdb corruption and issue a warning in that case. - Refactor the pkg_vulnerabilities logic to use the compression support from libarchive. This reduces the amount zlib/bzip2 interaction to the linkage.
Diffstat (limited to 'pkgtools')
-rw-r--r--pkgtools/pkg_install/Makefile9
-rw-r--r--pkgtools/pkg_install/files/add/perform.c6
-rw-r--r--pkgtools/pkg_install/files/admin/audit.c22
-rw-r--r--pkgtools/pkg_install/files/lib/Makefile.in4
-rw-r--r--pkgtools/pkg_install/files/lib/decompress.c186
-rw-r--r--pkgtools/pkg_install/files/lib/lib.h11
-rw-r--r--pkgtools/pkg_install/files/lib/pkgdb.c20
-rw-r--r--pkgtools/pkg_install/files/lib/version.h4
-rw-r--r--pkgtools/pkg_install/files/lib/vulnerabilities-file.c123
9 files changed, 126 insertions, 259 deletions
diff --git a/pkgtools/pkg_install/Makefile b/pkgtools/pkg_install/Makefile
index f854d2bb1ad..e104062de04 100644
--- a/pkgtools/pkg_install/Makefile
+++ b/pkgtools/pkg_install/Makefile
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.176 2010/03/26 17:04:45 joerg Exp $
+# $NetBSD: Makefile,v 1.177 2010/04/14 18:24:58 joerg Exp $
# Notes to package maintainers:
#
@@ -83,11 +83,8 @@ MESSAGE_SUBST+= PKGVULNDIR=${PKG_DBDIR:Q} \
VERSION!= ${AWK} '/PKGTOOLS_VERSION/ {print $$3}' \
${FILESDIR}/lib/version.h
-# linkresolver interface appeared in libarchive 2.5 and extract
-# requires version 2.5.4b to handle hardlinks correctly.
-BUILDLINK_API_DEPENDS.libarchive+= libarchive>=2.5.4b
-# Depends on gzip handling of zlib
-BUILDLINK_API_DEPENDS.zlib+= zlib>=1.2
+# raw format appeared in libarchive 2.8.
+BUILDLINK_API_DEPENDS.libarchive+= libarchive>=2.8.0
.include "../../archivers/bzip2/builtin.mk"
.include "../../archivers/libarchive/builtin.mk"
diff --git a/pkgtools/pkg_install/files/add/perform.c b/pkgtools/pkg_install/files/add/perform.c
index bbd379ba889..081b6d3f48f 100644
--- a/pkgtools/pkg_install/files/add/perform.c
+++ b/pkgtools/pkg_install/files/add/perform.c
@@ -1,4 +1,4 @@
-/* $NetBSD: perform.c,v 1.95 2010/02/20 04:40:03 joerg Exp $ */
+/* $NetBSD: perform.c,v 1.96 2010/04/14 18:24:58 joerg Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
#endif
@@ -6,7 +6,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: perform.c,v 1.95 2010/02/20 04:40:03 joerg Exp $");
+__RCSID("$NetBSD: perform.c,v 1.96 2010/04/14 18:24:58 joerg Exp $");
/*-
* Copyright (c) 2003 Grant Beattie <grant@NetBSD.org>
@@ -1280,7 +1280,7 @@ check_vulnerable(struct pkg_task *pkg)
}
if (pv == NULL) {
- pv = read_pkg_vulnerabilities(pkg_vulnerabilities_file,
+ pv = read_pkg_vulnerabilities_file(pkg_vulnerabilities_file,
require_check, 0);
if (pv == NULL)
return require_check;
diff --git a/pkgtools/pkg_install/files/admin/audit.c b/pkgtools/pkg_install/files/admin/audit.c
index 2d7c9332cef..c23ed42064c 100644
--- a/pkgtools/pkg_install/files/admin/audit.c
+++ b/pkgtools/pkg_install/files/admin/audit.c
@@ -1,4 +1,4 @@
-/* $NetBSD: audit.c,v 1.14 2009/08/02 17:56:44 joerg Exp $ */
+/* $NetBSD: audit.c,v 1.15 2010/04/14 18:24:58 joerg Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
@@ -7,7 +7,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: audit.c,v 1.14 2009/08/02 17:56:44 joerg Exp $");
+__RCSID("$NetBSD: audit.c,v 1.15 2010/04/14 18:24:58 joerg Exp $");
/*-
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
@@ -209,7 +209,7 @@ check_and_read_pkg_vulnerabilities(void)
(long)(now / 86400), now / 86400 == 1 ? "" : "s");
}
- pv = read_pkg_vulnerabilities(pkg_vulnerabilities_file, 0, check_signature);
+ pv = read_pkg_vulnerabilities_file(pkg_vulnerabilities_file, 0, check_signature);
}
void
@@ -282,7 +282,7 @@ check_pkg_vulnerabilities(int argc, char **argv)
if (argc != optind + 1)
usage();
- pv = read_pkg_vulnerabilities(argv[optind], 0, check_signature);
+ pv = read_pkg_vulnerabilities_file(argv[optind], 0, check_signature);
free_pkg_vulnerabilities(pv);
}
@@ -290,8 +290,8 @@ void
fetch_pkg_vulnerabilities(int argc, char **argv)
{
struct pkg_vulnerabilities *pv_check;
- char *buf, *decompressed_input;
- size_t buf_len, buf_fetched, decompressed_len;
+ char *buf;
+ size_t buf_len, buf_fetched;
ssize_t cur_fetched;
struct url *url;
struct url_stat st;
@@ -363,15 +363,7 @@ fetch_pkg_vulnerabilities(int argc, char **argv)
buf[buf_len] = '\0';
- if (decompress_buffer(buf, buf_len, &decompressed_input,
- &decompressed_len)) {
- pv_check = parse_pkg_vulnerabilities(decompressed_input,
- decompressed_len, check_signature);
- free(decompressed_input);
- } else {
- pv_check = parse_pkg_vulnerabilities(buf, buf_len,
- check_signature);
- }
+ pv_check = read_pkg_vulnerabilities_memory(buf, buf_len, check_signature);
free_pkg_vulnerabilities(pv_check);
fd = open(pkg_vulnerabilities_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
diff --git a/pkgtools/pkg_install/files/lib/Makefile.in b/pkgtools/pkg_install/files/lib/Makefile.in
index c8b4e7ff69c..fcedbb67f02 100644
--- a/pkgtools/pkg_install/files/lib/Makefile.in
+++ b/pkgtools/pkg_install/files/lib/Makefile.in
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.in,v 1.28 2010/01/22 13:30:42 joerg Exp $
+# $NetBSD: Makefile.in,v 1.29 2010/04/14 18:24:58 joerg Exp $
srcdir= @srcdir@
@@ -26,7 +26,7 @@ INSTALL= @INSTALL@
LIB= libinstall.a
-OBJS= automatic.o conflicts.o decompress.o dewey.o fexec.o file.o \
+OBJS= automatic.o conflicts.o dewey.o fexec.o file.o \
gpgsig.o global.o iterate.o license.o lpkg.o opattern.o \
parse-config.o pkgdb.o plist.o remove.o \
str.o var.o version.o vulnerabilities-file.o xwrapper.o
diff --git a/pkgtools/pkg_install/files/lib/decompress.c b/pkgtools/pkg_install/files/lib/decompress.c
deleted file mode 100644
index 31500f2580d..00000000000
--- a/pkgtools/pkg_install/files/lib/decompress.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* $NetBSD: decompress.c,v 1.3 2009/08/02 17:56:45 joerg Exp $ */
-
-/*-
- * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <nbcompat.h>
-
-#if HAVE_SYS_CDEFS_H
-#include <sys/cdefs.h>
-#endif
-
-__RCSID("$NetBSD: decompress.c,v 1.3 2009/08/02 17:56:45 joerg Exp $");
-
-#ifdef BOOTSTRAP
-#include "lib.h"
-
-int
-decompress_buffer(const char *input, size_t input_len, char **output,
- size_t *output_len)
-{
- return 0;
-}
-
-#else
-
-#include <bzlib.h>
-#if HAVE_ERR_H
-#include <err.h>
-#endif
-#include <limits.h>
-#include <stdlib.h>
-#include <zlib.h>
-
-#include "lib.h"
-
-static void
-decompress_bzip2(const char *in, size_t in_len, char **out, size_t *out_len)
-{
- bz_stream stream;
- size_t output_produced;
-
- if (in_len < SSIZE_MAX / 10)
- *out_len = in_len * 10;
- else
- *out_len = in_len;
- *out = xmalloc(*out_len + 1);
-
- stream.next_in = __UNCONST(in);
- stream.avail_in = in_len;
- stream.next_out = *out;
- stream.avail_out = *out_len;
- output_produced = 0;
- stream.bzalloc = NULL;
- stream.bzfree = NULL;
- stream.opaque = NULL;
-
- if (BZ2_bzDecompressInit(&stream, 0, 0) != BZ_OK)
- errx(EXIT_FAILURE, "BZ2_bzDecompressInit failed");
-
- for (;;) {
- switch (BZ2_bzDecompress(&stream)) {
- case BZ_STREAM_END:
- if (BZ2_bzDecompressEnd(&stream) != Z_OK)
- errx(EXIT_FAILURE, "inflateEnd failed");
- output_produced = *out_len - stream.avail_out;
- *out = xrealloc(*out, output_produced + 1);
- *out_len = output_produced;
- (*out)[*out_len] = '\0';
- return;
- case BZ_OK:
- output_produced = *out_len - stream.avail_out;
- if (*out_len <= SSIZE_MAX / 2)
- *out_len *= 2;
- else
- errx(EXIT_FAILURE, "input too large");
- *out = xrealloc(*out, *out_len + 1);
- stream.next_out = *out + output_produced;
- stream.avail_out = *out_len - output_produced;
- break;
- default:
- errx(EXIT_FAILURE, "inflate failed");
- }
- }
-}
-
-static void
-decompress_zlib(const char *in, size_t in_len, char **out, size_t *out_len)
-{
- z_stream stream;
- size_t output_produced;
-
- if (in_len < SSIZE_MAX / 10)
- *out_len = in_len * 10;
- else
- *out_len = in_len;
- *out = xmalloc(*out_len + 1);
-
- stream.next_in = __UNCONST(in);
- stream.avail_in = in_len;
- stream.next_out = (unsigned char *)*out;
- stream.avail_out = *out_len;
- output_produced = 0;
- stream.zalloc = Z_NULL;
- stream.zfree = Z_NULL;
- stream.opaque = NULL;
-
- if (inflateInit2(&stream, 47) != Z_OK)
- errx(EXIT_FAILURE, "inflateInit failed");
-
- for (;;) {
- switch (inflate(&stream, Z_FINISH)) {
- case Z_STREAM_END:
- if (inflateEnd(&stream) != Z_OK)
- errx(EXIT_FAILURE, "inflateEnd failed");
- output_produced = *out_len - stream.avail_out;
- *out = xrealloc(*out, output_produced + 1);
- *out_len = output_produced;
- (*out)[*out_len] = '\0';
- return;
- case Z_OK:
- output_produced = *out_len - stream.avail_out;
- if (*out_len < SSIZE_MAX / 2)
- *out_len *= 2;
- else if (*out_len == SSIZE_MAX - 1)
- errx(EXIT_FAILURE, "input too large");
- else
- *out_len = SSIZE_MAX - 1;
- *out = xrealloc(*out, *out_len + 1);
- stream.next_out = (unsigned char *)*out + output_produced;
- stream.avail_out = *out_len - output_produced;
- break;
- default:
- errx(EXIT_FAILURE, "inflate failed");
- }
- }
-}
-
-int
-decompress_buffer(const char *input, size_t input_len, char **output,
- size_t *output_len)
-{
- if (input_len < 4)
- return 0;
- if (input[0] == 'B' && input[1] == 'Z' && input[2] == 'h' &&
- input[3] >= '1' && input[3] <= '9') {
- /* Normal bzip2. */
- decompress_bzip2(input, input_len, output, output_len);
- } else if (input[0] == 037 && (unsigned char)input[1] == 139 &&
- input[2] == 8 && (input[3] & 0xe0) == 0) {
- /* gzip header with Deflate method */
- decompress_zlib(input, input_len, output, output_len);
- } else /* plain text */
- return 0;
- return 1;
-}
-#endif /* BOOTSTRAP */
diff --git a/pkgtools/pkg_install/files/lib/lib.h b/pkgtools/pkg_install/files/lib/lib.h
index 1d6237171d5..4006474c9ea 100644
--- a/pkgtools/pkg_install/files/lib/lib.h
+++ b/pkgtools/pkg_install/files/lib/lib.h
@@ -1,4 +1,4 @@
-/* $NetBSD: lib.h,v 1.62 2010/02/20 04:40:03 joerg Exp $ */
+/* $NetBSD: lib.h,v 1.63 2010/04/14 18:24:58 joerg Exp $ */
/* from FreeBSD Id: lib.h,v 1.25 1997/10/08 07:48:03 charnier Exp */
@@ -374,13 +374,10 @@ lpkg_t *alloc_lpkg(const char *);
lpkg_t *find_on_queue(lpkg_head_t *, const char *);
void free_lpkg(lpkg_t *);
-/* Extract input if compressed to NUL terminated buffer (not counted) */
-int decompress_buffer(const char *, size_t, char **, size_t *);
-
-/* Parse NUL terminated inputed, argument is strlen of the input */
-struct pkg_vulnerabilities *parse_pkg_vulnerabilities(const char *, size_t, int);
/* Read pkg_vulnerabilities from file */
-struct pkg_vulnerabilities *read_pkg_vulnerabilities(const char *, int, int);
+struct pkg_vulnerabilities *read_pkg_vulnerabilities_file(const char *, int, int);
+/* Read pkg_vulnerabilities from memory */
+struct pkg_vulnerabilities *read_pkg_vulnerabilities_memory(void *, size_t, int);
void free_pkg_vulnerabilities(struct pkg_vulnerabilities *);
int audit_package(struct pkg_vulnerabilities *, const char *, const char *,
int, int);
diff --git a/pkgtools/pkg_install/files/lib/pkgdb.c b/pkgtools/pkg_install/files/lib/pkgdb.c
index 7a6d2da34fb..0d9244b9d09 100644
--- a/pkgtools/pkg_install/files/lib/pkgdb.c
+++ b/pkgtools/pkg_install/files/lib/pkgdb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pkgdb.c,v 1.37 2010/01/22 13:30:42 joerg Exp $ */
+/* $NetBSD: pkgdb.c,v 1.38 2010/04/14 18:24:58 joerg Exp $ */
#if HAVE_CONFIG_H
#include "config.h"
@@ -7,10 +7,10 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: pkgdb.c,v 1.37 2010/01/22 13:30:42 joerg Exp $");
+__RCSID("$NetBSD: pkgdb.c,v 1.38 2010/04/14 18:24:58 joerg Exp $");
/*-
- * Copyright (c) 1999-2008 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999-2010 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
@@ -168,6 +168,8 @@ pkgdb_retrieve(const char *key)
{
DBT keyd, vald;
int status;
+ char *eos;
+ static int corruption_warning;
if (pkgdbp == NULL)
return NULL;
@@ -179,9 +181,15 @@ pkgdb_retrieve(const char *key)
vald.data = (void *)NULL;
vald.size = 0;
status = (*pkgdbp->get) (pkgdbp, &keyd, &vald, 0);
- if (status) {
- vald.data = NULL;
- vald.size = 0;
+ if (status)
+ return NULL;
+ eos = memchr(vald.data, 0, vald.size);
+ if (eos == NULL || eos != (char *)vald.data + vald.size) {
+ if (!corruption_warning) {
+ warnx("pkgdb corrupted, please run ``pkg_admin rebuild''");
+ corruption_warning = 1;
+ }
+ return NULL;
}
return vald.data;
diff --git a/pkgtools/pkg_install/files/lib/version.h b/pkgtools/pkg_install/files/lib/version.h
index f45b14cddd1..fed93d9923c 100644
--- a/pkgtools/pkg_install/files/lib/version.h
+++ b/pkgtools/pkg_install/files/lib/version.h
@@ -1,4 +1,4 @@
-/* $NetBSD: version.h,v 1.152 2010/03/19 12:49:53 wiz Exp $ */
+/* $NetBSD: version.h,v 1.153 2010/04/14 18:24:58 joerg Exp $ */
/*
* Copyright (c) 2001 Thomas Klausner. All rights reserved.
@@ -27,6 +27,6 @@
#ifndef _INST_LIB_VERSION_H_
#define _INST_LIB_VERSION_H_
-#define PKGTOOLS_VERSION 20100319
+#define PKGTOOLS_VERSION 20100405
#endif /* _INST_LIB_VERSION_H_ */
diff --git a/pkgtools/pkg_install/files/lib/vulnerabilities-file.c b/pkgtools/pkg_install/files/lib/vulnerabilities-file.c
index a53f73466ff..897795fd9b1 100644
--- a/pkgtools/pkg_install/files/lib/vulnerabilities-file.c
+++ b/pkgtools/pkg_install/files/lib/vulnerabilities-file.c
@@ -1,7 +1,7 @@
-/* $NetBSD: vulnerabilities-file.c,v 1.5 2009/03/02 14:59:14 joerg Exp $ */
+/* $NetBSD: vulnerabilities-file.c,v 1.6 2010/04/14 18:24:58 joerg Exp $ */
/*-
- * Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>.
+ * Copyright (c) 2008, 2010 Joerg Sonnenberger <joerg@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,7 @@
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
-__RCSID("$NetBSD: vulnerabilities-file.c,v 1.5 2009/03/02 14:59:14 joerg Exp $");
+__RCSID("$NetBSD: vulnerabilities-file.c,v 1.6 2010/04/14 18:24:58 joerg Exp $");
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
@@ -46,6 +46,9 @@ __RCSID("$NetBSD: vulnerabilities-file.c,v 1.5 2009/03/02 14:59:14 joerg Exp $")
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
+#ifndef BOOTSTRAP
+#include <archive.h>
+#endif
#include <ctype.h>
#if HAVE_ERR_H
#include <err.h>
@@ -66,6 +69,9 @@ __RCSID("$NetBSD: vulnerabilities-file.c,v 1.5 2009/03/02 14:59:14 joerg Exp $")
#include "lib.h"
+static struct pkg_vulnerabilities *read_pkg_vulnerabilities_archive(struct archive *, int);
+static struct pkg_vulnerabilities *parse_pkg_vuln(const char *, size_t, int);
+
static const char pgp_msg_start[] = "-----BEGIN PGP SIGNED MESSAGE-----\n";
static const char pgp_msg_end[] = "-----BEGIN PGP SIGNATURE-----\n";
static const char pkcs7_begin[] = "-----BEGIN PKCS7-----\n";
@@ -336,14 +342,38 @@ add_vulnerability(struct pkg_vulnerabilities *pv, size_t *allocated, const char
}
struct pkg_vulnerabilities *
-read_pkg_vulnerabilities(const char *path, int ignore_missing, int check_sum)
+read_pkg_vulnerabilities_memory(void *buf, size_t len, int check_sum)
+{
+#ifdef BOOTSTRAP
+ errx(EXIT_FAILURE, "Audit functions are unsupported during bootstrap");
+#else
+ struct archive *a;
+ struct pkg_vulnerabilities *pv;
+
+ if ((a = archive_read_new()) == NULL)
+ errx(EXIT_FAILURE, "memory allocation failed");
+
+ if (archive_read_support_compression_all(a) != ARCHIVE_OK ||
+ archive_read_support_format_raw(a) != ARCHIVE_OK ||
+ archive_read_open_memory(a, buf, len) != ARCHIVE_OK)
+ errx(EXIT_FAILURE, "Cannot open pkg_vulnerabilies buffer: %s",
+ archive_error_string(a));
+
+ pv = read_pkg_vulnerabilities_archive(a, check_sum);
+
+ return pv;
+#endif
+}
+
+struct pkg_vulnerabilities *
+read_pkg_vulnerabilities_file(const char *path, int ignore_missing, int check_sum)
{
+#ifdef BOOTSTRAP
+ errx(EXIT_FAILURE, "Audit functions are unsupported during bootstrap");
+#else
+ struct archive *a;
struct pkg_vulnerabilities *pv;
- struct stat st;
int fd;
- char *input, *decompressed_input;
- size_t input_len, decompressed_len;
- ssize_t bytes_read;
if ((fd = open(path, O_RDONLY)) == -1) {
if (errno == ENOENT && ignore_missing)
@@ -351,39 +381,67 @@ read_pkg_vulnerabilities(const char *path, int ignore_missing, int check_sum)
err(EXIT_FAILURE, "Cannot open %s", path);
}
- if (fstat(fd, &st) == -1)
- err(EXIT_FAILURE, "Cannot stat %s", path);
+ if ((a = archive_read_new()) == NULL)
+ errx(EXIT_FAILURE, "memory allocation failed");
+
+ if (archive_read_support_compression_all(a) != ARCHIVE_OK ||
+ archive_read_support_format_raw(a) != ARCHIVE_OK ||
+ archive_read_open_fd(a, fd, 65536) != ARCHIVE_OK)
+ errx(EXIT_FAILURE, "Cannot open ``%s'': %s", path,
+ archive_error_string(a));
- if ((st.st_mode & S_IFMT) != S_IFREG)
- errx(EXIT_FAILURE, "Input is not regular file");
- if (st.st_size > SSIZE_MAX - 1)
- errx(EXIT_FAILURE, "Input too large");
+ pv = read_pkg_vulnerabilities_archive(a, check_sum);
+ close(fd);
+
+ return pv;
+#endif
+}
- input_len = (size_t)st.st_size;
- if (input_len < 4)
- err(EXIT_FAILURE, "Input too short for a pkg_vulnerability file");
- input = xmalloc(input_len + 1);
- if ((bytes_read = read(fd, input, input_len)) == -1)
- err(1, "Failed to read input");
- if (bytes_read != st.st_size)
- errx(1, "Unexpected short read");
+#ifndef BOOTSTRAP
+static struct pkg_vulnerabilities *
+read_pkg_vulnerabilities_archive(struct archive *a, int check_sum)
+{
+ struct archive_entry *ae;
+ struct pkg_vulnerabilities *pv;
+ char *buf;
+ size_t buf_len, off;
+ ssize_t r;
- close(fd);
+ if (archive_read_next_header(a, &ae) != ARCHIVE_OK)
+ errx(EXIT_FAILURE, "Cannot read pkg_vulnerabilities: %s",
+ archive_error_string(a));
- if (decompress_buffer(input, input_len, &decompressed_input,
- &decompressed_len)) {
- free(input);
- input = decompressed_input;
- input_len = decompressed_len;
+ off = 0;
+ buf_len = 65536;
+ buf = xmalloc(buf_len + 1);
+
+ for (;;) {
+ r = archive_read_data(a, buf + off, buf_len - off);
+ if (r <= 0)
+ break;
+ off += r;
+ if (off == buf_len) {
+ buf_len *= 2;
+ if (buf_len < off)
+ errx(EXIT_FAILURE, "pkg_vulnerabilties too large");
+ buf = xrealloc(buf, buf_len + 1);
+ }
}
- pv = parse_pkg_vulnerabilities(input, input_len, check_sum);
- free(input);
+ if (r != ARCHIVE_OK)
+ errx(EXIT_FAILURE, "Cannot read pkg_vulnerabilities: %s",
+ archive_error_string(a));
+
+ archive_read_close(a);
+
+ buf[off] = '\0';
+ pv = parse_pkg_vuln(buf, off, check_sum);
+ free(buf);
return pv;
}
-struct pkg_vulnerabilities *
-parse_pkg_vulnerabilities(const char *input, size_t input_len, int check_sum)
+static struct pkg_vulnerabilities *
+parse_pkg_vuln(const char *input, size_t input_len, int check_sum)
{
struct pkg_vulnerabilities *pv;
long version;
@@ -502,6 +560,7 @@ parse_pkg_vulnerabilities(const char *input, size_t input_len, int check_sum)
return pv;
}
+#endif
void
free_pkg_vulnerabilities(struct pkg_vulnerabilities *pv)