From: utzoo!decvax!pur-ee!ks Newsgroups: net.sources Title: Re: talk.c - unbuffered write.c - (nf) Article-I.D.: pur-ee.475 Posted: Sun Aug 1 01:26:30 1982 Received: Sun Aug 1 04:34:51 1982 #R:pur-ee:9200001:pur-ee:9200002:000:6339 pur-ee!ks Jul 31 23:34:00 1982 "Better" version of talk.c with a few problems fixed.. Thanks to sdcarl!rusty and psi!jed. Kirk Smith Purdue EE static char *sccsid = "@(#)talk.c 4.2 (pur-ee!aef & Berkeley) 10/1/80"; /* * TALK * write to another user * (from write.c) * Modified A E Feather for unbuffered writes * 29-Oct-80 * Modified to handle "newtty" driver ctlecho mode * pur-ee!aef 1-17-81 * Modified to set terminal to -echo mode to make the screen reflect erasures * like on the other terminal. Also eliminated need for local mode stuff. * Handles STOP signals from terminals properly for BSD systems. * pur-ee!ks 7-31-8 (with help from sdcarl!rusty) */ #include#include #include #include #include #include #include struct sgttyb tbuf; short cptr; #define SETMODES gtty(0,&tbuf); tbuf.sg_flags |= CBREAK;\ tbuf.sg_flags &= ~ECHO; stty(0,&tbuf) #define RESETMODES gtty(0,&tbuf); tbuf.sg_flags &= ~CBREAK;\ tbuf.sg_flags |= ECHO; stty(0,&tbuf) #define NMAX sizeof(ubuf.ut_name) #define LMAX sizeof(ubuf.ut_line) char *strcat(); char *strcpy(); struct utmp ubuf; int signum[] = {SIGHUP, SIGINT, SIGQUIT, 0}; char me[10] = "???"; char *him; char *mytty; char histty[32]; char *histtya; char *ttyname(); char *rindex(); int logcnt; int eof(); int timout(); FILE *tf; char *getenv(); main(argc, argv) char *argv[]; { struct stat stbuf; register ii, i; register FILE *uf; int c1, c2, c3; long clock = time( 0 ); struct tm *localtime(); struct tm *localclock = localtime( &clock ); if(argc < 2) { printf("usage: talk user [ttyname]\n"); exit(1); } him = argv[1]; if(argc > 2) histtya = argv[2]; if ((uf = fopen("/etc/utmp", "r")) == NULL) { printf("cannot open /etc/utmp\n"); goto cont; } mytty = ttyname(2); if (mytty == NULL) { printf("Can't find your tty\n"); exit(1); } /* check if message permission on mytty is on */ if(stat(mytty, &stbuf) < 0){ printf("Can't stat your tty!\n"); exit(1); } if((stbuf.st_mode&02) == 0){ printf("Your message permission is OFF!\n"); exit(1); } mytty = rindex(mytty, '/') + 1; if (histtya) { strcpy(histty, "/dev/"); strcat(histty, histtya); } while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) { if (strcmp(ubuf.ut_line, mytty)==0) { for(i=0; i 1){ printf(", %s", ubuf.ut_line); } if (histtya==0) { strcpy(histty, "/dev/"); strcat(histty, ubuf.ut_line); } nomat: ; } cont: if (logcnt==0 && histty[0]=='\0') { printf("%s not logged in.\n", him); exit(1); } if(histtya == 0 && logcnt > 1){ printf("\nTalk to which one: "); fflush(stdout); strcpy(histty, "/dev/"); i = read(0, histty+5, 8); if(i>8)i=8; histty[i+4] = '\0'; lseek(fileno(uf), 0L, 0); while (fread((char *)&ubuf, sizeof(ubuf), 1, uf) == 1) { for(i=0; i tm_hour , localclock -> tm_min ); fflush(tf); SETMODES; printf("\07"); fflush(stdout); cptr = 0; for(;;) { char buf; for(c3 = 0; c3 < 10 ; c3++) { i = read(0, &buf, 1); if(i > 0) break; } if(i <= 0) eof(); if(buf == '\04') eof(); if(buf == tbuf.sg_erase){ write(1, "\b \b", 3); write( fileno( tf ), "\b \b", 3); if(cptr>0) cptr--; continue; } write(1, &buf, 1); cptr++; if(buf == '!' && cptr == 1) { char buf1[128]; RESETMODES; while( buf != '\n') { read(0, &buf, 1); buf1[cptr++] = buf; } buf1[--cptr] = 0; ex(buf1); cptr = 0; continue; } write(fileno(tf), &buf, 1); if ( buf == '\n' ){ write( fileno( tf ) , "\r" , 1 ); cptr = 0; } } perm: printf("Permission denied\n"); exit(1); } timout() { printf("Timeout opening their tty\n"); exit(1); } eof() { fprintf(tf, "EOF\r\n"); RESETMODES; exit(0); } ex(bp) char *bp; { register i; sigs(SIG_IGN); i = fork(); if(i < 0) { printf("Try again\n"); goto out; } if(i == 0) { sigs(SIG_IGN); execl(getenv("SHELL") ? getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0); exit(0); } while(wait((int *)NULL) != i) ; printf("!\n"); out: SETMODES; sigs(eof); } sigs(sig) int (*sig)(); { register i; #ifdef SIGTSTP int onsusp(); if(sig == SIG_DFL) signal(SIGTSTP, SIG_DFL); else signal(SIGTSTP, onsusp); #endif for(i=0;signum[i];i++) signal(signum[i],sig); } #ifdef SIGTSTP onsusp() { signal(SIGTSTP, SIG_IGN); RESETMODES; sigs(SIG_DFL); kill(0, SIGTSTP); /* the pc stops here */ SETMODES; sigs(eof); } #endif