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
62 DBM *
63 ypdb_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
91 void
92 ypdb_close(DBM *db)
93 {
94 (void)(db->close)(db);
95 }
96
97 /*
98 * Returns:
99 * DATUM on success
100 * NULL on failure
101 */
102
103 datum
104 ypdb_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
129 datum
130 ypdb_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
153 datum
154 ypdb_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
177 datum
178 ypdb_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
199 int
200 ypdb_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
221 int
222 ypdb_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