1/*
2 * CDDL HEADER START
3 *
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.
8 *
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.
13 *
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]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2017 Gary Mills
24 * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25 * Use is subject to license terms.
26 */
27
28/*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
29/*	  All Rights Reserved  	*/
30
31#include <time.h>
32#include "uucp.h"
33
34#ifdef	V7
35#define O_RDONLY	0
36#endif
37#define KILLMSG "the system administrator has killed job"
38#define USAGE1	"[-q] | [-m] | [-k JOB [-n]] | [-r JOB [-n]] | [-p]"
39#define USAGE2	"[-a] [-s SYSTEM [-j]] [-u USER] [-S STATE]"
40#define USAGE3  "-t SYSTEM [-d number] [-c]"
41#define LOCK "LCK.."
42#define STST_MAX	132
43#define MAXDATE		12
44#define MINTIME		60
45#define MINUTES		60
46#define CHAR		"a"
47#define MAXSTATE	4
48/* #include "logs.h" */
49struct m {
50	char	mach[15];		/* machine name */
51	char	locked;
52	int	ccount, xcount;
53	int	count, type;
54	long	retrytime;
55	time_t lasttime;
56	short	c_age;			/* age of oldest C. file */
57	short	x_age;			/* age of oldest X. file */
58	char	stst[STST_MAX];
59} M[UUSTAT_TBL+2];
60
61
62struct userdate {
63	char uhour[3];
64	char umin[3];
65	char lhour[3];
66	char lmin[3];
67};
68
69struct userdate userformat;
70struct userdate *friendlyptr = &userformat;
71
72extern long atol();
73static int whattodo();
74static int readperf();
75static void queuetime();
76static void xfertime();
77static char * gmt();
78static char * gmts();
79static void errortn();
80static void friendlytime();
81static void complete();
82static int state();
83static int gnameflck();
84static void kprocessC();
85static int convert();
86void uprocessC(), printit(), docalc(), procState();
87
88static short State, Queued, Running, Complete, Interrupted;
89
90static char mailmsg[BUFSIZ];
91static char outbuf[BUFSIZ+1];
92static int count;
93static short jobcount;
94static short execute;
95static char lowerlimit[MAXDATE+1], upperlimit[MAXDATE+1];
96static float totalque, totalxfer;
97static long totaljob, totalbytes;
98static long inputsecs;
99#ifdef ATTSV
100extern void qsort();		/* qsort(3) and comparison test */
101#endif /* ATTSV */
102int sortcnt = -1;
103extern int machcmp();
104extern int _age();		/* find the age of a file */
105static long calcnum;
106extern char Jobid[];	/* jobid for status or kill option */
107short Kill;		/*  == 1 if -k specified */
108short Rejuvenate;	/*  == 1 for -r specified */
109short Uopt;		/*  == 1 if -u option specified */
110short Sysopt;		/*  == 1 if -s option specified */
111static short Calctime;   /*  == 1 if -t parameter set */
112short Summary;		/*  == 1 if -q or -m is specified */
113short Queue;		/*  == 1 if -q option set - queue summary */
114short Machines;		/*  == 1 if -m option set - machines summary */
115short Psopt;		/*  == 1 if -p option set - output "ps" of LCK pids */
116static short Window;    /*  == 1 if -d parameter set with -t option */
117static short nonotf;    /*  == 1 if -n parameter set with -k option */
118short avgqueue;		/*  == 1 if -c parameter set with -t option */
119short avgxfer;		/*  will be set to 1 if -c not specified    */
120short Jobcount;		/* == 1 if -j parameter set with -s option */
121char f[NAMESIZE];
122
123int
124main(argc, argv, envp)
125char *argv[];
126char **envp;
127{
128	struct m *m, *machine();
129	DIR *spooldir, *subdir, *machdir, *gradedir;
130	char *str, *rindex();
131	char subf[256], gradef[256];
132	char *c, lckdir[BUFSIZ];
133	char buf[BUFSIZ];
134	char chkname[MAXFULLNAME];
135	char *vec[7];
136	int i, chkid;
137	char fullpath[MAXFULLNAME];
138	long temp;
139
140	char arglist[MAXSTATE+1];
141
142	/* Set locale environment variables local definitions */
143	(void) setlocale(LC_ALL, "");
144#if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
145#define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it wasn't */
146#endif
147	(void) textdomain(TEXT_DOMAIN);
148
149	User[0] = '\0';
150	Rmtname[0] = '\0';
151	Jobid[0] = '\0';
152	Psopt=Machines=Summary=Queue=Kill=Rejuvenate=Uopt=Sysopt=Jobcount=0;
153	execute=avgqueue=avgxfer=Calctime=Window=0;
154	jobcount=nonotf=0;
155
156	/* set calcnum to default time in minutes */
157	calcnum=MINTIME;
158
159	(void) strcpy(Progname, "uustat");
160	Uid = getuid();
161	Euid = geteuid();
162	guinfo(Uid, Loginuser);
163	uucpname(Myname);
164	while ((i = getopt(argc, argv, "acjk:mnpr:qs:u:x:t:d:S:")) != EOF) {
165		switch(i){
166		case 'a':
167			Sysopt = 1;
168			break;
169		case 'c':
170			avgqueue = 1;
171			break;
172		case 'd':
173			Window = 1;
174			calcnum = atoi(optarg);
175			if (calcnum <= 0)
176				calcnum = MINTIME;
177			break;
178		case 'k':
179			(void) strncpy(Jobid, optarg, NAMESIZE);
180			Jobid[NAMESIZE-1] = '\0';
181			Kill = 1;
182			break;
183		case 'j':
184			Jobcount = 1;
185			break;
186		case 'm':
187			Machines = Summary = 1;
188			break;
189		case 'n':
190			nonotf = 1;
191			break;
192		case 'p':
193			Psopt = 1;
194			break;
195		case 'r':
196			(void) strncpy(Jobid, optarg, NAMESIZE);
197			Jobid[NAMESIZE-1] = '\0';
198			Rejuvenate = 1;
199			break;
200		case 'q':
201			Queue = Summary = 1;
202			break;
203		case 's':
204			(void) strncpy(Rmtname, optarg, MAXBASENAME);
205
206			Rmtname[MAXBASENAME] = '\0';
207			if (versys(Rmtname)) {
208				fprintf(stderr, gettext("Invalid system\n"));
209				exit(1);
210			}
211			Sysopt = 1;
212			break;
213		case 't':
214			Calctime = 1;
215			(void) strncpy(Rmtname, optarg, MAXBASENAME);
216			Rmtname[MAXBASENAME] = '\0';
217			if (versys(Rmtname)) {
218				fprintf(stderr, gettext("Invalid system\n"));
219				exit(1);
220			}
221			break;
222		case 'u':
223			(void) strncpy(User, optarg, 8);
224			User[8] = '\0';
225			if(gninfo(User, &chkid, chkname)) {
226				fprintf(stderr, gettext("Invalid user\n"));
227				exit(1);
228			}
229			Uopt = 1;
230			execute = 1;
231			break;
232		case 'x':
233			Debug = atoi(optarg);
234			if (Debug <= 0)
235				Debug = 1;
236			break;
237		case 'S':
238			if (strlen(optarg) > sizeof (arglist)) {
239				errortn();
240				exit(1);
241			}
242			State = 1;
243			(void) strlcpy(arglist, optarg, sizeof (arglist));
244			procState(arglist);
245			break;
246		default:
247			errortn();
248			exit(1);
249		}
250	}
251
252	if (argc != optind) {
253		errortn();
254		exit(1);
255	}
256
257	DEBUG(9, "Progname (%s): STARTED\n", Progname);
258	DEBUG(9, "User=%s, ", User);
259	DEBUG(9, "Loginuser=%s, ", Loginuser);
260	DEBUG(9, "Jobid=%s, ", Jobid);
261	DEBUG(9, "Rmtname=%s\n", Rmtname);
262
263	/* -j only allowed with -s */
264	if (Jobcount && !Sysopt)
265		{
266		errortn();
267		exit(1);
268		}
269       if ((Calctime + Psopt + Machines + Queue + Kill + Rejuvenate + (Uopt|Sysopt |State)) >1) {
270		/* only -u, -S and -s can be used together */
271		errortn();
272		exit(1);
273	}
274	if ((avgqueue | Window) & (!Calctime))
275		{
276		errortn();
277		exit(1);
278	}
279
280	if (  !(Calctime | Kill | Rejuvenate | Uopt | Sysopt | Queue| Machines | State) ) {
281		(void) strcpy(User, Loginuser);
282		Uopt = 1;
283	}
284
285	if ( nonotf && !(Kill | Rejuvenate) ) {
286		errortn();
287		exit(1);
288	}
289
290	/*****************************************/
291	/* PROCESS THE OPTIONS                   */
292	/*****************************************/
293
294	if (State && Complete)
295		{
296		   DEBUG(9, "calling complete %d\n",Complete);
297		   complete();
298		}
299
300	if (Calctime) {
301		count = readperf(calcnum);
302
303		if (count != 0)
304			docalc();
305
306	}
307
308	if (Psopt) {
309		/* do "ps -flp" or pids in LCK files */
310		lckpid();
311		/* lckpid will not return */
312	}
313
314	if (Summary) {
315	    /*   Gather data for Summary option report  */
316	    if (chdir(STATDIR) || (spooldir = opendir(STATDIR)) == NULL)
317		exit(101);		/* good old code 101 */
318	    while (gnamef(spooldir, f) == TRUE) {
319		if (freopen(f, "r", stdin) == NULL)
320			continue;
321		m = machine(f);
322		if (fgets(buf, sizeof(buf), stdin) == NULL)
323			continue;
324		if (getargs(buf, vec, 5) < 5)
325			continue;
326		m->type = atoi(vec[0]);
327		m->count = atoi(vec[1]);
328		m->lasttime = atol(vec[2]);
329		m->retrytime = atol(vec[3]);
330		(void) strncpy(m->stst, vec[4], STST_MAX);
331		str = rindex(m->stst, ' ');
332		(void) machine(++str);	/* longer name? */
333		*str = '\0';
334
335	    }
336	    closedir(spooldir);
337	}
338
339
340	if (Summary) {
341	    /*  search for LCK machines  */
342	    char flck[MAXNAMESIZE];
343
344	    (void) strcpy(lckdir, LOCKPRE);
345	    *strrchr(lckdir, '/') = '\0';
346	    /* open lock directory */
347	    if (chdir(lckdir) != 0 || (subdir = opendir(lckdir)) == NULL)
348		exit(101);		/* good old code 101 */
349
350	    while (gnameflck(subdir, flck) == TRUE) {
351		/* XXX - this is disgusting... */
352		if (EQUALSN("LCK..", flck, 5)) {
353		    if (!EQUALSN(flck + 5, "cul", 3)
354		     && !EQUALSN(flck + 5, "cua", 3)
355		     && !EQUALSN(flck + 5, "tty", 3)
356		     && !EQUALSN(flck + 5, "dtsw", 4)
357		     && !EQUALSN(flck + 5, "vadic", 5)
358		     && !EQUALSN(flck + 5, "micom", 5))
359			machine(flck + 5)->locked++;
360		}
361	    }
362	}
363
364	if (chdir(SPOOL) != 0 || (spooldir = opendir(SPOOL)) == NULL)
365		exit(101);		/* good old code 101 */
366
367	while (gnamef(spooldir, f) == TRUE) {
368	 /* at /var/spool/uucp directory */
369	 /* f will contain remote machine names */
370
371          if (EQUALSN("LCK..", f, 5))
372		continue;
373
374          if (*Rmtname && !EQUALSN(Rmtname, f, MAXBASENAME))
375		continue;
376
377          if ( (Kill || Rejuvenate)
378	      && (!EQUALSN(f, Jobid, strlen(Jobid)-5)) )
379		    continue;
380
381	  if (DIRECTORY(f))  {
382		if (chdir(f) != 0)
383			exit(101);
384		(void) sprintf(fullpath, "%s/%s", SPOOL, f);
385		machdir = opendir(fullpath);
386		if (machdir == NULL)
387			exit(101);
388
389		m = machine(f);
390		while (gnamef(machdir, gradef) == TRUE) {
391			/* at /var/spool/uucp/remote_name */
392			/* gradef will contain job_grade directory names */
393
394	     		if (DIRECTORY(gradef) && (gradedir = opendir(gradef))) {
395				/* at /var/spool/uucp/remote_name/job_grade */
396
397		  		while (gnamef(gradedir, subf) == TRUE) {
398				    /* subf will contain file names */
399				    /* files can be C. or D. or A., etc.. */
400
401				    if (subf[1] == '.') {
402		  		      if (subf[0] == CMDPRE) {
403					/* if file name is C. */
404					m->ccount++;
405
406					if (Kill || Rejuvenate)
407					    kprocessC(gradef, subf);
408					else if (Uopt | Sysopt | Queued | Running | Interrupted)
409				 	   /* go print out C. file info */
410				  	   uprocessC(f ,gradef, subf);
411
412					else 	/* get the age of the C. file */
413				 	   if ( (i = _age(gradef, subf))>m->c_age)
414						m->c_age = i;
415					}
416		    		    }
417				}
418				closedir(gradedir);
419			}
420
421			else if (gradef[0] == XQTPRE && gradef[1] == '.') {
422			   m->xcount++;
423			   if ( (i = _age(machdir, gradef)) > m->x_age)
424				m->x_age = i;
425			}
426		}
427		closedir(machdir);
428	  }
429	  /* cd back to /var/spoool/uucp dir */
430	  if (chdir(SPOOL) != 0)
431		exit(101);
432	} /* while more files in spooldir */
433	closedir(spooldir);
434
435	if (Jobcount && (jobcount != 0))
436		printf("job count = %d\n",jobcount);
437
438	/* for Kill or Rejuvenate - will not get here unless it failed */
439	if (Kill) {
440	    printf(gettext("Can't find Job %s; Not killed\n"), Jobid);
441	    exit(1);
442	} else if (Rejuvenate) {
443	    printf(gettext("Can't find Job %s; Not rejuvenated\n"), Jobid);
444	    exit(1);
445	}
446
447	/* Make sure the overflow entry is null since it may be incorrect */
448	M[UUSTAT_TBL].mach[0] = NULLCHAR;
449	if (Summary) {
450	    for((sortcnt = 0, m = &M[0]);*(m->mach) != '\0';(sortcnt++,m++))
451			;
452	    qsort((char *)M, (unsigned int)sortcnt, sizeof(struct m), machcmp);
453	    for (m = M; m->mach[0] != NULLCHAR; m++)
454		printit(m);
455	}
456	return (0);
457}
458
459
460/*
461 * uprocessC - get information about C. file
462 *
463 */
464
465void
466uprocessC(machine, dir, file)
467char   *machine, *dir, *file;
468{
469	struct stat s;
470	struct tm *tp;
471	char fullname[MAXFULLNAME], buf[BUFSIZ], user[9];
472	char xfullname[MAXFULLNAME];
473	char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
474	short goodRecord = 0;
475	FILE *fp, *xfp;
476	short first = 1;
477	int statefound = 0;
478	extern long fsize();
479	char format_tmp[BUFSIZ+1];
480	fp=xfp=NULL;
481
482	/*********************************************/
483	/* initialize output buffer to blanks        */
484	/*********************************************/
485
486	if (Complete && !Queued && !Running && !Interrupted)
487		return;
488	outbuf[0] = NULLCHAR;
489
490	DEBUG(9, "uprocessC(%s, ", dir);
491	DEBUG(9, "%s);\n", file);
492
493	if (Jobid[0] != '\0' && (!EQUALS(Jobid, &file[2])) ) {
494		/* kill job - not this one */
495		return;
496	}
497
498	(void) sprintf(fullname, "%s/%s", dir, file);
499	if (stat(fullname, &s) != 0) {
500	     /* error - can't stat */
501	    DEBUG(4, "Can't stat file (%s),", fullname);
502	    DEBUG(4, " errno (%d) -- skip it!\n", errno);
503	}
504
505	fp = fopen(fullname, "r");
506	if (fp == NULL) {
507		DEBUG(4, "Can't open file (%s), ", fullname);
508		DEBUG(4, "errno=%d -- skip it!\n", errno);
509		return;
510	}
511	tp = localtime(&s.st_mtime);
512
513	if (s.st_size == 0 && User[0] == '\0') { /* dummy D. for polling */
514	    sprintf(format_tmp,"%-12s  %2.2d/%2.2d-%2.2d:%2.2d:%2.2d  (POLL)\n",
515		&file[2], tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
516		tp->tm_min, tp->tm_sec);
517		(void) strcat(outbuf, format_tmp);
518	}
519	else while (fgets(buf, BUFSIZ, fp) != NULL) {
520	    if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
521	      user, opt, file3) <5) {
522		DEBUG(4, "short line (%s)\n", buf);
523		continue;
524	    }
525	    DEBUG(9, "type (%s), ", type);
526	    DEBUG(9, "file1 (%s)", file1);
527	    DEBUG(9, "file2 (%s)", file2);
528	    DEBUG(9, "file3 (%s)", file3);
529	    DEBUG(9, "user (%s)", user);
530
531	    goodRecord = 0;
532
533	    if (User[0] != '\0' && (!EQUALS(User, user)) )
534		continue;
535
536
537	    if (first)
538	       {
539	        sprintf(format_tmp,"%-12s", &file[2]);
540		(void) strcat(outbuf, format_tmp);
541
542		/* if the job state is requested call the
543		   state function to determine this job's state */
544
545		if (State)
546		{
547		   statefound = state(dir, file);
548	           DEBUG(9, "uprocessC: statefound value = %d\n", statefound);
549 		   if ((whattodo(statefound) != TRUE))
550			{
551			   outbuf[0] = NULLCHAR;
552			   return;
553			}
554		   else
555			{
556			   if (statefound == 1)
557				(void) strcat(outbuf, "queued");
558			   else if (statefound == 2)
559				(void) strcat(outbuf, "running");
560			   else if (statefound == 3)
561				(void) strcat(outbuf, "interrupted");
562			}
563		}
564		sprintf(format_tmp, " %2.2d/%2.2d-%2.2d:%2.2d ",
565		    tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
566		    tp->tm_min);
567		(void) strcat(outbuf, format_tmp);
568	       }
569	    else
570	       {
571		sprintf(format_tmp,"%-12s %2.2d/%2.2d-%2.2d:%2.2d ",
572		    "", tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
573		    tp->tm_min);
574		(void) strcat(outbuf, format_tmp);
575		}
576	    first = 0;
577
578	    sprintf(format_tmp,"%s  %s  ", type, machine);
579	    (void) strcat(outbuf, format_tmp);
580	    if (*type == 'R')
581	       {
582	        sprintf(format_tmp,"%s  %s ", user, file1);
583	        (void) strcat(outbuf, format_tmp);
584	       }
585	    else if (file2[0] != 'X')
586		{
587		 sprintf(format_tmp,"%s %ld %s ", user, fsize(dir, file3, file1), file1);
588		 (void) strcat(outbuf, format_tmp);
589		}
590	    else if (*type == 'S' && file2[0] == 'X') {
591		(void) sprintf(xfullname, "%s/%s", dir, file1);
592		xfp = fopen(xfullname, "r");
593		if (xfp == NULL) { /* program error */
594		    DEBUG(4, "Can't read %s, ", xfullname);
595		    DEBUG(4, "errno=%d -- skip it!\n", errno);
596		    sprintf(format_tmp,"%s  ", user);
597		    (void) strcat(outbuf, format_tmp);
598		    (void) strcat(outbuf,"????\n");
599		}
600		else {
601		    char command[BUFSIZ], uline_u[BUFSIZ], uline_m[BUFSIZ];
602		    char retaddr[BUFSIZ], *username;
603
604		    *retaddr = *uline_u = *uline_m = '\0';
605		    while (fgets(buf, BUFSIZ, xfp) != NULL) {
606			switch(buf[0]) {
607			case 'C':
608				strcpy(command, buf + 2);
609				break;
610			case 'U':
611				sscanf(buf + 2, "%s%s", uline_u, uline_m);
612				break;
613			case 'R':
614				sscanf(buf+2, "%s", retaddr);
615				break;
616			}
617		    }
618		    username = user;
619		    if (*uline_u != '\0')
620			    username = uline_u;
621		    if (*retaddr != '\0')
622			username = retaddr;
623		    if (!EQUALS(uline_m, Myname))
624			printf("%s!", uline_m);
625		    sprintf(format_tmp,"%s  %s", username, command);
626		    (void) strcat(outbuf, format_tmp);
627		}
628	    }
629       	strcat(outbuf, "\n");
630	fputs(outbuf, stdout);
631        outbuf[0] = NULLCHAR;
632	goodRecord = 1;
633       } /* end of while more data in buffer */
634
635       /* successful processing of a job, increment job count
636	  counter */
637	if (goodRecord)
638            jobcount++;
639
640	if (xfp != NULL)
641	    fclose(xfp);
642
643	fclose(fp);
644	return;
645}
646/*
647 * whattodo - determine what to do with current C dot file
648 *  	     depending on any combination (2**3 - 1) of input
649 *	     job states
650 */
651static int
652whattodo(inputint)
653int inputint;
654{
655	/* Maybe some commentary here will help explain this truth
656	   table.
657
658	Queued		|Running	|Interrupted
659	-------------------------------------------------
660		X	|		|
661	-------------------------------------------------
662			|	X	|
663	-------------------------------------------------
664			|		|      X
665	-------------------------------------------------
666		X	|	X	|
667	-------------------------------------------------
668			|	X	|      X
669	-------------------------------------------------
670		X	|		|      X
671	-------------------------------------------------
672		X	|	X	|      X
673	-------------------------------------------------
674
675	Now do you understand.  All  possible combinations have to
676	be evaluated to determine whether or not to print the C dot
677	information out or not! Well, all but 000, because if neither
678	of these states are input by the user we would not be
679	examing the C dot file anyway!
680	*/
681
682	if (Queued && Running && Interrupted)
683		return(TRUE);
684	else if ((Queued && !Running && !Interrupted) && (inputint == 1))
685		return(TRUE);
686	else if ((Running && !Queued && !Interrupted) && (inputint == 2))				return(TRUE);
687	else if ((Interrupted && !Queued && !Running) && (inputint == 3))				return(TRUE);
688	else if ((Queued && Running && !Interrupted) &&
689		(inputint == 1 || inputint == 2))
690	  		return(TRUE);
691	else if ((!Queued && Running && Interrupted) &&
692		(inputint == 2 || inputint == 3))
693			return(TRUE);
694	else if ((Queued && !Running && Interrupted) &&
695		(inputint ==1 || inputint == 3))
696			return(TRUE);
697	else return(FALSE);
698}
699/*
700 * kprocessC - process kill or rejuvenate job
701 */
702
703static void
704kprocessC(dir, file)
705char *file, *dir;
706{
707	struct stat s;
708	struct tm *tp;
709	extern struct tm *localtime();
710	char fullname[MAXFULLNAME], buf[BUFSIZ], user[9];
711	char rfullname[MAXFULLNAME];
712	char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
713	FILE *fp, *xfp;
714 	struct utimbuf times;
715	short ret;
716	short first = 1;
717
718	DEBUG(9, "kprocessC(%s, ", dir);
719	DEBUG(9, "%s);\n", file);
720
721	if ((!EQUALS(Jobid, &file[2])) ) {
722		/* kill job - not this one */
723		return;
724	}
725
726	(void) sprintf(fullname, "%s/%s", dir, file);
727	if (stat(fullname, &s) != 0) {
728	     /* error - can't stat */
729	    if(Kill) {
730		fprintf(stderr,
731		  gettext("Can't stat:%s, errno (%d)--can't kill it!\n"),
732		  fullname, errno);
733	    } else {
734		fprintf(stderr,
735		  gettext("Can't stat:%s, errno (%d)--can't rejuvenate it!\n"),
736		  fullname, errno);
737	    }
738	    exit(1);
739	}
740
741	fp = fopen(fullname, "r");
742	if (fp == NULL) {
743	    if(Kill) {
744		fprintf(stderr,
745		  gettext("Can't read:%s, errno (%d)--can't kill it!\n"),
746		  fullname, errno);
747	    } else {
748		fprintf(stderr,
749		  gettext("Can't read:%s, errno (%d)--can't rejuvenate it!\n"),
750		  fullname, errno);
751	    }
752	    exit(1);
753	}
754
755 	times.actime = times.modtime = time((time_t *)NULL);
756
757	while (fgets(buf, BUFSIZ, fp) != NULL) {
758	    if (sscanf(buf,"%s%s%s%s%s%s", type, file1, file2,
759	      user, opt, file3) <6) {
760		if(Kill) {
761		    fprintf(stderr,
762		      gettext("Bad format:%s, errno (%d)--can't kill it!\n"),
763		      fullname, errno);
764		} else {
765		    fprintf(stderr,
766		      gettext("Bad format:%s, errno (%d)--can't rejuvenate it!\n"),
767		      fullname, errno);
768		}
769	        exit(1);
770	    }
771
772	    DEBUG(9, "buf in uprocessK = %s\n ", buf);
773	    DEBUG(9, "fullname is %s\n",fullname);
774	    DEBUG(9, "type (%s), ", type);
775	    DEBUG(9, "file1 (%s)", file1);
776	    DEBUG(9, "file2 (%s)", file2);
777	    DEBUG(9, "file3 (%s)", file3);
778	    DEBUG(9, "user (%s)", user);
779
780
781	    if (first) {
782	        if ((access(fullname, 02) != 0)
783		    && !PREFIX(Loginuser, user)
784		    && !PREFIX(user, Loginuser) ) {
785			/* not allowed - not owner or root */
786			if(Kill)
787			    fprintf(stderr, gettext("Not owner,"
788			      " uucp or root - can't kill job %s\n"), Jobid);
789			else
790			    fprintf(stderr, gettext("Not owner, uucp or root -"
791			      " can't rejuvenate job %s\n"), Jobid);
792		    exit(1);
793		}
794		first = 0;
795	    }
796
797	    /* remove D. file */
798	    (void) sprintf(rfullname, "%s/%s", dir, file3);
799	    DEBUG(4, "Remove %s\n", rfullname);
800	    if (Kill)
801		ret = unlink(rfullname);
802	    else /* Rejuvenate */
803 		ret = utime(rfullname, &times);
804	    if (ret != 0 && errno != ENOENT) {
805		/* program error?? */
806		if(Kill)
807		    fprintf(stderr, gettext("Error: Can't kill,"
808		      " File (%s), errno (%d)\n"), rfullname, errno);
809		else
810		    fprintf(stderr, gettext("Error: Can't rejuvenated,"
811		      " File (%s), errno (%d)\n"), rfullname, errno);
812		exit(1);
813	    }
814	}
815
816	DEBUG(4, "Remove %s\n", fullname);
817	if (Kill)
818	    ret = unlink(fullname);
819	else /* Rejuvenate */
820		ret = utime(fullname, &times);
821
822	if (ret != 0) {
823	    /* program error?? */
824	    if(Kill)
825	        fprintf(stderr, gettext("Error1: Can't kill,"
826	          " File (%s), errno (%d)\n"), fullname, errno);
827	    else
828	        fprintf(stderr, gettext("Error1: Can't rejuvenate,"
829	          " File (%s), errno (%d)\n"), fullname, errno);
830	    exit(1);
831	}
832	/* if kill done by SA then send user mail */
833	else if (!EQUALS(Loginuser, user))
834	   {
835		sprintf(mailmsg, "%s %s", KILLMSG, Jobid);
836		mailst(user, "job killed", mailmsg, "", "");
837	   }
838	fclose(fp);
839	if (!nonotf) {
840		if(Kill)
841			printf(gettext("Job: %s successfully killed\n"), Jobid);
842		else
843			printf(gettext("Job: %s successfully rejuvenated\n"),
844			    Jobid);
845		}
846	exit(0);
847}
848
849/*
850 * fsize - return the size of f1 or f2 (if f1 does not exist)
851 *	f1 is the local name
852 *
853 */
854
855long
856fsize(dir, f1, f2)
857char *dir, *f1, *f2;
858{
859	struct stat s;
860	char fullname[BUFSIZ];
861
862	(void) sprintf(fullname, "%s/%s", dir, f1);
863	if (stat(fullname, &s) == 0) {
864	    return(s.st_size);
865	}
866	if (stat(f2, &s) == 0) {
867	    return(s.st_size);
868	}
869
870	return(-99999);
871}
872
873void cleanup(){}
874void logent(){}		/* to load ulockf.c */
875void systat(){}		/* to load utility.c */
876
877struct m	*
878machine(name)
879char	*name;
880{
881	struct m *m;
882	size_t	namelen;
883
884	DEBUG(9, "machine(%s), ", name);
885	namelen = strlen(name);
886	for (m = M; m->mach[0] != NULLCHAR; m++)
887		/* match on overlap? */
888		if (EQUALSN(name, m->mach, MAXBASENAME)) {
889			/* use longest name */
890			if (namelen > strlen(m->mach))
891				(void) strcpy(m->mach, name);
892			return(m);
893		}
894
895	/*
896	 * The table is set up with 2 extra entries
897	 * When we go over by one, output error to errors log
898	 * When more than one over, just reuse the previous entry
899	 */
900	DEBUG(9, "m-M=%d\n", m-M);
901	if (m-M >= UUSTAT_TBL) {
902	    if (m-M == UUSTAT_TBL) {
903		errent("MACHINE TABLE FULL", "", UUSTAT_TBL,
904		__FILE__, __LINE__);
905		(void) fprintf(stderr,
906		    gettext("WARNING: Table Overflow--output not complete\n"));
907	    }
908	    else
909		/* use the last entry - overwrite it */
910		m = &M[UUSTAT_TBL];
911	}
912
913	(void) strcpy(m->mach, name);
914	m->c_age= m->x_age= m->lasttime= m->locked= m->ccount= m->xcount= 0;
915	m->stst[0] = '\0';
916	return(m);
917}
918
919void
920printit(m)
921struct m *m;
922{
923	struct tm *tp;
924	time_t	t;
925	int	minimum;
926	extern struct tm *localtime();
927
928	if (m->ccount == 0
929	 && m->xcount == 0
930	 /*&& m->stst[0] == '\0'*/
931	 && m->locked == 0
932	 && Queue
933	 && m->type == 0)
934		return;
935	printf("%-10s", m->mach);
936	if (Queue) {
937		if (m->ccount)
938			printf("%3dC", m->ccount);
939		else
940			printf("    ");
941		if (m->c_age)
942			printf("(%d)", m->c_age);
943		else
944			printf("   ");
945		if (m->xcount)
946			printf("%3dX", m->xcount);
947		else
948			printf("    ");
949		if (m->x_age)
950			printf("(%d) ", m->x_age);
951		else
952			printf("    ");
953	} else
954		printf(" ");
955
956	if (m->lasttime) {
957	    tp = localtime(&m->lasttime);
958	    printf("%2.2d/%2.2d-%2.2d:%2.2d ",
959		tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
960		tp->tm_min);
961	}
962/*	if (m->locked && m->type != SS_INPROGRESS) */
963	if (m->locked)
964		printf("Locked ");
965	if (m->stst[0] != '\0') {
966		printf("%s", m->stst);
967		switch (m->type) {
968		case SS_SEQBAD:
969		case SS_LOGIN_FAILED:
970		case SS_DIAL_FAILED:
971		case SS_BAD_LOG_MCH:
972		case SS_BADSYSTEM:
973		case SS_CANT_ACCESS_DEVICE:
974		case SS_DEVICE_FAILED:
975		case SS_WRONG_MCH:
976		case SS_RLOCKED:
977		case SS_RUNKNOWN:
978		case SS_RLOGIN:
979		case SS_UNKNOWN_RESPONSE:
980		case SS_STARTUP:
981		case SS_CHAT_FAILED:
982			(void) time(&t);
983			t = m->retrytime - (t - m->lasttime);
984			if (t > 0) {
985				minimum = (t + 59) / 60;
986				printf("Retry: %d:%2.2d", minimum/60, minimum%60);
987			}
988			if (m->count > 1)
989				printf(" Count: %d", m->count);
990		}
991	}
992	putchar('\n');
993	return;
994}
995
996#define MAXLOCKS 100	/* Maximum number of lock files this will handle */
997
998int
999lckpid()
1000{
1001    int i;
1002    int fd, ret;
1003    pid_t pid, list[MAXLOCKS];
1004    char alpid[SIZEOFPID+2];	/* +2 for '\n' and null */
1005    char buf[BUFSIZ], f[MAXNAMESIZE];
1006    char *c, lckdir[BUFSIZ];
1007    DIR *dir;
1008
1009    DEBUG(9, "lckpid() - entered\n%s", "");
1010    for (i=0; i<MAXLOCKS; i++)
1011	list[i] = -1;
1012    (void) strcpy(lckdir, LOCKPRE);
1013    *strrchr(lckdir, '/') = '\0';
1014    DEBUG(9, "lockdir (%s)\n", lckdir);
1015
1016    /* open lock directory */
1017    if (chdir(lckdir) != 0 || (dir = opendir(lckdir)) == NULL)
1018		exit(101);		/* good old code 101 */
1019    while (gnameflck(dir, f) == TRUE) {
1020	/* find all lock files */
1021	DEBUG(9, "f (%s)\n", f);
1022	if (EQUALSN("LCK.", f, 4) || EQUALSN("LK.", f, 3)) {
1023	    /* read LCK file */
1024	    fd = open(f, O_RDONLY);
1025	    printf("%s: ", f);
1026	    ret = read(fd, alpid, SIZEOFPID+2); /* +2 for '\n' and null */
1027	    pid = strtol(alpid, (char **) NULL, 10);
1028	    (void) close(fd);
1029	    if (ret != -1) {
1030		printf("%ld\n", (long) pid);
1031		for(i=0; i<MAXLOCKS; i++) {
1032		    if (list[i] == pid)
1033			break;
1034		    if (list[i] == -1) {
1035		        list[i] = pid;
1036		        break;
1037		    }
1038		}
1039	    }
1040	    else
1041		printf("????\n");
1042	}
1043    }
1044    fflush(stdout);
1045    *buf = NULLCHAR;
1046    for (i=0; i<MAXLOCKS; i++) {
1047	if( list[i] == -1)
1048		break;
1049	(void) sprintf(&buf[strlen(buf)], "%d ", list[i]);
1050    }
1051
1052    if (i > 0)
1053#ifdef V7
1054	execl("/bin/ps", "uustat-ps", buf, (char *) 0);
1055#else
1056	execl("/usr/bin/ps", "ps", "-flp", buf, (char *) 0);
1057#endif
1058    exit(0);
1059}
1060
1061/*
1062 * get next file name from lock directory
1063 *	p	 -> file description of directory file to read
1064 *	filename -> address of buffer to return filename in
1065 *		    must be of size NAMESIZE
1066 * returns:
1067 *	FALSE	-> end of directory read
1068 *	TRUE	-> returned name
1069 */
1070static int
1071gnameflck(p, filename)
1072char *filename;
1073DIR *p;
1074{
1075	struct dirent dentry;
1076	struct dirent *dp = &dentry;
1077
1078	for (;;) {
1079		if ((dp = readdir(p)) == NULL)
1080			return(FALSE);
1081		if (dp->d_ino != 0 && dp->d_name[0] != '.')
1082			break;
1083	}
1084
1085	(void) strncpy(filename, dp->d_name, MAXNAMESIZE-1);
1086	filename[MAXNAMESIZE-1] = '\0';
1087	return(TRUE);
1088}
1089
1090int
1091machcmp(a,b)
1092char *a,*b;
1093{
1094	return(strcmp(((struct m *) a)->mach,((struct m *) b)->mach));
1095}
1096
1097static long _sec_per_day = 86400L;
1098
1099/*
1100 * _age - find the age of "file" in days
1101 * return:
1102 *	age of file
1103 *	0 - if stat fails
1104 */
1105
1106int
1107_age(dir, file)
1108char * file;	/* the file name */
1109char * dir;	/* system spool directory */
1110{
1111	char fullname[MAXFULLNAME];
1112	static time_t ptime = 0;
1113	time_t time();
1114	struct stat stbuf;
1115
1116	if (!ptime)
1117		(void) time(&ptime);
1118	(void) sprintf(fullname, "%s/%s", dir, file);
1119	if (stat(fullname, &stbuf) != -1) {
1120		return ((int)((ptime - stbuf.st_mtime)/_sec_per_day));
1121	}
1122	else
1123		return(0);
1124}
1125/* Function:  complete - find and print jobids of completed jobs for
1126 *		         user.
1127 *
1128 * Look thru the /var/uucp/.Admin/account file (if present)
1129 * for all jobs initiated by user and print.
1130 *
1131 * Parameters:
1132 *
1133 *		Username - user that initiated uustat request
1134 *
1135 * Returns:
1136 *
1137 */
1138static void
1139complete()
1140{
1141
1142	/* Function name: complete
1143	   Author:	  Roland T. Conwell
1144	   Date:	  July 31, 1986
1145	   Naration: This function will search through
1146		     /var/uucp/.Admin/account file
1147		     for all jobs submitted by User.  If User jobs are
1148		     found the state of 'completed' will be
1149		     printed on stdout. Module called by uustat main
1150
1151	*/
1152char abuf[BUFSIZ];
1153FILE *fp;
1154char accno[15], jobid[15], system[15], loginame[15], time[20], dest[15];
1155char size[15];
1156char grade[2], jgrade[2];
1157char status[2];
1158int x;
1159
1160fp = fopen(ACCOUNT, "r");
1161if (fp == NULL)
1162   {
1163	fprintf(stderr, gettext("Can't open account log\n"));
1164		return;
1165   }
1166while (fgets(abuf, BUFSIZ, fp) != NULL)
1167   {
1168
1169	x = sscanf(abuf, "%s%s%s%s%s%s%s%s%s%s",
1170		accno,jobid, size, status, grade, jgrade, system, loginame,
1171		time, dest);
1172	if (x < 6)
1173		continue;
1174
1175	if (!EQUALS(status, "C"))
1176		continue;
1177
1178	DEBUG(9, "COMPLETE: accno = %s\n", accno);
1179	DEBUG(9, "COMPLETE: jobid = %s\n", jobid);
1180	DEBUG(9, "COMPLETE: size = %s\n", size);
1181	DEBUG(9, "COMPLETE: status = %s\n", status);
1182	DEBUG(9, "COMPLETE: grade = %s\n", grade);
1183	DEBUG(9, "COMPLETE: jgrade = %s\n", jgrade);
1184	DEBUG(9, "COMPLETE: system = %s\n", system);
1185	DEBUG(9, "COMPLETE: loginame = %s\n", loginame);
1186	DEBUG(9, "COMPLETE: time = %s\n", time);
1187	DEBUG(9, "COMPLETE: dest = %s\n", dest);
1188
1189	if (*Rmtname && !EQUALS(Rmtname, dest))
1190		continue;
1191	if (*User && !EQUALS(User, loginame))
1192		continue;
1193	if (State && !Uopt)
1194	  {
1195	   if (EQUALS(Loginuser, loginame))
1196		{
1197			printf("%s completed\n",jobid);
1198			jobcount++;
1199		}
1200	  }
1201	else
1202	  {
1203		printf("%s completed\n", jobid);
1204		jobcount++;
1205	  }
1206   }
1207   fclose(fp);
1208   return;
1209}
1210
1211/* Function: state - determine if Cdotfile is queued or running
1212 *
1213 * This function searches thru the directory jcdir for a Adotfile
1214 * that matches the Cdotfile.  If found then look for a matching
1215 * lock file.  If a Adotfile and a lock file is found then the
1216 * job is in the running state.  If no Adotfile is found then the
1217 * job is in the queued state.  If a Adotfile is found and no
1218 * lock file is found then the job is queued.
1219 *
1220 * Parameters:
1221 *
1222 *	jcdir    -   the job grade directory to search
1223 *	cdotfile -   the Cdotfile whose state is to be determined
1224 *
1225 * Returns:
1226 *
1227 */
1228static int
1229state(jcdir, cdotfile)
1230char *jcdir, *cdotfile;
1231{
1232	short found, foundlck, CequalA;
1233	char comparef[MAXBASENAME+1], afile[MAXBASENAME+1], cfile[MAXBASENAME+1];
1234	char lckfile[MAXBASENAME+1], lockname[MAXBASENAME+1];
1235	char lckdir[BUFSIZ+1];
1236	DIR *subjcdir, *sjcdir;
1237	int rtnstate = 0;
1238	foundlck = 0;
1239	CequalA = 0;
1240	sjcdir = opendir(jcdir);
1241	if (sjcdir == NULL)
1242		return (0);
1243
1244	while (gnamef(sjcdir, comparef) == TRUE) {
1245	    if (comparef[0] == 'A') {
1246
1247		(void) strcpy(afile, comparef);
1248		*strchr(afile, 'A') = ' ';
1249		(void) strcpy(cfile, cdotfile);
1250		*strchr(cfile, 'C') = ' ';
1251
1252		if (EQUALS(cfile, afile)) {
1253	 	    /* now we have a C. and A. for same job */
1254	  	    /* check for LCK..machine.job_grade     */
1255		    /* if no LCK file at this point we will */
1256		    /* print the RUNNING state	        */
1257			CequalA = 1;
1258
1259			(void) strcpy(lckdir, LOCKPRE);
1260			*strrchr(lckdir, '/') = '\0';
1261			/* open lock directory */
1262
1263			subjcdir = opendir(lckdir);
1264			if (subjcdir == NULL)
1265			   exit(101); /* I know, I know! */
1266			(void) sprintf(lockname,"%s%s.%s",LOCK, f, jcdir);
1267			while (gnamef(subjcdir, lckfile) == TRUE)
1268			  {
1269			    DEBUG(9, "STATE: lockfile = %s\n",lckfile);
1270			    if (EQUALS(lockname, lckfile))
1271			          foundlck = 1;
1272			  }
1273			closedir(subjcdir);
1274
1275			}
1276		}
1277
1278	}
1279
1280	closedir(sjcdir);
1281	/* got adot, cdot and lock file */
1282
1283	if (Running && foundlck)
1284		rtnstate = 2;
1285	else if (Interrupted && CequalA && !foundlck)
1286		rtnstate = 3;
1287	else if (Queued && !CequalA && !foundlck)
1288		rtnstate = 1;
1289	DEBUG(9, "STATE: returning with value %d\n",rtnstate);
1290	return(rtnstate);
1291
1292} /* end of state.c */
1293
1294
1295
1296static int
1297readperf(timerange)
1298long timerange;
1299{
1300
1301	char proto[2], jc[2], role[2];
1302	char rectype[5],  time[MAXDATE+1], pid[10],wmachine[10];
1303	char remote[10],device[10], netid[20], jobid[20];
1304	static float queuetime, tat;
1305	static long size;
1306        struct tm tm_tmp;
1307	time_t t_time, t_starttime, t_upperlimit;
1308
1309	char options[10];
1310	static float rst, ust, kst, xferrate, utt, ktt;
1311	static float rtt, wfield, xfield, yfield;
1312
1313	struct perfrec *recptr;
1314	static float tqt;
1315	static int jobs;
1316	char abuf[BUFSIZ];
1317	FILE *fp;
1318	static int x;
1319	char *strptr, *startime;
1320	int recordcnt;
1321
1322	totalxfer=totalbytes=recordcnt=totaljob=totalque=0;
1323	lowerlimit[0] = '\0';
1324	upperlimit[0] = '\0';
1325
1326
1327	inputsecs = convert(timerange);
1328	startime = gmts();
1329	strncpy(lowerlimit, startime, MAXDATE);
1330	strncpy(upperlimit, gmt(), MAXDATE);
1331
1332	/* convert lowerlimit and upperlimit to HH:MM format */
1333	friendlytime(lowerlimit, upperlimit);
1334
1335	fp = fopen(PERFLOG, "r");
1336	if (fp == NULL)
1337 	  {
1338		(void) fprintf(stderr, gettext("Can't open performance log\n"));
1339			return(0);
1340	   }
1341
1342
1343	while (fgets(abuf, BUFSIZ, fp) != NULL)
1344	  {
1345	    DEBUG(9, "READPERF: abuf before = %s\n",abuf);
1346
1347	    if (!EQUALSN(abuf, "xfer", 4))
1348		continue;
1349
1350            /* convert all '|'s to blanks for sscanf */
1351	    for (strptr = abuf; *strptr != '\0'; strptr++)
1352		if (*strptr == '|')
1353		    *strptr = ' ';
1354	    DEBUG(9, "READPERF: abuf = %s\n",abuf);
1355
1356	    x = sscanf(abuf, "%s%*s%s%s%s%s%s%s%*s%s%s%f%f%ld%s%f%f%f%f%f%f%f%f%f%*s",
1357		rectype, time, pid, wmachine, role, remote, device, netid,
1358		jobid, &queuetime, &tat, &size, options, &rst,
1359		&ust, &kst, &xferrate, &utt, &ktt, &rtt, &wfield,
1360		&xfield);
1361
1362		DEBUG(9, "READPERF: rectype = %s\n",rectype);
1363		DEBUG(9, "READPERF: time = %s\n",time);
1364		DEBUG(9, "READPERF: pid = %s\n",pid);
1365		DEBUG(9, "READPERF: remote = %s\n",remote);
1366		DEBUG(9, "READPERF: jobid = %s\n",jobid);
1367		DEBUG(9, "READPERF: queuetime = %f\n",queuetime);
1368		DEBUG(9, "READPERF: tat = %f\n",tat);
1369		DEBUG(9, "READPERF: xferrate = %f\n",xferrate);
1370
1371		abuf[0] = '\0';
1372
1373		if (!EQUALS(Rmtname, remote))
1374			continue;
1375
1376		if (!EQUALS(role, "M"))
1377			continue;
1378
1379		if (x < 18)
1380			continue;
1381
1382		DEBUG(9, "READPERF: startime = %s\n", startime);
1383		DEBUG(9, "READPERF: lowerlimit = %s\n", lowerlimit);
1384		DEBUG(9, "READPERF: time = %s\n", time);
1385		DEBUG(9, "READPERF: upperlimit = %s\n", upperlimit);
1386
1387		strptime(time, "%y %m %d %H %M %S", &tm_tmp);
1388		t_time = mktime(&tm_tmp);
1389		strptime(startime, "%y %m %d %H %M %S", &tm_tmp);
1390		t_starttime = mktime(&tm_tmp);
1391		strptime(upperlimit, "%y %m %d %H %M %S", &tm_tmp);
1392		t_upperlimit = mktime(&tm_tmp);
1393
1394		DEBUG(9, "READPERF: t_time = %d\n", t_time);
1395		DEBUG(9, "READPERF: t_starttime = %d\n", t_starttime);
1396		DEBUG(9, "READPERF: t_upperlimit = %d\n", t_upperlimit);
1397		if (t_starttime <= t_time && t_upperlimit >= t_time)
1398		{
1399			totaljob++;
1400			totalque = totalque + queuetime;
1401			totalxfer = totalxfer + xferrate;
1402			totalbytes = totalbytes + size;
1403			recordcnt = recordcnt + 1;
1404		DEBUG(9, "  processing recordcnt %d\n", recordcnt);
1405		}
1406	DEBUG(9, "END step 1 %d\n", recordcnt);
1407  	 } /* while */
1408	DEBUG(9, "END step 2 recordcnt %d\n", recordcnt);
1409
1410	fclose(fp);
1411	return(recordcnt);
1412
1413
1414} /* end of readperf */
1415
1416void
1417docalc()
1418{
1419   if (avgqueue)
1420	queuetime();
1421   else
1422	xfertime();
1423   return;
1424}
1425
1426static int
1427convert(intime)
1428long intime;
1429{
1430	long outtime;
1431
1432	outtime = intime * 60;
1433	return(outtime);
1434
1435}
1436static void
1437queuetime()
1438{
1439 	static double avgqtime;
1440
1441	avgqtime = totalque / totaljob;
1442
1443	printf("average queue time to [%s] for last [%ld] minutes:  %6.2f seconds\n",Rmtname, calcnum, avgqtime);
1444 	 printf("data gathered from %s:%s to %s:%s GMT\n", friendlyptr->uhour, friendlyptr->umin, friendlyptr->lhour, friendlyptr->lmin);
1445	return;
1446}
1447
1448
1449static void
1450xfertime()
1451{
1452         static double avgxrate;
1453
1454	avgxrate = totalbytes / totalxfer;
1455
1456	printf("average transfer rate with [ %s ] for last [%ld] minutes: %6.2f bytes/sec\n", Rmtname, calcnum, avgxrate);
1457 	 printf("data gathered from %s:%s to %s:%s GMT\n", friendlyptr->uhour, friendlyptr->umin, friendlyptr->lhour, friendlyptr->lmin);
1458	return;
1459}
1460
1461/*
1462 * Local Function:	gmts - Generate Start Time String
1463 *
1464 * This function returns the address to a string containing the start
1465 * time, or upperlimit, for searching the PERFLOG.
1466 * The start time is in GMT in the form YYMMDDhhmmss.
1467 *
1468 * Parameters:
1469 *
1470 *	none
1471 *
1472 * Return:
1473 *
1474 *	An address of a static character array containing the date.
1475 */
1476
1477static char *
1478gmts()
1479{
1480	static char	date[] = "YYMMDDhhmmss";
1481
1482	struct tm 		*td;
1483	time_t			now;	/* Current time. */
1484	time_t			temp;
1485	now = time((time_t *) 0);
1486
1487	/* inputsecs is declared global to this file */
1488	DEBUG(9, "GMTS: now = %ld\n", now);
1489	DEBUG(9, "GMTS: inputsecs = %ld\n", inputsecs);
1490
1491	temp = (now - inputsecs);
1492	td = gmtime(&temp);
1493	(void) sprintf(date, "%02d%02d%02d%02d%02d%02d",
1494				(td->tm_year % 100),
1495				td->tm_mon + 1,
1496				td->tm_mday,
1497				td->tm_hour,
1498				td->tm_min,
1499				td->tm_sec
1500		      );
1501	return date;
1502}
1503
1504/*
1505 * Local Function:	gmt - Generate Current Time String
1506 *
1507 * This function returns the address to a string containing the current
1508 * GMT in the form YYMMDDhhmmss.
1509 *
1510 * Parameters:
1511 *
1512 *	none
1513 *
1514 * Return:
1515 *
1516 *	An address of a static character array containing the date.
1517 */
1518
1519static char *
1520gmt()
1521{
1522	static char	date[] = "YYMMDDhhmmss";
1523
1524	struct tm	*td;
1525	time_t			now;	/* Current time. */
1526
1527	now = time((time_t *) 0);
1528	td = gmtime(&now);
1529	(void) sprintf(date, "%02d%02d%02d%02d%02d%02d",
1530				(td->tm_year % 100),
1531				td->tm_mon + 1,
1532				td->tm_mday,
1533				td->tm_hour,
1534				td->tm_min,
1535				td->tm_sec
1536		      );
1537	return date;
1538}
1539
1540static void
1541friendlytime(uplimit, lolimit)
1542char *uplimit, *lolimit;
1543{
1544
1545	friendlyptr->uhour[0] = *(uplimit+6);
1546	friendlyptr->uhour[1] = *(uplimit+7);
1547	friendlyptr->lhour[0] = *(lolimit+6);
1548	friendlyptr->lhour[1] = *(lolimit+7);
1549	friendlyptr->umin[0]  = *(uplimit+8);
1550	friendlyptr->umin[1]  = *(uplimit+9);
1551	friendlyptr->lmin[0]  = *(lolimit+8);
1552	friendlyptr->lmin[1]  = *(lolimit+9);
1553
1554	friendlyptr->uhour[2] = '\0';
1555	friendlyptr->lhour[2] = '\0';
1556	friendlyptr->umin[2] = '\0';
1557	friendlyptr->lmin[2] = '\0';
1558	return;
1559}
1560
1561void
1562procState(inputargs)
1563char * inputargs;
1564{
1565	if (strchr(inputargs, 'q') != NULL)
1566		Queued = 1;
1567	if (strchr(inputargs, 'r') != NULL)
1568		Running = 1;
1569	if (strchr(inputargs, 'i') != NULL)
1570		Interrupted = 1;
1571	if (strchr(inputargs, 'c') != NULL)
1572		Complete = 1;
1573
1574	if ((size_t)(Queued + Running + Interrupted + Complete) < strlen(inputargs))
1575		{
1576			errortn();
1577			exit(1);
1578		}
1579	return;
1580}
1581
1582static void
1583errortn()
1584{
1585
1586
1587	(void) fprintf(stderr, gettext("\tUsage: %s " USAGE1 "\n"),
1588	    Progname);
1589	(void) fprintf(stderr, gettext("or\n\tUsage: %s " USAGE2 "\n"),
1590	    Progname);
1591	(void) fprintf(stderr, gettext("or\n\tUsage: %s " USAGE3 "\n"),
1592	    Progname);
1593	return;
1594}
1595