~oem-solutions-group/network-manager/network-mananger-applet-hardy

« back to all changes in this revision

Viewing changes to src/connection-editor/main.c

  • Committer: Neil Jagdish Patel
  • Date: 2008-11-19 16:42:12 UTC
  • Revision ID: neil.patel@canonical.com-20081119164212-0v212d4hpst66ish
* Initial import
  - Source from https://edge.launchpad.net/%7Enetwork-manager/+archive/+files/network-manager-applet_0.7~~svn20081012t133407.orig.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
 
2
/* NetworkManager Connection editor -- Connection editor for NetworkManager
 
3
 *
 
4
 * Rodrigo Moya <rodrigo@gnome-db.org>
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License along
 
17
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
18
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
19
 *
 
20
 * (C) Copyright 2004-2005 Red Hat, Inc.
 
21
 */
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
# include <config.h>
 
25
#endif
 
26
 
 
27
#include <string.h>
 
28
#include <stdlib.h>
 
29
#include <signal.h>
 
30
 
 
31
#include <dbus/dbus.h>
 
32
#include <gtk/gtk.h>
 
33
#include <glib/gi18n-lib.h>
 
34
#include <glib/gtypes.h>
 
35
#include <glib-object.h>
 
36
#include <dbus/dbus-glib.h>
 
37
#include <dbus/dbus-glib-lowlevel.h>
 
38
 
 
39
#include <nm-setting-wired.h>
 
40
#include "nm-connection-list.h"
 
41
 
 
42
static GMainLoop *loop = NULL;
 
43
 
 
44
#define ARG_TYPE "type"
 
45
 
 
46
#define DBUS_TYPE_G_MAP_OF_VARIANT          (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
 
47
 
 
48
#define NM_CE_DBUS_SERVICE_NAME "org.freedesktop.NetworkManager.Gnome.ConnectionEditor"
 
49
 
 
50
#define NM_TYPE_CE_SERVICE            (nm_ce_service_get_type ())
 
51
#define NM_CE_SERVICE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CE_SERVICE, NMCEService))
 
52
#define NM_CE_SERVICE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CE_SERVICE, NMCEServiceClass))
 
53
#define NM_IS_CE_SERVICE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CE_SERVICE))
 
54
#define NM_IS_CE_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CE_SERVICE))
 
55
#define NM_CE_SERVICE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CE_SERVICE, NMCEServiceClass))
 
56
 
 
57
typedef struct {
 
58
        GObject parent;
 
59
        NMConnectionList *list;
 
60
} NMCEService;
 
61
 
 
62
typedef struct {
 
63
        GObjectClass parent;
 
64
} NMCEServiceClass;
 
65
 
 
66
GType nm_ce_service_get_type (void);
 
67
 
 
68
G_DEFINE_TYPE (NMCEService, nm_ce_service, G_TYPE_OBJECT)
 
69
 
 
70
static gboolean impl_start (NMCEService *self, GHashTable *args, GError **error);
 
71
 
 
72
#include "nm-connection-editor-service-glue.h"
 
73
 
 
74
static NMCEService *
 
75
nm_ce_service_new (DBusGConnection *bus, DBusGProxy *proxy, NMConnectionList *list)
 
