37 #define G_LOG_USE_STRUCTURED 39 #define G_LOG_DOMAIN ((gchar*)"remmina") 41 #ifdef GDK_WINDOWING_X11 43 #elif defined(GDK_WINDOWING_WAYLAND) 44 #include <gdk/gdkwayland.h> 47 #include <glib/gi18n.h> 60 #ifdef WITH_PYTHONLIBS 61 #include "remmina_plugin_python.h" 76 # if GCRYPT_VERSION_NUMBER < 0x010600 82 # if GCRYPT_VERSION_NUMBER < 0x010600 96 {
"about",
'a', 0, G_OPTION_ARG_NONE, NULL,
N_(
"Show \'About\'"), NULL },
98 {
"connect",
'c', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL,
N_(
"Connect either to a desktop described in a file (.remmina or a filetype supported by a plugin) or a supported URI (RDP, VNC, SSH or SPICE)"),
N_(
"FILE") },
100 { G_OPTION_REMAINING,
'\0', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL,
N_(
"Connect to a desktop described in a file (.remmina or a filetype supported by a plugin)"),
N_(
"FILE") },
102 {
"edit",
'e', 0, G_OPTION_ARG_FILENAME_ARRAY, NULL,
N_(
"Edit desktop connection described in file (.remmina or a filetype supported by plugin)"),
N_(
"FILE") },
103 {
"help",
'?', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, NULL, NULL, NULL },
105 {
"kiosk",
'k', 0, G_OPTION_ARG_NONE, NULL,
N_(
"Start in kiosk mode"), NULL },
107 {
"new",
'n', 0, G_OPTION_ARG_NONE, NULL,
N_(
"Create new connection profile"), NULL },
109 {
"pref",
'p', 0, G_OPTION_ARG_STRING, NULL,
N_(
"Show preferences"),
N_(
"TABINDEX") },
116 {
"quit",
'q', 0, G_OPTION_ARG_NONE, NULL,
N_(
"Quit"), NULL },
118 {
"server",
's', 0, G_OPTION_ARG_STRING, NULL,
N_(
"Use default server name (for --new)"),
N_(
"SERVER") },
120 {
"protocol",
't', 0, G_OPTION_ARG_STRING, NULL,
N_(
"Use default protocol (for --new)"),
N_(
"PROTOCOL") },
122 {
"icon",
'i', 0, G_OPTION_ARG_NONE, NULL,
N_(
"Start in tray"), NULL },
124 {
"version",
'v', 0, G_OPTION_ARG_NONE, NULL,
N_(
"Show the application version"), NULL },
126 {
"full-version",
'V', 0, G_OPTION_ARG_NONE, NULL,
N_(
"Show version of the application and its plugins"), NULL },
128 {
"update-profile", 0, 0, G_OPTION_ARG_FILENAME, NULL,
N_(
"Modify connection profile (requires --set-option)"), NULL },
130 {
"set-option", 0, 0, G_OPTION_ARG_STRING_ARRAY, NULL,
N_(
"Set one or more profile settings, to be used with --update-profile"), NULL },
131 {
"encrypt-password", 0, 0, G_OPTION_ARG_NONE, NULL,
N_(
"Encrypt a password"), NULL },
132 {
"disable-toolbar", 0, 0, G_OPTION_ARG_NONE, NULL,
N_(
"Disable toolbar"), NULL },
133 {
"enable-fullscreen", 0, 0, G_OPTION_ARG_NONE, NULL,
N_(
"Enable fullscreen"), NULL },
134 {
"enable-extra-hardening", 0, 0, G_OPTION_ARG_NONE, NULL,
N_(
"Enable extra hardening (disable closing confirmation, disable unsafe shortcut keys, hide tabs, hide search bar)"), NULL },
135 {
"no-tray-icon", 0, 0, G_OPTION_ARG_NONE, NULL,
N_(
"Disable tray icon"), NULL },
139 #ifdef WITH_LIBGCRYPT 144 if (e == GPG_ERR_NO_ERROR)
153 TRACE_CALL(__func__);
156 gboolean executed = FALSE;
160 const gchar **remaining_args;
164 #if SODIUM_VERSION_INT >= 90200 167 opts = g_application_command_line_get_options_dict(cmdline);
169 if (g_variant_dict_lookup_value(opts,
"disable-toolbar", NULL)) {
173 if (g_variant_dict_lookup_value(opts,
"enable-fullscreen", NULL)) {
177 if (g_variant_dict_lookup_value(opts,
"enable-extra-hardening", NULL)) {
181 if (g_variant_dict_lookup_value(opts,
"no-tray-icon", NULL)) {
187 if (g_variant_dict_lookup_value(opts,
"quit", NULL)) {
193 if (g_variant_dict_lookup_value(opts,
"about", NULL)) {
201 if (g_variant_dict_lookup(opts,
"connect",
"^aay", &files)) {
203 for (gint i = 0; files[i]; i++) {
204 g_debug (
"Connecting to: %s", files[i]);
210 if (g_variant_dict_lookup(opts, G_OPTION_REMAINING,
"^a&ay", &remaining_args)) {
212 g_free(remaining_args);
216 if (g_variant_dict_lookup(opts,
"edit",
"^aay", &files)) {
218 for (gint i = 0; files[i]; i++) {
219 g_debug (
"Editing file: %s", files[i]);
227 if (g_variant_dict_lookup_value(opts,
"kiosk", NULL)) {
233 if (g_variant_dict_lookup_value(opts,
"new", NULL)) {
234 if (!g_variant_dict_lookup(opts,
"protocol",
"&s", &protocol))
237 if (g_variant_dict_lookup(opts,
"server",
"&s", &server))
238 str = g_strdup_printf(
"%s,%s", protocol, server);
240 str = g_strdup(protocol);
247 if (g_variant_dict_lookup(opts,
"pref",
"&s", &str)) {
252 if (g_variant_dict_lookup(opts,
"plugin",
"&s", &str)) {
257 if (g_variant_dict_lookup_value(opts,
"icon", NULL)) {
262 if (g_variant_dict_lookup_value(opts,
"encrypt-password", NULL)) {
276 TRACE_CALL(__func__);
285 g_set_application_name(
"Remmina");
286 gtk_window_set_default_icon_name(REMMINA_APP_ID);
290 gdk_set_program_class(REMMINA_APP_ID);
292 gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(),
293 REMMINA_RUNTIME_DATADIR G_DIR_SEPARATOR_S
"icons");
294 g_application_hold(app);
300 g_print(
"Warning: Remmina is running without a secret plugin. Passwords will be saved in a less secure way.\n");
303 g_print(
"Warning: Remmina is running with a secrecy plugin, but it cannot connect to a secrecy service.\n");
310 TRACE_CALL(__func__);
319 if (g_variant_dict_lookup_value(opts,
"version", NULL)) {
324 if (g_variant_dict_lookup_value(opts,
"full-version", NULL)) {
329 if (g_variant_dict_lookup(opts,
"update-profile",
"^&ay", &str)) {
330 if (g_variant_dict_lookup(opts,
"set-option",
"^a&s", &settings)) {
331 if (settings != NULL) {
339 g_print(
"Error: --update-profile requires --set-option\n");
347 int main(
int argc,
char *argv[])
349 TRACE_CALL(__func__);
354 g_unsetenv(
"GDK_CORE_DEVICE_EVENTS");
359 if(!getenv(
"G_MESSAGES_DEBUG")) {
364 g_message(_(
"Remmina does not log all output statements. " 365 "Turn on more verbose output by using " 366 "\"G_MESSAGES_DEBUG=all\" as an environment variable.\n" 367 "More info available on the Remmina wiki at:\n" 368 "https://gitlab.com/Remmina/Remmina/-/wikis/Usage/Remmina-debugging" 375 gdk_set_allowed_backends(
"wayland,x11,broadway,quartz,mir");
377 gdk_set_allowed_backends(
"x11,broadway,quartz,mir");
381 bindtextdomain(GETTEXT_PACKAGE, REMMINA_RUNTIME_LOCALEDIR);
382 bind_textdomain_codeset(GETTEXT_PACKAGE,
"UTF-8");
383 textdomain(GETTEXT_PACKAGE);
385 #ifdef HAVE_LIBGCRYPT 386 # if GCRYPT_VERSION_NUMBER < 0x010600 389 if ((e = gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)) != GPG_ERR_NO_ERROR)
394 gcry_check_version(NULL);
395 gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
396 gcry_control(GCRYCTL_INITIALIZATION_FINISHED, 0);
407 app_id = g_application_id_is_valid(REMMINA_APP_ID) ? REMMINA_APP_ID : NULL;
408 app = gtk_application_new(app_id, G_APPLICATION_HANDLES_COMMAND_LINE | G_APPLICATION_CAN_OVERRIDE_APP_ID);
409 #if !GTK_CHECK_VERSION(4, 0, 0) 410 g_set_prgname(app_id);
412 g_application_add_main_option_entries(G_APPLICATION(app),
remmina_options);
413 #if GLIB_CHECK_VERSION(2,56,0) 414 gchar *summary = g_strdup_printf (
"%s %s", app_id, VERSION);
415 g_application_set_option_context_summary (G_APPLICATION(app), summary);
418 g_application_set_option_context_parameter_string (G_APPLICATION(app), _(
"- or protocol://username:encryptedpassword@host:port"));
420 g_application_set_option_context_description (G_APPLICATION(app),
422 "To connect using an existing connection profile, use:\n" 424 "\tremmina -c FILE.remmina\n" 426 "To quick connect using a URI:\n" 428 "\tremmina -c rdp://username@server\n" 429 "\tremmina -c rdp://domain\\\\username@server\n" 430 "\tremmina -c vnc://username@server\n" 431 "\tremmina -c vnc://server?VncUsername=username\n" 432 "\tremmina -c ssh://user@server\n" 433 "\tremmina -c spice://server\n" 435 "To quick connect using a URI along with an encrypted password:\n" 437 "\tremmina -c rdp://username:encrypted-password@server\n" 438 "\tremmina -c vnc://username:encrypted-password@server\n" 439 "\tremmina -c vnc://server?VncUsername=username\\&VncPassword=encrypted-password\n" 441 "To encrypt a password for use with a URI:\n" 443 "\tremmina --encrypt-password\n" 445 "To update username and password and set a different resolution mode of a Remmina connection profile, use:\n" 447 "\techo \"username\\napassword\" | remmina --update-profile /PATH/TO/FOO.remmina --set-option username --set-option resolution_mode=2 --set-option password\n"));
455 g_application_set_inactivity_timeout(G_APPLICATION(app), 10000);
456 status = g_application_run(G_APPLICATION(app), argc, argv);
int remmina_exec_set_setting(gchar *profilefilename, gchar **settings)
static GOptionEntry remmina_options[]
static void remmina_on_startup(GApplication *app)
RemminaSecretPlugin * remmina_plugin_manager_get_secret_plugin(void)
gboolean(* is_service_available)(struct _RemminaSecretPlugin *instance)
void remmina_masterthread_exec_save_main_thread_id()
void remmina_sftp_plugin_register(void)
int main(int argc, char *argv[])
static int _gpg_error_to_errno(gcry_error_t e)
static gint remmina_on_command_line(GApplication *app, GApplicationCommandLine *cmdline)
void remmina_file_manager_init(void)
It creates the Remmina data and cache folders.
void remmina_ssh_plugin_register(void)
void remmina_icon_init(void)
static gint remmina_on_local_cmdline(GApplication *app, GVariantDict *opts, gpointer user_data)
static int gcrypt_thread_initialized
void remmina_exec_command(RemminaCommandType command, const gchar *data)
void remmina_plugin_manager_init()
gboolean remmina_gtk_check_version(guint major, guint minor, guint micro)
void remmina_pref_init(void)
GCRY_THREAD_OPTION_PTHREAD_IMPL
N_("Unable to connect to VNC server")
void remmina_sodium_init(void)