#include "ppdc-private.h"
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
static void usage(void);
int main(int argc, char *argv[]) {
int i, j; ppdcCatalog *catalog; const char *outdir; ppdcSource *src; ppdcDriver *d; cups_file_t *fp; char *opt, *value, *outname, make_model[1024],
pcfilename[1024],
filename[1024]; int comp, do_test, single_language, use_model_name, verbose; ppdcLineEnding le; ppdcArray *locales; cups_array_t *filenames;
_cupsSetLocale(argv);
catalog = NULL;
comp = 0;
do_test = 0;
le = PPDC_LFONLY;
locales = NULL;
outdir = "ppd";
single_language = 0;
src = new ppdcSource();
use_model_name = 0;
verbose = 0;
filenames = cupsArrayNew((cups_array_func_t)strcasecmp, NULL);
for (i = 1; i < argc; i ++)
if (argv[i][0] == '-')
{
for (opt = argv[i] + 1; *opt; opt ++)
switch (*opt)
{
case 'D' : i ++;
if (i >= argc)
usage();
if ((value = strchr(argv[i], '=')) != NULL)
{
*value++ = '\0';
src->set_variable(argv[i], value);
}
else
src->set_variable(argv[i], "1");
break;
case 'I' : i ++;
if (i >= argc)
usage();
if (verbose > 1)
_cupsLangPrintf(stdout,
_("ppdc: Adding include directory \"%s\"...\n"),
argv[i]);
ppdcSource::add_include(argv[i]);
break;
case 'c' : i ++;
if (i >= argc)
usage();
if (verbose > 1)
_cupsLangPrintf(stdout,
_("ppdc: Loading messages from \"%s\"...\n"),
argv[i]);
if (!catalog)
catalog = new ppdcCatalog("en");
if (catalog->load_messages(argv[i]))
{
_cupsLangPrintf(stderr,
_("ppdc: Unable to load localization file "
"\"%s\" - %s\n"), argv[i], strerror(errno));
return (1);
}
break;
case 'd' : i ++;
if (i >= argc)
usage();
if (verbose > 1)
_cupsLangPrintf(stdout,
_("ppdc: Writing PPD files to directory "
"\"%s\"...\n"), argv[i]);
outdir = argv[i];
break;
case 'l' : i ++;
if (i >= argc)
usage();
if (strchr(argv[i], ','))
{
char temp[1024], *start, *end;
locales = new ppdcArray();
strlcpy(temp, argv[i], sizeof(temp));
for (start = temp; *start; start = end)
{
if ((end = strchr(start, ',')) != NULL)
*end++ = '\0';
else
end = start + strlen(start);
if (end > start)
locales->add(new ppdcString(start));
}
}
else
{
single_language = 1;
if (verbose > 1)
_cupsLangPrintf(stdout,
_("ppdc: Loading messages for locale "
"\"%s\"...\n"), argv[i]);
if (catalog)
catalog->release();
catalog = new ppdcCatalog(argv[i]);
if (catalog->messages->count == 0)
{
_cupsLangPrintf(stderr,
_("ppdc: Unable to find localization for "
"\"%s\" - %s\n"), argv[i], strerror(errno));
return (1);
}
}
break;
case 'm' : use_model_name = 1;
break;
case 't' : do_test = 1;
break;
case 'v' : verbose ++;
break;
case 'z' : comp = 1;
break;
case '-' : if (!strcmp(opt, "-lf"))
{
le = PPDC_LFONLY;
opt += strlen(opt) - 1;
break;
}
else if (!strcmp(opt, "-cr"))
{
le = PPDC_CRONLY;
opt += strlen(opt) - 1;
break;
}
else if (!strcmp(opt, "-crlf"))
{
le = PPDC_CRLF;
opt += strlen(opt) - 1;
break;
}
default : usage();
break;
}
}
else
{
if (verbose > 1)
_cupsLangPrintf(stdout,
_("ppdc: Loading driver information file \"%s\"...\n"),
argv[i]);
src->read_file(argv[i]);
}
if (src->drivers->count > 0)
{
if (mkdir(outdir, 0777))
{
if (errno != EEXIST)
{
_cupsLangPrintf(stderr,
_("ppdc: Unable to create output directory %s: %s\n"),
outdir, strerror(errno));
return (1);
}
}
for (d = (ppdcDriver *)src->drivers->first();
d;
d = (ppdcDriver *)src->drivers->next())
{
if (do_test)
{
int pid, fds[2];
if (pipe(fds))
{
_cupsLangPrintf(stderr,
_("ppdc: Unable to create output pipes: %s\n"),
strerror(errno));
return (1);
}
if ((pid = fork()) == 0)
{
dup2(fds[0], 0);
close(fds[0]);
close(fds[1]);
execlp("cupstestppd", "cupstestppd", "-", (char *)0);
_cupsLangPrintf(stderr,
_("ppdc: Unable to execute cupstestppd: %s\n"),
strerror(errno));
return (errno);
}
else if (pid < 0)
{
_cupsLangPrintf(stderr,
_("ppdc: Unable to execute cupstestppd: %s\n"),
strerror(errno));
return (errno);
}
close(fds[0]);
fp = cupsFileOpenFd(fds[1], "w");
}
else
{
if (use_model_name)
{
if (!strncasecmp(d->model_name->value, d->manufacturer->value,
strlen(d->manufacturer->value)))
{
outname = d->model_name->value;
}
else
{
snprintf(make_model, sizeof(make_model), "%s %s",
d->manufacturer->value, d->model_name->value);
outname = make_model;
}
}
else if (d->file_name)
outname = d->file_name->value;
else
outname = d->pc_file_name->value;
if (strstr(outname, ".PPD"))
{
for (j = 0;
outname[j] && j < (int)(sizeof(pcfilename) - 1);
j ++)
pcfilename[j] = tolower(outname[j] & 255);
pcfilename[j] = '\0';
}
else
{
strlcpy(pcfilename, outname, sizeof(pcfilename));
}
if (comp)
snprintf(filename, sizeof(filename), "%s/%s.gz", outdir, pcfilename);
else
snprintf(filename, sizeof(filename), "%s/%s", outdir, pcfilename);
if (cupsArrayFind(filenames, filename))
_cupsLangPrintf(stderr,
_("ppdc: Warning - overlapping filename \"%s\".\n"),
filename);
else
cupsArrayAdd(filenames, strdup(filename));
fp = cupsFileOpen(filename, comp ? "w9" : "w");
if (!fp)
{
_cupsLangPrintf(stderr,
_("ppdc: Unable to create PPD file \"%s\" - %s.\n"),
filename, strerror(errno));
return (1);
}
if (verbose)
_cupsLangPrintf(stdout, _("ppdc: Writing %s...\n"), filename);
}
ppdcArray *templocales = locales;
if (!templocales && !single_language)
{
templocales = new ppdcArray();
for (ppdcCatalog *tempcatalog = (ppdcCatalog *)src->po_files->first();
tempcatalog;
tempcatalog = (ppdcCatalog *)src->po_files->next())
{
tempcatalog->locale->retain();
templocales->add(tempcatalog->locale);
}
}
if (d->write_ppd_file(fp, catalog, templocales, src, le))
{
cupsFileClose(fp);
return (1);
}
if (templocales != locales)
templocales->release();
cupsFileClose(fp);
}
}
else
usage();
src->release();
if (catalog)
catalog->release();
return (0);
}
static void
usage(void)
{
_cupsLangPuts(stdout,
_("Usage: ppdc [options] filename.drv [ ... filenameN.drv ]\n"
"Options:\n"
" -D name=value Set named variable to value.\n"
" -I include-dir Add include directory to search "
"path.\n"
" -c catalog.po Load the specified message catalog.\n"
" -d output-dir Specify the output directory.\n"
" -l lang[,lang,...] Specify the output language(s) "
"(locale).\n"
" -m Use the ModelName value as the "
"filename.\n"
" -t Test PPDs instead of generating "
"them.\n"
" -v Be verbose (more v's for more "
"verbosity).\n"
" -z Compress PPD files using GNU zip.\n"
" --cr End lines with CR (Mac OS 9).\n"
" --crlf End lines with CR + LF (Windows).\n"
" --lf End lines with LF (UNIX/Linux/Mac "
"OS X).\n"));
exit(1);
}