Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IPP Everywhere PPD generator #4258

Closed
michaelrsweet opened this issue Jan 10, 2013 · 7 comments
Closed

Add IPP Everywhere PPD generator #4258

michaelrsweet opened this issue Jan 10, 2013 · 7 comments
Labels
enhancement New feature or request
Milestone

Comments

@michaelrsweet
Copy link
Collaborator

Version: 2.1-feature
CUPS.org User: mike

To fully support IPP Everywhere printers today, we need a PPD generator that will drive a traditional CUPS print queue. The PPD generator should query the IPP Everywhere printer, creating the necessary PPD options and values needed to support native PWG Raster, JPEG, and PDF printing.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Note that this bug may end up closed depending on when we actually implement IPP Everywhere printing support since PPDs are a legacy implementation detail of the CUPS printing infrastructure - if we end up with a native set of IPP Everywhere-based filters then this PPD generator will be unnecessary...

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: till.kamppeter

The filter set for PPD-less printing on IPP Everywhere printers (PWG Raster, PDF, PostScript) is already in place in cups-filters 1.0.43 and cups-browsed is already capable of auto-creating appropriate queues. A client (print dialog) can ask the printer for available options and capabilities now and send PDF jobs with appropriate IPP attributes to these queues.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

First part of the equation: a private API for generating a PPD from the response of a Get-Printer-Attributes request.

Next up will be lpadmin and web interface support.

@michaelrsweet
Copy link
Collaborator Author

CUPS.org User: mike

Fixed in Subversion repository.

Second part.

@michaelrsweet
Copy link
Collaborator Author

"str4258p1.patch":

Index: cups/ppd-cache.c

--- cups/ppd-cache.c (revision 12508)
+++ cups/ppd-cache.c (working copy)
@@ -37,6 +37,7 @@
_pwg_finishings_t *b);
static void pwg_free_finishings(_pwg_finishings_t *f);
static void pwg_ppdize_name(const char *ipp, char *name, size_t namesize);
+static void pwg_ppdize_resolution(ipp_attribute_t *attr, int element, int *xres, int *yres, char *name, size_t namesize);
static void pwg_unppdize_name(const char *ppd, char *name, size_t namesize,
const char *dashchars);

@@ -2782,6 +2783,479 @@

