comparison src/util.c @ 91:93cc929329eb noffle

[svn] Date output change and now date parsing
author bears
date Fri, 19 May 2000 16:12:45 +0100
parents bf8c97460fd7
children 2bedacfe1ba7
comparison
equal deleted inserted replaced
90:9cf0d605465a 91:93cc929329eb
1 /* 1 /*
2 util.c 2 util.c
3 3
4 $Id: util.c 99 2000-05-18 12:11:05Z bears $ 4 $Id: util.c 110 2000-05-19 15:12:45Z 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
23 #include <errno.h> 23 #include <errno.h>
24 #include <ctype.h> 24 #include <ctype.h>
25 #include <sys/types.h> 25 #include <sys/types.h>
26 #include <sys/stat.h> 26 #include <sys/stat.h>
27 #include <fcntl.h> 27 #include <fcntl.h>
28 #include <stdlib.h>
28 #include <unistd.h> 29 #include <unistd.h>
29 #include "configfile.h" 30 #include "configfile.h"
30 #include "log.h" 31 #include "log.h"
31 #include "wildmat.h" 32 #include "wildmat.h"
32 #include "portable.h" 33 #include "portable.h"
34
35 #if defined(UTIL_TEST)
36 #define Log_err printf
37 #define Log_dbg printf
38 #endif
33 39
34 static const char * 40 static const char *
35 nextWhiteSpace( const char *p ) 41 nextWhiteSpace( const char *p )
36 { 42 {
37 while ( *p && ! isspace( *p ) ) 43 while ( *p && ! isspace( *p ) )
252 } 258 }
253 fclose( f ); 259 fclose( f );
254 return TRUE; 260 return TRUE;
255 } 261 }
256 262
257 void 263 static const char *DOTW[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
258 Utl_rfc822Date( time_t t, Str res ) 264 "Sat", NULL };
259 { 265 static const char *MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
260 strftime( res, MAXCHAR,"%a, %d %b %Y %H:%M:%S %z", localtime( &t ) ); 266 "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
267
268 void
269 Utl_newsDate( time_t t, Str res )
270 {
271 struct tm local, localAsGmt;
272 time_t tlocalAsGmt;
273 int tzdiff, hoffset, moffset;
274
275 local = *localtime( &t );
276 memset( &localAsGmt, 0, sizeof( localAsGmt ) );
277 localAsGmt.tm_sec = local.tm_sec;
278 localAsGmt.tm_min = local.tm_min;
279 localAsGmt.tm_hour = local.tm_hour;
280 localAsGmt.tm_mday = local.tm_mday;
281 localAsGmt.tm_mon = local.tm_mon;
282 localAsGmt.tm_year = local.tm_year;
283 tlocalAsGmt = mktime( &localAsGmt );
284 tzdiff = (int) ( ( (long) difftime( tlocalAsGmt, t ) ) / 60 );
285 hoffset = tzdiff / 60;
286 moffset = tzdiff % 60;
287 if ( moffset < 0 ) moffset = -moffset;
288
289 sprintf( res, "%s, %d %s %4d %02d:%02d:%02d %+03d%02d",
290 DOTW[local.tm_wday], local.tm_mday,
291 MON[local.tm_mon], local.tm_year + 1900,
292 local.tm_hour, local.tm_min, local.tm_sec,
293 hoffset, moffset );
294 }
295
296 time_t
297 Utl_parseNewsDate( const char *s )
298 {
299 struct tm tm;
300 int wday, tzoffset, hoffset, moffset;
301 char *p;
302 time_t res;
303
304 memset( &tm, 0, sizeof( tm ) );
305 wday = -1;
306
307 s = nextNonWhiteSpace( s );
308
309 /* Is this the day number, or a weekday? */
310 if ( ! isdigit( *s ) )
311 {
312 if ( strlen( s ) < 4 )
313 return (time_t) -1;
314
315 for ( wday = 0; DOTW[ wday ] != NULL; wday++ )
316 if ( strncmp( DOTW[ wday ], s, 3 ) == 0 )
317 break;
318
319 if( DOTW[ wday ] == NULL || s[3] != ',' )
320 return (time_t) -1;
321
322 s += 4;
323 }
324
325 /* Get the day number */
326 tm.tm_mday = (int) strtol( s, &p, 10 );
327 if ( p == s )
328 return (time_t) -1;
329 s = p;
330
331 /* Look for month name */
332 s = nextNonWhiteSpace( s );
333 if ( strlen( s ) < 4 )
334 return (time_t) -1;
335 for ( tm.tm_mon = 0; MON[ tm.tm_mon ] != NULL; tm.tm_mon++ )
336 if ( strncmp( MON[ tm.tm_mon ], s, 3 ) == 0 )
337 break;
338
339 if ( MON[ tm.tm_mon ] == NULL )
340 return (time_t) -1;
341 s += 3;
342
343 /* Year next */
344 tm.tm_year = (int) strtol( s, &p, 10 );
345 if ( p == s || ( tm.tm_year >= 100 && tm.tm_year < 1900 ) )
346 return (time_t) -1;
347 if ( tm.tm_year >= 1900 )
348 tm.tm_year -= 1900;
349 s = p;
350
351 /* Hours */
352 tm.tm_hour = (int) strtol( s, &p, 10 );
353 if ( p == s || *p != ':' )
354 return (time_t) -1;
355 s = ++p;
356
357 /* Minutes */
358 tm.tm_min = (int) strtol( s, &p, 10 );
359 if ( p == s || ( *p != ':' && *p != ' ' ) )
360 return (time_t) -1;
361 s = p;
362
363 /* Seconds */
364 if ( *s == ':' )
365 {
366 s++;
367 tm.tm_sec = (int) strtol( s, &p, 10 );
368 if ( p == s )
369 return (time_t) -1;
370 s = p;
371 }
372
373 /* GMT/UT or timezone offset */
374 tzoffset = 0;
375 while ( isspace( *s ) )
376 s++;
377 if ( strncmp( s, "GMT", 3) == 0 )
378 s += 3;
379 else if ( strncmp( s, "UT", 2 ) == 0 )
380 s += 2;
381 else
382 {
383 tzoffset = (int) strtol( s, &p, 10 );
384 s = p;
385 }
386
387 /* Check for following junk */
388 if ( *s != '\0' && ! isspace( *s ) )
389 return (time_t) -1;
390
391 res = mktime( &tm );
392 if ( res == (time_t) -1 )
393 return res;
394
395 if ( wday >= 0 && wday != tm.tm_wday )
396 return (time_t) -1;
397
398 moffset = tzoffset % 100;
399 hoffset = tzoffset / 100;
400 res = res - ( ( hoffset * 60 + moffset ) * 60 );
401 return res;
261 } 402 }
262 403
263 void 404 void
264 Utl_allocAndCpy( char **dst, const char *src ) 405 Utl_allocAndCpy( char **dst, const char *src )
265 { 406 {
269 Log_err( "Cannot allocate string with length %lu", strlen( src ) ); 410 Log_err( "Cannot allocate string with length %lu", strlen( src ) );
270 exit( EXIT_FAILURE ); 411 exit( EXIT_FAILURE );
271 } 412 }
272 memcpy( *dst, src, (size_t)len + 1 ); 413 memcpy( *dst, src, (size_t)len + 1 );
273 } 414 }
415
416 #if defined(UTIL_TEST)
417
418 /* Test code borrowed from wildmat.c. Yep, still uses gets(). */
419 extern char *gets();
420
421 int
422 main()
423 {
424 Str line;
425 time_t t;
426
427 printf( "Util date tester. Enter date to test.\n" );
428 printf( "A blank line exits the program.\n" );
429
430 for ( ; ; )
431 {
432 printf( "\nEnter date: " );
433 (void) fflush( stdout );
434 if ( gets( line ) == NULL || line[0] == '\0' )
435 break;
436
437 t = Utl_parseNewsDate( line );
438 if ( t == (time_t) -1 )
439 printf( "Date parse failed\n" );
440 else
441 {
442 Utl_newsDate( t, line );
443 printf( "Utl_newsDate -> '%s'\nctime() -> '%s'\n",
444 line, ctime( &t ) );
445 }
446 }
447
448 exit(0);
449 /* NOTREACHED */
450 }
451 #endif