while( *name )
{
if( *name == '\\' )
- {
- *p++ = '/';
- }
+ *name = '/';
name++;
}
#endif
/* Parse a directory and recursively add files */
int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root,
- char *psz_dir )
+ char *psz_dir )
{
intf_sys_t *p_sys = p_intf->p_sys;
char dir[MAX_DIR_SIZE];
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 ) );
+ httpd_file_sys_t *f = NULL;
+ httpd_handler_sys_t *h = NULL;
vlc_bool_t b_index;
- char *psz_tmp;
+ char *psz_tmp, *psz_file, *psz_name, *psz_ext;
- f->p_intf = p_intf;
- f->p_file = NULL;
- f->p_redir = NULL;
- f->p_redir2 = NULL;
psz_tmp = vlc_fix_readdir_charset( p_intf, dir );
- f->file = E_(FromUTF8)( p_intf, psz_tmp );
+ psz_file = E_(FromUTF8)( p_intf, psz_tmp );
free( psz_tmp );
psz_tmp = vlc_fix_readdir_charset( p_intf,
&dir[strlen( psz_root )] );
- f->name = E_(FileToUrl)( psz_tmp, &b_index );
+ psz_name = E_(FileToUrl)( psz_tmp, &b_index );
free( psz_tmp );
+ psz_ext = strrchr( psz_file, '.' );
+ if( psz_ext != NULL )
+ {
+ int i;
+ psz_ext++;
+ for( i = 0; i < p_sys->i_handlers; i++ )
+ if( !strcmp( p_sys->pp_handlers[i]->psz_ext, psz_ext ) )
+ break;
+ if( i < p_sys->i_handlers )
+ {
+ f = malloc( sizeof( httpd_handler_sys_t ) );
+ h = (httpd_handler_sys_t *)f;
+ f->b_handler = VLC_TRUE;
+ h->p_association = p_sys->pp_handlers[i];
+ }
+ }
+ if( f == NULL )
+ {
+ f = malloc( sizeof( httpd_file_sys_t ) );
+ f->b_handler = VLC_FALSE;
+ }
+
+ f->p_intf = p_intf;
+ f->p_file = NULL;
+ f->p_redir = NULL;
+ f->p_redir2 = NULL;
+ f->file = psz_file;
+ f->name = psz_name;
f->b_html = strstr( &dir[strlen( psz_root )], ".htm" ) ? VLC_TRUE : VLC_FALSE;
if( !f->name )
msg_Dbg( p_intf, "file=%s (url=%s)",
f->file, f->name );
- f->p_file = httpd_FileNew( p_sys->p_httpd_host,
- f->name,
- f->b_html ? p_sys->psz_html_type : NULL,
- user, password, p_acl,
- E_(HttpCallback), f );
-
- if( f->p_file )
+ if( !f->b_handler )
+ {
+ f->p_file = httpd_FileNew( p_sys->p_httpd_host,
+ f->name,
+ f->b_html ? p_sys->psz_html_type :
+ NULL,
+ user, password, p_acl,
+ E_(HttpCallback), f );
+ if( f->p_file != NULL )
+ {
+ TAB_APPEND( p_sys->i_files, p_sys->pp_files, f );
+ }
+ }
+ else
{
- TAB_APPEND( p_sys->i_files, p_sys->pp_files, f );
+ h->p_handler = httpd_HandlerNew( p_sys->p_httpd_host,
+ f->name,
+ user, password, p_acl,
+ E_(HandlerCallback), h );
+ if( h->p_handler != NULL )
+ {
+ TAB_APPEND( p_sys->i_files, p_sys->pp_files,
+ (httpd_file_sys_t *)h );
+ }
}
+
/* for url that ends by / add
* - a redirect from rep to rep/
* - in case of index.* rep/index.html to rep/ */
if ( p_sys->iconv_from_utf8 != (vlc_iconv_t)-1 )
{
- char *psz_in = psz_utf8;
- size_t i_in = strlen(psz_in);
+ size_t i_in = strlen(psz_utf8);
size_t i_out = i_in * 2;
char *psz_local = malloc(i_out + 1);
char *psz_out = psz_local;
+ size_t i_ret;
+ char psz_tmp[i_in + 1];
+ char *psz_in = psz_tmp;
+ uint8_t *p = (uint8_t *)psz_tmp;
+ strcpy( psz_tmp, psz_utf8 );
+
+ /* Fix Unicode quotes. If we are here we are probably converting
+ * to an inferior charset not understanding Unicode quotes. */
+ while( *p )
+ {
+ if( p[0] == 0xe2 && p[1] == 0x80 && p[2] == 0x99 )
+ {
+ *p = '\'';
+ memmove( &p[1], &p[3], strlen(&p[3]) + 1 );
+ }
+ if( p[0] == 0xe2 && p[1] == 0x80 && p[2] == 0x9a )
+ {
+ *p = '"';
+ memmove( &p[1], &p[3], strlen(&p[3]) + 1 );
+ }
+ p++;
+ }
+ i_in = strlen( psz_tmp );
- size_t i_ret = vlc_iconv( p_sys->iconv_from_utf8, &psz_in, &i_in,
- &psz_out, &i_out );
+ i_ret = vlc_iconv( p_sys->iconv_from_utf8, &psz_in, &i_in,
+ &psz_out, &i_out );
if( i_ret == (size_t)-1 || i_in )
{
msg_Warn( p_intf,
{
char value[512];
char *psz;
- mvar_t *itm = mvar_New( name, "set" );
+ mvar_t *itm = E_(mvar_New)( name, "set" );
sprintf( value, "%d", ( p_pl->status.p_item == p_node )? 1 : 0 );
- mvar_AppendNewVar( itm, "current", value );
+ E_(mvar_AppendNewVar)( itm, "current", value );
sprintf( value, "%d", p_node->input.i_id );
- mvar_AppendNewVar( itm, "index", value );
+ E_(mvar_AppendNewVar)( itm, "index", value );
psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
- mvar_AppendNewVar( itm, "name", psz );
+ E_(mvar_AppendNewVar)( itm, "name", psz );
free( psz );
psz = E_(FromUTF8)( p_intf, p_node->input.psz_uri );
- mvar_AppendNewVar( itm, "uri", psz );
+ E_(mvar_AppendNewVar)( itm, "uri", psz );
free( psz );
sprintf( value, "Item");
- mvar_AppendNewVar( itm, "type", value );
+ E_(mvar_AppendNewVar)( itm, "type", value );
sprintf( value, "%d", i_depth );
- mvar_AppendNewVar( itm, "depth", value );
+ E_(mvar_AppendNewVar)( itm, "depth", value );
- mvar_AppendVar( s, itm );
+ E_(mvar_AppendVar)( s, itm );
}
else
{
char value[512];
char *psz;
int i_child;
- mvar_t *itm = mvar_New( name, "set" );
+ mvar_t *itm = E_(mvar_New)( name, "set" );
psz = E_(FromUTF8)( p_intf, p_node->input.psz_name );
- mvar_AppendNewVar( itm, "name", psz );
- mvar_AppendNewVar( itm, "uri", psz );
+ E_(mvar_AppendNewVar)( itm, "name", psz );
+ E_(mvar_AppendNewVar)( itm, "uri", psz );
free( psz );
sprintf( value, "Node" );
- mvar_AppendNewVar( itm, "type", value );
+ E_(mvar_AppendNewVar)( itm, "type", value );
sprintf( value, "%d", p_node->input.i_id );
- mvar_AppendNewVar( itm, "index", value );
+ E_(mvar_AppendNewVar)( itm, "index", value );
sprintf( value, "%d", p_node->i_children);
- mvar_AppendNewVar( itm, "i_children", value );
+ E_(mvar_AppendNewVar)( itm, "i_children", value );
sprintf( value, "%d", i_depth );
- mvar_AppendNewVar( itm, "depth", value );
+ E_(mvar_AppendNewVar)( itm, "depth", value );
- mvar_AppendVar( s, itm );
+ E_(mvar_AppendVar)( s, itm );
for (i_child = 0 ; i_child < p_node->i_children ; i_child++)
E_(PlaylistListNode)( p_intf, p_pl,
/****************************************************************************
* Seek command parsing handling
****************************************************************************/
-
-void E_(Seek)( intf_thread_t *p_intf, char *p_value )
+void E_(HandleSeek)( intf_thread_t *p_intf, char *p_value )
{
intf_sys_t *p_sys = p_intf->p_sys;
vlc_value_t val;
/****************************************************************************
* URI Parsing functions
****************************************************************************/
-int E_(uri_test_param)( char *psz_uri, const char *psz_name )
+int E_(TestURIParam)( char *psz_uri, const char *psz_name )
{
char *p = psz_uri;
return VLC_FALSE;
}
-char *E_(uri_extract_value)( char *psz_uri, const char *psz_name,
+char *E_(ExtractURIValue)( char *psz_uri, const char *psz_name,
char *psz_value, int i_value_max )
{
char *p = psz_uri;
return p;
}
-void E_(uri_decode_url_encoded)( char *psz )
+void E_(DecodeEncodedURI)( char *psz )
{
char *dup = strdup( psz );
char *p = dup;
else
return NULL;
}
+/**********************************************************************
+ * Find_end_MRL: Find the end of the sentence :
+ * this function parses the string psz and find the end of the item
+ * and/or option with detecting the " and ' problems.
+ * returns NULL if an error is detected, otherwise, returns a pointer
+ * of the end of the sentence (after the last character)
+**********************************************************************/
+static char *Find_end_MRL( char *psz )
+{
+ char *s_sent = psz;
+
+ switch( *s_sent )
+ {
+ case '\"':
+ {
+ s_sent++;
+
+ while( ( *s_sent != '\"' ) && ( *s_sent != '\0' ) )
+ {
+ if( *s_sent == '\'' )
+ {
+ s_sent = Find_end_MRL( s_sent );
+
+ if( s_sent == NULL )
+ {
+ return NULL;
+ }
+ } else
+ {
+ s_sent++;
+ }
+ }
+
+ if( *s_sent == '\"' )
+ {
+ s_sent++;
+ return s_sent;
+ } else /* *s_sent == '\0' , which means the number of " is incorrect */
+ {
+ return NULL;
+ }
+ break;
+ }
+ case '\'':
+ {
+ s_sent++;
+ while( ( *s_sent != '\'' ) && ( *s_sent != '\0' ) )
+ {
+ if( *s_sent == '\"' )
+ {
+ s_sent = Find_end_MRL( s_sent );
+
+ if( s_sent == NULL )
+ {
+ return NULL;
+ }
+ } else
+ {
+ s_sent++;
+ }
+ }
+
+ if( *s_sent == '\'' )
+ {
+ s_sent++;
+ return s_sent;
+ } else /* *s_sent == '\0' , which means the number of ' is incorrect */
+ {
+ return NULL;
+ }
+ break;
+ }
+ default: /* now we can look for spaces */
+ {
+ while( ( *s_sent != ' ' ) && ( *s_sent != '\0' ) )
+ {
+ if( ( *s_sent == '\'' ) || ( *s_sent == '\"' ) )
+ {
+ s_sent = Find_end_MRL( s_sent );
+ } else
+ {
+ s_sent++;
+ }
+ }
+ return s_sent;
+ }
+ }
+}
/**********************************************************************
* parse_MRL: parse the MRL, find the mrl string and the options,
* create an item with all information in it, and return the item.
* return NULL if there is an error.
**********************************************************************/
-playlist_item_t *E_(parse_MRL)( intf_thread_t *p_intf, char *_psz,
+playlist_item_t *E_(MRLParse)( intf_thread_t *p_intf, char *psz,
char *psz_name )
{
- char *psz = strdup( _psz );
+ char **ppsz_options = NULL;
+ char *mrl;
char *s_mrl = psz;
+ int i_error = 0;
char *s_temp;
+ int i = 0;
+ int i_options = 0;
playlist_item_t * p_item = NULL;
+ /* In case there is spaces before the mrl */
+ while( ( *s_mrl == ' ' ) && ( *s_mrl != '\0' ) )
+ {
+ s_mrl++;
+ }
+
/* extract the mrl */
- s_temp = E_(FirstWord)( s_mrl, s_mrl );
+ s_temp = strstr( s_mrl , " :" );
if( s_temp == NULL )
{
s_temp = s_mrl + strlen( s_mrl );
+ } else
+ {
+ while( (*s_temp == ' ') && (s_temp != s_mrl ) )
+ {
+ s_temp--;
+ }
+ s_temp++;
+ }
+
+ /* if the mrl is between " or ', we must remove them */
+ if( (*s_mrl == '\'') || (*s_mrl == '\"') )
+ {
+ mrl = (char *)malloc( (s_temp - s_mrl - 1) * sizeof( char ) );
+ strncpy( mrl , (s_mrl + 1) , s_temp - s_mrl - 2 );
+ mrl[ s_temp - s_mrl - 2 ] = '\0';
+ } else
+ {
+ mrl = (char *)malloc( (s_temp - s_mrl + 1) * sizeof( char ) );
+ strncpy( mrl , s_mrl , s_temp - s_mrl );
+ mrl[ s_temp - s_mrl ] = '\0';
}
- p_item = playlist_ItemNew( p_intf, s_mrl, psz_name );
s_mrl = s_temp;
/* now we can take care of the options */
- while( *s_mrl != '\0' )
+ while( (*s_mrl != '\0') && (i_error == 0) )
{
- s_temp = E_(FirstWord)( s_mrl, s_mrl );
- if( s_mrl == '\0' )
- break;
- if( s_temp == NULL )
+ switch( *s_mrl )
{
- s_temp = s_mrl + strlen( s_mrl );
+ case ' ':
+ {
+ s_mrl++;
+ break;
+ }
+ case ':': /* an option */
+ {
+ s_temp = Find_end_MRL( s_mrl );
+
+ if( s_temp == NULL )
+ {
+ i_error = 1;
+ }
+ else
+ {
+ i_options++;
+ ppsz_options = realloc( ppsz_options , i_options *
+ sizeof(char *) );
+ ppsz_options[ i_options - 1 ] =
+ malloc( (s_temp - s_mrl + 1) * sizeof(char) );
+
+ strncpy( ppsz_options[ i_options - 1 ] , s_mrl ,
+ s_temp - s_mrl );
+
+ /* don't forget to finish the string with a '\0' */
+ (ppsz_options[ i_options - 1 ])[ s_temp - s_mrl ] = '\0';
+
+ s_mrl = s_temp;
+ }
+ break;
+ }
+ default:
+ {
+ i_error = 1;
+ break;
+ }
+ }
+ }
+
+ if( i_error != 0 )
+ {
+ free( mrl );
+ }
+ else
+ {
+ /* now create an item */
+ p_item = playlist_ItemNew( p_intf, mrl, psz_name );
+ for( i = 0 ; i< i_options ; i++ )
+ {
+ playlist_ItemAddOption( p_item, ppsz_options[i] );
}
- if( *s_mrl != ':' )
- msg_Warn( p_intf, "invalid MRL option: %s", s_mrl );
- else
- playlist_ItemAddOption( p_item, s_mrl );
- s_mrl = s_temp;
}
- free( psz );
+ for( i = 0; i < i_options; i++ ) free( ppsz_options[i] );
+ if( i_options ) free( ppsz_options );
+
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_userdir) );
+ /* This is incomplete : we should also support the ~cmassiot/ syntax. */
+ sprintf( dir, "%s%s", p_intf->p_vlc->psz_userdir, 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, strlen(p) + 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;
+}