Back to index

openldap  2.4.31
Classes | Defines | Typedefs | Functions | Variables
utils.c File Reference
#include "portable.h"
#include <limits.h>
#include <stdio.h>
#include <ac/stdlib.h>
#include <ac/stdarg.h>
#include <ac/string.h>
#include <ac/ctype.h>
#include <ac/unistd.h>
#include <ac/time.h>
#include <ac/errno.h>
#include "lutil.h"
#include "ldap_defaults.h"
#include "ldap_pvt.h"
#include "lber_pvt.h"

Go to the source code of this file.

Classes

struct  lutil_int_decnum

Defines

#define FACTOR1   (100000000&0xffff)
#define FACTOR2   (100000000>>16)
#define HEXMAX   (2 * sizeof(long))
#define DECMAX   8 /* 8 digits at a time */

Typedefs

typedef struct lutil_int_decnum lutil_int_decnum

Functions

char * lutil_progname (const char *name, int argc, char *argv[])
size_t lutil_localtime (char *s, size_t smax, const struct tm *tm, long delta)
int lutil_tm2time (struct lutil_tm *tm, struct lutil_timet *tt)
int lutil_parsetime (char *atm, struct lutil_tm *tm)
char * lutil_strcopy (char *a, const char *b)
char * lutil_strncopy (char *a, const char *b, size_t n)
char * lutil_memcopy (char *a, const char *b, size_t n)
int mkstemp (char *template)
void *() lutil_memrchr (const void *b, int c, size_t n)
int lutil_atoix (int *v, const char *s, int x)
int lutil_atoux (unsigned *v, const char *s, int x)
int lutil_atolx (long *v, const char *s, int x)
int lutil_atoulx (unsigned long *v, const char *s, int x)
static void scale (int new, lutil_int_decnum *prev, unsigned char *tmp)
int lutil_str2bin (struct berval *in, struct berval *out, void *ctx)
int lutil_parse_time (const char *in, unsigned long *tp)
int lutil_unparse_time (char *buf, size_t buflen, unsigned long t)
int lutil_snprintf (char *buf, ber_len_t bufsize, char **next, ber_len_t *len, LDAP_CONST char *fmt,...)

Variables

static char time_unit [] = "dhms"

Class Documentation

struct lutil_int_decnum

Definition at line 658 of file utils.c.

Class Members
int beg
unsigned char * buf
int bufsiz
int len

Define Documentation

#define DECMAX   8 /* 8 digits at a time */
#define FACTOR1   (100000000&0xffff)

Definition at line 665 of file utils.c.

#define FACTOR2   (100000000>>16)

Definition at line 666 of file utils.c.

#define HEXMAX   (2 * sizeof(long))

Typedef Documentation


Function Documentation

int lutil_atoix ( int v,
const char *  s,
int  x 
)

Definition at line 465 of file utils.c.

{
       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;
}

Here is the caller graph for this function:

int lutil_atolx ( long *  v,
const char *  s,
int  x 
)

Definition at line 516 of file utils.c.

{
       char *next;
       long l;
       int save_errno;

       assert( s != NULL );
       assert( v != NULL );

       if ( isspace( s[ 0 ] ) ) {
              return -1;
       }

       errno = 0;
       l = strtol( s, &next, x );
       save_errno = errno;
       if ( next == s || next[ 0 ] != '\0' ) {
              return -1;
       }

       if ( ( l == LONG_MIN || l == LONG_MAX ) && save_errno != 0 ) {
              return -1;
       }

       *v = l;

       return 0;
}

Here is the caller graph for this function:

int lutil_atoulx ( unsigned long *  v,
const char *  s,
int  x 
)

Definition at line 546 of file utils.c.

