X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmisc%2Fupdate.c;h=4660b0b5b0a979ec1b6f823095a18dd7a0d54261;hb=354f70c527ff183d34f0432b3611ef762fbc84b9;hp=7cbaea099e6859398fcbb8137bdb7dd28de6dd49;hpb=85abebf7168aba4fbbfe806567d8a2d55f6ca784;p=vlc diff --git a/src/misc/update.c b/src/misc/update.c index 7cbaea099e..4660b0b5b0 100644 --- a/src/misc/update.c +++ b/src/misc/update.c @@ -46,12 +46,15 @@ #include #include #include -#include +#include #include +#include #include #include - +#ifdef WIN32 +#include +#endif #include "update.h" #include "../libvlc.h" @@ -88,26 +91,18 @@ #endif -/***************************************************************************** - * Local Prototypes - *****************************************************************************/ -static void EmptyRelease( update_t *p_update ); -static bool GetUpdateFile( update_t *p_update ); -static char * size_str( long int l_size ); - - - /***************************************************************************** * Update_t functions *****************************************************************************/ +#undef update_New /** * 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 *update_New( vlc_object_t *p_this ) { update_t *p_update; assert( p_this ); @@ -143,12 +138,12 @@ void update_Delete( update_t *p_update ) if( p_update->p_check ) { - assert( !p_update->p_download ); vlc_object_kill( p_update->p_check ); vlc_thread_join( p_update->p_check ); vlc_object_release( p_update->p_check ); } - else if( p_update->p_download ) + + if( p_update->p_download ) { vlc_object_kill( p_update->p_download ); vlc_thread_join( p_update->p_download ); @@ -195,6 +190,7 @@ static bool GetUpdateFile( update_t *p_update ) int i_revision = 0; unsigned char extra; char *psz_version_line = NULL; + char *psz_update_data = NULL; p_stream = stream_UrlNew( p_update->p_libvlc, UPDATE_VLC_STATUS_URL ); if( !p_stream ) @@ -204,15 +200,34 @@ static bool GetUpdateFile( update_t *p_update ) goto error; } - /* Start reading the status file */ - if( !( psz_version_line = stream_ReadLine( p_stream ) ) ) + const int64_t i_read = stream_Size( p_stream ); + psz_update_data = malloc( i_read + 1 ); /* terminating '\0' */ + if( !psz_update_data ) + goto error; + + if( stream_Read( p_stream, psz_update_data, i_read ) != i_read ) { - msg_Err( p_update->p_libvlc, "Update file %s is corrupted : missing version", - UPDATE_VLC_STATUS_URL ); + msg_Err( p_update->p_libvlc, "Couldn't download update file %s", + UPDATE_VLC_STATUS_URL ); goto error; } + psz_update_data[i_read] = '\0'; + + stream_Delete( p_stream ); + p_stream = NULL; /* first line : version number */ + char *psz_update_data_parser = psz_update_data; + size_t i_len = strcspn( psz_update_data, "\r\n" ); + psz_update_data_parser += i_len; + while( *psz_update_data_parser == '\r' || *psz_update_data_parser == '\n' ) + psz_update_data_parser++; + + if( !(psz_version_line = malloc( i_len + 1)) ) + goto error; + 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 ) ) @@ -230,16 +245,27 @@ static bool GetUpdateFile( update_t *p_update ) } /* second line : URL */ - if( !( p_update->release.psz_url = stream_ReadLine( p_stream ) ) ) + i_len = strcspn( psz_update_data_parser, "\r\n" ); + if( i_len == 0 ) { - msg_Err( p_update->p_libvlc, "Update file %s is corrupted : URL missing", + msg_Err( p_update->p_libvlc, "Update file %s is corrupted: URL missing", UPDATE_VLC_STATUS_URL ); + goto error; } + if( !(p_update->release.psz_url = malloc( i_len + 1)) ) + goto error; + strncpy( p_update->release.psz_url, psz_update_data_parser, i_len ); + p_update->release.psz_url[i_len] = '\0'; + + psz_update_data_parser += i_len; + while( *psz_update_data_parser == '\r' || *psz_update_data_parser == '\n' ) + psz_update_data_parser++; + /* Remaining data : description */ - int i_read = stream_Size( p_stream ) - stream_Tell( p_stream ); - if( i_read <= 0 ) + i_len = strlen( psz_update_data_parser ); + if( i_len == 0 ) { msg_Err( p_update->p_libvlc, "Update file %s is corrupted: description missing", @@ -247,20 +273,10 @@ static bool GetUpdateFile( update_t *p_update ) goto error; } - p_update->release.psz_desc = (char*) malloc( i_read + 1 ); - if( !p_update->release.psz_desc ) + if( !(p_update->release.psz_desc = malloc( i_len + 1)) ) goto error; - - if( stream_Read( p_stream, p_update->release.psz_desc, i_read ) != i_read ) - { - msg_Err( p_update->p_libvlc, "Couldn't download update file %s", - UPDATE_VLC_STATUS_URL ); - goto error; - } - p_update->release.psz_desc[i_read] = '\0'; - - stream_Delete( p_stream ); - p_stream = NULL; + strncpy( p_update->release.psz_desc, psz_update_data_parser, i_len ); + p_update->release.psz_desc[i_len] = '\0'; /* Now that we know the status is valid, we must download its signature * to authenticate it */ @@ -330,16 +346,7 @@ static bool GetUpdateFile( update_t *p_update ) } } - /* FIXME : read the status file all at once instead of line per line */ - char *psz_text; - if( asprintf( &psz_text, "%s\n%s\n%s", psz_version_line, - p_update->release.psz_url, p_update->release.psz_desc ) == -1 ) - { - goto error; - } - FREENULL( psz_version_line ); - - uint8_t *p_hash = hash_sha1_from_text( psz_text, &sign ); + uint8_t *p_hash = hash_sha1_from_text( psz_update_data, &sign ); if( !p_hash ) { msg_Warn( p_update->p_libvlc, "Can't compute SHA1 hash for status file" ); @@ -370,6 +377,7 @@ error: if( p_stream ) stream_Delete( p_stream ); free( psz_version_line ); + free( psz_update_data ); return false; } @@ -451,7 +459,9 @@ bool update_NeedUpgrade( update_t *p_update ) *PACKAGE_VERSION_MAJOR - '0', *PACKAGE_VERSION_MINOR - '0', *PACKAGE_VERSION_REVISION - '0', - *PACKAGE_VERSION_EXTRA + /* 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 }; int latest_version[] = { p_update->release.i_major, @@ -474,11 +484,11 @@ static char *size_str( long int l_size ) char *psz_tmp = NULL; int i_retval = 0; if( l_size >> 30 ) - i_retval = asprintf( &psz_tmp, _("%.1f GB"), (float)l_size/(1<<30) ); + i_retval = asprintf( &psz_tmp, _("%.1f GiB"), (float)l_size/(1<<30) ); else if( l_size >> 20 ) - i_retval = asprintf( &psz_tmp, _("%.1f MB"), (float)l_size/(1<<20) ); + i_retval = asprintf( &psz_tmp, _("%.1f MiB"), (float)l_size/(1<<20) ); else if( l_size >> 10 ) - i_retval = asprintf( &psz_tmp, _("%.1f kB"), (float)l_size/(1<<10) ); + i_retval = asprintf( &psz_tmp, _("%.1f KiB"), (float)l_size/(1<<10) ); else i_retval = asprintf( &psz_tmp, _("%ld B"), l_size ); @@ -568,7 +578,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) if( asprintf( &psz_destfile, "%s%s", psz_destdir, psz_tmpdestfile ) == -1 ) goto end; - p_file = utf8_fopen( psz_destfile, "w" ); + p_file = vlc_fopen( psz_destfile, "w" ); if( !p_file ) { msg_Err( p_udt, "Failed to open %s for writing", psz_destfile ); @@ -611,9 +621,9 @@ static void* update_DownloadReal( vlc_object_t *p_this ) psz_downloaded = size_str( l_downloaded ); f_progress = (float)l_downloaded/(float)l_size; - if( asprintf( &psz_status, _( "%s\nDownloading... %s/%s %.1f%% done" ), + if( asprintf( &psz_status, _( "%s\nDownloading... %s/%s - %.1f%% done" ), p_update->release.psz_url, psz_downloaded, psz_size, - f_progress ) != -1 ) + f_progress*100 ) != -1 ) { dialog_ProgressSet( p_progress, psz_status, f_progress ); free( psz_status ); @@ -638,7 +648,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) } else { - utf8_unlink( psz_destfile ); + vlc_unlink( psz_destfile ); goto end; } @@ -646,7 +656,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) if( download_signature( VLC_OBJECT( p_udt ), &sign, p_update->release.psz_url ) != VLC_SUCCESS ) { - utf8_unlink( psz_destfile ); + vlc_unlink( psz_destfile ); dialog_FatalWait( p_udt, _("File could not be verified"), _("It was not possible to download a cryptographic signature for " @@ -658,7 +668,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) if( memcmp( sign.issuer_longid, p_update->p_pkey->longid, 8 ) ) { - utf8_unlink( psz_destfile ); + vlc_unlink( psz_destfile ); msg_Err( p_udt, "Invalid signature issuer" ); dialog_FatalWait( p_udt, _("Invalid signature"), _("The cryptographic signature for the downloaded file \"%s\" was " @@ -670,7 +680,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) if( sign.type != BINARY_SIGNATURE ) { - utf8_unlink( psz_destfile ); + vlc_unlink( psz_destfile ); msg_Err( p_udt, "Invalid signature type" ); dialog_FatalWait( p_udt, _("Invalid signature"), _("The cryptographic signature for the downloaded file \"%s\" was " @@ -684,7 +694,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) if( !p_hash ) { msg_Err( p_udt, "Unable to hash %s", psz_destfile ); - utf8_unlink( psz_destfile ); + vlc_unlink( psz_destfile ); dialog_FatalWait( p_udt, _("File not verifiable"), _("It was not possible to securely verify the downloaded file" " \"%s\". Thus, it was deleted."), @@ -696,7 +706,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) if( p_hash[0] != sign.hash_verification[0] || p_hash[1] != sign.hash_verification[1] ) { - utf8_unlink( psz_destfile ); + vlc_unlink( psz_destfile ); dialog_FatalWait( p_udt, _("File corrupted"), _("Downloaded file \"%s\" was corrupted. Thus, it was deleted."), psz_destfile ); @@ -708,7 +718,7 @@ static void* update_DownloadReal( vlc_object_t *p_this ) if( verify_signature( sign.r, sign.s, &p_update->p_pkey->key, p_hash ) != VLC_SUCCESS ) { - utf8_unlink( psz_destfile ); + vlc_unlink( psz_destfile ); dialog_FatalWait( p_udt, _("File corrupted"), _("Downloaded file \"%s\" was corrupted. Thus, it was deleted."), psz_destfile ); @@ -720,6 +730,20 @@ static void* update_DownloadReal( vlc_object_t *p_this ) msg_Info( p_udt, "%s authenticated", psz_destfile ); free( p_hash ); +#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); + + if(answer == 1) + { + wchar_t psz_wdestfile[MAX_PATH]; + MultiByteToWideChar( CP_UTF8, 0, psz_destfile, -1, psz_wdestfile, MAX_PATH ); + answer = ShellExecuteW( NULL, L"open", psz_wdestfile, NULL, NULL, SW_SHOW); + if(answer > 32) + libvlc_Quit(p_this->p_libvlc); + } +#endif end: if( p_progress ) dialog_ProgressDestroy( p_progress ); @@ -732,8 +756,6 @@ end: free( p_buffer ); free( psz_size ); - p_udt->p_update->p_download = NULL; - vlc_restorecancel( canc ); return NULL; } @@ -744,7 +766,8 @@ update_release_t *update_GetRelease( update_t *p_update ) } #else -update_t *__update_New( vlc_object_t *p_this ) +#undef update_New +update_t *update_New( vlc_object_t *p_this ) { (void)p_this; return NULL;