Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 09:29:47

0001 //------------------------------------------------------------------------------
0002 // Copyright (c) 2011-2012 by European Organization for Nuclear Research (CERN)
0003 // Author: Lukasz Janyst <ljanyst@cern.ch>
0004 //------------------------------------------------------------------------------
0005 // XRootD is free software: you can redistribute it and/or modify
0006 // it under the terms of the GNU Lesser General Public License as published by
0007 // the Free Software Foundation, either version 3 of the License, or
0008 // (at your option) any later version.
0009 //
0010 // XRootD is distributed in the hope that it will be useful,
0011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
0012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0013 // GNU General Public License for more details.
0014 //
0015 // You should have received a copy of the GNU Lesser General Public License
0016 // along with XRootD.  If not, see <http://www.gnu.org/licenses/>.
0017 //------------------------------------------------------------------------------
0018 
0019 #ifndef __XRD_CL_UTILS_HH__
0020 #define __XRD_CL_UTILS_HH__
0021 
0022 #include <string>
0023 #include <vector>
0024 #include "XrdCl/XrdClStatus.hh"
0025 #include "XrdCl/XrdClLog.hh"
0026 #include "XrdCl/XrdClURL.hh"
0027 #include "XrdCl/XrdClXRootDResponses.hh"
0028 #include "XrdCl/XrdClPropertyList.hh"
0029 #include "XrdCl/XrdClDefaultEnv.hh"
0030 #include "XrdCl/XrdClConstants.hh"
0031 #include "XrdCl/XrdClPostMaster.hh"
0032 #include "XrdCl/XrdClXRootDTransport.hh"
0033 #include "XrdNet/XrdNetUtils.hh"
0034 #include "XrdOuc/XrdOucTUtils.hh"
0035 
0036 #include <sys/time.h>
0037 
0038 #ifdef __linux__
0039 #include <sys/fsuid.h>
0040 #endif
0041 
0042 namespace XrdCl
0043 {
0044   class Message;
0045 
0046   //----------------------------------------------------------------------------
0047   //! Random utilities
0048   //----------------------------------------------------------------------------
0049   class Utils
0050   {
0051     public:
0052       //------------------------------------------------------------------------
0053       //! Split a string
0054       //------------------------------------------------------------------------
0055       template<class Container>
0056       static void splitString( Container         &result,
0057                                const std::string &input,
0058                                const std::string &delimiter )
0059       {
0060           /*
0061            * This was done in order to not duplicate code as this method
0062            * is also used in XrdHttp
0063            * TODO: Maybe this method could be collapsed
0064            * to avoid this middle-man call here
0065            */
0066           XrdOucTUtils::splitString(result,input,delimiter);
0067       }
0068 
0069       //------------------------------------------------------------------------
0070       //! Get a parameter either from the environment or URL
0071       //------------------------------------------------------------------------
0072       static int GetIntParameter( const URL         &url,
0073                                   const std::string &name,
0074                                   int                defaultVal );
0075 
0076       //------------------------------------------------------------------------
0077       //! Get a parameter either from the environment or URL
0078       //------------------------------------------------------------------------
0079       static std::string GetStringParameter( const URL         &url,
0080                                              const std::string &name,
0081                                              const std::string &defaultVal );
0082 
0083       //------------------------------------------------------------------------
0084       //! Address type
0085       //------------------------------------------------------------------------
0086       enum AddressType
0087       {
0088         IPAuto        = 0,
0089         IPAll         = 1,
0090         IPv6          = 2,
0091         IPv4          = 3,
0092         IPv4Mapped6   = 4
0093       };
0094 
0095       //------------------------------------------------------------------------
0096       //! Interpret a string as address type, default to IPAll
0097       //------------------------------------------------------------------------
0098       static AddressType String2AddressType( const std::string &addressType );
0099 
0100       //------------------------------------------------------------------------
0101       //! Resolve IP addresses
0102       //------------------------------------------------------------------------
0103       static Status GetHostAddresses( std::vector<XrdNetAddr> &addresses,
0104                                       const URL               &url,
0105                                       AddressType              type );
0106 
0107       //------------------------------------------------------------------------
0108       //! Log all the addresses on the list
0109       //------------------------------------------------------------------------
0110       static void LogHostAddresses( Log                     *log,
0111                                     uint64_t                 type,
0112                                     const std::string       &hostId,
0113                                     std::vector<XrdNetAddr> &addresses );
0114 
0115       //------------------------------------------------------------------------
0116       //! Convert timestamp to a string
0117       //------------------------------------------------------------------------
0118       static std::string TimeToString( time_t timestamp );
0119 
0120       //------------------------------------------------------------------------
0121       //! Get the elapsed microseconds between two timevals
0122       //------------------------------------------------------------------------
0123       static uint64_t GetElapsedMicroSecs( timeval start, timeval end );
0124 
0125       //------------------------------------------------------------------------
0126       //! Get a checksum from a remote xrootd server
0127       //------------------------------------------------------------------------
0128       static XRootDStatus GetRemoteCheckSum( std::string       &checkSum,
0129                                              const std::string &checkSumType,
0130                                              const URL         &url );
0131 
0132       //------------------------------------------------------------------------
0133       //! Get a checksum from local file
0134       //------------------------------------------------------------------------
0135       static XRootDStatus GetLocalCheckSum( std::string       &checkSum,
0136                                             const std::string &checkSumType,
0137                                             const std::string &path );
0138 
0139       //------------------------------------------------------------------------
0140       //! Convert bytes to a human readable string
0141       //------------------------------------------------------------------------
0142       static std::string BytesToString( uint64_t bytes );
0143 
0144       //------------------------------------------------------------------------
0145       //! Check if peer supports tpc
0146       //------------------------------------------------------------------------
0147       static XRootDStatus CheckTPC( const std::string &server,
0148                                     uint16_t           timeout = 0 );
0149 
0150       //------------------------------------------------------------------------
0151       //! Check if peer supports tpc / tpc lite
0152       //!
0153       //! @return : suDone if TPC lite is supported, suPartial if plain TPC is
0154       //!           supported, stError otherwise
0155       //------------------------------------------------------------------------
0156       static XRootDStatus CheckTPCLite( const std::string &server,
0157                                         uint16_t           timeout = 0 );
0158 
0159       //------------------------------------------------------------------------
0160       //! Convert the fully qualified host name to country code
0161       //------------------------------------------------------------------------
0162       static std::string FQDNToCC( const std::string &fqdn );
0163 
0164       //------------------------------------------------------------------------
0165       //! Get directory entries
0166       //------------------------------------------------------------------------
0167       static Status GetDirectoryEntries( std::vector<std::string> &entries,
0168                                          const std::string        &path );
0169 
0170       //------------------------------------------------------------------------
0171       //! Process a config file and return key-value pairs
0172       //------------------------------------------------------------------------
0173       static Status ProcessConfig( std::map<std::string, std::string> &config,
0174                                    const std::string                  &file );
0175 
0176       //------------------------------------------------------------------------
0177       //! Process a config directory and return key-value pairs
0178       //------------------------------------------------------------------------
0179       static Status ProcessConfigDir( std::map<std::string, std::string> &config,
0180                                       const std::string                  &dir );
0181 
0182       //------------------------------------------------------------------------
0183       //! Trim a string
0184       //------------------------------------------------------------------------
0185       static void Trim( std::string &str );
0186 
0187       //------------------------------------------------------------------------
0188       //! Log property list
0189       //------------------------------------------------------------------------
0190       static void LogPropertyList( Log                *log,
0191                                    uint64_t            topic,
0192                                    const char         *format,
0193                                    const PropertyList &list );
0194 
0195       //------------------------------------------------------------------------
0196       //! Print a char array as hex
0197       //------------------------------------------------------------------------
0198       static std::string Char2Hex( uint8_t *array, uint16_t size );
0199 
0200       //------------------------------------------------------------------------
0201       //! Normalize checksum
0202       //------------------------------------------------------------------------
0203       static std::string NormalizeChecksum( const std::string &name,
0204                                             const std::string &checksum );
0205 
0206       //------------------------------------------------------------------------
0207       //! Get supported checksum types for given URL
0208       //------------------------------------------------------------------------
0209       static std::vector<std::string> GetSupportedCheckSums( const XrdCl::URL &url );
0210 
0211       //------------------------------------------------------------------------
0212       //! Automatically infer the right checksum type
0213       //!
0214       //! @param source      : source URL
0215       //! @param destination : destination URL
0216       //! @param zip         : true if the source file is being extracted from
0217       //!                      a ZIP archive, false otherwise
0218       //! @return            : checksum type
0219       //------------------------------------------------------------------------
0220       static std::string InferChecksumType( const XrdCl::URL &source,
0221                                             const XrdCl::URL &destination,
0222                                             bool              zip = false );
0223 
0224       //------------------------------------------------------------------------
0225       //! Check if this client can support given EC redirect
0226       //------------------------------------------------------------------------
0227       static bool CheckEC( const Message *req, const URL &url );
0228 
0229       //------------------------------------------------------------------------
0230       //! Get protocol version of the given server
0231       //! @param url     : URL pointing to the server
0232       //! @param protver : protocol version (output parameter)
0233       //! @return        : operation status
0234       //------------------------------------------------------------------------
0235       inline static XrdCl::XRootDStatus GetProtocolVersion( const XrdCl::URL url, int &protver )
0236       {
0237         XrdCl::AnyObject  qryResult;
0238         XrdCl::XRootDStatus st = XrdCl::DefaultEnv::GetPostMaster()->
0239             QueryTransport( url, XrdCl::XRootDQuery::ProtocolVersion, qryResult );
0240         if( !st.IsOK() ) return st;
0241         int *tmp = 0;
0242         qryResult.Get( tmp );
0243         if( !tmp )
0244           return st;
0245         protver = *tmp;
0246         delete tmp;
0247         return XrdCl::XRootDStatus();
0248       }
0249 
0250       //------------------------------------------------------------------------
0251       //! Check if given server supports extended file attributes
0252       //! @param url : URL pointing to the server
0253       //! @return    : true if yes, false otherwise
0254       //------------------------------------------------------------------------
0255       inline static bool HasXAttr( const XrdCl::URL &url )
0256       {
0257         if( url.IsLocalFile() ) return true;
0258         int protver = 0;
0259         auto st = GetProtocolVersion( url, protver );
0260         if( !st.IsOK() ) return false;
0261         return protver >= kXR_PROTXATTVERSION;
0262       }
0263 
0264       //------------------------------------------------------------------------
0265       //! Check if given server supports pgread/pgwrite
0266       //! @param url : URL pointing to the server
0267       //! @return    : true if yes, false otherwise
0268       //------------------------------------------------------------------------
0269       inline static bool HasPgRW( const XrdCl::URL &url )
0270       {
0271         if( url.IsLocalFile() ) return false;
0272         int protver = 0;
0273         auto st = GetProtocolVersion( url, protver );
0274         if( !st.IsOK() ) return false;
0275         return protver >= kXR_PROTPGRWVERSION;
0276       }
0277 
0278       //------------------------------------------------------------------------
0279       //! Split chunks in a ChunkList into one or more ChunkLists
0280       //! @param listsvec        : output vector of ChunkLists
0281       //! @param chunks          : input ChunkLisits
0282       //! @param maxcs           : maximum size of a ChunkInfo in output
0283       //! @param maxc            : maximum number of ChunkInfo in each ChunkList
0284       //------------------------------------------------------------------------
0285       static void SplitChunks( std::vector<ChunkList> &listsvec,
0286                                const ChunkList        &chunks,
0287                                const uint32_t          maxcs,
0288                                const size_t            maxc );
0289   };
0290 
0291   //----------------------------------------------------------------------------
0292   //! Smart descriptor - closes the descriptor on destruction
0293   //----------------------------------------------------------------------------
0294   class ScopedDescriptor
0295   {
0296     public:
0297       //------------------------------------------------------------------------
0298       //! Constructor
0299       //------------------------------------------------------------------------
0300       ScopedDescriptor( int descriptor ): pDescriptor( descriptor ) {}
0301 
0302       //------------------------------------------------------------------------
0303       //! Destructor
0304       //------------------------------------------------------------------------
0305       ~ScopedDescriptor() { if( pDescriptor >= 0 ) close( pDescriptor ); }
0306 
0307       //------------------------------------------------------------------------
0308       //! Release the descriptor being held
0309       //------------------------------------------------------------------------
0310       int Release()
0311       {
0312         int desc = pDescriptor;
0313         pDescriptor = -1;
0314         return desc;
0315       }
0316 
0317       //------------------------------------------------------------------------
0318       //! Get the descriptor
0319       //------------------------------------------------------------------------
0320       int GetDescriptor()
0321       {
0322         return pDescriptor;
0323       }
0324 
0325     private:
0326       int pDescriptor;
0327   };
0328 
0329 #ifdef __linux__
0330   //----------------------------------------------------------------------------
0331   //! Scoped fsuid and fsgid setter, restoring original values on destruction
0332   //----------------------------------------------------------------------------
0333   class ScopedFsUidSetter
0334   {
0335     public:
0336       //------------------------------------------------------------------------
0337       //! Constructor
0338       //------------------------------------------------------------------------
0339       ScopedFsUidSetter(uid_t fsuid, gid_t fsgid, const std::string &streamName)
0340       : pFsUid(fsuid), pFsGid(fsgid), pStreamName(streamName)
0341       {
0342         pOk = true;
0343         pPrevFsUid = -1;
0344         pPrevFsGid = -1;
0345 
0346         //----------------------------------------------------------------------
0347         //! Set fsuid
0348         //----------------------------------------------------------------------
0349         if(pFsUid >= 0) {
0350           pPrevFsUid = setfsuid(pFsUid);
0351 
0352           if(setfsuid(pFsUid) != pFsUid) {
0353             pOk = false;
0354             return;
0355           }
0356         }
0357 
0358         //----------------------------------------------------------------------
0359         //! Set fsgid
0360         //----------------------------------------------------------------------
0361         if(pFsGid >= 0) {
0362           pPrevFsGid = setfsgid(pFsGid);
0363 
0364           if(setfsgid(pFsGid) != pFsGid) {
0365             pOk = false;
0366             return;
0367           }
0368         }
0369       }
0370 
0371       //------------------------------------------------------------------------
0372       //! Destructor
0373       //------------------------------------------------------------------------
0374       ~ScopedFsUidSetter() {
0375         Log *log = DefaultEnv::GetLog();
0376 
0377         if(pPrevFsUid >= 0) {
0378           int retcode = setfsuid(pPrevFsUid);
0379           log->Dump(XRootDTransportMsg, "[%s] Restored fsuid from %d to %d", pStreamName.c_str(), retcode, pPrevFsUid);
0380         }
0381 
0382         if(pPrevFsGid >= 0) {
0383           int retcode = setfsgid(pPrevFsGid);
0384           log->Dump(XRootDTransportMsg, "[%s] Restored fsgid from %d to %d", pStreamName.c_str(), retcode, pPrevFsGid);
0385         }
0386       }
0387 
0388       bool IsOk() const {
0389         return pOk;
0390       }
0391 
0392     private:
0393       int pFsUid;
0394       int pFsGid;
0395 
0396       const std::string &pStreamName;
0397 
0398       int pPrevFsUid;
0399       int pPrevFsGid;
0400 
0401       bool pOk;
0402   };
0403 #endif
0404 
0405 }
0406 
0407 #endif // __XRD_CL_UTILS_HH__