commit b6966e8560b0fc0e9fa3d74832e1010c73d8bff9
parent 7b369dafb749ba6bf6442e7440146b834a8b9600
Author: Remy Noulin <loader2x@gmail.com>
Date: Sat, 13 Aug 2022 17:04:31 -0400
add receive recursive and globbing in server
NOTES.md | 6 +--
sclient.c | 23 ++++++--
sserver.c | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++-----------
3 files changed, 171 insertions(+), 39 deletions(-)
Diffstat:
| M | NOTES.md | | | 6 | +++--- |
| M | sclient.c | | | 23 | +++++++++++++++++++---- |
| M | sserver.c | | | 181 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- |
3 files changed, 171 insertions(+), 39 deletions(-)
diff --git a/NOTES.md b/NOTES.md
@@ -11,7 +11,7 @@ x./sclient.c dev:NOTES.md
x./sclient.c dev:NOTES.md ../
x./sclient.c dev:NOTES.md test.txt
-cp file tuyau://ip/path
+//cp file tuyau://ip/path
0 frame send file:
1 byte command
@@ -49,8 +49,8 @@ port 1032
..- mkdir
..- send files with glob
..- send files recursive
-- receive files, glob
-- receive files recursive
+..- receive files, glob
+..- receive files recursive
//- list files in path
..- token, home directory
..- server name ip port in config
diff --git a/sclient.c b/sclient.c
@@ -358,10 +358,15 @@ bool saveReceivedData(void *receiveB, size_t sz, void *context) {
if (not root) {
// save file in current directory
- path = strdup(filename);
+ if (not destPath) {
+ path = strdup(filename);
+ }
+ else {
+ path = catS(destPath, "/", filename);
+ }
}
elif (isDir(root)) {
- path = catS(root, "/", filename);
+ path = catS(root, "/", nS(destPath), "/", filename);
}
else {
// root has a filename
@@ -393,13 +398,23 @@ bool saveReceivedData(void *receiveB, size_t sz, void *context) {
}
elif (*command == 1) {
// mkdir
- TODO("mkdir");
+ if (root and not isDir(root)) {
+ logE("Cant create directory if root is not a directory %s", root);
+ ret yes;
+ }
+ logD("mkdir");
u16 *filemode = (u16*)(receiveB + 9);
u16 *pathLength = (u16*)(receiveB + 11);
cleanCharP(destPath) = malloc(*pathLength + 1);
memcpy(destPath, receiveB + 13, *pathLength);
destPath[*pathLength] = 0;
- char *path = catS(root, "/", destPath);
+ cleanCharP(path) = null;
+ if (not root) {
+ path = strdup(destPath);
+ }
+ else {
+ path = catS(root, "/", destPath);
+ }
pErrorNULL(normalizePathG(&path));
pErrorNULL(trimG(&path));
logD(BLD GRN"mkdir" RST);
diff --git a/sserver.c b/sserver.c
@@ -13,6 +13,8 @@
#include <sys/stat.h>
#include <fcntl.h>
+#include <glob.h>
+
#include "netFrame.h"
#include "shpPackages/short/short.h"
#include "makeHeader.h"
@@ -188,7 +190,7 @@ void saveReceivedData(void *receiveB, size_t sz) {
cleanCharP(destPath) = malloc(*pathLength + 1);
memcpy(destPath, receiveB + 13, *pathLength);
destPath[*pathLength] = 0;
- char *path = catS(root, "/", destPath);
+ cleanCharP(path) = catS(root, "/", destPath);
pErrorNULL(normalizePathG(&path));
pErrorNULL(trimG(&path));
logD(BLD GRN"mkdir" RST);
@@ -197,11 +199,12 @@ void saveReceivedData(void *receiveB, size_t sz) {
pError0(fileChmod(path, *filemode));
}
elif (*command == 2) {
- TODO("send files to client, send back sendFile basename");
+ logD("send files to client");
u16 *sendFileLength = (u16*)(receiveB + 9);
cleanCharP(sendFile) = malloc(*sendFileLength + 1);
memcpy(sendFile, receiveB + 11, *sendFileLength);
sendFile[*sendFileLength] = 0;
+
pErrorNULL(prependG(&sendFile, '/'));
pErrorNULL(prependG(&sendFile, root));
pErrorNULL(normalizePathG(&sendFile));
@@ -212,50 +215,164 @@ void saveReceivedData(void *receiveB, size_t sz) {
logE("Incorrect path, outside home directory: "BLD YLW"%s"RST,sendFile);
ret;
}
- if (not isPath(sendFile)) {
- logE("Incorrect path: "BLD YLW"%s"RST,sendFile);
- ret;
+
+ cleanAllocateSmallArray(pathToSend);
+
+ if (isPath(sendFile)) {
+ pushG(pathToSend, sendFile);
+ }
+ else {
+ // check if sendFile is a glob
+ glob_t globbuf = init0Var;
+ glob(sendFile, 0, NULL, &globbuf);
+ if (!globbuf.gl_pathv) {
+ logE("Incorrect path: "BLD YLW"%s"RST,sendFile);
+ ret;
+ }
+ forEachS(globbuf.gl_pathv, s) {
+ pushG(pathToSend, s);
+ }
+ globfree(&globbuf);
}
cleanAllocateNetFrame(netframe);
u8 buf[1024*1024] = init0Var;
- // send
- u32 bufi = 0;
- u64 *filesize = null;
- makeHeader(buf, &bufi, 0 /* command */, null/*svrInfo no need to authenticate the client*/, sendFile, null/*destPath is already selected in client*/, &filesize);
+ cleanAllocateSmallDict(recusive);
- if (*filesize < (sizeof(buf) - bufi)) {
- pError0(bReadFile(sendFile, buf + bufi));
- o(netframe,send , mysock, buf, bufi + *filesize);
- }
- else {
- logD("big file");
- u64 szToSend = *filesize;
- u8 *b = buf + bufi;
- u64 bSz = sizeof(buf) - bufi;
- int fd = open(sendFile, O_RDONLY);
- do {
- if (szToSend <= bSz) {
- read(fd, b, szToSend);
- o(netframe,send , mysock, b, szToSend);
- szToSend = 0;
+ iter(pathToSend, P) {
+ castS(p, P);
+ char *sendFile = ssGet(P);
+
+ if (isDirG(p)) {
+ logD("mkdir in client");
+
+ char *dirname = basename(ssGet(p));
+
+ u32 bufi = 0;
+ u64 *filesize = null;
+ makeHeader(buf, &bufi, 1 /* command */, null/*svrInfo no need to authenticate the client*/, ssGet(P), dirname/*dest*/, &filesize);
+
+ o(netframe,send , mysock, buf, bufi);
+
+ var dir = readDirAllG(rtSmallArrayt, p);
+ //lv(dir);
+ if (not isEmptyG(dir)) {
+ pushG(dir, ssGet(p));
+ setNFreeG(recusive, dirname, dir);
}
- else {
- read(fd, b, bSz);
- if (szToSend == *filesize) {
- o(netframe,send , mysock, buf, bufi + bSz);
+ lv(recusive);
+ continue;
+ }
+
+ // send
+ u32 bufi = 0;
+ u64 *filesize = null;
+ makeHeader(buf, &bufi, 0 /* command */, null/*svrInfo no need to authenticate the client*/, sendFile, null/*destPath is already selected in client*/, &filesize);
+
+ if (*filesize < (sizeof(buf) - bufi)) {
+ pError0(bReadFile(sendFile, buf + bufi));
+ o(netframe,send , mysock, buf, bufi + *filesize);
+ }
+ else {
+ logD("big file");
+ u64 szToSend = *filesize;
+ u8 *b = buf + bufi;
+ u64 bSz = sizeof(buf) - bufi;
+ int fd = open(sendFile, O_RDONLY);
+ do {
+ if (szToSend <= bSz) {
+ read(fd, b, szToSend);
+ o(netframe,send , mysock, b, szToSend);
+ szToSend = 0;
}
else {
- o(netframe,send , mysock, b, bSz);
+ read(fd, b, bSz);
+ if (szToSend == *filesize) {
+ o(netframe,send , mysock, buf, bufi + bSz);
+ }
+ else {
+ o(netframe,send , mysock, b, bSz);
+ }
+ szToSend -= bSz;
+ }
+ } while(szToSend);
+ close(fd);
+ }
+ } // sendFile or globbing
+
+ // Send files recursively
+
+ iter(recusive, A) {
+ cast(smallArrayt*,a,A);
+ cleanCharP(localPath) = cropElemG(a, rtChar, -1);
+ lv(localPath);
+ iter(a, P) {
+ castS(p, P);
+ char *sendFile = ssGet(P);
+
+ cleanCharP(localp) = catS(localPath, "/", ssGet(p));
+ if (isDirG(localp)) {
+ logD("mkdir in client");
+ cleanCharP(dirname) = catS(iK(recusive), "/", ssGet(p));
+
+ u32 bufi = 0;
+ u64 *filesize = null;
+ makeHeader(buf, &bufi, 1 /* command */, null/*svrInfo no need to authenticate the client*/, localp, dirname, &filesize);
+
+ o(netframe,send , mysock, buf, bufi);
+
+ var dir = readDirAllG(rtSmallArrayt, localp);
+ lv(dir);
+ if (not isEmptyG(dir)) {
+ pushG(dir, localp);
+ setNFreeG(recusive, dirname, dir);
}
- szToSend -= bSz;
+ //lv(recusive);
+ continue;
}
- } while(szToSend);
- close(fd);
+
+ logD("Send localp file to iK(recusive) client directory");
+ // send
+ u32 bufi = 0;
+ u64 *filesize = null;
+ makeHeader(buf, &bufi, 0 /* command */, null/*svrInfo no need to authenticate the client*/, localp, (char*)iK(recusive) /*dest*/, &filesize);
+
+ if (*filesize < (sizeof(buf) - bufi)) {
+ pError0(bReadFile(localp, buf + bufi));
+ o(netframe,send , mysock, buf, bufi + *filesize);
+ }
+ else {
+ logD("big file");
+ u64 szToSend = *filesize;
+ u8 *b = buf + bufi;
+ u64 bSz = sizeof(buf) - bufi;
+ int fd = open(localp, O_RDONLY);
+ do {
+ if (szToSend <= bSz) {
+ read(fd, b, szToSend);
+ o(netframe,send , mysock, b, szToSend);
+ szToSend = 0;
+ }
+ else {
+ read(fd, b, bSz);
+ if (szToSend == *filesize) {
+ o(netframe,send , mysock, buf, bufi + bSz);
+ }
+ else {
+ o(netframe,send , mysock, b, bSz);
+ }
+ szToSend -= bSz;
+ }
+ } while(szToSend);
+ close(fd);
+ }
+ }
}
+ lv(recusive);
+
// last frame size 0
// close connection
o(netframe,end, mysock);