xref: /netbsd-src/usr.sbin/ypserv/common/ypdb.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
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 
68 DBM *
69 ypdb_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 
105 void
106 ypdb_close(DBM *db)
107 {
108 	(void)(db->close)(db);
109 }
110 
111 /*
112  * Returns:
113  *	DATUM on success
114  *	NULL on failure
115  */
116 
117 datum
118 ypdb_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 
143 datum
144 ypdb_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 
167 datum
168 ypdb_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 
191 datum
192 ypdb_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 
213 int
214 ypdb_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 
235 int
236 ypdb_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