11//! File Systems related commands for Neotron OS
22
3- use embedded_sdmmc:: VolumeIdx ;
4-
53use crate :: { bios, osprint, osprintln, Ctx } ;
64
75pub static DIR_ITEM : menu:: Item < Ctx > = menu:: Item {
@@ -25,6 +23,18 @@ pub static LOAD_ITEM: menu::Item<Ctx> = menu::Item {
2523 help : Some ( "Load a file into the application area" ) ,
2624} ;
2725
26+ pub static EXEC_ITEM : menu:: Item < Ctx > = menu:: Item {
27+ item_type : menu:: ItemType :: Callback {
28+ function : exec,
29+ parameters : & [ menu:: Parameter :: Mandatory {
30+ parameter_name : "file" ,
31+ help : Some ( "The shell script to run" ) ,
32+ } ] ,
33+ } ,
34+ command : "exec" ,
35+ help : Some ( "Execute a shell script" ) ,
36+ } ;
37+
2838pub static TYPE_ITEM : menu:: Item < Ctx > = menu:: Item {
2939 item_type : menu:: ItemType :: Callback {
3040 function : typefn,
@@ -45,7 +55,7 @@ fn dir(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, _args: &[&str], _ctx: &
4555 let time = crate :: fs:: BiosTime ( ) ;
4656 let mut mgr = embedded_sdmmc:: VolumeManager :: new ( bios_block, time) ;
4757 // Open the first partition
48- let volume = mgr. open_volume ( VolumeIdx ( 0 ) ) ?;
58+ let volume = mgr. open_volume ( embedded_sdmmc :: VolumeIdx ( 0 ) ) ?;
4959 let root_dir = mgr. open_root_dir ( volume) ?;
5060 let mut total_bytes = 0u64 ;
5161 let mut num_files = 0 ;
@@ -112,14 +122,49 @@ fn load(_menu: &menu::Menu<Ctx>, _item: &menu::Item<Ctx>, args: &[&str], ctx: &m
112122 }
113123}
114124
125+ /// Called when the "exec" command is executed.
126+ fn exec ( _menu : & menu:: Menu < Ctx > , _item : & menu:: Item < Ctx > , args : & [ & str ] , ctx : & mut Ctx ) {
127+ fn work ( ctx : & mut Ctx , filename : & str ) -> Result < ( ) , embedded_sdmmc:: Error < bios:: Error > > {
128+ let bios_block = crate :: fs:: BiosBlock ( ) ;
129+ let time = crate :: fs:: BiosTime ( ) ;
130+ let mut mgr = embedded_sdmmc:: VolumeManager :: new ( bios_block, time) ;
131+ // Open the first partition
132+ let volume = mgr. open_volume ( embedded_sdmmc:: VolumeIdx ( 0 ) ) ?;
133+ let root_dir = mgr. open_root_dir ( volume) ?;
134+ let file = mgr. open_file_in_dir ( root_dir, filename, embedded_sdmmc:: Mode :: ReadOnly ) ?;
135+ let buffer = ctx. tpa . as_slice_u8 ( ) ;
136+ let count = mgr. read ( file, buffer) ?;
137+ if count != mgr. file_length ( file) ? as usize {
138+ osprintln ! ( "File too large! Max {} bytes allowed." , buffer. len( ) ) ;
139+ return Ok ( ( ) ) ;
140+ }
141+ let Ok ( s) = core:: str:: from_utf8 ( & buffer[ 0 ..count] ) else {
142+ osprintln ! ( "File is not valid UTF-8" ) ;
143+ return Ok ( ( ) ) ;
144+ } ;
145+ // tell the main loop to run from these bytes next
146+ ctx. exec_tpa = Some ( s. len ( ) ) ;
147+ Ok ( ( ) )
148+ }
149+
150+ // index can't panic - we always have enough args
151+ let r = work ( ctx, args[ 0 ] ) ;
152+ match r {
153+ Ok ( _) => { }
154+ Err ( e) => {
155+ osprintln ! ( "Error: {:?}" , e) ;
156+ }
157+ }
158+ }
159+
115160/// Called when the "type" command is executed.
116161fn typefn ( _menu : & menu:: Menu < Ctx > , _item : & menu:: Item < Ctx > , args : & [ & str ] , ctx : & mut Ctx ) {
117162 fn work ( ctx : & mut Ctx , filename : & str ) -> Result < ( ) , embedded_sdmmc:: Error < bios:: Error > > {
118163 let bios_block = crate :: fs:: BiosBlock ( ) ;
119164 let time = crate :: fs:: BiosTime ( ) ;
120165 let mut mgr = embedded_sdmmc:: VolumeManager :: new ( bios_block, time) ;
121166 // Open the first partition
122- let volume = mgr. open_volume ( VolumeIdx ( 0 ) ) ?;
167+ let volume = mgr. open_volume ( embedded_sdmmc :: VolumeIdx ( 0 ) ) ?;
123168 let root_dir = mgr. open_root_dir ( volume) ?;
124169 let file = mgr. open_file_in_dir ( root_dir, filename, embedded_sdmmc:: Mode :: ReadOnly ) ?;
125170 let buffer = ctx. tpa . as_slice_u8 ( ) ;
0 commit comments