netopen.c

来自「UNIX下SH的实现源码」· C语言 代码 · 共 229 行

C
229
字号
/*    * netopen.c -- functions to make tcp/udp connections * * Chet Ramey * chet@ins.CWRU.Edu *//* Copyright (C) 1987,1991 Free Software Foundation, Inc.   This file is part of GNU Bash, the Bourne Again SHell.   Bash is free software; you can redistribute it and/or modify it   under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   Bash is distributed in the hope that it will be useful, but WITHOUT   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public   License for more details.   You should have received a copy of the GNU General Public License   along with Bash; see the file COPYING.  If not, write to the Free   Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */#include <config.h>#if defined (HAVE_NETWORK)#include <stdio.h> #include <sys/types.h>#if defined (HAVE_SYS_SOCKET_H)#  include <sys/socket.h>#endif#if defined (HAVE_NETINET_IN_H)#  include <netinet/in.h>#endif#if defined (HAVE_NETDB_H)#  include <netdb.h>#endif#if defined (HAVE_ARPA_INET_H)#  include <arpa/inet.h>#endif#include <bashansi.h>#include <ctype.h>#include <errno.h>#ifndef errnoextern int errno;#endif#if !defined (HAVE_INET_ATON)extern int inet_aton ();#endifextern char *xmalloc ();/* Stuff the internet address corresponding to HOST into AP, in network   byte order.  Return 1 on success, 0 on failure. */static int_getaddr (host, ap)     char *host;     struct in_addr *ap;{  struct hostent *h;  int r;  r = 0;  if (isdigit (host[0]))    {      /* If the first character is a digit, guess that it's an	 Internet address and return immediately if inet_aton succeeds. */      r = inet_aton (host, ap);      if (r)	return r;    }#if !defined (HAVE_GETHOSTBYNAME)  return 0;#else  h = gethostbyname (host);  if (h && h->h_addr)    {      bcopy(h->h_addr, (char *)ap, h->h_length);      return 1;    }#endif  return 0;  }/* Return 1 if SERV is a valid port number and stuff the converted value into   PP in network byte order. */   static int_getserv (serv, pp)     char *serv;     unsigned short *pp;{  long l;  unsigned short s;  if (legal_number (serv, &l))    {      if (l > 65535)	return 0;      s = (unsigned short)(l & 0xFFFF);      s = htons (s);      if (pp)	*pp = s;      return 1;    }  else    return 0;}static int _netopen(host, serv, typ)     char *host, *serv;     int typ;{  struct in_addr ina;  struct sockaddr_in sin;  unsigned short p;  int s;  char **cp;  if (_getaddr(host, &ina) == 0)    {      internal_error ("%s: host unknown", host);      return -1;    }  if (_getserv(serv, &p) == 0)    {      internal_error("%s: invalid service", serv);      return -1;    }	  bzero ((char *)&sin, sizeof(sin));  sin.sin_family = AF_INET;  sin.sin_port = p;  sin.sin_addr = ina;  s = socket(AF_INET, (typ == 't') ? SOCK_STREAM : SOCK_DGRAM, 0);  if (s < 0)    {      sys_error ("socket");      return (-1);    }  if (connect (s, (struct sockaddr *)&sin, sizeof (sin)) < 0)    {      sys_error("connect");      close(s);      return (-1);    }  return(s);}/* * Open a TCP or UDP connection given a path like `/dev/tcp/host/port' to * host `host' on port `port' and return the connected socket. */intnetopen (path)     char *path;{  char *np, *s, *t;  int fd;  np = xmalloc (strlen (path) + 1);  strcpy (np, path);  s = np + 9;  t = strchr (s, '/');  if (t == 0)    {      internal_error ("%s: bad network path specification", path);      return -1;    }  *t++ = '\0';  fd = _netopen (s, t, path[5]);  free (np);  return fd;}#if 0/* * Open a TCP connection to host `host' on the port defined for service * `serv' and return the connected socket. */inttcpopen (host, serv)     char *host, *serv;{  return (_netopen (host, serv, 't'));}/* * Open a UDP connection to host `host' on the port defined for service * `serv' and return the connected socket. */intudpopen (host, serv)     char *host, *serv;{  return _netopen (host, serv, 'u');}#endif#else /* !HAVE_NETWORK */intnetopen (path)     char *path;{  internal_error ("network operations not supported");  return -1;}#endif /* !HAVE_NETWORK */

⌨️ 快捷键说明

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