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

#include <outputHandlerLibssh.h>

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

Classes

class  writerLibssh
 

Public Member Functions

 libssh ()
 
 ~libssh () 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 > attrData, 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 createSymlink (const std::vector< char > &target, const std::string &path, uid_t uid, gid_t gid) override
 
size_t getMaxNameLength (const std::string &dirPath) 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 doAttributePreservations (const std::string &, const genericStat &)
 
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 libsshCommon
void reconnectSessions ()
 
template<typename T >
std::unique_ptr< T, void(*)(T *)> getUniquePtr (T *obj, void(*deleter)(T *))
 
 libsshCommon (sshOptions &aOpt)
 
 ~libsshCommon () override
 
bool pathExists (const std::string &path) override
 
std::unique_ptr< const genericStatgetStat (const std::string &path, bool followLink) override
 
const sftp_statvfs_struct & getVfsStat (const std::string &path)
 

Static Private Attributes

static factoryTemplate< libsshfactory
 

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)
 
- Public Attributes inherited from libsshCommon
ssh_session session
 
sftp_session sftp
 
- Protected Member Functions inherited from outputHandler::base
 base ()=default
 
- Protected Member Functions inherited from libsshCommon
void openSessions ()
 
void closeSessions ()
 
- Static Protected Member Functions inherited from outputHandler::base
static std::map< std::string, factoryClass * > & getFactoryMap ()
 
- Protected Attributes inherited from libsshCommon
sshOptionsopt
 
bool reconnecting
 

Detailed Description

Definition at line 10 of file outputHandlerLibssh.h.

Constructor & Destructor Documentation

◆ libssh()

outputHandler::libssh::libssh ( )

Definition at line 21 of file outputHandlerLibssh.cpp.

21  :
23  }

◆ ~libssh()

outputHandler::libssh::~libssh ( )
overridedefault

Member Function Documentation

◆ createSymlink()

void outputHandler::libssh::createSymlink ( const std::vector< char > &  target,
const std::string &  path,
uid_t  uid,
gid_t  gid 
)
overridevirtual

Reimplemented from outputHandler::base.

Definition at line 201 of file outputHandlerLibssh.cpp.

203  {
204  {
205  timerInst(sftp_symlink);
206  auto retval = sftp_symlink(sftp, target.data(), path.c_str());
207  if (retval != 0 && sftp_get_error(sftp) != SSH_FX_FILE_ALREADY_EXISTS) {
208  throwcall::sftp::good0(retval, *this, "can't create link at ", path);
209  }
210  }
211  if (static_cast<std::make_signed<decltype(gid)>::type>(gid) != -1
212  || static_cast<std::make_signed<decltype(uid)>::type>(uid) != -1) {
213  timerInst(sftp_chown);
214  throwcall::sftp::good0(sftp_chown(sftp, path.c_str(), uid, gid), *this,
215  "can't set owner/group (", uid, ",", gid, ") on ", path);
216  }
217  }

References gid, throwcall::sftp::good0(), libsshCommon::sftp, timerInst, and uid.

Here is the call graph for this function:

◆ ensureParentDirs()

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

Implements outputHandler::base.

Definition at line 43 of file outputHandlerLibssh.cpp.

45  {
46  std::vector<std::remove_reference<decltype(path)>::type::value_type> disposable_buffer(path.c_str(), path.c_str() + path.size() + 1);
47  std::string dir(dirname(disposable_buffer.data()));
48  static timer::anchor a("sftp_stat");
50  auto stat = getUniquePtr(sftp_stat(sftp, dir.c_str()), sftp_attributes_free);
51  i.stop();
52 
53  if (stat == nullptr) {
54  if (sftp_get_error(sftp) == SSH_FX_NO_SUCH_FILE) {
55  ensureParentDirs(dir, srcPath, InputHandler);
56  {
57  timerInst(sftp_mkdir);
58  auto result = sftp_mkdir(sftp, dir.c_str(), 0777u);
59 
60  if (result != 0 && sftp_get_error(sftp) == SSH_FX_FILE_ALREADY_EXISTS) {
61  return; // we lost a race with another copy process...
62  }
63 
64  throwcall::sftp::good0(result, *this, "can't create directory ", dir);
65  }
66  if (gid != -1 || uid != -1) {
67  timerInst(sftp_chown);
68  throwcall::sftp::good0(sftp_chown(sftp, dir.c_str(), uid, gid), *this,
69  "can't set owner/group (", uid, ",", gid, ") on ", dir);
70  }
71  }
72  } else if (stat->type != SSH_FILEXFER_TYPE_DIRECTORY) {
74  dir, "ensure parents",
75  "is not a directory (st_mode is ",
76  static_cast<int>(stat->type),
77  ", perm: ", std::hex, stat->permissions,
78  ") but should be");
79  }
80  }

