]> git.sesse.net Git - vlc/commitdiff
* modules/control/http/rpn.c: vlc_var_* now take an extra argument to
authorChristophe Massiot <massiot@videolan.org>
Fri, 19 Aug 2005 17:07:27 +0000 (17:07 +0000)
committerChristophe Massiot <massiot@videolan.org>
Fri, 19 Aug 2005 17:07:27 +0000 (17:07 +0000)
   indicate which object we are playing with (for instance 'VLC_OBJECT_INPUT'
   or 'VLC_OBJECT_PLAYLIST'). Espace \ in addslashes.
 * modules/control/http: Factorized and simplified the RealPath() stuff.
   Fixed a few hardcoded '/' as a path separator.

modules/control/http/http.h
modules/control/http/macro.c
modules/control/http/mvar.c
modules/control/http/rpn.c
modules/control/http/util.c

index 80f9b68aa4574e5c4a166cf06506a293bfa699c9..50b710aeb5d9dda6055e3e2963b2448cd1b9f384 100644 (file)
@@ -105,6 +105,8 @@ int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root,
 int E_(FileLoad)( FILE *f, char **pp_data, int *pi_data );
 /** This function creates a suitable URL for a filename */
 char *E_(FileToUrl)( char *name, vlc_bool_t *pb_index );
+/** This function returns the real path of a file or directory */
+char *E_(RealPath)( intf_thread_t *p_intf, const char *psz_src );
 
 /* Locale handling functions */
 
