#include <cups/cups.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <cups/string.h>
#include <signal.h>
#ifdef WIN32
# include <io.h>
#else
# include <unistd.h>
# include <fcntl.h>
# include <termios.h>
#endif
#ifdef __sgi
# include <invent.h>
# ifndef INV_EPP_ECP_PLP
# define INV_EPP_ECP_PLP 6
# define INV_ASO_SERIAL 14
# define INV_IOC3_DMA 16
# define INV_IOC3_PIO 17
# define INV_ISA_DMA 19
# endif
#endif
void list_devices(void);
int
main(int argc,
char *argv[])
{
char method[255],
hostname[1024],
username[255],
resource[1024],
*options;
int port;
int fp;
int copies;
int fd;
int wbytes;
size_t nbytes,
tbytes;
char buffer[8192],
*bufptr;
struct termios opts;
#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
struct sigaction action;
#endif
setbuf(stderr, NULL);
if (argc == 1)
{
list_devices();
return (0);
}
else if (argc < 6 || argc > 7)
{
fputs("Usage: parallel job-id user title copies options [file]\n", stderr);
return (1);
}
if (argc == 6)
{
fp = 0;
copies = 1;
}
else
{
if ((fp = open(argv[6], O_RDONLY)) < 0)
{
perror("ERROR: unable to open print file");
return (1);
}
copies = atoi(argv[4]);
}
httpSeparate(argv[0], method, username, hostname, &port, resource);
if ((options = strchr(resource, '?')) != NULL)
{
*options++ = '\0';
}
do
{
if ((fd = open(resource, O_WRONLY | O_EXCL)) == -1)
{
if (errno == EBUSY)
{
fputs("INFO: Parallel port busy; will retry in 30 seconds...\n", stderr);
sleep(30);
}
else if (errno == ENXIO || errno == EIO || errno == ENOENT)
{
fputs("INFO: Printer not connected; will retry in 30 seconds...\n", stderr);
sleep(30);
}
else
{
fprintf(stderr, "ERROR: Unable to open parallel port device file \"%s\": %s\n",
resource, strerror(errno));
return (1);
}
}
}
while (fd < 0);
tcgetattr(fd, &opts);
opts.c_lflag &= ~(ICANON | ECHO | ISIG);
tcsetattr(fd, TCSANOW, &opts);
if (argc < 7)
{
#ifdef HAVE_SIGSET
sigset(SIGTERM, SIG_IGN);
#elif defined(HAVE_SIGACTION)
memset(&action, 0, sizeof(action));
sigemptyset(&action.sa_mask);
action.sa_handler = SIG_IGN;
sigaction(SIGTERM, &action, NULL);
#else
signal(SIGTERM, SIG_IGN);
#endif
}
while (copies > 0)
{
copies --;
if (fp != 0)
{
fputs("PAGE: 1 1\n", stderr);
lseek(fp, 0, SEEK_SET);
}
tbytes = 0;
while ((nbytes = read(fp, buffer, sizeof(buffer))) > 0)
{
tbytes += nbytes;
bufptr = buffer;
while (nbytes > 0)
{
if ((wbytes = write(fd, bufptr, nbytes)) < 0)
if (errno == ENOTTY)
wbytes = write(fd, bufptr, nbytes);
if (wbytes < 0)
{
perror("ERROR: Unable to send print file to printer");
break;
}
nbytes -= wbytes;
bufptr += wbytes;
}
if (argc > 6)
fprintf(stderr, "INFO: Sending print file, %lu bytes...\n",
(unsigned long)tbytes);
}
}
close(fd);
if (fp != 0)
close(fp);
fputs("INFO: Ready to print.\n", stderr);
return (0);
}
void
list_devices(void)
{
#if defined(__hpux) || defined(__sgi) || defined(__sun)
static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz";
#endif
#ifdef __linux
int i;
int fd;
char device[255],
probefile[255],
basedevice[255];
FILE *probe;
char line[1024],
*delim,
make[IPP_MAX_NAME],
model[IPP_MAX_NAME];
for (i = 0; i < 4; i ++)
{
if ((fd = open("/dev/parallel/0", O_WRONLY)) >= 0)
{
close(fd);
strcpy(basedevice, "/dev/parallel/");
}
else
{
sprintf(device, "/dev/lp%d", i);
if ((fd = open(device, O_WRONLY)) >= 0)
{
close(fd);
strcpy(basedevice, "/dev/lp");
}
else
{
sprintf(device, "/dev/par%d", i);
if ((fd = open(device, O_WRONLY)) >= 0)
{
close(fd);
strcpy(basedevice, "/dev/par");
}
else
{
sprintf(device, "/dev/printers/%d", i);
if ((fd = open(device, O_WRONLY)) >= 0)
{
close(fd);
strcpy(basedevice, "/dev/printers/");
}
else
strcpy(basedevice, "/dev/unknown-parallel");
}
}
}
sprintf(probefile, "/proc/parport/%d/autoprobe", i);
if ((probe = fopen(probefile, "r")) == NULL)
{
sprintf(probefile, "/proc/sys/dev/parport/parport%d/autoprobe", i);
probe = fopen(probefile, "r");
}
if (probe != NULL)
{
memset(make, 0, sizeof(make));
memset(model, 0, sizeof(model));
strcpy(model, "Unknown");
while (fgets(line, sizeof(line), probe) != NULL)
{
if ((delim = strrchr(line, ';')) != NULL)
*delim = '\0';
else if ((delim = strrchr(line, '\n')) != NULL)
*delim = '\0';
if (strncmp(line, "MODEL:", 6) == 0 &&
strncmp(line, "MODEL:Unknown", 13) != 0)
strlcpy(model, line + 6, sizeof(model));
else if (strncmp(line, "MANUFACTURER:", 13) == 0 &&
strncmp(line, "MANUFACTURER:Unknown", 20) != 0)
strlcpy(make, line + 13, sizeof(make));
}
fclose(probe);
if (make[0])
printf("direct parallel:%s%d \"%s %s\" \"Parallel Port #%d\"\n",
basedevice, i, make, model, i + 1);
else
printf("direct parallel:%s%d \"%s\" \"Parallel Port #%d\"\n",
basedevice, i, model, i + 1);
}
else if (fd >= 0)
{
printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1);
}
}
#elif defined(__sgi)
int i, j, n;
char device[255];
inventory_t *inv;
setinvent();
while ((inv = getinvent()) != NULL)
{
if (inv->inv_class == INV_PARALLEL &&
(inv->inv_type == INV_ONBOARD_PLP ||
inv->inv_type == INV_EPP_ECP_PLP))
{
puts("direct parallel:/dev/plp \"Unknown\" \"Onboard Parallel Port\"");
}
else if (inv->inv_class == INV_PARALLEL &&
inv->inv_type == INV_EPC_PLP)
{
printf("direct parallel:/dev/plp%d \"Unknown\" \"Integral EPC parallel port, Ebus slot %d\"\n",
inv->inv_controller, inv->inv_controller);
}
}
endinvent();
for (i = 0; i < 10; i ++)
for (j = 0; j < 8; j ++)
for (n = 0; n < 32; n ++)
{
if (i == 8)
sprintf(device, "/dev/lpn%d%c", j, funky_hex[n]);
else if (i == 9)
sprintf(device, "/dev/lpp%d%c", j, funky_hex[n]);
else
sprintf(device, "/dev/lp%d%d%c", i, j, funky_hex[n]);
if (access(device, 0) == 0)
{
if (i == 8)
printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n",
device, j, n);
else if (i == 9)
printf("direct parallel:%s \"Unknown\" \"Central Data PCI Parallel Port, ID %d, port %d\"\n",
device, j, n);
else
printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n",
device, i, j, n);
}
}
#elif defined(__sun)
int i, j, n;
char device[255];
for (i = 0; i < 10; i ++)
{
sprintf(device, "/dev/ecpp%d", i);
if (access(device, 0) == 0)
printf("direct parallel:%s \"Unknown\" \"Sun IEEE-1284 Parallel Port #%d\"\n",
device, i + 1);
}
for (i = 0; i < 10; i ++)
{
sprintf(device, "/dev/bpp%d", i);
if (access(device, 0) == 0)
printf("direct parallel:%s \"Unknown\" \"Sun Standard Parallel Port #%d\"\n",
device, i + 1);
}
for (i = 0; i < 3; i ++)
{
sprintf(device, "/dev/lp%d", i);
if (access(device, 0) == 0)
printf("direct parallel:%s \"Unknown\" \"PC Parallel Port #%d\"\n",
device, i + 1);
}
for (i = 0; i < 40; i ++)
{
sprintf(device, "/dev/pm%02d", i);
if (access(device, 0) == 0)
printf("direct parallel:%s \"Unknown\" \"MAGMA Parallel Board #%d Port #%d\"\n",
device, (i / 10) + 1, (i % 10) + 1);
}
for (i = 0; i < 9; i ++)
for (j = 0; j < 8; j ++)
for (n = 0; n < 32; n ++)
{
if (i == 8)
sprintf(device, "/dev/sts/lpN%d%c", j, funky_hex[n]);
else
sprintf(device, "/dev/sts/lp%c%d%c", i + 'C', j,
funky_hex[n]);
if (access(device, 0) == 0)
{
if (i == 8)
printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n",
device, j, n);
else
printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n",
device, i, j, n);
}
}
#elif defined(__hpux)
int i, j, n;
char device[255];
if (access("/dev/rlp", 0) == 0)
puts("direct parallel:/dev/rlp \"Unknown\" \"Standard Parallel Port (/dev/rlp)\"");
for (i = 0; i < 7; i ++)
for (j = 0; j < 7; j ++)
{
sprintf(device, "/dev/c%dt%dd0_lp", i, j);
if (access(device, 0) == 0)
printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d,%d\"\n",
device, i, j);
}
for (i = 0; i < 9; i ++)
for (j = 0; j < 8; j ++)
for (n = 0; n < 32; n ++)
{
if (i == 8)
sprintf(device, "/dev/lpN%d%c", j, funky_hex[n]);
else
sprintf(device, "/dev/lp%c%d%c", i + 'C', j,
funky_hex[n]);
if (access(device, 0) == 0)
{
if (i == 8)
printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n",
device, j, n);
else
printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n",
device, i, j, n);
}
}
#elif defined(__osf__)
int i;
int fd;
char device[255];
for (i = 0; i < 3; i ++)
{
sprintf(device, "/dev/lp%d", i);
if ((fd = open(device, O_WRONLY)) >= 0)
{
close(fd);
printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1);
}
}
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
int i;
int fd;
char device[255];
for (i = 0; i < 3; i ++)
{
sprintf(device, "/dev/lpt%d", i);
if ((fd = open(device, O_WRONLY)) >= 0)
{
close(fd);
printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (interrupt-driven)\"\n", device, i + 1);
}
sprintf(device, "/dev/lpa%d", i);
if ((fd = open(device, O_WRONLY)) >= 0)
{
close(fd);
printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d (polled)\"\n", device, i + 1);
}
}
#elif defined(_AIX)
int i;
int fd;
char device[255];
for (i = 0; i < 8; i ++)
{
sprintf(device, "/dev/lp%d", i);
if ((fd = open(device, O_WRONLY)) >= 0)
{
close(fd);
printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1);
}
}
#endif
}