Changeset 1719464 for lib/misc.c


Ignore:
Timestamp:
2006-06-28T14:47:05Z (18 years ago)
Author:
Wilmer van der Gaast <wilmer@…>
Branches:
master
Children:
5c9512f
Parents:
b3c467b
Message:

Added random_bytes() function for better/more reliable randomization and
moved set_eval_ops() to a slightly more suitable place.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • lib/misc.c

    rb3c467b r1719464  
    22  * BitlBee -- An IRC to other IM-networks gateway                     *
    33  *                                                                    *
    4   * Copyright 2002-2004 Wilmer van der Gaast and others                *
     4  * Copyright 2002-2006 Wilmer van der Gaast and others                *
    55  \********************************************************************/
    66
     
    1111 * Copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
    1212 *                          (and possibly other members of the Gaim team)
    13  * Copyright 2002-2005 Wilmer van der Gaast <wilmer@gaast.net>
     13 * Copyright 2002-2006 Wilmer van der Gaast <wilmer@gaast.net>
    1414 */
    1515
     
    422422}
    423423
    424 char *set_eval_charset( irc_t *irc, set_t *set, char *value )
    425 {
    426         GIConv cd;
    427 
    428         if ( g_strncasecmp( value, "none", 4 ) == 0 )
    429                 return( value );
    430 
    431         cd = g_iconv_open( "UTF-8", value );
    432         if( cd == (GIConv) -1 )
    433                 return( NULL );
    434 
    435         g_iconv_close( cd );
    436         return( value );
    437 }
     424/* A pretty reliable random number generator. Tries to use the /dev/random
     425   devices first, and falls back to the random number generator from libc
     426   when it fails. Opens randomizer devices with O_NONBLOCK to make sure a
     427   lack of entropy won't halt BitlBee. */
     428void random_bytes( unsigned char *buf, int count )
     429{
     430        static int use_dev = -1;
     431       
     432        /* Actually this probing code isn't really necessary, is it? */
     433        if( use_dev == -1 )
     434        {
     435                if( access( "/dev/random", R_OK ) == 0 || access( "/dev/urandom", R_OK ) == 0 )
     436                        use_dev = 1;
     437                else
     438                {
     439                        use_dev = 0;
     440                        srand( ( getpid() << 16 ) ^ time( NULL ) );
     441                }
     442        }
     443       
     444        if( use_dev )
     445        {
     446                int fd;
     447               
     448                /* At least on Linux, /dev/random can block if there's not
     449                   enough entropy. We really don't want that, so if it can't
     450                   give anything, use /dev/urandom instead. */
     451                if( ( fd = open( "/dev/random", O_RDONLY | O_NONBLOCK ) ) >= 0 )
     452                        if( read( fd, buf, count ) == count )
     453                        {
     454                                close( fd );
     455                                return;
     456                        }
     457                close( fd );
     458               
     459                /* urandom isn't supposed to block at all, but just to be
     460                   sure. If it blocks, we'll disable use_dev and use the libc
     461                   randomizer instead. */
     462                if( ( fd = open( "/dev/urandom", O_RDONLY | O_NONBLOCK ) ) >= 0 )
     463                        if( read( fd, buf, count ) == count )
     464                        {
     465                                close( fd );
     466                                return;
     467                        }
     468                close( fd );
     469               
     470                /* If /dev/random blocks once, we'll still try to use it
     471                   again next time. If /dev/urandom also fails for some
     472                   reason, stick with libc during this session. */
     473               
     474                use_dev = 0;
     475                srand( ( getpid() << 16 ) ^ time( NULL ) );
     476        }
     477       
     478        if( !use_dev )
     479        {
     480                int i;
     481               
     482                /* Possibly the LSB of rand() isn't very random on some
     483                   platforms. Seems okay on at least Linux and OSX though. */
     484                for( i = 0; i < count; i ++ )
     485                        buf[i] = rand() & 0xff;
     486        }
     487}
Note: See TracChangeset for help on using the changeset viewer.