]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/ipp.c
Merge changes from CUPS 1.5svn-r9641
[thirdparty/cups.git] / scheduler / ipp.c
index 207596c0859564677453633f6ca956dfea8532be..ef466a1c827b616568990ee3d76593eca0cd2f99 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   IPP routines for the CUPS scheduler.
  *
- *   Copyright 2007-2010 by Apple Inc.
+ *   Copyright 2007-2011 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   This file contains Kerberos support code, copyright 2006 by
 
 #ifdef __APPLE__
 #  include <ApplicationServices/ApplicationServices.h>
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+extern CFUUIDRef ColorSyncCreateUUIDFromUInt32(unsigned id);
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 #  include <CoreFoundation/CoreFoundation.h>
 #  ifdef HAVE_MEMBERSHIP_H
 #    include <membership.h>
@@ -149,9 +152,13 @@ static void        add_printer_state_reasons(cupsd_client_t *con,
 static void    add_queued_job_count(cupsd_client_t *con, cupsd_printer_t *p);
 #ifdef __APPLE__
 static void    apple_init_profile(ppd_file_t *ppd, cups_array_t *languages,
-                                  CMDeviceProfileInfo *profile, unsigned id,
-                                  const char *name, const char *text,
-                                  const char *iccfile);
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+                                   CFMutableDictionaryRef profile,
+#  else
+                                  CMDeviceProfileInfo *profile,
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
+                                  unsigned id, const char *name,
+                                  const char *text, const char *iccfile);
 static void    apple_register_profiles(cupsd_printer_t *p);
 static void    apple_unregister_profiles(cupsd_printer_t *p);
 #endif /* __APPLE__ */
@@ -299,7 +306,7 @@ cupsdProcessIPPRequest(
                  con->request->request.any.version[1]);
 
     send_ipp_status(con, IPP_VERSION_NOT_SUPPORTED,
-                    _("Bad request version number %d.%d"),
+                    _("Bad request version number %d.%d."),
                    con->request->request.any.version[0],
                    con->request->request.any.version[1]);
   }
@@ -314,7 +321,7 @@ cupsdProcessIPPRequest(
                  IPP_BAD_REQUEST, con->http.hostname,
                   con->request->request.any.request_id);
 
-    send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d"),
+    send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d."),
                    con->request->request.any.request_id);
   }
   else if (!con->request->attrs)
@@ -323,7 +330,7 @@ cupsdProcessIPPRequest(
                   "%04X %s No attributes in request",
                  IPP_BAD_REQUEST, con->http.hostname);
 
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in request"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in request."));
   }
   else
   {
@@ -346,7 +353,7 @@ cupsdProcessIPPRequest(
                      IPP_BAD_REQUEST, con->http.hostname);
 
        send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Attribute groups are out of order (%x < %x)"),
+                       _("Attribute groups are out of order (%x < %x)."),
                        attr->group_tag, group);
        break;
       }
@@ -423,7 +430,7 @@ cupsdProcessIPPRequest(
                      IPP_CHARSET, con->http.hostname,
                      charset->values[0].string.text);
        send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Unsupported character set \"%s\""),
+                       _("Unsupported character set \"%s\"."),
                        charset->values[0].string.text);
       }
       else if (!charset || !language ||
@@ -482,7 +489,7 @@ cupsdProcessIPPRequest(
        cupsdLogMessage(CUPSD_LOG_DEBUG, "End of attributes...");
 
        send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Missing required attributes"));
+                       _("Missing required attributes."));
       }
       else
       {
@@ -712,7 +719,7 @@ cupsdProcessIPPRequest(
                            ippOpString(con->request->request.op.operation_id));
 
               send_ipp_status(con, IPP_OPERATION_NOT_SUPPORTED,
-                             _("%s not supported"),
+                             _("%s not supported."),
                              ippOpString(
                                  con->request->request.op.operation_id));
              break;
@@ -898,7 +905,7 @@ accept_jobs(cupsd_client_t  *con,   /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -919,8 +926,6 @@ accept_jobs(cupsd_client_t  *con,   /* I - Client connection */
   printer->accepting        = 1;
   printer->state_message[0] = '\0';
 
-  cupsdAddPrinterHistory(printer);
-
   cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
                 "Now accepting jobs.");
 
@@ -1030,7 +1035,7 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("A printer named \"%s\" already exists"),
+                      _("A printer named \"%s\" already exists."),
                      resource + 9);
       return;
     }
@@ -1130,7 +1135,6 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
                     pclass->name, attr->values[0].boolean, pclass->accepting);
 
     pclass->accepting = attr->values[0].boolean;
-    cupsdAddPrinterHistory(pclass);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s accepting jobs.",
                  pclass->accepting ? "Now" : "No longer");
@@ -1156,7 +1160,7 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
         attr->values[0].integer != IPP_PRINTER_STOPPED)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Attempt to set %s printer-state to bad value %d"),
+                      _("Attempt to set %s printer-state to bad value %d."),
                       pclass->name, attr->values[0].integer);
       return;
     }
@@ -1177,7 +1181,6 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
   {
     strlcpy(pclass->state_message, attr->values[0].string.text,
             sizeof(pclass->state_message));
-    cupsdAddPrinterHistory(pclass);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s",
                   pclass->state_message);
@@ -1214,13 +1217,13 @@ add_class(cupsd_client_t  *con,         /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
+                       _("The printer or class does not exist."));
        return;
       }
       else if (dtype & CUPS_PRINTER_CLASS)
       {
         send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Nested classes are not allowed"));
+                       _("Nested classes are not allowed."));
         return;
       }
 
@@ -1268,8 +1271,6 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
   }
   else
   {
-    cupsdAddPrinterHistory(pclass);
-
     cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
                  pclass, NULL, "New class \"%s\" added by \"%s\".",
                  pclass->name, get_username(con));
@@ -1326,7 +1327,7 @@ add_file(cupsd_client_t *con,             /* I - Connection to client */
 
     if (con)
       send_ipp_status(con, IPP_INTERNAL_ERROR,
-                     _("Unable to allocate memory for file types"));
+                     _("Unable to allocate memory for file types."));
 
     return (-1);
   }
@@ -1384,7 +1385,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
       strcasecmp(con->http.hostname, ServerName))
   {
     send_ipp_status(con, IPP_NOT_AUTHORIZED,
-                    _("The printer or class is not shared"));
+                    _("The printer or class is not shared."));
     return (NULL);
   }
 
@@ -1447,7 +1448,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
              filetype->type);
 
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported format \'%s\'"), mimetype);
+                    _("Unsupported format \"%s\"."), mimetype);
 
     ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
                  "document-format", NULL, mimetype);
@@ -1474,14 +1475,14 @@ add_job(cupsd_client_t  *con,           /* I - Client connection */
     if (attr->value_tag != IPP_TAG_KEYWORD &&
         attr->value_tag != IPP_TAG_NAME)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type"));
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type."));
       return (NULL);
     }
 
     if (attr->num_values > 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Too many job-sheets values (%d > 2)"),
+                      _("Too many job-sheets values (%d > 2)."),
                      attr->num_values);
       return (NULL);
     }
@@ -1490,7 +1491,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
       if (strcmp(attr->values[i].string.text, "none") &&
           !cupsdFindBanner(attr->values[i].string.text))
       {
-       send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\""),
+       send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\"."),
                        attr->values[i].string.text);
        return (NULL);
       }
