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

📄 connect.c

📁 prozgui是一款Linxu下著名的下载工具
💻 C
字号:
/****************************************************************************** libprozilla - a download accelerator library Copyright (C) 2001 Kalum Somaratna This program 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 of the License, or (at your option) any later version. This program 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 this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA******************************************************************************//* Connection routines. *//* $Id: connect.c,v 1.23 2001/09/27 22:52:04 kalum Exp $ */#include "common.h"#include "misc.h"#include "debug.h"#include "connect.h"/****************************************************************************** Connect to the specified server.******************************************************************************/uerr_t connect_to_server(int *sock, const char *name, int port,			 struct timeval *tout){  unsigned int portnum;  int status, noblock, flags;  struct sockaddr_in server;  struct hostent *hp, hostbuf;  extern int h_errno;  /* int opt; */  char *tmphstbuf;  struct timeval timeout;  size_t hstbuflen = 2048;  assert(name != NULL);  tmphstbuf = kmalloc(hstbuflen);  portnum = port;  memset((void *) &server, 0, sizeof(server));  memcpy(&timeout, tout, sizeof(timeout));  hp = k_gethostname(name, &hostbuf, &tmphstbuf, &hstbuflen);  if (hp == NULL)    return HOSTERR;  memcpy((void *) &server.sin_addr, hp->h_addr, hp->h_length);  server.sin_family = hp->h_addrtype;  server.sin_port = htons(portnum);  /* Create a socket. */  if ((*sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 1)  {    kfree(tmphstbuf);    return CONSOCKERR;  }  /* Experimental. */  flags = fcntl(*sock, F_GETFL, 0);  if (flags != -1)    noblock = fcntl(*sock, F_SETFL, flags | O_NONBLOCK);  else    noblock = -1;  status = connect(*sock, (struct sockaddr *) &server, sizeof(server));  if ((status == -1) && (noblock != -1) && (errno == EINPROGRESS))  {    fd_set writefd;    FD_ZERO(&writefd);    FD_SET(*sock, &writefd);    status = select((*sock + 1), NULL, &writefd, NULL, &timeout);    /* Do we need to retry if the err is EINTR? */    if (status > 0)    {      socklen_t arglen = sizeof(int);      if (getsockopt(*sock, SOL_SOCKET, SO_ERROR, &status, &arglen) < 0)	status = errno;      if (status != 0)	errno = status, status = -1;      if (errno == EINPROGRESS)	errno = ETIMEDOUT;    } else if (status == 0)      errno = ETIMEDOUT, status = -1;  }  if (status < 0)  {    close(*sock);    if (errno == ECONNREFUSED)    {      kfree(tmphstbuf);      return CONREFUSED;    } else    {      kfree(tmphstbuf);      return CONERROR;    }  } else  {    flags = fcntl(*sock, F_GETFL, 0);    if (flags != -1)      fcntl(*sock, F_SETFL, flags & ~O_NONBLOCK);  }  /* setsockopt(*sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&opt,     (int) sizeof(opt)); */  kfree(tmphstbuf);  return NOCONERROR;}/****************************************************************************** ...******************************************************************************/uerr_t bind_socket(int *sockfd){  struct sockaddr_in serv_addr;  /* Open a TCP socket (an Internet stream socket). */  if ((*sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)    return CONSOCKERR;  /* Fill in the structure fields for binding. */  memset((void *) &serv_addr, 0, sizeof(serv_addr));  serv_addr.sin_family = AF_INET;  serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);  serv_addr.sin_port = htons(0);	/* Let the system choose. */  /* Bind the address to the socket. */  if (bind(*sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)  {    perror("bind");    close(*sockfd);    return BINDERR;  }  /* Allow only one server. */  if (listen(*sockfd, 1) < 0)  {    perror("listen");    close(*sockfd);    return LISTENERR;  }  return BINDOK;}/****************************************************************************** ...******************************************************************************/int select_fd(int fd, struct timeval *timeout, int writep){  fd_set fds, exceptfds;  struct timeval to;  FD_ZERO(&fds);  FD_SET(fd, &fds);  FD_ZERO(&exceptfds);  FD_SET(fd, &exceptfds);  memcpy(&to, timeout, sizeof(struct timeval));  return (select(fd + 1, writep ? NULL : &fds, writep ? &fds : NULL,		 &exceptfds, &to));}/****************************************************************************** Receive size bytes from sock with a time delay.******************************************************************************/int krecv(int sock, char *buffer, int size, int flags,	  struct timeval *timeout){  int ret, arglen;  arglen = sizeof(int);  assert(size >= 0);  do  {    if (timeout)    {      do      {	ret = select_fd(sock, timeout, 0);      }      while ((ret == -1) && (errno == EINTR));      if (ret <= 0)      {	/* proz_debug("Error after select res=%d errno=%d.", ret, errno); */	/* Set errno to ETIMEDOUT on timeout. */	if (ret == 0)	  errno = ETIMEDOUT;	return -1;      }    }    ret = recv(sock, buffer, size, flags);  }  while ((ret == -1) && (errno == EINTR));  return ret;}/****************************************************************************** Send size bytes to sock with a time delay.******************************************************************************/int ksend(int sock, char *buffer, int size, int flags,	  struct timeval *timeout){  int ret = 0;  /* write() may write less than size bytes, thus the outward loop     keeps trying it until all was written, or an error occurred. The     inner loop is reserved for the usual EINTR f*kage, and the     innermost loop deals with the same during select(). */  while (size != 0)  {    do    {      if (timeout)      {	do	{	  ret = select_fd(sock, timeout, 1);	}	while ((ret == -1) && (errno == EINTR));	if (ret <= 0)	{	  /* Set errno to ETIMEDOUT on timeout. */	  if (ret == 0)	    errno = ETIMEDOUT;	  return -1;	}      }      ret = send(sock, buffer, size, flags);    }    while ((ret == -1) && (errno == EINTR));    if (ret <= 0)      break;    buffer += ret;    size -= ret;  }  return ret;}/****************************************************************************** Get host data by hostname.******************************************************************************/struct hostent *k_gethostname(const char *host, struct hostent *hostbuf,			      char **tmphstbuf, size_t * hstbuflen){  struct hostent *hp;  int herr, res;  if (*hstbuflen == 0)  {    *hstbuflen = 2048;    *tmphstbuf = kmalloc(*hstbuflen);  }#ifdef HAVE_FUNC_GETHOSTBYNAME_R_6  while ((res = gethostbyname_r(host, hostbuf, *tmphstbuf, *hstbuflen, &hp,				&herr)) && (errno == ERANGE))#endif#ifdef HAVE_FUNC_GETHOSTBYNAME_R_5    while ((NULL == (hp = gethostbyname_r(host, hostbuf, *tmphstbuf,					  *hstbuflen, &herr)))	   && (errno == ERANGE))#endif    {      /* Enlarge the buffer. */      *hstbuflen *= 2;      *tmphstbuf = krealloc(*tmphstbuf, *hstbuflen);    }  if (res != 0)    return NULL;  return hp;}/****************************************************************************** Accept a connection.******************************************************************************/uerr_t accept_connection(int listen_sock, int *data_sock){  struct sockaddr_in cli_addr;  socklen_t clilen = sizeof(cli_addr);  int sockfd;  sockfd = accept(listen_sock, (struct sockaddr *) &cli_addr, &clilen);  if (sockfd < 0)  {    perror("accept");    return ACCEPTERR;  }  *data_sock = sockfd;  /* Now we can free the listen socket since it is not needed...     accept() returned the new socket... */  close(listen_sock);  return ACCEPTOK;}

⌨️ 快捷键说明

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