1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/*
* $Id: psa.c,v 1.5 2009-10-13 22:55:37 didg Exp $
*
* Copyright (c) 1990,1995 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
*
* PostScript Accounting, psa.
*
* psa is invoked by psf, as output for a communication program. The
* communication program is expected to send a small program before and
* after each job, which causes the page count to be emitted in a well
* known format. psa reads its input, looking for page counts and other
* interesting data. Any data that it doesn't understand, it emits to
* stderr, the lpd log file. Data that it does understand may be written
* to a status file or logged. Once all input has been received, psa
* subtracts the beginning and end page counts, and log an accounting
* record in the accounting file.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main( int ac, char **av)
{
FILE *af;
char *acc, *user, *host;
char buf[ 1024 ], *p, *end;
int cc, n, ipc = -1, fpc = -1;
if ( ac != 4 ) {
fprintf( stderr, "Usage:\t%s accounting-file user host\n", av[ 0 ] );
exit( 2 );
}
acc = av[ 1 ];
user = av[ 2 ];
host = av[ 3 ];
/*
* Explain n = !n ... Is there no beauty in truth?
*/
while (( cc = read( 0, buf, sizeof( buf ))) > 0 ) {
if ( ipc < 0 && *buf == '*' ) {
/* find initial pagecount */
for ( p = buf, end = buf + cc; p < end; p++ ) {
if ( *p == '\n' || *p == '\r' ) {
break;
}
}
if ( p == end ) {
fprintf( stderr, "Can't find initial page count!\n" );
exit( 2 );
}
p++;
ipc = atoi( buf + 1 );
cc -= ( p - buf );
if ( cc != 0 ) {
bcopy( p, buf, cc );
}
} else {
/* find final pagecount */
for ( p = buf + cc - 1; p >= buf; p-- ) {
if ( *p != '\n' && *p != '\r' ) {
break;
}
}
if ( p < buf ) {
fprintf( stderr, "Can't find final page count!\n" );
exit( 2 );
}
for ( ; p >= buf; p-- ) {
if ( *p == '\n' || *p == '\r' ) {
break;
}
}
if ( p < buf ) {
p = buf;
} else {
cc -= p - buf;
p++;
}
if ( *p == '*' ) {
n = atoi( p + 1 );
#define max(x,y) ((x)>(y)?(x):(y))
fpc = max( n, fpc );
}
}
if ( cc != 0 && write( 2, buf, cc ) != cc ) {
fprintf( stderr, "write 1: 2 %p %d\n", buf, cc );
perror( "write" );
exit( 2 );
}
}
if ( cc < 0 ) {
perror( "read" );
exit( 2 );
}
if ( ipc < 0 ) {
fprintf( stderr, "Didn't find initial page count!\n" );
exit( 2 );
}
if ( fpc < 0 ) {
fprintf( stderr, "Didn't find final page count!\n" );
exit( 2 );
}
/*
* Write accounting record.
*/
if (( af = fopen( acc, "a" )) != NULL ) {
fprintf( af, "%7.2f\t%s:%s\n", (float)( fpc - ipc ), host, user );
} else {
perror( acc );
exit( 2 );
}
exit( 0 );
}
|