Home | History | Annotate | Line # | Download | only in common
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