root@ozdaltx.UUCP (08/30/87)
I know this is probably simple, but for the life of me I can't figure out how to do it. I need to be able to monitor, at will, a port or tty and be able to see what the person using the tty is seeing and what they are responding. I'm running SCO XENIX V5. You'd think this would be simple to do... but... Any ideas? -- ************************************************ * Scotty * Adapt * * ihnp4!killer!ozdaltx!sysop * Enjoy * * "Ad Venerem Securiorem" * Survive *
root@ozdaltx.UUCP (09/25/87)
First, let thank the 30 or so folks who responded in reference of my looking for code for a tty watcher that *might* run on a XENIX system. Some of the names on the responces looked like a who's who in *NIX. However, after many "I wrote"s, "I have written"s , chest pounding and other self induced back slapping, forwarded to this site, with four or five possible exceptions, I have yet to see any genuine offers of help... either in the form of actual code or logical suggestions. Also noted that many of the responders obviously DID NOT read/understand the original question as the referenced systems ranged from Sun to MINIX (sp?) to whatever.. In other words referencing specific "flavors" of *NIX... when generic was/is needed. What has prompted this is, I have seen too many people in the same situation as I'm in. Asking honest questions and hoping for a legitimate responce. Instead I see (quite often from the same people), something to the effect of, "YOU DUMB S**T.. READ THE F***ING MANUAL... YOU SHOULD BE A GURU LIKE THE REST OF US". etc., etc., ect. This seems to be a common malady among programers. (I'm sure I've suffered the same on occasion). How about putting the ole egos out to pasture and cut the **FLAMES** to the newcommers. I once had a professor who's favorite saying was, "There is no such thing as a dumb question, unless it is never asked". To future posters, at least tell what system/version you are running. *NIX IS NOT STANDARD.... YET. We ALL started out pretty DUMB. -- ============================================================ | Scotty | Adapt - Enjoy - Survive | | ihnp4!killer!ozdaltx!sysop | "Ad Venerem Securiorem" | ============================================================
drears@ARDEC.arpa (10/03/87)
I just started reading this discussion. I am enclosing a program soemone sent to me that will allow people with kmem read access to watch the input of a tty. It will not work if the user is in raw mode. I do not know the orginal author's name. It was sent to me unsolicited about two years ago. Dennis Disclaimer: Opinions and statements are mine only. cut here ------------------------ #include <stdio.h> #include <sys/param.h> #include <sys/clist.h> #include <nlist.h> #include <ctype.h> #include "tty.h" #define NDZ 1 /* should be gotten from /sys/dev/dz.h */ #define NDH 3 /* should be gotten from /sys/dev/dh.h */ #define DZ11 1 /* major device number of the dz11 */ #define DH11 12 /* major device number of the dh11 */ #define DZ_X 8 /* eight lines per dz11 */ #define DH_X 16 /* sixteen lines per dh11 */ #undef major() /* need to do this because of kernel */ #undef minor() /* macros used to strip off device #'s */ static struct nlist nl[2]; static char *name_list[] = { "_dz_tty" , /* base address of the dz tty structures*/ "_dh11" , /* same for the dh's */ 0 }; main(argc , argv) char **argv; int argc; { /********************************/ int major; /* place to hold major # */ int minor; /* place to hold minor # */ int board_type; /* tells me which kind of tty */ int fd; /* fd for memory */ long offset; /* how far into the above tables*/ struct tty ttyb; /* place to put the tty buffer */ extern char *calloc(); /* our friend calloc */ char *p; /* destroy the argv's so noone */ /* can see what we are doing */ /********************************/ get_args(&major , &minor , argc , argv); check_args(major , minor , &board_type , argv); get_name_list(board_type , argv); open_memory(&fd , argv); for (p = argv[1]; *p != '\0'; p++) *p = '\0'; for (p = argv[2]; *p != '\0'; p++) *p = '\0'; offset = minor * sizeof(struct tty); fflush(stdout); fflush(stdout); while (1) { read_tty(fd , nl[0].n_value , offset , &ttyb); get_clist(fd , &ttyb.t_nu.t_t.T_rawq); } } /** *** Much monkeying around was done before I settled on this *** procedure. I attempted to follow the c_next pointers in *** the individual cblocks. This is friutless since by the *** time we do the second seek and read the information has *** been whisked away. *** *** So - The LIMITATIONS of this routine are: *** *** cannot read from any tty in RAW mode *** can only snarf first 28 characters (ie *** the first cblock) *** *** Nice things about this routine: *** *** only NEW characters are echoed to the output *** (eg characters in the cblock which have been *** seen before are swallowed). **/ get_clist(fd , cl) register struct clist *cl; { static char c[CBSIZE]; static char *old_start = 0 , *old_finish = 0; static int old_i = 0; char *pntr; int tn , in; if ((cl->c_cc > 0) && ((old_start != cl->c_cf) || (old_finish != cl->c_cl))) { pntr = c; lseek(fd , (long) cl->c_cf , 0); read(fd , c ,(tn=in=cl->c_cc > CBSIZE ? CBSIZE : cl->c_cc)); if (old_start == cl->c_cf) { in -= old_i; pntr += old_i; } if (in > 0) while (in--) putchar(*(pntr++)); else if (in < 0) while (in++) putchar('\010'); fflush(stdout); old_i = tn; old_start = cl->c_cf; old_finish = cl->c_cl; } if (cl->c_cc <= 0) { if (old_i != 0) putchar('\n'); old_i = old_start = old_finish = NULL; } } /** *** The rest of the routines are very strait forward and *** Rick and Lory won't need comments. **/ read_tty(fd , base , offset , buffer) long base , offset; register struct tty *buffer; { register int i; lseek(fd , base + offset , 0); i = read(fd , buffer , sizeof(struct tty)); if (i != sizeof(struct tty)) { printf("unexpected return from read\n"); printf("should have been %d\n" , sizeof(struct tty)); printf("was %d\n" , i); exit(0); } } open_memory(fd , argv) int *fd; char **argv; { if ((*fd = open("/dev/kmem" , 0)) < 0) { perror(argv[0]); exit(0); } } get_name_list(index,argv) char **argv; { nl[0].n_name = name_list[index]; nlist("/vmunix" , nl); if (! nl[0].n_type) { printf("%s: couldn't get name list\n" , argv[0]); } printf("%s starts at %08x\n" , nl[0].n_name , nl[0].n_value); } get_args(major , minor , argc , argv) int *major , *minor , argc; char **argv; { if (argc != 3) { fprintf(stderr,"%s: arg count\n" , argv[0]); exit(0); } *major = atoi(argv[1]); *minor = atoi(argv[2]); printf("Major Device: %d -- Minor Device: %d\n" , *major , *minor); } check_args(major , minor , board , argv) char **argv; int *board; { if (minor < 0) { bad_minor: printf("%s: bad minor device number\n" , argv[0]); exit(0); } switch (major) { case DZ11: if (minor >= NDZ * DZ_X) goto bad_minor; printf("DZ11 - Unit %d\n" , minor / DZ_X); *board = 0; break; case DH11: if (minor >= NDH * DH_X) goto bad_minor; printf("DH11 - Unit %d\n" , minor / DH_X); *board = 1; break; default: printf("%s: bad major device number\n" , argv[0]); exit(0); } }