1 /* $NetBSD: pkgdb.c,v 1.36 2009/10/22 22:51:29 joerg Exp $ */
10 __RCSID("$NetBSD: pkgdb.c,v 1.36 2009/10/22 22:51:29 joerg Exp $");
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
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.
44 #include <nbcompat/db.h>
67 #define PKGDB_FILE "pkgdb.byfile.db" /* indexed by filename */
70 * Where we put logging information by default if PKG_DBDIR is unset.
73 #define DEF_LOG_DIR "/var/db/pkg"
76 /* just in case we change the environment variable name */
77 #define PKG_DBDIR "PKG_DBDIR"
80 static char *pkgdb_dir
= NULL
;
83 * Open the pkg-database
92 char cachename
[MaxPathSize
];
94 /* try our btree format first */
96 info
.cachesize
= 2*1024*1024;
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
115 if (pkgdbp
!= NULL
) {
116 (void) (*pkgdbp
->close
) (pkgdbp
);
122 * Store value "val" with key "key" in database
123 * Return value is as from ypdb_store:
125 * 1: key already present
126 * -1: some other error, see errno
129 pkgdb_store(const char *key
, const char *val
)
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
)
144 return (*pkgdbp
->put
) (pkgdbp
, &keyd
, &vald
, R_NOOVERWRITE
);
148 * Recall value for given key
150 * NULL if some error occurred or value for key not found (check errno!)
151 * String for "value" else
154 pkgdb_retrieve(const char *key
)
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
;
168 status
= (*pkgdbp
->get
) (pkgdbp
, &keyd
, &vald
, 0);
177 /* dump contents of the database to stdout */
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
);
198 * Remove data set from pkgdb
199 * Return value as ypdb_delete:
202 * -1: some error occurred (see errno)
205 pkgdb_remove(const char *key
)
212 keyd
.data
= __UNCONST(key
);
213 keyd
.size
= strlen(key
) + 1;
214 if (keyd
.size
> MaxPathSize
)
217 return (*pkgdbp
->del
) (pkgdbp
, &keyd
, 0);
221 * Remove any entry from the cache which has a data field of `pkg'.
227 pkgdb_remove_pkg(const char *pkg
)
234 char cachename
[MaxPathSize
];
236 if (pkgdbp
== NULL
) {
239 (void) _pkgdb_getPKGDB_FILE(cachename
, sizeof(cachename
));
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) {
244 printf("Removing file `%s' from %s\n", (char *)key
.data
, cachename
);
246 switch ((*pkgdbp
->del
)(pkgdbp
, &key
, 0)) {
248 warn("Error removing `%s' from %s", (char *)key
.data
, cachename
);
252 warn("Key `%s' not present in %s", (char *)key
.data
, cachename
);
263 * Return the location of the package reference counts database directory.
266 pkgdb_refcount_dir(void)
268 static char buf
[MaxPathSize
];
271 if ((tmp
= getenv(PKG_REFCOUNT_DBDIR_VNAME
)) != NULL
)
272 strlcpy(buf
, tmp
, sizeof(buf
));
274 snprintf(buf
, sizeof(buf
), "%s.refcount", _pkgdb_getPKGDB_DIR());
279 * Return name of cache file in the buffer that was passed.
282 _pkgdb_getPKGDB_FILE(char *buf
, unsigned size
)
284 (void) snprintf(buf
, size
, "%s/%s", _pkgdb_getPKGDB_DIR(), PKGDB_FILE
);
289 * Return directory where pkgdb is stored
292 _pkgdb_getPKGDB_DIR(void)
296 if (pkgdb_dir
== NULL
) {
297 if ((tmp
= getenv(PKG_DBDIR
)) != NULL
)
298 _pkgdb_setPKGDB_DIR(tmp
);
300 _pkgdb_setPKGDB_DIR(DEF_LOG_DIR
);
307 * Set the first place we look for where pkgdb is stored.
310 _pkgdb_setPKGDB_DIR(const char *dir
)
314 if (dir
== pkgdb_dir
)
316 new_dir
= xstrdup(dir
);
322 pkgdb_pkg_file(const char *pkg
, const char *file
)
324 return xasprintf("%s/%s/%s", _pkgdb_getPKGDB_DIR(), pkg
, file
);