xref: /netbsd-src/lib/libc/yp/yp_first.c (revision fdecd6a253f999ae92b139670d9e15cc9df4497c)
1 /*	$NetBSD: yp_first.c,v 1.6 1997/07/07 02:00:32 lukem Exp $	 */
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 
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static char rcsid[] = "$NetBSD: yp_first.c,v 1.6 1997/07/07 02:00:32 lukem Exp $";
36 #endif
37 
38 #include <stdlib.h>
39 #include <string.h>
40 #include <rpc/rpc.h>
41 #include <rpcsvc/yp_prot.h>
42 #include <rpcsvc/ypclnt.h>
43 
44 extern struct timeval _yplib_timeout;
45 extern int _yplib_nerrs;
46 
47 int
48 yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen)
49 	const char     *indomain;
50 	const char     *inmap;
51 	char          **outkey;
52 	int            *outkeylen;
53 	char          **outval;
54 	int            *outvallen;
55 {
56 	struct ypresp_key_val yprkv;
57 	struct ypreq_nokey yprnk;
58 	struct dom_binding *ysd;
59 	int r, nerrs = 0;
60 
61 	if (outkey == NULL || outval == NULL)
62 		return YPERR_BADARGS;
63 	*outkey = *outval = NULL;
64 	*outkeylen = *outvallen = 0;
65 	if (_yp_invalid_domain(indomain))
66 		return YPERR_BADARGS;
67 	if (inmap == NULL || *inmap == '\0'
68 	    || strlen(inmap) > YPMAXMAP)
69 		return YPERR_BADARGS;
70 
71 again:
72 	if (_yp_dobind(indomain, &ysd) != 0)
73 		return YPERR_DOMAIN;
74 
75 	yprnk.domain = indomain;
76 	yprnk.map = inmap;
77 	(void)memset(&yprkv, 0, sizeof yprkv);
78 
79 	r = clnt_call(ysd->dom_client, YPPROC_FIRST,
80 		   xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv,
81 		   _yplib_timeout);
82 	if (r != RPC_SUCCESS) {
83 		if (++nerrs == _yplib_nerrs) {
84 			clnt_perror(ysd->dom_client, "yp_first: clnt_call");
85 			nerrs = 0;
86 		}
87 		ysd->dom_vers = -1;
88 		goto again;
89 	}
90 	if (!(r = ypprot_err(yprkv.status))) {
91 		*outkeylen = yprkv.keydat.dsize;
92 		if ((*outkey = malloc(*outkeylen + 1)) == NULL)
93 			r = YPERR_RESRC;
94 		else {
95 			(void)memcpy(*outkey, yprkv.keydat.dptr, *outkeylen);
96 			(*outkey)[*outkeylen] = '\0';
97 		}
98 		*outvallen = yprkv.valdat.dsize;
99 		if ((*outval = malloc(*outvallen + 1)) == NULL)
100 			r = YPERR_RESRC;
101 		else {
102 			(void)memcpy(*outval, yprkv.valdat.dptr, *outvallen);
103 			(*outval)[*outvallen] = '\0';
104 		}
105 	}
106 	xdr_free(xdr_ypresp_key_val, (char *) &yprkv);
107 	_yp_unbind(ysd);
108 	if (r != 0) {
109 		if (*outkey) {
110 			free(*outkey);
111 			*outkey = NULL;
112 		}
113 		if (*outval) {
114 			free(*outval);
115 			*outval = NULL;
116 		}
117 	}
118 	return r;
119 }
120 
121 int
122 yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen)
123 	const char     *indomain;
124 	const char     *inmap;
125 	const char     *inkey;
126 	int             inkeylen;
127 	char          **outkey;
128 	int            *outkeylen;
129 	char          **outval;
130 	int            *outvallen;
131 {
132 	struct ypresp_key_val yprkv;
133 	struct ypreq_key yprk;
134 	struct dom_binding *ysd;
135 	int r, nerrs = 0;
136 
137 	if (outkey == NULL || outval == NULL)
138 		return YPERR_BADARGS;
139 	*outkey = *outval = NULL;
140 	*outkeylen = *outvallen = 0;
141 
142 	if (_yp_invalid_domain(indomain))
143 		return YPERR_BADARGS;
144 	if (inmap == NULL || *inmap == '\0'
145 	    || strlen(inmap) > YPMAXMAP)
146 		return YPERR_BADARGS;
147 
148 again:
149 	if (_yp_dobind(indomain, &ysd) != 0)
150 		return YPERR_DOMAIN;
151 
152 	yprk.domain = indomain;
153 	yprk.map = inmap;
154 	yprk.keydat.dptr = inkey;
155 	yprk.keydat.dsize = inkeylen;
156 	(void)memset(&yprkv, 0, sizeof yprkv);
157 
158 	r = clnt_call(ysd->dom_client, YPPROC_NEXT,
159 		      xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv,
160 		      _yplib_timeout);
161 	if (r != RPC_SUCCESS) {
162 		if (++nerrs == _yplib_nerrs) {
163 			clnt_perror(ysd->dom_client, "yp_next: clnt_call");
164 			nerrs = 0;
165 		}
166 		ysd->dom_vers = -1;
167 		goto again;
168 	}
169 	if (!(r = ypprot_err(yprkv.status))) {
170 		*outkeylen = yprkv.keydat.dsize;
171 		if ((*outkey = malloc(*outkeylen + 1)) == NULL)
172 			r = YPERR_RESRC;
173 		else {
174 			(void)memcpy(*outkey, yprkv.keydat.dptr, *outkeylen);
175 			(*outkey)[*outkeylen] = '\0';
176 		}
177 		*outvallen = yprkv.valdat.dsize;
178 		if ((*outval = malloc(*outvallen + 1)) == NULL)
179 			r = YPERR_RESRC;
180 		else {
181 			(void)memcpy(*outval, yprkv.valdat.dptr, *outvallen);
182 			(*outval)[*outvallen] = '\0';
183 		}
184 	}
185 	xdr_free(xdr_ypresp_key_val, (char *) &yprkv);
186 	_yp_unbind(ysd);
187 	if (r != 0) {
188 		if (*outkey) {
189 			free(*outkey);
190 			*outkey = NULL;
191 		}
192 		if (*outval) {
193 			free(*outval);
194 			*outval = NULL;
195 		}
196 	}
197 	return r;
198 }
199