Expand PMF_FN_* macros.
[netbsd-mini2440.git] / external / bsd / pkg_install / dist / lib / pkgdb.c
bloba72664d542a2ebca1276f2ada9c1321d5cea0b16
1 /* $NetBSD: pkgdb.c,v 1.36 2009/10/22 22:51:29 joerg Exp $ */
3 #if HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 #include <nbcompat.h>
7 #if HAVE_SYS_CDEFS_H
8 #include <sys/cdefs.h>
9 #endif
10 __RCSID("$NetBSD: pkgdb.c,v 1.36 2009/10/22 22:51:29 joerg Exp $");
12 /*-
13 * Copyright (c) 1999-2008 The NetBSD Foundation, Inc.
14 * All rights reserved.
16 * This code is derived from software contributed to The NetBSD Foundation
17 * by Hubert Feyrer <hubert@feyrer.de>.
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
41 #ifdef NETBSD
42 #include <db.h>
43 #else
44 #include <nbcompat/db.h>
45 #endif
46 #if HAVE_ERR_H
47 #include <err.h>
48 #endif
49 #if HAVE_ERRNO_H
50 #include <errno.h>
51 #endif
52 #if HAVE_FCNTL_H
53 #include <fcntl.h>
54 #endif
55 #if HAVE_STDARG_H
56 #include <stdarg.h>
57 #endif
58 #if HAVE_STDIO_H
59 #include <stdio.h>
60 #endif
61 #if HAVE_STRING_H
62 #include <string.h>
63 #endif
65 #include "lib.h"
67 #define PKGDB_FILE "pkgdb.byfile.db" /* indexed by filename */
70 * Where we put logging information by default if PKG_DBDIR is unset.
72 #ifndef DEF_LOG_DIR
73 #define DEF_LOG_DIR "/var/db/pkg"
74 #endif
76 /* just in case we change the environment variable name */
77 #define PKG_DBDIR "PKG_DBDIR"
79 static DB *pkgdbp;
80 static char *pkgdb_dir = NULL;
83 * Open the pkg-database
84 * Return value:
85 * 1: everything ok
86 * 0: error
88 int
89 pkgdb_open(int mode)
91 BTREEINFO info;
92 char cachename[MaxPathSize];
94 /* try our btree format first */
95 info.flags = 0;
96 info.cachesize = 2*1024*1024;
97 info.maxkeypage = 0;
98 info.minkeypage = 0;
99 info.psize = 4096;
100 info.compare = NULL;
101 info.prefix = NULL;
102 info.lorder = 0;
103 pkgdbp = (DB *) dbopen(_pkgdb_getPKGDB_FILE(cachename, sizeof(cachename)),
104 (mode == ReadOnly) ? O_RDONLY : O_RDWR | O_CREAT,
105 0644, DB_BTREE, (void *) &info);
106 return (pkgdbp != NULL);
110 * Close the pkg database
112 void
113 pkgdb_close(void)
115 if (pkgdbp != NULL) {
116 (void) (*pkgdbp->close) (pkgdbp);
117 pkgdbp = NULL;
122 * Store value "val" with key "key" in database
123 * Return value is as from ypdb_store:
124 * 0: ok
125 * 1: key already present
126 * -1: some other error, see errno
129 pkgdb_store(const char *key, const char *val)
131 DBT keyd, vald;
133 if (pkgdbp == NULL)
134 return -1;
136 keyd.data = __UNCONST(key);
137 keyd.size = strlen(key) + 1;
138 vald.data = __UNCONST(val);
139 vald.size = strlen(val) + 1;
141 if (keyd.size > MaxPathSize || vald.size > MaxPathSize)
142 return -1;
144 return (*pkgdbp->put) (pkgdbp, &keyd, &vald, R_NOOVERWRITE);
148 * Recall value for given key
149 * Return value:
150 * NULL if some error occurred or value for key not found (check errno!)
151 * String for "value" else
153 char *
154 pkgdb_retrieve(const char *key)
156 DBT keyd, vald;
157 int status;
159 if (pkgdbp == NULL)
160 return NULL;
162 keyd.data = __UNCONST(key);
163 keyd.size = strlen(key) + 1;
164 errno = 0; /* to be sure it's 0 if the key doesn't match anything */
166 vald.data = (void *)NULL;
167 vald.size = 0;
168 status = (*pkgdbp->get) (pkgdbp, &keyd, &vald, 0);
169 if (status) {
170 vald.data = NULL;
171 vald.size = 0;
174 return vald.data;
177 /* dump contents of the database to stdout */
179 pkgdb_dump(void)
181 DBT key;
182 DBT val;
183 int type;
185 if (pkgdb_open(ReadOnly)) {
186 for (type = R_FIRST ; (*pkgdbp->seq)(pkgdbp, &key, &val, type) == 0 ; type = R_NEXT) {
187 printf("file: %.*s pkg: %.*s\n",
188 (int) key.size, (char *) key.data,
189 (int) val.size, (char *) val.data);
191 pkgdb_close();
192 return 0;
193 } else
194 return -1;
198 * Remove data set from pkgdb
199 * Return value as ypdb_delete:
200 * 0: everything ok
201 * 1: key not present
202 * -1: some error occurred (see errno)
205 pkgdb_remove(const char *key)
207 DBT keyd;
209 if (pkgdbp == NULL)
210 return -1;
212 keyd.data = __UNCONST(key);
213 keyd.size = strlen(key) + 1;
214 if (keyd.size > MaxPathSize)
215 return -1;
217 return (*pkgdbp->del) (pkgdbp, &keyd, 0);
221 * Remove any entry from the cache which has a data field of `pkg'.
222 * Return value:
223 * 1: everything ok
224 * 0: error
227 pkgdb_remove_pkg(const char *pkg)
229 DBT data;
230 DBT key;
231 int type;
232 int ret;
233 size_t cc;
234 char cachename[MaxPathSize];
236 if (pkgdbp == NULL) {
237 return 0;
239 (void) _pkgdb_getPKGDB_FILE(cachename, sizeof(cachename));
240 cc = strlen(pkg);
241 for (ret = 1, type = R_FIRST; (*pkgdbp->seq)(pkgdbp, &key, &data, type) == 0 ; type = R_NEXT) {
242 if ((cc + 1) == data.size && strncmp(data.data, pkg, cc) == 0) {
243 if (Verbose) {
244 printf("Removing file `%s' from %s\n", (char *)key.data, cachename);
246 switch ((*pkgdbp->del)(pkgdbp, &key, 0)) {
247 case -1:
248 warn("Error removing `%s' from %s", (char *)key.data, cachename);
249 ret = 0;
250 break;
251 case 1:
252 warn("Key `%s' not present in %s", (char *)key.data, cachename);
253 ret = 0;
254 break;
259 return ret;
263 * Return the location of the package reference counts database directory.
265 char *
266 pkgdb_refcount_dir(void)
268 static char buf[MaxPathSize];
269 char *tmp;
271 if ((tmp = getenv(PKG_REFCOUNT_DBDIR_VNAME)) != NULL)
272 strlcpy(buf, tmp, sizeof(buf));
273 else
274 snprintf(buf, sizeof(buf), "%s.refcount", _pkgdb_getPKGDB_DIR());
275 return buf;
279 * Return name of cache file in the buffer that was passed.
281 char *
282 _pkgdb_getPKGDB_FILE(char *buf, unsigned size)
284 (void) snprintf(buf, size, "%s/%s", _pkgdb_getPKGDB_DIR(), PKGDB_FILE);
285 return buf;
289 * Return directory where pkgdb is stored
291 const char *
292 _pkgdb_getPKGDB_DIR(void)
294 char *tmp;
296 if (pkgdb_dir == NULL) {
297 if ((tmp = getenv(PKG_DBDIR)) != NULL)
298 _pkgdb_setPKGDB_DIR(tmp);
299 else
300 _pkgdb_setPKGDB_DIR(DEF_LOG_DIR);
303 return pkgdb_dir;
307 * Set the first place we look for where pkgdb is stored.
309 void
310 _pkgdb_setPKGDB_DIR(const char *dir)
312 char *new_dir;
314 if (dir == pkgdb_dir)
315 return;
316 new_dir = xstrdup(dir);
317 free(pkgdb_dir);
318 pkgdb_dir = new_dir;
321 char *
322 pkgdb_pkg_file(const char *pkg, const char *file)
324 return xasprintf("%s/%s/%s", _pkgdb_getPKGDB_DIR(), pkg, file);