8349 thrd_equal implements the wrong specification
[unleashed.git] / usr / src / cmd / bnu / perfstat.c
blobd705796bb130007cf5bf515a1249002810080f1e
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 1997 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
33 * This module is intended to collect performance statistics about the
34 * operation of uucico. All instances of uucico will write their log
35 * entries to the files who's path is defined by PERFLOG. Statistics
36 * will only be collected if PERFLOG exists when uucico starts, it will
37 * not be created automatically. This gives the SA an easy way to turn
38 * statistics collection on or off at run time. Three types
39 * of records will be written to the file, and each record will be
40 * identified by a mnemonic type at the begining of the record. The record
41 * types are as follows:
43 * conn - Contains statistics about the establishment of
44 * a connection.
46 * xfer - Contains statistics about a file transfer.
48 * The intention is to use grep to select the conn and xfer records and put
49 * them in two Unity data bases. No attempt will be made to process the
50 * error records with Unity.
52 * Both the conn and the xfer records will contain a time stamp field.
53 * This field will be written in case there is a desire to do time of
54 * day traffic studies. The time that will be written will be GMT
55 * to avoid the vagaries of time zone setting for uucico. The time
56 * stamp will contain 12 digits of the form YYMMDDhhmmss. This allows
57 * proper sorting by time, and the fixed length field type of Unity
58 * can be used to pick it apart if necessary. The time stamp is the
59 * time that the record is written.
61 * Statistics will be collected on the wall clock (real) time to perform
62 * an action and CPU consumption to perform an action. These times will
63 * be written in seconds and fractions of a second to two decimal places.
65 * The conn and xfer records will be written so that they can be processed
66 * with the following Unity schema (D files). For those not familiar with
67 * Unity, the columns are:
69 * column 1 - field name
70 * column 2 - field type (t=variable width) and field separator.
71 * column 3 - number of columns to use when printing the field
72 * with uprint.
73 * column 4 - a user friendly field name.
75 * Conn:
77 * type t| 4 record type (always conn)
78 * ts t| 12 time stamp
79 * procid t| 5 uucico's process id
80 * myname t| 6 name of the machine where the record is written
81 * role t| 1 M = master, S = slave
82 * remote t| 6 name of remote system
83 * device t| 6 name of device used for connection
84 * protocol t| 1 the protocal that is used for communication
85 * netid t| 6 physical network ID
86 * real t| 6 real time to connect
87 * user t| 6 user time to connect
88 * sys t\n 6 system (kernal) time to connect
90 * The timer for connection processing starts immediately after the
91 * command line processing is complete, and it is stopped after the
92 * protocol has been selected.
94 * Xfer:
96 * type t| 4 record type (always xfer)
97 * jobgrade t| 1 job grade ID
98 * ts t| 12 time stamp
99 * procid t| 5 uucico's process id
100 * myname t| 6 name of the machine where the record is written
101 * role t| 1 M = master, S = slave
102 * remote t| 6 name of remote system
103 * device t| 6 name of device used for connection
104 * protocol t| 1 the protocal that is used for communication
105 * netid t| 6 physical network ID
106 * job t| 7 name of the job. (Master only).
107 * inqueue t| 6 time in seconds that file was in queue (Master
108 * only).
109 * tat t| 6 turn around time in sec. (Master only).
110 * bytes t| 6 size of the file that was transferred
111 * flags t| 3 m = mail to requester on completion,
112 * n = notify remote user, s = write status
113 * file. (Master only).
114 * streal t| 6 real time to start up transfer (master only).
115 * stuser t| 6
116 * stsys t| 6
117 * xfrreal t| 6 real time to transfer file
118 * xfruser t| 6
119 * xfrsys t| 6
120 * trmreal t| 6 real time to terminate the transfer
121 * trmuser t| 6
122 * trmsys t| 6
123 * text t| 12 "PARTIAL FILE" if the data is being transmitted
124 * before breaking the transmission; blank if the
125 * partial file after the breakpoint or the whole
126 * file is being transmitted completely.
128 * Start up time includes the time for the master to search the queues
129 * for the next file, for the master and slave to exchange work vectors,
130 * and time to open files. It is only recorded on the master.
131 * Xfer times is the time to transfer the data, close the file, and
132 * exchange confirmation messages. Termination time is the time to send
133 * mail notifications and write status files. Turn around time is the
134 * difference between the time that the file was queued and the time that
135 * the final notification was sent.
138 #include "uucp.h"
139 #include "log.h"
142 * SYMBOL DEFINITIONS
145 #define FS '|' /* Field seperator for output records. */
146 #define LOGCHECK {if ((Initialized == FALSE) || \
147 (Collecting == FALSE)) return; }
149 /* Subscripts for connection time marks: */
151 #define CT_START 0 /* Start connection establishment. */
152 #define CT_CONNECTED 1 /* Connection completed. */
153 #define CT_SIZE 2 /* Number of elements in array. */
155 /* Subscripts for xfer time marks: */
157 #define XT_LOOK 0 /* Start looking for a file (master only). */
158 #define XT_FOUND 1 /* File found (master only). */
159 #define XT_BEGXFER 2 /* Start of xfer of data. */
160 #define XT_ENDXFER 3 /* Data xfer complete. */
161 #define XT_ENDFILE 4 /* Done mailing and notifying. */
162 #define XT_SIZE 5 /* Number of elements in array. */
165 * STRUCTURE DEFINITIONS
168 typedef struct timeUsed /* Time consummed between events. */
170 float tu_real; /* Real time used. */
171 float tu_user; /* User time used. */
172 float tu_sys; /* System time used. */
173 } TUSED;
175 typedef struct timeMark /* Holds times for an event. */
177 int tm_valid; /* True if data present. */
178 long tm_real; /* Relative wall clock. */
179 struct tms tm_cycles; /* CPU consumption. */
180 } TMARK;
182 struct connData /* Data for construction of conn record. */
184 char cn_role; /* Master/slave indicator. */
185 TMARK cn_times[CT_SIZE]; /* Event data. */
188 struct xferData /* Data for construction of xfer record. */
190 char xf_role; /* Master/slave indicator. */
191 char xf_direction; /* Send/receive indicator. */
192 time_t xf_intoque; /* Time that file was placed
193 * in the queue. (master
194 * only). */
195 long xf_deque; /* Time that file was
196 * dequeued. (master only)*/
197 long xf_filedone; /* Time that file was
198 * completed. */
199 char xf_jobname[MODSTR]; /* C. file (master only)*/
200 char xf_jobgrade[MODSTR]; /* job grade id */
201 off_t xf_bytes; /* Bytes transferred. */
202 char xf_flags[MODSTR]; /* Notification flags. */
203 TMARK xf_times[XT_SIZE]; /* Event data. */
207 * LOCAL DATA
210 static int Collecting = FALSE; /* True if we are collecting
211 * data. */
212 static struct connData Conn = {0}; /* Connection data. */
213 static char Device[MODSTR] = ""; /* Type of communication
214 * device. */
215 static int Initialized = FALSE; /* True if we have been
216 * initialized. */
217 static int LogFile = CLOSED; /* Log file file destriptor. */
218 static char LogName[] = PERFLOG; /* Name of our log file. */
219 static pid_t Procid = {0}; /* Our processid. */
220 static char Record[LOGSIZE]; /* Place to build log records. */
221 static char Remote[MODSTR] = ""; /* Name of the remote system. */
222 static char myname[MAXBASENAME+1] = ""; /* Name of the source system
223 . */
224 static char Protocol[MODSTR]; /* Protocol in use */
225 static char Netid[MODSTR] = NOTAVAIL; /* Network ID in use */
226 static struct xferData Xfer = {0}; /* Transfer data. */
228 /* Messages: */
230 static char Msg_badopen[] = "failed to open %s. Errno=%%d\n";
231 static char Msg_opening[] = "attempting to open %s\n";
232 static char Msg_write[] = "error in writing to %s. Errno=%%d.\n";
235 * LOCAL FUNCTIONS
238 /* Declarations of functions: */
240 STATIC_FUNC void grabTimes();
241 STATIC_FUNC void pfloat();
242 STATIC_FUNC void reportConn();
243 STATIC_FUNC void reportFile();
244 STATIC_FUNC void reportTimes();
245 STATIC_FUNC void subTimes();
249 * Local Function: grabTimes - Get Real and CPU Times
251 * This function uses times(2) to obtain the current real time and CPU
252 * consumption. The time mark is also marked as valid.
254 * Parameters:
256 * markptr - Address of structure to save times.
258 * Return:
260 * none.
263 STATIC_FUNC void
264 grabTimes (markptr)
266 register TMARK * markptr;
269 markptr->tm_real = times(&markptr->tm_cycles);
270 if (markptr->tm_real != FAIL)
271 markptr->tm_valid = TRUE;
272 return;
277 * Local Function: pfloat - Print a Floating Number
279 * Format a floating point number for output to the Unity data base.
280 * If the number is NOTIME, "na" will be displayed instead.
282 * Parameters:
284 * dest - The result will be concatenated to this string.
286 * number - The number to be formated.
288 * sep - Field separator character.
291 STATIC_FUNC void
292 pfloat (dest, number, sep)
294 char * dest;
295 double number; /* float is promoted to double for args. */
296 char sep;
299 static char rformat[] = "%c%.2f";
300 static char naformat[] = "%c%s";
302 register char * cp;
304 cp = dest + strlen(dest);
305 if (number == (float) NOTIME)
306 sprintf(cp, naformat, sep, NOTAVAIL);
307 else
308 sprintf(cp, rformat, sep, number);
309 return;
313 * Local Function: reportConn - Write Out Conn Record
315 * This function writes a conn record to the logfile.
317 * Parameters:
319 * None.
321 * Returns:
323 * None.
326 STATIC_FUNC void
327 reportConn ()
330 TUSED contimes; /* Times to make connection. */
331 static char format[] = "%s%c%s%c%ld%c%s%c%c%c%s%c%s%c%s%c%s";
333 sprintf(Record, format,
334 "conn", FS, /* record type. */
335 gmt(), FS, /* current time. */
336 (long) Procid, FS, /* our process id. */
337 myname, FS, /* name of local system */
338 Conn.cn_role, FS, /* slave or master. */
339 Remote, FS, /* name of remote system. */
340 Device, FS, /* device used for communication. */
341 Protocol, FS, /* protocol used for comm. */
342 Netid /* Network ID */
344 subTimes(&contimes, &Conn.cn_times[CT_CONNECTED],
345 &Conn.cn_times[CT_START]);
346 reportTimes(Record, &contimes, FS);
347 strcat(Record, EOR);
348 writeLog(Record,&LogFile,LogName,&Collecting);
349 return;
353 * Local Function: reportFile - Write File Statistics to Log
355 * This function writes statistics about the current file to the log
356 * file.
358 * Parameters:
360 * none.
363 STATIC_FUNC void
364 reportFile (breakmsg)
365 char * breakmsg;
368 /* minuend, subtrahand */
369 static int drvtab[] = {
370 XT_FOUND, XT_LOOK, /* startup */
371 XT_ENDXFER, XT_BEGXFER, /* xfer */
372 XT_ENDFILE, XT_ENDXFER /* term. */
374 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 static char format2[] = "%c%ld%c%s"; /* Bytes & flags. */
377 register struct xferData * xdptr;
378 register TMARK * tdptr;
379 register int i;
381 TUSED diff; /* time difference between events. */
382 float inque; /* time in queue. */
383 int lastbyte; /* Offset to last byte in Record. */
384 char * na = NOTAVAIL; /* String to show data not available*/
385 char role; /* Current master/slave status. */
386 float tat; /* Turn around time. */
388 xdptr = &Xfer; /* Point to Xfer data. */
389 role = xdptr->xf_role;
390 sprintf(Record, format1,
391 "xfer", FS, /* Record type. */
392 (role == MCHAR) ? xdptr->xf_jobgrade : na ,FS, /* job grade */
393 gmt(), FS, /* Current time. */
394 (long) Procid, FS, /* Our process id. */
395 myname, FS, /* name of local system */
396 role, FS, /* master/slave. */
397 Remote, FS, /* remote. */
398 Device, FS, /* communications device. */
399 Protocol, FS, /* protocol used for comm. */
400 Netid, FS, /* Network ID */
401 (role == MCHAR) ? xdptr->xf_jobname : na
404 /* Do time in queue and turn around time. */
406 if (role == MCHAR)
408 inque = (float) (xdptr->xf_deque - xdptr->xf_intoque);
409 tat = (float) (xdptr->xf_filedone - xdptr->xf_intoque);
410 } else
412 inque = (float) NOTIME; /* Not app. if not master. */
413 tat = (float) NOTIME;
415 pfloat(Record, inque, FS);
416 pfloat(Record, tat, FS);
419 * Report bytes transferred and notification flags.
422 lastbyte = strlen(Record);
423 (void) sprintf(Record+lastbyte, format2,
424 FS, getfilesize(),FS,
425 (role == MCHAR) ? xdptr->xf_flags : na
429 * Report resource consumption for file startup, file transfer,
430 * and file termination. This means reporting the differences
431 * between pairs of elements in the xf_times array of Xfer. This
432 * will be controled by drvtab which contains pairs of subscripts
433 * to designate the xf_times elements.
436 tdptr = &xdptr->xf_times[0];
437 for (i = 0; i < sizeof(drvtab)/(sizeof(int)); i += 2)
439 subTimes(&diff, (tdptr + drvtab[i]), (tdptr + drvtab[i+1]));
440 reportTimes(Record, &diff, FS);
444 * write file status
447 lastbyte = strlen(Record);
448 (void) sprintf(Record+lastbyte, "%c%s%c",
449 FS, (*breakmsg == NULLCHAR) ? NOTAVAIL : breakmsg, FS);
451 /* Terminate the record and write it out. */
453 (void) strcat(Record, EOR);
454 writeLog(Record,&LogFile,LogName,&Collecting);
455 return;
459 * Local Function: reportTimes - Print Real, User, and Sys Times
461 * This function is used to convert the real, user, and system times from
462 * a TUSED structure to Ascii strings. The results are concatenated to
463 * the dest string. If any of the times are NOTIME, they will be reported
464 * as "na". The fields will be seperated by the sep character and the
465 * sep character will be the first character concatenated to the buffer. No
466 * seperator character will be placed at the end. Thus, the output string
467 * will be of the form:
469 * |real|user|sys
471 * Parameters:
473 * dest - String to receive Ascii times.
475 * diffptr - Address of the time data.
477 * sep - The field seperator character.
480 STATIC_FUNC void
481 reportTimes (dest, diffptr, sep)
483 register char * dest;
484 register TUSED * diffptr;
485 char sep;
488 pfloat(dest, diffptr->tu_real, sep);
489 pfloat(dest, diffptr->tu_user, sep);
490 pfloat(dest, diffptr->tu_sys, sep);
491 return;
495 * Local Function: subTimes - Subtract Times Between Events
497 * This function takes the output from two calls to times(2) in the form
498 * of two TMARK structures, and determines the amount of time consummed
499 * for various categories. The result is stored in the specified
500 * TUSED structure.
502 * Parameters:
504 * diff - Place to store the result of the subtraction.
505 * minuend - The second time event.
506 * subtra - The subtrahend in the subtraction. This should
507 * be the first of two time events.
509 * On the large scale this function does the following:
511 * diff = minuend - subtra
514 STATIC_FUNC void
515 subTimes (diff, minuend, subtra)
517 register TUSED * diff;
518 register TMARK * minuend;
519 register TMARK * subtra;
522 register struct tms * mintms;
523 register struct tms * subtms;
525 long ltemp; /* Temporary storage for long arith. */
526 float ticks; /* Clock interrupts per second. */
528 if ((minuend->tm_valid != TRUE) || (subtra->tm_valid != TRUE))
529 { /* If data has not been collected. */
530 diff->tu_real = NOTIME;
531 diff->tu_user = NOTIME;
532 diff->tu_sys = NOTIME;
533 } else
535 ticks = (float) HZ; /* HZ defined in <sys/param.h>. */
536 mintms = &minuend->tm_cycles;
537 subtms = &subtra->tm_cycles;
539 /* Calculate real time. */
541 ltemp = minuend->tm_real - subtra->tm_real;
542 diff->tu_real = ((float) ltemp)/ticks;
544 /* Calculate user time. */
546 ltemp = mintms->tms_utime
547 - subtms->tms_utime
548 + mintms->tms_cutime
549 - subtms->tms_cutime;
550 diff->tu_user = ((float) ltemp)/ticks;
552 /* Calculate user time. */
554 ltemp = mintms->tms_stime
555 - subtms->tms_stime
556 + mintms->tms_cstime
557 - subtms->tms_cstime;
558 diff->tu_sys = ((float) ltemp)/ticks;
560 return;
564 * EXTERNAL FUNCTIONS
568 * Function: gmt - Generate Current Time String
570 * This function returns the address a string containing the current
571 * GMT in the form YYMMDDhhmmss.
573 * Parameters:
575 * none
577 * Return:
579 * An address of a static character array containing the date.
582 char *
583 gmt()
586 static char date[] = "YYMMDDhhmmss";
588 register struct tm * td;
589 time_t now; /* Current time. */
591 now = time((time_t *) 0);
592 td = gmtime(&now);
593 (void) sprintf(date, "%02d%02d%02d%02d%02d%02d",
594 (td->tm_year % 100),
595 td->tm_mon + 1,
596 td->tm_mday,
597 td->tm_hour,
598 td->tm_min,
599 td->tm_sec
601 return date;
606 * Function: writeLog - Write String to Log File
608 * After insuring that the log file is open, this function will write
609 * the specified string to the log file. If a write error occurs,
610 * statistics collection will be disabled.
612 * Parameters:
614 * string - Null terminated string to be written out.
615 * logfile - file descripter
616 * logname - name of log file.
617 * collecting - log enable/disable
620 void
621 writeLog (string, logfile, logname, collecting)
623 char * string;
624 int * logfile;
625 char * logname;
626 int * collecting;
629 register int length; /* Length of the string. */
630 register int rv; /* Return value from write. */
632 char errmsg[BUFSIZ]; /* Place for error messages. */
634 if (openLog(logfile,logname) != SUCCESS){
635 *collecting = FALSE;
636 return;
638 length = strlen(string);
641 rv = write(*logfile, string, (unsigned) length);
642 } while ((rv < 0) && (errno == EINTR)); /* Retry if interrupted. */
643 if (rv < length)
644 { /* Error or incomplete output. */
645 (void) sprintf(errmsg, Msg_write, logname);
646 DEBUG(DB_IMPORTANT, errmsg, errno);
648 /* If we had a write error, lets give up on loggine. */
650 closeLog(logfile);
651 *collecting = FALSE;
653 return;
657 * Function: closeLog - Close the Log File
659 * This function allows uucico to close the log file in preparation for
660 * forking.
662 * Parameters:
664 * log file descriptor
667 void
668 closeLog (logfile)
669 int *logfile;
672 if (*logfile != CLOSED)
674 (void) close(*logfile);
675 *logfile = CLOSED;
677 return;
682 * Function: copyText - Copy String to Dynamic Memory
684 * This function copies a string to a buffer. It insures that there is
685 * no overflow of the buffer and that the result is null terminated.
687 * Parameters:
689 * tptr - address of the buffer where the string is to
690 * be stored.
692 * size - number of bytes in the buffer.
694 * string - string to be saved.
696 * Returns:
698 * none.
701 void
702 copyText (tptr, size, string)
704 register char * tptr;
705 register int size;
706 char * string;
709 (void) strncpy(tptr, string, size);
710 *(tptr + size - 1) = NULLCHAR;
711 return;
715 * Function: pfConnected - Report Connection Completion
717 * Uucico uses pfConnected to tell this performance package that a connection
718 * has been established with the remote system.
720 * Parameters:
722 * remote - name of the remote system.
724 * device - the type of device being used for communicaitons.
727 void
728 pfConnected (remote, device)
730 char * remote;
731 char * device;
734 register int i;
735 register TMARK * tptr;
737 LOGCHECK;
738 grabTimes(&Conn.cn_times[CT_CONNECTED]);
739 copyText(Remote, sizeof(Remote), remote);
740 copyText(Device, sizeof(Device), device);
741 reportConn();
742 tptr = &Conn.cn_times[0];
745 * Mark connection times as invalid. This is really unnecessary
746 * since there should only be one connection per invocation of uucico.
747 * We do it for consistency with use of the transfer data.
750 for (i = 0; i < CT_SIZE; i++, tptr++)
751 tptr->tm_valid = FALSE;
752 return;
757 * Function: pfEndFile - Report End of File
759 * Uucico uses pfEndFile to tell our statistics collection package that
760 * all processing has been finished on the current file. PfEndfile should
761 * be called after all notifications have been done and after the status
762 * file has been written. PfEndfile writes out a xfer record for the
763 * file that just completed.
765 * Parameters:
767 * none
770 void
771 pfEndfile (breakmsg)
772 char * breakmsg;
774 register int i;
775 register TMARK * tdptr;
776 register struct xferData * xptr = &Xfer;
778 LOGCHECK;
779 grabTimes(&Xfer.xf_times[XT_ENDFILE]);
780 Xfer.xf_filedone = time((time_t *) 0);
781 reportFile(breakmsg);
783 /* Now that we have reported them, mark all times as invalid. */
785 copyText(xptr->xf_flags, sizeof(xptr->xf_flags), NOTAVAIL);
786 tdptr = &Xfer.xf_times[0];
787 for (i = 0; i < XT_SIZE; i++, tdptr++)
788 tdptr->tm_valid = FALSE;
789 return;
793 * Function: pfEndXfer - File Transfer Complete
795 * Calling pfEndXfer tells the performance package that a file transfer
796 * has been completed. It should be called after the destination site
797 * closes the file and confirms receipt, but before notifications are done.
799 * Parameters:
801 * none
804 void
805 pfEndXfer ()
808 LOGCHECK;
809 grabTimes(&Xfer.xf_times[XT_ENDXFER]);
810 return;
814 * Function: pfFindFile - Looking for Another File
816 * Uucico uses pfFindFile to announce that it is going to explore the
817 * queues for another file transfer to do. PfFindFile is only called
818 * when uucico is in the role of master.
820 * Parameters:
822 * none
825 void
826 pfFindFile ()
829 LOGCHECK;
830 grabTimes(&Xfer.xf_times[XT_LOOK]);
831 return;
835 * Function: pfFound - Found Another File
837 * PfFound is a counterpart of pfFindFile. It is called when a new file
838 * has been found. Like pfFindFile it is called only by a master uucico.
840 * Parameters:
842 * jobid - The name of the job that was found.
844 * flags - Options flags that were stored in the queue.
845 * These flags are originally set by uucp.
847 * intoQue - The time that the C. file was placed in the queue.
850 void
851 pfFound (jobid, flags, intoQue)
853 char * jobid;
854 char * flags;
855 time_t intoQue;
858 register struct xferData * xptr = &Xfer;
860 LOGCHECK;
861 grabTimes(&xptr->xf_times[XT_FOUND]);
862 copyText(xptr->xf_jobname, sizeof(xptr->xf_jobname), jobid);
863 xptr->xf_jobgrade[0] = jobid[strlen(jobid)-5];
864 xptr->xf_jobgrade[1] = NULLCHAR;/* get job grade from jobid */
865 copyText(xptr->xf_flags, sizeof(xptr->xf_flags), flags);
867 /* Save time that file was placed in queue and current time. */
869 xptr->xf_intoque = intoQue;
870 xptr->xf_deque = time((time_t *) 0);
871 return;
875 * Function: pfInit - Initialize Performance Package
877 * This function allows the performance package to initialize its internal
878 * data structures. It should be called one time only when uucico starts
879 * running.
881 * Parameters:
883 * none
886 void
887 pfInit ()
890 register struct xferData * xptr = &Xfer;
892 if (Initialized == TRUE)
893 return;
894 Procid = getpid();
895 myName(myname);
896 copyText(xptr->xf_flags, sizeof(xptr->xf_flags), NOTAVAIL);
899 * Attempt to open the log file. If we can't do it, then we
900 * won't collect statistics.
903 if (openLog(&LogFile,LogName) == SUCCESS)
904 Collecting = TRUE;
905 else
906 Collecting = FALSE;
907 Initialized = TRUE;
908 return;
912 * Function: pfStrtConn - Going to Establish Connection
914 * Uucico uses pfStrtConn to announce that it is going to attempt
915 * to establish a connection.
917 * Parameters:
919 * role - An indication of whether uucico is currently
920 * running in master or slave mode. M = master,
921 * S = slave.
924 void
925 pfStrtConn (role)
927 char role;
929 LOGCHECK;
930 grabTimes(&Conn.cn_times[CT_START]);
931 Conn.cn_role = role;
932 return;
936 * Function: pfStrtXfer - Starting File Transfer
938 * This function should be called just as the first byte of data is
939 * about to be transferred.
941 * Parameters:
943 * role - An indication of whether uucico is currently
944 * running in master or slave mode. M = master,
945 * S = slave.
947 * direction - Direction of file transfer. S = sending to
948 * remote, R = receiving from remote.
951 void
952 pfStrtXfer(role, direction)
954 char role;
955 char direction;
958 register struct xferData * xptr = &Xfer;
960 LOGCHECK;
961 grabTimes(&xptr->xf_times[XT_BEGXFER]);
962 xptr->xf_role = role;
963 xptr->xf_direction = direction;
964 return;
968 A protocol which both master and slave sides agree on
971 void
972 pfPtcl(str)
973 char *str;
975 strcpy(Protocol,str);
976 return;
980 * Function: openLog - Open the Log File
982 * If the log file is already open this function immediately returns
983 * success. Otherwise, an attempt is made to open the logfile in append
984 * mode.
986 * Parameters:
988 * logfile - file descripter
989 * logname - name of log file.
991 * Returns:
993 * SUCCESS - The log file is open.
994 * FAIL - Unable to open logfile.
998 openLog (logfile,logname)
999 int *logfile;
1000 char *logname;
1002 register int fd; /* File descriptor of log file. */
1004 int level; /* Level for debug message. */
1005 char msgbuf[BUFSIZ];
1007 /* See if file already open. */
1009 if (*logfile != CLOSED)
1010 return (SUCCESS);
1012 /* Attempt to open the file. */
1014 DEBUG(DB_TRACE, Msg_opening, logname);
1017 fd = open(logname, O_WRONLY | O_APPEND);
1018 } while ((fd < 0) && (errno == EINTR)); /* Retry if interrupted. */
1019 if (fd < 0) { /* Error on open. */
1020 (void) sprintf(msgbuf, Msg_badopen, logname);
1021 if (errno == ENOENT)
1022 level = DB_DETAIL; /* If the file is not there
1023 * it will usually mean
1024 * that the SA doesn't
1025 * want to collect
1026 * statisitcs. */
1027 else
1028 level = DB_IMPORTANT; /* Unexpected error */
1029 DEBUG(level, msgbuf, errno); /* No log file. */
1030 return FAIL;
1031 } else {
1032 *logfile = fd;
1033 return SUCCESS;
1037 #ifdef BSD4_2
1038 #include <sys/time.h>
1039 #include <sys/times.h>
1040 #include <sys/resource.h>
1042 static clock_t
1043 scale60(tvp)
1044 register struct timeval *tvp;
1046 return (tvp->tv_sec * 60 + tvp->tv_usec / 16667);
1049 clock_t
1050 times(tmsp)
1051 register struct tms *tmsp;
1053 struct rusage ru;
1054 struct timeval now;
1055 static time_t epoch;
1057 if (getrusage(RUSAGE_SELF, &ru) < 0)
1058 return (clock_t)(-1);
1059 tmsp->tms_utime = scale60(&ru.ru_utime);
1060 tmsp->tms_stime = scale60(&ru.ru_stime);
1061 if (getrusage(RUSAGE_CHILDREN, &ru) < 0)
1062 return (clock_t)(-1);
1063 tmsp->tms_cutime = scale60(&ru.ru_utime);
1064 tmsp->tms_cstime = scale60(&ru.ru_stime);
1065 if (gettimeofday(&now, (struct timezone *)0) < 0)
1066 return (clock_t)(-1);
1067 if (epoch == 0)
1068 epoch = now.tv_sec;
1069 now.tv_sec -= epoch;
1070 return (scale60(&now));
1072 #endif /* BSD4_2 */