!! for session history, !. for history save ##shell

This commit is contained in:
pancake 2024-08-05 13:06:19 +02:00 committed by GitHub
parent ebd8bf9042
commit 361b8b0c15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 122 additions and 58 deletions

View File

@ -705,6 +705,20 @@ R_API const char *r_line_hist_get(int n) {
return NULL; return NULL;
} }
#if R2_USE_NEW_ABI
R_API int r_line_hist_list(bool full) {
int i = 0;
inithist ();
if (I.history.data) {
i = full? 0: I.history.load_index;
for (; i < I.history.size && I.history.data[i]; i++) {
const char *pad = r_str_pad (' ', 32 - strlen (I.history.data[i]));
r_cons_printf ("%s %s # !%d\n", I.history.data[i], pad, i);
}
}
return i;
}
#else
R_API int r_line_hist_list(void) { R_API int r_line_hist_list(void) {
int i = 0; int i = 0;
inithist (); inithist ();
@ -716,6 +730,7 @@ R_API int r_line_hist_list(void) {
} }
return i; return i;
} }
#endif
R_API void r_line_hist_free(void) { R_API void r_line_hist_free(void) {
int i; int i;
@ -746,6 +761,9 @@ R_API bool r_line_hist_load(const char *file) {
} }
memset (buf, 0, R_LINE_BUFSIZE); memset (buf, 0, R_LINE_BUFSIZE);
} }
#if R2_USE_NEW_ABI
I.history.load_index = I.history.index;
#endif
fclose (fd); fclose (fd);
free (buf); free (buf);
return true; return true;
@ -2407,7 +2425,11 @@ _end:
// shouldnt be here // shouldnt be here
if (r_str_startswith (I.buffer.data, "!history")) { if (r_str_startswith (I.buffer.data, "!history")) {
#if R2_USE_NEW_ABI
r_line_hist_list (true);
#else
r_line_hist_list (); r_line_hist_list ();
#endif
return ""; return "";
} }
return I.buffer.data[0] != '\0'? I.buffer.data: ""; return I.buffer.data[0] != '\0'? I.buffer.data: "";

View File

