ewmscp  ..
Classes | Public Member Functions | Static Public Attributes | Static Protected Member Functions | Static Private Attributes | List of all members
outputHandler::dcap Class Reference

#include <outputHandlerDcap.h>

Inheritance diagram for outputHandler::dcap:
[legend]
Collaboration diagram for outputHandler::dcap:
[legend]

Classes

class  writerDcap
 

Public Member Functions

 dcap ()
 
 ~dcap () override=default
 
std::unique_ptr< writernewWriter (const std::string &path, bool mightAppend, size_t sourceSize, size_t readBlockSize, copyRequest::stateType &state, bool noWrite, std::unique_ptr< ioHandle::attrDataType >, std::unique_ptr< acl::list > aclData) override
 
void ensureParentDirs (const std::string &path, const std::string &srcPath, inputHandler::base *InputHandler) override
 
void remove (const std::string &path, copyRequest::stateType &state) override
 
bool renameSimple (const std::string &fromPath, const std::string &toPath) override
 
base::renameRetvalType rename (const std::string &fromPath, const std::unique_ptr< const genericStat > &readInitialStat, const std::string &toPath, copyRequest::stateType &state) override
 
void doAttributePreservations (const std::string &path, const genericStat &stat) override
 
- Public Member Functions inherited from outputHandler::base
 ~base () override=default
 
virtual std::unique_ptr< writernewTmpWriter (std::string &path, size_t sourceSize, bool noWrite, std::unique_ptr< ioHandle::attrDataType > attrData, std::unique_ptr< acl::list > aclData)
 
virtual void createSymlink (const std::vector< char > &, const std::string &, uid_t, gid_t)
 
virtual size_t getMaxNameLength (const std::string &dirPath)
 
template<class C >
void shortenNameToMax (const std::string &path, C &pathBuf, const std::string &suffix)
 
- Public Member Functions inherited from pathHandler
virtual ~pathHandler ()=default
 
virtual std::string getXattr (const std::string &, const std::string &)
 
- Public Member Functions inherited from dcapCommon
 dcapCommon ()
 
bool pathExists (const std::string &path) override
 
std::unique_ptr< const genericStatgetStat (const std::string &path, bool followLink) override
 

Static Public Attributes

static const std::string parPrefix
 

Static Protected Member Functions

static void setAclData (const acl::list &aclData, bool isDir=false)
 
- Static Protected Member Functions inherited from outputHandler::base
static std::map< std::string, factoryClass * > & getFactoryMap ()
 

Static Private Attributes

static factoryTemplate< dcapfactory
 

Additional Inherited Members

- Public Types inherited from outputHandler::base
enum  renameRetvalType { renameRetvalType::ok, renameRetvalType::fileChanged, renameRetvalType::fileVanished, renameRetvalType::cantHappen }
 
- Static Public Member Functions inherited from outputHandler::base
static basenewHandler (const std::string &name)
 
template<class T >
static void addAllowedNamesToOption (T &option)
 
- Static Public Member Functions inherited from dcapCommon
static std::string fixPathUrl (const std::string &path)
 
- Protected Member Functions inherited from outputHandler::base
 base ()=default
 

Detailed Description

Definition at line 8 of file outputHandlerDcap.h.

Constructor & Destructor Documentation

◆ dcap()

outputHandler::dcap::dcap ( )

Definition at line 27 of file outputHandlerDcap.cpp.

27  {
30  "--", "dcap output handler",
31  "setting setAttributesAfterClose automatically");
33  }
34  }

References errMsg::emit(), errMsg::info, and copyRequest::base::setAttributesAfterClose.

Here is the call graph for this function:

◆ ~dcap()

outputHandler::dcap::~dcap ( )
overridedefault

Member Function Documentation

◆ doAttributePreservations()

void outputHandler::dcap::doAttributePreservations ( const std::string &  path,
const genericStat stat 
)
overridevirtual

