comparison src/server.c @ 49:5ecb646acf97 noffle

[svn] Article numbering bug fixes
author bears
date Sat, 06 May 2000 17:56:50 +0100
parents 32ba1198c6fa
children 125d79c9e586
comparison
equal deleted inserted replaced
48:21d3102dbc37 49:5ecb646acf97
1 /* 1 /*
2 server.c 2 server.c
3 3
4 $Id: server.c 51 2000-05-05 23:49:38Z uh1763 $ 4 $Id: server.c 55 2000-05-06 16:56:50Z bears $
5 */ 5 */
6 6
7 #if HAVE_CONFIG_H 7 #if HAVE_CONFIG_H
8 #include <config.h> 8 #include <config.h>
9 #endif 9 #endif
30 #include "itemlist.h" 30 #include "itemlist.h"
31 #include "lock.h" 31 #include "lock.h"
32 #include "log.h" 32 #include "log.h"
33 #include "online.h" 33 #include "online.h"
34 #include "outgoing.h" 34 #include "outgoing.h"
35 #include "over.h"
35 #include "post.h" 36 #include "post.h"
36 #include "protocol.h" 37 #include "protocol.h"
37 #include "pseudo.h" 38 #include "pseudo.h"
38 #include "request.h" 39 #include "request.h"
39 #include "util.h" 40 #include "util.h"
222 Fetch_postArts(); 223 Fetch_postArts();
223 Fetch_close(); 224 Fetch_close();
224 } 225 }
225 } 226 }
226 227
228 static Bool
229 needsPseudoGenInfo( const char *grp )
230 {
231 return ! ( Grp_local( grp )
232 || Fetchlist_contains( grp )
233 || Online_true() );
234 }
235
227 static void 236 static void
228 readCont( const char *name ) 237 readCont( const char *name )
229 { 238 {
230 Fetchlist_read(); 239 Fetchlist_read();
231 Cont_read( name ); 240 Cont_read( name );
232 if ( ! Grp_local ( name ) 241 if ( needsPseudoGenInfo( name ) )
233 && ! Fetchlist_contains( name )
234 && ! Online_true() )
235 { 242 {
236 Pseudo_appGeneralInfo(); 243 Pseudo_appGeneralInfo();
237 Grp_setFirstLast( name, Cont_first(), Cont_last() ); 244 /* This adds the pseudo message to the overview contents
245 but NOT to the group info. If an article gets added,
246 the group info will get updated then from the
247 contents, so the article number will be preserved.
248 Otherwise it will be lost when the content is discarded. */
238 } 249 }
239 } 250 }
240 251
241 static void 252 static void
242 changeToGrp( const char *grp ) 253 changeToGrp( const char *grp )
641 } 652 }
642 653
643 static void 654 static void
644 printActive( Str result, const char *grp ) 655 printActive( Str result, const char *grp )
645 { 656 {
657 int last;
658
659 /* If there will be a pseudo gen info message waiting when we join
660 this group, fiddle the group numbers to show it. */
661 last = Grp_last( grp );
662 if ( needsPseudoGenInfo( grp ) )
663 last++;
664
646 snprintf( result, MAXCHAR, "%s %d %d %c", 665 snprintf( result, MAXCHAR, "%s %d %d %c",
647 grp, Grp_last( grp ), Grp_first( grp ), Grp_postAllow( grp ) ); 666 grp, last, Grp_first( grp ), Grp_postAllow( grp ) );
648 } 667 }
649 668
650 static void 669 static void
651 doListActive( const char *pat ) 670 doListActive( const char *pat )
652 { 671 {
672 /* We need to read the fetchlist so we know whether a pseudo
673 gen info article needs to be faked when printing the group
674 last. */
675 Fetchlist_read();
653 printGroups( pat, &printActive ); 676 printGroups( pat, &printActive );
654 } 677 }
655 678
656 static void 679 static void
657 printNewsgrp( Str result, const char *grp ) 680 printNewsgrp( Str result, const char *grp )
1208 for ( i = *first; i <= *last; ++i ) 1231 for ( i = *first; i <= *last; ++i )
1209 if ( Cont_validNumb( i ) ) 1232 if ( Cont_validNumb( i ) )
1210 ++(*numb); 1233 ++(*numb);
1211 } 1234 }
1212 1235
1236 /*
1237 Note this only handles a subset of headers. But they are all
1238 the headers any newsreader should need to work properly.
1239
1240 That last sentence will at some stage be proved wrong.
1241 */
1213 static Bool 1242 static Bool
1214 doXhdr( char *arg, const Cmd *cmd ) 1243 doXhdr( char *arg, const Cmd *cmd )
1215 { 1244 {
1216 int first, last, i, n, numb; 1245 int first, last, i, n, numb;
1217 enum { SUBJ, FROM, DATE, MSG_ID, REF, BYTES, LINES } what; 1246 enum { SUBJ, FROM, DATE, MSG_ID, REF, BYTES, LINES, XREF } what;
1218 const char *p; 1247 const char *p, *msgId;
1219 const Over *ov; 1248 const Over *ov;
1220 Str whatStr; 1249 Str whatStr;
1221 1250
1222 if ( ! testGrpSelected() ) 1251 if ( ! testGrpSelected() )
1223 return TRUE; 1252 return TRUE;
1239 what = REF; 1268 what = REF;
1240 else if ( strcmp( whatStr, "bytes" ) == 0 ) 1269 else if ( strcmp( whatStr, "bytes" ) == 0 )
1241 what = BYTES; 1270 what = BYTES;
1242 else if ( strcmp( whatStr, "lines" ) == 0 ) 1271 else if ( strcmp( whatStr, "lines" ) == 0 )
1243 what = LINES; 1272 what = LINES;
1273 else if ( strcmp( whatStr, "xref" ) == 0 )
1274 what = XREF;
1244 else 1275 else
1245 { 1276 {
1246 putStat( STAT_HEAD_FOLLOWS, "Unknown header (empty list follows)" ); 1277 putStat( STAT_HEAD_FOLLOWS, "Unknown header (empty list follows)" );
1247 putEndOfTxt(); 1278 putEndOfTxt();
1248 return TRUE; 1279 return TRUE;
1249 } 1280 }
1250 p = Utl_restOfLn( arg, 1 ); 1281 p = Utl_restOfLn( arg, 1 );
1251 parseRange( p, &first, &last, &numb ); 1282 if ( p[ 0 ] == '<' )
1283 {
1284 first = last = Cont_find( p );
1285 if ( first < 0 )
1286 numb = 0;
1287 }
1288 else
1289 parseRange( p, &first, &last, &numb );
1252 if ( numb == 0 ) 1290 if ( numb == 0 )
1253 putStat( STAT_NO_ART_SELECTED, "No articles selected" ); 1291 putStat( STAT_NO_ART_SELECTED, "No articles selected" );
1254 else 1292 else
1255 { 1293 {
1256 putStat( STAT_HEAD_FOLLOWS, "%s header %lu-%lu", 1294 putStat( STAT_HEAD_FOLLOWS, "%s header %lu-%lu",
1280 putTxtLn( "%lu %d", n, Ov_bytes( ov ) ); 1318 putTxtLn( "%lu %d", n, Ov_bytes( ov ) );
1281 break; 1319 break;
1282 case LINES: 1320 case LINES:
1283 putTxtLn( "%lu %d", n, Ov_lines( ov ) ); 1321 putTxtLn( "%lu %d", n, Ov_lines( ov ) );
1284 break; 1322 break;
1323 case XREF:
1324 msgId = Ov_msgId( ov );
1325 if ( Pseudo_isGeneralInfo( msgId ) )
1326 putTxtLn( "%lu %s:%lu", n, serv.grp, n );
1327 else
1328 putTxtLn( "%lu %s", n, Db_xref( msgId ) );
1329 break;
1285 default: 1330 default:
1286 ASSERT( FALSE ); 1331 ASSERT( FALSE );
1287 } 1332 }
1288 } 1333 }
1289 putEndOfTxt(); 1334 putEndOfTxt();
1403 1448
1404 if ( ! testGrpSelected() ) 1449 if ( ! testGrpSelected() )
1405 return TRUE; 1450 return TRUE;
1406 parseRange( arg, &first, &last, &n ); 1451 parseRange( arg, &first, &last, &n );
1407 if ( n == 0 ) 1452 if ( n == 0 )
1408 putStat( STAT_NO_ART_SELECTED, "No articles selected" ); 1453 first = last = serv.artPtr;
1409 else 1454 putStat( STAT_OVERS_FOLLOW, "Overview %ld-%ld", first, last );
1410 { 1455 for ( i = first; i <= last; ++i )
1411 putStat( STAT_OVERS_FOLLOW, "Overview %ld-%ld", first, last ); 1456 if ( ( ov = Cont_get( i ) ) )
1412 for ( i = first; i <= last; ++i ) 1457 putTxtLn( "%lu\t%s\t%s\t%s\t%s\t%s\t%d\t%d\t",
1413 if ( ( ov = Cont_get( i ) ) ) 1458 Ov_numb( ov ), Ov_subj( ov ), Ov_from( ov ),
1414 putTxtLn( "%lu\t%s\t%s\t%s\t%s\t%s\t%d\t%d\t", 1459 Ov_date( ov ), Ov_msgId( ov ), Ov_ref( ov ),
1415 Ov_numb( ov ), Ov_subj( ov ), Ov_from( ov ), 1460 Ov_bytes( ov ), Ov_lines( ov ) );
1416 Ov_date( ov ), Ov_msgId( ov ), Ov_ref( ov ), 1461 putEndOfTxt();
1417 Ov_bytes( ov ), Ov_lines( ov ) );
1418 putEndOfTxt();
1419 }
1420 return TRUE; 1462 return TRUE;
1421 } 1463 }
1422 1464
1423 static void 1465 static void
1424 putFatal( const char *fmt, ... ) 1466 putFatal( const char *fmt, ... )