]> git.sesse.net Git - vlc/blobdiff - src/misc/update.c
use backtrace with vlc_object_get warning
[vlc] / src / misc / update.c
index 1b7e54cbe4f1234e17b5cc71647d94a526e1f500..7e7913a0b24d2c328a464b07f1be13fdb68e3216 100644 (file)
@@ -53,6 +53,7 @@
 #include <vlc_gcrypt.h>
 
 #include "update.h"
+#include "../libvlc.h"
 
 /*****************************************************************************
  * Misc defines
@@ -1049,6 +1050,9 @@ update_t *__update_New( vlc_object_t *p_this )
     p_update->release.psz_url = NULL;
     p_update->release.psz_desc = NULL;
 
+    p_update->p_download = NULL;
+    p_update->p_check = NULL;
+
     p_update->p_pkey = NULL;
     vlc_gcrypt_init();
 
@@ -1065,6 +1069,20 @@ void update_Delete( update_t *p_update )
 {
     assert( 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 )
+    {
+        vlc_object_kill( p_update->p_download );
+        vlc_thread_join( p_update->p_download );
+        vlc_object_release( p_update->p_download );
+    }
+
     vlc_mutex_destroy( &p_update->lock );
 
     free( p_update->release.psz_url );
@@ -1336,19 +1354,7 @@ error:
     return false;
 }
 
-
-/**
- * Struct to launch the check in an other thread
- */
-typedef struct
-{
-    VLC_COMMON_MEMBERS
-    update_t *p_update;
-    void (*pf_callback)( void *, bool );
-    void *p_data;
-} update_check_thread_t;
-
-void update_CheckReal( update_check_thread_t *p_uct );
+static void* update_CheckReal( vlc_object_t *p_this );
 
 /**
  * Check for updates
@@ -1362,11 +1368,13 @@ void update_Check( update_t *p_update, void (*pf_callback)( void*, bool ), void
 {
     assert( p_update );
 
-    update_check_thread_t *p_uct = vlc_object_create( p_update->p_libvlc,
-                                            sizeof( update_check_thread_t ) );
+    update_check_thread_t *p_uct =
+        vlc_custom_create( p_update->p_libvlc, sizeof( *p_uct ),
+                           VLC_OBJECT_GENERIC, "update check" );
     if( !p_uct ) return;
 
     p_uct->p_update = p_update;
+    p_update->p_check = p_uct;
     p_uct->pf_callback = pf_callback;
     p_uct->p_data = p_data;
 
@@ -1374,9 +1382,13 @@ void update_Check( update_t *p_update, void (*pf_callback)( void*, bool ), void
                        VLC_THREAD_PRIORITY_LOW, false );
 }
 
-void update_CheckReal( update_check_thread_t *p_uct )
+void* update_CheckReal( vlc_object_t* p_this )
 {
+    update_check_thread_t *p_uct = (update_check_thread_t *)p_this;
     bool b_ret;
+    int canc;
+
+    canc = vlc_savecancel ();
     vlc_mutex_lock( &p_uct->p_update->lock );
 
     EmptyRelease( p_uct->p_update );
@@ -1385,6 +1397,9 @@ void update_CheckReal( update_check_thread_t *p_uct )
 
     if( p_uct->pf_callback )
         (p_uct->pf_callback)( p_uct->p_data, b_ret );
+
+    vlc_restorecancel (canc);
+    return NULL;
 }
 
 /**
@@ -1393,14 +1408,32 @@ void update_CheckReal( update_check_thread_t *p_uct )
  * \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 );
 
-    return  p_update->release.i_major    < *PACKAGE_VERSION_MAJOR    - '0'  ||
-            p_update->release.i_minor    < *PACKAGE_VERSION_MINOR    - '0'  ||
-            p_update->release.i_revision < *PACKAGE_VERSION_REVISION - '0'  ||
-            p_update->release.extra      < *PACKAGE_VERSION_EXTRA;
+    int current_version[] = {
+        *PACKAGE_VERSION_MAJOR - '0',
+        *PACKAGE_VERSION_MINOR - '0',
+        *PACKAGE_VERSION_REVISION - '0',
+        *PACKAGE_VERSION_EXTRA
+    };
+    int latest_version[] = {
+        p_update->release.i_major,
+        p_update->release.i_minor,
+        p_update->release.i_revision,
+        p_update->release.extra
+    };
+
+    return is_strictly_greater( latest_version, current_version, 4 );
 }
 
 /**
@@ -1414,29 +1447,26 @@ 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 GB"), (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 MB"), (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 kB"), (float)l_size/(1<<10) );
     else
-        i_retval = asprintf( &psz_tmp, "%ld B", l_size );
+        i_retval = asprintf( &psz_tmp, _("%ld B"), l_size );
 
     return i_retval == -1 ? NULL : psz_tmp;
 }
 
-
-/**
- * Struct to launch the download in a thread
- */
-typedef struct
+void update_WaitDownload( update_t *p_update )
 {
-    VLC_COMMON_MEMBERS
-    update_t *p_update;
-    char *psz_destdir;
-} update_download_thread_t;
+    if(p_update->p_download)
+        vlc_thread_join( p_update->p_download );
+    vlc_object_release( p_update->p_download );
+    p_update->p_download = NULL;
+}
 
