yp_dblookup.c revision 13896
1/*
2 * Copyright (c) 1995
3 *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 *	$Id: yp_dblookup.c,v 1.2 1995/12/23 21:35:28 wpaul Exp $
33 *
34 */
35#include <stdio.h>
36#include <stdlib.h>
37#include <fcntl.h>
38#include <string.h>
39#include <limits.h>
40#include <unistd.h>
41#include <db.h>
42#include <sys/stat.h>
43#include <errno.h>
44#include <paths.h>
45#include "yp.h"
46#include "yp_extern.h"
47
48int ypdb_debug = 0;
49int yp_errno = YP_TRUE;
50
51#define PERM_SECURE (S_IRUSR|S_IWUSR)
52HASHINFO openinfo = {
53	4096,		/* bsize */
54	32,		/* ffactor */
55	256,		/* nelem */
56	2048 * 1024, 	/* cachesize */
57	NULL,		/* hash */
58	0,		/* lorder */
59};
60
61/*
62 * Open a DB database
63 */
64DB *yp_open_db(domain, map)
65	const char *domain;
66	const char *map;
67{
68	DB *dbp;
69	char buf[1025];
70
71
72	yp_errno = YP_TRUE;
73
74	if (map[0] == '.' || strchr(map, '/')) {
75		yp_errno = YP_BADARGS;
76		return (NULL);
77	}
78
79	snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, domain, map);
80
81	dbp = dbopen(buf,O_RDONLY|O_EXCL, PERM_SECURE, DB_HASH, &openinfo);
82
83	if (dbp == NULL) {
84		switch(errno) {
85		case ENOENT:
86			yp_errno = YP_NOMAP;
87			break;
88		case EFTYPE:
89			yp_errno = YP_BADDB;
90			break;
91		default:
92			yp_errno = YP_YPERR;
93			break;
94		}
95	}
96
97	return (dbp);
98}
99
100/*
101 * Database access routines.
102 *
103 * - yp_get_record(): retrieve an arbitrary key/data pair given one key
104 *                 to match against.
105 *
106 * - yp_first_record(): retrieve first key/data base in a database.
107 *
108 * - yp_next_record(): retrieve key/data pair that sequentially follows
109 *                   the supplied key value in the database.
110 */
111
112int yp_get_record(domain,map,key,data,allow)
113	const char *domain;
114	const char *map;
115	const DBT *key;
116	DBT *data;
117	int allow;
118{
119	DB *dbp;
120	int rval;
121
122	if (ypdb_debug)
123		yp_error("Looking up key [%.*s] in map [%s]",
124			  key->size, key->data, map);
125
126	/*
127	 * Avoid passing back magic "YP_*" entries unless
128	 * the caller specifically requested them by setting
129	 * the 'allow' flag.
130	 */
131	if (!allow && !strncmp(key->data, "YP_", 3))
132		return(YP_NOKEY);
133
134	if ((dbp = yp_open_db(domain, map)) == NULL) {
135		return(yp_errno);
136	}
137
138	if ((rval = (dbp->get)(dbp,key,data,0)) != 0) {
139		(void)(dbp->close)(dbp);
140		if (rval == 1)
141			return(YP_NOKEY);
142		else
143			return(YP_BADDB);
144	}
145
146	(void)(dbp->close)(dbp);
147
148	if (ypdb_debug)
149		yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
150			 key->size, key->data, data->size, data->data);
151
152	return(YP_TRUE);
153}
154
155int yp_first_record(dbp,key,data)
156	const DB *dbp;
157	DBT *key;
158	DBT *data;
159{
160	int rval;
161
162	if (ypdb_debug)
163		yp_error("Retrieving first key in map.");
164
165	if ((rval = (dbp->seq)(dbp,key,data,R_FIRST)) != 0) {
166		if (rval == 1)
167			return(YP_NOKEY);
168		else
169			return(YP_BADDB);
170	}
171
172	/* Avoid passing back magic "YP_*" records. */
173	while (!strncmp(key->data, "YP_", 3)) {
174		if ((rval = (dbp->seq)(dbp,key,data,R_NEXT)) != 0) {
175			if (rval == 1)
176				return(YP_NOKEY);
177			else
178				return(YP_BADDB);
179		}
180	}
181
182	if (ypdb_debug)
183		yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
184			 key->size, key->data, data->size, data->data);
185
186	return(YP_TRUE);
187}
188
189int yp_next_record(dbp,key,data,all)
190	const DB *dbp;
191	DBT *key;
192	DBT *data;
193	int all;
194{
195	DBT lkey, ldata;
196	int rval;
197
198	if (key == NULL || key->data == NULL) {
199		rval = yp_first_record(dbp,key,data);
200		if (rval == YP_NOKEY)
201			return(YP_NOMORE);
202		else
203			return(rval);
204	}
205
206	if (ypdb_debug)
207		yp_error("Retreiving next key, previous was: [%.*s]",
208			  key->size, key->data);
209
210	if (!all) {
211		(dbp->seq)(dbp,&lkey,&ldata,R_FIRST);
212		while(strncmp((char *)key->data,lkey.data,(int)key->size) ||
213		      key->size != lkey.size)
214			(dbp->seq)(dbp,&lkey,&ldata,R_NEXT);
215	}
216
217	if ((dbp->seq)(dbp,&lkey,&ldata,R_NEXT))
218		return(YP_NOMORE);
219
220	/* Avoid passing back magic "YP_*" records. */
221	while (!strncmp(lkey.data, "YP_", 3))
222		if ((dbp->seq)(dbp,&lkey,&ldata,R_NEXT))
223			return(YP_NOMORE);
224
225	if ((dbp->get)(dbp,&lkey,&ldata,0))
226		return(YP_FALSE);
227
228	*key = lkey;
229	*data = ldata;
230
231	if (ypdb_debug)
232		yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
233			 key->size, key->data, data->size, data->data);
234
235	return(YP_TRUE);
236}
237