ftp.nice.ch/pub/next/tools/printer/JetDirectDriver.0.96.NI.bs.tar.gz#/JetDirectDriver/ps-pagecount.c

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.