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