Reimplemented from outputHandler::base.

Definition at line 331 of file outputHandlerDcap.cpp.

332  {
333  if (preserve.timestamps) { // for mtime we must use a parallel nfs mount, there is no function in the dcap lib.
334  struct timespec times[2];
335  times[0].tv_nsec = UTIME_OMIT; // leave atime unchanged
336  stat.getMtime(times[1]);
337  auto serverStart = path.find("://");
338  if (serverStart == std::string::npos) {
339  throw std::runtime_error(path + " contains no \"://\"");
340  }
341  auto realPathStart = path.find("/", serverStart + 3);
342  if (realPathStart == std::string::npos) {
343  throw std::runtime_error(path + " contains no path after server part");
344  }
345  throwcall::good0(utimensat(0, path.c_str() + realPathStart,
346  times, 0),
347  "can't set mtime on ", path.c_str() + realPathStart);
348  }
349  dCapLock extraOptionLock;
350  if (preserve.mode) {
351  throwcall::dcap::good0(dc_chmod(path.c_str(), stat.mode), "can't set mode of ", path);
352  } else {
353  auto oldmask = umask(0);
354  auto retval = dc_chmod(path.c_str(), modeBits & ~oldmask);
355  if (retval != 0) {
357  path, "chmod", "can't set mode ", dc_errno, " (", dc_strerror(dc_errno), ") ");
358  }
359  //throwcall::dcap::good0(dc_chmod(path.c_str(), modeBits & ~oldmask), "can't set mode of ", path);
360  umask(oldmask);
361  }
362 
363  if (gid != -1 || uid != -1) {
364  throwcall::dcap::good0(dc_chown(path.c_str(), uid, gid), "can't set owner/group (", uid, ",", gid, ") of ", path);
365  } else if (preserve.ownership) {
366  throwcall::dcap::good0(dc_chown(path.c_str(), stat.ownerUid, stat.ownerGid),
367  "can't set owner/group (", stat.ownerUid, ",", stat.ownerGid, ") of ",
368  path);
369  }
370  }

References errMsg::emit(), genericStat::getMtime(), gid, throwcall::dcap::good0(), throwcall::good0(), genericStat::mode, modeBits, errMsg::notice, genericStat::ownerGid, genericStat::ownerUid, preserve, and uid.

Here is the call graph for this function:

◆ ensureParentDirs()

void outputHandler::dcap::ensureParentDirs ( const std::string &  path,
const std::string &  srcPath,
inputHandler::base InputHandler 
)
overridevirtual

Implements outputHandler::base.

Definition at line 36 of file outputHandlerDcap.cpp.

38  {
39  std::vector<std::remove_reference<decltype(path)>::type::value_type> disposable_buffer(path.c_str(), path.c_str() + path.size() + 1);
40  std::string dir(dirname(disposable_buffer.data()));
41  struct dcapStat statbuf;
42  int statResult;
43  {
44  dCapLock extraOptionLock;
45  statResult = dc_stat(fixPathUrl(dir).c_str(), &statbuf);
46  }
47  if (statResult) {
48  if (errno == ENOENT) {
49  auto srcDir = srcPath.substr(0, srcPath.find_last_of('/'));
50  while (srcDir.back() == '/') {
51  srcDir.pop_back();
52  }
53  ensureParentDirs(dir, srcDir, InputHandler);
54  dCapLock extraOptionLock;
55  if (preserve.acls) {
56  auto aclData = InputHandler->getAclData(srcDir);
57  if (aclData) {
58  setAclData(*aclData, true);
59  }
60  }
61  auto result = dc_mkdir(fixPathUrl(dir).c_str(), 0777u);
62 
63  if (result != 0 && errno == EEXIST) {
64  return; // we lost a race with another copy process...
65  }
66 
67  throwcall::dcap::good0(result, "can't create directory ", dir);
68 
69  if (gid != -1 || uid != -1) {
70  throwcall::dcap::good0(dc_chown(fixPathUrl(dir).c_str(), uid, gid), "can't set owner/group (", uid, ",", gid, ") on ", dir);
71  }
72  }
73  } else if (! S_ISDIR(statbuf.st_mode)) {
75  dir, "ensure parents",
76  "is not a directory (st_mode is ", statbuf.st_mode, ") but should be");
77  }
78  }

