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

📄 netutils.c

📁 一套客户/服务器模式的备份系统代码,跨平台,支持linux,AIX, IRIX, FreeBSD, Digital Unix (OSF1), Solaris and HP-UX.
💻 C
📖 第 1 页 / 共 2 页
字号:
  ZFREE(status.closed_conns);  ZFREE(status.conn_user_data);  sigaction(SIGPIPE, &org_sigact, NULL);  return(r);}/* * Use configured name services to get our official host name.  Returns * a malloc'd string on success, NULL on failure. */UChar *get_my_off_hn(){  struct utsname	unamb;  struct hostent	*hp;  if(uname(&unamb) < 0)    return(NULL);  hp = get_host_by_name(unamb.nodename);  if(!hp)    return(NULL);  return(strdup(hp->h_name));}Int8same_host(UChar * hn1, UChar * hn2){  struct hostent	*hep1, *hep2;  Int32		i, j, n1, n2, l1, l2;  Int8		r = 0, ce;  char		*addresses1 = NULL, *addresses2 = NULL;  if(! hn1 || ! hn2){    errno = EINVAL;    return(-1);  }  ce = (strcmp(hn1, hn2) ? 0 : 2);  if(ce)    return(ce);  hep1 = get_host_by_name(hn1);  if(!hep1)    return(ce);  l1 = hep1->h_length;  for(n1 = 0; hep1->h_addr_list[n1]; n1++);  addresses1 = NEWP(UChar, n1 * l1);  if(!addresses1){    r = - errno;    GETOUT;  }  for(i = 0; i < n1; i++)    memcpy(addresses1 + i * l1, hep1->h_addr_list[i], l1);  hep2 = get_host_by_name(hn2);  if(!hep2){    r = ce;    CLEANUP;  }  l2 = hep2->h_length;  for(n2 = 0; hep2->h_addr_list[n2]; n2++);  addresses2 = NEWP(UChar, n2 * l2);  if(!addresses2){    r = - errno;    GETOUT;  }  for(i = 0; i < n2; i++)    memcpy(addresses2 + i * l2, hep2->h_addr_list[i], l2);  if(l1 != l2){    r = ce;    CLEANUP;  }  for(i = 0; i < n1; i++){    for(j = 0; j < n2; j++){	if(! memcmp(addresses1 + i * l1, addresses2 + j * l2, l1)){	  r = 1;	  i = n1;	  break;	}    }  } cleanup:  ZFREE(addresses1);  ZFREE(addresses2);  return(r); getout:  CLEANUP;}/* * Takes <servicename>, which may either be a number or a name as specified * in /etc/services or in a name service (according to /etc/nsswitch.conf), * and returns the associated port number as an int, always for protocol TCP * Returns a value < 0 on error. */intget_tcp_portnum(UChar * servicename){  struct servent	*se;  int			n, p, len, l;  UChar			*sn_cp;  if(!servicename){    errno = EINVAL;    return(-1);  }  sn_cp = strdup(servicename);  if(!sn_cp)    return(-1);  massage_string(sn_cp);  len = strlen(sn_cp);  l = -1;  n = sscanf(sn_cp, "%d%n", &p, &l);  free(sn_cp);  if(n > 0 && len == l)    return(p);  se = getservbyname(servicename, "tcp");  if(!se)    return(-1);  return(ntohs(se->s_port));}Int32anon_tcp_sockaddr(  struct sockaddr	*addr,  Int32		*sockaddrsize,  int		addrfamily){  if(addrfamily != AF_INET#ifdef	HAVE_IP6			&& addrfamily != AF_INET6#endif							)    return(-5);  if(addrfamily == AF_INET){    if(addr){	SETZERO(((struct sockaddr_in *)addr)[0]);	((struct sockaddr_in *)addr)->sin_port = htons(0);    }    if(sockaddrsize)	*sockaddrsize = sizeof(struct sockaddr_in);  }#ifdef	HAVE_IP6  if(addrfamily == AF_INET6){    if(addr){	SETZERO(((struct sockaddr_in6 *)addr)[0]);	((struct sockaddr_in6 *)addr)->sin6_port = htons(0);    }    if(sockaddrsize)	*sockaddrsize = sizeof(struct sockaddr_in6);  }#endif  if(addr)    addr->sa_family = addrfamily;  return(0);}void *inaddr_from_sockaddr(struct sockaddr * sockaddr, Int32 * addrsize)
{  void		*retaddr = NULL;  if(sockaddr->sa_family != AF_INET#ifdef	HAVE_IP6			&& sockaddr->sa_family != AF_INET6#endif							)    return(NULL);  if(sockaddr->sa_family == AF_INET){    retaddr = &(((struct sockaddr_in *)sockaddr)->sin_addr);    if(addrsize)	*addrsize = sizeof(struct in_addr);  }#ifdef	HAVE_IP6  if(sockaddr->sa_family == AF_INET6){    retaddr = &(((struct sockaddr_in6 *)sockaddr)->sin6_addr);    if(addrsize)	*addrsize = sizeof(struct in6_addr);  }#endif  return(retaddr);}Int32set_tcp_sockaddr_hp(  struct sockaddr	*addr,  struct hostent	*hp,  int		portnum){  if(hp->h_addrtype != AF_INET#ifdef	HAVE_IP6			&& hp->h_addrtype != AF_INET6#endif							)    return(-5);  addr->sa_family = hp->h_addrtype;  if(hp->h_addrtype == AF_INET){    if(hp)	memcpy(&(((struct sockaddr_in *)addr)->sin_addr),					hp->h_addr, hp->h_length);    if(portnum >= 0)	((struct sockaddr_in *)addr)->sin_port = htons(portnum);  }#ifdef	HAVE_IP6  if(hp->h_addrtype == AF_INET6){    if(hp)	memcpy(&(((struct sockaddr_in6 *)addr)->sin6_addr),					hp->h_addr, hp->h_length);    if(portnum >= 0)	((struct sockaddr_in6 *)addr)->sin6_port = htons(portnum);  }#endif  return(0);}/* return value <= - 128: may be a temporary resource shortage */intopen_tcpip_conn(UChar * hostname, UChar * servname, Int32 fallback_port){  nodeaddr	addr;  struct hostent	*hp;  struct linger	linger;  int		sockfd, fl;  Int32		sock_typesize, i, portnum;  if(!servname && fallback_port < 0){    errno = EINVAL;    return(-1);  }  hp = get_host_by_name(hostname);  if(!hp)    return(-2);  if(!servname){    portnum = fallback_port;  }  else{    portnum = get_tcp_portnum(servname);    if(portnum < 0)	return(-3);  }  if( (i = set_tcp_sockaddr_hp((struct sockaddr *)(&addr), hp, portnum)) )    return(i);  if( (i = anon_tcp_sockaddr((struct sockaddr *)(&addr), &sock_typesize, hp->h_addrtype)) )    return(i);  sockfd = socket(hp->h_addrtype, SOCK_STREAM, 0);  if(sockfd < 0)    return(-4 - 128);  i = bind(sockfd, (struct sockaddr *)(&addr), sock_typesize);  if(i){    close(sockfd);    return(-5 - 128);  }  set_tcp_sockaddr_hp((struct sockaddr *)(&addr), hp, portnum);  if(connect(sockfd, (struct sockaddr *)(&addr), sock_typesize) < 0){    close(sockfd);    i = 128;    if(errno == EACCES || errno == EPERM#ifdef	ENETUNREACH	|| errno == ENETUNREACH#endif#ifdef	EADDRNOTAVAIL	|| errno == EADDRNOTAVAIL#endif		)	i = 0;    return(-6 - i);  }  linger.l_onoff = 1;  linger.l_linger = 60;  i = setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *) &linger,						sizeof (linger));  fl = fcntl(sockfd, F_GETFL);  fcntl(sockfd, F_SETFL, fl & INV_NONBLOCKING_FLAGS);  return(sockfd);}Int32set_ip_throughput(int sockfd){    int			sock_optval;    Int32		r, i;    r = 0;#if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)    sock_optval = IPTOS_THROUGHPUT;    if( (i = setsockopt(sockfd, IPPROTO_IP, IP_TOS,				(char *) &sock_optval, sizeof(int))) < 0)	r -= 1;#endif    return(r);}Int32set_tcp_nodelay(int sockfd, Flag turn_on){    int			sock_optval, sockfd_socktype;    Int32		sock_optlen[2], r, i;    r = 0;	/* I use 32 Bit int for sock_optlen. See server.c for a *comment* */    *((int *) &(sock_optlen[0])) = sizeof(int);    i = getsockopt(sockfd, SOL_SOCKET, SO_TYPE,			(char *) &sockfd_socktype, (int *) &(sock_optlen[0]));    if(i){	r -= 1;	sockfd_socktype = -1;    }#ifdef	TCP_NODELAY    sock_optval = (turn_on ? 1 : 0);    if(sockfd_socktype == SOCK_STREAM){      if( (i = setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY,				(char *) &sock_optval, sizeof(int))) < 0)	r -= 2;    }#endif    return(r);}Int32set_socket_keepalive(int sockfd){    int			sock_optval;    Int32		r, i;    r = 0;#ifdef	SO_KEEPALIVE    sock_optval = 1;    if( (i = setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE,				(char *) &sock_optval, sizeof(int))) < 0)	r -= 1;#endif    return(r);}UChar *addr_to_string(int socktype, void * addr){  UChar		*ascaddr = NULL;  if(socktype != AF_INET#ifdef	HAVE_IP6  			&& socktype != AF_INET6#endif						)    return(NULL);#ifdef	HAVE_INET_NTOP		/* this should work, if IP6 is present */    ascaddr = NEWP(UChar, 256);    if(ascaddr){	if(inet_ntop(socktype, addr, ascaddr, 256))	  ascaddr = ZRENEWP(ascaddr, UChar, strlen(ascaddr) + 1);	else	  ZFREE(ascaddr);    }#else    if(socktype == AF_INET){#ifdef	HAVE_INET_NTOA	ascaddr = strdup(inet_ntoa(*((struct in_addr *) addr)));#else	{	  char		naddr[30];	/* manually: assuming IP-V4-address */	  unsigned long	laddr;	  laddr = ntohl(addr);	  sprintf(naddr, "%u.%u.%u.%u", laddr >> 24, (laddr >> 16) & 0xff,				(laddr >> 8) & 0xff, laddr & 0xff);	  ascaddr = strdup(naddr);	}	  #endif	/* defined(HAVE_INET_NTOA) */    }#endif	/* defined(HAVE_INET_NTOP) */  return(ascaddr);}UChar *get_hostnamestr(struct sockaddr * peeraddr){  struct hostent	*hp;  UChar		*hostname = NULL;  void		*addr;  Int32		alen;  if(!peeraddr)    return(get_my_off_hn());  if(peeraddr->sa_family == AF_UNIX)    return(strdup("localhost"));  if(peeraddr->sa_family == AF_INET){    addr = &(((struct sockaddr_in *)peeraddr)->sin_addr);    alen = sizeof(struct in_addr);  }#ifdef	HAVE_IP6  else if(peeraddr->sa_family == AF_INET6){    addr = &(((struct sockaddr_in6 *) peeraddr)->sin6_addr);    alen = sizeof(struct in6_addr);  }#endif  else    return(NULL);  hp = get_host_by_addr(addr, alen, peeraddr->sa_family);  if(hp)    hostname = strdup(hp->h_name);  else    hostname = addr_to_string(peeraddr->sa_family, addr);  return(hostname);}UChar *get_connected_peername(int sock){  int		i;  nodeaddr	peeraddr;  Int32		len[2];  len[0] = len[1] = 0;  *((int *) &(len[0])) = sizeof(peeraddr);  i = getpeername(sock, (struct sockaddr *) &peeraddr, (int *) &(len[0]));  if(i){    return(NULL);  }  return(get_hostnamestr((struct sockaddr *)(&peeraddr)));}/* *comment* on getsockopt argument 5: * The IBM had the *great* idea to change the type of argument 5 of * getsockopt (and BTW argument 3 of getpeername) to size_t *. On the * Digital Unix size_t is an 8 Byte unsigned integer. Therefore the * safety belt  *  int sock_optlen[2]. * I tried to find a workaround using autoconfig. Parsing the Headers * using cpp and perl or awk does not lead to satisfying results. Using * the TRY_COMPILE macro of autoconfig fails sometimes. E.G. the DEC * C-compiler does not complain on wrong re-declarations (neither via * error-message nor by the exit status). Try yourself, if you don't * believe. Furthermore there are 4 ways of declaration i found on * several systems. 4th argument as char * or void *, 5th arg as * explained of type int * or size_t *. Testing all these is annoying. * Maybe some other vendors have other ideas, how getsockopt should * be declared (sigh). Therefore i use two 32-Bit integers. Even if * a system call thinks, it must put there a 64-Bit int, the program * does not fail. */

⌨️ 快捷键说明

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