/** Allocate a buffer and read in a file. @note Caller must free 'buf' parameter on success. Callers do not need to free buf on function failure. Two variants: psGetFileBuf takes in a filename, psGetFileBufFp takes in a pointer to an already opened FILE. */ int32 psGetFileBufFp(psPool_t *pool, FILE *fp, unsigned char **buf, int32 *bufLen) { struct stat f_stat; size_t tmp = 0; int fno = fileno(fp); if (fstat(fno, &f_stat) != 0) { fclose(fp); psTraceIntCore("Unable to stat fp %d\n", fno); return PS_PLATFORM_FAIL; } *buf = psMalloc(pool, (size_t) (f_stat.st_size + 1)); if (*buf == NULL) { fclose(fp); return PS_MEM_FAIL; } memset(*buf, 0x0, (size_t) f_stat.st_size + 1); while (((tmp = fread(*buf + *bufLen, sizeof(char), 512, fp)) > 0) && (*bufLen < f_stat.st_size)) { *bufLen += (int32) tmp; } fclose(fp); return PS_SUCCESS; }
/* PScore Public API implementations */ int32 psCreateMutex(psMutex_t *mutex) { int32 err; if ((err = pthread_mutex_init(mutex, &attr)) != 0) { psTraceIntCore("pthread_mutex_init failed %d\n", err); return PS_PLATFORM_FAIL; } return PS_SUCCESS; }
/* PScore Public API implementations */ int32 psGetEntropy(unsigned char *bytes, uint32 size, void *userPtr) { /* Read from /dev/random non-blocking first, then from urandom if it would block. Also, handle file closure case and re-open. */ int32 rc, sanity, retry, readBytes; unsigned char *where = bytes; sanity = retry = rc = readBytes = 0; while (size) { if ((rc = read(randfd, where, size)) < 0 || sanity > MAX_RAND_READS) { if (errno == EINTR) { if (sanity > MAX_RAND_READS) { psTraceCore("psGetEntropy failed randfd sanity\n"); return PS_PLATFORM_FAIL; } sanity++; continue; } else if (errno == EAGAIN) { break; } else if (errno == EBADF && retry == 0) { close(randfd); if ((randfd = open("/dev/random", O_RDONLY | O_NONBLOCK)) < 0) { break; } retry++; continue; } else { break; } } readBytes += rc; where += rc; size -= rc; } sanity = retry = 0; while (size) { if ((rc = read(urandfd, where, size)) < 0 || sanity > MAX_RAND_READS) { if (errno == EINTR) { if (sanity > MAX_RAND_READS) { psTraceCore("psGetEntropy failed urandfd sanity\n"); return PS_PLATFORM_FAIL; } sanity++; continue; } else if (errno == EBADF && retry == 0) { close(urandfd); if ((urandfd = open("/dev/urandom", O_RDONLY | O_NONBLOCK)) < 0) { psTraceCore("psGetEntropy failed urandom open\n"); return PS_PLATFORM_FAIL; } retry++; continue; } else { psTraceIntCore("psGetEntropy fail errno %d\n", errno); return PS_PLATFORM_FAIL; } } readBytes += rc; where += rc; size -= rc; } return readBytes; }