From ffcfaec72128b7008cb8f06275a954d93c2d4fc5 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Fri, 3 Dec 1999 06:33:10 +0000 Subject: [PATCH] Be careful not to re-initialise `struct stat' while it still has a running timer. This fixes a problem where a dial is manually aborted, the hangup script kicks in and the chat timer ends up on the timer queue twice (tick tick tick tick *boom*) --- usr.sbin/ppp/chat.c | 31 +++++++++++++++++++++++-------- usr.sbin/ppp/chat.h | 5 +++-- usr.sbin/ppp/datalink.c | 32 ++++++++++++++++---------------- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/usr.sbin/ppp/chat.c b/usr.sbin/ppp/chat.c index f3bc7d67f70..0ccda30d583 100644 --- a/usr.sbin/ppp/chat.c +++ b/usr.sbin/ppp/chat.c @@ -531,8 +531,7 @@ chat_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) } void -chat_Init(struct chat *c, struct physical *p, const char *data, - const char *phone) +chat_Init(struct chat *c, struct physical *p) { c->desc.type = CHAT_DESCRIPTOR; c->desc.UpdateSet = chat_UpdateSet; @@ -540,7 +539,20 @@ chat_Init(struct chat *c, struct physical *p, const char *data, c->desc.Read = chat_Read; c->desc.Write = chat_Write; c->physical = p; + *c->script = '\0'; + c->argc = 0; + c->arg = -1; + c->argptr = NULL; + c->nargptr = NULL; + c->bufstart = c->bufend = c->buf; + memset(&c->pause, '\0', sizeof c->pause); + memset(&c->timeout, '\0', sizeof c->timeout); +} + +void +chat_Setup(struct chat *c, const char *data, const char *phone) +{ c->state = CHAT_EXPECT; if (data == NULL) { @@ -556,20 +568,17 @@ chat_Init(struct chat *c, struct physical *p, const char *data, c->argptr = NULL; c->nargptr = NULL; - if (c->bufstart == NULL) - c->bufstart = c->bufend = c->buf; - c->TimeoutSec = 30; c->TimedOut = 0; c->phone = phone; c->abort.num = 0; - memset(&c->pause, '\0', sizeof c->pause); - memset(&c->timeout, '\0', sizeof c->timeout); + timer_Stop(&c->pause); + timer_Stop(&c->timeout); } void -chat_Destroy(struct chat *c) +chat_Finish(struct chat *c) { timer_Stop(&c->pause); timer_Stop(&c->timeout); @@ -578,6 +587,12 @@ chat_Destroy(struct chat *c) c->abort.num = 0; } +void +chat_Destroy(struct chat *c) +{ + chat_Finish(c); +} + /* * \c don't add a cr * \d Sleep a little (delay 2 seconds diff --git a/usr.sbin/ppp/chat.h b/usr.sbin/ppp/chat.h index 90d625dc8dd..872e1c6368f 100644 --- a/usr.sbin/ppp/chat.h +++ b/usr.sbin/ppp/chat.h @@ -76,6 +76,7 @@ struct chat { ((d)->type == CHAT_DESCRIPTOR ? (struct chat *)(d) : NULL) #define VECSIZE(v) (sizeof(v) / sizeof(v[0])) -extern void chat_Init(struct chat *, struct physical *, const char *, - const char *); +extern void chat_Init(struct chat *, struct physical *); +extern void chat_Setup(struct chat *, const char *, const char *); +extern void chat_Finish(struct chat *); extern void chat_Destroy(struct chat *); diff --git a/usr.sbin/ppp/datalink.c b/usr.sbin/ppp/datalink.c index a050e2598f6..b5e20f9eb39 100644 --- a/usr.sbin/ppp/datalink.c +++ b/usr.sbin/ppp/datalink.c @@ -120,7 +120,7 @@ datalink_HangupDone(struct datalink *dl) return; } - chat_Destroy(&dl->chat); + chat_Finish(&dl->chat); physical_Close(dl->physical); dl->phone.chosen = "N/A"; @@ -203,7 +203,7 @@ datalink_ChoosePhoneNumber(struct datalink *dl) static void datalink_LoginDone(struct datalink *dl) { - chat_Destroy(&dl->chat); + chat_Finish(&dl->chat); if (!dl->script.packetmode) { dl->dial.tries = -1; @@ -214,7 +214,7 @@ datalink_LoginDone(struct datalink *dl) log_Printf(LogWARN, "datalink_LoginDone: Not connected.\n"); if (dl->script.run) { datalink_NewState(dl, DATALINK_LOGOUT); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.logout, NULL); + chat_Setup(&dl->chat, dl->cfg.script.logout, NULL); } else { physical_StopDeviceTimer(dl->physical); if (dl->physical->type == PHYS_DEDICATED) @@ -273,9 +273,8 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, dl->physical->name.full); if (dl->script.run) { datalink_NewState(dl, DATALINK_DIAL); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.dial, - *dl->cfg.script.dial ? - datalink_ChoosePhoneNumber(dl) : ""); + chat_Setup(&dl->chat, dl->cfg.script.dial, *dl->cfg.script.dial ? + datalink_ChoosePhoneNumber(dl) : ""); if (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) && dl->cfg.dial.max) log_Printf(LogCHAT, "%s: Dial attempt %u of %d\n", @@ -323,7 +322,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, case CARRIER_OK: if (dl->script.run) { datalink_NewState(dl, DATALINK_LOGIN); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.login, NULL); + chat_Setup(&dl->chat, dl->cfg.script.login, NULL); } else datalink_LoginDone(dl); return datalink_UpdateSet(d, r, w, e, n); @@ -332,7 +331,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, physical_Offline(dl->physical); /* Is this required ? */ if (dl->script.run) { datalink_NewState(dl, DATALINK_HANGUP); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, NULL); + chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL); return datalink_UpdateSet(d, r, w, e, n); } else { datalink_HangupDone(dl); @@ -358,7 +357,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, case DATALINK_LOGOUT: datalink_NewState(dl, DATALINK_HANGUP); physical_Offline(dl->physical); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, NULL); + chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL); return datalink_UpdateSet(d, r, w, e, n); case DATALINK_LOGIN: dl->phone.alt = NULL; @@ -378,7 +377,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, case DATALINK_LOGIN: datalink_NewState(dl, DATALINK_HANGUP); physical_Offline(dl->physical); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, NULL); + chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL); return datalink_UpdateSet(d, r, w, e, n); } break; @@ -512,10 +511,10 @@ datalink_ComeDown(struct datalink *dl, int how) if (dl->script.run && dl->state != DATALINK_OPENING) { if (dl->state == DATALINK_LOGOUT) { datalink_NewState(dl, DATALINK_HANGUP); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, NULL); + chat_Setup(&dl->chat, dl->cfg.script.hangup, NULL); } else { datalink_NewState(dl, DATALINK_LOGOUT); - chat_Init(&dl->chat, dl->physical, dl->cfg.script.logout, NULL); + chat_Setup(&dl->chat, dl->cfg.script.logout, NULL); } } else datalink_HangupDone(dl); @@ -825,7 +824,7 @@ datalink_Create(const char *name, struct bundle *bundle, int type) cbcp_Init(&dl->cbcp, dl->physical); memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ - chat_Init(&dl->chat, dl->physical, NULL, NULL); + chat_Init(&dl->chat, dl->physical); log_Printf(LogPHASE, "%s: Created in %s state\n", dl->name, datalink_State(dl)); @@ -889,7 +888,7 @@ datalink_Clone(struct datalink *odl, const char *name) cbcp_Init(&dl->cbcp, dl->physical); memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ - chat_Init(&dl->chat, dl->physical, NULL, NULL); + chat_Init(&dl->chat, dl->physical); log_Printf(LogPHASE, "%s: Cloned in %s state\n", dl->name, datalink_State(dl)); @@ -909,11 +908,12 @@ datalink_Destroy(struct datalink *dl) case DATALINK_HANGUP: case DATALINK_DIAL: case DATALINK_LOGIN: - chat_Destroy(&dl->chat); /* Gotta blat the timers ! */ + chat_Finish(&dl->chat); /* Gotta blat the timers ! */ break; } } + chat_Destroy(&dl->chat); timer_Stop(&dl->dial.timer); result = dl->next; physical_Destroy(dl->physical); @@ -1327,7 +1327,7 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov, cbcp_Init(&dl->cbcp, dl->physical); memset(&dl->chat, '\0', sizeof dl->chat); /* Force buf{start,end} reset */ - chat_Init(&dl->chat, dl->physical, NULL, NULL); + chat_Init(&dl->chat, dl->physical); log_Printf(LogPHASE, "%s: Transferred in %s state\n", dl->name, datalink_State(dl));