Skip to content

Commit 45f0e0f

Browse files
committed
lib: self-update no longer bypasses integrity checks, make a warning
This partially reverts 83ade39. In the past, self-updates mandated that only xbps and its dependencies can be updated if an xbps update is avaliable. As updating dependencies may break their depndents, xbps used XBPS_FLAG_FORCE_REMOVE_REVDEPS in order to bypass integrety checks when using xbps-install -u xbps. This can result in circumstances where the the system is rendered inoperable due to missing or mismatched dependencies of core system packages (e.g. PAM). Downgrade it to a warning, don't bypass integrity checks, and allow full system upgrades to upgrade xbps to ensure that users don't end up with a broken system after upgrading xbps.
1 parent 05cfbfb commit 45f0e0f

File tree

4 files changed

+90
-95
lines changed

4 files changed

+90
-95
lines changed

bin/xbps-install/state_cb.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,18 @@ state_cb(const struct xbps_state_cb_data *xscd, void *cbdata UNUSED)
158158
case XBPS_STATE_UNPACK_FILE_PRESERVED:
159159
printf("%s\n", xscd->desc);
160160
break;
161+
case XBPS_STATE_OUTOFDATE:
162+
if (!xbps_pkg_name(pkgname, sizeof(pkgname), xscd->arg)) {
163+
abort();
164+
}
165+
newver = xscd->arg;
166+
pkgd = xbps_pkgdb_get_pkg(xscd->xhp, pkgname);
167+
xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &instver);
168+
fprintf(stderr, "WARNING: The '%s' package is out of date, '%s' is available.\n", instver, newver);
169+
if (xscd->desc)
170+
fprintf(stderr, "%s\n", xscd->desc);
171+
fprintf(stderr, "NOTE: This can be resolved by running `xbps-install -u`\n");
172+
break;
161173
/* errors */
162174
case XBPS_STATE_TRANS_FAIL:
163175
case XBPS_STATE_UNPACK_FAIL:

bin/xbps-install/transaction.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -319,9 +319,6 @@ dist_upgrade(struct xbps_handle *xhp, unsigned int cols, bool yes, bool drun)
319319
} else if (rv == EBUSY) {
320320
if (drun) {
321321
rv = 0;
322-
} else {
323-
xbps_error_printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
324-
return rv;
325322
}
326323
} else if (rv == EEXIST) {
327324
return 0;
@@ -350,8 +347,6 @@ install_new_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
350347
xbps_error_printf("No repositories currently registered!\n");
351348
else if (rv == ENXIO)
352349
xbps_error_printf("Package `%s' contains invalid dependencies, exiting.\n", pkg);
353-
else if (rv == EBUSY)
354-
xbps_error_printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
355350
else if (rv != 0) {
356351
xbps_error_printf("Unexpected error: %s\n", strerror(rv));
357352
rv = -1;
@@ -375,8 +370,6 @@ update_pkg(struct xbps_handle *xhp, const char *pkg, bool force)
375370
xbps_error_printf("No repositories currently registered!\n");
376371
else if (rv == ENXIO)
377372
xbps_error_printf("Package `%s' contains invalid dependencies, exiting.\n", pkg);
378-
else if (rv == EBUSY)
379-
xbps_error_printf("The 'xbps' package must be updated, please run `xbps-install -u xbps`\n");
380373
else if (rv != 0) {
381374
xbps_error_printf("Unexpected error: %s\n", strerror(rv));
382375
return -1;

include/xbps.h.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,8 @@ typedef enum xbps_state {
374374
XBPS_STATE_ALTGROUP_REMOVED,
375375
XBPS_STATE_ALTGROUP_SWITCHED,
376376
XBPS_STATE_ALTGROUP_LINK_ADDED,
377-
XBPS_STATE_ALTGROUP_LINK_REMOVED
377+
XBPS_STATE_ALTGROUP_LINK_REMOVED,
378+
XBPS_STATE_OUTOFDATE
378379
} xbps_state_t;
379380

380381
/**

lib/transaction_ops.c

Lines changed: 76 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -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
*/
228228
static 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

299305
int
@@ -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

Comments
 (0)