aboutsummaryrefslogtreecommitdiffstats
path: root/src/app_adbsign.c
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2019-12-13 15:22:33 +0200
committerTimo Teräs <timo.teras@iki.fi>2020-02-28 23:18:52 +0200
commit9530fbfa044bedf5821ff5ffffb7d4f3994f603f (patch)
treea54a0dcc1eff93429c822fcb89dfaccb73ab6285 /src/app_adbsign.c
parentc054fbc11e9beca0d45285c3e1f448c81416c5ce (diff)
downloadapk-tools-v3.0-wip.tar.bz2
apk-tools-v3.0-wip.tar.xz
adb: introduce apk-tools database format, and few appletsv3.0-wip
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.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/app_adbsign.c b/src/app_adbsign.c
new file mode 100644
index 0000000..834d82a
--- /dev/null
+++ b/src/app_adbsign.c
@@ -0,0 +1,100 @@
+#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;
+};
+
+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 'R':
+ ctx->reset_signatures = 1;
+ break;
+ default:
+ return -ENOTSUP;
+ }
+ return 0;
+}
+
+static const struct apk_option options_applet[] = {
+ { 'R', "reset-signatures" },
+};
+
+static const struct apk_option_group optgroup_applet = {
+ .name = "Sign",
+ .options = options_applet,
+ .num_options = ARRAY_SIZE(options_applet),
+ .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",
+ .arguments = "FILE...",
+ .open_flags = APK_OPENF_READ | APK_OPENF_NO_STATE | APK_OPENF_NO_REPOS,
+ .command_groups = APK_COMMAND_GROUP_REPO,
+ .context_size = sizeof(struct sign_ctx),
+ .optgroups = { &optgroup_global, &optgroup_signing, &optgroup_applet },
+ .main = adbsign_main,
+};
+
+APK_DEFINE_APPLET(apk_adbsign);