-void update_DownloadReal( update_download_thread_t *p_udt );
+static void* update_DownloadReal( vlc_object_t *p_this );
 
 /**
  * Download the file given in the update_t
@@ -1449,23 +1479,23 @@ void update_Download( update_t *p_update, const char *psz_destdir )
 {
     assert( p_update );
 
-    update_download_thread_t *p_udt = vlc_object_create( p_update->p_libvlc,
-                                        sizeof( update_download_thread_t ) );
+    update_download_thread_t *p_udt =
+        vlc_custom_create( p_update->p_libvlc, sizeof( *p_udt ),
+                           VLC_OBJECT_GENERIC, "update download" );
     if( !p_udt )
-    {
-        msg_Err( p_update->p_libvlc, "out of memory" );
         return;
-    }
 
     p_udt->p_update = p_update;
+    p_update->p_download = p_udt;
     p_udt->psz_destdir = psz_destdir ? strdup( psz_destdir ) : NULL;
 
     vlc_thread_create( p_udt, "download update", update_DownloadReal,
                        VLC_THREAD_PRIORITY_LOW, false );
 }
 
-void update_DownloadReal( update_download_thread_t *p_udt )
+static void* update_DownloadReal( vlc_object_t *p_this )
 {
+    update_download_thread_t *p_udt = (update_download_thread_t *)p_this;
     int i_progress = 0;
     long int l_size;
     long int l_downloaded = 0;
@@ -1480,10 +1510,14 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     stream_t *p_stream = NULL;
     void* p_buffer = NULL;
     int i_read;
+    int canc;
 
     update_t *p_update = p_udt->p_update;
     char *psz_destdir = p_udt->psz_destdir;
 
+    msg_Dbg( p_udt, "Opening Stream '%s'", p_update->release.psz_url );
+    canc = vlc_savecancel ();
+
     /* Open the stream */
     p_stream = stream_UrlNew( p_udt, p_update->release.psz_url );
     if( !p_stream )
@@ -1499,7 +1533,8 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     psz_tmpdestfile = strrchr( p_update->release.psz_url, '/' );
     if( !psz_tmpdestfile )
     {
-        msg_Err( p_udt, "The URL %s is false formated", p_update->release.psz_url );
+        msg_Err( p_udt, "The URL %s is badly formated",
+                 p_update->release.psz_url );
         goto end;
     }
     psz_tmpdestfile++;
@@ -1516,19 +1551,28 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     /* 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." );
         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... O.O/%s %.1f%% done",
-        p_update->release.psz_url, psz_size, 0.0 ) != -1 )
+    if( asprintf( &psz_status, _("%s\nDownloading... %s/%s %.1f%% done"),
+        p_update->release.psz_url, "0.0", psz_size, 0.0 ) != -1 )
     {
-        i_progress = intf_UserProgress( p_udt, "Downloading ...", psz_status, 0.0, 0 );
+        i_progress = intf_UserProgress( p_udt, _( "Downloading ..."),
+                                        psz_status, 0.0, 0 );
         free( psz_status );
     }
 
-    while( ( i_read = stream_Read( p_stream, p_buffer, 1 << 10 ) ) &&
-                                   !intf_ProgressIsCancelled( p_udt, i_progress ) )
+    vlc_object_lock( p_udt );
+    while( vlc_object_alive( p_udt ) &&
+           ( i_read = stream_Read( p_stream, p_buffer, 1 << 10 ) ) &&
+           !intf_ProgressIsCancelled( p_udt, i_progress ) )
     {
+        vlc_object_unlock( p_udt );
         if( fwrite( p_buffer, i_read, 1, p_file ) < 1 )
         {
             msg_Err( p_udt, "Failed to write into %s", psz_destfile );
@@ -1539,7 +1583,7 @@ void update_DownloadReal( update_download_thread_t *p_udt )
         psz_downloaded = size_str( l_downloaded );
         f_progress = 100.0*(float)l_downloaded/(float)l_size;
 
-        if( asprintf( &psz_status, "%s\nDonwloading... %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 )
         {
@@ -1547,23 +1591,28 @@ void update_DownloadReal( update_download_thread_t *p_udt )
             free( psz_status );
         }
         free( psz_downloaded );
+        vlc_object_lock( p_udt );
     }
 
     /* Finish the progress bar or delete the file if the user had canceled */
     fclose( p_file );
     p_file = NULL;
 
