# include "config.h"
#endif
-#include <vlc/vlc.h>
+#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_interface.h>
#include <vlc_input.h>
"to protect this interface. The default value is \"admin\"." )
#define TELNETPWD_DEFAULT "admin"
-vlc_module_begin();
- set_shortname( "Telnet" );
- set_category( CAT_INTERFACE );
- set_subcategory( SUBCAT_INTERFACE_CONTROL );
+vlc_module_begin ()
+ set_shortname( "Telnet" )
+ set_category( CAT_INTERFACE )
+ set_subcategory( SUBCAT_INTERFACE_CONTROL )
add_string( "telnet-host", "", NULL, TELNETHOST_TEXT,
- TELNETHOST_LONGTEXT, true );
+ TELNETHOST_LONGTEXT, true )
add_integer( "telnet-port", TELNETPORT_DEFAULT, NULL, TELNETPORT_TEXT,
- TELNETPORT_LONGTEXT, true );
+ TELNETPORT_LONGTEXT, true )
add_password( "telnet-password", TELNETPWD_DEFAULT, NULL, TELNETPWD_TEXT,
- TELNETPWD_LONGTEXT, true );
- set_description( _("VLM remote control interface") );
- add_category_hint( "VLM", NULL, false );
- set_capability( "interface", 0 );
- set_callbacks( Open , Close );
-vlc_module_end();
+ TELNETPWD_LONGTEXT, true )
+ set_description( N_("VLM remote control interface") )
+ add_category_hint( "VLM", NULL, false )
+ set_capability( "interface", 0 )
+ set_callbacks( Open , Close )
+vlc_module_end ()
/*****************************************************************************
* Local prototypes.
* This code relies upon the fact the url.i_port is 0 if the :PORT
* option is missing from --telnet-host.
*/
-static int getPort(intf_thread_t *p_intf, vlc_url_t url, int i_port)
+static int getPort(intf_thread_t *p_intf, const vlc_url_t *url, int i_port)
{
- // Print error if two different ports have been specified
- if (url.i_port != 0 &&
- i_port != TELNETPORT_DEFAULT &&
- url.i_port != i_port )
- {
- msg_Err( p_intf, "ignoring port %d and using %d", url.i_port,
- i_port);
- }
- if (i_port != TELNETPORT_DEFAULT)
- {
- return i_port;
- }
- if (url.i_port != 0)
- {
- return url.i_port;
- }
+ if (i_port == TELNETPORT_DEFAULT && url->i_port != 0)
+ i_port = url->i_port;
+ if (url->i_port != 0 && url->i_port != i_port)
+ // Print error if two different ports have been specified
+ msg_Warn( p_intf, "ignoring port %d (using %d)", url->i_port, i_port );
return i_port;
}
psz_address = config_GetPsz( p_intf, "telnet-host" );
vlc_UrlParse(&url, psz_address, 0);
+ free( psz_address );
// There might be two ports given, resolve any potentially
// conflict
- url.i_port = getPort(p_intf, url, i_telnetport);
+ url.i_port = getPort(p_intf, &url, i_telnetport);
p_intf->p_sys = malloc( sizeof( intf_sys_t ) );
- if( ( p_intf->p_sys->pi_fd = net_ListenTCP( p_intf, url.psz_host, url.i_port ) )
- == NULL )
+ if( !p_intf->p_sys )
+ {
+ vlm_Delete( mediatheque );
+ vlc_UrlClean( &url );
+ return VLC_ENOMEM;
+ }
+ if( ( p_intf->p_sys->pi_fd = net_ListenTCP( p_intf, url.psz_host, url.i_port ) ) == NULL )
{
msg_Err( p_intf, "cannot listen for telnet" );
- vlc_UrlClean(&url);
- free( psz_address );
+ vlm_Delete( mediatheque );
+ vlc_UrlClean( &url );
free( p_intf->p_sys );
return VLC_EGENERIC;
}
p_intf->p_sys->mediatheque = mediatheque;
p_intf->pf_run = Run;
- vlc_UrlClean(&url);
- free( psz_address );
+ vlc_UrlClean( &url );
return VLC_SUCCESS;
}
{
telnet_client_t *cl = p_sys->clients[i];
net_Close( cl->fd );
+ free( cl->buffer_write );
free( cl );
- p_sys->clients[i] = NULL;
}
free( p_sys->clients );
for (const int *pfd = p_sys->pi_fd; *pfd != -1; pfd++)
nlisten++; /* How many listening sockets do we have? */
+ /* FIXME: make sure config_* is cancel-safe */
psz_password = config_GetPsz( p_intf, "telnet-password" );
+ vlc_cleanup_push( free, psz_password );
- while( !intf_ShouldDie( p_intf ) )
+ for( ;; )
{
unsigned ncli = p_sys->i_clients;
struct pollfd ufd[ncli + nlisten];
ufd[ncli + i].revents = 0;
}
- /* FIXME: arbitrary tick */
- switch (poll (ufd, sizeof (ufd) / sizeof (ufd[0]), 500))
+ switch (poll (ufd, sizeof (ufd) / sizeof (ufd[0]), -1))
{
case -1:
if (net_errno != EINTR)
continue;
}
+ int canc = vlc_savecancel ();
/* check if there is something to do with the socket */
for (unsigned i = 0; i < ncli; i++)
{
net_Close( cl->fd );
TAB_REMOVE( p_intf->p_sys->i_clients ,
p_intf->p_sys->clients , cl );
+ free( cl->buffer_write );
free( cl );
continue;
}
cl->i_mode + 2 );
}
+#ifdef WIN32
+ if( i_recv <= 0 && WSAGetLastError() == WSAEWOULDBLOCK )
+ {
+ errno = EAGAIN;
+ }
+#endif
if (i_recv <= 0 && ( end || errno != EAGAIN ) )
goto drop;
}
net_Close( cl->fd );
TAB_REMOVE( p_intf->p_sys->i_clients ,
p_intf->p_sys->clients , cl );
+ free( cl->buffer_write );
free( cl );
}
else if( !strncmp( cl->buffer_read, "shutdown", 8 ) )
{
msg_Err( p_intf, "shutdown requested" );
- vlc_object_kill( p_intf->p_libvlc );
+ libvlc_Quit( p_intf->p_libvlc );
}
else if( *cl->buffer_read == '@'
&& strchr( cl->buffer_read, ' ' ) )
}
Write_message( cl, message, NULL, WRITE_MODE_CMD );
vlm_MessageDelete( message );
-
}
}
}
if (fd == -1)
continue;
- telnet_client_t *cl = malloc( sizeof( telnet_client_t ));
+ telnet_client_t *cl = calloc( 1, sizeof( telnet_client_t ));
if (cl == NULL)
{
net_Close (fd);
continue;
}
- memset( cl, 0, sizeof(telnet_client_t) );
cl->i_tel_cmd = 0;
cl->fd = fd;
cl->buffer_write = NULL;
"Password: \xff\xfb\x01" , WRITE_MODE_PWD );
TAB_APPEND( p_sys->i_clients, p_sys->clients, cl );
}
+ vlc_restorecancel( canc );
}
- free( psz_password );
+ vlc_cleanup_run ();
}
static void Write_message( telnet_client_t *client, vlm_message_t *message,