telnet.lua
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:8k
源码类别:

midi

开发平台:

Unix_Linux

  1. --[==========================================================================[
  2.  telnet.lua: VLM interface plugin
  3. --[==========================================================================[
  4.  Copyright (C) 2007 the VideoLAN team
  5.  $Id$
  6.  Authors: Antoine Cellerier <dionoea at videolan dot org>
  7.  This program is free software; you can redistribute it and/or modify
  8.  it under the terms of the GNU General Public License as published by
  9.  the Free Software Foundation; either version 2 of the License, or
  10.  (at your option) any later version.
  11.  This program is distributed in the hope that it will be useful,
  12.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  GNU General Public License for more details.
  15.  You should have received a copy of the GNU General Public License
  16.  along with this program; if not, write to the Free Software
  17.  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  18. --]==========================================================================]
  19. description=
  20. [============================================================================[
  21.  VLM Interface plugin
  22.  Copy (features wise) of the original VLC modules/control/telnet.c module.
  23.  Differences are:
  24.     * it's in Lua
  25.     * 'lock' command to lock the telnet promt
  26.     * possibility to listen on different hosts including stdin
  27.       for example:
  28.         listen on stdin: vlc -I lua --lua-intf telnet --lua-config "telnet={host='*console'}"
  29.         listen on stdin + 2 ports on localhost: vlc -I lua --lua-intf telnet --lua-config "telnet={hosts={'localhost:4212','localhost:5678','*console'}}"
  30.  
  31.  Configuration options setable throught the --lua-config option are:
  32.     * hosts: A list of hosts to listen on (see examples above).
  33.     * host: A host to listen on. (won't be used if `hosts' is set)
  34.     * password: The password used for remote clients.
  35.     * prompt: The prompt.
  36. ]============================================================================]
  37. require "host"
  38. --[[ Some telnet command special characters ]]
  39. WILL = "251" -- Indicates the desire to begin performing, or confirmation that you are now performing, the indicated option.
  40. WONT = "252" -- Indicates the refusal to perform, or continue performing, the indicated option.
  41. DO   = "253" -- Indicates the request that the other party perform, or confirmation that you are expecting the other party to perform, the indicated option.
  42. 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.
  43. IAC  = "255" -- Interpret as command
  44. ECHO = "01"
  45. --[[ Client status change callbacks ]]
  46. function on_password( client )
  47.     if client.type == host.client_type.net then
  48.         client:send( "Password: " ..IAC..WILL..ECHO )
  49.     else
  50.         -- no authentification needed on stdin
  51.         client:switch_status( host.status.read )
  52.     end
  53. end
  54. function on_read( client )
  55.     client:send( config.prompt and tostring(config.prompt) or "> " )
  56. end
  57. function on_write( client )
  58. end
  59. --[[ Misc functions ]]
  60. function telnet_commands( client )
  61.     -- remove telnet command replies from the client's data
  62.     client.buffer = string.gsub( client.buffer, IAC.."["..DO..DONT..WILL..WONT.."].", "" )
  63. end
  64. function vlm_message_to_string(client,message,prefix)
  65.     local prefix = prefix or ""
  66.     if message.value then
  67.         client:append(prefix .. message.name .. " : " .. message.value)
  68.         return
  69.     else
  70.         client:append(prefix .. message.name)
  71.         if message.children then
  72.             for i,c in ipairs(message.children) do
  73.                 vlm_message_to_string(client,c,prefix.."    ")
  74.             end
  75.         end
  76.         return
  77.     end
  78. end
  79. --[[ Configure the host ]]
  80. h = host.host()
  81. h.status_callbacks[host.status.password] = on_password
  82. h.status_callbacks[host.status.read] = on_read
  83. h.status_callbacks[host.status.write] = on_write
  84. h:listen( config.hosts or config.host or "localhost:4212" )
  85. password = config.password or "admin"
  86. --[[ Launch vlm ]]
  87. vlm = vlc.vlm()
  88. --[[ Commands ]]
  89. function shutdown(client)
  90.     h:broadcast("Shutting down.rn")
  91.     vlc.msg.err("shutdown requested")
  92.     vlc.misc.quit()
  93.     return true
  94. end
  95. function logout(client)
  96.     client:del()
  97.     return true
  98. end
  99. function quit(client)
  100.     if client.type == host.client_type.net then
  101.         return logout(client)
  102.     else
  103.         return shutdown(client)
  104.     end
  105. end
  106. function lock(client)
  107.     client:send("rn")
  108.     client:switch_status( host.status.password )
  109.     client.buffer = ""
  110.     return false
  111. end
  112. function print_text(text)
  113.     return function(client)
  114.         client:append(string.gsub(text,"r?n","rn"))
  115.         return true
  116.     end
  117. end
  118. function help(client)
  119.     client:append("    Telnet Specific Commands:")
  120.     for c,t in pairs(commands) do
  121.         client:append("        "..c.." : "..t.help)
  122.     end
  123.     return true
  124. end
  125. commands = {
  126.     ["shutdown"]    = { func = shutdown, help = "shutdown VLC" },
  127.     ["quit"]        = { func = quit, help = "logout from telnet/shutdown VLC from local shell" },
  128.     ["logout"]      = { func = logout, help = "logout" },
  129.     ["lock"]        = { func = lock, help = "lock the telnet prompt" },
  130.     ["description"] = { func = print_text(description), help = "describe this module" },
  131.     ["license"]     = { func = print_text(vlc.misc.license()), help = "print VLC's license message" },
  132.     ["help"]        = { func = help, help = "show this help", dovlm = true },
  133.     }
  134. function client_command( client )
  135.     local cmd = client.buffer
  136.     client.buffer = ""
  137.     if not commands[cmd] or not commands[cmd].func or commands[cmd].dovlm then
  138.         -- if it's not an interface specific command, it has to be a VLM command
  139.         local message, vlc_err = vlm:execute_command( cmd )
  140.         vlm_message_to_string( client, message )
  141.         if not commands[cmd] or not commands[cmd].func and not commands[cmd].dovlm then
  142.             if vlc_err ~= 0 then client:append( "Type `help' for help." ) end
  143.             return true
  144.         end
  145.     end
  146.     ok, msg = pcall( commands[cmd].func, client )
  147.     if not ok then
  148.         client:append( "Error in `"..cmd.."' "..msg )
  149.         return true
  150.     end
  151.     return msg
  152. end
  153. --[[ The main loop ]]
  154. while not vlc.misc.should_die() do
  155.     h:accept()
  156.     local w, r = h:select( 0.1 )
  157.     -- Handle writes
  158.     for _, client in pairs(w) do
  159.         local len = client:send()
  160.         client.buffer = string.sub(client.buffer,len+1)
  161.         if client.buffer == "" then client:switch_status( host.status.read ) end
  162.     end
  163.     -- Handle reads
  164.     for _, client in pairs(r) do
  165.         local str = client:recv(1000)
  166.         local done = false
  167.         if string.match(str,"n$") then
  168.             client.buffer = string.gsub(client.buffer..str,"r?n$","")
  169.             done = true
  170.         elseif client.buffer == ""
  171.            and ((client.type == host.client_type.stdio and str == "")
  172.            or  (client.type == host.client_type.net and str == "04")) then
  173.             -- Caught a ^D
  174.             client.buffer = "quit"
  175.             done = true
  176.         else
  177.             client.buffer = client.buffer .. str
  178.         end
  179.         if client.type == host.client_type.net then
  180.             telnet_commands( client )
  181.         end
  182.         if done then
  183.             if client.status == host.status.password then
  184.                 if client.buffer == password then
  185.                     client:send( IAC..WONT..ECHO.."rnWelcome, Masterrn" )
  186.                     client.buffer = ""
  187.                     client:switch_status( host.status.write )
  188.                 else
  189.                     client:send( "rnWrong passwordrnPassword: " )
  190.                     client.buffer = ""
  191.                 end
  192.             elseif client_command( client ) then
  193.                 client:switch_status( host.status.write )
  194.             end
  195.         end
  196.     end
  197. end
  198. --[[ Clean up ]]
  199. vlm = nil