[gdm/wip/slave-connection: 23/36] daemon: Remove transient displays from display store when finished



commit 18bb69fa514c0348d2a8b2459e56044c8e4922dc
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Sat Jul 7 15:07:11 2012 -0400

    daemon: Remove transient displays from display store when finished
    
    When a display finishes (because it failed to start, or the users
    session ended) the GDM display handling code needs to remove the
    display from its display store.
    
    For static (logind or the first automatic) displays this happens in the
    
    on_static_display_status_changed
    
    function.  For transient (user-switch initiated) displays, though,
    it never happens.
    
    This commit reworks on_static_display_status_changed into a more
    generally applicable on_display_status_changed function, so the proper
    bookkeeping can happen for transient displays, too.

 daemon/Makefile.am                 |    6 -
 daemon/gdm-display.c               |    4 +-
 daemon/gdm-local-display-factory.c |   54 +++++---
 daemon/gdm-manager.c               |   34 +++---
 daemon/gdm-manager.xml             |   14 --
 daemon/main.c                      |  258 ++++++++++++------------------------
 data/gdm.conf.in                   |    8 +-
 7 files changed, 138 insertions(+), 240 deletions(-)
---
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 0ad4ea2..495fcb3 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -31,7 +31,6 @@ AM_CPPFLAGS = \
 BUILT_SOURCES =					\
 	gdm-slave-glue.h			\
 	gdm-xdmcp-chooser-slave-glue.h		\
-	gdm-manager-glue.h			\
 	gdm-display-glue.h			\
 	gdm-xdmcp-display-glue.h		\
 	gdm-static-display-glue.h		\
@@ -40,9 +39,6 @@ BUILT_SOURCES =					\
 	gdm-greeter-glue.h			\
 	$(NULL)
 
-gdm-manager-glue.h: gdm-manager.xml Makefile.am
-	dbus-binding-tool --prefix=gdm_manager --mode=glib-server --output=gdm-manager-glue.h $(srcdir)/gdm-manager.xml
-
 gdm-display-glue.c gdm-display-glue.h: gdm-display.xml Makefile.am
 	$(AM_V_GEN)gdbus-codegen 					\
 		--c-namespace=GdmDBus					\
@@ -367,8 +363,6 @@ EXTRA_DIST = 				\
 	gdm-slave.xml			\
 	gdm-simple-slave.xml		\
 	gdm-xdmcp-chooser-slave.xml	\
-	gdm-session.xml			\
-	gdm-manager.xml			\
 	gdm-display.xml			\
 	gdm-xdmcp-display.xml		\
 	gdm-static-display.xml		\
diff --git a/daemon/gdm-display.c b/daemon/gdm-display.c
index 017347d..f51819d 100644
--- a/daemon/gdm-display.c
+++ b/daemon/gdm-display.c
@@ -1207,7 +1207,7 @@ register_display (GdmDisplay *display)
 }
 
 /*
-  dbus-send --system --print-reply --dest=org.gnome.DisplayManager /org/gnome/DisplayManager/Display1 org.freedesktop.DBus.Introspectable.Introspect
+  dbus-send --system --print-reply --dest=org.gnome.DisplayManager /org/gnome/DisplayManager/Displays/1 org.freedesktop.DBus.Introspectable.Introspect
 */
 
 static GObject *
@@ -1223,7 +1223,7 @@ gdm_display_constructor (GType                  type,
                                                                                        construct_properties));
 
         g_free (display->priv->id);
