!! 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;
}
#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) {
int i = 0;
inithist ();
@ -716,6 +730,7 @@ R_API int r_line_hist_list(void) {
}
return i;
}
#endif
R_API void r_line_hist_free(void) {
int i;
@ -746,6 +761,9 @@ R_API bool r_line_hist_load(const char *file) {
}
memset (buf, 0, R_LINE_BUFSIZE);
}
#if R2_USE_NEW_ABI
I.history.load_index = I.history.index;
#endif
fclose (fd);
free (buf);
return true;
@ -2407,7 +2425,11 @@ _end:
// shouldnt be here
if (r_str_startswith (I.buffer.data, "!history")) {
#if R2_USE_NEW_ABI
r_line_hist_list (true);
#else
r_line_hist_list ();
#endif
return "";
}
return I.buffer.data[0] != '\0'? I.buffer.data: "";

View File

@ -470,6 +470,21 @@ struct duplicate_flag_t {
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) {
struct duplicate_flag_t *user = (struct duplicate_flag_t *)u;
/* filter per flag spaces */
@ -3446,7 +3461,15 @@ static int cmd_system(void *data, const char *input) {
}
}
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] == '!') { // !!! & !!!-
cmd_autocomplete (core, input + 2);
} 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);
free (cmd);
} else {
if (r_sandbox_enable (0)) {
R_LOG_ERROR ("The !! command is disabled in sandbox mode");
return 0;
}
if (input[1]) {
if (r_sandbox_enable (0)) {
R_LOG_ERROR ("The !! command is disabled in sandbox mode");
return 0;
}
int olen;
char *out = NULL;
char *cmd = r_core_sysenv_begin (core, input);
@ -3474,28 +3497,33 @@ static int cmd_system(void *data, const char *input) {
free (cmd);
}
} else {
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);
#if R2_USE_NEW_ABI
r_line_hist_list (false);
#else
__line_hist_list (false);
#endif
}
}
break;
case '\0':
#if R2_USE_NEW_ABI
r_line_hist_list (true);
#else
r_line_hist_list ();
#endif
break;
case '?': //!?
case '?': // "!?"
cmd_help_exclamation (core);
break;
case '*':
case '*': // "!*"
// TODO: use the api
{
char *cmd = r_str_trim_dup (input + 1);
cmd = r_str_replace (cmd, " ", "\\ ", true);
cmd = r_str_replace (cmd, "\\ ", " ", false);
cmd = r_str_replace (cmd, "\"", "'", false);
ret = r_core_cmdf (core, "\"#!pipe %s\"", cmd);
free (cmd);
char *cmd = r_str_trim_dup (input + 1);
cmd = r_str_replace (cmd, " ", "\\ ", true);
cmd = r_str_replace (cmd, "\\ ", " ", false);
cmd = r_str_replace (cmd, "\"", "'", false);
ret = r_core_cmdf (core, "\"#!pipe %s\"", cmd);
free (cmd);
}
break;
default:
@ -5694,10 +5722,8 @@ static void foreachWord(RCore *core, const char *_cmd, const char *each) {
/* foreach list of items */
while (each) {
// skip spaces
while (*each == ' ') {
each++;
}
// stahp if empty string
each = r_str_trim_head_ro (each);
// stahp on empty string
if (!*each) {
break;
}
@ -5768,7 +5794,7 @@ static void foreachOffset(RCore *core, const char *_cmd, const char *each) {
*nl = 0;
}
// space separated numbers
while (each && *each) {
while (R_STR_ISNOTEMPTY (each)) {
// find spaces
while (*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 ()) {
break;
}
char *buf = NULL;
const char *tmp = NULL;
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);
ret = handle_command_call (core, cstr);
if (!strcmp (cstr, "!") || !strcmp (cstr, "!!")) {
log = false;
}
if (ret != -1) {
if (log) {
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') {
R_FREE (core->cmdremote);
goto beach; // false
} else if (*cstr != '=' && strncmp (cstr, "!=", 2)) {
} else if (*cstr != '=' && !r_str_startswith (cstr, "!=")) {
if (core->cmdremote[0]) {
char *s = r_str_newf ("%s %s", core->cmdremote, cstr);
r_core_rtr_cmd (core, s);
@ -6378,7 +6406,9 @@ R_API int r_core_cmd_lines(RCore *core, const char *lines) {
return ret;
}
// R2_600 - return bool
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);
if (!data) {
return false;
@ -6646,7 +6676,6 @@ R_API RBuffer *r_core_cmd_tobuf(RCore *core, const char *cmd) {
r_cons_filter ();
RBuffer *out = r_buf_new_with_bytes ((const ut8*)r_cons_get_buffer (), r_cons_get_buffer_len ());
r_cons_pop ();
r_cons_echo (NULL);
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) {
RCoreTask *task = core->tasks.main_task;
char *s = strdup (cmd);
if (!s) {
return 0;
if (R_LIKELY (s)) {
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;
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;
return 0;
}
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 = {
"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",
"!*", "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'",
"!!!", "cmd [args|$type]", "adds the autocomplete value",
"!!!-", "cmd [args]", "removes the autocomplete value",

View File

@ -962,7 +962,6 @@ R_API RCore *r_core_new(void) {
return c;
}
/*-----------------------------------*/
#define radare_argc (sizeof (radare_argv) / sizeof (const char*) - 1)
#define ms_argc (sizeof (ms_argv) / sizeof (const char*) - 1)
static const char *ms_argv[] = {
@ -3172,7 +3171,6 @@ R_API bool r_core_init(RCore *core) {
core->times = R_NEW0 (RCoreTimes);
core->vmode = false;
core_visual_init (&core->visual);
core->lastcmd = NULL;
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) {
#if !R2_USE_NEW_ABI
Gload_index = r_cons_singleton()->line->history.index;
#endif
int ret = 0;
do {
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>
@ -144,23 +144,23 @@ RDebugInfo *bsd_info(RDebug *dbg, const char *arg) {
rdi->exe = strdup (kp->ki_comm);
switch (kp->ki_stat) {
case SSLEEP:
rdi->status = R_DBG_PROC_SLEEP;
break;
case SSTOP:
rdi->status = R_DBG_PROC_STOP;
break;
case SZOMB:
rdi->status = R_DBG_PROC_ZOMBIE;
break;
case SRUN:
case SIDL:
case SLOCK:
case SWAIT:
rdi->status = R_DBG_PROC_RUN;
break;
default:
rdi->status = R_DBG_PROC_DEAD;
case SSLEEP:
rdi->status = R_DBG_PROC_SLEEP;
break;
case SSTOP:
rdi->status = R_DBG_PROC_STOP;
break;
case SZOMB:
rdi->status = R_DBG_PROC_ZOMBIE;
break;
case SRUN:
case SIDL:
case SLOCK:
case SWAIT:
rdi->status = R_DBG_PROC_RUN;
break;
default:
rdi->status = R_DBG_PROC_DEAD;
}
free (kp);

View File

@ -1078,6 +1078,9 @@ typedef struct r_line_hist_t {
int top;
int autosave;
bool do_setup_match;
#if R2_USE_NEW_ABI
int load_index;
#endif
} RLineHistory;
typedef struct r_line_buffer_t {
@ -1138,7 +1141,7 @@ struct r_line_t {
char *contents;
bool zerosep;
bool enable_vi_mode; // can be merged with vi_mode
int vi_mode;
int vi_mode; // TODO bool ?
bool prompt_mode;
RLinePromptType prompt_type;
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 int r_line_hist_label(const char *label, void(*cb)(const char*));
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);
#endif
R_API int r_line_hist_get_size(void);
R_API void r_line_hist_set_size(int size);
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;
if (r_file_exists (path)) {
// TODO: should 'q' unset the interactive bit?
bool isInteractive = r_cons_is_interactive ();
if (isInteractive && r_cons_yesno ('n', "Do you want to run the '%s' script? (y/N) ", path)) {
const bool isint = r_cons_is_interactive ();
if (isint && r_cons_yesno ('n', "Do you want to run the '%s' script? (y/N) ", path)) {
r_core_cmd_file (r, path);
}
}