ypxfr.c

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

C
1,787
字号
}/* * This gets values for the YP_LAST_MODIFIED and YP_MASTER_NAME keys from the * master server's version of the map.  Values are held in static variables * here.  In the success cases, global pointer variables are set to point at * the local statics.   */boolget_private_recs(pushstat)	int *pushstat;{	static char anumber[20];	static unsigned number;	static char name[YPMAXPEER + 1];	int status;	status = 0;		if (get_order(anumber, &number, &status) ) {		master_version = &number;		master_ascii_version = anumber;	} else {		if (status != 0) {			*pushstat = status;			return (FALSE);		}	}	if (get_master_name(name, &status) ) {		master_name = name;	} else {		if (status != 0) {			*pushstat = status;			return (FALSE);		}		master_name = master;	}	return (TRUE);}/* * This gets the map's order number from the master server */boolget_order(an, n, pushstat)	char *an;	unsigned *n;	int *pushstat;{	if (master_prog_vers == YPVERS) {		return (get_v2order(an, n, pushstat) );	} else {		return (get_v1order(an, n, pushstat) );	}}boolget_v1order(an, n, pushstat)	char *an;	unsigned *n;	int *pushstat;{	struct yprequest req;	struct ypresponse resp;	bool retval;	char errmsg[256];	retval = FALSE;	req.yp_reqtype = YPMATCH_REQTYPE;	req.ypmatch_req_domain = domain;	req.ypmatch_req_map = map;	req.ypmatch_req_keyptr = yp_last_modified;	req.ypmatch_req_keysize = (sizeof (yp_last_modified)) - 1;		resp.ypmatch_resp_valptr = NULL;	resp.ypmatch_resp_valsize = 0;	if(clnt_call(master_server.dom_client, YPOLDPROC_MATCH, _xdr_yprequest,	    &req, _xdr_ypresponse, &resp, udp_timeout) == RPC_SUCCESS) {		if (resp.ypmatch_resp_status == YP_TRUE) {			bcopy(resp.ypmatch_resp_valptr, an,			    resp.ypmatch_resp_valsize);			an[resp.ypmatch_resp_valsize] = '\0';			*n = atoi(an);			retval = TRUE;		} else if (resp.ypmatch_resp_status != YP_NOKEY) {			*pushstat = map_yperr_to_pusherr(			    resp.ypmatch_resp_status);			if (!logging) {				logprintf(    "(info) Can't get order number from ypserv at %s.  Reason: %s.\n",				    master, yperr_string(ypprot_err(				    (unsigned) resp.ypmatch_resp_status)) );			}		}		CLNT_FREERES(master_server.dom_client, _xdr_ypresponse, &resp);	} else {		*pushstat = YPPUSH_RPC;		(void) sprintf(errmsg,		    "ypxfr(get_v1order) RPC call to %s failed", master);		clnt_perror(master_server.dom_client, errmsg);	}	return(retval);}boolget_v2order(an, n, pushstat)	char *an;	unsigned *n;	int *pushstat;{	struct ypreq_nokey req;	struct ypresp_order resp;	int retval;	char errmsg[256];	req.domain = domain;	req.map = map;		/*	 * Get the map''s order number, null-terminate it and store it,	 * and convert it to binary and store it again.	 */	retval = FALSE;		if((enum clnt_stat) clnt_call(master_server.dom_client,	    YPPROC_ORDER, xdr_ypreq_nokey, &req, xdr_ypresp_order, &resp,	    udp_timeout) == RPC_SUCCESS) {		if (resp.status == YP_TRUE) {			sprintf(an, "%d", resp.ordernum);			*n = resp.ordernum;			retval = TRUE;		} else if (resp.status != YP_BADDB) {			*pushstat = ypprot_err(resp.status);						if (!logging) {				logprintf(    "(info) Can't get order number from ypserv at %s.  Reason: %s.\n",				    master, yperr_string(				    ypprot_err(resp.status)) );			}		}		CLNT_FREERES(master_server.dom_client, xdr_ypresp_order,		    &resp);	} else {		*pushstat = YPPUSH_RPC;		logprintf("ypxfr(get_v2order) RPC call to %s failed", master);		clnt_perror(master_server.dom_client, "");	}	return (retval);}/* * This gets the map's master name from the master server */boolget_master_name(name, pushstat)	char *name;	int *pushstat;{	if (master_prog_vers == YPVERS) {		return (get_v2master_name(name, pushstat));	} else {		return (get_v1master_name(name, pushstat));	}}boolget_v1master_name(name, pushstat)	char *name;	int *pushstat;{	struct yprequest req;	struct ypresponse resp;	bool retval;	char errmsg[256];	retval = FALSE;	req.yp_reqtype = YPMATCH_REQTYPE;	req.ypmatch_req_domain = domain;	req.ypmatch_req_map = map;	req.ypmatch_req_keyptr = yp_master_name;	req.ypmatch_req_keysize = (sizeof (yp_master_name)) -1;		resp.ypmatch_resp_valptr = NULL;	resp.ypmatch_resp_valsize = 0;	if(clnt_call(master_server.dom_client, YPOLDPROC_MATCH, _xdr_yprequest,	    &req, _xdr_ypresponse, &resp, udp_timeout) == RPC_SUCCESS) {		if (resp.ypmatch_resp_status == YP_TRUE) {			bcopy(resp.ypmatch_resp_valptr, name,			    resp.ypmatch_resp_valsize);			name[resp.ypmatch_resp_valsize] = '\0';			retval = TRUE;		} else if (resp.ypmatch_resp_status != YP_NOKEY) {			*pushstat = map_yperr_to_pusherr(			    resp.ypmatch_resp_status);			logprintf(	"(info) Can't get master name from ypserv at %s. Reason: %s.\n",				    master, 	yperr_string(ypprot_err((unsigned) resp.ypmatch_resp_status)) );		}				CLNT_FREERES(master_server.dom_client, _xdr_ypresponse, &resp);	} else {		*pushstat = YPPUSH_RPC;		(void) sprintf(errmsg,		   "ypxfr(get_v1master_name) RPC call to %s failed", master);		clnt_perror(master_server.dom_client, errmsg);	}	return(retval);}boolget_v2master_name(name, pushstat)	char *name;	int *pushstat;{	struct ypreq_nokey req;	struct ypresp_master resp;	int retval;	char errmsg[256];	req.domain = domain;	req.map = map;	resp.master = NULL;	retval = FALSE;		if((enum clnt_stat) clnt_call(master_server.dom_client,	    YPPROC_MASTER, xdr_ypreq_nokey, &req, xdr_ypresp_master, &resp,	    udp_timeout) == RPC_SUCCESS) {		if (resp.status == YP_TRUE) {			strcpy(name, resp.master);			retval = TRUE;		} else if (resp.status != YP_BADDB) {			*pushstat = ypprot_err(resp.status);			if (!logging) {				logprintf("(info) Can't get master name from ypserv at %s. Reason: %s.\n",				    master, yperr_string(				    ypprot_err(resp.status)) );			}		}			CLNT_FREERES(master_server.dom_client, xdr_ypresp_master,		    &resp);	} else {		*pushstat = YPPUSH_RPC;		logprintf(		   "ypxfr(get_v2master_name) RPC call to %s failed", master);		clnt_perror(master_server.dom_client, "");	}	return (retval);}/* * This tries to get the master name for the named map, from any * server's version, using the vanilla yp client interface.  If we get a * name back, the global "master" gets pointed to it. */voidfind_map_master(){	int err;			if (err = yp_master(domain, map, &master)) {		logprintf("Can't get master of %s. Reason: %s.\n", map,		    yperr_string(err));	}		yp_unbind(domain);}/* * This does the work of transferrring the map. */boolmove_map(pushstat)	int *pushstat;{	unsigned local_version;	char map_name[MAXNAMLEN + 1];	char tmp_name[MAXNAMLEN + 1];	char bkup_name[MAXNAMLEN + 1];	char an[11];	unsigned n;	mkfilename(map_name);		if (!force) {		local_version = get_local_version(map_name);		if (local_version >= *master_version) {			logprintf(			    "Map %s at %s is not more recent than local.\n",			    map, master);			*pushstat = YPPUSH_AGE;			return (FALSE);		}	}	 	mk_tmpname(yptempname_prefix, tmp_name);		if (!new_mapfiles(tmp_name) ) {		logprintf(		    "Can't create temp map %s.\n", tmp_name);		*pushstat = YPPUSH_FILE;		return (FALSE);	}	if (dbminit(tmp_name) < 0) {		logprintf(		    "Can't dbm init temp map %s.\n", tmp_name);		del_mapfiles(tmp_name);		*pushstat = YPPUSH_DBM;		return (FALSE);	}	if (!get_map(tmp_name, pushstat) ) {		del_mapfiles(tmp_name);		return (FALSE);	}	if (!add_private_entries(tmp_name) ) {		del_mapfiles(tmp_name);		*pushstat = YPPUSH_DBM;		return (FALSE);	}	if (dbmclose(tmp_name) < 0) {		logprintf(		    "Can't do dbm close operation on temp map %s.\n",		    tmp_name);		del_mapfiles(tmp_name);		*pushstat = YPPUSH_DBM;		return (FALSE);	}	if (!get_order(an, &n, pushstat)) {		return(FALSE);	}	if (n != *master_version) {		logprintf(		    "Version skew at %s while transferring map %s.\n",		    master, map);		del_mapfiles(tmp_name);		*pushstat = YPPUSH_SKEW;		return (FALSE);	}# ifdef PARANOID	if (!count_mismatch(tmp_name,entry_count)) {		del_mapfiles(tmp_name);		*pushstat = YPPUSH_DBM;		return(FALSE);	}# endif PARANOID	if (!check_map_existence(map_name) ) {		if (!rename_map(tmp_name, map_name) ) {			del_mapfiles(tmp_name);			logprintf(			  "Rename error:  couldn't mv %s to %s.\n",			    tmp_name, map_name);			*pushstat = YPPUSH_FILE;			return (FALSE);		}			} else {		mk_tmpname(ypbkupname_prefix, bkup_name);			if (!rename_map(map_name, bkup_name) ) {			(void) rename_map(bkup_name, map_name);			logprintf(			  "Rename error:  check that old %s is still intact.\n",			    map_name);			del_mapfiles(tmp_name);			*pushstat = YPPUSH_FILE;			return (FALSE);		}		if (rename_map(tmp_name, map_name) ) {			del_mapfiles(bkup_name);		} else {			del_mapfiles(tmp_name);			(void) rename_map(bkup_name, map_name);				logprintf(			  "Rename error:  check that old %s is still intact.\n",			    map_name);			*pushstat = YPPUSH_FILE;			return (FALSE);		}	}	return (TRUE);}/* * This tries to get the order number out of the local version of the map. * If the attempt fails for any version, the function will return "0" */unsignedget_local_version(name)	char *name;{	datum key;	datum val;	char number[11];		if (!check_map_existence(name) ) {		return (0);	}	if (dbminit(name) < 0) {		return (0);	}			key.dptr = yp_last_modified;	key.dsize = (sizeof (yp_last_modified) - 1);	val = fetch(key);	(void) dbmclose(name);	if (!val.dptr) {		return (0);	}	if (val.dsize == 0 || val.dsize > 10) {		return (0);	}	(void) bcopy(val.dptr, number, val.dsize);	number[val.dsize] = '\0';	return ((unsigned) atoi(number) );}/* * This constructs a file name for a map, minus its ".dir" or ".pag" extensions */voidmkfilename(ppath)	char *ppath;{	if ( (strlen(domain) + strlen(map) + strlen(ypdbpath) + 3) 	    > (MAXNAMLEN + 1) ) {		logprintf( "Map name string too long.\n");	}	(void) strcpy(ppath, ypdbpath);	(void) strcat(ppath, "/");	(void) strcat(ppath, domain);	(void) strcat(ppath, "/");	(void) strcat(ppath, map);}/* * This returns a temporary name for a map transfer minus its ".dir" or * ".pag" extensions. */voidmk_tmpname(prefix, xfr_name)	char *prefix;	char *xfr_name;{	char xfr_anumber[10];	long xfr_number;	if (!xfr_name) {		return;	}	xfr_number = getpid();	(void) sprintf(xfr_anumber, "%d", xfr_number);		(void) strcpy(xfr_name, ypdbpath);	(void) strcat(xfr_name, "/");	(void) strcat(xfr_name, domain);	(void) strcat(xfr_name, "/");	(void) strcat(xfr_name, prefix);	(void) strcat(xfr_name, map);	(void) strcat(xfr_name, ".");	(void) strcat(xfr_name, xfr_anumber);}/* * This deletes the .pag and .dir files which implement a map. * * Note:  No error checking is done here for a garbage input file name or for * failed unlink operations. */voiddel_mapfiles(basename)	char *basename;{	char dbfilename[MAXNAMLEN + 1];	if (!basename) {		return;	}		strcpy(dbfilename, basename);	strcat(dbfilename, ".pag");	unlink(dbfilename);	strcpy(dbfilename, basename);	strcat(dbfilename, ".dir");	unlink(dbfilename);}/* * This checks to see if the source map files exist, then renames them to the * target names.  This is a boolean function.  The file names from.pag and * from.dir will be changed to to.pag and to.dir in the success case. * * Note:  If the second of the two renames fails, yprename_map will try to * un-rename the first pair, and leave the world in the state it was on entry. * This might fail, too, though... */boolrename_map(from, to)	char *from;	char *to;{	char fromfile[MAXNAMLEN + 1];	char tofile[MAXNAMLEN + 1];        char savefile[MAXNAMLEN + 1];	if (!from || !to) {		return (FALSE);	}		if (!check_map_existence(from) ) {		return (FALSE);	}		(void) strcpy(fromfile, from);	(void) strcat(fromfile, ".pag");	(void) strcpy(tofile, to);	(void) strcat(tofile, ".pag");		if (rename(fromfile, tofile) ) {		logprintf( "Can't mv %s to %s.\n", fromfile,		    tofile);		return (FALSE);	}		(void) strcpy(fromfile, from);	(void) strcat(fromfile, ".dir");	(void) strcpy(tofile, to);	(void) strcat(tofile, ".dir");		if (rename(fromfile, tofile) ) {		logprintf( "Can't mv %s to %s.\n", fromfile,		    tofile);		(void) strcpy(fromfile, from);		(void) strcat(fromfile, ".pag");		(void) strcpy(tofile, to);		(void) strcat(tofile, ".pag");				if (rename(tofile, fromfile) ) {			logprintf(			    "Can't recover from rename failure.\n");			return (FALSE);		}				return (FALSE);	}		return (TRUE);}/* * This performs an existence check on the dbm data base files <pname>.pag and * <pname>.dir. */boolcheck_map_existence(pname)	char *pname;{

⌨️ 快捷键说明

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