@@ -1539,7 +1540,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
 
   if (!ippFindAttribute(con->request, "PageRegion", IPP_TAG_ZERO) &&
       !ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) &&
-      _pwgGetPageSize(printer->pwg, con->request, NULL, &exact))
+      _ppdCacheGetPageSize(printer->pc, con->request, NULL, &exact))
   {
     if (!exact &&
         (media_col = ippFindAttribute(con->request, "media-col",
@@ -1587,8 +1588,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
 
   if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs)
   {
-    send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Too many active jobs."));
+    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Too many active jobs."));
     return (NULL);
   }
 
@@ -1629,7 +1629,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
   if ((job = cupsdAddJob(priority, printer->name)) == NULL)
   {
     send_ipp_status(con, IPP_INTERNAL_ERROR,
-                    _("Unable to add job for destination \"%s\""),
+                    _("Unable to add job for destination \"%s\"."),
                    printer->name);
     return (NULL);
   }
@@ -1972,7 +1972,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
   }
   else if ((attr = ippFindAttribute(job->attrs, "job-sheets",
                                     IPP_TAG_ZERO)) != NULL)
-    job->sheets = attr;
+    job->job_sheets = attr;
 
  /*
   * Fill in the response info...
@@ -2159,7 +2159,7 @@ add_job_subscriptions(
                            resource, sizeof(resource)) < HTTP_URI_OK)
         {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-recipient-uri URI \"%s\""), recipient);
+                         _("Bad notify-recipient-uri \"%s\"."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -2171,7 +2171,7 @@ add_job_subscriptions(
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
                          _("notify-recipient-uri URI \"%s\" uses unknown "
-                           "scheme"), recipient);
+                           "scheme."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -2180,7 +2180,7 @@ add_job_subscriptions(
         if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("notify-recipient-uri URI \"%s\" is already used"),
+                         _("notify-recipient-uri URI \"%s\" is already used."),
                          recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
@@ -2195,7 +2195,7 @@ add_job_subscriptions(
         if (strcmp(pullmethod, "ippget"))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-pull-method \"%s\""), pullmethod);
+                         _("Bad notify-pull-method \"%s\"."), pullmethod);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
          return;
@@ -2207,7 +2207,7 @@ add_job_subscriptions(
               strcmp(attr->values[0].string.text, "utf-8"))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Character set \"%s\" not supported"),
+                       _("Character set \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -2216,7 +2216,7 @@ add_job_subscriptions(
                strcmp(attr->values[0].string.text, DefaultLanguage)))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Language \"%s\" not supported"),
+                       _("Language \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -2227,7 +2227,7 @@ add_job_subscriptions(
        {
           send_ipp_status(con, IPP_REQUEST_VALUE,
                          _("The notify-user-data value is too large "
-                           "(%d > 63 octets)"),
+                           "(%d > 63 octets)."),
                          attr->values[0].unknown.length);
          return;
        }
@@ -2332,45 +2332,16 @@ static void
 add_job_uuid(cupsd_client_t *con,      /* I - Client connection */
              cupsd_job_t    *job)      /* I - Job */
 {
-  char                 uuid[1024];     /* job-uuid string */
-  _cups_md5_state_t    md5state;       /* MD5 state */
-  unsigned char                md5sum[16];     /* MD5 digest/sum */
-
-
- /*
-  * First see if the job already has a job-uuid attribute; if so, return...
-  */
-
-  if (ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI))
-    return;
-
- /*
-  * No job-uuid attribute, so build a version 3 UUID with the local job
-  * ID at the end; see RFC 4122 for details.  Start with the MD5 sum of
-  * the ServerName, server name and port that the client connected to,
-  * and local job ID...
-  */
-
-  snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername,
-          con->serverport, job->id);
+  char                 uuid[64];       /* job-uuid string */
 
-  _cupsMD5Init(&md5state);
-  _cupsMD5Append(&md5state, (unsigned char *)uuid, strlen(uuid));
-  _cupsMD5Finish(&md5state, md5sum);
 
  /*
-  * Format the UUID URI using the MD5 sum and job ID.
+  * Add a job-uuid attribute if none exists...
   */
 
-  snprintf(uuid, sizeof(uuid),
-           "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
-          "%02x%02x%02x%02x%02x%02x",
-          md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5],
-          (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40,
-          md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13],
-          md5sum[14], md5sum[15]);
-
-  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid);
+  if (!ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI))
+    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL,
+                cupsdMakeUUID(job->dest, job->id, uuid, sizeof(uuid)));
 }
 
 
@@ -2460,7 +2431,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("A class named \"%s\" already exists"),
+                      _("A class named \"%s\" already exists."),
                      resource + 10);
       return;
     }
@@ -2579,7 +2550,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
 
     if (uri_status < HTTP_URI_OK)
     {
-      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\""),
+      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"."),
                      attr->values[0].string.text);
       cupsdLogMessage(CUPSD_LOG_DEBUG,
                       "add_printer: httpSeparateURI returned %d", uri_status);
@@ -2599,7 +2570,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_POSSIBLE,
-                       _("File device URIs have been disabled! "
+                       _("File device URIs have been disabled. "
                          "To enable, see the FileDevice directive in "
                          "\"%s/cupsd.conf\"."),
                        ServerRoot);
@@ -2619,8 +2590,8 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
         * Could not find device in list!
        */
 
-       send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri scheme \"%s\""),
-                       scheme);
+       send_ipp_status(con, IPP_NOT_POSSIBLE,
+                        _("Bad device-uri scheme \"%s\"."), scheme);
        return;
       }
     }
@@ -2663,7 +2634,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
 
     if (!supported || i >= supported->num_values)
     {
-      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\""),
+      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"."),
                      attr->values[0].string.text);
       return;
     }
@@ -2690,7 +2661,6 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
                     printer->name, attr->values[0].boolean, printer->accepting);
 
     printer->accepting = attr->values[0].boolean;
-    cupsdAddPrinterHistory(printer);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
                   "%s accepting jobs.",
@@ -2716,7 +2686,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
     if (attr->values[0].integer != IPP_PRINTER_IDLE &&
         attr->values[0].integer != IPP_PRINTER_STOPPED)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d"),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d."),
                       attr->values[0].integer);
       return;
     }
@@ -2738,7 +2708,6 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
   {
     strlcpy(printer->state_message, attr->values[0].string.text,
             sizeof(printer->state_message));
-    cupsdAddPrinterHistory(printer);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, "%s",
                   printer->state_message);
@@ -2751,7 +2720,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
             (int)(sizeof(printer->reasons) / sizeof(printer->reasons[0])))
     {
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("Too many printer-state-reasons values (%d > %d)"),
+                      _("Too many printer-state-reasons values (%d > %d)."),
                      attr->num_values,
                      (int)(sizeof(printer->reasons) /
                            sizeof(printer->reasons[0])));
@@ -2926,7 +2895,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
 
       if (copy_model(con, attr->values[0].string.text, dstfile))
       {
-        send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file"));
+        send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file."));
        return;
       }
 