-    if( !intf_ProgressIsCancelled( p_udt, i_progress ) )
+    if( vlc_object_alive( p_udt ) &&
+        !intf_ProgressIsCancelled( p_udt, i_progress ) )
     {
-        if( asprintf( &psz_status, "%s\nDone %s (100.0%%)",
+        vlc_object_unlock( p_udt );
+        if( asprintf( &psz_status, _("%s\nDone %s (100.0%%)"),
             p_update->release.psz_url, psz_size ) != -1 )
         {
             intf_ProgressUpdate( p_udt, i_progress, psz_status, 100.0, 0 );
+            i_progress = 0;
             free( psz_status );
         }
     }
     else
     {
+        vlc_object_unlock( p_udt );
         utf8_unlink( psz_destfile );
         goto end;
     }
@@ -1574,9 +1623,9 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     {
         utf8_unlink( psz_destfile );
 
-        intf_UserFatal( p_udt, true, _("File can not be verified"),
+        intf_UserFatal( p_udt, true, _("File could not be verified"),
             _("It was not possible to download a cryptographic signature for "
-              "downloaded file \"%s\", and so VLC deleted it."),
+              "the downloaded file \"%s\". Thus, it was deleted."),
             psz_destfile );
         msg_Err( p_udt, "Couldn't download signature of downloaded file" );
         goto end;
@@ -1587,9 +1636,9 @@ void update_DownloadReal( update_download_thread_t *p_udt )
         utf8_unlink( psz_destfile );
         msg_Err( p_udt, "Invalid signature issuer" );
         intf_UserFatal( p_udt, true, _("Invalid signature"),
-            _("The cryptographic signature for downloaded file \"%s\" was "
-              "invalid and couldn't be used to securely verify it, and so "
-              "VLC deleted it."),
+            _("The cryptographic signature for the downloaded file \"%s\" was "
+              "invalid and could not be used to securely verify it. Thus, the "
+              "file was deleted."),
             psz_destfile );
         goto end;
     }
@@ -1599,9 +1648,9 @@ void update_DownloadReal( update_download_thread_t *p_udt )
         utf8_unlink( psz_destfile );
         msg_Err( p_udt, "Invalid signature type" );
         intf_UserFatal( p_udt, true, _("Invalid signature"),
-            _("The cryptographic signature for downloaded file \"%s\" was "
-              "invalid and couldn't be used to securely verify it, and so "
-              "VLC deleted it."),
+            _("The cryptographic signature for the downloaded file \"%s\" was "
+              "invalid and could not be used to securely verify it. Thus, the "
+              "file was deleted."),
             psz_destfile );
         goto end;
     }
@@ -1612,8 +1661,8 @@ void update_DownloadReal( update_download_thread_t *p_udt )
         msg_Err( p_udt, "Unable to hash %s", psz_destfile );
         utf8_unlink( psz_destfile );
         intf_UserFatal( p_udt, true, _("File not verifiable"),
-            _("It was not possible to securely verify downloaded file \"%s\", "
-              "and so VLC deleted it."),
+            _("It was not possible to securely verify the downloaded file"
+              " \"%s\". Thus, it was deleted."),
             psz_destfile );
 
         goto end;
@@ -1624,7 +1673,7 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     {
         utf8_unlink( psz_destfile );
         intf_UserFatal( p_udt, true, _("File corrupted"),
-            _("Downloaded file \"%s\" was corrupted, and so VLC deleted it."),
+            _("Downloaded file \"%s\" was corrupted. Thus, it was deleted."),
              psz_destfile );
         msg_Err( p_udt, "Bad SHA1 hash for %s", psz_destfile );
         free( p_hash );
@@ -1636,7 +1685,7 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     {
         utf8_unlink( psz_destfile );
         intf_UserFatal( p_udt, true, _("File corrupted"),
-            _("Downloaded file \"%s\" was corrupted, and so VLC deleted it."),
+            _("Downloaded file \"%s\" was corrupted. Thus, it was deleted."),
              psz_destfile );
         msg_Err( p_udt, "BAD SIGNATURE for %s", psz_destfile );
         free( p_hash );
@@ -1647,6 +1696,10 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     free( p_hash );
 
 end:
+    if( i_progress )
+    {
+        intf_ProgressUpdate( p_udt, i_progress, _("Cancelled"), 100.0, 0 );
+    }
     if( p_stream )
         stream_Delete( p_stream );
     if( p_file )
@@ -1655,6 +1708,12 @@ end:
     free( psz_destfile );
     free( p_buffer );
     free( psz_size );
+
+    p_udt->p_update->p_download = NULL;
+
+    vlc_object_release( p_udt );
+    vlc_restorecancel (canc);
+    return NULL;
 }
 
 update_release_t *update_GetRelease( update_t *p_update )
@@ -1686,6 +1745,11 @@ bool update_NeedUpgrade( update_t *p_update )
     return false;
 }
 
+void update_WaitDownload( update_t *p_update )
+{
+    (void)p_update;
+}
+
 void update_Download( update_t *p_update, const char *psz_destdir )
 {
     (void)p_update; (void)psz_destdir;