📄 util.c
字号:
/***************************************************************************** * util.c : Utility functions for HTTP interface ***************************************************************************** * Copyright (C) 2001-2005 the VideoLAN team * $Id: util.c 18329 2006-12-08 18:07:54Z hartman $ * * Authors: Gildas Bazin <gbazin@netcourrier.com> * Laurent Aimar <fenrir@via.ecp.fr> * Christophe Massiot <massiot@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#include "http.h"#include "vlc_strings.h"/**************************************************************************** * File and directory functions ****************************************************************************//* ToUrl: create a good name for an url from filename */char *E_(FileToUrl)( char *name, vlc_bool_t *pb_index ){ char *url, *p; url = p = malloc( strlen( name ) + 1 ); *pb_index = VLC_FALSE; if( !url || !p ) { return NULL; }#ifdef WIN32 while( *name == '\\' || *name == '/' )#else while( *name == '/' )#endif { name++; } *p++ = '/'; strcpy( p, name );#ifdef WIN32 /* convert '\\' into '/' */ name = p; while( *name ) { if( *name == '\\' ) *name = '/'; name++; }#endif /* index.* -> / */ if( ( p = strrchr( url, '/' ) ) != NULL ) { if( !strncmp( p, "/index.", 7 ) ) { p[1] = '\0'; *pb_index = VLC_TRUE; } } return url;}/* Load a file */int E_(FileLoad)( FILE *f, char **pp_data, int *pi_data ){ int i_read; /* just load the file */ *pi_data = 0; *pp_data = malloc( 1025 ); /* +1 for \0 */ while( ( i_read = fread( &(*pp_data)[*pi_data], 1, 1024, f ) ) == 1024 ) { *pi_data += 1024; *pp_data = realloc( *pp_data, *pi_data + 1025 ); } if( i_read > 0 ) { *pi_data += i_read; } (*pp_data)[*pi_data] = '\0'; return VLC_SUCCESS;}/* Parse a directory and recursively add files */int E_(ParseDirectory)( intf_thread_t *p_intf, char *psz_root, char *psz_dir ){ intf_sys_t *p_sys = p_intf->p_sys; char dir[MAX_DIR_SIZE];#ifdef HAVE_SYS_STAT_H struct stat stat_info;#endif DIR *p_dir; vlc_acl_t *p_acl; FILE *file; char *user = NULL; char *password = NULL; int i_dirlen; char sep;#if defined( WIN32 ) sep = '\\';#else sep = '/';#endif#ifdef HAVE_SYS_STAT_H if( utf8_stat( psz_dir, &stat_info ) == -1 || !S_ISDIR( stat_info.st_mode ) ) { return VLC_EGENERIC; }#endif if( ( p_dir = utf8_opendir( psz_dir ) ) == NULL ) { msg_Err( p_intf, "cannot open directory (%s)", psz_dir ); return VLC_EGENERIC; } i_dirlen = strlen( psz_dir ); if( i_dirlen + 10 > MAX_DIR_SIZE ) { msg_Warn( p_intf, "skipping too deep directory (%s)", psz_dir ); return 0; } msg_Dbg( p_intf, "dir=%s", psz_dir ); sprintf( dir, "%s%c.access", psz_dir, sep ); if( ( file = utf8_fopen( dir, "r" ) ) != NULL ) { char line[1024]; int i_size; msg_Dbg( p_intf, "find .access in dir=%s", psz_dir ); i_size = fread( line, 1, 1023, file ); if( i_size > 0 ) { char *p; while( i_size > 0 && ( line[i_size-1] == '\n' || line[i_size-1] == '\r' ) ) { i_size--; } line[i_size] = '\0'; p = strchr( line, ':' ); if( p ) { *p++ = '\0'; user = strdup( line ); password = strdup( p ); } } msg_Dbg( p_intf, "using user=%s password=%s (read=%d)", user, password, i_size ); fclose( file ); } sprintf( dir, "%s%c.hosts", psz_dir, sep ); p_acl = ACL_Create( p_intf, VLC_FALSE ); if( ACL_LoadFile( p_acl, dir ) ) { ACL_Destroy( p_acl ); p_acl = NULL; } for( ;; ) { const char *psz_filename; /* parse psz_src dir */ if( ( psz_filename = utf8_readdir( p_dir ) ) == NULL ) { break; } if( ( psz_filename[0] == '.' ) || ( i_dirlen + strlen( psz_filename ) > MAX_DIR_SIZE ) ) continue; sprintf( dir, "%s%c%s", psz_dir, sep, psz_filename ); LocaleFree( psz_filename ); if( E_(ParseDirectory)( p_intf, psz_root, dir ) ) { httpd_file_sys_t *f = NULL; httpd_handler_sys_t *h = NULL; vlc_bool_t b_index; char *psz_tmp, *psz_file, *psz_name, *psz_ext; psz_tmp = vlc_fix_readdir_charset( p_intf, dir ); psz_file = E_(FromUTF8)( p_intf, psz_tmp ); free( psz_tmp ); psz_tmp = vlc_fix_readdir_charset( p_intf, &dir[strlen( psz_root )] ); 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" ) || strstr( &dir[strlen( psz_root )], ".xml" ) ? VLC_TRUE : VLC_FALSE; if( !f->name ) { msg_Err( p_intf , "unable to parse directory" ); vlc_closedir_wrapper( p_dir ); free( f ); return( VLC_ENOMEM ); } msg_Dbg( p_intf, "file=%s (url=%s)", f->file, f->name ); if( !f->b_handler ) { char *psz_type = strdup( p_sys->psz_html_type ); if( strstr( &dir[strlen( psz_root )], ".xml" ) ) { char *psz = strstr( psz_type, "html;" ); if( psz ) { psz[0] = 'x'; psz[1] = 'm'; psz[2] = 'l'; psz[3] = ';'; psz[4] = ' '; } } f->p_file = httpd_FileNew( p_sys->p_httpd_host, f->name, f->b_html ? psz_type : NULL, user, password, p_acl, E_(HttpCallback), f ); free( psz_type ); if( f->p_file != NULL ) { TAB_APPEND( p_sys->i_files, p_sys->pp_files, f ); } } else { 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( f && f->name[strlen(f->name) - 1] == '/' ) { char *psz_redir = strdup( f->name ); char *p; psz_redir[strlen( psz_redir ) - 1] = '\0'; msg_Dbg( p_intf, "redir=%s -> %s", psz_redir, f->name ); f->p_redir = httpd_RedirectNew( p_sys->p_httpd_host, f->name, psz_redir ); free( psz_redir ); if( b_index && ( p = strstr( f->file, "index." ) ) ) { asprintf( &psz_redir, "%s%s", f->name, p ); msg_Dbg( p_intf, "redir=%s -> %s", psz_redir, f->name ); f->p_redir2 = httpd_RedirectNew( p_sys->p_httpd_host, f->name, psz_redir ); free( psz_redir ); } } } } if( user ) { free( user ); } if( password ) { free( password ); } ACL_Destroy( p_acl ); vlc_closedir_wrapper( p_dir ); return VLC_SUCCESS;}/************************************************************************** * Locale functions **************************************************************************/char *E_(FromUTF8)( intf_thread_t *p_intf, char *psz_utf8 ){ intf_sys_t *p_sys = p_intf->p_sys; if ( p_sys->iconv_from_utf8 != (vlc_iconv_t)-1 ) { 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]; const char *psz_in = psz_tmp; strcpy( psz_tmp, psz_utf8 ); i_in = strlen( psz_tmp ); 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, "failed to convert \"%s\" to desired charset (%s)", psz_utf8, strerror(errno) ); free( psz_local ); return strdup( psz_utf8 ); } *psz_out = '\0'; return psz_local; } else return strdup( psz_utf8 );}char *E_(ToUTF8)( intf_thread_t *p_intf, char *psz_local ){ intf_sys_t *p_sys = p_intf->p_sys; if ( p_sys->iconv_to_utf8 != (vlc_iconv_t)-1 ) { const char *psz_in = psz_local; size_t i_in = strlen(psz_in); size_t i_out = i_in * 6; char *psz_utf8 = malloc(i_out + 1); char *psz_out = psz_utf8; size_t i_ret = vlc_iconv( p_sys->iconv_to_utf8, &psz_in, &i_in, &psz_out, &i_out ); if( i_ret == (size_t)-1 || i_in ) { msg_Warn( p_intf, "failed to convert \"%s\" to desired charset (%s)", psz_local, strerror(errno) ); free( psz_utf8 ); return strdup( psz_local ); } *psz_out = '\0'; return psz_utf8; } else return strdup( psz_local );}/************************************************************************* * Playlist stuff *************************************************************************/void E_(PlaylistListNode)( intf_thread_t *p_intf, playlist_t *p_pl, playlist_item_t *p_node, char *name, mvar_t *s, int i_depth ){ if( p_node != NULL ) { if( p_node->i_children == -1 ) { char value[512]; char *psz; mvar_t *itm = E_(mvar_New)( name, "set" ); sprintf( value, "%d", ( p_pl->status.p_item == p_node )? 1 : 0 ); E_(mvar_AppendNewVar)( itm, "current", value ); sprintf( value, "%d", p_node->input.i_id ); E_(mvar_AppendNewVar)( itm, "index", value ); psz = E_(FromUTF8)( p_intf, p_node->input.psz_name ); E_(mvar_AppendNewVar)( itm, "name", psz ); free( psz ); psz = E_(FromUTF8)( p_intf, p_node->input.psz_uri ); E_(mvar_AppendNewVar)( itm, "uri", psz ); free( psz ); sprintf( value, "Item"); E_(mvar_AppendNewVar)( itm, "type", value ); sprintf( value, "%d", i_depth ); E_(mvar_AppendNewVar)( itm, "depth", value ); if( p_node->i_flags & PLAYLIST_RO_FLAG ) { E_(mvar_AppendNewVar)( itm, "ro", "ro" ); } else { E_(mvar_AppendNewVar)( itm, "ro", "rw" ); } sprintf( value, "%ld", (long)p_node->input.i_duration ); E_(mvar_AppendNewVar)( itm, "duration", value ); E_(mvar_AppendVar)( s, itm ); } else { char value[512]; char *psz; int i_child; mvar_t *itm = E_(mvar_New)( name, "set" ); psz = E_(FromUTF8)( p_intf, p_node->input.psz_name ); E_(mvar_AppendNewVar)( itm, "name", psz ); E_(mvar_AppendNewVar)( itm, "uri", psz ); free( psz ); sprintf( value, "Node" ); E_(mvar_AppendNewVar)( itm, "type", value ); sprintf( value, "%d", p_node->input.i_id ); E_(mvar_AppendNewVar)( itm, "index", value ); sprintf( value, "%d", p_node->i_children); E_(mvar_AppendNewVar)( itm, "i_children", value ); sprintf( value, "%d", i_depth ); E_(mvar_AppendNewVar)( itm, "depth", value ); if( p_node->i_flags & PLAYLIST_RO_FLAG ) { E_(mvar_AppendNewVar)( itm, "ro", "ro" ); } else { E_(mvar_AppendNewVar)( itm, "ro", "rw" ); } E_(mvar_AppendVar)( s, itm );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -