Skip to content

Commit 316a188

Browse files
committed
lib: error handling and cleanup of xbps_transaction_store
1 parent 80c610d commit 316a188

2 files changed

Lines changed: 94 additions & 72 deletions

File tree

include/xbps_api_impl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ bool HIDDEN xbps_transaction_check_revdeps(struct xbps_handle *, xbps_array_t);
9090
bool HIDDEN xbps_transaction_check_shlibs(struct xbps_handle *, xbps_array_t);
9191
bool HIDDEN xbps_transaction_check_replaces(struct xbps_handle *, xbps_array_t);
9292
int HIDDEN xbps_transaction_check_conflicts(struct xbps_handle *, xbps_array_t);
93-
bool HIDDEN xbps_transaction_store(struct xbps_handle *, xbps_array_t, xbps_dictionary_t, bool);
93+
int HIDDEN xbps_transaction_store(struct xbps_handle *, xbps_array_t, xbps_dictionary_t, bool);
9494
int HIDDEN xbps_transaction_init(struct xbps_handle *);
9595
int HIDDEN xbps_transaction_files(struct xbps_handle *,
9696
xbps_object_iterator_t);

lib/transaction_store.c

Lines changed: 93 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -27,87 +27,112 @@
2727

2828
#include "xbps_api_impl.h"
2929

30-
bool HIDDEN
31-
xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs,
32-
xbps_dictionary_t pkgrd, bool autoinst)
30+
static int
31+
transaction_replace_package(xbps_array_t pkgs, const char *pkgname, const char *pkgver)
3332
{
34-
bool alloc_replaces = false;
35-
xbps_dictionary_t d, pkgd;
36-
xbps_array_t replaces;
37-
const char *pkgver, *pkgname, *curpkgver, *repo;
38-
char *self_replaced;
39-
int rv;
33+
xbps_dictionary_t pkgd;
34+
const char *curpkgver = NULL;
35+
int r;
4036

41-
assert(xhp);
42-
assert(pkgs);
43-
assert(pkgrd);
37+
pkgd = xbps_find_pkg_in_array(pkgs, pkgname, 0);
38+
if (!pkgd)
39+
return 1;
40+
41+
/* compare version stored in transaction vs current */
42+
if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &curpkgver))
43+
xbps_unreachable();
44+
45+
r = xbps_cmpver(pkgver, curpkgver);
46+
if (r == 0)
47+
return 0;
48+
// XXX: should it be possible to replace with lower version?
49+
if (r == -1)
50+
return 0;
51+
52+
if (!xbps_remove_pkg_from_array_by_pkgver(pkgs, curpkgver))
53+
xbps_unreachable();
54+
55+
xbps_dbg_printf("[trans] replaced %s with %s\n", curpkgver, pkgver);
4456

