00001
00002
00003 const char *XrdSutRndmCVSID = "$Id: XrdSutRndm.cc 30949 2009-11-02 16:37:58Z ganis $";
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <stdlib.h>
00014 #include <unistd.h>
00015 #include <string.h>
00016 #include <sys/types.h>
00017 #include <sys/stat.h>
00018 #include <time.h>
00019 #include <fcntl.h>
00020 #include <errno.h>
00021
00022 #include <XrdOuc/XrdOucString.hh>
00023 #include <XrdSut/XrdSutRndm.hh>
00024 #include <XrdSut/XrdSutTrace.hh>
00025
00026
00027
00028
00029 static kXR_int32 XrdSutCharMsk[4][4] =
00030 { {0x0, 0xffffff08, 0xafffffff, 0x2ffffffe},
00031 {0x0, 0x3ff0000, 0x7fffffe, 0x7fffffe},
00032 {0x0, 0x3ff0000, 0x7e, 0x7e},
00033 {0x0, 0x3ffc000, 0x7fffffe, 0x7fffffe} };
00034
00035
00036
00037
00038
00039
00040
00041 bool XrdSutRndm::fgInit = 0;
00042
00043
00044 bool XrdSutRndm::Init(bool force)
00045 {
00046
00047
00048
00049 EPNAME("Rndm::Init");
00050
00051 const char *randdev = "/dev/urandom";
00052 bool rc = 0;
00053
00054
00055 if (fgInit && !force)
00056 return 1;
00057
00058 int fd;
00059 unsigned int seed;
00060 if ((fd = open(randdev, O_RDONLY)) != -1) {
00061 DEBUG("taking seed from " <<randdev);
00062 if (read(fd, &seed, sizeof(seed)) == sizeof(seed)) rc = 1;
00063 close(fd);
00064 }
00065 if (rc == 0) {
00066 DEBUG(randdev <<" not available: using time()");
00067 seed = time(0);
00068 rc = 1;
00069 }
00070 srand(seed);
00071
00072
00073 fgInit = 1;
00074
00075 return rc;
00076 }
00077
00078
00079 int XrdSutRndm::GetString(const char *copt, int len, XrdOucString &str)
00080 {
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 int opt = 0;
00091 if (!strncasecmp(copt,"LetNum",6))
00092 opt = 1;
00093 else if (!strncasecmp(copt,"Hex",3))
00094 opt = 2;
00095 else if (!strncasecmp(copt,"Crypt",5))
00096 opt = 3;
00097
00098 return XrdSutRndm::GetString(opt,len,str);
00099 }
00100
00101
00102 int XrdSutRndm::GetString(int opt, int len, XrdOucString &str)
00103 {
00104
00105
00106
00107
00108
00109
00110 EPNAME("Rndm::GetString");
00111
00112 const char *cOpt[4] = { "Any", "LetNum", "Hex", "Crypt" };
00113
00114
00115 if (opt < 0 || opt > 3) {
00116 opt = 0;
00117 DEBUG("unknown option: " <<opt <<": assume 0");
00118 }
00119 DEBUG("enter: len: " <<len <<" (type: " <<cOpt[opt] <<")");
00120
00121
00122 if (!XrdSutRndm::fgInit)
00123 XrdSutRndm::fgInit = XrdSutRndm::Init();
00124
00125
00126 char *buf = new char[len+1];
00127 if (!buf) {
00128 errno = ENOSPC;
00129 return -1;
00130 }
00131
00132 kXR_int32 k = 0;
00133 kXR_int32 i, j, l, m, frnd;
00134 while (k < len) {
00135 frnd = rand();
00136 for (m = 7; m < 32; m += 7) {
00137 i = 0x7F & (frnd >> m);
00138 j = i / 32;
00139 l = i - j * 32;
00140 if ((XrdSutCharMsk[opt][j] & (1 << l))) {
00141 buf[k] = i;
00142 k++;
00143 }
00144 if (k == len)
00145 break;
00146 }
00147 }
00148
00149
00150 buf[len] = 0;
00151 DEBUG("got: " <<buf);
00152
00153
00154 str = buf;
00155 delete[] buf;
00156
00157 return 0;
00158 }
00159
00160
00161 char *XrdSutRndm::GetBuffer(int len, int opt)
00162 {
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 EPNAME("Rndm::GetBuffer");
00173
00174 DEBUG("enter: len: " <<len);
00175
00176
00177 if (!fgInit) {
00178 Init();
00179 fgInit = 1;
00180 }
00181
00182
00183 char *buf = new char[len];
00184 if (!buf) {
00185 errno = ENOSPC;
00186 return 0;
00187 }
00188
00189
00190 bool filter = (opt >= 0 && opt <= 3);
00191
00192 kXR_int32 k = 0;
00193 kXR_int32 i, m, frnd, j = 0, l = 0;
00194 while (k < len) {
00195 frnd = rand();
00196 for (m = 0; m < 32; m += 8) {
00197 i = 0xFF & (frnd >> m);
00198 bool keep = 1;
00199 if (filter) {
00200 j = i / 32;
00201 l = i - j * 32;
00202 keep = (XrdSutCharMsk[opt][j] & (1 << l));
00203 }
00204 if (keep) {
00205 buf[k] = i;
00206 k++;
00207 }
00208 if (k == len)
00209 break;
00210 }
00211 }
00212
00213 return buf;
00214 }
00215
00216
00217 int XrdSutRndm::GetRndmTag(XrdOucString &rtag)
00218 {
00219
00220
00221
00222
00223
00224 return XrdSutRndm::GetString(3,8,rtag);
00225 }
00226
00227
00228
00229 unsigned int XrdSutRndm::GetUInt()
00230 {
00231
00232
00233
00234 if (!fgInit) {
00235 Init();
00236 fgInit = 1;
00237 }
00238
00239
00240 return rand();
00241 }