ypdb.c revision 1.10
1/*	$NetBSD: ypdb.c,v 1.10 2005/06/20 00:29:42 lukem 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.10 2005/06/20 00:29:42 lukem Exp $");
42#endif
43
44#include <sys/param.h>
45#include <sys/types.h>
46
47#include <db.h>
48#include <err.h>
49#include <errno.h>
50#include <stdio.h>
51#include <string.h>
52
53#include <rpcsvc/yp.h>
54
55#include "ypdb.h"
56
57/*
58 * ypdb_open --
59 *	dbopen(3) file with the flags & mode.
60 *	First ensure that file has a suffix of YPDB_SUFFIX.
61 *	Try opening as a DB_BTREE first, then DB_HASH.
62 *
63 * Returns:
64 * 	*DBM on success
65 *	 NULL on failure
66 */
67
68DBM *
69ypdb_open(const char *file, int flags, int mode)
70{
71	char path[MAXPATHLEN];
72	const char *cp, *suffix;
73	DBM *db;
74	BTREEINFO info;
75
76	cp = strrchr(file, '.');
77	if (cp != NULL && strcmp(cp, YPDB_SUFFIX) == 0)
78		suffix = "";
79	else
80		suffix = YPDB_SUFFIX;
81	if (strlen(file) + strlen(suffix) > (sizeof(path) - 1)) {
82		warnx("File name `%s' is too long", file);
83		return (NULL);
84	}
85	snprintf(path, sizeof(path), "%s%s", file, suffix);
86
87		/* try our btree format first */
88	info.flags = 0;
89	info.cachesize = 0;
90	info.maxkeypage = 0;
91	info.minkeypage = 0;
92	info.psize = 0;
93	info.compare = NULL;
94	info.prefix = NULL;
95	info.lorder = 0;
96	db = (DBM *)dbopen(path, flags, mode, DB_BTREE, (void *)&info);
97	if (db != NULL || errno != EFTYPE)
98		return (db);
99
100		/* fallback to standard hash (for sendmail's aliases.db) */
101	db = (DBM *)dbopen(path, flags, mode, DB_HASH, NULL);
102	return (db);
103}
104
105void
106ypdb_close(DBM *db)
107{
108	(void)(db->close)(db);
109}
110
111/*
112 * Returns:
113 *	DATUM on success
114 *	NULL on failure
115 */
116
117datum
118ypdb_fetch(DBM *db, datum key)
119{
120	datum retkey;
121	DBT nk, nd;
122	int status;
123
124	nk.data = key.dptr;
125	nk.size = key.dsize;
126	status = (db->get)(db, &nk, &nd, 0);
127	if (status) {
128		retkey.dptr = NULL;
129		retkey.dsize = 0;
130	} else {
131		retkey.dptr = nd.data;
132		retkey.dsize = nd.size;
133	}
134	return (retkey);
135}
136
137/*
138 * Returns:
139 *	DATUM on success
140 *	NULL on failure
141 */
142
143datum
144ypdb_firstkey(DBM *db)
145{
146	int status;
147	datum retkey;
148	DBT nk, nd;
149
150	status = (db->seq)(db, &nk, &nd, R_FIRST);
151	if (status) {
152		retkey.dptr = NULL;
153		retkey.dsize = 0;
154	} else {
155		retkey.dptr = nk.data;
156		retkey.dsize = nk.size;
157	}
158	return (retkey);
159}
160
161/*
162 * Returns:
163 *	DATUM on success
164 *	NULL on failure
165 */
166
167datum
168ypdb_nextkey(DBM *db)
169{
170	int status;
171	datum retkey;
172	DBT nk, nd;
173
174	status = (db->seq)(db, &nk, &nd, R_NEXT);
175	if (status) {
176		retkey.dptr = NULL;
177		retkey.dsize = 0;
178	} else {
179		retkey.dptr = nk.data;
180		retkey.dsize = nk.size;
181	}
182	return (retkey);
183}
184
185/*
186 * Returns:
187 *	DATUM on success
188 *	NULL on failure
189 */
190
191datum
192ypdb_setkey(DBM *db, datum key)
193{
194	int status;
195	DBT nk, nd;
196
197	nk.data = key.dptr;
198	nk.size = key.dsize;
199	status = (db->seq)(db, &nk, &nd, R_CURSOR);
200	if (status) {
201		key.dptr = NULL;
202		key.dsize = 0;
203	}
204	return (key);
205}
206
207/*
208 * Returns:
209 *	 0 on success
210 *	<0 failure
211 */
212
213int
214ypdb_delete(DBM *db, datum key)
215{
216	int status;
217	DBT nk;
218
219	nk.data = key.dptr;
220	nk.size = key.dsize;
221	status = (db->del)(db, &nk, 0);
222	if (status)
223		return (-1);
224	else
225		return (0);
226}
227
228/*
229 * Returns:
230 *	 0 on success
231 *	<0 failure
232 *	 1 if YPDB_INSERT and entry exists
233 */
234
235int
236ypdb_store(DBM *db, datum key, datum content, int flags)
237{
238	DBT nk, nd;
239
240	if (key.dsize > YPMAXRECORD || content.dsize > YPMAXRECORD)
241		return -1;
242	nk.data = key.dptr;
243	nk.size = key.dsize;
244	nd.data = content.dptr;
245	nd.size = content.dsize;
246	return ((db->put)(db, &nk, &nd,
247	    (flags == YPDB_INSERT) ? R_NOOVERWRITE : 0));
248}
249