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