/*

  • * '_ppdCreateFromIPP()' - Create a PPD file describing the capabilities
  • * of an IPP printer.
  • /
    +
    +char * /
    O - PPD filename or NULL on error _/
    +ppdCreateFromIPP(char *buffer, / I - Filename buffer */
  •              size_t bufsize,  /\* I - Size of filename buffer */
    
  •     ipp_t  _response) /_ I - Get-Printer-Attributes response */
    
    +{
  • cups_file_t fp; / PPD file */
  • ipp_attribute_t attr, / xxx-supported */
  •       _defattr,   /_ xxx-default */
    
  •       _x_dim, *y_dim; /_ Media dimensions */
    
  • ipp_t media_size; / Media size collection */
  • char make[256], /* Make and model */
  •       _model,     /_ Model name */
    
  •       ppdname[PPD_MAX_NAME];
    
  •                   /\* PPD keyword */
    
  • int i, j, /* Looping vars */
  •       count,      /\* Number of values */
    
  •       bottom,     /\* Largest bottom margin */
    
  •       left,       /\* Largest left margin */
    
  •       right,      /\* Largest right margin */
    
  •       top;        /\* Largest top margin */
    
  • pwg_media_t pwg; / PWG media size */
  • int xres, yres; /* Resolution values */
  • /*
  • * Range check input...
  • */
  • if (!buffer || bufsize < 1 || !response)
  • return (NULL);
  • /*
  • * Open a temporary file for the PPD...
  • */
  • if ((fp = cupsTempFile2(buffer, (int)bufsize)) == NULL)
  • return (NULL);
  • /*
  • * Standard stuff for PPD file...
  • */
  • cupsFilePuts(fp, "*PPD-Adobe: "4.3"\n");
  • cupsFilePuts(fp, "*FormatVersion: "4.3"\n");
  • cupsFilePrintf(fp, "*FileVersion: "%d.%d"\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
  • cupsFilePuts(fp, "*LanguageVersion: English\n");
  • cupsFilePuts(fp, "*LanguageEncoding: ISOLatin1\n");
  • cupsFilePuts(fp, "*PSVersion: "(3010.000) 0"\n");
  • cupsFilePuts(fp, "*LanguageLevel: "3"\n");
  • cupsFilePuts(fp, "*FileSystem: False\n");
  • cupsFilePuts(fp, "*PCFileName: "ippeve.ppd"\n");
  • if ((attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL)
  • strlcpy(make, ippGetString(attr, 0, NULL), sizeof(make));
  • else
  • strlcpy(make, "Unknown Printer", sizeof(make));
  • if (!_cups_strncasecmp(make, "Hewlett Packard ", 16) ||
  •  !_cups_strncasecmp(make, "Hewlett-Packard ", 16))
    
  • {
  • model = make + 16;
  • strlcpy(make, "HP", sizeof(make));
  • }
  • else if ((model = strchr(make, ' ')) != NULL)
  • *model++ = '\0';
  • else
  • model = make;
  • cupsFilePrintf(fp, "*Manufacturer: "%s"\n", make);
  • cupsFilePrintf(fp, "*ModelName: "%s"\n", model);
  • cupsFilePrintf(fp, "*Product: "(%s)"\n", model);
  • cupsFilePrintf(fp, "*NickName: "%s"\n", model);
  • cupsFilePrintf(fp, "*ShortNickName: "%s"\n", model);
  • cupsFilePrintf(fp, "*cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
  • cupsFilePuts(fp, "*cupsSNMPSupplies: False\n");
  • cupsFilePuts(fp, "*cupsLanguages: "en"\n");
  • /*
  • * Filters...
  • */
  • if ((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL)
  • {
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  const char *format = ippGetString(attr, i, NULL);
    
  •               /\* PDL */
    
  •  if (!_cups_strcasecmp(format, "application/pdf"))
    
  •    cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n");
    
  •  else if (_cups_strcasecmp(format, "application/octet-stream"))
    
  •    cupsFilePrintf(fp, "*cupsFilter2: \"%s %s 10 -\"\n", format, format);
    
  • }
  • }
  • /*
  • * PageSize/PageRegion/ImageableArea/PaperDimension
  • */
  • if ((attr = ippFindAttribute(response, "media-bottom-margin-supported", IPP_TAG_INTEGER)) != NULL)
  • {
  • for (i = 1, bottom = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
  •  if (ippGetInteger(attr, i) > bottom)
    
  •    bottom = ippGetInteger(attr, i);
    
  • }
  • else
  • bottom = 1270;
  • if ((attr = ippFindAttribute(response, "media-left-margin-supported", IPP_TAG_INTEGER)) != NULL)
  • {
  • for (i = 1, left = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
  •  if (ippGetInteger(attr, i) > left)
    
  •    left = ippGetInteger(attr, i);
    
  • }
  • else
  • left = 635;
  • if ((attr = ippFindAttribute(response, "media-right-margin-supported", IPP_TAG_INTEGER)) != NULL)
  • {
  • for (i = 1, right = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
  •  if (ippGetInteger(attr, i) > right)
    
  •    right = ippGetInteger(attr, i);
    
  • }
  • else
  • right = 635;
  • if ((attr = ippFindAttribute(response, "media-top-margin-supported", IPP_TAG_INTEGER)) != NULL)
  • {
  • for (i = 1, top = ippGetInteger(attr, 0), count = ippGetCount(attr); i < count; i ++)
  •  if (ippGetInteger(attr, i) > top)
    
  •    top = ippGetInteger(attr, i);
    
  • }
  • else
  • top = 1270;
  • if ((defattr = ippFindAttribute(response, "media-col-default", IPP_TAG_BEGIN_COLLECTION)) != NULL)
  • {
  • if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-size", IPP_TAG_BEGIN_COLLECTION)) != NULL)
  • {
  •  media_size = ippGetCollection(attr, 0);
    
  •  x_dim      = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
    
  •  y_dim      = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
    
  •  if (x_dim && y_dim)
    
  •  {
    
  •    pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
    
  • strlcpy(ppdname, pwg->ppd, sizeof(ppdname));
  •  }
    
  •  else
    
  • strlcpy(ppdname, "Unknown", sizeof(ppdname));
  • }
  • else
  •  strlcpy(ppdname, "Unknown", sizeof(ppdname));
    
  • }
  • if ((attr = ippFindAttribute(response, "media-size-supported", IPP_TAG_BEGIN_COLLECTION)) != NULL)
  • {
  • cupsFilePrintf(fp, "*OpenUI *PageSize: PickOne\n"
  •          "*OrderDependency: 10 AnySetup *PageSize\n"
    
  •                   "*DefaultPageSize: %s\n", ppdname);
    
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  media_size = ippGetCollection(attr, i);
    
  •  x_dim      = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
    
  •  y_dim      = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
    
  •  if (x_dim && y_dim)
    
  •  {
    
  •    pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
    
  •    cupsFilePrintf(fp, "*PageSize %s: \"<</PageSize[%.1f %.1f]>>setpagedevice\"\n", pwg->ppd, pwg->width \* 72.0 / 2540.0, pwg->length \* 72.0 / 2540.0);
    
  •  }
    
  • }
  • cupsFilePuts(fp, "*CloseUI: *PageSize\n");
  • cupsFilePrintf(fp, "*OpenUI *PageRegion: PickOne\n"
  •                   "*OrderDependency: 10 AnySetup *PageRegion\n"
    
  •                   "*DefaultPageRegion: %s\n", ppdname);
    
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  media_size = ippGetCollection(attr, i);
    
  •  x_dim      = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
    
  •  y_dim      = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
    
  •  if (x_dim && y_dim)
    
  •  {
    
  •    pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
    
  •    cupsFilePrintf(fp, "*PageRegion %s: \"<</PageSize[%.1f %.1f]>>setpagedevice\"\n", pwg->ppd, pwg->width \* 72.0 / 2540.0, pwg->length \* 72.0 / 2540.0);
    
  •  }
    
  • }
  • cupsFilePuts(fp, "*CloseUI: *PageRegion\n");
  • cupsFilePrintf(fp, "*DefaultImageableArea: %s\n"
  •          "*DefaultPaperDimension: %s\n", ppdname, ppdname);
    
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  media_size = ippGetCollection(attr, i);
    
  •  x_dim      = ippFindAttribute(media_size, "x-dimension", IPP_TAG_INTEGER);
    
  •  y_dim      = ippFindAttribute(media_size, "y-dimension", IPP_TAG_INTEGER);
    
  •  if (x_dim && y_dim)
    
  •  {
    
  •    pwg = pwgMediaForSize(ippGetInteger(x_dim, 0), ippGetInteger(y_dim, 0));
    
  •    cupsFilePrintf(fp, "*ImageableArea %s: \"%.1f %.1f %.1f %.1f\"\n", pwg->ppd, left \* 72.0 / 2540.0, bottom \* 72.0 / 2540.0, (pwg->width - right) \* 72.0 / 2540.0, (pwg->length - top) \* 72.0 / 2540.0);
    
  •    cupsFilePrintf(fp, "*PaperDimension %s: \"%.1f %.1f\"\n", pwg->ppd, pwg->width \* 72.0 / 2540.0, pwg->length \* 72.0 / 2540.0);
    
  •  }
    
  • }
  • }
  • /*
  • * InputSlot...
  • */
  • if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-source", IPP_TAG_KEYWORD)) != NULL)
  • pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
  • else
  • strlcpy(ppdname, "Unknown", sizeof(ppdname));
  • if ((attr = ippFindAttribute(response, "media-source-supported", IPP_TAG_KEYWORD)) != NULL && (count = ippGetCount(attr)) > 1)
  • {
  • static const char * const sources[][2] =
  • {
  •  { "Auto", "Automatic" },
    
  •  { "Main", "Main" },
    
  •  { "Alternate", "Alternate" },
    
  •  { "LargeCapacity", "Large Capacity" },
    
  •  { "Manual", "Manual" },
    
  •  { "Envelope", "Envelope" },
    
  •  { "Disc", "Disc" },
    
  •  { "Photo", "Photo" },
    
  •  { "Hagaki", "Hagaki" },
    
  •  { "MainRoll", "Main Roll" },
    
  •  { "AlternateRoll", "Alternate Roll" },
    
  •  { "Top", "Top" },
    
  •  { "Middle", "Middle" },
    
  •  { "Bottom", "Bottom" },
    
  •  { "Side", "Side" },
    
  •  { "Left", "Left" },
    
  •  { "Right", "Right" },
    
  •  { "Center", "Center" },
    
  •  { "Rear", "Rear" },
    
  •  { "ByPassTray", "Multipurpose" },
    
  •  { "Tray1", "Tray 1" },
    
  •  { "Tray2", "Tray 2" },
    
  •  { "Tray3", "Tray 3" },
    
  •  { "Tray4", "Tray 4" },
    
  •  { "Tray5", "Tray 5" },
    
  •  { "Tray6", "Tray 6" },
    
  •  { "Tray7", "Tray 7" },
    
  •  { "Tray8", "Tray 8" },
    
  •  { "Tray9", "Tray 9" },
    
  •  { "Tray10", "Tray 10" },
    
  •  { "Tray11", "Tray 11" },
    
  •  { "Tray12", "Tray 12" },
    
  •  { "Tray13", "Tray 13" },
    
  •  { "Tray14", "Tray 14" },
    
  •  { "Tray15", "Tray 15" },
    
  •  { "Tray16", "Tray 16" },
    
  •  { "Tray17", "Tray 17" },
    
  •  { "Tray18", "Tray 18" },
    
  •  { "Tray19", "Tray 19" },
    
  •  { "Tray20", "Tray 20" },
    
  •  { "Roll1", "Roll 1" },
    
  •  { "Roll2", "Roll 2" },
    
  •  { "Roll3", "Roll 3" },
    
  •  { "Roll4", "Roll 4" },
    
  •  { "Roll5", "Roll 5" },
    
  •  { "Roll6", "Roll 6" },
    
  •  { "Roll7", "Roll 7" },
    
  •  { "Roll8", "Roll 8" },
    
  •  { "Roll9", "Roll 9" },
    
  •  { "Roll10", "Roll 10" }
    
  • };
  • cupsFilePrintf(fp, "*OpenUI *InputSlot: PickOne\n"
  •                   "*OrderDependency: 10 AnySetup *InputSlot\n"
    
  •                   "*DefaultInputSlot: %s\n", ppdname);
    
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  pwg_ppdize_name(ippGetString(attr, i, NULL), ppdname, sizeof(ppdname));
    
  •  for (j = 0; j < (int)(sizeof(sources) / sizeof(sources[0])); j ++)
    
  •    if (!strcmp(sources[j][0], ppdname))
    
  • {
  • cupsFilePrintf(fp, "*InputSlot %s/%s: \"<</MediaPosition %d>>setpagedevice\"\n", ppdname, sources[j][1], j);
    
  • break;
    
  • }
  • }
  • cupsFilePuts(fp, "*CloseUI: *InputSlot\n");
  • }
  • /*
  • * MediaType...
  • */
  • if ((attr = ippFindAttribute(ippGetCollection(defattr, 0), "media-type", IPP_TAG_KEYWORD)) != NULL)
  • pwg_ppdize_name(ippGetString(attr, 0, NULL), ppdname, sizeof(ppdname));
  • else
  • strlcpy(ppdname, "Unknown", sizeof(ppdname));
  • if ((attr = ippFindAttribute(response, "media-type-supported", IPP_TAG_KEYWORD)) != NULL && (count = ippGetCount(attr)) > 1)
  • {
  • static const char * const types[][2] =
  • { /* Media type strings (far from complete) */
  •  { "Auto", "Automatic" },
    
  •  { "Cardstock", "Cardstock" },
    
  •  { "Disc", "CD/DVD/Bluray" },
    
  •  { "Envelope", "Envelope" },
    
  •  { "Labels", "Label" },
    
  •  { "Other", "Other" },
    
  •  { "Photographic", "Photo" },
    
  •  { "PhotographicGlossy", "Glossy Photo" },
    
  •  { "PhotographicHighGloss", "High-Gloss Photo" },
    
  •  { "PhotographicMatte", "Matte Photo" },
    
  •  { "PhotographicSatin", "Satin Photo" },
    
  •  { "PhotographicSemiGloss", "Semi-Gloss Photo" },
    
  •  { "Stationery", "Plain Paper" },
    
  •  { "StationeryLetterhead", "Letterhead" },
    
  •  { "Transparency", "Transparency" }
    
  • };
  • cupsFilePrintf(fp, "*OpenUI *MediaType: PickOne\n"
  •                   "*OrderDependency: 10 AnySetup *MediaType\n"
    
  •                   "*DefaultMediaType: %s\n", ppdname);
    
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  pwg_ppdize_name(ippGetString(attr, i, NULL), ppdname, sizeof(ppdname));
    
  •  for (j = 0; j < (int)(sizeof(types) / sizeof(types[0])); j ++)
    
  •    if (!strcmp(types[j][0], ppdname))
    
  • {
  • cupsFilePrintf(fp, "*MediaType %s/%s: \"<</MediaType(%s)>>setpagedevice\"\n", ppdname, types[j][1], ppdname);
    
  • break;
    
  • }
  •  if (j >= (int)(sizeof(types) / sizeof(types[0])))
    
  • cupsFilePrintf(fp, "*MediaType %s: "<</MediaType(%s)>>setpagedevice"\n", ppdname, ppdname);
  • }
  • cupsFilePuts(fp, "*CloseUI: *MediaType\n");
  • }
  • /*
  • * ColorModel...
  • */
  • if ((attr = ippFindAttribute(response, "pwg-raster-document-type-supported", IPP_TAG_KEYWORD)) == NULL)
  • attr = ippFindAttribute(response, "print-color-mode-supported", IPP_TAG_KEYWORD);
  • if (attr)
  • {
  • const char default_color = NULL; / Default */
  • cupsFilePuts(fp, "*OpenUI *ColorModel/Color Mode: PickOne\n"
  •        "*OrderDependency: 10 AnySetup *ColorModel\n");
    
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  const char *keyword = ippGetString(attr, i, NULL);
    
  •               /\* Keyword for color/bit depth */
    
  •  if (!strcmp(keyword, "black_1"))
    
  •  {
    
  •    cupsFilePuts(fp, "*ColorModel FastGray/Fast Grayscale: \"<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n");
    
  •    if (!default_color)
    
  • default_color = "FastGray";
    
  •  }
    
  •  else if (!strcmp(keyword, "sgray_8") || !strcmp(keyword, "monochrome") || !strcmp(keyword, "process-monochrome"))
    
  •  {
    
  •    cupsFilePuts(fp, "*ColorModel Gray/Grayscale: \"<</cupsColorSpace 18/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n");
    
  •    if (!default_color || !strcmp(default_color, "FastGray"))
    
  • default_color = "Gray";
    
  •  }
    
  •  else if (!strcmp(keyword, "srgb_8") || !strcmp(keyword, "color"))
    
  •  {
    
  •    cupsFilePuts(fp, "*ColorModel RGB/Color: \"<</cupsColorSpace 19/cupsBitsPerColor 8/cupsColorOrder 0/cupsCompression 0>>setpagedevice\"\n");
    
  • default_color = "RGB";
  •  }
    
  • }
  • if (default_color)
  •  cupsFilePrintf(fp, "*DefaultColorModel: %s\n", default_color);
    
  • cupsFilePuts(fp, "*CloseUI: *ColorModel\n");
  • }
  • /*
  • * Duplex...
  • */
  • if ((attr = ippFindAttribute(response, "sides-supported", IPP_TAG_KEYWORD)) != NULL && ippContainsString(attr, "two-sided-long-edge"))
  • {
  • cupsFilePuts(fp, "*OpenUI *Duplex/2-Sided Printing: PickOne\n"
  •                 "*OrderDependency: 10 AnySetup *Duplex\n"
    
  •                 "*DefaultDuplex: None\n"
    
  •                 "*Duplex None/Off (1-Sided): \"<</Duplex false>>setpagedevice\"\n"
    
  •                 "*Duplex DuplexNoTumble/Long-Edge (Portrait): \"<</Duplex true/Tumble false>>setpagedevice\"\n"
    
  •                 "*Duplex DuplexTumble/Short-Edge (Landscape): \"<</Duplex true/Tumble true>>setpagedevice\"\n"
    
  •                 "*CloseUI: *Duplex\n");
    
  • if ((attr = ippFindAttribute(response, "pwg-raster-document-sheet-back", IPP_TAG_KEYWORD)) != NULL)
  • {
  •  const char *keyword = ippGetString(attr, 0, NULL);
    
  •               /\* Keyword value */
    
  •  if (!strcmp(keyword, "flipped"))
    
  •    cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
    
  •  else if (!strcmp(keyword, "manual-tumble"))
    
  •    cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
    
  •  else if (!strcmp(keyword, "normal"))
    
  •    cupsFilePuts(fp, "*cupsBackSide: Normal\n");
    
  •  else
    
  •    cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
    
  • }
  • }
  • /*
  • * cupsPrintQuality and DefaultResolution...
  • */
  • if ((attr = ippFindAttribute(response, "pwg-raster-document-resolution-supported", IPP_TAG_RESOLUTION)) != NULL)
  • {
  • count = ippGetCount(attr);
  • pwg_ppdize_resolution(attr, count / 2, &xres, &yres, ppdname, sizeof(ppdname));
  • cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
  • cupsFilePuts(fp, "*OpenUI *cupsPrintQuality/Print Quality: PickOne\n"
  •                 "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
    
  •                 "*DefaultcupsPrintQuality: Normal\n");
    
  • if (count > 2)
  • {
  •  pwg_ppdize_resolution(attr, 0, &xres, &yres, NULL, 0);
    
  •  cupsFilePrintf(fp, "*cupsPrintQuality Draft: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
    
  • }
  • pwg_ppdize_resolution(attr, count / 2, &xres, &yres, NULL, 0);
  • cupsFilePrintf(fp, "*cupsPrintQuality Normal: "<</HWResolution[%d %d]>>setpagedevice"\n", xres, yres);
  • if (count > 1)
  • {
  •  pwg_ppdize_resolution(attr, count - 1, &xres, &yres, NULL, 0);
    
  •  cupsFilePrintf(fp, "*cupsPrintQuality High: \"<</HWResolution[%d %d]>>setpagedevice\"\n", xres, yres);
    
  • }
  • cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
  • }
  • else if ((attr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL)
  • {
  • pwg_ppdize_resolution(attr, 0, &xres, &yres, ppdname, sizeof(ppdname));
  • cupsFilePrintf(fp, "*DefaultResolution: %s\n", ppdname);
  • }
  • else
  • cupsFilePuts(fp, "*DefaultResolution: 300dpi\n");
  • /*
  • * Close up and return...
  • */
  • cupsFileClose(fp);
  • return (buffer);
    +}

+/*

  • '_pwgInputSlotForSource()' - Get the InputSlot name for the given PWG
  •                          media-source.
    
    */
    @@ -2992,7 +3466,42 @@
    }

/*

  • * 'pwg_ppdize_resolution()' - Convert PWG resolution values to PPD values.
  • */
    +
    +static void
    +pwg_ppdize_resolution(
  • ipp_attribute_t attr, / I - Attribute to convert */
  • int element, /* I - Element to convert */
  • int xres, / O - X resolution in DPI */
  • int yres, / O - Y resolution in DPI */
  • char name, / I - Name buffer */
  • size_t namesize) /* I - Size of name buffer */
    +{
  • ipp_res_t units; /* Units for resolution */
  • *xres = ippGetResolution(attr, element, yres, &units);
  • if (units == IPP_RES_PER_CM)
  • {
  • _xres = (int)(_xres * 2.54);
  • _yres = (int)(_yres * 2.54);
  • }
  • if (name && namesize > 4)
  • {
  • if (*xres == *yres)
  •  snprintf(name, namesize, "%ddpi", *xres);
    
  • else
  •  snprintf(name, namesize, "%dx%ddpi", *xres, *yres);
    
  • }
    +}

+/*

  • 'pwg_unppdize_name()' - Convert a PPD keyword to a lowercase IPP keyword.
    */

Index: cups/ppd-private.h

--- cups/ppd-private.h (revision 12508)
+++ cups/ppd-private.h (working copy)
@@ -188,6 +188,7 @@
const char *media_type);
extern int _ppdCacheWriteFile(_ppd_cache_t *pc,
const char *filename, ipp_t *attrs);
+extern char *_ppdCreateFromIPP(char *buffer, size_t bufsize, ipp_t *response);
extern void _ppdFreeLanguages(cups_array_t *languages);
extern cups_encoding_t _ppdGetEncoding(const char *name);
extern cups_array_t *_ppdGetLanguages(ppd_file_t *ppd);

