2010-02-21 08:47:22 +08:00
//-----------------------------------------------------------------------------
2010-02-26 05:57:35 +08:00
// Copyright (C) 2009 Michael Gernoth <michael at gernoth.net>
2010-02-21 08:47:22 +08:00
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Main binary
//-----------------------------------------------------------------------------
2019-09-05 21:52:40 +08:00
# include "proxmark3.h"
2020-01-06 04:45:29 +08:00
2010-02-07 08:31:32 +08:00
# include <stdlib.h>
2020-01-06 04:45:29 +08:00
# include <stdio.h> // for Mingw readline
# include <limits.h>
2011-06-18 02:39:54 +08:00
# include <unistd.h>
2020-06-09 04:15:47 +08:00
# ifdef HAVE_READLINE
2009-04-09 14:43:20 +08:00
# include <readline/readline.h>
# include <readline/history.h>
2020-06-30 00:10:40 +08:00
# include <signal.h>
2020-06-09 04:15:47 +08:00
# endif
# include <ctype.h>
2020-06-30 00:10:40 +08:00
2019-08-08 22:57:33 +08:00
# include "usart_defs.h"
2018-09-07 03:43:20 +08:00
# include "util_posix.h"
2009-04-09 14:43:20 +08:00
# include "proxgui.h"
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
# include "cmdmain.h"
2012-12-05 07:39:18 +08:00
# include "ui.h"
2015-06-25 18:22:34 +08:00
# include "cmdhw.h"
2017-02-24 22:00:49 +08:00
# include "whereami.h"
2018-09-07 03:43:20 +08:00
# include "comms.h"
2019-09-05 05:29:03 +08:00
# include "fileutils.h"
2019-09-09 07:07:46 +08:00
# include "flash.h"
2020-04-12 11:07:25 +08:00
# include "preferences.h"
2020-05-28 08:13:21 +08:00
# ifndef LIBPM3
2020-09-25 22:43:48 +08:00
# define BANNERMSG1 " Iceman :coffee:"
# define BANNERMSG2 " :snowflake: bleeding edge"
2020-07-01 18:31:57 +08:00
# define BANNERMSG3 " https: //github.com/rfidresearchgroup/proxmark3/"
2020-04-16 15:01:14 +08:00
2020-05-08 06:48:20 +08:00
typedef enum LogoMode { UTF8 , ANSI , ASCII } LogoMode ;
2020-04-10 17:51:08 +08:00
2020-05-08 06:48:20 +08:00
static void showBanner_logo ( LogoMode mode ) {
switch ( mode ) {
case UTF8 : {
2020-05-09 06:24:20 +08:00
const char * sq = " \xE2 \x96 \x88 " ; // square block
const char * tr = " \xE2 \x95 \x97 " ; // top right corner
const char * tl = " \xE2 \x95 \x94 " ; // top left corner
const char * br = " \xE2 \x95 \x9D " ; // bottom right corner
const char * bl = " \xE2 \x95 \x9A " ; // bottom left corner
const char * hl = " \xE2 \x95 \x90 " ; // horiz line
const char * vl = " \xE2 \x95 \x91 " ; // vert line
const char * __ = " " ;
2020-04-12 11:07:25 +08:00
2020-05-08 06:48:20 +08:00
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s " ) ,
2020-05-09 06:24:20 +08:00
sq , sq , sq , sq , sq , sq , tr , __ , sq , sq , sq , tr , __ , __ , __ , sq , sq , sq , tr , sq , sq , sq , sq , sq , tr , __ ) ;
2020-05-08 06:48:20 +08:00
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s " ) ,
2020-05-09 06:24:20 +08:00
sq , sq , tl , hl , hl , sq , sq , tr , sq , sq , sq , sq , tr , __ , sq , sq , sq , sq , vl , bl , hl , hl , hl , sq , sq , tr ) ;
2020-05-08 06:48:20 +08:00
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s " ) ,
2020-05-09 06:24:20 +08:00
sq , sq , sq , sq , sq , sq , tl , br , sq , sq , tl , sq , sq , sq , sq , tl , sq , sq , vl , __ , sq , sq , sq , sq , tl , br ) ;
2020-07-01 18:31:57 +08:00
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s " ) ,
2020-05-09 06:24:20 +08:00
sq , sq , tl , hl , hl , hl , br , __ , sq , sq , vl , bl , sq , sq , tl , br , sq , sq , vl , __ , bl , hl , hl , sq , sq , tr ) ;
2020-07-01 18:31:57 +08:00
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s " ) " " BANNERMSG1 ,
2020-05-09 06:24:20 +08:00
sq , sq , vl , __ , __ , __ , __ , __ , sq , sq , vl , __ , bl , hl , br , __ , sq , sq , vl , sq , sq , sq , sq , sq , tl , br ) ;
2020-07-01 18:31:57 +08:00
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s " ) " " BANNERMSG2 ,
2020-05-09 06:24:20 +08:00
bl , hl , br , __ , __ , __ , __ , __ , bl , hl , br , __ , __ , __ , __ , __ , bl , hl , br , bl , hl , hl , hl , hl , br , __ ) ;
2020-05-08 06:48:20 +08:00
break ;
}
case ANSI : {
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " ██████╗ ███╗ ███╗█████╗ " ) ) ;
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " ██╔══██╗████╗ ████║╚═══██╗ " ) ) ;
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " ██████╔╝██╔████╔██║ ████╔╝ " ) ) ;
2020-07-01 18:31:57 +08:00
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " ██╔═══╝ ██║╚██╔╝██║ ╚══██╗ " ) ) ;
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " ██║ ██║ ╚═╝ ██║█████╔╝ " ) " " BANNERMSG1 ) ;
PrintAndLogEx ( NORMAL , " " _BLUE_ ( " ╚═╝ ╚═╝ ╚═╝╚════╝ " ) " " BANNERMSG2 ) ;
2020-05-08 06:48:20 +08:00
break ;
}
case ASCII : {
PrintAndLogEx ( NORMAL , " ######. ###. ###.#####. " ) ;
PrintAndLogEx ( NORMAL , " ##...##.####. ####. ...##. " ) ;
PrintAndLogEx ( NORMAL , " ######..##.####.##. ####.. " ) ;
2020-07-01 18:31:57 +08:00
PrintAndLogEx ( NORMAL , " ##..... ##..##..##. ..##. " ) ;
PrintAndLogEx ( NORMAL , " ##. ##. .. ##.#####.. " BANNERMSG1 ) ;
PrintAndLogEx ( NORMAL , " .. .. .. ..... " BANNERMSG2 ) ;
2020-05-08 06:48:20 +08:00
break ;
}
}
2020-07-01 18:31:57 +08:00
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , BANNERMSG3 ) ;
2020-05-08 05:00:45 +08:00
}
2020-04-10 17:51:08 +08:00
2019-03-10 18:20:22 +08:00
static void showBanner ( void ) {
2020-04-12 11:07:25 +08:00
2020-05-08 05:00:45 +08:00
g_printAndLog = PRINTANDLOG_PRINT ;
PrintAndLogEx ( NORMAL , " \n " ) ;
# if defined(_WIN32)
2020-04-12 11:07:25 +08:00
if ( GetConsoleCP ( ) = = 65001 ) {
2020-05-08 05:00:45 +08:00
// If on Windows and using UTF-8 then we need utf-8 ascii art for banner.
2020-05-08 06:48:20 +08:00
showBanner_logo ( UTF8 ) ;
2020-05-08 05:00:45 +08:00
} else {
2020-05-08 06:48:20 +08:00
showBanner_logo ( ANSI ) ;
2020-04-12 11:07:25 +08:00
}
2020-05-08 05:00:45 +08:00
# elif defined(__linux__) || defined(__APPLE__)
2020-05-08 06:48:20 +08:00
showBanner_logo ( ANSI ) ;
2019-04-13 19:34:02 +08:00
# else
2020-05-08 06:48:20 +08:00
showBanner_logo ( ASCII ) ;
2019-04-13 19:34:02 +08:00
# endif
2019-12-06 15:51:24 +08:00
// PrintAndLogEx(NORMAL, "\nSupport iceman on patreon - https://www.patreon.com/iceman1001/");
// PrintAndLogEx(NORMAL, " on paypal - https://www.paypal.me/iceman1001");
2020-08-29 22:21:17 +08:00
// PrintAndLogEx(NORMAL, "\nMonero: 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP");
2019-12-06 15:51:24 +08:00
PrintAndLogEx ( NORMAL , " " ) ;
2019-03-10 06:35:06 +08:00
fflush ( stdout ) ;
2019-10-16 20:46:57 +08:00
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG ;
2017-07-31 21:12:38 +08:00
}
2020-05-28 08:13:21 +08:00
# endif //LIBPM3
2016-09-09 17:56:20 +08:00
2020-04-22 18:22:24 +08:00
static const char * prompt_dev = " " ;
static const char * prompt_ctx = " " ;
2020-05-03 07:13:28 +08:00
static void prompt_compose ( char * buf , size_t buflen , const char * promptctx , const char * promptdev ) {
snprintf ( buf , buflen - 1 , PROXPROMPT_COMPOSE , promptdev , promptctx ) ;
2020-04-22 18:22:24 +08:00
}
2020-04-12 11:07:25 +08:00
2019-10-25 06:55:16 +08:00
static int check_comm ( void ) {
2019-05-07 07:06:01 +08:00
// If communications thread goes down. Device disconnected then this should hook up PM3 again.
2019-05-08 07:35:51 +08:00
if ( IsCommunicationThreadDead ( ) & & session . pm3_present ) {
2020-06-19 03:04:57 +08:00
PrintAndLogEx ( INFO , " Running in " _YELLOW_ ( " OFFLINE " ) " mode. Use " _YELLOW_ ( " \" hw connect \" " ) " to reconnect \n " ) ;
2020-04-22 18:22:24 +08:00
prompt_dev = PROXPROMPT_DEV_OFFLINE ;
2020-06-19 03:04:57 +08:00
# ifdef HAVE_READLINE
2020-04-22 18:22:24 +08:00
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 ) , ! session . supports_colors ) ;
rl_set_prompt ( prompt_filtered ) ;
2019-05-08 07:35:51 +08:00
rl_forced_update_display ( ) ;
2020-06-19 03:04:57 +08:00
# endif
2020-05-28 08:13:21 +08:00
CloseProxmark ( session . current_device ) ;
2019-05-07 07:06:01 +08:00
}
2020-08-13 15:04:02 +08:00
msleep ( 10 ) ;
2019-05-07 07:06:01 +08:00
return 0 ;
}
2020-06-30 00:10:40 +08:00
# ifdef HAVE_READLINE
2020-08-13 15:42:50 +08:00
static void flush_history ( void ) {
2020-06-30 00:10:40 +08:00
if ( session . history_path ) {
write_history ( session . history_path ) ;
free ( session . history_path ) ;
}
}
2020-06-30 04:23:46 +08:00
# if defined(_WIN32)
/*
static bool WINAPI terminate_handler ( DWORD t ) {
if ( t = = CTRL_C_EVENT ) {
flush_history ( ) ;
return true ;
}
return false ;
}
*/
# else
2020-06-30 00:10:40 +08:00
struct sigaction old_action ;
static void terminate_handler ( int signum ) {
sigaction ( SIGINT , & old_action , NULL ) ;
flush_history ( ) ;
kill ( 0 , SIGINT ) ;
}
# endif
2019-05-07 07:06:01 +08:00
2020-06-30 04:23:46 +08:00
# endif
2019-09-10 05:46:38 +08:00
// first slot is always NULL, indicating absence of script when idx=0
2020-06-02 02:45:37 +08:00
static FILE * cmdscriptfile [ MAX_NESTED_CMDSCRIPT + 1 ] = { 0 } ;
static uint8_t cmdscriptfile_idx = 0 ;
static bool cmdscriptfile_stayafter = false ;
2019-09-10 05:46:38 +08:00
int push_cmdscriptfile ( char * path , bool stayafter ) {
if ( cmdscriptfile_idx = = MAX_NESTED_CMDSCRIPT ) {
PrintAndLogEx ( ERR , " Too many nested scripts, skipping %s \n " , path ) ;
return PM3_EMALLOC ;
}
2020-06-03 21:27:22 +08:00
FILE * f = fopen ( path , " r " ) ;
if ( f = = NULL )
2019-09-10 05:46:38 +08:00
return PM3_EFILE ;
2020-06-03 21:27:22 +08:00
2019-09-10 05:46:38 +08:00
if ( cmdscriptfile_idx = = 0 )
cmdscriptfile_stayafter = stayafter ;
2020-06-03 21:27:22 +08:00
cmdscriptfile [ + + cmdscriptfile_idx ] = f ;
2019-09-10 05:46:38 +08:00
return PM3_SUCCESS ;
}
2020-05-03 07:13:28 +08:00
static FILE * current_cmdscriptfile ( void ) {
2019-09-10 05:46:38 +08:00
return cmdscriptfile [ cmdscriptfile_idx ] ;
}
2020-05-03 07:13:28 +08:00
static bool pop_cmdscriptfile ( void ) {
2019-09-10 05:46:38 +08:00
fclose ( cmdscriptfile [ cmdscriptfile_idx ] ) ;
cmdscriptfile [ cmdscriptfile_idx - - ] = NULL ;
if ( cmdscriptfile_idx = = 0 )
return cmdscriptfile_stayafter ;
else
return true ;
}
2019-05-06 20:11:23 +08:00
// Main thread of PM3 Client
2018-02-01 22:24:36 +08:00
void
# ifdef __has_attribute
# if __has_attribute(force_align_arg_pointer)
2019-03-09 15:59:13 +08:00
__attribute__ ( ( force_align_arg_pointer ) )
2018-02-01 22:24:36 +08:00
# endif
# endif
2019-08-04 21:34:18 +08:00
main_loop ( char * script_cmds_file , char * script_cmd , bool stayInCommandLoop ) {
2017-09-26 23:04:25 +08:00
2019-03-10 06:35:06 +08:00
char * cmd = NULL ;
bool execCommand = ( script_cmd ! = NULL ) ;
2019-04-27 22:52:23 +08:00
uint16_t script_cmd_len = 0 ;
if ( execCommand ) {
script_cmd_len = strlen ( script_cmd ) ;
2019-04-27 06:30:44 +08:00
strcreplace ( script_cmd , script_cmd_len , ' ; ' , ' \0 ' ) ;
2019-04-27 22:52:23 +08:00
}
2019-03-10 06:35:06 +08:00
bool stdinOnPipe = ! isatty ( STDIN_FILENO ) ;
char script_cmd_buf [ 256 ] = { 0x00 } ; // iceman, needs lua script the same file_path_buffer as the rest
2019-05-01 05:52:40 +08:00
if ( session . pm3_present ) {
2019-03-10 06:35:06 +08:00
// cache Version information now:
2019-03-10 07:00:59 +08:00
if ( execCommand | | script_cmds_file | | stdinOnPipe )
2019-08-21 18:52:59 +08:00
pm3_version ( false , false ) ;
2019-03-10 06:35:06 +08:00
else
2019-08-21 18:52:59 +08:00
pm3_version ( true , false ) ;
2019-03-10 06:35:06 +08:00
}
if ( script_cmds_file ) {
2019-09-05 05:29:03 +08:00
char * path ;
int res = searchFile ( & path , CMD_SCRIPTS_SUBDIR , script_cmds_file , " .cmd " , false ) ;
if ( res = = PM3_SUCCESS ) {
2019-09-10 05:46:38 +08:00
if ( push_cmdscriptfile ( path , stayInCommandLoop ) = = PM3_SUCCESS )
2019-09-05 05:29:03 +08:00
PrintAndLogEx ( SUCCESS , " executing commands from file: %s \n " , path ) ;
else
PrintAndLogEx ( ERR , " could not open " _YELLOW_ ( " %s " ) " ... " , path ) ;
free ( path ) ;
}
2019-03-10 06:35:06 +08:00
}
2020-06-09 04:15:47 +08:00
# ifdef HAVE_READLINE
2020-06-30 00:10:40 +08:00
session . history_path = NULL ;
2020-10-07 00:11:45 +08:00
if ( session . incognito ) {
PrintAndLogEx ( INFO , " No history will be recorded " ) ;
2019-08-29 03:15:11 +08:00
} else {
2020-10-07 00:11:45 +08:00
if ( searchHomeFilePath ( & session . history_path , NULL , PROXHISTORY , true ) ! = PM3_SUCCESS ) {
PrintAndLogEx ( ERR , " No history will be recorded " ) ;
session . history_path = NULL ;
} else {
2020-06-30 00:10:40 +08:00
2020-10-07 00:41:15 +08:00
# if defined(_WIN32)
// SetConsoleCtrlHandler((PHANDLER_ROUTINE)terminate_handler, true);
# else
2020-10-07 00:11:45 +08:00
struct sigaction action ;
memset ( & action , 0 , sizeof ( action ) ) ;
action . sa_handler = & terminate_handler ;
sigaction ( SIGINT , & action , & old_action ) ;
2020-10-07 00:41:15 +08:00
# endif
2020-10-07 00:11:45 +08:00
rl_catch_signals = 1 ;
rl_set_signals ( ) ;
read_history ( session . history_path ) ;
}
2019-08-29 03:15:11 +08:00
}
2020-06-09 04:15:47 +08:00
# endif
2020-06-30 00:10:40 +08:00
2019-03-10 06:35:06 +08:00
// loops every time enter is pressed...
while ( 1 ) {
2020-06-30 00:10:40 +08:00
2019-04-29 04:38:44 +08:00
bool printprompt = false ;
2020-04-22 18:22:24 +08:00
if ( session . pm3_present ) {
if ( conn . send_via_fpc_usart = = false )
prompt_dev = PROXPROMPT_DEV_USB ;
else
prompt_dev = PROXPROMPT_DEV_FPC ;
} else {
prompt_dev = PROXPROMPT_DEV_OFFLINE ;
}
2019-03-10 06:35:06 +08:00
2019-09-10 05:46:38 +08:00
check_script :
2019-03-10 06:35:06 +08:00
// If there is a script file
2019-09-10 05:46:38 +08:00
if ( current_cmdscriptfile ( ) ) {
2019-03-10 06:35:06 +08:00
// clear array
memset ( script_cmd_buf , 0 , sizeof ( script_cmd_buf ) ) ;
// read script file
2019-10-09 19:44:51 +08:00
if ( fgets ( script_cmd_buf , sizeof ( script_cmd_buf ) , current_cmdscriptfile ( ) ) = = NULL ) {
2019-09-10 05:46:38 +08:00
if ( ! pop_cmdscriptfile ( ) )
break ;
2020-05-15 23:04:33 +08:00
2019-09-10 05:46:38 +08:00
goto check_script ;
2019-03-10 06:35:06 +08:00
} else {
2020-04-22 18:22:24 +08:00
prompt_ctx = PROXPROMPT_CTX_SCRIPTFILE ;
2019-03-10 06:35:06 +08:00
// remove linebreaks
strcleanrn ( script_cmd_buf , sizeof ( script_cmd_buf ) ) ;
2020-01-06 05:24:24 +08:00
cmd = str_dup ( script_cmd_buf ) ;
2020-01-06 04:45:29 +08:00
if ( cmd ! = NULL )
2019-04-29 04:38:44 +08:00
printprompt = true ;
2019-03-10 06:35:06 +08:00
}
} else {
// If there is a script command
2019-03-10 07:00:59 +08:00
if ( execCommand ) {
2020-04-22 18:22:24 +08:00
prompt_ctx = PROXPROMPT_CTX_SCRIPTCMD ;
2020-01-06 04:45:29 +08:00
2020-01-06 05:24:24 +08:00
cmd = str_dup ( script_cmd ) ;
2020-01-06 04:45:29 +08:00
if ( cmd ! = NULL )
2019-04-29 04:38:44 +08:00
printprompt = true ;
2020-01-04 23:25:31 +08:00
2019-04-27 06:30:44 +08:00
uint16_t len = strlen ( script_cmd ) + 1 ;
script_cmd + = len ;
2020-01-04 23:25:31 +08:00
2019-04-27 06:30:44 +08:00
if ( script_cmd_len = = len - 1 )
execCommand = false ;
2020-01-04 23:25:31 +08:00
2019-04-27 06:30:44 +08:00
script_cmd_len - = len ;
2019-03-10 06:35:06 +08:00
} else {
// exit after exec command
2019-08-04 21:34:18 +08:00
if ( script_cmd & & ! stayInCommandLoop )
2019-03-10 06:35:06 +08:00
break ;
// if there is a pipe from stdin
if ( stdinOnPipe ) {
2020-04-22 18:22:24 +08:00
prompt_ctx = PROXPROMPT_CTX_STDIN ;
2019-03-10 06:35:06 +08:00
// clear array
memset ( script_cmd_buf , 0 , sizeof ( script_cmd_buf ) ) ;
// get
2019-05-01 04:03:20 +08:00
if ( fgets ( script_cmd_buf , sizeof ( script_cmd_buf ) , stdin ) = = NULL ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( ERR , " STDIN unexpected end, exit... " ) ;
break ;
}
// remove linebreaks
strcleanrn ( script_cmd_buf , sizeof ( script_cmd_buf ) ) ;
2020-01-06 05:24:24 +08:00
cmd = str_dup ( script_cmd_buf ) ;
2020-01-06 04:45:29 +08:00
if ( cmd ! = NULL )
2019-04-29 04:38:44 +08:00
printprompt = true ;
2019-03-10 06:35:06 +08:00
} else {
2020-06-19 03:04:57 +08:00
# ifdef HAVE_READLINE
rl_event_hook = check_comm ;
# else
check_comm ( ) ;
# endif
2020-04-22 18:22:24 +08:00
prompt_ctx = PROXPROMPT_CTX_INTERACTIVE ;
char prompt [ PROXPROMPT_MAX_SIZE ] = { 0 } ;
prompt_compose ( prompt , sizeof ( prompt ) , prompt_ctx , prompt_dev ) ;
2020-04-22 15:32:32 +08:00
char prompt_filtered [ PROXPROMPT_MAX_SIZE ] = { 0 } ;
memcpy_filter_ansi ( prompt_filtered , prompt , sizeof ( prompt_filtered ) , ! session . supports_colors ) ;
2020-08-14 06:14:46 +08:00
g_pendingPrompt = true ;
2020-06-09 04:15:47 +08:00
# ifdef HAVE_READLINE
2020-04-22 15:32:32 +08:00
cmd = readline ( prompt_filtered ) ;
2020-06-09 04:15:47 +08:00
# 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
2019-03-10 06:35:06 +08:00
fflush ( NULL ) ;
}
}
}
// execute command
if ( cmd ) {
// rtrim
size_t l = strlen ( cmd ) ;
2019-04-29 04:38:44 +08:00
while ( l > 0 & & isspace ( cmd [ l - 1 ] ) ) {
cmd [ - - l ] = ' \0 ' ;
}
// ltrim
2019-04-29 04:54:00 +08:00
size_t off = 0 ;
2020-01-04 23:25:31 +08:00
while ( ( cmd [ off ] ! = ' \0 ' ) & & isspace ( cmd [ off ] ) ) {
2019-04-29 04:38:44 +08:00
off + + ;
2020-01-04 23:25:31 +08:00
}
for ( size_t i = 0 ; i < strlen ( cmd ) - off ; i + + ) {
2019-04-29 04:54:00 +08:00
cmd [ i ] = cmd [ i + off ] ;
2020-01-04 23:25:31 +08:00
}
2019-04-29 04:38:44 +08:00
cmd [ strlen ( cmd ) - off ] = ' \0 ' ;
if ( cmd [ 0 ] ! = ' \0 ' ) {
2020-01-04 23:25:31 +08:00
if ( ! printprompt ) {
2019-09-10 03:30:25 +08:00
g_printAndLog = PRINTANDLOG_LOG ;
2020-01-04 23:25:31 +08:00
}
2020-04-22 18:22:24 +08:00
char prompt [ PROXPROMPT_MAX_SIZE ] = { 0 } ;
prompt_compose ( prompt , sizeof ( prompt ) , prompt_ctx , prompt_dev ) ;
2020-05-09 00:12:10 +08:00
// always filter RL magic separators if not using readline
char prompt_filtered [ PROXPROMPT_MAX_SIZE ] = { 0 } ;
memcpy_filter_rlmarkers ( prompt_filtered , prompt , sizeof ( prompt_filtered ) ) ;
PrintAndLogEx ( NORMAL , " %s%s " , prompt_filtered , cmd ) ;
2019-09-10 03:30:25 +08:00
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG ;
2019-05-08 07:35:51 +08:00
2020-06-09 04:15:47 +08:00
# ifdef HAVE_READLINE
2019-09-10 05:46:38 +08:00
// 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
2020-01-04 23:25:31 +08:00
if ( ( ! entry ) | | ( strcmp ( entry - > line , cmd ) ! = 0 ) ) {
2019-09-10 05:46:38 +08:00
add_history ( cmd ) ;
2020-01-04 23:25:31 +08:00
}
2019-09-10 05:46:38 +08:00
}
2020-06-09 04:15:47 +08:00
# endif
2019-09-10 05:46:38 +08:00
// process cmd
2020-08-14 06:14:46 +08:00
g_pendingPrompt = false ;
2019-03-10 06:35:06 +08:00
int ret = CommandReceived ( cmd ) ;
// exit or quit
2019-04-19 06:42:25 +08:00
if ( ret = = PM3_EFATAL )
2019-03-10 06:35:06 +08:00
break ;
}
free ( cmd ) ;
cmd = NULL ;
} else {
PrintAndLogEx ( NORMAL , " \n " ) ;
2019-08-04 21:34:18 +08:00
if ( script_cmds_file & & stayInCommandLoop )
stayInCommandLoop = false ;
else
break ;
2019-03-10 06:35:06 +08:00
}
} // end while
2019-10-04 15:30:36 +08:00
if ( session . pm3_present ) {
clearCommandBuffer ( ) ;
SendCommandNG ( CMD_QUIT_SESSION , NULL , 0 ) ;
msleep ( 100 ) ; // Make sure command is sent before killing client
}
2019-06-03 05:20:02 +08:00
2019-09-10 05:46:38 +08:00
while ( current_cmdscriptfile ( ) )
pop_cmdscriptfile ( ) ;
2019-03-10 06:35:06 +08:00
2020-06-09 04:15:47 +08:00
# ifdef HAVE_READLINE
2020-06-30 00:10:40 +08:00
flush_history ( ) ;
2020-06-09 04:15:47 +08:00
# endif
2020-06-30 00:10:40 +08:00
2019-03-10 06:35:06 +08:00
if ( cmd ) {
free ( cmd ) ;
cmd = NULL ;
}
2009-04-09 14:43:20 +08:00
}
2020-05-28 08:13:21 +08:00
# ifndef LIBPM3
2019-03-10 18:20:22 +08:00
static void dumpAllHelp ( int markdown ) {
2019-05-02 02:48:15 +08:00
session . help_dump_mode = true ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " \n %sProxmark3 command dump%s \n \n " , markdown ? " # " : " " , markdown ? " " : " \n ====================== " ) ;
2019-04-17 02:00:25 +08:00
PrintAndLogEx ( NORMAL , " Some commands are available only if a Proxmark3 is actually connected.%s \n " , markdown ? " " : " " ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Check column \" offline \" for their availability. \n " ) ;
PrintAndLogEx ( NORMAL , " \n " ) ;
command_t * cmds = getTopLevelCommandTable ( ) ;
dumpCommandsRecursive ( cmds , markdown ) ;
2019-05-02 02:48:15 +08:00
session . help_dump_mode = false ;
2014-03-27 05:08:55 +08:00
}
2020-05-28 08:13:21 +08:00
# endif //LIBPM3
2014-03-27 05:08:55 +08:00
2017-02-24 22:00:49 +08:00
static char * my_executable_path = NULL ;
static char * my_executable_directory = NULL ;
2019-03-10 18:20:22 +08:00
const char * get_my_executable_path ( void ) {
2019-03-10 06:35:06 +08:00
return my_executable_path ;
2017-02-24 22:00:49 +08:00
}
2019-03-10 18:20:22 +08:00
const char * get_my_executable_directory ( void ) {
2019-03-10 06:35:06 +08:00
return my_executable_directory ;
2017-02-24 22:00:49 +08:00
}
2019-03-10 18:20:22 +08:00
static void set_my_executable_path ( void ) {
2019-03-10 06:35:06 +08:00
int path_length = wai_getExecutablePath ( NULL , 0 , NULL ) ;
2019-04-14 17:43:05 +08:00
if ( path_length = = - 1 )
2019-04-13 19:34:02 +08:00
return ;
2019-04-14 17:43:05 +08:00
2019-04-13 19:34:02 +08:00
my_executable_path = ( char * ) calloc ( path_length + 1 , sizeof ( uint8_t ) ) ;
int dirname_length = 0 ;
if ( wai_getExecutablePath ( my_executable_path , path_length , & dirname_length ) ! = - 1 ) {
my_executable_path [ path_length ] = ' \0 ' ;
my_executable_directory = ( char * ) calloc ( dirname_length + 2 , sizeof ( uint8_t ) ) ;
strncpy ( my_executable_directory , my_executable_path , dirname_length + 1 ) ;
my_executable_directory [ dirname_length + 1 ] = ' \0 ' ;
2019-03-10 06:35:06 +08:00
}
2017-02-24 22:00:49 +08:00
}
2019-10-27 01:40:32 +08:00
static const char * my_user_directory = NULL ;
2020-04-17 17:29:33 +08:00
// static char _cwd_Buffer [FILENAME_MAX] = {0};
2020-04-14 17:17:00 +08:00
2019-09-13 02:13:01 +08:00
const char * get_my_user_directory ( void ) {
return my_user_directory ;
}
2020-04-17 17:29:33 +08:00
2019-09-13 02:13:01 +08:00
static void set_my_user_directory ( void ) {
2020-04-26 17:18:04 +08:00
/* my_user_directory = getenv("HOME");
2020-04-15 14:40:28 +08:00
2020-04-26 17:18:04 +08:00
// if not found, default to current directory
if ( my_user_directory = = NULL ) {
my_user_directory = GetCurrentDir ( _cwd_Buffer , sizeof ( _cwd_Buffer ) ) ;
2020-10-23 07:24:54 +08:00
// change all slashes to / (windows should not care...
2020-04-26 17:18:04 +08:00
for ( int i = 0 ; i < strlen ( _cwd_Buffer ) ; i + + )
if ( _cwd_Buffer [ i ] = = ' \\ ' ) _cwd_Buffer [ i ] = ' / ' ;
// my_user_directory = ".";
}
*/
2020-04-17 17:29:33 +08:00
my_user_directory = getenv ( " HOME " ) ;
// if not found, default to current directory
if ( my_user_directory = = NULL ) {
uint16_t pathLen = FILENAME_MAX ; // should be a good starting point
bool error = false ;
2020-05-28 02:53:04 +08:00
char * cwd_buffer = ( char * ) calloc ( pathLen , sizeof ( uint8_t ) ) ;
2020-04-26 17:18:04 +08:00
2020-05-28 02:53:04 +08:00
while ( ! error & & ( GetCurrentDir ( cwd_buffer , pathLen ) = = NULL ) ) {
2020-04-17 17:29:33 +08:00
if ( errno = = ERANGE ) { // Need bigger buffer
pathLen + = 10 ; // if buffer was too small add 10 characters and try again
2020-05-28 02:53:04 +08:00
char * tmp = realloc ( cwd_buffer , pathLen ) ;
if ( tmp = = NULL ) {
PrintAndLogEx ( WARNING , " failed to allocate memory " ) ;
free ( cwd_buffer ) ;
return ;
}
cwd_buffer = tmp ;
2020-04-17 17:29:33 +08:00
} else {
2020-05-28 02:53:04 +08:00
free ( cwd_buffer ) ;
return ;
2020-04-17 17:29:33 +08:00
}
}
if ( ! error ) {
2020-04-26 17:18:04 +08:00
2020-05-28 02:53:04 +08:00
for ( int i = 0 ; i < strlen ( cwd_buffer ) ; i + + ) {
if ( cwd_buffer [ i ] = = ' \\ ' ) {
cwd_buffer [ i ] = ' / ' ;
}
}
2020-04-17 17:29:33 +08:00
2020-05-28 02:53:04 +08:00
my_user_directory = cwd_buffer ;
2020-04-17 17:29:33 +08:00
}
}
2019-09-13 02:13:01 +08:00
}
2020-05-28 08:13:21 +08:00
# ifndef LIBPM3
2019-04-14 19:35:52 +08:00
static void show_help ( bool showFullHelp , char * exec_name ) {
2019-04-14 18:54:13 +08:00
2019-09-09 07:07:46 +08:00
PrintAndLogEx ( NORMAL , " \n syntax: %s [-h|-t|-m] " , exec_name ) ;
2019-09-10 02:45:10 +08:00
PrintAndLogEx ( NORMAL , " %s [[-p] <port>] [-b] [-w] [-f] [-c <command>]|[-l <lua_script_file>]|[-s <cmd_script_file>] [-i] [-d <0|1|2>] " , exec_name ) ;
PrintAndLogEx ( NORMAL , " %s [-p] <port> --flash [--unlock-bootloader] [--image <imagefile>]+ [-w] [-f] [-d <0|1|2>] " , exec_name ) ;
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
if ( showFullHelp ) {
2019-09-10 02:45:10 +08:00
PrintAndLogEx ( NORMAL , " \n Common options: " ) ;
2019-04-14 18:54:13 +08:00
PrintAndLogEx ( NORMAL , " -h/--help this help " ) ;
2019-09-10 02:45:10 +08:00
PrintAndLogEx ( NORMAL , " -v/--version print client version " ) ;
2019-04-14 18:54:13 +08:00
PrintAndLogEx ( NORMAL , " -p/--port serial port to connect to " ) ;
PrintAndLogEx ( NORMAL , " -w/--wait 20sec waiting the serial port to appear in the OS " ) ;
PrintAndLogEx ( NORMAL , " -f/--flush output will be flushed after every print " ) ;
2019-09-10 02:45:10 +08:00
PrintAndLogEx ( NORMAL , " -d/--debug <0|1|2> set debugmode " ) ;
PrintAndLogEx ( NORMAL , " \n Options in client mode: " ) ;
PrintAndLogEx ( NORMAL , " -t/--text dump all interactive command's help at once " ) ;
PrintAndLogEx ( NORMAL , " -m/--markdown dump all interactive help at once in markdown syntax " ) ;
PrintAndLogEx ( NORMAL , " -b/--baud serial port speed (only needed for physical UART, not for USB-CDC or BT) " ) ;
2019-05-19 00:02:30 +08:00
PrintAndLogEx ( NORMAL , " -c/--command <command> execute one Proxmark3 command (or several separated by ';'). " ) ;
2019-04-14 18:54:13 +08:00
PrintAndLogEx ( NORMAL , " -l/--lua <lua script file> execute lua script. " ) ;
2019-05-19 00:02:30 +08:00
PrintAndLogEx ( NORMAL , " -s/--script-file <cmd_script_file> script file with one Proxmark3 command per line " ) ;
2019-08-04 21:34:18 +08:00
PrintAndLogEx ( NORMAL , " -i/--interactive enter interactive mode after executing the script or the command " ) ;
2020-10-08 15:52:33 +08:00
PrintAndLogEx ( NORMAL , " --incognito do not use history, prefs file nor log files " ) ;
2019-09-09 07:07:46 +08:00
PrintAndLogEx ( NORMAL , " \n Options in flasher mode: " ) ;
PrintAndLogEx ( NORMAL , " --flash flash Proxmark3, requires at least one --image " ) ;
PrintAndLogEx ( NORMAL , " --unlock-bootloader Enable flashing of bootloader area *DANGEROUS* (need --flash or --flash-info) " ) ;
PrintAndLogEx ( NORMAL , " --image <imagefile> image to flash. Can be specified several times. " ) ;
PrintAndLogEx ( NORMAL , " \n Examples: " ) ;
PrintAndLogEx ( NORMAL , " \n to run Proxmark3 client: \n " ) ;
PrintAndLogEx ( NORMAL , " %s " SERIAL_PORT_EXAMPLE_H " -- runs the pm3 client " , exec_name ) ;
PrintAndLogEx ( NORMAL , " %s " SERIAL_PORT_EXAMPLE_H " -f -- flush output everytime " , exec_name ) ;
PrintAndLogEx ( NORMAL , " %s " SERIAL_PORT_EXAMPLE_H " -w -- wait for serial port " , exec_name ) ;
PrintAndLogEx ( NORMAL , " %s -- runs the pm3 client in OFFLINE mode " , exec_name ) ;
PrintAndLogEx ( NORMAL , " \n to execute different commands from terminal: \n " ) ;
2021-02-14 10:03:57 +08:00
PrintAndLogEx ( NORMAL , " %s " SERIAL_PORT_EXAMPLE_H " -c \" hf mf chk --1k \" -- execute cmd and quit client " , exec_name ) ;
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( NORMAL , " %s " SERIAL_PORT_EXAMPLE_H " -l hf_read -- execute lua script " _YELLOW_ ( " `hf_read` " ) " and quit client " , exec_name ) ;
2019-09-09 07:07:46 +08:00
PrintAndLogEx ( NORMAL , " %s " SERIAL_PORT_EXAMPLE_H " -s mycmds.txt -- execute each pm3 cmd in file and quit client " , exec_name ) ;
PrintAndLogEx ( NORMAL , " \n to flash fullimage and bootloader: \n " ) ;
PrintAndLogEx ( NORMAL , " %s " SERIAL_PORT_EXAMPLE_H " --flash --unlock-bootloader --image bootrom.elf --image fullimage.elf " , exec_name ) ;
# ifdef __linux__
2019-09-13 22:32:37 +08:00
PrintAndLogEx ( NORMAL , " \n Note (Linux): \n if the flasher gets stuck in 'Waiting for Proxmark3 to reappear on <DEVICE>', " ) ;
PrintAndLogEx ( NORMAL , " you need to blacklist Proxmark3 for modem-manager - see documentation for more details: " ) ;
PrintAndLogEx ( NORMAL , " * https://github.com/RfidResearchGroup/proxmark3/blob/master/doc/md/Installation_Instructions/ModemManager-Must-Be-Discarded.md " ) ;
PrintAndLogEx ( NORMAL , " \n More info on flashing procedure from the official Proxmark3 wiki: " ) ;
PrintAndLogEx ( NORMAL , " * https://github.com/Proxmark/proxmark3/wiki/Gentoo%%20Linux " ) ;
PrintAndLogEx ( NORMAL , " * https://github.com/Proxmark/proxmark3/wiki/Ubuntu%%20Linux " ) ;
PrintAndLogEx ( NORMAL , " * https://github.com/Proxmark/proxmark3/wiki/OSX \n " ) ;
2019-09-09 07:07:46 +08:00
# endif
}
}
static int flash_pm3 ( char * serial_port_name , uint8_t num_files , char * filenames [ FLASH_MAX_FILES ] , bool can_write_bl ) {
int ret = PM3_EUNDEF ;
flash_file_t files [ FLASH_MAX_FILES ] ;
memset ( files , 0 , sizeof ( files ) ) ;
2019-10-06 07:18:04 +08:00
char * filepaths [ FLASH_MAX_FILES ] = { 0 } ;
2019-09-09 07:07:46 +08:00
if ( serial_port_name = = NULL ) {
PrintAndLogEx ( ERR , " You must specify a port. \n " ) ;
return PM3_EINVARG ;
}
2019-09-10 01:55:27 +08:00
for ( int i = 0 ; i < num_files ; + + i ) {
char * path ;
ret = searchFile ( & path , FIRMWARES_SUBDIR , filenames [ i ] , " .elf " , true ) ;
if ( ret ! = PM3_SUCCESS ) {
ret = searchFile ( & path , BOOTROM_SUBDIR , filenames [ i ] , " .elf " , true ) ;
}
if ( ret ! = PM3_SUCCESS ) {
// Last try, let the error msg be displayed if not found
ret = searchFile ( & path , FULLIMAGE_SUBDIR , filenames [ i ] , " .elf " , false ) ;
}
if ( ret ! = PM3_SUCCESS ) {
goto finish2 ;
}
filepaths [ i ] = path ;
}
PrintAndLogEx ( SUCCESS , " About to use the following file%s: " , num_files > 1 ? " s " : " " ) ;
for ( int i = 0 ; i < num_files ; + + i ) {
2020-05-08 22:43:31 +08:00
PrintAndLogEx ( SUCCESS , " " _YELLOW_ ( " %s " ) , filepaths [ i ] ) ;
2019-09-10 01:55:27 +08:00
}
2020-05-28 08:13:21 +08:00
if ( OpenProxmark ( & session . current_device , serial_port_name , true , 60 , true , FLASHMODE_SPEED ) ) {
2020-05-08 22:43:31 +08:00
PrintAndLogEx ( NORMAL , _GREEN_ ( " found " ) ) ;
2019-09-09 07:07:46 +08:00
} else {
PrintAndLogEx ( ERR , " Could not find Proxmark3 on " _RED_ ( " %s " ) " . \n " , serial_port_name ) ;
2019-09-10 01:55:27 +08:00
ret = PM3_ETIMEOUT ;
goto finish2 ;
2019-09-09 07:07:46 +08:00
}
uint32_t max_allowed = 0 ;
ret = flash_start_flashing ( can_write_bl , serial_port_name , & max_allowed ) ;
if ( ret ! = PM3_SUCCESS ) {
goto finish ;
}
if ( num_files = = 0 )
goto finish ;
for ( int i = 0 ; i < num_files ; + + i ) {
2019-09-10 01:55:27 +08:00
ret = flash_load ( & files [ i ] , filepaths [ i ] , can_write_bl , max_allowed * ONE_KB ) ;
2019-09-09 07:07:46 +08:00
if ( ret ! = PM3_SUCCESS ) {
goto finish ;
}
PrintAndLogEx ( NORMAL , " " ) ;
2019-03-10 06:35:06 +08:00
}
2019-09-09 07:07:46 +08:00
2020-05-08 22:43:31 +08:00
PrintAndLogEx ( SUCCESS , _CYAN_ ( " Flashing... " ) ) ;
2019-09-09 07:07:46 +08:00
for ( int i = 0 ; i < num_files ; i + + ) {
ret = flash_write ( & files [ i ] ) ;
if ( ret ! = PM3_SUCCESS ) {
goto finish ;
}
flash_free ( & files [ i ] ) ;
2020-05-08 22:43:31 +08:00
PrintAndLogEx ( NORMAL , " " ) ;
2019-09-09 07:07:46 +08:00
}
finish :
ret = flash_stop_flashing ( ) ;
2020-05-28 08:13:21 +08:00
CloseProxmark ( session . current_device ) ;
2019-09-10 01:55:27 +08:00
finish2 :
for ( int i = 0 ; i < num_files ; + + i ) {
if ( filepaths [ i ] ! = NULL )
free ( filepaths [ i ] ) ;
}
2019-09-09 07:07:46 +08:00
if ( ret = = PM3_SUCCESS )
2020-05-08 22:43:31 +08:00
PrintAndLogEx ( SUCCESS , _CYAN_ ( " All done " ) ) ;
2019-09-09 07:07:46 +08:00
else
2020-05-08 22:43:31 +08:00
PrintAndLogEx ( ERR , " Aborted on error " ) ;
2019-09-09 07:07:46 +08:00
PrintAndLogEx ( NORMAL , " \n Have a nice day! " ) ;
return ret ;
2017-10-21 02:39:57 +08:00
}
2020-05-28 08:13:21 +08:00
# endif //LIBPM3
2017-10-21 02:39:57 +08:00
2020-06-13 00:21:03 +08:00
# if defined(_WIN32)
2019-10-16 20:46:57 +08:00
static bool DetectWindowsAnsiSupport ( void ) {
2020-07-08 17:09:20 +08:00
# ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
# define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
# endif
2020-06-24 17:51:00 +08:00
HANDLE hOut = GetStdHandle ( STD_OUTPUT_HANDLE ) ;
DWORD dwMode = 0 ;
GetConsoleMode ( hOut , & dwMode ) ;
dwMode | = ENABLE_VIRTUAL_TERMINAL_PROCESSING ;
2020-08-31 20:41:40 +08:00
return SetConsoleMode ( hOut , dwMode ) ? true : false ;
2019-10-16 20:46:57 +08:00
}
2020-05-28 08:13:21 +08:00
# endif //_WIN32
2020-04-10 17:51:08 +08:00
2020-05-28 08:13:21 +08:00
void pm3_init ( void ) {
2019-03-10 06:35:06 +08:00
srand ( time ( 0 ) ) ;
2019-03-09 15:59:13 +08:00
2019-05-01 05:52:40 +08:00
session . pm3_present = false ;
2019-05-02 02:48:15 +08:00
session . help_dump_mode = false ;
2020-10-07 00:11:45 +08:00
session . incognito = false ;
2020-05-28 08:13:21 +08:00
session . supports_colors = false ;
2021-01-09 21:00:58 +08:00
session . emoji_mode = EMO_ALTTEXT ;
2020-05-28 08:13:21 +08:00
session . stdinOnTTY = false ;
session . stdoutOnTTY = false ;
// set global variables soon enough to get the log path
set_my_executable_path ( ) ;
set_my_user_directory ( ) ;
}
# ifndef LIBPM3
int main ( int argc , char * argv [ ] ) {
pm3_init ( ) ;
2019-03-10 06:35:06 +08:00
bool waitCOMPort = false ;
bool addLuaExec = false ;
2019-08-04 21:34:18 +08:00
bool stayInCommandLoop = false ;
2019-03-10 06:35:06 +08:00
char * script_cmds_file = NULL ;
char * script_cmd = NULL ;
2019-04-03 04:06:10 +08:00
char * port = NULL ;
uint32_t speed = 0 ;
2018-03-17 21:35:34 +08:00
2020-06-09 04:15:47 +08:00
# ifdef HAVE_READLINE
2019-03-10 07:00:59 +08:00
/* initialize history */
2019-03-10 06:35:06 +08:00
using_history ( ) ;
2018-11-03 01:27:42 +08:00
2018-11-03 18:10:55 +08:00
# ifdef RL_STATE_READCMD
2019-03-10 06:35:06 +08:00
rl_extend_line_buffer ( 1024 ) ;
2020-06-09 04:15:47 +08:00
# endif // RL_STATE_READCMD
# endif // HAVE_READLINE
2019-03-09 15:59:13 +08:00
2019-04-14 19:35:52 +08:00
char * exec_name = argv [ 0 ] ;
2019-04-13 19:34:02 +08:00
# if defined(_WIN32)
2019-04-14 19:35:52 +08:00
for ( int m = strlen ( exec_name ) ; m > 0 ; m - - ) {
2019-04-14 19:37:53 +08:00
if ( exec_name [ m ] = = ' \\ ' ) {
2019-04-14 19:35:52 +08:00
exec_name + = ( + + m ) ;
2019-04-14 18:54:13 +08:00
break ;
2019-04-13 19:34:02 +08:00
}
2019-03-10 06:35:06 +08:00
}
2019-04-14 18:54:13 +08:00
# endif
2019-03-10 06:35:06 +08:00
2019-09-09 07:07:46 +08:00
bool flash_mode = false ;
bool flash_can_write_bl = false ;
2020-05-22 19:59:30 +08:00
bool debug_mode_forced = false ;
2019-09-09 07:07:46 +08:00
int flash_num_files = 0 ;
char * flash_filenames [ FLASH_MAX_FILES ] ;
2020-06-13 01:45:18 +08:00
// color management:
// 1. default = no color
// 2. enable colors if OS seems to support colors and if stdin/stdout aren't redirected
// 3. load prefs if available, overwrite colors choice if needed
// 4. disable colors anyway if stdin/stdout are redirected
//
// For info, grep --color=auto is doing sth like this, plus test getenv("TERM") != "dumb":
// struct stat tmp_stat;
// if ((fstat (STDOUT_FILENO, &tmp_stat) == 0) && (S_ISCHR (tmp_stat.st_mode)) && isatty(STDIN_FILENO))
session . stdinOnTTY = isatty ( STDIN_FILENO ) ;
session . stdoutOnTTY = isatty ( STDOUT_FILENO ) ;
session . supports_colors = false ;
2021-01-09 21:00:58 +08:00
session . emoji_mode = EMO_ALTTEXT ;
2020-06-13 01:45:18 +08:00
if ( session . stdinOnTTY & & session . stdoutOnTTY ) {
# if defined(__linux__) || defined(__APPLE__)
session . supports_colors = true ;
2021-01-09 21:00:58 +08:00
session . emoji_mode = EMO_EMOJI ;
2020-06-13 01:45:18 +08:00
# elif defined(_WIN32)
session . supports_colors = DetectWindowsAnsiSupport ( ) ;
2021-01-09 21:00:58 +08:00
session . emoji_mode = EMO_ALTTEXT ;
2020-06-13 01:45:18 +08:00
# endif
}
2019-04-14 19:37:53 +08:00
for ( int i = 1 ; i < argc ; i + + ) {
2019-03-10 06:35:06 +08:00
2019-04-14 18:54:13 +08:00
if ( argv [ i ] [ 0 ] ! = ' - ' ) {
// For backward compatibility we accept direct port
if ( port ! = NULL ) {
// We got already one
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " cannot parse command line. We got " _YELLOW_ ( " %s " ) " as port and now we got also: " _YELLOW_ ( " %s " ) " \n " , port , argv [ i ] ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
}
port = argv [ i ] ;
continue ;
}
// port
if ( strcmp ( argv [ i ] , " -p " ) = = 0 | | strcmp ( argv [ i ] , " --port " ) = = 0 ) {
if ( i + 1 = = argc ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " missing port specification after -p \n " ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
}
if ( port ! = NULL ) {
// We got already one
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " cannot parse command line. We got " _YELLOW_ ( " %s " ) " as port and now we got also: " _YELLOW_ ( " %s " ) " \n " , port , argv [ i + 1 ] ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
}
port = argv [ + + i ] ;
continue ;
}
// short help
if ( strcmp ( argv [ i ] , " -h " ) = = 0 | | strcmp ( argv [ i ] , " --help " ) = = 0 ) {
2019-09-10 03:30:25 +08:00
g_printAndLog = PRINTANDLOG_PRINT ;
2019-04-14 19:35:52 +08:00
show_help ( true , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 0 ;
}
// dump help
if ( strcmp ( argv [ i ] , " -t " ) = = 0 | | strcmp ( argv [ i ] , " --text " ) = = 0 ) {
2019-09-10 03:30:25 +08:00
g_printAndLog = PRINTANDLOG_PRINT ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-03-10 06:35:06 +08:00
dumpAllHelp ( 0 ) ;
return 0 ;
}
// dump markup
2019-04-14 18:54:13 +08:00
if ( strcmp ( argv [ i ] , " -m " ) = = 0 | | strcmp ( argv [ i ] , " --markdown " ) = = 0 ) {
2019-09-10 03:30:25 +08:00
g_printAndLog = PRINTANDLOG_PRINT ;
2019-03-10 06:35:06 +08:00
dumpAllHelp ( 1 ) ;
return 0 ;
}
2019-09-10 02:45:10 +08:00
// print client version
2019-08-21 18:52:59 +08:00
if ( strcmp ( argv [ i ] , " -v " ) = = 0 | | strcmp ( argv [ i ] , " --version " ) = = 0 ) {
pm3_version ( true , true ) ;
return 0 ;
}
2019-09-10 02:45:10 +08:00
// set debugmode
if ( strcmp ( argv [ i ] , " -d " ) = = 0 | | strcmp ( argv [ i ] , " --debug " ) = = 0 ) {
if ( i + 1 = = argc ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " missing debugmode specification after -d \n " ) ;
2019-09-10 02:45:10 +08:00
show_help ( false , exec_name ) ;
return 1 ;
}
int demod = atoi ( argv [ i + 1 ] ) ;
if ( demod < 0 | | demod > 2 ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " invalid debugmode: -d " _YELLOW_ ( " %s " ) " \n " , argv [ i + 1 ] ) ;
2019-09-10 02:45:10 +08:00
return 1 ;
}
g_debugMode = demod ;
2020-05-22 19:59:30 +08:00
debug_mode_forced = true ;
2019-09-10 02:45:10 +08:00
i + + ;
continue ;
}
2019-03-10 06:35:06 +08:00
// flush output
2019-04-14 18:54:13 +08:00
if ( strcmp ( argv [ i ] , " -f " ) = = 0 | | strcmp ( argv [ i ] , " --flush " ) = = 0 ) {
2019-03-10 06:35:06 +08:00
SetFlushAfterWrite ( true ) ;
PrintAndLogEx ( INFO , " Output will be flushed after every print. \n " ) ;
2019-04-03 04:06:10 +08:00
continue ;
}
// set baudrate
2019-04-14 18:54:13 +08:00
if ( strcmp ( argv [ i ] , " -b " ) = = 0 | | strcmp ( argv [ i ] , " --baud " ) = = 0 ) {
if ( i + 1 = = argc ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " missing baud specification after -b \n " ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
}
2019-07-11 00:46:30 +08:00
uint64_t tmpspeed = strtoul ( argv [ i + 1 ] , NULL , 10 ) ;
2019-04-03 04:06:10 +08:00
if ( ( tmpspeed = = ULONG_MAX ) | | ( tmpspeed = = 0 ) ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " invalid baudrate: -b " _YELLOW_ ( " %s " ) " \n " , argv [ i + 1 ] ) ;
2019-04-03 04:06:10 +08:00
return 1 ;
}
speed = tmpspeed ;
i + + ;
continue ;
2019-03-10 06:35:06 +08:00
}
// wait for comport
2019-04-14 18:54:13 +08:00
if ( strcmp ( argv [ i ] , " -w " ) = = 0 | | strcmp ( argv [ i ] , " --wait " ) = = 0 ) {
2019-03-10 06:35:06 +08:00
waitCOMPort = true ;
2019-04-03 04:06:10 +08:00
continue ;
2019-03-10 06:35:06 +08:00
}
// execute pm3 command
2019-04-14 18:54:13 +08:00
if ( strcmp ( argv [ i ] , " -c " ) = = 0 | | strcmp ( argv [ i ] , " --command " ) = = 0 ) {
if ( i + 1 = = argc ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " missing command specification after -c \n " ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
}
script_cmd = argv [ + + i ] ;
2019-04-03 04:06:10 +08:00
continue ;
2019-03-10 06:35:06 +08:00
}
2019-05-06 20:11:23 +08:00
// execute pm3 command file
2019-04-14 18:54:13 +08:00
if ( strcmp ( argv [ i ] , " -s " ) = = 0 | | strcmp ( argv [ i ] , " --script-file " ) = = 0 ) {
2020-11-13 23:26:46 +08:00
if ( i + 1 = = argc | | strlen ( argv [ i + 1 ] ) = = 0 ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " missing script file specification after -s \n " ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
}
script_cmds_file = argv [ + + i ] ;
2019-04-03 04:06:10 +08:00
continue ;
}
2019-04-14 18:54:13 +08:00
// execute lua script
if ( strcmp ( argv [ i ] , " -l " ) = = 0 | | strcmp ( argv [ i ] , " --lua " ) = = 0 ) {
addLuaExec = true ;
2020-11-13 23:26:46 +08:00
if ( i + 1 = = argc | | strlen ( argv [ i + 1 ] ) = = 0 ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " missing lua script specification after -l \n " ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
}
script_cmd = argv [ + + i ] ;
continue ;
2019-04-03 04:06:10 +08:00
}
2019-08-04 21:34:18 +08:00
// go to interactive instead of quitting after a script/command
2019-08-04 22:57:06 +08:00
if ( strcmp ( argv [ i ] , " -i " ) = = 0 | | strcmp ( argv [ i ] , " --interactive " ) = = 0 ) {
2019-08-04 21:34:18 +08:00
stayInCommandLoop = true ;
continue ;
}
2020-10-07 00:11:45 +08:00
// do not use history nor log files
if ( strcmp ( argv [ i ] , " --incognito " ) = = 0 ) {
session . incognito = true ;
continue ;
}
2019-09-09 07:07:46 +08:00
// go to flash mode
if ( strcmp ( argv [ i ] , " --flash " ) = = 0 ) {
flash_mode = true ;
continue ;
}
// unlock bootloader area
if ( strcmp ( argv [ i ] , " --unlock-bootloader " ) = = 0 ) {
flash_can_write_bl = true ;
continue ;
}
// flash file
if ( strcmp ( argv [ i ] , " --image " ) = = 0 ) {
if ( flash_num_files = = FLASH_MAX_FILES ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " too many --image, please use it max %i times \n " , FLASH_MAX_FILES ) ;
2019-09-09 07:07:46 +08:00
return 1 ;
}
if ( i + 1 = = argc ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " missing image specification after --image \n " ) ;
2019-09-09 07:07:46 +08:00
show_help ( false , exec_name ) ;
return 1 ;
}
flash_filenames [ flash_num_files + + ] = argv [ + + i ] ;
continue ;
}
2019-04-14 18:54:13 +08:00
// We got an unknown parameter
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " invalid parameter: " _YELLOW_ ( " %s " ) " \n " , argv [ i ] ) ;
2019-04-14 19:35:52 +08:00
show_help ( false , exec_name ) ;
2019-04-14 18:54:13 +08:00
return 1 ;
2019-03-10 06:35:06 +08:00
}
2020-05-22 19:59:30 +08:00
// Load Settings and assign
// This will allow the command line to override the settings.json values
preferences_load ( ) ;
// quick patch for debug level
if ( ! debug_mode_forced )
g_debugMode = session . client_debug_level ;
// settings_save ();
// End Settings
2019-10-05 12:09:46 +08:00
2020-06-13 01:45:18 +08:00
// even if prefs, we disable colors if stdin or stdout is not a TTY
if ( ( ! session . stdinOnTTY ) | | ( ! session . stdoutOnTTY ) ) {
session . supports_colors = false ;
2021-01-09 21:00:58 +08:00
session . emoji_mode = EMO_ALTTEXT ;
2020-04-16 15:01:14 +08:00
}
2020-04-12 17:49:17 +08:00
2019-04-29 04:51:40 +08:00
// Let's take a baudrate ok for real UART, USB-CDC & BT don't use that info anyway
2019-04-03 04:06:10 +08:00
if ( speed = = 0 )
2019-04-21 01:17:32 +08:00
speed = USART_BAUD_RATE ;
2019-04-03 04:06:10 +08:00
2019-09-09 07:07:46 +08:00
if ( flash_mode ) {
flash_pm3 ( port , flash_num_files , flash_filenames , flash_can_write_bl ) ;
exit ( EXIT_SUCCESS ) ;
}
2019-04-14 18:54:13 +08:00
if ( script_cmd ) {
while ( script_cmd [ strlen ( script_cmd ) - 1 ] = = ' ' )
script_cmd [ strlen ( script_cmd ) - 1 ] = 0x00 ;
2019-03-10 06:35:06 +08:00
2019-04-14 18:54:13 +08:00
if ( strlen ( script_cmd ) = = 0 ) {
script_cmd = NULL ;
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " execute command: " _YELLOW_ ( " command not found " ) " . \n " ) ;
2019-04-14 18:54:13 +08:00
return 2 ;
} else {
if ( addLuaExec ) {
// add "script run " to command
int len = strlen ( script_cmd ) + 11 + 1 ;
char * ctmp = ( char * ) calloc ( len , sizeof ( uint8_t ) ) ;
if ( ctmp ! = NULL ) {
memset ( ctmp , 0 , len ) ;
strcpy ( ctmp , " script run " ) ;
strcpy ( & ctmp [ 11 ] , script_cmd ) ;
script_cmd = ctmp ;
2019-03-10 06:35:06 +08:00
}
}
2019-04-16 23:29:19 +08:00
PrintAndLogEx ( SUCCESS , " execute command from commandline: " _YELLOW_ ( " %s " ) " \n " , script_cmd ) ;
2019-04-14 18:54:13 +08:00
}
2019-03-10 06:35:06 +08:00
}
2017-10-22 17:05:25 +08:00
2019-03-10 06:35:06 +08:00
// try to open USB connection to Proxmark
2019-05-07 23:31:07 +08:00
if ( port ! = NULL ) {
2020-05-28 08:13:21 +08:00
OpenProxmark ( & session . current_device , port , waitCOMPort , 20 , false , speed ) ;
2019-05-07 23:31:07 +08:00
}
2019-04-14 18:54:13 +08:00
2020-05-28 08:13:21 +08:00
if ( session . pm3_present & & ( TestProxmark ( session . current_device ) ! = PM3_SUCCESS ) ) {
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( ERR , _RED_ ( " ERROR: " ) " cannot communicate with the Proxmark \n " ) ;
2020-05-28 08:13:21 +08:00
CloseProxmark ( session . current_device ) ;
2019-04-27 08:46:20 +08:00
}
2019-05-06 04:04:35 +08:00
2019-07-18 02:15:47 +08:00
if ( ( port ! = NULL ) & & ( ! session . pm3_present ) )
exit ( EXIT_FAILURE ) ;
2019-05-01 05:52:40 +08:00
if ( ! session . pm3_present )
2020-04-22 08:22:55 +08:00
PrintAndLogEx ( INFO , " Running in " _YELLOW_ ( " OFFLINE " ) " mode. Check " _YELLOW_ ( " \" %s -h \" " ) " if it's not what you want. \n " , exec_name ) ;
Client cleanup and restructuring. Stage 1...
Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.
The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P
The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.
Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)
client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.
client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.
client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.
client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.
include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.
common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.
armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.
common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
2020-01-05 02:59:36 +08:00
// ascii art only in interactive client
if ( ! script_cmds_file & & ! script_cmd & & session . stdinOnTTY & & session . stdoutOnTTY & & ! flash_mode )
showBanner ( ) ;
2020-04-12 18:24:56 +08:00
// Save settings if not loaded from settings json file.
2020-04-10 17:51:08 +08:00
// Doing this here will ensure other checks and updates are saved to over rule default
// e.g. Linux color use check
2020-10-08 15:50:17 +08:00
if ( ( ! session . preferences_loaded ) & & ( ! session . incognito ) ) {
2020-04-26 17:18:04 +08:00
PrintAndLogEx ( INFO , " Creating initial preferences file " ) ; // json save reports file name, so just info msg here
2020-04-16 15:01:14 +08:00
preferences_save ( ) ; // Save defaults
2020-04-12 17:49:17 +08:00
session . preferences_loaded = true ;
2020-04-24 14:56:35 +08:00
} /* else {
2020-04-17 17:29:33 +08:00
// Set device debug level
PrintAndLogEx ( INFO , " setting device debug loglevel " ) ;
if ( session . pm3_present ) {
SendCommandNG ( CMD_SET_DBGMODE , & session . device_debug_level , 1 ) ;
PacketResponseNG resp ;
if ( WaitForResponseTimeout ( CMD_SET_DBGMODE , & resp , 2000 ) = = false )
PrintAndLogEx ( INFO , " failed to set device debug loglevel " ) ;
}
else
PrintAndLogEx ( WARNING , " Proxmark3 not ready to set debug level " ) ;
2020-04-12 17:49:17 +08:00
}
2020-04-24 14:56:35 +08:00
*/
2020-04-10 17:51:08 +08:00
2017-07-28 03:32:15 +08:00
# ifdef HAVE_GUI
2017-08-27 14:50:55 +08:00
2020-06-30 04:23:46 +08:00
# if defined(_WIN32)
2019-08-04 21:34:18 +08:00
InitGraphics ( argc , argv , script_cmds_file , script_cmd , stayInCommandLoop ) ;
2019-03-10 06:35:06 +08:00
MainGraphics ( ) ;
2017-08-27 14:50:55 +08:00
# else
2020-10-23 07:24:54 +08:00
// for *nix distro's, check environment variable to verify a display
2019-03-10 07:00:59 +08:00
char * display = getenv ( " DISPLAY " ) ;
2019-03-10 06:35:06 +08:00
if ( display & & strlen ( display ) > 1 ) {
2019-08-04 21:34:18 +08:00
InitGraphics ( argc , argv , script_cmds_file , script_cmd , stayInCommandLoop ) ;
2019-03-10 06:35:06 +08:00
MainGraphics ( ) ;
} else {
2019-08-04 21:34:18 +08:00
main_loop ( script_cmds_file , script_cmd , stayInCommandLoop ) ;
2019-03-10 06:35:06 +08:00
}
2017-08-27 14:50:55 +08:00
# endif
2019-03-09 15:59:13 +08:00
2017-07-28 03:32:15 +08:00
# else
2019-08-04 21:34:18 +08:00
main_loop ( script_cmds_file , script_cmd , stayInCommandLoop ) ;
2019-03-09 15:59:13 +08:00
# endif
2019-03-10 06:35:06 +08:00
// Clean up the port
2019-05-01 05:52:40 +08:00
if ( session . pm3_present ) {
2020-05-28 08:13:21 +08:00
CloseProxmark ( session . current_device ) ;
2019-03-10 06:35:06 +08:00
}
2019-03-09 15:59:13 +08:00
2020-04-13 14:17:57 +08:00
if ( session . window_changed ) // Plot/Overlay moved or resized
2020-04-16 15:01:14 +08:00
preferences_save ( ) ;
2019-07-18 02:15:47 +08:00
exit ( EXIT_SUCCESS ) ;
2019-03-06 04:14:30 +08:00
}
2020-05-28 08:13:21 +08:00
# endif //LIBPM3