]> git.saurik.com Git - apple/network_cmds.git/blame - yppush.tproj/yppush.c
network_cmds-176.3.5.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 *
921c0aec
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,
921c0aec
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>
70#include <sys/stat.h>
71#include <sys/resource.h>
72#include <sys/signal.h>
73#include <sys/wait.h>
74#include <netdb.h>
75#include <errno.h>
76#include <fcntl.h>
77
78#include "yplib_host.h"
79#include "ypdef.h"
80#include "ypdb.h"
81
82int Verbose = 0;
83char Domain[MAXHOSTNAMELEN], Map[255];
84u_int32_t OrderNum;
85char *master;
86
87extern void yppush_xfrrespprog_1(struct svc_req *request, SVCXPRT *xprt);
88extern bool_t xdr_ypreq_xfr(XDR *, struct ypreq_xfr *);
89
90void
91usage()
92{
93 fprintf(stderr, "Usage:\n");
94/*
95 fprintf(stderr, "\typpush [-d domainname] [-t seconds] [-p #paralleljobs] [-h host] [-v] mapname\n");
96*/
97 fprintf(stderr, "\typpush [-d domainname] [-h host] [-v] mapname\n");
98 exit(1);
99}
100
101void
102_svc_run()
103{
104 fd_set readfds;
105 struct timeval timeout;
106
107 timeout.tv_sec=60; timeout.tv_usec=0;
108
109 for(;;) {
110 readfds = svc_fdset;
111 switch (select(_rpc_dtablesize(), &readfds, (void *) 0,
112 (void *) 0, &timeout)) {
113 case -1:
114 if (errno == EINTR) {
115 continue;
116 }
117 perror("yppush: _svc_run: select failed");
118 return;
119 case 0:
120 fprintf(stderr, "yppush: Callback timed out.\n");
121 exit(0);
122 default:
123 svc_getreqset(&readfds);
124 }
125 }
126
127}
128
129void
130req_xfr(pid, prog, transp, host, client)
131pid_t pid;
132u_int prog;
133SVCXPRT *transp;
134char *host;
135CLIENT *client;
136{
137 struct ypreq_xfr request;
138 struct timeval tv;
139
140 tv.tv_sec=0; tv.tv_usec=0;
141
142 request.map_parms.domain=(char *)&Domain;
143 request.map_parms.map=(char *)&Map;
144 request.map_parms.peer=master;
145 request.map_parms.ordernum=OrderNum;
146 request.transid=(u_int)pid;
147 request.prog=prog;
148 request.port=transp->xp_port;
149
150 if (Verbose)
151 printf("%d: %s(%u@%s) -> %s@%s\n",
152 request.transid,
153 request.map_parms.map,
154 request.map_parms.ordernum,
155 host,
156 request.map_parms.peer,
157 request.map_parms.domain);
158 switch (clnt_call(client, YPPROC_XFR, xdr_ypreq_xfr, &request,
159 xdr_void, NULL, tv)) {
160 case RPC_SUCCESS:
161 case RPC_TIMEDOUT:
162 break;
163 default:
164 clnt_perror(client, "yppush: Cannot call YPPROC_XFR");
165 kill(pid, SIGTERM);
166 }
167}
168
169void
170push(inlen, indata)
171int inlen;
172char *indata;
173{
174 char host[MAXHOSTNAMELEN];
175 CLIENT *client;
176 SVCXPRT *transp;
177 int sock = RPC_ANYSOCK;
178 u_int prog;
179 bool_t sts;
180 pid_t pid;
181 int status;
182 struct rusage res;
183
184 snprintf(host,sizeof host,"%*.*s" ,inlen ,inlen, indata);
185
186 client = clnt_create(host, YPPROG, YPVERS, "tcp");
187 if (client == NULL) {
188 if (Verbose)
189 fprintf(stderr,"Target Host: %s\n",host);
190 clnt_pcreateerror("yppush: Cannot create client");
191 return;
192 }
193
194 transp = svcudp_create(sock);
195 if (transp == NULL) {
196 fprintf(stderr, "yppush: Cannot create callback transport.\n");
197 return;
198 }
199 if (transp->xp_port >= IPPORT_RESERVED) {
200 SVC_DESTROY(transp);
201 fprintf(stderr, "yppush: Cannot allocate reserved port.\n");
202 return;
203 }
204
205 for (prog=0x40000000; prog<0x5fffffff; prog++) {
206 if (sts = svc_register(transp, prog, 1,
207 yppush_xfrrespprog_1, IPPROTO_UDP))
208 break;
209 }
210
211 if (!sts) {
212 fprintf(stderr, "yppush: Cannot register callback.\n");
213 return;
214 }
215
216 switch(pid=fork()) {
217 case -1:
218 fprintf(stderr, "yppush: Cannot fork.\n");
219 exit(1);
220 case 0:
221 _svc_run();
222 exit(0);
223 default:
224 close(transp->xp_sock);
225 transp->xp_sock = -1;
226 req_xfr(pid, prog, transp, host, client);
227 wait4(pid, &status, 0, &res);
228 svc_unregister(prog, 1);
229 if (client != NULL)
230 clnt_destroy(client);
231 /* XXX transp leak? */
232 }
233
234}
235
236int
237pushit(instatus, inkey, inkeylen, inval, invallen, indata)
238int instatus;
239char *inkey;
240int inkeylen;
241char *inval;
242int invallen;
243char *indata;
244{
245 if(instatus != YP_TRUE)
246 return instatus;
247 push(invallen, inval);
248 return 0;
249}
250
251int
252main(argc, argv)
253int argc;
254char **argv;
255{
256 struct ypall_callback ypcb;
257 extern char *optarg;
258 extern int optind;
259 char *domain,*map,*hostname,*parallel,*timeout;
260 int c, r, i;
261 char *ypmap = "ypservers";
262 CLIENT *client;
263 static char map_path[MAXPATHLEN];
264 struct stat finfo;
265 DBM *yp_databas;
266 char order_key[YP_LAST_LEN] = YP_LAST_KEY;
267 datum o;
268
269 yp_get_default_domain(&domain);
270 hostname = NULL;
271/*
272 while( (c=getopt(argc, argv, "d:h:p:t:v?")) != -1)
273*/
274 while( (c=getopt(argc, argv, "d:h:v?")) != -1)
275 switch(c) {
276 case 'd':
277 domain = optarg;
278 break;
279 case 'h':
280 hostname = optarg;
281 break;
282 case 'p':
283 parallel = optarg;
284 break;
285 case 't':
286 timeout = optarg;
287 break;
288 case 'v':
289 Verbose = 1;
290 break;
291 case '?':
292 usage();
293 /*NOTREACHED*/
294 }
295
296 if(optind + 1 != argc )
297 usage();
298
299 map = argv[optind];
300
301 strncpy(Domain,domain,sizeof(Domain)-1);
302 Domain[sizeof(Domain)-1] = '\0';
303 strncpy(Map,map,sizeof(Map)-1);
304 Map[sizeof(Map)-1] = '\0';
305
306 /* Check domain */
307 snprintf(map_path,sizeof map_path,"%s/%s",YP_DB_PATH,domain);
308 if (!((stat(map_path, &finfo) == 0) &&
309 ((finfo.st_mode & S_IFMT) == S_IFDIR))) {
310 fprintf(stderr,"yppush: Map does not exist.\n");
311 exit(1);
312 }
313
314
315 /* Check map */
316 snprintf(map_path,sizeof map_path,"%s/%s/%s%s",
317 YP_DB_PATH,domain,Map,YPDB_SUFFIX);
318 if (!(stat(map_path, &finfo) == 0)) {
319 fprintf(stderr,"yppush: Map does not exist.\n");
320 exit(1);
321 }
322
323 snprintf(map_path,sizeof map_path,"%s/%s/%s",YP_DB_PATH,domain,Map);
324 yp_databas = ypdb_open(map_path,0,O_RDONLY);
325 OrderNum=0xffffffff;
326 if (yp_databas == 0) {
327 fprintf(stderr, "yppush: %s%s: Cannot open database\n",
328 map_path, YPDB_SUFFIX);
329 } else {
330 o.dptr = (char *) &order_key;
331 o.dsize = YP_LAST_LEN;
332 o=ypdb_fetch(yp_databas,o);
333 if (o.dptr == NULL) {
334 fprintf(stderr,
335 "yppush: %s: Cannot determine order number\n",
336 Map);
337 } else {
338 OrderNum=0;
339 for(i=0; i<o.dsize-1; i++) {
340 if (!isdigit(o.dptr[i])) {
341 OrderNum=0xffffffff;
342 }
343 }
344 if (OrderNum != 0) {
345 fprintf(stderr,
346 "yppush: %s: Invalid order number '%s'\n",
347 Map,
348 o.dptr);
349 } else {
350 OrderNum = atoi(o.dptr);
351 }
352 }
353 }
354
355
356 yp_bind(Domain);
357
358 r = yp_master(Domain, ypmap, &master);
359 if (r != 0) {
360 fprintf(stderr, "yppush: could not get ypservers map\n");
361 exit(1);
362 }
363
364 if (hostname != NULL) {
365 push(strlen(hostname), hostname);
366 } else {
367
368 if (Verbose) {
369 printf("Contacting master for ypservers (%s).\n", master);
370 }
371
372 client = yp_bind_host(master, YPPROG, YPVERS, 0, 1);
373
374 ypcb.foreach = pushit;
375 ypcb.data = NULL;
376
377 r = yp_all_host(client,Domain, ypmap, &ypcb);
378 }
379
380 exit(0);
381}
382