]> git.sesse.net Git - vlc/blobdiff - src/misc/update.c
vlc_object_create: assert that the object type is known
[vlc] / src / misc / update.c
index dc6ec48333a80fae930b0d7e08ff30c991ae8f6d..45fb993e4debc448ff24f5cac144f8c8a9f236fa 100644 (file)
@@ -67,7 +67,7 @@
  *      * e is an OPTIONAL extra letter
  *      * AKA "0.8.6d" or "0.9.0"
  * Second line is an url of the binary for this last version
- * Third line is a description of the update (it MAY be extended to several lines, but for now it is only one line)
+ * Remaining text is a required description of the update
  */
 
 #if defined( UNDER_CE )
@@ -1049,6 +1049,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 +1068,18 @@ 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 );
+    }
+    else if( p_update->p_download )
+    {
+        vlc_object_kill( p_update->p_download );
+        vlc_thread_join( p_update->p_download );
+    }
+
     vlc_mutex_destroy( &p_update->lock );
 
     free( p_update->release.psz_url );
@@ -1104,7 +1119,6 @@ static bool GetUpdateFile( update_t *p_update )
     int i_minor = 0;
     int i_revision = 0;
     unsigned char extra;
-    char *psz_line = NULL;
     char *psz_version_line = NULL;
 
     p_stream = stream_UrlNew( p_update->p_libvlc, UPDATE_VLC_STATUS_URL );
@@ -1115,18 +1129,18 @@ static bool GetUpdateFile( update_t *p_update )
         goto error;
     }
 
-    /* Try to read three lines */
-    if( !( psz_line = stream_ReadLine( p_stream ) ) )
+    /* Start reading the status file */
+    if( !( psz_version_line = stream_ReadLine( p_stream ) ) )
     {
         msg_Err( p_update->p_libvlc, "Update file %s is corrupted : missing version",
                  UPDATE_VLC_STATUS_URL );
         goto error;
     }
 
-    psz_version_line = psz_line;
     /* first line : version number */
     p_update->release.extra = 0;
-    switch( sscanf( psz_line, "%i.%i.%i%c", &i_major, &i_minor, &i_revision, &extra ) )
+    switch( sscanf( psz_version_line, "%i.%i.%i%c",
+                    &i_major, &i_minor, &i_revision, &extra ) )
     {
         case 4:
             p_update->release.extra = extra;
@@ -1140,24 +1154,35 @@ static bool GetUpdateFile( update_t *p_update )
             goto error;
     }
 
-    /* Second line : URL */
-    if( !( psz_line = stream_ReadLine( p_stream ) ) )
+    /* second line : URL */
+    if( !( p_update->release.psz_url = stream_ReadLine( p_stream ) ) )
     {
         msg_Err( p_update->p_libvlc, "Update file %s is corrupted : URL missing",
                  UPDATE_VLC_STATUS_URL );
         goto error;
     }
-    p_update->release.psz_url = psz_line;
 
+    /* Remaining data : description */
+    int i_read = stream_Size( p_stream ) - stream_Tell( p_stream );
+    if( i_read <= 0 )
+    {
+        msg_Err( p_update->p_libvlc,
+                "Update file %s is corrupted: description missing",
+                UPDATE_VLC_STATUS_URL );
+        goto error;
+    }
+
+    p_update->release.psz_desc = (char*) malloc( i_read + 1 );
+    if( !p_update->release.psz_desc )
+        goto error;
 
-    /* Third line : description */
-    if( !( psz_line = stream_ReadLine( p_stream ) ) )
+    if( stream_Read( p_stream, p_update->release.psz_desc, i_read ) != i_read )
     {
-        msg_Err( p_update->p_libvlc, "Update file %s is corrupted : description missing",
-                 UPDATE_VLC_STATUS_URL );
+        msg_Err( p_update->p_libvlc, "Couldn't download update file %s",
+                UPDATE_VLC_STATUS_URL );
         goto error;
     }
