⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prnetdb.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		else			af = AF_INET;#elif defined(_PR_INET6)		af = AF_INET6;#else		af = AF_INET;#endif	}	else	{		PR_ASSERT(hostaddr->raw.family == AF_INET);		af = AF_INET;	}	if (hostaddr->raw.family == PR_AF_INET6) {#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)		if (af == AF_INET6) {			addr = &hostaddr->ipv6.ip;			addrlen = sizeof(hostaddr->ipv6.ip);		}		else#endif		{			PR_ASSERT(af == AF_INET);			if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) {				PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);				return rv;			}			tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)												&hostaddr->ipv6.ip);			addr = &tmp_ip;			addrlen = sizeof(tmp_ip);		}	} else {		PR_ASSERT(hostaddr->raw.family == AF_INET);		PR_ASSERT(af == AF_INET);		addr = &hostaddr->inet.ip;		addrlen = sizeof(hostaddr->inet.ip);	}#if defined(_PR_HAVE_GETHOST_R)    tmpbuf = localbuf;    if (bufsize > sizeof(localbuf))    {        tmpbuf = (char *)PR_Malloc(bufsize);        if (NULL == tmpbuf)        {            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);            return rv;        }    }#endif    /* Do not need to lock the DNS lock if getipnodebyaddr() is called */#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)	h = getipnodebyaddr(addr, addrlen, af, &error_num);#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)    if (_pr_ipv6_is_present == PR_TRUE)    	h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen,				af, &error_num);	else    {        LOCK_DNS();		h = GETHOSTBYADDR(addr, addrlen, af);    }#else	/* _PR_HAVE_GETIPNODEBYADDR */    LOCK_DNS();#ifdef XP_OS2_VACPP	h = GETHOSTBYADDR((char *)addr, addrlen, af);#else	h = GETHOSTBYADDR(addr, addrlen, af);#endif#endif /* _PR_HAVE_GETIPNODEBYADDR */	if (NULL == h)	{#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)    	if (_pr_ipv6_is_present == PR_TRUE)	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);		else	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());#else		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());#endif	}	else	{		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;		if (hostaddr->raw.family == PR_AF_INET6) {			if (af == AF_INET) {				if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*)												&hostaddr->ipv6.ip)) {					conversion = _PRIPAddrIPv4Mapped;				} else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *)													&hostaddr->ipv6.ip)) {					conversion = _PRIPAddrIPv4Compat;				}			}		}		rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry);		if (PR_SUCCESS != rv) {		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);		}#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)		freehostent(h);#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)    	if (_pr_ipv6_is_present == PR_TRUE)			(*((_pr_freehostent_t)_pr_freehostent_fp))(h);#endif	}    /* Must match the convoluted logic above for LOCK_DNS() */#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)    if (_pr_ipv6_is_present == PR_FALSE)        UNLOCK_DNS();#else	/* _PR_HAVE_GETIPNODEBYADDR */    UNLOCK_DNS();#endif /* _PR_HAVE_GETIPNODEBYADDR */#if defined(_PR_HAVE_GETHOST_R)    if (tmpbuf != localbuf)        PR_Free(tmpbuf);#endif	return rv;}/******************************************************************************//* * Some systems define a reentrant version of getprotobyname(). Too bad * the signature isn't always the same. But hey, they tried. If there * is such a definition, use it. Otherwise, grab a lock and do it here. *//******************************************************************************/#if !defined(_PR_HAVE_GETPROTO_R)/* * This may seem like a silly thing to do, but the compiler SHOULD * complain if getprotobyname_r() is implemented on some system and * we're not using it. For sure these signatures are different than * any usable implementation. */static struct protoent *getprotobyname_r(const char* name){#ifdef XP_OS2_VACPP	return getprotobyname((char *)name);#else	return getprotobyname(name);#endif} /* getprotobyname_r */static struct protoent *getprotobynumber_r(PRInt32 number){	return getprotobynumber(number);} /* getprotobynumber_r */#endif /* !defined(_PR_HAVE_GETPROTO_R) */PR_IMPLEMENT(PRStatus) PR_GetProtoByName(    const char* name, char* buffer, PRInt32 buflen, PRProtoEnt* result){	PRStatus rv = PR_SUCCESS;#if defined(_PR_HAVE_GETPROTO_R)	struct protoent* res = (struct protoent*)result;#endif    if (!_pr_initialized) _PR_ImplicitInitialization();#if defined(_PR_HAVE_GETPROTO_R_INT)    {        /*        ** The protoent_data has a pointer as the first field.        ** That implies the buffer better be aligned, and char*        ** doesn't promise much.        */        PRUptrdiff aligned = (PRUptrdiff)buffer;        if (0 != (aligned & (sizeof(struct protoent_data*) - 1)))        {            aligned += sizeof(struct protoent_data*) - 1;            aligned &= ~(sizeof(struct protoent_data*) - 1);            buflen -= (aligned - (PRUptrdiff)buffer);            buffer = (char*)aligned;        }    }#endif  /* defined(_PR_HAVE_GETPROTO_R_INT) */    if (PR_NETDB_BUF_SIZE > buflen)    {        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);        return PR_FAILURE;    }#if defined(_PR_HAVE_GETPROTO_R_POINTER)    if (NULL == getprotobyname_r(name, res, buffer, buflen))    {        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        return PR_FAILURE;    }#elif defined(_PR_HAVE_GETPROTO_R_INT)    /*    ** The buffer needs to be zero'd, and it should be    ** at least the size of a struct protoent_data.    */    memset(buffer, 0, buflen);	if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer))    {        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        return PR_FAILURE;    }#elif defined(_PR_HAVE_5_ARG_GETPROTO_R)    /* The 5th argument for getprotobyname_r() cannot be NULL */    if (-1 == getprotobyname_r(name, res, buffer, buflen, &res))    {        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        return PR_FAILURE;    }#else  /* do it the hard way */	{		struct protoent *staticBuf;		PR_Lock(_getproto_lock);		staticBuf = getprotobyname_r(name);		if (NULL == staticBuf)		{		    rv = PR_FAILURE;		    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        }		else		{			rv = CopyProtoent(staticBuf, buffer, buflen, result);			if (PR_FAILURE == rv)			    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);        }		PR_Unlock(_getproto_lock);	}#endif  /* all that */    return rv;}PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber(    PRInt32 number, char* buffer, PRInt32 buflen, PRProtoEnt* result){	PRStatus rv = PR_SUCCESS;#if defined(_PR_HAVE_GETPROTO_R)	struct protoent* res = (struct protoent*)result;#endif    if (!_pr_initialized) _PR_ImplicitInitialization();#if defined(_PR_HAVE_GETPROTO_R_INT)    {        /*        ** The protoent_data has a pointer as the first field.        ** That implies the buffer better be aligned, and char*        ** doesn't promise much.        */        PRUptrdiff aligned = (PRUptrdiff)buffer;        if (0 != (aligned & (sizeof(struct protoent_data*) - 1)))        {            aligned += sizeof(struct protoent_data*) - 1;            aligned &= ~(sizeof(struct protoent_data*) - 1);            buflen -= (aligned - (PRUptrdiff)buffer);            buffer = (char*)aligned;        }    }#endif /* defined(_PR_HAVE_GETPROTO_R_INT) */    if (PR_NETDB_BUF_SIZE > buflen)    {        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);        return PR_FAILURE;    }#if defined(_PR_HAVE_GETPROTO_R_POINTER)    if (NULL == getprotobynumber_r(number, res, buffer, buflen))    {        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        return PR_FAILURE;    }#elif defined(_PR_HAVE_GETPROTO_R_INT)    /*    ** The buffer needs to be zero'd for these OS's.    */    memset(buffer, 0, buflen);	if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer))    {        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        return PR_FAILURE;    }#elif defined(_PR_HAVE_5_ARG_GETPROTO_R)    /* The 5th argument for getprotobynumber_r() cannot be NULL */    if (-1 == getprotobynumber_r(number, res, buffer, buflen, &res))    {        PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        return PR_FAILURE;    }#else  /* do it the hard way */	{		struct protoent *staticBuf;		PR_Lock(_getproto_lock);		staticBuf = getprotobynumber_r(number);		if (NULL == staticBuf)		{		    rv = PR_FAILURE;		    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO());        }		else		{			rv = CopyProtoent(staticBuf, buffer, buflen, result);			if (PR_FAILURE == rv)			    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);        }		PR_Unlock(_getproto_lock);	}#endif  /* all that crap */    return rv;}PRUintn _PR_NetAddrSize(const PRNetAddr* addr){    PRUintn addrsize;    /*     * RFC 2553 added a new field (sin6_scope_id) to     * struct sockaddr_in6.  PRNetAddr's ipv6 member has a     * scope_id field to match the new field.  In order to     * work with older implementations supporting RFC 2133,     * we take the size of struct sockaddr_in6 instead of     * addr->ipv6.     */    if (AF_INET == addr->raw.family)        addrsize = sizeof(addr->inet);    else if (PR_AF_INET6 == addr->raw.family)#if defined(_PR_INET6)        addrsize = sizeof(struct sockaddr_in6);#else        addrsize = sizeof(addr->ipv6);#endif#if defined(XP_UNIX)    else if (AF_UNIX == addr->raw.family)        addrsize = sizeof(addr->local);#endif    else addrsize = 0;    return addrsize;}  /* _PR_NetAddrSize */PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt(    PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address){    void *addr = hostEnt->h_addr_list[enumIndex++];    memset(address, 0, sizeof(PRNetAddr));    if (NULL == addr) enumIndex = 0;    else    {        address->raw.family = hostEnt->h_addrtype;        if (PR_AF_INET6 == hostEnt->h_addrtype)        {            address->ipv6.port = htons(port);        	address->ipv6.flowinfo = 0;        	address->ipv6.scope_id = 0;            memcpy(&address->ipv6.ip, addr, hostEnt->h_length);        }        else        {            PR_ASSERT(AF_INET == hostEnt->h_addrtype);            address->inet.port = htons(port);            memcpy(&address->inet.ip, addr, hostEnt->h_length);        }    }    return enumIndex;}  /* PR_EnumerateHostEnt */PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr(    PRNetAddrValue val, PRUint16 port, PRNetAddr *addr){    PRStatus rv = PR_SUCCESS;    if (!_pr_initialized) _PR_ImplicitInitialization();	if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet));	addr->inet.family = AF_INET;	addr->inet.port = htons(port);	switch (val)	{	case PR_IpAddrNull:		break;  /* don't overwrite the address */	case PR_IpAddrAny:		addr->inet.ip = htonl(INADDR_ANY);		break;	case PR_IpAddrLoopback:		addr->inet.ip = htonl(INADDR_LOOPBACK);		break;	default:		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);		rv = PR_FAILURE;	}    return rv;}  /* PR_InitializeNetAddr */PR_IMPLEMENT(PRStatus) PR_SetNetAddr(    PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr){    PRStatus rv = PR_SUCCESS;    if (!_pr_initialized) _PR_ImplicitInitialization();    if (af == PR_AF_INET6)    {        if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->ipv6));        addr->ipv6.family = af;        addr->ipv6.port = htons(port);        addr->ipv6.flowinfo = 0;        addr->ipv6.scope_id = 0;        switch (val)        {        case PR_IpAddrNull:            break;  /* don't overwrite the address */        case PR_IpAddrAny:            addr->ipv6.ip = _pr_in6addr_any;            break;        case PR_IpAddrLoopback:            addr->ipv6.ip = _pr_in6addr_loopback;            break;        default:            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);            rv = PR_FAILURE;        }    }    else    {        if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet));        addr->inet.family = af;        addr->inet.port = htons(port);        switch (val)        {        case PR_IpAddrNull:            break;  /* don't overwrite the address */        case PR_IpAddrAny:            addr->inet.ip = htonl(INADDR_ANY);

⌨️ 快捷键说明

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