How do I set up postscript accounting?

How do I set up postscript accounting?

[ formerly in section 1.118 ]

/* pswrap.c

compile with: cc pswrap.c -o pswrap -lqb
(for doc on the qb library see "understanding backend routines in libqb")

BTW: The log_charge() function doesn't seem to do anything,
but log_pages() updates the accounting info.

Ephraim Vider, original author

--
Feb 10, 1993

You can set pswrap up to use either the accounting file specified in
/etc/qconfig (which means that you need to get your data from 'pac') or
you can comment out the #define WANT_PAC line and then the accounting
data will only go into the ACCTFILE.

Also modified the logging to the ASCII acctfile so that it looks more
readable.

Vince Taluskie
*/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "qprocs.h"

char *nextword (char *p);
char *skipvalue (char *p);

#define LOGDIR "/tmp"
#define ACCTFILE "/usr/adm/acct/lpr/ps-acct"
/* #define WANT_PAC 1 */ /* this define will also send accounting
info to the acctfile specified in
/etc/qconfig file. If this define is
commented out then accounting info will
only go to ACCTFILE */


char pcprog[] = "statusdict begin pagecount = end\n\x04";

char *keyw[] = {
"idle",
"busy",
"waiting",
"printing",
"initializing",
NULL
};
enum { PS_IDLE, PS_BUSY, PS_WAIT, PS_PRINT, PS_INIT, PS_UNKNOWN };

void giveup();
jmp_buf jumper;

char logfname[30];
FILE *logfile, *acctfile;

main (argc, argv)
int argc;
char *argv[];
{
char *devname;
int pagcnt, c;
int pid;
int w, status;

if (argc < 2) {
fprintf(stderr, "Usage: psbe file\n");
exit(-1);
}
if (log_init(argv[1]) < 0) {
fprintf(stderr, "log_init failed!\n");
exit(EXITBAD);
}
sprintf(logfname, "%s/%s.log", LOGDIR, get_device_name());
if ((logfile = fopen(logfname, "a")) == NULL) {
fprintf(stderr, "Can't open logfile.\n");
exit(EXITBAD);
}

if ((acctfile = fopen(ACCTFILE, "a")) == NULL) {
fprintf(stderr, "Can't open logfile.\n");
exit(EXITBAD);
}

setvbuf(logfile, NULL, _IOLBF, BUFSIZ);
setvbuf(acctfile, NULL, _IOLBF, BUFSIZ);

setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
fprintf(logfile, "start Job no. %d, queued on %s\n", get_job_number(),
get_qdate());
log_status(WAITING);
pagcnt = getpagecnt();
log_status(RUNNING);
if ((pid = fork()) < 0) {
perror("fork");
exit(EXITBAD);
}
if (pid == 0) {
argv[0] = "piobe";
execv("/usr/lpd/piobe", argv);
perror("exec");
exit(EXITBAD);
}
while ((w = wait(&status)) != pid)
if (w == -1) {
perror("wait");
exit(EXITBAD);
}
if (WEXITSTATUS(status) != 0)
exit(WEXITSTATUS(status));
log_status(WAITING);

if (pagcnt > 0 && (c = getpagecnt()) > 0) {
#ifdef WANT_PAC
log_pages(c - pagcnt);
#endif
}

fprintf(logfile, "end Job no. %d, queued on %s\n", get_job_number(),
get_qdate());

/* the accounting file format is

pages_printed user queue_printed_on time_queued

*/

fprintf(acctfile, "%d %35s %7s %s \n", (c - pagcnt), get_from(), get_queue_name(), get_qdate());

fclose(logfile);
fclose(acctfile);
exit(EXITOK);
}

void giveup ()
{
longjmp(jumper, 1);
}

getpagecnt ()
{
int pc = 0, pstat;
char buf[81];

if (setjmp(jumper) != 0) {
fprintf(logfile, "giving up on status\n");
return (0);
}
alarm(60 * 2);
signal(SIGALRM, giveup);
do {
if (!gets(buf)) {
sleep(5);
putchar('\x14'); /* ^T returns status */
sleep(1); /* wait for answer from printer */
if (!gets(buf))
return (0);
}
fprintf(logfile, "%s\n", buf);
if ((pstat = getstatus(buf)) == PS_WAIT) {
putchar('\x04');
sleep(1);
}
} while (pstat != PS_IDLE);
alarm(0);
while (gets(buf))
fprintf(logfile, "%s\n", buf);
printf("%s", pcprog);
sleep(1); /* wait for answer from printer */
if (!gets(buf))
return (0);
if (sscanf(buf, "%d", &pc) != 1)
return (0);
fprintf(logfile, "%d\n", pc);
return (pc);
}

/*
* Parser for printer status messages
*/

getstatus (p)
char *p;
{
char *t;
int i;

if ((p = strchr(p, '%')) == NULL)
return (PS_UNKNOWN);
if (strncmp(p, "%%[", 3) != 0)
return (PS_UNKNOWN);
for (p = nextword(p + 3) ; p != NULL ; p = skipvalue(p)) {
t = p;
p = strchr(p, ':');
*p++ = '\0';
p = nextword(p);
if (strcmp(t, "status") == 0)
break;
}
if (p == NULL)
return (PS_UNKNOWN);
t = p;
p = strchr(p, ' ');
if (p[-1] == ';')
p--;
*p = '\0';
for (i = 0 ; keyw[i] != NULL ; i++)
if (strcmp(t, keyw[i]) == 0)
break;
return (i);
}

char *nextword (p)
char *p;
{
while (isspace(*p))
p++;
if (strncmp(p, "]%%", 3) == 0)
return (NULL);
return (p);
}

char *skipvalue (p)
char *p;
{
char *t;

while (p != NULL) {
p = strchr(p, ' ');
t = p;
p = nextword(p);
if (t[-1] == ';')
break;
}
return (p);
}

/********* qprocs.h ***********/
/* functions for communication between qdaemon and the backend */

char *get_from();
char *get_to();
char *get_qdate();
char *get_queue_name();
char *get_device_name();
char *get_title();




Home FAQ