@ -470,6 +470,21 @@ struct duplicate_flag_t {
const char *word; const char *word;
}; };
#if !R2_USE_NEW_ABI
extern int Gload_index;
static void __line_hist_list(bool full) {
RLineHistory *hist = &r_cons_singleton()->line->history;
eprintf ("LOAD INDEX %d\n", Gload_index);
if (hist && hist->data) {
int i = full? 0: Gload_index;
for (; i < hist->size && hist->data[i]; i++) {
const char *pad = r_str_pad (' ', 32 - strlen (hist->data[i]));
r_cons_printf ("%s %s # !%d\n", hist->data[i], pad, i);
}
}
}
#endif
static bool duplicate_flag(RFlagItem *flag, void *u) { static bool duplicate_flag(RFlagItem *flag, void *u) {
struct duplicate_flag_t *user = (struct duplicate_flag_t *)u; struct duplicate_flag_t *user = (struct duplicate_flag_t *)u;
/* filter per flag spaces */ /* filter per flag spaces */
@ -3446,7 +3461,15 @@ static int cmd_system(void *data, const char *input) {
} }
} }
break; break;
case '!': //!! case '.': // "!."
{
char *history_file = r_xdg_cachedir ("history");
R_LOG_INFO ("History saved to %s", history_file);
r_line_hist_save (history_file);
free (history_file);
}
break;
case '!': // "!!"
if (input[1] == '!') { // !!! & !!!- if (input[1] == '!') { // !!! & !!!-
cmd_autocomplete (core, input + 2); cmd_autocomplete (core, input + 2);
} else if (input[1] == '?') { } else if (input[1] == '?') {
@ -3456,11 +3479,11 @@ static int cmd_system(void *data, const char *input) {
(void)r_core_cmdf (core, "\"#!pipe %s\"", cmd); (void)r_core_cmdf (core, "\"#!pipe %s\"", cmd);
free (cmd); free (cmd);
} else { } else {
if (r_sandbox_enable (0)) {
R_LOG_ERROR ("The !! command is disabled in sandbox mode");
return 0;
}
if (input[1]) { if (input[1]) {
if (r_sandbox_enable (0)) {
R_LOG_ERROR ("The !! command is disabled in sandbox mode");
return 0;
}
int olen; int olen;
char *out = NULL; char *out = NULL;
char *cmd = r_core_sysenv_begin (core, input); char *cmd = r_core_sysenv_begin (core, input);
@ -3474,28 +3497,33 @@ static int cmd_system(void *data, const char *input) {
free (cmd); free (cmd);
} }
} else { } else {
char *history_file = r_xdg_cachedir ("history"); #if R2_USE_NEW_ABI
R_LOG_INFO ("History saved to %s", history_file); r_line_hist_list (false);
r_line_hist_save (history_file); #else
free (history_file); __line_hist_list (false);
#endif
} }
} }
break; break;
case '\0': case '\0':
#if R2_USE_NEW_ABI
r_line_hist_list (true);
#else
r_line_hist_list (); r_line_hist_list ();
#endif
break; break;
case '?': //!? case '?': // "!?"
cmd_help_exclamation (core); cmd_help_exclamation (core);
break; break;
case '*': case '*': // "!*"
// TODO: use the api // TODO: use the api
{ {
char *cmd = r_str_trim_dup (input + 1); char *cmd = r_str_trim_dup (input + 1);
cmd = r_str_replace (cmd, " ", "\\ ", true); cmd = r_str_replace (cmd, " ", "\\ ", true);
cmd = r_str_replace (cmd, "\\ ", " ", false); cmd = r_str_replace (cmd, "\\ ", " ", false);
cmd = r_str_replace (cmd, "\"", "'", false); cmd = r_str_replace (cmd, "\"", "'", false);
ret = r_core_cmdf (core, "\"#!pipe %s\"", cmd); ret = r_core_cmdf (core, "\"#!pipe %s\"", cmd);
free (cmd); free (cmd);
} }
break; break;
default: default:
@ -5694,10 +5722,8 @@ static void foreachWord(RCore *core, const char *_cmd, const char *each) {
/* foreach list of items */ /* foreach list of items */
while (each) { while (each) {
// skip spaces // skip spaces
while (*each == ' ') { each = r_str_trim_head_ro (each);
each++; // stahp on empty string
}
// stahp if empty string
if (!*each) { if (!*each) {
break; break;
} }
@ -5768,7 +5794,7 @@ static void foreachOffset(RCore *core, const char *_cmd, const char *each) {
*nl = 0; *nl = 0;
} }
// space separated numbers // space separated numbers
while (each && *each) { while (R_STR_ISNOTEMPTY (each)) {
// find spaces // find spaces
while (*each == ' ') { while (*each == ' ') {
each++; each++;
@ -6156,7 +6182,6 @@ R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) {
if (r_cons_is_breaked ()) { if (r_cons_is_breaked ()) {
break; break;
} }
char *buf = NULL; char *buf = NULL;
const char *tmp = NULL; const char *tmp = NULL;
r_core_seek (core, flag->offset, true); r_core_seek (core, flag->offset, true);
@ -6238,6 +6263,9 @@ R_API int r_core_cmd(RCore *core, const char *cstr, bool log) {
} }
r_core_return_code (core, 0); r_core_return_code (core, 0);
ret = handle_command_call (core, cstr); ret = handle_command_call (core, cstr);
if (!strcmp (cstr, "!") || !strcmp (cstr, "!!")) {
log = false;
}
if (ret != -1) { if (ret != -1) {
if (log) { if (log) {
r_line_hist_add (cstr); r_line_hist_add (cstr);
@ -6265,7 +6293,7 @@ R_API int r_core_cmd(RCore *core, const char *cstr, bool log) {
if (*cstr == 'q') { if (*cstr == 'q') {
R_FREE (core->cmdremote); R_FREE (core->cmdremote);
goto beach; // false goto beach; // false
} else if (*cstr != '=' && strncmp (cstr, "!=", 2)) { } else if (*cstr != '=' && !r_str_startswith (cstr, "!=")) {
if (core->cmdremote[0]) { if (core->cmdremote[0]) {
char *s = r_str_newf ("%s %s", core->cmdremote, cstr); char *s = r_str_newf ("%s %s", core->cmdremote, cstr);
r_core_rtr_cmd (core, s); r_core_rtr_cmd (core, s);
@ -6378,7 +6406,9 @@ R_API int r_core_cmd_lines(RCore *core, const char *lines) {
return ret; return ret;
} }
// R2_600 - return bool
R_API int r_core_cmd_file(RCore *core, const char *file) { R_API int r_core_cmd_file(RCore *core, const char *file) {
R_RETURN_VAL_IF_FAIL (core && file, false);
char *data = r_file_abspath (file); char *data = r_file_abspath (file);
if (!data) { if (!data) {
return false; return false;
@ -6646,7 +6676,6 @@ R_API RBuffer *r_core_cmd_tobuf(RCore *core, const char *cmd) {
r_cons_filter (); r_cons_filter ();
RBuffer *out = r_buf_new_with_bytes ((const ut8*)r_cons_get_buffer (), r_cons_get_buffer_len ()); RBuffer *out = r_buf_new_with_bytes ((const ut8*)r_cons_get_buffer (), r_cons_get_buffer_len ());
r_cons_pop (); r_cons_pop ();
r_cons_echo (NULL); r_cons_echo (NULL);
return out; return out;
@ -6656,15 +6685,15 @@ R_API RBuffer *r_core_cmd_tobuf(RCore *core, const char *cmd) {
R_API int r_core_cmd_task_sync(RCore *core, const char *cmd, bool log) { R_API int r_core_cmd_task_sync(RCore *core, const char *cmd, bool log) {
RCoreTask *task = core->tasks.main_task; RCoreTask *task = core->tasks.main_task;
char *s = strdup (cmd); char *s = strdup (cmd);
if (!s) { if (R_LIKELY (s)) {
return 0; task->cmd = s;
task->cmd_log = log;
task->state = R_CORE_TASK_STATE_BEFORE_START;
int res = r_core_task_run_sync (&core->tasks, task);
free (s);
return res;
} }
task->cmd = s; return 0;
task->cmd_log = log;
task->state = R_CORE_TASK_STATE_BEFORE_START;
int res = r_core_task_run_sync (&core->tasks, task);
free (s);
return res;
} }
static int cmd_ox(void *data, const char *input) { // "0x" static int cmd_ox(void *data, const char *input) { // "0x"

View File

@ -175,10 +175,11 @@ static RCoreHelpMessage help_msg_env = {
static RCoreHelpMessage help_msg_exclamation = { static RCoreHelpMessage help_msg_exclamation = {
"Usage:", "!<cmd>", " Run given command as in system(3)", "Usage:", "!<cmd>", " Run given command as in system(3)",
"!", "", "list all historic commands", "!", "", "list all commands in the shell history",
"!", "ls", "execute 'ls' in shell", "!", "ls", "execute 'ls' in shell",
"!*", "r2p x", "run r2 command via r2pipe in current session", "!*", "r2p x", "run r2 command via r2pipe in current session",
"!!", "", "save command history to hist file", "!.", "", "save command history to hist file",
"!!", "", "list commands used in current session",
"!!", "ls~txt", "print output of 'ls' and grep for 'txt'", "!!", "ls~txt", "print output of 'ls' and grep for 'txt'",
"!!!", "cmd [args|$type]", "adds the autocomplete value", "!!!", "cmd [args|$type]", "adds the autocomplete value",
"!!!-", "cmd [args]", "removes the autocomplete value", "!!!-", "cmd [args]", "removes the autocomplete value",

View File

@ -962,7 +962,6 @@ R_API RCore *r_core_new(void) {
return c; return c;
} }
/*-----------------------------------*/
#define radare_argc (sizeof (radare_argv) / sizeof (const char*) - 1) #define radare_argc (sizeof (radare_argv) / sizeof (const char*) - 1)
#define ms_argc (sizeof (ms_argv) / sizeof (const char*) - 1) #define ms_argc (sizeof (ms_argv) / sizeof (const char*) - 1)
static const char *ms_argv[] = { static const char *ms_argv[] = {
@ -3172,7 +3171,6 @@ R_API bool r_core_init(RCore *core) {
core->times = R_NEW0 (RCoreTimes); core->times = R_NEW0 (RCoreTimes);
core->vmode = false; core->vmode = false;
core_visual_init (&core->visual); core_visual_init (&core->visual);
core->lastcmd = NULL; core->lastcmd = NULL;
if (core->print->charset) { if (core->print->charset) {
@ -3489,7 +3487,14 @@ R_API void r_core_free(RCore *c) {
} }
} }
#if !R2_USE_NEW_ABI
R_IPI int Gload_index = 0;
#endif
R_API bool r_core_prompt_loop(RCore *r) { R_API bool r_core_prompt_loop(RCore *r) {
#if !R2_USE_NEW_ABI
Gload_index = r_cons_singleton()->line->history.index;
#endif
int ret = 0; int ret = 0;
do { do {
int err = r_core_prompt (r, false); int err = r_core_prompt (r, false);

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2023 - pancake */ /* radare - LGPL - Copyright 2009-2024 - pancake */
#include <r_userconf.h> #include <r_userconf.h>
@ -144,23 +144,23 @@ RDebugInfo *bsd_info(RDebug *dbg, const char *arg) {
rdi->exe = strdup (kp->ki_comm); rdi->exe = strdup (kp->ki_comm);
switch (kp->ki_stat) { switch (kp->ki_stat) {
case SSLEEP: case SSLEEP:
rdi->status = R_DBG_PROC_SLEEP; rdi->status = R_DBG_PROC_SLEEP;
break; break;
case SSTOP: case SSTOP:
rdi->status = R_DBG_PROC_STOP; rdi->status = R_DBG_PROC_STOP;
break; break;
case SZOMB: case SZOMB:
rdi->status = R_DBG_PROC_ZOMBIE; rdi->status = R_DBG_PROC_ZOMBIE;
break; break;
case SRUN: case SRUN:
case SIDL: case SIDL:
case SLOCK: case SLOCK:
case SWAIT: case SWAIT:
rdi->status = R_DBG_PROC_RUN; rdi->status = R_DBG_PROC_RUN;
break; break;
default: default:
rdi->status = R_DBG_PROC_DEAD; rdi->status = R_DBG_PROC_DEAD;
} }
free (kp); free (kp);

View File

@ -1078,6 +1078,9 @@ typedef struct r_line_hist_t {
int top; int top;
int autosave; int autosave;
bool do_setup_match; bool do_setup_match;
#if R2_USE_NEW_ABI
int load_index;
#endif
} RLineHistory; } RLineHistory;
typedef struct r_line_buffer_t { typedef struct r_line_buffer_t {
@ -1138,7 +1141,7 @@ struct r_line_t {
char *contents; char *contents;
bool zerosep; bool zerosep;
bool enable_vi_mode; // can be merged with vi_mode bool enable_vi_mode; // can be merged with vi_mode
int vi_mode; int vi_mode; // TODO bool ?
bool prompt_mode; bool prompt_mode;
RLinePromptType prompt_type; RLinePromptType prompt_type;
int offset_hist_index; int offset_hist_index;
@ -1172,7 +1175,11 @@ R_API int r_line_hist_add(const char *line);
R_API bool r_line_hist_save(const char *file); R_API bool r_line_hist_save(const char *file);
R_API int r_line_hist_label(const char *label, void(*cb)(const char*)); R_API int r_line_hist_label(const char *label, void(*cb)(const char*));
R_API void r_line_label_show(void); R_API void r_line_label_show(void);
#if R2_USE_NEW_ABI
R_API int r_line_hist_list(bool full);
#else
R_API int r_line_hist_list(void); R_API int r_line_hist_list(void);
#endif
R_API int r_line_hist_get_size(void); R_API int r_line_hist_get_size(void);
R_API void r_line_hist_set_size(int size); R_API void r_line_hist_set_size(int size);
R_API const char *r_line_hist_get(int n); R_API const char *r_line_hist_get(int n);

View File

@ -1702,8 +1702,8 @@ R_API int r_main_radare2(int argc, const char **argv) {
const char *path = uri_splitter? uri_splitter + 3: f; const char *path = uri_splitter? uri_splitter + 3: f;
if (r_file_exists (path)) { if (r_file_exists (path)) {
// TODO: should 'q' unset the interactive bit? // TODO: should 'q' unset the interactive bit?
bool isInteractive = r_cons_is_interactive (); const bool isint = r_cons_is_interactive ();
if (isInteractive && r_cons_yesno ('n', "Do you want to run the '%s' script? (y/N) ", path)) { if (isint && r_cons_yesno ('n', "Do you want to run the '%s' script? (y/N) ", path)) {
r_core_cmd_file (r, path); r_core_cmd_file (r, path);
} }
} }