Index: test/run-stp-tests.sh =================================================================== --- test/run-stp-tests.sh (revision 8145) +++ test/run-stp-tests.sh (revision 8146) @@ -307,6 +307,7 @@ DocumentRoot $root/doc RequestRoot /tmp/cups-$user/spool TempDir /tmp/cups-$user/spool/temp +MaxSubscriptions 3 MaxLogSize 0 AccessLog /tmp/cups-$user/log/access_log ErrorLog /tmp/cups-$user/log/error_log Index: test/4.4-subscription-ops.test =================================================================== --- test/4.4-subscription-ops.test (revision 8145) +++ test/4.4-subscription-ops.test (revision 8146) @@ -116,7 +116,33 @@ EXPECT notify-events DISPLAY notify-events } +{ + # The name of the test... + NAME "Check MaxSubscriptions limits" + # The operation to use + OPERATION Create-Printer-Subscription + RESOURCE / + + # The attributes to send + GROUP operation + ATTR charset attributes-charset utf-8 + ATTR language attributes-natural-language en + ATTR uri printer-uri $method://$hostname:$port/printers/Test1 + + GROUP subscription + ATTR uri notify-recipient-uri testnotify:// + ATTR keyword notify-events printer-state-changed + ATTR integer notify-lease-duration 5 + + # What statuses are OK? + STATUS client-error-too-many-subscriptions + + # What attributes do we expect? + EXPECT attributes-charset + EXPECT attributes-natural-language +} + # # End of "$Id$" # Index: scheduler/subscriptions.c =================================================================== --- scheduler/subscriptions.c (revision 8145) +++ scheduler/subscriptions.c (revision 8146) @@ -341,9 +341,55 @@ * Limit the number of subscriptions... */ - if (cupsArrayCount(Subscriptions) >= MaxSubscriptions) + if (MaxSubscriptions > 0 && cupsArrayCount(Subscriptions) >= MaxSubscriptions) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAddSubscription: Reached MaxSubscriptions %d", + MaxSubscriptions); return (NULL); + } + if (MaxSubscriptionsPerJob > 0 && job) + { + int count; /* Number of job subscriptions */ + + for (temp = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), + count = 0; + temp; + temp = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if (temp->job == job) + count ++; + + if (count >= MaxSubscriptionsPerJob) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAddSubscription: Reached MaxSubscriptionsPerJob %d " + "for job #%d", MaxSubscriptionsPerJob, job->id); + return (NULL); + } + } + + if (MaxSubscriptionsPerPrinter > 0 && dest) + { + int count; /* Number of printer subscriptions */ + + for (temp = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions), + count = 0; + temp; + temp = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) + if (temp->dest == dest) + count ++; + + if (count >= MaxSubscriptionsPerPrinter) + { + cupsdLogMessage(CUPSD_LOG_DEBUG, + "cupsdAddSubscription: Reached " + "MaxSubscriptionsPerPrinter %d for %s", + MaxSubscriptionsPerPrinter, dest->name); + return (NULL); + } + } + /* * Allocate memory for this subscription... */ @@ -758,7 +804,6 @@ cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); - break; } else if (!strcasecmp(line, "Events")) { Index: scheduler/ipp.c =================================================================== --- scheduler/ipp.c (revision 8145) +++ scheduler/ipp.c (revision 8146) @@ -2119,24 +2119,25 @@ if (mask == CUPSD_EVENT_NONE) mask = CUPSD_EVENT_JOB_COMPLETED; - sub = cupsdAddSubscription(mask, cupsdFindDest(job->dest), job, recipient, - 0); + if ((sub = cupsdAddSubscription(mask, cupsdFindDest(job->dest), job, + recipient, 0)) != NULL) + { + sub->interval = interval; - sub->interval = interval; + cupsdSetString(&sub->owner, job->username); - cupsdSetString(&sub->owner, job->username); + if (user_data) + { + sub->user_data_len = user_data->values[0].unknown.length; + memcpy(sub->user_data, user_data->values[0].unknown.data, + sub->user_data_len); + } - if (user_data) - { - sub->user_data_len = user_data->values[0].unknown.length; - memcpy(sub->user_data, user_data->values[0].unknown.data, - sub->user_data_len); + ippAddSeparator(con->response); + ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, + "notify-subscription-id", sub->id); } - ippAddSeparator(con->response); - ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, - "notify-subscription-id", sub->id); - if (attr) attr = attr->next; } @@ -5590,7 +5591,12 @@ else job = NULL; - sub = cupsdAddSubscription(mask, printer, job, recipient, 0); + if ((sub = cupsdAddSubscription(mask, printer, job, recipient, 0)) == NULL) + { + send_ipp_status(con, IPP_TOO_MANY_SUBSCRIPTIONS, + _("There are too many subscriptions.")); + return; + } if (job) cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for job %d",