aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/add.c2
-rw-r--r--src/apk_archive.h5
-rw-r--r--src/apk_database.h1
-rw-r--r--src/apk_io.h1
-rw-r--r--src/apk_package.h6
-rw-r--r--src/archive.c39
-rw-r--r--src/database.c30
-rw-r--r--src/gunzip.c98
-rw-r--r--src/index.c51
-rw-r--r--src/io.c39
-rw-r--r--src/package.c93
11 files changed, 289 insertions, 76 deletions
diff --git a/src/add.c b/src/add.c
index 180615c11b..8f067b7545 100644
--- a/src/add.c
+++ b/src/add.c
@@ -118,7 +118,7 @@ static int add_main(void *ctx, int argc, char **argv)
if (strstr(argv[i], ".apk") != NULL) {
struct apk_package *pkg;
- pkg = apk_db_pkg_add_file(&db, argv[i]);
+ pkg = apk_pkg_read(&db, argv[i], APK_SIGN_VERIFY);
if (pkg == NULL) {
apk_error("Unable to read '%s'", argv[i]);
goto err;
diff --git a/src/apk_archive.h b/src/apk_archive.h
index f1787dc507..a0a289acc1 100644
--- a/src/apk_archive.h
+++ b/src/apk_archive.h
@@ -20,8 +20,9 @@ typedef int (*apk_archive_entry_parser)(void *ctx,
const struct apk_file_info *ae,
struct apk_istream *istream);
-int apk_parse_tar(struct apk_istream *, apk_archive_entry_parser parser, void *ctx);
-int apk_write_tar_entry(struct apk_ostream *, const struct apk_file_info *ae, char *data);
+int apk_tar_parse(struct apk_istream *, apk_archive_entry_parser parser, void *ctx);
+int apk_tar_write_entry(struct apk_ostream *, const struct apk_file_info *ae, char *data);
+int apk_tar_write_padding(struct apk_ostream *, const struct apk_file_info *ae);
int apk_archive_entry_extract(const struct apk_file_info *ae,
struct apk_istream *is,
diff --git a/src/apk_database.h b/src/apk_database.h
index b4c3f04e20..979d0e862b 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -134,7 +134,6 @@ int apk_db_write_config(struct apk_database *db);
void apk_db_close(struct apk_database *db);
int apk_db_cache_active(struct apk_database *db);
-struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file);
struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *pkg);
struct apk_package *apk_db_get_pkg(struct apk_database *db, struct apk_checksum *csum);
struct apk_package *apk_db_get_file_owner(struct apk_database *db, apk_blob_t filename);
diff --git a/src/apk_io.h b/src/apk_io.h
index 49d9fcfa35..e547668dc7 100644
--- a/src/apk_io.h
+++ b/src/apk_io.h
@@ -59,6 +59,7 @@ static inline struct apk_istream *apk_bstream_gunzip(struct apk_bstream *bs)
}
struct apk_ostream *apk_ostream_gzip(struct apk_ostream *);
+struct apk_ostream *apk_ostream_counter(off_t *);
struct apk_istream *apk_istream_from_fd(int fd);
struct apk_istream *apk_istream_from_file(const char *file);
diff --git a/src/apk_package.h b/src/apk_package.h
index b874e0c2df..bf30350d29 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -30,6 +30,10 @@ struct apk_name;
#define APK_PKG_NOT_INSTALLED 0
#define APK_PKG_INSTALLED 1
+#define APK_SIGN_VERIFY 0
+#define APK_SIGN_GENERATE_V1 1
+#define APK_SIGN_GENERATE 2
+
struct apk_script {
struct hlist_node script_list;
unsigned int type;
@@ -80,7 +84,7 @@ int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os);
int apk_script_type(const char *name);
struct apk_package *apk_pkg_new(void);
-struct apk_package *apk_pkg_read(struct apk_database *db, const char *name);
+struct apk_package *apk_pkg_read(struct apk_database *db, const char *name, int indexstyle);
void apk_pkg_free(struct apk_package *pkg);
int apk_pkg_parse_name(apk_blob_t apkname, apk_blob_t *name, apk_blob_t *version);
diff --git a/src/archive.c b/src/archive.c
index 8e55295b5e..f30463f550 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -93,7 +93,7 @@ static size_t tar_entry_read(void *stream, void *ptr, size_t size)
return size;
}
-int apk_parse_tar(struct apk_istream *is, apk_archive_entry_parser parser,
+int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
void *ctx)
{
struct apk_file_info entry;
@@ -205,11 +205,9 @@ err:
return r;
}
-int apk_write_tar_entry(struct apk_ostream *os, const struct apk_file_info *ae, char *data)
+int apk_tar_write_entry(struct apk_ostream *os, const struct apk_file_info *ae, char *data)
{
- static char padding[512];
struct tar_header buf;
- int pad;
memset(&buf, 0, sizeof(buf));
if (ae != NULL) {
@@ -221,15 +219,17 @@ int apk_write_tar_entry(struct apk_ostream *os, const struct apk_file_info *ae,
else
return -1;
- strncpy(buf.name, ae->name, sizeof(buf.name));
- strncpy(buf.uname, ae->uname, sizeof(buf.uname));
- strncpy(buf.gname, ae->gname, sizeof(buf.gname));
+ if (ae->name != NULL)
+ strncpy(buf.name, ae->name, sizeof(buf.name));
+
+ strncpy(buf.uname, ae->uname ?: "root", sizeof(buf.uname));
+ strncpy(buf.gname, ae->gname ?: "root", sizeof(buf.gname));
PUT_OCTAL(buf.size, ae->size);
PUT_OCTAL(buf.uid, ae->uid);
PUT_OCTAL(buf.gid, ae->gid);
PUT_OCTAL(buf.mode, ae->mode & 07777);
- PUT_OCTAL(buf.mtime, ae->mtime);
+ PUT_OCTAL(buf.mtime, ae->mtime ?: time(NULL));
/* Checksum */
strcpy(buf.magic, "ustar ");
@@ -243,18 +243,33 @@ int apk_write_tar_entry(struct apk_ostream *os, const struct apk_file_info *ae,
if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
return -1;
- if (data != NULL) {
+ if (ae == NULL) {
+ /* End-of-archive is two empty headers */
+ if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
+ return -1;
+ } else if (data != NULL) {
if (os->write(os, data, ae->size) != ae->size)
return -1;
- pad = 512 - (ae->size & 511);
- if (pad != 512 &&
- os->write(os, padding, pad) != pad)
+ if (apk_tar_write_padding(os, ae) != 0)
return -1;
}
return 0;
}
+int apk_tar_write_padding(struct apk_ostream *os, const struct apk_file_info *ae)
+{
+ static char padding[512];
+ int pad;
+
+ pad = 512 - (ae->size & 511);
+ if (pad != 512 &&
+ os->write(os, padding, pad) != pad)
+ return -1;
+
+ return 0;
+}
+
int apk_archive_entry_extract(const struct apk_file_info *ae,
struct apk_istream *is,
const char *fn, apk_progress_cb cb,
diff --git a/src/database.c b/src/database.c
index 2a15385a15..5a1348e063 100644
--- a/src/database.c
+++ b/src/database.c
@@ -545,19 +545,14 @@ static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os
struct apk_file_info fi;
char filename[256];
apk_blob_t bfn;
- int r, i;
+ int r;
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
hlist_for_each_entry(script, c2, &pkg->scripts, script_list) {
fi = (struct apk_file_info) {
.name = filename,
- .uname = "root",
- .gname = "root",
.size = script->size,
- .uid = 0,
- .gid = 0,
.mode = 0755 | S_IFREG,
- .mtime = time(NULL),
};
/* The scripts db expects file names in format:
* pkg-version.<hexdump of package checksum>.action */
@@ -571,18 +566,13 @@ static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os
apk_blob_push_blob(&bfn, APK_BLOB_STR(apk_script_types[script->type]));
apk_blob_push_blob(&bfn, APK_BLOB_PTR_LEN("", 1));
- r = apk_write_tar_entry(os, &fi, script->script);
+ r = apk_tar_write_entry(os, &fi, script->script);
if (r < 0)
return r;
}
}
- for (i = 0; i < 2; i++) {
- r = apk_write_tar_entry(os, NULL, NULL);
- if (r < 0)
- return r;
- }
- return 0;
+ return apk_tar_write_entry(os, NULL, NULL);
}
static int apk_db_scriptdb_read_v1(struct apk_database *db, struct apk_istream *is)
@@ -688,7 +678,7 @@ static int apk_db_read_state(struct apk_database *db, int flags)
if (!(flags & APK_OPENF_NO_SCRIPTS)) {
is = apk_istream_from_file("var/lib/apk/scripts.tar");
if (is != NULL) {
- apk_parse_tar(is, apk_read_script_archive_entry, db);
+ apk_tar_parse(is, apk_read_script_archive_entry, db);
} else {
is = apk_istream_from_file("var/lib/apk/scripts");
if (is != NULL)
@@ -970,16 +960,6 @@ struct apk_package *apk_db_get_file_owner(struct apk_database *db,
return dbf->diri->pkg;
}
-struct apk_package *apk_db_pkg_add_file(struct apk_database *db, const char *file)
-{
- struct apk_package *info;
-
- info = apk_pkg_read(db, file);
- if (info != NULL)
- info = apk_db_pkg_add(db, info);
- return info;
-}
-
struct index_write_ctx {
struct apk_ostream *os;
int count;
@@ -1433,7 +1413,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
};
tar = apk_bstream_gunzip_mpart(bs, apk_db_gzip_part, &ctx);
- if (apk_parse_tar(tar, apk_db_install_archive_entry, &ctx) != 0)
+ if (apk_tar_parse(tar, apk_db_install_archive_entry, &ctx) != 0)
goto err_close;
tar->close(tar);
diff --git a/src/gunzip.c b/src/gunzip.c
index af906d1e51..2c4387e0aa 100644
--- a/src/gunzip.c
+++ b/src/gunzip.c
@@ -30,7 +30,7 @@ struct apk_gzip_istream {
void *cbctx;
};
-static size_t gz_read(void *stream, void *ptr, size_t size)
+static size_t gzi_read(void *stream, void *ptr, size_t size)
{
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
@@ -78,11 +78,13 @@ static size_t gz_read(void *stream, void *ptr, size_t size)
EVP_DigestUpdate(&gis->mdctx, gis->mdblock,
(void *)gis->zs.next_in - gis->mdblock);
gis->mdblock = gis->zs.next_in;
- gis->cb(gis->cbctx, &gis->mdctx,
- APK_MPART_BOUNDARY);
+ if (gis->cb(gis->cbctx, &gis->mdctx,
+ APK_MPART_BOUNDARY)) {
+ gis->z_err = Z_STREAM_END;
+ break;
+ }
}
inflateEnd(&gis->zs);
-
if (inflateInit2(&gis->zs, 15+32) != Z_OK)
return -1;
gis->z_err = Z_OK;
@@ -95,7 +97,7 @@ static size_t gz_read(void *stream, void *ptr, size_t size)
return size - gis->zs.avail_out;
}
-static void gz_close(void *stream)
+static void gzi_close(void *stream)
{
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
@@ -117,11 +119,11 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
gis = malloc(sizeof(struct apk_gzip_istream));
if (gis == NULL)
- return NULL;
+ goto err;
*gis = (struct apk_gzip_istream) {
- .is.read = gz_read,
- .is.close = gz_close,
+ .is.read = gzi_read,
+ .is.close = gzi_close,
.bs = bs,
.z_err = 0,
.cb = cb,
@@ -130,7 +132,7 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
if (inflateInit2(&gis->zs, 15+32) != Z_OK) {
free(gis);
- return NULL;
+ goto err;
}
if (gis->cb != NULL) {
@@ -139,5 +141,83 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
}
return &gis->is;
+err:
+ bs->close(bs, NULL);
+ return NULL;
+}
+
+struct apk_gzip_ostream {
+ struct apk_ostream os;
+ struct apk_ostream *output;
+ z_stream zs;
+ unsigned char buffer[8*1024];
+};
+
+static size_t gzo_write(void *stream, const void *ptr, size_t size)
+{
+ struct apk_gzip_ostream *gos = (struct apk_gzip_ostream *) stream;
+ size_t have;
+ int r;
+
+ gos->zs.avail_in = size;
+ gos->zs.next_in = (void *) ptr;
+ while (gos->zs.avail_in) {
+ gos->zs.avail_out = sizeof(gos->buffer);
+ gos->zs.next_out = gos->buffer;
+ r = deflate(&gos->zs, Z_NO_FLUSH);
+ if (r == Z_STREAM_ERROR)
+ return -1;
+ have = sizeof(gos->buffer) - gos->zs.avail_out;
+ if (have != 0) {
+ r = gos->output->write(gos->output, gos->buffer, have);
+ if (r != have)
+ return -1;
+ }
+ }
+
+ return size;
+}
+
+static void gzo_close(void *stream)
+{
+ struct apk_gzip_ostream *gos = (struct apk_gzip_ostream *) stream;
+ size_t have;
+
+ deflate(&gos->zs, Z_FINISH);
+ have = sizeof(gos->buffer) - gos->zs.avail_out;
+ gos->output->write(gos->output, gos->buffer, have);
+ gos->output->close(gos->output);
+
+ deflateEnd(&gos->zs);
+ free(stream);
+}
+
+struct apk_ostream *apk_ostream_gzip(struct apk_ostream *output)
+{
+ struct apk_gzip_ostream *gos;
+
+ if (output == NULL)
+ return NULL;
+
+ gos = malloc(sizeof(struct apk_gzip_ostream));
+ if (gos == NULL)
+ goto err;
+
+ *gos = (struct apk_gzip_ostream) {
+ .os.write = gzo_write,
+ .os.close = gzo_close,
+ .output = output,
+ };
+
+ if (deflateInit2(&gos->zs, 9, Z_DEFLATED, 15 | 16, 8,
+ Z_DEFAULT_STRATEGY) != Z_OK) {
+ free(gos);
+ goto err;
+ }
+
+ return &gos->os;
+err:
+ output->close(output);
+ return NULL;
}
diff --git a/src/index.c b/src/index.c
index d7402f9ee5..86c1f44c37 100644
--- a/src/index.c
+++ b/src/index.c
@@ -10,18 +10,23 @@
*/
#include <stdio.h>
+#include <fcntl.h>
#include <unistd.h>
#include "apk_applet.h"
#include "apk_database.h"
+#define INDEX_OLD_FORMAT 0x10000
+
struct counts {
int unsatisfied;
};
struct index_ctx {
const char *index;
+ const char *output;
time_t index_mtime;
+ int method;
};
static int index_parse(void *ctx, int optch, int optindex, const char *optarg)
@@ -32,6 +37,12 @@ static int index_parse(void *ctx, int optch, int optindex, const char *optarg)
case 'x':
ictx->index = optarg;
break;
+ case 'o':
+ ictx->output = optarg;
+ break;
+ case INDEX_OLD_FORMAT:
+ ictx->method = APK_SIGN_GENERATE_V1;
+ break;
default:
return -1;
}
@@ -83,6 +94,16 @@ static int index_main(void *ctx, int argc, char **argv)
int total, i, j, found, newpkgs = 0;
struct index_ctx *ictx = (struct index_ctx *) ctx;
+ if (isatty(STDOUT_FILENO) && ictx->output == NULL &&
+ !(apk_flags & APK_FORCE)) {
+ apk_error("Will not write binary index to console "
+ "without --force");
+ return -1;
+ }
+
+ if (ictx->method == 0)
+ ictx->method = APK_SIGN_GENERATE;
+
apk_db_open(&db, NULL, APK_OPENF_READ);
if (index_read_file(&db, ictx) < 0) {
apk_db_close(&db);
@@ -137,13 +158,33 @@ static int index_main(void *ctx, int argc, char **argv)
} while (0);
if (!found) {
- apk_db_pkg_add_file(&db, argv[i]);
- newpkgs++;
+ if (apk_pkg_read(&db, argv[i], ictx->method) != NULL)
+ newpkgs++;
}
}
- os = apk_ostream_to_fd(STDOUT_FILENO);
+ if (ictx->method == APK_SIGN_GENERATE) {
+ memset(&fi, 0, sizeof(fi));
+ fi.name = "APKINDEX";
+ fi.mode = 0755 | S_IFREG;
+ os = apk_ostream_counter(&fi.size);
+ apk_db_index_write(&db, os);
+ os->close(os);
+ }
+
+ if (ictx->output != NULL)
+ os = apk_ostream_to_file(ictx->output, 0755);
+ else
+ os = apk_ostream_to_fd(STDOUT_FILENO);
+ if (ictx->method == APK_SIGN_GENERATE) {
+ os = apk_ostream_gzip(os);
+ apk_tar_write_entry(os, &fi, NULL);
+ }
total = apk_db_index_write(&db, os);
+ if (ictx->method == APK_SIGN_GENERATE) {
+ apk_tar_write_padding(os, &fi);
+ apk_tar_write_entry(os, NULL, NULL);
+ }
os->close(os);
apk_hash_foreach(&db.available.names, warn_if_no_providers, &counts);
@@ -160,9 +201,13 @@ static int index_main(void *ctx, int argc, char **argv)
}
static struct apk_option index_options[] = {
+ { 'o', "output", "Write the generated index to FILE",
+ required_argument, "FILE" },
{ 'x', "index", "Read INDEX to speed up new index creation by reusing "
"the information from an old index",
required_argument, "INDEX" },
+ { INDEX_OLD_FORMAT, "old-format",
+ "Specify to create old style index files" }
};
static struct apk_applet apk_index = {
diff --git a/src/io.c b/src/io.c
index 26d51b986f..c7846c9555 100644
--- a/src/io.c
+++ b/src/io.c
@@ -578,6 +578,45 @@ struct apk_ostream *apk_ostream_to_file(const char *file, mode_t mode)
return apk_ostream_to_fd(fd);
}
+struct apk_counter_ostream {
+ struct apk_ostream os;
+ off_t *counter;
+};
+
+static size_t co_write(void *stream, const void *ptr, size_t size)
+{
+ struct apk_counter_ostream *cos =
+ container_of(stream, struct apk_counter_ostream, os);
+
+ *cos->counter += size;
+ return size;
+}
+
+static void co_close(void *stream)
+{
+ struct apk_counter_ostream *cos =
+ container_of(stream, struct apk_counter_ostream, os);
+
+ free(cos);
+}
+
+struct apk_ostream *apk_ostream_counter(off_t *counter)
+{
+ struct apk_counter_ostream *cos;
+
+ cos = malloc(sizeof(struct apk_counter_ostream));
+ if (cos == NULL)
+ return NULL;
+
+ *cos = (struct apk_counter_ostream) {
+ .os.write = co_write,
+ .os.close = co_close,
+ .counter = counter,
+ };
+
+ return &cos->os;
+}
+
size_t apk_ostream_write_string(struct apk_ostream *os, const char *string)
{
size_t len;
diff --git a/src/package.c b/src/package.c
index c01a5e8baa..95c4cc062f 100644
--- a/src/package.c
+++ b/src/package.c
@@ -257,8 +257,13 @@ int apk_script_type(const char *name)
struct read_info_ctx {
struct apk_database *db;
struct apk_package *pkg;
- int version;
- int has_install;
+ const EVP_MD *md;
+ int version, action;
+ int has_signature : 1;
+ int has_install : 1;
+ int has_data_checksum : 1;
+ int data_started : 1;
+ int in_signatures : 1;
};
int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
@@ -325,12 +330,16 @@ static int read_info_line(void *ctx, apk_blob_t line)
return 0;
for (i = 0; i < ARRAY_SIZE(fields); i++) {
- if (strncmp(fields[i].str, l.ptr, l.len) == 0) {
+ if (apk_blob_compare(APK_BLOB_STR(fields[i].str), l) == 0) {
apk_pkg_add_info(ri->db, ri->pkg, fields[i].field, r);
- break;
+ return 0;
}
}
+ if (ri->data_started == 0 &&
+ apk_blob_compare(APK_BLOB_STR("sha256"), l) == 0)
+ ri->has_data_checksum = 1;
+
return 0;
}
@@ -354,21 +363,27 @@ static int read_info_entry(void *ctx, const struct apk_file_info *ae,
int i;
/* Meta info and scripts */
- if (ae->name[0] == '.') {
+ if (ri->in_signatures && strncmp(ae->name, ".SIGN.", 6) != 0)
+ ri->in_signatures = 0;
+
+ if (ri->data_started == 0 && ae->name[0] == '.') {
/* APK 2.0 format */
- ri->version = 2;
if (strcmp(ae->name, ".PKGINFO") == 0) {
apk_blob_t blob = apk_blob_from_istream(is, ae->size);
apk_blob_for_each_segment(blob, "\n", read_info_line, ctx);
free(blob.ptr);
- return 0;
- }
- if (strcmp(ae->name, ".INSTALL") == 0) {
+ ri->version = 2;
+ } else if (strncmp(ae->name, ".SIGN.", 6) == 0) {
+ ri->has_signature = 1;
+ } else if (strcmp(ae->name, ".INSTALL") == 0) {
apk_warning("Package '%s-%s' contains deprecated .INSTALL",
pkg->name->name, pkg->version);
- return 0;
}
- } else if (strncmp(ae->name, "var/db/apk/", 11) == 0) {
+ return 0;
+ }
+
+ ri->data_started = 1;
+ if (strncmp(ae->name, "var/db/apk/", 11) == 0) {
/* APK 1.0 format */
ri->version = 1;
if (!S_ISREG(ae->mode))
@@ -399,10 +414,7 @@ static int read_info_entry(void *ctx, const struct apk_file_info *ae,
if (apk_script_type(slash+1) == APK_SCRIPT_POST_INSTALL ||
apk_script_type(slash+1) == APK_SCRIPT_PRE_INSTALL)
ri->has_install = 1;
- } else if (ri->version == 2) {
- /* All metdata of version 2.x package handled */
- return 0;
- } else {
+ } else if (ri->version < 2) {
/* Version 1.x packages do not contain installed size
* in metadata, so we calculate it here */
pkg->installed_size += apk_calc_installed_size(ae->size);
@@ -417,29 +429,59 @@ static int apk_pkg_gzip_part(void *ctx, EVP_MD_CTX *mdctx, int part)
switch (part) {
case APK_MPART_BEGIN:
- EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
+ EVP_DigestInit_ex(mdctx, ri->md, NULL);
break;
+ case APK_MPART_BOUNDARY:
+ if (ri->in_signatures) {
+ EVP_DigestFinal_ex(mdctx, ri->pkg->csum.data, NULL);
+ EVP_DigestInit_ex(mdctx, ri->md, NULL);
+ return 0;
+ }
+
+ if (ri->action == APK_SIGN_GENERATE_V1 ||
+ !ri->has_data_checksum)
+ break;
+ /* Fallthrough to calculate checksum */
case APK_MPART_END:
ri->pkg->csum.type = EVP_MD_CTX_size(mdctx);
EVP_DigestFinal_ex(mdctx, ri->pkg->csum.data, NULL);
- break;
+ return 1;
}
return 0;
}
-struct apk_package *apk_pkg_read(struct apk_database *db, const char *file)
+struct apk_package *apk_pkg_read(struct apk_database *db, const char *file,
+ int action)
{
struct read_info_ctx ctx;
struct apk_file_info fi;
struct apk_bstream *bs;
struct apk_istream *tar;
char realfile[PATH_MAX];
+ int r;
if (realpath(file, realfile) < 0)
return NULL;
if (apk_file_get_info(realfile, APK_CHECKSUM_NONE, &fi) < 0)
return NULL;
+ memset(&ctx, 0, sizeof(ctx));
+ switch (action) {
+ case APK_SIGN_VERIFY:
+ ctx.in_signatures = 1;
+ ctx.md = EVP_md_null();
+ break;
+ case APK_SIGN_GENERATE:
+ ctx.in_signatures = 1;
+ ctx.md = EVP_sha1();
+ break;
+ case APK_SIGN_GENERATE_V1:
+ ctx.md = EVP_md5();
+ break;
+ default:
+ return NULL;
+ }
+
ctx.pkg = apk_pkg_new();
if (ctx.pkg == NULL)
return NULL;
@@ -450,15 +492,22 @@ struct apk_package *apk_pkg_read(struct apk_database *db, const char *file)
ctx.db = db;
ctx.has_install = 0;
+ ctx.action = action;
ctx.pkg->size = fi.size;
tar = apk_bstream_gunzip_mpart(bs, apk_pkg_gzip_part, &ctx);
- if (apk_parse_tar(tar, read_info_entry, &ctx) < 0) {
+ r = apk_tar_parse(tar, read_info_entry, &ctx);
+ tar->close(tar);
+ switch (r) {
+ case 0:
+ break;
+ case -2:
+ apk_error("File %s does not have a signature", file);
+ goto err;
+ default:
apk_error("File %s is not an APK archive", file);
- bs->close(bs, NULL);
goto err;
}
- tar->close(tar);
if (ctx.pkg->name == NULL) {
apk_error("File %s is corrupted", file);
@@ -474,7 +523,7 @@ struct apk_package *apk_pkg_read(struct apk_database *db, const char *file)
}
ctx.pkg->filename = strdup(realfile);
- return ctx.pkg;
+ return apk_db_pkg_add(db, ctx.pkg);
err:
apk_pkg_free(ctx.pkg);
return NULL;