@@ -2945,11 +2914,7 @@ add_printer(cupsd_client_t  *con,        /* I - Client connection */
 
     char cache_name[1024];             /* Cache filename for printer attrs */
 
-    snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp4", CacheDir,
-             printer->name);
-    unlink(cache_name);
-
-    snprintf(cache_name, sizeof(cache_name), "%s/%s.pwg3", CacheDir,
+    snprintf(cache_name, sizeof(cache_name), "%s/%s.data", CacheDir,
              printer->name);
     unlink(cache_name);
 
@@ -3040,8 +3005,6 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
   }
   else
   {
-    cupsdAddPrinterHistory(printer);
-
     cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
                   printer, NULL, "New printer \"%s\" added by \"%s\".",
                  printer->name, get_username(con));
@@ -3108,15 +3071,21 @@ add_queued_job_count(
 
 static void
 apple_init_profile(
-    ppd_file_t          *ppd,          /* I - PPD file */
-    cups_array_t       *languages,     /* I - Languages in the PPD file */
-    CMDeviceProfileInfo *profile,      /* I - Profile record */
-    unsigned            id,            /* I - Profile ID */
-    const char          *name,         /* I - Profile name */
-    const char          *text,         /* I - Profile UI text */
-    const char          *iccfile)      /* I - ICC filename */
+    ppd_file_t             *ppd,       /* I - PPD file */
+    cups_array_t          *languages,  /* I - Languages in the PPD file */
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+    CFMutableDictionaryRef profile,    /* I - Profile dictionary */
+#  else
+    CMDeviceProfileInfo    *profile,   /* I - Profile record */
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
+    unsigned               id,         /* I - Profile ID */
+    const char             *name,      /* I - Profile name */
+    const char             *text,      /* I - Profile UI text */
+    const char             *iccfile)   /* I - ICC filename */
 {
-  char                 url[1024];      /* URL for profile filename */
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+  CFURLRef             url;            /* URL for profile filename */
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
   CFMutableDictionaryRef dict;         /* Dictionary for name */
   char                 *language;      /* Current language */
   ppd_attr_t           *attr;          /* Profile attribute */
@@ -3137,7 +3106,7 @@ apple_init_profile(
 
   if (cftext)
   {
-    CFDictionarySetValue(dict, CFSTR("en"), cftext);
+    CFDictionarySetValue(dict, CFSTR("en_US"), cftext);
     CFRelease(cftext);
   }
 
@@ -3187,10 +3156,24 @@ apple_init_profile(
   * Fill in the profile data...
   */
 
-  if (iccfile)
-    httpAssembleURI(HTTP_URI_CODING_ALL, url, sizeof(url), "file", NULL, "", 0,
-                   iccfile);
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+ if (iccfile)
+ {
+    url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
+                                                 (const UInt8 *)iccfile,
+                                                  strlen(iccfile), false);
 
+    if (url)
+    {
+      CFDictionarySetValue(profile, kColorSyncDeviceProfileURL, url);
+      CFRelease(url);
+    }
+  }
+
+  CFDictionarySetValue(profile, kColorSyncDeviceModeDescriptions, dict);
+  CFRelease(dict);
+
+#  else
   profile->dataVersion        = cmDeviceProfileInfoVersion1;
   profile->profileID          = id;
   profile->profileLoc.locType = iccfile ? cmPathBasedProfile : cmNoProfileBase;
@@ -3199,6 +3182,7 @@ apple_init_profile(
   if (iccfile)
     strlcpy(profile->profileLoc.u.pathLoc.path, iccfile,
            sizeof(profile->profileLoc.u.pathLoc.path));
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 }
 
 
@@ -3230,13 +3214,19 @@ apple_register_profiles(
   ppd_option_t         *cm_option;     /* Color model option */
   ppd_choice_t         *cm_choice;     /* Color model choice */
   int                  num_profiles;   /* Number of profiles */
-  CMError              error;          /* Last error */
+  OSStatus             error = 0;      /* Last error */
   unsigned             device_id,      /* Printer device ID */
                        profile_id,     /* Profile ID */
                        default_profile_id = 0;
                                        /* Default profile ID */
   CFMutableDictionaryRef device_name;  /* Printer device name dictionary */
   CFStringRef          printer_name;   /* Printer name string */
+  cups_array_t         *languages;     /* Languages array */
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+  CFMutableDictionaryRef profiles,     /* Dictionary of profiles */
+                       profile;        /* Current profile info dictionary */
+  CFStringRef          dict_key;       /* Key in factory profile dictionary */
+#  else
   CMDeviceScope                scope =         /* Scope of the registration */
                        {
                          kCFPreferencesAnyUser,
@@ -3244,15 +3234,21 @@ apple_register_profiles(
                        };
   CMDeviceProfileArrayPtr profiles;    /* Profiles */
   CMDeviceProfileInfo  *profile;       /* Current profile */
-  cups_array_t         *languages;     /* Languages array */
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 
 
  /*
   * Make sure ColorSync is available...
   */
 
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+  if (ColorSyncRegisterDevice == NULL)
+    return;
+
+#  else
   if (CMRegisterColorDevice == NULL)
     return;
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 
  /*
   * Try opening the PPD file for this printer...
@@ -3289,6 +3285,22 @@ apple_register_profiles(
       num_profiles ++;
     }
 
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+ /*
+  * Create a dictionary for the factory profiles...
+  */
+
+  profiles = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                      &kCFTypeDictionaryKeyCallBacks,
+                                      &kCFTypeDictionaryValueCallBacks);
+  if (!profiles)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR,
+                   "Unable to allocate memory for factory profiles.");
+    ppdClose(ppd);
+    return;
+  }
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 
  /*
   * If we have profiles, add them...
@@ -3358,6 +3370,7 @@ apple_register_profiles(
        q3_choice = NULL;
     }
 
+#  ifndef HAVE_COLORSYNCREGISTERDEVICE
    /*
     * Build the array of profiles...
     *
@@ -3367,17 +3380,22 @@ apple_register_profiles(
     if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to allocate memory for %d profiles",
-                     num_profiles);
+                      "Unable to allocate memory for factory profiles.");
       ppdClose(ppd);
       return;
     }
 
     profiles->profileCount = num_profiles;
-    languages              = _ppdGetLanguages(ppd);
+    profile = profiles->profiles;
+#  endif /* !HAVE_COLORSYNCREGISTERDEVICE */
+
+   /*
+    * Loop through the profiles listed in the PPD...
+    */
 
-    for (profile = profiles->profiles,
-             attr = ppdFindAttr(ppd, profile_key, NULL);
+    languages = _ppdGetLanguages(ppd);
+
+    for (attr = ppdFindAttr(ppd, profile_key, NULL);
         attr;
         attr = ppdFindNextAttr(ppd, profile_key, NULL))
       if (attr->spec[0] && attr->value && attr->value[0])
@@ -3411,50 +3429,91 @@ apple_register_profiles(
        else
          profile_id = atoi(attr->spec);
 
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+       profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                           &kCFTypeDictionaryKeyCallBacks,
+                                           &kCFTypeDictionaryValueCallBacks);
+       if (!profile)
+       {
+         cupsdLogMessage(CUPSD_LOG_ERROR,
+                         "Unable to allocate memory for color profile.");
+         CFRelease(profiles);
+         ppdClose(ppd);
+         return;
+       }
+
+       apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
+                          attr->text[0] ? attr->text : attr->spec, iccfile);
+
+       dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                                           CFSTR("%u"), profile_id);
+       if (dict_key)
+       {
+         CFDictionarySetValue(profiles, dict_key, profile);
+         CFRelease(dict_key);
+       }
+
+       CFRelease(profile);
+
+#  else
         apple_init_profile(ppd, languages, profile, profile_id, attr->spec,
                           attr->text[0] ? attr->text : attr->spec, iccfile);
 
        profile ++;
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 
        /*
         * See if this is the default profile...
        */
 