Index: cups/testppd.c

--- cups/testppd.c (revision 12508)
+++ cups/testppd.c (working copy)
@@ -3,7 +3,7 @@
*

  • PPD test program for CUPS.
    *
    • * Copyright 2007-2014 by Apple Inc.
    • * Copyright 2007-2015 by Apple Inc.
  • Copyright 1997-2006 by Easy Software Products.
    *
  • These coded instructions, statements, and computer programs are the
    @@ -863,6 +863,46 @@
    status ++;
    }
    }
    • else if (!strncmp(argv[1], "ipp:https://", 6) || !strncmp(argv[1], "ipps:https://", 7))
    • {
    • /*
    • * ipp:https://... or ipps:https://...
    • */
    • http_t http; / Connection to printer */
    • ipp_t request, / Get-Printer-Attributes request */
    •   _response;      /_ Get-Printer-Attributes response */
      
    • char scheme[32], /* URI scheme */
    •   userpass[256],      /\* Username:password */
      
    •   host[256],      /\* Hostname */
      
    •   resource[256];      /\* Resource path */
      
    • int port; /* Port number */
    • if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
    • {
    •  printf("Bad URI \"%s\".\n", argv[1]);
      
    •  return (1);
      
    • }
    • http = httpConnect2(host, port, NULL, AF_UNSPEC, !strcmp(scheme, "ipps") ? HTTP_ENCRYPTION_ALWAYS : HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
    • if (!http)
    • {
    •  printf("Unable to connect to \"%s:%d\": %s\n", host, port, cupsLastErrorString());
      
    •  return (1);
      
    • }
    • request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
    • ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, argv[1]);
    • response = cupsDoRequest(http, request, resource);
    • if (_ppdCreateFromIPP(buffer, sizeof(buffer), response))
    •  printf("Created PPD: %s\n", buffer);
      
    • else
    •  puts("Unable to create PPD.");
      
    • ippDelete(response);
    • return (0);
    • }
      else
      {
      const char filename; / PPD filename */

@michaelrsweet
Copy link
Collaborator Author

"str4258p2.patch":

Index: cups/ppd-cache.c

--- cups/ppd-cache.c (revision 12510)
+++ cups/ppd-cache.c (working copy)
@@ -2815,6 +2815,9 @@

  • Range check input...
    */
  • if (buffer)
  • *buffer = '\0';

if (!buffer || bufsize < 1 || !response)
return (NULL);

Index: cups/testppd.c

--- cups/testppd.c (revision 12510)
+++ cups/testppd.c (working copy)
@@ -901,6 +901,7 @@
puts("Unable to create PPD.");

 ippDelete(response);
  • httpClose(http);
    return (0);
    }
    else
    Index: man/lpadmin.man
    ===================================================================
    --- man/lpadmin.man (revision 12508)
    +++ man/lpadmin.man (working copy)
    @@ -3,7 +3,7 @@
    ."
    ." lpadmin man page for CUPS.
    ."
    -." Copyright 2007-2014 by Apple Inc.
    +." Copyright 2007-2015 by Apple Inc.
    ." Copyright 1997-2006 by Easy Software Products.
    ."
    ." These coded instructions, statements, and computer programs are the
    @@ -12,7 +12,7 @@
    ." which should have been included with this file. If this file is
    ." file is missing or damaged, see the license at "http:https://www.cups.org/".
    ."
    -.TH lpadmin 8 "CUPS" "11 June 2014" "Apple Inc."
    +.TH lpadmin 8 "CUPS" "11 February 2015" "Apple Inc."
    .SH NAME
    lpadmin - configure cups printers and classes
    .SH SYNOPSIS
    @@ -91,6 +91,7 @@
    Use the \fI-m\fR option with the
    .BR lpinfo (8)
    command to get a list of supported models.
    +The model "raw" clears any existing interface script or PPD file and the model "everywhere" queries the printer referred to by the specified IPP \fIdevice-uri\fR.
    .TP 5
    \fB-o cupsIPPSupplies=true\fR
    .TP 5
    @@ -199,6 +200,13 @@
    This differs from the System V version which requires the root user to execute this command.
    .SH NOTES
    The CUPS version of \fBlpadmin\fR does not support all of the System V or Solaris printing system configuration options.
    +.SH EXAMPLE
    +Create an IPP Everywhere print queue:
    +.nf
  • lpadmin -p myprinter -E -v ipp:https://myprinter.local/ipp/print -m everywhere

