Mercurial > noffle
comparison src/fetch.c @ 127:3c71e28c8eef noffle
[svn] Release-1-0 mergedocs/NOTES
| author | bears |
|---|---|
| date | Tue, 25 Jul 2000 13:14:54 +0100 |
| parents | 05f50c1761d9 |
| children | 6b2b93288caa |
comparison
equal
deleted
inserted
replaced
| 126:7c7a7c96d35b | 127:3c71e28c8eef |
|---|---|
| 1 /* | 1 /* |
| 2 fetch.c | 2 fetch.c |
| 3 | 3 |
| 4 $Id: fetch.c 174 2000-07-19 07:02:45Z enz $ | 4 $Id: fetch.c 183 2000-07-25 12:14:54Z 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 |
| 29 #include "content.h" | 29 #include "content.h" |
| 30 #include "dynamicstring.h" | 30 #include "dynamicstring.h" |
| 31 #include "fetchlist.h" | 31 #include "fetchlist.h" |
| 32 #include "request.h" | 32 #include "request.h" |
| 33 #include "group.h" | 33 #include "group.h" |
| 34 #include "lock.h" | |
| 34 #include "log.h" | 35 #include "log.h" |
| 35 #include "outgoing.h" | 36 #include "outgoing.h" |
| 36 #include "protocol.h" | 37 #include "protocol.h" |
| 37 #include "pseudo.h" | 38 #include "pseudo.h" |
| 38 #include "util.h" | 39 #include "util.h" |
| 39 #include "portable.h" | 40 #include "portable.h" |
| 40 | 41 |
| 42 #define MAX_ARTICLE_CMDS_QUEUED 20 | |
| 43 | |
| 41 struct Fetch | 44 struct Fetch |
| 42 { | 45 { |
| 43 Bool ready; | 46 Bool ready; |
| 44 Str serv; | 47 Str serv; |
| 45 } fetch = { FALSE, "" }; | 48 } fetch = { FALSE, "" }; |
| 61 { | 64 { |
| 62 time_t t; | 65 time_t t; |
| 63 Str file; | 66 Str file; |
| 64 | 67 |
| 65 ASSERT( fetch.ready ); | 68 ASSERT( fetch.ready ); |
| 66 snprintf( file, MAXCHAR, "%s/groupinfo.lastupdate", Cfg_spoolDir() ); | 69 snprintf( file, MAXCHAR, "%s/lastupdate.%s", |
| 70 Cfg_spoolDir(), fetch.serv ); | |
| 67 if ( ! Utl_getStamp( &t, file ) ) | 71 if ( ! Utl_getStamp( &t, file ) ) |
| 68 { | 72 { |
| 69 Log_err( "Cannot read %s. Please run noffle --query groups", file ); | 73 Log_err( "Cannot read %s. Please run noffle --query groups", file ); |
| 70 return; | 74 return; |
| 71 } | 75 } |
| 72 Log_inf( "Updating groupinfo" ); | 76 Log_inf( "Updating groupinfo" ); |
| 73 Client_getNewgrps( &t ); | 77 Client_getNewgrps( &t ); |
| 74 Utl_stamp( file ); | 78 } |
| 75 } | 79 |
| 76 | 80 /* Databases open on entry, closed on exit. */ |
| 77 void | 81 static void |
| 78 Fetch_getNewArts( const char *name, FetchMode mode ) | 82 fetchNewArts( const char *name, FetchMode mode ) |
| 79 { | 83 { |
| 80 int next, first, last; | 84 int next, first, last; |
| 81 | 85 |
| 82 if ( ! Client_changeToGrp( name ) ) | 86 if ( ! Client_changeToGrp( name ) ) |
| 83 { | 87 { |
| 84 Log_err( "Could not change to group %s", name ); | 88 Log_err( "Could not change to group %s", name ); |
| 85 return; | 89 Lock_closeDatabases(); |
| 86 } | 90 return; |
| 91 } | |
| 92 Client_rmtFirstLast( &first, &last ); | |
| 87 Cont_read( name ); | 93 Cont_read( name ); |
| 88 Client_rmtFirstLast( &first, &last ); | |
| 89 next = Grp_rmtNext( name ); | 94 next = Grp_rmtNext( name ); |
| 90 if ( next == GRP_RMT_NEXT_NOT_SUBSCRIBED ) | 95 if ( next == GRP_RMT_NEXT_NOT_SUBSCRIBED ) |
| 91 next = first; | 96 next = first; |
| 92 if ( next == last + 1 ) | 97 if ( next == last + 1 ) |
| 93 { | 98 { |
| 94 Log_inf( "No new articles in %s", name ); | 99 Log_inf( "No new articles in %s", name ); |
| 95 Cont_write(); | 100 Cont_write(); |
| 96 Grp_setFirstLast( name, Cont_first(), Cont_last() ); | 101 Grp_setFirstLast( name, Cont_first(), Cont_last() ); |
| 102 Lock_closeDatabases(); | |
| 97 return; | 103 return; |
| 98 } | 104 } |
| 99 if ( first == 0 && last == 0 ) | 105 if ( first == 0 && last == 0 ) |
| 100 { | 106 { |
| 101 Log_inf( "No articles in %s", name ); | 107 Log_inf( "No articles in %s", name ); |
| 102 Cont_write(); | 108 Cont_write(); |
| 103 Grp_setFirstLast( name, Cont_first(), Cont_last() ); | 109 Grp_setFirstLast( name, Cont_first(), Cont_last() ); |
| 110 Lock_closeDatabases(); | |
| 104 return; | 111 return; |
| 105 } | 112 } |
| 106 if ( next > last + 1 ) | 113 if ( next > last + 1 ) |
| 107 { | 114 { |
| 108 Log_err( "Article number inconsistent (%s rmt=%lu-%lu, next=%lu)", | 115 Log_err( "Article number inconsistent (%s rmt=%lu-%lu, next=%lu)", |
| 122 Log_ntc( "Cutting number of overviews to %lu", Cfg_maxFetch() ); | 129 Log_ntc( "Cutting number of overviews to %lu", Cfg_maxFetch() ); |
| 123 first = last - Cfg_maxFetch() + 1; | 130 first = last - Cfg_maxFetch() + 1; |
| 124 } | 131 } |
| 125 Log_inf( "Getting remote overviews %lu-%lu for group %s", | 132 Log_inf( "Getting remote overviews %lu-%lu for group %s", |
| 126 first, last, name ); | 133 first, last, name ); |
| 127 Client_getOver( first, last, mode ); | 134 Lock_closeDatabases(); |
| 128 Cont_write(); | 135 Client_getOver( name, first, last, mode ); |
| 129 Grp_setFirstLast( name, Cont_first(), Cont_last() ); | 136 } |
| 137 | |
| 138 void | |
| 139 Fetch_getNewArts( const char *name, FetchMode mode ) | |
| 140 { | |
| 141 if ( ! Lock_openDatabases() ) | |
| 142 { | |
| 143 Log_err( "Could not open message base" ); | |
| 144 return; | |
| 145 } | |
| 146 fetchNewArts( name, mode ); | |
| 130 } | 147 } |
| 131 | 148 |
| 132 void | 149 void |
| 133 Fetch_updateGrps( void ) | 150 Fetch_updateGrps( void ) |
| 134 { | 151 { |
| 135 FetchMode mode; | 152 FetchMode mode; |
| 136 int i, size; | 153 int i, size; |
| 137 const char* name; | 154 const char *name; |
| 138 | 155 |
| 139 ASSERT( fetch.ready ); | 156 ASSERT( fetch.ready ); |
| 157 if ( ! Lock_openDatabases() ) | |
| 158 { | |
| 159 Log_err( "Could not open message base" ); | |
| 160 return; | |
| 161 } | |
| 140 Fetchlist_read(); | 162 Fetchlist_read(); |
| 141 size = Fetchlist_size(); | 163 size = Fetchlist_size(); |
| 142 for ( i = 0; i < size; ++i ) | 164 for ( i = 0; i < size; ++i ) |
| 143 { | 165 { |
| 144 Fetchlist_element( &name, &mode, i ); | 166 Fetchlist_element( &name, &mode, i ); |
| 145 if ( strcmp( Grp_server( name ), fetch.serv ) == 0 ) | 167 if ( strcmp( Grp_server( name ), fetch.serv ) == 0 ) |
| 146 Fetch_getNewArts( name, mode ); | 168 { |
| 147 } | 169 fetchNewArts( name, mode ); |
| 170 if ( ! Lock_openDatabases() ) | |
| 171 { | |
| 172 Log_err( "Could not open message base" ); | |
| 173 return; | |
| 174 } | |
| 175 } | |
| 176 } | |
| 177 Lock_closeDatabases(); | |
| 178 } | |
| 179 | |
| 180 static void | |
| 181 fetchMessageList( const char *list, int *artcnt, int artmax ) | |
| 182 { | |
| 183 const char *p; | |
| 184 Str msgId; | |
| 185 | |
| 186 ASSERT( Lock_gotLock() ); | |
| 187 Client_retrieveArtList( list, artcnt, artmax ); | |
| 188 p = list; | |
| 189 while ( ( p = Utl_getLn( msgId, p ) ) ) | |
| 190 Req_remove( fetch.serv, msgId ); | |
| 148 } | 191 } |
| 149 | 192 |
| 150 void | 193 void |
| 151 Fetch_getReq_( void ) | 194 Fetch_getReq_( void ) |
| 152 { | 195 { |
| 153 Str msgId; | 196 Str msgId; |
| 154 DynStr *list; | 197 DynStr *list; |
| 198 DynStr *fetchList; | |
| 155 const char *p; | 199 const char *p; |
| 156 int count = 0, artcnt = 0, artmax = 0; | 200 int count = 0, artcnt = 0, artmax = 0; |
| 157 | 201 |
| 158 ASSERT( fetch.ready ); | 202 ASSERT( fetch.ready ); |
| 159 Log_dbg( "Retrieving articles marked for download" ); | 203 Log_dbg( "Retrieving articles marked for download" ); |
| 160 list = new_DynStr( 10000 ); | 204 list = new_DynStr( 10000 ); |
| 161 if ( Req_first( fetch.serv, msgId ) ) do { artmax++; } while ( Req_next( msgId ) ); | 205 fetchList = new_DynStr( 1000 ); |
| 162 Log_inf( "%d TOTAL messages to download", artmax); | 206 if ( list == NULL || fetchList == NULL ) |
| 207 { | |
| 208 if ( list != NULL ) | |
| 209 del_DynStr( list ); | |
| 210 Log_err( "Out of memory in Fetch_get_Req_"); | |
| 211 return; | |
| 212 } | |
| 213 | |
| 214 /* | |
| 215 * Get all waiting message IDs for this server. We copy into a master | |
| 216 * list as the requests file will be closed and re-opened during the | |
| 217 * fetch and the position therein will be lost. | |
| 218 */ | |
| 219 if ( ! Lock_openDatabases() ) | |
| 220 { | |
| 221 Log_err( "Could not open message base" ); | |
| 222 return; | |
| 223 } | |
| 224 | |
| 163 if ( Req_first( fetch.serv, msgId ) ) | 225 if ( Req_first( fetch.serv, msgId ) ) |
| 226 { | |
| 164 do | 227 do |
| 165 { | 228 { |
| 166 DynStr_appLn( list, msgId ); | 229 DynStr_appLn( list, msgId ); |
| 167 if ( ++count % 20 == 0 ) /* Send max. 20 ARTICLE cmds at once */ | 230 artmax++; |
| 168 { | |
| 169 p = DynStr_str( list ); | |
| 170 Client_retrieveArtList( p, &artcnt, artmax ); | |
| 171 while ( ( p = Utl_getLn( msgId, p ) ) ) | |
| 172 Req_remove( fetch.serv, msgId ); | |
| 173 DynStr_clear( list ); | |
| 174 } | |
| 175 } | 231 } |
| 176 while ( Req_next( msgId ) ); | 232 while ( Req_next( msgId ) ); |
| 233 Log_inf( "%d TOTAL messages to download", artmax); | |
| 234 } | |
| 235 | |
| 236 /* Retrieve in groups of up to size MAX_ARTICLE_CMDS_QUEUED. */ | |
| 177 p = DynStr_str( list ); | 237 p = DynStr_str( list ); |
| 178 Client_retrieveArtList( p, &artcnt, artmax ); | 238 while ( ( p = Utl_getLn( msgId, p ) ) != NULL ) |
| 179 while ( ( p = Utl_getLn( msgId, p ) ) ) | 239 { |
| 180 Req_remove( fetch.serv, msgId ); | 240 DynStr_appLn( fetchList, msgId ); |
| 241 if ( ++count % MAX_ARTICLE_CMDS_QUEUED == 0 ) | |
| 242 { | |
| 243 fetchMessageList( DynStr_str( fetchList ), &artcnt, artmax ); | |
| 244 DynStr_clear( fetchList ); | |
| 245 } | |
| 246 } | |
| 247 fetchMessageList( DynStr_str( fetchList ), &artcnt, artmax ); | |
| 248 | |
| 249 del_DynStr( fetchList ); | |
| 181 del_DynStr( list ); | 250 del_DynStr( list ); |
| 251 Lock_closeDatabases(); | |
| 182 } | 252 } |
| 183 | 253 |
| 184 static void | 254 static void |
| 185 returnArticleToSender( const char *sender, const char *reason, | 255 returnArticleToSender( const char *sender, const char *reason, |
| 186 const char *article ) | 256 const char *article ) |
| 254 } | 324 } |
| 255 | 325 |
| 256 Bool | 326 Bool |
| 257 Fetch_init( const char *serv ) | 327 Fetch_init( const char *serv ) |
| 258 { | 328 { |
| 329 Lock_closeDatabases(); | |
| 259 if ( ! connectToServ( serv ) ) | 330 if ( ! connectToServ( serv ) ) |
| 260 return FALSE; | 331 return FALSE; |
| 261 Utl_cpyStr( fetch.serv, serv ); | 332 Utl_cpyStr( fetch.serv, serv ); |
| 262 fetch.ready = TRUE; | 333 fetch.ready = TRUE; |
| 263 return TRUE; | 334 return TRUE; |
| 267 Fetch_close() | 338 Fetch_close() |
| 268 { | 339 { |
| 269 Client_disconnect(); | 340 Client_disconnect(); |
| 270 fetch.ready = FALSE; | 341 fetch.ready = FALSE; |
| 271 Log_inf( "Fetch from '%s' finished", fetch.serv ); | 342 Log_inf( "Fetch from '%s' finished", fetch.serv ); |
| 272 } | 343 Lock_openDatabases(); |
| 344 } |
