From:	MERC::"uunet!CRVAX.SRI.COM!RELAY-INFO-VAX" 11-JUN-1992 01:44:30.81
To:	info-vax@kl.sri.com
CC:	
Subj:	Re: Dial-back modem access

In article <1992Jun7.222121.1@geovax.ed.ac.uk>, boss@geovax.ed.ac.uk (Bruce Gittings) writes:
>I live in a country where we are charged (too much!!) for local phone calls 
>and I therefore wonder if someone on the net can help use reduce costs.
>
>Does anyone have a program which will cause a modem attached to VAX/VMS
>to dial back to the caller, thus charging my employers rather than myself?
>
>What I want to do is call through to the VAX to indicate I wish to log
>in,  then have it call me back offering a session.

Here are two programs that do it for a Hayes-compatible modem.  The first
program should be run once during the system startup procedure.  It sets the
MODHANGUP bit in the terminal characteristics.  The second is to be run by the
user wanting the computer to dial back to him.

/** SETUP_MODEM.C -- set the MODHANGUP bit in the terminal characteristics. ***/
#include iodef
#include ssdef
#include ttdef
#include tt2def
#include descrip

main(nargs, args)
int nargs;
char **args;
{   struct
    {   unsigned short status, count;
	unsigned char term, dummy, trmlen, linel;
    } iosb;
    $DESCRIPTOR(modemname, "");
    long tmpchar[3], stat, efn, efs;
    short chan, func, cnt;
    unsigned char buffer[255];

    modemname.dsc$a_pointer = *++args;
    modemname.dsc$w_length = strlen(modemname.dsc$a_pointer);
/* Assign channel to modem line */
    if(((stat = SYS$ASSIGN(&modemname, &chan, 0, 0)) & 7) != 1)
	exit(stat);
/* And get terminal characteristics */
    if((((stat=SYS$QIOW(0,chan,IO$_SENSECHAR,&iosb,0,0,
	tmpchar,12,0,0,0,0)) & 7) != 1) ||
	(((stat = iosb.status) & 7) != 1))
	exit(stat);
/* Then set modified characteristics */
    tmpchar[2] |= TT2$M_MODHANGUP;
    if((((stat=SYS$QIOW(0,chan,IO$_SETCHAR,&iosb,0,0,
	tmpchar,12,0,0,0,0)) & 7) != 1) ||
	(((stat = iosb.status) & 7) != 1))
	exit(stat);
    SYS$EXIT(1);
}
/***************************** End SETUP_MODEM.C ******************************/

/******** DIALBACK.C -- Call back the user on a Hayes-compatible modem ********/
/*	Usage:  DIALBACK [phone_number] [terminal_line] 		      */
#include iodef
#include ssdef
#include ttdef
#include tt2def
#include descrip
#include dvidef
#include stdio
#define debug

