-- tinyftp.lua - standalone version -- by Edrx - version: 2006-03-24 -- Usage: -- tinyftp.lua host:path/ lists the dir "path/" in "host" -- tinyftp.lua host:path/fname "cat"s fname -- tinyftp.lua hst1:pth1/fnam1 hst2:pth2/fnam2 copies fnam1 to fnam2 -- The trick: tinyftp's notion of a "filename" is quite flexible. -- "Filenames" starting with "ftp://" are remote files, the other ones -- are not; things like host:foo work because every "filename" is -- expanded by noralize_fname before being used, and normalize_fname -- expands some "host:foo" filenames to -- "ftp://login:passwd@hostlongname/foo". A "~" or a "$VARNAME" at the -- beginning of a "filename" is also expanded, and "-" is treated as -- stdin/stdout. -- I wrote this because tramp wasn't working on the w32 box that I had -- to use at my real-worldish job. For the full story see -- . -- (find-luasocket20file "src/") -- (find-luasocket20file "src/ftp.lua") -- (find-luasocket20file "src/ftp.lua" "function override(t)") -- (find-luasocket20file "src/compat-5.1r4/compat-5.1.lua" "LUA_PATH") -- (find-luasocket20file "src/compat-5.1r4/compat-5.1.lua" "LUA_CPATH") -- (find-es "lua5" "luasocket-on-linux") LUA_PATH = LUA_PATH or os.getenv("LUA_PATH") or os.getenv("HOME") .. "/.lua50/?.lua" LUA_CPATH = LUA_CPATH or os.getenv("LUA_CPATH") or os.getenv("HOME") .. "/.lua50/?.so" load_socket = function () if socket then return end require "compat-5.1" package.cpath = LUA_CPATH -- require "socket" ftp = require("socket.ftp") url = require("socket.url") -- -- binget = socket.protect(binget_) -- binput = socket.protect(binput_) end -- (find-eevfile "eev-dev.el" "defun ee-expand") ee_expand = function (path) path = string.gsub(path, "^~$", "$HOME/", 1) path = string.gsub(path, "^~/", "$HOME/", 1) path = string.gsub(path, "^%$(%w+)", os.getenv, 1) return path end readfile = function (fname) local f = assert(io.open(fname, "rb")) local bigstr = f:read("*a") f:close() return bigstr end writefile = function (fname, bigstr) local f = assert(io.open(fname, "w+b")) f:write(bigstr) f:close() end -- Usage: str = trimlines(tounix(str)) -- The other order may not work. -- tounix = function (str) return (string.gsub(str, "\r", "")) end trimlines = function (str) return string.gsub(str, "[ \t]+\n", "\n") end isdir = function (str) return fname_nondir(str) == "" end isftp = function (str) return (string.find(str, "ftp://")) end fname_nondir = function (str) local _, _, nondir = string.find(str, "([^/]*)$") return nondir end -- You should preload a version with your expansions using LUA_INIT -- normalize_fname = normalize_fname or function (str) str = ee_expand(str) str = gsub(str, "\\", "/") str = gsub(str, "^local:", "ftp://edrx:edrx@127.0.0.1/") str = gsub(str, "^host:", "ftp://login:password@hostname/") return str end -- 2005-12-12 -- tinyftp and his lower buddies -- These functions support three kinds of "filenames": "ftp://...", -- "-" (for stdin/stdout), and "other" (local files). -- All ftp transfers are done in binary mode. -- For simplicity, connections are never reused. tinyftpwrite = function (fname, stuff) fname = normalize_fname(fname) if fname == "-" then io.write(stuff); return "stdout" elseif isftp(fname) then ftp.put(fname..";type=i", stuff); return "ftp" else writefile(fname, stuff) return "file" end end tinyftpread = function (fname) fname = normalize_fname(fname) if fname == "-" then return io.read("*a"), "stdout" elseif isftp(fname) then return assert(ftp.get(fname..";type=i")), "ftp" else return readfile(fname), "file" end end tinyftpls = function (fname) fname = normalize_fname(fname) local t = {} local p = url.parse(fname) p.command = "list" p.sink = ltn12.sink.table(t) local r, e = ftp.get(p) t = tounix(table.concat(t)) t = string.gsub(t, "(\nd[^\n]*)", "%1/") -- add slashes to dirs -- bug: doesn't add a "/" to a dir on the first line return r and t, e end -- (find-alides "edrx/") -- (find-alides "src/sync_FOBA_bcorp/") tinyftpcopy = function (arg1, arg2) arg1 = normalize_fname(arg1) arg2 = normalize_fname(arg2) if isdir(arg2) then args2 = arg2 .. fname_nondir(arg1) end local stuff, inputtype = tinyftpread(arg1) local outputtype = tinyftpwrite(arg2, stuff) return format("%s -> %d bytes -> %s", inputtype, strlen(stuff), outputtype) end tinyftp = function (arg1, arg2) if (arg2 or "") == "" then -- if we only got one argument if isdir(normalize_fname(arg1)) -- if it is an ftp directory then print((tinyftpls(arg1))) -- then list it else io.write(tinyftpread(arg1)) -- otherwise cat it end else -- if we got two arguments if arg2 == "-" -- if the target is stdout then tinyftpcopy(arg1, arg2) -- then just cat the input else print(tinyftpcopy(arg1, arg2)) -- otherwise print "src -> nbytes -> tgt" end end end load_socket() tinyftp(arg[1], arg[2]) -- Missing: support for "file:///" urls