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 */
36 #define KILLMSG "the system administrator has killed job"
37 #define USAGE1 "[-q] | [-m] | [-k JOB [-n]] | [-r JOB [-n]] | [-p]"
38 #define USAGE2 "[-a] [-s SYSTEM [-j]] [-u USER] [-S STATE]"
39 #define USAGE3 "-t SYSTEM [-d number] [-c]"
47 /* #include "logs.h" */
49 char mach
[15]; /* machine name */
55 short c_age
; /* age of oldest C. file */
56 short x_age
; /* age of oldest X. file */
68 struct userdate userformat
;
69 struct userdate
*friendlyptr
= &userformat
;
72 static int whattodo();
73 static int readperf();
74 static void queuetime();
75 static void xfertime();
78 static void errortn();
79 static void friendlytime();
80 static void complete();
82 static int gnameflck();
83 static void kprocessC();
85 void uprocessC(), printit(), docalc(), procState();
87 static short State
, Queued
, Running
, Complete
, Interrupted
;
89 static char mailmsg
[BUFSIZ
];
90 static char outbuf
[BUFSIZ
+1];
92 static short jobcount
;
94 static char lowerlimit
[MAXDATE
+1], upperlimit
[MAXDATE
+1];
95 static float totalque
, totalxfer
;
96 static long totaljob
, totalbytes
;
97 static long inputsecs
;
99 extern void qsort(); /* qsort(3) and comparison test */
102 extern int machcmp();
103 extern int _age(); /* find the age of a file */
105 extern char Jobid
[]; /* jobid for status or kill option */
106 short Kill
; /* == 1 if -k specified */
107 short Rejuvenate
; /* == 1 for -r specified */
108 short Uopt
; /* == 1 if -u option specified */
109 short Sysopt
; /* == 1 if -s option specified */
110 static short Calctime
; /* == 1 if -t parameter set */
111 short Summary
; /* == 1 if -q or -m is specified */
112 short Queue
; /* == 1 if -q option set - queue summary */
113 short Machines
; /* == 1 if -m option set - machines summary */
114 short Psopt
; /* == 1 if -p option set - output "ps" of LCK pids */
115 static short Window
; /* == 1 if -d parameter set with -t option */
116 static short nonotf
; /* == 1 if -n parameter set with -k option */
117 short avgqueue
; /* == 1 if -c parameter set with -t option */
118 short avgxfer
; /* will be set to 1 if -c not specified */
119 short Jobcount
; /* == 1 if -j parameter set with -s option */
123 main(argc
, argv
, envp
)
127 struct m
*m
, *machine();
128 DIR *spooldir
, *subdir
, *machdir
, *gradedir
;
129 char *str
, *rindex();
130 char subf
[256], gradef
[256];
131 char *c
, lckdir
[BUFSIZ
];
133 char chkname
[MAXFULLNAME
];
136 char fullpath
[MAXFULLNAME
];
139 char arglist
[MAXSTATE
+1];
141 /* Set locale environment variables local definitions */
142 (void) setlocale(LC_ALL
, "");
143 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
144 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
146 (void) textdomain(TEXT_DOMAIN
);
151 Psopt
=Machines
=Summary
=Queue
=Kill
=Rejuvenate
=Uopt
=Sysopt
=Jobcount
=0;
152 execute
=avgqueue
=avgxfer
=Calctime
=Window
=0;
155 /* set calcnum to default time in minutes */
158 (void) strcpy(Progname
, "uustat");
161 guinfo(Uid
, Loginuser
);
163 while ((i
= getopt(argc
, argv
, "acjk:mnpr:qs:u:x:t:d:S:")) != EOF
) {
173 calcnum
= atoi(optarg
);
178 (void) strncpy(Jobid
, optarg
, NAMESIZE
);
179 Jobid
[NAMESIZE
-1] = '\0';
186 Machines
= Summary
= 1;
195 (void) strncpy(Jobid
, optarg
, NAMESIZE
);
196 Jobid
[NAMESIZE
-1] = '\0';
203 (void) strncpy(Rmtname
, optarg
, MAXBASENAME
);
205 Rmtname
[MAXBASENAME
] = '\0';
206 if (versys(Rmtname
)) {
207 fprintf(stderr
, gettext("Invalid system\n"));
214 (void) strncpy(Rmtname
, optarg
, MAXBASENAME
);
215 Rmtname
[MAXBASENAME
] = '\0';
216 if (versys(Rmtname
)) {
217 fprintf(stderr
, gettext("Invalid system\n"));
222 (void) strncpy(User
, optarg
, 8);
224 if(gninfo(User
, &chkid
, chkname
)) {
225 fprintf(stderr
, gettext("Invalid user\n"));
232 Debug
= atoi(optarg
);
237 if (strlen(optarg
) > sizeof (arglist
)) {
242 (void) strlcpy(arglist
, optarg
, sizeof (arglist
));
251 if (argc
!= optind
) {
256 DEBUG(9, "Progname (%s): STARTED\n", Progname
);
257 DEBUG(9, "User=%s, ", User
);
258 DEBUG(9, "Loginuser=%s, ", Loginuser
);
259 DEBUG(9, "Jobid=%s, ", Jobid
);
260 DEBUG(9, "Rmtname=%s\n", Rmtname
);
262 /* -j only allowed with -s */
263 if (Jobcount
&& !Sysopt
)
268 if ((Calctime
+ Psopt
+ Machines
+ Queue
+ Kill
+ Rejuvenate
+ (Uopt
|Sysopt
|State
)) >1) {
269 /* only -u, -S and -s can be used together */
273 if ((avgqueue
| Window
) & (!Calctime
))
279 if ( !(Calctime
| Kill
| Rejuvenate
| Uopt
| Sysopt
| Queue
| Machines
| State
) ) {
280 (void) strcpy(User
, Loginuser
);
284 if ( nonotf
&& !(Kill
| Rejuvenate
) ) {
289 /*****************************************/
290 /* PROCESS THE OPTIONS */
291 /*****************************************/
293 if (State
&& Complete
)
295 DEBUG(9, "calling complete %d\n",Complete
);
300 count
= readperf(calcnum
);
308 /* do "ps -flp" or pids in LCK files */
310 /* lckpid will not return */
314 /* Gather data for Summary option report */
315 if (chdir(STATDIR
) || (spooldir
= opendir(STATDIR
)) == NULL
)
316 exit(101); /* good old code 101 */
317 while (gnamef(spooldir
, f
) == TRUE
) {
318 if (freopen(f
, "r", stdin
) == NULL
)
321 if (fgets(buf
, sizeof(buf
), stdin
) == NULL
)
323 if (getargs(buf
, vec
, 5) < 5)
325 m
->type
= atoi(vec
[0]);
326 m
->count
= atoi(vec
[1]);
327 m
->lasttime
= atol(vec
[2]);
328 m
->retrytime
= atol(vec
[3]);
329 (void) strncpy(m
->stst
, vec
[4], STST_MAX
);
330 str
= rindex(m
->stst
, ' ');
331 (void) machine(++str
); /* longer name? */
340 /* search for LCK machines */
341 char flck
[MAXNAMESIZE
];
343 (void) strcpy(lckdir
, LOCKPRE
);
344 *strrchr(lckdir
, '/') = '\0';
345 /* open lock directory */
346 if (chdir(lckdir
) != 0 || (subdir
= opendir(lckdir
)) == NULL
)
347 exit(101); /* good old code 101 */
349 while (gnameflck(subdir
, flck
) == TRUE
) {
350 /* XXX - this is disgusting... */
351 if (EQUALSN("LCK..", flck
, 5)) {
352 if (!EQUALSN(flck
+ 5, "cul", 3)
353 && !EQUALSN(flck
+ 5, "cua", 3)
354 && !EQUALSN(flck
+ 5, "tty", 3)
355 && !EQUALSN(flck
+ 5, "dtsw", 4)
356 && !EQUALSN(flck
+ 5, "vadic", 5)
357 && !EQUALSN(flck
+ 5, "micom", 5))
358 machine(flck
+ 5)->locked
++;
363 if (chdir(SPOOL
) != 0 || (spooldir
= opendir(SPOOL
)) == NULL
)
364 exit(101); /* good old code 101 */
366 while (gnamef(spooldir
, f
) == TRUE
) {
367 /* at /var/spool/uucp directory */
368 /* f will contain remote machine names */
370 if (EQUALSN("LCK..", f
, 5))
373 if (*Rmtname
&& !EQUALSN(Rmtname
, f
, MAXBASENAME
))
376 if ( (Kill
|| Rejuvenate
)
377 && (!EQUALSN(f
, Jobid
, strlen(Jobid
)-5)) )
383 (void) sprintf(fullpath
, "%s/%s", SPOOL
, f
);
384 machdir
= opendir(fullpath
);
389 while (gnamef(machdir
, gradef
) == TRUE
) {
390 /* at /var/spool/uucp/remote_name */
391 /* gradef will contain job_grade directory names */
393 if (DIRECTORY(gradef
) && (gradedir
= opendir(gradef
))) {
394 /* at /var/spool/uucp/remote_name/job_grade */
396 while (gnamef(gradedir
, subf
) == TRUE
) {
397 /* subf will contain file names */
398 /* files can be C. or D. or A., etc.. */
400 if (subf
[1] == '.') {
401 if (subf
[0] == CMDPRE
) {
402 /* if file name is C. */
405 if (Kill
|| Rejuvenate
)
406 kprocessC(gradef
, subf
);
407 else if (Uopt
| Sysopt
| Queued
| Running
| Interrupted
)
408 /* go print out C. file info */
409 uprocessC(f
,gradef
, subf
);
411 else /* get the age of the C. file */
412 if ( (i
= _age(gradef
, subf
))>m
->c_age
)
420 else if (gradef
[0] == XQTPRE
&& gradef
[1] == '.') {
422 if ( (i
= _age(machdir
, gradef
)) > m
->x_age
)
428 /* cd back to /var/spoool/uucp dir */
429 if (chdir(SPOOL
) != 0)
431 } /* while more files in spooldir */
434 if (Jobcount
&& (jobcount
!= 0))
435 printf("job count = %d\n",jobcount
);
437 /* for Kill or Rejuvenate - will not get here unless it failed */
439 printf(gettext("Can't find Job %s; Not killed\n"), Jobid
);
441 } else if (Rejuvenate
) {
442 printf(gettext("Can't find Job %s; Not rejuvenated\n"), Jobid
);
446 /* Make sure the overflow entry is null since it may be incorrect */
447 M
[UUSTAT_TBL
].mach
[0] = NULLCHAR
;
449 for((sortcnt
= 0, m
= &M
[0]);*(m
->mach
) != NULLCHAR
;(sortcnt
++,m
++))
451 qsort((char *)M
, (unsigned int)sortcnt
, sizeof(struct m
), machcmp
);
452 for (m
= M
; m
->mach
[0] != NULLCHAR
; m
++)
460 * uprocessC - get information about C. file
465 uprocessC(machine
, dir
, file
)
466 char *machine
, *dir
, *file
;
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;
478 char format_tmp
[BUFSIZ
+1];
481 /*********************************************/
482 /* initialize output buffer to blanks */
483 /*********************************************/
485 if (Complete
&& !Queued
&& !Running
&& !Interrupted
)
487 outbuf
[0] = NULLCHAR
;
489 DEBUG(9, "uprocessC(%s, ", dir
);
490 DEBUG(9, "%s);\n", file
);
492 if (Jobid
[0] != '\0' && (!EQUALS(Jobid
, &file
[2])) ) {
493 /* kill job - not this one */
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
);
504 fp
= fopen(fullname
, "r");
506 DEBUG(4, "Can't open file (%s), ", fullname
);
507 DEBUG(4, "errno=%d -- skip it!\n", errno
);
510 tp
= localtime(&s
.st_mtime
);
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
);
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
);
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
);
532 if (User
[0] != '\0' && (!EQUALS(User
, user
)) )
538 sprintf(format_tmp
,"%-12s", &file
[2]);
539 (void) strcat(outbuf
, format_tmp
);
541 /* if the job state is requested call the
542 state function to determine this job's state */
546 statefound
= state(dir
, file
);
547 DEBUG(9, "uprocessC: statefound value = %d\n", statefound
);
548 if ((whattodo(statefound
) != TRUE
))
550 outbuf
[0] = NULLCHAR
;
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");
563 sprintf(format_tmp
, " %2.2d/%2.2d-%2.2d:%2.2d ",
564 tp
->tm_mon
+ 1, tp
->tm_mday
, tp
->tm_hour
,
566 (void) strcat(outbuf
, format_tmp
);
570 sprintf(format_tmp
,"%-12s %2.2d/%2.2d-%2.2d:%2.2d ",
571 "", tp
->tm_mon
+ 1, tp
->tm_mday
, tp
->tm_hour
,
573 (void) strcat(outbuf
, format_tmp
);
577 sprintf(format_tmp
,"%s %s ", type
, machine
);
578 (void) strcat(outbuf
, format_tmp
);
581 sprintf(format_tmp
,"%s %s ", user
, file1
);
582 (void) strcat(outbuf
, format_tmp
);
584 else if (file2
[0] != 'X')
586 sprintf(format_tmp
,"%s %ld %s ", user
, fsize(dir
, file3
, file1
), file1
);
587 (void) strcat(outbuf
, format_tmp
);
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");
600 char command
[BUFSIZ
], uline_u
[BUFSIZ
], uline_m
[BUFSIZ
];
601 char retaddr
[BUFSIZ
], *username
;
603 *retaddr
= *uline_u
= *uline_m
= '\0';
604 while (fgets(buf
, BUFSIZ
, xfp
) != NULL
) {
607 strcpy(command
, buf
+ 2);
610 sscanf(buf
+ 2, "%s%s", uline_u
, uline_m
);
613 sscanf(buf
+2, "%s", retaddr
);
618 if (*uline_u
!= '\0')
620 if (*retaddr
!= '\0')
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
);
628 strcat(outbuf
, "\n");
629 fputs(outbuf
, stdout
);
630 outbuf
[0] = NULLCHAR
;
632 } /* end of while more data in buffer */
634 /* successful processing of a job, increment job count
646 * whattodo - determine what to do with current C dot file
647 * depending on any combination (2**3 - 1) of input
654 /* Maybe some commentary here will help explain this truth
657 Queued |Running |Interrupted
658 -------------------------------------------------
660 -------------------------------------------------
662 -------------------------------------------------
664 -------------------------------------------------
666 -------------------------------------------------
668 -------------------------------------------------
670 -------------------------------------------------
672 -------------------------------------------------
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!
681 if (Queued
&& Running
&& Interrupted
)
683 else if ((Queued
&& !Running
&& !Interrupted
) && (inputint
== 1))
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))
690 else if ((!Queued
&& Running
&& Interrupted
) &&
691 (inputint
== 2 || inputint
== 3))
693 else if ((Queued
&& !Running
&& Interrupted
) &&
694 (inputint
==1 || inputint
== 3))
699 * kprocessC - process kill or rejuvenate job
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];
713 struct utimbuf times
;
717 DEBUG(9, "kprocessC(%s, ", dir
);
718 DEBUG(9, "%s);\n", file
);
720 if ((!EQUALS(Jobid
, &file
[2])) ) {
721 /* kill job - not this one */
725 (void) sprintf(fullname
, "%s/%s", dir
, file
);
726 if (stat(fullname
, &s
) != 0) {
727 /* error - can't stat */
730 gettext("Can't stat:%s, errno (%d)--can't kill it!\n"),
734 gettext("Can't stat:%s, errno (%d)--can't rejuvenate it!\n"),
740 fp
= fopen(fullname
, "r");
744 gettext("Can't read:%s, errno (%d)--can't kill it!\n"),
748 gettext("Can't read:%s, errno (%d)--can't rejuvenate it!\n"),
754 times
.actime
= times
.modtime
= time(NULL
);
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) {
761 gettext("Bad format:%s, errno (%d)--can't kill it!\n"),
765 gettext("Bad format:%s, errno (%d)--can't rejuvenate it!\n"),
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
);
781 if ((access(fullname
, 02) != 0)
782 && !PREFIX(Loginuser
, user
)
783 && !PREFIX(user
, Loginuser
) ) {
784 /* not allowed - not owner or root */
786 fprintf(stderr
, gettext("Not owner,"
787 " uucp or root - can't kill job %s\n"), Jobid
);
789 fprintf(stderr
, gettext("Not owner, uucp or root -"
790 " can't rejuvenate job %s\n"), Jobid
);
797 (void) sprintf(rfullname
, "%s/%s", dir
, file3
);
798 DEBUG(4, "Remove %s\n", rfullname
);
800 ret
= unlink(rfullname
);
801 else /* Rejuvenate */
802 ret
= utime(rfullname
, ×
);
803 if (ret
!= 0 && errno
!= ENOENT
) {
804 /* program error?? */
806 fprintf(stderr
, gettext("Error: Can't kill,"
807 " File (%s), errno (%d)\n"), rfullname
, errno
);
809 fprintf(stderr
, gettext("Error: Can't rejuvenated,"
810 " File (%s), errno (%d)\n"), rfullname
, errno
);
815 DEBUG(4, "Remove %s\n", fullname
);
817 ret
= unlink(fullname
);
818 else /* Rejuvenate */
819 ret
= utime(fullname
, ×
);
822 /* program error?? */
824 fprintf(stderr
, gettext("Error1: Can't kill,"
825 " File (%s), errno (%d)\n"), fullname
, errno
);
827 fprintf(stderr
, gettext("Error1: Can't rejuvenate,"
828 " File (%s), errno (%d)\n"), fullname
, errno
);
831 /* if kill done by SA then send user mail */
832 else if (!EQUALS(Loginuser
, user
))
834 sprintf(mailmsg
, "%s %s", KILLMSG
, Jobid
);
835 mailst(user
, "job killed", mailmsg
, "", "");
840 printf(gettext("Job: %s successfully killed\n"), Jobid
);
842 printf(gettext("Job: %s successfully rejuvenated\n"),
849 * fsize - return the size of f1 or f2 (if f1 does not exist)
850 * f1 is the local name
859 char fullname
[BUFSIZ
];
861 (void) sprintf(fullname
, "%s/%s", dir
, f1
);
862 if (stat(fullname
, &s
) == 0) {
865 if (stat(f2
, &s
) == 0) {
873 void logent(){} /* to load ulockf.c */
874 void systat(){} /* to load utility.c */
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
);
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
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
,
904 (void) fprintf(stderr
,
905 gettext("WARNING: Table Overflow--output not complete\n"));
908 /* use the last entry - overwrite it */
912 (void) strcpy(m
->mach
, name
);
913 m
->c_age
= m
->x_age
= m
->lasttime
= m
->locked
= m
->ccount
= m
->xcount
= 0;
925 extern struct tm
*localtime();
929 /*&& m->stst[0] == '\0'*/
934 printf("%-10s", m
->mach
);
937 printf("%3dC", m
->ccount
);
941 printf("(%d)", m
->c_age
);
945 printf("%3dX", m
->xcount
);
949 printf("(%d) ", m
->x_age
);
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
,
961 /* if (m->locked && m->type != SS_INPROGRESS) */
964 if (m
->stst
[0] != '\0') {
965 printf("%s", m
->stst
);
968 case SS_LOGIN_FAILED
:
972 case SS_CANT_ACCESS_DEVICE
:
973 case SS_DEVICE_FAILED
:
978 case SS_UNKNOWN_RESPONSE
:
982 t
= m
->retrytime
- (t
- m
->lasttime
);
984 minimum
= (t
+ 59) / 60;
985 printf("Retry: %d:%2.2d", minimum
/60, minimum
%60);
988 printf(" Count: %d", m
->count
);
995 #define MAXLOCKS 100 /* Maximum number of lock files this will handle */
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
];
1008 DEBUG(9, "lckpid() - entered\n%s", "");
1009 for (i
=0; i
<MAXLOCKS
; i
++)
1011 (void) strcpy(lckdir
, LOCKPRE
);
1012 *strrchr(lckdir
, '/') = '\0';
1013 DEBUG(9, "lockdir (%s)\n", lckdir
);
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)) {
1023 fd
= open(f
, O_RDONLY
);
1025 ret
= read(fd
, alpid
, SIZEOFPID
+2); /* +2 for '\n' and null */
1026 pid
= strtol(alpid
, (char **) NULL
, 10);
1029 printf("%ld\n", (long) pid
);
1030 for(i
=0; i
<MAXLOCKS
; i
++) {
1033 if (list
[i
] == -1) {
1045 for (i
=0; i
<MAXLOCKS
; i
++) {
1048 (void) sprintf(&buf
[strlen(buf
)], "%d ", list
[i
]);
1053 execl("/bin/ps", "uustat-ps", buf
, (char *) 0);
1055 execl("/usr/bin/ps", "ps", "-flp", buf
, (char *) 0);
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
1066 * FALSE -> end of directory read
1067 * TRUE -> returned name
1070 gnameflck(p
, filename
)
1074 struct dirent dentry
;
1075 struct dirent
*dp
= &dentry
;
1078 if ((dp
= readdir(p
)) == NULL
)
1080 if (dp
->d_ino
!= 0 && dp
->d_name
[0] != '.')
1084 (void) strncpy(filename
, dp
->d_name
, MAXNAMESIZE
-1);
1085 filename
[MAXNAMESIZE
-1] = '\0';
1093 return(strcmp(((struct m
*) a
)->mach
,((struct m
*) b
)->mach
));
1096 static long _sec_per_day
= 86400L;
1099 * _age - find the age of "file" in days
1107 char * file
; /* the file name */
1108 char * dir
; /* system spool directory */
1110 char fullname
[MAXFULLNAME
];
1111 static time_t ptime
= 0;
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
));
1124 /* Function: complete - find and print jobids of completed jobs for
1127 * Look thru the /var/uucp/.Admin/account file (if present)
1128 * for all jobs initiated by user and print.
1132 * Username - user that initiated uustat request
1141 /* Function name: complete
1142 Author: Roland T. Conwell
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
1153 char accno
[15], jobid
[15], system
[15], loginame
[15], time
[20], dest
[15];
1155 char grade
[2], jgrade
[2];
1159 fp
= fopen(ACCOUNT
, "r");
1162 fprintf(stderr
, gettext("Can't open account log\n"));
1165 while (fgets(abuf
, BUFSIZ
, fp
) != NULL
)
1168 x
= sscanf(abuf
, "%s%s%s%s%s%s%s%s%s%s",
1169 accno
,jobid
, size
, status
, grade
, jgrade
, system
, loginame
,
1174 if (!EQUALS(status
, "C"))
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
);
1188 if (*Rmtname
&& !EQUALS(Rmtname
, dest
))
1190 if (*User
&& !EQUALS(User
, loginame
))
1194 if (EQUALS(Loginuser
, loginame
))
1196 printf("%s completed\n",jobid
);
1202 printf("%s completed\n", jobid
);
1210 /* Function: state - determine if Cdotfile is queued or running
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.
1221 * jcdir - the job grade directory to search
1222 * cdotfile - the Cdotfile whose state is to be determined
1228 state(jcdir
, cdotfile
)
1229 char *jcdir
, *cdotfile
;
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
;
1239 sjcdir
= opendir(jcdir
);
1243 while (gnamef(sjcdir
, comparef
) == TRUE
) {
1244 if (comparef
[0] == 'A') {
1246 (void) strcpy(afile
, comparef
);
1247 *strchr(afile
, 'A') = ' ';
1248 (void) strcpy(cfile
, cdotfile
);
1249 *strchr(cfile
, 'C') = ' ';
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 */
1258 (void) strcpy(lckdir
, LOCKPRE
);
1259 *strrchr(lckdir
, '/') = '\0';
1260 /* open lock directory */
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
)
1268 DEBUG(9, "STATE: lockfile = %s\n",lckfile
);
1269 if (EQUALS(lockname
, lckfile
))
1280 /* got adot, cdot and lock file */
1282 if (Running
&& foundlck
)
1284 else if (Interrupted
&& CequalA
&& !foundlck
)
1286 else if (Queued
&& !CequalA
&& !foundlck
)
1288 DEBUG(9, "STATE: returning with value %d\n",rtnstate
);
1291 } /* end of state.c */
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
;
1306 time_t t_time
, t_starttime
, t_upperlimit
;
1309 static float rst
, ust
, kst
, xferrate
, utt
, ktt
;
1310 static float rtt
, wfield
, xfield
, yfield
;
1312 struct perfrec
*recptr
;
1318 char *strptr
, *startime
;
1321 totalxfer
=totalbytes
=recordcnt
=totaljob
=totalque
=0;
1322 lowerlimit
[0] = '\0';
1323 upperlimit
[0] = '\0';
1326 inputsecs
= convert(timerange
);
1328 strncpy(lowerlimit
, startime
, MAXDATE
);
1329 strncpy(upperlimit
, gmt(), MAXDATE
);
1331 /* convert lowerlimit and upperlimit to HH:MM format */
1332 friendlytime(lowerlimit
, upperlimit
);
1334 fp
= fopen(PERFLOG
, "r");
1337 (void) fprintf(stderr
, gettext("Can't open performance log\n"));
1342 while (fgets(abuf
, BUFSIZ
, fp
) != NULL
)
1344 DEBUG(9, "READPERF: abuf before = %s\n",abuf
);
1346 if (!EQUALSN(abuf
, "xfer", 4))
1349 /* convert all '|'s to blanks for sscanf */
1350 for (strptr
= abuf
; *strptr
!= '\0'; strptr
++)
1353 DEBUG(9, "READPERF: abuf = %s\n",abuf
);
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
,
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
);
1372 if (!EQUALS(Rmtname
, remote
))
1375 if (!EQUALS(role
, "M"))
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
);
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
);
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
)
1399 totalque
= totalque
+ queuetime
;
1400 totalxfer
= totalxfer
+ xferrate
;
1401 totalbytes
= totalbytes
+ size
;
1402 recordcnt
= recordcnt
+ 1;
1403 DEBUG(9, " processing recordcnt %d\n", recordcnt
);
1405 DEBUG(9, "END step 1 %d\n", recordcnt
);
1407 DEBUG(9, "END step 2 recordcnt %d\n", recordcnt
);
1413 } /* end of readperf */
1431 outtime
= intime
* 60;
1438 static double avgqtime
;
1440 avgqtime
= totalque
/ totaljob
;
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
);
1451 static double avgxrate
;
1453 avgxrate
= totalbytes
/ totalxfer
;
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
);
1461 * Local Function: gmts - Generate Start Time String
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.
1473 * An address of a static character array containing the date.
1479 static char date
[] = "YYMMDDhhmmss";
1482 time_t now
; /* Current time. */
1484 now
= time((time_t *) 0);
1486 /* inputsecs is declared global to this file */
1487 DEBUG(9, "GMTS: now = %ld\n", now
);
1488 DEBUG(9, "GMTS: inputsecs = %ld\n", inputsecs
);
1490 temp
= (now
- inputsecs
);
1492 (void) sprintf(date
, "%02d%02d%02d%02d%02d%02d",
1493 (td
->tm_year
% 100),
1504 * Local Function: gmt - Generate Current Time String
1506 * This function returns the address to a string containing the current
1507 * GMT in the form YYMMDDhhmmss.
1515 * An address of a static character array containing the date.
1521 static char date
[] = "YYMMDDhhmmss";
1524 time_t now
; /* Current time. */
1526 now
= time((time_t *) 0);
1528 (void) sprintf(date
, "%02d%02d%02d%02d%02d%02d",
1529 (td
->tm_year
% 100),
1540 friendlytime(uplimit
, lolimit
)
1541 char *uplimit
, *lolimit
;
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);
1556 friendlyptr
->uhour
[2] = '\0';
1557 friendlyptr
->lhour
[2] = '\0';
1558 friendlyptr
->umin
[2] = '\0';
1559 friendlyptr
->lmin
[2] = '\0';
1564 procState(inputargs
)
1567 if (strchr(inputargs
, 'q') != NULL
)
1569 if (strchr(inputargs
, 'r') != NULL
)
1571 if (strchr(inputargs
, 'i') != NULL
)
1573 if (strchr(inputargs
, 'c') != NULL
)
1576 if ((size_t)(Queued
+ Running
+ Interrupted
+ Complete
) < strlen(inputargs
))
1589 (void) fprintf(stderr
, gettext("\tUsage: %s " USAGE1
"\n"),
1591 (void) fprintf(stderr
, gettext("or\n\tUsage: %s " USAGE2
"\n"),
1593 (void) fprintf(stderr
, gettext("or\n\tUsage: %s " USAGE3
"\n"),