From a4b1b63a2bffe7675ae63bad6556af81dd4ddcbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=AE=D1=80=D0=B8=D0=B9=20=D0=94=D0=B0=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= <75733634+LxrdTendx@users.noreply.github.com> Date: Sat, 4 Dec 2021 16:43:40 +0300 Subject: [PATCH 1/4] Update ftp-server.py --- ftp-server.py | 247 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 234 insertions(+), 13 deletions(-) diff --git a/ftp-server.py b/ftp-server.py index bdb4f38..c3997ba 100644 --- a/ftp-server.py +++ b/ftp-server.py @@ -1,35 +1,256 @@ import socket import os +import shutil +import csv +import re + + +helping = 'help - показывает все возможные команды\npwd - показывает название рабочей директории\nls - показывает содержимое текущей директории\ncd - перемещение по директориям\nmkdir - создать директорию (рекурсивно)\nrmtree - удалить директорию (рекурсивно)\ntouch - создать пустой файл\nremove - удалить файл\ncat - отправляет содержимое файла\nget_file - отправляет файл в текущую директорию у клиента\nsend_file - принимает файл с текущей директории клиента' ''' +help - показывает все возможные команды pwd - показывает название рабочей директории ls - показывает содержимое текущей директории +cd - перемещение по директориям +mkdir - создать директорию (рекурсивно) +rmtree - удалить директорию (рекурсивно) +touch - создать пустой файл +remove - удалить файл cat - отправляет содержимое файла +get_file - отправляет файл в текущую директорию у клиента +send_file - принимает файл с текущей директории клиента ''' -dirname = os.path.join(os.getcwd(), 'docs') +END_FLAG = b"$$STREAM_FILE_END_FLAG$$" +FAIL_FLAG = b'$FAILED$' +PORT = 6161 +global_root = os.path.join(os.getcwd()) +usersfile = os.path.join(global_root, "users.csv") +log_file = os.path.join(global_root, "log.txt") + + +def get_size(start_path): + total_size = 0 + for dirpath, dirnames, filenames in os.walk(start_path): + for f in filenames: + fp = os.path.join(dirpath, f) + # skip if it is symbolic link + if not os.path.islink(fp): + total_size += os.path.getsize(fp) + + return total_size + + +def log_print(*strings): + print(*strings) + with open(log_file, "a") as logfile: + logfile.write(" ".join([str(item) for item in strings]) + "\n") + + +def authorization(message): + global usersfile, global_root + login, message = message.split("=login", 1) + password, message = message.split("=password", 1) + current_directory, message = message.split("=cur_dir", 1) + size, message = message.split("=file_size", 1) + if login == password == "admin": + user_root = global_root + else: + user_root = os.path.join(global_root, login) + with open(usersfile, "a+", newline="") as csvfile: + csvfile.seek(0, 0) + reader = csv.reader(csvfile, delimiter=";") + for line in reader: + if line[0] == login: + if line[1] == password: + break + else: + return None + else: + writer = csv.writer(csvfile, delimiter=";") + writer.writerow([login, password]) + + try: + os.makedirs(user_root) + except FileExistsError: + pass + + return user_root, current_directory, message, size + def process(req): - if req == 'pwd': - return dirname - elif req == 'ls': - return '; '.join(os.listdir(dirname)) - return 'bad request' + req = authorization(req) + if req: + user_root, current_directory, req, size = req + req, *dir_ = req.split() + path = [path_decoder(user_root, current_directory, item) for item in dir_] + if not path: + path = [""] + # print("#####################", req) + if req == 'pwd': + return pwd(current_directory) + elif req == 'ls': + return ls(os.path.join(user_root, current_directory[1:])) + elif req == "cd": + return cd(path[0], current_directory, user_root) + elif req == 'mkdir': + + return mkdir(path[0]) + elif req == 'rmtree': + return rmtree(path[0]) + elif req == 'touch': + return touch(path[0]) + elif req == 'remove': + return remove(path[0]) + elif req == 'cat': + return cat(path[0]) + elif req == 'rename': + return rename(*path[:2]) + elif req == "get_file": + return get_file(path[0]) + elif req == "send_file": + return send_file(path[0], user_root, size) + elif req == "help": + return helping + else: + return 'bad request' + else: + return "Incorrect password" + + +def path_decoder(root, current, dir_): + if current == "\\" and dir_[:2] == "..": + + return root + dir_[2:] + elif dir_[0] in ["\\", "/"]: + dir_ = re.sub(r"^[\\/]+", "", dir_) + log_print(dir_) + return os.path.join(root, dir_) + else: + return os.path.join(root, current[1:], dir_) + + +def try_decorator(path_func): + def wrapper(*path): + try: + returned = path_func(*path) + if returned == None: + return "successfully" + else: + return returned + except FileNotFoundError: + return (f'Invalid path') + except FileExistsError: + return (f'Has already exist') + except PermissionError: + return f"Permission denied" + + return wrapper + + +def pwd(dirname): + return os.path.join(dirname) + +def ls(path): + return '\n\r'.join(os.listdir(path)) + + +def cd(path, current, root): + try: + os.chdir(path) + except: + return current + return os.getcwd().replace(root, "") + "\\" + + +@try_decorator +def mkdir(path): + os.makedirs(path) + + +@try_decorator +def rmtree(path): + shutil.rmtree(path) + + +@try_decorator +def remove(path): + os.remove(path) + + +@try_decorator +def touch(path): + with open(path, 'x'): + pass + + +@try_decorator +def cat(path): + with open(path, "r") as file: + return "\n\r".join(file.readlines()) + + +@try_decorator +def rename(path1, path2): + os.rename(path1, path2) + + +def get_file(path): + global conn, END_FLAG, FAIL_FLAG + try: + with open(path, "rb") as bytefile: + while read_bytes := bytefile.read(1024): + conn.send(read_bytes) + + except FileNotFoundError: + returned = b'Invalid path' + FAIL_FLAG + except PermissionError: + returned = b"Permission denied" + FAIL_FLAG + else: + returned = END_FLAG + log_print("Has been sent") + return returned + + +def send_file(path, root, size): + global conn, END_FLAG, FAIL_FLAG + available = pow(2, 20) * 10 - get_size(root) # 10Mb for each user + print(available, int(size)) + if available < int(size): + return "Not enough disk space!" + else: + conn.send(b"$ENOUGHT$") + flag_finder = conn.recv(1024) + with open(path, "wb") as bytefile: + while True: + if END_FLAG in flag_finder: + bytefile.write(flag_finder.replace(END_FLAG, b"")) + break + else: + bytefile.write(flag_finder) + flag_finder = conn.recv(1024) + log_print("Has been received") + return "uploaded successfully" -PORT = 6666 sock = socket.socket() sock.bind(('', PORT)) sock.listen() -print("Прослушиваем порт", PORT) +log_print("Прослушиваем порт", PORT) while True: conn, addr = sock.accept() - + request = conn.recv(1024).decode() - print(request) - - response = process(request) - conn.send(response.encode()) + log_print("request:", request) + response = process(request) + log_print("response:", response) + if not response: + response = "\00" + try: + conn.send(response.encode()) + except AttributeError: + conn.send(response) + # log_print("responsed") conn.close() From 24a1b4a642acde3fb6857d2f7171a98006362ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=AE=D1=80=D0=B8=D0=B9=20=D0=94=D0=B0=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= <75733634+LxrdTendx@users.noreply.github.com> Date: Sat, 4 Dec 2021 16:44:10 +0300 Subject: [PATCH 2/4] Update ftp-client.py --- ftp-client.py | 88 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 10 deletions(-) diff --git a/ftp-client.py b/ftp-client.py index 3339519..7b19ef6 100644 --- a/ftp-client.py +++ b/ftp-client.py @@ -1,17 +1,85 @@ import socket +import re +import os HOST = 'localhost' -PORT = 6666 +PORT = 6161 +END_FLAG = b"$$STREAM_FILE_END_FLAG$$" +FAIL_FLAG = b'$FAILED$' +login = input("Введите логин: ") +password = input("Введите пароль: ") +# login = "admin" +# password = "admin" +current_directory = "\\" + + +def creator(message, size=0): + global login, password, current_directory + return f"{login}=login{password}=password{current_directory}=cur_dir{size}=file_size{message}".encode() + + +def receiving(request): + global sock, FAIL_FLAG, END_FLAG + + flag_finder = sock.recv(1024) + if FAIL_FLAG in flag_finder: + print((flag_finder.replace(FAIL_FLAG, b"")).decode()) + else: + filename = re.split("[ \\/]+", request)[-1] + with open(filename, "wb") as bytefile: + while True: + if END_FLAG in flag_finder: + flag_finder, end_flag_msg = flag_finder.split(END_FLAG) + bytefile.write(flag_finder.replace(END_FLAG, b"")) + break + else: + bytefile.write(flag_finder) + flag_finder = sock.recv(1024) + + +def sending(request): + global sock, END_FLAG + filename = re.split("[ \\/]+", request)[-1] + if os.path.exists(filename): + size = os.path.getsize(filename) + sock.send(creator(request, size)) + enought_flag = sock.recv(1024).decode() + if enought_flag != '$ENOUGHT$': + print(enought_flag) + return + with open(filename, "rb") as bytefile: + + while read_bytes := bytefile.read(1024): + sock.send(read_bytes) + sock.send(END_FLAG) + else: + print("Нет такого файла") + print(sock.recv(1024).decode()) + while True: - request = input('>') - + request = input(current_directory + '>') + request = request.strip() + if request == "exit": + print("goodbye") + break sock = socket.socket() sock.connect((HOST, PORT)) - - sock.send(request.encode()) - - response = sock.recv(1024).decode() - print(response) - - sock.close() \ No newline at end of file + if request[:9] == "send_file": + if request == "send_file": + print("Нет такого файла") + else: + sending(request) + else: + sock.send(creator(request)) + if request[:9] == "get_file " or request == "get_file": + receiving(request) + else: + response = sock.recv(1024).decode() + # print("recieved:", response) + if request[:3] == "cd " or request == "cd": + current_directory = response + else: + print(response) + + sock.close() From 54e2e9acc4d523f380e75af274df919f24301aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=AE=D1=80=D0=B8=D0=B9=20=D0=94=D0=B0=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= <75733634+LxrdTendx@users.noreply.github.com> Date: Sat, 4 Dec 2021 16:46:47 +0300 Subject: [PATCH 3/4] Update ftp-server.py --- ftp-server.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ftp-server.py b/ftp-server.py index c3997ba..6c4a1b5 100644 --- a/ftp-server.py +++ b/ftp-server.py @@ -5,7 +5,7 @@ import re -helping = 'help - показывает все возможные команды\npwd - показывает название рабочей директории\nls - показывает содержимое текущей директории\ncd - перемещение по директориям\nmkdir - создать директорию (рекурсивно)\nrmtree - удалить директорию (рекурсивно)\ntouch - создать пустой файл\nremove - удалить файл\ncat - отправляет содержимое файла\nget_file - отправляет файл в текущую директорию у клиента\nsend_file - принимает файл с текущей директории клиента' +helping = 'help - показывает все возможные команды\npwd - показывает название рабочей директории\nls - показывает содержимое текущей директории\ncd - перемещение по директориям\nmkdir - создать директорию (рекурсивно)\nrmtree - удалить директорию (рекурсивно)\ntouch - создать пустой файл\nremove - удалить файл\ncat - отправляет содержимое файла\nget_file - отправляет файл в текущую директорию у клиента\nsend_file - принимает файл с текущей директории клиента\nexit - отключение клиента от сервера' ''' help - показывает все возможные команды pwd - показывает название рабочей директории @@ -18,6 +18,7 @@ cat - отправляет содержимое файла get_file - отправляет файл в текущую директорию у клиента send_file - принимает файл с текущей директории клиента +exit - отключение клиента от сервера ''' END_FLAG = b"$$STREAM_FILE_END_FLAG$$" From 2d64918bc040fbd5905a91805249cb051a14f5d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=AE=D1=80=D0=B8=D0=B9=20=D0=94=D0=B0=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2?= <75733634+LxrdTendx@users.noreply.github.com> Date: Sat, 4 Dec 2021 16:47:05 +0300 Subject: [PATCH 4/4] Update ftp-client.py --- ftp-client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ftp-client.py b/ftp-client.py index 7b19ef6..208cf48 100644 --- a/ftp-client.py +++ b/ftp-client.py @@ -61,7 +61,7 @@ def sending(request): request = input(current_directory + '>') request = request.strip() if request == "exit": - print("goodbye") + print("Всего хорошего!") break sock = socket.socket() sock.connect((HOST, PORT))