77fb3e11a9
The first problem I found was that descriptor 0 was being closed. This happens because the modem variable is set to 0 to indicate that it is not valid but there are not enough tests for the modem variable being 0. You can see where I have done this in the patch. Code in OpenModem() dups the modem descriptor if it is < 3. Once this happened the modem was always open and an incomming call would have getty and ppp reading the modem. Descriptor 1 is closed when the quit command was executed from a telnet connection. The next modem open returns descriptor 1 and this gets duped leaving the modem always open again. The modem was not being closed when the connection dropped or was closed from the other end. The UUCP lock was also not removed if the modem could not be opened. Reviewed by: Atsushi Murai <amurai@spec.co.jp> Submitted by: John Capo <jc@irbs.com>
774 lines
16 KiB
C
774 lines
16 KiB
C
/*
|
|
* PPP Modem handling module
|
|
*
|
|
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
|
|
*
|
|
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
|
|
*
|
|
* Redistribution and use in source and binary forms are permitted
|
|
* provided that the above copyright notice and this paragraph are
|
|
* duplicated in all such forms and that any documentation,
|
|
* advertising materials, and other materials related to such
|
|
* distribution and use acknowledge that the software was developed
|
|
* by the Internet Initiative Japan, Inc. The name of the
|
|
* IIJ may not be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* $Id: modem.c,v 1.4 1995/03/11 15:18:48 amurai Exp $
|
|
*
|
|
* TODO:
|
|
*/
|
|
#include "fsm.h"
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/tty.h>
|
|
#include <errno.h>
|
|
#include "hdlc.h"
|
|
#include "lcp.h"
|
|
#include "modem.h"
|
|
#include "vars.h"
|
|
|
|
#ifndef O_NONBLOCK
|
|
#ifdef O_NDELAY
|
|
#define O_NONBLOCK O_NDELAY
|
|
#endif
|
|
#endif
|
|
|
|
extern int DoChat();
|
|
|
|
static int mbits; /* Current DCD status */
|
|
static int connect_time; /* connection time */
|
|
static int connect_count;
|
|
static struct pppTimer ModemTimer;
|
|
static char uucplock[10];
|
|
|
|
extern int uu_lock(), uu_unlock();
|
|
extern void PacketMode();
|
|
|
|
#define Online (mbits & TIOCM_CD)
|
|
|
|
static struct mbuf *modemout;
|
|
static struct mqueue OutputQueues[PRI_URGENT+1];
|
|
static int dev_is_modem;
|
|
|
|
void
|
|
Enqueue(queue, bp)
|
|
struct mqueue *queue;
|
|
struct mbuf *bp;
|
|
{
|
|
if (queue->last) {
|
|
queue->last->pnext = bp;
|
|
queue->last = bp;
|
|
} else
|
|
queue->last = queue->top = bp;
|
|
queue->qlen++;
|
|
#ifdef QDEBUG
|
|
logprintf("Enqueue: len = %d\n", queue->qlen);
|
|
#endif
|
|
}
|
|
|
|
struct mbuf *
|
|
Dequeue(queue)
|
|
struct mqueue *queue;
|
|
{
|
|
struct mbuf *bp;
|
|
|
|
#ifdef QDEBUG
|
|
logprintf("Dequeue: len = %d\n", queue->qlen);
|
|
#endif
|
|
if (bp = queue->top) {
|
|
queue->top = queue->top->pnext;
|
|
queue->qlen--;
|
|
if (queue->top == NULL) {
|
|
queue->last = queue->top;
|
|
#ifdef QDEBUG
|
|
if (queue->qlen)
|
|
logprintf("!!! not zero (%d)!!!\n", queue->qlen);
|
|
#endif
|
|
}
|
|
}
|
|
return(bp);
|
|
}
|
|
|
|
static struct speeds{
|
|
int nspeed;
|
|
speed_t speed;
|
|
} speeds[] = {
|
|
#ifdef B50
|
|
{ 50, B50, },
|
|
#endif
|
|
#ifdef B75
|
|
{ 75, B75, },
|
|
#endif
|
|
#ifdef B110
|
|
{ 110, B110, },
|
|
#endif
|
|
#ifdef B134
|
|
{ 134, B134, },
|
|
#endif
|
|
#ifdef B150
|
|
{ 150, B150, },
|
|
#endif
|
|
#ifdef B200
|
|
{ 200, B200, },
|
|
#endif
|
|
#ifdef B300
|
|
{ 300, B300, },
|
|
#endif
|
|
#ifdef B600
|
|
{ 600, B600, },
|
|
#endif
|
|
#ifdef B1200
|
|
{ 1200, B1200, },
|
|
#endif
|
|
#ifdef B1800
|
|
{ 1800, B1800, },
|
|
#endif
|
|
#ifdef B2400
|
|
{ 2400, B2400, },
|
|
#endif
|
|
#ifdef B4800
|
|
{ 4800, B4800, },
|
|
#endif
|
|
#ifdef B9600
|
|
{ 9600, B9600, },
|
|
#endif
|
|
#ifdef B19200
|
|
{ 19200, B19200, },
|
|
#endif
|
|
#ifdef B38400
|
|
{ 38400, B38400, },
|
|
#endif
|
|
#ifndef _POSIX_SOURCE
|
|
#ifdef B7200
|
|
{ 7200, B7200, },
|
|
#endif
|
|
#ifdef B14400
|
|
{ 14400, B14400, },
|
|
#endif
|
|
#ifdef B28800
|
|
{ 28800, B28800, },
|
|
#endif
|
|
#ifdef B57600
|
|
{ 57600, B57600, },
|
|
#endif
|
|
#ifdef B76800
|
|
{ 76800, B76800, },
|
|
#endif
|
|
#ifdef B115200
|
|
{ 115200, B115200, },
|
|
#endif
|
|
#ifdef B230400
|
|
{ 230400, B230400, },
|
|
#endif
|
|
#ifdef EXTA
|
|
{ 19200, EXTA, },
|
|
#endif
|
|
#ifdef EXTB
|
|
{ 38400, EXTB, },
|
|
#endif
|
|
#endif /*_POSIX_SOURCE */
|
|
{ 0, 0 }
|
|
};
|
|
|
|
int SpeedToInt(speed)
|
|
speed_t speed;
|
|
{
|
|
struct speeds *sp;
|
|
|
|
for (sp = speeds; sp->nspeed; sp++) {
|
|
if (sp->speed == speed) {
|
|
return(sp->nspeed);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
speed_t IntToSpeed(nspeed)
|
|
int nspeed;
|
|
{
|
|
struct speeds *sp;
|
|
|
|
for (sp = speeds; sp->nspeed; sp++) {
|
|
if (sp->nspeed == nspeed) {
|
|
return(sp->speed);
|
|
}
|
|
}
|
|
return B0;
|
|
}
|
|
|
|
static time_t uptime;
|
|
|
|
void
|
|
DownConnection()
|
|
{
|
|
LogPrintf(LOG_PHASE, "Disconnected!\n");
|
|
LogPrintf(LOG_PHASE, "Connect time: %d secs\n", time(NULL) - uptime);
|
|
CloseModem();
|
|
LcpDown();
|
|
connect_time = 0;
|
|
}
|
|
|
|
/*
|
|
* ModemTimeout() watches DCD signal and notifies if it's status is changed.
|
|
*
|
|
*/
|
|
void
|
|
ModemTimeout()
|
|
{
|
|
int ombits = mbits;
|
|
int change;
|
|
|
|
StopTimer(&ModemTimer);
|
|
if (Online)
|
|
connect_time++;
|
|
StartTimer(&ModemTimer);
|
|
|
|
if (dev_is_modem) {
|
|
ioctl(modem, TIOCMGET, &mbits);
|
|
change = ombits ^ mbits;
|
|
if (change & TIOCM_CD) {
|
|
if (Online) {
|
|
time(&uptime);
|
|
LogPrintf(LOG_PHASE, "*Connected!\n");
|
|
connect_count++;
|
|
/*
|
|
* In dedicated mode, start packet mode immediate
|
|
* after we detected carrier.
|
|
*/
|
|
if (mode & MODE_DEDICATED)
|
|
PacketMode();
|
|
} else {
|
|
DownConnection();
|
|
}
|
|
}
|
|
} else {
|
|
if (!Online) {
|
|
time(&uptime);
|
|
LogPrintf(LOG_PHASE, "Connected!\n");
|
|
mbits = TIOCM_CD;
|
|
connect_count++;
|
|
connect_time = 0;
|
|
} else if (uptime == 0) {
|
|
time(&uptime);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
StartModemTimer()
|
|
{
|
|
connect_time = 0;
|
|
StopTimer(&ModemTimer);
|
|
ModemTimer.state = TIMER_STOPPED;
|
|
ModemTimer.load = SECTICKS;
|
|
ModemTimer.func = ModemTimeout;
|
|
StartTimer(&ModemTimer);
|
|
}
|
|
|
|
struct parity {
|
|
char *name;
|
|
char *name1;
|
|
int set;
|
|
} validparity[] = {
|
|
{ "even", "P_EVEN", CS7 | PARENB }, { "odd", "P_ODD", CS7 | PARENB | PARODD },
|
|
{ "none", "P_ZERO", CS8 }, { NULL, 0 },
|
|
};
|
|
|
|
int
|
|
GetParityValue(str)
|
|
char *str;
|
|
{
|
|
struct parity *pp;
|
|
|
|
for (pp = validparity; pp->name; pp++) {
|
|
if (strcasecmp(pp->name, str) == 0 ||
|
|
strcasecmp(pp->name1, str) == 0) {
|
|
VarParity = pp->set;
|
|
return(pp->set);
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
int
|
|
ChangeParity(str)
|
|
char *str;
|
|
{
|
|
struct termios rstio;
|
|
int val;
|
|
|
|
val = GetParityValue(str);
|
|
if (val > 0) {
|
|
VarParity = val;
|
|
tcgetattr(modem, &rstio);
|
|
rstio.c_cflag &= ~(CSIZE|PARODD|PARENB);
|
|
rstio.c_cflag |= val;
|
|
tcsetattr(modem, TCSADRAIN, &rstio);
|
|
}
|
|
return(val);
|
|
}
|
|
|
|
#include <sys/socket.h>
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
|
|
int
|
|
OpenConnection(host, port)
|
|
char *host, *port;
|
|
{
|
|
struct sockaddr_in dest;
|
|
int sock;
|
|
struct hostent *hp;
|
|
struct servent *sp;
|
|
|
|
dest.sin_family = AF_INET;
|
|
dest.sin_addr.s_addr = inet_addr(host);
|
|
if (dest.sin_addr.s_addr == INADDR_NONE) {
|
|
hp = gethostbyname(host);
|
|
if (hp) {
|
|
bcopy(hp->h_addr_list[0], &dest.sin_addr.s_addr, 4);
|
|
} else {
|
|
printf("unknown host: %s\n", host);
|
|
return(-1);
|
|
}
|
|
}
|
|
dest.sin_port = htons(atoi(port));
|
|
if (dest.sin_port == 0) {
|
|
sp = getservbyname(port, "tcp");
|
|
if (sp) {
|
|
dest.sin_port = sp->s_port;
|
|
} else {
|
|
printf("unknown service: %s\n", port);
|
|
return(-1);
|
|
}
|
|
}
|
|
LogPrintf(LOG_PHASE, "Connected to %s:%s\n", host, port);
|
|
|
|
sock = socket(PF_INET, SOCK_STREAM, 0);
|
|
if (sock < 0) {
|
|
return(sock);
|
|
}
|
|
if (connect(sock, (struct sockaddr *)&dest, sizeof(dest)) < 0) {
|
|
printf("connection failed.\n");
|
|
return(-1);
|
|
}
|
|
return(sock);
|
|
}
|
|
|
|
int
|
|
OpenModem(mode)
|
|
int mode;
|
|
{
|
|
struct termios rstio;
|
|
int oldflag;
|
|
char *host, *cp, *port;
|
|
|
|
mbits = 0;
|
|
if (mode & MODE_DIRECT) {
|
|
if (isatty(0))
|
|
modem = open(ctermid(NULL), O_RDWR|O_NONBLOCK);
|
|
} else if (modem == 0) {
|
|
if (strncmp(VarDevice, "/dev", 4) == 0) {
|
|
strcpy(uucplock, rindex(VarDevice, '/')+1);
|
|
if (uu_lock(uucplock) < 0) {
|
|
LogPrintf(LOG_PHASE, "Modem %s is in use\n", VarDevice);
|
|
return(-1);
|
|
}
|
|
modem = open(VarDevice, O_RDWR|O_NONBLOCK);
|
|
if (modem < 0) {
|
|
LogPrintf(LOG_PHASE, "Open Failed %s\n", VarDevice);
|
|
(void) uu_unlock(uucplock);
|
|
return(modem);
|
|
}
|
|
} else {
|
|
/* XXX: PPP over TCP */
|
|
cp = index(VarDevice, ':');
|
|
if (cp) {
|
|
*cp = 0;
|
|
host = VarDevice;
|
|
port = cp + 1;
|
|
if (*host && *port) {
|
|
modem = OpenConnection(host, port);
|
|
*cp = ':'; /* Don't destroy VarDevice */
|
|
if (modem < 0) return(-1);
|
|
} else {
|
|
*cp = ':'; /* Don't destroy VarDevice */
|
|
return(-1);
|
|
}
|
|
} else
|
|
return(-1);
|
|
}
|
|
}
|
|
|
|
/* This code gets around the problem of closing descriptor 0
|
|
* when it should not have been closed and closing descriptor 1
|
|
* when the telnet connection dies. Since this program always
|
|
* opens a descriptor for the modem in auto and direct mode,
|
|
* having to dup the descriptor here is a fatal error.
|
|
*
|
|
* With the other changes I have made this should no longer happen.
|
|
* JC
|
|
*/
|
|
while (modem < 3)
|
|
{
|
|
logprintf("Duping modem fd %d\n", modem);
|
|
modem = dup(modem);
|
|
}
|
|
|
|
/*
|
|
* If we are working on tty device, change it's mode into
|
|
* the one desired for further operation. In this implementation,
|
|
* we assume that modem is configuted to use CTS/RTS flow control.
|
|
*/
|
|
dev_is_modem = isatty(modem) || DEV_IS_SYNC;
|
|
if (DEV_IS_SYNC)
|
|
sleep(1);
|
|
if (dev_is_modem && !DEV_IS_SYNC) {
|
|
tcgetattr(modem, &rstio);
|
|
#ifdef DEBUG
|
|
logprintf("## modem = %d\n", modem);
|
|
logprintf("modem (get): iflag = %x, oflag = %x, cflag = %x\n",
|
|
rstio.c_iflag, rstio.c_oflag, rstio.c_cflag);
|
|
#endif
|
|
#define USE_CTSRTS
|
|
#ifdef USE_CTSRTS
|
|
rstio.c_cflag = (CS8 | CREAD | CLOCAL | CCTS_OFLOW|CRTS_IFLOW);
|
|
#else
|
|
rstio.c_cflag = (CS8 | CREAD | CLOCAL);
|
|
#endif
|
|
if ((mode & MODE_DIRECT) == 0) {
|
|
/*
|
|
* If we are working as direct mode, don't change tty speed.
|
|
*/
|
|
rstio.c_cflag &= ~(CSIZE|PARENB|PARODD);
|
|
rstio.c_cflag |= VarParity;
|
|
cfsetspeed(&rstio, IntToSpeed(VarSpeed));
|
|
}
|
|
rstio.c_iflag |= (IGNBRK | ISTRIP | IGNPAR | IXON | IXOFF);
|
|
rstio.c_iflag &= ~(BRKINT|ICRNL|IXANY|IMAXBEL);
|
|
rstio.c_lflag = 0;
|
|
|
|
rstio.c_oflag &= ~OPOST;
|
|
#ifdef notdef
|
|
rstio.c_cc[VMIN] = 10;
|
|
rstio.c_cc[VTIME] = 1;
|
|
#else
|
|
rstio.c_cc[VMIN] = 1;
|
|
rstio.c_cc[VTIME] = 0;
|
|
#endif
|
|
tcsetattr(modem, TCSADRAIN, &rstio);
|
|
#ifdef DEBUG
|
|
logprintf("modem (put): iflag = %x, oflag = %x, cflag = %x\n",
|
|
rstio.c_iflag, rstio.c_oflag, rstio.c_cflag);
|
|
#endif
|
|
|
|
if (!(mode & MODE_DIRECT))
|
|
ioctl(modem, TIOCMGET, &mbits);
|
|
#ifdef DEBUG
|
|
fprintf(stderr, "modem control = %o\n", mbits);
|
|
#endif
|
|
|
|
oldflag = fcntl(modem, F_GETFL, 0);
|
|
fcntl(modem, F_SETFL, oldflag & ~O_NONBLOCK);
|
|
}
|
|
StartModemTimer();
|
|
|
|
return(modem);
|
|
}
|
|
|
|
int
|
|
ModemSpeed()
|
|
{
|
|
struct termios rstio;
|
|
|
|
tcgetattr(modem, &rstio);
|
|
return(SpeedToInt(cfgetispeed(&rstio)));
|
|
}
|
|
|
|
static struct termios modemios;
|
|
|
|
/*
|
|
* Put modem tty line into raw mode which is necessary in packet mode operation
|
|
*/
|
|
int
|
|
RawModem(modem)
|
|
int modem;
|
|
{
|
|
struct termios rstio;
|
|
int oldflag;
|
|
|
|
if (!isatty(modem) || DEV_IS_SYNC)
|
|
return(0);
|
|
if (!(mode & MODE_DIRECT) && modem && !Online) {
|
|
#ifdef DEBUG
|
|
logprintf("mode = %d, modem = %d, mbits = %x\n", mode, modem, mbits);
|
|
#endif
|
|
#ifdef notdef
|
|
return(-1);
|
|
#endif
|
|
}
|
|
tcgetattr(modem, &rstio);
|
|
modemios = rstio;
|
|
rstio.c_cflag &= ~(CSIZE|PARENB|PARODD);
|
|
rstio.c_cflag |= CS8;
|
|
rstio.c_iflag &= ~(ISTRIP|IXON|IXOFF|BRKINT|ICRNL|INLCR);
|
|
tcsetattr(modem, TCSADRAIN, &rstio);
|
|
oldflag = fcntl(modem, F_GETFL, 0);
|
|
fcntl(modem, F_SETFL, oldflag | O_NONBLOCK);
|
|
#ifdef DEBUG
|
|
oldflag = fcntl(modem, F_GETFL, 0);
|
|
logprintf("modem (put2): iflag = %x, oflag = %x, cflag = %x\n",
|
|
rstio.c_iflag, rstio.c_oflag, rstio.c_cflag);
|
|
logprintf("flag = %x\n", oldflag);
|
|
#endif
|
|
return(0);
|
|
}
|
|
|
|
void
|
|
UnrawModem(modem)
|
|
int modem;
|
|
{
|
|
int oldflag;
|
|
|
|
if (isatty(modem)) {
|
|
tcsetattr(modem, TCSADRAIN, &modemios);
|
|
oldflag = fcntl(modem, F_GETFL, 0);
|
|
fcntl(modem, F_SETFL, oldflag & ~O_NONBLOCK);
|
|
}
|
|
}
|
|
|
|
void
|
|
HangupModem(flag)
|
|
int flag;
|
|
{
|
|
struct termios tio;
|
|
|
|
if (!isatty(modem)) {
|
|
mbits &= ~TIOCM_DTR;
|
|
close(modem);
|
|
modem = 0; /* Mark as modem has closed */
|
|
return;
|
|
}
|
|
|
|
if (modem && Online) {
|
|
mbits &= ~TIOCM_DTR;
|
|
#ifdef __bsdi__ /* not a POSIX way */
|
|
ioctl(modem, TIOCMSET, &mbits);
|
|
#else
|
|
tcgetattr(modem, &tio);
|
|
cfsetspeed(&tio, B0);
|
|
tcsetattr(modem, TCSANOW, &tio);
|
|
#endif
|
|
sleep(1);
|
|
#ifdef notdef
|
|
mbits &= ~TIOCM_CD;
|
|
#endif
|
|
}
|
|
/*
|
|
* If we are working as dedicated mode, never close it
|
|
* until we are directed to quit program.
|
|
*/
|
|
if (modem && (flag || !(mode & MODE_DEDICATED))) {
|
|
ModemTimeout(); /* XXX */
|
|
StopTimer(&ModemTimer); /* XXX */
|
|
|
|
/* ModemTimeout() may call DownConection() to close the modem
|
|
* resulting in modem == 0.
|
|
*/
|
|
if (modem)
|
|
{
|
|
tcflush(modem, TIOCFLUSH);
|
|
UnrawModem(modem);
|
|
close(modem);
|
|
}
|
|
(void) uu_unlock(uucplock);
|
|
modem = 0; /* Mark as modem has closed */
|
|
} else if (modem) {
|
|
mbits |= TIOCM_DTR;
|
|
#ifndef notyet
|
|
ioctl(modem, TIOCMSET, &mbits);
|
|
#else
|
|
tcgetattr(modem, &ts);
|
|
cfsetspeed(&ts, IntToSpeed(VarSpeed));
|
|
tcsetattr(modem, TCSADRAIN, &ts);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
CloseModem()
|
|
{
|
|
if (modem >= 3)
|
|
{
|
|
close(modem);
|
|
modem = 0;
|
|
}
|
|
(void) uu_unlock(uucplock);
|
|
}
|
|
|
|
/*
|
|
* Write to modem. Actualy, requested packets are queued, and goes out
|
|
* to the line when ModemStartOutput() is called.
|
|
*/
|
|
void
|
|
WriteModem(pri, ptr, count)
|
|
int pri;
|
|
char *ptr;
|
|
int count;
|
|
{
|
|
struct mbuf *bp;
|
|
|
|
bp = mballoc(count, MB_MODEM);
|
|
bcopy(ptr, MBUF_CTOP(bp), count);
|
|
Enqueue(&OutputQueues[pri], bp);
|
|
}
|
|
|
|
void
|
|
ModemOutput(pri, bp)
|
|
int pri;
|
|
struct mbuf *bp;
|
|
{
|
|
struct mbuf *wp;
|
|
int len;
|
|
|
|
len = plength(bp);
|
|
wp = mballoc(len, MB_MODEM);
|
|
mbread(bp, MBUF_CTOP(wp), len);
|
|
Enqueue(&OutputQueues[pri], wp);
|
|
ModemStartOutput(modem);
|
|
}
|
|
|
|
int
|
|
ModemQlen()
|
|
{
|
|
struct mbuf *bp;
|
|
int len = 0;
|
|
int i;
|
|
|
|
for (i = PRI_NORMAL; i <= PRI_URGENT; i++) {
|
|
for (bp = OutputQueues[i].top; bp; bp = bp->pnext)
|
|
len++;
|
|
}
|
|
|
|
return(len);
|
|
}
|
|
|
|
void
|
|
ModemStartOutput(fd)
|
|
int fd;
|
|
{
|
|
struct mqueue *queue;
|
|
int nb, nw, i;
|
|
|
|
if (modemout == NULL) {
|
|
i = 0;
|
|
for (queue = &OutputQueues[PRI_URGENT]; queue >= OutputQueues; queue--) {
|
|
if (queue->top) {
|
|
modemout = Dequeue(queue);
|
|
#ifdef QDEBUG
|
|
if (i < 2) {
|
|
struct mqueue *q;
|
|
|
|
q = &OutputQueues[0];
|
|
logprintf("output from queue %d, normal has %d\n", i, q->qlen);
|
|
}
|
|
logprintf("Dequeue(%d): ", i);
|
|
#endif
|
|
break;
|
|
}
|
|
i++;
|
|
}
|
|
}
|
|
if (modemout) {
|
|
nb = modemout->cnt;
|
|
if (nb > 1600) nb = 1600;
|
|
if (fd == 0) fd = 1;
|
|
nw = write(fd, MBUF_CTOP(modemout), nb);
|
|
#ifdef QDEBUG
|
|
logprintf("wrote: %d(%d)\n", nw, nb);
|
|
LogDumpBuff(LOG_HDLC, "modem write", MBUF_CTOP(modemout), nb);
|
|
#endif
|
|
if (nw > 0) {
|
|
modemout->cnt -= nw;
|
|
modemout->offset += nw;
|
|
if (modemout->cnt == 0) {
|
|
modemout = mbfree(modemout);
|
|
#ifdef QDEBUG
|
|
logprintf(" mbfree\n");
|
|
#endif
|
|
}
|
|
} else if (nw < 0) {
|
|
if (errno != EAGAIN)
|
|
perror("modem write");
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
DialModem()
|
|
{
|
|
char ScriptBuffer[200];
|
|
|
|
strcpy(ScriptBuffer, VarDialScript);
|
|
if (DoChat(ScriptBuffer) > 0) {
|
|
fprintf(stderr, "dial OK!\n");
|
|
strcpy(ScriptBuffer, VarLoginScript);
|
|
if (DoChat(ScriptBuffer) > 0) {
|
|
fprintf(stderr, "login OK!\n");
|
|
return(1);
|
|
} else {
|
|
fprintf(stderr, "login failed.\n");
|
|
}
|
|
ModemTimeout(); /* Dummy call to check modem status */
|
|
}
|
|
else
|
|
fprintf(stderr, "dial failed.\n");
|
|
return(0);
|
|
}
|
|
|
|
int
|
|
ShowModemStatus()
|
|
{
|
|
#ifdef TIOCOUTQ
|
|
int nb;
|
|
#endif
|
|
|
|
printf("device: %s speed: ", VarDevice);
|
|
if (DEV_IS_SYNC)
|
|
printf("sync\n");
|
|
else
|
|
printf("%d\n", VarSpeed);
|
|
|
|
switch (VarParity & CSIZE) {
|
|
case CS7:
|
|
printf("cs7, ");
|
|
break;
|
|
case CS8:
|
|
printf("cs8, ");
|
|
break;
|
|
}
|
|
if (VarParity & PARENB) {
|
|
if (VarParity & PARODD)
|
|
printf("odd parity\n");
|
|
else
|
|
printf("even parity\n");
|
|
} else
|
|
printf("none parity\n");
|
|
#ifdef DEBUG
|
|
printf("fd = %d, modem control = %o\n", modem, mbits);
|
|
#endif
|
|
printf("connect count: %d\n", connect_count);
|
|
#ifdef TIOCOUTQ
|
|
ioctl(modem, TIOCOUTQ, &nb);
|
|
printf("outq: %d\n", nb);
|
|
#endif
|
|
printf("DialScript = %s\n", VarDialScript);
|
|
printf("LoginScript = %s\n", VarLoginScript);
|
|
printf("PhoneNumber = %s\n", VarPhone);
|
|
return(1);
|
|
}
|