Parent document is top of "comp.unix.aix Frequently Asked Questions (Part 5 of 5)"
Previous document is "6.11: How can I access the comp.unix.aix newsgroup via email (or Web)?"
Next document is "8.04: How can I find out the machine type?"
8.03: 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 <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/wait.h>
#include <IN/backend.h>
#include <IN/standard.h>
#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();
Parent document is top of "comp.unix.aix Frequently Asked Questions (Part 5 of 5)"
Previous document is "6.11: How can I access the comp.unix.aix newsgroup via email (or Web)?"
Next document is "8.04: How can I find out the machine type?"