index 7d3764e9f7120cddf0d6498786e26b4a3192453f..ce84c8217d7e705c352d40b99cc50f22d837f250 100644 (file)
@@ -861,11 +861,18 @@ void E_(Execute)( httpd_file_sys_t *p_args,
                     char *p_buffer;
                     char psz_file[MAX_DIR_SIZE];
                     char *p;
+                    char sep;
 
-                    if( m.param1[0] != '/' )
+#if defined( WIN32 )
+                    sep = '\\';
+#else
+                    sep = '/';
+#endif
+
+                    if( m.param1[0] != sep )
                     {
                         strcpy( psz_file, p_args->file );
-                        p = strrchr( psz_file, '/' );
+                        p = strrchr( psz_file, sep );
                         if( p != NULL )
                             strcpy( p + 1, m.param1 );
                         else
index 8dbc31dea8303a1a4a9128c34a687d5d754a0ffe..79b7eebac7e8f09577003815812dc195a442428a 100644 (file)
@@ -495,10 +495,10 @@ mvar_t *mvar_HttpdInfoSetNew( char *name, httpd_t *p_httpd, int i_type )
 #endif
 
 mvar_t *mvar_FileSetNew( intf_thread_t *p_intf, char *name,
-                                char *psz_dir )
+                         char *psz_dir )
 {
     mvar_t *s = mvar_New( name, "set" );
-    char          tmp[MAX_DIR_SIZE], dir[MAX_DIR_SIZE], *p, *src;
+    char          tmp[MAX_DIR_SIZE];
 #ifdef HAVE_SYS_STAT_H
     struct stat   stat_info;
 #endif
@@ -508,91 +508,17 @@ mvar_t *mvar_FileSetNew( intf_thread_t *p_intf, char *name,
 
     /* convert all / to native separator */
 #if defined( WIN32 )
-    while( (p = strchr( psz_dir, '/' )) )
-    {
-        *p = '\\';
-    }
     sep = '\\';
 #else
     sep = '/';
 #endif
 
-    /* remove trailling separator */
-    while( strlen( psz_dir ) > 1 &&
-#if defined( WIN32 )
-           !( strlen(psz_dir)==3 && psz_dir[1]==':' && psz_dir[2]==sep ) &&
-#endif
-           psz_dir[strlen( psz_dir ) -1 ] == sep )
-    {
-        psz_dir[strlen( psz_dir ) -1 ]  ='\0';
-    }
-    /* remove double separator */
-    for( p = src = psz_dir; *src != '\0'; src++, p++ )
-    {
-        if( src[0] == sep && src[1] == sep )
-        {
-            src++;
-        }
-        *p = *src;
-    }
-    *p = '\0';
-
-    if( *psz_dir == '\0' )
-    {
-        return s;
-    }
-
-    if( psz_dir[0] == '~' && psz_dir[1] == '/' )
-    {
-        /* This is incomplete : we should also support the ~cmassiot/ syntax. */
-        snprintf( dir, sizeof(dir), "%s/%s", p_intf->p_vlc->psz_homedir,
-                  psz_dir + 2 );
-        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 );
-        }
-    }
-    *p = '\0';
+    psz_dir = E_(RealPath)( p_intf, psz_dir );
 
 #ifdef HAVE_SYS_STAT_H
     if( stat( psz_dir, &stat_info ) == -1 || !S_ISDIR( stat_info.st_mode ) )
     {
+        free( psz_dir );
         return s;
     }
 #endif
@@ -603,16 +529,10 @@ mvar_t *mvar_FileSetNew( intf_thread_t *p_intf, char *name,
     {
         msg_Warn( p_intf, "scandir error on %s (%s)", psz_dir,
                   strerror(errno) );
+        free( psz_dir );
         return s;
     }
 
-    /* remove trailing / or \ */
-    for( p = &psz_dir[strlen( psz_dir) - 1];
-         p >= psz_dir && ( *p =='/' || *p =='\\' ); p-- )
-    {
-        *p = '\0';
-    }
-
     for( i = 0; i < i_dir_content; i++ )
     {
         struct dirent *p_dir_content = pp_dir_content[i];
@@ -625,7 +545,8 @@ mvar_t *mvar_FileSetNew( intf_thread_t *p_intf, char *name,
             continue;
         }
 
-        snprintf( tmp, sizeof(tmp), "%s/%s", psz_dir, p_dir_content->d_name );
+        snprintf( tmp, sizeof(tmp), "%s%c%s", psz_dir, sep,
+                  p_dir_content->d_name );
 
 #ifdef HAVE_SYS_STAT_H
         if( stat( tmp, &stat_info ) == -1 )
@@ -638,7 +559,7 @@ mvar_t *mvar_FileSetNew( intf_thread_t *p_intf, char *name,
         psz_tmp = vlc_fix_readdir_charset( p_intf, p_dir_content->d_name );
         psz_name = E_(FromUTF8)( p_intf, psz_tmp );
         free( psz_tmp );
-        snprintf( tmp, sizeof(tmp), "%s/%s", psz_dir, psz_name );
+        snprintf( tmp, sizeof(tmp), "%s%c%s", psz_dir, sep, psz_name );
         mvar_AppendNewVar( f, "name", tmp );
         mvar_AppendNewVar( f, "basename", psz_name );
 
@@ -681,6 +602,7 @@ mvar_t *mvar_FileSetNew( intf_thread_t *p_intf, char *name,
         mvar_AppendVar( s, f );
     }
 
+    free( psz_dir );
     return s;
 }
 
index b5c840ec015b10a24c2d4d21724500b2ee66161c..43dee08060d666c566cca9d83406c7e002f732e6 100644 (file)
 
 #include "http.h"
 
+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 SSInit( rpn_stack_t *st )
 {
     st->i_stack = 0;
@@ -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++ = '\\';
                 }
@@ -428,73 +465,13 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
         }
         else if( !strcmp( s, "realpath" ) )
         {
-            char dir[MAX_DIR_SIZE], *src;
             char *psz_src = SSPop( st );
-            char *psz_dir = psz_src;
+            char *psz_dir = E_(RealPath)( p_intf, psz_src );
             char sep;
 
-            /* 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 );
             free( psz_src );
+            free( psz_dir );
         }
         /* 4. stack functions */
         else if( !strcmp( s, "dup" ) )
@@ -584,21 +561,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 = SSPop( st );
+                char *psz_variable = 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 = SSPop( st );
                 p_object = VLC_OBJECT(p_intf);
                 i_type = config_GetType( p_object, psz_variable );
+                free( psz_variable );
             }
 
             if( p_object != NULL )
@@ -640,33 +627,37 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
                 psz_type = "INVALID";
 
             SSPush( st, psz_type );
-            free( psz_variable );
         }
         else if( !strcmp( s, "vlc_var_set" ) )
         {
+            char *psz_object = SSPop( st );
             char *psz_variable = 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 );
+                    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 );
+                    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:
@@ -674,41 +665,51 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
                 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 );
+                    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 );
                     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 );