-    p_update->release.psz_desc = psz_line;
+    p_update->release.psz_desc[i_read] = '\0';
 
     stream_Delete( p_stream );
     p_stream = NULL;
@@ -1244,12 +1269,23 @@ static bool GetUpdateFile( update_t *p_update )
     if( sign.type == TEXT_SIGNATURE )
         gcry_md_putc( hd, '\r' );
     gcry_md_putc( hd, '\n' );
-    gcry_md_write( hd, p_update->release.psz_desc,
-                        strlen( p_update->release.psz_desc ) );
-    if( sign.type == TEXT_SIGNATURE )
-        gcry_md_putc( hd, '\r' );
-    gcry_md_putc( hd, '\n' );
 
+    char *psz_desc = p_update->release.psz_desc;
+    while( *psz_desc )
+    {
+        size_t i_len = strcspn( psz_desc, "\r\n" );
+        if( !i_len )
+            break;
+
+        gcry_md_write( hd, psz_desc, i_len );
+        if( sign.type == TEXT_SIGNATURE )
+            gcry_md_putc( hd, '\r' );
+        gcry_md_putc( hd, '\n' );
+
+        psz_desc += i_len;
+        while( *psz_desc == '\r' || *psz_desc == '\n' )
+            psz_desc++;
+    }
 
     if( sign.version == 3 )
     {
@@ -1315,19 +1351,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( update_check_thread_t *p_uct );
 
 /**
  * Check for updates
@@ -1346,6 +1370,7 @@ void update_Check( update_t *p_update, void (*pf_callback)( void*, bool ), void
     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;
 
@@ -1365,6 +1390,8 @@ void update_CheckReal( update_check_thread_t *p_uct )
     if( p_uct->pf_callback )
         (p_uct->pf_callback)( p_uct->p_data, b_ret );
 
+    p_uct->p_update->p_check = NULL;
+
     vlc_object_release( p_uct );
 }
 
@@ -1406,18 +1433,7 @@ static char *size_str( long int l_size )
     return i_retval == -1 ? NULL : psz_tmp;
 }
 
-
-/**
- * Struct to launch the download in a thread
- */
-typedef struct
-{
-    VLC_COMMON_MEMBERS
-    update_t *p_update;
-    char *psz_destdir;
-} update_download_thread_t;
-
-void update_DownloadReal( update_download_thread_t *p_udt );
+static void update_DownloadReal( update_download_thread_t *p_udt );
 
 /**
  * Download the file given in the update_t
@@ -1426,26 +1442,24 @@ void update_DownloadReal( update_download_thread_t *p_udt );
  * \param dir to store the download file
  * \return nothing
  */
-void update_Download( update_t *p_update, char *psz_destdir )
+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 ) );
     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( update_download_thread_t *p_udt )
 {
     int i_progress = 0;
     long int l_size;
@@ -1507,9 +1521,12 @@ void update_DownloadReal( update_download_thread_t *p_udt )
         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 );
@@ -1528,14 +1545,17 @@ 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 ) )
     {
+        vlc_object_unlock( p_udt );
         if( asprintf( &psz_status, "%s\nDone %s (100.0%%)",
             p_update->release.psz_url, psz_size ) != -1 )
         {
@@ -1545,6 +1565,7 @@ void update_DownloadReal( update_download_thread_t *p_udt )
     }
     else
     {
+        vlc_object_unlock( p_udt );
         utf8_unlink( psz_destfile );
         goto end;
     }
@@ -1637,6 +1658,8 @@ end:
     free( p_buffer );
     free( psz_size );
 
+    p_udt->p_update->p_download = NULL;
+
     vlc_object_release( p_udt );
 }
 
@@ -1669,7 +1692,7 @@ bool update_NeedUpgrade( update_t *p_update )
     return false;
 }
 
-void update_Download( update_t *p_update, char *psz_destdir )
+void update_Download( update_t *p_update, const char *psz_destdir )
 {
     (void)p_update; (void)psz_destdir;
 }