Re: Escape to shell in interactive mode

Hans Bezemer via Ecasound-list <[email protected]> Sun, 23 Mar 2025 15:55:44 +0100
Newsgroups gmane.comp.audio.ecasound.general
Message-ID <uiucoloqib6dtb3srlifvpmaj477ztpcgyhdcqi4u7htzzfacd@2ynergwz3cxm>
--v52vs26nzigfh5go
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline

Dear fellow ecasound users,

I've managed to add a command which passes the remaining
arguments to a shell (see attachment).
This obviously gives a security risk when running in
ecasound in NetECI mode.
I would like to add a conditional which prohibits the
use of the command in NetECI mode.
From what I understand the variable neteci_mode is set to
true when NetECI is activated.
My programming skills fall short here.
I've tried several suggestions found on the internet,
but without succes.
Could someone give a pointer on how I can access that variable?


Kind regards,

Hans

 
 


On Sat, Mar 22, 2025 at 11:27:13AM +0100, Hans Bezemer wrote:
> Dear fellow ecasound users,
> 
> Lately I'm using ecasound in interactive mode more frequently.
> To speed up me workflow (I make most of my changes by editing
> the chain setup in vi) I added some shorthands for editing,
> saving and getting and setting the position.
> I've attached a patch file for those interested.
> 
> Although the workflow is pretty comfortable, I sometimes
> want to be able to send shell commands.
> Somewhere along the lines of:
> !cp Temp.wav Guitar.wav
> !ls
> !make c #to make a commit with a timestamp
> Of course this can be done when editing using vi or
> by pressing ctrl-z,
> but sometimes it would be nice to do this directly 
> from ecasound.
> 
> Although not a programmer I would like to give it
> a try to implement this, but I would like to get
> some pointers before I dive in.
> Would this be a useful feature?
> Are the things to consider before starting?
> 
> Kind regards,
> 
> Hans
> 
> 