-        if (!default_profile_id)
+        if (!default_profile_id && q1_choice && q2_choice && q3_choice)
        {
-         if (q2_choice)
-         {
-           if (q3_choice)
-           {
-             snprintf(selector, sizeof(selector), "%s.%s.%s",
-                      q1_choice, q2_choice, q3_choice);
-              if (!strcmp(selector, attr->spec))
-               default_profile_id = profile_id;
-            }
+         snprintf(selector, sizeof(selector), "%s.%s.%s", q1_choice, q2_choice,
+                  q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
 
-            if (!default_profile_id)
-           {
-             snprintf(selector, sizeof(selector), "%s.%s.", q1_choice,
-                      q2_choice);
-              if (!strcmp(selector, attr->spec))
-               default_profile_id = profile_id;
-           }
-          }
+        if (!default_profile_id && q1_choice && q2_choice)
+       {
+         snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, q2_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
 
-          if (!default_profile_id && q3_choice)
-         {
-           snprintf(selector, sizeof(selector), "%s..%s", q1_choice,
-                    q3_choice);
-           if (!strcmp(selector, attr->spec))
-             default_profile_id = profile_id;
-         }
+        if (!default_profile_id && q1_choice && q3_choice)
+       {
+         snprintf(selector, sizeof(selector), "%s..%s", q1_choice, q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
 
-          if (!default_profile_id)
-         {
-           snprintf(selector, sizeof(selector), "%s..", q1_choice);
-           if (!strcmp(selector, attr->spec))
-             default_profile_id = profile_id;
-         }
+        if (!default_profile_id && q1_choice)
+       {
+         snprintf(selector, sizeof(selector), "%s..", q1_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
+
+        if (!default_profile_id && q2_choice && q3_choice)
+       {
+         snprintf(selector, sizeof(selector), ".%s.%s", q2_choice, q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
+
+        if (!default_profile_id && q2_choice)
+       {
+         snprintf(selector, sizeof(selector), ".%s.", q2_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
+
+        if (!default_profile_id && q3_choice)
+       {
+         snprintf(selector, sizeof(selector), "..%s", q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
        }
       }
 
@@ -3471,21 +3530,26 @@ apple_register_profiles(
 
     num_profiles = cm_option->num_choices;
 
+#  ifndef HAVE_COLORSYNCREGISTERDEVICE
+   /*
+    * Create an array for the factory profiles...
+    */
+
     if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to allocate memory for %d profiles",
-                     num_profiles);
+                      "Unable to allocate memory for factory profiles.");
       ppdClose(ppd);
       return;
     }
 
     profiles->profileCount = num_profiles;
+    profile = profiles->profiles;
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 
-    for (profile = profiles->profiles, i = cm_option->num_choices,
-             cm_choice = cm_option->choices;
+    for (i = cm_option->num_choices, cm_choice = cm_option->choices;
          i > 0;
-        i --, cm_choice ++, profile ++)
+        i --, cm_choice ++)
     {
       if (!strcmp(cm_choice->choice, "Gray") ||
           !strcmp(cm_choice->choice, "Black"))
@@ -3502,9 +3566,38 @@ apple_register_profiles(
       snprintf(selector, sizeof(selector), "%s..", profile_name);
       profile_id = _ppdHashName(selector);
 
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+      profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                         &kCFTypeDictionaryKeyCallBacks,
+                                         &kCFTypeDictionaryValueCallBacks);
+      if (!profile)
+      {
+       cupsdLogMessage(CUPSD_LOG_ERROR,
+                       "Unable to allocate memory for color profile.");
+       CFRelease(profiles);
+       ppdClose(ppd);
+       return;
+      }
+
       apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice,
                          cm_choice->text, NULL);
 
+      dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                                          CFSTR("%u"), profile_id);
+      if (dict_key)
+      {
+       CFDictionarySetValue(profiles, dict_key, profile);
+       CFRelease(dict_key);
+      }
+
+      CFRelease(profile);
+
+#  else
+      apple_init_profile(ppd, NULL, profile, profile_id, cm_choice->choice,
+                         cm_choice->text, NULL);
+      profile ++;
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
+
       if (cm_choice->marked)
         default_profile_id = profile_id;
     }
@@ -3519,31 +3612,133 @@ apple_register_profiles(
 
     num_profiles = (attr && ppd->colorspace == PPD_CS_GRAY) ? 1 : 2;
 
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+   /*
+    * Add the grayscale profile first.  We always have a grayscale profile.
+    */
+
+    profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                       &kCFTypeDictionaryKeyCallBacks,
+                                       &kCFTypeDictionaryValueCallBacks);
+
+    if (!profile)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Unable to allocate memory for color profile.");
+      CFRelease(profiles);
+      ppdClose(ppd);
+      return;
+    }
+
+    profile_id = _ppdHashName("Gray..");
+    apple_init_profile(ppd, NULL, profile, profile_id, "Gray", "Gray", NULL);
+
+    dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
+                                        profile_id);
+    if (dict_key)
+    {
+      CFDictionarySetValue(profiles, dict_key, profile);
+      CFRelease(dict_key);
+    }
+
+    CFRelease(profile);
+
+   /*
+    * Then add the RGB/CMYK/DeviceN color profile...
+    */
+
+    profile = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                       &kCFTypeDictionaryKeyCallBacks,
+                                       &kCFTypeDictionaryValueCallBacks);
+
+    if (!profile)
+    {
+      cupsdLogMessage(CUPSD_LOG_ERROR,
+                      "Unable to allocate memory for color profile.");
+      CFRelease(profiles);
+      ppdClose(ppd);
+      return;
+    }
+
+    switch (ppd->colorspace)
+    {
+      case PPD_CS_RGB :
+      case PPD_CS_CMY :
+          profile_id = _ppdHashName("RGB..");
+          apple_init_profile(ppd, NULL, profile, profile_id, "RGB", "RGB",
+                            NULL);
+          break;
+      case PPD_CS_RGBK :
+      case PPD_CS_CMYK :
+          profile_id = _ppdHashName("CMYK..");
+          apple_init_profile(ppd, NULL, profile, profile_id, "CMYK", "CMYK",
+                            NULL);
+          break;
+
+      case PPD_CS_GRAY :
+          if (attr)
+            break;
+
+      case PPD_CS_N :
+          profile_id = _ppdHashName("DeviceN..");
+          apple_init_profile(ppd, NULL, profile, profile_id, "DeviceN",
+                            "DeviceN", NULL);
+          break;
+    }
+
+    if (CFDictionaryGetCount(profile) > 0)
+    {
+      dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
+                                          CFSTR("%u"), profile_id);
+      if (dict_key)
+      {
+        CFDictionarySetValue(profiles, dict_key, profile);
+        CFRelease(dict_key);
+      }
+    }
+
+    CFRelease(profile);
+
+#  else
+   /*
+    * Create an array for the factory profiles...
+    */
+
     if ((profiles = calloc(num_profiles, sizeof(CMDeviceProfileArray))) == NULL)
     {
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                      "Unable to allocate memory for %d profiles",
-                     num_profiles);
+                      "Unable to allocate memory for factory profiles.");
       ppdClose(ppd);
       return;
     }
 
     profiles->profileCount = num_profiles;
 
-    apple_init_profile(ppd, NULL, profiles->profiles, _ppdHashName("Gray.."),
-                       "Gray", "Gray", NULL);
+   /*
+    * Add the grayscale profile first.  We always have a grayscale profile.
+    */
+
+    profile_id = _ppdHashName("Gray..");
+    apple_init_profile(ppd, NULL, profiles->profiles, profile_id, "Gray",
+                       "Gray", NULL);
+
+   /*
+    * Then add the RGB/CMYK/DeviceN color profile...
+    */
 
     switch (ppd->colorspace)
     {
       case PPD_CS_RGB :
       case PPD_CS_CMY :
-          apple_init_profile(ppd, NULL, profiles->profiles + 1,
-                            _ppdHashName("RGB.."), "RGB", "RGB", NULL);
+          profile_id = _ppdHashName("RGB..");
+          apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
+                            "RGB", "RGB", NULL);
           break;
       case PPD_CS_RGBK :
       case PPD_CS_CMYK :
-          apple_init_profile(ppd, NULL, profiles->profiles + 1,
-                            _ppdHashName("CMYK.."), "CMYK", "CMYK", NULL);
+          profile_id = _ppdHashName("CMYK..");
+          apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
+                            "CMYK", "CMYK", NULL);
           break;
 
       case PPD_CS_GRAY :
