1 /*
2 * Remmina - The GTK+ Remote Desktop Client
3 * Copyright (C) 2009-2011 Vic Lee
4 * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
5 * Copyright (C) 2016-2021 Antenore Gatta, Giovanni Panozzo
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
21 *
22 * In addition, as a special exception, the copyright holders give
23 * permission to link the code of portions of this program with the
24 * OpenSSL library under certain conditions as described in each
25 * individual source file, and distribute linked combinations
26 * including the two.
27 * You must obey the GNU General Public License in all respects
28 * for all of the code used other than OpenSSL. * If you modify
29 * file(s) with this exception, you may extend this exception to your
30 * version of the file(s), but you are not obligated to do so. * If you
31 * do not wish to do so, delete this exception statement from your
32 * version. * If you delete this exception statement from all source
33 * files in the program, then also delete it here.
34 *
35 */
36
37 #include "config.h"
38
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <sys/time.h>
43 #include <sys/utsname.h>
44
45 #include <glib/gstdio.h>
46 #include <gdk/gdkkeysyms.h>
47 #include <gtk/gtk.h>
48
49 #include "remmina_sodium.h"
50
51 #include "remmina_public.h"
52 #include "remmina_string_array.h"
53 #include "remmina_pref.h"
54 #include "remmina/remmina_trace_calls.h"
55
56 const gchar *default_resolutions = "640x480,800x600,1024x768,1152x864,1280x960,1400x1050";
57 const gchar *default_keystrokes = "Send hello world§hello world\\n";
58
59 gchar *remmina_keymap_file;
60 static GHashTable *remmina_keymap_table = NULL;
61
62 /* We could customize this further if there are more requirements */
63 static const gchar *default_keymap_data = "# Please check gdk/gdkkeysyms.h for a full list of all key names or hex key values\n"
64 "\n"
65 "[Map Meta Keys]\n"
66 "Super_L = Meta_L\n"
67 "Super_R = Meta_R\n"
68 "Meta_L = Super_L\n"
69 "Meta_R = Super_R\n";
70
remmina_pref_gen_secret(void)71 static void remmina_pref_gen_secret(void)
72 {
73 TRACE_CALL(__func__);
74 guchar s[32];
75 gint i;
76 GKeyFile *gkeyfile;
77 g_autofree gchar *content = NULL;
78 gsize length;
79
80 for (i = 0; i < 32; i++)
81 s[i] = (guchar)(randombytes_uniform(257));
82 remmina_pref.secret = g_base64_encode(s, 32);
83
84 gkeyfile = g_key_file_new();
85 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
86 g_key_file_set_string(gkeyfile, "remmina_pref", "secret", remmina_pref.secret);
87 content = g_key_file_to_data(gkeyfile, &length, NULL);
88 g_file_set_contents(remmina_pref_file, content, length, NULL);
89
90 g_key_file_free(gkeyfile);
91 }
92
remmina_pref_get_keyval_from_str(const gchar * str)93 static guint remmina_pref_get_keyval_from_str(const gchar *str)
94 {
95 TRACE_CALL(__func__);
96 guint k;
97
98 if (!str)
99 return 0;
100
101 k = gdk_keyval_from_name(str);
102 if (!k)
103 if (sscanf(str, "%x", &k) < 1)
104 k = 0;
105 return k;
106 }
107
remmina_pref_init_keymap(void)108 static void remmina_pref_init_keymap(void)
109 {
110 TRACE_CALL(__func__);
111 GKeyFile *gkeyfile;
112 gchar **groups;
113 gchar **gptr;
114 gchar **keys;
115 gchar **kptr;
116 gsize nkeys;
117 g_autofree gchar *value = NULL;
118 guint *table;
119 guint *tableptr;
120 guint k1, k2;
121
122 if (remmina_keymap_table)
123 g_hash_table_destroy(remmina_keymap_table);
124 remmina_keymap_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
125
126 gkeyfile = g_key_file_new();
127 if (!g_key_file_load_from_file(gkeyfile, remmina_keymap_file, G_KEY_FILE_NONE, NULL)) {
128 if (!g_key_file_load_from_data(gkeyfile, default_keymap_data, strlen(default_keymap_data), G_KEY_FILE_NONE,
129 NULL)) {
130 g_print("Failed to initialize keymap table\n");
131 g_key_file_free(gkeyfile);
132 return;
133 }
134 }
135
136 groups = g_key_file_get_groups(gkeyfile, NULL);
137 gptr = groups;
138 while (*gptr) {
139 keys = g_key_file_get_keys(gkeyfile, *gptr, &nkeys, NULL);
140 table = g_new0(guint, nkeys * 2 + 1);
141 g_hash_table_insert(remmina_keymap_table, g_strdup(*gptr), table);
142
143 kptr = keys;
144 tableptr = table;
145 while (*kptr) {
146 k1 = remmina_pref_get_keyval_from_str(*kptr);
147 if (k1) {
148 value = g_key_file_get_string(gkeyfile, *gptr, *kptr, NULL);
149 k2 = remmina_pref_get_keyval_from_str(value);
150 *tableptr++ = k1;
151 *tableptr++ = k2;
152 }
153 kptr++;
154 }
155 g_strfreev(keys);
156 gptr++;
157 }
158 g_strfreev(groups);
159 g_key_file_free(gkeyfile);
160 }
161
162 /** @todo remmina_pref_file_do_copy and remmina_file_manager_do_copy to remmina_files_copy */
remmina_pref_file_do_copy(const char * src_path,const char * dst_path)163 static gboolean remmina_pref_file_do_copy(const char *src_path, const char *dst_path)
164 {
165 GFile *src = g_file_new_for_path(src_path), *dst = g_file_new_for_path(dst_path);
166 /* We don’t overwrite the target if it exists, because overwrite is not set */
167 const gboolean ok = g_file_copy(src, dst, G_FILE_COPY_NONE, NULL, NULL, NULL, NULL);
168
169 g_object_unref(dst);
170 g_object_unref(src);
171
172 return ok;
173 }
174
remmina_pref_file_load_colors(GKeyFile * gkeyfile,RemminaColorPref * color_pref)175 void remmina_pref_file_load_colors(GKeyFile *gkeyfile, RemminaColorPref *color_pref)
176 {
177 const struct {
178 const char * name;
179 char ** setting;
180 char * fallback;
181 } colors[] = {
182 { "background", &color_pref->background, "#d5ccba" },
183 { "cursor", &color_pref->cursor, "#45373c" },
184 { "cursor_foreground", &color_pref->cursor_foreground, "#d5ccba" },
185 { "highlight", &color_pref->highlight, "#45373c" },
186 { "highlight_foreground", &color_pref->highlight_foreground, "#d5ccba" },
187 { "colorBD", &color_pref->colorBD, "#45373c" },
188 { "foreground", &color_pref->foreground, "#45373c" },
189 { "color0", &color_pref->color0, "#20111b" },
190 { "color1", &color_pref->color1, "#be100e" },
191 { "color2", &color_pref->color2, "#858162" },
192 { "color3", &color_pref->color3, "#eaa549" },
193 { "color4", &color_pref->color4, "#426a79" },
194 { "color5", &color_pref->color5, "#97522c" },
195 { "color6", &color_pref->color6, "#989a9c" },
196 { "color7", &color_pref->color7, "#968c83" },
197 { "color8", &color_pref->color8, "#5e5252" },
198 { "color9", &color_pref->color9, "#be100e" },
199 { "color10", &color_pref->color10, "#858162" },
200 { "color11", &color_pref->color11, "#eaa549" },
201 { "color12", &color_pref->color12, "#426a79" },
202 { "color13", &color_pref->color13, "#97522c" },
203 { "color14", &color_pref->color14, "#989a9c" },
204 { "color15", &color_pref->color15, "#d5ccba" },
205 };
206
207 int i;
208
209 for (i = 0; i < (sizeof(colors) / sizeof(colors[0])); i++) {
210 if (g_key_file_has_key(gkeyfile, "ssh_colors", colors[i].name, NULL))
211 *colors[i].setting = g_key_file_get_string(gkeyfile, "ssh_colors", colors[i].name,
212 NULL);
213 else
214 *colors[i].setting = colors[i].fallback;
215 }
216 }
217
remmina_pref_init(void)218 void remmina_pref_init(void)
219 {
220 TRACE_CALL(__func__);
221 GKeyFile *gkeyfile;
222 gchar *remmina_dir;
223 const gchar *filename = "remmina.pref";
224 const gchar *colors_filename = "remmina.colors";
225 g_autofree gchar *remmina_colors_file = NULL;
226 GDir *dir;
227 const gchar *legacy = ".remmina";
228 int i;
229
230 remmina_dir = g_build_path("/", g_get_user_config_dir(), "remmina", NULL);
231 /* Create the XDG_CONFIG_HOME directory */
232 g_mkdir_with_parents(remmina_dir, 0750);
233
234 g_free(remmina_dir), remmina_dir = NULL;
235 /* Legacy ~/.remmina we copy the existing remmina.pref file inside
236 * XDG_CONFIG_HOME */
237 remmina_dir = g_build_path("/", g_get_home_dir(), legacy, NULL);
238 if (g_file_test(remmina_dir, G_FILE_TEST_IS_DIR)) {
239 dir = g_dir_open(remmina_dir, 0, NULL);
240 remmina_pref_file_do_copy(
241 g_build_path("/", remmina_dir, filename, NULL),
242 g_build_path("/", g_get_user_config_dir(),
243 "remmina", filename, NULL));
244 }
245
246 /* /usr/local/etc/remmina */
247 const gchar *const *dirs = g_get_system_config_dirs();
248
249 g_free(remmina_dir), remmina_dir = NULL;
250 for (i = 0; dirs[i] != NULL; ++i) {
251 remmina_dir = g_build_path("/", dirs[i], "remmina", NULL);
252 if (g_file_test(remmina_dir, G_FILE_TEST_IS_DIR)) {
253 dir = g_dir_open(remmina_dir, 0, NULL);
254 while ((filename = g_dir_read_name(dir)) != NULL) {
255 remmina_pref_file_do_copy(
256 g_build_path("/", remmina_dir, filename, NULL),
257 g_build_path("/", g_get_user_config_dir(),
258 "remmina", filename, NULL));
259 }
260 g_free(remmina_dir), remmina_dir = NULL;
261 }
262 }
263
264 /* The last case we use the home ~/.config/remmina */
265 if (remmina_dir != NULL)
266 g_free(remmina_dir), remmina_dir = NULL;
267 remmina_dir = g_build_path("/", g_get_user_config_dir(),
268 "remmina", NULL);
269
270 remmina_pref_file = g_strdup_printf("%s/remmina.pref", remmina_dir);
271 /* remmina.colors */
272 remmina_colors_file = g_strdup_printf("%s/%s", remmina_dir, colors_filename);
273
274 remmina_keymap_file = g_strdup_printf("%s/remmina.keymap", remmina_dir);
275
276 gkeyfile = g_key_file_new();
277
278 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
279
280 if (g_key_file_has_key(gkeyfile, "remmina_pref", "save_view_mode", NULL))
281 remmina_pref.save_view_mode = g_key_file_get_boolean(gkeyfile, "remmina_pref", "save_view_mode", NULL);
282 else
283 remmina_pref.save_view_mode = TRUE;
284
285 if (g_key_file_has_key(gkeyfile, "remmina_pref", "use_master_password", NULL))
286 remmina_pref.use_master_password = g_key_file_get_boolean(gkeyfile, "remmina_pref", "use_master_password", NULL);
287 else
288 remmina_pref.use_master_password = FALSE;
289
290 if (g_key_file_has_key(gkeyfile, "remmina_pref", "unlock_timeout", NULL))
291 remmina_pref.unlock_timeout = g_key_file_get_integer(gkeyfile, "remmina_pref", "unlock_timeout", NULL);
292 else
293 remmina_pref.unlock_timeout = 0;
294
295 if (g_key_file_has_key(gkeyfile, "remmina_pref", "unlock_password", NULL))
296 remmina_pref.unlock_password = g_key_file_get_string(gkeyfile, "remmina_pref", "unlock_password", NULL);
297 else
298 remmina_pref.unlock_password = g_strdup("");
299
300 if (g_key_file_has_key(gkeyfile, "remmina_pref", "trust_all", NULL))
301 remmina_pref.trust_all = g_key_file_get_boolean(gkeyfile, "remmina_pref", "trust_all", NULL);
302 else
303 remmina_pref.trust_all = FALSE;
304
305 if (g_key_file_has_key(gkeyfile, "remmina_pref", "fullscreen_on_auto", NULL))
306 remmina_pref.fullscreen_on_auto = g_key_file_get_boolean(gkeyfile, "remmina_pref", "fullscreen_on_auto", NULL);
307 else
308 remmina_pref.fullscreen_on_auto = TRUE;
309
310 if (g_key_file_has_key(gkeyfile, "remmina_pref", "floating_toolbar_placement", NULL))
311 remmina_pref.floating_toolbar_placement = g_key_file_get_integer(gkeyfile, "remmina_pref", "floating_toolbar_placement", NULL);
312 else
313 remmina_pref.floating_toolbar_placement = FLOATING_TOOLBAR_PLACEMENT_TOP;
314
315 if (g_key_file_has_key(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", NULL))
316 remmina_pref.prevent_snap_welcome_message = g_key_file_get_boolean(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", NULL);
317 else
318 remmina_pref.prevent_snap_welcome_message = FALSE;
319
320 if (g_key_file_has_key(gkeyfile, "remmina_pref", "last_quickconnect_protocol", NULL))
321 remmina_pref.last_quickconnect_protocol = g_key_file_get_string(gkeyfile, "remmina_pref", "last_quickconnect_protocol", NULL);
322 else
323 remmina_pref.last_quickconnect_protocol = g_strdup("");
324
325 if (g_key_file_has_key(gkeyfile, "remmina_pref", "toolbar_placement", NULL))
326 remmina_pref.toolbar_placement = g_key_file_get_integer(gkeyfile, "remmina_pref", "toolbar_placement", NULL);
327 else
328 remmina_pref.toolbar_placement = TOOLBAR_PLACEMENT_LEFT;
329
330 if (g_key_file_has_key(gkeyfile, "remmina_pref", "always_show_tab", NULL))
331 remmina_pref.always_show_tab = g_key_file_get_boolean(gkeyfile, "remmina_pref", "always_show_tab", NULL);
332 else
333 remmina_pref.always_show_tab = TRUE;
334
335 if (g_key_file_has_key(gkeyfile, "remmina_pref", "hide_connection_toolbar", NULL))
336 remmina_pref.hide_connection_toolbar = g_key_file_get_boolean(gkeyfile, "remmina_pref",
337 "hide_connection_toolbar", NULL);
338 else
339 remmina_pref.hide_connection_toolbar = FALSE;
340
341 if (g_key_file_has_key(gkeyfile, "remmina_pref", "hide_searchbar", NULL))
342 remmina_pref.hide_searchbar = g_key_file_get_boolean(gkeyfile, "remmina_pref",
343 "hide_searchbar", NULL);
344 else
345 remmina_pref.hide_searchbar = FALSE;
346
347 if (g_key_file_has_key(gkeyfile, "remmina_pref", "default_action", NULL))
348 remmina_pref.default_action = g_key_file_get_integer(gkeyfile, "remmina_pref", "default_action", NULL);
349 else
350 remmina_pref.default_action = REMMINA_ACTION_CONNECT;
351
352 if (g_key_file_has_key(gkeyfile, "remmina_pref", "scale_quality", NULL))
353 remmina_pref.scale_quality = g_key_file_get_integer(gkeyfile, "remmina_pref", "scale_quality", NULL);
354 else
355 remmina_pref.scale_quality = GDK_INTERP_HYPER;
356
357 if (g_key_file_has_key(gkeyfile, "remmina_pref", "hide_toolbar", NULL))
358 remmina_pref.hide_toolbar = g_key_file_get_boolean(gkeyfile, "remmina_pref", "hide_toolbar", NULL);
359 else
360 remmina_pref.hide_toolbar = FALSE;
361
362 if (g_key_file_has_key(gkeyfile, "remmina_pref", "small_toolbutton", NULL))
363 remmina_pref.small_toolbutton = g_key_file_get_boolean(gkeyfile, "remmina_pref", "small_toolbutton", NULL);
364 else
365 remmina_pref.small_toolbutton = FALSE;
366
367 if (g_key_file_has_key(gkeyfile, "remmina_pref", "view_file_mode", NULL))
368 remmina_pref.view_file_mode = g_key_file_get_integer(gkeyfile, "remmina_pref", "view_file_mode", NULL);
369 else
370 remmina_pref.view_file_mode = REMMINA_VIEW_FILE_LIST;
371
372 if (g_key_file_has_key(gkeyfile, "remmina_pref", "resolutions", NULL))
373 remmina_pref.resolutions = g_key_file_get_string(gkeyfile, "remmina_pref", "resolutions", NULL);
374 else
375 remmina_pref.resolutions = g_strdup(default_resolutions);
376
377 if (g_key_file_has_key(gkeyfile, "remmina_pref", "keystrokes", NULL))
378 remmina_pref.keystrokes = g_key_file_get_string(gkeyfile, "remmina_pref", "keystrokes", NULL);
379 else
380 remmina_pref.keystrokes = g_strdup(default_keystrokes);
381
382 if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_width", NULL))
383 remmina_pref.main_width = MAX(600, g_key_file_get_integer(gkeyfile, "remmina_pref", "main_width", NULL));
384 else
385 remmina_pref.main_width = 600;
386
387 if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_height", NULL))
388 remmina_pref.main_height = MAX(400, g_key_file_get_integer(gkeyfile, "remmina_pref", "main_height", NULL));
389 else
390 remmina_pref.main_height = 400;
391
392 if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_maximize", NULL))
393 remmina_pref.main_maximize = g_key_file_get_boolean(gkeyfile, "remmina_pref", "main_maximize", NULL);
394 else
395 remmina_pref.main_maximize = FALSE;
396
397 if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_sort_column_id", NULL))
398 remmina_pref.main_sort_column_id = g_key_file_get_integer(gkeyfile, "remmina_pref", "main_sort_column_id",
399 NULL);
400 else
401 remmina_pref.main_sort_column_id = 1;
402
403 if (g_key_file_has_key(gkeyfile, "remmina_pref", "main_sort_order", NULL))
404 remmina_pref.main_sort_order = g_key_file_get_integer(gkeyfile, "remmina_pref", "main_sort_order", NULL);
405 else
406 remmina_pref.main_sort_order = 0;
407
408 if (g_key_file_has_key(gkeyfile, "remmina_pref", "expanded_group", NULL))
409 remmina_pref.expanded_group = g_key_file_get_string(gkeyfile, "remmina_pref", "expanded_group", NULL);
410 else
411 remmina_pref.expanded_group = g_strdup("");
412
413 if (g_key_file_has_key(gkeyfile, "remmina_pref", "toolbar_pin_down", NULL))
414 remmina_pref.toolbar_pin_down = g_key_file_get_boolean(gkeyfile, "remmina_pref", "toolbar_pin_down", NULL);
415 else
416 remmina_pref.toolbar_pin_down = FALSE;
417
418 if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_loglevel", NULL))
419 remmina_pref.ssh_loglevel = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_loglevel", NULL);
420 else
421 remmina_pref.ssh_loglevel = DEFAULT_SSH_LOGLEVEL;
422
423 if (g_key_file_has_key(gkeyfile, "remmina_pref", "deny_screenshot_clipboard", NULL))
424 remmina_pref.deny_screenshot_clipboard = g_key_file_get_boolean(gkeyfile, "remmina_pref", "deny_screenshot_clipboard", NULL);
425 else
426 remmina_pref.deny_screenshot_clipboard = TRUE;
427
428 if (g_key_file_has_key(gkeyfile, "remmina_pref", "datadir_path", NULL))
429 remmina_pref.datadir_path = g_key_file_get_string(gkeyfile, "remmina_pref", "datadir_path", NULL);
430 else
431 remmina_pref.datadir_path = g_strdup("");
432
433 if (g_key_file_has_key(gkeyfile, "remmina_pref", "remmina_file_name", NULL))
434 remmina_pref.remmina_file_name = g_key_file_get_string(gkeyfile, "remmina_pref", "remmina_file_name", NULL);
435 else
436 remmina_pref.remmina_file_name = g_strdup("%G_%P_%N_%h");
437
438 if (g_key_file_has_key(gkeyfile, "remmina_pref", "screenshot_path", NULL)) {
439 remmina_pref.screenshot_path = g_key_file_get_string(gkeyfile, "remmina_pref", "screenshot_path", NULL);
440 } else {
441 remmina_pref.screenshot_path = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES);
442 if (remmina_pref.screenshot_path == NULL)
443 remmina_pref.screenshot_path = g_get_home_dir();
444 }
445
446 if (g_key_file_has_key(gkeyfile, "remmina_pref", "screenshot_name", NULL))
447 remmina_pref.screenshot_name = g_key_file_get_string(gkeyfile, "remmina_pref", "screenshot_name", NULL);
448 else
449 remmina_pref.screenshot_name = g_strdup("remmina_%p_%h_%Y%m%d-%H%M%S");
450
451 if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_parseconfig", NULL))
452 remmina_pref.ssh_parseconfig = g_key_file_get_boolean(gkeyfile, "remmina_pref", "ssh_parseconfig", NULL);
453 else
454 remmina_pref.ssh_parseconfig = DEFAULT_SSH_PARSECONFIG;
455
456 if (g_key_file_has_key(gkeyfile, "remmina_pref", "sshtunnel_port", NULL))
457 remmina_pref.sshtunnel_port = g_key_file_get_integer(gkeyfile, "remmina_pref", "sshtunnel_port", NULL);
458 else
459 remmina_pref.sshtunnel_port = DEFAULT_SSHTUNNEL_PORT;
460
461 if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_keepidle", NULL))
462 remmina_pref.ssh_tcp_keepidle = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepidle", NULL);
463 else
464 remmina_pref.ssh_tcp_keepidle = SSH_SOCKET_TCP_KEEPIDLE;
465
466 if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_keepintvl", NULL))
467 remmina_pref.ssh_tcp_keepintvl = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepintvl", NULL);
468 else
469 remmina_pref.ssh_tcp_keepintvl = SSH_SOCKET_TCP_KEEPINTVL;
470
471 if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_keepcnt", NULL))
472 remmina_pref.ssh_tcp_keepcnt = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepcnt", NULL);
473 else
474 remmina_pref.ssh_tcp_keepcnt = SSH_SOCKET_TCP_KEEPCNT;
475
476 if (g_key_file_has_key(gkeyfile, "remmina_pref", "ssh_tcp_usrtimeout", NULL))
477 remmina_pref.ssh_tcp_usrtimeout = g_key_file_get_integer(gkeyfile, "remmina_pref", "ssh_tcp_usrtimeout", NULL);
478 else
479 remmina_pref.ssh_tcp_usrtimeout = SSH_SOCKET_TCP_USER_TIMEOUT;
480
481 if (g_key_file_has_key(gkeyfile, "remmina_pref", "applet_new_ontop", NULL))
482 remmina_pref.applet_new_ontop = g_key_file_get_boolean(gkeyfile, "remmina_pref", "applet_new_ontop", NULL);
483 else
484 remmina_pref.applet_new_ontop = FALSE;
485
486 if (g_key_file_has_key(gkeyfile, "remmina_pref", "applet_hide_count", NULL))
487 remmina_pref.applet_hide_count = g_key_file_get_boolean(gkeyfile, "remmina_pref", "applet_hide_count", NULL);
488 else
489 remmina_pref.applet_hide_count = FALSE;
490
491 if (g_key_file_has_key(gkeyfile, "remmina_pref", "applet_enable_avahi", NULL))
492 remmina_pref.applet_enable_avahi = g_key_file_get_boolean(gkeyfile, "remmina_pref", "applet_enable_avahi",
493 NULL);
494 else
495 remmina_pref.applet_enable_avahi = FALSE;
496
497 if (g_key_file_has_key(gkeyfile, "remmina_pref", "disable_tray_icon", NULL))
498 remmina_pref.disable_tray_icon = g_key_file_get_boolean(gkeyfile, "remmina_pref", "disable_tray_icon", NULL);
499 else
500 remmina_pref.disable_tray_icon = FALSE;
501
502 if (g_key_file_has_key(gkeyfile, "remmina_pref", "dark_theme", NULL))
503 remmina_pref.dark_theme = g_key_file_get_boolean(gkeyfile, "remmina_pref", "dark_theme", NULL);
504 else
505 remmina_pref.dark_theme = FALSE;
506
507 if (g_key_file_has_key(gkeyfile, "remmina_pref", "grab_color_switch", NULL))
508 remmina_pref.grab_color_switch = g_key_file_get_boolean(gkeyfile, "remmina_pref", "grab_color_switch", NULL);
509 else
510 remmina_pref.grab_color_switch = FALSE;
511
512 if (g_key_file_has_key(gkeyfile, "remmina_pref", "grab_color", NULL))
513 remmina_pref.grab_color = g_key_file_get_string(gkeyfile, "remmina_pref", "grab_color", NULL);
514 else
515 remmina_pref.grab_color = "#00ff00";
516
517 if (g_key_file_has_key(gkeyfile, "remmina_pref", "recent_maximum", NULL))
518 remmina_pref.recent_maximum = g_key_file_get_integer(gkeyfile, "remmina_pref", "recent_maximum", NULL);
519 else
520 remmina_pref.recent_maximum = 10;
521
522 if (g_key_file_has_key(gkeyfile, "remmina_pref", "default_mode", NULL))
523 remmina_pref.default_mode = g_key_file_get_integer(gkeyfile, "remmina_pref", "default_mode", NULL);
524 else
525 remmina_pref.default_mode = 0;
526
527 if (g_key_file_has_key(gkeyfile, "remmina_pref", "tab_mode", NULL))
528 remmina_pref.tab_mode = g_key_file_get_integer(gkeyfile, "remmina_pref", "tab_mode", NULL);
529 else
530 remmina_pref.tab_mode = 0;
531
532 if (g_key_file_has_key(gkeyfile, "remmina_pref", "fullscreen_toolbar_visibility", NULL))
533 remmina_pref.fullscreen_toolbar_visibility = g_key_file_get_integer(gkeyfile, "remmina_pref", "fullscreen_toolbar_visibility", NULL);
534 else
535 remmina_pref.fullscreen_toolbar_visibility = FLOATING_TOOLBAR_VISIBILITY_PEEKING;
536
537 if (g_key_file_has_key(gkeyfile, "remmina_pref", "auto_scroll_step", NULL))
538 remmina_pref.auto_scroll_step = g_key_file_get_integer(gkeyfile, "remmina_pref", "auto_scroll_step", NULL);
539 else
540 remmina_pref.auto_scroll_step = 10;
541
542 if (g_key_file_has_key(gkeyfile, "remmina_pref", "hostkey", NULL))
543 remmina_pref.hostkey = g_key_file_get_integer(gkeyfile, "remmina_pref", "hostkey", NULL);
544 else
545 remmina_pref.hostkey = GDK_KEY_Control_R;
546
547 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_fullscreen", NULL))
548 remmina_pref.shortcutkey_fullscreen = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_fullscreen",
549 NULL);
550 else
551 remmina_pref.shortcutkey_fullscreen = GDK_KEY_f;
552
553 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_autofit", NULL))
554 remmina_pref.shortcutkey_autofit = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_autofit",
555 NULL);
556 else
557 remmina_pref.shortcutkey_autofit = GDK_KEY_1;
558
559 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_nexttab", NULL))
560 remmina_pref.shortcutkey_nexttab = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_nexttab",
561 NULL);
562 else
563 remmina_pref.shortcutkey_nexttab = GDK_KEY_Right;
564
565 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_prevtab", NULL))
566 remmina_pref.shortcutkey_prevtab = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_prevtab",
567 NULL);
568 else
569 remmina_pref.shortcutkey_prevtab = GDK_KEY_Left;
570
571 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_scale", NULL))
572 remmina_pref.shortcutkey_scale = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_scale", NULL);
573 else
574 remmina_pref.shortcutkey_scale = GDK_KEY_s;
575
576 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_viewonly", NULL))
577 remmina_pref.shortcutkey_viewonly = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_viewonly", NULL);
578 else
579 remmina_pref.shortcutkey_viewonly = GDK_KEY_m;
580
581 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_multimon", NULL))
582 remmina_pref.shortcutkey_multimon = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_multimon", NULL);
583 else
584 remmina_pref.shortcutkey_multimon = GDK_KEY_Page_Up;
585
586 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_grab", NULL))
587 remmina_pref.shortcutkey_grab = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_grab", NULL);
588 else
589 remmina_pref.shortcutkey_grab = GDK_KEY_Control_R;
590
591 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_minimize", NULL))
592 remmina_pref.shortcutkey_minimize = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize", NULL);
593 else
594 remmina_pref.shortcutkey_minimize = GDK_KEY_F9;
595
596 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_screenshot", NULL))
597 remmina_pref.shortcutkey_screenshot = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_screenshot", NULL);
598 else
599 remmina_pref.shortcutkey_screenshot = GDK_KEY_F12;
600
601 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_disconnect", NULL))
602 remmina_pref.shortcutkey_disconnect = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_disconnect",
603 NULL);
604 else
605 remmina_pref.shortcutkey_disconnect = GDK_KEY_F4;
606
607 if (g_key_file_has_key(gkeyfile, "remmina_pref", "shortcutkey_toolbar", NULL))
608 remmina_pref.shortcutkey_toolbar = g_key_file_get_integer(gkeyfile, "remmina_pref", "shortcutkey_toolbar",
609 NULL);
610 else
611 remmina_pref.shortcutkey_toolbar = GDK_KEY_t;
612
613 if (g_key_file_has_key(gkeyfile, "remmina_pref", "secret", NULL))
614 remmina_pref.secret = g_key_file_get_string(gkeyfile, "remmina_pref", "secret", NULL);
615 else
616 remmina_pref.secret = NULL;
617
618 if (g_key_file_has_key(gkeyfile, "remmina_pref", "uid", NULL))
619 remmina_pref.uid = g_key_file_get_string(gkeyfile, "remmina_pref", "uid", NULL);
620 else
621 remmina_pref.uid = NULL;
622
623 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_font", NULL))
624 remmina_pref.vte_font = g_key_file_get_string(gkeyfile, "remmina_pref", "vte_font", NULL);
625 else
626 remmina_pref.vte_font = 0;
627
628 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_allow_bold_text", NULL))
629 remmina_pref.vte_allow_bold_text = g_key_file_get_boolean(gkeyfile, "remmina_pref", "vte_allow_bold_text",
630 NULL);
631 else
632 remmina_pref.vte_allow_bold_text = TRUE;
633
634 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_lines", NULL))
635 remmina_pref.vte_lines = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_lines", NULL);
636 else
637 remmina_pref.vte_lines = 512;
638
639 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_copy", NULL))
640 remmina_pref.vte_shortcutkey_copy = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_copy",
641 NULL);
642 else
643 remmina_pref.vte_shortcutkey_copy = GDK_KEY_c;
644
645 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_paste", NULL))
646 remmina_pref.vte_shortcutkey_paste = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_paste",
647 NULL);
648 else
649 remmina_pref.vte_shortcutkey_paste = GDK_KEY_v;
650
651 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_select_all", NULL))
652 remmina_pref.vte_shortcutkey_select_all = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_select_all",
653 NULL);
654 else
655 remmina_pref.vte_shortcutkey_select_all = GDK_KEY_a;
656
657 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_increase_font", NULL))
658 remmina_pref.vte_shortcutkey_increase_font = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_increase_font",
659 NULL);
660 else
661 remmina_pref.vte_shortcutkey_increase_font = GDK_KEY_Page_Up;
662
663 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_decrease_font", NULL))
664 remmina_pref.vte_shortcutkey_decrease_font = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_decrease_font",
665 NULL);
666 else
667 remmina_pref.vte_shortcutkey_decrease_font = GDK_KEY_Page_Down;
668
669 if (g_key_file_has_key(gkeyfile, "remmina_pref", "vte_shortcutkey_search_text", NULL))
670 remmina_pref.vte_shortcutkey_search_text = g_key_file_get_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_search_text",
671 NULL);
672 else
673 remmina_pref.vte_shortcutkey_search_text = GDK_KEY_g;
674
675
676 remmina_pref_file_load_colors(gkeyfile, &remmina_pref.color_pref);
677
678 if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL))
679 remmina_pref.periodic_usage_stats_permitted = g_key_file_get_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", NULL);
680 else
681 remmina_pref.periodic_usage_stats_permitted = FALSE;
682
683 if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL))
684 remmina_pref.periodic_usage_stats_last_sent = g_key_file_get_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", NULL);
685 else
686 remmina_pref.periodic_usage_stats_last_sent = 0;
687
688 if (g_key_file_has_key(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix", NULL))
689 remmina_pref.periodic_usage_stats_uuid_prefix = g_key_file_get_string(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix", NULL);
690 else
691 remmina_pref.periodic_usage_stats_uuid_prefix = NULL;
692
693 /** RMNEWS_ENABLE_NEWS is equal to 0 (FALSE) when compiled with -DWiTH_NEWS=OFF,
694 * otherwise is value is 1 (TRUE), that is the default value
695 */
696 if (RMNEWS_ENABLE_NEWS == 0)
697 remmina_pref.periodic_news_permitted = RMNEWS_ENABLE_NEWS;
698 else if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_news_permitted", NULL))
699 remmina_pref.periodic_news_permitted = g_key_file_get_boolean(gkeyfile, "remmina_news", "periodic_news_permitted", NULL);
700 else
701 remmina_pref.periodic_news_permitted = RMNEWS_ENABLE_NEWS;
702
703
704 if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_last_get", NULL)) {
705 remmina_pref.periodic_rmnews_last_get = g_key_file_get_int64(gkeyfile, "remmina_news", "periodic_rmnews_last_get", NULL);
706 g_debug("(%s) - periodic_rmnews_last_get set to %ld", __func__, remmina_pref.periodic_rmnews_last_get);
707 } else {
708 remmina_pref.periodic_rmnews_last_get = 0;
709 g_debug("(%s) - periodic_rmnews_last_get set to 0", __func__);
710 }
711
712 if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_get_count", NULL))
713 remmina_pref.periodic_rmnews_get_count = g_key_file_get_int64(gkeyfile, "remmina_news", "periodic_rmnews_get_count", NULL);
714 else
715 remmina_pref.periodic_rmnews_get_count = 0;
716
717 if (g_key_file_has_key(gkeyfile, "remmina_news", "periodic_rmnews_uuid_prefix", NULL))
718 remmina_pref.periodic_rmnews_uuid_prefix = g_key_file_get_string(gkeyfile, "remmina_news", "periodic_rmnews_uuid_prefix", NULL);
719 else
720 remmina_pref.periodic_rmnews_uuid_prefix = NULL;
721
722 /* If we have a color scheme file, we switch to it, GIO will merge it in the
723 * remmina.pref file */
724 if (g_file_test(remmina_colors_file, G_FILE_TEST_IS_REGULAR)) {
725 g_key_file_load_from_file(gkeyfile, remmina_colors_file, G_KEY_FILE_NONE, NULL);
726 g_remove(remmina_colors_file);
727 }
728
729 /* Default settings */
730 if (!g_key_file_has_key(gkeyfile, "remmina", "name", NULL)) {
731 g_key_file_set_string(gkeyfile, "remmina", "name", "");
732 g_key_file_set_integer(gkeyfile, "remmina", "ignore-tls-errors", 1);
733 g_key_file_set_integer(gkeyfile, "remmina", "enable-plugins", 1);
734 remmina_pref_save();
735 }
736
737 g_key_file_free(gkeyfile);
738
739 if (remmina_pref.secret == NULL)
740 remmina_pref_gen_secret();
741
742 remmina_pref_init_keymap();
743 }
744
remmina_pref_is_rw(void)745 gboolean remmina_pref_is_rw(void)
746 {
747 TRACE_CALL(__func__);
748 if (access(remmina_pref_file, W_OK) == 0)
749 return TRUE;
750 else
751 return FALSE;
752 return FALSE;
753 }
754
remmina_pref_save(void)755 gboolean remmina_pref_save(void)
756 {
757 TRACE_CALL(__func__);
758
759 if (remmina_pref_is_rw() == FALSE) {
760 g_debug("remmina.pref is not writable, returning");
761 return FALSE;
762 }
763 GKeyFile *gkeyfile;
764 GError *error = NULL;
765 g_autofree gchar *content = NULL;
766 gsize length;
767
768 gkeyfile = g_key_file_new();
769
770 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
771
772 g_key_file_set_string(gkeyfile, "remmina_pref", "datadir_path", remmina_pref.datadir_path);
773 g_key_file_set_string(gkeyfile, "remmina_pref", "remmina_file_name", remmina_pref.remmina_file_name);
774 g_key_file_set_string(gkeyfile, "remmina_pref", "screenshot_path", remmina_pref.screenshot_path);
775 g_key_file_set_string(gkeyfile, "remmina_pref", "screenshot_name", remmina_pref.screenshot_name);
776 g_key_file_set_boolean(gkeyfile, "remmina_pref", "deny_screenshot_clipboard", remmina_pref.deny_screenshot_clipboard);
777 g_key_file_set_boolean(gkeyfile, "remmina_pref", "save_view_mode", remmina_pref.save_view_mode);
778 #if SODIUM_VERSION_INT >= 90200
779 g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_master_password", remmina_pref.use_master_password);
780 g_key_file_set_integer(gkeyfile, "remmina_pref", "unlock_timeout", remmina_pref.unlock_timeout);
781 g_key_file_set_string(gkeyfile, "remmina_pref", "unlock_password", remmina_pref.unlock_password);
782 #else
783 g_key_file_set_boolean(gkeyfile, "remmina_pref", "use_master_password", FALSE);
784 g_key_file_set_integer(gkeyfile, "remmina_pref", "unlock_timeout", 0);
785 g_key_file_set_string(gkeyfile, "remmina_pref", "unlock_password", g_strdup(""));
786 #endif
787 g_key_file_set_boolean(gkeyfile, "remmina_pref", "trust_all", remmina_pref.trust_all);
788 g_key_file_set_integer(gkeyfile, "remmina_pref", "floating_toolbar_placement", remmina_pref.floating_toolbar_placement);
789 g_key_file_set_integer(gkeyfile, "remmina_pref", "toolbar_placement", remmina_pref.toolbar_placement);
790 g_key_file_set_boolean(gkeyfile, "remmina_pref", "prevent_snap_welcome_message", remmina_pref.prevent_snap_welcome_message);
791 g_key_file_set_string(gkeyfile, "remmina_pref", "last_quickconnect_protocol", remmina_pref.last_quickconnect_protocol);
792 g_key_file_set_boolean(gkeyfile, "remmina_pref", "fullscreen_on_auto", remmina_pref.fullscreen_on_auto);
793 g_key_file_set_boolean(gkeyfile, "remmina_pref", "always_show_tab", remmina_pref.always_show_tab);
794 g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_connection_toolbar", remmina_pref.hide_connection_toolbar);
795 g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_searchbar", remmina_pref.hide_searchbar);
796 g_key_file_set_integer(gkeyfile, "remmina_pref", "default_action", remmina_pref.default_action);
797 g_key_file_set_integer(gkeyfile, "remmina_pref", "scale_quality", remmina_pref.scale_quality);
798 g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_loglevel", remmina_pref.ssh_loglevel);
799 g_key_file_set_boolean(gkeyfile, "remmina_pref", "ssh_parseconfig", remmina_pref.ssh_parseconfig);
800 g_key_file_set_boolean(gkeyfile, "remmina_pref", "hide_toolbar", remmina_pref.hide_toolbar);
801 g_key_file_set_boolean(gkeyfile, "remmina_pref", "small_toolbutton", remmina_pref.small_toolbutton);
802 g_key_file_set_integer(gkeyfile, "remmina_pref", "view_file_mode", remmina_pref.view_file_mode);
803 g_key_file_set_string(gkeyfile, "remmina_pref", "resolutions", remmina_pref.resolutions);
804 g_key_file_set_string(gkeyfile, "remmina_pref", "keystrokes", remmina_pref.keystrokes);
805 g_key_file_set_integer(gkeyfile, "remmina_pref", "main_width", remmina_pref.main_width);
806 g_key_file_set_integer(gkeyfile, "remmina_pref", "main_height", remmina_pref.main_height);
807 g_key_file_set_boolean(gkeyfile, "remmina_pref", "main_maximize", remmina_pref.main_maximize);
808 g_key_file_set_integer(gkeyfile, "remmina_pref", "main_sort_column_id", remmina_pref.main_sort_column_id);
809 g_key_file_set_integer(gkeyfile, "remmina_pref", "main_sort_order", remmina_pref.main_sort_order);
810 g_key_file_set_string(gkeyfile, "remmina_pref", "expanded_group", remmina_pref.expanded_group);
811 g_key_file_set_boolean(gkeyfile, "remmina_pref", "toolbar_pin_down", remmina_pref.toolbar_pin_down);
812 g_key_file_set_integer(gkeyfile, "remmina_pref", "sshtunnel_port", remmina_pref.sshtunnel_port);
813 g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepidle", remmina_pref.ssh_tcp_keepidle);
814 g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepintvl", remmina_pref.ssh_tcp_keepintvl);
815 g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_keepcnt", remmina_pref.ssh_tcp_keepcnt);
816 g_key_file_set_integer(gkeyfile, "remmina_pref", "ssh_tcp_usrtimeout", remmina_pref.ssh_tcp_usrtimeout);
817 g_key_file_set_boolean(gkeyfile, "remmina_pref", "applet_new_ontop", remmina_pref.applet_new_ontop);
818 g_key_file_set_boolean(gkeyfile, "remmina_pref", "applet_hide_count", remmina_pref.applet_hide_count);
819 g_key_file_set_boolean(gkeyfile, "remmina_pref", "applet_enable_avahi", remmina_pref.applet_enable_avahi);
820 g_key_file_set_boolean(gkeyfile, "remmina_pref", "disable_tray_icon", remmina_pref.disable_tray_icon);
821 g_key_file_set_boolean(gkeyfile, "remmina_pref", "dark_theme", remmina_pref.dark_theme);
822 g_key_file_set_integer(gkeyfile, "remmina_pref", "recent_maximum", remmina_pref.recent_maximum);
823 g_key_file_set_integer(gkeyfile, "remmina_pref", "default_mode", remmina_pref.default_mode);
824 g_key_file_set_integer(gkeyfile, "remmina_pref", "tab_mode", remmina_pref.tab_mode);
825 g_key_file_set_integer(gkeyfile, "remmina_pref", "fullscreen_toolbar_visibility", remmina_pref.fullscreen_toolbar_visibility);
826 g_key_file_set_integer(gkeyfile, "remmina_pref", "auto_scroll_step", remmina_pref.auto_scroll_step);
827 g_key_file_set_integer(gkeyfile, "remmina_pref", "hostkey", remmina_pref.hostkey);
828 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_fullscreen", remmina_pref.shortcutkey_fullscreen);
829 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_autofit", remmina_pref.shortcutkey_autofit);
830 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_nexttab", remmina_pref.shortcutkey_nexttab);
831 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_prevtab", remmina_pref.shortcutkey_prevtab);
832 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_scale", remmina_pref.shortcutkey_scale);
833 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_grab", remmina_pref.shortcutkey_grab);
834 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_multimon", remmina_pref.shortcutkey_multimon);
835 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_viewonly", remmina_pref.shortcutkey_viewonly);
836 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_screenshot", remmina_pref.shortcutkey_screenshot);
837 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_minimize", remmina_pref.shortcutkey_minimize);
838 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_disconnect", remmina_pref.shortcutkey_disconnect);
839 g_key_file_set_integer(gkeyfile, "remmina_pref", "shortcutkey_toolbar", remmina_pref.shortcutkey_toolbar);
840 g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_copy", remmina_pref.vte_shortcutkey_copy);
841 g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_paste", remmina_pref.vte_shortcutkey_paste);
842 g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_select_all", remmina_pref.vte_shortcutkey_select_all);
843 g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_increase_font", remmina_pref.vte_shortcutkey_increase_font);
844 g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_decrease_font", remmina_pref.vte_shortcutkey_decrease_font);
845 g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_shortcutkey_search_text", remmina_pref.vte_shortcutkey_search_text);
846 g_key_file_set_string(gkeyfile, "remmina_pref", "vte_font", remmina_pref.vte_font ? remmina_pref.vte_font : "");
847 g_key_file_set_string(gkeyfile, "remmina_pref", "grab_color", remmina_pref.grab_color ? remmina_pref.grab_color : "");
848 g_key_file_set_boolean(gkeyfile, "remmina_pref", "grab_color_switch", remmina_pref.grab_color_switch);
849 g_key_file_set_boolean(gkeyfile, "remmina_pref", "vte_allow_bold_text", remmina_pref.vte_allow_bold_text);
850 g_key_file_set_integer(gkeyfile, "remmina_pref", "vte_lines", remmina_pref.vte_lines);
851 g_key_file_set_string(gkeyfile, "ssh_colors", "background", remmina_pref.color_pref.background ? remmina_pref.color_pref.background : "");
852 g_key_file_set_string(gkeyfile, "ssh_colors", "cursor", remmina_pref.color_pref.cursor ? remmina_pref.color_pref.cursor : "");
853 g_key_file_set_string(gkeyfile, "ssh_colors", "cursor_foreground", remmina_pref.color_pref.cursor_foreground ? remmina_pref.color_pref.cursor_foreground : "");
854 g_key_file_set_string(gkeyfile, "ssh_colors", "highlight", remmina_pref.color_pref.highlight ? remmina_pref.color_pref.highlight : "");
855 g_key_file_set_string(gkeyfile, "ssh_colors", "highlight_foreground", remmina_pref.color_pref.highlight_foreground ? remmina_pref.color_pref.highlight_foreground : "");
856 g_key_file_set_string(gkeyfile, "ssh_colors", "colorBD", remmina_pref.color_pref.colorBD ? remmina_pref.color_pref.colorBD : "");
857 g_key_file_set_string(gkeyfile, "ssh_colors", "foreground", remmina_pref.color_pref.foreground ? remmina_pref.color_pref.foreground : "");
858 g_key_file_set_string(gkeyfile, "ssh_colors", "color0", remmina_pref.color_pref.color0 ? remmina_pref.color_pref.color0 : "");
859 g_key_file_set_string(gkeyfile, "ssh_colors", "color1", remmina_pref.color_pref.color1 ? remmina_pref.color_pref.color1 : "");
860 g_key_file_set_string(gkeyfile, "ssh_colors", "color2", remmina_pref.color_pref.color2 ? remmina_pref.color_pref.color2 : "");
861 g_key_file_set_string(gkeyfile, "ssh_colors", "color3", remmina_pref.color_pref.color3 ? remmina_pref.color_pref.color3 : "");
862 g_key_file_set_string(gkeyfile, "ssh_colors", "color4", remmina_pref.color_pref.color4 ? remmina_pref.color_pref.color4 : "");
863 g_key_file_set_string(gkeyfile, "ssh_colors", "color5", remmina_pref.color_pref.color5 ? remmina_pref.color_pref.color5 : "");
864 g_key_file_set_string(gkeyfile, "ssh_colors", "color6", remmina_pref.color_pref.color6 ? remmina_pref.color_pref.color6 : "");
865 g_key_file_set_string(gkeyfile, "ssh_colors", "color7", remmina_pref.color_pref.color7 ? remmina_pref.color_pref.color7 : "");
866 g_key_file_set_string(gkeyfile, "ssh_colors", "color8", remmina_pref.color_pref.color8 ? remmina_pref.color_pref.color8 : "");
867 g_key_file_set_string(gkeyfile, "ssh_colors", "color9", remmina_pref.color_pref.color9 ? remmina_pref.color_pref.color9 : "");
868 g_key_file_set_string(gkeyfile, "ssh_colors", "color10", remmina_pref.color_pref.color10 ? remmina_pref.color_pref.color10 : "");
869 g_key_file_set_string(gkeyfile, "ssh_colors", "color11", remmina_pref.color_pref.color11 ? remmina_pref.color_pref.color11 : "");
870 g_key_file_set_string(gkeyfile, "ssh_colors", "color12", remmina_pref.color_pref.color12 ? remmina_pref.color_pref.color12 : "");
871 g_key_file_set_string(gkeyfile, "ssh_colors", "color13", remmina_pref.color_pref.color13 ? remmina_pref.color_pref.color13 : "");
872 g_key_file_set_string(gkeyfile, "ssh_colors", "color14", remmina_pref.color_pref.color14 ? remmina_pref.color_pref.color14 : "");
873 g_key_file_set_string(gkeyfile, "ssh_colors", "color15", remmina_pref.color_pref.color15 ? remmina_pref.color_pref.color15 : "");
874
875 g_key_file_set_boolean(gkeyfile, "usage_stats", "periodic_usage_stats_permitted", remmina_pref.periodic_usage_stats_permitted);
876 g_key_file_set_int64(gkeyfile, "usage_stats", "periodic_usage_stats_last_sent", remmina_pref.periodic_usage_stats_last_sent);
877 g_key_file_set_string(gkeyfile, "usage_stats", "periodic_usage_stats_uuid_prefix",
878 remmina_pref.periodic_usage_stats_uuid_prefix ? remmina_pref.periodic_usage_stats_uuid_prefix : "");
879 g_key_file_set_boolean(gkeyfile, "remmina_news", "periodic_news_permitted", remmina_pref.periodic_news_permitted);
880 g_debug("(%s) - Setting periodic_rmnews_last_get to %ld", __func__, remmina_pref.periodic_rmnews_last_get);
881 g_key_file_set_int64(gkeyfile, "remmina_news", "periodic_rmnews_last_get", remmina_pref.periodic_rmnews_last_get);
882 g_key_file_set_integer(gkeyfile, "remmina_news", "periodic_rmnews_get_count", remmina_pref.periodic_rmnews_get_count);
883 g_key_file_set_string(gkeyfile, "remmina_news", "periodic_rmnews_uuid_prefix",
884 remmina_pref.periodic_rmnews_uuid_prefix ? remmina_pref.periodic_rmnews_uuid_prefix : "");
885
886 /* Default settings */
887 g_key_file_set_string(gkeyfile, "remmina", "name", "");
888 g_key_file_set_integer(gkeyfile, "remmina", "ignore-tls-errors", 1);
889
890 content = g_key_file_to_data(gkeyfile, &length, NULL);
891 g_file_set_contents(remmina_pref_file, content, length, &error);
892
893 if (error != NULL) {
894 g_warning("remmina_pref_save error: %s", error->message);
895 g_clear_error(&error);
896 g_key_file_free(gkeyfile);
897 return FALSE;
898 }
899 g_key_file_free(gkeyfile);
900 return TRUE;
901 }
902
remmina_pref_add_recent(const gchar * protocol,const gchar * server)903 void remmina_pref_add_recent(const gchar *protocol, const gchar *server)
904 {
905 TRACE_CALL(__func__);
906 RemminaStringArray *array;
907 GKeyFile *gkeyfile;
908 gchar key[20];
909 g_autofree gchar *val = NULL;
910 g_autofree gchar *content = NULL;
911 gsize length;
912
913 if (remmina_pref.recent_maximum <= 0 || server == NULL || server[0] == 0)
914 return;
915
916 /* Load original value into memory */
917 gkeyfile = g_key_file_new();
918
919 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
920
921 g_snprintf(key, sizeof(key), "recent_%s", protocol);
922 array = remmina_string_array_new_from_allocated_string(g_key_file_get_string(gkeyfile, "remmina_pref", key, NULL));
923
924 /* Add the new value */
925 remmina_string_array_remove(array, server);
926 while (array->len >= remmina_pref.recent_maximum)
927 remmina_string_array_remove_index(array, 0);
928 remmina_string_array_add(array, server);
929
930 /* Save */
931 val = remmina_string_array_to_string(array);
932 g_key_file_set_string(gkeyfile, "remmina_pref", key, val);
933
934 content = g_key_file_to_data(gkeyfile, &length, NULL);
935 g_file_set_contents(remmina_pref_file, content, length, NULL);
936
937 g_key_file_free(gkeyfile);
938 }
939
940 gchar *
remmina_pref_get_recent(const gchar * protocol)941 remmina_pref_get_recent(const gchar *protocol)
942 {
943 TRACE_CALL(__func__);
944 GKeyFile *gkeyfile;
945 gchar key[20];
946 gchar *val = NULL;
947
948 gkeyfile = g_key_file_new();
949
950 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
951
952 g_snprintf(key, sizeof(key), "recent_%s", protocol);
953 val = g_key_file_get_string(gkeyfile, "remmina_pref", key, NULL);
954
955 g_key_file_free(gkeyfile);
956
957 return val;
958 }
959
remmina_pref_clear_recent(void)960 void remmina_pref_clear_recent(void)
961 {
962 TRACE_CALL(__func__);
963 GKeyFile *gkeyfile;
964 gchar **keys;
965 gint i;
966 g_autofree gchar *content = NULL;
967 gsize length;
968
969 gkeyfile = g_key_file_new();
970
971 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
972 keys = g_key_file_get_keys(gkeyfile, "remmina_pref", NULL, NULL);
973 if (keys) {
974 for (i = 0; keys[i]; i++)
975 if (strncmp(keys[i], "recent_", 7) == 0)
976 g_key_file_set_string(gkeyfile, "remmina_pref", keys[i], "");
977 g_strfreev(keys);
978 }
979
980 content = g_key_file_to_data(gkeyfile, &length, NULL);
981 g_file_set_contents(remmina_pref_file, content, length, NULL);
982
983 g_key_file_free(gkeyfile);
984 }
985
remmina_pref_keymap_get_keyval(const gchar * keymap,guint keyval)986 guint remmina_pref_keymap_get_keyval(const gchar *keymap, guint keyval)
987 {
988 TRACE_CALL(__func__);
989 guint *table;
990 gint i;
991
992 if (!keymap || keymap[0] == '\0')
993 return keyval;
994
995 table = (guint *)g_hash_table_lookup(remmina_keymap_table, keymap);
996 if (!table)
997 return keyval;
998 for (i = 0; table[i] > 0; i += 2)
999 if (table[i] == keyval)
1000 return table[i + 1];
1001 return keyval;
1002 }
1003
1004 gchar **
remmina_pref_keymap_groups(void)1005 remmina_pref_keymap_groups(void)
1006 {
1007 TRACE_CALL(__func__);
1008 GList *list;
1009 guint len;
1010 gchar **keys;
1011 guint i;
1012
1013 list = g_hash_table_get_keys(remmina_keymap_table);
1014 len = g_list_length(list);
1015
1016 keys = g_new0(gchar *, (len + 1) * 2 + 1);
1017 keys[0] = g_strdup("");
1018 keys[1] = g_strdup("");
1019 for (i = 0; i < len; i++) {
1020 keys[(i + 1) * 2] = g_strdup((gchar *)g_list_nth_data(list, i));
1021 keys[(i + 1) * 2 + 1] = g_strdup((gchar *)g_list_nth_data(list, i));
1022 }
1023 g_list_free(list);
1024
1025 return keys;
1026 }
1027
remmina_pref_get_scale_quality(void)1028 gint remmina_pref_get_scale_quality(void)
1029 {
1030 TRACE_CALL(__func__);
1031 /* Paranoid programming */
1032 if (remmina_pref.scale_quality < 0)
1033 remmina_pref.scale_quality = 0;
1034 return remmina_pref.scale_quality;
1035 }
1036
remmina_pref_get_ssh_loglevel(void)1037 gint remmina_pref_get_ssh_loglevel(void)
1038 {
1039 TRACE_CALL(__func__);
1040 return remmina_pref.ssh_loglevel;
1041 }
1042
remmina_pref_get_ssh_parseconfig(void)1043 gboolean remmina_pref_get_ssh_parseconfig(void)
1044 {
1045 TRACE_CALL(__func__);
1046 return remmina_pref.ssh_parseconfig;
1047 }
1048
remmina_pref_get_sshtunnel_port(void)1049 gint remmina_pref_get_sshtunnel_port(void)
1050 {
1051 TRACE_CALL(__func__);
1052 return remmina_pref.sshtunnel_port;
1053 }
1054
remmina_pref_get_ssh_tcp_keepidle(void)1055 gint remmina_pref_get_ssh_tcp_keepidle(void)
1056 {
1057 TRACE_CALL(__func__);
1058 return remmina_pref.ssh_tcp_keepidle;
1059 }
1060
remmina_pref_get_ssh_tcp_keepintvl(void)1061 gint remmina_pref_get_ssh_tcp_keepintvl(void)
1062 {
1063 TRACE_CALL(__func__);
1064 return remmina_pref.ssh_tcp_keepintvl;
1065 }
1066
remmina_pref_get_ssh_tcp_keepcnt(void)1067 gint remmina_pref_get_ssh_tcp_keepcnt(void)
1068 {
1069 TRACE_CALL(__func__);
1070 return remmina_pref.ssh_tcp_keepcnt;
1071 }
1072
remmina_pref_get_ssh_tcp_usrtimeout(void)1073 gint remmina_pref_get_ssh_tcp_usrtimeout(void)
1074 {
1075 TRACE_CALL(__func__);
1076 return remmina_pref.ssh_tcp_usrtimeout;
1077 }
1078
remmina_pref_set_value(const gchar * key,const gchar * value)1079 void remmina_pref_set_value(const gchar *key, const gchar *value)
1080 {
1081 TRACE_CALL(__func__);
1082 GKeyFile *gkeyfile;
1083 gchar *content;
1084 gsize length;
1085
1086 gkeyfile = g_key_file_new();
1087 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
1088 g_key_file_set_string(gkeyfile, "remmina_pref", key, value);
1089 content = g_key_file_to_data(gkeyfile, &length, NULL);
1090 g_file_set_contents(remmina_pref_file, content, length, NULL);
1091
1092 g_key_file_free(gkeyfile);
1093 g_free(content);
1094 }
1095
remmina_pref_get_value(const gchar * key)1096 gchar *remmina_pref_get_value(const gchar *key)
1097 {
1098 TRACE_CALL(__func__);
1099 GKeyFile *gkeyfile;
1100 gchar *value = NULL;
1101
1102 gkeyfile = g_key_file_new();
1103 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
1104 value = g_key_file_get_string(gkeyfile, "remmina_pref", key, NULL);
1105 g_key_file_free(gkeyfile);
1106
1107 return value;
1108 }
1109
remmina_pref_get_boolean(const gchar * key)1110 gboolean remmina_pref_get_boolean(const gchar *key)
1111 {
1112 TRACE_CALL(__func__);
1113 GKeyFile *gkeyfile;
1114 gboolean value;
1115
1116 gkeyfile = g_key_file_new();
1117 g_key_file_load_from_file(gkeyfile, remmina_pref_file, G_KEY_FILE_NONE, NULL);
1118 value = g_key_file_get_boolean(gkeyfile, "remmina_pref", key, NULL);
1119 g_key_file_free(gkeyfile);
1120
1121 return value;
1122 }
1123