Advertisement
Guest User

Untitled

a guest
Oct 10th, 2018
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 13.45 KB | None | 0 0
  1. import sys
  2. import socket
  3. import os
  4. import datetime
  5.  
  6. PORT = 58002
  7. BUFFER_SIZE = 1024
  8.  
  9.  
  10. #backup_list.txt: <user>|<dir>|<bsip>|<bsport>
  11. #BS_registry.txt: <bsip>:<bsport>
  12. #------------------------------------
  13. #|     INIT                         |
  14. #------------------------------------
  15. if len(sys.argv) == 3:
  16.     PORT = int(sys.argv[2])
  17.  
  18. print [l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2]
  19.             if not ip.startswith("127.")][:1], [[(s.connect(('8.8.8.8', 53)),
  20.             s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET,
  21.             socket.SOCK_DGRAM)]][0][1]]) if l][0][0]
  22.  
  23. print socket.gethostname()
  24. f = open("BS_registry.txt","w")
  25. f.close()
  26. f = open("backup_list.txt","w")
  27. f.close()
  28. f = open("user_reg.txt","w")
  29. f.close()
  30. s_tcp = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  31. s_tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  32. s_tcp.bind(("", PORT))
  33. s_tcp.listen(1)
  34.  
  35. s_udp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  36. s_udp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  37. s_udp.bind(("", PORT))
  38.  
  39. class File:
  40.     def __init__(self, name, date, time, size):
  41.         self.name = name
  42.         self.datetime = datetime.datetime(int(date.split(".")[2]),int(date.split(".")[1]),int(date.split(".")[0]),int(time.split(":")[0]),int(time.split(":")[1]),int(time.split(":")[2]))
  43.         self.size=int(size)
  44.  
  45.     def is_more_recent_than(self, file):
  46.         return self.datetime > file.datetime
  47.  
  48.     def is_the_same_file(self, file):
  49.         return self.name == file.name
  50.  
  51.     def __str__(self):
  52.         return "{0:s} {1:02d}.{2:02d}.{3:04d} {4:02d}.{5:02d}.{6:02d} {7:d}".format(self.name, self.datetime.day, self.datetime.month, self.datetime.year, self.datetime.hour, self.datetime.minute, self.datetime.second, self.size)
  53.  
  54.  
  55.  
  56. #------------------------------------
  57. #|     Communication Interface      |
  58. #------------------------------------
  59.  
  60. def receive_tcp(conn, addr):
  61.     print datetime.datetime.now().strftime("[%H:%M:%S.%f")+']TCP: Connection address:', addr
  62.     data = conn.recv(BUFFER_SIZE)
  63.     data.decode()
  64.     print datetime.datetime.now().strftime("[%H:%M:%S.%f")+"]TCP: Received "+ data+" from ",addr
  65.     return data
  66.  
  67. def send_tcp(message, conn, addr):
  68.     print datetime.datetime.now().strftime("[%H:%M:%S.%f")+"]TCP: Sending "+message+" to ",addr
  69.     message.encode()
  70.     conn.send(message)
  71.  
  72. #Implement receive from wrong address gets buffered
  73. #Timed resend
  74. def receive_udp():
  75.     data, addr = s_udp.recvfrom(1024)
  76.     print datetime.datetime.now().strftime("[%H:%M:%S.%f")+"]UDP: Received "+ data+" from ",addr
  77.     data.decode()
  78.     return data, addr
  79.  
  80. """def send_udp(message, addr):
  81.    print datetime.datetime.now().strftime("[%H:%M:%S.%f")+"]UDP: Sending "+message+" to ",addr
  82.    message.encode()
  83.    s_udp.sendto(message, addr)
  84. """
  85. def send_udp(message, ip, port):
  86.     print datetime.datetime.now().strftime("[%H:%M:%S.%f")+"]UDP: Sending "+message+" to "+ip+":",port
  87.     message.encode()
  88.     s_udp.sendto(message, (ip,int(port)))
  89.  
  90. def send_udp_request(message, ip, port):
  91.     print datetime.datetime.now().strftime("[%H:%M:%S.%f")+"]UDP: Sending "+message+" to "+ip+":",port
  92.     message.encode()
  93.     s_udp_requests.sendto(message, (ip,int(port)))
  94.  
  95. def send(message):
  96.     print "sending "+message
  97.  
  98. def receive():
  99.     message = raw_input("receiving... ")
  100.     return message
  101.  
  102.  
  103. #------------------------------------
  104. #|       Auxiliary funciotions       |
  105. #------------------------------------
  106.  
  107. def create_user(user,password):
  108.     f = open("user_reg.txt","a")
  109.     f.write(user+"|"+password+"\n")
  110.     f.close()
  111.  
  112. def check_user(user,password):
  113.     f = open("user_reg.txt","r")
  114.     for line in f:
  115.         if line.split("|")[0] == user:
  116.             f.close()
  117.             if line.split("|")[1] == password:
  118.                 return "OK"
  119.             else:
  120.                 return "NOK"
  121.     f.close()
  122.     create_user(user,password)
  123.     return "NEW"
  124.  
  125. def fetch_user(user):
  126.     f=open("user_reg.txt","r")
  127.     for lin in f:
  128.         if lin.split("|")[0] == user:
  129.             f.close()
  130.             return lin.split("|")[1][:-1]
  131.     f.close()
  132.     return False
  133.  
  134. def del_user(user):
  135.     f = open("user_reg.txt","r")
  136.     lines = f.readlines()
  137.     f.close()
  138.     f = open("user_reg.txt","w")
  139.     for line in lines:
  140.         if line.split("|")[0] != user:
  141.             f.write(line)
  142.     f.close()
  143.  
  144.  
  145. #dir_stored: checks within the internal registry if dir belonging to user exists.
  146. #   returns info on the bs storing it, or False in case file isnt registered
  147. def dir_stored(user, dir):
  148.     f = open("backup_list.txt","r")
  149.     for line in f:
  150.         if line.split("|")[1] == dir and line.split("|")[0] == user:
  151.             f.close()
  152.             return (line.split("|")[2],line.split("|")[3])
  153.     f.close()
  154.     return False
  155.  
  156. #store_dir: stores the dir in the internal registry
  157. def store_dir(user, dir, bsip, bsport):
  158.     f = open("backup_list.txt","a")
  159.     f.write(user+"|"+dir+"|"+bsip+"|"+bsport+"\n")
  160.     f.close()
  161.  
  162. def format_files(n,files):
  163.     Files = []
  164.     if len(files.split(" ")) != n*4:
  165.         return False
  166.     for i in range(n):
  167.         file = File(files.split(" ")[i*4], files.split(" ")[i*4+1], files.split(" ")[i*4+2], files.split(" ")[i*4+3])
  168.         Files.append(file)
  169.     return Files,(UDP_IP,UDP_PORT)
  170.  
  171. def get_new_files(files, stored_files):
  172.     new_files = []
  173.     for file in files:
  174.         is_new=True
  175.         for stored_file in stored_files:
  176.             if file.is_the_same_file(stored_file) and not file.is_more_recent_than(stored_file):
  177.                 is_new=False
  178.                 break
  179.         if is_new:
  180.             new_files.append(file)
  181.     return new_files
  182.  
  183. #------------------------------------
  184. #|         USER interactions        |
  185. #------------------------------------
  186.  
  187. def authenticate(user, password):
  188.      return "AUR "+check_user(user, password)+"\n"
  189.  
  190. def delete_user(user):
  191.     f = open("backup_list.txt","r")
  192.     for line in f:
  193.         if user == line.split("|")[0]:
  194.             f.close()
  195.             return "DLR NOK\n"
  196.     print("deleting user "+user)
  197.     f.close()
  198.     del_user(user)
  199.     return "DLR OK\n"
  200.  
  201. def list_dir(user):
  202.     f = open("backup_list.txt","r")
  203.     n=0
  204.     dirs = ""
  205.     for line in f:
  206.         if line.split("|")[0]==user:
  207.             n+=1
  208.             dirs = dirs + line.split("|")[1] + " "
  209.     f.close()
  210.     return str(n) + " " + dirs[:-1]
  211.  
  212. def bs_available():
  213.     if (os.stat("BS_registry.txt").st_size == 0):
  214.         return False
  215.     else:
  216.         return True
  217.  
  218. def get_bs():
  219.     f = open("BS_registry.txt","r")
  220.     bs = f.readline()
  221.     lines =f.readlines()
  222.     f.close()
  223.     f = open("BS_registry.txt","w")
  224.     for line in lines:
  225.         f.write(line)
  226.     f.write(bs)
  227.     f.close()
  228.     return (bs.split(":")[0],bs.split(":")[1][:-1])
  229.  
  230. def find_bs(user, dir):
  231.     f = open("backup_list.txt","r")
  232.     for line in f:
  233.         if line.split("|")[0] == user and line.split("|")[1] == dir:
  234.             bsip = line.split("|")[2]
  235.             bsport = line.split("|")[3]
  236.             f.close()
  237.             return (bsip,bsport)
  238.     f.close()
  239.     return False
  240.  
  241.  
  242.  
  243. #------------------------------------
  244. #|         BS interactions          |
  245. #------------------------------------
  246.  
  247. def register_bs(ipaddr,port):
  248.     f = open("BS_registry.txt","r")
  249.     bs_ip_port = ipaddr + ":" + port
  250.     if bs_ip_port in f.read():
  251.         f.close()
  252.         return "RGR NOK\n"
  253.     f.close()
  254.     f = open("BS_registry.txt","a")
  255.     f.write(bs_ip_port + "\n")
  256.     f.close()
  257.     return "RGR OK\n"
  258.  
  259. def unregister_bs(ipaddr,port):
  260.     found = False
  261.     f = open("BS_registry.txt","r")
  262.     lines = f.readlines()
  263.     f.close()
  264.     f = open("BS_registry.txt","w")
  265.     for line in lines:
  266.         if line!=ipaddr+":"+port+"\n":
  267.             print line + " != " + ipaddr + ":" + port + "\n"
  268.             f.write(line)
  269.         else:
  270.             print line + " == " + ipaddr + ":" + port + "\n"
  271.             found = True
  272.     f.close()
  273.     if found:
  274.         return "UAR OK\n"
  275.     else:
  276.         return "UAR NOK\n"
  277.  
  278. def list_files(user,dir):
  279.     f = open("backup_list.txt","r")
  280.     for line in f:
  281.         if line.split("|")[0] == user and line.split("|")[1] == dir:
  282.             bsip = line.split("|")[2]
  283.             bsport = line.split("|")[3]
  284.             send_udp("LSF "+user+" "+dir+"\n", bsip, bsport)
  285.             message, addr = receive_udp()
  286.             f.close()
  287.             if addr[0]== bsip and addr[1]==bsport and message.split(" ")[0] == "LFD" and message.split(" ")[1] != "NOK":
  288.                 return "LFD "+bsip+" "+bsport+" "+ message[4:]+"\n"
  289.             else:
  290.                 return "LFD NOK\n"
  291.     f.close()
  292.     return "LFD NOK\n"
  293.  
  294. def check_files(user,dir,n,files):
  295.     stored_files = list_files(user,dir)
  296.     stored_n = int(stored_files.split(" ")[3])
  297.     if stored_files != "LFD NOK":
  298.         bsip = files.split(" ")[1]
  299.         bsport = files.split(" ")[2]
  300.         new_files = get_new_files(format_files(n,files),format_files(stored_n,stored_files[5+len(str(stored_n)):-1]))
  301.         new_files_str = str(len(new_files)) + " "
  302.         for file in new_files:
  303.             new_files_str += str(file) +" "
  304.         return new_files_str[:-1]
  305.     #else:
  306.         #TODO
  307.  
  308. def create_dir(user,dir,bsip,bsport):
  309.     send_udp("LSU "+user+" "+fetch_user(user)+"\n", bsip, bsport)
  310.     print "[DEBUG:LUR]"
  311.     #message, addr = receive_udp()
  312.     print "[DEBUG:LUR]"+message
  313.  
  314.     if message == "LUR OK\n":
  315.         print "[DEBUG]Storing dir"
  316.         store_dir(user,dir,bsip,bsport)
  317.         return True
  318.     return False
  319.  
  320. def del_dir(user, dir):
  321.     f = open("backup_list.txt","r")
  322.     for line in f:
  323.         if line.split("|")[0] == user and line.split("|")[1] == dir:
  324.             bsip = line.split("|")[2]
  325.             bsport = line.split("|")[3]
  326.             f.close()
  327.             send_udp("DLB "+user+" "+dir+"\n", bsip, bsport)
  328.             message, addr = receive_udp()
  329.             if message == "DBR OK\n":
  330.                 f = open("backup_list.txt","r")
  331.                 lines = f.readlines()
  332.                 f.close()
  333.                 f = open("backup_list.txt","w")
  334.                 for line in lines:
  335.                     if line!=user+"|"+dir+"|"+bsip+"|"+bsport+"\n":
  336.                         f.write(line)
  337.                 f.close()
  338.                 return "DDR OK\n"
  339.             else:
  340.                 return "DDR NOK\n"
  341.     f.close()
  342.     return "DDR NOK\n"
  343.  
  344. #------------------------------------
  345. #|        CS UDP operation          |
  346. #------------------------------------
  347.  
  348. def child():
  349.     while True:
  350.         code, addr =receive_udp()
  351.         if code.split(" ")[0] == "REG":
  352.             if len(code.split(" "))!=3:
  353.                 send_udp("RGR ERR\n",addr[0],addr[1])
  354.             else:
  355.                 send_udp(register_bs(code.split(" ")[1],code.split(" ")[2]),addr[0],addr[1])
  356.         elif code.split(" ")[0] == "UNR":
  357.             if len(code.split(" "))!=3:
  358.                 send_udp("UAR ERR\n",addr[0],addr[1])
  359.             else:
  360.                 send_udp(unregister_bs(code.split(" ")[1],code.split(" ")[2]),addr[0],addr[1])
  361. #------------------------------------
  362. #|        CS TCP operation          |
  363. #------------------------------------
  364.  
  365. for i in range(len(sys.argv)):
  366.     if sys.argv[i] == "-p":
  367.         TCP_PORT = sys.argv[i+1]
  368.         print("Port: " + TCP_PORT)
  369.  
  370.  
  371. pid = os.fork()
  372.  
  373. if pid==0:
  374.     child()
  375. else:
  376.     while True:
  377.         print(datetime.datetime.now().strftime("[%H:%M:%S.%f")+"]Awaiting connection...")
  378.         conn, addr = s_tcp.accept()
  379.         code = receive_tcp(conn, addr)
  380.         if code.split(" ")[0] == "AUT":
  381.             aut = authenticate(code.split(" ")[1], code.split(" ")[2])
  382.             if aut == "AUR NEW\n" or aut == "AUR OK\n":
  383.                 user = code.split(" ")[1]
  384.                 send_tcp(aut, conn, addr)
  385.                 code = receive_tcp(conn, addr)
  386.                 if code.split(" ")[0] == "DLU\n":
  387.                     send_tcp(delete_user(user), conn, addr)
  388.                 elif code.split(" ")[0] == "LSD\n":
  389.                     send_tcp("LDR "+list_dir(user) +"\n", conn, addr)
  390.                 elif code.split(" ")[0] == "LSF":
  391.                     send_tcp(list_files(user,code.split(" ")[1]), conn, addr)
  392.                 elif code.split(" ")[0] == "DEL":
  393.                     send_tcp(del_dir(user,code.split(" ")[1]), conn, addr)
  394.                 elif code.split(" ")[0] == "BCK":
  395.                     if len(code.split(" "))<3:
  396.                         send_tcp("BKR ERR", conn, addr)
  397.                     else:
  398.                         dir = code.split(" ")[1]
  399.                         n = code.split(" ")[2]
  400.                         files = code.split(" ")[3:]
  401.                         if not bs_available():
  402.                             send_tcp("BKR EOF", conn, addr)
  403.                         elif dir_stored(user,dir):#TODO if user_stored
  404.                             bsip, bsport = dir_stored(user,dir)
  405.                             send_tcp("BKR " + bsip + " " + bsport + " " + check_files(user,dir,n,files), conn, addr)
  406.                         else:
  407.                             new_bs = get_bs()
  408.                             if create_dir(user,dir,new_bs[0],new_bs[1]):
  409.                                 send("BKR "+new_bs[0]+" "+new_bs[1]+code[3:])
  410.                 elif code.split(" ")[0] == "RST":
  411.                     send_tcp("RSR " + dir_stored(user,code.split(" ")[1])[0] + " " + dir_stored(user,code.split(" ")[1])[1], conn, addr)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement