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