References dcapStat, errMsg::emit(), dcapCommon::fixPathUrl(), inputHandler::base::getAclData(), gid, throwcall::dcap::good0(), errMsg::info, preserve, setAclData(), and uid.

Here is the call graph for this function:

◆ newWriter()

std::unique_ptr< base::writer > outputHandler::dcap::newWriter ( const std::string &  path,
bool  mightAppend,
size_t  sourceSize,
size_t  readBlockSize,
copyRequest::stateType state,
bool  noWrite,
std::unique_ptr< ioHandle::attrDataType ,
std::unique_ptr< acl::list aclData 
)
overridevirtual

Implements outputHandler::base.

Definition at line 13 of file outputHandlerDcap.cpp.

20  {
21  return std::unique_ptr<base::writer>(new writerDcap(path, mightAppend,
22  sourceSize, readBlockSize,
23  state, noWrite,
24  std::move(aclData)));
25  }

◆ remove()

void outputHandler::dcap::remove ( const std::string &  path,
copyRequest::stateType state 
)
overridevirtual

Implements outputHandler::base.

Definition at line 81 of file outputHandlerDcap.cpp.

81  {
82  dCapLock extraOptionLock;
83  struct dcapStat dsttat;
84  {
85  auto retval = dc_lstat(fixPathUrl(path).c_str(), &dsttat);
86 
87  if (retval && errno == ENOENT) {
89  return;
90  }
91  }
92  if (S_ISDIR(dsttat.st_mode)) {
93  auto retval = dc_rmdir(fixPathUrl(path).c_str());
94  if (retval) {
95  switch (errno) {
96  case ENOENT:
98  return;
99  case ENOTEMPTY:
100  case EEXIST: // POSIX.1 allows this also
102  path, "remove", "directory not empty but should be removed");
104  return;
105  }
106  throwcall::dcap::good0(retval, "can't reemove directory ", path);
107  } else {
109  return;
110  }
111  } else {
112  auto retval = dc_unlink(fixPathUrl(path).c_str());
113 
114  if (retval && errno == ENOENT) {
116  } else {
117  throwcall::dcap::good0(retval, "can't unlink ", path);
118  }
120  }
121  }

References dcapStat, copyRequest::done, errMsg::emit(), copyRequest::failed, dcapCommon::fixPathUrl(), throwcall::dcap::good0(), errMsg::info, and copyRequest::vanished.

Here is the call graph for this function:

◆ rename()

base::renameRetvalType outputHandler::dcap::rename ( const std::string &  fromPath,
const std::unique_ptr< const genericStat > &  readInitialStat,
const std::string &  toPath,
copyRequest::stateType state 
)
overridevirtual
Bug:
what if at the end a directory is renamed?

Implements outputHandler::base.

Definition at line 136 of file outputHandlerDcap.cpp.