76
{
 
77
        GObject *object;
 
78
        DBusConnection *connection;
 
79
        GError *err = NULL;
 
80
        guint32 result;
 
81
 
 
82
        g_return_val_if_fail (bus != NULL, NULL);
 
83
        g_return_val_if_fail (proxy != NULL, NULL);
 
84
 
 
85
        object = g_object_new (NM_TYPE_CE_SERVICE, NULL);
 
86
        if (!object)
 
87
                return NULL;
 
88
 
 
89
        NM_CE_SERVICE (object)->list = list;
 
90
 
 
91
        dbus_connection_set_change_sigpipe (TRUE);
 
92
        connection = dbus_g_connection_get_connection (bus);
 
93
        dbus_connection_set_exit_on_disconnect (connection, FALSE);
 
94
 
 
95
        /* Register our single-instance service.  Don't care if it fails. */
 
96
        if (!dbus_g_proxy_call (proxy, "RequestName", &err,
 
97
                                            G_TYPE_STRING, NM_CE_DBUS_SERVICE_NAME,
 
98
                                            G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
 
99
                                            G_TYPE_INVALID,
 
100
                                            G_TYPE_UINT, &result,
 
101
                                            G_TYPE_INVALID)) {
 
102
                g_warning ("Could not acquire the connection editor service.\n"
 
103
                            "  Message: '%s'", err->message);
 
104
                g_error_free (err);
 
105
        } else {
 
106
                if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
 
107
                        g_warning ("Could not acquire the connection editor service as it is already taken.");
 
108
                else {
 
109
                        /* success */
 
110
                        dbus_g_connection_register_g_object (bus, "/", object);
 
111
                }
 
112
        }
 
113
 
 
114
        return (NMCEService *) object;
 
115
}
 
116
 
 
117
static void
 
118
nm_ce_service_init (NMCEService *self)
 
119
{
 
120
}
 
121
 
 
122
static void
 
123
nm_ce_service_class_init (NMCEServiceClass *config_class)
 
124
{
 
125
        dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class),
 
126
                                                                         &dbus_glib_nm_connection_editor_service_object_info);
 
127
}
 
128
 
 
129
static gboolean
 
130
impl_start (NMCEService *self, GHashTable *table, GError **error)
 
131
{
 
132
        GValue *value;
 
133
 
 
134
        value = g_hash_table_lookup (table, ARG_TYPE);
 
135
        if (value && G_VALUE_HOLDS_STRING (value))
 
136
                nm_connection_list_set_type (self->list, g_value_get_string (value));
 
137
 
 
138
        return TRUE;
 
139
}
 
140
 
 
141
 
 
142
static void
 
143
signal_handler (int signo)
 
144
{
 
145
        if (signo == SIGINT || signo == SIGTERM) {
 
146
                g_message ("Caught signal %d, shutting down...", signo);
 
147
                g_main_loop_quit (loop);
 
148
        }
 
149
}
 
150
 
 
151
static void
 
152
setup_signals (void)
 
153
{
 
154
        struct sigaction action;
 
155
        sigset_t mask;
 
156
 
 
157
        sigemptyset (&mask);
 
158
        action.sa_handler = signal_handler;
 
159
        action.sa_mask = mask;
 
160
        action.sa_flags = 0;
 
161
        sigaction (SIGTERM,  &action, NULL);
 
162
        sigaction (SIGINT,  &action, NULL);
 
163
}
 
164
 
 
165
static gboolean
 
166
try_existing_instance (DBusGConnection *bus, DBusGProxy *proxy, const char *type)
 
167
{
 
168
        gboolean has_owner = FALSE;
 
169
        DBusGProxy *instance;
 
170
        GHashTable *args;
 
171
        GValue type_value = { 0, };
 
172
        gboolean success = FALSE;
 
173
 
 
174
        if (!dbus_g_proxy_call (proxy, "NameHasOwner", NULL,
 
175
                                G_TYPE_STRING, NM_CE_DBUS_SERVICE_NAME, G_TYPE_INVALID,
 
176
                                G_TYPE_BOOLEAN, &has_owner, G_TYPE_INVALID))
 
177
                return FALSE;
 
178
 
 
179
        if (!has_owner)
 
180
                return FALSE;
 
181
 
 
182
        /* Send arguments to existing process */
 
183
        instance = dbus_g_proxy_new_for_name (bus,
 
184
                                              NM_CE_DBUS_SERVICE_NAME,
 
185
                                              "/",
 
186
                                              NM_CE_DBUS_SERVICE_NAME);
 
187
        if (!instance)
 
188
                return FALSE;
 
189
 
 
190
        args = g_hash_table_new (g_str_hash, g_str_equal);
 
191
        if (type) {
 
192
                g_value_init (&type_value, G_TYPE_STRING);
 
193
                g_value_set_static_string (&type_value, type);
 
194
                g_hash_table_insert (args, "type", &type_value);
 
195
        }
 
196
 
 
197
        if (dbus_g_proxy_call (instance, "Start", NULL,
 
198
                               DBUS_TYPE_G_MAP_OF_VARIANT, args, G_TYPE_INVALID,
 
199
                               G_TYPE_INVALID))
 
200
                success = TRUE;
 
201
 
 
202
        g_hash_table_destroy (args);
 
203
        g_object_unref (instance);
 
204
        return success;
 
205
}
 