References errMsg::emit(), libsshCommon::getUniquePtr(), gid, throwcall::sftp::good0(), errMsg::info, libsshCommon::sftp, timer::instanceUnscoped::stop(), timerInst, and uid.

Here is the call graph for this function:

◆ getMaxNameLength()

size_t outputHandler::libssh::getMaxNameLength ( const std::string &  dirPath)
overridevirtual

Reimplemented from outputHandler::base.

Definition at line 398 of file outputHandlerLibssh.cpp.

398  {
399  auto stat = getVfsStat(dirPath);
400  if (stat.f_namemax > 0) {
401  return stat.f_namemax;
402  } else {
403  return 255; // best guess if no sane value forem system
404  }
405  }

References libsshCommon::getVfsStat().

Here is the call graph for this function:

◆ newWriter()

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

Implements outputHandler::base.

Definition at line 27 of file outputHandlerLibssh.cpp.

34  {
35  return std::unique_ptr<base::writer>(new writerLibssh(path,
36  *this,
37  mightAppend,
38  sourceSize, readBlockSize,
39  state, noWrite, std::move(attrData),
40  std::move(aclData)));
41  }

◆ remove()

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

Implements outputHandler::base.

Definition at line 83 of file outputHandlerLibssh.cpp.

83  {
84  auto stat = getUniquePtr(sftp_lstat(sftp, path.c_str()), sftp_attributes_free);
85  if (stat == nullptr && sftp_get_error(sftp) == SSH_FX_NO_SUCH_FILE) {
87  return;
88  }
89  if (stat->type == SSH_FILEXFER_TYPE_DIRECTORY) {
90  auto retval = sftp_rmdir(sftp, path.c_str());
91  if (retval) {
92  switch (sftp_get_error(sftp)) {
93  case SSH_FX_NO_SUCH_FILE:
95  return;
96  case SSH_FX_FILE_ALREADY_EXISTS:
98  path, "remove", "directory not empty but should be removed");
100  return;
101  }
102  throwcall::sftp::good0(retval, *this, "can't remove directory ", path);
103  } else {
105  return;
106  }
107  } else {
108  auto retval = sftp_unlink(sftp, path.c_str());
109 
110  if (retval && sftp_get_error(sftp) == SSH_FX_NO_SUCH_FILE) {
112  } else {
113  throwcall::sftp::good0(retval, *this, "can't unlink ", path);
114  }
116  }
117  }

References copyRequest::done, errMsg::emit(), copyRequest::failed, libsshCommon::getUniquePtr(), throwcall::sftp::good0(), errMsg::info, libsshCommon::sftp, and copyRequest::vanished.

Here is the call graph for this function:

◆ rename()

base::renameRetvalType outputHandler::libssh::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 140 of file outputHandlerLibssh.cpp.

143  {
144  auto fromPathStatBuf = getUniquePtr(sftp_stat(sftp, fromPath.c_str()),
145  sftp_attributes_free);
146  if (fromPathStatBuf == nullptr && sftp_get_error(sftp) == SSH_FX_NO_SUCH_FILE) {
147  if (readInitialStat && readInitialStat->isDir()) { // no need to act, dirs are created on the fly
151  }
153  } else if (fromPathStatBuf == nullptr) { // curious error
154  throwcall::sftp::badval(nullptr, nullptr, *this, "can't stat '", fromPath, "'");
155  return base::renameRetvalType::cantHappen; // never reached
156  }
157  genericSftpStat fromPathStat(*fromPathStatBuf, getVfsStat(fromPath));
158  if (!readInitialStat || (! readInitialStat->isDir() &&
159  (fromPathStat.size != readInitialStat->size
160  || !fromPathStat.isSameMtimeAs(*readInitialStat)))) {
161  // the copy on fromPath is not up to date, create a new copy
162  if (readInitialStat) {
163  std::string initialTime;
164  std::string finalTime;
165  readInitialStat->getMtime(initialTime);
166  fromPathStat.getMtime(finalTime);
168  fromPath, "move"
169  "file (", toPath, ") changed unexpectedly ("
170  , initialTime, " -> ", finalTime, ", "
171  , readInitialStat->size, " -> ", fromPathStat.size
172  , ", doing fresh copy");
173  } else {
175  fromPath, "move",
176  "file (", toPath, ") has no initial stat, doing fresh copy");
177  }
179  } else { // try to move the existing copy
180  auto retval = sftp_rename(sftp, fromPath.c_str(), toPath.c_str());
181 
182  if (retval && (errno == ENOENT || errno == ENOTDIR)) {
183  if (readInitialStat->isDir()) { // no need to act, dirs are created on the fly
186  }
188  fromPath, "move",
189  "vanished unexpectedly, doing fresh copy");
190  // file was probably not copied yet, try to copy it from the move target
192  } else {
193  throwcall::good0(retval, "can't rename '", fromPath, "' to '", toPath, "'");
196  }
197  }
198  }