45-
if (!xbps_dictionary_get_cstring_nocopy(pkgrd, "pkgver", &pkgver)) {
46-
return false;
57+
return 1;
58+
}
59+
60+
// XXX: the automatic self replace is weird, there should be a better way
61+
// than having to add and remove it from the metdata...
62+
static int
63+
package_self_replace(xbps_dictionary_t pkgd, const char *pkgname)
64+
{
65+
char buf[XBPS_NAME_SIZE + sizeof(">=0") - 1];
66+
xbps_array_t replaces;
67+
68+
replaces = xbps_dictionary_get(pkgd, "replaces");
69+
if (!replaces) {
70+
replaces = xbps_array_create();
71+
if (!replaces)
72+
return xbps_error_oom();
73+
} else {
74+
xbps_object_retain(replaces);
4775
}
48-
if (!xbps_dictionary_get_cstring_nocopy(pkgrd, "pkgname", &pkgname)) {
49-
return false;
76+
77+
snprintf(buf,sizeof(buf), "%s>=0", pkgname);
78+
if (!xbps_array_add_cstring(replaces, buf)) {
79+
xbps_object_release(replaces);
80+
return xbps_error_oom();
5081
}
51-
d = xbps_find_pkg_in_array(pkgs, pkgname, 0);
52-
if (xbps_object_type(d) == XBPS_TYPE_DICTIONARY) {
53-
/* compare version stored in transaction vs current */
54-
if (!xbps_dictionary_get_cstring_nocopy(d, "pkgver", &curpkgver)) {
55-
return false;
56-
}
57-
rv = xbps_cmpver(pkgver, curpkgver);
58-
if (rv == 0 || rv == -1) {
59-
/* same version or stored version greater than current */
60-
return true;
61-
} else {
62-
/*
63-
* Current version is greater than stored,
64-
* replace stored with current.
65-
*/
66-
if (!xbps_remove_pkg_from_array_by_pkgver(pkgs, curpkgver)) {
67-
return false;
68-
}
69-
xbps_dbg_printf("[trans] replaced %s with %s\n", curpkgver, pkgver);
70-
}
82+
83+
if (!xbps_dictionary_set(pkgd, "replaces", replaces)) {
84+
xbps_object_release(replaces);
85+
return xbps_error_oom();
7186
}
7287

73-
if ((pkgd = xbps_dictionary_copy_mutable(pkgrd)) == NULL)
74-
return false;
88+
xbps_object_release(replaces);
89+
return 0;
90+
}
7591

76-
/*
77-
* Add required objects into package dep's dictionary.
78-
*/
79-
if (autoinst && !xbps_dictionary_set_bool(pkgd, "automatic-install", true))
80-
goto err;
92+
int HIDDEN
93+
xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs,
94+
xbps_dictionary_t pkgrd, bool autoinst)
95+
{
96+
xbps_dictionary_t pkgd;
97+
const char *pkgver = NULL, *pkgname = NULL, *repo = NULL;
98+
int r;
8199

82-
/*
83-
* Set a replaces to itself, so that virtual packages are always replaced.
84-
*/
85-
if ((replaces = xbps_dictionary_get(pkgd, "replaces")) == NULL) {
86-
replaces = xbps_array_create();
87-
if (!replaces) {
88-
xbps_error_oom();
89-
goto err;
90-
}
91-
alloc_replaces = true;
100+
assert(xhp);
101+
assert(pkgs);
102+
assert(pkgrd);
103+
104+
if (!xbps_dictionary_get_cstring_nocopy(pkgrd, "pkgver", &pkgver))
105+
xbps_unreachable();
106+
if (!xbps_dictionary_get_cstring_nocopy(pkgrd, "pkgname", &pkgname))
107+
xbps_unreachable();
108+
109+
r = transaction_replace_package(pkgs, pkgname, pkgver);
110+
if (r < 0)
111+
return r;
112+
if (r == 0)
113+
return 0;
114+
115+
pkgd = xbps_dictionary_copy_mutable(pkgrd);
116+
if (!pkgd) {
117+
xbps_object_release(pkgd);
118+
return xbps_error_oom();
92119
}
93120

94-
self_replaced = xbps_xasprintf("%s>=0", pkgname);
95-
xbps_array_add_cstring(replaces, self_replaced);
96-
free(self_replaced);
121+
if (autoinst && !xbps_dictionary_set_bool(pkgd, "automatic-install", true)) {
122+
xbps_object_release(pkgd);
123+
return xbps_error_oom();
124+
}
97125

98-
if (!xbps_dictionary_set(pkgd, "replaces", replaces)) {
99-
if (alloc_replaces)
100-
xbps_object_release(replaces);
101-
goto err;
126+
r = package_self_replace(pkgd, pkgname);
127+
if (r < 0) {
128+
xbps_object_release(pkgd);
129+
return r;
102130
}
103-
if (alloc_replaces)
104-
xbps_object_release(replaces);
105131

106-
/*
107-
* Add the dictionary into the unsorted queue.
108-
*/
109-
if (!xbps_array_add(pkgs, pkgd))
110-
goto err;
132+
if (!xbps_array_add(pkgs, pkgd)) {
133+
xbps_object_release(pkgd);
134+
return xbps_error_oom();
135+
}
111136

112137
xbps_dictionary_get_cstring_nocopy(pkgd, "repository", &repo);
113138

@@ -118,8 +143,5 @@ xbps_transaction_store(struct xbps_handle *xhp, xbps_array_t pkgs,
118143
autoinst ? " as automatic install" : "", repo);
119144
xbps_object_release(pkgd);
120145

121-
return true;
122-
err:
123-
xbps_object_release(pkgd);
124-
return false;
146+
return 0;
125147
}

0 commit comments

Comments
 (0)