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 68DBM * 69ypdb_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 105void 106ypdb_close(DBM *db) 107{ 108 (void)(db->close)(db); 109} 110 111/* 112 * Returns: 113 * DATUM on success 114 * NULL on failure 115 */ 116 117datum 118ypdb_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 143datum 144ypdb_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 167datum 168ypdb_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 191datum 192ypdb_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 213int 214ypdb_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 235int 236ypdb_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