1 /* $NetBSD: yppoll.c,v 1.14 2008/01/25 19:58:54 christos 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 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * Copyright (c) 1992, 1993 John Brezak 31 * All rights reserved. 32 * 33 * Redistribution and use in source and binary forms, with or without 34 * modification, are permitted provided that the following conditions 35 * are met: 36 * 1. Redistributions of source code must retain the above copyright 37 * notice, this list of conditions and the following disclaimer. 38 * 2. Redistributions in binary form must reproduce the above copyright 39 * notice, this list of conditions and the following disclaimer in the 40 * documentation and/or other materials provided with the distribution. 41 * 3. The name of the author may not be used to endorse or promote 42 * products derived from this software without specific prior written 43 * permission. 44 * 45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 46 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 47 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 49 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 55 * SUCH DAMAGE. 56 */ 57 58 #include <sys/cdefs.h> 59 #ifndef lint 60 __RCSID("$NetBSD: yppoll.c,v 1.14 2008/01/25 19:58:54 christos Exp $"); 61 #endif /* not lint */ 62 63 #include <sys/param.h> 64 #include <sys/types.h> 65 #include <sys/socket.h> 66 #include <err.h> 67 #include <stdio.h> 68 #include <stdlib.h> 69 #include <time.h> 70 #include <netdb.h> 71 #include <unistd.h> 72 #include <string.h> 73 #include <netinet/in.h> 74 #include <arpa/inet.h> 75 76 #include <rpc/rpc.h> 77 #include <rpc/xdr.h> 78 #include <rpcsvc/yp_prot.h> 79 #include <rpcsvc/ypclnt.h> 80 81 static CLIENT *mkclient(struct sockaddr_in *, unsigned long, unsigned long, 82 int); 83 static int get_remote_info(const char *, const char *, const char *, int *, 84 char **, int); 85 static void usage(void) __attribute__((__noreturn__)); 86 87 int 88 main(int argc, char *argv[]) 89 { 90 char *domainname; 91 char *hostname = NULL; 92 char *inmap, *master; 93 int order; 94 int c, r, tcp = 0; 95 96 (void)yp_get_default_domain(&domainname); 97 98 while ((c = getopt(argc, argv, "Th:d:")) != -1) { 99 switch (c) { 100 case 'T': 101 tcp = 1; 102 break; 103 case 'd': 104 domainname = optarg; 105 break; 106 107 case 'h': 108 hostname = optarg; 109 break; 110 111 default: 112 usage(); 113 /*NOTREACHED*/ 114 } 115 } 116 117 if (domainname == NULL) 118 errx(1, "YP domain name not set"); 119 120 argc -= optind; 121 argv += optind; 122 123 if (argc != 1) 124 usage(); 125 126 inmap = argv[0]; 127 128 if (hostname != NULL) 129 r = get_remote_info(domainname, inmap, hostname, 130 &order, &master, tcp); 131 else { 132 r = yp_order(domainname, inmap, &order); 133 if (r == 0) 134 r = yp_master(domainname, inmap, &master); 135 } 136 137 if (r != 0) 138 errx(1, "no such map %s. Reason: %s", 139 inmap, yperr_string(r)); 140 141 (void)printf("Map %s has order number %d. %s", inmap, order, 142 ctime((void *)&order)); 143 (void)printf("The master server is %s.\n", master); 144 return 0; 145 } 146 147 static CLIENT * 148 mkclient(struct sockaddr_in *sin, unsigned long prog, unsigned long vers, 149 int tcp) 150 { 151 static struct timeval tv = { 10, 0 }; 152 int fd = RPC_ANYSOCK; 153 154 if (tcp) 155 return clnttcp_create(sin, prog, vers, &fd, 0, 0); 156 else 157 return clntudp_create(sin, prog, vers, tv, &fd); 158 } 159 160 static int 161 get_remote_info(const char *indomain, const char *inmap, const char *server, 162 int *outorder, char **outname, int tcp) 163 { 164 struct ypresp_order ypro; 165 struct ypresp_master yprm; 166 struct ypreq_nokey yprnk; 167 struct timeval tv; 168 int r; 169 struct sockaddr_in rsrv_sin; 170 CLIENT *client; 171 struct hostent *h; 172 173 (void)memset(&rsrv_sin, 0, sizeof(rsrv_sin)); 174 rsrv_sin.sin_len = sizeof rsrv_sin; 175 rsrv_sin.sin_family = AF_INET; 176 177 h = gethostbyname(server); 178 if (h == NULL) { 179 if (inet_aton(server, &rsrv_sin.sin_addr) == 0) 180 errx(1, "unknown host %s", server); 181 } else 182 (void)memcpy(&rsrv_sin.sin_addr.s_addr, h->h_addr, 183 (size_t)h->h_length); 184 185 client = mkclient(&rsrv_sin, YPPROG, YPVERS, tcp); 186 if (client == NULL) 187 errx(1, "clnt%s_create: no contact with host %s.", 188 tcp ? "tcp" : "udp", server); 189 190 yprnk.domain = indomain; 191 yprnk.map = inmap; 192 193 (void)memset(&ypro, 0, sizeof(ypro)); 194 195 tv.tv_sec = 10; 196 tv.tv_usec = 0; 197 198 r = clnt_call(client, (unsigned int)YPPROC_ORDER, xdr_ypreq_nokey, 199 &yprnk, xdr_ypresp_order, &ypro, tv); 200 if (r != RPC_SUCCESS) 201 clnt_perror(client, "yp_order: clnt_call"); 202 203 *outorder = ypro.ordernum; 204 xdr_free(xdr_ypresp_order, (void *)&ypro); 205 206 r = ypprot_err(ypro.status); 207 if (r == RPC_SUCCESS) { 208 (void)memset(&yprm, 0, sizeof(yprm)); 209 210 r = clnt_call(client, (unsigned int)YPPROC_MASTER, 211 xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv); 212 if (r != RPC_SUCCESS) 213 clnt_perror(client, "yp_master: clnt_call"); 214 r = ypprot_err(yprm.status); 215 if (r == 0) 216 *outname = (char *)strdup(yprm.master); 217 xdr_free(xdr_ypresp_master, (void *)&yprm); 218 } 219 clnt_destroy(client); 220 return r; 221 } 222 223 static void 224 usage(void) 225 { 226 227 (void)fprintf(stderr, 228 "Usage: %s [-T] [-h host] [-d domainname] mapname\n", 229 getprogname()); 230 exit(1); 231 } 232