@@ -3551,11 +3746,12 @@ apple_register_profiles(
            break;
 
       case PPD_CS_N :
-          apple_init_profile(ppd, NULL, profiles->profiles + 1,
-                            _ppdHashName("DeviceN.."), "DeviceN", "DeviceN",
-                            NULL);
+          profile_id = _ppdHashName("DeviceN..");
+          apple_init_profile(ppd, NULL, profiles->profiles + 1, profile_id,
+                            "DeviceN", "DeviceN", NULL);
           break;
     }
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
   }
 
   if (num_profiles > 0)
@@ -3565,7 +3761,18 @@ apple_register_profiles(
     */
 
     if (!default_profile_id)
-      default_profile_id = profiles->profiles[num_profiles - 1].profileID;
+      default_profile_id = profile_id; /* Last profile */
+
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+    dict_key = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%u"),
+                                        default_profile_id);
+    if (dict_key)
+    {
+      CFDictionarySetValue(profiles, kColorSyncDeviceDefaultProfileID,
+                           dict_key);
+      CFRelease(dict_key);
+    }
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 
    /*
     * Get the device ID hash and pathelogical name dictionary.
@@ -3583,12 +3790,61 @@ apple_register_profiles(
 
     if (device_name && printer_name)
     {
-      CFDictionarySetValue(device_name, CFSTR("en"), printer_name);
+      CFDictionarySetValue(device_name, CFSTR("en_US"), printer_name);
 
      /*
       * Register the device with ColorSync...
       */
 
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+      CFTypeRef                deviceDictKeys[] =
+      {                                        /* Device keys */
+        kColorSyncDeviceDescriptions,
+       kColorSyncFactoryProfiles,
+       kColorSyncDeviceUserScope,
+       kColorSyncDeviceHostScope
+      };
+      CFTypeRef        deviceDictVals[] =
+      {                                        /* Device values */
+        device_name,
+       profiles,
+       kCFPreferencesAnyUser,
+       kCFPreferencesCurrentHost
+      };
+      CFDictionaryRef  deviceDict;     /* Device dictionary */
+      CFStringRef      printerUUID;    /* Printer UUID */
+      CFUUIDRef                deviceUUID;     /* Device UUID */
+
+      deviceDict = CFDictionaryCreate(kCFAllocatorDefault,
+                                     (const void **)deviceDictKeys,
+                                     (const void **)deviceDictVals,
+                                     sizeof(deviceDictKeys) /
+                                         sizeof(deviceDictKeys[0]),
+                                     &kCFTypeDictionaryKeyCallBacks,
+                                     &kCFTypeDictionaryValueCallBacks);
+      printerUUID = CFStringCreateWithCString(kCFAllocatorDefault,
+                                              p->uuid + 9, /* Skip urn:uuid: */
+                                             kCFStringEncodingUTF8);
+      if (printerUUID)
+      {
+        deviceUUID = CFUUIDCreateFromString(kCFAllocatorDefault, printerUUID);
+       CFRelease(printerUUID);
+
+       if (!deviceDict || !deviceUUID ||
+           !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
+                                    deviceDict))
+         error = 1001;
+      }
+      else
+        error = 1001;
+
+      if (deviceUUID)
+        CFRelease(deviceUUID);
+
+      if (deviceDict)
+        CFRelease(deviceDict);
+
+#  else
       error = CMRegisterColorDevice(cmPrinterDeviceClass, device_id,
                                     device_name, &scope);
 
@@ -3599,6 +3855,7 @@ apple_register_profiles(
       if (error == noErr)
        error = CMSetDeviceFactoryProfiles(cmPrinterDeviceClass, device_id,
                                           default_profile_id, profiles);
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
     }
     else
       error = 1000;
@@ -3609,22 +3866,34 @@ apple_register_profiles(
 
     if (error != noErr)
       cupsdLogMessage(CUPSD_LOG_ERROR,
-                     "Unable to register ICC color profiles for \"%s\" - %d",
+                     "Unable to register ICC color profiles for \"%s\": %d",
                      p->name, (int)error);
 
+    if (printer_name)
+      CFRelease(printer_name);
+
+    if (device_name)
+      CFRelease(device_name);
+  }
+
+ /*
+  * Free any memory we used...
+  */
+
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+  CFRelease(profiles);
+
+#  else
+  if (num_profiles > 0)
+  {
     for (profile = profiles->profiles;
         num_profiles > 0;
         profile ++, num_profiles --)
       CFRelease(profile->profileName);
 
     free(profiles);
-
-    if (printer_name)
-      CFRelease(printer_name);
-
-    if (device_name)
-      CFRelease(device_name);
   }
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 
   ppdClose(ppd);
 }
@@ -3643,11 +3912,48 @@ apple_unregister_profiles(
   * Make sure ColorSync is available...
   */
 
+#  ifdef HAVE_COLORSYNCREGISTERDEVICE
+  if (ColorSyncUnregisterDevice != NULL)
+  {
+   /*
+    * Because we may have registered the printer profiles using a prior device
+    * ID-based UUID, remove both the old style UUID and current UUID for the
+    * printer.
+    */
+
+    CFStringRef printerUUID;           /* Printer UUID */
+    CFUUIDRef deviceUUID;              /* Device UUID */
+
+    deviceUUID = ColorSyncCreateUUIDFromUInt32(_ppdHashName(p->name));
+    if (deviceUUID)
+    {
+      ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID);
+      CFRelease(deviceUUID);
+    }
+
+    printerUUID = CFStringCreateWithCString(kCFAllocatorDefault, p->uuid + 9,
+                                            kCFStringEncodingUTF8);
+    if (printerUUID)
+    {
+      deviceUUID = CFUUIDCreateFromString(kCFAllocatorDefault, printerUUID);
+      if (deviceUUID)
+      {
+       ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID);
+       CFRelease(deviceUUID);
+      }
+
+      CFRelease(printerUUID);
+    }
+  }
+
+#  else
   if (CMUnregisterColorDevice != NULL)
     CMUnregisterColorDevice(cmPrinterDeviceClass, _ppdHashName(p->name));
