ypxfr_main.c revision 13007
113007Swpaul/*
213007Swpaul * Copyright (c) 1995
313007Swpaul *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
413007Swpaul *
513007Swpaul * Redistribution and use in source and binary forms, with or without
613007Swpaul * modification, are permitted provided that the following conditions
713007Swpaul * are met:
813007Swpaul * 1. Redistributions of source code must retain the above copyright
913007Swpaul *    notice, this list of conditions and the following disclaimer.
1013007Swpaul * 2. Redistributions in binary form must reproduce the above copyright
1113007Swpaul *    notice, this list of conditions and the following disclaimer in the
1213007Swpaul *    documentation and/or other materials provided with the distribution.
1313007Swpaul * 3. All advertising materials mentioning features or use of this software
1413007Swpaul *    must display the following acknowledgement:
1513007Swpaul *	This product includes software developed by Bill Paul.
1613007Swpaul * 4. Neither the name of the author nor the names of any co-contributors
1713007Swpaul *    may be used to endorse or promote products derived from this software
1813007Swpaul *    without specific prior written permission.
1913007Swpaul *
2013007Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2113007Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2213007Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2313007Swpaul * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2413007Swpaul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2513007Swpaul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2613007Swpaul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2713007Swpaul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2813007Swpaul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2913007Swpaul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3013007Swpaul * SUCH DAMAGE.
3113007Swpaul *
3213007Swpaul *	$Id: ypxfr_main.c,v 1.11 1995/12/25 02:53:33 wpaul Exp $
3313007Swpaul */
3413007Swpaul#include <stdio.h>
3513007Swpaul#include <stdlib.h>
3613007Swpaul#include <unistd.h>
3713007Swpaul#include <string.h>
3813007Swpaul#include <syslog.h>
3913007Swpaul#include <errno.h>
4013007Swpaul#include <sys/types.h>
4113007Swpaul#include <sys/param.h>
4213007Swpaul#include <sys/socket.h>
4313007Swpaul#include <netinet/in.h>
4413007Swpaul#include <arpa/inet.h>
4513007Swpaul#include <rpc/rpc.h>
4613007Swpaul#include <rpcsvc/yp.h>
4713007Swpaulstruct dom_binding {};
4813007Swpaul#include <rpcsvc/ypclnt.h>
4913007Swpaul#include "ypxfr_extern.h"
5013007Swpaul
5113007Swpaul#ifndef lint
5213007Swpaulstatic const char rcsid[] = "$Id: ypxfr_main.c,v 1.11 1995/12/25 02:53:33 wpaul Exp $";
5313007Swpaul#endif
5413007Swpaul
5513007Swpaulchar *progname = "ypxfr";
5613007Swpaulchar *yp_dir = _PATH_YP;
5713007Swpaulint _rpcpmstart = 0;
5813007Swpaulint ypxfr_use_yplib = 0; /* Assume the worst. */
5913007Swpaulint ypxfr_clear = 1;
6013007Swpaulint ypxfr_prognum = 0;
6113007Swpaulstruct sockaddr_in ypxfr_callback_addr;
6213007Swpaulstruct yppushresp_xfr ypxfr_resp;
6313007SwpaulDB *dbp;
6413007Swpaul
6513007Swpaulstatic void ypxfr_exit(retval, temp)
6613007Swpaul	ypxfrstat retval;
6713007Swpaul	char *temp;
6813007Swpaul{
6913007Swpaul	CLIENT *clnt;
7013007Swpaul	int sock = RPC_ANYSOCK;
7113007Swpaul	struct timeval timeout;
7213007Swpaul
7313007Swpaul	/* Clean up no matter what happened previously. */
7413007Swpaul	if (temp != NULL) {
7513007Swpaul		(void)(dbp->close)(dbp);
7613007Swpaul		if (unlink(temp) == -1) {
7713007Swpaul			yp_error("failed to unlink %s",strerror(errno));
7813007Swpaul		}
7913007Swpaul	}
8013007Swpaul
8113007Swpaul	if (_rpcpmstart) {
8213007Swpaul		timeout.tv_sec = 20;
8313007Swpaul		timeout.tv_usec = 0;
8413007Swpaul
8513007Swpaul		if ((clnt = clntudp_create(&ypxfr_callback_addr, ypxfr_prognum,
8613007Swpaul					1, timeout, &sock)) == NULL) {
8713007Swpaul			yp_error("%s", clnt_spcreateerror("failed to establish callback handle"));
8813007Swpaul			exit(1);
8913007Swpaul		}
9013007Swpaul
9113007Swpaul		ypxfr_resp.status = retval;
9213007Swpaul
9313007Swpaul		if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
9413007Swpaul			yp_error("%s", clnt_sperror(clnt, "callback failed"));
9513007Swpaul			clnt_destroy(clnt);
9613007Swpaul			exit(1);
9713007Swpaul		}
9813007Swpaul		clnt_destroy(clnt);
9913007Swpaul	} else {
10013007Swpaul		yp_error("Exiting: %s", ypxfrerr_string(retval));
10113007Swpaul	}
10213007Swpaul
10313007Swpaul	exit(0);
10413007Swpaul}
10513007Swpaul
10613007Swpaulstatic void usage()
10713007Swpaul{
10813007Swpaul	if (_rpcpmstart) {
10913007Swpaul		ypxfr_exit(YPXFR_BADARGS,NULL);
11013007Swpaul	} else {
11113007Swpaul		fprintf(stderr,"usage: %s [-f] [-c] [-d target domain] \
11213007Swpaul[-h source host] [-s source domain]\n", progname);
11313007Swpaul		fprintf(stderr,"\t     [-p path] [-C taskid program-number \
11413007Swpaulipaddr port] mapname\n");
11513007Swpaul		exit(1);
11613007Swpaul	}
11713007Swpaul}
11813007Swpaul
11913007Swpaulint ypxfr_foreach(status, key, keylen, val, vallen, data)
12013007Swpaul	int status;
12113007Swpaul	char *key;
12213007Swpaul	int keylen;
12313007Swpaul	char *val;
12413007Swpaul	int vallen;
12513007Swpaul	char *data;
12613007Swpaul{
12713007Swpaul	DBT dbkey, dbval;
12813007Swpaul
12913007Swpaul	if (status != YP_TRUE)
13013007Swpaul		return (status);
13113007Swpaul
13213007Swpaul	dbkey.data = key;
13313007Swpaul	dbkey.size = keylen;
13413007Swpaul	dbval.data = val;
13513007Swpaul	dbval.size = vallen;
13613007Swpaul
13713007Swpaul	if (yp_put_record(dbp, &dbkey, &dbval) != YP_TRUE)
13813007Swpaul		return(yp_errno);
13913007Swpaul
14013007Swpaul	return (0);
14113007Swpaul}
14213007Swpaul
14313007Swpaulmain(argc,argv)
14413007Swpaul	int argc;
14513007Swpaul	char *argv[];
14613007Swpaul{
14713007Swpaul	int ch;
14813007Swpaul	int ypxfr_force = 0;
14913007Swpaul	char *ypxfr_dest_domain = NULL;
15013007Swpaul	char *ypxfr_source_host = NULL;
15113007Swpaul	char *ypxfr_source_domain = NULL;
15213007Swpaul	char *ypxfr_local_domain = NULL;
15313007Swpaul	char *ypxfr_master = NULL;
15413007Swpaul	unsigned long ypxfr_order = -1, ypxfr_skew_check = -1;
15513007Swpaul	char *ypxfr_mapname = NULL;
15613007Swpaul	int ypxfr_args = 0;
15713007Swpaul	char ypxfr_temp_map[MAXPATHLEN + 2];
15813007Swpaul	char tempmap[MAXPATHLEN + 2];
15913007Swpaul	char buf[MAXPATHLEN + 2];
16013007Swpaul	DBT key, data;
16113007Swpaul
16213007Swpaul	debug = 1;
16313007Swpaul
16413007Swpaul	if (!isatty(fileno(stderr))) {
16513007Swpaul		openlog(progname, LOG_PID, LOG_DAEMON);
16613007Swpaul		_rpcpmstart = 1;
16713007Swpaul	}
16813007Swpaul
16913007Swpaul	if (argc < 2)
17013007Swpaul		usage();
17113007Swpaul
17213007Swpaul	while ((ch = getopt(argc, argv, "fcd:h:s:p:C:")) != EOF) {
17313007Swpaul		int my_optind;
17413007Swpaul		switch(ch) {
17513007Swpaul		case 'f':
17613007Swpaul			ypxfr_force++;
17713007Swpaul			ypxfr_args++;
17813007Swpaul			break;
17913007Swpaul		case 'c':
18013007Swpaul			ypxfr_clear = 0;
18113007Swpaul			ypxfr_args++;
18213007Swpaul			break;
18313007Swpaul		case 'd':
18413007Swpaul			ypxfr_dest_domain = optarg;
18513007Swpaul			ypxfr_args += 2;
18613007Swpaul			break;
18713007Swpaul		case 'h':
18813007Swpaul			ypxfr_source_host = optarg;
18913007Swpaul			ypxfr_args += 2;
19013007Swpaul			break;
19113007Swpaul		case 's':
19213007Swpaul			ypxfr_source_domain = optarg;
19313007Swpaul			ypxfr_args += 2;
19413007Swpaul			break;
19513007Swpaul		case 'p':
19613007Swpaul			yp_dir = optarg;
19713007Swpaul			ypxfr_args += 2;
19813007Swpaul			break;
19913007Swpaul		case 'C':
20013007Swpaul			/*
20113007Swpaul			 * Whoever decided that the -C flag should take
20213007Swpaul			 * four arguments is a twit.
20313007Swpaul			 */
20413007Swpaul			my_optind = optind - 1;
20513007Swpaul			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
20613007Swpaul				yp_error("transaction ID not specified");
20713007Swpaul				usage();
20813007Swpaul			}
20913007Swpaul			ypxfr_resp.transid = atol(argv[my_optind]);
21013007Swpaul			my_optind++;
21113007Swpaul			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
21213007Swpaul				yp_error("RPC program number not specified");
21313007Swpaul				usage();
21413007Swpaul			}
21513007Swpaul			ypxfr_prognum = atol(argv[my_optind]);
21613007Swpaul			my_optind++;
21713007Swpaul			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
21813007Swpaul				yp_error("address not specified");
21913007Swpaul				usage();
22013007Swpaul			}
22113007Swpaul			if (!inet_aton(argv[my_optind], &ypxfr_callback_addr.sin_addr)) {
22213007Swpaul				yp_error("failed to convert '%s' to IP addr",
22313007Swpaul					argv[my_optind]);
22413007Swpaul				exit(1);
22513007Swpaul			}
22613007Swpaul			my_optind++;
22713007Swpaul			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
22813007Swpaul				yp_error("port not specified");
22913007Swpaul				usage();
23013007Swpaul			}
23113007Swpaul			ypxfr_callback_addr.sin_port = htons((u_short)atoi(argv[my_optind]));
23213007Swpaul			ypxfr_args += 5;
23313007Swpaul			break;
23413007Swpaul		default:
23513007Swpaul			usage();
23613007Swpaul			break;
23713007Swpaul		}
23813007Swpaul	}
23913007Swpaul
24013007Swpaul	ypxfr_mapname = argv[ypxfr_args + 1];
24113007Swpaul
24213007Swpaul	if (ypxfr_mapname == NULL) {
24313007Swpaul		yp_error("no map name specified");
24413007Swpaul		usage();
24513007Swpaul	}
24613007Swpaul
24713007Swpaul	/* Always the case. */
24813007Swpaul	ypxfr_callback_addr.sin_family = AF_INET;
24913007Swpaul
25013007Swpaul	/* Determine if local NIS client facilities are turned on. */
25113007Swpaul	if (!yp_get_default_domain(&ypxfr_local_domain) &&
25213007Swpaul	    _yp_check(&ypxfr_local_domain))
25313007Swpaul		ypxfr_use_yplib = 1;
25413007Swpaul
25513007Swpaul	/*
25613007Swpaul	 * If no destination domain is specified, assume that the
25713007Swpaul	 * local default domain is to be used and try to obtain it.
25813007Swpaul	 * Fails if NIS client facilities are turned off.
25913007Swpaul	 */
26013007Swpaul	if (ypxfr_dest_domain == NULL) {
26113007Swpaul		if (ypxfr_use_yplib) {
26213007Swpaul			yp_get_default_domain(&ypxfr_dest_domain);
26313007Swpaul		} else {
26413007Swpaul			yp_error("no destination domain specified and \
26513007Swpaulthe local domain name isn't set");
26613007Swpaul			ypxfr_exit(YPXFR_BADARGS,NULL);
26713007Swpaul		}
26813007Swpaul	}
26913007Swpaul
27013007Swpaul	/*
27113007Swpaul	 * If a source domain is not specified, assume it to
27213007Swpaul	 * be the same as the destination domain.
27313007Swpaul	 */
27413007Swpaul	if (ypxfr_source_domain == NULL) {
27513007Swpaul		ypxfr_source_domain = ypxfr_dest_domain;
27613007Swpaul	}
27713007Swpaul
27813007Swpaul	/*
27913007Swpaul	 * If the source host is not specified, assume it to be the
28013007Swpaul	 * master for the specified map. If local NIS client facilities
28113007Swpaul	 * are turned on, we can figure this out using yp_master().
28213007Swpaul	 * If not, we have to see if a local copy of the map exists
28313007Swpaul	 * and extract its YP_MASTER_NAME record. If _that_ fails,
28413007Swpaul	 * we are stuck and must ask the user for more information.
28513007Swpaul	 */
28613007Swpaul	if (ypxfr_source_host == NULL) {
28713007Swpaul		if (!ypxfr_use_yplib) {
28813007Swpaul		/*
28913007Swpaul		 * Double whammy: NIS isn't turned on and the user
29013007Swpaul		 * didn't specify a source host.
29113007Swpaul		 */
29213007Swpaul			char *dptr;
29313007Swpaul			key.data = "YP_MASTER_NAME";
29413007Swpaul			key.size = sizeof("YP_MASTER_NAME") - 1;
29513007Swpaul
29613007Swpaul			if (yp_get_record(ypxfr_dest_domain, ypxfr_mapname,
29713007Swpaul					 &key, &data, 1) != YP_TRUE) {
29813007Swpaul				yp_error("no source host specified");
29913007Swpaul				ypxfr_exit(YPXFR_BADARGS,NULL);
30013007Swpaul			}
30113007Swpaul			dptr = data.data;
30213007Swpaul			dptr[data.size] = '\0';
30313007Swpaul			ypxfr_master = ypxfr_source_host = strdup(dptr);
30413007Swpaul		}
30513007Swpaul	} else {
30613007Swpaul		if (ypxfr_use_yplib)
30713007Swpaul			ypxfr_use_yplib = 0;
30813007Swpaul	}
30913007Swpaul
31013007Swpaul	if (ypxfr_master == NULL) {
31113007Swpaul		if ((ypxfr_master = ypxfr_get_master(ypxfr_source_domain,
31213007Swpaul					    	 ypxfr_mapname,
31313007Swpaul					     	ypxfr_source_host,
31413007Swpaul					     	ypxfr_use_yplib)) == NULL) {
31513007Swpaul			yp_error("failed to find master of %s in domain %s",
31613007Swpaul				  ypxfr_mapname, ypxfr_source_domain);
31713007Swpaul			ypxfr_exit(YPXFR_MADDR,NULL);
31813007Swpaul		}
31913007Swpaul	}
32013007Swpaul
32113007Swpaul	/*
32213007Swpaul	 * If we got here and ypxfr_source_host is still undefined,
32313007Swpaul	 * it means we had to resort to using yp_master() to find the
32413007Swpaul	 * master server for the map. The source host and master should
32513007Swpaul	 * be identical.
32613007Swpaul	 */
32713007Swpaul	if (ypxfr_source_host == NULL)
32813007Swpaul		ypxfr_source_host = ypxfr_master;
32913007Swpaul
33013007Swpaul	if ((ypxfr_order = ypxfr_get_order(ypxfr_source_domain,
33113007Swpaul					     ypxfr_mapname,
33213007Swpaul					     ypxfr_master, 0)) == 0) {
33313007Swpaul		yp_error("failed to get order number of %s",
33413007Swpaul						ypxfr_mapname);
33513007Swpaul		ypxfr_exit(YPXFR_YPERR,NULL);
33613007Swpaul	}
33713007Swpaul
33813007Swpaul	key.data = "YP_LAST_MODIFIED";
33913007Swpaul	key.size = sizeof("YP_LAST_MODIFIED") - 1;
34013007Swpaul
34113007Swpaul	/* The order number is immaterial when the 'force' flag is set. */
34213007Swpaul
34313007Swpaul	if (!ypxfr_force) {
34413007Swpaul		int ignore = 0;
34513007Swpaul		if (yp_get_record(ypxfr_dest_domain,ypxfr_mapname,&key,&data,1) != YP_TRUE) {
34613007Swpaul			switch(yp_errno) {
34713007Swpaul			case YP_NOKEY:
34813007Swpaul				ypxfr_exit(YPXFR_FORCE,NULL);
34913007Swpaul				break;
35013007Swpaul			case YP_NOMAP:
35113007Swpaul				/*
35213007Swpaul				 * If the map doesn't exist, we're
35313007Swpaul				 * creating it. Ignore the error.
35413007Swpaul				 */
35513007Swpaul				ignore++;
35613007Swpaul				break;
35713007Swpaul			case YP_BADDB:
35813007Swpaul			default:
35913007Swpaul				ypxfr_exit(YPXFR_DBM,NULL);
36013007Swpaul				break;
36113007Swpaul			}
36213007Swpaul		}
36313007Swpaul		if (!ignore && ypxfr_order <= atoi(data.data))
36413007Swpaul			ypxfr_exit(YPXFR_AGE, NULL);
36513007Swpaul
36613007Swpaul	}
36713007Swpaul
36813007Swpaul	/* Construct a temporary map file name */
36913007Swpaul	snprintf(tempmap, sizeof(tempmap), "%s.%d",ypxfr_mapname, getpid());
37013007Swpaul	snprintf(ypxfr_temp_map, sizeof(ypxfr_temp_map), "%s/%s/%s", yp_dir,
37113007Swpaul		 ypxfr_dest_domain, tempmap);
37213007Swpaul
37313007Swpaul	/* Open the temporary map read/write. */
37413007Swpaul	if ((dbp = yp_open_db_rw(ypxfr_dest_domain, tempmap)) == NULL) {
37513007Swpaul		yp_error("failed to open temporary map file");
37613007Swpaul		ypxfr_exit(YPXFR_DBM,NULL);
37713007Swpaul	}
37813007Swpaul
37913007Swpaul	/*
38013007Swpaul	 * Fill in the keys we already know, such as the order number,
38113007Swpaul	 * master name, input file name (we actually make up a bogus
38213007Swpaul	 * name for that) and output file name.
38313007Swpaul	 */
38413007Swpaul	snprintf(buf, sizeof(buf), "%d", ypxfr_order);
38513007Swpaul	data.data = buf;
38613007Swpaul	data.size = strlen(buf);
38713007Swpaul
38813007Swpaul	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
38913007Swpaul		yp_error("failed to write order number to database");
39013007Swpaul		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
39113007Swpaul	}
39213007Swpaul
39313007Swpaul	key.data = "YP_MASTER_NAME";
39413007Swpaul	key.size = sizeof("YP_MASTER_NAME") - 1;
39513007Swpaul	data.data = ypxfr_master;
39613007Swpaul	data.size = strlen(ypxfr_master);
39713007Swpaul
39813007Swpaul	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
39913007Swpaul		yp_error("failed to write master name to database");
40013007Swpaul		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
40113007Swpaul	}
40213007Swpaul
40313007Swpaul	key.data = "YP_DOMAIN_NAME";
40413007Swpaul	key.size = sizeof("YP_DOMAIN_NAME") - 1;
40513007Swpaul	data.data = ypxfr_dest_domain;
40613007Swpaul	data.size = strlen(ypxfr_dest_domain);
40713007Swpaul
40813007Swpaul	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
40913007Swpaul		yp_error("failed to write domain name to database");
41013007Swpaul		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
41113007Swpaul	}
41213007Swpaul
41313007Swpaul	snprintf (buf, sizeof(buf), "%s:%s", ypxfr_source_host, ypxfr_mapname);
41413007Swpaul
41513007Swpaul	key.data = "YP_INPUT_NAME";
41613007Swpaul	key.size = sizeof("YP_INPUT_NAME") - 1;
41713007Swpaul	data.data = &buf;
41813007Swpaul	data.size = strlen(buf);
41913007Swpaul
42013007Swpaul	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
42113007Swpaul		yp_error("failed to write input name to database");
42213007Swpaul		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
42313007Swpaul
42413007Swpaul	}
42513007Swpaul
42613007Swpaul	snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, ypxfr_dest_domain,
42713007Swpaul							ypxfr_mapname);
42813007Swpaul
42913007Swpaul	key.data = "YP_OUTPUT_NAME";
43013007Swpaul	key.size = sizeof("YP_OUTPUT_NAME") - 1;
43113007Swpaul	data.data = &buf;
43213007Swpaul	data.size = strlen(buf);
43313007Swpaul
43413007Swpaul	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
43513007Swpaul		yp_error("failed to write output name to database");
43613007Swpaul		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
43713007Swpaul	}
43813007Swpaul
43913007Swpaul	/* Now suck over the contents of the map from the master. */
44013007Swpaul
44113007Swpaul	if (ypxfr_get_map(ypxfr_mapname,ypxfr_source_domain,
44213007Swpaul			  ypxfr_source_host, ypxfr_foreach)){
44313007Swpaul		yp_error("failed to retrieve map from source host");
44413007Swpaul		ypxfr_exit(YPXFR_YPERR,&ypxfr_temp_map);
44513007Swpaul	}
44613007Swpaul
44713007Swpaul	(void)(dbp->close)(dbp);
44813007Swpaul
44913007Swpaul	/* Peek at the order number again and check for skew. */
45013007Swpaul	if ((ypxfr_skew_check = ypxfr_get_order(ypxfr_source_domain,
45113007Swpaul					     ypxfr_mapname,
45213007Swpaul					     ypxfr_master, 0)) == 0) {
45313007Swpaul		yp_error("failed to get order number of %s",
45413007Swpaul						ypxfr_mapname);
45513007Swpaul		ypxfr_exit(YPXFR_YPERR,&ypxfr_temp_map);
45613007Swpaul	}
45713007Swpaul
45813007Swpaul	if (ypxfr_order != ypxfr_skew_check)
45913007Swpaul		ypxfr_exit(YPXFR_SKEW,&ypxfr_temp_map);
46013007Swpaul
46113007Swpaul	/*
46213007Swpaul	 * Send a YPPROC_CLEAR to the local ypserv.
46313007Swpaul	 * The FreeBSD ypserv doesn't really need this, but we send it
46413007Swpaul	 * here anyway for the sake of consistency.
46513007Swpaul	 */
46613007Swpaul	if (!ypxfr_clear) {
46713007Swpaul		char in = 0;
46813007Swpaul		char *out = NULL;
46913007Swpaul		if (callrpc("localhost",YPPROG,YPVERS,YPPROC_CLEAR, xdr_void,
47013007Swpaul			(void *)&in, xdr_void, (void *)out) == NULL) {
47113007Swpaul			yp_error("failed to send 'clear' to local ypserv");
47213007Swpaul			ypxfr_exit(YPXFR_YPERR, &ypxfr_temp_map);
47313007Swpaul		}
47413007Swpaul	}
47513007Swpaul
47613007Swpaul	if (unlink(buf) == -1 && errno != ENOENT) {
47713007Swpaul		yp_error("unlink(%s) failed: %s", buf, strerror(errno));
47813007Swpaul		ypxfr_exit(YPXFR_FILE,NULL);
47913007Swpaul	}
48013007Swpaul
48113007Swpaul	if (rename(ypxfr_temp_map, buf) == -1) {
48213007Swpaul		yp_error("rename(%s,%s) failed: %s", ypxfr_temp_map, buf,
48313007Swpaul							strerror(errno));
48413007Swpaul		ypxfr_exit(YPXFR_FILE,NULL);
48513007Swpaul	}
48613007Swpaul
48713007Swpaul	ypxfr_exit(YPXFR_SUCC,NULL);
48813007Swpaul
48913007Swpaul	return(1);
49013007Swpaul}
491