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*)
This commit is contained in:
parent
47f97505ad
commit
ffcfaec721
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue