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