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

📄 net.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* net.cc: network-related routines.   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. *//* #define DEBUG_NEST_ON 1 */#define  __INSIDE_CYGWIN_NET__#include "winsup.h"#include <errno.h>#include <sys/socket.h>#include <sys/un.h>#include <iphlpapi.h>#include <stdlib.h>#include <unistd.h>#include <netdb.h>#define USE_SYS_TYPES_FD_SET#include <winsock2.h>#include "cygerrno.h"#include "security.h"#include "fhandler.h"#include "path.h"#include "dtable.h"#include "cygheap.h"#include "sigproc.h"#include "pinfo.h"#include "registry.h"#include "wsock_event.h"extern "C"{  int h_errno;  int __stdcall rcmd (char **ahost, unsigned short inport, char *locuser,		      char *remuser, char *cmd, SOCKET * fd2p);  int __stdcall rexec (char **ahost, unsigned short inport, char *locuser,		       char *password, char *cmd, SOCKET * fd2p);  int __stdcall rresvport (int *);  int sscanf (const char *, const char *, ...);}				/* End of "C" section */LPWSAOVERLAPPEDwsock_event::prepare (){  LPWSAOVERLAPPED ret = NULL;  SetLastError (0);  if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT)    {      memset (&ovr, 0, sizeof ovr);      ovr.hEvent = event;      ret = &ovr;    }  else if (GetLastError () == ERROR_PROC_NOT_FOUND) /* winsock2 not available */    WSASetLastError (0);  debug_printf ("%d = wsock_event::prepare ()", ret);  return ret;}intwsock_event::wait (int socket, LPDWORD flags){  int ret = -1;  WSAEVENT ev[2] = { event, signal_arrived };  switch (WSAWaitForMultipleEvents (2, ev, FALSE, WSA_INFINITE, FALSE))    {      case WSA_WAIT_EVENT_0:	DWORD len;	if (WSAGetOverlappedResult (socket, &ovr, &len, FALSE, flags))	  ret = (int) len;	break;      case WSA_WAIT_EVENT_0 + 1:	if (!CancelIo ((HANDLE) socket))	  {	    debug_printf ("CancelIo() %E, fallback to blocking io");	    WSAGetOverlappedResult (socket, &ovr, &len, TRUE, flags);	  }	else	  WSASetLastError (WSAEINTR);	break;      case WSA_WAIT_FAILED:	break;      default:			/* Should be impossible. *LOL* */	WSASetLastError (WSAEFAULT);	break;    }  WSACloseEvent (event);  event = NULL;  return ret;}WSADATA wsadata;static fhandler_socket *get (const int fd){  cygheap_fdget cfd (fd);  if (cfd < 0)    return 0;  fhandler_socket *const fh = cfd->is_socket ();  if (!fh)    set_errno (ENOTSOCK);  return fh;}static SOCKET __stdcallset_socket_inheritance (SOCKET sock){  SOCKET osock = sock;  if (!DuplicateHandle (hMainProc, (HANDLE) sock, hMainProc, (HANDLE *) &sock,                        0, TRUE, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE))    system_printf ("DuplicateHandle failed %E");  else    debug_printf ("DuplicateHandle succeeded osock %p, sock %p", osock, sock);  return sock;}/* htonl: standards? */extern "C" unsigned long inthtonl (unsigned long int x){  return ((((x & 0x000000ffU) << 24) |	   ((x & 0x0000ff00U) << 8) |	   ((x & 0x00ff0000U) >> 8) |	   ((x & 0xff000000U) >> 24)));}/* ntohl: standards? */extern "C" unsigned long intntohl (unsigned long int x){  return htonl (x);}/* htons: standards? */extern "C" unsigned shorthtons (unsigned short x){  return ((((x & 0x000000ffU) << 8) |           ((x & 0x0000ff00U) >> 8)));}/* ntohs: standards? */extern "C" unsigned shortntohs (unsigned short x){  return htons (x);}static voiddump_protoent (struct protoent *p){  if (p)    debug_printf ("protoent %s %x %x", p->p_name, p->p_aliases, p->p_proto);}/* exported as inet_ntoa: BSD 4.3 */extern "C" char *cygwin_inet_ntoa (struct in_addr in){#ifdef _MT_SAFE#define ntoa_buf  _reent_winsup ()->_ntoa_buf#else  static char *ntoa_buf = NULL;#endif  char *res = inet_ntoa (in);  if (ntoa_buf)    {      free (ntoa_buf);      ntoa_buf = NULL;    }  if (res)    ntoa_buf = strdup (res);  return ntoa_buf;}/* exported as inet_addr: BSD 4.3 */extern "C" unsigned longcygwin_inet_addr (const char *cp){  if (check_null_str_errno (cp))    return INADDR_NONE;  unsigned long res = inet_addr (cp);  return res;}/* exported as inet_aton: BSD 4.3   inet_aton is not exported by wsock32 and ws2_32,   so it has to be implemented here. */extern "C" intcygwin_inet_aton (const char *cp, struct in_addr *inp){  if (check_null_str_errno (cp) || check_null_invalid_struct_errno (inp))    return 0;  unsigned long res = inet_addr (cp);  if (res == INADDR_NONE && strcmp (cp, "255.255.255.255"))    return 0;  if (inp)    inp->s_addr = res;  return 1;}/* undocumented in wsock32.dll */extern "C" unsigned int WINAPI inet_network (const char *);extern "C" unsigned intcygwin_inet_network (const char *cp){  if (check_null_str_errno (cp))    return INADDR_NONE;  unsigned int res = inet_network (cp);  return res;}/* inet_netof is in the standard BSD sockets library.  It is useless   for modern networks, since it assumes network values which are no   longer meaningful, but some existing code calls it.  */extern "C" unsigned longinet_netof (struct in_addr in){  unsigned long i, res;  i = ntohl (in.s_addr);  if (IN_CLASSA (i))    res = (i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT;  else if (IN_CLASSB (i))    res = (i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT;  else    res = (i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT;  return res;}/* inet_makeaddr is in the standard BSD sockets library.  It is   useless for modern networks, since it assumes network values which   are no longer meaningful, but some existing code calls it.  */extern "C" struct in_addrinet_makeaddr (int net, int lna){  unsigned long i;  struct in_addr in;  if (net < IN_CLASSA_MAX)    i = (net << IN_CLASSA_NSHIFT) | (lna & IN_CLASSA_HOST);  else if (net < IN_CLASSB_MAX)    i = (net << IN_CLASSB_NSHIFT) | (lna & IN_CLASSB_HOST);  else if (net < 0x1000000)    i = (net << IN_CLASSC_NSHIFT) | (lna & IN_CLASSC_HOST);  else    i = net | lna;  in.s_addr = htonl (i);  return in;}struct tl{  int w;  const char *s;  int e;};static NO_COPY struct tl errmap[] = {  {WSAEINTR, "WSAEINTR", EINTR},  {WSAEWOULDBLOCK, "WSAEWOULDBLOCK", EWOULDBLOCK},  {WSAEINPROGRESS, "WSAEINPROGRESS", EINPROGRESS},  {WSAEALREADY, "WSAEALREADY", EALREADY},  {WSAENOTSOCK, "WSAENOTSOCK", ENOTSOCK},  {WSAEDESTADDRREQ, "WSAEDESTADDRREQ", EDESTADDRREQ},  {WSAEMSGSIZE, "WSAEMSGSIZE", EMSGSIZE},  {WSAEPROTOTYPE, "WSAEPROTOTYPE", EPROTOTYPE},  {WSAENOPROTOOPT, "WSAENOPROTOOPT", ENOPROTOOPT},  {WSAEPROTONOSUPPORT, "WSAEPROTONOSUPPORT", EPROTONOSUPPORT},  {WSAESOCKTNOSUPPORT, "WSAESOCKTNOSUPPORT", ESOCKTNOSUPPORT},  {WSAEOPNOTSUPP, "WSAEOPNOTSUPP", EOPNOTSUPP},  {WSAEPFNOSUPPORT, "WSAEPFNOSUPPORT", EPFNOSUPPORT},  {WSAEAFNOSUPPORT, "WSAEAFNOSUPPORT", EAFNOSUPPORT},  {WSAEADDRINUSE, "WSAEADDRINUSE", EADDRINUSE},  {WSAEADDRNOTAVAIL, "WSAEADDRNOTAVAIL", EADDRNOTAVAIL},  {WSAENETDOWN, "WSAENETDOWN", ENETDOWN},  {WSAENETUNREACH, "WSAENETUNREACH", ENETUNREACH},  {WSAENETRESET, "WSAENETRESET", ENETRESET},  {WSAECONNABORTED, "WSAECONNABORTED", ECONNABORTED},  {WSAECONNRESET, "WSAECONNRESET", ECONNRESET},  {WSAENOBUFS, "WSAENOBUFS", ENOBUFS},  {WSAEISCONN, "WSAEISCONN", EISCONN},  {WSAENOTCONN, "WSAENOTCONN", ENOTCONN},  {WSAESHUTDOWN, "WSAESHUTDOWN", ESHUTDOWN},  {WSAETOOMANYREFS, "WSAETOOMANYREFS", ETOOMANYREFS},  {WSAETIMEDOUT, "WSAETIMEDOUT", ETIMEDOUT},  {WSAECONNREFUSED, "WSAECONNREFUSED", ECONNREFUSED},  {WSAELOOP, "WSAELOOP", ELOOP},  {WSAENAMETOOLONG, "WSAENAMETOOLONG", ENAMETOOLONG},  {WSAEHOSTDOWN, "WSAEHOSTDOWN", EHOSTDOWN},  {WSAEHOSTUNREACH, "WSAEHOSTUNREACH", EHOSTUNREACH},  {WSAENOTEMPTY, "WSAENOTEMPTY", ENOTEMPTY},  {WSAEPROCLIM, "WSAEPROCLIM", EPROCLIM},  {WSAEUSERS, "WSAEUSERS", EUSERS},  {WSAEDQUOT, "WSAEDQUOT", EDQUOT},  {WSAESTALE, "WSAESTALE", ESTALE},  {WSAEREMOTE, "WSAEREMOTE", EREMOTE},  {WSAEINVAL, "WSAEINVAL", EINVAL},  {WSAEFAULT, "WSAEFAULT", EFAULT},  {0, "NOERROR", 0},  {0, NULL, 0}};static intfind_winsock_errno (int why){  for (int i = 0; errmap[i].s != NULL; ++i)    if (why == errmap[i].w)      return errmap[i].e;  return EPERM;}void__set_winsock_errno (const char *fn, int ln){  DWORD werr = WSAGetLastError ();  int err = find_winsock_errno (werr);  set_errno (err);  syscall_printf ("%s:%d - winsock error %d -> errno %d", fn, ln, werr, err);}/* * Since the member `s' isn't used for debug output we can use it * for the error text returned by herror and hstrerror. */static NO_COPY struct tl host_errmap[] = {  {WSAHOST_NOT_FOUND, "Unknown host", HOST_NOT_FOUND},  {WSATRY_AGAIN, "Host name lookup failure", TRY_AGAIN},  {WSANO_RECOVERY, "Unknown server error", NO_RECOVERY},  {WSANO_DATA, "No address associated with name", NO_DATA},  {0, NULL, 0}};static voidset_host_errno (){  int i;  int why = WSAGetLastError ();  for (i = 0; host_errmap[i].w != 0; ++i)    if (why == host_errmap[i].w)      break;  if (host_errmap[i].w != 0)    h_errno = host_errmap[i].e;  else    h_errno = NETDB_INTERNAL;}static voidfree_char_list (char **clist){  if (clist)    {      for (char **cl = clist; *cl; ++cl)	free (*cl);      free (clist);    }}static char **dup_char_list (char **src){  char **dst;  int cnt = 0;  for (char **cl = src; *cl; ++cl)    ++cnt;  if (!(dst = (char **) calloc (cnt + 1, sizeof *dst)))    return NULL;  while (cnt-- > 0)    if (!(dst[cnt] = strdup (src[cnt])))      return NULL;  return dst;}#define free_addr_list(addr_list)	free_char_list (addr_list)static char **dup_addr_list (char **src, unsigned int size){  char **dst;  int cnt = 0;  for (char **cl = src; *cl; ++cl)    ++cnt;  if (!(dst = (char **) calloc (cnt + 1, sizeof *dst)))    return NULL;  while (cnt-- > 0)    {      if (!(dst[cnt] = (char *) malloc (size)))	return NULL;      memcpy (dst[cnt], src[cnt], size);    }  return dst;}static voidfree_protoent_ptr (struct protoent *&p){  if (p)    {      debug_printf ("protoent: %s", p->p_name);      if (p->p_name)	free (p->p_name);      free_char_list (p->p_aliases);      p = NULL;    }}static struct protoent *dup_protoent_ptr (struct protoent *src){  if (!src)    return NULL;  struct protoent *dst = (struct protoent *) calloc (1, sizeof *dst);  if (!dst)    return NULL;  debug_printf ("protoent: %s", src->p_name);  dst->p_proto = src->p_proto;  if (src->p_name && !(dst->p_name = strdup (src->p_name)))    goto out;  if (src->p_aliases && !(dst->p_aliases = dup_char_list (src->p_aliases)))    goto out;  debug_printf ("protoent: copied %s", dst->p_name);  return dst;out:  free_protoent_ptr (dst);  return NULL;}#ifdef _MT_SAFE#define protoent_buf  _reent_winsup ()->_protoent_buf#elsestatic struct protoent *protoent_buf = NULL;#endif/* exported as getprotobyname: standards? */extern "C" struct protoent *cygwin_getprotobyname (const char *p){  if (check_null_str_errno (p))    return NULL;  free_protoent_ptr (protoent_buf);  protoent_buf = dup_protoent_ptr (getprotobyname (p));  if (!protoent_buf)    set_winsock_errno ();  dump_protoent (protoent_buf);  return protoent_buf;}/* exported as getprotobynumber: standards? */extern "C" struct protoent *cygwin_getprotobynumber (int number){  free_protoent_ptr (protoent_buf);  protoent_buf = dup_protoent_ptr (getprotobynumber (number));  if (!protoent_buf)    set_winsock_errno ();  dump_protoent (protoent_buf);  return protoent_buf;}fhandler_socket *fdsock (int &fd, const char *name, SOCKET soc){  if (!winsock2_active)    soc = set_socket_inheritance (soc);  else if (wincap.has_set_handle_information ())    {      /* NT systems apparently set sockets to inheritable by default */      SetHandleInformation ((HANDLE) soc, HANDLE_FLAG_INHERIT, 0);      debug_printf ("reset socket inheritance since winsock2_active %d",		    winsock2_active);    }  else    debug_printf ("not setting socket inheritance since winsock2_active %d",		  winsock2_active);  fhandler_socket *fh =    (fhandler_socket *) cygheap->fdtab.build_fhandler (fd, FH_SOCKET, name);  fh->set_io_handle ((HANDLE) soc);  fh->set_flags (O_RDWR | O_BINARY);  fh->set_r_no_interrupt (winsock2_active);  debug_printf ("fd %d, name '%s', soc %p", fd, name, soc);  return fh;}/* exported as socket: standards? */extern "C" intcygwin_socket (int af, int type, int protocol){  int res = -1;  SOCKET soc = 0;  fhandler_socket *fh = NULL;  cygheap_fdnew fd;  if (fd >= 0)    {      debug_printf ("socket (%d, %d, %d)", af, type, protocol);      soc = socket (AF_INET, type, af == AF_LOCAL ? 0 : protocol);      if (soc == INVALID_SOCKET)	{	  set_winsock_errno ();	  goto done;	}      const char *name;      if (af == AF_INET)	name = (type == SOCK_STREAM ? "/dev/tcp" : "/dev/udp");      else	name = (type == SOCK_STREAM ? "/dev/streamsocket" : "/dev/dgsocket");      fh = fdsock (fd, name, soc);      if (fh)	{	  fh->set_addr_family (af);	  fh->set_socket_type (type);	}      res = fd;    }

⌨️ 快捷键说明

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