Python_FTP/client.py

186 lines
5.5 KiB
Python

import os
from socket import *
import configparser
import ssl
import sys
CLIENT_FILE = "clientfile"
BUFFER_SIZE = 1024
# TODO: Buggy after some time, Not everything is transmitted
def handle_list(conn, args):
# send command over
conn.sendall("LIST\r\n".encode())
num_of_files_received = 0
num_of_files = 0
# Receive response from server
# Decode bytes to string
response = conn.recv(BUFFER_SIZE).decode('utf-8').strip()
try:
num_of_files = int(response)
except ValueError:
print(response)
return
while num_of_files_received < num_of_files:
# Print response
print(conn.recv(BUFFER_SIZE).decode('utf-8').strip())
num_of_files_received += 1
def handle_quit(conn, args):
conn.sendall("QUIT\r\n".encode())
# Receive response from server
# Decode bytes to string
response = conn.recv(BUFFER_SIZE).decode('utf-8').strip()
print(response)
conn.close()
return True
def handle_DWLD(conn, args):
# send command over
filename = args
conn.sendall(f"DWLD {filename}\r".encode())
os.chdir(os.path.abspath(CLIENT_FILE))
filesize = int(conn.recv(BUFFER_SIZE).decode('utf-8'))
bytes_received = 0
with open(filename, "wb") as f:
while bytes_received < filesize:
data = conn.recv(BUFFER_SIZE)
f.write(data)
bytes_received += BUFFER_SIZE
response = conn.recv(BUFFER_SIZE).decode('utf-8')
print(response)
os.chdir("../")
def handle_UPLD(conn, args):
filename = args
os.chdir(os.path.abspath(CLIENT_FILE))
if not os.path.exists(filename):
print("File does not exist")
else:
bytes_sent = 0
file_size = os.path.getsize(filename)
conn.sendall(f"UPLD {filename} {file_size}\r".encode())
# does file exist at the server?
serverExist = conn.recv(BUFFER_SIZE).decode('utf-8')
# if server already has the file
if serverExist == 'T':
# do you want to overwrite?
print(conn.recv(BUFFER_SIZE).decode('utf-8'))
overwrite = input()
conn.sendall(overwrite.encode('utf-8'))
# yes, overwrite
if overwrite.upper() == 'Y':
with open(filename, "rb") as f:
while bytes_sent < file_size:
filedata = f.read(BUFFER_SIZE)
conn.sendall(filedata)
bytes_sent += BUFFER_SIZE
response = conn.recv(BUFFER_SIZE).decode().strip()
print(response)
os.chdir("../")
# no, dont overwrite
elif overwrite.upper() == 'N':
response = conn.recv(BUFFER_SIZE).decode().strip()
print(response)
os.chdir("../")
# server doesnt have the file
elif serverExist == 'F':
print(conn.recv(BUFFER_SIZE).decode('utf-8'))
with open(filename, "rb") as f:
while bytes_sent < file_size:
filedata = f.read(BUFFER_SIZE)
conn.sendall(filedata)
bytes_sent += BUFFER_SIZE
response = conn.recv(BUFFER_SIZE).decode().strip()
print(response)
os.chdir("../")
def handle_HELP(conn, args):
conn.sendall(f"HELP\r".encode())
response = conn.recv(BUFFER_SIZE).decode('utf-8')
print(response)
def user_input():
# Get user input
user_input = input("> ").strip()
# Parse command and arguments
if " " in user_input:
command, args = user_input.split(" ", 1)
else:
command, args = user_input, ""
return command, args
def ftp_client(host, port, cert):
context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.load_verify_locations(cert)
context.check_hostname = False
sock = context.wrap_socket(socket(AF_INET, SOCK_STREAM), server_hostname=host)
sock.connect((host, port))
response = sock.recv(BUFFER_SIZE).decode().strip()
print(response)
while True:
user_input = input("> ").strip()
if " " in user_input:
command, args = user_input.split(" ", 1)
else:
command, args = user_input, ""
if command.upper() == "LIST":
# sock.sendall("LIST\r\n".encode())
handle_list(sock, args)
elif command.upper() == "QUIT":
handle_quit(sock, args)
break
elif command.upper() == "DWLD":
handle_DWLD(sock, args)
elif command.upper() == "UPLD":
handle_UPLD(sock, args)
elif command.upper() == "DELF":
filename = args
sock.sendall(f"DELF {filename}\r".encode())
response = sock.recv(BUFFER_SIZE).decode('utf-8')
print(response)
elif command.upper() == "RNTO":
oldName, newName = args.split(" ", 1)
sock.sendall(f"RNTO {oldName} {newName}\r".encode())
elif command.upper() == "HELP":
handle_HELP(sock, args)
else:
print("Invalid command")
sock.close()
if __name__ == "__main__":
# FTP Client should be able to define IP and port
config = configparser.ConfigParser()
config.read('./config/config.ini')
ip = config['FTPSERVER']['ip']
port = int(config['FTPSERVER']['port'])
cert = config['SSL']['cert']
try:
ftp_client(ip, port, cert)
except KeyboardInterrupt:
print("Client interrupted")
try:
sys.exit(0)
except SystemExit:
os._exit(0)