+#  endif /* HAVE_COLORSYNCREGISTERDEVICE */
 }
 #endif /* __APPLE__ */
 
+
 /*
  * 'apply_printer_defaults()' - Apply printer default options to a job.
  */
@@ -3733,7 +4039,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -3755,7 +4061,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -3773,8 +4079,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -3789,7 +4094,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d is not held for authentication"),
+                    _("Job #%d is not held for authentication."),
                    jobid);
     return;
   }
@@ -3817,7 +4122,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
       send_http_error(con, HTTP_UNAUTHORIZED, printer);
     else
       send_ipp_status(con, IPP_NOT_AUTHORIZED,
-                     _("No authentication information provided"));
+                     _("No authentication information provided."));
     return;
   }
 
@@ -3858,7 +4163,11 @@ authenticate_job(cupsd_client_t  *con,   /* I - Client connection */
 
   cupsdReleaseJob(job);
 
+  cupsdAddEvent(CUPSD_EVENT_JOB_STATE, NULL, job, "Job authenticated by user");
+
   cupsdLogJob(job, CUPSD_LOG_INFO, "Authenticated by \"%s\".", con->username);
+
+  cupsdCheckJobs();
 }
 
 
@@ -3912,7 +4221,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
          else
          {
            send_ipp_status(con, IPP_BAD_REQUEST,
-                           _("Missing requesting-user-name attribute"));
+                           _("Missing requesting-user-name attribute."));
            return;
          }
        }
@@ -3937,7 +4246,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
         else
         {
          send_ipp_status(con, IPP_BAD_REQUEST,
-                         _("Missing requesting-user-name attribute"));
+                         _("Missing requesting-user-name attribute."));
          return;
         }
 
@@ -3954,7 +4263,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
   if (strcmp(uri->name, "printer-uri"))
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("The printer-uri attribute is required"));
+                    _("The printer-uri attribute is required."));
     return;
   }
 
@@ -3977,7 +4286,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
         (!strncmp(resource, "/classes/", 9) && resource[9]))
     {
       send_ipp_status(con, IPP_NOT_FOUND,
-                      _("The printer or class was not found."));
+                      _("The printer or class does not exist."));
       return;
     }
 
@@ -4001,7 +4310,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
 
       if (i < job_ids->num_values)
       {
-       send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+       send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                        job_ids->values[i].integer);
        return;
       }
@@ -4056,7 +4365,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
 
       if (i < job_ids->num_values)
       {
-       send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+       send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                        job_ids->values[i].integer);
        return;
       }
@@ -4131,7 +4440,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -4148,7 +4457,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
+                       _("The printer or class does not exist."));
        return;
       }
 
@@ -4182,7 +4491,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
          jobid = job->id;
        else
        {
-         send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s"),
+         send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s."),
                          printer->name);
          return;
        }
@@ -4205,8 +4514,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -4234,7 +4542,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -4329,7 +4637,7 @@ cancel_subscription(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good"), sub_id);
+                    _("Subscription #%d does not exist."), sub_id);
     return;
   }
 
@@ -4667,7 +4975,7 @@ close_job(cupsd_client_t  *con,           /* I - Client connection */
                               IPP_TAG_INTEGER)) == NULL)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                   _("Got a printer-uri attribute but no job-id"));
+                   _("Got a printer-uri attribute but no job-id."));
     return;
   }
 
@@ -4677,7 +4985,7 @@ close_job(cupsd_client_t  *con,           /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"),
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                     attr->values[0].integer);
     return;
   }
@@ -4965,7 +5273,7 @@ copy_attrs(ipp_t        *to,              /* I - Destination request */
          fromattr->group_tag != IPP_TAG_ZERO) || !fromattr->name)
       continue;
 
-    if (exclude && 
+    if (exclude &&
         (cupsArrayFind(exclude, fromattr->name) ||
         cupsArrayFind(exclude, "all")))
     {
@@ -5189,7 +5497,11 @@ copy_banner(cupsd_client_t *con, /* I - Client connection */
          case IPP_TAG_ENUM :
              if (!strncmp(s, "time-at-", 8))
              {
-               struct timeval tv = { attr->values[i].integer, 0 };
+               struct timeval tv;      /* Time value */
+
+               tv.tv_sec  = attr->values[i].integer;
+               tv.tv_usec = 0;
+
                cupsFilePuts(out, cupsdGetDateTime(&tv, CUPSD_TIME_STANDARD));
              }
              else
@@ -5698,7 +6010,6 @@ copy_printer_attrs(
                                        /* Printer icons */
   time_t               curtime;        /* Current time */
   int                  i;              /* Looping var */
-  ipp_attribute_t      *history;       /* History collection */
 
 
  /*
@@ -5836,23 +6147,6 @@ copy_printer_attrs(
     ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                   "printer-state-change-time", printer->state_time);
 
-  if (MaxPrinterHistory > 0 && printer->num_history > 0 &&
-      cupsArrayFind(ra, "printer-state-history"))
-  {
-   /*
-    * Printer history is only sent if specifically requested, so that
-    * older CUPS/IPP clients won't barf on the collection attributes.
-    */
-
-    history = ippAddCollections(con->response, IPP_TAG_PRINTER,
-                                "printer-state-history",
-                                printer->num_history, NULL);
-
-    for (i = 0; i < printer->num_history; i ++)
-      copy_attrs(history->values[i].collection = ippNew(), printer->history[i],
-                 NULL, IPP_TAG_ZERO, 0, NULL);
-  }
-
   if (!ra || cupsArrayFind(ra, "printer-state-message"))
     ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
                 "printer-state-message", NULL, printer->state_message);
@@ -5864,7 +6158,6 @@ copy_printer_attrs(
   {
     int type;                          /* printer-type value */
 
-
    /*
     * Add the CUPS-specific printer-type attribute...
     */
@@ -6057,7 +6350,7 @@ create_job(cupsd_client_t  *con,  /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -6360,7 +6653,7 @@ create_subscription(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -6401,7 +6694,7 @@ create_subscription(
   if (!attr)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("No subscription attributes in request"));
+                    _("No subscription attributes in request."));
     return;
   }
 
@@ -6459,7 +6752,7 @@ create_subscription(
                            resource, sizeof(resource)) < HTTP_URI_OK)
         {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-recipient-uri URI \"%s\""), recipient);
+                         _("Bad notify-recipient-uri \"%s\"."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -6471,7 +6764,7 @@ create_subscription(
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
                          _("notify-recipient-uri URI \"%s\" uses unknown "
-                           "scheme"), recipient);
+                           "scheme."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -6480,7 +6773,7 @@ create_subscription(
         if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("notify-recipient-uri URI \"%s\" is already used"),
+                         _("notify-recipient-uri URI \"%s\" is already used."),
                          recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
@@ -6495,7 +6788,7 @@ create_subscription(
         if (strcmp(pullmethod, "ippget"))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-pull-method \"%s\""), pullmethod);
+                         _("Bad notify-pull-method \"%s\"."), pullmethod);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
          return;
@@ -6507,7 +6800,7 @@ create_subscription(
               strcmp(attr->values[0].string.text, "utf-8"))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Character set \"%s\" not supported"),
+                       _("Character set \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -6516,7 +6809,7 @@ create_subscription(
                strcmp(attr->values[0].string.text, DefaultLanguage)))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Language \"%s\" not supported"),
