1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * This module is intended to collect performance statistics about the 34*7c478bd9Sstevel@tonic-gate * operation of uucico. All instances of uucico will write their log 35*7c478bd9Sstevel@tonic-gate * entries to the files who's path is defined by PERFLOG. Statistics 36*7c478bd9Sstevel@tonic-gate * will only be collected if PERFLOG exists when uucico starts, it will 37*7c478bd9Sstevel@tonic-gate * not be created automatically. This gives the SA an easy way to turn 38*7c478bd9Sstevel@tonic-gate * statistics collection on or off at run time. Three types 39*7c478bd9Sstevel@tonic-gate * of records will be written to the file, and each record will be 40*7c478bd9Sstevel@tonic-gate * identified by a mnemonic type at the begining of the record. The record 41*7c478bd9Sstevel@tonic-gate * types are as follows: 42*7c478bd9Sstevel@tonic-gate * 43*7c478bd9Sstevel@tonic-gate * conn - Contains statistics about the establishment of 44*7c478bd9Sstevel@tonic-gate * a connection. 45*7c478bd9Sstevel@tonic-gate * 46*7c478bd9Sstevel@tonic-gate * xfer - Contains statistics about a file transfer. 47*7c478bd9Sstevel@tonic-gate * 48*7c478bd9Sstevel@tonic-gate * The intention is to use grep to select the conn and xfer records and put 49*7c478bd9Sstevel@tonic-gate * them in two Unity data bases. No attempt will be made to process the 50*7c478bd9Sstevel@tonic-gate * error records with Unity. 51*7c478bd9Sstevel@tonic-gate * 52*7c478bd9Sstevel@tonic-gate * Both the conn and the xfer records will contain a time stamp field. 53*7c478bd9Sstevel@tonic-gate * This field will be written in case there is a desire to do time of 54*7c478bd9Sstevel@tonic-gate * day traffic studies. The time that will be written will be GMT 55*7c478bd9Sstevel@tonic-gate * to avoid the vagaries of time zone setting for uucico. The time 56*7c478bd9Sstevel@tonic-gate * stamp will contain 12 digits of the form YYMMDDhhmmss. This allows 57*7c478bd9Sstevel@tonic-gate * proper sorting by time, and the fixed length field type of Unity 58*7c478bd9Sstevel@tonic-gate * can be used to pick it apart if necessary. The time stamp is the 59*7c478bd9Sstevel@tonic-gate * time that the record is written. 60*7c478bd9Sstevel@tonic-gate * 61*7c478bd9Sstevel@tonic-gate * Statistics will be collected on the wall clock (real) time to perform 62*7c478bd9Sstevel@tonic-gate * an action and CPU consumption to perform an action. These times will 63*7c478bd9Sstevel@tonic-gate * be written in seconds and fractions of a second to two decimal places. 64*7c478bd9Sstevel@tonic-gate * 65*7c478bd9Sstevel@tonic-gate * The conn and xfer records will be written so that they can be processed 66*7c478bd9Sstevel@tonic-gate * with the following Unity schema (D files). For those not familiar with 67*7c478bd9Sstevel@tonic-gate * Unity, the columns are: 68*7c478bd9Sstevel@tonic-gate * 69*7c478bd9Sstevel@tonic-gate * column 1 - field name 70*7c478bd9Sstevel@tonic-gate * column 2 - field type (t=variable width) and field separator. 71*7c478bd9Sstevel@tonic-gate * column 3 - number of columns to use when printing the field 72*7c478bd9Sstevel@tonic-gate * with uprint. 73*7c478bd9Sstevel@tonic-gate * column 4 - a user friendly field name. 74*7c478bd9Sstevel@tonic-gate * 75*7c478bd9Sstevel@tonic-gate * Conn: 76*7c478bd9Sstevel@tonic-gate * 77*7c478bd9Sstevel@tonic-gate * type t| 4 record type (always conn) 78*7c478bd9Sstevel@tonic-gate * ts t| 12 time stamp 79*7c478bd9Sstevel@tonic-gate * procid t| 5 uucico's process id 80*7c478bd9Sstevel@tonic-gate * myname t| 6 name of the machine where the record is written 81*7c478bd9Sstevel@tonic-gate * role t| 1 M = master, S = slave 82*7c478bd9Sstevel@tonic-gate * remote t| 6 name of remote system 83*7c478bd9Sstevel@tonic-gate * device t| 6 name of device used for connection 84*7c478bd9Sstevel@tonic-gate * protocol t| 1 the protocal that is used for communication 85*7c478bd9Sstevel@tonic-gate * netid t| 6 physical network ID 86*7c478bd9Sstevel@tonic-gate * real t| 6 real time to connect 87*7c478bd9Sstevel@tonic-gate * user t| 6 user time to connect 88*7c478bd9Sstevel@tonic-gate * sys t\n 6 system (kernal) time to connect 89*7c478bd9Sstevel@tonic-gate * 90*7c478bd9Sstevel@tonic-gate * The timer for connection processing starts immediately after the 91*7c478bd9Sstevel@tonic-gate * command line processing is complete, and it is stopped after the 92*7c478bd9Sstevel@tonic-gate * protocol has been selected. 93*7c478bd9Sstevel@tonic-gate * 94*7c478bd9Sstevel@tonic-gate * Xfer: 95*7c478bd9Sstevel@tonic-gate * 96*7c478bd9Sstevel@tonic-gate * type t| 4 record type (always xfer) 97*7c478bd9Sstevel@tonic-gate * jobgrade t| 1 job grade ID 98*7c478bd9Sstevel@tonic-gate * ts t| 12 time stamp 99*7c478bd9Sstevel@tonic-gate * procid t| 5 uucico's process id 100*7c478bd9Sstevel@tonic-gate * myname t| 6 name of the machine where the record is written 101*7c478bd9Sstevel@tonic-gate * role t| 1 M = master, S = slave 102*7c478bd9Sstevel@tonic-gate * remote t| 6 name of remote system 103*7c478bd9Sstevel@tonic-gate * device t| 6 name of device used for connection 104*7c478bd9Sstevel@tonic-gate * protocol t| 1 the protocal that is used for communication 105*7c478bd9Sstevel@tonic-gate * netid t| 6 physical network ID 106*7c478bd9Sstevel@tonic-gate * job t| 7 name of the job. (Master only). 107*7c478bd9Sstevel@tonic-gate * inqueue t| 6 time in seconds that file was in queue (Master 108*7c478bd9Sstevel@tonic-gate * only). 109*7c478bd9Sstevel@tonic-gate * tat t| 6 turn around time in sec. (Master only). 110*7c478bd9Sstevel@tonic-gate * bytes t| 6 size of the file that was transferred 111*7c478bd9Sstevel@tonic-gate * flags t| 3 m = mail to requester on completion, 112*7c478bd9Sstevel@tonic-gate * n = notify remote user, s = write status 113*7c478bd9Sstevel@tonic-gate * file. (Master only). 114*7c478bd9Sstevel@tonic-gate * streal t| 6 real time to start up transfer (master only). 115*7c478bd9Sstevel@tonic-gate * stuser t| 6 116*7c478bd9Sstevel@tonic-gate * stsys t| 6 117*7c478bd9Sstevel@tonic-gate * xfrreal t| 6 real time to transfer file 118*7c478bd9Sstevel@tonic-gate * xfruser t| 6 119*7c478bd9Sstevel@tonic-gate * xfrsys t| 6 120*7c478bd9Sstevel@tonic-gate * trmreal t| 6 real time to terminate the transfer 121*7c478bd9Sstevel@tonic-gate * trmuser t| 6 122*7c478bd9Sstevel@tonic-gate * trmsys t| 6 123*7c478bd9Sstevel@tonic-gate * text t| 12 "PARTIAL FILE" if the data is being transmitted 124*7c478bd9Sstevel@tonic-gate * before breaking the transmission; blank if the 125*7c478bd9Sstevel@tonic-gate * partial file after the breakpoint or the whole 126*7c478bd9Sstevel@tonic-gate * file is being transmitted completely. 127*7c478bd9Sstevel@tonic-gate * 128*7c478bd9Sstevel@tonic-gate * Start up time includes the time for the master to search the queues 129*7c478bd9Sstevel@tonic-gate * for the next file, for the master and slave to exchange work vectors, 130*7c478bd9Sstevel@tonic-gate * and time to open files. It is only recorded on the master. 131*7c478bd9Sstevel@tonic-gate * Xfer times is the time to transfer the data, close the file, and 132*7c478bd9Sstevel@tonic-gate * exchange confirmation messages. Termination time is the time to send 133*7c478bd9Sstevel@tonic-gate * mail notifications and write status files. Turn around time is the 134*7c478bd9Sstevel@tonic-gate * difference between the time that the file was queued and the time that 135*7c478bd9Sstevel@tonic-gate * the final notification was sent. 136*7c478bd9Sstevel@tonic-gate */ 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate #include "uucp.h" 139*7c478bd9Sstevel@tonic-gate #include "log.h" 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate /* 142*7c478bd9Sstevel@tonic-gate * SYMBOL DEFINITIONS 143*7c478bd9Sstevel@tonic-gate */ 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate #define FS '|' /* Field seperator for output records. */ 146*7c478bd9Sstevel@tonic-gate #define LOGCHECK {if ((Initialized == FALSE) || \ 147*7c478bd9Sstevel@tonic-gate (Collecting == FALSE)) return; } 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate /* Subscripts for connection time marks: */ 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate #define CT_START 0 /* Start connection establishment. */ 152*7c478bd9Sstevel@tonic-gate #define CT_CONNECTED 1 /* Connection completed. */ 153*7c478bd9Sstevel@tonic-gate #define CT_SIZE 2 /* Number of elements in array. */ 154*7c478bd9Sstevel@tonic-gate 155*7c478bd9Sstevel@tonic-gate /* Subscripts for xfer time marks: */ 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate #define XT_LOOK 0 /* Start looking for a file (master only). */ 158*7c478bd9Sstevel@tonic-gate #define XT_FOUND 1 /* File found (master only). */ 159*7c478bd9Sstevel@tonic-gate #define XT_BEGXFER 2 /* Start of xfer of data. */ 160*7c478bd9Sstevel@tonic-gate #define XT_ENDXFER 3 /* Data xfer complete. */ 161*7c478bd9Sstevel@tonic-gate #define XT_ENDFILE 4 /* Done mailing and notifying. */ 162*7c478bd9Sstevel@tonic-gate #define XT_SIZE 5 /* Number of elements in array. */ 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate /* 165*7c478bd9Sstevel@tonic-gate * STRUCTURE DEFINITIONS 166*7c478bd9Sstevel@tonic-gate */ 167*7c478bd9Sstevel@tonic-gate 168*7c478bd9Sstevel@tonic-gate typedef struct timeUsed /* Time consummed between events. */ 169*7c478bd9Sstevel@tonic-gate { 170*7c478bd9Sstevel@tonic-gate float tu_real; /* Real time used. */ 171*7c478bd9Sstevel@tonic-gate float tu_user; /* User time used. */ 172*7c478bd9Sstevel@tonic-gate float tu_sys; /* System time used. */ 173*7c478bd9Sstevel@tonic-gate } TUSED; 174*7c478bd9Sstevel@tonic-gate 175*7c478bd9Sstevel@tonic-gate typedef struct timeMark /* Holds times for an event. */ 176*7c478bd9Sstevel@tonic-gate { 177*7c478bd9Sstevel@tonic-gate int tm_valid; /* True if data present. */ 178*7c478bd9Sstevel@tonic-gate long tm_real; /* Relative wall clock. */ 179*7c478bd9Sstevel@tonic-gate struct tms tm_cycles; /* CPU consumption. */ 180*7c478bd9Sstevel@tonic-gate } TMARK; 181*7c478bd9Sstevel@tonic-gate 182*7c478bd9Sstevel@tonic-gate struct connData /* Data for construction of conn record. */ 183*7c478bd9Sstevel@tonic-gate { 184*7c478bd9Sstevel@tonic-gate char cn_role; /* Master/slave indicator. */ 185*7c478bd9Sstevel@tonic-gate TMARK cn_times[CT_SIZE]; /* Event data. */ 186*7c478bd9Sstevel@tonic-gate }; 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate struct xferData /* Data for construction of xfer record. */ 189*7c478bd9Sstevel@tonic-gate { 190*7c478bd9Sstevel@tonic-gate char xf_role; /* Master/slave indicator. */ 191*7c478bd9Sstevel@tonic-gate char xf_direction; /* Send/receive indicator. */ 192*7c478bd9Sstevel@tonic-gate time_t xf_intoque; /* Time that file was placed 193*7c478bd9Sstevel@tonic-gate * in the queue. (master 194*7c478bd9Sstevel@tonic-gate * only). */ 195*7c478bd9Sstevel@tonic-gate long xf_deque; /* Time that file was 196*7c478bd9Sstevel@tonic-gate * dequeued. (master only)*/ 197*7c478bd9Sstevel@tonic-gate long xf_filedone; /* Time that file was 198*7c478bd9Sstevel@tonic-gate * completed. */ 199*7c478bd9Sstevel@tonic-gate char xf_jobname[MODSTR]; /* C. file (master only)*/ 200*7c478bd9Sstevel@tonic-gate char xf_jobgrade[MODSTR]; /* job grade id */ 201*7c478bd9Sstevel@tonic-gate off_t xf_bytes; /* Bytes transferred. */ 202*7c478bd9Sstevel@tonic-gate char xf_flags[MODSTR]; /* Notification flags. */ 203*7c478bd9Sstevel@tonic-gate TMARK xf_times[XT_SIZE]; /* Event data. */ 204*7c478bd9Sstevel@tonic-gate }; 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * LOCAL DATA 208*7c478bd9Sstevel@tonic-gate */ 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate static int Collecting = FALSE; /* True if we are collecting 211*7c478bd9Sstevel@tonic-gate * data. */ 212*7c478bd9Sstevel@tonic-gate static struct connData Conn = {0}; /* Connection data. */ 213*7c478bd9Sstevel@tonic-gate static char Device[MODSTR] = ""; /* Type of communication 214*7c478bd9Sstevel@tonic-gate * device. */ 215*7c478bd9Sstevel@tonic-gate static int Initialized = FALSE; /* True if we have been 216*7c478bd9Sstevel@tonic-gate * initialized. */ 217*7c478bd9Sstevel@tonic-gate static int LogFile = CLOSED; /* Log file file destriptor. */ 218*7c478bd9Sstevel@tonic-gate static char LogName[] = PERFLOG; /* Name of our log file. */ 219*7c478bd9Sstevel@tonic-gate static pid_t Procid = {0}; /* Our processid. */ 220*7c478bd9Sstevel@tonic-gate static char Record[LOGSIZE]; /* Place to build log records. */ 221*7c478bd9Sstevel@tonic-gate static char Remote[MODSTR] = ""; /* Name of the remote system. */ 222*7c478bd9Sstevel@tonic-gate static char myname[MAXBASENAME+1] = ""; /* Name of the source system 223*7c478bd9Sstevel@tonic-gate . */ 224*7c478bd9Sstevel@tonic-gate static char Protocol[MODSTR]; /* Protocol in use */ 225*7c478bd9Sstevel@tonic-gate static char Netid[MODSTR] = NOTAVAIL; /* Network ID in use */ 226*7c478bd9Sstevel@tonic-gate static struct xferData Xfer = {0}; /* Transfer data. */ 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate /* Messages: */ 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate static char Msg_badopen[] = "failed to open %s. Errno=%%d\n"; 231*7c478bd9Sstevel@tonic-gate static char Msg_opening[] = "attempting to open %s\n"; 232*7c478bd9Sstevel@tonic-gate static char Msg_write[] = "error in writing to %s. Errno=%%d.\n"; 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate /* 235*7c478bd9Sstevel@tonic-gate * LOCAL FUNCTIONS 236*7c478bd9Sstevel@tonic-gate */ 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate /* Declarations of functions: */ 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate STATIC_FUNC void grabTimes(); 241*7c478bd9Sstevel@tonic-gate STATIC_FUNC void pfloat(); 242*7c478bd9Sstevel@tonic-gate STATIC_FUNC void reportConn(); 243*7c478bd9Sstevel@tonic-gate STATIC_FUNC void reportFile(); 244*7c478bd9Sstevel@tonic-gate STATIC_FUNC void reportTimes(); 245*7c478bd9Sstevel@tonic-gate STATIC_FUNC void subTimes(); 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate /* 249*7c478bd9Sstevel@tonic-gate * Local Function: grabTimes - Get Real and CPU Times 250*7c478bd9Sstevel@tonic-gate * 251*7c478bd9Sstevel@tonic-gate * This function uses times(2) to obtain the current real time and CPU 252*7c478bd9Sstevel@tonic-gate * consumption. The time mark is also marked as valid. 253*7c478bd9Sstevel@tonic-gate * 254*7c478bd9Sstevel@tonic-gate * Parameters: 255*7c478bd9Sstevel@tonic-gate * 256*7c478bd9Sstevel@tonic-gate * markptr - Address of structure to save times. 257*7c478bd9Sstevel@tonic-gate * 258*7c478bd9Sstevel@tonic-gate * Return: 259*7c478bd9Sstevel@tonic-gate * 260*7c478bd9Sstevel@tonic-gate * none. 261*7c478bd9Sstevel@tonic-gate */ 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate STATIC_FUNC void 264*7c478bd9Sstevel@tonic-gate grabTimes (markptr) 265*7c478bd9Sstevel@tonic-gate 266*7c478bd9Sstevel@tonic-gate register TMARK * markptr; 267*7c478bd9Sstevel@tonic-gate 268*7c478bd9Sstevel@tonic-gate { 269*7c478bd9Sstevel@tonic-gate markptr->tm_real = times(&markptr->tm_cycles); 270*7c478bd9Sstevel@tonic-gate if (markptr->tm_real != FAIL) 271*7c478bd9Sstevel@tonic-gate markptr->tm_valid = TRUE; 272*7c478bd9Sstevel@tonic-gate return; 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* 277*7c478bd9Sstevel@tonic-gate * Local Function: pfloat - Print a Floating Number 278*7c478bd9Sstevel@tonic-gate * 279*7c478bd9Sstevel@tonic-gate * Format a floating point number for output to the Unity data base. 280*7c478bd9Sstevel@tonic-gate * If the number is NOTIME, "na" will be displayed instead. 281*7c478bd9Sstevel@tonic-gate * 282*7c478bd9Sstevel@tonic-gate * Parameters: 283*7c478bd9Sstevel@tonic-gate * 284*7c478bd9Sstevel@tonic-gate * dest - The result will be concatenated to this string. 285*7c478bd9Sstevel@tonic-gate * 286*7c478bd9Sstevel@tonic-gate * number - The number to be formated. 287*7c478bd9Sstevel@tonic-gate * 288*7c478bd9Sstevel@tonic-gate * sep - Field separator character. 289*7c478bd9Sstevel@tonic-gate */ 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate STATIC_FUNC void 292*7c478bd9Sstevel@tonic-gate pfloat (dest, number, sep) 293*7c478bd9Sstevel@tonic-gate 294*7c478bd9Sstevel@tonic-gate char * dest; 295*7c478bd9Sstevel@tonic-gate double number; /* float is promoted to double for args. */ 296*7c478bd9Sstevel@tonic-gate char sep; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate { 299*7c478bd9Sstevel@tonic-gate static char rformat[] = "%c%.2f"; 300*7c478bd9Sstevel@tonic-gate static char naformat[] = "%c%s"; 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate register char * cp; 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate cp = dest + strlen(dest); 305*7c478bd9Sstevel@tonic-gate if (number == (float) NOTIME) 306*7c478bd9Sstevel@tonic-gate sprintf(cp, naformat, sep, NOTAVAIL); 307*7c478bd9Sstevel@tonic-gate else 308*7c478bd9Sstevel@tonic-gate sprintf(cp, rformat, sep, number); 309*7c478bd9Sstevel@tonic-gate return; 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate /* 313*7c478bd9Sstevel@tonic-gate * Local Function: reportConn - Write Out Conn Record 314*7c478bd9Sstevel@tonic-gate * 315*7c478bd9Sstevel@tonic-gate * This function writes a conn record to the logfile. 316*7c478bd9Sstevel@tonic-gate * 317*7c478bd9Sstevel@tonic-gate * Parameters: 318*7c478bd9Sstevel@tonic-gate * 319*7c478bd9Sstevel@tonic-gate * None. 320*7c478bd9Sstevel@tonic-gate * 321*7c478bd9Sstevel@tonic-gate * Returns: 322*7c478bd9Sstevel@tonic-gate * 323*7c478bd9Sstevel@tonic-gate * None. 324*7c478bd9Sstevel@tonic-gate */ 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate STATIC_FUNC void 327*7c478bd9Sstevel@tonic-gate reportConn () 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate { 330*7c478bd9Sstevel@tonic-gate TUSED contimes; /* Times to make connection. */ 331*7c478bd9Sstevel@tonic-gate static char format[] = "%s%c%s%c%ld%c%s%c%c%c%s%c%s%c%s%c%s"; 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate sprintf(Record, format, 334*7c478bd9Sstevel@tonic-gate "conn", FS, /* record type. */ 335*7c478bd9Sstevel@tonic-gate gmt(), FS, /* current time. */ 336*7c478bd9Sstevel@tonic-gate (long) Procid, FS, /* our process id. */ 337*7c478bd9Sstevel@tonic-gate myname, FS, /* name of local system */ 338*7c478bd9Sstevel@tonic-gate Conn.cn_role, FS, /* slave or master. */ 339*7c478bd9Sstevel@tonic-gate Remote, FS, /* name of remote system. */ 340*7c478bd9Sstevel@tonic-gate Device, FS, /* device used for communication. */ 341*7c478bd9Sstevel@tonic-gate Protocol, FS, /* protocol used for comm. */ 342*7c478bd9Sstevel@tonic-gate Netid /* Network ID */ 343*7c478bd9Sstevel@tonic-gate ); 344*7c478bd9Sstevel@tonic-gate subTimes(&contimes, &Conn.cn_times[CT_CONNECTED], 345*7c478bd9Sstevel@tonic-gate &Conn.cn_times[CT_START]); 346*7c478bd9Sstevel@tonic-gate reportTimes(Record, &contimes, FS); 347*7c478bd9Sstevel@tonic-gate strcat(Record, EOR); 348*7c478bd9Sstevel@tonic-gate writeLog(Record,&LogFile,LogName,&Collecting); 349*7c478bd9Sstevel@tonic-gate return; 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * Local Function: reportFile - Write File Statistics to Log 354*7c478bd9Sstevel@tonic-gate * 355*7c478bd9Sstevel@tonic-gate * This function writes statistics about the current file to the log 356*7c478bd9Sstevel@tonic-gate * file. 357*7c478bd9Sstevel@tonic-gate * 358*7c478bd9Sstevel@tonic-gate * Parameters: 359*7c478bd9Sstevel@tonic-gate * 360*7c478bd9Sstevel@tonic-gate * none. 361*7c478bd9Sstevel@tonic-gate */ 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate STATIC_FUNC void 364*7c478bd9Sstevel@tonic-gate reportFile (breakmsg) 365*7c478bd9Sstevel@tonic-gate char * breakmsg; 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate { 368*7c478bd9Sstevel@tonic-gate /* minuend, subtrahand */ 369*7c478bd9Sstevel@tonic-gate static int drvtab[] = { 370*7c478bd9Sstevel@tonic-gate XT_FOUND, XT_LOOK, /* startup */ 371*7c478bd9Sstevel@tonic-gate XT_ENDXFER, XT_BEGXFER, /* xfer */ 372*7c478bd9Sstevel@tonic-gate XT_ENDFILE, XT_ENDXFER /* term. */ 373*7c478bd9Sstevel@tonic-gate }; 374*7c478bd9Sstevel@tonic-gate static char format1[] = "%s%c%s%c%s%c%ld%c%s%c%c%c%s%c%s%c%s%c%s%c%s"; 375*7c478bd9Sstevel@tonic-gate static char format2[] = "%c%ld%c%s"; /* Bytes & flags. */ 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate register struct xferData * xdptr; 378*7c478bd9Sstevel@tonic-gate register TMARK * tdptr; 379*7c478bd9Sstevel@tonic-gate register int i; 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate TUSED diff; /* time difference between events. */ 382*7c478bd9Sstevel@tonic-gate float inque; /* time in queue. */ 383*7c478bd9Sstevel@tonic-gate int lastbyte; /* Offset to last byte in Record. */ 384*7c478bd9Sstevel@tonic-gate char * na = NOTAVAIL; /* String to show data not available*/ 385*7c478bd9Sstevel@tonic-gate char role; /* Current master/slave status. */ 386*7c478bd9Sstevel@tonic-gate float tat; /* Turn around time. */ 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate xdptr = &Xfer; /* Point to Xfer data. */ 389*7c478bd9Sstevel@tonic-gate role = xdptr->xf_role; 390*7c478bd9Sstevel@tonic-gate sprintf(Record, format1, 391*7c478bd9Sstevel@tonic-gate "xfer", FS, /* Record type. */ 392*7c478bd9Sstevel@tonic-gate (role == MCHAR) ? xdptr->xf_jobgrade : na ,FS, /* job grade */ 393*7c478bd9Sstevel@tonic-gate gmt(), FS, /* Current time. */ 394*7c478bd9Sstevel@tonic-gate (long) Procid, FS, /* Our process id. */ 395*7c478bd9Sstevel@tonic-gate myname, FS, /* name of local system */ 396*7c478bd9Sstevel@tonic-gate role, FS, /* master/slave. */ 397*7c478bd9Sstevel@tonic-gate Remote, FS, /* remote. */ 398*7c478bd9Sstevel@tonic-gate Device, FS, /* communications device. */ 399*7c478bd9Sstevel@tonic-gate Protocol, FS, /* protocol used for comm. */ 400*7c478bd9Sstevel@tonic-gate Netid, FS, /* Network ID */ 401*7c478bd9Sstevel@tonic-gate (role == MCHAR) ? xdptr->xf_jobname : na 402*7c478bd9Sstevel@tonic-gate ); 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate /* Do time in queue and turn around time. */ 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate if (role == MCHAR) 407*7c478bd9Sstevel@tonic-gate { 408*7c478bd9Sstevel@tonic-gate inque = (float) (xdptr->xf_deque - xdptr->xf_intoque); 409*7c478bd9Sstevel@tonic-gate tat = (float) (xdptr->xf_filedone - xdptr->xf_intoque); 410*7c478bd9Sstevel@tonic-gate } else 411*7c478bd9Sstevel@tonic-gate { 412*7c478bd9Sstevel@tonic-gate inque = (float) NOTIME; /* Not app. if not master. */ 413*7c478bd9Sstevel@tonic-gate tat = (float) NOTIME; 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate pfloat(Record, inque, FS); 416*7c478bd9Sstevel@tonic-gate pfloat(Record, tat, FS); 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate /* 419*7c478bd9Sstevel@tonic-gate * Report bytes transferred and notification flags. 420*7c478bd9Sstevel@tonic-gate */ 421*7c478bd9Sstevel@tonic-gate 422*7c478bd9Sstevel@tonic-gate lastbyte = strlen(Record); 423*7c478bd9Sstevel@tonic-gate (void) sprintf(Record+lastbyte, format2, 424*7c478bd9Sstevel@tonic-gate FS, getfilesize(),FS, 425*7c478bd9Sstevel@tonic-gate (role == MCHAR) ? xdptr->xf_flags : na 426*7c478bd9Sstevel@tonic-gate ); 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate /* 429*7c478bd9Sstevel@tonic-gate * Report resource consumption for file startup, file transfer, 430*7c478bd9Sstevel@tonic-gate * and file termination. This means reporting the differences 431*7c478bd9Sstevel@tonic-gate * between pairs of elements in the xf_times array of Xfer. This 432*7c478bd9Sstevel@tonic-gate * will be controled by drvtab which contains pairs of subscripts 433*7c478bd9Sstevel@tonic-gate * to designate the xf_times elements. 434*7c478bd9Sstevel@tonic-gate */ 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate tdptr = &xdptr->xf_times[0]; 437*7c478bd9Sstevel@tonic-gate for (i = 0; i < sizeof(drvtab)/(sizeof(int)); i += 2) 438*7c478bd9Sstevel@tonic-gate { 439*7c478bd9Sstevel@tonic-gate subTimes(&diff, (tdptr + drvtab[i]), (tdptr + drvtab[i+1])); 440*7c478bd9Sstevel@tonic-gate reportTimes(Record, &diff, FS); 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate /* 444*7c478bd9Sstevel@tonic-gate * write file status 445*7c478bd9Sstevel@tonic-gate */ 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate lastbyte = strlen(Record); 448*7c478bd9Sstevel@tonic-gate (void) sprintf(Record+lastbyte, "%c%s%c", 449*7c478bd9Sstevel@tonic-gate FS, (*breakmsg == NULLCHAR) ? NOTAVAIL : breakmsg, FS); 450*7c478bd9Sstevel@tonic-gate 451*7c478bd9Sstevel@tonic-gate /* Terminate the record and write it out. */ 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate (void) strcat(Record, EOR); 454*7c478bd9Sstevel@tonic-gate writeLog(Record,&LogFile,LogName,&Collecting); 455*7c478bd9Sstevel@tonic-gate return; 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate 458*7c478bd9Sstevel@tonic-gate /* 459*7c478bd9Sstevel@tonic-gate * Local Function: reportTimes - Print Real, User, and Sys Times 460*7c478bd9Sstevel@tonic-gate * 461*7c478bd9Sstevel@tonic-gate * This function is used to convert the real, user, and system times from 462*7c478bd9Sstevel@tonic-gate * a TUSED structure to Ascii strings. The results are concatenated to 463*7c478bd9Sstevel@tonic-gate * the dest string. If any of the times are NOTIME, they will be reported 464*7c478bd9Sstevel@tonic-gate * as "na". The fields will be seperated by the sep character and the 465*7c478bd9Sstevel@tonic-gate * sep character will be the first character concatenated to the buffer. No 466*7c478bd9Sstevel@tonic-gate * seperator character will be placed at the end. Thus, the output string 467*7c478bd9Sstevel@tonic-gate * will be of the form: 468*7c478bd9Sstevel@tonic-gate * 469*7c478bd9Sstevel@tonic-gate * |real|user|sys 470*7c478bd9Sstevel@tonic-gate * 471*7c478bd9Sstevel@tonic-gate * Parameters: 472*7c478bd9Sstevel@tonic-gate * 473*7c478bd9Sstevel@tonic-gate * dest - String to receive Ascii times. 474*7c478bd9Sstevel@tonic-gate * 475*7c478bd9Sstevel@tonic-gate * diffptr - Address of the time data. 476*7c478bd9Sstevel@tonic-gate * 477*7c478bd9Sstevel@tonic-gate * sep - The field seperator character. 478*7c478bd9Sstevel@tonic-gate */ 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate STATIC_FUNC void 481*7c478bd9Sstevel@tonic-gate reportTimes (dest, diffptr, sep) 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate register char * dest; 484*7c478bd9Sstevel@tonic-gate register TUSED * diffptr; 485*7c478bd9Sstevel@tonic-gate char sep; 486*7c478bd9Sstevel@tonic-gate 487*7c478bd9Sstevel@tonic-gate { 488*7c478bd9Sstevel@tonic-gate pfloat(dest, diffptr->tu_real, sep); 489*7c478bd9Sstevel@tonic-gate pfloat(dest, diffptr->tu_user, sep); 490*7c478bd9Sstevel@tonic-gate pfloat(dest, diffptr->tu_sys, sep); 491*7c478bd9Sstevel@tonic-gate return; 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate /* 495*7c478bd9Sstevel@tonic-gate * Local Function: subTimes - Subtract Times Between Events 496*7c478bd9Sstevel@tonic-gate * 497*7c478bd9Sstevel@tonic-gate * This function takes the output from two calls to times(2) in the form 498*7c478bd9Sstevel@tonic-gate * of two TMARK structures, and determines the amount of time consummed 499*7c478bd9Sstevel@tonic-gate * for various categories. The result is stored in the specified 500*7c478bd9Sstevel@tonic-gate * TUSED structure. 501*7c478bd9Sstevel@tonic-gate * 502*7c478bd9Sstevel@tonic-gate * Parameters: 503*7c478bd9Sstevel@tonic-gate * 504*7c478bd9Sstevel@tonic-gate * diff - Place to store the result of the subtraction. 505*7c478bd9Sstevel@tonic-gate * minuend - The second time event. 506*7c478bd9Sstevel@tonic-gate * subtra - The subtrahend in the subtraction. This should 507*7c478bd9Sstevel@tonic-gate * be the first of two time events. 508*7c478bd9Sstevel@tonic-gate * 509*7c478bd9Sstevel@tonic-gate * On the large scale this function does the following: 510*7c478bd9Sstevel@tonic-gate * 511*7c478bd9Sstevel@tonic-gate * diff = minuend - subtra 512*7c478bd9Sstevel@tonic-gate */ 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate STATIC_FUNC void 515*7c478bd9Sstevel@tonic-gate subTimes (diff, minuend, subtra) 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate register TUSED * diff; 518*7c478bd9Sstevel@tonic-gate register TMARK * minuend; 519*7c478bd9Sstevel@tonic-gate register TMARK * subtra; 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate { 522*7c478bd9Sstevel@tonic-gate register struct tms * mintms; 523*7c478bd9Sstevel@tonic-gate register struct tms * subtms; 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate long ltemp; /* Temporary storage for long arith. */ 526*7c478bd9Sstevel@tonic-gate float ticks; /* Clock interrupts per second. */ 527*7c478bd9Sstevel@tonic-gate 528*7c478bd9Sstevel@tonic-gate if ((minuend->tm_valid != TRUE) || (subtra->tm_valid != TRUE)) 529*7c478bd9Sstevel@tonic-gate { /* If data has not been collected. */ 530*7c478bd9Sstevel@tonic-gate diff->tu_real = NOTIME; 531*7c478bd9Sstevel@tonic-gate diff->tu_user = NOTIME; 532*7c478bd9Sstevel@tonic-gate diff->tu_sys = NOTIME; 533*7c478bd9Sstevel@tonic-gate } else 534*7c478bd9Sstevel@tonic-gate { 535*7c478bd9Sstevel@tonic-gate ticks = (float) HZ; /* HZ defined in <sys/param.h>. */ 536*7c478bd9Sstevel@tonic-gate mintms = &minuend->tm_cycles; 537*7c478bd9Sstevel@tonic-gate subtms = &subtra->tm_cycles; 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate /* Calculate real time. */ 540*7c478bd9Sstevel@tonic-gate 541*7c478bd9Sstevel@tonic-gate ltemp = minuend->tm_real - subtra->tm_real; 542*7c478bd9Sstevel@tonic-gate diff->tu_real = ((float) ltemp)/ticks; 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate /* Calculate user time. */ 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate ltemp = mintms->tms_utime 547*7c478bd9Sstevel@tonic-gate - subtms->tms_utime 548*7c478bd9Sstevel@tonic-gate + mintms->tms_cutime 549*7c478bd9Sstevel@tonic-gate - subtms->tms_cutime; 550*7c478bd9Sstevel@tonic-gate diff->tu_user = ((float) ltemp)/ticks; 551*7c478bd9Sstevel@tonic-gate 552*7c478bd9Sstevel@tonic-gate /* Calculate user time. */ 553*7c478bd9Sstevel@tonic-gate 554*7c478bd9Sstevel@tonic-gate ltemp = mintms->tms_stime 555*7c478bd9Sstevel@tonic-gate - subtms->tms_stime 556*7c478bd9Sstevel@tonic-gate + mintms->tms_cstime 557*7c478bd9Sstevel@tonic-gate - subtms->tms_cstime; 558*7c478bd9Sstevel@tonic-gate diff->tu_sys = ((float) ltemp)/ticks; 559*7c478bd9Sstevel@tonic-gate } 560*7c478bd9Sstevel@tonic-gate return; 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate 563*7c478bd9Sstevel@tonic-gate /* 564*7c478bd9Sstevel@tonic-gate * EXTERNAL FUNCTIONS 565*7c478bd9Sstevel@tonic-gate */ 566*7c478bd9Sstevel@tonic-gate 567*7c478bd9Sstevel@tonic-gate /* 568*7c478bd9Sstevel@tonic-gate * Function: gmt - Generate Current Time String 569*7c478bd9Sstevel@tonic-gate * 570*7c478bd9Sstevel@tonic-gate * This function returns the address a string containing the current 571*7c478bd9Sstevel@tonic-gate * GMT in the form YYMMDDhhmmss. 572*7c478bd9Sstevel@tonic-gate * 573*7c478bd9Sstevel@tonic-gate * Parameters: 574*7c478bd9Sstevel@tonic-gate * 575*7c478bd9Sstevel@tonic-gate * none 576*7c478bd9Sstevel@tonic-gate * 577*7c478bd9Sstevel@tonic-gate * Return: 578*7c478bd9Sstevel@tonic-gate * 579*7c478bd9Sstevel@tonic-gate * An address of a static character array containing the date. 580*7c478bd9Sstevel@tonic-gate */ 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate char * 583*7c478bd9Sstevel@tonic-gate gmt() 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate { 586*7c478bd9Sstevel@tonic-gate static char date[] = "YYMMDDhhmmss"; 587*7c478bd9Sstevel@tonic-gate 588*7c478bd9Sstevel@tonic-gate register struct tm * td; 589*7c478bd9Sstevel@tonic-gate time_t now; /* Current time. */ 590*7c478bd9Sstevel@tonic-gate 591*7c478bd9Sstevel@tonic-gate now = time((time_t *) 0); 592*7c478bd9Sstevel@tonic-gate td = gmtime(&now); 593*7c478bd9Sstevel@tonic-gate (void) sprintf(date, "%02d%02d%02d%02d%02d%02d", 594*7c478bd9Sstevel@tonic-gate (td->tm_year % 100), 595*7c478bd9Sstevel@tonic-gate td->tm_mon + 1, 596*7c478bd9Sstevel@tonic-gate td->tm_mday, 597*7c478bd9Sstevel@tonic-gate td->tm_hour, 598*7c478bd9Sstevel@tonic-gate td->tm_min, 599*7c478bd9Sstevel@tonic-gate td->tm_sec 600*7c478bd9Sstevel@tonic-gate ); 601*7c478bd9Sstevel@tonic-gate return date; 602*7c478bd9Sstevel@tonic-gate } 603*7c478bd9Sstevel@tonic-gate 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate /* 606*7c478bd9Sstevel@tonic-gate * Function: writeLog - Write String to Log File 607*7c478bd9Sstevel@tonic-gate * 608*7c478bd9Sstevel@tonic-gate * After insuring that the log file is open, this function will write 609*7c478bd9Sstevel@tonic-gate * the specified string to the log file. If a write error occurs, 610*7c478bd9Sstevel@tonic-gate * statistics collection will be disabled. 611*7c478bd9Sstevel@tonic-gate * 612*7c478bd9Sstevel@tonic-gate * Parameters: 613*7c478bd9Sstevel@tonic-gate * 614*7c478bd9Sstevel@tonic-gate * string - Null terminated string to be written out. 615*7c478bd9Sstevel@tonic-gate * logfile - file descripter 616*7c478bd9Sstevel@tonic-gate * logname - name of log file. 617*7c478bd9Sstevel@tonic-gate * collecting - log enable/disable 618*7c478bd9Sstevel@tonic-gate */ 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate void 621*7c478bd9Sstevel@tonic-gate writeLog (string, logfile, logname, collecting) 622*7c478bd9Sstevel@tonic-gate 623*7c478bd9Sstevel@tonic-gate char * string; 624*7c478bd9Sstevel@tonic-gate int * logfile; 625*7c478bd9Sstevel@tonic-gate char * logname; 626*7c478bd9Sstevel@tonic-gate int * collecting; 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate { 629*7c478bd9Sstevel@tonic-gate register int length; /* Length of the string. */ 630*7c478bd9Sstevel@tonic-gate register int rv; /* Return value from write. */ 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate char errmsg[BUFSIZ]; /* Place for error messages. */ 633*7c478bd9Sstevel@tonic-gate 634*7c478bd9Sstevel@tonic-gate if (openLog(logfile,logname) != SUCCESS){ 635*7c478bd9Sstevel@tonic-gate *collecting = FALSE; 636*7c478bd9Sstevel@tonic-gate return; 637*7c478bd9Sstevel@tonic-gate } 638*7c478bd9Sstevel@tonic-gate length = strlen(string); 639*7c478bd9Sstevel@tonic-gate do 640*7c478bd9Sstevel@tonic-gate { 641*7c478bd9Sstevel@tonic-gate rv = write(*logfile, string, (unsigned) length); 642*7c478bd9Sstevel@tonic-gate } while ((rv < 0) && (errno == EINTR)); /* Retry if interrupted. */ 643*7c478bd9Sstevel@tonic-gate if (rv < length) 644*7c478bd9Sstevel@tonic-gate { /* Error or incomplete output. */ 645*7c478bd9Sstevel@tonic-gate (void) sprintf(errmsg, Msg_write, logname); 646*7c478bd9Sstevel@tonic-gate DEBUG(DB_IMPORTANT, errmsg, errno); 647*7c478bd9Sstevel@tonic-gate 648*7c478bd9Sstevel@tonic-gate /* If we had a write error, lets give up on loggine. */ 649*7c478bd9Sstevel@tonic-gate 650*7c478bd9Sstevel@tonic-gate closeLog(logfile); 651*7c478bd9Sstevel@tonic-gate *collecting = FALSE; 652*7c478bd9Sstevel@tonic-gate } 653*7c478bd9Sstevel@tonic-gate return; 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate 656*7c478bd9Sstevel@tonic-gate /* 657*7c478bd9Sstevel@tonic-gate * Function: closeLog - Close the Log File 658*7c478bd9Sstevel@tonic-gate * 659*7c478bd9Sstevel@tonic-gate * This function allows uucico to close the log file in preparation for 660*7c478bd9Sstevel@tonic-gate * forking. 661*7c478bd9Sstevel@tonic-gate * 662*7c478bd9Sstevel@tonic-gate * Parameters: 663*7c478bd9Sstevel@tonic-gate * 664*7c478bd9Sstevel@tonic-gate * log file descriptor 665*7c478bd9Sstevel@tonic-gate */ 666*7c478bd9Sstevel@tonic-gate 667*7c478bd9Sstevel@tonic-gate void 668*7c478bd9Sstevel@tonic-gate closeLog (logfile) 669*7c478bd9Sstevel@tonic-gate int *logfile; 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate { 672*7c478bd9Sstevel@tonic-gate if (*logfile != CLOSED) 673*7c478bd9Sstevel@tonic-gate { 674*7c478bd9Sstevel@tonic-gate (void) close(*logfile); 675*7c478bd9Sstevel@tonic-gate *logfile = CLOSED; 676*7c478bd9Sstevel@tonic-gate } 677*7c478bd9Sstevel@tonic-gate return; 678*7c478bd9Sstevel@tonic-gate } 679*7c478bd9Sstevel@tonic-gate 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate /* 682*7c478bd9Sstevel@tonic-gate * Function: copyText - Copy String to Dynamic Memory 683*7c478bd9Sstevel@tonic-gate * 684*7c478bd9Sstevel@tonic-gate * This function copies a string to a buffer. It insures that there is 685*7c478bd9Sstevel@tonic-gate * no overflow of the buffer and that the result is null terminated. 686*7c478bd9Sstevel@tonic-gate * 687*7c478bd9Sstevel@tonic-gate * Parameters: 688*7c478bd9Sstevel@tonic-gate * 689*7c478bd9Sstevel@tonic-gate * tptr - address of the buffer where the string is to 690*7c478bd9Sstevel@tonic-gate * be stored. 691*7c478bd9Sstevel@tonic-gate * 692*7c478bd9Sstevel@tonic-gate * size - number of bytes in the buffer. 693*7c478bd9Sstevel@tonic-gate * 694*7c478bd9Sstevel@tonic-gate * string - string to be saved. 695*7c478bd9Sstevel@tonic-gate * 696*7c478bd9Sstevel@tonic-gate * Returns: 697*7c478bd9Sstevel@tonic-gate * 698*7c478bd9Sstevel@tonic-gate * none. 699*7c478bd9Sstevel@tonic-gate */ 700*7c478bd9Sstevel@tonic-gate 701*7c478bd9Sstevel@tonic-gate void 702*7c478bd9Sstevel@tonic-gate copyText (tptr, size, string) 703*7c478bd9Sstevel@tonic-gate 704*7c478bd9Sstevel@tonic-gate register char * tptr; 705*7c478bd9Sstevel@tonic-gate register int size; 706*7c478bd9Sstevel@tonic-gate char * string; 707*7c478bd9Sstevel@tonic-gate 708*7c478bd9Sstevel@tonic-gate { 709*7c478bd9Sstevel@tonic-gate (void) strncpy(tptr, string, size); 710*7c478bd9Sstevel@tonic-gate *(tptr + size - 1) = NULLCHAR; 711*7c478bd9Sstevel@tonic-gate return; 712*7c478bd9Sstevel@tonic-gate } 713*7c478bd9Sstevel@tonic-gate 714*7c478bd9Sstevel@tonic-gate /* 715*7c478bd9Sstevel@tonic-gate * Function: pfConnected - Report Connection Completion 716*7c478bd9Sstevel@tonic-gate * 717*7c478bd9Sstevel@tonic-gate * Uucico uses pfConnected to tell this performance package that a connection 718*7c478bd9Sstevel@tonic-gate * has been established with the remote system. 719*7c478bd9Sstevel@tonic-gate * 720*7c478bd9Sstevel@tonic-gate * Parameters: 721*7c478bd9Sstevel@tonic-gate * 722*7c478bd9Sstevel@tonic-gate * remote - name of the remote system. 723*7c478bd9Sstevel@tonic-gate * 724*7c478bd9Sstevel@tonic-gate * device - the type of device being used for communicaitons. 725*7c478bd9Sstevel@tonic-gate */ 726*7c478bd9Sstevel@tonic-gate 727*7c478bd9Sstevel@tonic-gate void 728*7c478bd9Sstevel@tonic-gate pfConnected (remote, device) 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate char * remote; 731*7c478bd9Sstevel@tonic-gate char * device; 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate { 734*7c478bd9Sstevel@tonic-gate register int i; 735*7c478bd9Sstevel@tonic-gate register TMARK * tptr; 736*7c478bd9Sstevel@tonic-gate 737*7c478bd9Sstevel@tonic-gate LOGCHECK; 738*7c478bd9Sstevel@tonic-gate grabTimes(&Conn.cn_times[CT_CONNECTED]); 739*7c478bd9Sstevel@tonic-gate copyText(Remote, sizeof(Remote), remote); 740*7c478bd9Sstevel@tonic-gate copyText(Device, sizeof(Device), device); 741*7c478bd9Sstevel@tonic-gate reportConn(); 742*7c478bd9Sstevel@tonic-gate tptr = &Conn.cn_times[0]; 743*7c478bd9Sstevel@tonic-gate 744*7c478bd9Sstevel@tonic-gate /* 745*7c478bd9Sstevel@tonic-gate * Mark connection times as invalid. This is really unnecessary 746*7c478bd9Sstevel@tonic-gate * since there should only be one connection per invocation of uucico. 747*7c478bd9Sstevel@tonic-gate * We do it for consistency with use of the transfer data. 748*7c478bd9Sstevel@tonic-gate */ 749*7c478bd9Sstevel@tonic-gate 750*7c478bd9Sstevel@tonic-gate for (i = 0; i < CT_SIZE; i++, tptr++) 751*7c478bd9Sstevel@tonic-gate tptr->tm_valid = FALSE; 752*7c478bd9Sstevel@tonic-gate return; 753*7c478bd9Sstevel@tonic-gate } 754*7c478bd9Sstevel@tonic-gate 755*7c478bd9Sstevel@tonic-gate 756*7c478bd9Sstevel@tonic-gate /* 757*7c478bd9Sstevel@tonic-gate * Function: pfEndFile - Report End of File 758*7c478bd9Sstevel@tonic-gate * 759*7c478bd9Sstevel@tonic-gate * Uucico uses pfEndFile to tell our statistics collection package that 760*7c478bd9Sstevel@tonic-gate * all processing has been finished on the current file. PfEndfile should 761*7c478bd9Sstevel@tonic-gate * be called after all notifications have been done and after the status 762*7c478bd9Sstevel@tonic-gate * file has been written. PfEndfile writes out a xfer record for the 763*7c478bd9Sstevel@tonic-gate * file that just completed. 764*7c478bd9Sstevel@tonic-gate * 765*7c478bd9Sstevel@tonic-gate * Parameters: 766*7c478bd9Sstevel@tonic-gate * 767*7c478bd9Sstevel@tonic-gate * none 768*7c478bd9Sstevel@tonic-gate */ 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate void 771*7c478bd9Sstevel@tonic-gate pfEndfile (breakmsg) 772*7c478bd9Sstevel@tonic-gate char * breakmsg; 773*7c478bd9Sstevel@tonic-gate { 774*7c478bd9Sstevel@tonic-gate register int i; 775*7c478bd9Sstevel@tonic-gate register TMARK * tdptr; 776*7c478bd9Sstevel@tonic-gate register struct xferData * xptr = &Xfer; 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate LOGCHECK; 779*7c478bd9Sstevel@tonic-gate grabTimes(&Xfer.xf_times[XT_ENDFILE]); 780*7c478bd9Sstevel@tonic-gate Xfer.xf_filedone = time((time_t *) 0); 781*7c478bd9Sstevel@tonic-gate reportFile(breakmsg); 782*7c478bd9Sstevel@tonic-gate 783*7c478bd9Sstevel@tonic-gate /* Now that we have reported them, mark all times as invalid. */ 784*7c478bd9Sstevel@tonic-gate 785*7c478bd9Sstevel@tonic-gate copyText(xptr->xf_flags, sizeof(xptr->xf_flags), NOTAVAIL); 786*7c478bd9Sstevel@tonic-gate tdptr = &Xfer.xf_times[0]; 787*7c478bd9Sstevel@tonic-gate for (i = 0; i < XT_SIZE; i++, tdptr++) 788*7c478bd9Sstevel@tonic-gate tdptr->tm_valid = FALSE; 789*7c478bd9Sstevel@tonic-gate return; 790*7c478bd9Sstevel@tonic-gate } 791*7c478bd9Sstevel@tonic-gate 792*7c478bd9Sstevel@tonic-gate /* 793*7c478bd9Sstevel@tonic-gate * Function: pfEndXfer - File Transfer Complete 794*7c478bd9Sstevel@tonic-gate * 795*7c478bd9Sstevel@tonic-gate * Calling pfEndXfer tells the performance package that a file transfer 796*7c478bd9Sstevel@tonic-gate * has been completed. It should be called after the destination site 797*7c478bd9Sstevel@tonic-gate * closes the file and confirms receipt, but before notifications are done. 798*7c478bd9Sstevel@tonic-gate * 799*7c478bd9Sstevel@tonic-gate * Parameters: 800*7c478bd9Sstevel@tonic-gate * 801*7c478bd9Sstevel@tonic-gate * none 802*7c478bd9Sstevel@tonic-gate */ 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate void 805*7c478bd9Sstevel@tonic-gate pfEndXfer () 806*7c478bd9Sstevel@tonic-gate 807*7c478bd9Sstevel@tonic-gate { 808*7c478bd9Sstevel@tonic-gate LOGCHECK; 809*7c478bd9Sstevel@tonic-gate grabTimes(&Xfer.xf_times[XT_ENDXFER]); 810*7c478bd9Sstevel@tonic-gate return; 811*7c478bd9Sstevel@tonic-gate } 812*7c478bd9Sstevel@tonic-gate 813*7c478bd9Sstevel@tonic-gate /* 814*7c478bd9Sstevel@tonic-gate * Function: pfFindFile - Looking for Another File 815*7c478bd9Sstevel@tonic-gate * 816*7c478bd9Sstevel@tonic-gate * Uucico uses pfFindFile to announce that it is going to explore the 817*7c478bd9Sstevel@tonic-gate * queues for another file transfer to do. PfFindFile is only called 818*7c478bd9Sstevel@tonic-gate * when uucico is in the role of master. 819*7c478bd9Sstevel@tonic-gate * 820*7c478bd9Sstevel@tonic-gate * Parameters: 821*7c478bd9Sstevel@tonic-gate * 822*7c478bd9Sstevel@tonic-gate * none 823*7c478bd9Sstevel@tonic-gate */ 824*7c478bd9Sstevel@tonic-gate 825*7c478bd9Sstevel@tonic-gate void 826*7c478bd9Sstevel@tonic-gate pfFindFile () 827*7c478bd9Sstevel@tonic-gate 828*7c478bd9Sstevel@tonic-gate { 829*7c478bd9Sstevel@tonic-gate LOGCHECK; 830*7c478bd9Sstevel@tonic-gate grabTimes(&Xfer.xf_times[XT_LOOK]); 831*7c478bd9Sstevel@tonic-gate return; 832*7c478bd9Sstevel@tonic-gate } 833*7c478bd9Sstevel@tonic-gate 834*7c478bd9Sstevel@tonic-gate /* 835*7c478bd9Sstevel@tonic-gate * Function: pfFound - Found Another File 836*7c478bd9Sstevel@tonic-gate * 837*7c478bd9Sstevel@tonic-gate * PfFound is a counterpart of pfFindFile. It is called when a new file 838*7c478bd9Sstevel@tonic-gate * has been found. Like pfFindFile it is called only by a master uucico. 839*7c478bd9Sstevel@tonic-gate * 840*7c478bd9Sstevel@tonic-gate * Parameters: 841*7c478bd9Sstevel@tonic-gate * 842*7c478bd9Sstevel@tonic-gate * jobid - The name of the job that was found. 843*7c478bd9Sstevel@tonic-gate * 844*7c478bd9Sstevel@tonic-gate * flags - Options flags that were stored in the queue. 845*7c478bd9Sstevel@tonic-gate * These flags are originally set by uucp. 846*7c478bd9Sstevel@tonic-gate * 847*7c478bd9Sstevel@tonic-gate * intoQue - The time that the C. file was placed in the queue. 848*7c478bd9Sstevel@tonic-gate */ 849*7c478bd9Sstevel@tonic-gate 850*7c478bd9Sstevel@tonic-gate void 851*7c478bd9Sstevel@tonic-gate pfFound (jobid, flags, intoQue) 852*7c478bd9Sstevel@tonic-gate 853*7c478bd9Sstevel@tonic-gate char * jobid; 854*7c478bd9Sstevel@tonic-gate char * flags; 855*7c478bd9Sstevel@tonic-gate time_t intoQue; 856*7c478bd9Sstevel@tonic-gate 857*7c478bd9Sstevel@tonic-gate { 858*7c478bd9Sstevel@tonic-gate register struct xferData * xptr = &Xfer; 859*7c478bd9Sstevel@tonic-gate 860*7c478bd9Sstevel@tonic-gate LOGCHECK; 861*7c478bd9Sstevel@tonic-gate grabTimes(&xptr->xf_times[XT_FOUND]); 862*7c478bd9Sstevel@tonic-gate copyText(xptr->xf_jobname, sizeof(xptr->xf_jobname), jobid); 863*7c478bd9Sstevel@tonic-gate xptr->xf_jobgrade[0] = jobid[strlen(jobid)-5]; 864*7c478bd9Sstevel@tonic-gate xptr->xf_jobgrade[1] = NULLCHAR;/* get job grade from jobid */ 865*7c478bd9Sstevel@tonic-gate copyText(xptr->xf_flags, sizeof(xptr->xf_flags), flags); 866*7c478bd9Sstevel@tonic-gate 867*7c478bd9Sstevel@tonic-gate /* Save time that file was placed in queue and current time. */ 868*7c478bd9Sstevel@tonic-gate 869*7c478bd9Sstevel@tonic-gate xptr->xf_intoque = intoQue; 870*7c478bd9Sstevel@tonic-gate xptr->xf_deque = time((time_t *) 0); 871*7c478bd9Sstevel@tonic-gate return; 872*7c478bd9Sstevel@tonic-gate } 873*7c478bd9Sstevel@tonic-gate 874*7c478bd9Sstevel@tonic-gate /* 875*7c478bd9Sstevel@tonic-gate * Function: pfInit - Initialize Performance Package 876*7c478bd9Sstevel@tonic-gate * 877*7c478bd9Sstevel@tonic-gate * This function allows the performance package to initialize its internal 878*7c478bd9Sstevel@tonic-gate * data structures. It should be called one time only when uucico starts 879*7c478bd9Sstevel@tonic-gate * running. 880*7c478bd9Sstevel@tonic-gate * 881*7c478bd9Sstevel@tonic-gate * Parameters: 882*7c478bd9Sstevel@tonic-gate * 883*7c478bd9Sstevel@tonic-gate * none 884*7c478bd9Sstevel@tonic-gate */ 885*7c478bd9Sstevel@tonic-gate 886*7c478bd9Sstevel@tonic-gate void 887*7c478bd9Sstevel@tonic-gate pfInit () 888*7c478bd9Sstevel@tonic-gate 889*7c478bd9Sstevel@tonic-gate { 890*7c478bd9Sstevel@tonic-gate register struct xferData * xptr = &Xfer; 891*7c478bd9Sstevel@tonic-gate 892*7c478bd9Sstevel@tonic-gate if (Initialized == TRUE) 893*7c478bd9Sstevel@tonic-gate return; 894*7c478bd9Sstevel@tonic-gate Procid = getpid(); 895*7c478bd9Sstevel@tonic-gate myName(myname); 896*7c478bd9Sstevel@tonic-gate copyText(xptr->xf_flags, sizeof(xptr->xf_flags), NOTAVAIL); 897*7c478bd9Sstevel@tonic-gate 898*7c478bd9Sstevel@tonic-gate /* 899*7c478bd9Sstevel@tonic-gate * Attempt to open the log file. If we can't do it, then we 900*7c478bd9Sstevel@tonic-gate * won't collect statistics. 901*7c478bd9Sstevel@tonic-gate */ 902*7c478bd9Sstevel@tonic-gate 903*7c478bd9Sstevel@tonic-gate if (openLog(&LogFile,LogName) == SUCCESS) 904*7c478bd9Sstevel@tonic-gate Collecting = TRUE; 905*7c478bd9Sstevel@tonic-gate else 906*7c478bd9Sstevel@tonic-gate Collecting = FALSE; 907*7c478bd9Sstevel@tonic-gate Initialized = TRUE; 908*7c478bd9Sstevel@tonic-gate return; 909*7c478bd9Sstevel@tonic-gate } 910*7c478bd9Sstevel@tonic-gate 911*7c478bd9Sstevel@tonic-gate /* 912*7c478bd9Sstevel@tonic-gate * Function: pfStrtConn - Going to Establish Connection 913*7c478bd9Sstevel@tonic-gate * 914*7c478bd9Sstevel@tonic-gate * Uucico uses pfStrtConn to announce that it is going to attempt 915*7c478bd9Sstevel@tonic-gate * to establish a connection. 916*7c478bd9Sstevel@tonic-gate * 917*7c478bd9Sstevel@tonic-gate * Parameters: 918*7c478bd9Sstevel@tonic-gate * 919*7c478bd9Sstevel@tonic-gate * role - An indication of whether uucico is currently 920*7c478bd9Sstevel@tonic-gate * running in master or slave mode. M = master, 921*7c478bd9Sstevel@tonic-gate * S = slave. 922*7c478bd9Sstevel@tonic-gate */ 923*7c478bd9Sstevel@tonic-gate 924*7c478bd9Sstevel@tonic-gate void 925*7c478bd9Sstevel@tonic-gate pfStrtConn (role) 926*7c478bd9Sstevel@tonic-gate 927*7c478bd9Sstevel@tonic-gate char role; 928*7c478bd9Sstevel@tonic-gate { 929*7c478bd9Sstevel@tonic-gate LOGCHECK; 930*7c478bd9Sstevel@tonic-gate grabTimes(&Conn.cn_times[CT_START]); 931*7c478bd9Sstevel@tonic-gate Conn.cn_role = role; 932*7c478bd9Sstevel@tonic-gate return; 933*7c478bd9Sstevel@tonic-gate } 934*7c478bd9Sstevel@tonic-gate 935*7c478bd9Sstevel@tonic-gate /* 936*7c478bd9Sstevel@tonic-gate * Function: pfStrtXfer - Starting File Transfer 937*7c478bd9Sstevel@tonic-gate * 938*7c478bd9Sstevel@tonic-gate * This function should be called just as the first byte of data is 939*7c478bd9Sstevel@tonic-gate * about to be transferred. 940*7c478bd9Sstevel@tonic-gate * 941*7c478bd9Sstevel@tonic-gate * Parameters: 942*7c478bd9Sstevel@tonic-gate * 943*7c478bd9Sstevel@tonic-gate * role - An indication of whether uucico is currently 944*7c478bd9Sstevel@tonic-gate * running in master or slave mode. M = master, 945*7c478bd9Sstevel@tonic-gate * S = slave. 946*7c478bd9Sstevel@tonic-gate * 947*7c478bd9Sstevel@tonic-gate * direction - Direction of file transfer. S = sending to 948*7c478bd9Sstevel@tonic-gate * remote, R = receiving from remote. 949*7c478bd9Sstevel@tonic-gate */ 950*7c478bd9Sstevel@tonic-gate 951*7c478bd9Sstevel@tonic-gate void 952*7c478bd9Sstevel@tonic-gate pfStrtXfer(role, direction) 953*7c478bd9Sstevel@tonic-gate 954*7c478bd9Sstevel@tonic-gate char role; 955*7c478bd9Sstevel@tonic-gate char direction; 956*7c478bd9Sstevel@tonic-gate 957*7c478bd9Sstevel@tonic-gate { 958*7c478bd9Sstevel@tonic-gate register struct xferData * xptr = &Xfer; 959*7c478bd9Sstevel@tonic-gate 960*7c478bd9Sstevel@tonic-gate LOGCHECK; 961*7c478bd9Sstevel@tonic-gate grabTimes(&xptr->xf_times[XT_BEGXFER]); 962*7c478bd9Sstevel@tonic-gate xptr->xf_role = role; 963*7c478bd9Sstevel@tonic-gate xptr->xf_direction = direction; 964*7c478bd9Sstevel@tonic-gate return; 965*7c478bd9Sstevel@tonic-gate } 966*7c478bd9Sstevel@tonic-gate 967*7c478bd9Sstevel@tonic-gate /* 968*7c478bd9Sstevel@tonic-gate A protocol which both master and slave sides agree on 969*7c478bd9Sstevel@tonic-gate */ 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate void 972*7c478bd9Sstevel@tonic-gate pfPtcl(str) 973*7c478bd9Sstevel@tonic-gate char *str; 974*7c478bd9Sstevel@tonic-gate { 975*7c478bd9Sstevel@tonic-gate strcpy(Protocol,str); 976*7c478bd9Sstevel@tonic-gate return; 977*7c478bd9Sstevel@tonic-gate } 978*7c478bd9Sstevel@tonic-gate 979*7c478bd9Sstevel@tonic-gate /* 980*7c478bd9Sstevel@tonic-gate * Function: openLog - Open the Log File 981*7c478bd9Sstevel@tonic-gate * 982*7c478bd9Sstevel@tonic-gate * If the log file is already open this function immediately returns 983*7c478bd9Sstevel@tonic-gate * success. Otherwise, an attempt is made to open the logfile in append 984*7c478bd9Sstevel@tonic-gate * mode. 985*7c478bd9Sstevel@tonic-gate * 986*7c478bd9Sstevel@tonic-gate * Parameters: 987*7c478bd9Sstevel@tonic-gate * 988*7c478bd9Sstevel@tonic-gate * logfile - file descripter 989*7c478bd9Sstevel@tonic-gate * logname - name of log file. 990*7c478bd9Sstevel@tonic-gate * 991*7c478bd9Sstevel@tonic-gate * Returns: 992*7c478bd9Sstevel@tonic-gate * 993*7c478bd9Sstevel@tonic-gate * SUCCESS - The log file is open. 994*7c478bd9Sstevel@tonic-gate * FAIL - Unable to open logfile. 995*7c478bd9Sstevel@tonic-gate */ 996*7c478bd9Sstevel@tonic-gate 997*7c478bd9Sstevel@tonic-gate int 998*7c478bd9Sstevel@tonic-gate openLog (logfile,logname) 999*7c478bd9Sstevel@tonic-gate int *logfile; 1000*7c478bd9Sstevel@tonic-gate char *logname; 1001*7c478bd9Sstevel@tonic-gate { 1002*7c478bd9Sstevel@tonic-gate register int fd; /* File descriptor of log file. */ 1003*7c478bd9Sstevel@tonic-gate 1004*7c478bd9Sstevel@tonic-gate int level; /* Level for debug message. */ 1005*7c478bd9Sstevel@tonic-gate char msgbuf[BUFSIZ]; 1006*7c478bd9Sstevel@tonic-gate 1007*7c478bd9Sstevel@tonic-gate /* See if file already open. */ 1008*7c478bd9Sstevel@tonic-gate 1009*7c478bd9Sstevel@tonic-gate if (*logfile != CLOSED) 1010*7c478bd9Sstevel@tonic-gate return (SUCCESS); 1011*7c478bd9Sstevel@tonic-gate 1012*7c478bd9Sstevel@tonic-gate /* Attempt to open the file. */ 1013*7c478bd9Sstevel@tonic-gate 1014*7c478bd9Sstevel@tonic-gate DEBUG(DB_TRACE, Msg_opening, logname); 1015*7c478bd9Sstevel@tonic-gate do 1016*7c478bd9Sstevel@tonic-gate { 1017*7c478bd9Sstevel@tonic-gate fd = open(logname, O_WRONLY | O_APPEND); 1018*7c478bd9Sstevel@tonic-gate } while ((fd < 0) && (errno == EINTR)); /* Retry if interrupted. */ 1019*7c478bd9Sstevel@tonic-gate if (fd < 0) { /* Error on open. */ 1020*7c478bd9Sstevel@tonic-gate (void) sprintf(msgbuf, Msg_badopen, logname); 1021*7c478bd9Sstevel@tonic-gate if (errno == ENOENT) 1022*7c478bd9Sstevel@tonic-gate level = DB_DETAIL; /* If the file is not there 1023*7c478bd9Sstevel@tonic-gate * it will usually mean 1024*7c478bd9Sstevel@tonic-gate * that the SA doesn't 1025*7c478bd9Sstevel@tonic-gate * want to collect 1026*7c478bd9Sstevel@tonic-gate * statisitcs. */ 1027*7c478bd9Sstevel@tonic-gate else 1028*7c478bd9Sstevel@tonic-gate level = DB_IMPORTANT; /* Unexpected error */ 1029*7c478bd9Sstevel@tonic-gate DEBUG(level, msgbuf, errno); /* No log file. */ 1030*7c478bd9Sstevel@tonic-gate return FAIL; 1031*7c478bd9Sstevel@tonic-gate } else { 1032*7c478bd9Sstevel@tonic-gate *logfile = fd; 1033*7c478bd9Sstevel@tonic-gate return SUCCESS; 1034*7c478bd9Sstevel@tonic-gate } 1035*7c478bd9Sstevel@tonic-gate } 1036*7c478bd9Sstevel@tonic-gate 1037*7c478bd9Sstevel@tonic-gate #ifdef BSD4_2 1038*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 1039*7c478bd9Sstevel@tonic-gate #include <sys/times.h> 1040*7c478bd9Sstevel@tonic-gate #include <sys/resource.h> 1041*7c478bd9Sstevel@tonic-gate 1042*7c478bd9Sstevel@tonic-gate static clock_t 1043*7c478bd9Sstevel@tonic-gate scale60(tvp) 1044*7c478bd9Sstevel@tonic-gate register struct timeval *tvp; 1045*7c478bd9Sstevel@tonic-gate { 1046*7c478bd9Sstevel@tonic-gate return (tvp->tv_sec * 60 + tvp->tv_usec / 16667); 1047*7c478bd9Sstevel@tonic-gate } 1048*7c478bd9Sstevel@tonic-gate 1049*7c478bd9Sstevel@tonic-gate clock_t 1050*7c478bd9Sstevel@tonic-gate times(tmsp) 1051*7c478bd9Sstevel@tonic-gate register struct tms *tmsp; 1052*7c478bd9Sstevel@tonic-gate { 1053*7c478bd9Sstevel@tonic-gate struct rusage ru; 1054*7c478bd9Sstevel@tonic-gate struct timeval now; 1055*7c478bd9Sstevel@tonic-gate static time_t epoch; 1056*7c478bd9Sstevel@tonic-gate 1057*7c478bd9Sstevel@tonic-gate if (getrusage(RUSAGE_SELF, &ru) < 0) 1058*7c478bd9Sstevel@tonic-gate return (clock_t)(-1); 1059*7c478bd9Sstevel@tonic-gate tmsp->tms_utime = scale60(&ru.ru_utime); 1060*7c478bd9Sstevel@tonic-gate tmsp->tms_stime = scale60(&ru.ru_stime); 1061*7c478bd9Sstevel@tonic-gate if (getrusage(RUSAGE_CHILDREN, &ru) < 0) 1062*7c478bd9Sstevel@tonic-gate return (clock_t)(-1); 1063*7c478bd9Sstevel@tonic-gate tmsp->tms_cutime = scale60(&ru.ru_utime); 1064*7c478bd9Sstevel@tonic-gate tmsp->tms_cstime = scale60(&ru.ru_stime); 1065*7c478bd9Sstevel@tonic-gate if (gettimeofday(&now, (struct timezone *)0) < 0) 1066*7c478bd9Sstevel@tonic-gate return (clock_t)(-1); 1067*7c478bd9Sstevel@tonic-gate if (epoch == 0) 1068*7c478bd9Sstevel@tonic-gate epoch = now.tv_sec; 1069*7c478bd9Sstevel@tonic-gate now.tv_sec -= epoch; 1070*7c478bd9Sstevel@tonic-gate return (scale60(&now)); 1071*7c478bd9Sstevel@tonic-gate } 1072*7c478bd9Sstevel@tonic-gate #endif /* BSD4_2 */ 1073