Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prior commands improvements #1378

Merged
merged 6 commits into from
Nov 21, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions remmina/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ list(APPEND REMMINA_SRCS
"src/remmina_string_array.h"
"src/remmina_string_list.c"
"src/remmina_string_list.h"
"src/remmina_utils.c"
"src/remmina_utils.h"
"src/remmina_widget_pool.c"
"src/remmina_widget_pool.h"
"src/remmina_external_tools.c"
Expand Down
3 changes: 0 additions & 3 deletions remmina/src/remmina_connection_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -3756,9 +3756,6 @@ GtkWidget* remmina_connection_window_open_from_file_full(RemminaFile* remminafil
cnnobj = g_new0(RemminaConnectionObject, 1);
cnnobj->remmina_file = remminafile;

/* Exec precommand before everything else */
remmina_plugin_cmdexec_new(cnnobj->remmina_file, "precommand");

/* Create the RemminaProtocolWidget */
protocolwidget = cnnobj->proto = remmina_protocol_widget_new();

Expand Down
19 changes: 13 additions & 6 deletions remmina/src/remmina_file_editor.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,15 @@ static const gchar * server_tips = N_( "<tt><big>"
"* [server]:port"
"</big></tt>");

static const gchar * cmd_tips = N_( "<tt><big>"
"* command in PATH args %h\n"
"* /path/to/foo -options %h %u %U %t\n"
"* %h is substituted with the server name\n"
"* %u is substituted with the user name\n"
"* %t is substituted with the ssh tunnel server name\n"
"* %U is substituted with the ssh tunnel user name\n"
"</big></tt>");

#ifdef HAVE_LIBSSH
static const gchar* server_tips2 = N_( "<tt><big>"
"Supported formats\n"
Expand Down Expand Up @@ -1418,9 +1427,8 @@ GtkWidget* remmina_file_editor_new_from_file(RemminaFile* remminafile)
priv->precommand_entry = widget;
cs = remmina_file_get_string(remminafile, "precommand");
gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
s = g_strdup_printf(_("Script/command with arguments"));
gtk_widget_set_tooltip_text(widget, s);
g_free(s);
gtk_entry_set_placeholder_text(GTK_ENTRY(widget), "command %h %u %t %U --option");
gtk_widget_set_tooltip_markup(widget, _(cmd_tips));

/* POST Connection Command */
widget = gtk_label_new(_("Post Command"));
Expand All @@ -1437,9 +1445,8 @@ GtkWidget* remmina_file_editor_new_from_file(RemminaFile* remminafile)
priv->postcommand_entry = widget;
cs = remmina_file_get_string(remminafile, "postcommand");
gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
s = g_strdup_printf(_("Script/command with arguments"));
gtk_widget_set_tooltip_text(widget, s);
g_free(s);
gtk_entry_set_placeholder_text(GTK_ENTRY(widget), "/path/to/command -opt1 arg %h %u %t -opt2 %U");
gtk_widget_set_tooltip_markup(widget, _(cmd_tips));

/* Create the Preference frame */
widget = gtk_event_box_new();
Expand Down
23 changes: 16 additions & 7 deletions remmina/src/remmina_plugin_cmdexec.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,13 @@
*
*/

#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <glib.h>
#include <stdlib.h>
#include <sys/wait.h>
#include "remmina_utils.h"
#include "remmina_file.h"
#include "remmina_plugin_cmdexec.h"
#include "remmina_public.h"
Expand All @@ -63,7 +65,8 @@ GtkDialog* remmina_plugin_cmdexec_new(RemminaFile* remminafile, const char *remm
PCon_Spinner *pcspinner;
GError *error = NULL;
char **argv;
char const *plugin_cmd = NULL;
gchar *cmd = NULL;
GString *cmd_str;
gchar pre[11];
gchar post[12];
GPid child_pid;
Expand All @@ -72,14 +75,20 @@ GtkDialog* remmina_plugin_cmdexec_new(RemminaFile* remminafile, const char *remm
strcpy(post, "postcommand");

if (remmina_plugin_cmdexec_type != NULL && (
strcmp(remmina_plugin_cmdexec_type, pre) |
strcmp(remmina_plugin_cmdexec_type, post) )) {
plugin_cmd = remmina_file_get_string(remminafile, remmina_plugin_cmdexec_type);
strcmp(remmina_plugin_cmdexec_type, pre) |
strcmp(remmina_plugin_cmdexec_type, post) )) {
cmd_str = g_string_new(remmina_file_get_string(remminafile, remmina_plugin_cmdexec_type));
remmina_utils_string_replace_all(cmd_str, "%h", remmina_file_get_string(remminafile, "server"));
remmina_utils_string_replace_all(cmd_str, "%t", remmina_file_get_string(remminafile, "ssh_server"));
remmina_utils_string_replace_all(cmd_str, "%u", remmina_file_get_string(remminafile, "username"));
remmina_utils_string_replace_all(cmd_str, "%U", remmina_file_get_string(remminafile, "ssh_username"));
}else{
return FALSE;
}

if (plugin_cmd != NULL) {
cmd = g_string_free(cmd_str, FALSE);
if (*cmd != 0) {

pcspinner = g_new(PCon_Spinner, 1);
builder = remmina_public_gtk_builder_new_from_file("remmina_spinner.glade");
pcspinner->dialog = GTK_DIALOG(gtk_builder_get_object(builder, "DialogSpinner"));
Expand All @@ -90,7 +99,7 @@ GtkDialog* remmina_plugin_cmdexec_new(RemminaFile* remminafile, const char *remm
gtk_builder_connect_signals(builder, NULL);

/* Exec a predefined command */
g_shell_parse_argv(plugin_cmd, NULL, &argv, &error);
g_shell_parse_argv(cmd, NULL, &argv, &error);

if (error) {
g_warning("%s\n", error->message);
Expand All @@ -113,7 +122,7 @@ GtkDialog* remmina_plugin_cmdexec_new(RemminaFile* remminafile, const char *remm
g_child_watch_add(child_pid, wait_for_child, (gpointer)pcspinner);
gtk_dialog_run(pcspinner->dialog);
}else {
g_warning("Command %s exited with error: %s\n", plugin_cmd, error->message);
g_warning("Command %s exited with error: %s\n", cmd, error->message);
g_error_free(error);
}
g_strfreev(argv);
Expand Down
3 changes: 3 additions & 0 deletions remmina/src/remmina_protocol_widget.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ void remmina_protocol_widget_open_connection(RemminaProtocolWidget* gp, RemminaF
gp->priv->scalemode = remmina_file_get_int(remminafile, "scale", FALSE);
gp->priv->scaler_expand = remmina_file_get_int(remminafile, "scaler_expand", FALSE);

/* Exec precommand before everything else */
remmina_plugin_cmdexec_new(remminafile, "precommand");

remmina_protocol_widget_show_init_dialog(gp, remmina_file_get_string(remminafile, "name"));

remmina_protocol_widget_open_connection_real(gp);
Expand Down
137 changes: 137 additions & 0 deletions remmina/src/remmina_utils.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2016-2017 Antenore Gatta, Giovanni Panozzo
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*/

/*
* General utility functions, non-GTK related.
*/

#include <glib/gi18n.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
#include <glib.h>
#include <stdlib.h>
#include "remmina/remmina_trace_calls.h"

/** Returns @c TRUE if @a ptr is @c NULL or @c *ptr is @c FALSE. */
#define EMPTY(ptr) \
(!(ptr) || !*(ptr))

gint remmina_utils_strpos(const gchar *haystack, const gchar *needle)
{
const gchar *sub;

if (! *needle)
return -1;

sub = strstr(haystack, needle);
if (! sub)
return -1;

return sub - haystack;
}

/* end can be -1 for haystack->len.
* returns: position of found text or -1.
* (C) Taken from geany */
gint remmina_utils_string_find(GString *haystack, gint start, gint end, const gchar *needle)
{
TRACE_CALL(__func__);
gint pos;

g_return_val_if_fail(haystack != NULL, -1);
if (haystack->len == 0)
return -1;

g_return_val_if_fail(start >= 0, -1);
if (start >= (gint)haystack->len)
return -1;

g_return_val_if_fail(!EMPTY(needle), -1);

if (end < 0)
end = haystack->len;

pos = remmina_utils_strpos(haystack->str + start, needle);
if (pos == -1)
return -1;

pos += start;
if (pos >= end)
return -1;
return pos;
}

/* Replaces @len characters from offset @a pos.
* len can be -1 to replace the remainder of @a str.
* returns: pos + strlen(replace).
* (C) Taken from geany */
gint remmina_utils_string_replace(GString *str, gint pos, gint len, const gchar *replace)
{
g_string_erase(str, pos, len);
if (replace)
{
g_string_insert(str, pos, replace);
pos += strlen(replace);
}
return pos;
}

/**
* Replaces all occurrences of @a needle in @a haystack with @a replace.
*
* @param haystack The input string to operate on. This string is modified in place.
* @param needle The string which should be replaced.
* @param replace The replacement for @a needle.
*
* @return Number of replacements made.
**/
guint remmina_utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace)
{
guint count = 0;
gint pos = 0;
gsize needle_length = strlen(needle);

while (1)
{
pos = remmina_utils_string_find(haystack, pos, -1, needle);

if (pos == -1)
break;

pos = remmina_utils_string_replace(haystack, pos, needle_length, replace);
count++;
}
return count;
}

48 changes: 48 additions & 0 deletions remmina/src/remmina_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Remmina - The GTK+ Remote Desktop Client
* Copyright (C) 2016-2017 Antenore Gatta, Giovanni Panozzo
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations
* including the two.
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL. * If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. * If you
* do not wish to do so, delete this exception statement from your
* version. * If you delete this exception statement from all source
* files in the program, then also delete it here.
*
*/

/**
* @file: remmina_utils.h
* General utility functions, non-GTK related.
*/

#pragma once

G_BEGIN_DECLS
gint remmina_utils_string_find(GString *haystack, gint start, gint end, const gchar *needle);

gint remmina_utils_string_replace(GString *str, gint pos, gint len, const gchar *replace);

guint remmina_utils_string_replace_all(GString *haystack, const gchar *needle, const gchar *replace);