Mercurial > noffle
diff server.c @ 26:526a4c34ee2e noffle
[svn] Applied patch from Jim Hague: support for local groups / new command
line options --create and --cancel.
author | enz |
---|---|
date | Sat, 29 Apr 2000 15:45:56 +0100 |
parents | 43631b72021f |
children | 792eb10e936d |
line wrap: on
line diff
--- a/server.c Sat Apr 29 14:37:59 2000 +0100 +++ b/server.c Sat Apr 29 15:45:56 2000 +0100 @@ -1,7 +1,7 @@ /* server.c - $Id: server.c 18 2000-04-15 10:09:20Z enz $ + $Id: server.c 32 2000-04-29 14:45:56Z enz $ */ #include "server.h" @@ -16,15 +16,18 @@ #include "common.h" #include "config.h" #include "content.h" +#include "control.h" #include "database.h" #include "dynamicstring.h" #include "fetch.h" #include "fetchlist.h" #include "group.h" +#include "itemlist.h" #include "lock.h" #include "log.h" #include "online.h" #include "outgoing.h" +#include "post.h" #include "protocol.h" #include "pseudo.h" #include "request.h" @@ -103,7 +106,7 @@ FetchMode mode; Grp_setLastAccess( serv.grp, time( NULL ) ); - if ( Cfg_autoSubscribe() && ! Online_true() ) + if ( ! Grp_local ( serv.grp ) && Cfg_autoSubscribe() && ! Online_true() ) { Fetchlist_read(); if ( ! Fetchlist_contains( serv.grp ) ) @@ -219,7 +222,9 @@ { Fetchlist_read(); Cont_read( name ); - if ( ! Fetchlist_contains( name ) && ! Online_true() ) + if ( ! Grp_local ( name ) + && ! Fetchlist_contains( name ) + && ! Online_true() ) { Pseudo_appGeneralInfo(); Grp_setFirstLast( name, Cont_first(), Cont_last() ); @@ -302,7 +307,7 @@ Str serv; findServ( msgId, serv ); - if ( strcmp( serv, "(unknown)" ) == 0 ) + if ( strcmp( serv, "(unknown)" ) == 0 || strcmp( serv, "(local)" ) == 0 ) return FALSE; if ( ! Client_connect( serv ) ) return FALSE; @@ -425,7 +430,9 @@ findServ( msgId, serv ); if ( Req_contains( serv, msgId ) ) putTxtBuf( Pseudo_alreadyMarkedBody() ); - else if ( strcmp( serv, "(unknown)" ) != 0 && Req_add( serv, msgId ) ) + else if ( strcmp( serv, "(unknown)" ) != 0 && + strcmp( serv, "(local)" ) != 0 && + Req_add( serv, msgId ) ) putTxtBuf( Pseudo_markedBody() ); else putTxtBuf( Pseudo_markingFailedBody() ); @@ -845,38 +852,133 @@ return TRUE; } +/* Cancel and return TRUE if need to send cancel message on to server. */ +static Bool +controlCancel( const char *cancelId ) +{ + return ( Ctrl_cancel( cancelId ) == CANCEL_NEEDS_MSG ); +} + /* - Get first group of the Newsgroups field content, which is - a comma separated list of groups. -*/ -static void -getFirstGrp( char *grpResult, const char *list ) + It's a control message. Currently we only know about 'cancel' + messages; others are passed on for outside groups, and logged + as ignored for local groups. + */ +static Bool +handleControl( ItemList *control, ItemList *newsgroups, + const char *msgId, const DynStr *art ) { - Str t; - const char *src = list; - char *dest = t; - while( TRUE ) + const char *grp; + const char *op; + Bool err = FALSE; + Bool localDone = FALSE; + + op = Itl_first( control ); + if ( op == NULL ) + { + Log_err( "Malformed control line." ); + return TRUE; + } + else if ( strcasecmp( op, "cancel" ) == 0 ) + { + if ( controlCancel( Itl_next( control ) ) ) + localDone = TRUE; + else + return err; + } + + /* Pass on for outside groups. */ + for( grp = Itl_first( newsgroups ); + grp != NULL; + grp = Itl_next( newsgroups ) ) + { + if ( Grp_exists( grp ) && ! Grp_local( grp ) ) + { + if ( ! Out_add( Grp_serv( grp ), msgId, art ) ) + { + Log_err( "Cannot add posted article to outgoing directory" ); + err = TRUE; + } + break; + } + } + + if ( localDone ) + return err; + + /* Log 'can't do' for internal groups. */ + for( grp = Itl_first( newsgroups ); + grp != NULL; + grp = Itl_next( newsgroups ) ) { - if ( *src == ',' ) - *dest = ' '; - else - *dest = *src; - if ( *src == '\0' ) - break; - ++src; - ++dest; + if ( Grp_exists( grp ) && Grp_local( grp ) ) + Log_inf( "Ignoring control '%s' for '%s'.", op, grp ); } - *grpResult = '\0'; - sscanf( t, "%s", grpResult ); + + return err; +} + +static Bool +postArticle( ItemList *newsgroups, const char *msgId, const DynStr *art ) +{ + const char *grp; + Bool err; + Bool oneLocal; + + err = oneLocal = FALSE; + + /* Run round first doing all local groups. */ + for( grp = Itl_first( newsgroups ); + grp != NULL; + grp = Itl_next( newsgroups ) ) + { + if ( Grp_local( grp ) ) + { + if ( ! oneLocal ) + { + if ( ! Post_open( DynStr_str( art ) ) ) + { + err = TRUE; + break; + } + else + oneLocal = TRUE; + } + + if ( ! Post_add( grp ) ) + err = TRUE; + } + } + if ( oneLocal ) + Post_close(); + + /* Now look for a valid external group. */ + for( grp = Itl_first( newsgroups ); + grp != NULL; + grp = Itl_next( newsgroups ) ) + { + if ( Grp_exists( grp ) && ! Grp_local( grp ) ) + { + if ( ! Out_add( Grp_serv( grp ), msgId, art ) ) + { + Log_err( "Cannot add posted article to outgoing directory" ); + err = TRUE; + } + break; + } + } + + return err; } static Bool doPost( char *arg, const Cmd *cmd ) { - Bool err, replyToFound, inHeader; + Bool err, replyToFound, dateFound, inHeader; DynStr *s; - Str line, field, val, msgId, from, grp; + Str line, field, val, msgId, from; const char* p; + ItemList * newsgroups, *control; /* Get article and make following changes to the header: @@ -895,8 +997,8 @@ s = new_DynStr( 10000 ); msgId[ 0 ] = '\0'; from[ 0 ] = '\0'; - grp[ 0 ] = '\0'; - replyToFound = FALSE; + newsgroups = control = NULL; + replyToFound = dateFound = FALSE; inHeader = TRUE; while ( getTxtLn( line, &err ) ) { @@ -918,6 +1020,7 @@ else if ( msgId[ 0 ] == '\0' ) { Prt_genMsgId( msgId, from, "NOFFLE" ); + Log_inf( "Adding missing Message-ID '%s'", msgId ); } else if ( ! Prt_isValidMsgId( msgId ) ) @@ -935,6 +1038,16 @@ DynStr_app( s, "Reply-To: " ); DynStr_appLn( s, from ); } + if ( ! dateFound ) + { + time_t t; + + time( &t ); + strftime( val, MAXCHAR, "%d %b %Y %H:%M:%S %Z", + localtime( &t ) ); + DynStr_app( s, "Date: " ); + DynStr_appLn( s, val ); + } DynStr_appLn( s, p ); } else if ( Prt_getField( field, val, p ) ) @@ -948,8 +1061,13 @@ } else if ( strcmp( field, "newsgroups" ) == 0 ) { - getFirstGrp( grp, val ); - Utl_toLower( grp ); + Utl_toLower( val ); + newsgroups = new_Itl ( val, " ," ); + DynStr_appLn( s, p ); + } + else if ( strcmp( field, "control" ) == 0 ) + { + control = new_Itl ( val, " " ); DynStr_appLn( s, p ); } else if ( strcmp( field, "reply-to" ) == 0 ) @@ -957,6 +1075,11 @@ replyToFound = TRUE; DynStr_appLn( s, p ); } + else if ( strcmp( field, "date" ) == 0 ) + { + dateFound = TRUE; + DynStr_appLn( s, p ); + } else if ( strcmp( field, "x-sender" ) == 0 ) { DynStr_app( s, "X-NOFFLE-X-Sender: " ); @@ -975,21 +1098,41 @@ Log_err( "Posted message has no body" ); if ( ! err ) { - if ( grp[ 0 ] == '\0' ) + if ( newsgroups == NULL || Itl_count( newsgroups ) == 0 ) { - Log_err( "Posted message has no Newsgroups header field" ); + Log_err( "Posted message has no valid Newsgroups header field" ); err = TRUE; } - else if ( ! Grp_exists( grp ) ) - { - Log_err( "Unknown group in Newsgroups header field" ); - err = TRUE; - } - else if ( ! Out_add( Grp_serv( grp ), msgId, s ) ) - { - Log_err( "Cannot add posted article to outgoing directory" ); - err = TRUE; - } + else + { + const char *grp; + Bool knownGrp = FALSE; + + /* Check at least one group is known. */ + for( grp = Itl_first( newsgroups ); + grp != NULL; + grp = Itl_next( newsgroups ) ) + { + if ( Grp_exists( grp ) ) + { + knownGrp = TRUE; + break; + } + } + + if ( ! knownGrp ) + { + + Log_err( "No known group in Newsgroups header field" ); + err = TRUE; + } + else + { + err = ( control == NULL ) + ? postArticle( newsgroups, msgId, s ) + : handleControl( control, newsgroups, msgId, s ); + } + } } if ( err ) putStat( STAT_POST_FAILED, "Posting failed" ); @@ -999,6 +1142,8 @@ if ( Online_true() ) postArts(); } + del_Itl( newsgroups ); + del_Itl( control ); del_DynStr( s ); return TRUE; }