+                       _("Language \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -6527,7 +6820,7 @@ create_subscription(
        {
           send_ipp_status(con, IPP_REQUEST_VALUE,
                          _("The notify-user-data value is too large "
-                           "(%d > 63 octets)"),
+                           "(%d > 63 octets)."),
                          attr->values[0].unknown.length);
          return;
        }
@@ -6575,7 +6868,7 @@ create_subscription(
       else
       {
         send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("notify-events not specified"));
+                       _("notify-events not specified."));
        return;
       }
     }
@@ -6593,7 +6886,8 @@ create_subscription(
     {
       if ((job = cupsdFindJob(jobid)) == NULL)
       {
-       send_ipp_status(con, IPP_NOT_FOUND, _("Job %d not found"), jobid);
+       send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
+                       jobid);
        return;
       }
     }
@@ -6608,14 +6902,14 @@ create_subscription(
     }
 
     if (job)
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for job %d",
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription #%d for job %d.",
                      sub->id, job->id);
     else if (printer)
       cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "Added subscription %d for printer \"%s\"",
+                      "Added subscription #%d for printer \"%s\".",
                      sub->id, printer->name);
     else
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for server",
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription #%d for server.",
                      sub->id);
 
     sub->interval = interval;
@@ -6673,7 +6967,7 @@ delete_printer(cupsd_client_t  *con,      /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -6716,13 +7010,10 @@ delete_printer(cupsd_client_t  *con,    /* I - Client connection */
            printer->name);
   unlink(filename);
 
-  snprintf(filename, sizeof(filename), "%s/%s.ipp4", CacheDir, printer->name);
-  unlink(filename);
-
   snprintf(filename, sizeof(filename), "%s/%s.png", CacheDir, printer->name);
   unlink(filename);
 
-  snprintf(filename, sizeof(filename), "%s/%s.pwg3", CacheDir, printer->name);
+  snprintf(filename, sizeof(filename), "%s/%s.data", CacheDir, printer->name);
   unlink(filename);
 
 #ifdef __APPLE__
@@ -6796,7 +7087,7 @@ get_default(cupsd_client_t *con)  /* I - Client connection */
     con->response->request.status.status_code = IPP_OK;
   }
   else
-    send_ipp_status(con, IPP_NOT_FOUND, _("No default printer"));
+    send_ipp_status(con, IPP_NOT_FOUND, _("No default printer."));
 }
 
 
@@ -6933,7 +7224,7 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -6955,8 +7246,7 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -6974,7 +7264,7 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -6982,7 +7272,8 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
   * Check policy...
   */
 
-  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con,
+                                 job->username)) != HTTP_OK)
   {
     send_http_error(con, status, NULL);
     return;
@@ -6996,15 +7287,16 @@ get_document(cupsd_client_t  *con,      /* I - Client connection */
                                IPP_TAG_INTEGER)) == NULL)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("Missing document-number attribute"));
+                    _("Missing document-number attribute."));
     return;
   }
 
   if ((docnum = attr->values[0].integer) < 1 || docnum > job->num_files ||
       attr->num_values > 1)
   {
-    send_ipp_status(con, IPP_NOT_FOUND, _("Document %d not found in job %d."),
-                    docnum, jobid);
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("Document #%d does not exist in job #%d."), docnum,
+                   jobid);
     return;
   }
 
@@ -7016,7 +7308,8 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
                     "Unable to open document %d in job %d - %s", docnum, jobid,
                    strerror(errno));
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("Unable to open document %d in job %d"), docnum, jobid);
+                    _("Unable to open document #%d in job #%d."), docnum,
+                   jobid);
     return;
   }
 
@@ -7078,7 +7371,7 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -7100,8 +7393,7 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -7119,7 +7411,7 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -7198,7 +7490,7 @@ get_jobs(cupsd_client_t  *con,            /* I - Client connection */
 
   if (strcmp(uri->name, "printer-uri"))
   {
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No printer-uri in request"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No printer-uri in request."));
     return;
   }
 
@@ -7235,7 +7527,7 @@ get_jobs(cupsd_client_t  *con,            /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
   else
@@ -7419,7 +7711,7 @@ get_jobs(cupsd_client_t  *con,            /* I - Client connection */
 
     if (i < job_ids->num_values)
     {
-      send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                       job_ids->values[i].integer);
       return;
     }
@@ -7549,7 +7841,7 @@ get_notifications(cupsd_client_t *con)    /* I - Client connection */
   if (!ids)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("Missing notify-subscription-ids attribute"));
+                    _("Missing notify-subscription-ids attribute."));
     return;
   }
 
@@ -7565,8 +7857,7 @@ get_notifications(cupsd_client_t *con)    /* I - Client connection */
       * Bad subscription ID...
       */
 
-      send_ipp_status(con, IPP_NOT_FOUND,
-                      _("notify-subscription-id %d no good"),
+      send_ipp_status(con, IPP_NOT_FOUND, _("Subscription #%d does not exist."),
                      ids->values[i].integer);
       return;
     }
@@ -8002,7 +8293,7 @@ get_printer_attrs(cupsd_client_t  *con,   /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -8058,7 +8349,7 @@ get_printer_supported(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -8275,8 +8566,8 @@ get_subscription_attrs(
     * Bad subscription ID...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good"), sub_id);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Subscription #%d does not exist."),
+                    sub_id);
     return;
   }
 
@@ -8369,8 +8660,8 @@ get_subscriptions(cupsd_client_t  *con,   /* I - Client connection */
 
     if (!job)
     {
-      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist"),
-                      resource + 6);
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
+                      atoi(resource + 6));
       return;
     }
   }
@@ -8381,7 +8672,7 @@ get_subscriptions(cupsd_client_t  *con,   /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
   else if ((attr = ippFindAttribute(con->request, "notify-job-id",
@@ -8391,7 +8682,7 @@ get_subscriptions(cupsd_client_t  *con,   /* I - Client connection */
 
     if (!job)
     {
-      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"),
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                       attr->values[0].integer);
       return;
     }
@@ -8522,7 +8813,7 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -8545,7 +8836,7 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+                      _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -8563,7 +8854,7 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -8631,7 +8922,7 @@ hold_new_jobs(cupsd_client_t  *con,       /* I - Connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -8652,7 +8943,6 @@ hold_new_jobs(cupsd_client_t  *con,       /* I - Connection */
   printer->holding_new_jobs = 1;
 
   cupsdSetPrinterReasons(printer, "+hold-new-jobs");
-  cupsdAddPrinterHistory(printer);
 
   if (dtype & CUPS_PRINTER_CLASS)
     cupsdLogMessage(CUPSD_LOG_INFO,
@@ -8710,7 +9000,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("job-printer-uri attribute missing"));
+                    _("job-printer-uri attribute missing."));
     return;
   }
 
@@ -8721,7 +9011,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -8754,7 +9044,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
+                       _("The printer or class does not exist."));
        return;
       }
 
@@ -8773,7 +9063,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("Job #%d does not exist"), attr->values[0].integer);
+                       _("Job #%d does not exist."), attr->values[0].integer);
        return;
       }
       else
@@ -8799,8 +9089,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -8817,8 +9106,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
       * Nope - return a "not found" error...
       */
 