{
       char *next;
       unsigned long ul;
       int save_errno;

       assert( s != NULL );
       assert( v != NULL );

       /* strtoul() has an odd interface */
       if ( s[ 0 ] == '-' || isspace( s[ 0 ] ) ) {
              return -1;
       }

       errno = 0;
       ul = strtoul( s, &next, x );
       save_errno = errno;
       if ( next == s || next[ 0 ] != '\0' ) {
              return -1;
       }

       if ( ( ul == 0 || ul == ULONG_MAX ) && save_errno != 0 ) {
              return -1;
       }

       *v = ul;

       return 0;
}

Here is the caller graph for this function:

int lutil_atoux ( unsigned v,
const char *  s,
int  x 
)

Definition at line 488 of file utils.c.

{
       char          *next;
       unsigned long u;

       assert( s != NULL );
       assert( v != NULL );

       /* strtoul() has an odd interface */
       if ( s[ 0 ] == '-' ) {
              return -1;
       }

       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;
}

Here is the caller graph for this function:

size_t lutil_localtime ( char *  s,
size_t  smax,
const struct tm tm,
long  delta 
)

Definition at line 110 of file utils.c.

{
       size_t ret;
       char   *p;

       if ( smax < 16 ) {   /* YYYYmmddHHMMSSZ */
              return 0;
       }

#ifdef HAVE_EBCDIC
/* We've been compiling in ASCII so far, but we want EBCDIC now since
 * strftime only understands EBCDIC input.
 */
#pragma convlit(suspend)
#endif
       ret = strftime( s, smax, "%Y%m%d%H%M%SZ", tm );
#ifdef HAVE_EBCDIC
#pragma convlit(resume)
       __etoa( s );
#endif
       if ( delta == 0 || ret == 0 ) {
              return ret;
       }

       if ( smax < 20 ) {   /* YYYYmmddHHMMSS+HHMM */
              return 0;
       }

       p = s + 14;

       if ( delta < 0 ) {
              p[ 0 ] = '-';
              delta = -delta;
       } else {
              p[ 0 ] = '+';
       }
       p++;

       snprintf( p, smax - 15, "%02ld%02ld", delta / 3600,
                     ( delta % 3600 ) / 60 );

       return ret + 4;
}
char* lutil_memcopy ( char *  a,
const char *  b,
size_t  n 
)

Definition at line 326 of file utils.c.

{
       AC_MEMCPY(a, b, n);
       return a + n;
}

Here is the caller graph for this function:

void*() lutil_memrchr ( const void b,
int  c,
size_t  n 
)

Definition at line 449 of file utils.c.

