get_notifications(cupsd_client_t *con)	/* I - Client connection */
{
  int			i, j;		/* Looping vars */
  http_status_t		status;		/* Policy status */
  cupsd_subscription_t	*sub;		/* Subscription */
  ipp_attribute_t	*ids,		/* notify-subscription-ids */
			*sequences;	/* notify-sequence-numbers */
  int			min_seq;	/* Minimum sequence number */
  int			interval;	/* Poll interval */


  cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_notifications(con=%p[%d])",
                  con, con->number);

 /*
  * Get subscription attributes...
  */

  ids       = ippFindAttribute(con->request, "notify-subscription-ids",
                               IPP_TAG_INTEGER);
  sequences = ippFindAttribute(con->request, "notify-sequence-numbers",
                               IPP_TAG_INTEGER);

  if (!ids)
  {
    send_ipp_status(con, IPP_BAD_REQUEST,
                    _("Missing notify-subscription-ids attribute."));
    return;
  }

 /*
  * Are the subscription IDs valid?
  */

  for (i = 0, interval = 60; i < ids->num_values; i ++)
  {
    if ((sub = cupsdFindSubscription(ids->values[i].integer)) == NULL)
    {
     /*
      * Bad subscription ID...
      */

      send_ipp_status(con, IPP_NOT_FOUND, _("Subscription #%d does not exist."),
		      ids->values[i].integer);
      return;
    }

   /*
    * Check policy...
    */

    if ((status = cupsdCheckPolicy(sub->dest ? sub->dest->op_policy_ptr :
                                               DefaultPolicyPtr,
                                   con, sub->owner)) != HTTP_OK)
    {
      send_http_error(con, status, sub->dest);
      return;
    }

   /*
    * Check the subscription type and update the interval accordingly.
    */

    if (sub->job && sub->job->state_value == IPP_JOB_PROCESSING &&
        interval > 10)
      interval = 10;
    else if (sub->job && sub->job->state_value >= IPP_JOB_STOPPED)
      interval = 0;
    else if (sub->dest && sub->dest->state == IPP_PRINTER_PROCESSING &&
             interval > 30)
      interval = 30;
  }

 /*
  * Tell the client to poll again in N seconds...
  */

  if (interval > 0)
    ippAddInteger(con->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
                  "notify-get-interval", interval);

  ippAddInteger(con->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
                "printer-up-time", time(NULL));

 /*
  * Copy the subscription event attributes to the response.
  */

  con->response->request.status.status_code =
      interval ? IPP_OK : IPP_OK_EVENTS_COMPLETE;

  for (i = 0; i < ids->num_values; i ++)
  {
   /*
    * Get the subscription and sequence number...
    */

    sub = cupsdFindSubscription(ids->values[i].integer);

    if (sequences && i < sequences->num_values)
      min_seq = sequences->values[i].integer;
    else
      min_seq = 1;

   /*
    * If we don't have any new events, nothing to do here...
    */

    if (min_seq > (sub->first_event_id + cupsArrayCount(sub->events)))
      continue;

   /*
    * Otherwise copy all of the new events...
    */

    if (sub->first_event_id > min_seq)
      j = 0;
    else
      j = min_seq - sub->first_event_id;

    for (; j < cupsArrayCount(sub->events); j ++)
    {
      ippAddSeparator(con->response);

      copy_attrs(con->response,
                 ((cupsd_event_t *)cupsArrayIndex(sub->events, j))->attrs, NULL,
        	 IPP_TAG_EVENT_NOTIFICATION, 0, NULL);
    }
  }
}