ks (07/28/82)
#N:pur-ee:9200001:000:6017 pur-ee!ks Jul 27 17:19:00 1982 static char *sccsid = "@(#)talk.c 4.2 (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 * aef 1-17-81 */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <signal.h> #include <utmp.h> #include <time.h> #include <sgtty.h> struct sgttyb stbuf; short cptr; #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(); int ildisc; /* original line discipline */ int locmod; /* newtty local mode bits */ short lctlech = LCTLECH; main(argc, argv) char *argv[]; { struct stat stbuf; register ii, i; register FILE *uf; int c1, c2; 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<NMAX; i++) { c1 = ubuf.ut_name[i]; if(c1 == ' ') c1 = 0; me[i] = c1; if(c1 == 0) break; } } if (histtya != 0) for(i=0; i<LMAX; i++) { c1 = histty[i+5]; c2 = ubuf.ut_line[i]; if(c1 == 0) if(c2 == 0 || c2 == ' '){ for(ii=0; ii<NMAX; ii++) { c1 = him[ii]; c2 = ubuf.ut_name[ii]; if(c1 == 0) if(c2 == 0 || c2 == ' ') break; if(c1 != c2) { histty[0] = '\0'; break; } } } if(c1 != c2) break; } if(him[0] != '-' || him[1] != 0) for(i=0; i<NMAX; i++) { c1 = him[i]; c2 = ubuf.ut_name[i]; if(c1 == 0) if(c2 == 0 || c2 == ' ') break; if(c1 != c2) goto nomat; } logcnt++; if (histtya==0 && logcnt == 2) { printf("%s logged more than once\n", him); printf("on: %s", histty+5); } if (histtya==0 && logcnt > 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<LMAX; i++) { c1 = histty[i+5]; c2 = ubuf.ut_line[i]; if(c1 == 0) if(c2 == 0 || c2 == ' '){ for(ii=0; ii<NMAX; ii++) { c1 = him[ii]; c2 = ubuf.ut_name[ii]; if(c1 == 0) if(c2 == 0 || c2 == ' ') goto fwd; if(c1 != c2){ histty[0] = '\0'; break; } } goto fwd; } if(c1 != c2) break; } } } fwd: fclose(uf); if(histty[0] == 0) { printf(him); if(logcnt) printf(" not on that tty\n"); else printf(" not logged in\n"); exit(1); } if (access(histty, 0) < 0) { printf("No such tty\n"); exit(1); } signal(SIGALRM, timout); alarm(5); if ((tf = fopen(histty, "w")) == NULL) goto perm; alarm(0); if (fstat(fileno(tf), &stbuf) < 0) goto perm; if ((stbuf.st_mode&02) == 0) goto perm; sigs(eof); fprintf(tf, "\r\nMessage from "); #ifdef interdata fprintf(tf, "(Interdata) " ); #endif fprintf(tf, "%s on %s at %d:%02d ...\r\n" , me, mytty , localclock -> tm_hour , localclock -> tm_min ); fflush(tf); gtty(0,&stbuf); ioctl(0, TIOCGETD, &ildisc); /* check if new line discipline */ if(ildisc == NTTYDISC){ ioctl(0, TIOCLGET, &locmod); /* get local bits */ if(locmod & LCTLECH) ioctl(0, TIOCLBIC, &lctlech); /* clear ctlecho */ } stbuf.sg_flags |= CBREAK; stty(0,&stbuf); printf("\07"); fflush(stdout); cptr = 0; for(;;) { char buf; i = read(0, &buf, 1); if(i <= 0) eof(); if(buf == '\04') eof(); if(buf == stbuf.sg_erase){ write( fileno( tf ), "\b \b", 3); continue; } cptr++; if(buf == '!' && cptr == 1) { char buf1[128]; while( buf != '\n'){ read(0, &buf, 1); buf1[cptr++] = buf; if(buf == stbuf.sg_erase){ if(cptr)cptr -= 2; } } 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"); gtty(0,&stbuf); stbuf.sg_flags &= ~ CBREAK; stty(0,&stbuf); if(ildisc == NTTYDISC){ if(locmod & LCTLECH) ioctl(0, TIOCLBIS, &lctlech); /* reset ctlecho */ } 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) { gtty(0,&stbuf); stbuf.sg_flags &= ~ CBREAK; stty(0,&stbuf); sigs((int (*)())0); execl(getenv("SHELL") ? getenv("SHELL") : "/bin/sh", "sh", "-c", bp+1, 0); exit(0); } while(wait((int *)NULL) != i) ; printf("!\n"); out: gtty(0,&stbuf); stbuf.sg_flags |= CBREAK; stty(0,&stbuf); sigs(eof); } sigs(sig) int (*sig)(); { register i; for(i=0;signum[i];i++) signal(signum[i],sig); }
ks (08/01/82)
#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 <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <signal.h> #include <utmp.h> #include <time.h> #include <sgtty.h> 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<NMAX; i++) { c1 = ubuf.ut_name[i]; if(c1 == ' ') c1 = 0; me[i] = c1; if(c1 == 0) break; } } if (histtya != 0) for(i=0; i<LMAX; i++) { c1 = histty[i+5]; c2 = ubuf.ut_line[i]; if(c1 == 0) if(c2 == 0 || c2 == ' '){ for(ii=0; ii<NMAX; ii++) { c1 = him[ii]; c2 = ubuf.ut_name[ii]; if(c1 == 0) if(c2 == 0 || c2 == ' ') break; if(c1 != c2) { histty[0] = '\0'; break; } } } if(c1 != c2) break; } if(him[0] != '-' || him[1] != 0) for(i=0; i<NMAX; i++) { c1 = him[i]; c2 = ubuf.ut_name[i]; if(c1 == 0) if(c2 == 0 || c2 == ' ') break; if(c1 != c2) goto nomat; } logcnt++; if (histtya==0 && logcnt == 2) { printf("%s logged more than once\n", him); printf("on: %s", histty+5); } if (histtya==0 && logcnt > 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<LMAX; i++) { c1 = histty[i+5]; c2 = ubuf.ut_line[i]; if(c1 == 0) if(c2 == 0 || c2 == ' '){ for(ii=0; ii<NMAX; ii++) { c1 = him[ii]; c2 = ubuf.ut_name[ii]; if(c1 == 0) if(c2 == 0 || c2 == ' ') goto fwd; if(c1 != c2){ histty[0] = '\0'; break; } } goto fwd; } if(c1 != c2) break; } } } fwd: fclose(uf); if(histty[0] == 0) { printf(him); if(logcnt) printf(" not on that tty\n"); else printf(" not logged in\n"); exit(1); } if (access(histty, 0) < 0) { printf("No such tty\n"); exit(1); } signal(SIGALRM, timout); alarm(5); if ((tf = fopen(histty, "w")) == NULL) goto perm; alarm(0); if (fstat(fileno(tf), &stbuf) < 0) goto perm; if ((stbuf.st_mode&02) == 0) goto perm; sigs(eof); fprintf(tf, "\r\nMessage from "); #ifdef interdata fprintf(tf, "(Interdata) " ); #endif fprintf(tf, "%s on %s at %d:%02d ...\r\n" , me, mytty , localclock -> 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