ypdb.c revision 1.9
1/*	$NetBSD: ypdb.c,v 1.9 2003/08/07 11:25:50 agc Exp $	*/
2
3/*
4 * Copyright (c) 1990, 1993
5 *	The Regents of the University of California.  All rights reserved.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * Margo Seltzer.
10 *
11 * This code is derived from ndbm module of BSD4.4 db (hash) by
12 * Mats O Jansson
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
27 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
30 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
39#include <sys/cdefs.h>
40#ifndef lint
41__RCSID("$NetBSD: ypdb.c,v 1.9 2003/08/07 11:25:50 agc Exp $");
42#endif
43
44#include <sys/param.h>
45#include <sys/types.h>
46
47#include <db.h>
48#include <errno.h>
49#include <stdio.h>
50#include <string.h>
51
52#include <rpcsvc/yp.h>
53
54#include "ypdb.h"
55
56/*
57 * Returns:
58 * 	*DBM on success
59 *	 NULL on failure
60 */
61
62DBM *
63ypdb_open(const char *file, int flags, int mode)
64{
65	char path[MAXPATHLEN], *cp;
66	DBM *db;
67	BTREEINFO info;
68
69	cp = strrchr(file, '.');
70	snprintf(path, sizeof(path), "%s%s", file,
71	    (cp != NULL && strcmp(cp, ".db") == 0) ? "" : YPDB_SUFFIX);
72
73		/* try our btree format first */
74	info.flags = 0;
75	info.cachesize = 0;
76	info.maxkeypage = 0;
77	info.minkeypage = 0;
78	info.psize = 0;
79	info.compare = NULL;
80	info.prefix = NULL;
81	info.lorder = 0;
82	db = (DBM *)dbopen(path, flags, mode, DB_BTREE, (void *)&info);
83	if (db != NULL || errno != EFTYPE)
84		return (db);
85
86		/* fallback to standard hash (for sendmail's aliases.db) */
87	db = (DBM *)dbopen(path, flags, mode, DB_HASH, NULL);
88	return (db);
89}
90
91void
92ypdb_close(DBM *db)
93{
94	(void)(db->close)(db);
95}
96
97/*
98 * Returns:
99 *	DATUM on success
100 *	NULL on failure
101 */
102
103datum
104ypdb_fetch(DBM *db, datum key)
105{
106	datum retkey;
107	DBT nk, nd;
108	int status;
109
110	nk.data = key.dptr;
111	nk.size = key.dsize;
112	status = (db->get)(db, &nk, &nd, 0);
113	if (status) {
114		retkey.dptr = NULL;
115		retkey.dsize = 0;
116	} else {
117		retkey.dptr = nd.data;
118		retkey.dsize = nd.size;
119	}
120	return (retkey);
121}
122
123/*
124 * Returns:
125 *	DATUM on success
126 *	NULL on failure
127 */
128
129datum
130ypdb_firstkey(DBM *db)
131{
132	int status;
133	datum retkey;
134	DBT nk, nd;
135
136	status = (db->seq)(db, &nk, &nd, R_FIRST);
137	if (status) {
138		retkey.dptr = NULL;
139		retkey.dsize = 0;
140	} else {
141		retkey.dptr = nk.data;
142		retkey.dsize = nk.size;
143	}
144	return (retkey);
145}
146
147/*
148 * Returns:
149 *	DATUM on success
150 *	NULL on failure
151 */
152
153datum
154ypdb_nextkey(DBM *db)
155{
156	int status;
157	datum retkey;
158	DBT nk, nd;
159
160	status = (db->seq)(db, &nk, &nd, R_NEXT);
161	if (status) {
162		retkey.dptr = NULL;
163		retkey.dsize = 0;
164	} else {
165		retkey.dptr = nk.data;
166		retkey.dsize = nk.size;
167	}
168	return (retkey);
169}
170
171/*
172 * Returns:
173 *	DATUM on success
174 *	NULL on failure
175 */
176
177datum
178ypdb_setkey(DBM *db, datum key)
179{
180	int status;
181	DBT nk, nd;
182
183	nk.data = key.dptr;
184	nk.size = key.dsize;
185	status = (db->seq)(db, &nk, &nd, R_CURSOR);
186	if (status) {
187		key.dptr = NULL;
188		key.dsize = 0;
189	}
190	return (key);
191}
192
193/*
194 * Returns:
195 *	 0 on success
196 *	<0 failure
197 */
198
199int
200ypdb_delete(DBM *db, datum key)
201{
202	int status;
203	DBT nk;
204
205	nk.data = key.dptr;
206	nk.size = key.dsize;
207	status = (db->del)(db, &nk, 0);
208	if (status)
209		return (-1);
210	else
211		return (0);
212}
213
214/*
215 * Returns:
216 *	 0 on success
217 *	<0 failure
218 *	 1 if YPDB_INSERT and entry exists
219 */
220
221int
222ypdb_store(DBM *db, datum key, datum content, int flags)
223{
224	DBT nk, nd;
225
226	if (key.dsize > YPMAXRECORD || content.dsize > YPMAXRECORD)
227		return -1;
228	nk.data = key.dptr;
229	nk.size = key.dsize;
230	nd.data = content.dptr;
231	nd.size = content.dsize;
232	return ((db->put)(db, &nk, &nd,
233	    (flags == YPDB_INSERT) ? R_NOOVERWRITE : 0));
234}
235