summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authororlikowski <orlikowski@13f79535-47bb-0310-9956-ffa450edef68>2002-07-10 05:54:12 +0000
committerorlikowski <orlikowski@13f79535-47bb-0310-9956-ffa450edef68>2002-07-10 05:54:12 +0000
commita56172a7141e17dc0e99d61fb7313c81ccbe955e (patch)
tree40342595c6b0eb8d6a96ff99cb3ad1de6a299ad5 /misc
parentc1d29ba186a3631a6ea144e5553a4b64ab9ed203 (diff)
downloadlibapr-a56172a7141e17dc0e99d61fb7313c81ccbe955e.tar.gz
Inspired by the OpenSSL guys, this allows the --with-egd parameter to
use defaults, if a socket is not specified. Reviewed by: Jeff Trawick git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@63594 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'misc')
-rw-r--r--misc/unix/rand.c121
1 files changed, 66 insertions, 55 deletions
diff --git a/misc/unix/rand.c b/misc/unix/rand.c
index 3cb9e7d20..94970dccb 100644
--- a/misc/unix/rand.c
+++ b/misc/unix/rand.c
@@ -86,7 +86,7 @@ APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf,
#ifdef DEV_RANDOM
int rnd;
- size_t got, tot;
+ apr_size_t got, tot;
if ((rnd = open(STR(DEV_RANDOM), O_RDONLY)) == -1)
return errno;
@@ -119,76 +119,87 @@ APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf,
* 0x04 (report PID)
* 0xMM (length of PID string, not null-terminated) MM chars
*/
- int egd_socket, egd_path_len, rv;
+ static const char *egd_sockets[] = { EGD_DEFAULT_SOCKET, NULL };
+ const char **egdsockname = NULL;
+
+ int egd_socket, egd_path_len, rv, bad_errno;
struct sockaddr_un addr;
apr_socklen_t egd_addr_len;
- size_t resp_expected;
+ apr_size_t resp_expected;
unsigned char req[2], resp[255];
unsigned char *curbuf = buf;
- egd_path_len = strlen(STR(EGD_DEFAULT_SOCKET));
-
- if (egd_path_len > sizeof(addr.sun_path)) {
- return APR_EINVAL;
- }
-
- memset(&addr, 0, sizeof(struct sockaddr_un));
- addr.sun_family = AF_UNIX;
- memcpy(addr.sun_path, STR(EGD_DEFAULT_SOCKET), egd_path_len);
- egd_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) +
- egd_path_len;
-
- egd_socket = socket(PF_UNIX, SOCK_STREAM, 0);
-
- if (egd_socket == -1) {
- return errno;
- }
-
- rv = connect(egd_socket, (struct sockaddr*)&addr, egd_addr_len);
-
- if (rv == -1) {
- return errno;
- }
+ for (egdsockname = egd_sockets; *egdsockname && length > 0; egdsockname++) {
+ egd_path_len = strlen(*egdsockname);
+
+ if (egd_path_len > sizeof(addr.sun_path)) {
+ return APR_EINVAL;
+ }
- /* EGD can only return 255 bytes of data at a time. Silly. */
- while (length > 0) {
- ssize_t srv;
- req[0] = 2; /* We'll block for now. */
- req[1] = length > 255 ? 255: length;
+ memset(&addr, 0, sizeof(struct sockaddr_un));
+ addr.sun_family = AF_UNIX;
+ memcpy(addr.sun_path, *egdsockname, egd_path_len);
+ egd_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) +
+ egd_path_len;
- srv = write(egd_socket, req, 2);
- if (srv == -1) {
- int bad_errno = errno;
+ egd_socket = socket(PF_UNIX, SOCK_STREAM, 0);
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
- return bad_errno;
+ if (egd_socket == -1) {
+ return errno;
}
- if (srv != 2) {
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
- return APR_EGENERAL; /* Try again. */
- }
+ rv = connect(egd_socket, (struct sockaddr*)&addr, egd_addr_len);
- resp_expected = req[1];
- srv = read(egd_socket, resp, resp_expected);
- if (srv == -1) {
- int bad_errno = errno;
+ if (rv == -1) {
+ bad_errno = errno;
+ continue;
+ }
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
- return bad_errno;
+ /* EGD can only return 255 bytes of data at a time. Silly. */
+ while (length > 0) {
+ apr_ssize_t srv;
+ req[0] = 2; /* We'll block for now. */
+ req[1] = length > 255 ? 255: length;
+
+ srv = write(egd_socket, req, 2);
+ if (srv == -1) {
+ bad_errno = errno;
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ break;
+ }
+
+ if (srv != 2) {
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ return APR_EGENERAL;
+ }
+
+ resp_expected = req[1];
+ srv = read(egd_socket, resp, resp_expected);
+ if (srv == -1) {
+ bad_errno = errno;
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ return bad_errno;
+ }
+
+ memcpy(curbuf, resp, srv);
+ curbuf += srv;
+ length -= srv;
}
+
+ shutdown(egd_socket, SHUT_RDWR);
+ close(egd_socket);
+ }
- memcpy(curbuf, resp, srv);
- curbuf += srv;
- length -= srv;
+ if (length > 0) {
+ /* We must have iterated through the list of sockets,
+ * and no go. Return the errno.
+ */
+ return bad_errno;
}
- shutdown(egd_socket, SHUT_RDWR);
- close(egd_socket);
-
#elif defined(HAVE_TRUERAND) /* use truerand */
extern int randbyte(void); /* from the truerand library */