X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fupdate.c;h=b00eb27bbf79dc78e922472aa6812e329659c9d7;hb=39827e4a5e846bf58a247b22e29cf7b8bbe9c6bc;hp=8e15307c477e9815c10540b1005ae0469aa4ab7f;hpb=d8ab9e3dced5f88df87f264abaac1287f6cf3c84;p=vlc diff --git a/src/misc/update.c b/src/misc/update.c index 8e15307c47..b00eb27bbf 100644 --- a/src/misc/update.c +++ b/src/misc/update.c @@ -1,26 +1,26 @@ /***************************************************************************** * update.c: VLC update checking and downloading ***************************************************************************** - * Copyright © 2005-2008 the VideoLAN team + * Copyright © 2005-2008 VLC authors and VideoLAN * $Id$ * * Authors: Antoine Cellerier * Rémi Duraffort Rafaël Carré * - * 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 + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser 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. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser 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. + * You should have received a copy of the GNU Lesser 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. *****************************************************************************/ /** @@ -52,7 +52,7 @@ #include #include -#ifdef WIN32 +#ifdef _WIN32 #include #endif #include "update.h" @@ -64,28 +64,29 @@ /* * Here is the format of these "status files" : - * First line is the last version: "X.Y.Ze" where: + * First line is the last version: "X.Y.Z.E" where: * * X is the major number * * Y is the minor number * * Z is the revision number - * * e is an OPTIONAL extra letter - * * AKA "0.8.6d" or "0.9.0" + * * .E is an OPTIONAL extra number + * * IE "1.2.0" or "1.1.10.1" * Second line is a url of the binary for this last version * Remaining text is a required description of the update */ -#if defined( UNDER_CE ) -# define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-ce" -#elif defined( WIN32 ) -# ifndef NDEBUG -# define UPDATE_VLC_STATUS_URL "http://update-test.videolan.org/vlc/status-win-x86" -# else -# define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-win-x86" -# endif +#if defined( _WIN64 ) +# define UPDATE_OS_SUFFIX "-win-x64" +#elif defined( _WIN32 ) +# define UPDATE_OS_SUFFIX "-win-x86" #else -# define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status" +# define UPDATE_OS_SUFFIX "" #endif +#ifndef NDEBUG +# define UPDATE_VLC_STATUS_URL "http://update-test.videolan.org/vlc/status-win-x86" +#else +# define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status" UPDATE_OS_SUFFIX +#endif /***************************************************************************** * Update_t functions @@ -140,7 +141,7 @@ void update_Delete( update_t *p_update ) if( p_update->p_download ) { - vlc_object_kill( p_update->p_download ); + atomic_store( &p_update->p_download->aborted, true ); vlc_join( p_update->p_download->thread, NULL ); vlc_object_release( p_update->p_download ); } @@ -180,10 +181,6 @@ static void EmptyRelease( update_t *p_update ) static bool GetUpdateFile( update_t *p_update ) { stream_t *p_stream = NULL; - int i_major = 0; - int i_minor = 0; - int i_revision = 0; - unsigned char extra; char *psz_version_line = NULL; char *psz_update_data = NULL; @@ -223,18 +220,12 @@ static bool GetUpdateFile( update_t *p_update ) strncpy( psz_version_line, psz_update_data, i_len ); psz_version_line[i_len] = '\0'; - p_update->release.extra = 0; - switch( sscanf( psz_version_line, "%i.%i.%i%c", - &i_major, &i_minor, &i_revision, &extra ) ) + p_update->release.i_extra = 0; + int ret = sscanf( psz_version_line, "%i.%i.%i.%i", + &p_update->release.i_major, &p_update->release.i_minor, + &p_update->release.i_revision, &p_update->release.i_extra); + if( ret != 3 && ret != 4 ) { - case 4: - p_update->release.extra = extra; - case 3: - p_update->release.i_major = i_major; - p_update->release.i_minor = i_minor; - p_update->release.i_revision = i_revision; - break; - default: msg_Err( p_update->p_libvlc, "Update version false formated" ); goto error; } @@ -316,7 +307,7 @@ static bool GetUpdateFile( update_t *p_update ) goto error; } - uint8_t *p_hash = hash_sha1_from_public_key( p_new_pkey ); + uint8_t *p_hash = hash_from_public_key( p_new_pkey ); if( !p_hash ) { msg_Err( p_update->p_libvlc, "Failed to hash signature" ); @@ -325,7 +316,7 @@ static bool GetUpdateFile( update_t *p_update ) goto error; } - if( verify_signature( p_new_pkey->sig.r, p_new_pkey->sig.s, + if( verify_signature( &p_new_pkey->sig, &p_update->p_pkey->key, p_hash ) == VLC_SUCCESS ) { free( p_hash ); @@ -341,30 +332,35 @@ static bool GetUpdateFile( update_t *p_update ) } } - uint8_t *p_hash = hash_sha1_from_text( psz_update_data, &sign ); + uint8_t *p_hash = hash_from_text( psz_update_data, &sign ); if( !p_hash ) { - msg_Warn( p_update->p_libvlc, "Can't compute SHA1 hash for status file" ); + msg_Warn( p_update->p_libvlc, "Can't compute hash for status file" ); goto error; } else if( p_hash[0] != sign.hash_verification[0] || p_hash[1] != sign.hash_verification[1] ) { - msg_Warn( p_update->p_libvlc, "Bad SHA1 hash for status file" ); + msg_Warn( p_update->p_libvlc, "Bad hash for status file" ); + free( p_hash ); goto error; } - else if( verify_signature( sign.r, sign.s, &p_update->p_pkey->key, p_hash ) + else if( verify_signature( &sign, &p_update->p_pkey->key, p_hash ) != VLC_SUCCESS ) { msg_Err( p_update->p_libvlc, "BAD SIGNATURE for status file" ); + free( p_hash ); goto error; } else { msg_Info( p_update->p_libvlc, "Status file authenticated" ); + free( p_hash ); + free( psz_version_line ); + free( psz_update_data ); return true; } @@ -428,40 +424,39 @@ void* update_CheckReal( void *obj ) return NULL; } -/** - * Compare a given release's version number to the current VLC's one - * - * \param p_update structure - * \return true if we have to upgrade to the given version to be up to date - */ -static bool is_strictly_greater( int * a, int * b, int n) -{ - if( n <= 0 ) return false; - if(a[0] > b[0] ) return true; - if(a[0] == b[0] ) return is_strictly_greater( a+1, b+1, n-1 ); - /* a[0] < b[0] */ return false; -} - bool update_NeedUpgrade( update_t *p_update ) { assert( p_update ); - int current_version[] = { - *PACKAGE_VERSION_MAJOR - '0', - *PACKAGE_VERSION_MINOR - '0', - *PACKAGE_VERSION_REVISION - '0', - /* extra string of development versions is "-git", "-rc" .. - * so make sure version a.b.c is newer than a.b.c-XXX */ - (*PACKAGE_VERSION_EXTRA == '-') ? -1 : *PACKAGE_VERSION_EXTRA + static const int current[4] = { + PACKAGE_VERSION_MAJOR, + PACKAGE_VERSION_MINOR, + PACKAGE_VERSION_REVISION, + PACKAGE_VERSION_EXTRA }; - int latest_version[] = { + const int latest[4] = { p_update->release.i_major, p_update->release.i_minor, p_update->release.i_revision, - p_update->release.extra + p_update->release.i_extra }; - return is_strictly_greater( latest_version, current_version, 4 ); + for (unsigned i = 0; i < sizeof latest / sizeof *latest; i++) { + /* there is a new version available */ + if (latest[i] > current[i]) + return true; + + /* current version is more recent than the latest version ?! */ + if (latest[i] < current[i]) + return false; + } + + /* current version is not a release, it's a -git or -rc version */ + if (*PACKAGE_VERSION_DEV) + return true; + + /* current version is latest version */ + return false; } /** @@ -502,7 +497,7 @@ void update_Download( update_t *p_update, const char *psz_destdir ) // If the object already exist, destroy it if( p_update->p_download ) { - vlc_object_kill( p_update->p_download ); + atomic_store( &p_update->p_download->aborted, true ); vlc_join( p_update->p_download->thread, NULL ); vlc_object_release( p_update->p_download ); } @@ -517,6 +512,7 @@ void update_Download( update_t *p_update, const char *psz_destdir ) p_update->p_download = p_udt; p_udt->psz_destdir = psz_destdir ? strdup( psz_destdir ) : NULL; + atomic_store(&p_udt->aborted, false); vlc_clone( &p_udt->thread, update_DownloadReal, p_udt, VLC_THREAD_PRIORITY_LOW ); } @@ -580,24 +576,24 @@ static void* update_DownloadReal( void *obj ) /* Create a buffer and fill it with the downloaded file */ p_buffer = (void *)malloc( 1 << 10 ); - if( !p_buffer ) - { - msg_Err( p_udt, "Can't malloc (1 << 10) bytes! download cancelled." ); + if( unlikely(p_buffer == NULL) ) goto end; - } msg_Dbg( p_udt, "Downloading Stream '%s'", p_update->release.psz_url ); psz_size = size_str( l_size ); if( asprintf( &psz_status, _("%s\nDownloading... %s/%s %.1f%% done"), - p_update->release.psz_url, "0.0", psz_size, 0.0 ) != -1 ) - { - p_progress = dialog_ProgressCreate( p_udt, _( "Downloading ..."), - psz_status, _("Cancel") ); - free( psz_status ); - } + p_update->release.psz_url, "0.0", psz_size, 0.0 ) == -1 ) + goto end; + + p_progress = dialog_ProgressCreate( p_udt, _( "Downloading ..."), + psz_status, _("Cancel") ); + + free( psz_status ); + if( p_progress == NULL ) + goto end; - while( vlc_object_alive( p_udt ) && + while( !atomic_load( &p_udt->aborted ) && ( i_read = stream_Read( p_stream, p_buffer, 1 << 10 ) ) && !dialog_ProgressCancelled( p_progress ) ) { @@ -625,7 +621,7 @@ static void* update_DownloadReal( void *obj ) fclose( p_file ); p_file = NULL; - if( vlc_object_alive( p_udt ) && + if( !atomic_load( &p_udt->aborted ) && !dialog_ProgressCancelled( p_progress ) ) { dialog_ProgressDestroy( p_progress ); @@ -675,7 +671,7 @@ static void* update_DownloadReal( void *obj ) goto end; } - uint8_t *p_hash = hash_sha1_from_file( psz_destfile, &sign ); + uint8_t *p_hash = hash_from_file( psz_destfile, &sign ); if( !p_hash ) { msg_Err( p_udt, "Unable to hash %s", psz_destfile ); @@ -695,12 +691,12 @@ static void* update_DownloadReal( void *obj ) dialog_FatalWait( p_udt, _("File corrupted"), _("Downloaded file \"%s\" was corrupted. Thus, it was deleted."), psz_destfile ); - msg_Err( p_udt, "Bad SHA1 hash for %s", psz_destfile ); + msg_Err( p_udt, "Bad hash for %s", psz_destfile ); free( p_hash ); goto end; } - if( verify_signature( sign.r, sign.s, &p_update->p_pkey->key, p_hash ) + if( verify_signature( &sign, &p_update->p_pkey->key, p_hash ) != VLC_SUCCESS ) { vlc_unlink( psz_destfile ); @@ -715,7 +711,7 @@ static void* update_DownloadReal( void *obj ) msg_Info( p_udt, "%s authenticated", psz_destfile ); free( p_hash ); -#ifdef WIN32 +#ifdef _WIN32 int answer = dialog_Question( p_udt, _("Update VLC media player"), _("The new version was successfully downloaded. Do you want to close VLC and install it now?"), _("Install"), _("Cancel"), NULL);