X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Fliblutil%2Futils.c;h=77baee98c65b847caf69e2bff2dc641df84f1fd5;hb=d8eace75a7472731d78f61df01e648e8af8deee5;hp=e09940c7daa2dc427d087f67410cc683b4fb9f61;hpb=3c598e89fb34a892d369a138daa8c3314294493c;p=openldap diff --git a/libraries/liblutil/utils.c b/libraries/liblutil/utils.c index e09940c7da..77baee98c6 100644 --- a/libraries/liblutil/utils.c +++ b/libraries/liblutil/utils.c @@ -1,7 +1,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2004 The OpenLDAP Foundation. + * Copyright 1998-2006 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #ifdef HAVE_IO_H @@ -34,6 +35,23 @@ int _trans_argv = 1; #endif +#ifdef _WIN32 +/* Some Windows versions accept both forward and backslashes in + * directory paths, but we always use backslashes when generating + * and parsing... + */ +void lutil_slashpath( char *path ) +{ + char *c, *p; + + p = path; + while (( c=strchr( p, '/' ))) { + *c++ = '\\'; + p = c; + } +} +#endif + char* lutil_progname( const char* name, int argc, char *argv[] ) { char *progname; @@ -49,9 +67,9 @@ char* lutil_progname( const char* name, int argc, char *argv[] ) _trans_argv = 0; } #endif + LUTIL_SLASHPATH( argv[0] ); progname = strrchr ( argv[0], *LDAP_DIRSEP ); progname = progname ? &progname[1] : argv[0]; - return progname; } @@ -118,6 +136,134 @@ size_t lutil_localtime( char *s, size_t smax, const struct tm *tm, long delta ) return ret + 5; } +int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt ) +{ + static int moffset[12] = { + 0, 31, 59, 90, 120, + 151, 181, 212, 243, + 273, 304, 334 }; + int sec; + + tt->tt_usec = tm->tm_usec; + + /* special case 0000/01/01+00:00:00 is returned as zero */ + if ( tm->tm_year == -1900 && tm->tm_mon == 0 && tm->tm_mday == 1 && + tm->tm_hour == 0 && tm->tm_min == 0 && tm->tm_sec == 0 ) { + tt->tt_sec = 0; + tt->tt_gsec = 0; + return 0; + } + + /* tm->tm_year is years since 1900 */ + /* calculate days from years since 1970 (epoch) */ + tt->tt_sec = tm->tm_year - 70; + tt->tt_sec *= 365L; + + /* count leap days in preceding years */ + tt->tt_sec += ((tm->tm_year -69) >> 2); + + /* calculate days from months */ + tt->tt_sec += moffset[tm->tm_mon]; + + /* add in this year's leap day, if any */ + if (((tm->tm_year & 3) == 0) && (tm->tm_mon > 1)) { + tt->tt_sec ++; + } + + /* add in days in this month */ + tt->tt_sec += (tm->tm_mday - 1); + + /* this function can handle a range of about 17408 years... */ + /* 86400 seconds in a day, divided by 128 = 675 */ + tt->tt_sec *= 675; + + /* move high 7 bits into tt_gsec */ + tt->tt_gsec = tt->tt_sec >> 25; + tt->tt_sec -= tt->tt_gsec << 25; + + /* get hours */ + sec = tm->tm_hour; + + /* convert to minutes */ + sec *= 60L; + sec += tm->tm_min; + + /* convert to seconds */ + sec *= 60L; + sec += tm->tm_sec; + + /* add remaining seconds */ + tt->tt_sec <<= 7; + tt->tt_sec += sec; + + /* return success */ + return 0; +} + +int lutil_parsetime( char *atm, struct lutil_tm *tm ) +{ + while (atm && tm) { + char *ptr = atm; + unsigned i, fracs; + + /* Is the stamp reasonably long? */ + for (i=0; isdigit(atm[i]); i++); + if (i < sizeof("00000101000000")-1) + break; + + /* + * parse the time into a struct tm + */ + /* 4 digit year to year - 1900 */ + tm->tm_year = *ptr++ - '0'; + tm->tm_year *= 10; tm->tm_year += *ptr++ - '0'; + tm->tm_year *= 10; tm->tm_year += *ptr++ - '0'; + tm->tm_year *= 10; tm->tm_year += *ptr++ - '0'; + tm->tm_year -= 1900; + /* month 01-12 to 0-11 */ + tm->tm_mon = *ptr++ - '0'; + tm->tm_mon *=10; tm->tm_mon += *ptr++ - '0'; + if (tm->tm_mon < 1 || tm->tm_mon > 12) break; + tm->tm_mon--; + + /* day of month 01-31 */ + tm->tm_mday = *ptr++ - '0'; + tm->tm_mday *=10; tm->tm_mday += *ptr++ - '0'; + if (tm->tm_mday < 1 || tm->tm_mday > 31) break; + + /* Hour 00-23 */ + tm->tm_hour = *ptr++ - '0'; + tm->tm_hour *=10; tm->tm_hour += *ptr++ - '0'; + if (tm->tm_hour < 0 || tm->tm_hour > 23) break; + + /* Minute 00-59 */ + tm->tm_min = *ptr++ - '0'; + tm->tm_min *=10; tm->tm_min += *ptr++ - '0'; + if (tm->tm_min < 0 || tm->tm_min > 59) break; + + /* Second 00-61 */ + tm->tm_sec = *ptr++ - '0'; + tm->tm_sec *=10; tm->tm_sec += *ptr++ - '0'; + if (tm->tm_sec < 0 || tm->tm_sec > 61) break; + + /* Fractions of seconds */ + for (i = 0, fracs = 0;isdigit(*ptr);) { + i*=10; i+= *ptr++ - '0'; + fracs++; + } + tm->tm_usec = i; + if (i) { + for (i = fracs; i<6; i++) + tm->tm_usec *= 10; + } + + /* Must be UTC */ + if (*ptr != 'Z') break; + + return 0; + } + return -1; +} /* strcopy is like strcpy except it returns a pointer to the trailing NUL of * the result string. This allows fast construction of catenated strings @@ -164,3 +310,185 @@ int mkstemp( char * template ) #endif } #endif + +/* + * Memory Reverse Search + */ +void * +lutil_memrchr(const void *b, int c, size_t n) +{ + if (n != 0) { + const unsigned char *s, *bb = b, cc = c; + + for ( s = bb + n; s > bb; ) { + if ( *--s == cc ) { + return (void *) s; + } + } + } + + return NULL; +} + +int +lutil_atoix( int *v, const char *s, int x ) +{ + char *next; + long i; + + assert( s != NULL ); + assert( v != NULL ); + + i = strtol( s, &next, x ); + if ( next == s || next[ 0 ] != '\0' ) { + return -1; + } + + if ( (long)(int)i != i ) { + return 1; + } + + *v = (int)i; + + return 0; +} + +int +lutil_atoux( unsigned *v, const char *s, int x ) +{ + char *next; + unsigned long u; + + assert( s != NULL ); + assert( v != NULL ); + + u = strtoul( s, &next, x ); + if ( next == s || next[ 0 ] != '\0' ) { + return -1; + } + + if ( (unsigned long)(unsigned)u != u ) { + return 1; + } + + *v = u; + + return 0; +} + +int +lutil_atolx( long *v, const char *s, int x ) +{ + char *next; + long l; + + assert( s != NULL ); + assert( v != NULL ); + + l = strtol( s, &next, x ); + if ( next == s || next[ 0 ] != '\0' ) { + return -1; + } + + *v = l; + + return 0; +} + +int +lutil_atoulx( unsigned long *v, const char *s, int x ) +{ + char *next; + unsigned long ul; + + assert( s != NULL ); + assert( v != NULL ); + + ul = strtoul( s, &next, x ); + if ( next == s || next[ 0 ] != '\0' ) { + return -1; + } + + *v = ul; + + return 0; +} + +static char time_unit[] = "dhms"; + +int +lutil_parse_time( + const char *in, + unsigned long *tp ) +{ + unsigned long t = 0; + char *s, + *next; + int sofar = -1, + scale[] = { 86400, 3600, 60, 1 }; + + *tp = 0; + + for ( s = (char *)in; s[ 0 ] != '\0'; ) { + unsigned long u; + char *what; + + u = strtoul( s, &next, 10 ); + if ( next == s ) { + return -1; + } + + if ( next[ 0 ] == '\0' ) { + /* assume seconds */ + t += u; + break; + } + + what = strchr( time_unit, next[ 0 ] ); + if ( what == NULL ) { + return -1; + } + + if ( what - time_unit <= sofar ) { + return -1; + } + + sofar = what - time_unit; + t += u * scale[ sofar ]; + + s = &next[ 1 ]; + } + + *tp = t; + return 0; +} + +int +lutil_unparse_time( + char *buf, + size_t buflen, + unsigned long t ) +{ + int len, i; + unsigned long v[ 4 ]; + char *ptr = buf; + + v[ 0 ] = t/86400; + v[ 1 ] = (t%86400)/3600; + v[ 2 ] = (t%3600)/60; + v[ 3 ] = t%60; + + for ( i = 0; i < 4; i++ ) { + if ( v[i] > 0 || ( i == 3 && ptr == buf ) ) { + len = snprintf( ptr, buflen, "%lu%c", v[ i ], time_unit[ i ] ); + if ( len < 0 || (unsigned)len >= buflen ) { + return -1; + } + buflen -= len; + ptr += len; + } + } + + return 0; +} +