References throwcall::sftp::badval(), outputHandler::base::cantHappen, copyRequest::done, errMsg::emit(), outputHandler::base::fileChanged, outputHandler::base::fileVanished, genericStat::getMtime(), libsshCommon::getUniquePtr(), libsshCommon::getVfsStat(), throwcall::good0(), copyRequest::ignore, errMsg::info, genericStat::isDir(), genericStat::isSameMtimeAs(), outputHandler::base::ok, libsshCommon::sftp, and genericStat::size.

Here is the call graph for this function:

◆ renameSimple()

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

Implements outputHandler::base.

Definition at line 119 of file outputHandlerLibssh.cpp.

120  {
121  if (pathExists(toPath)) {
122  auto retval = sftp_unlink(sftp, toPath.c_str());
123  if (retval && sftp_get_error(sftp) == SSH_FX_NO_SUCH_FILE) {
125  toPath, "unlink in renameSimple",
126  "vanished");
127  } else {
128  throwcall::sftp::good0(retval, *this, "can't unlink in renameSimple ", toPath);
129  }
130  }
131  auto retval = sftp_rename(sftp, fromPath.c_str(), toPath.c_str());
132  if (retval && (sftp_get_error(sftp) == SSH_FX_NO_SUCH_FILE)) {
133  return false;
134  }
135  throwcall::sftp::good0(retval, *this, "can't rename '", fromPath, "' to '", toPath, "'");
136  return true;
137  }

References errMsg::emit(), throwcall::sftp::good0(), errMsg::notice, libsshCommon::pathExists(), and libsshCommon::sftp.

Here is the call graph for this function:

Member Data Documentation

◆ factory

factoryTemplate<libssh> outputHandler::libssh::factory
staticprivate

Definition at line 11 of file outputHandlerLibssh.h.


The documentation for this class was generated from the following files:
outputHandler::outputConfig
static davixConfigObject outputConfig("davixOut")
errMsg::location
class for defining the location of a error message in the source code.
Definition: errMsgQueue.h:14
libsshCommon::pathExists
bool pathExists(const std::string &path) override
Definition: libsshCommon.cpp:120
outputHandler::libssh::ensureParentDirs
void ensureParentDirs(const std::string &path, const std::string &srcPath, inputHandler::base *InputHandler) override
Definition: outputHandlerLibssh.cpp:43
copyRequest::stateBitType::ignore
@ ignore
errMsg::level::info
@ info
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
genericStat::size
size_t size
Definition: genericStat.h:16
outputHandler::base::renameRetvalType::fileVanished
@ fileVanished
outputHandler::base::renameRetvalType::ok
@ ok
timer::instanceUnscoped
Definition: timer.h:95
timer::anchor
Definition: timer.h:22
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
timerInst
#define timerInst(subfunc)
Definition: timer.h:157
libsshCommon::getUniquePtr
std::unique_ptr< T, void(*)(T *)> getUniquePtr(T *obj, void(*deleter)(T *))
Definition: libsshCommon.h:45
libsshCommon::sftp
sftp_session sftp
Definition: libsshCommon.h:28
genericSftpStat
Definition: libsshCommon.h:16
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
throwcall::sftp::badval
T badval(T call, t badvalue, libsshCommon &handler, const Args &... args)
Definition: libsshCommon.h:82
libsshCommon::getVfsStat
const sftp_statvfs_struct & getVfsStat(const std::string &path)
Definition: libsshCommon.cpp:152
libsshCommon::libsshCommon
libsshCommon(sshOptions &aOpt)
Definition: libsshCommon.cpp:113
throwcall::sftp::good0
void good0(T call, libsshCommon &handler, const Args &... args)
Definition: libsshCommon.h:70