clix/raw.lua

Mon, 16 Jan 2012 21:27:33 +0100

author
Kim Alvefur <zash@zash.se>
date
Mon, 16 Jan 2012 21:27:33 +0100
changeset 68
b7d92ed9c268
parent 46
b5d6e443e571
child 83
040fadcc86f9
permissions
-rw-r--r--

clix.raw: Add a small sandbox with util.stanza functions

short_opts.i = "interactive";
short_opts.e = "echo";

return function (opts, args)
	if opts.short_help then
		print("Send/receive raw XML to/from the server");
		return;
	end
	
	local send_xml;
	if opts.stdin then
		send_xml = io.read("*a");
	end
	
	local function on_connect(conn)
		conn:hook("incoming-raw", function (data) print(data) end);
		if opts.interactive then
			local stdin = {
				getfd = function () return 0; end;
				dirty = function (self) return false; end;
				settimeout = function () end;
				send = function (_, d) return #d, 0; end;
				close = function () end;
				receive = function (_, patt)
					local data = io.stdin:read(patt);
				if data == nil then
					conn:close();
				end
					if opts.echo then
						io.write(data, patt == "*l" and "\n" or "");
					end
					return data;
				end
			};
			local env = setmetatable({}, { __index = {
				s = verse.stanza,
				m = verse.message,
				p = verse.presence,
				iq = verse.iq,
			}});
			local function on_incoming(stdin, data)
				if not data then
					conn:close();
					return
				end
				if data:sub(1,1) ~= "<" then
					local chunk = assert(loadstring("return "..data, "@stdin"));
					data = "";
					setfenv(chunk, env);
					local ok, ret = pcall(chunk);
					if ok then
						data = ret
					end
				end
				if data then
					conn:send(data);
				end
				if not opts.interactive then
					conn:close();
				end
			end
			stdin = require "net.server".wrapclient(stdin, "stdin", 0, {
				onincoming = on_incoming, ondisconnect = function () end
				}, "*l");
		else
			if send_xml then
				conn:send(send_xml);
			else
				conn:send(table.concat(arg, " "));
			end
			conn:close();
		end

	end
	return clix_connect(opts, on_connect);
end

mercurial