+                    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_object = SSPop( st );
             char *psz_variable = 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 )
                 {
@@ -735,17 +736,21 @@ void  EvaluateRPN( intf_thread_t *p_intf, mvar_t  *vars,
                     break;
                 }
                 default:
-                    msg_Warn( p_intf, "invalid variable type %d (%s)",
-                              i_type & VLC_VAR_TYPE, psz_variable );
+                    msg_Warn( p_intf, "invalid %s variable type %d (%s)",
+                              psz_object, i_type & VLC_VAR_TYPE, psz_variable );
                     SSPush( st, "" );
                 }
             }
             else
             {
-                msg_Warn( p_intf, "vlc_var_get called without an input" );
+                msg_Warn( p_intf, "vlc_var_get called without an object" );
                 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" ) )
         {
index ee4c5ee9b4327f0c5ff049277a58f666ababc373..213081810b23f73b9d45b945f4c104d3c80efcd1 100644 (file)
@@ -120,6 +120,14 @@ int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root,
 
     int           i_dirlen;
 
+    char sep;
+
+#if defined( WIN32 )
+    sep = '\\';
+#else
+    sep = '/';
+#endif
+
 #ifdef HAVE_SYS_STAT_H
     if( stat( psz_dir, &stat_info ) == -1 || !S_ISDIR( stat_info.st_mode ) )
     {
@@ -142,7 +150,7 @@ int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root,
 
     msg_Dbg( p_intf, "dir=%s", psz_dir );
 
-    sprintf( dir, "%s/.access", psz_dir );
+    sprintf( dir, "%s%c.access", psz_dir, sep );
     if( ( file = fopen( dir, "r" ) ) != NULL )
     {
         char line[1024];
@@ -176,7 +184,7 @@ int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root,
         fclose( file );
     }
 
-    sprintf( dir, "%s/.hosts", psz_dir );
+    sprintf( dir, "%s%c.hosts", psz_dir, sep );
     p_acl = ACL_Create( p_intf, VLC_FALSE );
     if( ACL_LoadFile( p_acl, dir ) )
     {
@@ -196,7 +204,7 @@ int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root,
          || ( i_dirlen + strlen( p_dir_content->d_name ) > MAX_DIR_SIZE ) )
             continue;
 
-        sprintf( dir, "%s/%s", psz_dir, p_dir_content->d_name );
+        sprintf( dir, "%s%c%s", psz_dir, sep, p_dir_content->d_name );
         if( E_(ParseDirectory)( p_intf, psz_root, dir ) )
         {
             httpd_file_sys_t *f = malloc( sizeof( httpd_file_sys_t ) );
@@ -793,3 +801,92 @@ playlist_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *_psz,
     free( psz );
     return p_item;
 }
+
+/**********************************************************************
+ * RealPath: parse ../, ~ and path stuff
+ **********************************************************************/
+char *E_(RealPath)( intf_thread_t *p_intf, const char *psz_src )
+{
+    char *psz_dir;
+    char *p;
+    int i_len = strlen(psz_src);
+    char sep;
+
+#if defined( WIN32 )
+    sep = '\\';
+#else
+    sep = '/';
+#endif
+
+    psz_dir = malloc( i_len + 2 );
+    strcpy( psz_dir, psz_src );
+
+    /* Add a trailing sep to ease the .. step */
+    psz_dir[i_len] = sep;
+    psz_dir[i_len + 1] = '\0';
+
+#ifdef WIN32
+    /* Convert all / to native separator */
+    p = psz_dir;
+    while( (p = strchr( p, '/' )) != NULL )
+    {
+        *p = sep;
+    }
+#endif
+
+    /* Remove multiple separators and /./ */
+    p = psz_dir;
+    while( (p = strchr( p, sep )) != NULL )
+    {
+        if( p[1] == sep )
+            memmove( &p[1], &p[2], strlen(&p[2]) + 1 );
+        else if( p[1] == '.' && p[2] == sep )
+            memmove( &p[1], &p[3], strlen(&p[3]) + 1 );
+        else
+            p++;
+    }
+
+    if( psz_dir[0] == '~' )
+    {
+        char *dir = malloc( strlen(psz_dir)
+                             + strlen(p_intf->p_vlc->psz_homedir) );
+        /* This is incomplete : we should also support the ~cmassiot/ syntax. */
+        sprintf( dir, "%s%s", p_intf->p_vlc->psz_homedir, psz_dir + 1 );
+        free( psz_dir );
+        psz_dir = dir;
+    }
+
+    if( strlen(psz_dir) > 2 )
+    {
+        /* Fix all .. dir */
+        p = psz_dir + 3;
+        while( (p = strchr( p, sep )) != NULL )
+        {
+            if( p[-1] == '.' && p[-2] == '.' && p[-3] == sep )
+            {
+                char *q;
+                p[-3] = '\0';
+                if( (q = strrchr( psz_dir, sep )) != NULL )
+                {
+                    memmove( q + 1, p + 1, strlen(p + 1) + 1 );
+                    p = q + 1;
+                }
+                else
+                {
+                    memmove( psz_dir, p + 1, strlen(p + 1) + 1 );
+                    p = psz_dir + 3;
+                }
+            }
+            else
+                p++;
+        }
+    }
+
+    /* Remove trailing sep if there are at least 2 sep in the string
+     * (handles the C:\ stuff) */
+    p = strrchr( psz_dir, sep );
+    if( p != NULL && p[1] == '\0' && p != strchr( psz_dir, sep ) )
+        *p = '\0';
+
+    return psz_dir;
+}