#include <cups/dir.h>
#include <cups/transcode.h>
#include "ppd.h"
+#include "ppdc.h"
#include "file-private.h"
#include "array-private.h"
#include <regex.h>
size_t size, int model_number, int type,
const char *scheme, ppd_list_t *ppdlist,
filter_logfunc_t log, void *ld);
+static cups_file_t *cat_drv(const char *name, char *ppdname,
+ filter_logfunc_t log, void *ld);
static cups_file_t *cat_static(const char *name,
filter_logfunc_t log, void *ld);
static cups_file_t *cat_tar(const char *name, char *ppdname,
const char *name,
ppd_list_t *ppdlist,
filter_logfunc_t log, void *ld);
+static int load_drv(const char *filename, const char *name,
+ cups_file_t *fp, time_t mtime, off_t size,
+ ppd_list_t *ppdlist,
+ filter_logfunc_t log, void *ld);
static void load_ppd(const char *filename, const char *name,
const char *scheme, struct stat *fileinfo,
ppd_info_t *ppd, cups_file_t *fp, off_t end,
int pid;
int bytes;
int is_archive = 0;
+ int is_drv = 0;
char realname[1024], /* Scheme from PPD name */
buffer[8192], /* Copy buffer */
tempname[1024], /* Temp file name */
if (strstr(name, ".tar:") || strstr(name, ".tar.gz:"))
is_archive = 1;
+ else if (strstr(name, ".drv:"))
+ is_drv = 1;
if (ppd_collections)
{
ppdname = NULL;
else
{
- if (!is_archive)
+ if (!is_archive && !is_drv)
strlcpy(ppduri, realname, sizeof(ppduri));
*ptr = '\0';
ppdname = ptr + 1;
ppdname = NULL;
else
{
- if (!is_archive)
+ if (!is_archive && !is_drv)
strlcpy(ppduri, realname, sizeof(ppduri));
*ptr = '\0';
ppdname = ptr + 1;
if (is_archive)
return(cat_tar(realname, ppdname, log, ld));
+ else if (is_drv)
+ return(cat_drv(realname, ppdname, log, ld));
else if (ppdname == NULL)
return(cat_static(realname, log, ld));
else
}
+/*
+ * 'cat_drv()' - Generate a PPD from a driver info file.
+ */
+
+static cups_file_t * /* O - Pointer to PPD file */
+cat_drv(const char *filename, /* I - *.drv file name */
+ char *ppdname, /* I - PPD name in the *.drv file */
+ filter_logfunc_t log, /* I - Log function */
+ void *ld) /* I - Aux. data for log function */
+{
+ cups_file_t *fp; // File pointer
+ int fd;
+ char tempname[1024]; // Name for the temporary file
+ ppdcSource *src; // PPD source file data
+ ppdcDriver *d; // Current driver
+ cups_file_t *out; // PPD output to temp file
+
+ if ((fp = cupsFileOpen(filename, "r")) == NULL)
+ {
+ if (log) log(ld, FILTER_LOGLEVEL_ERROR,
+ "libppd: [PPD Collections] Unable to open \"%s\" - %s\n",
+ filename, strerror(errno));
+
+ return (NULL);
+ }
+
+ src = new ppdcSource(filename, fp);
+
+ for (d = (ppdcDriver *)src->drivers->first();
+ d;
+ d = (ppdcDriver *)src->drivers->next())
+ if (!strcmp(ppdname, d->pc_file_name->value) ||
+ (d->file_name && !strcmp(ppdname, d->file_name->value)))
+ break;
+
+ if (d)
+ {
+ ppdcArray *locales; // Locale names
+ ppdcCatalog *catalog; // Message catalog in .drv file
+
+
+ if (log) log(ld, FILTER_LOGLEVEL_DEBUG,
+ "libppd: [PPD Collections] %u locales defined in \"%s\"...\n",
+ (unsigned)src->po_files->count, filename);
+
+ locales = new ppdcArray();
+ for (catalog = (ppdcCatalog *)src->po_files->first();
+ catalog;
+ catalog = (ppdcCatalog *)src->po_files->next())
+ {
+ if (log) log(ld, FILTER_LOGLEVEL_DEBUG,
+ "libppd: [PPD Collections] Adding locale \"%s\"...\n",
+ catalog->locale->value);
+ catalog->locale->retain();
+ locales->add(catalog->locale);
+ }
+
+ if ((fd = cupsTempFd(tempname, sizeof(tempname))) < 0)
+ {
+ if (log) log(ld, FILTER_LOGLEVEL_ERROR,
+ "libppd: [PPD Collections] Unable to copy PPD to temp "
+ "file: %s",
+ strerror(errno));
+ return (NULL);
+ }
+ out = cupsFileOpenFd(fd, "w");
+ d->write_ppd_file(out, NULL, locales, src, PPDC_LFONLY);
+ cupsFileClose(out);
+ close(fd);
+ locales->release();
+ src->release();
+ cupsFileClose(fp);
+
+ out = cupsFileOpen(tempname, "r");
+ unlink(tempname);
+
+ return(out);
+
+ }
+ else
+ if (log) log(ld, FILTER_LOGLEVEL_ERROR,
+ "libppd: [PPD Collections] PPD \"%s\" not found.\n", ppdname);
+
+ src->release();
+ cupsFileClose(fp);
+
+ return (NULL);
+}
+
+
/*
* 'cat_static()' - Return pointer to static PPD file
*/
/*
- * 'cat_tar()' - Copy an archived PPD file to stdout.
+ * 'cat_tar()' - Copy an archived PPD file to temp file.
*/
static cups_file_t * /* O - Pointer to PPD file */
}
+/*
+ * 'load_drv()' - Load the PPDs from a driver information file.
+ */
+
+static int /* O - 1 on success, 0 on failure */
+load_drv(const char *filename, /* I - Actual filename */
+ const char *name, /* I - Name to the rest of the world */
+ cups_file_t *fp, /* I - File to read from */
+ time_t mtime, /* I - Mod time of driver info file */
+ off_t size, /* I - Size of driver info file */
+ ppd_list_t *ppdlist,
+ filter_logfunc_t log, /* I - Log function */
+ void *ld) /* I - Aux. data for log function */
+{
+ ppdcSource *src; // Driver information file
+ ppdcDriver *d; // Current driver
+ ppdcAttr *device_id, // 1284DeviceID attribute
+ *product, // Current product value
+ *ps_version, // PSVersion attribute
+ *cups_fax, // cupsFax attribute
+ *nick_name; // NickName attribute
+ ppdcFilter *filter; // Current filter
+ ppd_info_t *ppd; // Current PPD
+ int products_found; // Number of products found
+ char uri[2048], // Driver URI
+ make_model[1024]; // Make and model
+ int type; // Driver type
+
+
+ /*
+ * Load the driver info file...
+ */
+
+ src = new ppdcSource(filename, fp);
+
+ if (src->drivers->count == 0)
+ {
+ if (log) log(ld, FILTER_LOGLEVEL_ERROR,
+ "libppd: [PPD Collections] Bad driver information file \"%s\"!\n",
+ filename);
+ src->release();
+ return (0);
+ }
+
+ /*
+ * Add a dummy entry for the file...
+ */
+
+ add_ppd(filename, name, "", "", "", "", "", "", mtime, (size_t)size, 0,
+ PPD_TYPE_DRV, "drv", ppdlist, log, ld);
+
+ /*
+ * Then the drivers in the file...
+ */
+
+ for (d = (ppdcDriver *)src->drivers->first();
+ d;
+ d = (ppdcDriver *)src->drivers->next())
+ {
+ snprintf(uri, sizeof(uri), "%s:%s", name,
+ d->file_name ? d->file_name->value :
+ d->pc_file_name->value);
+
+ device_id = d->find_attr("1284DeviceID", NULL);
+ ps_version = d->find_attr("PSVersion", NULL);
+ nick_name = d->find_attr("NickName", NULL);
+
+ if (nick_name)
+ strncpy(make_model, nick_name->value->value, sizeof(make_model) - 1);
+ else if (strncasecmp(d->model_name->value, d->manufacturer->value,
+ strlen(d->manufacturer->value)))
+ snprintf(make_model, sizeof(make_model), "%s %s, %s",
+ d->manufacturer->value, d->model_name->value,
+ d->version->value);
+ else
+ snprintf(make_model, sizeof(make_model), "%s, %s", d->model_name->value,
+ d->version->value);
+
+ if ((cups_fax = d->find_attr("cupsFax", NULL)) != NULL &&
+ !strcasecmp(cups_fax->value->value, "true"))
+ type = PPD_TYPE_FAX;
+ else if (d->type == PPDC_DRIVER_PS)
+ type = PPD_TYPE_POSTSCRIPT;
+ else if (d->type != PPDC_DRIVER_CUSTOM)
+ type = PPD_TYPE_RASTER;
+ else
+ {
+ for (filter = (ppdcFilter *)d->filters->first(),
+ type = PPD_TYPE_POSTSCRIPT;
+ filter;
+ filter = (ppdcFilter *)d->filters->next())
+ if (strcasecmp(filter->mime_type->value, "application/vnd.cups-raster"))
+ type = PPD_TYPE_RASTER;
+ else if (strcasecmp(filter->mime_type->value,
+ "application/vnd.cups-pdf"))
+ type = PPD_TYPE_PDF;
+ }
+
+ for (product = (ppdcAttr *)d->attrs->first(), products_found = 0,
+ ppd = NULL;
+ product;
+ product = (ppdcAttr *)d->attrs->next())
+ if (!strcmp(product->name->value, "Product"))
+ {
+ if (!products_found)
+ ppd = add_ppd(filename, uri, "en", d->manufacturer->value,
+ make_model, device_id ? device_id->value->value : "",
+ product->value->value,
+ ps_version ? ps_version->value->value : "(3010) 0",
+ mtime, (size_t)size, d->model_number, type, "drv",
+ ppdlist, log, ld);
+ else if (products_found < PPD_MAX_PROD)
+ strncpy(ppd->record.products[products_found], product->value->value,
+ sizeof(ppd->record.products[0]));
+ else
+ break;
+
+ products_found ++;
+ }
+
+ if (!products_found)
+ add_ppd(filename, uri, "en", d->manufacturer->value, make_model,
+ device_id ? device_id->value->value : "", d->model_name->value,
+ ps_version ? ps_version->value->value : "(3010) 0", mtime,
+ (size_t)size, d->model_number, type, "drv", ppdlist, log, ld);
+ }
+
+ src->release();
+
+ return (1);
+}
+
+
/*
* 'load_ppd()' - Load a PPD file.
*/
else
{
/*
- * Nope, treat it as a an archive or PPD-generating executable...
+ * Nope, treat it as a an archive, a PPD-generating executable, or a
+ * driver information file...
*/
cupsFileRewind(fp);
(!strcmp(ptr, ".tar") || !strcmp(ptr, ".tar.gz")))
load_tar(filename, name, fp, dent->fileinfo.st_mtime,
dent->fileinfo.st_size, ppdlist, log, ld);
+ else if ((ptr = strstr(filename, ".drv")) != NULL && !strcmp(ptr, ".drv"))
+ load_drv(filename, name, fp, dent->fileinfo.st_mtime,
+ dent->fileinfo.st_size, ppdlist, log, ld);
else if ((dent->fileinfo.st_mode & 0111) &&
S_ISREG(dent->fileinfo.st_mode))
{
//
#include "ppdc-private.h"
-#include <cupsfilters/ppdgenerator.h>
+#include "string-private.h"
//
if ((a = find_attr("cupsVersion", NULL)) != NULL)
cupsFilePrintf(fp, "*cupsVersion: %s%s", a->value->value, lf);
else
- cupsFilePrintf(fp, "*cupsVersion: %d.%d%s", CUPS_VERSION_MAJOR,
- CUPS_VERSION_MINOR, lf);
+ cupsFilePrintf(fp, "*cupsVersion: %s%s", PACKAGE_VERSION, lf);
cupsFilePrintf(fp, "*cupsModelNumber: %d%s", model_number, lf);
cupsFilePrintf(fp, "*cupsManualCopies: %s%s",
manual_copies ? "True" : "False", lf);
{
char density[255], gamma[255], profile[9][255];
- cfStrFormatd(density, density + sizeof(density), p->density, loc);
- cfStrFormatd(gamma, gamma + sizeof(gamma), p->gamma, loc);
+ _ppdStrFormatd(density, density + sizeof(density), p->density, loc);
+ _ppdStrFormatd(gamma, gamma + sizeof(gamma), p->gamma, loc);
for (int i = 0; i < 9; i ++)
- cfStrFormatd(profile[i], profile[i] + sizeof(profile[0]),
+ _ppdStrFormatd(profile[i], profile[i] + sizeof(profile[0]),
p->profile[i], loc);
cupsFilePrintf(fp,
m;
m = (ppdcMediaSize *)sizes->next())
{
- cfStrFormatd(left, left + sizeof(left), m->left, loc);
- cfStrFormatd(bottom, bottom + sizeof(bottom), m->bottom, loc);
- cfStrFormatd(right, right + sizeof(right), m->width - m->right, loc);
- cfStrFormatd(top, top + sizeof(top), m->length - m->top, loc);
+ _ppdStrFormatd(left, left + sizeof(left), m->left, loc);
+ _ppdStrFormatd(bottom, bottom + sizeof(bottom), m->bottom, loc);
+ _ppdStrFormatd(right, right + sizeof(right), m->width - m->right, loc);
+ _ppdStrFormatd(top, top + sizeof(top), m->length - m->top, loc);
cupsFilePrintf(fp, "*ImageableArea %s/%s: \"%s %s %s %s\"%s",
m->name->value, catalog->find_message(m->text->value),
m;
m = (ppdcMediaSize *)sizes->next())
{
- cfStrFormatd(width, width + sizeof(width), m->width, loc);
- cfStrFormatd(length, length + sizeof(length), m->length, loc);
+ _ppdStrFormatd(width, width + sizeof(width), m->width, loc);
+ _ppdStrFormatd(length, length + sizeof(length), m->length, loc);
cupsFilePrintf(fp, "*PaperDimension %s/%s: \"%s %s\"%s",
m->name->value, catalog->find_message(m->text->value),
// Custom size support...
if (variable_paper_size)
{
- cfStrFormatd(width, width + sizeof(width), max_width, loc);
- cfStrFormatd(length, length + sizeof(length), max_length, loc);
+ _ppdStrFormatd(width, width + sizeof(width), max_width, loc);
+ _ppdStrFormatd(length, length + sizeof(length), max_length, loc);
- cfStrFormatd(left, left + sizeof(left), left_margin, loc);
- cfStrFormatd(bottom, bottom + sizeof(bottom), bottom_margin, loc);
- cfStrFormatd(right, right + sizeof(right), right_margin, loc);
- cfStrFormatd(top, top + sizeof(top), top_margin, loc);
+ _ppdStrFormatd(left, left + sizeof(left), left_margin, loc);
+ _ppdStrFormatd(bottom, bottom + sizeof(bottom), bottom_margin, loc);
+ _ppdStrFormatd(right, right + sizeof(right), right_margin, loc);
+ _ppdStrFormatd(top, top + sizeof(top), top_margin, loc);
cupsFilePrintf(fp, "*MaxMediaWidth: \"%s\"%s", width, lf);
cupsFilePrintf(fp, "*MaxMediaHeight: \"%s\"%s", length, lf);
{
char width0[255];
- cfStrFormatd(width0, width0 + sizeof(width0), min_width, loc);
- cfStrFormatd(width, width + sizeof(width), max_width, loc);
+ _ppdStrFormatd(width0, width0 + sizeof(width0), min_width, loc);
+ _ppdStrFormatd(width, width + sizeof(width), max_width, loc);
cupsFilePrintf(fp, "*ParamCustomPageSize Width: 1 points %s %s%s",
width0, width, lf);
{
char length0[255];
- cfStrFormatd(length0, length0 + sizeof(length0), min_length, loc);
- cfStrFormatd(length, length + sizeof(length), max_length, loc);
+ _ppdStrFormatd(length0, length0 + sizeof(length0), min_length, loc);
+ _ppdStrFormatd(length, length + sizeof(length), max_length, loc);
cupsFilePrintf(fp, "*ParamCustomPageSize Height: 2 points %s %s%s",
length0, length, lf);
}
char order[255];
- cfStrFormatd(order, order + sizeof(order), o->order, loc);
+ _ppdStrFormatd(order, order + sizeof(order), o->order, loc);
cupsFilePrintf(fp, "*OrderDependency: %s ", order);
switch (o->section)