ref: 3519f1d58ff78407227adb5a3a202d7a4e626a93
dir: /lib/lua/net.lua/
--- -- plan9 network utilities --- --- -- dial(2) --- DialAux = { new = function(self, proto) local o = {} setmetatable(o, self) self.__index = self if proto == nil then o.proto = "tcp" else o.proto = proto end return o end, -- connect (compat method) connect = function(self, host, port) raddr = self.proto.."!"..host.."!"..port end, -- dial (needs more checks) dial = function(self, raddr) local cs_fd, clone_fd, data_fd, ctl_fd, proto local data_fid, conn_param, clone_path, data_path, addr if not(self.clone_path) and not(self.addr) then cs_fd = io.open("/net/cs", "r+") if not(cs_fd) then return false, "unable to open cs file" end cs_fd:write(raddr) cs_fd:seek("set") conn_param = cs_fd:read("a") cs_fd:close() self.clone_path = string.sub(conn_param, 0, string.find(conn_param, " ") - 1) self.addr = string.sub(conn_param, string.find(conn_param, " ") + 1) end clone_path = self.clone_path addr = self.addr clone_fd = io.open(clone_path, "r+") if not(clone_fd) then return false, "unable to open clone file" end data_fid = clone_fd:read() clone_fd:seek("set") local n = clone_fd:write("connect "..addr.."\n") clone_fd:flush() data_path = string.match(clone_path, "([a-zA-Z0-9/.]+)/clone") data_path = data_path.."/"..data_fid.."/data" data_fdin = io.open(data_path, "r+") data_fdout = io.open(data_path, "a+") if not(data_fdin) then return false, "unable to open data" end self.data_fdin = data_fdin self.data_fdout = data_fdout self.clone_fd = clone_fd return true, nil end, -- close connection and file descriptors close = function(self) self.data_fdin:close() self.data_fdout:close() self.clone_fd:write("close\n") self.clone_fd:close() self.data_fdin = nil self.data_fdout = nil self.clone_fd = nil end, -- dummy compat function set_timeout = function(self, t) self.timeout = t end, -- send data send = function(self, d) -- self.data_fdout:seek("set") local fd = self.data_fdout:write(d) self.data_fdout:flush() if fd == nil then return false, "connection dropped" end return true, d end, -- receive data receive_bytes = function(self, sz) if sz == nil then sz = SOCKET_MAXSZ end local data = self.data_fdin:read(sz) if not(data) then return false, "eof" end return true, data end, -- receive all receive_all = function(self) local data = self.data_fdin:read("a") if not(data) then return false, "eof" end return true, data end, } --- -- webfs(4) client --- WebfsRequest = { new = function(self, mtpt) local o = {} setmetatable(o, self) self.__index = self if mtpt == nil then o.mtpt = "/mnt/web" else o.mtpt = mtpt end return o end, open = function(self) local clone_fd local web_fid, clone_path clone_path=self.mtpt.."/clone" clone_fd = io.open(clone_path, "r+") if not(clone_fd) then return false, "unable to clone" end web_fid = clone_fd:read() clone_fd:seek("set") self.clone_fd = clone_fd self.web_fid = web_fid return true, nil end, set_param = function(self, paramname, paramval) -- self.clone_fd:seek("set") self.clone_fd:write(paramname.." "..paramval.."\n") self.clone_fd:flush() end, read_body = function(self) local body_fd, buf body_fd = io.open(self.mtpt.."/"..self.web_fid.."/body", "r") if not(body_fd) then return false, "body cannot be opened" end buf = body_fd:read("a") body_fd:close() if not(buf) then return false, "unable to read body" end return true, buf end, post_body = function(self, body) local body_fd, ofd body_fd = io.open(self.mtpt.."/"..self.web_fid.."/postbody", "w") if not(body_fd) then return false, "body cannot be opened" end ofd = body_fd:write(body) body_fd:close() if not(ofd) then return false, "unable to write to body fd" end return true, nil end, close = function(self) self.clone_fd:close() end, } Webfs = { new = function(self, mtpt) local o = {} setmetatable(o, self) self.__index = self if mtpt == nil then o.mtpt = "/mnt/web" else o.mtpt = mtpt end return o end, get = function(self, url, headers) local request, status, data if not(url) then return false, "no url" end if not(headers) then headers = {} end request = WebfsRequest:new(self.mtpt) status, data = request:open() if not(status) then return status, data end request:set_param("url", url) for hdrname,hdrval in pairs(headers) do request:set_param("headers", string.format("%s: %s", hdrname, hdrval)) end status, data = request:read_body() request:close() return status, data end, post = function(self, url, body, contenttype, headers) local request, status, data if not(url) then return false, "no url" end if not(headers) then headers = {} end request = WebfsRequest:new(self.mtpt) status, data = request:open() if not(status) then return status, data end request:set_param("url", url) request:set_param("request", "POST") for k,header in pairs(headers) do request:set_param("headers", header) end if contenttype then request:set_param("contenttype", contenttype) end status, data = request:post_body(body) if not(status) then request:close() return status, data end status, data = request:read_body() request:close() return status, data end, } local net = { DialAux = DialAux, Socket = DialAux, -- nmap/unix compat (someday) WebfsRequest = WebfsRequest, Webfs = Webfs, } return net