main(nargs, args)
int nargs;
char **args;
{   struct
    {   unsigned short status, count;
	unsigned char term, dummy, trmlen, linel;
    } iosb;
    FILE *fp;
    unsigned char buffer[255], command[255], *number, mdm[64];
    long tmpchar[3], stat, i;
    short chan;
    $DESCRIPTOR(modemname, mdm);
    struct item_list_3
    {	unsigned short buflen, itmcod;
	unsigned long *bufadr, *reslen;
    } itmlst[] =
    {	{   64, DVI$_TT_PHYDEVNAM, mdm, &modemname.dsc$w_length },
	{   0, 0, 0, 0 }
    };
    $DESCRIPTOR(dev, "sys$input");

#ifdef debug
    fp = fopen("dialback.log", "w");
#endif
    if(--nargs > 0)
	number = *++args;
    else
    {	printf("Number: ");
	number = gets(buffer);
    }
    sprintf(command,"ATQ0S52=2DT%s\r", number);
    if(--nargs > 0)
    {	modemname.dsc$a_pointer = *++args;
	modemname.dsc$w_length = strlen(modemname.dsc$a_pointer);
    } else if((((stat = SYS$GETDVI(0, 0, &dev, itmlst, &iosb, 0, 0, 0)) & 7)
	!=1) || ((iosb.status& 7) != 1))
	SYS$EXIT(stat);
/* Assign channel to modem line */
    if(((stat = SYS$ASSIGN(&modemname, &chan, 0, 0)) & 7) != 1)
	exit(stat);
    if((((stat=SYS$QIOW(0,chan,IO$_SETMODE|IO$M_HANGUP,&iosb,0,0,0,0,0,0,0,0)) &
	7) != 1) || (((stat = iosb.status) & 7) != 1))
	exit(stat);
    SYS$DASSGN(chan);
    for(stat = i = 0; i < 36 && ((stat & 7) != 1); ++i)
    {	sleep(i == 0 ? 2 : 5);
	stat = SYS$ASSIGN(&modemname, &chan, 0, 0);
    }
    if ((stat & 7) != 1) exit(stat);
/* And get terminal characteristics */
    if((((stat=SYS$QIOW(0,chan,IO$_SENSEMODE,&iosb,0,0,
	tmpchar,12,0,0,0,0)) & 7) != 1) ||
	(((stat = iosb.status) & 7) != 1))
	exit(stat);
/* Then set modified characteristics */
    tmpchar[1] |= TT$M_NOECHO | TT$M_HOSTSYNC;
    tmpchar[2] &= ~TT2$M_HANGUP;
    if((((stat=SYS$QIOW(0,chan,IO$_SETMODE,&iosb,0,0,
	tmpchar,12,0,0,0,0)) & 7) != 1) ||
	(((stat = iosb.status) & 7) != 1))
	exit(stat);
/* Set up MODEM for appropriate operation */
    if((((stat=SYS$QIOW(0,chan,IO$_WRITEVBLK,&iosb,0,0,
	command,strlen(command),0,0,0,0)) & 7) != 1) ||
	(((stat = iosb.status) & 7) != 1))
    	exit(stat);
/* Wait for connection */
    while(((stat=SYS$QIOW(0,chan,IO$_READVBLK | IO$M_TIMED, &iosb, 0, 0,
	buffer, 255, 59, 0, 0, 0)) & 7) == 1)
    {	if((iosb.status & 7) != 1) SYS$EXIT(iosb.status);
	else
	{	buffer[iosb.count] = '\0';
#ifdef debug
		fprintf(fp, "%s\n", buffer);
#endif
		if (find(buffer,"NO CARRIER") == 0 || find(buffer,"BUSY") == 0)
			SYS$EXIT(1);
		else if(find(buffer, "CONNECT") == 0) 
		{	sleep(2);
			SYS$QIOW(0, chan, IO$_WRITEVBLK, &iosb, 0, 0,
				"\7Please login now\r\n", 19, 0, 0, 0, 0);
			sleep(1);
			SYS$DASSGN(chan);
#ifdef debug
			fprintf(fp, "%s\n", "Creating process");
#endif
			SYS$EXIT(1);
		}
	}
    }
    SYS$EXIT(1);
}

int find(char *str1, char *str2)
{	while(*str1 != 0)
	{	if(strncmp(str1, str2, strlen(str2)) == 0) return 0;
		else str1++;
	}
}
/******************************* End DIALBACK.C *******************************/
--------------------------------------------------------------------------------
Carl J Lydick | INTERnet: CARL@SOL1.GPS.CALTECH.EDU | NSI/HEPnet: SOL1::CARL

Disclaimer:  Hey, I understand VAXen and VMS.  That's what I get paid for.  My
understanding of astronomy is purely at the amateur level (or below).  So
unless what I'm saying is directly related to VAX/VMS, don't hold me or my
organization responsible for it.  If it IS related to VAX/VMS, you can try to
hold me responsible for it, but my organization had nothing to do with it.

