mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-30 20:23:46 +08:00
Add pm3line API to hide readline, allowing easier implementation of alternatives
This commit is contained in:
parent
4e78034a6e
commit
fc13b6b20c
12 changed files with 265 additions and 227 deletions
2
Makefile
2
Makefile
|
@ -287,7 +287,7 @@ style:
|
|||
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | sed 's#com[0-9]#/dev/ttyacm0#'|python3 client/pyscripts/pm3_help2json.py - doc/commands.json
|
||||
|
||||
# Update the readline autocomplete autogenerated code
|
||||
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | python3 client/pyscripts/pm3_help2list.py - client/src/rl_vocabulory.h
|
||||
[ -x client/proxmark3 ] && client/proxmark3 --fulltext | python3 client/pyscripts/pm3_help2list.py - client/src/pm3line_vocabulory.h
|
||||
|
||||
|
||||
# Detecting weird codepages and tabs.
|
||||
|
|
|
@ -340,6 +340,7 @@ set (TARGET_SOURCES
|
|||
${PM3_ROOT}/client/src/pm3.c
|
||||
${PM3_ROOT}/client/src/pm3_binlib.c
|
||||
${PM3_ROOT}/client/src/pm3_bitlib.c
|
||||
${PM3_ROOT}/client/src/pm3line.c
|
||||
${PM3_ROOT}/client/src/prng.c
|
||||
${PM3_ROOT}/client/src/scandir.c
|
||||
${PM3_ROOT}/client/src/scripting.c
|
||||
|
@ -578,6 +579,7 @@ endif (NOT APPLE)
|
|||
if (NOT JANSSON_FOUND)
|
||||
set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK})
|
||||
endif (NOT JANSSON_FOUND)
|
||||
|
||||
if (NOT WHEREAMI_FOUND)
|
||||
set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK})
|
||||
endif (NOT WHEREAMI_FOUND)
|
||||
|
|
|
@ -635,6 +635,7 @@ SRCS = mifare/aiddesfire.c \
|
|||
pm3_bitlib.c \
|
||||
preferences.c \
|
||||
prng.c \
|
||||
pm3line.c \
|
||||
proxmark3.c \
|
||||
scandir.c \
|
||||
uart/uart_posix.c \
|
||||
|
|
|
@ -341,6 +341,7 @@ set (TARGET_SOURCES
|
|||
${PM3_ROOT}/client/src/pm3.c
|
||||
${PM3_ROOT}/client/src/pm3_binlib.c
|
||||
${PM3_ROOT}/client/src/pm3_bitlib.c
|
||||
${PM3_ROOT}/client/src/pm3line.c
|
||||
${PM3_ROOT}/client/src/prng.c
|
||||
${PM3_ROOT}/client/src/scandir.c
|
||||
${PM3_ROOT}/client/src/scripting.c
|
||||
|
@ -581,6 +582,7 @@ endif (NOT APPLE)
|
|||
if (NOT JANSSON_FOUND)
|
||||
set(ADDITIONAL_LNK pm3rrg_rdv4_jansson ${ADDITIONAL_LNK})
|
||||
endif (NOT JANSSON_FOUND)
|
||||
|
||||
if (NOT WHEREAMI_FOUND)
|
||||
set(ADDITIONAL_LNK pm3rrg_rdv4_whereami ${ADDITIONAL_LNK})
|
||||
endif (NOT WHEREAMI_FOUND)
|
||||
|
|
|
@ -12,7 +12,7 @@ This version
|
|||
- Iceman
|
||||
|
||||
Note:
|
||||
This script is used as a helper script to generate the rl_vocabulory.h file.
|
||||
This script is used as a helper script to generate the pm3line_vocabulory.h file.
|
||||
It need a working proxmark3 client to extract the help text.
|
||||
|
||||
Ie: this script can't be used inside the normal build sequence.
|
||||
|
@ -65,22 +65,14 @@ def main():
|
|||
// readline auto complete utilities
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef RL_VOCABULORY_H__
|
||||
#define RL_VOCABULORY_H__
|
||||
#ifndef PM3LINE_VOCABULORY_H__
|
||||
#define PM3LINE_VOCABULORY_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE)
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <readline/readline.h>
|
||||
#include "ui.h" // g_session
|
||||
#include "util.h" // str_ndup
|
||||
|
||||
char* rl_command_generator(const char *text, int state);
|
||||
char **rl_command_completion(const char *text, int start, int end);
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct vocabulory_s {
|
||||
bool offline;
|
||||
|
@ -100,50 +92,6 @@ const static vocabulory_t vocabulory[] = {\n""")
|
|||
|
||||
args.output_file.write(""" {0, NULL}\n};
|
||||
|
||||
|
||||
char **rl_command_completion(const char *text, int start, int end) {
|
||||
rl_attempted_completion_over = 0;
|
||||
return rl_completion_matches (text, rl_command_generator);
|
||||
}
|
||||
|
||||
char* rl_command_generator(const char *text, int state) {
|
||||
static int index;
|
||||
static size_t len;
|
||||
size_t rlen = strlen(rl_line_buffer);
|
||||
const char *command;
|
||||
|
||||
if (!state) {
|
||||
index = 0;
|
||||
len = strlen(text);
|
||||
}
|
||||
|
||||
while ((command = vocabulory[index].name)) {
|
||||
|
||||
// When no pm3 device present
|
||||
// and the command is not available offline,
|
||||
// we skip it.
|
||||
if ((g_session.pm3_present == false) && (vocabulory[index].offline == false )) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (strncmp (command, rl_line_buffer, rlen) == 0) {
|
||||
const char *next = command + (rlen - len);
|
||||
const char *space = strstr(next, " ");
|
||||
if (space != NULL) {
|
||||
return str_ndup(next, space - next);
|
||||
}
|
||||
return str_dup(next);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -17,13 +17,9 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include "cmdhflegic.h"
|
||||
|
||||
#include <stdio.h> // for Mingw readline
|
||||
#include <ctype.h> // tolower
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
|
||||
#include "pm3line.h" // pm3line_read, pm3line_free
|
||||
#include "cliparser.h"
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h" // clearCommandBuffer
|
||||
|
@ -553,19 +549,9 @@ static int CmdLegicWrbl(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "#####################################");
|
||||
const char *confirm = "Do you really want to continue? y(es)/n(o) : ";
|
||||
bool overwrite = false;
|
||||
#ifdef HAVE_READLINE
|
||||
char *answer = readline(confirm);
|
||||
char *answer = pm3line_read(confirm);
|
||||
overwrite = (answer[0] == 'y' || answer[0] == 'Y');
|
||||
#else
|
||||
PrintAndLogEx(NORMAL, "%s" NOLF, confirm);
|
||||
char *answer = NULL;
|
||||
size_t anslen = 0;
|
||||
if (getline(&answer, &anslen, stdin) > 0) {
|
||||
overwrite = (answer[0] == 'y' || answer[0] == 'Y');
|
||||
}
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
#endif
|
||||
free(answer);
|
||||
pm3line_free(answer);
|
||||
if (overwrite == false) {
|
||||
PrintAndLogEx(WARNING, "command cancelled");
|
||||
return PM3_EOPABORTED;
|
||||
|
|
|
@ -993,7 +993,7 @@ void pm3_version(bool verbose, bool oneliner) {
|
|||
PrintAndLogEx(NORMAL, "%s", temp);
|
||||
PrintAndLogEx(NORMAL, " compiled with............. " PM3CLIENTCOMPILER __VERSION__);
|
||||
PrintAndLogEx(NORMAL, " platform.................. " PM3HOSTOS " / " PM3HOSTARCH);
|
||||
#ifdef HAVE_READLINE
|
||||
#if defined(HAVE_READLINE)
|
||||
PrintAndLogEx(NORMAL, " Readline support.......... " _GREEN_("present"));
|
||||
#else
|
||||
PrintAndLogEx(NORMAL, " Readline support.......... " _YELLOW_("absent"));
|
||||
|
|
200
client/src/pm3line.c
Normal file
200
client/src/pm3line.c
Normal file
|
@ -0,0 +1,200 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// See LICENSE.txt for the text of the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// API to abstract Readline / Linenoise support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "pm3line.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h> // for Mingw readline and for getline
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#if defined(HAVE_READLINE)
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#endif
|
||||
#include "pm3line_vocabulory.h"
|
||||
#include "pm3_cmd.h"
|
||||
#include "ui.h" // g_session
|
||||
#include "util.h" // str_ndup
|
||||
|
||||
#if defined(HAVE_READLINE)
|
||||
|
||||
static char* rl_command_generator(const char *text, int state) {
|
||||
static int index;
|
||||
static size_t len;
|
||||
size_t rlen = strlen(rl_line_buffer);
|
||||
const char *command;
|
||||
|
||||
if (!state) {
|
||||
index = 0;
|
||||
len = strlen(text);
|
||||
}
|
||||
|
||||
while ((command = vocabulory[index].name)) {
|
||||
|
||||
// When no pm3 device present
|
||||
// and the command is not available offline,
|
||||
// we skip it.
|
||||
if ((g_session.pm3_present == false) && (vocabulory[index].offline == false )) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (strncmp (command, rl_line_buffer, rlen) == 0) {
|
||||
const char *next = command + (rlen - len);
|
||||
const char *space = strstr(next, " ");
|
||||
if (space != NULL) {
|
||||
return str_ndup(next, space - next);
|
||||
}
|
||||
return str_dup(next);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char **rl_command_completion(const char *text, int start, int end) {
|
||||
rl_attempted_completion_over = 0;
|
||||
return rl_completion_matches (text, rl_command_generator);
|
||||
}
|
||||
|
||||
#endif // HAVE_READLINE
|
||||
|
||||
# if defined(_WIN32)
|
||||
/*
|
||||
static bool WINAPI terminate_handler(DWORD t) {
|
||||
if (t == CTRL_C_EVENT) {
|
||||
flush_history();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
# else
|
||||
static struct sigaction gs_old_sigint_action;
|
||||
static void sigint_handler(int signum) {
|
||||
sigaction(SIGINT, &gs_old_sigint_action, NULL);
|
||||
pm3line_flush_history();
|
||||
kill(0, SIGINT);
|
||||
}
|
||||
#endif
|
||||
|
||||
void pm3line_install_signals(void){
|
||||
# if defined(_WIN32)
|
||||
// SetConsoleCtrlHandler((PHANDLER_ROUTINE)terminate_handler, true);
|
||||
# else
|
||||
struct sigaction action;
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.sa_handler = &sigint_handler;
|
||||
sigaction(SIGINT, &action, &gs_old_sigint_action);
|
||||
# endif
|
||||
#if defined(HAVE_READLINE)
|
||||
rl_catch_signals = 1;
|
||||
rl_set_signals();
|
||||
#endif // HAVE_READLINE
|
||||
}
|
||||
|
||||
void pm3line_init(void) {
|
||||
#if defined(HAVE_READLINE)
|
||||
/* initialize history */
|
||||
using_history();
|
||||
rl_readline_name = "PM3";
|
||||
rl_attempted_completion_function = rl_command_completion;
|
||||
|
||||
#ifdef RL_STATE_READCMD
|
||||
rl_extend_line_buffer(1024);
|
||||
#endif // RL_STATE_READCMD
|
||||
#endif // HAVE_READLINE
|
||||
}
|
||||
|
||||
char *pm3line_read(const char *s) {
|
||||
#if defined(HAVE_READLINE)
|
||||
return readline(s);
|
||||
#else
|
||||
printf("%s", s);
|
||||
char *answer = NULL;
|
||||
size_t anslen = 0;
|
||||
int ret;
|
||||
if ((ret = getline(&answer, &anslen, stdin)) < 0) {
|
||||
// TODO this happens also when kbd_enter_pressed() is used, with a key pressed or not
|
||||
printf("DEBUG: getline returned %i", ret);
|
||||
free(answer);
|
||||
answer = NULL;
|
||||
}
|
||||
return answer;
|
||||
#endif
|
||||
}
|
||||
|
||||
void pm3line_free(void *ref) {
|
||||
free(ref);
|
||||
}
|
||||
|
||||
void pm3line_update_prompt(const char *prompt) {
|
||||
#if defined(HAVE_READLINE)
|
||||
rl_set_prompt(prompt);
|
||||
rl_forced_update_display();
|
||||
#else
|
||||
(void) prompt;
|
||||
#endif
|
||||
}
|
||||
|
||||
int pm3line_load_history(const char *path) {
|
||||
#if defined(HAVE_READLINE)
|
||||
if (read_history(path) == 0) {
|
||||
return PM3_SUCCESS;
|
||||
} else {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
#else
|
||||
(void) path;
|
||||
return PM3_ENOTIMPL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void pm3line_add_history(const char *line) {
|
||||
#if defined(HAVE_READLINE)
|
||||
HIST_ENTRY *entry = history_get(history_length);
|
||||
// add if not identical to latest recorded line
|
||||
if ((!entry) || (strcmp(entry->line, line) != 0)) {
|
||||
add_history(line);
|
||||
}
|
||||
#else
|
||||
(void) line;
|
||||
#endif
|
||||
}
|
||||
|
||||
void pm3line_flush_history(void) {
|
||||
if (g_session.history_path) {
|
||||
#if defined(HAVE_READLINE)
|
||||
write_history(g_session.history_path);
|
||||
#endif // HAVE_READLINE
|
||||
free(g_session.history_path);
|
||||
g_session.history_path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void pm3line_check(int (check)(void)) {
|
||||
#if defined(HAVE_READLINE)
|
||||
rl_event_hook = check;
|
||||
#else
|
||||
check();
|
||||
#endif
|
||||
}
|
||||
|
||||
// TODO:
|
||||
// src/ui.c print_progress()
|
32
client/src/pm3line.h
Normal file
32
client/src/pm3line.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// See LICENSE.txt for the text of the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// API to abstract Readline / Linenoise support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef PM3LINE_H__
|
||||
#define PM3LINE_H__
|
||||
|
||||
void pm3line_init(void);
|
||||
void pm3line_install_signals(void);
|
||||
char *pm3line_read(const char* s);
|
||||
void pm3line_free(void *ref);
|
||||
void pm3line_update_prompt(const char *prompt);
|
||||
int pm3line_load_history(const char *path);
|
||||
void pm3line_add_history(const char *line);
|
||||
void pm3line_flush_history(void);
|
||||
void pm3line_check(int (check)(void));
|
||||
|
||||
#endif // PM3LINE_H__
|
|
@ -16,22 +16,14 @@
|
|||
// readline auto complete utilities
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef RL_VOCABULORY_H__
|
||||
#define RL_VOCABULORY_H__
|
||||
#ifndef PM3LINE_VOCABULORY_H__
|
||||
#define PM3LINE_VOCABULORY_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_READLINE)
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <readline/readline.h>
|
||||
#include "ui.h" // g_session
|
||||
#include "util.h" // str_ndup
|
||||
|
||||
char* rl_command_generator(const char *text, int state);
|
||||
char **rl_command_completion(const char *text, int start, int end);
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct vocabulory_s {
|
||||
bool offline;
|
||||
|
@ -722,50 +714,6 @@ const static vocabulory_t vocabulory[] = {
|
|||
{0, NULL}
|
||||
};
|
||||
|
||||
|
||||
char **rl_command_completion(const char *text, int start, int end) {
|
||||
rl_attempted_completion_over = 0;
|
||||
return rl_completion_matches (text, rl_command_generator);
|
||||
}
|
||||
|
||||
char* rl_command_generator(const char *text, int state) {
|
||||
static int index;
|
||||
static size_t len;
|
||||
size_t rlen = strlen(rl_line_buffer);
|
||||
const char *command;
|
||||
|
||||
if (!state) {
|
||||
index = 0;
|
||||
len = strlen(text);
|
||||
}
|
||||
|
||||
while ((command = vocabulory[index].name)) {
|
||||
|
||||
// When no pm3 device present
|
||||
// and the command is not available offline,
|
||||
// we skip it.
|
||||
if ((g_session.pm3_present == false) && (vocabulory[index].offline == false )) {
|
||||
index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
|
||||
if (strncmp (command, rl_line_buffer, rlen) == 0) {
|
||||
const char *next = command + (rlen - len);
|
||||
const char *space = strstr(next, " ");
|
||||
if (space != NULL) {
|
||||
return str_ndup(next, space - next);
|
||||
}
|
||||
return str_dup(next);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -19,18 +19,12 @@
|
|||
#include "proxmark3.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h> // for Mingw readline
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#ifdef HAVE_READLINE
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include "rl_vocabulory.h"
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <libgen.h> // basename
|
||||
|
||||
#include "pm3line.h"
|
||||
#include "usart_defs.h"
|
||||
#include "util_posix.h"
|
||||
#include "proxgui.h"
|
||||
|
@ -137,48 +131,16 @@ static int check_comm(void) {
|
|||
if (IsCommunicationThreadDead() && g_session.pm3_present) {
|
||||
PrintAndLogEx(INFO, "Running in " _YELLOW_("OFFLINE") " mode. Use "_YELLOW_("\"hw connect\"") " to reconnect\n");
|
||||
prompt_dev = PROXPROMPT_DEV_OFFLINE;
|
||||
#ifdef HAVE_READLINE
|
||||
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
||||
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev);
|
||||
char prompt_filtered[PROXPROMPT_MAX_SIZE] = {0};
|
||||
memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !g_session.supports_colors);
|
||||
rl_set_prompt(prompt_filtered);
|
||||
rl_redisplay();
|
||||
#endif
|
||||
pm3line_update_prompt(prompt_filtered);
|
||||
CloseProxmark(g_session.current_device);
|
||||
}
|
||||
msleep(10);
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_READLINE
|
||||
static void flush_history(void) {
|
||||
if (g_session.history_path) {
|
||||
write_history(g_session.history_path);
|
||||
free(g_session.history_path);
|
||||
g_session.history_path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
# if defined(_WIN32)
|
||||
/*
|
||||
static bool WINAPI terminate_handler(DWORD t) {
|
||||
if (t == CTRL_C_EVENT) {
|
||||
flush_history();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
# else
|
||||
static struct sigaction gs_old_sigint_action;
|
||||
static void sigint_handler(int signum) {
|
||||
sigaction(SIGINT, &gs_old_sigint_action, NULL);
|
||||
flush_history();
|
||||
kill(0, SIGINT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
static bool DetectWindowsAnsiSupport(void) {
|
||||
|
@ -278,30 +240,22 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
g_session.history_path = NULL;
|
||||
if (g_session.incognito) {
|
||||
PrintAndLogEx(INFO, "No history will be recorded");
|
||||
} else {
|
||||
bool loaded_history = false;
|
||||
if (searchHomeFilePath(&g_session.history_path, NULL, PROXHISTORY, true) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "No history will be recorded");
|
||||
g_session.history_path = NULL;
|
||||
} else {
|
||||
|
||||
# if defined(_WIN32)
|
||||
// SetConsoleCtrlHandler((PHANDLER_ROUTINE)terminate_handler, true);
|
||||
# else
|
||||
struct sigaction action;
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.sa_handler = &sigint_handler;
|
||||
sigaction(SIGINT, &action, &gs_old_sigint_action);
|
||||
# endif
|
||||
rl_catch_signals = 1;
|
||||
rl_set_signals();
|
||||
read_history(g_session.history_path);
|
||||
loaded_history = (pm3line_load_history(g_session.history_path) == PM3_SUCCESS);
|
||||
}
|
||||
if (loaded_history) {
|
||||
pm3line_install_signals();
|
||||
} else {
|
||||
PrintAndLogEx(ERR, "No history will be recorded");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// loops every time enter is pressed...
|
||||
while (1) {
|
||||
|
@ -378,19 +332,14 @@ check_script:
|
|||
strcleanrn(script_cmd, script_cmd_len);
|
||||
goto check_script;
|
||||
} else {
|
||||
#ifdef HAVE_READLINE
|
||||
rl_event_hook = check_comm;
|
||||
#else
|
||||
check_comm();
|
||||
#endif
|
||||
pm3line_check(check_comm);
|
||||
prompt_ctx = PROXPROMPT_CTX_INTERACTIVE;
|
||||
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
||||
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev);
|
||||
char prompt_filtered[PROXPROMPT_MAX_SIZE] = {0};
|
||||
memcpy_filter_ansi(prompt_filtered, prompt, sizeof(prompt_filtered), !g_session.supports_colors);
|
||||
g_pendingPrompt = true;
|
||||
#ifdef HAVE_READLINE
|
||||
script_cmd = readline(prompt_filtered);
|
||||
cmd = pm3line_read(prompt_filtered);
|
||||
#if defined(_WIN32)
|
||||
//Check if color support needs to be enabled again in case the window buffer did change
|
||||
g_session.supports_colors = DetectWindowsAnsiSupport();
|
||||
|
@ -405,18 +354,6 @@ check_script:
|
|||
strcleanrn(script_cmd, script_cmd_len);
|
||||
goto check_script;
|
||||
}
|
||||
#else
|
||||
printf("%s", prompt_filtered);
|
||||
cmd = NULL;
|
||||
size_t len = 0;
|
||||
int ret;
|
||||
if ((ret = getline(&cmd, &len, stdin)) < 0) {
|
||||
// TODO this happens also when kbd_enter_pressed() is used, with a key pressed or not
|
||||
printf("GETLINE ERR %i", ret);
|
||||
free(cmd);
|
||||
cmd = NULL;
|
||||
}
|
||||
#endif
|
||||
fflush(NULL);
|
||||
}
|
||||
}
|
||||
|
@ -455,16 +392,10 @@ check_script:
|
|||
PrintAndLogEx(NORMAL, "%s%s", prompt_filtered, cmd);
|
||||
g_printAndLog = old_printAndLog;
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
// add to history if not from a script
|
||||
if (!current_cmdscriptfile()) {
|
||||
HIST_ENTRY *entry = history_get(history_length);
|
||||
// add if not identical to latest recorded cmd
|
||||
if ((!entry) || (strcmp(entry->line, cmd) != 0)) {
|
||||
add_history(cmd);
|
||||
}
|
||||
pm3line_add_history(cmd);
|
||||
}
|
||||
#endif
|
||||
// process cmd
|
||||
g_pendingPrompt = false;
|
||||
int ret = CommandReceived(cmd);
|
||||
|
@ -495,9 +426,7 @@ check_script:
|
|||
while (current_cmdscriptfile())
|
||||
pop_cmdscriptfile();
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
flush_history();
|
||||
#endif
|
||||
pm3line_flush_history();
|
||||
|
||||
if (cmd) {
|
||||
free(cmd);
|
||||
|
@ -780,17 +709,7 @@ int main(int argc, char *argv[]) {
|
|||
char *port = NULL;
|
||||
uint32_t speed = 0;
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
/* initialize history */
|
||||
using_history();
|
||||
|
||||
rl_readline_name = "PM3";
|
||||
rl_attempted_completion_function = rl_command_completion;
|
||||
|
||||
#ifdef RL_STATE_READCMD
|
||||
rl_extend_line_buffer(1024);
|
||||
#endif // RL_STATE_READCMD
|
||||
#endif // HAVE_READLINE
|
||||
pm3line_init();
|
||||
|
||||
char exec_name[100] = {0};
|
||||
strncpy(exec_name, basename(argv[0]), sizeof(exec_name) - 1);
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
#if defined(HAVE_READLINE)
|
||||
//Load readline after stdio.h
|
||||
#include <readline/readline.h>
|
||||
#endif
|
||||
|
@ -643,7 +643,7 @@ void iceSimple_Filter(int *data, const size_t len, uint8_t k) {
|
|||
|
||||
void print_progress(size_t count, uint64_t max, barMode_t style) {
|
||||
int cols = 100 + 35;
|
||||
#ifdef HAVE_READLINE
|
||||
#if defined(HAVE_READLINE)
|
||||
static int prev_cols = 0;
|
||||
int rows;
|
||||
rl_reset_screen_size(); // refresh Readline idea of the actual screen width
|
||||
|
|
Loading…
Reference in a new issue