[gnome-settings-daemon/f15/master] Make CUPS' subscriptions expirable

mkasik mkasik at fedoraproject.org
Wed Mar 30 15:46:47 UTC 2011


commit 08051e5c746763966f65fb160224d0dc6b359362
Author: Marek Kasik <mkasik at redhat.com>
Date:   Wed Mar 30 17:45:23 2011 +0200

    Make CUPS' subscriptions expirable

 gnome-settings-daemon.spec             |    8 +-
 printing-expirable-subscriptions.patch |  294 ++++++++++++++++++++++++++++++++
 2 files changed, 301 insertions(+), 1 deletions(-)
---
diff --git a/gnome-settings-daemon.spec b/gnome-settings-daemon.spec
index 6aa2e2f..cfaea04 100644
--- a/gnome-settings-daemon.spec
+++ b/gnome-settings-daemon.spec
@@ -1,6 +1,6 @@
 Name:           gnome-settings-daemon
 Version:        2.91.93
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        The daemon sharing settings from GNOME to GTK+/KDE applications
 
 Group:          System Environment/Daemons
@@ -38,6 +38,8 @@ BuildRequires:  upower-devel
 BuildRequires:  libgudev1-devel
 BuildRequires:  nss-devel
 
+Patch0: printing-expirable-subscriptions.patch
+
 %description
 A daemon to share settings from GNOME to other applications. It also
 handles global keybindings, as well as a number of desktop-wide settings.
@@ -54,6 +56,7 @@ developing applications that use %{name}.
 
 %prep
 %setup -q
+%patch0 -p1 -b .subscriptions
 
 autoreconf -i -f
 
@@ -196,6 +199,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor >&/dev/null || :
 %{_datadir}/gnome-settings-daemon-3.0/input-device-example.sh
 
 %changelog
+* Wed Mar 30 2011 Marek Kasik <mkasik at redhat.com> 2.91.93-2
+- Make CUPS' subscriptions expirable
+
 * Fri Mar 25 2011 Bastien Nocera <bnocera at redhat.com> 2.91.93-1
 - Update to 2.91.93
 
