ypxfr_main.c revision 13008
155682Smarkm/*
2142403Snectar * Copyright (c) 1995
355682Smarkm *	Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
455682Smarkm *
555682Smarkm * Redistribution and use in source and binary forms, with or without
655682Smarkm * modification, are permitted provided that the following conditions
755682Smarkm * are met:
855682Smarkm * 1. Redistributions of source code must retain the above copyright
955682Smarkm *    notice, this list of conditions and the following disclaimer.
1055682Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1155682Smarkm *    notice, this list of conditions and the following disclaimer in the
1255682Smarkm *    documentation and/or other materials provided with the distribution.
1355682Smarkm * 3. All advertising materials mentioning features or use of this software
1455682Smarkm *    must display the following acknowledgement:
1555682Smarkm *	This product includes software developed by Bill Paul.
1655682Smarkm * 4. Neither the name of the author nor the names of any co-contributors
1755682Smarkm *    may be used to endorse or promote products derived from this software
1855682Smarkm *    without specific prior written permission.
1955682Smarkm *
2055682Smarkm * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
2155682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2255682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2355682Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE
2455682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2555682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2655682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2755682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2855682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2955682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3055682Smarkm * SUCH DAMAGE.
3155682Smarkm *
3255682Smarkm *	$Id: ypxfr_main.c,v 1.11 1995/12/25 02:53:33 wpaul Exp $
3355682Smarkm */
3455682Smarkm#include <stdio.h>
35178825Sdfr#include <stdlib.h>
3655682Smarkm#include <unistd.h>
3755682Smarkm#include <string.h>
3855682Smarkm#include <syslog.h>
3955682Smarkm#include <errno.h>
4055682Smarkm#include <sys/types.h>
4155682Smarkm#include <sys/param.h>
4255682Smarkm#include <sys/socket.h>
4355682Smarkm#include <netinet/in.h>
4455682Smarkm#include <arpa/inet.h>
4555682Smarkm#include <rpc/rpc.h>
4655682Smarkm#include <rpcsvc/yp.h>
4755682Smarkmstruct dom_binding {};
4855682Smarkm#include <rpcsvc/ypclnt.h>
4955682Smarkm#include "ypxfr_extern.h"
5055682Smarkm
5155682Smarkm#ifndef lint
5255682Smarkmstatic const char rcsid[] = "$Id: ypxfr_main.c,v 1.11 1995/12/25 02:53:33 wpaul Exp $";
5355682Smarkm#endif
5455682Smarkm
5555682Smarkmchar *progname = "ypxfr";
5655682Smarkmchar *yp_dir = _PATH_YP;
5755682Smarkmint _rpcpmstart = 0;
5855682Smarkmint ypxfr_use_yplib = 0; /* Assume the worst. */
5955682Smarkmint ypxfr_clear = 1;
6055682Smarkmint ypxfr_prognum = 0;
6155682Smarkmstruct sockaddr_in ypxfr_callback_addr;
6255682Smarkmstruct yppushresp_xfr ypxfr_resp;
6355682SmarkmDB *dbp;
6455682Smarkm
6555682Smarkmstatic void ypxfr_exit(retval, temp)
6655682Smarkm	ypxfrstat retval;
6755682Smarkm	char *temp;
6855682Smarkm{
6955682Smarkm	CLIENT *clnt;
7055682Smarkm	int sock = RPC_ANYSOCK;
7155682Smarkm	struct timeval timeout;
7255682Smarkm
7355682Smarkm	/* Clean up no matter what happened previously. */
7455682Smarkm	if (temp != NULL) {
7572445Sassar		(void)(dbp->close)(dbp);
7655682Smarkm		if (unlink(temp) == -1) {
7755682Smarkm			yp_error("failed to unlink %s",strerror(errno));
7855682Smarkm		}
7955682Smarkm	}
8055682Smarkm
8155682Smarkm	if (_rpcpmstart) {
8255682Smarkm		timeout.tv_sec = 20;
8355682Smarkm		timeout.tv_usec = 0;
8455682Smarkm
8555682Smarkm		if ((clnt = clntudp_create(&ypxfr_callback_addr, ypxfr_prognum,
8655682Smarkm					1, timeout, &sock)) == NULL) {
8755682Smarkm			yp_error("%s", clnt_spcreateerror("failed to establish callback handle"));
8855682Smarkm			exit(1);
8955682Smarkm		}
9072445Sassar
9155682Smarkm		ypxfr_resp.status = retval;
9255682Smarkm
9355682Smarkm		if (yppushproc_xfrresp_1(&ypxfr_resp, clnt) == NULL) {
9455682Smarkm			yp_error("%s", clnt_sperror(clnt, "callback failed"));
9555682Smarkm			clnt_destroy(clnt);
9655682Smarkm			exit(1);
9755682Smarkm		}
9855682Smarkm		clnt_destroy(clnt);
9955682Smarkm	} else {
10055682Smarkm		yp_error("Exiting: %s", ypxfrerr_string(retval));
10172445Sassar	}
10255682Smarkm
10355682Smarkm	exit(0);
10455682Smarkm}
10555682Smarkm
10655682Smarkmstatic void usage()
10755682Smarkm{
10855682Smarkm	if (_rpcpmstart) {
10955682Smarkm		ypxfr_exit(YPXFR_BADARGS,NULL);
11055682Smarkm	} else {
11155682Smarkm		fprintf(stderr,"usage: %s [-f] [-c] [-d target domain] \
11255682Smarkm[-h source host] [-s source domain]\n", progname);
11355682Smarkm		fprintf(stderr,"\t     [-p path] [-C taskid program-number \
11455682Smarkmipaddr port] mapname\n");
11555682Smarkm		exit(1);
11655682Smarkm	}
11755682Smarkm}
11855682Smarkm
11955682Smarkmint ypxfr_foreach(status, key, keylen, val, vallen, data)
12055682Smarkm	int status;
12155682Smarkm	char *key;
12255682Smarkm	int keylen;
12355682Smarkm	char *val;
12455682Smarkm	int vallen;
12555682Smarkm	char *data;
12655682Smarkm{
12755682Smarkm	DBT dbkey, dbval;
12855682Smarkm
12955682Smarkm	if (status != YP_TRUE)
13055682Smarkm		return (status);
13155682Smarkm
13255682Smarkm	dbkey.data = key;
13355682Smarkm	dbkey.size = keylen;
13455682Smarkm	dbval.data = val;
13555682Smarkm	dbval.size = vallen;
13655682Smarkm
13755682Smarkm	if (yp_put_record(dbp, &dbkey, &dbval) != YP_TRUE)
13855682Smarkm		return(yp_errno);
13955682Smarkm
140120945Snectar	return (0);
141120945Snectar}
142120945Snectar
143120945Snectarmain(argc,argv)
144120945Snectar	int argc;
14555682Smarkm	char *argv[];
14655682Smarkm{
14755682Smarkm	int ch;
14855682Smarkm	int ypxfr_force = 0;
14955682Smarkm	char *ypxfr_dest_domain = NULL;
15055682Smarkm	char *ypxfr_source_host = NULL;
15155682Smarkm	char *ypxfr_source_domain = NULL;
15255682Smarkm	char *ypxfr_local_domain = NULL;
15355682Smarkm	char *ypxfr_master = NULL;
15455682Smarkm	unsigned long ypxfr_order = -1, ypxfr_skew_check = -1;
15555682Smarkm	char *ypxfr_mapname = NULL;
15655682Smarkm	int ypxfr_args = 0;
15755682Smarkm	char ypxfr_temp_map[MAXPATHLEN + 2];
15855682Smarkm	char tempmap[MAXPATHLEN + 2];
15955682Smarkm	char buf[MAXPATHLEN + 2];
16055682Smarkm	DBT key, data;
16155682Smarkm
16255682Smarkm	debug = 1;
16355682Smarkm
16455682Smarkm	if (!isatty(fileno(stderr))) {
16572445Sassar		openlog(progname, LOG_PID, LOG_DAEMON);
16655682Smarkm		_rpcpmstart = 1;
16755682Smarkm	}
16855682Smarkm
16955682Smarkm	if (argc < 2)
17055682Smarkm		usage();
17155682Smarkm
17255682Smarkm	while ((ch = getopt(argc, argv, "fcd:h:s:p:C:")) != EOF) {
17355682Smarkm		int my_optind;
17455682Smarkm		switch(ch) {
17555682Smarkm		case 'f':
17655682Smarkm			ypxfr_force++;
17755682Smarkm			ypxfr_args++;
17855682Smarkm			break;
17972445Sassar		case 'c':
18072445Sassar			ypxfr_clear = 0;
18155682Smarkm			ypxfr_args++;
18255682Smarkm			break;
18355682Smarkm		case 'd':
18455682Smarkm			ypxfr_dest_domain = optarg;
18555682Smarkm			ypxfr_args += 2;
18655682Smarkm			break;
18755682Smarkm		case 'h':
18855682Smarkm			ypxfr_source_host = optarg;
18955682Smarkm			ypxfr_args += 2;
19055682Smarkm			break;
19155682Smarkm		case 's':
19255682Smarkm			ypxfr_source_domain = optarg;
19355682Smarkm			ypxfr_args += 2;
19455682Smarkm			break;
19555682Smarkm		case 'p':
19655682Smarkm			yp_dir = optarg;
19755682Smarkm			ypxfr_args += 2;
19855682Smarkm			break;
19955682Smarkm		case 'C':
20055682Smarkm			/*
20155682Smarkm			 * Whoever decided that the -C flag should take
20255682Smarkm			 * four arguments is a twit.
20355682Smarkm			 */
20455682Smarkm			my_optind = optind - 1;
20555682Smarkm			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
20655682Smarkm				yp_error("transaction ID not specified");
20755682Smarkm				usage();
20855682Smarkm			}
20955682Smarkm			ypxfr_resp.transid = atol(argv[my_optind]);
21055682Smarkm			my_optind++;
21155682Smarkm			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
21255682Smarkm				yp_error("RPC program number not specified");
21355682Smarkm				usage();
21455682Smarkm			}
21555682Smarkm			ypxfr_prognum = atol(argv[my_optind]);
21690926Snectar			my_optind++;
217142403Snectar			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
218142403Snectar				yp_error("address not specified");
21955682Smarkm				usage();
220142403Snectar			}
22155682Smarkm			if (!inet_aton(argv[my_optind], &ypxfr_callback_addr.sin_addr)) {
22255682Smarkm				yp_error("failed to convert '%s' to IP addr",
22355682Smarkm					argv[my_optind]);
22455682Smarkm				exit(1);
22555682Smarkm			}
22655682Smarkm			my_optind++;
22755682Smarkm			if (argv[my_optind] == NULL || !strlen(argv[my_optind])) {
22855682Smarkm				yp_error("port not specified");
22955682Smarkm				usage();
23072445Sassar			}
23172445Sassar			ypxfr_callback_addr.sin_port = htons((u_short)atoi(argv[my_optind]));
23272445Sassar			ypxfr_args += 5;
23372445Sassar			break;
23455682Smarkm		default:
235142403Snectar			usage();
236142403Snectar			break;
237142403Snectar		}
238142403Snectar	}
23955682Smarkm
24072445Sassar	ypxfr_mapname = argv[ypxfr_args + 1];
24172445Sassar
24272445Sassar	if (ypxfr_mapname == NULL) {
24372445Sassar		yp_error("no map name specified");
24455682Smarkm		usage();
24555682Smarkm	}
24655682Smarkm
24772445Sassar	/* Always the case. */
24872445Sassar	ypxfr_callback_addr.sin_family = AF_INET;
24972445Sassar
25072445Sassar	/* Determine if local NIS client facilities are turned on. */
25172445Sassar	if (!yp_get_default_domain(&ypxfr_local_domain) &&
25272445Sassar	    _yp_check(&ypxfr_local_domain))
25372445Sassar		ypxfr_use_yplib = 1;
25472445Sassar
25572445Sassar	/*
25672445Sassar	 * If no destination domain is specified, assume that the
25772445Sassar	 * local default domain is to be used and try to obtain it.
25872445Sassar	 * Fails if NIS client facilities are turned off.
25972445Sassar	 */
26055682Smarkm	if (ypxfr_dest_domain == NULL) {
26155682Smarkm		if (ypxfr_use_yplib) {
26255682Smarkm			yp_get_default_domain(&ypxfr_dest_domain);
26355682Smarkm		} else {
26455682Smarkm			yp_error("no destination domain specified and \
26555682Smarkmthe local domain name isn't set");
26655682Smarkm			ypxfr_exit(YPXFR_BADARGS,NULL);
26755682Smarkm		}
26855682Smarkm	}
26955682Smarkm
27055682Smarkm	/*
271178825Sdfr	 * If a source domain is not specified, assume it to
272178825Sdfr	 * be the same as the destination domain.
27355682Smarkm	 */
27455682Smarkm	if (ypxfr_source_domain == NULL) {
27555682Smarkm		ypxfr_source_domain = ypxfr_dest_domain;
27655682Smarkm	}
277178825Sdfr
27890926Snectar	/*
27955682Smarkm	 * If the source host is not specified, assume it to be the
28055682Smarkm	 * master for the specified map. If local NIS client facilities
28155682Smarkm	 * are turned on, we can figure this out using yp_master().
282120945Snectar	 * If not, we have to see if a local copy of the map exists
28355682Smarkm	 * and extract its YP_MASTER_NAME record. If _that_ fails,
28455682Smarkm	 * we are stuck and must ask the user for more information.
28555682Smarkm	 */
28655682Smarkm	if (ypxfr_source_host == NULL) {
28755682Smarkm		if (!ypxfr_use_yplib) {
28855682Smarkm		/*
28955682Smarkm		 * Double whammy: NIS isn't turned on and the user
29055682Smarkm		 * didn't specify a source host.
29155682Smarkm		 */
29272445Sassar			char *dptr;
29372445Sassar			key.data = "YP_MASTER_NAME";
29455682Smarkm			key.size = sizeof("YP_MASTER_NAME") - 1;
295120945Snectar
296120945Snectar			if (yp_get_record(ypxfr_dest_domain, ypxfr_mapname,
297120945Snectar					 &key, &data, 1) != YP_TRUE) {
298120945Snectar				yp_error("no source host specified");
299120945Snectar				ypxfr_exit(YPXFR_BADARGS,NULL);
300120945Snectar			}
301120945Snectar			dptr = data.data;
30255682Smarkm			dptr[data.size] = '\0';
30355682Smarkm			ypxfr_master = ypxfr_source_host = strdup(dptr);
30455682Smarkm		}
30555682Smarkm	} else {
30655682Smarkm		if (ypxfr_use_yplib)
30755682Smarkm			ypxfr_use_yplib = 0;
30855682Smarkm	}
30955682Smarkm
31055682Smarkm	if (ypxfr_master == NULL) {
31155682Smarkm		if ((ypxfr_master = ypxfr_get_master(ypxfr_source_domain,
31255682Smarkm					    	 ypxfr_mapname,
31355682Smarkm					     	ypxfr_source_host,
31455682Smarkm					     	ypxfr_use_yplib)) == NULL) {
31555682Smarkm			yp_error("failed to find master of %s in domain %s",
31655682Smarkm				  ypxfr_mapname, ypxfr_source_domain);
31755682Smarkm			ypxfr_exit(YPXFR_MADDR,NULL);
31855682Smarkm		}
31955682Smarkm	}
320142403Snectar
321142403Snectar	/*
322142403Snectar	 * If we got here and ypxfr_source_host is still undefined,
323142403Snectar	 * it means we had to resort to using yp_master() to find the
324142403Snectar	 * master server for the map. The source host and master should
325142403Snectar	 * be identical.
326142403Snectar	 */
327142403Snectar	if (ypxfr_source_host == NULL)
32855682Smarkm		ypxfr_source_host = ypxfr_master;
32955682Smarkm
33055682Smarkm	if ((ypxfr_order = ypxfr_get_order(ypxfr_source_domain,
33155682Smarkm					     ypxfr_mapname,
33255682Smarkm					     ypxfr_master, 0)) == 0) {
33355682Smarkm		yp_error("failed to get order number of %s",
33455682Smarkm						ypxfr_mapname);
33555682Smarkm		ypxfr_exit(YPXFR_YPERR,NULL);
33655682Smarkm	}
33755682Smarkm
33855682Smarkm	key.data = "YP_LAST_MODIFIED";
33955682Smarkm	key.size = sizeof("YP_LAST_MODIFIED") - 1;
34055682Smarkm
34155682Smarkm	/* The order number is immaterial when the 'force' flag is set. */
34255682Smarkm
34355682Smarkm	if (!ypxfr_force) {
34472445Sassar		int ignore = 0;
34572445Sassar		if (yp_get_record(ypxfr_dest_domain,ypxfr_mapname,&key,&data,1) != YP_TRUE) {
34672445Sassar			switch(yp_errno) {
34772445Sassar			case YP_NOKEY:
34872445Sassar				ypxfr_exit(YPXFR_FORCE,NULL);
34972445Sassar				break;
35072445Sassar			case YP_NOMAP:
35155682Smarkm				/*
35255682Smarkm				 * If the map doesn't exist, we're
35372445Sassar				 * creating it. Ignore the error.
35472445Sassar				 */
35555682Smarkm				ignore++;
35655682Smarkm				break;
35755682Smarkm			case YP_BADDB:
35855682Smarkm			default:
35955682Smarkm				ypxfr_exit(YPXFR_DBM,NULL);
360120945Snectar				break;
36155682Smarkm			}
36255682Smarkm		}
36355682Smarkm		if (!ignore && ypxfr_order <= atoi(data.data))
36455682Smarkm			ypxfr_exit(YPXFR_AGE, NULL);
36555682Smarkm
36655682Smarkm	}
36755682Smarkm
36855682Smarkm	/* Construct a temporary map file name */
36955682Smarkm	snprintf(tempmap, sizeof(tempmap), "%s.%d",ypxfr_mapname, getpid());
37055682Smarkm	snprintf(ypxfr_temp_map, sizeof(ypxfr_temp_map), "%s/%s/%s", yp_dir,
37155682Smarkm		 ypxfr_dest_domain, tempmap);
37255682Smarkm
37355682Smarkm	/* Open the temporary map read/write. */
37455682Smarkm	if ((dbp = yp_open_db_rw(ypxfr_dest_domain, tempmap)) == NULL) {
37555682Smarkm		yp_error("failed to open temporary map file");
37655682Smarkm		ypxfr_exit(YPXFR_DBM,NULL);
37755682Smarkm	}
37855682Smarkm
37955682Smarkm	/*
38055682Smarkm	 * Fill in the keys we already know, such as the order number,
38155682Smarkm	 * master name, input file name (we actually make up a bogus
38255682Smarkm	 * name for that) and output file name.
383120945Snectar	 */
38455682Smarkm	snprintf(buf, sizeof(buf), "%d", ypxfr_order);
38555682Smarkm	data.data = buf;
38655682Smarkm	data.size = strlen(buf);
38755682Smarkm
38855682Smarkm	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
38955682Smarkm		yp_error("failed to write order number to database");
39055682Smarkm		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
39155682Smarkm	}
39255682Smarkm
39355682Smarkm	key.data = "YP_MASTER_NAME";
39455682Smarkm	key.size = sizeof("YP_MASTER_NAME") - 1;
39555682Smarkm	data.data = ypxfr_master;
39655682Smarkm	data.size = strlen(ypxfr_master);
39755682Smarkm
39855682Smarkm	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
39955682Smarkm		yp_error("failed to write master name to database");
40055682Smarkm		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
40155682Smarkm	}
40255682Smarkm
40355682Smarkm	key.data = "YP_DOMAIN_NAME";
40455682Smarkm	key.size = sizeof("YP_DOMAIN_NAME") - 1;
40555682Smarkm	data.data = ypxfr_dest_domain;
40655682Smarkm	data.size = strlen(ypxfr_dest_domain);
40755682Smarkm
40855682Smarkm	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
40955682Smarkm		yp_error("failed to write domain name to database");
41055682Smarkm		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
41155682Smarkm	}
41255682Smarkm
41355682Smarkm	snprintf (buf, sizeof(buf), "%s:%s", ypxfr_source_host, ypxfr_mapname);
41455682Smarkm
41555682Smarkm	key.data = "YP_INPUT_NAME";
41655682Smarkm	key.size = sizeof("YP_INPUT_NAME") - 1;
41755682Smarkm	data.data = &buf;
41855682Smarkm	data.size = strlen(buf);
41955682Smarkm
42055682Smarkm	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
42155682Smarkm		yp_error("failed to write input name to database");
42255682Smarkm		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
42355682Smarkm
42455682Smarkm	}
42555682Smarkm
42655682Smarkm	snprintf(buf, sizeof(buf), "%s/%s/%s", yp_dir, ypxfr_dest_domain,
42755682Smarkm							ypxfr_mapname);
42855682Smarkm
42955682Smarkm	key.data = "YP_OUTPUT_NAME";
430120945Snectar	key.size = sizeof("YP_OUTPUT_NAME") - 1;
43155682Smarkm	data.data = &buf;
43255682Smarkm	data.size = strlen(buf);
43355682Smarkm
43455682Smarkm	if (yp_put_record(dbp, &key, &data) != YP_TRUE) {
43555682Smarkm		yp_error("failed to write output name to database");
43655682Smarkm		ypxfr_exit(YPXFR_DBM,&ypxfr_temp_map);
437120945Snectar	}
43855682Smarkm
43955682Smarkm	/* Now suck over the contents of the map from the master. */
44055682Smarkm
44155682Smarkm	if (ypxfr_get_map(ypxfr_mapname,ypxfr_source_domain,
44255682Smarkm			  ypxfr_source_host, ypxfr_foreach)){
44355682Smarkm		yp_error("failed to retrieve map from source host");
44455682Smarkm		ypxfr_exit(YPXFR_YPERR,&ypxfr_temp_map);
44555682Smarkm	}
44655682Smarkm
44755682Smarkm	(void)(dbp->close)(dbp);
44855682Smarkm
44955682Smarkm	/* Peek at the order number again and check for skew. */
45055682Smarkm	if ((ypxfr_skew_check = ypxfr_get_order(ypxfr_source_domain,
45155682Smarkm					     ypxfr_mapname,
45255682Smarkm					     ypxfr_master, 0)) == 0) {
45355682Smarkm		yp_error("failed to get order number of %s",
45455682Smarkm						ypxfr_mapname);
45555682Smarkm		ypxfr_exit(YPXFR_YPERR,&ypxfr_temp_map);
45655682Smarkm	}
457120945Snectar
45855682Smarkm	if (ypxfr_order != ypxfr_skew_check)
45955682Smarkm		ypxfr_exit(YPXFR_SKEW,&ypxfr_temp_map);
46055682Smarkm
46155682Smarkm	/*
46255682Smarkm	 * Send a YPPROC_CLEAR to the local ypserv.
46355682Smarkm	 * The FreeBSD ypserv doesn't really need this, but we send it
46455682Smarkm	 * here anyway for the sake of consistency.
46555682Smarkm	 */
46655682Smarkm	if (!ypxfr_clear) {
46755682Smarkm		char in = 0;
46855682Smarkm		char *out = NULL;
46955682Smarkm		if (callrpc("localhost",YPPROG,YPVERS,YPPROC_CLEAR, xdr_void,
47055682Smarkm			(void *)&in, xdr_void, (void *)out) == NULL) {
47155682Smarkm			yp_error("failed to send 'clear' to local ypserv");
47255682Smarkm			ypxfr_exit(YPXFR_YPERR, &ypxfr_temp_map);
47355682Smarkm		}
47455682Smarkm	}
47555682Smarkm
47655682Smarkm	if (unlink(buf) == -1 && errno != ENOENT) {
47755682Smarkm		yp_error("unlink(%s) failed: %s", buf, strerror(errno));
47855682Smarkm		ypxfr_exit(YPXFR_FILE,NULL);
47955682Smarkm	}
48055682Smarkm
48155682Smarkm	if (rename(ypxfr_temp_map, buf) == -1) {
48255682Smarkm		yp_error("rename(%s,%s) failed: %s", ypxfr_temp_map, buf,
48355682Smarkm							strerror(errno));
48455682Smarkm		ypxfr_exit(YPXFR_FILE,NULL);
48555682Smarkm	}
48655682Smarkm
48755682Smarkm	ypxfr_exit(YPXFR_SUCC,NULL);
48855682Smarkm
48955682Smarkm	return(1);
49055682Smarkm}
49155682Smarkm