rizin/librz/core/cmd/cmd_math.c
Riccardo Schirone 9d68e9614f
Fix old math commands (#3828)
* core/cmd: Adjust math commands

* shell: make `?x` commands a parsing failure

We have moved the `?x` commands to `%x`, thus now no command should
start with `?`. This patch makes the parser fail to parse `?x`
strings.

* core/tui: use APIs in panels

* There's no `%q` anymore, use `%=`
2023-09-14 08:53:25 +08:00

676 lines
22 KiB
C

// SPDX-FileCopyrightText: 2009-2020 pancake <pancake@nopcode.org>
// SPDX-License-Identifier: LGPL-3.0-only
#include <stddef.h>
#include <math.h> // required for signbit
#include "rz_cons.h"
#include "rz_core.h"
#include "rz_util.h"
#include "rz_types.h"
static const char *help_msg_greater_sign[] = {
"Usage:", "[cmd]>[file]", "redirects console from 'cmd' output to 'file'",
"[cmd] > [file]", "", "redirect STDOUT of 'cmd' to 'file'",
"[cmd] > $alias", "", "save the output of the command as an alias (see $?)",
"[cmd] H> [file]", "", "redirect html output of 'cmd' to 'file'",
"[cmd] 2> [file]", "", "redirect STDERR of 'cmd' to 'file'",
"[cmd] 2> /dev/null", "", "omit the STDERR output of 'cmd'",
NULL
};
struct rz_core_var {
const char *name;
const char *description;
};
struct rz_core_var core_vars[] = {
{ "$$", "here (current virtual seek)" },
{ "$$$", "current non-temporary virtual seek" },
{ "$?", "last comparison value" },
{ "$B", "base address (aligned lowest map address)" },
{ "$b", "block size" },
{ "$c", "get terminal width in character columns" },
{ "$Cn", "get nth call of function" },
{ "$D", "current debug map base address %v $D @ rsp" },
{ "$DB", "same as dbg.baddr, progam base address" },
{ "$DD", "current debug map size" },
{ "$Dn", "get nth data reference in function" },
{ "$e", "1 if end of block, else 0" },
{ "$f", "jump fail address (e.g. jz 0x10 => next instruction)" },
{ "$F", "Same as $FB" },
{ "$Fb", "begin of basic block" },
{ "$FB", "begin of function" },
{ "$Fe", "end of basic block" },
{ "$FE", "end of function" },
{ "$Ff", "function false destination" },
{ "$Fi", "basic block instructions" },
{ "$FI", "function instructions" },
{ "$Fj", "function jump destination" },
{ "$fl", "flag length (size) at current address (fla; pD $l @ entry0)" },
{ "$FS", "function size (linear length)" },
{ "$Fs", "size of the current basic block" },
{ "$FSS", "function size (sum bb sizes)" },
{ "$j", "jump address (e.g. jmp 0x10, jz 0x10 => 0x10)" },
{ "$Ja", "get nth jump of function" },
{ "$l", "opcode length" },
{ "$M", "map address (lowest map address)" },
{ "$m", "opcode memory reference (e.g. mov eax,[0x10] => 0x10)" },
{ "$MM", "map size (lowest map address)" },
{ "$O", "cursor here (current offset pointed by the cursor)" },
{ "$o", "here (current disk io offset)" },
{ "$p", "getpid()" },
{ "$P", "pid of children (only in debug)" },
{ "$r", "get console height (in rows, see $c for columns)" },
{ "$s", "file size" },
{ "$S", "section offset" },
{ "$SS", "section size" },
{ "$v", "opcode immediate value (e.g. lui a0,0x8010 => 0x8010)" },
{ "$w", "get word size, 4 if asm.bits=32, 8 if 64, ..." },
{ "$Xn", "get nth xref of function" },
};
struct rz_core_var help_core_vars[] = {
{ "flag", "offset of flag" },
{ "${ev}", "get value of eval <config variable <ev>" },
{ "$alias", "alias commands (simple macros)" },
{ "$e{flag}", "end of <flag> (flag->offset + flag->size)" },
{ "$k{kv}", "get value of an sdb query value" },
{ "$r{reg}", "get value of named register <reg>" },
{ "$s{flag}", "get size of <flag>" },
};
/**
* \brief Returns all the $ variable names in a NULL-terminated arr
*/
RZ_DEPRECATE RZ_API const char **rz_core_help_vars_get(RzCore *core) {
static const char *vars[] = {
"$$", "$$$", "$?", "$B", "$b", "$c", "$Cn", "$D", "$DB", "$DD", "$Dn",
"$e", "$f", "$F", "$Fb", "$FB", "$Fe", "$FE", "$Ff", "$Fi", "$FI", "$Fj",
"$fl", "$FS", "$Fs", "$FSS", "$j", "$Ja", "$l", "$M", "$m", "$MM", "$O",
"$o", "$p", "$P", "$r", "$s", "$S", "$SS", "$v", "$w", "$Xn", NULL
};
return vars;
}
RZ_DEPRECATE RZ_API void rz_core_help_vars_print(RzCore *core) {
rz_list_rizin_vars_handler(core, 0, NULL);
}
RZ_IPI RzCmdStatus rz_list_rizin_vars_handler(RzCore *core, int argc, const char **argv) {
const bool wideOffsets = rz_config_get_i(core->config, "scr.wideoff");
for (int i = 0; i < RZ_ARRAY_SIZE(core_vars); i++) {
struct rz_core_var *var = &core_vars[i];
if (argc > 1 && strcmp(argv[1], var->name)) {
continue;
}
const char *pad = rz_str_pad(' ', 6 - strlen(var->name));
if (wideOffsets) {
rz_cons_printf("%s %s 0x%016" PFMT64x "\n", var->name, pad, rz_num_math(core->num, var->name));
} else {
rz_cons_printf("%s %s 0x%08" PFMT64x "\n", var->name, pad, rz_num_math(core->num, var->name));
}
}
return RZ_CMD_STATUS_OK;
}
/**
* \brief If \p pj is NULL then standard output will be displayed
* If it's non-NULL then it's treated as a borrowed PJ and used and
* printing will be done in JSON format and not standard one.
* Hence the the third parameter decides in which format data will be displayed.
*
* \param core RzCore.
* \param input Input mathematical expression.
* \param pj Borrowed PJ if calculated value is to be printed in JSON format.
* \return true on success, false otherwise.
**/
RZ_IPI bool rz_core_cmd_calculate_expr(RZ_NONNULL RzCore *core, RZ_NONNULL const char *input, RZ_BORROW PJ *pj) {
rz_return_val_if_fail(core && input, false);
char unit[8];
char number[128], out[128] = RZ_EMPTY;
ut64 n = rz_num_math(core->num, input);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
core->num->dbz = 0;
return false;
}
/* decimal, hexa, octal */
ut32 s, a;
s = n >> 16 << 12;
a = n & 0x0fff;
rz_num_units(unit, sizeof(unit), n);
/* binary and floating point */
double d;
float f;
rz_str_bits64(out, n);
f = d = core->num->fvalue;
/* adjust sign for nan floats, different libcs are confused */
if (isnan(f) && signbit(f)) {
f = -f;
}
if (isnan(d) && signbit(d)) {
d = -d;
}
if (pj) {
;
pj_o(pj);
if (n >> 32) {
pj_ks(pj, "int32", rz_strf(number, "%d", (st32)(n & UT32_MAX)));
pj_ks(pj, "uint32", rz_strf(number, "%u", (ut32)n));
} else {
pj_ks(pj, "int64", rz_strf(number, "%" PFMT64d, (st64)n));
pj_ks(pj, "uint64", rz_strf(number, "%" PFMT64u, (ut64)n));
}
pj_ks(pj, "hex", rz_strf(number, "0x%08" PFMT64x, n));
pj_ks(pj, "octal", rz_strf(number, "0%" PFMT64o, n));
pj_ks(pj, "unit", unit);
pj_ks(pj, "segment", rz_strf(number, "%04x:%04x", s, a));
pj_ks(pj, "fvalue", rz_strf(number, "%.1lf", core->num->fvalue));
pj_ks(pj, "float", rz_strf(number, "%ff", f));
pj_ks(pj, "double", rz_strf(number, "%lf", d));
pj_ks(pj, "binary", rz_strf(number, "0b%s", out));
/* ternary */
rz_num_to_trits(out, n);
pj_ks(pj, "trits", rz_strf(number, "0t%s", out));
pj_end(pj);
} else {
if (n >> 32) {
rz_cons_printf("int64 %" PFMT64d "\n", (st64)n);
rz_cons_printf("uint64 %" PFMT64u "\n", (ut64)n);
} else {
rz_cons_printf("int32 %d\n", (st32)n);
rz_cons_printf("uint32 %u\n", (ut32)n);
}
rz_cons_printf("hex 0x%" PFMT64x "\n", n);
rz_cons_printf("octal 0%" PFMT64o "\n", n);
rz_cons_printf("unit %s\n", unit);
rz_cons_printf("segment %04x:%04x\n", s, a);
char *asnum = rz_num_as_string(NULL, n, false);
if (asnum) {
rz_cons_printf("string \"%s\"\n", asnum);
free(asnum);
}
rz_cons_printf("fvalue %.1lf\n", core->num->fvalue);
rz_cons_printf("float %ff\n", f);
rz_cons_printf("double %lf\n", d);
rz_cons_printf("binary 0b%s\n", out);
/* ternary*/
rz_num_to_trits(out, n);
rz_cons_printf("trits 0t%s\n", out);
}
return true;
}
RZ_IPI RzCmdStatus rz_calculate_expr_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
bool res;
if (state->mode == RZ_OUTPUT_MODE_JSON) {
res = rz_core_cmd_calculate_expr(core, argv[1], state->d.pj);
} else {
res = rz_core_cmd_calculate_expr(core, argv[1], NULL);
}
return res ? RZ_CMD_STATUS_OK : RZ_CMD_STATUS_ERROR;
}
RZ_IPI RzCmdStatus rz_set_active_tab_zero_handler(RzCore *core, int argc, const char **argv) {
core->curtab = 0;
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_set_active_tab_next_handler(RzCore *core, int argc, const char **argv) {
if (core->curtab < 0) {
core->curtab = 0;
}
core->curtab++;
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_generate_random_number_handler(RzCore *core, int argc, const char **argv) {
const char *lowlimit = argv[1];
ut64 low = rz_num_math(core->num, lowlimit);
const char *uplimit = argv[2];
ut64 high = rz_num_math(core->num, uplimit);
if (low >= high) {
RZ_LOG_ERROR("core : Invalid arguments passed to %s : low-limit shouldn't be more then high-limit", argv[0]);
return RZ_CMD_STATUS_ERROR;
}
core->num->value = (ut64)(low + rz_num_rand64(high - low));
rz_cons_printf("0x%" PFMT64x "\n", core->num->value);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_print_binary_handler(RzCore *core, int argc, const char **argv) {
char out[128] = RZ_EMPTY;
ut64 n = rz_num_math(core->num, argv[1]);
rz_num_to_bits(out, n);
rz_cons_printf("%sb\n", out);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_base64_encode_handler(RzCore *core, int argc, const char **argv) {
char *buf = rz_base64_encode_dyn((ut8 *)argv[1], strlen(argv[1]));
if (!buf) {
RZ_LOG_ERROR("core: Out of memory!");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_println(buf);
free(buf);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_base64_decode_handler(RzCore *core, int argc, const char **argv) {
ut8 *buf = rz_base64_decode_dyn(argv[1], -1);
if (!buf) {
RZ_LOG_ERROR("core: Out of memory!");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_println((char *)buf);
free(buf);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_check_between_handler(RzCore *core, int argc, const char **argv) {
st64 f = rz_num_math(core->num, argv[1]);
st64 m = rz_num_math(core->num, argv[2]);
st64 l = rz_num_math(core->num, argv[3]);
core->num->value = RZ_BETWEEN(f, m, l);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_print_boundaries_prot_handler(RzCore *core, int argc, const char **argv) {
const char *mode = rz_str_trim_head_ro(argv[1]);
RzList *list = rz_core_get_boundaries_prot(core, -1, mode, "search");
if (!list) {
RZ_LOG_ERROR("core: Failed to get boundaries protection values in RzList");
return RZ_CMD_STATUS_ERROR;
}
RzListIter *iter;
RzIOMap *map;
rz_list_foreach (list, iter, map) {
rz_cons_printf("0x%" PFMT64x " 0x%" PFMT64x "\n", map->itv.addr, rz_itv_end(map->itv));
}
rz_list_free(list);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_print_djb2_hash_handler(RzCore *core, int argc, const char **argv) {
ut32 hash = (ut32)rz_str_djb2_hash(argv[1]);
rz_cons_printf("0x%08x\n", hash);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_print_bitstring_handler(RzCore *core, int argc, const char **argv) {
ut64 n = rz_num_get(core->num, argv[1]);
char out[128] = RZ_EMPTY;
rz_str_bits(out, (const ut8 *)&n, sizeof(n) * 8, argv[2]);
rz_cons_println(out);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_eval_expr_print_octal_handler(RzCore *core, int argc, const char **argv) {
ut64 n = rz_num_math(core->num, argv[1]);
rz_cons_printf("0%" PFMT64o "\n", n);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_num_to_units_handler(RzCore *core, int argc, const char **argv) {
char unit[8];
ut64 n = rz_num_math(core->num, argv[1]);
rz_num_units(unit, sizeof(unit), n);
rz_cons_println(unit);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_set_last_eval_expr_handler(RzCore *core, int argc, const char **argv) {
rz_num_math(core->num, argv[1]);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_show_value_handler(RzCore *core, int argc, const char **argv) {
ut64 n = argc < 2 ? core->num->value : rz_num_math(core->num, argv[1]);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_printf("0x%" PFMT64x "\n", n);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_show_value_hex_handler(RzCore *core, int argc, const char **argv) {
ut64 n = argc < 2 ? core->num->value : rz_num_math(core->num, argv[1]);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_printf("0x%08" PFMT64x "\n", n); // differs from %v here 0x%08
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_show_value_i1_handler(RzCore *core, int argc, const char **argv) {
st8 n = argc < 2 ? core->num->value : rz_num_math(core->num, argv[1]);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_printf("%d\n", (st8)(n & UT8_MAX));
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_show_value_i2_handler(RzCore *core, int argc, const char **argv) {
st16 n = argc < 2 ? core->num->value : rz_num_math(core->num, argv[1]);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_printf("%d\n", (st16)(n & UT16_MAX));
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_show_value_i4_handler(RzCore *core, int argc, const char **argv) {
st32 n = argc < 2 ? core->num->value : rz_num_math(core->num, argv[1]);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_printf("%d\n", (st32)(n & UT32_MAX));
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_show_value_i8_handler(RzCore *core, int argc, const char **argv) {
st64 n = argc < 2 ? core->num->value : rz_num_math(core->num, argv[1]);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_printf("%" PFMT64d "\n", (st64)(n & UT64_MAX));
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_show_value_int_handler(RzCore *core, int argc, const char **argv) {
st64 n = argc < 2 ? core->num->value : rz_num_math(core->num, argv[1]);
if (core->num->dbz) {
RZ_LOG_ERROR("core: RzNum ERROR: Division by Zero\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_printf("%" PFMT64d "\n", n);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_compare_and_set_core_num_value_handler(RzCore *core, int argc, const char **argv) {
core->num->value = strcmp(argv[1], argv[2]);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_exec_cmd_if_core_num_value_positive_handler(RzCore *core, int argc, const char **argv) {
st64 n = (st64)core->num->value;
if (n > 0) {
rz_core_cmd(core, argv[1], 0);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_exec_cmd_if_core_num_value_negative_handler(RzCore *core, int argc, const char **argv) {
st64 n = (st64)core->num->value;
if (n < 0) {
rz_core_cmd(core, argv[1], 0);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_exec_cmd_if_core_num_value_zero_handler(RzCore *core, int argc, const char **argv) {
if (!core->num->value) {
core->num->value = rz_core_cmd(core, argv[1], 0);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_exec_cmd_if_core_num_value_nonzero_handler(RzCore *core, int argc, const char **argv) {
if (core->num->value) {
core->num->value = rz_core_cmd(core, argv[1], 0);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdDescDetail *rz_cmd_math_help_vars_details_cb(RzCore *core, int argc, const char **argv) {
RzCmdDescDetail *details = RZ_NEWS0(RzCmdDescDetail, 2);
if (!details) {
return NULL;
}
details[0].name = (const char *)strdup("Rizin variables");
if (!details->name) {
goto err;
}
RzCmdDescDetailEntry *entries = RZ_NEWS0(RzCmdDescDetailEntry, RZ_ARRAY_SIZE(core_vars) + RZ_ARRAY_SIZE(help_core_vars) + 1);
details[0].entries = (const RzCmdDescDetailEntry *)entries;
if (!entries) {
goto err;
}
int i;
for (i = 0; i < RZ_ARRAY_SIZE(core_vars); i++) {
struct rz_core_var *var = &core_vars[i];
entries[i].text = (char *)strdup(var->name);
entries[i].arg_str = strdup("");
entries[i].comment = strdup(var->description);
if (!entries[i].text || !entries[i].arg_str || !entries[i].comment) {
goto err;
}
}
for (int j = 0; j < RZ_ARRAY_SIZE(help_core_vars); j++, i++) {
struct rz_core_var *var = &help_core_vars[j];
entries[i].text = (char *)strdup(var->name);
entries[i].arg_str = strdup("");
entries[i].comment = strdup(var->description);
if (!entries[i].text || !entries[i].arg_str || !entries[i].comment) {
goto err;
}
}
details->entries = (const RzCmdDescDetailEntry *)entries;
return details;
err:
rz_cmd_desc_details_free(details);
return NULL;
}
RZ_IPI RzCmdStatus rz_calculate_string_length_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
core->num->value = strlen(argv[1]);
if (state->mode == RZ_OUTPUT_MODE_STANDARD) {
rz_cons_printf("%" PFMT64d "\n", core->num->value);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_calc_expr_show_hex_handler(RzCore *core, int argc, const char **argv) {
ut64 n = rz_num_math(core->num, argv[1]);
rz_cons_printf("%" PFMT64x "\n", n);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_ascii_to_hex_handler(RzCore *core, int argc, const char **argv) {
const char *str = argv[1];
int n = strlen(str);
for (int i = 0; i < n; i++) {
rz_cons_printf("%02x", str[i]);
}
rz_cons_newline();
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_numeric_expr_to_hex_handler(RzCore *core, int argc, const char **argv) {
ut64 n = rz_num_math(core->num, argv[1]);
int bits = rz_num_to_bits(NULL, n) / 8;
for (int i = 0; i < bits; i++) {
rz_cons_printf("%02x", (ut8)((n >> (i * 8)) & 0xff));
}
rz_cons_newline();
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_hex_to_ascii_handler(RzCore *core, int argc, const char **argv) {
ut8 *out = malloc(strlen(argv[1]) + 1);
if (out) {
int len = rz_hex_str2bin(argv[1], out);
if (len >= 0) {
out[len] = 0;
rz_cons_println((const char *)out);
} else {
RZ_LOG_ERROR("core: Error parsing the hexpair string\n");
}
free(out);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_generate_sequence_handler(RzCore *core, int argc, const char **argv) {
ut64 from, to, step;
from = rz_num_math(core->num, argv[1]);
to = rz_num_math(core->num, argv[2]);
if (argc == 4) {
step = rz_num_math(core->num, argv[3]);
if (step == 0) {
step = 1;
}
} else {
step = 1;
}
for (; from <= to; from += step)
rz_cons_printf("%" PFMT64d " ", from);
rz_cons_newline();
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_phys2virt_handler(RzCore *core, int argc, const char **argv) {
ut64 n = argc == 2 ? rz_num_math(core->num, argv[1]) : core->offset;
ut64 vaddr = rz_io_p2v(core->io, n);
if (vaddr == UT64_MAX) {
rz_cons_printf("no map at 0x%08" PFMT64x "\n", n);
} else {
rz_cons_printf("0x%08" PFMT64x "\n", vaddr);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_virt2phys_handler(RzCore *core, int argc, const char **argv) {
ut64 n = argc == 2 ? rz_num_math(core->num, argv[1]) : core->offset;
ut64 paddr = rz_io_v2p(core->io, n);
if (paddr == UT64_MAX) {
rz_cons_printf("no map at 0x%08" PFMT64x "\n", n);
} else {
rz_cons_printf("0x%08" PFMT64x "\n", paddr);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_yank_hud_file_handler(RzCore *core, int argc, const char **argv) {
rz_core_yank_hud_file(core, argv[1]);
return RZ_CMD_STATUS_OK;
}
static RzCmdStatus prompt_handler(RzCore *core, int argc, const char **argv, bool echo) {
if (!rz_cons_is_interactive()) {
RZ_LOG_ERROR("core: Not running in interactive mode\n");
return RZ_CMD_STATUS_WRONG_ARGS;
}
char foo[1024];
rz_cons_flush();
// TODO: rz_cons_input()
snprintf(foo, sizeof(foo) - 1, "%s: ", argv[1]);
rz_line_set_prompt(foo);
rz_cons_fgets(foo, sizeof(foo), 0, NULL);
foo[sizeof(foo) - 1] = 0;
rz_core_yank_set_str(core, RZ_CORE_FOREIGN_ADDR, foo);
core->num->value = rz_num_math(core->num, foo);
rz_cons_set_raw(0);
if (echo) {
rz_cons_printf("%s\n", foo);
}
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_input_prompt_handler(RzCore *core, int argc, const char **argv) {
return prompt_handler(core, argc, argv, false);
}
RZ_IPI RzCmdStatus rz_input_prompt_echo_handler(RzCore *core, int argc, const char **argv) {
return prompt_handler(core, argc, argv, true);
}
static RzCmdStatus yesno_handler(RzCore *core, int argc, const char **argv, const char *yn) {
if (!rz_cons_is_interactive()) {
RZ_LOG_ERROR("core: Not running in interactive mode\n");
return RZ_CMD_STATUS_WRONG_ARGS;
}
core->num->value = rz_cons_yesno(0, "%s? (%s) ", argv[1], yn);
rz_cons_set_raw(0);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_input_yesno_no_handler(RzCore *core, int argc, const char **argv) {
return yesno_handler(core, argc, argv, "y/N");
}
RZ_IPI RzCmdStatus rz_input_yesno_yes_handler(RzCore *core, int argc, const char **argv) {
return yesno_handler(core, argc, argv, "Y/n");
}
RZ_IPI RzCmdStatus rz_input_any_key_handler(RzCore *core, int argc, const char **argv) {
if (!rz_cons_is_interactive()) {
RZ_LOG_ERROR("core: Not running in interactive mode\n");
return RZ_CMD_STATUS_WRONG_ARGS;
}
rz_cons_any_key(NULL);
rz_cons_set_raw(0);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_input_yank_hud_handler(RzCore *core, int argc, const char **argv) {
if (!rz_cons_is_interactive()) {
RZ_LOG_ERROR("core: Not running in interactive mode\n");
return RZ_CMD_STATUS_WRONG_ARGS;
}
core->num->value = rz_core_yank_hud_path(core, argv[1], 0) == true;
rz_cons_set_raw(0);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_input_msg_handler(RzCore *core, int argc, const char **argv) {
if (!rz_cons_is_interactive()) {
RZ_LOG_ERROR("core: Not running in interactive mode\n");
return RZ_CMD_STATUS_WRONG_ARGS;
}
rz_cons_message(argv[1]);
rz_cons_set_raw(0);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_input_conditional_handler(RzCore *core, int argc, const char **argv) {
if (!rz_cons_is_interactive()) {
RZ_LOG_ERROR("core: Not running in interactive mode\n");
return RZ_CMD_STATUS_WRONG_ARGS;
}
core->num->value = !rz_num_conditional(core->num, argv[1]);
rz_cons_printf("%s\n", rz_str_bool(!core->num->value));
rz_cons_set_raw(0);
return RZ_CMD_STATUS_OK;
}
RZ_IPI RzCmdStatus rz_get_addr_references_handler(RzCore *core, int argc, const char **argv) {
ut64 addr = rz_num_math(core->num, argv[1]);
char *rstr = core->print->hasrefs(core->print->user, addr, true);
if (!rstr) {
RZ_LOG_ERROR("core: Cannot get refs\n");
return RZ_CMD_STATUS_ERROR;
}
rz_cons_println(rstr);
free(rstr);
return RZ_CMD_STATUS_OK;
}