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