]> git.saurik.com Git - apple/network_cmds.git/blame - yppush.tproj/yppush.c
network_cmds-245.tar.gz
[apple/network_cmds.git] / yppush.tproj / yppush.c
CommitLineData
b7080c8e
A
1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
2b484d24
A
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
b7080c8e
A
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2b484d24
A
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License."
b7080c8e
A
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24/* $OpenBSD: yppush.c,v 1.10 1997/11/10 05:49:17 deraadt Exp $ */
25
26/*
27 * Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
28 * All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by Mats O Jansson
41 * 4. The name of the author may not be used to endorse or promote products
42 * derived from this software without specific prior written permission.
43 *
44 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
45 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
46 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
48 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 */
56
57#ifndef lint
58static char rcsid[] = "$OpenBSD: yppush.c,v 1.10 1997/11/10 05:49:17 deraadt Exp $";
59#endif /* not lint */
60
61#include <sys/types.h>
62#include <stdio.h>
63#include <stdlib.h>
64#include <unistd.h>
65#include <string.h>
66#include <rpc/rpc.h>
67#include <rpc/xdr.h>
68#include <rpcsvc/yp.h>
69#include <rpcsvc/ypclnt.h>
2b484d24 70#include <sys/param.h>
b7080c8e
A
71#include <sys/stat.h>
72#include <sys/resource.h>
73#include <sys/signal.h>
74#include <sys/wait.h>
75#include <netdb.h>
76#include <errno.h>
77#include <fcntl.h>
78
79#include "yplib_host.h"
80#include "ypdef.h"
81#include "ypdb.h"
82
83int Verbose = 0;
84char Domain[MAXHOSTNAMELEN], Map[255];
85u_int32_t OrderNum;
86char *master;
87
88extern void yppush_xfrrespprog_1(struct svc_req *request, SVCXPRT *xprt);
89extern bool_t xdr_ypreq_xfr(XDR *, struct ypreq_xfr *);
90
91void
92usage()
93{
94 fprintf(stderr, "Usage:\n");
95/*
96 fprintf(stderr, "\typpush [-d domainname] [-t seconds] [-p #paralleljobs] [-h host] [-v] mapname\n");
97*/
98 fprintf(stderr, "\typpush [-d domainname] [-h host] [-v] mapname\n");
99 exit(1);
100}
101
102void
103_svc_run()
104{
105 fd_set readfds;
106 struct timeval timeout;
107
108 timeout.tv_sec=60; timeout.tv_usec=0;
109
110 for(;;) {
111 readfds = svc_fdset;
112 switch (select(_rpc_dtablesize(), &readfds, (void *) 0,
113 (void *) 0, &timeout)) {
114 case -1:
115 if (errno == EINTR) {
116 continue;
117 }
118 perror("yppush: _svc_run: select failed");
119 return;
120 case 0:
121 fprintf(stderr, "yppush: Callback timed out.\n");
122 exit(0);
123 default:
124 svc_getreqset(&readfds);
125 }
126 }
127
128}
129
130void
131req_xfr(pid, prog, transp, host, client)
132pid_t pid;
133u_int prog;
134SVCXPRT *transp;
135char *host;
136CLIENT *client;
137{
138 struct ypreq_xfr request;
139 struct timeval tv;
140
141 tv.tv_sec=0; tv.tv_usec=0;
142
143 request.map_parms.domain=(char *)&Domain;
144 request.map_parms.map=(char *)&Map;
145 request.map_parms.peer=master;
146 request.map_parms.ordernum=OrderNum;
147 request.transid=(u_int)pid;
148 request.prog=prog;
149 request.port=transp->xp_port;
150
151 if (Verbose)
152 printf("%d: %s(%u@%s) -> %s@%s\n",
153 request.transid,
154 request.map_parms.map,
155 request.map_parms.ordernum,
156 host,
157 request.map_parms.peer,
158 request.map_parms.domain);
159 switch (clnt_call(client, YPPROC_XFR, xdr_ypreq_xfr, &request,
160 xdr_void, NULL, tv)) {
161 case RPC_SUCCESS:
162 case RPC_TIMEDOUT:
163 break;
164 default:
165 clnt_perror(client, "yppush: Cannot call YPPROC_XFR");
166 kill(pid, SIGTERM);
167 }
168}
169
170void
171push(inlen, indata)
172int inlen;
173char *indata;
174{
175 char host[MAXHOSTNAMELEN];
176 CLIENT *client;
177 SVCXPRT *transp;
178 int sock = RPC_ANYSOCK;
179 u_int prog;
180 bool_t sts;
181 pid_t pid;
182 int status;
183 struct rusage res;
184
185 snprintf(host,sizeof host,"%*.*s" ,inlen ,inlen, indata);
186
187 client = clnt_create(host, YPPROG, YPVERS, "tcp");
188 if (client == NULL) {
189 if (Verbose)
190 fprintf(stderr,"Target Host: %s\n",host);
191 clnt_pcreateerror("yppush: Cannot create client");
192 return;
193 }
194
195 transp = svcudp_create(sock);
196 if (transp == NULL) {
197 fprintf(stderr, "yppush: Cannot create callback transport.\n");
198 return;
199 }
200 if (transp->xp_port >= IPPORT_RESERVED) {
201 SVC_DESTROY(transp);
202 fprintf(stderr, "yppush: Cannot allocate reserved port.\n");
203 return;
204 }
205
206 for (prog=0x40000000; prog<0x5fffffff; prog++) {
207 if (sts = svc_register(transp, prog, 1,
208 yppush_xfrrespprog_1, IPPROTO_UDP))
209 break;
210 }
211
212 if (!sts) {
213 fprintf(stderr, "yppush: Cannot register callback.\n");
214 return;
215 }
216
217 switch(pid=fork()) {
218 case -1:
219 fprintf(stderr, "yppush: Cannot fork.\n");
220 exit(1);
221 case 0:
222 _svc_run();
223 exit(0);
224 default:
225 close(transp->xp_sock);
226 transp->xp_sock = -1;
227 req_xfr(pid, prog, transp, host, client);
228 wait4(pid, &status, 0, &res);
229 svc_unregister(prog, 1);
230 if (client != NULL)
231 clnt_destroy(client);
232 /* XXX transp leak? */
233 }
234
235}
236
237int
238pushit(instatus, inkey, inkeylen, inval, invallen, indata)
239int instatus;
240char *inkey;
241int inkeylen;
242char *inval;
243int invallen;
244char *indata;
245{
246 if(instatus != YP_TRUE)
247 return instatus;
248 push(invallen, inval);
249 return 0;
250}
251
252int
253main(argc, argv)
254int argc;
255char **argv;
256{
257 struct ypall_callback ypcb;
258 extern char *optarg;
259 extern int optind;
260 char *domain,*map,*hostname,*parallel,*timeout;
261 int c, r, i;
262 char *ypmap = "ypservers";
263 CLIENT *client;
264 static char map_path[MAXPATHLEN];
265 struct stat finfo;
266 DBM *yp_databas;
267 char order_key[YP_LAST_LEN] = YP_LAST_KEY;
268 datum o;
269
270 yp_get_default_domain(&domain);
271 hostname = NULL;
272/*
273 while( (c=getopt(argc, argv, "d:h:p:t:v?")) != -1)
274*/
275 while( (c=getopt(argc, argv, "d:h:v?")) != -1)
276 switch(c) {
277 case 'd':
278 domain = optarg;
279 break;
280 case 'h':
281 hostname = optarg;
282 break;
283 case 'p':
284 parallel = optarg;
285 break;
286 case 't':
287 timeout = optarg;
288 break;
289 case 'v':
290 Verbose = 1;
291 break;
292 case '?':
293 usage();
294 /*NOTREACHED*/
295 }
296
297 if(optind + 1 != argc )
298 usage();
299
300 map = argv[optind];
301
302 strncpy(Domain,domain,sizeof(Domain)-1);
303 Domain[sizeof(Domain)-1] = '\0';
304 strncpy(Map,map,sizeof(Map)-1);
305 Map[sizeof(Map)-1] = '\0';
306
307 /* Check domain */
308 snprintf(map_path,sizeof map_path,"%s/%s",YP_DB_PATH,domain);
309 if (!((stat(map_path, &finfo) == 0) &&
310 ((finfo.st_mode & S_IFMT) == S_IFDIR))) {
311 fprintf(stderr,"yppush: Map does not exist.\n");
312 exit(1);
313 }
314
315
316 /* Check map */
317 snprintf(map_path,sizeof map_path,"%s/%s/%s%s",
318 YP_DB_PATH,domain,Map,YPDB_SUFFIX);
319 if (!(stat(map_path, &finfo) == 0)) {
320 fprintf(stderr,"yppush: Map does not exist.\n");
321 exit(1);
322 }
323
324 snprintf(map_path,sizeof map_path,"%s/%s/%s",YP_DB_PATH,domain,Map);
325 yp_databas = ypdb_open(map_path,0,O_RDONLY);
326 OrderNum=0xffffffff;
327 if (yp_databas == 0) {
328 fprintf(stderr, "yppush: %s%s: Cannot open database\n",
329 map_path, YPDB_SUFFIX);
330 } else {
331 o.dptr = (char *) &order_key;
332 o.dsize = YP_LAST_LEN;
333 o=ypdb_fetch(yp_databas,o);
334 if (o.dptr == NULL) {
335 fprintf(stderr,
336 "yppush: %s: Cannot determine order number\n",
337 Map);
338 } else {
339 OrderNum=0;
340 for(i=0; i<o.dsize-1; i++) {
341 if (!isdigit(o.dptr[i])) {
342 OrderNum=0xffffffff;
343 }
344 }
345 if (OrderNum != 0) {
346 fprintf(stderr,
347 "yppush: %s: Invalid order number '%s'\n",
348 Map,
349 o.dptr);
350 } else {
351 OrderNum = atoi(o.dptr);
352 }
353 }
354 }
355
356
357 yp_bind(Domain);
358
359 r = yp_master(Domain, ypmap, &master);
360 if (r != 0) {
361 fprintf(stderr, "yppush: could not get ypservers map\n");
362 exit(1);
363 }
364
365 if (hostname != NULL) {
366 push(strlen(hostname), hostname);
367 } else {
368
369 if (Verbose) {
370 printf("Contacting master for ypservers (%s).\n", master);
371 }
372
373 client = yp_bind_host(master, YPPROG, YPVERS, 0, 1);
374
375 ypcb.foreach = pushit;
376 ypcb.data = NULL;
377
378 r = yp_all_host(client,Domain, ypmap, &ypcb);
379 }
380
381 exit(0);
382}
383