{
       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_parse_time ( const char *  in,
unsigned long *  tp 
)

Definition at line 857 of file utils.c.

{
       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;

              /* strtoul() has an odd interface */
              if ( s[ 0 ] == '-' ) {
                     return -1;
              }

              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;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int lutil_parsetime ( char *  atm,
struct lutil_tm tm 
)

Definition at line 218 of file utils.c.

{
       while (atm && tm) {
              char *ptr = atm;
              unsigned i, fracs;

              /* Is the stamp reasonably long? */
              for (i=0; isdigit((unsigned char) 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 */
              if ( *ptr == '.' ) {
                     ptr++;
                     for (i = 0, fracs = 0; isdigit((unsigned char) *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;
}

Here is the caller graph for this function:

char* lutil_progname ( const char *  name,
int  argc,
char *  argv[] 
)

Definition at line 63 of file utils.c.

{
       char *progname;

       if(argc == 0) {
              return (char *)name;
       }

#ifdef HAVE_EBCDIC
       if (_trans_argv) {
              int i;
              for (i=0; i<argc; i++) __etoa(argv[i]);
              _trans_argv = 0;
       }
#endif
       LUTIL_SLASHPATH( argv[0] );
       progname = strrchr ( argv[0], *LDAP_DIRSEP );
       progname = progname ? &progname[1] : argv[0];
#ifdef _WIN32
       {
              size_t len = strlen( progname );
              if ( len > 4 && strcasecmp( &progname[len - 4], ".exe" ) == 0 )
                     progname[len - 4] = '\0';
       }
#endif
       return progname;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int lutil_snprintf ( char *  buf,
ber_len_t  bufsize,
char **  next,
ber_len_t len,
LDAP_CONST char *  fmt,
  ... 
)

Definition at line 951 of file utils.c.

{
       va_list              ap;
       int           ret;

       assert( buf != NULL );
       assert( bufsize > 0 );
       assert( fmt != NULL );

       va_start( ap, fmt );
       ret = vsnprintf( buf, bufsize, fmt, ap );
       va_end( ap );

       if ( ret < 0 ) {
              return ret;
       }

       if ( len ) {
              *len = ret;
       }

       if ( (unsigned) ret >= bufsize ) {
              if ( next ) {
                     *next = &buf[ bufsize - 1 ];
              }

              return 1;
       }

       if ( next ) {
              *next = &buf[ ret ];
       }

       return 0;
}
int lutil_str2bin ( struct berval in,
struct berval out,
void ctx 
)

Definition at line 723 of file utils.c.

{
       char *pin, *pout;
       char *end;
       int i, chunk, len, rc = 0, hex = 0;
       if ( !out || !out->bv_val || out->bv_len < in->bv_len )
              return -1;

       pout = out->bv_val;
       /* Leading "0x" for hex input */
       if ( in->bv_len > 2 && in->bv_val[0] == '0' &&
              ( in->bv_val[1] == 'x' || in->bv_val[1] == 'X' ) )
       {
              len = in->bv_len - 2;
              pin = in->bv_val + 2;
              hex = 1;
       } else if ( in->bv_len > 3 && in->bv_val[0] == '\'' &&
              in->bv_val[in->bv_len-2] == '\'' &&
              in->bv_val[in->bv_len-1] == 'H' )
       {
              len = in->bv_len - 3;
              pin = in->bv_val + 1;
              hex = 1;
       }
       if ( hex ) {
#define HEXMAX       (2 * sizeof(long))
              unsigned long l;
              char tbuf[HEXMAX+1];

              /* Convert a longword at a time, but handle leading
               * odd bytes first
               */
              chunk = len % HEXMAX;
              if ( !chunk )
                     chunk = HEXMAX;

              while ( len ) {
                     int ochunk;
                     memcpy( tbuf, pin, chunk );
                     tbuf[chunk] = '\0';
                     errno = 0;
                     l = strtoul( tbuf, &end, 16 );
                     if ( errno )
                            return -1;
                     ochunk = (chunk + 1)/2;
                     for ( i = ochunk - 1; i >= 0; i-- ) {
                            pout[i] = l & 0xff;
                            l >>= 8;
                     }
                     pin += chunk;
                     pout += ochunk;
                     len -= chunk;
                     chunk = HEXMAX;
              }
              out->bv_len = pout - out->bv_val;
       } else {
       /* Decimal */
#define       DECMAX 8      /* 8 digits at a time */
              char tmpbuf[64], *tmp;
              lutil_int_decnum num;
              int neg = 0;
              long l;
              char tbuf[DECMAX+1];

              len = in->bv_len;
              pin = in->bv_val;
              num.buf = (unsigned char *)out->bv_val;
              num.bufsiz = out->bv_len;
              num.beg = num.bufsiz-1;
              num.len = 0;
              if ( pin[0] == '-' ) {
                     neg = 0xff;
                     len--;
                     pin++;
              }

              /* tmp must be at least as large as outbuf */
              if ( out->bv_len > sizeof(tmpbuf)) {
                     tmp = ber_memalloc_x( out->bv_len, ctx );
              } else {
                     tmp = tmpbuf;
              }
              chunk = len & (DECMAX-1);
              if ( !chunk )
                     chunk = DECMAX;

              while ( len ) {
                     memcpy( tbuf, pin, chunk );
                     tbuf[chunk] = '\0';
                     errno = 0;
                     l = strtol( tbuf, &end, 10 );
                     if ( errno ) {
                            rc = -1;
                            goto decfail;
                     }
                     scale( l, &num, (unsigned char *)tmp );
                     pin += chunk;
                     len -= chunk;
                     chunk = DECMAX;
              }
              /* Negate the result */
              if ( neg ) {
                     unsigned char *ptr;

                     ptr = num.buf+num.beg;

                     /* flip all bits */
                     for ( i=0; i<num.len; i++ )
                            ptr[i] ^= 0xff;

                     /* add 1, with carry - overflow handled below */
                     while ( i-- && ! (ptr[i] = (ptr[i] + 1) & 0xff )) ;
              }
              /* Prepend sign byte if wrong sign bit */
              if (( num.buf[num.beg] ^ neg ) & 0x80 ) {
                     num.beg--;
                     num.len++;
                     num.buf[num.beg] = neg;
              }
              if ( num.beg )
                     AC_MEMCPY( num.buf, num.buf+num.beg, num.len );
              out->bv_len = num.len;
decfail:
              if ( tmp != tmpbuf ) {
                     ber_memfree_x( tmp, ctx );
              }
       }
       return rc;
}

Here is the call graph for this function:

Here is the caller graph for this function:

char* lutil_strcopy ( char *  a,
const char *  b 
)

Definition at line 291 of file utils.c.

{
       if (!a || !b)
              return a;
       
       while ((*a++ = *b++)) ;
       return a-1;
}
char* lutil_strncopy ( char *  a,
const char *  b,
size_t  n 
)

Definition at line 308 of file utils.c.

{
       if (!a || !b || n == 0)
              return a;
       
       while ((*a++ = *b++) && n-- > 0) ;
       return a-1;
}

Here is the caller graph for this function:

int lutil_tm2time ( struct lutil_tm tm,
struct lutil_timet tt 
)

Definition at line 154 of file utils.c.

{
       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; 
}

Here is the caller graph for this function:

int lutil_unparse_time ( char *  buf,
size_t  buflen,
unsigned long  t 
)

Definition at line 909 of file utils.c.

{
       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;
}

Here is the caller graph for this function:

int mkstemp ( char *  template)

Definition at line 337 of file utils.c.

{
#ifdef HAVE_MKTEMP
       return open ( mktemp ( template ), O_RDWR|O_CREAT|O_EXCL, 0600 );
#else
       return -1;
#endif
}

Here is the caller graph for this function:

static void scale ( int  new,
lutil_int_decnum prev,
unsigned char *  tmp 
) [static]

Definition at line 669 of file utils.c.

{
       int i, j;
       unsigned char *in = prev->buf+prev->beg;
       unsigned int part;
       unsigned char *out = tmp + prev->bufsiz - prev->len;

       memset( tmp, 0, prev->bufsiz );
       if ( prev->len ) {
              for ( i = prev->len-1; i>=0; i-- ) {
                     part = in[i] * FACTOR1;
                     for ( j = i; part; j-- ) {
                            part += out[j];
                            out[j] = part & 0xff;
                            part >>= 8;
                     }
                     part = in[i] * FACTOR2;
                     for ( j = i-2; part; j-- ) {
                            part += out[j];
                            out[j] = part & 0xff;
                            part >>= 8;
                     }
              }
              j++;
              prev->beg += j;
              prev->len -= j;
       }

       out = tmp + prev->bufsiz;
       i = 0;
       do {
              i--;
              new += out[i];
              out[i] = new & 0xff;
              new >>= 8;
       } while ( new );
       i = -i;
       if ( prev->len < i ) {
              prev->beg = prev->bufsiz - i;
              prev->len = i;
       }
       AC_MEMCPY( prev->buf+prev->beg, tmp+prev->beg, prev->len );
}

Here is the caller graph for this function:


Variable Documentation

char time_unit[] = "dhms" [static]

Definition at line 853 of file utils.c.