> diff --git a/Documentation/ecasound-iam_manpage.yo b/Documentation/ecasound-iam_manpage.yo
> index fc971c28..88a6dc68 100644
> --- a/Documentation/ecasound-iam_manpage.yo
> +++ b/Documentation/ecasound-iam_manpage.yo
> @@ -184,7 +184,7 @@ dit(cs-load 'filename')
>  Adds a new chainsetup by loading it from file 'filename'. 
>  'filename' is now the selected chainsetup. em([-])
>  
> -dit(cs-save) 
> +dit(cs-save, save) 
>  Saves the currently selected chainsetup to file. If chainsetup was loaded
>  from a file, the saved version will replace the original. If it doesn't 
>  have a default filename, it's saved to "chainsetup_name.ecs". em([-])
> @@ -192,7 +192,7 @@ have a default filename, it's saved to "chainsetup_name.ecs". em([-])
>  dit(cs-save-as 'filename')
>  Saves currently selected chainsetup to file 'filename'. em([-])
>  
> -dit(cs-edit) 
> +dit(cs-edit, edit, ed, e) 
>  Currently selected chainsetup is saved to a temporary file. This
>  file is loaded to an external editor (see ecasoundrc (5)). After
>  editing, the chainsetup is loaded back to ecasound. em([-])
> @@ -224,7 +224,7 @@ The current chainsetup position is forwarded by 'time-in-seconds'
>  seconds. Position of all inputs and outputs attached to the selected chainsetup
>  is also affected. em([-])
>   
> -dit(cs-set-position 'time-in-seconds', cs-setpos 'time-in-seconds', setpos 'time-in-seconds', set-position 'time-in-seconds')
> +dit(cs-set-position 'time-in-seconds', cs-setpos 'time-in-seconds', setpos 'time-in-seconds', set-position 'time-in-seconds', sp 'time-in-seconds')
>  Sets the chainsetup position to 'time-in-seconds' seconds from the 
>  beginning. Position of all inputs and outputs attached to the selected 
>  chainsetup is also affected. em([-])
> @@ -234,7 +234,7 @@ Sets the chainsetup position to 'time-in-samples' samples from the
>  beginning. Position of all inputs and outputs attached to the selected 
>  chainsetup is also affected. em([-])
>  
> -dit(cs-get-position, cs-getpos, getpos, get-position)
> +dit(cs-get-position, cs-getpos, getpos, get-position, gp)
>  Returns the current chainsetup position in seconds. em([f])
>  
>  dit(cs-get-position-samples)
> diff --git a/libecasound/eca-iamode-parser.cpp b/libecasound/eca-iamode-parser.cpp
> index 9754ddf1..8dc0e206 100644
> --- a/libecasound/eca-iamode-parser.cpp
> +++ b/libecasound/eca-iamode-parser.cpp
> @@ -152,8 +152,12 @@ void ECA_IAMODE_PARSER::register_commands_cs(void)
>    (*cmd_map_repp)["cs-iselect"] = ec_cs_index_select;
>    (*cmd_map_repp)["cs-load"] = ec_cs_load;
>    (*cmd_map_repp)["cs-save"] = ec_cs_save;
> +  (*cmd_map_repp)["save"] = ec_cs_save;
>    (*cmd_map_repp)["cs-save-as"] = ec_cs_save_as;
>    (*cmd_map_repp)["cs-edit"] = ec_cs_edit;
> +  (*cmd_map_repp)["edit"] = ec_cs_edit;
> +  (*cmd_map_repp)["ed"] = ec_cs_edit;
> +  (*cmd_map_repp)["e"] = ec_cs_edit;
>    (*cmd_map_repp)["cs-is-valid"] = ec_cs_is_valid;
>    (*cmd_map_repp)["cs-connect"] = ec_cs_connect;
>    (*cmd_map_repp)["cs-connected"] = ec_cs_connected;
> @@ -171,11 +175,13 @@ void ECA_IAMODE_PARSER::register_commands_cs(void)
>    (*cmd_map_repp)["cs-set-position"] = ec_cs_set_position;
>    (*cmd_map_repp)["cs-set-position-samples"] = ec_cs_set_position_samples;
>    (*cmd_map_repp)["setpos"] = ec_cs_set_position;
> +  (*cmd_map_repp)["sp"] = ec_cs_set_position;
>    (*cmd_map_repp)["set-position"] = ec_cs_set_position;
>    (*cmd_map_repp)["cs-getpos"] = ec_cs_get_position;
>    (*cmd_map_repp)["cs-get-position"] = ec_cs_get_position;
>    (*cmd_map_repp)["cs-get-position-samples"] = ec_cs_get_position_samples;
>    (*cmd_map_repp)["getpos"] = ec_cs_get_position;
> +  (*cmd_map_repp)["gp"] = ec_cs_get_position;
>    (*cmd_map_repp)["get-position"] = ec_cs_get_position;
>    (*cmd_map_repp)["cs-get-length"] = ec_cs_get_length;
>    (*cmd_map_repp)["cs-get-length-samples"] = ec_cs_get_length_samples;


--v52vs26nzigfh5go
Content-Type: text/plain; charset=utf-8
Content-Disposition: attachment; filename="bzrmods.patch"

diff --git a/Documentation/ecasound-iam_manpage.yo b/Documentation/ecasound-iam_manpage.yo
index fc971c28..39117c63 100644
--- a/Documentation/ecasound-iam_manpage.yo
+++ b/Documentation/ecasound-iam_manpage.yo
@@ -104,6 +104,9 @@ Like 'start' but blocks until processing is finished. Error string
 is return if any errors upon startup, or during process, are 
 encountered. em([e])
 
+dit(sh 'things-to-pass-to-shell',! 'things-to-pass-to-shell') 
+Spawns a shell and passes all the arguments to it.
+
 dit(debug 'debug-level')
 Set debug level to 'debug-level'. Notice that client programs can
 reimplement the debug routines. em([-])
@@ -145,7 +148,7 @@ was running. See also em(cs-disconnet) and em(stop). When
 ecasound is used as a JACK client, em(engine-halt) will 
 cause ecasound to become a deactivated client (all JACK
 connections are torn down). em([-])
- 
+
 enddit()
 
 manpagesection(CHAINSETUPS)
@@ -184,7 +187,7 @@ dit(cs-load 'filename')
 Adds a new chainsetup by loading it from file 'filename'. 
 'filename' is now the selected chainsetup. em([-])
 
-dit(cs-save) 
+dit(cs-save, save) 
 Saves the currently selected chainsetup to file. If chainsetup was loaded
 from a file, the saved version will replace the original. If it doesn't 
 have a default filename, it's saved to "chainsetup_name.ecs". em([-])
