XRootD
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 
39 #include "XrdOuc/XrdOucString.hh"
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 
47 static kXR_unt32 XrdSutCharMsk[4][4] =
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 
59 bool XrdSutRndm::fgInit = 0;
60 
61 //______________________________________________________________________________
62 bool 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 //______________________________________________________________________________
97 int 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 //______________________________________________________________________________
120 int 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
140  if (!XrdSutRndm::fgInit)
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 //______________________________________________________________________________
179 char *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 //______________________________________________________________________________
247 unsigned int XrdSutRndm::GetUInt()
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)
Definition: XrdBwmTrace.hh:54
#define EPNAME(x)
Definition: XrdBwmTrace.hh:56
int open(const char *path, int oflag,...)
ssize_t read(int fildes, void *buf, size_t nbyte)
#define close(a)
Definition: XrdPosix.hh:43
static kXR_unt32 XrdSutCharMsk[4][4]
Definition: XrdSutRndm.cc:47
static int GetRndmTag(XrdOucString &rtag)
Definition: XrdSutRndm.cc:235
static unsigned int GetUInt()
Definition: XrdSutRndm.cc:247
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)
Definition: XrdSutRndm.cc:179
static int GetString(int opt, int len, XrdOucString &s)
Definition: XrdSutRndm.cc:120