11/*-
22 * Copyright (c) 2014-2020 Juan Romero Pardines.
3+ * Copyright (c) 2025-2026 Duncan Overbruck <mail@duncano.de>.
34 * All rights reserved.
45 *
56 * Redistribution and use in source and binary forms, with or without
@@ -56,6 +57,7 @@ struct shlib_entry {
5657struct shlib_ctx {
5758 struct xbps_handle * xhp ;
5859 struct shlib_entry * entries ;
60+ struct shlib_entry * entries_32bit ;
5961 xbps_dictionary_t seen ;
6062 xbps_array_t missing ;
6163};
@@ -69,9 +71,9 @@ shlib_entry_find(struct shlib_entry *head, const char *name)
6971}
7072
7173static struct shlib_entry *
72- shlib_entry_get (struct shlib_ctx * ctx , const char * name )
74+ shlib_entry_get (struct shlib_entry * * head , const char * name )
7375{
74- struct shlib_entry * res = shlib_entry_find (ctx -> entries , name );
76+ struct shlib_entry * res = shlib_entry_find (* head , name );
7577 if (res )
7678 return res ;
7779 res = calloc (1 , sizeof (* res ));
@@ -80,25 +82,34 @@ shlib_entry_get(struct shlib_ctx *ctx, const char *name)
8082 return NULL ;
8183 }
8284 res -> name = name ;
83- HASH_ADD_STR (ctx -> entries , name , res );
85+ HASH_ADD_STR (* head , name , res );
8486 return res ;
8587}
8688
8789static int
88- collect_shlib_array (struct shlib_ctx * ctx , xbps_array_t array )
90+ collect_shlib_array (struct shlib_entry * * head , xbps_array_t array )
8991{
9092 for (unsigned int i = 0 ; i < xbps_array_count (array ); i ++ ) {
9193 struct shlib_entry * entry ;
9294 const char * shlib = NULL ;
9395 if (!xbps_array_get_cstring_nocopy (array , i , & shlib ))
9496 return - EINVAL ;
95- entry = shlib_entry_get (ctx , shlib );
97+ entry = shlib_entry_get (head , shlib );
9698 if (!entry )
9799 return - errno ;
98100 }
99101 return 0 ;
100102}
101103
104+ static bool
105+ endswith (const char * s , const char * end , size_t len )
106+ {
107+ size_t slen = strlen (s );
108+ if (slen <= len )
109+ return false;
110+ return strcmp (s + (slen - len ), end ) == 0 ;
111+ }
112+
102113static int
103114collect_shlibs (struct shlib_ctx * ctx , xbps_array_t pkgs )
104115{
@@ -134,7 +145,11 @@ collect_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
134145
135146 array = xbps_dictionary_get (pkgd , "shlib-provides" );
136147 if (array ) {
137- int r = collect_shlib_array (ctx , array );
148+ bool is32bit =
149+ endswith (pkgname , "-32bit" , sizeof ("-32bit" ) - 1 );
150+ int r = collect_shlib_array (
151+ !is32bit ? & ctx -> entries : & ctx -> entries_32bit ,
152+ array );
138153 if (r < 0 )
139154 return r ;
140155 }
@@ -161,7 +176,11 @@ collect_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
161176
162177 array = xbps_dictionary_get (pkgd , "shlib-provides" );
163178 if (array ) {
164- int r = collect_shlib_array (ctx , array );
179+ bool is32bit =
180+ endswith (pkgname , "-32bit" , sizeof ("-32bit" ) - 1 );
181+ int r = collect_shlib_array (
182+ !is32bit ? & ctx -> entries : & ctx -> entries_32bit ,
183+ array );
165184 if (r < 0 )
166185 return r ;
167186 }
@@ -174,34 +193,41 @@ collect_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
174193static int
175194check_shlibs (struct shlib_ctx * ctx , xbps_array_t pkgs )
176195{
196+ char msg [1024 ];
177197 xbps_object_iterator_t iter ;
178198 xbps_object_t obj ;
179199
180200 for (unsigned int i = 0 ; i < xbps_array_count (pkgs ); i ++ ) {
181201 xbps_array_t array ;
182202 xbps_dictionary_t pkgd = xbps_array_get (pkgs , i );
183203 xbps_trans_type_t ttype = xbps_transaction_pkg_type (pkgd );
204+ const char * pkgname = NULL ;
205+ bool is32bit ;
184206
185207 if (ttype == XBPS_TRANS_HOLD || ttype == XBPS_TRANS_REMOVE )
186208 continue ;
187209
210+ if (!xbps_dictionary_get_cstring_nocopy (pkgd , "pkgname" , & pkgname ))
211+ return - EINVAL ;
212+
213+ is32bit = endswith (pkgname , "-32bit" , sizeof ("-32bit" ) - 1 );
214+
188215 array = xbps_dictionary_get (pkgd , "shlib-requires" );
189216 if (!array )
190217 continue ;
191218 for (unsigned int j = 0 ; j < xbps_array_count (array ); j ++ ) {
192219 const char * pkgver = NULL ;
193220 const char * shlib = NULL ;
194- char * missing ;
195221 if (!xbps_array_get_cstring_nocopy (array , j , & shlib ))
196222 return - EINVAL ;
197- if (shlib_entry_find (ctx -> entries , shlib ))
223+ if (shlib_entry_find (! is32bit ? ctx -> entries : ctx -> entries_32bit , shlib ))
198224 continue ;
199225 if (!xbps_dictionary_get_cstring_nocopy (pkgd , "pkgver" , & pkgver ))
200226 return - EINVAL ;
201- missing = xbps_xasprintf (
202- "%s: broken, unresolvable shlib `%s'" ,
203- pkgver , shlib );
204- if (!xbps_array_add_cstring_nocopy (ctx -> missing , missing ))
227+ snprintf ( msg , sizeof ( msg ),
228+ "%s: broken, unresolvable shlib `%s'" , pkgver ,
229+ shlib );
230+ if (!xbps_array_add_cstring_nocopy (ctx -> missing , msg ))
205231 return xbps_error_oom ();
206232 }
207233 }
@@ -214,6 +240,7 @@ check_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
214240 xbps_array_t array ;
215241 xbps_dictionary_t pkgd ;
216242 const char * pkgname = NULL ;
243+ bool is32bit ;
217244
218245 pkgname = xbps_dictionary_keysym_cstring_nocopy (obj );
219246 /* ignore internal objs */
@@ -225,23 +252,24 @@ check_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
225252 if (xbps_dictionary_get (ctx -> seen , pkgname ))
226253 continue ;
227254
255+ is32bit = endswith (pkgname , "-32bit" , sizeof ("-32bit" ) - 1 );
256+
228257 array = xbps_dictionary_get (pkgd , "shlib-requires" );
229258 if (!array )
230259 continue ;
231260 for (unsigned int i = 0 ; i < xbps_array_count (array ); i ++ ) {
232261 const char * pkgver = NULL ;
233262 const char * shlib = NULL ;
234- char * missing ;
235263 if (!xbps_array_get_cstring_nocopy (array , i , & shlib ))
236264 return - EINVAL ;
237- if (shlib_entry_find (ctx -> entries , shlib ))
265+ if (shlib_entry_find (! is32bit ? ctx -> entries : ctx -> entries_32bit , shlib ))
238266 continue ;
239267 if (!xbps_dictionary_get_cstring_nocopy (pkgd , "pkgver" , & pkgver ))
240268 return - EINVAL ;
241- missing = xbps_xasprintf (
269+ snprintf ( msg , sizeof ( msg ),
242270 "%s: broken, unresolvable shlib `%s'" , pkgver ,
243271 shlib );
244- if (!xbps_array_add_cstring_nocopy (ctx -> missing , missing ))
272+ if (!xbps_array_add_cstring_nocopy (ctx -> missing , msg ))
245273 return xbps_error_oom ();
246274 }
247275 }
@@ -276,6 +304,10 @@ xbps_transaction_check_shlibs(struct xbps_handle *xhp, xbps_array_t pkgs)
276304 HASH_DEL (ctx .entries , entry );
277305 free (entry );
278306 }
307+ HASH_ITER (hh , ctx .entries_32bit , entry , tmp ) {
308+ HASH_DEL (ctx .entries_32bit , entry );
309+ free (entry );
310+ }
279311 if (ctx .seen )
280312 xbps_object_release (ctx .seen );
281313 return r == 0 ;
0 commit comments