xref: /minix/external/bsd/pkg_install/dist/lib/pkgdb.c (revision a824f5a1)
1*a824f5a1SJean-Baptiste Boric /*	$NetBSD: pkgdb.c,v 1.1.1.8 2010/04/23 20:54:11 joerg Exp $	*/
2*a824f5a1SJean-Baptiste Boric 
3*a824f5a1SJean-Baptiste Boric #if HAVE_CONFIG_H
4*a824f5a1SJean-Baptiste Boric #include "config.h"
5*a824f5a1SJean-Baptiste Boric #endif
6*a824f5a1SJean-Baptiste Boric #include <nbcompat.h>
7*a824f5a1SJean-Baptiste Boric #if HAVE_SYS_CDEFS_H
8*a824f5a1SJean-Baptiste Boric #include <sys/cdefs.h>
9*a824f5a1SJean-Baptiste Boric #endif
10*a824f5a1SJean-Baptiste Boric __RCSID("$NetBSD: pkgdb.c,v 1.1.1.8 2010/04/23 20:54:11 joerg Exp $");
11*a824f5a1SJean-Baptiste Boric 
12*a824f5a1SJean-Baptiste Boric /*-
13*a824f5a1SJean-Baptiste Boric  * Copyright (c) 1999-2010 The NetBSD Foundation, Inc.
14*a824f5a1SJean-Baptiste Boric  * All rights reserved.
15*a824f5a1SJean-Baptiste Boric  *
16*a824f5a1SJean-Baptiste Boric  * This code is derived from software contributed to The NetBSD Foundation
17*a824f5a1SJean-Baptiste Boric  * by Hubert Feyrer <hubert@feyrer.de>.
18*a824f5a1SJean-Baptiste Boric  *
19*a824f5a1SJean-Baptiste Boric  * Redistribution and use in source and binary forms, with or without
20*a824f5a1SJean-Baptiste Boric  * modification, are permitted provided that the following conditions
21*a824f5a1SJean-Baptiste Boric  * are met:
22*a824f5a1SJean-Baptiste Boric  * 1. Redistributions of source code must retain the above copyright
23*a824f5a1SJean-Baptiste Boric  *    notice, this list of conditions and the following disclaimer.
24*a824f5a1SJean-Baptiste Boric  * 2. Redistributions in binary form must reproduce the above copyright
25*a824f5a1SJean-Baptiste Boric  *    notice, this list of conditions and the following disclaimer in the
26*a824f5a1SJean-Baptiste Boric  *    documentation and/or other materials provided with the distribution.
27*a824f5a1SJean-Baptiste Boric  *
28*a824f5a1SJean-Baptiste Boric  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29*a824f5a1SJean-Baptiste Boric  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30*a824f5a1SJean-Baptiste Boric  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31*a824f5a1SJean-Baptiste Boric  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32*a824f5a1SJean-Baptiste Boric  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33*a824f5a1SJean-Baptiste Boric  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34*a824f5a1SJean-Baptiste Boric  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35*a824f5a1SJean-Baptiste Boric  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36*a824f5a1SJean-Baptiste Boric  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37*a824f5a1SJean-Baptiste Boric  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38*a824f5a1SJean-Baptiste Boric  * POSSIBILITY OF SUCH DAMAGE.
39*a824f5a1SJean-Baptiste Boric  */
40*a824f5a1SJean-Baptiste Boric 
41*a824f5a1SJean-Baptiste Boric #ifdef NETBSD
42*a824f5a1SJean-Baptiste Boric #include <db.h>
43*a824f5a1SJean-Baptiste Boric #else
44*a824f5a1SJean-Baptiste Boric #include <nbcompat/db.h>
45*a824f5a1SJean-Baptiste Boric #endif
46*a824f5a1SJean-Baptiste Boric #if HAVE_ERR_H
47*a824f5a1SJean-Baptiste Boric #include <err.h>
48*a824f5a1SJean-Baptiste Boric #endif
49*a824f5a1SJean-Baptiste Boric #if HAVE_ERRNO_H
50*a824f5a1SJean-Baptiste Boric #include <errno.h>
51*a824f5a1SJean-Baptiste Boric #endif
52*a824f5a1SJean-Baptiste Boric #if HAVE_FCNTL_H
53*a824f5a1SJean-Baptiste Boric #include <fcntl.h>
54*a824f5a1SJean-Baptiste Boric #endif
55*a824f5a1SJean-Baptiste Boric #if HAVE_STDARG_H
56*a824f5a1SJean-Baptiste Boric #include <stdarg.h>
57*a824f5a1SJean-Baptiste Boric #endif
58*a824f5a1SJean-Baptiste Boric #if HAVE_STDIO_H
59*a824f5a1SJean-Baptiste Boric #include <stdio.h>
60*a824f5a1SJean-Baptiste Boric #endif
61*a824f5a1SJean-Baptiste Boric #if HAVE_STRING_H
62*a824f5a1SJean-Baptiste Boric #include <string.h>
63*a824f5a1SJean-Baptiste Boric #endif
64*a824f5a1SJean-Baptiste Boric 
65*a824f5a1SJean-Baptiste Boric #include "lib.h"
66*a824f5a1SJean-Baptiste Boric 
67*a824f5a1SJean-Baptiste Boric #define PKGDB_FILE	"pkgdb.byfile.db"	/* indexed by filename */
68*a824f5a1SJean-Baptiste Boric 
69*a824f5a1SJean-Baptiste Boric /*
70*a824f5a1SJean-Baptiste Boric  * Where we put logging information by default if PKG_DBDIR is unset.
71*a824f5a1SJean-Baptiste Boric  */
72*a824f5a1SJean-Baptiste Boric #ifndef DEF_LOG_DIR
73*a824f5a1SJean-Baptiste Boric #define DEF_LOG_DIR		"/var/db/pkg"
74*a824f5a1SJean-Baptiste Boric #endif
75*a824f5a1SJean-Baptiste Boric 
76*a824f5a1SJean-Baptiste Boric /* just in case we change the environment variable name */
77*a824f5a1SJean-Baptiste Boric #define PKG_DBDIR		"PKG_DBDIR"
78*a824f5a1SJean-Baptiste Boric 
79*a824f5a1SJean-Baptiste Boric static DB   *pkgdbp;
80*a824f5a1SJean-Baptiste Boric static char pkgdb_dir_default[] = DEF_LOG_DIR;
81*a824f5a1SJean-Baptiste Boric static char *pkgdb_dir = pkgdb_dir_default;
82*a824f5a1SJean-Baptiste Boric static int pkgdb_dir_prio = 0;
83*a824f5a1SJean-Baptiste Boric 
84*a824f5a1SJean-Baptiste Boric /*
85*a824f5a1SJean-Baptiste Boric  *  Return name of cache file in the buffer that was passed.
86*a824f5a1SJean-Baptiste Boric  */
87*a824f5a1SJean-Baptiste Boric char *
pkgdb_get_database(void)88*a824f5a1SJean-Baptiste Boric pkgdb_get_database(void)
89*a824f5a1SJean-Baptiste Boric {
90*a824f5a1SJean-Baptiste Boric 	return xasprintf("%s/%s", pkgdb_get_dir(), PKGDB_FILE);
91*a824f5a1SJean-Baptiste Boric }
92*a824f5a1SJean-Baptiste Boric 
93*a824f5a1SJean-Baptiste Boric /*
94*a824f5a1SJean-Baptiste Boric  *  Open the pkg-database
95*a824f5a1SJean-Baptiste Boric  *  Return value:
96*a824f5a1SJean-Baptiste Boric  *   1: everything ok
97*a824f5a1SJean-Baptiste Boric  *   0: error
98*a824f5a1SJean-Baptiste Boric  */
99*a824f5a1SJean-Baptiste Boric int
pkgdb_open(int mode)100*a824f5a1SJean-Baptiste Boric pkgdb_open(int mode)
101*a824f5a1SJean-Baptiste Boric {
102*a824f5a1SJean-Baptiste Boric 	BTREEINFO info;
103*a824f5a1SJean-Baptiste Boric 	char *cachename;
104*a824f5a1SJean-Baptiste Boric 
105*a824f5a1SJean-Baptiste Boric 	/* try our btree format first */
106*a824f5a1SJean-Baptiste Boric 	info.flags = 0;
107*a824f5a1SJean-Baptiste Boric 	info.cachesize = 2*1024*1024;
108*a824f5a1SJean-Baptiste Boric 	info.maxkeypage = 0;
109*a824f5a1SJean-Baptiste Boric 	info.minkeypage = 0;
110*a824f5a1SJean-Baptiste Boric 	info.psize = 4096;
111*a824f5a1SJean-Baptiste Boric 	info.compare = NULL;
112*a824f5a1SJean-Baptiste Boric 	info.prefix = NULL;
113*a824f5a1SJean-Baptiste Boric 	info.lorder = 0;
114*a824f5a1SJean-Baptiste Boric 	cachename = pkgdb_get_database();
115*a824f5a1SJean-Baptiste Boric 	pkgdbp = (DB *) dbopen(cachename,
116*a824f5a1SJean-Baptiste Boric 	    (mode == ReadOnly) ? O_RDONLY : O_RDWR | O_CREAT,
117*a824f5a1SJean-Baptiste Boric 	    0644, DB_BTREE, (void *) &info);
118*a824f5a1SJean-Baptiste Boric 	free(cachename);
119*a824f5a1SJean-Baptiste Boric 	return (pkgdbp != NULL);
120*a824f5a1SJean-Baptiste Boric }
121*a824f5a1SJean-Baptiste Boric 
122*a824f5a1SJean-Baptiste Boric /*
123*a824f5a1SJean-Baptiste Boric  * Close the pkg database
124*a824f5a1SJean-Baptiste Boric  */
125*a824f5a1SJean-Baptiste Boric void
pkgdb_close(void)126*a824f5a1SJean-Baptiste Boric pkgdb_close(void)
127*a824f5a1SJean-Baptiste Boric {
128*a824f5a1SJean-Baptiste Boric 	if (pkgdbp != NULL) {
129*a824f5a1SJean-Baptiste Boric 		(void) (*pkgdbp->close) (pkgdbp);
130*a824f5a1SJean-Baptiste Boric 		pkgdbp = NULL;
131*a824f5a1SJean-Baptiste Boric 	}
132*a824f5a1SJean-Baptiste Boric }
133*a824f5a1SJean-Baptiste Boric 
134*a824f5a1SJean-Baptiste Boric /*
135*a824f5a1SJean-Baptiste Boric  * Store value "val" with key "key" in database
136*a824f5a1SJean-Baptiste Boric  * Return value is as from ypdb_store:
137*a824f5a1SJean-Baptiste Boric  *  0: ok
138*a824f5a1SJean-Baptiste Boric  *  1: key already present
139*a824f5a1SJean-Baptiste Boric  * -1: some other error, see errno
140*a824f5a1SJean-Baptiste Boric  */
141*a824f5a1SJean-Baptiste Boric int
pkgdb_store(const char * key,const char * val)142*a824f5a1SJean-Baptiste Boric pkgdb_store(const char *key, const char *val)
143*a824f5a1SJean-Baptiste Boric {
144*a824f5a1SJean-Baptiste Boric 	DBT     keyd, vald;
145*a824f5a1SJean-Baptiste Boric 
146*a824f5a1SJean-Baptiste Boric 	if (pkgdbp == NULL)
147*a824f5a1SJean-Baptiste Boric 		return -1;
148*a824f5a1SJean-Baptiste Boric 
149*a824f5a1SJean-Baptiste Boric 	keyd.data = __UNCONST(key);
150*a824f5a1SJean-Baptiste Boric 	keyd.size = strlen(key) + 1;
151*a824f5a1SJean-Baptiste Boric 	vald.data = __UNCONST(val);
152*a824f5a1SJean-Baptiste Boric 	vald.size = strlen(val) + 1;
153*a824f5a1SJean-Baptiste Boric 
154*a824f5a1SJean-Baptiste Boric 	if (keyd.size > MaxPathSize || vald.size > MaxPathSize)
155*a824f5a1SJean-Baptiste Boric 		return -1;
156*a824f5a1SJean-Baptiste Boric 
157*a824f5a1SJean-Baptiste Boric 	return (*pkgdbp->put) (pkgdbp, &keyd, &vald, R_NOOVERWRITE);
158*a824f5a1SJean-Baptiste Boric }
159*a824f5a1SJean-Baptiste Boric 
160*a824f5a1SJean-Baptiste Boric /*
161*a824f5a1SJean-Baptiste Boric  * Recall value for given key
162*a824f5a1SJean-Baptiste Boric  * Return value:
163*a824f5a1SJean-Baptiste Boric  *  NULL if some error occurred or value for key not found (check errno!)
164*a824f5a1SJean-Baptiste Boric  *  String for "value" else
165*a824f5a1SJean-Baptiste Boric  */
166*a824f5a1SJean-Baptiste Boric char   *
pkgdb_retrieve(const char * key)167*a824f5a1SJean-Baptiste Boric pkgdb_retrieve(const char *key)
168*a824f5a1SJean-Baptiste Boric {
169*a824f5a1SJean-Baptiste Boric 	DBT     keyd, vald;
170*a824f5a1SJean-Baptiste Boric 	int     status;
171*a824f5a1SJean-Baptiste Boric 	char	*eos;
172*a824f5a1SJean-Baptiste Boric 	static int corruption_warning;
173*a824f5a1SJean-Baptiste Boric 
174*a824f5a1SJean-Baptiste Boric 	if (pkgdbp == NULL)
175*a824f5a1SJean-Baptiste Boric 		return NULL;
176*a824f5a1SJean-Baptiste Boric 
177*a824f5a1SJean-Baptiste Boric 	keyd.data = __UNCONST(key);
178*a824f5a1SJean-Baptiste Boric 	keyd.size = strlen(key) + 1;
179*a824f5a1SJean-Baptiste Boric 	errno = 0;		/* to be sure it's 0 if the key doesn't match anything */
180*a824f5a1SJean-Baptiste Boric 
181*a824f5a1SJean-Baptiste Boric 	vald.data = (void *)NULL;
182*a824f5a1SJean-Baptiste Boric 	vald.size = 0;
183*a824f5a1SJean-Baptiste Boric 	status = (*pkgdbp->get) (pkgdbp, &keyd, &vald, 0);
184*a824f5a1SJean-Baptiste Boric 	if (status)
185*a824f5a1SJean-Baptiste Boric 		return NULL;
186*a824f5a1SJean-Baptiste Boric 	eos = memchr(vald.data, 0, vald.size);
187*a824f5a1SJean-Baptiste Boric 	if (eos == NULL || eos + 1 != (char *)vald.data + vald.size) {
188*a824f5a1SJean-Baptiste Boric 		if (!corruption_warning) {
189*a824f5a1SJean-Baptiste Boric 			warnx("pkgdb corrupted, please run ``pkg_admin rebuild''");
190*a824f5a1SJean-Baptiste Boric 			corruption_warning = 1;
191*a824f5a1SJean-Baptiste Boric 		}
192*a824f5a1SJean-Baptiste Boric 		return NULL;
193*a824f5a1SJean-Baptiste Boric 	}
194*a824f5a1SJean-Baptiste Boric 
195*a824f5a1SJean-Baptiste Boric 	return vald.data;
196*a824f5a1SJean-Baptiste Boric }
197*a824f5a1SJean-Baptiste Boric 
198*a824f5a1SJean-Baptiste Boric /* dump contents of the database to stdout */
199*a824f5a1SJean-Baptiste Boric int
pkgdb_dump(void)200*a824f5a1SJean-Baptiste Boric pkgdb_dump(void)
201*a824f5a1SJean-Baptiste Boric {
202*a824f5a1SJean-Baptiste Boric 	DBT     key;
203*a824f5a1SJean-Baptiste Boric 	DBT	val;
204*a824f5a1SJean-Baptiste Boric 	int	type;
205*a824f5a1SJean-Baptiste Boric 
206*a824f5a1SJean-Baptiste Boric 	if (pkgdb_open(ReadOnly)) {
207*a824f5a1SJean-Baptiste Boric 		for (type = R_FIRST ; (*pkgdbp->seq)(pkgdbp, &key, &val, type) == 0 ; type = R_NEXT) {
208*a824f5a1SJean-Baptiste Boric 			printf("file: %.*s pkg: %.*s\n",
209*a824f5a1SJean-Baptiste Boric 				(int) key.size, (char *) key.data,
210*a824f5a1SJean-Baptiste Boric 				(int) val.size, (char *) val.data);
211*a824f5a1SJean-Baptiste Boric 		}
212*a824f5a1SJean-Baptiste Boric 		pkgdb_close();
213*a824f5a1SJean-Baptiste Boric 		return 0;
214*a824f5a1SJean-Baptiste Boric 	} else
215*a824f5a1SJean-Baptiste Boric 		return -1;
216*a824f5a1SJean-Baptiste Boric }
217*a824f5a1SJean-Baptiste Boric 
218*a824f5a1SJean-Baptiste Boric /*
219*a824f5a1SJean-Baptiste Boric  *  Remove data set from pkgdb
220*a824f5a1SJean-Baptiste Boric  *  Return value as ypdb_delete:
221*a824f5a1SJean-Baptiste Boric  *   0: everything ok
222*a824f5a1SJean-Baptiste Boric  *   1: key not present
223*a824f5a1SJean-Baptiste Boric  *  -1: some error occurred (see errno)
224*a824f5a1SJean-Baptiste Boric  */
225*a824f5a1SJean-Baptiste Boric int
pkgdb_remove(const char * key)226*a824f5a1SJean-Baptiste Boric pkgdb_remove(const char *key)
227*a824f5a1SJean-Baptiste Boric {
228*a824f5a1SJean-Baptiste Boric 	DBT     keyd;
229*a824f5a1SJean-Baptiste Boric 
230*a824f5a1SJean-Baptiste Boric 	if (pkgdbp == NULL)
231*a824f5a1SJean-Baptiste Boric 		return -1;
232*a824f5a1SJean-Baptiste Boric 
233*a824f5a1SJean-Baptiste Boric 	keyd.data = __UNCONST(key);
234*a824f5a1SJean-Baptiste Boric 	keyd.size = strlen(key) + 1;
235*a824f5a1SJean-Baptiste Boric 	if (keyd.size > MaxPathSize)
236*a824f5a1SJean-Baptiste Boric 		return -1;
237*a824f5a1SJean-Baptiste Boric 
238*a824f5a1SJean-Baptiste Boric 	return (*pkgdbp->del) (pkgdbp, &keyd, 0);
239*a824f5a1SJean-Baptiste Boric }
240*a824f5a1SJean-Baptiste Boric 
241*a824f5a1SJean-Baptiste Boric /*
242*a824f5a1SJean-Baptiste Boric  *  Remove any entry from the cache which has a data field of `pkg'.
243*a824f5a1SJean-Baptiste Boric  *  Return value:
244*a824f5a1SJean-Baptiste Boric  *   1: everything ok
245*a824f5a1SJean-Baptiste Boric  *   0: error
246*a824f5a1SJean-Baptiste Boric  */
247*a824f5a1SJean-Baptiste Boric int
pkgdb_remove_pkg(const char * pkg)248*a824f5a1SJean-Baptiste Boric pkgdb_remove_pkg(const char *pkg)
249*a824f5a1SJean-Baptiste Boric {
250*a824f5a1SJean-Baptiste Boric 	DBT     data;
251*a824f5a1SJean-Baptiste Boric 	DBT     key;
252*a824f5a1SJean-Baptiste Boric 	int	type;
253*a824f5a1SJean-Baptiste Boric 	int	ret;
254*a824f5a1SJean-Baptiste Boric 	size_t	cc;
255*a824f5a1SJean-Baptiste Boric 	char	*cachename;
256*a824f5a1SJean-Baptiste Boric 
257*a824f5a1SJean-Baptiste Boric 	if (pkgdbp == NULL) {
258*a824f5a1SJean-Baptiste Boric 		return 0;
259*a824f5a1SJean-Baptiste Boric 	}
260*a824f5a1SJean-Baptiste Boric 	cachename = pkgdb_get_database();
261*a824f5a1SJean-Baptiste Boric 	cc = strlen(pkg);
262*a824f5a1SJean-Baptiste Boric 	for (ret = 1, type = R_FIRST; (*pkgdbp->seq)(pkgdbp, &key, &data, type) == 0 ; type = R_NEXT) {
263*a824f5a1SJean-Baptiste Boric 		if ((cc + 1) == data.size && strncmp(data.data, pkg, cc) == 0) {
264*a824f5a1SJean-Baptiste Boric 			if (Verbose) {
265*a824f5a1SJean-Baptiste Boric 				printf("Removing file `%s' from %s\n", (char *)key.data, cachename);
266*a824f5a1SJean-Baptiste Boric 			}
267*a824f5a1SJean-Baptiste Boric 			switch ((*pkgdbp->del)(pkgdbp, &key, 0)) {
268*a824f5a1SJean-Baptiste Boric 			case -1:
269*a824f5a1SJean-Baptiste Boric 				warn("Error removing `%s' from %s", (char *)key.data, cachename);
270*a824f5a1SJean-Baptiste Boric 				ret = 0;
271*a824f5a1SJean-Baptiste Boric 				break;
272*a824f5a1SJean-Baptiste Boric 			case 1:
273*a824f5a1SJean-Baptiste Boric 				warn("Key `%s' not present in %s", (char *)key.data, cachename);
274*a824f5a1SJean-Baptiste Boric 				ret = 0;
275*a824f5a1SJean-Baptiste Boric 				break;
276*a824f5a1SJean-Baptiste Boric 
277*a824f5a1SJean-Baptiste Boric 			}
278*a824f5a1SJean-Baptiste Boric 		}
279*a824f5a1SJean-Baptiste Boric 	}
280*a824f5a1SJean-Baptiste Boric 	free(cachename);
281*a824f5a1SJean-Baptiste Boric 	return ret;
282*a824f5a1SJean-Baptiste Boric }
283*a824f5a1SJean-Baptiste Boric 
284*a824f5a1SJean-Baptiste Boric /*
285*a824f5a1SJean-Baptiste Boric  *  Return the location of the package reference counts database directory.
286*a824f5a1SJean-Baptiste Boric  */
287*a824f5a1SJean-Baptiste Boric char *
pkgdb_refcount_dir(void)288*a824f5a1SJean-Baptiste Boric pkgdb_refcount_dir(void)
289*a824f5a1SJean-Baptiste Boric {
290*a824f5a1SJean-Baptiste Boric 	static char buf[MaxPathSize];
291*a824f5a1SJean-Baptiste Boric 	char *tmp;
292*a824f5a1SJean-Baptiste Boric 
293*a824f5a1SJean-Baptiste Boric 	if ((tmp = getenv(PKG_REFCOUNT_DBDIR_VNAME)) != NULL)
294*a824f5a1SJean-Baptiste Boric 		strlcpy(buf, tmp, sizeof(buf));
295*a824f5a1SJean-Baptiste Boric 	else
296*a824f5a1SJean-Baptiste Boric 		snprintf(buf, sizeof(buf), "%s.refcount", pkgdb_get_dir());
297*a824f5a1SJean-Baptiste Boric 	return buf;
298*a824f5a1SJean-Baptiste Boric }
299*a824f5a1SJean-Baptiste Boric 
300*a824f5a1SJean-Baptiste Boric /*
301*a824f5a1SJean-Baptiste Boric  *  Return directory where pkgdb is stored
302*a824f5a1SJean-Baptiste Boric  */
303*a824f5a1SJean-Baptiste Boric const char *
pkgdb_get_dir(void)304*a824f5a1SJean-Baptiste Boric pkgdb_get_dir(void)
305*a824f5a1SJean-Baptiste Boric {
306*a824f5a1SJean-Baptiste Boric 
307*a824f5a1SJean-Baptiste Boric 	return pkgdb_dir;
308*a824f5a1SJean-Baptiste Boric }
309*a824f5a1SJean-Baptiste Boric 
310*a824f5a1SJean-Baptiste Boric /*
311*a824f5a1SJean-Baptiste Boric  *  Set the first place we look for where pkgdb is stored.
312*a824f5a1SJean-Baptiste Boric  */
313*a824f5a1SJean-Baptiste Boric void
pkgdb_set_dir(const char * dir,int prio)314*a824f5a1SJean-Baptiste Boric pkgdb_set_dir(const char *dir, int prio)
315*a824f5a1SJean-Baptiste Boric {
316*a824f5a1SJean-Baptiste Boric 
317*a824f5a1SJean-Baptiste Boric 	if (prio < pkgdb_dir_prio)
318*a824f5a1SJean-Baptiste Boric 		return;
319*a824f5a1SJean-Baptiste Boric 
320*a824f5a1SJean-Baptiste Boric 	pkgdb_dir_prio = prio;
321*a824f5a1SJean-Baptiste Boric 
322*a824f5a1SJean-Baptiste Boric 	if (dir == pkgdb_dir)
323*a824f5a1SJean-Baptiste Boric 		return;
324*a824f5a1SJean-Baptiste Boric 	if (pkgdb_dir != pkgdb_dir_default)
325*a824f5a1SJean-Baptiste Boric 		free(pkgdb_dir);
326*a824f5a1SJean-Baptiste Boric 	pkgdb_dir = xstrdup(dir);
327*a824f5a1SJean-Baptiste Boric }
328*a824f5a1SJean-Baptiste Boric 
329*a824f5a1SJean-Baptiste Boric char *
pkgdb_pkg_dir(const char * pkg)330*a824f5a1SJean-Baptiste Boric pkgdb_pkg_dir(const char *pkg)
331*a824f5a1SJean-Baptiste Boric {
332*a824f5a1SJean-Baptiste Boric 	return xasprintf("%s/%s", pkgdb_get_dir(), pkg);
333*a824f5a1SJean-Baptiste Boric }
334*a824f5a1SJean-Baptiste Boric 
335*a824f5a1SJean-Baptiste Boric char *
pkgdb_pkg_file(const char * pkg,const char * file)336*a824f5a1SJean-Baptiste Boric pkgdb_pkg_file(const char *pkg, const char *file)
337*a824f5a1SJean-Baptiste Boric {
338*a824f5a1SJean-Baptiste Boric 	return xasprintf("%s/%s/%s", pkgdb_get_dir(), pkg, file);
339*a824f5a1SJean-Baptiste Boric }
340