42 #include <gdk/gdkkeysyms.h> 49 #define GET_PLUGIN_DATA(gp) (RemminaPluginExecData*)g_object_get_data(G_OBJECT(gp), "plugin-data") 60 #define REMMINA_PLUGIN_DEBUG(fmt, ...) remmina_plugin_service->_remmina_debug(__func__, fmt, ##__VA_ARGS__) 67 g_spawn_close_pid( pid );
83 if( cond == G_IO_HUP )
85 g_io_channel_unref( channel );
89 g_io_channel_read_line( channel, &
string, &size, NULL, NULL );
90 gtk_text_buffer_insert_at_cursor( gpdata->
log_buffer,
string, -1 );
104 if( cond == G_IO_HUP )
106 g_io_channel_unref( channel );
110 g_io_channel_read_line( channel, &
string, &size, NULL, NULL );
111 gtk_text_buffer_insert_at_cursor( gpdata->
err,
string, -1 );
119 TRACE_CALL(__func__);
122 REMMINA_PLUGIN_DEBUG(
"[%s] Plugin init", PLUGIN_NAME);
125 g_object_set_data_full(G_OBJECT(gp),
"plugin-data", gpdata, g_free);
128 gpdata->
log_view = gtk_text_view_new();
129 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(gpdata->
log_view), GTK_WRAP_CHAR);
130 gtk_text_view_set_editable(GTK_TEXT_VIEW(gpdata->
log_view), FALSE);
131 gtk_text_view_set_left_margin (GTK_TEXT_VIEW (gpdata->
log_view), 20);
132 gtk_text_view_set_right_margin (GTK_TEXT_VIEW (gpdata->
log_view), 20);
134 gpdata->
sw = gtk_scrolled_window_new (NULL, NULL);
135 gtk_widget_set_size_request (gpdata->
sw, 640, 480);
136 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (gpdata->
sw),
137 GTK_POLICY_AUTOMATIC,
138 GTK_POLICY_AUTOMATIC);
139 gtk_container_add(GTK_CONTAINER(gp), gpdata->
sw);
140 gtk_container_add(GTK_CONTAINER(gpdata->
sw), gpdata->
log_view);
141 gtk_text_buffer_set_text (gpdata->
log_buffer,
"Remmina Exec Plugin Logger", -1);
143 gtk_widget_show_all(gpdata->
sw);
148 TRACE_CALL(__func__);
151 gchar *stdout_buffer;
152 gchar *stderr_buffer;
154 GError *error = NULL;
156 gint child_stdout, child_stderr;
158 GIOChannel *out_ch, *err_ch;
160 REMMINA_PLUGIN_DEBUG(
"[%s] Plugin run", PLUGIN_NAME);
164 cmd = remmina_plugin_service->
file_get_string(remminafile,
"execcommand");
167 _(
"You did not set any command to be executed"), -1);
172 g_shell_parse_argv(cmd, NULL, &argv, &error);
174 gtk_text_buffer_set_text (gpdata->
log_buffer, error->message, -1);
180 if (remmina_plugin_service->
file_get_int(remminafile,
"runasync", FALSE)) {
181 REMMINA_PLUGIN_DEBUG(
"[%s] Run Async", PLUGIN_NAME);
182 g_spawn_async_with_pipes( NULL,
185 G_SPAWN_DO_NOT_REAP_CHILD |
186 G_SPAWN_SEARCH_PATH_FROM_ENVP |
196 gtk_text_buffer_set_text (gpdata->
log_buffer, error->message, -1);
201 g_child_watch_add(child_pid, (GChildWatchFunc)
cb_child_watch, gp );
203 gpdata->
pid = child_pid;
205 out_ch = g_io_channel_unix_new(child_stdout);
206 err_ch = g_io_channel_unix_new(child_stderr);
208 g_io_add_watch(out_ch, G_IO_IN | G_IO_HUP, (GIOFunc)
cb_out_watch, gp );
209 g_io_add_watch(err_ch, G_IO_IN | G_IO_HUP, (GIOFunc)
cb_err_watch, gp );
212 dialog = GTK_DIALOG(gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
213 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
214 _(
"Warning: Running a command synchronously may cause Remmina not to respond.\nDo you really want to continue?")));
215 gint result = gtk_dialog_run (GTK_DIALOG (dialog));
219 case GTK_RESPONSE_YES:
222 gtk_widget_destroy(GTK_WIDGET(dialog));
226 gtk_widget_destroy(GTK_WIDGET(dialog));
227 REMMINA_PLUGIN_DEBUG(
"[%s] Run Sync", PLUGIN_NAME);
231 G_SPAWN_SEARCH_PATH |
232 G_SPAWN_SEARCH_PATH_FROM_ENVP,
240 REMMINA_PLUGIN_DEBUG(
"[%s] Command executed", PLUGIN_NAME);
241 gtk_text_buffer_set_text (gpdata->
log_buffer, stdout_buffer, -1);
243 g_warning(
"Command %s exited with error: %s\n", cmd, error->message);
244 gtk_text_buffer_set_text (gpdata->
log_buffer, error->message, -1);
257 TRACE_CALL(__func__);
258 REMMINA_PLUGIN_DEBUG(
"[%s] Plugin close", PLUGIN_NAME);
262 if (remmina_plugin_service->
file_get_int(remminafile,
"kill_proc", FALSE)) {
263 if (gpdata->
pid !=0 ){
264 int pgid = getpgid(gpdata->
pid);
266 kill(-gpdata->
pid, SIGHUP);
269 kill(gpdata->
pid, SIGHUP);
329 TRACE_CALL(__func__);
330 remmina_plugin_service = service;
332 bindtextdomain(GETTEXT_PACKAGE, REMMINA_RUNTIME_LOCALEDIR);
333 bind_textdomain_codeset(GETTEXT_PACKAGE,
"UTF-8");
static const RemminaProtocolSetting remmina_plugin_exec_basic_settings[]
static void cb_child_watch(GPid pid, gint status)
typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
static RemminaProtocolPlugin remmina_plugin
static void remmina_plugin_exec_init(RemminaProtocolWidget *gp)
struct _RemminaPluginExecData RemminaPluginExecData
static gboolean remmina_plugin_exec_run(RemminaProtocolWidget *gp)
void(* protocol_plugin_signal_connection_closed)(RemminaProtocolWidget *gp)
gint(* file_get_int)(RemminaFile *remminafile, const gchar *setting, gint default_value)
void(* protocol_plugin_signal_connection_opened)(RemminaProtocolWidget *gp)
gboolean(* register_plugin)(RemminaPlugin *plugin)
static gboolean remmina_plugin_exec_close(RemminaProtocolWidget *gp)
RemminaFile *(* protocol_plugin_get_file)(RemminaProtocolWidget *gp)
static void cb_child_setup(gpointer data)
const gchar *(* file_get_string)(RemminaFile *remminafile, const gchar *setting)
static gboolean cb_err_watch(GIOChannel *channel, GIOCondition cond, RemminaProtocolWidget *gp)
GtkTextBuffer * log_buffer
N_("Unable to connect to VNC server")
static gboolean cb_out_watch(GIOChannel *channel, GIOCondition cond, RemminaProtocolWidget *gp)
G_MODULE_EXPORT gboolean remmina_plugin_entry(RemminaPluginService *service)
static RemminaPluginService * remmina_plugin_service