#include <cups/cups-private.h>
#include <cups/ppd.h>
static char *psgets(char *buf, size_t *bytes, FILE *fp);
static ssize_t pswrite(const char *buf, size_t bytes);
int
main(int argc,
char *argv[])
{
FILE *fp;
int copies;
char line[1024];
size_t linelen;
ppd_file_t *ppd;
if (argc < 6 || argc > 7)
{
_cupsLangPrintf(stderr,
_("Usage: %s job-id user title copies options [file]"),
argv[0]);
return (1);
}
if (argc == 6)
{
copies = 1;
fp = stdin;
}
else
{
copies = atoi(argv[4]);
fp = fopen(argv[6], "rb");
if (!fp)
{
perror(argv[6]);
return (1);
}
}
ppd = ppdOpenFile(getenv("PPD"));
while (copies > 0)
{
copies --;
if (ppd && ppd->jcl_begin)
fputs(ppd->jcl_begin, stdout);
if (ppd && ppd->jcl_ps)
fputs(ppd->jcl_ps, stdout);
if (!ppd || ppd->language_level == 1)
{
puts("%!PS-Adobe-3.0 ExitServer");
puts("%%Title: (BCP - Level 1)");
puts("%%EndComments");
puts("%%BeginExitServer: 0");
puts("serverdict begin 0 exitserver");
puts("%%EndExitServer");
puts("statusdict begin");
puts("/setsoftwareiomode known {100 setsoftwareiomode}");
puts("end");
puts("%EOF");
}
else
{
puts("%!PS-Adobe-3.0");
puts("%%Title: (BCP - Level 2)");
puts("%%EndComments");
puts("currentsysparams");
puts("/CurInputDevice 2 copy known {");
puts("get");
puts("<</Protocol /Binary>> setdevparams");
puts("}{");
puts("pop pop");
puts("} ifelse");
puts("%EOF");
}
if (ppd && ppd->jcl_end)
fputs(ppd->jcl_end, stdout);
else if (!ppd || ppd->num_filters == 0)
putchar(0x04);
do
{
linelen = sizeof(line);
if (psgets(line, &linelen, fp) == NULL)
break;
}
while (pswrite(line, linelen) > 0);
fflush(stdout);
}
return (0);
}
static char *
psgets(char *buf,
size_t *bytes,
FILE *fp)
{
char *bufptr;
int ch;
size_t len;
len = *bytes - 1;
bufptr = buf;
ch = EOF;
while ((size_t)(bufptr - buf) < len)
{
if ((ch = getc(fp)) == EOF)
break;
if (ch == '\r')
{
ch = getc(fp);
if (ch != EOF && ch != '\n')
{
ungetc(ch, fp);
ch = '\r';
}
else
*bufptr++ = '\r';
break;
}
else if (ch == '\n')
break;
else
*bufptr++ = (char)ch;
}
if (ch == '\n' || ch == '\r')
{
if ((size_t)(bufptr - buf) < len)
*bufptr++ = (char)ch;
else
ungetc(ch, fp);
}
*bufptr = '\0';
*bytes = (size_t)(bufptr - buf);
if (ch == EOF && bufptr == buf)
return (NULL);
else
return (buf);
}
static ssize_t
pswrite(const char *buf,
size_t bytes)
{
size_t count;
for (count = bytes; count > 0; count --, buf ++)
switch (*buf)
{
case 0x04 :
if (bytes == 1)
{
putchar(0x04);
break;
}
case 0x01 :
case 0x03 :
case 0x05 :
case 0x11 :
case 0x13 :
case 0x14 :
case 0x1c :
if (putchar(0x01) < 0)
return (-1);
if (putchar(*buf ^ 0x40) < 0)
return (-1);
break;
default :
if (putchar(*buf) < 0)
return (-1);
break;
}
return ((ssize_t)bytes);
}