From 86de838eb5ed49711be8d62e01255cc2ccd3342e Mon Sep 17 00:00:00 2001 From: Thijs Schreijer Date: Wed, 23 Mar 2022 16:05:11 +0100 Subject: cleanup; move ./etc into ./samples and mark 'unsupported' --- etc/README | 89 -------------- etc/b64.lua | 19 --- etc/check-links.lua | 111 ------------------ etc/check-memory.lua | 17 --- etc/cookie.lua | 88 -------------- etc/dict.lua | 151 ------------------------ etc/dispatch.lua | 307 ------------------------------------------------ etc/eol.lua | 13 --- etc/forward.lua | 65 ----------- etc/get.lua | 141 ---------------------- etc/links | 17 --- etc/lp.lua | 323 --------------------------------------------------- etc/qp.lua | 23 ---- etc/tftp.lua | 154 ------------------------ 14 files changed, 1518 deletions(-) delete mode 100644 etc/README delete mode 100644 etc/b64.lua delete mode 100644 etc/check-links.lua delete mode 100644 etc/check-memory.lua delete mode 100644 etc/cookie.lua delete mode 100644 etc/dict.lua delete mode 100644 etc/dispatch.lua delete mode 100644 etc/eol.lua delete mode 100644 etc/forward.lua delete mode 100644 etc/get.lua delete mode 100644 etc/links delete mode 100644 etc/lp.lua delete mode 100644 etc/qp.lua delete mode 100644 etc/tftp.lua (limited to 'etc') diff --git a/etc/README b/etc/README deleted file mode 100644 index cfd3e37..0000000 --- a/etc/README +++ /dev/null @@ -1,89 +0,0 @@ -This directory contains code that is more useful than the -samples. This code *is* supported. - - tftp.lua -- Trivial FTP client - -This module implements file retrieval by the TFTP protocol. -Its main use was to test the UDP code, but since someone -found it usefull, I turned it into a module that is almost -official (no uploads, yet). - - dict.lua -- Dict client - -The dict.lua module started with a cool simple client -for the DICT protocol, written by Luiz Henrique Figueiredo. -This new version has been converted into a library, similar -to the HTTP and FTP libraries, that can be used from within -any luasocket application. Take a look on the source code -and you will be able to figure out how to use it. - - lp.lua -- LPD client library - -The lp.lua module implements the client part of the Line -Printer Daemon protocol, used to print files on Unix -machines. It is courtesy of David Burgess! See the source -code and the lpr.lua in the examples directory. - - b64.lua - qp.lua - eol.lua - -These are tiny programs that perform Base64, -Quoted-Printable and end-of-line marker conversions. - - get.lua -- file retriever - -This little program is a client that uses the FTP and -HTTP code to implement a command line file graber. Just -run - - lua get.lua [] - -to download a remote file (either ftp:// or http://) to -the specified local file. The program also prints the -download throughput, elapsed time, bytes already downloaded -etc during download. - - check-memory.lua -- checks memory consumption - -This is just to see how much memory each module uses. - - dispatch.lua -- coroutine based dispatcher - -This is a first try at a coroutine based non-blocking -dispatcher for LuaSocket. Take a look at 'check-links.lua' -and at 'forward.lua' to see how to use it. - - check-links.lua -- HTML link checker program - -This little program scans a HTML file and checks for broken -links. It is similar to check-links.pl by Jamie Zawinski, -but uses all facilities of the LuaSocket library and the Lua -language. It has not been thoroughly tested, but it should -work. Just run - - lua check-links.lua [-n] {} > output - -and open the result to see a list of broken links. Make sure -you check the '-n' switch. It runs in non-blocking mode, -using coroutines, and is MUCH faster! - - forward.lua -- coroutine based forward server - -This is a forward server that can accept several connections -and transfers simultaneously using non-blocking I/O and the -coroutine-based dispatcher. You can run, for example - - lua forward.lua 8080:proxy.com:3128 - -to redirect all local conections to port 8080 to the host -'proxy.com' at port 3128. - - unix.c and unix.h - -This is an implementation of Unix local domain sockets and -demonstrates how to extend LuaSocket with a new type of -transport. It has been tested on Linux and on Mac OS X. - -Good luck, -Diego. diff --git a/etc/b64.lua b/etc/b64.lua deleted file mode 100644 index 11eeb2d..0000000 --- a/etc/b64.lua +++ /dev/null @@ -1,19 +0,0 @@ ------------------------------------------------------------------------------ --- Little program to convert to and from Base64 --- LuaSocket sample files --- Author: Diego Nehab ------------------------------------------------------------------------------ -local ltn12 = require("ltn12") -local mime = require("mime") -local source = ltn12.source.file(io.stdin) -local sink = ltn12.sink.file(io.stdout) -local convert -if arg and arg[1] == '-d' then - convert = mime.decode("base64") -else - local base64 = mime.encode("base64") - local wrap = mime.wrap() - convert = ltn12.filter.chain(base64, wrap) -end -sink = ltn12.sink.chain(convert, sink) -ltn12.pump.all(source, sink) diff --git a/etc/check-links.lua b/etc/check-links.lua deleted file mode 100644 index 283f3ac..0000000 --- a/etc/check-links.lua +++ /dev/null @@ -1,111 +0,0 @@ ------------------------------------------------------------------------------ --- Little program that checks links in HTML files, using coroutines and --- non-blocking I/O via the dispatcher module. --- LuaSocket sample files --- Author: Diego Nehab ------------------------------------------------------------------------------ -local url = require("socket.url") -local dispatch = require("dispatch") -local http = require("socket.http") -dispatch.TIMEOUT = 10 - --- make sure the user knows how to invoke us -arg = arg or {} -if #arg < 1 then - print("Usage:\n luasocket check-links.lua [-n] {}") - exit() -end - --- '-n' means we are running in non-blocking mode -if arg[1] == "-n" then - -- if non-blocking I/O was requested, use real dispatcher interface - table.remove(arg, 1) - handler = dispatch.newhandler("coroutine") -else - -- if using blocking I/O, use fake dispatcher interface - handler = dispatch.newhandler("sequential") -end - -local nthreads = 0 - --- get the status of a URL using the dispatcher -function getstatus(link) - local parsed = url.parse(link, {scheme = "file"}) - if parsed.scheme == "http" then - nthreads = nthreads + 1 - handler:start(function() - local r, c, h, s = http.request{ - method = "HEAD", - url = link, - create = handler.tcp - } - if r and c == 200 then io.write('\t', link, '\n') - else io.write('\t', link, ': ', tostring(c), '\n') end - nthreads = nthreads - 1 - end) - end -end - -function readfile(path) - path = url.unescape(path) - local file, error = io.open(path, "r") - if file then - local body = file:read("*a") - file:close() - return body - else return nil, error end -end - -function load(u) - local parsed = url.parse(u, { scheme = "file" }) - local body, headers, code, error - local base = u - if parsed.scheme == "http" then - body, code, headers = http.request(u) - if code == 200 then - -- if there was a redirect, update base to reflect it - base = headers.location or base - end - if not body then - error = code - end - elseif parsed.scheme == "file" then - body, error = readfile(parsed.path) - else error = string.format("unhandled scheme '%s'", parsed.scheme) end - return base, body, error -end - -function getlinks(body, base) - -- get rid of comments - body = string.gsub(body, "%<%!%-%-.-%-%-%>", "") - local links = {} - -- extract links - body = string.gsub(body, '[Hh][Rr][Ee][Ff]%s*=%s*"([^"]*)"', function(href) - table.insert(links, url.absolute(base, href)) - end) - body = string.gsub(body, "[Hh][Rr][Ee][Ff]%s*=%s*'([^']*)'", function(href) - table.insert(links, url.absolute(base, href)) - end) - string.gsub(body, "[Hh][Rr][Ee][Ff]%s*=%s*(.-)>", function(href) - table.insert(links, url.absolute(base, href)) - end) - return links -end - -function checklinks(address) - local base, body, error = load(address) - if not body then print(error) return end - print("Checking ", base) - local links = getlinks(body, base) - for _, link in ipairs(links) do - getstatus(link) - end -end - -for _, address in ipairs(arg) do - checklinks(url.absolute("file:", address)) -end - -while nthreads > 0 do - handler:step() -end diff --git a/etc/check-memory.lua b/etc/check-memory.lua deleted file mode 100644 index 7bd984d..0000000 --- a/etc/check-memory.lua +++ /dev/null @@ -1,17 +0,0 @@ -function load(s) - collectgarbage() - local a = gcinfo() - _G[s] = require(s) - collectgarbage() - local b = gcinfo() - print(s .. ":\t " .. (b-a) .. "k") -end - -load("socket.url") -load("ltn12") -load("socket") -load("mime") -load("socket.tp") -load("socket.smtp") -load("socket.http") -load("socket.ftp") diff --git a/etc/cookie.lua b/etc/cookie.lua deleted file mode 100644 index fec10a1..0000000 --- a/etc/cookie.lua +++ /dev/null @@ -1,88 +0,0 @@ -local socket = require"socket" -local http = require"socket.http" -local url = require"socket.url" -local ltn12 = require"ltn12" - -local token_class = '[^%c%s%(%)%<%>%@%,%;%:%\\%"%/%[%]%?%=%{%}]' - -local function unquote(t, quoted) - local n = string.match(t, "%$(%d+)$") - if n then n = tonumber(n) end - if quoted[n] then return quoted[n] - else return t end -end - -local function parse_set_cookie(c, quoted, cookie_table) - c = c .. ";$last=last;" - local _, _, n, v, i = string.find(c, "(" .. token_class .. - "+)%s*=%s*(.-)%s*;%s*()") - local cookie = { - name = n, - value = unquote(v, quoted), - attributes = {} - } - while 1 do - _, _, n, v, i = string.find(c, "(" .. token_class .. - "+)%s*=?%s*(.-)%s*;%s*()", i) - if not n or n == "$last" then break end - cookie.attributes[#cookie.attributes+1] = { - name = n, - value = unquote(v, quoted) - } - end - cookie_table[#cookie_table+1] = cookie -end - -local function split_set_cookie(s, cookie_table) - cookie_table = cookie_table or {} - -- remove quoted strings from cookie list - local quoted = {} - s = string.gsub(s, '"(.-)"', function(q) - quoted[#quoted+1] = q - return "$" .. #quoted - end) - -- add sentinel - s = s .. ",$last=" - -- split into individual cookies - i = 1 - while 1 do - local _, _, cookie, next_token - _, _, cookie, i, next_token = string.find(s, "(.-)%s*%,%s*()(" .. - token_class .. "+)%s*=", i) - if not next_token then break end - parse_set_cookie(cookie, quoted, cookie_table) - if next_token == "$last" then break end - end - return cookie_table -end - -local function quote(s) - if string.find(s, "[ %,%;]") then return '"' .. s .. '"' - else return s end -end - -local _empty = {} -local function build_cookies(cookies) - s = "" - for i,v in ipairs(cookies or _empty) do - if v.name then - s = s .. v.name - if v.value and v.value ~= "" then - s = s .. '=' .. quote(v.value) - end - end - if v.name and #(v.attributes or _empty) > 0 then s = s .. "; " end - for j,u in ipairs(v.attributes or _empty) do - if u.name then - s = s .. u.name - if u.value and u.value ~= "" then - s = s .. '=' .. quote(u.value) - end - end - if j < #v.attributes then s = s .. "; " end - end - if i < #cookies then s = s .. ", " end - end - return s -end - diff --git a/etc/dict.lua b/etc/dict.lua deleted file mode 100644 index 8c5b711..0000000 --- a/etc/dict.lua +++ /dev/null @@ -1,151 +0,0 @@ ------------------------------------------------------------------------------ --- Little program to download DICT word definitions --- LuaSocket sample files --- Author: Diego Nehab ------------------------------------------------------------------------------ - ------------------------------------------------------------------------------ --- Load required modules ------------------------------------------------------------------------------ -local base = _G -local string = require("string") -local table = require("table") -local socket = require("socket") -local url = require("socket.url") -local tp = require("socket.tp") -module("socket.dict") - ------------------------------------------------------------------------------ --- Globals ------------------------------------------------------------------------------ -HOST = "dict.org" -PORT = 2628 -TIMEOUT = 10 - ------------------------------------------------------------------------------ --- Low-level dict API ------------------------------------------------------------------------------ -local metat = { __index = {} } - -function open(host, port) - local tp = socket.try(tp.connect(host or HOST, port or PORT, TIMEOUT)) - return base.setmetatable({tp = tp}, metat) -end - -function metat.__index:greet() - return socket.try(self.tp:check(220)) -end - -function metat.__index:check(ok) - local code, status = socket.try(self.tp:check(ok)) - return code, - base.tonumber(socket.skip(2, string.find(status, "^%d%d%d (%d*)"))) -end - -function metat.__index:getdef() - local line = socket.try(self.tp:receive()) - local def = {} - while line ~= "." do - table.insert(def, line) - line = socket.try(self.tp:receive()) - end - return table.concat(def, "\n") -end - -function metat.__index:define(database, word) - database = database or "!" - socket.try(self.tp:command("DEFINE", database .. " " .. word)) - local code, count = self:check(150) - local defs = {} - for i = 1, count do - self:check(151) - table.insert(defs, self:getdef()) - end - self:check(250) - return defs -end - -function metat.__index:match(database, strat, word) - database = database or "!" - strat = strat or "." - socket.try(self.tp:command("MATCH", database .." ".. strat .." ".. word)) - self:check(152) - local mat = {} - local line = socket.try(self.tp:receive()) - while line ~= '.' do - database, word = socket.skip(2, string.find(line, "(%S+) (.*)")) - if not mat[database] then mat[database] = {} end - table.insert(mat[database], word) - line = socket.try(self.tp:receive()) - end - self:check(250) - return mat -end - -function metat.__index:quit() - self.tp:command("QUIT") - return self:check(221) -end - -function metat.__index:close() - return self.tp:close() -end - ------------------------------------------------------------------------------ --- High-level dict API ------------------------------------------------------------------------------ -local default = { - scheme = "dict", - host = "dict.org" -} - -local function there(f) - if f == "" then return nil - else return f end -end - -local function parse(u) - local t = socket.try(url.parse(u, default)) - socket.try(t.scheme == "dict", "invalid scheme '" .. t.scheme .. "'") - socket.try(t.path, "invalid path in url") - local cmd, arg = socket.skip(2, string.find(t.path, "^/(.)(.*)$")) - socket.try(cmd == "d" or cmd == "m", " should be 'm' or 'd'") - socket.try(arg and arg ~= "", "need at least in URL") - t.command, t.argument = cmd, arg - arg = string.gsub(arg, "^:([^:]+)", function(f) t.word = f end) - socket.try(t.word, "need at least in URL") - arg = string.gsub(arg, "^:([^:]*)", function(f) t.database = there(f) end) - if cmd == "m" then - arg = string.gsub(arg, "^:([^:]*)", function(f) t.strat = there(f) end) - end - string.gsub(arg, ":([^:]*)$", function(f) t.n = base.tonumber(f) end) - return t -end - -local function tget(gett) - local con = open(gett.host, gett.port) - con:greet() - if gett.command == "d" then - local def = con:define(gett.database, gett.word) - con:quit() - con:close() - if gett.n then return def[gett.n] - else return def end - elseif gett.command == "m" then - local mat = con:match(gett.database, gett.strat, gett.word) - con:quit() - con:close() - return mat - else return nil, "invalid command" end -end - -local function sget(u) - local gett = parse(u) - return tget(gett) -end - -get = socket.protect(function(gett) - if base.type(gett) == "string" then return sget(gett) - else return tget(gett) end -end) - diff --git a/etc/dispatch.lua b/etc/dispatch.lua deleted file mode 100644 index 2485415..0000000 --- a/etc/dispatch.lua +++ /dev/null @@ -1,307 +0,0 @@ ------------------------------------------------------------------------------ --- A hacked dispatcher module --- LuaSocket sample files --- Author: Diego Nehab ------------------------------------------------------------------------------ -local base = _G -local table = require("table") -local string = require("string") -local socket = require("socket") -local coroutine = require("coroutine") -module("dispatch") - --- if too much time goes by without any activity in one of our sockets, we --- just kill it -TIMEOUT = 60 - ------------------------------------------------------------------------------ --- We implement 3 types of dispatchers: --- sequential --- coroutine --- threaded --- The user can choose whatever one is needed ------------------------------------------------------------------------------ -local handlert = {} - --- default handler is coroutine -function newhandler(mode) - mode = mode or "coroutine" - return handlert[mode]() -end - -local function seqstart(self, func) - return func() -end - --- sequential handler simply calls the functions and doesn't wrap I/O -function handlert.sequential() - return { - tcp = socket.tcp, - start = seqstart - } -end - ------------------------------------------------------------------------------ --- Mega hack. Don't try to do this at home. ------------------------------------------------------------------------------ --- we can't yield across calls to protect on Lua 5.1, so we rewrite it with --- coroutines --- make sure you don't require any module that uses socket.protect before --- loading our hack -if string.sub(base._VERSION, -3) == "5.1" then - local function _protect(co, status, ...) - if not status then - local msg = ... - if base.type(msg) == 'table' then - return nil, msg[1] - else - base.error(msg, 0) - end - end - if coroutine.status(co) == "suspended" then - return _protect(co, coroutine.resume(co, coroutine.yield(...))) - else - return ... - end - end - - function socket.protect(f) - return function(...) - local co = coroutine.create(f) - return _protect(co, coroutine.resume(co, ...)) - end - end -end - ------------------------------------------------------------------------------ --- Simple set data structure. O(1) everything. ------------------------------------------------------------------------------ -local function newset() - local reverse = {} - local set = {} - return base.setmetatable(set, {__index = { - insert = function(set, value) - if not reverse[value] then - table.insert(set, value) - reverse[value] = #set - end - end, - remove = function(set, value) - local index = reverse[value] - if index then - reverse[value] = nil - local top = table.remove(set) - if top ~= value then - reverse[top] = index - set[index] = top - end - end - end - }}) -end - ------------------------------------------------------------------------------ --- socket.tcp() wrapper for the coroutine dispatcher ------------------------------------------------------------------------------ -local function cowrap(dispatcher, tcp, error) - if not tcp then return nil, error end - -- put it in non-blocking mode right away - tcp:settimeout(0) - -- metatable for wrap produces new methods on demand for those that we - -- don't override explicitly. - local metat = { __index = function(table, key) - table[key] = function(...) - return tcp[key](tcp,select(2,...)) - end - return table[key] - end} - -- does our user want to do his own non-blocking I/O? - local zero = false - -- create a wrap object that will behave just like a real socket object - local wrap = { } - -- we ignore settimeout to preserve our 0 timeout, but record whether - -- the user wants to do his own non-blocking I/O - function wrap:settimeout(value, mode) - if value == 0 then zero = true - else zero = false end - return 1 - end - -- send in non-blocking mode and yield on timeout - function wrap:send(data, first, last) - first = (first or 1) - 1 - local result, error - while true do - -- return control to dispatcher and tell it we want to send - -- if upon return the dispatcher tells us we timed out, - -- return an error to whoever called us - if coroutine.yield(dispatcher.sending, tcp) == "timeout" then - return nil, "timeout" - end - -- try sending - result, error, first = tcp:send(data, first+1, last) - -- if we are done, or there was an unexpected error, - -- break away from loop - if error ~= "timeout" then return result, error, first end - end - end - -- receive in non-blocking mode and yield on timeout - -- or simply return partial read, if user requested timeout = 0 - function wrap:receive(pattern, partial) - local error = "timeout" - local value - while true do - -- return control to dispatcher and tell it we want to receive - -- if upon return the dispatcher tells us we timed out, - -- return an error to whoever called us - if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then - return nil, "timeout" - end - -- try receiving - value, error, partial = tcp:receive(pattern, partial) - -- if we are done, or there was an unexpected error, - -- break away from loop. also, if the user requested - -- zero timeout, return all we got - if (error ~= "timeout") or zero then - return value, error, partial - end - end - end - -- connect in non-blocking mode and yield on timeout - function wrap:connect(host, port) - local result, error = tcp:connect(host, port) - if error == "timeout" then - -- return control to dispatcher. we will be writable when - -- connection succeeds. - -- if upon return the dispatcher tells us we have a - -- timeout, just abort - if coroutine.yield(dispatcher.sending, tcp) == "timeout" then - return nil, "timeout" - end - -- when we come back, check if connection was successful - result, error = tcp:connect(host, port) - if result or error == "already connected" then return 1 - else return nil, "non-blocking connect failed" end - else return result, error end - end - -- accept in non-blocking mode and yield on timeout - function wrap:accept() - while 1 do - -- return control to dispatcher. we will be readable when a - -- connection arrives. - -- if upon return the dispatcher tells us we have a - -- timeout, just abort - if coroutine.yield(dispatcher.receiving, tcp) == "timeout" then - return nil, "timeout" - end - local client, error = tcp:accept() - if error ~= "timeout" then - return cowrap(dispatcher, client, error) - end - end - end - -- remove cortn from context - function wrap:close() - dispatcher.stamp[tcp] = nil - dispatcher.sending.set:remove(tcp) - dispatcher.sending.cortn[tcp] = nil - dispatcher.receiving.set:remove(tcp) - dispatcher.receiving.cortn[tcp] = nil - return tcp:close() - end - return base.setmetatable(wrap, metat) -end - - ------------------------------------------------------------------------------ --- Our coroutine dispatcher ------------------------------------------------------------------------------ -local cometat = { __index = {} } - -function schedule(cortn, status, operation, tcp) - if status then - if cortn and operation then - operation.set:insert(tcp) - operation.cortn[tcp] = cortn - operation.stamp[tcp] = socket.gettime() - end - else base.error(operation) end -end - -function kick(operation, tcp) - operation.cortn[tcp] = nil - operation.set:remove(tcp) -end - -function wakeup(operation, tcp) - local cortn = operation.cortn[tcp] - -- if cortn is still valid, wake it up - if cortn then - kick(operation, tcp) - return cortn, coroutine.resume(cortn) - -- othrewise, just get scheduler not to do anything - else - return nil, true - end -end - -function abort(operation, tcp) - local cortn = operation.cortn[tcp] - if cortn then - kick(operation, tcp) - coroutine.resume(cortn, "timeout") - end -end - --- step through all active cortns -function cometat.__index:step() - -- check which sockets are interesting and act on them - local readable, writable = socket.select(self.receiving.set, - self.sending.set, 1) - -- for all readable connections, resume their cortns and reschedule - -- when they yield back to us - for _, tcp in base.ipairs(readable) do - schedule(wakeup(self.receiving, tcp)) - end - -- for all writable connections, do the same - for _, tcp in base.ipairs(writable) do - schedule(wakeup(self.sending, tcp)) - end - -- politely ask replacement I/O functions in idle cortns to - -- return reporting a timeout - local now = socket.gettime() - for tcp, stamp in base.pairs(self.stamp) do - if tcp.class == "tcp{client}" and now - stamp > TIMEOUT then - abort(self.sending, tcp) - abort(self.receiving, tcp) - end - end -end - -function cometat.__index:start(func) - local cortn = coroutine.create(func) - schedule(cortn, coroutine.resume(cortn)) -end - -function handlert.coroutine() - local stamp = {} - local dispatcher = { - stamp = stamp, - sending = { - name = "sending", - set = newset(), - cortn = {}, - stamp = stamp - }, - receiving = { - name = "receiving", - set = newset(), - cortn = {}, - stamp = stamp - }, - } - function dispatcher.tcp() - return cowrap(dispatcher, socket.tcp()) - end - return base.setmetatable(dispatcher, cometat) -end - diff --git a/etc/eol.lua b/etc/eol.lua deleted file mode 100644 index eeaf0ce..0000000 --- a/etc/eol.lua +++ /dev/null @@ -1,13 +0,0 @@ ------------------------------------------------------------------------------ --- Little program to adjust end of line markers. --- LuaSocket sample files --- Author: Diego Nehab ------------------------------------------------------------------------------ -local mime = require("mime") -local ltn12 = require("ltn12") -local marker = '\n' -if arg and arg[1] == '-d' then marker = '\r\n' end -local filter = mime.normalize(marker) -local source = ltn12.source.chain(ltn12.source.file(io.stdin), filter) -local sink = ltn12.sink.file(io.stdout) -ltn12.pump.all(source, sink) diff --git a/etc/forward.lua b/etc/forward.lua deleted file mode 100644 index 05ced1a..0000000 --- a/etc/forward.lua +++ /dev/null @@ -1,65 +0,0 @@ --- load our favourite library -local dispatch = require("dispatch") -local handler = dispatch.newhandler() - --- make sure the user knows how to invoke us -if #arg < 1 then - print("Usage") - print(" lua forward.lua ...") - os.exit(1) -end - --- function to move data from one socket to the other -local function move(foo, bar) - local live - while 1 do - local data, error, partial = foo:receive(2048) - live = data or error == "timeout" - data = data or partial - local result, error = bar:send(data) - if not live or not result then - foo:close() - bar:close() - break - end - end -end - --- for each tunnel, start a new server -for i, v in ipairs(arg) do - -- capture forwarding parameters - local _, _, iport, ohost, oport = string.find(v, "([^:]+):([^:]+):([^:]+)") - assert(iport, "invalid arguments") - -- create our server socket - local server = assert(handler.tcp()) - assert(server:setoption("reuseaddr", true)) - assert(server:bind("*", iport)) - assert(server:listen(32)) - -- handler for the server object loops accepting new connections - handler:start(function() - while 1 do - local client = assert(server:accept()) - assert(client:settimeout(0)) - -- for each new connection, start a new client handler - handler:start(function() - -- handler tries to connect to peer - local peer = assert(handler.tcp()) - assert(peer:settimeout(0)) - assert(peer:connect(ohost, oport)) - -- if sucessful, starts a new handler to send data from - -- client to peer - handler:start(function() - move(client, peer) - end) - -- afte starting new handler, enter in loop sending data from - -- peer to client - move(peer, client) - end) - end - end) -end - --- simply loop stepping the server -while 1 do - handler:step() -end diff --git a/etc/get.lua b/etc/get.lua deleted file mode 100644 index d53c465..0000000 --- a/etc/get.lua +++ /dev/null @@ -1,141 +0,0 @@ ------------------------------------------------------------------------------ --- Little program to download files from URLs --- LuaSocket sample files --- Author: Diego Nehab ------------------------------------------------------------------------------ -local socket = require("socket") -local http = require("socket.http") -local ftp = require("socket.ftp") -local url = require("socket.url") -local ltn12 = require("ltn12") - --- formats a number of seconds into human readable form -function nicetime(s) - local l = "s" - if s > 60 then - s = s / 60 - l = "m" - if s > 60 then - s = s / 60 - l = "h" - if s > 24 then - s = s / 24 - l = "d" -- hmmm - end - end - end - if l == "s" then return string.format("%5.0f%s", s, l) - else return string.format("%5.2f%s", s, l) end -end - --- formats a number of bytes into human readable form -function nicesize(b) - local l = "B" - if b > 1024 then - b = b / 1024 - l = "KB" - if b > 1024 then - b = b / 1024 - l = "MB" - if b > 1024 then - b = b / 1024 - l = "GB" -- hmmm - end - end - end - return string.format("%7.2f%2s", b, l) -end - --- returns a string with the current state of the download -local remaining_s = "%s received, %s/s throughput, %2.0f%% done, %s remaining" -local elapsed_s = "%s received, %s/s throughput, %s elapsed " -function gauge(got, delta, size) - local rate = got / delta - if size and size >= 1 then - return string.format(remaining_s, nicesize(got), nicesize(rate), - 100*got/size, nicetime((size-got)/rate)) - else - return string.format(elapsed_s, nicesize(got), - nicesize(rate), nicetime(delta)) - end -end - --- creates a new instance of a receive_cb that saves to disk --- kind of copied from luasocket's manual callback examples -function stats(size) - local start = socket.gettime() - local last = start - local got = 0 - return function(chunk) - -- elapsed time since start - local current = socket.gettime() - if chunk then - -- total bytes received - got = got + string.len(chunk) - -- not enough time for estimate - if current - last > 1 then - io.stderr:write("\r", gauge(got, current - start, size)) - io.stderr:flush() - last = current - end - else - -- close up - io.stderr:write("\r", gauge(got, current - start), "\n") - end - return chunk - end -end - --- determines the size of a http file -function gethttpsize(u) - local r, c, h = http.request {method = "HEAD", url = u} - if c == 200 then - return tonumber(h["content-length"]) - end -end - --- downloads a file using the http protocol -function getbyhttp(u, file) - local save = ltn12.sink.file(file or io.stdout) - -- only print feedback if output is not stdout - if file then save = ltn12.sink.chain(stats(gethttpsize(u)), save) end - local r, c, h, s = http.request {url = u, sink = save } - if c ~= 200 then io.stderr:write(s or c, "\n") end -end - --- downloads a file using the ftp protocol -function getbyftp(u, file) - local save = ltn12.sink.file(file or io.stdout) - -- only print feedback if output is not stdout - -- and we don't know how big the file is - if file then save = ltn12.sink.chain(stats(), save) end - local gett = url.parse(u) - gett.sink = save - gett.type = "i" - local ret, err = ftp.get(gett) - if err then print(err) end -end - --- determines the scheme -function getscheme(u) - -- this is an heuristic to solve a common invalid url poblem - if not string.find(u, "//") then u = "//" .. u end - local parsed = url.parse(u, {scheme = "http"}) - return parsed.scheme -end - --- gets a file either by http or ftp, saving as -function get(u, name) - local fout = name and io.open(name, "wb") - local scheme = getscheme(u) - if scheme == "ftp" then getbyftp(u, fout) - elseif scheme == "http" then getbyhttp(u, fout) - else print("unknown scheme" .. scheme) end -end - --- main program -arg = arg or {} -if #arg < 1 then - io.write("Usage:\n lua get.lua []\n") - os.exit(1) -else get(arg[1], arg[2]) end diff --git a/etc/links b/etc/links deleted file mode 100644 index 087f1c0..0000000 --- a/etc/links +++ /dev/null @@ -1,17 +0,0 @@ - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla - bla diff --git a/etc/lp.lua b/etc/lp.lua deleted file mode 100644 index 25f0b95..0000000 --- a/etc/lp.lua +++ /dev/null @@ -1,323 +0,0 @@ ------------------------------------------------------------------------------ --- LPD support for the Lua language --- LuaSocket toolkit. --- Author: David Burgess --- Modified by Diego Nehab, but David is in charge ------------------------------------------------------------------------------ ---[[ - if you have any questions: RFC 1179 -]] --- make sure LuaSocket is loaded -local io = require("io") -local base = _G -local os = require("os") -local math = require("math") -local string = require("string") -local socket = require("socket") -local ltn12 = require("ltn12") -module("socket.lp") - --- default port -PORT = 515 -SERVER = os.getenv("SERVER_NAME") or os.getenv("COMPUTERNAME") or "localhost" -PRINTER = os.getenv("PRINTER") or "printer" - -local function connect(localhost, option) - local host = option.host or SERVER - local port = option.port or PORT - local skt - local try = socket.newtry(function() if skt then skt:close() end end) - if option.localbind then - -- bind to a local port (if we can) - local localport = 721 - local done, err - repeat - skt = socket.try(socket.tcp()) - try(skt:settimeout(30)) - done, err = skt:bind(localhost, localport) - if not done then - localport = localport + 1 - skt:close() - skt = nil - else break end - until localport > 731 - socket.try(skt, err) - else skt = socket.try(socket.tcp()) end - try(skt:connect(host, port)) - return { skt = skt, try = try } -end - ---[[ -RFC 1179 -5.3 03 - Send queue state (short) - - +----+-------+----+------+----+ - | 03 | Queue | SP | List | LF | - +----+-------+----+------+----+ - Command code - 3 - Operand 1 - Printer queue name - Other operands - User names or job numbers - - If the user names or job numbers or both are supplied then only those - jobs for those users or with those numbers will be sent. - - The response is an ASCII stream which describes the printer queue. - The stream continues until the connection closes. Ends of lines are - indicated with ASCII LF control characters. The lines may also - contain ASCII HT control characters. - -5.4 04 - Send queue state (long) - - +----+-------+----+------+----+ - | 04 | Queue | SP | List | LF | - +----+-------+----+------+----+ - Command code - 4 - Operand 1 - Printer queue name - Other operands - User names or job numbers - - If the user names or job numbers or both are supplied then only those - jobs for those users or with those numbers will be sent. - - The response is an ASCII stream which describes the printer queue. - The stream continues until the connection closes. Ends of lines are - indicated with ASCII LF control characters. The lines may also - contain ASCII HT control characters. -]] - --- gets server acknowledement -local function recv_ack(con) - local ack = con.skt:receive(1) - con.try(string.char(0) == ack, "failed to receive server acknowledgement") -end - --- sends client acknowledement -local function send_ack(con) - local sent = con.skt:send(string.char(0)) - con.try(sent == 1, "failed to send acknowledgement") -end - --- sends queue request --- 5.2 02 - Receive a printer job --- --- +----+-------+----+ --- | 02 | Queue | LF | --- +----+-------+----+ --- Command code - 2 --- Operand - Printer queue name --- --- Receiving a job is controlled by a second level of commands. The --- daemon is given commands by sending them over the same connection. --- The commands are described in the next section (6). --- --- After this command is sent, the client must read an acknowledgement --- octet from the daemon. A positive acknowledgement is an octet of --- zero bits. A negative acknowledgement is an octet of any other --- pattern. -local function send_queue(con, queue) - queue = queue or PRINTER - local str = string.format("\2%s\10", queue) - local sent = con.skt:send(str) - con.try(sent == string.len(str), "failed to send print request") - recv_ack(con) -end - --- sends control file --- 6.2 02 - Receive control file --- --- +----+-------+----+------+----+ --- | 02 | Count | SP | Name | LF | --- +----+-------+----+------+----+ --- Command code - 2 --- Operand 1 - Number of bytes in control file --- Operand 2 - Name of control file --- --- The control file must be an ASCII stream with the ends of lines --- indicated by ASCII LF. The total number of bytes in the stream is --- sent as the first operand. The name of the control file is sent as --- the second. It should start with ASCII "cfA", followed by a three --- digit job number, followed by the host name which has constructed the --- control file. Acknowledgement processing must occur as usual after --- the command is sent. --- --- The next "Operand 1" octets over the same TCP connection are the --- intended contents of the control file. Once all of the contents have --- been delivered, an octet of zero bits is sent as an indication that --- the file being sent is complete. A second level of acknowledgement --- processing must occur at this point. - --- sends data file --- 6.3 03 - Receive data file --- --- +----+-------+----+------+----+ --- | 03 | Count | SP | Name | LF | --- +----+-------+----+------+----+ --- Command code - 3 --- Operand 1 - Number of bytes in data file --- Operand 2 - Name of data file --- --- The data file may contain any 8 bit values at all. The total number --- of bytes in the stream may be sent as the first operand, otherwise --- the field should be cleared to 0. The name of the data file should --- start with ASCII "dfA". This should be followed by a three digit job --- number. The job number should be followed by the host name which has --- constructed the data file. Interpretation of the contents of the --- data file is determined by the contents of the corresponding control --- file. If a data file length has been specified, the next "Operand 1" --- octets over the same TCP connection are the intended contents of the --- data file. In this case, once all of the contents have been --- delivered, an octet of zero bits is sent as an indication that the --- file being sent is complete. A second level of acknowledgement --- processing must occur at this point. - - -local function send_hdr(con, control) - local sent = con.skt:send(control) - con.try(sent and sent >= 1 , "failed to send header file") - recv_ack(con) -end - -local function send_control(con, control) - local sent = con.skt:send(control) - con.try(sent and sent >= 1, "failed to send control file") - send_ack(con) -end - -local function send_data(con,fh,size) - local buf - while size > 0 do - buf,message = fh:read(8192) - if buf then - st = con.try(con.skt:send(buf)) - size = size - st - else - con.try(size == 0, "file size mismatch") - end - end - recv_ack(con) -- note the double acknowledgement - send_ack(con) - recv_ack(con) - return size -end - - ---[[ -local control_dflt = { - "H"..string.sub(socket.hostname,1,31).."\10", -- host - "C"..string.sub(socket.hostname,1,31).."\10", -- class - "J"..string.sub(filename,1,99).."\10", -- jobname - "L"..string.sub(user,1,31).."\10", -- print banner page - "I"..tonumber(indent).."\10", -- indent column count ('f' only) - "M"..string.sub(mail,1,128).."\10", -- mail when printed user@host - "N"..string.sub(filename,1,131).."\10", -- name of source file - "P"..string.sub(user,1,31).."\10", -- user name - "T"..string.sub(title,1,79).."\10", -- title for banner ('p' only) - "W"..tonumber(width or 132).."\10", -- width of print f,l,p only - - "f"..file.."\10", -- formatted print (remove control chars) - "l"..file.."\10", -- print - "o"..file.."\10", -- postscript - "p"..file.."\10", -- pr format - requires T, L - "r"..file.."\10", -- fortran format - "U"..file.."\10", -- Unlink (data file only) -} -]] - --- generate a varying job number -local seq = 0 -local function newjob(connection) - seq = seq + 1 - return math.floor(socket.gettime() * 1000 + seq)%1000 -end - - -local format_codes = { - binary = 'l', - text = 'f', - ps = 'o', - pr = 'p', - fortran = 'r', - l = 'l', - r = 'r', - o = 'o', - p = 'p', - f = 'f' -} - --- lp.send{option} --- requires option.file - -send = socket.protect(function(option) - socket.try(option and base.type(option) == "table", "invalid options") - local file = option.file - socket.try(file, "invalid file name") - local fh = socket.try(io.open(file,"rb")) - local datafile_size = fh:seek("end") -- get total size - fh:seek("set") -- go back to start of file - local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME") - or "localhost" - local con = connect(localhost, option) --- format the control file - local jobno = newjob() - local localip = socket.dns.toip(localhost) - localhost = string.sub(localhost,1,31) - local user = string.sub(option.user or os.getenv("LPRUSER") or - os.getenv("USERNAME") or os.getenv("USER") or "anonymous", 1,31) - local lpfile = string.format("dfA%3.3d%-s", jobno, localhost); - local fmt = format_codes[option.format] or 'l' - local class = string.sub(option.class or localip or localhost,1,31) - local _,_,ctlfn = string.find(file,".*[%/%\\](.*)") - ctlfn = string.sub(ctlfn or file,1,131) - local cfile = - string.format("H%-s\nC%-s\nJ%-s\nP%-s\n%.1s%-s\nU%-s\nN%-s\n", - localhost, - class, - option.job or "LuaSocket", - user, - fmt, lpfile, - lpfile, - ctlfn); -- mandatory part of ctl file - if (option.banner) then cfile = cfile .. 'L'..user..'\10' end - if (option.indent) then cfile = cfile .. 'I'..base.tonumber(option.indent)..'\10' end - if (option.mail) then cfile = cfile .. 'M'..string.sub((option.mail),1,128)..'\10' end - if (fmt == 'p' and option.title) then cfile = cfile .. 'T'..string.sub((option.title),1,79)..'\10' end - if ((fmt == 'p' or fmt == 'l' or fmt == 'f') and option.width) then - cfile = cfile .. 'W'..base.tonumber(option,width)..'\10' - end - - con.skt:settimeout(option.timeout or 65) --- send the queue header - send_queue(con, option.queue) --- send the control file header - local cfilecmd = string.format("\2%d cfA%3.3d%-s\n",string.len(cfile), jobno, localhost); - send_hdr(con,cfilecmd) - --- send the control file - send_control(con,cfile) - --- send the data file header - local dfilecmd = string.format("\3%d dfA%3.3d%-s\n",datafile_size, jobno, localhost); - send_hdr(con,dfilecmd) - --- send the data file - send_data(con,fh,datafile_size) - fh:close() - con.skt:close(); - return jobno, datafile_size -end) - --- --- lp.query({host=,queue=printer|'*', format='l'|'s', list=}) --- -query = socket.protect(function(p) - p = p or {} - local localhost = socket.dns.gethostname() or os.getenv("COMPUTERNAME") - or "localhost" - local con = connect(localhost,p) - local fmt - if string.sub(p.format or 's',1,1) == 's' then fmt = 3 else fmt = 4 end - con.try(con.skt:send(string.format("%c%s %s\n", fmt, p.queue or "*", - p.list or ""))) - local data = con.try(con.skt:receive("*a")) - con.skt:close() - return data -end) diff --git a/etc/qp.lua b/etc/qp.lua deleted file mode 100644 index 523238b..0000000 --- a/etc/qp.lua +++ /dev/null @@ -1,23 +0,0 @@ ------------------------------------------------------------------------------ --- Little program to convert to and from Quoted-Printable --- LuaSocket sample files --- Author: Diego Nehab ------------------------------------------------------------------------------ -local ltn12 = require("ltn12") -local mime = require("mime") -local convert -arg = arg or {} -local mode = arg and arg[1] or "-et" -if mode == "-et" then - local normalize = mime.normalize() - local qp = mime.encode("quoted-printable") - local wrap = mime.wrap("quoted-printable") - convert = ltn12.filter.chain(normalize, qp, wrap) -elseif mode == "-eb" then - local qp = mime.encode("quoted-printable", "binary") - local wrap = mime.wrap("quoted-printable") - convert = ltn12.filter.chain(qp, wrap) -else convert = mime.decode("quoted-printable") end -local source = ltn12.source.chain(ltn12.source.file(io.stdin), convert) -local sink = ltn12.sink.file(io.stdout) -ltn12.pump.all(source, sink) diff --git a/etc/tftp.lua b/etc/tftp.lua deleted file mode 100644 index ed99cd1..0000000 --- a/etc/tftp.lua +++ /dev/null @@ -1,154 +0,0 @@ ------------------------------------------------------------------------------ --- TFTP support for the Lua language --- LuaSocket toolkit. --- Author: Diego Nehab ------------------------------------------------------------------------------ - ------------------------------------------------------------------------------ --- Load required files ------------------------------------------------------------------------------ -local base = _G -local table = require("table") -local math = require("math") -local string = require("string") -local socket = require("socket") -local ltn12 = require("ltn12") -local url = require("socket.url") -module("socket.tftp") - ------------------------------------------------------------------------------ --- Program constants ------------------------------------------------------------------------------ -local char = string.char -local byte = string.byte - -PORT = 69 -local OP_RRQ = 1 -local OP_WRQ = 2 -local OP_DATA = 3 -local OP_ACK = 4 -local OP_ERROR = 5 -local OP_INV = {"RRQ", "WRQ", "DATA", "ACK", "ERROR"} - ------------------------------------------------------------------------------ --- Packet creation functions ------------------------------------------------------------------------------ -local function RRQ(source, mode) - return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) -end - -local function WRQ(source, mode) - return char(0, OP_RRQ) .. source .. char(0) .. mode .. char(0) -end - -local function ACK(block) - local low, high - low = math.mod(block, 256) - high = (block - low)/256 - return char(0, OP_ACK, high, low) -end - -local function get_OP(dgram) - local op = byte(dgram, 1)*256 + byte(dgram, 2) - return op -end - ------------------------------------------------------------------------------ --- Packet analysis functions ------------------------------------------------------------------------------ -local function split_DATA(dgram) - local block = byte(dgram, 3)*256 + byte(dgram, 4) - local data = string.sub(dgram, 5) - return block, data -end - -local function get_ERROR(dgram) - local code = byte(dgram, 3)*256 + byte(dgram, 4) - local msg - _,_, msg = string.find(dgram, "(.*)\000", 5) - return string.format("error code %d: %s", code, msg) -end - ------------------------------------------------------------------------------ --- The real work ------------------------------------------------------------------------------ -local function tget(gett) - local retries, dgram, sent, datahost, dataport, code - local last = 0 - socket.try(gett.host, "missing host") - local con = socket.try(socket.udp()) - local try = socket.newtry(function() con:close() end) - -- convert from name to ip if needed - gett.host = try(socket.dns.toip(gett.host)) - con:settimeout(1) - -- first packet gives data host/port to be used for data transfers - local path = string.gsub(gett.path or "", "^/", "") - path = url.unescape(path) - retries = 0 - repeat - sent = try(con:sendto(RRQ(path, "octet"), gett.host, gett.port)) - dgram, datahost, dataport = con:receivefrom() - retries = retries + 1 - until dgram or datahost ~= "timeout" or retries > 5 - try(dgram, datahost) - -- associate socket with data host/port - try(con:setpeername(datahost, dataport)) - -- default sink - local sink = gett.sink or ltn12.sink.null() - -- process all data packets - while 1 do - -- decode packet - code = get_OP(dgram) - try(code ~= OP_ERROR, get_ERROR(dgram)) - try(code == OP_DATA, "unhandled opcode " .. code) - -- get data packet parts - local block, data = split_DATA(dgram) - -- if not repeated, write - if block == last+1 then - try(sink(data)) - last = block - end - -- last packet brings less than 512 bytes of data - if string.len(data) < 512 then - try(con:send(ACK(block))) - try(con:close()) - try(sink(nil)) - return 1 - end - -- get the next packet - retries = 0 - repeat - sent = try(con:send(ACK(last))) - dgram, err = con:receive() - retries = retries + 1 - until dgram or err ~= "timeout" or retries > 5 - try(dgram, err) - end -end - -local default = { - port = PORT, - path ="/", - scheme = "tftp" -} - -local function parse(u) - local t = socket.try(url.parse(u, default)) - socket.try(t.scheme == "tftp", "invalid scheme '" .. t.scheme .. "'") - socket.try(t.host, "invalid host") - return t -end - -local function sget(u) - local gett = parse(u) - local t = {} - gett.sink = ltn12.sink.table(t) - tget(gett) - return table.concat(t) -end - -get = socket.protect(function(gett) - if base.type(gett) == "string" then return sget(gett) - else return tget(gett) end -end) - -- cgit v1.2.3-55-g6feb