Advertisement
pedrosgali

OC DNS/File server

Jun 6th, 2014
647
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.74 KB | None | 0 0
  1. local comp = require("component")
  2. local fs = require("filesystem")
  3. local modem = comp.modem
  4. local term = require("term")
  5. local event = require("event")
  6. local serial = require("serialization")
  7.  
  8. local debug = ...
  9.  
  10. local dn = "c/" -- Change this if you didn't label your drive c. (Like a real man.)
  11. local timeout = 150 -- Maximum number of times the server will listen for an incoming file before bailing out.
  12.  
  13. function initTables()
  14.     if not fs.isDirectory(dn.."DNS") then fs.makeDirectory(dn.."DNS") end
  15.     if fs.exists(dn.."DNS/DNSList") then
  16.         fileData = io.open(dn.."DNS/DNSList")
  17.         dnsList = serial.unserialize(fileData:read())
  18.         fileData:close()
  19.         dnsCount = #dnsList
  20.     end
  21. end
  22.  
  23. function addMsg(msg)
  24.     if msgTab == nil then
  25.         msgTab = {}
  26.         msgCount = 0
  27.     end
  28.     msgCount = msgCount + 1
  29.     msgTab[msgCount] = msg
  30.     if debug ~= nil then
  31.         drawScreen()
  32.     end
  33. end
  34.  
  35. function saveDNS()
  36.     file = io.open(dn.."DNS/DNSList", "w")
  37.     file:write(serial.serialize(dnsList))
  38.     file:close()
  39. end
  40.  
  41. function addClient(name, add, portId)
  42.     if dnsList == nil then
  43.         dnsList = {}
  44.         dnsCount = 0
  45.     end
  46.     for i = 1, #dnsList do
  47.         if dnsList[i]["label"] == name then
  48.             if dnsList[i]["address"] == add then
  49.                 for i = 1, 5 do
  50.                     modem.send(add, tonumber(portId), name.." online.")
  51.                 end
  52.                 addMsg(name.." online.")
  53.                 return false
  54.             else
  55.                 modem.send(add, tonumber(portId), "ERROR: Hostname exists")
  56.                 return false
  57.             end
  58.         end
  59.     end
  60.     dnsCount = dnsCount + 1
  61.     dnsList[dnsCount] = {
  62.         label = name,
  63.         address = add,
  64.         port = portId,
  65.         }
  66.     modem.send(add, tonumber(portId), "DNS registered as "..name)
  67.     addMsg("registry confirmation sent to "..name)
  68.     saveDNS()
  69.     drawScreen()
  70.     return true
  71. end
  72.  
  73. function nameLookup(address)
  74.     for i = 1, #dnsList do
  75.         if dnsList[i]["address"] == address then
  76.             return dnsList[i]["label"]
  77.         end
  78.     end
  79. end
  80.  
  81. function clientLookup(name)
  82.     for i = 1, #dnsList do
  83.         if dnsList[i]["label"] == name then
  84.           return dnsList[i]["address"], dnsList[i]["port"]
  85.          end
  86.     end
  87. end
  88.  
  89. function listen()
  90.     if not modem.isOpen(1) then modem.open(1) end
  91.     ev, la, sa, port, dist, protocol, opt1, opt2, opt3 = event.pull(.4, _, ev, la, sa, port, dist, protocol, opt1, opt2, opt3)
  92.     if ev == "modem_message" then
  93.         addMsg(protocol.." protocol activated.")
  94.         if protocol == "register" then
  95.             if addClient(opt1, sa, tonumber(opt2)) then
  96.                 addMsg("Client '"..opt1.."' registered on port "..opt2..".")
  97.             end
  98.             return
  99.         elseif protocol == "send" then
  100.             dest, dPort = clientLookup(opt1)
  101.             addMsg("Sending data to "..dest.." on port "..dPort)
  102.             modem.send(dest, dPort, opt2, opt3)
  103.             return
  104.         elseif protocol == "file_request" then
  105.             addMsg("File transfer requested by "..nameLookup(sa))
  106.             addMsg("Checking for file "..opt2)
  107.             dest, dPort = clientLookup(opt1)
  108.             if fileGet(dest, dPort, opt2) then
  109.                 addMsg("File sent.")
  110.             else
  111.                 modem.send(dest, dPort, "file not found.")
  112.                 addMsg("File not found.")
  113.             end
  114.             return
  115.         elseif protocol == "file_transfer" then
  116.             clName = nameLookup(sa)
  117.             dest, dPort = clientLookup(clName)
  118.             fileReceive(dest, dPort, opt1)
  119.         elseif protocol == "directory_request" then
  120.             dest, dPort = clientLookup(opt1)
  121.             addMsg("Directory request from "..opt1)
  122.             sendList(dest, dPort)
  123.             addMsg("Directory list sent.")
  124.             return
  125.         end
  126.     elseif ev == "key_down" then
  127.         running = false
  128.     end
  129. end
  130.  
  131. function fileGet(reciever, portId, filename)
  132.     addMsg("File requested... "..filename)
  133.     if fs.isDirectory(dn.."REPO/"..filename.."/") then
  134.         addMsg("File found at "..dn.."REPO/"..filename.." checking versions.")
  135.         verCheck = io.open(dn.."REPO/"..filename.."/latest.txt", "r")
  136.         latestVersion = tonumber(verCheck:read("*line"))
  137.         installDir = verCheck:read("*line")
  138.         verCheck:close()
  139.         addMsg("File version: "..latestVersion.." checking filesize.")
  140.         filesize = fs.size(dn.."REPO/"..filename.."/"..latestVersion)
  141.         addMsg(filesize)
  142.         if filesize > 8000 then
  143.             addMsg("File too large, breaking it down.")
  144.             transferTab = {}
  145.             tCount = 0
  146.             data = assert(io.open(dn.."REPO/"..filename.."/"..latestVersion, "r"))
  147.             while filesize > 0 do
  148.                 tCount = tCount + 1
  149.                 transferTab[tCount] = data:read(8000)
  150.                 filesize = filesize - 8000
  151.             end
  152.             data:close()
  153.             addMsg("Data broken into "..tCount.." packets.")
  154.             for i = 1, 5 do
  155.                 modem.send(reciever, portId, "init_transfer", installDir, tCount)
  156.             end
  157.             for i = 1, #transferTab do
  158.                 addMsg("Sending data packet "..i..".")
  159.                 packetId = "packet_transfer_"..i
  160.                 for j = 1, 5 do
  161.                     modem.send(reciever, portId, packetId, installDir, transferTab[i])
  162.                 end
  163.             end
  164.             return true
  165.         else
  166.             addMsg("Sending data.")
  167.             data = assert(io.open(dn.."REPO/"..filename.."/"..latestVersion, "r"))
  168.             filedata = data:read("*all")
  169.             data:close()
  170.             for i = 1, 5 do
  171.                 modem.send(reciever, portId, "file_transfer", installDir, filedata)
  172.             end
  173.             addMsg("Data sent.")
  174.             return true
  175.         end
  176.     else
  177.         return false
  178.     end
  179. end
  180.  
  181. function fileReceive(sender, portId, filename)
  182.     addMsg("Checking for directory "..dn.."REPO/"..filename)
  183.     if not fs.isDirectory(dn.."REPO/"..filename) then
  184.         addMsg("Directory not found, creating.")
  185.         fs.makeDirectory(dn.."REPO/"..filename)
  186.     end
  187.     addMsg("Sending file detail request.")
  188.     for i = 1, 5 do
  189.         modem.send(sender, portId, "transfer_details")
  190.     end
  191.     loopCount = 0
  192.     while true do
  193.         ev, la, sa, po, di, msg, version, installDir, packetCount = event.pull(.1, "modem_message", ev, la, sa, po, di, msg, version, installDir, packetCount)
  194.         if msg ~= nil then
  195.             addMsg(msg)
  196.             if string.sub(msg, 1, 5) == "multi" then
  197.                 packetCount = string.sub(msg, 7, #msg)
  198.                 addMsg("Reviewing file details.")
  199.                 addMsg("Install directory: "..installDir)
  200.                 addMsg("File version: "..version)
  201.                 addMsg("Packets: "..packetCount)
  202.                 packetCount = tonumber(packetCount)
  203.                 break
  204.             elseif string.sub(msg, 1, 6) == "single" then
  205.                 addMsg("Reviewing file details.")
  206.                 addMsg("Install directory: "..installDir)
  207.                 addMsg("File version: "..version)
  208.                 packetCount = 1
  209.                 break
  210.             end
  211.         end
  212.         if loopCount == timeout then
  213.             return false
  214.         else
  215.             loopCount = loopCount + 1
  216.         end
  217.     end
  218.     if packetCount > 1 then
  219.         for i = 1, packetCount do
  220.             while true do
  221.                 ev, la, sa, po, di, msg, filePacket = event.pull(.1, "modem_message", ev, la, sa, po, di, msg, filePacket)
  222.                 if msg == "data_packet_"..i then
  223.                     if i == 1 then
  224.                         fileData = filePacket
  225.                     else
  226.                         fileData = fileData..filePacket
  227.                     end
  228.                     addMsg("Data packet "..i.." received.")
  229.                     break
  230.                 end
  231.             end
  232.         end
  233.     else
  234.         while true do
  235.             ev, la, sa, po, di, msg, filePacket = event.pull(.1, "modem_message", ev, la, sa, po, di, msg, filePacket)
  236.             if msg == "data_packet" then
  237.                 fileData = filePacket
  238.                 addMsg("Data packet received.")
  239.                 break
  240.             end
  241.         end
  242.     end
  243.     addMsg("Writing files.")
  244.     data = io.open(dn.."REPO/"..filename.."/"..version, "w")
  245.     data:write(fileData)
  246.     data:close()
  247.     data = io.open(dn.."REPO/"..filename.."/latest.txt", "w")
  248.     data:write(version, "\n")
  249.     data:write(installDir)
  250.     data:close()
  251.     addMsg("Files written.")
  252. end
  253.  
  254. function sendList(reciever, portId)
  255.     path = dn.."REPO/"
  256.     filedata = fs.list(path)
  257.     dataTab = {}
  258.     i = 0
  259.     for k in filedata do
  260.         i = i + 1
  261.         dataTab[i] = k
  262.     end
  263.     dataTab = serial.serialize(dataTab)
  264.     modem.send(reciever, portId, "directory_transfer", dataTab)
  265. end
  266.  
  267. function drawScreen(reciever, portId)
  268.     term.clear()
  269.     print("DNS Server running.")
  270.     print("DNS lookup table:-")
  271.     print(" ")
  272.     if dnsList ~= nil then
  273.         for i = 1, #dnsList do
  274.             print(i..". "..dnsList[i]["label"]..", Address: "..dnsList[i]["address"].." Port: "..dnsList[i]["port"]..".")
  275.         end
  276.     end
  277.     print(" ")
  278.     if debug ~= nil then
  279.         if msgTab ~= nil then
  280.             for i = 1, #msgTab do
  281.                 print(msgTab[i])
  282.             end
  283.         end
  284.     end
  285. end
  286.  
  287. function listenUp(target)
  288.     local msg = nil
  289.     local opt1 = nil
  290.     local opt2 = nil
  291.     local opt3 = nil
  292.     local loopCount = 0
  293.     if not modem.isOpen(1) then modem.open(1) end
  294.     while true do
  295.         local ev, la, sa, po, di, msg, opt1, opt2, opt3 = event.pull(.3, "modem_message", ev, la, sa, po, di, msg, opt1, opt2, opt3)
  296.         if msg ~= nil then addMsg(msg) end
  297.         if target ~= nil then
  298.             if msg == target then
  299.                 if opt3 ~= nil then
  300.                     return msg, opt1, opt2, opt3
  301.                 elseif opt2 ~= nil then
  302.                     return msg, opt1, opt2
  303.                 elseif opt1 ~= nil then
  304.                     return msg, opt1
  305.                 elseif msg ~= nil then
  306.                     return msg
  307.                 end
  308.             end
  309.         else
  310.             if msg ~= nil then
  311.                 if opt3 ~= nil then
  312.                     return msg, opt1, opt2, opt3
  313.                 elseif opt2 ~= nil then
  314.                     return msg, opt1, opt2
  315.                 elseif opt1 ~= nil then
  316.                     return msg, opt1
  317.                 elseif msg ~= nil then
  318.                     return msg
  319.                 end
  320.             end
  321.         end
  322.     end
  323. end
  324.  
  325. initTables()
  326. running = true
  327. drawScreen()
  328. while running do
  329.     listen()
  330. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement