/********************************************************************** * Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. * * All Rights Reserved. * * Reference "/usr/src/COPYRIGHT" for applicable restrictions. * **********************************************************************/ static char Sccsid[] = "@(#)sysx_r.c 3.0 4/22/86"; /* * ULTRIX-11 system exerciser control program (sysx). * * Part III - running exerciser scripts * * * Fred Canter 12/18/83 * Bill Burns 4/84 * added check for rx50 for rax * added eventflag usage * * * 1. Start/stop execution of exercisers. * * 2. Print exerciser log files. * */ #include <stdio.h> #include <signal.h> #include <setjmp.h> #include <sys/types.h> #include <sys/stat.h> #include <a.out.h> char *gs_more = "\nPress <RETURN> for more:"; char *gs_prtc = "\nPress <RETURN> to continue:"; char *h_z[] = { "", "The `!' is used to escape from the sysx program back to ", "the ULTRIX-11 command interpreter (shell), execute any of ", "the ULTRIX-11 commands, and then return to the sysx program. ", "The `!' feature may only be used when sysx is ready to ", "accept a command, i.e., in response to the `>' and `run>' ", "prompts. The `!' may be used, while the exercisers are running, ", "to execute ULTRIX-11 commands like ps, pstat, and iostat ", "to monitor system operation. The usage of the `!' is as ", "follows:", "", " ! command", "", "where command is any of the ULTRIX-11 commands. For a ", "description of the ULTRIX-11 commands refer to section ", "one of the \"ULTRIX-11 Programmers Manual\". For example:", "", " ! ls -l", "", "would produce a listing of all the files in the current ", "directory.", "", 0, }; char *h_h[] = { "", "The `run>' prompt indicates that SYSX is running a script", "and is ready to accept a limited number of commands.", "Except for <CTRL/D> and <CTRL/C>, commands are executed ", "by typing the command letter followed by a <RETURN>. ", "The commands will ask for additional information, such as ", "script name, if required. For more help type `h' followed ", "by the command, `h r' for help restart.", "", "Command Description", "", "<CTRL/D> Exit from the sysx program.", "<CTRL/C> Cancel current command and return to the `run>' ", " prompt.", "", "! command Execute an ULTRIX-11 command.", "p Print the status of the currently running ", " script.", "r Restart exerciser(s).", "s Stop exerciser(s).", "l Print log files on the terminal or line ", " printer.", "", 0, }; char *h_l[] = { "", "The `l' command is used to print the contents of exerciser", "log files on the terminal or the line printer.", "", "When asked for `which log files', respond with:", "1. A <RETURN> to print `all' existing log files.", " There could be very many log files in existence !", "", "2. An exerciser name, to print all log files for that ", " exerciser. There can be many log files associated ", " with an exerciser, for example there could be 20 ", " copies of CPX running, so there would be 20 log files.", "", "3. A specific log file name, obtained from the exerciser ", " script via the `p' command. For example, `cpx_2.log' ", " would print only the log file for the second copy of ", " CPX.", "", -1, "", "When asked `Output on ', answer:", "1. Yes for output on the line printer.", " Answering yes when no line printer exists will cause", " line printer spool files to be created and waste ", " disk space.", "", "2. No or <RETURN> for output on the terminal.", "", 0, }; char *h_p[] = { "", "The `p' command prints the contents of the currently running ", "script. To execute the `p' command, type `p' followed ", "by a <RETURN> after the `run>' prompt. The printout consists of; ", "the exerciser number, the name of the exerciser, the state of the ", "exerciser (run/stop), and the options specified for the ", "exerciser. ", "", 0, }; char *h_s[] = { "", "The `s' command is used to stop the execution of one, all, ", "or a group of exercisers. Answer the `Stop which exercisers' ", "question with one of the following three responses:", "", "1. `a', `all', or only a <RETURN>, to stop all exercisers. ", "", "2. The name of an exerciser, such as `cpx', to stop all ", " running copies of that exerciser.", "", "3. The number of the exerciser to stop. The exerciser", " number is based upon the exerciser's position in the", " script. Use the `p' command to list the script.", "", "SYSX waits for the specified exerciser(s) to stop and then returns ", "to either the `run>' prompt (if there are still exercisers running) ", "or the `>' prompt (if no exercisers are running). If the message ", "\"`exerciser' did not stop\" is printed; stop all exercisers, and ", "then restart the exerciser script.", "", 0, }; char *h_r[] = { "", "The `r' command is used to restart the execution of one, all, ", "or a group of exercisers. Answer the `Restart which exercisers' ", "question with one of the following three responses:", "", "1. `a', `all', or only a <RETURN>, to restart all stopped", " exercisers.", "", "2. The name of an exerciser, such as `cpx', to restart all ", " stopped copies of that exerciser.", "", "3. The number of the exerciser to restart. The exerciser", " number is based upon the exerciser's position in the", " script. Use the `p' command to list the script.", "", "SYSX waits for the named exerciser(s) to start then returns ", "to the `run>' prompt. If the message \"`exerciser' did not start\" ", "is printed; stop all exercisers, then restart the exerciser script.", "", 0, }; char *h_alf[] = { "", "Answering yes will cause any restarted exercisers to append", "their output to already existing logfiles. Answering no will", "cause the exerciser to recreate the logfile.", "", 0, }; struct hsub { char *hs_name; char **hs_msg; } hsub[] = { "z", &h_z, /* help for "!" */ "h", &h_h, /* general help */ "l", &h_l, /* help for list log files */ "p", &h_p, /* help for print script status */ "r", &h_r, /* help for restart */ "s", &h_s, /* help for stop */ "alf", &h_alf, /* append to logfile help */ 0 }; #define SBSIZE 8192 #define YES 1 #define NO 0 #define HELP 1 #define NOHELP 0 #define XRUN 1 #define XSTOP 0 int sswait; /* number of seconds to wait for exer start/stop */ /* 23 or 24 = 450, micro/pdp-11 = 600, others = 300 */ int cputype; /* * Below needed for proper handling * of rax "maint area" question * Bill 4/20/84 */ #define RX50 50 struct ra_drv { /* RA drive information */ char ra_dt; /* RA drive type */ char ra_online; /* RA drive on-line flag */ union { daddr_t ra_dsize; /* RA drive size (# of LBN's) */ struct { int ra_dslo; int ra_dshi; }; } d_un; } ra_drv[8]; /* size MUST be 8 */ long evntflg(); /* type returned by event flag syscall */ struct nlist nl[] = { { "_cputype" }, { "_ra_drv" }, { "" }, }; /* * Exerciser control table. * Contains the exerciser run/stop status, * its name, and pointers to its kill & log file names. */ #ifdef EFLG #include <sys/eflg.h> #define MAXEXR 64 /* maximum number of exercisers */ struct extab { char *exn; /* pointer to exerciser name in sbuf */ char *exo; /* " options */ char *exlf; /* " log filename */ long osz; /* old logfile size - monitoring */ long nsz; /* new logfile size - monitoring */ int exs; /* run/stop status */ } exrtab[MAXEXR+1]; #else #define MAXEXR 150 /* maximum number of exercisers */ struct extab { char *exn; /* pointer to exerciser name in sbuf */ char *exo; /* " options */ char *exkf; /* " kill filename */ char *exlf; /* " log filename */ long osz; /* old logfile size - monitoring */ long nsz; /* new logfile size - monitoring */ int exs; /* run/stop status */ } exrtab[MAXEXR+1]; #endif char helpcmd[] = "cat sysx_?.help\0"; char xrn[20]; /* exerciser name */ char logfn[20]; /* log file name */ #ifdef EFLG int efid[2]; /* eventflag id array */ long eflg[2]; /* eventflags */ int nexer; /* number of exercisers in script */ #else char killfn[20]; /* kill file name */ #endif char line[140]; char script[20]; /* name of current script */ char sbuf[SBSIZE+256]; /* script buffer */ /* * Exerciser run flag, * 1 = Some or all exercisers are running * 0 = No exercisers are running * * When set, this flag prevents the execution of * certain commands and modifies the operation * of other commands. */ int xrun; int stpflg; int logused; int alrmflag; int alrmcnt; jmp_buf savej; int buflag; /* used to cancel a line when creating a script */ struct stat statb; /* used by logfile montioring */ time_t timbuf; time_t stime1; time_t stime2; int swiflag; /* flag to interrupt exer startup wail loop */ char z2[3]; char z3[6]; char z4[6]; int pgrp = 31111; main(argc, argv) int argc; char *argv[]; { int logmon(); int swintr(); int intr(); register int i; int j, k; register char *p, *n; char *q; struct xtab *xp; int cc, fd; int mtfirst; int ncopy; int logfil; int sst; int cmxon; int yn; int lstall; int savebp; int ker; FILE *fnx; int ncbx, ncix, nbix; int mem; int dn; #ifdef EFLG int pis; #endif int lfflag; nlist("/unix", nl); if(nl[0].n_type == 0) { printf("\nsysx: can't access namelist in /unix\n"); exit(0); } if((mem = open("/dev/mem", 0)) < 0) { printf("\nsysx: can't open /dev/mem\n"); exit(0); } lseek(mem, (long)nl[0].n_value, 0); read(mem, (char *)&cputype, sizeof(cputype)); lseek(mem, (long)nl[1].n_value, 0); read(mem, (char *)&ra_drv, sizeof(ra_drv)); close(mem); sswait = 300; if((cputype == 23) || (cputype == 24)) sswait += 150; if((cputype == 23) && (nl[1].n_type)) sswait += 150; /* if ra_drv, assume Micro/pdp-11 */ signal(SIGQUIT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGINT, SIG_IGN); #ifndef EFLG system("touch junk.kill"); system("rm -f *.kill"); #endif strcpy(script, argv[1]); p = &script; fd = open(p, 0); p = &sbuf[0]; /* clear script buffer */ for(i=0; i<SBSIZE+256; i++) *p++ = 0; if(read(fd, (char *)&sbuf, SBSIZE+256) < 0) { printf("\n%s script file read error", p); exit(0); } close(fd); setext(); /* set up exerciser control table */ cmxon = 0; ncbx = 0; ncix = 0; nbix = 0; for(i=0; exrtab[i].exn; i++) { /* * Count the number of exercisers in each class. */ if((strcmp("cpx", exrtab[i].exn) == 0) || (strcmp("fpx", exrtab[i].exn) == 0) || (strcmp("memx", exrtab[i].exn) == 0)) ncbx++; /* compute bound exer */ if((strcmp("lpx", exrtab[i].exn) == 0) || (strcmp("cmx", exrtab[i].exn) == 0)) ncix++; /* char I/O intensive exer */ if((strcmp("rlx", exrtab[i].exn) == 0) || (strcmp("rkx", exrtab[i].exn) == 0) || (strcmp("rpx", exrtab[i].exn) == 0) || (strcmp("hkx", exrtab[i].exn) == 0) || (strcmp("hpx", exrtab[i].exn) == 0) || (strcmp("rax", exrtab[i].exn) == 0) || (strcmp("mtx", exrtab[i].exn) == 0)) nbix++; /* block I/O intensive exer */ if(strcmp("cmx", exrtab[i].exn) == 0) cmxon++; /* cmx in use */ exrtab[i].osz = 0L; /* initial logfile length */ if(exrtab[i].exlf) logused++; } /* * Write the number of exercisers in each class * out to the `sysxr.nx' file. This tells the memory * exerciser what the load on the system will be, * so that it can adjust the number of processes * that it runs. */ fnx = fopen("sysxr.nx", "w"); if(fnx == NULL) { printf("\nsysx: Can't open sysxr.nx file !\n"); exit(0); } putw(ncbx, fnx); /* # of compute bound exer */ putw(ncix, fnx); /* # of char I/O intensive exer */ putw(nbix, fnx); /* # of block I/O intensive exer */ fclose(fnx); /* * If the comm. mux exerciser (cmx) is to be used, * warn about disconnecting customer equipment from * dh, dz, and dzv lines ! */ if(cmxon) { printf("\n\7\7\7Disconnect any customer equipment "); printf("that may be affected"); printf("\nby test data transmitted on DH, DHU, DHV,"); printf("\nDZ, DZV, DZQ, DL output lines !"); printf("\n\nConfirm"); if(yes(NO, NOHELP) == NO) exit(0); } if(logused) { printf("\n\7\7\7Log files will be overwritten !"); printf("\nThe `b' command may be used to save log files."); printf("\n\nProceed"); if(yes(NO, NOHELP) == NO) exit(0); } #ifdef EFLG /* request the eventflags */ /* initial values for flags are generated by setext() */ efid[0] = (int)evntflg(EFREQ, 0666, (long)eflg[0]); itos(efid[0], z3); if(nexer > 32) { efid[1] = (int)evntflg(EFREQ, 0666, (long)eflg[1]); itos(efid[1], z4); } #else for(i=0; exrtab[i].exn; i++) close(creat(exrtab[i].exkf, 0644)); #endif wmsg2(); /* Run the exercisers in the script */ for(i=0; exrtab[i].exn; i++) run(i,0); time(&stime1); for( ;; ) { j = 0; time(&stime2); if((stime2 - stime1) > sswait) break; if(swiflag) { /* cancel wait loop */ printf("\nWait loop canceled !\n"); goto r_xit1; } #ifdef EFLG eflg[0] = evntflg(EFRD, efid[0], (long)0); if(nexer > 32) eflg[1] = evntflg(EFRD, efid[1], (long)0); for(k=0; exrtab[k].exn; k++) { if(exrtab[k].exs == XRUN) continue; if((eflg[k>>5] & (1L << (k & 037))) == 0) { exrtab[k].exs = XRUN; xrun++; /* say exercisers running */ time(&timbuf); q = &xrn; p = exrtab[k].exlf; while(*p != '.') *q++ = *p++; *q = '\0'; printf("\n%8s started - %s", &xrn, ctime(&timbuf)); } else j++; } #else for(k=0; exrtab[k].exn; k++) { if(exrtab[k].exs == XRUN) continue; if(access(exrtab[k].exkf, 0) != 0) { exrtab[k].exs = XRUN; xrun++; /* say exercisers running */ unlink(exrtab[k].exkf); time(&timbuf); q = &xrn; p = exrtab[k].exkf; while(*p != '.') *q++ = *p++; *q = '\0'; printf("\n%8s started - %s", &xrn, ctime(&timbuf)); } else j++; } #endif if(j == 0) break; } r_xit1: #ifdef EFLG for(i=0; exrtab[i].exn; i++) if(exrtab[i].exs != XRUN) { q = &xrn; p = exrtab[i].exlf; while(*p != '.') *q++ = *p++; *q = '\0'; printf("\n`%8s' did not start !", &xrn); } #else for(i=0; exrtab[i].exn; i++) if(exrtab[i].exs != XRUN) { q = &xrn; p = exrtab[i].exkf; while(*p != '.') *q++ = *p++; *q = '\0'; printf("\n`%8s' did not start !", &xrn); } #endif r_xit: signal(SIGINT, intr); if(xrun && logused) { /* monitor log file growth */ signal(SIGALRM, logmon); alarm(60); } setjmp(savej); cloop: if(!xrun) exit(0); printf("\n\nrun> "); cloop1: alrmflag = 0; fflush(stdout); cc = read(0, (char *)&line[0], 132); if((cc == -1) && alrmflag) goto cloop1; /* alarm caused return ! */ if(cc == 0) { /* control d */ if(xrun) { printf("\n\n\7\7\7Exercisers running !, really exit"); if(yes(NO, NOHELP) == NO) goto cloop; printf("\nType \"sysxstop\" to stop exercisers."); } printf("\n\n"); exit(1); } if(cc == 1) goto cloop; if(cc > 100) { badl: printf("\nBad command line !"); goto cloop; } p = &line; while((*p != '\r') && (*p != '\n')) { if((*p >= 'A') && (*p <= 'Z')) *p |= 040; /* force lower case */ p++; } *p = 0; p = line; if((*p >= 'a') && (*p <= 'z') && (strlen(p) != 1) && (*p != 'h')) goto badl; while(*++p == ' ') ; /* * Decode the command and act accordingly * line[0] = command * *p = rest of command line */ switch(line[0]) { case 'h': /* ON-LINE HELP FACILITY */ if(!(*p)) { *p = 'h'; *(p+1) = '\0'; } if(*p == '!') *p = 'z'; dohelp(p); goto cloop; case '!': /* EXECUTE UNIX COMMAND */ if(*p) { fflush(stdout); if(logused) /* turn off alarm clock */ alarm(0); system(p); printf("!\nrun> "); if(logused) /* turn on alarm clock */ logmon(); } else printf("\nCommand missing !\n> "); goto cloop1; case 'p': /* DISPLAY SCRIPT/STATUS */ n = &script; while(*n++ != '.') ; *--n = 0; printf("\n\nCurrent running script is `%s'", script); *n = '.'; printf("\n\n # EXER STATE LOGFILE OPTIONS"); for(i=0; exrtab[i].exn; i++) { printf("\n%2d ", i+1); printf("%4s ", exrtab[i].exn); if(exrtab[i].exs == XRUN) printf("run "); else printf("stop "); if(exrtab[i].exlf) printf("%12s ", exrtab[i].exlf); else printf(" "); if(exrtab[i].exo) printf("%s", exrtab[i].exo); } break; case 'r': /* RESTART EXERCISERS */ do printf("\nRestart which exerciser(s) <all> ? "); while((cc = getline(18)) < 0); signal(SIGINT, SIG_IGN); alarm(0); /* stop monitoring log files */ logused = 0; if(tall(cc)) { /* restart all stopped exercisers */ for(i = 0; exrtab[i].exn; i++) if(exrtab[i].exs == XSTOP) stpflg++; if(!stpflg) { printf("\nNo exercisers stopped !\n"); goto cloop; } #ifdef EFLG eflg[0] = 0L; eflg[1] = 0L; lfflag = 0; for(i=0; exrtab[i].exn; i++) if(exrtab[i].exs == XSTOP) { eflg[i>>5] |= (1L << (i & 037)); if(exrtab[i].exlf) lfflag++; } evntflg(EFWRT, efid[0], (long)eflg[0]); if(eflg[1]) evntflg(EFWRT, efid[1], (long)eflg[1]); #else for(i=0; exrtab[i].exn; i++) if((exrtab[i].exs == XRUN) && exrtab[i].exkf) close(creat(exrtab[i].exkf, 0644)); #endif /* Run all stopped exercisers */ if(lfflag) { alf: printf("\nAppend to log files"); if((yn = yes(YES, HELP)) == -1) { dohelp("alf"); goto alf; } } for(i=0; exrtab[i].exn; i++) { if(exrtab[i].exs == XRUN) continue; if((exrtab[i].exlf) && (!yn)) exrtab[i].osz = exrtab[i].nsz = 0L; run(i, yn); } wmsg2(); /* print waiting for start message */ time(&stime1); for( ;; ) { j = 0; time(&stime2); if((stime2 - stime1) > sswait) break; if(swiflag) { /* cancel wait loop */ printf("\nWait loop canceled !\n"); goto rs_xit1; } #ifdef EFLG eflg[0] = evntflg(EFRD, efid[0], (long)0); if(nexer > 32) eflg[1] = evntflg(EFRD, efid[1], (long)0); for(k=0; exrtab[k].exn; k++) { if(exrtab[k].exs == XSTOP) { if((eflg[k>>5] & (1L << (k & 037))) == 0) { exrtab[k].exs = XRUN; started(exrtab[k].exlf); } else j++; } } #else for(k=0; exrtab[k].exn; k++) { if(exrtab[k].exs == XSTOP) { if(access(exrtab[k].exkf, 0) != 0) { exrtab[k].exs = XRUN; started(exrtab[k].exkf); } else j++; } } #endif if(j == 0) break; } rs_xit1: for(i=0; exrtab[i].exn; i++) if(exrtab[i].exs == XSTOP) nostart(exrtab[i].exlf); } else if(cc < 4) { /* start one copy of an exerciser */ #ifdef EFLG i = atoi(line); i--; if(exrtab[i].exn == 0) { printf("\n`Exexciser #%d' - not in script !",i+1 ); goto rs_xit; } q = &xrn; p = exrtab[i].exlf; while(*p != '.') *q++ = *p++; *q = '\0'; #else q = &xrn; p = &line; while(*p != '.') *q++ = *p++; *q = '\0'; #endif #ifdef EFLG eflg[0] = 0L; eflg[1] = 0L; lfflag = 0; if(exrtab[i].exs == XSTOP) { eflg[i>>5] = (1L << (i & 037)); evntflg(EFWRT, efid[i>>5], (long)eflg[i>>5]); if(exrtab[i].exlf) lfflag++; } else { printf("\nExerciser %d - is running !", i+1); goto rs_xit; } #else for(i=0; exrtab[i].exn; i++) if(strcmp(&line, exrtab[i].exkf) == 0) if(exrtab[i].exs == XRUN) { close(creat(exrtab[i].exkf,0644)); break; } else { printf("\n`%s' - not running !",&xrn); goto rs_xit; } #endif if(lfflag) { alf1: printf("\nAppend to log files"); if((yn = yes(YES, HELP)) == -1) { dohelp("alf"); goto alf1; } } /* Run the selected exerciser */ if((exrtab[i].exlf) && (!yn)) exrtab[i].osz = exrtab[i].nsz = 0L; run(i, yn); wmsg2(); time(&stime1); for( ;; ) { time(&stime2); if((stime2 - stime1) > sswait) break; if(swiflag) { /* cancel wait loop */ printf("\nWait loop canceled !\n"); goto rs_xit2; } #ifdef EFLG eflg[i>>5] = evntflg(EFRD, efid[i>>5], (long)0); if((eflg[i>>5] & (1L << (i & 037))) == 0) { exrtab[i].exs = XRUN; started(exrtab[i].exlf); break; } #else if(access(exrtab[i].exkf, 0) != 0) { exrtab[i].exs = XSTOP; started(exrtab[i].exkf); break; } #endif } rs_xit2: if(exrtab[i].exs != XRUN) nostart(exrtab[i].exlf); } else { /* start all copies of an exerciser */ #ifdef EFLG eflg[0] = 0L; eflg[1] = 0L; lfflag = 0; for(i=0, j=0, k=0; exrtab[i].exn; i++) if(strcmp(&line, exrtab[i].exn) == 0) { k++; if(exrtab[i].exs == XSTOP) { j++; eflg[i>>5] |= (1L << (i & 037)); if(exrtab[i].exlf) lfflag++; } } if(eflg[0]) evntflg(EFWRT, efid[0], (long)eflg[0]); if(eflg[1]) evntflg(EFWRT, efid[1], (long)eflg[1]); #else for(i=0, j=0, k=0; exrtab[i].exn; i++) if(strcmp(&line, exrtab[i].exn) == 0) { k++; if(exrtab[i].exs == XRUN) { j++; close(creat(exrtab[i].exkf,0644)); } } #endif if(k == 0) { printf("\n`%s' - not in script !", &line); goto rs_xit; } if(j == 0) { printf("\n`%s' - no copies stopped !", &line); goto rs_xit; } if(lfflag) { alf2: printf("\nAppend to log files"); if((yn = yes(YES, HELP)) == -1) { dohelp("alf"); goto alf2; } } for(i=0; exrtab[i].exn; i++) if(strcmp(&line, exrtab[i].exn) == 0) { if((exrtab[i].exlf) && (!yn)) exrtab[i].osz = exrtab[i].nsz = 0L; if(exrtab[i].exs == XSTOP) run(i, yn); } wmsg2(); time(&stime1); for( ;; ) { k = 0; time(&stime2); if((stime2 - stime1) > sswait) break; if(swiflag) { /* cancel wait loop */ printf("\nWait loop canceled !\n"); goto rs_xit3; } for(i=0; exrtab[i].exn; i++) { if(exrtab[i].exs != XSTOP) continue; if(strcmp(&line, exrtab[i].exn) == 0) { k++; #ifdef EFLG eflg[i>>5] = evntflg(EFRD, efid[i>>5], (long)0); if((eflg[i>>5] & (1L << (i & 037))) == 0) { exrtab[i].exs = XRUN; started(exrtab[i].exlf); } #else if(access(exrtab[i].exkf, 0) != 0) { exrtab[i].exs = XSTOP; started(exrtab[i].exkf); } #endif } } if(k == 0) break; } rs_xit3: for(i=0; exrtab[i].exn; i++) if((strcmp(&line, exrtab[i].exn) == 0) && (exrtab[i].exs != XRUN)) nostart(exrtab[i].exlf); } rs_xit: for(j=0; exrtab[j].exn; j++) if(exrtab[j].exs == XRUN) if(exrtab[j].exlf) logused++; if(logused) alarm(60); signal(SIGINT, intr); break; case 's': /* STOP EXERCISERS */ do printf("\nStop which exerciser(s) <all> ? "); while((cc = getline(18)) < 0); signal(SIGINT, SIG_IGN); alarm(0); /* stop monitoring log files */ logused = 0; /* clear log file in use flag */ if(tall(cc)) { /* stop all exercisers */ #ifdef EFLG eflg[0] = 0L; eflg[1] = 0L; for(i=0; exrtab[i].exn; i++) if(exrtab[i].exs == XRUN) eflg[i>>5] |= (1L << (i & 037)); evntflg(EFWRT, efid[0], (long)eflg[0]); if(eflg[1]) evntflg(EFWRT, efid[1], (long)eflg[1]); #else for(i=0; exrtab[i].exn; i++) if((exrtab[i].exs == XRUN) && exrtab[i].exkf) close(creat(exrtab[i].exkf, 0644)); #endif killpg(pgrp, SIGQUIT); wmsg(); /* print waiting for stop message */ time(&stime1); for( ;; ) { j = 0; time(&stime2); if((stime2 - stime1) > sswait) break; if(swiflag) { /* cancel wait loop */ printf("\nWait loop canceled !\n"); goto s_xit1; } #ifdef EFLG eflg[0] = evntflg(EFRD, efid[0], (long)0); if(nexer > 32) eflg[1] = evntflg(EFRD, efid[1], (long)0); for(k=0; exrtab[k].exn; k++) { if(exrtab[k].exs == XRUN) { if((eflg[k>>5] & (1L << (k & 037))) == 0) { exrtab[k].exs = XSTOP; stoped(exrtab[k].exlf); } else j++; } } #else for(k=0; exrtab[k].exn; k++) { if(exrtab[k].exs == XRUN) { if(access(exrtab[k].exkf, 0) != 0) { exrtab[k].exs = XSTOP; stoped(exrtab[k].exkf); } else j++; } } #endif if(j == 0) break; } s_xit1: for(i=0; exrtab[i].exn; i++) if(exrtab[i].exs == XRUN) nostop(exrtab[i].exlf); } else if(cc < 4) { /* stop one copy of an exerciser */ #ifdef EFLG i = atoi(line); i--; if(exrtab[i].exn == 0) { printf("\n`Exexciser #%d' - not in script !",i+1 ); goto s_xit; } q = &xrn; p = exrtab[i].exlf; while(*p != '.') *q++ = *p++; *q = '\0'; #else q = &xrn; p = &line; while(*p != '.') *q++ = *p++; *q = '\0'; #endif #ifdef EFLG eflg[0] = 0L; eflg[1] = 0L; if(exrtab[i].exs == XRUN) { eflg[i>>5] = (1L << (i & 037)); evntflg(EFWRT, efid[i>>5], (long)eflg[i>>5]); } else { printf("\nExerciser %d - not running !", i+1); goto s_xit; } #else for(i=0; exrtab[i].exn; i++) if(strcmp(&line, exrtab[i].exkf) == 0) if(exrtab[i].exs == XRUN) { close(creat(exrtab[i].exkf,0644)); break; } else { printf("\n`%s' - not running !",&xrn); goto s_xit; } #endif killpg(pgrp, SIGTERM); wmsg(); time(&stime1); for( ;; ) { time(&stime2); if((stime2 - stime1) > sswait) break; if(swiflag) { /* cancel wait loop */ printf("\nWait loop canceled !\n"); goto s_xit2; } #ifdef EFLG eflg[i>>5] = evntflg(EFRD, efid[i>>5], (long)0); if((eflg[i>>5] & (1L << (i & 037))) == 0) { exrtab[i].exs = XSTOP; stoped(exrtab[i].exlf); break; } #else if(access(exrtab[i].exkf, 0) != 0) { exrtab[i].exs = XSTOP; stoped(exrtab[i].exkf); break; } #endif } s_xit2: if(exrtab[i].exs != XSTOP) nostop(exrtab[i].exlf); } else { /* stop all copies of an exerciser */ #ifdef EFLG eflg[0] = 0L; eflg[1] = 0L; for(i=0, j=0, k=0; exrtab[i].exn; i++) if(strcmp(&line, exrtab[i].exn) == 0) { k++; if(exrtab[i].exs == XRUN) { j++; eflg[i>>5] |= (1L << (i & 037)); } } if(eflg[0]) evntflg(EFWRT, efid[0], (long)eflg[0]); if(eflg[1]) evntflg(EFWRT, efid[1], (long)eflg[1]); #else for(i=0, j=0, k=0; exrtab[i].exn; i++) if(strcmp(&line, exrtab[i].exn) == 0) { k++; if(exrtab[i].exs == XRUN) { j++; close(creat(exrtab[i].exkf,0644)); } } #endif if(k == 0) { printf("\n`%s' - not in script !", &line); goto s_xit; } if(j == 0) { printf("\n`%s' - no copies running !", &line); goto s_xit; } killpg(pgrp, SIGTERM); wmsg(); time(&stime1); for( ;; ) { k = 0; time(&stime2); if((stime2 - stime1) > sswait) break; if(swiflag) { /* cancel wait loop */ printf("\nWait loop canceled !\n"); goto s_xit3; } for(i=0; exrtab[i].exn; i++) { if(exrtab[i].exs != XRUN) continue; if(strcmp(&line, exrtab[i].exn) == 0) { k++; #ifdef EFLG eflg[i>>5] = evntflg(EFRD, efid[i>>5], (long)0); if((eflg[i>>5] & (1L << (i & 037))) == 0) { exrtab[i].exs = XSTOP; stoped(exrtab[i].exlf); } #else if(access(exrtab[i].exkf, 0) != 0) { exrtab[i].exs = XSTOP; stoped(exrtab[i].exkf); } #endif } } if(k == 0) break; } s_xit3: for(i=0; exrtab[i].exn; i++) if((strcmp(&line, exrtab[i].exn) == 0) && (exrtab[i].exs != XSTOP)) nostop(exrtab[i].exlf); } s_xit: for(j=0; exrtab[j].exn; j++) if(exrtab[j].exs == XRUN) if(exrtab[j].exlf) logused++; if(logused) alarm(60); for(j=0; exrtab[j].exn; j++) if(exrtab[j].exs == XRUN) break; if(exrtab[j].exn == 0) { xrun = 0; #ifdef EFLG evntflg(EFREL, efid[0], (long)0); if(efid[1]) evntflg(EFREL, efid[1], (long)0); #endif unlink("sysxr.nx"); } signal(SIGINT, intr); break; case 'l': /* PRINT LOG FILES */ if(logused) /* turn off alarm clock */ alarm(0); do printf("\nPrint which log files <all> ? "); while((cc = getline(19)) < 0); if(tall(cc)) lstall = 1; else lstall = 0; printf("\nOutput on line printer"); if(yes(NO, NOHELP) == YES) { if(lstall) { system("pr *.log |lpr"); } else if(cc <= 5) { p = strcpy(&xrn, "pr "); p = strcat(p, &line); p = strcat(p, "*.log |lpr"); system(p); } else { if(access(&line, 0) != 0) { lferr: printf("\nNo such log file !"); break; } p = strcpy(&xrn, "pr "); p = strcat(p, &line); p = strcat(p, " |lpr"); system(p); } if(logused) /* turn on alarm clock */ logmon(); } else { /* code to use more commented out printf("\nUse more for video terminal"); if(yes(NO, NOHELP) == YES) { if(lstall) system("pr *.log | more -22"); else if(cc <= 5) { p = strcpy(&xrn, "pr "); p = strcat(p, &line); p = strcat(p, "*.log"); p = strcat(p, " | more -22"); system(p); } else { if(access(&line, 0) != 0) goto lferr; p = strcpy(&xrn, "pr "); p = strcat(p, &line); p = strcat(p, " | more -22"); system(p); } } else { */ if(lstall) system("pr *.log"); else if(cc <= 5) { p = strcpy(&xrn, "pr "); p = strcat(p, &line); p = strcat(p, "*.log"); system(p); } else { if(access(&line, 0) != 0) goto lferr; p = strcpy(&xrn, "pr "); p = strcat(p, &line); system(p); } if(logused) /* turn on alarm clock */ logmon(); /* } commented out: goes with 'more' code */ } break; case 'b': /* illegal option in run mode */ case 'c': /* illegal option in run mode */ case 'd': /* illegal option in run mode */ case 'n': /* illegal option in run mode */ case 'x': /* illegal option in run mode */ printf("\nThe %s command is illegal when in run mode !\n", line); break; default: goto badl; } goto cloop; } /* * Handle yes or no responses. * If only return typed take default response. * y or yes is the yes response anything else is NO ! * def = 1, default answer is yes - return 1 on yes * def = 0, default answer is no - return 0 on no * hlp = 1, help available - return -1 on ? * hlp = 0, no help - print "type yes or no" on ? */ yes(def, hlp) { char resp[10]; int cc; buflag = 0; if(def) printf(" <yes> ? "); else printf(" <no> ? "); yn: alrmflag = 0; fflush(stdout); cc = read(0, (char *)&resp, 10); if((cc == -1) && alrmflag) goto yn; if(cc == 0) { /* ^D - cancel script line */ buflag++; return(NO); } if(cc > 4) return(NO); if(cc == 1) return(def); if((cc == 2) && (resp[0] == '?')) { if(hlp == HELP) return(-1); else { printf("\nPlease answer yes or no ! "); goto yn; } } if(resp[0] == 'y') { if(cc == 2) return(YES); if((cc == 4) && (resp[1] == 'e') && (resp[2] == 's')) return(YES); } else return(NO); } /* * Get a line of text form the terminal, * replace the new line character with 0 * and return the character count. * hlp = 0, print `no help available' * hlp > 0, print help message if `?' typed */ getline(hlp) { register int cc, i; buflag = 0; loop: alrmflag = 0; fflush(stdout); while((cc = read(0, (char *)&line, 50)) >= 50) printf("\nToo many characters, try again !\n"); if((cc == -1) && alrmflag) goto loop; for(i=0; i<50; i++) { if((line[i] >= 'A') && (line[i] <= 'Z')) line[i] |= 040; /* force lower case */ if((line[i] == '\r') || (line[i] == '\n')) { line[i] = 0; break; } } if(cc == 0) { /* ^D - cancel script line */ buflag++; return(cc); } if((cc == 2) && (line[0] == '?')) { cc = -1; switch(hlp) { case NOHELP: printf("\nSorry no help available !"); break; case 18: dohelp("s"); break; case 19: dohelp("l"); break; default: printf("\nsysx: bad help message number\n"); break; } } return(cc); } intr() { signal(SIGINT, intr); longjmp(savej, 1); } swintr() { signal(SIGINT, SIG_IGN); swiflag++; } tall(cc) { if((cc == 1) || (strcmp("a", line) == 0) || (strcmp("all", line) == 0)) return(1); else return(0); } /* * Monitor the growth of log files every 15 minutes, * to warn the user that errors are occurring and * that disk space could become tight ! */ logmon() { register int i, ft; long sd; if(!xrun || !logused) return; alrmflag++; /* tell the world alarm occurred */ alrmcnt++; ft = 0; for(i=0; exrtab[i].exn; i++) { if(exrtab[i].exlf == 0) continue; /* no logfile */ if(stat(exrtab[i].exlf, &statb) < 0) { printf("\nsysx: Can't stat %s file\n", exrtab[i].exlf); continue; } exrtab[i].nsz = statb.st_size; sd = exrtab[i].nsz - exrtab[i].osz; if((sd && (alrmcnt >= 15)) || (sd > 500)) { if(ft++ == 0) { time(&timbuf); printf("\n\n\t Log file status - %s ", ctime(&timbuf)); } printf("\nLog file `%13s' size changed", exrtab[i].exlf); printf(" from %06lu to %06lu bytes", exrtab[i].osz, exrtab[i].nsz); exrtab[i].osz = exrtab[i].nsz; } } if(ft) printf("\n\nrun> "); fflush(stdout); if(alrmcnt >= 15) alrmcnt = 0; signal(SIGALRM, logmon); alarm(60); } /* * Scan the script in sbuf and load the needed * pointers to names and the like into the exerciser * control table (exrtab). */ setext() { register int i; register char *n; eflg[0] = 0L; eflg[1] = 0L; for(i=0, n = &sbuf; *n; i++) { exrtab[i].exn = n; /* exer name */ while(*++n != ' ') ; *n++ = '\0'; /* terminate name string */ if(*n == '-') exrtab[i].exo = n; /* options */ else exrtab[i].exo = 0; /* no options, can't happen */ #ifdef EFLG eflg[i>>5] |= (1L << (i & 037)); nexer++; while((*n != '>') && (*n != '&') && (*n != '\n')) n++; if(exrtab[i].exo) *(n-1) = '\0'; #else exrtab[i].exkf = 0; while((*n != '>') && (*n != '&') && (*n != '\n')) { if(*n++ == '-') if(*n++ == 'r') { /* kill file */ exrtab[i].exkf = ++n; while(*++n != ' ') ; *n++ = '\0'; } } if(exrtab[i].exo && (exrtab[i].exkf == 0)) *(n-1) = '\0'; #endif exrtab[i].exlf = 0; if(*n == '>') { n += 2; exrtab[i].exlf = n; /* log file */ while(*++n != ' ') ; *n++ = '\0'; } while(*n++ != '\n') ; if((*n == 0) && (*(n+1) != 0)) n++; /* ed strips nulls from end of line */ exrtab[i].exs = XSTOP; exrtab[i+1].exn = 0; /* terminate table */ if(i == (MAXEXR - 1)) { printf("\nMaximum of %d exercisers reached !", MAXEXR); break; } } } nostop(kfn) char *kfn; { register char *q, *p; char xn[20]; q = &xn; p = kfn; while(*p != '.') *q++ = *p++; *q = '\0'; printf("\n`%8s' did not stop !", &xn); } nostart(kfn) char *kfn; { register char *q, *p; char xn[20]; q = &xn; p = kfn; while(*p != '.') *q++ = *p++; *q = '\0'; printf("\n`%8s' did not start !", &xn); } stoped(kfn) char *kfn; { register char *q, *p; char xn[20]; q = &xn; p = kfn; while(*p != '.') *q++ = *p++; *q = '\0'; time(&timbuf); printf("\n%8s stopped - %s", &xn, ctime(&timbuf)); } started(kfn) char *kfn; { register char *q, *p; char xn[20]; q = &xn; p = kfn; while(*p != '.') *q++ = *p++; *q = '\0'; time(&timbuf); printf("\n%8s started - %s", &xn, ctime(&timbuf)); } wmsg() { printf("\nWaiting for shutdown confirmation from exercisers."); printf("\nTyping <CTRL/C> will cancel wait loop !\n"); swiflag = 0; signal(SIGINT, swintr); } wmsg2() { printf("\nWaiting for startup confirmation from exercisers."); printf("\nTyping <CTRL/C> will cancel wait loop !\n"); swiflag = 0; signal(SIGINT, swintr); } /* * Convert an int to an ascii string * and place it in "str". * Strip off leading zero's */ itos(num, str) int num; char *str; { char *n; int i, x, div, frst; frst = 0; x = 0; n = str; i = num; div = 10000; while(div) { x = (i / div); if((x != 0) && (!frst)) frst++; if(frst) *n++ = (x + '0'); i -= (x * div); div /= 10; } *n++ = '\0'; if(*str == '\0') { *str++ = '0'; *str = '\0'; } } /* * Run an exerciser * For each exer in script * do a fork/exec dynamically adding "-z efpis efid" to each exer * note: "i" is the "position in script" */ run(pis,appflg) int pis; int appflg; { int i, j; char *n; char *execbuf[25]; static char z1[] = "-z"; char parse[256]; for(i = 0; i < 256; i++) parse[i] = 0; i = pis; j = 0; execbuf[j++] = exrtab[i].exn; if(exrtab[i].exo) { strcpy(parse, exrtab[i].exo); n = &parse[0]; execbuf[j++] = n; while(*n++ != '\0') { if(*n == ' ') { execbuf[j++] = n+1; *n++ = '\0'; } } } execbuf[j++] = &z1; n = &z2; if(i > 31) itos((i-32), z2); else itos(i, z2); execbuf[j++] = &z2; if(i > 31) execbuf[j++] = &z4; else execbuf[j++] = &z3; execbuf[j++] = 0; if(exrtab[i].exlf != 0) if(appflg) freopen(exrtab[i].exlf, "a", stdout); else freopen(exrtab[i].exlf, "w", stdout); if(fork() == 0) { execv(exrtab[i].exn, execbuf); printf("exec failed\n"); exit(0); } if(exrtab[i].exlf != 0) freopen("/dev/tty", "w", stdout); } dohelp(s) char *s; { register int i, j; /* if(args[0] == 0) args[0] = "help"; */ for(i=0; hsub[i].hs_name; i++) if(strcmp(s, hsub[i].hs_name) == 0) break; if(hsub[i].hs_name == 0) { printf("\nNo help available for `%s' subject.\n", s); return(1); } for(j=0; hsub[i].hs_msg[j]; j++) { if(hsub[i].hs_msg[j] == -1) { printf("%s", gs_more); while(getchar() != '\n') ; continue; } printf("\n%s", hsub[i].hs_msg[j]); } }