# HG changeset patch # User Sean Egan # Date 1160296809 0 # Node ID 34083fe39891f0717b063578137ccd8acdc4262c # Parent fa0c8fa2b5a7b59124321e596af8b9651b90c2d1 [gaim-migrate @ 17448] From Paul Betts, NetworkManager integration. This will smartly disconnect and reconnect accounts according to network availability. Probably needs some more tweaking. committer: Tailor Script diff -r fa0c8fa2b5a7 -r 34083fe39891 COPYRIGHT --- a/COPYRIGHT Sun Oct 08 04:31:39 2006 +0000 +++ b/COPYRIGHT Sun Oct 08 08:40:09 2006 +0000 @@ -22,6 +22,7 @@ Curtis Beattie Dave Bell Igor Belyi +Paul Betts Brian Bernas Jonas Birmé Eric Blade diff -r fa0c8fa2b5a7 -r 34083fe39891 configure.ac --- a/configure.ac Sun Oct 08 04:31:39 2006 +0000 +++ b/configure.ac Sun Oct 08 08:40:09 2006 +0000 @@ -887,6 +887,14 @@ AC_MSG_RESULT(no) enable_dbus=no ]) + +dnl Check for libnm_glib; if we don't have it, oh well + PKG_CHECK_MODULES(LIBNM, libnm_glib, + [ + AC_DEFINE(HAVE_LIBNM, 1, [Check to see if we have NetworkManager]) + ]) + AC_SUBST(LIBNM_CFLAGS) + AC_SUBST(LIBNM_LIBS) fi dnl ####################################################################### diff -r fa0c8fa2b5a7 -r 34083fe39891 gtk/gtkconn.c --- a/gtk/gtkconn.c Sun Oct 08 04:31:39 2006 +0000 +++ b/gtk/gtkconn.c Sun Oct 08 08:40:09 2006 +0000 @@ -101,13 +101,6 @@ } static void -gaim_gtk_connection_notice(GaimConnection *gc, - const char *text) -{ -} - - -static void free_auto_recon(gpointer data) { GaimAutoRecon *info = data; @@ -201,6 +194,32 @@ } } +static void gaim_gtk_connection_network_connected () +{ + GList *list = gaim_accounts_get_all_active(); + while (list) { + GaimAccount *account = (GaimAccount*)list->data; + GaimAutoRecon *info = g_hash_table_lookup(hash, account); + if (info) + free_auto_recon(info); + do_signon(account); + list = list->next; + } +} + +static void gaim_gtk_connection_network_disconnected () +{ + GList *l = gaim_accounts_get_all_active(); + while (l) { + GaimAccount *a = (GaimAccount*)l->data; + gaim_account_disconnect(a); + l = l->next; + } +} + +static void gaim_gtk_connection_notice(GaimConnection *gc, const char *text) +{ } + static GaimConnectionUiOps conn_ui_ops = { gaim_gtk_connection_connect_progress, @@ -208,6 +227,8 @@ gaim_gtk_connection_disconnected, gaim_gtk_connection_notice, gaim_gtk_connection_report_disconnect, + gaim_gtk_connection_network_connected, + gaim_gtk_connection_network_disconnected }; GaimConnectionUiOps * diff -r fa0c8fa2b5a7 -r 34083fe39891 libgaim/Makefile.am --- a/libgaim/Makefile.am Sun Oct 08 04:31:39 2006 +0000 +++ b/libgaim/Makefile.am Sun Oct 08 08:40:09 2006 +0000 @@ -218,6 +218,7 @@ $(DBUS_LIBS) \ $(GLIB_LIBS) \ $(LIBXML_LIBS) \ + $(LIBNM_LIBS) \ $(STATIC_LINK_LIBS) \ $(INTLLIBS) \ -lm @@ -231,4 +232,5 @@ $(GLIB_CFLAGS) \ $(DEBUG_CFLAGS) \ $(DBUS_CFLAGS) \ - $(LIBXML_CFLAGS) + $(LIBXML_CFLAGS) \ + $(LIBNM_CFLAGS) diff -r fa0c8fa2b5a7 -r 34083fe39891 libgaim/account.c --- a/libgaim/account.c Sun Oct 08 04:31:39 2006 +0000 +++ b/libgaim/account.c Sun Oct 08 08:40:09 2006 +0000 @@ -27,6 +27,7 @@ #include "core.h" #include "dbus-maybe.h" #include "debug.h" +#include "network.h" #include "notify.h" #include "pounce.h" #include "prefs.h" @@ -2242,6 +2243,13 @@ GList *l; GaimAccount *account; + /* If we're not connected to the Internet right now, we bail on this */ + if (!gaim_network_is_available()) + { + fprintf(stderr, "Network not connected; skipping reconnect\n"); + return; + } + for (l = gaim_accounts_get_all(); l != NULL; l = l->next) { account = (GaimAccount *)l->data; diff -r fa0c8fa2b5a7 -r 34083fe39891 libgaim/connection.h --- a/libgaim/connection.h Sun Oct 08 04:31:39 2006 +0000 +++ b/libgaim/connection.h Sun Oct 08 08:40:09 2006 +0000 @@ -68,6 +68,8 @@ void (*disconnected)(GaimConnection *gc); void (*notice)(GaimConnection *gc, const char *text); void (*report_disconnect)(GaimConnection *gc, const char *text); + void (*network_connected)(); + void (*network_disconnected)(); } GaimConnectionUiOps; diff -r fa0c8fa2b5a7 -r 34083fe39891 libgaim/network.c --- a/libgaim/network.c Sun Oct 08 04:31:39 2006 +0000 +++ b/libgaim/network.c Sun Oct 08 08:40:09 2006 +0000 @@ -42,6 +42,14 @@ #include "stun.h" #include "upnp.h" +#ifdef HAVE_LIBNM +#include + +libnm_glib_ctx *nm_context = NULL; +guint nm_callback_idx = 0; + +#endif + struct _GaimNetworkListenData { int listenfd; int socket_type; @@ -51,6 +59,10 @@ gpointer cb_data; }; +#ifdef HAVE_LIBNM +void nm_callback_func(libnm_glib_ctx* ctx, gpointer user_data); +#endif + const unsigned char * gaim_network_ip_atoi(const char *ip) { @@ -360,6 +372,60 @@ return ntohs(addr.sin_port); } +gboolean +gaim_network_is_available(void) +{ +#ifdef HAVE_LIBNM + /* Try NetworkManager first, maybe we'll get lucky */ + int libnm_retval = -1; + + if (nm_context) + { + if ((libnm_retval = libnm_glib_get_network_state(nm_context)) == LIBNM_NO_NETWORK_CONNECTION) + { + gaim_debug_warning("network", "NetworkManager not active or reports no connection (retval = %i)\n", libnm_retval); + return FALSE; + } + if (libnm_retval == LIBNM_ACTIVE_NETWORK_CONNECTION) return TRUE; + } +#endif + return TRUE; +} + +#ifdef HAVE_LIBNM +void +nm_callback_func(libnm_glib_ctx* ctx, gpointer user_data) +{ + GList *l; + GaimAccount *account; + static libnm_glib_state prev = LIBNM_NO_DBUS; + libnm_glib_state current; + GaimConnectionUiOps *ui_ops = gaim_connections_get_ui_ops(); + + current = libnm_glib_get_network_state(ctx); + gaim_debug_info("network","Entering nm_callback_func!\n"); + + switch(current) + { + case LIBNM_ACTIVE_NETWORK_CONNECTION: + ui_ops->network_connected(); + prev = current; + break; + case LIBNM_NO_NETWORK_CONNECTION: + if (prev != LIBNM_ACTIVE_NETWORK_CONNECTION) + break; + ui_ops->network_disconnected(); + prev = current; + break; + case LIBNM_NO_DBUS: + case LIBNM_NO_NETWORKMANAGER: + case LIBNM_INVALID_CONTEXT: + default: + break; + } +} +#endif + void gaim_network_init(void) { @@ -371,4 +437,24 @@ gaim_prefs_add_int ("/core/network/ports_range_end", 2048); gaim_upnp_discover(NULL, NULL); + +#ifdef HAVE_LIBNM + nm_context = libnm_glib_init(); + if(nm_context) + nm_callback_idx = libnm_glib_register_callback(nm_context, nm_callback_func, NULL, g_main_context_default()); +#endif } + +void +gaim_network_uninit(void) +{ +#ifdef HAVE_LIBNM + /* FIXME: If anyone can think of a more clever way to shut down libnm without + * using a global variable + this function, please do. */ + if(nm_context && nm_callback_idx) + libnm_glib_unregister_callback(nm_context, nm_callback_idx); + + if(nm_context) + libnm_glib_shutdown(nm_context); +#endif +} diff -r fa0c8fa2b5a7 -r 34083fe39891 libgaim/network.h --- a/libgaim/network.h Sun Oct 08 04:31:39 2006 +0000 +++ b/libgaim/network.h Sun Oct 08 08:40:09 2006 +0000 @@ -188,10 +188,24 @@ unsigned short gaim_network_get_port_from_fd(int fd); /** + * Detects if there is an available Internet connection. Note that this call + * could block for the amount of time specified in inet_detect_timeout, so + * using it in a UI thread may cause uncomfortableness + * + * @return TRUE if the Internet is available + */ +gboolean gaim_network_is_available(void); + +/** * Initializes the network subsystem. */ void gaim_network_init(void); +/** + * Shuts down the network subsystem. + */ +void gaim_network_uninit(void); + /*@}*/ #ifdef __cplusplus