diff --git a/printing-expirable-subscriptions.patch b/printing-expirable-subscriptions.patch
new file mode 100644
index 0000000..25a6b45
--- /dev/null
+++ b/printing-expirable-subscriptions.patch
@@ -0,0 +1,294 @@
+--- a/plugins/print-notifications/gsd-print-notifications-manager.c
++++ b/plugins/print-notifications/gsd-print-notifications-manager.c
+@@ -45,6 +45,9 @@
+ #define CUPS_DBUS_PATH      "/org/cups/cupsd/Notifier"
+ #define CUPS_DBUS_INTERFACE "org.cups.cupsd.Notifier"
+ 
++#define RENEW_INTERVAL        3500
++#define SUBSCRIPTION_DURATION 3600
++
+ struct GsdPrintNotificationsManagerPrivate
+ {
+         GDBusProxy                   *cups_proxy;
+@@ -512,14 +515,35 @@ scp_handler (GsdPrintNotificationsManager *manager,
+         }
+ }
+ 
+-gboolean
+-gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
+-                                       GError                      **error)
++static void
++cancel_subscription (gint id)
+ {
+-        GError     *lerror;
+-        ipp_t      *request, *response;
+-        http_t     *http;
+-        gint        num_events = 7;
++        http_t *http;
++        ipp_t  *request;
++
++        if (id >= 0 &&
++            ((http = httpConnectEncrypt (cupsServer (), ippPort (),
++                                        cupsEncryption ())) != NULL)) {
++                request = ippNewRequest (IPP_CANCEL_SUBSCRIPTION);
++                ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
++                             "printer-uri", NULL, "/");
++                ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
++                             "requesting-user-name", NULL, cupsUser ());
++                ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
++                              "notify-subscription-id", id);
++                ippDelete (cupsDoRequest (http, request, "/"));
++        }
++}
++
++static gboolean
++renew_subscription (gpointer data)
++{
++        GsdPrintNotificationsManager *manager = (GsdPrintNotificationsManager *) data;
++        ipp_attribute_t              *attr = NULL;
++        http_t                       *http;
++        ipp_t                        *request;
++        ipp_t                        *response;
++        gint                          num_events = 7;
+         static const char * const events[] = {
+                 "job-created",
+                 "job-completed",
+@@ -528,50 +552,177 @@ gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
+                 "printer-added",
+                 "printer-deleted",
+                 "printer-state-changed"};
+-        ipp_attribute_t *attr = NULL;
+ 
+-        g_debug ("Starting print-notifications manager");
++        if ((http = httpConnectEncrypt (cupsServer (), ippPort (),
++                                        cupsEncryption ())) == NULL) {
++                g_debug ("Connection to CUPS server \'%s\' failed.", cupsServer ());
++        }
++        else {
++                if (manager->priv->subscription_id >= 0) {
++                        request = ippNewRequest (IPP_RENEW_SUBSCRIPTION);
++                        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
++                                     "printer-uri", NULL, "/");
++                        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
++                                     "requesting-user-name", NULL, cupsUser ());
++                        ippAddInteger (request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
++                                      "notify-subscription-id", manager->priv->subscription_id);
++                        ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
++                                      "notify-lease-duration", SUBSCRIPTION_DURATION);
++                        ippDelete (cupsDoRequest (http, request, "/"));
++                }
++                else {
++                        request = ippNewRequest (IPP_CREATE_PRINTER_SUBSCRIPTION);
++                        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
++                                      "printer-uri", NULL,
++                                      "/");
++                        ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME,
++                                      "requesting-user-name", NULL, cupsUser ());
++                        ippAddStrings (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
++                                       "notify-events", num_events, NULL, events);
++                        ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
++                                      "notify-pull-method", NULL, "ippget");
++                        ippAddString (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
++                                      "notify-recipient-uri", NULL, "dbus://");
++                        ippAddInteger (request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
++                                       "notify-lease-duration", SUBSCRIPTION_DURATION);
++                        response = cupsDoRequest (http, request, "/");
++
++                        if (response != NULL && response->request.status.status_code <= IPP_OK_CONFLICT) {
++                                if ((attr = ippFindAttribute (response, "notify-subscription-id",
++                                                              IPP_TAG_INTEGER)) == NULL)
++                                        g_debug ("No notify-subscription-id in response!\n");
++                                else
++                                        manager->priv->subscription_id = attr->values[0].integer;
++                        }
+ 
+-        gnome_settings_profile_start (NULL);
++                        if (response)
++                                ippDelete (response);
++                }
++                httpClose (http);
++        }
++        return TRUE;
++}
+ 
+-        manager->priv->subscription_id = -1;
+-        manager->priv->dests = NULL;
+-        manager->priv->num_dests = 0;
+-        manager->priv->scp_handler_spawned = FALSE;
++static void
++cancel_old_subscriptions ()
++{
++        http_t *http;
++        ipp_t  *request;
++        ipp_t  *response;
++        static const char * const old_events[] = {
++                "printer-state-changed",
++                "printer-restarted",
++                "printer-shutdown",
++                "printer-stopped",
++                "printer-added",
++                "printer-deleted",
++                "job-state-changed",
++                "job-created",
++                "job-completed",
++                "job-stopped" };
+ 
+         if ((http = httpConnectEncrypt (cupsServer (), ippPort (),
+                                         cupsEncryption ())) == NULL) {
+                 g_debug ("Connection to CUPS server \'%s\' failed.", cupsServer ());
+         }
+         else {
+-                request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION);
+-                ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+-                             "/");
+-                ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+-                             NULL, cupsUser ());
+-                ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events",
+-                              num_events, NULL, events);
+-                ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
+-                             "notify-pull-method", NULL, "ippget");
+-                ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI, "notify-recipient-uri",
+-                             NULL, "dbus://");
+-                ippAddInteger(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+-                              "notify-lease-duration", 0);
+-                response = cupsDoRequest(http, request, "/");
++                request = ippNewRequest (IPP_GET_SUBSCRIPTIONS);
++                ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_URI,
++                              "printer-uri", NULL, "/");
++                ippAddString (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
++                              NULL, cupsUser ());
++                ippAddBoolean (request, IPP_TAG_SUBSCRIPTION, "my-subscriptions", 1);
++                response = cupsDoRequest (http, request, "/");
+ 
+                 if (response != NULL && response->request.status.status_code <= IPP_OK_CONFLICT) {
+-                        if ((attr = ippFindAttribute(response, "notify-subscription-id",
+-                                                     IPP_TAG_INTEGER)) == NULL)
+-                                g_debug ("No notify-subscription-id in response!\n");
+-                        else
+-                                manager->priv->subscription_id = attr->values[0].integer;
+-                }
++                        ipp_attribute_t *events;
++                        ipp_attribute_t *attr;
++                        gchar           *recipient_uri;
++                        gint             lease_duration;
++                        gint             id;
++                        gint             i, j;
++
++                        for (attr = response->attrs; attr; attr = attr->next) {
++                                recipient_uri = NULL;
++                                events = NULL;
++                                id = -1;
++                                lease_duration = -1;
++
++                                while (attr && attr->group_tag != IPP_TAG_SUBSCRIPTION)
++                                        attr = attr->next;
++
++                                while (attr && attr->group_tag == IPP_TAG_SUBSCRIPTION) {
++                                        if (g_strcmp0 (attr->name, "notify-subscription-id") == 0)
++                                                id = attr->values[0].integer;
++                                        else if (g_strcmp0 (attr->name, "notify-recipient-uri") == 0)
++                                                recipient_uri = attr->values[0].string.text;
++                                        else if (g_strcmp0 (attr->name, "notify-lease-duration") == 0)
++                                                lease_duration = attr->values[0].integer;
++                                        else if (g_strcmp0 (attr->name, "notify-events") == 0)
++                                                events = attr;
++                                        attr = attr->next;
++                                }
++
++                                if (recipient_uri && events && id >= 0 && lease_duration >=0) {
++                                        gboolean remove = TRUE;
++                                        gboolean have;
++                                        gint length = 0;
++
++                                        if (lease_duration != 0)
++                                                remove = FALSE;
++
++                                        if (g_strcmp0 (recipient_uri, "dbus://") != 0)
++                                                remove = FALSE;
++
++                                        length = G_N_ELEMENTS (old_events);
++                                        if (events->num_values != G_N_ELEMENTS (old_events))
++                                                remove = FALSE;
++                                        else
++                                                for (i = 0; i < events->num_values; i++) {
++                                                        have = FALSE;
++                                                        for (j = 0; j < length; j++) {
++                                                                if (g_strcmp0 (events->values[i].string.text, old_events[j]) == 0)
++                                                                        have = TRUE;
++                                                        }
++                                                        if (!have)
++                                                                remove = FALSE;
++                                                }
++
++                                        if (remove)
++                                                cancel_subscription (id);
++                                }
+ 
+-                if (response)
+-                  ippDelete(response);
++                                if (!attr)
++                                        break;
++                        }
++                }
+ 
+-                httpClose(http);
++                if (response) {
++                        ippDelete (response);
++                        response = NULL;
++                }
+         }
++}
++
++gboolean
++gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
++                                       GError                      **error)
++{
++        GError     *lerror;
++
++        g_debug ("Starting print-notifications manager");
++
++        gnome_settings_profile_start (NULL);
++
++        manager->priv->subscription_id = -1;
++        manager->priv->dests = NULL;
++        manager->priv->num_dests = 0;
++        manager->priv->scp_handler_spawned = FALSE;
++
++        cancel_old_subscriptions ();
++
++        renew_subscription (manager);
++        g_timeout_add_seconds (RENEW_INTERVAL, renew_subscription, manager);
+ 
+         manager->priv->num_dests = cupsGetDests (&manager->priv->dests);
+ 
+@@ -613,27 +764,14 @@ gsd_print_notifications_manager_start (GsdPrintNotificationsManager *manager,
+ void
+ gsd_print_notifications_manager_stop (GsdPrintNotificationsManager *manager)
+ {
+-        ipp_t      *request;
+-        http_t     *http;
+-
+         g_debug ("Stopping print-notifications manager");
+ 
+         cupsFreeDests (manager->priv->num_dests, manager->priv->dests);
+         manager->priv->num_dests = 0;
+         manager->priv->dests = NULL;
+ 
+-        if (manager->priv->subscription_id >= 0 &&
+-            ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+-                                       cupsEncryption())) != NULL)) {
+-                request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION);
+-                ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
+-                             "/");
+-                ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+-                             NULL, cupsUser ());
+-                ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+-                              "notify-subscription-ids", manager->priv->subscription_id);
+-                ippDelete(cupsDoRequest(http, request, "/"));
+-        }
++        if (manager->priv->subscription_id >= 0)
++                cancel_subscription (manager->priv->subscription_id);
+ 
+         manager->priv->cups_bus_connection = NULL;
+ 
+-- 


More information about the scm-commits mailing list