home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume16
/
pcomm2
/
part04
/
dial.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-09-14
|
7KB
|
357 lines
/*
* The routines that dial the modem and listen for the return codes.
*/
#include <stdio.h>
#include <termio.h>
#include "config.h"
#ifdef UNIXPC
#include <sys/phone.h>
#endif /* UNIXPC */
#include "dial_dir.h"
#include "misc.h"
#include "modem.h"
#include "param.h"
/*
* Get the dial string ready, send it to the modem. The parameter is not
* the actual entry number, it is an index into the queue.
*/
void
dial_it(num)
int num;
{
extern int fd;
int i, skip;
char s[100], number[40], *strcpy(), *strcat(), *n, *strchr();
void send_str();
#ifdef UNIXPC
struct updata pbuf;
unsigned int sleep();
#endif /* UNIXPC */
/*
* Create the string to be sent to the modem. The long distance
* codes are added if they are requested.
*/
s[0] = NULL;
strcpy(s, modem->dial[modem->m_cur]);
switch (dir->q_ld[num]) {
case 0: /* no ld code requested */
break;
case '+':
strcat(s, param->ld_plus);
break;
case '-':
strcat(s, param->ld_minus);
break;
case '@':
strcat(s, param->ld_at);
break;
case '#':
strcat(s, param->ld_pound);
break;
}
/*
* Purify the phone number by removing all the pretty characters
* that don't need to be sent to the modem. Typically the "-",
* "(", ")", and space characters are just for looks. To prevent
* this action, prepend a "\" to the character.
*/
i = 0;
skip = 0;
n = dir->number[dir->q_num[num]];
while (*n) {
if (*n == '\\' && !skip) {
skip++;
n++;
continue;
}
if (!strchr("-() ", *n) || skip)
number[i++] = *n;
n++;
skip = 0;
}
number[i] = NULL;
/* add it to the string */
strcat(s, number);
strcat(s, modem->suffix[modem->m_cur]);
#ifdef DEBUG
fprintf(stderr, "raw dial string: '%s'\n", s);
#endif /* DEBUG */
#ifdef UNIXPC
/* special case for OBM */
if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
/* prepare the modem */
pbuf.c_lineparam = DATA|DTMF;
pbuf.c_waitdialtone = 5;
pbuf.c_linestatus = 0;
pbuf.c_feedback = SPEAKERON|NORMSPK;
pbuf.c_waitflash = 500;
ioctl(fd, PIOCSETP, &pbuf);
sleep(1);
/* connect the dialer */
ioctl(fd, PIOCRECONN);
sleep(1);
/* dial each digit */
n = s;
while (*n) {
/* switch tone/pulse dialing? */
switch (*n) {
case '^':
pbuf.c_lineparam = DATA|PULSE;
ioctl(fd, PIOCSETP, &pbuf);
break;
case '%':
pbuf.c_lineparam = DATA|DTMF;
ioctl(fd, PIOCSETP, &pbuf);
break;
default:
ioctl(fd, PIOCDIAL, n);
break;
}
n++;
}
return;
}
#endif /* UNIXPC */
send_str(s);
return;
}
/*
* Send a string to the modem. Performs all the character synonym
* translations. No sanity checking on the "m_cur" value.
*/
void
send_str(s)
char *s;
{
extern int fd;
int skip;
unsigned int sleep();
/* empty string? */
if (s == NULL || *s == NULL)
return;
ioctl(fd, TCFLSH, 1);
/*
* Change the character synonyms to their real values. Writes
* the characters to the modem. To remove the special meaning
* of one of the characters, prepend a "\" to it.
*/
skip = 0;
while (*s) {
/* send the literal character */
if (skip) {
skip = 0;
write(fd, s, 1);
ioctl(fd, TCSBRK, 1);
#ifdef DEBUG
fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s);
#endif /* DEBUG */
s++;
continue;
}
/* turn off the special meaning */
if (*s == '\\') {
skip++;
s++;
continue;
}
/* pause synonym */
if (*s == param->pause_char) {
sleep(1);
s++;
continue;
}
/* carriage return synonym */
if (*s == param->cr_char)
*s = '\r';
/* 2 character control sequence */
if (*s == param->ctrl_char) {
s++;
/* premature EOF? */
if (*s == NULL)
break;
/* upper and lower case */
if (*s > '_')
*s -= 96;
else
*s -= 64;
}
/* escape synonym */
if (*s == param->esc_char)
*s = ESC;
/* modem break synonym */
if (*s == param->brk_char) {
ioctl(fd, TCSBRK, 0);
sleep(1);
s++;
continue;
}
write(fd, s, 1);
#ifdef DEBUG
fprintf(stderr, "send_str: '%c', %02x, %03o, %d\n", *s, *s, *s, *s);
#endif /* DEBUG */
/*
* Because the pause char makes the timing critical, we
* wait until the buffer is clear before we continue.
*/
ioctl(fd, TCSBRK, 1);
s++;
}
return;
}
/*
* Read the result codes coming back from the modem. Test for the 6
* "connect" strings and the 4 "no connect" strings. Return the connected
* baud rate (as a string) or the error message.
*/
char rc_buf[512];
int rc_index;
char *
read_codes()
{
extern int fd;
char c;
#ifdef UNIXPC
unsigned int sleep();
struct updata pbuf;
/* special case for OBM */
if (!strcmp(modem->mname[modem->m_cur], "OBM")) {
ioctl(fd, PIOCGETP, &pbuf);
/*
* The OBM doesn't use a return message to announce the
* connection to a remote, so we fake one. The 1200
* is quite arbitrary... it is not an indicator of the
* connected baud rate.
*/
if (pbuf.c_linestatus & MODEMCONNECTED)
return("1200");
sleep(1);
return(NULL);
}
#endif /* UNIXPC */
/* search for key words */
for (; rc_index<511; rc_index++) {
if ((int) (c = getc_line(1)) <= 0)
return(NULL);
#ifdef DEBUG
fprintf(stderr, "read_codes: '%c', %02x, %03o, %d\n", c, c, c, c);
#endif /* DEBUG */
rc_buf[rc_index] = c;
rc_buf[rc_index+1] = NULL;
/* the connect strings */
if (match(rc_buf, modem->con_3[modem->m_cur]))
return("300");
if (match(rc_buf, modem->con_12[modem->m_cur]))
return("1200");
if (match(rc_buf, modem->con_24[modem->m_cur]))
return("2400");
if (match(rc_buf, modem->con_48[modem->m_cur]))
return("4800");
if (match(rc_buf, modem->con_96[modem->m_cur]))
return("9600");
if (match(rc_buf, modem->con_192[modem->m_cur]))
return("19200");
/* the no connect strings */
if (match(rc_buf, modem->no_con1[modem->m_cur]))
return(modem->no_con1[modem->m_cur]);
if (match(rc_buf, modem->no_con2[modem->m_cur]))
return(modem->no_con2[modem->m_cur]);
if (match(rc_buf, modem->no_con3[modem->m_cur]))
return(modem->no_con3[modem->m_cur]);
if (match(rc_buf, modem->no_con4[modem->m_cur]))
return(modem->no_con4[modem->m_cur]);
}
/* ran out of buffer? */
return("ERROR");
}
/*
* Test for a match between two character strings. A return code of 1
* means that s2 was found at the end of s1.
*/
static int
match(s1, s2)
char *s1, *s2;
{
register int i;
int skip, diff;
char new[40];
/* if no string to match */
if (*s2 == NULL)
return(0);
/* translate synonyms */
i = 0;
skip = 0;
while (*s2) {
/* literal character */
if (skip) {
skip = 0;
new[i++] = *s2;
s2++;
continue;
}
/* turn off the special meaning */
if (*s2 == '\\') {
skip++;
s2++;
continue;
}
/* carriage return synonym */
if (*s2 == param->cr_char)
*s2 = '\r';
/* 2 character control sequence */
if (*s2 == param->ctrl_char) {
s2++;
if (*s2 == NULL)
break;
if (*s2 > '_')
*s2 -= 96;
else
*s2 -= 64;
}
/* escape synonym */
if (*s2 == param->esc_char)
*s2 = ESC;
new[i++] = *s2;
s2++;
}
new[i] = NULL;
diff = strlen(s1) - strlen(new);
/* is it possible? */
if (diff < 0)
return(0);
/* test it out */
if (!strcmp(&s1[diff], new))
return(1);
return(0);
}