27 return std::unique_ptr<base::reader>(
new readerLibssh(aPath,
35 std::vector<char>& target) {
36 auto targetString = sftp_readlink(
sftp, path.c_str());
37 if (targetString ==
nullptr && sftp_get_error(
sftp) == SSH_FX_NO_SUCH_FILE) {
41 auto linklength = strlen(targetString);
42 if (linklength >= target.size()) {
43 ssh_string_free_char(targetString);
44 throw std::runtime_error(
"link size increased after stat for " + path);
46 for (
auto c = targetString; *c; c++) {
47 target.at(c - targetString) = *c;
49 ssh_string_free_char(targetString);
50 target[linklength] =
'\0';
62 reader(inititalStat) {
64 if (
file ==
nullptr) {
65 if (sftp_get_error(
handler.
sftp) == SSH_FX_NO_SUCH_FILE) {
74 if (file !=
nullptr) {
76 if (sftp_close(file) == SSH_ERROR) {
78 path,
"close during unwind ",
79 "sftp error ", sftp_get_error(handler.sftp),
80 ", ssh error ", ssh_get_error(handler.session));
85 "can't close ", path,
" after reading");
94 "can't seek ", path,
" to ", pos);
98 b.
clear(totalBytesRead);
99 bool lastblock =
false;
103 while (b.
size() + blockSize <= bytesToRead) {
105 auto bytes_read = sftp_read(file, b.
bufferAt(b.
size()), blockSize);
106 if (bytes_read < 0) {
110 if (bytes_read == 0) {
112 if (totalBytesRead < readInitialStat.size) {
114 std::to_string(readInitialStat.size) +
116 std::to_string(totalBytesRead) +
121 totalBytesRead += bytes_read;
122 if (totalBytesRead > readInitialStat.size) {
124 std::to_string(readInitialStat.size) +
126 std::to_string(totalBytesRead) +
142 sftp_attributes_free(stat);
143 if (readFinalStat.
size != readInitialStat.size) {
145 std::to_string(readInitialStat.size) +
147 std::to_string(readFinalStat.
size) +
148 ") during reading on " + path);
153 std::to_string(std::chrono::duration_cast<std::chrono::duration<double>>(readFinalStat.
getMtime() - readInitialStat.getMtime()).count()) +
154 "s different mtime) during reading");
160 const std::string& aPath):
165 "can't open directory ", path);
169 if (sftp_closedir(dir) == SSH_ERROR) {
171 path,
"close during unwind ",
172 "sftp error ", sftp_get_error(handler.sftp),
173 ", ssh error ", ssh_get_error(handler.session));
177 "can't close directory");
181 while (
auto entry = sftp_readdir(handler.sftp, dir)) {
182 if (entry->name[entry->name[0] !=
'.' ? 0 : entry->name[1] !=
'.' ? 1 : 2] ==
'\0') {
183 sftp_attributes_free(entry);
186 auto genStat = std::unique_ptr<const genericStat>(
new genericSftpStat(*entry,
187 handler.getVfsStat(path)));
188 auto retval =
new Entry(entry->name, genStat);
189 sftp_attributes_free(entry);
190 return std::unique_ptr<Entry>(retval);
195 return std::unique_ptr<Directory>(
new SftpDirectory(*
this, path));