1 /*****************************************************************************
2 * update.c: VLC update and plugins download
3 *****************************************************************************
4 * Copyright (C) 2005 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea -at- videolan -dot- org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either release 2 of the License, or
12 * (at your option) any later release.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
26 * This file contains functions related to VLC and plugins update management
29 /*****************************************************************************
31 *****************************************************************************/
35 #include <ctype.h> /* tolower() */
39 #include <vlc_update.h>
41 #include <vlc_block.h>
42 #include <vlc_stream.h>
43 #include <vlc_interface.h>
44 #include <vlc_charset.h>
46 /*****************************************************************************
48 *****************************************************************************/
50 #if defined( UNDER_CE )
51 # define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-ce"
52 #elif defined( WIN32 )
53 # define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-win-x86"
54 #elif defined( __APPLE__ )
55 # define UPDATE_VLC_OS "macosx"
56 # if defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
57 # define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-mac-ppc"
59 # define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-mac-x86"
61 #elif defined( SYS_BEOS )
62 # define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status-beos-x86"
64 # define UPDATE_VLC_STATUS_URL "http://update.videolan.org/vlc/status"
67 #define STRDUP( a ) ( a ? strdup( a ) : NULL )
70 /*****************************************************************************
72 *****************************************************************************/
73 static void EmptyRelease( update_t *p_update );
74 static void GetUpdateFile( update_t *p_update );
75 static int extracmp( char *psz_1, char *psz_2 );
76 static int CompareReleases( const struct update_release_t *p1,
77 const struct update_release_t *p2 );
80 /*****************************************************************************
82 *****************************************************************************/
85 * Create a new update VLC struct
87 * \param p_this the calling vlc_object
88 * \return pointer to new update_t or NULL
90 update_t *__update_New( vlc_object_t *p_this )
94 if( p_this == NULL ) return NULL;
96 p_update = (update_t *)malloc( sizeof( update_t ) );
97 if( !p_update ) return NULL;
99 vlc_mutex_init( p_this, &p_update->lock );
101 p_update->p_libvlc = p_this->p_libvlc;
103 p_update->release.psz_svnrev = NULL;
104 p_update->release.psz_extra = NULL;
105 p_update->release.psz_url = NULL;
106 p_update->release.psz_desc = NULL;
112 * Delete an update_t struct
114 * \param p_update update_t* pointer
117 void update_Delete( update_t *p_update )
121 vlc_mutex_destroy( &p_update->lock );
123 FREENULL( p_update->release.psz_svnrev );
124 FREENULL( p_update->release.psz_extra );
125 FREENULL( p_update->release.psz_url );
126 FREENULL( p_update->release.psz_desc );
132 * Empty the release struct
134 * \param p_update update_t* pointer
137 static void EmptyRelease( update_t *p_update )
139 p_update->release.i_major = 0;
140 p_update->release.i_minor = 0;
141 p_update->release.i_revision = 0;
143 FREENULL( p_update->release.psz_svnrev );
144 FREENULL( p_update->release.psz_extra );
145 FREENULL( p_update->release.psz_url );
146 FREENULL( p_update->release.psz_desc );
150 * Get the update file and parse it
151 * *p_update has to be unlocked when calling this function
153 * \param p_update pointer to update struct
156 static void GetUpdateFile( update_t *p_update )
158 stream_t *p_stream = NULL;
162 char *psz_extra = NULL;
163 char *psz_svnrev = NULL;
164 char *psz_line = NULL;
166 vlc_mutex_lock( &p_update->lock );
168 p_stream = stream_UrlNew( p_update->p_libvlc, UPDATE_VLC_STATUS_URL );
171 msg_Err( p_update->p_libvlc, "Failed to open %s for reading",
172 UPDATE_VLC_STATUS_URL );
176 /* Try to read three lines */
177 if( !( psz_line = stream_ReadLine( p_stream ) ) )
179 msg_Err( p_update->p_libvlc, "Update file %s is corrupted : missing version",
180 UPDATE_VLC_STATUS_URL );
184 /* first line : version number */
185 if( sscanf( psz_line, "%i.%i.%i%as %as", &i_major, &i_minor, &i_revision, &psz_extra, &psz_svnrev ) )
187 p_update->release.i_major = i_major;
188 p_update->release.i_minor = i_minor;
189 p_update->release.i_revision = i_revision;
191 p_update->release.psz_svnrev = psz_svnrev ? psz_svnrev : STRDUP( "" );
192 p_update->release.psz_extra = psz_extra ? psz_extra : STRDUP( "" );
196 msg_Err( p_update->p_libvlc, "Update version false formated" );
201 /* Second line : URL */
202 if( !( psz_line = stream_ReadLine( p_stream ) ) )
204 msg_Err( p_update->p_libvlc, "Update file %s is corrupted : URL missing",
205 UPDATE_VLC_STATUS_URL );
208 p_update->release.psz_url = psz_line;
211 /* Third line : description */
212 if( !( psz_line = stream_ReadLine( p_stream ) ) )
214 msg_Err( p_update->p_libvlc, "Update file %s is corrupted : description missing",
215 UPDATE_VLC_STATUS_URL );
218 p_update->release.psz_desc = psz_line;
221 vlc_mutex_unlock( &p_update->lock );
224 stream_Delete( p_stream );
230 * \param p_update pointer to update struct
233 void update_Check( update_t *p_update )
237 EmptyRelease( p_update );
239 GetUpdateFile( p_update );
245 * \param p1 first integer
246 * \param p2 second integer
247 * \return like strcmp
249 static int extracmp( char *psz_1, char *psz_2 )
251 if( psz_1[0] == '-' )
253 if( psz_2[0] == '-' )
254 return strcmp( psz_1, psz_2 );
260 if( psz_2[0] == '-' )
263 return strcmp( psz_1, psz_2 );
267 * Compare two release numbers
269 * \param p1 first release
270 * \param p2 second release
271 * \return UpdateReleaseStatus(Older|Equal|Newer)
273 static int CompareReleases( const struct update_release_t *p1,
274 const struct update_release_t *p2 )
277 d = ( p1->i_major << 24 ) + ( p1->i_minor << 16 ) + ( p1->i_revision << 8 );
278 d = d - ( p2->i_major << 24 ) - ( p2->i_minor << 16 ) - ( p2->i_revision << 8 );
279 d += extracmp( p1->psz_extra, p2->psz_extra );
282 d = strcmp( p1->psz_svnrev, p2->psz_svnrev );
285 return UpdateReleaseStatusOlder;
287 return UpdateReleaseStatusEqual;
289 return UpdateReleaseStatusNewer;
293 * Compare a given release's version number to the current VLC's one
296 * \return UpdateReleaseStatus(Older|Equal|Newer)
298 int update_CompareReleaseToCurrent( update_t *p_update )
302 struct update_release_t c;
307 int i_result = UpdateReleaseStatusOlder;
309 /* get the current version number */
310 if( sscanf( PACKAGE_VERSION, "%i.%i.%i%as", &i_major, &i_minor, &i_revision, &psz_extra ) )
314 c.i_revision = i_revision;
316 c.psz_extra = psz_extra;
318 c.psz_extra = STRDUP( "" );
319 c.psz_svnrev = STRDUP( VLC_Changeset() );
321 i_result = CompareReleases( &p_update->release, &c );
324 free( c.psz_svnrev );