00001
00002
00003 const char *XrdSutAuxCVSID = "$Id: XrdSutAux.cc 31508 2009-12-02 19:11:01Z brun $";
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdio.h>
00015 #include <stdlib.h>
00016 #include <string.h>
00017 #include <unistd.h>
00018 #include <errno.h>
00019 #include <netinet/in.h>
00020 #include <time.h>
00021 #include <pwd.h>
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <fcntl.h>
00025
00026 #include <XrdSys/XrdSysLogger.hh>
00027 #include <XrdSys/XrdSysError.hh>
00028 #include <XrdOuc/XrdOucString.hh>
00029
00030 #include <XrdSut/XrdSutAux.hh>
00031 #include <XrdSut/XrdSutTrace.hh>
00032
00033 static const char *gXRSBucketTypes[] = {
00034 "kXRS_none",
00035 "kXRS_inactive",
00036 "kXRS_cryptomod",
00037 "kXRS_main",
00038 "kXRS_srv_seal",
00039 "kXRS_clnt_seal",
00040 "kXRS_puk",
00041 "kXRS_cipher",
00042 "kXRS_rtag",
00043 "kXRS_signed_rtag",
00044 "kXRS_user",
00045 "kXRS_host",
00046 "kXRS_creds",
00047 "kXRS_message",
00048 "kXRS_srvID",
00049 "kXRS_sessionID",
00050 "kXRS_version",
00051 "kXRS_status",
00052 "kXRS_localstatus",
00053 "kXRS_othercreds",
00054 "kXRS_cache_idx",
00055 "kXRS_clnt_opts",
00056 "kXRS_error_code",
00057 "kXRS_timestamp",
00058 "kXRS_x509",
00059 "kXRS_issuer_hash",
00060 "kXRS_x509_req",
00061 "kXRS_cipher_alg",
00062 "kXRS_md_alg",
00063 "kXRS_afsinfo",
00064 "kXRS_reserved"
00065 };
00066
00067
00068
00069 static XrdSysLogger Logger;
00070 static XrdSysError eDest(0,"sut_");
00071 XrdOucTrace *sutTrace = 0;
00072
00073
00074
00075
00076
00077 void XrdSutSetTrace(kXR_int32 trace)
00078 {
00079
00080
00081
00082
00083 eDest.logger(&Logger);
00084 if (!sutTrace)
00085 sutTrace = new XrdOucTrace(&eDest);
00086 if (sutTrace) {
00087
00088 sutTrace->What = 0;
00089
00090 if ((trace & sutTRACE_Notify))
00091 sutTrace->What |= sutTRACE_Notify;
00092
00093 if ((trace & sutTRACE_Debug))
00094 sutTrace->What |= (sutTRACE_Notify | sutTRACE_Debug);
00095
00096 if ((trace & sutTRACE_Dump))
00097 sutTrace->What |= sutTRACE_ALL;
00098 }
00099 }
00100
00101
00102
00103
00104
00105 const char *XrdSutBuckStr(int kbck)
00106 {
00107
00108 static const char *ukn = "Unknown";
00109
00110 kbck = (kbck < 0) ? 0 : kbck;
00111 kbck = (kbck > kXRS_reserved) ? 0 : kbck;
00112 kbck = (kbck >= kXRS_cryptomod) ? (kbck - kXRS_cryptomod + 2) : kbck;
00113
00114 if (kbck < 0 || kbck > (kXRS_reserved - kXRS_cryptomod + 2))
00115 return ukn;
00116 else
00117 return gXRSBucketTypes[kbck];
00118 }
00119
00120
00121
00122
00123
00124 volatile void *XrdSutMemSet(volatile void *dst, int c, int len)
00125 {
00126
00127
00128
00129 volatile char *buf;
00130
00131 for (buf = (volatile char *)dst; len; buf[--len] = c);
00132 return dst;
00133 }
00134
00135 #ifndef USE_EXTERNAL_GETPASS
00136
00137
00138
00139
00140 int XrdSutGetPass(const char *prompt, XrdOucString &passwd)
00141 {
00142
00143
00144
00145
00146
00147 EPNAME("GetPass");
00148
00149 char *pw = getpass(prompt);
00150 if (pw) {
00151
00152 int k = 0, i = 0, len = strlen(pw);
00153 for (; i<len ; i++)
00154 if (pw[i] > 0x20) pw[k++] = pw[i];
00155 pw[k] = 0;
00156 passwd = pw;
00157 XrdSutMemSet((volatile void *)pw,0,len);
00158 } else {
00159 DEBUG("error from getpass");
00160 return -1;
00161 }
00162 return 0;
00163 }
00164 #endif
00165
00166
00167
00168
00169 int XrdSutGetLine(XrdOucString &line, const char *prompt)
00170 {
00171
00172
00173
00174
00175 char bin[XrdSutMAXBUF] = {0};
00176
00177
00178 if (prompt)
00179 cout << prompt;
00180
00181
00182 cin.getline(bin,XrdSutMAXBUF-1);
00183
00184
00185 line = bin;
00186
00187 return line.length();
00188 }
00189
00190
00191
00192
00193 bool XrdSutAskConfirm(const char *msg1, bool defact, const char *msg2)
00194 {
00195
00196
00197
00198
00199
00200
00201 bool rc = defact;
00202
00203 if (msg2)
00204 cout << msg2;
00205 XrdOucString ask;
00206 XrdOucString prompt = defact ? " [y]: " : " [n]: ";
00207 if (msg1)
00208 prompt.insert(msg1,0);
00209 XrdSutGetLine(ask,prompt.c_str());
00210 ask.lower(0);
00211 if (ask.length()) {
00212 if (defact && (ask == 'n' || ask == "no")) {
00213 rc = 0;
00214 } else if (!defact && (ask == 'y' || ask == "yes")) {
00215 rc = 1;
00216 }
00217 }
00218
00219 return rc;
00220 }
00221
00222
00223
00224
00225 int XrdSutToHex(const char *in, int lin, char *out)
00226 {
00227
00228
00229
00230
00231
00232
00233
00234 if (!in || !out) {
00235 errno = EINVAL;
00236 return -1;
00237 }
00238
00239 int lbuf = 2*lin+1;
00240 int i = 0;
00241 out[0] = 0;
00242 for ( ; i < lin; i++)
00243 sprintf(out,"%s%02x",out,(0xFF & in[i]));
00244
00245 out[lbuf-1] = 0;
00246
00247
00248 return 0;
00249 }
00250
00251
00252
00253
00254 int XrdSutFromHex(const char *in, char *out, int &lout)
00255 {
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 lout = 0;
00266 if (!in || !out) {
00267 errno = EINVAL;
00268 return -1;
00269 }
00270
00271 int lin = strlen(in);
00272 char st[3] = {0};
00273 int i = 0, k = 0;
00274 for ( ; i<lin; i += 2) {
00275 st[0] = in[i];
00276 st[1] = ((i+1) < lin) ? in[i+1] : 0;
00277 int c;
00278 sscanf(st,"%x",&c);
00279 out[k++] = (char)(0x000000FF & c);
00280 }
00281
00282 lout = k;
00283
00284 return 0;
00285 }
00286
00287
00288
00289
00290
00291 int XrdSutTimeString(int t, char *st, int opt)
00292 {
00293
00294
00295
00296
00297
00298 static char month[12][4] = {"Jan","Feb","Mar","Apr","May","Jun",
00299 "Jul","Aug","Sep","Oct","Nov","Dec"};
00300 static short flen = strlen("24Apr2006:09:10:23");
00301
00302
00303 if (t == -1)
00304 return (flen+1);
00305
00306
00307 if (t < 0 || !st)
00308 return -1;
00309
00310
00311 struct tm tst;
00312 time_t ttmp = t;
00313 if (!localtime_r(&ttmp,&tst))
00314 return -2;
00315
00316
00317 if (opt == 1) {
00318 sprintf(st,"%2d%3s%4d-%2d%2d%2d",tst.tm_mday,month[tst.tm_mon],
00319 1900+tst.tm_year,
00320 tst.tm_hour,tst.tm_min,tst.tm_sec);
00321
00322 st[flen-2] = '\0';
00323 } else {
00324 sprintf(st,"%2d%3s%4d:%2d:%2d:%2d",tst.tm_mday,month[tst.tm_mon],
00325 1900+tst.tm_year,
00326 tst.tm_hour,tst.tm_min,tst.tm_sec);
00327 }
00328
00329
00330 if (st[0] == 0x20) st[0] = 0x30;
00331 int i = 10;
00332 for (; i <= 16; i++ )
00333 if (st[i] == 0x20) st[i] = 0x30;
00334
00335
00336
00337 st[flen] = 0;
00338
00339
00340 return 0;
00341 }
00342
00343
00344
00345
00346 int XrdSutExpand(XrdOucString &path)
00347 {
00348
00349
00350
00351
00352 EPNAME("Expand");
00353
00354
00355 if (!path.length())
00356 return -EINVAL;
00357
00358
00359 if (path[0] == '/')
00360 return 0;
00361
00362 if (path[0] == '~') {
00363 XrdOucString unam, home;
00364 XrdOucString sdir(path);
00365 int iu = path.find('/');
00366 if (iu != STR_NPOS) {
00367 if (iu > 1)
00368 unam.assign(path, 1, iu-1);
00369 sdir.erase(0, iu);
00370 } else
00371 sdir = '/';
00372 if (unam.length() > 0) {
00373 struct passwd *pw = 0;
00374 if (!(pw = getpwnam(unam.c_str()))) {
00375 DEBUG("cannot pwnam information for local user "<<
00376 ((unam.length() > 0) ? unam : XrdOucString("")));
00377 return -errno;
00378 }
00379 home = pw->pw_dir;
00380 } else
00381 home = XrdSutHome();
00382 if (home.length() > 0) {
00383 sdir.insert(home.c_str(),0);
00384 path = sdir;
00385 }
00386 } else {
00387
00388 char *pwd = getenv("PWD");
00389 if (pwd) {
00390 path.insert('/',0);
00391 path.insert(pwd,0);
00392 path.erase("//");
00393 } else {
00394 DEBUG("PWD undefined ");
00395 return -ENOENT;
00396 }
00397 }
00398 return 0;
00399 }
00400
00401
00402
00403
00404 int XrdSutResolve(XrdOucString &path,
00405 const char *ho, const char *vo, const char *gr, const char *us)
00406 {
00407
00408
00409
00410
00411 if (!path.length())
00412 return -EINVAL;
00413
00414
00415 if (path.find("<") == STR_NPOS)
00416 return 0;
00417
00418
00419 if (ho && strlen(ho) > 0) path.replace("<host>", ho);
00420
00421
00422 if (vo && strlen(vo) > 0) path.replace("<vo>", vo);
00423
00424
00425 if (gr && strlen(gr) > 0) path.replace("<group>", gr);
00426
00427
00428 if (us && strlen(us) > 0) path.replace("<user>", us);
00429
00430
00431 return 0;
00432 }
00433
00434
00435
00436
00437 const char *XrdSutHome()
00438 {
00439
00440 EPNAME("Home");
00441
00442
00443 static XrdOucString homedir;
00444 if (homedir.length() <= 0) {
00445
00446 if (getenv("HOME"))
00447 homedir = getenv("HOME");
00448 if (homedir.length() <= 0) {
00449 struct passwd *pw = getpwuid(getuid());
00450 homedir = pw->pw_dir;
00451 }
00452 if (homedir.length() <= 0)
00453 DEBUG("Warning: home directory undefined! ");
00454 }
00455
00456
00457 return homedir.c_str();
00458 }
00459
00460
00461
00462
00463
00464 int XrdSutMkdir(const char *dir, unsigned int mode, const char *opt)
00465 {
00466
00467
00468
00469
00470 if (!dir) {
00471 errno = EINVAL;
00472 return -1;
00473 }
00474
00475 if (!strncmp(opt,"-p",2)) {
00476
00477
00478 XrdOucString dd(dir);
00479 XrdSutExpand(dd);
00480 if (dd[dd.length()-1] != '/')
00481 dd.append('/');
00482 int lsl = dd.find('/',1);
00483 while (lsl > -1) {
00484 XrdOucString pd(dd,0,lsl-1);
00485 struct stat st;
00486 if (stat(pd.c_str(),&st) == -1) {
00487 if (errno == ENOENT) {
00488
00489 if (mkdir(pd.c_str(),mode) != 0)
00490 return -1;
00491 } else {
00492 return -1;
00493 }
00494 }
00495
00496 lsl = dd.find('/',lsl+1);
00497 }
00498
00499 } else {
00500 return mkdir(dir,mode);
00501 }
00502
00503 return 0;
00504 }
00505
00506
00507
00508
00509
00510
00511 int XrdSutParseTime(const char *tstr, int opt)
00512 {
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 EPNAME("ParseTime");
00525
00526 XrdOucString ts = tstr;
00527 XrdOucString fr = "";
00528 int i = 0;
00529 int tsec = 0;
00530
00531 if (ts.length()) {
00532 int ls = 0;
00533 int ld = ts.find(':',1);
00534 ld = (ld == -1) ? ts.length() - 1 : ld;
00535 while (ld >= ls) {
00536 fr.assign(ts, ls, ld);
00537 fr.erase(":");
00538
00539 if (opt == 0) {
00540 if (fr.length() > 1) {
00541
00542 char u = fr[fr.length()-1];
00543 fr.erase(fr.length()-1);
00544 if (u == 'y') {
00545 tsec += atoi(fr.c_str())*31536000;
00546 } else if (u == 'd') {
00547 tsec += atoi(fr.c_str())*86400;
00548 } else if (u == 'h') {
00549 tsec += atoi(fr.c_str())*3600;
00550 } else if (u == 'm') {
00551 tsec += atoi(fr.c_str())*60;
00552 } else if (u == 's') {
00553 tsec += atoi(fr.c_str());
00554 } else {
00555 DEBUG("unknown unit: "<<u);
00556 }
00557 } else {
00558 DEBUG("Incomplete fraction: "<<fr.c_str());
00559 }
00560 } else {
00561 if (i == 0) {
00562 tsec += atoi(fr.c_str())*3600;
00563 } else if (i == 1) {
00564 tsec += atoi(fr.c_str())*60;
00565 } else if (i == 2) {
00566 tsec += atoi(fr.c_str());
00567 }
00568 }
00569 i++;
00570 ls = ld + 1;
00571 ld = ts.find(':',ls);
00572 ld = (ld == -1) ? ts.length() - 1 : ld;
00573 }
00574 }
00575 return tsec;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 XrdSutFileLocker::XrdSutFileLocker(int fd, ELockType lock)
00593 {
00594
00595
00596
00597 valid = 0;
00598 fdesk = fd;
00599
00600
00601 int lockmode = (lock == XrdSutFileLocker::kExcl) ? (F_WRLCK | F_RDLCK)
00602 : F_RDLCK;
00603 #ifdef __macos__
00604 struct flock flck = {0, 0, 0, lockmode, SEEK_SET};
00605 #else
00606 struct flock flck = {lockmode, SEEK_SET, 0, 0};
00607 #endif
00608 if (fcntl(fdesk, F_SETLK, &flck) != 0)
00609
00610 return;
00611
00612
00613 valid = 1;
00614 }
00615
00616 XrdSutFileLocker::~XrdSutFileLocker()
00617 {
00618
00619
00620 if (fdesk < 0 || !IsValid())
00621 return;
00622
00623
00624 #ifdef __macos__
00625 struct flock flck = {0, 0, 0, F_UNLCK, SEEK_SET};
00626 #else
00627 struct flock flck = {F_UNLCK, SEEK_SET, 0, 0};
00628 #endif
00629 fcntl(fdesk, F_SETLK, &flck);
00630 }
00631