TXNetSystem.cxx

Go to the documentation of this file.
00001 // @(#)root/netx:$Id: TXNetSystem.cxx 36197 2010-10-08 13:35:03Z rdm $
00002 // Author: Frank Winklmeier, Fabrizio Furano
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TXNetSystem                                                          //
00015 //                                                                      //
00016 // Authors: Frank Winklmeier,  Fabrizio Furano                          //
00017 //          INFN Padova, 2005                                           //
00018 //                                                                      //
00019 // TXNetSystem is an extension of TNetSystem able to deal with new      //
00020 // xrootd servers. The class detects the nature of the server and       //
00021 // redirects the calls to TNetSystem in case of a rootd server.         //
00022 //                                                                      //
00023 //////////////////////////////////////////////////////////////////////////
00024 
00025 #include "TEnv.h"
00026 #include "TFileStager.h"
00027 #include "TObjString.h"
00028 #include "TROOT.h"
00029 #include "TSocket.h"
00030 #include "TString.h"
00031 #include "TUrl.h"
00032 #include "TVirtualMutex.h"
00033 #include "TXNetFile.h"
00034 #include "TXNetSystem.h"
00035 
00036 #include "XrdClient/XrdClientAdmin.hh"
00037 #include "XrdClient/XrdClientConn.hh"
00038 #include <XrdClient/XrdClientConst.hh>
00039 #include "XrdClient/XrdClientEnv.hh"
00040 #include "XProtocol/XProtocol.hh"
00041 
00042 
00043 ClassImp(TXNetSystem);
00044 
00045 Bool_t TXNetSystem::fgInitDone = kFALSE;
00046 Bool_t TXNetSystem::fgRootdBC = kTRUE;
00047 #ifndef OLDXRDLOCATE
00048 THashList TXNetSystem::fgAddrFQDN;
00049 THashList TXNetSystem::fgAdminHash;
00050 #endif
00051 
00052 //_____________________________________________________________________________
00053 TXNetSystem::TXNetSystem(Bool_t owner) : TNetSystem(owner)
00054 {
00055    // Create system management class without connecting to server.
00056 
00057    SetTitle("(x)rootd system administration");
00058    fIsXRootd = kFALSE;
00059    fDir = "";
00060    fDirp = 0;
00061    fDirListValid = kFALSE;
00062    fUrl = "";
00063 }
00064 
00065 //_____________________________________________________________________________
00066 TXNetSystem::TXNetSystem(const char *url, Bool_t owner) : TNetSystem(owner)
00067 {
00068    // Create system management class and connect to server specified by url.
00069 
00070    SetTitle("(x)rootd system administration");
00071    fIsRootd = kFALSE;
00072    fIsXRootd = kFALSE;
00073    fDir = "";
00074    fDirp = 0;
00075    fDirListValid = kFALSE;
00076    fUrl = url;
00077 
00078 #ifndef OLDXRDLOCATE
00079    fgAddrFQDN.SetOwner();
00080    fgAdminHash.SetOwner();
00081 #endif
00082 
00083    // Set debug level
00084    EnvPutInt(NAME_DEBUG, gEnv->GetValue("XNet.Debug", -1));
00085 
00086    // The first time do some global initialization
00087    if (!fgInitDone)
00088       InitXrdClient();
00089 
00090    // Fill in user, host, port
00091    TNetSystem::InitRemoteEntity(url);
00092 
00093    TXNetSystemConnectGuard cguard(this, url);
00094    if (!cguard.IsValid() && !fIsRootd)
00095       Error("TXNetSystem","fatal error: connection creation failed.");
00096 
00097    return;
00098 }
00099 
00100 //_____________________________________________________________________________
00101 XrdClientAdmin *TXNetSystem::Connect(const char *url)
00102 {
00103    // Init a connection to the server.
00104    // Returns a pointer to the appropriate instance of XrdClientAdmin or 0
00105    // in case of failure.
00106 
00107    // We need a dummy filename after the server url to connect
00108    TString dummy = url;
00109    dummy += "/dummy";
00110 
00111 #ifndef OLDXRDLOCATE
00112    XrdClientAdmin *cadm = TXNetSystem::GetClientAdmin(dummy);
00113 #else
00114    XrdClientAdmin *cadm = XrdClientAdmin::GetClientAdmin(dummy);
00115 #endif
00116 
00117    if (!cadm) {
00118       Error("Connect","fatal error: new object creation failed.");
00119       return cadm;
00120    }
00121 
00122    // Do not block: restore old value after
00123    Int_t maxOld = EnvGetLong(NAME_FIRSTCONNECTMAXCNT);
00124 
00125    // Try to connect to the server
00126    gEnv->SetValue("XNet.FirstConnectMaxCnt", 1);
00127    EnvPutInt(NAME_FIRSTCONNECTMAXCNT, 1);
00128    if (cadm->Connect()) {
00129       fIsXRootd = kTRUE;
00130       EnvPutInt(NAME_FIRSTCONNECTMAXCNT, maxOld);
00131    } else {
00132       EnvPutInt(NAME_FIRSTCONNECTMAXCNT, maxOld);
00133       if (fgRootdBC) {
00134          Bool_t isRootd =
00135             (cadm->GetClientConn()->GetServerType() == kSTRootd);
00136          Int_t sd = cadm->GetClientConn()->GetOpenSockFD();
00137          if (isRootd && sd > -1) {
00138             //
00139             // Create a TSocket on the open connection
00140             TSocket *s = new TSocket(sd);
00141 
00142             // We will clean it by ourselves
00143             R__LOCKGUARD2(gROOTMutex);
00144             gROOT->GetListOfSockets()->Remove(s);
00145 
00146             s->SetOption(kNoBlock, 0);
00147 
00148             // Find out the remote protocol (send the client protocol first)
00149             Int_t rproto = TXNetFile::GetRootdProtocol(s);
00150             if (rproto < 0) {
00151                Error("TXNetSystem", "getting protocol of the rootd server");
00152                cadm = 0;
00153                return 0;
00154             }
00155             // Finalize TSocket initialization
00156             s->SetRemoteProtocol(rproto);
00157             TUrl uut((cadm->GetClientConn()
00158                              ->GetCurrentUrl()).GetUrl().c_str());
00159             TString uu;
00160             TXNetFile::FormUrl(uut,uu);
00161             if (gDebug > 2)
00162                Info("Connect"," url: %s",uu.Data());
00163 
00164             s->SetUrl(uu.Data());
00165             s->SetService("rootd");
00166             s->SetServType(TSocket::kROOTD);
00167             //
00168             // Now we can check if we can create a TNetFile on the
00169             // open connection
00170             if (rproto > 13) {
00171                //
00172                // Remote support for reuse of open connection
00173                TNetSystem::Create(uu, s);
00174             } else {
00175                //
00176                // Open connection has been closed because could
00177                // not be reused; TNetSystem will open a new connection
00178                TNetSystem::Create(uu);
00179             }
00180 
00181             // Type of server
00182             fIsRootd = kTRUE;
00183             cadm = 0;
00184 
00185          } else {
00186             Error("Connect", "some severe error occurred while opening"
00187                   " the connection at %s - exit", url);
00188             cadm = 0;
00189             return cadm;
00190          }
00191       } else {
00192          Error("Connect",
00193                "while opening the connection at %s - exit", url);
00194          cadm = 0;
00195          return cadm;
00196       }
00197    }
00198 
00199    return cadm;
00200 }
00201 
00202 //_____________________________________________________________________________
00203 void TXNetSystem::InitXrdClient()
00204 {
00205    // One-time initialization of some communication variables for xrootd protocol
00206 
00207    // Init vars with default debug level -1, so we do not get warnings
00208    TXNetFile::SetEnv();
00209 
00210 #if defined(OLDXRDLOCATE) && !defined(OLDXRDOUC)
00211    // Use optimized connections
00212    XrdClientAdmin::SetAdminConn();
00213 #endif
00214 
00215    // Only once
00216    fgInitDone = kTRUE;
00217 
00218    // Print the tag, if required (only once)
00219    if (gEnv->GetValue("XNet.PrintTAG",0) == 1)
00220      Info("TXNetFile","(C) 2005 SLAC TXNetSystem (eXtended TNetSystem) %s",
00221          gROOT->GetVersion());
00222 }
00223 
00224 //_____________________________________________________________________________
00225 void* TXNetSystem::OpenDirectory(const char* dir)
00226 {
00227    // Open a directory. Returns a non-zero pointer (with no special
00228    // purpose) in case of success, 0 in case of error.
00229 
00230    if (fIsXRootd) {
00231       // Check if the directory exists
00232       TXNetSystemConnectGuard cg(this, dir);
00233       if (cg.IsValid()) {
00234          fUrl = dir;
00235          // Extract the directory name
00236          fDir = TUrl(dir).GetFile();
00237          fDirp = (void*)&fDir;     // serves as directory pointer
00238 
00239          vecString dirs;
00240          vecBool existDirs;
00241          XrdOucString s(fDir.Data());
00242          dirs.Push_back(s);
00243          cg.ClientAdmin()->ExistDirs(dirs, existDirs);
00244          cg.ClientAdmin()->GoBackToRedirector();
00245          if (existDirs.GetSize()>0 && existDirs[0])
00246             return fDirp;
00247          else
00248             cg.NotifyLastError();
00249       }
00250       return 0;
00251    }
00252 
00253    if (gDebug > 1)
00254       Info("OpenDirectory", "calling TNetSystem::OpenDirectory");
00255    return TNetSystem::OpenDirectory(dir);       // for a rootd
00256 }
00257 
00258 //_____________________________________________________________________________
00259 void TXNetSystem::FreeDirectory(void *dirp)
00260 {
00261    // Free(Close) the directory referenced by dirp
00262 
00263    if (fIsXRootd) {
00264       if (dirp != fDirp) {
00265          Error("FreeDirectory","invalid directory pointer (%p, %p)", dirp, fDirp);
00266          return;
00267       }
00268       fDir = "";
00269       fDirp = 0;
00270       fDirListValid = kFALSE;
00271       fDirEntry = "";
00272       fDirList.Clear();
00273       return;
00274    }
00275 
00276    if (gDebug > 1)
00277       Info("FreeDirectory","calling TNetSystem::FreeDirectory");
00278    return TNetSystem::FreeDirectory(dirp);     // for a rootd
00279 }
00280 
00281 //_____________________________________________________________________________
00282 Int_t TXNetSystem::MakeDirectory(const char* dir)
00283 {
00284    // Create a directory. Return 0 on success, -1 otherwise.
00285 
00286    if (fIsXRootd) {
00287       TXNetSystemConnectGuard cg(this, dir);
00288       if (cg.IsValid()) {
00289          // use default permissions 755 to create directory
00290          Bool_t ok = cg.ClientAdmin()->Mkdir(TUrl(dir).GetFile(),7,5,5);
00291          cg.ClientAdmin()->GoBackToRedirector();
00292          if (ok) {
00293             return 0;
00294          } else {
00295             cg.NotifyLastError();
00296             return -1;
00297          }
00298       }
00299    }
00300 
00301    if (gDebug > 1)
00302       Info("MakeDirectory","Calling TNetSystem::MakeDirectory");
00303    return TNetSystem::MakeDirectory(dir);     // for a rootd
00304 }
00305 
00306 //_____________________________________________________________________________
00307 const char* TXNetSystem::GetDirEntry(void *dirp)
00308 {
00309    // Get directory entry for directory referenced by dirp.
00310    // Returns 0 in case there are no more entries.
00311 
00312    if (fIsXRootd) {
00313       if (dirp != fDirp) {
00314          Error("GetDirEntry","invalid directory pointer");
00315          return 0;
00316       }
00317 
00318       // Only request new directory listing the first time called
00319       if (!fDirListValid) {
00320          TXNetSystemConnectGuard cg(this, fUrl);
00321          if (cg.IsValid()) {
00322             Bool_t ok = cg.ClientAdmin()->DirList(fDir, fDirList);
00323             cg.ClientAdmin()->GoBackToRedirector();
00324             if (ok) {
00325                fDirListValid = kTRUE;
00326             } else {
00327                cg.NotifyLastError();
00328                return 0;
00329             }
00330          }
00331       }
00332 
00333       // Return entries one by one with each call of method
00334       if (fDirList.GetSize() > 0) {
00335          fDirEntry = fDirList.Pop_front().c_str();
00336          return fDirEntry.Data();
00337       }
00338       return 0;   // until all of them have been returned
00339    }
00340 
00341    if (gDebug > 1) Info("GetDirEntry","Calling TNetSystem::GetDirEntry");
00342    return TNetSystem::GetDirEntry(dirp);      // for a rootd
00343 }
00344 
00345 //_____________________________________________________________________________
00346 Int_t TXNetSystem::GetPathInfo(const char* path, FileStat_t &buf)
00347 {
00348    // Get info about a file. Info is returned in the form of a FileStat_t
00349    // structure (see TSystem.h).
00350    // The function returns 0 in case of success and 1 if the file could
00351    // not be stat'ed.
00352    // NOTICE: Not all information is available with an xrootd server.
00353 
00354    if (fIsXRootd) {
00355       TXNetSystemConnectGuard cg(this, path);
00356       if (cg.IsValid()) {
00357 
00358          Long_t id;
00359          Long64_t size;
00360          Long_t flags;
00361          Long_t modtime;
00362 
00363          // Issue the request
00364          TUrl urlpath(path);
00365          Bool_t ok = cg.ClientAdmin()->Stat(urlpath.GetFile(),id,size,flags,modtime);
00366          if (ok) {
00367             // Save the endpoint path
00368             urlpath.SetProtocol(cg.ClientAdmin()->GetCurrentUrl().Proto.c_str());
00369             urlpath.SetHost(cg.ClientAdmin()->GetCurrentUrl().Host.c_str());
00370             urlpath.SetPort(cg.ClientAdmin()->GetCurrentUrl().Port);
00371             buf.fUrl = urlpath.GetUrl();
00372          }
00373          cg.ClientAdmin()->GoBackToRedirector();
00374 
00375          // Flag offline files
00376          if (flags & kXR_offline) {
00377             buf.fMode = kS_IFOFF;
00378          } else if (ok) {
00379             buf.fDev = (id >> 24);
00380             buf.fIno = (id & 0x00FFFFFF);
00381             buf.fUid = -1;       // not all information available in xrootd
00382             buf.fGid = -1;       // not available
00383             buf.fSize = size;
00384             buf.fMtime = modtime;
00385 
00386             if (flags == 0) buf.fMode = kS_IFREG;
00387             if (flags & kXR_xset) buf.fMode = (kS_IFREG|kS_IXUSR|kS_IXGRP|kS_IXOTH);
00388             if (flags & kXR_isDir) buf.fMode = kS_IFDIR;
00389             if (flags & kXR_other) buf.fMode = kS_IFSOCK;
00390             if (flags & kXR_readable) buf.fMode |= kS_IRUSR;
00391             if (flags & kXR_writable) buf.fMode |= kS_IWUSR;
00392 
00393             buf.fIsLink = 0;     // not available
00394             return 0;
00395          } else {
00396             if (gDebug > 0)
00397                cg.NotifyLastError();
00398          }
00399       }
00400       return 1;
00401    }
00402 
00403    if (gDebug > 1)
00404       Info("GetPathInfo","Calling TNetSystem::GetPathInfo");
00405    return TNetSystem::GetPathInfo(path,buf);       // for a rootd
00406 }
00407 
00408 //_____________________________________________________________________________
00409 Bool_t TXNetSystem::ConsistentWith(const char *path, void *dirptr)
00410 {
00411    // Check consistency of this helper with the one required
00412    // by 'path' or 'dirptr'.
00413 
00414    if (gDebug > 1)
00415       Info("ConsistentWith",
00416            "calling for path: %s, dir: %p", path, dirptr);
00417 
00418    return TNetSystem::ConsistentWith(path,dirptr);    // for a rootd
00419 }
00420 
00421 //_____________________________________________________________________________
00422 Bool_t TXNetSystem::AccessPathName(const char *path, EAccessMode mode)
00423 {
00424    // Returns FALSE if one can access a file using the specified access mode.
00425    // NB: for the time being mode is ignored for XROOTD (just checks existence
00426    // of the file or directory).
00427    // Mode is the same as for the Unix access(2) function.
00428    // Attention, bizarre convention of return value!!
00429 
00430    if (fIsXRootd) {
00431       // Check only if the file or directory exists and
00432       FileStat_t buf;
00433       if (GetPathInfo(path, buf) == 0)
00434          if (buf.fMode != kS_IFSOCK)
00435             return kFALSE;
00436       // The file could not be stated
00437       return kTRUE;
00438    }
00439 
00440    if (gDebug > 1)
00441       Info("AccessPathName", "calling TNetSystem::AccessPathName");
00442    return TNetSystem::AccessPathName(path,mode);    // for a rootd
00443 }
00444 
00445 //_____________________________________________________________________________
00446 int TXNetSystem::Unlink(const char *path)
00447 {
00448    // Unlink 'path' on the remote server system.
00449    // Returns 0 on success, -1 otherwise.
00450 
00451    if (fIsXRootd) {
00452 
00453       TXNetSystemConnectGuard cg(this, path);
00454       if (cg.IsValid()) {
00455 
00456          Long_t id;
00457          Long64_t size;
00458          Long_t flags;
00459          Long_t modtime;
00460 
00461          // Extract the directory name
00462          TString edir = TUrl(path).GetFile();
00463          Bool_t ok = cg.ClientAdmin()->Stat(edir.Data(), id, size, flags, modtime);
00464 
00465          // Flag offline files
00466          if (ok && !(flags & kXR_offline)) {
00467             if (flags & kXR_isDir)
00468                ok = cg.ClientAdmin()->Rmdir(edir.Data());
00469             else
00470                ok = cg.ClientAdmin()->Rm(edir.Data());
00471             cg.ClientAdmin()->GoBackToRedirector();
00472 
00473             // Done
00474             return ((ok) ? 0 : -1);
00475          } else if (!ok) {
00476             cg.ClientAdmin()->GoBackToRedirector();
00477             cg.NotifyLastError();
00478          }
00479       }
00480    }
00481 
00482    if (gDebug > 1)
00483       Info("Unlink", "calling TNetSystem::Unlink");
00484    return -1;    // not implemented for rootd
00485 }
00486 
00487 //_____________________________________________________________________________
00488 Bool_t TXNetSystem::IsOnline(const char *path)
00489 {
00490    // Check if the file defined by 'path' is ready to be used
00491 
00492    // This is most efficiently done using GetPathInfo
00493    FileStat_t st;
00494    if (GetPathInfo(path, st) != 0) {
00495       if (gDebug > 0)
00496          Info("IsOnline", "path '%s' cannot be stat'ed", path);
00497       return kFALSE;
00498    }
00499    if (R_ISOFF(st.fMode)) {
00500       if (gDebug > 0)
00501          Info("IsOnline", "path '%s' is offline", path);
00502       return kFALSE;
00503    }
00504    // Done
00505    return kTRUE;
00506 }
00507 
00508 //_____________________________________________________________________________
00509 Bool_t TXNetSystem::Prepare(const char *path, UChar_t option, UChar_t priority)
00510 {
00511    // Issue a prepare request for file defined by 'path'
00512 
00513    TXNetSystemConnectGuard cg(this, path);
00514    if (cg.IsValid()) {
00515       XrdOucString pathname = TUrl(path).GetFileAndOptions();
00516       vecString vs;
00517       vs.Push_back(pathname);
00518       cg.ClientAdmin()->Prepare(vs, (kXR_char)option, (kXR_char)priority);
00519       cg.ClientAdmin()->GoBackToRedirector();
00520       if (gDebug >0)
00521          Info("Prepare", "Got Status %d for %s",
00522               cg.ClientAdmin()->LastServerResp()->status, pathname.c_str());
00523       if (!(cg.ClientAdmin()->LastServerResp()->status)){
00524          return kTRUE;
00525       }
00526       cg.NotifyLastError();
00527    }
00528 
00529    // Done
00530    return kFALSE;
00531 }
00532 
00533 //_____________________________________________________________________________
00534 Int_t TXNetSystem::Prepare(TCollection *paths,
00535                            UChar_t opt, UChar_t prio, TString *bufout)
00536 {
00537    // Issue a prepare request for a list of files defined by 'paths', which must
00538    // be of one of the following types: TFileInfo, TUrl, TObjString.
00539    // On output, bufout, if defined, points to a buffer form that can be used
00540    // with GetPathsInfo.
00541    // Return the number of paths found or -1 if any error occured.
00542 
00543    if (!paths) {
00544       Warning("Prepare", "input list is empty!");
00545       return -1;
00546    }
00547 
00548    Int_t npaths = 0;
00549 
00550    TXNetSystemConnectGuard cg(this, "");
00551    if (cg.IsValid()) {
00552 
00553       TString *buf = (bufout) ? bufout : new TString();
00554 
00555       // Prepare the buffer
00556       TObject *o = 0;
00557       TUrl u;
00558       TString path;
00559       TIter nxt(paths);
00560       while ((o = nxt()))  {
00561          // Extract the path name from the allowed object types
00562          TString pn = TFileStager::GetPathName(o);
00563          if (pn == "") {
00564             Warning("Prepare", "object is of unexpected type %s - ignoring", o->ClassName());
00565             continue;
00566          }
00567          u.SetUrl(pn);
00568          // The path
00569          path = u.GetFileAndOptions();
00570          path.ReplaceAll("\n","\r");
00571          npaths++;
00572          *buf += Form("%s\n", path.Data());
00573       }
00574 
00575       Info("Prepare","buffer ready: issuing prepare ...");
00576       cg.ClientAdmin()->Prepare(buf->Data(), (kXR_char)opt, (kXR_char)prio);
00577       cg.ClientAdmin()->GoBackToRedirector();
00578       if (!bufout)
00579          delete buf;
00580       if (gDebug >0)
00581          Info("Prepare", "Got Status %d",
00582               cg.ClientAdmin()->LastServerResp()->status);
00583       if (!(cg.ClientAdmin()->LastServerResp()->status)){
00584          return npaths;
00585       }
00586       cg.NotifyLastError();
00587    }
00588 
00589    // Done
00590    return -1;
00591 }
00592 
00593 //_____________________________________________________________________________
00594 Bool_t TXNetSystem::GetPathsInfo(const char *paths, UChar_t *info)
00595 {
00596    // Retrieve status of a '\n'-separated list of files in 'paths'.
00597    // The information is returned as one UChar_t per file in 'info';
00598    // 'info' must be allocated by the caller.
00599 
00600    if (!paths) {
00601       Warning("GetPathsInfo", "input list is empty!");
00602       return kFALSE;
00603    }
00604 
00605    TXNetSystemConnectGuard cg(this, "");
00606    if (cg.IsValid()) {
00607       cg.ClientAdmin()->SysStatX(paths, info);
00608       cg.ClientAdmin()->GoBackToRedirector();
00609       if (gDebug >0)
00610          Info("GetPathsInfo", "Got Status %d",
00611               cg.ClientAdmin()->LastServerResp()->status);
00612       if (!(cg.ClientAdmin()->LastServerResp()->status)){
00613          return kTRUE;
00614       }
00615       cg.NotifyLastError();
00616    }
00617 
00618    // Done
00619    return kFALSE;
00620 }
00621 
00622 //______________________________________________________________________________
00623 Bool_t TXNetSystem::IsPathLocal(const char *path)
00624 {
00625    // Returns TRUE if the url in 'path' points to the local file system.
00626    // This is used to avoid going through the NIC card for local operations.
00627 
00628    if (fIsXRootd) {
00629       TXNetSystemConnectGuard cg(this, path);
00630       if (cg.IsValid()) {
00631          if (cg.ClientAdmin()->GetClientConn()->GetServerType() != kSTDataXrootd) {
00632             // Not an end point data server: cannot assert locality
00633             return kFALSE;
00634          }
00635       }
00636    }
00637    // Either an end-point data server or 'rootd': check for locality
00638    return TSystem::IsPathLocal(path);
00639 }
00640 
00641 //_____________________________________________________________________________
00642 Int_t TXNetSystem::Locate(const char *path, TString &eurl)
00643 {
00644    // Get end-point url of a file. Info is returned in eurl.
00645    // The function returns 0 in case of success and 1 if the file could
00646    // not be stat'ed.
00647 
00648    if (fIsXRootd) {
00649       TXNetSystemConnectGuard cg(this, path);
00650       if (cg.IsValid()) {
00651 
00652 #ifndef OLDXRDLOCATE
00653          // Extract the directory name
00654          XrdClientLocate_Info li;
00655          TString edir = TUrl(path).GetFile();
00656 
00657          if (cg.ClientAdmin()->Locate((kXR_char *)edir.Data(), li)) {
00658             TUrl u(path);
00659             XrdClientUrlInfo ui((const char *)&li.Location[0]);
00660             // We got the IP address but we need the FQDN: if we did not resolve
00661             // it yet do it and cache the result
00662             TNamed *hn = 0;
00663             if (fgAddrFQDN.GetSize() <= 0 ||
00664                !(hn = dynamic_cast<TNamed *>(fgAddrFQDN.FindObject(ui.Host.c_str())))) {
00665                TInetAddress a(gSystem->GetHostByName(ui.Host.c_str()));
00666                if (strlen(a.GetHostName()) > 0)
00667                   hn = new TNamed(ui.Host.c_str(), a.GetHostName());
00668                else
00669                   hn = new TNamed(ui.Host.c_str(), ui.Host.c_str());
00670                fgAddrFQDN.Add(hn);
00671                if (gDebug > 0)
00672                   Info("Locate","caching host name: %s", hn->GetTitle());
00673             }
00674             if (hn)
00675                u.SetHost(hn->GetTitle());
00676             else
00677                u.SetHost(ui.Host.c_str());
00678             u.SetPort(ui.Port);
00679             eurl = u.GetUrl();
00680             return 0;
00681          }
00682 #else
00683          // Extract the directory name
00684          XrdClientUrlInfo ui;
00685          TString edir = TUrl(path).GetFile();
00686 
00687          if (cg.ClientAdmin()->Locate((kXR_char *)edir.Data(), ui, kTRUE)) {
00688             TUrl u(path);
00689             u.SetHost(ui.Host.c_str());
00690             u.SetPort(ui.Port);
00691             eurl = u.GetUrl();
00692             return 0;
00693          }
00694 #endif
00695          cg.NotifyLastError();
00696       }
00697       return 1;
00698    }
00699 
00700    // Not implemented
00701    if (gDebug > 0) Info("Locate", "server not Xrootd: method not implemented!");
00702    return -1;
00703 }
00704 
00705 #ifndef OLDXRDLOCATE
00706 //_____________________________________________________________________________
00707 XrdClientAdmin *TXNetSystem::GetClientAdmin(const char *url)
00708 {
00709    // Checks if an admin for 'url' exists already.
00710    // Avoid duplications.
00711    XrdClientAdmin *ca = 0;
00712 
00713    // ID key
00714    TString key = TXNetSystem::GetKey(url);
00715 
00716    // If we have one for 'key', just use it
00717    TXrdClientAdminWrapper *caw = 0;
00718    if (fgAdminHash.GetSize() > 0 &&
00719       (caw = dynamic_cast<TXrdClientAdminWrapper *>(fgAdminHash.FindObject(key.Data()))))
00720       return caw->fXCA;
00721 
00722    // Create one and save the reference in the hash table
00723    ca = new XrdClientAdmin(url);
00724    fgAdminHash.Add(new TXrdClientAdminWrapper(key, ca));
00725 
00726    // Done
00727    return ca;
00728 }
00729 
00730 //_____________________________________________________________________________
00731 TString TXNetSystem::GetKey(const char *url)
00732 {
00733    // Build from uu a unique ID key used in hash tables
00734 
00735    TUrl u(url);
00736    TString key(u.GetUser());
00737    if (!key.IsNull())
00738       key += "@";
00739    key += u.GetHost();
00740    if (u.GetPort() > 0) {
00741       key += ":";
00742       key += u.GetPort();
00743    }
00744 
00745    // Done
00746    return key;
00747 }
00748 
00749 //
00750 // Wrapper class
00751 //
00752 //_____________________________________________________________________________
00753 TXrdClientAdminWrapper::~TXrdClientAdminWrapper()
00754 {
00755    // Destructor: destroy the instance
00756 
00757    SafeDelete(fXCA);
00758 }
00759 #endif
00760 
00761 //
00762 // Guard methods
00763 //
00764 //_____________________________________________________________________________
00765 TXNetSystemConnectGuard::TXNetSystemConnectGuard(TXNetSystem *xn, const char *url)
00766                         : fClientAdmin(0)
00767 {
00768    // Construct a guard object
00769 
00770     if (xn)
00771        // Connect
00772        fClientAdmin = (url && strlen(url) > 0) ? xn->Connect(url)
00773                                                : xn->Connect(xn->fUrl);
00774 }
00775 
00776 //_____________________________________________________________________________
00777 TXNetSystemConnectGuard::~TXNetSystemConnectGuard()
00778 {
00779    // Destructor: close the connection
00780 
00781    fClientAdmin = 0;
00782 }
00783 
00784 //_____________________________________________________________________________
00785 void TXNetSystemConnectGuard::NotifyLastError()
00786 {
00787    // Print message about last occured error
00788 
00789    if (fClientAdmin)
00790       if (fClientAdmin->GetClientConn())
00791          Printf("Srv err: %s", fClientAdmin->GetClientConn()->LastServerError.errmsg);
00792 }

Generated on Tue Jul 5 14:46:12 2011 for ROOT_528-00b_version by  doxygen 1.5.1