zeeff@b-tech.UUCP (Jon Zeeff) (08/26/88)
Posting-number: Volume 4, Issue 36 Submitted-by: "Jon Zeeff" <zeeff@b-tech.UUCP> Archive-name: ringback [People, *please* "shar" your submissions!!!!! Apologies for the delay; "jetroff" was clogging the pipes. It will probably start going out on September 6. ++bsa] #! /bin/sh echo x - ringback.c sed 's/^X//' << \EOF > ringback.c X/* X XRingback.c V1.3 X XThis program implements a ring-back system that allows a phone line Xthat is normally used as a voice line and a dial-out data line to be Xused as a limited dial-in data and voice line. It does not interfere Xwith the use of the line for an answering machine. X XIt solves a problem for my situation: X X1) I am normally in my office. The phone line is used for dial-out via Xmodem and dial-in/dial-out voice traffic. X X2) I sometimes travel, at which time I connect an answering machine to Xthe line. X X3) I'd like to be able to call in to my system via modem when I am Xtravelling, without interfering with others use of my answering Xmachine. X X4) I don't want to pay for another phone line. X XThis program functions by watching a tty port for an incoming call on Xa smart modem. Forty seconds after an incoming call, it will spawn a Xgetty on the line. If no one calls and logs in, the getty will be Xkilled by an uncaught alarm and the line will be set back to a no Xanswer state. X XThis implements a ringback dialin system. Just call, wait a minute, Xand call again. X XIf the program notices that a user (uucp or kermit) is using the line Xfor an outgoing call, it will back off until that call is completed. X(Note: the first modem response char will be eaten. Uucp dialing scripts Xshould be set up to tolerate this.) X XWritten for Sys V.3 and HDB uucp (but easily modified for others) X XTwo arguments must be present - tty and type X XSample lines from /etc/inittab: X rb:1234:respawn:/etc/ringback tty1 1200 X XMake sure that you trust the people who are allowed to login on this Xline. It is possible for them to dial-out on the line. X XTo install: X X1) Edit TTYID and TTYGID and UUGETTY. X2) Compile and install as /etc/ringback X3) Create an initab line like the above one. X X - Jon Zeeff (umix!b-tech!zeeff) X XThis program is in the public domain. X X*/ X X#include <stdio.h> X#include <sys/types.h> X#include <sys/stat.h> X#include <signal.h> X#include <fcntl.h> X#include <termio.h> X Xchar *strcpy(); Xchar *strcat(); Xunsigned sleep(); Xunsigned alarm(); Xvoid exit(); X X/* the id and gid for normal ownership of tty lines (usually uucp) */ X X#define TTYID 5 /* uucp */ X#define TTYGID 11 /* staff */ X X/* if you have a getty/tty/modem combination that doesn't get in a babbling X getty loop, then there is no need to define this. If you do, make sure X that /etc/uugetty exists. X*/ X#define UUGETTY /* #define UUGETTY */ X Xmain(argc,argv) Xint argc; Xchar **argv; X{ X Xchar c; XFILE *tty0,*tty1,*tty2; X#ifdef DEBUG XFILE *console; X#endif XFILE *tty; XFILE *lock; Xstruct termio ttymodes; Xstruct stat buf; Xchar tty_lock[100]; Xchar tty_name[100]; Xint i; X X/* name and location of tty locks - change this as needed */ X Xstrcpy(tty_lock,"/usr/spool/locks/LCK.."); Xstrcat(tty_lock,argv[1]); X Xstrcpy(tty_name,"/dev/"); Xstrcat(tty_name,argv[1]); X Xif (argc != 3) exit(2); X Xunlink(tty_lock); Xumask(022); X Xsignal(SIGHUP,SIG_IGN); Xsignal(SIGINT,SIG_IGN); Xsignal(SIGQUIT,SIG_IGN); Xsignal(SIGTERM,SIG_IGN); X Xfor (;;) { X X /* Set the line permissions, owner, and group for dial-out use */ X X chown(tty_name,TTYID,TTYGID); X chmod(tty_name,0660); X X /* Open line - getty will close the first 3, so make sure we are #4 */ X /* so that the modem doesn't get reset on dtr drop and our autoanswer */ X /* setting don't get undone. */ X X tty0 = fopen(tty_name,"r+"); X tty1 = fopen(tty_name,"r+"); X tty2 = fopen(tty_name,"r+"); X tty = fopen(tty_name,"r+"); X X fclose(tty0); fclose(tty1); fclose(tty2); X X#ifdef DEBUG Xconsole = fopen("/dev/console","w"); Xfprintf(console,"check 1\n"); fflush(console); X#endif X X ttymodes.c_iflag = 0; X ttymodes.c_oflag = NL1 | CR3; X ttymodes.c_cflag = 0; X ttymodes.c_lflag = 0; X ttymodes.c_line = 0; X for (i = 0; i < NCC; ++i) ttymodes.c_cc[i] = 0; X ttymodes.c_cc[VMIN] = 1; /* min number of characters */ X ttymodes.c_cc[VTIME] = 0; /* no max time before return */ X ioctl(fileno(tty),TCSETA,&ttymodes); /* hang up the line */ X sleep(1); X ttymodes.c_cflag = B1200 | CS8 | CREAD | HUPCL; X ioctl(fileno(tty),TCSETA,&ttymodes); X sleep(1); X#ifdef DEBUG Xfprintf(console,"check 1.3\n"); fflush(console); X#endif X X /* setup the modem */ X X fputs("AT\r",tty); fflush(tty); sleep(1); X fputs("ATZ\r",tty); fflush(tty); sleep(2); X fputs("ATS0=0\r",tty); fflush(tty); sleep(1); /* Don't answer phone */ X fputs("ATE0\r",tty); fflush(tty); sleep(1); X fputs("ATV0\r",tty); fflush(tty); sleep(1); X fputs("ATQ0\r",tty); fflush(tty); sleep(1); X X#ifdef DEBUG Xfprintf(console,"check 2\n"); fflush(console); X#endif X fcntl(fileno(tty),F_SETFL,O_NDELAY); /* Set to nonblocking reads */ X while (read(fileno(tty),&c,(unsigned)1) == 1); /* Flush input */ X fcntl(fileno(tty),F_SETFL,O_RDWR); /* Set to blocking reads */ X X /* Wait for incoming call ('2') or other usage (uucp or user) */ X X /* Get char from tty port */ X X while (read(fileno(tty),&c,(unsigned)1) != 1); X X /* X If we receive a '2' and no lock file is present, we can be sure X that it is not someone calling out. X */ X X#ifdef DEBUG Xfprintf(console,"check 2.5 %d\n",c); fflush(console); X#endif X X if ((c&0x7f) == '2' && stat(tty_lock,&buf) == -1) { X X /* create a hdb style lock file */ X X lock = fopen(tty_lock,"w"); X if (lock) { X fprintf(lock,"%10.10d\n",(int)getpid()); X fclose(lock); X } X X /* wait for this call to end */ X X sleep(32); /* should be long enough for answering machine X to answer if they let it ring. */ X X /* Setup modem for incoming call */ X X fputs("AT\r",tty);fflush(tty);sleep(1); X fputs("ATZ\r",tty);fflush(tty);sleep(1); X fputs("ATQ1\r",tty);fflush(tty);sleep(1); X fputs("ATS0=1\r",tty);fflush(tty);sleep(5); X X#ifdef DEBUG Xfprintf(console,"check 4\n"); fflush(console); X#endif X X /* set things up so the getty will live a short life */ X X alarm(120); X X#ifndef UUGETTY X execl("/etc/getty","getty","-t","90","-h", X argv[1],argv[2],(char *)0); X#else X unlink(tty_lock); X execl("/etc/uugetty","uugetty","-r","-h","-t","90", X argv[1],argv[2],(char *)0); X#endif X X#ifdef DEBUG Xfprintf(console,"check 5\n"); fflush(console); X#endif X } else { /* Must be someone using line */ X X fclose(tty); /* Release line */ X X /* Loop until lock file goes away (uucp or user done) */ X X do { X while (stat(tty_lock,&buf) == 0) sleep(40); X sleep(40); X } while (stat(tty_lock,&buf) == 0); X X } /* end_if */ X X } /* next */ X X} EOF exit 0 -- Jon Zeeff Branch Technology, uunet!umix!b-tech!zeeff zeeff%b-tech.uucp@umix.cc.umich.edu