This is ps-pagecount.c in view mode; [Download] [Up]
/* ps-pagecount.c -- gets cumulative page count from a PostScript printer
that is directly connected via TCP/IP network interface,
e.g., HP LaserJet ???/PS with JetDirect Ethernet interface.
The printer must have a PostScript interpreter built-in.
It does not work with a PCL only printer with JetDirect.
Usage: ps-pagecount printer_hostname [port#]
If omitted, port# defaults to 9100.
*** Generic compile command:
cc -o ps-pagecount ps-pagecount.c
*** On NEXTSTEP
Single arch compile:
cc -Wall -s -o ps-pagecount ps-pagecount.c
Fat compile (add -arch xxxx as needed):
cc -Wall -s -arch m68k -arch i386 -o ps-pagecount ps-pagecount.c
*/
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <libc.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define DEF_PRINTER_PORT 9100 /* TCP port of network printer */
#define ERROR_WAIT_SEC 60 /* seconds to wait for pagecount response */
#define OPEN_RETRY_DELAY 15 /* delay for open retry attempts */
#define BUSY_RETRY_LIMIT 120 /* 30 min (#minutes x 60/OPEN_RETRY_DELAY) */
#ifdef HAVE_STRERROR
#define ERRSTR strerror(errno)
#else
extern char *sys_errlist[];
#define ERRSTR sys_errlist[errno]
#endif
/* some global vars */
int sockfd = -1;
char Host[64];
unsigned short Port;
/* OLD -- PostScript command for getting page count returned via PostScript stdout */
/*
char *page_count_comd = "%!\n\
(%%PageCount: ) print\n\
statusdict /pagecount get exec ( ) cvs print ( \\n) print flush\n\004";
*/
/* PostScript command for getting page count returned via PostScript stdout */
char *page_count_comd = "%!\n\
(%%PageCount: ) print\n\
statusdict begin pagecount == end flush\n\004";
/* Opens a TCP socket to the printer */
/* When the printer is busy, we have to keep trying until the port opens */
void open_sock(void)
{
struct hostent *host; /* host entry pointer */
struct sockaddr_in sin;
int retry = 0;
if ((host = gethostbyname (Host)) == NULL) {
fprintf (stderr, "Unknown host: %s [%s]\n", Host, ERRSTR);
exit (2);
}
bzero ((char *) &sin, sizeof (sin));
sin.sin_family = AF_INET;
bcopy (host->h_addr, (caddr_t) & sin.sin_addr, host->h_length);
sin.sin_family = host->h_addrtype;
sin.sin_port = htons (Port);
do { /* open the socket. */
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("can't open socket");
}
if (connect(sockfd, (struct sockaddr *) & sin, sizeof (sin)) == 0) {
break;
} else {
close(sockfd);
fprintf(stderr, "Busy... Waiting for TCP port %d on printer: %s ...\n", Port, Host);
sleep(OPEN_RETRY_DELAY);
retry++;
}
} while (retry < BUSY_RETRY_LIMIT); /* block forever */
if(retry >= BUSY_RETRY_LIMIT) {
fprintf(stderr, "Can't connect to port %d on printer: %s\n", Port, Host);
exit(2);
}
}
int do_write (int fd, char *buf, int n)
{
int i;
int N;
N = n;
while (n > 0) {
if ((i = write (fd, buf, n)) < 0)
return i;
n -= i;
buf += i;
}
return N;
}
void get_page_count(void)
{
int in;
int pagecount=-1; /* # of pages printed after this run */
int pagecountCame = 0;
int eoifromprn = 0;
int pseofdone = 0;
int do_exit = 0;
fd_set rmask;
char buf[BUFSIZ];
char bufcopy[BUFSIZ+1];
char *cptr;
open_sock();
/* send PS code to print page count out to PS stdout */
do_write(sockfd, page_count_comd, strlen(page_count_comd));
while ( !pagecountCame && pseofdone < ERROR_WAIT_SEC ) {
FD_ZERO (&rmask);
FD_SET (sockfd, &rmask); /* socket */
/* Find out where input is available */
select (sockfd + 1, &rmask, 0, 0, 0);
if(FD_ISSET (sockfd, &rmask)) { /* socket has data for reading */
in = read (sockfd, buf, BUFSIZ);
switch (in) {
case -1: /* error */
perror ("read error (socket)");
do_exit = 1;
eoifromprn = 1;
break;
case 0: /* EOF */
eoifromprn = 1;
break;
default:
/* out = do_write (0, buf, in); *//* yes, we write to stdin! */
if(in > 10) {
/* needs copying because buf is not a string */
bcopy(buf, bufcopy, in);
bufcopy[in] = 0;
if( (cptr = strstr(bufcopy, "%%PageCount:")) != NULL) {
cptr = index(cptr, ':'); cptr++; /* now on space */
sscanf(cptr, "%d", &pagecount); /* got count! */
pagecountCame = 1;
}
}
break;
} /* end switch() */
} /* end if(FD_ISSET (sockfd, &rmask)) */
pseofdone++;
sleep(1);
} /* end while() for getting pagecount */
close (sockfd);
printf("%d\n", pagecount);
}
void kill_job (int signal) /* the current job has been lprm'ed */
{
if (sockfd > 0) {
/* send an interrupt character to stop the current job */
(void) write (sockfd, "\003", 1);
(void) close (sockfd);
}
exit (0);
}
int main (int argc, char **argv)
{
(void) signal (SIGINT, kill_job);
Port = DEF_PRINTER_PORT;
if(argc < 2 || argc > 3) {
fprintf(stderr, "Usage: %s printer_hostname [port#]\n", argv[0]);
fprintf(stderr, " Queries page count from a TCP/IP network PostScript printer.\n");
fprintf(stderr, " Port# defaults to 9100. Value -1 indicates error.\n");
exit(1);
}
if(argc == 3) Port = atoi(argv[2]);
strncpy(Host, argv[1], 60);
get_page_count();
exit (0);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.