diff --git a/src/XProtocol/XProtocol.cc b/src/XProtocol/XProtocol.cc index 6e5674abdd7..51961db07fa 100644 --- a/src/XProtocol/XProtocol.cc +++ b/src/XProtocol/XProtocol.cc @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include "XProtocol/XProtocol.hh" @@ -135,7 +137,7 @@ const char *XProtocol::errName(kXR_int32 errCode) /******************************************************************************/ /* r e q N a m e */ /******************************************************************************/ - + const char *XProtocol::reqName(kXR_unt16 reqCode) { // Mangle request code if the byte orderdoesn't match our host order @@ -150,3 +152,80 @@ const char *XProtocol::reqName(kXR_unt16 reqCode) // return reqNames[reqCode - kXR_auth]; } + +/******************************************************************************/ +/* n v e c & v v e c o p e r a t i n s */ +/******************************************************************************/ + +// Add an attribute name to nvec (the buffer has to be sufficiently big) +// +char* ClientFattrRequest::NVecInsert( const char *name, char *buffer ) +{ + // set rc to 0 + memset( buffer, 0, sizeof( kXR_unt16 ) ); + buffer += sizeof( kXR_unt16 ); + // copy attribute name including trailing null + size_t len = strlen( name ); + memcpy( buffer, name, len + 1 ); + buffer += len + 1; + + // return memory that comes right after newly inserted nvec record + return buffer; +} + +// Add an attribute name to vvec (the buffer has to be sufficiently big) +// +char* ClientFattrRequest::VVecInsert( const char *value, char *buffer ) +{ + // copy value size + kXR_int32 len = strlen( value ); + kXR_int32 lendat = htonl( len ); + memcpy( buffer, &lendat, sizeof( kXR_int32 ) ); + buffer += sizeof( kXR_int32 ); + // copy value itself + memcpy( buffer, value, len ); + buffer += len; + + // return memory that comes right after newly inserted vvec entry + return buffer; +} + +// Read error code from nvec +// +char* ClientFattrRequest::NVecRead( char* buffer, kXR_unt16 &rc ) + { + rc = *reinterpret_cast( buffer ); + rc = htons( rc ); + buffer += sizeof( kXR_unt16 ); + return buffer; + } + +// Read attribute name from nvec +// +char* ClientFattrRequest::NVecRead( char* buffer, char *&name ) +{ + name = strdup( buffer ); + buffer += strlen( name ) + 1; + return buffer; +} + +// Read value length from vvec +// +char* ClientFattrRequest::VVecRead( char* buffer, kXR_int32 &len ) +{ + len = *reinterpret_cast( buffer ); + len = htonl( len ); + buffer += sizeof( kXR_int32 ); + return buffer; +} + +// Read attribute value from vvec +// +char* ClientFattrRequest::VVecRead( char* buffer, kXR_int32 len, char *&value ) +{ + value = reinterpret_cast( malloc( len + 1 ) ); + strncpy( value, buffer, len ); + value[len] = 0; + buffer += len; + return buffer; +} diff --git a/src/XProtocol/XProtocol.hh b/src/XProtocol/XProtocol.hh index e8af2553fc2..686280a89ac 100644 --- a/src/XProtocol/XProtocol.hh +++ b/src/XProtocol/XProtocol.hh @@ -461,6 +461,31 @@ struct ClientFattrRequest { // static const int isNew = 0x01; // For set, the variable must not exist static const int aData = 0x10; // For list, return attribute value + +// Add an attribute name to nvec (the buffer has to be sufficiently big) +// + static char* NVecInsert( const char *name, char *buffer ); + +// Add an attribute name to vvec (the buffer has to be sufficiently big) +// + static char* VVecInsert( const char *value, char *buffer ); + +// Read error code from nvec +// + static char* NVecRead( char* buffer, kXR_unt16 &rc ); + +// Read attribute name from nvec, should be deallocated with free() +// + static char* NVecRead( char* buffer, char *&name ); + +// Read value length from vvec +// + static char* VVecRead( char* buffer, kXR_int32 &len ); + +// Read attribute value from vvec, should be deallocated with free() +// + static char* VVecRead( char* buffer, kXR_int32 len, char *&value ); + }; struct ClientGetfileRequest { kXR_char streamid[2]; diff --git a/src/XrdCl/XrdClLocalFileHandler.cc b/src/XrdCl/XrdClLocalFileHandler.cc index 1b579102913..1def703e36b 100644 --- a/src/XrdCl/XrdClLocalFileHandler.cc +++ b/src/XrdCl/XrdClLocalFileHandler.cc @@ -951,12 +951,11 @@ namespace XrdCl body += sizeof( kXR_unt16 ); bodylen -= sizeof( kXR_unt16 ); // get the size of attribute name - size_t len = strlen( body ); - if( len > bodylen ) return XRootDStatus( stError, errDataError ); - std::string name( body, len ); - attrs.push_back( std::make_tuple( name, std::string() ) ); - body += len + 1; // +1 for the null terminating the string - bodylen -= len + 1; // +1 for the null terminating the string + char *name = 0; + body = ClientFattrRequest::NVecRead( body, name ); + attrs.push_back( std::make_tuple( std::string( name ), std::string() ) ); + bodylen -= strlen( name ) + 1; // +1 for the null terminating the string + free( name ); } // parse valuevec for( kXR_char i = 0; i < numattr; ++i ) @@ -964,16 +963,15 @@ namespace XrdCl // get value length if( bodylen < sizeof( kXR_int32 ) ) return XRootDStatus( stError, errDataError ); kXR_int32 len = 0; - memcpy( &len, body, sizeof( kXR_int32 ) ); - len = ntohl( len ); - body += sizeof( kXR_int32 ); + body = ClientFattrRequest::VVecRead( body, len ); bodylen -= sizeof( kXR_int32 ); // get value if( size_t( len ) > bodylen ) return XRootDStatus( stError, errDataError ); - std::string value( body, len ); - std::get( attrs[i] ) = value; - body += len; + char *value = 0; + body = ClientFattrRequest::VVecRead( body, len, value ); bodylen -= len; + std::get( attrs[i] ) = value; + free( value ); } return SetXAttr( attrs, handler ); diff --git a/src/XrdCl/XrdClMessageUtils.cc b/src/XrdCl/XrdClMessageUtils.cc index 36ab1d688e6..77e67ed5fcc 100644 --- a/src/XrdCl/XrdClMessageUtils.cc +++ b/src/XrdCl/XrdClMessageUtils.cc @@ -33,6 +33,8 @@ #include "XrdCl/XrdClXRootDMsgHandler.hh" #include "XrdClRedirectorRegistry.hh" +#include "XProtocol/XProtocol.hh" + namespace XrdCl { //---------------------------------------------------------------------------- @@ -428,9 +430,9 @@ namespace XrdCl for( auto itr = attrs.begin(); itr != attrs.end(); ++itr ) { const std::string &name = std::get( *itr ); - XRootDTransport::InsertXAttrNVecEntry( name, nvec ); + nvec = ClientFattrRequest::NVecInsert( name.c_str(), nvec ); const std::string &value = std::get( *itr ); - XRootDTransport::InsertXAttrVVecEntry( value, vvec ); + vvec = ClientFattrRequest::VVecInsert( value.c_str(), vvec ); } return Status(); @@ -469,52 +471,8 @@ namespace XrdCl char *nptr = nvec.data(); for( auto itr = attrs.begin(); itr != attrs.end(); ++itr ) - XRootDTransport::InsertXAttrNVecEntry( *itr, nptr ); + nptr = ClientFattrRequest::NVecInsert( itr->c_str(), nptr ); return Status(); } - -// //------------------------------------------------------------------------ -// // Create body of xattr request and set the body size -// //------------------------------------------------------------------------ -// template -// Status MessageUtils::CreateXAttrBody( Message *msg, -// const std::vector &vec, -// const std::string &path ) -// { -// ClientRequestHdr *hdr = reinterpret_cast( msg->GetBuffer() ); -// -// std::vector xattrvec; -// Status st = MessageUtils::CreateXAttrVec( vec, xattrvec ); -// if( !st.IsOK() ) -// return st; -// -// // update body size in the header -// hdr->dlen = path.size() + 1; -// hdr->dlen += xattrvec.size(); -// -// // append the body -// size_t offset = sizeof( ClientRequestHdr ); -// msg->Append( path.c_str(), path.size() + 1, offset ); -// offset += path.size() + 1; -// msg->Append( xattrvec.data(), xattrvec.size(), offset ); -// } -// -// //------------------------------------------------------------------------ -// // Manually instantiate the template for std::string -// //------------------------------------------------------------------------ -// template<> -// Status MessageUtils::CreateXAttrBody( -// Message *msg, -// const std::vector &vec, -// const std::string &path ); -// -// //------------------------------------------------------------------------ -// // Manually instantiate the template for xattr_t -// //------------------------------------------------------------------------ -// template<> -// Status MessageUtils::CreateXAttrBody( -// Message *msg, -// const std::vector &vec, -// const std::string &path ); } diff --git a/src/XrdCl/XrdClXRootDTransport.cc b/src/XrdCl/XrdClXRootDTransport.cc index 9e11bc030ad..8a9ad56c673 100644 --- a/src/XrdCl/XrdClXRootDTransport.cc +++ b/src/XrdCl/XrdClXRootDTransport.cc @@ -1097,37 +1097,6 @@ namespace XrdCl header->dlen = ntohl( header->dlen ); } - //---------------------------------------------------------------------------- - // Insert new element into xattr name vector - //---------------------------------------------------------------------------- - void XRootDTransport::InsertXAttrNVecEntry( const std::string &name, - char *&nvec ) - { - // copy rc - static const kXR_unt16 rc = 0; - memcpy( nvec, &rc, sizeof( rc ) ); - nvec += sizeof( rc ); - // copy attribute name including trailing null - memcpy( nvec, name.c_str(), name.size() + 1 ); - nvec += name.size() + 1; - } - - //---------------------------------------------------------------------------- - // Insert new element into xattr value vector - //---------------------------------------------------------------------------- - void XRootDTransport::InsertXAttrVVecEntry( const std::string &value, - char *&vvec ) - { - // copy value size - kXR_int32 len = value.size(); - len = htonl( len ); - memcpy( vvec, &len, sizeof( len ) ); - vvec += sizeof( len ); - // copy value itself - memcpy( vvec, value.c_str(), value.size() ); - vvec += value.size(); - } - //---------------------------------------------------------------------------- // Log server error response //---------------------------------------------------------------------------- diff --git a/src/XrdCl/XrdClXRootDTransport.hh b/src/XrdCl/XrdClXRootDTransport.hh index 2509bbeb2cb..50e7a8f830f 100644 --- a/src/XrdCl/XrdClXRootDTransport.hh +++ b/src/XrdCl/XrdClXRootDTransport.hh @@ -184,22 +184,6 @@ namespace XrdCl //------------------------------------------------------------------------ static void UnMarshallHeader( Message *msg ); - //------------------------------------------------------------------------ - //! Insert new element into xattr name vector - //! - //! @param name : extended attribute name - //! @param nvec : vector of extended atribute names - //------------------------------------------------------------------------ - static void InsertXAttrNVecEntry( const std::string &name, char *&nvec ); - - //------------------------------------------------------------------------ - //! Insert new element into xattr value vector - //! - //! @param value : extended attribute value - //! @param vvec : vector of extended atribute values - //------------------------------------------------------------------------ - static void InsertXAttrVVecEntry( const std::string &value, char *&vvec ); - //------------------------------------------------------------------------ //! Log server error response //------------------------------------------------------------------------