Beispiel #1
0
static void
send_error_packet(int to_peer, int err, const char* msg)
{
    size_t msg_size = strlen(msg);
    if (msg_size > UINT16_MAX)
        msg_size = UINT16_MAX;
    struct xfer_msg m = {
        .type = XFER_MSG_ERROR,
        .u.error.err = err,
        .u.error.msg_size = msg_size,
    };
    send_xfer_msg(to_peer, &m);
    write_all(to_peer, msg, msg_size);
}

int
xfer_stub_main(const struct cmd_xfer_stub_info* info)
{
    struct xfer_ctx ctx = {
        .from_peer = STDIN_FILENO,
        .to_peer = STDOUT_FILENO,
        .info = info,
    };

    struct errinfo ei = {
        .want_msg = true
    };

    if (catch_error(do_xfer, &ctx, &ei)) {
        send_error_packet(ctx.to_peer, ei.err, ei.msg);
        return 1;
    }

    return 0;
}

#if FBADB_MAIN
int
xfer_handle_command(
    const struct start_peer_info* spi,
    const struct cmd_xfer_stub_info* local,
    const struct cmd_xfer_stub_info* remote)
{
    struct child* peer = start_peer(
        spi,
        make_args_cmd_xfer_stub(
            CMD_ARG_NAME | CMD_ARG_FORWARDED,
            remote));

    struct xfer_ctx ctx = {
        .from_peer = peer->fd[1]->fd,
        .to_peer = peer->fd[0]->fd,
        .info = local,
    };

    do_xfer(&ctx);
    return child_status_to_exit_code(child_wait(peer));
}
Beispiel #2
0
static void
compile_dex_with_dexopt(const char* dex_file_name,
                        const char* odex_file_name)
{
    SCOPED_RESLIST(rl);

    int dex_file = xopen(dex_file_name, O_RDONLY, 0);
    const char* odex_temp_filename = xaprintf(
        "%s.tmp.%s",
        odex_file_name,
        gen_hex_random(ENOUGH_ENTROPY));
    cleanup_commit(cleanup_allocate(), cleanup_tmpfile, odex_temp_filename);
    int odex_temp_file = xopen(odex_temp_filename,
                               O_RDWR | O_CREAT | O_EXCL,
                               0644);

    allow_inherit(dex_file);
    allow_inherit(odex_temp_file);

    struct child_start_info csi = {
        .io[0] = CHILD_IO_DEV_NULL,
        .io[1] = CHILD_IO_PIPE,
        .io[2] = CHILD_IO_DUP_TO_STDOUT,
        .exename = "dexopt",
        .argv = ARGV(
            "dexopt",
            "--zip",
            xaprintf("%d", dex_file),
            xaprintf("%d", odex_temp_file),
            dex_file_name,
            "v=ao=fm=y"),
    };

    struct child* dexopt = child_start(&csi);
    struct growable_buffer output = slurp_fd_buf(dexopt->fd[1]->fd);
    int status = child_status_to_exit_code(child_wait(dexopt));
    if (status != 0)
        die(EINVAL,
            "dexopt failed: %s",
            massage_output_buf(output));

    xrename(odex_temp_filename, odex_file_name);
}

static void
compile_dex(const char* dex_file_name,
            const char* odex_file_name)
{
    if (api_level() < 21)
        compile_dex_with_dexopt(dex_file_name, odex_file_name);
}

int
rdex_main(const struct cmd_rdex_info* info)
{
    const char* dex_file_name = info->dexfile;
    struct stat dex_stat = xstat(dex_file_name);
    const char* odex_file_name = make_odex_name(dex_file_name);

    bool need_recompile = true;

    struct stat odex_stat;
    if (stat(odex_file_name, &odex_stat) == 0 &&
        dex_stat.st_mtime <= odex_stat.st_mtime)
    {
        need_recompile = false;
    }

    (void) need_recompile;
    (void) odex_file_name;
    (void) compile_dex;

    if (need_recompile)
        compile_dex(dex_file_name, odex_file_name);

    if (setenv("CLASSPATH", dex_file_name, 1) == -1)
        die_errno("setenv");

    if (info->classname[0] == '-')
        die(EINVAL, "class name cannot begin with '-'");

    execvp("app_process",
           (char* const*)
           ARGV_CONCAT(
               ARGV("app_process",
                    xdirname(dex_file_name),
                    info->classname),
               info->args ?: empty_argv));
    die_errno("execvp(\"app_process\", ...");
}