BSD 4_4_Lite2 development
[unix-history] / usr / src / contrib / usr.x25 / x25sa / x25sa.c
CommitLineData
4b2bb158
C
1/*
2 * Print the kernel X.25 accounting file, in the following format:
3 * month
4 * day
5 * hour:min - call start time
6 * duration - call duration in seconds
7 * user - name of user who placed the call
8 * in/out - incoming or outgoing call flag
9 * address - X.121 address
10 * host - host name associated with address, if known
11 * rev/--- - reverse charge flag
12 * packet size - packet size in bytes
13 * user data - 4 bytes of user data (protocol),
14 * ITI calls appear as x29d, EAN 1&2 as ean1/ean2,
15 * others as 4 hex digits.
16 * packets sent
17 * packets received - number of packets sent and received.
18 *
19 * Not the nicest format for people, but it is assumed that the
20 * output will be further processed before people see it.
21 * The idea here is to convert the raw data to a form
22 * convenient for shell or awk scripts.
23 */
24#include <stdio.h>
25#include <sys/file.h>
26#include <sys/types.h>
27#include <sys/time.h>
28#include <pwd.h>
29#include <netccitt/x25.h>
30#include <netccitt/x25acct.h>
31#include <netdb.h>
32
33main(argc, argv)
34 char **argv;
35{
36 struct passwd *pw;
37 char *user, ubuf[20], *dayt, *filename;
38 FILE *fp;
39 struct x25acct ac;
40 char addr[16+1];
41 char *format_udata();
42 struct hostent *hp, *getx25hostbyaddr();
43
44 if (argc > 2) {
45 fprintf(stderr, "usage: %s [file]\n", argv[0]);
46 exit(1);
47 }
48 filename = argc == 2 ? argv[1] : X25ACCTF;
49 if ((fp = fopen(filename, "r")) == NULL) {
50 fprintf(stderr, "%s: ", argv[0]);
51 perror(filename);
52 exit(1);
53 }
54 setx25hostent(1); /* don't close after each call */
55 while (fread((char *)&ac, sizeof ac, 1, fp) == 1) {
56 if (ac.x25acct_txcnt == 0 && ac.x25acct_rxcnt == 0)
57 continue;
58 if ((pw = getpwuid(ac.x25acct_uid)) == NULL) {
59 fprintf(stderr, "%s: unknown uid: %d\n",
60 argv[0], ac.x25acct_uid);
61 sprintf(ubuf, "#%d", ac.x25acct_uid);
62 user = ubuf;
63 }
64 else
65 user = pw->pw_name;
66 dayt = ctime(&ac.x25acct_stime);
67 dayt[16] = '\0'; /* we probably know what year it is */
68 dayt += 4; /* skip the day */
69
70 if (ac.x25acct_addrlen > 16) {
71 fprintf(stderr, "%s: Invalid addrlen %d\n",
72 argv[0], ac.x25acct_addrlen);
73 continue;
74 }
75 /*
76 * Convert bcd address to ascii.
77 */
78 bzero(addr, sizeof addr);
79 from_bcd(addr, (u_char *)ac.x25acct_addr,
80 (int)ac.x25acct_addrlen);
81 hp = getx25hostbyaddr(addr);
82
83 printf("%s %4d %-8s %s %-14s %-9s %s %3d %-4s %3ld %3ld\n",
84 dayt,
85 ac.x25acct_etime,
86 user,
87 ac.x25acct_callin ? "in " : "out",
88 addr,
89 hp ? hp->h_name : addr,
90 /* REVERSE means collect (by default caller pays) */
91 ac.x25acct_revcharge ? "rev" : "---",
92 1 << ac.x25acct_psize,
93 format_udata(ac.x25acct_udata),
94 ac.x25acct_txcnt,
95 ac.x25acct_rxcnt);
96 }
97 exit(0);
98}
99
100 char *
101format_udata(udata)
102 char *udata;
103{
104 static char buf[15];
105
106 if (bcmp(udata, "\1\0\0\0", 4) == 0)
107 return "x29d";
108 if (bcmp(udata, "ean", 3) == 0)
109 return udata;
110 sprintf(buf, "%x.%x.%x.%x",
111 udata[0], udata[1], udata[2], udata[3]);
112 return buf;
113}
114
115from_bcd (a, x, len)
116 register char *a;
117 register u_char *x;
118 register int len;
119{
120 register int posn = 0;
121
122 while (--len >= 0) {
123 if (posn++ & 0x01)
124 *a = *x++ & 0x0f;
125 else
126 *a = (*x >> 4) & 0x0f;
127 *a++ |= 0x30;
128 }
129}