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 $!-----------------------------------------------------------------------