NetworkManager/info-daemon/NetworkManagerInfo.c
Dan Williams d06aa3e6ff 2004-08-11 Dan Williams <dcbw@redhat.com>
* info-daemon/NetworkManagerInfo.c:
		- (main): clean up Seth's code style

	* info-daemon/NetworkManagerInfoDbus.c:
		- Use the more aptly-named path/service/interface constants from NetworkManager
		- Don't return empty strings ("") as object paths ever, instead return errors

	* panel-applet/NMWirelessApplet.c:
		- Clean up Seth's code style

	* src/NetworkManager.[ch]
		- (nm_remove_device_from_list): remove anything having to do with pending_device
		- (main, nm_print_usage): change --daemon=[yes|no] -> --no-daemon

	* src/NetworkManagerAPList.[ch]
		- Move Iter struct right above the iter functions to preserve opacity
		- (nm_ap_list_remove_ap): implement
		- (nm_ap_list_update_network): deal with errors returned from nm_dbus_get_network_priority(),
			remove AP if NetworkManagerInfo doesn't know anything about it
		- (nm_ap_list_diff): user NMAPList iterators
		- (nm_ap_list_print_members): implement debugging function

	* src/NetworkManagerDbus.[ch]
		- (nm_dbus_nm_get_active_device): remove anything to do with pending_device
		- (nm_dbus_get_user_key_for_network): remove DBusPendingCall stuff (unused),
			and move the actual key setting stuff into NetworkManagerDevice.c
		- (nm_dbus_get_network_priority): return -1 now on errors
		- (nm_dbus_nmi_filter): fix strcmp() error that caused PreferredNetworkUpdate signals to
			get lost, and force the active device to update its "best" ap when AP lists change
		- (nm_dbus_nm_message_handler): Update conditions for returning "connecting" for a "status"
			method call due to pending_device member removal

	* src/NetworkManagerDevice.[ch]
		- Move NMDevice structure to the top
		- Add a wireless scan mutex and a best_ap mutex to the Wireless Options structure
		- Remove Pending Action stuff from everywhere
		- (nm_device_activation_*): We now "begin" activation and start a thread to do the
			activation for us.  This thread blocks until all conditions for activation have
			been met (ie for wireless devices, we need a valid WEP key and a "best" ap), and
			then setup up the interface and runs dhclient.  We have to do this because there
			is no guaruntee how long dhclient takes, and while we are blocking on it, we cannot
			run our main loop and respond to dbus method calls or HAL device removals/inserts
		- (nm_device_set_user_key_for_network): Move logic here from NetworkManagerDbus.c so we
			can tell nm_device_activation_worker() that we've got a key
		- (nm_device_*_best_ap): lock access to best_ap member of Wireless Options structure
		- (nm_device_get_path_for_ap): dumb it down so the list doesn't lock against itself when
			diffing (AP appear/disappear signal functions make sure the AP is actually in the device's
list)
		- (nm_device_update_best_ap): move logic from nm_wireless_is_ap_better() here

	* src/NetworkManagerPolicy.c
		- Remove anything to do with pending_device
		- Adjust device activation to deal with activation-in-worker-thread

	* src/NetworkManagerUtils.c
		- Clean up locking debugging a bit

	* src/NetworkManagerWireless.[ch]
		- (nm_wireless_is_ap_better): remove, stick logic in nm_device_update_best_ap().  This function
			was badly named and is better as a device function

	* panel-applet/.cvsignore: add


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@46 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2004-08-11 18:14:02 +00:00

265 lines
6.8 KiB
C