-        display->priv->id = g_strdup_printf ("/org/gnome/DisplayManager/Display%u", get_next_display_serial ());
+        display->priv->id = g_strdup_printf ("/org/gnome/DisplayManager/Displays/%u", get_next_display_serial ());
 
         res = register_display (display);
         if (! res) {
diff --git a/daemon/gdm-local-display-factory.c b/daemon/gdm-local-display-factory.c
index be5620c..eee884f 100644
--- a/daemon/gdm-local-display-factory.c
+++ b/daemon/gdm-local-display-factory.c
@@ -32,6 +32,7 @@
 #include <systemd/sd-daemon.h>
 #endif
 
+#include "gdm-manager.h"
 #include "gdm-display-factory.h"
 #include "gdm-local-display-factory.h"
 #include "gdm-local-display-factory-glue.h"
@@ -77,6 +78,10 @@ static void     gdm_local_display_factory_finalize      (GObject
 static GdmDisplay *create_display                       (GdmLocalDisplayFactory      *factory,
                                                          const char                  *seat_id);
 
+static void     on_display_status_changed               (GdmDisplay                  *display,
+                                                         GParamSpec                  *arg1,
+                                                         GdmLocalDisplayFactory      *factory);
+
 static gpointer local_display_factory_object = NULL;
 
 G_DEFINE_TYPE (GdmLocalDisplayFactory, gdm_local_display_factory, GDM_TYPE_DISPLAY_FACTORY)
@@ -180,6 +185,9 @@ store_display (GdmLocalDisplayFactory *factory,
 {
         GdmDisplayStore *store;
 
+        g_signal_connect (display, "notify::status",
+                          G_CALLBACK (on_display_status_changed), factory);
+
         g_object_weak_ref (G_OBJECT (display), (GWeakNotify)on_display_disposed, factory);
 
         store = gdm_display_factory_get_display_store (GDM_DISPLAY_FACTORY (factory));
@@ -256,9 +264,9 @@ gdm_local_display_factory_create_transient_display (GdmLocalDisplayFactory *fact
 }
 
 static void
-on_static_display_status_changed (GdmDisplay             *display,
-                                  GParamSpec             *arg1,
-                                  GdmLocalDisplayFactory *factory)
+on_display_status_changed (GdmDisplay             *display,
+                           GParamSpec             *arg1,
+                           GdmLocalDisplayFactory *factory)
 {
         int              status;
         GdmDisplayStore *store;
@@ -275,29 +283,40 @@ on_static_display_status_changed (GdmDisplay             *display,
 
         status = gdm_display_get_status (display);
 
-        g_debug ("GdmLocalDisplayFactory: static display status changed: %d", status);
+        g_debug ("GdmLocalDisplayFactory: display status changed: %d", status);
         switch (status) {
         case GDM_DISPLAY_FINISHED:
                 /* remove the display number from factory->priv->displays
                    so that it may be reused */
                 g_hash_table_remove (factory->priv->displays, GUINT_TO_POINTER (num));
                 gdm_display_store_remove (store, display);
-                /* reset num failures */
-                factory->priv->num_failures = 0;
-                create_display (factory, seat_id);
+
+                /* Create a new equivalent display if it was static */
+                if (GDM_IS_STATIC_DISPLAY (display)) {
+                        /* reset num failures */
+                        factory->priv->num_failures = 0;
+
+                        create_display (factory, seat_id);
+                }
                 break;
         case GDM_DISPLAY_FAILED:
                 /* leave the display number in factory->priv->displays
                    so that it doesn't get reused */
                 gdm_display_store_remove (store, display);
-                factory->priv->num_failures++;
-                if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) {
-                        /* oh shit */
-                        g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors");
-                        /* FIXME: should monitor hardware changes to
-                           try again when seats change */
-                } else {
-                        create_display (factory, seat_id);
+
+                /* Create a new equivalent display if it was static */
+                if (GDM_IS_STATIC_DISPLAY (display)) {
+
+                        factory->priv->num_failures++;
+
+                        if (factory->priv->num_failures > MAX_DISPLAY_FAILURES) {
+                                /* oh shit */
+                                g_warning ("GdmLocalDisplayFactory: maximum number of X display failures reached: check X server log for errors");
+                                /* FIXME: should monitor hardware changes to
+                                   try again when seats change */
+                        } else {
+                                create_display (factory, seat_id);
+                        }
                 }
                 break;
         case GDM_DISPLAY_UNMANAGED:
@@ -355,11 +374,6 @@ create_display (GdmLocalDisplayFactory *factory,
 
         g_object_set (display, "seat-id", seat_id, NULL);
 
-        g_signal_connect (display,
-                          "notify::status",
-                          G_CALLBACK (on_static_display_status_changed),
-                          factory);
-
         store_display (factory, num, display);
 
         /* let store own the ref */
diff --git a/daemon/gdm-manager.c b/daemon/gdm-manager.c
index 6cc38e4..c0bdc5c 100644
--- a/daemon/gdm-manager.c
+++ b/daemon/gdm-manager.c
@@ -33,14 +33,10 @@
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
 #include <glib-object.h>
-#define DBUS_API_SUBJECT_TO_CHANGE
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
 
 #include "gdm-common.h"
 
 #include "gdm-manager.h"
-#include "gdm-manager-glue.h"
 #include "gdm-display-store.h"
 #include "gdm-display-factory.h"
 #include "gdm-local-display-factory.h"
@@ -49,7 +45,7 @@
 #define GDM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_MANAGER, GdmManagerPrivate))
 
 #define GDM_DBUS_PATH         "/org/gnome/DisplayManager"
-#define GDM_MANAGER_DBUS_PATH GDM_DBUS_PATH "/Manager"
+#define GDM_MANAGER_DBUS_PATH GDM_DBUS_PATH "/Displays"
 #define GDM_MANAGER_DBUS_NAME "org.gnome.DisplayManager.Manager"
 
 struct GdmManagerPrivate
@@ -65,7 +61,9 @@ struct GdmManagerPrivate
         gboolean                wait_for_go;
         gboolean                no_console;
 
-        DBusGConnection        *connection;
+        GDBusProxy               *bus_proxy;
+        GDBusConnection          *connection;
+        GDBusObjectManagerServer *object_manager;
 };
 
 enum {
@@ -99,6 +97,8 @@ on_display_removed (GdmDisplayStore *display_store,
         display = gdm_display_store_lookup (display_store, id);
 
         if (display != NULL) {
+                g_dbus_object_manager_server_unexport (manager->priv->object_manager, id);
+
                 g_signal_emit (manager, signals[DISPLAY_REMOVED], 0, id);
         }
 }
@@ -113,6 +113,8 @@ on_display_added (GdmDisplayStore *display_store,
         display = gdm_display_store_lookup (display_store, id);
 
         if (display != NULL) {
+                g_dbus_object_manager_server_export (manager->priv->object_manager,
+                                                     gdm_display_get_object_skeleton (display));
                 g_signal_emit (manager, signals[DISPLAY_ADDED], 0, id);
         }
 }
@@ -143,8 +145,8 @@ listify_display_ids (const char *id,
   Example:
   dbus-send --system --dest=org.gnome.DisplayManager \
   --type=method_call --print-reply --reply-timeout=2000 \
-  /org/gnome/DisplayManager/Manager \
-  org.gnome.DisplayManager.Manager.GetDisplays
+  /org/gnome/DisplayManager/Displays \
+  org.freedesktop.ObjectManager.GetAll
 */
 gboolean
 gdm_manager_get_displays (GdmManager *manager,
@@ -230,18 +232,19 @@ static gboolean
 register_manager (GdmManager *manager)
 {
         GError *error = NULL;
+        GDBusObjectManagerServer *object_server;
 
         error = NULL;
-        manager->priv->connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        manager->priv->connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
         if (manager->priv->connection == NULL) {
-                if (error != NULL) {
-                        g_critical ("error getting system bus: %s", error->message);
-                        g_error_free (error);
-                }
+                g_critical ("error getting system bus: %s", error->message);
+                g_error_free (error);
                 exit (1);
         }
 
-        dbus_g_connection_register_g_object (manager->priv->connection, GDM_MANAGER_DBUS_PATH, G_OBJECT (manager));
+        object_server = g_dbus_object_manager_server_new (GDM_MANAGER_DBUS_PATH);
+        g_dbus_object_manager_server_set_connection (object_server, manager->priv->connection);
+        manager->priv->object_manager = object_server;
 
         return TRUE;
 }
@@ -375,8 +378,6 @@ gdm_manager_class_init (GdmManagerClass *klass)
                                                                G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
         g_type_class_add_private (klass, sizeof (GdmManagerPrivate));
-
-        dbus_g_object_type_install_info (GDM_TYPE_MANAGER, &dbus_glib_gdm_manager_object_info);
 }
 
 static void
@@ -415,6 +416,7 @@ gdm_manager_finalize (GObject *object)
 #endif
         g_clear_object (&manager->priv->local_factory);
         g_clear_object (&manager->priv->connection);
+        g_clear_object (&manager->priv->object_manager);
 
         gdm_display_store_clear (manager->priv->display_store);
 
diff --git a/daemon/main.c b/daemon/main.c
index ea34533..0255c53 100644
--- a/daemon/main.c
+++ b/daemon/main.c
@@ -38,10 +38,7 @@
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
 #include <glib-object.h>
-
-#define DBUS_API_SUBJECT_TO_CHANGE
-#include <dbus/dbus-glib.h>
-#include <dbus/dbus-glib-lowlevel.h>
+#include <gio/gio.h>
 
 #include "gdm-manager.h"
 #include "gdm-log.h"
@@ -54,12 +51,13 @@
 
 #define GDM_DBUS_NAME "org.gnome.DisplayManager"
 
-static void bus_proxy_destroyed_cb (DBusGProxy  *bus_proxy,
-                                    GdmManager **managerp);
+static GDBusConnection *get_system_bus (void);
+static gboolean         bus_reconnect (void);
 
 extern char **environ;
 
 static GdmManager      *manager       = NULL;
+static int              name_id       = -1;
 static GdmSettings     *settings      = NULL;
 static uid_t            gdm_uid       = -1;
 static gid_t            gdm_gid       = -1;
@@ -71,76 +69,29 @@ timed_exit_cb (GMainLoop *loop)
         return FALSE;
 }
 
-static DBusGProxy *
-get_bus_proxy (DBusGConnection *connection)
-{
-        DBusGProxy *bus_proxy;
-
-        bus_proxy = dbus_g_proxy_new_for_name (connection,
-                                               DBUS_SERVICE_DBUS,
-                                               DBUS_PATH_DBUS,
-                                               DBUS_INTERFACE_DBUS);
-        return bus_proxy;
-}
-
-static gboolean
-acquire_name_on_proxy (DBusGProxy *bus_proxy)
+static void
+bus_connection_closed (void)
 {
-        GError     *error;
-        guint       result;
-        gboolean    res;
-        gboolean    ret;
-
-        ret = FALSE;
-
-        if (bus_proxy == NULL) {
-                goto out;
-        }
-
-        error = NULL;
-        res = dbus_g_proxy_call (bus_proxy,
-                                 "RequestName",
-                                 &error,
-                                 G_TYPE_STRING, GDM_DBUS_NAME,
-                                 G_TYPE_UINT, 0,
-                                 G_TYPE_INVALID,
-                                 G_TYPE_UINT, &result,
-                                 G_TYPE_INVALID);
-        if (! res) {
-                if (error != NULL) {
-                        g_warning ("Failed to acquire %s: %s", GDM_DBUS_NAME, error->message);
-                        g_error_free (error);
-                } else {
-                        g_warning ("Failed to acquire %s", GDM_DBUS_NAME);
-                }
-                goto out;
-        }
+        g_debug ("Disconnected from D-Bus");
 
-        if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
-                if (error != NULL) {
-                        g_warning ("Failed to acquire %s: %s", GDM_DBUS_NAME, error->message);
-                        g_error_free (error);
-                } else {
-                        g_warning ("Failed to acquire %s", GDM_DBUS_NAME);
-                }
-                goto out;
+        if (manager == NULL) {
+                /* probably shutting down or something */
+                return;
         }
 
-        ret = TRUE;
+        g_clear_object (&manager);
 
- out:
-        return ret;
+        g_timeout_add_seconds (3, (GSourceFunc)bus_reconnect, NULL);
 }
 
-static DBusGConnection *
+static GDBusConnection *
 get_system_bus (void)
 {
         GError          *error;
-        DBusGConnection *bus;
-        DBusConnection  *connection;
+        GDBusConnection *bus;
 
         error = NULL;
-        bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
+        bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
         if (bus == NULL) {
                 g_warning ("Couldn't connect to system bus: %s",
                            error->message);
@@ -148,76 +99,14 @@ get_system_bus (void)
                 goto out;
         }
 
-        connection = dbus_g_connection_get_connection (bus);
-        dbus_connection_set_exit_on_disconnect (connection, FALSE);
+        g_signal_connect (bus, "closed",
+                          G_CALLBACK (bus_connection_closed), NULL);
+        g_dbus_connection_set_exit_on_close (bus, FALSE);
 
  out:
         return bus;
 }
 
-static gboolean
-bus_reconnect (GdmManager *manager)
-{
-        DBusGConnection *bus;
-        DBusGProxy      *bus_proxy;
-        gboolean         ret;
-
-        ret = TRUE;
-
-        bus = get_system_bus ();
-        if (bus == NULL) {
-                goto out;
-        }
-
-        bus_proxy = get_bus_proxy (bus);
-        if (bus_proxy == NULL) {
-                g_warning ("Could not construct bus_proxy object; will retry");
-                goto out;
-        }
-
-        if (! acquire_name_on_proxy (bus_proxy) ) {
-                g_warning ("Could not acquire name; will retry");
-                goto out;
-        }
-
-        manager = gdm_manager_new ();
-        if (manager == NULL) {
-                g_warning ("Could not construct manager object");
-                exit (1);
-        }
-
-        g_signal_connect (bus_proxy,
-                          "destroy",
-                          G_CALLBACK (bus_proxy_destroyed_cb),
-                          &manager);
-
-        g_debug ("Successfully reconnected to D-Bus");
-
-        gdm_manager_start (manager);
-
-        ret = FALSE;
-
- out:
-        return ret;
-}
-
-static void
-bus_proxy_destroyed_cb (DBusGProxy  *bus_proxy,
-                        GdmManager **managerp)
-{
-        g_debug ("Disconnected from D-Bus");
-
-        if (managerp == NULL || *managerp == NULL) {
-                /* probably shutting down or something */
-                return;
-        }
-
-        g_object_unref (*managerp);
-        *managerp = NULL;
-
-        g_timeout_add_seconds (3, (GSourceFunc)bus_reconnect, managerp);
-}
-
 static void
 delete_pid (void)
 {
@@ -527,12 +416,9 @@ main (int    argc,
 {
         GMainLoop          *main_loop;
         GOptionContext     *context;
-        DBusGProxy         *bus_proxy;
-        DBusGConnection    *connection;
         GError             *error;
         int                 ret;
         gboolean            res;
-        gboolean            xdmcp_enabled;
         GdmSignalHandler   *signal_handler;
         static gboolean     do_timed_exit    = FALSE;
         static gboolean     print_version    = FALSE;
@@ -579,22 +465,6 @@ main (int    argc,
                 g_log_set_always_fatal (fatal_mask);
         }
 
-        connection = get_system_bus ();
-        if (connection == NULL) {
-                goto out;
-        }
-
-        bus_proxy = get_bus_proxy (connection);
-        if (bus_proxy == NULL) {
-                g_warning ("Could not construct bus_proxy object; bailing out");
-                goto out;
-        }
-
-        if (! acquire_name_on_proxy (bus_proxy) ) {
-                g_warning ("Could not acquire name; bailing out");
-                goto out;
-        }
-
         gdm_log_init ();
 
         settings = gdm_settings_new ();
@@ -623,27 +493,15 @@ main (int    argc,
                 exit (-1);
         }
 
+        /* Connect to the bus, own the name and start the manager */
+        bus_reconnect ();
+
         /* pid file */
         delete_pid ();
         write_pid ();
 
         g_chdir (AUTHDIR);
 
-        manager = gdm_manager_new ();
-
-        if (manager == NULL) {
-                goto out;
-        }
-
-        xdmcp_enabled = FALSE;
-        gdm_settings_direct_get_boolean (GDM_KEY_XDMCP_ENABLE, &xdmcp_enabled);
-        gdm_manager_set_xdmcp_enabled (manager, xdmcp_enabled);
-
-        g_signal_connect (bus_proxy,
-                          "destroy",
-                          G_CALLBACK (bus_proxy_destroyed_cb),
-                          &manager);
-
         main_loop = g_main_loop_new (NULL, FALSE);
 
         signal_handler = gdm_signal_handler_new ();
@@ -661,23 +519,13 @@ main (int    argc,
                 g_timeout_add_seconds (30, (GSourceFunc) timed_exit_cb, main_loop);
         }
 
-        gdm_manager_start (manager);
-
         g_main_loop_run (main_loop);
 
         g_debug ("GDM finished, cleaning up...");
 
-        if (manager != NULL) {
-                g_object_unref (manager);
-        }
-
-        if (settings != NULL) {
-                g_object_unref (settings);
-        }
-
-        if (signal_handler != NULL) {
-                g_object_unref (signal_handler);
-        }
+        g_clear_object (&manager);
+        g_clear_object (&settings);
+        g_clear_object (&signal_handler);
 
         gdm_settings_direct_shutdown ();
         gdm_log_shutdown ();
@@ -690,3 +538,61 @@ main (int    argc,
 
         return ret;
 }
+
+static void
+on_name_acquired (GDBusConnection *bus,
+                  const char      *name,
+                  gpointer         user_data)
+{
+        gboolean xdmcp_enabled;
+
+        manager = gdm_manager_new ();
+        if (manager == NULL) {
+                g_warning ("Could not construct manager object");
+                exit (1);
+        }
+
+        g_debug ("Successfully connected to D-Bus");
+
+        gdm_manager_start (manager);
+
+        xdmcp_enabled = FALSE;
+        gdm_settings_direct_get_boolean (GDM_KEY_XDMCP_ENABLE, &xdmcp_enabled);
+        gdm_manager_set_xdmcp_enabled (manager, xdmcp_enabled);
+}
+
+static void
+on_name_lost (GDBusConnection *bus,
+              const char      *name,
+              gpointer         user_data)
+{
+        g_debug ("Lost GDM name on bus");
+
+        bus_connection_closed ();
+}
+
+static gboolean
+bus_reconnect ()
+{
+        GDBusConnection *bus;
+        gboolean         ret;
+
+        ret = TRUE;
+
+        bus = get_system_bus ();
+        if (bus == NULL) {
+                goto out;
+        }
+
+        name_id = g_bus_own_name_on_connection (bus,
+                                                GDM_DBUS_NAME,
+                                                G_BUS_NAME_OWNER_FLAGS_NONE,
+                                                on_name_acquired,
+                                                on_name_lost,
+                                                NULL,
+                                                NULL);
+
+        ret = FALSE;
+ out:
+        return ret;
+}
diff --git a/data/gdm.conf.in b/data/gdm.conf.in
index c3e28f5..b455971 100644
--- a/data/gdm.conf.in
+++ b/data/gdm.conf.in
@@ -20,7 +20,6 @@
     <allow send_interface="org.gnome.DisplayManager.Slave"/>
     <allow send_destination="org.gnome.DisplayManager"
            send_interface="org.freedesktop.DBus.Introspectable"/>
-
   </policy>
 
   <policy context="default">
@@ -39,6 +38,8 @@
     <allow send_destination="org.gnome.DisplayManager"
            send_interface="org.freedesktop.DBus.Introspectable"/>
     <allow send_destination="org.gnome.DisplayManager"
+           send_interface="org.freedesktop.DBus.ObjectManager"/>
+    <allow send_destination="org.gnome.DisplayManager"
            send_interface="org.gnome.DisplayManager.Display"
            send_member="GetId"/>
     <allow send_destination="org.gnome.DisplayManager"
@@ -60,11 +61,6 @@
     <allow send_destination="org.gnome.DisplayManager"
            send_interface="org.gnome.DisplayManager.LocalDisplayFactory"
            send_member="CreateTransientDisplay"/>
-
-    <allow send_destination="org.gnome.DisplayManager"
-           send_interface="org.gnome.DisplayManager.Manager"
-           send_member="GetDisplays"/>
-
   </policy>
 
   <policy user="@GDM_USERNAME@">



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]