dougf.UUCP@dartvax.UUCP (Doug Fraser) (07/27/87)
$!
$! ----------------------------- Cut here ----------------------------
$!
$ write sys$output "Creating: IMAGEN_ACCT.C"
$ create IMAGEN_ACCT.C
$ deck /dollars
/*
* IMAGEN_ACCT.C
*
* Reads accounting packets sent by the Imagen 3320 laser printer via
* TCP/IP and writes relevant information into a DCL compatible
* ASCII (one line per print job) accounting file.
*
* System requirements: VMS 4.5 and WIN/TCP 3.0
*
* For use on VAX/VMS with the Wallongong TCP/IP package V. 3.0.
* For this to work correctly, the string "User" in the default
* IMPRINT.FMT supplied with the Kellerman & Smith VMS/Imagen spooler
* package will have to be changed to "Owner". This will allow this
* accounting to also work with files spooled from UNIX machines using
* the Imagen spooling software. This clearly a kludge. It would be
* preferable if K&S would get together with Imagen and agree on a
* header prefix format containing username, filename, etc.
*
* 24-Jul-1987
*
* Doug Fraser
* Thayer School of Engineering, Dartmouth College, Hanover, NH. 03755
* dougf%thayer@dartmouth.EDU
*/
#include dvidef
#include <sys/types.h>
#include <sys/netdb.h>
#include <iodef.h>
#include <stdio.h>
#include <sys/socket.h>
#include <time>
#define PORT_IMAGEN_ACCT 36
#define INADDR_ANY (u_long)0x00000000
#define DATA_FILE_NAME "DUA0:[SYS0.SYSMGR.BILLING]imagen_acct.dat"
int chan;
main (argc, argv)
int argc;
char *argv[];
{
int status, i, len, time_val;
char *ptr, *tmp_ptr, printer[32], source[32], user[32];
FILE *data_file;
struct tm *time_structure;
struct hostent *host_ptr; /* hostname lookup */
struct acct_header { /* Imagen accounting header */
unsigned long noonce; /* Job ID */
unsigned long source; /* Source */
unsigned long npages; /* Number of pages */
unsigned char data[256]; /* ASCII Header contents */
} acct_data, *pkt_ptr;
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
unsigned long sin_addr;
char sin_zero[8];
} sin, remote;
static char *month[12] =
{"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
/* Start here */
sin.sin_port = htons(PORT_IMAGEN_ACCT);
sin.sin_addr = INADDR_ANY;
sin.sin_family = AF_INET;
/* Connect to the network */
chan = socket(AF_INET, SOCK_DGRAM, 0);
if (chan == -1){
printf ("Imagen_acct: Socket connect failed");
exit(1);
}
status = bind(chan, &sin, sizeof(sin));
if (status == -1)
errormsg("Imagen_acct: Bind failed");
/*
* Do the following forever.
*/
while(1) {
len = sizeof(remote);
pkt_ptr = (struct acct_hdr *)&acct_data;
/* Get packet */
status = recvfrom(chan, pkt_ptr, sizeof(*pkt_ptr),0,
(struct sock_addr *)&remote, &len);
if (status == -1)
errormsg ("Imagen_acct: Receive failed");
/* Get time */
time (&time_val);
time_structure = localtime(&time_val);
/* Get printer name */
if ((host_ptr = gethostbyaddr(&remote.sin_addr,
sizeof(remote.sin_addr), AF_INET)) == NULL)
strcpy(printer, "<unknown>");
else
strcpy(printer, host_ptr->h_name);
/* Get host name */
if ((host_ptr = gethostbyaddr(&acct_data.source,
sizeof(acct_data.source), AF_INET)) == NULL)
strcpy(source, "<unknown>");
else
strcpy(source, host_ptr->h_name);
/* Get user name */
ptr = &acct_data.data[0];
i = sizeof (acct_data.data);
/* Look for the string "Owner" in the ASCII header sent from the Imagen.
* Note that this will probably have to changed from "User" in the file
* "sys$manager:IMPRINT.FMT"
*/
while ((--i >= 0) && (strncmp (ptr, "Owner", 5) != NULL))
ptr++;
while ((--i >= 0) && (*ptr != '"'))
ptr++;
ptr++;
tmp_ptr = (char *)ptr;
while (( --i >= 0) && (*ptr != ' '))
ptr++;
*ptr = 0x00;
if (i < 0)
strcpy(user, "<unknown>");
else
strcpy (user, tmp_ptr);
/* Write it all into the accounting file */
if ((data_file = fopen(DATA_FILE_NAME, "a")) == NULL)
errormsg ("Imagen_acct: File open failed");
fprintf (data_file,
"%02d-%s-19%02d %02d:%02d:%02d %-15.14s%-13.12s%-13.12s %4d\n",
time_structure->tm_mday,
month[time_structure->tm_mon],
time_structure->tm_year,
time_structure->tm_hour,
time_structure->tm_min,
time_structure->tm_sec, /* Time in DCL format */
printer, /* Printer name */
source, /* Source of print job */
user, /* User name */
ntohl(acct_data.npages)-1); /* Subtract 1 for the header page. */
/* Another bogus maneuver since */
/* there could be several or none.*/
/* The following writes the entire ASCII header into the data file
* for diagnostic purposes.
*
* ptr = &acct_data.data[0];
*
* fwrite (ptr, status-24, 1, data_file);
* fputs ("\n --------------- \n", data_file);
*/
fclose(data_file);
}
netclose(chan);
exit (0);
}
errormsg(msg)
char *msg;
{
printf("%s\n", msg);
netclose (chan);
exit (1);
}
$ EOD
$!
$ write sys$output "Creating: BUILD.COM"
$ create BUILD.COM
$ deck/dollars
$!
$! BUILD.COM
$!
$ set verify
$!
$ define /job lnk$library sys$library:vaxcrtl.olb
$!
$! Define the locations of the Wallongong TCP include files below
$!
$ define /job sys dua0:[netdist.include.sys]
$ define /job netinet dua0:[netdist.include.netinet]
$!
$ cc /list imagen_acct
$!
$ link imagen_acct,dua0:[netdist.lib]libnet/lib,libnetacc/lib,libnet/lib
$!
$ copy imagen_acct.exe sys$manager:*
$!
$! The following should go in your sys$manager:systartup.com
$! after TCP/IP and IMPRINT have been started
$!
$! run/det/proc=imagen_acct/uic=[1,4]/prio=6 sys$manager:imagen_acct
$!
$ set noverify
$ EOD
$ write sys$output "Done..."
$ write sys$output "Modify the system dependent sections of both files,"
$ write sys$output "and execute BUILD.COM."
$ exit
$!-----------------------------------------------------------------------