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
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