206
 
 
207
int
 
208
main (int argc, char *argv[])
 
209
{
 
210
        GOptionContext *opt_ctx;
 
211
        GError *error = NULL;
 
212
        NMConnectionList *list;
 
213
        DBusGConnection *bus;
 
214
        char *type = NULL;
 
215
        NMCEService *service = NULL;
 
216
        DBusGProxy *proxy = NULL;
 
217
 
 
218
        GOptionEntry entries[] = {
 
219
                { ARG_TYPE, 0, 0, G_OPTION_ARG_STRING, &type, "Type of connection to show at launch", NM_SETTING_WIRED_SETTING_NAME },
 
220
                { NULL }
 
221
        };
 
222
 
 
223
        bindtextdomain (GETTEXT_PACKAGE, NMALOCALEDIR);
 
224
        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
 
225
        gtk_init (&argc, &argv);
 
226
        textdomain (GETTEXT_PACKAGE);
 
227
 
 
228
        /* parse arguments: an idea is to use gconf://$setting_name / system://$setting_name to
 
229
           allow this program to work with both GConf and system-wide settings */
 
230
 
 
231
        opt_ctx = g_option_context_new (NULL);
 
232
        g_option_context_set_summary (opt_ctx, "Allows users to view and edit network connection settings");
 
233
        g_option_context_add_main_entries (opt_ctx, entries, NULL);
 
234
 
 
235
        if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) {
 
236
                g_warning ("%s\n", error->message);
 
237
                g_error_free (error);
 
238
                return 1;
 
239
        }
 
240
 
 
241
        g_option_context_free (opt_ctx);
 
242
 
 
243
        /* Inits the dbus-glib type system too */
 
244
        bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
 
245
        proxy = dbus_g_proxy_new_for_name (bus,
 
246
                                                                         "org.freedesktop.DBus",
 
247
                                                                         "/org/freedesktop/DBus",
 
248
                                                                         "org.freedesktop.DBus");
 
249
 
 
250
        /* Check for an existing instance on the bus */
 
251
        if (proxy) {
 
252
                if (try_existing_instance (bus, proxy, type))
 
253
                        goto exit;
 
254
        }
 
255
 
 
256
        loop = g_main_loop_new (NULL, FALSE);
 
257
 
 
258
        list = nm_connection_list_new (type);
 
259
        if (!list) {
 
260
                g_warning ("Failed to initialize the UI, exiting...");
 
261
                return 1;
 
262
        }
 
263
 
 
264
        /* Create our single-instance-app service if we can */
 
265
        if (proxy)
 
266
                service = nm_ce_service_new (bus, proxy, list);
 
267
 
 
268
        g_signal_connect_swapped (G_OBJECT (list), "done", G_CALLBACK (g_main_loop_quit), loop);
 
269
        nm_connection_list_run (list);
 
270
 
 
271
        setup_signals ();
 
272
        g_main_loop_run (loop);
 
273
 
 
274
        g_object_unref (list);
 
275
        if (service)
 
276
                g_object_unref (service);
 
277
 
 
278
exit:
 
279
        if (proxy)
 
280
                g_object_unref (proxy);
 
281
        dbus_g_connection_unref (bus);
 
282
        return 0;
 
283
}
 
284