📄 update.c
字号:
case -1: msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_STATUS_URL ); goto error; case XML_READER_STARTELEM: psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) { msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_STATUS_URL ); goto error; } while( xml_ReaderNextAttr( p_xml_reader ) == VLC_SUCCESS ) { psz_name = xml_ReaderName( p_xml_reader ); psz_value = xml_ReaderValue( p_xml_reader ); if( !psz_name || !psz_value ) { msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_STATUS_URL ); goto error; } if( b_os && b_arch ) { if( strcmp( psz_eltname, "version" ) == 0 ) { if( !strcmp( psz_name, "major" ) ) tmp_release.psz_major = STRDUP( psz_value ); else if( !strcmp( psz_name, "minor" ) ) tmp_release.psz_minor = STRDUP( psz_value ); else if( !strcmp( psz_name, "revision" ) ) tmp_release.psz_revision = STRDUP( psz_value ); else if( !strcmp( psz_name, "extra" ) ) tmp_release.psz_extra = STRDUP( psz_value ); else if( !strcmp( psz_name, "svn" ) ) tmp_release.psz_svn_revision = STRDUP( psz_value ); else if( !strcmp( psz_name, "version" ) ) { if( !strcmp( psz_value, "unstable" ) ) tmp_release.i_type = UPDATE_RELEASE_TYPE_UNSTABLE; else if( !strcmp( psz_value, "testing" ) ) tmp_release.i_type = UPDATE_RELEASE_TYPE_TESTING; else tmp_release.i_type = UPDATE_RELEASE_TYPE_STABLE; } } else if( !strcmp( psz_eltname, "file" ) ) { if( !strcmp( psz_name, "type" ) ) { if( !strcmp( psz_value, "info" ) ) tmp_file.i_type = UPDATE_FILE_TYPE_INFO; else if( !strcmp( psz_value, "source" ) ) tmp_file.i_type = UPDATE_FILE_TYPE_SOURCE; else if( !strcmp( psz_value, "binary" ) ) tmp_file.i_type = UPDATE_FILE_TYPE_BINARY; else if( !strcmp( psz_value, "plugin" ) ) tmp_file.i_type = UPDATE_FILE_TYPE_PLUGIN; else tmp_file.i_type = UPDATE_FILE_TYPE_UNDEF; } else if( !strcmp( psz_name, "md5" ) ) tmp_file.psz_md5 = STRDUP( psz_value ); else if( !strcmp( psz_name, "size" ) ) tmp_file.l_size = atol( psz_value ); else if( !strcmp( psz_name, "url" ) ) tmp_file.psz_url = STRDUP( psz_value ); } } if( !strcmp( psz_name, "name" ) && ( !strcmp( psz_value, UPDATE_VLC_OS ) || !strcmp( psz_value, "*" ) ) && !strcmp( psz_eltname, "os" ) ) { b_os = VLC_TRUE; } if( b_os && !strcmp( psz_name, "name" ) && ( !strcmp( psz_value, UPDATE_VLC_ARCH ) || !strcmp( psz_value, "*" ) ) && !strcmp( psz_eltname, "arch" ) ) { b_arch = VLC_TRUE; } FREE( psz_name ); FREE( psz_value ); } if( ( b_os && b_arch && strcmp( psz_eltname, "arch" ) ) ) { if( !strcmp( psz_eltname, "version" ) ) { int i; /* look for a previous occurence of this release */ for( i = 0; i < p_update->i_releases; i++ ) { p_release = p_update->p_releases + i; if( CompareReleases( p_release, &tmp_release ) == UPDATE_RELEASE_STATUS_EQUAL ) { break; } } /* if this is the first time that we see this release, * append it to the list of releases */ if( i == p_update->i_releases ) { tmp_release.i_status = CompareReleaseToCurrent( &tmp_release ); p_update->p_releases = (struct update_release_t *)realloc( p_update->p_releases, (++(p_update->i_releases))*sizeof( struct update_release_t ) ); p_update->p_releases[ p_update->i_releases - 1 ] = tmp_release; p_release = p_update->p_releases + p_update->i_releases - 1; tmp_release.psz_major = NULL; tmp_release.psz_minor = NULL; tmp_release.psz_revision = NULL; tmp_release.psz_extra = NULL; tmp_release.psz_svn_revision = NULL; tmp_release.i_type = UPDATE_RELEASE_TYPE_STABLE; tmp_release.i_status = 0; tmp_release.p_files = NULL; tmp_release.i_files = 0; } else { FREE( tmp_release.psz_major ); FREE( tmp_release.psz_minor ); FREE( tmp_release.psz_revision ); FREE( tmp_release.psz_extra ); FREE( tmp_release.psz_svn_revision ); tmp_release.i_type = UPDATE_RELEASE_TYPE_STABLE; FREE( tmp_release.p_files ); tmp_release.i_files = 0; } } else if( !strcmp( psz_eltname, "file" ) ) { /* append file to p_release's file list */ if( p_release == NULL ) { goto error; } p_release->p_files = (struct update_file_t *)realloc( p_release->p_files, (++(p_release->i_files))*sizeof( struct update_file_t ) ); p_release->p_files[ p_release->i_files - 1 ] = tmp_file; tmp_file.i_type = UPDATE_FILE_TYPE_UNDEF; tmp_file.psz_md5 = NULL; tmp_file.l_size = 0; tmp_file.psz_url = NULL; tmp_file.psz_description = NULL; } } FREE( psz_eltname ); break; case XML_READER_ENDELEM: psz_eltname = xml_ReaderName( p_xml_reader ); if( !psz_eltname ) { msg_Err( p_update->p_vlc, "Error while parsing %s", UPDATE_VLC_STATUS_URL ); goto error; } if( !strcmp( psz_eltname, "os" ) ) b_os = VLC_FALSE; else if( !strcmp( psz_eltname, "arch" ) ) b_arch = VLC_FALSE; FREE( psz_eltname ); break; case XML_READER_TEXT: psz_eltvalue = xml_ReaderValue( p_xml_reader ); if( p_release && p_release->i_files ) p_release->p_files[ p_release->i_files - 1 ] .psz_description = STRDUP( psz_eltvalue ); FREE( psz_eltvalue ); break; } } p_update->b_releases = VLC_TRUE; error: vlc_mutex_unlock( &p_update->lock ); free( psz_eltname ); free( psz_eltvalue ); free( psz_name ); free( psz_value ); free( tmp_release.psz_major ); free( tmp_release.psz_minor ); free( tmp_release.psz_revision ); free( tmp_release.psz_extra ); free( tmp_release.psz_svn_revision ); free( tmp_file.psz_md5 ); free( tmp_file.psz_url ); free( tmp_file.psz_description ); if( p_xml_reader && p_xml ) xml_ReaderDelete( p_xml, p_xml_reader ); if( p_stream ) stream_Delete( p_stream ); if( p_xml ) xml_Delete( p_xml );}/** * Check for updates * * \param p_update pointer to update struct * \param b_force set to VLC_TRUE if you want to force the update * \returns nothing */void update_Check( update_t *p_update, vlc_bool_t b_force ){ if( p_update == NULL ) return; GetMirrorsList( p_update, b_force ); GetFilesList( p_update, b_force );}/** * Compare two release numbers * The comparision algorith basically performs an alphabetical order (strcmp) * comparision of each of the version number elements until it finds two * different ones. This is the tricky function. * * \param p1 first release * \param p2 second release * \return like strcmp */int CompareReleases( struct update_release_t *p1, struct update_release_t *p2 ){ int d; if( ( d = strcmp( p1->psz_major, p2->psz_major ) ) ) ; else if( ( d = strcmp( p1->psz_minor, p2->psz_minor ) ) ) ; else if( ( d = strcmp( p1->psz_revision, p2->psz_revision ) ) ) ; else { d = strcmp( p1->psz_extra, p2->psz_extra ); if( d<0 ) { /* FIXME: * not num < NULL < num * -test and -svn releases are thus always considered older than * -'' or -0 releases, which is the best i could come up with */ char *psz_end1; char *psz_end2; strtol( p1->psz_extra, &psz_end1, 10 ); strtol( p2->psz_extra, &psz_end2, 10 ); if( psz_end2 == p2->psz_extra && ( psz_end1 != p1->psz_extra || *p1->psz_extra == '\0' ) ) d = 1; } } if( d < 0 ) return UPDATE_RELEASE_STATUS_OLDER; else if( d == 0 ) return UPDATE_RELEASE_STATUS_EQUAL; else return UPDATE_RELEASE_STATUS_NEWER;}/** * Compare a given release's version number to the current VLC's one * * \param p a release * \return >0 if newer, 0 if equal and <0 if older */int CompareReleaseToCurrent( struct update_release_t *p ){ struct update_release_t c = {0}; int r; c.psz_major = STRDUP( PACKAGE_VERSION_MAJOR ); c.psz_minor = STRDUP( PACKAGE_VERSION_MINOR ); c.psz_revision = STRDUP( PACKAGE_VERSION_REVISION ); c.psz_extra = STRDUP( PACKAGE_VERSION_EXTRA ); r = CompareReleases( p, &c ); free( c.psz_major ); free( c.psz_minor ); free( c.psz_revision ); free( c.psz_extra ); return r;}/***************************************************************************** * Updatei_iterator_t functions *****************************************************************************//** * Create a new update iterator structure. This structure can then be used to * describe a position and move through the update and mirror trees/lists. * This will use an existing update struct or create a new one if none is * found * * \param p_u the calling update_t * \return a pointer to an update iterator */update_iterator_t *update_iterator_New( update_t *p_u ){ update_iterator_t *p_uit = NULL; if( p_u == NULL ) return NULL; p_uit = (update_iterator_t *)malloc( sizeof( update_iterator_t ) ); if( p_uit == NULL ) return NULL; p_uit->p_u = p_u; p_uit->i_m = -1; p_uit->i_r = -1; p_uit->i_f = -1; p_uit->i_t = UPDATE_FILE_TYPE_ALL; p_uit->i_rs = UPDATE_RELEASE_STATUS_ALL; p_uit->i_rt = UPDATE_RELEASE_TYPE_STABLE; p_uit->file.i_type = UPDATE_FILE_TYPE_NONE; p_uit->file.psz_md5 = NULL; p_uit->file.psz_url = NULL; p_uit->file.l_size = 0; p_uit->file.psz_description = NULL; p_uit->release.psz_version = NULL; p_uit->release.psz_svn_revision = NULL; p_uit->release.i_type = UPDATE_RELEASE_TYPE_UNSTABLE; p_uit->release.i_status = UPDATE_RELEASE_STATUS_NONE; p_uit->mirror.psz_name = NULL; p_uit->mirror.psz_location = NULL; p_uit->mirror.psz_type = NULL; return p_uit;}/** * Delete an update iterator structure (duh!) * * \param p_uit pointer to an update iterator * \return nothing */void update_iterator_Delete( update_iterator_t *p_uit ){ if( !p_uit ) return; update_iterator_ClearData( p_uit ); free( p_uit );}/** * Reset an update_iterator_t structure * * \param p_uit pointer to an update iterator * \return UPDATE_FAIL upon error, UPDATE_SUCCESS otherwise */unsigned int update_iterator_Reset( update_iterator_t *p_uit ){ if( !p_uit ) return UPDATE_FAIL; p_uit->i_r = -1; p_uit->i_f = -1; p_uit->i_m = -1; update_iterator_ClearData( p_uit ); return UPDATE_SUCCESS;}/** * Finds the next file in the update tree that matches status and type * requirements set in the update_iterator * * \param p_uit update iterator * \return UPDATE_FAIL if we can't find the next file, UPDATE_SUCCESS|UPDATE_FILE if we stay in the same release, UPDATE_SUCCESS|UPDATE_RELEASE|UPDATE_FILE if we change the release index */unsigned int update_iterator_NextFile( update_iterator_t *p_uit ){ int r,f=-1,old_r; if( !p_uit ) return UPDATE_FAIL; old_r=p_uit->i_r; /* if the update iterator was already in a "no match" state, start over */ if( p_uit->i_r == -1 ) p_uit->i_r = 0; //if( p_uit->i_f == -1 ) p_uit->i_f = 0; vlc_mutex_lock( &p_uit->p_u->lock ); for( r = p_uit->i_r; r < p_uit->p_u->i_releases; r++ ) { if( !( p_uit->p_u->p_releases[r].i_status & p_uit->i_rs ) ) continue; for( f = ( r == p_uit->i_r ? p_uit->i_f + 1 : 0 ); f < p_uit->p_u->p_releases[r].i_files; f++ ) { if( p_uit->p_u->p_releases[r].p_files[f].i_type & p_uit->i_t ) { goto done;/* "double break" */ } } } done: p_uit->i_r = r; p_uit->i_f = f; r = p_uit->p_u->i_releases; if( old_r == p_uit->i_r ) { update_iterator_GetData( p_uit ); vlc_mutex_unlock( &p_uit->p_u->lock ); return UPDATE_SUCCESS|UPDATE_FILE; } else if( p_uit->i_r == r ) { p_uit->i_r = -1; p_uit->i_f = -1; update_iterator_GetData( p_uit ); vlc_mutex_unlock( &p_uit->p_u->lock ); return UPDATE_FAIL; } else { update_iterator_GetData( p_uit ); vlc_mutex_unlock( &p_uit->p_u->lock ); return UPDATE_SUCCESS|UPDATE_RELEASE|UPDATE_FILE; }}/** * Finds the previous file in the update tree that matches status and type * requirements set in the update_iterator * * \param p_uit update iterator * \return UPDATE_FAIL if we can't find the previous file, UPDATE_SUCCESS|UPDATE_FILE if we stay in the same release, UPDATE_SUCCESS|UPDATE_RELEASE|UPDATE_FILE if we change the release index */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -