]> git.sesse.net Git - vlc/blobdiff - modules/control/http/rpn.c
* modules/control/http/http.c: Fixed argv[1] in CGI mode.
[vlc] / modules / control / http / rpn.c
index b5c840ec015b10a24c2d4d21724500b2ee66161c..5dcc2847272c42d7ba5bb7b417e4d2294fcff424 100644 (file)
 
 #include "http.h"
 
-void SSInit( rpn_stack_t *st )
+static vlc_object_t *GetVLCObject( intf_thread_t *p_intf,
+                                   const char *psz_object,
+                                   vlc_bool_t *pb_need_release )
+{
+    intf_sys_t    *p_sys = p_intf->p_sys;
+    int i_object_type = 0;
+    vlc_object_t *p_object = NULL;
+    *pb_need_release = VLC_FALSE;
+
+    if( !strcmp( psz_object, "VLC_OBJECT_ROOT" ) )
+        i_object_type = VLC_OBJECT_ROOT;
+    else if( !strcmp( psz_object, "VLC_OBJECT_VLC" ) )
+        p_object = VLC_OBJECT(p_intf->p_vlc);
+    else if( !strcmp( psz_object, "VLC_OBJECT_INTF" ) )
+        p_object = VLC_OBJECT(p_intf);
+    else if( !strcmp( psz_object, "VLC_OBJECT_PLAYLIST" ) )
+        p_object = VLC_OBJECT(p_sys->p_playlist);
+    else if( !strcmp( psz_object, "VLC_OBJECT_INPUT" ) )
+        p_object = VLC_OBJECT(p_sys->p_input);
+    else if( !strcmp( psz_object, "VLC_OBJECT_VOUT" ) )
+        i_object_type = VLC_OBJECT_VOUT;
+    else if( !strcmp( psz_object, "VLC_OBJECT_AOUT" ) )
+        i_object_type = VLC_OBJECT_AOUT;
+    else if( !strcmp( psz_object, "VLC_OBJECT_SOUT" ) )
+        i_object_type = VLC_OBJECT_SOUT;
+    else
+        msg_Warn( p_intf, "unknown object type (%s)", psz_object );
+
+    if( p_object == NULL && i_object_type )
+    {
+        *pb_need_release = VLC_TRUE;
+        p_object = vlc_object_find( p_intf, i_object_type, FIND_ANYWHERE );
+    }
+
+    return p_object;
+}
+
+void E_(SSInit)( rpn_stack_t *st )
 {
     st->i_stack = 0;
 }
 
-void SSClean( rpn_stack_t *st )
+void E_(SSClean)( rpn_stack_t *st )
 {
     while( st->i_stack > 0 )
     {
@@ -38,7 +75,7 @@ void SSClean( rpn_stack_t *st )
     }
 }
 
-void SSPush( rpn_stack_t *st, const char *s )
+void E_(SSPush)( rpn_stack_t *st, const char *s )
 {
     if( st->i_stack < STACK_MAX )
     {
@@ -46,7 +83,7 @@ void SSPush( rpn_stack_t *st, const char *s )
     }
 }
 
-char * SSPop( rpn_stack_t *st )
+char *E_(SSPop)( rpn_stack_t *st )
 {
     if( st->i_stack <= 0 )
     {
@@ -58,7 +95,7 @@ char * SSPop( rpn_stack_t *st )
     }
 }
 
-int SSPopN( rpn_stack_t *st, mvar_t  *vars )
+int E_(SSPopN)( rpn_stack_t *st, mvar_t  *vars )
 {
     char *name;
     char *value;
@@ -66,11 +103,11 @@ int SSPopN( rpn_stack_t *st, mvar_t  *vars )
     char *end;
     int  i;
 
-    name = SSPop( st );
+    name = E_(SSPop)( st );
     i = strtol( name, &end, 0 );
     if( end == name )
     {
-        value = mvar_GetValue( vars, name );
+        value = E_(mvar_GetValue)( vars, name );
         i = atoi( value );
     }
     free( name );
@@ -78,16 +115,16 @@ int SSPopN( rpn_stack_t *st, mvar_t  *vars )
     return( i );
 }
 
