yp_dblookup.c revision 12997
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.1.1.1 1995/12/16 20:54:17 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
121	if (ypdb_debug)
122		yp_error("Looking up key [%.*s] in map [%s]",
123			  key->size, key->data, map);
124
125	/*
126	 * Avoid passing back magic "YP_*" entries unless
127	 * the caller specifically requested them by setting
128	 * the 'allow' flag.
129	 */
130	if (!allow && !strncmp(key->data, "YP_", 3))
131		return(YP_NOKEY);
132
133	if ((dbp = yp_open_db(domain, map)) == NULL) {
134		return(yp_errno);
135	}
136
137	if ((dbp->get)(dbp,key,data,0)) {
138		(void)(dbp->close)(dbp);
139		return(YP_NOKEY);
140	}
141
142	(void)(dbp->close)(dbp);
143
144	if (ypdb_debug)
145		yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
146			 key->size, key->data, data->size, data->data);
147
148	return(YP_TRUE);
149}
150
151int yp_first_record(dbp,key,data)
152	const DB *dbp;
153	DBT *key;
154	DBT *data;
155{
156
157	if (ypdb_debug)
158		yp_error("Retrieving first key in map.");
159
160	if ((dbp->seq)(dbp,key,data,R_FIRST))
161		return(YP_BADDB);
162
163	/* Avoid passing back magic "YP_*" records. */
164	while (!strncmp(key->data, "YP_", 3)) {
165		if ((dbp->seq)(dbp,key,data,R_NEXT))
166			return(YP_BADDB);
167	}
168
169	if (ypdb_debug)
170		yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
171			 key->size, key->data, data->size, data->data);
172
173	return(YP_TRUE);
174}
175
176int yp_next_record(dbp,key,data,all)
177	const DB *dbp;
178	DBT *key;
179	DBT *data;
180	int all;
181{
182	DBT lkey, ldata;
183
184	if (key == NULL || key->data == NULL)
185		return(yp_first_record(dbp,key,data));
186
187	if (ypdb_debug)
188		yp_error("Retreiving next key, previous was: [%.*s]",
189			  key->size, key->data);
190
191	if (!all) {
192		(dbp->seq)(dbp,&lkey,&ldata,R_FIRST);
193		while(strncmp((char *)key->data,lkey.data,(int)key->size) ||
194		      key->size != lkey.size)
195			(dbp->seq)(dbp,&lkey,&ldata,R_NEXT);
196	}
197
198	if ((dbp->seq)(dbp,&lkey,&ldata,R_NEXT))
199		return(YP_NOMORE);
200
201	/* Avoid passing back magic "YP_*" records. */
202	while (!strncmp(lkey.data, "YP_", 3))
203		if ((dbp->seq)(dbp,&lkey,&ldata,R_NEXT))
204			return(YP_NOMORE);
205
206	if ((dbp->get)(dbp,&lkey,&ldata,0))
207		return(YP_FALSE);
208
209	*key = lkey;
210	*data = ldata;
211
212	if (ypdb_debug)
213		yp_error("Result of lookup: key: [%.*s] data: [%.*s]",
214			 key->size, key->data, data->size, data->data);
215
216	return(YP_TRUE);
217}
218