comparison src/util.c @ 259:b660fadc1814 noffle

[svn] * src/server.c,src/util.c,src/util.h: Recognise GMT/UTC on NNTP NEWGROUPS. Do small reorg of some of the timezone sensitive code, and introduce use of timegm(). An implementation is provided for systems without timegm().
author bears
date Wed, 26 Jun 2002 14:30:26 +0100
parents 4e69e9b722ae
children 3477050e8d10
comparison
equal deleted inserted replaced
258:ebd9c98bbc7f 259:b660fadc1814
1 /* 1 /*
2 util.c 2 util.c
3 3
4 $Id: util.c 375 2002-03-15 10:50:33Z bears $ 4 $Id: util.c 391 2002-06-26 13:30:26Z 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
292 "Sat", NULL }; 292 "Sat", NULL };
293 static const char *MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", 293 static const char *MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
294 "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; 294 "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
295 295
296 /* 296 /*
297 * Calculate the difference between local time and GMT. This is INN's 297 * Calculate the difference between local time and GMT at GMT time t.
298 * 'always-works' method. It assumes the time differences is < 24hrs. 298 *
299 * Sounds reasonable to me. It also assumes it can ignore seconds. 299 * This is INN's 'always-works' method. It assumes the time differences
300 * Returns GMT - localtime minutes. It will also trash the localtime/ 300 * is < 24hrs. Sounds reasonable to me. It also assumes it can ignore seconds.
301 * Returns localtime - GMT seconds. It will also trash the localtime/
301 * gmtime/etc. static buffer. 302 * gmtime/etc. static buffer.
302 */ 303 */
303 static int 304 static int
304 tzDiff( void ) 305 localTimeDiff( time_t t )
305 { 306 {
306 time_t now; 307 time_t now;
307 struct tm local, gmt, *tm; 308 struct tm local, gmt, *tm;
308 static time_t nextCalc = 0; 309 static time_t nextCalc = 0;
309 static int res = 0; 310 static int res = 0;
310 311
311 now = time( NULL ); 312 now = time( NULL );
312 if ( now < nextCalc ) 313 if ( now < nextCalc )
313 return res; 314 return res;
314 315
315 tm = localtime( &now ); 316 tm = localtime( &t );
316 if ( tm == NULL ) 317 if ( tm == NULL )
317 return 0; 318 return 0;
318 local = *tm; 319 local = *tm;
319 tm = gmtime( &now ); 320 tm = gmtime( &t );
320 if ( tm == NULL ) 321 if ( tm == NULL )
321 return 0; 322 return 0;
322 gmt = *tm; 323 gmt = *tm;
323 324
324 res = gmt.tm_yday - local.tm_yday; 325 res = local.tm_yday - gmt.tm_yday;
325 if ( res < -1 ) 326 if ( res < -1 )
326 res = -1; /* Year rollover? */ 327 res = -1; /* Year rollover? */
327 else if ( res > 1 ) 328 else if ( res > 1 )
328 res = 1; 329 res = 1;
329 330
330 res *= 24; 331 res *= 24;
331 res += gmt.tm_hour - local.tm_hour; 332 res += local.tm_hour - gmt.tm_hour;
332 res *= 60; 333 res *= 60;
333 res += gmt.tm_min - local.tm_min; 334 res += local.tm_min - gmt.tm_min;
335 res *= 60;
334 336
335 /* Need to recalc at start of next hour */ 337 /* Need to recalc at start of next hour */
336 nextCalc = now + ( 60 - local.tm_sec ) + 60 * ( 59 - local.tm_min ); 338 nextCalc = now + ( 60 - local.tm_sec ) + 60 * ( 59 - local.tm_min );
337 339
338 return res; 340 return res;
341 }
342
343 time_t
344 Utl_mktimeGMT( struct tm *t )
345 {
346 #if HAVE_TIMEGM
347 return timegm( t );
348 #else
349 /*
350 * Based on the portable implementation suggested in the glibc man page
351 * for timegm.
352 */
353 time_t ret;
354 char *tz;
355
356 tz = getenv("TZ");
357 setenv("TZ", "", 1);
358 tzset();
359 ret = mktime(t);
360 if (tz)
361 setenv("TZ", tz, 1);
362 else
363 unsetenv("TZ");
364 tzset();
365 return ret;
366 #endif
339 } 367 }
340 368
341 void 369 void
342 Utl_newsDate( time_t t, Str res ) 370 Utl_newsDate( time_t t, Str res )
343 { 371 {
344 struct tm *local; 372 struct tm *local;
345 long tzdiff, hoffset, moffset; 373 long tzdiff, hoffset, moffset;
346 374
347 tzdiff = - tzDiff(); 375 tzdiff = localTimeDiff( t ) / 60;
348 376
349 local = localtime( &t ); 377 local = localtime( &t );
350 if ( local == NULL ) 378 if ( local == NULL )
351 { 379 {
352 Utl_cpyStr( res, "** localtime failure **" ); 380 Utl_cpyStr( res, "** localtime failure **" );
461 489
462 /* Check for following junk */ 490 /* Check for following junk */
463 if ( *s != '\0' && ! isspace( *s ) ) 491 if ( *s != '\0' && ! isspace( *s ) )
464 return (time_t) -1; 492 return (time_t) -1;
465 493
466 res = mktime( &tm ); 494 res = Utl_mktimeGMT( &tm );
467 if ( res == (time_t) -1 ) 495 if ( res == (time_t) -1 )
468 return res; 496 return res;
469 497
470 if ( wday >= 0 && wday != tm.tm_wday ) 498 if ( wday >= 0 && wday != tm.tm_wday )
471 return (time_t) -1; 499 return (time_t) -1;
472
473 /* Remove local time diff from res to give time as if GMT */
474 res -= tzDiff() * 60;
475 500
476 /* And now adjust for tzoffset */ 501 /* And now adjust for tzoffset */
477 res -= tzoffset * 60; 502 res -= tzoffset * 60;
478 503
479 return res; 504 return res;