sandy@turnkey.TCC.COM (Sanford 'Sandy' Zelkovitz) (01/23/89)
The following is the Xenix 386, version 2.3.1 modifications to Ed Carp's uustatus and filefind. It turns out that the SCO Xenix HDB uucp has 23 return codes instead of the 22 that uustatus.h described. When error code 23 was encountered a memory fault core dump was the result. The code now looks for a M_XENIX compile switch, which is automatically given by the SCO compiler and the proper includes, etc. are compiled. Since SCO only supports HDB uucp in their 386 release to date, no attempt has been made to test it under Xenix286. Sandy ------------------ cut/ax/snip/whatever here ------------------------- #!/bin/sh # to extract, remove the header and type "sh filename" if `test ! -s ./README` then echo "writing ./README" cat > ./README << '\Rogue\Monster\' uustatus - by Ed Carp HDB UUCP may be a dream to some, but for me it can be a real pain, keeping up with everything that's happening on my system. This simple (relatively) program dynamically displays the status of your UUCP connections for you, without you having to cd into all of those pesky directories. It's also faster than uustat -m, and it's real-time! The best part about this mish-mash, however, is dirent.h. I liked the BSD/XENIX directory routines a lot, but didn't have them on my System V box. So, I hacked up a couple of routines that work just as well. opendir(), closedir(), and readdir() are all that are supported, but that was (and still is) enough for most system programming applications. I also have a little gadget that will search your path for a program - handy if you can get to a program (execute it), but need to know where the dumb thing is, and don't have the time to waste with "find `echo $PATH|tr ... stuff. It's also MUCH faster, and it's included FREE! Compiling: 1. cc -s -o uustatus uustatus.c -lcurses -ltermcap -O (or whatever libraries your system needs to support curses). cc -s -o findpath findpath.c -O Docs: The manpage source is in uustatus.1, the nroff'ed output is in uustatus.prt, and the viewable output is in uustatus.doc. I used the -man macro package, so it should work on anyone's system. Customization: There are a number of tuneable parameters in uustatus.h that you can play with. #define STATUS "/usr/spool/uucp/.Status" This is where HDB UUCP puts its status files. This should not be changed. #define LOCKFILE "/usr/spool/uucp/LCK..%s" This is where the lock files reside. Don't touch this, either... #define WORKFILE "/usr/spool/uucp/%s" This is another one of those "don't touch me" parameters... #define EXPDAYS 14 /* connections older than X days will not be displayed */ In this example, UUCP connections older than 14 days will not be displayed, regardless of their status. #define LOGON NO /* log expired systems? */ If you want to log everything that goes on, set this to YES. Generally useless except for debugging. #define LOGFILE "/tmp/uuexp.log" This is where the log output goes. #define WAITMSG "WAIT" Standard wait message. #define BWAITMSG " " /* blank wait msg string */ This must be the same length as the WAITMSG string (unless you want your screen to wind up looking strange). #define LLIMIT LINES-5 This is how many lines of data we can display on the screen. Generally a no-no to touch. #define FLIMIT 50 /* over this many files for site, we quit - must be < 100 */ When we scan the directories for work, we don't want to eat up too many system resources if we have a large directory with lots of stuff in it (not too uncommon for a large news feed), so after we read FLIMIT file names, we quit that directory and indicate that we have over that many files. I set mine to 50, bt you can use a smaller number if your system is very I/O bound (like you're running XENIX on an XT with a 65ms hard drive). #define SLEEPTIME 10 /* time to sleep between samples */ Time to sleep between samples. If you have a fast system with caching, you might want to up this to make it more real-time. If nothing ever happens on your system and you want to leave this up in a window, you might want to set it to something like 30 or 60. That's it! Enjoy...and please remember -- if you make any changes or enhancements, please let me know (context diffs are OK). No warranty expressed or implied. I have tried as best I could to make sure there are no bugs, but you know how that goes...at least it doesn't do anything but read files... Enhancements: Well, a sorted display of systems would be nice...Any other suggestions? ----------------------------------- cut here ----------------------------------- Ed Carp N7EKG/5 (28.3-28.5) erc@unisec.usi.com UniSecure Systems, Inc.; OS/2, Just say No! Round Rock, Tx; (home) (512) 834-2507 UUCP: erc@unisec Snail Mail: 2001A Pipersfield Austin, Tx 78758 Be ye therefore kind one to another, tenderhearted, forgiving one another, even as God for Christ's sake hath forgiven you. -- Ephesians 4:32 \Rogue\Monster\ else echo "will not over write ./README" fi if `test ! -s ./basename.fun` then echo "writing ./basename.fun" cat > ./basename.fun << '\Rogue\Monster\' /* * * basename - returns base name of whatever's pass to it * strips off directory info * not for MSDOS * */ char *basename(string) char *string; { /* strips off directory information from string */ char *strrchr(); static char outstr[256]; char *target, *start; start = strrchr(string, '/'); /* find last slash */ if(start == NULL) return(string); start++; /* bump past / */ strcpy(outstr, start); return(outstr); } \Rogue\Monster\ else echo "will not over write ./basename.fun" fi if `test ! -s ./dirent.h` then echo "writing ./dirent.h" cat > ./dirent.h << '\Rogue\Monster\' /* * * /usr/include/dirent.h for SYS V (AT&T) * * Copyright 1989 by Edwin R. Carp * * kludgy, but it works... * */ #define DIR FILE #define dirent direct #include <sys/dir.h> static struct direct wdp; DIR *opendir(name) char *name; { return(fopen(name, "r")); } struct direct *readdir(dp) DIR *dp; { int ret; while(1) { ret=fread(&wdp, 1, sizeof(struct direct), dp); if(ret < sizeof(struct dirent)) return((struct direct *)NULL); if(wdp.d_ino == 0) continue; return(&wdp); } } closedir(dp) DIR *dp; { fclose(dp); } \Rogue\Monster\ else echo "will not over write ./dirent.h" fi if `test ! -s ./findpath.1` then echo "writing ./findpath.1" cat > ./findpath.1 << '\Rogue\Monster\' .TH FINDPATH 1 .SH NAME findpath \- find file in path path \- display path directories .SH SYNOPSIS /usr/local/bin/findpath .I file .SH DESCRIPTION .I Findpath will report on the location of .I file, searching every directory in the path (as defined in the $PATH variable), much like the operating system does when searching $PATH to execute a program. It is handy for finding out where in your path a command resides. .PP .I Findpath is linked to .I path, which simply displays a list of directories to be searched. It is much faster than 'echo $PATH|tr ":" " "'. .SH SEE ALSO csh(1) .SH CREDITS This utility was written by Ed Carp. \Rogue\Monster\ else echo "will not over write ./findpath.1" fi if `test ! -s ./findpath.c` then echo "writing ./findpath.c" cat > ./findpath.c << '\Rogue\Monster\' static char *sccsid = "%Z% %M% %I% %G% %U%"; /* * * findpath - find a command in a path * path - list directories searched in path * * usage: findpath command(s) * path * * Written by Ed Carp * */ #include <stdio.h> #ifndef BSD #include <string.h> #else #include <strings.h> #endif #include <sys/types.h> #ifdef M_XENIX #include <sys/ndir.h> #define dirent direct #else #include <dirent.h> #endif #include "basename.fun" #include "strrep.fun" char *getenv(); main(argc, argv) int argc; char **argv; { DIR *d; struct dirent *dire; char *dir, *ptr, path[512], home[64]; int i=1, vflag=0, pflag=0; if(strcmp("path", basename(argv[0])) == 0) { pflag = 1; vflag = 1; } if(argc < 2 && pflag == 0) { fprintf(stderr, "usage: findpath command(s)...\n"); exit(1); } if((dir=getenv("path")) == (char *)NULL) { if((dir=getenv("PATH")) == (char *)NULL) { fprintf(stderr, "PATH not set!\n"); exit(1); } } /* expand ~ in path to $HOME */ strcpy(home, getenv("HOME")); if(home != (char *)EOF) { while((ptr=strrep("~", home, dir)) != (char *)EOF) { strcpy(dir, ptr); } } strcpy(path, dir); /* save it away */ ptr = path; while((dir=strtok(ptr, ":")) != (char *)NULL) { ptr = NULL; if(!pflag) { if((d=opendir(dir)) == (DIR *)NULL) { perror(dir); continue; } } if(vflag) printf("%s\n", dir); if(!pflag) { while((dire=readdir(d)) != (struct dirent *)NULL) { if(strcmp(dire->d_name, argv[i]) == 0) printf("%s/%s\n", dir, argv[i]); } } closedir(d); } } \Rogue\Monster\ else echo "will not over write ./findpath.c" fi if `test ! -s ./findpath.doc` then echo "writing ./findpath.doc" cat > ./findpath.doc << '\Rogue\Monster\' FINDPATH(1) FINDPATH(1) NAME findpath - find file in path path - display path directories SYNOPSIS /usr/local/bin/findpath file DESCRIPTION Findpath will report on the location of file, searching every directory in the path (as defined in the $PATH variable), much like the operating system does when searching $PATH to execute a program. It is handy for finding out where in your path a command resides. Findpath is linked to path, which simply displays a list of directories to be searched. It is much faster than 'echo $PATH|tr ":" " "'. SEE ALSO csh(1) CREDITS This utility was written by Ed Carp. Page 1 (printed 1/20/89) \Rogue\Monster\ else echo "will not over write ./findpath.doc" fi if `test ! -s ./findpath.prt` then echo "writing ./findpath.prt" cat > ./findpath.prt << '\Rogue\Monster\' FINDPATH(1) FINDPATH(1) NAME findpath - find file in path path - display path directories SYNOPSIS /usr/local/bin/findpath _f_i_l_e DESCRIPTION _F_i_n_d_p_a_t_h will report on the location of _f_i_l_e, searching every directory in the path (as defined in the $PATH variable), much like the operating system does when searching $PATH to execute a program. It is handy for finding out where in your path a command resides. _F_i_n_d_p_a_t_h is linked to _p_a_t_h, which simply displays a list of directories to be searched. It is much faster than 'echo $PATH|tr ":" " "'. SEE ALSO csh(1) CREDITS This utility was written by Ed Carp. Page 1 (printed 1/20/89) \Rogue\Monster\ else echo "will not over write ./findpath.prt" fi if `test ! -s ./strrep.fun` then echo "writing ./strrep.fun" cat > ./strrep.fun << '\Rogue\Monster\' #ifndef NULL #include <stdio.h> #endif char *strrep(a, b, c) /* replace first a with b in string c */ char *a, *b, *c; { char *pd; static char d[512]; /* yes, yes, could be fancier, I know! */ *d = '\0'; pd = d; while(*c) { if(strncmp(a, c, strlen(a)) == 0) break; *pd++ = *c++; } if(!*c) return((char *)EOF); /* a not found in c */ *pd = '\0'; strcat(d, b); strcat(d, c+strlen(a)); return(d); } \Rogue\Monster\ else echo "will not over write ./strrep.fun" fi if `test ! -s ./uustatus.1` then echo "writing ./uustatus.1" cat > ./uustatus.1 << '\Rogue\Monster\' .TH UUSTATUS 1L "January 20, 1989" "Version 1.0" .ad b .SH NAME uustatus \- check UUCP status on HDB systems .SH SYNOPSIS uustatus .SH DESCRIPTION .I Uustatus will dynamically display the status of ongoing and failed UUCP connections. It is intended to be used with the HDB (HoneyDanBer) UUCP system. .SH PORTING This utility was written for System V; however it should run "as is" on BSD systems and should run on XENIX systems by changing the reference to .B dirent.h in .B uustatus.h to .B sys/ndir.h. .SH NOTES As distributed, this utility will not display statistics concerning failed UUCP connections due to "WRONG TIME TO CALL" errors. .SH CREDITS This utility was written by Edwin R. Carp. \Rogue\Monster\ else echo "will not over write ./uustatus.1" fi if `test ! -s ./uustatus.c` then echo "writing ./uustatus.c" cat > ./uustatus.c << '\Rogue\Monster\' /* * * uustatus - display UUCP communications status for HDB systems * * Written 01/19/89 by Ed Carp * * Copyright 1989, by Edwin R. Carp * */ char *sccsid = "uustatus, version 1.0 01/20/89 Copyright 1989 by Edwin R. Carp"; #include <stdio.h> #include <sys/types.h> #include <curses.h> #ifdef M_XENIX #include <sys/ndir.h> #define dirent direct #else #include "dirent.h" #endif #include <time.h> #include <signal.h> #define YES 1 #define NO 0 #include "uustatus.h" #include "basename.fun" DIR *din, *win; struct dirent *dp, *dpw; FILE *in, *exp; main(argc, argv) int argc; char **argv; { int i, status, files, retries, bye(); int systems, expflag, display; long secs, retryt, curr; char line[512], lock[64], cretries[6]; char cfiles[6], work[64], name[15]; struct tm *t1, *t2; printf("%s\n\n", sccsid); if(argc > 2) { printf("usage: %s\n", basename(argv[0])); exit(1); } sleep(2); chdir(STATUS); for(i=1; i<4; i++) signal(i, bye); if(LOGON) exp = fopen(LOGFILE, "w"); initscr(); while(1) { move(0, 0); if((din=opendir(".")) == (DIR *)NULL) { perror(STATUS); exit(1); } printw("SYSTEM RETRY FILES LAST TRY NEXT TRY STATUS"); time(&curr); if(LOGON) fprintf(exp, "%s", ctime(&curr)); display = systems = 0; move(0, COLS-(1+strlen(WAITMSG))); standout(); addstr(WAITMSG); standend(); move(2, 0); refresh(); clrtobot(); while((dp=readdir(din)) != (struct dirent *)NULL) { if(display > LLIMIT) break; if(*dp->d_name == '.') continue; systems++; if((in=fopen(dp->d_name, "r")) == (FILE *)NULL) continue; fgets(line, 510, in); fclose(in); line[strlen(line)-1] = 0; sscanf(line, "%d %d %ld %ld", &status, &retries, &secs, &retryt); expflag = 0; strcpy(name, dp->d_name); if((curr - secs) > ((long)EXPDAYS*(long)24*(long)60*(long)60)) { if(LOGON) fprintf(exp, "%s EXPIRED! (%ld - %ld) > %ld\n", name, curr, secs, ((long)EXPDAYS*(long)24*(long)60*(long)60)); expflag = 1; } sprintf(lock, LOCKFILE, name); sprintf(work, WORKFILE, name); files = 0; if((win=opendir(work)) != (DIR *)NULL) { /* count the number of C. files */ while((dp=readdir(win)) != (struct dirent *)NULL) { if(strncmp(dp->d_name, "C.", 2) == 0) files++; if(files > FLIMIT) break; } closedir(win); } if(files != 0) sprintf(cfiles, "%d", files); else strcpy(cfiles, " "); if(files > FLIMIT) sprintf(cfiles, ">%d", FLIMIT); if(retries != 0) sprintf(cretries, "%d", retries); else strcpy(cretries, " "); /* kludges for screwy status stuff with HDB */ if(access(lock, 0) == 0 && status != 3) status = 22; if(status == 11) status = 13; /* fix bug */ if(status == 2) continue; /* skip WRONG TIME TO CALL */ t1 = localtime(&secs); retryt += secs; t2 = localtime(&retryt); if(expflag == 0) printw("%-14s %-3s %-3s ", name, cretries, cfiles); else if(LOGON) fprintf(exp, "%-14s %-3d ", name, retries); t1 = localtime(&secs); if(expflag == 0) printw("%02d/%02d %02d:%02d ", t1->tm_mon+1, t1->tm_mday, t1->tm_hour, t1->tm_min); else if(LOGON) fprintf(exp, "%02d/%02d %02d:%02d ", t1->tm_mon+1, t1->tm_mday, t1->tm_hour, t1->tm_min); t2 = localtime(&retryt); if(expflag == 0) printw("%02d/%02d %02d:%02d ", t2->tm_mon+1, t2->tm_mday, t2->tm_hour, t2->tm_min); else if(LOGON) fprintf(exp, "%02d/%02d %02d:%02d ", t2->tm_mon+1, t2->tm_mday, t2->tm_hour, t2->tm_min); if(status == 3 || status == 22) standout(); if(expflag == 0) printw("%s\n", errortext[status]); else if(LOGON) fprintf(exp, "%s\n", errortext[status]); if(status == 3 || status == 22) standend(); display++; } printw("\n%d UUCP connections active", systems); move(0, COLS-(1+strlen(BWAITMSG))); addstr(BWAITMSG); move(1, 0); refresh(); closedir(din); sleep(SLEEPTIME); } } bye(sig) int sig; { if(LOGON) fclose(exp); endwin(); exit(0); } \Rogue\Monster\ else echo "will not over write ./uustatus.c" fi if `test ! -s ./uustatus.doc` then echo "writing ./uustatus.doc" cat > ./uustatus.doc << '\Rogue\Monster\' UUSTATUS(1L) Version 1.0 UUSTATUS(1L) NAME uustatus - check UUCP status on HDB systems SYNOPSIS uustatus DESCRIPTION Uustatus will dynamically display the status of ongoing and failed UUCP connections. It is intended to be used with the HDB (HoneyDanBer) UUCP system. PORTING This utility was written for System V; however it should run "as is" on BSD systems and should run on XENIX systems by changing the reference to dirent.h in uustatus.h to sys/ndir.h. NOTES As distributed, this utility will not display statistics concerning failed UUCP connections due to "WRONG TIME TO CALL" errors. CREDITS This utility was written by Edwin R. Carp. Page 1 (January 20, 1989) (printed 1/20/89) \Rogue\Monster\ else echo "will not over write ./uustatus.doc" fi if `test ! -s ./uustatus.h` then echo "writing ./uustatus.h" cat > ./uustatus.h << '\Rogue\Monster\' /* * * tuneable parameters * */ #define STATUS "/usr/spool/uucp/.Status" #define LOCKFILE "/usr/spool/uucp/LCK..%s" #define WORKFILE "/usr/spool/uucp/%s" #define EXPDAYS 14 /* connections older than X days will not be displayed */ #define LOGON NO /* log expired systems? */ #define LOGFILE "/tmp/uuexp.log" #define WAITMSG "WAIT" #define BWAITMSG " " /* blank wait msg string */ #define LLIMIT LINES-5 #define FLIMIT 50 /* over this many files for site, we quit - must be < 100 */ #define SLEEPTIME 10 /* time to sleep between samples */ /* * * end of tuneable parameters * */ char *errortext[] = { /* SS_OK 0 */ "SUCCESSFUL", /* SS_NO_DEVICE 1 */ "NO DEVICES AVAILABLE", /* SS_TIME_WRONG 2 */ "WRONG TIME TO CALL", /* SS_INPROGRESS 3 */ "TALKING", /* SS_CONVERSATION 4 */ "CONVERSATION FAILED", /* SS_SEQBAD 5 */ "BAD SEQUENCE CHECK", /* SS_LOGIN_FAILED 6 */ "LOGIN FAILED", /* SS_DIAL_FAILED 7 */ "DIAL FAILED", /* SS_BAD_LOG_MCH 8 */ "BAD LOGIN/MACHINE COMBINATION", /* SS_LOCKED_DEVICE 9 */ "DEVICE LOCKED", /* SS_ASSERT_ERROR 10 */ "ASSERT ERROR", /* SS_BADSYSTEM 11 */ "SYSTEM NOT IN Systems FILE", /* SS_CANT_ACCESS_DEVICE 12 */ "CAN'T ACCESS DEVICE", /* SS_DEVICE_FAILED 13 */ "DEVICE FAILED", /* SS_WRONG_MCH 14 */ "WRONG MACHINE NAME", /* SS_CALLBACK 15 */ "CALLBACK REQUIRED", /* SS_RLOCKED 16 */ "REMOTE HAS A LCK FILE FOR ME", /* SS_RUNKNOWN 17 */ "REMOTE DOES NOT KNOW ME", /* SS_RLOGIN 18 */ "REMOTE REJECT AFTER LOGIN", /* SS_UNKNOWN_RESPONSE 19 */ "REMOTE REJECT, UNKNOWN MESSAGE", /* SS_STARTUP 20 */ "STARTUP FAILED", /* SS_CHAT_FAILED 21 */ "CALLER SCRIPT FAILED", #ifdef M_XENIX /* 22 */ "EXECDIAL LOCAL FAILURE", /* 23 */ "EXECDIAL REMOTE FAILURE", #else /* 22 */ "CALL IN PROGRESS", #endif }; \Rogue\Monster\ else echo "will not over write ./uustatus.h" fi if `test ! -s ./uustatus.prt` then echo "writing ./uustatus.prt" cat > ./uustatus.prt << '\Rogue\Monster\' UUSTATUS(1L) Version 1.0 UUSTATUS(1L) NAME uustatus - check UUCP status on HDB systems SYNOPSIS uustatus DESCRIPTION _U_u_s_t_a_t_u_s will dynamically display the status of ongoing and failed UUCP connections. It is intended to be used with the HDB (HoneyDanBer) UUCP system. PORTING This utility was written for System V; however it should run "as is" on BSD systems and should run on XENIX systems by changing the reference to dirent.h in uustatus.h to sys/ndir.h. NOTES As distributed, this utility will not display statistics concerning failed UUCP connections due to "WRONG TIME TO CALL" errors. CREDITS This utility was written by Edwin R. Carp. Page 1 (January 20, 1989) (printed 1/20/89) \Rogue\Monster\ else echo "will not over write ./uustatus.prt" fi echo "Finished archive 1 of 1" exit -- Sanford <sandy> Zelkovitz XBBS 714-898-8634 UUCP: ....att!hermix!alphacm!sandy ....trwrb!ucla-an!alphacm!sandy ....uunet!turnkey!alphacm!sandy ....ucbvax!ucivax!icnvax!alphacm!sandy DATA: 714-898-8634 VOICE: 714-894-7898
rjg@sialis.mn.org (Robert J. Granvin) (01/27/89)
In article <5316@turnkey.TCC.COM> sandy@turnkey.TCC.COM (Sanford 'Sandy' Zelkovitz) writes: >The following is the Xenix 386, version 2.3.1 modifications to Ed Carp's >uustatus and filefind. It turns out that the SCO Xenix HDB uucp has 23 >return codes instead of the 22 that uustatus.h described. When error code >23 was encountered a memory fault core dump was the result. The code >now looks for a M_XENIX compile switch, which is automatically given by >the SCO compiler and the proper includes, etc. are compiled. Since SCO only >supports HDB uucp in their 386 release to date, no attempt has been made >to test it under Xenix286. If you're not running SCO, and you still have core dumps or memory faults after the copyright notice comes up, check for a line in uustatus.c that reads: while(fgets(line, 510, in) != (char *)NULL) and change it to: while(fgets(line, 128, in) != (char *)NULL) Earlier in the code, line is defined as a char of 128 positions. Making this change will prevent the memory fault/core dumps. This seems to work fine. :-) -- Robert J. Granvin "A cowboy should know his horse, but it National Information Services seemed to the podners at the Triple Q rjg@sialis.mn.org Ranch that Vernon McChew had gotten TOO {amdahl,hpda}!bungia!sialis!rjg close."