# HG changeset patch # User enz # Date 969705635 -3600 # Node ID 8b9366fc13610816ca4ed0cf7465020cf31d0377 # Parent 7400a8e9d5ba4777d2e87b4c574e976bc08936ab [svn] Added timeout to Prt_getLn to avoid Noffle hanging if the connection breaks down during a fetch. diff -r 7400a8e9d5ba -r 8b9366fc1361 Makefile.in --- a/Makefile.in Sat Sep 23 11:37:01 2000 +0100 +++ b/Makefile.in Sat Sep 23 11:40:35 2000 +0100 @@ -265,7 +265,7 @@ @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$/$$file $(distdir)/$$file; \ + cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff -r 7400a8e9d5ba -r 8b9366fc1361 configure --- a/configure Sat Sep 23 11:37:01 2000 +0100 +++ b/configure Sat Sep 23 11:40:35 2000 +0100 @@ -2030,7 +2030,7 @@ int main() { /* Ultrix mips cc rejects this. */ -typedef int charset[2]; const charset x; +typedef int charset[2]; const charset x = {0,0}; /* SunOS 4.1.1 cc rejects this. */ char const *const *ccp; char **p; diff -r 7400a8e9d5ba -r 8b9366fc1361 docs/Makefile.in --- a/docs/Makefile.in Sat Sep 23 11:37:01 2000 +0100 +++ b/docs/Makefile.in Sat Sep 23 11:40:35 2000 +0100 @@ -185,7 +185,7 @@ @for file in $(DISTFILES); do \ d=$(srcdir); \ if test -d $$d/$$file; then \ - cp -pr $$/$$file $(distdir)/$$file; \ + cp -pr $$d/$$file $(distdir)/$$file; \ else \ test -f $(distdir)/$$file \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ diff -r 7400a8e9d5ba -r 8b9366fc1361 src/client.c --- a/src/client.c Sat Sep 23 11:37:01 2000 +0100 +++ b/src/client.c Sat Sep 23 11:40:35 2000 +0100 @@ -1,7 +1,7 @@ /* client.c - $Id: client.c 191 2000-08-09 21:26:28Z bears $ + $Id: client.c 217 2000-09-23 10:40:35Z enz $ */ #if HAVE_CONFIG_H @@ -87,7 +87,7 @@ { Bool r; - r = Prt_getLn( line, client.in ); + r = Prt_getLn( line, client.in, Cfg_connectTimeout() ); if ( ! r ) logBreakDown(); return r; @@ -98,7 +98,7 @@ { Bool r; - r = Prt_getTxtLn( line, err, client.in ); + r = Prt_getTxtLn( line, err, client.in, Cfg_connectTimeout() ); if ( *err ) logBreakDown(); return r; diff -r 7400a8e9d5ba -r 8b9366fc1361 src/protocol.c --- a/src/protocol.c Sat Sep 23 11:37:01 2000 +0100 +++ b/src/protocol.c Sat Sep 23 11:40:35 2000 +0100 @@ -1,7 +1,7 @@ /* protocol.c - $Id: protocol.c 183 2000-07-25 12:14:54Z bears $ + $Id: protocol.c 217 2000-09-23 10:40:35Z enz $ */ #if HAVE_CONFIG_H @@ -11,8 +11,10 @@ #include #include #include +#include #include #include +#include #include "common.h" #include "dynamicstring.h" #include "log.h" @@ -21,20 +23,61 @@ #include "protocol.h" #include "portable.h" +static void +readAlarm( int sig ) +{ + UNUSED( sig ); + + return; +} + +static sig_t +installSignalHandler( int sig, sig_t handler ) +{ + struct sigaction act, oldAct; + + act.sa_handler = handler; + sigemptyset( &act.sa_mask ); + act.sa_flags = 0; + if ( sig == SIGALRM ) + act.sa_flags |= SA_INTERRUPT; + else + act.sa_flags |= SA_RESTART; + if ( sigaction( sig, &act, &oldAct ) < 0 ) + return SIG_ERR; + return oldAct.sa_handler; +} + Bool -Prt_getLn( Str line, FILE *f ) +Prt_getLn( Str line, FILE *f, int timeoutSeconds ) { size_t len; + char *ret; + sig_t oldHandler = NULL; + if ( timeoutSeconds >= 0 ) + { + oldHandler = installSignalHandler( SIGALRM, readAlarm ); + if ( oldHandler == SIG_ERR ) + { + Log_err( "Prt_getLn: signal failed." ); + return FALSE; + } + if ( alarm( timeoutSeconds ) != 0 ) + Log_err( "Prt_getLn: Alarm was already set." ); + } /* We also accept lines ending with "\n" instead of "\r\n", some clients wrongly send such lines. */ - if ( ! fgets( line, MAXCHAR, f ) ) + ret = fgets( line, MAXCHAR, f ); + if ( timeoutSeconds >= 0 ) { - Log_dbg( "Prt_getLn failed" ); + alarm( 0 ); + installSignalHandler( SIGALRM, oldHandler ); + } + if ( ret == NULL ) return FALSE; - } len = strlen( line ); if ( line[ len - 1 ] == '\n' ) { @@ -47,11 +90,11 @@ } Bool -Prt_getTxtLn( Str line, Bool *err, FILE *f ) +Prt_getTxtLn( Str line, Bool *err, FILE *f, int timeoutSeconds ) { Str buf; - if ( ! Prt_getLn( buf, f ) ) + if ( ! Prt_getLn( buf, f, timeoutSeconds ) ) { Log_err( "Cannot get text line" ); *err = TRUE; diff -r 7400a8e9d5ba -r 8b9366fc1361 src/protocol.h --- a/src/protocol.h Sat Sep 23 11:37:01 2000 +0100 +++ b/src/protocol.h Sat Sep 23 11:40:35 2000 +0100 @@ -4,7 +4,7 @@ Functions related with the NNTP protocol which are useful for both the server and the client. - $Id: protocol.h 155 2000-06-24 20:28:01Z bears $ + $Id: protocol.h 217 2000-09-23 10:40:35Z enz $ */ #ifndef PRT_H @@ -58,16 +58,18 @@ /* Read next line from f into Str, up to "\n" or "\r\n". Don't save "\n" or "\r\n" in line. Terminate with '\0'. + If timeoutSeconds < 0, no timeout alarm is used. */ Bool -Prt_getLn( Str line, FILE *f ); +Prt_getLn( Str line, FILE *f, int timeoutSeconds ); /* Read a text line from server. Returns TRUE if line != ".", removes leading '.' otherwise. + If timeoutSeconds < 0, no timeout alarm is used. */ Bool -Prt_getTxtLn( Str line, Bool *err, FILE *f ); +Prt_getTxtLn( Str line, Bool *err, FILE *f, int timeoutSeconds ); /* Write text line to f. Escape "." at the beginning with another ".". diff -r 7400a8e9d5ba -r 8b9366fc1361 src/server.c --- a/src/server.c Sat Sep 23 11:37:01 2000 +0100 +++ b/src/server.c Sat Sep 23 11:40:35 2000 +0100 @@ -1,7 +1,7 @@ /* server.c - $Id: server.c 183 2000-07-25 12:14:54Z bears $ + $Id: server.c 217 2000-09-23 10:40:35Z enz $ */ #if HAVE_CONFIG_H @@ -246,7 +246,7 @@ /* Special case - no timeout. */ if ( timeoutSeconds == 0 ) { - r = Prt_getLn( line, stdin ); + r = Prt_getLn( line, stdin, -1 ); return ( r ) ? 1 : -1; } @@ -259,7 +259,7 @@ } if ( alarm( ( unsigned int ) timeoutSeconds ) != 0 ) Log_err( "server.c:waitCmdLn: Alarm was already set." ); - r = Prt_getLn( line, stdin ); + r = Prt_getLn( line, stdin, -1 ); alarm( 0 ); installSignalHandler( SIGALRM, oldHandler ); if ( server.readAlarmFlag ) @@ -272,7 +272,7 @@ static Bool getTxtLn( Str line, Bool *err ) { - return Prt_getTxtLn( line, err, stdin ); + return Prt_getTxtLn( line, err, stdin, -1 ); } static Bool