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 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  28 /*        All Rights Reserved   */
  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 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
 124 main(argc, argv, envp)
 125 char *argv[];
 126 char **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) != NULL;(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 
 465 void
 466 uprocessC(machine, dir, file)
 467 char   *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  */
 651 static int
 652 whattodo(inputint)
 653 int 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 
 703 static void
 704 kprocessC(dir, file)
 705 char *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 
 855 long
 856 fsize(dir, f1, f2)
 857 char *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 
 873 void cleanup(){}
 874 void logent(){}         /* to load ulockf.c */
 875 void systat(){}         /* to load utility.c */
 876 
 877 struct m        *
 878 machine(name)
 879 char    *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 
 919 void
 920 printit(m)
 921 struct 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 
 998 int
 999 lckpid()
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  */
1070 static int
1071 gnameflck(p, filename)
1072 char *filename;
1073 DIR *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 
1090 int
1091 machcmp(a,b)
1092 char *a,*b;
1093 {
1094         return(strcmp(((struct m *) a)->mach,((struct m *) b)->mach));
1095 }
1096 
1097 static 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 
1106 int
1107 _age(dir, file)
1108 char * file;    /* the file name */
1109 char * 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  */
1138 static void
1139 complete()
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         */
1152 char abuf[BUFSIZ];
1153 FILE *fp;
1154 char accno[15], jobid[15], system[15], loginame[15], time[20], dest[15];
1155 char size[15];
1156 char grade[2], jgrade[2];
1157 char status[2];
1158 int x;
1159 
1160 fp = fopen(ACCOUNT, "r");
1161 if (fp == NULL)
1162    {
1163         fprintf(stderr, gettext("Can't open account log\n"));
1164                 return;
1165    }
1166 while (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  */
1228 static int
1229 state(jcdir, cdotfile)
1230 char *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 
1296 static int 
1297 readperf(timerange)
1298 long 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 
1416 void
1417 docalc()
1418 {
1419    if (avgqueue)
1420         queuetime();
1421    else
1422         xfertime();
1423    return;
1424 }
1425 
1426 static int
1427 convert(intime)
1428 long intime;
1429 {
1430         long outtime;
1431 
1432         outtime = intime * 60;
1433         return(outtime);
1434 
1435 }
1436 static void
1437 queuetime()
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 
1449 static void
1450 xfertime()
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 
1477 static char *
1478 gmts()
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 
1519 static char *
1520 gmt()
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 
1540 static void
1541 friendlytime(uplimit, lolimit)
1542 char *uplimit, *lolimit;
1543 {
1544 
1545         char c;
1546 
1547         c = *(uplimit+6);
1548         friendlyptr->uhour[0] = *(uplimit+6);
1549         friendlyptr->uhour[1] = *(uplimit+7);
1550         friendlyptr->lhour[0] = *(lolimit+6);
1551         friendlyptr->lhour[1] = *(lolimit+7);
1552         friendlyptr->umin[0]  = *(uplimit+8);
1553         friendlyptr->umin[1]  = *(uplimit+9);
1554         friendlyptr->lmin[0]  = *(lolimit+8);
1555         friendlyptr->lmin[1]  = *(lolimit+9);
1556 
1557         friendlyptr->uhour[2] = '\0';
1558         friendlyptr->lhour[2] = '\0';
1559         friendlyptr->umin[2] = '\0';
1560         friendlyptr->lmin[2] = '\0';
1561         return;
1562 }
1563 
1564 void
1565 procState(inputargs)
1566 char * inputargs;
1567 {
1568         if (strchr(inputargs, 'q') != NULL)
1569                 Queued = 1;
1570         if (strchr(inputargs, 'r') != NULL)
1571                 Running = 1;
1572         if (strchr(inputargs, 'i') != NULL)
1573                 Interrupted = 1;
1574         if (strchr(inputargs, 'c') != NULL)
1575                 Complete = 1;
1576 
1577         if ((size_t)(Queued + Running + Interrupted + Complete) < strlen(inputargs))
1578                 {
1579                         errortn();
1580                         exit(1);
1581                 }
1582         return;
1583 }
1584 
1585 static void
1586 errortn()
1587 {
1588 
1589 
1590         (void) fprintf(stderr, gettext("\tUsage: %s " USAGE1 "\n"),
1591             Progname);
1592         (void) fprintf(stderr, gettext("or\n\tUsage: %s " USAGE2 "\n"),
1593             Progname);
1594         (void) fprintf(stderr, gettext("or\n\tUsage: %s " USAGE3 "\n"),
1595             Progname);
1596         return;
1597 }