+.fi
.SH SEE ALSO
.BR cupsaccept (8),
.BR cupsenable (8),
@@ -206,7 +214,7 @@
.BR lpoptions (1),
CUPS Online Help (http:https://localhost:631/help)
.SH COPYRIGHT
-Copyright [co] 2007-2014 by Apple Inc.
+Copyright [co] 2007-2015 by Apple Inc.
."
." End of "$Id$".
."
Index: systemv/lpadmin.c

--- systemv/lpadmin.c (revision 12508)
+++ systemv/lpadmin.c (working copy)
@@ -3,7 +3,7 @@
*

  • "lpadmin" command for CUPS.
    *
  • * Copyright 2007-2014 by Apple Inc.
  • * Copyright 2007-2015 by Apple Inc.
    • Copyright 1997-2006 by Easy Software Products.
      *
    • These coded instructions, statements, and computer programs are the
      @@ -17,6 +17,8 @@
    • Include necessary headers...
      */

+#define _CUPS_NO_DEPRECATED
+#define _PPD_DEPRECATED
#include <cups/cups-private.h>

@@ -32,6 +34,7 @@
static int delete_printer_option(http_t http, char *printer,
char *option);
static int enable_printer(http_t *http, char *printer);
+static char *get_printer_ppd(const char *uri, char *buffer, size_t bufsize);
static cups_ptype_t get_printer_type(http_t *http, char *printer, char *uri,
size_t urisize);
static int set_printer_options(http_t *http, char *printer,
@@ -55,7 +58,11 @@
*val; /
Pointer to allow/deny value /
int num_options; /
Number of options /
cups_option_t *options; /
Options */

  • char file; / New PPD file/interface script */

  • char file, / New PPD file/interface script */

  •   evefile[1024] = "";
    
  •           /\* IPP Everywhere PPD */
    
  • const char ppd_name, / ppd-name value */

  •   *device_uri;    /* device-uri value */
    

    _cupsSetLocale(argv);
    @@ -73,8 +80,7 @@
    case 'c' : /* Add printer to class */
    if (!http)
    {

  •          http = httpConnectEncrypt(cupsServer(), ippPort(),
    
  •                               cupsEncryption());
    
  •          http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
    
      if (http == NULL)
      {
    

    @@ -126,8 +132,7 @@
    case 'd' : /* Set as default destination */
    if (!http)
    {

  •          http = httpConnectEncrypt(cupsServer(), ippPort(),
    
  •                               cupsEncryption());
    
  •          http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
    
      if (http == NULL)
      {
    

    @@ -217,10 +222,10 @@
    if (printer == NULL)
    {
    #ifdef HAVE_SSL

  •     cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
    
  •     cupsSetEncryption(HTTP_ENCRYPTION_REQUIRED);
    
      if (http)
    
  •   httpEncryption(http, HTTP_ENCRYPT_REQUIRED);
    
  •   httpEncryption(http, HTTP_ENCRYPTION_REQUIRED);
    

    #else
    _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."),
    argv[0]);
    @@ -230,8 +235,7 @@

    if (!http)
    {
    
  •          http = httpConnectEncrypt(cupsServer(), ippPort(),
    
  •                               cupsEncryption());
    
  •          http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
    
      if (http == NULL)
      {
    

    @@ -316,8 +320,7 @@
    case 'r' : /* Remove printer from class */
    if (!http)
    {

  •          http = httpConnectEncrypt(cupsServer(), ippPort(),
    
  •                               cupsEncryption());
    
  •          http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
    
      if (http == NULL)
      {
    

    @@ -370,8 +373,7 @@
    case 'R' : /* Remove option */
    if (!http)
    {

  •          http = httpConnectEncrypt(cupsServer(), ippPort(),
    
  •                               cupsEncryption());
    
  •          http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
    
      if (http == NULL)
      {
    

    @@ -487,8 +489,7 @@
    case 'x' : /* Delete a printer */
    if (!http)
    {

  •          http = httpConnectEncrypt(cupsServer(), ippPort(),
    
  •                               cupsEncryption());
    
  •          http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
    
      if (http == NULL)
      {
    

    @@ -621,11 +622,19 @@

    • Set options as needed...
      */
  • if ((ppd_name = cupsGetOption("ppd-name", num_options, options)) != NULL && !strcmp(ppd_name, "everywhere") && (device_uri = cupsGetOption("device-uri", num_options, options)) != NULL)

  • {

  • if ((file = get_printer_ppd(device_uri, evefile, sizeof(evefile))) == NULL)

  •  return (1);
    
  • num_options = cupsRemoveOption("ppd-name", num_options, &options);

  • }

if (num_options || file)
{
if (!http)
{

  •  http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
    
  •  http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL);
    

    if (http == NULL)
    {
    @@ -648,6 +657,9 @@
    return (1);
    }

  • if (evefile[0])

  • unlink(evefile);

if (printer == NULL)
{
_cupsLangPuts(stdout,
@@ -692,7 +704,7 @@
printer, pclass));

/*

  • * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
    • Build an IPP_OP_GET_PRINTER_ATTRIBUTES request, which requires the following
    • attributes:
      *
    • attributes-charset
      @@ -701,7 +713,7 @@
    • requesting-user-name
      */
  • request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
  • request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);

httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
"localhost", 0, "/classes/%s", pclass);
@@ -717,7 +729,7 @@
response = cupsDoRequest(http, request, "/");

/*

  • * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following
    • Build a CUPS-Add-Modify-Class request, which requires the following
    • attributes:
      *
    • attributes-charset
      @@ -727,7 +739,7 @@
    • member-uris
      */
  • request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_CLASS);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
@@ -786,7 +798,7 @@
ippDelete(response);

ippDelete(cupsDoRequest(http, request, "/admin/"));

  • if (cupsLastError() > IPP_OK_CONFLICT)
  • if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

@@ -812,7 +824,7 @@
DEBUG_printf(("default_printer(%p, "%s")\n", http, printer));

/*

  • * Build a CUPS_SET_DEFAULT request, which requires the following
    • Build a CUPS-Set-Default request, which requires the following
    • attributes:
      *
    • attributes-charset
      @@ -824,7 +836,7 @@
      httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
      "localhost", 0, "/printers/%s", printer);
  • request = ippNewRequest(CUPS_SET_DEFAULT);
  • request = ippNewRequest(IPP_OP_CUPS_SET_DEFAULT);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
@@ -837,7 +849,7 @@

ippDelete(cupsDoRequest(http, request, "/admin/"));

  • if (cupsLastError() > IPP_OK_CONFLICT)
  • if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

@@ -863,7 +875,7 @@
DEBUG_printf(("delete_printer(%p, "%s")\n", http, printer));

/*

  • * Build a CUPS_DELETE_PRINTER request, which requires the following
    • Build a CUPS-Delete-Printer request, which requires the following
    • attributes:
      *
    • attributes-charset
      @@ -872,7 +884,7 @@
    • requesting-user-name
      */
  • request = ippNewRequest(CUPS_DELETE_PRINTER);
  • request = ippNewRequest(IPP_OP_CUPS_DELETE_PRINTER);

httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
"localhost", 0, "/printers/%s", printer);
@@ -887,7 +899,7 @@

ippDelete(cupsDoRequest(http, request, "/admin/"));

  • if (cupsLastError() > IPP_OK_CONFLICT)
  • if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

@@ -920,7 +932,7 @@
printer, pclass));

/*

  • * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
    • Build an IPP_OP_GET_PRINTER_ATTRIBUTES request, which requires the following
    • attributes:
      *
    • attributes-charset
      @@ -929,7 +941,7 @@
    • requesting-user-name
      */
  • request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
  • request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);

httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
"localhost", 0, "/classes/%s", pclass);
@@ -943,7 +955,7 @@
*/

if ((response = cupsDoRequest(http, request, "/classes/")) == NULL ||

  •  response->request.status.status_code == IPP_NOT_FOUND)
    
  •  response->request.status.status_code == IPP_STATUS_ERROR_NOT_FOUND)
    
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

@@ -983,7 +995,7 @@
if (members->num_values == 1)
{
/*

  • * Build a CUPS_DELETE_CLASS request, which requires the following
    • Build a CUPS-Delete-Class request, which requires the following
    • attributes:
      *
    • attributes-charset
      @@ -992,7 +1004,7 @@
    • requesting-user-name
      */
  • request = ippNewRequest(CUPS_DELETE_CLASS);
  • request = ippNewRequest(IPP_OP_CUPS_DELETE_CLASS);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
@@ -1002,7 +1014,7 @@
else
{
/*

  • * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following
    • Build a IPP_OP_CUPS_ADD_MODIFY_CLASS request, which requires the following
    • attributes:
      *
    • attributes-charset
      @@ -1012,7 +1024,7 @@
    • member-uris
      */
  • request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);
  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_CLASS);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
@@ -1041,7 +1053,7 @@

ippDelete(cupsDoRequest(http, request, "/admin/"));

  • if (cupsLastError() > IPP_OK_CONFLICT)
  • if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

@@ -1066,7 +1078,7 @@

/*

  • * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which

    • Build a IPP_OP_CUPS_ADD_MODIFY_PRINTER or IPP_OP_CUPS_ADD_MODIFY_CLASS request, which
    • requires the following attributes:
      *
    • attributes-charset
      @@ -1077,9 +1089,9 @@
      */

    if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)

  • request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);

  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_CLASS);
    else

  • request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);

  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_PRINTER);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
@@ -1093,7 +1105,7 @@

ippDelete(cupsDoRequest(http, request, "/admin/"));

  • if (cupsLastError() > IPP_OK_CONFLICT)
  • if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

@@ -1119,7 +1131,7 @@
DEBUG_printf(("enable_printer(%p, "%s")\n", http, printer));

/*

  • * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which

    • Build a IPP_OP_CUPS_ADD_MODIFY_PRINTER or IPP_OP_CUPS_ADD_MODIFY_CLASS request, which
    • require the following attributes:
      *
    • attributes-charset
      @@ -1131,16 +1143,16 @@
      */

    if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)

  • request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);

  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_CLASS);
    else

  • request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);

  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_PRINTER);

ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
"printer-uri", NULL, uri);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
"requesting-user-name", NULL, cupsUser());
ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",

  •            IPP_PRINTER_IDLE);
    
  •            IPP_PSTATE_IDLE);
    

    ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);

    /*
    @@ -1149,7 +1161,7 @@

    ippDelete(cupsDoRequest(http, request, "/admin/"));

  • if (cupsLastError() > IPP_OK_CONFLICT)

  • if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

@@ -1161,6 +1173,63 @@

/*

  • * 'get_printer_ppd()' - Get an IPP Everywhere PPD file for the given URI.
  • /
    +
    +static char * /
    O - Filename or NULL /
    +get_printer_ppd(const char *uri, /
    I - Printer URI */
  •            char       _buffer,    /_ I - Filename buffer */
    
  •   size_t     bufsize) /\* I - Size of filename buffer */
    
    +{
  • http_t http; / Connection to printer */
  • ipp_t request, / Get-Printer-Attributes request */
  •   _response;      /_ Get-Printer-Attributes response */
    
  • char scheme[32], /* URI scheme */
  •   userpass[256],      /\* Username:password */
    
  •   host[256],      /\* Hostname */
    
  •   resource[256];      /\* Resource path */
    
  • int port; /* Port number */
  • /*
  • * Connect to the printer...
  • */
  • if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
  • {
  • _cupsLangPrintf(stderr, _("%s: Bad printer URI "%s"."), "lpadmin", uri);
  • return (NULL);
  • }
  • http = httpConnect2(host, port, NULL, AF_UNSPEC, !strcmp(scheme, "ipps") ? HTTP_ENCRYPTION_ALWAYS : HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
  • if (!http)
  • {
  • _cupsLangPrintf(stderr, _("%s: Unable to connect to "%s:%d": %s"), "lpadmin", host, port, cupsLastErrorString());
  • return (NULL);
  • }
  • /*
  • * Send a Get-Printer-Attributes request...
  • */
  • request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
  • ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
  • response = cupsDoRequest(http, request, resource);
  • if (!_ppdCreateFromIPP(buffer, bufsize, response))
  • _cupsLangPrintf(stderr, _("%s: Unable to create PPD file: %s"), "lpadmin", strerror(errno));
  • ippDelete(response);
  • httpClose(http);
  • if (buffer[0])
  • return (buffer);
  • else
  • return (NULL);
    +}

+/*

  • 'get_printer_type()' - Determine the printer type and URI.
    */

@@ -1189,7 +1258,7 @@

httpAssembleURIf(HTTP_URI_CODING_ALL, uri, (int)urisize, "ipp", NULL, "localhost", ippPort(), "/printers/%s", printer);

  • request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
  • request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
    "printer-uri", NULL, uri);
    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
    @@ -1255,8 +1324,8 @@
    options, file));

