remove xvm/ipagent
[unleashed.git] / usr / src / cmd / bnu / uustat.c
blob4b51d02b116b60aea0487ee19d7d961913916111
1 /*
2 * CDDL HEADER START
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.
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]
20 * CDDL HEADER END
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 #include <time.h>
31 #include "uucp.h"
33 #ifdef V7
34 #define O_RDONLY 0
35 #endif
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]"
40 #define LOCK "LCK.."
41 #define STST_MAX 132
42 #define MAXDATE 12
43 #define MINTIME 60
44 #define MINUTES 60
45 #define CHAR "a"
46 #define MAXSTATE 4
47 /* #include "logs.h" */
48 struct m {
49 char mach[15]; /* machine name */
50 char locked;
51 int ccount, xcount;
52 int count, type;
53 long retrytime;
54 time_t lasttime;
55 short c_age; /* age of oldest C. file */
56 short x_age; /* age of oldest X. file */
57 char stst[STST_MAX];
58 } M[UUSTAT_TBL+2];
61 struct userdate {
62 char uhour[3];
63 char umin[3];
64 char lhour[3];
65 char lmin[3];
68 struct userdate userformat;
69 struct userdate *friendlyptr = &userformat;
71 extern long atol();
72 static int whattodo();
73 static int readperf();
74 static void queuetime();
75 static void xfertime();
76 static char * gmt();
77 static char * gmts();
78 static void errortn();
79 static void friendlytime();
80 static void complete();
81 static int state();
82 static int gnameflck();
83 static void kprocessC();
84 static int convert();
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];
91 static int count;
92 static short jobcount;
93 static short execute;
94 static char lowerlimit[MAXDATE+1], upperlimit[MAXDATE+1];
95 static float totalque, totalxfer;
96 static long totaljob, totalbytes;
97 static long inputsecs;
98 #ifdef ATTSV
99 extern void qsort(); /* qsort(3) and comparison test */
100 #endif /* ATTSV */
101 int sortcnt = -1;
102 extern int machcmp();
103 extern int _age(); /* find the age of a file */
104 static long calcnum;
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 */
120 char f[NAMESIZE];
123 main(argc, argv, envp)
124 char *argv[];
125 char **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];
132 char buf[BUFSIZ];
133 char chkname[MAXFULLNAME];
134 char *vec[7];
135 int i, chkid;
136 char fullpath[MAXFULLNAME];
137 long temp;
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 */
145 #endif
146 (void) textdomain(TEXT_DOMAIN);
148 User[0] = '\0';
149 Rmtname[0] = '\0';
150 Jobid[0] = '\0';
151 Psopt=Machines=Summary=Queue=Kill=Rejuvenate=Uopt=Sysopt=Jobcount=0;
152 execute=avgqueue=avgxfer=Calctime=Window=0;
153 jobcount=nonotf=0;
155 /* set calcnum to default time in minutes */
156 calcnum=MINTIME;
158 (void) strcpy(Progname, "uustat");
159 Uid = getuid();
160 Euid = geteuid();
161 guinfo(Uid, Loginuser);
162 uucpname(Myname);
163 while ((i = getopt(argc, argv, "acjk:mnpr:qs:u:x:t:d:S:")) != EOF) {
164 switch(i){
165 case 'a':
166 Sysopt = 1;
167 break;
168 case 'c':
169 avgqueue = 1;
170 break;
171 case 'd':
172 Window = 1;
173 calcnum = atoi(optarg);
174 if (calcnum <= 0)
175 calcnum = MINTIME;
176 break;
177 case 'k':
178 (void) strncpy(Jobid, optarg, NAMESIZE);
179 Jobid[NAMESIZE-1] = '\0';
180 Kill = 1;
181 break;
182 case 'j':
183 Jobcount = 1;
184 break;
185 case 'm':
186 Machines = Summary = 1;
187 break;
188 case 'n':
189 nonotf = 1;
190 break;
191 case 'p':
192 Psopt = 1;
193 break;
194 case 'r':
195 (void) strncpy(Jobid, optarg, NAMESIZE);
196 Jobid[NAMESIZE-1] = '\0';
197 Rejuvenate = 1;
198 break;
199 case 'q':
200 Queue = Summary = 1;
201 break;
202 case 's':
203 (void) strncpy(Rmtname, optarg, MAXBASENAME);
205 Rmtname[MAXBASENAME] = '\0';
206 if (versys(Rmtname)) {
207 fprintf(stderr, gettext("Invalid system\n"));
208 exit(1);
210 Sysopt = 1;
211 break;
212 case 't':
213 Calctime = 1;
214 (void) strncpy(Rmtname, optarg, MAXBASENAME);
215 Rmtname[MAXBASENAME] = '\0';
216 if (versys(Rmtname)) {
217 fprintf(stderr, gettext("Invalid system\n"));
218 exit(1);
220 break;
221 case 'u':
222 (void) strncpy(User, optarg, 8);
223 User[8] = '\0';
224 if(gninfo(User, &chkid, chkname)) {
225 fprintf(stderr, gettext("Invalid user\n"));
226 exit(1);
228 Uopt = 1;
229 execute = 1;
230 break;
231 case 'x':
232 Debug = atoi(optarg);
233 if (Debug <= 0)
234 Debug = 1;
235 break;
236 case 'S':
237 if (strlen(optarg) > sizeof (arglist)) {
238 errortn();
239 exit(1);
241 State = 1;
242 (void) strlcpy(arglist, optarg, sizeof (arglist));
243 procState(arglist);
244 break;
245 default:
246 errortn();
247 exit(1);
251 if (argc != optind) {
252 errortn();
253 exit(1);
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)
265 errortn();
266 exit(1);
268 if ((Calctime + Psopt + Machines + Queue + Kill + Rejuvenate + (Uopt|Sysopt |State)) >1) {
269 /* only -u, -S and -s can be used together */
270 errortn();
271 exit(1);
273 if ((avgqueue | Window) & (!Calctime))
275 errortn();
276 exit(1);
279 if ( !(Calctime | Kill | Rejuvenate | Uopt | Sysopt | Queue| Machines | State) ) {
280 (void) strcpy(User, Loginuser);
281 Uopt = 1;
284 if ( nonotf && !(Kill | Rejuvenate) ) {
285 errortn();
286 exit(1);
289 /*****************************************/
290 /* PROCESS THE OPTIONS */
291 /*****************************************/
293 if (State && Complete)
295 DEBUG(9, "calling complete %d\n",Complete);
296 complete();
299 if (Calctime) {
300 count = readperf(calcnum);
302 if (count != 0)
303 docalc();
307 if (Psopt) {
308 /* do "ps -flp" or pids in LCK files */
309 lckpid();
310 /* lckpid will not return */
313 if (Summary) {
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)
319 continue;
320 m = machine(f);
321 if (fgets(buf, sizeof(buf), stdin) == NULL)
322 continue;
323 if (getargs(buf, vec, 5) < 5)
324 continue;
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? */
332 *str = '\0';
335 closedir(spooldir);
339 if (Summary) {
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))
371 continue;
373 if (*Rmtname && !EQUALSN(Rmtname, f, MAXBASENAME))
374 continue;
376 if ( (Kill || Rejuvenate)
377 && (!EQUALSN(f, Jobid, strlen(Jobid)-5)) )
378 continue;
380 if (DIRECTORY(f)) {
381 if (chdir(f) != 0)
382 exit(101);
383 (void) sprintf(fullpath, "%s/%s", SPOOL, f);
384 machdir = opendir(fullpath);
385 if (machdir == NULL)
386 exit(101);
388 m = machine(f);
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. */
403 m->ccount++;
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)
413 m->c_age = i;
417 closedir(gradedir);
420 else if (gradef[0] == XQTPRE && gradef[1] == '.') {
421 m->xcount++;
422 if ( (i = _age(machdir, gradef)) > m->x_age)
423 m->x_age = i;
426 closedir(machdir);
428 /* cd back to /var/spoool/uucp dir */
429 if (chdir(SPOOL) != 0)
430 exit(101);
431 } /* while more files in spooldir */
432 closedir(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 */
438 if (Kill) {
439 printf(gettext("Can't find Job %s; Not killed\n"), Jobid);
440 exit(1);
441 } else if (Rejuvenate) {
442 printf(gettext("Can't find Job %s; Not rejuvenated\n"), Jobid);
443 exit(1);
446 /* Make sure the overflow entry is null since it may be incorrect */
447 M[UUSTAT_TBL].mach[0] = NULLCHAR;
448 if (Summary) {
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++)
453 printit(m);
455 return (0);
460 * uprocessC - get information about C. file
464 void
465 uprocessC(machine, dir, file)
466 char *machine, *dir, *file;
468 struct stat s;
469 struct tm *tp;
470 char fullname[MAXFULLNAME], buf[BUFSIZ], user[9];
471 char xfullname[MAXFULLNAME];
472 char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
473 short goodRecord = 0;
474 FILE *fp, *xfp;
475 short first = 1;
476 int statefound = 0;
477 extern long fsize();
478 char format_tmp[BUFSIZ+1];
479 fp=xfp=NULL;
481 /*********************************************/
482 /* initialize output buffer to blanks */
483 /*********************************************/
485 if (Complete && !Queued && !Running && !Interrupted)
486 return;
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 */
494 return;
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");
505 if (fp == NULL) {
506 DEBUG(4, "Can't open file (%s), ", fullname);
507 DEBUG(4, "errno=%d -- skip it!\n", errno);
508 return;
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);
522 continue;
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);
530 goodRecord = 0;
532 if (User[0] != '\0' && (!EQUALS(User, user)) )
533 continue;
536 if (first)
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 */
544 if (State)
546 statefound = state(dir, file);
547 DEBUG(9, "uprocessC: statefound value = %d\n", statefound);
548 if ((whattodo(statefound) != TRUE))
550 outbuf[0] = NULLCHAR;
551 return;
553 else
555 if (statefound == 1)
556 (void) strcat(outbuf, "queued");
557 else if (statefound == 2)
558 (void) strcat(outbuf, "running");
559 else if (statefound == 3)
560 (void) strcat(outbuf, "interrupted");
563 sprintf(format_tmp, " %2.2d/%2.2d-%2.2d:%2.2d ",
564 tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
565 tp->tm_min);
566 (void) strcat(outbuf, format_tmp);
568 else
570 sprintf(format_tmp,"%-12s %2.2d/%2.2d-%2.2d:%2.2d ",
571 "", tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
572 tp->tm_min);
573 (void) strcat(outbuf, format_tmp);
575 first = 0;
577 sprintf(format_tmp,"%s %s ", type, machine);
578 (void) strcat(outbuf, format_tmp);
579 if (*type == 'R')
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");
599 else {
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) {
605 switch(buf[0]) {
606 case 'C':
607 strcpy(command, buf + 2);
608 break;
609 case 'U':
610 sscanf(buf + 2, "%s%s", uline_u, uline_m);
611 break;
612 case 'R':
613 sscanf(buf+2, "%s", retaddr);
614 break;
617 username = user;
618 if (*uline_u != '\0')
619 username = uline_u;
620 if (*retaddr != '\0')
621 username = retaddr;
622 if (!EQUALS(uline_m, Myname))
623 printf("%s!", uline_m);
624 sprintf(format_tmp,"%s %s", username, command);
625 (void) strcat(outbuf, format_tmp);
628 strcat(outbuf, "\n");
629 fputs(outbuf, stdout);
630 outbuf[0] = NULLCHAR;
631 goodRecord = 1;
632 } /* end of while more data in buffer */
634 /* successful processing of a job, increment job count
635 counter */
636 if (goodRecord)
637 jobcount++;
639 if (xfp != NULL)
640 fclose(xfp);
642 fclose(fp);
643 return;
646 * whattodo - determine what to do with current C dot file
647 * depending on any combination (2**3 - 1) of input
648 * job states
650 static int
651 whattodo(inputint)
652 int inputint;
654 /* Maybe some commentary here will help explain this truth
655 table.
657 Queued |Running |Interrupted
658 -------------------------------------------------
659 X | |
660 -------------------------------------------------
661 | X |
662 -------------------------------------------------
663 | | X
664 -------------------------------------------------
665 X | X |
666 -------------------------------------------------
667 | X | X
668 -------------------------------------------------
669 X | | X
670 -------------------------------------------------
671 X | X | X
672 -------------------------------------------------
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)
682 return(TRUE);
683 else if ((Queued && !Running && !Interrupted) && (inputint == 1))
684 return(TRUE);
685 else if ((Running && !Queued && !Interrupted) && (inputint == 2)) return(TRUE);
686 else if ((Interrupted && !Queued && !Running) && (inputint == 3)) return(TRUE);
687 else if ((Queued && Running && !Interrupted) &&
688 (inputint == 1 || inputint == 2))
689 return(TRUE);
690 else if ((!Queued && Running && Interrupted) &&
691 (inputint == 2 || inputint == 3))
692 return(TRUE);
693 else if ((Queued && !Running && Interrupted) &&
694 (inputint ==1 || inputint == 3))
695 return(TRUE);
696 else return(FALSE);
699 * kprocessC - process kill or rejuvenate job
702 static void
703 kprocessC(dir, file)
704 char *file, *dir;
706 struct stat s;
707 struct tm *tp;
708 extern struct tm *localtime();
709 char fullname[MAXFULLNAME], buf[BUFSIZ], user[9];
710 char rfullname[MAXFULLNAME];
711 char file1[BUFSIZ], file2[BUFSIZ], file3[BUFSIZ], type[2], opt[256];
712 FILE *fp, *xfp;
713 struct utimbuf times;
714 short ret;
715 short first = 1;
717 DEBUG(9, "kprocessC(%s, ", dir);
718 DEBUG(9, "%s);\n", file);
720 if ((!EQUALS(Jobid, &file[2])) ) {
721 /* kill job - not this one */
722 return;
725 (void) sprintf(fullname, "%s/%s", dir, file);
726 if (stat(fullname, &s) != 0) {
727 /* error - can't stat */
728 if(Kill) {
729 fprintf(stderr,
730 gettext("Can't stat:%s, errno (%d)--can't kill it!\n"),
731 fullname, errno);
732 } else {
733 fprintf(stderr,
734 gettext("Can't stat:%s, errno (%d)--can't rejuvenate it!\n"),
735 fullname, errno);
737 exit(1);
740 fp = fopen(fullname, "r");
741 if (fp == NULL) {
742 if(Kill) {
743 fprintf(stderr,
744 gettext("Can't read:%s, errno (%d)--can't kill it!\n"),
745 fullname, errno);
746 } else {
747 fprintf(stderr,
748 gettext("Can't read:%s, errno (%d)--can't rejuvenate it!\n"),
749 fullname, errno);
751 exit(1);
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) {
759 if(Kill) {
760 fprintf(stderr,
761 gettext("Bad format:%s, errno (%d)--can't kill it!\n"),
762 fullname, errno);
763 } else {
764 fprintf(stderr,
765 gettext("Bad format:%s, errno (%d)--can't rejuvenate it!\n"),
766 fullname, errno);
768 exit(1);
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);
780 if (first) {
781 if ((access(fullname, 02) != 0)
782 && !PREFIX(Loginuser, user)
783 && !PREFIX(user, Loginuser) ) {
784 /* not allowed - not owner or root */
785 if(Kill)
786 fprintf(stderr, gettext("Not owner,"
787 " uucp or root - can't kill job %s\n"), Jobid);
788 else
789 fprintf(stderr, gettext("Not owner, uucp or root -"
790 " can't rejuvenate job %s\n"), Jobid);
791 exit(1);
793 first = 0;
796 /* remove D. file */
797 (void) sprintf(rfullname, "%s/%s", dir, file3);
798 DEBUG(4, "Remove %s\n", rfullname);
799 if (Kill)
800 ret = unlink(rfullname);
801 else /* Rejuvenate */
802 ret = utime(rfullname, &times);
803 if (ret != 0 && errno != ENOENT) {
804 /* program error?? */
805 if(Kill)
806 fprintf(stderr, gettext("Error: Can't kill,"
807 " File (%s), errno (%d)\n"), rfullname, errno);
808 else
809 fprintf(stderr, gettext("Error: Can't rejuvenated,"
810 " File (%s), errno (%d)\n"), rfullname, errno);
811 exit(1);
815 DEBUG(4, "Remove %s\n", fullname);
816 if (Kill)
817 ret = unlink(fullname);
818 else /* Rejuvenate */
819 ret = utime(fullname, &times);
821 if (ret != 0) {
822 /* program error?? */
823 if(Kill)
824 fprintf(stderr, gettext("Error1: Can't kill,"
825 " File (%s), errno (%d)\n"), fullname, errno);
826 else
827 fprintf(stderr, gettext("Error1: Can't rejuvenate,"
828 " File (%s), errno (%d)\n"), fullname, errno);
829 exit(1);
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, "", "");
837 fclose(fp);
838 if (!nonotf) {
839 if(Kill)
840 printf(gettext("Job: %s successfully killed\n"), Jobid);
841 else
842 printf(gettext("Job: %s successfully rejuvenated\n"),
843 Jobid);
845 exit(0);
849 * fsize - return the size of f1 or f2 (if f1 does not exist)
850 * f1 is the local name
854 long
855 fsize(dir, f1, f2)
856 char *dir, *f1, *f2;
858 struct stat s;
859 char fullname[BUFSIZ];
861 (void) sprintf(fullname, "%s/%s", dir, f1);
862 if (stat(fullname, &s) == 0) {
863 return(s.st_size);
865 if (stat(f2, &s) == 0) {
866 return(s.st_size);
869 return(-99999);
872 void cleanup(){}
873 void logent(){} /* to load ulockf.c */
874 void systat(){} /* to load utility.c */
876 struct m *
877 machine(name)
878 char *name;
880 struct m *m;
881 size_t namelen;
883 DEBUG(9, "machine(%s), ", name);
884 namelen = strlen(name);
885 for (m = M; m->mach[0] != NULLCHAR; m++)
886 /* match on overlap? */
887 if (EQUALSN(name, m->mach, MAXBASENAME)) {
888 /* use longest name */
889 if (namelen > strlen(m->mach))
890 (void) strcpy(m->mach, name);
891 return(m);
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,
903 __FILE__, __LINE__);
904 (void) fprintf(stderr,
905 gettext("WARNING: Table Overflow--output not complete\n"));
907 else
908 /* use the last entry - overwrite it */
909 m = &M[UUSTAT_TBL];
912 (void) strcpy(m->mach, name);
913 m->c_age= m->x_age= m->lasttime= m->locked= m->ccount= m->xcount= 0;
914 m->stst[0] = '\0';
915 return(m);
918 void
919 printit(m)
920 struct m *m;
922 struct tm *tp;
923 time_t t;
924 int minimum;
925 extern struct tm *localtime();
927 if (m->ccount == 0
928 && m->xcount == 0
929 /*&& m->stst[0] == '\0'*/
930 && m->locked == 0
931 && Queue
932 && m->type == 0)
933 return;
934 printf("%-10s", m->mach);
935 if (Queue) {
936 if (m->ccount)
937 printf("%3dC", m->ccount);
938 else
939 printf(" ");
940 if (m->c_age)
941 printf("(%d)", m->c_age);
942 else
943 printf(" ");
944 if (m->xcount)
945 printf("%3dX", m->xcount);
946 else
947 printf(" ");
948 if (m->x_age)
949 printf("(%d) ", m->x_age);
950 else
951 printf(" ");
952 } else
953 printf(" ");
955 if (m->lasttime) {
956 tp = localtime(&m->lasttime);
957 printf("%2.2d/%2.2d-%2.2d:%2.2d ",
958 tp->tm_mon + 1, tp->tm_mday, tp->tm_hour,
959 tp->tm_min);
961 /* if (m->locked && m->type != SS_INPROGRESS) */
962 if (m->locked)
963 printf("Locked ");
964 if (m->stst[0] != '\0') {
965 printf("%s", m->stst);
966 switch (m->type) {
967 case SS_SEQBAD:
968 case SS_LOGIN_FAILED:
969 case SS_DIAL_FAILED:
970 case SS_BAD_LOG_MCH:
971 case SS_BADSYSTEM:
972 case SS_CANT_ACCESS_DEVICE:
973 case SS_DEVICE_FAILED:
974 case SS_WRONG_MCH:
975 case SS_RLOCKED:
976 case SS_RUNKNOWN:
977 case SS_RLOGIN:
978 case SS_UNKNOWN_RESPONSE:
979 case SS_STARTUP:
980 case SS_CHAT_FAILED:
981 (void) time(&t);
982 t = m->retrytime - (t - m->lasttime);
983 if (t > 0) {
984 minimum = (t + 59) / 60;
985 printf("Retry: %d:%2.2d", minimum/60, minimum%60);
987 if (m->count > 1)
988 printf(" Count: %d", m->count);
991 putchar('\n');
992 return;
995 #define MAXLOCKS 100 /* Maximum number of lock files this will handle */
998 lckpid()
1000 int i;
1001 int fd, ret;
1002 pid_t pid, list[MAXLOCKS];
1003 char alpid[SIZEOFPID+2]; /* +2 for '\n' and null */
1004 char buf[BUFSIZ], f[MAXNAMESIZE];
1005 char *c, lckdir[BUFSIZ];
1006 DIR *dir;
1008 DEBUG(9, "lckpid() - entered\n%s", "");
1009 for (i=0; i<MAXLOCKS; i++)
1010 list[i] = -1;
1011 (void) strcpy(lckdir, LOCKPRE);
1012 *strrchr(lckdir, '/') = '\0';
1013 DEBUG(9, "lockdir (%s)\n", lckdir);
1015 /* open lock directory */
1016 if (chdir(lckdir) != 0 || (dir = opendir(lckdir)) == NULL)
1017 exit(101); /* good old code 101 */
1018 while (gnameflck(dir, f) == TRUE) {
1019 /* find all lock files */
1020 DEBUG(9, "f (%s)\n", f);
1021 if (EQUALSN("LCK.", f, 4) || EQUALSN("LK.", f, 3)) {
1022 /* read LCK file */
1023 fd = open(f, O_RDONLY);
1024 printf("%s: ", f);
1025 ret = read(fd, alpid, SIZEOFPID+2); /* +2 for '\n' and null */
1026 pid = strtol(alpid, (char **) NULL, 10);
1027 (void) close(fd);
1028 if (ret != -1) {
1029 printf("%ld\n", (long) pid);
1030 for(i=0; i<MAXLOCKS; i++) {
1031 if (list[i] == pid)
1032 break;
1033 if (list[i] == -1) {
1034 list[i] = pid;
1035 break;
1039 else
1040 printf("????\n");
1043 fflush(stdout);
1044 *buf = NULLCHAR;
1045 for (i=0; i<MAXLOCKS; i++) {
1046 if( list[i] == -1)
1047 break;
1048 (void) sprintf(&buf[strlen(buf)], "%d ", list[i]);
1051 if (i > 0)
1052 #ifdef V7
1053 execl("/bin/ps", "uustat-ps", buf, (char *) 0);
1054 #else
1055 execl("/usr/bin/ps", "ps", "-flp", buf, (char *) 0);
1056 #endif
1057 exit(0);
1061 * get next file name from lock directory
1062 * p -> file description of directory file to read
1063 * filename -> address of buffer to return filename in
1064 * must be of size NAMESIZE
1065 * returns:
1066 * FALSE -> end of directory read
1067 * TRUE -> returned name
1069 static int
1070 gnameflck(p, filename)
1071 char *filename;
1072 DIR *p;
1074 struct dirent dentry;
1075 struct dirent *dp = &dentry;
1077 for (;;) {
1078 if ((dp = readdir(p)) == NULL)
1079 return(FALSE);
1080 if (dp->d_ino != 0 && dp->d_name[0] != '.')
1081 break;
1084 (void) strncpy(filename, dp->d_name, MAXNAMESIZE-1);
1085 filename[MAXNAMESIZE-1] = '\0';
1086 return(TRUE);
1090 machcmp(a,b)
1091 char *a,*b;
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
1100 * return:
1101 * age of file
1102 * 0 - if stat fails
1106 _age(dir, file)
1107 char * file; /* the file name */
1108 char * dir; /* system spool directory */
1110 char fullname[MAXFULLNAME];
1111 static time_t ptime = 0;
1112 time_t time();
1113 struct stat stbuf;
1115 if (!ptime)
1116 (void) time(&ptime);
1117 (void) sprintf(fullname, "%s/%s", dir, file);
1118 if (stat(fullname, &stbuf) != -1) {
1119 return ((int)((ptime - stbuf.st_mtime)/_sec_per_day));
1121 else
1122 return(0);
1124 /* Function: complete - find and print jobids of completed jobs for
1125 * user.
1127 * Look thru the /var/uucp/.Admin/account file (if present)
1128 * for all jobs initiated by user and print.
1130 * Parameters:
1132 * Username - user that initiated uustat request
1134 * Returns:
1137 static void
1138 complete()
1141 /* Function name: complete
1142 Author: Roland T. Conwell
1143 Date: July 31, 1986
1144 Naration: This function will search through
1145 /var/uucp/.Admin/account file
1146 for all jobs submitted by User. If User jobs are
1147 found the state of 'completed' will be
1148 printed on stdout. Module called by uustat main
1151 char abuf[BUFSIZ];
1152 FILE *fp;
1153 char accno[15], jobid[15], system[15], loginame[15], time[20], dest[15];
1154 char size[15];
1155 char grade[2], jgrade[2];
1156 char status[2];
1157 int x;
1159 fp = fopen(ACCOUNT, "r");
1160 if (fp == NULL)
1162 fprintf(stderr, gettext("Can't open account log\n"));
1163 return;
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,
1170 time, dest);
1171 if (x < 6)
1172 continue;
1174 if (!EQUALS(status, "C"))
1175 continue;
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))
1189 continue;
1190 if (*User && !EQUALS(User, loginame))
1191 continue;
1192 if (State && !Uopt)
1194 if (EQUALS(Loginuser, loginame))
1196 printf("%s completed\n",jobid);
1197 jobcount++;
1200 else
1202 printf("%s completed\n", jobid);
1203 jobcount++;
1206 fclose(fp);
1207 return;
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.
1219 * Parameters:
1221 * jcdir - the job grade directory to search
1222 * cdotfile - the Cdotfile whose state is to be determined
1224 * Returns:
1227 static int
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;
1236 int rtnstate = 0;
1237 foundlck = 0;
1238 CequalA = 0;
1239 sjcdir = opendir(jcdir);
1240 if (sjcdir == NULL)
1241 return (0);
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 */
1256 CequalA = 1;
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))
1270 foundlck = 1;
1272 closedir(subjcdir);
1279 closedir(sjcdir);
1280 /* got adot, cdot and lock file */
1282 if (Running && foundlck)
1283 rtnstate = 2;
1284 else if (Interrupted && CequalA && !foundlck)
1285 rtnstate = 3;
1286 else if (Queued && !CequalA && !foundlck)
1287 rtnstate = 1;
1288 DEBUG(9, "STATE: returning with value %d\n",rtnstate);
1289 return(rtnstate);
1291 } /* end of state.c */
1295 static int
1296 readperf(timerange)
1297 long timerange;
1300 char proto[2], jc[2], role[2];
1301 char rectype[5], time[MAXDATE+1], pid[10],wmachine[10];
1302 char remote[10],device[10], netid[20], jobid[20];
1303 static float queuetime, tat;
1304 static long size;
1305 struct tm tm_tmp;
1306 time_t t_time, t_starttime, t_upperlimit;
1308 char options[10];
1309 static float rst, ust, kst, xferrate, utt, ktt;
1310 static float rtt, wfield, xfield, yfield;
1312 struct perfrec *recptr;
1313 static float tqt;
1314 static int jobs;
1315 char abuf[BUFSIZ];
1316 FILE *fp;
1317 static int x;
1318 char *strptr, *startime;
1319 int recordcnt;
1321 totalxfer=totalbytes=recordcnt=totaljob=totalque=0;
1322 lowerlimit[0] = '\0';
1323 upperlimit[0] = '\0';
1326 inputsecs = convert(timerange);
1327 startime = gmts();
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");
1335 if (fp == NULL)
1337 (void) fprintf(stderr, gettext("Can't open performance log\n"));
1338 return(0);
1342 while (fgets(abuf, BUFSIZ, fp) != NULL)
1344 DEBUG(9, "READPERF: abuf before = %s\n",abuf);
1346 if (!EQUALSN(abuf, "xfer", 4))
1347 continue;
1349 /* convert all '|'s to blanks for sscanf */
1350 for (strptr = abuf; *strptr != '\0'; strptr++)
1351 if (*strptr == '|')
1352 *strptr = ' ';
1353 DEBUG(9, "READPERF: abuf = %s\n",abuf);
1355 x = sscanf(abuf, "%s%*s%s%s%s%s%s%s%*s%s%s%f%f%ld%s%f%f%f%f%f%f%f%f%f%*s",
1356 rectype, time, pid, wmachine, role, remote, device, netid,
1357 jobid, &queuetime, &tat, &size, options, &rst,
1358 &ust, &kst, &xferrate, &utt, &ktt, &rtt, &wfield,
1359 &xfield);
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);
1370 abuf[0] = '\0';
1372 if (!EQUALS(Rmtname, remote))
1373 continue;
1375 if (!EQUALS(role, "M"))
1376 continue;
1378 if (x < 18)
1379 continue;
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)
1398 totaljob++;
1399 totalque = totalque + queuetime;
1400 totalxfer = totalxfer + xferrate;
1401 totalbytes = totalbytes + size;
1402 recordcnt = recordcnt + 1;
1403 DEBUG(9, " processing recordcnt %d\n", recordcnt);
1405 DEBUG(9, "END step 1 %d\n", recordcnt);
1406 } /* while */
1407 DEBUG(9, "END step 2 recordcnt %d\n", recordcnt);
1409 fclose(fp);
1410 return(recordcnt);
1413 } /* end of readperf */
1415 void
1416 docalc()
1418 if (avgqueue)
1419 queuetime();
1420 else
1421 xfertime();
1422 return;
1425 static int
1426 convert(intime)
1427 long intime;
1429 long outtime;
1431 outtime = intime * 60;
1432 return(outtime);
1435 static void
1436 queuetime()
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);
1444 return;
1448 static void
1449 xfertime()
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);
1457 return;
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.
1467 * Parameters:
1469 * none
1471 * Return:
1473 * An address of a static character array containing the date.
1476 static char *
1477 gmts()
1479 static char date[] = "YYMMDDhhmmss";
1481 struct tm *td;
1482 time_t now; /* Current time. */
1483 time_t temp;
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);
1491 td = gmtime(&temp);
1492 (void) sprintf(date, "%02d%02d%02d%02d%02d%02d",
1493 (td->tm_year % 100),
1494 td->tm_mon + 1,
1495 td->tm_mday,
1496 td->tm_hour,
1497 td->tm_min,
1498 td->tm_sec
1500 return date;
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.
1509 * Parameters:
1511 * none
1513 * Return:
1515 * An address of a static character array containing the date.
1518 static char *
1519 gmt()
1521 static char date[] = "YYMMDDhhmmss";
1523 struct tm *td;
1524 time_t now; /* Current time. */
1526 now = time((time_t *) 0);
1527 td = gmtime(&now);
1528 (void) sprintf(date, "%02d%02d%02d%02d%02d%02d",
1529 (td->tm_year % 100),
1530 td->tm_mon + 1,
1531 td->tm_mday,
1532 td->tm_hour,
1533 td->tm_min,
1534 td->tm_sec
1536 return date;
1539 static void
1540 friendlytime(uplimit, lolimit)
1541 char *uplimit, *lolimit;
1544 char c;
1546 c = *(uplimit+6);
1547 friendlyptr->uhour[0] = *(uplimit+6);
1548 friendlyptr->uhour[1] = *(uplimit+7);
1549 friendlyptr->lhour[0] = *(lolimit+6);
1550 friendlyptr->lhour[1] = *(lolimit+7);
1551 friendlyptr->umin[0] = *(uplimit+8);
1552 friendlyptr->umin[1] = *(uplimit+9);
1553 friendlyptr->lmin[0] = *(lolimit+8);
1554 friendlyptr->lmin[1] = *(lolimit+9);
1556 friendlyptr->uhour[2] = '\0';
1557 friendlyptr->lhour[2] = '\0';
1558 friendlyptr->umin[2] = '\0';
1559 friendlyptr->lmin[2] = '\0';
1560 return;
1563 void
1564 procState(inputargs)
1565 char * inputargs;
1567 if (strchr(inputargs, 'q') != NULL)
1568 Queued = 1;
1569 if (strchr(inputargs, 'r') != NULL)
1570 Running = 1;
1571 if (strchr(inputargs, 'i') != NULL)
1572 Interrupted = 1;
1573 if (strchr(inputargs, 'c') != NULL)
1574 Complete = 1;
1576 if ((size_t)(Queued + Running + Interrupted + Complete) < strlen(inputargs))
1578 errortn();
1579 exit(1);
1581 return;
1584 static void
1585 errortn()
1589 (void) fprintf(stderr, gettext("\tUsage: %s " USAGE1 "\n"),
1590 Progname);
1591 (void) fprintf(stderr, gettext("or\n\tUsage: %s " USAGE2 "\n"),
1592 Progname);
1593 (void) fprintf(stderr, gettext("or\n\tUsage: %s " USAGE3 "\n"),
1594 Progname);
1595 return;