[gnome-settings-daemon] printers: Make CUPS' subscriptions expirable



commit b7b025505fccb161ce9cb2493b117cdc5e342b12
Author: Marek Kasik <mkasik redhat com>
Date:   Wed Mar 30 17:15:22 2011 +0200

    printers: Make CUPS' subscriptions expirable
    
    Set expiration for subscriptions so they don't last forever and
    renew them if needed.

 .../gsd-print-notifications-manager.c              |  242 +++++++++++++++-----
 1 files changed, 190 insertions(+), 52 deletions(-)
---
diff --git a/plugins/print-notifications/gsd-print-notifications-manager.c b/plugins/print-notifications/gsd-print-notifications-manager.c
index 9005714..4f35846 100644
--- 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-id", 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;
 



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