summaryrefslogtreecommitdiff
path: root/src/app_adbsign.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2020-09-30 14:11:37 +0300
committerTimo Teräs <timo.teras@iki.fi>2020-10-09 16:09:19 +0300
commitefe0c4afecb9fd3da2ab4849d2b8edd5bea14d08 (patch)
treeb04a9d2533148a1fcb4a28560ffd76c4bbc5e5ad /src/app_adbsign.c
parent81782bfc150225df75b11efa4fa0ade428ae3676 (diff)
downloadapk-tools-efe0c4afecb9fd3da2ab4849d2b8edd5bea14d08.tar.gz
apk-tools-efe0c4afecb9fd3da2ab4849d2b8edd5bea14d08.tar.bz2
apk-tools-efe0c4afecb9fd3da2ab4849d2b8edd5bea14d08.tar.xz
apk-tools-efe0c4afecb9fd3da2ab4849d2b8edd5bea14d08.zip
adb: introduce apk-tools database format, and few applets
This is a flat buffers inspired format that allows fast mmaped access to the data with low overhead, signature support and relatively good forward support.
Diffstat (limited to 'src/app_adbsign.c')
-rw-r--r--src/app_adbsign.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/app_adbsign.c b/src/app_adbsign.c
new file mode 100644
index 0000000..6861776
--- /dev/null
+++ b/src/app_adbsign.c
@@ -0,0 +1,97 @@
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include "adb.h"
+#include "apk_applet.h"
+#include "apk_print.h"
+
+struct sign_ctx {
+ struct adb_xfrm xfrm;
+ struct apk_database *db;
+ int reset_signatures : 1;
+ int signatures_written : 1;
+};
+
+#define ADBSIGN_OPTIONS(OPT) \
+ OPT(OPT_ADBSIGN_reset_signatures, "reset-signatures")
+
+APK_OPT_APPLET(option_desc, ADBSIGN_OPTIONS);
+
+static int option_parse_applet(void *pctx, struct apk_db_options *dbopts, int optch, const char *optarg)
+{
+ struct sign_ctx *ctx = (struct sign_ctx *) pctx;
+
+ switch (optch) {
+ case OPT_ADBSIGN_reset_signatures:
+ ctx->reset_signatures = 1;
+ break;
+ default:
+ return -ENOTSUP;
+ }
+ return 0;
+}
+
+static const struct apk_option_group optgroup_applet = {
+ .desc = option_desc,
+ .parse = option_parse_applet,
+};
+
+static int update_signatures(struct adb_xfrm *xfrm, struct adb_block *blk, struct apk_istream *is)
+{
+ struct sign_ctx *ctx = container_of(xfrm, struct sign_ctx, xfrm);
+ int r;
+
+ switch (blk ? ADB_BLOCK_TYPE(blk) : -1) {
+ case ADB_BLOCK_ADB:
+ return adb_c_block_copy(xfrm->os, blk, is, &xfrm->vfy);
+ case ADB_BLOCK_SIG:
+ if (ctx->reset_signatures)
+ break;
+ return adb_c_block_copy(xfrm->os, blk, is, NULL);
+ default:
+ if (!ctx->signatures_written) {
+ ctx->signatures_written = 1;
+ r = adb_trust_write_signatures(&ctx->db->trust, &xfrm->db, &xfrm->vfy, xfrm->os);
+ if (r) return r;
+ }
+ if (!blk) break;
+ return adb_c_block_copy(xfrm->os, blk, is, NULL);
+ }
+ return 0;
+}
+
+static int adbsign_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
+{
+ char tmpname[PATH_MAX];
+ struct sign_ctx *ctx = pctx;
+ char **arg;
+ int r;
+
+ ctx->db = db;
+ foreach_array_item(arg, args) {
+ if (snprintf(tmpname, sizeof tmpname, "%s.tmp", *arg) >= sizeof tmpname) {
+ r = ENAMETOOLONG;
+ } else {
+ ctx->xfrm.is = apk_istream_from_file(AT_FDCWD, *arg);
+ ctx->xfrm.os = apk_ostream_to_file(AT_FDCWD, *arg, tmpname, 0644);
+ adb_c_xfrm(&ctx->xfrm, update_signatures);
+ apk_istream_close(ctx->xfrm.is);
+ r = apk_ostream_close(ctx->xfrm.os);
+ }
+ if (r) apk_error("%s: %s", *arg, apk_error_str(r));
+ }
+
+ return 0;
+}
+
+static struct apk_applet apk_adbsign = {
+ .name = "adbsign",
+ .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS,
+ .context_size = sizeof(struct sign_ctx),
+ .optgroups = { &optgroup_global, &optgroup_signing, &optgroup_applet },
+ .main = adbsign_main,
+};
+
+APK_DEFINE_APPLET(apk_adbsign);