139  {
140  dCapLock extraOptionLock;
141  struct dcapStat fromPathStatBuf;
142  auto statRetVal = dc_stat(fixPathUrl(fromPath).c_str(), &fromPathStatBuf);
143  if (statRetVal && (errno == ENOENT || errno == ENOTDIR)) {
144  if (readInitialStat && readInitialStat->isDir()) { // no need to act, dirs are created on the fly
148  }
150  } else if (statRetVal) { // curious error
151  throwcall::dcap::good0(statRetVal, "can't stat '", fromPath, "'");
152  return base::renameRetvalType::cantHappen; // never reached
153  }
154  genericStat fromPathStat(fromPathStatBuf, std::chrono::seconds(1));
155  if (! readInitialStat || (
156  ! readInitialStat->isDir() &&
157  (fromPathStat.size != readInitialStat->size
158  || !fromPathStat.isSameMtimeAs(*readInitialStat)))) {
159  // the copy on fromPath is not up to date, create a new copy
161  fromPath, "move",
162  "file (", toPath, ") changed unexpectedly, doing fresh copy");
164  } else { // try to move the existing copy
165  auto retval = dc_rename(fixPathUrl(fromPath).c_str(), fixPathUrl(toPath).c_str());
166 
167  if (retval && (errno == ENOENT || errno == ENOTDIR)) {
168  if (readInitialStat->isDir()) { // no need to act, dirs are created on the fly
171  }
173  fromPath, "move",
174  "vanished unexpectedly, doing fresh copy");
175  // file was probably not copied yet, try to copy it from the move target
177  } else {
178  throwcall::dcap::good0(retval, "can't rename '", fromPath, "' to '", toPath, "'");
181  }
182  }
184  }

References outputHandler::base::cantHappen, dcapStat, copyRequest::done, errMsg::emit(), outputHandler::base::fileChanged, outputHandler::base::fileVanished, dcapCommon::fixPathUrl(), throwcall::dcap::good0(), copyRequest::ignore, errMsg::info, genericStat::isDir(), genericStat::isSameMtimeAs(), outputHandler::base::ok, and genericStat::size.

Here is the call graph for this function:

◆ renameSimple()

bool outputHandler::dcap::renameSimple ( const std::string &  fromPath,
const std::string &  toPath 
)
overridevirtual

Implements outputHandler::base.

Definition at line 124 of file outputHandlerDcap.cpp.

125  {
126  dCapLock extraOptionLock;
127  auto retval = dc_rename(fromPath.c_str(), toPath.c_str());
128  //find out proper errno
129  // if (retval && (errno == ENOENT || errno == ENOTDIR)) {
130  // return false;
131  //}
132  throwcall::dcap::good0(retval, "can't rename '", fromPath, "' to '", toPath, "'");
133  return true;
134  }

References throwcall::dcap::good0().

Here is the call graph for this function:

◆ setAclData()

void outputHandler::dcap::setAclData ( const acl::list aclData,
bool  isDir = false 
)
staticprotected

Definition at line 188 of file outputHandlerDcap.cpp.

188  {
189  if (aclData.entries.empty()) {
190  return;
191  }
192  bool needSpace = false;
193  std::string result(" -acl=\"");
194  for (const auto& entry : aclData.entries) {
195  if (needSpace) {
196  result += " ";
197  }
198  needSpace = true;
199  result += entry.isAllowedType() ? "A:" : "D:";
200  result += entry.isFlagSet(acl::list::entryType::flagsType::identifier_group) &&
202  ? "g:" : ":";
203  if (entry.isFlagSet(acl::list::entryType::flagsType::special_who)) {
204  switch (entry.e_id) {
205  case acl::list::entryType::specialIdType::owner_special_id:
206  result += "OWNER@:";
207  break;
208  case acl::list::entryType::specialIdType::group_special_id:
209  result += "GROUP@:";
210  break;
211  case acl::list::entryType::specialIdType::everyone_special_id:
212  result += "EVERYONE@:";
213  break;
214  default:
215  throw std::runtime_error("illegal special id");
216  }
217  } else {
218  result += std::to_string(entry.e_id);
219  result += ":";
220  }
221  for (const auto& item : acl::list::entryType::aclMaskBits) {
222  auto mask = entry._mask;
223  if (isDir) {
225  }
226  if (mask & item.first) {
227  result += item.second;
228  }
229  }
230  }
231  result += "\"";
232  dc_setExtraOption(const_cast<char*>(result.c_str())); // ugly const cast due to bad dCap interface
233 
234  };