/*

  • * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which

  • * requires the following attributes:

  • * Build a CUPS-Add-Modify-Printer or CUPS-Add-Modify-Class request,

    • which requires the following attributes:
      *
    • attributes-charset
    • attributes-natural-language
      @@ -1266,19 +1335,24 @@
      */

    if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS)

  • request = ippNewRequest(CUPS_ADD_MODIFY_CLASS);

  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_CLASS);
    else

  • request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER);

  • request = ippNewRequest(IPP_OP_CUPS_ADD_MODIFY_PRINTER);

  • ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,

  •           "printer-uri", NULL, uri);
    
  • ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,

  •           "requesting-user-name", NULL, cupsUser());
    
  • ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);

  • ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser());

/*

  • Add the options...
    */
  • if (file)
  • ppdfile = file;
  • else if (request->request.op.operation_id == IPP_OP_CUPS_ADD_MODIFY_PRINTER)
  • ppdfile = cupsGetPPD(printer);
  • else
  • ppdfile = NULL;

cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION);
cupsEncodeOptions2(request, num_options, options, IPP_TAG_PRINTER);

@@ -1292,14 +1366,7 @@
NULL, "tbcp");
}

  • if (file)
  • ppdfile = file;
  • else if (request->request.op.operation_id == CUPS_ADD_MODIFY_PRINTER)
  • ppdfile = cupsGetPPD(printer);
  • else

- ppdfile = NULL;

  • if (ppdfile != NULL)
  • if (ppdfile)
    {
    /*
  • Set default options in the PPD file...
    @@ -1458,7 +1525,7 @@
    • Check the response...
      */
  • if (cupsLastError() > IPP_OK_CONFLICT)
  • if (cupsLastError() > IPP_STATUS_OK_CONFLICTING)
    {
    _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString());

Index: xcode/CUPS.xcodeproj/project.pbxproj

--- xcode/CUPS.xcodeproj/project.pbxproj (revision 12508)
+++ xcode/CUPS.xcodeproj/project.pbxproj (working copy)
@@ -31,6 +31,7 @@
buildPhases = (
);
dependencies = (

  •           27A034871A8BDC6900650675 /\* PBXTargetDependency _/,
            274EE2821A03EEE0003213D1 /_ PBXTargetDependency _/,
            274EE2841A03EEE0003213D1 /_ PBXTargetDependency _/,
            274FF5E313332D4300317ECB /_ PBXTargetDependency _/,
    
    @@ -246,6 +247,8 @@
    278C58EA136B64B000836530 /_ Kerberos.framework in Frameworks / = {isa = PBXBuildFile; fileRef = 278C58E6136B64B000836530 / Kerberos.framework /; };
    278C58EB136B64B000836530 /
    Security.framework in Frameworks / = {isa = PBXBuildFile; fileRef = 278C58E7136B64B000836530 / Security.framework /; };
    278C58EC136B64B000836530 /
    SystemConfiguration.framework in Frameworks / = {isa = PBXBuildFile; fileRef = 278C58E8136B64B000836530 / SystemConfiguration.framework */; };
  •   27A034821A8BDC3A00650675 /\* lpadmin.c in Sources _/ = {isa = PBXBuildFile; fileRef = 2732E08D137A3F5200FAFEF6 /_ lpadmin.c */; };
    
  •   27A034851A8BDC5C00650675 /\* libcups.dylib in Frameworks _/ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /_ libcups.dylib _/; };
    7200511218F492F200E7B81B /_ CoreFoundation.framework in Frameworks _/ = {isa = PBXBuildFile; fileRef = 278C58E5136B64AF00836530 /_ CoreFoundation.framework _/; };
    720DD6CD1358FD720064AA82 /_ libcups.dylib in Frameworks _/ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /_ libcups.dylib _/; };
    720DD6D31358FDDE0064AA82 /_ snmp.c in Sources _/ = {isa = PBXBuildFile; fileRef = 720DD6D21358FDDE0064AA82 /_ snmp.c */; };
    
    @@ -816,6 +819,20 @@
    remoteGlobalIDString = 274FF6891333B1C400317ECB;
    remoteInfo = libcups_static;
    };
  •   27A034831A8BDC4A00650675 /\* PBXContainerItemProxy */ = {
    
  •       isa = PBXContainerItemProxy;
    
  •       containerPortal = 72BF96371333042100B1EAD7 /\* Project object */;
    
  •       proxyType = 1;
    
  •       remoteGlobalIDString = 72220EAD1333047D00FCA411;
    
  •       remoteInfo = libcups;
    
  •   };
    
  •   27A034861A8BDC6900650675 /\* PBXContainerItemProxy */ = {
    
  •       isa = PBXContainerItemProxy;
    
  •       containerPortal = 72BF96371333042100B1EAD7 /\* Project object */;
    
  •       proxyType = 1;
    
  •       remoteGlobalIDString = 27A0347A1A8BDB1200650675;
    
  •       remoteInfo = lpadmin;
    
  •   };
    720DD6CE1358FD790064AA82 /\* PBXContainerItemProxy _/ = {
        isa = PBXContainerItemProxy;
        containerPortal = 72BF96371333042100B1EAD7 /_ Project object */;
    
    @@ -1179,6 +1196,15 @@
    );
    runOnlyForDeploymentPostprocessing = 1;
    };
  •   27A034791A8BDB1200650675 /\* CopyFiles */ = {
    
  •       isa = PBXCopyFilesBuildPhase;
    
  •       buildActionMask = 2147483647;
    
  •       dstPath = /usr/share/man/man1/;
    
  •       dstSubfolderSpec = 0;
    
  •       files = (
    
  •       );
    
  •       runOnlyForDeploymentPostprocessing = 1;
    
  •   };
    720DD6C01358FD5F0064AA82 /\* CopyFiles _/ = {
        isa = PBXCopyFilesBuildPhase;
        buildActionMask = 2147483647;
    
    @@ -1368,6 +1394,7 @@
    278C58E6136B64B000836530 /_ Kerberos.framework / = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Kerberos.framework; path = /System/Library/Frameworks/Kerberos.framework; sourceTree = ""; };
    278C58E7136B64B000836530 /
    Security.framework / = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = /System/Library/Frameworks/Security.framework; sourceTree = ""; };
    278C58E8136B64B000836530 /
    SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = /System/Library/Frameworks/SystemConfiguration.framework; sourceTree = ""; };
  •   27A0347B1A8BDB1300650675 /\* lpadmin _/ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = lpadmin; sourceTree = BUILT_PRODUCTS_DIR; };
    27D3037D134148CB00F022B1 /_ libcups2.def _/ = {isa = PBXFileReference; lastKnownFileType = text; name = libcups2.def; path = ../cups/libcups2.def; sourceTree = "<group>"; };
    720DD6C21358FD5F0064AA82 /_ snmp _/ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = snmp; sourceTree = BUILT_PRODUCTS_DIR; };
    720DD6D21358FDDE0064AA82 /_ snmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = snmp.c; path = ../backend/snmp.c; sourceTree = "<group>"; };
    
    @@ -1868,6 +1895,14 @@
    );
    runOnlyForDeploymentPostprocessing = 0;
    };
  •   27A034781A8BDB1200650675 /\* Frameworks */ = {
    
  •       isa = PBXFrameworksBuildPhase;
    
  •       buildActionMask = 2147483647;
    
  •       files = (
    
  •           27A034851A8BDC5C00650675 /\* libcups.dylib in Frameworks */,
    
  •       );
    
  •       runOnlyForDeploymentPostprocessing = 0;
    
  •   };
    720DD6BF1358FD5F0064AA82 /\* Frameworks _/ = {
        isa = PBXFrameworksBuildPhase;
        buildActionMask = 2147483647;
    
    @@ -2151,6 +2186,7 @@
    2767FC5019266A0D000F61D3 /_ testdest /,
    274EE26B1A03EDCA003213D1 /
    ippserver copy /,
    274EE27C1A03EDCB003213D1 /
    ippserver copy copy */,
  •           27A0347B1A8BDB1300650675 /\* lpadmin _/,
        );
        name = Products;
        sourceTree = "<group>";
    
    @@ -3027,6 +3063,24 @@
    productReference = 278C58CB136B640300836530 /_ testhttp */;
    productType = "com.apple.product-type.tool";
    };
  •   27A0347A1A8BDB1200650675 /\* lpadmin */ = {
    
  •       isa = PBXNativeTarget;
    
  •       buildConfigurationList = 27A034811A8BDB1300650675 /\* Build configuration list for PBXNativeTarget "lpadmin" */;
    
  •       buildPhases = (
    
  •           27A034771A8BDB1200650675 /\* Sources */,
    
  •           27A034781A8BDB1200650675 /\* Frameworks */,
    
  •           27A034791A8BDB1200650675 /\* CopyFiles */,
    
  •       );
    
  •       buildRules = (
    
  •       );
    
  •       dependencies = (
    
  •           27A034841A8BDC4A00650675 /\* PBXTargetDependency */,
    
  •       );
    
  •       name = lpadmin;
    
  •       productName = lpadmin;
    
  •       productReference = 27A0347B1A8BDB1300650675 /\* lpadmin */;
    
  •       productType = "com.apple.product-type.tool";
    
  •   };
    720DD6C11358FD5F0064AA82 /\* snmp _/ = {
        isa = PBXNativeTarget;
        buildConfigurationList = 720DD6CB1358FD600064AA82 /_ Build configuration list for PBXNativeTarget "snmp" */;
    
    @@ -3289,6 +3343,11 @@
    attributes = {
    LastUpgradeCheck = 0600;
    ORGANIZATIONNAME = "Apple Inc.";
  •           TargetAttributes = {
    
  •               27A0347A1A8BDB1200650675 = {
    
  •                   CreatedOnToolsVersion = 6.1.1;
    
  •               };
    
  •           };
        };
        buildConfigurationList = 72BF963A1333042100B1EAD7 /\* Build configuration list for PBXProject "CUPS" _/;
        compatibilityVersion = "Xcode 3.2";
    
    @@ -3325,6 +3384,7 @@
    274EE26C1A03EDCB003213D1 /_ ippproxy /,
    726AD6F6135E88F0002C930D /
    ippserver /,
    276683EF1337F78E000D33D0 /
    ipptool */,
  •           27A0347A1A8BDB1200650675 /\* lpadmin _/,
            724379171333E532009631B9 /_ lpd _/,
            2766836F1337AC79000D33D0 /_ ppdc _/,
            2766837C1337AC8C000D33D0 /_ ppdhtml */,
    
    @@ -3581,6 +3641,14 @@
    );
    runOnlyForDeploymentPostprocessing = 0;
    };
  •   27A034771A8BDB1200650675 /\* Sources */ = {
    
  •       isa = PBXSourcesBuildPhase;
    
  •       buildActionMask = 2147483647;
    
  •       files = (
    
  •           27A034821A8BDC3A00650675 /\* lpadmin.c in Sources */,
    
  •       );
    
  •       runOnlyForDeploymentPostprocessing = 0;
    
  •   };
    720DD6BE1358FD5F0064AA82 /\* Sources _/ = {
        isa = PBXSourcesBuildPhase;
        buildActionMask = 2147483647;
    
    @@ -4059,6 +4127,16 @@
    target = 274FF6891333B1C400317ECB /_ libcups_static /;
    targetProxy = 278C58D7136B642F00836530 /
    PBXContainerItemProxy */;
    };
  •   27A034841A8BDC4A00650675 /\* PBXTargetDependency */ = {
    
  •       isa = PBXTargetDependency;
    
  •       target = 72220EAD1333047D00FCA411 /\* libcups */;
    
  •       targetProxy = 27A034831A8BDC4A00650675 /\* PBXContainerItemProxy */;
    
  •   };
    
  •   27A034871A8BDC6900650675 /\* PBXTargetDependency */ = {
    
  •       isa = PBXTargetDependency;
    
  •       target = 27A0347A1A8BDB1200650675 /\* lpadmin */;
    
  •       targetProxy = 27A034861A8BDC6900650675 /\* PBXContainerItemProxy */;
    
  •   };
    720DD6CF1358FD790064AA82 /\* PBXTargetDependency _/ = {
        isa = PBXTargetDependency;
        target = 72220EAD1333047D00FCA411 /_ libcups */;
    
    @@ -4571,6 +4649,74 @@
    };
    name = Release;
    };
  •   27A0347F1A8BDB1300650675 /\* Debug */ = {
    
  •       isa = XCBuildConfiguration;
    
  •       buildSettings = {
    
  •           ALWAYS_SEARCH_USER_PATHS = NO;
    
  •           CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
    
  •           CLANG_CXX_LIBRARY = "libc++";
    
  •           CLANG_ENABLE_MODULES = YES;
    
  •           CLANG_ENABLE_OBJC_ARC = YES;
    
  •           CLANG_WARN_BOOL_CONVERSION = YES;
    
  •           CLANG_WARN_CONSTANT_CONVERSION = YES;
    
  •           CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
    
  •           CLANG_WARN_EMPTY_BODY = YES;
    
  •           CLANG_WARN_INT_CONVERSION = YES;
    
  •           CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
    
  •           CLANG_WARN_UNREACHABLE_CODE = YES;
    
  •           CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
    
  •           COPY_PHASE_STRIP = NO;
    
  •           ENABLE_STRICT_OBJC_MSGSEND = YES;
    
  •           GCC_C_LANGUAGE_STANDARD = gnu99;
    
  •           GCC_DYNAMIC_NO_PIC = NO;
    
  •           GCC_OPTIMIZATION_LEVEL = 0;
    
  •           GCC_PREPROCESSOR_DEFINITIONS = (
    
  •               "DEBUG=1",
    
  •               "$(inherited)",
    
  •           );
    
  •           GCC_SYMBOLS_PRIVATE_EXTERN = NO;
    
  •           GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
    
  •           GCC_WARN_UNDECLARED_SELECTOR = YES;
    
  •           GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
    
  •           INSTALL_PATH = /usr/sbin;
    
  •           MACOSX_DEPLOYMENT_TARGET = 10.10;
    
  •           MTL_ENABLE_DEBUG_INFO = YES;
    
  •           PRODUCT_NAME = "$(TARGET_NAME)";
    
  •           SDKROOT = macosx;
    
  •       };
    
  •       name = Debug;
    
  •   };
    
  •   27A034801A8BDB1300650675 /\* Release */ = {
    
  •       isa = XCBuildConfiguration;
    
  •       buildSettings = {
    
  •           ALWAYS_SEARCH_USER_PATHS = NO;
    
  •           CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
    
  •           CLANG_CXX_LIBRARY = "libc++";
    
  •           CLANG_ENABLE_MODULES = YES;
    
  •           CLANG_ENABLE_OBJC_ARC = YES;
    
  •           CLANG_WARN_BOOL_CONVERSION = YES;
    
  •           CLANG_WARN_CONSTANT_CONVERSION = YES;
    
  •           CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
    
  •           CLANG_WARN_EMPTY_BODY = YES;
    
  •           CLANG_WARN_INT_CONVERSION = YES;
    
  •           CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
    
  •           CLANG_WARN_UNREACHABLE_CODE = YES;
    
  •           CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
    
  •           COPY_PHASE_STRIP = YES;
    
  •           ENABLE_NS_ASSERTIONS = NO;
    
  •           ENABLE_STRICT_OBJC_MSGSEND = YES;
    
  •           GCC_C_LANGUAGE_STANDARD = gnu99;
    
  •           GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
    
  •           GCC_WARN_UNDECLARED_SELECTOR = YES;
    
  •           GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
    
  •           INSTALL_PATH = /usr/sbin;
    
  •           MACOSX_DEPLOYMENT_TARGET = 10.10;
    
  •           MTL_ENABLE_DEBUG_INFO = NO;
    
  •           PRODUCT_NAME = "$(TARGET_NAME)";
    
  •           SDKROOT = macosx;
    
  •       };
    
  •       name = Release;
    
  •   };
    720DD6C91358FD5F0064AA82 /\* Debug */ = {
        isa = XCBuildConfiguration;
        buildSettings = {
    
    @@ -5085,6 +5231,14 @@
    defaultConfigurationIsVisible = 0;
    defaultConfigurationName = Release;
    };
  •   27A034811A8BDB1300650675 /\* Build configuration list for PBXNativeTarget "lpadmin" */ = {
    
  •       isa = XCConfigurationList;
    
  •       buildConfigurations = (
    
  •           27A0347F1A8BDB1300650675 /\* Debug */,
    
  •           27A034801A8BDB1300650675 /\* Release */,
    
  •       );
    
  •       defaultConfigurationIsVisible = 0;
    
  •   };
    720DD6CB1358FD600064AA82 /\* Build configuration list for PBXNativeTarget "snmp" */ = {
        isa = XCConfigurationList;
        buildConfigurations = (
    

@michaelrsweet
Copy link
Collaborator Author

"str4258p3.patch":

Index: cgi-bin/admin.c

--- cgi-bin/admin.c (revision 12514)
+++ cgi-bin/admin.c (working copy)
@@ -3,7 +3,7 @@
*

  • Administration CGI for CUPS.
    *

    • * Copyright 2007-2014 by Apple Inc.
    • * Copyright 2007-2015 by Apple Inc.
  • Copyright 1997-2007 by Easy Software Products.
    *

  • These coded instructions, statements, and computer programs are the
    @@ -18,6 +18,8 @@
    */

    #include "cgi-private.h"
    +#include <cups/http-private.h>
    +#include <cups/ppd-private.h>
    #include <cups/adminutil.h>
    #include <cups/ppd.h>
    #include <errno.h>
    @@ -38,12 +40,7 @@

  • Local functions...
    */

-static void choose_device_cb(const char *device_class,

  •                             const char *device_id, const char *device_info,
    
  •                             const char *device_make_and_model,
    
  •                             const char *device_uri,
    
  •                             const char *device_location,
    
  •            const char *title);
    

    +static void choose_device_cb(const char *device_class, const char *device_id, const char *device_info, const char *device_make_and_model, const char *device_uri, const char *device_location, const char *title);
    static void do_add_rss_subscription(http_t *http);
    static void do_am_class(http_t *http, int modify);
    static void do_am_printer(http_t *http, int modify);
    @@ -61,6 +58,7 @@
    static char *get_option_value(ppd_file_t *ppd, const char *name,
    char *buffer, size_t bufsize);
    static double get_points(double number, const char *uval);
    +static char *get_printer_ppd(const char *uri, char *buffer, size_t bufsize);

    /*
    @@ -832,7 +830,8 @@
    const cgi_file_t file; / Uploaded file, if any /
    const char *var; /
    CGI variable /
    char uri[HTTP_MAX_URI], /
    Device or printer URI */

  •   _uriptr;        /_ Pointer into URI */
    
  •   _uriptr,        /_ Pointer into URI */
    
  •   evefile[1024] = ""; /\* IPP Everywhere PPD file _/
    

    int maxrate; /_ Maximum baud rate /
    char baudrate[255]; /
    Baud rate string /
    const char *name, /
    Pointer to class name */
    @@ -1331,7 +1330,9 @@
    if (!file)
    {
    var = cgiGetVariable("PPD_NAME");

  •  if (strcmp(var, "**no_change**"))
    
  •  if (!strcmp(var, "everywhere"))
    
  •    get_printer_ppd(cgiGetVariable("DEVICE_URI"), evefile, sizeof(evefile));
    
  •  else if (strcmp(var, "__no_change__"))
    

    ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
    NULL, var);
    }
    @@ -1384,6 +1385,11 @@

    if (file)
    ippDelete(cupsDoFileRequest(http, request, "/admin/", file->tempfile));

  • else if (evefile[0])

  • {

  •  ippDelete(cupsDoFileRequest(http, request, "/admin/", evefile));
    
  •  unlink(evefile);
    
  • }
    else
    ippDelete(cupsDoRequest(http, request, "/admin/"));

@@ -4198,5 +4204,78 @@

/*

  • * 'get_printer_ppd()' - Get an IPP Everywhere PPD file for the given URI.
  • /
    +
    +static char * /
    O - Filename or NULL /
    +get_printer_ppd(const char *uri, /
    I - Printer URI */
  •            char       _buffer,    /_ I - Filename buffer */
    
  •   size_t     bufsize) /\* I - Size of filename buffer */
    
    +{
  • http_t http; / Connection to printer */
  • ipp_t request, / Get-Printer-Attributes request */
  •   _response;      /_ Get-Printer-Attributes response */
    
  • char resolved[1024], /* Resolved URI */
  •   scheme[32],     /\* URI scheme */
    
  •   userpass[256],      /\* Username:password */
    
  •   host[256],      /\* Hostname */
    
  •   resource[256];      /\* Resource path */
    
  • int port; /* Port number */
  • /*
  • * Connect to the printer...
  • */
  • if (strstr(uri, "._tcp"))
  • {
  • /*
  • * Resolve URI...
  • */
  • if (!_httpResolveURI(uri, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL))
  • {
  •  fprintf(stderr, "ERROR: Unable to resolve \"%s\".\n", uri);
    
  •  return (NULL);
    
  • }
  • uri = resolved;
  • }
  • if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
  • {
  • fprintf(stderr, "ERROR: Bad printer URI "%s".\n", uri);
  • return (NULL);
  • }
  • http = httpConnect2(host, port, NULL, AF_UNSPEC, !strcmp(scheme, "ipps") ? HTTP_ENCRYPTION_ALWAYS : HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
  • if (!http)
  • {
  • fprintf(stderr, "ERROR: Unable to connect to "%s:%d": %s\n", host, port, cupsLastErrorString());
  • return (NULL);
  • }
  • /*
  • * Send a Get-Printer-Attributes request...
  • */
  • request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
  • ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
  • response = cupsDoRequest(http, request, resource);
  • if (!_ppdCreateFromIPP(buffer, bufsize, response))
  • fprintf(stderr, "ERROR: Unable to create PPD file: %s\n", strerror(errno));
  • ippDelete(response);
  • httpClose(http);
  • if (buffer[0])
  • return (buffer);
  • else
  • return (NULL);
    +}

+/*

  • End of "$Id$".
    _/
    Index: cups/ppd-cache.c

    --- cups/ppd-cache.c (revision 12514)
    +++ cups/ppd-cache.c (working copy)
    @@ -2864,6 +2864,11 @@
    cupsFilePrintf(fp, "_NickName: "%s"\n", model);
    cupsFilePrintf(fp, "*ShortNickName: "%s"\n", model);
  • if ((attr = ippFindAttribute(response, "color-supported", IPP_TAG_BOOLEAN)) != NULL && ippGetBoolean(attr, 0))
  • cupsFilePuts(fp, "*ColorDevice: True\n");
  • else
  • cupsFilePuts(fp, "_ColorDevice: False\n");

cupsFilePrintf(fp, "_cupsVersion: %d.%d\n", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR);
cupsFilePuts(fp, "_cupsSNMPSupplies: False\n");
cupsFilePuts(fp, "_cupsLanguages: "en"\n");
@@ -2881,7 +2886,9 @@

 if (!_cups_strcasecmp(format, "application/pdf"))
   cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-pdf application/pdf 10 -\"\n");
  •  else if (_cups_strcasecmp(format, "application/octet-stream"))
    
  •  else if (!_cups_strcasecmp(format, "application/postscript"))
    
  •    cupsFilePuts(fp, "*cupsFilter2: \"application/vnd.cups-postscript application/postscript 10 -\"\n");
    
  •  else if (_cups_strcasecmp(format, "application/octet-stream") && _cups_strcasecmp(format, "application/vnd.hp-pcl") && _cups_strcasecmp(format, "text/plain"))
     cupsFilePrintf(fp, "*cupsFilter2: \"%s %s 10 -\"\n", format, format);
    

    }
    }
    @@ -3153,7 +3160,7 @@
    const char keyword = ippGetString(attr, i, NULL);
    /
    Keyword for color/bit depth */

  •  if (!strcmp(keyword, "black_1"))
    
  •  if (!strcmp(keyword, "black_1") || !strcmp(keyword, "bi-level") || !strcmp(keyword, "process-bi-level"))
    

    {
    cupsFilePuts(fp, "*ColorModel FastGray/Fast Grayscale: "<</cupsColorSpace 3/cupsBitsPerColor 1/cupsColorOrder 0/cupsCompression 0>>setpagedevice"\n");

@@ -3209,6 +3216,35 @@
else
cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
}

  • else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
  • {
  •  for (i = 0, count = ippGetCount(attr); i < count; i ++)
    
  •  {
    
  • const char *dm = ippGetString(attr, i, NULL);
  •                 /\* DM value */
    
  • if (!_cups_strcasecmp(dm, "DM1"))
  • {
  • cupsFilePuts(fp, "*cupsBackSide: Normal\n");
    
  • break;
    
  • }
  • else if (!_cups_strcasecmp(dm, "DM2"))
  • {
  • cupsFilePuts(fp, "*cupsBackSide: Flipped\n");
    
  • break;
    
  • }
  • else if (!_cups_strcasecmp(dm, "DM3"))
  • {
  • cupsFilePuts(fp, "*cupsBackSide: Rotated\n");
    
  • break;
    
  • }
  • else if (!_cups_strcasecmp(dm, "DM4"))
  • {
  • cupsFilePuts(fp, "*cupsBackSide: ManualTumble\n");
    
  • break;
    
  • }
  •  }
    
  • }
    }

/*
@@ -3240,6 +3276,53 @@

cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
}

  • else if ((attr = ippFindAttribute(response, "urf-supported", IPP_TAG_KEYWORD)) != NULL)
  • {
  • int lowdpi = 0, hidpi = 0; /* Lower and higher resolution */
  • for (i = 0, count = ippGetCount(attr); i < count; i ++)
  • {
  •  const char *rs = ippGetString(attr, i, NULL);
    
  •               /\* RS value */
    
  •  if (_cups_strncasecmp(rs, "RS", 2))
    
  •    continue;
    
  •  lowdpi = atoi(rs + 2);
    
  •  if ((rs = strrchr(rs, '-')) != NULL)
    
  •    hidpi = atoi(rs + 1);
    
  •  else
    
  •    hidpi = lowdpi;
    
  •  break;
    
  • }
  • if (lowdpi == 0)
  • {
  • /*
    
  •  \* Invalid "urf-supported" value...
    
  •  */
    
  •  cupsFilePuts(fp, "*DefaultResolution: 300dpi\n");
    
  • }
  • else
  • {
  • /*
    
  •  \* Generate print qualities based on low and high DPIs...
    
  •  */
    
  •  cupsFilePrintf(fp, "*DefaultResolution: %ddpi\n", lowdpi);
    
  •  cupsFilePuts(fp, "*OpenUI *cupsPrintQuality/Print Quality: PickOne\n"
    
  •          "*OrderDependency: 10 AnySetup *cupsPrintQuality\n"
    
  •          "*DefaultcupsPrintQuality: Normal\n");
    
  •  if ((lowdpi & 1) == 0)
    
  • cupsFilePrintf(fp, "*cupsPrintQuality Draft: "<</HWResolution[%d %d]>>setpagedevice"\n", lowdpi, lowdpi / 2);
  •  cupsFilePrintf(fp, "*cupsPrintQuality Normal: \"<</HWResolution[%d %d]>>setpagedevice\"\n", lowdpi, lowdpi);
    
  •  if (hidpi > lowdpi)
    
  • cupsFilePrintf(fp, "*cupsPrintQuality High: "<</HWResolution[%d %d]>>setpagedevice"\n", hidpi, hidpi);
  •  cupsFilePuts(fp, "*CloseUI: *cupsPrintQuality\n");
    
  • }
  • }
    else if ((attr = ippFindAttribute(response, "printer-resolution-default", IPP_TAG_RESOLUTION)) != NULL)
    {
    pwg_ppdize_resolution(attr, 0, &xres, &yres, ppdname, sizeof(ppdname));
    Index: doc/help/man-lpadmin.html
    ===================================================================
    --- doc/help/man-lpadmin.html (revision 12514)
    +++ doc/help/man-lpadmin.html (working copy)
    @@ -79,6 +79,7 @@
    Use the -m option with the
    lpinfo(8)
    command to get a list of supported models.
    +The model "raw" clears any existing interface script or PPD file and the model "everywhere" queries the printer referred to by the specified IPP device-uri.
-o cupsIPPSupplies=true
-o cupsIPPSupplies=false
Specifies whether IPP supply level values should be reported. @@ -161,6 +162,13 @@ This differs from the System V version which requires the root user to execute this command.

Notes

The CUPS version of lpadmin does not support all of the System V or Solaris printing system configuration options. +

Example

+Create an IPP Everywhere print queue: +
  +
-    lpadmin -p myprinter -E -v ipp:https://myprinter.local/ipp/print -m everywhere
  +
  +

See Also

cupsaccept(8),
cupsenable(8),
@@ -168,7 +176,7 @@
lpoptions(1),
CUPS Online Help (http:https://localhost:631/help)

Copyright

-Copyright © 2007-2014 by Apple Inc.
+Copyright © 2007-2015 by Apple Inc.

Index: scheduler/cups-driverd.cxx

--- scheduler/cups-driverd.cxx (revision 12514)
+++ scheduler/cups-driverd.cxx (working copy)
@@ -7,7 +7,7 @@

  • created from driver information files, and dynamically generated PPD files

  • using driver helper programs.
    *

  • * Copyright 2007-2014 by Apple Inc.

    • Copyright 2007-2015 by Apple Inc.
    • Copyright 1997-2007 by Easy Software Products.
      *
    • These coded instructions, statements, and computer programs are the
      @@ -1172,11 +1172,11 @@
      load_drivers(include, exclude);

    /*

  • * Add the raw driver...

    • Add the raw and IPP Everywhere drivers...
      */
  • add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0,

  •      PPD_TYPE_UNKNOWN, "raw");
    
  • add_ppd("", "everywhere", "en", "Generic", "IPP Everywhere", "", "", "", 0, 0, 0, PPD_TYPE_UNKNOWN, "everywhere");

  • add_ppd("", "raw", "en", "Raw", "Raw Queue", "", "", "", 0, 0, 0, PPD_TYPE_UNKNOWN, "raw");

/*

  • Send IPP attributes...
    Index: systemv/lpadmin.c

    --- systemv/lpadmin.c (revision 12514)
    +++ systemv/lpadmin.c (working copy)
    @@ -1184,7 +1184,8 @@
    http_t http; / Connection to printer /
    ipp_t *request, /
    Get-Printer-Attributes request /
    *response; /
    Get-Printer-Attributes response */

  • char scheme[32], /* URI scheme */

  • char resolved[1024], /* Resolved URI */

  •   scheme[32],     /* URI scheme */
    userpass[256],      /* Username:password */
    host[256],      /* Hostname */
    resource[256];      /* Resource path */
    

    @@ -1195,6 +1196,21 @@

    • Connect to the printer...
      */
  • if (strstr(uri, "._tcp"))

  • {

  • /*

  • * Resolve URI...

  • */

  • if (!_httpResolveURI(uri, resolved, sizeof(resolved), _HTTP_RESOLVE_DEFAULT, NULL, NULL))
  • {
  •  _cupsLangPrintf(stderr, _("%s: Unable to resolve \"%s\"."), "lpadmin", uri);
    
  •  return (NULL);
    
  • }
  • uri = resolved;
  • }

if (httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme), userpass, sizeof(userpass), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_STATUS_OK)
{
_cupsLangPrintf(stderr, _("%s: Bad printer URI "%s"."), "lpadmin", uri);
Index: xcode/CUPS.xcodeproj/project.pbxproj

--- xcode/CUPS.xcodeproj/project.pbxproj (revision 12514)
+++ xcode/CUPS.xcodeproj/project.pbxproj (working copy)
@@ -1552,7 +1552,7 @@
7271882313746EA8001A2036 /* rastertolabel.c / = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = rastertolabel.c; path = ../filter/rastertolabel.c; sourceTree = ""; };
7271883C1374AB14001A2036 /
mime-private.h / = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "mime-private.h"; path = "../scheduler/mime-private.h"; sourceTree = ""; };
727AD5B619100A58009F6862 /
tls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tls.c; path = ../cups/tls.c; sourceTree = ""; };

  •   727EF02F192E3498001EF690 /\* admin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = admin.c; path = "../cgi-bin/admin.c"; sourceTree = "<group>"; };
    
  •   727EF02F192E3498001EF690 /\* admin.c _/ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = admin.c; path = "../cgi-bin/admin.c"; sourceTree = "<group>"; wrapsLines = 1; };
    727EF030192E3498001EF690 /_ cgi-private.h _/ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "cgi-private.h"; path = "../cgi-bin/cgi-private.h"; sourceTree = "<group>"; };
    727EF031192E3498001EF690 /_ cgi.h _/ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cgi.h; path = "../cgi-bin/cgi.h"; sourceTree = "<group>"; };
    727EF032192E3498001EF690 /_ classes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = classes.c; path = "../cgi-bin/classes.c"; sourceTree = "<group>"; };
    
    @@ -2491,7 +2491,7 @@
    indentWidth = 2;
    sourceTree = "";
    tabWidth = 8;
  •       wrapsLines = 0;
    
  •       wrapsLines = 1;
    };
    72E65BA218DC796500097E89 /\* Autoconf Files _/ = {
        isa = PBXGroup;
    
    @@ -5238,6 +5238,7 @@
    27A034801A8BDB1300650675 /_ Release */,
    );
    defaultConfigurationIsVisible = 0;
  •       defaultConfigurationName = Release;
    };
    720DD6CB1358FD600064AA82 /\* Build configuration list for PBXNativeTarget "snmp" */ = {
        isa = XCConfigurationList;
    

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant