@cetapod/react-native-smb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +72 -0
- package/ReactNativeSmb.podspec +59 -0
- package/cpp/ios/OnLoad.mm +24 -0
- package/cpp/shared/HybridSMB.cpp +324 -0
- package/cpp/shared/HybridSMB.hpp +102 -0
- package/cpp/shared/ReactNativeSmb.hpp +428 -0
- package/cpp/shared/connection/ContextRequest.hpp +27 -0
- package/cpp/shared/connection/ContextRequestQueue.cpp +85 -0
- package/cpp/shared/connection/ContextRequestQueue.hpp +28 -0
- package/cpp/shared/connection/MetadataContextLease.hpp +33 -0
- package/cpp/shared/connection/PoolContextHandle.cpp +35 -0
- package/cpp/shared/connection/PoolContextHandle.hpp +44 -0
- package/cpp/shared/connection/PoolSlot.cpp +73 -0
- package/cpp/shared/connection/PoolSlot.hpp +46 -0
- package/cpp/shared/connection/PoolTypes.hpp +41 -0
- package/cpp/shared/connection/SmbConnection.cpp +385 -0
- package/cpp/shared/connection/SmbConnection.hpp +93 -0
- package/cpp/shared/connection/SmbConnectionPool.cpp +316 -0
- package/cpp/shared/connection/SmbConnectionPool.hpp +84 -0
- package/cpp/shared/core/CancellationToken.hpp +22 -0
- package/cpp/shared/core/OperatorContext.hpp +24 -0
- package/cpp/shared/core/SmbEnums.hpp +126 -0
- package/cpp/shared/core/SmbTask.cpp +131 -0
- package/cpp/shared/core/SmbTask.hpp +52 -0
- package/cpp/shared/core/SmbTaskCore.cpp +222 -0
- package/cpp/shared/core/SmbTaskCore.hpp +107 -0
- package/cpp/shared/core/SmbTypes.hpp +35 -0
- package/cpp/shared/core/TaskObserverHub.cpp +166 -0
- package/cpp/shared/core/TaskObserverHub.hpp +66 -0
- package/cpp/shared/core/TaskSnapshotCodec.cpp +32 -0
- package/cpp/shared/core/TaskSnapshotCodec.hpp +41 -0
- package/cpp/shared/io/SmbCopyTree.hpp +114 -0
- package/cpp/shared/io/SmbDirScan.hpp +80 -0
- package/cpp/shared/io/SmbFileIO.cpp +1355 -0
- package/cpp/shared/io/SmbFileIO.hpp +45 -0
- package/cpp/shared/io/SmbPathUtil.hpp +75 -0
- package/cpp/shared/io/SmbSecurity.cpp +308 -0
- package/cpp/shared/io/SmbSecurity.hpp +32 -0
- package/cpp/shared/io/SmbTreeOps.hpp +112 -0
- package/cpp/shared/operators/Operator.hpp +35 -0
- package/cpp/shared/operators/OperatorBase.cpp +57 -0
- package/cpp/shared/operators/OperatorBase.hpp +57 -0
- package/cpp/shared/operators/connection/ConnectOperator.cpp +19 -0
- package/cpp/shared/operators/connection/ConnectOperator.hpp +22 -0
- package/cpp/shared/operators/connection/ConnectShareOperator.cpp +19 -0
- package/cpp/shared/operators/connection/ConnectShareOperator.hpp +21 -0
- package/cpp/shared/operators/connection/DisconnectOperator.cpp +12 -0
- package/cpp/shared/operators/connection/DisconnectOperator.hpp +15 -0
- package/cpp/shared/operators/connection/InitializeOperator.cpp +12 -0
- package/cpp/shared/operators/connection/InitializeOperator.hpp +22 -0
- package/cpp/shared/operators/connection/ListSharesOperator.cpp +13 -0
- package/cpp/shared/operators/connection/ListSharesOperator.hpp +18 -0
- package/cpp/shared/operators/listing/GetPathInfoOperator.cpp +43 -0
- package/cpp/shared/operators/listing/GetPathInfoOperator.hpp +21 -0
- package/cpp/shared/operators/listing/GetSecurityDescriptorOperator.cpp +202 -0
- package/cpp/shared/operators/listing/GetSecurityDescriptorOperator.hpp +22 -0
- package/cpp/shared/operators/listing/ListDirectoryOperator.cpp +20 -0
- package/cpp/shared/operators/listing/ListDirectoryOperator.hpp +24 -0
- package/cpp/shared/operators/mutate/CopyItemOperator.cpp +19 -0
- package/cpp/shared/operators/mutate/CopyItemOperator.hpp +25 -0
- package/cpp/shared/operators/mutate/CreateDirectoryOperator.cpp +28 -0
- package/cpp/shared/operators/mutate/CreateDirectoryOperator.hpp +20 -0
- package/cpp/shared/operators/mutate/DeleteItemOperator.cpp +96 -0
- package/cpp/shared/operators/mutate/DeleteItemOperator.hpp +23 -0
- package/cpp/shared/operators/mutate/DuplicateItemOperator.cpp +48 -0
- package/cpp/shared/operators/mutate/DuplicateItemOperator.hpp +23 -0
- package/cpp/shared/operators/mutate/MoveItemOperator.cpp +32 -0
- package/cpp/shared/operators/mutate/MoveItemOperator.hpp +21 -0
- package/cpp/shared/operators/mutate/RenameItemOperator.cpp +37 -0
- package/cpp/shared/operators/mutate/RenameItemOperator.hpp +21 -0
- package/cpp/shared/operators/transfer/DownloadFileOperator.cpp +31 -0
- package/cpp/shared/operators/transfer/DownloadFileOperator.hpp +21 -0
- package/cpp/shared/operators/transfer/UploadFileOperator.cpp +27 -0
- package/cpp/shared/operators/transfer/UploadFileOperator.hpp +21 -0
- package/cpp/shared/util/SmbErrorMapper.hpp +229 -0
- package/cpp/shared/util/SmbLog.hpp +20 -0
- package/docs/API.md +105 -0
- package/docs/ARCHITECTURE.md +70 -0
- package/docs/TASK_MODEL.md +149 -0
- package/ios/include/smb2/libsmb2-dcerpc-lsa.h +172 -0
- package/ios/include/smb2/libsmb2-dcerpc-srvsvc.h +180 -0
- package/ios/include/smb2/libsmb2-dcerpc.h +155 -0
- package/ios/include/smb2/libsmb2-raw.h +497 -0
- package/ios/include/smb2/libsmb2.h +1384 -0
- package/ios/include/smb2/smb2-errors.h +549 -0
- package/ios/include/smb2/smb2.h +1251 -0
- package/ios/libs/device/libsmb2-device.a +0 -0
- package/ios/libs/libsmb2.xcframework/Info.plist +48 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-dcerpc-lsa.h +172 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-dcerpc-srvsvc.h +180 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-dcerpc.h +155 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2-raw.h +497 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/libsmb2.h +1384 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/smb2-errors.h +549 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/Headers/smb2/smb2.h +1251 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64/libsmb2.a +0 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-dcerpc-lsa.h +172 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-dcerpc-srvsvc.h +180 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-dcerpc.h +155 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2-raw.h +497 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/libsmb2.h +1384 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/smb2-errors.h +549 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/Headers/smb2/smb2.h +1251 -0
- package/ios/libs/libsmb2.xcframework/ios-arm64_x86_64-simulator/libsmb2.a +0 -0
- package/ios/libs/simulator/libsmb2-simulator.a +0 -0
- package/lib/ReactNativeSmb.d.ts +200 -0
- package/lib/ReactNativeSmb.js +1 -0
- package/lib/bridge/decode.d.ts +4 -0
- package/lib/bridge/decode.js +92 -0
- package/lib/core/SMB.d.ts +3 -0
- package/lib/core/SMB.js +4 -0
- package/lib/core/SmbClient.d.ts +35 -0
- package/lib/core/SmbClient.js +99 -0
- package/lib/core/SmbTask.d.ts +41 -0
- package/lib/core/SmbTask.js +74 -0
- package/lib/core/TransferStore.d.ts +22 -0
- package/lib/core/TransferStore.js +88 -0
- package/lib/core/ids.d.ts +1 -0
- package/lib/core/ids.js +3 -0
- package/lib/core/taskResult.d.ts +3 -0
- package/lib/core/taskResult.js +52 -0
- package/lib/hooks/useSubscribe.d.ts +20 -0
- package/lib/hooks/useSubscribe.js +36 -0
- package/lib/hooks/useTransfers.d.ts +7 -0
- package/lib/hooks/useTransfers.js +29 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +7 -0
- package/lib/labels.d.ts +6 -0
- package/lib/labels.js +71 -0
- package/lib/types.d.ts +141 -0
- package/lib/types.js +59 -0
- package/lib/utils.d.ts +79 -0
- package/lib/utils.js +153 -0
- package/package.json +63 -0
- package/scripts/build-libsmb2.sh +143 -0
- package/scripts/create-xcframework.sh +84 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#include "DeleteItemOperator.hpp"
|
|
2
|
+
|
|
3
|
+
#include <smb2/libsmb2.h>
|
|
4
|
+
#include <smb2/smb2.h>
|
|
5
|
+
|
|
6
|
+
#include <algorithm>
|
|
7
|
+
#include <stdexcept>
|
|
8
|
+
#include <vector>
|
|
9
|
+
|
|
10
|
+
#include "../../ReactNativeSmb.hpp"
|
|
11
|
+
#include "../../io/SmbPathUtil.hpp"
|
|
12
|
+
#include "../../io/SmbTreeOps.hpp"
|
|
13
|
+
|
|
14
|
+
namespace react_native_smb {
|
|
15
|
+
|
|
16
|
+
void DeleteItemOperator::run() {
|
|
17
|
+
const CancellationToken token = cancelToken();
|
|
18
|
+
const std::string norm = path_util::normalized(path_);
|
|
19
|
+
setSourceDestination(norm, "");
|
|
20
|
+
|
|
21
|
+
bool isDirectory = false;
|
|
22
|
+
{
|
|
23
|
+
auto handle = requestContext(AcquireMode::Metadata);
|
|
24
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
25
|
+
struct smb2_stat_64 st;
|
|
26
|
+
if (smb2_stat(ctx, norm.c_str(), &st) < 0) {
|
|
27
|
+
throw std::runtime_error("Delete Failed: Could not stat '" + path_ + "'. Error: " + smb2_get_error(ctx));
|
|
28
|
+
}
|
|
29
|
+
isDirectory = (st.smb2_type & SMB2_TYPE_DIRECTORY) != 0;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!isDirectory) {
|
|
34
|
+
auto handle = requestContext(AcquireMode::Metadata);
|
|
35
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
36
|
+
const int r = smb2_unlink(ctx, norm.c_str());
|
|
37
|
+
if (r < 0) throw std::runtime_error("Failed to delete file '" + path_ + "': " + smb2_get_error(ctx));
|
|
38
|
+
});
|
|
39
|
+
emitStatus(SmbTaskStatus::Success);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
std::vector<SmbFileInfo> allItems;
|
|
44
|
+
{
|
|
45
|
+
auto handle = requestContext(AcquireMode::Metadata);
|
|
46
|
+
handle.submitSync([&](smb2_context* ctx) { tree_ops::collectAllItems(ctx, path_, allItems, token); });
|
|
47
|
+
}
|
|
48
|
+
if (isCancelled()) {
|
|
49
|
+
emitStatus(SmbTaskStatus::Cancelled);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
std::vector<SmbFileInfo> fileItems;
|
|
54
|
+
std::vector<SmbFileInfo> dirItems;
|
|
55
|
+
for (auto& item : allItems) {
|
|
56
|
+
if (item.isDirectory)
|
|
57
|
+
dirItems.push_back(std::move(item));
|
|
58
|
+
else
|
|
59
|
+
fileItems.push_back(std::move(item));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!fileItems.empty() && !isCancelled()) {
|
|
63
|
+
auto handle = requestContext(AcquireMode::Metadata);
|
|
64
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
65
|
+
for (const auto& item : fileItems) {
|
|
66
|
+
if (isCancelled()) return;
|
|
67
|
+
std::string n = path_util::normalized(item.path);
|
|
68
|
+
const int r = smb2_unlink(ctx, n.c_str());
|
|
69
|
+
if (r < 0) throw std::runtime_error("Recursive Delete Failed: Could not delete file '" + item.path + "'. Error: " + smb2_get_error(ctx));
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (isCancelled()) {
|
|
74
|
+
emitStatus(SmbTaskStatus::Cancelled);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
std::sort(dirItems.begin(), dirItems.end(), [](const SmbFileInfo& a, const SmbFileInfo& b) { return a.path.length() > b.path.length(); });
|
|
79
|
+
{
|
|
80
|
+
auto handle = requestContext(AcquireMode::Metadata);
|
|
81
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
82
|
+
for (const auto& item : dirItems) {
|
|
83
|
+
if (isCancelled()) return;
|
|
84
|
+
std::string n = path_util::normalized(item.path);
|
|
85
|
+
const int r = smb2_rmdir(ctx, n.c_str());
|
|
86
|
+
if (r < 0) throw std::runtime_error("Recursive Delete Failed: Could not delete sub-directory '" + item.path + "'. Error: " + smb2_get_error(ctx));
|
|
87
|
+
}
|
|
88
|
+
const int rootR = smb2_rmdir(ctx, norm.c_str());
|
|
89
|
+
if (rootR < 0) throw std::runtime_error("Delete Failed: Could not delete directory '" + path_ + "'. Error: " + smb2_get_error(ctx));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
emitStatus(SmbTaskStatus::Success);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
|
|
5
|
+
#include "../OperatorBase.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
// Deletes a file or a directory tree. Directory deletion walks the tree and
|
|
10
|
+
// removes deepest-first (strict ordering), so it runs self-contained on Bulk
|
|
11
|
+
// Metadata slots rather than spawning child operators.
|
|
12
|
+
class DeleteItemOperator : public OperatorBase {
|
|
13
|
+
public:
|
|
14
|
+
explicit DeleteItemOperator(std::string path) : path_(std::move(path)) {}
|
|
15
|
+
|
|
16
|
+
SmbOperatorKind kind() const override { return SmbOperatorKind::DeleteItem; }
|
|
17
|
+
void run() override;
|
|
18
|
+
|
|
19
|
+
private:
|
|
20
|
+
std::string path_;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#include "DuplicateItemOperator.hpp"
|
|
2
|
+
|
|
3
|
+
#include <smb2/libsmb2.h>
|
|
4
|
+
#include <smb2/smb2.h>
|
|
5
|
+
|
|
6
|
+
#include <string>
|
|
7
|
+
|
|
8
|
+
#include "../../io/SmbCopyTree.hpp"
|
|
9
|
+
#include "../../io/SmbPathUtil.hpp"
|
|
10
|
+
#include "../../io/SmbTreeOps.hpp"
|
|
11
|
+
|
|
12
|
+
namespace react_native_smb {
|
|
13
|
+
|
|
14
|
+
void DuplicateItemOperator::run() {
|
|
15
|
+
const CancellationToken token = cancelToken();
|
|
16
|
+
|
|
17
|
+
const std::string parentPath = path_util::parentOf(path_);
|
|
18
|
+
const std::string fileName = path_util::extractFileName(path_);
|
|
19
|
+
|
|
20
|
+
MetadataContextLease lease = makeMetadataLease();
|
|
21
|
+
|
|
22
|
+
std::string destPath;
|
|
23
|
+
lease.submitSync([&](smb2_context* ctx) {
|
|
24
|
+
std::string newName = tree_ops::generateUniqueCopyName(ctx, parentPath, fileName, token);
|
|
25
|
+
destPath = path_util::buildUrl(parentPath, newName);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
if (isCancelled() || destPath.empty()) {
|
|
29
|
+
emitStatus(SmbTaskStatus::Cancelled);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setSourceDestination(path_, destPath);
|
|
34
|
+
|
|
35
|
+
copyTreeImpl(pool(), kind(), path_, destPath, /*recursive=*/true, token, [this](double done, double total) { emitProgress(done, total); },
|
|
36
|
+
[this](int64_t n) { addExpectedBytes(n); }, owningTaskId(), &lease);
|
|
37
|
+
|
|
38
|
+
if (isCancelled()) {
|
|
39
|
+
emitStatus(SmbTaskStatus::Cancelled);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
result_ = destPath;
|
|
44
|
+
publishThisResult();
|
|
45
|
+
emitStatus(SmbTaskStatus::Success);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
|
|
5
|
+
#include "../Operator.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
// Duplicates a file or directory into the same parent with a unique
|
|
10
|
+
// "<name> copy" suffix. Returns the new path. Self-contained (reuses the same
|
|
11
|
+
// tree-copy logic as CopyItemOperator).
|
|
12
|
+
class DuplicateItemOperator : public Operator<std::string> {
|
|
13
|
+
public:
|
|
14
|
+
explicit DuplicateItemOperator(std::string path) : path_(std::move(path)) {}
|
|
15
|
+
|
|
16
|
+
SmbOperatorKind kind() const override { return SmbOperatorKind::DuplicateItem; }
|
|
17
|
+
void run() override;
|
|
18
|
+
|
|
19
|
+
private:
|
|
20
|
+
std::string path_;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#include "MoveItemOperator.hpp"
|
|
2
|
+
|
|
3
|
+
#include <smb2/libsmb2.h>
|
|
4
|
+
#include <smb2/smb2.h>
|
|
5
|
+
|
|
6
|
+
#include <stdexcept>
|
|
7
|
+
|
|
8
|
+
#include "../../connection/SmbConnectionPool.hpp"
|
|
9
|
+
#include "../../io/SmbPathUtil.hpp"
|
|
10
|
+
|
|
11
|
+
namespace react_native_smb {
|
|
12
|
+
|
|
13
|
+
void MoveItemOperator::run() {
|
|
14
|
+
|
|
15
|
+
const std::string from = path_util::normalized(fromPath_);
|
|
16
|
+
const std::string to = path_util::normalized(toPath_);
|
|
17
|
+
|
|
18
|
+
setSourceDestination(from, to);
|
|
19
|
+
|
|
20
|
+
auto handle = requestContext(AcquireMode::Interactive);
|
|
21
|
+
|
|
22
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
23
|
+
const int r = smb2_rename(ctx, from.c_str(), to.c_str());
|
|
24
|
+
if (r < 0) {
|
|
25
|
+
throw std::runtime_error("Move Failed: Could not move '" + fromPath_ + "' to '" + toPath_ + "'. Error: " + smb2_get_error(ctx));
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
emitStatus(SmbTaskStatus::Success);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
|
|
5
|
+
#include "../OperatorBase.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
class MoveItemOperator : public OperatorBase {
|
|
10
|
+
public:
|
|
11
|
+
MoveItemOperator(std::string fromPath, std::string toPath) : fromPath_(std::move(fromPath)), toPath_(std::move(toPath)) {}
|
|
12
|
+
|
|
13
|
+
SmbOperatorKind kind() const override { return SmbOperatorKind::MoveItem; }
|
|
14
|
+
void run() override;
|
|
15
|
+
|
|
16
|
+
private:
|
|
17
|
+
std::string fromPath_;
|
|
18
|
+
std::string toPath_;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#include "RenameItemOperator.hpp"
|
|
2
|
+
|
|
3
|
+
#include <smb2/libsmb2.h>
|
|
4
|
+
#include <smb2/smb2.h>
|
|
5
|
+
|
|
6
|
+
#include <stdexcept>
|
|
7
|
+
|
|
8
|
+
#include "../../connection/SmbConnectionPool.hpp"
|
|
9
|
+
#include "../../io/SmbPathUtil.hpp"
|
|
10
|
+
|
|
11
|
+
namespace react_native_smb {
|
|
12
|
+
|
|
13
|
+
void RenameItemOperator::run() {
|
|
14
|
+
if (newName_.empty() || newName_.find('/') != std::string::npos || newName_.find('\\') != std::string::npos) {
|
|
15
|
+
throw std::runtime_error("Rename Failed: invalid new name '" + newName_ + "'");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const std::string normCurrent = path_util::normalized(currentPath_);
|
|
20
|
+
const std::string parentDir = path_util::parentOf(currentPath_);
|
|
21
|
+
const std::string newPath = path_util::normalized(path_util::buildUrl(parentDir, newName_));
|
|
22
|
+
|
|
23
|
+
setSourceDestination(normCurrent, newPath);
|
|
24
|
+
|
|
25
|
+
auto handle = requestContext(AcquireMode::Interactive);
|
|
26
|
+
|
|
27
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
28
|
+
const int r = smb2_rename(ctx, normCurrent.c_str(), newPath.c_str());
|
|
29
|
+
if (r < 0) {
|
|
30
|
+
throw std::runtime_error("Rename Failed: Could not rename '" + currentPath_ + "' to '" + newName_ + "'. Error: " + smb2_get_error(ctx));
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
emitStatus(SmbTaskStatus::Success);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
|
|
5
|
+
#include "../OperatorBase.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
class RenameItemOperator : public OperatorBase {
|
|
10
|
+
public:
|
|
11
|
+
RenameItemOperator(std::string currentPath, std::string newName) : currentPath_(std::move(currentPath)), newName_(std::move(newName)) {}
|
|
12
|
+
|
|
13
|
+
SmbOperatorKind kind() const override { return SmbOperatorKind::RenameItem; }
|
|
14
|
+
void run() override;
|
|
15
|
+
|
|
16
|
+
private:
|
|
17
|
+
std::string currentPath_;
|
|
18
|
+
std::string newName_;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#include "DownloadFileOperator.hpp"
|
|
2
|
+
|
|
3
|
+
#include "../../connection/SmbConnectionPool.hpp"
|
|
4
|
+
#include "../../io/SmbFileIO.hpp"
|
|
5
|
+
#include "../../io/SmbPathUtil.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
void DownloadFileOperator::run() {
|
|
10
|
+
|
|
11
|
+
const std::string remote = path_util::normalized(remotePath_);
|
|
12
|
+
const std::string local = path_util::convertUriToPath(localPath_);
|
|
13
|
+
|
|
14
|
+
setSourceDestination(remote, local);
|
|
15
|
+
|
|
16
|
+
auto handle = requestContext(AcquireMode::Metadata);
|
|
17
|
+
|
|
18
|
+
const CancellationToken token = cancelToken();
|
|
19
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
20
|
+
smbReadFileAsync(
|
|
21
|
+
ctx, remote, local, [this](double done, double total) { emitProgress(done, total); }, token);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
if (isCancelled()) {
|
|
25
|
+
emitStatus(SmbTaskStatus::Cancelled);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
emitStatus(SmbTaskStatus::Success);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
|
|
5
|
+
#include "../OperatorBase.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
class DownloadFileOperator : public OperatorBase {
|
|
10
|
+
public:
|
|
11
|
+
DownloadFileOperator(std::string remotePath, std::string localPath) : remotePath_(std::move(remotePath)), localPath_(std::move(localPath)) {}
|
|
12
|
+
|
|
13
|
+
SmbOperatorKind kind() const override { return SmbOperatorKind::DownloadFile; }
|
|
14
|
+
void run() override;
|
|
15
|
+
|
|
16
|
+
private:
|
|
17
|
+
std::string remotePath_;
|
|
18
|
+
std::string localPath_;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#include "UploadFileOperator.hpp"
|
|
2
|
+
|
|
3
|
+
#include "../../connection/SmbConnectionPool.hpp"
|
|
4
|
+
#include "../../io/SmbFileIO.hpp"
|
|
5
|
+
#include "../../io/SmbPathUtil.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
void UploadFileOperator::run() {
|
|
10
|
+
|
|
11
|
+
const std::string remote = path_util::normalized(remotePath_);
|
|
12
|
+
const std::string local = path_util::convertUriToPath(localPath_);
|
|
13
|
+
|
|
14
|
+
setSourceDestination(local, remote); // local -> remote for upload
|
|
15
|
+
|
|
16
|
+
auto handle = requestContext(AcquireMode::Metadata);
|
|
17
|
+
|
|
18
|
+
const CancellationToken token = cancelToken();
|
|
19
|
+
handle.submitSync([&](smb2_context* ctx) {
|
|
20
|
+
smbWriteFileAsync(
|
|
21
|
+
ctx, local, remote, [this](double done, double total) { emitProgress(done, total); }, token);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
emitStatus(SmbTaskStatus::Success);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <string>
|
|
4
|
+
|
|
5
|
+
#include "../OperatorBase.hpp"
|
|
6
|
+
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
|
|
9
|
+
class UploadFileOperator : public OperatorBase {
|
|
10
|
+
public:
|
|
11
|
+
UploadFileOperator(std::string localPath, std::string remotePath) : localPath_(std::move(localPath)), remotePath_(std::move(remotePath)) {}
|
|
12
|
+
|
|
13
|
+
SmbOperatorKind kind() const override { return SmbOperatorKind::UploadFile; }
|
|
14
|
+
void run() override;
|
|
15
|
+
|
|
16
|
+
private:
|
|
17
|
+
std::string localPath_;
|
|
18
|
+
std::string remotePath_;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <algorithm>
|
|
4
|
+
#include <cctype>
|
|
5
|
+
#include <cerrno>
|
|
6
|
+
#include <cstdint>
|
|
7
|
+
#include <initializer_list>
|
|
8
|
+
#include <optional>
|
|
9
|
+
#include <string>
|
|
10
|
+
|
|
11
|
+
namespace react_native_smb {
|
|
12
|
+
|
|
13
|
+
enum class SmbErrorCode : int {
|
|
14
|
+
Unknown = 0,
|
|
15
|
+
Cancelled = 1,
|
|
16
|
+
|
|
17
|
+
InvalidArgument = 100,
|
|
18
|
+
NotFound = 101,
|
|
19
|
+
AlreadyExists = 102,
|
|
20
|
+
AccessDenied = 103,
|
|
21
|
+
NotDirectory = 104,
|
|
22
|
+
IsDirectory = 105,
|
|
23
|
+
DirectoryNotEmpty = 106,
|
|
24
|
+
|
|
25
|
+
NotConnected = 200,
|
|
26
|
+
ConnectionRefused = 201,
|
|
27
|
+
TimedOut = 202,
|
|
28
|
+
|
|
29
|
+
Busy = 300,
|
|
30
|
+
NoSpace = 301,
|
|
31
|
+
Io = 302,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
class SmbErrorMapper {
|
|
35
|
+
public:
|
|
36
|
+
static int normalizeErrnoCode(int resultCode) {
|
|
37
|
+
if (resultCode == 0) {
|
|
38
|
+
return 0;
|
|
39
|
+
}
|
|
40
|
+
return resultCode < 0 ? -resultCode : resultCode;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static int fromErrnoResult(int resultCode) { return fromErrno(normalizeErrnoCode(resultCode)); }
|
|
44
|
+
|
|
45
|
+
static int fromErrnoOrMessage(int errnoCode, const std::string& errorMessage) {
|
|
46
|
+
const int mappedFromErrno = fromErrno(errnoCode);
|
|
47
|
+
if (mappedFromErrno != static_cast<int>(SmbErrorCode::Unknown)) {
|
|
48
|
+
return mappedFromErrno;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return fromMessage(errorMessage);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static int fromErrno(int errnoCode) {
|
|
55
|
+
switch (errnoCode) {
|
|
56
|
+
case 0:
|
|
57
|
+
return static_cast<int>(SmbErrorCode::Unknown);
|
|
58
|
+
case ECANCELED:
|
|
59
|
+
return static_cast<int>(SmbErrorCode::Cancelled);
|
|
60
|
+
case EINVAL:
|
|
61
|
+
return static_cast<int>(SmbErrorCode::InvalidArgument);
|
|
62
|
+
case ENOENT:
|
|
63
|
+
return static_cast<int>(SmbErrorCode::NotFound);
|
|
64
|
+
case EEXIST:
|
|
65
|
+
return static_cast<int>(SmbErrorCode::AlreadyExists);
|
|
66
|
+
case EACCES:
|
|
67
|
+
case EPERM:
|
|
68
|
+
return static_cast<int>(SmbErrorCode::AccessDenied);
|
|
69
|
+
case ENOTDIR:
|
|
70
|
+
return static_cast<int>(SmbErrorCode::NotDirectory);
|
|
71
|
+
case EISDIR:
|
|
72
|
+
return static_cast<int>(SmbErrorCode::IsDirectory);
|
|
73
|
+
case ENOTEMPTY:
|
|
74
|
+
return static_cast<int>(SmbErrorCode::DirectoryNotEmpty);
|
|
75
|
+
case ENOTCONN:
|
|
76
|
+
case EHOSTUNREACH:
|
|
77
|
+
case EPIPE:
|
|
78
|
+
#ifdef ENETRESET
|
|
79
|
+
case ENETRESET:
|
|
80
|
+
#endif
|
|
81
|
+
return static_cast<int>(SmbErrorCode::NotConnected);
|
|
82
|
+
case ECONNREFUSED:
|
|
83
|
+
return static_cast<int>(SmbErrorCode::ConnectionRefused);
|
|
84
|
+
case ETIMEDOUT:
|
|
85
|
+
return static_cast<int>(SmbErrorCode::TimedOut);
|
|
86
|
+
case EBUSY:
|
|
87
|
+
return static_cast<int>(SmbErrorCode::Busy);
|
|
88
|
+
case ENOSPC:
|
|
89
|
+
return static_cast<int>(SmbErrorCode::NoSpace);
|
|
90
|
+
case EIO:
|
|
91
|
+
return static_cast<int>(SmbErrorCode::Io);
|
|
92
|
+
default:
|
|
93
|
+
return static_cast<int>(SmbErrorCode::Unknown);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private:
|
|
98
|
+
static int fromMessage(const std::string& errorMessage) {
|
|
99
|
+
if (errorMessage.empty()) {
|
|
100
|
+
return static_cast<int>(SmbErrorCode::Unknown);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
std::string upper = errorMessage;
|
|
104
|
+
std::transform(upper.begin(), upper.end(), upper.begin(), [](unsigned char c) { return static_cast<char>(std::toupper(c)); });
|
|
105
|
+
|
|
106
|
+
if (const auto ntStatus = extractNtStatusHex(upper); ntStatus.has_value()) {
|
|
107
|
+
const int mapped = fromNtStatus(*ntStatus);
|
|
108
|
+
if (mapped != static_cast<int>(SmbErrorCode::Unknown)) {
|
|
109
|
+
return mapped;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (containsAny(upper, {"STATUS_OBJECT_NAME_COLLISION", "FILE_EXISTS", "EEXIST"})) {
|
|
114
|
+
return static_cast<int>(SmbErrorCode::AlreadyExists);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (containsAny(upper, {"STATUS_OBJECT_NAME_NOT_FOUND", "STATUS_OBJECT_PATH_NOT_FOUND", "STATUS_NO_SUCH_FILE", "NO SUCH FILE"})) {
|
|
118
|
+
return static_cast<int>(SmbErrorCode::NotFound);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (containsAny(upper, {"STATUS_ACCESS_DENIED", "STATUS_LOGON_FAILURE", "ACCESS_DENIED", "PERMISSION DENIED"})) {
|
|
122
|
+
return static_cast<int>(SmbErrorCode::AccessDenied);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (contains(upper, "STATUS_NOT_A_DIRECTORY")) {
|
|
126
|
+
return static_cast<int>(SmbErrorCode::NotDirectory);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (contains(upper, "STATUS_FILE_IS_A_DIRECTORY")) {
|
|
130
|
+
return static_cast<int>(SmbErrorCode::IsDirectory);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (contains(upper, "STATUS_DIRECTORY_NOT_EMPTY")) {
|
|
134
|
+
return static_cast<int>(SmbErrorCode::DirectoryNotEmpty);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (containsAny(upper, {"STATUS_CONNECTION_DISCONNECTED", "STATUS_NETWORK_NAME_DELETED", "BROKEN PIPE"})) {
|
|
138
|
+
return static_cast<int>(SmbErrorCode::NotConnected);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if (contains(upper, "STATUS_CONNECTION_REFUSED")) {
|
|
142
|
+
return static_cast<int>(SmbErrorCode::ConnectionRefused);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (containsAny(upper, {"STATUS_IO_TIMEOUT", "TIMED OUT"})) {
|
|
146
|
+
return static_cast<int>(SmbErrorCode::TimedOut);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (containsAny(upper, {"STATUS_SHARING_VIOLATION", "RESOURCE BUSY"})) {
|
|
150
|
+
return static_cast<int>(SmbErrorCode::Busy);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (containsAny(upper, {"STATUS_DISK_FULL", "NO SPACE"})) {
|
|
154
|
+
return static_cast<int>(SmbErrorCode::NoSpace);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (containsAny(upper, {"STATUS_IO_DEVICE_ERROR", "I/O"})) {
|
|
158
|
+
return static_cast<int>(SmbErrorCode::Io);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return static_cast<int>(SmbErrorCode::Unknown);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static int fromNtStatus(uint32_t ntStatus) {
|
|
165
|
+
switch (ntStatus) {
|
|
166
|
+
case 0xC0000034: // STATUS_OBJECT_NAME_NOT_FOUND
|
|
167
|
+
case 0xC000003A: // STATUS_OBJECT_PATH_NOT_FOUND
|
|
168
|
+
return static_cast<int>(SmbErrorCode::NotFound);
|
|
169
|
+
case 0xC0000035: // STATUS_OBJECT_NAME_COLLISION
|
|
170
|
+
return static_cast<int>(SmbErrorCode::AlreadyExists);
|
|
171
|
+
case 0xC0000022: // STATUS_ACCESS_DENIED
|
|
172
|
+
case 0xC000006D: // STATUS_LOGON_FAILURE
|
|
173
|
+
return static_cast<int>(SmbErrorCode::AccessDenied);
|
|
174
|
+
case 0xC0000103: // STATUS_NOT_A_DIRECTORY
|
|
175
|
+
return static_cast<int>(SmbErrorCode::NotDirectory);
|
|
176
|
+
case 0xC00000BA: // STATUS_FILE_IS_A_DIRECTORY
|
|
177
|
+
return static_cast<int>(SmbErrorCode::IsDirectory);
|
|
178
|
+
case 0xC0000101: // STATUS_DIRECTORY_NOT_EMPTY
|
|
179
|
+
return static_cast<int>(SmbErrorCode::DirectoryNotEmpty);
|
|
180
|
+
case 0xC00000B5: // STATUS_IO_TIMEOUT
|
|
181
|
+
return static_cast<int>(SmbErrorCode::TimedOut);
|
|
182
|
+
case 0xC000007F: // STATUS_DISK_FULL
|
|
183
|
+
return static_cast<int>(SmbErrorCode::NoSpace);
|
|
184
|
+
case 0xC00000E9: // STATUS_UNEXPECTED_IO_ERROR
|
|
185
|
+
case 0xC0000185: // STATUS_IO_DEVICE_ERROR / transport I/O
|
|
186
|
+
return static_cast<int>(SmbErrorCode::Io);
|
|
187
|
+
default:
|
|
188
|
+
return static_cast<int>(SmbErrorCode::Unknown);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
static std::optional<uint32_t> extractNtStatusHex(const std::string& upperMessage) {
|
|
193
|
+
size_t pos = 0;
|
|
194
|
+
while ((pos = upperMessage.find("0X", pos)) != std::string::npos) {
|
|
195
|
+
size_t hexStart = pos + 2;
|
|
196
|
+
size_t hexEnd = hexStart;
|
|
197
|
+
|
|
198
|
+
while (hexEnd < upperMessage.size() && std::isxdigit(static_cast<unsigned char>(upperMessage[hexEnd]))) {
|
|
199
|
+
++hexEnd;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const size_t hexLen = hexEnd - hexStart;
|
|
203
|
+
if (hexLen >= 6 && hexLen <= 8) {
|
|
204
|
+
try {
|
|
205
|
+
const auto parsed = static_cast<uint32_t>(std::stoul(upperMessage.substr(hexStart, hexLen), nullptr, 16));
|
|
206
|
+
return parsed;
|
|
207
|
+
} catch (...) {
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
pos = hexStart;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return std::nullopt;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
static bool contains(const std::string& haystack, const char* needle) { return haystack.find(needle) != std::string::npos; }
|
|
218
|
+
|
|
219
|
+
static bool containsAny(const std::string& haystack, std::initializer_list<const char*> needles) {
|
|
220
|
+
for (const char* needle : needles) {
|
|
221
|
+
if (contains(haystack, needle)) {
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
} // namespace react_native_smb
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
// Diagnostic logging: os_log on Apple, __android_log_print on Android, fprintf(stderr) elsewhere.
|
|
4
|
+
|
|
5
|
+
#if defined(__APPLE__)
|
|
6
|
+
#include <os/log.h>
|
|
7
|
+
namespace react_native_smb {
|
|
8
|
+
inline os_log_t smb_log_handle() {
|
|
9
|
+
static os_log_t h = os_log_create("com.cetapod.smb", "smb");
|
|
10
|
+
return h;
|
|
11
|
+
}
|
|
12
|
+
} // namespace react_native_smb
|
|
13
|
+
#define SMB_LOG(fmt, ...) os_log(::react_native_smb::smb_log_handle(), "[smb] " fmt, ##__VA_ARGS__)
|
|
14
|
+
#elif defined(__ANDROID__)
|
|
15
|
+
#include <android/log.h>
|
|
16
|
+
#define SMB_LOG(fmt, ...) __android_log_print(ANDROID_LOG_INFO, "smb", fmt, ##__VA_ARGS__)
|
|
17
|
+
#else
|
|
18
|
+
#include <cstdio>
|
|
19
|
+
#define SMB_LOG(fmt, ...) std::fprintf(stderr, "[smb] " fmt "\n", ##__VA_ARGS__)
|
|
20
|
+
#endif
|