Mercurial > noffle
comparison src/content.c @ 223:ffb1848a39db noffle
[svn] * src/util.c: Improve (correct) error detection when updating
timestamp file.
* src/content.h, src/content.c: Return Boolean success/fail from
Cont_write. Also ensure cont.first isn't polluted in the event
of a failed update.
* src/client.c,src/control.c,src/fetch.c,src/noffle.c,src/post.c,
src/pseudo.c: If Cont_write fails, don't do actions that need it to
have worked. Typically, don't update first and last article numbers
in group database.
* src/server.c: If groupinfo.lastupdate is unreadable or corrupt,
spot this and report it and give an explicit error when processing
NNTP NEWGROUPS command.
author | bears |
---|---|
date | Sun, 09 Dec 2001 12:31:57 +0000 |
parents | d9f314014f7a |
children | c48d7e881a21 |
comparison
equal
deleted
inserted
replaced
222:bf290632d29e | 223:ffb1848a39db |
---|---|
1 /* | 1 /* |
2 content.c | 2 content.c |
3 | 3 |
4 $Id: content.c 338 2001-11-29 22:16:06Z bears $ | 4 $Id: content.c 342 2001-12-09 12:31:57Z 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 |
181 if ( cont.last < grpLast ) | 181 if ( cont.last < grpLast ) |
182 extendCont( grpLast - cont.first + 1 ); | 182 extendCont( grpLast - cont.first + 1 ); |
183 } | 183 } |
184 } | 184 } |
185 | 185 |
186 void | 186 Bool |
187 Cont_write( void ) | 187 Cont_write( void ) |
188 { | 188 { |
189 Bool anythingWritten; | 189 Bool anythingWritten; |
190 int i; | 190 int i; |
191 FILE *f; | 191 FILE *f; |
192 const Over *ov, *ov_next; | 192 const Over *ov, *ov_next; |
193 Str tmpfname; | 193 Str tmpfname; |
194 Bool writeErr; | 194 Bool writeErr; |
195 int first; | |
195 | 196 |
196 /* If nowt has changed, do nowt. */ | 197 /* If nowt has changed, do nowt. */ |
197 if ( ! cont.dirty ) | 198 if ( ! cont.dirty ) |
198 return; | 199 return TRUE; |
199 | 200 |
200 /* Save the overview to temporary file in same dir. */ | 201 /* Save the overview to temporary file in same dir. */ |
201 /* old tmpfnames will be expired at noffle.c:expireContents() */ | 202 /* old tmpfnames will be expired at noffle.c:expireContents() */ |
202 snprintf( tmpfname, MAXCHAR, "%s/overview/.#%d.%s", | 203 snprintf( tmpfname, MAXCHAR, "%s/overview/.#%d.%s", |
203 Cfg_spoolDir(), (int) getpid(), cont.name ); | 204 Cfg_spoolDir(), (int) getpid(), cont.name ); |
204 if ( ! ( f = fopen( tmpfname, "w" ) ) ) | 205 if ( ! ( f = fopen( tmpfname, "w" ) ) ) |
205 { | 206 { |
206 Log_err( "Could not open %s for writing", tmpfname ); | 207 Log_err( "Could not open %s for writing", tmpfname ); |
207 return; | 208 return FALSE; |
208 } | 209 } |
209 Log_dbg( LOG_DBG_NEWSBASE, "Writing %s (%lu)", tmpfname, cont.size ); | 210 Log_dbg( LOG_DBG_NEWSBASE, "Writing %s (%lu)", tmpfname, cont.size ); |
210 anythingWritten = FALSE; | 211 anythingWritten = FALSE; |
211 cont.first = -1; | 212 first = -1; |
212 writeErr = FALSE; | 213 writeErr = FALSE; |
213 | 214 |
214 for ( i = 0; i < cont.size; ++i ) | 215 for ( i = 0; i < cont.size; ++i ) |
215 { | 216 { |
216 ov = cont.elem[ i ]; | 217 ov = cont.elem[ i ]; |
230 */ | 231 */ |
231 if ( ! Pseudo_isGeneralInfo( Ov_msgId( ov ) ) | 232 if ( ! Pseudo_isGeneralInfo( Ov_msgId( ov ) ) |
232 || ( ov_next != NULL && | 233 || ( ov_next != NULL && |
233 Ov_numb( ov_next ) - Ov_numb( ov ) == 1 ) ) | 234 Ov_numb( ov_next ) - Ov_numb( ov ) == 1 ) ) |
234 { | 235 { |
235 anythingWritten = TRUE; | 236 anythingWritten = TRUE; |
236 if ( ! Ov_write( ov, f ) ) | 237 if ( ! Ov_write( ov, f ) ) |
237 { | 238 { |
238 Log_err( "Writing of overview line to %s failed: %s", | 239 Log_err( "Writing of overview line to %s failed: %s", |
239 tmpfname, strerror( errno ) ); | 240 tmpfname, strerror( errno ) ); |
240 writeErr = TRUE; | 241 writeErr = TRUE; |
241 break; | 242 break; |
242 } | 243 } |
243 else | 244 else |
244 { | 245 { |
245 if ( cont.first < 0 ) | 246 if ( first < 0 ) |
246 cont.first = cont.vecFirst + i; | 247 first = cont.vecFirst + i; |
247 } | 248 } |
248 } | 249 } |
249 } | 250 } |
250 } | 251 } |
251 if ( fclose( f ) != 0 ) | 252 if ( fclose( f ) != 0 ) |
253 Log_err( "Close of content file %s failed: %s", | 254 Log_err( "Close of content file %s failed: %s", |
254 tmpfname, strerror( errno ) ); | 255 tmpfname, strerror( errno ) ); |
255 writeErr = TRUE; | 256 writeErr = TRUE; |
256 } | 257 } |
257 | 258 |
259 if ( writeErr ) | |
260 { | |
261 /* Write error - leave everything as at present */ | |
262 return FALSE; | |
263 } | |
264 | |
258 /* | 265 /* |
259 If empty, remove the overview file and set set first to one | 266 If empty, remove the overview file and set first to one |
260 beyond last to flag said emptiness. | 267 beyond last to flag said emptiness. |
261 */ | 268 */ |
262 if ( ! anythingWritten ) | 269 if ( ! anythingWritten ) |
263 { | 270 { |
264 if ( unlink( tmpfname ) < 0 ) | 271 if ( unlink( tmpfname ) < 0 ) |
265 Log_err( "Unlink of %s failed: %s", tmpfname, strerror( errno ) ); | 272 Log_err( "Unlink of %s failed: %s", tmpfname, strerror( errno ) ); |
266 if ( unlink( cont.file ) < 0 ) | 273 if ( unlink( cont.file ) < 0 ) |
274 { | |
267 Log_err( "Unlink of %s failed: %s", cont.file, strerror( errno ) ); | 275 Log_err( "Unlink of %s failed: %s", cont.file, strerror( errno ) ); |
276 return FALSE; | |
277 } | |
268 else | 278 else |
269 { | 279 { |
270 cont.dirty = FALSE; | 280 cont.dirty = FALSE; |
271 cont.first = cont.last + 1; | 281 cont.first = cont.last + 1; |
272 } | 282 } |
273 } | 283 } |
274 else if ( ! writeErr ) | 284 else |
275 { | 285 { |
276 if ( rename( tmpfname, cont.file ) < 0 ) | 286 if ( rename( tmpfname, cont.file ) < 0 ) |
287 { | |
277 Log_err( "Rename of content file %s to %s failed: %s", | 288 Log_err( "Rename of content file %s to %s failed: %s", |
278 tmpfname, cont.file, strerror( errno ) ); | 289 tmpfname, cont.file, strerror( errno ) ); |
290 return FALSE; | |
291 } | |
279 else | 292 else |
293 { | |
294 ASSERT( first != -1 ); | |
280 cont.dirty = FALSE; | 295 cont.dirty = FALSE; |
281 } | 296 cont.first = first; |
297 } | |
298 } | |
299 | |
300 return TRUE; | |
282 } | 301 } |
283 | 302 |
284 const Over * | 303 const Over * |
285 Cont_get( int numb ) | 304 Cont_get( int numb ) |
286 { | 305 { |