Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Crafted this code specifically for lyqyd net testing, there may be bugs and
- -- odd architecture in here due to the fact that I ripped all this out of my
- -- framework. :)
- os.loadAPI("connection")
- os.loadAPI("net")
- os.loadAPI("netfile")
- os.loadAPI("netscreen")
- -- Logging
- local fd = nil
- function logToFile(filename)
- if (filename ~= nil) then
- fd = fs.open(filename,"a")
- if (fd == nil) then
- log("Unable to open '%s' for logging", filename)
- return false
- end
- return true
- else
- log("Filename not provided to logToFile")
- return false
- end
- end
- function log(fmt, ... )
- local out = nil
- if (arg == nil or arg[1] == nil) then
- out = fmt
- else
- out = string.format(fmt,unpack(arg))
- end
- print(out)
- if (fd ~= nil) then
- fd.writeLine(out)
- fd.flush()
- end
- end
- -- Peripheral checking
- local sides = { "left", "right", "top", "bottom", "front", "back" }
- local mon = {}
- local monfound = false
- local modemside = nil
- for i,v in ipairs(sides) do
- local ptype = peripheral.getType(v)
- if (ptype ~= nil) then
- log("...Found '%s' on the %s", ptype, v)
- if (peripheral.getType(v) == "monitor") then
- mon[v] = peripheral.wrap(v)
- monfound = true
- end
- if (peripheral.getType(v) == "modem") then
- modemside = v
- end
- end
- end
- function hasModem()
- if (modemside ~= nil) then
- return true
- else
- return false
- end
- end
- function hasMonitor()
- return monfound
- end
- function getMonitors()
- return mon
- end
- -- Table dump with recursion
- local function tval(v,l)
- local tv = type(v)
- if tv == 'string' then
- return v
- elseif tv == 'number' or tv == 'boolean' or tv == 'nil' then
- return tostring(v)
- elseif tv == 'table' then
- return tdump(v,l+1)
- else
- return '(unknown)'
- end
- end
- function tdump(t,l)
- if (type(t) ~= "table") then
- return '(not a table)'
- end
- if (l == nil) then
- l = 0
- end
- local str = "tbl["
- local nulltable = true
- for k,v in pairs(t) do
- nulltable = false
- str = str .. tostring(k)..":"..tval(v,l) .."|"
- end
- if (not nulltable) then
- str = string.sub(str,0,string.len(str)-1)
- end
- str = str .. "]lbt"
- return str
- end
- -- Port (Socket) numbers we use
- S_sock_echo = 7
- --- Hosts file stuff
- csep = 'ZZZ'
- local hosttable = {}
- local typetable = {}
- function readHosts()
- hosttable = {}
- if fs.exists("/etc/hosts") then
- local file = io.open("/etc/hosts", "r" )
- local line = file:read()
- while line do
- local id,type,host = string.match(line,"^(%d+)%:.*%;([CRT]) (%w+)")
- if (host) then
- hosttable[host] = id
- typetable[host] = type
- else
- log("Unparsable hosts line: '%s'",line)
- end
- line = file:read()
- end
- file:close()
- end
- end
- function displayHosts()
- return function()
- readHosts();
- log("##>> Hosts file")
- for host,id in pairs(hosttable) do
- print(string.format("%3d - %s",id,host))
- end
- log("##<< Hosts file")
- end
- end
- function doDisplayHosts()
- f = displayHosts()
- f()
- end
- function getClass(host)
- return string.match(host,"^(%w+)"..csep..".*")
- end
- function getID(host)
- return hosttable[host]
- end
- function getType(host)
- return typetable[host]
- end
- function getInstances(class)
- local insts = {}
- for host,id in pairs(hosttable) do
- if (string.match(host, "^"..class..csep)) then
- table.insert(insts, host)
- end
- end
- return insts
- end
- ------- SERVER CODE
- --- Standard daemon skeleton code, this returns a function with your server handling the
- --- valid message types below, in the foreground (no coroutine.yield).
- --- Note the serverCode is called like so:
- --- serverCode(conn, packet)
- ---
- local validMessages = {
- ["data"]=1,
- ["instruction"]=1,
- ["event"]=1
- }
- function newServer(serverName, serverPort, serverCode)
- log("Creating new daemon '%s' port %d ", serverName, serverPort)
- return function ()
- log("Daemon '%s' starting up",serverName)
- local connections = {}
- while true do
- local p, conn = connection.listen(serverPort)
- local messType = packet.types[p.type]
- local key = conn:name()
- log("Received packet: %s - %s - %s",
- tostring(conn:name()), tostring(messType), tostring(p.payload))
- if connections[key] and connections[key].status == "open" then
- if validMessages[messType] then
- serverCode(conn, p)
- elseif messType == "close" then
- conn:close()
- connections[key].status = "closed"
- end
- elseif messType == "query" then
- log("Query received?")
- if connections[key] then
- log("Interpreting as already open")
- connections[key].status = open
- else
- local connect = {}
- connect.status = "open"
- connect.conn = conn
- connections[key] = connect
- end
- if conn:send("response", "ok") then
- log("Response sent")
- else
- log("Response not sent!")
- end
- end
- end
- end
- end
- ------CLIENT CODE
- local cfac = "client"
- local contbl = {}
- -- Common connection code, returns true or false based on success
- -- if you provide a timeout note that deep in there is os.timer stuff
- function connectTo( name, port, timeout )
- if (not name) then
- log("Must specify a name in connectTo()")
- return false
- end
- if (not port) then
- log("Must specify a port in connectTo()")
- return false
- end
- log("Connecting to %s:%d", name, port)
- if (contbl[name]) then
- return contbl[name]
- else
- local conn = connection.new(name, port)
- if (not conn) then
- log("Failed to get new connection")
- return false
- end
- if (conn:open(timeout)) then
- contbl[conn:name()] = conn
- return conn
- else
- log("Failed to open %s:%d", name, port)
- return false
- end
- end
- end
- -- Echo client
- function echoToRouter( routerName, message )
- conn = connectTo(routerName, S_sock_echo, 10)
- if (not conn) then
- return false
- end
- log("Echo client connected to '%s'", routerName)
- conn:send("data", message)
- log("Data message sent '%s'", message)
- local p = conn:listen(10)
- if (p) then
- log("Message recieved '%s'", p.payload)
- return true
- else
- log("No message recieved '%s'")
- return false
- end
- end
- if (not hasModem()) then
- log("Needs modem")
- os.exit()
- end
- local router = false
- local myname = "pinger"
- local args = { ... }
- if (args[1] ~= nil) then
- router = true
- myname = "router"
- end
- os.setComputerLabel(myname)
- local myid = os.getComputerID()
- log("Pinger started: I am %s (%d)",myname, myid)
- shell.run("lyqydnet")
- log("Lyqyd net done")
- if (router) then
- shell.run("router")
- end
- net.netInit()
- log("netInit done")
- if (router) then
- log("Running router...")
- readHosts()
- local echoServe = newServer("echo", S_sock_echo,
- function(conn, packet)
- if (packet.types[packet.type] == "data") then
- if (conn:send("data", packet.payload)) then
- log("Echoing [%s]",packet.payload)
- else
- log("Could not echo: send failed")
- end
- else
- log("Illegal packet: %s (%s)", packet.types[packet.type], packet.payload);
- end
- end)
- echoServe()
- else
- log("Running pinger...")
- readHosts()
- while true do
- local timerid = os.startTimer(5)
- while true do
- local event = { os.pullEvent() }
- if (event[1] == "timer" and event[2] == timerid) then
- for i,v in ipairs(getInstances("router")) do
- log("%s sending", v)
- if (echoToRouter(v, "ping")) then
- log("%s responded", v)
- end
- end
- break
- else
- log("Discarding event: %s",tdump(event))
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement