diff options
author | Antenore Gatta (tmow) <antenore@simbiosi.org> | 2021-12-03 17:56:25 +0300 |
---|---|---|
committer | Antenore Gatta (tmow) <antenore@simbiosi.org> | 2021-12-03 17:56:25 +0300 |
commit | 0c2fe32ec2366f4dae4b189dc44890b08ef72256 (patch) | |
tree | ddcd671d4258d20c726a383c7a512120680084f3 /src | |
parent | 050fc71c88b9b3722da6d1a3ae9ae5594f9b17f8 (diff) |
Removing the Remmina stats sender and repurposing Remmina stats
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/remmina.c | 3 | ||||
-rw-r--r-- | src/remmina_file.c | 7 | ||||
-rw-r--r-- | src/remmina_icon.c | 10 | ||||
-rw-r--r-- | src/remmina_log.c | 153 | ||||
-rw-r--r-- | src/remmina_main.c | 49 | ||||
-rw-r--r-- | src/remmina_main.h | 8 | ||||
-rw-r--r-- | src/remmina_monitor.c | 223 | ||||
-rw-r--r-- | src/remmina_monitor.h | 56 | ||||
-rw-r--r-- | src/remmina_ssh.c | 12 | ||||
-rw-r--r-- | src/remmina_ssh_plugin.c | 3 | ||||
-rw-r--r-- | src/remmina_stats.c | 54 | ||||
-rw-r--r-- | src/rmnews.c | 48 |
13 files changed, 468 insertions, 162 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9d2051629..71fc9ff2e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -64,6 +64,8 @@ list( "remmina_log.h" "remmina_main.c" "remmina_main.h" + "remmina_monitor.c" + "remmina_monitor.h" "remmina_marshals.c" "remmina_marshals.h" "remmina_marshals.list" @@ -121,8 +123,6 @@ list( "remmina_scheduler.h" "remmina_stats.c" "remmina_stats.h" - "remmina_stats_sender.c" - "remmina_stats_sender.h" "resources.c") set(RESOURCE_LIST diff --git a/src/remmina.c b/src/remmina.c index e0eba489a..d2b987d2d 100644 --- a/src/remmina.c +++ b/src/remmina.c @@ -58,8 +58,6 @@ #include "remmina_widget_pool.h" #include "remmina/remmina_trace_calls.h" #include "rmnews.h" -#include "remmina_stats_sender.h" - #ifdef HAVE_ERRNO_H #include <errno.h> @@ -263,7 +261,6 @@ static void remmina_on_startup(GApplication *app) REMMINA_RUNTIME_DATADIR G_DIR_SEPARATOR_S "icons"); g_application_hold(app); - remmina_stats_sender_schedule(); rmnews_schedule(); /* Check for secret plugin and service initialization and show console warnings if diff --git a/src/remmina_file.c b/src/remmina_file.c index e52c2b529..4d86e919e 100644 --- a/src/remmina_file.c +++ b/src/remmina_file.c @@ -831,6 +831,8 @@ remmina_file_dup(RemminaFile *remminafile) while (g_hash_table_iter_next(&iter, (gpointer *)&key, (gpointer *)&value)) remmina_file_set_string(dupfile, key, value); + remmina_file_set_statefile(dupfile); + remmina_file_touch(dupfile); return dupfile; } @@ -904,7 +906,7 @@ void remmina_file_state_last_success(RemminaFile *remminafile) g_autoptr(GKeyFile) key_statefile = g_key_file_new(); g_autoptr(GKeyFile) key_remminafile = g_key_file_new(); - g_autoptr(GError) error = NULL; + GError *error = NULL; const gchar *date = NULL; GDateTime *d = g_date_time_new_now_utc(); @@ -916,8 +918,11 @@ void remmina_file_state_last_success(RemminaFile *remminafile) g_key_file_set_string(key_statefile, KEYFILE_GROUP_STATE, "last_success", date); + REMMINA_DEBUG("State file %s.", remminafile->statefile); if (!g_key_file_save_to_file(key_statefile, remminafile->statefile, &error)) { REMMINA_CRITICAL("Could not save the key file. %s", error->message); + g_error_free(error); + error = NULL; return; } /* Delete old pre-1.5 keys */ diff --git a/src/remmina_icon.c b/src/remmina_icon.c index e1bf80c94..e9c3b1855 100644 --- a/src/remmina_icon.c +++ b/src/remmina_icon.c @@ -338,6 +338,7 @@ static void remmina_icon_connection_changed_cb(AppIndicator *indicator, gboolean connected, gpointer data) { TRACE_CALL(__func__); + REMMINA_DEBUG("Indicator connection changed to: %d", connected); remmina_icon.indicator_connected = connected; } @@ -383,14 +384,8 @@ void remmina_icon_init(void) //TRANSLATORS: %s is a placeholder for "StatusNotifier/Appindicator suppor in “DESKTOP NAME”: " REMMINA_INFO(_("%s You may need to install, and use Gnome Shell Extension Appindicator"), msg); - - if (!remmina_icon.icon && !remmina_pref.disable_tray_icon) { remmina_icon.icon = app_indicator_new("remmina-icon", remmina_panel, APP_INDICATOR_CATEGORY_APPLICATION_STATUS); - //app_indicator_set_icon_theme_path(remmina_icon.icon, REMMINA_RUNTIME_DATADIR G_DIR_SEPARATOR_S "icons"); - //const gchar *theme_path = app_indicator_get_icon_theme_path(remmina_icon.icon); - //REMMINA_DEBUG("Custom app indicator icon theme path is %s", theme_path); - app_indicator_set_status(remmina_icon.icon, APP_INDICATOR_STATUS_ACTIVE); app_indicator_set_title(remmina_icon.icon, "Remmina"); remmina_icon_populate_menu(); @@ -400,6 +395,7 @@ void remmina_icon_init(void) /* With libappindicator we can also change the icon on the fly */ app_indicator_set_icon(remmina_icon.icon, remmina_panel); } + remmina_icon.indicator_connected = TRUE; #ifdef HAVE_LIBAVAHI_CLIENT if (!remmina_icon.avahi) remmina_icon.avahi = remmina_avahi_new(); @@ -418,7 +414,7 @@ void remmina_icon_init(void) } // "connected" property means a visible indicator, otherwise could be hidden. or fall back to GtkStatusIcon g_signal_connect(G_OBJECT(remmina_icon.icon), "connection-changed", G_CALLBACK(remmina_icon_connection_changed_cb), NULL); - g_object_get(G_OBJECT(remmina_icon.icon), "connected", &remmina_icon.indicator_connected, NULL); + //g_object_get(G_OBJECT(remmina_icon.icon), "connected", &remmina_icon.indicator_connected, NULL); } gboolean remmina_icon_is_autostart(void) diff --git a/src/remmina_log.c b/src/remmina_log.c index 0b9d389e3..5e1a7d747 100644 --- a/src/remmina_log.c +++ b/src/remmina_log.c @@ -38,9 +38,11 @@ #include <glib/gi18n.h> #include "remmina_public.h" #include "remmina_log.h" -#include "remmina_stats_sender.h" +#include "remmina_stats.h" #include "remmina/remmina_trace_calls.h" +gboolean logstart; + /***** Define the log window GUI *****/ #define REMMINA_TYPE_LOG_WINDOW (remmina_log_window_get_type()) #define REMMINA_LOG_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), REMMINA_TYPE_LOG_WINDOW, RemminaLogWindow)) @@ -65,56 +67,32 @@ G_GNUC_CONST; G_DEFINE_TYPE(RemminaLogWindow, remmina_log_window, GTK_TYPE_WINDOW) -static void remmina_log_window_class_init(RemminaLogWindowClass *klass) -{ - TRACE_CALL(__func__); -} - -/* We will always only have one log window per instance */ -static GtkWidget *log_window = NULL; - -static gboolean remmina_log_on_keypress(GtkWidget *widget, GdkEvent *event, gpointer user_data) +void remmina_log_stats() { TRACE_CALL(__func__); - GdkEventKey *e = (GdkEventKey *)event; - - if (!log_window) - return FALSE; - - if ((e->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) { - if ((e->keyval == GDK_KEY_s || e->keyval == GDK_KEY_t) && remmina_stat_sender_can_send()) { - remmina_stats_sender_send(e->keyval != GDK_KEY_s); - } - return TRUE; + JsonNode *n; + + n = remmina_stats_get_all(); + if (n != NULL) { + + JsonGenerator *g = json_generator_new(); + json_generator_set_pretty (g, TRUE); + json_generator_set_root(g, n); + json_node_unref(n); + g_autofree gchar *s = json_generator_to_data(g, NULL); // s=serialized stats + REMMINA_DEBUG("STATS: JSON data%s\n", s); + g_object_unref(g); } - - return FALSE; } -static void remmina_log_window_init(RemminaLogWindow *logwin) +static void remmina_log_window_class_init(RemminaLogWindowClass *klass) { TRACE_CALL(__func__); - GtkWidget *scrolledwindow; - GtkWidget *widget; - - gtk_container_set_border_width(GTK_CONTAINER(logwin), 4); - - scrolledwindow = gtk_scrolled_window_new(NULL, NULL); - gtk_widget_show(scrolledwindow); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); - gtk_container_add(GTK_CONTAINER(logwin), scrolledwindow); - - widget = gtk_text_view_new(); - gtk_widget_show(widget); - gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(widget), GTK_WRAP_WORD_CHAR); - gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), FALSE); - gtk_container_add(GTK_CONTAINER(scrolledwindow), widget); - logwin->log_view = widget; - logwin->log_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); - - g_signal_connect(G_OBJECT(logwin->log_view), "key-press-event", G_CALLBACK(remmina_log_on_keypress), (gpointer)logwin); } +/* We will always only have one log window per instance */ +static GtkWidget *log_window = NULL; + static GtkWidget* remmina_log_window_new(void) { @@ -128,6 +106,12 @@ static void remmina_log_end(GtkWidget *widget, gpointer data) log_window = NULL; } +static void remmina_log_start_stop (GtkSwitch *logswitch, gpointer user_data) +{ + TRACE_CALL(__func__); + logstart = !logstart; +} + void remmina_log_start(void) { TRACE_CALL(__func__); @@ -136,13 +120,41 @@ void remmina_log_start(void) }else { log_window = remmina_log_window_new(); gtk_window_set_default_size(GTK_WINDOW(log_window), 640, 480); + gtk_window_set_resizable (GTK_WINDOW(log_window), TRUE); + gtk_window_set_decorated (GTK_WINDOW(log_window), TRUE); + + /* Header bar */ + GtkWidget *header = gtk_header_bar_new (); + gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header), TRUE); + gtk_header_bar_set_title (GTK_HEADER_BAR (header), _("Remmina debugging window")); + gtk_header_bar_set_has_subtitle (GTK_HEADER_BAR (header), FALSE); + /* Stats */ + GtkWidget *getstat = gtk_button_new (); + gtk_widget_set_tooltip_text (getstat, _("Paste sytem information in the Remmina debugging window")); + GIcon *icon = g_themed_icon_new ("edit-paste-symbolic"); + GtkWidget *image = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_BUTTON); + g_object_unref (icon); + gtk_container_add (GTK_CONTAINER (getstat), image); + gtk_header_bar_pack_start (GTK_HEADER_BAR (header), getstat); + /* Start logging */ + GtkWidget *start = gtk_switch_new (); + logstart = TRUE; + gtk_switch_set_active (GTK_SWITCH(start), logstart); + gtk_header_bar_pack_start (GTK_HEADER_BAR (header), start); + + gtk_window_set_titlebar (GTK_WINDOW (log_window), header); + + g_signal_connect(getstat, "button-press-event", G_CALLBACK(remmina_log_stats), NULL); + g_signal_connect(start, "notify::active", G_CALLBACK(remmina_log_start_stop), NULL); g_signal_connect(G_OBJECT(log_window), "destroy", G_CALLBACK(remmina_log_end), NULL); - gtk_widget_show(log_window); + gtk_widget_show_all(log_window); } - if (remmina_stat_sender_can_send()) - remmina_log_print("Shortcut keys for stats:\n" - "\tCTRL+S: collect, show and send stats\n" - "\tCTRL+T: collect and show stats\n"); + + remmina_log_print(_("This window can help you finding connections problems.\n" + "You can stop and start the logging at any moment using the On/Off switch.\n" + "The stats button (Ctrl+T), may be useful to gather system information that you may share while reporting a bug.\n" + "For more information on debugging Remmina see : https://gitlab.com/Remmina/Remmina/-/wikis/Usage/Remmina-debugging\n" + )); } gboolean remmina_log_running(void) @@ -169,7 +181,7 @@ static gboolean remmina_log_print_real(gpointer data) TRACE_CALL(__func__); GtkTextIter iter; - if (log_window) { + if (log_window && logstart) { gtk_text_buffer_get_end_iter(REMMINA_LOG_WINDOW(log_window)->log_buffer, &iter); gtk_text_buffer_insert(REMMINA_LOG_WINDOW(log_window)->log_buffer, &iter, (const gchar*)data, -1); IDLE_ADD(remmina_log_scroll_to_end, NULL); @@ -368,3 +380,48 @@ void remmina_log_printf(const gchar *fmt, ...) IDLE_ADD(remmina_log_print_real, text); } + +static gboolean remmina_log_on_keypress(GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + TRACE_CALL(__func__); + + if (!log_window) + return FALSE; + + GdkEventKey *e = (GdkEventKey *)event; + + if ((e->state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK) { + if (e->keyval == GDK_KEY_t) { + remmina_log_stats(); + } + return TRUE; + } + + return FALSE; +} + +static void remmina_log_window_init(RemminaLogWindow *logwin) +{ + TRACE_CALL(__func__); + GtkWidget *scrolledwindow; + GtkWidget *widget; + + gtk_container_set_border_width(GTK_CONTAINER(logwin), 4); + + scrolledwindow = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_show(scrolledwindow); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS); + gtk_container_add(GTK_CONTAINER(logwin), scrolledwindow); + + widget = gtk_text_view_new(); + gtk_widget_show(widget); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(widget), GTK_WRAP_WORD_CHAR); + gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), FALSE); + gtk_text_view_set_monospace(GTK_TEXT_VIEW(widget), TRUE); + gtk_container_add(GTK_CONTAINER(scrolledwindow), widget); + logwin->log_view = widget; + logwin->log_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); + + g_signal_connect(G_OBJECT(logwin->log_view), "key-press-event", G_CALLBACK(remmina_log_on_keypress), (gpointer)logwin); +} + diff --git a/src/remmina_main.c b/src/remmina_main.c index d3662c065..a66724b7e 100644 --- a/src/remmina_main.c +++ b/src/remmina_main.c @@ -478,7 +478,7 @@ static void remmina_main_load_file_tree_callback(RemminaFile *remminafile, gpoin GtkTreeIter iter, child; GtkTreeStore *store; gboolean found; - gchar *datetime; + gchar *datetime = NULL; store = GTK_TREE_STORE(user_data); @@ -488,7 +488,7 @@ static void remmina_main_load_file_tree_callback(RemminaFile *remminafile, gpoin remmina_file_get_string(remminafile, "group")); datetime = remmina_file_get_datetime(remminafile); - REMMINA_DEBUG("The date is %s", datetime); + //REMMINA_DEBUG("The date is %s", datetime); gtk_tree_store_append(store, &child, (found ? &iter : NULL)); gtk_tree_store_set(store, &child, PROTOCOL_COLUMN, remmina_file_get_icon_name(remminafile), @@ -547,7 +547,7 @@ static gboolean remmina_main_filter_visible_func(GtkTreeModel *model, GtkTreeIte s = g_ascii_strdown(date ? date : "", -1); g_free(date); date = s; - result = (strstr(name, text) || strstr(group, text) || strstr(server, text) || strstr(plugin, text) || strstr(date, text)); + result = ( strstr(name, text) || strstr(group, text) || strstr(server, text) || strstr(plugin, text) || strstr(date, text)); } g_free(protocol); g_free(name); @@ -597,6 +597,8 @@ static void remmina_main_load_files() gint view_file_mode; char *save_selected_filename; GtkTreeModel *newmodel; + const gchar *neticon; + const gchar *connection_tooltip; save_selected_filename = g_strdup(remminamain->priv->selected_filename); remmina_main_save_expanded_group(); @@ -618,7 +620,14 @@ static void remmina_main_load_files() switch (view_file_mode) { case REMMINA_VIEW_FILE_TREE: /* Create new GtkTreeStore model */ - newmodel = GTK_TREE_MODEL(gtk_tree_store_new(7, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING)); + newmodel = GTK_TREE_MODEL(gtk_tree_store_new(7, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING)); /* Hide the Group column in the tree view mode */ gtk_tree_view_column_set_visible(remminamain->column_files_list_group, FALSE); /* Load groups first */ @@ -630,7 +639,14 @@ static void remmina_main_load_files() case REMMINA_VIEW_FILE_LIST: default: /* Create new GtkListStore model */ - newmodel = GTK_TREE_MODEL(gtk_list_store_new(7, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING)); + newmodel = GTK_TREE_MODEL(gtk_list_store_new(7, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING)); /* Show the Group column in the list view mode */ gtk_tree_view_column_set_visible(remminamain->column_files_list_group, TRUE); /* Load files list */ @@ -672,6 +688,26 @@ static void remmina_main_load_files() context_id = gtk_statusbar_get_context_id(remminamain->statusbar_main, "status"); gtk_statusbar_pop(remminamain->statusbar_main, context_id); gtk_statusbar_push(remminamain->statusbar_main, context_id, buf); + + if (remminamain->monitor->connected){ + neticon = g_strdup("network-transmit-receive-symbolic"); + connection_tooltip = g_strdup(_("Network status: fully online")); + } else { + neticon = g_strdup("network-offline-symbolic"); + connection_tooltip = g_strdup(_("Network status: offline")); + } + + if (GTK_IS_WIDGET(remminamain->network_icon)) + gtk_widget_destroy(remminamain->network_icon); + GIcon *icon = g_themed_icon_new (neticon); + remminamain->network_icon = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_BUTTON); + gtk_widget_set_tooltip_text (remminamain->network_icon, connection_tooltip); + + g_object_unref (icon); + + gtk_box_pack_start (GTK_BOX(remminamain->statusbar_main), remminamain->network_icon, FALSE, FALSE, 0); + gtk_widget_show (remminamain->network_icon); + } void remmina_main_load_files_cb(GtkEntry *entry, char *string, gpointer user_data) @@ -1356,6 +1392,9 @@ static void remmina_main_init(void) settings = gtk_settings_get_default(); g_object_set(settings, "gtk-application-prefer-dark-theme", remmina_pref.dark_theme, NULL); + REMMINA_DEBUG ("Initializing monitor"); + remminamain->monitor = remmina_network_monitor_new(); + remminamain->priv->expanded_group = remmina_string_array_new_from_string(remmina_pref.expanded_group); if (!kioskmode && kioskmode == FALSE) gtk_window_set_title(remminamain->window, _("Remmina Remote Desktop Client")); diff --git a/src/remmina_main.h b/src/remmina_main.h index 66115c0d2..e4b106f01 100644 --- a/src/remmina_main.h +++ b/src/remmina_main.h @@ -34,11 +34,13 @@ * */ -#include "remmina_string_array.h" - #pragma once #include "remmina_file.h" +#include "remmina_monitor.h" +#include <gtk/gtk.h> + +#include "remmina_string_array.h" typedef struct _RemminaMainPriv RemminaMainPriv; @@ -74,9 +76,11 @@ typedef struct _RemminaMain { GtkTreeViewColumn * column_files_list_plugin; GtkTreeViewColumn * column_files_list_date; GtkStatusbar * statusbar_main; + GtkWidget * network_icon; /* Non widget objects */ GtkAccelGroup * accelgroup_shortcuts; RemminaMainPriv * priv; + RemminaMonitor * monitor; } RemminaMain; struct _RemminaMainPriv { diff --git a/src/remmina_monitor.c b/src/remmina_monitor.c new file mode 100644 index 000000000..c6e9c8e4e --- /dev/null +++ b/src/remmina_monitor.c @@ -0,0 +1,223 @@ +/* + * Remmina - The GTK+ Remote Desktop Client + * Copyright (C) 2016-2021 Antenore Gatta + * + * 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. + * + */ + +#include "config.h" +#include "remmina_monitor.h" +#include "remmina_log.h" +#include "remmina_public.h" +#include "remmina/remmina_trace_calls.h" + +RemminaMonitor *rm_monitor; + +static void remmina_monitor_can_reach_cb (GNetworkMonitor *netmonitor, GAsyncResult *result, RemminaMonitor *monitor) +{ + g_autoptr (GError) error = NULL; + + gchar *status = NULL; + + gboolean is_reachable = g_network_monitor_can_reach_finish (netmonitor, result, &error); + + const gchar *addr_tostr = g_strdup(g_socket_connectable_to_string (monitor->addr)); + //gchar *value = (gchar *)g_hash_table_lookup (monitor->server_status, addr_tostr); + + if (is_reachable) { + + REMMINA_DEBUG ("Network object %s is reachable", g_socket_connectable_to_string (monitor->addr)); + status = g_strdup ("online"); + + } else { + + REMMINA_DEBUG ("Network object %s is not reachable", g_socket_connectable_to_string (monitor->addr)); + status = g_strdup ("offline"); + } + + if (g_hash_table_replace (monitor->server_status, g_strdup(addr_tostr), g_strdup(status))) { + REMMINA_DEBUG ("Inserting %s -> %s", addr_tostr, status); + } else { + REMMINA_DEBUG ("Replacing %s -> %s", addr_tostr, status); + } + + /* Cannot use remminafile here because is freed by remmina_file_manager_iterate */ + //if (remminafile) + //remmina_file_set_state_int (remminafile, "reachable", reachable); + g_free (status); +} + +gchar *remmina_monitor_can_reach(RemminaFile *remminafile, RemminaMonitor *monitor) +{ + TRACE_CALL(__func__); + + const gchar *server; + const gchar *ssh_tunnel_server; + const gchar *addr_tostr; + gchar *status = NULL; + gchar *ssh_tunnel_host, *srv_host; + gint netmonit, srv_port, ssh_tunnel_port; + const gchar *protocol; + gint default_port = 0; + + + if (!remminafile) { + status = g_strdup ("I/O Error"); + REMMINA_DEBUG (status); + return NULL; + } + + netmonit = remmina_file_get_int(remminafile, "enable-netmonit", FALSE); + + if (!netmonit) { + status = g_strdup ("Monitoring disabled"); + REMMINA_DEBUG (status); + return NULL; + } + + protocol = remmina_file_get_string (remminafile, "protocol"); + + if (protocol && protocol[0] != '\0') { + REMMINA_DEBUG ("Evaluating protocol %s for monitoring", protocol); + if (g_strcmp0("RDP", protocol) == 0) + default_port = 3389; + if (g_strcmp0("VNC", protocol) == 0) + default_port = 5900; + if (g_strcmp0("GVNC", protocol) == 0) + default_port = 5900; + if (g_strcmp0("SPICE", protocol) == 0) + default_port = 5900; + if (g_strcmp0("WWW", protocol) == 0) + default_port = 443; + if (g_strcmp0("X2GO", protocol) == 0) + default_port = 22; + if (g_strcmp0("SSH", protocol) == 0) + default_port = 22; + if (g_strcmp0("SFTP", protocol) == 0) + default_port = 22; + if (g_strcmp0("EXEC", protocol) == 0) + default_port = -1; + + if (default_port == 0) { + status = g_strdup ("Unknown protocol"); + REMMINA_DEBUG (status); + return NULL; + } + if (default_port < 0) { + status = g_strdup ("Cannot monitor"); + REMMINA_DEBUG (status); + return NULL; + } + + ssh_tunnel_server = remmina_file_get_string(remminafile, "ssh_tunnel_server"); + if (remmina_file_get_int(remminafile, "ssh_tunnel_enabled", FALSE)) { + remmina_public_get_server_port(ssh_tunnel_server, 22, &ssh_tunnel_host, &ssh_tunnel_port); + monitor->addr = g_network_address_new (ssh_tunnel_host, ssh_tunnel_port); + g_free(ssh_tunnel_host), ssh_tunnel_host = NULL; + } else { + server = remmina_file_get_string(remminafile, "server"); + remmina_public_get_server_port(server, default_port, &srv_host, &srv_port); + monitor->addr = g_network_address_new (srv_host, srv_port); + g_free(srv_host), srv_host = NULL; + } + addr_tostr = g_strdup(g_socket_connectable_to_string (monitor->addr)); + + REMMINA_DEBUG ("addr is %s", addr_tostr); + if (monitor->connected && netmonit) { + REMMINA_DEBUG ("Testing for %s", addr_tostr); + g_network_monitor_can_reach_async ( + monitor->netmonitor, + monitor->addr, + NULL, + (GAsyncReadyCallback) remmina_monitor_can_reach_cb, + monitor); + } + + + status = (gchar *)g_hash_table_lookup (monitor->server_status, addr_tostr); + //if (!status) + //g_hash_table_insert (monitor->server_status, g_strdup(addr_tostr), "offline"); + + } + + if (!status) { + return g_strdup(addr_tostr); + } else + return status; + + //g_free(ssh_tunnel_host), ssh_tunnel_host = NULL; + //g_free(srv_host), srv_host = NULL; + //g_free(dest), dest = NULL; + +} + +RemminaMonitor *remmina_network_monitor_new () +{ + TRACE_CALL(__func__); + + gboolean status; + + rm_monitor = g_new0(RemminaMonitor, 1); + + rm_monitor->netmonitor = g_network_monitor_get_default (); + + status = g_network_monitor_get_connectivity (rm_monitor->netmonitor); + + rm_monitor->server_status = g_hash_table_new_full( + g_str_hash, + g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)g_free); + + switch (status) + { + case G_NETWORK_CONNECTIVITY_LOCAL: + REMMINA_DEBUG ("G_NETWORK_CONNECTIVITY_LOCAL"); + rm_monitor->connected = FALSE; + break; + + case G_NETWORK_CONNECTIVITY_LIMITED: + REMMINA_DEBUG ("G_NETWORK_CONNECTIVITY_LIMITED"); + rm_monitor->connected = FALSE; + break; + + case G_NETWORK_CONNECTIVITY_PORTAL: + REMMINA_DEBUG ("G_NETWORK_CONNECTIVITY_PORTAL"); + rm_monitor->connected = FALSE; + break; + + case G_NETWORK_CONNECTIVITY_FULL: + REMMINA_DEBUG ("G_NETWORK_CONNECTIVITY_FULL"); + rm_monitor->connected = TRUE; + break; + } + + return rm_monitor; +} diff --git a/src/remmina_monitor.h b/src/remmina_monitor.h new file mode 100644 index 000000000..6694197af --- /dev/null +++ b/src/remmina_monitor.h @@ -0,0 +1,56 @@ +/* + * Remmina - The GTK+ Remote Desktop Client + * Copyright (C) 2016-2021 Antenore Gatta + * + * 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. + * + */ + +#pragma once + +#include <glib/gi18n.h> +#include <glib-object.h> +#include <gio/gio.h> + +#include "remmina_file.h" + +typedef struct _RemminaMonitor { + GNetworkMonitor * netmonitor; + gboolean connected; + GSocketConnectable * addr; + gboolean reachable; + GHashTable * server_status; +} RemminaMonitor; + +G_BEGIN_DECLS + +RemminaMonitor *remmina_network_monitor_new (); +gchar *remmina_monitor_can_reach(RemminaFile *remminafile, RemminaMonitor *monitor); + +G_END_DECLS diff --git a/src/remmina_ssh.c b/src/remmina_ssh.c index 116bf8153..f81d448ef 100644 --- a/src/remmina_ssh.c +++ b/src/remmina_ssh.c @@ -2363,7 +2363,7 @@ remmina_ssh_shell_thread(gpointer data) gint buf_len; gint len; gint i, ret; - const gchar *filename; + gchar *filename; const gchar *dir; const gchar *sshlogname; FILE *fp; @@ -2427,13 +2427,15 @@ remmina_ssh_shell_thread(gpointer data) REMMINA_DEBUG("Saving session log to %s", filename); fp = fopen(filename, "w"); } - + + g_free(filename); + REMMINA_DEBUG("Run_line: %s", shell->run_line); if (!shell->closed && shell->run_line && shell->run_line[0]) { LOCK_SSH(shell) //TODO: Confirm assumption - assuming null terminated gchar string - ssh_channel_write(channel, shell->run_line, (gint)strlen(shell->run_line)); - ssh_channel_write(channel, "\n", (gint)1); //TODO: Test this + ssh_channel_write(channel, shell->run_line, (gint)strlen(shell->run_line)); + ssh_channel_write(channel, "\n", (gint)1); //TODO: Test this UNLOCK_SSH(shell) REMMINA_DEBUG("Run_line written to channel"); } @@ -2455,7 +2457,7 @@ remmina_ssh_shell_thread(gpointer data) ssh_channel_write(channel, buf, len); UNLOCK_SSH(shell) } - + for (i = 0; i < 2; i++) { LOCK_SSH(shell) len = ssh_channel_poll(channel, i); diff --git a/src/remmina_ssh_plugin.c b/src/remmina_ssh_plugin.c index 9aad68cb4..89447e9f7 100644 --- a/src/remmina_ssh_plugin.c +++ b/src/remmina_ssh_plugin.c @@ -1216,7 +1216,7 @@ remmina_plugin_ssh_init(RemminaProtocolWidget *gp) const gchar *dir; const gchar *sshlogname; - const gchar *fp; + gchar *fp; GFile *rf = g_file_new_for_path(remminafile->filename); @@ -1234,6 +1234,7 @@ remmina_plugin_ssh_init(RemminaProtocolWidget *gp) fp = g_strconcat(dir, "/", sshlogname, NULL); gpdata->vte_session_file = g_file_new_for_path(fp); + g_free(fp); g_signal_connect(G_OBJECT(vte), "size-allocate", G_CALLBACK(remmina_plugin_ssh_on_size_allocate), gp); g_signal_connect(G_OBJECT(vte), "unrealize", G_CALLBACK(remmina_plugin_ssh_eof), gp); diff --git a/src/remmina_stats.c b/src/remmina_stats.c index ac6b16e51..fcdcefe25 100644 --- a/src/remmina_stats.c +++ b/src/remmina_stats.c @@ -38,6 +38,10 @@ * @author Antenore Gatta and Giovanni Panozzo * @date 12 Feb 2018 * + * Since October 29, 2021 data is not collected nor sent to remmina.org anymore. All the + * code intended to send data has been removed. The following documentation + * has to be kept for those with versions of Remmina older than 1.4.22. + * * When Remmina starts asks the user to share some usage statistics * with the Remmina developers. As per the opt-in model * (https://en.wikipedia.org/wiki/Opt-in_email), without the consent of the user, @@ -127,7 +131,7 @@ * - Protocols used * - Last time each protocol has been used (globally). * - * @see https://www.remmina.org/wp for more info. + * @see https://www.remmina.org for more info. */ @@ -168,48 +172,6 @@ struct ProfilesData { gchar datestr; }; -JsonNode *remmina_stats_get_uid() -{ - TRACE_CALL(__func__); - JsonNode *r; - GChecksum *chs; - const gchar *uname, *hname; - const gchar *uid_suffix; - gchar *uid_prefix; - gchar *uid; - - /** @warning this function is usually executed on a dedicated thread, - * not on the main thread - */ - - if (remmina_pref.periodic_usage_stats_uuid_prefix == NULL || remmina_pref.periodic_usage_stats_uuid_prefix[0] == 0) { - /* Generate a new UUID_PREFIX for this installation */ - uid_prefix = remmina_gen_random_uuid(); - if (remmina_pref.periodic_usage_stats_uuid_prefix) - g_free(remmina_pref.periodic_usage_stats_uuid_prefix); - remmina_pref.periodic_usage_stats_uuid_prefix = uid_prefix; - remmina_pref_save(); - } - - uname = g_get_user_name(); - hname = g_get_host_name(); - chs = g_checksum_new(G_CHECKSUM_SHA256); - g_checksum_update(chs, (const guchar*)uname, strlen(uname)); - g_checksum_update(chs, (const guchar*)hname, strlen(hname)); - uid_suffix = g_checksum_get_string(chs); - - uid = g_strdup_printf("%s-%.10s", remmina_pref.periodic_usage_stats_uuid_prefix, uid_suffix); - g_checksum_free(chs); - - r = json_node_alloc(); - json_node_init_string(r, uid); - - g_free(uid); - - return r; - -} - JsonNode *remmina_stats_get_os_info() { TRACE_CALL(__func__); @@ -836,8 +798,6 @@ JsonNode *remmina_stats_get_kiosk_mode() return r; } - - /** * Get all statistics in JSON format to send periodically to the PHP server. * The caller should free the returned buffer with g_free() @@ -854,10 +814,6 @@ JsonNode *remmina_stats_get_all() b = json_builder_new(); json_builder_begin_object(b); - n = remmina_stats_get_uid(); - json_builder_set_member_name(b, "UID"); - json_builder_add_value(b, n); - n = remmina_stats_get_version(); json_builder_set_member_name(b, "REMMINAVERSION"); json_builder_add_value(b, n); diff --git a/src/rmnews.c b/src/rmnews.c index 6fbe5ccf6..d723f1638 100644 --- a/src/rmnews.c +++ b/src/rmnews.c @@ -35,17 +35,17 @@ #include "config.h" #include "remmina/remmina_trace_calls.h" -#include <stdlib.h> -#include <stdio.h> -#include <gtk/gtk.h> -#include <gio/gio.h> +#include <fcntl.h> #include <gio/gdesktopappinfo.h> +#include <gio/gio.h> #include <glib/gi18n.h> -#include <libsoup/soup.h> #include <glib/gstdio.h> -#include <fcntl.h> -#include <sys/types.h> +#include <gtk/gtk.h> +#include <libsoup/soup.h> +#include <stdio.h> +#include <stdlib.h> #include <sys/stat.h> +#include <sys/types.h> #include <time.h> #include "remmina.h" @@ -56,8 +56,6 @@ #include "remmina_sodium.h" #include "remmina_utils.h" #include "remmina_scheduler.h" -#include "remmina_stats_sender.h" -#include "remmina_stats.h" #include "remmina_sysinfo.h" #include "rmnews.h" @@ -77,7 +75,6 @@ static RemminaNewsDialog *rmnews_news_dialog; #define GET_OBJ(object_name) gtk_builder_get_object(rmnews_news_dialog->builder, object_name) static SoupSession *session; -//static const gchar *rmnews_url = NULL; static const gchar *output_file_path = NULL; static @@ -106,24 +103,9 @@ void rmnews_news_switch_state_set_cb() if (rmnews_news_dialog->rmnews_news_switch && \ gtk_switch_get_active(rmnews_news_dialog->rmnews_news_switch)) { remmina_pref.periodic_news_permitted = TRUE; - if (remmina_pref_save()) - remmina_stats_sender_schedule(); - } else { - remmina_pref.periodic_news_permitted = FALSE; remmina_pref_save(); - } -} - -void rmnews_stats_switch_state_set_cb() -{ - TRACE_CALL(__func__); - if (rmnews_news_dialog->rmnews_stats_switch \ - && gtk_switch_get_active(rmnews_news_dialog->rmnews_stats_switch)) { - remmina_pref.periodic_usage_stats_permitted = TRUE; - if (remmina_pref_save()) - remmina_stats_sender_schedule(); } else { - remmina_pref.periodic_usage_stats_permitted = FALSE; + remmina_pref.periodic_news_permitted = FALSE; remmina_pref_save(); } } @@ -203,10 +185,6 @@ void rmnews_show_news(GtkWindow *parent) rmnews_news_dialog->rmnews_text_view = GTK_TEXT_VIEW(GET_OBJ("rmnews_text_view")); rmnews_news_dialog->rmnews_label = GTK_LABEL(GET_OBJ("rmnews_label")); - //rmnews_news_dialog->rmnews_stats_label = GTK_LABEL(GET_OBJ("rmnews_stats_label")); - rmnews_news_dialog->rmnews_stats_switch = GTK_SWITCH(GET_OBJ("rmnews_stats_switch")); - if (remmina_pref.periodic_usage_stats_permitted == 1) - gtk_switch_set_active(rmnews_news_dialog->rmnews_stats_switch, TRUE); rmnews_news_dialog->rmnews_defaultcl_label = GTK_LABEL(GET_OBJ("rmnews_defaultcl_label")); rmnews_news_dialog->rmnews_defaultcl_button = GTK_BUTTON(GET_OBJ("rmnews_defaultcl_switch")); rmnews_news_dialog->rmnews_news_switch = GTK_SWITCH(GET_OBJ("rmnews_news_switch")); @@ -450,7 +428,6 @@ void rmnews_get_news() int fd; gchar *uid; gchar mage[20], gcount[20]; - gboolean sa; struct stat sb; gchar *cachedir = g_build_path("/", g_get_user_cache_dir(), REMMINA_APP_ID, NULL); @@ -504,12 +481,6 @@ void rmnews_get_news() uid = rmnews_get_uid(); - sa = FALSE; - if (remmina_pref.periodic_usage_stats_permitted && - remmina_pref.periodic_usage_stats_uuid_prefix != NULL && - remmina_pref.periodic_usage_stats_uuid_prefix[0] != 0) - sa = TRUE; - if (stat("/etc/machine-id", &sb) == 0) sprintf(mage, "%ld", (long)(time(NULL) - sb.st_mtim.tv_sec)); else @@ -524,8 +495,7 @@ void rmnews_get_news() VERSION, "&uid=", uid, - "&sa=", - sa ? "1" : "0", + "&sa=0", "&mage=", mage, "&gcount=", |