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.