-void SSPushN( rpn_stack_t *st, int i )
+void E_(SSPushN)( rpn_stack_t *st, int i )
 {
     char v[512];
 
     sprintf( v, "%d", i );
-    SSPush( st, v );
+    E_(SSPush)( st, v );
 }
 
-void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
-                   rpn_stack_t *st, char *exp )
+void E_(EvaluateRPN)( intf_thread_t *p_intf, mvar_t  *vars,
+                      rpn_stack_t *st, char *exp )
 {
     intf_sys_t    *p_sys = p_intf->p_sys;
 
@@ -105,7 +142,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         {
             /* extract string */
             p = E_(FirstWord)( exp, exp );
-            SSPush( st, exp );
+            E_(SSPush)( st, exp );
             exp = p;
             continue;
         }
@@ -130,129 +167,129 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         /* 1. Integer function */
         if( !strcmp( s, "!" ) )
         {
-            SSPushN( st, ~SSPopN( st, vars ) );
+            E_(SSPushN)( st, ~E_(SSPopN)( st, vars ) );
         }
         else if( !strcmp( s, "^" ) )
         {
-            SSPushN( st, SSPopN( st, vars ) ^ SSPopN( st, vars ) );
+            E_(SSPushN)( st, E_(SSPopN)( st, vars ) ^ E_(SSPopN)( st, vars ) );
         }
         else if( !strcmp( s, "&" ) )
         {
-            SSPushN( st, SSPopN( st, vars ) & SSPopN( st, vars ) );
+            E_(SSPushN)( st, E_(SSPopN)( st, vars ) & E_(SSPopN)( st, vars ) );
         }
         else if( !strcmp( s, "|" ) )
         {
-            SSPushN( st, SSPopN( st, vars ) | SSPopN( st, vars ) );
+            E_(SSPushN)( st, E_(SSPopN)( st, vars ) | E_(SSPopN)( st, vars ) );
         }
         else if( !strcmp( s, "+" ) )
         {
-            SSPushN( st, SSPopN( st, vars ) + SSPopN( st, vars ) );
+            E_(SSPushN)( st, E_(SSPopN)( st, vars ) + E_(SSPopN)( st, vars ) );
         }
         else if( !strcmp( s, "-" ) )
         {
-            int j = SSPopN( st, vars );
-            int i = SSPopN( st, vars );
-            SSPushN( st, i - j );
+            int j = E_(SSPopN)( st, vars );
+            int i = E_(SSPopN)( st, vars );
+            E_(SSPushN)( st, i - j );
         }
         else if( !strcmp( s, "*" ) )
         {
-            SSPushN( st, SSPopN( st, vars ) * SSPopN( st, vars ) );
+            E_(SSPushN)( st, E_(SSPopN)( st, vars ) * E_(SSPopN)( st, vars ) );
         }
         else if( !strcmp( s, "/" ) )
         {
             int i, j;
 
-            j = SSPopN( st, vars );
-            i = SSPopN( st, vars );
+            j = E_(SSPopN)( st, vars );
+            i = E_(SSPopN)( st, vars );
 
-            SSPushN( st, j != 0 ? i / j : 0 );
+            E_(SSPushN)( st, j != 0 ? i / j : 0 );
         }
         else if( !strcmp( s, "%" ) )
         {
             int i, j;
 
-            j = SSPopN( st, vars );
-            i = SSPopN( st, vars );
+            j = E_(SSPopN)( st, vars );
+            i = E_(SSPopN)( st, vars );
 
-            SSPushN( st, j != 0 ? i % j : 0 );
+            E_(SSPushN)( st, j != 0 ? i % j : 0 );
         }
         /* 2. integer tests */
         else if( !strcmp( s, "=" ) )
         {
-            SSPushN( st, SSPopN( st, vars ) == SSPopN( st, vars ) ? -1 : 0 );
+            E_(SSPushN)( st, E_(SSPopN)( st, vars ) == E_(SSPopN)( st, vars ) ? -1 : 0 );
         }
         else if( !strcmp( s, "!=" ) )
         {
-            SSPushN( st, SSPopN( st, vars ) != SSPopN( st, vars ) ? -1 : 0 );
+            E_(SSPushN)( st, E_(SSPopN)( st, vars ) != E_(SSPopN)( st, vars ) ? -1 : 0 );
         }
         else if( !strcmp( s, "<" ) )
         {
-            int j = SSPopN( st, vars );
-            int i = SSPopN( st, vars );
+            int j = E_(SSPopN)( st, vars );
+            int i = E_(SSPopN)( st, vars );
 
-            SSPushN( st, i < j ? -1 : 0 );
+            E_(SSPushN)( st, i < j ? -1 : 0 );
         }
         else if( !strcmp( s, ">" ) )
         {
-            int j = SSPopN( st, vars );
-            int i = SSPopN( st, vars );
+            int j = E_(SSPopN)( st, vars );
+            int i = E_(SSPopN)( st, vars );
 
-            SSPushN( st, i > j ? -1 : 0 );
+            E_(SSPushN)( st, i > j ? -1 : 0 );
         }
         else if( !strcmp( s, "<=" ) )
         {
-            int j = SSPopN( st, vars );
-            int i = SSPopN( st, vars );
+            int j = E_(SSPopN)( st, vars );
+            int i = E_(SSPopN)( st, vars );
 
-            SSPushN( st, i <= j ? -1 : 0 );
+            E_(SSPushN)( st, i <= j ? -1 : 0 );
         }
         else if( !strcmp( s, ">=" ) )
         {
-            int j = SSPopN( st, vars );
-            int i = SSPopN( st, vars );
+            int j = E_(SSPopN)( st, vars );
+            int i = E_(SSPopN)( st, vars );
 
-            SSPushN( st, i >= j ? -1 : 0 );
+            E_(SSPushN)( st, i >= j ? -1 : 0 );
         }
         /* 3. string functions */
         else if( !strcmp( s, "strcat" ) )
         {
-            char *s2 = SSPop( st );
-            char *s1 = SSPop( st );
+            char *s2 = E_(SSPop)( st );
+            char *s1 = E_(SSPop)( st );
             char *str = malloc( strlen( s1 ) + strlen( s2 ) + 1 );
 
             strcpy( str, s1 );
             strcat( str, s2 );
 
-            SSPush( st, str );
+            E_(SSPush)( st, str );
             free( s1 );
             free( s2 );
             free( str );
         }
         else if( !strcmp( s, "strcmp" ) )
         {
-            char *s2 = SSPop( st );
-            char *s1 = SSPop( st );
+            char *s2 = E_(SSPop)( st );
+            char *s1 = E_(SSPop)( st );
 
-            SSPushN( st, strcmp( s1, s2 ) );
+            E_(SSPushN)( st, strcmp( s1, s2 ) );
             free( s1 );
             free( s2 );
         }
         else if( !strcmp( s, "strncmp" ) )
         {
-            int n = SSPopN( st, vars );
-            char *s2 = SSPop( st );
-            char *s1 = SSPop( st );
+            int n = E_(SSPopN)( st, vars );
+            char *s2 = E_(SSPop)( st );
+            char *s1 = E_(SSPop)( st );
 
-            SSPushN( st, strncmp( s1, s2 , n ) );
+            E_(SSPushN)( st, strncmp( s1, s2 , n ) );
             free( s1 );
             free( s2 );
         }
         else if( !strcmp( s, "strsub" ) )
         {
-            int n = SSPopN( st, vars );
-            int m = SSPopN( st, vars );
+            int n = E_(SSPopN)( st, vars );
+            int m = E_(SSPopN)( st, vars );
             int i_len;
-            char *s = SSPop( st );
+            char *s = E_(SSPop)( st );
             char *str;
 
             if( n >= m )
@@ -269,22 +306,22 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             memcpy( str, s + m - 1, i_len );
             str[ i_len ] = '\0';
 
-            SSPush( st, str );
+            E_(SSPush)( st, str );
             free( s );
             free( str );
         }
         else if( !strcmp( s, "strlen" ) )
         {
-            char *str = SSPop( st );
+            char *str = E_(SSPop)( st );
 
-            SSPushN( st, strlen( str ) );
+            E_(SSPushN)( st, strlen( str ) );
             free( str );
         }
         else if( !strcmp( s, "str_replace" ) )
         {
-            char *psz_to = SSPop( st );
-            char *psz_from = SSPop( st );
-            char *psz_in = SSPop( st );
+            char *psz_to = E_(SSPop)( st );
+            char *psz_from = E_(SSPop)( st );
+            char *psz_in = E_(SSPop)( st );
             char *psz_in_current = psz_in;
             char *psz_out = malloc( strlen(psz_in) * strlen(psz_to) + 1 );
             char *psz_out_current = psz_out;
@@ -301,7 +338,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             psz_out_current += strlen(psz_in_current);
             *psz_out_current = '\0';
 
-            SSPush( st, psz_out );
+            E_(SSPush)( st, psz_out );
             free( psz_to );
             free( psz_from );
             free( psz_in );
@@ -309,21 +346,21 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else if( !strcmp( s, "url_extract" ) )
         {
-            char *url = mvar_GetValue( vars, "url_value" );
-            char *name = SSPop( st );
+            char *url = E_(mvar_GetValue)( vars, "url_value" );
+            char *name = E_(SSPop)( st );
             char value[512];
             char *tmp;
 
             E_(ExtractURIValue)( url, name, value, 512 );
             E_(DecodeEncodedURI)( value );
             tmp = E_(FromUTF8)( p_intf, value );
-            SSPush( st, tmp );
+            E_(SSPush)( st, tmp );
             free( tmp );
             free( name );
         }
         else if( !strcmp( s, "url_encode" ) )
         {
-            char *url = SSPop( st );
+            char *url = E_(SSPop)( st );
             char *value;
 
             value = E_(ToUTF8)( p_intf, url );
@@ -331,12 +368,12 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             url = value;
             value = vlc_UrlEncode( url );
             free( url );
-            SSPush( st, value );
+            E_(SSPush)( st, value );
             free( value );
         }
         else if( !strcmp( s, "addslashes" ) )
         {
-            char *psz_src = SSPop( st );
+            char *psz_src = E_(SSPop)( st );
             char *psz_dest;
             char *str = psz_src;
 
@@ -344,7 +381,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
 
             while( *str != '\0' )
             {
-                if( *str == '"' || *str == '\'' )
+                if( *str == '"' || *str == '\'' || *str == '\\' )
                 {
                     *p++ = '\\';
                 }
@@ -353,13 +390,13 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             }
             *p = '\0';
 
-            SSPush( st, psz_dest );
+            E_(SSPush)( st, psz_dest );
             free( psz_src );
             free( psz_dest );
         }
         else if( !strcmp( s, "stripslashes" ) )
         {
-            char *psz_src = SSPop( st );
+            char *psz_src = E_(SSPop)( st );
             char *psz_dest;
 
             p = psz_dest = strdup( psz_src );
@@ -375,13 +412,13 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             }
             *p = '\0';
 
-            SSPush( st, psz_dest );
+            E_(SSPush)( st, psz_dest );
             free( psz_src );
             free( psz_dest );
         }
         else if( !strcmp( s, "htmlspecialchars" ) )
         {
-            char *psz_src = SSPop( st );
+            char *psz_src = E_(SSPop)( st );
             char *psz_dest;
             char *str = psz_src;
 
@@ -422,137 +459,76 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             }
             *p = '\0';
 
-            SSPush( st, psz_dest );
+            E_(SSPush)( st, psz_dest );
             free( psz_src );
             free( psz_dest );
         }
         else if( !strcmp( s, "realpath" ) )
         {
-            char dir[MAX_DIR_SIZE], *src;
-            char *psz_src = SSPop( st );
-            char *psz_dir = psz_src;
-            char sep;
+            char *psz_src = E_(SSPop)( st );
+            char *psz_dir = E_(RealPath)( p_intf, psz_src );
 
-            /* convert all / to native separator */
-#if defined( WIN32 )
-            while( (p = strchr( psz_dir, '/' )) )
-            {
-                *p = '\\';
-            }
-            sep = '\\';
-#else
-            sep = '/';
-#endif
-
-            if( *psz_dir == '~' )
-            {
-                /* This is incomplete : we should also support the ~cmassiot/ syntax. */
-                snprintf( dir, sizeof(dir), "%s/%s", p_intf->p_vlc->psz_homedir,
-                          psz_dir + 1 );
-                psz_dir = dir;
-            }
-
-            /* first fix all .. dir */
-            p = src = psz_dir;
-            while( *src )
-            {
-                if( src[0] == '.' && src[1] == '.' )
-                {
-                    src += 2;
-                    if( p <= &psz_dir[1] )
-                    {
-                        continue;
-                    }
-
-                    p -= 2;
-
-                    while( p > &psz_dir[1] && *p != sep )
-                    {
-                        p--;
-                    }
-                }
-                else if( *src == sep )
-                {
-                    if( p > psz_dir && p[-1] == sep )
-                    {
-                        src++;
-                    }
-                    else
-                    {
-                        *p++ = *src++;
-                    }
-                }
-                else
-                {
-                    do
-                    {
-                        *p++ = *src++;
-                    } while( *src && *src != sep );
-                }
-            }
-            if( p != psz_dir + 1 && p[-1] == '/' ) p--;
-            *p = '\0';
-
-            SSPush( st, psz_dir );
+            E_(SSPush)( st, psz_dir );
             free( psz_src );
+            free( psz_dir );
         }
         /* 4. stack functions */
         else if( !strcmp( s, "dup" ) )
         {
-            char *str = SSPop( st );
-            SSPush( st, str );
-            SSPush( st, str );
+            char *str = E_(SSPop)( st );
+            E_(SSPush)( st, str );
+            E_(SSPush)( st, str );
             free( str );
         }
         else if( !strcmp( s, "drop" ) )
         {
-            char *str = SSPop( st );
+            char *str = E_(SSPop)( st );
             free( str );
         }
         else if( !strcmp( s, "swap" ) )
         {
-            char *s1 = SSPop( st );
-            char *s2 = SSPop( st );
+            char *s1 = E_(SSPop)( st );
+            char *s2 = E_(SSPop)( st );
 
-            SSPush( st, s1 );
-            SSPush( st, s2 );
+            E_(SSPush)( st, s1 );
+            E_(SSPush)( st, s2 );
             free( s1 );
             free( s2 );
         }
         else if( !strcmp( s, "flush" ) )
         {
-            SSClean( st );
-            SSInit( st );
+            E_(SSClean)( st );
+            E_(SSInit)( st );
         }
         else if( !strcmp( s, "store" ) )
         {
-            char *value = SSPop( st );
-            char *name  = SSPop( st );
+            char *value = E_(SSPop)( st );
+            char *name  = E_(SSPop)( st );
 
-            mvar_PushNewVar( vars, name, value );
+            E_(mvar_PushNewVar)( vars, name, value );
             free( name );
             free( value );
         }
         else if( !strcmp( s, "value" ) )
         {
-            char *name  = SSPop( st );
-            char *value = mvar_GetValue( vars, name );
+            char *name  = E_(SSPop)( st );
+            char *value = E_(mvar_GetValue)( vars, name );
 
-            SSPush( st, value );
+            E_(SSPush)( st, value );
 
             free( name );
         }
         /* 5. player control */
         else if( !strcmp( s, "vlc_play" ) )
         {
-            int i_id = SSPopN( st, vars );
+            int i_id = E_(SSPopN)( st, vars );
             int i_ret;
 
             i_ret = playlist_Control( p_sys->p_playlist, PLAYLIST_ITEMPLAY,
                                       playlist_ItemGetById( p_sys->p_playlist,
                                       i_id ) );
             msg_Dbg( p_intf, "requested playlist item: %i", i_id );
-            SSPushN( st, i_ret );
+            E_(SSPushN)( st, i_ret );
         }
         else if( !strcmp( s, "vlc_stop" ) )
         {
@@ -576,7 +552,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else if( !strcmp( s, "vlc_seek" ) )
         {
-            char *psz_value = SSPop( st );
+            char *psz_value = E_(SSPop)( st );
             E_(HandleSeek)( p_intf, psz_value );
             msg_Dbg( p_intf, "requested playlist seek: %s", psz_value );
             free( psz_value );
@@ -584,21 +560,31 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         else if( !strcmp( s, "vlc_var_type" )
                   || !strcmp( s, "vlc_config_type" ) )
         {
-            const char *psz_type = NULL;
-            char *psz_variable = SSPop( st );
             vlc_object_t *p_object;
-            int i_type;
+            const char *psz_type = NULL;
+            int i_type = 0;
 
             if( !strcmp( s, "vlc_var_type" ) )
             {
-                p_object = VLC_OBJECT(p_sys->p_input);
+                char *psz_object = E_(SSPop)( st );
+                char *psz_variable = E_(SSPop)( st );
+                vlc_bool_t b_need_release;
+
+                p_object = GetVLCObject( p_intf, psz_object, &b_need_release );
+
                 if( p_object != NULL )
                     i_type = var_Type( p_object, psz_variable );
+                free( psz_variable );
+                free( psz_object );
+                if( b_need_release && p_object != NULL )
+                    vlc_object_release( p_object );
             }
             else
             {
+                char *psz_variable = E_(SSPop)( st );
                 p_object = VLC_OBJECT(p_intf);
                 i_type = config_GetType( p_object, psz_variable );
+                free( psz_variable );
             }
 
             if( p_object != NULL )
@@ -639,138 +625,156 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             else
                 psz_type = "INVALID";
 
-            SSPush( st, psz_type );
-            free( psz_variable );
+            E_(SSPush)( st, psz_type );
         }
         else if( !strcmp( s, "vlc_var_set" ) )
         {
-            char *psz_variable = SSPop( st );
+            char *psz_object = E_(SSPop)( st );
+            char *psz_variable = E_(SSPop)( st );
+            vlc_bool_t b_need_release;
 
-            if( p_sys->p_input != NULL )
+            vlc_object_t *p_object = GetVLCObject( p_intf, psz_object,
+                                                   &b_need_release );
+
+            if( p_object != NULL )
             {
                 vlc_bool_t b_error = VLC_FALSE;
                 char *psz_value = NULL;
                 vlc_value_t val;
                 int i_type;
 
-                i_type = var_Type( p_sys->p_input, psz_variable );
+                i_type = var_Type( p_object, psz_variable );
 
                 switch( i_type & VLC_VAR_TYPE )
                 {
                 case VLC_VAR_BOOL:
-                    val.b_bool = SSPopN( st, vars );
-                    msg_Dbg( p_intf, "requested input var change: %s->%d",
-                             psz_variable, val.b_bool );
+                    val.b_bool = E_(SSPopN)( st, vars );
+                    msg_Dbg( p_intf, "requested %s var change: %s->%d",
+                             psz_object, psz_variable, val.b_bool );
                     break;
                 case VLC_VAR_INTEGER:
                 case VLC_VAR_HOTKEY:
-                    val.i_int = SSPopN( st, vars );
-                    msg_Dbg( p_intf, "requested input var change: %s->%d",
-                             psz_variable, val.i_int );
+                    val.i_int = E_(SSPopN)( st, vars );
+                    msg_Dbg( p_intf, "requested %s var change: %s->%d",
+                             psz_object, psz_variable, val.i_int );
                     break;
                 case VLC_VAR_STRING:
                 case VLC_VAR_MODULE:
                 case VLC_VAR_FILE:
                 case VLC_VAR_DIRECTORY:
                 case VLC_VAR_VARIABLE:
-                    val.psz_string = psz_value = SSPop( st );
-                    msg_Dbg( p_intf, "requested input var change: %s->%s",
-                             psz_variable, psz_value );
+                    val.psz_string = psz_value = E_(SSPop)( st );
+                    msg_Dbg( p_intf, "requested %s var change: %s->%s",
+                             psz_object, psz_variable, psz_value );
                     break;
                 case VLC_VAR_FLOAT:
-                    psz_value = SSPop( st );
+                    psz_value = E_(SSPop)( st );
                     val.f_float = atof( psz_value );
-                    msg_Dbg( p_intf, "requested input var change: %s->%f",
-                             psz_variable, val.f_float );
+                    msg_Dbg( p_intf, "requested %s var change: %s->%f",
+                             psz_object, psz_variable, val.f_float );
                     break;
                 default:
-                    msg_Warn( p_intf, "invalid variable type %d (%s)",
-                              i_type & VLC_VAR_TYPE, psz_variable );
+                    E_(SSPopN)( st, vars );
+                    msg_Warn( p_intf, "invalid %s variable type %d (%s)",
+                              psz_object, i_type & VLC_VAR_TYPE, psz_variable );
                     b_error = VLC_TRUE;
                 }
 
                 if( !b_error )
-                    var_Set( p_sys->p_input, psz_variable, val );
+                    var_Set( p_object, psz_variable, val );
                 if( psz_value != NULL )
                     free( psz_value );
             }
             else
-                msg_Warn( p_intf, "vlc_var_set called without an input" );
+                msg_Warn( p_intf, "vlc_var_set called without an object" );
             free( psz_variable );
+            free( psz_object );
+
+            if( b_need_release && p_object != NULL )
+                vlc_object_release( p_object );
         }
         else if( !strcmp( s, "vlc_var_get" ) )
         {
-            char *psz_variable = SSPop( st );
+            char *psz_object = E_(SSPop)( st );
+            char *psz_variable = E_(SSPop)( st );
+            vlc_bool_t b_need_release;
+
+            vlc_object_t *p_object = GetVLCObject( p_intf, psz_object,
+                                                   &b_need_release );
 
-            if( p_sys->p_input != NULL )
+            if( p_object != NULL )
             {
                 vlc_value_t val;
                 int i_type;
 
-                i_type = var_Type( p_sys->p_input, psz_variable );
-                var_Get( p_sys->p_input, psz_variable, &val );
+                i_type = var_Type( p_object, psz_variable );
+                var_Get( p_object, psz_variable, &val );
 
                 switch( i_type & VLC_VAR_TYPE )
                 {
                 case VLC_VAR_BOOL:
-                    SSPushN( st, val.b_bool );
+                    E_(SSPushN)( st, val.b_bool );
                     break;
                 case VLC_VAR_INTEGER:
                 case VLC_VAR_HOTKEY:
-                    SSPushN( st, val.i_int );
+                    E_(SSPushN)( st, val.i_int );
                     break;
                 case VLC_VAR_STRING:
                 case VLC_VAR_MODULE:
                 case VLC_VAR_FILE:
                 case VLC_VAR_DIRECTORY:
                 case VLC_VAR_VARIABLE:
-                    SSPush( st, val.psz_string );
+                    E_(SSPush)( st, val.psz_string );
                     free( val.psz_string );
                     break;
                 case VLC_VAR_FLOAT:
                 {
                     char psz_value[20];
                     snprintf( psz_value, sizeof(psz_value), "%f", val.f_float );
-                    SSPush( st, psz_value );
+                    E_(SSPush)( st, psz_value );
                     break;
                 }
                 default:
-                    msg_Warn( p_intf, "invalid variable type %d (%s)",
-                              i_type & VLC_VAR_TYPE, psz_variable );
-                    SSPush( st, "" );
+                    msg_Warn( p_intf, "invalid %s variable type %d (%s)",
+                              psz_object, i_type & VLC_VAR_TYPE, psz_variable );
+                    E_(SSPush)( st, "" );
                 }
             }
             else
             {
-                msg_Warn( p_intf, "vlc_var_get called without an input" );
-                SSPush( st, "" );
+                msg_Warn( p_intf, "vlc_var_get called without an object" );
+                E_(SSPush)( st, "" );
             }
             free( psz_variable );
+            free( psz_object );
+
+            if( b_need_release && p_object != NULL )
+                vlc_object_release( p_object );
         }
         else if( !strcmp( s, "vlc_config_set" ) )
         {
-            char *psz_variable = SSPop( st );
+            char *psz_variable = E_(SSPop)( st );
             int i_type = config_GetType( p_intf, psz_variable );
 
             switch( i_type & VLC_VAR_TYPE )
             {
             case VLC_VAR_BOOL:
             case VLC_VAR_INTEGER:
-                config_PutInt( p_intf, psz_variable, SSPopN( st, vars ) );
+                config_PutInt( p_intf, psz_variable, E_(SSPopN)( st, vars ) );
                 break;
             case VLC_VAR_STRING:
             case VLC_VAR_MODULE:
             case VLC_VAR_FILE:
             case VLC_VAR_DIRECTORY:
             {
-                char *psz_string = SSPop( st );
+                char *psz_string = E_(SSPop)( st );
                 config_PutPsz( p_intf, psz_variable, psz_string );
                 free( psz_string );
                 break;
             }
             case VLC_VAR_FLOAT:
             {
-                char *psz_string = SSPop( st );
+                char *psz_string = E_(SSPop)( st );
                 config_PutFloat( p_intf, psz_variable, atof(psz_string) );
                 free( psz_string );
                 break;
@@ -783,14 +787,14 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else if( !strcmp( s, "vlc_config_get" ) )
         {
-            char *psz_variable = SSPop( st );
+            char *psz_variable = E_(SSPop)( st );
             int i_type = config_GetType( p_intf, psz_variable );
 
             switch( i_type & VLC_VAR_TYPE )
             {
             case VLC_VAR_BOOL:
             case VLC_VAR_INTEGER:
-                SSPushN( st, config_GetInt( p_intf, psz_variable ) );
+                E_(SSPushN)( st, config_GetInt( p_intf, psz_variable ) );
                 break;
             case VLC_VAR_STRING:
             case VLC_VAR_MODULE:
@@ -798,7 +802,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
             case VLC_VAR_DIRECTORY:
             {
                 char *psz_string = config_GetPsz( p_intf, psz_variable );
-                SSPush( st, psz_string );
+                E_(SSPush)( st, psz_string );
                 free( psz_string );
                 break;
             }
@@ -807,7 +811,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
                 char psz_string[20];
                 snprintf( psz_string, sizeof(psz_string), "%f",
                           config_GetFloat( p_intf, psz_variable ) );
-                SSPush( st, psz_string );
+                E_(SSPush)( st, psz_string );
                 break;
             }
             default:
@@ -818,7 +822,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else if( !strcmp( s, "vlc_config_save" ) )
         {
-            char *psz_module = SSPop( st );
+            char *psz_module = E_(SSPop)( st );
             int i_result;
 
             if( !*psz_module )
@@ -830,7 +834,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
 
             if( psz_module != NULL )
                 free( psz_module );
-            SSPushN( st, i_result );
+            E_(SSPushN)( st, i_result );
         }
         else if( !strcmp( s, "vlc_config_reset" ) )
         {
@@ -839,8 +843,8 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         /* 6. playlist functions */
         else if( !strcmp( s, "playlist_add" ) )
         {
-            char *psz_name = SSPop( st );
-            char *mrl = SSPop( st );
+            char *psz_name = E_(SSPop)( st );
+            char *mrl = E_(SSPop)( st );
             char *tmp;
             playlist_item_t *p_item;
             int i_id;
@@ -873,7 +877,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
                                          PLAYLIST_APPEND, PLAYLIST_END );
                 msg_Dbg( p_intf, "requested mrl add: %s", mrl );
             }
-            SSPushN( st, i_id );
+            E_(SSPushN)( st, i_id );
 
             free( mrl );
             free( psz_name );
@@ -885,14 +889,14 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else if( !strcmp( s, "playlist_delete" ) )
         {
-            int i_id = SSPopN( st, vars );
+            int i_id = E_(SSPopN)( st, vars );
             playlist_LockDelete( p_sys->p_playlist, i_id );
             msg_Dbg( p_intf, "requested playlist delete: %d", i_id );
         }
         else if( !strcmp( s, "playlist_move" ) )
         {
-            int i_newpos = SSPopN( st, vars );
-            int i_pos = SSPopN( st, vars );
+            int i_newpos = E_(SSPopN)( st, vars );
+            int i_pos = E_(SSPopN)( st, vars );
             if ( i_pos < i_newpos )
             {
                 playlist_Move( p_sys->p_playlist, i_pos, i_newpos + 1 );
@@ -906,7 +910,7 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else
         {
-            SSPush( st, s );
+            E_(SSPush)( st, s );
         }
     }
 }