XRootD
XrdPosixAdmin.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d P o s i x A d m i n . c c */
4 /* */
5 /* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cerrno>
32 #include <limits>
33 #include <cstddef>
34 #include <unistd.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 
38 #include "XrdNet/XrdNetAddr.hh"
40 #include "XrdPosix/XrdPosixMap.hh"
41 
42 /******************************************************************************/
43 /* F a n O u t */
44 /******************************************************************************/
45 
47 {
48  XrdCl::XRootDStatus xStatus;
49  XrdCl::LocationInfo *info = 0;
51  XrdCl::URL *uVec;
52  XrdNetAddr netLoc;
53  const char *hName;
54  unsigned long i;
55 
56 // Make sure admin is ok
57 //
58  if (!isOK()) return 0;
59 
60 // Issue the deep locate and verify that all went well
61 //
62  xStatus = Xrd.DeepLocate(Url.GetPathWithParams(),XrdCl::OpenFlags::PrefName,info);
63  if (!xStatus.IsOK())
64  {num = XrdPosixMap::Result(xStatus, ecMsg, false);
65  return 0;
66  }
67 
68 // Allocate an array large enough to hold this information
69 //
70  if (!(i = info->GetSize())) {delete info; return 0;}
71  if (i > std::numeric_limits<ptrdiff_t>::max() / sizeof(XrdCl::URL))
72  {delete info; return 0;}
73  uVec = new XrdCl::URL[i];
74 
75 // Now start filling out the array
76 //
77  num = 0;
78  for( it = info->Begin(); it != info->End(); ++it )
79  {if (!netLoc.Set(it->GetAddress().c_str()) && (hName = netLoc.Name()))
80  {std::string hString(hName);
81  uVec[num] = Url;
82  uVec[num].SetHostName(hString);
83  uVec[num].SetPort(netLoc.Port());
84  num++;
85  }
86  }
87 
88 // Make sure we can return something;
89 //
90  delete info;
91  if (!num) {delete [] uVec; return 0;}
92  return uVec;
93 }
94 
95 /******************************************************************************/
96 /* Q u e r y */
97 /******************************************************************************/
98 
99 int XrdPosixAdmin::Query(XrdCl::QueryCode::Code reqCode, void *buff, int bsz)
100 {
101  XrdCl::Buffer reqBuff, *rspBuff = 0;
102 
103 // Make sure we are OK
104 //
105  if (!isOK()) return -1;
106 
107 // Get argument
108 //
109  reqBuff.FromString(Url.GetPathWithParams());
110 
111 // Issue the query
112 //
113  if (!XrdPosixMap::Result(Xrd.Query(reqCode, reqBuff, rspBuff),ecMsg))
114  {uint32_t rspSz = rspBuff->GetSize();
115  char *rspbuff = rspBuff->GetBuffer();
116  if (rspbuff && rspSz)
117  {// if the string is null-terminated decrement the size
118  if ( !(rspbuff[rspSz - 1]) ) --rspSz;
119  if (bsz >= (int)rspSz + 1)
120  {strncpy((char *)buff, rspbuff, rspSz);
121  ((char*)buff)[rspSz] = 0; // make sure it is null-terminated
122  delete rspBuff;
123  return static_cast<int>(rspSz + 1);
124  } else ecMsg.SetErrno(ERANGE,0,"buffer to small to hold result");
125  } else ecMsg.SetErrno(EFAULT,0,"Invalid return results");
126  }
127 
128 // Return error
129 //
130  delete rspBuff;
131  return -1;
132 }
133 
134 /******************************************************************************/
135 
136 int XrdPosixAdmin::Query(XrdCl::QueryCode::Code reqCode, std::string& resp)
137 {
138  XrdCl::Buffer reqBuff, *rspBuff = 0;
139 
140 // Make sure we are OK
141 //
142  if (!isOK()) return -1;
143 
144 // Get argument
145 //
146  reqBuff.FromString(Url.GetPathWithParams());
147 
148 // Issue the query
149 //
150  if (!XrdPosixMap::Result(Xrd.Query(reqCode, reqBuff, rspBuff),ecMsg))
151  {uint32_t rspSz = rspBuff->GetSize();
152  char *rspData = rspBuff->GetBuffer();
153  if (rspData && rspSz)
154  {std::string tmp(rspData, (size_t)rspSz);
155  delete rspBuff;
156  resp = std::move(tmp);
157  return static_cast<int>(rspSz + 1);
158  } else ecMsg.SetErrno(EFAULT,0,"Invalid return results");
159  }
160 
161 // Return error
162 //
163  delete rspBuff;
164  return -1;
165 }
166 /******************************************************************************/
167 /* S t a t */
168 /******************************************************************************/
169 
170 bool XrdPosixAdmin::Stat(mode_t *flags, time_t *mtime)
171 {
172  XrdCl::XRootDStatus xStatus;
173  XrdCl::StatInfo *sInfo = 0;
174 
175 // Make sure admin is ok
176 //
177  if (!isOK()) return false;
178 
179 // Issue the stat and verify that all went well
180 //
181  xStatus = Xrd.Stat(Url.GetPathWithParams(), sInfo);
182  if (!xStatus.IsOK())
183  {XrdPosixMap::Result(xStatus,ecMsg);
184  delete sInfo;
185  return false;
186  }
187 
188 // Return wanted data
189 //
190  if (flags) *flags = XrdPosixMap::Flags2Mode(0, sInfo->GetFlags());
191  if (mtime) *mtime = static_cast<time_t>(sInfo->GetModTime());
192 
193 // Delete our status information and return final result
194 //
195  delete sInfo;
196  return true;
197 }
198 
199 /******************************************************************************/
200 
202 {
203  XrdCl::XRootDStatus xStatus;
204  XrdCl::StatInfo *sInfo = 0;
205 
206 // Make sure admin is ok
207 //
208  if (!isOK()) return false;
209 
210 // Issue the stat and verify that all went well
211 //
212  xStatus = Xrd.Stat(Url.GetPathWithParams(), sInfo);
213  if (!xStatus.IsOK())
214  {XrdPosixMap::Result(xStatus,ecMsg);
215  delete sInfo;
216  return false;
217  }
218 
219 // Return the data
220 //
221  Stat.st_size = static_cast<size_t>(sInfo->GetSize());
222  Stat.st_blocks = Stat.st_size/512 + Stat.st_size%512;
223  Stat.st_ino = static_cast<ino_t>(strtoll(sInfo->GetId().c_str(), 0, 10));
224 #if defined(__mips__) && _MIPS_SIM == _ABIO32
225  // Work around inconsistent type definitions on MIPS
226  // The st_rdev field in struct stat (which is 32 bits) is not type
227  // dev_t (which is 64 bits)
228  dev_t tmp_rdev = Stat.st_rdev;
229  Stat.st_mode = XrdPosixMap::Flags2Mode(&tmp_rdev, sInfo->GetFlags());
230  Stat.st_rdev = tmp_rdev;
231 #else
232  Stat.st_mode = XrdPosixMap::Flags2Mode(&Stat.st_rdev, sInfo->GetFlags());
233 #endif
234  Stat.st_mtime = static_cast<time_t>(sInfo->GetModTime());
235 
236  if (sInfo->ExtendedFormat())
237  {
238  // Flags2Mode only maps the simplified protocol flags to owner permission
239  // bits (S_IRUSR, S_IWUSR, S_IXUSR). The extended stat response carries
240  // the full POSIX permission mode as an octal string (e.g. "0644").
241  // Replace the permission bits while preserving the file type (S_IFMT).
242  mode_t realPerms = strtol(sInfo->GetModeAsString().c_str(), nullptr, 8);
243  Stat.st_mode = (Stat.st_mode & S_IFMT) | (realPerms & 07777);
244  Stat.st_ctime = static_cast<time_t>(sInfo->GetChangeTime());
245  Stat.st_atime = static_cast<time_t>(sInfo->GetAccessTime());
246  } else {
247  Stat.st_ctime = Stat.st_mtime;
248  Stat.st_atime = time(0);
249  }
250 
251 // Delete our status information and return final result
252 //
253  delete sInfo;
254  return true;
255 }
struct stat Stat
Definition: XrdCks.cc:49
#define stat(a, b)
Definition: XrdPosix.hh:105
Binary blob representation.
Definition: XrdClBuffer.hh:34
void FromString(const std::string str)
Fill the buffer from a string.
Definition: XrdClBuffer.hh:205
const char * GetBuffer(uint32_t offset=0) const
Get the message buffer.
Definition: XrdClBuffer.hh:72
uint32_t GetSize() const
Get the size of the message.
Definition: XrdClBuffer.hh:132
Path location info.
uint32_t GetSize() const
Get number of locations.
Iterator Begin()
Get the location begin iterator.
LocationList::iterator Iterator
Iterator over locations.
Iterator End()
Get the location end iterator.
Object stat info.
uint64_t GetChangeTime() const
Get change time (in seconds since epoch)
uint64_t GetSize() const
Get size (in bytes)
uint32_t GetFlags() const
Get flags.
bool ExtendedFormat() const
Has extended stat information.
const std::string & GetModeAsString() const
Get mode.
const std::string & GetId() const
Get id.
uint64_t GetModTime() const
Get modification time (in seconds since epoch)
uint64_t GetAccessTime() const
Get change time (in seconds since epoch)
URL representation.
Definition: XrdClURL.hh:31
void SetPort(int port)
Definition: XrdClURL.hh:196
std::string GetPathWithParams() const
Get the path with params.
Definition: XrdClURL.cc:318
void SetHostName(const std::string &hostName)
Set the host name.
Definition: XrdClURL.hh:178
const char * Name(const char *eName=0, const char **eText=0)
int Port(int pNum=-1)
Definition: XrdNetAddr.cc:156
const char * Set(const char *hSpec, int pNum=PortInSpec)
Definition: XrdNetAddr.cc:216
int SetErrno(int ecc, int ret=-1, const char *alt=0)
Definition: XrdOucECMsg.cc:152
bool Stat(mode_t *flags=0, time_t *mtime=0)
XrdCl::URL * FanOut(int &num)
XrdOucECMsg & ecMsg
int Query(XrdCl::QueryCode::Code reqCode, void *buff, int bsz)
XrdCl::URL Url
static mode_t Flags2Mode(dev_t *rdv, uint32_t flags)
Definition: XrdPosixMap.cc:62
static int Result(const XrdCl::XRootDStatus &Status, XrdOucECMsg &ecMsg, bool retneg1=false)
Definition: XrdPosixMap.cc:195
Code
XRootD query request codes.
bool IsOK() const
We're fine.
Definition: XrdClStatus.hh:124