-
Notifications
You must be signed in to change notification settings - Fork 0
/
client2baks.py
491 lines (388 loc) · 17.7 KB
/
client2baks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
import sys, os, hashlib
import socket, time
import glob
import re
import subprocess #Using Python3.5.2+
import random
from datetime import datetime
import select
import cmd
# python startup file
import readline
import rlcompleter
import atexit
import os
# tab completion
readline.parse_and_bind('tab: complete')
# history file
histfile = os.path.join(os.environ['HOME'], '.pythonhistory')
try:
readline.read_history_file(histfile)
except IOError:
pass
atexit.register(readline.write_history_file, histfile)
del histfile, readline, rlcompleter
HOST = 'localhost' #server name goes in here
PORT = 1443
class client:
def __init__ (self):
self.init_time = datetime.now()
def download(self, input_command, file_str):
if (input_command[1] == "TCP"):
#Create a new client socket for connections with the server.
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Open a new file received_file and receive all the data in that file
with open(file_str, 'wb') as f:
print ('A new creative file opened')
#Convert to string and send to the server
input_temp_command =" ".join(str(x) for x in input_command)
cli_socket.send(input_temp_command.encode('utf-8'))
while True:
data = cli_socket.recv(1024)
if (data.decode() == 'WRONG'):
print ("Wrong file. Enter the correct file")
return
#print("data={}".format(data))
print('receiving data...')
if not data:
break
# write data to a file
f.write(data)
f.close()
#Set file permissions. BONUS!
str_filep = self.get_file_permission(["filepermission", input_command[2]])
print (str_filep)
int_filep = int(str_filep)
print (file_str)
print (int_filep)
try:
os.chmod(file_str,int_filep)
print ("Set file permissions of {} to {}".format(file_str, oct(int_filep)))
except:
print ("You do not have sufficient read permissions to access the last modified file")
print('Successfully got the file')
cli_socket.close()
#Create a new socket function for receiving this data
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Concatening the string
str_data = "downloaddata TCP "
b = input_command[2]
str_data = str_data + b
cli_socket.send(str_data.encode())
#Now printing the received file data
file_data = cli_socket.recv(1024)
#print (file_data)
#Decode!
file_data =file_data.decode()
#Convert the decoded string back to a list for easy access to data
#file_data = file_data.split(" ")
print (file_data)
#f.close()
cli_socket.close()
elif (input_command[1] == "UDP"):
#Create a new client socket(original TCP acting as client) for connections with the server.
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Create a new UDP client socket server for connections with the original server.
cli_udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
UDP_HOST = 'localhost'
UDP_PORT = 1401
cli_udp_socket.bind((UDP_HOST, UDP_PORT))
#Set time-out on the UDP socket.
cli_udp_socket.settimeout(30)
#cli_socket.connect((HOST, PORT))
#Open a new file received_file and receive all the data in that file
with open('udp_received_file', 'wb') as fudp:
print ('file opened')
#Convert to string and send to the server
input_temp_command =" ".join(str(x) for x in input_command)
cli_socket.send(input_temp_command.encode('utf-8'))
while True:
print('receiving data...')
try:
data, addr = cli_udp_socket.recvfrom(32678)
except socket.timeout:
print("Write timeout on socket")
break
#print (data)
print (addr)
fudp.write(data)
if (data == ''):
break
#print("data={}".format(data))
if not data:
break
# write data to a file
#f.close()
print('Successfully got the UDP file....Verifying now..')
cli_socket.close()
#----------------------------------------------------------------------
#Verify the calculated hash with the received file hash
#Create a new socket function for receiving this data
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Concatening the string
str_data = "downloaddata TCP "
b = input_command[2]
str_data = str_data + b
cli_socket.send(str_data.encode())
#Now printing the received file data
file_data = cli_socket.recv(1024)
#print (file_data)
#Decode!
file_data =file_data.decode()
print (file_data)
#Convert the decoded string back to a list for easy access to data
file_data = file_data.split(" ")
#Store the UDP hash somewhere, it is the last member of the file_data list
udp_hash = file_data[-1]
#TIME TO CALCULATE THE HASH OF THIS FILE
#Compute the hash function now
hashfunction = hashlib.md5()
with open("udp_received_file", "rb") as file:
for chunk in iter(lambda: file.read(4096), b""):
hashfunction.update(chunk)
#Append hexdigest to the last modified time of the file
udp_thishash= hashfunction.hexdigest()
print ("This file's hash here is {}".format(udp_thishash))
if(udp_hash == udp_thishash):
print ("YES! LUCKY! SUCCESSFUL UDP TRANSFER")
else:
print("Sadly your UDP was Unethical Destructive Protocol")
#f.close()
cli_socket.close()
def hash(self, input_command):
#Create a new client socket for connections with the server.
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
if (input_command[1] == "verify"):
#Store the filename in a variable, can be used later
filename = input_command[2]
#Convert to string and send to the server
input_command =" ".join(str(x) for x in input_command)
cli_socket.send(input_command.encode('utf-8'))
#Receive the output of the command from the other client i.e. the server in our case
cli_output = cli_socket.recv(1024)
if (cli_output.decode() == 'WRONG'):
print ("Wrong file. Enter the correct file")
return
#Decode!
cli_output = cli_output.decode()
#Convert the decoded string back to a string for easy access to data
cli_output =cli_output.split(" ")
#print (cli_output)
print ("The hash of the file {} is {} , last modified on {} {} {}.".format(filename,cli_output[3] ,cli_output[0], cli_output[1], cli_output[2]))
return cli_output
cli_socket.close()
elif (input_command[1] == "checkall"):
#Convert to string and send to the server
input_command =" ".join(str(x) for x in input_command)
cli_socket.send(input_command.encode('utf-8'))
#Receive the output of the command from the other client i.e. the server in our case
cli_output = cli_socket.recv(1024)
#Decode!
cli_output = cli_output.decode()
#Convert the decoded string back to a string for easy access to data
cli_output =cli_output.split("\n")
print ("Filenames with their last modified times and their hashes: \n")
for i in cli_output:
print (i)
return cli_output
cli_socket.close()
def index(self, input_command):
#Create a new client socket for connections with the server.
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Convert to string and send to the server
input_command =" ".join(str(x) for x in input_command)
cli_socket.send(input_command.encode('utf-8'))
#Receive the command's output when it was run on the server/the other client.
cli_output = ""
cli_output = cli_socket.recv(1024)
cli_output = cli_output.decode()
list_cli_output = cli_output.split(" ")
#for i in cli_output:
#print (len(list_cli_output))
if (len(list_cli_output) == 0):
cli_socket.close()
return
print (cli_output)
#print (cli_output)
cli_socket.close()
return
def getlist(self, input_command):
#Create a new client socket for connections with the server.
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Convert input_command into a string for send, since send does not accept lists.
input_command =" ".join(str(x) for x in input_command)
#Send the string via the socket to the server.
#print (type(input_command))
cli_socket.send((input_command).encode('utf-8'))
#Receive the command's output when it was run on the server/the other client.
cli_output = cli_socket.recv(1024)
print (cli_output.decode())
cli_socket.close()
cli_output = cli_output.decode().split("\n")
#Remove total 140
del cli_output[0]
#Remove last element which is nothing basically
del cli_output[-1]
return cli_output
def get_file_permission(self, input_command):
#Create a new client socket for connections with the server.
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Convert input_command into a string for send, since send does not accept lists.
input_command =" ".join(str(x) for x in input_command)
#Send the string via the socket to the server.
#print (type(input_command))
cli_socket.send((input_command).encode('utf-8'))
#Receive the command's output when it was run on the server/the other client.
cli_output = cli_socket.recv(1024)
print (cli_output.decode())
return (cli_output.decode())
cli_socket.close()
def get_last_modified_time(self, input_command):
#Create a new client socket for connections with the server.
try:
cli_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cli_socket.connect((HOST, PORT))
except socket.error as e:
print ("Connection refused.")
#Convert input_command into a string for send, since send does not accept lists.
input_command =" ".join(str(x) for x in input_command)
#Send the string via the socket to the server.
#print (type(input_command))
cli_socket.send((input_command).encode('utf-8'))
#Receive the command's output when it was run on the server/the other client.
cli_output = cli_socket.recv(1024)
print (cli_output.decode())
return (cli_output.decode())
cli_socket.close()
def sync(self):
#Periodically check if files are present or not first
#print ("HI")
#Check for files in the current directory
local_file_list = os.listdir(".")
print (local_file_list)
#Get files from those directory
get_list = ["lls"]
lls_list = self.getlist(get_list)
temp_list= []
#Store filenames in server_file_list
server_file_list=[]
for element in lls_list:
temp_list = element.split(" ")
server_file_list.append(temp_list[-1])
#Iterate over the elements
for element in server_file_list:
if element is '':
break
if element is None:
break
if element in local_file_list:
continue
self.download(["download", "TCP", element], element)
print ("Successfully download file {}".format(element))
print (server_file_list)
#Get the local file list again for hash verification with the server
local_file_list = os.listdir(".")
for element in server_file_list:
if element is None:
continue
hash_server_list = self.hash(["hash", "verify", element])
hash_server_file = hash_server_list[3]
#Compute the hash function now for local file
hashfunction = hashlib.md5()
with open(element, "rb") as file:
for chunk in iter(lambda: file.read(4096), b""):
hashfunction.update(chunk)
#Append hexdigest to the last modified time of the file
hash_local_file = hashfunction.hexdigest()
server_last_modified = self.get_last_modified_time(["modified", element])
client_last_modified = str(os.path.getmtime(element))
if (client_last_modified > server_last_modified):
continue
else:
if(hash_local_file != hash_server_file):
self.download(["download", "TCP", element], element)
#print ("Holaa")
return
#for f in file_list:
def run(self):
#Main Loop
while True:
#The left-most symbol in the application
print ('Client > ', end = " ", flush= True)
#Time-out for automatic sync
i, o, e = select.select( [sys.stdin], [], [], 100)
if (i):
input_command = sys.stdin.readline().strip()
#Read in the input command, stripped of whitespaces at the back and the end
#input_command = input().strip()
#Transform the string into a list to better capture the
input_command = input_command.split(" ")
#print len(input_command)
if (len(input_command) == 1):
#ls command output handling
if(input_command[0] == "ls"):
file_list = os.listdir(".")
for f in file_list:
print (f)
#lls is the long-list output from the server directory
elif (input_command[0] == "lls" ):
lls_list = self.getlist(input_command)
#print (lls_list)
#RUN THE SYNC COMMAND!
elif (input_command[0] == "sync"):
self.sync()
#index functions
elif (input_command[0] == "index"):
self.index(input_command)
#hash functions
elif (input_command[0] == "hash"):
cli_hash_list = self.hash(input_command)
#print (cli_hash_list)
#print (cli_hash_list)
#download function call
elif (input_command[0] == "download"):
name_of_file = 'received_file_'
random_int = str(random.randrange(1,1000))
name_of_file = name_of_file + random_int
self.download(input_command, name_of_file)
#print (type(input_command))
else:
print ("Please enter a valid command.")
else:
# os.system("clear")
self.sync()
os.system("clear")
Client = client()
Client.run()