diff options
author | Antenore Gatta (tmow) <antenore@simbiosi.org> | 2021-12-14 16:35:34 +0300 |
---|---|---|
committer | Antenore Gatta (tmow) <antenore@simbiosi.org> | 2021-12-14 16:35:34 +0300 |
commit | 162ea287e39f9e0319c038f1a82b22ab49455a37 (patch) | |
tree | ed91dfe843c554e09f8bc5c8f4f50b2c62f813ff | |
parent | 3939a7c8e27a0492e80a1d7e214654aeacd54ab5 (diff) |
Stats related code left behind since 1.4.22
-rw-r--r-- | src/rcw.c | 16 | ||||
-rw-r--r-- | src/remmina_pref.c | 19 | ||||
-rw-r--r-- | src/remmina_pref.h | 3 | ||||
-rw-r--r-- | src/remmina_pref_dialog.c | 4 | ||||
-rw-r--r-- | src/remmina_pref_dialog.h | 1 | ||||
-rw-r--r-- | src/remmina_stats_sender.c | 338 | ||||
-rw-r--r-- | src/remmina_stats_sender.h | 45 | ||||
-rw-r--r-- | src/rmnews.h | 2 |
8 files changed, 7 insertions, 421 deletions
@@ -2614,7 +2614,7 @@ static void rco_update_toolbar(RemminaConnectionObject *cnnobj) /* REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON */ toolitem = priv->toolitem_multimon; - if (toolitem != NULL) { + if (toolitem) { gint hasmultimon = remmina_protocol_widget_query_feature_by_type(REMMINA_PROTOCOL_WIDGET(cnnobj->proto), REMMINA_PROTOCOL_FEATURE_TYPE_MULTIMON); @@ -2622,12 +2622,12 @@ static void rco_update_toolbar(RemminaConnectionObject *cnnobj) gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem), remmina_file_get_int(cnnobj->remmina_file, "multimon", FALSE)); gtk_widget_set_sensitive(GTK_WIDGET(toolitem), hasmultimon); + } toolitem = priv->toolitem_grab; gtk_widget_set_sensitive(GTK_WIDGET(toolitem), cnnobj->connected); gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(toolitem), remmina_file_get_int(cnnobj->remmina_file, "keyboard_grab", FALSE)); - } toolitem = priv->toolitem_preferences; gtk_widget_set_sensitive(GTK_WIDGET(toolitem), cnnobj->connected); @@ -4172,13 +4172,11 @@ void rco_on_connect(RemminaProtocolWidget *gp, RemminaConnectionObject *cnnobj) */ if (remmina_file_get_filename(cnnobj->remmina_file) == NULL) remmina_pref_add_recent(remmina_file_get_string(cnnobj->remmina_file, "protocol"), - remmina_file_get_string(cnnobj->remmina_file, "server")); - if (remmina_pref.periodic_usage_stats_permitted) { - REMMINA_DEBUG("Stats are allowed, we save the last successful connection date"); - //remmina_file_set_string(cnnobj->remmina_file, "last_success", last_success); - remmina_file_state_last_success(cnnobj->remmina_file); - //REMMINA_DEBUG("Last connection made on %s.", last_success); - } + remmina_file_get_string(cnnobj->remmina_file, "server")); + REMMINA_DEBUG("We save the last successful connection date"); + //remmina_file_set_string(cnnobj->remmina_file, "last_success", last_success); + remmina_file_state_last_success(cnnobj->remmina_file); + //REMMINA_DEBUG("Last connection made on %s.", last_success); REMMINA_DEBUG("Saving credentials"); /* Save credentials */ diff --git a/src/remmina_pref.c b/src/remmina_pref.c index 9a9af01cc..680ea7a98 100644 --- a/src/remmina_pref.c +++ b/src/remmina_pref.c @@ -680,21 +680,6 @@ void remmina_pref_init(void) remmina_pref_file_load_colors(gkeyfile, &remmina_pref.color_pref); - if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL)) - remmina_pref.periodic_usage_stats_permitted = g_key_file_get_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL); - else - remmina_pref.periodic_usage_stats_permitted = FALSE; - - if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL)) - remmina_pref.periodic_usage_stats_last_sent = g_key_file_get_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL); - else - remmina_pref.periodic_usage_stats_last_sent = 0; - - if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix", NULL)) - remmina_pref.periodic_usage_stats_uuid_prefix = g_key_file_get_string(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix", NULL); - else - remmina_pref.periodic_usage_stats_uuid_prefix = NULL; - /** RMNEWS_ENABLE_NEWS is equal to 0 (FALSE) when compiled with -DWiTH_NEWS=OFF, * otherwise is value is 1 (TRUE), that is the default value */ @@ -877,10 +862,6 @@ gboolean remmina_pref_save(void) g_key_file_set_string(gkeyfile, "ssh_colors", "color14", remmina_pref.color_pref.color14 ? remmina_pref.color_pref.color14 : ""); g_key_file_set_string(gkeyfile, "ssh_colors", "color15", remmina_pref.color_pref.color15 ? remmina_pref.color_pref.color15 : ""); - g_key_file_set_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", remmina_pref.periodic_usage_stats_permitted); - g_key_file_set_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", remmina_pref.periodic_usage_stats_last_sent); - g_key_file_set_string(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix", - remmina_pref.periodic_usage_stats_uuid_prefix ? remmina_pref.periodic_usage_stats_uuid_prefix : ""); g_key_file_set_boolean(gkeyfile, "remmina_news", "periodic_news_permitted", remmina_pref.periodic_news_permitted); g_debug("(%s) - Setting periodic_rmnews_last_get to %ld", __func__, remmina_pref.periodic_rmnews_last_get); g_key_file_set_int64(gkeyfile, "remmina_news", "periodic_rmnews_last_get", remmina_pref.periodic_rmnews_last_get); diff --git a/src/remmina_pref.h b/src/remmina_pref.h index e93fd5c9b..10a37c060 100644 --- a/src/remmina_pref.h +++ b/src/remmina_pref.h @@ -211,9 +211,6 @@ typedef struct _RemminaPref { RemminaColorPref color_pref; /* Usage stats */ - gboolean periodic_usage_stats_permitted; - glong periodic_usage_stats_last_sent; - gchar * periodic_usage_stats_uuid_prefix; gchar * last_success; /* Remmina news */ diff --git a/src/remmina_pref_dialog.c b/src/remmina_pref_dialog.c index 609e9049c..15b8031c0 100644 --- a/src/remmina_pref_dialog.c +++ b/src/remmina_pref_dialog.c @@ -246,8 +246,6 @@ void remmina_pref_on_dialog_destroy(GtkWidget *widget, gpointer user_data) remmina_pref.hide_connection_toolbar = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(remmina_pref_dialog->checkbutton_appearance_hide_toolbar)); remmina_pref.hide_searchbar = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(remmina_pref_dialog->checkbutton_appearance_hide_searchbar)); - b = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_permit_send_stats)); - remmina_pref.periodic_usage_stats_permitted = b; b = gtk_switch_get_active(GTK_SWITCH(remmina_pref_dialog->switch_permit_news)); remmina_pref.periodic_news_permitted = b; @@ -497,7 +495,6 @@ static void remmina_pref_dialog_init(void) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remmina_pref_dialog->checkbutton_appearance_hide_toolbar), remmina_pref.hide_connection_toolbar); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remmina_pref_dialog->checkbutton_appearance_hide_searchbar), remmina_pref.hide_searchbar); - gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_permit_send_stats), remmina_pref.periodic_usage_stats_permitted); gtk_switch_set_active(GTK_SWITCH(remmina_pref_dialog->switch_permit_news), remmina_pref.periodic_news_permitted); g_snprintf(buf, sizeof(buf), "%i", remmina_pref.sshtunnel_port); @@ -715,7 +712,6 @@ GtkWidget* remmina_pref_dialog_new(gint default_tab, GtkWindow *parent) remmina_pref_dialog->checkbutton_appearance_show_tabs = GTK_CHECK_BUTTON(GET_OBJECT("checkbutton_appearance_show_tabs")); remmina_pref_dialog->checkbutton_appearance_hide_toolbar = GTK_CHECK_BUTTON(GET_OBJECT("checkbutton_appearance_hide_toolbar")); remmina_pref_dialog->checkbutton_appearance_hide_searchbar = GTK_CHECK_BUTTON(GET_OBJECT("checkbutton_appearance_hide_searchbar")); - remmina_pref_dialog->switch_permit_send_stats = GTK_SWITCH(GET_OBJECT("switch_permit_send_stats")); remmina_pref_dialog->switch_permit_news = GTK_SWITCH(GET_OBJECT("switch_permit_news")); gtk_widget_set_sensitive (GTK_WIDGET(remmina_pref_dialog->switch_permit_news), RMNEWS_ENABLE_NEWS); remmina_pref_dialog->comboboxtext_options_double_click = GTK_COMBO_BOX(GET_OBJECT("comboboxtext_options_double_click")); diff --git a/src/remmina_pref_dialog.h b/src/remmina_pref_dialog.h index 44112e28a..60223cac4 100644 --- a/src/remmina_pref_dialog.h +++ b/src/remmina_pref_dialog.h @@ -66,7 +66,6 @@ typedef struct _RemminaPrefDialog { GtkCheckButton * checkbutton_appearance_show_tabs; GtkCheckButton * checkbutton_appearance_hide_toolbar; GtkCheckButton * checkbutton_appearance_hide_searchbar; - GtkSwitch * switch_permit_send_stats; GtkSwitch * switch_permit_news; GtkComboBox * comboboxtext_options_double_click; GtkComboBox * comboboxtext_appearance_view_mode; diff --git a/src/remmina_stats_sender.c b/src/remmina_stats_sender.c deleted file mode 100644 index 35868348f..000000000 --- a/src/remmina_stats_sender.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Remmina - The GTK+ Remote Desktop Client - * Copyright (C) 2016-2021 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. - * - */ - -#include "config.h" -#include <gtk/gtk.h> -#include <string.h> -#include <libsoup/soup.h> -#include <openssl/rsa.h> -#include <openssl/pem.h> -#include <openssl/err.h> -#include "remmina_scheduler.h" -#include "remmina/remmina_trace_calls.h" -#include "remmina_log.h" -#include "remmina_stats.h" -#include "remmina_pref.h" - -#if !JSON_CHECK_VERSION(1, 2, 0) - #define json_node_unref(x) json_node_free(x) -#endif - -/* Timers */ -#define PERIODIC_CHECK_1ST_MS 60000 -#define PERIODIC_CHECK_INTERVAL_MS 1200000 - -#define PERIODIC_UPLOAD_INTERVAL_SEC 2678400 - -#define PERIODIC_UPLOAD_URL "https://www.remmina.org/stats/upload_stats.php" - - -//static gint periodic_check_source; -//static gint periodic_check_counter; - -static char *remmina_RSA_PubKey_v1 = - "-----BEGIN PUBLIC KEY-----\n" - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwuI8eOnDV2y9uPdhN+6Q\n" - "Cju8+YapN0wKlvwfy1ccQBS+4YnM7/+vzelOzLXJwWBDr/He7G5XEIzOcc9LZsRw\n" - "XYAoeB3+kP4OrNIVmKfxL7uijoh+79t3WpR8OOOTFDLmtk23tvdJVj+KfRpm0REK\n" - "BmdPHP8NpBzQElEDgXP9weHwQhPLB6MqpaJmfR4AqSumAcsukjbSaCWhqjO2rEiA\n" - "eXqJ0JE+PIe4WO1IBvKyYBYP3S77FEMJojkVWGVsjOUGe2VqpX02GaRajRkbqzNK\n" - "dGmLQt//kcCuPkiqm/qQQTZc0JJYUrmOjFJW9jODQKXHdZrSz8Xz5+v6VJ49v2TM\n" - "PwIDAQAB\n" - "-----END PUBLIC KEY-----\n"; - -typedef struct { - gboolean show_only; - JsonNode *statsroot; -} sc_tdata; - -static void soup_callback(SoupSession *session, SoupMessage *msg, gpointer user_data) -{ - TRACE_CALL(__func__); - gchar *s = (gchar*)user_data; - SoupBuffer *sb; - gboolean passed; - GDateTime *gdt; - gint64 unixts; - - g_free(s); - - if (msg->status_code != 200) { - REMMINA_DEBUG("HTTP status error sending stats: %d\n", msg->status_code); - return; - } - - gdt = g_date_time_new_now_utc(); - unixts = g_date_time_to_unix(gdt); - g_date_time_to_unix(gdt); - - passed = FALSE; - sb = soup_message_body_flatten(msg->response_body); - REMMINA_DEBUG("STATS script response: %.40s\n", sb->data); - if (strncmp(sb->data, "200 ", 4) != 0) { - REMMINA_DEBUG("STATS http upload error from server side script: %s\n", sb->data); - } else { - passed = TRUE; - } - soup_buffer_free(sb); - - if (passed) { - remmina_pref.periodic_usage_stats_last_sent = unixts; - remmina_pref_save(); - } - -} - -static gchar *rsa_encrypt_string(RSA *pubKey, const char *instr) -{ - TRACE_CALL(__func__); - /* Calls RSA_public_encrypt multiple times to encrypt instr. - * At the end, base64 encode the resulting buffer - * Return a buffer ptr. Use g_free() to deallocate it */ - - int rsaLen = RSA_size(pubKey); - int inLen = strlen(instr); - int remaining, r; - int blksz, maxblksz; - int ebufSize; - unsigned char *ebuf, *outptr; - gchar *enc; - - maxblksz = rsaLen - 12; - ebufSize = (((inLen - 1) / maxblksz) + 1) * rsaLen; - ebuf = g_malloc(ebufSize); - outptr = ebuf; - remaining = strlen(instr); - - while(remaining > 0) { - blksz = remaining > maxblksz ? maxblksz : remaining; - r = RSA_public_encrypt(blksz, - (const unsigned char *)instr, - outptr, - pubKey, RSA_PKCS1_PADDING); /* Our poor JS libraries only supports RSA_PKCS1_PADDING */ - if (r == -1 ) { - unsigned long e; - ERR_load_crypto_strings(); - e = ERR_get_error(); - g_print("Error RSA_public_encrypt(): %s - func: %s - reason: %s\n", ERR_lib_error_string(e), ERR_func_error_string(e), ERR_reason_error_string(e)); - g_free(ebuf); - ERR_free_strings(); - return NULL; - } - instr += blksz; - remaining -= blksz; - outptr += r; - } - - enc = g_base64_encode(ebuf, ebufSize); - g_free(ebuf); - - return enc; - - -} - -static gboolean remmina_stats_collector_done(gpointer data) -{ - TRACE_CALL(__func__); - JsonNode *n; - JsonGenerator *g; - gchar *unenc_s, *enc_s; - SoupSession *ss; - SoupMessage *msg; - JsonBuilder *b; - JsonObject *o; - BIO *pkbio; - RSA *pubkey; - gchar *uid; - sc_tdata *sctdata; - - sctdata = (sc_tdata *)data; - if (sctdata == NULL) - return G_SOURCE_REMOVE; - - n = sctdata->statsroot; - if (n == NULL) { - g_free(data); - return G_SOURCE_REMOVE; - } - - if ((o = json_node_get_object(n)) == NULL) { - g_free(data); - return G_SOURCE_REMOVE; - } - - uid = g_strdup(json_object_get_string_member(o, "UID")); - - g = json_generator_new(); - json_generator_set_root(g, n); - json_node_unref(n); - unenc_s = json_generator_to_data(g, NULL); // unenc_s=serialized stats - REMMINA_DEBUG("STATS upload: JSON data%s\n", unenc_s); - g_object_unref(g); - - /* Now encrypt "s" with remminastats public key */ - - pkbio = BIO_new_mem_buf(remmina_RSA_PubKey_v1, -1); - pubkey = PEM_read_bio_RSA_PUBKEY(pkbio, NULL, NULL, NULL); - if (pubkey == NULL) { - ERR_load_crypto_strings(); - unsigned long e; - e = ERR_get_error(); - g_print("Failure in PEM_read_bio_RSAPublicKey: %s - func: %s - reason: %s\n", ERR_lib_error_string(e), ERR_func_error_string(e), ERR_reason_error_string(e)); - g_print("%s\n", ERR_error_string( e, NULL )); - BIO_free(pkbio); - g_free(unenc_s); - ERR_free_strings(); - g_free(data); - g_free(uid); - return G_SOURCE_REMOVE; - } - - enc_s = rsa_encrypt_string(pubkey, unenc_s); - - g_free(unenc_s); - BIO_free(pkbio); - - - /* Create new json encrypted object */ - - b = json_builder_new(); - json_builder_begin_object(b); - json_builder_set_member_name(b, "keyversion"); - json_builder_add_int_value(b, 1); - json_builder_set_member_name(b, "encdata"); - json_builder_add_string_value(b, enc_s); - json_builder_set_member_name(b, "UID"); - json_builder_add_string_value(b, uid); - json_builder_end_object(b); - n = json_builder_get_root(b); - g_object_unref(b); - - g_free(uid); - g_free(enc_s); - - if (!sctdata->show_only) { - - g = json_generator_new(); - json_generator_set_root(g, n); - enc_s = json_generator_to_data(g, NULL); // unenc_s=serialized stats - g_object_unref(g); - - ss = soup_session_new(); - msg = soup_message_new("POST", PERIODIC_UPLOAD_URL); - soup_message_set_request(msg, "application/json", - SOUP_MEMORY_COPY, enc_s, strlen(enc_s)); - soup_session_queue_message(ss, msg, soup_callback, enc_s); - - REMMINA_DEBUG("STATS upload: Starting upload to url %s\n", PERIODIC_UPLOAD_URL); - } - - json_node_unref(n); - g_free(data); - - return G_SOURCE_REMOVE; -} - - -static gpointer remmina_stats_collector(gpointer data) -{ - TRACE_CALL(__func__); - JsonNode *n; - sc_tdata *sctdata; - - sctdata = (sc_tdata *)data; - n = remmina_stats_get_all(); - - /* stats collecting is done. Notify main thread calling - * remmina_stats_collector_done() */ - sctdata->statsroot = n; - g_idle_add(remmina_stats_collector_done, sctdata); - - return NULL; -} - -void remmina_stats_sender_send(gboolean show_only) -{ - TRACE_CALL(__func__); - - sc_tdata *sctdata; - - sctdata = g_malloc(sizeof(sc_tdata)); - sctdata->show_only = show_only; - - g_thread_new("stats_collector", remmina_stats_collector, (gpointer)sctdata); - -} - -gboolean remmina_stat_sender_can_send() -{ - if (remmina_pref.periodic_usage_stats_permitted && remmina_pref_save()) - return TRUE; - else - return FALSE; -} - -static gboolean remmina_stats_sender_periodic_check(gpointer user_data) -{ - TRACE_CALL(__func__); - GDateTime *gdt; - gint64 unixts; - glong next; - - gdt = g_date_time_new_now_utc(); - unixts = g_date_time_to_unix(gdt); - g_date_time_to_unix(gdt); - - if (!remmina_stat_sender_can_send()) - return G_SOURCE_REMOVE; - - /* Calculate "next" upload time based on last sent time */ - next = remmina_pref.periodic_usage_stats_last_sent + PERIODIC_UPLOAD_INTERVAL_SEC; - /* If current time is after "next" or clock is going back (but > 1/1/2018), then do send stats */ - if (unixts > next || (unixts < remmina_pref.periodic_usage_stats_last_sent && unixts > 1514764800)) { - remmina_stats_sender_send(FALSE); - } - - return G_SOURCE_CONTINUE; -} - -void remmina_stats_sender_schedule() -{ - TRACE_CALL(__func__); - remmina_scheduler_setup(remmina_stats_sender_periodic_check, - NULL, - PERIODIC_CHECK_1ST_MS, - PERIODIC_CHECK_INTERVAL_MS); -} diff --git a/src/remmina_stats_sender.h b/src/remmina_stats_sender.h deleted file mode 100644 index 465e94eec..000000000 --- a/src/remmina_stats_sender.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Remmina - The GTK+ Remote Desktop Client - * Copyright (C) 2016-2021 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. - * - */ - -#pragma once - -G_BEGIN_DECLS - -void remmina_stats_sender_schedule(void); -gboolean remmina_stat_sender_can_send(void); - -/* This is only for testing purposes: force a SEND */ -void remmina_stats_sender_send(gboolean show_only); - -G_END_DECLS diff --git a/src/rmnews.h b/src/rmnews.h index 149a62e57..bf7e1f184 100644 --- a/src/rmnews.h +++ b/src/rmnews.h @@ -39,8 +39,6 @@ typedef struct _RemminaNewsDialog { GtkTextView * rmnews_text_view; GtkLabel * rmnews_label; GtkButton * rmnews_button_close; - //GtkLabel * rmnews_stats_label; - GtkSwitch * rmnews_stats_switch; GtkLabel * rmnews_defaultcl_label; GtkButton * rmnews_defaultcl_button; GtkSwitch * rmnews_news_switch; |