ypxfr.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,787 行 · 第 1/3 页

C
1,787
字号
	char dbfile[MAXNAMLEN + 1];	struct stat filestat;	int len;	if (!pname || ((len = strlen(pname)) == 0) ||	    (len + 5) > (MAXNAMLEN + 1) ) {		return (FALSE);	}			errno = 0;	(void) strcpy(dbfile, pname);	(void) strcat(dbfile, ".dir");	if (stat(dbfile, &filestat) != -1) {		(void) strcpy(dbfile, pname);		(void) strcat(dbfile, ".pag");		if (stat(dbfile, &filestat) != -1) {			return (TRUE);		} else {			if (errno != ENOENT) {				logprintf(				    "Stat error on map file %s.\n",				    dbfile);			}			return (FALSE);		}	} else {		if (errno != ENOENT) {			logprintf(			    "Stat error on map file %s.\n",			    dbfile);		}		return (FALSE);	}}/* * This creates <pname>.dir and <pname>.pag */boolnew_mapfiles(pname)	char *pname;{	char dbfile[MAXNAMLEN + 1];	int f;	int len;	if (!pname || ((len = strlen(pname)) == 0) ||	    (len + 5) > (MAXNAMLEN + 1) ) {		return (FALSE);	}			errno = 0;	(void) strcpy(dbfile, pname);	(void) strcat(dbfile, ".dir");	if ((f = open(dbfile, (O_WRONLY | O_CREAT | O_TRUNC), 0600)) >= 0) {		(void) close(f);		(void) strcpy(dbfile, pname);		(void) strcat(dbfile, ".pag");		if ((f = open(dbfile, (O_WRONLY | O_CREAT | O_TRUNC),		    0600)) >= 0) {			(void) close(f);			return (TRUE);		} else {			return (FALSE);		}	} else {		return (FALSE);	}}count_callback(status) 	int status;{	if (status != YP_TRUE) {				if (status != YP_NOMORE) {			logprintf(			    "Error from ypserv on %s (ypall_callback) = %s.\n",			    master, yperr_string(ypprot_err(status)));		}				return(TRUE);	}	entry_count++;	return(FALSE);}/* * This counts the entries in the dbm file after the transfer to * make sure that the dbm file was built correctly.   * Returns TRUE if everything is OK, FALSE if they mismatch. */count_mismatch(pname,oldcount)	char *pname;	int oldcount;{	datum key, value;	struct dom_binding domb;	enum clnt_stat s;	struct ypreq_nokey allreq;	struct ypall_callback cbinfo;    entry_count = 0;    dbminit(pname);    for (key = firstkey(); key.dptr != NULL; key = nextkey(key))	entry_count++;    dbmclose(pname);    if (oldcount != entry_count) {	logprintf( 		  "*** Count mismatch in dbm file %s: old=%d, new=%d ***\n",		    map, oldcount, entry_count);	return(FALSE);    }# ifdef REALLY_PARANOID	domb.dom_server_addr.sin_addr = master_addr;	domb.dom_server_addr.sin_family = AF_INET;	domb.dom_server_addr.sin_port = htons((u_short) 0);	domb.dom_server_port = htons((u_short) 0);	domb.dom_socket = RPC_ANYSOCK;	if ((domb.dom_client = clnttcp_create(&(domb.dom_server_addr),	    YPPROG, master_prog_vers, &(domb.dom_socket), 0, 0)) ==	    (CLIENT *) NULL) {		clnt_pcreateerror(		    "ypxfr (mismatch) - TCP channel create failure");		return(FALSE);	}	if (master_prog_vers == YPVERS) {		int tmpstat;		allreq.domain = domain;		allreq.map = map;		cbinfo.foreach = count_callback;		tmpstat = 0;		cbinfo.data = (char *) &tmpstat;			entry_count = 0;		s = clnt_call(domb.dom_client, YPPROC_ALL, xdr_ypreq_nokey,		    &allreq, xdr_ypall, &cbinfo, tcp_timeout);		if (tmpstat == 0) {			if (s == RPC_SUCCESS) {			} else {				clnt_perror(domb.dom_client,			   "ypxfr (get_map/all) - RPC clnt_call (TCP) failure");		    return(FALSE);			}					} else {		    return(FALSE);		}			} else {	    logprintf("Wrong version number!\n");	    return(FALSE);	}    clnt_destroy(domb.dom_client);    close(domb.dom_socket);    entry_count += 2;			/* add in YP_entries */    if (oldcount != entry_count) {	logprintf(	"*** Count mismatch after enumerate %s: old=%d, new=%d ***\n",		    map, oldcount, entry_count);	return(FALSE);    }# endif REALLY_PARANOID    return(TRUE);}/* * This sets up a TCP connection to the master server, and either gets * ypall_callback to do all the work of writing it to the local dbm file * (if the ypserv is current version), or does it itself for an old ypserv.   */boolget_map(pname, pushstat)	char *pname;	int *pushstat;{	struct dom_binding domb;	enum clnt_stat s;	struct ypreq_nokey allreq;	struct ypall_callback cbinfo;	struct yprequest oldreq;	struct ypresponse resp;	bool retval = FALSE;	int tmpstat;		domb.dom_server_addr.sin_addr = master_addr;	domb.dom_server_addr.sin_family = AF_INET;	domb.dom_server_addr.sin_port = htons((u_short) 0);	domb.dom_server_port = htons((u_short) 0);	domb.dom_socket = RPC_ANYSOCK;	if ((domb.dom_client = clnttcp_create(&(domb.dom_server_addr),	    YPPROG, master_prog_vers, &(domb.dom_socket), 0, 0)) ==	    (CLIENT *) NULL) {		clnt_pcreateerror(			"ypxfr (get_map) - TCP channel create failure");		*pushstat = YPPUSH_RPC;		return(FALSE);	}	entry_count = 0;	if (master_prog_vers == YPVERS) {		allreq.domain = domain;		allreq.map = map;		cbinfo.foreach = ypall_callback;		tmpstat = 0;		cbinfo.data = (char *) &tmpstat;			s = clnt_call(domb.dom_client, YPPROC_ALL, xdr_ypreq_nokey,		    &allreq, xdr_ypall, &cbinfo, tcp_timeout);		if (tmpstat == 0) {						if (s == RPC_SUCCESS) {				retval = TRUE;			} else {				clnt_perror(domb.dom_client,			   "ypxfr (get_map/all) - RPC clnt_call (TCP) failure");				*pushstat = YPPUSH_RPC;			}					} else {			*pushstat = tmpstat;		}			} else {		datum inkey, inval;		oldreq.yp_reqtype = YPFIRST_REQTYPE;		oldreq.ypfirst_req_domain = domain;		oldreq.ypfirst_req_map = map;			resp.ypfirst_resp_keyptr = NULL;		resp.ypfirst_resp_keysize = 0;		resp.ypfirst_resp_valptr = NULL;		resp.ypfirst_resp_valsize = 0;			if((s = clnt_call(domb.dom_client, YPOLDPROC_FIRST,		    _xdr_yprequest, &oldreq, _xdr_ypresponse,		    &resp, tcp_timeout)) != RPC_SUCCESS) {			clnt_perror(domb.dom_client,			 "ypxfr (get_map/first) - RPC clnt_call (TCP) failure");			*pushstat = YPPUSH_RPC;			goto cleanup;		}		if (resp.ypfirst_resp_status != YP_TRUE) {			logprintf(			    "Error from ypserv on %s (get first) = %s.\n",			    master, yperr_string(ypprot_err(			    resp.ypfirst_resp_status)));			*pushstat = YPPUSH_RPC;			goto cleanup;		}		inkey = resp.ypfirst_resp_keydat;		inval = resp.ypfirst_resp_valdat;			/*		 * Continue to get the next entries in the map as long as		 * there are no errors, and there are entries remaining.  		 */		oldreq.yp_reqtype = YPNEXT_REQTYPE;		oldreq.ypnext_req_domain = domain;		oldreq.ypnext_req_map = map;		while (TRUE) {			if (strncmp(inkey.dptr,"YP_",3)) {				if (store(inkey, inval) < 0) {					logprintf(				    "Can't do dbm store into temp map %s.\n",				    	    pname);					*pushstat = YPPUSH_DBM;					goto cleanup;				}				entry_count++;			}			CLNT_FREERES(domb.dom_client, _xdr_ypresponse, &resp);			oldreq.ypnext_req_keydat = inkey;			resp.ypnext_resp_keydat.dptr = NULL;			resp.ypnext_resp_valdat.dptr = NULL;			resp.ypnext_resp_keydat.dsize = 0;			resp.ypnext_resp_valdat.dsize = 0;				if ((s = clnt_call(domb.dom_client, YPOLDPROC_NEXT,		    	    _xdr_yprequest, &oldreq, _xdr_ypresponse,		    	    &resp, tcp_timeout)) != RPC_SUCCESS) {				clnt_perror(domb.dom_client,			  "ypxfr (get_map/next) - RPC clnt_call (TCP) failure");				*pushstat = YPPUSH_RPC;				break;			}			if (resp.ypnext_resp_status != YP_TRUE) {				if (resp.ypnext_resp_status == YP_NOMORE) {					retval = TRUE;				} else {					logprintf(			    "Error from ypserv on %s (get next) = %d.\n",			    		    master, yperr_string(ypprot_err(			    resp.ypnext_resp_status)));					*pushstat = YPPUSH_RPC;				}								break;			}			inkey = resp.ypnext_resp_keydat;			inval = resp.ypnext_resp_valdat;		}	}cleanup:	clnt_destroy(domb.dom_client);	close(domb.dom_socket);	return (retval);}/* * This sticks each key-value pair into the current map.  It returns FALSE as * long as it wants to keep getting called back, and TRUE on error conditions * and "No more k-v pairs". */intypall_callback(status, key, kl, val, vl, pushstat)	int status;	char *key;	int kl;	char *val;	int vl;	int *pushstat;{	datum keydat;	datum valdat;	datum test;	if (status != YP_TRUE) {				if (status != YP_NOMORE) {			logprintf(			    "Error from ypserv on %s (ypall_callback) = %s.\n",			    master, yperr_string(ypprot_err(status)));			*pushstat = map_yperr_to_pusherr(status);		}				return(TRUE);	}	keydat.dptr = key;	keydat.dsize = kl;	valdat.dptr = val;	valdat.dsize = vl;	entry_count++;# ifdef PARANOID	test = fetch(keydat);	if (test.dptr!=NULL) {		logprintf("Duplicate key %s in map %s\n",key,map);		*pushstat  = YPPUSH_DBM;		return(TRUE);	}# endif PARANOID	if (store(keydat, valdat) < 0) {		logprintf(		    "Can't do dbm store into temp map %s.\n",map);		*pushstat  = YPPUSH_DBM;		return(TRUE);	}# ifdef PARANOID	test = fetch(keydat);	if (test.dptr==NULL) {		logprintf("Key %s was not inserted into dbm file %s\n",			key,map);		*pushstat  = YPPUSH_DBM;		return(TRUE);	}# endif PARANOID	return(FALSE);}/* * This maps a YP_xxxx error code into a YPPUSH_xxxx error code */intmap_yperr_to_pusherr(yperr)	int yperr;{	int reason;	switch (yperr) {	 	case YP_NOMORE:		reason = YPPUSH_SUCC;		break; 	case YP_NOMAP:		reason = YPPUSH_NOMAP;		break; 	case YP_NODOM:		reason = YPPUSH_NODOM;		break; 	case YP_NOKEY:		reason = YPPUSH_YPERR;		break; 	case YP_BADARGS:		reason = YPPUSH_BADARGS;		break; 	case YP_BADDB:		reason = YPPUSH_YPERR;		break;	default:		reason = YPPUSH_XFRERR;		break;	}	  	return(reason);}/* * This writes the last-modified and master entries into the new dbm file */booladd_private_entries(pname)	char *pname;{	datum key;	datum val;	if (!fake_master_version) {		key.dptr = yp_last_modified;		key.dsize = sizeof (yp_last_modified) - 1;		val.dptr = master_ascii_version;		val.dsize = strlen(master_ascii_version);		if (store(key, val) < 0) {			logprintf(			    "Can't do dbm store into temp map %s.\n",		    	    pname);			return (FALSE);		}		entry_count++;	}		if (master_name) {		key.dptr = yp_master_name;		key.dsize = sizeof (yp_master_name) - 1;		val.dptr = master_name;		val.dsize = strlen(master_name);		if (store(key, val) < 0) {			logprintf(			    "Can't do dbm store into temp map %s.\n",		    	    pname);			return (FALSE);		}		entry_count++;	}		return (TRUE);}		/* * This sends a YPPROC_CLEAR message to the local ypserv process.  If the * local ypserv is a v.1 protocol guy, we'll just say we succeeded.  Such a * situation is outlandish - why are they running the old ypserv at the same * place they are running ypxfr?  And who are they, anyway? */boolsend_ypclear(pushstat)	int *pushstat;{	struct sockaddr_in myaddr;	struct dom_binding domb;	char local_host_name[256];	unsigned int progvers;	get_myaddress(&myaddr);	if (gethostname(local_host_name, 256)) {		logprintf( "Can't get local machine name.\n");		*pushstat = YPPUSH_RSRC;		return (FALSE);	}	if (!bind_to_server(local_host_name, myaddr.sin_addr, &domb,	    &progvers) ) {		*pushstat = YPPUSH_CLEAR;		return (FALSE);	}	if (progvers == YPOLDVERS)		return (TRUE);	if((enum clnt_stat) clnt_call(domb.dom_client,	    YPPROC_CLEAR, xdr_void, 0, xdr_void, 0,	    udp_timeout) != RPC_SUCCESS) {		logprintf(		"Can't send ypclear message to ypserv on the local machine.\n");		xfr_exit(YPPUSH_CLEAR);	}	return (TRUE);}/* * This decides if send_callback has to get called, and does the process exit. */voidxfr_exit(status)	int status;{	if (callback) {		send_callback(&status);	}	if (status == YPPUSH_SUCC) {		exit(0);	} else {		exit(1);	}}/* * This sets up a UDP connection to the yppush process which contacted our * parent ypserv, and sends him a status on the requested transfer. */voidsend_callback(status)	int *status;{	struct yppushresp_xfr resp;	struct dom_binding domb;#ifdef ORIGINALSUN	resp.transid = (unsigned long) htonl(atoi(tid));	resp.status = (unsigned long) htonl(*status);#endif ORIGINALSUN	resp.transid = (unsigned long) atoi(tid);	resp.status = (unsigned long) *status;	domb.dom_server_addr.sin_addr.s_addr = inet_addr(ipadd);	domb.dom_server_addr.sin_family = AF_INET;	domb.dom_server_addr.sin_port = (unsigned short) htons(atoi(port));	domb.dom_server_port = domb.dom_server_addr.sin_port;	domb.dom_socket = RPC_ANYSOCK;	udp_intertry.tv_sec = CALLINTER_TRY;	udp_timeout.tv_sec = CALLTIMEOUT;/* ORIGINALSUN code  had   htons(atoi(proto)) in the following call. * It fails.. */	if ((domb.dom_client = clntudp_create(&(domb.dom_server_addr),	    (unsigned long) atoi(proto), YPPUSHVERS, 	    udp_intertry, &(domb.dom_socket) ) ) == NULL) {		clnt_perror(domb.dom_client, "ypxfr:  clntudp_create failure");		*status = YPPUSH_RPC;		return;	}			if((enum clnt_stat) clnt_call(domb.dom_client,	    YPPUSHPROC_XFRRESP, xdr_yppushresp_xfr, &resp, xdr_void, 0, 	    udp_timeout) != RPC_SUCCESS) {		clnt_perror(domb.dom_client, "ypxfr:  clnt_call back failure");		*status = YPPUSH_RPC;		return;	} }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?