References acl::list::entryType::aclMaskBits, acl::list::entryType::delete_child, acl::list::entries, acl::list::entryType::identifier_group, and acl::list::entryType::special_who.

Referenced by ensureParentDirs(), and outputHandler::dcap::writerDcap::writerDcap().

Here is the caller graph for this function:

Member Data Documentation

◆ factory

factoryTemplate<dcap> outputHandler::dcap::factory
staticprivate

Definition at line 9 of file outputHandlerDcap.h.

◆ parPrefix

const std::string outputHandler::dcap::parPrefix
static

Definition at line 11 of file outputHandlerDcap.h.


The documentation for this class was generated from the following files:
genericStat::ownerGid
gid_t ownerGid
Definition: genericStat.h:24
genericStat::mode
mode_t mode
Definition: genericStat.h:22
inputHandler::base::getAclData
virtual std::unique_ptr< acl::list > getAclData(const std::string &)
Definition: inputHandler.h:155
errMsg::location
class for defining the location of a error message in the source code.
Definition: errMsgQueue.h:14
dCapLock
Definition: dcapCommon.h:40
genericStat
generic stat abstraction class Used to abstract the variants of the stat structure.
Definition: genericStat.h:12
dcapStat
#define dcapStat
Definition: dcapCommon.h:7
copyRequest::stateBitType::ignore
@ ignore
errMsg::level::info
@ info
outputHandler::dcap::setAclData
static void setAclData(const acl::list &aclData, bool isDir=false)
Definition: outputHandlerDcap.cpp:188
acl::list::entryType::flagsType::special_who
@ special_who
outputHandler::base::renameRetvalType::cantHappen
@ cantHappen
copyRequest::stateBitType::done
@ done
outputHandler::base::renameRetvalType::fileChanged
@ fileChanged
copyRequest::stateBitType::failed
@ failed
genericStat::getMtime
void getMtime(struct timespec &spec) const
Definition: genericStat.cpp:65
gid
options::single< int > gid
copyRequest::stateBitType::vanished
@ vanished
genericStat::isDir
bool isDir() const
Definition: genericStat.cpp:92
acl::list::entryType::aclMaskBits
static std::vector< std::pair< list::entryType::maskType, char > > aclMaskBits
Definition: acl.h:86
genericStat::size
size_t size
Definition: genericStat.h:16
copyRequest::base::setAttributesAfterClose
static options::single< bool > setAttributesAfterClose
Definition: copyRequest.h:124
outputHandler::base::renameRetvalType::fileVanished
@ fileVanished
dcapCommon::fixPathUrl
static std::string fixPathUrl(const std::string &path)
Definition: dcapCommon.cpp:127
outputHandler::base::renameRetvalType::ok
@ ok
acl::list::entryType::flagsType::identifier_group
@ identifier_group
preserve
decltype(preserve) preserve
set of properties to preserve in the copy
Definition: ewmscp.cpp:111
uid
options::single< int > uid
errMsg::emit
void emit(level aLogLevel, const location &loc, const std::string &aObject, const std::string &aAction, const Args &... args)
function to create and enqueue a message, this is the only way that messages should be created!
Definition: errMsgQueue.h:148
throwcall::dcap::good0
void good0(T call, const Args &... args)
Definition: dcapCommon.h:21
acl::list::entries
std::vector< entryType > entries
Definition: acl.h:108
throwcall::good0
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
Definition: throwcall.h:40
errMsg::level::notice
@ notice
acl::list::entryType::maskType::delete_child
@ delete_child
outputHandler::dcap::ensureParentDirs
void ensureParentDirs(const std::string &path, const std::string &srcPath, inputHandler::base *InputHandler) override
Definition: outputHandlerDcap.cpp:36
genericStat::ownerUid
uid_t ownerUid
Definition: genericStat.h:23
modeBits
options::single< modeBitType > modeBits