/* randstr.c  --  Functions for getting random data
 *
 *  GPLv2 only - Copyright (C) 2009 - 2012
 *               David Sommerseth <dazo@users.sourceforge.net>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; version 2
 *  of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

/**
 * @file   randstr.c
 * @author David Sommerseth <dazo@users.sourceforge.net>
 * @date   2009-01-10
 *
 * @brief  Simple functions for gathering random data
 *
 */

#include <stdio.h>
#include <unistd.h>
#include <openssl/rand.h>

#include <eurephia_nullsafe.h>
#include <eurephia_context.h>
#include <eurephia_log.h>

/**
 * Flag for indicating if the random generator has been initialised
 */
static int rand_init = 0;

/**
 * Generate some random data and return a string.  This function makes use of OpenSSL's RAND_pseudo_bytes()
 * function.
 *
 * @param ctx     eurephiaCTX
 * @param rndstr  Return buffer of the random data
 * @param len     Size of the return buffer
 *
 * @return Returns 1 on success, otherwise 0.
 */
int eurephia_randstring(eurephiaCTX *ctx, void *rndstr, size_t len) {
        int attempts = 0;
        do {
                if( !rand_init ) {
                        if( !RAND_load_file("/dev/urandom", 64) ) {
                                eurephia_log(ctx, LOG_FATAL, 0, "Could not load random data from /dev/urandom");
                                return 0;
                        }
                        rand_init = 1;
                }

                if( RAND_pseudo_bytes((unsigned char *) rndstr, len) ) {
                        return 1;
                }
                sleep(1);
                rand_init = 0;
        } while( attempts++ < 11 );
        eurephia_log(ctx, LOG_FATAL, 0, "RAND_pseudo_bytes() could not generate enough random data");
        return 0;
}
