Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:15:37

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         protver = *tmp;
0244         delete tmp;
0245         return XrdCl::XRootDStatus();
0246       }
0247 
0248       //------------------------------------------------------------------------
0249       //! Check if given server supports extended file attributes
0250       //! @param url : URL pointing to the server
0251       //! @return    : true if yes, false otherwise
0252       //------------------------------------------------------------------------
0253       inline static bool HasXAttr( const XrdCl::URL &url )
0254       {
0255         if( url.IsLocalFile() ) return true;
0256         int protver = 0;
0257         auto st = GetProtocolVersion( url, protver );
0258         if( !st.IsOK() ) return false;
0259         return protver >= kXR_PROTXATTVERSION;
0260       }
0261 
0262       //------------------------------------------------------------------------
0263       //! Check if given server supports pgread/pgwrite
0264       //! @param url : URL pointing to the server
0265       //! @return    : true if yes, false otherwise
0266       //------------------------------------------------------------------------
0267       inline static bool HasPgRW( const XrdCl::URL &url )
0268       {
0269         if( url.IsLocalFile() ) return false;
0270         int protver = 0;
0271         auto st = GetProtocolVersion( url, protver );
0272         if( !st.IsOK() ) return false;
0273         return protver >= kXR_PROTPGRWVERSION;
0274       }
0275 
0276       //------------------------------------------------------------------------
0277       //! Split chunks in a ChunkList into one or more ChunkLists
0278       //! @param listsvec        : output vector of ChunkLists
0279       //! @param chunks          : input ChunkLisits
0280       //! @param maxcs           : maximum size of a ChunkInfo in output
0281       //! @param maxc            : maximum number of ChunkInfo in each ChunkList
0282       //------------------------------------------------------------------------
0283       static void SplitChunks( std::vector<ChunkList> &listsvec,
0284                                const ChunkList        &chunks,
0285                                const uint32_t          maxcs,
0286                                const size_t            maxc );
0287   };
0288 
0289   //----------------------------------------------------------------------------
0290   //! Smart descriptor - closes the descriptor on destruction
0291   //----------------------------------------------------------------------------
0292   class ScopedDescriptor
0293   {
0294     public:
0295       //------------------------------------------------------------------------
0296       //! Constructor
0297       //------------------------------------------------------------------------
0298       ScopedDescriptor( int descriptor ): pDescriptor( descriptor ) {}
0299 
0300       //------------------------------------------------------------------------
0301       //! Destructor
0302       //------------------------------------------------------------------------
0303       ~ScopedDescriptor() { if( pDescriptor >= 0 ) close( pDescriptor ); }
0304 
0305       //------------------------------------------------------------------------
0306       //! Release the descriptor being held
0307       //------------------------------------------------------------------------
0308       int Release()
0309       {
0310         int desc = pDescriptor;
0311         pDescriptor = -1;
0312         return desc;
0313       }
0314 
0315       //------------------------------------------------------------------------
0316       //! Get the descriptor
0317       //------------------------------------------------------------------------
0318       int GetDescriptor()
0319       {
0320         return pDescriptor;
0321       }
0322 
0323     private:
0324       int pDescriptor;
0325   };
0326 
0327 #ifdef __linux__
0328   //----------------------------------------------------------------------------
0329   //! Scoped fsuid and fsgid setter, restoring original values on destruction
0330   //----------------------------------------------------------------------------
0331   class ScopedFsUidSetter
0332   {
0333     public:
0334       //------------------------------------------------------------------------
0335       //! Constructor
0336       //------------------------------------------------------------------------
0337       ScopedFsUidSetter(uid_t fsuid, gid_t fsgid, const std::string &streamName)
0338       : pFsUid(fsuid), pFsGid(fsgid), pStreamName(streamName)
0339       {
0340         pOk = true;
0341         pPrevFsUid = -1;
0342         pPrevFsGid = -1;
0343 
0344         //----------------------------------------------------------------------
0345         //! Set fsuid
0346         //----------------------------------------------------------------------
0347         if(pFsUid >= 0) {
0348           pPrevFsUid = setfsuid(pFsUid);
0349 
0350           if(setfsuid(pFsUid) != pFsUid) {
0351             pOk = false;
0352             return;
0353           }
0354         }
0355 
0356         //----------------------------------------------------------------------
0357         //! Set fsgid
0358         //----------------------------------------------------------------------
0359         if(pFsGid >= 0) {
0360           pPrevFsGid = setfsgid(pFsGid);
0361 
0362           if(setfsgid(pFsGid) != pFsGid) {
0363             pOk = false;
0364             return;
0365           }
0366         }
0367       }
0368 
0369       //------------------------------------------------------------------------
0370       //! Destructor
0371       //------------------------------------------------------------------------
0372       ~ScopedFsUidSetter() {
0373         Log *log = DefaultEnv::GetLog();
0374 
0375         if(pPrevFsUid >= 0) {
0376           int retcode = setfsuid(pPrevFsUid);
0377           log->Dump(XRootDTransportMsg, "[%s] Restored fsuid from %d to %d", pStreamName.c_str(), retcode, pPrevFsUid);
0378         }
0379 
0380         if(pPrevFsGid >= 0) {
0381           int retcode = setfsgid(pPrevFsGid);
0382           log->Dump(XRootDTransportMsg, "[%s] Restored fsgid from %d to %d", pStreamName.c_str(), retcode, pPrevFsGid);
0383         }
0384       }
0385 
0386       bool IsOk() const {
0387         return pOk;
0388       }
0389 
0390     private:
0391       int pFsUid;
0392       int pFsGid;
0393 
0394       const std::string &pStreamName;
0395 
0396       int pPrevFsUid;
0397       int pPrevFsGid;
0398 
0399       bool pOk;
0400   };
0401 #endif
0402 
0403 }
0404 
0405 #endif // __XRD_CL_UTILS_HH__