diff options
| -rw-r--r-- | src/lib/core/include/utils.h | 12 | ||||
| -rw-r--r-- | src/lib/core/utils.c | 50 |
2 files changed, 62 insertions, 0 deletions
diff --git a/src/lib/core/include/utils.h b/src/lib/core/include/utils.h index ea98faf..335a7e4 100644 --- a/src/lib/core/include/utils.h +++ b/src/lib/core/include/utils.h @@ -27,6 +27,15 @@ #define LINE_SEP "\n" #endif +#if defined(STASIS_OS_LINUX) +#define STASIS_RANDOM_GENERATOR_FILE "/dev/urandom" +#elif defined(STASIS_OS_DARWIN) +#define STASIS_RANDOM_GENERATOR_FILE "/dev/random" +#else +#define STASIS_RANDOM_GENERATOR_FILE NULL +#define NEED_SRAND 1 +#endif + #define STASIS_XML_PRETTY_PRINT_PROG "xmllint" #define STASIS_XML_PRETTY_PRINT_ARGS "--format" @@ -470,4 +479,7 @@ void seconds_to_human_readable(int v, char *result, size_t maxlen); #define STR_TO_TIMEOUT_INVALID_TIME_SCALE (-2) int str_to_timeout(char *s); +const char *get_random_generator_file(); +int get_random_bytes(char *result, size_t maxlen); + #endif //STASIS_UTILS_H diff --git a/src/lib/core/utils.c b/src/lib/core/utils.c index 34dee45..142e2b8 100644 --- a/src/lib/core/utils.c +++ b/src/lib/core/utils.c @@ -1120,3 +1120,53 @@ void seconds_to_human_readable(const int v, char *result, const size_t maxlen) { snprintf(result + strlen(result), maxlen, "%ds", seconds); } +const char *get_random_generator_file() { + return STASIS_RANDOM_GENERATOR_FILE; +} + +#ifdef NEED_SRAND +static char stasis_srand_initialized = 0; +#endif + +int get_random_bytes(char *result, size_t maxlen) { +#ifdef NEED_SRAND + if (!srand_initialized) { + srand(time(NULL)); + srand_initialized = 1; + } +#endif + size_t bytes = 0; + const char *filename = get_random_generator_file(); + FILE *fp = NULL; + if (filename != NULL) { + fp = fopen(filename, "rb"); + if (!fp) { + SYSERROR("%s", "unable to open random generator"); + return -1; + } + } + + do { + int ch = 0; + if (fp) { + ch = fgetc(fp); + } else { + ch = rand() % 255; + } + if (fp && ferror(fp)) { + SYSERROR("%s", "unable to read from random generator"); + return -1; + } + if (isalnum(ch)) { + result[bytes] = (char) ch; + bytes++; + } + } while (bytes < maxlen); + + if (fp) { + fclose(fp); + } + result[bytes ? bytes - 1 : 0] = '\0'; + return 0; +} + |
