[comp.dcom.modems] Callback program wanted

bill@videovax.Tek.COM (William K. McFadden) (11/30/88)

Does anybody have a callback program for 4.3 BSD?  I would like to have the
VAX call me at home and allow me to login (instead of my dialing).  Here's my
situation:  Calling the VAX is a toll call, but the VAX can call me for free.
(Actually it's free for me right now; I want to change to metered phone service
to save money.)  What I would like to do is call the VAX and tell it to wait a
minute and call me back.  That way I only have to pay for the first minute.
Surely somebody has implemented something similar on their system.  Can
anybody help with this?  Thanks.
-- 
Bill McFadden    Tektronix, Inc.  P.O. Box 500  MS 58-639  Beaverton, OR  97077
UUCP: bill@videovax.Tek.COM,  {hplabs,uw-beaver,decvax}!tektronix!videovax!bill
GTE: (503) 627-6920    Silliest new cartoon title: Teenage Mutant Ninja Turtles

rpw3@amdcad.AMD.COM (Rob Warnock) (12/02/88)

In article <5342@videovax.Tek.COM> bill@videovax.Tek.COM (William K. McFadden)
writes:
+---------------
| Does anybody have a callback program for 4.3 BSD?  I would like to have the
| VAX call me at home and allow me to login (instead of my dialing).  Here's my
| situation:  Calling the VAX is a toll call, but the VAX can call me for free.
| (Actually it's free for me right now; I want to change to metered phone...
| to save money.)  What I would like to do is call the VAX and tell it to wait a
| minute and call me back.  That way I only have to pay for the first minute.
| Surely somebody has implemented something similar on their system.  Can
| anybody help with this?  Thanks.
+---------------

