as_rand.cpp

Thu, 06 Aug 2009 13:21:30 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 06 Aug 2009 13:21:30 +0200
changeset 15
0e0eb7c91312
parent 3
c1941114ca88
permissions
-rw-r--r--

Remove seemingly declarations unnecessary according to Qt 4.5.2 headers.

michael@1 1 //
michael@1 2 // OSSP asgui - Accounting system graphical user interface
michael@12 3 // Copyright (c) 2002-2009 The OSSP Project (http://www.ossp.org/)
michael@12 4 // Copyright (c) 2002-2009 Ralf S. Engelschall <rse@engelschall.com>
michael@12 5 // Copyright (c) 2002-2009 Michael Schloh von Bennewitz <michael@schloh.com>
michael@12 6 // Copyright (c) 2002-2009 Cable & Wireless Telecommunications Services GmbH
michael@1 7 //
michael@1 8 // This file is part of OSSP asgui, an accounting system graphical user
michael@3 9 // interface which can be found at http://asgui.europalab.com/.
michael@1 10 //
michael@1 11 // Permission to use, copy, modify, and distribute this software for
michael@1 12 // any purpose with or without fee is hereby granted, provided that
michael@1 13 // the above copyright notice and this permission notice appear in all
michael@1 14 // copies.
michael@1 15 //
michael@1 16 // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
michael@1 17 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
michael@1 18 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
michael@1 19 // IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
michael@1 20 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@1 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@1 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
michael@1 23 // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
michael@1 24 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
michael@1 25 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
michael@1 26 // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
michael@1 27 // SUCH DAMAGE.
michael@1 28 //
michael@1 29 // as_rand.cpp: ISO C++ implementation
michael@1 30 //
michael@1 31
michael@1 32 #include <fcntl.h>
michael@1 33 #include <cerrno>
michael@1 34
michael@1 35 #include "as_rand.h"
michael@1 36
michael@1 37 #if HAVE_UNISTD_H
michael@1 38 #include <unistd.h>
michael@1 39 #endif // HAVE_UNISTD_H
michael@1 40 #if HAVE_STDLIB_H
michael@1 41 #include <stdlib.h>
michael@1 42 #endif // HAVE_STDLIB_H
michael@1 43
michael@1 44 #if TIME_WITH_SYS_TIME
michael@1 45 #include <sys/time.h>
michael@1 46 #include <time.h>
michael@1 47 #else
michael@1 48 #if HAVE_SYS_TIME_H
michael@1 49 #include <sys/time.h>
michael@1 50 #else
michael@1 51 #include <time.h>
michael@1 52 #endif // HAVE_SYS_TIME_H
michael@1 53 #endif // TIME_WITH_SYS_TIME
michael@1 54
michael@1 55
michael@1 56 namespace AS {
michael@1 57
michael@1 58 // Constructor
michael@1 59 Rand::Rand(void)
michael@1 60 {
michael@1 61 this->nFd = -4; // Object fresh status
michael@1 62 this->openDevice(); // Open the random device
michael@1 63 // if (this->nFd < 0)
michael@1 64 // throw Genexcept("Could not open /dev/urandom or /dev/random.");
michael@1 65 }
michael@1 66
michael@1 67 // Destructor
michael@1 68 Rand::~Rand(void)
michael@1 69 {
michael@1 70 this->closeDevice(); // Close the random device
michael@1 71 this->nFd = -4; // Return this object to its fresh status
michael@1 72 }
michael@1 73
michael@1 74 //
michael@1 75 // Rand::openDevice(void)
michael@1 76 // Open the random device associated with this object
michael@1 77 //
michael@1 78 void Rand::openDevice(void)
michael@1 79 {
michael@1 80 struct timeval Time;
michael@1 81
michael@1 82 if (this->nFd == -4) { // -4 indicates a fresh object
michael@1 83 gettimeofday(&Time, 0);
michael@1 84 this->nFd = open("/dev/urandom", O_RDONLY);
michael@1 85 if (this->nFd == -1)
michael@1 86 this->nFd = open("/dev/random", O_RDONLY | O_NONBLOCK);
michael@1 87 srand((getpid() << 16) ^ getuid() ^ Time.tv_sec ^ Time.tv_usec); // Seed
michael@1 88 }
michael@1 89
michael@1 90 // Improve randomness by stirring in entropy
michael@1 91 gettimeofday(&Time, 0);
michael@1 92 for (int nIter = (Time.tv_sec ^ Time.tv_usec) & 0x1F; nIter > 0; nIter--)
michael@1 93 rand();
michael@1 94 }
michael@1 95
michael@1 96 //
michael@1 97 // Rand::closeDevice(void)
michael@1 98 // Close the random device associated with this object
michael@1 99 //
michael@1 100 void Rand::closeDevice(void)
michael@1 101 {
michael@1 102 if (this->nFd >= 0)
michael@1 103 close(this->nFd);
michael@1 104 }
michael@1 105
michael@1 106 //
michael@1 107 // Rand::genData(void *pvBuf, int nBytes)
michael@1 108 // Generate a series of random data from the system
michael@1 109 // standard random devices /dev/[u|s]random
michael@1 110 //
michael@1 111 void Rand::genData(void *pBuf, int nBytes)
michael@1 112 {
michael@1 113 int nRead = 0;
michael@1 114 int nLost = 0;
michael@1 115 char *szOut = (char *)pBuf;
michael@1 116
michael@1 117 if (this->nFd >= 0) {
michael@1 118 while (nBytes > 0) {
michael@1 119 nRead = read(this->nFd, szOut, nBytes);
michael@1 120 if ((nRead < 0) && ((errno == EINTR) || (errno == EAGAIN)))
michael@1 121 continue;
michael@1 122 if (nRead <= 0) {
michael@1 123 if (nLost++ == 8)
michael@1 124 break;
michael@1 125 continue;
michael@1 126 }
michael@1 127 nBytes -= nRead;
michael@1 128 szOut += nRead;
michael@1 129 nLost = 0;
michael@1 130 }
michael@1 131 }
michael@1 132
michael@1 133 // For systems with no /dev/random, we do the next best thing
michael@1 134 for (int nIter = 0; nIter< nBytes; nIter++)
michael@1 135 *szOut++ = rand() & 0xFF;
michael@1 136 }
michael@1 137 } // namespace AS

mercurial