]> git.saurik.com Git - apple/network_cmds.git/blob - yppush.tproj/yppush.c
network_cmds-245.1.3.tar.gz
[apple/network_cmds.git] / yppush.tproj / yppush.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /* $OpenBSD: yppush.c,v 1.10 1997/11/10 05:49:17 deraadt Exp $ */
24
25 /*
26 * Copyright (c) 1995 Mats O Jansson <moj@stacken.kth.se>
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by Mats O Jansson
40 * 4. The name of the author may not be used to endorse or promote products
41 * derived from this software without specific prior written permission.
42 *
43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
44 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
45 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
47 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 * SUCH DAMAGE.
54 */
55
56 #ifndef lint
57 static char rcsid[] = "$OpenBSD: yppush.c,v 1.10 1997/11/10 05:49:17 deraadt Exp $";
58 #endif /* not lint */
59
60 #include <sys/types.h>
61 #include <stdio.h>
62 #include <stdlib.h>
63 #include <unistd.h>
64 #include <string.h>
65 #include <rpc/rpc.h>
66 #include <rpc/xdr.h>
67 #include <rpcsvc/yp.h>
68 #include <rpcsvc/ypclnt.h>
69 #include <sys/param.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
82 int Verbose = 0;
83 char Domain[MAXHOSTNAMELEN], Map[255];
84 u_int32_t OrderNum;
85 char *master;
86
87 extern void yppush_xfrrespprog_1(struct svc_req *request, SVCXPRT *xprt);
88 extern bool_t xdr_ypreq_xfr(XDR *, struct ypreq_xfr *);
89
90 void
91 usage()
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
101 void
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
129 void
130 req_xfr(pid, prog, transp, host, client)
131 pid_t pid;
132 u_int prog;
133 SVCXPRT *transp;
134 char *host;
135 CLIENT *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
169 void
170 push(inlen, indata)
171 int inlen;
172 char *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
236 int
237 pushit(instatus, inkey, inkeylen, inval, invallen, indata)
238 int instatus;
239 char *inkey;
240 int inkeylen;
241 char *inval;
242 int invallen;
243 char *indata;
244 {
245 if(instatus != YP_TRUE)
246 return instatus;
247 push(invallen, inval);
248 return 0;
249 }
250
251 int
252 main(argc, argv)
253 int argc;
254 char **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