@@ -192,7 +195,7 @@ have a default filename, it's saved to "chainsetup_name.ecs". em([-])
 dit(cs-save-as 'filename')
 Saves currently selected chainsetup to file 'filename'. em([-])
 
-dit(cs-edit) 
+dit(cs-edit, edit, ed, e) 
 Currently selected chainsetup is saved to a temporary file. This
 file is loaded to an external editor (see ecasoundrc (5)). After
 editing, the chainsetup is loaded back to ecasound. em([-])
@@ -224,7 +227,7 @@ The current chainsetup position is forwarded by 'time-in-seconds'
 seconds. Position of all inputs and outputs attached to the selected chainsetup
 is also affected. em([-])
  
-dit(cs-set-position 'time-in-seconds', cs-setpos 'time-in-seconds', setpos 'time-in-seconds', set-position 'time-in-seconds')
+dit(cs-set-position 'time-in-seconds', cs-setpos 'time-in-seconds', setpos 'time-in-seconds', set-position 'time-in-seconds', sp 'time-in-seconds')
 Sets the chainsetup position to 'time-in-seconds' seconds from the 
 beginning. Position of all inputs and outputs attached to the selected 
 chainsetup is also affected. em([-])
@@ -234,7 +237,7 @@ Sets the chainsetup position to 'time-in-samples' samples from the
 beginning. Position of all inputs and outputs attached to the selected 
 chainsetup is also affected. em([-])
 
-dit(cs-get-position, cs-getpos, getpos, get-position)
+dit(cs-get-position, cs-getpos, getpos, get-position, gp)
 Returns the current chainsetup position in seconds. em([f])
 
 dit(cs-get-position-samples)
diff --git a/libecasound/eca-control.cpp b/libecasound/eca-control.cpp
index 729e9197..091f7e4b 100644
--- a/libecasound/eca-control.cpp
+++ b/libecasound/eca-control.cpp
@@ -33,6 +33,7 @@
 #include <list>
 #include <algorithm>
 #include <unistd.h>
+#include <sstream>
 
 #ifdef HAVE_LOCALE_H
 #include <locale.h>
@@ -221,6 +222,21 @@ string ECA_CONTROL::first_action_argument_as_string(void) const
   return action_args_rep[0];
 }
 
+string ECA_CONTROL::action_arguments_as_string(void) const
+{
+  if (action_args_rep.size() == 0)
+    return std::string();
+
+  std::stringstream ss;
+    for (auto it = action_args_rep.begin(); it != action_args_rep.end(); it++)    {
+      if (it != action_args_rep.begin()) {
+        ss << " ";
+      }
+      ss << *it;
+    }
+  return ss.str();
+}
+
 const vector<string>& ECA_CONTROL::action_arguments_as_vector(void) const
 {
   return action_args_rep;
@@ -460,6 +476,7 @@ void ECA_CONTROL::action(int action_id)
 					     first_action_argument_as_string());
       break;
     }
+    case ec_shell: { shell(); break; }
 
     // ---
     // Chainsetups
@@ -1575,3 +1592,12 @@ void ECA_CONTROL::ctrl_descriptions(void)
   operator_descriptions_helper(ECA_OBJECT_FACTORY::controller_map(), &result);
   set_last_string(result);
 }
+void ECA_CONTROL::shell(void)
+{
+  int result = system(action_arguments_as_string().c_str());
+  if (result == 0) {
+        std::cout << "Command executed successfully!" << std::endl;
+    } else {
+        std::cout << "Command execution failed!" << std::endl;
+    }
+}
diff --git a/libecasound/eca-control.h b/libecasound/eca-control.h
index b38e1bfb..44ecda45 100644
--- a/libecasound/eca-control.h
+++ b/libecasound/eca-control.h
@@ -143,6 +143,7 @@ class ECA_CONTROL : public ECA_IAMODE_PARSER,
   void select_chainsetup(const std::string& name);
   void select_chainsetup_by_index(int index);
   void edit_chainsetup(void);
+  void shell(void);
 
   std::string selected_chainsetup(void) const;
   std::string connected_chainsetup(void) const;
