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