udp.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 250 行

C
250
字号
# ifndef lintstatic char *sccsid = "@(#)udp.c	4.1	(ULTRIX)	7/2/90";# endif not lint/**************************************************************** *								* *  Licensed to Digital Equipment Corporation, Maynard, MA	* *		Copyright 1985 Sun Microsystems, Inc.		* *			All rights reserved.			* *								* ****************************************************************//**//* *	Modification history: *	~~~~~~~~~~~~~~~~~~~~ * *	revision			comments *	--------	----------------------------------------------- * *	01-Jun-89	Fred Glover *			Update for nfssrc 4.0 * *	22-Nov-88	Fred Glover  *			Modify hash() to guarantee positive offset * *	18-Jan-88	fries *			Added Header and Copyright notice. * *	 *//* * this file consists of routines to support call_udp(); * client handles are cached in a hash table; * clntudp_create is only called if (site, prog#, vers#) cannot * be found in the hash table; * a cached entry is destroyed, when remote site crashes */#include <stdio.h>#include <rpc/rpc.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <sys/time.h>#include <netdb.h>#define MAX_HASHSIZE 100char *malloc();char *xmalloc();static int mysock = RPC_ANYSOCK;extern int debug;extern int HASH_SIZE;struct cache {	char *host;	int prognum;	int versnum;	int sock;	CLIENT *client;	struct cache *nxt;};struct cache *table[MAX_HASHSIZE];int cache_len = sizeof(struct cache);hash(name)	char *name;{	int len, i;	unsigned int c;		/* Ultrix Mod - fsg */	c = 0;	len = strlen(name);	for (i = 0; i< len; i++) {		c = c +(int) name[i];	}	c = c %HASH_SIZE;	return(c);}/* * find_hash returns the cached entry; * it returns NULL if not found; */struct cache *find_hash(host, prognum, versnum)	char *host;	int prognum, versnum;{	struct cache *cp;	cp = table[hash(host)];	while ( cp != NULL) {		if (strcmp(cp->host, host) == 0 &&		 cp->prognum == prognum && cp->versnum == versnum) {			/*found */			return(cp);		}		cp = cp->nxt;	}	return(NULL);}struct cache *add_hash(host, prognum, versnum)	char *host;	int prognum, versnum;{	struct cache *cp;	int h;	if ((cp = (struct cache *) xmalloc(cache_len)) == NULL ) {		return(NULL);	/* malloc error */	}	if ((cp->host = xmalloc(strlen(host)+1)) == NULL ) {		free(cp);		return(NULL);	/* malloc error */	}	(void) strcpy(cp->host, host);	cp->prognum = prognum;	cp->versnum = versnum;	h = hash(host);	cp->nxt = table[h];	table[h] = cp;	return(cp);}voiddelete_hash(host) 	char *host;{	struct cache *cp;	struct cache *cp_prev = NULL;	struct cache *next;	int h;	/* if there is more than one entry with same host name;	 * delete has to be recurrsively called */	h = hash(host);	next = table[h];	while ((cp = next) != NULL) {		next = cp->nxt;		if (strcmp(cp->host, host) == 0) {			if (cp_prev == NULL) {				table[h] = cp->nxt;			}			else {				cp_prev->nxt = cp->nxt;			}			if (debug)				printf("delete hash entry (%x), %s \n", cp, host);			clnt_destroy(cp->client);			free(cp->host);			free(cp);		}		else {			cp_prev = cp;		}	}}call_udp(host, prognum, versnum, procnum, inproc, in, outproc, out, valid_in, t)	char *host;	xdrproc_t inproc, outproc;	char *in, *out;	int valid_in;	int t;{	struct sockaddr_in server_addr;	enum clnt_stat clnt_stat;	struct hostent *hp;	struct timeval timeout, tottimeout;	struct cache *cp;	/* Get a long lived socket to talk to the status monitor with */	if (mysock == RPC_ANYSOCK) {		int	dontblock = 1;		mysock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);                if (mysock < 0) {			fprintf(stderr,"rpc.lockd : cannot send because socket could not be created.\n");                        return(-1);                }                /* attempt to bind to prov port */                (void)bindresvport(mysock, (struct sockaddr_in *)0);                /* the sockets rpc controls are non-blocking */                (void)ioctl(mysock, FIONBIO, (char *) &dontblock);	}	if ((cp = find_hash(host, prognum, versnum)) == NULL) {		if ((cp = add_hash(host, prognum, versnum)) == NULL) {			fprintf(stderr, "udp cannot send due to out of cache\n");			return(-1);		}		if (debug)			printf("(%x):[%s, %d, %d] is a new connection\n", cp, host, prognum, versnum);		if ((hp = gethostbyname(host)) == NULL)			return ((int) RPC_UNKNOWNHOST);		timeout.tv_usec = 0;		if (t == 0) {	/* Ultrix Mod - fsg */			timeout.tv_sec = 0;		} else {			timeout.tv_sec = 5;		}		bcopy(hp->h_addr, &server_addr.sin_addr, hp->h_length);		server_addr.sin_family = AF_INET;		server_addr.sin_port =  0;		if ((cp->client = clntudp_create(&server_addr, prognum, 	 	versnum, timeout, &mysock)) == NULL)			return ((int) rpc_createerr.cf_stat);	}	else {		if (valid_in == 0) { /* cannot use cache */		if (debug)			printf("(%x):[%s, %d, %d] is a new connection\n", cp, host, prognum, versnum);			if ((hp = gethostbyname(host)) == NULL)				return ((int) RPC_UNKNOWNHOST);			/* get rid of previous client struct */			if (cp->client != NULL) clnt_destroy(cp->client);			timeout.tv_usec = 0;			if (t == 0) {	/* Ultrix Mod - fsg */				timeout.tv_sec = 0;			} else {				timeout.tv_sec = 5;			}			bcopy(hp->h_addr, &server_addr.sin_addr, hp->h_length);			server_addr.sin_family = AF_INET;			server_addr.sin_port =  0;			if ((cp->client = clntudp_create(&server_addr, prognum, 	 		versnum, timeout, &mysock)) == NULL)				return ((int) rpc_createerr.cf_stat);		}	}	cp->sock = mysock;	tottimeout.tv_sec = t;	tottimeout.tv_usec = 0;	clnt_stat = clnt_call(cp->client, procnum, inproc, in,	    outproc, out, tottimeout);	return ((int) clnt_stat);}

⌨️ 快捷键说明

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