#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
/* 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
{
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];
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 )
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 );
mvar_AppendVar( s, f );
}
+ free( psz_dir );
return s;
}
#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;
while( *str != '\0' )
{
- if( *str == '"' || *str == '\'' )
+ if( *str == '"' || *str == '\'' || *str == '\\' )
{
*p++ = '\\';
}
}
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" ) )
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 )
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:
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 )
{
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" ) )
{
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 ) )
{
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];
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 ) )
{
|| ( 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 ) );
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;
+}