/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2000-2001 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* .
*/
#define APR_WANT_MEMFUNC
#include "apr_want.h"
#include "apr_general.h"
#include "misc.h"
#include
#if APR_HAVE_SYS_TYPES_H
#include
#endif
#if APR_HAVE_SYS_SOCKET_H
#include
#endif
#if APR_HAVE_FCNTL_H
#include
#endif
#if APR_HAVE_UNISTD_H
#include
#endif
#if APR_HAVE_SYS_UN_H
#include
#endif
#if APR_HAS_RANDOM
/* This tells the preprocessor to put quotes around the value. */
#define XSTR(x) #x
#define STR(x) XSTR(x)
APR_DECLARE(apr_status_t) apr_generate_random_bytes(unsigned char *buf,
int length)
{
#ifdef DEV_RANDOM
int rnd;
size_t got, tot;
if ((rnd = open(STR(DEV_RANDOM), O_RDONLY)) == -1)
return errno;
for (tot=0; tot 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_XtOffsetOf(struct sockaddr_un, sun_path) +
egd_path_len;
egd_socket = socket(PF_UNIX, SOCK_STREAM, 0);
if (egd_socket == -1) {
/* Does socket set errno? */
return APR_EGENERAL;
}
rv = connect(egd_socket, (struct sockaddr*)&addr, egd_addr_len);
if (rv == -1) {
return errno;
}
/* 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;
srv = write(egd_socket, req, 2);
if (srv == -1) {
shutdown(egd_socket, SHUT_RDWR);
close(egd_socket);
return errno;
}
if (srv != 2) {
shutdown(egd_socket, SHUT_RDWR);
close(egd_socket);
return APR_EGENERAL; /* Try again. */
}
resp_expected = req[1];
srv = read(egd_socket, resp, resp_expected);
if (srv == -1) {
shutdown(egd_socket, SHUT_RDWR);
close(egd_socket);
return errno;
}
memcpy(curbuf, resp, srv);
curbuf += srv;
length -= srv;
}
shutdown(egd_socket, SHUT_RDWR);
close(egd_socket);
#elif defined(HAVE_TRUERAND) /* use truerand */
extern int randbyte(void); /* from the truerand library */
unsigned int idx;
/* this will increase the startup time of the server, unfortunately...
* (generating 20 bytes takes about 8 seconds)
*/
for (idx=0; idx