From 9eadf0b143403db444c333e7e187b9e902dc6134 Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Wed, 17 Sep 2003 19:33:34 +0000 Subject: [PATCH] Fixed zmodem timeout bug --- ChangeLog | 8 +++ lib/Makefile | 5 +- lib/common.h | 22 ++++---- lib/timers.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++ mbcico/emsi.c | 22 ++++---- mbcico/session.c | 24 ++++----- 6 files changed, 174 insertions(+), 36 deletions(-) create mode 100644 lib/timers.c diff --git a/ChangeLog b/ChangeLog index 3baf9eae..187fc95c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,14 @@ v0.37.8 14-Sep-2003 general: This version is issued to prepare for a stable release. + common.a: + Added a set of general purpose timers. + + mbcico: + Session handshake and EMSI handshake use the general purpose + timers instead of the ttyio timers. This should prevent invalid + timeouts during zmodem transfers. (bug since 0.37.6). + v0.37.7 09-Sep-2003 - 14-09-2003 diff --git a/lib/Makefile b/lib/Makefile index d0cb9885..e6019730 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -11,12 +11,12 @@ COMMON_SRCS = attach.c falists.c hdr.c parsedate.c rfcmsg.c unpacker.c \ batchrd.c ftn.c pktname.c mangle.c sectest.c proglock.c \ dostran.c ftnmsg.c mbfile.c nodelock.c rawio.c strcasestr.c \ execute.c expipe.c getheader.c noderecord.c rfcaddr.c strutil.c \ - faddr.c gmtoffset.c packet.c rfcdate.c term.c endian.c + faddr.c gmtoffset.c packet.c rfcdate.c term.c endian.c timers.c COMMON_OBJS = ftscprod.o attach.o falists.o hdr.o parsedate.o rfcmsg.o unpacker.o \ batchrd.o ftn.o pktname.o mangle.o sectest.o proglock.o \ dostran.o ftnmsg.o mbfile.o nodelock.o rawio.o strcasestr.o \ execute.o expipe.o getheader.o noderecord.o rfcaddr.o strutil.o \ - faddr.o gmtoffset.o packet.o rfcdate.o term.o endian.o + faddr.o gmtoffset.o packet.o rfcdate.o term.o endian.o timers.o COMMON_HDRS = common.h NODELIST_SRCS = nodelist.c NODELIST_OBJS = nodelist.o @@ -152,6 +152,7 @@ packet.o: ../config.h libs.h structs.h users.h records.h clcomm.h common.h dbnod rfcdate.o: ../config.h libs.h structs.h common.h clcomm.h term.o: ../config.h libs.h structs.h users.h ansi.h records.h common.h endian.o: ../config.h libs.h structs.h common.h +timers.o: ../config.h libs.h structs.h clcomm.h common.h dbcfg.o: ../config.h libs.h mbse.h structs.h users.h records.h mberrors.h dbcfg.h dbdupe.o: ../config.h libs.h structs.h clcomm.h mberrors.h dbdupe.h dbftn.o: ../config.h libs.h structs.h users.h records.h dbcfg.h dbftn.h diff --git a/lib/common.h b/lib/common.h index 7fdf1d7a..0192635a 100644 --- a/lib/common.h +++ b/lib/common.h @@ -434,17 +434,6 @@ char *bgets(char *, int, FILE *); -/* - * some special chars values - */ -// #define NUL 0 -// #define NL 10 -// #define FF 12 -// #define CR 13 -// #define ESC 27 - - - /* * parsedate.c */ @@ -514,5 +503,16 @@ int Le_Access(securityrec, securityrec); /* Endian independant */ int lockprogram(char *); /* Lock a program */ void ulockprogram(char *); /* Unlock a program */ + + +/* + * timers.c + */ +int gpt_resettimer(int); /* Reset timer no */ +void gpt_resettimers(void); /* Reset all timers */ +int gpt_settimer(int, int); /* Set timer no to time */ +int gpt_expired(int); /* Is timer expired */ +int gpt_running(int); /* Is timer running */ + #endif diff --git a/lib/timers.c b/lib/timers.c new file mode 100644 index 00000000..365de5df --- /dev/null +++ b/lib/timers.c @@ -0,0 +1,129 @@ +/***************************************************************************** + * + * $Id$ + * Purpose ...............: General Purpose Timers + * + ***************************************************************************** + * Copyright (C) 1997-2003 + * + * Michiel Broek FIDO: 2:280/2802 + * Beekmansbos 10 + * 1971 BV IJmuiden + * the Netherlands + * + * This file is part of MBSE BBS. + * + * This BBS is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * MBSE BBS is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MBSE BBS; see the file COPYING. If not, write to the Free + * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + *****************************************************************************/ + +#include "../config.h" +#include "libs.h" +#include "structs.h" +#include "clcomm.h" +#include "common.h" + + +/* + * Number of timers + */ +#define GENTIMERS 3 + +static time_t gentimer[GENTIMERS]; + + +/* + * Reset a timer + */ +int gpt_resettimer(int tno) +{ + if (tno >= GENTIMERS) { + errno = EINVAL; + WriteError("invalid timer number for gpt_resettimer(%d)", tno); + return -1; + } + + gentimer[tno] = (time_t) 0; + return 0; +} + + + +void gpt_resettimers(void) +{ + int i; + + for (i = 0; i < GENTIMERS; i++) + gpt_resettimer(i); +} + + + +/* + * Set timer + */ +int gpt_settimer(int tno, int interval) +{ + if (tno >= GENTIMERS) { + errno = EINVAL; + WriteError("invalid timer number for gpt_settimer(%d)", tno); + return -1; + } + + gentimer[tno] = time((time_t*)NULL) + interval; + return 0; +} + + + +/* + * Check if timer is expired + */ +int gpt_expired(int tno) +{ + time_t now; + + if (tno >= GENTIMERS) { + errno = EINVAL; + WriteError("invalid timer number for gpt_expired(%d)", tno); + return -1; + } + + /* + * Check if timer is running + */ + if (gentimer[tno] == (time_t) 0) + return 0; + + now = time(NULL); + return (now >= gentimer[tno]); +} + + + +int gpt_running(int tno) +{ + if (tno >= GENTIMERS) { + errno = EINVAL; + WriteError("invalid timer number for gpt_running(%d)", tno); + return -1; + } + + if (gentimer[tno] == (time_t) 0) + return 0; + else + return 1; +} + + diff --git a/mbcico/emsi.c b/mbcico/emsi.c index 997be710..6485401a 100644 --- a/mbcico/emsi.c +++ b/mbcico/emsi.c @@ -307,28 +307,28 @@ SM_START(init) SM_STATE(init) Syslog('i', "RXEMSI: init"); - RESETTIMERS(); - SETTIMER(0, 60); - SETTIMER(1, 20); + gpt_resettimers(); + gpt_settimer(0, 60); + gpt_settimer(1, 20); SM_PROCEED(checkpkt); SM_STATE(waitpkt) Syslog('i', "RXEMSI: waitpkt"); standby = 0; - SETTIMER(1, 20); + gpt_settimer(1, 20); SM_PROCEED(waitchar); SM_STATE(waitchar) Syslog('i', "RXEMSI: waitchar, tries=%d", tries); - if (EXPIRED(0)) { + if (gpt_expired(0)) { Syslog('+', "EMSI receive 60 seconds timeout"); SM_ERROR; } - if (EXPIRED(1)) { + if (gpt_expired(1)) { Syslog('s', "20 sec timeout"); SM_PROCEED(sendnak); } @@ -517,8 +517,8 @@ SM_EDECL p = buf; memset(&buf, 0, sizeof(buf)); strncpy(buf, intro, sizeof(buf) - 1); - RESETTIMERS(); - SETTIMER(0, 60); + gpt_resettimers(); + gpt_settimer(0, 60); Syslog('i', "TXEMSI: 60 seconds timer set"); SM_START(senddata) @@ -534,7 +534,7 @@ SM_STATE(senddata) PUTSTR(trailer); Syslog('i', "TXEMSI: send **%s%04X", p, crc16xmodem(p, strlen(p))); free(p); - SETTIMER(1, 20); + gpt_settimer(1, 20); SM_PROCEED(waitpkt); SM_STATE(waitpkt) @@ -544,12 +544,12 @@ SM_STATE(waitpkt) SM_STATE(waitchar) - if (EXPIRED(0)) { + if (gpt_expired(0)) { Syslog('+', "EMSI transmit 60 seconds timeout"); SM_ERROR; } - if (EXPIRED(1)) { + if (gpt_expired(1)) { Syslog('i', "TXEMSI: 20 seconds timeout"); if (++tries > 19) { Syslog('+', "too many tries sending EMSI"); diff --git a/mbcico/session.c b/mbcico/session.c index 4a62933b..4bb5d48c 100644 --- a/mbcico/session.c +++ b/mbcico/session.c @@ -232,8 +232,8 @@ SM_STATE(skipjunk) Syslog('s', "tx_define_type SKIPJUNK"); while ((c = GETCHAR(1)) >= 0) /*nothing*/ ; if (c == TIMEOUT) { - RESETTIMERS(); - SETTIMER(0, 60); /* 60 second master timer */ + gpt_resettimers(); + gpt_settimer(0, 60); /* 60 second master timer */ SM_PROCEED(wake); } else { SM_ERROR; @@ -242,7 +242,7 @@ SM_STATE(skipjunk) SM_STATE(wake) Syslog('s', "tx_define_type WAKE"); - if (EXPIRED(0)) { + if (gpt_expired(0)) { Syslog('+', "Remote did not respond"); SM_ERROR; } @@ -255,7 +255,7 @@ SM_STATE(wake) WriteError("Error while waking remote"); SM_ERROR; } else { - SETTIMER(0, 60); + gpt_settimer(0, 60); Syslog('S', "Got %c wakeup", c); SM_PROCEED(nextchar); } @@ -266,7 +266,7 @@ SM_STATE(waitchar) standby = 0; ep = ebuf; ebuf[0] = '\0'; - if (EXPIRED(0)) { + if (gpt_expired(0)) { Syslog('+', "Too many tries waking remote"); SM_ERROR; } @@ -413,9 +413,9 @@ SM_EDECL session_flags|=FTSC_XMODEM_CRC; ebuf[0]='\0'; ep=ebuf; - RESETTIMERS(); - SETTIMER(0, 60); - SETTIMER(1, 20); + gpt_resettimers(); + gpt_settimer(0, 60); + gpt_settimer(1, 20); SM_START(sendintro) @@ -457,17 +457,17 @@ SM_STATE(sendintro) SM_STATE(settimer) Syslog('s', "Set 20 secs timer"); - SETTIMER(1, 20); + gpt_settimer(1, 20); SM_PROCEED(waitchar); SM_STATE(waitchar) - if (EXPIRED(0)) { + if (gpt_expired(0)) { Syslog('+', "Session setup timeout"); SM_ERROR; } - if (EXPIRED(1)) { + if (gpt_expired(1)) { Syslog('s', "20 sec timer timeout"); SM_PROCEED(sendintro); } @@ -535,7 +535,7 @@ SM_STATE(nextchar) * first sendintro, send the intro again. After * that take it easy. */ - if (EXPIRED(1) || (count == 1)) { + if (gpt_expired(1) || (count == 1)) { Syslog('s', "sendintro after eol char"); SM_PROCEED(sendintro); } else {