Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local comp = require("component")
- local fs = require("filesystem")
- local modem = comp.modem
- local term = require("term")
- local event = require("event")
- local serial = require("serialization")
- local debug = ...
- local dn = "c/" -- Change this if you didn't label your drive c. (Like a real man.)
- local timeout = 150 -- Maximum number of times the server will listen for an incoming file before bailing out.
- function initTables()
- if not fs.isDirectory(dn.."DNS") then fs.makeDirectory(dn.."DNS") end
- if fs.exists(dn.."DNS/DNSList") then
- fileData = io.open(dn.."DNS/DNSList")
- dnsList = serial.unserialize(fileData:read())
- fileData:close()
- dnsCount = #dnsList
- end
- end
- function addMsg(msg)
- if msgTab == nil then
- msgTab = {}
- msgCount = 0
- end
- msgCount = msgCount + 1
- msgTab[msgCount] = msg
- if debug ~= nil then
- drawScreen()
- end
- end
- function saveDNS()
- file = io.open(dn.."DNS/DNSList", "w")
- file:write(serial.serialize(dnsList))
- file:close()
- end
- function addClient(name, add, portId)
- if dnsList == nil then
- dnsList = {}
- dnsCount = 0
- end
- for i = 1, #dnsList do
- if dnsList[i]["label"] == name then
- if dnsList[i]["address"] == add then
- for i = 1, 5 do
- modem.send(add, tonumber(portId), name.." online.")
- end
- addMsg(name.." online.")
- return false
- else
- modem.send(add, tonumber(portId), "ERROR: Hostname exists")
- return false
- end
- end
- end
- dnsCount = dnsCount + 1
- dnsList[dnsCount] = {
- label = name,
- address = add,
- port = portId,
- }
- modem.send(add, tonumber(portId), "DNS registered as "..name)
- addMsg("registry confirmation sent to "..name)
- saveDNS()
- drawScreen()
- return true
- end
- function nameLookup(address)
- for i = 1, #dnsList do
- if dnsList[i]["address"] == address then
- return dnsList[i]["label"]
- end
- end
- end
- function clientLookup(name)
- for i = 1, #dnsList do
- if dnsList[i]["label"] == name then
- return dnsList[i]["address"], dnsList[i]["port"]
- end
- end
- end
- function listen()
- if not modem.isOpen(1) then modem.open(1) end
- ev, la, sa, port, dist, protocol, opt1, opt2, opt3 = event.pull(.4, _, ev, la, sa, port, dist, protocol, opt1, opt2, opt3)
- if ev == "modem_message" then
- addMsg(protocol.." protocol activated.")
- if protocol == "register" then
- if addClient(opt1, sa, tonumber(opt2)) then
- addMsg("Client '"..opt1.."' registered on port "..opt2..".")
- end
- return
- elseif protocol == "send" then
- dest, dPort = clientLookup(opt1)
- addMsg("Sending data to "..dest.." on port "..dPort)
- modem.send(dest, dPort, opt2, opt3)
- return
- elseif protocol == "file_request" then
- addMsg("File transfer requested by "..nameLookup(sa))
- addMsg("Checking for file "..opt2)
- dest, dPort = clientLookup(opt1)
- if fileGet(dest, dPort, opt2) then
- addMsg("File sent.")
- else
- modem.send(dest, dPort, "file not found.")
- addMsg("File not found.")
- end
- return
- elseif protocol == "file_transfer" then
- clName = nameLookup(sa)
- dest, dPort = clientLookup(clName)
- fileReceive(dest, dPort, opt1)
- elseif protocol == "directory_request" then
- dest, dPort = clientLookup(opt1)
- addMsg("Directory request from "..opt1)
- sendList(dest, dPort)
- addMsg("Directory list sent.")
- return
- end
- elseif ev == "key_down" then
- running = false
- end
- end
- function fileGet(reciever, portId, filename)
- addMsg("File requested... "..filename)
- if fs.isDirectory(dn.."REPO/"..filename.."/") then
- addMsg("File found at "..dn.."REPO/"..filename.." checking versions.")
- verCheck = io.open(dn.."REPO/"..filename.."/latest.txt", "r")
- latestVersion = tonumber(verCheck:read("*line"))
- installDir = verCheck:read("*line")
- verCheck:close()
- addMsg("File version: "..latestVersion.." checking filesize.")
- filesize = fs.size(dn.."REPO/"..filename.."/"..latestVersion)
- addMsg(filesize)
- if filesize > 8000 then
- addMsg("File too large, breaking it down.")
- transferTab = {}
- tCount = 0
- data = assert(io.open(dn.."REPO/"..filename.."/"..latestVersion, "r"))
- while filesize > 0 do
- tCount = tCount + 1
- transferTab[tCount] = data:read(8000)
- filesize = filesize - 8000
- end
- data:close()
- addMsg("Data broken into "..tCount.." packets.")
- for i = 1, 5 do
- modem.send(reciever, portId, "init_transfer", installDir, tCount)
- end
- for i = 1, #transferTab do
- addMsg("Sending data packet "..i..".")
- packetId = "packet_transfer_"..i
- for j = 1, 5 do
- modem.send(reciever, portId, packetId, installDir, transferTab[i])
- end
- end
- return true
- else
- addMsg("Sending data.")
- data = assert(io.open(dn.."REPO/"..filename.."/"..latestVersion, "r"))
- filedata = data:read("*all")
- data:close()
- for i = 1, 5 do
- modem.send(reciever, portId, "file_transfer", installDir, filedata)
- end
- addMsg("Data sent.")
- return true
- end
- else
- return false
- end
- end
- function fileReceive(sender, portId, filename)
- addMsg("Checking for directory "..dn.."REPO/"..filename)
- if not fs.isDirectory(dn.."REPO/"..filename) then
- addMsg("Directory not found, creating.")
- fs.makeDirectory(dn.."REPO/"..filename)
- end
- addMsg("Sending file detail request.")
- for i = 1, 5 do
- modem.send(sender, portId, "transfer_details")
- end
- loopCount = 0
- while true do
- ev, la, sa, po, di, msg, version, installDir, packetCount = event.pull(.1, "modem_message", ev, la, sa, po, di, msg, version, installDir, packetCount)
- if msg ~= nil then
- addMsg(msg)
- if string.sub(msg, 1, 5) == "multi" then
- packetCount = string.sub(msg, 7, #msg)
- addMsg("Reviewing file details.")
- addMsg("Install directory: "..installDir)
- addMsg("File version: "..version)
- addMsg("Packets: "..packetCount)
- packetCount = tonumber(packetCount)
- break
- elseif string.sub(msg, 1, 6) == "single" then
- addMsg("Reviewing file details.")
- addMsg("Install directory: "..installDir)
- addMsg("File version: "..version)
- packetCount = 1
- break
- end
- end
- if loopCount == timeout then
- return false
- else
- loopCount = loopCount + 1
- end
- end
- if packetCount > 1 then
- for i = 1, packetCount do
- while true do
- ev, la, sa, po, di, msg, filePacket = event.pull(.1, "modem_message", ev, la, sa, po, di, msg, filePacket)
- if msg == "data_packet_"..i then
- if i == 1 then
- fileData = filePacket
- else
- fileData = fileData..filePacket
- end
- addMsg("Data packet "..i.." received.")
- break
- end
- end
- end
- else
- while true do
- ev, la, sa, po, di, msg, filePacket = event.pull(.1, "modem_message", ev, la, sa, po, di, msg, filePacket)
- if msg == "data_packet" then
- fileData = filePacket
- addMsg("Data packet received.")
- break
- end
- end
- end
- addMsg("Writing files.")
- data = io.open(dn.."REPO/"..filename.."/"..version, "w")
- data:write(fileData)
- data:close()
- data = io.open(dn.."REPO/"..filename.."/latest.txt", "w")
- data:write(version, "\n")
- data:write(installDir)
- data:close()
- addMsg("Files written.")
- end
- function sendList(reciever, portId)
- path = dn.."REPO/"
- filedata = fs.list(path)
- dataTab = {}
- i = 0
- for k in filedata do
- i = i + 1
- dataTab[i] = k
- end
- dataTab = serial.serialize(dataTab)
- modem.send(reciever, portId, "directory_transfer", dataTab)
- end
- function drawScreen(reciever, portId)
- term.clear()
- print("DNS Server running.")
- print("DNS lookup table:-")
- print(" ")
- if dnsList ~= nil then
- for i = 1, #dnsList do
- print(i..". "..dnsList[i]["label"]..", Address: "..dnsList[i]["address"].." Port: "..dnsList[i]["port"]..".")
- end
- end
- print(" ")
- if debug ~= nil then
- if msgTab ~= nil then
- for i = 1, #msgTab do
- print(msgTab[i])
- end
- end
- end
- end
- function listenUp(target)
- local msg = nil
- local opt1 = nil
- local opt2 = nil
- local opt3 = nil
- local loopCount = 0
- if not modem.isOpen(1) then modem.open(1) end
- while true do
- local ev, la, sa, po, di, msg, opt1, opt2, opt3 = event.pull(.3, "modem_message", ev, la, sa, po, di, msg, opt1, opt2, opt3)
- if msg ~= nil then addMsg(msg) end
- if target ~= nil then
- if msg == target then
- if opt3 ~= nil then
- return msg, opt1, opt2, opt3
- elseif opt2 ~= nil then
- return msg, opt1, opt2
- elseif opt1 ~= nil then
- return msg, opt1
- elseif msg ~= nil then
- return msg
- end
- end
- else
- if msg ~= nil then
- if opt3 ~= nil then
- return msg, opt1, opt2, opt3
- elseif opt2 ~= nil then
- return msg, opt1, opt2
- elseif opt1 ~= nil then
- return msg, opt1
- elseif msg ~= nil then
- return msg
- end
- end
- end
- end
- end
- initTables()
- running = true
- drawScreen()
- while running do
- listen()
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement