From 08051e5c746763966f65fb160224d0dc6b359362 Mon Sep 17 00:00:00 2001 From: Marek Kasik Date: Wed, 30 Mar 2011 17:45:23 +0200 Subject: [PATCH] Make CUPS' subscriptions expirable --- gnome-settings-daemon.spec | 8 +- printing-expirable-subscriptions.patch | 294 +++++++++++++++++++++++++ 2 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 printing-expirable-subscriptions.patch 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 2.91.93-2 +- Make CUPS' subscriptions expirable + * Fri Mar 25 2011 Bastien Nocera 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; + +--