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