XRootD
Loading...
Searching...
No Matches
XrdSutRndm.cc
Go to the documentation of this file.
1
2/******************************************************************************/
3/* */
4/* X r d S u t R n d m . c c */
5/* */
6/* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
7/* Produced by Gerri Ganis for CERN */
8/* */
9/* This file is part of the XRootD software suite. */
10/* */
11/* XRootD is free software: you can redistribute it and/or modify it under */
12/* the terms of the GNU Lesser General Public License as published by the */
13/* Free Software Foundation, either version 3 of the License, or (at your */
14/* option) any later version. */
15/* */
16/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
17/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
18/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
19/* License for more details. */
20/* */
21/* You should have received a copy of the GNU Lesser General Public License */
22/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
23/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
24/* */
25/* The copyright holder's institutional names and contributor's names may not */
26/* be used to endorse or promote products derived from this software without */
27/* specific prior written permission of the institution or contributor. */
28/******************************************************************************/
29
30#include <cstdlib>
31#include <unistd.h>
32#include <cstring>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <ctime>
36#include <fcntl.h>
37#include <cerrno>
38
40#include "XrdSut/XrdSutRndm.hh"
41#include "XrdSut/XrdSutTrace.hh"
42
43/******************************************************************************/
44/* M a s k s f o r A S C I I c h a r a c t e r s */
45/******************************************************************************/
46
48 { {0x0, 0xffffff08, 0xafffffff, 0x2ffffffe}, // any printable char
49 {0x0, 0x3ff0000, 0x7fffffe, 0x7fffffe}, // letters/numbers (up/low case)
50 {0x0, 0x3ff0000, 0x7e, 0x7e}, // hex characters (up/low case)
51 {0x0, 0x3ffc000, 0x7fffffe, 0x7fffffe} }; // crypt like [a-zA-Z0-9./]
52
53/******************************************************************************/
54/* */
55/* Provider of random bunches of bits */
56/* */
57/******************************************************************************/
58
59bool XrdSutRndm::fgInit = 0;
60
61//______________________________________________________________________________
62bool XrdSutRndm::Init(bool force)
63{
64 // Initialize the random machinery; try using /dev/urandom to avoid
65 // hanging.
66 // The bool 'force' can be used to force re-initialization.
67 EPNAME("Rndm::Init");
68
69 const char *randdev = "/dev/urandom";
70 bool rc = 0;
71
72 // We do not do it twice
73 if (fgInit && !force)
74 return 1;
75
76 int fd;
77 unsigned int seed = 0;
78 if ((fd = open(randdev, O_RDONLY)) != -1) {
79 DEBUG("taking seed from " <<randdev);
80 if (read(fd, &seed, sizeof(seed)) == sizeof(seed)) rc = 1;
81 close(fd);
82 }
83 if (rc == 0) {
84 DEBUG(randdev <<" not available: using time()");
85 seed = time(0); //better use times() + win32 equivalent
86 rc = 1;
87 }
88 srand(seed);
89
90 // Flag as initialized
91 fgInit = 1;
92
93 return rc;
94}
95
96//______________________________________________________________________________
97int XrdSutRndm::GetString(const char *copt, int len, XrdOucString &str)
98{
99 // Static method to fill string str with len random characters.
100 // Returns 0 if ok, -1 in case of error.
101 // copt = "Any" any printable char
102 // "LetNum" letters and numbers (upper and lower case)
103 // "Hex" hex characters (upper and lower case)
104 // "Crypt" crypt like [a-zA-Z0-9./]
105 //
106 // (opt is not case sensitive)
107
108 int opt = 0;
109 if (!strncasecmp(copt,"LetNum",6))
110 opt = 1;
111 else if (!strncasecmp(copt,"Hex",3))
112 opt = 2;
113 else if (!strncasecmp(copt,"Crypt",5))
114 opt = 3;
115
116 return XrdSutRndm::GetString(opt,len,str);
117}
118
119//______________________________________________________________________________
120int XrdSutRndm::GetString(int opt, int len, XrdOucString &str)
121{
122 // Static method to fill string str with len random characters.
123 // Returns 0 if ok, -1 in case of error.
124 // opt = 0 any printable char
125 // 1 letters and numbers (upper and lower case)
126 // 2 hex characters (upper and lower case)
127 // 3 crypt like [a-zA-Z0-9./]
128 EPNAME("Rndm::GetString");
129
130 const char *cOpt[4] = { "Any", "LetNum", "Hex", "Crypt" };
131
132 // Default option 0
133 if (opt < 0 || opt > 3) {
134 opt = 0;
135 DEBUG("unknown option: " <<opt <<": assume 0");
136 }
137 DEBUG("enter: len: " <<len <<" (type: " <<cOpt[opt] <<")");
138
139 // Init Random machinery ... if needed
142
143 // randomize
144 char *buf = new char[len+1];
145 if (!buf) {
146 errno = ENOSPC;
147 return -1;
148 }
149
150 kXR_int32 k = 0;
151 kXR_int32 i, j, l, m, frnd;
152 while (k < len) {
153 frnd = rand();
154 for (m = 7; m < 32; m += 7) {
155 i = 0x7F & (frnd >> m);
156 j = i / 32;
157 l = i - j * 32;
158 if ((XrdSutCharMsk[opt][j] & (1 << l))) {
159 buf[k] = i;
160 k++;
161 }
162 if (k == len)
163 break;
164 }
165 }
166
167 // null terminated
168 buf[len] = 0;
169 DEBUG("got: " <<buf);
170
171 // Fill output
172 str = buf;
173 delete[] buf;
174
175 return 0;
176}
177
178//______________________________________________________________________________
179char *XrdSutRndm::GetBuffer(int len, int opt)
180{
181 // Static method to fill randomly a buffer.
182 // Returns the pointer to the buffer if ok, 0 in case of error.
183 // If opt has one of the following values, the random bytes are
184 // chosen between the corrsponding subset:
185 // opt = 0 any printable char
186 // 1 letters and numbers (upper and lower case)
187 // 2 hex characters (upper and lower case)
188 // 3 crypt like [a-zA-Z0-9./]
189 // The caller is responsible to destroy the buffer
190 EPNAME("Rndm::GetBuffer");
191
192 DEBUG("enter: len: " <<len);
193
194 // Init Random machinery ... if needed
195 if (!fgInit) {
196 Init();
197 fgInit = 1;
198 }
199
200 // randomize
201 char *buf = new char[len];
202 if (!buf) {
203 errno = ENOSPC;
204 return 0;
205 }
206
207 // Filtering ?
208 bool filter = (opt >= 0 && opt <= 3);
209
210 kXR_int32 k = 0;
211 kXR_int32 i, m, frnd, j = 0, l = 0;
212 while (k < len) {
213 frnd = rand();
214 for (m = 0; m < 32; m += 8) {
215 i = 0xFF & (frnd >> m);
216 bool keep = 1;
217 if (filter) {
218 j = i / 32;
219 l = i - j * 32;
220 keep = (XrdSutCharMsk[opt][j%4] & (1 << l));
221 }
222 if (keep) {
223 buf[k] = i;
224 k++;
225 }
226 if (k == len)
227 break;
228 }
229 }
230
231 return buf;
232}
233
234//______________________________________________________________________________
236{
237 // Static method generating a 64 bit random tag (8 chars in [a-zA-Z0-9./])
238 // saved in rtag.
239 // Return 0 in case of success; in case of error, -1 is returned
240 // and errno set accordingly (see XrdSutRndm::GetString)
241
242 return XrdSutRndm::GetString(3,8,rtag);
243}
244
245
246//______________________________________________________________________________
248{
249 // Static method to return an unsigned int.
250
251 // Init Random machinery ... if needed
252 if (!fgInit) {
253 Init();
254 fgInit = 1;
255 }
256
257 // As simple as this
258 return rand();
259}
int kXR_int32
Definition XPtypes.hh:89
unsigned int kXR_unt32
Definition XPtypes.hh:90
#define DEBUG(x)
#define EPNAME(x)
#define close(a)
Definition XrdPosix.hh:43
#define open
Definition XrdPosix.hh:71
#define read(a, b, c)
Definition XrdPosix.hh:77
static kXR_int32 XrdSutCharMsk[4][4]
static int GetRndmTag(XrdOucString &rtag)
static unsigned int GetUInt()
static bool fgInit
Definition XrdSutRndm.hh:46
static bool Init(bool force=0)
Definition XrdSutRndm.cc:62
static char * GetBuffer(int len, int opt=-1)
static int GetString(int opt, int len, XrdOucString &s)