Mercurial > noffle
view src/util.c @ 109:2bedacfe1ba7 noffle
[svn] Fix header line reading buf
author | bears |
---|---|
date | Mon, 19 Jun 2000 22:56:12 +0100 |
parents | 93cc929329eb |
children | 3c71e28c8eef |
line wrap: on
line source
/* util.c $Id: util.c 149 2000-06-19 21:56:12Z bears $ */ #if HAVE_CONFIG_H #include <config.h> #endif #if TIME_WITH_SYS_TIME #include <sys/time.h> #include <time.h> #else #if HAVE_SYS_TIME_H #include <sys/time.h> #else #include <time.h> #endif #endif #include "util.h" #include <errno.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <unistd.h> #include "configfile.h" #include "log.h" #include "wildmat.h" #include "portable.h" #if defined(UTIL_TEST) #define Log_err printf #define Log_dbg printf #endif static const char * nextWhiteSpace( const char *p ) { while ( *p && ! isspace( *p ) ) ++p; return p; } static const char * nextNonWhiteSpace( const char *p ) { while ( *p && isspace( *p ) ) ++p; return p; } const char * Utl_restOfLn( const char *line, unsigned int token ) { unsigned int i; const char *p; p = line; for ( i = 0; i < token; ++i ) { p = nextNonWhiteSpace( p ); p = nextWhiteSpace( p ); } p = nextNonWhiteSpace( p ); return p; } const char * Utl_getLn( Str result, const char *pos ) { int len = 0; const char *p = pos; if ( ! p ) return NULL; while ( *p != '\n' ) { if ( *p == '\0' ) { if ( len > 0 ) Log_err( "Line not terminated by newline: '%s'", pos ); return NULL; } *(result++) = *(p++); ++len; if ( len >= MAXCHAR - 1 ) { *result = '\0'; Log_err( "Utl_getLn: line too long: %s", result ); return ++p; } } *result = '\0'; return ++p; } const char * Utl_ungetLn( const char *str, const char *p ) { if ( str == p ) return FALSE; --p; if ( *p != '\n' ) { Log_dbg( "Utl_ungetLn: not at beginning of line" ); return NULL; } --p; while ( TRUE ) { if ( p == str ) return p; if ( *p == '\n' ) return p + 1; --p; } } const char * Utl_getHeaderLn( Str result, const char *p ) { const char * res = Utl_getLn( result, p ); /* Look for followon line if this isn't a blank line. */ if ( res != NULL && result[ 0 ] != '\0' && ! isspace( result[ 0 ] ) ) for(;;) { Str nextLine; const char *here; here = res; nextLine[ 0 ] = '\0'; res = Utl_getLn( nextLine, res ); if ( res == NULL || nextLine[ 0 ] == '\0' || ! isspace( nextLine[ 0 ] ) ) { res = here; break; } else { Utl_catStr( result, "\n" ); Utl_catStr( result, nextLine ); } } return res; } void Utl_toLower( Str line ) { char *p; p = line; while ( *p ) { *p = tolower( *p ); ++p; } } char * Utl_stripWhiteSpace( char *line ) { char *p; while ( isspace( *line ) ) ++line; p = line + strlen( line ) - 1; while ( isspace( *p ) ) { *p = '\0'; --p; } return line; } void Utl_stripComment( char *line ) { for ( ; *line != '\0'; line++ ) if ( *line =='#' ) { *line = '\0'; break; } } void Utl_cpyStr( Str dst, const char *src ) { dst[ 0 ] = '\0'; strncat( dst, src, MAXCHAR ); } void Utl_cpyStrN( Str dst, const char *src, int n ) { if ( n > MAXCHAR ) n = MAXCHAR; dst[ 0 ] = '\0'; strncat( dst, src, (size_t)n ); } void Utl_catStr( Str dst, const char *src ) { strncat( dst, src, MAXCHAR - strlen( dst ) ); } void Utl_catStrN( Str dst, const char *src, int n ) { size_t un; ASSERT( n >= 0 ); un = (size_t)n; if ( un > MAXCHAR - strlen( dst ) ) un = MAXCHAR - strlen( dst ); strncat( dst, src, un ); } void Utl_stamp( Str file ) { FILE *f; time_t t; time( &t ); if ( ! ( f = fopen( file, "w" ) ) ) { Log_err( "Could not open %s for writing (%s)", file, strerror( errno ) ); return; } fprintf( f, "%lu\n", t ); fclose( f ); } Bool Utl_getStamp( time_t *result, Str file ) { FILE *f; if ( ! ( f = fopen( file, "r" ) ) ) return FALSE; if ( fscanf( f, "%lu", result ) != 1 ) { Log_err( "File %s corrupted", file ); fclose( f ); return FALSE; } fclose( f ); return TRUE; } static const char *DOTW[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL }; static const char *MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL }; void Utl_newsDate( time_t t, Str res ) { struct tm local, localAsGmt; time_t tlocalAsGmt; int tzdiff, hoffset, moffset; local = *localtime( &t ); memset( &localAsGmt, 0, sizeof( localAsGmt ) ); localAsGmt.tm_sec = local.tm_sec; localAsGmt.tm_min = local.tm_min; localAsGmt.tm_hour = local.tm_hour; localAsGmt.tm_mday = local.tm_mday; localAsGmt.tm_mon = local.tm_mon; localAsGmt.tm_year = local.tm_year; tlocalAsGmt = mktime( &localAsGmt ); tzdiff = (int) ( ( (long) difftime( tlocalAsGmt, t ) ) / 60 ); hoffset = tzdiff / 60; moffset = tzdiff % 60; if ( moffset < 0 ) moffset = -moffset; sprintf( res, "%s, %d %s %4d %02d:%02d:%02d %+03d%02d", DOTW[local.tm_wday], local.tm_mday, MON[local.tm_mon], local.tm_year + 1900, local.tm_hour, local.tm_min, local.tm_sec, hoffset, moffset ); } time_t Utl_parseNewsDate( const char *s ) { struct tm tm; int wday, tzoffset, hoffset, moffset; char *p; time_t res; memset( &tm, 0, sizeof( tm ) ); wday = -1; s = nextNonWhiteSpace( s ); /* Is this the day number, or a weekday? */ if ( ! isdigit( *s ) ) { if ( strlen( s ) < 4 ) return (time_t) -1; for ( wday = 0; DOTW[ wday ] != NULL; wday++ ) if ( strncmp( DOTW[ wday ], s, 3 ) == 0 ) break; if( DOTW[ wday ] == NULL || s[3] != ',' ) return (time_t) -1; s += 4; } /* Get the day number */ tm.tm_mday = (int) strtol( s, &p, 10 ); if ( p == s ) return (time_t) -1; s = p; /* Look for month name */ s = nextNonWhiteSpace( s ); if ( strlen( s ) < 4 ) return (time_t) -1; for ( tm.tm_mon = 0; MON[ tm.tm_mon ] != NULL; tm.tm_mon++ ) if ( strncmp( MON[ tm.tm_mon ], s, 3 ) == 0 ) break; if ( MON[ tm.tm_mon ] == NULL ) return (time_t) -1; s += 3; /* Year next */ tm.tm_year = (int) strtol( s, &p, 10 ); if ( p == s || ( tm.tm_year >= 100 && tm.tm_year < 1900 ) ) return (time_t) -1; if ( tm.tm_year >= 1900 ) tm.tm_year -= 1900; s = p; /* Hours */ tm.tm_hour = (int) strtol( s, &p, 10 ); if ( p == s || *p != ':' ) return (time_t) -1; s = ++p; /* Minutes */ tm.tm_min = (int) strtol( s, &p, 10 ); if ( p == s || ( *p != ':' && *p != ' ' ) ) return (time_t) -1; s = p; /* Seconds */ if ( *s == ':' ) { s++; tm.tm_sec = (int) strtol( s, &p, 10 ); if ( p == s ) return (time_t) -1; s = p; } /* GMT/UT or timezone offset */ tzoffset = 0; while ( isspace( *s ) ) s++; if ( strncmp( s, "GMT", 3) == 0 ) s += 3; else if ( strncmp( s, "UT", 2 ) == 0 ) s += 2; else { tzoffset = (int) strtol( s, &p, 10 ); s = p; } /* Check for following junk */ if ( *s != '\0' && ! isspace( *s ) ) return (time_t) -1; res = mktime( &tm ); if ( res == (time_t) -1 ) return res; if ( wday >= 0 && wday != tm.tm_wday ) return (time_t) -1; moffset = tzoffset % 100; hoffset = tzoffset / 100; res = res - ( ( hoffset * 60 + moffset ) * 60 ); return res; } void Utl_allocAndCpy( char **dst, const char *src ) { int len = strlen( src ); if ( ! ( *dst = malloc( (size_t)len + 1 ) ) ) { Log_err( "Cannot allocate string with length %lu", strlen( src ) ); exit( EXIT_FAILURE ); } memcpy( *dst, src, (size_t)len + 1 ); } #if defined(UTIL_TEST) /* Test code borrowed from wildmat.c. Yep, still uses gets(). */ extern char *gets(); int main() { Str line; time_t t; printf( "Util date tester. Enter date to test.\n" ); printf( "A blank line exits the program.\n" ); for ( ; ; ) { printf( "\nEnter date: " ); (void) fflush( stdout ); if ( gets( line ) == NULL || line[0] == '\0' ) break; t = Utl_parseNewsDate( line ); if ( t == (time_t) -1 ) printf( "Date parse failed\n" ); else { Utl_newsDate( t, line ); printf( "Utl_newsDate -> '%s'\nctime() -> '%s'\n", line, ctime( &t ) ); } } exit(0); /* NOTREACHED */ } #endif