📄 update.c
字号:
/***************************************************************************** * update.c: VLC update and plugins download ***************************************************************************** * Copyright (C) 2005 the VideoLAN team * $Id: $ * * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org> * * 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 release 2 of the License, or * (at your option) any later release. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************//* TODO * --> check release types. * --> make sure that the version comparision method is ok. *//** * \file * This file contains functions related to VLC and plugins update management *//***************************************************************************** * Preamble *****************************************************************************/#include <stdlib.h> /* malloc(), free() */#include <ctype.h> /* tolower() */#include <vlc/vlc.h>#include "vlc_update.h"#include "vlc_block.h"#include "vlc_stream.h"#include "vlc_xml.h"#include "vlc_interaction.h"#include "charset.h"/***************************************************************************** * Misc defines *****************************************************************************//* All release notes and source packages should match on "*" * Only binary installers are OS specific ( we only provide these * for Win32, Mac OS X, WincCE, beos(?) ) */#if defined( UNDER_CE )# define UPDATE_VLC_OS "*"# define UPDATE_VLC_ARCH "*"#elif defined( WIN32 )# define UPDATE_VLC_OS "windows"# define UPDATE_VLC_ARCH "i386"#elif defined( __APPLE__ )# define UPDATE_VLC_OS "macosx"# if defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )# define UPDATE_VLC_ARCH "ppc"# else# define UPDATE_VLC_ARCH "x86"# endif#elif defined( SYS_BEOS )# define UPDATE_VLC_OS "beos"# define UPDATE_VLC_ARCH "i386"#else# define UPDATE_VLC_OS "*"# define UPDATE_VLC_ARCH "*"#endif#define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status.xml"#define UPDATE_VLC_MIRRORS_URL "http://update.videolan.org/mirrors.xml"#define FREE( a ) free(a);a=NULL;#define STRDUP( a ) ( a ? strdup( a ) : NULL )/***************************************************************************** * Local Prototypes *****************************************************************************/void FreeMirrorsList( update_t * );void FreeReleasesList( update_t * );void GetMirrorsList( update_t *, vlc_bool_t );void GetFilesList( update_t *, vlc_bool_t );int CompareReleases( struct update_release_t *, struct update_release_t * );int CompareReleaseToCurrent( struct update_release_t * );unsigned int update_iterator_Reset( update_iterator_t * );unsigned int update_iterator_NextFile( update_iterator_t * );unsigned int update_iterator_PrevFile( update_iterator_t * );unsigned int update_iterator_NextMirror( update_iterator_t * );unsigned int update_iterator_PrevMirror( update_iterator_t * );void update_iterator_GetData( update_iterator_t * );void update_iterator_ClearData( update_iterator_t * );/***************************************************************************** * Update_t functions *****************************************************************************//** * Create a new update VLC struct * * \param p_this the calling vlc_object * \return pointer to new update_t or NULL */update_t *__update_New( vlc_object_t *p_this ){ update_t *p_update; if( p_this == NULL ) return NULL; p_update = (update_t *)malloc( sizeof( update_t ) ); vlc_mutex_init( p_this, &p_update->lock ); p_update->p_vlc = p_this->p_vlc; p_update->p_releases = NULL; p_update->i_releases = 0; p_update->b_releases = VLC_FALSE; p_update->p_mirrors = NULL; p_update->i_mirrors = 0; p_update->b_mirrors = VLC_FALSE; return p_update;}/** * Delete an update_t struct * * \param p_update update_t* pointer * \return nothing */void update_Delete( update_t *p_update ){ vlc_mutex_destroy( &p_update->lock ); FreeMirrorsList( p_update ); FreeReleasesList( p_update ); free( p_update );}/** * Empty the mirrors list * *p_update should be locked before using this function * * \param p_update pointer to the update struct * \return nothing */void FreeMirrorsList( update_t *p_update ){ int i; for( i = 0; i < p_update->i_mirrors; i++ ) { free( p_update->p_mirrors[i].psz_name ); free( p_update->p_mirrors[i].psz_location ); free( p_update->p_mirrors[i].psz_type ); free( p_update->p_mirrors[i].psz_base_url ); } FREE( p_update->p_mirrors ); p_update->i_mirrors = 0; p_update->b_mirrors = VLC_FALSE;}/** * Empty the releases list * *p_update should be locked before calling this function * * \param p_update pointer to the update struct * \return nothing */void FreeReleasesList( update_t *p_update ){ int i; for( i = 0; i < p_update->i_releases; i++ ) { int j; struct update_release_t *p_release = (p_update->p_releases + i); for( j = 0; j < p_release->i_files; j++ ) { free( p_release->p_files[j].psz_md5 ); free( p_release->p_files[j].psz_url ); free( p_release->p_files[j].psz_description ); } free( p_release->psz_major ); free( p_release->psz_minor ); free( p_release->psz_revision ); free( p_release->psz_extra ); free( p_release->psz_svn_revision ); free( p_release->p_files ); } FREE( p_update->p_releases ); p_update->i_releases = 0; p_update->b_releases = VLC_FALSE;}/** * Get the mirrors list XML file and parse it * *p_update has to be unlocked when calling this function * * \param p_update pointer to the update struct * \param b_force set to VLC_TRUE if you want to force the mirrors list update * \return nothing */void GetMirrorsList( update_t *p_update, vlc_bool_t b_force ){ stream_t *p_stream = NULL; xml_t *p_xml = NULL; xml_reader_t *p_xml_reader = NULL; char *psz_eltname = NULL; //char *psz_eltvalue = NULL; char *psz_name = NULL; char *psz_value = NULL; struct update_mirror_t tmp_mirror = {0}; vlc_mutex_lock( &p_update->lock ); if( p_update->b_mirrors && b_force == VLC_FALSE ) { vlc_mutex_unlock( &p_update->lock ); return; } p_xml = xml_Create( p_update->p_vlc ); if( !p_xml ) { msg_Err( p_update->p_vlc, "Failed to open XML parser" ); goto error; } p_stream = stream_UrlNew( p_update->p_vlc, UPDATE_VLC_MIRRORS_URL ); if( !p_stream ) { msg_Err( p_update->p_vlc, "Failed to open %s for reading", UPDATE_VLC_MIRRORS_URL ); goto error; } p_xml_reader = xml_ReaderCreate( p_xml, p_stream ); if( !p_xml_reader ) { msg_Err( p_update->p_vlc, "Failed to open %s for parsing", UPDATE_VLC_MIRRORS_URL ); goto error; } if( p_update->p_mirrors ) { FreeMirrorsList( p_update ); } while( xml_ReaderRead( p_xml_reader ) == 1 ) { switch( xml_ReaderNodeType( p_xml_reader ) ) { case -1: msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_MIRRORS_URL ); goto error; case XML_READER_STARTELEM: psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) { msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_MIRRORS_URL ); goto error; } while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { psz_name = xml_ReaderName( p_xml_reader ); psz_value = xml_ReaderValue( p_xml_reader ); if( !psz_name || !psz_value ) { msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_MIRRORS_URL ); goto error; } if( !strcmp( psz_eltname, "mirror" ) ) { if( !strcmp( psz_name, "name" ) ) tmp_mirror.psz_name = STRDUP( psz_value ); else if( !strcmp( psz_name, "location" ) ) tmp_mirror.psz_location = STRDUP( psz_value ); } else if( !strcmp( psz_eltname, "url" ) ) { if( !strcmp( psz_name, "type" ) ) tmp_mirror.psz_type = STRDUP( psz_value ); else if( !strcmp( psz_name, "base" ) ) tmp_mirror.psz_base_url = STRDUP( psz_value ); } FREE( psz_name ); FREE( psz_value ); } if( !strcmp( psz_eltname, "url" ) ) { /* append to mirrors list */ p_update->p_mirrors = (struct update_mirror_t *)realloc( p_update->p_mirrors, (++(p_update->i_mirrors)) *sizeof( struct update_mirror_t ) ); p_update->p_mirrors[ p_update->i_mirrors - 1 ] = tmp_mirror; tmp_mirror.psz_name = STRDUP( tmp_mirror.psz_name ); tmp_mirror.psz_location = STRDUP( tmp_mirror.psz_location ); tmp_mirror.psz_type = NULL; tmp_mirror.psz_base_url = NULL; } FREE( psz_eltname ); break; case XML_READER_ENDELEM: psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) { msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_MIRRORS_URL ); goto error; } if( !strcmp( psz_eltname, "mirror" ) ) { FREE( tmp_mirror.psz_name ); FREE( tmp_mirror.psz_location ); } FREE( psz_eltname ); break; /*case XML_READER_TEXT: psz_eltvalue = xml_ReaderValue( p_xml_reader ); FREE( psz_eltvalue ); break;*/ } } p_update->b_mirrors = VLC_TRUE; error: vlc_mutex_unlock( &p_update->lock ); free( psz_eltname ); //free( psz_eltvalue ); free( psz_name ); free( psz_value ); free( tmp_mirror.psz_name ); free( tmp_mirror.psz_location ); free( tmp_mirror.psz_type ); free( tmp_mirror.psz_base_url ); if( p_xml_reader && p_xml ) xml_ReaderDelete( p_xml, p_xml_reader ); if( p_stream ) stream_Delete( p_stream ); if( p_xml ) xml_Delete( p_xml );}/** * Get the files list XML file and parse it * *p_update has to be unlocked when calling this function * * \param p_update pointer to update struct * \param b_force set to VLC_TRUE if you want to force the files list update * \return nothing */void GetFilesList( update_t *p_update, vlc_bool_t b_force ){ stream_t *p_stream = NULL; xml_t *p_xml = NULL; xml_reader_t *p_xml_reader = NULL; char *psz_eltname = NULL; char *psz_eltvalue = NULL; char *psz_name = NULL; char *psz_value = NULL; struct update_release_t *p_release = NULL; struct update_release_t tmp_release = {0}; struct update_file_t tmp_file = {0}; vlc_bool_t b_os = VLC_FALSE, b_arch = VLC_FALSE; tmp_release.i_type = UPDATE_RELEASE_TYPE_STABLE; vlc_mutex_lock( &p_update->lock ); if( p_update->b_releases && b_force == VLC_FALSE ) { vlc_mutex_unlock( &p_update->lock ); return; } p_xml = xml_Create( p_update->p_vlc ); if( !p_xml ) { msg_Err( p_update->p_vlc, "Failed to open XML parser" ); goto error; } p_stream = stream_UrlNew( p_update->p_vlc, UPDATE_VLC_STATUS_URL ); if( !p_stream ) { msg_Err( p_update->p_vlc, "Failed to open %s for reading", UPDATE_VLC_STATUS_URL ); goto error; } p_xml_reader = xml_ReaderCreate( p_xml, p_stream ); if( !p_xml_reader ) { msg_Err( p_update->p_vlc, "Failed to open %s for parsing", UPDATE_VLC_STATUS_URL ); goto error; } if( p_update->p_releases ) { FreeReleasesList( p_update ); } while( xml_ReaderRead( p_xml_reader ) == 1 ) { switch( xml_ReaderNodeType( p_xml_reader ) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -