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
grabTimes(markptr)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
pfloat(dest,number,sep)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
reportConn()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
reportFile(breakmsg)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
reportTimes(dest,diffptr,sep)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
subTimes(diff,minuend,subtra)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 *
gmt()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
writeLog(string,logfile,logname,collecting)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
closeLog(logfile)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
copyText(tptr,size,string)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
pfConnected(remote,device)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
pfEndfile(breakmsg)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
pfEndXfer()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
pfFindFile()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
pfFound(jobid,flags,intoQue)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
pfInit()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
pfStrtConn(role)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
pfStrtXfer(role,direction)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
pfPtcl(str)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
openLog(logfile,logname)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
scale60(tvp)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
times(tmsp)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