Mercurial > noffle
changeset 149:bfeea2bc09b6 noffle
[svn] Output to buffer, release lock and then send output.
author | bears |
---|---|
date | Thu, 26 Oct 2000 22:13:28 +0100 |
parents | b226cebd6a84 |
children | 1c7303c71f66 |
files | src/server.c |
diffstat | 1 files changed, 48 insertions(+), 136 deletions(-) [+] |
line wrap: on
line diff
--- a/src/server.c Sun Oct 15 18:30:19 2000 +0100 +++ b/src/server.c Thu Oct 26 22:13:28 2000 +0100 @@ -1,7 +1,7 @@ /* server.c - $Id: server.c 217 2000-09-23 10:40:35Z enz $ + $Id: server.c 225 2000-10-26 21:13:28Z bears $ */ #if HAVE_CONFIG_H @@ -55,8 +55,9 @@ time_t lastServerOpen; int artPtr; Str grp; /* selected group, "" if none */ - Bool readAlarmFlag; -} server = { FALSE, 0L, 0, "", FALSE }; + DynStr *reply; + Bool eotAfterReply; +} server = { FALSE, 0L, 0, "", NULL, FALSE }; typedef struct Cmd { @@ -172,8 +173,8 @@ vsnprintf( s, MAXCHAR, fmt, ap ); va_end( ap ); snprintf( line, MAXCHAR, "%u %s", stat, s ); + DynStr_appLn( server.reply, line ); Log_dbg( "[S] %s", line ); - printf( "%s\r\n", line ); } static void @@ -185,20 +186,20 @@ va_start( ap, fmt ); vsnprintf( line, MAXCHAR, fmt, ap ); va_end( ap ); - Prt_putTxtLn( line, stdout ); + DynStr_appLn( server.reply, line ); } static void putTxtBuf( const char *buf ) { if ( buf ) - Prt_putTxtBuf( buf, stdout ); + DynStr_app( server.reply, buf ); } static void putEndOfTxt( void ) { - Prt_putEndOfTxt( stdout ); + server.eotAfterReply = TRUE; } static void @@ -208,65 +209,21 @@ } static void -readAlarm( int sig ) -{ - UNUSED( sig ); - - server.readAlarmFlag = TRUE; - return; -} - -static sig_t -installSignalHandler( int sig, sig_t handler ) +initOutput( void ) { - struct sigaction act, oldAct; - - act.sa_handler = handler; - sigemptyset( &act.sa_mask ); - act.sa_flags = 0; - if ( sig != SIGALRM ) - act.sa_flags |= SA_RESTART; - if ( sigaction( sig, &act, &oldAct ) < 0 ) - return SIG_ERR; - return oldAct.sa_handler; + server.reply = new_DynStr( 100 ); + server.eotAfterReply = FALSE; } -/* - * Returns: < 0 on error, 0 on timeout, > 0 on success. - * If timeout is zero, wait indefinitely. - */ -static int -waitCmdLn( Str line, int timeoutSeconds ) +static void +sendOutput( void ) { - sig_t oldHandler; - int r; - - ASSERT( timeoutSeconds >= 0 ); - - /* Special case - no timeout. */ - if ( timeoutSeconds == 0 ) - { - r = Prt_getLn( line, stdin, -1 ); - return ( r ) ? 1 : -1; - } - - server.readAlarmFlag = FALSE; - oldHandler = installSignalHandler( SIGALRM, readAlarm ); - if ( oldHandler == SIG_ERR ) - { - Log_err( "client.c:connectWithTimeout: signal failed." ); - return -1; - } - if ( alarm( ( unsigned int ) timeoutSeconds ) != 0 ) - Log_err( "server.c:waitCmdLn: Alarm was already set." ); - r = Prt_getLn( line, stdin, -1 ); - alarm( 0 ); - installSignalHandler( SIGALRM, oldHandler ); - if ( server.readAlarmFlag ) - return 0; - else if ( r ) - return 1; - return -1; + Prt_putTxtBuf( DynStr_str( server.reply ), stdout ); + if ( server.eotAfterReply ) + Prt_putEndOfTxt( stdout ); + fflush( stdout ); + Log_dbg( "[S FLUSH]" ); + del_DynStr( server.reply ); } static Bool @@ -699,14 +656,11 @@ const char *g; putStat( STAT_GRPS_FOLLOW, "Groups" ); - fflush( stdout ); - Log_dbg( "[S FLUSH]" ); if ( Grp_exists( pat ) ) { (*printProc)( line, pat ); - if ( ! Prt_putTxtLn( line, stdout ) ) - Log_err( "Writing to stdout failed." ); - } + putTxtLn( line ); + } else { if ( Grp_firstGrp( &g ) ) @@ -714,8 +668,7 @@ if ( Wld_match( g, pat ) ) { (*printProc)( line, g ); - if ( ! Prt_putTxtLn( line, stdout ) ) - Log_err( "Writing to stdout failed." ); + putTxtLn( line ); } while ( Grp_nextGrp( &g ) ); } @@ -844,14 +797,6 @@ else { changeToGrp( arg ); - - /* - * The output may take some time, so release the lock - * while outputting (all the required data is in RAM - * at this point). - */ - closeServer(); - first = Cont_first(); last = Cont_last(); putStat( STAT_GRP_SELECTED, "Article list" ); @@ -1015,22 +960,20 @@ UNUSED(arg); UNUSED(cmd); - putStat( STAT_SEND_ART, "Continue (end with period)" ); - fflush( stdout ); - Log_dbg( "[S FLUSH]" ); - s = new_DynStr( 10000 ); - - /* * The article may take some time coming in, so release the * lock while collecting it. */ + putStat( STAT_SEND_ART, "Continue (end with period)" ); + sendOutput(); closeServer(); + s = new_DynStr( 10000 ); err = FALSE; while ( ! err && getTxtLn( line, &err ) ) DynStr_appLn( s, line ); + initOutput(); if ( ! initServer() ) { del_DynStr( s ); @@ -1038,7 +981,7 @@ } if ( ! err - && Post_open( DynStr_str( s ) ) + && Post_open( DynStr_str( s ), 0 ) && Post_post() ) { putStat( STAT_POST_OK, "Message posted" ); @@ -1350,15 +1293,6 @@ if ( ! testGrpSelected() ) return TRUE; - Grp_setLastAccess( server.grp, time( NULL ) ); - - /* - * All the info we require is now in RAM, and we may generate - * lots of output (consider XOVER 2-3999), so release the lock - * while responding. - */ - closeServer(); - parseRange( arg, &first, &last, &n ); if ( n == 0 ) first = last = server.artPtr; @@ -1370,6 +1304,7 @@ Ov_date( ov ), Ov_msgId( ov ), Ov_ref( ov ), Ov_bytes( ov ), Ov_lines( ov ) ); putEndOfTxt(); + Grp_setLastAccess( server.grp, time( NULL ) ); return TRUE; } @@ -1384,8 +1319,6 @@ va_end( ap ); Log_err( s ); putStat( STAT_PROGRAM_FAULT, "%s", s ); - fflush( stdout ); - Log_dbg( "[S FLUSH]" ); } /* Parse line, execute command and return FALSE, if it was the quit command. */ @@ -1406,24 +1339,20 @@ if ( strcmp( c->name, s ) == 0 ) { ret = c->cmdProc( Utl_stripWhiteSpace( arg ), c ); - fflush( stdout ); - Log_dbg( "[S FLUSH]" ); return ret; } } putStat( STAT_NO_SUCH_CMD, "Command not recognized" ); - fflush( stdout ); - Log_dbg( "[S FLUSH]" ); return TRUE; } static void putWelcome( void ) { + initOutput(); putStat( STAT_READY_POST_ALLOW, "NNTP server NOFFLE %s", Cfg_version() ); - fflush( stdout ); - Log_dbg( "[S FLUSH]" ); + sendOutput(); } static Bool @@ -1449,54 +1378,37 @@ Server_run( void ) { Bool done; - int r; Str line; putWelcome(); done = FALSE; while ( ! done ) { - /* - * If we've had the lock for more than 2 seconds, - * force it to be released. Otherwise, if we have - * the lock but have had it for < 2 secs, - * wait for a command line for a maximum - * of 2 seconds. This is all an attempt at striking a - * balance between efficient processing of commands - * and hogging the lock. - */ - if ( server.running ) + if ( Prt_getLn( line, stdin, -1 ) ) { - time_t now; + initOutput(); - now = time( NULL ); - if ( difftime( now, server.lastServerOpen ) > 2.0 ) + if ( ! initServer() ) + { + putFatal( "Cannot init server" ); + done = TRUE; + } + else + { + if ( ! parseAndExecute( line ) ) + done = TRUE; + } + + if ( server.running ) closeServer(); - } - r = waitCmdLn( line, ( server.running ) ? 2 : 0 ); - if ( r < 0 ) + + sendOutput(); + } + else { Log_inf( "Client disconnected. Terminating." ); done = TRUE; } - else if ( r == 0 ) - { - if ( server.running ) - closeServer(); - } - else /* ( r > 0 ) */ - { - if ( ! server.running ) - { - if ( ! initServer() ) - { - putFatal( "Cannot init server" ); - done = TRUE; - } - } - if ( ! parseAndExecute( line ) ) - done = TRUE; - } } if ( server.running ) closeServer();