@@ -407,6 +408,7 @@ class ECA_CONTROL : public ECA_IAMODE_PARSER,
   void clear_action_arguments(void);
   double first_action_argument_as_float(void) const;
   std::string first_action_argument_as_string(void) const;
+  std::string action_arguments_as_string(void) const;
   int first_action_argument_as_int(void) const;
   long int first_action_argument_as_long_int(void) const;
   SAMPLE_SPECS::sample_pos_t first_action_argument_as_samples(void) const;
diff --git a/libecasound/eca-iamode-parser.cpp b/libecasound/eca-iamode-parser.cpp
index 9754ddf1..58e25b09 100644
--- a/libecasound/eca-iamode-parser.cpp
+++ b/libecasound/eca-iamode-parser.cpp
@@ -30,6 +30,7 @@
 #include <vector>
 #include <string>
 #include <pthread.h>
+#include <cstdlib>
 
 #include "kvu_message_item.h"
 #include "kvu_locks.h"
@@ -97,6 +98,9 @@ void ECA_IAMODE_PARSER::register_commands_misc(void)
 
   (*cmd_map_repp)["quit"] = ec_exit;
   (*cmd_map_repp)["q"] = ec_exit;
+
+  (*cmd_map_repp)["sh"] = ec_shell;
+  (*cmd_map_repp)["!"] = ec_shell;
    
   (*cmd_map_repp)["start"] = ec_start;
   (*cmd_map_repp)["t"] = ec_start;
@@ -152,8 +156,12 @@ void ECA_IAMODE_PARSER::register_commands_cs(void)
   (*cmd_map_repp)["cs-iselect"] = ec_cs_index_select;
   (*cmd_map_repp)["cs-load"] = ec_cs_load;
   (*cmd_map_repp)["cs-save"] = ec_cs_save;
+  (*cmd_map_repp)["save"] = ec_cs_save;
   (*cmd_map_repp)["cs-save-as"] = ec_cs_save_as;
   (*cmd_map_repp)["cs-edit"] = ec_cs_edit;
+  (*cmd_map_repp)["edit"] = ec_cs_edit;
+  (*cmd_map_repp)["ed"] = ec_cs_edit;
+  (*cmd_map_repp)["e"] = ec_cs_edit;
   (*cmd_map_repp)["cs-is-valid"] = ec_cs_is_valid;
   (*cmd_map_repp)["cs-connect"] = ec_cs_connect;
   (*cmd_map_repp)["cs-connected"] = ec_cs_connected;
@@ -171,11 +179,13 @@ void ECA_IAMODE_PARSER::register_commands_cs(void)
   (*cmd_map_repp)["cs-set-position"] = ec_cs_set_position;
   (*cmd_map_repp)["cs-set-position-samples"] = ec_cs_set_position_samples;
   (*cmd_map_repp)["setpos"] = ec_cs_set_position;
+  (*cmd_map_repp)["sp"] = ec_cs_set_position;
   (*cmd_map_repp)["set-position"] = ec_cs_set_position;
   (*cmd_map_repp)["cs-getpos"] = ec_cs_get_position;
   (*cmd_map_repp)["cs-get-position"] = ec_cs_get_position;
   (*cmd_map_repp)["cs-get-position-samples"] = ec_cs_get_position_samples;
   (*cmd_map_repp)["getpos"] = ec_cs_get_position;
+  (*cmd_map_repp)["gp"] = ec_cs_get_position;
   (*cmd_map_repp)["get-position"] = ec_cs_get_position;
   (*cmd_map_repp)["cs-get-length"] = ec_cs_get_length;
   (*cmd_map_repp)["cs-get-length-samples"] = ec_cs_get_length_samples;
diff --git a/libecasound/eca-iamode-parser_impl.h b/libecasound/eca-iamode-parser_impl.h
index b05449ba..1da1ad3e 100644
--- a/libecasound/eca-iamode-parser_impl.h
+++ b/libecasound/eca-iamode-parser_impl.h
@@ -16,6 +16,7 @@ class ECA_IAMODE_PARSER_COMMANDS {
     ec_run,
     ec_debug,
     ec_resource_file,
+    ec_shell,
     // --
     ec_engine_status,
     ec_engine_launch,

--v52vs26nzigfh5go
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline


--v52vs26nzigfh5go
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Ecasound-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ecasound-list

--v52vs26nzigfh5go--