ewmscp  ..
cmdLineRequestProvider.cpp
Go to the documentation of this file.
2 #include "scoped.h"
3 #include "throwcall.h"
4 #include "escapism.h"
5 #include "timer.h"
6 #include <errMsgQueue.h>
7 
9  "follow command-line symbolic links in SOURCE", false);
11  "treat directories recursively", false);
12 
14 
16 
17 
18 const singleMap& cmdLineRequestProvider::getDstPath(const std::string& source,
19  std::string& destination,
20  bool baseNameOnly) {
21  if (!singleDestination.empty() || noCopy) { // we have the special case that we have one destination file only
22  destination = singleDestination;
23  static singleMap singleDestMap(source, singleDestination);
24  return singleDestMap;
25  }
26  return requestProvider::getDstPath(source, destination, baseNameOnly);
27 }
28 
29 void cmdLineRequestProvider::prepareMappings(std::vector<std::string>& sources,
30  std::string& destination) {
31  std::string dstdir;
32  auto dstStat = OutputHandler->getStat(destination);
33  if (dstStat == nullptr) { // destination does not exist, create the new file in the working dir
34  if (recursive) {
35  dstdir = destination;
36  } else {
37  singleDestination = destination;
38  }
39  } else {
40  if (dstStat->isDir()) {
41  dstdir = destination;
42  } else {
43  singleDestination = destination;
44  }
45  }
46 
47  if (!dstdir.empty()) {
48  if (sources.size() == 1) { // special case
49  auto srcStat = InputHandler->getStat(sources.front());
50  if (srcStat && srcStat->isDir()) {
51  pathMap.emplace(sources.front(), dstdir);
52  return; // all set, we may return
53  }
54  }
55 
56  if (workDir.fIsSet()) {
57  pathMap.emplace(workDir, dstdir);
58  } else {
59  pathMap.emplace("", dstdir);
60  }
61  }
62  if (dstdir.empty() && pathMap.empty() &&
63  (sources.size() > 1 || recursive) && !noCopy) {
64  throw std::runtime_error("multiple sources and destination is not a directory");
65  }
66 }
67 
68 void cmdLineRequestProvider::printMappings(std::ostream& stream) {
69  if (singleDestination.empty()) {
70  stream << "no special singleDestination (used for cmdLineRequestProvider only)\n";
71  } else {
72  stream << "special destination: '" << singleDestination << "'\n";
73  }
75 }
76 void cmdLineRequestProvider::processSource(const std::string& source) {
77  auto sourceStat = InputHandler->getStat(source, dereferenceCmdLine);
78  if (!sourceStat) {
79  if (ignoreMissing) {
80  if (! quiet) {
82  source, "stat", "not found");
83  }
84  return;
85  }
86  throw std::runtime_error("can't stat " + source);
87  }
88  if (sourceStat->isDir()) {
90  std::string dstPath;
91  auto mapEntry = getDstPath(source, dstPath, !parents);
92  addDirContent(source, dstPath, mapEntry, *sourceStat);
93  } else {
94  throw std::runtime_error(source + " is a directory");
95  }
96  } else {
97  std::string dst;
98  auto mapEntry = getDstPath(source, dst, !parents);
99  timerInst(emplace);
100  requestSet.emplace(newRequest(InputHandler, source, dst, sourceStat,
101  mapEntry,
102  false, copyRequest::clock_type::now()));
103  }
104 }
105 
106 void cmdLineRequestProvider::addDirContent(const std::string& srcpath,
107  const std::string& dstpath,
108  const singleMap& mapEntry,
109  const genericStat& dirStat) {
110  // with the subdir list we have only one open dir at a time
111  class subdirType {
112  public:
113  std::string srcPath;
114  std::string dstPath;
115  std::unique_ptr<const genericStat> dirStat;
116  subdirType(const std::string& aSrcPath,
117  const std::string& aDstPath,
118  std::unique_ptr<const genericStat>& aDirStat) :
119  srcPath(aSrcPath),
120  dstPath(aDstPath),
121  dirStat(std::move(aDirStat)) {};
122  };
123  std::list<subdirType> subdirs;
124  {
125  auto dir = InputHandler->getDirectory(srcpath);
126  while (auto entry = dir->getNextEntry(ignoreMissing)) {
127  std::string subpath(srcpath);
128  subpath += "/";
129  subpath += entry->getName();
130  std::string destpath(dstpath);
131  destpath += "/";
132  destpath += entry->getName();
133  auto entryStat = entry->getStat();
134  if (entryStat->isDir() &&
135  entryStat->device == dirStat.device &&
136  recursive) {
137  subdirs.emplace_back(subpath, destpath, entryStat);
138  } else {
139  if (entryStat->isRegularFile() || entryStat->isLink() || processCmdLineDirs) {
140  timerInst(emplace);
141  requestSet.emplace(newRequest(InputHandler, subpath, destpath, entryStat,
142  mapEntry,
143  false, copyRequest::clock_type::now()));
144  }
145  }
146  }
147  }
148 
149  for (auto& subdir : subdirs) {
150  addDirContent(subdir.srcPath, subdir.dstPath, mapEntry, *(subdir.dirStat));
151  if (processCmdLineDirs) { // special case for listingRequestProvider
152  timerInst(emplace);
153  requestSet.emplace(newRequest(InputHandler, subdir.srcPath, subdir.dstPath, subdir.dirStat,
154  mapEntry,
155  false, copyRequest::clock_type::now()));
156  }
157  }
158 }
noFollowRequestProvider::ignoreMissing
static options::single< bool > ignoreMissing
Definition: noFollowRequestProvider.h:11
errMsgQueue.h
errMsg::level::warning
@ warning
noCopy
options::single< bool > noCopy
workDir
options::single< std::string > workDir
errMsg::location
class for defining the location of a error message in the source code.
Definition: errMsgQueue.h:14
inputHandler::base::getDirectory
virtual std::unique_ptr< Directory > getDirectory(const std::string &path)=0
cmdLineRequestProvider.h
genericStat
generic stat abstraction class Used to abstract the variants of the stat structure.
Definition: genericStat.h:12
options::base::fIsSet
virtual bool fIsSet() const
check if this option was set, regardless of from command line or config file
Definition: Options.h:263
cmdLineRequestProvider::processSource
void processSource(const std::string &source) override
Definition: cmdLineRequestProvider.cpp:76
cmdLineRequestProvider::getDstPath
const singleMap & getDstPath(const std::string &source, std::string &destination, bool baseNameOnly=false) override
get detstination papth for a given source path
Definition: cmdLineRequestProvider.cpp:18
cmdLineRequestProvider::recursive
static options::single< bool > recursive
Definition: cmdLineRequestProvider.h:13
requestProvider::parents
bool parents
Definition: requestProvider.h:33
scoped.h
cmdLineRequestProvider::processCmdLineDirs
bool processCmdLineDirs
Definition: cmdLineRequestProvider.h:16
cmdLineRequestProvider::addDirContent
virtual void addDirContent(const std::string &srcpath, const std::string &dstpath, const singleMap &mapEntry, const genericStat &dirStat)
Definition: cmdLineRequestProvider.cpp:106
escapism.h
timer.h
throwcall.h
noFollowRequestProvider::newRequest
virtual copyRequest::base * newRequest(inputHandler::base *InputHandler, const std::string &aSource, const std::string &aDestination, std::unique_ptr< const genericStat > &aStat, const singleMap &aMapEntry, bool remove, copyRequest::clock_type::time_point timestamp)
Definition: noFollowRequestProvider.cpp:15
requestProvider::OutputHandler
outputHandler::base * OutputHandler
Definition: requestProvider.h:35
defineStaticNoArg
#define defineStaticNoArg(var)
defines a static variable that needs no arguments to it's constructor
Definition: ewmscp.h:44
genericStat::device
dev_t device
Definition: genericStat.h:15
cmdLineRequestProvider::prepareMappings
void prepareMappings(std::vector< std::string > &sources, std::string &destination) override
Definition: cmdLineRequestProvider.cpp:29
cmdLineRequestProvider::printMappings
void printMappings(std::ostream &stream) override
Definition: cmdLineRequestProvider.cpp:68
requestProvider::pathMap
static options::map< std::string, pathMapType > pathMap
Definition: requestProvider.h:29
pathHandler::getStat
virtual std::unique_ptr< const genericStat > getStat(const std::string &path, bool followLink=true)=0
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
singleMap
std::pair< std::string, std::string > singleMap
Definition: copyRequest.h:52
requestProvider::InputHandler
inputHandler::base * InputHandler
Definition: requestProvider.h:34
requestProvider::printMappings
virtual void printMappings(std::ostream &stream)
Definition: requestProvider.cpp:81
cmdLineRequestProvider::factory
static factoryTemplate< cmdLineRequestProvider > factory
Definition: cmdLineRequestProvider.h:11
noFollowRequestProvider::requestSet
static std::multiset< copyRequest::base *, copyRequest::base::pointerCompare > requestSet
Definition: noFollowRequestProvider.h:13
requestProvider::getDstPath
virtual const singleMap & getDstPath(const std::string &source, std::string &destination, bool baseNameOnly=false)
get detstination papth for a given source path
Definition: requestProvider.cpp:30
quiet
static options::single< bool > quiet('q', "quiet", "be quiet, no prefix to output lines")
cmdLineRequestProvider::singleDestination
static std::string singleDestination
Definition: cmdLineRequestProvider.h:15
cmdLineRequestProvider::dereferenceCmdLine
static options::single< bool > dereferenceCmdLine
Definition: cmdLineRequestProvider.h:14
defineStatic
#define defineStatic(var,...)
defines a static variable and instatitates the constructor with the variable number of arguments.
Definition: ewmscp.h:42