@@ -226,19 +226,18 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
226226 * Returns 1 if there's an update, 0 if none or -1 on error.
227227 */
228228static int
229- xbps_autoupdate (struct xbps_handle * xhp )
229+ trans_check_uptodate (struct xbps_handle * xhp , const char * checkpkg , const char * * new_pkgver )
230230{
231- xbps_array_t rdeps ;
232- xbps_dictionary_t pkgd ;
233- const char * pkgver = NULL , * pkgname = NULL ;
234- int rv ;
231+ xbps_array_t pkgs ;
232+ xbps_dictionary_t pkgd = NULL , pkg_repod = NULL ;
233+ const char * pkgver = NULL , * pkgname = NULL , * repopkgver = NULL , * repoloc = NULL ;
235234
236235 /*
237236 * Check if there's a new update for XBPS before starting
238237 * another transaction.
239238 */
240- if (((pkgd = xbps_pkgdb_get_pkg (xhp , "xbps" )) == NULL ) &&
241- ((pkgd = xbps_pkgdb_get_virtualpkg (xhp , "xbps" )) == NULL ))
239+ if (((pkgd = xbps_pkgdb_get_pkg (xhp , checkpkg )) == NULL ) &&
240+ ((pkgd = xbps_pkgdb_get_virtualpkg (xhp , checkpkg )) == NULL ))
242241 return 0 ;
243242
244243 if (!xbps_dictionary_get_cstring_nocopy (pkgd , "pkgver" , & pkgver )) {
@@ -248,52 +247,59 @@ xbps_autoupdate(struct xbps_handle *xhp)
248247 return EINVAL ;
249248 }
250249
251- rv = trans_find_pkg (xhp , pkgname , false);
252-
253- xbps_dbg_printf ("%s: trans_find_pkg xbps: %d\n" , __func__ , rv );
254-
255- if (rv == 0 ) {
256- if (xhp -> flags & XBPS_FLAG_DOWNLOAD_ONLY ) {
250+ if (xbps_dictionary_get (pkgd , "repolock" )) {
251+ struct xbps_repo * repo ;
252+ /* find update from repo */
253+ xbps_dictionary_get_cstring_nocopy (pkgd , "repository" , & repoloc );
254+ assert (repoloc );
255+ if ((repo = xbps_regget_repo (xhp , repoloc )) == NULL ) {
256+ /* not found */
257257 return 0 ;
258258 }
259- /* a new xbps version is available, check its revdeps */
260- rdeps = xbps_pkgdb_get_pkg_revdeps (xhp , "xbps" );
261- for (unsigned int i = 0 ; i < xbps_array_count (rdeps ); i ++ ) {
262- const char * curpkgver = NULL ;
263- char curpkgn [XBPS_NAME_SIZE ] = {0 };
259+ pkg_repod = xbps_repo_get_pkg (repo , pkgname );
260+ } else {
261+ /* find update from rpool */
262+ pkg_repod = xbps_rpool_get_pkg (xhp , pkgname );
263+ }
264+ if (pkg_repod == NULL ) {
265+ /* not found */
266+ return 0 ;
267+ }
264268
265- xbps_array_get_cstring_nocopy (rdeps , i , & curpkgver );
266- xbps_dbg_printf ("%s: processing revdep %s\n" , __func__ , curpkgver );
269+ xbps_dictionary_get_cstring_nocopy (pkg_repod , "pkgver" , & repopkgver );
270+
271+ /*
272+ * Compare installed version vs best pkg available in repos
273+ * for pkg updates.
274+ */
275+ xbps_dictionary_get_cstring_nocopy (pkgd ,
276+ "pkgver" , & pkgver );
277+ if (xbps_cmpver (repopkgver , pkgver ) <= 0 &&
278+ !xbps_pkg_reverts (pkg_repod , pkgver )) {
279+ xbps_dictionary_get_cstring_nocopy (pkg_repod ,
280+ "repository" , & repoloc );
281+ xbps_dbg_printf ("%s: [rpool] Skipping `%s' "
282+ "(installed: %s) from repository `%s'\n" ,
283+ __func__ , repopkgver , pkgver , repoloc );
284+ return 0 ;
285+ }
267286
268- if (!xbps_pkg_name (curpkgn , sizeof (curpkgn ), curpkgver )) {
269- abort ();
270- }
271- rv = trans_find_pkg (xhp , curpkgn , false);
272- xbps_dbg_printf ("%s: trans_find_pkg revdep %s: %d\n" , __func__ , curpkgver , rv );
273- if (rv && rv != ENOENT && rv != EEXIST && rv != ENODEV )
274- return -1 ;
275- }
276- /*
277- * Set XBPS_FLAG_FORCE_REMOVE_REVDEPS to ignore broken
278- * reverse dependencies in xbps_transaction_prepare().
279- *
280- * This won't skip revdeps of the xbps pkg, rather other
281- * packages in rootdir that could be broken indirectly.
282- *
283- * A sysup transaction after updating xbps should fix them
284- * again.
285- */
286- xhp -> flags |= XBPS_FLAG_FORCE_REMOVE_REVDEPS ;
287- return 1 ;
288- } else if (rv == ENOENT || rv == EEXIST || rv == ENODEV ) {
289- /* no update */
287+ pkgs = xbps_dictionary_get (xhp -> transd , "packages" );
288+ /*
289+ * Find out if package being checked already has a queued
290+ * transaction, in that case ignore it.
291+ */
292+ if (xbps_find_pkg_in_array (pkgs , repopkgver , 0 )) {
293+ xbps_dbg_printf ("%s: [update] `%s' already queued in "
294+ "transaction.\n" , __func__ , repopkgver );
290295 return 0 ;
291- } else {
292- /* error */
293- return -1 ;
294296 }
295297
296- return 0 ;
298+ if (xhp -> flags & XBPS_FLAG_DOWNLOAD_ONLY ) {
299+ return 0 ;
300+ }
301+ if (new_pkgver ) * new_pkgver = repopkgver ;
302+ return 1 ;
297303}
298304
299305int
@@ -305,17 +311,8 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
305311 bool newpkg_found = false;
306312 int rv = 0 ;
307313
308- rv = xbps_autoupdate (xhp );
309- switch (rv ) {
310- case 1 :
311- /* xbps needs to be updated, don't allow any other update */
312- return EBUSY ;
313- case -1 :
314- /* error */
314+ if (xbps_pkgdb_init (xhp ) != 0 )
315315 return EINVAL ;
316- default :
317- break ;
318- }
319316
320317 iter = xbps_dictionary_iterator (xhp -> pkgdb );
321318 assert (iter );
@@ -346,6 +343,13 @@ xbps_transaction_update_packages(struct xbps_handle *xhp)
346343 }
347344 xbps_object_iterator_release (iter );
348345
346+ /* Notify consumer if xbps is out of date */
347+ {
348+ const char * pkgver = NULL ;
349+ if (trans_check_uptodate (xhp , "xbps" , & pkgver ) == 1 )
350+ xbps_set_cb_state (xhp , XBPS_STATE_OUTOFDATE , 0 , pkgver , NULL );
351+ }
352+
349353 return newpkg_found ? rv : EEXIST ;
350354}
351355
@@ -355,22 +359,6 @@ xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg, bool force
355359 xbps_array_t rdeps ;
356360 int rv ;
357361
358- rv = xbps_autoupdate (xhp );
359- xbps_dbg_printf ("%s: xbps_autoupdate %d\n" , __func__ , rv );
360- switch (rv ) {
361- case 1 :
362- /* xbps needs to be updated, only allow xbps to be updated */
363- if (strcmp (pkg , "xbps" ))
364- return EBUSY ;
365- return 0 ;
366- case -1 :
367- /* error */
368- return EINVAL ;
369- default :
370- /* no update */
371- break ;
372- }
373-
374362 /* update its reverse dependencies */
375363 rdeps = xbps_pkgdb_get_pkg_revdeps (xhp , pkg );
376364 if (xhp -> flags & XBPS_FLAG_DOWNLOAD_ONLY ) {
@@ -397,6 +385,14 @@ xbps_transaction_update_pkg(struct xbps_handle *xhp, const char *pkg, bool force
397385 /* add pkg repod */
398386 rv = trans_find_pkg (xhp , pkg , force );
399387 xbps_dbg_printf ("%s: trans_find_pkg %s: %d\n" , __func__ , pkg , rv );
388+
389+ /* Notify consumer if xbps is out of date */
390+ {
391+ const char * pkgver = NULL ;
392+ if (trans_check_uptodate (xhp , "xbps" , & pkgver ) == 1 )
393+ xbps_set_cb_state (xhp , XBPS_STATE_OUTOFDATE , 0 , pkgver , NULL );
394+ }
395+
400396 return rv ;
401397}
402398
@@ -406,21 +402,6 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, bool forc
406402 xbps_array_t rdeps ;
407403 int rv ;
408404
409- rv = xbps_autoupdate (xhp );
410- switch (rv ) {
411- case 1 :
412- /* xbps needs to be updated, only allow xbps to be updated */
413- if (strcmp (pkg , "xbps" ))
414- return EBUSY ;
415- return 0 ;
416- case -1 :
417- /* error */
418- return EINVAL ;
419- default :
420- /* no update */
421- break ;
422- }
423-
424405 /* update its reverse dependencies */
425406 rdeps = xbps_pkgdb_get_pkg_revdeps (xhp , pkg );
426407 if (xhp -> flags & XBPS_FLAG_DOWNLOAD_ONLY ) {
@@ -446,6 +427,14 @@ xbps_transaction_install_pkg(struct xbps_handle *xhp, const char *pkg, bool forc
446427 }
447428 rv = trans_find_pkg (xhp , pkg , force );
448429 xbps_dbg_printf ("%s: trans_find_pkg %s: %d\n" , __func__ , pkg , rv );
430+
431+ /* Notify consumer if xbps is out of date */
432+ {
433+ const char * pkgver = NULL ;
434+ if (trans_check_uptodate (xhp , "xbps" , & pkgver ) == 1 )
435+ xbps_set_cb_state (xhp , XBPS_STATE_OUTOFDATE , 0 , pkgver , NULL );
436+ }
437+
449438 return rv ;
450439}
451440
0 commit comments