*
* 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
*/
#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>
* 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);
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);
/*
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 */
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);
}
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/"));
}
+/*
+ * '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$".
*/
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");
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);
}
}
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");
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;
+ }
+ }
+ }
}
/*
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));
Use the <i>-m</i> option with the
<a href="man-lpinfo.html?TOPIC=Man+Pages"><b>lpinfo</b>(8)</a>
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 <i>device-uri</i>.
<dt><b>-o cupsIPPSupplies=true</b>
<dd style="margin-left: 5.0em"><dt><b>-o cupsIPPSupplies=false</b>
<dd style="margin-left: 5.0em">Specifies whether IPP supply level values should be reported.
This differs from the System V version which requires the root user to execute this command.
<h2 class="title"><a name="NOTES">Notes</a></h2>
The CUPS version of <b>lpadmin</b> does not support all of the System V or Solaris printing system configuration options.
+<h2 class="title"><a name="EXAMPLE">Example</a></h2>
+Create an IPP Everywhere print queue:
+<pre class="man">
+
+ lpadmin -p myprinter -E -v ipp://myprinter.local/ipp/print -m everywhere
+
+</pre>
<h2 class="title"><a name="SEE_ALSO">See Also</a></h2>
<a href="man-cupsaccept.html?TOPIC=Man+Pages"><b>cupsaccept</b>(8),</a>
<a href="man-cupsenable.html?TOPIC=Man+Pages"><b>cupsenable</b>(8),</a>
<a href="man-lpoptions.html?TOPIC=Man+Pages"><b>lpoptions</b>(1),</a>
CUPS Online Help (<a href="http://localhost:631/help">http://localhost:631/help</a>)
<h2 class="title"><a name="COPYRIGHT">Copyright</a></h2>
-Copyright © 2007-2014 by Apple Inc.
+Copyright © 2007-2015 by Apple Inc.
</body>
</html>
* 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
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...
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 */
* 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);
7271882313746EA8001A2036 /* rastertolabel.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = rastertolabel.c; path = ../filter/rastertolabel.c; sourceTree = "<group>"; };
7271883C1374AB14001A2036 /* mime-private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "mime-private.h"; path = "../scheduler/mime-private.h"; sourceTree = "<group>"; };
727AD5B619100A58009F6862 /* tls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tls.c; path = ../cups/tls.c; sourceTree = "<group>"; };
- 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>"; };
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 8;
- wrapsLines = 0;
+ wrapsLines = 1;
};
72E65BA218DC796500097E89 /* Autoconf Files */ = {
isa = PBXGroup;
27A034801A8BDB1300650675 /* Release */,
);
defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
};
720DD6CB1358FD600064AA82 /* Build configuration list for PBXNativeTarget "snmp" */ = {
isa = XCConfigurationList;