Rizin
unix-like reverse engineering framework and cli tools
cmd.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2021 nibble <nibble.ds@gmail.com>
2 // SPDX-FileCopyrightText: 2009-2021 pancake <pancake@nopcode.org>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #define INTERACTIVE_MAX_REP 1024
6 
7 #include <rz_core.h>
8 #include <rz_analysis.h>
9 #include <rz_cons.h>
10 #include <rz_cmd.h>
11 #include <rz_windows.h>
12 #include <stdint.h>
13 #include <sys/types.h>
14 #include <ctype.h>
15 #include <stdarg.h>
16 #if __UNIX__
17 #include <sys/utsname.h>
18 #endif
19 
20 #include <cmd_descs.h>
21 
22 #include <tree_sitter/api.h>
24 
25 RZ_API void rz_save_panels_layout(RzCore *core, const char *_name);
26 RZ_API bool rz_load_panels_layout(RzCore *core, const char *_name);
27 
28 static RzCmdDescriptor *cmd_descriptor(const char *cmd, const char *help[]) {
30  if (d) {
31  d->cmd = cmd;
32  d->help_msg = help;
33  }
34  return d;
35 }
36 
37 #define DEPRECATED_DEFINE_CMD_DESCRIPTOR(core, cmd_) \
38  { \
39  RzCmdDescriptor *d = cmd_descriptor(#cmd_, help_msg_##cmd_); \
40  if (d) { \
41  rz_list_append((core)->cmd_descriptors, d); \
42  } \
43  }
44 
45 #define DEPRECATED_DEFINE_CMD_DESCRIPTOR_WITH_DETAIL(core, cmd_) \
46  { \
47  RzCmdDescriptor *d = cmd_descriptor(#cmd_, help_msg##cmd_); \
48  if (d) { \
49  d->help_detail = help_detail_##cmd_; \
50  rz_list_append((core)->cmd_descriptors, d); \
51  } \
52  }
53 
54 #define DEPRECATED_DEFINE_CMD_DESCRIPTOR_WITH_DETAIL2(core, cmd_) \
55  { \
56  RzCmdDescriptor *d = cmd_descriptor(#cmd_, help_msg_##cmd_); \
57  if (d) { \
58  d->help_detail = help_detail_##cmd_; \
59  d->help_detail2 = help_detail2_##cmd_; \
60  rz_list_append((core)->cmd_descriptors, d); \
61  } \
62  }
63 
64 #define DEPRECATED_DEFINE_CMD_DESCRIPTOR_SPECIAL(core, cmd_, named_cmd) \
65  { \
66  RzCmdDescriptor *d = RZ_NEW0(RzCmdDescriptor); \
67  if (d) { \
68  d->cmd = #cmd_; \
69  d->help_msg = help_msg_##named_cmd; \
70  rz_list_append((core)->cmd_descriptors, d); \
71  } \
72  }
73 
74 static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpseek);
75 
76 #include "cmd_debug.c"
77 #include "cmd_analysis.c"
78 #include "cmd_macro.c"
79 #include "cmd_magic.c"
80 #include "cmd_search.c" // defines incDigitBuffer... used by cmd_print
81 #include "cmd_print.c"
82 #include "cmd_help.c"
83 
84 static const char *help_msg_dollar[] = {
85  "Usage:", "$alias[=cmd] [args...]", "Alias commands and strings (See ?$? for help on $variables)",
86  "$", "", "list all defined aliases",
87  "$*", "", "list all the aliases as rizin commands in base64",
88  "$**", "", "same as above, but using plain text",
89  "$", "foo:=123", "alias for 'f foo=123'",
90  "$", "foo-=4", "alias for 'f foo-=4'",
91  "$", "foo+=4", "alias for 'f foo+=4'",
92  "$", "foo", "alias for 's foo' (note that command aliases can override flag resolution)",
93  "$", "dis=base64:AAA==", "alias this base64 encoded text to be printed when $dis is called",
94  "$", "dis=$hello world", "alias this text to be printed when $dis is called",
95  "$", "dis=-", "open cfg.editor to set the new value for dis alias",
96  "$", "dis=af;pdf", "create command - analyze to show function",
97  "$", "test=#!pipe node /tmp/test.js", "create command - rlangpipe script",
98  "$", "dis=", "undefine alias",
99  "$", "dis", "execute the previously defined alias",
100  "$", "dis?", "show commands aliased by $dis",
101  "$", "dis?n", "show commands aliased by $dis, without a new line",
102  NULL
103 };
104 
105 static const char *help_msg_k[] = {
106  "Usage:",
107  "k[s] [key[=value]]",
108  "Sdb Query",
109  "k",
110  " analysis/**",
111  "list namespaces under analysis",
112  "k",
113  " analysis/meta/*",
114  "list kv from analysis > meta namespaces",
115  "k",
116  " analysis/meta/meta.0x80404",
117  "get value for meta.0x80404 key",
118  "k",
119  " foo",
120  "show value",
121  "k",
122  " foo=bar",
123  "set value",
124  "k",
125  "",
126  "list keys",
127  "kd",
128  " [file.sdb] [ns]",
129  "dump namespace to disk",
130  "kj",
131  "",
132  "List all namespaces and sdb databases in JSON format",
133  "ko",
134  " [file.sdb] [ns]",
135  "open file into namespace",
136  "ks",
137  " [ns]",
138  "enter the sdb query shell",
139  //"kl", " ha.sdb", "load keyvalue from ha.sdb",
140  //"ks", " ha.sdb", "save keyvalue to ha.sdb",
141  NULL,
142 };
143 
144 static const char *help_msg_vertical_bar[] = {
145  "Usage:", "[cmd] | [program|H|T|.|]", "",
146  "", "[cmd] |?", "show this help",
147  "", "[cmd] |", "disable scr.html and scr.color",
148  "", "[cmd] |H", "enable scr.html, respect scr.color",
149  "", "[cmd] | [program]", "pipe output of command to program",
150  "", "[cmd] |.", "alias for .[cmd]",
151  NULL
152 };
153 
154 static const char *help_msg_v[] = {
155  "Usage:", "v[*i]", "",
156  "v", "", "open visual panels",
157  "v", " test", "load saved layout with name test",
158  "v=", " test", "save current layout with name test",
159  "vi", " test", "open the file test in 'cfg.editor'",
160  NULL
161 };
162 
163 RZ_API void rz_core_cmd_help(const RzCore *core, const char *help[]) {
165 }
166 
169  const char *word;
170 };
171 
172 static bool duplicate_flag(RzFlagItem *flag, void *u) {
173  struct duplicate_flag_t *user = (struct duplicate_flag_t *)u;
174  /* filter per flag spaces */
175  if (!user->word || rz_str_glob(flag->name, user->word)) {
176  RzFlagItem *cloned_item = rz_flag_item_clone(flag);
177  if (!cloned_item) {
178  return false;
179  }
180  rz_list_append(user->ret, cloned_item);
181  }
182  return true;
183 }
184 
186  int i;
187  if (desc->help_msg) {
188  rz_core_cmd_help(core, desc->help_msg);
189  }
190  if (detail >= 1) {
191  if (desc->help_detail) {
192  rz_core_cmd_help(core, desc->help_detail);
193  }
194  if (detail >= 2 && desc->help_detail2) {
195  rz_core_cmd_help(core, desc->help_detail2);
196  }
197  }
198  for (i = 32; i < RZ_ARRAY_SIZE(desc->sub); i++) {
199  if (desc->sub[i]) {
200  recursive_help_go(core, detail, desc->sub[i]);
201  }
202  }
203 }
204 
205 static void recursive_help(RzCore *core, int detail, const char *cmd_prefix) {
206  const ut8 *p;
208  for (p = (const ut8 *)cmd_prefix; *p && *p < RZ_ARRAY_SIZE(desc->sub); p++) {
209  if (!(desc = desc->sub[*p])) {
210  return;
211  }
212  }
213  recursive_help_go(core, detail, desc);
214 }
215 
216 RZ_IPI bool rz_core_cmd_lastcmd_repeat(RzCore *core, bool next) {
217  int res = -1;
218  // Fix for backtickbug px`~`
219  if (!core->lastcmd || core->cons->context->cmd_depth < 1) {
220  return false;
221  }
222  switch (*core->lastcmd) {
223  case '.':
224  if (core->lastcmd[1] == '(') { // macro call
225  res = rz_core_cmd0(core, core->lastcmd);
226  }
227  break;
228  case 'd': // debug
229  res = rz_core_cmd0(core, core->lastcmd);
230  switch (core->lastcmd[1]) {
231  case 's':
232  case 'c':
233  rz_core_seek_to_register(core, "PC", false);
234  rz_core_cmd0(core, "pd 1");
235  }
236  break;
237  case 'p': // print
238  case 'x':
239  case '$':
240  if (!strncmp(core->lastcmd, "pd", 2)) {
241  if (core->lastcmd[2] == ' ') {
242  ut64 addr = rz_num_math(core->num, core->lastcmd + 3);
243  rz_core_seek_opcode(core, addr, false);
244  } else {
245  rz_core_cmd0(core, "so `pi~?`");
246  }
247  } else {
248  if (next) {
249  rz_core_seek(core, core->offset + core->blocksize, true);
250  } else {
251  if (core->blocksize > core->offset) {
252  rz_core_seek(core, 0, true);
253  } else {
254  rz_core_seek(core, core->offset - core->blocksize, true);
255  }
256  }
257  }
258  res = rz_core_cmd0(core, core->lastcmd);
259  break;
260  }
261  core->is_lastcmd = true;
262  return res != -1;
263 }
264 
265 static int rz_core_cmd_nullcallback(void *data) {
266  RzCore *core = (RzCore *)data;
267  if (core->cons->context->breaked) {
268  core->cons->context->breaked = false;
269  return 0;
270  }
271  if (!core->cmdrepeat) {
272  return 0;
273  }
274  rz_core_cmd_lastcmd_repeat(core, true);
275  return 1;
276 }
277 
278 RZ_IPI int rz_cmd_alias(void *data, const char *input) {
279  RzCore *core = (RzCore *)data;
280  if (*input == '?') {
282  return 0;
283  }
284  int i = strlen(input);
285  char *buf = malloc(i + 2);
286  if (!buf) {
287  return 0;
288  }
289  *buf = '$'; // prefix aliases with a dollar
290  memcpy(buf + 1, input, i + 1);
291  char *q = strchr(buf, ' ');
292  char *def = strchr(buf, '=');
293  char *desc = strchr(buf, '?');
294  char *nonl = strchr(buf, 'n');
295 
296  int defmode = 0;
297  if (def && def > buf) {
298  char *prev = def - 1;
299  switch (*prev) {
300  case ':':
301  defmode = *prev;
302  *prev = 0;
303  break;
304  case '+':
305  defmode = *prev;
306  *prev = 0;
307  break;
308  case '-':
309  defmode = *prev;
310  *prev = 0;
311  break;
312  }
313  }
314 
315  /* create alias */
316  if ((def && q && (def < q)) || (def && !q)) {
317  *def++ = 0;
318  size_t len = strlen(def);
319  if (defmode) {
320  ut64 at = rz_num_math(core->num, def);
321  switch (defmode) {
322  case ':':
323  rz_flag_set(core->flags, buf + 1, at, 1);
324  return 1;
325  case '+':
326  at = rz_num_get(core->num, buf + 1) + at;
327  rz_flag_set(core->flags, buf + 1, at, 1);
328  return 1;
329  case '-':
330  at = rz_num_get(core->num, buf + 1) - at;
331  rz_flag_set(core->flags, buf + 1, at, 1);
332  return 1;
333  }
334  }
335  /* Remove quotes */
336  if (len > 0 && (def[0] == '\'') && (def[len - 1] == '\'')) {
337  def[len - 1] = 0x00;
338  def++;
339  }
340  if (!q || (q && q > def)) {
341  if (*def) {
342  if (!strcmp(def, "-")) {
343  char *v = rz_cmd_alias_get(core->rcmd, buf, 0);
344  char *n = rz_core_editor(core, NULL, v);
345  if (n) {
346  rz_cmd_alias_set(core->rcmd, buf, n, 0);
347  free(n);
348  }
349  } else {
350  rz_cmd_alias_set(core->rcmd, buf, def, 0);
351  }
352  } else {
353  rz_cmd_alias_del(core->rcmd, buf);
354  }
355  }
356  /* Show command for alias */
357  } else if (desc && !q) {
358  *desc = 0;
359  char *v = rz_cmd_alias_get(core->rcmd, buf, 0);
360  if (v) {
361  if (nonl == desc + 1) {
362  rz_cons_print(v);
363  } else {
365  }
366  free(buf);
367  return 1;
368  } else {
369  eprintf("unknown key '%s'\n", buf);
370  }
371  } else if (buf[1] == '*') {
372  /* Show aliases */
373  int i, count = 0;
374  char **keys = rz_cmd_alias_keys(core->rcmd, &count);
375  for (i = 0; i < count; i++) {
376  char *v = rz_cmd_alias_get(core->rcmd, keys[i], 0);
377  char *q = rz_base64_encode_dyn((const ut8 *)v, strlen(v));
378  if (buf[2] == '*') {
379  rz_cons_printf("%s=%s\n", keys[i], v);
380  } else {
381  rz_cons_printf("%s=base64:%s\n", keys[i], q);
382  }
383  free(q);
384  }
385  } else if (!buf[1]) {
386  int i, count = 0;
387  char **keys = rz_cmd_alias_keys(core->rcmd, &count);
388  for (i = 0; i < count; i++) {
390  }
391  } else {
392  /* Execute alias */
393  if (q) {
394  *q = 0;
395  }
396  char *v = rz_cmd_alias_get(core->rcmd, buf, 0);
397  if (v) {
398  if (*v == '$') {
399  rz_cons_strcat(v + 1);
400  rz_cons_newline();
401  } else if (q) {
402  char *out = rz_str_newf("%s %s", v, q + 1);
403  rz_core_cmd0(core, out);
404  free(out);
405  } else {
406  rz_core_cmd0(core, v);
407  }
408  } else {
409  ut64 at = rz_num_get(core->num, buf + 1);
410  if (at != UT64_MAX) {
411  rz_core_seek(core, at, true);
412  } else {
413  eprintf("Unknown alias '%s'\n", buf + 1);
414  }
415  }
416  }
417  free(buf);
418  return 0;
419 }
420 
421 static int lang_run_file(RzCore *core, RzLang *lang, const char *file) {
422  rz_core_sysenv_begin(core);
423  return rz_lang_run_file(core->lang, file);
424 }
425 
426 static char *langFromHashbang(RzCore *core, const char *file) {
427  int fd = rz_sys_open(file, O_RDONLY, 0);
428  if (fd != -1) {
429  char firstLine[128] = { 0 };
430  int len = read(fd, (ut8 *)firstLine, sizeof(firstLine) - 1);
431  if (len < 1) {
432  close(fd);
433  return NULL;
434  }
435  firstLine[len] = 0;
436  if (!strncmp(firstLine, "#!/", 3)) {
437  // I CAN HAS A HASHBANG
438  char *nl = strchr(firstLine, '\n');
439  if (nl) {
440  *nl = 0;
441  }
442  nl = strchr(firstLine, ' ');
443  if (nl) {
444  *nl = 0;
445  }
446  nl = strdup(firstLine + 2);
447  close(fd);
448  return nl;
449  }
450  close(fd);
451  }
452  return NULL;
453 }
454 
455 /* \brief Run the script defined by path in \p file. Could be a Rizin script, or rz-pipe one.
456  */
457 RZ_API bool rz_core_run_script(RzCore *core, RZ_NONNULL const char *file) {
458  rz_return_val_if_fail(file, false);
459  bool ret = false;
460  RzListIter *iter;
461  RzLangPlugin *p;
462  char *name;
463 
464  rz_list_foreach (core->scriptstack, iter, name) {
465  if (!strcmp(file, name)) {
466  RZ_LOG_WARN("Ignored nested source: '%s'\n", file);
467  return false;
468  }
469  }
471 
472  if (!strcmp(file, "-")) {
473  char *out = rz_core_editor(core, NULL, NULL);
474  if (out) {
475  ret = rz_core_cmd_lines(core, out);
476  free(out);
477  }
478  } else if (rz_str_endswith(file, ".html")) {
479  char *httpIndex = strdup(rz_config_get(core->config, "http.index"));
480  char *absfile = rz_file_abspath(file);
481  rz_config_set(core->config, "http.index", absfile);
482  free(absfile);
483  rz_equal_H_handler_old(core, "");
484  rz_config_set(core->config, "http.index", httpIndex);
485  free(httpIndex);
486  ret = true;
487  } else if (rz_str_endswith(file, ".c")) {
488  rz_core_cmd_strf(core, "#!c %s", file);
489  ret = true;
490  } else if (rz_file_is_c(file)) {
491  const char *dir = rz_config_get(core->config, "dir.types");
492  char *error_msg = NULL;
493  int result = rz_type_parse_file(core->analysis->typedb, file, dir, &error_msg);
494  if (error_msg) {
495  eprintf("%s", error_msg);
496  free(error_msg);
497  }
498  ret = result != 0;
499  } else {
501  if (p) {
502  rz_lang_use(core->lang, p->name);
503  ret = lang_run_file(core, core->lang, file);
504  } else {
505 // XXX this is an ugly hack, we need to use execve here and specify args properly
506 #if __WINDOWS__
507 #define cmdstr(x) rz_str_newf(x " %s", file);
508 #else
509 #define cmdstr(x) rz_str_newf(x " '%s'", file);
510 #endif
511  const char *p = rz_str_lchr(file, '.');
512  if (p) {
513  const char *ext = p + 1;
514  /* TODO: handle this inside rz_lang_pipe with new APIs */
515  if (!strcmp(ext, "js")) {
516  char *cmd = cmdstr("node");
517  rz_lang_use(core->lang, "pipe");
518  lang_run_file(core, core->lang, cmd);
519  free(cmd);
520  ret = 1;
521  } else if (!strcmp(ext, "exe")) {
522 #if __WINDOWS__
523  char *cmd = rz_str_newf("%s", file);
524 #else
525  char *cmd = cmdstr("wine");
526 #endif
527  rz_lang_use(core->lang, "pipe");
528  lang_run_file(core, core->lang, cmd);
529  free(cmd);
530  ret = 1;
531  } else if (!strcmp(ext, "zig")) {
532  char *cmd = cmdstr("zig run");
533  rz_lang_use(core->lang, "pipe");
534  lang_run_file(core, core->lang, cmd);
535  free(cmd);
536  ret = 1;
537  } else if (!strcmp(ext, "d")) {
538  char *cmd = cmdstr("dmd -run");
539  rz_lang_use(core->lang, "pipe");
540  lang_run_file(core, core->lang, cmd);
541  free(cmd);
542  ret = 1;
543  } else if (!strcmp(ext, "go")) {
544  char *cmd = cmdstr("go run");
545  rz_lang_use(core->lang, "pipe");
546  lang_run_file(core, core->lang, cmd);
547  free(cmd);
548  ret = 1;
549  } else if (!strcmp(ext, "rb")) {
550  char *cmd = cmdstr("ruby");
551  rz_lang_use(core->lang, "pipe");
552  lang_run_file(core, core->lang, cmd);
553  free(cmd);
554  ret = 1;
555  } else if (!strcmp(ext, "vala")) {
556  rz_lang_use(core->lang, "vala");
557  lang_run_file(core, core->lang, file);
558  ret = 1;
559  } else if (!strcmp(ext, "sh")) {
560  char *shell = rz_sys_getenv("SHELL");
561  if (!shell) {
562  shell = strdup("sh");
563  }
564  if (shell) {
565  rz_lang_use(core->lang, "pipe");
566  char *cmd = rz_str_newf("%s '%s'", shell, file);
567  if (cmd) {
568  lang_run_file(core, core->lang, cmd);
569  free(cmd);
570  }
571  free(shell);
572  }
573  ret = 1;
574  } else if (!strcmp(ext, "pl")) {
575  char *cmd = cmdstr("perl");
576  rz_lang_use(core->lang, "pipe");
577  lang_run_file(core, core->lang, cmd);
578  free(cmd);
579  ret = 1;
580  } else if (!strcmp(ext, "py")) {
581  char *cmd = cmdstr("python");
582  rz_lang_use(core->lang, "pipe");
583  lang_run_file(core, core->lang, cmd);
584  free(cmd);
585  ret = 1;
586  }
587  } else {
588  char *abspath = rz_file_path(file);
589  char *lang = langFromHashbang(core, file);
590  if (lang) {
591  rz_lang_use(core->lang, "pipe");
592  char *cmd = rz_str_newf("%s '%s'", lang, file);
593  lang_run_file(core, core->lang, cmd);
594  free(lang);
595  free(cmd);
596  ret = 1;
597  }
598  free(abspath);
599  }
600  if (!ret) {
601  ret = rz_core_cmd_file(core, file);
602  }
603  }
604  }
605  free(rz_list_pop(core->scriptstack));
606  return ret;
607 }
608 
609 static bool callback_foreach_kv(void *user, const char *k, const char *v) {
610  rz_cons_printf("%s=%s\n", k, v);
611  return true;
612 }
613 
615  if (!line->sdbshell_hist_iter || !line->sdbshell_hist_iter->n) {
616  return false;
617  }
618  line->sdbshell_hist_iter = line->sdbshell_hist_iter->n;
619  strncpy(line->buffer.data, line->sdbshell_hist_iter->data, RZ_LINE_BUFSIZE - 1);
620  line->buffer.index = line->buffer.length = strlen(line->buffer.data);
621  return true;
622 }
623 
625  if (!line->sdbshell_hist_iter || !line->sdbshell_hist_iter->p) {
626  return false;
627  }
628  line->sdbshell_hist_iter = line->sdbshell_hist_iter->p;
629  strncpy(line->buffer.data, line->sdbshell_hist_iter->data, RZ_LINE_BUFSIZE - 1);
630  line->buffer.index = line->buffer.length = strlen(line->buffer.data);
631  return true;
632 }
633 
634 RZ_IPI void rz_core_kuery_print(RzCore *core, const char *k) {
635  char *out = sdb_querys(core->sdb, NULL, 0, k);
636  if (out) {
637  rz_cons_print(out);
638  }
639  free(out);
640 }
641 
642 RZ_IPI int rz_cmd_kuery(void *data, const char *input) {
643  char buf[1024], *out, *tofree;
644  RzCore *core = (RzCore *)data;
645  const char *sp, *p = "[sdb]> ";
646  Sdb *s = core->sdb;
647 
648  char *cur_pos = NULL, *cur_cmd = NULL, *next_cmd = NULL;
649  char *temp_pos = NULL, *temp_cmd = NULL;
650 
651  switch (input[0]) {
652  case 'j':
653  tofree = out = sdb_querys(s, NULL, 0, "analysis/**");
654  if (!out) {
655  rz_cons_println("No Output from sdb");
656  break;
657  }
658  PJ *pj = pj_new();
659  if (!pj) {
660  free(out);
661  break;
662  }
663  pj_o(pj);
664  pj_ko(pj, "analysis");
665  pj_ka(pj, "cur_cmd");
666 
667  while (*out) {
668  cur_pos = strchr(out, '\n');
669  if (!cur_pos) {
670  break;
671  }
672  cur_cmd = rz_str_ndup(out, cur_pos - out);
673  pj_s(pj, cur_cmd);
674 
675  free(next_cmd);
676  next_cmd = rz_str_newf("analysis/%s/*", cur_cmd);
677  char *query_result = sdb_querys(s, NULL, 0, next_cmd);
678 
679  if (!query_result) {
680  out = cur_pos + 1;
681  continue;
682  }
683 
684  char *temp = query_result;
685  while (*temp) {
686  temp_pos = strchr(temp, '\n');
687  if (!temp_pos) {
688  break;
689  }
690  temp_cmd = rz_str_ndup(temp, temp_pos - temp);
691  pj_s(pj, temp_cmd);
692  free(temp_cmd);
693  temp = temp_pos + 1;
694  }
695  out = cur_pos + 1;
696  free(query_result);
697  }
698  pj_end(pj);
699  pj_end(pj);
700  pj_end(pj);
702  pj_free(pj);
703  RZ_FREE(next_cmd);
704  free(next_cmd);
705  free(cur_cmd);
706  free(tofree);
707  break;
708 
709  case ' ':
710  rz_core_kuery_print(core, input + 1);
711  break;
712  // case 's': rz_pair_save (s, input + 3); break;
713  // case 'l': rz_pair_load (sdb, input + 3); break;
714  case '\0':
716  break;
717  // TODO: add command to list all namespaces // sdb_ns_foreach ?
718  case 's': // "ks"
719  if (core->http_up) {
720  return false;
721  }
722  if (!rz_cons_is_interactive()) {
723  return false;
724  }
725  if (input[1] == ' ') {
726  char *n, *o, *p = strdup(input + 2);
727  // TODO: slash split here? or inside sdb_ns ?
728  for (n = o = p; n; o = n) {
729  n = strchr(o, '/'); // SDB_NS_SEPARATOR NAMESPACE
730  if (n) {
731  *n++ = 0;
732  }
733  s = sdb_ns(s, o, 1);
734  }
735  free(p);
736  }
737  if (!s) {
738  s = core->sdb;
739  }
740  RzLine *line = core->cons->line;
741  if (!line->sdbshell_hist) {
742  line->sdbshell_hist = rz_list_newf(free);
743  rz_list_append(line->sdbshell_hist, rz_str_new("\0"));
744  }
745  RzList *sdb_hist = line->sdbshell_hist;
747  for (;;) {
749  if (rz_cons_fgets(buf, sizeof(buf), 0, NULL) < 1) {
750  break;
751  }
752  if (!*buf) {
753  break;
754  }
755  if (sdb_hist) {
756  if ((rz_list_length(sdb_hist) == 1) || (rz_list_length(sdb_hist) > 1 && strcmp(rz_list_get_n(sdb_hist, 1), buf))) {
757  rz_list_insert(sdb_hist, 1, strdup(buf));
758  }
759  line->sdbshell_hist_iter = sdb_hist->head;
760  }
761  out = sdb_querys(s, NULL, 0, buf);
762  if (out) {
764  rz_cons_flush();
765  }
766  }
768  break;
769  case 'o': // "ko"
770  if (input[1] == ' ') {
771  char *fn = strdup(input + 2);
772  if (!fn) {
773  eprintf("Unable to allocate memory\n");
774  return 0;
775  }
776  char *ns = strchr(fn, ' ');
777  if (ns) {
778  Sdb *db;
779  *ns++ = 0;
780  if (rz_file_exists(fn)) {
781  db = sdb_ns_path(core->sdb, ns, 1);
782  if (db) {
783  Sdb *newdb = sdb_new(NULL, fn, 0);
784  if (newdb) {
785  sdb_drain(db, newdb);
786  } else {
787  eprintf("Cannot open sdb '%s'\n", fn);
788  }
789  } else {
790  eprintf("Cannot find sdb '%s'\n", ns);
791  }
792  } else {
793  eprintf("Cannot open file\n");
794  }
795  } else {
796  eprintf("Missing sdb namespace\n");
797  }
798  free(fn);
799  } else {
800  eprintf("Usage: ko [file] [namespace]\n");
801  }
802  break;
803  case 'd': // "kd"
804  if (input[1] == ' ') {
805  char *fn = strdup(input + 2);
806  char *ns = strchr(fn, ' ');
807  if (ns) {
808  *ns++ = 0;
809  Sdb *db = sdb_ns_path(core->sdb, ns, 0);
810  if (db) {
811  sdb_file(db, fn);
812  sdb_sync(db);
813  } else {
814  eprintf("Cannot find sdb '%s'\n", ns);
815  }
816  } else {
817  eprintf("Missing sdb namespace\n");
818  }
819  free(fn);
820  } else {
821  eprintf("Usage: kd [file] [namespace]\n");
822  }
823  break;
824  case '?':
826  break;
827  }
828 
829  if (input[0] == '\0') {
830  /* nothing more to do, the command has been parsed. */
831  return 0;
832  }
833 
834  sp = strchr(input + 1, ' ');
835  if (sp) {
836  char *inp = strdup(input);
837  inp[(size_t)(sp - input)] = 0;
838  s = sdb_ns(core->sdb, inp + 1, 1);
839  out = sdb_querys(s, NULL, 0, sp + 1);
840  if (out) {
842  free(out);
843  }
844  free(inp);
845  return 0;
846  }
847  return 0;
848 }
849 
850 RZ_IPI int rz_cmd_panels(void *data, const char *input) {
851  RzCore *core = (RzCore *)data;
852  if (core->vmode) {
853  return false;
854  }
855  if (!rz_cons_is_interactive()) {
856  eprintf("Panel mode requires scr.interactive=true.\n");
857  return false;
858  }
859  char *sp = strchr(input, ' ');
860  switch (input[0]) {
861  case ' ': // "v [name]"
862  if (core->panels) {
863  rz_load_panels_layout(core, input + 1);
864  }
865  rz_config_set(core->config, "scr.layout", input + 1);
866  return true;
867  case '=': // "v= [name]"
868  rz_save_panels_layout(core, input + 1);
869  rz_config_set(core->config, "scr.layout", input + 1);
870  return true;
871  case 'i': // "vi [file]"
872  if (sp) {
873  char *r = rz_core_editor(core, sp + 1, NULL);
874  if (r) {
875  free(r);
876  } else {
877  eprintf("Cannot open file (%s)\n", sp + 1);
878  }
879  }
881  return false;
882  case 0:
884  return true;
885  default:
887  return false;
888  }
889 }
890 
891 RZ_IPI int rz_cmd_visual(void *data, const char *input) {
892  RzCore *core = (RzCore *)data;
893  if (core->http_up) {
894  return false;
895  }
896  if (!rz_cons_is_interactive()) {
897  eprintf("Visual mode requires scr.interactive=true.\n");
898  return false;
899  }
900  return rz_core_visual((RzCore *)data, input);
901 }
902 
903 RZ_IPI RzCmdStatus rz_push_escaped_handler(RzCore *core, int argc, const char **argv) {
904  char *input = rz_str_array_join(argv + 1, argc - 1, " ");
905  int len = rz_str_unescape(input);
907  free(input);
908  return res;
909 }
910 
911 RZ_IPI RzCmdStatus rz_pointer_handler(RzCore *core, int argc, const char **argv) {
912  int ret;
913  switch (argc) {
914  case 2:
915  ret = rz_core_cmdf(core, "?v [%s]", argv[1]);
916  return rz_cmd_int2status(ret);
917  case 3:
918  if (rz_str_startswith(argv[2], "0x")) {
919  ret = rz_core_cmdf(core, "wv %s @ %s", argv[2], argv[1]);
920  } else {
921  ret = rz_core_cmdf(core, "wx %s @ %s", argv[2], argv[1]);
922  }
923  return rz_cmd_int2status(ret);
924  default:
926  }
927 }
928 
929 RZ_IPI RzCmdStatus rz_last_output_handler(RzCore *core, int argc, const char **argv) {
930  rz_cons_last();
931  return RZ_CMD_STATUS_OK;
932 }
933 
934 #if __WINDOWS__
935 #include <tchar.h>
936 #define __CLOSE_DUPPED_PIPES() \
937  close(1); \
938  close(fd_out); \
939  fd_out = -1;
940 
941 static void rz_w32_cmd_pipe(RzCore *core, char *rizin_cmd, char *shell_cmd) {
942  STARTUPINFO si = { 0 };
943  PROCESS_INFORMATION pi = { 0 };
944  SECURITY_ATTRIBUTES sa;
945  HANDLE pipe[2] = { NULL, NULL };
946  int fd_out = -1, cons_out = -1;
947  char *_shell_cmd = NULL;
948  LPTSTR _shell_cmd_ = NULL;
949  DWORD mode;
950  TCHAR *systemdir = NULL;
951  GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &mode);
952 
953  sa.nLength = sizeof(SECURITY_ATTRIBUTES);
954  sa.bInheritHandle = TRUE;
955  sa.lpSecurityDescriptor = NULL;
956  if (!CreatePipe(&pipe[0], &pipe[1], &sa, 0)) {
957  rz_sys_perror("rz_w32_cmd_pipe/CreatePipe");
958  goto err_r_w32_cmd_pipe;
959  }
960  if (!SetHandleInformation(pipe[1], HANDLE_FLAG_INHERIT, 0)) {
961  rz_sys_perror("rz_w32_cmd_pipe/SetHandleInformation");
962  goto err_r_w32_cmd_pipe;
963  }
964  si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
965  si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
966  si.hStdInput = pipe[0];
967  si.dwFlags |= STARTF_USESTDHANDLES;
968  si.cb = sizeof(si);
969  _shell_cmd = shell_cmd;
970  while (*_shell_cmd && isspace((ut8)*_shell_cmd)) {
971  _shell_cmd++;
972  }
973  char *tmp = rz_str_newf("/Q /c \"%s\"", _shell_cmd);
974  if (!tmp) {
975  goto err_r_w32_cmd_pipe;
976  }
977  _shell_cmd = tmp;
978  _shell_cmd_ = rz_sys_conv_utf8_to_win(_shell_cmd);
979  free(tmp);
980  if (!_shell_cmd_) {
981  goto err_r_w32_cmd_pipe;
982  }
983  systemdir = calloc(MAX_PATH, sizeof(TCHAR));
984  if (!systemdir) {
985  goto err_r_w32_cmd_pipe;
986  }
987  int ret = GetSystemDirectory(systemdir, MAX_PATH);
988  if (!ret) {
989  rz_sys_perror("rz_w32_cmd_pipe/systemdir");
990  goto err_r_w32_cmd_pipe;
991  }
992  _tcscat_s(systemdir, MAX_PATH, TEXT("\\cmd.exe"));
993  // exec windows process
994  if (!CreateProcess(systemdir, _shell_cmd_, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
995  rz_sys_perror("rz_w32_cmd_pipe/CreateProcess");
996  goto err_r_w32_cmd_pipe;
997  }
998  fd_out = _open_osfhandle((intptr_t)pipe[1], _O_WRONLY | _O_TEXT);
999  if (fd_out == -1) {
1000  perror("_open_osfhandle");
1001  goto err_r_w32_cmd_pipe;
1002  }
1003  cons_out = dup(1);
1004  dup2(fd_out, 1);
1005  // exec rizin command
1006  rz_core_cmd(core, rizin_cmd, 0);
1007 
1008  HANDLE th = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)rz_cons_flush, NULL, 0, NULL);
1009  if (!th) {
1010  __CLOSE_DUPPED_PIPES();
1011  goto err_r_w32_cmd_pipe;
1012  }
1013  while (true) {
1014  int ret = WaitForSingleObject(th, 50);
1015  if (!ret) {
1016  // Successfully written everything to pipe
1017  __CLOSE_DUPPED_PIPES();
1018  WaitForSingleObject(pi.hProcess, INFINITE);
1019  break;
1020  }
1021  ret = WaitForSingleObject(pi.hProcess, 50);
1022  if (!ret) {
1023  // Process exited before we finished writing to pipe
1024  DWORD exit;
1025  if (GetExitCodeThread(th, &exit) && exit == STILL_ACTIVE) {
1026  CancelSynchronousIo(th);
1027  }
1028  WaitForSingleObject(th, INFINITE);
1029  __CLOSE_DUPPED_PIPES();
1030  break;
1031  }
1032  }
1033  CloseHandle(th);
1034 err_r_w32_cmd_pipe:
1035  if (pi.hProcess) {
1036  CloseHandle(pi.hProcess);
1037  }
1038  if (pi.hThread) {
1039  CloseHandle(pi.hThread);
1040  }
1041  if (pipe[0]) {
1042  CloseHandle(pipe[0]);
1043  }
1044  if (fd_out != -1) {
1045  close(fd_out);
1046  }
1047  if (cons_out != -1) {
1048  dup2(cons_out, 1);
1049  close(cons_out);
1050  }
1051  free(systemdir);
1052  free(_shell_cmd_);
1053  SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode);
1054 }
1055 #undef __CLOSE_DUPPED_PIPES
1056 #endif
1057 
1058 RZ_API int rz_core_cmd_pipe_old(RzCore *core, char *rizin_cmd, char *shell_cmd) {
1059 #if __UNIX__
1060  int stdout_fd, fds[2];
1061  int child;
1062 #endif
1063  int si, olen, ret = -1, pipecolor = -1;
1064  char *str, *out = NULL;
1065 
1067  rz_config_set_i(core->config, "scr.interactive", 0);
1068  if (!rz_config_get_i(core->config, "scr.color.pipe")) {
1069  pipecolor = rz_config_get_i(core->config, "scr.color");
1070  rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
1071  }
1072  if (*shell_cmd == '!') {
1073  rz_cons_grep_parsecmd(shell_cmd, "\"");
1074  olen = 0;
1075  out = NULL;
1076  // TODO: implement foo
1077  str = rz_core_cmd_str(core, rizin_cmd);
1078  rz_sys_cmd_str_full(shell_cmd + 1, str, &out, &olen, NULL);
1079  free(str);
1080  rz_cons_memcat(out, olen);
1081  free(out);
1082  ret = 0;
1083  }
1084 #if __UNIX__
1085  rz_str_trim_head(rizin_cmd);
1086  rz_str_trim_head(shell_cmd);
1087 
1088  rz_sys_signal(SIGPIPE, SIG_IGN);
1089  stdout_fd = dup(1);
1090  if (stdout_fd != -1) {
1091  if (rz_sys_pipe(fds, true) == 0) {
1092  child = rz_sys_fork();
1093  if (child == -1) {
1094  eprintf("Cannot fork\n");
1095  close(stdout_fd);
1096  } else if (child) {
1097  dup2(fds[1], 1);
1098  rz_sys_pipe_close(fds[1]);
1099  rz_sys_pipe_close(fds[0]);
1100  rz_core_cmd(core, rizin_cmd, 0);
1101  rz_cons_flush();
1102  close(1);
1103  wait(&ret);
1104  dup2(stdout_fd, 1);
1105  close(stdout_fd);
1106  } else {
1107  close(fds[1]);
1108  dup2(fds[0], 0);
1109  // dup2 (1, 2); // stderr goes to stdout
1110  rz_sys_execl("/bin/sh", "sh", "-c", shell_cmd, (const char *)NULL);
1111  close(stdout_fd);
1112  }
1113  } else {
1114  eprintf("rz_core_cmd_pipe: Could not pipe\n");
1115  }
1116  }
1117 #elif __WINDOWS__
1118  rz_w32_cmd_pipe(core, rizin_cmd, shell_cmd);
1119 #else
1120 #ifdef _MSC_VER
1121 #pragma message("rz_core_cmd_pipe UNIMPLEMENTED FOR THIS PLATFORM")
1122 #else
1123 #warning rz_core_cmd_pipe UNIMPLEMENTED FOR THIS PLATFORM
1124 #endif
1125  eprintf("rz_core_cmd_pipe: unimplemented for this platform\n");
1126 #endif
1127  if (pipecolor != -1) {
1128  rz_config_set_i(core->config, "scr.color", pipecolor);
1129  }
1130  rz_config_set_i(core->config, "scr.interactive", si);
1131  return ret;
1132 }
1133 
1134 static char *parse_tmp_evals(RzCore *core, const char *str) {
1135  char *s = strdup(str);
1136  int i, argc = rz_str_split(s, ',');
1137  char *res = strdup("");
1138  if (!s || !res) {
1139  free(s);
1140  free(res);
1141  return NULL;
1142  }
1143  for (i = 0; i < argc; i++) {
1144  char *eq, *kv = (char *)rz_str_word_get0(s, i);
1145  if (!kv) {
1146  break;
1147  }
1148  eq = strchr(kv, '=');
1149  if (eq) {
1150  *eq = 0;
1151  const char *ov = rz_config_get(core->config, kv);
1152  if (!ov) {
1153  continue;
1154  }
1155  char *cmd = rz_str_newf("e %s=%s;", kv, ov);
1156  if (!cmd) {
1157  free(s);
1158  free(res);
1159  return NULL;
1160  }
1161  res = rz_str_prepend(res, cmd);
1162  free(cmd);
1163  rz_config_set(core->config, kv, eq + 1);
1164  *eq = '=';
1165  } else {
1166  eprintf("Missing '=' in e: expression (%s)\n", kv);
1167  }
1168  }
1169  free(s);
1170  return res;
1171 }
1172 
1173 static bool is_macro_command(const char *ptr) {
1174  ptr = rz_str_trim_head_ro(ptr);
1175  while (IS_DIGIT(*ptr)) {
1176  ptr++;
1177  }
1178  return *ptr == '(';
1179 }
1180 
1181 static char *find_ch_after_macro(char *ptr, char ch) {
1182  int depth = 0;
1183  while (*ptr) {
1184  if (depth == 0 && *ptr == ch) {
1185  return ptr;
1186  }
1187  if (*ptr == '(') {
1188  depth++;
1189  } else if (*ptr == ')') {
1190  depth--;
1191  }
1192  ptr++;
1193  }
1194  return NULL;
1195 }
1196 
1197 static int rz_core_cmd_subst(RzCore *core, char *cmd) {
1198  ut64 rep = strtoull(cmd, NULL, 10);
1199  int ret = 0, orep;
1200  char *colon = NULL, *icmd = NULL;
1201  bool tmpseek = false;
1202  bool original_tmpseek = core->tmpseek;
1203 
1204  if (rz_str_startswith(cmd, "GET /cmd/")) {
1205  memmove(cmd, cmd + 9, strlen(cmd + 9) + 1);
1206  char *http = strstr(cmd, "HTTP");
1207  if (http) {
1208  *http = 0;
1209  http--;
1210  if (*http == ' ') {
1211  *http = 0;
1212  }
1213  }
1214  rz_cons_printf("HTTP/1.0 %d %s\r\n%s"
1215  "Connection: close\r\nContent-Length: %d\r\n\r\n",
1216  200, "OK", "", -1);
1217  return rz_core_cmd0(core, cmd);
1218  }
1219 
1220  /* must store a local orig_offset because there can be
1221  * nested call of this function */
1222  ut64 orig_offset = core->offset;
1223  icmd = strdup(cmd);
1224  if (!icmd) {
1225  goto beach;
1226  }
1227 
1228  if (core->max_cmd_depth - core->cons->context->cmd_depth == 1) {
1229  core->prompt_offset = core->offset;
1230  }
1231  cmd = (char *)rz_str_trim_head_ro(icmd);
1233  // lines starting with # are ignored (never reach cmd_hash()), except #! and #?
1234  if (!*cmd) {
1235  if (core->cmdrepeat > 0) {
1236  rz_core_cmd_lastcmd_repeat(core, true);
1237  ret = rz_core_cmd_nullcallback(core);
1238  }
1239  goto beach;
1240  }
1241  if (!icmd || (cmd[0] == '#' && cmd[1] != '!' && cmd[1] != '?')) {
1242  goto beach;
1243  }
1244  if (*icmd && !strchr(icmd, '"')) {
1245  char *hash;
1246  for (hash = icmd + 1; *hash; hash++) {
1247  if (*hash == '\\') {
1248  hash++;
1249  if (*hash == '#') {
1250  continue;
1251  }
1252  }
1253  if (*hash == '#') {
1254  break;
1255  }
1256  }
1257  if (hash && *hash) {
1258  *hash = 0;
1259  rz_str_trim_tail(icmd);
1260  }
1261  }
1262  if (*cmd != '"') {
1263  if (!strchr(cmd, '\'')) { // allow | awk '{foo;bar}' // ignore ; if there's a single quote
1264  if (is_macro_command(cmd)) {
1265  colon = find_ch_after_macro(cmd, ';');
1266  } else {
1267  colon = strchr(cmd, ';');
1268  }
1269  if (colon) {
1270  *colon = 0;
1271  }
1272  }
1273  } else {
1274  colon = NULL;
1275  }
1276  if (rep > 0) {
1277  while (IS_DIGIT(*cmd)) {
1278  cmd++;
1279  }
1280  // do not repeat null cmd
1281  if (!*cmd) {
1282  goto beach;
1283  }
1284  }
1285  if (rep < 1) {
1286  rep = 1;
1287  }
1288  // XXX if output is a pipe then we don't want to be interactive
1289  if (rep > INTERACTIVE_MAX_REP) {
1290  if (rz_cons_is_interactive()) {
1291  if (!rz_cons_yesno('n', "Are you sure to repeat this %" PFMT64d " times? (y/N)", rep)) {
1292  goto beach;
1293  }
1294  }
1295  }
1296  // TODO: store in core->cmdtimes to speedup ?
1297  const char *cmdrep = core->cmdtimes ? core->cmdtimes : "";
1298  orep = rep;
1299 
1301 
1302  int ocur_enabled = core->print && core->print->cur_enabled;
1303  while (rep-- && *cmd) {
1304  if (core->print) {
1305  core->print->cur_enabled = false;
1306  if (ocur_enabled && core->seltab >= 0) {
1307  if (core->seltab == core->curtab) {
1308  core->print->cur_enabled = true;
1309  }
1310  }
1311  }
1312  if (rz_cons_is_breaked()) {
1313  break;
1314  }
1315  char *cr = strdup(cmdrep);
1316  core->break_loop = false;
1317  ret = rz_core_cmd_subst_i(core, cmd, colon, (rep == orep - 1) ? &tmpseek : NULL);
1318  if (ret && *cmd == 'q') {
1319  free(cr);
1320  goto beach;
1321  }
1322  if (core->break_loop) {
1323  free(cr);
1324  break;
1325  }
1326  if (cr && *cr && orep > 1) {
1327  // XXX: do not flush here, we need rz_cons_push () and rz_cons_pop()
1328  rz_cons_flush();
1329  // XXX: we must import register flags in C
1331  (void)rz_core_cmd0(core, cr);
1332  }
1333  free(cr);
1334  }
1335 
1337 
1338  if (tmpseek) {
1339  rz_core_seek(core, orig_offset, true);
1340  core->tmpseek = original_tmpseek;
1341  }
1342  if (core->print) {
1343  core->print->cur_enabled = ocur_enabled;
1344  }
1345  if (colon && colon[1]) {
1346  for (++colon; *colon == ';'; colon++) {
1347  ;
1348  }
1349  rz_core_cmd_subst(core, colon);
1350  } else {
1351  if (!*icmd) {
1353  }
1354  }
1355 beach:
1356  free(icmd);
1357  return ret;
1358 }
1359 
1360 static char *find_eoq(char *p) {
1361  for (; *p; p++) {
1362  if (*p == '"') {
1363  break;
1364  }
1365  if (*p == '\\' && p[1] == '"') {
1366  p++;
1367  }
1368  }
1369  return p;
1370 }
1371 
1372 static char *findSeparator(char *p) {
1373  char *q = strchr(p, '+');
1374  if (q) {
1375  return q;
1376  }
1377  return strchr(p, '-');
1378 }
1379 
1380 static void tmpenvs_free(void *item) {
1381  rz_sys_setenv(item, NULL);
1382  free(item);
1383 }
1384 
1385 static bool set_tmp_arch(RzCore *core, char *arch, char **tmparch) {
1386  rz_return_val_if_fail(tmparch, false);
1387  *tmparch = strdup(rz_config_get(core->config, "asm.arch"));
1388  rz_config_set(core->config, "asm.arch", arch);
1389  core->fixedarch = true;
1390  return true;
1391 }
1392 
1393 static bool set_tmp_bits(RzCore *core, int bits, char **tmpbits, int *cmd_ignbithints) {
1394  rz_return_val_if_fail(tmpbits, false);
1395  *tmpbits = strdup(rz_config_get(core->config, "asm.bits"));
1396  rz_config_set_i(core->config, "asm.bits", bits);
1397  core->fixedbits = true;
1398  // XXX: why?
1399  *cmd_ignbithints = rz_config_get_i(core->config, "analysis.ignbithints");
1400  rz_config_set_i(core->config, "analysis.ignbithints", 1);
1401  return true;
1402 }
1403 
1404 static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpseek) {
1405  RzList *tmpenvs = rz_list_newf(tmpenvs_free);
1406  const char *quotestr = "`";
1407  const char *tick = NULL;
1408  char *ptr, *ptr2, *str;
1409  char *arroba = NULL;
1410  char *grep = NULL;
1411  RzIODesc *tmpdesc = NULL;
1412  int pamode = !core->io->va;
1413  int i, ret = 0, pipefd;
1414  bool usemyblock = false;
1415  int scr_html = -1;
1416  int scr_color = -1;
1417  bool eos = false;
1418  bool haveQuote = false;
1419  bool oldfixedarch = core->fixedarch;
1420  bool oldfixedbits = core->fixedbits;
1421  bool cmd_tmpseek = false;
1422  ut64 tmpbsz = core->blocksize;
1423  int cmd_ignbithints = -1;
1424 
1425  if (!cmd) {
1426  rz_list_free(tmpenvs);
1427  return 0;
1428  }
1429  rz_str_trim(cmd);
1430 
1431  char *$0 = strstr(cmd, "$(");
1432  if ($0) {
1433  char *$1 = strchr($0 + 2, ')');
1434  if ($1) {
1435  *$0 = '`';
1436  *$1 = '`';
1437  memmove($0 + 1, $0 + 2, strlen($0 + 2) + 1);
1438  } else {
1439  eprintf("Unterminated $() block\n");
1440  }
1441  }
1442 
1443  /* quoted / raw command */
1444  switch (*cmd) {
1445  case '.':
1446  if (cmd[1] == '"') { /* interpret */
1447  rz_list_free(tmpenvs);
1448  return rz_cmd_call(core->rcmd, cmd);
1449  }
1450  break;
1451  case '"':
1452  for (; *cmd;) {
1453  int pipefd = -1;
1454  ut64 oseek = UT64_MAX;
1455  char *line, *p;
1456  haveQuote = *cmd == '"';
1457  if (haveQuote) {
1458  cmd++;
1459  p = *cmd ? find_eoq(cmd) : NULL;
1460  if (!p || !*p) {
1461  eprintf("Missing \" in (%s).", cmd);
1462  rz_list_free(tmpenvs);
1463  return false;
1464  }
1465  *p++ = 0;
1466  if (!*p) {
1467  eos = true;
1468  }
1469  } else {
1470  char *sc = strchr(cmd, ';');
1471  if (sc) {
1472  *sc = 0;
1473  }
1474  rz_core_cmd0(core, cmd);
1475  if (!sc) {
1476  break;
1477  }
1478  cmd = sc + 1;
1479  continue;
1480  }
1481  char op0 = 0;
1482  if (*p) {
1483  // workaround :D
1484  if (p[0] == '@') {
1485  p--;
1486  }
1487  while (p[1] == ';' || IS_WHITESPACE(p[1])) {
1488  p++;
1489  }
1490  if (p[1] == '@' || (p[1] && p[2] == '@')) {
1491  char *q = strchr(p + 1, '"');
1492  if (q) {
1493  op0 = *q;
1494  *q = 0;
1495  }
1496  haveQuote = q != NULL;
1497  oseek = core->offset;
1498  rz_core_seek(core, rz_num_math(core->num, p + 2), true);
1499  if (q) {
1500  *p = '"';
1501  p = q;
1502  } else {
1503  p = strchr(p + 1, ';');
1504  }
1505  }
1506  if (p && *p && p[1] == '>') {
1507  str = p + 2;
1508  while (*str == '>') {
1509  str++;
1510  }
1511  str = (char *)rz_str_trim_head_ro(str);
1512  rz_cons_flush();
1513  const bool append = p[2] == '>';
1514  pipefd = rz_cons_pipe_open(str, 1, append);
1515  }
1516  }
1517  line = strdup(cmd);
1518  line = rz_str_replace(line, "\\\"", "\"", true);
1519  if (p && *p && p[1] == '|') {
1520  str = (char *)rz_str_trim_head_ro(p + 2);
1521  rz_core_cmd_pipe_old(core, cmd, str);
1522  } else {
1523  rz_cmd_call(core->rcmd, line);
1524  }
1525  free(line);
1526  if (oseek != UT64_MAX) {
1527  rz_core_seek(core, oseek, true);
1528  }
1529  if (pipefd != -1) {
1530  rz_cons_flush();
1531  rz_cons_pipe_close(pipefd);
1532  }
1533  if (!p) {
1534  break;
1535  }
1536  if (eos) {
1537  break;
1538  }
1539  if (haveQuote) {
1540  if (*p == ';') {
1541  cmd = p + 1;
1542  } else {
1543  if (*p == '"') {
1544  cmd = p;
1545  } else {
1546  *p = op0;
1547  cmd = p;
1548  }
1549  }
1550  } else {
1551  cmd = p + 1;
1552  }
1553  }
1554  rz_list_free(tmpenvs);
1555  return true;
1556  case '(':
1557  if (cmd[1] != '*' && !strstr(cmd, ")()")) {
1558  rz_list_free(tmpenvs);
1559  return rz_cmd_call(core->rcmd, cmd);
1560  }
1561  break;
1562  case '?':
1563  if (cmd[1] == '>') {
1565  rz_list_free(tmpenvs);
1566  return true;
1567  }
1568  }
1569 
1570  // TODO must honor `
1571  /* comments */
1572  if (*cmd != '#') {
1573  ptr = (char *)rz_str_firstbut(cmd, '#', "`\""); // TODO: use quotestr here
1574  if (ptr && (ptr[1] == ' ' || ptr[1] == '\t')) {
1575  *ptr = '\0';
1576  }
1577  }
1578 
1579  /* multiple commands */
1580  // TODO: must honor " and ` boundaries
1581  // ptr = strrchr (cmd, ';');
1582  if (*cmd != '#') {
1583  if (is_macro_command(cmd)) {
1584  ptr = find_ch_after_macro(cmd, ';');
1585  } else {
1586  ptr = (char *)rz_str_lastbut(cmd, ';', quotestr);
1587  }
1588  if (colon && ptr) {
1589  int ret;
1590  *ptr = '\0';
1591  if (rz_core_cmd_subst(core, cmd) == -1) {
1592  rz_list_free(tmpenvs);
1593  return -1;
1594  }
1595  cmd = ptr + 1;
1596  ret = rz_core_cmd_subst(core, cmd);
1597  *ptr = ';';
1598  rz_list_free(tmpenvs);
1599  return ret;
1600  // rz_cons_flush ();
1601  }
1602  }
1603 
1604  // TODO must honor " and `
1605  /* pipe console to shell process */
1606  // ptr = strchr (cmd, '|');
1607  ptr = (char *)rz_str_lastbut(cmd, '|', quotestr);
1608  if (ptr) {
1609  if (ptr > cmd) {
1610  char *ch = ptr - 1;
1611  if (*ch == '\\') {
1612  memmove(ch, ptr, strlen(ptr) + 1);
1613  goto escape_pipe;
1614  }
1615  }
1616  char *ptr2 = strchr(cmd, '`');
1617  if (!ptr2 || (ptr2 && ptr2 > ptr)) {
1618  if (!tick || (tick && tick > ptr)) {
1619  *ptr = '\0';
1620  cmd = rz_str_trim_nc(cmd);
1621  if (!strcmp(ptr + 1, "?")) { // "|?"
1623  rz_list_free(tmpenvs);
1624  return ret;
1625  } else if (!strncmp(ptr + 1, "H", 1)) { // "|H"
1626  scr_html = rz_config_get_i(core->config, "scr.html");
1627  rz_config_set_i(core->config, "scr.html", true);
1628  } else if (!strcmp(ptr + 1, ".")) { // "|."
1629  ret = *cmd ? rz_core_cmdf(core, ".%s", cmd) : 0;
1630  rz_list_free(tmpenvs);
1631  return ret;
1632  } else if (ptr[1]) { // "| grep .."
1633  int value = core->num->value;
1634  if (*cmd) {
1635  rz_core_cmd_pipe_old(core, cmd, ptr + 1);
1636  } else {
1637  char *res = rz_io_system(core->io, ptr + 1);
1638  if (res) {
1639  rz_cons_printf("%s\n", res);
1640  free(res);
1641  }
1642  }
1643  core->num->value = value;
1644  rz_list_free(tmpenvs);
1645  return 0;
1646  } else { // "|"
1647  scr_html = rz_config_get_i(core->config, "scr.html");
1648  rz_config_set_i(core->config, "scr.html", 0);
1649  scr_color = rz_config_get_i(core->config, "scr.color");
1650  rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
1651  }
1652  }
1653  }
1654  }
1655 escape_pipe:
1656 
1657  // TODO must honor " and `
1658  /* bool conditions */
1659  ptr = (char *)rz_str_lastbut(cmd, '&', quotestr);
1660  // ptr = strchr (cmd, '&');
1661  while (ptr && *ptr && ptr[1] == '&') {
1662  *ptr = '\0';
1663  ret = rz_cmd_call(core->rcmd, cmd);
1664  if (ret == -1) {
1665  eprintf("command error(%s)\n", cmd);
1666  if (scr_html != -1) {
1667  rz_config_set_i(core->config, "scr.html", scr_html);
1668  }
1669  if (scr_color != -1) {
1670  rz_config_set_i(core->config, "scr.color", scr_color);
1671  }
1672  rz_list_free(tmpenvs);
1673  return ret;
1674  }
1675  for (cmd = ptr + 2; cmd && *cmd == ' '; cmd++) {
1676  ;
1677  }
1678  ptr = strchr(cmd, '&');
1679  }
1680 
1681  ptr = strstr(cmd, "?*");
1682  if (ptr && (ptr == cmd || ptr[-1] != '~')) {
1683  ptr[0] = 0;
1684  if (*cmd != '#') {
1685  int detail = 0;
1686  if (cmd < ptr && ptr[-1] == '?') {
1687  detail++;
1688  if (cmd < ptr - 1 && ptr[-2] == '?') {
1689  detail++;
1690  }
1691  }
1693  recursive_help(core, detail, cmd);
1695  rz_cons_grep_parsecmd(ptr + 2, "`");
1696  if (scr_html != -1) {
1697  rz_config_set_i(core->config, "scr.html", scr_html);
1698  }
1699  if (scr_color != -1) {
1700  rz_config_set_i(core->config, "scr.color", scr_color);
1701  }
1702  rz_list_free(tmpenvs);
1703  return 0;
1704  }
1705  }
1706 
1707  /* pipe console to file */
1708  ptr = (char *)rz_str_firstbut(cmd, '>', "\"");
1709  // TODO honor `
1710  if (ptr) {
1711  if (ptr > cmd) {
1712  char *ch = ptr - 1;
1713  if (*ch == '\\') {
1714  memmove(ch, ptr, strlen(ptr) + 1);
1715  goto escape_redir;
1716  }
1717  }
1718  if (ptr[0] && ptr[1] == '?') {
1720  rz_list_free(tmpenvs);
1721  return true;
1722  }
1723  int fdn = 1;
1724  int pipecolor = rz_config_get_i(core->config, "scr.color.pipe");
1725  int use_editor = false;
1726  int ocolor = rz_config_get_i(core->config, "scr.color");
1727  *ptr = '\0';
1728  str = ptr + 1 + (ptr[1] == '>');
1729  rz_str_trim(str);
1730  if (!*str) {
1731  eprintf("No output?\n");
1732  goto next2;
1733  }
1734  /* rz_cons_flush() handles interactive output (to the terminal)
1735  * differently (e.g. asking about too long output). This conflicts
1736  * with piping to a file. Disable it while piping. */
1737  if (ptr > (cmd + 1) && IS_WHITECHAR(ptr[-2])) {
1738  char *fdnum = ptr - 1;
1739  if (*fdnum == 'H') { // "H>"
1740  scr_html = rz_config_get_i(core->config, "scr.html");
1741  rz_config_set_i(core->config, "scr.html", true);
1742  pipecolor = true;
1743  *fdnum = 0;
1744  } else {
1745  if (IS_DIGIT(*fdnum)) {
1746  fdn = *fdnum - '0';
1747  }
1748  *fdnum = 0;
1749  }
1750  }
1751  rz_cons_set_interactive(false);
1752  if (!strcmp(str, "-")) {
1753  use_editor = true;
1754  str = rz_file_temp("dumpedit");
1755  rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
1756  }
1757  const bool appendResult = (ptr[1] == '>');
1758  if (*str == '$') {
1759  // pipe to alias variable
1760  // register output of command as an alias
1761  char *o = rz_core_cmd_str(core, cmd);
1762  if (appendResult) {
1763  char *oldText = rz_cmd_alias_get(core->rcmd, str, 1);
1764  if (oldText) {
1765  char *two = rz_str_newf("%s%s", oldText, o);
1766  if (two) {
1767  rz_cmd_alias_set(core->rcmd, str, two, 1);
1768  free(two);
1769  }
1770  } else {
1771  char *n = rz_str_newf("$%s", o);
1772  rz_cmd_alias_set(core->rcmd, str, n, 1);
1773  free(n);
1774  }
1775  } else {
1776  char *n = rz_str_newf("$%s", o);
1777  rz_cmd_alias_set(core->rcmd, str, n, 1);
1778  free(n);
1779  }
1780  ret = 0;
1781  free(o);
1782  } else if (fdn > 0) {
1783  // pipe to file (or append)
1784  pipefd = rz_cons_pipe_open(str, fdn, appendResult);
1785  if (pipefd != -1) {
1786  if (!pipecolor) {
1787  rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
1788  }
1789  ret = rz_core_cmd_subst(core, cmd);
1790  rz_cons_flush();
1791  rz_cons_pipe_close(pipefd);
1792  }
1793  }
1795  if (!pipecolor) {
1796  rz_config_set_i(core->config, "scr.color", ocolor);
1797  }
1798  if (use_editor) {
1799  const char *editor = rz_config_get(core->config, "cfg.editor");
1800  if (editor && *editor) {
1801  rz_sys_cmdf("%s '%s'", editor, str);
1802  rz_file_rm(str);
1803  } else {
1804  eprintf("No cfg.editor configured\n");
1805  }
1806  rz_config_set_i(core->config, "scr.color", ocolor);
1807  free(str);
1808  }
1809  if (scr_html != -1) {
1810  rz_config_set_i(core->config, "scr.html", scr_html);
1811  }
1812  if (scr_color != -1) {
1813  rz_config_set_i(core->config, "scr.color", scr_color);
1814  }
1815  rz_list_free(tmpenvs);
1816  return ret;
1817  }
1818 escape_redir:
1819 next2:
1820  /* sub commands */
1821  ptr = strchr(cmd, '`');
1822  if (ptr) {
1823  if (ptr > cmd) {
1824  char *ch = ptr - 1;
1825  if (*ch == '\\') {
1826  memmove(ch, ptr, strlen(ptr) + 1);
1827  goto escape_backtick;
1828  }
1829  }
1830  bool empty = false;
1831  int oneline = 1;
1832  if (ptr[1] == '`') {
1833  memmove(ptr, ptr + 1, strlen(ptr));
1834  oneline = 0;
1835  empty = true;
1836  }
1837  ptr2 = strchr(ptr + 1, '`');
1838  if (empty) {
1839  /* do nothing */
1840  } else if (!ptr2) {
1841  eprintf("parse: Missing backtick in expression.\n");
1842  goto fail;
1843  } else {
1844  int value = core->num->value;
1845  *ptr = '\0';
1846  *ptr2 = '\0';
1847  if (ptr[1] == '!') {
1848  str = rz_core_cmd_str_pipe(core, ptr + 1);
1849  } else {
1850  // Color disabled when doing backticks ?e `pi 1`
1851  int ocolor = rz_config_get_i(core->config, "scr.color");
1852  rz_config_set_i(core->config, "scr.color", 0);
1853  core->cmd_in_backticks = true;
1854  str = rz_core_cmd_str(core, ptr + 1);
1855  core->cmd_in_backticks = false;
1856  rz_config_set_i(core->config, "scr.color", ocolor);
1857  }
1858  if (!str) {
1859  goto fail;
1860  }
1861  // ignore contents if first char is pipe or comment
1862  if (*str == '|' || *str == '*') {
1863  eprintf("rz_core_cmd_subst_i: invalid backticked command\n");
1864  free(str);
1865  goto fail;
1866  }
1867  if (oneline && str) {
1868  for (i = 0; str[i]; i++) {
1869  if (str[i] == '\n') {
1870  str[i] = ' ';
1871  }
1872  }
1873  }
1874  str = rz_str_append(str, ptr2 + 1);
1876  core->num->value = value;
1877  ret = rz_core_cmd_subst(core, cmd);
1878  free(cmd);
1879  if (scr_html != -1) {
1880  rz_config_set_i(core->config, "scr.html", scr_html);
1881  }
1882  free(str);
1883  rz_list_free(tmpenvs);
1884  return ret;
1885  }
1886  }
1887 escape_backtick:
1888  // TODO must honor " and `
1889  if (*cmd != '"' && *cmd) {
1890  const char *s = strstr(cmd, "~?");
1891  if (s) {
1892  bool showHelp = false;
1893  if (cmd == s) {
1894  // ~?
1895  // ~??
1896  showHelp = true;
1897  } else {
1898  // pd~?
1899  // pd~??
1900  if (!strcmp(s, "~??")) {
1901  showHelp = true;
1902  }
1903  }
1904  if (showHelp) {
1906  rz_list_free(tmpenvs);
1907  return true;
1908  }
1909  }
1910  }
1911  if (*cmd != '.') {
1912  grep = rz_cons_grep_strip(cmd, quotestr);
1913  }
1914 
1915  /* temporary seek commands */
1916  // if (*cmd != '(' && *cmd != '"') {
1917  if (*cmd != '"') {
1918  ptr = strchr(cmd, '@');
1919  if (ptr == cmd + 1 && *cmd == '?') {
1920  ptr = NULL;
1921  }
1922  } else {
1923  ptr = NULL;
1924  }
1925 
1926  cmd_tmpseek = core->tmpseek = ptr != NULL;
1927  int rc = 0;
1928  if (ptr) {
1929  char *f, *ptr2 = strchr(ptr + 1, '!');
1930  ut64 addr = core->offset;
1931  bool addr_is_set = false;
1932  char *tmpbits = NULL;
1933  const char *offstr = NULL;
1934  bool is_bits_set = false;
1935  bool is_arch_set = false;
1936  char *tmpeval = NULL;
1937  char *tmpasm = NULL;
1938  bool flgspc_changed = false;
1939  int tmpfd = -1;
1940  size_t sz;
1941  int len;
1942  ut8 *buf;
1943 
1944  *ptr++ = '\0';
1945  repeat_arroba:
1946  arroba = (ptr[0] && ptr[1] && ptr[2]) ? strchr(ptr + 2, '@') : NULL;
1947  if (arroba) {
1948  *arroba = 0;
1949  }
1950 
1951  for (; *ptr == ' '; ptr++) {
1952  // nothing to see here
1953  }
1954  if (*ptr && ptr[1] == ':') {
1955  /* do nothing here */
1956  } else {
1957  ptr--;
1958  }
1959 
1960  rz_str_trim_tail(ptr);
1961 
1962  if (ptr[1] == '?') {
1964  } else if (ptr[1] == '%') { // "@%"
1965  char *k = strdup(ptr + 2);
1966  char *v = strchr(k, '=');
1967  if (v) {
1968  *v++ = 0;
1969  rz_sys_setenv(k, v);
1970  rz_list_append(tmpenvs, k);
1971  } else {
1972  free(k);
1973  }
1974  } else if (ptr[1] == '.') { // "@."
1975  if (ptr[2] == '.') { // "@.."
1976  if (ptr[3] == '.') { // "@..."
1977  ut64 addr = rz_num_tail(core->num, core->offset, ptr + 4);
1978  rz_core_block_size(core, RZ_ABS((st64)addr - (st64)core->offset));
1979  goto fuji;
1980  } else {
1981  addr = rz_num_tail(core->num, core->offset, ptr + 3);
1982  rz_core_seek(core, addr, true);
1983  cmd_tmpseek = core->tmpseek = true;
1984  goto fuji;
1985  }
1986  } else {
1987  // WAT DU
1988  eprintf("TODO: what do you expect for @. import offset from file maybe?\n");
1989  }
1990  } else if (ptr[0] && ptr[1] == ':' && ptr[2]) {
1991  switch (ptr[0]) {
1992  case 'F': // "@F:" // temporary flag space
1993  flgspc_changed = rz_flag_space_push(core->flags, ptr + 2);
1994  break;
1995  case 'B': // "@B:#" // seek to the last instruction in current bb
1996  {
1997  int index = (int)rz_num_math(core->num, ptr + 2);
1998  if (rz_core_seek_bb_instruction(core, index)) {
1999  cmd_tmpseek = core->tmpseek = true;
2000  }
2001  break;
2002  } break;
2003  case 'f': // "@f:" // slurp file in block
2004  f = rz_file_slurp(ptr + 2, &sz);
2005  if (f) {
2006  {
2007  RzBuffer *b = rz_buf_new_with_bytes((const ut8 *)f, (ut64)sz);
2008  RzIODesc *d = rz_io_open_buffer(core->io, b, RZ_PERM_RWX, 0);
2009  if (d) {
2010  if (tmpdesc) {
2011  rz_io_desc_close(tmpdesc);
2012  }
2013  tmpdesc = d;
2014  if (pamode) {
2015  rz_config_set_i(core->config, "io.va", 1);
2016  }
2017  rz_io_map_new(core->io, d->fd, d->perm, 0, core->offset, rz_buf_size(b));
2018  }
2019  }
2020  } else {
2021  eprintf("cannot open '%s'\n", ptr + 3);
2022  }
2023  break;
2024  case 'r': // "@r:" // regname
2025  if (ptr[1] == ':') {
2026  ut64 regval;
2027  char *mander = strdup(ptr + 2);
2028  char *sep = findSeparator(mander);
2029  if (sep) {
2030  char ch = *sep;
2031  *sep = 0;
2032  regval = rz_debug_reg_get(core->dbg, mander);
2033  *sep = ch;
2034  char *numexpr = rz_str_newf("0x%" PFMT64x "%s", regval, sep);
2035  regval = rz_num_math(core->num, numexpr);
2036  free(numexpr);
2037  } else {
2038  regval = rz_debug_reg_get(core->dbg, ptr + 2);
2039  }
2040  rz_core_seek(core, regval, true);
2041  cmd_tmpseek = core->tmpseek = true;
2042  free(mander);
2043  }
2044  break;
2045  case 'b': // "@b:" // bits
2046  is_bits_set = set_tmp_bits(core, rz_num_math(core->num, ptr + 2), &tmpbits, &cmd_ignbithints);
2047  break;
2048  case 'i': // "@i:"
2049  {
2050  ut64 addr = rz_num_math(core->num, ptr + 2);
2051  if (addr) {
2052  rz_core_seek_opcode(core, addr, false);
2053  cmd_tmpseek = core->tmpseek = true;
2054  }
2055  } break;
2056  case 'e': // "@e:"
2057  {
2058  char *cmd = parse_tmp_evals(core, ptr + 2);
2059  if (!tmpeval) {
2060  tmpeval = cmd;
2061  } else {
2062  tmpeval = rz_str_prepend(tmpeval, cmd);
2063  free(cmd);
2064  }
2065  } break;
2066  case 'v': // "@v:" // value (honors asm.bits and cfg.bigendian)
2067  if (ptr[1] == ':') {
2068  ut8 buf[8] = { 0 };
2069  ut64 v = rz_num_math(core->num, ptr + 2);
2070  int be = rz_config_get_i(core->config, "cfg.bigendian");
2071  int bi = rz_config_get_i(core->config, "asm.bits");
2072  if (bi == 64) {
2073  rz_write_ble64(buf, v, be);
2074  len = 8;
2075  } else {
2076  rz_write_ble32(buf, v, be);
2077  len = 4;
2078  }
2079  rz_core_block_size(core, RZ_ABS(len));
2081  RzIODesc *d = rz_io_open_buffer(core->io, b, RZ_PERM_RWX, 0);
2082  if (d) {
2083  if (tmpdesc) {
2084  rz_io_desc_close(tmpdesc);
2085  }
2086  tmpdesc = d;
2087  if (pamode) {
2088  rz_config_set_i(core->config, "io.va", 1);
2089  }
2090  rz_io_map_new(core->io, d->fd, d->perm, 0, core->offset, rz_buf_size(b));
2091  rz_core_block_size(core, len);
2092  rz_core_block_read(core);
2093  }
2094  } else {
2095  eprintf("Invalid @v: syntax\n");
2096  }
2097  break;
2098  case 'x': // "@x:" // hexpairs
2099  if (ptr[1] == ':') {
2100  buf = malloc(strlen(ptr + 2) + 1);
2101  if (buf) {
2102  len = rz_hex_str2bin(ptr + 2, buf);
2103  rz_core_block_size(core, RZ_ABS(len));
2104  if (len > 0) {
2106  RzIODesc *d = rz_io_open_buffer(core->io, b, RZ_PERM_RWX, 0);
2107  if (d) {
2108  if (tmpdesc) {
2109  rz_io_desc_close(tmpdesc);
2110  }
2111  tmpdesc = d;
2112  if (pamode) {
2113  rz_config_set_i(core->config, "io.va", 1);
2114  }
2115  rz_io_map_new(core->io, d->fd, d->perm, 0, core->offset, rz_buf_size(b));
2116  rz_core_block_size(core, len);
2117  rz_core_block_read(core);
2118  }
2119  } else {
2120  eprintf("Error: Invalid hexpairs for @x:\n");
2121  }
2122  free(buf);
2123  } else {
2124  eprintf("cannot allocate\n");
2125  }
2126  } else {
2127  eprintf("Invalid @x: syntax\n");
2128  }
2129  break;
2130  case 'k': // "@k"
2131  {
2132  char *out = sdb_querys(core->sdb, NULL, 0, ptr + ((ptr[1]) ? 2 : 1));
2133  if (out) {
2134  rz_core_seek(core, rz_num_math(core->num, out), true);
2135  free(out);
2136  usemyblock = true;
2137  }
2138  } break;
2139  case 'o': // "@o:3"
2140  if (ptr[1] == ':') {
2141  tmpfd = core->io->desc ? core->io->desc->fd : -1;
2142  rz_io_use_fd(core->io, atoi(ptr + 2));
2143  }
2144  break;
2145  case 'a': // "@a:"
2146  if (ptr[1] == ':') {
2147  char *q = strchr(ptr + 2, ':');
2148  if (q) {
2149  *q++ = 0;
2150  int bits = rz_num_math(core->num, q);
2151  is_bits_set = set_tmp_bits(core, bits, &tmpbits, &cmd_ignbithints);
2152  }
2153  is_arch_set = set_tmp_arch(core, ptr + 2, &tmpasm);
2154  } else {
2155  eprintf("Usage: pd 10 @a:arm:32\n");
2156  }
2157  break;
2158  case 's': // "@s:" // wtf syntax
2159  {
2160  len = strlen(ptr + 2);
2161  rz_core_block_size(core, len);
2162  const ut8 *buf = (const ut8 *)rz_str_trim_head_ro(ptr + 2);
2163 
2164  if (len > 0) {
2166  RzIODesc *d = rz_io_open_buffer(core->io, b, RZ_PERM_RWX, 0);
2167  if (!core->io->va) {
2168  rz_config_set_i(core->config, "io.va", 1);
2169  }
2170  if (d) {
2171  if (tmpdesc) {
2172  rz_io_desc_close(tmpdesc);
2173  }
2174  tmpdesc = d;
2175  if (pamode) {
2176  rz_config_set_i(core->config, "io.va", 1);
2177  }
2178  rz_io_map_new(core->io, d->fd, d->perm, 0, core->offset, rz_buf_size(b));
2179  rz_core_block_size(core, len);
2180  // rz_core_block_read (core);
2181  }
2182  }
2183  } break;
2184  default:
2185  goto ignore;
2186  }
2187  *ptr = '@';
2188  /* trim whitespaces before the @ */
2189  /* Fixes pd @x:9090 */
2190  char *trim = ptr - 2;
2191  while (trim > cmd) {
2192  if (!IS_WHITESPACE(*trim)) {
2193  break;
2194  }
2195  *trim = 0;
2196  trim--;
2197  }
2198  goto next_arroba;
2199  }
2200  ignore:
2201  rz_str_trim_head(ptr + 1);
2202  cmd = rz_str_trim_nc(cmd);
2203  if (ptr2) {
2204  if (strlen(ptr + 1) == 13 && strlen(ptr2 + 1) == 6 &&
2205  !memcmp(ptr + 1, "0x", 2) &&
2206  !memcmp(ptr2 + 1, "0x", 2)) {
2207  /* 0xXXXX:0xYYYY */
2208  } else if (strlen(ptr + 1) == 9 && strlen(ptr2 + 1) == 4) {
2209  /* XXXX:YYYY */
2210  } else {
2211  *ptr2 = '\0';
2212  if (!ptr2[1]) {
2213  goto fail;
2214  }
2216  core, rz_num_math(core->num, ptr2 + 1));
2217  }
2218  }
2219 
2220  rz_str_trim_head(ptr + 1);
2221  offstr = ptr + 1;
2222 
2223  addr = (*offstr == '{') ? core->offset : rz_num_math(core->num, offstr);
2224  addr_is_set = true;
2225 
2226  if (isalpha((ut8)ptr[1]) && !addr) {
2227  if (!rz_flag_get(core->flags, ptr + 1)) {
2228  eprintf("Invalid address (%s)\n", ptr + 1);
2229  goto fail;
2230  }
2231  } else {
2232  char ch = *offstr;
2233  if (ch == '-' || ch == '+') {
2234  addr = core->offset + addr;
2235  }
2236  }
2237  // remap thhe tmpdesc if any
2238  if (addr) {
2239  RzIODesc *d = tmpdesc;
2240  if (d) {
2241  rz_io_map_new(core->io, d->fd, d->perm, 0, addr, rz_io_desc_size(d));
2242  }
2243  }
2244  next_arroba:
2245  if (arroba) {
2246  ptr = arroba + 1;
2247  *arroba = '@';
2248  arroba = NULL;
2249  goto repeat_arroba;
2250  }
2251  core->fixedblock = !!tmpdesc;
2252  if (core->fixedblock) {
2253  rz_core_block_read(core);
2254  }
2255  if (ptr[1] == '@') {
2256  if (ptr[2] == '@') {
2257  char *rule = ptr + 3;
2258  while (*rule && *rule == ' ') {
2259  rule++;
2260  }
2261  ret = rz_core_cmd_foreach3(core, cmd, rule);
2262  } else {
2263  ret = rz_core_cmd_foreach(core, cmd, ptr + 2);
2264  }
2265  } else {
2266  bool tmpseek = false;
2267  const char *fromvars[] = { "analysis.from", "diff.from", "graph.from", "search.from", "zoom.from", NULL };
2268  const char *tovars[] = { "analysis.to", "diff.to", "graph.to", "search.to", "zoom.to", NULL };
2269  ut64 curfrom[RZ_ARRAY_SIZE(fromvars) - 1], curto[RZ_ARRAY_SIZE(tovars) - 1];
2270 
2271  // "@{A B}"
2272  if (ptr[1] == '{') {
2273  char *range = ptr + 2;
2274  char *p = strchr(range, ' ');
2275  if (!p) {
2276  eprintf("Usage: / ABCD @{0x1000 0x3000}\n");
2277  eprintf("Run command and define the following vars:\n");
2278  eprintf(" (analysis|diff|graph|search|zoom).{from,to}\n");
2279  free(tmpeval);
2280  free(tmpasm);
2281  free(tmpbits);
2282  goto fail;
2283  }
2284  char *arg = p + 1;
2285  int arg_len = strlen(arg);
2286  if (arg_len > 0) {
2287  arg[arg_len - 1] = 0;
2288  }
2289  *p = '\x00';
2290  ut64 from = rz_num_math(core->num, range);
2291  ut64 to = rz_num_math(core->num, arg);
2292  // save current ranges
2293  for (i = 0; fromvars[i]; i++) {
2294  curfrom[i] = rz_config_get_i(core->config, fromvars[i]);
2295  }
2296  for (i = 0; tovars[i]; i++) {
2297  curto[i] = rz_config_get_i(core->config, tovars[i]);
2298  }
2299  // set new ranges
2300  for (i = 0; fromvars[i]; i++) {
2301  rz_config_set_i(core->config, fromvars[i], from);
2302  }
2303  for (i = 0; tovars[i]; i++) {
2304  rz_config_set_i(core->config, tovars[i], to);
2305  }
2306  tmpseek = true;
2307  }
2308  if (usemyblock) {
2309  if (addr_is_set) {
2310  core->offset = addr;
2311  }
2313  } else {
2314  if (addr_is_set) {
2315  if (ptr[1]) {
2316  rz_core_seek(core, addr, true);
2317  rz_core_block_read(core);
2318  }
2319  }
2321  }
2322  if (tmpseek) {
2323  // restore ranges
2324  for (i = 0; fromvars[i]; i++) {
2325  rz_config_set_i(core->config, fromvars[i], curfrom[i]);
2326  }
2327  for (i = 0; tovars[i]; i++) {
2328  rz_config_set_i(core->config, tovars[i], curto[i]);
2329  }
2330  }
2331  }
2332  if (ptr2) {
2333  *ptr2 = '!';
2334  rz_core_block_size(core, tmpbsz);
2335  }
2336  if (is_arch_set) {
2337  core->fixedarch = oldfixedarch;
2338  rz_config_set(core->config, "asm.arch", tmpasm);
2339  RZ_FREE(tmpasm);
2340  }
2341  if (tmpfd != -1) {
2342  // TODO: reuse tmpfd instead of
2343  rz_io_use_fd(core->io, tmpfd);
2344  }
2345  if (tmpdesc) {
2346  if (pamode) {
2347  rz_config_set_i(core->config, "io.va", 0);
2348  }
2349  rz_io_desc_close(tmpdesc);
2350  tmpdesc = NULL;
2351  }
2352  if (is_bits_set) {
2353  rz_config_set(core->config, "asm.bits", tmpbits);
2354  core->fixedbits = oldfixedbits;
2355  }
2356  if (tmpbsz != core->blocksize) {
2357  rz_core_block_size(core, tmpbsz);
2358  }
2359  if (tmpeval) {
2360  rz_core_cmd0(core, tmpeval);
2361  RZ_FREE(tmpeval);
2362  }
2363  if (flgspc_changed) {
2364  rz_flag_space_pop(core->flags);
2365  }
2366  *ptr = '@';
2367  rc = ret;
2368  goto beach;
2369  }
2370 fuji:
2371  if (cmd) {
2373  rc = rz_cmd_call(core->rcmd, cmd);
2374  } else {
2375  rc = false;
2376  }
2377 beach:
2378  if (grep) {
2379  char *old_grep = grep;
2380  grep = rz_cmd_unescape_arg(old_grep, true);
2381  free(old_grep);
2382  }
2383  rz_cons_grep_process(grep);
2384  if (scr_html != -1) {
2385  rz_cons_flush();
2386  rz_config_set_i(core->config, "scr.html", scr_html);
2387  }
2388  if (scr_color != -1) {
2389  rz_config_set_i(core->config, "scr.color", scr_color);
2390  }
2391  rz_list_free(tmpenvs);
2392  if (tmpdesc) {
2393  rz_io_desc_close(tmpdesc);
2394  tmpdesc = NULL;
2395  }
2396  core->fixedarch = oldfixedarch;
2397  core->fixedbits = oldfixedbits;
2398  if (tmpseek) {
2399  *tmpseek = cmd_tmpseek;
2400  }
2401  if (cmd_ignbithints != -1) {
2402  rz_config_set_i(core->config, "analysis.ignbithints", cmd_ignbithints);
2403  }
2404  return rc;
2405 fail:
2406  rc = -1;
2407  goto beach;
2408 }
2409 
2412  const char *cmd;
2413 };
2414 
2415 static bool copy_into_flagitem_list(RzFlagItem *flg, void *u) {
2416  RzFlagItem *fi = rz_mem_dup(flg, sizeof(RzFlagItem));
2417  rz_list_append(u, fi);
2418  return true;
2419 }
2420 
2421 static void foreach_pairs(RzCore *core, const char *cmd, const char *each) {
2422  const char *arg;
2423  int pair = 0;
2424  for (arg = each;;) {
2425  if (!arg) {
2426  return;
2427  }
2428  char *next = strchr(arg, ' ');
2429  if (next) {
2430  *next = 0;
2431  }
2432  if (arg && *arg) {
2433  ut64 n = rz_num_get(NULL, arg);
2434  if (pair % 2) {
2435  rz_core_block_size(core, n);
2436  rz_core_cmd0(core, cmd);
2437  } else {
2438  rz_core_seek(core, n, true);
2439  }
2440  pair++;
2441  }
2442  if (!next) {
2443  break;
2444  }
2445  arg = next + 1;
2446  }
2447 }
2448 
2449 RZ_API int rz_core_cmd_foreach3(RzCore *core, const char *cmd, char *each) { // "@@@"
2450  RzDebug *dbg = core->dbg;
2451  RzList *list;
2452  const RzList *head;
2453  RzListIter *iter;
2454  int i;
2455  const char *filter = NULL;
2456 
2457  if (each[0] && each[1] == ':') {
2458  filter = each + 2;
2459  }
2460 
2461  switch (each[0]) {
2462  case '=':
2463  foreach_pairs(core, cmd, each + 1);
2464  break;
2465  case '?':
2467  break;
2468  case 'c':
2469  if (filter) {
2470  char *arg = rz_core_cmd_str(core, filter);
2471  foreach_pairs(core, cmd, arg);
2472  free(arg);
2473  } else {
2474  eprintf("Usage: @@@c:command # same as @@@=`command`\n");
2475  }
2476  break;
2477  case 'C': {
2478  char *glob = filter ? rz_str_trim_dup(filter) : NULL;
2479  RzIntervalTreeIter it;
2480  RzAnalysisMetaItem *meta;
2481  rz_interval_tree_foreach (&core->analysis->meta, it, meta) {
2482  if (meta->type != RZ_META_TYPE_COMMENT) {
2483  continue;
2484  }
2485  if (!glob || (meta->str && rz_str_glob(meta->str, glob))) {
2486  rz_core_seek(core, rz_interval_tree_iter_get(&it)->start, true);
2487  rz_core_cmd0(core, cmd);
2488  }
2489  }
2490  free(glob);
2491  break;
2492  }
2493  case 'm': {
2494  int fd = rz_io_fd_get_current(core->io);
2495  // only iterate maps of current fd
2496  RzList *maps = rz_io_map_get_for_fd(core->io, fd);
2497  RzIOMap *map;
2498  if (maps) {
2499  RzListIter *iter;
2500  rz_list_foreach (maps, iter, map) {
2501  rz_core_seek(core, map->itv.addr, true);
2502  rz_core_block_size(core, map->itv.size);
2503  rz_core_cmd0(core, cmd);
2504  }
2505  rz_list_free(maps);
2506  }
2507  } break;
2508  case 'M':
2509  if (dbg && dbg->cur && dbg->maps) {
2510  RzDebugMap *map;
2511  rz_list_foreach (dbg->maps, iter, map) {
2512  rz_core_seek(core, map->addr, true);
2513  // rz_core_block_size (core, map->size);
2514  rz_core_cmd0(core, cmd);
2515  }
2516  }
2517  break;
2518  case 't':
2519  // iterate over all threads
2520  if (dbg && dbg->cur && dbg->cur->threads) {
2521  int origpid = dbg->pid;
2522  RzDebugPid *p;
2523  list = dbg->cur->threads(dbg, dbg->pid);
2524  if (!list) {
2525  return false;
2526  }
2527  rz_list_foreach (list, iter, p) {
2528  rz_core_cmdf(core, "dp %d", p->pid);
2529  rz_cons_printf("PID %d\n", p->pid);
2530  rz_core_cmd0(core, cmd);
2531  }
2532  rz_core_cmdf(core, "dp %d", origpid);
2533  rz_list_free(list);
2534  }
2535  break;
2536  case 'r': // @@@r
2537  {
2538  RzReg *reg = rz_core_reg_default(core);
2539  ut64 offorig = core->offset;
2540  for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
2541  RzRegItem *item;
2542  ut64 value;
2543  head = rz_reg_get_list(reg, i);
2544  if (!head) {
2545  continue;
2546  }
2548  rz_list_foreach (head, iter, item) {
2549  if (item->size != core->analysis->bits) {
2550  continue;
2551  }
2552  if (item->type != i) {
2553  continue;
2554  }
2555  rz_list_append(list, strdup(item->name));
2556  }
2557  const char *item_name;
2558  rz_list_foreach (list, iter, item_name) {
2559  value = rz_reg_getv(reg, item_name);
2560  rz_core_seek(core, value, true);
2561  rz_cons_printf("%s: ", item_name);
2562  rz_core_cmd0(core, cmd);
2563  }
2564  rz_list_free(list);
2565  }
2566  rz_core_seek(core, offorig, true);
2567  } break;
2568  case 'i': // @@@i
2569  {
2570  RzBinImport *imp;
2571  ut64 offorig = core->offset;
2572  list = rz_bin_get_imports(core->bin);
2573  RzList *lost = rz_list_newf(free);
2574  rz_list_foreach (list, iter, imp) {
2575  char *impflag = rz_str_newf("sym.imp.%s", imp->name);
2576  ut64 addr = rz_num_math(core->num, impflag);
2577  ut64 *n = RZ_NEW(ut64);
2578  *n = addr;
2579  rz_list_append(lost, n);
2580  free(impflag);
2581  }
2582  ut64 *naddr;
2583  rz_list_foreach (lost, iter, naddr) {
2584  ut64 addr = *naddr;
2585  if (addr && addr != UT64_MAX) {
2586  rz_core_seek(core, addr, true);
2587  rz_core_cmd0(core, cmd);
2588  }
2589  }
2590  rz_core_seek(core, offorig, true);
2591  rz_list_free(lost);
2592  } break;
2593  case 'S': // "@@@S"
2594  {
2595  RzBinObject *obj = rz_bin_cur_object(core->bin);
2596  if (obj) {
2597  ut64 offorig = core->offset;
2598  ut64 bszorig = core->blocksize;
2599  RzBinSection *sec;
2600  RzListIter *iter;
2601  rz_list_foreach (obj->sections, iter, sec) {
2602  rz_core_seek(core, sec->vaddr, true);
2603  rz_core_block_size(core, sec->vsize);
2604  rz_core_cmd0(core, cmd);
2605  }
2606  rz_core_block_size(core, bszorig);
2607  rz_core_seek(core, offorig, true);
2608  }
2609  }
2610 #if ATTIC
2611  if (each[1] == 'S') {
2612  RzListIter *it;
2613  RzBinSection *sec;
2614  RzBinObject *obj = rz_bin_cur_object(core->bin);
2615  int cbsz = core->blocksize;
2616  rz_list_foreach (obj->sections, it, sec) {
2617  ut64 addr = sec->vaddr;
2618  ut64 size = sec->vsize;
2619  // TODO:
2620  // if (RZ_BIN_SCN_EXECUTABLE & sec->perm) {
2621  // continue;
2622  //}
2623  rz_core_seek_size(core, addr, size);
2624  rz_core_cmd(core, cmd, 0);
2625  }
2626  rz_core_block_size(core, cbsz);
2627  }
2628 #endif
2629  break;
2630  case 's':
2631  if (each[1] == 't') { // strings
2632  list = rz_bin_get_strings(core->bin);
2633  if (list) {
2634  ut64 offorig = core->offset;
2635  ut64 obs = core->blocksize;
2636  RzBinString *s;
2637  RzList *lost = rz_list_newf(free);
2638  rz_list_foreach (list, iter, s) {
2639  RzBinString *bs = rz_mem_dup(s, sizeof(RzBinString));
2640  rz_list_append(lost, bs);
2641  }
2642  rz_list_foreach (lost, iter, s) {
2643  rz_core_block_size(core, s->size);
2644  rz_core_seek(core, s->vaddr, true);
2645  rz_core_cmd0(core, cmd);
2646  }
2647  rz_core_block_size(core, obs);
2648  rz_core_seek(core, offorig, true);
2649  rz_list_free(lost);
2650  }
2651  } else {
2652  // symbols
2653  RzBinSymbol *sym;
2654  ut64 offorig = core->offset;
2655  ut64 obs = core->blocksize;
2656  list = rz_bin_get_symbols(core->bin);
2658  RzList *lost = rz_list_newf(free);
2659  rz_list_foreach (list, iter, sym) {
2660  RzBinSymbol *bs = rz_mem_dup(sym, sizeof(RzBinSymbol));
2661  rz_list_append(lost, bs);
2662  }
2663  rz_list_foreach (lost, iter, sym) {
2664  if (rz_cons_is_breaked()) {
2665  break;
2666  }
2667  rz_core_block_size(core, sym->size);
2668  rz_core_seek(core, sym->vaddr, true);
2669  rz_core_cmd0(core, cmd);
2670  }
2672  rz_list_free(lost);
2673  rz_core_block_size(core, obs);
2674  rz_core_seek(core, offorig, true);
2675  }
2676  break;
2677  case 'f': // flags
2678  {
2679  // TODO: honor ^C
2680  char *glob = filter ? rz_str_trim_dup(filter) : NULL;
2681  ut64 off = core->offset;
2682  ut64 obs = core->blocksize;
2685  RzListIter *iter;
2686  RzFlagItem *f;
2687  rz_list_foreach (flags, iter, f) {
2688  rz_core_block_size(core, f->size);
2689  rz_core_seek(core, f->offset, true);
2690  rz_core_cmd0(core, cmd);
2691  }
2692  rz_core_seek(core, off, false);
2693  rz_core_block_size(core, obs);
2694  free(glob);
2695  } break;
2696  case 'F': // functions
2697  {
2698  ut64 obs = core->blocksize;
2699  ut64 offorig = core->offset;
2700  RzAnalysisFunction *fcn;
2701  list = core->analysis->fcns;
2703  rz_list_foreach (list, iter, fcn) {
2704  if (rz_cons_is_breaked()) {
2705  break;
2706  }
2707  if (!filter || rz_str_glob(fcn->name, filter)) {
2708  rz_core_seek(core, fcn->addr, true);
2710  rz_core_cmd0(core, cmd);
2711  }
2712  }
2714  rz_core_block_size(core, obs);
2715  rz_core_seek(core, offorig, true);
2716  } break;
2717  case 'b': {
2718  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
2719  ut64 offorig = core->offset;
2720  ut64 obs = core->blocksize;
2721  if (fcn) {
2722  RzListIter *iter;
2723  RzAnalysisBlock *bb;
2724  rz_list_foreach (fcn->bbs, iter, bb) {
2725  rz_core_seek(core, bb->addr, true);
2726  rz_core_block_size(core, bb->size);
2727  rz_core_cmd0(core, cmd);
2728  }
2729  rz_core_block_size(core, obs);
2730  rz_core_seek(core, offorig, true);
2731  }
2732  } break;
2733  }
2734  return 0;
2735 }
2736 
2737 static void foreachOffset(RzCore *core, const char *_cmd, const char *each) {
2738  char *cmd = strdup(_cmd);
2739  char *nextLine = NULL;
2740  ut64 addr;
2741  /* foreach list of items */
2742  while (each) {
2743  // skip spaces
2744  while (*each == ' ') {
2745  each++;
2746  }
2747  // stahp if empty string
2748  if (!*each) {
2749  break;
2750  }
2751  // find newline
2752  char *nl = strchr(each, '\n');
2753  if (nl) {
2754  *nl = 0;
2755  nextLine = nl + 1;
2756  } else {
2757  nextLine = NULL;
2758  }
2759  // chop comment in line
2760  nl = strchr(each, '#');
2761  if (nl) {
2762  *nl = 0;
2763  }
2764  // space separated numbers
2765  while (each && *each) {
2766  // find spaces
2767  while (*each == ' ') {
2768  each++;
2769  }
2770  char *str = strchr(each, ' ');
2771  if (str) {
2772  *str = '\0';
2773  addr = rz_num_math(core->num, each);
2774  *str = ' ';
2775  each = str + 1;
2776  } else {
2777  if (!*each) {
2778  break;
2779  }
2780  addr = rz_num_math(core->num, each);
2781  each = NULL;
2782  }
2783  rz_core_seek(core, addr, true);
2784  rz_core_cmd(core, cmd, 0);
2785  rz_cons_flush();
2786  }
2787  each = nextLine;
2788  }
2789  free(cmd);
2790 }
2791 
2792 static int bb_cmp(const void *a, const void *b) {
2793  const RzAnalysisBlock *ba = a;
2794  const RzAnalysisBlock *bb = b;
2795  return ba->addr - bb->addr;
2796 }
2797 
2798 RZ_API int rz_core_cmd_foreach(RzCore *core, const char *cmd, char *each) {
2799  int i, j;
2800  char ch;
2801  char *word = NULL;
2802  char *str, *ostr = NULL;
2803  RzListIter *iter;
2804  RzFlagItem *flag;
2805  ut64 oseek, addr;
2806 
2807  for (; *cmd == ' '; cmd++) {
2808  ;
2809  }
2810 
2811  oseek = core->offset;
2812  ostr = str = strdup(each);
2813  rz_cons_break_push(NULL, NULL); // pop on return
2814  switch (each[0]) {
2815  case '/': // "@@/"
2816  {
2817  char *cmdhit = strdup(rz_config_get(core->config, "cmd.hit"));
2818  rz_config_set(core->config, "cmd.hit", cmd);
2819  rz_core_cmd0(core, each);
2820  rz_config_set(core->config, "cmd.hit", cmdhit);
2821  free(cmdhit);
2822  }
2823  free(ostr);
2824  return 0;
2825  case '?': // "@@?"
2827  break;
2828  case 'b': // "@@b" - function basic blocks
2829  {
2830  RzListIter *iter;
2831  RzAnalysisBlock *bb;
2833  int bs = core->blocksize;
2834  if (fcn) {
2835  rz_list_sort(fcn->bbs, bb_cmp);
2836  rz_list_foreach (fcn->bbs, iter, bb) {
2837  rz_core_block_size(core, bb->size);
2838  rz_core_seek(core, bb->addr, true);
2839  rz_core_cmd(core, cmd, 0);
2840  if (rz_cons_is_breaked()) {
2841  break;
2842  }
2843  }
2844  }
2845  rz_core_block_size(core, bs);
2846  goto out_finish;
2847  } break;
2848  case 's': // "@@s" - sequence
2849  {
2850  char *str = each + 1;
2851  if (*str == ':' || *str == ' ') {
2852  str++;
2853  }
2854  int count = rz_str_split(str, ' ');
2855  if (count == 3) {
2856  ut64 cur;
2857  ut64 from = rz_num_math(core->num, rz_str_word_get0(str, 0));
2858  ut64 to = rz_num_math(core->num, rz_str_word_get0(str, 1));
2859  ut64 step = rz_num_math(core->num, rz_str_word_get0(str, 2));
2860  for (cur = from; cur <= to; cur += step) {
2861  (void)rz_core_seek(core, cur, true);
2862  rz_core_cmd(core, cmd, 0);
2863  if (rz_cons_is_breaked()) {
2864  break;
2865  }
2866  }
2867  } else {
2868  eprintf("Usage: cmd @@s:from to step\n");
2869  }
2870  goto out_finish;
2871  } break;
2872  case 'i': // "@@i" - function instructions
2873  {
2874  RzListIter *iter;
2875  RzAnalysisBlock *bb;
2876  int i;
2878  if (fcn) {
2879  rz_list_sort(fcn->bbs, bb_cmp);
2880  rz_list_foreach (fcn->bbs, iter, bb) {
2881  for (i = 0; i < bb->op_pos_size; i++) {
2882  ut64 addr = bb->addr + bb->op_pos[i];
2883  rz_core_seek(core, addr, true);
2884  rz_core_cmd(core, cmd, 0);
2885  if (rz_cons_is_breaked()) {
2886  break;
2887  }
2888  }
2889  }
2890  }
2891  goto out_finish;
2892  } break;
2893  case 'f': // "@@f"
2894  if (each[1] == ':') {
2895  RzAnalysisFunction *fcn;
2896  RzListIter *iter;
2897  if (core->analysis) {
2898  rz_list_foreach (core->analysis->fcns, iter, fcn) {
2899  if (each[2] && strstr(fcn->name, each + 2)) {
2900  rz_core_seek(core, fcn->addr, true);
2901  rz_core_cmd(core, cmd, 0);
2902  if (rz_cons_is_breaked()) {
2903  break;
2904  }
2905  }
2906  }
2907  }
2908  goto out_finish;
2909  } else {
2910  RzAnalysisFunction *fcn;
2911  RzListIter *iter;
2912  if (core->analysis) {
2913  RzConsGrep grep = core->cons->context->grep;
2914  rz_list_foreach (core->analysis->fcns, iter, fcn) {
2915  char *buf;
2916  rz_core_seek(core, fcn->addr, true);
2917  rz_cons_push();
2918  rz_core_cmd(core, cmd, 0);
2920  rz_cons_pop();
2922  free(buf);
2923  if (rz_cons_is_breaked()) {
2924  break;
2925  }
2926  }
2927  core->cons->context->grep = grep;
2928  }
2929  goto out_finish;
2930  }
2931  break;
2932  case 't': // "@@t"
2933  {
2934  RzDebugPid *p;
2935  int pid = core->dbg->pid;
2936  if (core->dbg->cur && core->dbg->cur->pids) {
2937  RzList *list = core->dbg->cur->pids(core->dbg, RZ_MAX(0, pid));
2938  rz_list_foreach (list, iter, p) {
2939  rz_cons_printf("# PID %d\n", p->pid);
2940  rz_debug_select(core->dbg, p->pid, p->pid);
2941  rz_core_cmd(core, cmd, 0);
2942  rz_cons_newline();
2943  }
2944  rz_list_free(list);
2945  }
2946  rz_debug_select(core->dbg, pid, pid);
2947  goto out_finish;
2948  } break;
2949  case 'c': // "@@c:"
2950  if (each[1] == ':') {
2951  char *arg = rz_core_cmd_str(core, each + 2);
2952  if (arg) {
2953  foreachOffset(core, cmd, arg);
2954  free(arg);
2955  }
2956  }
2957  break;
2958  case '=': // "@@="
2959  foreachOffset(core, cmd, str + 1);
2960  break;
2961  case 'd': // "@@d"
2962  if (each[1] == 'b' && each[2] == 't') {
2963  ut64 oseek = core->offset;
2964  RzDebugFrame *frame;
2965  RzListIter *iter;
2966  RzList *list;
2967  list = rz_debug_frames(core->dbg, UT64_MAX);
2968  i = 0;
2969  rz_list_foreach (list, iter, frame) {
2970  switch (each[3]) {
2971  case 'b':
2972  rz_core_seek(core, frame->bp, true);
2973  break;
2974  case 's':
2975  rz_core_seek(core, frame->sp, true);
2976  break;
2977  default:
2978  case 'a':
2979  rz_core_seek(core, frame->addr, true);
2980  break;
2981  }
2982  rz_core_cmd(core, cmd, 0);
2983  rz_cons_newline();
2984  i++;
2985  }
2986  rz_core_seek(core, oseek, false);
2987  rz_list_free(list);
2988  } else {
2989  eprintf("Invalid for-each statement. Use @@=dbt[abs]\n");
2990  }
2991  break;
2992  case 'k': // "@@k"
2993  /* foreach list of items */
2994  {
2995  char *out = sdb_querys(core->sdb, NULL, 0, str + ((str[1]) ? 2 : 1));
2996  if (out) {
2997  each = out;
2998  do {
2999  while (*each == ' ') {
3000  each++;
3001  }
3002  if (!*each) {
3003  break;
3004  }
3005  str = strchr(each, ' ');
3006  if (str) {
3007  *str = '\0';
3008  addr = rz_num_math(core->num, each);
3009  *str = ' ';
3010  } else {
3011  addr = rz_num_math(core->num, each);
3012  }
3013  // eprintf ("; 0x%08"PFMT64x":\n", addr);
3014  each = str + 1;
3015  rz_core_seek(core, addr, true);
3016  rz_core_cmd(core, cmd, 0);
3017  rz_cons_flush();
3018  } while (str != NULL);
3019  free(out);
3020  }
3021  }
3022  break;
3023  case '.': // "@@."
3024  if (each[1] == '(') {
3025  char cmd2[1024];
3026  // XXX what's this 999 ?
3027  i = 0;
3028  for (core->rcmd->macro.counter = 0; i < 999; core->rcmd->macro.counter++) {
3029  if (rz_cons_is_breaked()) {
3030  break;
3031  }
3032  rz_cmd_macro_call(&core->rcmd->macro, each + 2);
3033  if (!core->rcmd->macro.brk_value) {
3034  break;
3035  }
3036  addr = core->rcmd->macro._brk_value;
3037  sprintf(cmd2, "%s @ 0x%08" PFMT64x "", cmd, addr);
3038  eprintf("0x%08" PFMT64x " (%s)\n", addr, cmd2);
3039  rz_core_seek(core, addr, true);
3040  rz_core_cmd(core, cmd2, 0);
3041  i++;
3042  }
3043  } else {
3044  char buf[1024];
3045  char cmd2[1024];
3046  FILE *fd = rz_sys_fopen(each + 1, "r");
3047  if (fd) {
3048  core->rcmd->macro.counter = 0;
3049  while (!feof(fd)) {
3050  buf[0] = '\0';
3051  if (!fgets(buf, sizeof(buf), fd)) {
3052  break;
3053  }
3054  addr = rz_num_math(core->num, buf);
3055  eprintf("0x%08" PFMT64x ": %s\n", addr, cmd);
3056  sprintf(cmd2, "%s @ 0x%08" PFMT64x "", cmd, addr);
3057  rz_core_seek(core, addr, true); // XXX
3058  rz_core_cmd(core, cmd2, 0);
3059  core->rcmd->macro.counter++;
3060  }
3061  fclose(fd);
3062  } else {
3063  eprintf("cannot open file '%s' to read offsets\n", each + 1);
3064  }
3065  }
3066  break;
3067  default:
3068  core->rcmd->macro.counter = 0;
3069  for (; *each == ' '; each++) {
3070  ;
3071  }
3072  i = 0;
3073  while (str[i]) {
3074  j = i;
3075  for (; str[j] && str[j] == ' '; j++) {
3076  ; // skip spaces
3077  }
3078  for (i = j; str[i] && str[i] != ' '; i++) {
3079  ; // find EOS
3080  }
3081  ch = str[i];
3082  str[i] = '\0';
3083  word = strdup(str + j);
3084  if (!word) {
3085  break;
3086  }
3087  str[i] = ch;
3088  {
3089  const RzSpace *flagspace = rz_flag_space_cur(core->flags);
3090  RzList *match_flag_items = rz_list_newf((RzListFree)rz_flag_item_free);
3091  if (!match_flag_items) {
3092  break;
3093  }
3094 
3095  /* duplicate flags that match word, to be sure
3096  the command is going to be executed on flags
3097  values at the moment the command is called
3098  (without side effects) */
3099  struct duplicate_flag_t u = {
3100  .ret = match_flag_items,
3101  .word = word,
3102  };
3103  rz_flag_foreach_space(core->flags, flagspace, duplicate_flag, &u);
3104 
3105  /* for all flags that match */
3106  rz_list_foreach (match_flag_items, iter, flag) {
3107  if (rz_cons_is_breaked()) {
3108  break;
3109  }
3110 
3111  char *buf = NULL;
3112  rz_core_seek(core, flag->offset, true);
3113  rz_cons_push();
3114  rz_core_cmd(core, cmd, 0);
3116  rz_cons_pop();
3118  free(buf);
3119  rz_core_task_yield(&core->tasks);
3120  }
3121 
3122  rz_list_free(match_flag_items);
3123  core->rcmd->macro.counter++;
3124  RZ_FREE(word);
3125  }
3126  }
3127  }
3129  // XXX: use rz_core_seek here
3130  core->offset = oseek;
3131 
3132  free(word);
3133  free(ostr);
3134  return true;
3135 out_finish:
3136  free(ostr);
3138  return false;
3139 }
3140 
3141 static int run_cmd_depth(RzCore *core, char *cmd);
3142 
3146  char *input;
3147  RzPVector /*<char *>*/ saved_input;
3149  RzPVector /*<TSTree *>*/ saved_tree;
3150  bool log;
3153 };
3154 
3156  char *new_text;
3157  char *old_text;
3162 };
3163 
3165 
3167  const char *name;
3168  void *data;
3169 };
3170 
3171 #define TS_START_END(node, start, end) \
3172  do { \
3173  start = ts_node_start_byte(node); \
3174  end = ts_node_end_byte(node); \
3175  } while (0)
3176 
3177 static char *ts_node_sub_string(TSNode node, const char *cstr) {
3178  ut32 start, end;
3179  TS_START_END(node, start, end);
3180  return rz_str_newf("%.*s", end - start, cstr + start);
3181 }
3182 
3183 static char *ts_node_sub_parent_string(TSNode parent, TSNode node, const char *cstr) {
3184  ut32 start, end;
3185  TS_START_END(node, start, end);
3186  ut32 parent_start = ts_node_start_byte(parent);
3187  start -= parent_start;
3188  end -= parent_start;
3189  return rz_str_newf("%.*s", end - start, cstr + start);
3190 }
3191 
3192 #define DEFINE_SYMBOL_TS_FCN(name) TSSymbol ts_##name##_symbol
3193 
3194 #define DEFINE_IS_TS_FCN(name) \
3195  static inline bool is_ts_##name(TSNode node) { \
3196  return ts_node_symbol(node) == ts_##name##_symbol; \
3197  }
3198 
3199 #define DEFINE_IS_TS_FCN_AND_SYMBOL(name) \
3200  DEFINE_SYMBOL_TS_FCN(name); \
3201  DEFINE_IS_TS_FCN(name)
3202 
3203 #define DEFINE_HANDLE_TS_FCN(name) \
3204  static RzCmdStatus handle_ts_##name##_internal(struct tsr2cmd_state *state, TSNode node, char *node_string); \
3205  static RzCmdStatus handle_ts_##name(struct tsr2cmd_state *state, TSNode node) { \
3206  char *node_string = ts_node_sub_string(node, state->input); \
3207  RZ_LOG_DEBUG(#name ": '%s'\n", node_string); \
3208  RzCmdStatus res = handle_ts_##name##_internal(state, node, node_string); \
3209  free(node_string); \
3210  return res; \
3211  } \
3212  static RzCmdStatus handle_ts_##name##_internal(struct tsr2cmd_state *state, TSNode node, char *node_string)
3213 
3214 #define DEFINE_HANDLE_TS_FCN_AND_SYMBOL(name) \
3215  DEFINE_SYMBOL_TS_FCN(name); \
3216  DEFINE_HANDLE_TS_FCN(name)
3217 
3218 #define UPDATE_CMD_STATUS_RES(res, cmd_res, label) \
3219  if ((cmd_res) != RZ_CMD_STATUS_OK) { \
3220  res = (cmd_res); \
3221  goto label; \
3222  }
3223 
3224 static RzCmdStatus handle_ts_stmt(struct tsr2cmd_state *state, TSNode node);
3226 static RzCmdStatus core_cmd_tsrzcmd(RzCore *core, const char *cstr, bool split_lines, bool log);
3227 
3228 static char *system_exec_stdin(bool is_pipe, int argc, char **argv, const ut8 *input, int input_len, int *length) {
3229  char *output = NULL;
3230  if (!rz_subprocess_init()) {
3231  RZ_LOG_ERROR("Cannot initialize subprocess.\n");
3232  return NULL;
3233  }
3234 
3235  RzSubprocessOpt opt = {
3236  .file = argv[0],
3237  .args = (const char **)&argv[1],
3238  .args_size = argc - 1,
3239  .envvars = NULL,
3240  .envvals = NULL,
3241  .env_size = 0,
3244  .stderr_pipe = is_pipe ? RZ_SUBPROCESS_PIPE_STDOUT : RZ_SUBPROCESS_PIPE_NONE,
3245  };
3246 
3248  if (!proc) {
3249  RZ_LOG_ERROR("Cannot start subprocess.\n");
3251  return NULL;
3252  }
3253 
3254  rz_subprocess_stdin_write(proc, input, input_len);
3256 
3257  output = (char *)rz_subprocess_out(proc, length);
3260 
3261  return output;
3262 }
3263 
3264 static ut8 *core_cmd_raw_node(RzCore *core, struct tsr2cmd_state *state, TSNode rizin_cmd, int *length) {
3265  const char *static_str;
3266  ut8 *retstr = NULL;
3267  rz_cons_push();
3268  if (handle_ts_stmt(state, rizin_cmd) != RZ_CMD_STATUS_OK) {
3269  rz_cons_pop();
3270  return NULL;
3271  }
3272  rz_cons_filter();
3273 
3274  static_str = rz_cons_get_buffer();
3275  int len = rz_cons_get_buffer_len();
3276  retstr = (ut8 *)rz_str_newlen(static_str, len);
3277  *length = len;
3278 
3279  rz_cons_pop();
3280  rz_cons_echo(NULL);
3281  return retstr;
3282 }
3283 
3292 static RzCmdStatus core_cmd_pipe(RzCore *core, struct tsr2cmd_state *state, TSNode rizin_cmd, int argc, char **argv) {
3293  int length = 0;
3294  bool is_pipe = core->is_pipe;
3295  core->is_pipe = true;
3296  ut8 *bytes = core_cmd_raw_node(core, state, rizin_cmd, &length);
3297  core->is_pipe = is_pipe;
3298  if (!bytes) {
3299  return RZ_CMD_STATUS_ERROR;
3300  }
3301 
3302  char *out = system_exec_stdin(core->is_pipe, argc, argv, bytes, length, &length);
3303  if (out) {
3305  }
3306 
3307  free(bytes);
3308  free(out);
3309  return RZ_CMD_STATUS_OK;
3310 }
3311 
3312 DEFINE_IS_TS_FCN_AND_SYMBOL(fdn_redirect_operator)
3313 DEFINE_IS_TS_FCN_AND_SYMBOL(fdn_append_operator)
3314 DEFINE_IS_TS_FCN_AND_SYMBOL(html_redirect_operator)
3315 DEFINE_IS_TS_FCN_AND_SYMBOL(html_append_operator)
3316 DEFINE_IS_TS_FCN_AND_SYMBOL(cmd_substitution_arg)
3319 DEFINE_IS_TS_FCN_AND_SYMBOL(arg_identifier)
3322 DEFINE_IS_TS_FCN_AND_SYMBOL(pf_dot_cmd_args)
3323 DEFINE_IS_TS_FCN_AND_SYMBOL(pf_new_args)
3324 DEFINE_IS_TS_FCN_AND_SYMBOL(pf_concatenation)
3325 DEFINE_IS_TS_FCN_AND_SYMBOL(double_quoted_arg)
3326 DEFINE_IS_TS_FCN_AND_SYMBOL(single_quoted_arg)
3327 DEFINE_IS_TS_FCN_AND_SYMBOL(concatenation)
3328 DEFINE_IS_TS_FCN_AND_SYMBOL(grep_specifier)
3329 DEFINE_IS_TS_FCN_AND_SYMBOL(statements)
3330 
3331 static struct tsr2cmd_edit *create_cmd_edit(struct tsr2cmd_state *state, TSNode arg, char *new_text) {
3332  struct tsr2cmd_edit *e = RZ_NEW0(struct tsr2cmd_edit);
3333  ut32 command_start = ts_node_start_byte(state->substitute_cmd);
3334  TSPoint command_point = ts_node_start_point(state->substitute_cmd);
3335  e->new_text = new_text;
3336  e->old_text = ts_node_sub_parent_string(state->substitute_cmd, arg, state->input);
3337  e->start = ts_node_start_byte(arg) - command_start;
3338  e->end = ts_node_end_byte(arg) - command_start;
3339  e->start_point = ts_node_start_point(arg);
3340  e->end_point = ts_node_end_point(arg);
3341  if (e->start_point.row == command_point.row) {
3342  e->start_point.column -= command_point.column;
3343  }
3344  if (e->end_point.row == command_point.row) {
3345  e->end_point.column -= command_point.column;
3346  }
3347  e->start_point.row -= command_point.row;
3348  e->end_point.row -= command_point.row;
3349  return e;
3350 }
3351 
3352 static void replace_whitespaces(char *s, char ch) {
3353  while (*s) {
3354  if (*s == '#') {
3355  while (*s && *s != '\r' && *s != '\n') {
3356  *s = ch;
3357  s++;
3358  }
3359  }
3360  if (isspace(*s)) {
3361  *s = ch;
3362  }
3363  s++;
3364  }
3365 }
3366 
3367 void free_tsr2cmd_edit(struct tsr2cmd_edit *edit) {
3368  free(edit->new_text);
3369  free(edit->old_text);
3370  free(edit);
3371 }
3372 
3373 static char *do_handle_substitution_cmd(struct tsr2cmd_state *state, TSNode inn_cmd) {
3374  RzCore *core = state->core;
3375  int value = core->num->value;
3376  char *inn_str = ts_node_sub_parent_string(state->substitute_cmd, inn_cmd, state->input);
3377 
3378  // save current color and disable it
3379  int ocolor = rz_config_get_i(core->config, "scr.color");
3380  rz_config_set_i(core->config, "scr.color", 0);
3381  core->cmd_in_backticks = true;
3382 
3383  // execute the sub command
3384  char *o_out = inn_str[0] == '!' ? rz_core_cmd_str_pipe(core, inn_str) : rz_core_cmd_str(core, inn_str);
3385 
3386  // restore color and cmd_in_backticks
3387  core->num->value = value;
3388  core->cmd_in_backticks = false;
3389  rz_config_set_i(core->config, "scr.color", ocolor);
3390  free(inn_str);
3391  if (!o_out) {
3392  return NULL;
3393  }
3394 
3395  // replace the output of the sub command with the current argument
3396  char *out = strdup(o_out);
3397  rz_str_trim(out);
3398  RZ_LOG_DEBUG("output of inner command: '%s'\n", out);
3399  free(o_out);
3400 
3401  // replace newlines and similar with spaces
3402  replace_whitespaces(out, ' ');
3403  return out;
3404 }
3405 
3407  TSNode inn_cmd = ts_node_child(arg, 1);
3409  char *out = do_handle_substitution_cmd(state, inn_cmd);
3410  if (!out) {
3411  return;
3412  }
3413 
3414  char *res = NULL;
3415  // escape special chars to prevent creation of new tokens when parsing again
3416  if (is_ts_double_quoted_arg(ts_node_parent(arg))) {
3418  } else if (is_ts_pf_arg(ts_node_parent(arg))) {
3420  } else {
3422  }
3423  free(out);
3424  struct tsr2cmd_edit *e = create_cmd_edit(state, arg, res);
3425  rz_list_append(edits, e);
3426 }
3427 
3429  return is_ts_args(args) || is_ts_concatenation(args) ||
3430  is_ts_double_quoted_arg(args) ||
3431  is_ts_pf_concatenation(args) || is_ts_pf_args(args) ||
3432  is_ts_pf_dot_cmd_args(args) || is_ts_pf_new_args(args) ||
3433  is_ts_grep_specifier(args);
3434 }
3435 
3436 static bool is_arg(TSNode args) {
3437  return is_ts_arg(args) || is_ts_pf_arg(args);
3438 }
3439 
3441  return is_group_of_args(args) || is_arg(args) ||
3442  is_ts_cmd_substitution_arg(args) || is_ts_grep_specifier(args);
3443 }
3444 
3446  if (is_group_of_args(args)) {
3447  uint32_t n_children = ts_node_named_child_count(args);
3448  uint32_t i;
3449  for (i = 0; i < n_children; i++) {
3452  }
3453  } else if (is_ts_cmd_substitution_arg(args)) {
3455  } else if (is_arg(args)) {
3458  }
3459 }
3460 
3461 static char *do_handle_ts_unescape_arg(struct tsr2cmd_state *state, TSNode arg, bool do_unwrap) {
3462  if (is_ts_arg(arg)) {
3463  return do_handle_ts_unescape_arg(state, ts_node_named_child(arg, 0), do_unwrap);
3464  } else if (is_ts_arg_identifier(arg)) {
3465  char *arg_str = ts_node_sub_string(arg, state->input);
3466  char *unescaped_arg = rz_cmd_unescape_arg(arg_str, RZ_CMD_ESCAPE_ONE_ARG);
3467  free(arg_str);
3468  return unescaped_arg;
3469  } else if (is_ts_single_quoted_arg(arg) || is_ts_double_quoted_arg(arg)) {
3470  char *o_arg_str = ts_node_sub_string(arg, state->input);
3471  char *arg_str = o_arg_str;
3472  if (do_unwrap) {
3473  // remove quotes
3474  arg_str[strlen(arg_str) - 1] = '\0';
3475  arg_str++;
3476  }
3477  char *res;
3478  if (is_ts_single_quoted_arg(arg)) {
3480  } else {
3482  }
3483  free(o_arg_str);
3484  return res;
3485  } else if (is_ts_concatenation(arg)) {
3486  uint32_t i, n_children = ts_node_named_child_count(arg);
3488  for (i = 0; i < n_children; i++) {
3489  TSNode sub_arg = ts_node_named_child(arg, i);
3490  char *s = do_handle_ts_unescape_arg(state, sub_arg, do_unwrap);
3491  rz_strbuf_append(sb, s);
3492  free(s);
3493  }
3494  return rz_strbuf_drain(sb);
3495  } else {
3496  return ts_node_sub_string(arg, state->input);
3497  }
3498 }
3499 
3500 static RzCmdParsedArgs *parse_args(struct tsr2cmd_state *state, TSNode args, bool do_unwrap) {
3501  if (ts_node_is_null(args)) {
3502  return rz_cmd_parsed_args_newargs(0, NULL);
3503  } else if (is_ts_args(args)) {
3504  uint32_t n_children = ts_node_named_child_count(args);
3505  uint32_t i;
3506  char **unescaped_args = RZ_NEWS0(char *, n_children);
3507  for (i = 0; i < n_children; i++) {
3509  unescaped_args[i] = do_handle_ts_unescape_arg(state, arg, do_unwrap);
3510  }
3511  RzCmdParsedArgs *res = rz_cmd_parsed_args_newargs(n_children, unescaped_args);
3512  for (i = 0; i < n_children; i++) {
3513  free(unescaped_args[i]);
3514  }
3515  free(unescaped_args);
3516  return res;
3517  } else {
3518  char *unescaped_args[] = { do_handle_ts_unescape_arg(state, args, do_unwrap) };
3519  RzCmdParsedArgs *res = rz_cmd_parsed_args_newargs(1, unescaped_args);
3520  free(unescaped_args[0]);
3521  return res;
3522  }
3523 }
3524 
3525 static TSTree *apply_edits(struct tsr2cmd_state *state, RzList *edits) {
3526  struct tsr2cmd_edit *edit;
3527  RzListIter *it;
3528 
3529  RZ_LOG_DEBUG("old input = '%s'\n", state->input);
3530  rz_list_foreach (edits, it, edit) {
3531  RZ_LOG_DEBUG("apply_edits: about to replace '%s' with '%s'\n", edit->old_text, edit->new_text);
3532  state->input = rz_str_replace(state->input, edit->old_text, edit->new_text, 0);
3533  }
3534  RZ_LOG_DEBUG("new input = '%s'\n", state->input);
3535  return ts_parser_parse_string(state->parser, NULL, state->input, strlen(state->input));
3536 }
3537 
3539  TSTree *saved_tree = rz_pvector_pop(&state->saved_tree);
3540  if (state->tree != saved_tree) {
3541  ts_tree_delete(state->tree);
3542  }
3543  state->tree = saved_tree;
3544 
3545  char *saved_input = rz_pvector_pop(&state->saved_input);
3546  if (state->input != saved_input) {
3547  free(state->input);
3548  }
3549  state->input = saved_input;
3550 }
3551 
3553  rz_pvector_push(&state->saved_input, state->input);
3554  rz_pvector_push(&state->saved_tree, state->tree);
3555 
3556  state->substitute_cmd = command;
3557  state->input = ts_node_sub_string(state->substitute_cmd, state->input);
3558  RZ_LOG_DEBUG("Shrinking input to '%s'\n", state->input);
3559 }
3560 
3561 static bool substitute_args_do(struct tsr2cmd_state *state, RzList *edits, TSNode *new_command) {
3562  TSTree *new_tree = apply_edits(state, edits);
3563  if (!new_tree) {
3564  return false;
3565  }
3566 
3567  TSNode root = ts_tree_root_node(new_tree);
3568  if (ts_node_has_error(root)) {
3569  ts_tree_delete(new_tree);
3570  return false;
3571  }
3572  *new_command = ts_node_named_child(root, 0);
3573  state->tree = new_tree;
3574  return true;
3575 }
3576 
3577 static bool substitute_args(struct tsr2cmd_state *state, TSNode args, TSNode *new_command) {
3579 
3580  if (is_handled_args(args)) {
3582  }
3583 
3584  bool res = substitute_args_do(state, edits, new_command);
3585  rz_list_free(edits);
3586  return res;
3587 }
3588 
3590  RzCmdParsedArgs *res = NULL;
3591  TSNode new_command;
3593  bool ok = substitute_args(state, arg, &new_command);
3594  if (!ok) {
3595  RZ_LOG_ERROR("Error while substituting arguments\n");
3596  goto err;
3597  }
3598 
3599  arg = ts_node_named_child(new_command, child_idx);
3600  res = parse_args(state, arg, do_unwrap);
3601  if (res == NULL) {
3602  RZ_LOG_ERROR("Cannot parse arg\n");
3603  goto err;
3604  }
3605 err:
3607  return res;
3608 }
3609 
3612  char *str = rz_cmd_parsed_args_argstr(a);
3614  return str;
3615 }
3616 
3617 static void get_help_wrong_cmd(RzCore *core, const char *cmdname) {
3618  char *cmdname_help = rz_str_newf("%s?", cmdname);
3619  if (!cmdname_help) {
3620  return;
3621  }
3622  RzCmdParsedArgs *help_pra = rz_cmd_parsed_args_newcmd(cmdname_help);
3623  if (!help_pra) {
3624  goto cmdname_err;
3625  }
3626  bool use_color = core->print->flags & RZ_PRINT_FLAGS_COLOR;
3627  char *help_msg = rz_cmd_get_help(core->rcmd, help_pra, use_color);
3628  if (!help_msg) {
3629  goto help_pra_err;
3630  }
3631  eprintf("%s", help_msg);
3632  free(help_msg);
3633 help_pra_err:
3634  rz_cmd_parsed_args_free(help_pra);
3635 cmdname_err:
3636  free(cmdname_help);
3637 }
3638 
3640  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
3642 
3643  TSNode command_extra = ts_node_child_by_field_name(command, "extra", strlen("extra"));
3644  char *command_str = NULL, *command_extra_str = NULL;
3645  if (!ts_node_is_null(command_extra)) {
3646  command_extra_str = ts_node_sub_string(command_extra, state->input);
3647  RZ_LOG_DEBUG("command_extra_str = '%s'\n", command_extra_str);
3648 
3650  ut32 end = ts_node_start_byte(command_extra);
3651  command_str = rz_str_newf("%.*s", end - start, state->input + start);
3652  } else {
3653  command_str = ts_node_sub_string(command, state->input);
3654  }
3655 
3656  rz_str_unescape(command_str);
3657  RZ_LOG_DEBUG("arged_stmt command: '%s'\n", command_str);
3658  TSNode args = ts_node_child_by_field_name(node, "args", strlen("args"));
3660 
3661  // FIXME: this special handling should be removed once we have a proper
3662  // command tree
3663  if (!strcmp(command_str, "|.")) {
3664  char *cmd_str = ts_node_sub_string(args, state->input);
3665  char *exec_string = rz_str_newf(".%s", cmd_str);
3666  free(cmd_str);
3667  free(command_str);
3668  res = core_cmd_tsrzcmd(state->core, exec_string, state->split_lines, false);
3669  free(exec_string);
3670  free(command_extra_str);
3671  return res;
3672  }
3673 
3674  RzCmdParsedArgs *pr_args = NULL;
3675  if (!ts_node_is_null(args)) {
3676  RzCmdDesc *cd = rz_cmd_get_desc(state->core->rcmd, command_str);
3677  bool do_unwrap = cd && cd->type != RZ_CMD_DESC_TYPE_OLDINPUT;
3678  pr_args = ts_node_handle_arg_prargs(state, node, args, 1, do_unwrap);
3679  if (!pr_args) {
3680  goto err;
3681  }
3682  rz_cmd_parsed_args_setcmd(pr_args, command_str);
3683  } else {
3684  pr_args = rz_cmd_parsed_args_newcmd(command_str);
3685  if (!pr_args) {
3686  goto err;
3687  }
3688  }
3689 
3690  pr_args->extra = command_extra_str;
3692  res = rz_cmd_call_parsed_args(state->core->rcmd, pr_args);
3693  if (res == RZ_CMD_STATUS_WRONG_ARGS) {
3694  const char *cmdname = rz_cmd_parsed_args_cmd(pr_args);
3695  eprintf("Wrong number of arguments passed to `%s`, see its help with `%s?`\n\n", cmdname, cmdname);
3696  get_help_wrong_cmd(state->core, cmdname);
3697  } else if (res == RZ_CMD_STATUS_NONEXISTINGCMD) {
3698  const char *cmdname = rz_cmd_parsed_args_cmd(pr_args);
3699  eprintf("Command '%s' does not exist.\n", cmdname);
3700  if (rz_str_endswith(cmdname, "?") && pr_args->argc > 1) {
3701  eprintf("Did you want to see the help? Try `%s` without any argument.\n", cmdname);
3702  } else {
3703  // Let's try to find the first command/group in the ancestor chain
3704  // that could provide some help
3705  RzCmdDesc *hcd = rz_cmd_get_desc_best(state->core->rcmd, cmdname);
3706  if (hcd) {
3707  eprintf("Displaying the help of command '%s'.\n\n", hcd->name);
3708  get_help_wrong_cmd(state->core, hcd->name);
3709  }
3710  }
3711  } else if (res == RZ_CMD_STATUS_ERROR) {
3712  RZ_LOG_DEBUG("Something wrong during the execution of `%s` command.\n", rz_cmd_parsed_args_cmd(pr_args));
3713  }
3714 
3715 err:
3716  RZ_LOG_DEBUG("arged_stmt finished command: '%s'\n", command_str);
3717  rz_cmd_parsed_args_free(pr_args);
3718  free(command_str);
3719  return res;
3720 }
3721 
3722 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(legacy_quoted_stmt) {
3723  return rz_cmd_int2status(run_cmd_depth(state->core, node_string));
3724 }
3725 
3727  TSNode number = ts_node_child_by_field_name(node, "arg", strlen("arg"));
3728  char *number_str = ts_node_sub_string(number, state->input);
3729  int rep = atoi(number_str);
3730  free(number_str);
3731 
3732  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
3734  if (!rz_cons_yesno('n', "Are you sure to repeat this %d times? (y/N)", rep)) {
3735  return RZ_CMD_STATUS_INVALID;
3736  }
3737  }
3738 
3740  size_t i;
3741  for (i = 0; i < rep; i++) {
3743  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
3744  }
3745 err:
3746  return res;
3747 }
3748 
3750  bool pipecolor = rz_config_get_b(state->core->config, "scr.color.pipe");
3751  int ocolor = rz_config_get_i(state->core->config, "scr.color");
3752  int scr_html = -1;
3753  RzCmdStatus res = RZ_CMD_STATUS_INVALID, is_append = false, is_html = false;
3754  int fdn = 1;
3755 
3756  TSNode redirect_op = ts_node_child_by_field_name(node, "redirect_operator", strlen("redirect_operator"));
3757  if (is_ts_fdn_redirect_operator(redirect_op)) {
3758  // this is the default operation, no html and no append
3759  } else if (is_ts_fdn_append_operator(redirect_op)) {
3760  is_append = true;
3761  } else if (is_ts_html_redirect_operator(redirect_op)) {
3762  is_html = true;
3763  } else if (is_ts_html_append_operator(redirect_op)) {
3764  is_html = true;
3765  is_append = true;
3766  } else {
3767  RZ_LOG_ERROR("This should never happen, redirect_operator is no known type");
3769  }
3770 
3771  if (is_html) {
3772  scr_html = rz_config_get_i(state->core->config, "scr.html");
3773  rz_config_set_i(state->core->config, "scr.html", true);
3774  pipecolor = true;
3775  } else {
3776  TSNode fd_desc = ts_node_named_child(redirect_op, 0);
3777  if (!ts_node_is_null(fd_desc)) {
3778  char *fd_str = ts_node_sub_string(fd_desc, state->input);
3779  fdn = atoi(fd_str);
3780  free(fd_str);
3781  }
3782  }
3783 
3784  rz_cons_set_interactive(false);
3785  // TODO: allow to use editor as the old behaviour
3786 
3787  // extract the string of the filename we need to write to
3788  TSNode arg = ts_node_child_by_field_name(node, "arg", strlen("arg"));
3789  char *arg_str = ts_node_handle_arg(state, node, arg, 2);
3790 
3791  if (arg_str[0] == '$') {
3792  // redirect output of command to an alias variable
3793  RZ_LOG_DEBUG("redirect_stmt: alias = '%s'\n", arg_str);
3794  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
3795  char *command_str = ts_node_sub_string(command, state->input);
3796 
3797  char *output = rz_core_cmd_str(state->core, command_str);
3798  char *old_alias_value = rz_cmd_alias_get(state->core->rcmd, arg_str, 1);
3799  char *new_alias_value;
3800  const char *start_char = "$";
3801  if (is_append && old_alias_value) {
3802  start_char = "";
3803  } else {
3804  old_alias_value = "";
3805  }
3806  new_alias_value = rz_str_newf("%s%s%s", start_char, old_alias_value, output ? output : "");
3807  free(output);
3808  rz_cmd_alias_set(state->core->rcmd, arg_str, new_alias_value, 1);
3809  free(new_alias_value);
3810  free(command_str);
3811  res = RZ_CMD_STATUS_OK;
3812  } else {
3813  rz_cons_flush();
3814  RZ_LOG_DEBUG("redirect_stmt: fdn = %d, is_append = %d\n", fdn, is_append);
3815  int pipefd = rz_cons_pipe_open(arg_str, fdn, is_append);
3816  if (pipefd != -1) {
3817  if (!pipecolor) {
3818  rz_config_set_i(state->core->config, "scr.color", COLOR_MODE_DISABLED);
3819  }
3820  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
3821  res = handle_ts_stmt(state, command);
3822  rz_cons_flush();
3823  rz_cons_pipe_close(pipefd);
3824  } else {
3825  RZ_LOG_WARN("Could not open pipe to %d", fdn);
3826  }
3827  }
3828  free(arg_str);
3830  if (!pipecolor) {
3831  rz_config_set_i(state->core->config, "scr.color", ocolor);
3832  }
3833  if (scr_html != -1) {
3834  rz_config_set_i(state->core->config, "scr.html", scr_html);
3835  }
3836  return res;
3837 }
3838 
3839 typedef struct _search_help {
3840  bool color;
3842  PJ *pj;
3844 
3845 static bool help_search_cmd_desc_entry(RzCmd *cmd, const RzCmdDesc *cd, void *user) {
3846  rz_return_val_if_fail(cd, false);
3847  RzHelpSearch *hs = (RzHelpSearch *)user;
3848  if (hs->pj) {
3849  rz_cmd_get_help_json(cmd, cd, hs->pj);
3850  } else {
3851  rz_cmd_get_help_strbuf(cmd, cd, hs->color, hs->sb);
3852  }
3853  return true;
3854 }
3855 
3858  RzCmdDesc *begin = NULL;
3859 
3860  if (argc == 2) {
3861  begin = rz_cmd_get_desc(core->rcmd, argv[1]);
3862  if (!begin) {
3863  RZ_LOG_ERROR("Command '%s' does not exist.\n", argv[1]);
3865  goto exit_status;
3866  }
3867  }
3868 
3869  RzHelpSearch hs = {
3870  .color = core->print->flags & RZ_PRINT_FLAGS_COLOR,
3871  .pj = NULL,
3872  .sb = NULL,
3873  };
3874 
3875  if (mode & RZ_OUTPUT_MODE_JSON) {
3876  hs.pj = pj_new();
3877  if (!hs.pj) {
3879  goto exit_status;
3880  }
3881  pj_o(hs.pj);
3882  } else {
3883  hs.sb = rz_strbuf_new(NULL);
3884  if (!hs.sb) {
3886  goto exit_status;
3887  }
3888  }
3889 
3891 
3892  if (mode & RZ_OUTPUT_MODE_JSON) {
3893  pj_end(hs.pj);
3894  rz_cons_printf("%s\n", pj_string(hs.pj));
3895  pj_free(hs.pj);
3896  } else {
3897  char *help = rz_strbuf_drain(hs.sb);
3898  rz_cons_printf("%s", help);
3899  free(help);
3900  }
3901 exit_status:
3902  return status;
3903 }
3904 
3906  size_t node_str_len = strlen(node_string);
3907  if (node_str_len >= 2 && !strcmp(node_string + node_str_len - 2, "?*")) {
3908  node_string[node_str_len - 2] = 0;
3909  const char *argv[2] = { NULL, node_string };
3911  } else if (node_str_len >= 3 && !strcmp(node_string + node_str_len - 3, "?*j")) {
3912  node_string[node_str_len - 3] = 0;
3913  const char *argv[2] = { NULL, node_string };
3915  }
3916 
3917  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
3918  char *command_str = ts_node_sub_string(command, state->input);
3919  TSNode args = ts_node_child_by_field_name(node, "args", strlen("args"));
3920  RzCmdParsedArgs *pr_args = NULL;
3922  if (!ts_node_is_null(args)) {
3923  RzCmdDesc *cd = rz_cmd_get_desc(state->core->rcmd, command_str);
3924  bool do_unwrap = cd && cd->type != RZ_CMD_DESC_TYPE_OLDINPUT;
3925  pr_args = ts_node_handle_arg_prargs(state, node, args, 1, do_unwrap);
3926  if (!pr_args) {
3927  goto err_else;
3928  }
3929  rz_cmd_parsed_args_setcmd(pr_args, command_str);
3930  } else {
3931  pr_args = rz_cmd_parsed_args_newcmd(command_str);
3932  if (!pr_args) {
3933  goto err_else;
3934  }
3935  }
3936 
3937  // let's try first with the new auto-generated help, if
3938  // something fails fallback to old behaviour
3939  bool use_color = state->core->print->flags & RZ_PRINT_FLAGS_COLOR;
3940  char *help_msg = rz_cmd_get_help(state->core->rcmd, pr_args, use_color);
3941  if (help_msg) {
3942  rz_cons_printf("%s", help_msg);
3943  free(help_msg);
3944  res = RZ_CMD_STATUS_OK;
3945  }
3946 err_else:
3947  rz_cmd_parsed_args_free(pr_args);
3948  free(command_str);
3949  return res;
3950 }
3951 
3953  TSNode command = ts_node_named_child(node, 0);
3954  TSNode offset = ts_node_named_child(node, 1);
3955  char *offset_string = ts_node_handle_arg(state, node, offset, 1);
3956  ut64 offset_val = rz_num_math(state->core->num, offset_string);
3957  ut64 orig_offset = state->core->offset;
3958  if (!offset_val && isalpha((int)offset_string[0])) {
3959  if (!rz_flag_get(state->core->flags, offset_string)) {
3960  eprintf("Invalid address (%s)\n", offset_string);
3961  free(offset_string);
3962  return RZ_CMD_STATUS_INVALID;
3963  }
3964  }
3965  if (offset_string[0] == '-' || offset_string[0] == '+') {
3966  offset_val += state->core->offset;
3967  }
3968  RZ_LOG_DEBUG("tmp_seek_stmt, changing offset to %" PFMT64x "\n", offset_val);
3969  rz_core_seek(state->core, offset_val, true);
3971  rz_core_seek(state->core, orig_offset, true);
3972  free(offset_string);
3973  return res;
3974 }
3975 
3977  TSNode command = ts_node_named_child(node, 0);
3978  TSNode blksz = ts_node_named_child(node, 1);
3979  char *blksz_string = ts_node_handle_arg(state, node, blksz, 1);
3980  ut64 orig_blksz = state->core->blocksize;
3981  RZ_LOG_DEBUG("tmp_blksz_stmt, changing blksz to %s\n", blksz_string);
3982  rz_core_block_size(state->core, rz_num_math(state->core->num, blksz_string));
3984  rz_core_block_size(state->core, orig_blksz);
3985  free(blksz_string);
3986  return res;
3987 }
3988 
3990  RzCore *core = state->core;
3991  TSNode command = ts_node_named_child(node, 0);
3992  TSNode fromto = ts_node_named_child(node, 1);
3993  RzCmdParsedArgs *a = ts_node_handle_arg_prargs(state, node, fromto, 1, true);
3994  if (!a || a->argc != 2 + 1) {
3996  return RZ_CMD_STATUS_INVALID;
3997  }
3998 
3999  char *from_str = a->argv[1];
4000  char *to_str = a->argv[2];
4001 
4002  const char *fromvars[] = { "analysis.from", "diff.from", "graph.from",
4003  "search.from", "zoom.from", NULL };
4004  const char *tovars[] = { "analysis.to", "diff.to", "graph.to",
4005  "search.to", "zoom.to", NULL };
4006  ut64 from_val = rz_num_math(core->num, from_str);
4007  ut64 to_val = rz_num_math(core->num, to_str);
4008  RZ_LOG_DEBUG("tmp_fromto_stmt, changing fromto to (%" PFMT64x ", %" PFMT64x ")\n", from_val, to_val);
4009 
4010  RzConfigHold *hc = rz_config_hold_new(core->config);
4011  int i;
4012  for (i = 0; fromvars[i]; i++) {
4013  rz_config_hold_i(hc, fromvars[i], NULL);
4014  rz_config_set_i(core->config, fromvars[i], from_val);
4015  }
4016  for (i = 0; tovars[i]; i++) {
4017  rz_config_hold_i(hc, tovars[i], NULL);
4018  rz_config_set_i(core->config, tovars[i], to_val);
4019  }
4020 
4022 
4024 
4025  rz_config_hold_free(hc);
4027  return res;
4028 }
4029 
4031  RzCore *core = state->core;
4032  TSNode command = ts_node_named_child(node, 0);
4033  TSNode arg = ts_node_named_child(node, 1);
4034  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4035  char *tmparch, *tmpbits;
4036  bool is_arch_set = false, is_bits_set = false;
4037  bool oldfixedarch = core->fixedarch, oldfixedbits = core->fixedbits;
4038  int cmd_ignbithints = -1;
4039 
4040  // change arch and bits
4041  char *q = strchr(arg_str, ':');
4042  if (q) {
4043  *q++ = '\0';
4044  int bits = rz_num_math(core->num, q);
4045  is_bits_set = set_tmp_bits(core, bits, &tmpbits, &cmd_ignbithints);
4046  }
4047  is_arch_set = set_tmp_arch(core, arg_str, &tmparch);
4048 
4049  // execute command with changed settings
4051 
4052  // restore original settings
4053  if (is_arch_set) {
4054  core->fixedarch = oldfixedarch;
4055  rz_config_set(core->config, "asm.arch", tmparch);
4056  free(tmparch);
4057  }
4058  if (is_bits_set) {
4059  rz_config_set(core->config, "asm.bits", tmpbits);
4060  core->fixedbits = oldfixedbits;
4061  free(tmpbits);
4062  }
4063  if (cmd_ignbithints != -1) {
4064  rz_config_set_i(core->config, "analysis.ignbithints", cmd_ignbithints);
4065  }
4066  free(arg_str);
4067  return res;
4068 }
4069 
4071  RzCore *core = state->core;
4072  TSNode command = ts_node_named_child(node, 0);
4073  TSNode arg = ts_node_named_child(node, 1);
4074  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4075  bool oldfixedbits = core->fixedbits;
4076  char *tmpbits;
4077  int cmd_ignbithints;
4078 
4079  int bits = rz_num_math(core->num, arg_str);
4080  set_tmp_bits(core, bits, &tmpbits, &cmd_ignbithints);
4081 
4083 
4084  rz_config_set(core->config, "asm.bits", tmpbits);
4085  core->fixedbits = oldfixedbits;
4086  rz_config_set_i(core->config, "analysis.ignbithints", cmd_ignbithints);
4087 
4088  free(tmpbits);
4089  free(arg_str);
4090  return res;
4091 }
4092 
4094  RzCore *core = state->core;
4095  TSNode command = ts_node_named_child(node, 0);
4096  TSNode arg = ts_node_named_child(node, 1);
4097  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4098 
4099  ut64 orig_offset = state->core->offset;
4100  int index = rz_num_math(core->num, arg_str);
4101  if (rz_core_seek_bb_instruction(core, index)) {
4102  core->tmpseek = true;
4103  }
4104 
4106 
4107  rz_core_seek(core, orig_offset, true);
4108 
4109  free(arg_str);
4110  return res;
4111 }
4112 
4114  // TODO: support cmd_substitution in tmp_eval_args
4115  RzCore *core = state->core;
4116  TSNode command = ts_node_named_child(node, 0);
4117  TSNode args = ts_node_named_child(node, 1);
4118 
4119  RzConfigHold *hc = rz_config_hold_new(core->config);
4121  for (i = 0; i < n_args; i++) {
4123  char *arg_str = ts_node_sub_string(arg, state->input);
4124  char *eq = strchr(arg_str, '=');
4125  if (eq) {
4126  *eq = 0;
4127  rz_config_hold_s(hc, arg_str, NULL);
4128  rz_config_set(core->config, arg_str, eq + 1);
4129  } else {
4130  eprintf("Missing '=' in e: expression (%s)\n", arg_str);
4131  }
4132  free(arg_str);
4133  }
4134 
4136 
4138  rz_config_hold_free(hc);
4139  return res;
4140 }
4141 
4143  RzCore *core = state->core;
4144  TSNode command = ts_node_named_child(node, 0);
4145  TSNode arg = ts_node_named_child(node, 1);
4146  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4147  rz_flag_space_push(core->flags, arg_str);
4149  rz_flag_space_pop(core->flags);
4150  free(arg_str);
4151  return res;
4152 }
4153 
4155  RzCore *core = state->core;
4156  TSNode command = ts_node_named_child(node, 0);
4157  TSNode arg = ts_node_named_child(node, 1);
4158  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4159  ut64 orig_offset = state->core->offset;
4160  ut64 addr = rz_num_math(core->num, arg_str);
4161  if (addr) {
4162  rz_core_seek_opcode(core, addr, false);
4163  }
4165  rz_core_seek(state->core, orig_offset, true);
4166  free(arg_str);
4167  return res;
4168 }
4169 
4171  RzCore *core = state->core;
4172  TSNode command = ts_node_named_child(node, 0);
4173  TSNode arg = ts_node_named_child(node, 1);
4174  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4175  ut64 orig_offset = state->core->offset;
4176  char *out = sdb_querys(core->sdb, NULL, 0, arg_str);
4177  if (out) {
4178  rz_core_seek(core, rz_num_math(core->num, out), true);
4179  free(out);
4180  }
4182  rz_core_seek(state->core, orig_offset, true);
4183  free(arg_str);
4184  return res;
4185 }
4186 
4188  RzCore *core = state->core;
4189  TSNode command = ts_node_named_child(node, 0);
4190  TSNode arg = ts_node_named_child(node, 1);
4191  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4192  int tmpfd = core->io->desc ? core->io->desc->fd : -1;
4193  rz_io_use_fd(core->io, atoi(arg_str));
4195  rz_io_use_fd(core->io, tmpfd);
4196  free(arg_str);
4197  return res;
4198 }
4199 
4201  RzCore *core = state->core;
4202  TSNode command = ts_node_named_child(node, 0);
4203  TSNode arg = ts_node_named_child(node, 1);
4204  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4205  ut64 orig_offset = state->core->offset;
4206  // TODO: add support for operations (e.g. @r:PC+10)
4207  ut64 regval = rz_debug_reg_get(core->dbg, arg_str);
4208  rz_core_seek(core, regval, true);
4210  rz_core_seek(core, orig_offset, true);
4211  free(arg_str);
4212  return res;
4213 }
4214 
4215 static bool handle_tmp_desc(struct tsr2cmd_state *state, TSNode command, const ut8 *buf, int sz) {
4216  RzCore *core = state->core;
4217  int pamode = !core->io->va;
4218  RzCmdStatus res = RZ_CMD_STATUS_INVALID, o_fixedblock = core->fixedblock;
4220  int cur_fd = rz_io_fd_get_current(core->io);
4221  RzIODesc *d = rz_io_open_buffer(core->io, b, RZ_PERM_RWX, 0);
4222  if (!d) {
4223  eprintf("Cannot open io buffer\n");
4224  goto out_buf;
4225  }
4226  if (pamode) {
4227  rz_config_set_i(core->config, "io.va", 1);
4228  }
4229  rz_io_map_new(core->io, d->fd, d->perm, 0, core->offset, rz_buf_size(b));
4230  ut32 obsz = core->blocksize;
4232  core->fixedblock = true;
4233  rz_core_block_read(core);
4234 
4235  res = handle_ts_stmt(state, command);
4236 
4237  core->fixedblock = o_fixedblock;
4238  if (pamode) {
4239  rz_config_set_i(core->config, "io.va", 0);
4240  }
4242  rz_core_block_size(core, obsz);
4243  rz_io_use_fd(core->io, cur_fd);
4244 
4245 out_buf:
4246  rz_buf_free(b);
4247  return res;
4248 }
4249 
4251  TSNode command = ts_node_named_child(node, 0);
4252  TSNode arg = ts_node_named_child(node, 1);
4253  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4254  size_t sz;
4256 
4257  char *f = rz_file_slurp(arg_str, &sz);
4258  if (!f) {
4259  eprintf("Cannot open '%s'\n", arg_str);
4260  goto out;
4261  }
4262 
4263  res = handle_tmp_desc(state, command, (ut8 *)f, (int)sz);
4264 
4265  free(f);
4266 out:
4267  free(arg_str);
4268  return res;
4269 }
4270 
4272  TSNode command = ts_node_named_child(node, 0);
4273  TSNode arg = ts_node_named_child(node, 1);
4274  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4275  int sz;
4276 
4277  sz = strlen(arg_str);
4278  const ut8 *buf = (const ut8 *)arg_str;
4279 
4281 
4282  free(arg_str);
4283  return res;
4284 }
4285 
4287  RzCore *core = state->core;
4288  TSNode command = ts_node_named_child(node, 0);
4289  TSNode arg = ts_node_named_child(node, 1);
4290  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4291 
4292  ut64 v = rz_num_math(core->num, arg_str);
4293  ut8 buf[8] = { 0 };
4294  int be = rz_config_get_i(core->config, "cfg.bigendian");
4295  int bi = rz_config_get_i(core->config, "asm.bits");
4296 
4297  rz_write_ble(buf, v, be, bi);
4298  int sz = bi / 8;
4299 
4301 
4302  free(arg_str);
4303  return res;
4304 }
4305 
4307  TSNode command = ts_node_named_child(node, 0);
4308  TSNode arg = ts_node_named_child(node, 1);
4309  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4310  int sz;
4311 
4312  size_t len = strlen(arg_str);
4313  ut8 *buf = RZ_NEWS(ut8, len + 1);
4314  sz = rz_hex_str2bin(arg_str, buf);
4315 
4317 
4318  free(buf);
4319  free(arg_str);
4320  return res;
4321 }
4322 
4324  RzCore *core = state->core;
4325  TSNode command = ts_node_named_child(node, 0);
4326  TSNode arg = ts_node_named_child(node, 1);
4327  char *arg_str = NULL;
4328  if (!ts_node_is_null(arg)) {
4329  arg_str = ts_node_handle_arg(state, node, arg, 1);
4330  }
4331  const RzSpace *flagspace = rz_flag_space_cur(core->flags);
4332  RzFlagItem *flag;
4333  RzListIter *iter;
4335  RzList *match_flag_items = rz_list_newf((RzListFree)rz_flag_item_free);
4336  if (!match_flag_items) {
4337  return RZ_CMD_STATUS_OK;
4338  }
4339 
4340  /* duplicate flags that match word, to be sure the command is going to
4341  be executed on flags values at the moment the command is called
4342  (without side effects) */
4343  struct duplicate_flag_t u = {
4344  .ret = match_flag_items,
4345  .word = arg_str,
4346  };
4347  rz_flag_foreach_space(core->flags, flagspace, duplicate_flag, &u);
4348 
4349  /* for all flags that match */
4350  rz_list_foreach (match_flag_items, iter, flag) {
4351  if (rz_cons_is_breaked()) {
4352  break;
4353  }
4354 
4355  RZ_LOG_DEBUG("iter_flags_stmt: seek to %" PFMT64x "\n", flag->offset);
4356  rz_core_seek(core, flag->offset, true);
4358  rz_core_task_yield(&core->tasks);
4359  UPDATE_CMD_STATUS_RES(ret, cmd_res, err);
4360  }
4361 
4362 err:
4363  rz_list_free(match_flag_items);
4364  free(arg_str);
4365  return ret;
4366 }
4367 
4372 };
4373 
4375  RzCore *core = state->core;
4376  TSNode command = ts_node_named_child(node, 0);
4377  RzList *list = rz_debug_frames(core->dbg, UT64_MAX);
4378  ut64 orig_offset = core->offset;
4379  RzDebugFrame *frame;
4380  RzListIter *iter;
4382 
4383  rz_list_foreach (list, iter, frame) {
4384  switch (mode) {
4386  rz_core_seek(core, frame->addr, true);
4387  break;
4388  case DBT_COMMANDS_MODE_SP:
4389  rz_core_seek(core, frame->sp, true);
4390  break;
4391  case DBT_COMMANDS_MODE_BP:
4392  rz_core_seek(core, frame->bp, true);
4393  break;
4394  default:
4396  return RZ_CMD_STATUS_INVALID;
4397  }
4399  rz_cons_newline();
4400  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4401  }
4402 err:
4403  rz_core_seek(core, orig_offset, true);
4404  rz_list_free(list);
4405  return res;
4406 }
4407 
4410 }
4411 
4414 }
4415 
4418 }
4419 
4420 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_file_lines_stmt) {
4421  RzCore *core = state->core;
4423  TSNode command = ts_node_named_child(node, 0);
4424  TSNode arg = ts_node_named_child(node, 1);
4425  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
4426  ut64 orig_offset = core->offset;
4427  FILE *fd = rz_sys_fopen(arg_str, "r");
4428  if (!fd) {
4429  res = RZ_CMD_STATUS_INVALID;
4430  goto arg_out;
4431  }
4432 
4433  core->rcmd->macro.counter = 0;
4434  while (!feof(fd)) {
4435  char buf[1024];
4436  buf[0] = '\0';
4437  if (!fgets(buf, sizeof(buf), fd)) {
4438  break;
4439  }
4440  ut64 addr = rz_num_math(core->num, buf);
4441  rz_core_seek(core, addr, true);
4443  core->rcmd->macro.counter++;
4444  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4445  }
4446 err:
4447  rz_core_seek(core, orig_offset, true);
4448  fclose(fd);
4449 
4450 arg_out:
4451  free(arg_str);
4452  return res;
4453 }
4454 
4457 
4458  const char *s;
4459  int i;
4460  ut64 orig_offset = core->offset;
4461  ut64 orig_blk_sz = core->blocksize;
4462  rz_cmd_parsed_args_foreach_arg(a, i, s) {
4463  ut64 addr = rz_num_math(core->num, s);
4464  ut64 blk_sz = core->blocksize;
4465  if (has_size) {
4466  blk_sz = rz_num_math(core->num, a->argv[i++ + 1]);
4467  }
4468  rz_core_seek(core, addr, true);
4469  if (has_size) {
4470  rz_core_block_size(core, blk_sz);
4471  }
4473  rz_cons_flush();
4474  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4475  }
4476 
4477 err:
4478  if (has_size) {
4479  rz_core_block_size(core, orig_blk_sz);
4480  }
4481  rz_core_seek(core, orig_offset, true);
4482  return res;
4483 }
4484 
4485 static RzCmdStatus iter_offsets_common(struct tsr2cmd_state *state, TSNode node, bool has_size) {
4486  RzCore *core = state->core;
4487  TSNode command = ts_node_named_child(node, 0);
4488  if (ts_node_named_child_count(node) < 2) {
4489  // no offsets provided, all's good.
4490  return RZ_CMD_STATUS_OK;
4491  }
4492 
4493  TSNode args = ts_node_named_child(node, 1);
4494 
4496  if (!a || (has_size && (a->argc - 1) % 2 != 0)) {
4497  RZ_LOG_ERROR("Cannot parse args\n");
4499  return RZ_CMD_STATUS_INVALID;
4500  }
4501 
4502  RzCmdStatus res = do_iter_offsets(core, state, &command, a, has_size);
4504  return res;
4505 }
4506 
4508  return iter_offsets_common(state, node, false);
4509 }
4510 
4511 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_offsetssizes_stmt) {
4512  return iter_offsets_common(state, node, true);
4513 }
4514 
4516  TSNode command = ts_node_named_child(node, 0);
4517  RzCore *core = state->core;
4519  ut64 orig_offset = core->offset;
4520  int bs = core->blocksize;
4521  RzList *bbl = rz_analysis_get_blocks_in(core->analysis, core->offset);
4522  if (!bbl || rz_list_empty(bbl)) {
4523  eprintf("No basic block contains current address\n");
4524  return RZ_CMD_STATUS_INVALID;
4525  }
4526  RzAnalysisBlock *bb = rz_list_get_top(bbl);
4528  rz_list_free(bbl);
4529 
4530  int i;
4531  for (i = 0; i < bb->ninstr; i++) {
4532  ut64 i_addr = rz_analysis_block_get_op_addr(bb, i);
4533  int sz = rz_analysis_block_get_op_size(bb, i);
4534  rz_core_block_size(core, sz);
4535  rz_core_seek(core, i_addr, true);
4537  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4538  if (rz_cons_is_breaked()) {
4539  break;
4540  }
4541  }
4543 
4544 err:
4545  rz_core_block_size(core, bs);
4546  rz_core_seek(core, orig_offset, true);
4547  return res;
4548 }
4549 
4551  TSNode command = ts_node_named_child(node, 0);
4552  TSNode args = ts_node_named_child(node, 1);
4554  if (!a || a->argc != 3 + 1) {
4556  return RZ_CMD_STATUS_INVALID;
4557  }
4558 
4559  RzCore *core = state->core;
4561  ut64 orig_offset = core->offset;
4562  int bs = core->blocksize;
4563 
4564  char *from_str = a->argv[1];
4565  char *to_str = a->argv[2];
4566  char *step_str = a->argv[3];
4567  ut64 from = rz_num_math(core->num, from_str);
4568  ut64 to = rz_num_math(core->num, to_str);
4569  ut64 step = rz_num_math(core->num, step_str);
4570 
4571  ut64 cur;
4572  for (cur = from; cur < to; cur += step) {
4573  rz_core_seek(core, cur, true);
4574  rz_core_block_size(core, step);
4576  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4577  if (rz_cons_is_breaked()) {
4578  break;
4579  }
4580  }
4581 
4582 err:
4583  rz_core_block_size(core, bs);
4584  rz_core_seek(core, orig_offset, true);
4586  return res;
4587 }
4588 
4590  RzCore *core = state->core;
4591  TSNode command = ts_node_named_child(node, 0);
4592  TSNode search_cmd = ts_node_named_child(node, 1);
4593  char *command_str = ts_node_sub_string(command, state->input);
4594  char *cmdhit = strdup(rz_config_get(core->config, "cmd.hit"));
4595  rz_config_set(core->config, "cmd.hit", command_str);
4596  RzCmdStatus res = handle_ts_stmt(state, search_cmd);
4597  rz_config_set(core->config, "cmd.hit", cmdhit);
4598  free(command_str);
4599  return res;
4600 }
4601 
4603  RzCore *core = state->core;
4604  TSNode command = ts_node_named_child(node, 0);
4605  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
4606  ut64 offorig = core->offset;
4607  ut64 obs = core->blocksize;
4608  if (!fcn) {
4609  return RZ_CMD_STATUS_INVALID;
4610  }
4611 
4612  RzListIter *iter;
4613  RzAnalysisBlock *bb;
4615  rz_list_sort(fcn->bbs, bb_cmp);
4616  rz_list_foreach (fcn->bbs, iter, bb) {
4617  rz_core_seek(core, bb->addr, true);
4618  rz_core_block_size(core, bb->size);
4620  UPDATE_CMD_STATUS_RES(ret, cmd_res, err);
4621  }
4622 err:
4623  rz_core_block_size(core, obs);
4624  rz_core_seek(core, offorig, true);
4625  return ret;
4626 }
4627 
4628 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_interpret_stmt) {
4629  // convert @@c: command into a @@= one, by using the output of the
4630  // in_cmd as addr of @@=
4632  TSNode in_cmd = ts_node_named_child(node, 1);
4633  substitute_args_init(state, node);
4634 
4636  if (!edits) {
4637  goto edits_err;
4638  }
4639 
4640  char *in_cmd_out = do_handle_substitution_cmd(state, in_cmd);
4641  if (!in_cmd_out) {
4642  goto err;
4643  }
4644 
4645  char *in_cmd_out_es = rz_cmd_escape_arg(in_cmd_out, RZ_CMD_ESCAPE_MULTI_ARG);
4646  free(in_cmd_out);
4647  struct tsr2cmd_edit *e = create_cmd_edit(state, in_cmd, in_cmd_out_es);
4648  rz_list_append(edits, e);
4649 
4650  TSNode op = ts_node_child(node, 1);
4651  e = create_cmd_edit(state, op, strdup("@@="));
4652  rz_list_append(edits, e);
4653 
4654  TSNode new_command;
4655  if (!substitute_args_do(state, edits, &new_command)) {
4656  goto err;
4657  }
4658  res = handle_ts_stmt(state, new_command);
4659 err:
4660  rz_list_free(edits);
4661 edits_err:
4663  return res;
4664 }
4665 
4666 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_interpret_offsetssizes_stmt) {
4667  // convert @@@c: command into a @@@= one, by using the output of the
4668  // in_cmd as addr/blksz of @@@=
4670  TSNode in_cmd = ts_node_named_child(node, 1);
4671  substitute_args_init(state, node);
4672 
4674  if (!edits) {
4675  goto edits_err;
4676  }
4677 
4678  char *in_cmd_out = do_handle_substitution_cmd(state, in_cmd);
4679  if (!in_cmd_out) {
4680  goto err;
4681  }
4682 
4683  char *in_cmd_out_es = rz_cmd_escape_arg(in_cmd_out, RZ_CMD_ESCAPE_MULTI_ARG);
4684  free(in_cmd_out);
4685  struct tsr2cmd_edit *e = create_cmd_edit(state, in_cmd, in_cmd_out_es);
4686  rz_list_append(edits, e);
4687 
4688  TSNode op = ts_node_child(node, 1);
4689  e = create_cmd_edit(state, op, strdup("@@@="));
4690  rz_list_append(edits, e);
4691 
4692  TSNode new_command;
4693  if (!substitute_args_do(state, edits, &new_command)) {
4694  goto err;
4695  }
4696  res = handle_ts_stmt(state, new_command);
4697 err:
4698  rz_list_free(edits);
4699 edits_err:
4701  return res;
4702 }
4703 
4705  RzCore *core = state->core;
4706  TSNode command = ts_node_named_child(node, 0);
4707  TSNode filter_node = ts_node_named_child(node, 1);
4708  char *glob = !ts_node_is_null(filter_node)
4709  ? ts_node_sub_string(filter_node, state->input)
4710  : NULL;
4711  ut64 off = core->offset;
4713  RzIntervalTreeIter it;
4714  RzAnalysisMetaItem *meta;
4715  rz_interval_tree_foreach (&core->analysis->meta, it, meta) {
4716  if (meta->type != RZ_META_TYPE_COMMENT) {
4717  continue;
4718  }
4719  if (!glob || (meta->str && rz_str_glob(meta->str, glob))) {
4720  rz_core_seek(core, rz_interval_tree_iter_get(&it)->start, true);
4722  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4723  }
4724  }
4725 err:
4726  rz_core_seek(core, off, false);
4727  free(glob);
4728  return res;
4729 }
4730 
4732  RzCore *core = state->core;
4733  TSNode command = ts_node_named_child(node, 0);
4734  RzBinSymbol *imp;
4735  ut64 offorig = core->offset;
4736  RzList *list = rz_bin_get_symbols(core->bin);
4737  if (!list) {
4738  return RZ_CMD_STATUS_OK;
4739  }
4740 
4741  RzList *lost = rz_list_newf(free);
4742  RzListIter *iter;
4743  rz_list_foreach (list, iter, imp) {
4744  if (!imp->is_imported) {
4745  continue;
4746  }
4747  ut64 *n = RZ_NEW(ut64);
4748  *n = imp->vaddr;
4749  rz_list_append(lost, n);
4750  }
4751  ut64 *naddr;
4753  rz_list_foreach (lost, iter, naddr) {
4754  ut64 addr = *naddr;
4755  if (addr != UT64_MAX) {
4756  rz_core_seek(core, addr, true);
4758  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4759  }
4760  }
4761 err:
4762  rz_core_seek(core, offorig, true);
4763  rz_list_free(lost);
4764  return res;
4765 }
4766 
4767 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_register_stmt) {
4768  RzCore *core = state->core;
4769  TSNode command = ts_node_named_child(node, 0);
4770  ut64 offorig = core->offset;
4771  RzReg *reg = rz_core_reg_default(core);
4772  int i;
4774  for (i = 0; i < RZ_REG_TYPE_LAST; i++) {
4775  RzRegItem *item;
4776  ut64 value;
4777  const RzList *head = rz_reg_get_list(reg, i);
4778  if (!head) {
4779  continue;
4780  }
4782  RzListIter *iter;
4783  rz_list_foreach (head, iter, item) {
4784  if (item->size != core->analysis->bits) {
4785  continue;
4786  }
4787  if (item->type != i) {
4788  continue;
4789  }
4790  rz_list_append(list, strdup(item->name));
4791  }
4792  const char *item_name;
4793  rz_list_foreach (list, iter, item_name) {
4794  value = rz_reg_getv(reg, item_name);
4795  rz_core_seek(core, value, true);
4796  rz_cons_printf("%s: ", item_name);
4798  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4799  }
4800  err:
4801  rz_list_free(list);
4802  }
4803  rz_core_seek(core, offorig, true);
4804  return res;
4805 }
4806 
4808  RzCore *core = state->core;
4809  TSNode command = ts_node_named_child(node, 0);
4810  RzBinSymbol *sym;
4811  ut64 offorig = core->offset;
4812  ut64 obs = core->blocksize;
4813  RzList *list = rz_bin_get_symbols(core->bin);
4814  RzListIter *iter;
4816  RzList *lost = rz_list_newf(free);
4817  rz_list_foreach (list, iter, sym) {
4818  RzBinSymbol *bs = rz_mem_dup(sym, sizeof(RzBinSymbol));
4819  rz_list_append(lost, bs);
4820  }
4822  rz_list_foreach (lost, iter, sym) {
4823  if (rz_cons_is_breaked()) {
4824  break;
4825  }
4826  rz_core_block_size(core, sym->size);
4827  rz_core_seek(core, sym->vaddr, true);
4829  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4830  }
4831 err:
4833  rz_list_free(lost);
4834  rz_core_block_size(core, obs);
4835  rz_core_seek(core, offorig, true);
4836  return res;
4837 }
4838 
4840  RzCore *core = state->core;
4841  TSNode command = ts_node_named_child(node, 0);
4842  RzList *list = rz_bin_get_strings(core->bin);
4844  if (list) {
4845  ut64 offorig = core->offset;
4846  ut64 obs = core->blocksize;
4847  RzBinString *s;
4848  RzList *lost = rz_list_newf(free);
4849  RzListIter *iter;
4850  rz_list_foreach (list, iter, s) {
4851  RzBinString *bs = rz_mem_dup(s, sizeof(RzBinString));
4852  rz_list_append(lost, bs);
4853  }
4854  rz_list_foreach (lost, iter, s) {
4855  rz_core_block_size(core, s->size);
4856  rz_core_seek(core, s->vaddr, true);
4858  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4859  }
4860  err:
4861  rz_core_block_size(core, obs);
4862  rz_core_seek(core, offorig, true);
4863  rz_list_free(lost);
4864  }
4865  return res;
4866 }
4867 
4868 static RzCmdStatus do_iter_sections(struct tsr2cmd_state *state, TSNode node, bool show_sections) {
4869  RzCore *core = state->core;
4870  TSNode command = ts_node_named_child(node, 0);
4871  RzBinObject *obj = rz_bin_cur_object(core->bin);
4872  if (!obj) {
4873  return false;
4874  }
4876  ut64 offorig = core->offset;
4877  ut64 bszorig = core->blocksize;
4878  RzBinSection *sec;
4879  RzListIter *iter;
4880  rz_list_foreach (obj->sections, iter, sec) {
4881  if ((sec->is_segment && show_sections) || (!sec->is_segment && !show_sections)) {
4882  continue;
4883  }
4884  if (sec->vaddr == UT64_MAX) {
4885  continue;
4886  }
4887  rz_core_seek(core, sec->vaddr, true);
4888  rz_core_block_size(core, sec->vsize);
4890  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4891  }
4892 err:
4893  rz_core_block_size(core, bszorig);
4894  rz_core_seek(core, offorig, true);
4895  return res;
4896 }
4897 
4898 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_sections_stmt) {
4899  return do_iter_sections(state, node, true);
4900 }
4901 
4902 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_segments_stmt) {
4903  return do_iter_sections(state, node, false);
4904 }
4905 
4907  RzCore *core = state->core;
4908  TSNode command = ts_node_named_child(node, 0);
4909  int fd = rz_io_fd_get_current(core->io);
4910  // only iterate maps of current fd
4911  RzList *maps = rz_io_map_get_for_fd(core->io, fd);
4912  RzIOMap *map;
4914  if (maps) {
4915  RzListIter *iter;
4916  rz_list_foreach (maps, iter, map) {
4917  rz_core_seek(core, map->itv.addr, true);
4918  rz_core_block_size(core, map->itv.size);
4920  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4921  }
4922  err:
4923  rz_list_free(maps);
4924  }
4925  return res;
4926 }
4927 
4929  RzCore *core = state->core;
4930  TSNode command = ts_node_named_child(node, 0);
4931  RzDebug *dbg = core->dbg;
4933  if (dbg && dbg->cur && dbg->maps) {
4934  RzList *dbg_maps_addrs = rz_list_newf((RzListFree)free);
4935  if (!dbg_maps_addrs) {
4936  return RZ_CMD_STATUS_INVALID;
4937  }
4938 
4939  RzDebugMap *map;
4940  RzListIter *iter;
4941  rz_list_foreach (dbg->maps, iter, map) {
4942  int *val = RZ_NEW(int);
4943  *val = map->addr;
4944  rz_list_append(dbg_maps_addrs, val);
4945  }
4946 
4947  int *map_addr;
4948  rz_list_foreach (dbg_maps_addrs, iter, map_addr) {
4949  rz_core_seek(core, *map_addr, true);
4951  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4952  }
4953  err:
4954  rz_list_free(dbg_maps_addrs);
4955  }
4956  return res;
4957 }
4958 
4959 DEFINE_HANDLE_TS_FCN_AND_SYMBOL(iter_function_stmt) {
4960  RzCore *core = state->core;
4961  TSNode command = ts_node_named_child(node, 0);
4962  TSNode filter_node = ts_node_named_child(node, 1);
4963  char *filter = NULL;
4964  if (!ts_node_is_null(filter_node)) {
4965  filter = ts_node_sub_string(filter_node, state->input);
4966  }
4967  ut64 obs = core->blocksize;
4968  ut64 offorig = core->offset;
4969  RzAnalysisFunction *fcn;
4970  RzList *list = core->analysis->fcns;
4971  RzListIter *iter;
4974  rz_list_foreach (list, iter, fcn) {
4975  if (rz_cons_is_breaked()) {
4976  break;
4977  }
4978  if (!filter || rz_str_glob(fcn->name, filter)) {
4979  rz_core_seek(core, fcn->addr, true);
4982  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
4983  }
4984  }
4985 err:
4987  rz_core_block_size(core, obs);
4988  rz_core_seek(core, offorig, true);
4989  free(filter);
4990  return res;
4991 }
4992 
4994  RzCore *core = state->core;
4995  TSNode command = ts_node_named_child(node, 0);
4996  RzDebug *dbg = core->dbg;
4998  if (dbg && dbg->cur && dbg->cur->threads) {
4999  int origtid = dbg->tid;
5000  RzDebugPid *p;
5001  RzList *list = dbg->cur->threads(dbg, dbg->pid);
5002  if (!list) {
5003  return RZ_CMD_STATUS_INVALID;
5004  }
5005  RzListIter *iter;
5006  rz_list_foreach (list, iter, p) {
5007  rz_debug_select(dbg, dbg->pid, p->pid);
5008  rz_cons_printf("PID %d\n", p->pid);
5010  UPDATE_CMD_STATUS_RES(res, cmd_res, err);
5011  }
5012  err:
5013  rz_debug_select(dbg, dbg->pid, origtid);
5014  rz_list_free(list);
5015  }
5016  return res;
5017 }
5018 
5020  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
5021  TSNode arg = ts_node_child_by_field_name(node, "specifier", strlen("specifier"));
5022  char *arg_str = ts_node_handle_arg(state, node, arg, 1);
5023  bool is_pipe = state->core->is_pipe;
5024  state->core->is_pipe = true;
5026  state->core->is_pipe = is_pipe;
5027  RZ_LOG_DEBUG("grep_stmt specifier: '%s'\n", arg_str);
5028  RzStrBuf *sb = rz_strbuf_new(arg_str);
5029  rz_strbuf_prepend(sb, "~");
5030  char *specifier_str_es = rz_cons_grep_strip(rz_strbuf_get(sb), "`");
5031  rz_strbuf_free(sb);
5032  char *specifier_str = rz_cmd_unescape_arg(specifier_str_es, true);
5033  RZ_LOG_DEBUG("grep_stmt processed specifier: '%s'\n", specifier_str);
5034  rz_cons_grep_process(specifier_str);
5035  free(specifier_str_es);
5036  free(arg_str);
5037  return res;
5038 }
5039 
5041  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
5042  int scr_html = rz_config_get_i(state->core->config, "scr.html");
5043  rz_config_set_i(state->core->config, "scr.html", 0);
5044  int scr_color = rz_config_get_i(state->core->config, "scr.color");
5045  rz_config_set_i(state->core->config, "scr.color", COLOR_MODE_DISABLED);
5047  if (scr_html != -1) {
5048  rz_cons_flush();
5049  rz_config_set_i(state->core->config, "scr.html", scr_html);
5050  }
5051  if (scr_color != -1) {
5052  rz_config_set_i(state->core->config, "scr.color", scr_color);
5053  }
5054  return res;
5055 }
5056 
5058  TSNode command = ts_node_child_by_field_name(node, "command", strlen("command"));
5059  int scr_html = rz_config_get_i(state->core->config, "scr.html");
5060  rz_config_set_i(state->core->config, "scr.html", true);
5062  if (scr_html != -1) {
5063  rz_cons_flush();
5064  rz_config_set_i(state->core->config, "scr.html", scr_html);
5065  }
5066  return res;
5067 }
5068 
5070  TSNode command_rizin = ts_node_named_child(node, 0);
5071  TSNode command_pipe = ts_node_named_child(node, 1);
5072 
5074  RzCmdParsedArgs *a = ts_node_handle_arg_prargs(state, node, command_pipe, 1, true);
5075  if (a && a->argc > 1) {
5076  res = core_cmd_pipe(state->core, state, command_rizin, a->argc - 1, a->argv + 1);
5077  }
5078 
5080  return res;
5081 }
5082 
5085  RzCore *core = state->core;
5086  RzCmd *cmd = core->rcmd;
5087 
5088  // NOTE: code copied from rz_core_cmd, needs rewrite when all the "remote"
5089  // concept is re-considered.
5090  if (core->cmdremote) {
5091  if (*state->input == 'q') {
5092  RZ_FREE(core->cmdremote);
5093  return RZ_CMD_STATUS_OK;
5094  } else if (*state->input != '=' && strncmp(state->input, "!=", 2)) {
5095  if (core->cmdremote[0]) {
5096  char *s = rz_str_newf("%s %s", core->cmdremote, state->input);
5097  rz_core_rtr_cmd(core, s);
5098  free(s);
5099  } else {
5100  char *res = rz_io_system(core->io, state->input);
5101  if (res) {
5102  rz_cons_printf("%s\n", res);
5103  free(res);
5104  }
5105  }
5106  return RZ_CMD_STATUS_OK;
5107  }
5108  }
5109 
5110  TSSymbol node_symbol = ts_node_symbol(node);
5111  ts_handler handler = ht_up_find(cmd->ts_symbols_ht, node_symbol, NULL);
5112 
5113  bool is_lastcmd = state->core->is_lastcmd;
5114  state->core->is_lastcmd = false;
5115  if (handler) {
5116  ret = handler(state, node);
5117  } else {
5118  RZ_LOG_WARN("No handler for this kind of command `%s`\n", ts_node_type(node));
5119  }
5120  if (state->log && !state->core->is_lastcmd) {
5121  free(state->core->lastcmd);
5122  state->core->lastcmd = ts_node_sub_string(node, state->input);
5123  }
5124  state->core->is_lastcmd = is_lastcmd;
5125  return ret;
5126 }
5127 
5129  // TODO: remove tmpseek when no commands will change behaviour based on `@` (tmpseek)
5130  RzCore *core = state->core;
5131  bool saved_tmpseek = core->tmpseek;
5132  core->tmpseek = true;
5133  RzCmdStatus ret = handle_ts_stmt(state, node);
5134  core->tmpseek = saved_tmpseek;
5135  return ret;
5136 }
5137 
5139  RzCore *core = state->core;
5141  ut32 child_count = ts_node_named_child_count(node);
5142  int i;
5143 
5144  RZ_LOG_DEBUG("commands with %d childs\n", child_count);
5145  if (child_count == 0 && !*state->input) {
5146  if (core->cons->context->breaked) {
5147  core->cons->context->breaked = false;
5148  return RZ_CMD_STATUS_INVALID;
5149  }
5150  if (!core->cmdrepeat) {
5151  return RZ_CMD_STATUS_OK;
5152  }
5154  }
5155  if (state->split_lines) {
5157  }
5158  for (i = 0; i < child_count; i++) {
5159  if (core->cons->context->cmd_depth < 1) {
5160  RZ_LOG_ERROR("handle_ts_statements: That was too deep...\n");
5161  return RZ_CMD_STATUS_INVALID;
5162  }
5163  core->cons->context->cmd_depth--;
5164  if (core->max_cmd_depth - core->cons->context->cmd_depth == 1) {
5165  core->prompt_offset = core->offset;
5166  }
5167 
5168  if (state->split_lines && rz_cons_is_breaked()) {
5170  return res;
5171  }
5174  if (state->split_lines) {
5175  rz_cons_flush();
5176  rz_core_task_yield(&core->tasks);
5177  }
5178  core->cons->context->cmd_depth++;
5179  if (cmd_res == RZ_CMD_STATUS_INVALID) {
5180  char *command_str = ts_node_sub_string(command, state->input);
5181  eprintf("Error while executing command: %s\n", command_str);
5182  free(command_str);
5183  res = cmd_res;
5184  goto err;
5185  } else if (cmd_res == RZ_CMD_STATUS_ERROR) {
5186  // make the whole script return ERROR, but continue to
5187  // execute the other commands
5188  res = cmd_res;
5189  } else if (cmd_res != RZ_CMD_STATUS_OK) {
5190  res = cmd_res;
5191  goto err;
5192  }
5193  }
5194 err:
5195  if (state->split_lines) {
5197  }
5198  return res;
5199 }
5200 
5201 #define HANDLER_RULE_OP(name) { #name, handle_ts_##name },
5202 #define RULE_OP(name)
5203 
5205 #include "rz-shell-parser-cmds.inc"
5206  { NULL, NULL },
5207 };
5208 
5209 #define RULE_OP(name) { #name, &ts_##name##_symbol },
5210 #define HANDLER_RULE_OP(name) RULE_OP(name)
5211 
5213 #include "rz-shell-parser-cmds.inc"
5214  { NULL, NULL },
5215 };
5216 
5220 RZ_API RzCmd *rz_core_cmd_new(bool has_cons) {
5221  RzCmd *res = rz_cmd_new(has_cons);
5222  if (!res) {
5223  return NULL;
5224  }
5225 
5226  TSLanguage *lang = tree_sitter_rzcmd();
5227  res->language = lang;
5228  res->ts_symbols_ht = ht_up_new0();
5230  while (entry->name) {
5231  TSSymbol symbol = ts_language_symbol_for_name(lang, entry->name, strlen(entry->name), true);
5232  ht_up_insert(res->ts_symbols_ht, symbol, entry->data);
5233  entry++;
5234  }
5235 
5237  while (entry->name) {
5238  TSSymbol *sym_ptr = entry->data;
5239  *sym_ptr = ts_language_symbol_for_name(lang, entry->name, strlen(entry->name), true);
5240  entry++;
5241  }
5242  return res;
5243 }
5244 
5245 static RzCmdStatus core_cmd_tsrzcmd(RzCore *core, const char *cstr, bool split_lines, bool log) {
5247  bool language_ok = ts_parser_set_language(parser, (TSLanguage *)core->rcmd->language);
5249 
5250  char *input = strdup(rz_str_trim_head_ro(cstr));
5251 
5252  TSTree *tree = ts_parser_parse_string(parser, NULL, input, strlen(input));
5253  if (!tree) {
5255  free(input);
5256  return RZ_CMD_STATUS_INVALID;
5257  }
5258 
5259  TSNode root = ts_tree_root_node(tree);
5260 
5262  struct tsr2cmd_state state;
5263  state.parser = parser;
5264  state.core = core;
5265  state.input = input;
5266  state.tree = tree;
5267  state.log = log;
5268  state.split_lines = split_lines;
5269  rz_pvector_init(&state.saved_input, NULL);
5270  rz_pvector_init(&state.saved_tree, NULL);
5271 
5272  if (state.log) {
5273  rz_line_hist_add(state.input);
5274  }
5275 
5276  char *ts_str = ts_node_string(root);
5277  RZ_LOG_DEBUG("s-expr %s\n", ts_str);
5278  free(ts_str);
5279 
5280  if (is_ts_statements(root) && !ts_node_has_error(root)) {
5281  res = handle_ts_statements(&state, root);
5282  } else {
5283  // TODO: print a more meaningful error message and use the ERROR
5284  // tokens to indicate where, probably, the error is.
5285  eprintf("Error while parsing command: `%s`\n", input);
5286  }
5287 
5290  free(input);
5291  rz_pvector_fini(&state.saved_input);
5292  rz_pvector_fini(&state.saved_tree);
5293  return res;
5294 }
5295 
5296 static int run_cmd_depth(RzCore *core, char *cmd) {
5297  char *rcmd;
5298  int ret = false;
5299 
5300  if (core->cons->context->cmd_depth < 1) {
5301  eprintf("rz_core_cmd: That was too deep (%s)...\n", cmd);
5302  return false;
5303  }
5304  core->cons->context->cmd_depth--;
5305  for (rcmd = cmd;;) {
5306  char *ptr = strchr(rcmd, '\n');
5307  if (ptr) {
5308  *ptr = '\0';
5309  }
5310  ret = rz_core_cmd_subst(core, rcmd);
5311  if (ret == -1) {
5312  eprintf("|ERROR| Invalid command '%s' (0x%02x)\n", rcmd, *rcmd);
5313  break;
5314  }
5315  if (!ptr) {
5316  break;
5317  }
5318  rcmd = ptr + 1;
5319  }
5320  core->cons->context->cmd_depth++;
5321  return ret;
5322 }
5323 
5325  return core_cmd_tsrzcmd(core, cstr, false, log);
5326 }
5327 
5328 RZ_API int rz_core_cmd(RzCore *core, const char *cstr, int log) {
5329  return rz_cmd_status2int(core_cmd_tsrzcmd(core, cstr, false, log));
5330 }
5331 
5333  return core_cmd_tsrzcmd(core, lines, true, false);
5334 }
5335 
5337  RzCmdStatus status = core_cmd_tsrzcmd(core, lines, true, false);
5338  return status == RZ_CMD_STATUS_OK;
5339 }
5340 
5342  char *data = rz_file_abspath(file);
5343  if (!data) {
5344  return false;
5345  }
5346  char *odata = rz_file_slurp(data, NULL);
5347  free(data);
5348  if (!odata) {
5349  return false;
5350  }
5351  if (!rz_core_cmd_lines(core, odata)) {
5352  eprintf("Failed to run script '%s'\n", file);
5353  free(odata);
5354  return false;
5355  }
5356  free(odata);
5357  return true;
5358 }
5359 
5361  int ret, len;
5362  char *buf, *rcmd;
5364  rcmd = buf = rz_sys_cmd_str(command, 0, &len);
5365  if (!buf) {
5366  return -1;
5367  }
5368  ret = rz_core_cmd(core, rcmd, 0);
5370  free(buf);
5371  return ret;
5372 }
5373 
5374 // TODO: Fix disasm loop is mandatory
5376  char *cmd, *ret = NULL;
5377  cmd = rz_str_newf("pd %i @ 0x%08" PFMT64x, l, addr);
5378  if (cmd) {
5379  ret = rz_core_cmd_str(core, cmd);
5380  free(cmd);
5381  }
5382  return ret;
5383 }
5384 
5386  char *cmd, *ret = NULL;
5387  cmd = rz_str_newf("pD %i @ 0x%08" PFMT64x, b, addr);
5388  if (cmd) {
5389  ret = rz_core_cmd_str(core, cmd);
5390  free(cmd);
5391  }
5392  return ret;
5393 }
5394 
5396  char *ptr, *optr, *str = strdup(buf);
5397  if (!str) {
5398  return false;
5399  }
5400  optr = str;
5401  ptr = strchr(str, '\n');
5402  while (ptr) {
5403  *ptr = '\0';
5404  rz_core_cmd(core, optr, 0);
5405  optr = ptr + 1;
5406  ptr = strchr(str, '\n');
5407  }
5408  rz_core_cmd(core, optr, 0);
5409  free(str);
5410  return true;
5411 }
5412 
5413 RZ_API int rz_core_cmdf(RzCore *core, const char *fmt, ...) {
5414  char string[4096];
5415  int ret;
5416  va_list ap;
5417  va_start(ap, fmt);
5418  vsnprintf(string, sizeof(string), fmt, ap);
5419  ret = rz_core_cmd(core, string, 0);
5420  va_end(ap);
5421  return ret;
5422 }
5423 
5425  return rz_core_cmd_rzshell(core, cmd, 0);
5426 }
5427 
5428 RZ_API int rz_core_cmd0(RzCore *core, const char *cmd) {
5429  return rz_core_cmd(core, cmd, 0);
5430 }
5431 
5432 RZ_API int rz_core_flush(RzCore *core, const char *cmd) {
5433  int ret = rz_core_cmd(core, cmd, 0);
5434  rz_cons_flush();
5435  return ret;
5436 }
5437 
5439  char *tmp = NULL;
5440  char *p = (*cmd != '"') ? strchr(cmd, '|') : NULL;
5441  if (!p && *cmd != '!' && *cmd != '.') {
5442  return rz_core_cmd_str(core, cmd);
5443  }
5444  rz_cons_reset();
5445  if (rz_file_mkstemp("cmd", &tmp) != -1) {
5446  int pipefd = rz_cons_pipe_open(tmp, 1, 0);
5447  if (pipefd == -1) {
5448  rz_file_rm(tmp);
5449  free(tmp);
5450  return rz_core_cmd_str(core, cmd);
5451  }
5452  char *_cmd = strdup(cmd);
5453  rz_core_cmd(core, _cmd, 0);
5454  rz_cons_flush();
5455  rz_cons_pipe_close(pipefd);
5456  if (rz_file_exists(tmp)) {
5457  char *s = rz_file_slurp(tmp, NULL);
5458  rz_file_rm(tmp);
5459  free(tmp);
5460  free(_cmd);
5461  return s ? s : strdup("");
5462  }
5463  eprintf("slurp %s fails\n", tmp);
5464  rz_file_rm(tmp);
5465  free(tmp);
5466  free(_cmd);
5467  return rz_core_cmd_str(core, cmd);
5468  }
5469  return NULL;
5470 }
5471 
5472 RZ_API char *rz_core_cmd_strf(RzCore *core, const char *fmt, ...) {
5473  char string[4096];
5474  char *ret;
5475  va_list ap;
5476  va_start(ap, fmt);
5477  vsnprintf(string, sizeof(string), fmt, ap);
5478  ret = rz_core_cmd_str(core, string);
5479  va_end(ap);
5480  return ret;
5481 }
5482 
5483 static ut8 *core_cmd_raw(RzCore *core, const char *cmd, int *length) {
5484  const char *static_str;
5485  ut8 *retstr = NULL;
5486  rz_cons_push();
5487  bool is_pipe = core->is_pipe;
5488  core->is_pipe = true;
5489  if (rz_core_cmd(core, cmd, 0) == -1) {
5490  core->is_pipe = is_pipe;
5491  rz_cons_pop();
5492  return NULL;
5493  }
5494  core->is_pipe = is_pipe;
5495  rz_cons_filter();
5496  static_str = rz_cons_get_buffer();
5497  if (length) {
5498  int len = rz_cons_get_buffer_len();
5499  retstr = (ut8 *)rz_str_newlen(static_str, len);
5500  *length = len;
5501  } else {
5502  retstr = (ut8 *)strdup(rz_str_get(static_str));
5503  }
5504 
5505  rz_cons_pop();
5506  rz_cons_echo(NULL);
5507  return retstr;
5508 }
5509 
5513 RZ_API char *rz_core_cmd_str(RzCore *core, const char *cmd) {
5515  return (char *)core_cmd_raw(core, cmd, NULL);
5516 }
5517 
5521 RZ_API ut8 *rz_core_cmd_raw(RzCore *core, const char *cmd, int *length) {
5523  return core_cmd_raw(core, cmd, length);
5524 }
5525 
5526 static int compare_cmd_descriptor_name(const void *a, const void *b) {
5527  return strcmp(((RzCmdDescriptor *)a)->cmd, ((RzCmdDescriptor *)b)->cmd);
5528 }
5529 
5531  const ut8 *p;
5532  RzListIter *iter;
5533  RzCmdDescriptor *x, *y;
5534  int n = core->cmd_descriptors->length;
5536  rz_list_foreach (core->cmd_descriptors, iter, y) {
5537  if (--n < 0) {
5538  break;
5539  }
5541  for (p = (const ut8 *)y->cmd; *p; p++) {
5542  if (!x->sub[*p]) {
5543  if (p[1]) {
5546  x->sub[*p] = d;
5547  } else {
5548  x->sub[*p] = y;
5549  }
5550  } else if (!p[1]) {
5551  eprintf("Command '%s' is duplicated, please check\n", y->cmd);
5552  }
5553  x = x->sub[*p];
5554  }
5555  }
5556 }
5557 
5558 static int core_cmd0_wrapper(void *core, const char *cmd) {
5559  return rz_core_cmd0((RzCore *)core, cmd);
5560 }
5561 
5563  struct {
5564  const char *cmd;
5565  const char *description;
5566  RzCmdCb cb;
5567  } cmds[] = {
5568  { "$", "alias", rz_cmd_alias },
5569  { "(", "macro", rz_cmd_macro },
5570  { "/", "search kw, pattern aes", rz_cmd_search },
5571  { "?", "help message", rz_cmd_help },
5572  { "a", "analysis", rz_cmd_analysis },
5573  { "d", "debugger operations", rz_cmd_debug },
5574  { "k", "perform sdb query", rz_cmd_kuery },
5575  { "p", "print current block", rz_cmd_print },
5576  { "V", "enter visual mode", rz_cmd_visual },
5577  { "v", "enter visual mode", rz_cmd_panels },
5578  { "x", "alias for px", rz_cmd_hexdump },
5579  };
5580 
5581  core->rcmd = rz_core_cmd_new(!!core->cons);
5582  core->rcmd->macro.user = core;
5583  core->rcmd->macro.num = core->num;
5584  core->rcmd->macro.cmd = core_cmd0_wrapper;
5587  rz_cmd_set_data(core->rcmd, core);
5589 
5590  size_t i;
5591  for (i = 0; i < RZ_ARRAY_SIZE(cmds); i++) {
5592  if (cmds[i].cb) {
5593  rz_cmd_add(core->rcmd, cmds[i].cmd, cmds[i].cb);
5594  }
5595  }
5597 
5599  cmd_descriptor_init(core);
5600  rzshell_cmddescs_init(core);
5601 }
5602 
5604  ut32 pointer_size = 0;
5605  if (argc != 2 || RZ_STR_ISEMPTY(argv[1])) {
5606  pointer_size = 32;
5607  } else if (!strcmp(argv[1], "32")) {
5608  pointer_size = 32;
5609  } else if (!strcmp(argv[1], "64")) {
5610  pointer_size = 64;
5611  }
5612  return bool2status(rz_core_bin_basefind_print(core, pointer_size, state));
5613 }
size_t len
Definition: 6502dis.c:15
si
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
RZ_API ut64 rz_analysis_function_linear_size(RzAnalysisFunction *fcn)
Definition: function.c:318
#define e(frag)
#define RZ_IPI
Definition: analysis_wasm.c:11
lzma_index ** i
Definition: index.h:629
const char * ts_node_type(TSNode)
Definition: node.c:420
void ts_parser_delete(TSParser *parser)
Definition: parser.c:1725
TSNode ts_node_named_child(TSNode, uint32_t)
Definition: node.c:496
uint32_t ts_node_start_byte(TSNode)
Definition: node.c:36
char * ts_node_string(TSNode)
Definition: node.c:426
TSNode ts_node_child(TSNode, uint32_t)
Definition: node.c:492
uint32_t ts_node_named_child_count(TSNode)
Definition: node.c:611
bool ts_node_is_null(TSNode)
Definition: node.c:434
TSNode ts_node_child_by_field_name(TSNode self, const char *field_name, uint32_t field_name_length)
Definition: node.c:589
TSSymbol ts_node_symbol(TSNode)
Definition: node.c:414
void ts_tree_delete(TSTree *self)
Definition: tree.c:26
TSPoint ts_node_start_point(TSNode)
Definition: node.c:40
TSNode ts_tree_root_node(const TSTree *self)
Definition: tree.c:36
bool ts_parser_set_language(TSParser *self, const TSLanguage *language)
Definition: parser.c:1754
bool ts_node_has_error(TSNode)
Definition: node.c:457
uint32_t ts_node_end_byte(TSNode)
Definition: node.c:406
TSParser * ts_parser_new(void)
Definition: parser.c:1704
TSNode ts_node_parent(TSNode)
Definition: node.c:461
TSTree * ts_parser_parse_string(TSParser *self, const TSTree *old_tree, const char *string, uint32_t length)
Definition: parser.c:1945
TSSymbol ts_language_symbol_for_name(const TSLanguage *self, const char *string, uint32_t length, bool is_named)
Definition: language.c:74
TSPoint ts_node_end_point(TSNode)
Definition: node.c:410
static const char ext[]
Definition: apprentice.c:1981
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
ut16 val
Definition: armass64_const.h:6
static bool err
Definition: armass.c:435
static ut8 bytes[32]
Definition: asm_arc.c:23
static csh cd
Definition: asm_mips_cs.c:10
RZ_API RzBinObject * rz_bin_cur_object(RzBin *bin)
Definition: bin.c:900
RZ_DEPRECATE RZ_API RZ_BORROW RzList * rz_bin_get_imports(RZ_NONNULL RzBin *bin)
Definition: bin.c:579
RZ_DEPRECATE RZ_API RZ_BORROW RzList * rz_bin_get_symbols(RZ_NONNULL RzBin *bin)
Definition: bin.c:696
RZ_DEPRECATE RZ_API RZ_BORROW RzList * rz_bin_get_strings(RZ_NONNULL RzBin *bin)
Definition: bin.c:690
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
static SblHeader sb
Definition: bin_mbn.c:26
static RzBinSourceLineInfo * lines(RzBinFile *bf)
Definition: bin_symbols.c:427
const char * desc
Definition: bin_vsf.c:19
int bits(struct state *s, int need)
Definition: blast.c:72
RZ_API void rz_analysis_block_ref(RzAnalysisBlock *bb)
Definition: block.c:40
RZ_API ut64 rz_analysis_block_get_op_size(RzAnalysisBlock *bb, size_t i)
Definition: block.c:1070
RZ_API ut64 rz_analysis_block_get_op_addr(RzAnalysisBlock *block, size_t i)
Definition: block.c:1016
RZ_API void rz_analysis_block_unref(RzAnalysisBlock *bb)
Definition: block.c:370
RZ_API RzList * rz_analysis_get_blocks_in(RzAnalysis *analysis, ut64 addr)
Definition: block.c:133
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
RZ_IPI void rzshell_cmddescs_init(RzCore *core)
Definition: cmd_descs.c:14595
RZ_IPI int rz_cmd_debug(void *data, const char *input)
Definition: cmd_debug.c:2289
RZ_IPI int rz_cmd_print(void *data, const char *input)
Definition: cmd_print.c:4700
RZ_IPI int rz_cmd_analysis(void *data, const char *input)
RZ_IPI int rz_cmd_macro(void *data, const char *input)
Definition: cmd_macro.c:22
RZ_IPI int rz_cmd_search(void *data, const char *input)
Definition: cmd_search.c:2875
RZ_IPI int rz_cmd_hexdump(void *data, const char *input)
Definition: cmd_print.c:5669
RZ_IPI int rz_equal_H_handler_old(void *data, const char *input)
Definition: cmd_remote.c:88
RZ_IPI int rz_cmd_help(void *data, const char *input)
Definition: cmd_help.c:419
RZ_API int rz_type_parse_file(RzTypeDB *typedb, const char *path, const char *dir, char **error_msg)
Parses the C types file creating the new parser state.
Definition: c_cpp_parser.c:260
RZ_API bool rz_core_bin_basefind_print(RzCore *core, ut32 pointer_size, RzCmdStateOutput *state)
Definition: cbin.c:2573
RZ_API void rz_core_sysenv_begin(RzCore *core)
Definition: cfile.c:540
RZ_API void rz_core_sysenv_end(RzCore *core)
Definition: cfile.c:526
RZ_API int rz_core_block_read(RzCore *core)
Definition: cio.c:243
static const char * help_msg_dollar[]
Definition: cmd.c:84
static RzCmdStatus iter_offsets_common(struct tsr2cmd_state *state, TSNode node, bool has_size)
Definition: cmd.c:4485
static char * do_handle_ts_unescape_arg(struct tsr2cmd_state *state, TSNode arg, bool do_unwrap)
Definition: cmd.c:3461
static RzCmdStatus core_cmd_pipe(RzCore *core, struct tsr2cmd_state *state, TSNode rizin_cmd, int argc, char **argv)
Executes a rizin command and pipes the result to the stdin of the program specified in argc/argv.
Definition: cmd.c:3292
RZ_IPI RzCmdStatus rz_push_escaped_handler(RzCore *core, int argc, const char **argv)
Definition: cmd.c:903
static bool set_tmp_bits(RzCore *core, int bits, char **tmpbits, int *cmd_ignbithints)
Definition: cmd.c:1393
RZ_IPI int rz_cmd_kuery(void *data, const char *input)
Definition: cmd.c:642
RZ_API int rz_core_cmd_foreach3(RzCore *core, const char *cmd, char *each)
Definition: cmd.c:2449
struct ts_data_symbol_map map_ts_symbols[]
Definition: cmd.c:5212
RZ_API int rz_line_hist_sdb_up(RzLine *line)
Definition: cmd.c:614
static char * find_eoq(char *p)
Definition: cmd.c:1360
static int rz_core_cmd_subst(RzCore *core, char *cmd)
Definition: cmd.c:1197
static void replace_whitespaces(char *s, char ch)
Definition: cmd.c:3352
RZ_API char * rz_core_cmd_str_pipe(RzCore *core, const char *cmd)
Definition: cmd.c:5438
static void foreach_pairs(RzCore *core, const char *cmd, const char *each)
Definition: cmd.c:2421
static void foreachOffset(RzCore *core, const char *_cmd, const char *each)
Definition: cmd.c:2737
#define TS_START_END(node, start, end)
Definition: cmd.c:3171
static void handle_substitution_args(struct tsr2cmd_state *state, TSNode args, RzList *edits)
Definition: cmd.c:3445
RZ_API RzCmd * rz_core_cmd_new(bool has_cons)
Create an instance of RzCmd for the Rizin language.
Definition: cmd.c:5220
RZ_API void rz_save_panels_layout(RzCore *core, const char *_name)
Definition: panels.c:5270
RZ_API int rz_core_cmd_buffer(RzCore *core, const char *buf)
Definition: cmd.c:5395
RZ_API int rz_line_hist_sdb_down(RzLine *line)
Definition: cmd.c:624
static char * parse_tmp_evals(RzCore *core, const char *str)
Definition: cmd.c:1134
static char * ts_node_handle_arg(struct tsr2cmd_state *state, TSNode command, TSNode arg, uint32_t child_idx)
Definition: cmd.c:3610
static bool substitute_args_do(struct tsr2cmd_state *state, RzList *edits, TSNode *new_command)
Definition: cmd.c:3561
static char * ts_node_sub_parent_string(TSNode parent, TSNode node, const char *cstr)
Definition: cmd.c:3183
static ut8 * core_cmd_raw_node(RzCore *core, struct tsr2cmd_state *state, TSNode rizin_cmd, int *length)
Definition: cmd.c:3264
#define cmdstr(x)
RZ_API int rz_core_cmd_lines(RzCore *core, const char *lines)
Definition: cmd.c:5336
static void cmd_descriptor_init(RzCore *core)
Definition: cmd.c:5530
static void substitute_args_init(struct tsr2cmd_state *state, TSNode command)
Definition: cmd.c:3552
static char * langFromHashbang(RzCore *core, const char *file)
Definition: cmd.c:426
dbt_commands_mode
Definition: cmd.c:4368
@ DBT_COMMANDS_MODE_SP
Definition: cmd.c:4371
@ DBT_COMMANDS_MODE_ADDR
Definition: cmd.c:4369
@ DBT_COMMANDS_MODE_BP
Definition: cmd.c:4370
static struct tsr2cmd_edit * create_cmd_edit(struct tsr2cmd_state *state, TSNode arg, char *new_text)
Definition: cmd.c:3331
RZ_IPI int rz_cmd_alias(void *data, const char *input)
Definition: cmd.c:278
RZ_API int rz_core_cmd0(RzCore *core, const char *cmd)
Definition: cmd.c:5428
#define DEFINE_HANDLE_TS_FCN(name)
Definition: cmd.c:3203
#define DEPRECATED_DEFINE_CMD_DESCRIPTOR_SPECIAL(core, cmd_, named_cmd)
Definition: cmd.c:64
RZ_IPI RzCmdStatus rz_last_output_handler(RzCore *core, int argc, const char **argv)
Definition: cmd.c:929
static const char * help_msg_k[]
Definition: cmd.c:105
static bool help_search_cmd_desc_entry(RzCmd *cmd, const RzCmdDesc *cd, void *user)
Definition: cmd.c:3845
static bool set_tmp_arch(RzCore *core, char *arch, char **tmparch)
Definition: cmd.c:1385
RZ_API ut8 * rz_core_cmd_raw(RzCore *core, const char *cmd, int *length)
Executes a rizin command and returns the raw stdout and its length.
Definition: cmd.c:5521
RZ_API int rz_core_cmd_foreach(RzCore *core, const char *cmd, char *each)
Definition: cmd.c:2798
RZ_API void rz_core_cmd_help(const RzCore *core, const char *help[])
Definition: cmd.c:163
RZ_API int rz_core_cmd(RzCore *core, const char *cstr, int log)
Definition: cmd.c:5328
RZ_IPI RzCmdStatus rz_cmd_help_search_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode)
Definition: cmd.c:3856
static bool iter_dbt_commands(struct tsr2cmd_state *state, TSNode node, enum dbt_commands_mode mode)
Definition: cmd.c:4374
#define DEFINE_HANDLE_TS_FCN_AND_SYMBOL(name)
Definition: cmd.c:3214
RZ_IPI int rz_cmd_visual(void *data, const char *input)
Definition: cmd.c:891
static ut8 * core_cmd_raw(RzCore *core, const char *cmd, int *length)
Definition: cmd.c:5483
RZ_API int rz_core_cmd_file(RzCore *core, const char *file)
Definition: cmd.c:5341
RZ_API bool rz_load_panels_layout(RzCore *core, const char *_name)
Definition: panels.c:5321
RZ_IPI RzCmdStatus rz_basefind_compute_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state)
Definition: cmd.c:5603
RZ_API int rz_core_cmd_command(RzCore *core, const char *command)
Definition: cmd.c:5360
static RzCmdStatus core_cmd_tsrzcmd(RzCore *core, const char *cstr, bool split_lines, bool log)
Definition: cmd.c:5245
RZ_API bool rz_core_run_script(RzCore *core, RZ_NONNULL const char *file)
Definition: cmd.c:457
static TSTree * apply_edits(struct tsr2cmd_state *state, RzList *edits)
Definition: cmd.c:3525
RZ_API char * rz_core_cmd_strf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5472
static int run_cmd_depth(RzCore *core, char *cmd)
Definition: cmd.c:5296
static int rz_core_cmd_subst_i(RzCore *core, char *cmd, char *colon, bool *tmpseek)
Definition: cmd.c:1404
void free_tsr2cmd_edit(struct tsr2cmd_edit *edit)
Definition: cmd.c:3367
static RzCmdDescriptor * cmd_descriptor(const char *cmd, const char *help[])
Definition: cmd.c:28
RZ_IPI RzCmdStatus rz_pointer_handler(RzCore *core, int argc, const char **argv)
Definition: cmd.c:911
static RzCmdStatus do_iter_offsets(RzCore *core, struct tsr2cmd_state *state, TSNode *command, RzCmdParsedArgs *a, bool has_size)
Definition: cmd.c:4455
RZ_API void rz_core_cmd_init(RzCore *core)
Definition: cmd.c:5562
static bool handle_tmp_desc(struct tsr2cmd_state *state, TSNode command, const ut8 *buf, int sz)
Definition: cmd.c:4215
static char * system_exec_stdin(bool is_pipe, int argc, char **argv, const ut8 *input, int input_len, int *length)
Definition: cmd.c:3228
#define DEFINE_IS_TS_FCN_AND_SYMBOL(name)
Definition: cmd.c:3199
#define UPDATE_CMD_STATUS_RES(res, cmd_res, label)
Definition: cmd.c:3218
static bool duplicate_flag(RzFlagItem *flag, void *u)
Definition: cmd.c:172
static bool callback_foreach_kv(void *user, const char *k, const char *v)
Definition: cmd.c:609
static RzCmdParsedArgs * ts_node_handle_arg_prargs(struct tsr2cmd_state *state, TSNode command, TSNode arg, uint32_t child_idx, bool do_unwrap)
Definition: cmd.c:3589
static int core_cmd0_wrapper(void *core, const char *cmd)
Definition: cmd.c:5558
RZ_API int rz_core_cmdf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5413
RZ_API RzCmdStatus rz_core_cmd_lines_rzshell(RzCore *core, const char *lines)
Definition: cmd.c:5332
RZ_IPI bool rz_core_cmd_lastcmd_repeat(RzCore *core, bool next)
Definition: cmd.c:216
static bool is_macro_command(const char *ptr)
Definition: cmd.c:1173
RZ_API RzCmdStatus rz_core_cmd0_rzshell(RzCore *core, const char *cmd)
Definition: cmd.c:5424
static void recursive_help_go(RzCore *core, int detail, RzCmdDescriptor *desc)
Definition: cmd.c:185
static RzCmdParsedArgs * parse_args(struct tsr2cmd_state *state, TSNode args, bool do_unwrap)
Definition: cmd.c:3500
static int rz_core_cmd_nullcallback(void *data)
Definition: cmd.c:265
static const char * help_msg_v[]
Definition: cmd.c:154
static RzCmdStatus handle_ts_stmt(struct tsr2cmd_state *state, TSNode node)
Definition: cmd.c:5083
#define DEPRECATED_DEFINE_CMD_DESCRIPTOR(core, cmd_)
Definition: cmd.c:37
static int compare_cmd_descriptor_name(const void *a, const void *b)
Definition: cmd.c:5526
static void tmpenvs_free(void *item)
Definition: cmd.c:1380
RZ_API char * rz_core_disassemble_instr(RzCore *core, ut64 addr, int l)
Definition: cmd.c:5375
static void get_help_wrong_cmd(RzCore *core, const char *cmdname)
Definition: cmd.c:3617
RZ_IPI int rz_cmd_panels(void *data, const char *input)
Definition: cmd.c:850
static RzCmdStatus do_iter_sections(struct tsr2cmd_state *state, TSNode node, bool show_sections)
Definition: cmd.c:4868
static bool substitute_args(struct tsr2cmd_state *state, TSNode args, TSNode *new_command)
Definition: cmd.c:3577
RZ_API char * rz_core_cmd_str(RzCore *core, const char *cmd)
Executes a rizin command and returns the stdout as a string.
Definition: cmd.c:5513
static int lang_run_file(RzCore *core, RzLang *lang, const char *file)
Definition: cmd.c:421
static char * findSeparator(char *p)
Definition: cmd.c:1372
RZ_API RzCmdStatus rz_core_cmd_rzshell(RzCore *core, const char *cstr, int log)
Definition: cmd.c:5324
TSLanguage * tree_sitter_rzcmd()
Definition: parser.c:28912
RZ_API char * rz_core_disassemble_bytes(RzCore *core, ut64 addr, int b)
Definition: cmd.c:5385
static char * find_ch_after_macro(char *ptr, char ch)
Definition: cmd.c:1181
static const char * help_msg_vertical_bar[]
Definition: cmd.c:144
static void recursive_help(RzCore *core, int detail, const char *cmd_prefix)
Definition: cmd.c:205
RZ_API int rz_core_cmd_pipe_old(RzCore *core, char *rizin_cmd, char *shell_cmd)
Definition: cmd.c:1058
static char * ts_node_sub_string(TSNode node, const char *cstr)
Definition: cmd.c:3177
static int bb_cmp(const void *a, const void *b)
Definition: cmd.c:2792
static bool is_group_of_args(TSNode args)
Definition: cmd.c:3428
static bool is_arg(TSNode args)
Definition: cmd.c:3436
#define INTERACTIVE_MAX_REP
Definition: cmd.c:5
RZ_IPI void rz_core_kuery_print(RzCore *core, const char *k)
Definition: cmd.c:634
struct _search_help RzHelpSearch
RZ_API int rz_core_flush(RzCore *core, const char *cmd)
Definition: cmd.c:5432
struct ts_data_symbol_map map_ts_stmt_handlers[]
Definition: cmd.c:5204
static RzCmdStatus handle_ts_stmt_tmpseek(struct tsr2cmd_state *state, TSNode node)
Definition: cmd.c:5128
static void substitute_args_fini(struct tsr2cmd_state *state)
Definition: cmd.c:3538
static bool copy_into_flagitem_list(RzFlagItem *flg, void *u)
Definition: cmd.c:2415
RzCmdStatus(* ts_handler)(struct tsr2cmd_state *state, TSNode node)
Definition: cmd.c:3164
static bool is_handled_args(TSNode args)
Definition: cmd.c:3440
static char * do_handle_substitution_cmd(struct tsr2cmd_state *state, TSNode inn_cmd)
Definition: cmd.c:3373
static void handle_cmd_substitution_arg(struct tsr2cmd_state *state, TSNode arg, RzList *edits)
Definition: cmd.c:3406
RZ_API RzCmdParsedArgs * rz_cmd_parsed_args_newargs(int n_args, char **args)
Definition: cmd_api.c:2032
RZ_API bool rz_cmd_get_help_json(RzCmd *cmd, const RzCmdDesc *cd, PJ *j)
Generates a JSON output of the given help message description.
Definition: cmd_api.c:1439
RZ_API RzCmdDesc * rz_cmd_get_desc(RzCmd *cmd, const char *cmd_identifier)
Retrieve the command descriptor for the command named cmd_identifier.
Definition: cmd_api.c:372
RZ_API char * rz_cmd_parsed_args_argstr(RzCmdParsedArgs *a)
Definition: cmd_api.c:2115
RZ_API const char * rz_cmd_parsed_args_cmd(RzCmdParsedArgs *a)
Definition: cmd_api.c:2135
RZ_API void rz_cmd_foreach_cmdname(RzCmd *cmd, RzCmdDesc *begin, RzCmdForeachNameCb cb, void *user)
Execute a callback function on each possible command the user can execute.
Definition: cmd_api.c:2474
RZ_API bool rz_cmd_alias_del(RzCmd *cmd, const char *k)
Definition: cmd_api.c:431
RZ_API bool rz_cmd_parsed_args_setcmd(RzCmdParsedArgs *a, const char *cmd)
Definition: cmd_api.c:2094
RZ_API int rz_cmd_add(RzCmd *c, const char *cmd, RzCmdCb cb)
Definition: cmd_api.c:528
RZ_API char * rz_cmd_unescape_arg(const char *arg, RzCmdEscape esc)
Definition: cmd_api.c:2536
RZ_API int rz_cmd_call(RzCmd *cmd, const char *input)
Definition: cmd_api.c:546
RZ_API bool rz_cmd_get_help_strbuf(RzCmd *cmd, const RzCmdDesc *cd, bool use_color, RzStrBuf *sb)
Generates a text output of the given help message description (summary format)
Definition: cmd_api.c:1488
RZ_API RzCmdParsedArgs * rz_cmd_parsed_args_newcmd(const char *cmd)
Definition: cmd_api.c:2028
RZ_API int rz_cmd_alias_set(RzCmd *cmd, const char *k, const char *v, int remote)
Definition: cmd_api.c:458
RZ_API char * rz_cmd_alias_get(RzCmd *cmd, const char *k, int remote)
Definition: cmd_api.c:501
RZ_API int rz_cmd_macro_call(RzCmdMacro *mac, const char *name)
Definition: cmd_api.c:1993
RZ_API RzCmdStatus rz_cmd_call_parsed_args(RzCmd *cmd, RzCmdParsedArgs *args)
Definition: cmd_api.c:794
RZ_API int rz_cmd_set_data(RzCmd *cmd, void *data)
Definition: cmd_api.c:523
RZ_API char * rz_cmd_get_help(RzCmd *cmd, RzCmdParsedArgs *args, bool use_color)
Definition: cmd_api.c:1494
RZ_API RzCmd * rz_cmd_new(bool has_cons)
Definition: cmd_api.c:190
static int value
Definition: cmd_api.c:93
RZ_API RzCmdDesc * rz_cmd_get_desc_best(RzCmd *cmd, const char *cmd_identifier)
Retrieve the command descriptor that best matches the name cmd_identifier.
Definition: cmd_api.c:355
RZ_API void rz_cmd_parsed_args_free(RzCmdParsedArgs *a)
Definition: cmd_api.c:2036
RZ_API char * rz_cmd_escape_arg(const char *arg, RzCmdEscape esc)
Definition: cmd_api.c:2516
RZ_API char ** rz_cmd_alias_keys(RzCmd *cmd, int *sz)
Definition: cmd_api.c:412
static const char * help_msg_greater_sign[]
Definition: cmd_help.c:201
static const char * help_msg_at_at[]
Definition: cmd_print.c:154
#define append(x, y)
Definition: cmd_print.c:1740
static const char * help_msg_at_at_at[]
Definition: cmd_print.c:175
static const char * help_msg_at[]
Definition: cmd_print.c:102
RZ_IPI bool rz_core_seek_to_register(RzCore *core, const char *regname, bool is_silent)
Definition: cmd_seek.c:22
RZ_IPI int rz_core_seek_opcode(RzCore *core, int n, bool silent)
Definition: cmd_seek.c:86
static io_buf out_buf
Definition: coder.c:40
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
Definition: config.c:267
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
RZ_API void rz_cons_pipe_close(int fd)
Definition: cpipe.c:53
RZ_API int rz_cons_pipe_open(const char *file, int fdn, int append)
Definition: cpipe.c:29
RZ_API int rz_cons_get_buffer_len(void)
Definition: cons.c:832
RZ_API void rz_cons_filter(void)
Definition: cons.c:836
RZ_API void rz_cons_last(void)
Definition: cons.c:927
RZ_API RZ_OWN char * rz_cons_get_buffer_dup(void)
Return a newly allocated buffer containing what's currently in RzCons buffer.
Definition: cons.c:827
RZ_API int rz_cons_memcat(const char *str, int len)
Definition: cons.c:1224
RZ_API void rz_cons_set_last_interactive(void)
Definition: cons.c:1729
RZ_API void rz_cons_strcat(const char *str)
Definition: cons.c:1263
RZ_API void rz_cons_newline(void)
Definition: cons.c:1274
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API void rz_cons_set_interactive(bool x)
Definition: cons.c:1724
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API void rz_cons_echo(const char *msg)
Definition: cons.c:939
RZ_API const char * rz_cons_get_buffer(void)
Return the current RzCons buffer.
Definition: cons.c:819
RZ_API bool rz_cons_is_interactive(void)
Definition: cons.c:365
RZ_API void rz_cons_cmd_help(const char *help[], bool use_color)
Definition: cons.c:1954
RZ_API void rz_cons_flush(void)
Definition: cons.c:959
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
RZ_API void rz_cons_reset(void)
Definition: cons.c:804
RZ_API void rz_cons_pop(void)
Definition: cons.c:876
RZ_API void rz_cons_push(void)
Definition: cons.c:860
#define RZ_API
static RzCmdStatus bool2status(bool val)
Definition: core_private.h:208
RZ_IPI bool rz_core_seek_bb_instruction(RzCore *core, int index)
Definition: seek.c:453
RZ_API void rz_core_reg_update_flags(RzCore *core)
Update or create flags for all registers where it makes sense.
Definition: creg.c:106
RZ_API RzReg * rz_core_reg_default(RzCore *core)
Get the currently relevant RzReg.
Definition: creg.c:17
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
cs_arch arch
Definition: cstool.c:13
static static fork const void static count close
Definition: sflib.h:33
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
uint32_t ut32
RzDebug * dbg
Definition: desil.c:30
RZ_API int rz_line_hist_cmd_down(RzLine *line)
Definition: dietline.c:346
RZ_API int rz_line_hist_cmd_up(RzLine *line)
Definition: dietline.c:316
RZ_API int rz_line_set_hist_callback(RzLine *line, RzLineHistoryUpCb up, RzLineHistoryDownCb down)
Definition: dietline.c:292
RZ_API int rz_line_hist_add(const char *line)
Definition: dietline.c:382
RZ_API ut64 rz_debug_reg_get(RzDebug *dbg, const char *name)
Definition: dreg.c:99
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
static char sc[]
Definition: egg_cb.c:6
static states step(struct re_guts *, sopno, sopno, states, int, states)
Definition: engine.c:888
int root
Definition: enough.c:226
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API RzFlagItem * rz_flag_item_clone(RzFlagItem *item)
Definition: flag.c:240
RZ_API void rz_flag_item_free(RzFlagItem *item)
Definition: flag.c:258
RZ_API RzFlagItem * rz_flag_get(RzFlag *f, const char *name)
Definition: flag.c:310
RZ_API RzFlagItem * rz_flag_set(RzFlag *f, const char *name, ut64 off, ut32 size)
Definition: flag.c:521
RZ_API void rz_flag_foreach_space(RzFlag *f, const RzSpace *space, RzFlagItemCb cb, void *user)
Definition: flag.c:826
RZ_API void rz_flag_foreach_glob(RzFlag *f, const char *glob, RzFlagItemCb cb, void *user)
Definition: flag.c:818
void trim(string &s, string characters)
Definition: gen_manual.cpp:43
RZ_API void rz_cons_grep_help(void)
Definition: grep.c:70
RZ_API char * rz_cons_grep_strip(char *cmd, const char *quotestr)
Definition: grep.c:411
RZ_API void rz_cons_grep_parsecmd(char *cmd, const char *quotestr)
Definition: grep.c:401
RZ_API void rz_cons_grep_process(char *grep)
Definition: grep.c:421
RZ_API void rz_config_hold_restore(RzConfigHold *h)
Restore whatever config options were previously saved in h.
Definition: hold.c:132
RZ_API RzConfigHold * rz_config_hold_new(RzConfig *cfg)
Create an opaque object to save/restore some configuration options.
Definition: hold.c:116
RZ_API bool rz_config_hold_s(RzConfigHold *h,...)
Save the current values of a list of config options that have string values.
Definition: hold.c:40
RZ_API bool rz_config_hold_i(RzConfigHold *h,...)
Save the current values of a list of config options that have integer values.
Definition: hold.c:81
RZ_API void rz_config_hold_free(RzConfigHold *h)
Free a RzConfigHold object h.
Definition: hold.c:152
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API bool rz_cons_readpush(const char *str, int len)
Definition: input.c:585
RZ_API int rz_cons_fgets(char *buf, int len, int argc, const char **argv)
Definition: input.c:339
RZ_API bool rz_cons_yesno(int def, const char *fmt,...)
Definition: input.c:666
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
sprintf
Definition: kernel.h:365
vsnprintf
Definition: kernel.h:366
#define reg(n)
RZ_API int rz_lang_run_file(RzLang *lang, const char *file)
Definition: lang.c:183
RZ_API RzLangPlugin * rz_lang_get_by_extension(RzLang *lang, const char *ext)
Definition: lang.c:126
RZ_API bool rz_lang_use(RzLang *lang, const char *name)
Definition: lang.c:155
uint8_t ut8
Definition: lh5801.h:11
void * p
Definition: libc.cpp:67
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_OWN char * rz_core_editor(const RzCore *core, RZ_NULLABLE const char *file, RZ_NULLABLE const char *str)
Definition: core.c:3214
RZ_API bool rz_core_block_size(RzCore *core, ut32 bsize)
Definition: core.c:2842
RZ_API bool rz_debug_select(RzDebug *dbg, int pid, int tid)
Definition: debug.c:595
RZ_API RzList * rz_debug_frames(RzDebug *dbg, ut64 at)
Definition: debug.c:1612
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_BORROW RzListIter * rz_list_insert(RZ_NONNULL RzList *list, ut32 n, void *data)
Inserts a new element at the N-th position.
Definition: list.c:342
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_BORROW void * rz_list_get_top(RZ_NONNULL const RzList *list)
Returns the last element of the list.
Definition: list.c:457
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
Definition: list.c:376
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API char * sdb_querys(Sdb *r, char *buf, size_t len, const char *_cmd)
Definition: query.c:164
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
RZ_API void rz_line_set_prompt(const char *prompt)
Definition: line.c:56
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode dup
Definition: sflib.h:68
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
static const char struct stat static buf struct stat static buf static idle const char static path static fd const char static len const void static prot const char struct module static image struct kernel_sym static table unsigned char static buf static fsuid unsigned struct dirent unsigned static count const struct iovec static count static pid const void static len static flags const struct sched_param static p static pid static policy struct timespec static tp static suid unsigned fn
Definition: sflib.h:186
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname unsigned long static filedes void static end_data_segment static handler static getegid char static len static pgid const char static path dup2
Definition: sflib.h:94
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname pipe
Definition: sflib.h:73
static const char struct stat static buf struct stat static buf static vhangup int status
Definition: sflib.h:145
@ ok
Definition: lz4.c:1706
@ RZ_ABS
int args
Definition: mipsasm.c:18
int x
Definition: mipsasm.c:20
int n
Definition: mipsasm.c:19
#define TRUE
Definition: mybfd.h:103
string FILE
Definition: benchmark.py:21
line
Definition: setup.py:34
description
Definition: setup.py:259
def log(text)
RZ_API Sdb * sdb_ns_path(Sdb *s, const char *path, int create)
Definition: ns.c:213
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
const char * name
Definition: op.c:541
static struct @218 keys[]
int off
Definition: pal.c:13
RZ_API bool rz_core_visual_panels_root(RzCore *core, RzPanelsRoot *panels_root)
Definition: panels.c:5947
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
Definition: reg.c:332
RZ_API const RzList * rz_reg_get_list(RzReg *reg, int type)
Definition: reg.c:389
uint16_t TSSymbol
Definition: parser.h:19
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
RZ_API void rz_core_rtr_cmd(RzCore *core, const char *input)
Definition: rtr.c:850
@ RZ_META_TYPE_COMMENT
Definition: rz_analysis.h:295
#define rz_warn_if_reached()
Definition: rz_assert.h:29
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API char * rz_base64_encode_dyn(const ut8 *bin, size_t sz)
Definition: ubase64.c:92
RZ_API void rz_buf_free(RzBuffer *b)
Free all internal data hold by the buffer and the buffer.
Definition: buf.c:1253
RZ_API RZ_OWN RzBuffer * rz_buf_new_with_bytes(RZ_NULLABLE RZ_BORROW const ut8 *bytes, ut64 len)
Creates a new buffer with a bytes array.
Definition: buf.c:465
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
@ RZ_CMD_ESCAPE_MULTI_ARG
The string should be escaped so that it appears as one or multiple arguments.
Definition: rz_cmd.h:80
@ RZ_CMD_ESCAPE_SINGLE_QUOTED_ARG
The string should be escaped so that it can be wrapped in '....'.
Definition: rz_cmd.h:83
@ RZ_CMD_ESCAPE_PF_ARG
The string should be escaped so that it appears as one or multiple pf arguments.
Definition: rz_cmd.h:81
@ RZ_CMD_ESCAPE_ONE_ARG
The string should be escaped so that it appears as one single argument.
Definition: rz_cmd.h:79
@ RZ_CMD_ESCAPE_DOUBLE_QUOTED_ARG
The string should be escaped so that it can be wrapped in "....".
Definition: rz_cmd.h:82
int(* RzCmdCb)(void *user, const char *input)
Definition: rz_cmd.h:107
@ RZ_CMD_DESC_TYPE_OLDINPUT
Definition: rz_cmd.h:355
enum rz_cmd_status_t RzCmdStatus
@ RZ_CMD_STATUS_OK
command handler exited in the right way
Definition: rz_cmd.h:24
@ RZ_CMD_STATUS_WRONG_ARGS
command handler could not handle the arguments passed to it
Definition: rz_cmd.h:25
@ RZ_CMD_STATUS_NONEXISTINGCMD
command does not exist
Definition: rz_cmd.h:28
@ RZ_CMD_STATUS_INVALID
command could not be executed (e.g. shell level error, bad expression, etc.)
Definition: rz_cmd.h:27
@ RZ_CMD_STATUS_ERROR
command handler had issues while running (e.g. allocation error, etc.)
Definition: rz_cmd.h:26
@ COLOR_MODE_DISABLED
Definition: rz_cons.h:442
#define RZ_LINE_BUFSIZE
Definition: rz_cons.h:991
static void rz_write_ble(void *dst, ut64 val, bool big_endian, int size)
Definition: rz_endian.h:548
static void rz_write_ble32(void *dest, ut32 val, bool big_endian)
Definition: rz_endian.h:540
static void rz_write_ble64(void *dest, ut64 val, bool big_endian)
Definition: rz_endian.h:544
RZ_API char * rz_file_temp(const char *prefix)
Definition: file.c:1048
RZ_API bool rz_file_is_c(const char *file)
Definition: file.c:147
RZ_API bool rz_file_exists(const char *str)
Definition: file.c:192
RZ_API char * rz_file_abspath(const char *file)
Definition: file.c:267
RZ_API int rz_file_mkstemp(RZ_NULLABLE const char *prefix, char **oname)
Definition: file.c:1058
RZ_API RZ_OWN char * rz_file_slurp(const char *str, RZ_NULLABLE size_t *usz)
Definition: file.c:454
RZ_API bool rz_file_rm(const char *file)
Definition: file.c:865
RZ_API char * rz_file_path(const char *bin)
Definition: file.c:354
RZ_API int rz_hex_str2bin(const char *in, ut8 *out)
Convert an input string in into the binary form in out.
Definition: hex.c:444
static RzIntervalNode * rz_interval_tree_iter_get(RzIntervalTreeIter *it)
#define rz_interval_tree_foreach(tree, it, dat)
RZ_API char * rz_io_system(RzIO *io, const char *cmd)
Definition: io.c:411
RZ_API ut64 rz_io_desc_size(RzIODesc *desc)
Definition: io_desc.c:224
RZ_API RzList * rz_io_map_get_for_fd(RzIO *io, int fd)
Definition: io_map.c:388
RZ_API int rz_io_fd_get_current(RzIO *io)
Definition: io_fd.c:135
RZ_API RzIODesc * rz_io_open_buffer(RzIO *io, RzBuffer *b, int flags, int mode)
Definition: io.c:133
RZ_API bool rz_io_use_fd(RzIO *io, int fd)
Definition: io_fd.c:118
RZ_API RzIOMap * rz_io_map_new(RzIO *io, int fd, int flags, ut64 delta, ut64 addr, ut64 size)
Definition: io_map.c:50
RZ_API bool rz_io_desc_close(RzIODesc *desc)
Definition: io_desc.c:165
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API void * rz_mem_dup(const void *s, int l)
Definition: mem.c:319
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
RZ_API ut64 rz_num_tail(RzNum *num, ut64 addr, const char *hex)
Definition: unum.c:775
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API PJ * pj_ko(PJ *j, const char *k)
Definition: pj.c:156
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_s(PJ *j, const char *k)
Definition: pj.c:197
#define RZ_PRINT_FLAGS_COLOR
Definition: rz_print.h:15
@ RZ_REG_TYPE_LAST
Definition: rz_reg.h:34
RZ_API const char * rz_str_lchr(const char *str, char chr)
Definition: str.c:669
static const char * rz_str_get(const char *str)
Definition: rz_str.h:187
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_append(char *ptr, const char *string)
Definition: str.c:1063
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
RZ_API char RZ_API char * rz_str_newlen(const char *str, int len)
Definition: str.c:871
RZ_API RZ_BORROW char * rz_str_trim_tail(RZ_NONNULL char *str)
Removes whitespace characters (space, tab, newline etc.) from the end of a string and replaces them w...
Definition: str_trim.c:125
RZ_API char * rz_str_trim_dup(const char *str)
Definition: str_trim.c:78
RZ_API void rz_str_trim_head(RZ_NONNULL char *str)
Removes whitespace characters (space, tab, newline etc.) from the end of a string....
Definition: str_trim.c:110
RZ_API char * rz_str_array_join(const char **a, size_t n, const char *sep)
Definition: str.c:3861
RZ_API bool rz_str_glob(const char *str, const char *glob)
Definition: str.c:2368
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67
RZ_API char * rz_str_prepend(char *ptr, const char *string)
Definition: str.c:1027
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
RZ_API const char * rz_str_firstbut(const char *s, char ch, const char *but)
Definition: str.c:2644
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
RZ_API int rz_str_unescape(char *buf)
Definition: str.c:1300
RZ_API const char * rz_str_word_get0(const char *str, int idx)
Definition: str.c:598
RZ_API const char * rz_str_lastbut(const char *s, char ch, const char *but)
Definition: str.c:2670
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
Definition: str.c:3329
RZ_API char * rz_str_trim_nc(char *str)
Definition: str_trim.c:197
RZ_API size_t rz_str_split(char *str, char ch)
Split string str in place by using ch as a delimiter.
Definition: str.c:406
#define IS_WHITESPACE(x)
Definition: rz_str_util.h:13
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
#define IS_WHITECHAR(x)
Definition: rz_str_util.h:5
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API bool rz_strbuf_prepend(RzStrBuf *sb, const char *s)
Definition: strbuf.c:201
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358
RZ_API RzSubprocessWaitReason rz_subprocess_wait(RzSubprocess *proc, ut64 timeout_ms)
Definition: subprocess.c:1185
RZ_API void rz_subprocess_free(RzSubprocess *proc)
Definition: subprocess.c:1273
RZ_API ut8 * rz_subprocess_out(RzSubprocess *proc, int *length)
Definition: subprocess.c:1301
RZ_API RzSubprocess * rz_subprocess_start_opt(RzSubprocessOpt *opt)
Definition: subprocess.c:893
RZ_API void rz_subprocess_fini(void)
Definition: subprocess.c:814
RZ_API ssize_t rz_subprocess_stdin_write(RzSubprocess *proc, const ut8 *buf, size_t buf_size)
Definition: subprocess.c:1206
RZ_API bool rz_subprocess_init(void)
Definition: subprocess.c:787
@ RZ_SUBPROCESS_PIPE_NONE
No pipe should be created. It can be used for stdin, stdout and stderr.
Definition: rz_subprocess.h:16
@ RZ_SUBPROCESS_PIPE_STDOUT
Definition: rz_subprocess.h:20
@ RZ_SUBPROCESS_PIPE_CREATE
Re-use the same pipe as stdout. It can be used for stderr only.
Definition: rz_subprocess.h:18
RZ_API int rz_sys_cmdf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_sys_getenv(const char *key)
Get the value of an environment variable named key or NULL if none exists.
Definition: sys.c:483
RZ_API int rz_sys_execl(const char *pathname, const char *arg,...)
Definition: sys.c:1575
RZ_API int rz_sys_setenv(const char *key, const char *value)
Set an environment variable in the calling process.
Definition: sys.c:405
RZ_API int rz_sys_pipe(int pipefd[2], bool close_on_exec)
Definition: sys.c:1458
RZ_API int rz_sys_open(const char *path, int perm, int mode)
Definition: sys.c:1740
RZ_API int rz_sys_fork(void)
Definition: sys.c:1679
RZ_API int rz_sys_pipe_close(int fd)
Definition: sys.c:1462
RZ_API FILE * rz_sys_fopen(const char *path, const char *mode)
Definition: sys.c:1815
RZ_API int RZ_API char * rz_sys_cmd_str(const char *cmd, const char *input, int *len)
Definition: sys.c:669
RZ_API int rz_sys_signal(int sig, void(*handler)(int))
Definition: sys.c:178
RZ_API int rz_sys_cmd_str_full(const char *cmd, const char *input, char **output, int *len, char **sterr)
Definition: sys.c:590
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
#define rz_sys_perror(x)
Definition: rz_types.h:336
#define PFMT64d
Definition: rz_types.h:394
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_NEW(x)
Definition: rz_types.h:285
int(* PrintfCallback)(const char *str,...) RZ_PRINTF_CHECK(1
Definition: rz_types.h:233
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
RzOutputMode
Enum to describe the way data are printed.
Definition: rz_types.h:38
@ RZ_OUTPUT_MODE_JSON
Definition: rz_types.h:40
@ RZ_OUTPUT_MODE_STANDARD
Definition: rz_types.h:39
#define RZ_PERM_RWX
Definition: rz_types.h:98
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define st64
Definition: rz_types_base.h:10
#define RZ_MAX(x, y)
#define UT64_MAX
Definition: rz_types_base.h:86
RZ_API void * rz_pvector_pop(RzPVector *vec)
Definition: vector.c:372
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
RZ_API void rz_pvector_fini(RzPVector *vec)
Definition: vector.c:331
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
#define isspace(c)
Definition: safe-ctype.h:141
#define isalpha(c)
Definition: safe-ctype.h:125
RZ_API Sdb * sdb_new(const char *path, const char *name, int lock)
Definition: sdb.c:47
RZ_API void sdb_file(Sdb *s, const char *dir)
Definition: sdb.c:128
RZ_API void sdb_drain(Sdb *s, Sdb *f)
Definition: sdb.c:1069
RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user)
Definition: sdb.c:758
RZ_API bool sdb_sync(Sdb *s)
Definition: sdb.c:803
RZ_API bool rz_core_seek(RzCore *core, ut64 addr, bool rb)
Seek to addr.
Definition: seek.c:116
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
static int
Definition: sfsocketcall.h:114
int size_t
Definition: sftypes.h:40
unsigned int uint32_t
Definition: sftypes.h:29
#define O_RDONLY
Definition: sftypes.h:486
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define f(i)
Definition: sha256.c:46
#define a(i)
Definition: sha256.c:41
_W64 signed int intptr_t
Definition: api.h:92
Definition: api.h:55
uint32_t row
Definition: api.h:56
uint32_t column
Definition: api.h:57
Definition: tree.h:15
bool color
Definition: cmd.c:3840
RzStrBuf * sb
Definition: cmd.c:3841
PJ * pj
Definition: cmd.c:3842
RzList * ret
Definition: cmd.c:168
const char * word
Definition: cmd.c:169
Definition: zipcmp.c:77
char * name
Definition: zipcmp.c:78
RzCore * core
Definition: cmd.c:2411
const char * cmd
Definition: cmd.c:2412
Definition: gzappend.c:170
Definition: gzlog.c:289
Definition: z80asm.h:102
Definition: rz_pj.h:12
RzAnalysisMetaType type
Definition: rz_analysis.h:302
RzList * fcns
Definition: rz_analysis.h:565
RzIntervalTree meta
Definition: rz_analysis.h:600
RzTypeDB * typedb
Definition: rz_analysis.h:602
char * name
Definition: rz_bin.h:701
RzList * sections
Definition: rz_bin.h:267
bool is_segment
Definition: rz_bin.h:634
bool is_imported
Definition: rz_bin.h:684
char * name
Definition: rz_cmd.h:425
const char * cmd
Definition: rz_cmd.h:505
ut64 _brk_value
Definition: rz_cmd.h:139
RzCoreCmd cmd
Definition: rz_cmd.h:142
PrintfCallback cb_printf
Definition: rz_cmd.h:143
ut64 * brk_value
Definition: rz_cmd.h:138
void * user
Definition: rz_cmd.h:144
RzNum * num
Definition: rz_cmd.h:145
bool has_space_after_cmd
Definition: rz_cmd.h:119
char * extra
Extra data that is neither a command name nor an argument (e.g. command modifiers/specifiers,...
Definition: rz_cmd.h:120
Represent the output state of a command handler.
Definition: rz_cmd.h:91
RzCmdMacro macro
Definition: rz_cmd.h:482
RzCmdNullCb nullcallback
Definition: rz_cmd.h:480
HtUP * ts_symbols_ht
Definition: rz_cmd.h:485
void * language
Definition: rz_cmd.h:484
RzConsGrep grep
Definition: rz_cons.h:466
struct rz_line_t * line
Definition: rz_cons.h:553
RzConsContext * context
Definition: rz_cons.h:502
bool vmode
Definition: rz_core.h:309
bool break_loop
Definition: rz_core.h:373
RzCons * cons
Definition: rz_core.h:312
int cmdrepeat
Definition: rz_core.h:341
bool is_lastcmd
Definition: rz_core.h:338
RzCmd * rcmd
Definition: rz_core.h:319
RzBin * bin
Definition: rz_core.h:298
ut64 offset
Definition: rz_core.h:301
char * lastcmd
Definition: rz_core.h:337
RzLang * lang
Definition: rz_core.h:328
int max_cmd_depth
Definition: rz_core.h:363
RzAnalysis * analysis
Definition: rz_core.h:322
int seltab
Definition: rz_core.h:368
RzDebug * dbg
Definition: rz_core.h:329
RzPanels * panels
Definition: rz_core.h:335
RzIO * io
Definition: rz_core.h:313
const char * cmdtimes
Definition: rz_core.h:342
RzCmdDescriptor root_cmd_descriptor
Definition: rz_core.h:320
RzNum * num
Definition: rz_core.h:316
bool fixedbits
Definition: rz_core.h:375
RZ_DEPRECATE bool cmd_in_backticks
Definition: rz_core.h:343
RzList * scriptstack
Definition: rz_core.h:361
RzCoreTaskScheduler tasks
Definition: rz_core.h:362
int curtab
Definition: rz_core.h:367
bool is_pipe
Definition: rz_core.h:339
ut64 prompt_offset
Definition: rz_core.h:302
RzList * cmd_descriptors
Definition: rz_core.h:321
bool tmpseek
Definition: rz_core.h:308
Sdb * sdb
Definition: rz_core.h:365
RzFlag * flags
Definition: rz_core.h:330
bool fixedblock
Definition: rz_core.h:377
bool fixedarch
Definition: rz_core.h:376
RzPanelsRoot * panels_root
Definition: rz_core.h:334
RzPrint * print
Definition: rz_core.h:327
char * cmdremote
Definition: rz_core.h:369
ut32 blocksize
Definition: rz_core.h:303
RzConfig * config
Definition: rz_core.h:300
int http_up
Definition: rz_core.h:355
RzList *(* threads)(RzDebug *dbg, int pid)
Definition: rz_debug.h:375
RzList *(* pids)(RzDebug *dbg, int pid)
Definition: rz_debug.h:376
RzList * maps
Definition: rz_debug.h:306
struct rz_debug_plugin_t * cur
Definition: rz_debug.h:295
ut64 offset
Definition: rz_flag.h:38
char * name
Definition: rz_flag.h:35
int fd
Definition: rz_io.h:96
struct rz_io_desc_t * desc
Definition: rz_io.h:60
int va
Definition: rz_io.h:63
RzListIter * head
Definition: rz_list.h:19
ut32 length
Definition: rz_list.h:22
ut64 value
Definition: rz_num.h:63
int flags
Definition: rz_print.h:137
bool cur_enabled
Definition: rz_print.h:130
RzRegisterType type
Register type.
Definition: rz_reg.h:119
int size
in bits> 8,16,32,64 ... 128/256
Definition: rz_reg.h:120
char * name
Definition: rz_reg.h:118
const char * file
< Name of the executable to run. It is searched also in PATH
Definition: rz_subprocess.h:59
Definition: sdb.h:63
Definition: dis.h:43
void * data
Definition: cmd.c:3168
const char * name
Definition: cmd.c:3167
ut32 end
Definition: cmd.c:3159
ut32 start
Definition: cmd.c:3158
TSPoint end_point
Definition: cmd.c:3161
TSPoint start_point
Definition: cmd.c:3160
char * old_text
Definition: cmd.c:3157
char * new_text
Definition: cmd.c:3156
TSNode substitute_cmd
Definition: cmd.c:3152
RzPVector saved_input
Definition: cmd.c:3147
RzCore * core
Definition: cmd.c:3145
RzPVector saved_tree
Definition: cmd.c:3149
char * input
Definition: cmd.c:3146
TSTree * tree
Definition: cmd.c:3148
TSParser * parser
Definition: cmd.c:3144
bool split_lines
Definition: cmd.c:3151
bool log
Definition: cmd.c:3150
const char * command
Definition: main.c:7
uv_timer_t tick
Definition: main.c:8
uv_pipe_t stdin_pipe
Definition: main.c:15
uv_pipe_t stdout_pipe
Definition: main.c:16
struct Proc * proc
static enum exit_status_type exit_status
Exit status to use. This can be changed with set_exit_status().
Definition: main.c:17
RZ_API void rz_core_task_yield(RzCoreTaskScheduler *scheduler)
Definition: task.c:336
#define fail(test)
Definition: tests.h:29
Definition: dis.c:32
static int obs
Definition: visual.c:14
RZ_API int rz_core_visual(RzCore *core, const char *input)
Definition: visual.c:3856
DWORD * HANDLE
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
DWORD
static const z80_opcode fd[]
Definition: z80_tab.h:997
static const char * cb[]
Definition: z80_tab.h:176
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58
static bool input(void *ud, zip_uint8_t *data, zip_uint64_t length)
diff_output_t output
Definition: zipcmp.c:237
int def(FILE *source, FILE *dest, int level)
Definition: zpipe.c:36
int read(izstream &zs, T *x, Items items)
Definition: zstream.h:115