Attached below (since I've meant to for a long time) is the C program I
use for *exactly* that purpose. It is a hack of a hack, and only works
as it stands for Telebit Trailblazers, but has #ifdef's for a few others
(Hayes & Practical Peripherals). (I know, I know, it should be a run-time
decision...)

To use, dial in to your host, log in, then say "callback <your-number>".
It will hang up the phone, dial you back, and then prompt you for your
login password. (You get three tries in 60 seconds to get it right.)

NO WARRANTY, NO SUPPORT, but it's free...     "It works for me."

Known deficiencies: It waits a fixed amount of time (30 sec.) before
assuming the callback should have completed, and prompting you for your
password. If you use it over very long distance callbacks, you may need
to jack this time up. On the other hand, very local users may wish to
decrease it. (That's why there's source!)

It was originally written by Jim Budler when he was at AMD (Thanks, Jim!),
but I've hacked on it enough that all bugs are mine. Read the comments; read
the code. I tried to document the problems I found (with modems, with 4.3)
as I went along.

Nota Bene: To avoid potentially locked-up modems or security problems (whether
or not you use this program, incidentally), your modems *MUST* be configured
to reset to NVRAM settings on DTR-down.


Rob Warnock
Systems Architecture Consultant

UUCP:	  {amdcad,fortune,sun}!redwood!rpw3
ATTmail:  !rpw3
DDD:	  (415)572-2607
USPS:	  627 26th Ave, San Mateo, CA  94403

============ attachment ======================================

/*
 * callback.c - sets tty nohang, noecho and ignore carrier,
 *		then does call back and restores tty settings
 *
 * 860520 jimb@glc1	created
 *
 * 870410 rpw3@amdcad	Modified to circumvent 4.3 conflict between carrier
 *			and output (between hangup and re-dial).
 *
 * 880728 rpw3@amdcad	Do password checking ourselves, rather than exec'ing
 *			login. Lets you keep your same environment. If fail,
 *			kill our parent shell, SIGHUP the process group, and
 *			DTR-down the line.
 *			(Bug? If parent is not top-level shell, can somebody
 *			else can dial in? Maybe. How secure is SIGHUP?)
 */


#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sgtty.h>
#include <pwd.h>

/* define exactly one of the following: */
/* #define PASSWORD	/* uncomment for glc1 Password Modem */
/* #define HAYES	/* uncomment for Hayes 1200 baud */
/* #define PPI		/* Practical Peripherals Inc. 2400 baud */
#define TB		/* Telebit TrailBlazer+ */

int parent;
struct passwd *pw;

main (argc,argv)
int argc;
char *argv[];
{
	int nohup = LNOHANG;
	int flushargs = 0;
	struct sgttyb ttystuff;
	int catcher();

	if( argc != 2 ) {
	    fprintf(stderr,"Usage: %s phone-number\n",argv[0]);
	    exit(1);
	}
	parent = getppid();
	if (parent <= 1)		/* don't try to kill init */
		parent = 0;
	pw = getpwuid(getuid());
	if (!pw) {
		fprintf(stderr, "Can't get pw entry!\n");
		exit(1);
	}
	if (!pw->pw_passwd) {
		fprintf(stderr, "Sorry, null password not allowed here!\n");
		exit(1);
	}
	signal(SIGINT, SIG_IGN);	/* turn off interrrupts */
	signal(SIGQUIT, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGTSTP, SIG_IGN);
	signal(SIGTTIN, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);
	setbuf(stdout,NULL); 		/* kill buffering */

	ioctl( 0, TIOCGETP, &ttystuff);
	ttystuff.sg_flags &= (~ECHO); /* stty noecho */
	ioctl( 0, TIOCSETP, &ttystuff);
	ioctl( 0, TIOCLBIS, &nohup); /* stty nohang */

#ifdef PASSWORD		/* Password modem picky about timing */
	sleep(2); printf("+++");sleep(2);	/* send the "+++" */
	printf("\r");sleep(1);
	printf("ATM0Q1DT %s\r",argv[1]);
#else HAYES_or_PPI_or_TB
	sleep(4); printf("+++");sleep(4);	/* send the "+++" */
	/* With 4.3, must do it all in one cmd
	 * to avoid the problem of not being
	 * able to write if carrier is down.
	 */
#ifdef HAYES
	printf("ATH,,,,,,DT%s\r",argv[1]);	/* hangup, wait 12, re-dial */
#else  PPI_or_TB
	/* Because the PPI and TB don't obey "," as a command (only as a dial
	 * modifier), we have to break hangup/dialback into two commands.
	 * To get around the 4.3 + carrier problem, we have to disable carrier-
	 * detection between the commands. DZ-11's can't do this (the driver
	 * is broken), so we can't use the ioctl. Solution: Tell the *modem*
	 * to ignore carrier with &C0. Hazard: If we die in the middle, the
	 * modem stays misconfigured. Safeguard: The PPI is configured &D3,
	 * so when "login" times out and drops DTR, we'll get &C1 ("respect
	 * carrier") back from the NVRAM.
	 */
#ifdef TB
	printf("ATS53=0H\r",argv[1]);		/* hangup, but with CD on */
#else PPI
	printf("AT&C0H\r",argv[1]);		/* hangup, but with CD on */
#endif PPI
	sleep(6);				/* wait for full hangup */
#ifdef TB
	printf("ATS53=3DT,,,%s\r",argv[1]);	/* re-dial (normal CD) */
#else PPI
	printf("AT&C1DT,,,%s\r",argv[1]);	/* re-dial (normal CD) */
#endif PPI
#endif PPI_or_TB
#endif not_PASSWORD
	sleep(30);		/* wait until it's certain to have answered */
	ioctl( 0, TIOCFLUSH, &flushargs);	/* flush any garbage... */
	ttystuff.sg_flags |= ECHO;		/* stty echo */
	ioctl( 0, TIOCSETP, &ttystuff);
	ioctl( 0, TIOCLBIC, &nohup);		/* stty hang */
	printf("\nWe're back!\007\n\n");	/* Hey, Yo! WAKE UP! */
	signal(SIGINT, catcher);		/* allow interrrupts */
	signal(SIGHUP, catcher);
	signal(SIGQUIT, catcher);
	alarm(0);
	signal(SIGALRM, catcher);
	alarm(60);				/* time, but not TOO much */
	if (checkpass())			/* verify same guy */
		catcher();			/* no? then die, scum! */
	exit(0);
}

catcher()
{
	ioctl( 0, TIOCCDTR, 0);		/* hang up the phone */
	if (parent > 1)
		kill(parent, SIGHUP);
	kill(0, SIGHUP);
	_exit(0);
}

int
checkpass()
{
	int i;
	extern char *crypt(), *getpass();
	char *pass, *pass2;

	for (i = 0; i < 3; ++i) {
		pass = getpass("Password: ");
		pass2 = crypt(pass, pw->pw_passwd);
		if (strcmp(pass2, pw->pw_passwd) == 0)
			return 0;
	}
	return -1;
}