summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/add.c3
-rw-r--r--src/apk.c2
-rw-r--r--src/apk_archive.h3
-rw-r--r--src/apk_blob.h44
-rw-r--r--src/apk_csum.h49
-rw-r--r--src/apk_database.h14
-rw-r--r--src/apk_io.h7
-rw-r--r--src/apk_package.h6
-rw-r--r--src/archive.c91
-rw-r--r--src/audit.c8
-rw-r--r--src/blob.c49
-rw-r--r--src/cache.c23
-rw-r--r--src/database.c198
-rw-r--r--src/io.c14
-rw-r--r--src/package.c19
15 files changed, 371 insertions, 159 deletions
diff --git a/src/add.c b/src/add.c
index b076706..180615c 100644
--- a/src/add.c
+++ b/src/add.c
@@ -103,7 +103,8 @@ static int add_main(void *ctx, int argc, char **argv)
goto err;
}
virtpkg->name = apk_db_get_name(&db, APK_BLOB_STR(actx->virtpkg));
- csum_blob(APK_BLOB_STR(virtpkg->name->name), virtpkg->csum);
+ apk_blob_checksum(APK_BLOB_STR(virtpkg->name->name),
+ apk_default_checksum(), &virtpkg->csum);
virtpkg->version = strdup("0");
virtpkg->description = strdup("virtual meta package");
virtdep = apk_dep_from_pkg(&db, virtpkg);
diff --git a/src/apk.c b/src/apk.c
index cd6cd91..ecbae72 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -23,9 +23,7 @@
#include "apk_defines.h"
#include "apk_applet.h"
#include "apk_blob.h"
-#include "apk_csum.h"
-csum_t bad_checksum = {0};
const char *apk_root;
struct apk_repository_url apk_repository_list;
int apk_verbosity = 1, apk_cwd_fd, apk_wait;
diff --git a/src/apk_archive.h b/src/apk_archive.h
index 4651255..d3b787d 100644
--- a/src/apk_archive.h
+++ b/src/apk_archive.h
@@ -4,7 +4,7 @@
* Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
* All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
+ * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation. See http://www.gnu.org/ for details.
*/
@@ -22,6 +22,7 @@ typedef int (*apk_archive_entry_parser)(void *ctx,
int apk_parse_tar(struct apk_istream *, apk_archive_entry_parser parser, void *ctx);
int apk_parse_tar_gz(struct apk_bstream *, 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_archive_entry_extract(const struct apk_file_info *ae,
struct apk_istream *is,
diff --git a/src/apk_blob.h b/src/apk_blob.h
index 9ad79c4..170cf20 100644
--- a/src/apk_blob.h
+++ b/src/apk_blob.h
@@ -13,6 +13,8 @@
#define APK_BLOB_H
#include <string.h>
+#include <openssl/evp.h>
+
#include "apk_defines.h"
struct apk_blob {
@@ -22,10 +24,38 @@ struct apk_blob {
typedef struct apk_blob apk_blob_t;
typedef int (*apk_blob_cb)(void *ctx, apk_blob_t blob);
+#define APK_CHECKSUM_NONE 0
+#define APK_CHECKSUM_MD5 16
+#define APK_CHECKSUM_SHA1 20
+
+/* Internal cointainer for MD5 or SHA1 */
+struct apk_checksum {
+ unsigned char data[20];
+ unsigned char type;
+};
+
+static inline const EVP_MD *apk_default_checksum(void)
+{
+ return EVP_sha1();
+}
+
+static inline const EVP_MD *apk_get_digest(int type)
+{
+ switch (type) {
+ case APK_CHECKSUM_MD5:
+ return EVP_md5();
+ case APK_CHECKSUM_SHA1:
+ return EVP_sha1();
+ }
+ return EVP_md_null();
+}
+
#define APK_BLOB_IS_NULL(blob) ((blob).ptr == NULL)
#define APK_BLOB_NULL ((apk_blob_t){0, NULL})
#define APK_BLOB_BUF(buf) ((apk_blob_t){sizeof(buf), (char *)(buf)})
+#define APK_BLOB_CSUM(csum) ((apk_blob_t){(csum).type, (char *)(csum).data})
+#define APK_BLOB_STRUCT(s) ((apk_blob_t){sizeof(s), (char*)&(s)})
#define APK_BLOB_PTR_LEN(beg,len) ((apk_blob_t){(len), (beg)})
#define APK_BLOB_PTR_PTR(beg,end) APK_BLOB_PTR_LEN((beg),(end)-(beg)+1)
@@ -47,12 +77,26 @@ int apk_blob_compare(apk_blob_t a, apk_blob_t b);
int apk_blob_for_each_segment(apk_blob_t blob, const char *split,
apk_blob_cb cb, void *ctx);
+static inline void apk_blob_checksum(apk_blob_t b, const EVP_MD *md, struct apk_checksum *csum)
+{
+ csum->type = EVP_MD_size(md);
+ EVP_Digest(b.ptr, b.len, csum->data, NULL, md, NULL);
+}
+static inline const int apk_checksum_compare(const struct apk_checksum *a,
+ const struct apk_checksum *b)
+{
+ return apk_blob_compare(APK_BLOB_PTR_LEN((char *) a->data, a->type),
+ APK_BLOB_PTR_LEN((char *) b->data, b->type));
+}
+
void apk_blob_push_blob(apk_blob_t *to, apk_blob_t literal);
void apk_blob_push_uint(apk_blob_t *to, unsigned int value, int radix);
+void apk_blob_push_csum(apk_blob_t *to, struct apk_checksum *csum);
void apk_blob_push_hexdump(apk_blob_t *to, apk_blob_t binary);
void apk_blob_pull_char(apk_blob_t *b, int expected);
unsigned int apk_blob_pull_uint(apk_blob_t *b, int radix);
+void apk_blob_pull_csum(apk_blob_t *b, struct apk_checksum *csum);
void apk_blob_pull_hexdump(apk_blob_t *b, apk_blob_t to);
#endif
diff --git a/src/apk_csum.h b/src/apk_csum.h
deleted file mode 100644
index f2335d3..0000000
--- a/src/apk_csum.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* apk_csum.c - Alpine Package Keeper (APK)
- *
- * Copyright (C) 2009 Timo Teräs <timo.teras@iki.fi>
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation. See http://www.gnu.org/ for details.
- */
-
-#ifndef APK_CSUM_H
-#define APK_CSUM_H
-
-#include <openssl/evp.h>
-
-#define MAX_CSUM_SIZE 16 /* MD5 */
-
-typedef unsigned char *csum_p;
-typedef unsigned char csum_t[MAX_CSUM_SIZE];
-typedef EVP_MD_CTX csum_ctx_t;
-
-extern csum_t bad_checksum;
-
-static inline void csum_init(csum_ctx_t *ctx)
-{
- EVP_DigestInit(ctx, EVP_md5());
-}
-
-static inline void csum_process(csum_ctx_t *ctx, unsigned char *buf, size_t len)
-{
- EVP_DigestUpdate(ctx, buf, len);
-}
-
-static inline void csum_finish(csum_ctx_t *ctx, csum_p csum)
-{
- EVP_DigestFinal(ctx, csum, NULL);
-}
-
-static inline int csum_valid(csum_p csum)
-{
- return memcmp(csum, bad_checksum, MAX_CSUM_SIZE);
-}
-
-static inline void csum_blob(apk_blob_t blob, csum_p csum)
-{
- EVP_Digest(blob.ptr, blob.len, csum, NULL, EVP_md5(), NULL);
-}
-
-#endif
diff --git a/src/apk_database.h b/src/apk_database.h
index 4235c56..b4c3f04 100644
--- a/src/apk_database.h
+++ b/src/apk_database.h
@@ -17,7 +17,8 @@
#include "apk_archive.h"
#include "apk_package.h"
-#define APK_MAX_REPOS 32
+#define APK_MAX_REPOS 32
+#define APK_CACHE_CSUM_BYTES 4
extern const char * const apk_index_gz;
@@ -29,8 +30,8 @@ struct apk_db_file {
struct hlist_node diri_files_list;
struct apk_db_dir_instance *diri;
- csum_t csum;
unsigned short namelen;
+ struct apk_checksum csum;
char name[];
};
@@ -73,7 +74,7 @@ struct apk_name {
struct apk_repository {
char *url;
- csum_t url_csum;
+ struct apk_checksum csum;
};
struct apk_database {
@@ -135,7 +136,7 @@ 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, csum_t sum);
+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);
int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo);
@@ -143,9 +144,10 @@ int apk_db_index_write(struct apk_database *db, struct apk_ostream *os);
int apk_db_add_repository(apk_database_t db, apk_blob_t repository);
int apk_repository_update(struct apk_database *db, struct apk_repository *repo);
-int apk_cache_download(struct apk_database *db, csum_t csum,
+int apk_cache_download(struct apk_database *db, struct apk_checksum *csum,
const char *url, const char *item);
-int apk_cache_exists(struct apk_database *db, csum_t csum, const char *item);
+int apk_cache_exists(struct apk_database *db, struct apk_checksum *csum,
+ const char *item);
int apk_db_install_pkg(struct apk_database *db,
struct apk_package *oldpkg,
diff --git a/src/apk_io.h b/src/apk_io.h
index 0ebf467..1fe4f2c 100644
--- a/src/apk_io.h
+++ b/src/apk_io.h
@@ -11,9 +11,10 @@
#ifndef APK_IO
#define APK_IO
+#include <openssl/evp.h>
+
#include "apk_defines.h"
#include "apk_blob.h"
-#include "apk_csum.h"
struct apk_file_info {
char *name;
@@ -26,7 +27,7 @@ struct apk_file_info {
mode_t mode;
time_t mtime;
dev_t device;
- csum_t csum;
+ struct apk_checksum csum;
};
struct apk_istream {
@@ -83,7 +84,7 @@ size_t apk_ostream_write_string(struct apk_ostream *ostream, const char *string)
apk_blob_t apk_blob_from_istream(struct apk_istream *istream, size_t size);
apk_blob_t apk_blob_from_file(const char *file);
-int apk_file_get_info(const char *filename, struct apk_file_info *fi);
+int apk_file_get_info(const char *filename, int checksum, struct apk_file_info *fi);
int apk_url_download(const char *url, const char *file);
const char *apk_url_local_file(const char *url);
diff --git a/src/apk_package.h b/src/apk_package.h
index a6e4784..bec495b 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -4,7 +4,7 @@
* Copyright (C) 2008 Timo Teräs <timo.teras@iki.fi>
* All rights reserved.
*
- * This program is free software; you can redistribute it and/or modify it
+ * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation. See http://www.gnu.org/ for details.
*/
@@ -52,7 +52,6 @@ APK_ARRAY(apk_dependency_array, struct apk_dependency);
struct apk_package {
apk_hash_node hash_node;
- csum_t csum;
unsigned repos;
struct apk_name *name;
char *version;
@@ -60,6 +59,7 @@ struct apk_package {
struct apk_dependency_array *depends;
size_t installed_size, size;
char *filename;
+ struct apk_checksum csum;
/* for installed packages only */
struct list_head installed_pkgs_list;
@@ -68,6 +68,8 @@ struct apk_package {
};
APK_ARRAY(apk_package_array, struct apk_package *);
+extern const char *apk_script_types[];
+
int apk_deps_add(struct apk_dependency_array **depends,
struct apk_dependency *dep);
void apk_deps_del(struct apk_dependency_array **deps,
diff --git a/src/archive.c b/src/archive.c
index 450c956..0a53792 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -44,19 +44,34 @@ struct tar_header {
char padding[12]; /* 500-512 */
};
-#define GET_OCTAL(s) get_octal(s, sizeof(s))
+#define GET_OCTAL(s) get_octal(s, sizeof(s))
+#define PUT_OCTAL(s,v) put_octal(s, sizeof(s), v)
+
static int get_octal(char *s, size_t l)
{
apk_blob_t b = APK_BLOB_PTR_LEN(s, l);
return apk_blob_pull_uint(&b, 8);
}
+static void put_octal(char *s, size_t l, size_t value)
+{
+ char *ptr = &s[l - 1];
+
+ *(ptr--) = '\0';
+ while (value != 0 && ptr >= s) {
+ *(ptr--) = '0' + (value % 8);
+ value /= 8;
+ }
+ while (ptr >= s)
+ *(ptr--) = '0';
+}
+
struct apk_tar_entry_istream {
struct apk_istream is;
struct apk_istream *tar_is;
size_t bytes_left;
- csum_ctx_t csum_ctx;
- csum_p csum;
+ EVP_MD_CTX mdctx;
+ struct apk_checksum *csum;
};
static size_t tar_entry_read(void *stream, void *ptr, size_t size)
@@ -69,9 +84,11 @@ static size_t tar_entry_read(void *stream, void *ptr, size_t size)
size = teis->tar_is->read(teis->tar_is, ptr, size);
if (size > 0) {
teis->bytes_left -= size;
- csum_process(&teis->csum_ctx, ptr, size);
- if (teis->bytes_left == 0)
- csum_finish(&teis->csum_ctx, teis->csum);
+ EVP_DigestUpdate(&teis->mdctx, ptr, size);
+ if (teis->bytes_left == 0) {
+ teis->csum->type = EVP_MD_CTX_size(&teis->mdctx);
+ EVP_DigestFinal_ex(&teis->mdctx, teis->csum->data, NULL);
+ }
}
return size;
}
@@ -83,13 +100,14 @@ int apk_parse_tar(struct apk_istream *is, apk_archive_entry_parser parser,
struct apk_tar_entry_istream teis = {
.is.read = tar_entry_read,
.tar_is = is,
- .csum = entry.csum,
+ .csum = &entry.csum,
};
struct tar_header buf;
unsigned long offset = 0;
int end = 0, r;
size_t toskip;
+ EVP_MD_CTX_init(&teis.mdctx);
memset(&entry, 0, sizeof(entry));
while ((r = is->read(is, &buf, 512)) == 512) {
offset += 512;
@@ -156,11 +174,11 @@ int apk_parse_tar(struct apk_istream *is, apk_archive_entry_parser parser,
entry.name = strdup(buf.name);
/* callback parser function */
- csum_init(&teis.csum_ctx);
+ EVP_DigestInit_ex(&teis.mdctx, apk_default_checksum(), NULL);
r = parser(ctx, &entry, &teis.is);
free(entry.name);
if (r != 0)
- return r;
+ goto err;
entry.name = NULL;
}
@@ -173,6 +191,7 @@ int apk_parse_tar(struct apk_istream *is, apk_archive_entry_parser parser,
if (toskip != 0)
is->read(is, NULL, toskip);
}
+ EVP_MD_CTX_cleanup(&teis.mdctx);
if (r != 0) {
apk_error("Bad TAR header (r=%d)", r);
@@ -180,6 +199,60 @@ int apk_parse_tar(struct apk_istream *is, apk_archive_entry_parser parser,
}
return 0;
+
+err:
+ EVP_MD_CTX_cleanup(&teis.mdctx);
+ return r;
+}
+
+int apk_write_tar_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) {
+ const unsigned char *src;
+ int chksum, i;
+
+ if (S_ISREG(ae->mode))
+ buf.typeflag = '0';
+ 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));
+
+ 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);
+
+ /* Checksum */
+ strcpy(buf.magic, "ustar ");
+ memset(buf.chksum, ' ', sizeof(buf.chksum));
+ src = (const unsigned char *) &buf;
+ for (i = chksum = 0; i < sizeof(buf); i++)
+ chksum += src[i];
+ put_octal(buf.chksum, sizeof(buf.chksum)-1, chksum);
+ }
+
+ if (os->write(os, &buf, sizeof(buf)) != sizeof(buf))
+ return -1;
+
+ 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)
+ return -1;
+ }
+
+ return 0;
}
int apk_parse_tar_gz(struct apk_bstream *bs, apk_archive_entry_parser parser,
diff --git a/src/audit.c b/src/audit.c
index 7a34f15..2c5a17a 100644
--- a/src/audit.c
+++ b/src/audit.c
@@ -46,7 +46,7 @@ static int audit_directory(apk_hash_item item, void *ctx)
snprintf(tmp, sizeof(tmp), "%s/%s", dbd->name, de->d_name);
- if (apk_file_get_info(tmp, &fi) < 0)
+ if (apk_file_get_info(tmp, APK_CHECKSUM_NONE, &fi) < 0)
continue;
if (S_ISDIR(fi.mode)) {
@@ -57,8 +57,10 @@ static int audit_directory(apk_hash_item item, void *ctx)
} else {
dbf = apk_db_file_query(db, bdir, APK_BLOB_STR(de->d_name));
if (dbf != NULL) {
- if (apk_blob_compare(APK_BLOB_BUF(fi.csum),
- APK_BLOB_BUF(dbf->csum)) == 0)
+ if (apk_file_get_info(tmp, dbf->csum.type, &fi) < 0)
+ continue;
+
+ if (apk_checksum_compare(&fi.csum, &dbf->csum) == 0)
continue;
reason = 'U';
diff --git a/src/blob.c b/src/blob.c
index 73d39ec..ed7f418 100644
--- a/src/blob.c
+++ b/src/blob.c
@@ -186,6 +186,30 @@ void apk_blob_push_uint(apk_blob_t *to, unsigned int value, int radix)
apk_blob_push_blob(to, APK_BLOB_PTR_PTR(ptr+1, &buf[sizeof(buf)-1]));
}
+static int checksum_char_to_id(char chr)
+{
+ switch (chr) {
+ case '1': return APK_CHECKSUM_SHA1;
+ }
+ return APK_CHECKSUM_NONE;
+}
+
+void apk_blob_push_csum(apk_blob_t *to, struct apk_checksum *csum)
+{
+ switch (csum->type) {
+ case APK_CHECKSUM_MD5:
+ apk_blob_push_hexdump(to, APK_BLOB_CSUM(*csum));
+ break;
+ case APK_CHECKSUM_SHA1:
+ apk_blob_push_blob(to, APK_BLOB_STR("X1"));
+ apk_blob_push_hexdump(to, APK_BLOB_CSUM(*csum));
+ break;
+ default:
+ *to = APK_BLOB_NULL;
+ break;
+ }
+}
+
void apk_blob_push_hexdump(apk_blob_t *to, apk_blob_t binary)
{
char *d;
@@ -239,6 +263,31 @@ unsigned int apk_blob_pull_uint(apk_blob_t *b, int radix)
return val;
}
+void apk_blob_pull_csum(apk_blob_t *b, struct apk_checksum *csum)
+{
+ if (unlikely(APK_BLOB_IS_NULL(*b)))
+ return;
+
+ if (unlikely(b->len < 2)) {
+ *b = APK_BLOB_NULL;
+ return;
+ }
+
+ switch (b->ptr[0]) {
+ case 'X':
+ csum->type = checksum_char_to_id(b->ptr[1]);
+ b->ptr += 2;
+ b->len -= 2;
+ apk_blob_pull_hexdump(b, APK_BLOB_CSUM(*csum));
+ break;
+ default:
+ /* Assume MD5 for backwards compatibility */
+ csum->type = APK_CHECKSUM_MD5;
+ apk_blob_pull_hexdump(b, APK_BLOB_CSUM(*csum));
+ break;
+ }
+}
+
void apk_blob_pull_hexdump(apk_blob_t *b, apk_blob_t to)
{
char *s, *d;
diff --git a/src/cache.c b/src/cache.c
index 423af72..a5643c4 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -46,13 +46,13 @@ static int cache_download(struct apk_database *db)
pkg = change->newpkg;
snprintf(pkgfile, sizeof(pkgfile), "%s-%s.apk",
pkg->name->name, pkg->version);
- if (apk_cache_exists(db, pkg->csum, pkgfile))
+ if (apk_cache_exists(db, &pkg->csum, pkgfile))
continue;
for (i = 0; i < db->num_repos; i++) {
if (!(pkg->repos & BIT(i)))
continue;
- r = apk_cache_download(db, pkg->csum, db->repos[i].url,
+ r = apk_cache_download(db, &pkg->csum, db->repos[i].url,
pkgfile);
if (r != 0)
return r;
@@ -68,11 +68,9 @@ static int cache_clean(struct apk_database *db)
{
DIR *dir;
struct dirent *de;
- struct apk_package *pkg;
- char path[256];
+ char path[256], csum[APK_CACHE_CSUM_BYTES];
int delete, i;
apk_blob_t b;
- csum_t csum;
snprintf(path, sizeof(path), "%s/%s", db->root, db->cache_dir);
if (chdir(path) != 0)
@@ -87,24 +85,25 @@ static int cache_clean(struct apk_database *db)
continue;
delete = TRUE;
do {
- if (strlen(de->d_name) <= sizeof(csum_t)*2+2)
+ if (strlen(de->d_name) <= APK_CACHE_CSUM_BYTES*2+2)
break;
- b = APK_BLOB_PTR_LEN(de->d_name, sizeof(csum_t) * 2);
+ b = APK_BLOB_PTR_LEN(de->d_name, APK_CACHE_CSUM_BYTES*2);
apk_blob_pull_hexdump(&b, APK_BLOB_BUF(csum));
if (APK_BLOB_IS_NULL(b))
break;
- if (de->d_name[sizeof(csum_t)*2] != '.')
+ if (de->d_name[APK_CACHE_CSUM_BYTES*2] != '.')
break;
- if (strcmp(&de->d_name[sizeof(csum_t)*2+1],
+ if (strcmp(&de->d_name[APK_CACHE_CSUM_BYTES*2+1],
apk_index_gz) == 0) {
/* Index - check for matching repository */
for (i = 0; i < db->num_repos; i++)
- if (memcmp(db->repos[i].url_csum,
- csum, sizeof(csum_t)) == 0)
+ if (memcmp(db->repos[i].csum.data,
+ csum, APK_CACHE_CSUM_BYTES) == 0)
break;
delete = (i >= db->num_repos);
} else {
/* Package - search for it */
+#if 0
pkg = apk_db_get_pkg(db, csum);
if (pkg == NULL)
break;
@@ -113,6 +112,8 @@ static int cache_clean(struct apk_database *db)
pkg->name->name, pkg->version);
delete = strcmp(&de->d_name[sizeof(csum_t)*2+1],
path);
+#endif
+//#warning FIXME - need to check if cache file is valid - look up using name, check csum
}
} while (0);
diff --git a/src/database.c b/src/database.c
index de03385..c80e9a9 100644
--- a/src/database.c
+++ b/src/database.c
@@ -36,7 +36,7 @@ struct install_ctx {
int script;
struct apk_db_dir_instance *diri;
- csum_t data_csum;
+ struct apk_checksum data_csum;
apk_progress_cb cb;
void *cb_ctx;
@@ -69,7 +69,7 @@ static const struct apk_hash_ops pkg_name_hash_ops = {
static apk_blob_t pkg_info_get_key(apk_hash_item item)
{
- return APK_BLOB_BUF(((struct apk_package *) item)->csum);
+ return APK_BLOB_CSUM(((struct apk_package *) item)->csum);
}
static unsigned long csum_hash(apk_blob_t csum)
@@ -372,7 +372,7 @@ struct apk_package *apk_db_pkg_add(struct apk_database *db, struct apk_package *
{
struct apk_package *idb;
- idb = apk_hash_get(&db->available.packages, APK_BLOB_BUF(pkg->csum));
+ idb = apk_hash_get(&db->available.packages, APK_BLOB_CSUM(pkg->csum));
if (idb == NULL) {
idb = pkg;
apk_hash_insert(&db->available.packages, pkg);
@@ -473,8 +473,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
apk_error("FDB checksum entry before file entry");
return -1;
}
-
- apk_blob_pull_hexdump(&l, APK_BLOB_BUF(file->csum));
+ apk_blob_pull_csum(&l, &file->csum);
break;
default:
apk_error("FDB entry '%c' unsupported", field);
@@ -518,9 +517,9 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
hlist_for_each_entry(file, c2, &diri->owned_files, diri_files_list) {
apk_blob_push_blob(&bbuf, APK_BLOB_STR("R:"));
apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN(file->name, file->namelen));
- if (csum_valid(file->csum)) {
+ if (file->csum.type != APK_CHECKSUM_NONE) {
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nZ:"));
- apk_blob_push_hexdump(&bbuf, APK_BLOB_BUF(file->csum));
+ apk_blob_push_csum(&bbuf, &file->csum);
}
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
@@ -538,50 +537,118 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
return 0;
}
-struct apk_script_header {
- csum_t csum;
- unsigned int type;
- unsigned int size;
-};
-
static int apk_db_scriptdb_write(struct apk_database *db, struct apk_ostream *os)
{
struct apk_package *pkg;
struct apk_script *script;
- struct apk_script_header hdr;
struct hlist_node *c2;
+ struct apk_file_info fi;
+ char filename[256];
+ apk_blob_t bfn;
+ int r, i;
list_for_each_entry(pkg, &db->installed.packages, installed_pkgs_list) {
hlist_for_each_entry(script, c2, &pkg->scripts, script_list) {
- memcpy(hdr.csum, pkg->csum, sizeof(csum_t));
- hdr.type = script->type;
- hdr.size = script->size;
-
- if (os->write(os, &hdr, sizeof(hdr)) != sizeof(hdr))
- return -1;
-
- if (os->write(os, script->script, script->size) != script->size)
- return -1;
+ 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 */
+ bfn = APK_BLOB_BUF(filename);
+ apk_blob_push_blob(&bfn, APK_BLOB_STR(pkg->name->name));
+ apk_blob_push_blob(&bfn, APK_BLOB_STR("-"));
+ apk_blob_push_blob(&bfn, APK_BLOB_STR(pkg->version));
+ apk_blob_push_blob(&bfn, APK_BLOB_STR("."));
+ apk_blob_push_csum(&bfn, &pkg->csum);
+ apk_blob_push_blob(&bfn, APK_BLOB_STR("."));
+ 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);
+ 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;
}
-static int apk_db_scriptdb_read(struct apk_database *db, struct apk_istream *is)
+static int apk_db_scriptdb_read_v1(struct apk_database *db, struct apk_istream *is)
{
struct apk_package *pkg;
- struct apk_script_header hdr;
+ struct {
+ unsigned char md5sum[16];
+ unsigned int type;
+ unsigned int size;
+ } hdr;
+ struct apk_checksum csum;
while (is->read(is, &hdr, sizeof(hdr)) == sizeof(hdr)) {
- pkg = apk_db_get_pkg(db, hdr.csum);
+ memcpy(csum.data, hdr.md5sum, sizeof(hdr.md5sum));
+ csum.type = APK_CHECKSUM_MD5;
+
+ pkg = apk_db_get_pkg(db, &csum);
if (pkg != NULL)
apk_pkg_add_script(pkg, is, hdr.type, hdr.size);
+ else
+ apk_istream_skip(is, hdr.size);
}
return 0;
}
+static int apk_read_script_archive_entry(void *ctx,
+ const struct apk_file_info *ae,
+ struct apk_istream *is)
+{
+ struct apk_database *db = (struct apk_database *) ctx;
+ struct apk_package *pkg;
+ char *fncsum, *fnaction;
+ struct apk_checksum csum;
+ apk_blob_t blob;
+ int type;
+
+ if (!S_ISREG(ae->mode))
+ return 0;
+
+ /* The scripts db expects file names in format:
+ * pkgname-version.<hexdump of package checksum>.action */
+ fnaction = memrchr(ae->name, '.', strlen(ae->name));
+ if (fnaction == NULL || fnaction == ae->name)
+ return 0;
+ fncsum = memrchr(ae->name, '.', fnaction - ae->name - 1);
+ if (fncsum == NULL)
+ return 0;
+ fnaction++;
+ fncsum++;
+
+ /* Parse it */
+ type = apk_script_type(fnaction);
+ if (type == APK_SCRIPT_INVALID)
+ return 0;
+ blob = APK_BLOB_PTR_PTR(fncsum, fnaction - 2);
+ apk_blob_pull_csum(&blob, &csum);
+
+ /* Attach script */
+ pkg = apk_db_get_pkg(db, &csum);
+ if (pkg != NULL)
+ apk_pkg_add_script(pkg, is, type, ae->size);
+
+ return 0;
+}
+
static int apk_db_read_state(struct apk_database *db, int flags)
{
struct apk_istream *is;
@@ -619,11 +686,16 @@ 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");
+ is = apk_istream_from_file("var/lib/apk/scripts.tar");
if (is != NULL) {
- apk_db_scriptdb_read(db, is);
- is->close(is);
+ apk_parse_tar(is, apk_read_script_archive_entry, db);
+ } else {
+ is = apk_istream_from_file("var/lib/apk/scripts");
+ if (is != NULL)
+ apk_db_scriptdb_read_v1(db, is);
}
+ if (is != NULL)
+ is->close(is);
}
return 0;
@@ -817,11 +889,15 @@ int apk_db_write_config(struct apk_database *db)
if (rename("var/lib/apk/installed.new", "var/lib/apk/installed") < 0)
return -errno;
- os = apk_ostream_to_file("var/lib/apk/scripts", 0644);
+ os = apk_ostream_to_file("var/lib/apk/scripts.tar.new", 0644);
if (os == NULL)
return -1;
apk_db_scriptdb_write(db, os);
os->close(os);
+ if (rename("var/lib/apk/scripts.tar.new", "var/lib/apk/scripts.tar") < 0)
+ return -errno;
+
+ unlink("var/lib/apk/scripts");
return 0;
}
@@ -868,10 +944,10 @@ int apk_db_cache_active(struct apk_database *db)
return db->cache_dir != apk_static_cache_dir;
}
-struct apk_package *apk_db_get_pkg(struct apk_database *db, csum_t sum)
+struct apk_package *apk_db_get_pkg(struct apk_database *db,
+ struct apk_checksum *csum)
{
- return apk_hash_get(&db->available.packages,
- APK_BLOB_PTR_LEN((void*) sum, sizeof(csum_t)));
+ return apk_hash_get(&db->available.packages, APK_BLOB_CSUM(*csum));
}
struct apk_package *apk_db_get_file_owner(struct apk_database *db,
@@ -939,22 +1015,24 @@ int apk_db_index_write(struct apk_database *db, struct apk_ostream *os)
}
static void apk_db_cache_get_name(char *buf, size_t bufsz,
- struct apk_database *db, csum_t csum,
+ struct apk_database *db,
+ struct apk_checksum *csum,
const char *file, int temp)
{
- char csumstr[sizeof(csum_t)*2+1];
+ char csumstr[APK_CACHE_CSUM_BYTES*2+1];
apk_blob_t bbuf = APK_BLOB_BUF(csumstr);
apk_blob_push_hexdump(&bbuf,
- APK_BLOB_PTR_LEN((void *)csum, sizeof(csum_t)));
- apk_blob_push_blob(&bbuf, APK_BLOB_STR(""));
+ APK_BLOB_PTR_LEN((char *) csum->data, APK_CACHE_CSUM_BYTES));
+ apk_blob_push_blob(&bbuf, APK_BLOB_PTR_LEN("", 1));
snprintf(buf, bufsz, "%s/%s/%s.%s%s",
db->root, db->cache_dir, csumstr, file, temp ? ".new" : "");
}
static struct apk_bstream *apk_db_cache_open(struct apk_database *db,
- csum_t csum, const char *file)
+ struct apk_checksum *csum,
+ const char *file)
{
char tmp[256];
@@ -975,7 +1053,7 @@ static struct apk_bstream *apk_repository_file_open(struct apk_repository *repo,
return apk_bstream_from_url(tmp);
}
-int apk_cache_download(struct apk_database *db, csum_t csum,
+int apk_cache_download(struct apk_database *db, struct apk_checksum *csum,
const char *url, const char *item)
{
char tmp[256], tmp2[256];
@@ -999,7 +1077,8 @@ int apk_cache_download(struct apk_database *db, csum_t csum,
return 0;
}
-int apk_cache_exists(struct apk_database *db, csum_t csum, const char *item)
+int apk_cache_exists(struct apk_database *db, struct apk_checksum *csum,
+ const char *item)
{
char tmp[256];
@@ -1012,10 +1091,10 @@ int apk_cache_exists(struct apk_database *db, csum_t csum, const char *item)
int apk_repository_update(struct apk_database *db, struct apk_repository *repo)
{
- if (!csum_valid(repo->url_csum))
+ if (repo->csum.type == APK_CHECKSUM_NONE)
return 0;
- return apk_cache_download(db, repo->url_csum, repo->url, apk_index_gz);
+ return apk_cache_download(db, &repo->csum, repo->url, apk_index_gz);
}
int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
@@ -1040,19 +1119,18 @@ int apk_db_add_repository(apk_database_t _db, apk_blob_t repository)
};
if (apk_url_local_file(repo->url) == NULL) {
- csum_blob(repository, repo->url_csum);
+ apk_blob_checksum(repository, apk_default_checksum(), &repo->csum);
if (apk_flags & APK_UPDATE_CACHE)
n = apk_repository_update(db, repo);
- bs = apk_db_cache_open(db, repo->url_csum, apk_index_gz);
+ bs = apk_db_cache_open(db, &repo->csum, apk_index_gz);
if (bs == NULL) {
if (n == 1)
n = apk_repository_update(db, repo);
if (n < 0)
return n;
- bs = apk_db_cache_open(db, repo->url_csum,
- apk_index_gz);
+ bs = apk_db_cache_open(db, &repo->csum, apk_index_gz);
}
} else {
bs = apk_repository_file_open(repo, apk_index_gz);
@@ -1203,9 +1281,8 @@ static int apk_db_install_archive_entry(void *_ctx,
printf("%s\n", ae->name);
if ((diri->dir->flags & APK_DBDIRF_PROTECTED) &&
- apk_file_get_info(ae->name, &fi) == 0 &&
- (memcmp(file->csum, fi.csum, sizeof(csum_t)) != 0 ||
- !csum_valid(file->csum))) {
+ apk_file_get_info(ae->name, file->csum.type, &fi) == 0 &&
+ apk_checksum_compare(&file->csum, &fi.csum) != 0) {
/* Protected file. Extract to separate place */
if (!(apk_flags & APK_CLEAN_PROTECTED)) {
snprintf(alt_name, sizeof(alt_name),
@@ -1213,15 +1290,18 @@ static int apk_db_install_archive_entry(void *_ctx,
diri->dir->name, file->name);
r = apk_archive_entry_extract(ae, is, alt_name,
extract_cb, ctx);
+
/* remove identical apk-new */
- if (memcmp(ae->csum, fi.csum, sizeof(csum_t)) == 0)
+ if (ae->csum.type != fi.csum.type)
+ apk_file_get_info(ae->name, ae->csum.type, &fi);
+ if (apk_checksum_compare(&ae->csum, &fi.csum) == 0)
unlink(alt_name);
}
} else {
r = apk_archive_entry_extract(ae, is, NULL,
extract_cb, ctx);
}
- memcpy(file->csum, ae->csum, sizeof(csum_t));
+ memcpy(&file->csum, &ae->csum, sizeof(file->csum));
} else {
if (apk_verbosity > 1)
printf("%s\n", ae->name);
@@ -1286,7 +1366,8 @@ static int apk_db_gzip_part(void *pctx, EVP_MD_CTX *mdctx, int part)
EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
break;
case APK_MPART_END:
- EVP_DigestFinal_ex(mdctx, ctx->data_csum, NULL);
+ ctx->data_csum.type = EVP_MD_CTX_size(mdctx);
+ EVP_DigestFinal_ex(mdctx, ctx->data_csum.data, NULL);
break;
}
return 0;
@@ -1320,14 +1401,15 @@ static int apk_db_unpack_pkg(struct apk_database *db,
}
repo = &db->repos[i];
- if (apk_db_cache_active(db) && csum_valid(repo->url_csum))
- bs = apk_db_cache_open(db, newpkg->csum, pkgname);
+ if (apk_db_cache_active(db) &&
+ repo->csum.type != APK_CHECKSUM_NONE)
+ bs = apk_db_cache_open(db, &newpkg->csum, pkgname);
if (bs == NULL) {
snprintf(file, sizeof(file), "%s/%s",
repo->url, pkgname);
bs = apk_bstream_from_url(file);
- if (csum_valid(repo->url_csum))
+ if (repo->csum.type != APK_CHECKSUM_NONE)
need_copy = TRUE;
}
} else {
@@ -1337,7 +1419,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
if (!apk_db_cache_active(db))
need_copy = FALSE;
if (need_copy) {
- apk_db_cache_get_name(file, sizeof(file), db, newpkg->csum,
+ apk_db_cache_get_name(file, sizeof(file), db, &newpkg->csum,
pkgname, TRUE);
bs = apk_bstream_tee(bs, file);
}
@@ -1362,7 +1444,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
bs->close(bs, &length);
/* Check the package checksum */
- if (memcmp(ctx.data_csum, newpkg->csum, sizeof(csum_t)) != 0)
+ if (apk_checksum_compare(&ctx.data_csum, &newpkg->csum) != 0)
apk_warning("%s-%s: checksum does not match",
newpkg->name->name, newpkg->version);
@@ -1370,7 +1452,7 @@ static int apk_db_unpack_pkg(struct apk_database *db,
if (length == newpkg->size) {
char file2[256];
apk_db_cache_get_name(file2, sizeof(file2), db,
- newpkg->csum, pkgname, FALSE);
+ &newpkg->csum, pkgname, FALSE);
rename(file, file2);
} else {
unlink(file);
diff --git a/src/io.c b/src/io.c
index 26c0ebf..335b14d 100644
--- a/src/io.c
+++ b/src/io.c
@@ -440,11 +440,10 @@ err_fd:
return APK_BLOB_NULL;
}
-int apk_file_get_info(const char *filename, struct apk_file_info *fi)
+int apk_file_get_info(const char *filename, int checksum, struct apk_file_info *fi)
{
struct stat st;
struct apk_bstream *bs;
- csum_ctx_t ctx;
if (stat(filename, &st) != 0)
return -1;
@@ -458,14 +457,19 @@ int apk_file_get_info(const char *filename, struct apk_file_info *fi)
.device = st.st_dev,
};
+ if (checksum == APK_CHECKSUM_NONE)
+ return 0;
+
bs = apk_bstream_from_file(filename);
if (bs != NULL) {
+ EVP_MD_CTX mdctx;
apk_blob_t blob;
- csum_init(&ctx);
+ EVP_DigestInit(&mdctx, apk_get_digest(checksum));
while (!APK_BLOB_IS_NULL(blob = bs->read(bs, APK_BLOB_NULL)))
- csum_process(&ctx, (void*) blob.ptr, blob.len);
- csum_finish(&ctx, fi->csum);
+ EVP_DigestUpdate(&mdctx, (void*) blob.ptr, blob.len);
+ fi->csum.type = EVP_MD_CTX_size(&mdctx);
+ EVP_DigestFinal(&mdctx, fi->csum.data, NULL);
bs->close(bs, NULL);
}
diff --git a/src/package.c b/src/package.c
index c6c6737..bb37317 100644
--- a/src/package.c
+++ b/src/package.c
@@ -230,7 +230,7 @@ int apk_deps_write(struct apk_dependency_array *deps, struct apk_ostream *os)
return n;
}
-static const char *script_types[] = {
+const char *apk_script_types[] = {
[APK_SCRIPT_PRE_INSTALL] = "pre-install",
[APK_SCRIPT_POST_INSTALL] = "post-install",
[APK_SCRIPT_PRE_DEINSTALL] = "pre-deinstall",
@@ -252,9 +252,9 @@ int apk_script_type(const char *name)
{
int i;
- for (i = 0; i < ARRAY_SIZE(script_types); i++)
- if (script_types[i] &&
- strcmp(script_types[i], name) == 0)
+ for (i = 0; i < ARRAY_SIZE(apk_script_types); i++)
+ if (apk_script_types[i] &&
+ strcmp(apk_script_types[i], name) == 0)
return i;
return APK_SCRIPT_INVALID;
@@ -290,7 +290,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
apk_deps_parse(db, &pkg->depends, value);
break;
case 'C':
- apk_blob_pull_hexdump(&value, APK_BLOB_BUF(pkg->csum));
+ apk_blob_pull_csum(&value, &pkg->csum);
break;
case 'S':
pkg->size = apk_blob_pull_uint(&value, 10);
@@ -426,7 +426,8 @@ static int apk_pkg_gzip_part(void *ctx, EVP_MD_CTX *mdctx, int part)
EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
break;
case APK_MPART_END:
- EVP_DigestFinal_ex(mdctx, ri->pkg->csum, NULL);
+ ri->pkg->csum.type = EVP_MD_CTX_size(mdctx);
+ EVP_DigestFinal_ex(mdctx, ri->pkg->csum.data, NULL);
break;
}
return 0;
@@ -572,7 +573,7 @@ int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
snprintf(fn, sizeof(fn),
"tmp/%s-%s.%s",
pkg->name->name, pkg->version,
- script_types[type]);
+ apk_script_types[type]);
fd = creat(fn, 0777);
if (fd < 0)
return fd;
@@ -591,7 +592,7 @@ int apk_pkg_run_script(struct apk_package *pkg, int root_fd,
execle(fn, "INSTALL", script_types2[type],
pkg->version, "", NULL, environment);
} else {
- execle(fn, script_types[type],
+ execle(fn, apk_script_types[type],
pkg->version, "", NULL, environment);
}
exit(1);
@@ -649,7 +650,7 @@ int apk_pkg_write_index_entry(struct apk_package *info,
int r;
apk_blob_push_blob(&bbuf, APK_BLOB_STR("C:"));
- apk_blob_push_hexdump(&bbuf, APK_BLOB_BUF(info->csum));
+ apk_blob_push_csum(&bbuf, &info->csum);
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nP:"));
apk_blob_push_blob(&bbuf, APK_BLOB_STR(info->name->name));
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nV:"));