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