Provide subshell command ! in the terminal

Needs to have allow_subshells = yes; in ~/.avrduderc. Then subshell
commands can be executed, eg,

$ avrdude -t

avrdude> !ls
myapplication.hex    myapplication.eep

avrdude> !avrdude -pm328p/St | grep efuse.initval
.ptmm   ATmega328P      efuse   initval 0xff
This commit is contained in:
Stefan Rueger
2023-06-12 16:24:20 +01:00
parent f0da9a6c44
commit 64a4bb18bd
9 changed files with 41 additions and 5 deletions

View File

@@ -421,6 +421,7 @@ default_serial = "@DEFAULT_SER_PORT@";
default_spi = "@DEFAULT_SPI_PORT@";
# default_bitclock = 2.5;
default_linuxgpio = "@DEFAULT_LINUXGPIO_PORT@";
allow_subshells = no;
@HAVE_PARPORT_BEGIN@

View File

@@ -41,6 +41,7 @@ const char *default_serial;
const char *default_spi;
double default_bitclock;
char const *default_linuxgpio;
int allow_subshells;
LISTID string_list;
LISTID number_list;

View File

@@ -73,6 +73,7 @@ static int pin_name;
%token K_PAGE_SIZE
%token K_ALIAS
%token K_ALLOW_SUBSHELLS
%token K_BUFF
%token K_CONNTYPE
%token K_DEDICATED
@@ -233,6 +234,11 @@ def :
free_token($3);
} |
K_ALLOW_SUBSHELLS TKN_EQUAL numexpr TKN_SEMI {
allow_subshells = $3->value.number;
free_token($3);
} |
K_DEFAULT_LINUXGPIO TKN_EQUAL TKN_STRING TKN_SEMI {
default_linuxgpio = cache_string($3->value.string);
free_token($3);

View File

@@ -905,6 +905,7 @@ void dev_output_pgm_part(int dev_opt_c, const char *programmer, int dev_opt_p, c
dev_info("default_spi = %s;\n", p = cfg_escape(default_spi)); free(p);
dev_info("default_bitclock = %7.5f;\n", default_bitclock);
dev_info("default_linuxgpio = %s;\n", p = cfg_escape(default_linuxgpio)); free(p);
dev_info("allow_subshells = %s;\n", allow_subshells? "yes": "no");
dev_info("\n#\n# PROGRAMMER DEFINITIONS\n#\n\n");
}

View File

@@ -2701,6 +2701,15 @@ option.
Assign the default bitclock value. Can be overridden using the @option{-B}
option.
@item allow_subshells = @var{no};
Whether or not AVRDUDE's interactive terminal is allowed to use subshell
@code{!} commands. This defaults to no for security reasons, eg, in the
rare case @code{avrdude -t} is set up with attached hardware to provide a
web service, remote ssh or a login on a PC instead of a shell, say, for
demo or training purposes. In almost all other cases this can be
overridden in the personal @code{avrddude.rc} or @code{.avrduderc}
configuration file with @var{yes}.
@end table

View File

@@ -179,6 +179,7 @@ INF [Ii][Nn][Ff]([Ii][Nn][Ii][Tt][Yy])?
}
alias { yylval=NULL; return K_ALIAS; }
allow_subshells { yylval=NULL; return K_ALLOW_SUBSHELLS; }
allowfullpagebitstream { yylval=NULL; ccap(); return K_ALLOWFULLPAGEBITSTREAM; }
buff { yylval=NULL; ccap(); return K_BUFF; }
chip_erase { yylval=new_token(K_CHIP_ERASE); ccap(); return K_CHIP_ERASE; }

View File

@@ -1136,14 +1136,15 @@ void walk_programmer_types(/*LISTID programmer_types,*/ walk_programmer_types_cb
/* formerly config.h */
extern LISTID part_list;
extern LISTID programmers;
extern LISTID part_list;
extern LISTID programmers;
extern const char *default_programmer;
extern const char *default_parallel;
extern const char *default_serial;
extern const char *default_spi;
extern double default_bitclock;
extern char const * default_linuxgpio;
extern double default_bitclock;
extern char const *default_linuxgpio;
extern int allow_subshells;
/* This name is fixed, it's only here for symmetry with
* default_parallel and default_serial. */

View File

@@ -573,6 +573,7 @@ int main(int argc, char * argv [])
default_spi = "";
default_bitclock = 0.0;
default_linuxgpio = "";
allow_subshells = 0;
init_config();

View File

@@ -1675,7 +1675,7 @@ static int cmd_help(const PROGRAMMER *pgm, const AVRPART *p, int argc, char *arg
term_out(cmd[i].desc, cmd[i].name);
term_out("\n");
}
term_out("\n"
term_out(" !<scmd> : run the command <scmd> in a subshell, eg, !ls\n\n"
"For more details about a terminal command cmd type cmd -?\n\n"
"Note that not all programmer derivatives support all commands. Flash and\n"
"EEPROM type memories are normally read and written using a cache via paged\n"
@@ -1896,6 +1896,21 @@ static int process_line(char *q, const PROGRAMMER *pgm, const AVRPART *p) {
if (!*q || (*q == '#'))
return 0;
if(*q == '!') {
if(allow_subshells) {
while(*++q && isspace((unsigned char) *q))
continue;
errno = 0;
int shret = *q? system(q): 0;
if(errno)
pmsg_warning("system() call returned %d: %s\n", shret, strerror(errno));
} else {
pmsg_warning("subshell commands are by default not allowed in the terminal\n");
imsg_warning("allow_subshells = yes; in avrdude.rc or ~/.avrduderc changes this\n");
}
return 0;
}
// Tokenize command line
do {
argc = 0; argv = NULL;