pidgin/pidgin

Embed SOCKS5 proxying in Jabber SI xfer code

2020-11-05, Elliott Sales de Andrade
f2d29265494b
Embed SOCKS5 proxying in Jabber SI xfer code

So it turns out that the `purple_proxy_connect_socks5_account` does use the Gio proxy code, but then wraps it up in our old file descriptor concepts. Instead, put that code directly in Jabber, which will eventually make it easier to use straight gio instead of file descriptors.

* Add a cancellable on JabberSIXfer.
* Embed SOCKS5 code directly in jabber SI xfer code.

Testing Done:
Compile only.

Reviewed at https://reviews.imfreedom.org/r/201/
/*
* Pidgin - Internet Messenger
* Copyright (C) Pidgin Developers <devel@pidgin.im>
*
* Pidgin is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* 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, see <https://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <glib/gstdio.h>
#include <gplugin.h>
#include <purple.h>
#include "pidginapplication.h"
#include "gtkaccount.h"
#include "gtkblist.h"
#include "pidgincore.h"
#include "pidgindebug.h"
struct _PidginApplication {
GtkApplication parent;
};
/******************************************************************************
* Globals
*****************************************************************************/
static gchar *opt_config_dir_arg = NULL;
static gboolean opt_nologin = FALSE;
static GOptionEntry option_entries[] = {
{
"config", 'c', 0, G_OPTION_ARG_FILENAME, &opt_config_dir_arg,
N_("use DIR for config files"), N_("DIR")
}, {
"nologin", 'n', 0, G_OPTION_ARG_NONE, &opt_nologin,
N_("don't automatically login"), NULL
},
{
"version", 'v', 0, G_OPTION_ARG_NONE, NULL,
N_("display the current version and exit"), NULL
}, {
NULL
}
};
G_DEFINE_TYPE(PidginApplication, pidgin_application, GTK_TYPE_APPLICATION)
/******************************************************************************
* GApplication Implementation
*****************************************************************************/
static void
pidgin_application_startup(GApplication *application) {
GtkCssProvider *provider = NULL;
GError *error = NULL;
GList *active_accounts = NULL;
gchar *search_path = NULL;
G_APPLICATION_CLASS(pidgin_application_parent_class)->startup(application);
/* set a user-specified config directory */
if (opt_config_dir_arg != NULL) {
if (g_path_is_absolute(opt_config_dir_arg)) {
purple_util_set_user_dir(opt_config_dir_arg);
} else {
/* Make an absolute (if not canonical) path */
gchar *cwd = g_get_current_dir();
gchar *path = g_build_filename(cwd, opt_config_dir_arg, NULL);
purple_util_set_user_dir(path);
g_free(cwd);
g_free(path);
}
}
provider = gtk_css_provider_new();
search_path = g_build_filename(purple_config_dir(), "gtk-3.0.css", NULL);
gtk_css_provider_load_from_path(provider, search_path, &error);
if(error != NULL) {
purple_debug_error("gtk", "Unable to load custom gtk-3.0.css: %s\n",
error->message);
g_clear_error(&error);
} else {
GdkScreen *screen = gdk_screen_get_default();
gtk_style_context_add_provider_for_screen(screen,
GTK_STYLE_PROVIDER(provider),
GTK_STYLE_PROVIDER_PRIORITY_USER);
}
g_free(search_path);
#ifdef _WIN32
winpidgin_init();
#endif
purple_core_set_ui_ops(pidgin_core_get_ui_ops());
if(!purple_core_init(PIDGIN_UI)) {
fprintf(stderr,
_("Initialization of the libpurple core failed. Aborting!\n"
"Please report this!\n"));
g_abort();
}
if(g_getenv("PURPLE_PLUGINS_SKIP")) {
purple_debug_info("gtk",
"PURPLE_PLUGINS_SKIP environment variable "
"set, skipping normal Pidgin plugin paths");
} else {
search_path = g_build_filename(purple_data_dir(), "plugins", NULL);
if(!g_file_test(search_path, G_FILE_TEST_IS_DIR)) {
g_mkdir(search_path, S_IRUSR | S_IWUSR | S_IXUSR);
}
purple_plugins_add_search_path(search_path);
g_free(search_path);
purple_plugins_add_search_path(PIDGIN_LIBDIR);
}
purple_plugins_refresh();
/* load plugins we had when we quit */
purple_plugins_load_saved(PIDGIN_PREFS_ROOT "/plugins/loaded");
/* gk 20201008: this needs to be moved to the buddy list initialization. */
pidgin_blist_setup_sort_methods();
gtk_window_set_default_icon_name("pidgin");
g_free(opt_config_dir_arg);
opt_config_dir_arg = NULL;
/*
* We want to show the blist early in the init process so the
* user feels warm and fuzzy.
*/
purple_blist_show();
if(purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/debug/enabled")) {
pidgin_debug_window_show();
}
if(opt_nologin) {
/* Set all accounts to "offline" */
PurpleSavedStatus *saved_status;
/* If we've used this type+message before, lookup the transient status */
saved_status = purple_savedstatus_find_transient_by_type_and_message(
PURPLE_STATUS_OFFLINE, NULL);
/* If this type+message is unique then create a new transient saved status */
if(saved_status == NULL) {
saved_status = purple_savedstatus_new(NULL, PURPLE_STATUS_OFFLINE);
}
/* Set the status for each account */
purple_savedstatus_activate(saved_status);
} else {
/* Everything is good to go--sign on already */
if (!purple_prefs_get_bool("/purple/savedstatus/startup_current_status")) {
purple_savedstatus_activate(purple_savedstatus_get_startup());
}
purple_accounts_restore_current_statuses();
}
if((active_accounts = purple_accounts_get_all_active()) == NULL) {
pidgin_accounts_window_show();
} else {
g_list_free(active_accounts);
}
/* GTK clears the notification for us when opening the first window, but we
* may have launched with only a status icon, so clear it just in case.
*/
gdk_notify_startup_complete();
/* TODO: Use GtkApplicationWindow or add a window instead */
g_application_hold(application);
}
static void
pidgin_application_activate(GApplication *application) {
PidginBuddyList *blist = pidgin_blist_get_default_gtk_blist();
if(blist != NULL && blist->window != NULL) {
gtk_window_present(GTK_WINDOW(blist->window));
}
}
static gint
pidgin_application_command_line(GApplication *application,
GApplicationCommandLine *cmdline)
{
gchar **argv = NULL;
gint argc = 0, i = 0;
argv = g_application_command_line_get_arguments(cmdline, &argc);
if(argc == 1) {
/* No arguments, just activate */
g_application_activate(application);
}
/* Start at 1 to skip the executable name */
for (i = 1; i < argc; i++) {
purple_got_protocol_handler_uri(argv[i]);
}
g_strfreev(argv);
return 0;
}
static gint
pidgin_application_handle_local_options(GApplication *application,
GVariantDict *options)
{
if (g_variant_dict_contains(options, "version")) {
printf("%s %s (libpurple %s)\n", PIDGIN_NAME, DISPLAY_VERSION,
purple_core_get_version());
return 0;
}
return -1;
}
/******************************************************************************
* GObject Implementation
*****************************************************************************/
static void
pidgin_application_init(PidginApplication *application) {
GApplication *gapp = G_APPLICATION(application);
g_application_add_main_option_entries(gapp, option_entries);
g_application_add_option_group(gapp, purple_get_option_group());
g_application_add_option_group(gapp, gplugin_get_option_group());
}
static void
pidgin_application_class_init(PidginApplicationClass *klass) {
GApplicationClass *app_class = G_APPLICATION_CLASS(klass);
app_class->startup = pidgin_application_startup;
app_class->activate = pidgin_application_activate;
app_class->command_line = pidgin_application_command_line;
app_class->handle_local_options = pidgin_application_handle_local_options;
}
/******************************************************************************
* Public API
*****************************************************************************/
GApplication *
pidgin_application_new(void) {
return g_object_new(
PIDGIN_TYPE_APPLICATION,
"flags", G_APPLICATION_CAN_OVERRIDE_APP_ID |
G_APPLICATION_HANDLES_COMMAND_LINE,
"register-session", TRUE,
NULL);
}