Commit bebf4725 authored by Pierre Ynard's avatar Pierre Ynard

lua: redirect telnet shortcut to unified rc interface

The telnet interface is removed. In its place, a small wrapper is used
to provide backward compatibility with --lua-config configuration.
parent 02651e28
......@@ -333,7 +333,7 @@ int Open_LuaIntf( vlc_object_t *p_this )
free( psz_telnet_host );
vlc_UrlClean( &url );
asprintf( &psz_telnet_host, "%s:%d", psz_esc_host ? psz_esc_host : "", i_telnet_port );
asprintf( &psz_telnet_host, "telnet://%s:%d", psz_esc_host ? psz_esc_host : "", i_telnet_port );
free( psz_esc_host );
}
......@@ -396,6 +396,23 @@ int Open_LuaIntf( vlc_object_t *p_this )
lua_setglobal( L, "config" );
}
/* Wrapper for legacy telnet config */
if ( !strcmp( psz_name, "telnet" ) )
{
char *wrapped_file = vlclua_find_file( p_this, "intf", "rc" );
if( !wrapped_file )
{
msg_Err( p_intf, "Couldn't find lua interface script \"rc\", "
"needed by telnet wrapper" );
p_intf->psz_header = NULL;
lua_close( p_sys->L );
goto error;
}
lua_pushstring( L, wrapped_file );
lua_setglobal( L, "wrapped_file" );
free( wrapped_file );
}
p_sys->L = L;
p_intf->psz_header = psz_name;
......
--[==========================================================================[
telnet.lua: VLM interface plugin
telnet.lua: wrapper for legacy telnet configuration
--[==========================================================================[
Copyright (C) 2007 the VideoLAN team
Copyright (C) 2011 the VideoLAN team
$Id$
Authors: Antoine Cellerier <dionoea at videolan dot org>
Authors: Pierre Ynard
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -21,211 +21,31 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
--]==========================================================================]
description=
[============================================================================[
VLM Interface plugin
--vlc.msg.warn("The telnet lua interface script was replaced by rc, please update your configuration!")
Copy (features wise) of the original VLC modules/control/telnet.c module.
Differences are:
* it's in Lua
* 'lock' command to lock the telnet prompt
* possibility to listen on different hosts including stdin
for example:
listen on stdin: vlc -I lua --lua-intf telnet --lua-config "telnet={host='*console'}"
listen on stdin + 2 ports on localhost: vlc -I lua --lua-intf telnet --lua-config "telnet={hosts={'localhost:4212','localhost:5678','*console'}}"
Configuration options setable throught the --lua-config option are:
* hosts: A list of hosts to listen on (see examples above).
* host: A host to listen on. (won't be used if `hosts' is set)
* password: The password used for remote clients.
* prompt: The prompt.
]============================================================================]
require "common"
require "host"
--[[ Some telnet command special characters ]]
WILL = "\251" -- Indicates the desire to begin performing, or confirmation that you are now performing, the indicated option.
WONT = "\252" -- Indicates the refusal to perform, or continue performing, the indicated option.
DO = "\253" -- Indicates the request that the other party perform, or confirmation that you are expecting the other party to perform, the indicated option.
DONT = "\254" -- Indicates the demand that the other party stop performing, or confirmation that you are no longer expecting the other party to perform, the indicated option.
IAC = "\255" -- Interpret as command
ECHO = "\001"
--[[ Client status change callbacks ]]
function on_password( client )
if client.type == host.client_type.net then
client:send( "Password: " ..IAC..WILL..ECHO )
else
-- no authentication needed on stdin
client:switch_status( host.status.read )
if config.hosts == nil and config.host == nil then
config.host = "telnet://localhost:4212"
else
if config.hosts == nil then
config.hosts = { config.host }
end
end
function on_read( client )
client:send( config.prompt and tostring(config.prompt) or "> " )
end
function on_write( client )
end
--[[ Misc functions ]]
function telnet_commands( client )
-- remove telnet command replies from the client's data
client.buffer = string.gsub( client.buffer, IAC.."["..DO..DONT..WILL..WONT.."].", "" )
end
function vlm_message_to_string(client,message,prefix)
local prefix = prefix or ""
if message.value then
client:append(prefix .. message.name .. " : " .. message.value)
else
client:append(prefix .. message.name)
end
if message.children then
for i,c in ipairs(message.children) do
vlm_message_to_string(client,c,prefix.." ")
end
end
end
--[[ Configure the host ]]
h = host.host()
h.status_callbacks[host.status.password] = on_password
h.status_callbacks[host.status.read] = on_read
h.status_callbacks[host.status.write] = on_write
h:listen( config.hosts or config.host or "localhost:4212" )
password = config.password or "admin"
--[[ Launch vlm ]]
vlm = vlc.vlm()
--[[ Commands ]]
function shutdown(client)
h:broadcast("Shutting down.\r\n")
vlc.msg.err("shutdown requested")
vlc.misc.quit()
return true
end
function logout(client)
client:del()
return true
end
function quit(client)
if client.type == host.client_type.net then
return logout(client)
else
return shutdown(client)
end
end
function lock(client)
client:switch_status( host.status.password )
client.buffer = ""
return false
end
function print_text(text)
return function(client)
client:append(string.gsub(text,"\r?\n","\r\n"))
return true
end
end
function help(client)
client:append(" Telnet Specific Commands:")
for c,t in pairs(commands) do
client:append(" "..c.." : "..t.help)
end
return true
end
commands = {
["shutdown"] = { func = shutdown, help = "shutdown VLC" },
["quit"] = { func = quit, help = "logout from telnet/shutdown VLC from local shell" },
["logout"] = { func = logout, help = "logout" },
["lock"] = { func = lock, help = "lock the telnet prompt" },
["description"] = { func = print_text(description), help = "describe this module" },
["license"] = { func = print_text(vlc.misc.license()), help = "print VLC's license message" },
["help"] = { func = help, help = "show this help", dovlm = true },
}
function client_command( client )
local cmd = client.buffer
client.buffer = ""
if not commands[cmd] or not commands[cmd].func or commands[cmd].dovlm then
-- if it's not an interface specific command, it has to be a VLM command
local message, vlc_err = vlm:execute_command( cmd )
vlm_message_to_string( client, message )
if not commands[cmd] or not commands[cmd].func and not commands[cmd].dovlm then
if vlc_err ~= 0 then client:append( "Type `help' for help." ) end
return true
end
end
ok, msg = pcall( commands[cmd].func, client )
if not ok then
client:append( "Error in `"..cmd.."' "..msg )
return true
end
return msg
end
--[[ The main loop ]]
while not vlc.misc.should_die() do
local w, r = h:accept_and_select()
-- Handle writes
for _, client in pairs(w) do
local len = client:send()
client.buffer = string.sub(client.buffer,len+1)
if client.buffer == "" then client:switch_status( host.status.read ) end
end
-- Handle reads
for _, client in pairs(r) do
local str = client:recv(1000)
if not str or str == "" -- the telnet client program has left
or (client.type == host.client_type.net and str == "\004") then
-- Caught a ^D
client.cmds = "quit\n"
else
client.cmds = client.cmds .. str
end
client.buffer = ""
-- split the command at the first '\n'
while string.find(client.cmds, "\n") do
-- save the buffer to send to the client
local saved_buffer = client.buffer
-- get the next command
local index = string.find(client.cmds, "\n")
client.buffer = common.strip(string.sub(client.cmds, 0, index - 1))
client.cmds = string.sub(client.cmds, index + 1)
-- Remove telnet commands from the command line
if client.type == host.client_type.net then
telnet_commands( client )
end
-- Run the command
if client.status == host.status.password then
if client.buffer == password then
client:send( IAC..WONT..ECHO.."\r\nWelcome, Master\r\n" )
client.buffer = ""
client:switch_status( host.status.write )
elseif client.buffer == "quit" then
client_command( client )
for i,host in pairs(config.hosts) do
if host ~= "*console" then
local proto = string.match(host, "^%s*(.-)://")
if proto == nil or proto ~= "telnet" then
local newhost
if proto == nil then
newhost = "telnet://"..host
else
client:send( "\r\nWrong password\r\nPassword: " )
client.buffer = ""
newhost = string.gsub(host, "^%s*.-://", "telnet://")
end
elseif client_command( client ) then
client:switch_status( host.status.write )
--vlc.msg.warn("Replacing host `"..host.."' with `"..newhost.."'")
config.hosts[i] = newhost
end
client.buffer = saved_buffer .. client.buffer
end
end
end
--[[ Clean up ]]
vlm = nil
dofile(wrapped_file)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment