1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
24
25
26 #ident "%Z%%M% %I% %E% SMI" /* from SVR4 bnu:account.c 1.3 */
27 /*
28 */
29
30 #include "uucp.h"
31 #include "log.h"
32 #include <pwd.h>
33
34 /*
35 * SYMBOL DEFINITIONS
36 */
37
38 #define FS ' ' /* Field seperator for output records. */
39 #define STD 'S' /* standard service. */
40 #define LOGCHECK { if (Collecting == FALSE) return; }
41
42 /*
43 * STRUCTURE DEFINITIONS
44 */
45
46 struct acData /* Data for construction of account record. */
47 {
48 char uid[MODSTR]; /* user id */
49 char jobID[MODSTR]; /* C. file */
50 off_t jobsize; /* Bytes transferred in a job.*/
51 char status; /* transaction status */
52 char service; /* service grade */
53 char jobgrade[MODSTR]; /* job grade */
54 char time[MODSTR]; /* date and time the job execed */
55 char origSystem[MODSTR]; /* originating system's name */
56 char origUser[MODSTR]; /* originator's login
57 name */
58 char rmtSystem[MODSTR]; /* system's name of
59 first hop */
60 char rmtUser[MODSTR]; /* user's name of first
61 hop */
62 char device[MODSTR]; /* network medium */
63 char netid[MODSTR]; /* Network ID in use */
64 char type[MODSTR]; /* type of transaction */
65 char path[BUFSIZ]; /* path of the rest of the hops */
66
67 };
68
69 /*
70 * LOCAL DATA
71 */
72
73 static int Collecting = FALSE; /* True if we are collecting
74 * data. */
75 static int LogFile = CLOSED; /* Log file file destriptor. */
76 static char LogName[] = ACCOUNT; /* Name of our log file. */
77 static char Record[LOGSIZE]; /* Place to build log records. */
78
79 static struct acData Acct; /* Accounting data. */
80
81 /*
82 * LOCAL FUNCTIONS
83 */
84
85 /* Declarations of functions: */
86
87 STATIC_FUNC void reportJob();
88
89 /*
90 * Local Function: reportJob - Write Job accounting information to Log
91 *
92 * This function writes accounting information about the current job to the log
93 * file.
94 *
95 * Parameters:
96 *
97 * none.
98 */
99
100 STATIC_FUNC void
reportJob()101 reportJob ()
102
103 {
104 static char format[] = "%s%c%s%c%ld%c%c%c%c%c%s%c%s%c%s%c(%s)%c%s%c%s%c%s%c%s%c%s%c%s%c";
105
106 register struct acData * acptr;
107
108 acptr = &Acct; /* Point to Acct data. */
109 sprintf(Record, format,
110 acptr->uid, FS,
111 acptr->jobID, FS,
112 acptr->jobsize, FS,
113 acptr->status, FS,
114 acptr->service, FS,
115 acptr->jobgrade, FS,
116 acptr->origSystem, FS,
117 acptr->origUser, FS,
118 acptr->time, FS,
119 acptr->rmtSystem, FS,
120 acptr->rmtUser, FS,
121 acptr->device, FS,
122 acptr->netid, FS,
123 acptr->type, FS,
124 acptr->path, FS);
125
126 /* Terminate the record and write it out. */
127
128 (void) strcat(Record, EOR);
129 writeLog(Record,&LogFile,LogName,&Collecting);
130 }
131
132
133 /*
134 * EXTERNAL FUNCTIONS
135 */
136
137 /*
138 * Function: acConnected - Report Connection Completion
139 *
140 * Parameters:
141 *
142 * remote - name of the remote system.
143 *
144 * device - the type of device being used for communicaitons.
145 */
146
147 void
acConnected(remote,device)148 acConnected (remote, device)
149
150 char * remote;
151 char * device;
152
153 {
154 register struct acData * acptr = &Acct;
155
156 LOGCHECK;
157 copyText(acptr->rmtSystem, sizeof(acptr->rmtSystem), remote);
158 copyText(acptr->device, sizeof(acptr->device), device);
159 acptr->service = 'S'; /* default to standard service */
160 }
161
162 /* Function: acDojob - Found Another Job
163 *
164 * acDojob is called when a new job has been found.
165 *
166 * Parameters:
167 *
168 * jobid - The name of the job that was found.
169 *
170 * system - Originating system's name.
171 *
172 * user - Originator's login name.
173 */
174
175 void
acDojob(jobid,system,user)176 acDojob(jobid, system, user)
177
178 char * jobid;
179 char * system;
180 char * user;
181
182 {
183 register struct acData * acptr = &Acct;
184
185 struct passwd *passent;
186 LOGCHECK;
187 if (strcmp(acptr->jobID,jobid) == 0)
188 return;
189 if ((*acptr->jobID != NULLCHAR) && (acptr->jobsize != 0)){
190 reportJob();
191 }
192 copyText(acptr->jobID, sizeof(acptr->jobID), jobid);
193 copyText(acptr->origSystem, sizeof(acptr->origSystem), system);
194 copyText(acptr->origUser, sizeof(acptr->origUser), user);
195 copyText(acptr->time, sizeof(acptr->time), timeStamp());
196 acptr->jobgrade[0] = jobid[strlen(jobid)-5];
197 acptr->jobgrade[1] = NULLCHAR;/* get job grade from jobid */
198 acptr->jobsize = 0;
199 while ((passent = getpwent()) != NULL){
200 if (strcmp(passent->pw_name,user) == 0){
201 sprintf(acptr->uid,"%ld",(long) passent->pw_uid);
202 break;
203 }
204 }
205 }
206
207 /* End recording the accounting log */
208
209 void
acEnd(status)210 acEnd(status)
211 char status;
212 {
213 register struct acData * acptr = &Acct;
214
215 LOGCHECK;
216 if (((*acptr->jobID != NULLCHAR) && (acptr->jobsize != 0))
217 || (status == PARTIAL)){
218 acptr->status = status;
219 reportJob();
220 }
221
222 }
223
224 /* increment job size */
225
226 void
acInc()227 acInc()
228 {
229 register struct acData * acptr = &Acct;
230
231 LOGCHECK;
232 acptr->jobsize += getfilesize();
233 }
234
235 /*
236 * Function: acInit - Initialize Accounting Package
237 *
238 * This function allows the accounting package to initialize its internal
239 * data structures. It should be called when uucico starts running on master
240 * or changes the role from slave to master, or uuxqt is invoked.
241 *
242 * Parameters:
243 *
244 * type: file transfer or remote exec.
245 */
246
247 void
acInit(type)248 acInit (type)
249 char * type;
250
251 {
252 register struct acData * acptr = &Acct;
253
254 /*
255 * Attempt to open the log file. If we can't do it, then we
256 * won't collect statistics.
257 */
258
259 if (openLog(&LogFile,LogName) == SUCCESS){
260 Collecting = TRUE;
261 acptr->service = STD; /* default to standard service */
262 acptr->status = COMPLETE; /* default to completed transfer */
263 copyText(acptr->jobgrade, sizeof(acptr->jobgrade), NOTAVAIL);
264 copyText(acptr->uid, sizeof(acptr->uid), NOTAVAIL);
265 copyText(acptr->origSystem, sizeof(acptr->origSystem), NOTAVAIL);
266 copyText(acptr->origUser, sizeof(acptr->origUser), NOTAVAIL);
267 copyText(acptr->rmtSystem, sizeof(acptr->rmtSystem), NOTAVAIL);
268 copyText(acptr->rmtUser, sizeof(acptr->rmtUser), NOTAVAIL);
269 copyText(acptr->device, sizeof(acptr->device), NOTAVAIL);
270 copyText(acptr->netid, sizeof(acptr->netid), NOTAVAIL);
271 copyText(acptr->path, sizeof(acptr->path), NOTAVAIL);
272 copyText(acptr->type, sizeof(acptr->type), type);
273 }
274 else
275 Collecting = FALSE;
276 }
277
278 /*
279 * It is called when uuxqt is running
280 *
281 * jobid - jobid after X. prefix
282 * origsys - Originating system's name.
283 * origuser - Originator's login name.
284 * connsys - local system
285 * connuser - login user
286 * cmd - command to be execed by uuxqt
287 */
288 void
acRexe(jobid,origsys,origuser,connsys,connuser,cmd)289 acRexe(jobid,origsys,origuser,connsys,connuser,cmd)
290 char * jobid;
291 char * origsys;
292 char * origuser;
293 char * connsys;
294 char * connuser;
295 char * cmd;
296 {
297 register struct acData * acptr = &Acct;
298
299 LOGCHECK;
300 copyText(acptr->jobID, sizeof(acptr->jobID), jobid);
301 copyText(acptr->origSystem, sizeof(acptr->origSystem), origsys);
302 copyText(acptr->origUser, sizeof(acptr->origUser), origuser);
303 copyText(acptr->rmtSystem, sizeof(acptr->rmtSystem), connsys);
304 copyText(acptr->rmtUser, sizeof(acptr->rmtUser), connuser);
305 copyText(acptr->path, sizeof(acptr->path), cmd);
306 copyText(acptr->time, sizeof(acptr->time), timeStamp());
307 }
308 /*
309 * It is called when the command to be execed is finished
310 *
311 * cpucycle: cpu time the command is consumed
312 */
313 void
acEndexe(cycle,status)314 acEndexe(cycle,status)
315 time_t cycle;
316 char status;
317 {
318
319 register struct acData * acptr = &Acct;
320
321 LOGCHECK;
322 acptr->jobsize = cycle;
323 acptr->status = status;
324 reportJob();
325 }
326 /*
327 * cpucycle()
328 *
329 * return cputime(utime+stime) since last time called
330 */
331 time_t
cpucycle()332 cpucycle()
333 {
334 struct tms tbuf;
335 time_t rval;
336 static time_t utime,stime; /* guaranteed 0 first time called */
337
338 times(&tbuf);
339 rval = ((tbuf.tms_utime-utime) + (tbuf.tms_stime-stime))*1000/HZ;
340 utime = tbuf.tms_utime;
341 stime = tbuf.tms_stime;
342 return(rval);
343 }
344