Update to version 2.0-beta

Allow for NULL fd_sets in descriptor_UpdateSet()
Reimplement the entire chat module, creating
`struct chat' - a `type' of struct descriptor.
Remove CARRIER logging.
CONNECT logging now only logs "CONNECT" lines.  CHAT logging
masks it with an entire log of the conversation.

Modem dialing is now asynchronous, including pauses
and timeouts :-)

The hooks in DoLoop() in main.c are *very* messy !  I'll have
to rewrite DoLoop fairly soon, so I don't care too much for the
moment.  This code is pretty raw.
This commit is contained in:
Brian Somers 1998-02-13 05:10:26 +00:00
parent 6b5fb63d1e
commit b6dec9f07f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=33305
14 changed files with 682 additions and 557 deletions

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: auth.c,v 1.27.2.6 1998/02/07 20:49:18 brian Exp $
* $Id: auth.c,v 1.27.2.7 1998/02/09 19:20:32 brian Exp $
*
* TODO:
* o Implement check against with registered IP addresses.
@ -42,7 +42,6 @@
#include "loadalias.h"
#include "vars.h"
#include "auth.h"
#include "chat.h"
#include "systems.h"
#include "lcp.h"
#include "hdlc.h"
@ -50,6 +49,7 @@
#include "link.h"
#include "descriptor.h"
#include "physical.h"
#include "chat.h"
#include "lcpproto.h"
const char *
@ -145,7 +145,7 @@ AuthValidate(struct bundle *bundle, const char *fname, const char *system,
if (n < 2)
continue;
if (strcmp(vector[0], system) == 0) {
ExpandString(vector[1], passwd, sizeof passwd, 0);
chat_ExpandString(NULL, vector[1], passwd, sizeof passwd, 0);
if (strcmp(passwd, key) == 0) {
CloseSecret(fp);
if (n > 2 && !UseHisaddr(bundle, vector[2], 1))
@ -184,7 +184,7 @@ AuthGetSecret(struct bundle *bundle, const char *fname, const char *system,
if (n < 2)
continue;
if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
ExpandString(vector[1], passwd, sizeof passwd, 0);
chat_ExpandString(NULL, vector[1], passwd, sizeof passwd, 0);
if (setaddr)
memset(&IpcpInfo.DefHisAddress, '\0', sizeof IpcpInfo.DefHisAddress);
if (n > 2 && setaddr)

View File

@ -1,30 +1,31 @@
/*
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
/*-
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
* All rights reserved.
*
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Most of codes are derived from chat.c by Karl Fox (karl@MorningStar.Com).
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Chat -- a program for automatic session establishment (i.e. dial
* the phone and log in).
*
* This software is in the public domain.
*
* Please send all bug reports, requests for information, etc. to:
*
* Karl Fox <karl@MorningStar.Com>
* Morning Star Technologies, Inc.
* 1760 Zollinger Road
* Columbus, OH 43221
* (614)451-1883
*
* $Id: chat.c,v 1.44.2.5 1998/02/09 19:20:36 brian Exp $
*
* TODO:
* o Support more UUCP compatible control sequences.
* o Dialing shoud not block monitor process.
* o Reading modem by select should be unified into main.c
* $Id$
*/
#include <sys/param.h>
#include <netinet/in.h>
@ -60,6 +61,10 @@
#include "chat.h"
#include "prompt.h"
#define BUFLEFT(c) (sizeof (c)->buf - ((c)->bufend - (c)->buf))
struct chat chat;
#ifndef isblank
#define isblank(c) ((c) == '\t' || (c) == ' ')
#endif
@ -78,6 +83,425 @@ static jmp_buf ChatEnv;
#define NOMATCH 0
#define ABORT -1
static void ExecStr(struct physical *, char *, char *, int);
static void
chat_PauseTimer(void *v)
{
struct chat *c = (struct chat *)v;
StopTimer(&c->pause);
c->pause.state = TIMER_STOPPED;
c->pause.load = 0;
}
static void
chat_Pause(struct chat *c, u_long load)
{
StopTimer(&c->pause);
c->pause.state = TIMER_STOPPED;
c->pause.load += load;
c->pause.func = chat_PauseTimer;
c->pause.arg = c;
StartTimer(&c->pause);
}
static void
chat_TimeoutTimer(void *v)
{
struct chat *c = (struct chat *)v;
StopTimer(&c->timeout);
c->TimedOut = 1;
}
static void
chat_SetTimeout(struct chat *c)
{
StopTimer(&c->timeout);
c->timeout.state = TIMER_STOPPED;
if (c->TimeoutSec > 0) {
c->timeout.load = SECTICKS * c->TimeoutSec;
c->timeout.func = chat_TimeoutTimer;
c->timeout.arg = c;
StartTimer(&c->timeout);
}
}
static char *
chat_NextChar(char *ptr, char ch)
{
for (; *ptr; ptr++)
if (*ptr == ch)
return ptr;
else if (*ptr == '\\')
if (*++ptr == '\0')
return NULL;
return NULL;
}
static int
chat_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
{
struct chat *c = descriptor2chat(d);
int special, gotabort, gottimeout, needcr;
if (c->pause.state == TIMER_RUNNING)
return 0;
if (c->TimedOut) {
LogPrintf(LogCHAT, "Expect timeout\n");
if ( c->nargptr == NULL)
c->state = CHAT_FAILED;
else {
c->state = CHAT_EXPECT;
c->argptr = "";
}
}
if (c->state != CHAT_EXPECT && c->state != CHAT_SEND)
return 0;
gottimeout = gotabort = 0;
if (c->arg < c->argc && (c->arg < 0 || *c->argptr == '\0')) {
/* Go get the next string */
if (c->arg < 0 || c->state == CHAT_SEND)
c->state = CHAT_EXPECT;
else
c->state = CHAT_SEND;
special = 1;
while (special && (c->nargptr || c->arg < c->argc - 1)) {
if (c->arg < 0 || !c->TimedOut)
c->nargptr = NULL;
if (c->nargptr != NULL) {
/* We're doing expect-send-expect.... */
c->argptr = c->nargptr;
/* Put the '-' back in case we ever want to rerun our script */
c->nargptr[-1] = '-';
c->nargptr = chat_NextChar(c->nargptr, '-');
if (c->nargptr != NULL)
*c->nargptr++ = '\0';
} else {
int minus;
c->argptr = c->argv[++c->arg];
if (c->state == CHAT_EXPECT) {
/* Look for expect-send-expect sequence */
c->nargptr = c->argptr;
minus = 0;
while ((c->nargptr = chat_NextChar(c->nargptr, '-'))) {
c->nargptr++;
minus++;
}
if (minus % 2)
LogPrintf(LogWARN, "chat_UpdateSet: \"%s\": Uneven number of"
" '-' chars, all ignored\n", c->argptr);
else if (minus) {
c->nargptr = chat_NextChar(c->argptr, '-');
*c->nargptr++ = '\0';
}
}
}
/*
* c->argptr now temporarily points into c->script (via c->argv)
* If it's an expect-send-expect sequence, we've just got the correct
* portion of that sequence.
*/
needcr = c->state == CHAT_SEND && *c->argptr != '!';
/* We leave room for a potential HDLC header in the target string */
chat_ExpandString(c, c->argptr, c->exp + 2, sizeof c->exp - 2, needcr);
if (gotabort) {
if (c->numaborts < sizeof c->AbortStrings / sizeof c->AbortStrings[0])
c->AbortStrings[c->numaborts++] = strdup(c->exp+2);
else
LogPrintf(LogERROR, "chat_UpdateSet: AbortStrings overflow\n");
gotabort = 0;
} else if (gottimeout) {
c->TimeoutSec = atoi(c->exp + 2);
if (c->TimeoutSec <= 0)
c->TimeoutSec = 30;
gottimeout = 0;
} else if (c->nargptr == NULL && !strcmp(c->exp+2, "ABORT"))
gotabort = 1;
else if (c->nargptr == NULL && !strcmp(c->exp+2, "TIMEOUT"))
gottimeout = 1;
else {
if (c->exp[2] == '!')
ExecStr(c->physical, c->exp + 3, c->exp + 2, sizeof c->exp - 2);
if (c->exp[2] == '\0')
/* Empty string, reparse (this may be better as a `goto start') */
return chat_UpdateSet(d, r, w, e, n);
special = 0;
}
}
if (special) {
if (gottimeout)
LogPrintf(LogWARN, "chat_UpdateSet: TIMEOUT: Argument expected\n");
else if (gotabort)
LogPrintf(LogWARN, "chat_UpdateSet: ABORT: Argument expected\n");
/* End of script - all ok */
c->state = CHAT_DONE;
return 0;
}
/* set c->argptr to point in the right place */
c->argptr = c->exp + 2;
c->arglen = strlen(c->argptr);
if (c->state == CHAT_EXPECT) {
/* We must check to see if the string's already been found ! */
char *begin, *end;
end = c->bufend - c->arglen + 1;
if (end < c->bufstart)
end = c->bufstart;
for (begin = c->bufstart; begin < end; begin++)
if (!strncmp(begin, c->argptr, c->arglen)) {
c->bufstart = begin + c->arglen;
c->argptr += c->arglen;
c->arglen = 0;
/* Continue - we've already read our expect string */
return chat_UpdateSet(d, r, w, e, n);
}
c->TimedOut = 0;
LogPrintf(LogCHAT, "Expect(%d): %s\n", c->TimeoutSec, c->argptr);
chat_SetTimeout(c);
}
}
/*
* We now have c->argptr pointing at what we want to expect/send and
* c->state saying what we want to do... we now know what to put in
* the fd_set :-)
*/
if (c->state == CHAT_EXPECT)
return Physical_UpdateSet(&c->physical->desc, r, NULL, e, n, 1);
else
return Physical_UpdateSet(&c->physical->desc, NULL, w, e, n, 1);
}
static int
chat_IsSet(struct descriptor *d, fd_set *fdset)
{
struct chat *c = descriptor2chat(d);
return Physical_IsSet(&c->physical->desc, fdset);
}
static void
chat_UpdateLog(struct chat *c, int in)
{
if (LogIsKept(LogCHAT) || LogIsKept(LogCONNECT)) {
/*
* If a linefeed appears in the last `in' characters of `c's input
* buffer, output from there, all the way back to the last linefeed.
* This is called for every read of `in' bytes.
*/
char *ptr, *end, *stop;
int level;
level = LogIsKept(LogCHAT) ? LogCHAT : LogCONNECT;
ptr = c->bufend - in;
for (end = c->bufend - 1; end >= ptr; end--)
if (*end == '\n')
break;
if (end >= ptr) {
for (ptr = c->bufend - in - 1; ptr >= c->bufstart; ptr--)
if (*ptr == '\n')
break;
ptr++;
stop = NULL;
while (stop != end && (stop = strchr(ptr, '\n'))) {
*stop = '\0';
if (level == LogCHAT || strstr(ptr, "CONNECT"))
LogPrintf(level, "Received: %s\n", ptr);
*stop = '\n';
ptr = stop + 1;
}
}
}
}
static void
chat_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
{
struct chat *c = descriptor2chat(d);
if (c->state == CHAT_EXPECT) {
ssize_t in;
char *begin, *end;
/*
* XXX - should this read only 1 byte to guarantee that we don't
* swallow any ppp talk from the peer ?
*/
in = BUFLEFT(c);
if (in > sizeof c->buf / 2)
in = sizeof c->buf / 2;
in = Physical_Read(c->physical, c->bufend, in);
if (in <= 0)
return;
/* `begin' and `end' delimit where we're going to strncmp() from */
begin = c->bufend - c->arglen + 1;
end = begin + in;
if (begin < c->bufstart)
begin = c->bufstart;
c->bufend += in;
chat_UpdateLog(c, in);
if (c->bufend > c->buf + sizeof c->buf / 2) {
/* Shuffle our receive buffer back a bit */
int chop;
for (chop = begin - c->buf; chop; chop--)
if (c->buf[chop] == '\n')
/* found some already-logged garbage to remove :-) */
break;
if (!chop) {
chop = begin - c->buf;
}
if (chop) {
char *from, *to;
to = c->buf;
from = to + chop;
while (from < c->bufend)
*to++ = *from++;
c->bufstart -= chop;
c->bufend -= chop;
begin -= chop;
end -= chop;
}
}
for (; begin < end; begin++)
if (!strncmp(begin, c->argptr, c->arglen)) {
/* Got it ! */
if (begin[c->arglen - 1] != '\n') {
/* Now coerce chat_UpdateLog() into logging it.... */
char ch;
end = c->bufend;
c->bufend = begin + c->arglen;
ch = *c->bufend;
*c->bufend++ = '\n';
chat_UpdateLog(c, 1);
*--c->bufend = ch;
c->bufend = end;
}
c->bufstart = begin + c->arglen;
c->argptr += c->arglen;
c->arglen = 0;
break;
}
}
}
static void
chat_Write(struct descriptor *d, const fd_set *fdset)
{
struct chat *c = descriptor2chat(d);
if (c->state == CHAT_SEND) {
int wrote;
if (strstr(c->argv[c->arg], "\\P")) /* Don't log the password */
LogPrintf(LogCHAT, "Send: %s\n", c->argv[c->arg]);
else {
int sz;
sz = c->arglen - 1;
while (sz >= 0 && c->argptr[sz] == '\n')
sz--;
LogPrintf(LogCHAT, "Send: %.*s\n", sz + 1, c->argptr);
}
if (Physical_IsSync(c->physical)) {
/* There's always room for the HDLC header */
c->argptr -= 2;
c->arglen += 2;
memcpy(c->argptr, "\377\003", 2); /* Prepend HDLC header */
}
wrote = Physical_Write(c->physical, c->argptr, c->arglen);
if (wrote == -1) {
if (errno != EINTR)
LogPrintf(LogERROR, "chat_Write: %s\n", strerror(errno));
if (Physical_IsSync(c->physical)) {
c->argptr += 2;
c->arglen -= 2;
}
} else if (wrote < 2 && Physical_IsSync(c->physical)) {
/* Oops - didn't even write our HDLC header ! */
c->argptr += 2;
c->arglen -= 2;
} else {
c->argptr += wrote;
c->arglen -= wrote;
}
}
}
void
chat_Init(struct chat *c, struct physical *p, const char *data, int emptybuf)
{
c->desc.type = CHAT_DESCRIPTOR;
c->desc.next = NULL;
c->desc.UpdateSet = chat_UpdateSet;
c->desc.IsSet = chat_IsSet;
c->desc.Read = chat_Read;
c->desc.Write = chat_Write;
c->physical = p;
c->state = CHAT_EXPECT;
strncpy(c->script, data, sizeof c->script - 1);
c->script[sizeof c->script - 1] = '\0';
c->argc = MakeArgs(c->script, c->argv, VECSIZE(c->argv));
c->arg = -1;
c->argptr = NULL;
c->nargptr = NULL;
if (emptybuf)
c->bufstart = c->bufend = c->buf;
c->TimeoutSec = 30;
c->TimedOut = 0;
c->numaborts = 0;
StopTimer(&c->pause);
c->pause.state = TIMER_STOPPED;
StopTimer(&c->timeout);
c->timeout.state = TIMER_STOPPED;
}
void
chat_Destroy(struct chat *c)
{
while (c->numaborts)
free(c->AbortStrings[--c->numaborts]);
}
static char *
findblank(char *p, int instring)
{
@ -146,7 +570,8 @@ MakeArgs(char *script, char **pvect, int maxargs)
* \U Auth User
*/
char *
ExpandString(const char *str, char *result, int reslen, int sendmode)
chat_ExpandString(struct chat *c, const char *str, char *result, int reslen,
int sendmode)
{
int addcr = 0;
char *phone;
@ -164,10 +589,12 @@ ExpandString(const char *str, char *result, int reslen, int sendmode)
addcr = 0;
break;
case 'd': /* Delay 2 seconds */
nointr_sleep(2);
if (c != NULL)
chat_Pause(c, 2 * SECTICKS);
break;
case 'p':
nointr_usleep(250000);
if (c != NULL)
chat_Pause(c, SECTICKS / 4);
break; /* Pause 0.25 sec */
case 'n':
*result++ = '\n';
@ -241,46 +668,6 @@ ExpandString(const char *str, char *result, int reslen, int sendmode)
return (result);
}
#define MAXLOGBUFF LINE_LEN
static char logbuff[MAXLOGBUFF];
static int loglen = 0;
static void
clear_log(void)
{
memset(logbuff, 0, MAXLOGBUFF);
loglen = 0;
}
static void
flush_log(void)
{
if (LogIsKept(LogCONNECT))
LogPrintf(LogCONNECT, "%s\n", logbuff);
else if (LogIsKept(LogCARRIER) && strstr(logbuff, "CARRIER"))
LogPrintf(LogCARRIER, "%s\n", logbuff);
clear_log();
}
static void
connect_log(const char *str, int single_p)
{
int space = MAXLOGBUFF - loglen - 1;
while (space--) {
if (*str == '\n') {
flush_log();
} else {
logbuff[loglen++] = *str;
}
if (single_p || !*++str)
break;
}
if (!space)
flush_log();
}
static void
ExecStr(struct physical *physical, char *command, char *out, int olen)
{
@ -364,325 +751,3 @@ ExecStr(struct physical *physical, char *command, char *out, int olen)
}
}
}
static int
WaitforString(struct physical *physical, const char *estr)
{
struct timeval timeout;
char *s, *str, ch;
char *inp;
fd_set rfds;
int i, nfds, nb;
char buff[IBSIZE];
#ifdef SIGALRM
int omask;
omask = sigblock(sigmask(SIGALRM));
#endif
clear_log();
if (*estr == '!') {
ExpandString(estr + 1, buff, sizeof buff, 0);
ExecStr(physical, buff, buff, sizeof buff);
} else {
ExpandString(estr, buff, sizeof buff, 0);
}
if (LogIsKept(LogCHAT)) {
s = buff + strlen(buff) - 1;
while (s >= buff && *s == '\n')
s--;
if (!strcmp(estr, buff))
LogPrintf(LogCHAT, "Wait for (%d): %.*s\n",
TimeoutSec, s - buff + 1, buff);
else
LogPrintf(LogCHAT, "Wait for (%d): %s --> %.*s\n",
TimeoutSec, estr, s - buff + 1, buff);
}
if (buff[0] == '\0')
return (MATCH);
str = buff;
inp = inbuff;
if (strlen(str) >= IBSIZE) {
str[IBSIZE - 1] = 0;
LogPrintf(LogCHAT, "Truncating String to %d character: %s\n", IBSIZE, str);
}
/* XXX-ML - this look REALLY fishy. */
nfds = Physical_GetFD(physical) + 1;
s = str;
for (;;) {
FD_ZERO(&rfds);
FD_SET(Physical_GetFD(physical), &rfds);
/*
* Because it is not clear whether select() modifies timeout value, it is
* better to initialize timeout values everytime.
*/
timeout.tv_sec = TimeoutSec;
timeout.tv_usec = 0;
i = select(nfds, &rfds, NULL, NULL, &timeout);
#ifdef notdef
TimerService();
#endif
if (i < 0) {
#ifdef SIGALRM
if (errno == EINTR)
continue;
sigsetmask(omask);
#endif
LogPrintf(LogERROR, "WaitForString: select(): %s\n", strerror(errno));
*inp = 0;
return (NOMATCH);
} else if (i == 0) { /* Timeout reached! */
*inp = 0;
if (inp != inbuff)
LogPrintf(LogCHAT, "Got: %s\n", inbuff);
LogPrintf(LogCHAT, "Can't get (%d).\n", timeout.tv_sec);
#ifdef SIGALRM
sigsetmask(omask);
#endif
return (NOMATCH);
}
if (Physical_FD_ISSET(physical, &rfds)) { /* got something */
if (Physical_IsSync(physical)) {
int length;
if ((length = strlen(inbuff)) > IBSIZE) {
/* shuffle down next part */
memcpy(inbuff, &(inbuff[IBSIZE]), IBSIZE + 1);
length = strlen(inbuff);
}
if (length + IBSIZE > sizeof(inbuff))
abort(); /* Bug & security problem */
nb = Physical_Read(physical, &(inbuff[length]), IBSIZE);
inbuff[nb + length] = 0;
connect_log(inbuff, 0);
if (strstr(inbuff, str)) {
#ifdef SIGALRM
sigsetmask(omask);
#endif
flush_log();
return (MATCH);
}
for (i = 0; i < numaborts; i++) {
if (strstr(inbuff, AbortStrings[i])) {
LogPrintf(LogCHAT, "Abort: %s\n", AbortStrings[i]);
#ifdef SIGALRM
sigsetmask(omask);
#endif
flush_log();
return (ABORT);
}
}
} else {
if (Physical_Read(physical, &ch, 1) < 0) {
LogPrintf(LogERROR, "read error: %s\n", strerror(errno));
*inp = '\0';
return (NOMATCH);
}
connect_log(&ch, 1);
*inp++ = ch;
if (ch == *s) {
s++;
if (*s == '\0') {
#ifdef SIGALRM
sigsetmask(omask);
#endif
*inp = 0;
flush_log();
return (MATCH);
}
} else
s = str;
if (inp == inbuff + IBSIZE) {
memcpy(inbuff, inp - 100, 100);
inp = inbuff + 100;
}
if (s == str) {
for (i = 0; i < numaborts; i++) { /* Look for Abort strings */
int len;
char *s1;
s1 = AbortStrings[i];
len = strlen(s1);
if ((len <= inp - inbuff) && (strncmp(inp - len, s1, len) == 0)) {
LogPrintf(LogCHAT, "Abort: %s\n", s1);
*inp = 0;
#ifdef SIGALRM
sigsetmask(omask);
#endif
flush_log();
return (ABORT);
}
}
}
}
}
}
}
static void
SendString(struct physical *physical, const char *str)
{
char *cp;
int on;
char buff[LINE_LEN];
if (abort_next) {
abort_next = 0;
ExpandString(str, buff, sizeof buff, 0);
AbortStrings[numaborts++] = strdup(buff);
} else if (timeout_next) {
timeout_next = 0;
TimeoutSec = atoi(str);
if (TimeoutSec <= 0)
TimeoutSec = 30;
} else {
if (*str == '!') {
ExpandString(str + 1, buff + 2, sizeof buff - 2, 0);
ExecStr(physical, buff + 2, buff + 2, sizeof buff - 2);
} else {
ExpandString(str, buff + 2, sizeof buff - 2, 1);
}
if (strstr(str, "\\P")) /* Do not log the password itself. */
LogPrintf(LogCHAT, "Sending: %s", str);
else {
cp = buff + strlen(buff + 2) + 1;
while (cp >= buff + 2 && *cp == '\n')
cp--;
LogPrintf(LogCHAT, "Sending: %.*s\n", cp - buff - 1, buff + 2);
}
cp = buff;
if (Physical_IsSync(physical))
memcpy(buff, "\377\003", 2); /* Prepend HDLC header */
else
cp += 2;
on = strlen(cp);
/* XXX - missing return value check */
Physical_Write(physical, cp, on);
}
}
static int
ExpectString(struct physical *physical, char *str)
{
char *minus;
int state;
if (strcmp(str, "ABORT") == 0) {
++abort_next;
return (MATCH);
}
if (strcmp(str, "TIMEOUT") == 0) {
++timeout_next;
return (MATCH);
}
LogPrintf(LogCHAT, "Expecting: %s\n", str);
while (*str) {
/*
* Check whether if string contains sub-send-expect.
*/
for (minus = str; *minus; minus++) {
if (*minus == '-') {
if (minus == str || minus[-1] != '\\')
break;
}
}
if (*minus == '-') { /* We have sub-send-expect. */
*minus = '\0'; /* XXX: Cheat with the const string */
state = WaitforString(physical, str);
*minus = '-'; /* XXX: Cheat with the const string */
minus++;
if (state != NOMATCH)
return (state);
/*
* Can't get expect string. Sendout send part.
*/
str = minus;
for (minus = str; *minus; minus++) {
if (*minus == '-') {
if (minus == str || minus[-1] != '\\')
break;
}
}
if (*minus == '-') {
*minus = '\0'; /* XXX: Cheat with the const string */
SendString(physical, str);
*minus = '-'; /* XXX: Cheat with the const string */
str = ++minus;
} else {
SendString(physical, str);
return (MATCH);
}
} else {
/*
* Simple case. Wait for string.
*/
return (WaitforString(physical, str));
}
}
return (MATCH);
}
static void (*oint) (int);
static void
StopDial(int sig)
{
LogPrintf(LogPHASE, "DoChat: Caught signal %d, abort connect\n", sig);
longjmp(ChatEnv, 1);
}
int
DoChat(struct physical *physical, char *script)
{
char *vector[MAXARGS];
char *const *argv;
int argc, n, state, err;
if (!script || !*script)
return MATCH;
if ((err = setjmp(ChatEnv))) {
signal(SIGINT, oint);
if (err == 1)
/* Caught a SIGINT during chat */
return (-1);
return (NOMATCH);
}
oint = signal(SIGINT, StopDial);
timeout_next = abort_next = 0;
for (n = 0; AbortStrings[n]; n++) {
free(AbortStrings[n]);
AbortStrings[n] = NULL;
}
numaborts = 0;
memset(vector, '\0', sizeof vector);
argc = MakeArgs(script, vector, VECSIZE(vector));
argv = vector;
TimeoutSec = 30;
while (*argv) {
if (strcmp(*argv, "P_ZERO") == 0 ||
strcmp(*argv, "P_ODD") == 0 || strcmp(*argv, "P_EVEN") == 0) {
modem_SetParity(physical, *argv++);
continue;
}
state = ExpectString(physical, *argv++);
switch (state) {
case MATCH:
if (*argv)
SendString(physical, *argv++);
break;
case ABORT:
case NOMATCH:
signal(SIGINT, oint);
return (NOMATCH);
}
}
signal(SIGINT, oint);
return (MATCH);
}

View File

@ -1,29 +1,75 @@
/*
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
/*-
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
* All rights reserved.
*
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* Most of codes are derived from chat.c by Karl Fox (karl@MorningStar.Com).
*
* Chat -- a program for automatic session establishment (i.e. dial
* the phone and log in).
*
* This software is in the public domain.
*
* Please send all bug reports, requests for information, etc. to:
*
* Karl Fox <karl@MorningStar.Com>
* Morning Star Technologies, Inc.
* 1760 Zollinger Road
* Columbus, OH 43221
* (614)451-1883
*
* $Id: chat.h,v 1.9 1997/11/22 03:37:27 brian Exp $
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#define CHAT_EXPECT 0
#define CHAT_SEND 1
#define CHAT_DONE 2
#define CHAT_FAILED 3
struct chat {
struct descriptor desc;
struct physical *physical;
int state; /* Our CHAT_* status */
char script[LINE_LEN]; /* Our arg buffer */
char *argv[MAXARGS]; /* Our arguments (pointing to script) */
int argc; /* Number of argv's */
int arg; /* Our current arg number */
char exp[LINE_LEN]; /* Our translated current argument */
char *argptr; /* Our current arg pointer */
int arglen; /* The length of argptr */
char *nargptr; /* Our next for expect-send-expect */
char buf[LINE_LEN*2]; /* Our input */
char *bufstart; /* start of relevent data */
char *bufend; /* end of relevent data */
int TimeoutSec; /* Expect timeout value */
int TimedOut; /* We timed out */
char *AbortStrings[50]; /* Abort the dial if we get one */
int numaborts; /* How many AbortStrings */
struct pppTimer pause; /* Inactivity timer */
struct pppTimer timeout; /* TimeoutSec timer */
};
#define chat2descriptor(c) (&(c)->desc)
#define descriptor2chat(d) \
((d)->type == CHAT_DESCRIPTOR ? (struct chat *)(d) : NULL)
void chat_Init(struct chat *, struct physical *, const char *, int);
void chat_Destroy(struct chat *);
extern struct chat chat;
#define VECSIZE(v) (sizeof(v) / sizeof(v[0]))
extern char *ExpandString(const char *, char *, int, int);
extern char *chat_ExpandString(struct chat *, const char *, char *, int, int);
extern int MakeArgs(char *, char **, int); /* Mangles the first arg ! */
extern int DoChat(struct physical *, char *); /* passes arg to MakeArgs() */

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: command.c,v 1.131.2.14 1998/02/10 03:21:39 brian Exp $
* $Id: command.c,v 1.131.2.15 1998/02/10 03:23:09 brian Exp $
*
*/
#include <sys/param.h>
@ -64,7 +64,6 @@
#include "loadalias.h"
#include "vars.h"
#include "systems.h"
#include "chat.h"
#include "bundle.h"
#include "main.h"
#include "route.h"
@ -78,6 +77,7 @@
#include "physical.h"
#include "server.h"
#include "prompt.h"
#include "chat.h"
struct in_addr ifnetmask;
static const char *HIDDEN = "********";
@ -169,6 +169,11 @@ DialCommand(struct cmdargs const *arg)
int tries;
int res;
if (dialing) {
prompt_Printf(&prompt, "A dial is already in progress\n");
return 0;
}
if (LcpInfo.fsm.state > ST_CLOSED) {
prompt_Printf(&prompt, "LCP state is [%s]\n",
StateNames[LcpInfo.fsm.state]);
@ -184,24 +189,7 @@ DialCommand(struct cmdargs const *arg)
if (arg->argc > 0 && (res = LoadCommand(arg)) != 0)
return res;
tries = 0;
do {
if (tries) {
LogPrintf(LogPHASE, "Enter pause (%d) for redialing.\n",
VarRedialNextTimeout);
nointr_sleep(VarRedialNextTimeout);
}
prompt_Printf(&prompt, "Dial attempt %u of %d\n", ++tries, VarDialTries);
if (modem_Open(arg->bundle->physical, arg->bundle) < 0) {
prompt_Printf(&prompt, "Failed to open modem.\n");
break;
}
if ((res = modem_Dial(arg->bundle->physical, arg->bundle)) == EX_DONE) {
PacketMode(arg->bundle, VarOpenMode);
break;
} else if (res == EX_SIG)
return 1;
} while (VarDialTries == 0 || tries < VarDialTries);
dial_up = 1;
return 0;
}

View File

@ -23,12 +23,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: descriptor.h,v 1.1.2.3 1998/02/10 03:21:55 brian Exp $
* $Id: descriptor.h,v 1.1.2.4 1998/02/10 03:23:17 brian Exp $
*/
#define PHYSICAL_DESCRIPTOR (1)
#define SERVER_DESCRIPTOR (2)
#define PROMPT_DESCRIPTOR (3)
#define CHAT_DESCRIPTOR (4)
struct descriptor {
int type;

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.c,v 1.121.2.19 1998/02/10 03:23:28 brian Exp $
* $Id: main.c,v 1.121.2.20 1998/02/10 22:28:51 brian Exp $
*
* TODO:
* o Add commands for traffic summary, version display, etc.
@ -79,6 +79,7 @@
#include "physical.h"
#include "server.h"
#include "prompt.h"
#include "chat.h"
#ifndef O_NONBLOCK
#ifdef O_NDELAY
@ -88,7 +89,8 @@
static pid_t BGPid = 0;
static char pid_filename[MAXPATHLEN];
static int dial_up;
int dial_up;
int dialing;
static void DoLoop(struct bundle *);
static void TerminalStop(int);
@ -603,7 +605,7 @@ DoLoop(struct bundle *bundle)
* If we lost carrier and want to re-establish the connection due to the
* "set reconnect" value, we'd better bring the line back up.
*/
if (LcpInfo.fsm.state <= ST_CLOSED) {
if (!dialing && LcpInfo.fsm.state <= ST_CLOSED) {
if (!dial_up && reconnectState == RECON_TRUE) {
if (++reconnectCount <= VarReconnectTries) {
LogPrintf(LogPHASE, "Connection lost, re-establish (%d/%d)\n",
@ -626,7 +628,7 @@ DoLoop(struct bundle *bundle)
/*
* If Ip packet for output is enqueued and require dial up, Just do it!
*/
if (dial_up && RedialTimer.state != TIMER_RUNNING) {
if (dial_up && !dialing && RedialTimer.state != TIMER_RUNNING) {
LogPrintf(LogDEBUG, "going to dial: modem = %d\n",
Physical_GetFD(bundle->physical));
if (modem_Open(bundle->physical, bundle) < 0) {
@ -654,33 +656,9 @@ DoLoop(struct bundle *bundle)
else
LogPrintf(LogCHAT, "Dial attempt %u\n", tries);
if ((res = modem_Dial(bundle->physical, bundle)) == EX_DONE) {
PacketMode(bundle, VarOpenMode);
dial_up = 0;
reconnectState = RECON_UNKNOWN;
tries = 0;
} else {
if (mode & MODE_BACKGROUND) {
if (VarNextPhone == NULL || res == EX_SIG)
Cleanup(EX_DIAL); /* Tried all numbers - no luck */
else
/* Try all numbers in background mode */
StartRedialTimer(VarRedialNextTimeout);
} else if (!(mode & MODE_DDIAL) &&
((VarDialTries && tries >= VarDialTries) ||
res == EX_SIG)) {
/* I give up ! Can't get through :( */
StartRedialTimer(VarRedialTimeout);
dial_up = 0;
reconnectState = RECON_UNKNOWN;
reconnectCount = 0;
tries = 0;
} else if (VarNextPhone == NULL)
/* Dial failed. Keep quite during redial wait period. */
StartRedialTimer(VarRedialTimeout);
else
StartRedialTimer(VarRedialNextTimeout);
}
chat_Init(&chat, bundle->physical, VarDialScript, 1);
dialing = 1;
dial_up = 0;
}
}
@ -692,7 +670,54 @@ DoLoop(struct bundle *bundle)
handle_signals();
descriptor_UpdateSet(&bundle->physical->desc, &rfds, &wfds, &efds, &nfds);
if (dialing) {
descriptor_UpdateSet(&chat.desc, &rfds, &wfds, &efds, &nfds);
if (dialing == -1) {
if (chat.state == CHAT_DONE || chat.state == CHAT_FAILED) {
dialing = 0;
modem_Close(bundle->physical);
if (mode & MODE_BACKGROUND) {
if (VarNextPhone == NULL || res == EX_SIG)
Cleanup(EX_DIAL); /* Tried all numbers - no luck */
else
/* Try all numbers in background mode */
StartRedialTimer(VarRedialNextTimeout);
} else if (!(mode & MODE_DDIAL) &&
((VarDialTries && tries >= VarDialTries) ||
res == EX_SIG)) {
/* I give up ! Can't get through :( */
StartRedialTimer(VarRedialTimeout);
dial_up = 0;
reconnectState = RECON_UNKNOWN;
reconnectCount = 0;
tries = 0;
} else if (VarNextPhone == NULL)
/* Dial failed. Keep quite during redial wait period. */
StartRedialTimer(VarRedialTimeout);
else
StartRedialTimer(VarRedialNextTimeout);
continue;
}
} else if (chat.state == CHAT_DONE) {
if (dialing == 1) {
chat_Init(&chat, bundle->physical, VarLoginScript, 0);
dialing++;
continue;
} else {
PacketMode(bundle, VarOpenMode);
reconnectState = RECON_UNKNOWN;
tries = 0;
dialing = 0;
}
} else if (chat.state == CHAT_FAILED) {
chat_Init(&chat, bundle->physical, VarHangupScript, 0);
dialing = -1;
continue;
}
}
if (!dialing)
descriptor_UpdateSet(&bundle->physical->desc, &rfds, &wfds, &efds, &nfds);
descriptor_UpdateSet(&server.desc, &rfds, &wfds, &efds, &nfds);
#ifndef SIGALRM
@ -761,15 +786,22 @@ DoLoop(struct bundle *bundle)
if (descriptor_IsSet(&prompt.desc, &rfds))
descriptor_Read(&prompt.desc, bundle, &rfds);
if (descriptor_IsSet(&bundle->physical->desc, &wfds)) {
/* ready to write into modem */
descriptor_Write(&bundle->physical->desc, &wfds);
if (!link_IsActive(physical2link(bundle->physical)))
dial_up = 1;
}
if (dialing) {
if (descriptor_IsSet(&chat.desc, &wfds))
descriptor_Write(&chat.desc, &wfds);
if (descriptor_IsSet(&chat.desc, &rfds))
descriptor_Read(&chat.desc, bundle, &rfds);
} else {
if (descriptor_IsSet(&bundle->physical->desc, &wfds)) {
/* ready to write into modem */
descriptor_Write(&bundle->physical->desc, &wfds);
if (!link_IsActive(physical2link(bundle->physical)))
dial_up = 1;
}
if (descriptor_IsSet(&bundle->physical->desc, &rfds))
descriptor_Read(&bundle->physical->desc, bundle, &rfds);
if (descriptor_IsSet(&bundle->physical->desc, &rfds))
descriptor_Read(&bundle->physical->desc, bundle, &rfds);
}
if (bundle->tun_fd >= 0 && FD_ISSET(bundle->tun_fd, &rfds)) {
/* something to read from tun */

View File

@ -17,11 +17,13 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: main.h,v 1.9.2.3 1998/02/08 11:07:32 brian Exp $
* $Id: main.h,v 1.9.2.4 1998/02/10 03:23:31 brian Exp $
*
*/
extern int CleaningUp;
extern int dial_up;
extern int dialing;
extern void Cleanup(int);
extern void AbortProgram(int);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: modem.c,v 1.77.2.13 1998/02/10 03:22:00 brian Exp $
* $Id: modem.c,v 1.77.2.14 1998/02/10 03:23:35 brian Exp $
*
* TODO:
*/
@ -57,7 +57,6 @@
#include "loadalias.h"
#include "vars.h"
#include "main.h"
#include "chat.h"
#include "throughput.h"
#include "async.h"
#include "bundle.h"
@ -65,6 +64,7 @@
#include "descriptor.h"
#include "physical.h"
#include "prompt.h"
#include "chat.h"
#ifndef O_NONBLOCK
@ -79,6 +79,8 @@ static void modem_Hangup(struct link *, int);
static void modem_Destroy(struct link *);
static void modem_DescriptorRead(struct descriptor *, struct bundle *,
const fd_set *);
static int modem_UpdateSet(struct descriptor *, fd_set *, fd_set *, fd_set *,
int *);
struct physical *
modem_Create(const char *name)
@ -101,7 +103,7 @@ modem_Create(const char *name)
p->speed = MODEM_SPEED;
p->parity = CS8;
p->desc.type = PHYSICAL_DESCRIPTOR;
p->desc.UpdateSet = Physical_UpdateSet;
p->desc.UpdateSet = modem_UpdateSet;
p->desc.IsSet = Physical_IsSet;
p->desc.Read = modem_DescriptorRead;
p->desc.Write = Physical_DescriptorWrite;
@ -727,24 +729,38 @@ modem_PhysicalClose(struct physical *modem)
throughput_log(&modem->link.throughput, LogPHASE, "Modem");
}
static int force_hack;
static void
modem_Hangup(struct link *l, int dedicated_force)
{
struct termios tio;
struct physical *modem = (struct physical *)l;
force_hack = dedicated_force;
if (modem->fd >= 0 && dialing != -1) {
StopTimer(&modem->link.Timer);
throughput_stop(&modem->link.throughput);
if (prompt_IsTermMode(&prompt))
prompt_TtyCommandMode(&prompt);
dialing = -1;
dial_up = 0;
chat_Init(&chat, modem, VarHangupScript, 1);
}
}
void
modem_Close(struct physical *modem)
{
struct termios tio;
LogPrintf(LogDEBUG, "Hangup modem (%s)\n",
modem->fd >= 0 ? "open" : "closed");
if (modem->fd < 0)
return;
StopTimer(&modem->link.Timer);
throughput_stop(&modem->link.throughput);
if (prompt_IsTermMode(&prompt))
prompt_TtyCommandMode(&prompt);
if (!isatty(modem->fd)) {
modem->mbits &= ~TIOCM_DTR;
modem_PhysicalClose(modem);
@ -762,19 +778,13 @@ modem_Hangup(struct link *l, int dedicated_force)
}
if (modem->fd >= 0) {
char ScriptBuffer[SCRIPT_LEN];
strncpy(ScriptBuffer, VarHangupScript, sizeof ScriptBuffer - 1);
ScriptBuffer[sizeof ScriptBuffer - 1] = '\0';
LogPrintf(LogDEBUG, "modem_Hangup: Script: %s\n", ScriptBuffer);
if (dedicated_force ||
if (force_hack ||
#ifdef notyet
!modem->is_dedicated
#else
!(mode & MODE_DEDICATED)
#endif
) {
DoChat(modem, ScriptBuffer);
tcflush(modem->fd, TCIOFLUSH);
modem_Unraw(modem);
modem_LogicalClose(modem);
@ -785,7 +795,6 @@ modem_Hangup(struct link *l, int dedicated_force)
*/
modem->mbits |= TIOCM_DTR;
ioctl(modem->fd, TIOCMSET, &modem->mbits);
DoChat(modem, ScriptBuffer);
}
}
}
@ -867,43 +876,6 @@ modem_IsActive(struct link *l)
return ((struct physical *)l)->fd >= 0;
}
int
modem_Dial(struct physical *modem, struct bundle *bundle)
{
char ScriptBuffer[SCRIPT_LEN];
int excode;
strncpy(ScriptBuffer, VarDialScript, sizeof ScriptBuffer - 1);
ScriptBuffer[sizeof ScriptBuffer - 1] = '\0';
if ((excode = DoChat(modem, ScriptBuffer)) > 0) {
prompt_Printf(&prompt, "dial OK!\n");
strncpy(ScriptBuffer, VarLoginScript, sizeof ScriptBuffer - 1);
if ((excode = DoChat(modem, ScriptBuffer)) > 0) {
struct timeoutArg to;
VarAltPhone = NULL;
prompt_Printf(&prompt, "login OK!\n");
to.modem = modem;
to.bundle = bundle;
modem_Timeout(&to);
return EX_DONE;
} else if (excode == -1)
excode = EX_SIG;
else {
LogPrintf(LogWARN, "modem_Dial: login failed.\n");
excode = EX_NOLOGIN;
}
modem_Timeout(modem); /* Dummy call to check modem status */
} else if (excode == -1)
excode = EX_SIG;
else {
LogPrintf(LogWARN, "modem_Dial: dial failed.\n");
excode = EX_NODIAL;
}
modem_Hangup(&modem->link, 0);
return (excode);
}
int
modem_ShowStatus(struct cmdargs const *arg)
{
@ -1015,3 +987,9 @@ modem_DescriptorRead(struct descriptor *d, struct bundle *bundle,
} else if (n > 0)
async_Input(bundle, rbuff, n, p);
}
static int
modem_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
{
return Physical_UpdateSet(d, r, w, e, n, 0);
}

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: modem.h,v 1.16.2.4 1998/02/06 02:22:23 brian Exp $
* $Id: modem.h,v 1.16.2.5 1998/02/06 02:22:51 brian Exp $
*
* TODO:
*/
@ -26,7 +26,7 @@ extern int modem_Raw(struct physical *);
extern struct physical *modem_Create(const char *);
extern int modem_Open(struct physical *, struct bundle *);
extern int modem_Speed(struct physical *);
extern int modem_Dial(struct physical *, struct bundle *);
extern speed_t IntToSpeed(int);
extern int modem_SetParity(struct physical *, const char *);
extern int modem_ShowStatus(struct cmdargs const *);
extern void modem_Close(struct physical *);

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: physical.c,v 1.1.2.6 1998/02/09 19:21:07 brian Exp $
* $Id: physical.c,v 1.1.2.7 1998/02/10 03:22:02 brian Exp $
*
*/
@ -179,25 +179,30 @@ Physical_ReportProtocolStatus(struct cmdargs const *arg)
int
Physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
int *n)
int *n, int force)
{
struct physical *p = descriptor2physical(d);
int sets;
LogPrintf(LogDEBUG, "descriptor2physical; %p -> %p\n", d, p);
sets = 0;
if (p->fd >= 0) {
if (*n < p->fd + 1)
*n = p->fd + 1;
FD_SET(p->fd, r);
FD_SET(p->fd, e);
if (link_QueueLen(&p->link)) {
if (r) {
FD_SET(p->fd, r);
sets++;
}
if (e) {
FD_SET(p->fd, e);
sets++;
}
if (w && (force || link_QueueLen(&p->link))) {
FD_SET(p->fd, w);
sets = 3;
} else
sets = 2;
} else
sets = 0;
sets++;
}
if (sets && *n < p->fd + 1)
*n = p->fd + 1;
}
return sets;
}

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: physical.h,v 1.1.2.6 1998/02/09 19:21:08 brian Exp $
* $Id: physical.h,v 1.1.2.7 1998/02/10 03:22:03 brian Exp $
*
*/
@ -86,6 +86,7 @@ void Physical_DupAndClose(struct physical *);
ssize_t Physical_Read(struct physical *phys, void *buf, size_t nbytes);
ssize_t Physical_Write(struct physical *phys, const void *buf, size_t nbytes);
int Physical_ReportProtocolStatus(struct cmdargs const *);
int Physical_UpdateSet(struct descriptor *, fd_set *, fd_set *, fd_set *, int *);
int Physical_UpdateSet(struct descriptor *, fd_set *, fd_set *, fd_set *,
int *, int);
int Physical_IsSet(struct descriptor *, fd_set *);
void Physical_DescriptorWrite(struct descriptor *, const fd_set *);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: prompt.c,v 1.1.2.1 1998/02/10 03:23:38 brian Exp $
*/
#include <sys/param.h>
@ -59,18 +59,25 @@ static int
prompt_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
{
struct prompt *p = descriptor2prompt(d);
int sets;
LogPrintf(LogDEBUG, "descriptor2prompt; %p -> %p\n", d, p);
sets = 0;
if (p->fd_in >= 0) {
if (*n < p->fd_in + 1)
if (r) {
FD_SET(p->fd_in, r);
sets++;
}
if (e) {
FD_SET(p->fd_in, e);
sets++;
}
if (sets && *n < p->fd_in + 1)
*n = p->fd_in + 1;
FD_SET(p->fd_in, r);
FD_SET(p->fd_in, e);
return 2;
}
return 0;
return sets;
}
static int

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: server.c,v 1.16.2.3 1998/02/10 03:22:05 brian Exp $
* $Id: server.c,v 1.16.2.4 1998/02/10 03:23:41 brian Exp $
*/
#include <sys/param.h>
@ -57,7 +57,7 @@ server_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
struct server *s = descriptor2server(d);
LogPrintf(LogDEBUG, "descriptor2server; %p -> %p\n", d, s);
if (s->fd >= 0) {
if (r && s->fd >= 0) {
if (*n < s->fd + 1)
*n = s->fd + 1;
FD_SET(s->fd, r);

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: vars.c,v 1.45.2.5 1998/02/09 19:21:11 brian Exp $
* $Id: vars.c,v 1.45.2.6 1998/02/10 03:23:49 brian Exp $
*
*/
#include <sys/param.h>
@ -45,8 +45,8 @@
#include "physical.h"
#include "prompt.h"
char VarVersion[] = "PPP Version 1.90";
char VarLocalVersion[] = "$Date: 1998/02/09 19:21:11 $";
char VarVersion[] = "PPP Version 2.0-beta";
char VarLocalVersion[] = "$Date: 1998/02/10 03:23:49 $";
int Utmp = 0;
int ipKeepAlive = 0;
int reconnectState = RECON_UNKNOWN;