xref: /illumos-gate/usr/src/cmd/bnu/perfstat.c (revision 7c478bd9)
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