/* NetworkManagerInfo -- Manage allowed access points and provide a UI
* for WEP key entry
*
* Dan Williams <dcbw@redhat.com>
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <glib.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <getopt.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <gtk/gtk.h>
#include <glade/glade.h>
#include <gconf/gconf-client.h>
#include <libgnome/gnome-init.h>
#include <libgnomeui/gnome-ui-init.h>
#include "NetworkManagerInfoDbus.h"
#include "NetworkManagerInfo.h"
#include "NetworkManagerInfoPassphraseDialog.h"
/*
* nmi_get_next_priority
*
* Gets the next available worse priority
*
*/
int nmi_get_next_priority (NMIAppInfo *info)
{
GSList *dir_list = NULL;
GSList *element = NULL;
int worst_prio = 0;
g_return_val_if_fail (info != NULL, 999);
/* List all allowed access points that gconf knows about */
element = dir_list = gconf_client_all_dirs (info->gconf_client, NMI_GCONF_TRUSTED_NETWORKS_PATH, NULL);
if (!dir_list)
return (10);
while (element)
{
gchar key[100];
GConfValue *value;
g_snprintf (&key[0], 99, "%s/priority", (char *)(element->data));
if ((value = gconf_client_get (info->gconf_client, key, NULL)))
{
if (worst_prio < gconf_value_get_int (value))
worst_prio = gconf_value_get_int (value);
gconf_value_free (value);
}
g_free (element->data);
element = g_slist_next (element);
}
g_slist_free (dir_list);
return (worst_prio + 10);
}
/*
* nmi_gconf_notify_callback
*
* Callback from gconf when wireless networking key/values have changed.
*
*/
void nmi_gconf_notify_callback (GConfClient *client, guint connection_id, GConfEntry *entry, gpointer user_data)
{
NMIAppInfo *info = (NMIAppInfo *)user_data;
const char *key = NULL;
g_return_if_fail (client != NULL);
g_return_if_fail (entry != NULL);
g_return_if_fail (info != NULL);
if ((key = gconf_entry_get_key (entry)))
{
NMINetworkType type = NETWORK_TYPE_UNKNOWN;
int trusted_path_len = strlen (NMI_GCONF_TRUSTED_NETWORKS_PATH) + 1;
int preferred_path_len = strlen (NMI_GCONF_PREFERRED_NETWORKS_PATH) + 1;
int len;
/* Extract the network name from the key */
if (strncmp (NMI_GCONF_TRUSTED_NETWORKS_PATH"/", key, trusted_path_len) == 0)
{
type = NETWORK_TYPE_TRUSTED;
len = trusted_path_len;
}
else if (strncmp (NMI_GCONF_PREFERRED_NETWORKS_PATH"/", key, preferred_path_len) == 0)
{
type = NETWORK_TYPE_PREFERRED;
len = preferred_path_len;
}
if (type != NETWORK_TYPE_UNKNOWN)
{
char *network = g_strdup ((key + len));
char *slash_pos;
/* If its a key under the network name, zero out the slash so we
* are left with only the network name.
*/
if ((slash_pos = strchr (network, '/')))
*slash_pos = '\0';
nmi_dbus_signal_update_network (info->connection, network, type);
g_free (network);
}
}
}
/*
* nmi_print_usage
*
* Prints program usage.
*
*/
static void nmi_print_usage (void)
{
fprintf (stderr, "\n" "usage : NetworkManagerInfo [--daemon=yes|no] [--help]\n");
fprintf (stderr,
"\n"
" --daemon=yes|no Become a daemon\n"
" --help Show this information and exit\n"
"\n"
"NetworkManagerInfo responds to NetworkManager requests for allowed access points\n"
"and WEP keys.\n"
"\n");
}
/*
* main
*
*/
int main( int argc, char *argv[] )
{
GnomeProgram *program;
gboolean no_daemon;
DBusError dbus_error;
DBusConnection *dbus_connection;
int err;
NMIAppInfo *app_info = NULL;
GMainLoop *loop;
guint notify_id;
struct poptOption options[] =
{
{ "no-daemon", 'n', POPT_ARG_NONE, NULL, 0,
"Don't detatch from the console and run in the background.", NULL },
{ NULL, '\0', 0, NULL, 0, NULL, NULL }
};
options[0].arg = &no_daemon;
program = gnome_program_init ("NetworkManagerInfo", VERSION,
LIBGNOMEUI_MODULE, argc, argv,
GNOME_PROGRAM_STANDARD_PROPERTIES,
GNOME_PARAM_POPT_TABLE, options,
GNOME_PARAM_HUMAN_READABLE_NAME, "Network Manager User Info Service",
NULL);
if (!no_daemon)
{
int child_pid;
if (chdir ("/") < 0)
{
fprintf( stderr, "NetworkManagerInfo could not chdir to /. errno=%d", errno);
return 1;
}
child_pid = fork ();
switch (child_pid)
{
case -1:
fprintf( stderr, "NetworkManagerInfo could not daemonize. errno = %d\n", errno );
break;
case 0:
/* Child */
break;
default:
exit (0);
break;
}
}
app_info = g_new0 (NMIAppInfo, 1);
if (!app_info)
{
fprintf (stderr, "Not enough memory for application data.\n");
exit (1);
}
g_type_init ();
if (!g_thread_supported ())
g_thread_init (NULL);
/* Set up our connection to the message bus */
dbus_error_init (&dbus_error);
dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
if (dbus_connection == NULL)
{
fprintf (stderr, "NetworkManagerInfo could not get the system bus. Make sure the message bus daemon is running?\n");
exit (1);
}
dbus_connection_set_change_sigpipe (TRUE);
dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
dbus_connection_setup_with_g_main (dbus_connection, NULL);
app_info->connection = dbus_connection;
/* Grab a connection to the GConf daemon. We also want to
* get change notifications for our wireless networking data.
*/
app_info->gconf_client = gconf_client_get_default ();
gconf_client_add_dir (app_info->gconf_client, NMI_GCONF_WIRELESS_NETWORKING_PATH,
GCONF_CLIENT_PRELOAD_NONE, NULL);
notify_id = gconf_client_notify_add (app_info->gconf_client, NMI_GCONF_WIRELESS_NETWORKING_PATH,
nmi_gconf_notify_callback, app_info, NULL, NULL);
/* Create our own dbus service */
err = nmi_dbus_service_init (dbus_connection, app_info);
if (err == -1)
exit (1);
gtk_init (&argc, &argv);
if (nmi_passphrase_dialog_init (app_info) != 0)
exit (1);
loop = g_main_loop_new (NULL, FALSE);
g_main_loop_run (loop);
gconf_client_notify_remove (app_info->gconf_client, notify_id);
g_object_unref (G_OBJECT (app_info->gconf_client));
g_free (app_info);
return 0;
}