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
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
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]"
48 /* #include "logs.h" */
50 char mach
[15]; /* machine name */
56 short c_age
; /* age of oldest C. file */
57 short x_age
; /* age of oldest X. file */
69 struct userdate userformat
;
70 struct userdate
*friendlyptr
= &userformat
;
73 static int whattodo();
74 static int readperf();
75 static void queuetime();
76 static void xfertime();
79 static void errortn();
80 static void friendlytime();
81 static void complete();
83 static int gnameflck();
84 static void kprocessC();
86 void uprocessC(), printit(), docalc(), procState();
88 static short State
, Queued
, Running
, Complete
, Interrupted
;
90 static char mailmsg
[BUFSIZ
];
91 static char outbuf
[BUFSIZ
+1];
93 static short jobcount
;
95 static char lowerlimit
[MAXDATE
+1], upperlimit
[MAXDATE
+1];
96 static float totalque
, totalxfer
;
97 static long totaljob
, totalbytes
;
98 static long inputsecs
;
100 extern void qsort(); /* qsort(3) and comparison test */
103 extern int machcmp();
104 extern int _age(); /* find the age of a file */
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 */
124 main(argc
, argv
, envp
)
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
];
134 char chkname
[MAXFULLNAME
];
137 char fullpath
[MAXFULLNAME
];
140 char arglist
[MAXSTATE
+1];
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 */
147 (void) textdomain(TEXT_DOMAIN
);
152 Psopt
=Machines
=Summary
=Queue
=Kill
=Rejuvenate
=Uopt
=Sysopt
=Jobcount
=0;
153 execute
=avgqueue
=avgxfer
=Calctime
=Window
=0;
156 /* set calcnum to default time in minutes */
159 (void) strcpy(Progname
, "uustat");
162 guinfo(Uid
, Loginuser
);
164 while ((i
= getopt(argc
, argv
, "acjk:mnpr:qs:u:x:t:d:S:")) != EOF
) {
174 calcnum
= atoi(optarg
);
179 (void) strncpy(Jobid
, optarg
, NAMESIZE
);
180 Jobid
[NAMESIZE
-1] = '\0';
187 Machines
= Summary
= 1;
196 (void) strncpy(Jobid
, optarg
, NAMESIZE
);
197 Jobid
[NAMESIZE
-1] = '\0';
204 (void) strncpy(Rmtname
, optarg
, MAXBASENAME
);
206 Rmtname
[MAXBASENAME
] = '\0';
207 if (versys(Rmtname
)) {
208 fprintf(stderr
, gettext("Invalid system\n"));
215 (void) strncpy(Rmtname
, optarg
, MAXBASENAME
);
216 Rmtname
[MAXBASENAME
] = '\0';
217 if (versys(Rmtname
)) {
218 fprintf(stderr
, gettext("Invalid system\n"));
223 (void) strncpy(User
, optarg
, 8);
225 if(gninfo(User
, &chkid
, chkname
)) {
226 fprintf(stderr
, gettext("Invalid user\n"));
233 Debug
= atoi(optarg
);
238 if (strlen(optarg
) > sizeof (arglist
)) {
243 (void) strlcpy(arglist
, optarg
, sizeof (arglist
));
252 if (argc
!= optind
) {
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
);
263 /* -j only allowed with -s */
264 if (Jobcount
&& !Sysopt
)
269 if ((Calctime
+ Psopt
+ Machines
+ Queue
+ Kill
+ Rejuvenate
+ (Uopt
|Sysopt
|State
)) >1) {
270 /* only -u, -S and -s can be used together */
274 if ((avgqueue
| Window
) & (!Calctime
))
280 if ( !(Calctime
| Kill
| Rejuvenate
| Uopt
| Sysopt
| Queue
| Machines
| State
) ) {
281 (void) strcpy(User
, Loginuser
);
285 if ( nonotf
&& !(Kill
| Rejuvenate
) ) {
290 /*****************************************/
291 /* PROCESS THE OPTIONS */
292 /*****************************************/
294 if (State
&& Complete
)
296 DEBUG(9, "calling complete %d\n",Complete
);
301 count
= readperf(calcnum
);
309 /* do "ps -flp" or pids in LCK files */
311 /* lckpid will not return */
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
)
322 if (fgets(buf
, sizeof(buf
), stdin
) == NULL
)
324 if (getargs(buf
, vec
, 5) < 5)
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? */
341 /* search for LCK machines */
342 char flck
[MAXNAMESIZE
];
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 */
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
++;
364 if (chdir(SPOOL
) != 0 || (spooldir
= opendir(SPOOL
)) == NULL
)
365 exit(101); /* good old code 101 */
367 while (gnamef(spooldir
, f
) == TRUE
) {
368 /* at /var/spool/uucp directory */
369 /* f will contain remote machine names */
371 if (EQUALSN("LCK..", f
, 5))
374 if (*Rmtname
&& !EQUALSN(Rmtname
, f
, MAXBASENAME
))
377 if ( (Kill
|| Rejuvenate
)
378 && (!EQUALSN(f
, Jobid
, strlen(Jobid
)-5)) )
384 (void) sprintf(fullpath
, "%s/%s", SPOOL
, f
);
385 machdir
= opendir(fullpath
);
390 while (gnamef(machdir
, gradef
) == TRUE
) {
391 /* at /var/spool/uucp/remote_name */
392 /* gradef will contain job_grade directory names */
394 if (DIRECTORY(gradef
) && (gradedir
= opendir(gradef
))) {
395 /* at /var/spool/uucp/remote_name/job_grade */
397 while (gnamef(gradedir
, subf
) == TRUE
) {
398 /* subf will contain file names */
399 /* files can be C. or D. or A., etc.. */
401 if (subf
[1] == '.') {
402 if (subf
[0] == CMDPRE
) {
403 /* if file name is C. */
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
);
412 else /* get the age of the C. file */
413 if ( (i
= _age(gradef
, subf
))>m
->c_age
)
421 else if (gradef
[0] == XQTPRE
&& gradef
[1] == '.') {
423 if ( (i
= _age(machdir
, gradef
)) > m
->x_age
)
429 /* cd back to /var/spoool/uucp dir */
430 if (chdir(SPOOL
) != 0)
432 } /* while more files in spooldir */
435 if (Jobcount
&& (jobcount
!= 0))
436 printf("job count = %d\n",jobcount
);
438 /* for Kill or Rejuvenate - will not get here unless it failed */
440 printf(gettext("Can't find Job %s; Not killed\n"), Jobid
);
442 } else if (Rejuvenate
) {
443 printf(gettext("Can't find Job %s; Not rejuvenated\n"), Jobid
);
447 /* Make sure the overflow entry is null since it may be incorrect */
448 M
[UUSTAT_TBL
].mach
[0] = NULLCHAR
;
450 for((sortcnt
= 0, m
= &M
[0]);*(m
->mach
) != NULL
;(sortcnt
++,m
++))
452 qsort((char *)M
, (unsigned int)sortcnt
, sizeof(struct m
), machcmp
);
453 for (m
= M
; m
->mach
[0] != NULLCHAR
; m
++)
461 * uprocessC - get information about C. file
466 uprocessC(machine
, dir
, file
)
467 char *machine
, *dir
, *file
;
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;
479 char format_tmp
[BUFSIZ
+1];
482 /*********************************************/
483 /* initialize output buffer to blanks */
484 /*********************************************/
486 if (Complete
&& !Queued
&& !Running
&& !Interrupted
)
488 outbuf
[0] = NULLCHAR
;
490 DEBUG(9, "uprocessC(%s, ", dir
);
491 DEBUG(9, "%s);\n", file
);
493 if (Jobid
[0] != '\0' && (!EQUALS(Jobid
, &file
[2])) ) {
494 /* kill job - not this one */
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
);
505 fp
= fopen(fullname
, "r");
507 DEBUG(4, "Can't open file (%s), ", fullname
);
508 DEBUG(4, "errno=%d -- skip it!\n", errno
);
511 tp
= localtime(&s
.st_mtime
);
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
);
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
);
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
);
533 if (User
[0] != '\0' && (!EQUALS(User
, user
)) )
539 sprintf(format_tmp
,"%-12s", &file
[2]);
540 (void) strcat(outbuf
, format_tmp
);
542 /* if the job state is requested call the
543 state function to determine this job's state */
547 statefound
= state(dir
, file
);
548 DEBUG(9, "uprocessC: statefound value = %d\n", statefound
);
549 if ((whattodo(statefound
) != TRUE
))
551 outbuf
[0] = NULLCHAR
;
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");
564 sprintf(format_tmp
, " %2.2d/%2.2d-%2.2d:%2.2d ",
565 tp
->tm_mon
+ 1, tp
->tm_mday
, tp
->tm_hour
,
567 (void) strcat(outbuf
, format_tmp
);
571 sprintf(format_tmp
,"%-12s %2.2d/%2.2d-%2.2d:%2.2d ",
572 "", tp
->tm_mon
+ 1, tp
->tm_mday
, tp
->tm_hour
,
574 (void) strcat(outbuf
, format_tmp
);
578 sprintf(format_tmp
,"%s %s ", type
, machine
);
579 (void) strcat(outbuf
, format_tmp
);
582 sprintf(format_tmp
,"%s %s ", user
, file1
);
583 (void) strcat(outbuf
, format_tmp
);
585 else if (file2
[0] != 'X')
587 sprintf(format_tmp
,"%s %ld %s ", user
, fsize(dir
, file3
, file1
), file1
);
588 (void) strcat(outbuf
, format_tmp
);
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");
601 char command
[BUFSIZ
], uline_u
[BUFSIZ
], uline_m
[BUFSIZ
];
602 char retaddr
[BUFSIZ
], *username
;
604 *retaddr
= *uline_u
= *uline_m
= '\0';
605 while (fgets(buf
, BUFSIZ
, xfp
) != NULL
) {
608 strcpy(command
, buf
+ 2);
611 sscanf(buf
+ 2, "%s%s", uline_u
, uline_m
);
614 sscanf(buf
+2, "%s", retaddr
);
619 if (*uline_u
!= '\0')
621 if (*retaddr
!= '\0')
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
);
629 strcat(outbuf
, "\n");
630 fputs(outbuf
, stdout
);
631 outbuf
[0] = NULLCHAR
;
633 } /* end of while more data in buffer */
635 /* successful processing of a job, increment job count
647 * whattodo - determine what to do with current C dot file
648 * depending on any combination (2**3 - 1) of input
655 /* Maybe some commentary here will help explain this truth
658 Queued |Running |Interrupted
659 -------------------------------------------------
661 -------------------------------------------------
663 -------------------------------------------------
665 -------------------------------------------------
667 -------------------------------------------------
669 -------------------------------------------------
671 -------------------------------------------------
673 -------------------------------------------------
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!
682 if (Queued
&& Running
&& Interrupted
)
684 else if ((Queued
&& !Running
&& !Interrupted
) && (inputint
== 1))
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))
691 else if ((!Queued
&& Running
&& Interrupted
) &&
692 (inputint
== 2 || inputint
== 3))
694 else if ((Queued
&& !Running
&& Interrupted
) &&
695 (inputint
==1 || inputint
== 3))
700 * kprocessC - process kill or rejuvenate job
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];
714 struct utimbuf times
;
718 DEBUG(9, "kprocessC(%s, ", dir
);
719 DEBUG(9, "%s);\n", file
);
721 if ((!EQUALS(Jobid
, &file
[2])) ) {
722 /* kill job - not this one */
726 (void) sprintf(fullname
, "%s/%s", dir
, file
);
727 if (stat(fullname
, &s
) != 0) {
728 /* error - can't stat */
731 gettext("Can't stat:%s, errno (%d)--can't kill it!\n"),
735 gettext("Can't stat:%s, errno (%d)--can't rejuvenate it!\n"),
741 fp
= fopen(fullname
, "r");
745 gettext("Can't read:%s, errno (%d)--can't kill it!\n"),
749 gettext("Can't read:%s, errno (%d)--can't rejuvenate it!\n"),
755 times
.actime
= times
.modtime
= time((time_t *)NULL
);
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) {
762 gettext("Bad format:%s, errno (%d)--can't kill it!\n"),
766 gettext("Bad format:%s, errno (%d)--can't rejuvenate it!\n"),
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
);
782 if ((access(fullname
, 02) != 0)
783 && !PREFIX(Loginuser
, user
)
784 && !PREFIX(user
, Loginuser
) ) {
785 /* not allowed - not owner or root */
787 fprintf(stderr
, gettext("Not owner,"
788 " uucp or root - can't kill job %s\n"), Jobid
);
790 fprintf(stderr
, gettext("Not owner, uucp or root -"
791 " can't rejuvenate job %s\n"), Jobid
);
798 (void) sprintf(rfullname
, "%s/%s", dir
, file3
);
799 DEBUG(4, "Remove %s\n", rfullname
);
801 ret
= unlink(rfullname
);
802 else /* Rejuvenate */
803 ret
= utime(rfullname
, ×
);
804 if (ret
!= 0 && errno
!= ENOENT
) {
805 /* program error?? */
807 fprintf(stderr
, gettext("Error: Can't kill,"
808 " File (%s), errno (%d)\n"), rfullname
, errno
);
810 fprintf(stderr
, gettext("Error: Can't rejuvenated,"
811 " File (%s), errno (%d)\n"), rfullname
, errno
);
816 DEBUG(4, "Remove %s\n", fullname
);
818 ret
= unlink(fullname
);
819 else /* Rejuvenate */
820 ret
= utime(fullname
, ×
);
823 /* program error?? */
825 fprintf(stderr
, gettext("Error1: Can't kill,"
826 " File (%s), errno (%d)\n"), fullname
, errno
);
828 fprintf(stderr
, gettext("Error1: Can't rejuvenate,"
829 " File (%s), errno (%d)\n"), fullname
, errno
);
832 /* if kill done by SA then send user mail */
833 else if (!EQUALS(Loginuser
, user
))
835 sprintf(mailmsg
, "%s %s", KILLMSG
, Jobid
);
836 mailst(user
, "job killed", mailmsg
, "", "");
841 printf(gettext("Job: %s successfully killed\n"), Jobid
);
843 printf(gettext("Job: %s successfully rejuvenated\n"),
850 * fsize - return the size of f1 or f2 (if f1 does not exist)
851 * f1 is the local name
860 char fullname
[BUFSIZ
];
862 (void) sprintf(fullname
, "%s/%s", dir
, f1
);
863 if (stat(fullname
, &s
) == 0) {
866 if (stat(f2
, &s
) == 0) {
874 void logent(){} /* to load ulockf.c */
875 void systat(){} /* to load utility.c */
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
);
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
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
,
905 (void) fprintf(stderr
,
906 gettext("WARNING: Table Overflow--output not complete\n"));
909 /* use the last entry - overwrite it */
913 (void) strcpy(m
->mach
, name
);
914 m
->c_age
= m
->x_age
= m
->lasttime
= m
->locked
= m
->ccount
= m
->xcount
= 0;
926 extern struct tm
*localtime();
930 /*&& m->stst[0] == '\0'*/
935 printf("%-10s", m
->mach
);
938 printf("%3dC", m
->ccount
);
942 printf("(%d)", m
->c_age
);
946 printf("%3dX", m
->xcount
);
950 printf("(%d) ", m
->x_age
);
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
,
962 /* if (m->locked && m->type != SS_INPROGRESS) */
965 if (m
->stst
[0] != '\0') {
966 printf("%s", m
->stst
);
969 case SS_LOGIN_FAILED
:
973 case SS_CANT_ACCESS_DEVICE
:
974 case SS_DEVICE_FAILED
:
979 case SS_UNKNOWN_RESPONSE
:
983 t
= m
->retrytime
- (t
- m
->lasttime
);
985 minimum
= (t
+ 59) / 60;
986 printf("Retry: %d:%2.2d", minimum
/60, minimum
%60);
989 printf(" Count: %d", m
->count
);
996 #define MAXLOCKS 100 /* Maximum number of lock files this will handle */
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
];
1009 DEBUG(9, "lckpid() - entered\n%s", "");
1010 for (i
=0; i
<MAXLOCKS
; i
++)
1012 (void) strcpy(lckdir
, LOCKPRE
);
1013 *strrchr(lckdir
, '/') = '\0';
1014 DEBUG(9, "lockdir (%s)\n", lckdir
);
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)) {
1024 fd
= open(f
, O_RDONLY
);
1026 ret
= read(fd
, alpid
, SIZEOFPID
+2); /* +2 for '\n' and null */
1027 pid
= strtol(alpid
, (char **) NULL
, 10);
1030 printf("%ld\n", (long) pid
);
1031 for(i
=0; i
<MAXLOCKS
; i
++) {
1034 if (list
[i
] == -1) {
1046 for (i
=0; i
<MAXLOCKS
; i
++) {
1049 (void) sprintf(&buf
[strlen(buf
)], "%d ", list
[i
]);
1054 execl("/bin/ps", "uustat-ps", buf
, (char *) 0);
1056 execl("/usr/bin/ps", "ps", "-flp", buf
, (char *) 0);
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
1067 * FALSE -> end of directory read
1068 * TRUE -> returned name
1071 gnameflck(p
, filename
)
1075 struct dirent dentry
;
1076 struct dirent
*dp
= &dentry
;
1079 if ((dp
= readdir(p
)) == NULL
)
1081 if (dp
->d_ino
!= 0 && dp
->d_name
[0] != '.')
1085 (void) strncpy(filename
, dp
->d_name
, MAXNAMESIZE
-1);
1086 filename
[MAXNAMESIZE
-1] = '\0';
1094 return(strcmp(((struct m
*) a
)->mach
,((struct m
*) b
)->mach
));
1097 static long _sec_per_day
= 86400L;
1100 * _age - find the age of "file" in days
1108 char * file
; /* the file name */
1109 char * dir
; /* system spool directory */
1111 char fullname
[MAXFULLNAME
];
1112 static time_t ptime
= 0;
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
));
1125 /* Function: complete - find and print jobids of completed jobs for
1128 * Look thru the /var/uucp/.Admin/account file (if present)
1129 * for all jobs initiated by user and print.
1133 * Username - user that initiated uustat request
1142 /* Function name: complete
1143 Author: Roland T. Conwell
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
1154 char accno
[15], jobid
[15], system
[15], loginame
[15], time
[20], dest
[15];
1156 char grade
[2], jgrade
[2];
1160 fp
= fopen(ACCOUNT
, "r");
1163 fprintf(stderr
, gettext("Can't open account log\n"));
1166 while (fgets(abuf
, BUFSIZ
, fp
) != NULL
)
1169 x
= sscanf(abuf
, "%s%s%s%s%s%s%s%s%s%s",
1170 accno
,jobid
, size
, status
, grade
, jgrade
, system
, loginame
,
1175 if (!EQUALS(status
, "C"))
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
);
1189 if (*Rmtname
&& !EQUALS(Rmtname
, dest
))
1191 if (*User
&& !EQUALS(User
, loginame
))
1195 if (EQUALS(Loginuser
, loginame
))
1197 printf("%s completed\n",jobid
);
1203 printf("%s completed\n", jobid
);
1211 /* Function: state - determine if Cdotfile is queued or running
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.
1222 * jcdir - the job grade directory to search
1223 * cdotfile - the Cdotfile whose state is to be determined
1229 state(jcdir
, cdotfile
)
1230 char *jcdir
, *cdotfile
;
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
;
1240 sjcdir
= opendir(jcdir
);
1244 while (gnamef(sjcdir
, comparef
) == TRUE
) {
1245 if (comparef
[0] == 'A') {
1247 (void) strcpy(afile
, comparef
);
1248 *strchr(afile
, 'A') = ' ';
1249 (void) strcpy(cfile
, cdotfile
);
1250 *strchr(cfile
, 'C') = ' ';
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 */
1259 (void) strcpy(lckdir
, LOCKPRE
);
1260 *strrchr(lckdir
, '/') = '\0';
1261 /* open lock directory */
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
)
1269 DEBUG(9, "STATE: lockfile = %s\n",lckfile
);
1270 if (EQUALS(lockname
, lckfile
))
1281 /* got adot, cdot and lock file */
1283 if (Running
&& foundlck
)
1285 else if (Interrupted
&& CequalA
&& !foundlck
)
1287 else if (Queued
&& !CequalA
&& !foundlck
)
1289 DEBUG(9, "STATE: returning with value %d\n",rtnstate
);
1292 } /* end of state.c */
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
;
1307 time_t t_time
, t_starttime
, t_upperlimit
;
1310 static float rst
, ust
, kst
, xferrate
, utt
, ktt
;
1311 static float rtt
, wfield
, xfield
, yfield
;
1313 struct perfrec
*recptr
;
1319 char *strptr
, *startime
;
1322 totalxfer
=totalbytes
=recordcnt
=totaljob
=totalque
=0;
1323 lowerlimit
[0] = '\0';
1324 upperlimit
[0] = '\0';
1327 inputsecs
= convert(timerange
);
1329 strncpy(lowerlimit
, startime
, MAXDATE
);
1330 strncpy(upperlimit
, gmt(), MAXDATE
);
1332 /* convert lowerlimit and upperlimit to HH:MM format */
1333 friendlytime(lowerlimit
, upperlimit
);
1335 fp
= fopen(PERFLOG
, "r");
1338 (void) fprintf(stderr
, gettext("Can't open performance log\n"));
1343 while (fgets(abuf
, BUFSIZ
, fp
) != NULL
)
1345 DEBUG(9, "READPERF: abuf before = %s\n",abuf
);
1347 if (!EQUALSN(abuf
, "xfer", 4))
1350 /* convert all '|'s to blanks for sscanf */
1351 for (strptr
= abuf
; *strptr
!= '\0'; strptr
++)
1354 DEBUG(9, "READPERF: abuf = %s\n",abuf
);
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
,
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
);
1373 if (!EQUALS(Rmtname
, remote
))
1376 if (!EQUALS(role
, "M"))
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
);
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
);
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
)
1400 totalque
= totalque
+ queuetime
;
1401 totalxfer
= totalxfer
+ xferrate
;
1402 totalbytes
= totalbytes
+ size
;
1403 recordcnt
= recordcnt
+ 1;
1404 DEBUG(9, " processing recordcnt %d\n", recordcnt
);
1406 DEBUG(9, "END step 1 %d\n", recordcnt
);
1408 DEBUG(9, "END step 2 recordcnt %d\n", recordcnt
);
1414 } /* end of readperf */
1432 outtime
= intime
* 60;
1439 static double avgqtime
;
1441 avgqtime
= totalque
/ totaljob
;
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
);
1452 static double avgxrate
;
1454 avgxrate
= totalbytes
/ totalxfer
;
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
);
1462 * Local Function: gmts - Generate Start Time String
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.
1474 * An address of a static character array containing the date.
1480 static char date
[] = "YYMMDDhhmmss";
1483 time_t now
; /* Current time. */
1485 now
= time((time_t *) 0);
1487 /* inputsecs is declared global to this file */
1488 DEBUG(9, "GMTS: now = %ld\n", now
);
1489 DEBUG(9, "GMTS: inputsecs = %ld\n", inputsecs
);
1491 temp
= (now
- inputsecs
);
1493 (void) sprintf(date
, "%02d%02d%02d%02d%02d%02d",
1494 (td
->tm_year
% 100),
1505 * Local Function: gmt - Generate Current Time String
1507 * This function returns the address to a string containing the current
1508 * GMT in the form YYMMDDhhmmss.
1516 * An address of a static character array containing the date.
1522 static char date
[] = "YYMMDDhhmmss";
1525 time_t now
; /* Current time. */
1527 now
= time((time_t *) 0);
1529 (void) sprintf(date
, "%02d%02d%02d%02d%02d%02d",
1530 (td
->tm_year
% 100),
1541 friendlytime(uplimit
, lolimit
)
1542 char *uplimit
, *lolimit
;
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);
1557 friendlyptr
->uhour
[2] = '\0';
1558 friendlyptr
->lhour
[2] = '\0';
1559 friendlyptr
->umin
[2] = '\0';
1560 friendlyptr
->lmin
[2] = '\0';
1565 procState(inputargs
)
1568 if (strchr(inputargs
, 'q') != NULL
)
1570 if (strchr(inputargs
, 'r') != NULL
)
1572 if (strchr(inputargs
, 'i') != NULL
)
1574 if (strchr(inputargs
, 'c') != NULL
)
1577 if ((size_t)(Queued
+ Running
+ Interrupted
+ Complete
) < strlen(inputargs
))
1590 (void) fprintf(stderr
, gettext("\tUsage: %s " USAGE1
"\n"),
1592 (void) fprintf(stderr
, gettext("or\n\tUsage: %s " USAGE2
"\n"),
1594 (void) fprintf(stderr
, gettext("or\n\tUsage: %s " USAGE3
"\n"),