Annotation of src/lib/libc/yp/yp_match.c, Revision 1.9
1.9 ! jtc 1: /* $NetBSD: yp_match.c,v 1.8 1997/07/13 20:28:14 christos Exp $ */
1.1 jtc 2:
3: /*
4: * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by Theo de Raadt.
18: * 4. The name of the author may not be used to endorse or promote products
19: * derived from this software without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22: * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
1.8 christos 34: #include <sys/cdefs.h>
1.1 jtc 35: #if defined(LIBC_SCCS) && !defined(lint)
1.9 ! jtc 36: __RCSID("$NetBSD: yp_match.c,v 1.8 1997/07/13 20:28:14 christos Exp $");
1.1 jtc 37: #endif
38:
1.9 ! jtc 39: #include "namespace.h"
1.1 jtc 40: #include <stdlib.h>
41: #include <string.h>
42: #include <rpc/rpc.h>
43: #include <rpcsvc/yp_prot.h>
44: #include <rpcsvc/ypclnt.h>
1.8 christos 45: #include "local.h"
1.1 jtc 46:
47: #define YPMATCHCACHE
48:
1.2 jtc 49: extern struct timeval _yplib_timeout;
1.3 christos 50: extern int _yplib_nerrs;
1.1 jtc 51: extern char _yp_domain[];
52:
1.9 ! jtc 53: #ifdef __weak_alias
! 54: __weak_alias(yp_match,_yp_match);
! 55: #endif
! 56:
1.1 jtc 57: #ifdef YPMATCHCACHE
58: int _yplib_cache = 5;
59:
60: static struct ypmatch_ent {
61: struct ypmatch_ent *next;
62: char *map, *key;
63: char *val;
64: int keylen, vallen;
65: time_t expire_t;
66: } *ypmc;
1.8 christos 67:
68: static bool_t ypmatch_add __P((const char *, const char *, int, char *, int));
69: static bool_t ypmatch_find __P((const char *, const char *, int, const char **,
70: int *));
1.1 jtc 71:
72: static bool_t
73: ypmatch_add(map, key, keylen, val, vallen)
74: const char *map;
75: const char *key;
76: int keylen;
77: char *val;
78: int vallen;
79: {
80: struct ypmatch_ent *ep;
81: time_t t;
82:
83: (void)time(&t);
84:
85: for (ep = ypmc; ep; ep = ep->next)
86: if (ep->expire_t < t)
87: break;
88: if (ep == NULL) {
89: if ((ep = malloc(sizeof *ep)) == NULL)
90: return 0;
91: (void)memset(ep, 0, sizeof *ep);
92: if (ypmc)
93: ep->next = ypmc;
94: ypmc = ep;
95: }
96:
97: if (ep->key) {
98: free(ep->key);
99: ep->key = NULL;
100: }
101: if (ep->val) {
102: free(ep->val);
103: ep->val = NULL;
104: }
105:
106: if ((ep->key = malloc(keylen)) == NULL)
107: return 0;
108:
109: if ((ep->val = malloc(vallen)) == NULL) {
110: free(ep->key);
111: ep->key = NULL;
112: return 0;
113: }
114:
115: ep->keylen = keylen;
116: ep->vallen = vallen;
117:
118: (void)memcpy(ep->key, key, ep->keylen);
119: (void)memcpy(ep->val, val, ep->vallen);
120:
121: if (ep->map) {
122: if (strcmp(ep->map, map)) {
123: free(ep->map);
124: if ((ep->map = strdup(map)) == NULL)
125: return 0;
126: }
127: } else {
128: if ((ep->map = strdup(map)) == NULL)
129: return 0;
130: }
131:
132: ep->expire_t = t + _yplib_cache;
133: return 1;
134: }
135:
136: static bool_t
137: ypmatch_find(map, key, keylen, val, vallen)
138: const char *map;
139: const char *key;
140: int keylen;
141: const char **val;
142: int *vallen;
143: {
144: struct ypmatch_ent *ep;
145: time_t t;
146:
147: if (ypmc == NULL)
148: return 0;
149:
150: (void) time(&t);
151:
152: for (ep = ypmc; ep; ep = ep->next) {
153: if (ep->keylen != keylen)
154: continue;
155: if (strcmp(ep->map, map))
156: continue;
157: if (memcmp(ep->key, key, keylen))
158: continue;
159: if (t > ep->expire_t)
160: continue;
161:
162: *val = ep->val;
163: *vallen = ep->vallen;
164: return 1;
165: }
166: return 0;
167: }
168: #endif
169:
170: int
171: yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen)
172: const char *indomain;
173: const char *inmap;
174: const char *inkey;
175: int inkeylen;
176: char **outval;
177: int *outvallen;
178: {
179: struct dom_binding *ysd;
180: struct ypresp_val yprv;
181: struct ypreq_key yprk;
1.3 christos 182: int r, nerrs = 0;
1.1 jtc 183:
1.4 lukem 184: if (outval == NULL)
185: return YPERR_BADARGS;
186: *outval = NULL;
187: *outvallen = 0;
1.2 jtc 188:
1.7 lukem 189: if (_yp_invalid_domain(indomain))
1.2 jtc 190: return YPERR_BADARGS;
191: if (inmap == NULL || *inmap == '\0'
192: || strlen(inmap) > YPMAXMAP)
193: return YPERR_BADARGS;
194: if (inkey == NULL || inkeylen == 0)
195: return YPERR_BADARGS;
1.1 jtc 196:
197: again:
198: if (_yp_dobind(indomain, &ysd) != 0)
199: return YPERR_DOMAIN;
200:
201: #ifdef YPMATCHCACHE
202: if (!strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey,
203: inkeylen, &yprv.valdat.dptr, &yprv.valdat.dsize)) {
204: *outvallen = yprv.valdat.dsize;
205: if ((*outval = malloc(*outvallen + 1)) == NULL)
206: return YPERR_YPERR;
207: (void)memcpy(*outval, yprv.valdat.dptr, *outvallen);
208: (*outval)[*outvallen] = '\0';
209: return 0;
210: }
211: #endif
212:
213: yprk.domain = indomain;
214: yprk.map = inmap;
215: yprk.keydat.dptr = (char *) inkey;
216: yprk.keydat.dsize = inkeylen;
217:
218: memset(&yprv, 0, sizeof yprv);
219:
220: r = clnt_call(ysd->dom_client, YPPROC_MATCH,
1.2 jtc 221: xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv,
222: _yplib_timeout);
1.1 jtc 223: if (r != RPC_SUCCESS) {
1.3 christos 224: if (++nerrs == _yplib_nerrs) {
225: clnt_perror(ysd->dom_client, "yp_match: clnt_call");
226: nerrs = 0;
227: }
1.1 jtc 228: ysd->dom_vers = -1;
229: goto again;
230: }
231: if (!(r = ypprot_err(yprv.status))) {
232: *outvallen = yprv.valdat.dsize;
233: if ((*outval = malloc(*outvallen + 1)) == NULL)
234: return YPERR_YPERR;
235: (void)memcpy(*outval, yprv.valdat.dptr, *outvallen);
236: (*outval)[*outvallen] = '\0';
237: #ifdef YPMATCHCACHE
238: if (strcmp(_yp_domain, indomain) == 0)
239: if (!ypmatch_add(inmap, inkey, inkeylen,
240: *outval, *outvallen))
1.5 lukem 241: r = YPERR_RESRC;
1.1 jtc 242: #endif
243: }
244: xdr_free(xdr_ypresp_val, (char *) &yprv);
1.9 ! jtc 245: __yp_unbind(ysd);
1.6 lukem 246: if (r != 0) {
247: if (*outval) {
248: free(*outval);
249: *outval = NULL;
250: }
251: }
1.1 jtc 252: return r;
253: }
CVSweb <webmaster@jp.NetBSD.org>