Almost ready for distribution...

This commit is contained in:
Diego Nehab 2004-06-17 21:46:22 +00:00
parent eac26d2c8d
commit 597a062b1b
14 changed files with 323 additions and 161 deletions

View file

@ -4,34 +4,42 @@ This directory contains code that is more useful than the examples. This code
lua.lua
These are modules to suport dynamic loading of LuaSocket by the stand alone
Lua Interpreter with the use of the "require" function. For my Mac OS X
system, I place all files in /Users/diego/tec/luasocket
and set the following environment variables:
Lua Interpreter with the use of new "require" and "requirelib" functions.
For my Mac OS X box, for instance, I place all files in
/Users/diego/tec/luasocket and set the following environment variables:
LUA_PATH=/Users/diego/tec/luasocket/?.lua
LUA_INIT=@/Users/diego/tec/luasocket/lua.lua
LUA_FUNCNAME=?
LUA_LIBNAME=/Users/diego/tec/luasocket/?.dylib
LUA_PATH=/Users/diego/tec/luasocket/?.lua;?.lua
LUA_PATHLIB=/Users/diego/tec/luasocket/?.dylib;?.dylib
With that, I can run any luasocket application with the command line:
lua -l socket <script>
lua <script>
as long as the script uses "require" to load the needed namespaces.
Much nicer than having to build a new executable just to initialize
LuaSocket!
tftp.lua -- Trivial FTP client
This module implements file retrieval by the TFTP protocol. Its main use
is to test the UDP code, but someone might find it usefull.
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.
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 -l socket get.lua <remote-file> [<local-file>]
lua get.lua <remote-file> [<local-file>]
to download a remote file (either ftp:// or http://) to the specified
local file. The program also prints the download throughput, elapsed
@ -44,7 +52,7 @@ 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 -l socket check-links.lua {<url>} > output
lua check-links.lua {<url>} > output
and open the result to see a list of broken links.

View file

@ -4,78 +4,144 @@
-- Author: Diego Nehab
-- RCS ID: $Id$
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- Load required modules
-----------------------------------------------------------------------------
local socket = require("socket")
local url = require("url")
local tp = require("tp")
function get_status(sock, valid)
local line, err = sock:receive()
local code, par
if not line then sock:close() return err end
code = socket.skip(2, string.find(line, "^(%d%d%d)"))
code = tonumber(code)
if code ~= valid then return code end
if code == 150 then
par = tonumber(socket.skip(2, string.find(line, "^%d%d%d (%d*)")))
-----------------------------------------------------------------------------
-- 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 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, 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 nil, par
return table.concat(def, "\n")
end
function get_def(sock)
local line, err = sock:receive()
local def = ""
while (not err) and line ~= "." do
def = def .. line .. "\n"
line, err = sock:receive()
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
if err then sock:close() return nil, err
else return def end
self:check(250)
return defs
end
function dict_open()
local sock, err = socket.connect("dict.org", 2628)
if not sock then return nil, err end
sock:settimeout(10)
local code, par = get_status(sock, 220)
if code then return nil, code end
return sock
end
function dict_define(sock, word, dict)
dict = dict or "web1913"
sock:send("DEFINE " .. dict .. " " .. word .. "\r\n")
local code, par = get_status(sock, 150)
if code or not par then return nil, code end
local defs = ""
for i = 1, par do
local def
code, par = get_status(sock, 151)
if code then return nil, code end
def, err = get_def(sock)
if not def then return nil, err end
defs = defs .. def .. "\n"
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
code, par = get_status(sock, 250)
if code then return nil, code end
return string.gsub(defs, "%s%s$", "")
self:check(250)
return mat
end
function dict_close(sock)
sock:send("QUIT\r\n")
local code, par = get_status(sock, 221)
sock:close()
return code
function metat.__index:quit()
self.tp:command("QUIT")
return self:check(221)
end
function dict_get(word, dict)
local sock, err = dict_open()
if not sock then return nil, err end
local defs, err = dict_define(sock, word, dict)
dict_close(sock)
return defs, err
function metat.__index:close()
return self.tp:close()
end
if arg and arg[1] then
defs, err = dict_get(arg[1], arg[2])
print(defs or err)
else
io.write("Usage:\n lua dict.lua <word> [<dictionary>]\n")
-----------------------------------------------------------------------------
-- 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", "<command> should be 'm' or 'd'")
socket.try(arg and arg ~= "", "need at least <word> 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 <word> 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 = 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
--function socket.protect(f) return f end
get = socket.protect(function(gett)
if type(gett) == "string" then return sget(gett)
else return tget(gett) end
end)

View file

@ -1,5 +1,11 @@
require("ltn12")
require("mime")
-----------------------------------------------------------------------------
-- Little program to convert to and from Quoted-Printable
-- LuaSocket sample files
-- Author: Diego Nehab
-- RCS ID: $Id$
-----------------------------------------------------------------------------
local ltn12 = require("ltn12")
local mime = require("mime")
local convert
arg = arg or {}
local mode = arg and arg[1] or "-et"