-      send_ipp_status(con, IPP_NOT_FOUND,
-                      _("Job #%d does not exist"), jobid);
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
       return;
     }
     else
@@ -8860,7 +9148,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("Job #%d is finished and cannot be altered"),
+                      _("Job #%d is finished and cannot be altered."),
                      job->id);
       return;
     }
@@ -9045,7 +9333,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
       )
     {
       send_ipp_status(con, IPP_ATTRIBUTES,
-                      _("Unsupported compression \"%s\""),
+                      _("Unsupported compression \"%s\"."),
                      attr->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
                   "compression", NULL, attr->values[0].string.text);
@@ -9064,7 +9352,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
 
   if (!con->filename)
   {
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No file in print request."));
     return;
   }
 
@@ -9079,7 +9367,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -9098,7 +9386,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
                type) != 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad document-format \"%s\""),
+                      _("Bad document-format \"%s\"."),
                      format->values[0].string.text);
       return;
     }
@@ -9114,7 +9402,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
     if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad document-format \"%s\""),
+                      _("Bad document-format \"%s\"."),
                      default_format);
       return;
     }
@@ -9179,7 +9467,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
   else if (!filetype)
   {
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported document-format \"%s\""),
+                    _("Unsupported document-format \"%s\"."),
                    format ? format->values[0].string.text :
                             "application/octet-stream");
     cupsdLogMessage(CUPSD_LOG_INFO,
@@ -9472,7 +9760,7 @@ reject_jobs(cupsd_client_t  *con, /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -9499,8 +9787,6 @@ reject_jobs(cupsd_client_t  *con, /* I - Client connection */
     strlcpy(printer->state_message, attr->values[0].string.text,
             sizeof(printer->state_message));
 
-  cupsdAddPrinterHistory(printer);
-
   cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
                 "No longer accepting jobs.");
 
@@ -9555,7 +9841,7 @@ release_held_new_jobs(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -9576,7 +9862,6 @@ release_held_new_jobs(
   printer->holding_new_jobs = 0;
 
   cupsdSetPrinterReasons(printer, "-hold-new-jobs");
-  cupsdAddPrinterHistory(printer);
 
   if (dtype & CUPS_PRINTER_CLASS)
     cupsdLogMessage(CUPSD_LOG_INFO,
@@ -9630,7 +9915,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -9652,8 +9937,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -9671,7 +9955,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -9685,7 +9969,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
     * Nope - return a "not possible" error...
     */
 
-    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not held"), jobid);
+    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not held."), jobid);
     return;
   }
 
@@ -9764,8 +10048,8 @@ renew_subscription(
     * Bad subscription ID...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good"), sub_id);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Subscription #%d does not exist."),
+                    sub_id);
     return;
   }
 
@@ -9776,7 +10060,7 @@ renew_subscription(
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job subscriptions cannot be renewed"));
+                    _("Job subscriptions cannot be renewed."));
     return;
   }
 
@@ -9856,7 +10140,7 @@ restart_job(cupsd_client_t  *con,        /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -9878,8 +10162,7 @@ restart_job(cupsd_client_t  *con,        /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -9897,7 +10180,7 @@ restart_job(cupsd_client_t  *con,        /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -9911,7 +10194,7 @@ restart_job(cupsd_client_t  *con,        /* I - Client connection */
     * Nope - return a "not possible" error...
     */
 
-    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not complete"),
+    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not complete."),
                     jobid);
     return;
   }
@@ -9929,7 +10212,7 @@ restart_job(cupsd_client_t  *con,        /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d cannot be restarted - no files"), jobid);
+                    _("Job #%d cannot be restarted - no files."), jobid);
     return;
   }
 
@@ -10211,7 +10494,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -10233,8 +10516,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -10252,7 +10534,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -10285,7 +10567,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
 #endif /* HAVE_LIBZ */
       )
     {
-      send_ipp_status(con, IPP_ATTRIBUTES, _("Unsupported compression \"%s\""),
+      send_ipp_status(con, IPP_ATTRIBUTES, _("Unsupported compression \"%s\"."),
                      attr->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
                   "compression", NULL, attr->values[0].string.text);
@@ -10315,7 +10597,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
         attr->values[0].boolean)
       goto last_document;
 
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No file in print request."));
     return;
   }
 
@@ -10333,7 +10615,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
     if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
                super, type) != 2)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."),
                      format->values[0].string.text);
       return;
     }
@@ -10349,8 +10631,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
     if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Could not scan type \"%s\""),
-                     default_format);
+                      _("Bad document-format-default \"%s\"."), default_format);
       return;
     }
   }
@@ -10383,8 +10664,9 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
     if (!filetype)
       filetype = mimeType(MimeDatabase, super, type);
 
-    cupsdLogJob(job, CUPSD_LOG_DEBUG, "Request file type is %s/%s.",
-               filetype->super, filetype->type);
+    if (filetype)
+      cupsdLogJob(job, CUPSD_LOG_DEBUG, "Request file type is %s/%s.",
+                 filetype->super, filetype->type);
   }
   else
     filetype = mimeType(MimeDatabase, super, type);
@@ -10413,7 +10695,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
   else if (!filetype)
   {
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported format \'%s/%s\'"), super, type);
+                    _("Unsupported document-format \"%s/%s\"."), super, type);
     cupsdLogMessage(CUPSD_LOG_INFO,
                     "Hint: Do you have the raw file printing rules enabled?");
 
@@ -10430,7 +10712,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
              filetype->type);
 
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported format \'%s\'"), mimetype);
+                    _("Unsupported document-format \"%s\"."), mimetype);
 
     ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
                  "document-format", NULL, mimetype);
@@ -10709,7 +10991,7 @@ set_default(cupsd_client_t  *con,       /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -10800,7 +11082,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -10822,8 +11104,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -10841,7 +11122,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -10856,7 +11137,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d is finished and cannot be altered"), jobid);
+                    _("Job #%d is finished and cannot be altered."), jobid);
     return;
   }
 
@@ -10931,7 +11212,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
 
       if (attr->value_tag != IPP_TAG_INTEGER)
       {
-       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value"));
+       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value."));
 
        if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
           attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
@@ -10961,7 +11242,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
 
       if (attr->value_tag != IPP_TAG_ENUM)
       {
-       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value"));
+       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value."));
 
        if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
           attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
@@ -11165,7 +11446,7 @@ set_printer_attrs(cupsd_client_t  *con, /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -11495,7 +11776,7 @@ start_printer(cupsd_client_t  *con,     /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -11577,7 +11858,7 @@ stop_printer(cupsd_client_t  *con,      /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -11821,7 +12102,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
       )
     {
       send_ipp_status(con, IPP_ATTRIBUTES,
-                      _("Unsupported compression \"%s\""),
+                      _("Unsupported compression \"%s\"."),
                      attr->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
                   "compression", NULL, attr->values[0].string.text);
@@ -11839,7 +12120,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
     if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
                super, type) != 2)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."),
                      format->values[0].string.text);
       return;
     }
@@ -11850,7 +12131,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
       cupsdLogMessage(CUPSD_LOG_INFO,
                       "Hint: Do you have the raw file printing rules enabled?");
       send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                      _("Unsupported document-format \"%s\""),
+                      _("Unsupported document-format \"%s\"."),
                      format->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
                    "document-format", NULL, format->values[0].string.text);
@@ -11869,7 +12150,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }